Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /intern
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'intern')
-rw-r--r--intern/atomic/atomic_ops.h4
-rw-r--r--intern/atomic/intern/atomic_ops_ext.h85
-rw-r--r--intern/atomic/intern/atomic_ops_msvc.h65
-rw-r--r--intern/atomic/intern/atomic_ops_unix.h200
-rw-r--r--intern/atomic/intern/atomic_ops_utils.h29
-rw-r--r--intern/audaspace/CMakeLists.txt56
-rw-r--r--intern/audaspace/intern/AUD_PyInit.cpp53
-rw-r--r--intern/audaspace/intern/AUD_PyInit.h13
-rw-r--r--intern/audaspace/intern/AUD_Set.cpp34
-rw-r--r--intern/audaspace/intern/AUD_Set.h4
-rw-r--r--intern/clog/CLG_log.h144
-rw-r--r--intern/clog/CMakeLists.txt10
-rw-r--r--intern/clog/clog.c706
-rw-r--r--intern/cycles/CMakeLists.txt494
-rw-r--r--intern/cycles/app/CMakeLists.txt202
-rw-r--r--intern/cycles/app/cycles_cubin_cc.cpp478
-rw-r--r--intern/cycles/app/cycles_server.cpp158
-rw-r--r--intern/cycles/app/cycles_standalone.cpp794
-rw-r--r--intern/cycles/app/cycles_xml.cpp1012
-rw-r--r--intern/cycles/app/cycles_xml.h2
-rw-r--r--intern/cycles/blender/CCL_api.h2
-rw-r--r--intern/cycles/blender/CMakeLists.txt98
-rw-r--r--intern/cycles/blender/blender_camera.cpp1541
-rw-r--r--intern/cycles/blender/blender_curves.cpp1961
-rw-r--r--intern/cycles/blender/blender_device.cpp140
-rw-r--r--intern/cycles/blender/blender_device.h8
-rw-r--r--intern/cycles/blender/blender_logging.cpp6
-rw-r--r--intern/cycles/blender/blender_mesh.cpp2173
-rw-r--r--intern/cycles/blender/blender_object.cpp1169
-rw-r--r--intern/cycles/blender/blender_object_cull.cpp193
-rw-r--r--intern/cycles/blender/blender_object_cull.h37
-rw-r--r--intern/cycles/blender/blender_particles.cpp116
-rw-r--r--intern/cycles/blender/blender_python.cpp1594
-rw-r--r--intern/cycles/blender/blender_session.cpp2538
-rw-r--r--intern/cycles/blender/blender_session.h298
-rw-r--r--intern/cycles/blender/blender_shader.cpp2589
-rw-r--r--intern/cycles/blender/blender_sync.cpp1463
-rw-r--r--intern/cycles/blender/blender_sync.h330
-rw-r--r--intern/cycles/blender/blender_texture.cpp50
-rw-r--r--intern/cycles/blender/blender_texture.h10
-rw-r--r--intern/cycles/blender/blender_util.h1078
-rw-r--r--intern/cycles/bvh/CMakeLists.txt50
-rw-r--r--intern/cycles/bvh/bvh.cpp946
-rw-r--r--intern/cycles/bvh/bvh.h128
-rw-r--r--intern/cycles/bvh/bvh2.cpp458
-rw-r--r--intern/cycles/bvh/bvh2.h75
-rw-r--r--intern/cycles/bvh/bvh4.cpp688
-rw-r--r--intern/cycles/bvh/bvh4.h70
-rw-r--r--intern/cycles/bvh/bvh8.cpp852
-rw-r--r--intern/cycles/bvh/bvh8.h70
-rw-r--r--intern/cycles/bvh/bvh_binning.cpp446
-rw-r--r--intern/cycles/bvh/bvh_binning.h149
-rw-r--r--intern/cycles/bvh/bvh_build.cpp2101
-rw-r--r--intern/cycles/bvh/bvh_build.h193
-rw-r--r--intern/cycles/bvh/bvh_embree.cpp1646
-rw-r--r--intern/cycles/bvh/bvh_embree.h103
-rw-r--r--intern/cycles/bvh/bvh_node.cpp290
-rw-r--r--intern/cycles/bvh/bvh_node.h429
-rw-r--r--intern/cycles/bvh/bvh_params.h448
-rw-r--r--intern/cycles/bvh/bvh_sort.cpp287
-rw-r--r--intern/cycles/bvh/bvh_sort.h2
-rw-r--r--intern/cycles/bvh/bvh_split.cpp872
-rw-r--r--intern/cycles/bvh/bvh_split.h416
-rw-r--r--intern/cycles/bvh/bvh_unaligned.cpp231
-rw-r--r--intern/cycles/bvh/bvh_unaligned.h71
-rw-r--r--intern/cycles/cmake/external_libs.cmake230
-rw-r--r--intern/cycles/cmake/macros.cmake20
-rw-r--r--intern/cycles/device/CMakeLists.txt92
-rw-r--r--intern/cycles/device/device.cpp921
-rw-r--r--intern/cycles/device/device.h744
-rw-r--r--intern/cycles/device/device_cpu.cpp2094
-rw-r--r--intern/cycles/device/device_cuda.cpp5137
-rw-r--r--intern/cycles/device/device_denoising.cpp537
-rw-r--r--intern/cycles/device/device_denoising.h320
-rw-r--r--intern/cycles/device/device_intern.h27
-rw-r--r--intern/cycles/device/device_memory.cpp113
-rw-r--r--intern/cycles/device/device_memory.h678
-rw-r--r--intern/cycles/device/device_multi.cpp769
-rw-r--r--intern/cycles/device/device_network.cpp1453
-rw-r--r--intern/cycles/device/device_network.h843
-rw-r--r--intern/cycles/device/device_opencl.cpp373
-rw-r--r--intern/cycles/device/device_split_kernel.cpp517
-rw-r--r--intern/cycles/device/device_split_kernel.h185
-rw-r--r--intern/cycles/device/device_task.cpp175
-rw-r--r--intern/cycles/device/device_task.h155
-rw-r--r--intern/cycles/device/opencl/memory_manager.cpp361
-rw-r--r--intern/cycles/device/opencl/memory_manager.h97
-rw-r--r--intern/cycles/device/opencl/opencl.h1222
-rw-r--r--intern/cycles/device/opencl/opencl_split.cpp3506
-rw-r--r--intern/cycles/device/opencl/opencl_util.cpp1948
-rw-r--r--intern/cycles/doc/license/CMakeLists.txt12
-rw-r--r--intern/cycles/graph/CMakeLists.txt16
-rw-r--r--intern/cycles/graph/node.cpp817
-rw-r--r--intern/cycles/graph/node.h131
-rw-r--r--intern/cycles/graph/node_enum.h55
-rw-r--r--intern/cycles/graph/node_type.cpp265
-rw-r--r--intern/cycles/graph/node_type.h425
-rw-r--r--intern/cycles/graph/node_xml.cpp768
-rw-r--r--intern/cycles/graph/node_xml.h4
-rw-r--r--intern/cycles/kernel/CMakeLists.txt898
-rw-r--r--intern/cycles/kernel/bvh/bvh.h577
-rw-r--r--intern/cycles/kernel/bvh/bvh_embree.h173
-rw-r--r--intern/cycles/kernel/bvh/bvh_local.h358
-rw-r--r--intern/cycles/kernel/bvh/bvh_nodes.h899
-rw-r--r--intern/cycles/kernel/bvh/bvh_shadow_all.h563
-rw-r--r--intern/cycles/kernel/bvh/bvh_traversal.h632
-rw-r--r--intern/cycles/kernel/bvh/bvh_types.h46
-rw-r--r--intern/cycles/kernel/bvh/bvh_volume.h438
-rw-r--r--intern/cycles/kernel/bvh/bvh_volume_all.h557
-rw-r--r--intern/cycles/kernel/bvh/obvh_local.h641
-rw-r--r--intern/cycles/kernel/bvh/obvh_nodes.h817
-rw-r--r--intern/cycles/kernel/bvh/obvh_shadow_all.h1060
-rw-r--r--intern/cycles/kernel/bvh/obvh_traversal.h1013
-rw-r--r--intern/cycles/kernel/bvh/obvh_volume.h760
-rw-r--r--intern/cycles/kernel/bvh/obvh_volume_all.h866
-rw-r--r--intern/cycles/kernel/bvh/qbvh_local.h427
-rw-r--r--intern/cycles/kernel/bvh/qbvh_nodes.h700
-rw-r--r--intern/cycles/kernel/bvh/qbvh_shadow_all.h685
-rw-r--r--intern/cycles/kernel/bvh/qbvh_traversal.h731
-rw-r--r--intern/cycles/kernel/bvh/qbvh_volume.h538
-rw-r--r--intern/cycles/kernel/bvh/qbvh_volume_all.h650
-rw-r--r--intern/cycles/kernel/closure/alloc.h85
-rw-r--r--intern/cycles/kernel/closure/bsdf.h1015
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h353
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h168
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h146
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h101
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h365
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair_principled.h679
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h1847
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h972
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h398
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h124
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h171
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_diffuse.h130
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_sheen.h116
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h63
-rw-r--r--intern/cycles/kernel/closure/bsdf_refraction.h80
-rw-r--r--intern/cycles/kernel/closure/bsdf_toon.h242
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h116
-rw-r--r--intern/cycles/kernel/closure/bsdf_util.h183
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h637
-rw-r--r--intern/cycles/kernel/closure/emissive.h42
-rw-r--r--intern/cycles/kernel/closure/volume.h209
-rw-r--r--intern/cycles/kernel/filter/filter.h6
-rw-r--r--intern/cycles/kernel/filter/filter_defines.h75
-rw-r--r--intern/cycles/kernel/filter/filter_features.h168
-rw-r--r--intern/cycles/kernel/filter/filter_features_sse.h129
-rw-r--r--intern/cycles/kernel/filter/filter_nlm_cpu.h334
-rw-r--r--intern/cycles/kernel/filter/filter_nlm_gpu.h365
-rw-r--r--intern/cycles/kernel/filter/filter_prefilter.h325
-rw-r--r--intern/cycles/kernel/filter/filter_reconstruction.h142
-rw-r--r--intern/cycles/kernel/filter/filter_transform.h177
-rw-r--r--intern/cycles/kernel/filter/filter_transform_gpu.h186
-rw-r--r--intern/cycles/kernel/filter/filter_transform_sse.h192
-rw-r--r--intern/cycles/kernel/geom/geom_attribute.h110
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h441
-rw-r--r--intern/cycles/kernel/geom/geom_curve_intersect.h1770
-rw-r--r--intern/cycles/kernel/geom/geom_motion_curve.h306
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle.h228
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle_intersect.h418
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle_shader.h151
-rw-r--r--intern/cycles/kernel/geom/geom_object.h503
-rw-r--r--intern/cycles/kernel/geom/geom_patch.h554
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h484
-rw-r--r--intern/cycles/kernel/geom/geom_subd_triangle.h765
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h353
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h1229
-rw-r--r--intern/cycles/kernel/geom/geom_volume.h56
-rw-r--r--intern/cycles/kernel/kernel.h11
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h1093
-rw-r--r--intern/cycles/kernel/kernel_bake.h944
-rw-r--r--intern/cycles/kernel/kernel_camera.h696
-rw-r--r--intern/cycles/kernel/kernel_color.h10
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h94
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h87
-rw-r--r--intern/cycles/kernel/kernel_compat_opencl.h11
-rw-r--r--intern/cycles/kernel/kernel_differential.h132
-rw-r--r--intern/cycles/kernel/kernel_emission.h455
-rw-r--r--intern/cycles/kernel/kernel_film.h92
-rw-r--r--intern/cycles/kernel/kernel_globals.h165
-rw-r--r--intern/cycles/kernel/kernel_id_passes.h123
-rw-r--r--intern/cycles/kernel/kernel_jitter.h258
-rw-r--r--intern/cycles/kernel/kernel_light.h1946
-rw-r--r--intern/cycles/kernel/kernel_math.h2
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h349
-rw-r--r--intern/cycles/kernel/kernel_passes.h647
-rw-r--r--intern/cycles/kernel/kernel_path.h1210
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h1032
-rw-r--r--intern/cycles/kernel/kernel_path_common.h31
-rw-r--r--intern/cycles/kernel/kernel_path_state.h367
-rw-r--r--intern/cycles/kernel/kernel_path_subsurface.h213
-rw-r--r--intern/cycles/kernel/kernel_path_surface.h603
-rw-r--r--intern/cycles/kernel/kernel_path_volume.h544
-rw-r--r--intern/cycles/kernel/kernel_profiling.h14
-rw-r--r--intern/cycles/kernel/kernel_projection.h272
-rw-r--r--intern/cycles/kernel/kernel_queues.h145
-rw-r--r--intern/cycles/kernel/kernel_random.h294
-rw-r--r--intern/cycles/kernel/kernel_shader.h1749
-rw-r--r--intern/cycles/kernel/kernel_shadow.h637
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h822
-rw-r--r--intern/cycles/kernel/kernel_types.h2105
-rw-r--r--intern/cycles/kernel/kernel_volume.h2244
-rw-r--r--intern/cycles/kernel/kernel_work_stealing.h59
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_avx.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_avx2.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_cpu.h42
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h229
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_sse2.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_sse3.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_sse41.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel.cpp34
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_avx.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu.h53
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h965
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h182
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_split.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_split_avx.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_split_avx2.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_split_sse2.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_split_sse3.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_split_sse41.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_sse2.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_sse3.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_sse41.cpp2
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel_config.h14
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h237
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h425
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_split_function.h59
-rw-r--r--intern/cycles/kernel/osl/CMakeLists.txt28
-rw-r--r--intern/cycles/kernel/osl/background.cpp37
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp43
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp45
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp18
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp133
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp1300
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h86
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h106
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp2064
-rw-r--r--intern/cycles/kernel/osl/osl_services.h388
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp580
-rw-r--r--intern/cycles/kernel/osl/osl_shader.h35
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt212
-rw-r--r--intern/cycles/kernel/shaders/node_absorption_volume.osl10
-rw-r--r--intern/cycles/kernel/shaders/node_add_closure.osl10
-rw-r--r--intern/cycles/kernel/shaders/node_ambient_occlusion.osl36
-rw-r--r--intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl70
-rw-r--r--intern/cycles/kernel/shaders/node_attribute.osl38
-rw-r--r--intern/cycles/kernel/shaders/node_background.osl10
-rw-r--r--intern/cycles/kernel/shaders/node_bevel.osl18
-rw-r--r--intern/cycles/kernel/shaders/node_blackbody.osl19
-rw-r--r--intern/cycles/kernel/shaders/node_brick_texture.osl165
-rw-r--r--intern/cycles/kernel/shaders/node_brightness.osl20
-rw-r--r--intern/cycles/kernel/shaders/node_bump.osl74
-rw-r--r--intern/cycles/kernel/shaders/node_camera.osl16
-rw-r--r--intern/cycles/kernel/shaders/node_checker_texture.osl71
-rw-r--r--intern/cycles/kernel/shaders/node_color.h197
-rw-r--r--intern/cycles/kernel/shaders/node_combine_hsv.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_combine_rgb.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_combine_xyz.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_color.osl26
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_float.osl26
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_int.osl28
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_normal.osl26
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_point.osl26
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_string.osl16
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_vector.osl26
-rw-r--r--intern/cycles/kernel/shaders/node_diffuse_bsdf.osl18
-rw-r--r--intern/cycles/kernel/shaders/node_displacement.osl30
-rw-r--r--intern/cycles/kernel/shaders/node_emission.osl8
-rw-r--r--intern/cycles/kernel/shaders/node_environment_texture.osl82
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.h44
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.osl14
-rw-r--r--intern/cycles/kernel/shaders/node_gamma.osl7
-rw-r--r--intern/cycles/kernel/shaders/node_geometry.osl88
-rw-r--r--intern/cycles/kernel/shaders/node_glass_bsdf.osl44
-rw-r--r--intern/cycles/kernel/shaders/node_glossy_bsdf.osl35
-rw-r--r--intern/cycles/kernel/shaders/node_gradient_texture.osl89
-rw-r--r--intern/cycles/kernel/shaders/node_hair_bsdf.osl65
-rw-r--r--intern/cycles/kernel/shaders/node_hair_info.osl22
-rw-r--r--intern/cycles/kernel/shaders/node_holdout.osl5
-rw-r--r--intern/cycles/kernel/shaders/node_hsv.osl36
-rw-r--r--intern/cycles/kernel/shaders/node_ies_light.osl29
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl378
-rw-r--r--intern/cycles/kernel/shaders/node_invert.osl10
-rw-r--r--intern/cycles/kernel/shaders/node_layer_weight.osl37
-rw-r--r--intern/cycles/kernel/shaders/node_light_falloff.osl40
-rw-r--r--intern/cycles/kernel/shaders/node_light_path.osl78
-rw-r--r--intern/cycles/kernel/shaders/node_magic_texture.osl162
-rw-r--r--intern/cycles/kernel/shaders/node_mapping.osl23
-rw-r--r--intern/cycles/kernel/shaders/node_math.osl162
-rw-r--r--intern/cycles/kernel/shaders/node_mix.osl421
-rw-r--r--intern/cycles/kernel/shaders/node_mix_closure.osl14
-rw-r--r--intern/cycles/kernel/shaders/node_musgrave_texture.osl302
-rw-r--r--intern/cycles/kernel/shaders/node_noise_texture.osl63
-rw-r--r--intern/cycles/kernel/shaders/node_normal.osl14
-rw-r--r--intern/cycles/kernel/shaders/node_normal_map.osl128
-rw-r--r--intern/cycles/kernel/shaders/node_object_info.osl18
-rw-r--r--intern/cycles/kernel/shaders/node_output_displacement.osl3
-rw-r--r--intern/cycles/kernel/shaders/node_output_surface.osl3
-rw-r--r--intern/cycles/kernel/shaders/node_output_volume.osl3
-rw-r--r--intern/cycles/kernel/shaders/node_particle_info.osl34
-rw-r--r--intern/cycles/kernel/shaders/node_principled_bsdf.osl245
-rw-r--r--intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl128
-rw-r--r--intern/cycles/kernel/shaders/node_principled_volume.osl126
-rw-r--r--intern/cycles/kernel/shaders/node_ramp_util.h108
-rw-r--r--intern/cycles/kernel/shaders/node_refraction_bsdf.osl32
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_curves.osl30
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_ramp.osl18
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_to_bw.osl7
-rw-r--r--intern/cycles/kernel/shaders/node_scatter_volume.osl12
-rw-r--r--intern/cycles/kernel/shaders/node_separate_hsv.osl19
-rw-r--r--intern/cycles/kernel/shaders/node_separate_rgb.osl15
-rw-r--r--intern/cycles/kernel/shaders/node_separate_xyz.osl15
-rw-r--r--intern/cycles/kernel/shaders/node_set_normal.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl157
-rw-r--r--intern/cycles/kernel/shaders/node_subsurface_scattering.osl43
-rw-r--r--intern/cycles/kernel/shaders/node_tangent.osl46
-rw-r--r--intern/cycles/kernel/shaders/node_texture.h210
-rw-r--r--intern/cycles/kernel/shaders/node_texture_coordinate.osl141
-rw-r--r--intern/cycles/kernel/shaders/node_toon_bsdf.osl22
-rw-r--r--intern/cycles/kernel/shaders/node_translucent_bsdf.osl8
-rw-r--r--intern/cycles/kernel/shaders/node_transparent_bsdf.osl8
-rw-r--r--intern/cycles/kernel/shaders/node_uv_map.osl47
-rw-r--r--intern/cycles/kernel/shaders/node_value.osl20
-rw-r--r--intern/cycles/kernel/shaders/node_vector_curves.osl30
-rw-r--r--intern/cycles/kernel/shaders/node_vector_displacement.osl78
-rw-r--r--intern/cycles/kernel/shaders/node_vector_math.osl60
-rw-r--r--intern/cycles/kernel/shaders/node_vector_transform.osl30
-rw-r--r--intern/cycles/kernel/shaders/node_velvet_bsdf.osl14
-rw-r--r--intern/cycles/kernel/shaders/node_voronoi_texture.osl273
-rw-r--r--intern/cycles/kernel/shaders/node_voxel_texture.osl52
-rw-r--r--intern/cycles/kernel/shaders/node_wave_texture.osl72
-rw-r--r--intern/cycles/kernel/shaders/node_wavelength.osl7
-rw-r--r--intern/cycles/kernel/shaders/node_wireframe.osl39
-rw-r--r--intern/cycles/kernel/shaders/oslutil.h100
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h1160
-rw-r--r--intern/cycles/kernel/split/kernel_branched.h350
-rw-r--r--intern/cycles/kernel/split/kernel_buffer_update.h227
-rw-r--r--intern/cycles/kernel/split/kernel_data_init.h122
-rw-r--r--intern/cycles/kernel/split/kernel_direct_lighting.h195
-rw-r--r--intern/cycles/kernel/split/kernel_do_volume.h325
-rw-r--r--intern/cycles/kernel/split/kernel_enqueue_inactive.h36
-rw-r--r--intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h186
-rw-r--r--intern/cycles/kernel/split/kernel_indirect_background.h72
-rw-r--r--intern/cycles/kernel/split/kernel_indirect_subsurface.h79
-rw-r--r--intern/cycles/kernel/split/kernel_lamp_emission.h62
-rw-r--r--intern/cycles/kernel/split/kernel_next_iteration_setup.h350
-rw-r--r--intern/cycles/kernel/split/kernel_path_init.h88
-rw-r--r--intern/cycles/kernel/split/kernel_queue_enqueue.h85
-rw-r--r--intern/cycles/kernel/split/kernel_scene_intersect.h83
-rw-r--r--intern/cycles/kernel/split/kernel_shader_eval.h57
-rw-r--r--intern/cycles/kernel/split/kernel_shader_setup.h78
-rw-r--r--intern/cycles/kernel/split/kernel_shader_sort.h134
-rw-r--r--intern/cycles/kernel/split/kernel_shadow_blocked_ao.h49
-rw-r--r--intern/cycles/kernel/split/kernel_shadow_blocked_dl.h135
-rw-r--r--intern/cycles/kernel/split/kernel_split_common.h75
-rw-r--r--intern/cycles/kernel/split/kernel_split_data.h39
-rw-r--r--intern/cycles/kernel/split/kernel_split_data_types.h170
-rw-r--r--intern/cycles/kernel/split/kernel_subsurface_scatter.h475
-rw-r--r--intern/cycles/kernel/svm/svm.h624
-rw-r--r--intern/cycles/kernel/svm/svm_ao.h151
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h248
-rw-r--r--intern/cycles/kernel/svm/svm_bevel.h379
-rw-r--r--intern/cycles/kernel/svm/svm_blackbody.h11
-rw-r--r--intern/cycles/kernel/svm/svm_brick.h196
-rw-r--r--intern/cycles/kernel/svm/svm_brightness.h19
-rw-r--r--intern/cycles/kernel/svm/svm_bump.h58
-rw-r--r--intern/cycles/kernel/svm/svm_camera.h33
-rw-r--r--intern/cycles/kernel/svm/svm_checker.h42
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h2147
-rw-r--r--intern/cycles/kernel/svm/svm_color_util.h366
-rw-r--r--intern/cycles/kernel/svm/svm_convert.h95
-rw-r--r--intern/cycles/kernel/svm/svm_displace.h225
-rw-r--r--intern/cycles/kernel/svm/svm_fresnel.h66
-rw-r--r--intern/cycles/kernel/svm/svm_gamma.h13
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h325
-rw-r--r--intern/cycles/kernel/svm/svm_gradient.h84
-rw-r--r--intern/cycles/kernel/svm/svm_hsv.h55
-rw-r--r--intern/cycles/kernel/svm/svm_ies.h149
-rw-r--r--intern/cycles/kernel/svm/svm_image.h324
-rw-r--r--intern/cycles/kernel/svm/svm_invert.h19
-rw-r--r--intern/cycles/kernel/svm/svm_light_path.h116
-rw-r--r--intern/cycles/kernel/svm/svm_magic.h159
-rw-r--r--intern/cycles/kernel/svm/svm_mapping.h30
-rw-r--r--intern/cycles/kernel/svm/svm_math.h48
-rw-r--r--intern/cycles/kernel/svm/svm_math_util.h269
-rw-r--r--intern/cycles/kernel/svm/svm_mix.h22
-rw-r--r--intern/cycles/kernel/svm/svm_musgrave.h319
-rw-r--r--intern/cycles/kernel/svm/svm_noise.h330
-rw-r--r--intern/cycles/kernel/svm/svm_noisetex.h55
-rw-r--r--intern/cycles/kernel/svm/svm_normal.h32
-rw-r--r--intern/cycles/kernel/svm/svm_ramp.h125
-rw-r--r--intern/cycles/kernel/svm/svm_ramp_util.h126
-rw-r--r--intern/cycles/kernel/svm/svm_sepcomb_hsv.h56
-rw-r--r--intern/cycles/kernel/svm/svm_sepcomb_vector.h30
-rw-r--r--intern/cycles/kernel/svm/svm_sky.h283
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h709
-rw-r--r--intern/cycles/kernel/svm/svm_texture.h56
-rw-r--r--intern/cycles/kernel/svm/svm_types.h745
-rw-r--r--intern/cycles/kernel/svm/svm_value.h17
-rw-r--r--intern/cycles/kernel/svm/svm_vector_transform.h141
-rw-r--r--intern/cycles/kernel/svm/svm_voronoi.h290
-rw-r--r--intern/cycles/kernel/svm/svm_voxel.h49
-rw-r--r--intern/cycles/kernel/svm/svm_wave.h70
-rw-r--r--intern/cycles/kernel/svm/svm_wavelength.h112
-rw-r--r--intern/cycles/kernel/svm/svm_wireframe.h150
-rw-r--r--intern/cycles/render/CMakeLists.txt132
-rw-r--r--intern/cycles/render/attribute.cpp969
-rw-r--r--intern/cycles/render/attribute.h300
-rw-r--r--intern/cycles/render/background.cpp150
-rw-r--r--intern/cycles/render/background.h38
-rw-r--r--intern/cycles/render/bake.cpp374
-rw-r--r--intern/cycles/render/bake.h91
-rw-r--r--intern/cycles/render/buffers.cpp709
-rw-r--r--intern/cycles/render/buffers.h180
-rw-r--r--intern/cycles/render/camera.cpp1297
-rw-r--r--intern/cycles/render/camera.h344
-rw-r--r--intern/cycles/render/constant_fold.cpp575
-rw-r--r--intern/cycles/render/constant_fold.h58
-rw-r--r--intern/cycles/render/coverage.cpp187
-rw-r--r--intern/cycles/render/coverage.h36
-rw-r--r--intern/cycles/render/curves.cpp222
-rw-r--r--intern/cycles/render/curves.h122
-rw-r--r--intern/cycles/render/denoising.cpp1370
-rw-r--r--intern/cycles/render/denoising.h238
-rw-r--r--intern/cycles/render/film.cpp856
-rw-r--r--intern/cycles/render/film.h92
-rw-r--r--intern/cycles/render/graph.cpp1906
-rw-r--r--intern/cycles/render/graph.h450
-rw-r--r--intern/cycles/render/image.cpp1741
-rw-r--r--intern/cycles/render/image.h259
-rw-r--r--intern/cycles/render/integrator.cpp363
-rw-r--r--intern/cycles/render/integrator.h96
-rw-r--r--intern/cycles/render/light.cpp1792
-rw-r--r--intern/cycles/render/light.h167
-rw-r--r--intern/cycles/render/merge.cpp824
-rw-r--r--intern/cycles/render/merge.h18
-rw-r--r--intern/cycles/render/mesh.cpp3754
-rw-r--r--intern/cycles/render/mesh.h642
-rw-r--r--intern/cycles/render/mesh_displace.cpp571
-rw-r--r--intern/cycles/render/mesh_subdivision.cpp1044
-rw-r--r--intern/cycles/render/mesh_volume.cpp728
-rw-r--r--intern/cycles/render/nodes.cpp8204
-rw-r--r--intern/cycles/render/nodes.h1834
-rw-r--r--intern/cycles/render/object.cpp1423
-rw-r--r--intern/cycles/render/object.h182
-rw-r--r--intern/cycles/render/osl.cpp1911
-rw-r--r--intern/cycles/render/osl.h223
-rw-r--r--intern/cycles/render/particles.cpp109
-rw-r--r--intern/cycles/render/particles.h47
-rw-r--r--intern/cycles/render/scene.cpp513
-rw-r--r--intern/cycles/render/scene.h396
-rw-r--r--intern/cycles/render/session.cpp1901
-rw-r--r--intern/cycles/render/session.h314
-rw-r--r--intern/cycles/render/shader.cpp1067
-rw-r--r--intern/cycles/render/shader.h248
-rw-r--r--intern/cycles/render/sobol.h2
-rw-r--r--intern/cycles/render/stats.cpp397
-rw-r--r--intern/cycles/render/stats.h134
-rw-r--r--intern/cycles/render/svm.cpp1398
-rw-r--r--intern/cycles/render/svm.h350
-rw-r--r--intern/cycles/render/tables.cpp98
-rw-r--r--intern/cycles/render/tables.h28
-rw-r--r--intern/cycles/render/tile.cpp854
-rw-r--r--intern/cycles/render/tile.h239
-rw-r--r--intern/cycles/subd/CMakeLists.txt18
-rw-r--r--intern/cycles/subd/subd_dice.cpp454
-rw-r--r--intern/cycles/subd/subd_dice.h157
-rw-r--r--intern/cycles/subd/subd_patch.cpp106
-rw-r--r--intern/cycles/subd/subd_patch.h41
-rw-r--r--intern/cycles/subd/subd_patch_table.cpp424
-rw-r--r--intern/cycles/subd/subd_patch_table.h32
-rw-r--r--intern/cycles/subd/subd_split.cpp351
-rw-r--r--intern/cycles/subd/subd_split.h26
-rw-r--r--intern/cycles/test/CMakeLists.txt110
-rw-r--r--intern/cycles/test/render_graph_finalize_test.cpp1883
-rw-r--r--intern/cycles/test/util_aligned_malloc_test.cpp14
-rw-r--r--intern/cycles/test/util_path_test.cpp250
-rw-r--r--intern/cycles/test/util_string_test.cpp191
-rw-r--r--intern/cycles/test/util_task_test.cpp49
-rw-r--r--intern/cycles/test/util_time_test.cpp61
-rw-r--r--intern/cycles/util/CMakeLists.txt246
-rw-r--r--intern/cycles/util/util_algorithm.h6
-rw-r--r--intern/cycles/util/util_aligned_malloc.cpp46
-rw-r--r--intern/cycles/util/util_aligned_malloc.h2
-rw-r--r--intern/cycles/util/util_args.h2
-rw-r--r--intern/cycles/util/util_array.h492
-rw-r--r--intern/cycles/util/util_atomic.h125
-rw-r--r--intern/cycles/util/util_avxb.h246
-rw-r--r--intern/cycles/util/util_avxf.h389
-rw-r--r--intern/cycles/util/util_boundbox.h457
-rw-r--r--intern/cycles/util/util_color.h286
-rw-r--r--intern/cycles/util/util_debug.cpp228
-rw-r--r--intern/cycles/util/util_debug.h285
-rw-r--r--intern/cycles/util/util_defines.h189
-rw-r--r--intern/cycles/util/util_foreach.h4
-rw-r--r--intern/cycles/util/util_function.h2
-rw-r--r--intern/cycles/util/util_guarded_allocator.cpp9
-rw-r--r--intern/cycles/util/util_guarded_allocator.h238
-rw-r--r--intern/cycles/util/util_half.h177
-rw-r--r--intern/cycles/util/util_hash.h55
-rw-r--r--intern/cycles/util/util_ies.cpp668
-rw-r--r--intern/cycles/util/util_ies.h62
-rw-r--r--intern/cycles/util/util_image.h80
-rw-r--r--intern/cycles/util/util_image_impl.h198
-rw-r--r--intern/cycles/util/util_list.h2
-rw-r--r--intern/cycles/util/util_logging.cpp60
-rw-r--r--intern/cycles/util/util_logging.h34
-rw-r--r--intern/cycles/util/util_map.h2
-rw-r--r--intern/cycles/util/util_math.h490
-rw-r--r--intern/cycles/util/util_math_cdf.cpp73
-rw-r--r--intern/cycles/util/util_math_cdf.h55
-rw-r--r--intern/cycles/util/util_math_fast.h860
-rw-r--r--intern/cycles/util/util_math_float2.h202
-rw-r--r--intern/cycles/util/util_math_float3.h395
-rw-r--r--intern/cycles/util/util_math_float4.h515
-rw-r--r--intern/cycles/util/util_math_int2.h18
-rw-r--r--intern/cycles/util/util_math_int3.h82
-rw-r--r--intern/cycles/util/util_math_int4.h157
-rw-r--r--intern/cycles/util/util_math_intersect.h359
-rw-r--r--intern/cycles/util/util_math_matrix.h527
-rw-r--r--intern/cycles/util/util_md5.cpp509
-rw-r--r--intern/cycles/util/util_md5.h36
-rw-r--r--intern/cycles/util/util_murmurhash.cpp134
-rw-r--r--intern/cycles/util/util_murmurhash.h3
-rw-r--r--intern/cycles/util/util_opengl.h2
-rw-r--r--intern/cycles/util/util_optimization.h50
-rw-r--r--intern/cycles/util/util_param.h2
-rw-r--r--intern/cycles/util/util_path.cpp1432
-rw-r--r--intern/cycles/util/util_path.h50
-rw-r--r--intern/cycles/util/util_profiling.cpp216
-rw-r--r--intern/cycles/util/util_profiling.h220
-rw-r--r--intern/cycles/util/util_progress.h706
-rw-r--r--intern/cycles/util/util_projection.h216
-rw-r--r--intern/cycles/util/util_queue.h2
-rw-r--r--intern/cycles/util/util_rect.h24
-rw-r--r--intern/cycles/util/util_set.h2
-rw-r--r--intern/cycles/util/util_simd.cpp42
-rw-r--r--intern/cycles/util/util_simd.h613
-rw-r--r--intern/cycles/util/util_sky_model.cpp402
-rw-r--r--intern/cycles/util/util_sky_model.h71
-rw-r--r--intern/cycles/util/util_sky_model_data.h7470
-rw-r--r--intern/cycles/util/util_sseb.h317
-rw-r--r--intern/cycles/util/util_ssef.h1128
-rw-r--r--intern/cycles/util/util_ssei.h664
-rw-r--r--intern/cycles/util/util_stack_allocator.h262
-rw-r--r--intern/cycles/util/util_static_assert.h16
-rw-r--r--intern/cycles/util/util_stats.h44
-rw-r--r--intern/cycles/util/util_string.cpp348
-rw-r--r--intern/cycles/util/util_string.h34
-rw-r--r--intern/cycles/util/util_system.cpp391
-rw-r--r--intern/cycles/util/util_system.h4
-rw-r--r--intern/cycles/util/util_task.cpp711
-rw-r--r--intern/cycles/util/util_task.h216
-rw-r--r--intern/cycles/util/util_texture.h62
-rw-r--r--intern/cycles/util/util_thread.cpp57
-rw-r--r--intern/cycles/util/util_thread.h156
-rw-r--r--intern/cycles/util/util_time.cpp146
-rw-r--r--intern/cycles/util/util_time.h54
-rw-r--r--intern/cycles/util/util_transform.cpp370
-rw-r--r--intern/cycles/util/util_transform.h578
-rw-r--r--intern/cycles/util/util_types.h22
-rw-r--r--intern/cycles/util/util_types_float2.h12
-rw-r--r--intern/cycles/util/util_types_float2_impl.h26
-rw-r--r--intern/cycles/util/util_types_float3.h51
-rw-r--r--intern/cycles/util/util_types_float3_impl.h70
-rw-r--r--intern/cycles/util/util_types_float4.h53
-rw-r--r--intern/cycles/util/util_types_float4_impl.h83
-rw-r--r--intern/cycles/util/util_types_float8.h45
-rw-r--r--intern/cycles/util/util_types_float8_impl.h70
-rw-r--r--intern/cycles/util/util_types_int2.h10
-rw-r--r--intern/cycles/util/util_types_int2_impl.h22
-rw-r--r--intern/cycles/util/util_types_int3.h51
-rw-r--r--intern/cycles/util/util_types_int3_impl.h70
-rw-r--r--intern/cycles/util/util_types_int4.h55
-rw-r--r--intern/cycles/util/util_types_int4_impl.h98
-rw-r--r--intern/cycles/util/util_types_uchar2.h10
-rw-r--r--intern/cycles/util/util_types_uchar2_impl.h22
-rw-r--r--intern/cycles/util/util_types_uchar3.h10
-rw-r--r--intern/cycles/util/util_types_uchar3_impl.h22
-rw-r--r--intern/cycles/util/util_types_uchar4.h10
-rw-r--r--intern/cycles/util/util_types_uchar4_impl.h22
-rw-r--r--intern/cycles/util/util_types_uint2.h10
-rw-r--r--intern/cycles/util/util_types_uint2_impl.h18
-rw-r--r--intern/cycles/util/util_types_uint3.h10
-rw-r--r--intern/cycles/util/util_types_uint3_impl.h18
-rw-r--r--intern/cycles/util/util_types_uint4.h10
-rw-r--r--intern/cycles/util/util_types_uint4_impl.h18
-rw-r--r--intern/cycles/util/util_types_ushort4.h4
-rw-r--r--intern/cycles/util/util_types_vector3.h18
-rw-r--r--intern/cycles/util/util_types_vector3_impl.h14
-rw-r--r--intern/cycles/util/util_unique_ptr.h2
-rw-r--r--intern/cycles/util/util_vector.h44
-rw-r--r--intern/cycles/util/util_version.h16
-rw-r--r--intern/cycles/util/util_view.cpp328
-rw-r--r--intern/cycles/util/util_view.h15
-rw-r--r--intern/cycles/util/util_windows.h24
-rw-r--r--intern/cycles/util/util_xml.h2
-rw-r--r--intern/dualcon/CMakeLists.txt36
-rw-r--r--intern/dualcon/dualcon.h34
-rw-r--r--intern/dualcon/intern/GeoCommon.h18
-rw-r--r--intern/dualcon/intern/MemoryAllocator.h289
-rw-r--r--intern/dualcon/intern/ModelReader.h45
-rw-r--r--intern/dualcon/intern/Projections.cpp504
-rw-r--r--intern/dualcon/intern/Projections.h109
-rw-r--r--intern/dualcon/intern/Queue.h143
-rw-r--r--intern/dualcon/intern/cubes.h32
-rw-r--r--intern/dualcon/intern/dualcon_c_api.cpp251
-rw-r--r--intern/dualcon/intern/manifold_table.cpp3586
-rw-r--r--intern/dualcon/intern/manifold_table.h6
-rw-r--r--intern/dualcon/intern/marching_cubes_table.cpp3095
-rw-r--r--intern/dualcon/intern/octree.cpp4852
-rw-r--r--intern/dualcon/intern/octree.h2524
-rw-r--r--intern/eigen/CMakeLists.txt22
-rw-r--r--intern/eigen/eigen_capi.h2
-rw-r--r--intern/eigen/intern/eigenvalues.cc35
-rw-r--r--intern/eigen/intern/eigenvalues.h7
-rw-r--r--intern/eigen/intern/linear_solver.cc482
-rw-r--r--intern/eigen/intern/linear_solver.h13
-rw-r--r--intern/eigen/intern/matrix.cc22
-rw-r--r--intern/eigen/intern/matrix.h2
-rw-r--r--intern/eigen/intern/svd.cc32
-rw-r--r--intern/eigen/intern/svd.h5
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h694
-rw-r--r--intern/ghost/CMakeLists.txt556
-rw-r--r--intern/ghost/GHOST_C-api.h87
-rw-r--r--intern/ghost/GHOST_IContext.h42
-rw-r--r--intern/ghost/GHOST_IEvent.h63
-rw-r--r--intern/ghost/GHOST_IEventConsumer.h35
-rw-r--r--intern/ghost/GHOST_ISystem.h657
-rw-r--r--intern/ghost/GHOST_ISystemPaths.h134
-rw-r--r--intern/ghost/GHOST_ITimerTask.h63
-rw-r--r--intern/ghost/GHOST_IWindow.h620
-rw-r--r--intern/ghost/GHOST_Path-api.h2
-rw-r--r--intern/ghost/GHOST_Rect.h359
-rw-r--r--intern/ghost/GHOST_Types.h727
-rw-r--r--intern/ghost/intern/GHOST_Buttons.cpp58
-rw-r--r--intern/ghost/intern/GHOST_Buttons.h51
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp665
-rw-r--r--intern/ghost/intern/GHOST_CallbackEventConsumer.cpp8
-rw-r--r--intern/ghost/intern/GHOST_CallbackEventConsumer.h58
-rw-r--r--intern/ghost/intern/GHOST_Context.cpp188
-rw-r--r--intern/ghost/intern/GHOST_Context.h218
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.h182
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.mm538
-rw-r--r--intern/ghost/intern/GHOST_ContextEGL.cpp848
-rw-r--r--intern/ghost/intern/GHOST_ContextEGL.h205
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp651
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.h190
-rw-r--r--intern/ghost/intern/GHOST_ContextNone.cpp28
-rw-r--r--intern/ghost/intern/GHOST_ContextNone.h104
-rw-r--r--intern/ghost/intern/GHOST_ContextSDL.cpp216
-rw-r--r--intern/ghost/intern/GHOST_ContextSDL.h170
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.cpp1090
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.h205
-rw-r--r--intern/ghost/intern/GHOST_Debug.h71
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.cpp274
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.h187
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.h106
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.mm179
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerNULL.h40
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerSDL.cpp218
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerSDL.h42
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.cpp237
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.h97
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.cpp341
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.h118
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.cpp512
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.h233
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.cpp398
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.h185
-rw-r--r--intern/ghost/intern/GHOST_Event.h112
-rw-r--r--intern/ghost/intern/GHOST_EventButton.h42
-rw-r--r--intern/ghost/intern/GHOST_EventCursor.h46
-rw-r--r--intern/ghost/intern/GHOST_EventDragnDrop.h114
-rw-r--r--intern/ghost/intern/GHOST_EventKey.h88
-rw-r--r--intern/ghost/intern/GHOST_EventManager.cpp247
-rw-r--r--intern/ghost/intern/GHOST_EventManager.h209
-rw-r--r--intern/ghost/intern/GHOST_EventNDOF.h43
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.cpp541
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.h33
-rw-r--r--intern/ghost/intern/GHOST_EventString.h44
-rw-r--r--intern/ghost/intern/GHOST_EventTrackpad.h60
-rw-r--r--intern/ghost/intern/GHOST_EventWheel.h38
-rw-r--r--intern/ghost/intern/GHOST_ISystem.cpp55
-rw-r--r--intern/ghost/intern/GHOST_ISystemPaths.cpp54
-rw-r--r--intern/ghost/intern/GHOST_IconX11.h1507
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.cpp769
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.h598
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.cpp163
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.h97
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp771
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h263
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.h13
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.mm307
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.cpp125
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.h19
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.cpp10
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.h13
-rw-r--r--intern/ghost/intern/GHOST_Path-api.cpp24
-rw-r--r--intern/ghost/intern/GHOST_Rect.cpp173
-rw-r--r--intern/ghost/intern/GHOST_System.cpp466
-rw-r--r--intern/ghost/intern/GHOST_System.h641
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h546
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm3012
-rw-r--r--intern/ghost/intern/GHOST_SystemNULL.h144
-rw-r--r--intern/ghost/intern/GHOST_SystemPaths.h74
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsCocoa.h69
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsCocoa.mm117
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.cpp105
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.h67
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.cpp67
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.h70
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp1183
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h111
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp3072
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h736
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp3850
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h598
-rw-r--r--intern/ghost/intern/GHOST_TaskbarWin32.h138
-rw-r--r--intern/ghost/intern/GHOST_TaskbarX11.cpp130
-rw-r--r--intern/ghost/intern/GHOST_TaskbarX11.h22
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.cpp141
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.h149
-rw-r--r--intern/ghost/intern/GHOST_TimerTask.h300
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp219
-rw-r--r--intern/ghost/intern/GHOST_Window.h760
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h552
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm1582
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.cpp215
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.h235
-rw-r--r--intern/ghost/intern/GHOST_WindowNULL.h210
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.cpp950
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.h201
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp2004
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h872
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp2677
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h523
-rw-r--r--intern/ghost/test/CMakeLists.txt218
-rw-r--r--intern/ghost/test/gears/GHOST_C-Test.c849
-rw-r--r--intern/ghost/test/gears/GHOST_Test.cpp1201
-rw-r--r--intern/ghost/test/multitest/Basic.c24
-rw-r--r--intern/ghost/test/multitest/Basic.h20
-rw-r--r--intern/ghost/test/multitest/EventToBuf.c393
-rw-r--r--intern/ghost/test/multitest/GL.h20
-rw-r--r--intern/ghost/test/multitest/MultiTest.c1150
-rw-r--r--intern/ghost/test/multitest/ScrollBar.c94
-rw-r--r--intern/ghost/test/multitest/ScrollBar.h31
-rw-r--r--intern/ghost/test/multitest/Util.c36
-rw-r--r--intern/ghost/test/multitest/Util.h6
-rw-r--r--intern/ghost/test/multitest/WindowData.c16
-rw-r--r--intern/ghost/test/multitest/WindowData.h8
-rw-r--r--intern/ghost/test/multitest/stubs.c9
-rw-r--r--intern/glew-mx/CMakeLists.txt12
-rw-r--r--intern/glew-mx/glew-mx.h11
-rw-r--r--intern/glew-mx/intern/gl-deprecated.h40
-rw-r--r--intern/glew-mx/intern/glew-mx.c72
-rw-r--r--intern/glew-mx/intern/symbol-binding.h332
-rw-r--r--intern/guardedalloc/CMakeLists.txt38
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h351
-rw-r--r--intern/guardedalloc/cpp/mallocn.cpp23
-rw-r--r--intern/guardedalloc/intern/mallocn.c95
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c1518
-rw-r--r--intern/guardedalloc/intern/mallocn_inline.h28
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h94
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c616
-rw-r--r--intern/guardedalloc/intern/mmap_win.c336
-rw-r--r--intern/guardedalloc/test/simpletest/memtest.c224
-rw-r--r--intern/iksolver/CMakeLists.txt28
-rw-r--r--intern/iksolver/extern/IK_solver.h42
-rw-r--r--intern/iksolver/intern/IK_Math.h330
-rw-r--r--intern/iksolver/intern/IK_QJacobian.cpp617
-rw-r--r--intern/iksolver/intern/IK_QJacobian.h97
-rw-r--r--intern/iksolver/intern/IK_QJacobianSolver.cpp585
-rw-r--r--intern/iksolver/intern/IK_QJacobianSolver.h96
-rw-r--r--intern/iksolver/intern/IK_QSegment.cpp1145
-rw-r--r--intern/iksolver/intern/IK_QSegment.h539
-rw-r--r--intern/iksolver/intern/IK_QTask.cpp264
-rw-r--r--intern/iksolver/intern/IK_QTask.h204
-rw-r--r--intern/iksolver/intern/IK_Solver.cpp547
-rw-r--r--intern/locale/CMakeLists.txt28
-rw-r--r--intern/locale/boost_locale_wrapper.cpp137
-rw-r--r--intern/locale/boost_locale_wrapper.h2
-rw-r--r--intern/locale/osx_user_locale.mm22
-rw-r--r--intern/memutil/CMakeLists.txt18
-rw-r--r--intern/memutil/MEM_Allocator.h126
-rw-r--r--intern/memutil/MEM_CacheLimiter.h492
-rw-r--r--intern/memutil/MEM_CacheLimiterC-Api.h19
-rw-r--r--intern/memutil/MEM_RefCounted.h91
-rw-r--r--intern/memutil/MEM_RefCountedC-Api.h13
-rw-r--r--intern/memutil/intern/MEM_CacheLimiterC-Api.cpp164
-rw-r--r--intern/memutil/intern/MEM_RefCountedC-Api.cpp11
-rw-r--r--intern/mikktspace/CMakeLists.txt14
-rw-r--r--intern/mikktspace/mikktspace.c3243
-rw-r--r--intern/mikktspace/mikktspace.h112
-rw-r--r--intern/opencolorio/CMakeLists.txt62
-rw-r--r--intern/opencolorio/fallback_impl.cc718
-rw-r--r--intern/opencolorio/gpu_shader_display_transform.glsl183
-rw-r--r--intern/opencolorio/gpu_shader_display_transform_vertex.glsl4
-rw-r--r--intern/opencolorio/ocio_capi.cc175
-rw-r--r--intern/opencolorio/ocio_capi.h179
-rw-r--r--intern/opencolorio/ocio_impl.cc847
-rw-r--r--intern/opencolorio/ocio_impl.h581
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc801
-rw-r--r--intern/opensubdiv/CMakeLists.txt164
-rw-r--r--intern/opensubdiv/internal/opensubdiv.cc17
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_factory.cc130
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_factory.h4
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_internal.cc15
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_internal.h8
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_orient.cc21
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_orient.h19
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h15
-rw-r--r--intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc135
-rw-r--r--intern/opensubdiv/internal/opensubdiv_device_context_cuda.h2
-rw-r--r--intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc165
-rw-r--r--intern/opensubdiv/internal/opensubdiv_device_context_opencl.h2
-rw-r--r--intern/opensubdiv/internal/opensubdiv_edge_map.h81
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator.cc129
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc637
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator_internal.h52
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh.cc152
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc271
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h4
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc76
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h12
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc8
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h4
-rw-r--r--intern/opensubdiv/internal/opensubdiv_topology_refiner.cc382
-rw-r--r--intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc7
-rw-r--r--intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h2
-rw-r--r--intern/opensubdiv/internal/opensubdiv_util.cc15
-rw-r--r--intern/opensubdiv/internal/opensubdiv_util.h6
-rw-r--r--intern/opensubdiv/opensubdiv_capi_type.h10
-rw-r--r--intern/opensubdiv/opensubdiv_converter_capi.h67
-rw-r--r--intern/opensubdiv/opensubdiv_evaluator_capi.h56
-rw-r--r--intern/opensubdiv/opensubdiv_gl_mesh_capi.h24
-rw-r--r--intern/opensubdiv/opensubdiv_topology_refiner_capi.h90
-rw-r--r--intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl239
-rw-r--r--intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl129
-rw-r--r--intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl18
-rw-r--r--intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc8
-rw-r--r--intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc13
-rw-r--r--intern/opensubdiv/stub/opensubdiv_stub.cc12
-rw-r--r--intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc15
-rw-r--r--intern/openvdb/CMakeLists.txt68
-rw-r--r--intern/openvdb/intern/openvdb_dense_convert.cc248
-rw-r--r--intern/openvdb/intern/openvdb_dense_convert.h154
-rw-r--r--intern/openvdb/intern/openvdb_reader.cc122
-rw-r--r--intern/openvdb/intern/openvdb_reader.h32
-rw-r--r--intern/openvdb/intern/openvdb_writer.cc106
-rw-r--r--intern/openvdb/intern/openvdb_writer.h34
-rw-r--r--intern/openvdb/openvdb_capi.cc218
-rw-r--r--intern/openvdb/openvdb_capi.h89
-rw-r--r--intern/openvdb/openvdb_util.cc9
-rw-r--r--intern/openvdb/openvdb_util.h22
-rw-r--r--intern/rigidbody/CMakeLists.txt8
-rw-r--r--intern/rigidbody/RBI_api.h84
-rw-r--r--intern/rigidbody/rb_bullet_api.cpp1333
-rw-r--r--intern/string/CMakeLists.txt6
-rw-r--r--intern/string/STR_String.h457
-rw-r--r--intern/string/intern/STR_String.cpp684
-rw-r--r--intern/utfconv/CMakeLists.txt14
-rw-r--r--intern/utfconv/utf_winfunc.c233
-rw-r--r--intern/utfconv/utf_winfunc.h6
-rw-r--r--intern/utfconv/utfconv.c443
-rw-r--r--intern/utfconv/utfconv.h23
870 files changed, 156420 insertions, 147070 deletions
diff --git a/intern/atomic/atomic_ops.h b/intern/atomic/atomic_ops.h
index 6cab507a8cb..07b7ce38b94 100644
--- a/intern/atomic/atomic_ops.h
+++ b/intern/atomic/atomic_ops.h
@@ -113,7 +113,8 @@ ATOMIC_INLINE size_t atomic_sub_and_fetch_z(size_t *p, size_t x);
ATOMIC_INLINE size_t atomic_fetch_and_add_z(size_t *p, size_t x);
ATOMIC_INLINE size_t atomic_fetch_and_sub_z(size_t *p, size_t x);
ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new);
-ATOMIC_INLINE size_t atomic_fetch_and_update_max_z(size_t *p, size_t x); /* Uses CAS loop, see warning below. */
+ATOMIC_INLINE size_t
+atomic_fetch_and_update_max_z(size_t *p, size_t x); /* Uses CAS loop, see warning below. */
ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x);
ATOMIC_INLINE unsigned int atomic_sub_and_fetch_u(unsigned int *p, unsigned int x);
@@ -123,7 +124,6 @@ ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsig
ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new);
-
ATOMIC_INLINE float atomic_cas_float(float *v, float old, float _new);
/* WARNING! Float 'atomics' are really faked ones, those are actually closer to some kind of spinlock-sync'ed operation,
diff --git a/intern/atomic/intern/atomic_ops_ext.h b/intern/atomic/intern/atomic_ops_ext.h
index 56ef3c33fce..4dbc1153506 100644
--- a/intern/atomic/intern/atomic_ops_ext.h
+++ b/intern/atomic/intern/atomic_ops_ext.h
@@ -56,105 +56,106 @@ ATOMIC_STATIC_ASSERT(sizeof(size_t) == LG_SIZEOF_PTR, "sizeof(size_t) != LG_SIZE
ATOMIC_INLINE size_t atomic_add_and_fetch_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 8)
- return (size_t)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
+ return (size_t)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
#elif (LG_SIZEOF_PTR == 4)
- return (size_t)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
+ return (size_t)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
#endif
}
ATOMIC_INLINE size_t atomic_sub_and_fetch_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 8)
- return (size_t)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
+ return (size_t)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t) - ((int64_t)x));
#elif (LG_SIZEOF_PTR == 4)
- return (size_t)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
+ return (size_t)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t) - ((int32_t)x));
#endif
}
ATOMIC_INLINE size_t atomic_fetch_and_add_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 8)
- return (size_t)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
+ return (size_t)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
#elif (LG_SIZEOF_PTR == 4)
- return (size_t)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
+ return (size_t)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
#endif
}
ATOMIC_INLINE size_t atomic_fetch_and_sub_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 8)
- return (size_t)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
+ return (size_t)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t) - ((int64_t)x));
#elif (LG_SIZEOF_PTR == 4)
- return (size_t)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
+ return (size_t)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t) - ((int32_t)x));
#endif
}
ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new)
{
#if (LG_SIZEOF_PTR == 8)
- return (size_t)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
+ return (size_t)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
#elif (LG_SIZEOF_PTR == 4)
- return (size_t)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
+ return (size_t)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
#endif
}
ATOMIC_INLINE size_t atomic_fetch_and_update_max_z(size_t *p, size_t x)
{
- size_t prev_value;
- while((prev_value = *p) < x) {
- if(atomic_cas_z(p, prev_value, x) == prev_value) {
- break;
- }
- }
- return prev_value;
+ size_t prev_value;
+ while ((prev_value = *p) < x) {
+ if (atomic_cas_z(p, prev_value, x) == prev_value) {
+ break;
+ }
+ }
+ return prev_value;
}
/******************************************************************************/
/* unsigned operations. */
-ATOMIC_STATIC_ASSERT(sizeof(unsigned int) == LG_SIZEOF_INT, "sizeof(unsigned int) != LG_SIZEOF_INT");
+ATOMIC_STATIC_ASSERT(sizeof(unsigned int) == LG_SIZEOF_INT,
+ "sizeof(unsigned int) != LG_SIZEOF_INT");
ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x)
{
#if (LG_SIZEOF_INT == 8)
- return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
+ return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
#elif (LG_SIZEOF_INT == 4)
- return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
+ return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
#endif
}
ATOMIC_INLINE unsigned int atomic_sub_and_fetch_u(unsigned int *p, unsigned int x)
{
#if (LG_SIZEOF_INT == 8)
- return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
+ return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t) - ((int64_t)x));
#elif (LG_SIZEOF_INT == 4)
- return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
+ return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t) - ((int32_t)x));
#endif
}
ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int x)
{
#if (LG_SIZEOF_INT == 8)
- return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
+ return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
#elif (LG_SIZEOF_INT == 4)
- return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
+ return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
#endif
}
ATOMIC_INLINE unsigned int atomic_fetch_and_sub_u(unsigned int *p, unsigned int x)
{
#if (LG_SIZEOF_INT == 8)
- return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
+ return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t) - ((int64_t)x));
#elif (LG_SIZEOF_INT == 4)
- return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
+ return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t) - ((int32_t)x));
#endif
}
ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsigned int _new)
{
#if (LG_SIZEOF_INT == 8)
- return (unsigned int)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
+ return (unsigned int)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
#elif (LG_SIZEOF_INT == 4)
- return (unsigned int)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
+ return (unsigned int)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
#endif
}
@@ -162,12 +163,12 @@ ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsig
/* Char operations. */
ATOMIC_INLINE char atomic_fetch_and_or_char(char *p, char b)
{
- return (char)atomic_fetch_and_or_uint8((uint8_t *)p, (uint8_t)b);
+ return (char)atomic_fetch_and_or_uint8((uint8_t *)p, (uint8_t)b);
}
ATOMIC_INLINE char atomic_fetch_and_and_char(char *p, char b)
{
- return (char)atomic_fetch_and_and_uint8((uint8_t *)p, (uint8_t)b);
+ return (char)atomic_fetch_and_and_uint8((uint8_t *)p, (uint8_t)b);
}
/******************************************************************************/
@@ -176,9 +177,9 @@ ATOMIC_INLINE char atomic_fetch_and_and_char(char *p, char b)
ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new)
{
#if (LG_SIZEOF_PTR == 8)
- return (void *)atomic_cas_uint64((uint64_t *)v, *(uint64_t *)&old, *(uint64_t *)&_new);
+ return (void *)atomic_cas_uint64((uint64_t *)v, *(uint64_t *)&old, *(uint64_t *)&_new);
#elif (LG_SIZEOF_PTR == 4)
- return (void *)atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new);
+ return (void *)atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new);
#endif
}
@@ -188,22 +189,22 @@ ATOMIC_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "sizeof(float) != sizeof
ATOMIC_INLINE float atomic_cas_float(float *v, float old, float _new)
{
- uint32_t ret = atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new);
- return *(float *)&ret;
+ uint32_t ret = atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new);
+ return *(float *)&ret;
}
ATOMIC_INLINE float atomic_add_and_fetch_fl(float *p, const float x)
{
- float oldval, newval;
- uint32_t prevval;
+ float oldval, newval;
+ uint32_t prevval;
- do { /* Note that since collisions are unlikely, loop will nearly always run once. */
- oldval = *p;
- newval = oldval + x;
- prevval = atomic_cas_uint32((uint32_t *)p, *(uint32_t *)(&oldval), *(uint32_t *)(&newval));
- } while (_ATOMIC_UNLIKELY(prevval != *(uint32_t *)(&oldval)));
+ do { /* Note that since collisions are unlikely, loop will nearly always run once. */
+ oldval = *p;
+ newval = oldval + x;
+ prevval = atomic_cas_uint32((uint32_t *)p, *(uint32_t *)(&oldval), *(uint32_t *)(&newval));
+ } while (_ATOMIC_UNLIKELY(prevval != *(uint32_t *)(&oldval)));
- return newval;
+ return newval;
}
#endif /* __ATOMIC_OPS_EXT_H__ */
diff --git a/intern/atomic/intern/atomic_ops_msvc.h b/intern/atomic/intern/atomic_ops_msvc.h
index 39ed4efe3a8..d9655defa81 100644
--- a/intern/atomic/intern/atomic_ops_msvc.h
+++ b/intern/atomic/intern/atomic_ops_msvc.h
@@ -40,7 +40,7 @@
#include <windows.h>
#include <intrin.h>
-#if defined (__clang__)
+#if defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#endif
@@ -50,53 +50,53 @@
/* Unsigned */
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x)
{
- return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x) + x;
+ return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x) + x;
}
ATOMIC_INLINE uint64_t atomic_sub_and_fetch_uint64(uint64_t *p, uint64_t x)
{
- return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x)) - x;
+ return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x)) - x;
}
ATOMIC_INLINE uint64_t atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
{
- return InterlockedCompareExchange64((int64_t *)v, _new, old);
+ return InterlockedCompareExchange64((int64_t *)v, _new, old);
}
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x)
{
- return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x);
+ return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x);
}
ATOMIC_INLINE uint64_t atomic_fetch_and_sub_uint64(uint64_t *p, uint64_t x)
{
- return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x));
+ return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x));
}
/* Signed */
ATOMIC_INLINE int64_t atomic_add_and_fetch_int64(int64_t *p, int64_t x)
{
- return InterlockedExchangeAdd64(p, x) + x;
+ return InterlockedExchangeAdd64(p, x) + x;
}
ATOMIC_INLINE int64_t atomic_sub_and_fetch_int64(int64_t *p, int64_t x)
{
- return InterlockedExchangeAdd64(p, -x) - x;
+ return InterlockedExchangeAdd64(p, -x) - x;
}
ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
{
- return InterlockedCompareExchange64(v, _new, old);
+ return InterlockedCompareExchange64(v, _new, old);
}
ATOMIC_INLINE int64_t atomic_fetch_and_add_int64(int64_t *p, int64_t x)
{
- return InterlockedExchangeAdd64(p, x);
+ return InterlockedExchangeAdd64(p, x);
}
ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x)
{
- return InterlockedExchangeAdd64(p, -x);
+ return InterlockedExchangeAdd64(p, -x);
}
#endif
@@ -105,63 +105,63 @@ ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x)
/* Unsigned */
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
{
- return InterlockedExchangeAdd(p, x) + x;
+ return InterlockedExchangeAdd(p, x) + x;
}
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
{
- return InterlockedExchangeAdd(p, -((int32_t)x)) - x;
+ return InterlockedExchangeAdd(p, -((int32_t)x)) - x;
}
ATOMIC_INLINE uint32_t atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
{
- return InterlockedCompareExchange((long *)v, _new, old);
+ return InterlockedCompareExchange((long *)v, _new, old);
}
ATOMIC_INLINE uint32_t atomic_fetch_and_add_uint32(uint32_t *p, uint32_t x)
{
- return InterlockedExchangeAdd(p, x);
+ return InterlockedExchangeAdd(p, x);
}
ATOMIC_INLINE uint32_t atomic_fetch_and_or_uint32(uint32_t *p, uint32_t x)
{
- return InterlockedOr((long *)p, x);
+ return InterlockedOr((long *)p, x);
}
ATOMIC_INLINE uint32_t atomic_fetch_and_and_uint32(uint32_t *p, uint32_t x)
{
- return InterlockedAnd((long *)p, x);
+ return InterlockedAnd((long *)p, x);
}
/* Signed */
ATOMIC_INLINE int32_t atomic_add_and_fetch_int32(int32_t *p, int32_t x)
{
- return InterlockedExchangeAdd((long *)p, x) + x;
+ return InterlockedExchangeAdd((long *)p, x) + x;
}
ATOMIC_INLINE int32_t atomic_sub_and_fetch_int32(int32_t *p, int32_t x)
{
- return InterlockedExchangeAdd((long *)p, -x) - x;
+ return InterlockedExchangeAdd((long *)p, -x) - x;
}
ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
{
- return InterlockedCompareExchange((long *)v, _new, old);
+ return InterlockedCompareExchange((long *)v, _new, old);
}
ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x)
{
- return InterlockedExchangeAdd((long *)p, x);
+ return InterlockedExchangeAdd((long *)p, x);
}
ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x)
{
- return InterlockedOr((long *)p, x);
+ return InterlockedOr((long *)p, x);
}
ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
{
- return InterlockedAnd((long *)p, x);
+ return InterlockedAnd((long *)p, x);
}
/******************************************************************************/
@@ -172,9 +172,9 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
{
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
- return InterlockedAnd8((char *)p, (char)b);
+ return InterlockedAnd8((char *)p, (char)b);
#else
- return _InterlockedAnd8((char *)p, (char)b);
+ return _InterlockedAnd8((char *)p, (char)b);
#endif
}
@@ -182,9 +182,9 @@ ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
{
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
- return InterlockedOr8((char *)p, (char)b);
+ return InterlockedOr8((char *)p, (char)b);
#else
- return _InterlockedOr8((char *)p, (char)b);
+ return _InterlockedOr8((char *)p, (char)b);
#endif
}
@@ -193,9 +193,9 @@ ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
ATOMIC_INLINE int8_t atomic_fetch_and_and_int8(int8_t *p, int8_t b)
{
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
- return InterlockedAnd8((char *)p, (char)b);
+ return InterlockedAnd8((char *)p, (char)b);
#else
- return _InterlockedAnd8((char *)p, (char)b);
+ return _InterlockedAnd8((char *)p, (char)b);
#endif
}
@@ -203,14 +203,13 @@ ATOMIC_INLINE int8_t atomic_fetch_and_and_int8(int8_t *p, int8_t b)
ATOMIC_INLINE int8_t atomic_fetch_and_or_int8(int8_t *p, int8_t b)
{
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
- return InterlockedOr8((char *)p, (char)b);
+ return InterlockedOr8((char *)p, (char)b);
#else
- return _InterlockedOr8((char *)p, (char)b);
+ return _InterlockedOr8((char *)p, (char)b);
#endif
}
-
-#if defined (__clang__)
+#if defined(__clang__)
# pragma GCC diagnostic pop
#endif
diff --git a/intern/atomic/intern/atomic_ops_unix.h b/intern/atomic/intern/atomic_ops_unix.h
index cda251f342b..e1126cab0c2 100644
--- a/intern/atomic/intern/atomic_ops_unix.h
+++ b/intern/atomic/intern/atomic_ops_unix.h
@@ -56,140 +56,128 @@
/* Unsigned */
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x)
{
- return __sync_add_and_fetch(p, x);
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE uint64_t atomic_sub_and_fetch_uint64(uint64_t *p, uint64_t x)
{
- return __sync_sub_and_fetch(p, x);
+ return __sync_sub_and_fetch(p, x);
}
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x)
{
- return __sync_fetch_and_add(p, x);
+ return __sync_fetch_and_add(p, x);
}
ATOMIC_INLINE uint64_t atomic_fetch_and_sub_uint64(uint64_t *p, uint64_t x)
{
- return __sync_fetch_and_sub(p, x);
+ return __sync_fetch_and_sub(p, x);
}
ATOMIC_INLINE uint64_t atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
{
- return __sync_val_compare_and_swap(v, old, _new);
+ return __sync_val_compare_and_swap(v, old, _new);
}
/* Signed */
ATOMIC_INLINE int64_t atomic_add_and_fetch_int64(int64_t *p, int64_t x)
{
- return __sync_add_and_fetch(p, x);
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE int64_t atomic_sub_and_fetch_int64(int64_t *p, int64_t x)
{
- return __sync_sub_and_fetch(p, x);
+ return __sync_sub_and_fetch(p, x);
}
ATOMIC_INLINE int64_t atomic_fetch_and_add_int64(int64_t *p, int64_t x)
{
- return __sync_fetch_and_add(p, x);
+ return __sync_fetch_and_add(p, x);
}
ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x)
{
- return __sync_fetch_and_sub(p, x);
+ return __sync_fetch_and_sub(p, x);
}
ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
{
- return __sync_val_compare_and_swap(v, old, _new);
+ return __sync_val_compare_and_swap(v, old, _new);
}
# elif (defined(__amd64__) || defined(__x86_64__))
/* Unsigned */
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x)
{
- asm volatile (
- "lock; xaddq %0, %1;"
- : "+r" (x), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return x;
+ asm volatile("lock; xaddq %0, %1;"
+ : "+r"(x), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return x;
}
ATOMIC_INLINE uint64_t atomic_fetch_and_sub_uint64(uint64_t *p, uint64_t x)
{
- x = (uint64_t)(-(int64_t)x);
- asm volatile (
- "lock; xaddq %0, %1;"
- : "+r" (x), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return x;
+ x = (uint64_t)(-(int64_t)x);
+ asm volatile("lock; xaddq %0, %1;"
+ : "+r"(x), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return x;
}
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x)
{
- return atomic_fetch_and_add_uint64(p, x) + x;
+ return atomic_fetch_and_add_uint64(p, x) + x;
}
ATOMIC_INLINE uint64_t atomic_sub_and_fetch_uint64(uint64_t *p, uint64_t x)
{
- return atomic_fetch_and_sub_uint64(p, x) - x;
+ return atomic_fetch_and_sub_uint64(p, x) - x;
}
ATOMIC_INLINE uint64_t atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
{
- uint64_t ret;
- asm volatile (
- "lock; cmpxchgq %2,%1"
- : "=a" (ret), "+m" (*v)
- : "r" (_new), "0" (old)
- : "memory");
- return ret;
+ uint64_t ret;
+ asm volatile("lock; cmpxchgq %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
+ return ret;
}
/* Signed */
ATOMIC_INLINE int64_t atomic_fetch_and_add_int64(int64_t *p, int64_t x)
{
- asm volatile (
- "lock; xaddq %0, %1;"
- : "+r" (x), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return x;
+ asm volatile("lock; xaddq %0, %1;"
+ : "+r"(x), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return x;
}
ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x)
{
- x = -x;
- asm volatile (
- "lock; xaddq %0, %1;"
- : "+r" (x), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return x;
+ x = -x;
+ asm volatile("lock; xaddq %0, %1;"
+ : "+r"(x), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return x;
}
ATOMIC_INLINE int64_t atomic_add_and_fetch_int64(int64_t *p, int64_t x)
{
- return atomic_fetch_and_add_int64(p, x) + x;
+ return atomic_fetch_and_add_int64(p, x) + x;
}
ATOMIC_INLINE int64_t atomic_sub_and_fetch_int64(int64_t *p, int64_t x)
{
- return atomic_fetch_and_sub_int64(p, x) - x;
+ return atomic_fetch_and_sub_int64(p, x) - x;
}
ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
{
- int64_t ret;
- asm volatile (
- "lock; cmpxchgq %2,%1"
- : "=a" (ret), "+m" (*v)
- : "r" (_new), "0" (old)
- : "memory");
- return ret;
+ int64_t ret;
+ asm volatile("lock; cmpxchgq %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
+ return ret;
}
# else
# error "Missing implementation for 64-bit atomic operations"
@@ -202,102 +190,90 @@ ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
/* Unsigned */
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
{
- return __sync_add_and_fetch(p, x);
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
{
- return __sync_sub_and_fetch(p, x);
+ return __sync_sub_and_fetch(p, x);
}
ATOMIC_INLINE uint32_t atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
{
- return __sync_val_compare_and_swap(v, old, _new);
+ return __sync_val_compare_and_swap(v, old, _new);
}
/* Signed */
ATOMIC_INLINE int32_t atomic_add_and_fetch_int32(int32_t *p, int32_t x)
{
- return __sync_add_and_fetch(p, x);
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE int32_t atomic_sub_and_fetch_int32(int32_t *p, int32_t x)
{
- return __sync_sub_and_fetch(p, x);
+ return __sync_sub_and_fetch(p, x);
}
ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
{
- return __sync_val_compare_and_swap(v, old, _new);
+ return __sync_val_compare_and_swap(v, old, _new);
}
#elif (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
/* Unsigned */
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
{
- uint32_t ret = x;
- asm volatile (
- "lock; xaddl %0, %1;"
- : "+r" (ret), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return ret + x;
+ uint32_t ret = x;
+ asm volatile("lock; xaddl %0, %1;"
+ : "+r"(ret), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return ret + x;
}
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
{
- uint32_t ret = (uint32_t)(-(int32_t)x);
- asm volatile (
- "lock; xaddl %0, %1;"
- : "+r" (ret), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return ret - x;
+ uint32_t ret = (uint32_t)(-(int32_t)x);
+ asm volatile("lock; xaddl %0, %1;"
+ : "+r"(ret), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return ret - x;
}
ATOMIC_INLINE uint32_t atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
{
- uint32_t ret;
- asm volatile (
- "lock; cmpxchgl %2,%1"
- : "=a" (ret), "+m" (*v)
- : "r" (_new), "0" (old)
- : "memory");
- return ret;
+ uint32_t ret;
+ asm volatile("lock; cmpxchgl %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
+ return ret;
}
/* Signed */
ATOMIC_INLINE int32_t atomic_add_and_fetch_int32(int32_t *p, int32_t x)
{
- int32_t ret = x;
- asm volatile (
- "lock; xaddl %0, %1;"
- : "+r" (ret), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return ret + x;
+ int32_t ret = x;
+ asm volatile("lock; xaddl %0, %1;"
+ : "+r"(ret), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return ret + x;
}
ATOMIC_INLINE int32_t atomic_sub_and_fetch_int32(int32_t *p, int32_t x)
{
- int32_t ret = -x;
- asm volatile (
- "lock; xaddl %0, %1;"
- : "+r" (ret), "=m" (*p) /* Outputs. */
- : "m" (*p) /* Inputs. */
- );
- return ret - x;
+ int32_t ret = -x;
+ asm volatile("lock; xaddl %0, %1;"
+ : "+r"(ret), "=m"(*p) /* Outputs. */
+ : "m"(*p) /* Inputs. */
+ );
+ return ret - x;
}
ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
{
- int32_t ret;
- asm volatile (
- "lock; cmpxchgl %2,%1"
- : "=a" (ret), "+m" (*v)
- : "r" (_new), "0" (old)
- : "memory");
- return ret;
+ int32_t ret;
+ asm volatile("lock; cmpxchgl %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
+ return ret;
}
#else
@@ -308,33 +284,33 @@ ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
/* Unsigned */
ATOMIC_INLINE uint32_t atomic_fetch_and_add_uint32(uint32_t *p, uint32_t x)
{
- return __sync_fetch_and_add(p, x);
+ return __sync_fetch_and_add(p, x);
}
ATOMIC_INLINE uint32_t atomic_fetch_and_or_uint32(uint32_t *p, uint32_t x)
{
- return __sync_fetch_and_or(p, x);
+ return __sync_fetch_and_or(p, x);
}
ATOMIC_INLINE uint32_t atomic_fetch_and_and_uint32(uint32_t *p, uint32_t x)
{
- return __sync_fetch_and_and(p, x);
+ return __sync_fetch_and_and(p, x);
}
/* Signed */
ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x)
{
- return __sync_fetch_and_add(p, x);
+ return __sync_fetch_and_add(p, x);
}
ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x)
{
- return __sync_fetch_and_or(p, x);
+ return __sync_fetch_and_or(p, x);
}
ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
{
- return __sync_fetch_and_and(p, x);
+ return __sync_fetch_and_and(p, x);
}
#else
@@ -347,21 +323,21 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
/* Unsigned */
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
{
- return __sync_fetch_and_and(p, b);
+ return __sync_fetch_and_and(p, b);
}
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
{
- return __sync_fetch_and_or(p, b);
+ return __sync_fetch_and_or(p, b);
}
/* Signed */
ATOMIC_INLINE int8_t atomic_fetch_and_and_int8(int8_t *p, int8_t b)
{
- return __sync_fetch_and_and(p, b);
+ return __sync_fetch_and_and(p, b);
}
ATOMIC_INLINE int8_t atomic_fetch_and_or_int8(int8_t *p, int8_t b)
{
- return __sync_fetch_and_or(p, b);
+ return __sync_fetch_and_or(p, b);
}
#else
diff --git a/intern/atomic/intern/atomic_ops_utils.h b/intern/atomic/intern/atomic_ops_utils.h
index ff71d113f45..4010051607c 100644
--- a/intern/atomic/intern/atomic_ops_utils.h
+++ b/intern/atomic/intern/atomic_ops_utils.h
@@ -62,11 +62,11 @@
#endif
#ifdef __GNUC__
-# define _ATOMIC_LIKELY(x) __builtin_expect(!!(x), 1)
-# define _ATOMIC_UNLIKELY(x) __builtin_expect(!!(x), 0)
+# define _ATOMIC_LIKELY(x) __builtin_expect(!!(x), 1)
+# define _ATOMIC_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
-# define _ATOMIC_LIKELY(x) (x)
-# define _ATOMIC_UNLIKELY(x) (x)
+# define _ATOMIC_LIKELY(x) (x)
+# define _ATOMIC_UNLIKELY(x) (x)
#endif
#if defined(__SIZEOF_POINTER__)
@@ -77,7 +77,7 @@
# elif (UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF)
# define LG_SIZEOF_PTR 8
# endif
-#elif defined(__WORDSIZE) /* Fallback for older glibc and cpp */
+#elif defined(__WORDSIZE) /* Fallback for older glibc and cpp */
# if (__WORDSIZE == 32)
# define LG_SIZEOF_PTR 4
# elif (__WORDSIZE == 64)
@@ -100,9 +100,8 @@
/* Copied from BLI_utils... */
/* C++ can't use _Static_assert, expects static_assert() but c++0x only,
* Coverity also errors out. */
-#if (!defined(__cplusplus)) && \
- (!defined(__COVERITY__)) && \
- (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */
+#if (!defined(__cplusplus)) && (!defined(__COVERITY__)) && \
+ (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */
# define ATOMIC_STATIC_ASSERT(a, msg) __extension__ _Static_assert(a, msg);
#else
/* Code adapted from http://www.pixelbeat.org/programming/gcc/static_assert.html */
@@ -110,17 +109,19 @@
* expand __LINE__ with one indirection before doing the actual concatenation. */
# define ATOMIC_ASSERT_CONCAT_(a, b) a##b
# define ATOMIC_ASSERT_CONCAT(a, b) ATOMIC_ASSERT_CONCAT_(a, b)
- /* These can't be used after statements in c89. */
-# if defined(__COUNTER__) /* MSVC */
+/* These can't be used after statements in c89. */
+# if defined(__COUNTER__) /* MSVC */
# define ATOMIC_STATIC_ASSERT(a, msg) \
- ; enum { ATOMIC_ASSERT_CONCAT(static_assert_, __COUNTER__) = 1 / (int)(!!(a)) };
-# else /* older gcc, clang... */
- /* This can't be used twice on the same line so ensure if using in headers
+ ; \
+ enum { ATOMIC_ASSERT_CONCAT(static_assert_, __COUNTER__) = 1 / (int)(!!(a)) };
+# else /* older gcc, clang... */
+/* This can't be used twice on the same line so ensure if using in headers
* that the headers are not included twice (by wrapping in #ifndef...#endif)
* Note it doesn't cause an issue when used on same line of separate modules
* compiled with gcc -combine -fwhole-program. */
# define ATOMIC_STATIC_ASSERT(a, msg) \
- ; enum { ATOMIC_ASSERT_CONCAT(assert_line_, __LINE__) = 1 / (int)(!!(a)) };
+ ; \
+ enum { ATOMIC_ASSERT_CONCAT(assert_line_, __LINE__) = 1 / (int)(!!(a)) };
# endif
#endif
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index 21657d6f3c0..7baaf301f6c 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -22,46 +22,46 @@
remove_strict_flags()
if(CMAKE_COMPILER_IS_GNUCC)
- remove_cc_flag("-Wunused-macros")
+ remove_cc_flag("-Wunused-macros")
endif()
- set(INC
- .
- )
+ set(INC
+ .
+ )
- set(INC_SYS
- ${AUDASPACE_C_INCLUDE_DIRS}
- ${AUDASPACE_PY_INCLUDE_DIRS}
- )
+ set(INC_SYS
+ ${AUDASPACE_C_INCLUDE_DIRS}
+ ${AUDASPACE_PY_INCLUDE_DIRS}
+ )
- set(SRC
- intern/AUD_Set.cpp
- intern/AUD_Set.h
- )
+ set(SRC
+ intern/AUD_Set.cpp
+ intern/AUD_Set.h
+ )
set(LIB
)
if(NOT WITH_SYSTEM_AUDASPACE)
- list(APPEND LIB
- audaspace
- )
+ list(APPEND LIB
+ audaspace
+ )
endif()
if(WITH_PYTHON)
- list(APPEND INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- )
- list(APPEND SRC
- intern/AUD_PyInit.cpp
- intern/AUD_PyInit.h
- )
- if(NOT WITH_SYSTEM_AUDASPACE)
- list(APPEND LIB
- audaspace-py
- )
- endif()
+ list(APPEND INC_SYS
+ ${PYTHON_INCLUDE_DIRS}
+ )
+ list(APPEND SRC
+ intern/AUD_PyInit.cpp
+ intern/AUD_PyInit.h
+ )
+ if(NOT WITH_SYSTEM_AUDASPACE)
+ list(APPEND LIB
+ audaspace-py
+ )
+ endif()
- add_definitions(-DWITH_PYTHON)
+ add_definitions(-DWITH_PYTHON)
endif()
blender_add_lib(bf_intern_audaspace "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/audaspace/intern/AUD_PyInit.cpp b/intern/audaspace/intern/AUD_PyInit.cpp
index b40cce34dfb..b65d2740f32 100644
--- a/intern/audaspace/intern/AUD_PyInit.cpp
+++ b/intern/audaspace/intern/AUD_PyInit.cpp
@@ -34,46 +34,47 @@ extern void *BKE_sound_get_factory(void *sound);
static PyObject *AUD_getSoundFromPointer(PyObject *self, PyObject *args)
{
- long int lptr;
+ long int lptr;
- if (PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) {
- if (lptr) {
- AUD_Sound* sound = BKE_sound_get_factory((void *) lptr);
+ if (PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) {
+ if (lptr) {
+ AUD_Sound *sound = BKE_sound_get_factory((void *)lptr);
- if (sound) {
- Sound *obj = (Sound *)Sound_empty();
- if (obj) {
- obj->sound = AUD_Sound_copy(sound);
- return (PyObject *) obj;
- }
- }
- }
- }
+ if (sound) {
+ Sound *obj = (Sound *)Sound_empty();
+ if (obj) {
+ obj->sound = AUD_Sound_copy(sound);
+ return (PyObject *)obj;
+ }
+ }
+ }
+ }
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyMethodDef meth_sound_from_pointer[] = {
- {"_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
+ {"_sound_from_pointer",
+ (PyCFunction)AUD_getSoundFromPointer,
+ METH_O,
"_sound_from_pointer(pointer)\n\n"
"Returns the corresponding :class:`Factory` object.\n\n"
":arg pointer: The pointer to the bSound object as long.\n"
":type pointer: long\n"
":return: The corresponding :class:`Factory` object.\n"
- ":rtype: :class:`Factory`"}
-};
+ ":rtype: :class:`Factory`"}};
PyObject *AUD_initPython(void)
{
- PyObject *module = PyInit_aud();
- if (module == NULL) {
- printf("Unable to initialise audio\n");
- return NULL;
- }
+ PyObject *module = PyInit_aud();
+ if (module == NULL) {
+ printf("Unable to initialise audio\n");
+ return NULL;
+ }
- PyModule_AddObject(module, "_sound_from_pointer", (PyObject *)PyCFunction_New(meth_sound_from_pointer, NULL));
- PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
+ PyModule_AddObject(
+ module, "_sound_from_pointer", (PyObject *)PyCFunction_New(meth_sound_from_pointer, NULL));
+ PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
- return module;
+ return module;
}
-
diff --git a/intern/audaspace/intern/AUD_PyInit.h b/intern/audaspace/intern/AUD_PyInit.h
index 0c8cd85623c..e572ea1a27a 100644
--- a/intern/audaspace/intern/AUD_PyInit.h
+++ b/intern/audaspace/intern/AUD_PyInit.h
@@ -22,26 +22,25 @@
* \ingroup audaspaceintern
*/
-
#ifndef __AUD_PYINIT_H__
#define __AUD_PYINIT_H__
#ifdef WITH_PYTHON
-#include "Python.h"
+# include "Python.h"
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
/**
* Initializes the Python module.
*/
extern PyObject *AUD_initPython(void);
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
-#endif //__AUD_PYINIT_H__
+#endif //__AUD_PYINIT_H__
diff --git a/intern/audaspace/intern/AUD_Set.cpp b/intern/audaspace/intern/AUD_Set.cpp
index d65f5e34a5f..2ab576cbd07 100644
--- a/intern/audaspace/intern/AUD_Set.cpp
+++ b/intern/audaspace/intern/AUD_Set.cpp
@@ -28,38 +28,38 @@
void *AUD_createSet()
{
- return new std::set<void *>();
+ return new std::set<void *>();
}
void AUD_destroySet(void *set)
{
- delete reinterpret_cast<std::set<void *>*>(set);
+ delete reinterpret_cast<std::set<void *> *>(set);
}
char AUD_removeSet(void *set, void *entry)
{
- if (set)
- return reinterpret_cast<std::set<void *>*>(set)->erase(entry);
- return 0;
+ if (set)
+ return reinterpret_cast<std::set<void *> *>(set)->erase(entry);
+ return 0;
}
void AUD_addSet(void *set, void *entry)
{
- if (entry)
- reinterpret_cast<std::set<void *>*>(set)->insert(entry);
+ if (entry)
+ reinterpret_cast<std::set<void *> *>(set)->insert(entry);
}
void *AUD_getSet(void *set)
{
- if (set) {
- std::set<void *>* rset = reinterpret_cast<std::set<void *>*>(set);
- if (!rset->empty()) {
- std::set<void *>::iterator it = rset->begin();
- void *result = *it;
- rset->erase(it);
- return result;
- }
- }
+ if (set) {
+ std::set<void *> *rset = reinterpret_cast<std::set<void *> *>(set);
+ if (!rset->empty()) {
+ std::set<void *>::iterator it = rset->begin();
+ void *result = *it;
+ rset->erase(it);
+ return result;
+ }
+ }
- return (void*) 0;
+ return (void *)0;
}
diff --git a/intern/audaspace/intern/AUD_Set.h b/intern/audaspace/intern/AUD_Set.h
index e71383a4817..c2c7b7f40ce 100644
--- a/intern/audaspace/intern/AUD_Set.h
+++ b/intern/audaspace/intern/AUD_Set.h
@@ -21,7 +21,7 @@
/** \file
* \ingroup audaspace
*/
-
+
#ifndef __AUD_SET_H__
#define __AUD_SET_H__
@@ -67,4 +67,4 @@ extern void *AUD_getSet(void *set);
}
#endif
-#endif //__AUD_SET_H__
+#endif //__AUD_SET_H__
diff --git a/intern/clog/CLG_log.h b/intern/clog/CLG_log.h
index 810997ac78b..1d78c401924 100644
--- a/intern/clog/CLG_log.h
+++ b/intern/clog/CLG_log.h
@@ -73,13 +73,14 @@ extern "C" {
#endif /* __cplusplus */
#ifdef __GNUC__
-# define _CLOG_ATTR_NONNULL(args ...) __attribute__((nonnull(args)))
+# define _CLOG_ATTR_NONNULL(args...) __attribute__((nonnull(args)))
#else
# define _CLOG_ATTR_NONNULL(...)
#endif
#ifdef __GNUC__
-# define _CLOG_ATTR_PRINTF_FORMAT(format_param, dots_param) __attribute__((format(printf, format_param, dots_param)))
+# define _CLOG_ATTR_PRINTF_FORMAT(format_param, dots_param) \
+ __attribute__((format(printf, format_param, dots_param)))
#else
# define _CLOG_ATTR_PRINTF_FORMAT(format_param, dots_param)
#endif
@@ -92,41 +93,44 @@ struct CLogContext;
/* Don't typedef enums. */
enum CLG_LogFlag {
- CLG_FLAG_USE = (1 << 0),
+ CLG_FLAG_USE = (1 << 0),
};
enum CLG_Severity {
- CLG_SEVERITY_INFO = 0,
- CLG_SEVERITY_WARN,
- CLG_SEVERITY_ERROR,
- CLG_SEVERITY_FATAL,
+ CLG_SEVERITY_INFO = 0,
+ CLG_SEVERITY_WARN,
+ CLG_SEVERITY_ERROR,
+ CLG_SEVERITY_FATAL,
};
#define CLG_SEVERITY_LEN (CLG_SEVERITY_FATAL + 1)
/* Each logger ID has one of these. */
typedef struct CLG_LogType {
- struct CLG_LogType *next;
- char identifier[64];
- /** FILE output. */
- struct CLogContext *ctx;
- /** Control behavior. */
- int level;
- enum CLG_LogFlag flag;
+ struct CLG_LogType *next;
+ char identifier[64];
+ /** FILE output. */
+ struct CLogContext *ctx;
+ /** Control behavior. */
+ int level;
+ enum CLG_LogFlag flag;
} CLG_LogType;
typedef struct CLG_LogRef {
- const char *identifier;
- CLG_LogType *type;
+ const char *identifier;
+ CLG_LogType *type;
} CLG_LogRef;
-void CLG_log_str(
- CLG_LogType *lg, enum CLG_Severity severity, const char *file_line, const char *fn,
- const char *message)
- _CLOG_ATTR_NONNULL(1, 3, 4, 5);
-void CLG_logf(
- CLG_LogType *lg, enum CLG_Severity severity, const char *file_line, const char *fn,
- const char *format, ...)
- _CLOG_ATTR_NONNULL(1, 3, 4, 5) _CLOG_ATTR_PRINTF_FORMAT(5, 6);
+void CLG_log_str(CLG_LogType *lg,
+ enum CLG_Severity severity,
+ const char *file_line,
+ const char *fn,
+ const char *message) _CLOG_ATTR_NONNULL(1, 3, 4, 5);
+void CLG_logf(CLG_LogType *lg,
+ enum CLG_Severity severity,
+ const char *file_line,
+ const char *fn,
+ const char *format,
+ ...) _CLOG_ATTR_NONNULL(1, 3, 4, 5) _CLOG_ATTR_PRINTF_FORMAT(5, 6);
/* Main initializer and distructor (per session, not logger). */
void CLG_init(void);
@@ -147,51 +151,63 @@ void CLG_logref_init(CLG_LogRef *clg_ref);
/** Declare outside function, declare as extern in header. */
#define CLG_LOGREF_DECLARE_GLOBAL(var, id) \
- static CLG_LogRef _static_ ## var = {id}; \
- CLG_LogRef *var = &_static_ ## var
+ static CLG_LogRef _static_##var = {id}; \
+ CLG_LogRef *var = &_static_##var
/** Initialize struct once. */
#define CLOG_ENSURE(clg_ref) \
- ((clg_ref)->type ? (clg_ref)->type : (CLG_logref_init(clg_ref), (clg_ref)->type))
-
-#define CLOG_AT_SEVERITY(clg_ref, severity, verbose_level, ...) { \
- CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
- if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || (severity >= CLG_SEVERITY_WARN)) { \
- CLG_logf(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, __VA_ARGS__); \
- } \
-} ((void)0)
-
-#define CLOG_STR_AT_SEVERITY(clg_ref, severity, verbose_level, str) { \
- CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
- if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || (severity >= CLG_SEVERITY_WARN)) { \
- CLG_log_str(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, str); \
- } \
-} ((void)0)
-
-#define CLOG_STR_AT_SEVERITY_N(clg_ref, severity, verbose_level, str) { \
- CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
- if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || (severity >= CLG_SEVERITY_WARN)) { \
- const char *_str = str; \
- CLG_log_str(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, _str); \
- MEM_freeN((void *)_str); \
- } \
-} ((void)0)
-
-#define CLOG_INFO(clg_ref, level, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_INFO, level, __VA_ARGS__)
-#define CLOG_WARN(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_WARN, 0, __VA_ARGS__)
-#define CLOG_ERROR(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_ERROR, 0, __VA_ARGS__)
-#define CLOG_FATAL(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_FATAL, 0, __VA_ARGS__)
-
-#define CLOG_STR_INFO(clg_ref, level, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_INFO, level, str)
-#define CLOG_STR_WARN(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_WARN, 0, str)
-#define CLOG_STR_ERROR(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_ERROR, 0, str)
-#define CLOG_STR_FATAL(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_FATAL, 0, str)
+ ((clg_ref)->type ? (clg_ref)->type : (CLG_logref_init(clg_ref), (clg_ref)->type))
+
+#define CLOG_AT_SEVERITY(clg_ref, severity, verbose_level, ...) \
+ { \
+ CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
+ if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || \
+ (severity >= CLG_SEVERITY_WARN)) { \
+ CLG_logf(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, __VA_ARGS__); \
+ } \
+ } \
+ ((void)0)
+
+#define CLOG_STR_AT_SEVERITY(clg_ref, severity, verbose_level, str) \
+ { \
+ CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
+ if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || \
+ (severity >= CLG_SEVERITY_WARN)) { \
+ CLG_log_str(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, str); \
+ } \
+ } \
+ ((void)0)
+
+#define CLOG_STR_AT_SEVERITY_N(clg_ref, severity, verbose_level, str) \
+ { \
+ CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
+ if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || \
+ (severity >= CLG_SEVERITY_WARN)) { \
+ const char *_str = str; \
+ CLG_log_str(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, _str); \
+ MEM_freeN((void *)_str); \
+ } \
+ } \
+ ((void)0)
+
+#define CLOG_INFO(clg_ref, level, ...) \
+ CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_INFO, level, __VA_ARGS__)
+#define CLOG_WARN(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_WARN, 0, __VA_ARGS__)
+#define CLOG_ERROR(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_ERROR, 0, __VA_ARGS__)
+#define CLOG_FATAL(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_FATAL, 0, __VA_ARGS__)
+
+#define CLOG_STR_INFO(clg_ref, level, str) \
+ CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_INFO, level, str)
+#define CLOG_STR_WARN(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_WARN, 0, str)
+#define CLOG_STR_ERROR(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_ERROR, 0, str)
+#define CLOG_STR_FATAL(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_FATAL, 0, str)
/* Allocated string which is immediately freed. */
-#define CLOG_STR_INFO_N(clg_ref, level, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_INFO, level, str)
-#define CLOG_STR_WARN_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_WARN, 0, str)
-#define CLOG_STR_ERROR_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_ERROR, 0, str)
-#define CLOG_STR_FATAL_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_FATAL, 0, str)
+#define CLOG_STR_INFO_N(clg_ref, level, str) \
+ CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_INFO, level, str)
+#define CLOG_STR_WARN_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_WARN, 0, str)
+#define CLOG_STR_ERROR_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_ERROR, 0, str)
+#define CLOG_STR_FATAL_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_FATAL, 0, str)
#ifdef __cplusplus
}
diff --git a/intern/clog/CMakeLists.txt b/intern/clog/CMakeLists.txt
index 3ca9094dae6..41009642e3f 100644
--- a/intern/clog/CMakeLists.txt
+++ b/intern/clog/CMakeLists.txt
@@ -17,9 +17,9 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../atomic
- ../guardedalloc
+ .
+ ../atomic
+ ../guardedalloc
)
set(INC_SYS
@@ -27,9 +27,9 @@ set(INC_SYS
)
set(SRC
- clog.c
+ clog.c
- CLG_log.h
+ CLG_log.h
)
set(LIB
diff --git a/intern/clog/clog.c b/intern/clog/clog.c
index 4bc277f8ef2..ea6f215e8f0 100644
--- a/intern/clog/clog.c
+++ b/intern/clog/clog.c
@@ -46,7 +46,6 @@
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
-
/* Only other dependency (could use regular malloc too). */
#include "MEM_guardedalloc.h"
@@ -68,40 +67,40 @@
* \{ */
typedef struct CLG_IDFilter {
- struct CLG_IDFilter *next;
- /** Over alloc. */
- char match[0];
+ struct CLG_IDFilter *next;
+ /** Over alloc. */
+ char match[0];
} CLG_IDFilter;
typedef struct CLogContext {
- /** Single linked list of types. */
- CLG_LogType *types;
+ /** Single linked list of types. */
+ CLG_LogType *types;
#ifdef WITH_CLOG_PTHREADS
- pthread_mutex_t types_lock;
+ pthread_mutex_t types_lock;
#endif
- /* exclude, include filters. */
- CLG_IDFilter *filters[2];
- bool use_color;
- bool use_basename;
- bool use_timestamp;
+ /* exclude, include filters. */
+ CLG_IDFilter *filters[2];
+ bool use_color;
+ bool use_basename;
+ bool use_timestamp;
- /** Borrowed, not owned. */
- int output;
- FILE *output_file;
+ /** Borrowed, not owned. */
+ int output;
+ FILE *output_file;
- /** For timer (use_timestamp). */
- uint64_t timestamp_tick_start;
+ /** For timer (use_timestamp). */
+ uint64_t timestamp_tick_start;
- /** For new types. */
- struct {
- int level;
- } default_type;
+ /** For new types. */
+ struct {
+ int level;
+ } default_type;
- struct {
- void (*fatal_fn)(void *file_handle);
- void (*backtrace_fn)(void *file_handle);
- } callbacks;
+ struct {
+ void (*fatal_fn)(void *file_handle);
+ void (*backtrace_fn)(void *file_handle);
+ } callbacks;
} CLogContext;
/** \} */
@@ -115,92 +114,92 @@ typedef struct CLogContext {
#define CLOG_BUF_LEN_INIT 512
typedef struct CLogStringBuf {
- char *data;
- uint len;
- uint len_alloc;
- bool is_alloc;
+ char *data;
+ uint len;
+ uint len_alloc;
+ bool is_alloc;
} CLogStringBuf;
static void clg_str_init(CLogStringBuf *cstr, char *buf_stack, uint buf_stack_len)
{
- cstr->data = buf_stack;
- cstr->len_alloc = buf_stack_len;
- cstr->len = 0;
- cstr->is_alloc = false;
+ cstr->data = buf_stack;
+ cstr->len_alloc = buf_stack_len;
+ cstr->len = 0;
+ cstr->is_alloc = false;
}
static void clg_str_free(CLogStringBuf *cstr)
{
- if (cstr->is_alloc) {
- MEM_freeN(cstr->data);
- }
+ if (cstr->is_alloc) {
+ MEM_freeN(cstr->data);
+ }
}
static void clg_str_reserve(CLogStringBuf *cstr, const uint len)
{
- if (len > cstr->len_alloc) {
- cstr->len_alloc *= 2;
- if (len > cstr->len_alloc) {
- cstr->len_alloc = len;
- }
-
- if (cstr->is_alloc) {
- cstr->data = MEM_reallocN(cstr->data, cstr->len_alloc);
- }
- else {
- /* Copy the static buffer. */
- char *data = MEM_mallocN(cstr->len_alloc, __func__);
- memcpy(data, cstr->data, cstr->len);
- cstr->data = data;
- cstr->is_alloc = true;
- }
- cstr->len_alloc = len;
- }
+ if (len > cstr->len_alloc) {
+ cstr->len_alloc *= 2;
+ if (len > cstr->len_alloc) {
+ cstr->len_alloc = len;
+ }
+
+ if (cstr->is_alloc) {
+ cstr->data = MEM_reallocN(cstr->data, cstr->len_alloc);
+ }
+ else {
+ /* Copy the static buffer. */
+ char *data = MEM_mallocN(cstr->len_alloc, __func__);
+ memcpy(data, cstr->data, cstr->len);
+ cstr->data = data;
+ cstr->is_alloc = true;
+ }
+ cstr->len_alloc = len;
+ }
}
static void clg_str_append_with_len(CLogStringBuf *cstr, const char *str, const uint len)
{
- uint len_next = cstr->len + len;
- clg_str_reserve(cstr, len_next);
- char *str_dst = cstr->data + cstr->len;
- memcpy(str_dst, str, len);
+ uint len_next = cstr->len + len;
+ clg_str_reserve(cstr, len_next);
+ char *str_dst = cstr->data + cstr->len;
+ memcpy(str_dst, str, len);
#if 0 /* no need. */
- str_dst[len] = '\0';
+ str_dst[len] = '\0';
#endif
- cstr->len = len_next;
+ cstr->len = len_next;
}
static void clg_str_append(CLogStringBuf *cstr, const char *str)
{
- clg_str_append_with_len(cstr, str, strlen(str));
+ clg_str_append_with_len(cstr, str, strlen(str));
}
static void clg_str_vappendf(CLogStringBuf *cstr, const char *fmt, va_list args)
{
- /* Use limit because windows may use '-1' for a formatting error. */
- const uint len_max = 65535;
- uint len_avail = (cstr->len_alloc - cstr->len);
- if (len_avail == 0) {
- len_avail = CLOG_BUF_LEN_INIT;
- clg_str_reserve(cstr, len_avail);
- }
- while (true) {
- va_list args_cpy;
- va_copy(args_cpy, args);
- int retval = vsnprintf(cstr->data + cstr->len, len_avail, fmt, args_cpy);
- va_end(args_cpy);
- if (retval != -1) {
- cstr->len += retval;
- break;
- }
- else {
- len_avail *= 2;
- if (len_avail >= len_max) {
- break;
- }
- clg_str_reserve(cstr, len_avail);
- }
- }
+ /* Use limit because windows may use '-1' for a formatting error. */
+ const uint len_max = 65535;
+ uint len_avail = (cstr->len_alloc - cstr->len);
+ if (len_avail == 0) {
+ len_avail = CLOG_BUF_LEN_INIT;
+ clg_str_reserve(cstr, len_avail);
+ }
+ while (true) {
+ va_list args_cpy;
+ va_copy(args_cpy, args);
+ int retval = vsnprintf(cstr->data + cstr->len, len_avail, fmt, args_cpy);
+ va_end(args_cpy);
+ if (retval != -1) {
+ cstr->len += retval;
+ break;
+ }
+ else {
+ len_avail *= 2;
+ if (len_avail >= len_max) {
+ break;
+ }
+ clg_str_reserve(cstr, len_avail);
+ }
+ }
}
/** \} */
@@ -210,12 +209,12 @@ static void clg_str_vappendf(CLogStringBuf *cstr, const char *fmt, va_list args)
* \{ */
enum eCLogColor {
- COLOR_DEFAULT,
- COLOR_RED,
- COLOR_GREEN,
- COLOR_YELLOW,
+ COLOR_DEFAULT,
+ COLOR_RED,
+ COLOR_GREEN,
+ COLOR_YELLOW,
- COLOR_RESET,
+ COLOR_RESET,
};
#define COLOR_LEN (COLOR_RESET + 1)
@@ -223,61 +222,61 @@ static const char *clg_color_table[COLOR_LEN] = {NULL};
static void clg_color_table_init(bool use_color)
{
- for (int i = 0; i < COLOR_LEN; i++) {
- clg_color_table[i] = "";
- }
- if (use_color) {
+ for (int i = 0; i < COLOR_LEN; i++) {
+ clg_color_table[i] = "";
+ }
+ if (use_color) {
#ifdef _WIN32
- /* TODO */
+ /* TODO */
#else
- clg_color_table[COLOR_DEFAULT] = "\033[1;37m";
- clg_color_table[COLOR_RED] = "\033[1;31m";
- clg_color_table[COLOR_GREEN] = "\033[1;32m";
- clg_color_table[COLOR_YELLOW] = "\033[1;33m";
- clg_color_table[COLOR_RESET] = "\033[0m";
+ clg_color_table[COLOR_DEFAULT] = "\033[1;37m";
+ clg_color_table[COLOR_RED] = "\033[1;31m";
+ clg_color_table[COLOR_GREEN] = "\033[1;32m";
+ clg_color_table[COLOR_YELLOW] = "\033[1;33m";
+ clg_color_table[COLOR_RESET] = "\033[0m";
#endif
- }
+ }
}
static const char *clg_severity_str[CLG_SEVERITY_LEN] = {
- [CLG_SEVERITY_INFO] = "INFO",
- [CLG_SEVERITY_WARN] = "WARN",
- [CLG_SEVERITY_ERROR] = "ERROR",
- [CLG_SEVERITY_FATAL] = "FATAL",
+ [CLG_SEVERITY_INFO] = "INFO",
+ [CLG_SEVERITY_WARN] = "WARN",
+ [CLG_SEVERITY_ERROR] = "ERROR",
+ [CLG_SEVERITY_FATAL] = "FATAL",
};
static const char *clg_severity_as_text(enum CLG_Severity severity)
{
- bool ok = (unsigned int)severity < CLG_SEVERITY_LEN;
- assert(ok);
- if (ok) {
- return clg_severity_str[severity];
- }
- else {
- return "INVALID_SEVERITY";
- }
+ bool ok = (unsigned int)severity < CLG_SEVERITY_LEN;
+ assert(ok);
+ if (ok) {
+ return clg_severity_str[severity];
+ }
+ else {
+ return "INVALID_SEVERITY";
+ }
}
static enum eCLogColor clg_severity_to_color(enum CLG_Severity severity)
{
- assert((unsigned int)severity < CLG_SEVERITY_LEN);
- enum eCLogColor color = COLOR_DEFAULT;
- switch (severity) {
- case CLG_SEVERITY_INFO:
- color = COLOR_DEFAULT;
- break;
- case CLG_SEVERITY_WARN:
- color = COLOR_YELLOW;
- break;
- case CLG_SEVERITY_ERROR:
- case CLG_SEVERITY_FATAL:
- color = COLOR_RED;
- break;
- default:
- /* should never get here. */
- assert(false);
- }
- return color;
+ assert((unsigned int)severity < CLG_SEVERITY_LEN);
+ enum eCLogColor color = COLOR_DEFAULT;
+ switch (severity) {
+ case CLG_SEVERITY_INFO:
+ color = COLOR_DEFAULT;
+ break;
+ case CLG_SEVERITY_WARN:
+ color = COLOR_YELLOW;
+ break;
+ case CLG_SEVERITY_ERROR:
+ case CLG_SEVERITY_FATAL:
+ color = COLOR_RED;
+ break;
+ default:
+ /* should never get here. */
+ assert(false);
+ }
+ return color;
}
/** \} */
@@ -295,27 +294,24 @@ static enum eCLogColor clg_severity_to_color(enum CLG_Severity severity)
*/
static bool clg_ctx_filter_check(CLogContext *ctx, const char *identifier)
{
- const int identifier_len = strlen(identifier);
- for (uint i = 0; i < 2; i++) {
- const CLG_IDFilter *flt = ctx->filters[i];
- while (flt != NULL) {
- const int len = strlen(flt->match);
- if (STREQ(flt->match, "*") ||
- ((len == identifier_len) && (STREQ(identifier, flt->match))))
- {
- return (bool)i;
- }
- if ((len >= 2) && (STREQLEN(".*", &flt->match[len - 2], 2))) {
- if (((identifier_len == len - 2) && STREQLEN(identifier, flt->match, len - 2)) ||
- ((identifier_len >= len - 1) && STREQLEN(identifier, flt->match, len - 1)))
- {
- return (bool)i;
- }
- }
- flt = flt->next;
- }
- }
- return false;
+ const int identifier_len = strlen(identifier);
+ for (uint i = 0; i < 2; i++) {
+ const CLG_IDFilter *flt = ctx->filters[i];
+ while (flt != NULL) {
+ const int len = strlen(flt->match);
+ if (STREQ(flt->match, "*") || ((len == identifier_len) && (STREQ(identifier, flt->match)))) {
+ return (bool)i;
+ }
+ if ((len >= 2) && (STREQLEN(".*", &flt->match[len - 2], 2))) {
+ if (((identifier_len == len - 2) && STREQLEN(identifier, flt->match, len - 2)) ||
+ ((identifier_len >= len - 1) && STREQLEN(identifier, flt->match, len - 1))) {
+ return (bool)i;
+ }
+ }
+ flt = flt->next;
+ }
+ }
+ return false;
}
/**
@@ -324,58 +320,58 @@ static bool clg_ctx_filter_check(CLogContext *ctx, const char *identifier)
*/
static CLG_LogType *clg_ctx_type_find_by_name(CLogContext *ctx, const char *identifier)
{
- for (CLG_LogType *ty = ctx->types; ty; ty = ty->next) {
- if (STREQ(identifier, ty->identifier)) {
- return ty;
- }
- }
- return NULL;
+ for (CLG_LogType *ty = ctx->types; ty; ty = ty->next) {
+ if (STREQ(identifier, ty->identifier)) {
+ return ty;
+ }
+ }
+ return NULL;
}
static CLG_LogType *clg_ctx_type_register(CLogContext *ctx, const char *identifier)
{
- assert(clg_ctx_type_find_by_name(ctx, identifier) == NULL);
- CLG_LogType *ty = MEM_callocN(sizeof(*ty), __func__);
- ty->next = ctx->types;
- ctx->types = ty;
- strncpy(ty->identifier, identifier, sizeof(ty->identifier) - 1);
- ty->ctx = ctx;
- ty->level = ctx->default_type.level;
+ assert(clg_ctx_type_find_by_name(ctx, identifier) == NULL);
+ CLG_LogType *ty = MEM_callocN(sizeof(*ty), __func__);
+ ty->next = ctx->types;
+ ctx->types = ty;
+ strncpy(ty->identifier, identifier, sizeof(ty->identifier) - 1);
+ ty->ctx = ctx;
+ ty->level = ctx->default_type.level;
- if (clg_ctx_filter_check(ctx, ty->identifier)) {
- ty->flag |= CLG_FLAG_USE;
- }
- return ty;
+ if (clg_ctx_filter_check(ctx, ty->identifier)) {
+ ty->flag |= CLG_FLAG_USE;
+ }
+ return ty;
}
static void clg_ctx_fatal_action(CLogContext *ctx)
{
- if (ctx->callbacks.fatal_fn != NULL) {
- ctx->callbacks.fatal_fn(ctx->output_file);
- }
- fflush(ctx->output_file);
- abort();
+ if (ctx->callbacks.fatal_fn != NULL) {
+ ctx->callbacks.fatal_fn(ctx->output_file);
+ }
+ fflush(ctx->output_file);
+ abort();
}
static void clg_ctx_backtrace(CLogContext *ctx)
{
- /* Note: we avoid writing fo 'FILE', for backtrace we make an exception,
- * if necessary we could have a version of the callback that writes to file descriptor all at once. */
- ctx->callbacks.backtrace_fn(ctx->output_file);
- fflush(ctx->output_file);
+ /* Note: we avoid writing fo 'FILE', for backtrace we make an exception,
+ * if necessary we could have a version of the callback that writes to file descriptor all at once. */
+ ctx->callbacks.backtrace_fn(ctx->output_file);
+ fflush(ctx->output_file);
}
static uint64_t clg_timestamp_ticks_get(void)
{
- uint64_t tick;
+ uint64_t tick;
#if defined(_MSC_VER)
- tick = GetTickCount64();
+ tick = GetTickCount64();
#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- tick = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ tick = tv.tv_sec * 1000 + tv.tv_usec / 1000;
#endif
- return tick;
+ return tick;
}
/** \} */
@@ -386,131 +382,140 @@ static uint64_t clg_timestamp_ticks_get(void)
static void write_timestamp(CLogStringBuf *cstr, const uint64_t timestamp_tick_start)
{
- char timestamp_str[64];
- const uint64_t timestamp = clg_timestamp_ticks_get() - timestamp_tick_start;
- const uint timestamp_len = snprintf(
- timestamp_str, sizeof(timestamp_str), "%" PRIu64 ".%03u ",
- timestamp / 1000, (uint)(timestamp % 1000));
- clg_str_append_with_len(cstr, timestamp_str, timestamp_len);
+ char timestamp_str[64];
+ const uint64_t timestamp = clg_timestamp_ticks_get() - timestamp_tick_start;
+ const uint timestamp_len = snprintf(timestamp_str,
+ sizeof(timestamp_str),
+ "%" PRIu64 ".%03u ",
+ timestamp / 1000,
+ (uint)(timestamp % 1000));
+ clg_str_append_with_len(cstr, timestamp_str, timestamp_len);
}
static void write_severity(CLogStringBuf *cstr, enum CLG_Severity severity, bool use_color)
{
- assert((unsigned int)severity < CLG_SEVERITY_LEN);
- if (use_color) {
- enum eCLogColor color = clg_severity_to_color(severity);
- clg_str_append(cstr, clg_color_table[color]);
- clg_str_append(cstr, clg_severity_as_text(severity));
- clg_str_append(cstr, clg_color_table[COLOR_RESET]);
- }
- else {
- clg_str_append(cstr, clg_severity_as_text(severity));
- }
+ assert((unsigned int)severity < CLG_SEVERITY_LEN);
+ if (use_color) {
+ enum eCLogColor color = clg_severity_to_color(severity);
+ clg_str_append(cstr, clg_color_table[color]);
+ clg_str_append(cstr, clg_severity_as_text(severity));
+ clg_str_append(cstr, clg_color_table[COLOR_RESET]);
+ }
+ else {
+ clg_str_append(cstr, clg_severity_as_text(severity));
+ }
}
static void write_type(CLogStringBuf *cstr, CLG_LogType *lg)
{
- clg_str_append(cstr, " (");
- clg_str_append(cstr, lg->identifier);
- clg_str_append(cstr, "): ");
-}
+ clg_str_append(cstr, " (");
+ clg_str_append(cstr, lg->identifier);
+ clg_str_append(cstr, "): ");
+}
-static void write_file_line_fn(CLogStringBuf *cstr, const char *file_line, const char *fn, const bool use_basename)
+static void write_file_line_fn(CLogStringBuf *cstr,
+ const char *file_line,
+ const char *fn,
+ const bool use_basename)
{
- uint file_line_len = strlen(file_line);
- if (use_basename) {
- uint file_line_offset = file_line_len;
- while (file_line_offset-- > 0) {
- if (file_line[file_line_offset] == PATHSEP_CHAR) {
- file_line_offset++;
- break;
- }
- }
- file_line += file_line_offset;
- file_line_len -= file_line_offset;
- }
- clg_str_append_with_len(cstr, file_line, file_line_len);
+ uint file_line_len = strlen(file_line);
+ if (use_basename) {
+ uint file_line_offset = file_line_len;
+ while (file_line_offset-- > 0) {
+ if (file_line[file_line_offset] == PATHSEP_CHAR) {
+ file_line_offset++;
+ break;
+ }
+ }
+ file_line += file_line_offset;
+ file_line_len -= file_line_offset;
+ }
+ clg_str_append_with_len(cstr, file_line, file_line_len);
-
- clg_str_append(cstr, " ");
- clg_str_append(cstr, fn);
- clg_str_append(cstr, ": ");
+ clg_str_append(cstr, " ");
+ clg_str_append(cstr, fn);
+ clg_str_append(cstr, ": ");
}
-void CLG_log_str(
- CLG_LogType *lg, enum CLG_Severity severity, const char *file_line, const char *fn,
- const char *message)
+void CLG_log_str(CLG_LogType *lg,
+ enum CLG_Severity severity,
+ const char *file_line,
+ const char *fn,
+ const char *message)
{
- CLogStringBuf cstr;
- char cstr_stack_buf[CLOG_BUF_LEN_INIT];
- clg_str_init(&cstr, cstr_stack_buf, sizeof(cstr_stack_buf));
+ CLogStringBuf cstr;
+ char cstr_stack_buf[CLOG_BUF_LEN_INIT];
+ clg_str_init(&cstr, cstr_stack_buf, sizeof(cstr_stack_buf));
- if (lg->ctx->use_timestamp) {
- write_timestamp(&cstr, lg->ctx->timestamp_tick_start);
- }
+ if (lg->ctx->use_timestamp) {
+ write_timestamp(&cstr, lg->ctx->timestamp_tick_start);
+ }
- write_severity(&cstr, severity, lg->ctx->use_color);
- write_type(&cstr, lg);
+ write_severity(&cstr, severity, lg->ctx->use_color);
+ write_type(&cstr, lg);
- {
- write_file_line_fn(&cstr, file_line, fn, lg->ctx->use_basename);
- clg_str_append(&cstr, message);
- }
- clg_str_append(&cstr, "\n");
+ {
+ write_file_line_fn(&cstr, file_line, fn, lg->ctx->use_basename);
+ clg_str_append(&cstr, message);
+ }
+ clg_str_append(&cstr, "\n");
- /* could be optional */
- int bytes_written = write(lg->ctx->output, cstr.data, cstr.len);
- (void)bytes_written;
+ /* could be optional */
+ int bytes_written = write(lg->ctx->output, cstr.data, cstr.len);
+ (void)bytes_written;
- clg_str_free(&cstr);
+ clg_str_free(&cstr);
- if (lg->ctx->callbacks.backtrace_fn) {
- clg_ctx_backtrace(lg->ctx);
- }
+ if (lg->ctx->callbacks.backtrace_fn) {
+ clg_ctx_backtrace(lg->ctx);
+ }
- if (severity == CLG_SEVERITY_FATAL) {
- clg_ctx_fatal_action(lg->ctx);
- }
+ if (severity == CLG_SEVERITY_FATAL) {
+ clg_ctx_fatal_action(lg->ctx);
+ }
}
-void CLG_logf(
- CLG_LogType *lg, enum CLG_Severity severity, const char *file_line, const char *fn,
- const char *fmt, ...)
+void CLG_logf(CLG_LogType *lg,
+ enum CLG_Severity severity,
+ const char *file_line,
+ const char *fn,
+ const char *fmt,
+ ...)
{
- CLogStringBuf cstr;
- char cstr_stack_buf[CLOG_BUF_LEN_INIT];
- clg_str_init(&cstr, cstr_stack_buf, sizeof(cstr_stack_buf));
+ CLogStringBuf cstr;
+ char cstr_stack_buf[CLOG_BUF_LEN_INIT];
+ clg_str_init(&cstr, cstr_stack_buf, sizeof(cstr_stack_buf));
- if (lg->ctx->use_timestamp) {
- write_timestamp(&cstr, lg->ctx->timestamp_tick_start);
- }
+ if (lg->ctx->use_timestamp) {
+ write_timestamp(&cstr, lg->ctx->timestamp_tick_start);
+ }
- write_severity(&cstr, severity, lg->ctx->use_color);
- write_type(&cstr, lg);
+ write_severity(&cstr, severity, lg->ctx->use_color);
+ write_type(&cstr, lg);
- {
- write_file_line_fn(&cstr, file_line, fn, lg->ctx->use_basename);
+ {
+ write_file_line_fn(&cstr, file_line, fn, lg->ctx->use_basename);
- va_list ap;
- va_start(ap, fmt);
- clg_str_vappendf(&cstr, fmt, ap);
- va_end(ap);
- }
- clg_str_append(&cstr, "\n");
+ va_list ap;
+ va_start(ap, fmt);
+ clg_str_vappendf(&cstr, fmt, ap);
+ va_end(ap);
+ }
+ clg_str_append(&cstr, "\n");
- /* could be optional */
- int bytes_written = write(lg->ctx->output, cstr.data, cstr.len);
- (void)bytes_written;
+ /* could be optional */
+ int bytes_written = write(lg->ctx->output, cstr.data, cstr.len);
+ (void)bytes_written;
- clg_str_free(&cstr);
+ clg_str_free(&cstr);
- if (lg->ctx->callbacks.backtrace_fn) {
- clg_ctx_backtrace(lg->ctx);
- }
+ if (lg->ctx->callbacks.backtrace_fn) {
+ clg_ctx_backtrace(lg->ctx);
+ }
- if (severity == CLG_SEVERITY_FATAL) {
- clg_ctx_fatal_action(lg->ctx);
- }
+ if (severity == CLG_SEVERITY_FATAL) {
+ clg_ctx_fatal_action(lg->ctx);
+ }
}
/** \} */
@@ -521,99 +526,105 @@ void CLG_logf(
static void CLG_ctx_output_set(CLogContext *ctx, void *file_handle)
{
- ctx->output_file = file_handle;
- ctx->output = fileno(ctx->output_file);
+ ctx->output_file = file_handle;
+ ctx->output = fileno(ctx->output_file);
#if defined(__unix__) || defined(__APPLE__)
- ctx->use_color = isatty(ctx->output);
+ ctx->use_color = isatty(ctx->output);
#endif
}
static void CLG_ctx_output_use_basename_set(CLogContext *ctx, int value)
{
- ctx->use_basename = (bool)value;
+ ctx->use_basename = (bool)value;
}
static void CLG_ctx_output_use_timestamp_set(CLogContext *ctx, int value)
{
- ctx->use_timestamp = (bool)value;
- if (ctx->use_timestamp) {
- ctx->timestamp_tick_start = clg_timestamp_ticks_get();
- }
+ ctx->use_timestamp = (bool)value;
+ if (ctx->use_timestamp) {
+ ctx->timestamp_tick_start = clg_timestamp_ticks_get();
+ }
}
/** Action on fatal severity. */
static void CLG_ctx_fatal_fn_set(CLogContext *ctx, void (*fatal_fn)(void *file_handle))
{
- ctx->callbacks.fatal_fn = fatal_fn;
+ ctx->callbacks.fatal_fn = fatal_fn;
}
static void CLG_ctx_backtrace_fn_set(CLogContext *ctx, void (*backtrace_fn)(void *file_handle))
{
- ctx->callbacks.backtrace_fn = backtrace_fn;
+ ctx->callbacks.backtrace_fn = backtrace_fn;
}
-static void clg_ctx_type_filter_append(CLG_IDFilter **flt_list, const char *type_match, int type_match_len)
+static void clg_ctx_type_filter_append(CLG_IDFilter **flt_list,
+ const char *type_match,
+ int type_match_len)
{
- if (type_match_len == 0) {
- return;
- }
- CLG_IDFilter *flt = MEM_callocN(sizeof(*flt) + (type_match_len + 1), __func__);
- flt->next = *flt_list;
- *flt_list = flt;
- memcpy(flt->match, type_match, type_match_len);
- /* no need to null terminate since we calloc'd */
+ if (type_match_len == 0) {
+ return;
+ }
+ CLG_IDFilter *flt = MEM_callocN(sizeof(*flt) + (type_match_len + 1), __func__);
+ flt->next = *flt_list;
+ *flt_list = flt;
+ memcpy(flt->match, type_match, type_match_len);
+ /* no need to null terminate since we calloc'd */
}
-static void CLG_ctx_type_filter_exclude(CLogContext *ctx, const char *type_match, int type_match_len)
+static void CLG_ctx_type_filter_exclude(CLogContext *ctx,
+ const char *type_match,
+ int type_match_len)
{
- clg_ctx_type_filter_append(&ctx->filters[0], type_match, type_match_len);
+ clg_ctx_type_filter_append(&ctx->filters[0], type_match, type_match_len);
}
-static void CLG_ctx_type_filter_include(CLogContext *ctx, const char *type_match, int type_match_len)
+static void CLG_ctx_type_filter_include(CLogContext *ctx,
+ const char *type_match,
+ int type_match_len)
{
- clg_ctx_type_filter_append(&ctx->filters[1], type_match, type_match_len);
+ clg_ctx_type_filter_append(&ctx->filters[1], type_match, type_match_len);
}
static void CLG_ctx_level_set(CLogContext *ctx, int level)
{
- ctx->default_type.level = level;
- for (CLG_LogType *ty = ctx->types; ty; ty = ty->next) {
- ty->level = level;
- }
+ ctx->default_type.level = level;
+ for (CLG_LogType *ty = ctx->types; ty; ty = ty->next) {
+ ty->level = level;
+ }
}
static CLogContext *CLG_ctx_init(void)
{
- CLogContext *ctx = MEM_callocN(sizeof(*ctx), __func__);
+ CLogContext *ctx = MEM_callocN(sizeof(*ctx), __func__);
#ifdef WITH_CLOG_PTHREADS
- pthread_mutex_init(&ctx->types_lock, NULL);
+ pthread_mutex_init(&ctx->types_lock, NULL);
#endif
- ctx->use_color = true;
- ctx->default_type.level = 1;
- CLG_ctx_output_set(ctx, stdout);
+ ctx->use_color = true;
+ ctx->default_type.level = 1;
+ CLG_ctx_output_set(ctx, stdout);
- return ctx;
+ return ctx;
}
static void CLG_ctx_free(CLogContext *ctx)
{
- while (ctx->types != NULL) {
- CLG_LogType *item = ctx->types;
- ctx->types = item->next;
- MEM_freeN(item);
- }
-
- for (uint i = 0; i < 2; i++) {
- while (ctx->filters[i] != NULL) {
- CLG_IDFilter *item = ctx->filters[i];
- ctx->filters[i] = item->next;
- MEM_freeN(item);
- }
- }
+ while (ctx->types != NULL) {
+ CLG_LogType *item = ctx->types;
+ ctx->types = item->next;
+ MEM_freeN(item);
+ }
+
+ for (uint i = 0; i < 2; i++) {
+ while (ctx->filters[i] != NULL) {
+ CLG_IDFilter *item = ctx->filters[i];
+ ctx->filters[i] = item->next;
+ MEM_freeN(item);
+ }
+ }
#ifdef WITH_CLOG_PTHREADS
- pthread_mutex_destroy(&ctx->types_lock);
+ pthread_mutex_destroy(&ctx->types_lock);
#endif
- MEM_freeN(ctx);
+ MEM_freeN(ctx);
}
/** \} */
@@ -629,57 +640,56 @@ static struct CLogContext *g_ctx = NULL;
void CLG_init(void)
{
- g_ctx = CLG_ctx_init();
+ g_ctx = CLG_ctx_init();
- clg_color_table_init(g_ctx->use_color);
+ clg_color_table_init(g_ctx->use_color);
}
void CLG_exit(void)
{
- CLG_ctx_free(g_ctx);
+ CLG_ctx_free(g_ctx);
}
void CLG_output_set(void *file_handle)
{
- CLG_ctx_output_set(g_ctx, file_handle);
+ CLG_ctx_output_set(g_ctx, file_handle);
}
void CLG_output_use_basename_set(int value)
{
- CLG_ctx_output_use_basename_set(g_ctx, value);
+ CLG_ctx_output_use_basename_set(g_ctx, value);
}
void CLG_output_use_timestamp_set(int value)
{
- CLG_ctx_output_use_timestamp_set(g_ctx, value);
+ CLG_ctx_output_use_timestamp_set(g_ctx, value);
}
void CLG_fatal_fn_set(void (*fatal_fn)(void *file_handle))
{
- CLG_ctx_fatal_fn_set(g_ctx, fatal_fn);
+ CLG_ctx_fatal_fn_set(g_ctx, fatal_fn);
}
void CLG_backtrace_fn_set(void (*fatal_fn)(void *file_handle))
{
- CLG_ctx_backtrace_fn_set(g_ctx, fatal_fn);
+ CLG_ctx_backtrace_fn_set(g_ctx, fatal_fn);
}
void CLG_type_filter_exclude(const char *type_match, int type_match_len)
{
- CLG_ctx_type_filter_exclude(g_ctx, type_match, type_match_len);
+ CLG_ctx_type_filter_exclude(g_ctx, type_match, type_match_len);
}
void CLG_type_filter_include(const char *type_match, int type_match_len)
{
- CLG_ctx_type_filter_include(g_ctx, type_match, type_match_len);
+ CLG_ctx_type_filter_include(g_ctx, type_match, type_match_len);
}
void CLG_level_set(int level)
{
- CLG_ctx_level_set(g_ctx, level);
+ CLG_ctx_level_set(g_ctx, level);
}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -690,22 +700,22 @@ void CLG_level_set(int level)
void CLG_logref_init(CLG_LogRef *clg_ref)
{
#ifdef WITH_CLOG_PTHREADS
- /* Only runs once when initializing a static type in most cases. */
- pthread_mutex_lock(&g_ctx->types_lock);
+ /* Only runs once when initializing a static type in most cases. */
+ pthread_mutex_lock(&g_ctx->types_lock);
#endif
- if (clg_ref->type == NULL) {
- CLG_LogType *clg_ty = clg_ctx_type_find_by_name(g_ctx, clg_ref->identifier);
- if (clg_ty == NULL) {
- clg_ty = clg_ctx_type_register(g_ctx, clg_ref->identifier);
- }
+ if (clg_ref->type == NULL) {
+ CLG_LogType *clg_ty = clg_ctx_type_find_by_name(g_ctx, clg_ref->identifier);
+ if (clg_ty == NULL) {
+ clg_ty = clg_ctx_type_register(g_ctx, clg_ref->identifier);
+ }
#ifdef WITH_CLOG_PTHREADS
- atomic_cas_ptr((void **)&clg_ref->type, clg_ref->type, clg_ty);
+ atomic_cas_ptr((void **)&clg_ref->type, clg_ref->type, clg_ty);
#else
- clg_ref->type = clg_ty;
+ clg_ref->type = clg_ty;
#endif
- }
+ }
#ifdef WITH_CLOG_PTHREADS
- pthread_mutex_unlock(&g_ctx->types_lock);
+ pthread_mutex_unlock(&g_ctx->types_lock);
#endif
}
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index d4a613a78c7..87f88f7ed34 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -1,16 +1,16 @@
# Standalone or with Blender
if(NOT WITH_BLENDER AND WITH_CYCLES_STANDALONE)
- set(CYCLES_INSTALL_PATH "")
+ set(CYCLES_INSTALL_PATH "")
else()
- set(WITH_CYCLES_BLENDER ON)
- # WINDOWS_PYTHON_DEBUG needs to write into the user addons folder since it will
- # be started with --env-system-scripts pointing to the release folder, which will
- # lack the cycles addon, and we don't want to write into it.
- if(NOT WINDOWS_PYTHON_DEBUG)
- set(CYCLES_INSTALL_PATH "scripts/addons/cycles")
- else()
- set(CYCLES_INSTALL_PATH "$ENV{appdata}/blender foundation/blender/${BLENDER_VERSION}/scripts/addons/cycles")
- endif()
+ set(WITH_CYCLES_BLENDER ON)
+ # WINDOWS_PYTHON_DEBUG needs to write into the user addons folder since it will
+ # be started with --env-system-scripts pointing to the release folder, which will
+ # lack the cycles addon, and we don't want to write into it.
+ if(NOT WINDOWS_PYTHON_DEBUG)
+ set(CYCLES_INSTALL_PATH "scripts/addons/cycles")
+ else()
+ set(CYCLES_INSTALL_PATH "$ENV{appdata}/blender foundation/blender/${BLENDER_VERSION}/scripts/addons/cycles")
+ endif()
endif()
# External Libraries
@@ -23,329 +23,329 @@ include(cmake/macros.cmake)
# note: CXX_HAS_SSE is needed in case passing SSE flags fails altogether (gcc-arm)
if(WITH_CYCLES_NATIVE_ONLY)
- set(CXX_HAS_SSE FALSE)
- set(CXX_HAS_AVX FALSE)
- set(CXX_HAS_AVX2 FALSE)
- add_definitions(
- -DWITH_KERNEL_NATIVE
- )
-
- if(NOT MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
- set(CYCLES_KERNEL_FLAGS "-march=native")
- endif()
+ set(CXX_HAS_SSE FALSE)
+ set(CXX_HAS_AVX FALSE)
+ set(CXX_HAS_AVX2 FALSE)
+ add_definitions(
+ -DWITH_KERNEL_NATIVE
+ )
+
+ if(NOT MSVC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
+ set(CYCLES_KERNEL_FLAGS "-march=native")
+ endif()
elseif(NOT WITH_CPU_SSE)
- set(CXX_HAS_SSE FALSE)
- set(CXX_HAS_AVX FALSE)
- set(CXX_HAS_AVX2 FALSE)
+ set(CXX_HAS_SSE FALSE)
+ set(CXX_HAS_AVX FALSE)
+ set(CXX_HAS_AVX2 FALSE)
elseif(WIN32 AND MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- set(CXX_HAS_SSE TRUE)
- set(CXX_HAS_AVX TRUE)
- set(CXX_HAS_AVX2 TRUE)
-
- # /arch:AVX for VC2012 and above
- if(NOT MSVC_VERSION LESS 1700)
- set(CYCLES_AVX_ARCH_FLAGS "/arch:AVX")
- set(CYCLES_AVX2_ARCH_FLAGS "/arch:AVX /arch:AVX2")
- elseif(NOT CMAKE_CL_64)
- set(CYCLES_AVX_ARCH_FLAGS "/arch:SSE2")
- set(CYCLES_AVX2_ARCH_FLAGS "/arch:SSE2")
- endif()
-
- # Unlike GCC/clang we still use fast math, because there is no fine
- # grained control and the speedup we get here is too big to ignore.
- set(CYCLES_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
-
- # there is no /arch:SSE3, but intrinsics are available anyway
- if(CMAKE_CL_64)
- set(CYCLES_SSE2_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_SSE3_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_SSE41_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_AVX2_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
- else()
- set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_SSE41_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
- set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_AVX2_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
- endif()
-
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CYCLES_KERNEL_FLAGS}")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox")
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox")
- set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /Ox")
+ set(CXX_HAS_SSE TRUE)
+ set(CXX_HAS_AVX TRUE)
+ set(CXX_HAS_AVX2 TRUE)
+
+ # /arch:AVX for VC2012 and above
+ if(NOT MSVC_VERSION LESS 1700)
+ set(CYCLES_AVX_ARCH_FLAGS "/arch:AVX")
+ set(CYCLES_AVX2_ARCH_FLAGS "/arch:AVX /arch:AVX2")
+ elseif(NOT CMAKE_CL_64)
+ set(CYCLES_AVX_ARCH_FLAGS "/arch:SSE2")
+ set(CYCLES_AVX2_ARCH_FLAGS "/arch:SSE2")
+ endif()
+
+ # Unlike GCC/clang we still use fast math, because there is no fine
+ # grained control and the speedup we get here is too big to ignore.
+ set(CYCLES_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
+
+ # there is no /arch:SSE3, but intrinsics are available anyway
+ if(CMAKE_CL_64)
+ set(CYCLES_SSE2_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_SSE3_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_SSE41_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_AVX2_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
+ else()
+ set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_SSE41_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
+ set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_AVX2_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}")
+ endif()
+
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CYCLES_KERNEL_FLAGS}")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox")
+ set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /Ox")
elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
- check_cxx_compiler_flag(-msse CXX_HAS_SSE)
- check_cxx_compiler_flag(-mavx CXX_HAS_AVX)
- check_cxx_compiler_flag(-mavx2 CXX_HAS_AVX2)
-
- # Assume no signal trapping for better code generation.
- set(CYCLES_KERNEL_FLAGS "-fno-trapping-math")
- # Avoid overhead of setting errno for NaNs.
- set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-math-errno")
- # Let compiler optimize 0.0 - x without worrying about signed zeros.
- set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-signed-zeros")
-
- if(CMAKE_COMPILER_IS_GNUCC)
- # Assume no signal trapping for better code generation.
- set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-signaling-nans")
- # Assume a fixed rounding mode for better constant folding.
- set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-rounding-math")
- endif()
-
- if(CXX_HAS_SSE)
- if(CMAKE_COMPILER_IS_GNUCC)
- set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -mfpmath=sse")
- endif()
-
- set(CYCLES_SSE2_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -msse -msse2")
- set(CYCLES_SSE3_KERNEL_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS} -msse3 -mssse3")
- set(CYCLES_SSE41_KERNEL_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS} -msse4.1")
- if(CXX_HAS_AVX)
- set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS} -mavx")
- endif()
- if(CXX_HAS_AVX2)
- set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS} -mavx -mavx2 -mfma -mlzcnt -mbmi -mbmi2 -mf16c")
- endif()
- endif()
-
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CYCLES_KERNEL_FLAGS}")
+ check_cxx_compiler_flag(-msse CXX_HAS_SSE)
+ check_cxx_compiler_flag(-mavx CXX_HAS_AVX)
+ check_cxx_compiler_flag(-mavx2 CXX_HAS_AVX2)
+
+ # Assume no signal trapping for better code generation.
+ set(CYCLES_KERNEL_FLAGS "-fno-trapping-math")
+ # Avoid overhead of setting errno for NaNs.
+ set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-math-errno")
+ # Let compiler optimize 0.0 - x without worrying about signed zeros.
+ set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-signed-zeros")
+
+ if(CMAKE_COMPILER_IS_GNUCC)
+ # Assume no signal trapping for better code generation.
+ set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-signaling-nans")
+ # Assume a fixed rounding mode for better constant folding.
+ set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-rounding-math")
+ endif()
+
+ if(CXX_HAS_SSE)
+ if(CMAKE_COMPILER_IS_GNUCC)
+ set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -mfpmath=sse")
+ endif()
+
+ set(CYCLES_SSE2_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -msse -msse2")
+ set(CYCLES_SSE3_KERNEL_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS} -msse3 -mssse3")
+ set(CYCLES_SSE41_KERNEL_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS} -msse4.1")
+ if(CXX_HAS_AVX)
+ set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS} -mavx")
+ endif()
+ if(CXX_HAS_AVX2)
+ set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS} -mavx -mavx2 -mfma -mlzcnt -mbmi -mbmi2 -mf16c")
+ endif()
+ endif()
+
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CYCLES_KERNEL_FLAGS}")
elseif(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Intel")
- check_cxx_compiler_flag(/QxSSE2 CXX_HAS_SSE)
- check_cxx_compiler_flag(/arch:AVX CXX_HAS_AVX)
- check_cxx_compiler_flag(/QxCORE-AVX2 CXX_HAS_AVX2)
-
- if(CXX_HAS_SSE)
- set(CYCLES_SSE2_KERNEL_FLAGS "/QxSSE2")
- set(CYCLES_SSE3_KERNEL_FLAGS "/QxSSSE3")
- set(CYCLES_SSE41_KERNEL_FLAGS "/QxSSE4.1")
-
- if(CXX_HAS_AVX)
- set(CYCLES_AVX_KERNEL_FLAGS "/arch:AVX")
- endif()
-
- if(CXX_HAS_AVX2)
- set(CYCLES_AVX2_KERNEL_FLAGS "/QxCORE-AVX2")
- endif()
- endif()
+ check_cxx_compiler_flag(/QxSSE2 CXX_HAS_SSE)
+ check_cxx_compiler_flag(/arch:AVX CXX_HAS_AVX)
+ check_cxx_compiler_flag(/QxCORE-AVX2 CXX_HAS_AVX2)
+
+ if(CXX_HAS_SSE)
+ set(CYCLES_SSE2_KERNEL_FLAGS "/QxSSE2")
+ set(CYCLES_SSE3_KERNEL_FLAGS "/QxSSSE3")
+ set(CYCLES_SSE41_KERNEL_FLAGS "/QxSSE4.1")
+
+ if(CXX_HAS_AVX)
+ set(CYCLES_AVX_KERNEL_FLAGS "/arch:AVX")
+ endif()
+
+ if(CXX_HAS_AVX2)
+ set(CYCLES_AVX2_KERNEL_FLAGS "/QxCORE-AVX2")
+ endif()
+ endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
- if(APPLE)
- # ICC does not support SSE2 flag on MacOSX
- check_cxx_compiler_flag(-xssse3 CXX_HAS_SSE)
- else()
- check_cxx_compiler_flag(-xsse2 CXX_HAS_SSE)
- endif()
-
- check_cxx_compiler_flag(-xavx CXX_HAS_AVX)
- check_cxx_compiler_flag(-xcore-avx2 CXX_HAS_AVX2)
-
- if(CXX_HAS_SSE)
- if(APPLE)
- # ICC does not support SSE2 flag on MacOSX
- set(CYCLES_SSE2_KERNEL_FLAGS "-xssse3")
- else()
- set(CYCLES_SSE2_KERNEL_FLAGS "-xsse2")
- endif()
-
- set(CYCLES_SSE3_KERNEL_FLAGS "-xssse3")
- set(CYCLES_SSE41_KERNEL_FLAGS "-xsse4.1")
-
- if(CXX_HAS_AVX)
- set(CYCLES_AVX_KERNEL_FLAGS "-xavx")
- endif()
-
- if(CXX_HAS_AVX2)
- set(CYCLES_AVX2_KERNEL_FLAGS "-xcore-avx2")
- endif()
- endif()
+ if(APPLE)
+ # ICC does not support SSE2 flag on MacOSX
+ check_cxx_compiler_flag(-xssse3 CXX_HAS_SSE)
+ else()
+ check_cxx_compiler_flag(-xsse2 CXX_HAS_SSE)
+ endif()
+
+ check_cxx_compiler_flag(-xavx CXX_HAS_AVX)
+ check_cxx_compiler_flag(-xcore-avx2 CXX_HAS_AVX2)
+
+ if(CXX_HAS_SSE)
+ if(APPLE)
+ # ICC does not support SSE2 flag on MacOSX
+ set(CYCLES_SSE2_KERNEL_FLAGS "-xssse3")
+ else()
+ set(CYCLES_SSE2_KERNEL_FLAGS "-xsse2")
+ endif()
+
+ set(CYCLES_SSE3_KERNEL_FLAGS "-xssse3")
+ set(CYCLES_SSE41_KERNEL_FLAGS "-xsse4.1")
+
+ if(CXX_HAS_AVX)
+ set(CYCLES_AVX_KERNEL_FLAGS "-xavx")
+ endif()
+
+ if(CXX_HAS_AVX2)
+ set(CYCLES_AVX2_KERNEL_FLAGS "-xcore-avx2")
+ endif()
+ endif()
endif()
if(CXX_HAS_SSE)
- add_definitions(
- -DWITH_KERNEL_SSE2
- -DWITH_KERNEL_SSE3
- -DWITH_KERNEL_SSE41
- )
+ add_definitions(
+ -DWITH_KERNEL_SSE2
+ -DWITH_KERNEL_SSE3
+ -DWITH_KERNEL_SSE41
+ )
endif()
if(CXX_HAS_AVX)
- add_definitions(-DWITH_KERNEL_AVX)
+ add_definitions(-DWITH_KERNEL_AVX)
endif()
if(CXX_HAS_AVX2)
- add_definitions(-DWITH_KERNEL_AVX2)
+ add_definitions(-DWITH_KERNEL_AVX2)
endif()
if(WITH_CYCLES_OSL)
- if(WIN32 AND MSVC)
- set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
- elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
- set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
- endif()
+ if(WIN32 AND MSVC)
+ set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
+ elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
+ set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
+ endif()
endif()
# Definitions and Includes
add_definitions(
- ${BOOST_DEFINITIONS}
- ${OPENIMAGEIO_DEFINITIONS}
+ ${BOOST_DEFINITIONS}
+ ${OPENIMAGEIO_DEFINITIONS}
)
add_definitions(
- -DCCL_NAMESPACE_BEGIN=namespace\ ccl\ {
- -DCCL_NAMESPACE_END=}
+ -DCCL_NAMESPACE_BEGIN=namespace\ ccl\ {
+ -DCCL_NAMESPACE_END=}
)
if(WITH_CYCLES_STANDALONE_GUI)
- add_definitions(-DWITH_CYCLES_STANDALONE_GUI)
+ add_definitions(-DWITH_CYCLES_STANDALONE_GUI)
endif()
if(WITH_CYCLES_PTEX)
- add_definitions(-DWITH_PTEX)
+ add_definitions(-DWITH_PTEX)
endif()
if(WITH_CYCLES_OSL)
- add_definitions(-DWITH_OSL)
- #osl 1.9.x
- add_definitions(-DOSL_STATIC_BUILD)
- #pre 1.9
- add_definitions(-DOSL_STATIC_LIBRARY)
- include_directories(
- SYSTEM
- ${OSL_INCLUDE_DIR}
- )
+ add_definitions(-DWITH_OSL)
+ #osl 1.9.x
+ add_definitions(-DOSL_STATIC_BUILD)
+ #pre 1.9
+ add_definitions(-DOSL_STATIC_LIBRARY)
+ include_directories(
+ SYSTEM
+ ${OSL_INCLUDE_DIR}
+ )
endif()
if(WITH_CYCLES_EMBREE)
- add_definitions(-DWITH_EMBREE)
- add_definitions(-DEMBREE_STATIC_LIB)
- include_directories(
- SYSTEM
- ${EMBREE_INCLUDE_DIRS}
- )
+ add_definitions(-DWITH_EMBREE)
+ add_definitions(-DEMBREE_STATIC_LIB)
+ include_directories(
+ SYSTEM
+ ${EMBREE_INCLUDE_DIRS}
+ )
endif()
if(WITH_OPENSUBDIV)
- add_definitions(-DWITH_OPENSUBDIV)
- include_directories(
- SYSTEM
- ${OPENSUBDIV_INCLUDE_DIR}
- )
+ add_definitions(-DWITH_OPENSUBDIV)
+ include_directories(
+ SYSTEM
+ ${OPENSUBDIV_INCLUDE_DIR}
+ )
endif()
if(WITH_CYCLES_STANDALONE)
- set(WITH_CYCLES_DEVICE_OPENCL TRUE)
- set(WITH_CYCLES_DEVICE_CUDA TRUE)
- # Experimental and unfinished.
- set(WITH_CYCLES_NETWORK FALSE)
+ set(WITH_CYCLES_DEVICE_OPENCL TRUE)
+ set(WITH_CYCLES_DEVICE_CUDA TRUE)
+ # Experimental and unfinished.
+ set(WITH_CYCLES_NETWORK FALSE)
endif()
# TODO(sergey): Consider removing it, only causes confusion in interface.
set(WITH_CYCLES_DEVICE_MULTI TRUE)
# Logging capabilities using GLog library.
if(WITH_CYCLES_LOGGING)
- add_definitions(-DWITH_CYCLES_LOGGING)
- add_definitions(${GLOG_DEFINES})
- add_definitions(-DCYCLES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
- include_directories(
- SYSTEM
- ${GLOG_INCLUDE_DIRS}
- ${GFLAGS_INCLUDE_DIRS}
- )
+ add_definitions(-DWITH_CYCLES_LOGGING)
+ add_definitions(${GLOG_DEFINES})
+ add_definitions(-DCYCLES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
+ include_directories(
+ SYSTEM
+ ${GLOG_INCLUDE_DIRS}
+ ${GFLAGS_INCLUDE_DIRS}
+ )
endif()
# Debugging capabilities (debug passes etc).
if(WITH_CYCLES_DEBUG)
- add_definitions(-DWITH_CYCLES_DEBUG)
+ add_definitions(-DWITH_CYCLES_DEBUG)
endif()
if(NOT OPENIMAGEIO_PUGIXML_FOUND)
- add_definitions(-DWITH_SYSTEM_PUGIXML)
+ add_definitions(-DWITH_SYSTEM_PUGIXML)
endif()
include_directories(
- SYSTEM
- ${BOOST_INCLUDE_DIR}
- ${OPENIMAGEIO_INCLUDE_DIRS}
- ${OPENIMAGEIO_INCLUDE_DIRS}/OpenImageIO
- ${OPENEXR_INCLUDE_DIR}
- ${OPENEXR_INCLUDE_DIRS}
- ${PUGIXML_INCLUDE_DIR}
+ SYSTEM
+ ${BOOST_INCLUDE_DIR}
+ ${OPENIMAGEIO_INCLUDE_DIRS}
+ ${OPENIMAGEIO_INCLUDE_DIRS}/OpenImageIO
+ ${OPENEXR_INCLUDE_DIR}
+ ${OPENEXR_INCLUDE_DIRS}
+ ${PUGIXML_INCLUDE_DIR}
)
if(CYCLES_STANDALONE_REPOSITORY)
- include_directories(../third_party/atomic)
+ include_directories(../third_party/atomic)
else()
- include_directories(../atomic)
+ include_directories(../atomic)
endif()
# Warnings
if(CMAKE_COMPILER_IS_GNUCXX)
- ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
- ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
- ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")
- unset(_has_cxxflag_float_conversion)
- unset(_has_cxxflag_double_promotion)
- unset(_has_no_error_unused_macros)
+ ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
+ ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
+ ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")
+ unset(_has_cxxflag_float_conversion)
+ unset(_has_cxxflag_double_promotion)
+ unset(_has_no_error_unused_macros)
endif()
if(WITH_CYCLES_CUDA_BINARIES AND (NOT WITH_CYCLES_CUBIN_COMPILER))
- if(MSVC)
- set(MAX_MSVC 1800)
- if(${CUDA_VERSION} EQUAL "8.0")
- set(MAX_MSVC 1900)
- elseif(${CUDA_VERSION} EQUAL "9.0")
- set(MAX_MSVC 1910)
- elseif(${CUDA_VERSION} EQUAL "9.1")
- set(MAX_MSVC 1911)
- elseif(${CUDA_VERSION} EQUAL "10.0")
- set(MAX_MSVC 1999)
- elseif(${CUDA_VERSION} EQUAL "10.1")
- set(MAX_MSVC 1999)
- endif()
- if(NOT MSVC_VERSION LESS ${MAX_MSVC} OR CMAKE_C_COMPILER_ID MATCHES "Clang")
- message(STATUS "nvcc not supported for this compiler version, using cycles_cubin_cc instead.")
- set(WITH_CYCLES_CUBIN_COMPILER ON)
- endif()
- unset(MAX_MSVC)
- elseif(APPLE)
- if(NOT (${XCODE_VERSION} VERSION_LESS 10.0))
- message(STATUS "nvcc not supported for this compiler version, using cycles_cubin_cc instead.")
- set(WITH_CYCLES_CUBIN_COMPILER ON)
- endif()
- endif()
+ if(MSVC)
+ set(MAX_MSVC 1800)
+ if(${CUDA_VERSION} EQUAL "8.0")
+ set(MAX_MSVC 1900)
+ elseif(${CUDA_VERSION} EQUAL "9.0")
+ set(MAX_MSVC 1910)
+ elseif(${CUDA_VERSION} EQUAL "9.1")
+ set(MAX_MSVC 1911)
+ elseif(${CUDA_VERSION} EQUAL "10.0")
+ set(MAX_MSVC 1999)
+ elseif(${CUDA_VERSION} EQUAL "10.1")
+ set(MAX_MSVC 1999)
+ endif()
+ if(NOT MSVC_VERSION LESS ${MAX_MSVC} OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ message(STATUS "nvcc not supported for this compiler version, using cycles_cubin_cc instead.")
+ set(WITH_CYCLES_CUBIN_COMPILER ON)
+ endif()
+ unset(MAX_MSVC)
+ elseif(APPLE)
+ if(NOT (${XCODE_VERSION} VERSION_LESS 10.0))
+ message(STATUS "nvcc not supported for this compiler version, using cycles_cubin_cc instead.")
+ set(WITH_CYCLES_CUBIN_COMPILER ON)
+ endif()
+ endif()
endif()
# NVRTC gives wrong rendering result in CUDA 10.0, so we must use NVCC.
if(WITH_CYCLES_CUDA_BINARIES AND WITH_CYCLES_CUBIN_COMPILER)
- if(NOT (${CUDA_VERSION} VERSION_LESS 10.0))
- message(STATUS "cycles_cubin_cc not supported for CUDA 10.0+, using nvcc instead.")
- set(WITH_CYCLES_CUBIN_COMPILER OFF)
- endif()
+ if(NOT (${CUDA_VERSION} VERSION_LESS 10.0))
+ message(STATUS "cycles_cubin_cc not supported for CUDA 10.0+, using nvcc instead.")
+ set(WITH_CYCLES_CUBIN_COMPILER OFF)
+ endif()
endif()
# Subdirectories
if(WITH_CYCLES_BLENDER)
- add_definitions(-DWITH_BLENDER_GUARDEDALLOC)
- add_subdirectory(blender)
+ add_definitions(-DWITH_BLENDER_GUARDEDALLOC)
+ add_subdirectory(blender)
endif()
if(WITH_CYCLES_NETWORK)
- add_definitions(-DWITH_NETWORK)
+ add_definitions(-DWITH_NETWORK)
endif()
if(WITH_OPENCOLORIO)
- add_definitions(-DWITH_OCIO)
- include_directories(
- SYSTEM
- ${OPENCOLORIO_INCLUDE_DIRS}
- )
+ add_definitions(-DWITH_OCIO)
+ include_directories(
+ SYSTEM
+ ${OPENCOLORIO_INCLUDE_DIRS}
+ )
endif()
if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
- add_subdirectory(app)
+ add_subdirectory(app)
endif()
add_subdirectory(bvh)
@@ -359,9 +359,9 @@ add_subdirectory(util)
# TODO(sergey): Make this to work with standalone repository.
if(WITH_GTESTS)
- add_subdirectory(test)
+ add_subdirectory(test)
endif()
if(NOT WITH_BLENDER AND WITH_CYCLES_STANDALONE)
- delayed_do_install(${CMAKE_BINARY_DIR}/bin)
+ delayed_do_install(${CMAKE_BINARY_DIR}/bin)
endif()
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index 2d7db860b09..36e3e179be5 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -1,6 +1,6 @@
set(INC
- ..
+ ..
)
set(INC_SYS
)
@@ -8,46 +8,46 @@ set(INC_SYS
# NOTE: LIBRARIES contains all the libraries which are common
# across release and debug build types, stored in a linking order.
set(LIBRARIES
- cycles_device
- cycles_kernel
- cycles_render
- cycles_bvh
- cycles_subd
- cycles_graph
- cycles_util
- ${BLENDER_GL_LIBRARIES}
- ${CYCLES_APP_GLEW_LIBRARY}
- ${PNG_LIBRARIES}
- ${JPEG_LIBRARIES}
- ${ZLIB_LIBRARIES}
- ${TIFF_LIBRARY}
- ${PTHREADS_LIBRARIES}
- extern_clew
+ cycles_device
+ cycles_kernel
+ cycles_render
+ cycles_bvh
+ cycles_subd
+ cycles_graph
+ cycles_util
+ ${BLENDER_GL_LIBRARIES}
+ ${CYCLES_APP_GLEW_LIBRARY}
+ ${PNG_LIBRARIES}
+ ${JPEG_LIBRARIES}
+ ${ZLIB_LIBRARIES}
+ ${TIFF_LIBRARY}
+ ${PTHREADS_LIBRARIES}
+ extern_clew
)
if(WITH_CUDA_DYNLOAD)
- list(APPEND LIBRARIES extern_cuew)
+ list(APPEND LIBRARIES extern_cuew)
else()
- list(APPEND LIBRARIES ${CUDA_CUDA_LIBRARY})
+ list(APPEND LIBRARIES ${CUDA_CUDA_LIBRARY})
endif()
if(WITH_CYCLES_OSL)
- list(APPEND LIBRARIES cycles_kernel_osl)
+ list(APPEND LIBRARIES cycles_kernel_osl)
endif()
if(NOT CYCLES_STANDALONE_REPOSITORY)
- list(APPEND LIBRARIES bf_intern_glew_mx bf_intern_guardedalloc bf_intern_numaapi)
+ list(APPEND LIBRARIES bf_intern_glew_mx bf_intern_guardedalloc bf_intern_numaapi)
endif()
if(WITH_CYCLES_LOGGING)
- list(APPEND LIBRARIES
- ${GLOG_LIBRARIES}
- ${GFLAGS_LIBRARIES}
- )
+ list(APPEND LIBRARIES
+ ${GLOG_LIBRARIES}
+ ${GFLAGS_LIBRARIES}
+ )
endif()
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
- list(APPEND LIBRARIES ${GLUT_LIBRARIES})
+ list(APPEND LIBRARIES ${GLUT_LIBRARIES})
endif()
# Common configuration.
@@ -62,7 +62,7 @@ link_directories(${OPENIMAGEIO_LIBPATH}
${OPENJPEG_LIBPATH})
if(WITH_OPENCOLORIO)
- link_directories(${OPENCOLORIO_LIBPATH})
+ link_directories(${OPENCOLORIO_LIBPATH})
endif()
add_definitions(${GL_DEFINITIONS})
@@ -78,90 +78,90 @@ include_directories(SYSTEM ${INC_SYS})
#
# TODO(sergey): Think of a better place for this?
macro(cycles_target_link_libraries target)
- target_link_libraries(${target} ${LIBRARIES})
- if(WITH_CYCLES_OSL)
- target_link_libraries(${target} ${OSL_LIBRARIES} ${LLVM_LIBRARIES})
- endif()
- if(WITH_CYCLES_EMBREE)
- target_link_libraries(${target} ${EMBREE_LIBRARIES})
- endif()
- if(WITH_OPENSUBDIV)
- target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
- endif()
- if(WITH_OPENCOLORIO)
- target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
- endif()
- target_link_libraries(
- ${target}
- ${OPENIMAGEIO_LIBRARIES}
- ${OPENEXR_LIBRARIES}
- ${OPENJPEG_LIBRARIES}
- ${PUGIXML_LIBRARIES}
- ${BOOST_LIBRARIES}
- ${CMAKE_DL_LIBS}
- ${PLATFORM_LINKLIBS}
- )
+ target_link_libraries(${target} ${LIBRARIES})
+ if(WITH_CYCLES_OSL)
+ target_link_libraries(${target} ${OSL_LIBRARIES} ${LLVM_LIBRARIES})
+ endif()
+ if(WITH_CYCLES_EMBREE)
+ target_link_libraries(${target} ${EMBREE_LIBRARIES})
+ endif()
+ if(WITH_OPENSUBDIV)
+ target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
+ endif()
+ if(WITH_OPENCOLORIO)
+ target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
+ endif()
+ target_link_libraries(
+ ${target}
+ ${OPENIMAGEIO_LIBRARIES}
+ ${OPENEXR_LIBRARIES}
+ ${OPENJPEG_LIBRARIES}
+ ${PUGIXML_LIBRARIES}
+ ${BOOST_LIBRARIES}
+ ${CMAKE_DL_LIBS}
+ ${PLATFORM_LINKLIBS}
+ )
endmacro()
# Application build targets
if(WITH_CYCLES_STANDALONE)
- set(SRC
- cycles_standalone.cpp
- cycles_xml.cpp
- cycles_xml.h
- )
- add_executable(cycles ${SRC})
- cycles_target_link_libraries(cycles)
-
- if(UNIX AND NOT APPLE)
- set_target_properties(cycles PROPERTIES INSTALL_RPATH $ORIGIN/lib)
- endif()
- unset(SRC)
+ set(SRC
+ cycles_standalone.cpp
+ cycles_xml.cpp
+ cycles_xml.h
+ )
+ add_executable(cycles ${SRC})
+ cycles_target_link_libraries(cycles)
+
+ if(UNIX AND NOT APPLE)
+ set_target_properties(cycles PROPERTIES INSTALL_RPATH $ORIGIN/lib)
+ endif()
+ unset(SRC)
endif()
if(WITH_CYCLES_NETWORK)
- set(SRC
- cycles_server.cpp
- )
- add_executable(cycles_server ${SRC})
- cycles_target_link_libraries(cycles_server)
-
- if(UNIX AND NOT APPLE)
- set_target_properties(cycles_server PROPERTIES INSTALL_RPATH $ORIGIN/lib)
- endif()
- unset(SRC)
+ set(SRC
+ cycles_server.cpp
+ )
+ add_executable(cycles_server ${SRC})
+ cycles_target_link_libraries(cycles_server)
+
+ if(UNIX AND NOT APPLE)
+ set_target_properties(cycles_server PROPERTIES INSTALL_RPATH $ORIGIN/lib)
+ endif()
+ unset(SRC)
endif()
if(WITH_CYCLES_CUBIN_COMPILER)
- # 32 bit windows is special, nvrtc is not supported on x86, so even
- # though we are building 32 bit blender a 64 bit cubin_cc will have
- # to be build to compile the cubins.
- if(MSVC AND NOT CMAKE_CL_64)
- message("Building with CUDA not supported on 32 bit, skipped")
- set(WITH_CYCLES_CUDA_BINARIES OFF CACHE BOOL "" FORCE)
- else()
- set(SRC
- cycles_cubin_cc.cpp
- )
- set(INC
- ../../../extern/cuew/include
- )
- add_executable(cycles_cubin_cc ${SRC})
- include_directories(${INC})
- target_link_libraries(cycles_cubin_cc
- extern_cuew
- ${OPENIMAGEIO_LIBRARIES}
- ${OPENEXR_LIBRARIES}
- ${OPENJPEG_LIBRARIES}
- ${PUGIXML_LIBRARIES}
- ${BOOST_LIBRARIES}
- ${PLATFORM_LINKLIBS}
- )
- if(NOT CYCLES_STANDALONE_REPOSITORY)
- target_link_libraries(cycles_cubin_cc bf_intern_guardedalloc)
- endif()
- unset(SRC)
- unset(INC)
- endif()
+ # 32 bit windows is special, nvrtc is not supported on x86, so even
+ # though we are building 32 bit blender a 64 bit cubin_cc will have
+ # to be build to compile the cubins.
+ if(MSVC AND NOT CMAKE_CL_64)
+ message("Building with CUDA not supported on 32 bit, skipped")
+ set(WITH_CYCLES_CUDA_BINARIES OFF CACHE BOOL "" FORCE)
+ else()
+ set(SRC
+ cycles_cubin_cc.cpp
+ )
+ set(INC
+ ../../../extern/cuew/include
+ )
+ add_executable(cycles_cubin_cc ${SRC})
+ include_directories(${INC})
+ target_link_libraries(cycles_cubin_cc
+ extern_cuew
+ ${OPENIMAGEIO_LIBRARIES}
+ ${OPENEXR_LIBRARIES}
+ ${OPENJPEG_LIBRARIES}
+ ${PUGIXML_LIBRARIES}
+ ${BOOST_LIBRARIES}
+ ${PLATFORM_LINKLIBS}
+ )
+ if(NOT CYCLES_STANDALONE_REPOSITORY)
+ target_link_libraries(cycles_cubin_cc bf_intern_guardedalloc)
+ endif()
+ unset(SRC)
+ unset(INC)
+ endif()
endif()
diff --git a/intern/cycles/app/cycles_cubin_cc.cpp b/intern/cycles/app/cycles_cubin_cc.cpp
index e6eb0be0d91..774c18f4219 100644
--- a/intern/cycles/app/cycles_cubin_cc.cpp
+++ b/intern/cycles/app/cycles_cubin_cc.cpp
@@ -26,272 +26,286 @@
#include "cuew.h"
#ifdef _MSC_VER
-# include <Windows.h>
+# include <Windows.h>
#endif
using std::string;
using std::vector;
namespace std {
- template<typename T>
- std::string to_string(const T &n) {
- std::ostringstream s;
- s << n;
- return s.str();
- }
-}
-
-class CompilationSettings
+template<typename T> std::string to_string(const T &n)
{
-public:
- CompilationSettings()
- : target_arch(0),
- bits(64),
- verbose(false),
- fast_math(false)
- {}
-
- string cuda_toolkit_dir;
- string input_file;
- string output_file;
- string ptx_file;
- vector<string> defines;
- vector<string> includes;
- int target_arch;
- int bits;
- bool verbose;
- bool fast_math;
+ std::ostringstream s;
+ s << n;
+ return s.str();
+}
+} // namespace std
+
+class CompilationSettings {
+ public:
+ CompilationSettings() : target_arch(0), bits(64), verbose(false), fast_math(false)
+ {
+ }
+
+ string cuda_toolkit_dir;
+ string input_file;
+ string output_file;
+ string ptx_file;
+ vector<string> defines;
+ vector<string> includes;
+ int target_arch;
+ int bits;
+ bool verbose;
+ bool fast_math;
};
static bool compile_cuda(CompilationSettings &settings)
{
- const char* headers[] = {"stdlib.h" , "float.h", "math.h", "stdio.h"};
- const char* header_content[] = {"\n", "\n", "\n", "\n"};
-
- printf("Building %s\n", settings.input_file.c_str());
-
- string code;
- if(!OIIO::Filesystem::read_text_file(settings.input_file, code)) {
- fprintf(stderr, "Error: unable to read %s\n", settings.input_file.c_str());
- return false;
- }
-
- vector<string> options;
- for(size_t i = 0; i < settings.includes.size(); i++) {
- options.push_back("-I" + settings.includes[i]);
- }
-
- for(size_t i = 0; i < settings.defines.size(); i++) {
- options.push_back("-D" + settings.defines[i]);
- }
- options.push_back("-D__KERNEL_CUDA_VERSION__=" + std::to_string(cuewNvrtcVersion()));
- options.push_back("-arch=compute_" + std::to_string(settings.target_arch));
- options.push_back("--device-as-default-execution-space");
- if(settings.fast_math)
- options.push_back("--use_fast_math");
-
- nvrtcProgram prog;
- nvrtcResult result = nvrtcCreateProgram(&prog,
- code.c_str(), // buffer
- NULL, // name
- sizeof(headers) / sizeof(void*), // numHeaders
- header_content, // headers
- headers); // includeNames
-
- if(result != NVRTC_SUCCESS) {
- fprintf(stderr, "Error: nvrtcCreateProgram failed (%d)\n\n", (int)result);
- return false;
- }
-
- /* Tranfer options to a classic C array. */
- vector<const char*> opts(options.size());
- for(size_t i = 0; i < options.size(); i++) {
- opts[i] = options[i].c_str();
- }
-
- result = nvrtcCompileProgram(prog, options.size(), &opts[0]);
-
- if(result != NVRTC_SUCCESS) {
- fprintf(stderr, "Error: nvrtcCompileProgram failed (%d)\n\n", (int)result);
-
- size_t log_size;
- nvrtcGetProgramLogSize(prog, &log_size);
-
- vector<char> log(log_size);
- nvrtcGetProgramLog(prog, &log[0]);
- fprintf(stderr, "%s\n", &log[0]);
-
- return false;
- }
-
- /* Retrieve the ptx code. */
- size_t ptx_size;
- result = nvrtcGetPTXSize(prog, &ptx_size);
- if(result != NVRTC_SUCCESS) {
- fprintf(stderr, "Error: nvrtcGetPTXSize failed (%d)\n\n", (int)result);
- return false;
- }
-
- vector<char> ptx_code(ptx_size);
- result = nvrtcGetPTX(prog, &ptx_code[0]);
- if(result != NVRTC_SUCCESS) {
- fprintf(stderr, "Error: nvrtcGetPTX failed (%d)\n\n", (int)result);
- return false;
- }
-
- /* Write a file in the temp folder with the ptx code. */
- settings.ptx_file = OIIO::Filesystem::temp_directory_path() + "/" + OIIO::Filesystem::unique_path();
- FILE * f= fopen(settings.ptx_file.c_str(), "wb");
- fwrite(&ptx_code[0], 1, ptx_size, f);
- fclose(f);
-
- return true;
+ const char *headers[] = {"stdlib.h", "float.h", "math.h", "stdio.h"};
+ const char *header_content[] = {"\n", "\n", "\n", "\n"};
+
+ printf("Building %s\n", settings.input_file.c_str());
+
+ string code;
+ if (!OIIO::Filesystem::read_text_file(settings.input_file, code)) {
+ fprintf(stderr, "Error: unable to read %s\n", settings.input_file.c_str());
+ return false;
+ }
+
+ vector<string> options;
+ for (size_t i = 0; i < settings.includes.size(); i++) {
+ options.push_back("-I" + settings.includes[i]);
+ }
+
+ for (size_t i = 0; i < settings.defines.size(); i++) {
+ options.push_back("-D" + settings.defines[i]);
+ }
+ options.push_back("-D__KERNEL_CUDA_VERSION__=" + std::to_string(cuewNvrtcVersion()));
+ options.push_back("-arch=compute_" + std::to_string(settings.target_arch));
+ options.push_back("--device-as-default-execution-space");
+ if (settings.fast_math)
+ options.push_back("--use_fast_math");
+
+ nvrtcProgram prog;
+ nvrtcResult result = nvrtcCreateProgram(&prog,
+ code.c_str(), // buffer
+ NULL, // name
+ sizeof(headers) / sizeof(void *), // numHeaders
+ header_content, // headers
+ headers); // includeNames
+
+ if (result != NVRTC_SUCCESS) {
+ fprintf(stderr, "Error: nvrtcCreateProgram failed (%d)\n\n", (int)result);
+ return false;
+ }
+
+ /* Tranfer options to a classic C array. */
+ vector<const char *> opts(options.size());
+ for (size_t i = 0; i < options.size(); i++) {
+ opts[i] = options[i].c_str();
+ }
+
+ result = nvrtcCompileProgram(prog, options.size(), &opts[0]);
+
+ if (result != NVRTC_SUCCESS) {
+ fprintf(stderr, "Error: nvrtcCompileProgram failed (%d)\n\n", (int)result);
+
+ size_t log_size;
+ nvrtcGetProgramLogSize(prog, &log_size);
+
+ vector<char> log(log_size);
+ nvrtcGetProgramLog(prog, &log[0]);
+ fprintf(stderr, "%s\n", &log[0]);
+
+ return false;
+ }
+
+ /* Retrieve the ptx code. */
+ size_t ptx_size;
+ result = nvrtcGetPTXSize(prog, &ptx_size);
+ if (result != NVRTC_SUCCESS) {
+ fprintf(stderr, "Error: nvrtcGetPTXSize failed (%d)\n\n", (int)result);
+ return false;
+ }
+
+ vector<char> ptx_code(ptx_size);
+ result = nvrtcGetPTX(prog, &ptx_code[0]);
+ if (result != NVRTC_SUCCESS) {
+ fprintf(stderr, "Error: nvrtcGetPTX failed (%d)\n\n", (int)result);
+ return false;
+ }
+
+ /* Write a file in the temp folder with the ptx code. */
+ settings.ptx_file = OIIO::Filesystem::temp_directory_path() + "/" +
+ OIIO::Filesystem::unique_path();
+ FILE *f = fopen(settings.ptx_file.c_str(), "wb");
+ fwrite(&ptx_code[0], 1, ptx_size, f);
+ fclose(f);
+
+ return true;
}
static bool link_ptxas(CompilationSettings &settings)
{
- string cudapath = "";
- if(settings.cuda_toolkit_dir.size())
- cudapath = settings.cuda_toolkit_dir + "/bin/";
-
- string ptx = "\"" +cudapath + "ptxas\" " + settings.ptx_file +
- " -o " + settings.output_file +
- " --gpu-name sm_" + std::to_string(settings.target_arch) +
- " -m" + std::to_string(settings.bits);
-
- if(settings.verbose) {
- ptx += " --verbose";
- printf("%s\n", ptx.c_str());
- }
-
- int pxresult = system(ptx.c_str());
- if(pxresult) {
- fprintf(stderr, "Error: ptxas failed (%d)\n\n", pxresult);
- return false;
- }
-
- if(!OIIO::Filesystem::remove(settings.ptx_file)) {
- fprintf(stderr, "Error: removing %s\n\n", settings.ptx_file.c_str());
- }
-
- return true;
+ string cudapath = "";
+ if (settings.cuda_toolkit_dir.size())
+ cudapath = settings.cuda_toolkit_dir + "/bin/";
+
+ string ptx = "\"" + cudapath + "ptxas\" " + settings.ptx_file + " -o " + settings.output_file +
+ " --gpu-name sm_" + std::to_string(settings.target_arch) + " -m" +
+ std::to_string(settings.bits);
+
+ if (settings.verbose) {
+ ptx += " --verbose";
+ printf("%s\n", ptx.c_str());
+ }
+
+ int pxresult = system(ptx.c_str());
+ if (pxresult) {
+ fprintf(stderr, "Error: ptxas failed (%d)\n\n", pxresult);
+ return false;
+ }
+
+ if (!OIIO::Filesystem::remove(settings.ptx_file)) {
+ fprintf(stderr, "Error: removing %s\n\n", settings.ptx_file.c_str());
+ }
+
+ return true;
}
static bool init(CompilationSettings &settings)
{
#ifdef _MSC_VER
- if(settings.cuda_toolkit_dir.size()) {
- SetDllDirectory((settings.cuda_toolkit_dir + "/bin").c_str());
- }
+ if (settings.cuda_toolkit_dir.size()) {
+ SetDllDirectory((settings.cuda_toolkit_dir + "/bin").c_str());
+ }
#else
- (void)settings;
+ (void)settings;
#endif
- int cuewresult = cuewInit(CUEW_INIT_NVRTC);
- if(cuewresult != CUEW_SUCCESS) {
- fprintf(stderr, "Error: cuew init fialed (0x%d)\n\n", cuewresult);
- return false;
- }
-
- if(cuewNvrtcVersion() < 80) {
- fprintf(stderr, "Error: only cuda 8 and higher is supported, %d\n\n", cuewCompilerVersion());
- return false;
- }
-
- if(!nvrtcCreateProgram) {
- fprintf(stderr, "Error: nvrtcCreateProgram not resolved\n");
- return false;
- }
-
- if(!nvrtcCompileProgram) {
- fprintf(stderr, "Error: nvrtcCompileProgram not resolved\n");
- return false;
- }
-
- if(!nvrtcGetProgramLogSize) {
- fprintf(stderr, "Error: nvrtcGetProgramLogSize not resolved\n");
- return false;
- }
-
- if(!nvrtcGetProgramLog) {
- fprintf(stderr, "Error: nvrtcGetProgramLog not resolved\n");
- return false;
- }
-
- if(!nvrtcGetPTXSize) {
- fprintf(stderr, "Error: nvrtcGetPTXSize not resolved\n");
- return false;
- }
-
- if(!nvrtcGetPTX) {
- fprintf(stderr, "Error: nvrtcGetPTX not resolved\n");
- return false;
- }
-
- return true;
+ int cuewresult = cuewInit(CUEW_INIT_NVRTC);
+ if (cuewresult != CUEW_SUCCESS) {
+ fprintf(stderr, "Error: cuew init fialed (0x%d)\n\n", cuewresult);
+ return false;
+ }
+
+ if (cuewNvrtcVersion() < 80) {
+ fprintf(stderr, "Error: only cuda 8 and higher is supported, %d\n\n", cuewCompilerVersion());
+ return false;
+ }
+
+ if (!nvrtcCreateProgram) {
+ fprintf(stderr, "Error: nvrtcCreateProgram not resolved\n");
+ return false;
+ }
+
+ if (!nvrtcCompileProgram) {
+ fprintf(stderr, "Error: nvrtcCompileProgram not resolved\n");
+ return false;
+ }
+
+ if (!nvrtcGetProgramLogSize) {
+ fprintf(stderr, "Error: nvrtcGetProgramLogSize not resolved\n");
+ return false;
+ }
+
+ if (!nvrtcGetProgramLog) {
+ fprintf(stderr, "Error: nvrtcGetProgramLog not resolved\n");
+ return false;
+ }
+
+ if (!nvrtcGetPTXSize) {
+ fprintf(stderr, "Error: nvrtcGetPTXSize not resolved\n");
+ return false;
+ }
+
+ if (!nvrtcGetPTX) {
+ fprintf(stderr, "Error: nvrtcGetPTX not resolved\n");
+ return false;
+ }
+
+ return true;
}
static bool parse_parameters(int argc, const char **argv, CompilationSettings &settings)
{
- OIIO::ArgParse ap;
- ap.options("Usage: cycles_cubin_cc [options]",
- "-target %d", &settings.target_arch, "target shader model",
- "-m %d", &settings.bits, "Cuda architecture bits",
- "-i %s", &settings.input_file, "Input source filename",
- "-o %s", &settings.output_file, "Output cubin filename",
- "-I %L", &settings.includes, "Add additional includepath",
- "-D %L", &settings.defines, "Add additional defines",
- "-v", &settings.verbose, "Use verbose logging",
- "--use_fast_math", &settings.fast_math, "Use fast math",
- "-cuda-toolkit-dir %s", &settings.cuda_toolkit_dir, "path to the cuda toolkit binary directory",
- NULL);
-
- if(ap.parse(argc, argv) < 0) {
- fprintf(stderr, "%s\n", ap.geterror().c_str());
- ap.usage();
- return false;
- }
-
- if(!settings.output_file.size()) {
- fprintf(stderr, "Error: Output file not set(-o), required\n\n");
- return false;
- }
-
- if(!settings.input_file.size()) {
- fprintf(stderr, "Error: Input file not set(-i, required\n\n");
- return false;
- }
-
- if(!settings.target_arch) {
- fprintf(stderr, "Error: target shader model not set (-target), required\n\n");
- return false;
- }
-
- return true;
+ OIIO::ArgParse ap;
+ ap.options("Usage: cycles_cubin_cc [options]",
+ "-target %d",
+ &settings.target_arch,
+ "target shader model",
+ "-m %d",
+ &settings.bits,
+ "Cuda architecture bits",
+ "-i %s",
+ &settings.input_file,
+ "Input source filename",
+ "-o %s",
+ &settings.output_file,
+ "Output cubin filename",
+ "-I %L",
+ &settings.includes,
+ "Add additional includepath",
+ "-D %L",
+ &settings.defines,
+ "Add additional defines",
+ "-v",
+ &settings.verbose,
+ "Use verbose logging",
+ "--use_fast_math",
+ &settings.fast_math,
+ "Use fast math",
+ "-cuda-toolkit-dir %s",
+ &settings.cuda_toolkit_dir,
+ "path to the cuda toolkit binary directory",
+ NULL);
+
+ if (ap.parse(argc, argv) < 0) {
+ fprintf(stderr, "%s\n", ap.geterror().c_str());
+ ap.usage();
+ return false;
+ }
+
+ if (!settings.output_file.size()) {
+ fprintf(stderr, "Error: Output file not set(-o), required\n\n");
+ return false;
+ }
+
+ if (!settings.input_file.size()) {
+ fprintf(stderr, "Error: Input file not set(-i, required\n\n");
+ return false;
+ }
+
+ if (!settings.target_arch) {
+ fprintf(stderr, "Error: target shader model not set (-target), required\n\n");
+ return false;
+ }
+
+ return true;
}
int main(int argc, const char **argv)
{
- CompilationSettings settings;
+ CompilationSettings settings;
- if(!parse_parameters(argc, argv, settings)) {
- fprintf(stderr, "Error: invalid parameters, exiting\n");
- exit(EXIT_FAILURE);
- }
+ if (!parse_parameters(argc, argv, settings)) {
+ fprintf(stderr, "Error: invalid parameters, exiting\n");
+ exit(EXIT_FAILURE);
+ }
- if(!init(settings)) {
- fprintf(stderr, "Error: initialization error, exiting\n");
- exit(EXIT_FAILURE);
- }
+ if (!init(settings)) {
+ fprintf(stderr, "Error: initialization error, exiting\n");
+ exit(EXIT_FAILURE);
+ }
- if(!compile_cuda(settings)) {
- fprintf(stderr, "Error: compilation error, exiting\n");
- exit(EXIT_FAILURE);
- }
+ if (!compile_cuda(settings)) {
+ fprintf(stderr, "Error: compilation error, exiting\n");
+ exit(EXIT_FAILURE);
+ }
- if(!link_ptxas(settings)) {
- exit(EXIT_FAILURE);
- }
+ if (!link_ptxas(settings)) {
+ exit(EXIT_FAILURE);
+ }
- return 0;
+ return 0;
}
diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp
index e2166473aa3..c5a4c9b375b 100644
--- a/intern/cycles/app/cycles_server.cpp
+++ b/intern/cycles/app/cycles_server.cpp
@@ -30,85 +30,93 @@ using namespace ccl;
int main(int argc, const char **argv)
{
- util_logging_init(argv[0]);
- path_init();
+ util_logging_init(argv[0]);
+ path_init();
+
+ /* device types */
+ string devicelist = "";
+ string devicename = "cpu";
+ bool list = false, debug = false;
+ int threads = 0, verbosity = 1;
+
+ vector<DeviceType> &types = Device::available_types();
+
+ foreach (DeviceType type, types) {
+ if (devicelist != "")
+ devicelist += ", ";
+
+ devicelist += Device::string_from_type(type);
+ }
+
+ /* parse options */
+ ArgParse ap;
+
+ ap.options("Usage: cycles_server [options]",
+ "--device %s",
+ &devicename,
+ ("Devices to use: " + devicelist).c_str(),
+ "--list-devices",
+ &list,
+ "List information about all available devices",
+ "--threads %d",
+ &threads,
+ "Number of threads to use for CPU device",
+#ifdef WITH_CYCLES_LOGGING
+ "--debug",
+ &debug,
+ "Enable debug logging",
+ "--verbose %d",
+ &verbosity,
+ "Set verbosity of the logger",
+#endif
+ NULL);
- /* device types */
- string devicelist = "";
- string devicename = "cpu";
- bool list = false, debug = false;
- int threads = 0, verbosity = 1;
+ if (ap.parse(argc, argv) < 0) {
+ fprintf(stderr, "%s\n", ap.geterror().c_str());
+ ap.usage();
+ exit(EXIT_FAILURE);
+ }
- vector<DeviceType>& types = Device::available_types();
+ if (debug) {
+ util_logging_start();
+ util_logging_verbosity_set(verbosity);
+ }
- foreach(DeviceType type, types) {
- if(devicelist != "")
- devicelist += ", ";
+ if (list) {
+ vector<DeviceInfo> &devices = Device::available_devices();
- devicelist += Device::string_from_type(type);
- }
+ printf("Devices:\n");
- /* parse options */
- ArgParse ap;
+ foreach (DeviceInfo &info, devices) {
+ printf(" %s%s\n", info.description.c_str(), (info.display_device) ? " (display)" : "");
+ }
- ap.options ("Usage: cycles_server [options]",
- "--device %s", &devicename, ("Devices to use: " + devicelist).c_str(),
- "--list-devices", &list, "List information about all available devices",
- "--threads %d", &threads, "Number of threads to use for CPU device",
-#ifdef WITH_CYCLES_LOGGING
- "--debug", &debug, "Enable debug logging",
- "--verbose %d", &verbosity, "Set verbosity of the logger",
-#endif
- NULL);
-
- if(ap.parse(argc, argv) < 0) {
- fprintf(stderr, "%s\n", ap.geterror().c_str());
- ap.usage();
- exit(EXIT_FAILURE);
- }
-
- if(debug) {
- util_logging_start();
- util_logging_verbosity_set(verbosity);
- }
-
- if(list) {
- vector<DeviceInfo>& devices = Device::available_devices();
-
- printf("Devices:\n");
-
- foreach(DeviceInfo& info, devices) {
- printf(" %s%s\n",
- info.description.c_str(),
- (info.display_device)? " (display)": "");
- }
-
- exit(EXIT_SUCCESS);
- }
-
- /* find matching device */
- DeviceType device_type = Device::type_from_string(devicename.c_str());
- vector<DeviceInfo>& devices = Device::available_devices();
- DeviceInfo device_info;
-
- foreach(DeviceInfo& device, devices) {
- if(device_type == device.type) {
- device_info = device;
- break;
- }
- }
-
- TaskScheduler::init(threads);
-
- while(1) {
- Stats stats;
- Device *device = Device::create(device_info, stats, true);
- printf("Cycles Server with device: %s\n", device->info.description.c_str());
- device->server_run();
- delete device;
- }
-
- TaskScheduler::exit();
-
- return 0;
+ exit(EXIT_SUCCESS);
+ }
+
+ /* find matching device */
+ DeviceType device_type = Device::type_from_string(devicename.c_str());
+ vector<DeviceInfo> &devices = Device::available_devices();
+ DeviceInfo device_info;
+
+ foreach (DeviceInfo &device, devices) {
+ if (device_type == device.type) {
+ device_info = device;
+ break;
+ }
+ }
+
+ TaskScheduler::init(threads);
+
+ while (1) {
+ Stats stats;
+ Device *device = Device::create(device_info, stats, true);
+ printf("Cycles Server with device: %s\n", device->info.description.c_str());
+ device->server_run();
+ delete device;
+ }
+
+ TaskScheduler::exit();
+
+ return 0;
}
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index 9c899a38e7b..d2d112e8d7e 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -36,7 +36,7 @@
#include "util/util_version.h"
#ifdef WITH_CYCLES_STANDALONE_GUI
-#include "util/util_view.h"
+# include "util/util_view.h"
#endif
#include "app/cycles_xml.h"
@@ -44,447 +44,494 @@
CCL_NAMESPACE_BEGIN
struct Options {
- Session *session;
- Scene *scene;
- string filepath;
- int width, height;
- SceneParams scene_params;
- SessionParams session_params;
- bool quiet;
- bool show_help, interactive, pause;
- string output_path;
+ Session *session;
+ Scene *scene;
+ string filepath;
+ int width, height;
+ SceneParams scene_params;
+ SessionParams session_params;
+ bool quiet;
+ bool show_help, interactive, pause;
+ string output_path;
} options;
-static void session_print(const string& str)
+static void session_print(const string &str)
{
- /* print with carriage return to overwrite previous */
- printf("\r%s", str.c_str());
+ /* print with carriage return to overwrite previous */
+ printf("\r%s", str.c_str());
- /* add spaces to overwrite longer previous print */
- static int maxlen = 0;
- int len = str.size();
- maxlen = max(len, maxlen);
+ /* add spaces to overwrite longer previous print */
+ static int maxlen = 0;
+ int len = str.size();
+ maxlen = max(len, maxlen);
- for(int i = len; i < maxlen; i++)
- printf(" ");
+ for (int i = len; i < maxlen; i++)
+ printf(" ");
- /* flush because we don't write an end of line */
- fflush(stdout);
+ /* flush because we don't write an end of line */
+ fflush(stdout);
}
static void session_print_status()
{
- string status, substatus;
+ string status, substatus;
- /* get status */
- float progress = options.session->progress.get_progress();
- options.session->progress.get_status(status, substatus);
+ /* get status */
+ float progress = options.session->progress.get_progress();
+ options.session->progress.get_status(status, substatus);
- if(substatus != "")
- status += ": " + substatus;
+ if (substatus != "")
+ status += ": " + substatus;
- /* print status */
- status = string_printf("Progress %05.2f %s", (double) progress*100, status.c_str());
- session_print(status);
+ /* print status */
+ status = string_printf("Progress %05.2f %s", (double)progress * 100, status.c_str());
+ session_print(status);
}
static bool write_render(const uchar *pixels, int w, int h, int channels)
{
- string msg = string_printf("Writing image %s", options.output_path.c_str());
- session_print(msg);
+ string msg = string_printf("Writing image %s", options.output_path.c_str());
+ session_print(msg);
- unique_ptr<ImageOutput> out = unique_ptr<ImageOutput>(ImageOutput::create(options.output_path));
- if(!out) {
- return false;
- }
+ unique_ptr<ImageOutput> out = unique_ptr<ImageOutput>(ImageOutput::create(options.output_path));
+ if (!out) {
+ return false;
+ }
- ImageSpec spec(w, h, channels, TypeDesc::UINT8);
- if(!out->open(options.output_path, spec)) {
- return false;
- }
+ ImageSpec spec(w, h, channels, TypeDesc::UINT8);
+ if (!out->open(options.output_path, spec)) {
+ return false;
+ }
- /* conversion for different top/bottom convention */
- out->write_image(TypeDesc::UINT8,
- pixels + (h - 1) * w * channels,
- AutoStride,
- -w * channels,
- AutoStride);
+ /* conversion for different top/bottom convention */
+ out->write_image(
+ TypeDesc::UINT8, pixels + (h - 1) * w * channels, AutoStride, -w * channels, AutoStride);
- out->close();
+ out->close();
- return true;
+ return true;
}
-static BufferParams& session_buffer_params()
+static BufferParams &session_buffer_params()
{
- static BufferParams buffer_params;
- buffer_params.width = options.width;
- buffer_params.height = options.height;
- buffer_params.full_width = options.width;
- buffer_params.full_height = options.height;
+ static BufferParams buffer_params;
+ buffer_params.width = options.width;
+ buffer_params.height = options.height;
+ buffer_params.full_width = options.width;
+ buffer_params.full_height = options.height;
- return buffer_params;
+ return buffer_params;
}
static void scene_init()
{
- options.scene = new Scene(options.scene_params, options.session->device);
-
- /* Read XML */
- xml_read_file(options.scene, options.filepath.c_str());
-
- /* Camera width/height override? */
- if(!(options.width == 0 || options.height == 0)) {
- options.scene->camera->width = options.width;
- options.scene->camera->height = options.height;
- }
- else {
- options.width = options.scene->camera->width;
- options.height = options.scene->camera->height;
- }
-
- /* Calculate Viewplane */
- options.scene->camera->compute_auto_viewplane();
+ options.scene = new Scene(options.scene_params, options.session->device);
+
+ /* Read XML */
+ xml_read_file(options.scene, options.filepath.c_str());
+
+ /* Camera width/height override? */
+ if (!(options.width == 0 || options.height == 0)) {
+ options.scene->camera->width = options.width;
+ options.scene->camera->height = options.height;
+ }
+ else {
+ options.width = options.scene->camera->width;
+ options.height = options.scene->camera->height;
+ }
+
+ /* Calculate Viewplane */
+ options.scene->camera->compute_auto_viewplane();
}
static void session_init()
{
- options.session_params.write_render_cb = write_render;
- options.session = new Session(options.session_params);
+ options.session_params.write_render_cb = write_render;
+ options.session = new Session(options.session_params);
- if(options.session_params.background && !options.quiet)
- options.session->progress.set_update_callback(function_bind(&session_print_status));
+ if (options.session_params.background && !options.quiet)
+ options.session->progress.set_update_callback(function_bind(&session_print_status));
#ifdef WITH_CYCLES_STANDALONE_GUI
- else
- options.session->progress.set_update_callback(function_bind(&view_redraw));
+ else
+ options.session->progress.set_update_callback(function_bind(&view_redraw));
#endif
- /* load scene */
- scene_init();
- options.session->scene = options.scene;
+ /* load scene */
+ scene_init();
+ options.session->scene = options.scene;
- options.session->reset(session_buffer_params(), options.session_params.samples);
- options.session->start();
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+ options.session->start();
}
static void session_exit()
{
- if(options.session) {
- delete options.session;
- options.session = NULL;
- }
-
- if(options.session_params.background && !options.quiet) {
- session_print("Finished Rendering.");
- printf("\n");
- }
+ if (options.session) {
+ delete options.session;
+ options.session = NULL;
+ }
+
+ if (options.session_params.background && !options.quiet) {
+ session_print("Finished Rendering.");
+ printf("\n");
+ }
}
#ifdef WITH_CYCLES_STANDALONE_GUI
-static void display_info(Progress& progress)
+static void display_info(Progress &progress)
{
- static double latency = 0.0;
- static double last = 0;
- double elapsed = time_dt();
- string str, interactive;
-
- latency = (elapsed - last);
- last = elapsed;
-
- double total_time, sample_time;
- string status, substatus;
-
- progress.get_time(total_time, sample_time);
- progress.get_status(status, substatus);
- float progress_val = progress.get_progress();
-
- if(substatus != "")
- status += ": " + substatus;
-
- interactive = options.interactive? "On":"Off";
-
- str = string_printf(
- "%s"
- " Time: %.2f"
- " Latency: %.4f"
- " Progress: %05.2f"
- " Average: %.4f"
- " Interactive: %s",
- status.c_str(), total_time, latency, (double) progress_val*100, sample_time, interactive.c_str());
-
- view_display_info(str.c_str());
-
- if(options.show_help)
- view_display_help();
+ static double latency = 0.0;
+ static double last = 0;
+ double elapsed = time_dt();
+ string str, interactive;
+
+ latency = (elapsed - last);
+ last = elapsed;
+
+ double total_time, sample_time;
+ string status, substatus;
+
+ progress.get_time(total_time, sample_time);
+ progress.get_status(status, substatus);
+ float progress_val = progress.get_progress();
+
+ if (substatus != "")
+ status += ": " + substatus;
+
+ interactive = options.interactive ? "On" : "Off";
+
+ str = string_printf(
+ "%s"
+ " Time: %.2f"
+ " Latency: %.4f"
+ " Progress: %05.2f"
+ " Average: %.4f"
+ " Interactive: %s",
+ status.c_str(),
+ total_time,
+ latency,
+ (double)progress_val * 100,
+ sample_time,
+ interactive.c_str());
+
+ view_display_info(str.c_str());
+
+ if (options.show_help)
+ view_display_help();
}
static void display()
{
- static DeviceDrawParams draw_params = DeviceDrawParams();
+ static DeviceDrawParams draw_params = DeviceDrawParams();
- options.session->draw(session_buffer_params(), draw_params);
+ options.session->draw(session_buffer_params(), draw_params);
- display_info(options.session->progress);
+ display_info(options.session->progress);
}
static void motion(int x, int y, int button)
{
- if(options.interactive) {
- Transform matrix = options.session->scene->camera->matrix;
-
- /* Translate */
- if(button == 0) {
- float3 translate = make_float3(x * 0.01f, -(y * 0.01f), 0.0f);
- matrix = matrix * transform_translate(translate);
- }
-
- /* Rotate */
- else if(button == 2) {
- float4 r1 = make_float4((float)x * 0.1f, 0.0f, 1.0f, 0.0f);
- matrix = matrix * transform_rotate(DEG2RADF(r1.x), make_float3(r1.y, r1.z, r1.w));
-
- float4 r2 = make_float4(y * 0.1f, 1.0f, 0.0f, 0.0f);
- matrix = matrix * transform_rotate(DEG2RADF(r2.x), make_float3(r2.y, r2.z, r2.w));
- }
-
- /* Update and Reset */
- options.session->scene->camera->matrix = matrix;
- options.session->scene->camera->need_update = true;
- options.session->scene->camera->need_device_update = true;
-
- options.session->reset(session_buffer_params(), options.session_params.samples);
- }
+ if (options.interactive) {
+ Transform matrix = options.session->scene->camera->matrix;
+
+ /* Translate */
+ if (button == 0) {
+ float3 translate = make_float3(x * 0.01f, -(y * 0.01f), 0.0f);
+ matrix = matrix * transform_translate(translate);
+ }
+
+ /* Rotate */
+ else if (button == 2) {
+ float4 r1 = make_float4((float)x * 0.1f, 0.0f, 1.0f, 0.0f);
+ matrix = matrix * transform_rotate(DEG2RADF(r1.x), make_float3(r1.y, r1.z, r1.w));
+
+ float4 r2 = make_float4(y * 0.1f, 1.0f, 0.0f, 0.0f);
+ matrix = matrix * transform_rotate(DEG2RADF(r2.x), make_float3(r2.y, r2.z, r2.w));
+ }
+
+ /* Update and Reset */
+ options.session->scene->camera->matrix = matrix;
+ options.session->scene->camera->need_update = true;
+ options.session->scene->camera->need_device_update = true;
+
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+ }
}
static void resize(int width, int height)
{
- options.width = width;
- options.height = height;
-
- if(options.session) {
- /* Update camera */
- options.session->scene->camera->width = width;
- options.session->scene->camera->height = height;
- options.session->scene->camera->compute_auto_viewplane();
- options.session->scene->camera->need_update = true;
- options.session->scene->camera->need_device_update = true;
-
- options.session->reset(session_buffer_params(), options.session_params.samples);
- }
+ options.width = width;
+ options.height = height;
+
+ if (options.session) {
+ /* Update camera */
+ options.session->scene->camera->width = width;
+ options.session->scene->camera->height = height;
+ options.session->scene->camera->compute_auto_viewplane();
+ options.session->scene->camera->need_update = true;
+ options.session->scene->camera->need_device_update = true;
+
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+ }
}
static void keyboard(unsigned char key)
{
- /* Toggle help */
- if(key == 'h')
- options.show_help = !(options.show_help);
-
- /* Reset */
- else if(key == 'r')
- options.session->reset(session_buffer_params(), options.session_params.samples);
-
- /* Cancel */
- else if(key == 27) // escape
- options.session->progress.set_cancel("Canceled");
-
- /* Pause */
- else if(key == 'p') {
- options.pause = !options.pause;
- options.session->set_pause(options.pause);
- }
-
- /* Interactive Mode */
- else if(key == 'i')
- options.interactive = !(options.interactive);
-
- /* Navigation */
- else if(options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) {
- Transform matrix = options.session->scene->camera->matrix;
- float3 translate;
-
- if(key == 'w')
- translate = make_float3(0.0f, 0.0f, 0.1f);
- else if(key == 's')
- translate = make_float3(0.0f, 0.0f, -0.1f);
- else if(key == 'a')
- translate = make_float3(-0.1f, 0.0f, 0.0f);
- else if(key == 'd')
- translate = make_float3(0.1f, 0.0f, 0.0f);
-
- matrix = matrix * transform_translate(translate);
-
- /* Update and Reset */
- options.session->scene->camera->matrix = matrix;
- options.session->scene->camera->need_update = true;
- options.session->scene->camera->need_device_update = true;
-
- options.session->reset(session_buffer_params(), options.session_params.samples);
- }
-
- /* Set Max Bounces */
- else if(options.interactive && (key == '0' || key == '1' || key == '2' || key == '3')) {
- int bounce;
- switch(key) {
- case '0': bounce = 0; break;
- case '1': bounce = 1; break;
- case '2': bounce = 2; break;
- case '3': bounce = 3; break;
- default: bounce = 0; break;
- }
-
- options.session->scene->integrator->max_bounce = bounce;
-
- /* Update and Reset */
- options.session->scene->integrator->need_update = true;
-
- options.session->reset(session_buffer_params(), options.session_params.samples);
- }
+ /* Toggle help */
+ if (key == 'h')
+ options.show_help = !(options.show_help);
+
+ /* Reset */
+ else if (key == 'r')
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+
+ /* Cancel */
+ else if (key == 27) // escape
+ options.session->progress.set_cancel("Canceled");
+
+ /* Pause */
+ else if (key == 'p') {
+ options.pause = !options.pause;
+ options.session->set_pause(options.pause);
+ }
+
+ /* Interactive Mode */
+ else if (key == 'i')
+ options.interactive = !(options.interactive);
+
+ /* Navigation */
+ else if (options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) {
+ Transform matrix = options.session->scene->camera->matrix;
+ float3 translate;
+
+ if (key == 'w')
+ translate = make_float3(0.0f, 0.0f, 0.1f);
+ else if (key == 's')
+ translate = make_float3(0.0f, 0.0f, -0.1f);
+ else if (key == 'a')
+ translate = make_float3(-0.1f, 0.0f, 0.0f);
+ else if (key == 'd')
+ translate = make_float3(0.1f, 0.0f, 0.0f);
+
+ matrix = matrix * transform_translate(translate);
+
+ /* Update and Reset */
+ options.session->scene->camera->matrix = matrix;
+ options.session->scene->camera->need_update = true;
+ options.session->scene->camera->need_device_update = true;
+
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+ }
+
+ /* Set Max Bounces */
+ else if (options.interactive && (key == '0' || key == '1' || key == '2' || key == '3')) {
+ int bounce;
+ switch (key) {
+ case '0':
+ bounce = 0;
+ break;
+ case '1':
+ bounce = 1;
+ break;
+ case '2':
+ bounce = 2;
+ break;
+ case '3':
+ bounce = 3;
+ break;
+ default:
+ bounce = 0;
+ break;
+ }
+
+ options.session->scene->integrator->max_bounce = bounce;
+
+ /* Update and Reset */
+ options.session->scene->integrator->need_update = true;
+
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+ }
}
#endif
static int files_parse(int argc, const char *argv[])
{
- if(argc > 0)
- options.filepath = argv[0];
+ if (argc > 0)
+ options.filepath = argv[0];
- return 0;
+ return 0;
}
static void options_parse(int argc, const char **argv)
{
- options.width = 0;
- options.height = 0;
- options.filepath = "";
- options.session = NULL;
- options.quiet = false;
-
- /* device names */
- string device_names = "";
- string devicename = "CPU";
- bool list = false;
-
- /* List devices for which support is compiled in. */
- vector<DeviceType> types = Device::available_types();
- foreach(DeviceType type, types) {
- if(device_names != "")
- device_names += ", ";
-
- device_names += Device::string_from_type(type);
- }
-
- /* shading system */
- string ssname = "svm";
-
- /* parse options */
- ArgParse ap;
- bool help = false, debug = false, version = false;
- int verbosity = 1;
-
- ap.options ("Usage: cycles [options] file.xml",
- "%*", files_parse, "",
- "--device %s", &devicename, ("Devices to use: " + device_names).c_str(),
+ options.width = 0;
+ options.height = 0;
+ options.filepath = "";
+ options.session = NULL;
+ options.quiet = false;
+
+ /* device names */
+ string device_names = "";
+ string devicename = "CPU";
+ bool list = false;
+
+ /* List devices for which support is compiled in. */
+ vector<DeviceType> types = Device::available_types();
+ foreach (DeviceType type, types) {
+ if (device_names != "")
+ device_names += ", ";
+
+ device_names += Device::string_from_type(type);
+ }
+
+ /* shading system */
+ string ssname = "svm";
+
+ /* parse options */
+ ArgParse ap;
+ bool help = false, debug = false, version = false;
+ int verbosity = 1;
+
+ ap.options("Usage: cycles [options] file.xml",
+ "%*",
+ files_parse,
+ "",
+ "--device %s",
+ &devicename,
+ ("Devices to use: " + device_names).c_str(),
#ifdef WITH_OSL
- "--shadingsys %s", &ssname, "Shading system to use: svm, osl",
+ "--shadingsys %s",
+ &ssname,
+ "Shading system to use: svm, osl",
#endif
- "--background", &options.session_params.background, "Render in background, without user interface",
- "--quiet", &options.quiet, "In background mode, don't print progress messages",
- "--samples %d", &options.session_params.samples, "Number of samples to render",
- "--output %s", &options.output_path, "File path to write output image",
- "--threads %d", &options.session_params.threads, "CPU Rendering Threads",
- "--width %d", &options.width, "Window width in pixel",
- "--height %d", &options.height, "Window height in pixel",
- "--tile-width %d", &options.session_params.tile_size.x, "Tile width in pixels",
- "--tile-height %d", &options.session_params.tile_size.y, "Tile height in pixels",
- "--list-devices", &list, "List information about all available devices",
+ "--background",
+ &options.session_params.background,
+ "Render in background, without user interface",
+ "--quiet",
+ &options.quiet,
+ "In background mode, don't print progress messages",
+ "--samples %d",
+ &options.session_params.samples,
+ "Number of samples to render",
+ "--output %s",
+ &options.output_path,
+ "File path to write output image",
+ "--threads %d",
+ &options.session_params.threads,
+ "CPU Rendering Threads",
+ "--width %d",
+ &options.width,
+ "Window width in pixel",
+ "--height %d",
+ &options.height,
+ "Window height in pixel",
+ "--tile-width %d",
+ &options.session_params.tile_size.x,
+ "Tile width in pixels",
+ "--tile-height %d",
+ &options.session_params.tile_size.y,
+ "Tile height in pixels",
+ "--list-devices",
+ &list,
+ "List information about all available devices",
#ifdef WITH_CYCLES_LOGGING
- "--debug", &debug, "Enable debug logging",
- "--verbose %d", &verbosity, "Set verbosity of the logger",
+ "--debug",
+ &debug,
+ "Enable debug logging",
+ "--verbose %d",
+ &verbosity,
+ "Set verbosity of the logger",
#endif
- "--help", &help, "Print help message",
- "--version", &version, "Print version number",
- NULL);
-
- if(ap.parse(argc, argv) < 0) {
- fprintf(stderr, "%s\n", ap.geterror().c_str());
- ap.usage();
- exit(EXIT_FAILURE);
- }
-
- if(debug) {
- util_logging_start();
- util_logging_verbosity_set(verbosity);
- }
-
- if(list) {
- vector<DeviceInfo> devices = Device::available_devices();
- printf("Devices:\n");
-
- foreach(DeviceInfo& info, devices) {
- printf(" %-10s%s%s\n",
- Device::string_from_type(info.type).c_str(),
- info.description.c_str(),
- (info.display_device)? " (display)": "");
- }
-
- exit(EXIT_SUCCESS);
- }
- else if(version) {
- printf("%s\n", CYCLES_VERSION_STRING);
- exit(EXIT_SUCCESS);
- }
- else if(help || options.filepath == "") {
- ap.usage();
- exit(EXIT_SUCCESS);
- }
-
- if(ssname == "osl")
- options.scene_params.shadingsystem = SHADINGSYSTEM_OSL;
- else if(ssname == "svm")
- options.scene_params.shadingsystem = SHADINGSYSTEM_SVM;
+ "--help",
+ &help,
+ "Print help message",
+ "--version",
+ &version,
+ "Print version number",
+ NULL);
+
+ if (ap.parse(argc, argv) < 0) {
+ fprintf(stderr, "%s\n", ap.geterror().c_str());
+ ap.usage();
+ exit(EXIT_FAILURE);
+ }
+
+ if (debug) {
+ util_logging_start();
+ util_logging_verbosity_set(verbosity);
+ }
+
+ if (list) {
+ vector<DeviceInfo> devices = Device::available_devices();
+ printf("Devices:\n");
+
+ foreach (DeviceInfo &info, devices) {
+ printf(" %-10s%s%s\n",
+ Device::string_from_type(info.type).c_str(),
+ info.description.c_str(),
+ (info.display_device) ? " (display)" : "");
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+ else if (version) {
+ printf("%s\n", CYCLES_VERSION_STRING);
+ exit(EXIT_SUCCESS);
+ }
+ else if (help || options.filepath == "") {
+ ap.usage();
+ exit(EXIT_SUCCESS);
+ }
+
+ if (ssname == "osl")
+ options.scene_params.shadingsystem = SHADINGSYSTEM_OSL;
+ else if (ssname == "svm")
+ options.scene_params.shadingsystem = SHADINGSYSTEM_SVM;
#ifndef WITH_CYCLES_STANDALONE_GUI
- options.session_params.background = true;
+ options.session_params.background = true;
#endif
- /* Use progressive rendering */
- options.session_params.progressive = true;
+ /* Use progressive rendering */
+ options.session_params.progressive = true;
- /* find matching device */
- DeviceType device_type = Device::type_from_string(devicename.c_str());
- vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK(device_type));
+ /* find matching device */
+ DeviceType device_type = Device::type_from_string(devicename.c_str());
+ vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK(device_type));
- bool device_available = false;
- if (!devices.empty()) {
- options.session_params.device = devices.front();
- device_available = true;
- }
+ bool device_available = false;
+ if (!devices.empty()) {
+ options.session_params.device = devices.front();
+ device_available = true;
+ }
- /* handle invalid configurations */
- if(options.session_params.device.type == DEVICE_NONE || !device_available) {
- fprintf(stderr, "Unknown device: %s\n", devicename.c_str());
- exit(EXIT_FAILURE);
- }
+ /* handle invalid configurations */
+ if (options.session_params.device.type == DEVICE_NONE || !device_available) {
+ fprintf(stderr, "Unknown device: %s\n", devicename.c_str());
+ exit(EXIT_FAILURE);
+ }
#ifdef WITH_OSL
- else if(!(ssname == "osl" || ssname == "svm")) {
- fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str());
- exit(EXIT_FAILURE);
- }
- else if(options.scene_params.shadingsystem == SHADINGSYSTEM_OSL && options.session_params.device.type != DEVICE_CPU) {
- fprintf(stderr, "OSL shading system only works with CPU device\n");
- exit(EXIT_FAILURE);
- }
+ else if (!(ssname == "osl" || ssname == "svm")) {
+ fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str());
+ exit(EXIT_FAILURE);
+ }
+ else if (options.scene_params.shadingsystem == SHADINGSYSTEM_OSL &&
+ options.session_params.device.type != DEVICE_CPU) {
+ fprintf(stderr, "OSL shading system only works with CPU device\n");
+ exit(EXIT_FAILURE);
+ }
#endif
- else if(options.session_params.samples < 0) {
- fprintf(stderr, "Invalid number of samples: %d\n", options.session_params.samples);
- exit(EXIT_FAILURE);
- }
- else if(options.filepath == "") {
- fprintf(stderr, "No file path specified\n");
- exit(EXIT_FAILURE);
- }
-
- /* For smoother Viewport */
- options.session_params.start_resolution = 64;
+ else if (options.session_params.samples < 0) {
+ fprintf(stderr, "Invalid number of samples: %d\n", options.session_params.samples);
+ exit(EXIT_FAILURE);
+ }
+ else if (options.filepath == "") {
+ fprintf(stderr, "No file path specified\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* For smoother Viewport */
+ options.session_params.start_resolution = 64;
}
CCL_NAMESPACE_END
@@ -493,26 +540,33 @@ using namespace ccl;
int main(int argc, const char **argv)
{
- util_logging_init(argv[0]);
- path_init();
- options_parse(argc, argv);
+ util_logging_init(argv[0]);
+ path_init();
+ options_parse(argc, argv);
#ifdef WITH_CYCLES_STANDALONE_GUI
- if(options.session_params.background) {
+ if (options.session_params.background) {
#endif
- session_init();
- options.session->wait();
- session_exit();
+ session_init();
+ options.session->wait();
+ session_exit();
#ifdef WITH_CYCLES_STANDALONE_GUI
- }
- else {
- string title = "Cycles: " + path_filename(options.filepath);
-
- /* init/exit are callback so they run while GL is initialized */
- view_main_loop(title.c_str(), options.width, options.height,
- session_init, session_exit, resize, display, keyboard, motion);
- }
+ }
+ else {
+ string title = "Cycles: " + path_filename(options.filepath);
+
+ /* init/exit are callback so they run while GL is initialized */
+ view_main_loop(title.c_str(),
+ options.width,
+ options.height,
+ session_init,
+ session_exit,
+ resize,
+ display,
+ keyboard,
+ motion);
+ }
#endif
- return 0;
+ return 0;
}
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index 86491adb3a4..9caf7068d3d 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -51,647 +51,649 @@ CCL_NAMESPACE_BEGIN
/* XML reading state */
struct XMLReadState : public XMLReader {
- Scene *scene; /* scene pointer */
- Transform tfm; /* current transform state */
- bool smooth; /* smooth normal state */
- Shader *shader; /* current shader */
- string base; /* base path to current file*/
- float dicing_rate; /* current dicing rate */
-
- XMLReadState()
- : scene(NULL),
- smooth(false),
- shader(NULL),
- dicing_rate(1.0f)
- {
- tfm = transform_identity();
- }
+ Scene *scene; /* scene pointer */
+ Transform tfm; /* current transform state */
+ bool smooth; /* smooth normal state */
+ Shader *shader; /* current shader */
+ string base; /* base path to current file*/
+ float dicing_rate; /* current dicing rate */
+
+ XMLReadState() : scene(NULL), smooth(false), shader(NULL), dicing_rate(1.0f)
+ {
+ tfm = transform_identity();
+ }
};
/* Attribute Reading */
static bool xml_read_int(int *value, xml_node node, const char *name)
{
- xml_attribute attr = node.attribute(name);
+ xml_attribute attr = node.attribute(name);
- if(attr) {
- *value = atoi(attr.value());
- return true;
- }
+ if (attr) {
+ *value = atoi(attr.value());
+ return true;
+ }
- return false;
+ return false;
}
-static bool xml_read_int_array(vector<int>& value, xml_node node, const char *name)
+static bool xml_read_int_array(vector<int> &value, xml_node node, const char *name)
{
- xml_attribute attr = node.attribute(name);
+ xml_attribute attr = node.attribute(name);
- if(attr) {
- vector<string> tokens;
- string_split(tokens, attr.value());
+ if (attr) {
+ vector<string> tokens;
+ string_split(tokens, attr.value());
- foreach(const string& token, tokens)
- value.push_back(atoi(token.c_str()));
+ foreach (const string &token, tokens)
+ value.push_back(atoi(token.c_str()));
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
static bool xml_read_float(float *value, xml_node node, const char *name)
{
- xml_attribute attr = node.attribute(name);
+ xml_attribute attr = node.attribute(name);
- if(attr) {
- *value = (float)atof(attr.value());
- return true;
- }
+ if (attr) {
+ *value = (float)atof(attr.value());
+ return true;
+ }
- return false;
+ return false;
}
-static bool xml_read_float_array(vector<float>& value, xml_node node, const char *name)
+static bool xml_read_float_array(vector<float> &value, xml_node node, const char *name)
{
- xml_attribute attr = node.attribute(name);
+ xml_attribute attr = node.attribute(name);
- if(attr) {
- vector<string> tokens;
- string_split(tokens, attr.value());
+ if (attr) {
+ vector<string> tokens;
+ string_split(tokens, attr.value());
- foreach(const string& token, tokens)
- value.push_back((float)atof(token.c_str()));
+ foreach (const string &token, tokens)
+ value.push_back((float)atof(token.c_str()));
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
static bool xml_read_float3(float3 *value, xml_node node, const char *name)
{
- vector<float> array;
+ vector<float> array;
- if(xml_read_float_array(array, node, name) && array.size() == 3) {
- *value = make_float3(array[0], array[1], array[2]);
- return true;
- }
+ if (xml_read_float_array(array, node, name) && array.size() == 3) {
+ *value = make_float3(array[0], array[1], array[2]);
+ return true;
+ }
- return false;
+ return false;
}
-static bool xml_read_float3_array(vector<float3>& value, xml_node node, const char *name)
+static bool xml_read_float3_array(vector<float3> &value, xml_node node, const char *name)
{
- vector<float> array;
+ vector<float> array;
- if(xml_read_float_array(array, node, name)) {
- for(size_t i = 0; i < array.size(); i += 3)
- value.push_back(make_float3(array[i+0], array[i+1], array[i+2]));
+ if (xml_read_float_array(array, node, name)) {
+ for (size_t i = 0; i < array.size(); i += 3)
+ value.push_back(make_float3(array[i + 0], array[i + 1], array[i + 2]));
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
static bool xml_read_float4(float4 *value, xml_node node, const char *name)
{
- vector<float> array;
+ vector<float> array;
- if(xml_read_float_array(array, node, name) && array.size() == 4) {
- *value = make_float4(array[0], array[1], array[2], array[3]);
- return true;
- }
+ if (xml_read_float_array(array, node, name) && array.size() == 4) {
+ *value = make_float4(array[0], array[1], array[2], array[3]);
+ return true;
+ }
- return false;
+ return false;
}
static bool xml_read_string(string *str, xml_node node, const char *name)
{
- xml_attribute attr = node.attribute(name);
+ xml_attribute attr = node.attribute(name);
- if(attr) {
- *str = attr.value();
- return true;
- }
+ if (attr) {
+ *str = attr.value();
+ return true;
+ }
- return false;
+ return false;
}
static bool xml_equal_string(xml_node node, const char *name, const char *value)
{
- xml_attribute attr = node.attribute(name);
+ xml_attribute attr = node.attribute(name);
- if(attr)
- return string_iequals(attr.value(), value);
+ if (attr)
+ return string_iequals(attr.value(), value);
- return false;
+ return false;
}
/* Camera */
-static void xml_read_camera(XMLReadState& state, xml_node node)
+static void xml_read_camera(XMLReadState &state, xml_node node)
{
- Camera *cam = state.scene->camera;
+ Camera *cam = state.scene->camera;
- xml_read_int(&cam->width, node, "width");
- xml_read_int(&cam->height, node, "height");
+ xml_read_int(&cam->width, node, "width");
+ xml_read_int(&cam->height, node, "height");
- cam->full_width = cam->width;
- cam->full_height = cam->height;
+ cam->full_width = cam->width;
+ cam->full_height = cam->height;
- xml_read_node(state, cam, node);
+ xml_read_node(state, cam, node);
- cam->matrix = state.tfm;
+ cam->matrix = state.tfm;
- cam->need_update = true;
- cam->update(state.scene);
+ cam->need_update = true;
+ cam->update(state.scene);
}
/* Shader */
-static void xml_read_shader_graph(XMLReadState& state, Shader *shader, xml_node graph_node)
+static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node graph_node)
{
- xml_read_node(state, shader, graph_node);
-
- ShaderGraph *graph = new ShaderGraph();
-
- /* local state, shader nodes can't link to nodes outside the shader graph */
- XMLReader graph_reader;
- graph_reader.node_map[ustring("output")] = graph->output();
-
- for(xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
- ustring node_name(node.name());
-
- if(node_name == "connect") {
- /* connect nodes */
- vector<string> from_tokens, to_tokens;
-
- string_split(from_tokens, node.attribute("from").value());
- string_split(to_tokens, node.attribute("to").value());
-
- if(from_tokens.size() == 2 && to_tokens.size() == 2) {
- ustring from_node_name(from_tokens[0]);
- ustring from_socket_name(from_tokens[1]);
- ustring to_node_name(to_tokens[0]);
- ustring to_socket_name(to_tokens[1]);
-
- /* find nodes and sockets */
- ShaderOutput *output = NULL;
- ShaderInput *input = NULL;
-
- if(graph_reader.node_map.find(from_node_name) != graph_reader.node_map.end()) {
- ShaderNode *fromnode = (ShaderNode*)graph_reader.node_map[from_node_name];
-
- foreach(ShaderOutput *out, fromnode->outputs)
- if(string_iequals(out->socket_type.name.string(), from_socket_name.string()))
- output = out;
-
- if(!output)
- fprintf(stderr, "Unknown output socket name \"%s\" on \"%s\".\n", from_node_name.c_str(), from_socket_name.c_str());
- }
- else
- fprintf(stderr, "Unknown shader node name \"%s\".\n", from_node_name.c_str());
-
- if(graph_reader.node_map.find(to_node_name) != graph_reader.node_map.end()) {
- ShaderNode *tonode = (ShaderNode*)graph_reader.node_map[to_node_name];
-
- foreach(ShaderInput *in, tonode->inputs)
- if(string_iequals(in->socket_type.name.string(), to_socket_name.string()))
- input = in;
-
- if(!input)
- fprintf(stderr, "Unknown input socket name \"%s\" on \"%s\".\n", to_socket_name.c_str(), to_node_name.c_str());
- }
- else
- fprintf(stderr, "Unknown shader node name \"%s\".\n", to_node_name.c_str());
-
- /* connect */
- if(output && input)
- graph->connect(output, input);
- }
- else
- fprintf(stderr, "Invalid from or to value for connect node.\n");
-
- continue;
- }
-
- ShaderNode *snode = NULL;
+ xml_read_node(state, shader, graph_node);
+
+ ShaderGraph *graph = new ShaderGraph();
+
+ /* local state, shader nodes can't link to nodes outside the shader graph */
+ XMLReader graph_reader;
+ graph_reader.node_map[ustring("output")] = graph->output();
+
+ for (xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
+ ustring node_name(node.name());
+
+ if (node_name == "connect") {
+ /* connect nodes */
+ vector<string> from_tokens, to_tokens;
+
+ string_split(from_tokens, node.attribute("from").value());
+ string_split(to_tokens, node.attribute("to").value());
+
+ if (from_tokens.size() == 2 && to_tokens.size() == 2) {
+ ustring from_node_name(from_tokens[0]);
+ ustring from_socket_name(from_tokens[1]);
+ ustring to_node_name(to_tokens[0]);
+ ustring to_socket_name(to_tokens[1]);
+
+ /* find nodes and sockets */
+ ShaderOutput *output = NULL;
+ ShaderInput *input = NULL;
+
+ if (graph_reader.node_map.find(from_node_name) != graph_reader.node_map.end()) {
+ ShaderNode *fromnode = (ShaderNode *)graph_reader.node_map[from_node_name];
+
+ foreach (ShaderOutput *out, fromnode->outputs)
+ if (string_iequals(out->socket_type.name.string(), from_socket_name.string()))
+ output = out;
+
+ if (!output)
+ fprintf(stderr,
+ "Unknown output socket name \"%s\" on \"%s\".\n",
+ from_node_name.c_str(),
+ from_socket_name.c_str());
+ }
+ else
+ fprintf(stderr, "Unknown shader node name \"%s\".\n", from_node_name.c_str());
+
+ if (graph_reader.node_map.find(to_node_name) != graph_reader.node_map.end()) {
+ ShaderNode *tonode = (ShaderNode *)graph_reader.node_map[to_node_name];
+
+ foreach (ShaderInput *in, tonode->inputs)
+ if (string_iequals(in->socket_type.name.string(), to_socket_name.string()))
+ input = in;
+
+ if (!input)
+ fprintf(stderr,
+ "Unknown input socket name \"%s\" on \"%s\".\n",
+ to_socket_name.c_str(),
+ to_node_name.c_str());
+ }
+ else
+ fprintf(stderr, "Unknown shader node name \"%s\".\n", to_node_name.c_str());
+
+ /* connect */
+ if (output && input)
+ graph->connect(output, input);
+ }
+ else
+ fprintf(stderr, "Invalid from or to value for connect node.\n");
+
+ continue;
+ }
+
+ ShaderNode *snode = NULL;
#ifdef WITH_OSL
- if(node_name == "osl_shader") {
- ShaderManager *manager = state.scene->shader_manager;
-
- if(manager->use_osl()) {
- std::string filepath;
-
- if(xml_read_string(&filepath, node, "src")) {
- if(path_is_relative(filepath)) {
- filepath = path_join(state.base, filepath);
- }
-
- snode = ((OSLShaderManager*)manager)->osl_node(filepath);
-
- if(!snode) {
- fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str());
- continue;
- }
- }
- else {
- fprintf(stderr, "OSL node missing \"src\" attribute.\n");
- continue;
- }
- }
- else {
- fprintf(stderr, "OSL node without using --shadingsys osl.\n");
- continue;
- }
- }
- else
+ if (node_name == "osl_shader") {
+ ShaderManager *manager = state.scene->shader_manager;
+
+ if (manager->use_osl()) {
+ std::string filepath;
+
+ if (xml_read_string(&filepath, node, "src")) {
+ if (path_is_relative(filepath)) {
+ filepath = path_join(state.base, filepath);
+ }
+
+ snode = ((OSLShaderManager *)manager)->osl_node(filepath);
+
+ if (!snode) {
+ fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str());
+ continue;
+ }
+ }
+ else {
+ fprintf(stderr, "OSL node missing \"src\" attribute.\n");
+ continue;
+ }
+ }
+ else {
+ fprintf(stderr, "OSL node without using --shadingsys osl.\n");
+ continue;
+ }
+ }
+ else
#endif
- {
- /* exception for name collision */
- if(node_name == "background")
- node_name = "background_shader";
-
- const NodeType *node_type = NodeType::find(node_name);
-
- if(!node_type) {
- fprintf(stderr, "Unknown shader node \"%s\".\n", node.name());
- continue;
- }
- else if(node_type->type != NodeType::SHADER) {
- fprintf(stderr, "Node type \"%s\" is not a shader node.\n", node_type->name.c_str());
- continue;
- }
-
- snode = (ShaderNode*) node_type->create(node_type);
- }
-
- xml_read_node(graph_reader, snode, node);
-
- if(node_name == "image_texture") {
- ImageTextureNode *img = (ImageTextureNode*) snode;
- img->filename = path_join(state.base, img->filename.string());
- }
- else if(node_name == "environment_texture") {
- EnvironmentTextureNode *env = (EnvironmentTextureNode*) snode;
- env->filename = path_join(state.base, env->filename.string());
- }
-
- if(snode) {
- /* add to graph */
- graph->add(snode);
- }
- }
-
- shader->set_graph(graph);
- shader->tag_update(state.scene);
+ {
+ /* exception for name collision */
+ if (node_name == "background")
+ node_name = "background_shader";
+
+ const NodeType *node_type = NodeType::find(node_name);
+
+ if (!node_type) {
+ fprintf(stderr, "Unknown shader node \"%s\".\n", node.name());
+ continue;
+ }
+ else if (node_type->type != NodeType::SHADER) {
+ fprintf(stderr, "Node type \"%s\" is not a shader node.\n", node_type->name.c_str());
+ continue;
+ }
+
+ snode = (ShaderNode *)node_type->create(node_type);
+ }
+
+ xml_read_node(graph_reader, snode, node);
+
+ if (node_name == "image_texture") {
+ ImageTextureNode *img = (ImageTextureNode *)snode;
+ img->filename = path_join(state.base, img->filename.string());
+ }
+ else if (node_name == "environment_texture") {
+ EnvironmentTextureNode *env = (EnvironmentTextureNode *)snode;
+ env->filename = path_join(state.base, env->filename.string());
+ }
+
+ if (snode) {
+ /* add to graph */
+ graph->add(snode);
+ }
+ }
+
+ shader->set_graph(graph);
+ shader->tag_update(state.scene);
}
-static void xml_read_shader(XMLReadState& state, xml_node node)
+static void xml_read_shader(XMLReadState &state, xml_node node)
{
- Shader *shader = new Shader();
- xml_read_shader_graph(state, shader, node);
- state.scene->shaders.push_back(shader);
+ Shader *shader = new Shader();
+ xml_read_shader_graph(state, shader, node);
+ state.scene->shaders.push_back(shader);
}
/* Background */
-static void xml_read_background(XMLReadState& state, xml_node node)
+static void xml_read_background(XMLReadState &state, xml_node node)
{
- /* Background Settings */
- xml_read_node(state, state.scene->background, node);
+ /* Background Settings */
+ xml_read_node(state, state.scene->background, node);
- /* Background Shader */
- Shader *shader = state.scene->default_background;
- xml_read_shader_graph(state, shader, node);
+ /* Background Shader */
+ Shader *shader = state.scene->default_background;
+ xml_read_shader_graph(state, shader, node);
}
/* Mesh */
-static Mesh *xml_add_mesh(Scene *scene, const Transform& tfm)
+static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm)
{
- /* create mesh */
- Mesh *mesh = new Mesh();
- scene->meshes.push_back(mesh);
+ /* create mesh */
+ Mesh *mesh = new Mesh();
+ scene->meshes.push_back(mesh);
- /* create object*/
- Object *object = new Object();
- object->mesh = mesh;
- object->tfm = tfm;
- scene->objects.push_back(object);
+ /* create object*/
+ Object *object = new Object();
+ object->mesh = mesh;
+ object->tfm = tfm;
+ scene->objects.push_back(object);
- return mesh;
+ return mesh;
}
-static void xml_read_mesh(const XMLReadState& state, xml_node node)
+static void xml_read_mesh(const XMLReadState &state, xml_node node)
{
- /* add mesh */
- Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
- mesh->used_shaders.push_back(state.shader);
-
- /* read state */
- int shader = 0;
- bool smooth = state.smooth;
-
- /* read vertices and polygons */
- vector<float3> P;
- vector<float> UV;
- vector<int> verts, nverts;
-
- xml_read_float3_array(P, node, "P");
- xml_read_int_array(verts, node, "verts");
- xml_read_int_array(nverts, node, "nverts");
-
- if(xml_equal_string(node, "subdivision", "catmull-clark")) {
- mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
- }
- else if(xml_equal_string(node, "subdivision", "linear")) {
- mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
- }
-
- if(mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
- /* create vertices */
- mesh->verts = P;
-
- size_t num_triangles = 0;
- for(size_t i = 0; i < nverts.size(); i++)
- num_triangles += nverts[i]-2;
- mesh->reserve_mesh(mesh->verts.size(), num_triangles);
-
- /* create triangles */
- int index_offset = 0;
-
- for(size_t i = 0; i < nverts.size(); i++) {
- for(int j = 0; j < nverts[i]-2; j++) {
- int v0 = verts[index_offset];
- int v1 = verts[index_offset + j + 1];
- int v2 = verts[index_offset + j + 2];
-
- assert(v0 < (int)P.size());
- assert(v1 < (int)P.size());
- assert(v2 < (int)P.size());
-
- mesh->add_triangle(v0, v1, v2, shader, smooth);
- }
-
- index_offset += nverts[i];
- }
-
- if(xml_read_float_array(UV, node, "UV")) {
- ustring name = ustring("UVMap");
- Attribute *attr = mesh->attributes.add(ATTR_STD_UV, name);
- float2 *fdata = attr->data_float2();
-
- /* loop over the triangles */
- index_offset = 0;
- for(size_t i = 0; i < nverts.size(); i++) {
- for(int j = 0; j < nverts[i]-2; j++) {
- int v0 = index_offset;
- int v1 = index_offset + j + 1;
- int v2 = index_offset + j + 2;
-
- assert(v0*2+1 < (int)UV.size());
- assert(v1*2+1 < (int)UV.size());
- assert(v2*2+1 < (int)UV.size());
-
- fdata[0] = make_float2(UV[v0*2], UV[v0*2+1]);
- fdata[1] = make_float2(UV[v1*2], UV[v1*2+1]);
- fdata[2] = make_float2(UV[v2*2], UV[v2*2+1]);
- fdata += 3;
- }
-
- index_offset += nverts[i];
- }
- }
- }
- else {
- /* create vertices */
- mesh->verts = P;
-
- size_t num_ngons = 0;
- size_t num_corners = 0;
- for(size_t i = 0; i < nverts.size(); i++) {
- num_ngons += (nverts[i] == 4) ? 0 : 1;
- num_corners += nverts[i];
- }
- mesh->reserve_subd_faces(nverts.size(), num_ngons, num_corners);
-
- /* create subd_faces */
- int index_offset = 0;
-
- for(size_t i = 0; i < nverts.size(); i++) {
- mesh->add_subd_face(&verts[index_offset], nverts[i], shader, smooth);
- index_offset += nverts[i];
- }
-
- /* uv map */
- if(xml_read_float_array(UV, node, "UV")) {
- ustring name = ustring("UVMap");
- Attribute *attr = mesh->subd_attributes.add(ATTR_STD_UV, name);
- float3 *fdata = attr->data_float3();
+ /* add mesh */
+ Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
+ mesh->used_shaders.push_back(state.shader);
+
+ /* read state */
+ int shader = 0;
+ bool smooth = state.smooth;
+
+ /* read vertices and polygons */
+ vector<float3> P;
+ vector<float> UV;
+ vector<int> verts, nverts;
+
+ xml_read_float3_array(P, node, "P");
+ xml_read_int_array(verts, node, "verts");
+ xml_read_int_array(nverts, node, "nverts");
+
+ if (xml_equal_string(node, "subdivision", "catmull-clark")) {
+ mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
+ }
+ else if (xml_equal_string(node, "subdivision", "linear")) {
+ mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
+ }
+
+ if (mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
+ /* create vertices */
+ mesh->verts = P;
+
+ size_t num_triangles = 0;
+ for (size_t i = 0; i < nverts.size(); i++)
+ num_triangles += nverts[i] - 2;
+ mesh->reserve_mesh(mesh->verts.size(), num_triangles);
+
+ /* create triangles */
+ int index_offset = 0;
+
+ for (size_t i = 0; i < nverts.size(); i++) {
+ for (int j = 0; j < nverts[i] - 2; j++) {
+ int v0 = verts[index_offset];
+ int v1 = verts[index_offset + j + 1];
+ int v2 = verts[index_offset + j + 2];
+
+ assert(v0 < (int)P.size());
+ assert(v1 < (int)P.size());
+ assert(v2 < (int)P.size());
+
+ mesh->add_triangle(v0, v1, v2, shader, smooth);
+ }
+
+ index_offset += nverts[i];
+ }
+
+ if (xml_read_float_array(UV, node, "UV")) {
+ ustring name = ustring("UVMap");
+ Attribute *attr = mesh->attributes.add(ATTR_STD_UV, name);
+ float2 *fdata = attr->data_float2();
+
+ /* loop over the triangles */
+ index_offset = 0;
+ for (size_t i = 0; i < nverts.size(); i++) {
+ for (int j = 0; j < nverts[i] - 2; j++) {
+ int v0 = index_offset;
+ int v1 = index_offset + j + 1;
+ int v2 = index_offset + j + 2;
+
+ assert(v0 * 2 + 1 < (int)UV.size());
+ assert(v1 * 2 + 1 < (int)UV.size());
+ assert(v2 * 2 + 1 < (int)UV.size());
+
+ fdata[0] = make_float2(UV[v0 * 2], UV[v0 * 2 + 1]);
+ fdata[1] = make_float2(UV[v1 * 2], UV[v1 * 2 + 1]);
+ fdata[2] = make_float2(UV[v2 * 2], UV[v2 * 2 + 1]);
+ fdata += 3;
+ }
+
+ index_offset += nverts[i];
+ }
+ }
+ }
+ else {
+ /* create vertices */
+ mesh->verts = P;
+
+ size_t num_ngons = 0;
+ size_t num_corners = 0;
+ for (size_t i = 0; i < nverts.size(); i++) {
+ num_ngons += (nverts[i] == 4) ? 0 : 1;
+ num_corners += nverts[i];
+ }
+ mesh->reserve_subd_faces(nverts.size(), num_ngons, num_corners);
+
+ /* create subd_faces */
+ int index_offset = 0;
+
+ for (size_t i = 0; i < nverts.size(); i++) {
+ mesh->add_subd_face(&verts[index_offset], nverts[i], shader, smooth);
+ index_offset += nverts[i];
+ }
+
+ /* uv map */
+ if (xml_read_float_array(UV, node, "UV")) {
+ ustring name = ustring("UVMap");
+ Attribute *attr = mesh->subd_attributes.add(ATTR_STD_UV, name);
+ float3 *fdata = attr->data_float3();
#if 0
- if(subdivide_uvs) {
- attr->flags |= ATTR_SUBDIVIDED;
- }
+ if(subdivide_uvs) {
+ attr->flags |= ATTR_SUBDIVIDED;
+ }
#endif
- index_offset = 0;
- for(size_t i = 0; i < nverts.size(); i++) {
- for(int j = 0; j < nverts[i]; j++) {
- *(fdata++) = make_float3(UV[index_offset++]);
- }
- }
- }
-
- /* setup subd params */
- if(!mesh->subd_params) {
- mesh->subd_params = new SubdParams(mesh);
- }
- SubdParams& sdparams = *mesh->subd_params;
-
- sdparams.dicing_rate = state.dicing_rate;
- xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
- sdparams.dicing_rate = std::max(0.1f, sdparams.dicing_rate);
-
- sdparams.objecttoworld = state.tfm;
- }
-
- /* we don't yet support arbitrary attributes, for now add vertex
- * coordinates as generated coordinates if requested */
- if(mesh->need_attribute(state.scene, ATTR_STD_GENERATED)) {
- Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
- memcpy(attr->data_float3(), mesh->verts.data(), sizeof(float3)*mesh->verts.size());
- }
+ index_offset = 0;
+ for (size_t i = 0; i < nverts.size(); i++) {
+ for (int j = 0; j < nverts[i]; j++) {
+ *(fdata++) = make_float3(UV[index_offset++]);
+ }
+ }
+ }
+
+ /* setup subd params */
+ if (!mesh->subd_params) {
+ mesh->subd_params = new SubdParams(mesh);
+ }
+ SubdParams &sdparams = *mesh->subd_params;
+
+ sdparams.dicing_rate = state.dicing_rate;
+ xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
+ sdparams.dicing_rate = std::max(0.1f, sdparams.dicing_rate);
+
+ sdparams.objecttoworld = state.tfm;
+ }
+
+ /* we don't yet support arbitrary attributes, for now add vertex
+ * coordinates as generated coordinates if requested */
+ if (mesh->need_attribute(state.scene, ATTR_STD_GENERATED)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+ memcpy(attr->data_float3(), mesh->verts.data(), sizeof(float3) * mesh->verts.size());
+ }
}
/* Light */
-static void xml_read_light(XMLReadState& state, xml_node node)
+static void xml_read_light(XMLReadState &state, xml_node node)
{
- Light *light = new Light();
+ Light *light = new Light();
- light->shader = state.shader;
- xml_read_node(state, light, node);
+ light->shader = state.shader;
+ xml_read_node(state, light, node);
- state.scene->lights.push_back(light);
+ state.scene->lights.push_back(light);
}
/* Transform */
-static void xml_read_transform(xml_node node, Transform& tfm)
+static void xml_read_transform(xml_node node, Transform &tfm)
{
- if(node.attribute("matrix")) {
- vector<float> matrix;
- if(xml_read_float_array(matrix, node, "matrix") && matrix.size() == 16) {
- ProjectionTransform projection = *(ProjectionTransform*)&matrix[0];
- tfm = tfm * projection_to_transform(projection_transpose(projection));
- }
- }
-
- if(node.attribute("translate")) {
- float3 translate = make_float3(0.0f, 0.0f, 0.0f);
- xml_read_float3(&translate, node, "translate");
- tfm = tfm * transform_translate(translate);
- }
-
- if(node.attribute("rotate")) {
- float4 rotate = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- xml_read_float4(&rotate, node, "rotate");
- tfm = tfm * transform_rotate(DEG2RADF(rotate.x), make_float3(rotate.y, rotate.z, rotate.w));
- }
-
- if(node.attribute("scale")) {
- float3 scale = make_float3(0.0f, 0.0f, 0.0f);
- xml_read_float3(&scale, node, "scale");
- tfm = tfm * transform_scale(scale);
- }
+ if (node.attribute("matrix")) {
+ vector<float> matrix;
+ if (xml_read_float_array(matrix, node, "matrix") && matrix.size() == 16) {
+ ProjectionTransform projection = *(ProjectionTransform *)&matrix[0];
+ tfm = tfm * projection_to_transform(projection_transpose(projection));
+ }
+ }
+
+ if (node.attribute("translate")) {
+ float3 translate = make_float3(0.0f, 0.0f, 0.0f);
+ xml_read_float3(&translate, node, "translate");
+ tfm = tfm * transform_translate(translate);
+ }
+
+ if (node.attribute("rotate")) {
+ float4 rotate = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ xml_read_float4(&rotate, node, "rotate");
+ tfm = tfm * transform_rotate(DEG2RADF(rotate.x), make_float3(rotate.y, rotate.z, rotate.w));
+ }
+
+ if (node.attribute("scale")) {
+ float3 scale = make_float3(0.0f, 0.0f, 0.0f);
+ xml_read_float3(&scale, node, "scale");
+ tfm = tfm * transform_scale(scale);
+ }
}
/* State */
-static void xml_read_state(XMLReadState& state, xml_node node)
+static void xml_read_state(XMLReadState &state, xml_node node)
{
- /* read shader */
- string shadername;
-
- if(xml_read_string(&shadername, node, "shader")) {
- bool found = false;
-
- foreach(Shader *shader, state.scene->shaders) {
- if(shader->name == shadername) {
- state.shader = shader;
- found = true;
- break;
- }
- }
-
- if(!found)
- fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
- }
-
- xml_read_float(&state.dicing_rate, node, "dicing_rate");
-
- /* read smooth/flat */
- if(xml_equal_string(node, "interpolation", "smooth"))
- state.smooth = true;
- else if(xml_equal_string(node, "interpolation", "flat"))
- state.smooth = false;
+ /* read shader */
+ string shadername;
+
+ if (xml_read_string(&shadername, node, "shader")) {
+ bool found = false;
+
+ foreach (Shader *shader, state.scene->shaders) {
+ if (shader->name == shadername) {
+ state.shader = shader;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
+ }
+
+ xml_read_float(&state.dicing_rate, node, "dicing_rate");
+
+ /* read smooth/flat */
+ if (xml_equal_string(node, "interpolation", "smooth"))
+ state.smooth = true;
+ else if (xml_equal_string(node, "interpolation", "flat"))
+ state.smooth = false;
}
/* Scene */
-static void xml_read_include(XMLReadState& state, const string& src);
+static void xml_read_include(XMLReadState &state, const string &src);
-static void xml_read_scene(XMLReadState& state, xml_node scene_node)
+static void xml_read_scene(XMLReadState &state, xml_node scene_node)
{
- for(xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
- if(string_iequals(node.name(), "film")) {
- xml_read_node(state, state.scene->film, node);
- }
- else if(string_iequals(node.name(), "integrator")) {
- xml_read_node(state, state.scene->integrator, node);
- }
- else if(string_iequals(node.name(), "camera")) {
- xml_read_camera(state, node);
- }
- else if(string_iequals(node.name(), "shader")) {
- xml_read_shader(state, node);
- }
- else if(string_iequals(node.name(), "background")) {
- xml_read_background(state, node);
- }
- else if(string_iequals(node.name(), "mesh")) {
- xml_read_mesh(state, node);
- }
- else if(string_iequals(node.name(), "light")) {
- xml_read_light(state, node);
- }
- else if(string_iequals(node.name(), "transform")) {
- XMLReadState substate = state;
-
- xml_read_transform(node, substate.tfm);
- xml_read_scene(substate, node);
- }
- else if(string_iequals(node.name(), "state")) {
- XMLReadState substate = state;
-
- xml_read_state(substate, node);
- xml_read_scene(substate, node);
- }
- else if(string_iequals(node.name(), "include")) {
- string src;
-
- if(xml_read_string(&src, node, "src"))
- xml_read_include(state, src);
- }
- else
- fprintf(stderr, "Unknown node \"%s\".\n", node.name());
- }
+ for (xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
+ if (string_iequals(node.name(), "film")) {
+ xml_read_node(state, state.scene->film, node);
+ }
+ else if (string_iequals(node.name(), "integrator")) {
+ xml_read_node(state, state.scene->integrator, node);
+ }
+ else if (string_iequals(node.name(), "camera")) {
+ xml_read_camera(state, node);
+ }
+ else if (string_iequals(node.name(), "shader")) {
+ xml_read_shader(state, node);
+ }
+ else if (string_iequals(node.name(), "background")) {
+ xml_read_background(state, node);
+ }
+ else if (string_iequals(node.name(), "mesh")) {
+ xml_read_mesh(state, node);
+ }
+ else if (string_iequals(node.name(), "light")) {
+ xml_read_light(state, node);
+ }
+ else if (string_iequals(node.name(), "transform")) {
+ XMLReadState substate = state;
+
+ xml_read_transform(node, substate.tfm);
+ xml_read_scene(substate, node);
+ }
+ else if (string_iequals(node.name(), "state")) {
+ XMLReadState substate = state;
+
+ xml_read_state(substate, node);
+ xml_read_scene(substate, node);
+ }
+ else if (string_iequals(node.name(), "include")) {
+ string src;
+
+ if (xml_read_string(&src, node, "src"))
+ xml_read_include(state, src);
+ }
+ else
+ fprintf(stderr, "Unknown node \"%s\".\n", node.name());
+ }
}
/* Include */
-static void xml_read_include(XMLReadState& state, const string& src)
+static void xml_read_include(XMLReadState &state, const string &src)
{
- /* open XML document */
- xml_document doc;
- xml_parse_result parse_result;
-
- string path = path_join(state.base, src);
- parse_result = doc.load_file(path.c_str());
-
- if(parse_result) {
- XMLReadState substate = state;
- substate.base = path_dirname(path);
-
- xml_node cycles = doc.child("cycles");
- xml_read_scene(substate, cycles);
- }
- else {
- fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description());
- exit(EXIT_FAILURE);
- }
+ /* open XML document */
+ xml_document doc;
+ xml_parse_result parse_result;
+
+ string path = path_join(state.base, src);
+ parse_result = doc.load_file(path.c_str());
+
+ if (parse_result) {
+ XMLReadState substate = state;
+ substate.base = path_dirname(path);
+
+ xml_node cycles = doc.child("cycles");
+ xml_read_scene(substate, cycles);
+ }
+ else {
+ fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description());
+ exit(EXIT_FAILURE);
+ }
}
/* File */
void xml_read_file(Scene *scene, const char *filepath)
{
- XMLReadState state;
+ XMLReadState state;
- state.scene = scene;
- state.tfm = transform_identity();
- state.shader = scene->default_surface;
- state.smooth = false;
- state.dicing_rate = 1.0f;
- state.base = path_dirname(filepath);
+ state.scene = scene;
+ state.tfm = transform_identity();
+ state.shader = scene->default_surface;
+ state.smooth = false;
+ state.dicing_rate = 1.0f;
+ state.base = path_dirname(filepath);
- xml_read_include(state, path_filename(filepath));
+ xml_read_include(state, path_filename(filepath));
- scene->params.bvh_type = SceneParams::BVH_STATIC;
+ scene->params.bvh_type = SceneParams::BVH_STATIC;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/app/cycles_xml.h b/intern/cycles/app/cycles_xml.h
index a7bc1895d4e..6a48980d8ea 100644
--- a/intern/cycles/app/cycles_xml.h
+++ b/intern/cycles/app/cycles_xml.h
@@ -29,4 +29,4 @@ void xml_read_file(Scene *scene, const char *filepath);
CCL_NAMESPACE_END
-#endif /* __CYCLES_XML_H__ */
+#endif /* __CYCLES_XML_H__ */
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
index b9750ad0c53..233ffc8802c 100644
--- a/intern/cycles/blender/CCL_api.h
+++ b/intern/cycles/blender/CCL_api.h
@@ -33,4 +33,4 @@ void CCL_logging_verbosity_set(int verbosity);
}
#endif
-#endif /* __CCL_API_H__ */
+#endif /* __CCL_API_H__ */
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index fc265a47a01..7354b1e615e 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -1,68 +1,68 @@
set(INC
- ..
- ../../glew-mx
- ../../guardedalloc
- ../../mikktspace
- ../../../source/blender/makesdna
- ../../../source/blender/makesrna
- ../../../source/blender/blenlib
- ${CMAKE_BINARY_DIR}/source/blender/makesrna/intern
+ ..
+ ../../glew-mx
+ ../../guardedalloc
+ ../../mikktspace
+ ../../../source/blender/makesdna
+ ../../../source/blender/makesrna
+ ../../../source/blender/blenlib
+ ${CMAKE_BINARY_DIR}/source/blender/makesrna/intern
)
set(INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- ${GLEW_INCLUDE_DIR}
+ ${PYTHON_INCLUDE_DIRS}
+ ${GLEW_INCLUDE_DIR}
)
set(SRC
- blender_camera.cpp
- blender_device.cpp
- blender_mesh.cpp
- blender_object.cpp
- blender_object_cull.cpp
- blender_particles.cpp
- blender_curves.cpp
- blender_logging.cpp
- blender_python.cpp
- blender_session.cpp
- blender_shader.cpp
- blender_sync.cpp
- blender_texture.cpp
+ blender_camera.cpp
+ blender_device.cpp
+ blender_mesh.cpp
+ blender_object.cpp
+ blender_object_cull.cpp
+ blender_particles.cpp
+ blender_curves.cpp
+ blender_logging.cpp
+ blender_python.cpp
+ blender_session.cpp
+ blender_shader.cpp
+ blender_sync.cpp
+ blender_texture.cpp
- CCL_api.h
- blender_object_cull.h
- blender_sync.h
- blender_session.h
- blender_texture.h
- blender_util.h
+ CCL_api.h
+ blender_object_cull.h
+ blender_sync.h
+ blender_session.h
+ blender_texture.h
+ blender_util.h
)
set(LIB
- cycles_bvh
- cycles_device
- cycles_graph
- cycles_kernel
- cycles_render
- cycles_subd
- cycles_util
+ cycles_bvh
+ cycles_device
+ cycles_graph
+ cycles_kernel
+ cycles_render
+ cycles_subd
+ cycles_util
)
if(WITH_CYCLES_LOGGING)
- list(APPEND LIB
- extern_glog
- )
+ list(APPEND LIB
+ extern_glog
+ )
endif()
set(ADDON_FILES
- addon/__init__.py
- addon/engine.py
- addon/operators.py
- addon/osl.py
- addon/presets.py
- addon/properties.py
- addon/ui.py
- addon/version_update.py
+ addon/__init__.py
+ addon/engine.py
+ addon/operators.py
+ addon/osl.py
+ addon/presets.py
+ addon/properties.py
+ addon/ui.py
+ addon/version_update.py
)
add_definitions(${GL_DEFINITIONS})
@@ -72,14 +72,14 @@ if(WITH_CYCLES_DEVICE_OPENCL)
endif()
if(WITH_CYCLES_NETWORK)
- add_definitions(-DWITH_NETWORK)
+ add_definitions(-DWITH_NETWORK)
endif()
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# avoid link failure with clang 3.4 debug
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gline-tables-only")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gline-tables-only")
endif()
add_dependencies(bf_intern_cycles bf_rna)
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 21efba4cdf0..b3bfaa992a9 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -28,875 +28,858 @@ CCL_NAMESPACE_BEGIN
* render camera to this, and from there convert to our native camera format. */
struct BlenderCamera {
- float nearclip;
- float farclip;
+ float nearclip;
+ float farclip;
- CameraType type;
- float ortho_scale;
+ CameraType type;
+ float ortho_scale;
- float lens;
- float shuttertime;
- Camera::MotionPosition motion_position;
- array<float> shutter_curve;
+ float lens;
+ float shuttertime;
+ Camera::MotionPosition motion_position;
+ array<float> shutter_curve;
- Camera::RollingShutterType rolling_shutter_type;
- float rolling_shutter_duration;
+ Camera::RollingShutterType rolling_shutter_type;
+ float rolling_shutter_duration;
- float aperturesize;
- uint apertureblades;
- float aperturerotation;
- float focaldistance;
+ float aperturesize;
+ uint apertureblades;
+ float aperturerotation;
+ float focaldistance;
- float2 shift;
- float2 offset;
- float zoom;
+ float2 shift;
+ float2 offset;
+ float zoom;
- float2 pixelaspect;
+ float2 pixelaspect;
- float aperture_ratio;
+ float aperture_ratio;
- PanoramaType panorama_type;
- float fisheye_fov;
- float fisheye_lens;
- float latitude_min;
- float latitude_max;
- float longitude_min;
- float longitude_max;
- bool use_spherical_stereo;
- float interocular_distance;
- float convergence_distance;
- bool use_pole_merge;
- float pole_merge_angle_from;
- float pole_merge_angle_to;
+ PanoramaType panorama_type;
+ float fisheye_fov;
+ float fisheye_lens;
+ float latitude_min;
+ float latitude_max;
+ float longitude_min;
+ float longitude_max;
+ bool use_spherical_stereo;
+ float interocular_distance;
+ float convergence_distance;
+ bool use_pole_merge;
+ float pole_merge_angle_from;
+ float pole_merge_angle_to;
- enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
- float sensor_width;
- float sensor_height;
+ enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
+ float sensor_width;
+ float sensor_height;
- int full_width;
- int full_height;
+ int full_width;
+ int full_height;
- BoundBox2D border;
- BoundBox2D pano_viewplane;
- BoundBox2D viewport_camera_border;
+ BoundBox2D border;
+ BoundBox2D pano_viewplane;
+ BoundBox2D viewport_camera_border;
- Transform matrix;
+ Transform matrix;
- float offscreen_dicing_scale;
+ float offscreen_dicing_scale;
- int motion_steps;
+ int motion_steps;
};
-static void blender_camera_init(BlenderCamera *bcam,
- BL::RenderSettings& b_render)
+static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_render)
{
- memset((void *)bcam, 0, sizeof(BlenderCamera));
-
- bcam->type = CAMERA_PERSPECTIVE;
- bcam->zoom = 1.0f;
- bcam->pixelaspect = make_float2(1.0f, 1.0f);
- bcam->sensor_width = 36.0f;
- bcam->sensor_height = 24.0f;
- bcam->sensor_fit = BlenderCamera::AUTO;
- bcam->shuttertime = 1.0f;
- bcam->motion_position = Camera::MOTION_POSITION_CENTER;
- bcam->rolling_shutter_type = Camera::ROLLING_SHUTTER_NONE;
- bcam->rolling_shutter_duration = 0.1f;
- bcam->border.right = 1.0f;
- bcam->border.top = 1.0f;
- bcam->pano_viewplane.right = 1.0f;
- bcam->pano_viewplane.top = 1.0f;
- bcam->viewport_camera_border.right = 1.0f;
- bcam->viewport_camera_border.top = 1.0f;
- bcam->offscreen_dicing_scale = 1.0f;
-
- /* render resolution */
- bcam->full_width = render_resolution_x(b_render);
- bcam->full_height = render_resolution_y(b_render);
+ memset((void *)bcam, 0, sizeof(BlenderCamera));
+
+ bcam->type = CAMERA_PERSPECTIVE;
+ bcam->zoom = 1.0f;
+ bcam->pixelaspect = make_float2(1.0f, 1.0f);
+ bcam->sensor_width = 36.0f;
+ bcam->sensor_height = 24.0f;
+ bcam->sensor_fit = BlenderCamera::AUTO;
+ bcam->shuttertime = 1.0f;
+ bcam->motion_position = Camera::MOTION_POSITION_CENTER;
+ bcam->rolling_shutter_type = Camera::ROLLING_SHUTTER_NONE;
+ bcam->rolling_shutter_duration = 0.1f;
+ bcam->border.right = 1.0f;
+ bcam->border.top = 1.0f;
+ bcam->pano_viewplane.right = 1.0f;
+ bcam->pano_viewplane.top = 1.0f;
+ bcam->viewport_camera_border.right = 1.0f;
+ bcam->viewport_camera_border.top = 1.0f;
+ bcam->offscreen_dicing_scale = 1.0f;
+
+ /* render resolution */
+ bcam->full_width = render_resolution_x(b_render);
+ bcam->full_height = render_resolution_y(b_render);
}
-static float blender_camera_focal_distance(BL::RenderEngine& b_engine,
- BL::Object& b_ob,
- BL::Camera& b_camera,
+static float blender_camera_focal_distance(BL::RenderEngine &b_engine,
+ BL::Object &b_ob,
+ BL::Camera &b_camera,
BlenderCamera *bcam)
{
- BL::Object b_dof_object = b_camera.dof_object();
-
- if(!b_dof_object)
- return b_camera.dof_distance();
-
- /* for dof object, return distance along camera Z direction */
- BL::Array<float, 16> b_ob_matrix;
- b_engine.camera_model_matrix(b_ob, bcam->use_spherical_stereo, b_ob_matrix);
- Transform obmat = transform_clear_scale(get_transform(b_ob_matrix));
- Transform dofmat = get_transform(b_dof_object.matrix_world());
- float3 view_dir = normalize(transform_get_column(&obmat, 2));
- float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3);
- return fabsf(dot(view_dir, dof_dir));
+ BL::Object b_dof_object = b_camera.dof_object();
+
+ if (!b_dof_object)
+ return b_camera.dof_distance();
+
+ /* for dof object, return distance along camera Z direction */
+ BL::Array<float, 16> b_ob_matrix;
+ b_engine.camera_model_matrix(b_ob, bcam->use_spherical_stereo, b_ob_matrix);
+ Transform obmat = transform_clear_scale(get_transform(b_ob_matrix));
+ Transform dofmat = get_transform(b_dof_object.matrix_world());
+ float3 view_dir = normalize(transform_get_column(&obmat, 2));
+ float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3);
+ return fabsf(dot(view_dir, dof_dir));
}
static void blender_camera_from_object(BlenderCamera *bcam,
- BL::RenderEngine& b_engine,
- BL::Object& b_ob,
+ BL::RenderEngine &b_engine,
+ BL::Object &b_ob,
bool skip_panorama = false)
{
- BL::ID b_ob_data = b_ob.data();
-
- 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();
-
- switch(b_camera.type())
- {
- case BL::Camera::type_ORTHO:
- bcam->type = CAMERA_ORTHOGRAPHIC;
- break;
- case BL::Camera::type_PANO:
- if(!skip_panorama)
- bcam->type = CAMERA_PANORAMA;
- else
- bcam->type = CAMERA_PERSPECTIVE;
- break;
- case BL::Camera::type_PERSP:
- default:
- bcam->type = CAMERA_PERSPECTIVE;
- break;
- }
-
- bcam->panorama_type = (PanoramaType)get_enum(ccamera,
- "panorama_type",
- PANORAMA_NUM_TYPES,
- PANORAMA_EQUIRECTANGULAR);
-
- 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->interocular_distance = b_camera.stereo().interocular_distance();
- if(b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) {
- bcam->convergence_distance = FLT_MAX;
- }
- else {
- bcam->convergence_distance = b_camera.stereo().convergence_distance();
- }
- bcam->use_spherical_stereo = b_engine.use_spherical_stereo(b_ob);
-
- bcam->use_pole_merge = b_camera.stereo().use_pole_merge();
- bcam->pole_merge_angle_from = b_camera.stereo().pole_merge_angle_from();
- bcam->pole_merge_angle_to = b_camera.stereo().pole_merge_angle_to();
-
- bcam->ortho_scale = b_camera.ortho_scale();
-
- bcam->lens = b_camera.lens();
-
- /* allow f/stop number to change aperture_size but still
- * give manual control over aperture radius */
- int aperture_type = get_enum(ccamera, "aperture_type");
-
- if(aperture_type == 1) {
- float fstop = RNA_float_get(&ccamera, "aperture_fstop");
- fstop = max(fstop, 1e-5f);
-
- if(bcam->type == CAMERA_ORTHOGRAPHIC)
- bcam->aperturesize = 1.0f/(2.0f*fstop);
- else
- bcam->aperturesize = (bcam->lens*1e-3f)/(2.0f*fstop);
- }
- else
- bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size");
-
- bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
- bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
- bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera, bcam);
- bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
-
- bcam->shift.x = b_engine.camera_shift_x(b_ob, bcam->use_spherical_stereo);
- bcam->shift.y = b_camera.shift_y();
-
- bcam->sensor_width = b_camera.sensor_width();
- bcam->sensor_height = b_camera.sensor_height();
-
- if(b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO)
- bcam->sensor_fit = BlenderCamera::AUTO;
- else if(b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL)
- bcam->sensor_fit = BlenderCamera::HORIZONTAL;
- else
- bcam->sensor_fit = BlenderCamera::VERTICAL;
- }
- else if(b_ob_data.is_a(&RNA_Light)) {
- /* Can also look through spot light. */
- BL::SpotLight b_light(b_ob_data);
- float lens = 16.0f / tanf(b_light.spot_size() * 0.5f);
- if (lens > 0.0f) {
- bcam->lens = lens;
- }
- }
-
- bcam->motion_steps = object_motion_steps(b_ob, b_ob);
+ BL::ID b_ob_data = b_ob.data();
+
+ 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();
+
+ switch (b_camera.type()) {
+ case BL::Camera::type_ORTHO:
+ bcam->type = CAMERA_ORTHOGRAPHIC;
+ break;
+ case BL::Camera::type_PANO:
+ if (!skip_panorama)
+ bcam->type = CAMERA_PANORAMA;
+ else
+ bcam->type = CAMERA_PERSPECTIVE;
+ break;
+ case BL::Camera::type_PERSP:
+ default:
+ bcam->type = CAMERA_PERSPECTIVE;
+ break;
+ }
+
+ bcam->panorama_type = (PanoramaType)get_enum(
+ ccamera, "panorama_type", PANORAMA_NUM_TYPES, PANORAMA_EQUIRECTANGULAR);
+
+ 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->interocular_distance = b_camera.stereo().interocular_distance();
+ if (b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) {
+ bcam->convergence_distance = FLT_MAX;
+ }
+ else {
+ bcam->convergence_distance = b_camera.stereo().convergence_distance();
+ }
+ bcam->use_spherical_stereo = b_engine.use_spherical_stereo(b_ob);
+
+ bcam->use_pole_merge = b_camera.stereo().use_pole_merge();
+ bcam->pole_merge_angle_from = b_camera.stereo().pole_merge_angle_from();
+ bcam->pole_merge_angle_to = b_camera.stereo().pole_merge_angle_to();
+
+ bcam->ortho_scale = b_camera.ortho_scale();
+
+ bcam->lens = b_camera.lens();
+
+ /* allow f/stop number to change aperture_size but still
+ * give manual control over aperture radius */
+ int aperture_type = get_enum(ccamera, "aperture_type");
+
+ if (aperture_type == 1) {
+ float fstop = RNA_float_get(&ccamera, "aperture_fstop");
+ fstop = max(fstop, 1e-5f);
+
+ if (bcam->type == CAMERA_ORTHOGRAPHIC)
+ bcam->aperturesize = 1.0f / (2.0f * fstop);
+ else
+ bcam->aperturesize = (bcam->lens * 1e-3f) / (2.0f * fstop);
+ }
+ else
+ bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size");
+
+ bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
+ bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
+ bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera, bcam);
+ bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
+
+ bcam->shift.x = b_engine.camera_shift_x(b_ob, bcam->use_spherical_stereo);
+ bcam->shift.y = b_camera.shift_y();
+
+ bcam->sensor_width = b_camera.sensor_width();
+ bcam->sensor_height = b_camera.sensor_height();
+
+ if (b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO)
+ bcam->sensor_fit = BlenderCamera::AUTO;
+ else if (b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL)
+ bcam->sensor_fit = BlenderCamera::HORIZONTAL;
+ else
+ bcam->sensor_fit = BlenderCamera::VERTICAL;
+ }
+ else if (b_ob_data.is_a(&RNA_Light)) {
+ /* Can also look through spot light. */
+ BL::SpotLight b_light(b_ob_data);
+ float lens = 16.0f / tanf(b_light.spot_size() * 0.5f);
+ if (lens > 0.0f) {
+ bcam->lens = lens;
+ }
+ }
+
+ bcam->motion_steps = object_motion_steps(b_ob, b_ob);
}
-static Transform blender_camera_matrix(const Transform& tfm,
+static Transform blender_camera_matrix(const Transform &tfm,
const CameraType type,
const PanoramaType panorama_type)
{
- Transform result;
-
- if(type == CAMERA_PANORAMA) {
- if(panorama_type == PANORAMA_MIRRORBALL) {
- /* Mirror ball camera is looking into the negative Y direction
- * which matches texture mirror ball mapping.
- */
- result = tfm *
- make_transform(1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f);
- }
- else {
- /* Make it so environment camera needs to be pointed in the direction
- * of the positive x-axis to match an environment texture, this way
- * it is looking at the center of the texture
- */
- result = tfm *
- make_transform( 0.0f, -1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- -1.0f, 0.0f, 0.0f, 0.0f);
- }
- }
- else {
- /* note the blender camera points along the negative z-axis */
- result = tfm * transform_scale(1.0f, 1.0f, -1.0f);
- }
-
- return transform_clear_scale(result);
+ Transform result;
+
+ if (type == CAMERA_PANORAMA) {
+ if (panorama_type == PANORAMA_MIRRORBALL) {
+ /* Mirror ball camera is looking into the negative Y direction
+ * which matches texture mirror ball mapping.
+ */
+ result = tfm * make_transform(
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
+ }
+ else {
+ /* Make it so environment camera needs to be pointed in the direction
+ * of the positive x-axis to match an environment texture, this way
+ * it is looking at the center of the texture
+ */
+ result = tfm * make_transform(
+ 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
+ }
+ }
+ else {
+ /* note the blender camera points along the negative z-axis */
+ result = tfm * transform_scale(1.0f, 1.0f, -1.0f);
+ }
+
+ return transform_clear_scale(result);
}
static void blender_camera_viewplane(BlenderCamera *bcam,
- int width, int height,
+ int width,
+ int height,
BoundBox2D *viewplane,
float *aspectratio,
float *sensor_size)
{
- /* dimensions */
- float xratio = (float)width*bcam->pixelaspect.x;
- float yratio = (float)height*bcam->pixelaspect.y;
-
- /* compute x/y aspect and ratio */
- float xaspect, yaspect;
- bool horizontal_fit;
-
- /* sensor fitting */
- if(bcam->sensor_fit == BlenderCamera::AUTO) {
- horizontal_fit = (xratio > yratio);
- if(sensor_size != NULL) {
- *sensor_size = bcam->sensor_width;
- }
- }
- else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
- horizontal_fit = true;
- if(sensor_size != NULL) {
- *sensor_size = bcam->sensor_width;
- }
- }
- else {
- horizontal_fit = false;
- if(sensor_size != NULL) {
- *sensor_size = bcam->sensor_height;
- }
- }
-
- if(horizontal_fit) {
- if(aspectratio != NULL) {
- *aspectratio = xratio/yratio;
- }
- xaspect = *aspectratio;
- yaspect = 1.0f;
- }
- else {
- if(aspectratio != NULL) {
- *aspectratio = yratio/xratio;
- }
- xaspect = 1.0f;
- yaspect = *aspectratio;
- }
-
- /* modify aspect for orthographic scale */
- if(bcam->type == CAMERA_ORTHOGRAPHIC) {
- xaspect = xaspect*bcam->ortho_scale/(*aspectratio*2.0f);
- yaspect = yaspect*bcam->ortho_scale/(*aspectratio*2.0f);
- if(aspectratio != NULL) {
- *aspectratio = bcam->ortho_scale/2.0f;
- }
- }
-
- if(bcam->type == CAMERA_PANORAMA) {
- /* set viewplane */
- if(viewplane != NULL) {
- *viewplane = bcam->pano_viewplane;
- }
- }
- else {
- /* set viewplane */
- if(viewplane != NULL) {
- viewplane->left = -xaspect;
- viewplane->right = xaspect;
- viewplane->bottom = -yaspect;
- viewplane->top = yaspect;
-
- /* zoom for 3d camera view */
- *viewplane = (*viewplane) * bcam->zoom;
-
- /* modify viewplane with camera shift and 3d camera view offset */
- float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f);
- float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f);
-
- viewplane->left += dx;
- viewplane->right += dx;
- viewplane->bottom += dy;
- viewplane->top += dy;
- }
- }
+ /* dimensions */
+ float xratio = (float)width * bcam->pixelaspect.x;
+ float yratio = (float)height * bcam->pixelaspect.y;
+
+ /* compute x/y aspect and ratio */
+ float xaspect, yaspect;
+ bool horizontal_fit;
+
+ /* sensor fitting */
+ if (bcam->sensor_fit == BlenderCamera::AUTO) {
+ horizontal_fit = (xratio > yratio);
+ if (sensor_size != NULL) {
+ *sensor_size = bcam->sensor_width;
+ }
+ }
+ else if (bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
+ horizontal_fit = true;
+ if (sensor_size != NULL) {
+ *sensor_size = bcam->sensor_width;
+ }
+ }
+ else {
+ horizontal_fit = false;
+ if (sensor_size != NULL) {
+ *sensor_size = bcam->sensor_height;
+ }
+ }
+
+ if (horizontal_fit) {
+ if (aspectratio != NULL) {
+ *aspectratio = xratio / yratio;
+ }
+ xaspect = *aspectratio;
+ yaspect = 1.0f;
+ }
+ else {
+ if (aspectratio != NULL) {
+ *aspectratio = yratio / xratio;
+ }
+ xaspect = 1.0f;
+ yaspect = *aspectratio;
+ }
+
+ /* modify aspect for orthographic scale */
+ if (bcam->type == CAMERA_ORTHOGRAPHIC) {
+ xaspect = xaspect * bcam->ortho_scale / (*aspectratio * 2.0f);
+ yaspect = yaspect * bcam->ortho_scale / (*aspectratio * 2.0f);
+ if (aspectratio != NULL) {
+ *aspectratio = bcam->ortho_scale / 2.0f;
+ }
+ }
+
+ if (bcam->type == CAMERA_PANORAMA) {
+ /* set viewplane */
+ if (viewplane != NULL) {
+ *viewplane = bcam->pano_viewplane;
+ }
+ }
+ else {
+ /* set viewplane */
+ if (viewplane != NULL) {
+ viewplane->left = -xaspect;
+ viewplane->right = xaspect;
+ viewplane->bottom = -yaspect;
+ viewplane->top = yaspect;
+
+ /* zoom for 3d camera view */
+ *viewplane = (*viewplane) * bcam->zoom;
+
+ /* modify viewplane with camera shift and 3d camera view offset */
+ float dx = 2.0f * (*aspectratio * bcam->shift.x + bcam->offset.x * xaspect * 2.0f);
+ float dy = 2.0f * (*aspectratio * bcam->shift.y + bcam->offset.y * yaspect * 2.0f);
+
+ viewplane->left += dx;
+ viewplane->right += dx;
+ viewplane->bottom += dy;
+ viewplane->top += dy;
+ }
+ }
}
static void blender_camera_sync(Camera *cam,
BlenderCamera *bcam,
- int width, int height,
+ int width,
+ int height,
const char *viewname,
PointerRNA *cscene)
{
- /* copy camera to compare later */
- Camera prevcam = *cam;
- float aspectratio, sensor_size;
-
- /* viewplane */
- blender_camera_viewplane(bcam, width, height,
- &cam->viewplane, &aspectratio, &sensor_size);
-
- cam->width = bcam->full_width;
- cam->height = bcam->full_height;
-
- cam->full_width = width;
- cam->full_height = height;
-
- /* panorama sensor */
- if(bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
- float fit_xratio = (float)bcam->full_width*bcam->pixelaspect.x;
- float fit_yratio = (float)bcam->full_height*bcam->pixelaspect.y;
- bool horizontal_fit;
- float sensor_size;
-
- if(bcam->sensor_fit == BlenderCamera::AUTO) {
- horizontal_fit = (fit_xratio > fit_yratio);
- sensor_size = bcam->sensor_width;
- }
- else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
- horizontal_fit = true;
- sensor_size = bcam->sensor_width;
- }
- else { /* vertical */
- horizontal_fit = false;
- sensor_size = bcam->sensor_height;
- }
-
- if(horizontal_fit) {
- cam->sensorwidth = sensor_size;
- cam->sensorheight = sensor_size * fit_yratio / fit_xratio;
- }
- else {
- cam->sensorwidth = sensor_size * fit_xratio / fit_yratio;
- cam->sensorheight = sensor_size;
- }
- }
-
- /* clipping distances */
- cam->nearclip = bcam->nearclip;
- cam->farclip = bcam->farclip;
-
- /* type */
- cam->type = bcam->type;
-
- /* panorama */
- cam->panorama_type = bcam->panorama_type;
- cam->fisheye_fov = bcam->fisheye_fov;
- cam->fisheye_lens = bcam->fisheye_lens;
- cam->latitude_min = bcam->latitude_min;
- cam->latitude_max = bcam->latitude_max;
-
- cam->longitude_min = bcam->longitude_min;
- cam->longitude_max = bcam->longitude_max;
-
- /* panorama stereo */
- cam->interocular_distance = bcam->interocular_distance;
- cam->convergence_distance = bcam->convergence_distance;
- cam->use_spherical_stereo = bcam->use_spherical_stereo;
-
- if(cam->use_spherical_stereo) {
- if(strcmp(viewname, "left") == 0)
- cam->stereo_eye = Camera::STEREO_LEFT;
- else if(strcmp(viewname, "right") == 0)
- cam->stereo_eye = Camera::STEREO_RIGHT;
- else
- cam->stereo_eye = Camera::STEREO_NONE;
- }
-
- cam->use_pole_merge = bcam->use_pole_merge;
- cam->pole_merge_angle_from = bcam->pole_merge_angle_from;
- cam->pole_merge_angle_to = bcam->pole_merge_angle_to;
-
- /* anamorphic lens bokeh */
- cam->aperture_ratio = bcam->aperture_ratio;
-
- /* perspective */
- cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio);
- cam->focaldistance = bcam->focaldistance;
- cam->aperturesize = bcam->aperturesize;
- cam->blades = bcam->apertureblades;
- cam->bladesrotation = bcam->aperturerotation;
-
- /* transform */
- cam->matrix = blender_camera_matrix(bcam->matrix,
- bcam->type,
- bcam->panorama_type);
- cam->motion.clear();
- cam->motion.resize(bcam->motion_steps, cam->matrix);
- cam->use_perspective_motion = false;
- cam->shuttertime = bcam->shuttertime;
- cam->fov_pre = cam->fov;
- cam->fov_post = cam->fov;
- cam->motion_position = bcam->motion_position;
-
- cam->rolling_shutter_type = bcam->rolling_shutter_type;
- cam->rolling_shutter_duration = bcam->rolling_shutter_duration;
-
- cam->shutter_curve = bcam->shutter_curve;
-
- /* border */
- cam->border = bcam->border;
- cam->viewport_camera_border = bcam->viewport_camera_border;
-
- bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale");
- cam->offscreen_dicing_scale = bcam->offscreen_dicing_scale;
-
- /* set update flag */
- if(cam->modified(prevcam))
- cam->tag_update();
+ /* copy camera to compare later */
+ Camera prevcam = *cam;
+ float aspectratio, sensor_size;
+
+ /* viewplane */
+ blender_camera_viewplane(bcam, width, height, &cam->viewplane, &aspectratio, &sensor_size);
+
+ cam->width = bcam->full_width;
+ cam->height = bcam->full_height;
+
+ cam->full_width = width;
+ cam->full_height = height;
+
+ /* panorama sensor */
+ if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
+ float fit_xratio = (float)bcam->full_width * bcam->pixelaspect.x;
+ float fit_yratio = (float)bcam->full_height * bcam->pixelaspect.y;
+ bool horizontal_fit;
+ float sensor_size;
+
+ if (bcam->sensor_fit == BlenderCamera::AUTO) {
+ horizontal_fit = (fit_xratio > fit_yratio);
+ sensor_size = bcam->sensor_width;
+ }
+ else if (bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
+ horizontal_fit = true;
+ sensor_size = bcam->sensor_width;
+ }
+ else { /* vertical */
+ horizontal_fit = false;
+ sensor_size = bcam->sensor_height;
+ }
+
+ if (horizontal_fit) {
+ cam->sensorwidth = sensor_size;
+ cam->sensorheight = sensor_size * fit_yratio / fit_xratio;
+ }
+ else {
+ cam->sensorwidth = sensor_size * fit_xratio / fit_yratio;
+ cam->sensorheight = sensor_size;
+ }
+ }
+
+ /* clipping distances */
+ cam->nearclip = bcam->nearclip;
+ cam->farclip = bcam->farclip;
+
+ /* type */
+ cam->type = bcam->type;
+
+ /* panorama */
+ cam->panorama_type = bcam->panorama_type;
+ cam->fisheye_fov = bcam->fisheye_fov;
+ cam->fisheye_lens = bcam->fisheye_lens;
+ cam->latitude_min = bcam->latitude_min;
+ cam->latitude_max = bcam->latitude_max;
+
+ cam->longitude_min = bcam->longitude_min;
+ cam->longitude_max = bcam->longitude_max;
+
+ /* panorama stereo */
+ cam->interocular_distance = bcam->interocular_distance;
+ cam->convergence_distance = bcam->convergence_distance;
+ cam->use_spherical_stereo = bcam->use_spherical_stereo;
+
+ if (cam->use_spherical_stereo) {
+ if (strcmp(viewname, "left") == 0)
+ cam->stereo_eye = Camera::STEREO_LEFT;
+ else if (strcmp(viewname, "right") == 0)
+ cam->stereo_eye = Camera::STEREO_RIGHT;
+ else
+ cam->stereo_eye = Camera::STEREO_NONE;
+ }
+
+ cam->use_pole_merge = bcam->use_pole_merge;
+ cam->pole_merge_angle_from = bcam->pole_merge_angle_from;
+ cam->pole_merge_angle_to = bcam->pole_merge_angle_to;
+
+ /* anamorphic lens bokeh */
+ cam->aperture_ratio = bcam->aperture_ratio;
+
+ /* perspective */
+ cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio);
+ cam->focaldistance = bcam->focaldistance;
+ cam->aperturesize = bcam->aperturesize;
+ cam->blades = bcam->apertureblades;
+ cam->bladesrotation = bcam->aperturerotation;
+
+ /* transform */
+ cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type, bcam->panorama_type);
+ cam->motion.clear();
+ cam->motion.resize(bcam->motion_steps, cam->matrix);
+ cam->use_perspective_motion = false;
+ cam->shuttertime = bcam->shuttertime;
+ cam->fov_pre = cam->fov;
+ cam->fov_post = cam->fov;
+ cam->motion_position = bcam->motion_position;
+
+ cam->rolling_shutter_type = bcam->rolling_shutter_type;
+ cam->rolling_shutter_duration = bcam->rolling_shutter_duration;
+
+ cam->shutter_curve = bcam->shutter_curve;
+
+ /* border */
+ cam->border = bcam->border;
+ cam->viewport_camera_border = bcam->viewport_camera_border;
+
+ bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale");
+ cam->offscreen_dicing_scale = bcam->offscreen_dicing_scale;
+
+ /* set update flag */
+ if (cam->modified(prevcam))
+ cam->tag_update();
}
/* Sync Render Camera */
-void BlenderSync::sync_camera(BL::RenderSettings& b_render,
- BL::Object& b_override,
- int width, int height,
+void BlenderSync::sync_camera(BL::RenderSettings &b_render,
+ BL::Object &b_override,
+ int width,
+ int height,
const char *viewname)
{
- BlenderCamera bcam;
- blender_camera_init(&bcam, b_render);
-
- /* pixel aspect */
- bcam.pixelaspect.x = b_render.pixel_aspect_x();
- bcam.pixelaspect.y = b_render.pixel_aspect_y();
- bcam.shuttertime = b_render.motion_blur_shutter();
-
- BL::CurveMapping b_shutter_curve(b_render.motion_blur_shutter_curve());
- curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE);
-
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- bcam.motion_position =
- (Camera::MotionPosition)get_enum(cscene,
- "motion_blur_position",
- Camera::MOTION_NUM_POSITIONS,
- Camera::MOTION_POSITION_CENTER);
- bcam.rolling_shutter_type =
- (Camera::RollingShutterType)get_enum(cscene,
- "rolling_shutter_type",
- Camera::ROLLING_SHUTTER_NUM_TYPES,
- Camera::ROLLING_SHUTTER_NONE);
- bcam.rolling_shutter_duration = RNA_float_get(&cscene, "rolling_shutter_duration");
-
- /* border */
- if(b_render.use_border()) {
- bcam.border.left = b_render.border_min_x();
- bcam.border.right = b_render.border_max_x();
- bcam.border.bottom = b_render.border_min_y();
- bcam.border.top = b_render.border_max_y();
- }
-
- /* camera object */
- BL::Object b_ob = b_scene.camera();
-
- if(b_override)
- b_ob = b_override;
-
- if(b_ob) {
- BL::Array<float, 16> b_ob_matrix;
- blender_camera_from_object(&bcam, b_engine, b_ob);
- b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
- bcam.matrix = get_transform(b_ob_matrix);
- }
-
- /* sync */
- Camera *cam = scene->camera;
- blender_camera_sync(cam, &bcam, width, height, viewname, &cscene);
-
- /* dicing camera */
- b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
- if(b_ob) {
- BL::Array<float, 16> b_ob_matrix;
- blender_camera_from_object(&bcam, b_engine, b_ob);
- b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
- bcam.matrix = get_transform(b_ob_matrix);
-
- blender_camera_sync(scene->dicing_camera, &bcam, width, height, viewname, &cscene);
- }
- else {
- *scene->dicing_camera = *cam;
- }
+ BlenderCamera bcam;
+ blender_camera_init(&bcam, b_render);
+
+ /* pixel aspect */
+ bcam.pixelaspect.x = b_render.pixel_aspect_x();
+ bcam.pixelaspect.y = b_render.pixel_aspect_y();
+ bcam.shuttertime = b_render.motion_blur_shutter();
+
+ BL::CurveMapping b_shutter_curve(b_render.motion_blur_shutter_curve());
+ curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE);
+
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ bcam.motion_position = (Camera::MotionPosition)get_enum(cscene,
+ "motion_blur_position",
+ Camera::MOTION_NUM_POSITIONS,
+ Camera::MOTION_POSITION_CENTER);
+ bcam.rolling_shutter_type = (Camera::RollingShutterType)get_enum(
+ cscene,
+ "rolling_shutter_type",
+ Camera::ROLLING_SHUTTER_NUM_TYPES,
+ Camera::ROLLING_SHUTTER_NONE);
+ bcam.rolling_shutter_duration = RNA_float_get(&cscene, "rolling_shutter_duration");
+
+ /* border */
+ if (b_render.use_border()) {
+ bcam.border.left = b_render.border_min_x();
+ bcam.border.right = b_render.border_max_x();
+ bcam.border.bottom = b_render.border_min_y();
+ bcam.border.top = b_render.border_max_y();
+ }
+
+ /* camera object */
+ BL::Object b_ob = b_scene.camera();
+
+ if (b_override)
+ b_ob = b_override;
+
+ if (b_ob) {
+ BL::Array<float, 16> b_ob_matrix;
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
+ bcam.matrix = get_transform(b_ob_matrix);
+ }
+
+ /* sync */
+ Camera *cam = scene->camera;
+ blender_camera_sync(cam, &bcam, width, height, viewname, &cscene);
+
+ /* dicing camera */
+ b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
+ if (b_ob) {
+ BL::Array<float, 16> b_ob_matrix;
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
+ bcam.matrix = get_transform(b_ob_matrix);
+
+ blender_camera_sync(scene->dicing_camera, &bcam, width, height, viewname, &cscene);
+ }
+ else {
+ *scene->dicing_camera = *cam;
+ }
}
-void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
- BL::Object& b_ob,
- int width, int height,
- float motion_time)
+void BlenderSync::sync_camera_motion(
+ BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time)
{
- if(!b_ob)
- return;
-
- Camera *cam = scene->camera;
- BL::Array<float, 16> b_ob_matrix;
- b_engine.camera_model_matrix(b_ob, cam->use_spherical_stereo, b_ob_matrix);
- Transform tfm = get_transform(b_ob_matrix);
- tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type);
-
- if(motion_time == 0.0f) {
- /* When motion blur is not centered in frame, cam->matrix gets reset. */
- cam->matrix = tfm;
- }
-
- /* Set transform in motion array. */
- int motion_step = cam->motion_step(motion_time);
- if(motion_step >= 0) {
- cam->motion[motion_step] = tfm;
- }
-
- if(cam->type == CAMERA_PERSPECTIVE) {
- BlenderCamera bcam;
- float aspectratio, sensor_size;
- blender_camera_init(&bcam, b_render);
-
- /* TODO(sergey): Consider making it a part of blender_camera_init(). */
- bcam.pixelaspect.x = b_render.pixel_aspect_x();
- bcam.pixelaspect.y = b_render.pixel_aspect_y();
-
- blender_camera_from_object(&bcam, b_engine, b_ob);
- blender_camera_viewplane(&bcam,
- width, height,
- NULL,
- &aspectratio,
- &sensor_size);
- /* TODO(sergey): De-duplicate calculation with camera sync. */
- float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
- if(fov != cam->fov) {
- VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
- if(motion_time == 0.0f) {
- cam->fov = fov;
- }
- else if(motion_time == -1.0f) {
- cam->fov_pre = fov;
- cam->use_perspective_motion = true;
- }
- else if(motion_time == 1.0f) {
- cam->fov_post = fov;
- cam->use_perspective_motion = true;
- }
- }
- }
+ if (!b_ob)
+ return;
+
+ Camera *cam = scene->camera;
+ BL::Array<float, 16> b_ob_matrix;
+ b_engine.camera_model_matrix(b_ob, cam->use_spherical_stereo, b_ob_matrix);
+ Transform tfm = get_transform(b_ob_matrix);
+ tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type);
+
+ if (motion_time == 0.0f) {
+ /* When motion blur is not centered in frame, cam->matrix gets reset. */
+ cam->matrix = tfm;
+ }
+
+ /* Set transform in motion array. */
+ int motion_step = cam->motion_step(motion_time);
+ if (motion_step >= 0) {
+ cam->motion[motion_step] = tfm;
+ }
+
+ if (cam->type == CAMERA_PERSPECTIVE) {
+ BlenderCamera bcam;
+ float aspectratio, sensor_size;
+ blender_camera_init(&bcam, b_render);
+
+ /* TODO(sergey): Consider making it a part of blender_camera_init(). */
+ bcam.pixelaspect.x = b_render.pixel_aspect_x();
+ bcam.pixelaspect.y = b_render.pixel_aspect_y();
+
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ blender_camera_viewplane(&bcam, width, height, NULL, &aspectratio, &sensor_size);
+ /* TODO(sergey): De-duplicate calculation with camera sync. */
+ float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
+ if (fov != cam->fov) {
+ VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
+ if (motion_time == 0.0f) {
+ cam->fov = fov;
+ }
+ else if (motion_time == -1.0f) {
+ cam->fov_pre = fov;
+ cam->use_perspective_motion = true;
+ }
+ else if (motion_time == 1.0f) {
+ cam->fov_post = fov;
+ cam->use_perspective_motion = true;
+ }
+ }
+ }
}
/* Sync 3D View Camera */
-static void blender_camera_view_subset(BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::Object& b_ob,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height,
+static void blender_camera_view_subset(BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::Object &b_ob,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height,
BoundBox2D *view_box,
BoundBox2D *cam_box);
static void blender_camera_from_view(BlenderCamera *bcam,
- BL::RenderEngine& b_engine,
- BL::Scene& b_scene,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height,
+ BL::RenderEngine &b_engine,
+ BL::Scene &b_scene,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height,
bool skip_panorama = false)
{
- /* 3d view parameters */
- bcam->nearclip = b_v3d.clip_start();
- bcam->farclip = b_v3d.clip_end();
- bcam->lens = b_v3d.lens();
- bcam->shuttertime = b_scene.render().motion_blur_shutter();
-
- BL::CurveMapping b_shutter_curve(b_scene.render().motion_blur_shutter_curve());
- curvemapping_to_array(b_shutter_curve, bcam->shutter_curve, RAMP_TABLE_SIZE);
-
- if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) {
- /* camera view */
- BL::Object b_ob = (b_v3d.use_local_camera())? b_v3d.camera(): b_scene.camera();
-
- if(b_ob) {
- blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama);
-
- if(!skip_panorama && bcam->type == CAMERA_PANORAMA) {
- /* in panorama camera view, we map viewplane to camera border */
- BoundBox2D view_box, cam_box;
-
- BL::RenderSettings b_render_settings(b_scene.render());
- blender_camera_view_subset(b_engine,
- b_render_settings,
- b_scene,
- b_ob,
- b_v3d,
- b_rv3d,
- width, height,
- &view_box,
- &cam_box);
-
- bcam->pano_viewplane = view_box.make_relative_to(cam_box);
- }
- else {
- /* magic zoom formula */
- bcam->zoom = (float)b_rv3d.view_camera_zoom();
- bcam->zoom = (1.41421f + bcam->zoom/50.0f);
- bcam->zoom *= bcam->zoom;
- bcam->zoom = 2.0f/bcam->zoom;
-
- /* offset */
- bcam->offset = get_float2(b_rv3d.view_camera_offset());
- }
- }
- }
- else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) {
- /* orthographic view */
- bcam->farclip *= 0.5f;
- bcam->nearclip = -bcam->farclip;
-
- float sensor_size;
- if(bcam->sensor_fit == BlenderCamera::VERTICAL)
- sensor_size = bcam->sensor_height;
- else
- sensor_size = bcam->sensor_width;
-
- bcam->type = CAMERA_ORTHOGRAPHIC;
- bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
- }
-
- bcam->zoom *= 2.0f;
-
- /* 3d view transform */
- bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
+ /* 3d view parameters */
+ bcam->nearclip = b_v3d.clip_start();
+ bcam->farclip = b_v3d.clip_end();
+ bcam->lens = b_v3d.lens();
+ bcam->shuttertime = b_scene.render().motion_blur_shutter();
+
+ BL::CurveMapping b_shutter_curve(b_scene.render().motion_blur_shutter_curve());
+ curvemapping_to_array(b_shutter_curve, bcam->shutter_curve, RAMP_TABLE_SIZE);
+
+ if (b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) {
+ /* camera view */
+ BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
+
+ if (b_ob) {
+ blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama);
+
+ if (!skip_panorama && bcam->type == CAMERA_PANORAMA) {
+ /* in panorama camera view, we map viewplane to camera border */
+ BoundBox2D view_box, cam_box;
+
+ BL::RenderSettings b_render_settings(b_scene.render());
+ blender_camera_view_subset(b_engine,
+ b_render_settings,
+ b_scene,
+ b_ob,
+ b_v3d,
+ b_rv3d,
+ width,
+ height,
+ &view_box,
+ &cam_box);
+
+ bcam->pano_viewplane = view_box.make_relative_to(cam_box);
+ }
+ else {
+ /* magic zoom formula */
+ bcam->zoom = (float)b_rv3d.view_camera_zoom();
+ bcam->zoom = (1.41421f + bcam->zoom / 50.0f);
+ bcam->zoom *= bcam->zoom;
+ bcam->zoom = 2.0f / bcam->zoom;
+
+ /* offset */
+ bcam->offset = get_float2(b_rv3d.view_camera_offset());
+ }
+ }
+ }
+ else if (b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) {
+ /* orthographic view */
+ bcam->farclip *= 0.5f;
+ bcam->nearclip = -bcam->farclip;
+
+ float sensor_size;
+ if (bcam->sensor_fit == BlenderCamera::VERTICAL)
+ sensor_size = bcam->sensor_height;
+ else
+ sensor_size = bcam->sensor_width;
+
+ bcam->type = CAMERA_ORTHOGRAPHIC;
+ bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
+ }
+
+ bcam->zoom *= 2.0f;
+
+ /* 3d view transform */
+ bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
}
-static void blender_camera_view_subset(BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::Object& b_ob,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height,
+static void blender_camera_view_subset(BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::Object &b_ob,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height,
BoundBox2D *view_box,
BoundBox2D *cam_box)
{
- BoundBox2D cam, view;
- float view_aspect, cam_aspect, sensor_size;
+ BoundBox2D cam, view;
+ float view_aspect, cam_aspect, sensor_size;
- /* get viewport viewplane */
- BlenderCamera view_bcam;
- blender_camera_init(&view_bcam, b_render);
- blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true);
+ /* get viewport viewplane */
+ BlenderCamera view_bcam;
+ blender_camera_init(&view_bcam, b_render);
+ blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true);
- blender_camera_viewplane(&view_bcam, width, height,
- &view, &view_aspect, &sensor_size);
+ blender_camera_viewplane(&view_bcam, width, height, &view, &view_aspect, &sensor_size);
- /* get camera viewplane */
- BlenderCamera cam_bcam;
- blender_camera_init(&cam_bcam, b_render);
- blender_camera_from_object(&cam_bcam, b_engine, b_ob, true);
+ /* get camera viewplane */
+ BlenderCamera cam_bcam;
+ blender_camera_init(&cam_bcam, b_render);
+ blender_camera_from_object(&cam_bcam, b_engine, b_ob, true);
- blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height,
- &cam, &cam_aspect, &sensor_size);
+ blender_camera_viewplane(
+ &cam_bcam, cam_bcam.full_width, cam_bcam.full_height, &cam, &cam_aspect, &sensor_size);
- /* return */
- *view_box = view * (1.0f/view_aspect);
- *cam_box = cam * (1.0f/cam_aspect);
+ /* return */
+ *view_box = view * (1.0f / view_aspect);
+ *cam_box = cam * (1.0f / cam_aspect);
}
-static void blender_camera_border_subset(BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- BL::Object& b_ob,
- int width, int height,
+static void blender_camera_border_subset(BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ BL::Object &b_ob,
+ int width,
+ int height,
const BoundBox2D &border,
BoundBox2D *result)
{
- /* Determine camera viewport subset. */
- BoundBox2D view_box, cam_box;
- blender_camera_view_subset(b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
- &view_box, &cam_box);
-
- /* Determine viewport subset matching given border. */
- cam_box = cam_box.make_relative_to(view_box);
- *result = cam_box.subset(border);
+ /* Determine camera viewport subset. */
+ BoundBox2D view_box, cam_box;
+ blender_camera_view_subset(
+ b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height, &view_box, &cam_box);
+
+ /* Determine viewport subset matching given border. */
+ cam_box = cam_box.make_relative_to(view_box);
+ *result = cam_box.subset(border);
}
static void blender_camera_border(BlenderCamera *bcam,
- BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height)
+ BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height)
{
- bool is_camera_view;
-
- /* camera view? */
- is_camera_view = b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA;
-
- if(!is_camera_view) {
- /* for non-camera view check whether render border is enabled for viewport
- * and if so use border from 3d viewport
- * assume viewport has got correctly clamped border already
- */
- if(b_v3d.use_render_border()) {
- bcam->border.left = b_v3d.render_border_min_x();
- bcam->border.right = b_v3d.render_border_max_x();
- bcam->border.bottom = b_v3d.render_border_min_y();
- bcam->border.top = b_v3d.render_border_max_y();
- }
- return;
- }
-
- BL::Object b_ob = (b_v3d.use_local_camera())? b_v3d.camera(): b_scene.camera();
-
- if(!b_ob)
- return;
-
- /* Determine camera border inside the viewport. */
- BoundBox2D full_border;
- blender_camera_border_subset(b_engine,
- b_render,
- b_scene,
- b_v3d,
- b_rv3d,
- b_ob,
- width, height,
- full_border,
- &bcam->viewport_camera_border);
-
- if(!b_render.use_border()) {
- return;
- }
-
- bcam->border.left = b_render.border_min_x();
- bcam->border.right = b_render.border_max_x();
- bcam->border.bottom = b_render.border_min_y();
- bcam->border.top = b_render.border_max_y();
-
- /* Determine viewport subset matching camera border. */
- blender_camera_border_subset(b_engine,
- b_render,
- b_scene,
- b_v3d,
- b_rv3d,
- b_ob,
- width, height,
- bcam->border,
- &bcam->border);
- bcam->border = bcam->border.clamp();
+ bool is_camera_view;
+
+ /* camera view? */
+ is_camera_view = b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA;
+
+ if (!is_camera_view) {
+ /* for non-camera view check whether render border is enabled for viewport
+ * and if so use border from 3d viewport
+ * assume viewport has got correctly clamped border already
+ */
+ if (b_v3d.use_render_border()) {
+ bcam->border.left = b_v3d.render_border_min_x();
+ bcam->border.right = b_v3d.render_border_max_x();
+ bcam->border.bottom = b_v3d.render_border_min_y();
+ bcam->border.top = b_v3d.render_border_max_y();
+ }
+ return;
+ }
+
+ BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
+
+ if (!b_ob)
+ return;
+
+ /* Determine camera border inside the viewport. */
+ BoundBox2D full_border;
+ blender_camera_border_subset(b_engine,
+ b_render,
+ b_scene,
+ b_v3d,
+ b_rv3d,
+ b_ob,
+ width,
+ height,
+ full_border,
+ &bcam->viewport_camera_border);
+
+ if (!b_render.use_border()) {
+ return;
+ }
+
+ bcam->border.left = b_render.border_min_x();
+ bcam->border.right = b_render.border_max_x();
+ bcam->border.bottom = b_render.border_min_y();
+ bcam->border.top = b_render.border_max_y();
+
+ /* Determine viewport subset matching camera border. */
+ blender_camera_border_subset(b_engine,
+ b_render,
+ b_scene,
+ b_v3d,
+ b_rv3d,
+ b_ob,
+ width,
+ height,
+ bcam->border,
+ &bcam->border);
+ bcam->border = bcam->border.clamp();
}
-void BlenderSync::sync_view(BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height)
+void BlenderSync::sync_view(BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height)
{
- BlenderCamera bcam;
- BL::RenderSettings b_render_settings(b_scene.render());
- blender_camera_init(&bcam, b_render_settings);
- blender_camera_from_view(&bcam,
- b_engine,
- b_scene,
- b_v3d,
- b_rv3d,
- width, height);
- blender_camera_border(&bcam,
- b_engine,
- b_render_settings,
- b_scene,
- b_v3d,
- b_rv3d,
- width, height);
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- blender_camera_sync(scene->camera, &bcam, width, height, "", &cscene);
-
- /* dicing camera */
- BL::Object b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
- if(b_ob) {
- BL::Array<float, 16> b_ob_matrix;
- blender_camera_from_object(&bcam, b_engine, b_ob);
- b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
- bcam.matrix = get_transform(b_ob_matrix);
-
- blender_camera_sync(scene->dicing_camera, &bcam, width, height, "", &cscene);
- }
- else {
- *scene->dicing_camera = *scene->camera;
- }
+ BlenderCamera bcam;
+ BL::RenderSettings b_render_settings(b_scene.render());
+ blender_camera_init(&bcam, b_render_settings);
+ blender_camera_from_view(&bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height);
+ blender_camera_border(&bcam, b_engine, b_render_settings, b_scene, b_v3d, b_rv3d, width, height);
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ blender_camera_sync(scene->camera, &bcam, width, height, "", &cscene);
+
+ /* dicing camera */
+ BL::Object b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
+ if (b_ob) {
+ BL::Array<float, 16> b_ob_matrix;
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
+ bcam.matrix = get_transform(b_ob_matrix);
+
+ blender_camera_sync(scene->dicing_camera, &bcam, width, height, "", &cscene);
+ }
+ else {
+ *scene->dicing_camera = *scene->camera;
+ }
}
-BufferParams BlenderSync::get_buffer_params(BL::RenderSettings& b_render,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
+BufferParams BlenderSync::get_buffer_params(BL::RenderSettings &b_render,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
Camera *cam,
- int width, int height)
+ int width,
+ int height)
{
- BufferParams params;
- bool use_border = false;
-
- params.full_width = width;
- params.full_height = height;
-
- if(b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
- use_border = b_v3d.use_render_border();
- else
- use_border = b_render.use_border();
-
- if(use_border) {
- /* border render */
- /* the viewport may offset the border outside the view */
- BoundBox2D border = cam->border.clamp();
- params.full_x = (int)(border.left * (float)width);
- params.full_y = (int)(border.bottom * (float)height);
- params.width = (int)(border.right * (float)width) - params.full_x;
- params.height = (int)(border.top * (float)height) - params.full_y;
-
- /* survive in case border goes out of view or becomes too small */
- params.width = max(params.width, 1);
- params.height = max(params.height, 1);
- }
- else {
- params.width = width;
- params.height = height;
- }
-
- return params;
+ BufferParams params;
+ bool use_border = false;
+
+ params.full_width = width;
+ params.full_height = height;
+
+ if (b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
+ use_border = b_v3d.use_render_border();
+ else
+ use_border = b_render.use_border();
+
+ if (use_border) {
+ /* border render */
+ /* the viewport may offset the border outside the view */
+ BoundBox2D border = cam->border.clamp();
+ params.full_x = (int)(border.left * (float)width);
+ params.full_y = (int)(border.bottom * (float)height);
+ params.width = (int)(border.right * (float)width) - params.full_x;
+ params.height = (int)(border.top * (float)height) - params.full_y;
+
+ /* survive in case border goes out of view or becomes too small */
+ params.width = max(params.width, 1);
+ params.height = max(params.height, 1);
+ }
+ else {
+ params.width = width;
+ params.height = height;
+ }
+
+ return params;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 602e63a3e47..d0375ceb79c 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -40,170 +40,165 @@ ParticleCurveData::~ParticleCurveData()
static void interp_weights(float t, float data[4])
{
- /* Cardinal curve interpolation */
- float t2 = t * t;
- float t3 = t2 * t;
- float fc = 0.71f;
-
- data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
- data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
- data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
- data[3] = fc * t3 - fc * t2;
+ /* Cardinal curve interpolation */
+ float t2 = t * t;
+ float t3 = t2 * t;
+ float fc = 0.71f;
+
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
}
-static void curveinterp_v3_v3v3v3v3(float3 *p,
- float3 *v1, float3 *v2, float3 *v3, float3 *v4,
- const float w[4])
+static void curveinterp_v3_v3v3v3v3(
+ float3 *p, float3 *v1, float3 *v2, float3 *v3, float3 *v4, const float w[4])
{
- p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3];
- p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3];
- p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3];
+ p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3];
+ p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3];
+ p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3];
}
static float shaperadius(float shape, float root, float tip, float time)
{
- assert(time >= 0.0f);
- assert(time <= 1.0f);
- float radius = 1.0f - time;
-
- if(shape != 0.0f) {
- if(shape < 0.0f)
- radius = powf(radius, 1.0f + shape);
- else
- radius = powf(radius, 1.0f / (1.0f - shape));
- }
- return (radius * (root - tip)) + tip;
+ assert(time >= 0.0f);
+ assert(time <= 1.0f);
+ float radius = 1.0f - time;
+
+ if (shape != 0.0f) {
+ if (shape < 0.0f)
+ radius = powf(radius, 1.0f + shape);
+ else
+ radius = powf(radius, 1.0f / (1.0f - shape));
+ }
+ return (radius * (root - tip)) + tip;
}
/* curve functions */
-static void InterpolateKeySegments(int seg,
- int segno,
- int key,
- int curve,
- float3 *keyloc,
- float *time,
- ParticleCurveData *CData)
+static void InterpolateKeySegments(
+ int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData)
{
- float3 ckey_loc1 = CData->curvekey_co[key];
- float3 ckey_loc2 = ckey_loc1;
- float3 ckey_loc3 = CData->curvekey_co[key+1];
- float3 ckey_loc4 = ckey_loc3;
+ float3 ckey_loc1 = CData->curvekey_co[key];
+ float3 ckey_loc2 = ckey_loc1;
+ float3 ckey_loc3 = CData->curvekey_co[key + 1];
+ float3 ckey_loc4 = ckey_loc3;
- if(key > CData->curve_firstkey[curve])
- ckey_loc1 = CData->curvekey_co[key - 1];
+ if (key > CData->curve_firstkey[curve])
+ ckey_loc1 = CData->curvekey_co[key - 1];
- if(key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
- ckey_loc4 = CData->curvekey_co[key + 2];
+ if (key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
+ ckey_loc4 = CData->curvekey_co[key + 2];
- float time1 = CData->curvekey_time[key]/CData->curve_length[curve];
- float time2 = CData->curvekey_time[key + 1]/CData->curve_length[curve];
+ float time1 = CData->curvekey_time[key] / CData->curve_length[curve];
+ float time2 = CData->curvekey_time[key + 1] / CData->curve_length[curve];
- float dfra = (time2 - time1) / (float)segno;
+ float dfra = (time2 - time1) / (float)segno;
- if(time)
- *time = (dfra * seg) + time1;
+ if (time)
+ *time = (dfra * seg) + time1;
- float t[4];
+ float t[4];
- interp_weights((float)seg / (float)segno, t);
+ interp_weights((float)seg / (float)segno, t);
- if(keyloc)
- curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
+ if (keyloc)
+ curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
}
-static bool ObtainCacheParticleData(Mesh *mesh,
- BL::Mesh *b_mesh,
- BL::Object *b_ob,
- ParticleCurveData *CData,
- bool background)
+static bool ObtainCacheParticleData(
+ Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background)
{
- int curvenum = 0;
- int keyno = 0;
-
- if(!(mesh && b_mesh && b_ob && CData))
- return false;
-
- Transform tfm = get_transform(b_ob->matrix_world());
- Transform itfm = transform_quick_inverse(tfm);
-
- BL::Object::modifiers_iterator b_mod;
- for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
- BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
- BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
- if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
- int shader = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
- int display_step = background ? b_part.render_step() : b_part.display_step();
- int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
- int totcurves = totchild;
-
- if(b_part.child_type() == 0 || totchild == 0)
- totcurves += totparts;
-
- if(totcurves == 0)
- continue;
-
- int ren_step = (1 << display_step) + 1;
- if(b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
- ren_step += b_part.kink_extra_steps();
-
- CData->psys_firstcurve.push_back_slow(curvenum);
- CData->psys_curvenum.push_back_slow(totcurves);
- CData->psys_shader.push_back_slow(shader);
-
- float radius = b_part.radius_scale() * 0.5f;
-
- CData->psys_rootradius.push_back_slow(radius * b_part.root_radius());
- CData->psys_tipradius.push_back_slow(radius * b_part.tip_radius());
- CData->psys_shape.push_back_slow(b_part.shape());
- CData->psys_closetip.push_back_slow(b_part.use_close_tip());
-
- int pa_no = 0;
- if(!(b_part.child_type() == 0) && totchild != 0)
- pa_no = totparts;
-
- int num_add = (totparts+totchild - pa_no);
- CData->curve_firstkey.reserve(CData->curve_firstkey.size() + num_add);
- CData->curve_keynum.reserve(CData->curve_keynum.size() + num_add);
- CData->curve_length.reserve(CData->curve_length.size() + num_add);
- CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add*ren_step);
- CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add*ren_step);
-
- for(; pa_no < totparts+totchild; pa_no++) {
- int keynum = 0;
- CData->curve_firstkey.push_back_slow(keyno);
-
- float curve_length = 0.0f;
- float3 pcKey;
- for(int step_no = 0; step_no < ren_step; step_no++) {
- float nco[3];
- b_psys.co_hair(*b_ob, pa_no, step_no, nco);
- float3 cKey = make_float3(nco[0], nco[1], nco[2]);
- cKey = transform_point(&itfm, cKey);
- if(step_no > 0) {
- const float step_length = len(cKey - pcKey);
- curve_length += step_length;
- }
- CData->curvekey_co.push_back_slow(cKey);
- CData->curvekey_time.push_back_slow(curve_length);
- pcKey = cKey;
- keynum++;
- }
- keyno += keynum;
-
- CData->curve_keynum.push_back_slow(keynum);
- CData->curve_length.push_back_slow(curve_length);
- curvenum++;
- }
- }
- }
- }
-
- return true;
+ int curvenum = 0;
+ int keyno = 0;
+
+ if (!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+
+ BL::Object::modifiers_iterator b_mod;
+ for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
+ (background ? b_mod->show_render() : b_mod->show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_part.type() == BL::ParticleSettings::type_HAIR)) {
+ int shader = clamp(b_part.material() - 1, 0, mesh->used_shaders.size() - 1);
+ int display_step = background ? b_part.render_step() : b_part.display_step();
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() :
+ (int)((float)b_psys.child_particles.length() *
+ (float)b_part.display_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (b_part.child_type() == 0 || totchild == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int ren_step = (1 << display_step) + 1;
+ if (b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
+ ren_step += b_part.kink_extra_steps();
+
+ CData->psys_firstcurve.push_back_slow(curvenum);
+ CData->psys_curvenum.push_back_slow(totcurves);
+ CData->psys_shader.push_back_slow(shader);
+
+ float radius = b_part.radius_scale() * 0.5f;
+
+ CData->psys_rootradius.push_back_slow(radius * b_part.root_radius());
+ CData->psys_tipradius.push_back_slow(radius * b_part.tip_radius());
+ CData->psys_shape.push_back_slow(b_part.shape());
+ CData->psys_closetip.push_back_slow(b_part.use_close_tip());
+
+ int pa_no = 0;
+ if (!(b_part.child_type() == 0) && totchild != 0)
+ pa_no = totparts;
+
+ int num_add = (totparts + totchild - pa_no);
+ CData->curve_firstkey.reserve(CData->curve_firstkey.size() + num_add);
+ CData->curve_keynum.reserve(CData->curve_keynum.size() + num_add);
+ CData->curve_length.reserve(CData->curve_length.size() + num_add);
+ CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add * ren_step);
+ CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add * ren_step);
+
+ for (; pa_no < totparts + totchild; pa_no++) {
+ int keynum = 0;
+ CData->curve_firstkey.push_back_slow(keyno);
+
+ float curve_length = 0.0f;
+ float3 pcKey;
+ for (int step_no = 0; step_no < ren_step; step_no++) {
+ float nco[3];
+ b_psys.co_hair(*b_ob, pa_no, step_no, nco);
+ float3 cKey = make_float3(nco[0], nco[1], nco[2]);
+ cKey = transform_point(&itfm, cKey);
+ if (step_no > 0) {
+ const float step_length = len(cKey - pcKey);
+ curve_length += step_length;
+ }
+ CData->curvekey_co.push_back_slow(cKey);
+ CData->curvekey_time.push_back_slow(curve_length);
+ pcKey = cKey;
+ keynum++;
+ }
+ keyno += keynum;
+
+ CData->curve_keynum.push_back_slow(keynum);
+ CData->curve_length.push_back_slow(curve_length);
+ curvenum++;
+ }
+ }
+ }
+ }
+
+ return true;
}
static bool ObtainCacheParticleUV(Mesh *mesh,
@@ -213,56 +208,60 @@ static bool ObtainCacheParticleUV(Mesh *mesh,
bool background,
int uv_num)
{
- if(!(mesh && b_mesh && b_ob && CData))
- return false;
-
- CData->curve_uv.clear();
-
- BL::Object::modifiers_iterator b_mod;
- for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
- BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
- BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
- if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
- int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
- int totcurves = totchild;
-
- if(b_part.child_type() == 0 || totchild == 0)
- totcurves += totparts;
-
- if(totcurves == 0)
- continue;
-
- int pa_no = 0;
- if(!(b_part.child_type() == 0) && totchild != 0)
- pa_no = totparts;
-
- int num_add = (totparts+totchild - pa_no);
- CData->curve_uv.reserve(CData->curve_uv.size() + num_add);
-
- BL::ParticleSystem::particles_iterator b_pa;
- b_psys.particles.begin(b_pa);
- for(; pa_no < totparts+totchild; pa_no++) {
- /* Add UVs */
- BL::Mesh::uv_layers_iterator l;
- b_mesh->uv_layers.begin(l);
-
- float2 uv = make_float2(0.0f, 0.0f);
- if(b_mesh->uv_layers.length())
- b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
- CData->curve_uv.push_back_slow(uv);
-
- if(pa_no < totparts && b_pa != b_psys.particles.end())
- ++b_pa;
- }
- }
- }
- }
-
- return true;
+ if (!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ CData->curve_uv.clear();
+
+ BL::Object::modifiers_iterator b_mod;
+ for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
+ (background ? b_mod->show_render() : b_mod->show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_part.type() == BL::ParticleSettings::type_HAIR)) {
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() :
+ (int)((float)b_psys.child_particles.length() *
+ (float)b_part.display_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (b_part.child_type() == 0 || totchild == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if (!(b_part.child_type() == 0) && totchild != 0)
+ pa_no = totparts;
+
+ int num_add = (totparts + totchild - pa_no);
+ CData->curve_uv.reserve(CData->curve_uv.size() + num_add);
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for (; pa_no < totparts + totchild; pa_no++) {
+ /* Add UVs */
+ BL::Mesh::uv_layers_iterator l;
+ b_mesh->uv_layers.begin(l);
+
+ float2 uv = make_float2(0.0f, 0.0f);
+ if (b_mesh->uv_layers.length())
+ b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
+ CData->curve_uv.push_back_slow(uv);
+
+ if (pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+ }
+ }
+ }
+ }
+
+ return true;
}
static bool ObtainCacheParticleVcol(Mesh *mesh,
@@ -272,481 +271,542 @@ static bool ObtainCacheParticleVcol(Mesh *mesh,
bool background,
int vcol_num)
{
- if(!(mesh && b_mesh && b_ob && CData))
- return false;
-
- CData->curve_vcol.clear();
-
- BL::Object::modifiers_iterator b_mod;
- for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
- BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
- BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
- if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
- int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
- int totcurves = totchild;
-
- if(b_part.child_type() == 0 || totchild == 0)
- totcurves += totparts;
-
- if(totcurves == 0)
- continue;
-
- int pa_no = 0;
- if(!(b_part.child_type() == 0) && totchild != 0)
- pa_no = totparts;
-
- int num_add = (totparts+totchild - pa_no);
- CData->curve_vcol.reserve(CData->curve_vcol.size() + num_add);
-
- BL::ParticleSystem::particles_iterator b_pa;
- b_psys.particles.begin(b_pa);
- for(; pa_no < totparts+totchild; pa_no++) {
- /* Add vertex colors */
- BL::Mesh::vertex_colors_iterator l;
- b_mesh->vertex_colors.begin(l);
-
- float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
- if(b_mesh->vertex_colors.length())
- b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
- CData->curve_vcol.push_back_slow(vcol);
-
- if(pa_no < totparts && b_pa != b_psys.particles.end())
- ++b_pa;
- }
- }
- }
- }
-
- return true;
+ if (!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ CData->curve_vcol.clear();
+
+ BL::Object::modifiers_iterator b_mod;
+ for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
+ (background ? b_mod->show_render() : b_mod->show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_part.type() == BL::ParticleSettings::type_HAIR)) {
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() :
+ (int)((float)b_psys.child_particles.length() *
+ (float)b_part.display_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (b_part.child_type() == 0 || totchild == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if (!(b_part.child_type() == 0) && totchild != 0)
+ pa_no = totparts;
+
+ int num_add = (totparts + totchild - pa_no);
+ CData->curve_vcol.reserve(CData->curve_vcol.size() + num_add);
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for (; pa_no < totparts + totchild; pa_no++) {
+ /* Add vertex colors */
+ BL::Mesh::vertex_colors_iterator l;
+ b_mesh->vertex_colors.begin(l);
+
+ float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
+ if (b_mesh->vertex_colors.length())
+ b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
+ CData->curve_vcol.push_back_slow(vcol);
+
+ if (pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+ }
+ }
+ }
+ }
+
+ return true;
}
-static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
- float3 RotCam, bool is_ortho)
+static void ExportCurveTrianglePlanes(Mesh *mesh,
+ ParticleCurveData *CData,
+ float3 RotCam,
+ bool is_ortho)
{
- int vertexno = mesh->verts.size();
- int vertexindex = vertexno;
- int numverts = 0, numtris = 0;
-
- /* compute and reserve size of arrays */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- numverts += 2 + (CData->curve_keynum[curve] - 1)*2;
- numtris += (CData->curve_keynum[curve] - 1)*2;
- }
- }
-
- mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
-
- /* actually export */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- float3 xbasis;
- float3 v1;
- float time = 0.0f;
- float3 ickey_loc = CData->curvekey_co[CData->curve_firstkey[curve]];
- float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.0f);
- v1 = CData->curvekey_co[CData->curve_firstkey[curve] + 1] - CData->curvekey_co[CData->curve_firstkey[curve]];
- if(is_ortho)
- xbasis = normalize(cross(RotCam, v1));
- else
- xbasis = normalize(cross(RotCam - ickey_loc, v1));
- float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
- float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
- mesh->add_vertex(ickey_loc_shfl);
- mesh->add_vertex(ickey_loc_shfr);
- vertexindex += 2;
-
- for(int curvekey = CData->curve_firstkey[curve] + 1; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) {
- ickey_loc = CData->curvekey_co[curvekey];
-
- if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
- v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 1, CData->curve_firstkey[curve])];
- else
- v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1];
-
- time = CData->curvekey_time[curvekey]/CData->curve_length[curve];
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
-
- if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
-
- if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
-
- if(is_ortho)
- xbasis = normalize(cross(RotCam, v1));
- else
- xbasis = normalize(cross(RotCam - ickey_loc, v1));
- float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
- float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
- mesh->add_vertex(ickey_loc_shfl);
- mesh->add_vertex(ickey_loc_shfr);
- mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], true);
- mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], true);
- vertexindex += 2;
- }
- }
- }
-
- mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
- mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
- mesh->add_face_normals();
- mesh->add_vertex_normals();
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
-
- /* texture coords still needed */
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+ int numverts = 0, numtris = 0;
+
+ /* compute and reserve size of arrays */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ numverts += 2 + (CData->curve_keynum[curve] - 1) * 2;
+ numtris += (CData->curve_keynum[curve] - 1) * 2;
+ }
+ }
+
+ mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
+
+ /* actually export */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ float3 xbasis;
+ float3 v1;
+ float time = 0.0f;
+ float3 ickey_loc = CData->curvekey_co[CData->curve_firstkey[curve]];
+ float radius = shaperadius(
+ CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.0f);
+ v1 = CData->curvekey_co[CData->curve_firstkey[curve] + 1] -
+ CData->curvekey_co[CData->curve_firstkey[curve]];
+ if (is_ortho)
+ xbasis = normalize(cross(RotCam, v1));
+ else
+ xbasis = normalize(cross(RotCam - ickey_loc, v1));
+ float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
+ float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
+ mesh->add_vertex(ickey_loc_shfl);
+ mesh->add_vertex(ickey_loc_shfr);
+ vertexindex += 2;
+
+ for (int curvekey = CData->curve_firstkey[curve] + 1;
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
+ curvekey++) {
+ ickey_loc = CData->curvekey_co[curvekey];
+
+ if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
+ v1 = CData->curvekey_co[curvekey] -
+ CData->curvekey_co[max(curvekey - 1, CData->curve_firstkey[curve])];
+ else
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1];
+
+ time = CData->curvekey_time[curvekey] / CData->curve_length[curve];
+ radius = shaperadius(
+ CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
+ radius = shaperadius(CData->psys_shape[sys],
+ CData->psys_rootradius[sys],
+ CData->psys_tipradius[sys],
+ 0.95f);
+
+ if (CData->psys_closetip[sys] &&
+ (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ if (is_ortho)
+ xbasis = normalize(cross(RotCam, v1));
+ else
+ xbasis = normalize(cross(RotCam - ickey_loc, v1));
+ float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
+ float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
+ mesh->add_vertex(ickey_loc_shfl);
+ mesh->add_vertex(ickey_loc_shfr);
+ mesh->add_triangle(
+ vertexindex - 2, vertexindex, vertexindex - 1, CData->psys_shader[sys], true);
+ mesh->add_triangle(
+ vertexindex + 1, vertexindex - 1, vertexindex, CData->psys_shader[sys], true);
+ vertexindex += 2;
+ }
+ }
+ }
+
+ mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
}
-static void ExportCurveTriangleGeometry(Mesh *mesh,
- ParticleCurveData *CData,
- int resolution)
+static void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resolution)
{
- int vertexno = mesh->verts.size();
- int vertexindex = vertexno;
- int numverts = 0, numtris = 0;
-
- /* compute and reserve size of arrays */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- numverts += (CData->curve_keynum[curve] - 1)*resolution + resolution;
- numtris += (CData->curve_keynum[curve] - 1)*2*resolution;
- }
- }
-
- mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
-
- /* actually export */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]);
- if(!is_zero(firstxbasis))
- firstxbasis = normalize(firstxbasis);
- else
- firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]));
-
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- float3 xbasis = firstxbasis;
- float3 v1;
- float3 v2;
-
- if(curvekey == CData->curve_firstkey[curve]) {
- v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
- v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- }
- else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
- v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
- }
- else {
- v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- }
-
- xbasis = cross(v1, v2);
-
- if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
- firstxbasis = normalize(xbasis);
- break;
- }
- }
-
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- int subv = 1;
- float3 xbasis;
- float3 ybasis;
- float3 v1;
- float3 v2;
-
- if(curvekey == CData->curve_firstkey[curve]) {
- subv = 0;
- v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
- v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- }
- else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
- v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
- }
- else {
- v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- }
-
- xbasis = cross(v1, v2);
-
- if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
- xbasis = normalize(xbasis);
- firstxbasis = xbasis;
- }
- else
- xbasis = firstxbasis;
-
- ybasis = normalize(cross(xbasis, v2));
-
- for(; subv <= 1; subv++) {
- float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
- float time = 0.0f;
-
- InterpolateKeySegments(subv, 1, curvekey, curve, &ickey_loc, &time, CData);
-
- float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
-
- if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == 1))
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
-
- if(CData->psys_closetip[sys] && (subv == 1) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
-
- float angle = M_2PI_F / (float)resolution;
- for(int section = 0; section < resolution; section++) {
- float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis + sinf(angle * section) * ybasis);
- mesh->add_vertex(ickey_loc_shf);
- }
-
- if(subv != 0) {
- for(int section = 0; section < resolution - 1; section++) {
- mesh->add_triangle(vertexindex - resolution + section, vertexindex + section, vertexindex - resolution + section + 1, CData->psys_shader[sys], true);
- mesh->add_triangle(vertexindex + section + 1, vertexindex - resolution + section + 1, vertexindex + section, CData->psys_shader[sys], true);
- }
- mesh->add_triangle(vertexindex-1, vertexindex + resolution - 1, vertexindex - resolution, CData->psys_shader[sys], true);
- mesh->add_triangle(vertexindex, vertexindex - resolution , vertexindex + resolution - 1, CData->psys_shader[sys], true);
- }
- vertexindex += resolution;
- }
- }
- }
- }
-
- mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
- mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
- mesh->add_face_normals();
- mesh->add_vertex_normals();
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
-
- /* texture coords still needed */
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+ int numverts = 0, numtris = 0;
+
+ /* compute and reserve size of arrays */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ numverts += (CData->curve_keynum[curve] - 1) * resolution + resolution;
+ numtris += (CData->curve_keynum[curve] - 1) * 2 * resolution;
+ }
+ }
+
+ mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
+
+ /* actually export */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ float3 firstxbasis = cross(make_float3(1.0f, 0.0f, 0.0f),
+ CData->curvekey_co[CData->curve_firstkey[curve] + 1] -
+ CData->curvekey_co[CData->curve_firstkey[curve]]);
+ if (!is_zero(firstxbasis))
+ firstxbasis = normalize(firstxbasis);
+ else
+ firstxbasis = normalize(cross(make_float3(0.0f, 1.0f, 0.0f),
+ CData->curvekey_co[CData->curve_firstkey[curve] + 1] -
+ CData->curvekey_co[CData->curve_firstkey[curve]]));
+
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ float3 xbasis = firstxbasis;
+ float3 v1;
+ float3 v2;
+
+ if (curvekey == CData->curve_firstkey[curve]) {
+ v1 = CData->curvekey_co[min(
+ curvekey + 2, CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] -
+ CData->curvekey_co[curvekey + 1];
+ v2 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ }
+ else if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ v2 = CData->curvekey_co[curvekey - 1] -
+ CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ }
+
+ xbasis = cross(v1, v2);
+
+ if (len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ firstxbasis = normalize(xbasis);
+ break;
+ }
+ }
+
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ int subv = 1;
+ float3 xbasis;
+ float3 ybasis;
+ float3 v1;
+ float3 v2;
+
+ if (curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(
+ curvekey + 2, CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] -
+ CData->curvekey_co[curvekey + 1];
+ v2 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ }
+ else if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ v2 = CData->curvekey_co[curvekey - 1] -
+ CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ }
+
+ xbasis = cross(v1, v2);
+
+ if (len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ xbasis = normalize(xbasis);
+ firstxbasis = xbasis;
+ }
+ else
+ xbasis = firstxbasis;
+
+ ybasis = normalize(cross(xbasis, v2));
+
+ for (; subv <= 1; subv++) {
+ float3 ickey_loc = make_float3(0.0f, 0.0f, 0.0f);
+ float time = 0.0f;
+
+ InterpolateKeySegments(subv, 1, curvekey, curve, &ickey_loc, &time, CData);
+
+ float radius = shaperadius(CData->psys_shape[sys],
+ CData->psys_rootradius[sys],
+ CData->psys_tipradius[sys],
+ time);
+
+ if ((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) &&
+ (subv == 1))
+ radius = shaperadius(CData->psys_shape[sys],
+ CData->psys_rootradius[sys],
+ CData->psys_tipradius[sys],
+ 0.95f);
+
+ if (CData->psys_closetip[sys] && (subv == 1) &&
+ (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ float angle = M_2PI_F / (float)resolution;
+ for (int section = 0; section < resolution; section++) {
+ float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis +
+ sinf(angle * section) * ybasis);
+ mesh->add_vertex(ickey_loc_shf);
+ }
+
+ if (subv != 0) {
+ for (int section = 0; section < resolution - 1; section++) {
+ mesh->add_triangle(vertexindex - resolution + section,
+ vertexindex + section,
+ vertexindex - resolution + section + 1,
+ CData->psys_shader[sys],
+ true);
+ mesh->add_triangle(vertexindex + section + 1,
+ vertexindex - resolution + section + 1,
+ vertexindex + section,
+ CData->psys_shader[sys],
+ true);
+ }
+ mesh->add_triangle(vertexindex - 1,
+ vertexindex + resolution - 1,
+ vertexindex - resolution,
+ CData->psys_shader[sys],
+ true);
+ mesh->add_triangle(vertexindex,
+ vertexindex - resolution,
+ vertexindex + resolution - 1,
+ CData->psys_shader[sys],
+ true);
+ }
+ vertexindex += resolution;
+ }
+ }
+ }
+ }
+
+ mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
}
static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
{
- int num_keys = 0;
- int num_curves = 0;
-
- if(mesh->num_curves())
- return;
-
- Attribute *attr_intercept = NULL;
- Attribute *attr_random = NULL;
-
- if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
- attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
- if(mesh->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
- attr_random = mesh->curve_attributes.add(ATTR_STD_CURVE_RANDOM);
-
- /* compute and reserve size of arrays */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- num_keys += CData->curve_keynum[curve];
- num_curves++;
- }
- }
-
- if(num_curves > 0) {
- VLOG(1) << "Exporting curve segments for mesh " << mesh->name;
- }
-
- mesh->reserve_curves(mesh->num_curves() + num_curves, mesh->curve_keys.size() + num_keys);
-
- num_keys = 0;
- num_curves = 0;
-
- /* actually export */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- size_t num_curve_keys = 0;
-
- for(int curvekey = CData->curve_firstkey[curve];
- curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
- curvekey++)
- {
- const float3 ickey_loc = CData->curvekey_co[curvekey];
- const float curve_time = CData->curvekey_time[curvekey];
- const float curve_length = CData->curve_length[curve];
- const float time = (curve_length > 0.0f)
- ? curve_time / curve_length
- : 0.0f;
- float radius = shaperadius(CData->psys_shape[sys],
- CData->psys_rootradius[sys],
- CData->psys_tipradius[sys],
- time);
- if(CData->psys_closetip[sys] &&
- (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
- {
- radius = 0.0f;
- }
- mesh->add_curve_key(ickey_loc, radius);
- if(attr_intercept)
- attr_intercept->add(time);
-
- num_curve_keys++;
- }
-
- if(attr_random != NULL) {
- attr_random->add(hash_int_01(num_curves));
- }
-
- mesh->add_curve(num_keys, CData->psys_shader[sys]);
- num_keys += num_curve_keys;
- num_curves++;
- }
- }
-
- /* check allocation */
- if((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) {
- VLOG(1) << "Allocation failed, clearing data";
- mesh->clear();
- }
+ int num_keys = 0;
+ int num_curves = 0;
+
+ if (mesh->num_curves())
+ return;
+
+ Attribute *attr_intercept = NULL;
+ Attribute *attr_random = NULL;
+
+ if (mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
+ attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+ if (mesh->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
+ attr_random = mesh->curve_attributes.add(ATTR_STD_CURVE_RANDOM);
+
+ /* compute and reserve size of arrays */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ num_keys += CData->curve_keynum[curve];
+ num_curves++;
+ }
+ }
+
+ if (num_curves > 0) {
+ VLOG(1) << "Exporting curve segments for mesh " << mesh->name;
+ }
+
+ mesh->reserve_curves(mesh->num_curves() + num_curves, mesh->curve_keys.size() + num_keys);
+
+ num_keys = 0;
+ num_curves = 0;
+
+ /* actually export */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ size_t num_curve_keys = 0;
+
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
+ curvekey++) {
+ const float3 ickey_loc = CData->curvekey_co[curvekey];
+ const float curve_time = CData->curvekey_time[curvekey];
+ const float curve_length = CData->curve_length[curve];
+ const float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
+ float radius = shaperadius(
+ CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+ if (CData->psys_closetip[sys] &&
+ (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) {
+ radius = 0.0f;
+ }
+ mesh->add_curve_key(ickey_loc, radius);
+ if (attr_intercept)
+ attr_intercept->add(time);
+
+ num_curve_keys++;
+ }
+
+ if (attr_random != NULL) {
+ attr_random->add(hash_int_01(num_curves));
+ }
+
+ mesh->add_curve(num_keys, CData->psys_shader[sys]);
+ num_keys += num_curve_keys;
+ num_curves++;
+ }
+ }
+
+ /* check allocation */
+ if ((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) {
+ VLOG(1) << "Allocation failed, clearing data";
+ mesh->clear();
+ }
}
static float4 CurveSegmentMotionCV(ParticleCurveData *CData, int sys, int curve, int curvekey)
{
- const float3 ickey_loc = CData->curvekey_co[curvekey];
- const float curve_time = CData->curvekey_time[curvekey];
- const float curve_length = CData->curve_length[curve];
- float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
- float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
-
- if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
- radius = 0.0f;
-
- /* curve motion keys store both position and radius in float4 */
- float4 mP = float3_to_float4(ickey_loc);
- mP.w = radius;
- return mP;
+ const float3 ickey_loc = CData->curvekey_co[curvekey];
+ const float curve_time = CData->curvekey_time[curvekey];
+ const float curve_length = CData->curve_length[curve];
+ float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
+ float radius = shaperadius(
+ CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if (CData->psys_closetip[sys] &&
+ (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = 0.0f;
+
+ /* curve motion keys store both position and radius in float4 */
+ float4 mP = float3_to_float4(ickey_loc);
+ mP.w = radius;
+ return mP;
}
static float4 LerpCurveSegmentMotionCV(ParticleCurveData *CData, int sys, int curve, float step)
{
- assert(step >= 0.0f);
- assert(step <= 1.0f);
- const int first_curve_key = CData->curve_firstkey[curve];
- const float curve_key_f = step * (CData->curve_keynum[curve] - 1);
- int curvekey = (int)floorf(curve_key_f);
- const float remainder = curve_key_f - curvekey;
- if(remainder == 0.0f) {
- return CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey);
- }
- int curvekey2 = curvekey + 1;
- if(curvekey2 >= (CData->curve_keynum[curve] - 1)) {
- curvekey2 = (CData->curve_keynum[curve] - 1);
- curvekey = curvekey2 - 1;
- }
- const float4 mP = CurveSegmentMotionCV(
- CData, sys, curve, first_curve_key + curvekey);
- const float4 mP2 = CurveSegmentMotionCV(
- CData, sys, curve, first_curve_key + curvekey2);
- return lerp(mP, mP2, remainder);
+ assert(step >= 0.0f);
+ assert(step <= 1.0f);
+ const int first_curve_key = CData->curve_firstkey[curve];
+ const float curve_key_f = step * (CData->curve_keynum[curve] - 1);
+ int curvekey = (int)floorf(curve_key_f);
+ const float remainder = curve_key_f - curvekey;
+ if (remainder == 0.0f) {
+ return CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey);
+ }
+ int curvekey2 = curvekey + 1;
+ if (curvekey2 >= (CData->curve_keynum[curve] - 1)) {
+ curvekey2 = (CData->curve_keynum[curve] - 1);
+ curvekey = curvekey2 - 1;
+ }
+ const float4 mP = CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey);
+ const float4 mP2 = CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey2);
+ return lerp(mP, mP2, remainder);
}
static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int motion_step)
{
- VLOG(1) << "Exporting curve motion segments for mesh " << mesh->name
- << ", motion step " << motion_step;
-
- /* find attribute */
- Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- bool new_attribute = false;
-
- /* add new attribute if it doesn't exist already */
- if(!attr_mP) {
- VLOG(1) << "Creating new motion vertex position attribute";
- attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- new_attribute = true;
- }
-
- /* export motion vectors for curve keys */
- size_t numkeys = mesh->curve_keys.size();
- float4 *mP = attr_mP->data_float4() + motion_step*numkeys;
- bool have_motion = false;
- int i = 0;
- int num_curves = 0;
-
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- /* Curve lengths may not match! Curves can be clipped. */
- int curve_key_end = (num_curves+1 < (int)mesh->curve_first_key.size() ? mesh->curve_first_key[num_curves+1] : (int)mesh->curve_keys.size());
- const int num_center_curve_keys = curve_key_end - mesh->curve_first_key[num_curves];
- const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys;
-
- if(!is_num_keys_different) {
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) {
- if(i < mesh->curve_keys.size()) {
- mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey);
- if(!have_motion) {
- /* unlike mesh coordinates, these tend to be slightly different
- * between frames due to particle transforms into/out of object
- * space, so we use an epsilon to detect actual changes */
- float4 curve_key = float3_to_float4(mesh->curve_keys[i]);
- curve_key.w = mesh->curve_radius[i];
- if(len_squared(mP[i] - curve_key) > 1e-5f*1e-5f)
- have_motion = true;
- }
- }
- i++;
- }
- }
- else {
- /* Number of keys has changed. Genereate an interpolated version
- * to preserve motion blur. */
- const float step_size =
- num_center_curve_keys > 1
- ? 1.0f / (num_center_curve_keys - 1)
- : 0.0f;
- for(int step_index = 0;
- step_index < num_center_curve_keys;
- ++step_index)
- {
- const float step = step_index * step_size;
- mP[i] = LerpCurveSegmentMotionCV(CData, sys, curve, step);
- i++;
- }
- have_motion = true;
- }
- num_curves++;
- }
- }
-
- /* in case of new attribute, we verify if there really was any motion */
- if(new_attribute) {
- if(i != numkeys || !have_motion) {
- /* No motion or hair "topology" changed, remove attributes again. */
- if(i != numkeys) {
- VLOG(1) << "Hair topology changed, removing attribute.";
- }
- else {
- VLOG(1) << "No motion, removing attribute.";
- }
- mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
- }
- else if(motion_step > 0) {
- VLOG(1) << "Filling in new motion vertex position for motion_step "
- << motion_step;
- /* motion, fill up previous steps that we might have skipped because
- * they had no motion, but we need them anyway now */
- for(int step = 0; step < motion_step; step++) {
- float4 *mP = attr_mP->data_float4() + step*numkeys;
-
- for(int key = 0; key < numkeys; key++) {
- mP[key] = float3_to_float4(mesh->curve_keys[key]);
- mP[key].w = mesh->curve_radius[key];
- }
- }
- }
- }
+ VLOG(1) << "Exporting curve motion segments for mesh " << mesh->name << ", motion step "
+ << motion_step;
+
+ /* find attribute */
+ Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ bool new_attribute = false;
+
+ /* add new attribute if it doesn't exist already */
+ if (!attr_mP) {
+ VLOG(1) << "Creating new motion vertex position attribute";
+ attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ new_attribute = true;
+ }
+
+ /* export motion vectors for curve keys */
+ size_t numkeys = mesh->curve_keys.size();
+ float4 *mP = attr_mP->data_float4() + motion_step * numkeys;
+ bool have_motion = false;
+ int i = 0;
+ int num_curves = 0;
+
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ /* Curve lengths may not match! Curves can be clipped. */
+ int curve_key_end = (num_curves + 1 < (int)mesh->curve_first_key.size() ?
+ mesh->curve_first_key[num_curves + 1] :
+ (int)mesh->curve_keys.size());
+ const int num_center_curve_keys = curve_key_end - mesh->curve_first_key[num_curves];
+ const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys;
+
+ if (!is_num_keys_different) {
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
+ curvekey++) {
+ if (i < mesh->curve_keys.size()) {
+ mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey);
+ if (!have_motion) {
+ /* unlike mesh coordinates, these tend to be slightly different
+ * between frames due to particle transforms into/out of object
+ * space, so we use an epsilon to detect actual changes */
+ float4 curve_key = float3_to_float4(mesh->curve_keys[i]);
+ curve_key.w = mesh->curve_radius[i];
+ if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f)
+ have_motion = true;
+ }
+ }
+ i++;
+ }
+ }
+ else {
+ /* Number of keys has changed. Genereate an interpolated version
+ * to preserve motion blur. */
+ const float step_size = num_center_curve_keys > 1 ? 1.0f / (num_center_curve_keys - 1) :
+ 0.0f;
+ for (int step_index = 0; step_index < num_center_curve_keys; ++step_index) {
+ const float step = step_index * step_size;
+ mP[i] = LerpCurveSegmentMotionCV(CData, sys, curve, step);
+ i++;
+ }
+ have_motion = true;
+ }
+ num_curves++;
+ }
+ }
+
+ /* in case of new attribute, we verify if there really was any motion */
+ if (new_attribute) {
+ if (i != numkeys || !have_motion) {
+ /* No motion or hair "topology" changed, remove attributes again. */
+ if (i != numkeys) {
+ VLOG(1) << "Hair topology changed, removing attribute.";
+ }
+ else {
+ VLOG(1) << "No motion, removing attribute.";
+ }
+ mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+ else if (motion_step > 0) {
+ VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
+ /* motion, fill up previous steps that we might have skipped because
+ * they had no motion, but we need them anyway now */
+ for (int step = 0; step < motion_step; step++) {
+ float4 *mP = attr_mP->data_float4() + step * numkeys;
+
+ for (int key = 0; key < numkeys; key++) {
+ mP[key] = float3_to_float4(mesh->curve_keys[key]);
+ mP[key].w = mesh->curve_radius[key];
+ }
+ }
+ }
+ }
}
static void ExportCurveTriangleUV(ParticleCurveData *CData,
@@ -754,30 +814,34 @@ static void ExportCurveTriangleUV(ParticleCurveData *CData,
int resol,
float2 *uvdata)
{
- if(uvdata == NULL)
- return;
- int vertexindex = vert_offset;
-
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- for(int section = 0; section < resol; section++) {
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- }
- }
- }
- }
+ if (uvdata == NULL)
+ return;
+ int vertexindex = vert_offset;
+
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ for (int section = 0; section < resol; section++) {
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ }
+ }
+ }
+ }
}
static void ExportCurveTriangleVcol(ParticleCurveData *CData,
@@ -785,295 +849,296 @@ static void ExportCurveTriangleVcol(ParticleCurveData *CData,
int resol,
uchar4 *cdata)
{
- if(cdata == NULL)
- return;
-
- int vertexindex = vert_offset;
-
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- for(int section = 0; section < resol; section++) {
- /* Encode vertex color using the sRGB curve. */
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- }
- }
- }
- }
+ if (cdata == NULL)
+ return;
+
+ int vertexindex = vert_offset;
+
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ for (int section = 0; section < resol; section++) {
+ /* Encode vertex color using the sRGB curve. */
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ }
+ }
+ }
+ }
}
/* Hair Curve Sync */
void BlenderSync::sync_curve_settings()
{
- PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves");
-
- CurveSystemManager *curve_system_manager = scene->curve_system_manager;
- CurveSystemManager prev_curve_system_manager = *curve_system_manager;
-
- curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
- curve_system_manager->minimum_width = get_float(csscene, "minimum_width");
- curve_system_manager->maximum_width = get_float(csscene, "maximum_width");
-
- curve_system_manager->primitive =
- (CurvePrimitiveType)get_enum(csscene,
- "primitive",
- CURVE_NUM_PRIMITIVE_TYPES,
- CURVE_LINE_SEGMENTS);
- curve_system_manager->curve_shape =
- (CurveShapeType)get_enum(csscene,
- "shape",
- CURVE_NUM_SHAPE_TYPES,
- CURVE_THICK);
- curve_system_manager->resolution = get_int(csscene, "resolution");
- curve_system_manager->subdivisions = get_int(csscene, "subdivisions");
- curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing");
-
- /* Triangles */
- if(curve_system_manager->primitive == CURVE_TRIANGLES) {
- /* camera facing planes */
- if(curve_system_manager->curve_shape == CURVE_RIBBON) {
- curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES;
- curve_system_manager->resolution = 1;
- }
- else if(curve_system_manager->curve_shape == CURVE_THICK) {
- curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES;
- }
- }
- /* Line Segments */
- else if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS) {
- if(curve_system_manager->curve_shape == CURVE_RIBBON) {
- /* tangent shading */
- curve_system_manager->line_method = CURVE_UNCORRECTED;
- curve_system_manager->use_encasing = true;
- curve_system_manager->use_backfacing = false;
- curve_system_manager->use_tangent_normal_geometry = true;
- }
- else if(curve_system_manager->curve_shape == CURVE_THICK) {
- curve_system_manager->line_method = CURVE_ACCURATE;
- curve_system_manager->use_encasing = false;
- curve_system_manager->use_tangent_normal_geometry = false;
- }
- }
- /* Curve Segments */
- else if(curve_system_manager->primitive == CURVE_SEGMENTS) {
- if(curve_system_manager->curve_shape == CURVE_RIBBON) {
- curve_system_manager->primitive = CURVE_RIBBONS;
- curve_system_manager->use_backfacing = false;
- }
- }
-
- if(curve_system_manager->modified_mesh(prev_curve_system_manager)) {
- BL::BlendData::objects_iterator b_ob;
-
- for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
- if(object_is_mesh(*b_ob)) {
- BL::Object::particle_systems_iterator b_psys;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
- if((b_psys->settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys->settings().type()==BL::ParticleSettings::type_HAIR)) {
- BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
- mesh_map.set_recalc(key);
- object_map.set_recalc(*b_ob);
- }
- }
- }
- }
- }
-
- if(curve_system_manager->modified(prev_curve_system_manager))
- curve_system_manager->tag_update(scene);
+ PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves");
+
+ CurveSystemManager *curve_system_manager = scene->curve_system_manager;
+ CurveSystemManager prev_curve_system_manager = *curve_system_manager;
+
+ curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
+ curve_system_manager->minimum_width = get_float(csscene, "minimum_width");
+ curve_system_manager->maximum_width = get_float(csscene, "maximum_width");
+
+ curve_system_manager->primitive = (CurvePrimitiveType)get_enum(
+ csscene, "primitive", CURVE_NUM_PRIMITIVE_TYPES, CURVE_LINE_SEGMENTS);
+ curve_system_manager->curve_shape = (CurveShapeType)get_enum(
+ csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK);
+ curve_system_manager->resolution = get_int(csscene, "resolution");
+ curve_system_manager->subdivisions = get_int(csscene, "subdivisions");
+ curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing");
+
+ /* Triangles */
+ if (curve_system_manager->primitive == CURVE_TRIANGLES) {
+ /* camera facing planes */
+ if (curve_system_manager->curve_shape == CURVE_RIBBON) {
+ curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES;
+ curve_system_manager->resolution = 1;
+ }
+ else if (curve_system_manager->curve_shape == CURVE_THICK) {
+ curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES;
+ }
+ }
+ /* Line Segments */
+ else if (curve_system_manager->primitive == CURVE_LINE_SEGMENTS) {
+ if (curve_system_manager->curve_shape == CURVE_RIBBON) {
+ /* tangent shading */
+ curve_system_manager->line_method = CURVE_UNCORRECTED;
+ curve_system_manager->use_encasing = true;
+ curve_system_manager->use_backfacing = false;
+ curve_system_manager->use_tangent_normal_geometry = true;
+ }
+ else if (curve_system_manager->curve_shape == CURVE_THICK) {
+ curve_system_manager->line_method = CURVE_ACCURATE;
+ curve_system_manager->use_encasing = false;
+ curve_system_manager->use_tangent_normal_geometry = false;
+ }
+ }
+ /* Curve Segments */
+ else if (curve_system_manager->primitive == CURVE_SEGMENTS) {
+ if (curve_system_manager->curve_shape == CURVE_RIBBON) {
+ curve_system_manager->primitive = CURVE_RIBBONS;
+ curve_system_manager->use_backfacing = false;
+ }
+ }
+
+ if (curve_system_manager->modified_mesh(prev_curve_system_manager)) {
+ BL::BlendData::objects_iterator b_ob;
+
+ for (b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
+ if (object_is_mesh(*b_ob)) {
+ BL::Object::particle_systems_iterator b_psys;
+ for (b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end();
+ ++b_psys) {
+ if ((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_psys->settings().type() == BL::ParticleSettings::type_HAIR)) {
+ BL::ID key = BKE_object_is_modified(*b_ob) ? *b_ob : b_ob->data();
+ mesh_map.set_recalc(key);
+ object_map.set_recalc(*b_ob);
+ }
+ }
+ }
+ }
+ }
+
+ if (curve_system_manager->modified(prev_curve_system_manager))
+ curve_system_manager->tag_update(scene);
}
-void BlenderSync::sync_curves(Mesh *mesh,
- BL::Mesh& b_mesh,
- BL::Object& b_ob,
- bool motion,
- int motion_step)
+void BlenderSync::sync_curves(
+ Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step)
{
- if(!motion) {
- /* Clear stored curve data */
- mesh->curve_keys.clear();
- mesh->curve_radius.clear();
- mesh->curve_first_key.clear();
- mesh->curve_shader.clear();
- mesh->curve_attributes.clear();
- }
-
- /* obtain general settings */
- const bool use_curves = scene->curve_system_manager->use_curves;
-
- if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
- if(!motion)
- mesh->compute_bounds();
- return;
- }
-
- const int primitive = scene->curve_system_manager->primitive;
- const int triangle_method = scene->curve_system_manager->triangle_method;
- const int resolution = scene->curve_system_manager->resolution;
- const size_t vert_num = mesh->verts.size();
- const size_t tri_num = mesh->num_triangles();
- int used_res = 1;
-
- /* extract particle hair data - should be combined with connecting to mesh later*/
-
- ParticleCurveData CData;
-
- ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
-
- /* add hair geometry to mesh */
- if(primitive == CURVE_TRIANGLES) {
- if(triangle_method == CURVE_CAMERA_TRIANGLES) {
- /* obtain camera parameters */
- float3 RotCam;
- Camera *camera = scene->camera;
- Transform &ctfm = camera->matrix;
- if(camera->type == CAMERA_ORTHOGRAPHIC) {
- RotCam = -make_float3(ctfm.x.z, ctfm.y.z, ctfm.z.z);
- }
- else {
- Transform tfm = get_transform(b_ob.matrix_world());
- Transform itfm = transform_quick_inverse(tfm);
- RotCam = transform_point(&itfm, make_float3(ctfm.x.w,
- ctfm.y.w,
- ctfm.z.w));
- }
- bool is_ortho = camera->type == CAMERA_ORTHOGRAPHIC;
- ExportCurveTrianglePlanes(mesh, &CData, RotCam, is_ortho);
- }
- else {
- ExportCurveTriangleGeometry(mesh, &CData, resolution);
- used_res = resolution;
- }
- }
- else {
- if(motion)
- ExportCurveSegmentsMotion(mesh, &CData, motion_step);
- else
- ExportCurveSegments(scene, mesh, &CData);
- }
-
- /* generated coordinates from first key. we should ideally get this from
- * blender to handle deforming objects */
- if(!motion) {
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
-
- if(primitive == CURVE_TRIANGLES) {
- Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED);
- float3 *generated = attr_generated->data_float3();
-
- for(size_t i = vert_num; i < mesh->verts.size(); i++)
- generated[i] = mesh->verts[i]*size - loc;
- }
- else {
- Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
- float3 *generated = attr_generated->data_float3();
-
- for(size_t i = 0; i < mesh->num_curves(); i++) {
- float3 co = mesh->curve_keys[mesh->get_curve(i).first_key];
- generated[i] = co*size - loc;
- }
- }
- }
- }
-
- /* create vertex color attributes */
- if(!motion) {
- BL::Mesh::vertex_colors_iterator l;
- int vcol_num = 0;
-
- for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
- if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
- continue;
-
- ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num);
-
- if(primitive == CURVE_TRIANGLES) {
- Attribute *attr_vcol = mesh->attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
-
- uchar4 *cdata = attr_vcol->data_uchar4();
-
- ExportCurveTriangleVcol(&CData, tri_num * 3, used_res, cdata);
- }
- else {
- Attribute *attr_vcol = mesh->curve_attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
-
- float3 *fdata = attr_vcol->data_float3();
-
- if(fdata) {
- size_t i = 0;
-
- /* Encode vertex color using the sRGB curve. */
- for(size_t curve = 0; curve < CData.curve_vcol.size(); curve++) {
- fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]);
- }
- }
- }
- }
- }
-
- /* create UV attributes */
- if(!motion) {
- BL::Mesh::uv_layers_iterator l;
- int uv_num = 0;
-
- for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) {
- bool active_render = l->active_render();
- AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
- ustring name = ustring(l->name().c_str());
-
- /* UV map */
- if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
- Attribute *attr_uv;
-
- ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num);
-
- if(primitive == CURVE_TRIANGLES) {
- if(active_render)
- attr_uv = mesh->attributes.add(std, name);
- else
- attr_uv = mesh->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
-
- float2 *uv = attr_uv->data_float2();
-
- ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv);
- }
- else {
- if(active_render)
- attr_uv = mesh->curve_attributes.add(std, name);
- else
- attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
-
- float2 *uv = attr_uv->data_float2();
-
- if(uv) {
- size_t i = 0;
-
- for(size_t curve = 0; curve < CData.curve_uv.size(); curve++) {
- uv[i++] = CData.curve_uv[curve];
- }
- }
- }
- }
- }
- }
-
- mesh->compute_bounds();
+ if (!motion) {
+ /* Clear stored curve data */
+ mesh->curve_keys.clear();
+ mesh->curve_radius.clear();
+ mesh->curve_first_key.clear();
+ mesh->curve_shader.clear();
+ mesh->curve_attributes.clear();
+ }
+
+ /* obtain general settings */
+ const bool use_curves = scene->curve_system_manager->use_curves;
+
+ if (!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
+ if (!motion)
+ mesh->compute_bounds();
+ return;
+ }
+
+ const int primitive = scene->curve_system_manager->primitive;
+ const int triangle_method = scene->curve_system_manager->triangle_method;
+ const int resolution = scene->curve_system_manager->resolution;
+ const size_t vert_num = mesh->verts.size();
+ const size_t tri_num = mesh->num_triangles();
+ int used_res = 1;
+
+ /* extract particle hair data - should be combined with connecting to mesh later*/
+
+ ParticleCurveData CData;
+
+ ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
+
+ /* add hair geometry to mesh */
+ if (primitive == CURVE_TRIANGLES) {
+ if (triangle_method == CURVE_CAMERA_TRIANGLES) {
+ /* obtain camera parameters */
+ float3 RotCam;
+ Camera *camera = scene->camera;
+ Transform &ctfm = camera->matrix;
+ if (camera->type == CAMERA_ORTHOGRAPHIC) {
+ RotCam = -make_float3(ctfm.x.z, ctfm.y.z, ctfm.z.z);
+ }
+ else {
+ Transform tfm = get_transform(b_ob.matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+ RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, ctfm.z.w));
+ }
+ bool is_ortho = camera->type == CAMERA_ORTHOGRAPHIC;
+ ExportCurveTrianglePlanes(mesh, &CData, RotCam, is_ortho);
+ }
+ else {
+ ExportCurveTriangleGeometry(mesh, &CData, resolution);
+ used_res = resolution;
+ }
+ }
+ else {
+ if (motion)
+ ExportCurveSegmentsMotion(mesh, &CData, motion_step);
+ else
+ ExportCurveSegments(scene, mesh, &CData);
+ }
+
+ /* generated coordinates from first key. we should ideally get this from
+ * blender to handle deforming objects */
+ if (!motion) {
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ if (primitive == CURVE_TRIANGLES) {
+ Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+
+ for (size_t i = vert_num; i < mesh->verts.size(); i++)
+ generated[i] = mesh->verts[i] * size - loc;
+ }
+ else {
+ Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+
+ for (size_t i = 0; i < mesh->num_curves(); i++) {
+ float3 co = mesh->curve_keys[mesh->get_curve(i).first_key];
+ generated[i] = co * size - loc;
+ }
+ }
+ }
+ }
+
+ /* create vertex color attributes */
+ if (!motion) {
+ BL::Mesh::vertex_colors_iterator l;
+ int vcol_num = 0;
+
+ for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
+ if (!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num);
+
+ if (primitive == CURVE_TRIANGLES) {
+ Attribute *attr_vcol = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+
+ uchar4 *cdata = attr_vcol->data_uchar4();
+
+ ExportCurveTriangleVcol(&CData, tri_num * 3, used_res, cdata);
+ }
+ else {
+ Attribute *attr_vcol = mesh->curve_attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
+
+ float3 *fdata = attr_vcol->data_float3();
+
+ if (fdata) {
+ size_t i = 0;
+
+ /* Encode vertex color using the sRGB curve. */
+ for (size_t curve = 0; curve < CData.curve_vcol.size(); curve++) {
+ fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]);
+ }
+ }
+ }
+ }
+ }
+
+ /* create UV attributes */
+ if (!motion) {
+ BL::Mesh::uv_layers_iterator l;
+ int uv_num = 0;
+
+ for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) {
+ bool active_render = l->active_render();
+ AttributeStandard std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
+ ustring name = ustring(l->name().c_str());
+
+ /* UV map */
+ if (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+ Attribute *attr_uv;
+
+ ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num);
+
+ if (primitive == CURVE_TRIANGLES) {
+ if (active_render)
+ attr_uv = mesh->attributes.add(std, name);
+ else
+ attr_uv = mesh->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
+
+ float2 *uv = attr_uv->data_float2();
+
+ ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv);
+ }
+ else {
+ if (active_render)
+ attr_uv = mesh->curve_attributes.add(std, name);
+ else
+ attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
+
+ float2 *uv = attr_uv->data_float2();
+
+ if (uv) {
+ size_t i = 0;
+
+ for (size_t curve = 0; curve < CData.curve_uv.size(); curve++) {
+ uv[i++] = CData.curve_uv[curve];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ mesh->compute_bounds();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp
index 969601b1c37..98fc0c6dec4 100644
--- a/intern/cycles/blender/blender_device.cpp
+++ b/intern/cycles/blender/blender_device.cpp
@@ -19,91 +19,89 @@
CCL_NAMESPACE_BEGIN
-int blender_device_threads(BL::Scene& b_scene)
+int blender_device_threads(BL::Scene &b_scene)
{
- BL::RenderSettings b_r = b_scene.render();
+ BL::RenderSettings b_r = b_scene.render();
- if(b_r.threads_mode() == BL::RenderSettings::threads_mode_FIXED)
- return b_r.threads();
- else
- return 0;
+ if (b_r.threads_mode() == BL::RenderSettings::threads_mode_FIXED)
+ return b_r.threads();
+ else
+ return 0;
}
-DeviceInfo blender_device_info(BL::Preferences& b_preferences, BL::Scene& b_scene, bool background)
+DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- /* Default to CPU device. */
- DeviceInfo device = Device::available_devices(DEVICE_MASK_CPU).front();
+ /* Default to CPU device. */
+ DeviceInfo device = Device::available_devices(DEVICE_MASK_CPU).front();
- if(get_enum(cscene, "device") == 2) {
- /* Find network device. */
- vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
- if(!devices.empty()) {
- device = devices.front();
- }
- }
- else if(get_enum(cscene, "device") == 1) {
- /* Find cycles preferences. */
- PointerRNA cpreferences;
+ if (get_enum(cscene, "device") == 2) {
+ /* Find network device. */
+ vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
+ if (!devices.empty()) {
+ device = devices.front();
+ }
+ }
+ else if (get_enum(cscene, "device") == 1) {
+ /* Find cycles preferences. */
+ PointerRNA cpreferences;
- BL::Preferences::addons_iterator b_addon_iter;
- for(b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end(); ++b_addon_iter) {
- if(b_addon_iter->module() == "cycles") {
- cpreferences = b_addon_iter->preferences().ptr;
- break;
- }
- }
+ BL::Preferences::addons_iterator b_addon_iter;
+ for (b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end();
+ ++b_addon_iter) {
+ if (b_addon_iter->module() == "cycles") {
+ cpreferences = b_addon_iter->preferences().ptr;
+ break;
+ }
+ }
- /* Test if we are using GPU devices. */
- enum ComputeDevice {
- COMPUTE_DEVICE_CPU = 0,
- COMPUTE_DEVICE_CUDA = 1,
- COMPUTE_DEVICE_OPENCL = 2,
- COMPUTE_DEVICE_NUM = 3,
- };
+ /* Test if we are using GPU devices. */
+ enum ComputeDevice {
+ COMPUTE_DEVICE_CPU = 0,
+ COMPUTE_DEVICE_CUDA = 1,
+ COMPUTE_DEVICE_OPENCL = 2,
+ COMPUTE_DEVICE_NUM = 3,
+ };
- ComputeDevice compute_device = (ComputeDevice)get_enum(cpreferences,
- "compute_device_type",
- COMPUTE_DEVICE_NUM,
- COMPUTE_DEVICE_CPU);
+ ComputeDevice compute_device = (ComputeDevice)get_enum(
+ cpreferences, "compute_device_type", COMPUTE_DEVICE_NUM, COMPUTE_DEVICE_CPU);
- if(compute_device != COMPUTE_DEVICE_CPU) {
- /* Query GPU devices with matching types. */
- uint mask = DEVICE_MASK_CPU;
- if(compute_device == COMPUTE_DEVICE_CUDA) {
- mask |= DEVICE_MASK_CUDA;
- }
- else if(compute_device == COMPUTE_DEVICE_OPENCL) {
- mask |= DEVICE_MASK_OPENCL;
- }
- vector<DeviceInfo> devices = Device::available_devices(mask);
+ if (compute_device != COMPUTE_DEVICE_CPU) {
+ /* Query GPU devices with matching types. */
+ uint mask = DEVICE_MASK_CPU;
+ if (compute_device == COMPUTE_DEVICE_CUDA) {
+ mask |= DEVICE_MASK_CUDA;
+ }
+ else if (compute_device == COMPUTE_DEVICE_OPENCL) {
+ mask |= DEVICE_MASK_OPENCL;
+ }
+ vector<DeviceInfo> devices = Device::available_devices(mask);
- /* Match device preferences and available devices. */
- vector<DeviceInfo> used_devices;
- RNA_BEGIN(&cpreferences, device, "devices") {
- if(get_boolean(device, "use")) {
- string id = get_string(device, "id");
- foreach(DeviceInfo& info, devices) {
- if(info.id == id) {
- used_devices.push_back(info);
- break;
- }
- }
- }
- } RNA_END;
+ /* Match device preferences and available devices. */
+ vector<DeviceInfo> used_devices;
+ RNA_BEGIN (&cpreferences, device, "devices") {
+ if (get_boolean(device, "use")) {
+ string id = get_string(device, "id");
+ foreach (DeviceInfo &info, devices) {
+ if (info.id == id) {
+ used_devices.push_back(info);
+ break;
+ }
+ }
+ }
+ }
+ RNA_END;
- if(!used_devices.empty()) {
- int threads = blender_device_threads(b_scene);
- device = Device::get_multi_device(used_devices,
- threads,
- background);
- }
- /* Else keep using the CPU device that was set before. */
- }
- }
+ if (!used_devices.empty()) {
+ int threads = blender_device_threads(b_scene);
+ device = Device::get_multi_device(used_devices, threads, background);
+ }
+ /* Else keep using the CPU device that was set before. */
+ }
+ }
- return device;
+ return device;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_device.h b/intern/cycles/blender/blender_device.h
index 061020936e2..fd6c045c966 100644
--- a/intern/cycles/blender/blender_device.h
+++ b/intern/cycles/blender/blender_device.h
@@ -27,11 +27,13 @@
CCL_NAMESPACE_BEGIN
/* Get number of threads to use for rendering. */
-int blender_device_threads(BL::Scene& b_scene);
+int blender_device_threads(BL::Scene &b_scene);
/* Convert Blender settings to device specification. */
-DeviceInfo blender_device_info(BL::Preferences& b_preferences, BL::Scene& b_scene, bool background);
+DeviceInfo blender_device_info(BL::Preferences &b_preferences,
+ BL::Scene &b_scene,
+ bool background);
CCL_NAMESPACE_END
-#endif /* __BLENDER_DEVICE_H__ */
+#endif /* __BLENDER_DEVICE_H__ */
diff --git a/intern/cycles/blender/blender_logging.cpp b/intern/cycles/blender/blender_logging.cpp
index 3fca4efd097..b42a1f47821 100644
--- a/intern/cycles/blender/blender_logging.cpp
+++ b/intern/cycles/blender/blender_logging.cpp
@@ -19,15 +19,15 @@
void CCL_init_logging(const char *argv0)
{
- ccl::util_logging_init(argv0);
+ ccl::util_logging_init(argv0);
}
void CCL_start_debug_logging()
{
- ccl::util_logging_start();
+ ccl::util_logging_start();
}
void CCL_logging_verbosity_set(int verbosity)
{
- ccl::util_logging_verbosity_set(verbosity);
+ ccl::util_logging_verbosity_set(verbosity);
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9b2c2c8e5d5..de594f4fb6c 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -38,1241 +38,1174 @@ CCL_NAMESPACE_BEGIN
/* Tangent Space */
struct MikkUserData {
- MikkUserData(const BL::Mesh& b_mesh,
- const char *layer_name,
- const Mesh *mesh,
- float3 *tangent,
- float *tangent_sign)
- : mesh(mesh),
- texface(NULL),
- orco(NULL),
- tangent(tangent),
- tangent_sign(tangent_sign)
- {
- const AttributeSet& attributes = (mesh->subd_faces.size()) ?
- mesh->subd_attributes : mesh->attributes;
-
- Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
- vertex_normal = attr_vN->data_float3();
-
- if(layer_name == NULL) {
- Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED);
-
- if(attr_orco) {
- orco = attr_orco->data_float3();
- mesh_texture_space(*(BL::Mesh*)&b_mesh, orco_loc, orco_size);
- }
- }
- else {
- Attribute *attr_uv = attributes.find(ustring(layer_name));
- if(attr_uv != NULL) {
- texface = attr_uv->data_float2();
- }
- }
- }
-
- const Mesh *mesh;
- int num_faces;
-
- float3 *vertex_normal;
- float2 *texface;
- float3 *orco;
- float3 orco_loc, orco_size;
-
- float3 *tangent;
- float *tangent_sign;
+ MikkUserData(const BL::Mesh &b_mesh,
+ const char *layer_name,
+ const Mesh *mesh,
+ float3 *tangent,
+ float *tangent_sign)
+ : mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign)
+ {
+ const AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes :
+ mesh->attributes;
+
+ Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
+ vertex_normal = attr_vN->data_float3();
+
+ if (layer_name == NULL) {
+ Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED);
+
+ if (attr_orco) {
+ orco = attr_orco->data_float3();
+ mesh_texture_space(*(BL::Mesh *)&b_mesh, orco_loc, orco_size);
+ }
+ }
+ else {
+ Attribute *attr_uv = attributes.find(ustring(layer_name));
+ if (attr_uv != NULL) {
+ texface = attr_uv->data_float2();
+ }
+ }
+ }
+
+ const Mesh *mesh;
+ int num_faces;
+
+ float3 *vertex_normal;
+ float2 *texface;
+ float3 *orco;
+ float3 orco_loc, orco_size;
+
+ float3 *tangent;
+ float *tangent_sign;
};
static int mikk_get_num_faces(const SMikkTSpaceContext *context)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- if(userdata->mesh->subd_faces.size()) {
- return userdata->mesh->subd_faces.size();
- }
- else {
- return userdata->mesh->num_triangles();
- }
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ if (userdata->mesh->subd_faces.size()) {
+ return userdata->mesh->subd_faces.size();
+ }
+ else {
+ return userdata->mesh->num_triangles();
+ }
}
-static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context,
- const int face_num)
+static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- if(userdata->mesh->subd_faces.size()) {
- const Mesh *mesh = userdata->mesh;
- return mesh->subd_faces[face_num].num_corners;
- }
- else {
- return 3;
- }
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ if (userdata->mesh->subd_faces.size()) {
+ const Mesh *mesh = userdata->mesh;
+ return mesh->subd_faces[face_num].num_corners;
+ }
+ else {
+ return 3;
+ }
}
static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num)
{
- if(mesh->subd_faces.size()) {
- const Mesh::SubdFace& face = mesh->subd_faces[face_num];
- return mesh->subd_face_corners[face.start_corner + vert_num];
- }
- else {
- return mesh->triangles[face_num * 3 + vert_num];
- }
+ if (mesh->subd_faces.size()) {
+ const Mesh::SubdFace &face = mesh->subd_faces[face_num];
+ return mesh->subd_face_corners[face.start_corner + vert_num];
+ }
+ else {
+ return mesh->triangles[face_num * 3 + vert_num];
+ }
}
static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num)
{
- if(mesh->subd_faces.size()) {
- const Mesh::SubdFace& face = mesh->subd_faces[face_num];
- return face.start_corner + vert_num;
- }
- else {
- return face_num * 3 + vert_num;
- }
+ if (mesh->subd_faces.size()) {
+ const Mesh::SubdFace &face = mesh->subd_faces[face_num];
+ return face.start_corner + vert_num;
+ }
+ else {
+ return face_num * 3 + vert_num;
+ }
}
static void mikk_get_position(const SMikkTSpaceContext *context,
float P[3],
- const int face_num, const int vert_num)
+ const int face_num,
+ const int vert_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- const float3 vP = mesh->verts[vertex_index];
- P[0] = vP.x;
- P[1] = vP.y;
- P[2] = vP.z;
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ const float3 vP = mesh->verts[vertex_index];
+ P[0] = vP.x;
+ P[1] = vP.y;
+ P[2] = vP.z;
}
static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
float uv[2],
- const int face_num, const int vert_num)
+ const int face_num,
+ const int vert_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- if(userdata->texface != NULL) {
- const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
- float2 tfuv = userdata->texface[corner_index];
- uv[0] = tfuv.x;
- uv[1] = tfuv.y;
- }
- else if(userdata->orco != NULL) {
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- const float3 orco_loc = userdata->orco_loc;
- const float3 orco_size = userdata->orco_size;
- const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
-
- const float2 tmp = map_to_sphere(orco);
- uv[0] = tmp.x;
- uv[1] = tmp.y;
- }
- else {
- uv[0] = 0.0f;
- uv[1] = 0.0f;
- }
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ if (userdata->texface != NULL) {
+ const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
+ float2 tfuv = userdata->texface[corner_index];
+ uv[0] = tfuv.x;
+ uv[1] = tfuv.y;
+ }
+ else if (userdata->orco != NULL) {
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ const float3 orco_loc = userdata->orco_loc;
+ const float3 orco_size = userdata->orco_size;
+ const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
+
+ const float2 tmp = map_to_sphere(orco);
+ uv[0] = tmp.x;
+ uv[1] = tmp.y;
+ }
+ else {
+ uv[0] = 0.0f;
+ uv[1] = 0.0f;
+ }
}
-static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3],
- const int face_num, const int vert_num)
+static void mikk_get_normal(const SMikkTSpaceContext *context,
+ float N[3],
+ const int face_num,
+ const int vert_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- float3 vN;
- if(mesh->subd_faces.size()) {
- const Mesh::SubdFace& face = mesh->subd_faces[face_num];
- if(face.smooth) {
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- vN = userdata->vertex_normal[vertex_index];
- }
- else {
- vN = face.normal(mesh);
- }
- }
- else {
- if(mesh->smooth[face_num]) {
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- vN = userdata->vertex_normal[vertex_index];
- }
- else {
- const Mesh::Triangle tri = mesh->get_triangle(face_num);
- vN = tri.compute_normal(&mesh->verts[0]);
- }
- }
- N[0] = vN.x;
- N[1] = vN.y;
- N[2] = vN.z;
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ float3 vN;
+ if (mesh->subd_faces.size()) {
+ const Mesh::SubdFace &face = mesh->subd_faces[face_num];
+ if (face.smooth) {
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ vN = userdata->vertex_normal[vertex_index];
+ }
+ else {
+ vN = face.normal(mesh);
+ }
+ }
+ else {
+ if (mesh->smooth[face_num]) {
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ vN = userdata->vertex_normal[vertex_index];
+ }
+ else {
+ const Mesh::Triangle tri = mesh->get_triangle(face_num);
+ vN = tri.compute_normal(&mesh->verts[0]);
+ }
+ }
+ N[0] = vN.x;
+ N[1] = vN.y;
+ N[2] = vN.z;
}
static void mikk_set_tangent_space(const SMikkTSpaceContext *context,
const float T[],
const float sign,
- const int face_num, const int vert_num)
+ const int face_num,
+ const int vert_num)
{
- MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
- userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
- if(userdata->tangent_sign != NULL) {
- userdata->tangent_sign[corner_index] = sign;
- }
+ MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
+ userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
+ if (userdata->tangent_sign != NULL) {
+ userdata->tangent_sign[corner_index] = sign;
+ }
}
-static void mikk_compute_tangents(const BL::Mesh& b_mesh,
- const char *layer_name,
- Mesh *mesh,
- bool need_sign,
- bool active_render)
+static void mikk_compute_tangents(
+ const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render)
{
- /* Create tangent attributes. */
- AttributeSet& attributes = (mesh->subd_faces.size()) ?
- mesh->subd_attributes : mesh->attributes;
- Attribute *attr;
- ustring name;
- if(layer_name != NULL) {
- name = ustring((string(layer_name) + ".tangent").c_str());
- }
- else {
- name = ustring("orco.tangent");
- }
- if(active_render) {
- attr = attributes.add(ATTR_STD_UV_TANGENT, name);
- }
- else {
- attr = attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
- }
- float3 *tangent = attr->data_float3();
- /* Create bitangent sign attribute. */
- float *tangent_sign = NULL;
- if(need_sign) {
- Attribute *attr_sign;
- ustring name_sign;
- if(layer_name != NULL) {
- name_sign = ustring((string(layer_name) +
- ".tangent_sign").c_str());
- }
- else {
- name_sign = ustring("orco.tangent_sign");
- }
-
- if(active_render) {
- attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
- }
- else {
- attr_sign = attributes.add(name_sign,
- TypeDesc::TypeFloat,
- ATTR_ELEMENT_CORNER);
- }
- tangent_sign = attr_sign->data_float();
- }
- /* Setup userdata. */
- MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
- /* Setup interface. */
- SMikkTSpaceInterface sm_interface;
- memset(&sm_interface, 0, sizeof(sm_interface));
- sm_interface.m_getNumFaces = mikk_get_num_faces;
- sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
- sm_interface.m_getPosition = mikk_get_position;
- sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
- sm_interface.m_getNormal = mikk_get_normal;
- sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
- /* Setup context. */
- SMikkTSpaceContext context;
- memset(&context, 0, sizeof(context));
- context.m_pUserData = &userdata;
- context.m_pInterface = &sm_interface;
- /* Compute tangents. */
- genTangSpaceDefault(&context);
+ /* Create tangent attributes. */
+ AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes : mesh->attributes;
+ Attribute *attr;
+ ustring name;
+ if (layer_name != NULL) {
+ name = ustring((string(layer_name) + ".tangent").c_str());
+ }
+ else {
+ name = ustring("orco.tangent");
+ }
+ if (active_render) {
+ attr = attributes.add(ATTR_STD_UV_TANGENT, name);
+ }
+ else {
+ attr = attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
+ }
+ float3 *tangent = attr->data_float3();
+ /* Create bitangent sign attribute. */
+ float *tangent_sign = NULL;
+ if (need_sign) {
+ Attribute *attr_sign;
+ ustring name_sign;
+ if (layer_name != NULL) {
+ name_sign = ustring((string(layer_name) + ".tangent_sign").c_str());
+ }
+ else {
+ name_sign = ustring("orco.tangent_sign");
+ }
+
+ if (active_render) {
+ attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
+ }
+ else {
+ attr_sign = attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
+ }
+ tangent_sign = attr_sign->data_float();
+ }
+ /* Setup userdata. */
+ MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
+ /* Setup interface. */
+ SMikkTSpaceInterface sm_interface;
+ memset(&sm_interface, 0, sizeof(sm_interface));
+ sm_interface.m_getNumFaces = mikk_get_num_faces;
+ sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
+ sm_interface.m_getPosition = mikk_get_position;
+ sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
+ sm_interface.m_getNormal = mikk_get_normal;
+ sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
+ /* Setup context. */
+ SMikkTSpaceContext context;
+ memset(&context, 0, sizeof(context));
+ context.m_pUserData = &userdata;
+ context.m_pInterface = &sm_interface;
+ /* Compute tangents. */
+ genTangSpaceDefault(&context);
}
/* Create Volume Attribute */
-static void create_mesh_volume_attribute(BL::Object& b_ob,
- Mesh *mesh,
- ImageManager *image_manager,
- AttributeStandard std,
- float frame)
+static void create_mesh_volume_attribute(
+ BL::Object &b_ob, Mesh *mesh, ImageManager *image_manager, AttributeStandard std, float frame)
{
- BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
-
- if(!b_domain)
- return;
-
- mesh->volume_isovalue = b_domain.clipping();
-
- Attribute *attr = mesh->attributes.add(std);
- VoxelAttribute *volume_data = attr->data_voxel();
- ImageMetaData metadata;
- bool animated = false;
- bool use_alpha = true;
-
- volume_data->manager = image_manager;
- volume_data->slot = image_manager->add_image(
- Attribute::standard_name(std),
- b_ob.ptr.data,
- animated,
- frame,
- INTERPOLATION_LINEAR,
- EXTENSION_CLIP,
- use_alpha,
- metadata);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if (!b_domain)
+ return;
+
+ mesh->volume_isovalue = b_domain.clipping();
+
+ Attribute *attr = mesh->attributes.add(std);
+ VoxelAttribute *volume_data = attr->data_voxel();
+ ImageMetaData metadata;
+ bool animated = false;
+ bool use_alpha = true;
+
+ volume_data->manager = image_manager;
+ volume_data->slot = image_manager->add_image(Attribute::standard_name(std),
+ b_ob.ptr.data,
+ animated,
+ frame,
+ INTERPOLATION_LINEAR,
+ EXTENSION_CLIP,
+ use_alpha,
+ metadata);
}
-static void create_mesh_volume_attributes(Scene *scene,
- BL::Object& b_ob,
- Mesh *mesh,
- float frame)
+static void create_mesh_volume_attributes(Scene *scene, BL::Object &b_ob, Mesh *mesh, float frame)
{
- /* for smoke volume rendering */
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_DENSITY))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_DENSITY, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_COLOR))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_COLOR, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_FLAME))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_FLAME, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_HEAT))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_TEMPERATURE))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_TEMPERATURE, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame);
+ /* for smoke volume rendering */
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_DENSITY))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_DENSITY, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_COLOR))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_COLOR, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_FLAME))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_FLAME, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_HEAT))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_TEMPERATURE))
+ create_mesh_volume_attribute(
+ b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_TEMPERATURE, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY))
+ create_mesh_volume_attribute(
+ b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame);
}
/* Create vertex color attributes. */
-static void attr_create_vertex_color(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh,
- bool subdivision)
+static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
{
- if(subdivision) {
- BL::Mesh::vertex_colors_iterator l;
-
- for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
- if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
- continue;
-
- Attribute *attr = mesh->subd_attributes.add(ustring(l->name().c_str()),
- TypeDesc::TypeColor,
- ATTR_ELEMENT_CORNER_BYTE);
-
- BL::Mesh::polygons_iterator p;
- uchar4 *cdata = attr->data_uchar4();
-
- for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- int n = p->loop_total();
- for(int i = 0; i < n; i++) {
- float3 color = get_float3(l->data[p->loop_start() + i].color());
- /* Compress/encode vertex color using the sRGB curve. */
- *(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
- }
- }
- }
- }
- else {
- BL::Mesh::vertex_colors_iterator l;
- for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
- if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
- continue;
-
- Attribute *attr = mesh->attributes.add(ustring(l->name().c_str()),
- TypeDesc::TypeColor,
- ATTR_ELEMENT_CORNER_BYTE);
-
- BL::Mesh::loop_triangles_iterator t;
- uchar4 *cdata = attr->data_uchar4();
-
- for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- int3 li = get_int3(t->loops());
- float3 c1 = get_float3(l->data[li[0]].color());
- float3 c2 = get_float3(l->data[li[1]].color());
- float3 c3 = get_float3(l->data[li[2]].color());
-
- /* Compress/encode vertex color using the sRGB curve. */
- cdata[0] = color_float_to_byte(color_srgb_to_linear_v3(c1));
- cdata[1] = color_float_to_byte(color_srgb_to_linear_v3(c2));
- cdata[2] = color_float_to_byte(color_srgb_to_linear_v3(c3));
- cdata += 3;
- }
- }
- }
+ if (subdivision) {
+ BL::Mesh::vertex_colors_iterator l;
+
+ for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
+ if (!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ Attribute *attr = mesh->subd_attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+
+ BL::Mesh::polygons_iterator p;
+ uchar4 *cdata = attr->data_uchar4();
+
+ for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ int n = p->loop_total();
+ for (int i = 0; i < n; i++) {
+ float3 color = get_float3(l->data[p->loop_start() + i].color());
+ /* Compress/encode vertex color using the sRGB curve. */
+ *(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
+ }
+ }
+ }
+ }
+ else {
+ BL::Mesh::vertex_colors_iterator l;
+ for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
+ if (!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ Attribute *attr = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+
+ BL::Mesh::loop_triangles_iterator t;
+ uchar4 *cdata = attr->data_uchar4();
+
+ for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ int3 li = get_int3(t->loops());
+ float3 c1 = get_float3(l->data[li[0]].color());
+ float3 c2 = get_float3(l->data[li[1]].color());
+ float3 c3 = get_float3(l->data[li[2]].color());
+
+ /* Compress/encode vertex color using the sRGB curve. */
+ cdata[0] = color_float_to_byte(color_srgb_to_linear_v3(c1));
+ cdata[1] = color_float_to_byte(color_srgb_to_linear_v3(c2));
+ cdata[2] = color_float_to_byte(color_srgb_to_linear_v3(c3));
+ cdata += 3;
+ }
+ }
+ }
}
/* Create uv map attributes. */
-static void attr_create_uv_map(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh)
+static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
{
- if(b_mesh.uv_layers.length() != 0) {
- BL::Mesh::uv_layers_iterator l;
-
- for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
- const bool active_render = l->active_render();
- AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
- ustring uv_name = ustring(l->name().c_str());
- AttributeStandard tangent_std = (active_render)? ATTR_STD_UV_TANGENT
- : ATTR_STD_NONE;
- ustring tangent_name = ustring(
- (string(l->name().c_str()) + ".tangent").c_str());
-
- /* Denotes whether UV map was requested directly. */
- const bool need_uv = mesh->need_attribute(scene, uv_name) ||
- mesh->need_attribute(scene, uv_std);
- /* Denotes whether tangent was requested directly. */
- const bool need_tangent =
- mesh->need_attribute(scene, tangent_name) ||
- (active_render && mesh->need_attribute(scene, tangent_std));
-
- /* UV map */
- /* NOTE: We create temporary UV layer if its needed for tangent but
- * wasn't requested by other nodes in shaders.
- */
- Attribute *uv_attr = NULL;
- if(need_uv || need_tangent) {
- if(active_render) {
- uv_attr = mesh->attributes.add(uv_std, uv_name);
- }
- else {
- uv_attr = mesh->attributes.add(uv_name,
- TypeFloat2,
- ATTR_ELEMENT_CORNER);
- }
-
- BL::Mesh::loop_triangles_iterator t;
- float2 *fdata = uv_attr->data_float2();
-
- for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- int3 li = get_int3(t->loops());
- fdata[0] = get_float2(l->data[li[0]].uv());
- fdata[1] = get_float2(l->data[li[1]].uv());
- fdata[2] = get_float2(l->data[li[2]].uv());
- fdata += 3;
- }
- }
-
- /* UV tangent */
- if(need_tangent) {
- AttributeStandard sign_std =
- (active_render)? ATTR_STD_UV_TANGENT_SIGN
- : ATTR_STD_NONE;
- ustring sign_name = ustring(
- (string(l->name().c_str()) + ".tangent_sign").c_str());
- bool need_sign = (mesh->need_attribute(scene, sign_name) ||
- mesh->need_attribute(scene, sign_std));
- mikk_compute_tangents(b_mesh,
- l->name().c_str(),
- mesh,
- need_sign,
- active_render);
- }
- /* Remove temporarily created UV attribute. */
- if(!need_uv && uv_attr != NULL) {
- mesh->attributes.remove(uv_attr);
- }
- }
- }
- else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
- bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
- mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
- if(!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- mesh->attributes.remove(ATTR_STD_GENERATED);
- }
- }
+ if (b_mesh.uv_layers.length() != 0) {
+ BL::Mesh::uv_layers_iterator l;
+
+ for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
+ const bool active_render = l->active_render();
+ AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
+ ustring uv_name = ustring(l->name().c_str());
+ AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
+ ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
+
+ /* Denotes whether UV map was requested directly. */
+ const bool need_uv = mesh->need_attribute(scene, uv_name) ||
+ mesh->need_attribute(scene, uv_std);
+ /* Denotes whether tangent was requested directly. */
+ const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
+ (active_render && mesh->need_attribute(scene, tangent_std));
+
+ /* UV map */
+ /* NOTE: We create temporary UV layer if its needed for tangent but
+ * wasn't requested by other nodes in shaders.
+ */
+ Attribute *uv_attr = NULL;
+ if (need_uv || need_tangent) {
+ if (active_render) {
+ uv_attr = mesh->attributes.add(uv_std, uv_name);
+ }
+ else {
+ uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
+ }
+
+ BL::Mesh::loop_triangles_iterator t;
+ float2 *fdata = uv_attr->data_float2();
+
+ for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ int3 li = get_int3(t->loops());
+ fdata[0] = get_float2(l->data[li[0]].uv());
+ fdata[1] = get_float2(l->data[li[1]].uv());
+ fdata[2] = get_float2(l->data[li[2]].uv());
+ fdata += 3;
+ }
+ }
+
+ /* UV tangent */
+ if (need_tangent) {
+ AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
+ ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
+ bool need_sign = (mesh->need_attribute(scene, sign_name) ||
+ mesh->need_attribute(scene, sign_std));
+ mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
+ }
+ /* Remove temporarily created UV attribute. */
+ if (!need_uv && uv_attr != NULL) {
+ mesh->attributes.remove(uv_attr);
+ }
+ }
+ }
+ else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
+ bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
+ mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
+ if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ mesh->attributes.remove(ATTR_STD_GENERATED);
+ }
+ }
}
-static void attr_create_subd_uv_map(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh,
- bool subdivide_uvs)
+static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
{
- if(b_mesh.uv_layers.length() != 0) {
- BL::Mesh::uv_layers_iterator l;
- int i = 0;
-
- for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
- bool active_render = l->active_render();
- AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
- ustring uv_name = ustring(l->name().c_str());
- AttributeStandard tangent_std = (active_render)? ATTR_STD_UV_TANGENT
- : ATTR_STD_NONE;
- ustring tangent_name = ustring(
- (string(l->name().c_str()) + ".tangent").c_str());
-
- /* Denotes whether UV map was requested directly. */
- const bool need_uv = mesh->need_attribute(scene, uv_name) ||
- mesh->need_attribute(scene, uv_std);
- /* Denotes whether tangent was requested directly. */
- const bool need_tangent =
- mesh->need_attribute(scene, tangent_name) ||
- (active_render && mesh->need_attribute(scene, tangent_std));
-
- Attribute *uv_attr = NULL;
-
- /* UV map */
- if(need_uv || need_tangent) {
- if(active_render)
- uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
- else
- uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
-
- if(subdivide_uvs) {
- uv_attr->flags |= ATTR_SUBDIVIDED;
- }
-
- BL::Mesh::polygons_iterator p;
- float2 *fdata = uv_attr->data_float2();
-
- for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- int n = p->loop_total();
- for(int j = 0; j < n; j++) {
- *(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
- }
- }
- }
-
- /* UV tangent */
- if(need_tangent) {
- AttributeStandard sign_std =
- (active_render)? ATTR_STD_UV_TANGENT_SIGN
- : ATTR_STD_NONE;
- ustring sign_name = ustring(
- (string(l->name().c_str()) + ".tangent_sign").c_str());
- bool need_sign = (mesh->need_attribute(scene, sign_name) ||
- mesh->need_attribute(scene, sign_std));
- mikk_compute_tangents(b_mesh,
- l->name().c_str(),
- mesh,
- need_sign,
- active_render);
- }
- /* Remove temporarily created UV attribute. */
- if(!need_uv && uv_attr != NULL) {
- mesh->subd_attributes.remove(uv_attr);
- }
- }
- }
- else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
- bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
- mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
- if(!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- mesh->subd_attributes.remove(ATTR_STD_GENERATED);
- }
- }
+ if (b_mesh.uv_layers.length() != 0) {
+ BL::Mesh::uv_layers_iterator l;
+ int i = 0;
+
+ for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
+ bool active_render = l->active_render();
+ AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
+ ustring uv_name = ustring(l->name().c_str());
+ AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
+ ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
+
+ /* Denotes whether UV map was requested directly. */
+ const bool need_uv = mesh->need_attribute(scene, uv_name) ||
+ mesh->need_attribute(scene, uv_std);
+ /* Denotes whether tangent was requested directly. */
+ const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
+ (active_render && mesh->need_attribute(scene, tangent_std));
+
+ Attribute *uv_attr = NULL;
+
+ /* UV map */
+ if (need_uv || need_tangent) {
+ if (active_render)
+ uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
+ else
+ uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
+
+ if (subdivide_uvs) {
+ uv_attr->flags |= ATTR_SUBDIVIDED;
+ }
+
+ BL::Mesh::polygons_iterator p;
+ float2 *fdata = uv_attr->data_float2();
+
+ for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ int n = p->loop_total();
+ for (int j = 0; j < n; j++) {
+ *(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
+ }
+ }
+ }
+
+ /* UV tangent */
+ if (need_tangent) {
+ AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
+ ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
+ bool need_sign = (mesh->need_attribute(scene, sign_name) ||
+ mesh->need_attribute(scene, sign_std));
+ mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
+ }
+ /* Remove temporarily created UV attribute. */
+ if (!need_uv && uv_attr != NULL) {
+ mesh->subd_attributes.remove(uv_attr);
+ }
+ }
+ }
+ else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
+ bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
+ mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
+ if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ mesh->subd_attributes.remove(ATTR_STD_GENERATED);
+ }
+ }
}
/* Create vertex pointiness attributes. */
/* Compare vertices by sum of their coordinates. */
class VertexAverageComparator {
-public:
- VertexAverageComparator(const array<float3>& verts)
- : verts_(verts) {
- }
-
- bool operator()(const int& vert_idx_a, const int& vert_idx_b)
- {
- const float3 &vert_a = verts_[vert_idx_a];
- const float3 &vert_b = verts_[vert_idx_b];
- if(vert_a == vert_b) {
- /* Special case for doubles, so we ensure ordering. */
- return vert_idx_a > vert_idx_b;
- }
- const float x1 = vert_a.x + vert_a.y + vert_a.z;
- const float x2 = vert_b.x + vert_b.y + vert_b.z;
- return x1 < x2;
- }
-
-protected:
- const array<float3>& verts_;
+ public:
+ VertexAverageComparator(const array<float3> &verts) : verts_(verts)
+ {
+ }
+
+ bool operator()(const int &vert_idx_a, const int &vert_idx_b)
+ {
+ const float3 &vert_a = verts_[vert_idx_a];
+ const float3 &vert_b = verts_[vert_idx_b];
+ if (vert_a == vert_b) {
+ /* Special case for doubles, so we ensure ordering. */
+ return vert_idx_a > vert_idx_b;
+ }
+ const float x1 = vert_a.x + vert_a.y + vert_a.z;
+ const float x2 = vert_b.x + vert_b.y + vert_b.z;
+ return x1 < x2;
+ }
+
+ protected:
+ const array<float3> &verts_;
};
-static void attr_create_pointiness(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh,
- bool subdivision)
+static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
{
- if(!mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
- return;
- }
- const int num_verts = b_mesh.vertices.length();
- if(num_verts == 0) {
- return;
- }
- /* STEP 1: Find out duplicated vertices and point duplicates to a single
- * original vertex.
- */
- vector<int> sorted_vert_indeices(num_verts);
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- sorted_vert_indeices[vert_index] = vert_index;
- }
- VertexAverageComparator compare(mesh->verts);
- sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
- /* This array stores index of the original vertex for the given vertex
- * index.
- */
- vector<int> vert_orig_index(num_verts);
- for(int sorted_vert_index = 0;
- sorted_vert_index < num_verts;
- ++sorted_vert_index)
- {
- const int vert_index = sorted_vert_indeices[sorted_vert_index];
- const float3 &vert_co = mesh->verts[vert_index];
- bool found = false;
- for(int other_sorted_vert_index = sorted_vert_index + 1;
- other_sorted_vert_index < num_verts;
- ++other_sorted_vert_index)
- {
- const int other_vert_index =
- sorted_vert_indeices[other_sorted_vert_index];
- const float3 &other_vert_co = mesh->verts[other_vert_index];
- /* We are too far away now, we wouldn't have duplicate. */
- if((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
- (vert_co.x + vert_co.y + vert_co.z) > 3 * FLT_EPSILON)
- {
- break;
- }
- /* Found duplicate. */
- if(len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
- found = true;
- vert_orig_index[vert_index] = other_vert_index;
- break;
- }
- }
- if(!found) {
- vert_orig_index[vert_index] = vert_index;
- }
- }
- /* Make sure we always points to the very first orig vertex. */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- int orig_index = vert_orig_index[vert_index];
- while(orig_index != vert_orig_index[orig_index]) {
- orig_index = vert_orig_index[orig_index];
- }
- vert_orig_index[vert_index] = orig_index;
- }
- sorted_vert_indeices.free_memory();
- /* STEP 2: Calculate vertex normals taking into account their possible
- * duplicates which gets "welded" together.
- */
- vector<float3> vert_normal(num_verts, make_float3(0.0f, 0.0f, 0.0f));
- /* First we accumulate all vertex normals in the original index. */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
- const int orig_index = vert_orig_index[vert_index];
- vert_normal[orig_index] += normal;
- }
- /* Then we normalize the accumulated result and flush it to all duplicates
- * as well.
- */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const int orig_index = vert_orig_index[vert_index];
- vert_normal[vert_index] = normalize(vert_normal[orig_index]);
- }
- /* STEP 3: Calculate pointiness using single ring neighborhood. */
- vector<int> counter(num_verts, 0);
- vector<float> raw_data(num_verts, 0.0f);
- vector<float3> edge_accum(num_verts, make_float3(0.0f, 0.0f, 0.0f));
- BL::Mesh::edges_iterator e;
- EdgeMap visited_edges;
- int edge_index = 0;
- memset(&counter[0], 0, sizeof(int) * counter.size());
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
- const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
- v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
- if(visited_edges.exists(v0, v1)) {
- continue;
- }
- visited_edges.insert(v0, v1);
- float3 co0 = get_float3(b_mesh.vertices[v0].co()),
- co1 = get_float3(b_mesh.vertices[v1].co());
- float3 edge = normalize(co1 - co0);
- edge_accum[v0] += edge;
- edge_accum[v1] += -edge;
- ++counter[v0];
- ++counter[v1];
- }
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const int orig_index = vert_orig_index[vert_index];
- if(orig_index != vert_index) {
- /* Skip duplicates, they'll be overwritten later on. */
- continue;
- }
- if(counter[vert_index] > 0) {
- const float3 normal = vert_normal[vert_index];
- const float angle =
- safe_acosf(dot(normal,
- edge_accum[vert_index] / counter[vert_index]));
- raw_data[vert_index] = angle * M_1_PI_F;
- }
- else {
- raw_data[vert_index] = 0.0f;
- }
- }
- /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
- AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
- Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
- float *data = attr->data_float();
- memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
- memset(&counter[0], 0, sizeof(int) * counter.size());
- edge_index = 0;
- visited_edges.clear();
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
- const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
- v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
- if(visited_edges.exists(v0, v1)) {
- continue;
- }
- visited_edges.insert(v0, v1);
- data[v0] += raw_data[v1];
- data[v1] += raw_data[v0];
- ++counter[v0];
- ++counter[v1];
- }
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- data[vert_index] /= counter[vert_index] + 1;
- }
- /* STEP 4: Copy attribute to the duplicated vertices. */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const int orig_index = vert_orig_index[vert_index];
- data[vert_index] = data[orig_index];
- }
+ if (!mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
+ return;
+ }
+ const int num_verts = b_mesh.vertices.length();
+ if (num_verts == 0) {
+ return;
+ }
+ /* STEP 1: Find out duplicated vertices and point duplicates to a single
+ * original vertex.
+ */
+ vector<int> sorted_vert_indeices(num_verts);
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ sorted_vert_indeices[vert_index] = vert_index;
+ }
+ VertexAverageComparator compare(mesh->verts);
+ sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
+ /* This array stores index of the original vertex for the given vertex
+ * index.
+ */
+ vector<int> vert_orig_index(num_verts);
+ for (int sorted_vert_index = 0; sorted_vert_index < num_verts; ++sorted_vert_index) {
+ const int vert_index = sorted_vert_indeices[sorted_vert_index];
+ const float3 &vert_co = mesh->verts[vert_index];
+ bool found = false;
+ for (int other_sorted_vert_index = sorted_vert_index + 1; other_sorted_vert_index < num_verts;
+ ++other_sorted_vert_index) {
+ const int other_vert_index = sorted_vert_indeices[other_sorted_vert_index];
+ const float3 &other_vert_co = mesh->verts[other_vert_index];
+ /* We are too far away now, we wouldn't have duplicate. */
+ if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
+ (vert_co.x + vert_co.y + vert_co.z) >
+ 3 * FLT_EPSILON) {
+ break;
+ }
+ /* Found duplicate. */
+ if (len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
+ found = true;
+ vert_orig_index[vert_index] = other_vert_index;
+ break;
+ }
+ }
+ if (!found) {
+ vert_orig_index[vert_index] = vert_index;
+ }
+ }
+ /* Make sure we always points to the very first orig vertex. */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ int orig_index = vert_orig_index[vert_index];
+ while (orig_index != vert_orig_index[orig_index]) {
+ orig_index = vert_orig_index[orig_index];
+ }
+ vert_orig_index[vert_index] = orig_index;
+ }
+ sorted_vert_indeices.free_memory();
+ /* STEP 2: Calculate vertex normals taking into account their possible
+ * duplicates which gets "welded" together.
+ */
+ vector<float3> vert_normal(num_verts, make_float3(0.0f, 0.0f, 0.0f));
+ /* First we accumulate all vertex normals in the original index. */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
+ const int orig_index = vert_orig_index[vert_index];
+ vert_normal[orig_index] += normal;
+ }
+ /* Then we normalize the accumulated result and flush it to all duplicates
+ * as well.
+ */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ vert_normal[vert_index] = normalize(vert_normal[orig_index]);
+ }
+ /* STEP 3: Calculate pointiness using single ring neighborhood. */
+ vector<int> counter(num_verts, 0);
+ vector<float> raw_data(num_verts, 0.0f);
+ vector<float3> edge_accum(num_verts, make_float3(0.0f, 0.0f, 0.0f));
+ BL::Mesh::edges_iterator e;
+ EdgeMap visited_edges;
+ int edge_index = 0;
+ memset(&counter[0], 0, sizeof(int) * counter.size());
+ for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
+ const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
+ v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
+ if (visited_edges.exists(v0, v1)) {
+ continue;
+ }
+ visited_edges.insert(v0, v1);
+ float3 co0 = get_float3(b_mesh.vertices[v0].co()), co1 = get_float3(b_mesh.vertices[v1].co());
+ float3 edge = normalize(co1 - co0);
+ edge_accum[v0] += edge;
+ edge_accum[v1] += -edge;
+ ++counter[v0];
+ ++counter[v1];
+ }
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ if (orig_index != vert_index) {
+ /* Skip duplicates, they'll be overwritten later on. */
+ continue;
+ }
+ if (counter[vert_index] > 0) {
+ const float3 normal = vert_normal[vert_index];
+ const float angle = safe_acosf(dot(normal, edge_accum[vert_index] / counter[vert_index]));
+ raw_data[vert_index] = angle * M_1_PI_F;
+ }
+ else {
+ raw_data[vert_index] = 0.0f;
+ }
+ }
+ /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
+ AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
+ Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
+ float *data = attr->data_float();
+ memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
+ memset(&counter[0], 0, sizeof(int) * counter.size());
+ edge_index = 0;
+ visited_edges.clear();
+ for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
+ const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
+ v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
+ if (visited_edges.exists(v0, v1)) {
+ continue;
+ }
+ visited_edges.insert(v0, v1);
+ data[v0] += raw_data[v1];
+ data[v1] += raw_data[v0];
+ ++counter[v0];
+ ++counter[v1];
+ }
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ data[vert_index] /= counter[vert_index] + 1;
+ }
+ /* STEP 4: Copy attribute to the duplicated vertices. */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ data[vert_index] = data[orig_index];
+ }
}
/* Create Mesh */
static void create_mesh(Scene *scene,
Mesh *mesh,
- BL::Mesh& b_mesh,
- const vector<Shader*>& used_shaders,
+ BL::Mesh &b_mesh,
+ const vector<Shader *> &used_shaders,
bool subdivision = false,
bool subdivide_uvs = true)
{
- /* count vertices and faces */
- int numverts = b_mesh.vertices.length();
- int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
- int numtris = 0;
- int numcorners = 0;
- int numngons = 0;
- bool use_loop_normals = b_mesh.use_auto_smooth() && (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK);
-
- /* If no faces, create empty mesh. */
- if(numfaces == 0) {
- return;
- }
-
- if(!subdivision) {
- numtris = numfaces;
- }
- else {
- BL::Mesh::polygons_iterator p;
- for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- numngons += (p->loop_total() == 4)? 0: 1;
- numcorners += p->loop_total();
- }
- }
-
- /* allocate memory */
- mesh->reserve_mesh(numverts, numtris);
- mesh->reserve_subd_faces(numfaces, numngons, numcorners);
-
- /* create vertex coordinates and normals */
- BL::Mesh::vertices_iterator v;
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
- mesh->add_vertex(get_float3(v->co()));
-
- AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
- Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
- float3 *N = attr_N->data_float3();
-
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
- *N = get_float3(v->normal());
- N = attr_N->data_float3();
-
- /* create generated coordinates from undeformed coordinates */
- const bool need_default_tangent =
- (subdivision == false) &&
- (b_mesh.uv_layers.length() == 0) &&
- (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED) ||
- need_default_tangent)
- {
- Attribute *attr = attributes.add(ATTR_STD_GENERATED);
- attr->flags |= ATTR_SUBDIVIDED;
-
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
-
- float3 *generated = attr->data_float3();
- size_t i = 0;
-
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
- generated[i++] = get_float3(v->undeformed_co())*size - loc;
- }
- }
-
- /* create faces */
- if(!subdivision) {
- BL::Mesh::loop_triangles_iterator t;
-
- for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
- int3 vi = get_int3(t->vertices());
-
- int shader = clamp(p.material_index(), 0, used_shaders.size()-1);
- bool smooth = p.use_smooth() || use_loop_normals;
-
- if(use_loop_normals) {
- BL::Array<float, 9> loop_normals = t->split_normals();
- for(int i = 0; i < 3; i++) {
- N[vi[i]] = make_float3(loop_normals[i * 3],
- loop_normals[i * 3 + 1],
- loop_normals[i * 3 + 2]);
- }
- }
-
- /* Create triangles.
- *
- * NOTE: Autosmooth is already taken care about.
- */
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
- }
- }
- else {
- BL::Mesh::polygons_iterator p;
- vector<int> vi;
-
- for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- int n = p->loop_total();
- int shader = clamp(p->material_index(), 0, used_shaders.size()-1);
- bool smooth = p->use_smooth() || use_loop_normals;
-
- vi.resize(n);
- for(int i = 0; i < n; i++) {
- /* NOTE: Autosmooth is already taken care about. */
- vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
- }
-
- /* create subd faces */
- mesh->add_subd_face(&vi[0], n, shader, smooth);
- }
- }
-
- /* Create all needed attributes.
- * The calculate functions will check whether they're needed or not.
- */
- attr_create_pointiness(scene, mesh, b_mesh, subdivision);
- attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
-
- if(subdivision) {
- attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
- }
- else {
- attr_create_uv_map(scene, mesh, b_mesh);
- }
-
- /* for volume objects, create a matrix to transform from object space to
- * mesh texture space. this does not work with deformations but that can
- * probably only be done well with a volume grid mapping of coordinates */
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
- Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
- Transform *tfm = attr->data_transform();
-
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
-
- *tfm = transform_translate(-loc)*transform_scale(size);
- }
+ /* count vertices and faces */
+ int numverts = b_mesh.vertices.length();
+ int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
+ int numtris = 0;
+ int numcorners = 0;
+ int numngons = 0;
+ bool use_loop_normals = b_mesh.use_auto_smooth() &&
+ (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK);
+
+ /* If no faces, create empty mesh. */
+ if (numfaces == 0) {
+ return;
+ }
+
+ if (!subdivision) {
+ numtris = numfaces;
+ }
+ else {
+ BL::Mesh::polygons_iterator p;
+ for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ numngons += (p->loop_total() == 4) ? 0 : 1;
+ numcorners += p->loop_total();
+ }
+ }
+
+ /* allocate memory */
+ mesh->reserve_mesh(numverts, numtris);
+ mesh->reserve_subd_faces(numfaces, numngons, numcorners);
+
+ /* create vertex coordinates and normals */
+ BL::Mesh::vertices_iterator v;
+ for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
+ mesh->add_vertex(get_float3(v->co()));
+
+ AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
+ Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
+ float3 *N = attr_N->data_float3();
+
+ for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
+ *N = get_float3(v->normal());
+ N = attr_N->data_float3();
+
+ /* create generated coordinates from undeformed coordinates */
+ const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) &&
+ (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) {
+ Attribute *attr = attributes.add(ATTR_STD_GENERATED);
+ attr->flags |= ATTR_SUBDIVIDED;
+
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ float3 *generated = attr->data_float3();
+ size_t i = 0;
+
+ for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
+ generated[i++] = get_float3(v->undeformed_co()) * size - loc;
+ }
+ }
+
+ /* create faces */
+ if (!subdivision) {
+ BL::Mesh::loop_triangles_iterator t;
+
+ for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
+ int3 vi = get_int3(t->vertices());
+
+ int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
+ bool smooth = p.use_smooth() || use_loop_normals;
+
+ if (use_loop_normals) {
+ BL::Array<float, 9> loop_normals = t->split_normals();
+ for (int i = 0; i < 3; i++) {
+ N[vi[i]] = make_float3(
+ loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
+ }
+ }
+
+ /* Create triangles.
+ *
+ * NOTE: Autosmooth is already taken care about.
+ */
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
+ }
+ }
+ else {
+ BL::Mesh::polygons_iterator p;
+ vector<int> vi;
+
+ for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ int n = p->loop_total();
+ int shader = clamp(p->material_index(), 0, used_shaders.size() - 1);
+ bool smooth = p->use_smooth() || use_loop_normals;
+
+ vi.resize(n);
+ for (int i = 0; i < n; i++) {
+ /* NOTE: Autosmooth is already taken care about. */
+ vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
+ }
+
+ /* create subd faces */
+ mesh->add_subd_face(&vi[0], n, shader, smooth);
+ }
+ }
+
+ /* Create all needed attributes.
+ * The calculate functions will check whether they're needed or not.
+ */
+ attr_create_pointiness(scene, mesh, b_mesh, subdivision);
+ attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
+
+ if (subdivision) {
+ attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
+ }
+ else {
+ attr_create_uv_map(scene, mesh, b_mesh);
+ }
+
+ /* for volume objects, create a matrix to transform from object space to
+ * mesh texture space. this does not work with deformations but that can
+ * probably only be done well with a volume grid mapping of coordinates */
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
+ Transform *tfm = attr->data_transform();
+
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ *tfm = transform_translate(-loc) * transform_scale(size);
+ }
}
static void create_subd_mesh(Scene *scene,
Mesh *mesh,
- BL::Object& b_ob,
- BL::Mesh& b_mesh,
- const vector<Shader*>& used_shaders,
+ BL::Object &b_ob,
+ BL::Mesh &b_mesh,
+ const vector<Shader *> &used_shaders,
float dicing_rate,
int max_subdivisions)
{
- BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]);
- bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
+ BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]);
+ bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
- create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
+ create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
- /* export creases */
- size_t num_creases = 0;
- BL::Mesh::edges_iterator e;
+ /* export creases */
+ size_t num_creases = 0;
+ BL::Mesh::edges_iterator e;
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
- if(e->crease() != 0.0f) {
- num_creases++;
- }
- }
+ for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
+ if (e->crease() != 0.0f) {
+ num_creases++;
+ }
+ }
- mesh->subd_creases.resize(num_creases);
+ mesh->subd_creases.resize(num_creases);
- Mesh::SubdEdgeCrease* crease = mesh->subd_creases.data();
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
- if(e->crease() != 0.0f) {
- crease->v[0] = e->vertices()[0];
- crease->v[1] = e->vertices()[1];
- crease->crease = e->crease();
+ Mesh::SubdEdgeCrease *crease = mesh->subd_creases.data();
+ for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
+ if (e->crease() != 0.0f) {
+ crease->v[0] = e->vertices()[0];
+ crease->v[1] = e->vertices()[1];
+ crease->crease = e->crease();
- crease++;
- }
- }
+ crease++;
+ }
+ }
- /* set subd params */
- if(!mesh->subd_params) {
- mesh->subd_params = new SubdParams(mesh);
- }
- SubdParams& sdparams = *mesh->subd_params;
+ /* set subd params */
+ if (!mesh->subd_params) {
+ mesh->subd_params = new SubdParams(mesh);
+ }
+ SubdParams &sdparams = *mesh->subd_params;
- PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
+ PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
- sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
- sdparams.max_level = max_subdivisions;
+ sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
+ sdparams.max_level = max_subdivisions;
- sdparams.objecttoworld = get_transform(b_ob.matrix_world());
+ sdparams.objecttoworld = get_transform(b_ob.matrix_world());
}
/* Sync */
-static void sync_mesh_fluid_motion(BL::Object& b_ob, Scene *scene, Mesh *mesh)
+static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
{
- if(scene->need_motion() == Scene::MOTION_NONE)
- return;
+ if (scene->need_motion() == Scene::MOTION_NONE)
+ return;
- BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
+ BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
- if(!b_fluid_domain)
- return;
+ if (!b_fluid_domain)
+ return;
- /* If the mesh has modifiers following the fluid domain we can't export motion. */
- if(b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size())
- return;
+ /* If the mesh has modifiers following the fluid domain we can't export motion. */
+ if (b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size())
+ return;
- /* Find or add attribute */
- float3 *P = &mesh->verts[0];
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ /* Find or add attribute */
+ float3 *P = &mesh->verts[0];
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(!attr_mP) {
- attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- }
+ if (!attr_mP) {
+ attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
- /* Only export previous and next frame, we don't have any in between data. */
- float motion_times[2] = {-1.0f, 1.0f};
- for(int step = 0; step < 2; step++) {
- float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
- float3 *mP = attr_mP->data_float3() + step*mesh->verts.size();
+ /* Only export previous and next frame, we don't have any in between data. */
+ float motion_times[2] = {-1.0f, 1.0f};
+ for (int step = 0; step < 2; step++) {
+ float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
+ float3 *mP = attr_mP->data_float3() + step * mesh->verts.size();
- BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi;
- int i = 0;
+ BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi;
+ int i = 0;
- for(b_fluid_domain.fluid_mesh_vertices.begin(fvi); fvi != b_fluid_domain.fluid_mesh_vertices.end(); ++fvi, ++i) {
- mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time;
- }
- }
+ for (b_fluid_domain.fluid_mesh_vertices.begin(fvi);
+ fvi != b_fluid_domain.fluid_mesh_vertices.end();
+ ++fvi, ++i) {
+ mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time;
+ }
+ }
}
-Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
+Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph,
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
bool object_updated,
bool show_self,
bool show_particles)
{
- /* test if we can instance or if the object is modified */
- BL::ID b_ob_data = b_ob.data();
- BL::ID key = (BKE_object_is_modified(b_ob))? b_ob_instance: b_ob_data;
- BL::Material material_override = view_layer.material_override;
-
- /* find shader indices */
- vector<Shader*> used_shaders;
-
- BL::Object::material_slots_iterator slot;
- for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
- if(material_override) {
- find_shader(material_override, used_shaders, scene->default_surface);
- }
- else {
- BL::ID b_material(slot->material());
- find_shader(b_material, used_shaders, scene->default_surface);
- }
- }
-
- if(used_shaders.size() == 0) {
- if(material_override)
- find_shader(material_override, used_shaders, scene->default_surface);
- else
- used_shaders.push_back(scene->default_surface);
- }
-
- /* test if we need to sync */
- int requested_geometry_flags = Mesh::GEOMETRY_NONE;
- if(view_layer.use_surfaces) {
- requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
- }
- if(view_layer.use_hair) {
- requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
- }
- Mesh *mesh;
-
- if(!mesh_map.sync(&mesh, key)) {
- /* if transform was applied to mesh, need full update */
- if(object_updated && mesh->transform_applied);
- /* test if shaders changed, these can be object level so mesh
- * does not get tagged for recalc */
- else if(mesh->used_shaders != used_shaders);
- else if(requested_geometry_flags != mesh->geometry_flags);
- else {
- /* even if not tagged for recalc, we may need to sync anyway
- * because the shader needs different mesh attributes */
- bool attribute_recalc = false;
-
- foreach(Shader *shader, mesh->used_shaders)
- if(shader->need_update_mesh)
- attribute_recalc = true;
-
- if(!attribute_recalc)
- return mesh;
- }
- }
-
- /* ensure we only sync instanced meshes once */
- if(mesh_synced.find(mesh) != mesh_synced.end())
- return mesh;
-
- progress.set_sync_status("Synchronizing object", b_ob.name());
-
- mesh_synced.insert(mesh);
-
- /* create derived mesh */
- array<int> oldtriangles;
- array<Mesh::SubdFace> oldsubd_faces;
- array<int> oldsubd_face_corners;
- oldtriangles.steal_data(mesh->triangles);
- oldsubd_faces.steal_data(mesh->subd_faces);
- oldsubd_face_corners.steal_data(mesh->subd_face_corners);
-
- /* compares curve_keys rather than strands in order to handle quick hair
- * adjustments in dynamic BVH - other methods could probably do this better*/
- array<float3> oldcurve_keys;
- array<float> oldcurve_radius;
- oldcurve_keys.steal_data(mesh->curve_keys);
- oldcurve_radius.steal_data(mesh->curve_radius);
-
- mesh->clear();
- mesh->used_shaders = used_shaders;
- mesh->name = ustring(b_ob_data.name().c_str());
-
- if(requested_geometry_flags != Mesh::GEOMETRY_NONE) {
- /* Adaptive subdivision setup. Not for baking since that requires
- * exact mapping to the Blender mesh. */
- if(scene->bake_manager->get_baking()) {
- mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
- }
- else {
- mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental);
- }
-
- /* For some reason, meshes do not need this... */
- bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
-
- BL::Mesh b_mesh = object_to_mesh(b_data,
- b_ob,
- b_depsgraph,
- need_undeformed,
- mesh->subdivision_type);
-
- if(b_mesh) {
- /* Sync mesh itself. */
- if(view_layer.use_surfaces && show_self) {
- if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
- create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders,
- dicing_rate, max_subdivisions);
- else
- create_mesh(scene, mesh, b_mesh, used_shaders, false);
-
- create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
- }
-
- /* Sync hair curves. */
- if(view_layer.use_hair && show_particles && mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
- sync_curves(mesh, b_mesh, b_ob, false);
- }
-
- free_object_to_mesh(b_data, b_ob, b_mesh);
- }
- }
- mesh->geometry_flags = requested_geometry_flags;
-
- /* fluid motion */
- sync_mesh_fluid_motion(b_ob, scene, mesh);
-
- /* tag update */
- bool rebuild = (oldtriangles != mesh->triangles) ||
- (oldsubd_faces != mesh->subd_faces) ||
- (oldsubd_face_corners != mesh->subd_face_corners) ||
- (oldcurve_keys != mesh->curve_keys) ||
- (oldcurve_radius != mesh->curve_radius);
-
- mesh->tag_update(scene, rebuild);
-
- return mesh;
+ /* test if we can instance or if the object is modified */
+ BL::ID b_ob_data = b_ob.data();
+ BL::ID key = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
+ BL::Material material_override = view_layer.material_override;
+
+ /* find shader indices */
+ vector<Shader *> used_shaders;
+
+ BL::Object::material_slots_iterator slot;
+ for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
+ if (material_override) {
+ find_shader(material_override, used_shaders, scene->default_surface);
+ }
+ else {
+ BL::ID b_material(slot->material());
+ find_shader(b_material, used_shaders, scene->default_surface);
+ }
+ }
+
+ if (used_shaders.size() == 0) {
+ if (material_override)
+ find_shader(material_override, used_shaders, scene->default_surface);
+ else
+ used_shaders.push_back(scene->default_surface);
+ }
+
+ /* test if we need to sync */
+ int requested_geometry_flags = Mesh::GEOMETRY_NONE;
+ if (view_layer.use_surfaces) {
+ requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
+ }
+ if (view_layer.use_hair) {
+ requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
+ }
+ Mesh *mesh;
+
+ if (!mesh_map.sync(&mesh, key)) {
+ /* if transform was applied to mesh, need full update */
+ if (object_updated && mesh->transform_applied)
+ ;
+ /* test if shaders changed, these can be object level so mesh
+ * does not get tagged for recalc */
+ else if (mesh->used_shaders != used_shaders)
+ ;
+ else if (requested_geometry_flags != mesh->geometry_flags)
+ ;
+ else {
+ /* even if not tagged for recalc, we may need to sync anyway
+ * because the shader needs different mesh attributes */
+ bool attribute_recalc = false;
+
+ foreach (Shader *shader, mesh->used_shaders)
+ if (shader->need_update_mesh)
+ attribute_recalc = true;
+
+ if (!attribute_recalc)
+ return mesh;
+ }
+ }
+
+ /* ensure we only sync instanced meshes once */
+ if (mesh_synced.find(mesh) != mesh_synced.end())
+ return mesh;
+
+ progress.set_sync_status("Synchronizing object", b_ob.name());
+
+ mesh_synced.insert(mesh);
+
+ /* create derived mesh */
+ array<int> oldtriangles;
+ array<Mesh::SubdFace> oldsubd_faces;
+ array<int> oldsubd_face_corners;
+ oldtriangles.steal_data(mesh->triangles);
+ oldsubd_faces.steal_data(mesh->subd_faces);
+ oldsubd_face_corners.steal_data(mesh->subd_face_corners);
+
+ /* compares curve_keys rather than strands in order to handle quick hair
+ * adjustments in dynamic BVH - other methods could probably do this better*/
+ array<float3> oldcurve_keys;
+ array<float> oldcurve_radius;
+ oldcurve_keys.steal_data(mesh->curve_keys);
+ oldcurve_radius.steal_data(mesh->curve_radius);
+
+ mesh->clear();
+ mesh->used_shaders = used_shaders;
+ mesh->name = ustring(b_ob_data.name().c_str());
+
+ if (requested_geometry_flags != Mesh::GEOMETRY_NONE) {
+ /* Adaptive subdivision setup. Not for baking since that requires
+ * exact mapping to the Blender mesh. */
+ if (scene->bake_manager->get_baking()) {
+ mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
+ }
+ else {
+ mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental);
+ }
+
+ /* For some reason, meshes do not need this... */
+ bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
+
+ BL::Mesh b_mesh = object_to_mesh(
+ b_data, b_ob, b_depsgraph, need_undeformed, mesh->subdivision_type);
+
+ if (b_mesh) {
+ /* Sync mesh itself. */
+ if (view_layer.use_surfaces && show_self) {
+ if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
+ create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders, dicing_rate, max_subdivisions);
+ else
+ create_mesh(scene, mesh, b_mesh, used_shaders, false);
+
+ create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
+ }
+
+ /* Sync hair curves. */
+ if (view_layer.use_hair && show_particles &&
+ mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
+ sync_curves(mesh, b_mesh, b_ob, false);
+ }
+
+ free_object_to_mesh(b_data, b_ob, b_mesh);
+ }
+ }
+ mesh->geometry_flags = requested_geometry_flags;
+
+ /* fluid motion */
+ sync_mesh_fluid_motion(b_ob, scene, mesh);
+
+ /* tag update */
+ bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) ||
+ (oldsubd_face_corners != mesh->subd_face_corners) ||
+ (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius);
+
+ mesh->tag_update(scene, rebuild);
+
+ return mesh;
}
-void BlenderSync::sync_mesh_motion(BL::Depsgraph& b_depsgraph,
- BL::Object& b_ob,
+void BlenderSync::sync_mesh_motion(BL::Depsgraph &b_depsgraph,
+ BL::Object &b_ob,
Object *object,
float motion_time)
{
- /* ensure we only sync instanced meshes once */
- Mesh *mesh = object->mesh;
-
- if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
- return;
-
- mesh_motion_synced.insert(mesh);
-
- /* ensure we only motion sync meshes that also had mesh synced, to avoid
- * unnecessary work and to ensure that its attributes were clear */
- if(mesh_synced.find(mesh) == mesh_synced.end())
- return;
-
- /* Find time matching motion step required by mesh. */
- int motion_step = mesh->motion_step(motion_time);
- if(motion_step < 0) {
- return;
- }
-
- /* skip empty meshes */
- const size_t numverts = mesh->verts.size();
- const size_t numkeys = mesh->curve_keys.size();
-
- if(!numverts && !numkeys)
- return;
-
- /* skip objects without deforming modifiers. this is not totally reliable,
- * would need a more extensive check to see which objects are animated */
- BL::Mesh b_mesh(PointerRNA_NULL);
-
- /* fluid motion is exported immediate with mesh, skip here */
- BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
- if(b_fluid_domain)
- return;
-
- if(ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
- /* get derived mesh */
- b_mesh = object_to_mesh(b_data,
- b_ob,
- b_depsgraph,
- false,
- Mesh::SUBDIVISION_NONE);
- }
-
- if(!b_mesh) {
- /* if we have no motion blur on this frame, but on other frames, copy */
- if(numverts) {
- /* triangles */
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr_mP) {
- Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
- Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
- float3 *P = &mesh->verts[0];
- float3 *N = (attr_N)? attr_N->data_float3(): NULL;
-
- memcpy(attr_mP->data_float3() + motion_step*numverts, P, sizeof(float3)*numverts);
- if(attr_mN)
- memcpy(attr_mN->data_float3() + motion_step*numverts, N, sizeof(float3)*numverts);
- }
- }
-
- if(numkeys) {
- /* curves */
- Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr_mP) {
- float3 *keys = &mesh->curve_keys[0];
- memcpy(attr_mP->data_float3() + motion_step*numkeys, keys, sizeof(float3)*numkeys);
- }
- }
-
- return;
- }
-
- /* TODO(sergey): Perform preliminary check for number of verticies. */
- if(numverts) {
- /* Find attributes. */
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
- Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
- bool new_attribute = false;
- /* Add new attributes if they don't exist already. */
- if(!attr_mP) {
- attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_N)
- attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
-
- new_attribute = true;
- }
- /* Load vertex data from mesh. */
- float3 *mP = attr_mP->data_float3() + motion_step*numverts;
- float3 *mN = (attr_mN)? attr_mN->data_float3() + motion_step*numverts: NULL;
- /* NOTE: We don't copy more that existing amount of vertices to prevent
- * possible memory corruption.
- */
- BL::Mesh::vertices_iterator v;
- int i = 0;
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
- mP[i] = get_float3(v->co());
- if(mN)
- mN[i] = get_float3(v->normal());
- }
- if(new_attribute) {
- /* In case of new attribute, we verify if there really was any motion. */
- if(b_mesh.vertices.length() != numverts ||
- memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0)
- {
- /* no motion, remove attributes again */
- if(b_mesh.vertices.length() != numverts) {
- VLOG(1) << "Topology differs, disabling motion blur for object "
- << b_ob.name();
- }
- else {
- VLOG(1) << "No actual deformation motion for object "
- << b_ob.name();
- }
- mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_mN)
- mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
- }
- else if(motion_step > 0) {
- VLOG(1) << "Filling deformation motion for object " << b_ob.name();
- /* motion, fill up previous steps that we might have skipped because
- * they had no motion, but we need them anyway now */
- float3 *P = &mesh->verts[0];
- float3 *N = (attr_N)? attr_N->data_float3(): NULL;
- for(int step = 0; step < motion_step; step++) {
- memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
- if(attr_mN)
- memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
- }
- }
- }
- else {
- if(b_mesh.vertices.length() != numverts) {
- VLOG(1) << "Topology differs, discarding motion blur for object "
- << b_ob.name() << " at time " << motion_step;
- memcpy(mP, &mesh->verts[0], sizeof(float3)*numverts);
- if(mN != NULL) {
- memcpy(mN, attr_N->data_float3(), sizeof(float3)*numverts);
- }
- }
- }
- }
-
- /* hair motion */
- if(numkeys)
- sync_curves(mesh, b_mesh, b_ob, true, motion_step);
-
- /* free derived mesh */
- free_object_to_mesh(b_data, b_ob, b_mesh);
+ /* ensure we only sync instanced meshes once */
+ Mesh *mesh = object->mesh;
+
+ if (mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
+ return;
+
+ mesh_motion_synced.insert(mesh);
+
+ /* ensure we only motion sync meshes that also had mesh synced, to avoid
+ * unnecessary work and to ensure that its attributes were clear */
+ if (mesh_synced.find(mesh) == mesh_synced.end())
+ return;
+
+ /* Find time matching motion step required by mesh. */
+ int motion_step = mesh->motion_step(motion_time);
+ if (motion_step < 0) {
+ return;
+ }
+
+ /* skip empty meshes */
+ const size_t numverts = mesh->verts.size();
+ const size_t numkeys = mesh->curve_keys.size();
+
+ if (!numverts && !numkeys)
+ return;
+
+ /* skip objects without deforming modifiers. this is not totally reliable,
+ * would need a more extensive check to see which objects are animated */
+ BL::Mesh b_mesh(PointerRNA_NULL);
+
+ /* fluid motion is exported immediate with mesh, skip here */
+ BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
+ if (b_fluid_domain)
+ return;
+
+ if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
+ /* get derived mesh */
+ b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
+ }
+
+ if (!b_mesh) {
+ /* if we have no motion blur on this frame, but on other frames, copy */
+ if (numverts) {
+ /* triangles */
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr_mP) {
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+ float3 *P = &mesh->verts[0];
+ float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
+
+ memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts);
+ if (attr_mN)
+ memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts);
+ }
+ }
+
+ if (numkeys) {
+ /* curves */
+ Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr_mP) {
+ float3 *keys = &mesh->curve_keys[0];
+ memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys);
+ }
+ }
+
+ return;
+ }
+
+ /* TODO(sergey): Perform preliminary check for number of verticies. */
+ if (numverts) {
+ /* Find attributes. */
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+ bool new_attribute = false;
+ /* Add new attributes if they don't exist already. */
+ if (!attr_mP) {
+ attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_N)
+ attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ new_attribute = true;
+ }
+ /* Load vertex data from mesh. */
+ float3 *mP = attr_mP->data_float3() + motion_step * numverts;
+ float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL;
+ /* NOTE: We don't copy more that existing amount of vertices to prevent
+ * possible memory corruption.
+ */
+ BL::Mesh::vertices_iterator v;
+ int i = 0;
+ for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
+ mP[i] = get_float3(v->co());
+ if (mN)
+ mN[i] = get_float3(v->normal());
+ }
+ if (new_attribute) {
+ /* In case of new attribute, we verify if there really was any motion. */
+ if (b_mesh.vertices.length() != numverts ||
+ memcmp(mP, &mesh->verts[0], sizeof(float3) * numverts) == 0) {
+ /* no motion, remove attributes again */
+ if (b_mesh.vertices.length() != numverts) {
+ VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name();
+ }
+ else {
+ VLOG(1) << "No actual deformation motion for object " << b_ob.name();
+ }
+ mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_mN)
+ mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
+ }
+ else if (motion_step > 0) {
+ VLOG(1) << "Filling deformation motion for object " << b_ob.name();
+ /* motion, fill up previous steps that we might have skipped because
+ * they had no motion, but we need them anyway now */
+ float3 *P = &mesh->verts[0];
+ float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
+ for (int step = 0; step < motion_step; step++) {
+ memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts);
+ if (attr_mN)
+ memcpy(attr_mN->data_float3() + step * numverts, N, sizeof(float3) * numverts);
+ }
+ }
+ }
+ else {
+ if (b_mesh.vertices.length() != numverts) {
+ VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name()
+ << " at time " << motion_step;
+ memcpy(mP, &mesh->verts[0], sizeof(float3) * numverts);
+ if (mN != NULL) {
+ memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts);
+ }
+ }
+ }
+ }
+
+ /* hair motion */
+ if (numkeys)
+ sync_curves(mesh, b_mesh, b_ob, true, motion_step);
+
+ /* free derived mesh */
+ free_object_to_mesh(b_data, b_ob, b_mesh);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index a296488a14a..095ecd59985 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -37,646 +37,631 @@ CCL_NAMESPACE_BEGIN
/* Utilities */
-bool BlenderSync::BKE_object_is_modified(BL::Object& b_ob)
+bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
{
- /* test if we can instance or if the object is modified */
- if(b_ob.type() == BL::Object::type_META) {
- /* multi-user and dupli metaballs are fused, can't instance */
- return true;
- }
- else if(ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
- /* modifiers */
- return true;
- }
- else {
- /* object level material links */
- BL::Object::material_slots_iterator slot;
- for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
- if(slot->link() == BL::MaterialSlot::link_OBJECT)
- return true;
- }
-
- return false;
+ /* test if we can instance or if the object is modified */
+ if (b_ob.type() == BL::Object::type_META) {
+ /* multi-user and dupli metaballs are fused, can't instance */
+ return true;
+ }
+ else if (ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
+ /* modifiers */
+ return true;
+ }
+ else {
+ /* object level material links */
+ BL::Object::material_slots_iterator slot;
+ for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
+ if (slot->link() == BL::MaterialSlot::link_OBJECT)
+ return true;
+ }
+
+ return false;
}
-bool BlenderSync::object_is_mesh(BL::Object& b_ob)
+bool BlenderSync::object_is_mesh(BL::Object &b_ob)
{
- BL::ID b_ob_data = b_ob.data();
-
- if(!b_ob_data) {
- return false;
- }
-
- if(b_ob.type() == BL::Object::type_CURVE) {
- /* Skip exporting curves without faces, overhead can be
- * significant if there are many for path animation. */
- BL::Curve b_curve(b_ob.data());
-
- return (b_curve.bevel_object() ||
- b_curve.extrude() != 0.0f ||
- b_curve.bevel_depth() != 0.0f ||
- b_curve.dimensions() == BL::Curve::dimensions_2D ||
- b_ob.modifiers.length());
- }
- else {
- return (b_ob_data.is_a(&RNA_Mesh) ||
- b_ob_data.is_a(&RNA_Curve) ||
- b_ob_data.is_a(&RNA_MetaBall));
- }
+ BL::ID b_ob_data = b_ob.data();
+
+ if (!b_ob_data) {
+ return false;
+ }
+
+ if (b_ob.type() == BL::Object::type_CURVE) {
+ /* Skip exporting curves without faces, overhead can be
+ * significant if there are many for path animation. */
+ BL::Curve b_curve(b_ob.data());
+
+ return (b_curve.bevel_object() || b_curve.extrude() != 0.0f || b_curve.bevel_depth() != 0.0f ||
+ b_curve.dimensions() == BL::Curve::dimensions_2D || b_ob.modifiers.length());
+ }
+ else {
+ return (b_ob_data.is_a(&RNA_Mesh) || b_ob_data.is_a(&RNA_Curve) ||
+ b_ob_data.is_a(&RNA_MetaBall));
+ }
}
-bool BlenderSync::object_is_light(BL::Object& b_ob)
+bool BlenderSync::object_is_light(BL::Object &b_ob)
{
- BL::ID b_ob_data = b_ob.data();
+ BL::ID b_ob_data = b_ob.data();
- return (b_ob_data && b_ob_data.is_a(&RNA_Light));
+ return (b_ob_data && b_ob_data.is_a(&RNA_Light));
}
-static uint object_ray_visibility(BL::Object& b_ob)
+static uint object_ray_visibility(BL::Object &b_ob)
{
- PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
- uint flag = 0;
+ PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
+ uint flag = 0;
- flag |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0;
- flag |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0;
- flag |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0;
- flag |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0;
- flag |= get_boolean(cvisibility, "shadow")? PATH_RAY_SHADOW: 0;
- flag |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0;
+ flag |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0;
+ flag |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0;
+ flag |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : 0;
+ flag |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0;
+ flag |= get_boolean(cvisibility, "shadow") ? PATH_RAY_SHADOW : 0;
+ flag |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0;
- return flag;
+ return flag;
}
/* Light */
-void BlenderSync::sync_light(BL::Object& b_parent,
+void BlenderSync::sync_light(BL::Object &b_parent,
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
int random_id,
- Transform& tfm,
+ Transform &tfm,
bool *use_portal)
{
- /* test if we need to sync */
- Light *light;
- ObjectKey key(b_parent, persistent_id, b_ob_instance);
-
- if(!light_map.sync(&light, b_ob, b_parent, key)) {
- if(light->is_portal)
- *use_portal = true;
- return;
- }
-
- BL::Light b_light(b_ob.data());
-
- /* type */
- switch(b_light.type()) {
- case BL::Light::type_POINT: {
- BL::PointLight b_point_light(b_light);
- light->size = b_point_light.shadow_soft_size();
- light->type = LIGHT_POINT;
- break;
- }
- case BL::Light::type_SPOT: {
- BL::SpotLight b_spot_light(b_light);
- light->size = b_spot_light.shadow_soft_size();
- light->type = LIGHT_SPOT;
- light->spot_angle = b_spot_light.spot_size();
- light->spot_smooth = b_spot_light.spot_blend();
- break;
- }
- /* Hemi were removed from 2.8 */
- // case BL::Light::type_HEMI: {
- // light->type = LIGHT_DISTANT;
- // light->size = 0.0f;
- // break;
- // }
- case BL::Light::type_SUN: {
- BL::SunLight b_sun_light(b_light);
- light->size = b_sun_light.shadow_soft_size();
- light->type = LIGHT_DISTANT;
- break;
- }
- case BL::Light::type_AREA: {
- BL::AreaLight b_area_light(b_light);
- light->size = 1.0f;
- light->axisu = transform_get_column(&tfm, 0);
- light->axisv = transform_get_column(&tfm, 1);
- light->sizeu = b_area_light.size();
- switch(b_area_light.shape()) {
- case BL::AreaLight::shape_SQUARE:
- light->sizev = light->sizeu;
- light->round = false;
- break;
- case BL::AreaLight::shape_RECTANGLE:
- light->sizev = b_area_light.size_y();
- light->round = false;
- break;
- case BL::AreaLight::shape_DISK:
- light->sizev = light->sizeu;
- light->round = true;
- break;
- case BL::AreaLight::shape_ELLIPSE:
- light->sizev = b_area_light.size_y();
- light->round = true;
- break;
- }
- light->type = LIGHT_AREA;
- break;
- }
- }
-
- /* location and (inverted!) direction */
- light->co = transform_get_column(&tfm, 3);
- light->dir = -transform_get_column(&tfm, 2);
- light->tfm = tfm;
-
- /* shader */
- vector<Shader*> used_shaders;
- find_shader(b_light, used_shaders, scene->default_light);
- light->shader = used_shaders[0];
-
- /* shadow */
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
- light->cast_shadow = get_boolean(clight, "cast_shadow");
- light->use_mis = get_boolean(clight, "use_multiple_importance_sampling");
-
- int samples = get_int(clight, "samples");
- if(get_boolean(cscene, "use_square_samples"))
- light->samples = samples * samples;
- else
- light->samples = samples;
-
- light->max_bounces = get_int(clight, "max_bounces");
-
- if(b_ob != b_ob_instance) {
- light->random_id = random_id;
- }
- else {
- light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
- }
-
- if(light->type == LIGHT_AREA)
- light->is_portal = get_boolean(clight, "is_portal");
- else
- light->is_portal = false;
-
- if(light->is_portal)
- *use_portal = true;
-
- /* visibility */
- uint visibility = object_ray_visibility(b_ob);
- light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
- light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
- light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
- light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0;
-
- /* tag */
- light->tag_update(scene);
+ /* test if we need to sync */
+ Light *light;
+ ObjectKey key(b_parent, persistent_id, b_ob_instance);
+
+ if (!light_map.sync(&light, b_ob, b_parent, key)) {
+ if (light->is_portal)
+ *use_portal = true;
+ return;
+ }
+
+ BL::Light b_light(b_ob.data());
+
+ /* type */
+ switch (b_light.type()) {
+ case BL::Light::type_POINT: {
+ BL::PointLight b_point_light(b_light);
+ light->size = b_point_light.shadow_soft_size();
+ light->type = LIGHT_POINT;
+ break;
+ }
+ case BL::Light::type_SPOT: {
+ BL::SpotLight b_spot_light(b_light);
+ light->size = b_spot_light.shadow_soft_size();
+ light->type = LIGHT_SPOT;
+ light->spot_angle = b_spot_light.spot_size();
+ light->spot_smooth = b_spot_light.spot_blend();
+ break;
+ }
+ /* Hemi were removed from 2.8 */
+ // case BL::Light::type_HEMI: {
+ // light->type = LIGHT_DISTANT;
+ // light->size = 0.0f;
+ // break;
+ // }
+ case BL::Light::type_SUN: {
+ BL::SunLight b_sun_light(b_light);
+ light->size = b_sun_light.shadow_soft_size();
+ light->type = LIGHT_DISTANT;
+ break;
+ }
+ case BL::Light::type_AREA: {
+ BL::AreaLight b_area_light(b_light);
+ light->size = 1.0f;
+ light->axisu = transform_get_column(&tfm, 0);
+ light->axisv = transform_get_column(&tfm, 1);
+ light->sizeu = b_area_light.size();
+ switch (b_area_light.shape()) {
+ case BL::AreaLight::shape_SQUARE:
+ light->sizev = light->sizeu;
+ light->round = false;
+ break;
+ case BL::AreaLight::shape_RECTANGLE:
+ light->sizev = b_area_light.size_y();
+ light->round = false;
+ break;
+ case BL::AreaLight::shape_DISK:
+ light->sizev = light->sizeu;
+ light->round = true;
+ break;
+ case BL::AreaLight::shape_ELLIPSE:
+ light->sizev = b_area_light.size_y();
+ light->round = true;
+ break;
+ }
+ light->type = LIGHT_AREA;
+ break;
+ }
+ }
+
+ /* location and (inverted!) direction */
+ light->co = transform_get_column(&tfm, 3);
+ light->dir = -transform_get_column(&tfm, 2);
+ light->tfm = tfm;
+
+ /* shader */
+ vector<Shader *> used_shaders;
+ find_shader(b_light, used_shaders, scene->default_light);
+ light->shader = used_shaders[0];
+
+ /* shadow */
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
+ light->cast_shadow = get_boolean(clight, "cast_shadow");
+ light->use_mis = get_boolean(clight, "use_multiple_importance_sampling");
+
+ int samples = get_int(clight, "samples");
+ if (get_boolean(cscene, "use_square_samples"))
+ light->samples = samples * samples;
+ else
+ light->samples = samples;
+
+ light->max_bounces = get_int(clight, "max_bounces");
+
+ if (b_ob != b_ob_instance) {
+ light->random_id = random_id;
+ }
+ else {
+ light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
+ }
+
+ if (light->type == LIGHT_AREA)
+ light->is_portal = get_boolean(clight, "is_portal");
+ else
+ light->is_portal = false;
+
+ if (light->is_portal)
+ *use_portal = true;
+
+ /* visibility */
+ uint visibility = object_ray_visibility(b_ob);
+ light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
+ light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
+ light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
+ light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0;
+
+ /* tag */
+ light->tag_update(scene);
}
void BlenderSync::sync_background_light(bool use_portal)
{
- BL::World b_world = b_scene.world();
-
- if(b_world) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
-
- enum SamplingMethod {
- SAMPLING_NONE = 0,
- SAMPLING_AUTOMATIC,
- SAMPLING_MANUAL,
- SAMPLING_NUM
- };
- int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
- bool sample_as_light = (sampling_method != SAMPLING_NONE);
-
- if(sample_as_light || use_portal) {
- /* test if we need to sync */
- Light *light;
- ObjectKey key(b_world, 0, b_world);
-
- if(light_map.sync(&light, b_world, b_world, key) ||
- world_recalc ||
- b_world.ptr.data != world_map)
- {
- light->type = LIGHT_BACKGROUND;
- if(sampling_method == SAMPLING_MANUAL) {
- light->map_resolution = get_int(cworld, "sample_map_resolution");
- }
- else {
- light->map_resolution = 0;
- }
- light->shader = scene->default_background;
- light->use_mis = sample_as_light;
- light->max_bounces = get_int(cworld, "max_bounces");
-
- int samples = get_int(cworld, "samples");
- if(get_boolean(cscene, "use_square_samples"))
- light->samples = samples * samples;
- else
- light->samples = samples;
-
- light->tag_update(scene);
- light_map.set_recalc(b_world);
- }
- }
- }
-
- world_map = b_world.ptr.data;
- world_recalc = false;
+ BL::World b_world = b_scene.world();
+
+ if (b_world) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
+
+ enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM };
+ int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
+ bool sample_as_light = (sampling_method != SAMPLING_NONE);
+
+ if (sample_as_light || use_portal) {
+ /* test if we need to sync */
+ Light *light;
+ ObjectKey key(b_world, 0, b_world);
+
+ if (light_map.sync(&light, b_world, b_world, key) || world_recalc ||
+ b_world.ptr.data != world_map) {
+ light->type = LIGHT_BACKGROUND;
+ if (sampling_method == SAMPLING_MANUAL) {
+ light->map_resolution = get_int(cworld, "sample_map_resolution");
+ }
+ else {
+ light->map_resolution = 0;
+ }
+ light->shader = scene->default_background;
+ light->use_mis = sample_as_light;
+ light->max_bounces = get_int(cworld, "max_bounces");
+
+ int samples = get_int(cworld, "samples");
+ if (get_boolean(cscene, "use_square_samples"))
+ light->samples = samples * samples;
+ else
+ light->samples = samples;
+
+ light->tag_update(scene);
+ light_map.set_recalc(b_world);
+ }
+ }
+ }
+
+ world_map = b_world.ptr.data;
+ world_recalc = false;
}
/* Object */
-Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
- BL::ViewLayer& b_view_layer,
- BL::DepsgraphObjectInstance& b_instance,
+Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
+ BL::ViewLayer &b_view_layer,
+ BL::DepsgraphObjectInstance &b_instance,
float motion_time,
bool show_self,
bool show_particles,
- BlenderObjectCulling& culling,
+ BlenderObjectCulling &culling,
bool *use_portal)
{
- const bool is_instance = b_instance.is_instance();
- BL::Object b_ob = b_instance.object();
- BL::Object b_parent = is_instance ? b_instance.parent()
- : b_instance.object();
- BL::Object b_ob_instance = is_instance ? b_instance.instance_object()
- : b_ob;
- const bool motion = motion_time != 0.0f;
- /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
- int *persistent_id = NULL;
- BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
- if(is_instance) {
- persistent_id_array = b_instance.persistent_id();
- persistent_id = persistent_id_array.data;
- }
-
- /* light is handled separately */
- if(!motion && object_is_light(b_ob)) {
- /* TODO: don't use lights for excluded layers used as mask layer,
- * when dynamic overrides are back. */
+ const bool is_instance = b_instance.is_instance();
+ BL::Object b_ob = b_instance.object();
+ BL::Object b_parent = is_instance ? b_instance.parent() : b_instance.object();
+ BL::Object b_ob_instance = is_instance ? b_instance.instance_object() : b_ob;
+ const bool motion = motion_time != 0.0f;
+ /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
+ int *persistent_id = NULL;
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
+ if (is_instance) {
+ persistent_id_array = b_instance.persistent_id();
+ persistent_id = persistent_id_array.data;
+ }
+
+ /* light is handled separately */
+ if (!motion && object_is_light(b_ob)) {
+ /* TODO: don't use lights for excluded layers used as mask layer,
+ * when dynamic overrides are back. */
#if 0
- if(!((layer_flag & view_layer.holdout_layer) &&
- (layer_flag & view_layer.exclude_layer)))
+ if(!((layer_flag & view_layer.holdout_layer) &&
+ (layer_flag & view_layer.exclude_layer)))
#endif
- {
- sync_light(b_parent,
- persistent_id,
- b_ob,
- b_ob_instance,
- is_instance ? b_instance.random_id() : 0,
- tfm,
- use_portal);
- }
-
- return NULL;
- }
-
- /* only interested in object that we can create meshes from */
- if(!object_is_mesh(b_ob)) {
- return NULL;
- }
-
- /* Perform object culling. */
- if(culling.test(scene, b_ob, tfm)) {
- return NULL;
- }
-
- /* Visibility flags for both parent and child. */
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_holdout = get_boolean(cobject, "is_holdout") ||
- b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
- uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
-
- if(b_parent.ptr.data != b_ob.ptr.data) {
- visibility &= object_ray_visibility(b_parent);
- }
-
- /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
+ {
+ sync_light(b_parent,
+ persistent_id,
+ b_ob,
+ b_ob_instance,
+ is_instance ? b_instance.random_id() : 0,
+ tfm,
+ use_portal);
+ }
+
+ return NULL;
+ }
+
+ /* only interested in object that we can create meshes from */
+ if (!object_is_mesh(b_ob)) {
+ return NULL;
+ }
+
+ /* Perform object culling. */
+ if (culling.test(scene, b_ob, tfm)) {
+ return NULL;
+ }
+
+ /* Visibility flags for both parent and child. */
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_holdout = get_boolean(cobject, "is_holdout") ||
+ b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
+ uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
+
+ if (b_parent.ptr.data != b_ob.ptr.data) {
+ visibility &= object_ray_visibility(b_parent);
+ }
+
+ /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
#if 0
- if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
- visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
- }
+ if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
+ visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
+ }
#endif
- /* Clear camera visibility for indirect only objects. */
- bool use_indirect_only = b_parent.indirect_only_get(PointerRNA_NULL, b_view_layer);
- if(use_indirect_only) {
- visibility &= ~PATH_RAY_CAMERA;
- }
-
- /* Don't export completely invisible objects. */
- if(visibility == 0) {
- return NULL;
- }
-
- /* key to lookup object */
- ObjectKey key(b_parent, persistent_id, b_ob_instance);
- Object *object;
-
- /* motion vector case */
- if(motion) {
- object = object_map.find(key);
-
- if(object && object->use_motion()) {
- /* Set transform at matching motion time step. */
- int time_index = object->motion_step(motion_time);
- if(time_index >= 0) {
- object->motion[time_index] = tfm;
- }
-
- /* mesh deformation */
- if(object->mesh)
- sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
- }
-
- return object;
- }
-
- /* test if we need to sync */
- bool object_updated = false;
-
- if(object_map.sync(&object, b_ob, b_parent, key))
- object_updated = true;
-
- /* mesh sync */
- object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
-
- /* special case not tracked by object update flags */
-
- /* holdout */
- if(use_holdout != object->use_holdout) {
- object->use_holdout = use_holdout;
- scene->object_manager->tag_update(scene);
- object_updated = true;
- }
-
- if(visibility != object->visibility) {
- object->visibility = visibility;
- object_updated = true;
- }
-
- bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
- if(is_shadow_catcher != object->is_shadow_catcher) {
- object->is_shadow_catcher = is_shadow_catcher;
- object_updated = true;
- }
-
- /* sync the asset name for Cryptomatte */
- BL::Object parent = b_ob.parent();
- ustring parent_name;
- if(parent) {
- while(parent.parent()) {
- parent = parent.parent();
- }
- parent_name = parent.name();
- }
- else {
- parent_name = b_ob.name();
- }
- if(object->asset_name != parent_name) {
- object->asset_name = parent_name;
- object_updated = true;
- }
-
- /* object sync
- * transform comparison should not be needed, but duplis don't work perfect
- * in the depsgraph and may not signal changes, so this is a workaround */
- if(object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
- object->name = b_ob.name().c_str();
- object->pass_id = b_ob.pass_index();
- object->tfm = tfm;
- object->motion.clear();
-
- /* motion blur */
- Scene::MotionType need_motion = scene->need_motion();
- if(need_motion != Scene::MOTION_NONE && object->mesh) {
- Mesh *mesh = object->mesh;
- mesh->use_motion_blur = false;
- mesh->motion_steps = 0;
-
- uint motion_steps;
-
- if(need_motion == Scene::MOTION_BLUR) {
- motion_steps = object_motion_steps(b_parent, b_ob);
- mesh->motion_steps = motion_steps;
- if(motion_steps && object_use_deform_motion(b_parent, b_ob)) {
- mesh->use_motion_blur = true;
- }
- }
- else {
- motion_steps = 3;
- mesh->motion_steps = motion_steps;
- }
-
- object->motion.clear();
- object->motion.resize(motion_steps, transform_empty());
-
- if(motion_steps) {
- object->motion[motion_steps/2] = tfm;
-
- for(size_t step = 0; step < motion_steps; step++) {
- motion_times.insert(object->motion_time(step));
- }
- }
- }
-
- /* dupli texture coordinates and random_id */
- if(is_instance) {
- object->dupli_generated = 0.5f*get_float3(b_instance.orco()) - make_float3(0.5f, 0.5f, 0.5f);
- object->dupli_uv = get_float2(b_instance.uv());
- object->random_id = b_instance.random_id();
- }
- else {
- object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
- object->dupli_uv = make_float2(0.0f, 0.0f);
- object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0);
- }
-
- object->tag_update(scene);
- }
-
- if(is_instance) {
- /* Sync possible particle data. */
- sync_dupli_particle(b_parent, b_instance, object);
- }
-
- return object;
+ /* Clear camera visibility for indirect only objects. */
+ bool use_indirect_only = b_parent.indirect_only_get(PointerRNA_NULL, b_view_layer);
+ if (use_indirect_only) {
+ visibility &= ~PATH_RAY_CAMERA;
+ }
+
+ /* Don't export completely invisible objects. */
+ if (visibility == 0) {
+ return NULL;
+ }
+
+ /* key to lookup object */
+ ObjectKey key(b_parent, persistent_id, b_ob_instance);
+ Object *object;
+
+ /* motion vector case */
+ if (motion) {
+ object = object_map.find(key);
+
+ if (object && object->use_motion()) {
+ /* Set transform at matching motion time step. */
+ int time_index = object->motion_step(motion_time);
+ if (time_index >= 0) {
+ object->motion[time_index] = tfm;
+ }
+
+ /* mesh deformation */
+ if (object->mesh)
+ sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
+ }
+
+ return object;
+ }
+
+ /* test if we need to sync */
+ bool object_updated = false;
+
+ if (object_map.sync(&object, b_ob, b_parent, key))
+ object_updated = true;
+
+ /* mesh sync */
+ object->mesh = sync_mesh(
+ b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
+
+ /* special case not tracked by object update flags */
+
+ /* holdout */
+ if (use_holdout != object->use_holdout) {
+ object->use_holdout = use_holdout;
+ scene->object_manager->tag_update(scene);
+ object_updated = true;
+ }
+
+ if (visibility != object->visibility) {
+ object->visibility = visibility;
+ object_updated = true;
+ }
+
+ bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
+ if (is_shadow_catcher != object->is_shadow_catcher) {
+ object->is_shadow_catcher = is_shadow_catcher;
+ object_updated = true;
+ }
+
+ /* sync the asset name for Cryptomatte */
+ BL::Object parent = b_ob.parent();
+ ustring parent_name;
+ if (parent) {
+ while (parent.parent()) {
+ parent = parent.parent();
+ }
+ parent_name = parent.name();
+ }
+ else {
+ parent_name = b_ob.name();
+ }
+ if (object->asset_name != parent_name) {
+ object->asset_name = parent_name;
+ object_updated = true;
+ }
+
+ /* object sync
+ * transform comparison should not be needed, but duplis don't work perfect
+ * in the depsgraph and may not signal changes, so this is a workaround */
+ if (object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
+ object->name = b_ob.name().c_str();
+ object->pass_id = b_ob.pass_index();
+ object->tfm = tfm;
+ object->motion.clear();
+
+ /* motion blur */
+ Scene::MotionType need_motion = scene->need_motion();
+ if (need_motion != Scene::MOTION_NONE && object->mesh) {
+ Mesh *mesh = object->mesh;
+ mesh->use_motion_blur = false;
+ mesh->motion_steps = 0;
+
+ uint motion_steps;
+
+ if (need_motion == Scene::MOTION_BLUR) {
+ motion_steps = object_motion_steps(b_parent, b_ob);
+ mesh->motion_steps = motion_steps;
+ if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
+ mesh->use_motion_blur = true;
+ }
+ }
+ else {
+ motion_steps = 3;
+ mesh->motion_steps = motion_steps;
+ }
+
+ object->motion.clear();
+ object->motion.resize(motion_steps, transform_empty());
+
+ if (motion_steps) {
+ object->motion[motion_steps / 2] = tfm;
+
+ for (size_t step = 0; step < motion_steps; step++) {
+ motion_times.insert(object->motion_time(step));
+ }
+ }
+ }
+
+ /* dupli texture coordinates and random_id */
+ if (is_instance) {
+ object->dupli_generated = 0.5f * get_float3(b_instance.orco()) -
+ make_float3(0.5f, 0.5f, 0.5f);
+ object->dupli_uv = get_float2(b_instance.uv());
+ object->random_id = b_instance.random_id();
+ }
+ else {
+ object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
+ object->dupli_uv = make_float2(0.0f, 0.0f);
+ object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0);
+ }
+
+ object->tag_update(scene);
+ }
+
+ if (is_instance) {
+ /* Sync possible particle data. */
+ sync_dupli_particle(b_parent, b_instance, object);
+ }
+
+ return object;
}
/* Object Loop */
-void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
+void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, float motion_time)
{
- /* layer data */
- bool motion = motion_time != 0.0f;
-
- if(!motion) {
- /* prepare for sync */
- light_map.pre_sync();
- mesh_map.pre_sync();
- object_map.pre_sync();
- particle_system_map.pre_sync();
- motion_times.clear();
- }
- else {
- mesh_motion_synced.clear();
- }
-
- /* initialize culling */
- BlenderObjectCulling culling(scene, b_scene);
-
- /* object loop */
- bool cancel = false;
- bool use_portal = false;
-
- BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
-
- BL::Depsgraph::object_instances_iterator b_instance_iter;
- for(b_depsgraph.object_instances.begin(b_instance_iter);
- b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
- ++b_instance_iter)
- {
- BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
- BL::Object b_ob = b_instance.object();
-
- /* load per-object culling data */
- culling.init_object(scene, b_ob);
-
- /* test if object needs to be hidden */
- const bool show_self = b_instance.show_self();
- const bool show_particles = b_instance.show_particles();
-
- if(show_self || show_particles) {
- /* object itself */
- sync_object(b_depsgraph,
- b_view_layer,
- b_instance,
- motion_time,
- show_self,
- show_particles,
- culling,
- &use_portal);
- }
-
- cancel = progress.get_cancel();
- }
-
- progress.set_sync_status("");
-
- if(!cancel && !motion) {
- sync_background_light(use_portal);
-
- /* handle removed data and modified pointers */
- if(light_map.post_sync())
- scene->light_manager->tag_update(scene);
- if(mesh_map.post_sync())
- scene->mesh_manager->tag_update(scene);
- if(object_map.post_sync())
- scene->object_manager->tag_update(scene);
- if(particle_system_map.post_sync())
- scene->particle_system_manager->tag_update(scene);
- }
-
- if(motion)
- mesh_motion_synced.clear();
+ /* layer data */
+ bool motion = motion_time != 0.0f;
+
+ if (!motion) {
+ /* prepare for sync */
+ light_map.pre_sync();
+ mesh_map.pre_sync();
+ object_map.pre_sync();
+ particle_system_map.pre_sync();
+ motion_times.clear();
+ }
+ else {
+ mesh_motion_synced.clear();
+ }
+
+ /* initialize culling */
+ BlenderObjectCulling culling(scene, b_scene);
+
+ /* object loop */
+ bool cancel = false;
+ bool use_portal = false;
+
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
+ BL::Depsgraph::object_instances_iterator b_instance_iter;
+ for (b_depsgraph.object_instances.begin(b_instance_iter);
+ b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
+ ++b_instance_iter) {
+ BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
+ BL::Object b_ob = b_instance.object();
+
+ /* load per-object culling data */
+ culling.init_object(scene, b_ob);
+
+ /* test if object needs to be hidden */
+ const bool show_self = b_instance.show_self();
+ const bool show_particles = b_instance.show_particles();
+
+ if (show_self || show_particles) {
+ /* object itself */
+ sync_object(b_depsgraph,
+ b_view_layer,
+ b_instance,
+ motion_time,
+ show_self,
+ show_particles,
+ culling,
+ &use_portal);
+ }
+
+ cancel = progress.get_cancel();
+ }
+
+ progress.set_sync_status("");
+
+ if (!cancel && !motion) {
+ sync_background_light(use_portal);
+
+ /* handle removed data and modified pointers */
+ if (light_map.post_sync())
+ scene->light_manager->tag_update(scene);
+ if (mesh_map.post_sync())
+ scene->mesh_manager->tag_update(scene);
+ if (object_map.post_sync())
+ scene->object_manager->tag_update(scene);
+ if (particle_system_map.post_sync())
+ scene->particle_system_manager->tag_update(scene);
+ }
+
+ if (motion)
+ mesh_motion_synced.clear();
}
-void BlenderSync::sync_motion(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::Object& b_override,
- int width, int height,
+void BlenderSync::sync_motion(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::Object &b_override,
+ int width,
+ int height,
void **python_thread_state)
{
- if(scene->need_motion() == Scene::MOTION_NONE)
- return;
-
- /* get camera object here to deal with camera switch */
- BL::Object b_cam = b_scene.camera();
- if(b_override)
- b_cam = b_override;
-
- Camera prevcam = *(scene->camera);
-
- int frame_center = b_scene.frame_current();
- float subframe_center = b_scene.frame_subframe();
- float frame_center_delta = 0.0f;
-
- if(scene->need_motion() != Scene::MOTION_PASS &&
- scene->camera->motion_position != Camera::MOTION_POSITION_CENTER)
- {
- float shuttertime = scene->camera->shuttertime;
- if(scene->camera->motion_position == Camera::MOTION_POSITION_END) {
- frame_center_delta = -shuttertime * 0.5f;
- }
- else {
- assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
- frame_center_delta = shuttertime * 0.5f;
- }
-
- float time = frame_center + subframe_center + frame_center_delta;
- int frame = (int)floorf(time);
- float subframe = time - frame;
- python_thread_state_restore(python_thread_state);
- b_engine.frame_set(frame, subframe);
- python_thread_state_save(python_thread_state);
- sync_camera_motion(b_render, b_cam, width, height, 0.0f);
- sync_objects(b_depsgraph, 0.0f);
- }
-
- /* always sample these times for camera motion */
- motion_times.insert(-1.0f);
- motion_times.insert(1.0f);
-
- /* note iteration over motion_times set happens in sorted order */
- foreach(float relative_time, motion_times) {
- /* center time is already handled. */
- if(relative_time == 0.0f) {
- continue;
- }
-
- VLOG(1) << "Synchronizing motion for the relative time "
- << relative_time << ".";
-
- /* fixed shutter time to get previous and next frame for motion pass */
- float shuttertime = scene->motion_shutter_time();
-
- /* compute frame and subframe time */
- float time = frame_center + subframe_center + frame_center_delta + relative_time * shuttertime * 0.5f;
- int frame = (int)floorf(time);
- float subframe = time - frame;
-
- /* change frame */
- python_thread_state_restore(python_thread_state);
- b_engine.frame_set(frame, subframe);
- python_thread_state_save(python_thread_state);
-
- /* sync camera, only supports two times at the moment */
- if(relative_time == -1.0f || relative_time == 1.0f) {
- sync_camera_motion(b_render,
- b_cam,
- width, height,
- relative_time);
- }
-
- /* sync object */
- sync_objects(b_depsgraph, relative_time);
- }
-
- /* we need to set the python thread state again because this
- * function assumes it is being executed from python and will
- * try to save the thread state */
- python_thread_state_restore(python_thread_state);
- b_engine.frame_set(frame_center, subframe_center);
- python_thread_state_save(python_thread_state);
-
- /* tag camera for motion update */
- if(scene->camera->motion_modified(prevcam))
- scene->camera->tag_update();
+ if (scene->need_motion() == Scene::MOTION_NONE)
+ return;
+
+ /* get camera object here to deal with camera switch */
+ BL::Object b_cam = b_scene.camera();
+ if (b_override)
+ b_cam = b_override;
+
+ Camera prevcam = *(scene->camera);
+
+ int frame_center = b_scene.frame_current();
+ float subframe_center = b_scene.frame_subframe();
+ float frame_center_delta = 0.0f;
+
+ if (scene->need_motion() != Scene::MOTION_PASS &&
+ scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) {
+ float shuttertime = scene->camera->shuttertime;
+ if (scene->camera->motion_position == Camera::MOTION_POSITION_END) {
+ frame_center_delta = -shuttertime * 0.5f;
+ }
+ else {
+ assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
+ frame_center_delta = shuttertime * 0.5f;
+ }
+
+ float time = frame_center + subframe_center + frame_center_delta;
+ int frame = (int)floorf(time);
+ float subframe = time - frame;
+ python_thread_state_restore(python_thread_state);
+ b_engine.frame_set(frame, subframe);
+ python_thread_state_save(python_thread_state);
+ sync_camera_motion(b_render, b_cam, width, height, 0.0f);
+ sync_objects(b_depsgraph, 0.0f);
+ }
+
+ /* always sample these times for camera motion */
+ motion_times.insert(-1.0f);
+ motion_times.insert(1.0f);
+
+ /* note iteration over motion_times set happens in sorted order */
+ foreach (float relative_time, motion_times) {
+ /* center time is already handled. */
+ if (relative_time == 0.0f) {
+ continue;
+ }
+
+ VLOG(1) << "Synchronizing motion for the relative time " << relative_time << ".";
+
+ /* fixed shutter time to get previous and next frame for motion pass */
+ float shuttertime = scene->motion_shutter_time();
+
+ /* compute frame and subframe time */
+ float time = frame_center + subframe_center + frame_center_delta +
+ relative_time * shuttertime * 0.5f;
+ int frame = (int)floorf(time);
+ float subframe = time - frame;
+
+ /* change frame */
+ python_thread_state_restore(python_thread_state);
+ b_engine.frame_set(frame, subframe);
+ python_thread_state_save(python_thread_state);
+
+ /* sync camera, only supports two times at the moment */
+ if (relative_time == -1.0f || relative_time == 1.0f) {
+ sync_camera_motion(b_render, b_cam, width, height, relative_time);
+ }
+
+ /* sync object */
+ sync_objects(b_depsgraph, relative_time);
+ }
+
+ /* we need to set the python thread state again because this
+ * function assumes it is being executed from python and will
+ * try to save the thread state */
+ python_thread_state_restore(python_thread_state);
+ b_engine.frame_set(frame_center, subframe_center);
+ python_thread_state_save(python_thread_state);
+
+ /* tag camera for motion update */
+ if (scene->camera->motion_modified(prevcam))
+ scene->camera->tag_update();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object_cull.cpp b/intern/cycles/blender/blender_object_cull.cpp
index 680d9d7b1ff..74f8fb1dc53 100644
--- a/intern/cycles/blender/blender_object_cull.cpp
+++ b/intern/cycles/blender/blender_object_cull.cpp
@@ -22,72 +22,69 @@
CCL_NAMESPACE_BEGIN
-BlenderObjectCulling::BlenderObjectCulling(Scene *scene, BL::Scene& b_scene)
- : use_scene_camera_cull_(false),
- use_camera_cull_(false),
- camera_cull_margin_(0.0f),
- use_scene_distance_cull_(false),
- use_distance_cull_(false),
- distance_cull_margin_(0.0f)
+BlenderObjectCulling::BlenderObjectCulling(Scene *scene, BL::Scene &b_scene)
+ : use_scene_camera_cull_(false),
+ use_camera_cull_(false),
+ camera_cull_margin_(0.0f),
+ use_scene_distance_cull_(false),
+ use_distance_cull_(false),
+ distance_cull_margin_(0.0f)
{
- if(b_scene.render().use_simplify()) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- use_scene_camera_cull_ = scene->camera->type != CAMERA_PANORAMA &&
- !b_scene.render().use_multiview() &&
- get_boolean(cscene, "use_camera_cull");
- use_scene_distance_cull_ = scene->camera->type != CAMERA_PANORAMA &&
- !b_scene.render().use_multiview() &&
- get_boolean(cscene, "use_distance_cull");
-
- camera_cull_margin_ = get_float(cscene, "camera_cull_margin");
- distance_cull_margin_ = get_float(cscene, "distance_cull_margin");
-
- if(distance_cull_margin_ == 0.0f) {
- use_scene_distance_cull_ = false;
- }
- }
+ if (b_scene.render().use_simplify()) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ use_scene_camera_cull_ = scene->camera->type != CAMERA_PANORAMA &&
+ !b_scene.render().use_multiview() &&
+ get_boolean(cscene, "use_camera_cull");
+ use_scene_distance_cull_ = scene->camera->type != CAMERA_PANORAMA &&
+ !b_scene.render().use_multiview() &&
+ get_boolean(cscene, "use_distance_cull");
+
+ camera_cull_margin_ = get_float(cscene, "camera_cull_margin");
+ distance_cull_margin_ = get_float(cscene, "distance_cull_margin");
+
+ if (distance_cull_margin_ == 0.0f) {
+ use_scene_distance_cull_ = false;
+ }
+ }
}
-void BlenderObjectCulling::init_object(Scene *scene, BL::Object& b_ob)
+void BlenderObjectCulling::init_object(Scene *scene, BL::Object &b_ob)
{
- if(!use_scene_camera_cull_ && !use_scene_distance_cull_) {
- return;
- }
+ if (!use_scene_camera_cull_ && !use_scene_distance_cull_) {
+ return;
+ }
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- use_camera_cull_ = use_scene_camera_cull_ && get_boolean(cobject, "use_camera_cull");
- use_distance_cull_ = use_scene_distance_cull_ && get_boolean(cobject, "use_distance_cull");
+ use_camera_cull_ = use_scene_camera_cull_ && get_boolean(cobject, "use_camera_cull");
+ use_distance_cull_ = use_scene_distance_cull_ && get_boolean(cobject, "use_distance_cull");
- if(use_camera_cull_ || use_distance_cull_) {
- /* Need to have proper projection matrix. */
- scene->camera->update(scene);
- }
+ if (use_camera_cull_ || use_distance_cull_) {
+ /* Need to have proper projection matrix. */
+ scene->camera->update(scene);
+ }
}
-bool BlenderObjectCulling::test(Scene *scene, BL::Object& b_ob, Transform& tfm)
+bool BlenderObjectCulling::test(Scene *scene, BL::Object &b_ob, Transform &tfm)
{
- if(!use_camera_cull_ && !use_distance_cull_) {
- return false;
- }
-
- /* Compute world space bounding box corners. */
- float3 bb[8];
- BL::Array<float, 24> boundbox = b_ob.bound_box();
- for(int i = 0; i < 8; ++i) {
- float3 p = make_float3(boundbox[3 * i + 0],
- boundbox[3 * i + 1],
- boundbox[3 * i + 2]);
- bb[i] = transform_point(&tfm, p);
- }
-
- bool camera_culled = use_camera_cull_ && test_camera(scene, bb);
- bool distance_culled = use_distance_cull_ && test_distance(scene, bb);
-
- return ((camera_culled && distance_culled) ||
- (camera_culled && !use_distance_cull_) ||
- (distance_culled && !use_camera_cull_));
+ if (!use_camera_cull_ && !use_distance_cull_) {
+ return false;
+ }
+
+ /* Compute world space bounding box corners. */
+ float3 bb[8];
+ BL::Array<float, 24> boundbox = b_ob.bound_box();
+ for (int i = 0; i < 8; ++i) {
+ float3 p = make_float3(boundbox[3 * i + 0], boundbox[3 * i + 1], boundbox[3 * i + 2]);
+ bb[i] = transform_point(&tfm, p);
+ }
+
+ bool camera_culled = use_camera_cull_ && test_camera(scene, bb);
+ bool distance_culled = use_distance_cull_ && test_distance(scene, bb);
+
+ return ((camera_culled && distance_culled) || (camera_culled && !use_distance_cull_) ||
+ (distance_culled && !use_camera_cull_));
}
/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order
@@ -95,54 +92,50 @@ bool BlenderObjectCulling::test(Scene *scene, BL::Object& b_ob, Transform& tfm)
*/
bool BlenderObjectCulling::test_camera(Scene *scene, float3 bb[8])
{
- Camera *cam = scene->camera;
- const ProjectionTransform& worldtondc = cam->worldtondc;
- float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
- bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
- bool all_behind = true;
- for(int i = 0; i < 8; ++i) {
- float3 p = bb[i];
- float4 b = make_float4(p.x, p.y, p.z, 1.0f);
- float4 c = make_float4(dot(worldtondc.x, b),
- dot(worldtondc.y, b),
- dot(worldtondc.z, b),
- dot(worldtondc.w, b));
- p = float4_to_float3(c / c.w);
- if(c.z < 0.0f) {
- p.x = 1.0f - p.x;
- p.y = 1.0f - p.y;
- }
- if(c.z >= -camera_cull_margin_) {
- all_behind = false;
- }
- bb_min = min(bb_min, p);
- bb_max = max(bb_max, p);
- }
- if(all_behind) {
- return true;
- }
- return (bb_min.x >= 1.0f + camera_cull_margin_ ||
- bb_min.y >= 1.0f + camera_cull_margin_ ||
- bb_max.x <= -camera_cull_margin_ ||
- bb_max.y <= -camera_cull_margin_);
+ Camera *cam = scene->camera;
+ const ProjectionTransform &worldtondc = cam->worldtondc;
+ float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
+ bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+ bool all_behind = true;
+ for (int i = 0; i < 8; ++i) {
+ float3 p = bb[i];
+ float4 b = make_float4(p.x, p.y, p.z, 1.0f);
+ float4 c = make_float4(
+ dot(worldtondc.x, b), dot(worldtondc.y, b), dot(worldtondc.z, b), dot(worldtondc.w, b));
+ p = float4_to_float3(c / c.w);
+ if (c.z < 0.0f) {
+ p.x = 1.0f - p.x;
+ p.y = 1.0f - p.y;
+ }
+ if (c.z >= -camera_cull_margin_) {
+ all_behind = false;
+ }
+ bb_min = min(bb_min, p);
+ bb_max = max(bb_max, p);
+ }
+ if (all_behind) {
+ return true;
+ }
+ return (bb_min.x >= 1.0f + camera_cull_margin_ || bb_min.y >= 1.0f + camera_cull_margin_ ||
+ bb_max.x <= -camera_cull_margin_ || bb_max.y <= -camera_cull_margin_);
}
bool BlenderObjectCulling::test_distance(Scene *scene, float3 bb[8])
{
- float3 camera_position = transform_get_column(&scene->camera->matrix, 3);
- float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
- bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
-
- /* Find min & max points for x & y & z on bounding box */
- for(int i = 0; i < 8; ++i) {
- float3 p = bb[i];
- bb_min = min(bb_min, p);
- bb_max = max(bb_max, p);
- }
-
- float3 closest_point = max(min(bb_max,camera_position),bb_min);
- return (len_squared(camera_position - closest_point) >
- distance_cull_margin_ * distance_cull_margin_);
+ float3 camera_position = transform_get_column(&scene->camera->matrix, 3);
+ float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
+ bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+
+ /* Find min & max points for x & y & z on bounding box */
+ for (int i = 0; i < 8; ++i) {
+ float3 p = bb[i];
+ bb_min = min(bb_min, p);
+ bb_max = max(bb_max, p);
+ }
+
+ float3 closest_point = max(min(bb_max, camera_position), bb_min);
+ return (len_squared(camera_position - closest_point) >
+ distance_cull_margin_ * distance_cull_margin_);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object_cull.h b/intern/cycles/blender/blender_object_cull.h
index 6e2a22438ec..0879db4f802 100644
--- a/intern/cycles/blender/blender_object_cull.h
+++ b/intern/cycles/blender/blender_object_cull.h
@@ -24,26 +24,25 @@ CCL_NAMESPACE_BEGIN
class Scene;
-class BlenderObjectCulling
-{
-public:
- BlenderObjectCulling(Scene *scene, BL::Scene& b_scene);
-
- void init_object(Scene *scene, BL::Object& b_ob);
- bool test(Scene *scene, BL::Object& b_ob, Transform& tfm);
-
-private:
- bool test_camera(Scene *scene, float3 bb[8]);
- bool test_distance(Scene *scene, float3 bb[8]);
-
- bool use_scene_camera_cull_;
- bool use_camera_cull_;
- float camera_cull_margin_;
- bool use_scene_distance_cull_;
- bool use_distance_cull_;
- float distance_cull_margin_;
+class BlenderObjectCulling {
+ public:
+ BlenderObjectCulling(Scene *scene, BL::Scene &b_scene);
+
+ void init_object(Scene *scene, BL::Object &b_ob);
+ bool test(Scene *scene, BL::Object &b_ob, Transform &tfm);
+
+ private:
+ bool test_camera(Scene *scene, float3 bb[8]);
+ bool test_distance(Scene *scene, float3 bb[8]);
+
+ bool use_scene_camera_cull_;
+ bool use_camera_cull_;
+ float camera_cull_margin_;
+ bool use_scene_distance_cull_;
+ bool use_distance_cull_;
+ float distance_cull_margin_;
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_OBJECT_CULL_H__ */
+#endif /* __BLENDER_OBJECT_CULL_H__ */
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index a733a499826..d74f132ed60 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -27,66 +27,66 @@ CCL_NAMESPACE_BEGIN
/* Utilities */
-bool BlenderSync::sync_dupli_particle(BL::Object& b_ob,
- BL::DepsgraphObjectInstance& b_instance,
+bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
+ BL::DepsgraphObjectInstance &b_instance,
Object *object)
{
- /* test if this dupli was generated from a particle sytem */
- BL::ParticleSystem b_psys = b_instance.particle_system();
- if(!b_psys)
- return false;
-
- object->hide_on_missing_motion = true;
-
- /* test if we need particle data */
- if(!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE))
- return false;
-
- /* don't handle child particles yet */
- BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
-
- if(persistent_id[0] >= b_psys.particles.length())
- return false;
-
- /* find particle system */
- ParticleSystemKey key(b_ob, persistent_id);
- ParticleSystem *psys;
-
- bool first_use = !particle_system_map.is_used(key);
- bool need_update = particle_system_map.sync(&psys, b_ob, b_instance.object(), key);
-
- /* no update needed? */
- if(!need_update && !object->mesh->need_update && !scene->object_manager->need_update)
- return true;
-
- /* first time used in this sync loop? clear and tag update */
- if(first_use) {
- psys->particles.clear();
- psys->tag_update(scene);
- }
-
- /* add particle */
- BL::Particle b_pa = b_psys.particles[persistent_id[0]];
- Particle pa;
-
- pa.index = persistent_id[0];
- pa.age = b_scene.frame_current() - b_pa.birth_time();
- pa.lifetime = b_pa.lifetime();
- pa.location = get_float3(b_pa.location());
- pa.rotation = get_float4(b_pa.rotation());
- pa.size = b_pa.size();
- pa.velocity = get_float3(b_pa.velocity());
- pa.angular_velocity = get_float3(b_pa.angular_velocity());
-
- psys->particles.push_back_slow(pa);
-
- if(object->particle_index != psys->particles.size() - 1)
- scene->object_manager->tag_update(scene);
- object->particle_system = psys;
- object->particle_index = psys->particles.size() - 1;
-
- /* return that this object has particle data */
- return true;
+ /* test if this dupli was generated from a particle sytem */
+ BL::ParticleSystem b_psys = b_instance.particle_system();
+ if (!b_psys)
+ return false;
+
+ object->hide_on_missing_motion = true;
+
+ /* test if we need particle data */
+ if (!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE))
+ return false;
+
+ /* don't handle child particles yet */
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
+
+ if (persistent_id[0] >= b_psys.particles.length())
+ return false;
+
+ /* find particle system */
+ ParticleSystemKey key(b_ob, persistent_id);
+ ParticleSystem *psys;
+
+ bool first_use = !particle_system_map.is_used(key);
+ bool need_update = particle_system_map.sync(&psys, b_ob, b_instance.object(), key);
+
+ /* no update needed? */
+ if (!need_update && !object->mesh->need_update && !scene->object_manager->need_update)
+ return true;
+
+ /* first time used in this sync loop? clear and tag update */
+ if (first_use) {
+ psys->particles.clear();
+ psys->tag_update(scene);
+ }
+
+ /* add particle */
+ BL::Particle b_pa = b_psys.particles[persistent_id[0]];
+ Particle pa;
+
+ pa.index = persistent_id[0];
+ pa.age = b_scene.frame_current() - b_pa.birth_time();
+ pa.lifetime = b_pa.lifetime();
+ pa.location = get_float3(b_pa.location());
+ pa.rotation = get_float4(b_pa.rotation());
+ pa.size = b_pa.size();
+ pa.velocity = get_float3(b_pa.velocity());
+ pa.angular_velocity = get_float3(b_pa.angular_velocity());
+
+ psys->particles.push_back_slow(pa);
+
+ if (object->particle_index != psys->particles.size() - 1)
+ scene->object_manager->tag_update(scene);
+ object->particle_system = psys;
+ object->particle_index = psys->particles.size() - 1;
+
+ /* return that this object has particle data */
+ return true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index ccd783073a3..ffd1c70a4e4 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -35,14 +35,14 @@
#include "util/util_types.h"
#ifdef WITH_OSL
-#include "render/osl.h"
+# include "render/osl.h"
-#include <OSL/oslquery.h>
-#include <OSL/oslconfig.h>
+# include <OSL/oslquery.h>
+# include <OSL/oslconfig.h>
#endif
#ifdef WITH_OPENCL
-#include "device/device_intern.h"
+# include "device/device_intern.h"
#endif
CCL_NAMESPACE_BEGIN
@@ -54,9 +54,9 @@ bool debug_flags_set = false;
void *pylong_as_voidptr_typesafe(PyObject *object)
{
- if(object == Py_None)
- return NULL;
- return PyLong_AsVoidPtr(object);
+ if (object == Py_None)
+ return NULL;
+ return PyLong_AsVoidPtr(object);
}
/* Synchronize debug flags from a given Blender scene.
@@ -64,48 +64,48 @@ void *pylong_as_voidptr_typesafe(PyObject *object)
*/
bool debug_flags_sync_from_scene(BL::Scene b_scene)
{
- DebugFlagsRef flags = DebugFlags();
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- /* Backup some settings for comparison. */
- DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
- /* Synchronize shared flags. */
- flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
- /* Synchronize CPU flags. */
- flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2");
- flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx");
- flags.cpu.sse41 = get_boolean(cscene, "debug_use_cpu_sse41");
- flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3");
- flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2");
- flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout");
- flags.cpu.split_kernel = get_boolean(cscene, "debug_use_cpu_split_kernel");
- /* Synchronize CUDA flags. */
- flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
- flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
- /* Synchronize OpenCL device type. */
- switch(get_enum(cscene, "debug_opencl_device_type")) {
- case 0:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
- break;
- case 1:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ALL;
- break;
- case 2:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
- break;
- case 3:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_CPU;
- break;
- case 4:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_GPU;
- break;
- case 5:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
- break;
- }
- /* Synchronize other OpenCL flags. */
- flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug");
- flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit"))*1024*1024;
- return flags.opencl.device_type != opencl_device_type;
+ DebugFlagsRef flags = DebugFlags();
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ /* Backup some settings for comparison. */
+ DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
+ /* Synchronize shared flags. */
+ flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
+ /* Synchronize CPU flags. */
+ flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2");
+ flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx");
+ flags.cpu.sse41 = get_boolean(cscene, "debug_use_cpu_sse41");
+ flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3");
+ flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2");
+ flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout");
+ flags.cpu.split_kernel = get_boolean(cscene, "debug_use_cpu_split_kernel");
+ /* Synchronize CUDA flags. */
+ flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
+ flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
+ /* Synchronize OpenCL device type. */
+ switch (get_enum(cscene, "debug_opencl_device_type")) {
+ case 0:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
+ break;
+ case 1:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ALL;
+ break;
+ case 2:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
+ break;
+ case 3:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_CPU;
+ break;
+ case 4:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_GPU;
+ break;
+ case 5:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
+ break;
+ }
+ /* Synchronize other OpenCL flags. */
+ flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug");
+ flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit")) * 1024 * 1024;
+ return flags.opencl.device_type != opencl_device_type;
}
/* Reset debug flags to default values.
@@ -113,928 +113,958 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene)
*/
bool debug_flags_reset()
{
- DebugFlagsRef flags = DebugFlags();
- /* Backup some settings for comparison. */
- DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
- flags.reset();
- return flags.opencl.device_type != opencl_device_type;
+ DebugFlagsRef flags = DebugFlags();
+ /* Backup some settings for comparison. */
+ DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
+ flags.reset();
+ return flags.opencl.device_type != opencl_device_type;
}
-} /* namespace */
+} /* namespace */
void python_thread_state_save(void **python_thread_state)
{
- *python_thread_state = (void*)PyEval_SaveThread();
+ *python_thread_state = (void *)PyEval_SaveThread();
}
void python_thread_state_restore(void **python_thread_state)
{
- PyEval_RestoreThread((PyThreadState*)*python_thread_state);
- *python_thread_state = NULL;
+ PyEval_RestoreThread((PyThreadState *)*python_thread_state);
+ *python_thread_state = NULL;
}
static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
{
- const char *result = _PyUnicode_AsString(py_str);
- if(result) {
- /* 99% of the time this is enough but we better support non unicode
- * chars since blender doesnt limit this.
- */
- return result;
- }
- else {
- PyErr_Clear();
- if(PyBytes_Check(py_str)) {
- return PyBytes_AS_STRING(py_str);
- }
- else if((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
- return PyBytes_AS_STRING(*coerce);
- }
- else {
- /* Clear the error, so Cycles can be at leadt used without
- * GPU and OSL support,
- */
- PyErr_Clear();
- return "";
- }
- }
+ const char *result = _PyUnicode_AsString(py_str);
+ if (result) {
+ /* 99% of the time this is enough but we better support non unicode
+ * chars since blender doesnt limit this.
+ */
+ return result;
+ }
+ else {
+ PyErr_Clear();
+ if (PyBytes_Check(py_str)) {
+ return PyBytes_AS_STRING(py_str);
+ }
+ else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
+ return PyBytes_AS_STRING(*coerce);
+ }
+ else {
+ /* Clear the error, so Cycles can be at leadt used without
+ * GPU and OSL support,
+ */
+ PyErr_Clear();
+ return "";
+ }
+ }
}
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *path, *user_path;
- int headless;
+ PyObject *path, *user_path;
+ int headless;
- if(!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
+ return NULL;
+ }
- PyObject *path_coerce = NULL, *user_path_coerce = NULL;
- path_init(PyC_UnicodeAsByte(path, &path_coerce),
- PyC_UnicodeAsByte(user_path, &user_path_coerce));
- Py_XDECREF(path_coerce);
- Py_XDECREF(user_path_coerce);
+ PyObject *path_coerce = NULL, *user_path_coerce = NULL;
+ path_init(PyC_UnicodeAsByte(path, &path_coerce),
+ PyC_UnicodeAsByte(user_path, &user_path_coerce));
+ Py_XDECREF(path_coerce);
+ Py_XDECREF(user_path_coerce);
- BlenderSession::headless = headless;
+ BlenderSession::headless = headless;
- VLOG(2) << "Debug flags initialized to:\n"
- << DebugFlags();
+ VLOG(2) << "Debug flags initialized to:\n" << DebugFlags();
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-
static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/)
{
- ShaderManager::free_memory();
- TaskScheduler::free_memory();
- Device::free_memory();
- Py_RETURN_NONE;
+ ShaderManager::free_memory();
+ TaskScheduler::free_memory();
+ Device::free_memory();
+ Py_RETURN_NONE;
}
static PyObject *create_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pyengine, *pypreferences, *pydata, *pyregion, *pyv3d, *pyrv3d;
- int preview_osl;
-
- if(!PyArg_ParseTuple(args, "OOOOOOi", &pyengine, &pypreferences, &pydata,
- &pyregion, &pyv3d, &pyrv3d, &preview_osl))
- {
- return NULL;
- }
-
- /* RNA */
- PointerRNA engineptr;
- RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
- BL::RenderEngine engine(engineptr);
-
- PointerRNA preferencesptr;
- RNA_pointer_create(NULL, &RNA_Preferences, (void*)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
- BL::Preferences preferences(preferencesptr);
-
- PointerRNA dataptr;
- RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
- BL::BlendData data(dataptr);
-
- PointerRNA regionptr;
- RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
- BL::Region region(regionptr);
-
- PointerRNA v3dptr;
- RNA_pointer_create(NULL, &RNA_SpaceView3D, pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
- BL::SpaceView3D v3d(v3dptr);
-
- PointerRNA rv3dptr;
- RNA_pointer_create(NULL, &RNA_RegionView3D, pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
- BL::RegionView3D rv3d(rv3dptr);
-
- /* create session */
- BlenderSession *session;
-
- if(rv3d) {
- /* interactive viewport session */
- int width = region.width();
- int height = region.height();
-
- session = new BlenderSession(engine, preferences, data, v3d, rv3d, width, height);
- }
- else {
- /* offline session or preview render */
- session = new BlenderSession(engine, preferences, data, preview_osl);
- }
-
- return PyLong_FromVoidPtr(session);
+ PyObject *pyengine, *pypreferences, *pydata, *pyregion, *pyv3d, *pyrv3d;
+ int preview_osl;
+
+ if (!PyArg_ParseTuple(args,
+ "OOOOOOi",
+ &pyengine,
+ &pypreferences,
+ &pydata,
+ &pyregion,
+ &pyv3d,
+ &pyrv3d,
+ &preview_osl)) {
+ return NULL;
+ }
+
+ /* RNA */
+ PointerRNA engineptr;
+ RNA_pointer_create(NULL, &RNA_RenderEngine, (void *)PyLong_AsVoidPtr(pyengine), &engineptr);
+ BL::RenderEngine engine(engineptr);
+
+ PointerRNA preferencesptr;
+ RNA_pointer_create(
+ NULL, &RNA_Preferences, (void *)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
+ BL::Preferences preferences(preferencesptr);
+
+ PointerRNA dataptr;
+ RNA_main_pointer_create((Main *)PyLong_AsVoidPtr(pydata), &dataptr);
+ BL::BlendData data(dataptr);
+
+ PointerRNA regionptr;
+ RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
+ BL::Region region(regionptr);
+
+ PointerRNA v3dptr;
+ RNA_pointer_create(NULL, &RNA_SpaceView3D, pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
+ BL::SpaceView3D v3d(v3dptr);
+
+ PointerRNA rv3dptr;
+ RNA_pointer_create(NULL, &RNA_RegionView3D, pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
+ BL::RegionView3D rv3d(rv3dptr);
+
+ /* create session */
+ BlenderSession *session;
+
+ if (rv3d) {
+ /* interactive viewport session */
+ int width = region.width();
+ int height = region.height();
+
+ session = new BlenderSession(engine, preferences, data, v3d, rv3d, width, height);
+ }
+ else {
+ /* offline session or preview render */
+ session = new BlenderSession(engine, preferences, data, preview_osl);
+ }
+
+ return PyLong_FromVoidPtr(session);
}
static PyObject *free_func(PyObject * /*self*/, PyObject *value)
{
- delete (BlenderSession*)PyLong_AsVoidPtr(value);
+ delete (BlenderSession *)PyLong_AsVoidPtr(value);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *render_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydepsgraph;
+ PyObject *pysession, *pydepsgraph;
- if(!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, (ID*)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, (ID *)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
- python_thread_state_save(&session->python_thread_state);
+ python_thread_state_save(&session->python_thread_state);
- session->render(b_depsgraph);
+ session->render(b_depsgraph);
- python_thread_state_restore(&session->python_thread_state);
+ python_thread_state_restore(&session->python_thread_state);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
/* pixel_array and result passed as pointers */
static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydepsgraph, *pyobject;
- PyObject *pypixel_array, *pyresult;
- const char *pass_type;
- int num_pixels, depth, object_id, pass_filter;
-
- if(!PyArg_ParseTuple(args, "OOOsiiOiiO", &pysession, &pydepsgraph, &pyobject, &pass_type, &pass_filter, &object_id, &pypixel_array, &num_pixels, &depth, &pyresult))
- return NULL;
-
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
-
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
-
- PointerRNA objectptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyobject), &objectptr);
- BL::Object b_object(objectptr);
-
- void *b_result = PyLong_AsVoidPtr(pyresult);
-
- PointerRNA bakepixelptr;
- RNA_pointer_create(NULL, &RNA_BakePixel, PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
- BL::BakePixel b_bake_pixel(bakepixelptr);
-
- python_thread_state_save(&session->python_thread_state);
-
- session->bake(b_depsgraph, b_object, pass_type, pass_filter, object_id, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result);
-
- python_thread_state_restore(&session->python_thread_state);
-
- Py_RETURN_NONE;
+ PyObject *pysession, *pydepsgraph, *pyobject;
+ PyObject *pypixel_array, *pyresult;
+ const char *pass_type;
+ int num_pixels, depth, object_id, pass_filter;
+
+ if (!PyArg_ParseTuple(args,
+ "OOOsiiOiiO",
+ &pysession,
+ &pydepsgraph,
+ &pyobject,
+ &pass_type,
+ &pass_filter,
+ &object_id,
+ &pypixel_array,
+ &num_pixels,
+ &depth,
+ &pyresult))
+ return NULL;
+
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
+
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
+
+ PointerRNA objectptr;
+ RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyobject), &objectptr);
+ BL::Object b_object(objectptr);
+
+ void *b_result = PyLong_AsVoidPtr(pyresult);
+
+ PointerRNA bakepixelptr;
+ RNA_pointer_create(NULL, &RNA_BakePixel, PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
+ BL::BakePixel b_bake_pixel(bakepixelptr);
+
+ python_thread_state_save(&session->python_thread_state);
+
+ session->bake(b_depsgraph,
+ b_object,
+ pass_type,
+ pass_filter,
+ object_id,
+ b_bake_pixel,
+ (size_t)num_pixels,
+ depth,
+ (float *)b_result);
+
+ python_thread_state_restore(&session->python_thread_state);
+
+ Py_RETURN_NONE;
}
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
+ PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
- if(!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- if(PyLong_AsVoidPtr(pyrv3d)) {
- /* 3d view drawing */
- int viewport[4];
- glGetIntegerv(GL_VIEWPORT, viewport);
+ if (PyLong_AsVoidPtr(pyrv3d)) {
+ /* 3d view drawing */
+ int viewport[4];
+ glGetIntegerv(GL_VIEWPORT, viewport);
- session->draw(viewport[2], viewport[3]);
- }
+ session->draw(viewport[2], viewport[3]);
+ }
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydata, *pydepsgraph;
+ PyObject *pysession, *pydata, *pydepsgraph;
- if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- PointerRNA dataptr;
- RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
- BL::BlendData b_data(dataptr);
+ PointerRNA dataptr;
+ RNA_main_pointer_create((Main *)PyLong_AsVoidPtr(pydata), &dataptr);
+ BL::BlendData b_data(dataptr);
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
- python_thread_state_save(&session->python_thread_state);
+ python_thread_state_save(&session->python_thread_state);
- session->reset_session(b_data, b_depsgraph);
+ session->reset_session(b_data, b_depsgraph);
- python_thread_state_restore(&session->python_thread_state);
+ python_thread_state_restore(&session->python_thread_state);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydepsgraph;
+ PyObject *pysession, *pydepsgraph;
- if(!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
- python_thread_state_save(&session->python_thread_state);
+ python_thread_state_save(&session->python_thread_state);
- session->synchronize(b_depsgraph);
+ session->synchronize(b_depsgraph);
- python_thread_state_restore(&session->python_thread_state);
+ python_thread_state_restore(&session->python_thread_state);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-static PyObject *available_devices_func(PyObject * /*self*/, PyObject * args)
+static PyObject *available_devices_func(PyObject * /*self*/, PyObject *args)
{
- const char *type_name;
- if(!PyArg_ParseTuple(args, "s", &type_name)) {
- return NULL;
- }
-
- DeviceType type = Device::type_from_string(type_name);
- uint mask = (type == DEVICE_NONE) ? DEVICE_MASK_ALL : DEVICE_MASK(type);
- mask |= DEVICE_MASK_CPU;
-
- vector<DeviceInfo> devices = Device::available_devices(mask);
- PyObject *ret = PyTuple_New(devices.size());
-
- for(size_t i = 0; i < devices.size(); i++) {
- DeviceInfo& device = devices[i];
- string type_name = Device::string_from_type(device.type);
- PyObject *device_tuple = PyTuple_New(3);
- PyTuple_SET_ITEM(device_tuple, 0, PyUnicode_FromString(device.description.c_str()));
- PyTuple_SET_ITEM(device_tuple, 1, PyUnicode_FromString(type_name.c_str()));
- PyTuple_SET_ITEM(device_tuple, 2, PyUnicode_FromString(device.id.c_str()));
- PyTuple_SET_ITEM(ret, i, device_tuple);
- }
-
- return ret;
+ const char *type_name;
+ if (!PyArg_ParseTuple(args, "s", &type_name)) {
+ return NULL;
+ }
+
+ DeviceType type = Device::type_from_string(type_name);
+ uint mask = (type == DEVICE_NONE) ? DEVICE_MASK_ALL : DEVICE_MASK(type);
+ mask |= DEVICE_MASK_CPU;
+
+ vector<DeviceInfo> devices = Device::available_devices(mask);
+ PyObject *ret = PyTuple_New(devices.size());
+
+ for (size_t i = 0; i < devices.size(); i++) {
+ DeviceInfo &device = devices[i];
+ string type_name = Device::string_from_type(device.type);
+ PyObject *device_tuple = PyTuple_New(3);
+ PyTuple_SET_ITEM(device_tuple, 0, PyUnicode_FromString(device.description.c_str()));
+ PyTuple_SET_ITEM(device_tuple, 1, PyUnicode_FromString(type_name.c_str()));
+ PyTuple_SET_ITEM(device_tuple, 2, PyUnicode_FromString(device.id.c_str()));
+ PyTuple_SET_ITEM(ret, i, device_tuple);
+ }
+
+ return ret;
}
#ifdef WITH_OSL
static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pydata, *pynodegroup, *pynode;
- const char *filepath = NULL;
-
- if(!PyArg_ParseTuple(args, "OOOs", &pydata, &pynodegroup, &pynode, &filepath))
- return NULL;
-
- /* RNA */
- PointerRNA dataptr;
- RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
- BL::BlendData b_data(dataptr);
-
- PointerRNA nodeptr;
- RNA_pointer_create((ID*)PyLong_AsVoidPtr(pynodegroup), &RNA_ShaderNodeScript, (void*)PyLong_AsVoidPtr(pynode), &nodeptr);
- BL::ShaderNodeScript b_node(nodeptr);
-
- /* update bytecode hash */
- string bytecode = b_node.bytecode();
-
- if(!bytecode.empty()) {
- MD5Hash md5;
- md5.append((const uint8_t*)bytecode.c_str(), bytecode.size());
- b_node.bytecode_hash(md5.get_hex().c_str());
- }
- else
- b_node.bytecode_hash("");
-
- /* query from file path */
- OSL::OSLQuery query;
-
- if(!OSLShaderManager::osl_query(query, filepath))
- Py_RETURN_FALSE;
-
- /* add new sockets from parameters */
- set<void*> used_sockets;
-
- for(int i = 0; i < query.nparams(); i++) {
- const OSL::OSLQuery::Parameter *param = query.getparam(i);
-
- /* skip unsupported types */
- if(param->varlenarray || param->isstruct || param->type.arraylen > 1)
- continue;
-
- /* determine socket type */
- string socket_type;
- BL::NodeSocket::type_enum data_type = BL::NodeSocket::type_VALUE;
- float4 default_float4 = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
- float default_float = 0.0f;
- int default_int = 0;
- string default_string = "";
-
- if(param->isclosure) {
- socket_type = "NodeSocketShader";
- data_type = BL::NodeSocket::type_SHADER;
- }
- else if(param->type.vecsemantics == TypeDesc::COLOR) {
- socket_type = "NodeSocketColor";
- data_type = BL::NodeSocket::type_RGBA;
-
- if(param->validdefault) {
- default_float4[0] = param->fdefault[0];
- default_float4[1] = param->fdefault[1];
- default_float4[2] = param->fdefault[2];
- }
- }
- else if(param->type.vecsemantics == TypeDesc::POINT ||
- param->type.vecsemantics == TypeDesc::VECTOR ||
- param->type.vecsemantics == TypeDesc::NORMAL)
- {
- socket_type = "NodeSocketVector";
- data_type = BL::NodeSocket::type_VECTOR;
-
- if(param->validdefault) {
- default_float4[0] = param->fdefault[0];
- default_float4[1] = param->fdefault[1];
- default_float4[2] = param->fdefault[2];
- }
- }
- else if(param->type.aggregate == TypeDesc::SCALAR) {
- if(param->type.basetype == TypeDesc::INT) {
- socket_type = "NodeSocketInt";
- data_type = BL::NodeSocket::type_INT;
- if(param->validdefault)
- default_int = param->idefault[0];
- }
- else if(param->type.basetype == TypeDesc::FLOAT) {
- socket_type = "NodeSocketFloat";
- data_type = BL::NodeSocket::type_VALUE;
- if(param->validdefault)
- default_float = param->fdefault[0];
- }
- else if(param->type.basetype == TypeDesc::STRING) {
- socket_type = "NodeSocketString";
- data_type = BL::NodeSocket::type_STRING;
- if(param->validdefault)
- default_string = param->sdefault[0].string();
- }
- else
- continue;
- }
- else
- continue;
-
- /* find socket socket */
- BL::NodeSocket b_sock(PointerRNA_NULL);
- if(param->isoutput) {
- b_sock = b_node.outputs[param->name.string()];
- /* remove if type no longer matches */
- if(b_sock && b_sock.bl_idname() != socket_type) {
- b_node.outputs.remove(b_data, b_sock);
- b_sock = BL::NodeSocket(PointerRNA_NULL);
- }
- }
- else {
- b_sock = b_node.inputs[param->name.string()];
- /* remove if type no longer matches */
- if(b_sock && b_sock.bl_idname() != socket_type) {
- b_node.inputs.remove(b_data, b_sock);
- b_sock = BL::NodeSocket(PointerRNA_NULL);
- }
- }
-
- if(!b_sock) {
- /* create new socket */
- if(param->isoutput)
- b_sock = b_node.outputs.create(b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
- else
- b_sock = b_node.inputs.create(b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
-
- /* set default value */
- if(data_type == BL::NodeSocket::type_VALUE) {
- set_float(b_sock.ptr, "default_value", default_float);
- }
- else if(data_type == BL::NodeSocket::type_INT) {
- set_int(b_sock.ptr, "default_value", default_int);
- }
- else if(data_type == BL::NodeSocket::type_RGBA) {
- set_float4(b_sock.ptr, "default_value", default_float4);
- }
- else if(data_type == BL::NodeSocket::type_VECTOR) {
- set_float3(b_sock.ptr, "default_value", float4_to_float3(default_float4));
- }
- else if(data_type == BL::NodeSocket::type_STRING) {
- set_string(b_sock.ptr, "default_value", default_string);
- }
- }
-
- used_sockets.insert(b_sock.ptr.data);
- }
-
- /* remove unused parameters */
- bool removed;
-
- do {
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
-
- removed = false;
-
- for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
- if(used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
- b_node.inputs.remove(b_data, *b_input);
- removed = true;
- break;
- }
- }
-
- for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
- if(used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
- b_node.outputs.remove(b_data, *b_output);
- removed = true;
- break;
- }
- }
- } while(removed);
-
- Py_RETURN_TRUE;
+ PyObject *pydata, *pynodegroup, *pynode;
+ const char *filepath = NULL;
+
+ if (!PyArg_ParseTuple(args, "OOOs", &pydata, &pynodegroup, &pynode, &filepath))
+ return NULL;
+
+ /* RNA */
+ PointerRNA dataptr;
+ RNA_main_pointer_create((Main *)PyLong_AsVoidPtr(pydata), &dataptr);
+ BL::BlendData b_data(dataptr);
+
+ PointerRNA nodeptr;
+ RNA_pointer_create((ID *)PyLong_AsVoidPtr(pynodegroup),
+ &RNA_ShaderNodeScript,
+ (void *)PyLong_AsVoidPtr(pynode),
+ &nodeptr);
+ BL::ShaderNodeScript b_node(nodeptr);
+
+ /* update bytecode hash */
+ string bytecode = b_node.bytecode();
+
+ if (!bytecode.empty()) {
+ MD5Hash md5;
+ md5.append((const uint8_t *)bytecode.c_str(), bytecode.size());
+ b_node.bytecode_hash(md5.get_hex().c_str());
+ }
+ else
+ b_node.bytecode_hash("");
+
+ /* query from file path */
+ OSL::OSLQuery query;
+
+ if (!OSLShaderManager::osl_query(query, filepath))
+ Py_RETURN_FALSE;
+
+ /* add new sockets from parameters */
+ set<void *> used_sockets;
+
+ for (int i = 0; i < query.nparams(); i++) {
+ const OSL::OSLQuery::Parameter *param = query.getparam(i);
+
+ /* skip unsupported types */
+ if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
+ continue;
+
+ /* determine socket type */
+ string socket_type;
+ BL::NodeSocket::type_enum data_type = BL::NodeSocket::type_VALUE;
+ float4 default_float4 = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
+ float default_float = 0.0f;
+ int default_int = 0;
+ string default_string = "";
+
+ if (param->isclosure) {
+ socket_type = "NodeSocketShader";
+ data_type = BL::NodeSocket::type_SHADER;
+ }
+ else if (param->type.vecsemantics == TypeDesc::COLOR) {
+ socket_type = "NodeSocketColor";
+ data_type = BL::NodeSocket::type_RGBA;
+
+ if (param->validdefault) {
+ default_float4[0] = param->fdefault[0];
+ default_float4[1] = param->fdefault[1];
+ default_float4[2] = param->fdefault[2];
+ }
+ }
+ else if (param->type.vecsemantics == TypeDesc::POINT ||
+ param->type.vecsemantics == TypeDesc::VECTOR ||
+ param->type.vecsemantics == TypeDesc::NORMAL) {
+ socket_type = "NodeSocketVector";
+ data_type = BL::NodeSocket::type_VECTOR;
+
+ if (param->validdefault) {
+ default_float4[0] = param->fdefault[0];
+ default_float4[1] = param->fdefault[1];
+ default_float4[2] = param->fdefault[2];
+ }
+ }
+ else if (param->type.aggregate == TypeDesc::SCALAR) {
+ if (param->type.basetype == TypeDesc::INT) {
+ socket_type = "NodeSocketInt";
+ data_type = BL::NodeSocket::type_INT;
+ if (param->validdefault)
+ default_int = param->idefault[0];
+ }
+ else if (param->type.basetype == TypeDesc::FLOAT) {
+ socket_type = "NodeSocketFloat";
+ data_type = BL::NodeSocket::type_VALUE;
+ if (param->validdefault)
+ default_float = param->fdefault[0];
+ }
+ else if (param->type.basetype == TypeDesc::STRING) {
+ socket_type = "NodeSocketString";
+ data_type = BL::NodeSocket::type_STRING;
+ if (param->validdefault)
+ default_string = param->sdefault[0].string();
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+
+ /* find socket socket */
+ BL::NodeSocket b_sock(PointerRNA_NULL);
+ if (param->isoutput) {
+ b_sock = b_node.outputs[param->name.string()];
+ /* remove if type no longer matches */
+ if (b_sock && b_sock.bl_idname() != socket_type) {
+ b_node.outputs.remove(b_data, b_sock);
+ b_sock = BL::NodeSocket(PointerRNA_NULL);
+ }
+ }
+ else {
+ b_sock = b_node.inputs[param->name.string()];
+ /* remove if type no longer matches */
+ if (b_sock && b_sock.bl_idname() != socket_type) {
+ b_node.inputs.remove(b_data, b_sock);
+ b_sock = BL::NodeSocket(PointerRNA_NULL);
+ }
+ }
+
+ if (!b_sock) {
+ /* create new socket */
+ if (param->isoutput)
+ b_sock = b_node.outputs.create(
+ b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
+ else
+ b_sock = b_node.inputs.create(
+ b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
+
+ /* set default value */
+ if (data_type == BL::NodeSocket::type_VALUE) {
+ set_float(b_sock.ptr, "default_value", default_float);
+ }
+ else if (data_type == BL::NodeSocket::type_INT) {
+ set_int(b_sock.ptr, "default_value", default_int);
+ }
+ else if (data_type == BL::NodeSocket::type_RGBA) {
+ set_float4(b_sock.ptr, "default_value", default_float4);
+ }
+ else if (data_type == BL::NodeSocket::type_VECTOR) {
+ set_float3(b_sock.ptr, "default_value", float4_to_float3(default_float4));
+ }
+ else if (data_type == BL::NodeSocket::type_STRING) {
+ set_string(b_sock.ptr, "default_value", default_string);
+ }
+ }
+
+ used_sockets.insert(b_sock.ptr.data);
+ }
+
+ /* remove unused parameters */
+ bool removed;
+
+ do {
+ BL::Node::inputs_iterator b_input;
+ BL::Node::outputs_iterator b_output;
+
+ removed = false;
+
+ for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
+ if (used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
+ b_node.inputs.remove(b_data, *b_input);
+ removed = true;
+ break;
+ }
+ }
+
+ for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
+ if (used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
+ b_node.outputs.remove(b_data, *b_output);
+ removed = true;
+ break;
+ }
+ }
+ } while (removed);
+
+ Py_RETURN_TRUE;
}
static PyObject *osl_compile_func(PyObject * /*self*/, PyObject *args)
{
- const char *inputfile = NULL, *outputfile = NULL;
+ const char *inputfile = NULL, *outputfile = NULL;
- if(!PyArg_ParseTuple(args, "ss", &inputfile, &outputfile))
- return NULL;
+ if (!PyArg_ParseTuple(args, "ss", &inputfile, &outputfile))
+ return NULL;
- /* return */
- if(!OSLShaderManager::osl_compile(inputfile, outputfile))
- Py_RETURN_FALSE;
+ /* return */
+ if (!OSLShaderManager::osl_compile(inputfile, outputfile))
+ Py_RETURN_FALSE;
- Py_RETURN_TRUE;
+ Py_RETURN_TRUE;
}
#endif
static PyObject *system_info_func(PyObject * /*self*/, PyObject * /*value*/)
{
- string system_info = Device::device_capabilities();
- return PyUnicode_FromString(system_info.c_str());
+ string system_info = Device::device_capabilities();
+ return PyUnicode_FromString(system_info.c_str());
}
#ifdef WITH_OPENCL
static PyObject *opencl_disable_func(PyObject * /*self*/, PyObject * /*value*/)
{
- VLOG(2) << "Disabling OpenCL platform.";
- DebugFlags().opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
- Py_RETURN_NONE;
+ VLOG(2) << "Disabling OpenCL platform.";
+ DebugFlags().opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
+ Py_RETURN_NONE;
}
static PyObject *opencl_compile_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *sequence = PySequence_Fast(args, "Arguments must be a sequence");
- if(sequence == NULL) {
- Py_RETURN_FALSE;
- }
-
- vector<string> parameters;
- for(Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
- PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
- PyObject *item_as_string = PyObject_Str(item);
- const char *parameter_string = PyUnicode_AsUTF8(item_as_string);
- parameters.push_back(parameter_string);
- Py_DECREF(item_as_string);
- }
- Py_DECREF(sequence);
-
- if (device_opencl_compile_kernel(parameters)) {
- Py_RETURN_TRUE;
- }
- else {
- Py_RETURN_FALSE;
- }
+ PyObject *sequence = PySequence_Fast(args, "Arguments must be a sequence");
+ if (sequence == NULL) {
+ Py_RETURN_FALSE;
+ }
+
+ vector<string> parameters;
+ for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
+ PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
+ PyObject *item_as_string = PyObject_Str(item);
+ const char *parameter_string = PyUnicode_AsUTF8(item_as_string);
+ parameters.push_back(parameter_string);
+ Py_DECREF(item_as_string);
+ }
+ Py_DECREF(sequence);
+
+ if (device_opencl_compile_kernel(parameters)) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
}
#endif
-static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string>& filepaths)
+static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string> &filepaths)
{
- if(PyUnicode_Check(pyfilepaths)) {
- const char *filepath = PyUnicode_AsUTF8(pyfilepaths);
- filepaths.push_back(filepath);
- return true;
- }
-
- PyObject *sequence = PySequence_Fast(pyfilepaths, "File paths must be a string or sequence of strings");
- if(sequence == NULL) {
- return false;
- }
-
- for(Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
- PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
- const char *filepath = PyUnicode_AsUTF8(item);
- if(filepath == NULL) {
- PyErr_SetString(PyExc_ValueError, "File paths must be a string or sequence of strings.");
- Py_DECREF(sequence);
- return false;
- }
- filepaths.push_back(filepath);
- }
- Py_DECREF(sequence);
-
- return true;
+ if (PyUnicode_Check(pyfilepaths)) {
+ const char *filepath = PyUnicode_AsUTF8(pyfilepaths);
+ filepaths.push_back(filepath);
+ return true;
+ }
+
+ PyObject *sequence = PySequence_Fast(pyfilepaths,
+ "File paths must be a string or sequence of strings");
+ if (sequence == NULL) {
+ return false;
+ }
+
+ for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
+ PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
+ const char *filepath = PyUnicode_AsUTF8(item);
+ if (filepath == NULL) {
+ PyErr_SetString(PyExc_ValueError, "File paths must be a string or sequence of strings.");
+ Py_DECREF(sequence);
+ return false;
+ }
+ filepaths.push_back(filepath);
+ }
+ Py_DECREF(sequence);
+
+ return true;
}
static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
{
- static const char *keyword_list[] = {"preferences", "scene", "view_layer",
- "input", "output",
- "tile_size", "samples", NULL};
- PyObject *pypreferences, *pyscene, *pyviewlayer;
- PyObject *pyinput, *pyoutput = NULL;
- int tile_size = 0, samples = 0;
-
- if (!PyArg_ParseTupleAndKeywords(args, keywords, "OOOO|Oii", (char**)keyword_list,
- &pypreferences, &pyscene, &pyviewlayer,
- &pyinput, &pyoutput,
- &tile_size, &samples)) {
- return NULL;
- }
-
- /* Get device specification from preferences and scene. */
- PointerRNA preferencesptr;
- RNA_pointer_create(NULL, &RNA_Preferences, (void*)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
- BL::Preferences b_preferences(preferencesptr);
-
- PointerRNA sceneptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
- BL::Scene b_scene(sceneptr);
-
- DeviceInfo device = blender_device_info(b_preferences, b_scene, true);
-
- /* Get denoising parameters from view layer. */
- PointerRNA viewlayerptr;
- RNA_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &RNA_ViewLayer, PyLong_AsVoidPtr(pyviewlayer), &viewlayerptr);
- PointerRNA cviewlayer = RNA_pointer_get(&viewlayerptr, "cycles");
-
- DenoiseParams params;
- params.radius = get_int(cviewlayer, "denoising_radius");
- params.strength = get_float(cviewlayer, "denoising_strength");
- params.feature_strength = get_float(cviewlayer, "denoising_feature_strength");
- params.relative_pca = get_boolean(cviewlayer, "denoising_relative_pca");
- params.neighbor_frames = get_int(cviewlayer, "denoising_neighbor_frames");
-
- /* Parse file paths list. */
- vector<string> input, output;
-
- if(!image_parse_filepaths(pyinput, input)) {
- return NULL;
- }
-
- if(pyoutput) {
- if(!image_parse_filepaths(pyoutput, output)) {
- return NULL;
- }
- }
- else {
- output = input;
- }
-
- if(input.empty()) {
- PyErr_SetString(PyExc_ValueError, "No input file paths specified.");
- return NULL;
- }
- if(input.size() != output.size()) {
- PyErr_SetString(PyExc_ValueError, "Number of input and output file paths does not match.");
- return NULL;
- }
-
- /* Create denoiser. */
- Denoiser denoiser(device);
- denoiser.params = params;
- denoiser.input = input;
- denoiser.output = output;
-
- if (tile_size > 0) {
- denoiser.tile_size = make_int2(tile_size, tile_size);
- }
- if (samples > 0) {
- denoiser.samples_override = samples;
- }
-
- /* Run denoiser. */
- if(!denoiser.run()) {
- PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
- return NULL;
- }
-
- Py_RETURN_NONE;
+ static const char *keyword_list[] = {
+ "preferences", "scene", "view_layer", "input", "output", "tile_size", "samples", NULL};
+ PyObject *pypreferences, *pyscene, *pyviewlayer;
+ PyObject *pyinput, *pyoutput = NULL;
+ int tile_size = 0, samples = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ keywords,
+ "OOOO|Oii",
+ (char **)keyword_list,
+ &pypreferences,
+ &pyscene,
+ &pyviewlayer,
+ &pyinput,
+ &pyoutput,
+ &tile_size,
+ &samples)) {
+ return NULL;
+ }
+
+ /* Get device specification from preferences and scene. */
+ PointerRNA preferencesptr;
+ RNA_pointer_create(
+ NULL, &RNA_Preferences, (void *)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
+ BL::Preferences b_preferences(preferencesptr);
+
+ PointerRNA sceneptr;
+ RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyscene), &sceneptr);
+ BL::Scene b_scene(sceneptr);
+
+ DeviceInfo device = blender_device_info(b_preferences, b_scene, true);
+
+ /* Get denoising parameters from view layer. */
+ PointerRNA viewlayerptr;
+ RNA_pointer_create((ID *)PyLong_AsVoidPtr(pyscene),
+ &RNA_ViewLayer,
+ PyLong_AsVoidPtr(pyviewlayer),
+ &viewlayerptr);
+ PointerRNA cviewlayer = RNA_pointer_get(&viewlayerptr, "cycles");
+
+ DenoiseParams params;
+ params.radius = get_int(cviewlayer, "denoising_radius");
+ params.strength = get_float(cviewlayer, "denoising_strength");
+ params.feature_strength = get_float(cviewlayer, "denoising_feature_strength");
+ params.relative_pca = get_boolean(cviewlayer, "denoising_relative_pca");
+ params.neighbor_frames = get_int(cviewlayer, "denoising_neighbor_frames");
+
+ /* Parse file paths list. */
+ vector<string> input, output;
+
+ if (!image_parse_filepaths(pyinput, input)) {
+ return NULL;
+ }
+
+ if (pyoutput) {
+ if (!image_parse_filepaths(pyoutput, output)) {
+ return NULL;
+ }
+ }
+ else {
+ output = input;
+ }
+
+ if (input.empty()) {
+ PyErr_SetString(PyExc_ValueError, "No input file paths specified.");
+ return NULL;
+ }
+ if (input.size() != output.size()) {
+ PyErr_SetString(PyExc_ValueError, "Number of input and output file paths does not match.");
+ return NULL;
+ }
+
+ /* Create denoiser. */
+ Denoiser denoiser(device);
+ denoiser.params = params;
+ denoiser.input = input;
+ denoiser.output = output;
+
+ if (tile_size > 0) {
+ denoiser.tile_size = make_int2(tile_size, tile_size);
+ }
+ if (samples > 0) {
+ denoiser.samples_override = samples;
+ }
+
+ /* Run denoiser. */
+ if (!denoiser.run()) {
+ PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
}
static PyObject *merge_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
{
- static const char *keyword_list[] = {"input", "output", NULL};
- PyObject *pyinput, *pyoutput = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, keywords, "OO", (char**)keyword_list, &pyinput, &pyoutput)) {
- return NULL;
- }
-
- /* Parse input list. */
- vector<string> input;
- if(!image_parse_filepaths(pyinput, input)) {
- return NULL;
- }
-
- /* Parse output string. */
- if(!PyUnicode_Check(pyoutput)) {
- PyErr_SetString(PyExc_ValueError, "Output must be a string.");
- return NULL;
- }
- string output = PyUnicode_AsUTF8(pyoutput);
-
- /* Merge. */
- ImageMerger merger;
- merger.input = input;
- merger.output = output;
-
- if(!merger.run()) {
- PyErr_SetString(PyExc_ValueError, merger.error.c_str());
- return NULL;
- }
-
- Py_RETURN_NONE;
+ static const char *keyword_list[] = {"input", "output", NULL};
+ PyObject *pyinput, *pyoutput = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, keywords, "OO", (char **)keyword_list, &pyinput, &pyoutput)) {
+ return NULL;
+ }
+
+ /* Parse input list. */
+ vector<string> input;
+ if (!image_parse_filepaths(pyinput, input)) {
+ return NULL;
+ }
+
+ /* Parse output string. */
+ if (!PyUnicode_Check(pyoutput)) {
+ PyErr_SetString(PyExc_ValueError, "Output must be a string.");
+ return NULL;
+ }
+ string output = PyUnicode_AsUTF8(pyoutput);
+
+ /* Merge. */
+ ImageMerger merger;
+ merger.input = input;
+ merger.output = output;
+
+ if (!merger.run()) {
+ PyErr_SetString(PyExc_ValueError, merger.error.c_str());
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
}
-
static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pyscene;
- if(!PyArg_ParseTuple(args, "O", &pyscene)) {
- return NULL;
- }
+ PyObject *pyscene;
+ if (!PyArg_ParseTuple(args, "O", &pyscene)) {
+ return NULL;
+ }
- PointerRNA sceneptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
- BL::Scene b_scene(sceneptr);
+ PointerRNA sceneptr;
+ RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyscene), &sceneptr);
+ BL::Scene b_scene(sceneptr);
- if(debug_flags_sync_from_scene(b_scene)) {
- VLOG(2) << "Tagging device list for update.";
- Device::tag_update();
- }
+ if (debug_flags_sync_from_scene(b_scene)) {
+ VLOG(2) << "Tagging device list for update.";
+ Device::tag_update();
+ }
- VLOG(2) << "Debug flags set to:\n"
- << DebugFlags();
+ VLOG(2) << "Debug flags set to:\n" << DebugFlags();
- debug_flags_set = true;
+ debug_flags_set = true;
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *debug_flags_reset_func(PyObject * /*self*/, PyObject * /*args*/)
{
- if(debug_flags_reset()) {
- VLOG(2) << "Tagging device list for update.";
- Device::tag_update();
- }
- if(debug_flags_set) {
- VLOG(2) << "Debug flags reset to:\n"
- << DebugFlags();
- debug_flags_set = false;
- }
- Py_RETURN_NONE;
+ if (debug_flags_reset()) {
+ VLOG(2) << "Tagging device list for update.";
+ Device::tag_update();
+ }
+ if (debug_flags_set) {
+ VLOG(2) << "Debug flags reset to:\n" << DebugFlags();
+ debug_flags_set = false;
+ }
+ Py_RETURN_NONE;
}
static PyObject *set_resumable_chunk_func(PyObject * /*self*/, PyObject *args)
{
- int num_resumable_chunks, current_resumable_chunk;
- if(!PyArg_ParseTuple(args, "ii",
- &num_resumable_chunks,
- &current_resumable_chunk)) {
- Py_RETURN_NONE;
- }
-
- if(num_resumable_chunks <= 0) {
- fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(current_resumable_chunk < 1 ||
- current_resumable_chunk > num_resumable_chunks)
- {
- fprintf(stderr, "Cycles: Bad value for current resumable chunk number.\n");
- abort();
- Py_RETURN_NONE;
- }
-
- VLOG(1) << "Initialized resumable render: "
- << "num_resumable_chunks=" << num_resumable_chunks << ", "
- << "current_resumable_chunk=" << current_resumable_chunk;
- BlenderSession::num_resumable_chunks = num_resumable_chunks;
- BlenderSession::current_resumable_chunk = current_resumable_chunk;
-
- printf("Cycles: Will render chunk %d of %d\n",
- current_resumable_chunk,
- num_resumable_chunks);
-
- Py_RETURN_NONE;
+ int num_resumable_chunks, current_resumable_chunk;
+ if (!PyArg_ParseTuple(args, "ii", &num_resumable_chunks, &current_resumable_chunk)) {
+ Py_RETURN_NONE;
+ }
+
+ if (num_resumable_chunks <= 0) {
+ fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (current_resumable_chunk < 1 || current_resumable_chunk > num_resumable_chunks) {
+ fprintf(stderr, "Cycles: Bad value for current resumable chunk number.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+
+ VLOG(1) << "Initialized resumable render: "
+ << "num_resumable_chunks=" << num_resumable_chunks << ", "
+ << "current_resumable_chunk=" << current_resumable_chunk;
+ BlenderSession::num_resumable_chunks = num_resumable_chunks;
+ BlenderSession::current_resumable_chunk = current_resumable_chunk;
+
+ printf("Cycles: Will render chunk %d of %d\n", current_resumable_chunk, num_resumable_chunks);
+
+ Py_RETURN_NONE;
}
static PyObject *set_resumable_chunk_range_func(PyObject * /*self*/, PyObject *args)
{
- int num_chunks, start_chunk, end_chunk;
- if(!PyArg_ParseTuple(args, "iii",
- &num_chunks,
- &start_chunk,
- &end_chunk)) {
- Py_RETURN_NONE;
- }
-
- if(num_chunks <= 0) {
- fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(start_chunk < 1 || start_chunk > num_chunks) {
- fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(end_chunk < 1 || end_chunk > num_chunks) {
- fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(start_chunk > end_chunk) {
- fprintf(stderr, "Cycles: End chunk should be higher than start one.\n");
- abort();
- Py_RETURN_NONE;
- }
-
- VLOG(1) << "Initialized resumable render: "
- << "num_resumable_chunks=" << num_chunks << ", "
- << "start_resumable_chunk=" << start_chunk
- << "end_resumable_chunk=" << end_chunk;
- BlenderSession::num_resumable_chunks = num_chunks;
- BlenderSession::start_resumable_chunk = start_chunk;
- BlenderSession::end_resumable_chunk = end_chunk;
-
- printf("Cycles: Will render chunks %d to %d of %d\n",
- start_chunk,
- end_chunk,
- num_chunks);
-
- Py_RETURN_NONE;
+ int num_chunks, start_chunk, end_chunk;
+ if (!PyArg_ParseTuple(args, "iii", &num_chunks, &start_chunk, &end_chunk)) {
+ Py_RETURN_NONE;
+ }
+
+ if (num_chunks <= 0) {
+ fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (start_chunk < 1 || start_chunk > num_chunks) {
+ fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (end_chunk < 1 || end_chunk > num_chunks) {
+ fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (start_chunk > end_chunk) {
+ fprintf(stderr, "Cycles: End chunk should be higher than start one.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+
+ VLOG(1) << "Initialized resumable render: "
+ << "num_resumable_chunks=" << num_chunks << ", "
+ << "start_resumable_chunk=" << start_chunk << "end_resumable_chunk=" << end_chunk;
+ BlenderSession::num_resumable_chunks = num_chunks;
+ BlenderSession::start_resumable_chunk = start_chunk;
+ BlenderSession::end_resumable_chunk = end_chunk;
+
+ printf("Cycles: Will render chunks %d to %d of %d\n", start_chunk, end_chunk, num_chunks);
+
+ Py_RETURN_NONE;
}
static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*/)
{
- BlenderSession::print_render_stats = true;
- Py_RETURN_NONE;
+ BlenderSession::print_render_stats = true;
+ Py_RETURN_NONE;
}
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
{
- vector<DeviceType> device_types = Device::available_types();
- bool has_cuda = false, has_opencl = false;
- foreach(DeviceType device_type, device_types) {
- has_cuda |= (device_type == DEVICE_CUDA);
- has_opencl |= (device_type == DEVICE_OPENCL);
- }
- PyObject *list = PyTuple_New(2);
- PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
- PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_opencl));
- return list;
+ vector<DeviceType> device_types = Device::available_types();
+ bool has_cuda = false, has_opencl = false;
+ foreach (DeviceType device_type, device_types) {
+ has_cuda |= (device_type == DEVICE_CUDA);
+ has_opencl |= (device_type == DEVICE_OPENCL);
+ }
+ PyObject *list = PyTuple_New(2);
+ PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
+ PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_opencl));
+ return list;
}
static PyMethodDef methods[] = {
- {"init", init_func, METH_VARARGS, ""},
- {"exit", exit_func, METH_VARARGS, ""},
- {"create", create_func, METH_VARARGS, ""},
- {"free", free_func, METH_O, ""},
- {"render", render_func, METH_VARARGS, ""},
- {"bake", bake_func, METH_VARARGS, ""},
- {"draw", draw_func, METH_VARARGS, ""},
- {"sync", sync_func, METH_VARARGS, ""},
- {"reset", reset_func, METH_VARARGS, ""},
+ {"init", init_func, METH_VARARGS, ""},
+ {"exit", exit_func, METH_VARARGS, ""},
+ {"create", create_func, METH_VARARGS, ""},
+ {"free", free_func, METH_O, ""},
+ {"render", render_func, METH_VARARGS, ""},
+ {"bake", bake_func, METH_VARARGS, ""},
+ {"draw", draw_func, METH_VARARGS, ""},
+ {"sync", sync_func, METH_VARARGS, ""},
+ {"reset", reset_func, METH_VARARGS, ""},
#ifdef WITH_OSL
- {"osl_update_node", osl_update_node_func, METH_VARARGS, ""},
- {"osl_compile", osl_compile_func, METH_VARARGS, ""},
+ {"osl_update_node", osl_update_node_func, METH_VARARGS, ""},
+ {"osl_compile", osl_compile_func, METH_VARARGS, ""},
#endif
- {"available_devices", available_devices_func, METH_VARARGS, ""},
- {"system_info", system_info_func, METH_NOARGS, ""},
+ {"available_devices", available_devices_func, METH_VARARGS, ""},
+ {"system_info", system_info_func, METH_NOARGS, ""},
#ifdef WITH_OPENCL
- {"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
- {"opencl_compile", opencl_compile_func, METH_VARARGS, ""},
+ {"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
+ {"opencl_compile", opencl_compile_func, METH_VARARGS, ""},
#endif
- /* Standalone denoising */
- {"denoise", (PyCFunction)denoise_func, METH_VARARGS|METH_KEYWORDS, ""},
- {"merge", (PyCFunction)merge_func, METH_VARARGS|METH_KEYWORDS, ""},
+ /* Standalone denoising */
+ {"denoise", (PyCFunction)denoise_func, METH_VARARGS | METH_KEYWORDS, ""},
+ {"merge", (PyCFunction)merge_func, METH_VARARGS | METH_KEYWORDS, ""},
- /* Debugging routines */
- {"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
- {"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""},
+ /* Debugging routines */
+ {"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
+ {"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""},
- /* Statistics. */
- {"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""},
+ /* Statistics. */
+ {"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""},
- /* Resumable render */
- {"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""},
- {"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""},
+ /* Resumable render */
+ {"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""},
+ {"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""},
- /* Compute Device selection */
- {"get_device_types", get_device_types_func, METH_VARARGS, ""},
+ /* Compute Device selection */
+ {"get_device_types", get_device_types_func, METH_VARARGS, ""},
- {NULL, NULL, 0, NULL},
+ {NULL, NULL, 0, NULL},
};
static struct PyModuleDef module = {
- PyModuleDef_HEAD_INIT,
- "_cycles",
- "Blender cycles render integration",
- -1,
- methods,
- NULL, NULL, NULL, NULL,
+ PyModuleDef_HEAD_INIT,
+ "_cycles",
+ "Blender cycles render integration",
+ -1,
+ methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
};
CCL_NAMESPACE_END
void *CCL_python_module_init()
{
- PyObject *mod = PyModule_Create(&ccl::module);
+ PyObject *mod = PyModule_Create(&ccl::module);
#ifdef WITH_OSL
- /* TODO(sergey): This gives us library we've been linking against.
- * In theory with dynamic OSL library it might not be
- * accurate, but there's nothing in OSL API which we
- * might use to get version in runtime.
- */
- int curversion = OSL_LIBRARY_VERSION_CODE;
- PyModule_AddObject(mod, "with_osl", Py_True);
- Py_INCREF(Py_True);
- PyModule_AddObject(mod, "osl_version",
- Py_BuildValue("(iii)",
- curversion / 10000, (curversion / 100) % 100, curversion % 100));
- PyModule_AddObject(mod, "osl_version_string",
- PyUnicode_FromFormat("%2d, %2d, %2d",
- curversion / 10000, (curversion / 100) % 100, curversion % 100));
+ /* TODO(sergey): This gives us library we've been linking against.
+ * In theory with dynamic OSL library it might not be
+ * accurate, but there's nothing in OSL API which we
+ * might use to get version in runtime.
+ */
+ int curversion = OSL_LIBRARY_VERSION_CODE;
+ PyModule_AddObject(mod, "with_osl", Py_True);
+ Py_INCREF(Py_True);
+ PyModule_AddObject(
+ mod,
+ "osl_version",
+ Py_BuildValue("(iii)", curversion / 10000, (curversion / 100) % 100, curversion % 100));
+ PyModule_AddObject(
+ mod,
+ "osl_version_string",
+ PyUnicode_FromFormat(
+ "%2d, %2d, %2d", curversion / 10000, (curversion / 100) % 100, curversion % 100));
#else
- PyModule_AddObject(mod, "with_osl", Py_False);
- Py_INCREF(Py_False);
- PyModule_AddStringConstant(mod, "osl_version", "unknown");
- PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
+ PyModule_AddObject(mod, "with_osl", Py_False);
+ Py_INCREF(Py_False);
+ PyModule_AddStringConstant(mod, "osl_version", "unknown");
+ PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
#endif
#ifdef WITH_CYCLES_DEBUG
- PyModule_AddObject(mod, "with_cycles_debug", Py_True);
- Py_INCREF(Py_True);
+ PyModule_AddObject(mod, "with_cycles_debug", Py_True);
+ Py_INCREF(Py_True);
#else
- PyModule_AddObject(mod, "with_cycles_debug", Py_False);
- Py_INCREF(Py_False);
+ PyModule_AddObject(mod, "with_cycles_debug", Py_False);
+ Py_INCREF(Py_False);
#endif
#ifdef WITH_NETWORK
- PyModule_AddObject(mod, "with_network", Py_True);
- Py_INCREF(Py_True);
+ PyModule_AddObject(mod, "with_network", Py_True);
+ Py_INCREF(Py_True);
#else /* WITH_NETWORK */
- PyModule_AddObject(mod, "with_network", Py_False);
- Py_INCREF(Py_False);
-#endif /* WITH_NETWORK */
+ PyModule_AddObject(mod, "with_network", Py_False);
+ Py_INCREF(Py_False);
+#endif /* WITH_NETWORK */
#ifdef WITH_EMBREE
- PyModule_AddObject(mod, "with_embree", Py_True);
- Py_INCREF(Py_True);
+ PyModule_AddObject(mod, "with_embree", Py_True);
+ Py_INCREF(Py_True);
#else /* WITH_EMBREE */
- PyModule_AddObject(mod, "with_embree", Py_False);
- Py_INCREF(Py_False);
-#endif /* WITH_EMBREE */
+ PyModule_AddObject(mod, "with_embree", Py_False);
+ Py_INCREF(Py_False);
+#endif /* WITH_EMBREE */
- return (void*)mod;
+ return (void *)mod;
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index cf856c3b3d4..29a97bf6546 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -53,1051 +53,1070 @@ int BlenderSession::start_resumable_chunk = 0;
int BlenderSession::end_resumable_chunk = 0;
bool BlenderSession::print_render_stats = false;
-BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
+BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
bool preview_osl)
-: session(NULL),
- sync(NULL),
- b_engine(b_engine),
- b_userpref(b_userpref),
- b_data(b_data),
- b_render(b_engine.render()),
- b_depsgraph(PointerRNA_NULL),
- b_scene(PointerRNA_NULL),
- b_v3d(PointerRNA_NULL),
- b_rv3d(PointerRNA_NULL),
- width(0),
- height(0),
- preview_osl(preview_osl),
- python_thread_state(NULL)
+ : session(NULL),
+ sync(NULL),
+ b_engine(b_engine),
+ b_userpref(b_userpref),
+ b_data(b_data),
+ b_render(b_engine.render()),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
+ b_v3d(PointerRNA_NULL),
+ b_rv3d(PointerRNA_NULL),
+ width(0),
+ height(0),
+ preview_osl(preview_osl),
+ python_thread_state(NULL)
{
- /* offline render */
- background = true;
- last_redraw_time = 0.0;
- start_resize_time = 0.0;
- last_status_time = 0.0;
+ /* offline render */
+ background = true;
+ last_redraw_time = 0.0;
+ start_resize_time = 0.0;
+ last_status_time = 0.0;
}
-BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height)
-: session(NULL),
- sync(NULL),
- b_engine(b_engine),
- b_userpref(b_userpref),
- b_data(b_data),
- b_render(b_engine.render()),
- b_depsgraph(PointerRNA_NULL),
- b_scene(PointerRNA_NULL),
- b_v3d(b_v3d),
- b_rv3d(b_rv3d),
- width(width),
- height(height),
- preview_osl(false),
- python_thread_state(NULL)
+BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height)
+ : session(NULL),
+ sync(NULL),
+ b_engine(b_engine),
+ b_userpref(b_userpref),
+ b_data(b_data),
+ b_render(b_engine.render()),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
+ b_v3d(b_v3d),
+ b_rv3d(b_rv3d),
+ width(width),
+ height(height),
+ preview_osl(false),
+ python_thread_state(NULL)
{
- /* 3d view render */
- background = false;
- last_redraw_time = 0.0;
- start_resize_time = 0.0;
- last_status_time = 0.0;
+ /* 3d view render */
+ background = false;
+ last_redraw_time = 0.0;
+ start_resize_time = 0.0;
+ last_status_time = 0.0;
}
BlenderSession::~BlenderSession()
{
- free_session();
+ free_session();
}
void BlenderSession::create()
{
- create_session();
+ create_session();
}
void BlenderSession::create_session()
{
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- bool session_pause = BlenderSync::get_session_pause(b_scene, background);
-
- /* reset status/progress */
- last_status = "";
- last_error = "";
- last_progress = -1.0f;
- start_resize_time = 0.0;
-
- /* create session */
- session = new Session(session_params);
- session->scene = scene;
- session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this));
- session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this));
- session->set_pause(session_pause);
-
- /* create scene */
- scene = new Scene(scene_params, session->device);
- scene->name = b_scene.name();
-
- /* setup callbacks for builtin image support */
- scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3);
- scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5);
- scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5);
-
- session->scene = scene;
-
- /* There is no single depsgraph to use for the entire render.
- * So we need to handle this differently.
- *
- * We could loop over the final render result render layers in pipeline and keep Cycles unaware of multiple layers,
- * or perhaps move syncing further down in the pipeline.
- */
- /* create sync */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
- BL::Object b_camera_override(b_engine.camera_override());
- if(b_v3d) {
- sync->sync_view(b_v3d, b_rv3d, width, height);
- }
- else {
- sync->sync_camera(b_render, b_camera_override, width, height, "");
- }
-
- /* set buffer parameters */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
- session->reset(buffer_params, session_params.samples);
-
- b_engine.use_highlight_tiles(session_params.progressive_refine == false);
-
- update_resumable_tile_manager(session_params.samples);
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
+
+ /* reset status/progress */
+ last_status = "";
+ last_error = "";
+ last_progress = -1.0f;
+ start_resize_time = 0.0;
+
+ /* create session */
+ session = new Session(session_params);
+ session->scene = scene;
+ session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this));
+ session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this));
+ session->set_pause(session_pause);
+
+ /* create scene */
+ scene = new Scene(scene_params, session->device);
+ scene->name = b_scene.name();
+
+ /* setup callbacks for builtin image support */
+ scene->image_manager->builtin_image_info_cb = function_bind(
+ &BlenderSession::builtin_image_info, this, _1, _2, _3);
+ scene->image_manager->builtin_image_pixels_cb = function_bind(
+ &BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5);
+ scene->image_manager->builtin_image_float_pixels_cb = function_bind(
+ &BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5);
+
+ session->scene = scene;
+
+ /* There is no single depsgraph to use for the entire render.
+ * So we need to handle this differently.
+ *
+ * We could loop over the final render result render layers in pipeline and keep Cycles unaware of multiple layers,
+ * or perhaps move syncing further down in the pipeline.
+ */
+ /* create sync */
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+ BL::Object b_camera_override(b_engine.camera_override());
+ if (b_v3d) {
+ sync->sync_view(b_v3d, b_rv3d, width, height);
+ }
+ else {
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
+ }
+
+ /* set buffer parameters */
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
+
+ update_resumable_tile_manager(session_params.samples);
}
-void BlenderSession::reset_session(BL::BlendData& b_data, BL::Depsgraph& b_depsgraph)
+void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph)
{
- this->b_data = b_data;
- this->b_depsgraph = b_depsgraph;
- this->b_scene = b_depsgraph.scene_eval();
-
- if(preview_osl) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- RNA_boolean_set(&cscene, "shading_system", preview_osl);
- }
-
- if(b_v3d) {
- this->b_render = b_scene.render();
- }
- else {
- this->b_render = b_engine.render();
- width = render_resolution_x(b_render);
- height = render_resolution_y(b_render);
- }
-
- if(session == NULL) {
- create();
- }
-
- if(b_v3d) {
- /* NOTE: We need to create session, but all the code from below
- * will make viewport render to stuck on initialization.
- */
- return;
- }
-
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
-
- if(scene->params.modified(scene_params) ||
- session->params.modified(session_params) ||
- !scene_params.persistent_data)
- {
- /* if scene or session parameters changed, it's easier to simply re-create
- * them rather than trying to distinguish which settings need to be updated
- */
- free_session();
- create_session();
- return;
- }
-
- session->progress.reset();
- scene->reset();
-
- session->tile_manager.set_tile_order(session_params.tile_order);
-
- /* peak memory usage should show current render peak, not peak for all renders
- * made by this render session
- */
- session->stats.mem_peak = session->stats.mem_used;
-
- /* There is no single depsgraph to use for the entire render.
- * See note on create_session().
- */
- /* sync object should be re-created */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
-
- BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
- BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render,
- b_null_space_view3d,
- b_null_region_view3d,
- scene->camera,
- width, height);
- session->reset(buffer_params, session_params.samples);
-
- b_engine.use_highlight_tiles(session_params.progressive_refine == false);
-
- /* reset time */
- start_resize_time = 0.0;
+ this->b_data = b_data;
+ this->b_depsgraph = b_depsgraph;
+ this->b_scene = b_depsgraph.scene_eval();
+
+ if (preview_osl) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ RNA_boolean_set(&cscene, "shading_system", preview_osl);
+ }
+
+ if (b_v3d) {
+ this->b_render = b_scene.render();
+ }
+ else {
+ this->b_render = b_engine.render();
+ width = render_resolution_x(b_render);
+ height = render_resolution_y(b_render);
+ }
+
+ if (session == NULL) {
+ create();
+ }
+
+ if (b_v3d) {
+ /* NOTE: We need to create session, but all the code from below
+ * will make viewport render to stuck on initialization.
+ */
+ return;
+ }
+
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+
+ if (scene->params.modified(scene_params) || session->params.modified(session_params) ||
+ !scene_params.persistent_data) {
+ /* if scene or session parameters changed, it's easier to simply re-create
+ * them rather than trying to distinguish which settings need to be updated
+ */
+ free_session();
+ create_session();
+ return;
+ }
+
+ session->progress.reset();
+ scene->reset();
+
+ session->tile_manager.set_tile_order(session_params.tile_order);
+
+ /* peak memory usage should show current render peak, not peak for all renders
+ * made by this render session
+ */
+ session->stats.mem_peak = session->stats.mem_used;
+
+ /* There is no single depsgraph to use for the entire render.
+ * See note on create_session().
+ */
+ /* sync object should be re-created */
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+
+ BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
+ BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_null_space_view3d, b_null_region_view3d, scene->camera, width, height);
+ session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
+
+ /* reset time */
+ start_resize_time = 0.0;
}
void BlenderSession::free_session()
{
- if(sync)
- delete sync;
+ if (sync)
+ delete sync;
- delete session;
+ delete session;
}
-static ShaderEvalType get_shader_type(const string& pass_type)
+static ShaderEvalType get_shader_type(const string &pass_type)
{
- const char *shader_type = pass_type.c_str();
-
- /* data passes */
- if(strcmp(shader_type, "NORMAL")==0)
- return SHADER_EVAL_NORMAL;
- else if(strcmp(shader_type, "UV")==0)
- return SHADER_EVAL_UV;
- else if(strcmp(shader_type, "ROUGHNESS")==0)
- return SHADER_EVAL_ROUGHNESS;
- else if(strcmp(shader_type, "DIFFUSE_COLOR")==0)
- return SHADER_EVAL_DIFFUSE_COLOR;
- else if(strcmp(shader_type, "GLOSSY_COLOR")==0)
- return SHADER_EVAL_GLOSSY_COLOR;
- else if(strcmp(shader_type, "TRANSMISSION_COLOR")==0)
- return SHADER_EVAL_TRANSMISSION_COLOR;
- else if(strcmp(shader_type, "SUBSURFACE_COLOR")==0)
- return SHADER_EVAL_SUBSURFACE_COLOR;
- else if(strcmp(shader_type, "EMIT")==0)
- return SHADER_EVAL_EMISSION;
-
- /* light passes */
- else if(strcmp(shader_type, "AO")==0)
- return SHADER_EVAL_AO;
- else if(strcmp(shader_type, "COMBINED")==0)
- return SHADER_EVAL_COMBINED;
- else if(strcmp(shader_type, "SHADOW")==0)
- return SHADER_EVAL_SHADOW;
- else if(strcmp(shader_type, "DIFFUSE")==0)
- return SHADER_EVAL_DIFFUSE;
- else if(strcmp(shader_type, "GLOSSY")==0)
- return SHADER_EVAL_GLOSSY;
- else if(strcmp(shader_type, "TRANSMISSION")==0)
- return SHADER_EVAL_TRANSMISSION;
- else if(strcmp(shader_type, "SUBSURFACE")==0)
- return SHADER_EVAL_SUBSURFACE;
-
- /* extra */
- else if(strcmp(shader_type, "ENVIRONMENT")==0)
- return SHADER_EVAL_ENVIRONMENT;
-
- else
- return SHADER_EVAL_BAKE;
+ const char *shader_type = pass_type.c_str();
+
+ /* data passes */
+ if (strcmp(shader_type, "NORMAL") == 0)
+ return SHADER_EVAL_NORMAL;
+ else if (strcmp(shader_type, "UV") == 0)
+ return SHADER_EVAL_UV;
+ else if (strcmp(shader_type, "ROUGHNESS") == 0)
+ return SHADER_EVAL_ROUGHNESS;
+ else if (strcmp(shader_type, "DIFFUSE_COLOR") == 0)
+ return SHADER_EVAL_DIFFUSE_COLOR;
+ else if (strcmp(shader_type, "GLOSSY_COLOR") == 0)
+ return SHADER_EVAL_GLOSSY_COLOR;
+ else if (strcmp(shader_type, "TRANSMISSION_COLOR") == 0)
+ return SHADER_EVAL_TRANSMISSION_COLOR;
+ else if (strcmp(shader_type, "SUBSURFACE_COLOR") == 0)
+ return SHADER_EVAL_SUBSURFACE_COLOR;
+ else if (strcmp(shader_type, "EMIT") == 0)
+ return SHADER_EVAL_EMISSION;
+
+ /* light passes */
+ else if (strcmp(shader_type, "AO") == 0)
+ return SHADER_EVAL_AO;
+ else if (strcmp(shader_type, "COMBINED") == 0)
+ return SHADER_EVAL_COMBINED;
+ else if (strcmp(shader_type, "SHADOW") == 0)
+ return SHADER_EVAL_SHADOW;
+ else if (strcmp(shader_type, "DIFFUSE") == 0)
+ return SHADER_EVAL_DIFFUSE;
+ else if (strcmp(shader_type, "GLOSSY") == 0)
+ return SHADER_EVAL_GLOSSY;
+ else if (strcmp(shader_type, "TRANSMISSION") == 0)
+ return SHADER_EVAL_TRANSMISSION;
+ else if (strcmp(shader_type, "SUBSURFACE") == 0)
+ return SHADER_EVAL_SUBSURFACE;
+
+ /* extra */
+ else if (strcmp(shader_type, "ENVIRONMENT") == 0)
+ return SHADER_EVAL_ENVIRONMENT;
+
+ else
+ return SHADER_EVAL_BAKE;
}
-static BL::RenderResult begin_render_result(BL::RenderEngine& b_engine,
- int x, int y,
- int w, int h,
+static BL::RenderResult begin_render_result(BL::RenderEngine &b_engine,
+ int x,
+ int y,
+ int w,
+ int h,
const char *layername,
const char *viewname)
{
- return b_engine.begin_result(x, y, w, h, layername, viewname);
+ return b_engine.begin_result(x, y, w, h, layername, viewname);
}
-static void end_render_result(BL::RenderEngine& b_engine,
- BL::RenderResult& b_rr,
+static void end_render_result(BL::RenderEngine &b_engine,
+ BL::RenderResult &b_rr,
bool cancel,
bool highlight,
bool do_merge_results)
{
- b_engine.end_result(b_rr, (int)cancel, (int) highlight, (int)do_merge_results);
+ b_engine.end_result(b_rr, (int)cancel, (int)highlight, (int)do_merge_results);
}
-void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight)
+void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
+ bool do_update_only,
+ bool highlight)
{
- int x = rtile.x - session->tile_manager.params.full_x;
- int y = rtile.y - session->tile_manager.params.full_y;
- int w = rtile.w;
- int h = rtile.h;
-
- /* get render result */
- BL::RenderResult b_rr = begin_render_result(b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str());
-
- /* can happen if the intersected rectangle gives 0 width or height */
- if(b_rr.ptr.data == NULL) {
- return;
- }
-
- BL::RenderResult::layers_iterator b_single_rlay;
- b_rr.layers.begin(b_single_rlay);
-
- /* layer will be missing if it was disabled in the UI */
- if(b_single_rlay == b_rr.layers.end())
- return;
-
- BL::RenderLayer b_rlay = *b_single_rlay;
-
- if(do_update_only) {
- /* Sample would be zero at initial tile update, which is only needed
- * to tag tile form blender side as IN PROGRESS for proper highlight
- * no buffers should be sent to blender yet. For denoise we also
- * keep showing the noisy buffers until denoise is done. */
- bool merge = (rtile.sample != 0) && (rtile.task != RenderTile::DENOISE);
-
- if(merge) {
- update_render_result(b_rr, b_rlay, rtile);
- }
-
- end_render_result(b_engine, b_rr, true, highlight, merge);
- }
- else {
- /* Write final render result. */
- write_render_result(b_rr, b_rlay, rtile);
- end_render_result(b_engine, b_rr, false, false, true);
- }
+ int x = rtile.x - session->tile_manager.params.full_x;
+ int y = rtile.y - session->tile_manager.params.full_y;
+ int w = rtile.w;
+ int h = rtile.h;
+
+ /* get render result */
+ BL::RenderResult b_rr = begin_render_result(
+ b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str());
+
+ /* can happen if the intersected rectangle gives 0 width or height */
+ if (b_rr.ptr.data == NULL) {
+ return;
+ }
+
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+
+ /* layer will be missing if it was disabled in the UI */
+ if (b_single_rlay == b_rr.layers.end())
+ return;
+
+ BL::RenderLayer b_rlay = *b_single_rlay;
+
+ if (do_update_only) {
+ /* Sample would be zero at initial tile update, which is only needed
+ * to tag tile form blender side as IN PROGRESS for proper highlight
+ * no buffers should be sent to blender yet. For denoise we also
+ * keep showing the noisy buffers until denoise is done. */
+ bool merge = (rtile.sample != 0) && (rtile.task != RenderTile::DENOISE);
+
+ if (merge) {
+ update_render_result(b_rr, b_rlay, rtile);
+ }
+
+ end_render_result(b_engine, b_rr, true, highlight, merge);
+ }
+ else {
+ /* Write final render result. */
+ write_render_result(b_rr, b_rlay, rtile);
+ end_render_result(b_engine, b_rr, false, false, true);
+ }
}
-void BlenderSession::write_render_tile(RenderTile& rtile)
+void BlenderSession::write_render_tile(RenderTile &rtile)
{
- do_write_update_render_tile(rtile, false, false);
+ do_write_update_render_tile(rtile, false, false);
}
-void BlenderSession::update_render_tile(RenderTile& rtile, bool highlight)
+void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight)
{
- /* use final write for preview renders, otherwise render result wouldn't be
- * be updated in blender side
- * would need to be investigated a bit further, but for now shall be fine
- */
- if(!b_engine.is_preview())
- do_write_update_render_tile(rtile, true, highlight);
- else
- do_write_update_render_tile(rtile, false, false);
+ /* use final write for preview renders, otherwise render result wouldn't be
+ * be updated in blender side
+ * would need to be investigated a bit further, but for now shall be fine
+ */
+ if (!b_engine.is_preview())
+ do_write_update_render_tile(rtile, true, highlight);
+ else
+ do_write_update_render_tile(rtile, false, false);
}
-static void add_cryptomatte_layer(BL::RenderResult& b_rr, string name, string manifest)
+static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest)
{
- string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0));
- string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/";
+ string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0));
+ string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/";
- render_add_metadata(b_rr, prefix+"name", name);
- render_add_metadata(b_rr, prefix+"hash", "MurmurHash3_32");
- render_add_metadata(b_rr, prefix+"conversion", "uint32_to_float32");
- render_add_metadata(b_rr, prefix+"manifest", manifest);
+ render_add_metadata(b_rr, prefix + "name", name);
+ render_add_metadata(b_rr, prefix + "hash", "MurmurHash3_32");
+ render_add_metadata(b_rr, prefix + "conversion", "uint32_to_float32");
+ render_add_metadata(b_rr, prefix + "manifest", manifest);
}
-void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string& view_layer_name)
+void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string &view_layer_name)
{
- BL::RenderResult b_rr = b_engine.get_result();
- string prefix = "cycles." + view_layer_name + ".";
-
- /* Configured number of samples for the view layer. */
- b_rr.stamp_data_add_field(
- (prefix + "samples").c_str(),
- to_string(session->params.samples).c_str());
-
- /* Store ranged samples information. */
- if(session->tile_manager.range_num_samples != -1) {
- b_rr.stamp_data_add_field(
- (prefix + "range_start_sample").c_str(),
- to_string(session->tile_manager.range_start_sample).c_str());
- b_rr.stamp_data_add_field(
- (prefix + "range_num_samples").c_str(),
- to_string(session->tile_manager.range_num_samples).c_str());
- }
-
- /* Write cryptomatte metadata. */
- if(scene->film->cryptomatte_passes & CRYPT_OBJECT) {
- add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoObject",
- scene->object_manager->get_cryptomatte_objects(scene));
- }
- if(scene->film->cryptomatte_passes & CRYPT_MATERIAL) {
- add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoMaterial",
- scene->shader_manager->get_cryptomatte_materials(scene));
- }
- if(scene->film->cryptomatte_passes & CRYPT_ASSET) {
- add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoAsset",
- scene->object_manager->get_cryptomatte_assets(scene));
- }
-
- /* Store synchronization and bare-render times. */
- double total_time, render_time;
- session->progress.get_time(total_time, render_time);
- b_rr.stamp_data_add_field((prefix + "total_time").c_str(),
- time_human_readable_from_seconds(total_time).c_str());
- b_rr.stamp_data_add_field((prefix + "render_time").c_str(),
- time_human_readable_from_seconds(render_time).c_str());
- b_rr.stamp_data_add_field((prefix + "synchronization_time").c_str(),
- time_human_readable_from_seconds(total_time - render_time).c_str());
+ BL::RenderResult b_rr = b_engine.get_result();
+ string prefix = "cycles." + view_layer_name + ".";
+
+ /* Configured number of samples for the view layer. */
+ b_rr.stamp_data_add_field((prefix + "samples").c_str(),
+ to_string(session->params.samples).c_str());
+
+ /* Store ranged samples information. */
+ if (session->tile_manager.range_num_samples != -1) {
+ b_rr.stamp_data_add_field((prefix + "range_start_sample").c_str(),
+ to_string(session->tile_manager.range_start_sample).c_str());
+ b_rr.stamp_data_add_field((prefix + "range_num_samples").c_str(),
+ to_string(session->tile_manager.range_num_samples).c_str());
+ }
+
+ /* Write cryptomatte metadata. */
+ if (scene->film->cryptomatte_passes & CRYPT_OBJECT) {
+ add_cryptomatte_layer(b_rr,
+ view_layer_name + ".CryptoObject",
+ scene->object_manager->get_cryptomatte_objects(scene));
+ }
+ if (scene->film->cryptomatte_passes & CRYPT_MATERIAL) {
+ add_cryptomatte_layer(b_rr,
+ view_layer_name + ".CryptoMaterial",
+ scene->shader_manager->get_cryptomatte_materials(scene));
+ }
+ if (scene->film->cryptomatte_passes & CRYPT_ASSET) {
+ add_cryptomatte_layer(b_rr,
+ view_layer_name + ".CryptoAsset",
+ scene->object_manager->get_cryptomatte_assets(scene));
+ }
+
+ /* Store synchronization and bare-render times. */
+ double total_time, render_time;
+ session->progress.get_time(total_time, render_time);
+ b_rr.stamp_data_add_field((prefix + "total_time").c_str(),
+ time_human_readable_from_seconds(total_time).c_str());
+ b_rr.stamp_data_add_field((prefix + "render_time").c_str(),
+ time_human_readable_from_seconds(render_time).c_str());
+ b_rr.stamp_data_add_field((prefix + "synchronization_time").c_str(),
+ time_human_readable_from_seconds(total_time - render_time).c_str());
}
-void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
+void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
{
- b_depsgraph = b_depsgraph_;
-
- /* set callback to write out render results */
- session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
- session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1, _2);
-
- /* get buffer parameters */
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
-
- /* render each layer */
- BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
-
- /* temporary render result to find needed passes and views */
- BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
- BL::RenderResult::layers_iterator b_single_rlay;
- b_rr.layers.begin(b_single_rlay);
- BL::RenderLayer b_rlay = *b_single_rlay;
- b_rlay_name = b_view_layer.name();
-
- /* add passes */
- vector<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer);
- buffer_params.passes = passes;
-
- PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
- bool full_denoising = get_boolean(crl, "use_denoising");
- bool write_denoising_passes = get_boolean(crl, "denoising_store_passes");
-
- bool run_denoising = full_denoising || write_denoising_passes;
-
- session->tile_manager.schedule_denoising = run_denoising;
- buffer_params.denoising_data_pass = run_denoising;
- buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
- buffer_params.denoising_prefiltered_pass = write_denoising_passes;
-
- session->params.run_denoising = run_denoising;
- session->params.full_denoising = full_denoising;
- session->params.write_denoising_passes = write_denoising_passes;
- session->params.denoising.radius = get_int(crl, "denoising_radius");
- session->params.denoising.strength = get_float(crl, "denoising_strength");
- session->params.denoising.feature_strength = get_float(crl, "denoising_feature_strength");
- session->params.denoising.relative_pca = get_boolean(crl, "denoising_relative_pca");
-
- scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
- scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
- scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass;
-
- scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
- scene->film->tag_passes_update(scene, passes);
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
-
- BL::RenderResult::views_iterator b_view_iter;
-
- int num_views = 0;
- for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter) {
- num_views++;
- }
-
- int view_index = 0;
- for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter, ++view_index) {
- b_rview_name = b_view_iter->name();
-
- /* set the current view */
- b_engine.active_view_set(b_rview_name.c_str());
-
- /* update scene */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
- sync->sync_data(b_render,
- b_depsgraph,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state);
- builtin_images_load();
-
- /* Attempt to free all data which is held by Blender side, since at this
- * point we knwo that we've got everything to render current view layer.
- */
- /* At the moment we only free if we are not doing multi-view (or if we are rendering the last view).
- * See T58142/D4239 for discussion.
- */
- if(view_index == num_views - 1) {
- free_blender_memory_if_possible();
- }
-
- /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
- if(view_index != 0) {
- scene->integrator->seed += hash_int_2d(scene->integrator->seed, hash_int(view_index * 0xdeadbeef));
- scene->integrator->tag_update(scene);
- }
-
- /* Update number of samples per layer. */
- int samples = sync->get_layer_samples();
- bool bound_samples = sync->get_layer_bound_samples();
- int effective_layer_samples;
-
- if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
- effective_layer_samples = samples;
- else
- effective_layer_samples = session_params.samples;
-
- /* Update tile manager if we're doing resumable render. */
- update_resumable_tile_manager(effective_layer_samples);
-
- /* Update session itself. */
- session->reset(buffer_params, effective_layer_samples);
-
- /* render */
- session->start();
- session->wait();
-
- if(!b_engine.is_preview() && background && print_render_stats) {
- RenderStats stats;
- session->collect_statistics(&stats);
- printf("Render statistics:\n%s\n", stats.full_report().c_str());
- }
-
- if(session->progress.get_cancel())
- break;
- }
-
- /* add metadata */
- stamp_view_layer_metadata(scene, b_rlay_name);
-
- /* free result without merging */
- end_render_result(b_engine, b_rr, true, true, false);
-
- double total_time, render_time;
- session->progress.get_time(total_time, render_time);
- VLOG(1) << "Total render time: " << total_time;
- VLOG(1) << "Render time (without synchronization): " << render_time;
-
- /* clear callback */
- session->write_render_tile_cb = function_null;
- session->update_render_tile_cb = function_null;
-
- /* TODO: find a way to clear this data for persistent data render */
+ b_depsgraph = b_depsgraph_;
+
+ /* set callback to write out render results */
+ session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
+ session->update_render_tile_cb = function_bind(
+ &BlenderSession::update_render_tile, this, _1, _2);
+
+ /* get buffer parameters */
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+
+ /* render each layer */
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
+ /* temporary render result to find needed passes and views */
+ BL::RenderResult b_rr = begin_render_result(
+ b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+ BL::RenderLayer b_rlay = *b_single_rlay;
+ b_rlay_name = b_view_layer.name();
+
+ /* add passes */
+ vector<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer);
+ buffer_params.passes = passes;
+
+ PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
+ bool full_denoising = get_boolean(crl, "use_denoising");
+ bool write_denoising_passes = get_boolean(crl, "denoising_store_passes");
+
+ bool run_denoising = full_denoising || write_denoising_passes;
+
+ session->tile_manager.schedule_denoising = run_denoising;
+ buffer_params.denoising_data_pass = run_denoising;
+ buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
+ buffer_params.denoising_prefiltered_pass = write_denoising_passes;
+
+ session->params.run_denoising = run_denoising;
+ session->params.full_denoising = full_denoising;
+ session->params.write_denoising_passes = write_denoising_passes;
+ session->params.denoising.radius = get_int(crl, "denoising_radius");
+ session->params.denoising.strength = get_float(crl, "denoising_strength");
+ session->params.denoising.feature_strength = get_float(crl, "denoising_feature_strength");
+ session->params.denoising.relative_pca = get_boolean(crl, "denoising_relative_pca");
+
+ scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
+ scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
+ scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass;
+
+ scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
+ scene->film->tag_passes_update(scene, passes);
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
+ BL::RenderResult::views_iterator b_view_iter;
+
+ int num_views = 0;
+ for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter) {
+ num_views++;
+ }
+
+ int view_index = 0;
+ for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end();
+ ++b_view_iter, ++view_index) {
+ b_rview_name = b_view_iter->name();
+
+ /* set the current view */
+ b_engine.active_view_set(b_rview_name.c_str());
+
+ /* update scene */
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
+ sync->sync_data(
+ b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
+ builtin_images_load();
+
+ /* Attempt to free all data which is held by Blender side, since at this
+ * point we knwo that we've got everything to render current view layer.
+ */
+ /* At the moment we only free if we are not doing multi-view (or if we are rendering the last view).
+ * See T58142/D4239 for discussion.
+ */
+ if (view_index == num_views - 1) {
+ free_blender_memory_if_possible();
+ }
+
+ /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
+ if (view_index != 0) {
+ scene->integrator->seed += hash_int_2d(scene->integrator->seed,
+ hash_int(view_index * 0xdeadbeef));
+ scene->integrator->tag_update(scene);
+ }
+
+ /* Update number of samples per layer. */
+ int samples = sync->get_layer_samples();
+ bool bound_samples = sync->get_layer_bound_samples();
+ int effective_layer_samples;
+
+ if (samples != 0 && (!bound_samples || (samples < session_params.samples)))
+ effective_layer_samples = samples;
+ else
+ effective_layer_samples = session_params.samples;
+
+ /* Update tile manager if we're doing resumable render. */
+ update_resumable_tile_manager(effective_layer_samples);
+
+ /* Update session itself. */
+ session->reset(buffer_params, effective_layer_samples);
+
+ /* render */
+ session->start();
+ session->wait();
+
+ if (!b_engine.is_preview() && background && print_render_stats) {
+ RenderStats stats;
+ session->collect_statistics(&stats);
+ printf("Render statistics:\n%s\n", stats.full_report().c_str());
+ }
+
+ if (session->progress.get_cancel())
+ break;
+ }
+
+ /* add metadata */
+ stamp_view_layer_metadata(scene, b_rlay_name);
+
+ /* free result without merging */
+ end_render_result(b_engine, b_rr, true, true, false);
+
+ double total_time, render_time;
+ session->progress.get_time(total_time, render_time);
+ VLOG(1) << "Total render time: " << total_time;
+ VLOG(1) << "Render time (without synchronization): " << render_time;
+
+ /* clear callback */
+ session->write_render_tile_cb = function_null;
+ session->update_render_tile_cb = function_null;
+
+ /* TODO: find a way to clear this data for persistent data render */
#if 0
- /* free all memory used (host and device), so we wouldn't leave render
- * engine with extra memory allocated
- */
+ /* free all memory used (host and device), so we wouldn't leave render
+ * engine with extra memory allocated
+ */
- session->device_free();
+ session->device_free();
- delete sync;
- sync = NULL;
+ delete sync;
+ sync = NULL;
#endif
}
-static void populate_bake_data(BakeData *data, const
- int object_id,
- BL::BakePixel& pixel_array,
+static void populate_bake_data(BakeData *data,
+ const int object_id,
+ BL::BakePixel &pixel_array,
const int num_pixels)
{
- BL::BakePixel bp = pixel_array;
-
- int i;
- for(i = 0; i < num_pixels; i++) {
- if(bp.object_id() == object_id) {
- data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy());
- } else {
- data->set_null(i);
- }
- bp = bp.next();
- }
+ BL::BakePixel bp = pixel_array;
+
+ int i;
+ for (i = 0; i < num_pixels; i++) {
+ if (bp.object_id() == object_id) {
+ data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy());
+ }
+ else {
+ data->set_null(i);
+ }
+ bp = bp.next();
+ }
}
static int bake_pass_filter_get(const int pass_filter)
{
- int flag = BAKE_FILTER_NONE;
-
- if((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0)
- flag |= BAKE_FILTER_DIRECT;
- if((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0)
- flag |= BAKE_FILTER_INDIRECT;
- if((pass_filter & BL::BakeSettings::pass_filter_COLOR) != 0)
- flag |= BAKE_FILTER_COLOR;
-
- if((pass_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0)
- flag |= BAKE_FILTER_DIFFUSE;
- if((pass_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0)
- flag |= BAKE_FILTER_GLOSSY;
- if((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0)
- flag |= BAKE_FILTER_TRANSMISSION;
- if((pass_filter & BL::BakeSettings::pass_filter_SUBSURFACE) != 0)
- flag |= BAKE_FILTER_SUBSURFACE;
-
- if((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0)
- flag |= BAKE_FILTER_EMISSION;
- if((pass_filter & BL::BakeSettings::pass_filter_AO) != 0)
- flag |= BAKE_FILTER_AO;
-
- return flag;
+ int flag = BAKE_FILTER_NONE;
+
+ if ((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0)
+ flag |= BAKE_FILTER_DIRECT;
+ if ((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0)
+ flag |= BAKE_FILTER_INDIRECT;
+ if ((pass_filter & BL::BakeSettings::pass_filter_COLOR) != 0)
+ flag |= BAKE_FILTER_COLOR;
+
+ if ((pass_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0)
+ flag |= BAKE_FILTER_DIFFUSE;
+ if ((pass_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0)
+ flag |= BAKE_FILTER_GLOSSY;
+ if ((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0)
+ flag |= BAKE_FILTER_TRANSMISSION;
+ if ((pass_filter & BL::BakeSettings::pass_filter_SUBSURFACE) != 0)
+ flag |= BAKE_FILTER_SUBSURFACE;
+
+ if ((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0)
+ flag |= BAKE_FILTER_EMISSION;
+ if ((pass_filter & BL::BakeSettings::pass_filter_AO) != 0)
+ flag |= BAKE_FILTER_AO;
+
+ return flag;
}
-void BlenderSession::bake(BL::Depsgraph& b_depsgraph_,
- BL::Object& b_object,
- const string& pass_type,
+void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
+ BL::Object &b_object,
+ const string &pass_type,
const int pass_filter,
const int object_id,
- BL::BakePixel& pixel_array,
+ BL::BakePixel &pixel_array,
const size_t num_pixels,
const int /*depth*/,
float result[])
{
- b_depsgraph = b_depsgraph_;
-
- ShaderEvalType shader_type = get_shader_type(pass_type);
-
- /* Set baking flag in advance, so kernel loading can check if we need
- * any baking capabilities.
- */
- scene->bake_manager->set_baking(true);
-
- /* ensure kernels are loaded before we do any scene updates */
- session->load_kernels();
-
- if(shader_type == SHADER_EVAL_UV) {
- /* force UV to be available */
- Pass::add(PASS_UV, scene->film->passes);
- }
-
- int bake_pass_filter = bake_pass_filter_get(pass_filter);
- bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter);
-
- /* force use_light_pass to be true if we bake more than just colors */
- if(bake_pass_filter & ~BAKE_FILTER_COLOR) {
- Pass::add(PASS_LIGHT, scene->film->passes);
- }
-
- /* create device and update scene */
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
-
- if(!session->progress.get_cancel()) {
- /* update scene */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height, "");
- sync->sync_data(b_render,
- b_depsgraph,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state);
- builtin_images_load();
- }
-
- BakeData *bake_data = NULL;
-
- if(!session->progress.get_cancel()) {
- /* get buffer parameters */
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
-
- scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y());
-
- /* set number of samples */
- session->tile_manager.set_samples(session_params.samples);
- session->reset(buffer_params, session_params.samples);
- session->update_scene();
-
- /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
- size_t object_index = OBJECT_NONE;
- int tri_offset = 0;
-
- for(size_t i = 0; i < scene->objects.size(); i++) {
- if(strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) {
- object_index = i;
- tri_offset = scene->objects[i]->mesh->tri_offset;
- break;
- }
- }
-
- /* Object might have been disabled for rendering or excluded in some
- * other way, in that case Blender will report a warning afterwards. */
- if (object_index != OBJECT_NONE) {
- int object = object_index;
-
- bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
- populate_bake_data(bake_data, object_id, pixel_array, num_pixels);
- }
-
- /* set number of samples */
- session->tile_manager.set_samples(session_params.samples);
- session->reset(buffer_params, session_params.samples);
- session->update_scene();
-
- session->progress.set_update_callback(function_bind(&BlenderSession::update_bake_progress, this));
- }
-
- /* Perform bake. Check cancel to avoid crash with incomplete scene data. */
- if(!session->progress.get_cancel() && bake_data) {
- scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_pass_filter, bake_data, result);
- }
-
- /* free all memory used (host and device), so we wouldn't leave render
- * engine with extra memory allocated
- */
-
- session->device_free();
-
- delete sync;
- sync = NULL;
+ b_depsgraph = b_depsgraph_;
+
+ ShaderEvalType shader_type = get_shader_type(pass_type);
+
+ /* Set baking flag in advance, so kernel loading can check if we need
+ * any baking capabilities.
+ */
+ scene->bake_manager->set_baking(true);
+
+ /* ensure kernels are loaded before we do any scene updates */
+ session->load_kernels();
+
+ if (shader_type == SHADER_EVAL_UV) {
+ /* force UV to be available */
+ Pass::add(PASS_UV, scene->film->passes);
+ }
+
+ int bake_pass_filter = bake_pass_filter_get(pass_filter);
+ bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter);
+
+ /* force use_light_pass to be true if we bake more than just colors */
+ if (bake_pass_filter & ~BAKE_FILTER_COLOR) {
+ Pass::add(PASS_LIGHT, scene->film->passes);
+ }
+
+ /* create device and update scene */
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
+ if (!session->progress.get_cancel()) {
+ /* update scene */
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
+ sync->sync_data(
+ b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
+ builtin_images_load();
+ }
+
+ BakeData *bake_data = NULL;
+
+ if (!session->progress.get_cancel()) {
+ /* get buffer parameters */
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+
+ scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y());
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
+ size_t object_index = OBJECT_NONE;
+ int tri_offset = 0;
+
+ for (size_t i = 0; i < scene->objects.size(); i++) {
+ if (strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) {
+ object_index = i;
+ tri_offset = scene->objects[i]->mesh->tri_offset;
+ break;
+ }
+ }
+
+ /* Object might have been disabled for rendering or excluded in some
+ * other way, in that case Blender will report a warning afterwards. */
+ if (object_index != OBJECT_NONE) {
+ int object = object_index;
+
+ bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
+ populate_bake_data(bake_data, object_id, pixel_array, num_pixels);
+ }
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ session->progress.set_update_callback(
+ function_bind(&BlenderSession::update_bake_progress, this));
+ }
+
+ /* Perform bake. Check cancel to avoid crash with incomplete scene data. */
+ if (!session->progress.get_cancel() && bake_data) {
+ scene->bake_manager->bake(scene->device,
+ &scene->dscene,
+ scene,
+ session->progress,
+ shader_type,
+ bake_pass_filter,
+ bake_data,
+ result);
+ }
+
+ /* free all memory used (host and device), so we wouldn't leave render
+ * engine with extra memory allocated
+ */
+
+ session->device_free();
+
+ delete sync;
+ sync = NULL;
}
-void BlenderSession::do_write_update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile,
+void BlenderSession::do_write_update_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile,
bool do_update_only)
{
- RenderBuffers *buffers = rtile.buffers;
-
- /* copy data from device */
- if(!buffers->copy_from_device())
- return;
-
- float exposure = scene->film->exposure;
-
- vector<float> pixels(rtile.w*rtile.h*4);
-
- /* Adjust absolute sample number to the range. */
- int sample = rtile.sample;
- const int range_start_sample = session->tile_manager.range_start_sample;
- if(range_start_sample != -1) {
- sample -= range_start_sample;
- }
-
- if(!do_update_only) {
- /* copy each pass */
- BL::RenderLayer::passes_iterator b_iter;
-
- for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
- BL::RenderPass b_pass(*b_iter);
-
- /* find matching pass type */
- PassType pass_type = BlenderSync::get_pass_type(b_pass);
- int components = b_pass.channels();
-
- bool read = false;
- if(pass_type != PASS_NONE) {
- /* copy pixels */
- read = buffers->get_pass_rect(pass_type, exposure, sample, components, &pixels[0], b_pass.name());
- }
- else {
- int denoising_offset = BlenderSync::get_denoising_pass(b_pass);
- if(denoising_offset >= 0) {
- read = buffers->get_denoising_pass_rect(denoising_offset, exposure, sample, components, &pixels[0]);
- }
- }
-
- if(!read) {
- memset(&pixels[0], 0, pixels.size()*sizeof(float));
- }
-
- b_pass.rect(&pixels[0]);
- }
- }
- else {
- /* copy combined pass */
- BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
- if(buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, &pixels[0], "Combined"))
- b_combined_pass.rect(&pixels[0]);
- }
-
- /* tag result as updated */
- b_engine.update_result(b_rr);
+ RenderBuffers *buffers = rtile.buffers;
+
+ /* copy data from device */
+ if (!buffers->copy_from_device())
+ return;
+
+ float exposure = scene->film->exposure;
+
+ vector<float> pixels(rtile.w * rtile.h * 4);
+
+ /* Adjust absolute sample number to the range. */
+ int sample = rtile.sample;
+ const int range_start_sample = session->tile_manager.range_start_sample;
+ if (range_start_sample != -1) {
+ sample -= range_start_sample;
+ }
+
+ if (!do_update_only) {
+ /* copy each pass */
+ BL::RenderLayer::passes_iterator b_iter;
+
+ for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
+ BL::RenderPass b_pass(*b_iter);
+
+ /* find matching pass type */
+ PassType pass_type = BlenderSync::get_pass_type(b_pass);
+ int components = b_pass.channels();
+
+ bool read = false;
+ if (pass_type != PASS_NONE) {
+ /* copy pixels */
+ read = buffers->get_pass_rect(
+ pass_type, exposure, sample, components, &pixels[0], b_pass.name());
+ }
+ else {
+ int denoising_offset = BlenderSync::get_denoising_pass(b_pass);
+ if (denoising_offset >= 0) {
+ read = buffers->get_denoising_pass_rect(
+ denoising_offset, exposure, sample, components, &pixels[0]);
+ }
+ }
+
+ if (!read) {
+ memset(&pixels[0], 0, pixels.size() * sizeof(float));
+ }
+
+ b_pass.rect(&pixels[0]);
+ }
+ }
+ else {
+ /* copy combined pass */
+ BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
+ if (buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, &pixels[0], "Combined"))
+ b_combined_pass.rect(&pixels[0]);
+ }
+
+ /* tag result as updated */
+ b_engine.update_result(b_rr);
}
-void BlenderSession::write_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile)
+void BlenderSession::write_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile)
{
- do_write_update_render_result(b_rr, b_rlay, rtile, false);
+ do_write_update_render_result(b_rr, b_rlay, rtile, false);
}
-void BlenderSession::update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile)
+void BlenderSession::update_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile)
{
- do_write_update_render_result(b_rr, b_rlay, rtile, true);
+ do_write_update_render_result(b_rr, b_rlay, rtile, true);
}
-void BlenderSession::synchronize(BL::Depsgraph& b_depsgraph_)
+void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
{
- /* only used for viewport render */
- if(!b_v3d)
- return;
-
- /* on session/scene parameter changes, we recreate session entirely */
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- bool session_pause = BlenderSync::get_session_pause(b_scene, background);
-
- if(session->params.modified(session_params) ||
- scene->params.modified(scene_params))
- {
- free_session();
- create_session();
- return;
- }
-
- /* increase samples, but never decrease */
- session->set_samples(session_params.samples);
- session->set_pause(session_pause);
-
- /* copy recalc flags, outside of mutex so we can decide to do the real
- * synchronization at a later time to not block on running updates */
- sync->sync_recalc(b_depsgraph_);
-
- /* don't do synchronization if on pause */
- if(session_pause) {
- tag_update();
- return;
- }
-
- /* try to acquire mutex. if we don't want to or can't, come back later */
- if(!session->ready_to_reset() || !session->scene->mutex.try_lock()) {
- tag_update();
- return;
- }
-
- /* data and camera synchronize */
- b_depsgraph = b_depsgraph_;
-
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_data(b_render,
- b_depsgraph,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state);
-
- if(b_rv3d)
- sync->sync_view(b_v3d, b_rv3d, width, height);
- else
- sync->sync_camera(b_render, b_camera_override, width, height, "");
-
- builtin_images_load();
-
- /* unlock */
- session->scene->mutex.unlock();
-
- /* reset if needed */
- if(scene->need_reset()) {
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
- session->reset(buffer_params, session_params.samples);
-
- /* reset time */
- start_resize_time = 0.0;
- }
-
- /* Start rendering thread, if it's not running already. Do this
- * after all scene data has been synced at least once. */
- session->start();
+ /* only used for viewport render */
+ if (!b_v3d)
+ return;
+
+ /* on session/scene parameter changes, we recreate session entirely */
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
+
+ if (session->params.modified(session_params) || scene->params.modified(scene_params)) {
+ free_session();
+ create_session();
+ return;
+ }
+
+ /* increase samples, but never decrease */
+ session->set_samples(session_params.samples);
+ session->set_pause(session_pause);
+
+ /* copy recalc flags, outside of mutex so we can decide to do the real
+ * synchronization at a later time to not block on running updates */
+ sync->sync_recalc(b_depsgraph_);
+
+ /* don't do synchronization if on pause */
+ if (session_pause) {
+ tag_update();
+ return;
+ }
+
+ /* try to acquire mutex. if we don't want to or can't, come back later */
+ if (!session->ready_to_reset() || !session->scene->mutex.try_lock()) {
+ tag_update();
+ return;
+ }
+
+ /* data and camera synchronize */
+ b_depsgraph = b_depsgraph_;
+
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_data(
+ b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
+
+ if (b_rv3d)
+ sync->sync_view(b_v3d, b_rv3d, width, height);
+ else
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
+
+ builtin_images_load();
+
+ /* unlock */
+ session->scene->mutex.unlock();
+
+ /* reset if needed */
+ if (scene->need_reset()) {
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ session->reset(buffer_params, session_params.samples);
+
+ /* reset time */
+ start_resize_time = 0.0;
+ }
+
+ /* Start rendering thread, if it's not running already. Do this
+ * after all scene data has been synced at least once. */
+ session->start();
}
bool BlenderSession::draw(int w, int h)
{
- /* pause in redraw in case update is not being called due to final render */
- session->set_pause(BlenderSync::get_session_pause(b_scene, background));
-
- /* before drawing, we verify camera and viewport size changes, because
- * we do not get update callbacks for those, we must detect them here */
- if(session->ready_to_reset()) {
- bool reset = false;
-
- /* if dimensions changed, reset */
- if(width != w || height != h) {
- if(start_resize_time == 0.0) {
- /* don't react immediately to resizes to avoid flickery resizing
- * of the viewport, and some window managers changing the window
- * size temporarily on unminimize */
- start_resize_time = time_dt();
- tag_redraw();
- }
- else if(time_dt() - start_resize_time < 0.2) {
- tag_redraw();
- }
- else {
- width = w;
- height = h;
- reset = true;
- }
- }
-
- /* try to acquire mutex. if we can't, come back later */
- if(!session->scene->mutex.try_lock()) {
- tag_update();
- }
- else {
- /* update camera from 3d view */
-
- sync->sync_view(b_v3d, b_rv3d, width, height);
-
- if(scene->camera->need_update)
- reset = true;
-
- session->scene->mutex.unlock();
- }
-
- /* reset if requested */
- if(reset) {
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
- bool session_pause = BlenderSync::get_session_pause(b_scene, background);
-
- if(session_pause == false) {
- session->reset(buffer_params, session_params.samples);
- start_resize_time = 0.0;
- }
- }
- }
- else {
- tag_update();
- }
-
- /* update status and progress for 3d view draw */
- update_status_progress();
-
- /* draw */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
- DeviceDrawParams draw_params;
-
- if(session->params.display_buffer_linear) {
- draw_params.bind_display_space_shader_cb = function_bind(&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
- draw_params.unbind_display_space_shader_cb = function_bind(&BL::RenderEngine::unbind_display_space_shader, &b_engine);
- }
-
- return !session->draw(buffer_params, draw_params);
+ /* pause in redraw in case update is not being called due to final render */
+ session->set_pause(BlenderSync::get_session_pause(b_scene, background));
+
+ /* before drawing, we verify camera and viewport size changes, because
+ * we do not get update callbacks for those, we must detect them here */
+ if (session->ready_to_reset()) {
+ bool reset = false;
+
+ /* if dimensions changed, reset */
+ if (width != w || height != h) {
+ if (start_resize_time == 0.0) {
+ /* don't react immediately to resizes to avoid flickery resizing
+ * of the viewport, and some window managers changing the window
+ * size temporarily on unminimize */
+ start_resize_time = time_dt();
+ tag_redraw();
+ }
+ else if (time_dt() - start_resize_time < 0.2) {
+ tag_redraw();
+ }
+ else {
+ width = w;
+ height = h;
+ reset = true;
+ }
+ }
+
+ /* try to acquire mutex. if we can't, come back later */
+ if (!session->scene->mutex.try_lock()) {
+ tag_update();
+ }
+ else {
+ /* update camera from 3d view */
+
+ sync->sync_view(b_v3d, b_rv3d, width, height);
+
+ if (scene->camera->need_update)
+ reset = true;
+
+ session->scene->mutex.unlock();
+ }
+
+ /* reset if requested */
+ if (reset) {
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
+
+ if (session_pause == false) {
+ session->reset(buffer_params, session_params.samples);
+ start_resize_time = 0.0;
+ }
+ }
+ }
+ else {
+ tag_update();
+ }
+
+ /* update status and progress for 3d view draw */
+ update_status_progress();
+
+ /* draw */
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ DeviceDrawParams draw_params;
+
+ if (session->params.display_buffer_linear) {
+ draw_params.bind_display_space_shader_cb = function_bind(
+ &BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
+ draw_params.unbind_display_space_shader_cb = function_bind(
+ &BL::RenderEngine::unbind_display_space_shader, &b_engine);
+ }
+
+ return !session->draw(buffer_params, draw_params);
}
-void BlenderSession::get_status(string& status, string& substatus)
+void BlenderSession::get_status(string &status, string &substatus)
{
- session->progress.get_status(status, substatus);
+ session->progress.get_status(status, substatus);
}
-void BlenderSession::get_kernel_status(string& kernel_status)
+void BlenderSession::get_kernel_status(string &kernel_status)
{
- session->progress.get_kernel_status(kernel_status);
+ session->progress.get_kernel_status(kernel_status);
}
-void BlenderSession::get_progress(float& progress, double& total_time, double& render_time)
+void BlenderSession::get_progress(float &progress, double &total_time, double &render_time)
{
- session->progress.get_time(total_time, render_time);
- progress = session->progress.get_progress();
+ session->progress.get_time(total_time, render_time);
+ progress = session->progress.get_progress();
}
void BlenderSession::update_bake_progress()
{
- float progress = session->progress.get_progress();
+ float progress = session->progress.get_progress();
- if(progress != last_progress) {
- b_engine.update_progress(progress);
- last_progress = progress;
- }
+ if (progress != last_progress) {
+ b_engine.update_progress(progress);
+ last_progress = progress;
+ }
}
void BlenderSession::update_status_progress()
{
- string timestatus, status, substatus, kernel_status;
- string scene_status = "";
- float progress;
- double total_time, remaining_time = 0, render_time;
- float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
- float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
-
- get_status(status, substatus);
- get_kernel_status(kernel_status);
- get_progress(progress, total_time, render_time);
-
- if(progress > 0)
- remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
-
- if(background) {
- scene_status += " | " + scene->name;
- if(b_rlay_name != "")
- scene_status += ", " + b_rlay_name;
-
- if(b_rview_name != "")
- scene_status += ", " + b_rview_name;
-
- if(remaining_time > 0) {
- timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | ";
- }
-
- timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
-
- if(status.size() > 0)
- status = " | " + status;
- if(substatus.size() > 0)
- status += " | " + substatus;
- if(kernel_status.size() > 0)
- status += " | " + kernel_status;
- }
-
- double current_time = time_dt();
- /* When rendering in a window, redraw the status at least once per second to keep the elapsed and remaining time up-to-date.
- * For headless rendering, only report when something significant changes to keep the console output readable. */
- if(status != last_status || (!headless && (current_time - last_status_time) > 1.0)) {
- b_engine.update_stats("", (timestatus + scene_status + status).c_str());
- b_engine.update_memory_stats(mem_used, mem_peak);
- last_status = status;
- last_status_time = current_time;
- }
- if(progress != last_progress) {
- b_engine.update_progress(progress);
- last_progress = progress;
- }
-
- if(session->progress.get_error()) {
- string error = session->progress.get_error_message();
- if(error != last_error) {
- /* TODO(sergey): Currently C++ RNA API doesn't let us to
- * use mnemonic name for the variable. Would be nice to
- * have this figured out.
- *
- * For until then, 1 << 5 means RPT_ERROR.
- */
- b_engine.report(1 << 5, error.c_str());
- b_engine.error_set(error.c_str());
- last_error = error;
- }
- }
+ string timestatus, status, substatus, kernel_status;
+ string scene_status = "";
+ float progress;
+ double total_time, remaining_time = 0, render_time;
+ float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
+ float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
+
+ get_status(status, substatus);
+ get_kernel_status(kernel_status);
+ get_progress(progress, total_time, render_time);
+
+ if (progress > 0)
+ remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
+
+ if (background) {
+ scene_status += " | " + scene->name;
+ if (b_rlay_name != "")
+ scene_status += ", " + b_rlay_name;
+
+ if (b_rview_name != "")
+ scene_status += ", " + b_rview_name;
+
+ if (remaining_time > 0) {
+ timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | ";
+ }
+
+ timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
+
+ if (status.size() > 0)
+ status = " | " + status;
+ if (substatus.size() > 0)
+ status += " | " + substatus;
+ if (kernel_status.size() > 0)
+ status += " | " + kernel_status;
+ }
+
+ double current_time = time_dt();
+ /* When rendering in a window, redraw the status at least once per second to keep the elapsed and remaining time up-to-date.
+ * For headless rendering, only report when something significant changes to keep the console output readable. */
+ if (status != last_status || (!headless && (current_time - last_status_time) > 1.0)) {
+ b_engine.update_stats("", (timestatus + scene_status + status).c_str());
+ b_engine.update_memory_stats(mem_used, mem_peak);
+ last_status = status;
+ last_status_time = current_time;
+ }
+ if (progress != last_progress) {
+ b_engine.update_progress(progress);
+ last_progress = progress;
+ }
+
+ if (session->progress.get_error()) {
+ string error = session->progress.get_error_message();
+ if (error != last_error) {
+ /* TODO(sergey): Currently C++ RNA API doesn't let us to
+ * use mnemonic name for the variable. Would be nice to
+ * have this figured out.
+ *
+ * For until then, 1 << 5 means RPT_ERROR.
+ */
+ b_engine.report(1 << 5, error.c_str());
+ b_engine.error_set(error.c_str());
+ last_error = error;
+ }
+ }
}
void BlenderSession::tag_update()
{
- /* tell blender that we want to get another update callback */
- b_engine.tag_update();
+ /* tell blender that we want to get another update callback */
+ b_engine.tag_update();
}
void BlenderSession::tag_redraw()
{
- if(background) {
- /* update stats and progress, only for background here because
- * in 3d view we do it in draw for thread safety reasons */
- update_status_progress();
-
- /* offline render, redraw if timeout passed */
- if(time_dt() - last_redraw_time > 1.0) {
- b_engine.tag_redraw();
- last_redraw_time = time_dt();
- }
- }
- else {
- /* tell blender that we want to redraw */
- b_engine.tag_redraw();
- }
+ if (background) {
+ /* update stats and progress, only for background here because
+ * in 3d view we do it in draw for thread safety reasons */
+ update_status_progress();
+
+ /* offline render, redraw if timeout passed */
+ if (time_dt() - last_redraw_time > 1.0) {
+ b_engine.tag_redraw();
+ last_redraw_time = time_dt();
+ }
+ }
+ else {
+ /* tell blender that we want to redraw */
+ b_engine.tag_redraw();
+ }
}
void BlenderSession::test_cancel()
{
- /* test if we need to cancel rendering */
- if(background)
- if(b_engine.test_break())
- session->progress.set_cancel("Cancelled");
+ /* test if we need to cancel rendering */
+ if (background)
+ if (b_engine.test_break())
+ session->progress.set_cancel("Cancelled");
}
/* builtin image file name is actually an image datablock name with
@@ -1107,89 +1126,88 @@ void BlenderSession::test_cancel()
*/
int BlenderSession::builtin_image_frame(const string &builtin_name)
{
- int last = builtin_name.find_last_of('@');
- return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
+ int last = builtin_name.find_last_of('@');
+ return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
}
void BlenderSession::builtin_image_info(const string &builtin_name,
void *builtin_data,
- ImageMetaData& metadata)
+ ImageMetaData &metadata)
{
- /* empty image */
- metadata.width = 1;
- metadata.height = 1;
-
- if(!builtin_data)
- return;
-
- /* recover ID pointer */
- PointerRNA ptr;
- RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::ID b_id(ptr);
-
- if(b_id.is_a(&RNA_Image)) {
- /* image data */
- BL::Image b_image(b_id);
-
- metadata.builtin_free_cache = !b_image.has_data();
- metadata.is_float = b_image.is_float();
- metadata.width = b_image.size()[0];
- metadata.height = b_image.size()[1];
- metadata.depth = 1;
- metadata.channels = b_image.channels();
- }
- else if(b_id.is_a(&RNA_Object)) {
- /* smoke volume data */
- BL::Object b_ob(b_id);
- BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
-
- metadata.is_float = true;
- metadata.depth = 1;
- metadata.channels = 1;
-
- if(!b_domain)
- return;
-
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE))
- metadata.channels = 1;
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
- metadata.channels = 4;
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY))
- metadata.channels = 3;
- else
- return;
-
- int3 resolution = get_int3(b_domain.domain_resolution());
- int amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
-
- /* Velocity and heat data is always low-resolution. */
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT))
- {
- amplify = 1;
- }
-
- metadata.width = resolution.x * amplify;
- metadata.height = resolution.y * amplify;
- metadata.depth = resolution.z * amplify;
- }
- else {
- /* TODO(sergey): Check we're indeed in shader node tree. */
- PointerRNA ptr;
- RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
- BL::Node b_node(ptr);
- if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
- BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
- metadata.channels = 4;
- metadata.width = b_point_density_node.resolution();
- metadata.height = metadata.width;
- metadata.depth = metadata.width;
- metadata.is_float = true;
- }
- }
+ /* empty image */
+ metadata.width = 1;
+ metadata.height = 1;
+
+ if (!builtin_data)
+ return;
+
+ /* recover ID pointer */
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID *)builtin_data, &ptr);
+ BL::ID b_id(ptr);
+
+ if (b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
+
+ metadata.builtin_free_cache = !b_image.has_data();
+ metadata.is_float = b_image.is_float();
+ metadata.width = b_image.size()[0];
+ metadata.height = b_image.size()[1];
+ metadata.depth = 1;
+ metadata.channels = b_image.channels();
+ }
+ else if (b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ metadata.is_float = true;
+ metadata.depth = 1;
+ metadata.channels = 1;
+
+ if (!b_domain)
+ return;
+
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE))
+ metadata.channels = 1;
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
+ metadata.channels = 4;
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY))
+ metadata.channels = 3;
+ else
+ return;
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int amplify = (b_domain.use_high_resolution()) ? b_domain.amplify() + 1 : 1;
+
+ /* Velocity and heat data is always low-resolution. */
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
+ amplify = 1;
+ }
+
+ metadata.width = resolution.x * amplify;
+ metadata.height = resolution.y * amplify;
+ metadata.depth = resolution.z * amplify;
+ }
+ else {
+ /* TODO(sergey): Check we're indeed in shader node tree. */
+ PointerRNA ptr;
+ RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
+ BL::Node b_node(ptr);
+ if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
+ BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
+ metadata.channels = 4;
+ metadata.width = b_point_density_node.resolution();
+ metadata.height = metadata.width;
+ metadata.depth = metadata.width;
+ metadata.is_float = true;
+ }
+ }
}
bool BlenderSession::builtin_image_pixels(const string &builtin_name,
@@ -1198,61 +1216,61 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name,
const size_t pixels_size,
const bool free_cache)
{
- if(!builtin_data) {
- return false;
- }
-
- const int frame = builtin_image_frame(builtin_name);
-
- PointerRNA ptr;
- RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::Image b_image(ptr);
-
- const int width = b_image.size()[0];
- const int height = b_image.size()[1];
- const int channels = b_image.channels();
-
- unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame);
- const size_t num_pixels = ((size_t)width) * height;
-
- if(image_pixels && num_pixels * channels == pixels_size) {
- memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
- }
- else {
- if(channels == 1) {
- memset(pixels, 0, pixels_size * sizeof(unsigned char));
- }
- else {
- const size_t num_pixels_safe = pixels_size / channels;
- unsigned char *cp = pixels;
- for(size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
- cp[0] = 255;
- cp[1] = 0;
- cp[2] = 255;
- if(channels == 4) {
- cp[3] = 255;
- }
- }
- }
- }
-
- if(image_pixels) {
- MEM_freeN(image_pixels);
- }
-
- /* Free image buffers to save memory during render. */
- if(free_cache) {
- b_image.buffers_free();
- }
-
- /* Premultiply, byte images are always straight for Blender. */
- unsigned char *cp = pixels;
- for(size_t i = 0; i < num_pixels; i++, cp += channels) {
- cp[0] = (cp[0] * cp[3]) >> 8;
- cp[1] = (cp[1] * cp[3]) >> 8;
- cp[2] = (cp[2] * cp[3]) >> 8;
- }
- return true;
+ if (!builtin_data) {
+ return false;
+ }
+
+ const int frame = builtin_image_frame(builtin_name);
+
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID *)builtin_data, &ptr);
+ BL::Image b_image(ptr);
+
+ const int width = b_image.size()[0];
+ const int height = b_image.size()[1];
+ const int channels = b_image.channels();
+
+ unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame);
+ const size_t num_pixels = ((size_t)width) * height;
+
+ if (image_pixels && num_pixels * channels == pixels_size) {
+ memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
+ }
+ else {
+ if (channels == 1) {
+ memset(pixels, 0, pixels_size * sizeof(unsigned char));
+ }
+ else {
+ const size_t num_pixels_safe = pixels_size / channels;
+ unsigned char *cp = pixels;
+ for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
+ cp[0] = 255;
+ cp[1] = 0;
+ cp[2] = 255;
+ if (channels == 4) {
+ cp[3] = 255;
+ }
+ }
+ }
+ }
+
+ if (image_pixels) {
+ MEM_freeN(image_pixels);
+ }
+
+ /* Free image buffers to save memory during render. */
+ if (free_cache) {
+ b_image.buffers_free();
+ }
+
+ /* Premultiply, byte images are always straight for Blender. */
+ unsigned char *cp = pixels;
+ for (size_t i = 0; i < num_pixels; i++, cp += channels) {
+ cp[0] = (cp[0] * cp[3]) >> 8;
+ cp[1] = (cp[1] * cp[3]) >> 8;
+ cp[2] = (cp[2] * cp[3]) >> 8;
+ }
+ return true;
}
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
@@ -1261,225 +1279,225 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
const size_t pixels_size,
const bool free_cache)
{
- if(!builtin_data) {
- return false;
- }
-
- PointerRNA ptr;
- RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::ID b_id(ptr);
-
- if(b_id.is_a(&RNA_Image)) {
- /* image data */
- BL::Image b_image(b_id);
- int frame = builtin_image_frame(builtin_name);
-
- const int width = b_image.size()[0];
- const int height = b_image.size()[1];
- const int channels = b_image.channels();
-
- float *image_pixels;
- image_pixels = image_get_float_pixels_for_frame(b_image, frame);
- const size_t num_pixels = ((size_t)width) * height;
-
- if(image_pixels && num_pixels * channels == pixels_size) {
- memcpy(pixels, image_pixels, pixels_size * sizeof(float));
- }
- else {
- if(channels == 1) {
- memset(pixels, 0, num_pixels * sizeof(float));
- }
- else {
- const size_t num_pixels_safe = pixels_size / channels;
- float *fp = pixels;
- for(int i = 0; i < num_pixels_safe; i++, fp += channels) {
- fp[0] = 1.0f;
- fp[1] = 0.0f;
- fp[2] = 1.0f;
- if(channels == 4) {
- fp[3] = 1.0f;
- }
- }
- }
- }
-
- if(image_pixels) {
- MEM_freeN(image_pixels);
- }
-
- /* Free image buffers to save memory during render. */
- if(free_cache) {
- b_image.buffers_free();
- }
-
- return true;
- }
- else if(b_id.is_a(&RNA_Object)) {
- /* smoke volume data */
- BL::Object b_ob(b_id);
- BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
-
- if(!b_domain) {
- return false;
- }
-
- int3 resolution = get_int3(b_domain.domain_resolution());
- int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
-
- /* Velocity and heat data is always low-resolution. */
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT))
- {
- amplify = 1;
- }
-
- const int width = resolution.x * amplify;
- const int height = resolution.y * amplify;
- const int depth = resolution.z * amplify;
- const size_t num_pixels = ((size_t)width) * height * depth;
-
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
- SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_density_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
- /* this is in range 0..1, and interpreted by the OpenGL smoke viewer
- * as 1500..3000 K with the first part faded to zero density */
- SmokeDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
- /* the RGB is "premultiplied" by density for better interpolation results */
- SmokeDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels*4) {
- SmokeDomainSettings_color_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
- SmokeDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels*3) {
- SmokeDomainSettings_velocity_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
- SmokeDomainSettings_heat_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_heat_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
- SmokeDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_temperature_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else {
- fprintf(stderr,
- "Cycles error: unknown volume attribute %s, skipping\n",
- builtin_name.c_str());
- pixels[0] = 0.0f;
- return false;
- }
-
- fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
- }
- else {
- /* We originally were passing view_layer here but in reality we need a
- * a depsgraph to pass to the RE_point_density_minmax() function.
- */
- /* TODO(sergey): Check we're indeed in shader node tree. */
- PointerRNA ptr;
- RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
- BL::Node b_node(ptr);
- if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
- BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
- int length;
- b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels);
- }
- }
-
- return false;
+ if (!builtin_data) {
+ return false;
+ }
+
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID *)builtin_data, &ptr);
+ BL::ID b_id(ptr);
+
+ if (b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
+ int frame = builtin_image_frame(builtin_name);
+
+ const int width = b_image.size()[0];
+ const int height = b_image.size()[1];
+ const int channels = b_image.channels();
+
+ float *image_pixels;
+ image_pixels = image_get_float_pixels_for_frame(b_image, frame);
+ const size_t num_pixels = ((size_t)width) * height;
+
+ if (image_pixels && num_pixels * channels == pixels_size) {
+ memcpy(pixels, image_pixels, pixels_size * sizeof(float));
+ }
+ else {
+ if (channels == 1) {
+ memset(pixels, 0, num_pixels * sizeof(float));
+ }
+ else {
+ const size_t num_pixels_safe = pixels_size / channels;
+ float *fp = pixels;
+ for (int i = 0; i < num_pixels_safe; i++, fp += channels) {
+ fp[0] = 1.0f;
+ fp[1] = 0.0f;
+ fp[2] = 1.0f;
+ if (channels == 4) {
+ fp[3] = 1.0f;
+ }
+ }
+ }
+ }
+
+ if (image_pixels) {
+ MEM_freeN(image_pixels);
+ }
+
+ /* Free image buffers to save memory during render. */
+ if (free_cache) {
+ b_image.buffers_free();
+ }
+
+ return true;
+ }
+ else if (b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if (!b_domain) {
+ return false;
+ }
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int length, amplify = (b_domain.use_high_resolution()) ? b_domain.amplify() + 1 : 1;
+
+ /* Velocity and heat data is always low-resolution. */
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
+ amplify = 1;
+ }
+
+ const int width = resolution.x * amplify;
+ const int height = resolution.y * amplify;
+ const int depth = resolution.z * amplify;
+ const size_t num_pixels = ((size_t)width) * height * depth;
+
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
+ SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_density_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
+ /* this is in range 0..1, and interpreted by the OpenGL smoke viewer
+ * as 1500..3000 K with the first part faded to zero density */
+ SmokeDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
+ /* the RGB is "premultiplied" by density for better interpolation results */
+ SmokeDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels * 4) {
+ SmokeDomainSettings_color_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
+ SmokeDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels * 3) {
+ SmokeDomainSettings_velocity_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
+ SmokeDomainSettings_heat_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_heat_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
+ SmokeDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_temperature_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else {
+ fprintf(
+ stderr, "Cycles error: unknown volume attribute %s, skipping\n", builtin_name.c_str());
+ pixels[0] = 0.0f;
+ return false;
+ }
+
+ fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
+ }
+ else {
+ /* We originally were passing view_layer here but in reality we need a
+ * a depsgraph to pass to the RE_point_density_minmax() function.
+ */
+ /* TODO(sergey): Check we're indeed in shader node tree. */
+ PointerRNA ptr;
+ RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
+ BL::Node b_node(ptr);
+ if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
+ BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
+ int length;
+ b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels);
+ }
+ }
+
+ return false;
}
void BlenderSession::builtin_images_load()
{
- /* Force builtin images to be loaded along with Blender data sync. This
- * is needed because we may be reading from depsgraph evaluated data which
- * can be freed by Blender before Cycles reads it. */
- ImageManager *manager = session->scene->image_manager;
- Device *device = session->device;
- manager->device_load_builtin(device, session->scene, session->progress);
+ /* Force builtin images to be loaded along with Blender data sync. This
+ * is needed because we may be reading from depsgraph evaluated data which
+ * can be freed by Blender before Cycles reads it. */
+ ImageManager *manager = session->scene->image_manager;
+ Device *device = session->device;
+ manager->device_load_builtin(device, session->scene, session->progress);
}
void BlenderSession::update_resumable_tile_manager(int num_samples)
{
- const int num_resumable_chunks = BlenderSession::num_resumable_chunks,
- current_resumable_chunk = BlenderSession::current_resumable_chunk;
- if(num_resumable_chunks == 0) {
- return;
- }
-
- if (num_resumable_chunks > num_samples) {
- fprintf(stderr, "Cycles warning: more sample chunks (%d) than samples (%d), "
- "this will cause some samples to be included in multiple chunks.\n",
- num_resumable_chunks, num_samples);
- }
-
- const float num_samples_per_chunk = (float)num_samples / num_resumable_chunks;
-
- float range_start_sample, range_num_samples;
- if(current_resumable_chunk != 0) {
- /* Single chunk rendering. */
- range_start_sample = num_samples_per_chunk * (current_resumable_chunk - 1);
- range_num_samples = num_samples_per_chunk;
- }
- else {
- /* Ranged-chunks. */
- const int num_chunks = end_resumable_chunk - start_resumable_chunk + 1;
- range_start_sample = num_samples_per_chunk * (start_resumable_chunk - 1);
- range_num_samples = num_chunks * num_samples_per_chunk;
- }
-
- /* Round after doing the multiplications with num_chunks and num_samples_per_chunk
- * to allow for many small chunks. */
- int rounded_range_start_sample = (int)floor(range_start_sample + 0.5f);
- int rounded_range_num_samples = max((int)floor(range_num_samples + 0.5f), 1);
-
- /* Make sure we don't overshoot. */
- if(rounded_range_start_sample + rounded_range_num_samples > num_samples) {
- rounded_range_num_samples = num_samples - rounded_range_num_samples;
- }
-
- VLOG(1) << "Samples range start is " << range_start_sample << ", "
- << "number of samples to render is " << range_num_samples;
-
- scene->integrator->start_sample = rounded_range_start_sample;
- scene->integrator->tag_update(scene);
-
- session->tile_manager.range_start_sample = rounded_range_start_sample;
- session->tile_manager.range_num_samples = rounded_range_num_samples;
+ const int num_resumable_chunks = BlenderSession::num_resumable_chunks,
+ current_resumable_chunk = BlenderSession::current_resumable_chunk;
+ if (num_resumable_chunks == 0) {
+ return;
+ }
+
+ if (num_resumable_chunks > num_samples) {
+ fprintf(stderr,
+ "Cycles warning: more sample chunks (%d) than samples (%d), "
+ "this will cause some samples to be included in multiple chunks.\n",
+ num_resumable_chunks,
+ num_samples);
+ }
+
+ const float num_samples_per_chunk = (float)num_samples / num_resumable_chunks;
+
+ float range_start_sample, range_num_samples;
+ if (current_resumable_chunk != 0) {
+ /* Single chunk rendering. */
+ range_start_sample = num_samples_per_chunk * (current_resumable_chunk - 1);
+ range_num_samples = num_samples_per_chunk;
+ }
+ else {
+ /* Ranged-chunks. */
+ const int num_chunks = end_resumable_chunk - start_resumable_chunk + 1;
+ range_start_sample = num_samples_per_chunk * (start_resumable_chunk - 1);
+ range_num_samples = num_chunks * num_samples_per_chunk;
+ }
+
+ /* Round after doing the multiplications with num_chunks and num_samples_per_chunk
+ * to allow for many small chunks. */
+ int rounded_range_start_sample = (int)floor(range_start_sample + 0.5f);
+ int rounded_range_num_samples = max((int)floor(range_num_samples + 0.5f), 1);
+
+ /* Make sure we don't overshoot. */
+ if (rounded_range_start_sample + rounded_range_num_samples > num_samples) {
+ rounded_range_num_samples = num_samples - rounded_range_num_samples;
+ }
+
+ VLOG(1) << "Samples range start is " << range_start_sample << ", "
+ << "number of samples to render is " << range_num_samples;
+
+ scene->integrator->start_sample = rounded_range_start_sample;
+ scene->integrator->tag_update(scene);
+
+ session->tile_manager.range_start_sample = rounded_range_start_sample;
+ session->tile_manager.range_num_samples = rounded_range_num_samples;
}
void BlenderSession::free_blender_memory_if_possible()
{
- if(!background) {
- /* During interactive render we can not free anything: attempts to save
- * memory would cause things to be allocated and evaluated for every
- * updated sample.
- */
- return;
- }
- b_engine.free_blender_memory();
+ if (!background) {
+ /* During interactive render we can not free anything: attempts to save
+ * memory would cause things to be allocated and evaluated for every
+ * updated sample.
+ */
+ return;
+ }
+ b_engine.free_blender_memory();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 2bfb9e56c37..f0107d4e0b1 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -33,159 +33,153 @@ class RenderBuffers;
class RenderTile;
class BlenderSession {
-public:
- BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
- bool preview_osl);
-
- BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height);
-
- ~BlenderSession();
-
- void create();
-
- /* session */
- void create_session();
- void free_session();
-
- void reset_session(BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph);
-
- /* offline render */
- void render(BL::Depsgraph& b_depsgraph);
-
- void bake(BL::Depsgraph& b_depsgrah,
- BL::Object& b_object,
- const string& pass_type,
- const int custom_flag,
- const int object_id,
- BL::BakePixel& pixel_array,
- const size_t num_pixels,
- const int depth,
- float pixels[]);
-
- void write_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile);
- void write_render_tile(RenderTile& rtile);
-
- /* update functions are used to update display buffer only after sample was rendered
- * only needed for better visual feedback */
- void update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile);
- void update_render_tile(RenderTile& rtile, bool highlight);
-
- /* interactive updates */
- void synchronize(BL::Depsgraph& b_depsgraph);
-
- /* drawing */
- bool draw(int w, int h);
- void tag_redraw();
- void tag_update();
- void get_status(string& status, string& substatus);
- void get_kernel_status(string& kernel_status);
- void get_progress(float& progress, double& total_time, double& render_time);
- void test_cancel();
- void update_status_progress();
- void update_bake_progress();
-
- bool background;
- Session *session;
- Scene *scene;
- BlenderSync *sync;
- double last_redraw_time;
-
- BL::RenderEngine b_engine;
- BL::Preferences b_userpref;
- BL::BlendData b_data;
- BL::RenderSettings b_render;
- BL::Depsgraph b_depsgraph;
- /* NOTE: Blender's scene might become invalid after call
- * free_blender_memory_if_possible().
- */
- BL::Scene b_scene;
- BL::SpaceView3D b_v3d;
- BL::RegionView3D b_rv3d;
- string b_rlay_name;
- string b_rview_name;
-
- string last_status;
- string last_error;
- float last_progress;
- double last_status_time;
-
- int width, height;
- bool preview_osl;
- double start_resize_time;
-
- void *python_thread_state;
-
- /* Global state which is common for all render sessions created from Blender.
- * Usually denotes command line arguments.
- */
-
- /* Blender is running from the command line, no windows are shown and some
- * extra render optimization is possible (possible to free draw-only data and
- * so on.
- */
- static bool headless;
-
- /* ** Resumable render ** */
-
- /* Overall number of chunks in which the sample range is to be devided. */
- static int num_resumable_chunks;
-
- /* Current resumable chunk index to render. */
- static int current_resumable_chunk;
-
- /* Alternative to single-chunk rendering to render a range of chunks. */
- static int start_resumable_chunk;
- static int end_resumable_chunk;
-
- static bool print_render_stats;
-
-protected:
- void stamp_view_layer_metadata(Scene *scene, const string& view_layer_name);
-
- void do_write_update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile,
- bool do_update_only);
- void do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight);
-
- int builtin_image_frame(const string &builtin_name);
- void builtin_image_info(const string &builtin_name,
- void *builtin_data,
- ImageMetaData& metadata);
- bool builtin_image_pixels(const string &builtin_name,
- void *builtin_data,
- unsigned char *pixels,
- const size_t pixels_size,
- const bool free_cache);
- bool builtin_image_float_pixels(const string &builtin_name,
- void *builtin_data,
- float *pixels,
- const size_t pixels_size,
- const bool free_cache);
- void builtin_images_load();
-
- /* Update tile manager to reflect resumable render settings. */
- void update_resumable_tile_manager(int num_samples);
-
- /* Is used after each render layer synchronization is done with the goal
- * of freeing render engine data which is held from Blender side (for
- * example, dependency graph).
- */
- void free_blender_memory_if_possible();
+ public:
+ BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
+ bool preview_osl);
+
+ BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height);
+
+ ~BlenderSession();
+
+ void create();
+
+ /* session */
+ void create_session();
+ void free_session();
+
+ void reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph);
+
+ /* offline render */
+ void render(BL::Depsgraph &b_depsgraph);
+
+ void bake(BL::Depsgraph &b_depsgrah,
+ BL::Object &b_object,
+ const string &pass_type,
+ const int custom_flag,
+ const int object_id,
+ BL::BakePixel &pixel_array,
+ const size_t num_pixels,
+ const int depth,
+ float pixels[]);
+
+ void write_render_result(BL::RenderResult &b_rr, BL::RenderLayer &b_rlay, RenderTile &rtile);
+ void write_render_tile(RenderTile &rtile);
+
+ /* update functions are used to update display buffer only after sample was rendered
+ * only needed for better visual feedback */
+ void update_render_result(BL::RenderResult &b_rr, BL::RenderLayer &b_rlay, RenderTile &rtile);
+ void update_render_tile(RenderTile &rtile, bool highlight);
+
+ /* interactive updates */
+ void synchronize(BL::Depsgraph &b_depsgraph);
+
+ /* drawing */
+ bool draw(int w, int h);
+ void tag_redraw();
+ void tag_update();
+ void get_status(string &status, string &substatus);
+ void get_kernel_status(string &kernel_status);
+ void get_progress(float &progress, double &total_time, double &render_time);
+ void test_cancel();
+ void update_status_progress();
+ void update_bake_progress();
+
+ bool background;
+ Session *session;
+ Scene *scene;
+ BlenderSync *sync;
+ double last_redraw_time;
+
+ BL::RenderEngine b_engine;
+ BL::Preferences b_userpref;
+ BL::BlendData b_data;
+ BL::RenderSettings b_render;
+ BL::Depsgraph b_depsgraph;
+ /* NOTE: Blender's scene might become invalid after call
+ * free_blender_memory_if_possible().
+ */
+ BL::Scene b_scene;
+ BL::SpaceView3D b_v3d;
+ BL::RegionView3D b_rv3d;
+ string b_rlay_name;
+ string b_rview_name;
+
+ string last_status;
+ string last_error;
+ float last_progress;
+ double last_status_time;
+
+ int width, height;
+ bool preview_osl;
+ double start_resize_time;
+
+ void *python_thread_state;
+
+ /* Global state which is common for all render sessions created from Blender.
+ * Usually denotes command line arguments.
+ */
+
+ /* Blender is running from the command line, no windows are shown and some
+ * extra render optimization is possible (possible to free draw-only data and
+ * so on.
+ */
+ static bool headless;
+
+ /* ** Resumable render ** */
+
+ /* Overall number of chunks in which the sample range is to be devided. */
+ static int num_resumable_chunks;
+
+ /* Current resumable chunk index to render. */
+ static int current_resumable_chunk;
+
+ /* Alternative to single-chunk rendering to render a range of chunks. */
+ static int start_resumable_chunk;
+ static int end_resumable_chunk;
+
+ static bool print_render_stats;
+
+ protected:
+ void stamp_view_layer_metadata(Scene *scene, const string &view_layer_name);
+
+ void do_write_update_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile,
+ bool do_update_only);
+ void do_write_update_render_tile(RenderTile &rtile, bool do_update_only, bool highlight);
+
+ int builtin_image_frame(const string &builtin_name);
+ void builtin_image_info(const string &builtin_name, void *builtin_data, ImageMetaData &metadata);
+ bool builtin_image_pixels(const string &builtin_name,
+ void *builtin_data,
+ unsigned char *pixels,
+ const size_t pixels_size,
+ const bool free_cache);
+ bool builtin_image_float_pixels(const string &builtin_name,
+ void *builtin_data,
+ float *pixels,
+ const size_t pixels_size,
+ const bool free_cache);
+ void builtin_images_load();
+
+ /* Update tile manager to reflect resumable render settings. */
+ void update_resumable_tile_manager(int num_samples);
+
+ /* Is used after each render layer synchronization is done with the goal
+ * of freeing render engine data which is held from Blender side (for
+ * example, dependency graph).
+ */
+ void free_blender_memory_if_possible();
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_SESSION_H__ */
+#endif /* __BLENDER_SESSION_H__ */
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 44ff29d4bf8..169c4d414a6 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -34,1449 +34,1416 @@
CCL_NAMESPACE_BEGIN
-typedef map<void*, ShaderInput*> PtrInputMap;
-typedef map<void*, ShaderOutput*> PtrOutputMap;
-typedef map<string, ConvertNode*> ProxyMap;
+typedef map<void *, ShaderInput *> PtrInputMap;
+typedef map<void *, ShaderOutput *> PtrOutputMap;
+typedef map<string, ConvertNode *> ProxyMap;
/* Find */
-void BlenderSync::find_shader(BL::ID& id,
- vector<Shader*>& used_shaders,
- Shader *default_shader)
+void BlenderSync::find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader)
{
- Shader *shader = (id)? shader_map.find(id): default_shader;
+ Shader *shader = (id) ? shader_map.find(id) : default_shader;
- used_shaders.push_back(shader);
- shader->tag_used(scene);
+ used_shaders.push_back(shader);
+ shader->tag_used(scene);
}
/* RNA translation utilities */
-static VolumeSampling get_volume_sampling(PointerRNA& ptr)
+static VolumeSampling get_volume_sampling(PointerRNA &ptr)
{
- return (VolumeSampling)get_enum(ptr,
- "volume_sampling",
- VOLUME_NUM_SAMPLING,
- VOLUME_SAMPLING_DISTANCE);
+ return (VolumeSampling)get_enum(
+ ptr, "volume_sampling", VOLUME_NUM_SAMPLING, VOLUME_SAMPLING_DISTANCE);
}
-static VolumeInterpolation get_volume_interpolation(PointerRNA& ptr)
+static VolumeInterpolation get_volume_interpolation(PointerRNA &ptr)
{
- return (VolumeInterpolation)get_enum(ptr,
- "volume_interpolation",
- VOLUME_NUM_INTERPOLATION,
- VOLUME_INTERPOLATION_LINEAR);
+ return (VolumeInterpolation)get_enum(
+ ptr, "volume_interpolation", VOLUME_NUM_INTERPOLATION, VOLUME_INTERPOLATION_LINEAR);
}
-static DisplacementMethod get_displacement_method(PointerRNA& ptr)
+static DisplacementMethod get_displacement_method(PointerRNA &ptr)
{
- return (DisplacementMethod)get_enum(ptr,
- "displacement_method",
- DISPLACE_NUM_METHODS,
- DISPLACE_BUMP);
+ return (DisplacementMethod)get_enum(
+ ptr, "displacement_method", DISPLACE_NUM_METHODS, DISPLACE_BUMP);
}
static int validate_enum_value(int value, int num_values, int default_value)
{
- if(value >= num_values) {
- return default_value;
- }
- return value;
+ if (value >= num_values) {
+ return default_value;
+ }
+ return value;
}
-template<typename NodeType>
-static InterpolationType get_image_interpolation(NodeType& b_node)
+template<typename NodeType> static InterpolationType get_image_interpolation(NodeType &b_node)
{
- int value = b_node.interpolation();
- return (InterpolationType)validate_enum_value(value,
- INTERPOLATION_NUM_TYPES,
- INTERPOLATION_LINEAR);
+ int value = b_node.interpolation();
+ return (InterpolationType)validate_enum_value(
+ value, INTERPOLATION_NUM_TYPES, INTERPOLATION_LINEAR);
}
-template<typename NodeType>
-static ExtensionType get_image_extension(NodeType& b_node)
+template<typename NodeType> static ExtensionType get_image_extension(NodeType &b_node)
{
- int value = b_node.extension();
- return (ExtensionType)validate_enum_value(value,
- EXTENSION_NUM_TYPES,
- EXTENSION_REPEAT);
+ int value = b_node.extension();
+ return (ExtensionType)validate_enum_value(value, EXTENSION_NUM_TYPES, EXTENSION_REPEAT);
}
/* Graph */
-static BL::NodeSocket get_node_output(BL::Node& b_node, const string& name)
+static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
{
- BL::Node::outputs_iterator b_out;
+ BL::Node::outputs_iterator b_out;
- for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
- if(b_out->name() == name)
- return *b_out;
+ for (b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
+ if (b_out->name() == name)
+ return *b_out;
- assert(0);
+ assert(0);
- return *b_out;
+ return *b_out;
}
-static float3 get_node_output_rgba(BL::Node& b_node, const string& name)
+static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
{
- BL::NodeSocket b_sock = get_node_output(b_node, name);
- float value[4];
- RNA_float_get_array(&b_sock.ptr, "default_value", value);
- return make_float3(value[0], value[1], value[2]);
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ float value[4];
+ RNA_float_get_array(&b_sock.ptr, "default_value", value);
+ return make_float3(value[0], value[1], value[2]);
}
-static float get_node_output_value(BL::Node& b_node, const string& name)
+static float get_node_output_value(BL::Node &b_node, const string &name)
{
- BL::NodeSocket b_sock = get_node_output(b_node, name);
- return RNA_float_get(&b_sock.ptr, "default_value");
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ return RNA_float_get(&b_sock.ptr, "default_value");
}
-static float3 get_node_output_vector(BL::Node& b_node, const string& name)
+static float3 get_node_output_vector(BL::Node &b_node, const string &name)
{
- BL::NodeSocket b_sock = get_node_output(b_node, name);
- float value[3];
- RNA_float_get_array(&b_sock.ptr, "default_value", value);
- return make_float3(value[0], value[1], value[2]);
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ float value[3];
+ RNA_float_get_array(&b_sock.ptr, "default_value", value);
+ return make_float3(value[0], value[1], value[2]);
}
-static SocketType::Type convert_socket_type(BL::NodeSocket& b_socket)
+static SocketType::Type convert_socket_type(BL::NodeSocket &b_socket)
{
- switch(b_socket.type()) {
- case BL::NodeSocket::type_VALUE:
- return SocketType::FLOAT;
- case BL::NodeSocket::type_INT:
- return SocketType::INT;
- case BL::NodeSocket::type_VECTOR:
- return SocketType::VECTOR;
- case BL::NodeSocket::type_RGBA:
- return SocketType::COLOR;
- case BL::NodeSocket::type_STRING:
- return SocketType::STRING;
- case BL::NodeSocket::type_SHADER:
- return SocketType::CLOSURE;
-
- default:
- return SocketType::UNDEFINED;
- }
+ switch (b_socket.type()) {
+ case BL::NodeSocket::type_VALUE:
+ return SocketType::FLOAT;
+ case BL::NodeSocket::type_INT:
+ return SocketType::INT;
+ case BL::NodeSocket::type_VECTOR:
+ return SocketType::VECTOR;
+ case BL::NodeSocket::type_RGBA:
+ return SocketType::COLOR;
+ case BL::NodeSocket::type_STRING:
+ return SocketType::STRING;
+ case BL::NodeSocket::type_SHADER:
+ return SocketType::CLOSURE;
+
+ default:
+ return SocketType::UNDEFINED;
+ }
}
static void set_default_value(ShaderInput *input,
- BL::NodeSocket& b_sock,
- BL::BlendData& b_data,
- BL::ID& b_id)
+ BL::NodeSocket &b_sock,
+ BL::BlendData &b_data,
+ BL::ID &b_id)
{
- Node *node = input->parent;
- const SocketType& socket = input->socket_type;
-
- /* copy values for non linked inputs */
- switch(input->type()) {
- case SocketType::FLOAT: {
- node->set(socket, get_float(b_sock.ptr, "default_value"));
- break;
- }
- case SocketType::INT: {
- node->set(socket, get_int(b_sock.ptr, "default_value"));
- break;
- }
- case SocketType::COLOR: {
- node->set(socket, float4_to_float3(get_float4(b_sock.ptr, "default_value")));
- break;
- }
- case SocketType::NORMAL:
- case SocketType::POINT:
- case SocketType::VECTOR: {
- node->set(socket, get_float3(b_sock.ptr, "default_value"));
- break;
- }
- case SocketType::STRING: {
- node->set(socket, (ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
- break;
- }
- default:
- break;
- }
+ Node *node = input->parent;
+ const SocketType &socket = input->socket_type;
+
+ /* copy values for non linked inputs */
+ switch (input->type()) {
+ case SocketType::FLOAT: {
+ node->set(socket, get_float(b_sock.ptr, "default_value"));
+ break;
+ }
+ case SocketType::INT: {
+ node->set(socket, get_int(b_sock.ptr, "default_value"));
+ break;
+ }
+ case SocketType::COLOR: {
+ node->set(socket, float4_to_float3(get_float4(b_sock.ptr, "default_value")));
+ break;
+ }
+ case SocketType::NORMAL:
+ case SocketType::POINT:
+ case SocketType::VECTOR: {
+ node->set(socket, get_float3(b_sock.ptr, "default_value"));
+ break;
+ }
+ case SocketType::STRING: {
+ node->set(
+ socket,
+ (ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
+ break;
+ }
+ default:
+ break;
+ }
}
-static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping& b_mapping)
+static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping &b_mapping)
{
- if(!b_mapping)
- return;
+ if (!b_mapping)
+ return;
- mapping->translation = get_float3(b_mapping.translation());
- mapping->rotation = get_float3(b_mapping.rotation());
- mapping->scale = get_float3(b_mapping.scale());
- mapping->type = (TextureMapping::Type)b_mapping.vector_type();
+ mapping->translation = get_float3(b_mapping.translation());
+ mapping->rotation = get_float3(b_mapping.rotation());
+ mapping->scale = get_float3(b_mapping.scale());
+ mapping->type = (TextureMapping::Type)b_mapping.vector_type();
- mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
- mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
- mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
+ mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
+ mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
+ mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
}
-static void get_tex_mapping(TextureMapping *mapping,
- BL::ShaderNodeMapping& b_mapping)
+static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping &b_mapping)
{
- if(!b_mapping)
- return;
+ if (!b_mapping)
+ return;
- mapping->translation = get_float3(b_mapping.translation());
- mapping->rotation = get_float3(b_mapping.rotation());
- mapping->scale = get_float3(b_mapping.scale());
- mapping->type = (TextureMapping::Type)b_mapping.vector_type();
+ mapping->translation = get_float3(b_mapping.translation());
+ mapping->rotation = get_float3(b_mapping.rotation());
+ mapping->scale = get_float3(b_mapping.scale());
+ mapping->type = (TextureMapping::Type)b_mapping.vector_type();
- mapping->use_minmax = b_mapping.use_min() || b_mapping.use_max();
+ mapping->use_minmax = b_mapping.use_min() || b_mapping.use_max();
- if(b_mapping.use_min())
- mapping->min = get_float3(b_mapping.min());
- if(b_mapping.use_max())
- mapping->max = get_float3(b_mapping.max());
+ if (b_mapping.use_min())
+ mapping->min = get_float3(b_mapping.min());
+ if (b_mapping.use_max())
+ mapping->max = get_float3(b_mapping.max());
}
static ShaderNode *add_node(Scene *scene,
- BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph,
- BL::Scene& b_scene,
+ BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Depsgraph &b_depsgraph,
+ BL::Scene &b_scene,
ShaderGraph *graph,
- BL::ShaderNodeTree& b_ntree,
- BL::ShaderNode& b_node)
+ BL::ShaderNodeTree &b_ntree,
+ BL::ShaderNode &b_node)
{
- ShaderNode *node = NULL;
-
- /* existing blender nodes */
- if(b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
- BL::ShaderNodeRGBCurve b_curve_node(b_node);
- BL::CurveMapping mapping(b_curve_node.mapping());
- RGBCurvesNode *curves = new RGBCurvesNode();
- curvemapping_color_to_array(mapping,
- curves->curves,
- RAMP_TABLE_SIZE,
- true);
- curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x);
- node = curves;
- }
- if(b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
- BL::ShaderNodeVectorCurve b_curve_node(b_node);
- BL::CurveMapping mapping(b_curve_node.mapping());
- VectorCurvesNode *curves = new VectorCurvesNode();
- curvemapping_color_to_array(mapping,
- curves->curves,
- RAMP_TABLE_SIZE,
- false);
- curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x);
- node = curves;
- }
- else if(b_node.is_a(&RNA_ShaderNodeValToRGB)) {
- RGBRampNode *ramp = new RGBRampNode();
- BL::ShaderNodeValToRGB b_ramp_node(b_node);
- BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp());
- colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE);
- ramp->interpolate = b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT;
- node = ramp;
- }
- else if(b_node.is_a(&RNA_ShaderNodeRGB)) {
- ColorNode *color = new ColorNode();
- color->value = get_node_output_rgba(b_node, "Color");
- node = color;
- }
- else if(b_node.is_a(&RNA_ShaderNodeValue)) {
- ValueNode *value = new ValueNode();
- value->value = get_node_output_value(b_node, "Value");
- node = value;
- }
- else if(b_node.is_a(&RNA_ShaderNodeCameraData)) {
- node = new CameraNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeInvert)) {
- node = new InvertNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeGamma)) {
- node = new GammaNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
- node = new BrightContrastNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeMixRGB)) {
- BL::ShaderNodeMixRGB b_mix_node(b_node);
- MixNode *mix = new MixNode();
- mix->type = (NodeMix)b_mix_node.blend_type();
- mix->use_clamp = b_mix_node.use_clamp();
- node = mix;
- }
- else if(b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
- node = new SeparateRGBNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeCombineRGB)) {
- node = new CombineRGBNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeSeparateHSV)) {
- node = new SeparateHSVNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeCombineHSV)) {
- node = new CombineHSVNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
- node = new SeparateXYZNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeCombineXYZ)) {
- node = new CombineXYZNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
- node = new HSVNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
- node = new RGBToBWNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeMath)) {
- BL::ShaderNodeMath b_math_node(b_node);
- MathNode *math = new MathNode();
- math->type = (NodeMath)b_math_node.operation();
- math->use_clamp = b_math_node.use_clamp();
- node = math;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVectorMath)) {
- BL::ShaderNodeVectorMath b_vector_math_node(b_node);
- VectorMathNode *vmath = new VectorMathNode();
- vmath->type = (NodeVectorMath)b_vector_math_node.operation();
- node = vmath;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
- BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
- VectorTransformNode *vtransform = new VectorTransformNode();
- vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type();
- vtransform->convert_from = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_from();
- vtransform->convert_to = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to();
- node = vtransform;
- }
- else if(b_node.is_a(&RNA_ShaderNodeNormal)) {
- BL::Node::outputs_iterator out_it;
- b_node.outputs.begin(out_it);
-
- NormalNode *norm = new NormalNode();
- norm->direction = get_node_output_vector(b_node, "Normal");
- node = norm;
- }
- else if(b_node.is_a(&RNA_ShaderNodeMapping)) {
- BL::ShaderNodeMapping b_mapping_node(b_node);
- MappingNode *mapping = new MappingNode();
-
- get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
-
- node = mapping;
- }
- else if(b_node.is_a(&RNA_ShaderNodeFresnel)) {
- node = new FresnelNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
- node = new LayerWeightNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeAddShader)) {
- node = new AddClosureNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeMixShader)) {
- node = new MixClosureNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeAttribute)) {
- BL::ShaderNodeAttribute b_attr_node(b_node);
- AttributeNode *attr = new AttributeNode();
- attr->attribute = b_attr_node.attribute_name();
- node = attr;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBackground)) {
- node = new BackgroundNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeHoldout)) {
- node = new HoldoutNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
- BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
- AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
-
- switch(b_aniso_node.distribution()) {
- case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
- aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
- aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
- aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID;
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
- aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
- break;
- }
-
- node = aniso;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
- node = new DiffuseBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) {
- BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node);
-
- SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode();
-
- switch(b_subsurface_node.falloff()) {
- case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
- subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID;
- break;
- case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN:
- subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID;
- break;
- case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
- subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID;
- break;
- case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
- subsurface->falloff = CLOSURE_BSSRDF_RANDOM_WALK_ID;
- break;
- }
-
- node = subsurface;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) {
- BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
- GlossyBsdfNode *glossy = new GlossyBsdfNode();
-
- switch(b_glossy_node.distribution()) {
- case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
- glossy->distribution = CLOSURE_BSDF_REFLECTION_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
- glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_GGX:
- glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY:
- glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX:
- glossy->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
- break;
- }
- node = glossy;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
- BL::ShaderNodeBsdfGlass b_glass_node(b_node);
- GlassBsdfNode *glass = new GlassBsdfNode();
- switch(b_glass_node.distribution()) {
- case BL::ShaderNodeBsdfGlass::distribution_SHARP:
- glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
- glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfGlass::distribution_GGX:
- glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX:
- glass->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
- break;
- }
- node = glass;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
- BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
- RefractionBsdfNode *refraction = new RefractionBsdfNode();
- switch(b_refraction_node.distribution()) {
- case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
- refraction->distribution = CLOSURE_BSDF_REFRACTION_ID;
- break;
- case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
- refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- break;
- case BL::ShaderNodeBsdfRefraction::distribution_GGX:
- refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- break;
- }
- node = refraction;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfToon)) {
- BL::ShaderNodeBsdfToon b_toon_node(b_node);
- ToonBsdfNode *toon = new ToonBsdfNode();
- switch(b_toon_node.component()) {
- case BL::ShaderNodeBsdfToon::component_DIFFUSE:
- toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID;
- break;
- case BL::ShaderNodeBsdfToon::component_GLOSSY:
- toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID;
- break;
- }
- node = toon;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfHair)) {
- BL::ShaderNodeBsdfHair b_hair_node(b_node);
- HairBsdfNode *hair = new HairBsdfNode();
- switch(b_hair_node.component()) {
- case BL::ShaderNodeBsdfHair::component_Reflection:
- hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID;
- break;
- case BL::ShaderNodeBsdfHair::component_Transmission:
- hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
- break;
- }
- node = hair;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
- BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
- PrincipledHairBsdfNode *principled_hair = new PrincipledHairBsdfNode();
- principled_hair->parametrization = (NodePrincipledHairParametrization) get_enum(b_principled_hair_node.ptr, "parametrization", NODE_PRINCIPLED_HAIR_NUM, NODE_PRINCIPLED_HAIR_REFLECTANCE);
- node = principled_hair;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
- BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
- PrincipledBsdfNode *principled = new PrincipledBsdfNode();
- switch (b_principled_node.distribution()) {
- case BL::ShaderNodeBsdfPrincipled::distribution_GGX:
- principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX:
- principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
- break;
- }
- switch (b_principled_node.subsurface_method()) {
- case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
- principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_ID;
- break;
- case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
- principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID;
- break;
- }
- node = principled;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
- node = new TranslucentBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
- node = new TransparentBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) {
- node = new VelvetBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeEmission)) {
- node = new EmissionNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
- BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
- AmbientOcclusionNode *ao = new AmbientOcclusionNode();
- ao->samples = b_ao_node.samples();
- ao->inside = b_ao_node.inside();
- ao->only_local = b_ao_node.only_local();
- node = ao;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
- node = new ScatterVolumeNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
- node = new AbsorptionVolumeNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeVolumePrincipled)) {
- PrincipledVolumeNode *principled = new PrincipledVolumeNode();
- node = principled;
- }
- else if(b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
- node = new GeometryNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeWireframe)) {
- BL::ShaderNodeWireframe b_wireframe_node(b_node);
- WireframeNode *wire = new WireframeNode();
- wire->use_pixel_size = b_wireframe_node.use_pixel_size();
- node = wire;
- }
- else if(b_node.is_a(&RNA_ShaderNodeWavelength)) {
- node = new WavelengthNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBlackbody)) {
- node = new BlackbodyNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeLightPath)) {
- node = new LightPathNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
- node = new LightFalloffNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
- node = new ObjectInfoNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
- node = new ParticleInfoNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeHairInfo)) {
- node = new HairInfoNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBump)) {
- BL::ShaderNodeBump b_bump_node(b_node);
- BumpNode *bump = new BumpNode();
- bump->invert = b_bump_node.invert();
- node = bump;
- }
- else if(b_node.is_a(&RNA_ShaderNodeScript)) {
+ ShaderNode *node = NULL;
+
+ /* existing blender nodes */
+ if (b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
+ BL::ShaderNodeRGBCurve b_curve_node(b_node);
+ BL::CurveMapping mapping(b_curve_node.mapping());
+ RGBCurvesNode *curves = new RGBCurvesNode();
+ curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, true);
+ curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x);
+ node = curves;
+ }
+ if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
+ BL::ShaderNodeVectorCurve b_curve_node(b_node);
+ BL::CurveMapping mapping(b_curve_node.mapping());
+ VectorCurvesNode *curves = new VectorCurvesNode();
+ curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, false);
+ curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x);
+ node = curves;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
+ RGBRampNode *ramp = new RGBRampNode();
+ BL::ShaderNodeValToRGB b_ramp_node(b_node);
+ BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp());
+ colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE);
+ ramp->interpolate = b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT;
+ node = ramp;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeRGB)) {
+ ColorNode *color = new ColorNode();
+ color->value = get_node_output_rgba(b_node, "Color");
+ node = color;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeValue)) {
+ ValueNode *value = new ValueNode();
+ value->value = get_node_output_value(b_node, "Value");
+ node = value;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCameraData)) {
+ node = new CameraNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeInvert)) {
+ node = new InvertNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeGamma)) {
+ node = new GammaNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
+ node = new BrightContrastNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) {
+ BL::ShaderNodeMixRGB b_mix_node(b_node);
+ MixNode *mix = new MixNode();
+ mix->type = (NodeMix)b_mix_node.blend_type();
+ mix->use_clamp = b_mix_node.use_clamp();
+ node = mix;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
+ node = new SeparateRGBNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCombineRGB)) {
+ node = new CombineRGBNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSeparateHSV)) {
+ node = new SeparateHSVNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCombineHSV)) {
+ node = new CombineHSVNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
+ node = new SeparateXYZNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCombineXYZ)) {
+ node = new CombineXYZNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
+ node = new HSVNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
+ node = new RGBToBWNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMath)) {
+ BL::ShaderNodeMath b_math_node(b_node);
+ MathNode *math = new MathNode();
+ math->type = (NodeMath)b_math_node.operation();
+ math->use_clamp = b_math_node.use_clamp();
+ node = math;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
+ BL::ShaderNodeVectorMath b_vector_math_node(b_node);
+ VectorMathNode *vmath = new VectorMathNode();
+ vmath->type = (NodeVectorMath)b_vector_math_node.operation();
+ node = vmath;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
+ BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
+ VectorTransformNode *vtransform = new VectorTransformNode();
+ vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type();
+ vtransform->convert_from = (NodeVectorTransformConvertSpace)
+ b_vector_transform_node.convert_from();
+ vtransform->convert_to = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to();
+ node = vtransform;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNormal)) {
+ BL::Node::outputs_iterator out_it;
+ b_node.outputs.begin(out_it);
+
+ NormalNode *norm = new NormalNode();
+ norm->direction = get_node_output_vector(b_node, "Normal");
+ node = norm;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMapping)) {
+ BL::ShaderNodeMapping b_mapping_node(b_node);
+ MappingNode *mapping = new MappingNode();
+
+ get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
+
+ node = mapping;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeFresnel)) {
+ node = new FresnelNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
+ node = new LayerWeightNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAddShader)) {
+ node = new AddClosureNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMixShader)) {
+ node = new MixClosureNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAttribute)) {
+ BL::ShaderNodeAttribute b_attr_node(b_node);
+ AttributeNode *attr = new AttributeNode();
+ attr->attribute = b_attr_node.attribute_name();
+ node = attr;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBackground)) {
+ node = new BackgroundNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHoldout)) {
+ node = new HoldoutNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
+ BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
+ AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
+
+ switch (b_aniso_node.distribution()) {
+ case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
+ aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
+ aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
+ aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID;
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
+ aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
+ break;
+ }
+
+ node = aniso;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
+ node = new DiffuseBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) {
+ BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node);
+
+ SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode();
+
+ switch (b_subsurface_node.falloff()) {
+ case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
+ subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID;
+ break;
+ case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN:
+ subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID;
+ break;
+ case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
+ subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID;
+ break;
+ case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
+ subsurface->falloff = CLOSURE_BSSRDF_RANDOM_WALK_ID;
+ break;
+ }
+
+ node = subsurface;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) {
+ BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
+ GlossyBsdfNode *glossy = new GlossyBsdfNode();
+
+ switch (b_glossy_node.distribution()) {
+ case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
+ glossy->distribution = CLOSURE_BSDF_REFLECTION_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
+ glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_GGX:
+ glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY:
+ glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX:
+ glossy->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
+ break;
+ }
+ node = glossy;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
+ BL::ShaderNodeBsdfGlass b_glass_node(b_node);
+ GlassBsdfNode *glass = new GlassBsdfNode();
+ switch (b_glass_node.distribution()) {
+ case BL::ShaderNodeBsdfGlass::distribution_SHARP:
+ glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
+ glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfGlass::distribution_GGX:
+ glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX:
+ glass->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ break;
+ }
+ node = glass;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
+ BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
+ RefractionBsdfNode *refraction = new RefractionBsdfNode();
+ switch (b_refraction_node.distribution()) {
+ case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
+ refraction->distribution = CLOSURE_BSDF_REFRACTION_ID;
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
+ refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_GGX:
+ refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ break;
+ }
+ node = refraction;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfToon)) {
+ BL::ShaderNodeBsdfToon b_toon_node(b_node);
+ ToonBsdfNode *toon = new ToonBsdfNode();
+ switch (b_toon_node.component()) {
+ case BL::ShaderNodeBsdfToon::component_DIFFUSE:
+ toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID;
+ break;
+ case BL::ShaderNodeBsdfToon::component_GLOSSY:
+ toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID;
+ break;
+ }
+ node = toon;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfHair)) {
+ BL::ShaderNodeBsdfHair b_hair_node(b_node);
+ HairBsdfNode *hair = new HairBsdfNode();
+ switch (b_hair_node.component()) {
+ case BL::ShaderNodeBsdfHair::component_Reflection:
+ hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID;
+ break;
+ case BL::ShaderNodeBsdfHair::component_Transmission:
+ hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
+ break;
+ }
+ node = hair;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
+ BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
+ PrincipledHairBsdfNode *principled_hair = new PrincipledHairBsdfNode();
+ principled_hair->parametrization = (NodePrincipledHairParametrization)get_enum(
+ b_principled_hair_node.ptr,
+ "parametrization",
+ NODE_PRINCIPLED_HAIR_NUM,
+ NODE_PRINCIPLED_HAIR_REFLECTANCE);
+ node = principled_hair;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
+ BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
+ PrincipledBsdfNode *principled = new PrincipledBsdfNode();
+ switch (b_principled_node.distribution()) {
+ case BL::ShaderNodeBsdfPrincipled::distribution_GGX:
+ principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX:
+ principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ break;
+ }
+ switch (b_principled_node.subsurface_method()) {
+ case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
+ principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_ID;
+ break;
+ case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
+ principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID;
+ break;
+ }
+ node = principled;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
+ node = new TranslucentBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
+ node = new TransparentBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) {
+ node = new VelvetBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeEmission)) {
+ node = new EmissionNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
+ BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
+ AmbientOcclusionNode *ao = new AmbientOcclusionNode();
+ ao->samples = b_ao_node.samples();
+ ao->inside = b_ao_node.inside();
+ ao->only_local = b_ao_node.only_local();
+ node = ao;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
+ node = new ScatterVolumeNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
+ node = new AbsorptionVolumeNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumePrincipled)) {
+ PrincipledVolumeNode *principled = new PrincipledVolumeNode();
+ node = principled;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
+ node = new GeometryNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeWireframe)) {
+ BL::ShaderNodeWireframe b_wireframe_node(b_node);
+ WireframeNode *wire = new WireframeNode();
+ wire->use_pixel_size = b_wireframe_node.use_pixel_size();
+ node = wire;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeWavelength)) {
+ node = new WavelengthNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBlackbody)) {
+ node = new BlackbodyNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLightPath)) {
+ node = new LightPathNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
+ node = new LightFalloffNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
+ node = new ObjectInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
+ node = new ParticleInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
+ node = new HairInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBump)) {
+ BL::ShaderNodeBump b_bump_node(b_node);
+ BumpNode *bump = new BumpNode();
+ bump->invert = b_bump_node.invert();
+ node = bump;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeScript)) {
#ifdef WITH_OSL
- if(scene->shader_manager->use_osl()) {
- /* create script node */
- BL::ShaderNodeScript b_script_node(b_node);
-
- OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager;
- string bytecode_hash = b_script_node.bytecode_hash();
-
- if(!bytecode_hash.empty()) {
- node = manager->osl_node("", bytecode_hash, b_script_node.bytecode());
- }
- else {
- string absolute_filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath());
- node = manager->osl_node(absolute_filepath, "");
- }
- }
+ if (scene->shader_manager->use_osl()) {
+ /* create script node */
+ BL::ShaderNodeScript b_script_node(b_node);
+
+ OSLShaderManager *manager = (OSLShaderManager *)scene->shader_manager;
+ string bytecode_hash = b_script_node.bytecode_hash();
+
+ if (!bytecode_hash.empty()) {
+ node = manager->osl_node("", bytecode_hash, b_script_node.bytecode());
+ }
+ else {
+ string absolute_filepath = blender_absolute_path(
+ b_data, b_ntree, b_script_node.filepath());
+ node = manager->osl_node(absolute_filepath, "");
+ }
+ }
#else
- (void) b_data;
- (void) b_ntree;
+ (void)b_data;
+ (void)b_ntree;
#endif
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexImage)) {
- BL::ShaderNodeTexImage b_image_node(b_node);
- BL::Image b_image(b_image_node.image());
- BL::ImageUser b_image_user(b_image_node.image_user());
- ImageTextureNode *image = new ImageTextureNode();
- if(b_image) {
- /* builtin images will use callback-based reading because
- * they could only be loaded correct from blender side
- */
- bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED ||
- b_image.source() == BL::Image::source_MOVIE ||
- (b_engine.is_preview() &&
- b_image.source() != BL::Image::source_SEQUENCE);
-
- if(is_builtin) {
- /* for builtin images we're using image datablock name to find an image to
- * read pixels from later
- *
- * also store frame number as well, so there's no differences in handling
- * builtin names for packed images and movies
- */
- int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user,
- scene_frame);
- image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
- image->builtin_data = b_image.ptr.data;
- }
- else {
- image->filename = image_user_file_path(b_image_user,
- b_image,
- b_scene.frame_current());
- image->builtin_data = NULL;
- }
-
- image->animated = b_image_node.image_user().use_auto_refresh();
- image->use_alpha = b_image.use_alpha();
-
- /* TODO: restore */
- /* TODO(sergey): Does not work properly when we change builtin type. */
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexImage)) {
+ BL::ShaderNodeTexImage b_image_node(b_node);
+ BL::Image b_image(b_image_node.image());
+ BL::ImageUser b_image_user(b_image_node.image_user());
+ ImageTextureNode *image = new ImageTextureNode();
+ if (b_image) {
+ /* builtin images will use callback-based reading because
+ * they could only be loaded correct from blender side
+ */
+ bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE ||
+ (b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE);
+
+ if (is_builtin) {
+ /* for builtin images we're using image datablock name to find an image to
+ * read pixels from later
+ *
+ * also store frame number as well, so there's no differences in handling
+ * builtin names for packed images and movies
+ */
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ image->builtin_data = b_image.ptr.data;
+ }
+ else {
+ image->filename = image_user_file_path(b_image_user, b_image, b_scene.frame_current());
+ image->builtin_data = NULL;
+ }
+
+ image->animated = b_image_node.image_user().use_auto_refresh();
+ image->use_alpha = b_image.use_alpha();
+
+ /* TODO: restore */
+ /* TODO(sergey): Does not work properly when we change builtin type. */
#if 0
- if(b_image.is_updated()) {
- scene->image_manager->tag_reload_image(
- image->filename.string(),
- image->builtin_data,
- get_image_interpolation(b_image_node),
- get_image_extension(b_image_node),
- image->use_alpha);
- }
+ if(b_image.is_updated()) {
+ scene->image_manager->tag_reload_image(
+ image->filename.string(),
+ image->builtin_data,
+ get_image_interpolation(b_image_node),
+ get_image_extension(b_image_node),
+ image->use_alpha);
+ }
#endif
- }
- image->color_space = (NodeImageColorSpace)b_image_node.color_space();
- image->projection = (NodeImageProjection)b_image_node.projection();
- image->interpolation = get_image_interpolation(b_image_node);
- image->extension = get_image_extension(b_image_node);
- image->projection_blend = b_image_node.projection_blend();
- BL::TexMapping b_texture_mapping(b_image_node.texture_mapping());
- get_tex_mapping(&image->tex_mapping, b_texture_mapping);
- node = image;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
- BL::ShaderNodeTexEnvironment b_env_node(b_node);
- BL::Image b_image(b_env_node.image());
- BL::ImageUser b_image_user(b_env_node.image_user());
- EnvironmentTextureNode *env = new EnvironmentTextureNode();
- if(b_image) {
- bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED ||
- b_image.source() == BL::Image::source_MOVIE ||
- (b_engine.is_preview() &&
- b_image.source() != BL::Image::source_SEQUENCE);
-
- if(is_builtin) {
- int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user,
- scene_frame);
- env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
- env->builtin_data = b_image.ptr.data;
- }
- else {
- env->filename = image_user_file_path(b_image_user,
- b_image,
- b_scene.frame_current());
- env->builtin_data = NULL;
- }
-
- env->animated = b_env_node.image_user().use_auto_refresh();
- env->use_alpha = b_image.use_alpha();
-
- /* TODO: restore */
- /* TODO(sergey): Does not work properly when we change builtin type. */
+ }
+ image->color_space = (NodeImageColorSpace)b_image_node.color_space();
+ image->projection = (NodeImageProjection)b_image_node.projection();
+ image->interpolation = get_image_interpolation(b_image_node);
+ image->extension = get_image_extension(b_image_node);
+ image->projection_blend = b_image_node.projection_blend();
+ BL::TexMapping b_texture_mapping(b_image_node.texture_mapping());
+ get_tex_mapping(&image->tex_mapping, b_texture_mapping);
+ node = image;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
+ BL::ShaderNodeTexEnvironment b_env_node(b_node);
+ BL::Image b_image(b_env_node.image());
+ BL::ImageUser b_image_user(b_env_node.image_user());
+ EnvironmentTextureNode *env = new EnvironmentTextureNode();
+ if (b_image) {
+ bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE ||
+ (b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE);
+
+ if (is_builtin) {
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ env->builtin_data = b_image.ptr.data;
+ }
+ else {
+ env->filename = image_user_file_path(b_image_user, b_image, b_scene.frame_current());
+ env->builtin_data = NULL;
+ }
+
+ env->animated = b_env_node.image_user().use_auto_refresh();
+ env->use_alpha = b_image.use_alpha();
+
+ /* TODO: restore */
+ /* TODO(sergey): Does not work properly when we change builtin type. */
#if 0
- if(b_image.is_updated()) {
- scene->image_manager->tag_reload_image(
- env->filename.string(),
- env->builtin_data,
- get_image_interpolation(b_env_node),
- EXTENSION_REPEAT,
- env->use_alpha);
- }
+ if(b_image.is_updated()) {
+ scene->image_manager->tag_reload_image(
+ env->filename.string(),
+ env->builtin_data,
+ get_image_interpolation(b_env_node),
+ EXTENSION_REPEAT,
+ env->use_alpha);
+ }
#endif
- }
- env->color_space = (NodeImageColorSpace)b_env_node.color_space();
- env->interpolation = get_image_interpolation(b_env_node);
- env->projection = (NodeEnvironmentProjection)b_env_node.projection();
- BL::TexMapping b_texture_mapping(b_env_node.texture_mapping());
- get_tex_mapping(&env->tex_mapping, b_texture_mapping);
- node = env;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexGradient)) {
- BL::ShaderNodeTexGradient b_gradient_node(b_node);
- GradientTextureNode *gradient = new GradientTextureNode();
- gradient->type = (NodeGradientType)b_gradient_node.gradient_type();
- BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping());
- get_tex_mapping(&gradient->tex_mapping, b_texture_mapping);
- node = gradient;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
- BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
- VoronoiTextureNode *voronoi = new VoronoiTextureNode();
- voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring();
- voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance();
- voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature();
- BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping());
- get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping);
- node = voronoi;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexMagic)) {
- BL::ShaderNodeTexMagic b_magic_node(b_node);
- MagicTextureNode *magic = new MagicTextureNode();
- magic->depth = b_magic_node.turbulence_depth();
- BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping());
- get_tex_mapping(&magic->tex_mapping, b_texture_mapping);
- node = magic;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexWave)) {
- BL::ShaderNodeTexWave b_wave_node(b_node);
- WaveTextureNode *wave = new WaveTextureNode();
- wave->type = (NodeWaveType)b_wave_node.wave_type();
- wave->profile = (NodeWaveProfile)b_wave_node.wave_profile();
- BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping());
- get_tex_mapping(&wave->tex_mapping, b_texture_mapping);
- node = wave;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexChecker)) {
- BL::ShaderNodeTexChecker b_checker_node(b_node);
- CheckerTextureNode *checker = new CheckerTextureNode();
- BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping());
- get_tex_mapping(&checker->tex_mapping, b_texture_mapping);
- node = checker;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexBrick)) {
- BL::ShaderNodeTexBrick b_brick_node(b_node);
- BrickTextureNode *brick = new BrickTextureNode();
- brick->offset = b_brick_node.offset();
- brick->offset_frequency = b_brick_node.offset_frequency();
- brick->squash = b_brick_node.squash();
- brick->squash_frequency = b_brick_node.squash_frequency();
- BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping());
- get_tex_mapping(&brick->tex_mapping, b_texture_mapping);
- node = brick;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexNoise)) {
- BL::ShaderNodeTexNoise b_noise_node(b_node);
- NoiseTextureNode *noise = new NoiseTextureNode();
- BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
- get_tex_mapping(&noise->tex_mapping, b_texture_mapping);
- node = noise;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexMusgrave)) {
- BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
- MusgraveTextureNode *musgrave = new MusgraveTextureNode();
- musgrave->type = (NodeMusgraveType)b_musgrave_node.musgrave_type();
- BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping());
- get_tex_mapping(&musgrave->tex_mapping, b_texture_mapping);
- node = musgrave;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexCoord)) {
- BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
- TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
- tex_coord->from_dupli = b_tex_coord_node.from_instancer();
- if(b_tex_coord_node.object()) {
- tex_coord->use_transform = true;
- tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world());
- }
- node = tex_coord;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexSky)) {
- BL::ShaderNodeTexSky b_sky_node(b_node);
- SkyTextureNode *sky = new SkyTextureNode();
- sky->type = (NodeSkyType)b_sky_node.sky_type();
- sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction()));
- sky->turbidity = b_sky_node.turbidity();
- sky->ground_albedo = b_sky_node.ground_albedo();
- BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping());
- get_tex_mapping(&sky->tex_mapping, b_texture_mapping);
- node = sky;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexIES)) {
- BL::ShaderNodeTexIES b_ies_node(b_node);
- IESLightNode *ies = new IESLightNode();
- switch(b_ies_node.mode()) {
- case BL::ShaderNodeTexIES::mode_EXTERNAL:
- ies->filename = blender_absolute_path(b_data, b_ntree, b_ies_node.filepath());
- break;
- case BL::ShaderNodeTexIES::mode_INTERNAL:
- ies->ies = get_text_datablock_content(b_ies_node.ies().ptr);
- if(ies->ies.empty()) {
- ies->ies = "\n";
- }
- break;
- }
- node = ies;
- }
- else if(b_node.is_a(&RNA_ShaderNodeNormalMap)) {
- BL::ShaderNodeNormalMap b_normal_map_node(b_node);
- NormalMapNode *nmap = new NormalMapNode();
- nmap->space = (NodeNormalMapSpace)b_normal_map_node.space();
- nmap->attribute = b_normal_map_node.uv_map();
- node = nmap;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTangent)) {
- BL::ShaderNodeTangent b_tangent_node(b_node);
- TangentNode *tangent = new TangentNode();
- tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type();
- tangent->axis = (NodeTangentAxis)b_tangent_node.axis();
- tangent->attribute = b_tangent_node.uv_map();
- node = tangent;
- }
- else if(b_node.is_a(&RNA_ShaderNodeUVMap)) {
- BL::ShaderNodeUVMap b_uvmap_node(b_node);
- UVMapNode *uvm = new UVMapNode();
- uvm->attribute = b_uvmap_node.uv_map();
- uvm->from_dupli = b_uvmap_node.from_instancer();
- node = uvm;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
- BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
- PointDensityTextureNode *point_density = new PointDensityTextureNode();
- point_density->filename = b_point_density_node.name();
- point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
- point_density->interpolation = get_image_interpolation(b_point_density_node);
- point_density->builtin_data = b_point_density_node.ptr.data;
- point_density->image_manager = scene->image_manager;
-
- /* TODO(sergey): Use more proper update flag. */
- if(true) {
- point_density->add_image();
- b_point_density_node.cache_point_density(b_depsgraph);
- scene->image_manager->tag_reload_image(
- point_density->filename.string(),
- point_density->builtin_data,
- point_density->interpolation,
- EXTENSION_CLIP,
- true);
- }
- node = point_density;
-
- /* Transformation form world space to texture space.
- *
- * NOTE: Do this after the texture is cached, this is because getting
- * min/max will need to access this cache.
- */
- BL::Object b_ob(b_point_density_node.object());
- if(b_ob) {
- float3 loc, size;
- point_density_texture_space(b_depsgraph,
- b_point_density_node,
- loc,
- size);
- point_density->tfm =
- transform_translate(-loc) * transform_scale(size) *
- transform_inverse(get_transform(b_ob.matrix_world()));
- }
- }
- else if(b_node.is_a(&RNA_ShaderNodeBevel)) {
- BL::ShaderNodeBevel b_bevel_node(b_node);
- BevelNode *bevel = new BevelNode();
- bevel->samples = b_bevel_node.samples();
- node = bevel;
- }
- else if(b_node.is_a(&RNA_ShaderNodeDisplacement)) {
- BL::ShaderNodeDisplacement b_disp_node(b_node);
- DisplacementNode *disp = new DisplacementNode();
- disp->space = (NodeNormalMapSpace)b_disp_node.space();
- node = disp;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) {
- BL::ShaderNodeVectorDisplacement b_disp_node(b_node);
- VectorDisplacementNode *disp = new VectorDisplacementNode();
- disp->space = (NodeNormalMapSpace)b_disp_node.space();
- disp->attribute = "";
- node = disp;
- }
-
- if(node) {
- node->name = b_node.name();
- graph->add(node);
- }
-
- return node;
+ }
+ env->color_space = (NodeImageColorSpace)b_env_node.color_space();
+ env->interpolation = get_image_interpolation(b_env_node);
+ env->projection = (NodeEnvironmentProjection)b_env_node.projection();
+ BL::TexMapping b_texture_mapping(b_env_node.texture_mapping());
+ get_tex_mapping(&env->tex_mapping, b_texture_mapping);
+ node = env;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) {
+ BL::ShaderNodeTexGradient b_gradient_node(b_node);
+ GradientTextureNode *gradient = new GradientTextureNode();
+ gradient->type = (NodeGradientType)b_gradient_node.gradient_type();
+ BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping());
+ get_tex_mapping(&gradient->tex_mapping, b_texture_mapping);
+ node = gradient;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
+ BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
+ VoronoiTextureNode *voronoi = new VoronoiTextureNode();
+ voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring();
+ voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance();
+ voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature();
+ BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping());
+ get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping);
+ node = voronoi;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) {
+ BL::ShaderNodeTexMagic b_magic_node(b_node);
+ MagicTextureNode *magic = new MagicTextureNode();
+ magic->depth = b_magic_node.turbulence_depth();
+ BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping());
+ get_tex_mapping(&magic->tex_mapping, b_texture_mapping);
+ node = magic;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexWave)) {
+ BL::ShaderNodeTexWave b_wave_node(b_node);
+ WaveTextureNode *wave = new WaveTextureNode();
+ wave->type = (NodeWaveType)b_wave_node.wave_type();
+ wave->profile = (NodeWaveProfile)b_wave_node.wave_profile();
+ BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping());
+ get_tex_mapping(&wave->tex_mapping, b_texture_mapping);
+ node = wave;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) {
+ BL::ShaderNodeTexChecker b_checker_node(b_node);
+ CheckerTextureNode *checker = new CheckerTextureNode();
+ BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping());
+ get_tex_mapping(&checker->tex_mapping, b_texture_mapping);
+ node = checker;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) {
+ BL::ShaderNodeTexBrick b_brick_node(b_node);
+ BrickTextureNode *brick = new BrickTextureNode();
+ brick->offset = b_brick_node.offset();
+ brick->offset_frequency = b_brick_node.offset_frequency();
+ brick->squash = b_brick_node.squash();
+ brick->squash_frequency = b_brick_node.squash_frequency();
+ BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping());
+ get_tex_mapping(&brick->tex_mapping, b_texture_mapping);
+ node = brick;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) {
+ BL::ShaderNodeTexNoise b_noise_node(b_node);
+ NoiseTextureNode *noise = new NoiseTextureNode();
+ BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
+ get_tex_mapping(&noise->tex_mapping, b_texture_mapping);
+ node = noise;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexMusgrave)) {
+ BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
+ MusgraveTextureNode *musgrave = new MusgraveTextureNode();
+ musgrave->type = (NodeMusgraveType)b_musgrave_node.musgrave_type();
+ BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping());
+ get_tex_mapping(&musgrave->tex_mapping, b_texture_mapping);
+ node = musgrave;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) {
+ BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
+ TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
+ tex_coord->from_dupli = b_tex_coord_node.from_instancer();
+ if (b_tex_coord_node.object()) {
+ tex_coord->use_transform = true;
+ tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world());
+ }
+ node = tex_coord;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexSky)) {
+ BL::ShaderNodeTexSky b_sky_node(b_node);
+ SkyTextureNode *sky = new SkyTextureNode();
+ sky->type = (NodeSkyType)b_sky_node.sky_type();
+ sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction()));
+ sky->turbidity = b_sky_node.turbidity();
+ sky->ground_albedo = b_sky_node.ground_albedo();
+ BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping());
+ get_tex_mapping(&sky->tex_mapping, b_texture_mapping);
+ node = sky;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexIES)) {
+ BL::ShaderNodeTexIES b_ies_node(b_node);
+ IESLightNode *ies = new IESLightNode();
+ switch (b_ies_node.mode()) {
+ case BL::ShaderNodeTexIES::mode_EXTERNAL:
+ ies->filename = blender_absolute_path(b_data, b_ntree, b_ies_node.filepath());
+ break;
+ case BL::ShaderNodeTexIES::mode_INTERNAL:
+ ies->ies = get_text_datablock_content(b_ies_node.ies().ptr);
+ if (ies->ies.empty()) {
+ ies->ies = "\n";
+ }
+ break;
+ }
+ node = ies;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) {
+ BL::ShaderNodeNormalMap b_normal_map_node(b_node);
+ NormalMapNode *nmap = new NormalMapNode();
+ nmap->space = (NodeNormalMapSpace)b_normal_map_node.space();
+ nmap->attribute = b_normal_map_node.uv_map();
+ node = nmap;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTangent)) {
+ BL::ShaderNodeTangent b_tangent_node(b_node);
+ TangentNode *tangent = new TangentNode();
+ tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type();
+ tangent->axis = (NodeTangentAxis)b_tangent_node.axis();
+ tangent->attribute = b_tangent_node.uv_map();
+ node = tangent;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeUVMap)) {
+ BL::ShaderNodeUVMap b_uvmap_node(b_node);
+ UVMapNode *uvm = new UVMapNode();
+ uvm->attribute = b_uvmap_node.uv_map();
+ uvm->from_dupli = b_uvmap_node.from_instancer();
+ node = uvm;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
+ BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
+ PointDensityTextureNode *point_density = new PointDensityTextureNode();
+ point_density->filename = b_point_density_node.name();
+ point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
+ point_density->interpolation = get_image_interpolation(b_point_density_node);
+ point_density->builtin_data = b_point_density_node.ptr.data;
+ point_density->image_manager = scene->image_manager;
+
+ /* TODO(sergey): Use more proper update flag. */
+ if (true) {
+ point_density->add_image();
+ b_point_density_node.cache_point_density(b_depsgraph);
+ scene->image_manager->tag_reload_image(point_density->filename.string(),
+ point_density->builtin_data,
+ point_density->interpolation,
+ EXTENSION_CLIP,
+ true);
+ }
+ node = point_density;
+
+ /* Transformation form world space to texture space.
+ *
+ * NOTE: Do this after the texture is cached, this is because getting
+ * min/max will need to access this cache.
+ */
+ BL::Object b_ob(b_point_density_node.object());
+ if (b_ob) {
+ float3 loc, size;
+ point_density_texture_space(b_depsgraph, b_point_density_node, loc, size);
+ point_density->tfm = transform_translate(-loc) * transform_scale(size) *
+ transform_inverse(get_transform(b_ob.matrix_world()));
+ }
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBevel)) {
+ BL::ShaderNodeBevel b_bevel_node(b_node);
+ BevelNode *bevel = new BevelNode();
+ bevel->samples = b_bevel_node.samples();
+ node = bevel;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeDisplacement)) {
+ BL::ShaderNodeDisplacement b_disp_node(b_node);
+ DisplacementNode *disp = new DisplacementNode();
+ disp->space = (NodeNormalMapSpace)b_disp_node.space();
+ node = disp;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) {
+ BL::ShaderNodeVectorDisplacement b_disp_node(b_node);
+ VectorDisplacementNode *disp = new VectorDisplacementNode();
+ disp->space = (NodeNormalMapSpace)b_disp_node.space();
+ disp->attribute = "";
+ node = disp;
+ }
+
+ if (node) {
+ node->name = b_node.name();
+ graph->add(node);
+ }
+
+ return node;
}
static bool node_use_modified_socket_name(ShaderNode *node)
{
- if(node->special_type == SHADER_SPECIAL_TYPE_SCRIPT)
- return false;
+ if (node->special_type == SHADER_SPECIAL_TYPE_SCRIPT)
+ return false;
- return true;
+ return true;
}
static ShaderInput *node_find_input_by_name(ShaderNode *node,
- BL::Node& b_node,
- BL::NodeSocket& b_socket)
+ BL::Node &b_node,
+ BL::NodeSocket &b_socket)
{
- string name = b_socket.name();
+ string name = b_socket.name();
- if(node_use_modified_socket_name(node)) {
- BL::Node::inputs_iterator b_input;
- bool found = false;
- int counter = 0, total = 0;
+ if (node_use_modified_socket_name(node)) {
+ BL::Node::inputs_iterator b_input;
+ bool found = false;
+ int counter = 0, total = 0;
- for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
- if(b_input->name() == name) {
- if(!found)
- counter++;
- total++;
- }
+ for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
+ if (b_input->name() == name) {
+ if (!found)
+ counter++;
+ total++;
+ }
- if(b_input->ptr.data == b_socket.ptr.data)
- found = true;
- }
+ if (b_input->ptr.data == b_socket.ptr.data)
+ found = true;
+ }
- /* rename if needed */
- if(name == "Shader")
- name = "Closure";
+ /* rename if needed */
+ if (name == "Shader")
+ name = "Closure";
- if(total > 1)
- name = string_printf("%s%d", name.c_str(), counter);
- }
+ if (total > 1)
+ name = string_printf("%s%d", name.c_str(), counter);
+ }
- return node->input(name.c_str());
+ return node->input(name.c_str());
}
static ShaderOutput *node_find_output_by_name(ShaderNode *node,
- BL::Node& b_node,
- BL::NodeSocket& b_socket)
+ BL::Node &b_node,
+ BL::NodeSocket &b_socket)
{
- string name = b_socket.name();
+ string name = b_socket.name();
- if(node_use_modified_socket_name(node)) {
- BL::Node::outputs_iterator b_output;
- bool found = false;
- int counter = 0, total = 0;
+ if (node_use_modified_socket_name(node)) {
+ BL::Node::outputs_iterator b_output;
+ bool found = false;
+ int counter = 0, total = 0;
- for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
- if(b_output->name() == name) {
- if(!found)
- counter++;
- total++;
- }
+ for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
+ if (b_output->name() == name) {
+ if (!found)
+ counter++;
+ total++;
+ }
- if(b_output->ptr.data == b_socket.ptr.data)
- found = true;
- }
+ if (b_output->ptr.data == b_socket.ptr.data)
+ found = true;
+ }
- /* rename if needed */
- if(name == "Shader")
- name = "Closure";
+ /* rename if needed */
+ if (name == "Shader")
+ name = "Closure";
- if(total > 1)
- name = string_printf("%s%d", name.c_str(), counter);
- }
+ if (total > 1)
+ name = string_printf("%s%d", name.c_str(), counter);
+ }
- return node->output(name.c_str());
+ return node->output(name.c_str());
}
static void add_nodes(Scene *scene,
- BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph,
- BL::Scene& b_scene,
+ BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Depsgraph &b_depsgraph,
+ BL::Scene &b_scene,
ShaderGraph *graph,
- BL::ShaderNodeTree& b_ntree,
+ BL::ShaderNodeTree &b_ntree,
const ProxyMap &proxy_input_map,
const ProxyMap &proxy_output_map)
{
- /* add nodes */
- BL::ShaderNodeTree::nodes_iterator b_node;
- PtrInputMap input_map;
- PtrOutputMap output_map;
-
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
-
- /* find the node to use for output if there are multiple */
- BL::ShaderNode output_node = b_ntree.get_output_node(BL::ShaderNodeOutputMaterial::target_CYCLES);
-
- /* add nodes */
- for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
- if(b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
- /* replace muted node with internal links */
- BL::Node::internal_links_iterator b_link;
- for(b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end(); ++b_link) {
- BL::NodeSocket to_socket(b_link->to_socket());
- SocketType::Type to_socket_type = convert_socket_type(to_socket);
- if(to_socket_type == SocketType::UNDEFINED) {
- continue;
- }
-
- ConvertNode *proxy = new ConvertNode(to_socket_type, to_socket_type, true);
-
- input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
- output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
-
- graph->add(proxy);
- }
- }
- else if(b_node->is_a(&RNA_ShaderNodeGroup) ||
- b_node->is_a(&RNA_NodeCustomGroup) ||
- b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
-
- BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
- if(b_node->is_a(&RNA_ShaderNodeGroup))
- b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
- else if (b_node->is_a(&RNA_NodeCustomGroup))
- b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
- else
- b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
-
- ProxyMap group_proxy_input_map, group_proxy_output_map;
-
- /* Add a proxy node for each socket
- * Do this even if the node group has no internal tree,
- * so that links have something to connect to and assert won't fail.
- */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- SocketType::Type input_type = convert_socket_type(*b_input);
- if(input_type == SocketType::UNDEFINED) {
- continue;
- }
-
- ConvertNode *proxy = new ConvertNode(input_type, input_type, true);
- graph->add(proxy);
-
- /* register the proxy node for internal binding */
- group_proxy_input_map[b_input->identifier()] = proxy;
-
- input_map[b_input->ptr.data] = proxy->inputs[0];
-
- set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
- }
- for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- SocketType::Type output_type = convert_socket_type(*b_output);
- if(output_type == SocketType::UNDEFINED) {
- continue;
- }
-
- ConvertNode *proxy = new ConvertNode(output_type, output_type, true);
- graph->add(proxy);
-
- /* register the proxy node for internal binding */
- group_proxy_output_map[b_output->identifier()] = proxy;
-
- output_map[b_output->ptr.data] = proxy->outputs[0];
- }
-
- if(b_group_ntree) {
- add_nodes(scene,
- b_engine,
- b_data,
- b_depsgraph,
- b_scene,
- graph,
- b_group_ntree,
- group_proxy_input_map,
- group_proxy_output_map);
- }
- }
- else if(b_node->is_a(&RNA_NodeGroupInput)) {
- /* map each socket to a proxy node */
- for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
- if(proxy_it != proxy_input_map.end()) {
- ConvertNode *proxy = proxy_it->second;
-
- output_map[b_output->ptr.data] = proxy->outputs[0];
- }
- }
- }
- else if(b_node->is_a(&RNA_NodeGroupOutput)) {
- BL::NodeGroupOutput b_output_node(*b_node);
- /* only the active group output is used */
- if(b_output_node.is_active_output()) {
- /* map each socket to a proxy node */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
- if(proxy_it != proxy_output_map.end()) {
- ConvertNode *proxy = proxy_it->second;
-
- input_map[b_input->ptr.data] = proxy->inputs[0];
-
- set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
- }
- }
- }
- }
- else {
- ShaderNode *node = NULL;
-
- if(b_node->ptr.data == output_node.ptr.data) {
- node = graph->output();
- }
- else {
- BL::ShaderNode b_shader_node(*b_node);
- node = add_node(scene,
- b_engine,
- b_data,
- b_depsgraph,
- b_scene,
- graph,
- b_ntree,
- b_shader_node);
- }
-
- if(node) {
- /* map node sockets for linking */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
- if(!input) {
- /* XXX should not happen, report error? */
- continue;
- }
- input_map[b_input->ptr.data] = input;
-
- set_default_value(input, *b_input, b_data, b_ntree);
- }
- for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
- if(!output) {
- /* XXX should not happen, report error? */
- continue;
- }
- output_map[b_output->ptr.data] = output;
- }
- }
- }
- }
-
- /* connect nodes */
- BL::NodeTree::links_iterator b_link;
-
- for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
- /* Ignore invalid links to avoid unwanted cycles created in graph. */
- if(!b_link->is_valid()) {
- continue;
- }
- /* get blender link data */
- BL::NodeSocket b_from_sock = b_link->from_socket();
- BL::NodeSocket b_to_sock = b_link->to_socket();
-
- ShaderOutput *output = 0;
- ShaderInput *input = 0;
-
- PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
- if(output_it != output_map.end())
- output = output_it->second;
- PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data);
- if(input_it != input_map.end())
- input = input_it->second;
-
- /* either node may be NULL when the node was not exported, typically
- * because the node type is not supported */
- if(output && input)
- graph->connect(output, input);
- }
+ /* add nodes */
+ BL::ShaderNodeTree::nodes_iterator b_node;
+ PtrInputMap input_map;
+ PtrOutputMap output_map;
+
+ BL::Node::inputs_iterator b_input;
+ BL::Node::outputs_iterator b_output;
+
+ /* find the node to use for output if there are multiple */
+ BL::ShaderNode output_node = b_ntree.get_output_node(
+ BL::ShaderNodeOutputMaterial::target_CYCLES);
+
+ /* add nodes */
+ for (b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
+ if (b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
+ /* replace muted node with internal links */
+ BL::Node::internal_links_iterator b_link;
+ for (b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end();
+ ++b_link) {
+ BL::NodeSocket to_socket(b_link->to_socket());
+ SocketType::Type to_socket_type = convert_socket_type(to_socket);
+ if (to_socket_type == SocketType::UNDEFINED) {
+ continue;
+ }
+
+ ConvertNode *proxy = new ConvertNode(to_socket_type, to_socket_type, true);
+
+ input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
+ output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
+
+ graph->add(proxy);
+ }
+ }
+ else if (b_node->is_a(&RNA_ShaderNodeGroup) || b_node->is_a(&RNA_NodeCustomGroup) ||
+ b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
+
+ BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
+ if (b_node->is_a(&RNA_ShaderNodeGroup))
+ b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
+ else if (b_node->is_a(&RNA_NodeCustomGroup))
+ b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
+ else
+ b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
+
+ ProxyMap group_proxy_input_map, group_proxy_output_map;
+
+ /* Add a proxy node for each socket
+ * Do this even if the node group has no internal tree,
+ * so that links have something to connect to and assert won't fail.
+ */
+ for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ SocketType::Type input_type = convert_socket_type(*b_input);
+ if (input_type == SocketType::UNDEFINED) {
+ continue;
+ }
+
+ ConvertNode *proxy = new ConvertNode(input_type, input_type, true);
+ graph->add(proxy);
+
+ /* register the proxy node for internal binding */
+ group_proxy_input_map[b_input->identifier()] = proxy;
+
+ input_map[b_input->ptr.data] = proxy->inputs[0];
+
+ set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
+ }
+ for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ SocketType::Type output_type = convert_socket_type(*b_output);
+ if (output_type == SocketType::UNDEFINED) {
+ continue;
+ }
+
+ ConvertNode *proxy = new ConvertNode(output_type, output_type, true);
+ graph->add(proxy);
+
+ /* register the proxy node for internal binding */
+ group_proxy_output_map[b_output->identifier()] = proxy;
+
+ output_map[b_output->ptr.data] = proxy->outputs[0];
+ }
+
+ if (b_group_ntree) {
+ add_nodes(scene,
+ b_engine,
+ b_data,
+ b_depsgraph,
+ b_scene,
+ graph,
+ b_group_ntree,
+ group_proxy_input_map,
+ group_proxy_output_map);
+ }
+ }
+ else if (b_node->is_a(&RNA_NodeGroupInput)) {
+ /* map each socket to a proxy node */
+ for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
+ if (proxy_it != proxy_input_map.end()) {
+ ConvertNode *proxy = proxy_it->second;
+
+ output_map[b_output->ptr.data] = proxy->outputs[0];
+ }
+ }
+ }
+ else if (b_node->is_a(&RNA_NodeGroupOutput)) {
+ BL::NodeGroupOutput b_output_node(*b_node);
+ /* only the active group output is used */
+ if (b_output_node.is_active_output()) {
+ /* map each socket to a proxy node */
+ for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
+ if (proxy_it != proxy_output_map.end()) {
+ ConvertNode *proxy = proxy_it->second;
+
+ input_map[b_input->ptr.data] = proxy->inputs[0];
+
+ set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
+ }
+ }
+ }
+ }
+ else {
+ ShaderNode *node = NULL;
+
+ if (b_node->ptr.data == output_node.ptr.data) {
+ node = graph->output();
+ }
+ else {
+ BL::ShaderNode b_shader_node(*b_node);
+ node = add_node(
+ scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree, b_shader_node);
+ }
+
+ if (node) {
+ /* map node sockets for linking */
+ for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
+ if (!input) {
+ /* XXX should not happen, report error? */
+ continue;
+ }
+ input_map[b_input->ptr.data] = input;
+
+ set_default_value(input, *b_input, b_data, b_ntree);
+ }
+ for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
+ if (!output) {
+ /* XXX should not happen, report error? */
+ continue;
+ }
+ output_map[b_output->ptr.data] = output;
+ }
+ }
+ }
+ }
+
+ /* connect nodes */
+ BL::NodeTree::links_iterator b_link;
+
+ for (b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
+ /* Ignore invalid links to avoid unwanted cycles created in graph. */
+ if (!b_link->is_valid()) {
+ continue;
+ }
+ /* get blender link data */
+ BL::NodeSocket b_from_sock = b_link->from_socket();
+ BL::NodeSocket b_to_sock = b_link->to_socket();
+
+ ShaderOutput *output = 0;
+ ShaderInput *input = 0;
+
+ PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
+ if (output_it != output_map.end())
+ output = output_it->second;
+ PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data);
+ if (input_it != input_map.end())
+ input = input_it->second;
+
+ /* either node may be NULL when the node was not exported, typically
+ * because the node type is not supported */
+ if (output && input)
+ graph->connect(output, input);
+ }
}
static void add_nodes(Scene *scene,
- BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph,
- BL::Scene& b_scene,
+ BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Depsgraph &b_depsgraph,
+ BL::Scene &b_scene,
ShaderGraph *graph,
- BL::ShaderNodeTree& b_ntree)
+ BL::ShaderNodeTree &b_ntree)
{
- static const ProxyMap empty_proxy_map;
- add_nodes(scene,
- b_engine,
- b_data,
- b_depsgraph,
- b_scene,
- graph,
- b_ntree,
- empty_proxy_map,
- empty_proxy_map);
+ static const ProxyMap empty_proxy_map;
+ add_nodes(scene,
+ b_engine,
+ b_data,
+ b_depsgraph,
+ b_scene,
+ graph,
+ b_ntree,
+ empty_proxy_map,
+ empty_proxy_map);
}
/* Sync Materials */
-void BlenderSync::sync_materials(BL::Depsgraph& b_depsgraph, bool update_all)
+void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
{
- shader_map.set_default(scene->default_surface);
-
- TaskPool pool;
- set<Shader*> updated_shaders;
-
- BL::Depsgraph::ids_iterator b_id;
- for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
- if(!b_id->is_a(&RNA_Material)) {
- continue;
- }
-
- BL::Material b_mat(*b_id);
- Shader *shader;
-
- /* test if we need to sync */
- if(shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) {
- ShaderGraph *graph = new ShaderGraph();
-
- shader->name = b_mat.name().c_str();
- shader->pass_id = b_mat.pass_index();
- shader->need_sync_object = false;
-
- /* create nodes */
- if(b_mat.use_nodes() && b_mat.node_tree()) {
- BL::ShaderNodeTree b_ntree(b_mat.node_tree());
-
- add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
- }
- else {
- DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
- diffuse->color = get_float3(b_mat.diffuse_color());
- graph->add(diffuse);
-
- ShaderNode *out = graph->output();
- graph->connect(diffuse->output("BSDF"), out->input("Surface"));
- }
-
- /* settings */
- PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
- shader->use_mis = get_boolean(cmat, "sample_as_light");
- shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow");
- shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume");
- shader->volume_sampling_method = get_volume_sampling(cmat);
- shader->volume_interpolation_method = get_volume_interpolation(cmat);
- shader->displacement_method = get_displacement_method(cmat);
-
- shader->set_graph(graph);
-
- /* By simplifying the shader graph as soon as possible, some
- * redundant shader nodes might be removed which prevents loading
- * unnecessary attributes later.
- *
- * However, since graph simplification also accounts for e.g. mix
- * weight, this would cause frequent expensive resyncs in interactive
- * sessions, so for those sessions optimization is only performed
- * right before compiling.
- */
- if(!preview) {
- pool.push(function_bind(&ShaderGraph::simplify, graph, scene));
- /* NOTE: Update shaders out of the threads since those routines
- * are accessing and writing to a global context.
- */
- updated_shaders.insert(shader);
- }
- else {
- /* NOTE: Update tagging can access links which are being
- * optimized out.
- */
- shader->tag_update(scene);
- }
- }
- }
-
- pool.wait_work();
-
- foreach(Shader *shader, updated_shaders) {
- shader->tag_update(scene);
- }
+ shader_map.set_default(scene->default_surface);
+
+ TaskPool pool;
+ set<Shader *> updated_shaders;
+
+ BL::Depsgraph::ids_iterator b_id;
+ for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+ if (!b_id->is_a(&RNA_Material)) {
+ continue;
+ }
+
+ BL::Material b_mat(*b_id);
+ Shader *shader;
+
+ /* test if we need to sync */
+ if (shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) {
+ ShaderGraph *graph = new ShaderGraph();
+
+ shader->name = b_mat.name().c_str();
+ shader->pass_id = b_mat.pass_index();
+ shader->need_sync_object = false;
+
+ /* create nodes */
+ if (b_mat.use_nodes() && b_mat.node_tree()) {
+ BL::ShaderNodeTree b_ntree(b_mat.node_tree());
+
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
+ }
+ else {
+ DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
+ diffuse->color = get_float3(b_mat.diffuse_color());
+ graph->add(diffuse);
+
+ ShaderNode *out = graph->output();
+ graph->connect(diffuse->output("BSDF"), out->input("Surface"));
+ }
+
+ /* settings */
+ PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
+ shader->use_mis = get_boolean(cmat, "sample_as_light");
+ shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow");
+ shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume");
+ shader->volume_sampling_method = get_volume_sampling(cmat);
+ shader->volume_interpolation_method = get_volume_interpolation(cmat);
+ shader->displacement_method = get_displacement_method(cmat);
+
+ shader->set_graph(graph);
+
+ /* By simplifying the shader graph as soon as possible, some
+ * redundant shader nodes might be removed which prevents loading
+ * unnecessary attributes later.
+ *
+ * However, since graph simplification also accounts for e.g. mix
+ * weight, this would cause frequent expensive resyncs in interactive
+ * sessions, so for those sessions optimization is only performed
+ * right before compiling.
+ */
+ if (!preview) {
+ pool.push(function_bind(&ShaderGraph::simplify, graph, scene));
+ /* NOTE: Update shaders out of the threads since those routines
+ * are accessing and writing to a global context.
+ */
+ updated_shaders.insert(shader);
+ }
+ else {
+ /* NOTE: Update tagging can access links which are being
+ * optimized out.
+ */
+ shader->tag_update(scene);
+ }
+ }
+ }
+
+ pool.wait_work();
+
+ foreach (Shader *shader, updated_shaders) {
+ shader->tag_update(scene);
+ }
}
/* Sync World */
-void BlenderSync::sync_world(BL::Depsgraph& b_depsgraph, bool update_all)
+void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, bool update_all)
{
- Background *background = scene->background;
- Background prevbackground = *background;
-
- BL::World b_world = b_scene.world();
-
- if(world_recalc || update_all || b_world.ptr.data != world_map) {
- Shader *shader = scene->default_background;
- ShaderGraph *graph = new ShaderGraph();
-
- /* create nodes */
- if(b_world && b_world.use_nodes() && b_world.node_tree()) {
- BL::ShaderNodeTree b_ntree(b_world.node_tree());
-
- add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
-
- /* volume */
- PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
- shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume");
- shader->volume_sampling_method = get_volume_sampling(cworld);
- shader->volume_interpolation_method = get_volume_interpolation(cworld);
- }
- else if(b_world) {
- BackgroundNode *background = new BackgroundNode();
- background->color = get_float3(b_world.color());
- graph->add(background);
-
- ShaderNode *out = graph->output();
- graph->connect(background->output("Background"), out->input("Surface"));
- }
-
- if(b_world) {
- /* AO */
- BL::WorldLighting b_light = b_world.light_settings();
-
- background->use_ao = b_light.use_ambient_occlusion();
- background->ao_factor = b_light.ao_factor();
- background->ao_distance = b_light.distance();
-
- /* visibility */
- PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
- uint visibility = 0;
-
- visibility |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0;
- visibility |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0;
- visibility |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0;
- visibility |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0;
- visibility |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0;
-
- background->visibility = visibility;
- }
- else {
- background->use_ao = false;
- background->ao_factor = 0.0f;
- background->ao_distance = FLT_MAX;
- }
-
- shader->set_graph(graph);
- shader->tag_update(scene);
- background->tag_update(scene);
- }
-
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- /* when doing preview render check for BI's transparency settings,
- * this is so because Blender's preview render routines are not able
- * to tweak all cycles's settings depending on different circumstances
- */
- if(b_engine.is_preview() == false)
- background->transparent = get_boolean(cscene, "film_transparent");
- else
- background->transparent = b_scene.render().alpha_mode() == BL::RenderSettings::alpha_mode_TRANSPARENT;
-
- if(background->transparent) {
- background->transparent_glass = get_boolean(cscene, "film_transparent_glass");
- background->transparent_roughness_threshold = get_float(cscene, "film_transparent_roughness");
- }
- else {
- background->transparent_glass = false;
- background->transparent_roughness_threshold = 0.0f;
- }
-
- background->use_shader = view_layer.use_background_shader;
- background->use_ao = background->use_ao && view_layer.use_background_ao;
-
- if(background->modified(prevbackground))
- background->tag_update(scene);
+ Background *background = scene->background;
+ Background prevbackground = *background;
+
+ BL::World b_world = b_scene.world();
+
+ if (world_recalc || update_all || b_world.ptr.data != world_map) {
+ Shader *shader = scene->default_background;
+ ShaderGraph *graph = new ShaderGraph();
+
+ /* create nodes */
+ if (b_world && b_world.use_nodes() && b_world.node_tree()) {
+ BL::ShaderNodeTree b_ntree(b_world.node_tree());
+
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
+
+ /* volume */
+ PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
+ shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume");
+ shader->volume_sampling_method = get_volume_sampling(cworld);
+ shader->volume_interpolation_method = get_volume_interpolation(cworld);
+ }
+ else if (b_world) {
+ BackgroundNode *background = new BackgroundNode();
+ background->color = get_float3(b_world.color());
+ graph->add(background);
+
+ ShaderNode *out = graph->output();
+ graph->connect(background->output("Background"), out->input("Surface"));
+ }
+
+ if (b_world) {
+ /* AO */
+ BL::WorldLighting b_light = b_world.light_settings();
+
+ background->use_ao = b_light.use_ambient_occlusion();
+ background->ao_factor = b_light.ao_factor();
+ background->ao_distance = b_light.distance();
+
+ /* visibility */
+ PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
+ uint visibility = 0;
+
+ visibility |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0;
+ visibility |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0;
+ visibility |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : 0;
+ visibility |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0;
+ visibility |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0;
+
+ background->visibility = visibility;
+ }
+ else {
+ background->use_ao = false;
+ background->ao_factor = 0.0f;
+ background->ao_distance = FLT_MAX;
+ }
+
+ shader->set_graph(graph);
+ shader->tag_update(scene);
+ background->tag_update(scene);
+ }
+
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ /* when doing preview render check for BI's transparency settings,
+ * this is so because Blender's preview render routines are not able
+ * to tweak all cycles's settings depending on different circumstances
+ */
+ if (b_engine.is_preview() == false)
+ background->transparent = get_boolean(cscene, "film_transparent");
+ else
+ background->transparent = b_scene.render().alpha_mode() ==
+ BL::RenderSettings::alpha_mode_TRANSPARENT;
+
+ if (background->transparent) {
+ background->transparent_glass = get_boolean(cscene, "film_transparent_glass");
+ background->transparent_roughness_threshold = get_float(cscene, "film_transparent_roughness");
+ }
+ else {
+ background->transparent_glass = false;
+ background->transparent_roughness_threshold = 0.0f;
+ }
+
+ background->use_shader = view_layer.use_background_shader;
+ background->use_ao = background->use_ao && view_layer.use_background_ao;
+
+ if (background->modified(prevbackground))
+ background->tag_update(scene);
}
/* Sync Lights */
-void BlenderSync::sync_lights(BL::Depsgraph& b_depsgraph, bool update_all)
+void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
{
- shader_map.set_default(scene->default_light);
-
- BL::Depsgraph::ids_iterator b_id;
- for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
- if(!b_id->is_a(&RNA_Light)) {
- continue;
- }
-
- BL::Light b_light(*b_id);
- Shader *shader;
-
- /* test if we need to sync */
- if(shader_map.sync(&shader, b_light) || update_all) {
- ShaderGraph *graph = new ShaderGraph();
-
- /* create nodes */
- if(b_light.use_nodes() && b_light.node_tree()) {
- shader->name = b_light.name().c_str();
-
- BL::ShaderNodeTree b_ntree(b_light.node_tree());
-
- add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
- }
- else {
- float strength = 1.0f;
-
- if(b_light.type() == BL::Light::type_POINT ||
- b_light.type() == BL::Light::type_SPOT ||
- b_light.type() == BL::Light::type_AREA)
- {
- strength = 100.0f;
- }
-
- EmissionNode *emission = new EmissionNode();
- emission->color = get_float3(b_light.color());
- emission->strength = strength;
- graph->add(emission);
-
- ShaderNode *out = graph->output();
- graph->connect(emission->output("Emission"), out->input("Surface"));
- }
-
- shader->set_graph(graph);
- shader->tag_update(scene);
- }
- }
+ shader_map.set_default(scene->default_light);
+
+ BL::Depsgraph::ids_iterator b_id;
+ for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+ if (!b_id->is_a(&RNA_Light)) {
+ continue;
+ }
+
+ BL::Light b_light(*b_id);
+ Shader *shader;
+
+ /* test if we need to sync */
+ if (shader_map.sync(&shader, b_light) || update_all) {
+ ShaderGraph *graph = new ShaderGraph();
+
+ /* create nodes */
+ if (b_light.use_nodes() && b_light.node_tree()) {
+ shader->name = b_light.name().c_str();
+
+ BL::ShaderNodeTree b_ntree(b_light.node_tree());
+
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
+ }
+ else {
+ float strength = 1.0f;
+
+ if (b_light.type() == BL::Light::type_POINT || b_light.type() == BL::Light::type_SPOT ||
+ b_light.type() == BL::Light::type_AREA) {
+ strength = 100.0f;
+ }
+
+ EmissionNode *emission = new EmissionNode();
+ emission->color = get_float3(b_light.color());
+ emission->strength = strength;
+ graph->add(emission);
+
+ ShaderNode *out = graph->output();
+ graph->connect(emission->output("Emission"), out->input("Surface"));
+ }
+
+ shader->set_graph(graph);
+ shader->tag_update(scene);
+ }
+ }
}
-void BlenderSync::sync_shaders(BL::Depsgraph& b_depsgraph)
+void BlenderSync::sync_shaders(BL::Depsgraph &b_depsgraph)
{
- /* for auto refresh images */
- bool auto_refresh_update = false;
+ /* for auto refresh images */
+ bool auto_refresh_update = false;
- if(preview) {
- ImageManager *image_manager = scene->image_manager;
- int frame = b_scene.frame_current();
- auto_refresh_update = image_manager->set_animation_frame_update(frame);
- }
+ if (preview) {
+ ImageManager *image_manager = scene->image_manager;
+ int frame = b_scene.frame_current();
+ auto_refresh_update = image_manager->set_animation_frame_update(frame);
+ }
- shader_map.pre_sync();
+ shader_map.pre_sync();
- sync_world(b_depsgraph, auto_refresh_update);
- sync_lights(b_depsgraph, auto_refresh_update);
- sync_materials(b_depsgraph, auto_refresh_update);
+ sync_world(b_depsgraph, auto_refresh_update);
+ sync_lights(b_depsgraph, auto_refresh_update);
+ sync_materials(b_depsgraph, auto_refresh_update);
- /* false = don't delete unused shaders, not supported */
- shader_map.post_sync(false);
+ /* false = don't delete unused shaders, not supported */
+ shader_map.post_sync(false);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 063a2cd4d16..0ab6d88487e 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -45,32 +45,33 @@ static const char *cryptomatte_prefix = "Crypto";
/* Constructor */
-BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Scene& b_scene,
+BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Scene &b_scene,
Scene *scene,
bool preview,
Progress &progress)
-: b_engine(b_engine),
- b_data(b_data),
- b_scene(b_scene),
- shader_map(&scene->shaders),
- object_map(&scene->objects),
- mesh_map(&scene->meshes),
- light_map(&scene->lights),
- particle_system_map(&scene->particle_systems),
- world_map(NULL),
- world_recalc(false),
- scene(scene),
- preview(preview),
- experimental(false),
- dicing_rate(1.0f),
- max_subdivisions(12),
- progress(progress)
+ : b_engine(b_engine),
+ b_data(b_data),
+ b_scene(b_scene),
+ shader_map(&scene->shaders),
+ object_map(&scene->objects),
+ mesh_map(&scene->meshes),
+ light_map(&scene->lights),
+ particle_system_map(&scene->particle_systems),
+ world_map(NULL),
+ world_recalc(false),
+ scene(scene),
+ preview(preview),
+ experimental(false),
+ dicing_rate(1.0f),
+ max_subdivisions(12),
+ progress(progress)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") : RNA_float_get(&cscene, "dicing_rate");
- max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
+ RNA_float_get(&cscene, "dicing_rate");
+ max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
}
BlenderSync::~BlenderSync()
@@ -79,788 +80,776 @@ BlenderSync::~BlenderSync()
/* Sync */
-void BlenderSync::sync_recalc(BL::Depsgraph& b_depsgraph)
+void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph)
{
- /* Sync recalc flags from blender to cycles. Actual update is done separate,
- * so we can do it later on if doing it immediate is not suitable. */
-
- bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
-
- if(experimental) {
- /* Mark all meshes as needing to be exported again if dicing changed. */
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- bool dicing_prop_changed = false;
-
- float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate")
- : RNA_float_get(&cscene, "dicing_rate");
-
- if(dicing_rate != updated_dicing_rate) {
- dicing_rate = updated_dicing_rate;
- dicing_prop_changed = true;
- }
-
- int updated_max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
-
- if(max_subdivisions != updated_max_subdivisions) {
- max_subdivisions = updated_max_subdivisions;
- dicing_prop_changed = true;
- }
-
- if(dicing_prop_changed) {
- for(const pair<void*, Mesh*>& iter: mesh_map.key_to_scene_data()) {
- Mesh *mesh = iter.second;
- if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
- mesh_map.set_recalc(iter.first);
- }
- }
- }
- }
-
- /* Iterate over all IDs in this depsgraph. */
- BL::Depsgraph::updates_iterator b_update;
- for(b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
- BL::ID b_id(b_update->id());
-
- /* Material */
- if(b_id.is_a(&RNA_Material)) {
- BL::Material b_mat(b_id);
- shader_map.set_recalc(b_mat);
- }
- /* Light */
- else if(b_id.is_a(&RNA_Light)) {
- BL::Light b_light(b_id);
- shader_map.set_recalc(b_light);
- }
- /* Object */
- else if(b_id.is_a(&RNA_Object)) {
- BL::Object b_ob(b_id);
- const bool updated_geometry = b_update->is_updated_geometry();
-
- if(b_update->is_updated_transform()) {
- object_map.set_recalc(b_ob);
- light_map.set_recalc(b_ob);
- }
-
- if(object_is_mesh(b_ob)) {
- if(updated_geometry ||
- (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
- {
- BL::ID key = BKE_object_is_modified(b_ob)? b_ob: b_ob.data();
- mesh_map.set_recalc(key);
- }
- }
- else if(object_is_light(b_ob)) {
- if(updated_geometry) {
- light_map.set_recalc(b_ob);
- }
- }
-
- if(updated_geometry) {
- BL::Object::particle_systems_iterator b_psys;
- for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys)
- particle_system_map.set_recalc(b_ob);
- }
- }
- /* Mesh */
- else if(b_id.is_a(&RNA_Mesh)) {
- BL::Mesh b_mesh(b_id);
- mesh_map.set_recalc(b_mesh);
- }
- /* World */
- else if(b_id.is_a(&RNA_World)) {
- BL::World b_world(b_id);
- if(world_map == b_world.ptr.data) {
- world_recalc = true;
- }
- }
- }
-
- /* Updates shader with object dependency if objects changed. */
- if(has_updated_objects) {
- if(scene->default_background->has_object_dependency) {
- world_recalc = true;
- }
-
- foreach(Shader *shader, scene->shaders) {
- if(shader->has_object_dependency) {
- shader->need_sync_object = true;
- }
- }
- }
+ /* Sync recalc flags from blender to cycles. Actual update is done separate,
+ * so we can do it later on if doing it immediate is not suitable. */
+
+ bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
+
+ if (experimental) {
+ /* Mark all meshes as needing to be exported again if dicing changed. */
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ bool dicing_prop_changed = false;
+
+ float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
+ RNA_float_get(&cscene, "dicing_rate");
+
+ if (dicing_rate != updated_dicing_rate) {
+ dicing_rate = updated_dicing_rate;
+ dicing_prop_changed = true;
+ }
+
+ int updated_max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
+
+ if (max_subdivisions != updated_max_subdivisions) {
+ max_subdivisions = updated_max_subdivisions;
+ dicing_prop_changed = true;
+ }
+
+ if (dicing_prop_changed) {
+ for (const pair<void *, Mesh *> &iter : mesh_map.key_to_scene_data()) {
+ Mesh *mesh = iter.second;
+ if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
+ mesh_map.set_recalc(iter.first);
+ }
+ }
+ }
+ }
+
+ /* Iterate over all IDs in this depsgraph. */
+ BL::Depsgraph::updates_iterator b_update;
+ for (b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
+ BL::ID b_id(b_update->id());
+
+ /* Material */
+ if (b_id.is_a(&RNA_Material)) {
+ BL::Material b_mat(b_id);
+ shader_map.set_recalc(b_mat);
+ }
+ /* Light */
+ else if (b_id.is_a(&RNA_Light)) {
+ BL::Light b_light(b_id);
+ shader_map.set_recalc(b_light);
+ }
+ /* Object */
+ else if (b_id.is_a(&RNA_Object)) {
+ BL::Object b_ob(b_id);
+ const bool updated_geometry = b_update->is_updated_geometry();
+
+ if (b_update->is_updated_transform()) {
+ object_map.set_recalc(b_ob);
+ light_map.set_recalc(b_ob);
+ }
+
+ if (object_is_mesh(b_ob)) {
+ if (updated_geometry ||
+ (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) {
+ BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
+ mesh_map.set_recalc(key);
+ }
+ }
+ else if (object_is_light(b_ob)) {
+ if (updated_geometry) {
+ light_map.set_recalc(b_ob);
+ }
+ }
+
+ if (updated_geometry) {
+ BL::Object::particle_systems_iterator b_psys;
+ for (b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys)
+ particle_system_map.set_recalc(b_ob);
+ }
+ }
+ /* Mesh */
+ else if (b_id.is_a(&RNA_Mesh)) {
+ BL::Mesh b_mesh(b_id);
+ mesh_map.set_recalc(b_mesh);
+ }
+ /* World */
+ else if (b_id.is_a(&RNA_World)) {
+ BL::World b_world(b_id);
+ if (world_map == b_world.ptr.data) {
+ world_recalc = true;
+ }
+ }
+ }
+
+ /* Updates shader with object dependency if objects changed. */
+ if (has_updated_objects) {
+ if (scene->default_background->has_object_dependency) {
+ world_recalc = true;
+ }
+
+ foreach (Shader *shader, scene->shaders) {
+ if (shader->has_object_dependency) {
+ shader->need_sync_object = true;
+ }
+ }
+ }
}
-void BlenderSync::sync_data(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::SpaceView3D& b_v3d,
- BL::Object& b_override,
- int width, int height,
+void BlenderSync::sync_data(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::SpaceView3D &b_v3d,
+ BL::Object &b_override,
+ int width,
+ int height,
void **python_thread_state)
{
- BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
-
- sync_view_layer(b_v3d, b_view_layer);
- sync_integrator();
- sync_film();
- sync_shaders(b_depsgraph);
- sync_images();
- sync_curve_settings();
-
- mesh_synced.clear(); /* use for objects and motion sync */
-
- if(scene->need_motion() == Scene::MOTION_PASS ||
- scene->need_motion() == Scene::MOTION_NONE ||
- scene->camera->motion_position == Camera::MOTION_POSITION_CENTER)
- {
- sync_objects(b_depsgraph);
- }
- sync_motion(b_render,
- b_depsgraph,
- b_override,
- width, height,
- python_thread_state);
-
- mesh_synced.clear();
-
- free_data_after_sync(b_depsgraph);
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
+ sync_view_layer(b_v3d, b_view_layer);
+ sync_integrator();
+ sync_film();
+ sync_shaders(b_depsgraph);
+ sync_images();
+ sync_curve_settings();
+
+ mesh_synced.clear(); /* use for objects and motion sync */
+
+ if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE ||
+ scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) {
+ sync_objects(b_depsgraph);
+ }
+ sync_motion(b_render, b_depsgraph, b_override, width, height, python_thread_state);
+
+ mesh_synced.clear();
+
+ free_data_after_sync(b_depsgraph);
}
/* Integrator */
void BlenderSync::sync_integrator()
{
- BL::RenderSettings r = b_scene.render();
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- experimental = (get_enum(cscene, "feature_set") != 0);
-
- Integrator *integrator = scene->integrator;
- Integrator previntegrator = *integrator;
-
- integrator->max_bounce = get_int(cscene, "max_bounces");
-
- integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces");
- integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces");
- integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces");
- integrator->max_volume_bounce = get_int(cscene, "volume_bounces");
-
- integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
-
- integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
- integrator->volume_step_size = get_float(cscene, "volume_step_size");
-
- integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective");
- integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive");
- integrator->filter_glossy = get_float(cscene, "blur_glossy");
-
- integrator->seed = get_int(cscene, "seed");
- if(get_boolean(cscene, "use_animated_seed")) {
- integrator->seed = hash_int_2d(b_scene.frame_current(),
- get_int(cscene, "seed"));
- if(b_scene.frame_subframe() != 0.0f) {
- /* TODO(sergey): Ideally should be some sort of hash_merge,
- * but this is good enough for now.
- */
- integrator->seed += hash_int_2d((int)(b_scene.frame_subframe() * (float)INT_MAX),
- get_int(cscene, "seed"));
- }
- }
-
- integrator->sampling_pattern = (SamplingPattern)get_enum(
- cscene,
- "sampling_pattern",
- SAMPLING_NUM_PATTERNS,
- SAMPLING_PATTERN_SOBOL);
-
- integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct");
- integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect");
- if(!preview) {
- if(integrator->motion_blur != r.use_motion_blur()) {
- scene->object_manager->tag_update(scene);
- scene->camera->tag_update();
- }
-
- integrator->motion_blur = r.use_motion_blur();
- }
-
- integrator->method = (Integrator::Method)get_enum(cscene,
- "progressive",
- Integrator::NUM_METHODS,
- Integrator::PATH);
-
- integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct");
- integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
- integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold");
-
- int diffuse_samples = get_int(cscene, "diffuse_samples");
- int glossy_samples = get_int(cscene, "glossy_samples");
- int transmission_samples = get_int(cscene, "transmission_samples");
- int ao_samples = get_int(cscene, "ao_samples");
- int mesh_light_samples = get_int(cscene, "mesh_light_samples");
- int subsurface_samples = get_int(cscene, "subsurface_samples");
- int volume_samples = get_int(cscene, "volume_samples");
-
- if(get_boolean(cscene, "use_square_samples")) {
- integrator->diffuse_samples = diffuse_samples * diffuse_samples;
- integrator->glossy_samples = glossy_samples * glossy_samples;
- integrator->transmission_samples = transmission_samples * transmission_samples;
- integrator->ao_samples = ao_samples * ao_samples;
- integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples;
- integrator->subsurface_samples = subsurface_samples * subsurface_samples;
- integrator->volume_samples = volume_samples * volume_samples;
- }
- else {
- integrator->diffuse_samples = diffuse_samples;
- integrator->glossy_samples = glossy_samples;
- integrator->transmission_samples = transmission_samples;
- integrator->ao_samples = ao_samples;
- integrator->mesh_light_samples = mesh_light_samples;
- integrator->subsurface_samples = subsurface_samples;
- integrator->volume_samples = volume_samples;
- }
-
- if(b_scene.render().use_simplify()) {
- if(preview) {
- integrator->ao_bounces = get_int(cscene, "ao_bounces");
- }
- else {
- integrator->ao_bounces = get_int(cscene, "ao_bounces_render");
- }
- }
- else {
- integrator->ao_bounces = 0;
- }
-
- if(integrator->modified(previntegrator))
- integrator->tag_update(scene);
+ BL::RenderSettings r = b_scene.render();
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ experimental = (get_enum(cscene, "feature_set") != 0);
+
+ Integrator *integrator = scene->integrator;
+ Integrator previntegrator = *integrator;
+
+ integrator->max_bounce = get_int(cscene, "max_bounces");
+
+ integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces");
+ integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces");
+ integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces");
+ integrator->max_volume_bounce = get_int(cscene, "volume_bounces");
+
+ integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
+
+ integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
+ integrator->volume_step_size = get_float(cscene, "volume_step_size");
+
+ integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective");
+ integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive");
+ integrator->filter_glossy = get_float(cscene, "blur_glossy");
+
+ integrator->seed = get_int(cscene, "seed");
+ if (get_boolean(cscene, "use_animated_seed")) {
+ integrator->seed = hash_int_2d(b_scene.frame_current(), get_int(cscene, "seed"));
+ if (b_scene.frame_subframe() != 0.0f) {
+ /* TODO(sergey): Ideally should be some sort of hash_merge,
+ * but this is good enough for now.
+ */
+ integrator->seed += hash_int_2d((int)(b_scene.frame_subframe() * (float)INT_MAX),
+ get_int(cscene, "seed"));
+ }
+ }
+
+ integrator->sampling_pattern = (SamplingPattern)get_enum(
+ cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL);
+
+ integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct");
+ integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect");
+ if (!preview) {
+ if (integrator->motion_blur != r.use_motion_blur()) {
+ scene->object_manager->tag_update(scene);
+ scene->camera->tag_update();
+ }
+
+ integrator->motion_blur = r.use_motion_blur();
+ }
+
+ integrator->method = (Integrator::Method)get_enum(
+ cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH);
+
+ integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct");
+ integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
+ integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold");
+
+ int diffuse_samples = get_int(cscene, "diffuse_samples");
+ int glossy_samples = get_int(cscene, "glossy_samples");
+ int transmission_samples = get_int(cscene, "transmission_samples");
+ int ao_samples = get_int(cscene, "ao_samples");
+ int mesh_light_samples = get_int(cscene, "mesh_light_samples");
+ int subsurface_samples = get_int(cscene, "subsurface_samples");
+ int volume_samples = get_int(cscene, "volume_samples");
+
+ if (get_boolean(cscene, "use_square_samples")) {
+ integrator->diffuse_samples = diffuse_samples * diffuse_samples;
+ integrator->glossy_samples = glossy_samples * glossy_samples;
+ integrator->transmission_samples = transmission_samples * transmission_samples;
+ integrator->ao_samples = ao_samples * ao_samples;
+ integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples;
+ integrator->subsurface_samples = subsurface_samples * subsurface_samples;
+ integrator->volume_samples = volume_samples * volume_samples;
+ }
+ else {
+ integrator->diffuse_samples = diffuse_samples;
+ integrator->glossy_samples = glossy_samples;
+ integrator->transmission_samples = transmission_samples;
+ integrator->ao_samples = ao_samples;
+ integrator->mesh_light_samples = mesh_light_samples;
+ integrator->subsurface_samples = subsurface_samples;
+ integrator->volume_samples = volume_samples;
+ }
+
+ if (b_scene.render().use_simplify()) {
+ if (preview) {
+ integrator->ao_bounces = get_int(cscene, "ao_bounces");
+ }
+ else {
+ integrator->ao_bounces = get_int(cscene, "ao_bounces_render");
+ }
+ }
+ else {
+ integrator->ao_bounces = 0;
+ }
+
+ if (integrator->modified(previntegrator))
+ integrator->tag_update(scene);
}
/* Film */
void BlenderSync::sync_film()
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- Film *film = scene->film;
- Film prevfilm = *film;
-
- film->exposure = get_float(cscene, "film_exposure");
- film->filter_type = (FilterType)get_enum(cscene,
- "pixel_filter_type",
- FILTER_NUM_TYPES,
- FILTER_BLACKMAN_HARRIS);
- film->filter_width = (film->filter_type == FILTER_BOX)? 1.0f: get_float(cscene, "filter_width");
-
- if(b_scene.world()) {
- BL::WorldMistSettings b_mist = b_scene.world().mist_settings();
-
- film->mist_start = b_mist.start();
- film->mist_depth = b_mist.depth();
-
- switch(b_mist.falloff()) {
- case BL::WorldMistSettings::falloff_QUADRATIC:
- film->mist_falloff = 2.0f;
- break;
- case BL::WorldMistSettings::falloff_LINEAR:
- film->mist_falloff = 1.0f;
- break;
- case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC:
- film->mist_falloff = 0.5f;
- break;
- }
- }
-
- if(film->modified(prevfilm))
- film->tag_update(scene);
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ Film *film = scene->film;
+ Film prevfilm = *film;
+
+ film->exposure = get_float(cscene, "film_exposure");
+ film->filter_type = (FilterType)get_enum(
+ cscene, "pixel_filter_type", FILTER_NUM_TYPES, FILTER_BLACKMAN_HARRIS);
+ film->filter_width = (film->filter_type == FILTER_BOX) ? 1.0f :
+ get_float(cscene, "filter_width");
+
+ if (b_scene.world()) {
+ BL::WorldMistSettings b_mist = b_scene.world().mist_settings();
+
+ film->mist_start = b_mist.start();
+ film->mist_depth = b_mist.depth();
+
+ switch (b_mist.falloff()) {
+ case BL::WorldMistSettings::falloff_QUADRATIC:
+ film->mist_falloff = 2.0f;
+ break;
+ case BL::WorldMistSettings::falloff_LINEAR:
+ film->mist_falloff = 1.0f;
+ break;
+ case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC:
+ film->mist_falloff = 0.5f;
+ break;
+ }
+ }
+
+ if (film->modified(prevfilm))
+ film->tag_update(scene);
}
/* Render Layer */
-void BlenderSync::sync_view_layer(BL::SpaceView3D& /*b_v3d*/, BL::ViewLayer& b_view_layer)
+void BlenderSync::sync_view_layer(BL::SpaceView3D & /*b_v3d*/, BL::ViewLayer &b_view_layer)
{
- /* render layer */
- view_layer.name = b_view_layer.name();
- view_layer.use_background_shader = b_view_layer.use_sky();
- view_layer.use_background_ao = b_view_layer.use_ao();
- view_layer.use_surfaces = b_view_layer.use_solid();
- view_layer.use_hair = b_view_layer.use_strand();
-
- /* Material override. */
- view_layer.material_override = b_view_layer.material_override();
-
- /* Sample override. */
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- int use_layer_samples = get_enum(cscene, "use_layer_samples");
-
- view_layer.bound_samples = (use_layer_samples == 1);
- view_layer.samples = 0;
-
- if(use_layer_samples != 2) {
- int samples = b_view_layer.samples();
- if(get_boolean(cscene, "use_square_samples"))
- view_layer.samples = samples * samples;
- else
- view_layer.samples = samples;
- }
-
+ /* render layer */
+ view_layer.name = b_view_layer.name();
+ view_layer.use_background_shader = b_view_layer.use_sky();
+ view_layer.use_background_ao = b_view_layer.use_ao();
+ view_layer.use_surfaces = b_view_layer.use_solid();
+ view_layer.use_hair = b_view_layer.use_strand();
+
+ /* Material override. */
+ view_layer.material_override = b_view_layer.material_override();
+
+ /* Sample override. */
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ int use_layer_samples = get_enum(cscene, "use_layer_samples");
+
+ view_layer.bound_samples = (use_layer_samples == 1);
+ view_layer.samples = 0;
+
+ if (use_layer_samples != 2) {
+ int samples = b_view_layer.samples();
+ if (get_boolean(cscene, "use_square_samples"))
+ view_layer.samples = samples * samples;
+ else
+ view_layer.samples = samples;
+ }
}
/* Images */
void BlenderSync::sync_images()
{
- /* Sync is a convention for this API, but currently it frees unused buffers. */
-
- const bool is_interface_locked = b_engine.render() &&
- b_engine.render().use_lock_interface();
- if(is_interface_locked == false && BlenderSession::headless == false) {
- /* If interface is not locked, it's possible image is needed for
- * the display.
- */
- return;
- }
- /* Free buffers used by images which are not needed for render. */
- BL::BlendData::images_iterator b_image;
- for(b_data.images.begin(b_image);
- b_image != b_data.images.end();
- ++b_image)
- {
- /* TODO(sergey): Consider making it an utility function to check
- * whether image is considered builtin.
- */
- const bool is_builtin = b_image->packed_file() ||
- b_image->source() == BL::Image::source_GENERATED ||
- b_image->source() == BL::Image::source_MOVIE ||
- b_engine.is_preview();
- if(is_builtin == false) {
- b_image->buffers_free();
- }
- /* TODO(sergey): Free builtin images not used by any shader. */
- }
+ /* Sync is a convention for this API, but currently it frees unused buffers. */
+
+ const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
+ if (is_interface_locked == false && BlenderSession::headless == false) {
+ /* If interface is not locked, it's possible image is needed for
+ * the display.
+ */
+ return;
+ }
+ /* Free buffers used by images which are not needed for render. */
+ BL::BlendData::images_iterator b_image;
+ for (b_data.images.begin(b_image); b_image != b_data.images.end(); ++b_image) {
+ /* TODO(sergey): Consider making it an utility function to check
+ * whether image is considered builtin.
+ */
+ const bool is_builtin = b_image->packed_file() ||
+ b_image->source() == BL::Image::source_GENERATED ||
+ b_image->source() == BL::Image::source_MOVIE || b_engine.is_preview();
+ if (is_builtin == false) {
+ b_image->buffers_free();
+ }
+ /* TODO(sergey): Free builtin images not used by any shader. */
+ }
}
/* Passes */
-PassType BlenderSync::get_pass_type(BL::RenderPass& b_pass)
+PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
{
- string name = b_pass.name();
-#define MAP_PASS(passname, passtype) if(name == passname) return passtype;
- /* NOTE: Keep in sync with defined names from DNA_scene_types.h */
- MAP_PASS("Combined", PASS_COMBINED);
- MAP_PASS("Depth", PASS_DEPTH);
- MAP_PASS("Mist", PASS_MIST);
- MAP_PASS("Normal", PASS_NORMAL);
- MAP_PASS("IndexOB", PASS_OBJECT_ID);
- MAP_PASS("UV", PASS_UV);
- MAP_PASS("Vector", PASS_MOTION);
- MAP_PASS("IndexMA", PASS_MATERIAL_ID);
-
- MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT);
- MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT);
- MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT);
- MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT);
- MAP_PASS("VolumeDir", PASS_VOLUME_DIRECT);
-
- MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT);
- MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT);
- MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT);
- MAP_PASS("SubsurfaceInd", PASS_SUBSURFACE_INDIRECT);
- MAP_PASS("VolumeInd", PASS_VOLUME_INDIRECT);
-
- MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR);
- MAP_PASS("GlossCol", PASS_GLOSSY_COLOR);
- MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR);
- MAP_PASS("SubsurfaceCol", PASS_SUBSURFACE_COLOR);
-
- MAP_PASS("Emit", PASS_EMISSION);
- MAP_PASS("Env", PASS_BACKGROUND);
- MAP_PASS("AO", PASS_AO);
- MAP_PASS("Shadow", PASS_SHADOW);
+ string name = b_pass.name();
+#define MAP_PASS(passname, passtype) \
+ if (name == passname) \
+ return passtype;
+ /* NOTE: Keep in sync with defined names from DNA_scene_types.h */
+ MAP_PASS("Combined", PASS_COMBINED);
+ MAP_PASS("Depth", PASS_DEPTH);
+ MAP_PASS("Mist", PASS_MIST);
+ MAP_PASS("Normal", PASS_NORMAL);
+ MAP_PASS("IndexOB", PASS_OBJECT_ID);
+ MAP_PASS("UV", PASS_UV);
+ MAP_PASS("Vector", PASS_MOTION);
+ MAP_PASS("IndexMA", PASS_MATERIAL_ID);
+
+ MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT);
+ MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT);
+ MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT);
+ MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT);
+ MAP_PASS("VolumeDir", PASS_VOLUME_DIRECT);
+
+ MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT);
+ MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT);
+ MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT);
+ MAP_PASS("SubsurfaceInd", PASS_SUBSURFACE_INDIRECT);
+ MAP_PASS("VolumeInd", PASS_VOLUME_INDIRECT);
+
+ MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR);
+ MAP_PASS("GlossCol", PASS_GLOSSY_COLOR);
+ MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR);
+ MAP_PASS("SubsurfaceCol", PASS_SUBSURFACE_COLOR);
+
+ MAP_PASS("Emit", PASS_EMISSION);
+ MAP_PASS("Env", PASS_BACKGROUND);
+ MAP_PASS("AO", PASS_AO);
+ MAP_PASS("Shadow", PASS_SHADOW);
#ifdef __KERNEL_DEBUG__
- MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES);
- MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES);
- MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS);
- MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES);
+ MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES);
+ MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES);
+ MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS);
+ MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES);
#endif
- MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
- if(string_startswith(name, cryptomatte_prefix)) {
- return PASS_CRYPTOMATTE;
- }
+ MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
+ if (string_startswith(name, cryptomatte_prefix)) {
+ return PASS_CRYPTOMATTE;
+ }
#undef MAP_PASS
- return PASS_NONE;
+ return PASS_NONE;
}
-int BlenderSync::get_denoising_pass(BL::RenderPass& b_pass)
+int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass)
{
- string name = b_pass.name();
-
- if(name == "Noisy Image") return DENOISING_PASS_PREFILTERED_COLOR;
-
- if(name.substr(0, 10) != "Denoising ") {
- return -1;
- }
- name = name.substr(10);
-
-#define MAP_PASS(passname, offset) if(name == passname) return offset;
- MAP_PASS("Normal", DENOISING_PASS_PREFILTERED_NORMAL);
- MAP_PASS("Albedo", DENOISING_PASS_PREFILTERED_ALBEDO);
- MAP_PASS("Depth", DENOISING_PASS_PREFILTERED_DEPTH);
- MAP_PASS("Shadowing", DENOISING_PASS_PREFILTERED_SHADOWING);
- MAP_PASS("Variance", DENOISING_PASS_PREFILTERED_VARIANCE);
- MAP_PASS("Intensity", DENOISING_PASS_PREFILTERED_INTENSITY);
- MAP_PASS("Clean", DENOISING_PASS_CLEAN);
+ string name = b_pass.name();
+
+ if (name == "Noisy Image")
+ return DENOISING_PASS_PREFILTERED_COLOR;
+
+ if (name.substr(0, 10) != "Denoising ") {
+ return -1;
+ }
+ name = name.substr(10);
+
+#define MAP_PASS(passname, offset) \
+ if (name == passname) \
+ return offset;
+ MAP_PASS("Normal", DENOISING_PASS_PREFILTERED_NORMAL);
+ MAP_PASS("Albedo", DENOISING_PASS_PREFILTERED_ALBEDO);
+ MAP_PASS("Depth", DENOISING_PASS_PREFILTERED_DEPTH);
+ MAP_PASS("Shadowing", DENOISING_PASS_PREFILTERED_SHADOWING);
+ MAP_PASS("Variance", DENOISING_PASS_PREFILTERED_VARIANCE);
+ MAP_PASS("Intensity", DENOISING_PASS_PREFILTERED_INTENSITY);
+ MAP_PASS("Clean", DENOISING_PASS_CLEAN);
#undef MAP_PASS
- return -1;
+ return -1;
}
-vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
- BL::ViewLayer& b_view_layer)
+vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_view_layer)
{
- vector<Pass> passes;
- Pass::add(PASS_COMBINED, passes);
-
- /* loop over passes */
- BL::RenderLayer::passes_iterator b_pass_iter;
-
- for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
- BL::RenderPass b_pass(*b_pass_iter);
- PassType pass_type = get_pass_type(b_pass);
-
- if(pass_type == PASS_MOTION && scene->integrator->motion_blur)
- continue;
- if(pass_type != PASS_NONE)
- Pass::add(pass_type, passes);
- }
-
- PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles");
- bool full_denoising = get_boolean(crp, "use_denoising");
- bool write_denoising_passes = get_boolean(crp, "denoising_store_passes");
-
- scene->film->denoising_flags = 0;
- if(full_denoising || write_denoising_passes) {
-#define MAP_OPTION(name, flag) if(!get_boolean(crp, name)) scene->film->denoising_flags |= flag;
- MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR);
- MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND);
- MAP_OPTION("denoising_glossy_direct", DENOISING_CLEAN_GLOSSY_DIR);
- MAP_OPTION("denoising_glossy_indirect", DENOISING_CLEAN_GLOSSY_IND);
- MAP_OPTION("denoising_transmission_direct", DENOISING_CLEAN_TRANSMISSION_DIR);
- MAP_OPTION("denoising_transmission_indirect", DENOISING_CLEAN_TRANSMISSION_IND);
- MAP_OPTION("denoising_subsurface_direct", DENOISING_CLEAN_SUBSURFACE_DIR);
- MAP_OPTION("denoising_subsurface_indirect", DENOISING_CLEAN_SUBSURFACE_IND);
+ vector<Pass> passes;
+ Pass::add(PASS_COMBINED, passes);
+
+ /* loop over passes */
+ BL::RenderLayer::passes_iterator b_pass_iter;
+
+ for (b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
+ BL::RenderPass b_pass(*b_pass_iter);
+ PassType pass_type = get_pass_type(b_pass);
+
+ if (pass_type == PASS_MOTION && scene->integrator->motion_blur)
+ continue;
+ if (pass_type != PASS_NONE)
+ Pass::add(pass_type, passes);
+ }
+
+ PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles");
+ bool full_denoising = get_boolean(crp, "use_denoising");
+ bool write_denoising_passes = get_boolean(crp, "denoising_store_passes");
+
+ scene->film->denoising_flags = 0;
+ if (full_denoising || write_denoising_passes) {
+#define MAP_OPTION(name, flag) \
+ if (!get_boolean(crp, name)) \
+ scene->film->denoising_flags |= flag;
+ MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR);
+ MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND);
+ MAP_OPTION("denoising_glossy_direct", DENOISING_CLEAN_GLOSSY_DIR);
+ MAP_OPTION("denoising_glossy_indirect", DENOISING_CLEAN_GLOSSY_IND);
+ MAP_OPTION("denoising_transmission_direct", DENOISING_CLEAN_TRANSMISSION_DIR);
+ MAP_OPTION("denoising_transmission_indirect", DENOISING_CLEAN_TRANSMISSION_IND);
+ MAP_OPTION("denoising_subsurface_direct", DENOISING_CLEAN_SUBSURFACE_DIR);
+ MAP_OPTION("denoising_subsurface_indirect", DENOISING_CLEAN_SUBSURFACE_IND);
#undef MAP_OPTION
- b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
- }
-
- if(write_denoising_passes) {
- b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str());
-
- if(scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES) {
- b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str());
- }
- }
+ b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
+ }
+
+ if (write_denoising_passes) {
+ b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str());
+
+ if (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES) {
+ b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str());
+ }
+ }
#ifdef __KERNEL_DEBUG__
- if(get_boolean(crp, "pass_debug_bvh_traversed_nodes")) {
- b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_BVH_TRAVERSED_NODES, passes);
- }
- if(get_boolean(crp, "pass_debug_bvh_traversed_instances")) {
- b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes);
- }
- if(get_boolean(crp, "pass_debug_bvh_intersections")) {
- b_engine.add_pass("Debug BVH Intersections", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_BVH_INTERSECTIONS, passes);
- }
- if(get_boolean(crp, "pass_debug_ray_bounces")) {
- b_engine.add_pass("Debug Ray Bounces", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_RAY_BOUNCES, passes);
- }
+ if (get_boolean(crp, "pass_debug_bvh_traversed_nodes")) {
+ b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_BVH_TRAVERSED_NODES, passes);
+ }
+ if (get_boolean(crp, "pass_debug_bvh_traversed_instances")) {
+ b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes);
+ }
+ if (get_boolean(crp, "pass_debug_bvh_intersections")) {
+ b_engine.add_pass("Debug BVH Intersections", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_BVH_INTERSECTIONS, passes);
+ }
+ if (get_boolean(crp, "pass_debug_ray_bounces")) {
+ b_engine.add_pass("Debug Ray Bounces", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_RAY_BOUNCES, passes);
+ }
#endif
- if(get_boolean(crp, "pass_debug_render_time")) {
- b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_RENDER_TIME, passes);
- }
- if(get_boolean(crp, "use_pass_volume_direct")) {
- b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
- Pass::add(PASS_VOLUME_DIRECT, passes);
- }
- if(get_boolean(crp, "use_pass_volume_indirect")) {
- b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
- Pass::add(PASS_VOLUME_INDIRECT, passes);
- }
-
- /* Cryptomatte stores two ID/weight pairs per RGBA layer.
- * User facing paramter is the number of pairs. */
- int crypto_depth = min(16, get_int(crp, "pass_crypto_depth")) / 2;
- scene->film->cryptomatte_depth = crypto_depth;
- scene->film->cryptomatte_passes = CRYPT_NONE;
- if(get_boolean(crp, "use_pass_crypto_object")) {
- for(int i = 0; i < crypto_depth; ++i) {
- string passname = cryptomatte_prefix + string_printf("Object%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
- Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
- }
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_OBJECT);
- }
- if(get_boolean(crp, "use_pass_crypto_material")) {
- for(int i = 0; i < crypto_depth; ++i) {
- string passname = cryptomatte_prefix + string_printf("Material%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
- Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
- }
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_MATERIAL);
- }
- if(get_boolean(crp, "use_pass_crypto_asset")) {
- for(int i = 0; i < crypto_depth; ++i) {
- string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
- Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
- }
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_ASSET);
- }
- if(get_boolean(crp, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) {
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_ACCURATE);
- }
-
- return passes;
+ if (get_boolean(crp, "pass_debug_render_time")) {
+ b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_RENDER_TIME, passes);
+ }
+ if (get_boolean(crp, "use_pass_volume_direct")) {
+ b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
+ Pass::add(PASS_VOLUME_DIRECT, passes);
+ }
+ if (get_boolean(crp, "use_pass_volume_indirect")) {
+ b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
+ Pass::add(PASS_VOLUME_INDIRECT, passes);
+ }
+
+ /* Cryptomatte stores two ID/weight pairs per RGBA layer.
+ * User facing paramter is the number of pairs. */
+ int crypto_depth = min(16, get_int(crp, "pass_crypto_depth")) / 2;
+ scene->film->cryptomatte_depth = crypto_depth;
+ scene->film->cryptomatte_passes = CRYPT_NONE;
+ if (get_boolean(crp, "use_pass_crypto_object")) {
+ for (int i = 0; i < crypto_depth; ++i) {
+ string passname = cryptomatte_prefix + string_printf("Object%02d", i);
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
+ Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
+ }
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_OBJECT);
+ }
+ if (get_boolean(crp, "use_pass_crypto_material")) {
+ for (int i = 0; i < crypto_depth; ++i) {
+ string passname = cryptomatte_prefix + string_printf("Material%02d", i);
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
+ Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
+ }
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_MATERIAL);
+ }
+ if (get_boolean(crp, "use_pass_crypto_asset")) {
+ for (int i = 0; i < crypto_depth; ++i) {
+ string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
+ Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
+ }
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_ASSET);
+ }
+ if (get_boolean(crp, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) {
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_ACCURATE);
+ }
+
+ return passes;
}
-void BlenderSync::free_data_after_sync(BL::Depsgraph& b_depsgraph)
+void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
{
- /* When viewport display is not needed during render we can force some
- * caches to be releases from blender side in order to reduce peak memory
- * footprint during synchronization process.
- */
- const bool is_interface_locked = b_engine.render() &&
- b_engine.render().use_lock_interface();
- const bool can_free_caches = BlenderSession::headless || is_interface_locked;
- if(!can_free_caches) {
- return;
- }
- /* TODO(sergey): We can actually remove the whole dependency graph,
- * but that will need some API support first.
- */
- BL::Depsgraph::objects_iterator b_ob;
- for(b_depsgraph.objects.begin(b_ob);
- b_ob != b_depsgraph.objects.end();
- ++b_ob)
- {
- b_ob->cache_release();
- }
+ /* When viewport display is not needed during render we can force some
+ * caches to be releases from blender side in order to reduce peak memory
+ * footprint during synchronization process.
+ */
+ const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
+ const bool can_free_caches = BlenderSession::headless || is_interface_locked;
+ if (!can_free_caches) {
+ return;
+ }
+ /* TODO(sergey): We can actually remove the whole dependency graph,
+ * but that will need some API support first.
+ */
+ BL::Depsgraph::objects_iterator b_ob;
+ for (b_depsgraph.objects.begin(b_ob); b_ob != b_depsgraph.objects.end(); ++b_ob) {
+ b_ob->cache_release();
+ }
}
/* Scene Parameters */
-SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
- bool background)
+SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
{
- BL::RenderSettings r = b_scene.render();
- SceneParams params;
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
-
- if(shadingsystem == 0)
- params.shadingsystem = SHADINGSYSTEM_SVM;
- else if(shadingsystem == 1)
- params.shadingsystem = SHADINGSYSTEM_OSL;
-
- if(background || DebugFlags().viewport_static_bvh)
- params.bvh_type = SceneParams::BVH_STATIC;
- else
- params.bvh_type = SceneParams::BVH_DYNAMIC;
-
- params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
- params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
- params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
-
- if(background && params.shadingsystem != SHADINGSYSTEM_OSL)
- params.persistent_data = r.use_persistent_data();
- else
- params.persistent_data = false;
-
- int texture_limit;
- if(background) {
- texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
- }
- else {
- texture_limit = RNA_enum_get(&cscene, "texture_limit");
- }
- if(texture_limit > 0 && b_scene.render().use_simplify()) {
- params.texture_limit = 1 << (texture_limit + 6);
- }
- else {
- params.texture_limit = 0;
- }
-
- /* TODO(sergey): Once OSL supports per-microarchitecture optimization get
- * rid of this.
- */
- if(params.shadingsystem == SHADINGSYSTEM_OSL) {
- params.bvh_layout = BVH_LAYOUT_BVH4;
- }
- else {
- params.bvh_layout = DebugFlags().cpu.bvh_layout;
- }
+ BL::RenderSettings r = b_scene.render();
+ SceneParams params;
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
+
+ if (shadingsystem == 0)
+ params.shadingsystem = SHADINGSYSTEM_SVM;
+ else if (shadingsystem == 1)
+ params.shadingsystem = SHADINGSYSTEM_OSL;
+
+ if (background || DebugFlags().viewport_static_bvh)
+ params.bvh_type = SceneParams::BVH_STATIC;
+ else
+ params.bvh_type = SceneParams::BVH_DYNAMIC;
+
+ params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
+ params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
+ params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
+
+ if (background && params.shadingsystem != SHADINGSYSTEM_OSL)
+ params.persistent_data = r.use_persistent_data();
+ else
+ params.persistent_data = false;
+
+ int texture_limit;
+ if (background) {
+ texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
+ }
+ else {
+ texture_limit = RNA_enum_get(&cscene, "texture_limit");
+ }
+ if (texture_limit > 0 && b_scene.render().use_simplify()) {
+ params.texture_limit = 1 << (texture_limit + 6);
+ }
+ else {
+ params.texture_limit = 0;
+ }
+
+ /* TODO(sergey): Once OSL supports per-microarchitecture optimization get
+ * rid of this.
+ */
+ if (params.shadingsystem == SHADINGSYSTEM_OSL) {
+ params.bvh_layout = BVH_LAYOUT_BVH4;
+ }
+ else {
+ params.bvh_layout = DebugFlags().cpu.bvh_layout;
+ }
#ifdef WITH_EMBREE
- params.bvh_layout = RNA_boolean_get(&cscene, "use_bvh_embree") ? BVH_LAYOUT_EMBREE : params.bvh_layout;
+ params.bvh_layout = RNA_boolean_get(&cscene, "use_bvh_embree") ? BVH_LAYOUT_EMBREE :
+ params.bvh_layout;
#endif
- return params;
+ return params;
}
/* Session Parameters */
-bool BlenderSync::get_session_pause(BL::Scene& b_scene, bool background)
+bool BlenderSync::get_session_pause(BL::Scene &b_scene, bool background)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- return (background)? false: get_boolean(cscene, "preview_pause");
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ return (background) ? false : get_boolean(cscene, "preview_pause");
}
-SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
- BL::Preferences& b_preferences,
- BL::Scene& b_scene,
+SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
+ BL::Preferences &b_preferences,
+ BL::Scene &b_scene,
bool background)
{
- SessionParams params;
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- /* feature set */
- params.experimental = (get_enum(cscene, "feature_set") != 0);
-
- /* Background */
- params.background = background;
-
- /* Device */
- params.threads = blender_device_threads(b_scene);
- params.device = blender_device_info(b_preferences, b_scene, params.background);
-
- /* samples */
- int samples = get_int(cscene, "samples");
- int aa_samples = get_int(cscene, "aa_samples");
- int preview_samples = get_int(cscene, "preview_samples");
- int preview_aa_samples = get_int(cscene, "preview_aa_samples");
-
- if(get_boolean(cscene, "use_square_samples")) {
- aa_samples = aa_samples * aa_samples;
- preview_aa_samples = preview_aa_samples * preview_aa_samples;
-
- samples = samples * samples;
- preview_samples = preview_samples * preview_samples;
- }
-
- if(get_enum(cscene, "progressive") == 0) {
- if(background) {
- params.samples = aa_samples;
- }
- else {
- params.samples = preview_aa_samples;
- if(params.samples == 0)
- params.samples = INT_MAX;
- }
- }
- else {
- if(background) {
- params.samples = samples;
- }
- else {
- params.samples = preview_samples;
- if(params.samples == 0)
- params.samples = INT_MAX;
- }
- }
-
- /* Clamp samples. */
- params.samples = min(params.samples, Integrator::MAX_SAMPLES);
-
- /* tiles */
- const bool is_cpu = (params.device.type == DEVICE_CPU);
- if(!is_cpu && !background) {
- /* currently GPU could be much slower than CPU when using tiles,
- * still need to be investigated, but meanwhile make it possible
- * to work in viewport smoothly
- */
- int debug_tile_size = get_int(cscene, "debug_tile_size");
-
- params.tile_size = make_int2(debug_tile_size, debug_tile_size);
- }
- else {
- int tile_x = b_engine.tile_x();
- int tile_y = b_engine.tile_y();
-
- params.tile_size = make_int2(tile_x, tile_y);
- }
-
- if((BlenderSession::headless == false) && background) {
- params.tile_order = (TileOrder)get_enum(cscene, "tile_order");
- }
- else {
- params.tile_order = TILE_BOTTOM_TO_TOP;
- }
-
- /* other parameters */
- params.start_resolution = get_int(cscene, "preview_start_resolution");
- params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
-
- /* other parameters */
- params.cancel_timeout = (double)get_float(cscene, "debug_cancel_timeout");
- params.reset_timeout = (double)get_float(cscene, "debug_reset_timeout");
- params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
-
- /* progressive refine */
- BL::RenderSettings b_r = b_scene.render();
- params.progressive_refine = (b_engine.is_preview() ||
- get_boolean(cscene, "use_progressive_refine")) &&
- !b_r.use_save_buffers();
-
- if(params.progressive_refine) {
- BL::Scene::view_layers_iterator b_view_layer;
- for(b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end(); ++b_view_layer) {
- PointerRNA crl = RNA_pointer_get(&b_view_layer->ptr, "cycles");
- if(get_boolean(crl, "use_denoising")) {
- params.progressive_refine = false;
- }
- }
- }
-
- if(background) {
- if(params.progressive_refine)
- params.progressive = true;
- else
- params.progressive = false;
-
- params.start_resolution = INT_MAX;
- params.pixel_size = 1;
- }
- else
- params.progressive = true;
-
- /* shading system - scene level needs full refresh */
- const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
-
- if(shadingsystem == 0)
- params.shadingsystem = SHADINGSYSTEM_SVM;
- else if(shadingsystem == 1)
- params.shadingsystem = SHADINGSYSTEM_OSL;
-
- /* color managagement */
- params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
-
- if(b_engine.is_preview()) {
- /* For preview rendering we're using same timeout as
- * blender's job update.
- */
- params.progressive_update_timeout = 0.1;
- }
-
- params.use_profiling = params.device.has_profiling && !b_engine.is_preview() &&
- background && BlenderSession::print_render_stats;
-
- return params;
+ SessionParams params;
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ /* feature set */
+ params.experimental = (get_enum(cscene, "feature_set") != 0);
+
+ /* Background */
+ params.background = background;
+
+ /* Device */
+ params.threads = blender_device_threads(b_scene);
+ params.device = blender_device_info(b_preferences, b_scene, params.background);
+
+ /* samples */
+ int samples = get_int(cscene, "samples");
+ int aa_samples = get_int(cscene, "aa_samples");
+ int preview_samples = get_int(cscene, "preview_samples");
+ int preview_aa_samples = get_int(cscene, "preview_aa_samples");
+
+ if (get_boolean(cscene, "use_square_samples")) {
+ aa_samples = aa_samples * aa_samples;
+ preview_aa_samples = preview_aa_samples * preview_aa_samples;
+
+ samples = samples * samples;
+ preview_samples = preview_samples * preview_samples;
+ }
+
+ if (get_enum(cscene, "progressive") == 0) {
+ if (background) {
+ params.samples = aa_samples;
+ }
+ else {
+ params.samples = preview_aa_samples;
+ if (params.samples == 0)
+ params.samples = INT_MAX;
+ }
+ }
+ else {
+ if (background) {
+ params.samples = samples;
+ }
+ else {
+ params.samples = preview_samples;
+ if (params.samples == 0)
+ params.samples = INT_MAX;
+ }
+ }
+
+ /* Clamp samples. */
+ params.samples = min(params.samples, Integrator::MAX_SAMPLES);
+
+ /* tiles */
+ const bool is_cpu = (params.device.type == DEVICE_CPU);
+ if (!is_cpu && !background) {
+ /* currently GPU could be much slower than CPU when using tiles,
+ * still need to be investigated, but meanwhile make it possible
+ * to work in viewport smoothly
+ */
+ int debug_tile_size = get_int(cscene, "debug_tile_size");
+
+ params.tile_size = make_int2(debug_tile_size, debug_tile_size);
+ }
+ else {
+ int tile_x = b_engine.tile_x();
+ int tile_y = b_engine.tile_y();
+
+ params.tile_size = make_int2(tile_x, tile_y);
+ }
+
+ if ((BlenderSession::headless == false) && background) {
+ params.tile_order = (TileOrder)get_enum(cscene, "tile_order");
+ }
+ else {
+ params.tile_order = TILE_BOTTOM_TO_TOP;
+ }
+
+ /* other parameters */
+ params.start_resolution = get_int(cscene, "preview_start_resolution");
+ params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
+
+ /* other parameters */
+ params.cancel_timeout = (double)get_float(cscene, "debug_cancel_timeout");
+ params.reset_timeout = (double)get_float(cscene, "debug_reset_timeout");
+ params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
+
+ /* progressive refine */
+ BL::RenderSettings b_r = b_scene.render();
+ params.progressive_refine = (b_engine.is_preview() ||
+ get_boolean(cscene, "use_progressive_refine")) &&
+ !b_r.use_save_buffers();
+
+ if (params.progressive_refine) {
+ BL::Scene::view_layers_iterator b_view_layer;
+ for (b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end();
+ ++b_view_layer) {
+ PointerRNA crl = RNA_pointer_get(&b_view_layer->ptr, "cycles");
+ if (get_boolean(crl, "use_denoising")) {
+ params.progressive_refine = false;
+ }
+ }
+ }
+
+ if (background) {
+ if (params.progressive_refine)
+ params.progressive = true;
+ else
+ params.progressive = false;
+
+ params.start_resolution = INT_MAX;
+ params.pixel_size = 1;
+ }
+ else
+ params.progressive = true;
+
+ /* shading system - scene level needs full refresh */
+ const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
+
+ if (shadingsystem == 0)
+ params.shadingsystem = SHADINGSYSTEM_SVM;
+ else if (shadingsystem == 1)
+ params.shadingsystem = SHADINGSYSTEM_OSL;
+
+ /* color managagement */
+ params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
+
+ if (b_engine.is_preview()) {
+ /* For preview rendering we're using same timeout as
+ * blender's job update.
+ */
+ params.progressive_update_timeout = 0.1;
+ }
+
+ params.use_profiling = params.device.has_profiling && !b_engine.is_preview() && background &&
+ BlenderSession::print_render_stats;
+
+ return params;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 8af3fde3323..00afceebde3 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -49,171 +49,173 @@ class ShaderGraph;
class ShaderNode;
class BlenderSync {
-public:
- BlenderSync(BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Scene& b_scene,
- Scene *scene,
- bool preview,
- Progress &progress);
- ~BlenderSync();
-
- /* sync */
- void sync_recalc(BL::Depsgraph& b_depsgraph);
- void sync_data(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::SpaceView3D& b_v3d,
- BL::Object& b_override,
- int width, int height,
- void **python_thread_state);
- void sync_view_layer(BL::SpaceView3D& b_v3d, BL::ViewLayer& b_view_layer);
- vector<Pass> sync_render_passes(BL::RenderLayer& b_render_layer,
- BL::ViewLayer& b_view_layer);
- void sync_integrator();
- void sync_camera(BL::RenderSettings& b_render,
- BL::Object& b_override,
- int width, int height,
- const char *viewname);
- void sync_view(BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height);
- inline int get_layer_samples() { return view_layer.samples; }
- inline int get_layer_bound_samples() { return view_layer.bound_samples; }
-
- /* get parameters */
- static SceneParams get_scene_params(BL::Scene& b_scene,
- bool background);
- static SessionParams get_session_params(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::Scene& b_scene,
- bool background);
- static bool get_session_pause(BL::Scene& b_scene, bool background);
- static BufferParams get_buffer_params(BL::RenderSettings& b_render,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- Camera *cam,
- int width, int height);
-
- static PassType get_pass_type(BL::RenderPass& b_pass);
- static int get_denoising_pass(BL::RenderPass& b_pass);
-
-private:
- /* sync */
- void sync_lights(BL::Depsgraph& b_depsgraph, bool update_all);
- void sync_materials(BL::Depsgraph& b_depsgraph, bool update_all);
- void sync_objects(BL::Depsgraph& b_depsgraph, float motion_time = 0.0f);
- void sync_motion(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::Object& b_override,
- int width, int height,
- void **python_thread_state);
- void sync_film();
- void sync_view();
- void sync_world(BL::Depsgraph& b_depsgraph, bool update_all);
- void sync_shaders(BL::Depsgraph& b_depsgraph);
- void sync_curve_settings();
-
- void sync_nodes(Shader *shader, BL::ShaderNodeTree& b_ntree);
- Mesh *sync_mesh(BL::Depsgraph& b_depsgrpah,
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
- bool object_updated,
- bool show_self,
- bool show_particles);
- void sync_curves(Mesh *mesh,
- BL::Mesh& b_mesh,
- BL::Object& b_ob,
- bool motion,
- int motion_step = 0);
- Object *sync_object(BL::Depsgraph& b_depsgraph,
- BL::ViewLayer& b_view_layer,
- BL::DepsgraphObjectInstance& b_instance,
- float motion_time,
- bool show_self,
- bool show_particles,
- BlenderObjectCulling& culling,
- bool *use_portal);
- void sync_light(BL::Object& b_parent,
- int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
- int random_id,
- Transform& tfm,
- bool *use_portal);
- void sync_background_light(bool use_portal);
- void sync_mesh_motion(BL::Depsgraph& b_depsgraph,
- BL::Object& b_ob,
- Object *object,
- float motion_time);
- void sync_camera_motion(BL::RenderSettings& b_render,
- BL::Object& b_ob,
- int width, int height,
- float motion_time);
-
- /* particles */
- bool sync_dupli_particle(BL::Object& b_ob,
- BL::DepsgraphObjectInstance& b_instance,
- Object *object);
-
- /* Images. */
- void sync_images();
-
- /* Early data free. */
- void free_data_after_sync(BL::Depsgraph& b_depsgraph);
-
- /* util */
- void find_shader(BL::ID& id, vector<Shader*>& used_shaders, Shader *default_shader);
- bool BKE_object_is_modified(BL::Object& b_ob);
- bool object_is_mesh(BL::Object& b_ob);
- bool object_is_light(BL::Object& b_ob);
-
- /* variables */
- BL::RenderEngine b_engine;
- BL::BlendData b_data;
- BL::Scene b_scene;
-
- id_map<void*, Shader> shader_map;
- id_map<ObjectKey, Object> object_map;
- id_map<void*, Mesh> mesh_map;
- id_map<ObjectKey, Light> light_map;
- id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
- set<Mesh*> mesh_synced;
- set<Mesh*> mesh_motion_synced;
- set<float> motion_times;
- void *world_map;
- bool world_recalc;
-
- Scene *scene;
- bool preview;
- bool experimental;
-
- float dicing_rate;
- int max_subdivisions;
-
- struct RenderLayerInfo {
- RenderLayerInfo()
- : material_override(PointerRNA_NULL),
- use_background_shader(true),
- use_background_ao(true),
- use_surfaces(true),
- use_hair(true),
- samples(0),
- bound_samples(false)
- {}
-
- string name;
- BL::Material material_override;
- bool use_background_shader;
- bool use_background_ao;
- bool use_surfaces;
- bool use_hair;
- int samples;
- bool bound_samples;
- } view_layer;
-
- Progress &progress;
+ public:
+ BlenderSync(BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Scene &b_scene,
+ Scene *scene,
+ bool preview,
+ Progress &progress);
+ ~BlenderSync();
+
+ /* sync */
+ void sync_recalc(BL::Depsgraph &b_depsgraph);
+ void sync_data(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::SpaceView3D &b_v3d,
+ BL::Object &b_override,
+ int width,
+ int height,
+ void **python_thread_state);
+ void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
+ vector<Pass> sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer);
+ void sync_integrator();
+ void sync_camera(BL::RenderSettings &b_render,
+ BL::Object &b_override,
+ int width,
+ int height,
+ const char *viewname);
+ void sync_view(BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, int width, int height);
+ inline int get_layer_samples()
+ {
+ return view_layer.samples;
+ }
+ inline int get_layer_bound_samples()
+ {
+ return view_layer.bound_samples;
+ }
+
+ /* get parameters */
+ static SceneParams get_scene_params(BL::Scene &b_scene, bool background);
+ static SessionParams get_session_params(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::Scene &b_scene,
+ bool background);
+ static bool get_session_pause(BL::Scene &b_scene, bool background);
+ static BufferParams get_buffer_params(BL::RenderSettings &b_render,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ Camera *cam,
+ int width,
+ int height);
+
+ static PassType get_pass_type(BL::RenderPass &b_pass);
+ static int get_denoising_pass(BL::RenderPass &b_pass);
+
+ private:
+ /* sync */
+ void sync_lights(BL::Depsgraph &b_depsgraph, bool update_all);
+ void sync_materials(BL::Depsgraph &b_depsgraph, bool update_all);
+ void sync_objects(BL::Depsgraph &b_depsgraph, float motion_time = 0.0f);
+ void sync_motion(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::Object &b_override,
+ int width,
+ int height,
+ void **python_thread_state);
+ void sync_film();
+ void sync_view();
+ void sync_world(BL::Depsgraph &b_depsgraph, bool update_all);
+ void sync_shaders(BL::Depsgraph &b_depsgraph);
+ void sync_curve_settings();
+
+ void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
+ Mesh *sync_mesh(BL::Depsgraph &b_depsgrpah,
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
+ bool object_updated,
+ bool show_self,
+ bool show_particles);
+ void sync_curves(
+ Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0);
+ Object *sync_object(BL::Depsgraph &b_depsgraph,
+ BL::ViewLayer &b_view_layer,
+ BL::DepsgraphObjectInstance &b_instance,
+ float motion_time,
+ bool show_self,
+ bool show_particles,
+ BlenderObjectCulling &culling,
+ bool *use_portal);
+ void sync_light(BL::Object &b_parent,
+ int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
+ int random_id,
+ Transform &tfm,
+ bool *use_portal);
+ void sync_background_light(bool use_portal);
+ void sync_mesh_motion(BL::Depsgraph &b_depsgraph,
+ BL::Object &b_ob,
+ Object *object,
+ float motion_time);
+ void sync_camera_motion(
+ BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time);
+
+ /* particles */
+ bool sync_dupli_particle(BL::Object &b_ob,
+ BL::DepsgraphObjectInstance &b_instance,
+ Object *object);
+
+ /* Images. */
+ void sync_images();
+
+ /* Early data free. */
+ void free_data_after_sync(BL::Depsgraph &b_depsgraph);
+
+ /* util */
+ void find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader);
+ bool BKE_object_is_modified(BL::Object &b_ob);
+ bool object_is_mesh(BL::Object &b_ob);
+ bool object_is_light(BL::Object &b_ob);
+
+ /* variables */
+ BL::RenderEngine b_engine;
+ BL::BlendData b_data;
+ BL::Scene b_scene;
+
+ id_map<void *, Shader> shader_map;
+ id_map<ObjectKey, Object> object_map;
+ id_map<void *, Mesh> mesh_map;
+ id_map<ObjectKey, Light> light_map;
+ id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
+ set<Mesh *> mesh_synced;
+ set<Mesh *> mesh_motion_synced;
+ set<float> motion_times;
+ void *world_map;
+ bool world_recalc;
+
+ Scene *scene;
+ bool preview;
+ bool experimental;
+
+ float dicing_rate;
+ int max_subdivisions;
+
+ struct RenderLayerInfo {
+ RenderLayerInfo()
+ : material_override(PointerRNA_NULL),
+ use_background_shader(true),
+ use_background_ao(true),
+ use_surfaces(true),
+ use_hair(true),
+ samples(0),
+ bound_samples(false)
+ {
+ }
+
+ string name;
+ BL::Material material_override;
+ bool use_background_shader;
+ bool use_background_ao;
+ bool use_surfaces;
+ bool use_hair;
+ int samples;
+ bool bound_samples;
+ } view_layer;
+
+ Progress &progress;
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_SYNC_H__ */
+#endif /* __BLENDER_SYNC_H__ */
diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp
index a0371a7eed8..7b05f361a29 100644
--- a/intern/cycles/blender/blender_texture.cpp
+++ b/intern/cycles/blender/blender_texture.cpp
@@ -22,36 +22,36 @@ namespace {
/* Point density helpers. */
-void density_texture_space_invert(float3& loc,
- float3& size)
+void density_texture_space_invert(float3 &loc, float3 &size)
{
- if(size.x != 0.0f) size.x = 0.5f/size.x;
- if(size.y != 0.0f) size.y = 0.5f/size.y;
- if(size.z != 0.0f) size.z = 0.5f/size.z;
-
- loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+ if (size.x != 0.0f)
+ size.x = 0.5f / size.x;
+ if (size.y != 0.0f)
+ size.y = 0.5f / size.y;
+ if (size.z != 0.0f)
+ size.z = 0.5f / size.z;
+
+ loc = loc * size - make_float3(0.5f, 0.5f, 0.5f);
}
-} /* namespace */
+} /* namespace */
-void point_density_texture_space(BL::Depsgraph& b_depsgraph,
- BL::ShaderNodeTexPointDensity& b_point_density_node,
- float3& loc,
- float3& size)
+void point_density_texture_space(BL::Depsgraph &b_depsgraph,
+ BL::ShaderNodeTexPointDensity &b_point_density_node,
+ float3 &loc,
+ float3 &size)
{
- BL::Object b_ob(b_point_density_node.object());
- if(!b_ob) {
- loc = make_float3(0.0f, 0.0f, 0.0f);
- size = make_float3(0.0f, 0.0f, 0.0f);
- return;
- }
- float3 min, max;
- b_point_density_node.calc_point_density_minmax(b_depsgraph,
- &min[0],
- &max[0]);
- loc = (min + max) * 0.5f;
- size = (max - min) * 0.5f;
- density_texture_space_invert(loc, size);
+ BL::Object b_ob(b_point_density_node.object());
+ if (!b_ob) {
+ loc = make_float3(0.0f, 0.0f, 0.0f);
+ size = make_float3(0.0f, 0.0f, 0.0f);
+ return;
+ }
+ float3 min, max;
+ b_point_density_node.calc_point_density_minmax(b_depsgraph, &min[0], &max[0]);
+ loc = (min + max) * 0.5f;
+ size = (max - min) * 0.5f;
+ density_texture_space_invert(loc, size);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_texture.h b/intern/cycles/blender/blender_texture.h
index b4e166c5cdd..896bf62da70 100644
--- a/intern/cycles/blender/blender_texture.h
+++ b/intern/cycles/blender/blender_texture.h
@@ -22,11 +22,11 @@
CCL_NAMESPACE_BEGIN
-void point_density_texture_space(BL::Depsgraph& b_depsgraph,
- BL::ShaderNodeTexPointDensity& b_point_density_node,
- float3& loc,
- float3& size);
+void point_density_texture_space(BL::Depsgraph &b_depsgraph,
+ BL::ShaderNodeTexPointDensity &b_point_density_node,
+ float3 &loc,
+ float3 &size);
CCL_NAMESPACE_END
-#endif /* __BLENDER_TEXTURE_H__ */
+#endif /* __BLENDER_TEXTURE_H__ */
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index f302b09459f..e68f92474bf 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -43,338 +43,320 @@ CCL_NAMESPACE_BEGIN
void python_thread_state_save(void **python_thread_state);
void python_thread_state_restore(void **python_thread_state);
-static inline BL::Mesh object_to_mesh(BL::BlendData& data,
- BL::Object& object,
- BL::Depsgraph& depsgraph,
+static inline BL::Mesh object_to_mesh(BL::BlendData &data,
+ BL::Object &object,
+ BL::Depsgraph &depsgraph,
bool calc_undeformed,
Mesh::SubdivisionType subdivision_type)
{
- /* TODO: make this work with copy-on-write, modifiers are already evaluated. */
+ /* TODO: make this work with copy-on-write, modifiers are already evaluated. */
#if 0
- bool subsurf_mod_show_render = false;
- bool subsurf_mod_show_viewport = false;
+ bool subsurf_mod_show_render = false;
+ bool subsurf_mod_show_viewport = false;
- if(subdivision_type != Mesh::SUBDIVISION_NONE) {
- BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+ if(subdivision_type != Mesh::SUBDIVISION_NONE) {
+ BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
- subsurf_mod_show_render = subsurf_mod.show_render();
- subsurf_mod_show_viewport = subsurf_mod.show_viewport();
+ subsurf_mod_show_render = subsurf_mod.show_render();
+ subsurf_mod_show_viewport = subsurf_mod.show_viewport();
- subsurf_mod.show_render(false);
- subsurf_mod.show_viewport(false);
- }
+ subsurf_mod.show_render(false);
+ subsurf_mod.show_viewport(false);
+ }
#endif
- BL::Mesh mesh(PointerRNA_NULL);
- if(object.type() == BL::Object::type_MESH) {
- /* TODO: calc_undeformed is not used. */
- mesh = BL::Mesh(object.data());
-
- /* Make a copy to split faces if we use autosmooth, otherwise not needed.
- * Also in edit mode do we need to make a copy, to ensure data layers like
- * UV are not empty. */
- if (mesh.is_editmode() ||
- (mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE))
- {
- mesh = data.meshes.new_from_object(depsgraph, object, false, false);
- }
- }
- else {
- mesh = data.meshes.new_from_object(depsgraph, object, true, calc_undeformed);
- }
+ BL::Mesh mesh(PointerRNA_NULL);
+ if (object.type() == BL::Object::type_MESH) {
+ /* TODO: calc_undeformed is not used. */
+ mesh = BL::Mesh(object.data());
+
+ /* Make a copy to split faces if we use autosmooth, otherwise not needed.
+ * Also in edit mode do we need to make a copy, to ensure data layers like
+ * UV are not empty. */
+ if (mesh.is_editmode() ||
+ (mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
+ mesh = data.meshes.new_from_object(depsgraph, object, false, false);
+ }
+ }
+ else {
+ mesh = data.meshes.new_from_object(depsgraph, object, true, calc_undeformed);
+ }
#if 0
- if(subdivision_type != Mesh::SUBDIVISION_NONE) {
- BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+ if(subdivision_type != Mesh::SUBDIVISION_NONE) {
+ BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
- subsurf_mod.show_render(subsurf_mod_show_render);
- subsurf_mod.show_viewport(subsurf_mod_show_viewport);
- }
+ subsurf_mod.show_render(subsurf_mod_show_render);
+ subsurf_mod.show_viewport(subsurf_mod_show_viewport);
+ }
#endif
- if((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) {
- if(mesh.use_auto_smooth()) {
- mesh.split_faces(false);
- }
+ if ((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) {
+ if (mesh.use_auto_smooth()) {
+ mesh.split_faces(false);
+ }
- mesh.calc_loop_triangles();
- }
+ mesh.calc_loop_triangles();
+ }
- return mesh;
+ return mesh;
}
-static inline void free_object_to_mesh(BL::BlendData& data,
- BL::Object& object,
- BL::Mesh& mesh)
+static inline void free_object_to_mesh(BL::BlendData &data, BL::Object &object, BL::Mesh &mesh)
{
- /* Free mesh if we didn't just use the existing one. */
- if(object.data().ptr.data != mesh.ptr.data) {
- data.meshes.remove(mesh, false, true, false);
- }
+ /* Free mesh if we didn't just use the existing one. */
+ if (object.data().ptr.data != mesh.ptr.data) {
+ data.meshes.remove(mesh, false, true, false);
+ }
}
-static inline void colorramp_to_array(BL::ColorRamp& ramp,
- array<float3>& ramp_color,
- array<float>& ramp_alpha,
+static inline void colorramp_to_array(BL::ColorRamp &ramp,
+ array<float3> &ramp_color,
+ array<float> &ramp_alpha,
int size)
{
- ramp_color.resize(size);
- ramp_alpha.resize(size);
+ ramp_color.resize(size);
+ ramp_alpha.resize(size);
- for(int i = 0; i < size; i++) {
- float color[4];
+ for (int i = 0; i < size; i++) {
+ float color[4];
- ramp.evaluate((float)i/(float)(size-1), color);
- ramp_color[i] = make_float3(color[0], color[1], color[2]);
- ramp_alpha[i] = color[3];
- }
+ ramp.evaluate((float)i / (float)(size - 1), color);
+ ramp_color[i] = make_float3(color[0], color[1], color[2]);
+ ramp_alpha[i] = color[3];
+ }
}
-static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap& curve,
- float *min_x,
- float *max_x)
+static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap &curve, float *min_x, float *max_x)
{
- *min_x = min(*min_x, curve.points[0].location()[0]);
- *max_x = max(*max_x, curve.points[curve.points.length() - 1].location()[0]);
+ *min_x = min(*min_x, curve.points[0].location()[0]);
+ *max_x = max(*max_x, curve.points[curve.points.length() - 1].location()[0]);
}
-static inline void curvemapping_minmax(/*const*/ BL::CurveMapping& cumap,
+static inline void curvemapping_minmax(/*const*/ BL::CurveMapping &cumap,
bool rgb_curve,
float *min_x,
float *max_x)
{
- /* const int num_curves = cumap.curves.length(); */ /* Gives linking error so far. */
- const int num_curves = rgb_curve? 4: 3;
- *min_x = FLT_MAX;
- *max_x = -FLT_MAX;
- for(int i = 0; i < num_curves; ++i) {
- BL::CurveMap map(cumap.curves[i]);
- curvemap_minmax_curve(map, min_x, max_x);
- }
+ /* const int num_curves = cumap.curves.length(); */ /* Gives linking error so far. */
+ const int num_curves = rgb_curve ? 4 : 3;
+ *min_x = FLT_MAX;
+ *max_x = -FLT_MAX;
+ for (int i = 0; i < num_curves; ++i) {
+ BL::CurveMap map(cumap.curves[i]);
+ curvemap_minmax_curve(map, min_x, max_x);
+ }
}
-static inline void curvemapping_to_array(BL::CurveMapping& cumap,
- array<float>& data,
- int size)
+static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &data, int size)
{
- cumap.update();
- BL::CurveMap curve = cumap.curves[0];
- data.resize(size);
- for(int i = 0; i < size; i++) {
- float t = (float)i/(float)(size-1);
- data[i] = curve.evaluate(t);
- }
+ cumap.update();
+ BL::CurveMap curve = cumap.curves[0];
+ data.resize(size);
+ for (int i = 0; i < size; i++) {
+ float t = (float)i / (float)(size - 1);
+ data[i] = curve.evaluate(t);
+ }
}
-static inline void curvemapping_color_to_array(BL::CurveMapping& cumap,
- array<float3>& data,
+static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
+ array<float3> &data,
int size,
bool rgb_curve)
{
- float min_x = 0.0f, max_x = 1.0f;
+ float min_x = 0.0f, max_x = 1.0f;
- /* TODO(sergey): There is no easy way to automatically guess what is
- * the range to be used here for the case when mapping is applied on
- * top of another mapping (i.e. R curve applied on top of common
- * one).
- *
- * Using largest possible range form all curves works correct for the
- * cases like vector curves and should be good enough heuristic for
- * the color curves as well.
- *
- * There might be some better estimations here tho.
- */
- curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
+ /* TODO(sergey): There is no easy way to automatically guess what is
+ * the range to be used here for the case when mapping is applied on
+ * top of another mapping (i.e. R curve applied on top of common
+ * one).
+ *
+ * Using largest possible range form all curves works correct for the
+ * cases like vector curves and should be good enough heuristic for
+ * the color curves as well.
+ *
+ * There might be some better estimations here tho.
+ */
+ curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
- const float range_x = max_x - min_x;
+ const float range_x = max_x - min_x;
- cumap.update();
+ cumap.update();
- BL::CurveMap mapR = cumap.curves[0];
- BL::CurveMap mapG = cumap.curves[1];
- BL::CurveMap mapB = cumap.curves[2];
+ BL::CurveMap mapR = cumap.curves[0];
+ BL::CurveMap mapG = cumap.curves[1];
+ BL::CurveMap mapB = cumap.curves[2];
- data.resize(size);
+ data.resize(size);
- if(rgb_curve) {
- BL::CurveMap mapI = cumap.curves[3];
- for(int i = 0; i < size; i++) {
- const float t = min_x + (float)i/(float)(size-1) * range_x;
- data[i] = make_float3(mapR.evaluate(mapI.evaluate(t)),
- mapG.evaluate(mapI.evaluate(t)),
- mapB.evaluate(mapI.evaluate(t)));
- }
- }
- else {
- for(int i = 0; i < size; i++) {
- float t = min_x + (float)i/(float)(size-1) * range_x;
- data[i] = make_float3(mapR.evaluate(t),
- mapG.evaluate(t),
- mapB.evaluate(t));
- }
- }
+ if (rgb_curve) {
+ BL::CurveMap mapI = cumap.curves[3];
+ for (int i = 0; i < size; i++) {
+ const float t = min_x + (float)i / (float)(size - 1) * range_x;
+ data[i] = make_float3(mapR.evaluate(mapI.evaluate(t)),
+ mapG.evaluate(mapI.evaluate(t)),
+ mapB.evaluate(mapI.evaluate(t)));
+ }
+ }
+ else {
+ for (int i = 0; i < size; i++) {
+ float t = min_x + (float)i / (float)(size - 1) * range_x;
+ data[i] = make_float3(mapR.evaluate(t), mapG.evaluate(t), mapB.evaluate(t));
+ }
+ }
}
-static inline bool BKE_object_is_modified(BL::Object& self,
- BL::Scene& scene,
- bool preview)
+static inline bool BKE_object_is_modified(BL::Object &self, BL::Scene &scene, bool preview)
{
- return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
+ return self.is_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
}
-static inline bool BKE_object_is_deform_modified(BL::Object& self,
- BL::Scene& scene,
- bool preview)
+static inline bool BKE_object_is_deform_modified(BL::Object &self, BL::Scene &scene, bool preview)
{
- return self.is_deform_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
+ return self.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
}
-static inline int render_resolution_x(BL::RenderSettings& b_render)
+static inline int render_resolution_x(BL::RenderSettings &b_render)
{
- return b_render.resolution_x()*b_render.resolution_percentage()/100;
+ return b_render.resolution_x() * b_render.resolution_percentage() / 100;
}
-static inline int render_resolution_y(BL::RenderSettings& b_render)
+static inline int render_resolution_y(BL::RenderSettings &b_render)
{
- return b_render.resolution_y()*b_render.resolution_percentage()/100;
+ return b_render.resolution_y() * b_render.resolution_percentage() / 100;
}
-static inline string image_user_file_path(BL::ImageUser& iuser,
- BL::Image& ima,
- int cfra)
+static inline string image_user_file_path(BL::ImageUser &iuser, BL::Image &ima, int cfra)
{
- char filepath[1024];
- BKE_image_user_frame_calc(iuser.ptr.data, cfra);
- BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
- return string(filepath);
+ char filepath[1024];
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra);
+ BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
+ return string(filepath);
}
-static inline int image_user_frame_number(BL::ImageUser& iuser, int cfra)
+static inline int image_user_frame_number(BL::ImageUser &iuser, int cfra)
{
- BKE_image_user_frame_calc(iuser.ptr.data, cfra);
- return iuser.frame_current();
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra);
+ return iuser.frame_current();
}
-static inline unsigned char *image_get_pixels_for_frame(BL::Image& image,
- int frame)
+static inline unsigned char *image_get_pixels_for_frame(BL::Image &image, int frame)
{
- return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
+ return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
}
-static inline float *image_get_float_pixels_for_frame(BL::Image& image,
- int frame)
+static inline float *image_get_float_pixels_for_frame(BL::Image &image, int frame)
{
- return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
+ return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
}
-static inline void render_add_metadata(BL::RenderResult& b_rr, string name, string value)
+static inline void render_add_metadata(BL::RenderResult &b_rr, string name, string value)
{
- b_rr.stamp_data_add_field(name.c_str(), value.c_str());
+ b_rr.stamp_data_add_field(name.c_str(), value.c_str());
}
-
/* Utilities */
-static inline Transform get_transform(const BL::Array<float, 16>& array)
+static inline Transform get_transform(const BL::Array<float, 16> &array)
{
- ProjectionTransform projection;
+ ProjectionTransform projection;
- /* We assume both types to be just 16 floats, and transpose because blender
- * use column major matrix order while we use row major. */
- memcpy((void *)&projection, &array, sizeof(float)*16);
- projection = projection_transpose(projection);
+ /* We assume both types to be just 16 floats, and transpose because blender
+ * use column major matrix order while we use row major. */
+ memcpy((void *)&projection, &array, sizeof(float) * 16);
+ projection = projection_transpose(projection);
- /* Drop last row, matrix is assumed to be affine transform. */
- return projection_to_transform(projection);
+ /* Drop last row, matrix is assumed to be affine transform. */
+ return projection_to_transform(projection);
}
-static inline float2 get_float2(const BL::Array<float, 2>& array)
+static inline float2 get_float2(const BL::Array<float, 2> &array)
{
- return make_float2(array[0], array[1]);
+ return make_float2(array[0], array[1]);
}
-static inline float3 get_float3(const BL::Array<float, 2>& array)
+static inline float3 get_float3(const BL::Array<float, 2> &array)
{
- return make_float3(array[0], array[1], 0.0f);
+ return make_float3(array[0], array[1], 0.0f);
}
-static inline float3 get_float3(const BL::Array<float, 3>& array)
+static inline float3 get_float3(const BL::Array<float, 3> &array)
{
- return make_float3(array[0], array[1], array[2]);
+ return make_float3(array[0], array[1], array[2]);
}
-static inline float3 get_float3(const BL::Array<float, 4>& array)
+static inline float3 get_float3(const BL::Array<float, 4> &array)
{
- return make_float3(array[0], array[1], array[2]);
+ return make_float3(array[0], array[1], array[2]);
}
-static inline float4 get_float4(const BL::Array<float, 4>& array)
+static inline float4 get_float4(const BL::Array<float, 4> &array)
{
- return make_float4(array[0], array[1], array[2], array[3]);
+ return make_float4(array[0], array[1], array[2], array[3]);
}
-static inline int3 get_int3(const BL::Array<int, 3>& array)
+static inline int3 get_int3(const BL::Array<int, 3> &array)
{
- return make_int3(array[0], array[1], array[2]);
+ return make_int3(array[0], array[1], array[2]);
}
-static inline int4 get_int4(const BL::Array<int, 4>& array)
+static inline int4 get_int4(const BL::Array<int, 4> &array)
{
- return make_int4(array[0], array[1], array[2], array[3]);
+ return make_int4(array[0], array[1], array[2], array[3]);
}
-static inline float3 get_float3(PointerRNA& ptr, const char *name)
+static inline float3 get_float3(PointerRNA &ptr, const char *name)
{
- float3 f;
- RNA_float_get_array(&ptr, name, &f.x);
- return f;
+ float3 f;
+ RNA_float_get_array(&ptr, name, &f.x);
+ return f;
}
-static inline void set_float3(PointerRNA& ptr, const char *name, float3 value)
+static inline void set_float3(PointerRNA &ptr, const char *name, float3 value)
{
- RNA_float_set_array(&ptr, name, &value.x);
+ RNA_float_set_array(&ptr, name, &value.x);
}
-static inline float4 get_float4(PointerRNA& ptr, const char *name)
+static inline float4 get_float4(PointerRNA &ptr, const char *name)
{
- float4 f;
- RNA_float_get_array(&ptr, name, &f.x);
- return f;
+ float4 f;
+ RNA_float_get_array(&ptr, name, &f.x);
+ return f;
}
-static inline void set_float4(PointerRNA& ptr, const char *name, float4 value)
+static inline void set_float4(PointerRNA &ptr, const char *name, float4 value)
{
- RNA_float_set_array(&ptr, name, &value.x);
+ RNA_float_set_array(&ptr, name, &value.x);
}
-static inline bool get_boolean(PointerRNA& ptr, const char *name)
+static inline bool get_boolean(PointerRNA &ptr, const char *name)
{
- return RNA_boolean_get(&ptr, name)? true: false;
+ return RNA_boolean_get(&ptr, name) ? true : false;
}
-static inline void set_boolean(PointerRNA& ptr, const char *name, bool value)
+static inline void set_boolean(PointerRNA &ptr, const char *name, bool value)
{
- RNA_boolean_set(&ptr, name, (int)value);
+ RNA_boolean_set(&ptr, name, (int)value);
}
-static inline float get_float(PointerRNA& ptr, const char *name)
+static inline float get_float(PointerRNA &ptr, const char *name)
{
- return RNA_float_get(&ptr, name);
+ return RNA_float_get(&ptr, name);
}
-static inline void set_float(PointerRNA& ptr, const char *name, float value)
+static inline void set_float(PointerRNA &ptr, const char *name, float value)
{
- RNA_float_set(&ptr, name, value);
+ RNA_float_set(&ptr, name, value);
}
-static inline int get_int(PointerRNA& ptr, const char *name)
+static inline int get_int(PointerRNA &ptr, const char *name)
{
- return RNA_int_get(&ptr, name);
+ return RNA_int_get(&ptr, name);
}
-static inline void set_int(PointerRNA& ptr, const char *name, int value)
+static inline void set_int(PointerRNA &ptr, const char *name, int value)
{
- RNA_int_set(&ptr, name, value);
+ RNA_int_set(&ptr, name, value);
}
/* Get a RNA enum value with sanity check: if the RNA value is above num_values
@@ -384,215 +366,214 @@ static inline void set_int(PointerRNA& ptr, const char *name, int value)
* from 0 to num_values-1. Be careful to use it with enums where some values are
* deprecated!
*/
-static inline int get_enum(PointerRNA& ptr,
+static inline int get_enum(PointerRNA &ptr,
const char *name,
int num_values = -1,
int default_value = -1)
{
- int value = RNA_enum_get(&ptr, name);
- if(num_values != -1 && value >= num_values) {
- assert(default_value != -1);
- value = default_value;
- }
- return value;
+ int value = RNA_enum_get(&ptr, name);
+ if (num_values != -1 && value >= num_values) {
+ assert(default_value != -1);
+ value = default_value;
+ }
+ return value;
}
-static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
+static inline string get_enum_identifier(PointerRNA &ptr, const char *name)
{
- PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
- const char *identifier = "";
- int value = RNA_property_enum_get(&ptr, prop);
+ PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
+ const char *identifier = "";
+ int value = RNA_property_enum_get(&ptr, prop);
- RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
+ RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
- return string(identifier);
+ return string(identifier);
}
-static inline void set_enum(PointerRNA& ptr, const char *name, int value)
+static inline void set_enum(PointerRNA &ptr, const char *name, int value)
{
- RNA_enum_set(&ptr, name, value);
+ RNA_enum_set(&ptr, name, value);
}
-static inline void set_enum(PointerRNA& ptr, const char *name, const string &identifier)
+static inline void set_enum(PointerRNA &ptr, const char *name, const string &identifier)
{
- RNA_enum_set_identifier(NULL, &ptr, name, identifier.c_str());
+ RNA_enum_set_identifier(NULL, &ptr, name, identifier.c_str());
}
-static inline string get_string(PointerRNA& ptr, const char *name)
+static inline string get_string(PointerRNA &ptr, const char *name)
{
- char cstrbuf[1024];
- char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
- string str(cstr);
- if(cstr != cstrbuf)
- MEM_freeN(cstr);
+ char cstrbuf[1024];
+ char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
+ string str(cstr);
+ if (cstr != cstrbuf)
+ MEM_freeN(cstr);
- return str;
+ return str;
}
-static inline void set_string(PointerRNA& ptr, const char *name, const string &value)
+static inline void set_string(PointerRNA &ptr, const char *name, const string &value)
{
- RNA_string_set(&ptr, name, value.c_str());
+ RNA_string_set(&ptr, name, value.c_str());
}
/* Relative Paths */
-static inline string blender_absolute_path(BL::BlendData& b_data,
- BL::ID& b_id,
- const string& path)
+static inline string blender_absolute_path(BL::BlendData &b_data, BL::ID &b_id, const string &path)
{
- if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
- string dirname;
+ if (path.size() >= 2 && path[0] == '/' && path[1] == '/') {
+ string dirname;
- if(b_id.library()) {
- BL::ID b_library_id(b_id.library());
- dirname = blender_absolute_path(b_data,
- b_library_id,
- b_id.library().filepath());
- }
- else
- dirname = b_data.filepath();
+ if (b_id.library()) {
+ BL::ID b_library_id(b_id.library());
+ dirname = blender_absolute_path(b_data, b_library_id, b_id.library().filepath());
+ }
+ else
+ dirname = b_data.filepath();
- return path_join(path_dirname(dirname), path.substr(2));
- }
+ return path_join(path_dirname(dirname), path.substr(2));
+ }
- return path;
+ return path;
}
-static inline string get_text_datablock_content(const PointerRNA& ptr)
+static inline string get_text_datablock_content(const PointerRNA &ptr)
{
- if(ptr.data == NULL) {
- return "";
- }
+ if (ptr.data == NULL) {
+ return "";
+ }
- string content;
- BL::Text::lines_iterator iter;
- for(iter.begin(ptr); iter; ++iter) {
- content += iter->body() + "\n";
- }
+ string content;
+ BL::Text::lines_iterator iter;
+ for (iter.begin(ptr); iter; ++iter) {
+ content += iter->body() + "\n";
+ }
- return content;
+ return content;
}
/* Texture Space */
-static inline void mesh_texture_space(BL::Mesh& b_mesh,
- float3& loc,
- float3& size)
+static inline void mesh_texture_space(BL::Mesh &b_mesh, float3 &loc, float3 &size)
{
- loc = get_float3(b_mesh.texspace_location());
- size = get_float3(b_mesh.texspace_size());
+ loc = get_float3(b_mesh.texspace_location());
+ size = get_float3(b_mesh.texspace_size());
- if(size.x != 0.0f) size.x = 0.5f/size.x;
- if(size.y != 0.0f) size.y = 0.5f/size.y;
- if(size.z != 0.0f) size.z = 0.5f/size.z;
+ if (size.x != 0.0f)
+ size.x = 0.5f / size.x;
+ if (size.y != 0.0f)
+ size.y = 0.5f / size.y;
+ if (size.z != 0.0f)
+ size.z = 0.5f / size.z;
- loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+ loc = loc * size - make_float3(0.5f, 0.5f, 0.5f);
}
/* Object motion steps, returns 0 if no motion blur needed. */
-static inline uint object_motion_steps(BL::Object& b_parent, BL::Object& b_ob)
+static inline uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob)
{
- /* Get motion enabled and steps from object itself. */
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_motion = get_boolean(cobject, "use_motion_blur");
- if(!use_motion) {
- return 0;
- }
+ /* Get motion enabled and steps from object itself. */
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_motion = get_boolean(cobject, "use_motion_blur");
+ if (!use_motion) {
+ return 0;
+ }
- uint steps = max(1, get_int(cobject, "motion_steps"));
+ uint steps = max(1, get_int(cobject, "motion_steps"));
- /* Also check parent object, so motion blur and steps can be
- * controlled by dupligroup duplicator for linked groups. */
- if(b_parent.ptr.data != b_ob.ptr.data) {
- PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
- use_motion &= get_boolean(parent_cobject, "use_motion_blur");
+ /* Also check parent object, so motion blur and steps can be
+ * controlled by dupligroup duplicator for linked groups. */
+ if (b_parent.ptr.data != b_ob.ptr.data) {
+ PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
+ use_motion &= get_boolean(parent_cobject, "use_motion_blur");
- if(!use_motion) {
- return 0;
- }
+ if (!use_motion) {
+ return 0;
+ }
- steps = max(steps, get_int(parent_cobject, "motion_steps"));
- }
+ steps = max(steps, get_int(parent_cobject, "motion_steps"));
+ }
- /* Use uneven number of steps so we get one keyframe at the current frame,
- * and use 2^(steps - 1) so objects with more/fewer steps still have samples
- * at the same times, to avoid sampling at many different times. */
- return (2 << (steps - 1)) + 1;
+ /* Use uneven number of steps so we get one keyframe at the current frame,
+ * and use 2^(steps - 1) so objects with more/fewer steps still have samples
+ * at the same times, to avoid sampling at many different times. */
+ return (2 << (steps - 1)) + 1;
}
/* object uses deformation motion blur */
-static inline bool object_use_deform_motion(BL::Object& b_parent,
- BL::Object& b_ob)
+static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_ob)
{
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
- /* If motion blur is enabled for the object we also check
- * whether it's enabled for the parent object as well.
- *
- * This way we can control motion blur from the dupligroup
- * duplicator much easier.
- */
- if(use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
- PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
- use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
- }
- return use_deform_motion;
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
+ /* If motion blur is enabled for the object we also check
+ * whether it's enabled for the parent object as well.
+ *
+ * This way we can control motion blur from the dupligroup
+ * duplicator much easier.
+ */
+ if (use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
+ PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
+ use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
+ }
+ return use_deform_motion;
}
-static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object& b_ob)
+static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object &b_ob)
{
- BL::Object::modifiers_iterator b_mod;
+ BL::Object::modifiers_iterator b_mod;
- for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
- if(b_mod->is_a(&RNA_SmokeModifier)) {
- BL::SmokeModifier b_smd(*b_mod);
+ for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
+ if (b_mod->is_a(&RNA_SmokeModifier)) {
+ BL::SmokeModifier b_smd(*b_mod);
- if(b_smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN)
- return b_smd.domain_settings();
- }
- }
+ if (b_smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN)
+ return b_smd.domain_settings();
+ }
+ }
- return BL::SmokeDomainSettings(PointerRNA_NULL);
+ return BL::SmokeDomainSettings(PointerRNA_NULL);
}
static inline BL::DomainFluidSettings object_fluid_domain_find(BL::Object b_ob)
{
- BL::Object::modifiers_iterator b_mod;
+ BL::Object::modifiers_iterator b_mod;
- for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
- if(b_mod->is_a(&RNA_FluidSimulationModifier)) {
- BL::FluidSimulationModifier b_fmd(*b_mod);
- BL::FluidSettings fss = b_fmd.settings();
+ for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
+ if (b_mod->is_a(&RNA_FluidSimulationModifier)) {
+ BL::FluidSimulationModifier b_fmd(*b_mod);
+ BL::FluidSettings fss = b_fmd.settings();
- if(fss.type() == BL::FluidSettings::type_DOMAIN)
- return (BL::DomainFluidSettings)b_fmd.settings();
- }
- }
+ if (fss.type() == BL::FluidSettings::type_DOMAIN)
+ return (BL::DomainFluidSettings)b_fmd.settings();
+ }
+ }
- return BL::DomainFluidSettings(PointerRNA_NULL);
+ return BL::DomainFluidSettings(PointerRNA_NULL);
}
-static inline Mesh::SubdivisionType object_subdivision_type(BL::Object& b_ob, bool preview, bool experimental)
+static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
+ bool preview,
+ bool experimental)
{
- PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
+ PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
- if(cobj.data && b_ob.modifiers.length() > 0 && experimental) {
- BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1];
- bool enabled = preview ? mod.show_viewport() : mod.show_render();
+ if (cobj.data && b_ob.modifiers.length() > 0 && experimental) {
+ BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length() - 1];
+ bool enabled = preview ? mod.show_viewport() : mod.show_render();
- if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_boolean_get(&cobj, "use_adaptive_subdivision")) {
- BL::SubsurfModifier subsurf(mod);
+ if (enabled && mod.type() == BL::Modifier::type_SUBSURF &&
+ RNA_boolean_get(&cobj, "use_adaptive_subdivision")) {
+ BL::SubsurfModifier subsurf(mod);
- if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
- return Mesh::SUBDIVISION_CATMULL_CLARK;
- }
- else {
- return Mesh::SUBDIVISION_LINEAR;
- }
- }
- }
+ if (subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
+ return Mesh::SUBDIVISION_CATMULL_CLARK;
+ }
+ else {
+ return Mesh::SUBDIVISION_LINEAR;
+ }
+ }
+ }
- return Mesh::SUBDIVISION_NONE;
+ return Mesh::SUBDIVISION_NONE;
}
/* ID Map
@@ -600,144 +581,143 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object& b_ob, bo
* Utility class to keep in sync with blender data.
* Used for objects, meshes, lights and shaders. */
-template<typename K, typename T>
-class id_map {
-public:
- id_map(vector<T*> *scene_data_)
- {
- scene_data = scene_data_;
- }
-
- T *find(const BL::ID& id)
- {
- return find(id.ptr.id.data);
- }
-
- T *find(const K& key)
- {
- if(b_map.find(key) != b_map.end()) {
- T *data = b_map[key];
- return data;
- }
-
- return NULL;
- }
-
- void set_recalc(const BL::ID& id)
- {
- b_recalc.insert(id.ptr.data);
- }
-
- void set_recalc(void *id_ptr)
- {
- b_recalc.insert(id_ptr);
- }
-
- bool has_recalc()
- {
- return !(b_recalc.empty());
- }
-
- void pre_sync()
- {
- used_set.clear();
- }
-
- bool sync(T **r_data, const BL::ID& id)
- {
- return sync(r_data, id, id, id.ptr.id.data);
- }
-
- bool sync(T **r_data, const BL::ID& id, const BL::ID& parent, const K& key)
- {
- T *data = find(key);
- bool recalc;
-
- if(!data) {
- /* add data if it didn't exist yet */
- data = new T();
- scene_data->push_back(data);
- b_map[key] = data;
- recalc = true;
- }
- else {
- recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
- if(parent.ptr.data)
- recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
- }
-
- used(data);
-
- *r_data = data;
- return recalc;
- }
-
- bool is_used(const K& key)
- {
- T *data = find(key);
- return (data) ? used_set.find(data) != used_set.end() : false;
- }
-
- void used(T *data)
- {
- /* tag data as still in use */
- used_set.insert(data);
- }
-
- void set_default(T *data)
- {
- b_map[NULL] = data;
- }
-
- bool post_sync(bool do_delete = true)
- {
- /* remove unused data */
- vector<T*> new_scene_data;
- typename vector<T*>::iterator it;
- bool deleted = false;
-
- for(it = scene_data->begin(); it != scene_data->end(); it++) {
- T *data = *it;
-
- if(do_delete && used_set.find(data) == used_set.end()) {
- delete data;
- deleted = true;
- }
- else
- new_scene_data.push_back(data);
- }
-
- *scene_data = new_scene_data;
-
- /* update mapping */
- map<K, T*> new_map;
- typedef pair<const K, T*> TMapPair;
- typename map<K, T*>::iterator jt;
-
- for(jt = b_map.begin(); jt != b_map.end(); jt++) {
- TMapPair& pair = *jt;
-
- if(used_set.find(pair.second) != used_set.end())
- new_map[pair.first] = pair.second;
- }
-
- used_set.clear();
- b_recalc.clear();
- b_map = new_map;
-
- return deleted;
- }
-
- const map<K, T*>& key_to_scene_data()
- {
- return b_map;
- }
-
-protected:
- vector<T*> *scene_data;
- map<K, T*> b_map;
- set<T*> used_set;
- set<void*> b_recalc;
+template<typename K, typename T> class id_map {
+ public:
+ id_map(vector<T *> *scene_data_)
+ {
+ scene_data = scene_data_;
+ }
+
+ T *find(const BL::ID &id)
+ {
+ return find(id.ptr.id.data);
+ }
+
+ T *find(const K &key)
+ {
+ if (b_map.find(key) != b_map.end()) {
+ T *data = b_map[key];
+ return data;
+ }
+
+ return NULL;
+ }
+
+ void set_recalc(const BL::ID &id)
+ {
+ b_recalc.insert(id.ptr.data);
+ }
+
+ void set_recalc(void *id_ptr)
+ {
+ b_recalc.insert(id_ptr);
+ }
+
+ bool has_recalc()
+ {
+ return !(b_recalc.empty());
+ }
+
+ void pre_sync()
+ {
+ used_set.clear();
+ }
+
+ bool sync(T **r_data, const BL::ID &id)
+ {
+ return sync(r_data, id, id, id.ptr.id.data);
+ }
+
+ bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key)
+ {
+ T *data = find(key);
+ bool recalc;
+
+ if (!data) {
+ /* add data if it didn't exist yet */
+ data = new T();
+ scene_data->push_back(data);
+ b_map[key] = data;
+ recalc = true;
+ }
+ else {
+ recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
+ if (parent.ptr.data)
+ recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
+ }
+
+ used(data);
+
+ *r_data = data;
+ return recalc;
+ }
+
+ bool is_used(const K &key)
+ {
+ T *data = find(key);
+ return (data) ? used_set.find(data) != used_set.end() : false;
+ }
+
+ void used(T *data)
+ {
+ /* tag data as still in use */
+ used_set.insert(data);
+ }
+
+ void set_default(T *data)
+ {
+ b_map[NULL] = data;
+ }
+
+ bool post_sync(bool do_delete = true)
+ {
+ /* remove unused data */
+ vector<T *> new_scene_data;
+ typename vector<T *>::iterator it;
+ bool deleted = false;
+
+ for (it = scene_data->begin(); it != scene_data->end(); it++) {
+ T *data = *it;
+
+ if (do_delete && used_set.find(data) == used_set.end()) {
+ delete data;
+ deleted = true;
+ }
+ else
+ new_scene_data.push_back(data);
+ }
+
+ *scene_data = new_scene_data;
+
+ /* update mapping */
+ map<K, T *> new_map;
+ typedef pair<const K, T *> TMapPair;
+ typename map<K, T *>::iterator jt;
+
+ for (jt = b_map.begin(); jt != b_map.end(); jt++) {
+ TMapPair &pair = *jt;
+
+ if (used_set.find(pair.second) != used_set.end())
+ new_map[pair.first] = pair.second;
+ }
+
+ used_set.clear();
+ b_recalc.clear();
+ b_map = new_map;
+
+ return deleted;
+ }
+
+ const map<K, T *> &key_to_scene_data()
+ {
+ return b_map;
+ }
+
+ protected:
+ vector<T *> *scene_data;
+ map<K, T *> b_map;
+ set<T *> used_set;
+ set<void *> b_recalc;
};
/* Object Key */
@@ -745,91 +725,95 @@ protected:
enum { OBJECT_PERSISTENT_ID_SIZE = 16 };
struct ObjectKey {
- void *parent;
- int id[OBJECT_PERSISTENT_ID_SIZE];
- void *ob;
-
- ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_)
- : parent(parent_), ob(ob_)
- {
- if(id_)
- memcpy(id, id_, sizeof(id));
- else
- memset(id, 0, sizeof(id));
- }
-
- bool operator<(const ObjectKey& k) const
- {
- if(ob < k.ob) {
- return true;
- }
- else if(ob == k.ob) {
- if(parent < k.parent)
- return true;
- else if(parent == k.parent)
- return memcmp(id, k.id, sizeof(id)) < 0;
- }
-
- return false;
- }
+ void *parent;
+ int id[OBJECT_PERSISTENT_ID_SIZE];
+ void *ob;
+
+ ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_)
+ : parent(parent_), ob(ob_)
+ {
+ if (id_)
+ memcpy(id, id_, sizeof(id));
+ else
+ memset(id, 0, sizeof(id));
+ }
+
+ bool operator<(const ObjectKey &k) const
+ {
+ if (ob < k.ob) {
+ return true;
+ }
+ else if (ob == k.ob) {
+ if (parent < k.parent)
+ return true;
+ else if (parent == k.parent)
+ return memcmp(id, k.id, sizeof(id)) < 0;
+ }
+
+ return false;
+ }
};
/* Particle System Key */
struct ParticleSystemKey {
- void *ob;
- int id[OBJECT_PERSISTENT_ID_SIZE];
-
- ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE])
- : ob(ob_)
- {
- if(id_)
- memcpy(id, id_, sizeof(id));
- else
- memset(id, 0, sizeof(id));
- }
-
- bool operator<(const ParticleSystemKey& k) const
- {
- /* first id is particle index, we don't compare that */
- if(ob < k.ob)
- return true;
- else if(ob == k.ob)
- return memcmp(id+1, k.id+1, sizeof(int)*(OBJECT_PERSISTENT_ID_SIZE-1)) < 0;
-
- return false;
- }
+ void *ob;
+ int id[OBJECT_PERSISTENT_ID_SIZE];
+
+ ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE]) : ob(ob_)
+ {
+ if (id_)
+ memcpy(id, id_, sizeof(id));
+ else
+ memset(id, 0, sizeof(id));
+ }
+
+ bool operator<(const ParticleSystemKey &k) const
+ {
+ /* first id is particle index, we don't compare that */
+ if (ob < k.ob)
+ return true;
+ else if (ob == k.ob)
+ return memcmp(id + 1, k.id + 1, sizeof(int) * (OBJECT_PERSISTENT_ID_SIZE - 1)) < 0;
+
+ return false;
+ }
};
class EdgeMap {
-public:
- EdgeMap() {
- }
-
- void clear() {
- edges_.clear();
- }
-
- void insert(int v0, int v1) {
- get_sorted_verts(v0, v1);
- edges_.insert(std::pair<int, int>(v0, v1));
- }
-
- bool exists(int v0, int v1) {
- get_sorted_verts(v0, v1);
- return edges_.find(std::pair<int, int>(v0, v1)) != edges_.end();
- }
-
-protected:
- void get_sorted_verts(int& v0, int& v1) {
- if(v0 > v1) {
- swap(v0, v1);
- }
- }
-
- set< std::pair<int, int> > edges_;
+ public:
+ EdgeMap()
+ {
+ }
+
+ void clear()
+ {
+ edges_.clear();
+ }
+
+ void insert(int v0, int v1)
+ {
+ get_sorted_verts(v0, v1);
+ edges_.insert(std::pair<int, int>(v0, v1));
+ }
+
+ bool exists(int v0, int v1)
+ {
+ get_sorted_verts(v0, v1);
+ return edges_.find(std::pair<int, int>(v0, v1)) != edges_.end();
+ }
+
+ protected:
+ void get_sorted_verts(int &v0, int &v1)
+ {
+ if (v0 > v1) {
+ swap(v0, v1);
+ }
+ }
+
+ set<std::pair<int, int>> edges_;
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_UTIL_H__ */
+#endif /* __BLENDER_UTIL_H__ */
diff --git a/intern/cycles/bvh/CMakeLists.txt b/intern/cycles/bvh/CMakeLists.txt
index ea31838d816..36bbd937e1a 100644
--- a/intern/cycles/bvh/CMakeLists.txt
+++ b/intern/cycles/bvh/CMakeLists.txt
@@ -1,42 +1,42 @@
set(INC
- ..
+ ..
)
set(INC_SYS
)
set(SRC
- bvh.cpp
- bvh2.cpp
- bvh4.cpp
- bvh8.cpp
- bvh_binning.cpp
- bvh_build.cpp
- bvh_embree.cpp
- bvh_node.cpp
- bvh_sort.cpp
- bvh_split.cpp
- bvh_unaligned.cpp
+ bvh.cpp
+ bvh2.cpp
+ bvh4.cpp
+ bvh8.cpp
+ bvh_binning.cpp
+ bvh_build.cpp
+ bvh_embree.cpp
+ bvh_node.cpp
+ bvh_sort.cpp
+ bvh_split.cpp
+ bvh_unaligned.cpp
)
set(SRC_HEADERS
- bvh.h
- bvh2.h
- bvh4.h
- bvh8.h
- bvh_binning.h
- bvh_build.h
- bvh_embree.h
- bvh_node.h
- bvh_params.h
- bvh_sort.h
- bvh_split.h
- bvh_unaligned.h
+ bvh.h
+ bvh2.h
+ bvh4.h
+ bvh8.h
+ bvh_binning.h
+ bvh_build.h
+ bvh_embree.h
+ bvh_node.h
+ bvh_params.h
+ bvh_sort.h
+ bvh_split.h
+ bvh_unaligned.h
)
set(LIB
- cycles_render
+ cycles_render
)
include_directories(${INC})
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index af012bbf3ac..53c66777928 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -27,7 +27,7 @@
#include "bvh/bvh_node.h"
#ifdef WITH_EMBREE
-#include "bvh/bvh_embree.h"
+# include "bvh/bvh_embree.h"
#endif
#include "util/util_foreach.h"
@@ -40,533 +40,529 @@ CCL_NAMESPACE_BEGIN
const char *bvh_layout_name(BVHLayout layout)
{
- switch(layout) {
- case BVH_LAYOUT_BVH2: return "BVH2";
- case BVH_LAYOUT_BVH4: return "BVH4";
- case BVH_LAYOUT_BVH8: return "BVH8";
- case BVH_LAYOUT_NONE: return "NONE";
- case BVH_LAYOUT_EMBREE: return "EMBREE";
- case BVH_LAYOUT_ALL: return "ALL";
- }
- LOG(DFATAL) << "Unsupported BVH layout was passed.";
- return "";
+ switch (layout) {
+ case BVH_LAYOUT_BVH2:
+ return "BVH2";
+ case BVH_LAYOUT_BVH4:
+ return "BVH4";
+ case BVH_LAYOUT_BVH8:
+ return "BVH8";
+ case BVH_LAYOUT_NONE:
+ return "NONE";
+ case BVH_LAYOUT_EMBREE:
+ return "EMBREE";
+ case BVH_LAYOUT_ALL:
+ return "ALL";
+ }
+ LOG(DFATAL) << "Unsupported BVH layout was passed.";
+ return "";
}
-BVHLayout BVHParams::best_bvh_layout(BVHLayout requested_layout,
- BVHLayoutMask supported_layouts)
+BVHLayout BVHParams::best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask supported_layouts)
{
- const BVHLayoutMask requested_layout_mask = (BVHLayoutMask)requested_layout;
- /* Check whether requested layout is supported, if so -- no need to do
- * any extra computation.
- */
- if(supported_layouts & requested_layout_mask) {
- return requested_layout;
- }
- /* Some bit magic to get widest supported BVH layout. */
- /* This is a mask of supported BVH layouts which are narrower than the
- * requested one.
- */
- const BVHLayoutMask allowed_layouts_mask =
- (supported_layouts & (requested_layout_mask - 1));
- /* We get widest from allowed ones and convert mask to actual layout. */
- const BVHLayoutMask widest_allowed_layout_mask = __bsr(allowed_layouts_mask);
- return (BVHLayout)(1 << widest_allowed_layout_mask);
+ const BVHLayoutMask requested_layout_mask = (BVHLayoutMask)requested_layout;
+ /* Check whether requested layout is supported, if so -- no need to do
+ * any extra computation.
+ */
+ if (supported_layouts & requested_layout_mask) {
+ return requested_layout;
+ }
+ /* Some bit magic to get widest supported BVH layout. */
+ /* This is a mask of supported BVH layouts which are narrower than the
+ * requested one.
+ */
+ const BVHLayoutMask allowed_layouts_mask = (supported_layouts & (requested_layout_mask - 1));
+ /* We get widest from allowed ones and convert mask to actual layout. */
+ const BVHLayoutMask widest_allowed_layout_mask = __bsr(allowed_layouts_mask);
+ return (BVHLayout)(1 << widest_allowed_layout_mask);
}
/* Pack Utility */
-BVHStackEntry::BVHStackEntry(const BVHNode *n, int i)
- : node(n), idx(i)
+BVHStackEntry::BVHStackEntry(const BVHNode *n, int i) : node(n), idx(i)
{
}
int BVHStackEntry::encodeIdx() const
{
- return (node->is_leaf())? ~idx: idx;
+ return (node->is_leaf()) ? ~idx : idx;
}
/* BVH */
-BVH::BVH(const BVHParams& params_, const vector<Object*>& objects_)
-: params(params_), objects(objects_)
+BVH::BVH(const BVHParams &params_, const vector<Object *> &objects_)
+ : params(params_), objects(objects_)
{
}
-BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects)
+BVH *BVH::create(const BVHParams &params, const vector<Object *> &objects)
{
- switch(params.bvh_layout) {
- case BVH_LAYOUT_BVH2:
- return new BVH2(params, objects);
- case BVH_LAYOUT_BVH4:
- return new BVH4(params, objects);
- case BVH_LAYOUT_BVH8:
- return new BVH8(params, objects);
- case BVH_LAYOUT_EMBREE:
+ switch (params.bvh_layout) {
+ case BVH_LAYOUT_BVH2:
+ return new BVH2(params, objects);
+ case BVH_LAYOUT_BVH4:
+ return new BVH4(params, objects);
+ case BVH_LAYOUT_BVH8:
+ return new BVH8(params, objects);
+ case BVH_LAYOUT_EMBREE:
#ifdef WITH_EMBREE
- return new BVHEmbree(params, objects);
+ return new BVHEmbree(params, objects);
#endif
- case BVH_LAYOUT_NONE:
- case BVH_LAYOUT_ALL:
- break;
- }
- LOG(DFATAL) << "Requested unsupported BVH layout.";
- return NULL;
+ case BVH_LAYOUT_NONE:
+ case BVH_LAYOUT_ALL:
+ break;
+ }
+ LOG(DFATAL) << "Requested unsupported BVH layout.";
+ return NULL;
}
/* Building */
-void BVH::build(Progress& progress, Stats*)
+void BVH::build(Progress &progress, Stats *)
{
- progress.set_substatus("Building BVH");
-
- /* build nodes */
- BVHBuild bvh_build(objects,
- pack.prim_type,
- pack.prim_index,
- pack.prim_object,
- pack.prim_time,
- params,
- progress);
- BVHNode *bvh2_root = bvh_build.run();
-
- if(progress.get_cancel()) {
- if(bvh2_root != NULL) {
- bvh2_root->deleteSubtree();
- }
- return;
- }
-
- /* BVH builder returns tree in a binary mode (with two children per inner
- * node. Need to adopt that for a wider BVH implementations. */
- BVHNode *root = widen_children_nodes(bvh2_root);
- if(root != bvh2_root) {
- bvh2_root->deleteSubtree();
- }
-
- if(progress.get_cancel()) {
- if(root != NULL) {
- root->deleteSubtree();
- }
- return;
- }
-
- /* pack triangles */
- progress.set_substatus("Packing BVH triangles and strands");
- pack_primitives();
-
- if(progress.get_cancel()) {
- root->deleteSubtree();
- return;
- }
-
- /* pack nodes */
- progress.set_substatus("Packing BVH nodes");
- pack_nodes(root);
-
- /* free build nodes */
- root->deleteSubtree();
+ progress.set_substatus("Building BVH");
+
+ /* build nodes */
+ BVHBuild bvh_build(objects,
+ pack.prim_type,
+ pack.prim_index,
+ pack.prim_object,
+ pack.prim_time,
+ params,
+ progress);
+ BVHNode *bvh2_root = bvh_build.run();
+
+ if (progress.get_cancel()) {
+ if (bvh2_root != NULL) {
+ bvh2_root->deleteSubtree();
+ }
+ return;
+ }
+
+ /* BVH builder returns tree in a binary mode (with two children per inner
+ * node. Need to adopt that for a wider BVH implementations. */
+ BVHNode *root = widen_children_nodes(bvh2_root);
+ if (root != bvh2_root) {
+ bvh2_root->deleteSubtree();
+ }
+
+ if (progress.get_cancel()) {
+ if (root != NULL) {
+ root->deleteSubtree();
+ }
+ return;
+ }
+
+ /* pack triangles */
+ progress.set_substatus("Packing BVH triangles and strands");
+ pack_primitives();
+
+ if (progress.get_cancel()) {
+ root->deleteSubtree();
+ return;
+ }
+
+ /* pack nodes */
+ progress.set_substatus("Packing BVH nodes");
+ pack_nodes(root);
+
+ /* free build nodes */
+ root->deleteSubtree();
}
/* Refitting */
-void BVH::refit(Progress& progress)
+void BVH::refit(Progress &progress)
{
- progress.set_substatus("Packing BVH primitives");
- pack_primitives();
+ progress.set_substatus("Packing BVH primitives");
+ pack_primitives();
- if(progress.get_cancel()) return;
+ if (progress.get_cancel())
+ return;
- progress.set_substatus("Refitting BVH nodes");
- refit_nodes();
+ progress.set_substatus("Refitting BVH nodes");
+ refit_nodes();
}
-void BVH::refit_primitives(int start, int end, BoundBox& bbox, uint& visibility)
+void BVH::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility)
{
- /* Refit range of primitives. */
- for(int prim = start; prim < end; prim++) {
- int pidx = pack.prim_index[prim];
- int tob = pack.prim_object[prim];
- Object *ob = objects[tob];
-
- if(pidx == -1) {
- /* Object instance. */
- bbox.grow(ob->bounds);
- }
- else {
- /* Primitives. */
- const Mesh *mesh = ob->mesh;
-
- if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
- /* Curves. */
- int str_offset = (params.top_level)? mesh->curve_offset: 0;
- Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
- int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
-
- curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
-
- visibility |= PATH_RAY_CURVE;
-
- /* Motion curves. */
- if(mesh->use_motion_blur) {
- Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr) {
- size_t mesh_size = mesh->curve_keys.size();
- size_t steps = mesh->motion_steps - 1;
- float3 *key_steps = attr->data_float3();
-
- for(size_t i = 0; i < steps; i++)
- curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
- }
- }
- }
- else {
- /* Triangles. */
- int tri_offset = (params.top_level)? mesh->tri_offset: 0;
- Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
- const float3 *vpos = &mesh->verts[0];
-
- triangle.bounds_grow(vpos, bbox);
-
- /* Motion triangles. */
- if(mesh->use_motion_blur) {
- Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr) {
- size_t mesh_size = mesh->verts.size();
- size_t steps = mesh->motion_steps - 1;
- float3 *vert_steps = attr->data_float3();
-
- for(size_t i = 0; i < steps; i++)
- triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
- }
- }
- }
- }
- visibility |= ob->visibility_for_tracing();
-
- }
+ /* Refit range of primitives. */
+ for (int prim = start; prim < end; prim++) {
+ int pidx = pack.prim_index[prim];
+ int tob = pack.prim_object[prim];
+ Object *ob = objects[tob];
+
+ if (pidx == -1) {
+ /* Object instance. */
+ bbox.grow(ob->bounds);
+ }
+ else {
+ /* Primitives. */
+ const Mesh *mesh = ob->mesh;
+
+ if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
+ /* Curves. */
+ int str_offset = (params.top_level) ? mesh->curve_offset : 0;
+ Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
+ int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
+
+ curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
+
+ visibility |= PATH_RAY_CURVE;
+
+ /* Motion curves. */
+ if (mesh->use_motion_blur) {
+ Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr) {
+ size_t mesh_size = mesh->curve_keys.size();
+ size_t steps = mesh->motion_steps - 1;
+ float3 *key_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps; i++)
+ curve.bounds_grow(k, key_steps + i * mesh_size, &mesh->curve_radius[0], bbox);
+ }
+ }
+ }
+ else {
+ /* Triangles. */
+ int tri_offset = (params.top_level) ? mesh->tri_offset : 0;
+ Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
+ const float3 *vpos = &mesh->verts[0];
+
+ triangle.bounds_grow(vpos, bbox);
+
+ /* Motion triangles. */
+ if (mesh->use_motion_blur) {
+ Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr) {
+ size_t mesh_size = mesh->verts.size();
+ size_t steps = mesh->motion_steps - 1;
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps; i++)
+ triangle.bounds_grow(vert_steps + i * mesh_size, bbox);
+ }
+ }
+ }
+ }
+ visibility |= ob->visibility_for_tracing();
+ }
}
/* Triangles */
void BVH::pack_triangle(int idx, float4 tri_verts[3])
{
- int tob = pack.prim_object[idx];
- assert(tob >= 0 && tob < objects.size());
- const Mesh *mesh = objects[tob]->mesh;
-
- int tidx = pack.prim_index[idx];
- Mesh::Triangle t = mesh->get_triangle(tidx);
- const float3 *vpos = &mesh->verts[0];
- float3 v0 = vpos[t.v[0]];
- float3 v1 = vpos[t.v[1]];
- float3 v2 = vpos[t.v[2]];
-
- tri_verts[0] = float3_to_float4(v0);
- tri_verts[1] = float3_to_float4(v1);
- tri_verts[2] = float3_to_float4(v2);
+ int tob = pack.prim_object[idx];
+ assert(tob >= 0 && tob < objects.size());
+ const Mesh *mesh = objects[tob]->mesh;
+
+ int tidx = pack.prim_index[idx];
+ Mesh::Triangle t = mesh->get_triangle(tidx);
+ const float3 *vpos = &mesh->verts[0];
+ float3 v0 = vpos[t.v[0]];
+ float3 v1 = vpos[t.v[1]];
+ float3 v2 = vpos[t.v[2]];
+
+ tri_verts[0] = float3_to_float4(v0);
+ tri_verts[1] = float3_to_float4(v1);
+ tri_verts[2] = float3_to_float4(v2);
}
void BVH::pack_primitives()
{
- const size_t tidx_size = pack.prim_index.size();
- size_t num_prim_triangles = 0;
- /* Count number of triangles primitives in BVH. */
- for(unsigned int i = 0; i < tidx_size; i++) {
- if((pack.prim_index[i] != -1)) {
- if((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
- ++num_prim_triangles;
- }
- }
- }
- /* Reserve size for arrays. */
- pack.prim_tri_index.clear();
- pack.prim_tri_index.resize(tidx_size);
- pack.prim_tri_verts.clear();
- pack.prim_tri_verts.resize(num_prim_triangles * 3);
- pack.prim_visibility.clear();
- pack.prim_visibility.resize(tidx_size);
- /* Fill in all the arrays. */
- size_t prim_triangle_index = 0;
- for(unsigned int i = 0; i < tidx_size; i++) {
- if(pack.prim_index[i] != -1) {
- int tob = pack.prim_object[i];
- Object *ob = objects[tob];
- if((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
- pack_triangle(i, (float4*)&pack.prim_tri_verts[3 * prim_triangle_index]);
- pack.prim_tri_index[i] = 3 * prim_triangle_index;
- ++prim_triangle_index;
- }
- else {
- pack.prim_tri_index[i] = -1;
- }
- pack.prim_visibility[i] = ob->visibility_for_tracing();
- if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
- pack.prim_visibility[i] |= PATH_RAY_CURVE;
- }
- }
- else {
- pack.prim_tri_index[i] = -1;
- pack.prim_visibility[i] = 0;
- }
- }
+ const size_t tidx_size = pack.prim_index.size();
+ size_t num_prim_triangles = 0;
+ /* Count number of triangles primitives in BVH. */
+ for (unsigned int i = 0; i < tidx_size; i++) {
+ if ((pack.prim_index[i] != -1)) {
+ if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
+ ++num_prim_triangles;
+ }
+ }
+ }
+ /* Reserve size for arrays. */
+ pack.prim_tri_index.clear();
+ pack.prim_tri_index.resize(tidx_size);
+ pack.prim_tri_verts.clear();
+ pack.prim_tri_verts.resize(num_prim_triangles * 3);
+ pack.prim_visibility.clear();
+ pack.prim_visibility.resize(tidx_size);
+ /* Fill in all the arrays. */
+ size_t prim_triangle_index = 0;
+ for (unsigned int i = 0; i < tidx_size; i++) {
+ if (pack.prim_index[i] != -1) {
+ int tob = pack.prim_object[i];
+ Object *ob = objects[tob];
+ if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
+ pack_triangle(i, (float4 *)&pack.prim_tri_verts[3 * prim_triangle_index]);
+ pack.prim_tri_index[i] = 3 * prim_triangle_index;
+ ++prim_triangle_index;
+ }
+ else {
+ pack.prim_tri_index[i] = -1;
+ }
+ pack.prim_visibility[i] = ob->visibility_for_tracing();
+ if (pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
+ pack.prim_visibility[i] |= PATH_RAY_CURVE;
+ }
+ }
+ else {
+ pack.prim_tri_index[i] = -1;
+ pack.prim_visibility[i] = 0;
+ }
+ }
}
/* Pack Instances */
void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
{
- /* The BVH's for instances are built separately, but for traversal all
- * BVH's are stored in global arrays. This function merges them into the
- * top level BVH, adjusting indexes and offsets where appropriate.
- */
- const bool use_qbvh = (params.bvh_layout == BVH_LAYOUT_BVH4);
- const bool use_obvh = (params.bvh_layout == BVH_LAYOUT_BVH8);
-
- /* Adjust primitive index to point to the triangle in the global array, for
- * meshes with transform applied and already in the top level BVH.
- */
- for(size_t i = 0; i < pack.prim_index.size(); i++)
- if(pack.prim_index[i] != -1) {
- if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
- else
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
- }
-
- /* track offsets of instanced BVH data in global array */
- size_t prim_offset = pack.prim_index.size();
- size_t nodes_offset = nodes_size;
- size_t nodes_leaf_offset = leaf_nodes_size;
-
- /* clear array that gives the node indexes for instanced objects */
- pack.object_node.clear();
-
- /* reserve */
- size_t prim_index_size = pack.prim_index.size();
- size_t prim_tri_verts_size = pack.prim_tri_verts.size();
-
- size_t pack_prim_index_offset = prim_index_size;
- size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
- size_t pack_nodes_offset = nodes_size;
- size_t pack_leaf_nodes_offset = leaf_nodes_size;
- size_t object_offset = 0;
-
- map<Mesh*, int> mesh_map;
-
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
- BVH *bvh = mesh->bvh;
-
- if(mesh->need_build_bvh()) {
- if(mesh_map.find(mesh) == mesh_map.end()) {
- prim_index_size += bvh->pack.prim_index.size();
- prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
- nodes_size += bvh->pack.nodes.size();
- leaf_nodes_size += bvh->pack.leaf_nodes.size();
-
- mesh_map[mesh] = 1;
- }
- }
- }
-
- mesh_map.clear();
-
- pack.prim_index.resize(prim_index_size);
- pack.prim_type.resize(prim_index_size);
- pack.prim_object.resize(prim_index_size);
- pack.prim_visibility.resize(prim_index_size);
- pack.prim_tri_verts.resize(prim_tri_verts_size);
- pack.prim_tri_index.resize(prim_index_size);
- pack.nodes.resize(nodes_size);
- pack.leaf_nodes.resize(leaf_nodes_size);
- pack.object_node.resize(objects.size());
-
- if(params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0) {
- pack.prim_time.resize(prim_index_size);
- }
-
- int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
- int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
- int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
- uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
- float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size())? &pack.prim_tri_verts[0]: NULL;
- uint *pack_prim_tri_index = (pack.prim_tri_index.size())? &pack.prim_tri_index[0]: NULL;
- int4 *pack_nodes = (pack.nodes.size())? &pack.nodes[0]: NULL;
- int4 *pack_leaf_nodes = (pack.leaf_nodes.size())? &pack.leaf_nodes[0]: NULL;
- float2 *pack_prim_time = (pack.prim_time.size())? &pack.prim_time[0]: NULL;
-
- /* merge */
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
-
- /* We assume that if mesh doesn't need own BVH it was already included
- * into a top-level BVH and no packing here is needed.
- */
- if(!mesh->need_build_bvh()) {
- pack.object_node[object_offset++] = 0;
- continue;
- }
-
- /* if mesh already added once, don't add it again, but used set
- * node offset for this object */
- map<Mesh*, int>::iterator it = mesh_map.find(mesh);
-
- if(mesh_map.find(mesh) != mesh_map.end()) {
- int noffset = it->second;
- pack.object_node[object_offset++] = noffset;
- continue;
- }
-
- BVH *bvh = mesh->bvh;
-
- int noffset = nodes_offset;
- int noffset_leaf = nodes_leaf_offset;
- int mesh_tri_offset = mesh->tri_offset;
- int mesh_curve_offset = mesh->curve_offset;
-
- /* fill in node indexes for instances */
- if(bvh->pack.root_index == -1)
- pack.object_node[object_offset++] = -noffset_leaf-1;
- else
- pack.object_node[object_offset++] = noffset;
-
- mesh_map[mesh] = pack.object_node[object_offset-1];
-
- /* merge primitive, object and triangle indexes */
- if(bvh->pack.prim_index.size()) {
- size_t bvh_prim_index_size = bvh->pack.prim_index.size();
- int *bvh_prim_index = &bvh->pack.prim_index[0];
- int *bvh_prim_type = &bvh->pack.prim_type[0];
- uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
- uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
- float2 *bvh_prim_time = bvh->pack.prim_time.size()? &bvh->pack.prim_time[0]: NULL;
-
- for(size_t i = 0; i < bvh_prim_index_size; i++) {
- if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
- pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
- pack_prim_tri_index[pack_prim_index_offset] = -1;
- }
- else {
- pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
- pack_prim_tri_index[pack_prim_index_offset] =
- bvh_prim_tri_index[i] + pack_prim_tri_verts_offset;
- }
-
- pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
- pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
- pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
- if(bvh_prim_time != NULL) {
- pack_prim_time[pack_prim_index_offset] = bvh_prim_time[i];
- }
- pack_prim_index_offset++;
- }
- }
-
- /* Merge triangle vertices data. */
- if(bvh->pack.prim_tri_verts.size()) {
- const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
- memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
- &bvh->pack.prim_tri_verts[0],
- prim_tri_size*sizeof(float4));
- pack_prim_tri_verts_offset += prim_tri_size;
- }
-
- /* merge nodes */
- if(bvh->pack.leaf_nodes.size()) {
- int4 *leaf_nodes_offset = &bvh->pack.leaf_nodes[0];
- size_t leaf_nodes_offset_size = bvh->pack.leaf_nodes.size();
- for(size_t i = 0, j = 0;
- i < leaf_nodes_offset_size;
- i += BVH_NODE_LEAF_SIZE, j++)
- {
- int4 data = leaf_nodes_offset[i];
- data.x += prim_offset;
- data.y += prim_offset;
- pack_leaf_nodes[pack_leaf_nodes_offset] = data;
- for(int j = 1; j < BVH_NODE_LEAF_SIZE; ++j) {
- pack_leaf_nodes[pack_leaf_nodes_offset + j] = leaf_nodes_offset[i + j];
- }
- pack_leaf_nodes_offset += BVH_NODE_LEAF_SIZE;
- }
- }
-
- if(bvh->pack.nodes.size()) {
- int4 *bvh_nodes = &bvh->pack.nodes[0];
- size_t bvh_nodes_size = bvh->pack.nodes.size();
-
- for(size_t i = 0, j = 0; i < bvh_nodes_size; j++) {
- size_t nsize, nsize_bbox;
- if(bvh_nodes[i].x & PATH_RAY_NODE_UNALIGNED) {
- if(use_obvh) {
- nsize = BVH_UNALIGNED_ONODE_SIZE;
- nsize_bbox = BVH_UNALIGNED_ONODE_SIZE-1;
- }
- else {
- nsize = use_qbvh
- ? BVH_UNALIGNED_QNODE_SIZE
- : BVH_UNALIGNED_NODE_SIZE;
- nsize_bbox = (use_qbvh) ? BVH_UNALIGNED_QNODE_SIZE-1 : 0;
- }
- }
- else {
- if(use_obvh) {
- nsize = BVH_ONODE_SIZE;
- nsize_bbox = BVH_ONODE_SIZE-1;
- }
- else {
- nsize = (use_qbvh)? BVH_QNODE_SIZE: BVH_NODE_SIZE;
- nsize_bbox = (use_qbvh)? BVH_QNODE_SIZE-1 : 0;
- }
- }
-
- memcpy(pack_nodes + pack_nodes_offset,
- bvh_nodes + i,
- nsize_bbox*sizeof(int4));
-
- /* Modify offsets into arrays */
- int4 data = bvh_nodes[i + nsize_bbox];
- int4 data1 = bvh_nodes[i + nsize_bbox-1];
- if(use_obvh) {
- data.z += (data.z < 0) ? -noffset_leaf : noffset;
- data.w += (data.w < 0) ? -noffset_leaf : noffset;
- data.x += (data.x < 0) ? -noffset_leaf : noffset;
- data.y += (data.y < 0) ? -noffset_leaf : noffset;
- data1.z += (data1.z < 0) ? -noffset_leaf : noffset;
- data1.w += (data1.w < 0) ? -noffset_leaf : noffset;
- data1.x += (data1.x < 0) ? -noffset_leaf : noffset;
- data1.y += (data1.y < 0) ? -noffset_leaf : noffset;
- }
- else {
- data.z += (data.z < 0) ? -noffset_leaf : noffset;
- data.w += (data.w < 0) ? -noffset_leaf : noffset;
- if(use_qbvh) {
- data.x += (data.x < 0)? -noffset_leaf: noffset;
- data.y += (data.y < 0)? -noffset_leaf: noffset;
- }
- }
- pack_nodes[pack_nodes_offset + nsize_bbox] = data;
- if(use_obvh) {
- pack_nodes[pack_nodes_offset + nsize_bbox - 1] = data1;
- }
-
- /* Usually this copies nothing, but we better
- * be prepared for possible node size extension.
- */
- memcpy(&pack_nodes[pack_nodes_offset + nsize_bbox+1],
- &bvh_nodes[i + nsize_bbox+1],
- sizeof(int4) * (nsize - (nsize_bbox+1)));
-
- pack_nodes_offset += nsize;
- i += nsize;
- }
- }
-
- nodes_offset += bvh->pack.nodes.size();
- nodes_leaf_offset += bvh->pack.leaf_nodes.size();
- prim_offset += bvh->pack.prim_index.size();
- }
+ /* The BVH's for instances are built separately, but for traversal all
+ * BVH's are stored in global arrays. This function merges them into the
+ * top level BVH, adjusting indexes and offsets where appropriate.
+ */
+ const bool use_qbvh = (params.bvh_layout == BVH_LAYOUT_BVH4);
+ const bool use_obvh = (params.bvh_layout == BVH_LAYOUT_BVH8);
+
+ /* Adjust primitive index to point to the triangle in the global array, for
+ * meshes with transform applied and already in the top level BVH.
+ */
+ for (size_t i = 0; i < pack.prim_index.size(); i++)
+ if (pack.prim_index[i] != -1) {
+ if (pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
+ else
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ }
+
+ /* track offsets of instanced BVH data in global array */
+ size_t prim_offset = pack.prim_index.size();
+ size_t nodes_offset = nodes_size;
+ size_t nodes_leaf_offset = leaf_nodes_size;
+
+ /* clear array that gives the node indexes for instanced objects */
+ pack.object_node.clear();
+
+ /* reserve */
+ size_t prim_index_size = pack.prim_index.size();
+ size_t prim_tri_verts_size = pack.prim_tri_verts.size();
+
+ size_t pack_prim_index_offset = prim_index_size;
+ size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
+ size_t pack_nodes_offset = nodes_size;
+ size_t pack_leaf_nodes_offset = leaf_nodes_size;
+ size_t object_offset = 0;
+
+ map<Mesh *, int> mesh_map;
+
+ foreach (Object *ob, objects) {
+ Mesh *mesh = ob->mesh;
+ BVH *bvh = mesh->bvh;
+
+ if (mesh->need_build_bvh()) {
+ if (mesh_map.find(mesh) == mesh_map.end()) {
+ prim_index_size += bvh->pack.prim_index.size();
+ prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
+ nodes_size += bvh->pack.nodes.size();
+ leaf_nodes_size += bvh->pack.leaf_nodes.size();
+
+ mesh_map[mesh] = 1;
+ }
+ }
+ }
+
+ mesh_map.clear();
+
+ pack.prim_index.resize(prim_index_size);
+ pack.prim_type.resize(prim_index_size);
+ pack.prim_object.resize(prim_index_size);
+ pack.prim_visibility.resize(prim_index_size);
+ pack.prim_tri_verts.resize(prim_tri_verts_size);
+ pack.prim_tri_index.resize(prim_index_size);
+ pack.nodes.resize(nodes_size);
+ pack.leaf_nodes.resize(leaf_nodes_size);
+ pack.object_node.resize(objects.size());
+
+ if (params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0) {
+ pack.prim_time.resize(prim_index_size);
+ }
+
+ int *pack_prim_index = (pack.prim_index.size()) ? &pack.prim_index[0] : NULL;
+ int *pack_prim_type = (pack.prim_type.size()) ? &pack.prim_type[0] : NULL;
+ int *pack_prim_object = (pack.prim_object.size()) ? &pack.prim_object[0] : NULL;
+ uint *pack_prim_visibility = (pack.prim_visibility.size()) ? &pack.prim_visibility[0] : NULL;
+ float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size()) ? &pack.prim_tri_verts[0] : NULL;
+ uint *pack_prim_tri_index = (pack.prim_tri_index.size()) ? &pack.prim_tri_index[0] : NULL;
+ int4 *pack_nodes = (pack.nodes.size()) ? &pack.nodes[0] : NULL;
+ int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL;
+ float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL;
+
+ /* merge */
+ foreach (Object *ob, objects) {
+ Mesh *mesh = ob->mesh;
+
+ /* We assume that if mesh doesn't need own BVH it was already included
+ * into a top-level BVH and no packing here is needed.
+ */
+ if (!mesh->need_build_bvh()) {
+ pack.object_node[object_offset++] = 0;
+ continue;
+ }
+
+ /* if mesh already added once, don't add it again, but used set
+ * node offset for this object */
+ map<Mesh *, int>::iterator it = mesh_map.find(mesh);
+
+ if (mesh_map.find(mesh) != mesh_map.end()) {
+ int noffset = it->second;
+ pack.object_node[object_offset++] = noffset;
+ continue;
+ }
+
+ BVH *bvh = mesh->bvh;
+
+ int noffset = nodes_offset;
+ int noffset_leaf = nodes_leaf_offset;
+ int mesh_tri_offset = mesh->tri_offset;
+ int mesh_curve_offset = mesh->curve_offset;
+
+ /* fill in node indexes for instances */
+ if (bvh->pack.root_index == -1)
+ pack.object_node[object_offset++] = -noffset_leaf - 1;
+ else
+ pack.object_node[object_offset++] = noffset;
+
+ mesh_map[mesh] = pack.object_node[object_offset - 1];
+
+ /* merge primitive, object and triangle indexes */
+ if (bvh->pack.prim_index.size()) {
+ size_t bvh_prim_index_size = bvh->pack.prim_index.size();
+ int *bvh_prim_index = &bvh->pack.prim_index[0];
+ int *bvh_prim_type = &bvh->pack.prim_type[0];
+ uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
+ uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
+ float2 *bvh_prim_time = bvh->pack.prim_time.size() ? &bvh->pack.prim_time[0] : NULL;
+
+ for (size_t i = 0; i < bvh_prim_index_size; i++) {
+ if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
+ pack_prim_tri_index[pack_prim_index_offset] = -1;
+ }
+ else {
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
+ pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] +
+ pack_prim_tri_verts_offset;
+ }
+
+ pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
+ pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
+ pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
+ if (bvh_prim_time != NULL) {
+ pack_prim_time[pack_prim_index_offset] = bvh_prim_time[i];
+ }
+ pack_prim_index_offset++;
+ }
+ }
+
+ /* Merge triangle vertices data. */
+ if (bvh->pack.prim_tri_verts.size()) {
+ const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
+ memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
+ &bvh->pack.prim_tri_verts[0],
+ prim_tri_size * sizeof(float4));
+ pack_prim_tri_verts_offset += prim_tri_size;
+ }
+
+ /* merge nodes */
+ if (bvh->pack.leaf_nodes.size()) {
+ int4 *leaf_nodes_offset = &bvh->pack.leaf_nodes[0];
+ size_t leaf_nodes_offset_size = bvh->pack.leaf_nodes.size();
+ for (size_t i = 0, j = 0; i < leaf_nodes_offset_size; i += BVH_NODE_LEAF_SIZE, j++) {
+ int4 data = leaf_nodes_offset[i];
+ data.x += prim_offset;
+ data.y += prim_offset;
+ pack_leaf_nodes[pack_leaf_nodes_offset] = data;
+ for (int j = 1; j < BVH_NODE_LEAF_SIZE; ++j) {
+ pack_leaf_nodes[pack_leaf_nodes_offset + j] = leaf_nodes_offset[i + j];
+ }
+ pack_leaf_nodes_offset += BVH_NODE_LEAF_SIZE;
+ }
+ }
+
+ if (bvh->pack.nodes.size()) {
+ int4 *bvh_nodes = &bvh->pack.nodes[0];
+ size_t bvh_nodes_size = bvh->pack.nodes.size();
+
+ for (size_t i = 0, j = 0; i < bvh_nodes_size; j++) {
+ size_t nsize, nsize_bbox;
+ if (bvh_nodes[i].x & PATH_RAY_NODE_UNALIGNED) {
+ if (use_obvh) {
+ nsize = BVH_UNALIGNED_ONODE_SIZE;
+ nsize_bbox = BVH_UNALIGNED_ONODE_SIZE - 1;
+ }
+ else {
+ nsize = use_qbvh ? BVH_UNALIGNED_QNODE_SIZE : BVH_UNALIGNED_NODE_SIZE;
+ nsize_bbox = (use_qbvh) ? BVH_UNALIGNED_QNODE_SIZE - 1 : 0;
+ }
+ }
+ else {
+ if (use_obvh) {
+ nsize = BVH_ONODE_SIZE;
+ nsize_bbox = BVH_ONODE_SIZE - 1;
+ }
+ else {
+ nsize = (use_qbvh) ? BVH_QNODE_SIZE : BVH_NODE_SIZE;
+ nsize_bbox = (use_qbvh) ? BVH_QNODE_SIZE - 1 : 0;
+ }
+ }
+
+ memcpy(pack_nodes + pack_nodes_offset, bvh_nodes + i, nsize_bbox * sizeof(int4));
+
+ /* Modify offsets into arrays */
+ int4 data = bvh_nodes[i + nsize_bbox];
+ int4 data1 = bvh_nodes[i + nsize_bbox - 1];
+ if (use_obvh) {
+ data.z += (data.z < 0) ? -noffset_leaf : noffset;
+ data.w += (data.w < 0) ? -noffset_leaf : noffset;
+ data.x += (data.x < 0) ? -noffset_leaf : noffset;
+ data.y += (data.y < 0) ? -noffset_leaf : noffset;
+ data1.z += (data1.z < 0) ? -noffset_leaf : noffset;
+ data1.w += (data1.w < 0) ? -noffset_leaf : noffset;
+ data1.x += (data1.x < 0) ? -noffset_leaf : noffset;
+ data1.y += (data1.y < 0) ? -noffset_leaf : noffset;
+ }
+ else {
+ data.z += (data.z < 0) ? -noffset_leaf : noffset;
+ data.w += (data.w < 0) ? -noffset_leaf : noffset;
+ if (use_qbvh) {
+ data.x += (data.x < 0) ? -noffset_leaf : noffset;
+ data.y += (data.y < 0) ? -noffset_leaf : noffset;
+ }
+ }
+ pack_nodes[pack_nodes_offset + nsize_bbox] = data;
+ if (use_obvh) {
+ pack_nodes[pack_nodes_offset + nsize_bbox - 1] = data1;
+ }
+
+ /* Usually this copies nothing, but we better
+ * be prepared for possible node size extension.
+ */
+ memcpy(&pack_nodes[pack_nodes_offset + nsize_bbox + 1],
+ &bvh_nodes[i + nsize_bbox + 1],
+ sizeof(int4) * (nsize - (nsize_bbox + 1)));
+
+ pack_nodes_offset += nsize;
+ i += nsize;
+ }
+ }
+
+ nodes_offset += bvh->pack.nodes.size();
+ nodes_leaf_offset += bvh->pack.leaf_nodes.size();
+ prim_offset += bvh->pack.prim_index.size();
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 33a069eeaf5..edce3ca6f2a 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -34,96 +34,92 @@ class LeafNode;
class Object;
class Progress;
-#define BVH_ALIGN 4096
+#define BVH_ALIGN 4096
#define TRI_NODE_SIZE 3
/* Packed BVH
*
* BVH stored as it will be used for traversal on the rendering device. */
struct PackedBVH {
- /* BVH nodes storage, one node is 4x int4, and contains two bounding boxes,
- * and child, triangle or object indexes depending on the node type */
- array<int4> nodes;
- /* BVH leaf nodes storage. */
- array<int4> leaf_nodes;
- /* object index to BVH node index mapping for instances */
- array<int> object_node;
- /* Mapping from primitive index to index in triangle array. */
- array<uint> prim_tri_index;
- /* Continuous storage of triangle vertices. */
- array<float4> prim_tri_verts;
- /* primitive type - triangle or strand */
- array<int> prim_type;
- /* visibility visibilitys for primitives */
- array<uint> prim_visibility;
- /* mapping from BVH primitive index to true primitive index, as primitives
- * may be duplicated due to spatial splits. -1 for instances. */
- array<int> prim_index;
- /* mapping from BVH primitive index, to the object id of that primitive. */
- array<int> prim_object;
- /* Time range of BVH primitive. */
- array<float2> prim_time;
-
- /* index of the root node. */
- int root_index;
-
- PackedBVH()
- {
- root_index = 0;
- }
+ /* BVH nodes storage, one node is 4x int4, and contains two bounding boxes,
+ * and child, triangle or object indexes depending on the node type */
+ array<int4> nodes;
+ /* BVH leaf nodes storage. */
+ array<int4> leaf_nodes;
+ /* object index to BVH node index mapping for instances */
+ array<int> object_node;
+ /* Mapping from primitive index to index in triangle array. */
+ array<uint> prim_tri_index;
+ /* Continuous storage of triangle vertices. */
+ array<float4> prim_tri_verts;
+ /* primitive type - triangle or strand */
+ array<int> prim_type;
+ /* visibility visibilitys for primitives */
+ array<uint> prim_visibility;
+ /* mapping from BVH primitive index to true primitive index, as primitives
+ * may be duplicated due to spatial splits. -1 for instances. */
+ array<int> prim_index;
+ /* mapping from BVH primitive index, to the object id of that primitive. */
+ array<int> prim_object;
+ /* Time range of BVH primitive. */
+ array<float2> prim_time;
+
+ /* index of the root node. */
+ int root_index;
+
+ PackedBVH()
+ {
+ root_index = 0;
+ }
};
-enum BVH_TYPE {
- bvh2,
- bvh4,
- bvh8
-};
+enum BVH_TYPE { bvh2, bvh4, bvh8 };
/* BVH */
-class BVH
-{
-public:
- PackedBVH pack;
- BVHParams params;
- vector<Object*> objects;
+class BVH {
+ public:
+ PackedBVH pack;
+ BVHParams params;
+ vector<Object *> objects;
- static BVH *create(const BVHParams& params, const vector<Object*>& objects);
- virtual ~BVH() {}
+ static BVH *create(const BVHParams &params, const vector<Object *> &objects);
+ virtual ~BVH()
+ {
+ }
- virtual void build(Progress& progress, Stats *stats=NULL);
- void refit(Progress& progress);
+ virtual void build(Progress &progress, Stats *stats = NULL);
+ void refit(Progress &progress);
-protected:
- BVH(const BVHParams& params, const vector<Object*>& objects);
+ protected:
+ BVH(const BVHParams &params, const vector<Object *> &objects);
- /* Refit range of primitives. */
- void refit_primitives(int start, int end, BoundBox& bbox, uint& visibility);
+ /* Refit range of primitives. */
+ void refit_primitives(int start, int end, BoundBox &bbox, uint &visibility);
- /* triangles and strands */
- void pack_primitives();
- void pack_triangle(int idx, float4 storage[3]);
+ /* triangles and strands */
+ void pack_primitives();
+ void pack_triangle(int idx, float4 storage[3]);
- /* merge instance BVH's */
- void pack_instances(size_t nodes_size, size_t leaf_nodes_size);
+ /* merge instance BVH's */
+ void pack_instances(size_t nodes_size, size_t leaf_nodes_size);
- /* for subclasses to implement */
- virtual void pack_nodes(const BVHNode *root) = 0;
- virtual void refit_nodes() = 0;
+ /* for subclasses to implement */
+ virtual void pack_nodes(const BVHNode *root) = 0;
+ virtual void refit_nodes() = 0;
- virtual BVHNode *widen_children_nodes(const BVHNode *root) = 0;
+ virtual BVHNode *widen_children_nodes(const BVHNode *root) = 0;
};
/* Pack Utility */
-struct BVHStackEntry
-{
- const BVHNode *node;
- int idx;
+struct BVHStackEntry {
+ const BVHNode *node;
+ int idx;
- BVHStackEntry(const BVHNode *n = 0, int i = 0);
- int encodeIdx() const;
+ BVHStackEntry(const BVHNode *n = 0, int i = 0);
+ int encodeIdx() const;
};
CCL_NAMESPACE_END
-#endif /* __BVH_H__ */
+#endif /* __BVH_H__ */
diff --git a/intern/cycles/bvh/bvh2.cpp b/intern/cycles/bvh/bvh2.cpp
index e5dc4e6b1a8..f419d413ef6 100644
--- a/intern/cycles/bvh/bvh2.cpp
+++ b/intern/cycles/bvh/bvh2.cpp
@@ -25,276 +25,268 @@
CCL_NAMESPACE_BEGIN
-BVH2::BVH2(const BVHParams& params_, const vector<Object*>& objects_)
-: BVH(params_, objects_)
+BVH2::BVH2(const BVHParams &params_, const vector<Object *> &objects_) : BVH(params_, objects_)
{
}
BVHNode *BVH2::widen_children_nodes(const BVHNode *root)
{
- return const_cast<BVHNode *>(root);
+ return const_cast<BVHNode *>(root);
}
-void BVH2::pack_leaf(const BVHStackEntry& e,
- const LeafNode *leaf)
+void BVH2::pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
{
- assert(e.idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
- float4 data[BVH_NODE_LEAF_SIZE];
- memset(data, 0, sizeof(data));
- if(leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
- /* object */
- data[0].x = __int_as_float(~(leaf->lo));
- data[0].y = __int_as_float(0);
- }
- else {
- /* triangle */
- data[0].x = __int_as_float(leaf->lo);
- data[0].y = __int_as_float(leaf->hi);
- }
- data[0].z = __uint_as_float(leaf->visibility);
- if(leaf->num_triangles() != 0) {
- data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
- }
-
- memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4)*BVH_NODE_LEAF_SIZE);
+ assert(e.idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
+ float4 data[BVH_NODE_LEAF_SIZE];
+ memset(data, 0, sizeof(data));
+ if (leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
+ /* object */
+ data[0].x = __int_as_float(~(leaf->lo));
+ data[0].y = __int_as_float(0);
+ }
+ else {
+ /* triangle */
+ data[0].x = __int_as_float(leaf->lo);
+ data[0].y = __int_as_float(leaf->hi);
+ }
+ data[0].z = __uint_as_float(leaf->visibility);
+ if (leaf->num_triangles() != 0) {
+ data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
+ }
+
+ memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4) * BVH_NODE_LEAF_SIZE);
}
-void BVH2::pack_inner(const BVHStackEntry& e,
- const BVHStackEntry& e0,
- const BVHStackEntry& e1)
+void BVH2::pack_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
{
- if(e0.node->is_unaligned || e1.node->is_unaligned) {
- pack_unaligned_inner(e, e0, e1);
- } else {
- pack_aligned_inner(e, e0, e1);
- }
+ if (e0.node->is_unaligned || e1.node->is_unaligned) {
+ pack_unaligned_inner(e, e0, e1);
+ }
+ else {
+ pack_aligned_inner(e, e0, e1);
+ }
}
-void BVH2::pack_aligned_inner(const BVHStackEntry& e,
- const BVHStackEntry& e0,
- const BVHStackEntry& e1)
+void BVH2::pack_aligned_inner(const BVHStackEntry &e,
+ const BVHStackEntry &e0,
+ const BVHStackEntry &e1)
{
- pack_aligned_node(e.idx,
- e0.node->bounds, e1.node->bounds,
- e0.encodeIdx(), e1.encodeIdx(),
- e0.node->visibility, e1.node->visibility);
+ pack_aligned_node(e.idx,
+ e0.node->bounds,
+ e1.node->bounds,
+ e0.encodeIdx(),
+ e1.encodeIdx(),
+ e0.node->visibility,
+ e1.node->visibility);
}
void BVH2::pack_aligned_node(int idx,
- const BoundBox& b0,
- const BoundBox& b1,
- int c0, int c1,
- uint visibility0, uint visibility1)
+ const BoundBox &b0,
+ const BoundBox &b1,
+ int c0,
+ int c1,
+ uint visibility0,
+ uint visibility1)
{
- assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
- assert(c0 < 0 || c0 < pack.nodes.size());
- assert(c1 < 0 || c1 < pack.nodes.size());
-
- int4 data[BVH_NODE_SIZE] = {
- make_int4(visibility0 & ~PATH_RAY_NODE_UNALIGNED,
- visibility1 & ~PATH_RAY_NODE_UNALIGNED,
- c0, c1),
- make_int4(__float_as_int(b0.min.x),
- __float_as_int(b1.min.x),
- __float_as_int(b0.max.x),
- __float_as_int(b1.max.x)),
- make_int4(__float_as_int(b0.min.y),
- __float_as_int(b1.min.y),
- __float_as_int(b0.max.y),
- __float_as_int(b1.max.y)),
- make_int4(__float_as_int(b0.min.z),
- __float_as_int(b1.min.z),
- __float_as_int(b0.max.z),
- __float_as_int(b1.max.z)),
- };
-
- memcpy(&pack.nodes[idx], data, sizeof(int4)*BVH_NODE_SIZE);
+ assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
+ assert(c0 < 0 || c0 < pack.nodes.size());
+ assert(c1 < 0 || c1 < pack.nodes.size());
+
+ int4 data[BVH_NODE_SIZE] = {
+ make_int4(
+ visibility0 & ~PATH_RAY_NODE_UNALIGNED, visibility1 & ~PATH_RAY_NODE_UNALIGNED, c0, c1),
+ make_int4(__float_as_int(b0.min.x),
+ __float_as_int(b1.min.x),
+ __float_as_int(b0.max.x),
+ __float_as_int(b1.max.x)),
+ make_int4(__float_as_int(b0.min.y),
+ __float_as_int(b1.min.y),
+ __float_as_int(b0.max.y),
+ __float_as_int(b1.max.y)),
+ make_int4(__float_as_int(b0.min.z),
+ __float_as_int(b1.min.z),
+ __float_as_int(b0.max.z),
+ __float_as_int(b1.max.z)),
+ };
+
+ memcpy(&pack.nodes[idx], data, sizeof(int4) * BVH_NODE_SIZE);
}
-void BVH2::pack_unaligned_inner(const BVHStackEntry& e,
- const BVHStackEntry& e0,
- const BVHStackEntry& e1)
+void BVH2::pack_unaligned_inner(const BVHStackEntry &e,
+ const BVHStackEntry &e0,
+ const BVHStackEntry &e1)
{
- pack_unaligned_node(e.idx,
- e0.node->get_aligned_space(),
- e1.node->get_aligned_space(),
- e0.node->bounds,
- e1.node->bounds,
- e0.encodeIdx(), e1.encodeIdx(),
- e0.node->visibility, e1.node->visibility);
+ pack_unaligned_node(e.idx,
+ e0.node->get_aligned_space(),
+ e1.node->get_aligned_space(),
+ e0.node->bounds,
+ e1.node->bounds,
+ e0.encodeIdx(),
+ e1.encodeIdx(),
+ e0.node->visibility,
+ e1.node->visibility);
}
void BVH2::pack_unaligned_node(int idx,
- const Transform& aligned_space0,
- const Transform& aligned_space1,
- const BoundBox& bounds0,
- const BoundBox& bounds1,
- int c0, int c1,
- uint visibility0, uint visibility1)
+ const Transform &aligned_space0,
+ const Transform &aligned_space1,
+ const BoundBox &bounds0,
+ const BoundBox &bounds1,
+ int c0,
+ int c1,
+ uint visibility0,
+ uint visibility1)
{
- assert(idx + BVH_UNALIGNED_NODE_SIZE <= pack.nodes.size());
- assert(c0 < 0 || c0 < pack.nodes.size());
- assert(c1 < 0 || c1 < pack.nodes.size());
-
- float4 data[BVH_UNALIGNED_NODE_SIZE];
- Transform space0 = BVHUnaligned::compute_node_transform(bounds0,
- aligned_space0);
- Transform space1 = BVHUnaligned::compute_node_transform(bounds1,
- aligned_space1);
- data[0] = make_float4(__int_as_float(visibility0 | PATH_RAY_NODE_UNALIGNED),
- __int_as_float(visibility1 | PATH_RAY_NODE_UNALIGNED),
- __int_as_float(c0),
- __int_as_float(c1));
-
- data[1] = space0.x;
- data[2] = space0.y;
- data[3] = space0.z;
- data[4] = space1.x;
- data[5] = space1.y;
- data[6] = space1.z;
-
- memcpy(&pack.nodes[idx], data, sizeof(float4)*BVH_UNALIGNED_NODE_SIZE);
+ assert(idx + BVH_UNALIGNED_NODE_SIZE <= pack.nodes.size());
+ assert(c0 < 0 || c0 < pack.nodes.size());
+ assert(c1 < 0 || c1 < pack.nodes.size());
+
+ float4 data[BVH_UNALIGNED_NODE_SIZE];
+ Transform space0 = BVHUnaligned::compute_node_transform(bounds0, aligned_space0);
+ Transform space1 = BVHUnaligned::compute_node_transform(bounds1, aligned_space1);
+ data[0] = make_float4(__int_as_float(visibility0 | PATH_RAY_NODE_UNALIGNED),
+ __int_as_float(visibility1 | PATH_RAY_NODE_UNALIGNED),
+ __int_as_float(c0),
+ __int_as_float(c1));
+
+ data[1] = space0.x;
+ data[2] = space0.y;
+ data[3] = space0.z;
+ data[4] = space1.x;
+ data[5] = space1.y;
+ data[6] = space1.z;
+
+ memcpy(&pack.nodes[idx], data, sizeof(float4) * BVH_UNALIGNED_NODE_SIZE);
}
void BVH2::pack_nodes(const BVHNode *root)
{
- const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
- const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
- assert(num_leaf_nodes <= num_nodes);
- const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
- size_t node_size;
- if(params.use_unaligned_nodes) {
- const size_t num_unaligned_nodes =
- root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
- node_size = (num_unaligned_nodes * BVH_UNALIGNED_NODE_SIZE) +
- (num_inner_nodes - num_unaligned_nodes) * BVH_NODE_SIZE;
- }
- else {
- node_size = num_inner_nodes * BVH_NODE_SIZE;
- }
- /* Resize arrays */
- pack.nodes.clear();
- pack.leaf_nodes.clear();
- /* For top level BVH, first merge existing BVH's so we know the offsets. */
- if(params.top_level) {
- pack_instances(node_size, num_leaf_nodes*BVH_NODE_LEAF_SIZE);
- }
- else {
- pack.nodes.resize(node_size);
- pack.leaf_nodes.resize(num_leaf_nodes*BVH_NODE_LEAF_SIZE);
- }
-
- int nextNodeIdx = 0, nextLeafNodeIdx = 0;
-
- vector<BVHStackEntry> stack;
- stack.reserve(BVHParams::MAX_DEPTH*2);
- if(root->is_leaf()) {
- stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
- }
- else {
- stack.push_back(BVHStackEntry(root, nextNodeIdx));
- nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_NODE_SIZE
- : BVH_NODE_SIZE;
- }
-
- while(stack.size()) {
- BVHStackEntry e = stack.back();
- stack.pop_back();
-
- if(e.node->is_leaf()) {
- /* leaf node */
- const LeafNode *leaf = reinterpret_cast<const LeafNode*>(e.node);
- pack_leaf(e, leaf);
- }
- else {
- /* inner node */
- int idx[2];
- for(int i = 0; i < 2; ++i) {
- if(e.node->get_child(i)->is_leaf()) {
- idx[i] = nextLeafNodeIdx++;
- }
- else {
- idx[i] = nextNodeIdx;
- nextNodeIdx += e.node->get_child(i)->has_unaligned()
- ? BVH_UNALIGNED_NODE_SIZE
- : BVH_NODE_SIZE;
- }
- }
-
- stack.push_back(BVHStackEntry(e.node->get_child(0), idx[0]));
- stack.push_back(BVHStackEntry(e.node->get_child(1), idx[1]));
-
- pack_inner(e, stack[stack.size()-2], stack[stack.size()-1]);
- }
- }
- assert(node_size == nextNodeIdx);
- /* root index to start traversal at, to handle case of single leaf node */
- pack.root_index = (root->is_leaf())? -1: 0;
+ const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
+ const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
+ assert(num_leaf_nodes <= num_nodes);
+ const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
+ size_t node_size;
+ if (params.use_unaligned_nodes) {
+ const size_t num_unaligned_nodes = root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
+ node_size = (num_unaligned_nodes * BVH_UNALIGNED_NODE_SIZE) +
+ (num_inner_nodes - num_unaligned_nodes) * BVH_NODE_SIZE;
+ }
+ else {
+ node_size = num_inner_nodes * BVH_NODE_SIZE;
+ }
+ /* Resize arrays */
+ pack.nodes.clear();
+ pack.leaf_nodes.clear();
+ /* For top level BVH, first merge existing BVH's so we know the offsets. */
+ if (params.top_level) {
+ pack_instances(node_size, num_leaf_nodes * BVH_NODE_LEAF_SIZE);
+ }
+ else {
+ pack.nodes.resize(node_size);
+ pack.leaf_nodes.resize(num_leaf_nodes * BVH_NODE_LEAF_SIZE);
+ }
+
+ int nextNodeIdx = 0, nextLeafNodeIdx = 0;
+
+ vector<BVHStackEntry> stack;
+ stack.reserve(BVHParams::MAX_DEPTH * 2);
+ if (root->is_leaf()) {
+ stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
+ }
+ else {
+ stack.push_back(BVHStackEntry(root, nextNodeIdx));
+ nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_NODE_SIZE : BVH_NODE_SIZE;
+ }
+
+ while (stack.size()) {
+ BVHStackEntry e = stack.back();
+ stack.pop_back();
+
+ if (e.node->is_leaf()) {
+ /* leaf node */
+ const LeafNode *leaf = reinterpret_cast<const LeafNode *>(e.node);
+ pack_leaf(e, leaf);
+ }
+ else {
+ /* inner node */
+ int idx[2];
+ for (int i = 0; i < 2; ++i) {
+ if (e.node->get_child(i)->is_leaf()) {
+ idx[i] = nextLeafNodeIdx++;
+ }
+ else {
+ idx[i] = nextNodeIdx;
+ nextNodeIdx += e.node->get_child(i)->has_unaligned() ? BVH_UNALIGNED_NODE_SIZE :
+ BVH_NODE_SIZE;
+ }
+ }
+
+ stack.push_back(BVHStackEntry(e.node->get_child(0), idx[0]));
+ stack.push_back(BVHStackEntry(e.node->get_child(1), idx[1]));
+
+ pack_inner(e, stack[stack.size() - 2], stack[stack.size() - 1]);
+ }
+ }
+ assert(node_size == nextNodeIdx);
+ /* root index to start traversal at, to handle case of single leaf node */
+ pack.root_index = (root->is_leaf()) ? -1 : 0;
}
void BVH2::refit_nodes()
{
- assert(!params.top_level);
+ assert(!params.top_level);
- BoundBox bbox = BoundBox::empty;
- uint visibility = 0;
- refit_node(0, (pack.root_index == -1)? true: false, bbox, visibility);
+ BoundBox bbox = BoundBox::empty;
+ uint visibility = 0;
+ refit_node(0, (pack.root_index == -1) ? true : false, bbox, visibility);
}
-void BVH2::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
+void BVH2::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
{
- if(leaf) {
- /* refit leaf node */
- assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
- const int4 *data = &pack.leaf_nodes[idx];
- const int c0 = data[0].x;
- const int c1 = data[0].y;
-
- BVH::refit_primitives(c0, c1, bbox, visibility);
-
- /* TODO(sergey): De-duplicate with pack_leaf(). */
- float4 leaf_data[BVH_NODE_LEAF_SIZE];
- leaf_data[0].x = __int_as_float(c0);
- leaf_data[0].y = __int_as_float(c1);
- leaf_data[0].z = __uint_as_float(visibility);
- leaf_data[0].w = __uint_as_float(data[0].w);
- memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4)*BVH_NODE_LEAF_SIZE);
- }
- else {
- assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
-
- const int4 *data = &pack.nodes[idx];
- const bool is_unaligned = (data[0].x & PATH_RAY_NODE_UNALIGNED) != 0;
- const int c0 = data[0].z;
- const int c1 = data[0].w;
- /* refit inner node, set bbox from children */
- BoundBox bbox0 = BoundBox::empty, bbox1 = BoundBox::empty;
- uint visibility0 = 0, visibility1 = 0;
-
- refit_node((c0 < 0)? -c0-1: c0, (c0 < 0), bbox0, visibility0);
- refit_node((c1 < 0)? -c1-1: c1, (c1 < 0), bbox1, visibility1);
-
- if(is_unaligned) {
- Transform aligned_space = transform_identity();
- pack_unaligned_node(idx,
- aligned_space, aligned_space,
- bbox0, bbox1,
- c0, c1,
- visibility0,
- visibility1);
- }
- else {
- pack_aligned_node(idx,
- bbox0, bbox1,
- c0, c1,
- visibility0,
- visibility1);
- }
-
- bbox.grow(bbox0);
- bbox.grow(bbox1);
- visibility = visibility0|visibility1;
- }
+ if (leaf) {
+ /* refit leaf node */
+ assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
+ const int4 *data = &pack.leaf_nodes[idx];
+ const int c0 = data[0].x;
+ const int c1 = data[0].y;
+
+ BVH::refit_primitives(c0, c1, bbox, visibility);
+
+ /* TODO(sergey): De-duplicate with pack_leaf(). */
+ float4 leaf_data[BVH_NODE_LEAF_SIZE];
+ leaf_data[0].x = __int_as_float(c0);
+ leaf_data[0].y = __int_as_float(c1);
+ leaf_data[0].z = __uint_as_float(visibility);
+ leaf_data[0].w = __uint_as_float(data[0].w);
+ memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4) * BVH_NODE_LEAF_SIZE);
+ }
+ else {
+ assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
+
+ const int4 *data = &pack.nodes[idx];
+ const bool is_unaligned = (data[0].x & PATH_RAY_NODE_UNALIGNED) != 0;
+ const int c0 = data[0].z;
+ const int c1 = data[0].w;
+ /* refit inner node, set bbox from children */
+ BoundBox bbox0 = BoundBox::empty, bbox1 = BoundBox::empty;
+ uint visibility0 = 0, visibility1 = 0;
+
+ refit_node((c0 < 0) ? -c0 - 1 : c0, (c0 < 0), bbox0, visibility0);
+ refit_node((c1 < 0) ? -c1 - 1 : c1, (c1 < 0), bbox1, visibility1);
+
+ if (is_unaligned) {
+ Transform aligned_space = transform_identity();
+ pack_unaligned_node(
+ idx, aligned_space, aligned_space, bbox0, bbox1, c0, c1, visibility0, visibility1);
+ }
+ else {
+ pack_aligned_node(idx, bbox0, bbox1, c0, c1, visibility0, visibility1);
+ }
+
+ bbox.grow(bbox0);
+ bbox.grow(bbox1);
+ visibility = visibility0 | visibility1;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh2.h b/intern/cycles/bvh/bvh2.h
index 6afa6c21796..c6a4e6fa73a 100644
--- a/intern/cycles/bvh/bvh2.h
+++ b/intern/cycles/bvh/bvh2.h
@@ -34,8 +34,8 @@ class LeafNode;
class Object;
class Progress;
-#define BVH_NODE_SIZE 4
-#define BVH_NODE_LEAF_SIZE 1
+#define BVH_NODE_SIZE 4
+#define BVH_NODE_LEAF_SIZE 1
#define BVH_UNALIGNED_NODE_SIZE 7
/* BVH2
@@ -43,48 +43,49 @@ class Progress;
* Typical BVH with each node having two children.
*/
class BVH2 : public BVH {
-protected:
- /* constructor */
- friend class BVH;
- BVH2(const BVHParams& params, const vector<Object*>& objects);
+ protected:
+ /* constructor */
+ friend class BVH;
+ BVH2(const BVHParams &params, const vector<Object *> &objects);
- /* Building process. */
- virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
+ /* Building process. */
+ virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
- /* pack */
- void pack_nodes(const BVHNode *root) override;
+ /* pack */
+ void pack_nodes(const BVHNode *root) override;
- void pack_leaf(const BVHStackEntry& e,
- const LeafNode *leaf);
- void pack_inner(const BVHStackEntry& e,
- const BVHStackEntry& e0,
- const BVHStackEntry& e1);
+ void pack_leaf(const BVHStackEntry &e, const LeafNode *leaf);
+ void pack_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1);
- void pack_aligned_inner(const BVHStackEntry& e,
- const BVHStackEntry& e0,
- const BVHStackEntry& e1);
- void pack_aligned_node(int idx,
- const BoundBox& b0,
- const BoundBox& b1,
- int c0, int c1,
- uint visibility0, uint visibility1);
+ void pack_aligned_inner(const BVHStackEntry &e,
+ const BVHStackEntry &e0,
+ const BVHStackEntry &e1);
+ void pack_aligned_node(int idx,
+ const BoundBox &b0,
+ const BoundBox &b1,
+ int c0,
+ int c1,
+ uint visibility0,
+ uint visibility1);
- void pack_unaligned_inner(const BVHStackEntry& e,
- const BVHStackEntry& e0,
- const BVHStackEntry& e1);
- void pack_unaligned_node(int idx,
- const Transform& aligned_space0,
- const Transform& aligned_space1,
- const BoundBox& b0,
- const BoundBox& b1,
- int c0, int c1,
- uint visibility0, uint visibility1);
+ void pack_unaligned_inner(const BVHStackEntry &e,
+ const BVHStackEntry &e0,
+ const BVHStackEntry &e1);
+ void pack_unaligned_node(int idx,
+ const Transform &aligned_space0,
+ const Transform &aligned_space1,
+ const BoundBox &b0,
+ const BoundBox &b1,
+ int c0,
+ int c1,
+ uint visibility0,
+ uint visibility1);
- /* refit */
- void refit_nodes() override;
- void refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility);
+ /* refit */
+ void refit_nodes() override;
+ void refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility);
};
CCL_NAMESPACE_END
-#endif /* __BVH2_H__ */
+#endif /* __BVH2_H__ */
diff --git a/intern/cycles/bvh/bvh4.cpp b/intern/cycles/bvh/bvh4.cpp
index a7c4cea85ce..850bdf5b8b4 100644
--- a/intern/cycles/bvh/bvh4.cpp
+++ b/intern/cycles/bvh/bvh4.cpp
@@ -31,141 +31,131 @@ CCL_NAMESPACE_BEGIN
* life easier all over the place.
*/
-BVH4::BVH4(const BVHParams& params_, const vector<Object*>& objects_)
-: BVH(params_, objects_)
+BVH4::BVH4(const BVHParams &params_, const vector<Object *> &objects_) : BVH(params_, objects_)
{
- params.bvh_layout = BVH_LAYOUT_BVH4;
+ params.bvh_layout = BVH_LAYOUT_BVH4;
}
namespace {
BVHNode *bvh_node_merge_children_recursively(const BVHNode *node)
{
- if(node->is_leaf()) {
- return new LeafNode(*reinterpret_cast<const LeafNode *>(node));
- }
- /* Collect nodes of one layer deeper, allowing us to have more childrem in
- * an inner layer. */
- assert(node->num_children() <= 2);
- const BVHNode *children[4];
- const BVHNode *child0 = node->get_child(0);
- const BVHNode *child1 = node->get_child(1);
- int num_children = 0;
- if(child0->is_leaf()) {
- children[num_children++] = child0;
- }
- else {
- children[num_children++] = child0->get_child(0);
- children[num_children++] = child0->get_child(1);
- }
- if(child1->is_leaf()) {
- children[num_children++] = child1;
- }
- else {
- children[num_children++] = child1->get_child(0);
- children[num_children++] = child1->get_child(1);
- }
- /* Merge children in subtrees. */
- BVHNode *children4[4];
- for(int i = 0; i < num_children; ++i) {
- children4[i] = bvh_node_merge_children_recursively(children[i]);
- }
- /* Allocate new node. */
- BVHNode *node4 = new InnerNode(node->bounds, children4, num_children);
- /* TODO(sergey): Consider doing this from the InnerNode() constructor.
- * But in order to do this nicely need to think of how to pass all the
- * parameters there. */
- if(node->is_unaligned) {
- node4->is_unaligned = true;
- node4->aligned_space = new Transform();
- *node4->aligned_space = *node->aligned_space;
- }
- return node4;
+ if (node->is_leaf()) {
+ return new LeafNode(*reinterpret_cast<const LeafNode *>(node));
+ }
+ /* Collect nodes of one layer deeper, allowing us to have more childrem in
+ * an inner layer. */
+ assert(node->num_children() <= 2);
+ const BVHNode *children[4];
+ const BVHNode *child0 = node->get_child(0);
+ const BVHNode *child1 = node->get_child(1);
+ int num_children = 0;
+ if (child0->is_leaf()) {
+ children[num_children++] = child0;
+ }
+ else {
+ children[num_children++] = child0->get_child(0);
+ children[num_children++] = child0->get_child(1);
+ }
+ if (child1->is_leaf()) {
+ children[num_children++] = child1;
+ }
+ else {
+ children[num_children++] = child1->get_child(0);
+ children[num_children++] = child1->get_child(1);
+ }
+ /* Merge children in subtrees. */
+ BVHNode *children4[4];
+ for (int i = 0; i < num_children; ++i) {
+ children4[i] = bvh_node_merge_children_recursively(children[i]);
+ }
+ /* Allocate new node. */
+ BVHNode *node4 = new InnerNode(node->bounds, children4, num_children);
+ /* TODO(sergey): Consider doing this from the InnerNode() constructor.
+ * But in order to do this nicely need to think of how to pass all the
+ * parameters there. */
+ if (node->is_unaligned) {
+ node4->is_unaligned = true;
+ node4->aligned_space = new Transform();
+ *node4->aligned_space = *node->aligned_space;
+ }
+ return node4;
}
} // namespace
BVHNode *BVH4::widen_children_nodes(const BVHNode *root)
{
- if(root == NULL) {
- return NULL;
- }
- if(root->is_leaf()) {
- return const_cast<BVHNode *>(root);
- }
- BVHNode *root4 = bvh_node_merge_children_recursively(root);
- /* TODO(sergey): Pack children nodes to parents which has less that 4
- * children. */
- return root4;
+ if (root == NULL) {
+ return NULL;
+ }
+ if (root->is_leaf()) {
+ return const_cast<BVHNode *>(root);
+ }
+ BVHNode *root4 = bvh_node_merge_children_recursively(root);
+ /* TODO(sergey): Pack children nodes to parents which has less that 4
+ * children. */
+ return root4;
}
-void BVH4::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf)
+void BVH4::pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
{
- float4 data[BVH_QNODE_LEAF_SIZE];
- memset(data, 0, sizeof(data));
- if(leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
- /* object */
- data[0].x = __int_as_float(~(leaf->lo));
- data[0].y = __int_as_float(0);
- }
- else {
- /* triangle */
- data[0].x = __int_as_float(leaf->lo);
- data[0].y = __int_as_float(leaf->hi);
- }
- data[0].z = __uint_as_float(leaf->visibility);
- if(leaf->num_triangles() != 0) {
- data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
- }
-
- memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4)*BVH_QNODE_LEAF_SIZE);
+ float4 data[BVH_QNODE_LEAF_SIZE];
+ memset(data, 0, sizeof(data));
+ if (leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
+ /* object */
+ data[0].x = __int_as_float(~(leaf->lo));
+ data[0].y = __int_as_float(0);
+ }
+ else {
+ /* triangle */
+ data[0].x = __int_as_float(leaf->lo);
+ data[0].y = __int_as_float(leaf->hi);
+ }
+ data[0].z = __uint_as_float(leaf->visibility);
+ if (leaf->num_triangles() != 0) {
+ data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
+ }
+
+ memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4) * BVH_QNODE_LEAF_SIZE);
}
-void BVH4::pack_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num)
+void BVH4::pack_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num)
{
- bool has_unaligned = false;
- /* Check whether we have to create unaligned node or all nodes are aligned
- * and we can cut some corner here.
- */
- if(params.use_unaligned_nodes) {
- for(int i = 0; i < num; i++) {
- if(en[i].node->is_unaligned) {
- has_unaligned = true;
- break;
- }
- }
- }
- if(has_unaligned) {
- /* There's no unaligned children, pack into AABB node. */
- pack_unaligned_inner(e, en, num);
- }
- else {
- /* Create unaligned node with orientation transform for each of the
- * children.
- */
- pack_aligned_inner(e, en, num);
- }
+ bool has_unaligned = false;
+ /* Check whether we have to create unaligned node or all nodes are aligned
+ * and we can cut some corner here.
+ */
+ if (params.use_unaligned_nodes) {
+ for (int i = 0; i < num; i++) {
+ if (en[i].node->is_unaligned) {
+ has_unaligned = true;
+ break;
+ }
+ }
+ }
+ if (has_unaligned) {
+ /* There's no unaligned children, pack into AABB node. */
+ pack_unaligned_inner(e, en, num);
+ }
+ else {
+ /* Create unaligned node with orientation transform for each of the
+ * children.
+ */
+ pack_aligned_inner(e, en, num);
+ }
}
-void BVH4::pack_aligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num)
+void BVH4::pack_aligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num)
{
- BoundBox bounds[4];
- int child[4];
- for(int i = 0; i < num; ++i) {
- bounds[i] = en[i].node->bounds;
- child[i] = en[i].encodeIdx();
- }
- pack_aligned_node(e.idx,
- bounds,
- child,
- e.node->visibility,
- e.node->time_from,
- e.node->time_to,
- num);
+ BoundBox bounds[4];
+ int child[4];
+ for (int i = 0; i < num; ++i) {
+ bounds[i] = en[i].node->bounds;
+ child[i] = en[i].encodeIdx();
+ }
+ pack_aligned_node(
+ e.idx, bounds, child, e.node->visibility, e.node->time_from, e.node->time_to, num);
}
void BVH4::pack_aligned_node(int idx,
@@ -176,66 +166,64 @@ void BVH4::pack_aligned_node(int idx,
const float time_to,
const int num)
{
- float4 data[BVH_QNODE_SIZE];
- memset(data, 0, sizeof(data));
+ float4 data[BVH_QNODE_SIZE];
+ memset(data, 0, sizeof(data));
- data[0].x = __uint_as_float(visibility & ~PATH_RAY_NODE_UNALIGNED);
- data[0].y = time_from;
- data[0].z = time_to;
+ data[0].x = __uint_as_float(visibility & ~PATH_RAY_NODE_UNALIGNED);
+ data[0].y = time_from;
+ data[0].z = time_to;
- for(int i = 0; i < num; i++) {
- float3 bb_min = bounds[i].min;
- float3 bb_max = bounds[i].max;
+ for (int i = 0; i < num; i++) {
+ float3 bb_min = bounds[i].min;
+ float3 bb_max = bounds[i].max;
- data[1][i] = bb_min.x;
- data[2][i] = bb_max.x;
- data[3][i] = bb_min.y;
- data[4][i] = bb_max.y;
- data[5][i] = bb_min.z;
- data[6][i] = bb_max.z;
+ data[1][i] = bb_min.x;
+ data[2][i] = bb_max.x;
+ data[3][i] = bb_min.y;
+ data[4][i] = bb_max.y;
+ data[5][i] = bb_min.z;
+ data[6][i] = bb_max.z;
- data[7][i] = __int_as_float(child[i]);
- }
+ data[7][i] = __int_as_float(child[i]);
+ }
- for(int i = num; i < 4; i++) {
- /* We store BB which would never be recorded as intersection
- * so kernel might safely assume there are always 4 child nodes.
- */
- data[1][i] = FLT_MAX;
- data[2][i] = -FLT_MAX;
+ for (int i = num; i < 4; i++) {
+ /* We store BB which would never be recorded as intersection
+ * so kernel might safely assume there are always 4 child nodes.
+ */
+ data[1][i] = FLT_MAX;
+ data[2][i] = -FLT_MAX;
- data[3][i] = FLT_MAX;
- data[4][i] = -FLT_MAX;
+ data[3][i] = FLT_MAX;
+ data[4][i] = -FLT_MAX;
- data[5][i] = FLT_MAX;
- data[6][i] = -FLT_MAX;
+ data[5][i] = FLT_MAX;
+ data[6][i] = -FLT_MAX;
- data[7][i] = __int_as_float(0);
- }
+ data[7][i] = __int_as_float(0);
+ }
- memcpy(&pack.nodes[idx], data, sizeof(float4)*BVH_QNODE_SIZE);
+ memcpy(&pack.nodes[idx], data, sizeof(float4) * BVH_QNODE_SIZE);
}
-void BVH4::pack_unaligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num)
+void BVH4::pack_unaligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num)
{
- Transform aligned_space[4];
- BoundBox bounds[4];
- int child[4];
- for(int i = 0; i < num; ++i) {
- aligned_space[i] = en[i].node->get_aligned_space();
- bounds[i] = en[i].node->bounds;
- child[i] = en[i].encodeIdx();
- }
- pack_unaligned_node(e.idx,
- aligned_space,
- bounds,
- child,
- e.node->visibility,
- e.node->time_from,
- e.node->time_to,
- num);
+ Transform aligned_space[4];
+ BoundBox bounds[4];
+ int child[4];
+ for (int i = 0; i < num; ++i) {
+ aligned_space[i] = en[i].node->get_aligned_space();
+ bounds[i] = en[i].node->bounds;
+ child[i] = en[i].encodeIdx();
+ }
+ pack_unaligned_node(e.idx,
+ aligned_space,
+ bounds,
+ child,
+ e.node->visibility,
+ e.node->time_from,
+ e.node->time_to,
+ num);
}
void BVH4::pack_unaligned_node(int idx,
@@ -247,235 +235,211 @@ void BVH4::pack_unaligned_node(int idx,
const float time_to,
const int num)
{
- float4 data[BVH_UNALIGNED_QNODE_SIZE];
- memset(data, 0, sizeof(data));
+ float4 data[BVH_UNALIGNED_QNODE_SIZE];
+ memset(data, 0, sizeof(data));
- data[0].x = __uint_as_float(visibility | PATH_RAY_NODE_UNALIGNED);
- data[0].y = time_from;
- data[0].z = time_to;
+ data[0].x = __uint_as_float(visibility | PATH_RAY_NODE_UNALIGNED);
+ data[0].y = time_from;
+ data[0].z = time_to;
- for(int i = 0; i < num; i++) {
- Transform space = BVHUnaligned::compute_node_transform(
- bounds[i],
- aligned_space[i]);
+ for (int i = 0; i < num; i++) {
+ Transform space = BVHUnaligned::compute_node_transform(bounds[i], aligned_space[i]);
- data[1][i] = space.x.x;
- data[2][i] = space.x.y;
- data[3][i] = space.x.z;
+ data[1][i] = space.x.x;
+ data[2][i] = space.x.y;
+ data[3][i] = space.x.z;
- data[4][i] = space.y.x;
- data[5][i] = space.y.y;
- data[6][i] = space.y.z;
+ data[4][i] = space.y.x;
+ data[5][i] = space.y.y;
+ data[6][i] = space.y.z;
- data[7][i] = space.z.x;
- data[8][i] = space.z.y;
- data[9][i] = space.z.z;
+ data[7][i] = space.z.x;
+ data[8][i] = space.z.y;
+ data[9][i] = space.z.z;
- data[10][i] = space.x.w;
- data[11][i] = space.y.w;
- data[12][i] = space.z.w;
+ data[10][i] = space.x.w;
+ data[11][i] = space.y.w;
+ data[12][i] = space.z.w;
- data[13][i] = __int_as_float(child[i]);
- }
+ data[13][i] = __int_as_float(child[i]);
+ }
- for(int i = num; i < 4; i++) {
- /* We store BB which would never be recorded as intersection
- * so kernel might safely assume there are always 4 child nodes.
- */
+ for (int i = num; i < 4; i++) {
+ /* We store BB which would never be recorded as intersection
+ * so kernel might safely assume there are always 4 child nodes.
+ */
- data[1][i] = NAN;
- data[2][i] = NAN;
- data[3][i] = NAN;
+ data[1][i] = NAN;
+ data[2][i] = NAN;
+ data[3][i] = NAN;
- data[4][i] = NAN;
- data[5][i] = NAN;
- data[6][i] = NAN;
+ data[4][i] = NAN;
+ data[5][i] = NAN;
+ data[6][i] = NAN;
- data[7][i] = NAN;
- data[8][i] = NAN;
- data[9][i] = NAN;
+ data[7][i] = NAN;
+ data[8][i] = NAN;
+ data[9][i] = NAN;
- data[10][i] = NAN;
- data[11][i] = NAN;
- data[12][i] = NAN;
+ data[10][i] = NAN;
+ data[11][i] = NAN;
+ data[12][i] = NAN;
- data[13][i] = __int_as_float(0);
- }
+ data[13][i] = __int_as_float(0);
+ }
- memcpy(&pack.nodes[idx], data, sizeof(float4)*BVH_UNALIGNED_QNODE_SIZE);
+ memcpy(&pack.nodes[idx], data, sizeof(float4) * BVH_UNALIGNED_QNODE_SIZE);
}
/* Quad SIMD Nodes */
void BVH4::pack_nodes(const BVHNode *root)
{
- /* Calculate size of the arrays required. */
- const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
- const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
- assert(num_leaf_nodes <= num_nodes);
- const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
- size_t node_size;
- if(params.use_unaligned_nodes) {
- const size_t num_unaligned_nodes =
- root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
- node_size = (num_unaligned_nodes * BVH_UNALIGNED_QNODE_SIZE) +
- (num_inner_nodes - num_unaligned_nodes) * BVH_QNODE_SIZE;
- }
- else {
- node_size = num_inner_nodes * BVH_QNODE_SIZE;
- }
- /* Resize arrays. */
- pack.nodes.clear();
- pack.leaf_nodes.clear();
- /* For top level BVH, first merge existing BVH's so we know the offsets. */
- if(params.top_level) {
- pack_instances(node_size, num_leaf_nodes*BVH_QNODE_LEAF_SIZE);
- }
- else {
- pack.nodes.resize(node_size);
- pack.leaf_nodes.resize(num_leaf_nodes*BVH_QNODE_LEAF_SIZE);
- }
-
- int nextNodeIdx = 0, nextLeafNodeIdx = 0;
-
- vector<BVHStackEntry> stack;
- stack.reserve(BVHParams::MAX_DEPTH*2);
- if(root->is_leaf()) {
- stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
- }
- else {
- stack.push_back(BVHStackEntry(root, nextNodeIdx));
- nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_QNODE_SIZE
- : BVH_QNODE_SIZE;
- }
-
- while(stack.size()) {
- BVHStackEntry e = stack.back();
- stack.pop_back();
-
- if(e.node->is_leaf()) {
- /* leaf node */
- const LeafNode *leaf = reinterpret_cast<const LeafNode*>(e.node);
- pack_leaf(e, leaf);
- }
- else {
- /* Inner node. */
- /* Collect nodes. */
- const BVHNode *children[4];
- const int num_children = e.node->num_children();
- /* Push entries on the stack. */
- for(int i = 0; i < num_children; ++i) {
- int idx;
- children[i] = e.node->get_child(i);
- assert(children[i] != NULL);
- if(children[i]->is_leaf()) {
- idx = nextLeafNodeIdx++;
- }
- else {
- idx = nextNodeIdx;
- nextNodeIdx += children[i]->has_unaligned()
- ? BVH_UNALIGNED_QNODE_SIZE
- : BVH_QNODE_SIZE;
- }
- stack.push_back(BVHStackEntry(children[i], idx));
- }
- /* Set node. */
- pack_inner(e, &stack[stack.size() - num_children], num_children);
- }
- }
-
- assert(node_size == nextNodeIdx);
- /* Root index to start traversal at, to handle case of single leaf node. */
- pack.root_index = (root->is_leaf())? -1: 0;
+ /* Calculate size of the arrays required. */
+ const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
+ const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
+ assert(num_leaf_nodes <= num_nodes);
+ const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
+ size_t node_size;
+ if (params.use_unaligned_nodes) {
+ const size_t num_unaligned_nodes = root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
+ node_size = (num_unaligned_nodes * BVH_UNALIGNED_QNODE_SIZE) +
+ (num_inner_nodes - num_unaligned_nodes) * BVH_QNODE_SIZE;
+ }
+ else {
+ node_size = num_inner_nodes * BVH_QNODE_SIZE;
+ }
+ /* Resize arrays. */
+ pack.nodes.clear();
+ pack.leaf_nodes.clear();
+ /* For top level BVH, first merge existing BVH's so we know the offsets. */
+ if (params.top_level) {
+ pack_instances(node_size, num_leaf_nodes * BVH_QNODE_LEAF_SIZE);
+ }
+ else {
+ pack.nodes.resize(node_size);
+ pack.leaf_nodes.resize(num_leaf_nodes * BVH_QNODE_LEAF_SIZE);
+ }
+
+ int nextNodeIdx = 0, nextLeafNodeIdx = 0;
+
+ vector<BVHStackEntry> stack;
+ stack.reserve(BVHParams::MAX_DEPTH * 2);
+ if (root->is_leaf()) {
+ stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
+ }
+ else {
+ stack.push_back(BVHStackEntry(root, nextNodeIdx));
+ nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_QNODE_SIZE : BVH_QNODE_SIZE;
+ }
+
+ while (stack.size()) {
+ BVHStackEntry e = stack.back();
+ stack.pop_back();
+
+ if (e.node->is_leaf()) {
+ /* leaf node */
+ const LeafNode *leaf = reinterpret_cast<const LeafNode *>(e.node);
+ pack_leaf(e, leaf);
+ }
+ else {
+ /* Inner node. */
+ /* Collect nodes. */
+ const BVHNode *children[4];
+ const int num_children = e.node->num_children();
+ /* Push entries on the stack. */
+ for (int i = 0; i < num_children; ++i) {
+ int idx;
+ children[i] = e.node->get_child(i);
+ assert(children[i] != NULL);
+ if (children[i]->is_leaf()) {
+ idx = nextLeafNodeIdx++;
+ }
+ else {
+ idx = nextNodeIdx;
+ nextNodeIdx += children[i]->has_unaligned() ? BVH_UNALIGNED_QNODE_SIZE : BVH_QNODE_SIZE;
+ }
+ stack.push_back(BVHStackEntry(children[i], idx));
+ }
+ /* Set node. */
+ pack_inner(e, &stack[stack.size() - num_children], num_children);
+ }
+ }
+
+ assert(node_size == nextNodeIdx);
+ /* Root index to start traversal at, to handle case of single leaf node. */
+ pack.root_index = (root->is_leaf()) ? -1 : 0;
}
void BVH4::refit_nodes()
{
- assert(!params.top_level);
+ assert(!params.top_level);
- BoundBox bbox = BoundBox::empty;
- uint visibility = 0;
- refit_node(0, (pack.root_index == -1)? true: false, bbox, visibility);
+ BoundBox bbox = BoundBox::empty;
+ uint visibility = 0;
+ refit_node(0, (pack.root_index == -1) ? true : false, bbox, visibility);
}
-void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
+void BVH4::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
{
- if(leaf) {
- /* Refit leaf node. */
- int4 *data = &pack.leaf_nodes[idx];
- int4 c = data[0];
-
- BVH::refit_primitives(c.x, c.y, bbox, visibility);
-
- /* TODO(sergey): This is actually a copy of pack_leaf(),
- * but this chunk of code only knows actual data and has
- * no idea about BVHNode.
- *
- * Would be nice to de-duplicate code, but trying to make
- * making code more general ends up in much nastier code
- * in my opinion so far.
- *
- * Same applies to the inner nodes case below.
- */
- float4 leaf_data[BVH_QNODE_LEAF_SIZE];
- leaf_data[0].x = __int_as_float(c.x);
- leaf_data[0].y = __int_as_float(c.y);
- leaf_data[0].z = __uint_as_float(visibility);
- leaf_data[0].w = __uint_as_float(c.w);
- memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4)*BVH_QNODE_LEAF_SIZE);
- }
- else {
- int4 *data = &pack.nodes[idx];
- bool is_unaligned = (data[0].x & PATH_RAY_NODE_UNALIGNED) != 0;
- int4 c;
- if(is_unaligned) {
- c = data[13];
- }
- else {
- c = data[7];
- }
- /* Refit inner node, set bbox from children. */
- BoundBox child_bbox[4] = {BoundBox::empty,
- BoundBox::empty,
- BoundBox::empty,
- BoundBox::empty};
- uint child_visibility[4] = {0};
- int num_nodes = 0;
-
- for(int i = 0; i < 4; ++i) {
- if(c[i] != 0) {
- refit_node((c[i] < 0)? -c[i]-1: c[i], (c[i] < 0),
- child_bbox[i], child_visibility[i]);
- ++num_nodes;
- bbox.grow(child_bbox[i]);
- visibility |= child_visibility[i];
- }
- }
-
- if(is_unaligned) {
- Transform aligned_space[4] = {transform_identity(),
- transform_identity(),
- transform_identity(),
- transform_identity()};
- pack_unaligned_node(idx,
- aligned_space,
- child_bbox,
- &c[0],
- visibility,
- 0.0f,
- 1.0f,
- num_nodes);
- }
- else {
- pack_aligned_node(idx,
- child_bbox,
- &c[0],
- visibility,
- 0.0f,
- 1.0f,
- num_nodes);
- }
- }
+ if (leaf) {
+ /* Refit leaf node. */
+ int4 *data = &pack.leaf_nodes[idx];
+ int4 c = data[0];
+
+ BVH::refit_primitives(c.x, c.y, bbox, visibility);
+
+ /* TODO(sergey): This is actually a copy of pack_leaf(),
+ * but this chunk of code only knows actual data and has
+ * no idea about BVHNode.
+ *
+ * Would be nice to de-duplicate code, but trying to make
+ * making code more general ends up in much nastier code
+ * in my opinion so far.
+ *
+ * Same applies to the inner nodes case below.
+ */
+ float4 leaf_data[BVH_QNODE_LEAF_SIZE];
+ leaf_data[0].x = __int_as_float(c.x);
+ leaf_data[0].y = __int_as_float(c.y);
+ leaf_data[0].z = __uint_as_float(visibility);
+ leaf_data[0].w = __uint_as_float(c.w);
+ memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4) * BVH_QNODE_LEAF_SIZE);
+ }
+ else {
+ int4 *data = &pack.nodes[idx];
+ bool is_unaligned = (data[0].x & PATH_RAY_NODE_UNALIGNED) != 0;
+ int4 c;
+ if (is_unaligned) {
+ c = data[13];
+ }
+ else {
+ c = data[7];
+ }
+ /* Refit inner node, set bbox from children. */
+ BoundBox child_bbox[4] = {BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty};
+ uint child_visibility[4] = {0};
+ int num_nodes = 0;
+
+ for (int i = 0; i < 4; ++i) {
+ if (c[i] != 0) {
+ refit_node((c[i] < 0) ? -c[i] - 1 : c[i], (c[i] < 0), child_bbox[i], child_visibility[i]);
+ ++num_nodes;
+ bbox.grow(child_bbox[i]);
+ visibility |= child_visibility[i];
+ }
+ }
+
+ if (is_unaligned) {
+ Transform aligned_space[4] = {
+ transform_identity(), transform_identity(), transform_identity(), transform_identity()};
+ pack_unaligned_node(
+ idx, aligned_space, child_bbox, &c[0], visibility, 0.0f, 1.0f, num_nodes);
+ }
+ else {
+ pack_aligned_node(idx, child_bbox, &c[0], visibility, 0.0f, 1.0f, num_nodes);
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh4.h b/intern/cycles/bvh/bvh4.h
index caa0e2c8182..38b0961d3df 100644
--- a/intern/cycles/bvh/bvh4.h
+++ b/intern/cycles/bvh/bvh4.h
@@ -34,8 +34,8 @@ class LeafNode;
class Object;
class Progress;
-#define BVH_QNODE_SIZE 8
-#define BVH_QNODE_LEAF_SIZE 1
+#define BVH_QNODE_SIZE 8
+#define BVH_QNODE_LEAF_SIZE 1
#define BVH_UNALIGNED_QNODE_SIZE 14
/* BVH4
@@ -43,48 +43,44 @@ class Progress;
* Quad BVH, with each node having four children, to use with SIMD instructions.
*/
class BVH4 : public BVH {
-protected:
- /* constructor */
- friend class BVH;
- BVH4(const BVHParams& params, const vector<Object*>& objects);
+ protected:
+ /* constructor */
+ friend class BVH;
+ BVH4(const BVHParams &params, const vector<Object *> &objects);
- /* Building process. */
- virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
+ /* Building process. */
+ virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
- /* pack */
- void pack_nodes(const BVHNode *root) override;
+ /* pack */
+ void pack_nodes(const BVHNode *root) override;
- void pack_leaf(const BVHStackEntry& e, const LeafNode *leaf);
- void pack_inner(const BVHStackEntry& e, const BVHStackEntry *en, int num);
+ void pack_leaf(const BVHStackEntry &e, const LeafNode *leaf);
+ void pack_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num);
- void pack_aligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num);
- void pack_aligned_node(int idx,
- const BoundBox *bounds,
- const int *child,
- const uint visibility,
- const float time_from,
- const float time_to,
- const int num);
+ void pack_aligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num);
+ void pack_aligned_node(int idx,
+ const BoundBox *bounds,
+ const int *child,
+ const uint visibility,
+ const float time_from,
+ const float time_to,
+ const int num);
- void pack_unaligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num);
- void pack_unaligned_node(int idx,
- const Transform *aligned_space,
- const BoundBox *bounds,
- const int *child,
- const uint visibility,
- const float time_from,
- const float time_to,
- const int num);
+ void pack_unaligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num);
+ void pack_unaligned_node(int idx,
+ const Transform *aligned_space,
+ const BoundBox *bounds,
+ const int *child,
+ const uint visibility,
+ const float time_from,
+ const float time_to,
+ const int num);
- /* refit */
- void refit_nodes() override;
- void refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility);
+ /* refit */
+ void refit_nodes() override;
+ void refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility);
};
CCL_NAMESPACE_END
-#endif /* __BVH4_H__ */
+#endif /* __BVH4_H__ */
diff --git a/intern/cycles/bvh/bvh8.cpp b/intern/cycles/bvh/bvh8.cpp
index af930b2f2df..e812d806b94 100644
--- a/intern/cycles/bvh/bvh8.cpp
+++ b/intern/cycles/bvh/bvh8.cpp
@@ -36,8 +36,7 @@
CCL_NAMESPACE_BEGIN
-BVH8::BVH8(const BVHParams& params_, const vector<Object*>& objects_)
-: BVH(params_, objects_)
+BVH8::BVH8(const BVHParams &params_, const vector<Object *> &objects_) : BVH(params_, objects_)
{
}
@@ -45,159 +44,148 @@ namespace {
BVHNode *bvh_node_merge_children_recursively(const BVHNode *node)
{
- if(node->is_leaf()) {
- return new LeafNode(*reinterpret_cast<const LeafNode *>(node));
- }
- /* Collect nodes of two layer deeper, allowing us to have more childrem in
- * an inner layer. */
- assert(node->num_children() <= 2);
- const BVHNode *children[8];
- const BVHNode *child0 = node->get_child(0);
- const BVHNode *child1 = node->get_child(1);
- int num_children = 0;
- if(child0->is_leaf()) {
- children[num_children++] = child0;
- }
- else {
- const BVHNode *child00 = child0->get_child(0),
- *child01 = child0->get_child(1);
- if(child00->is_leaf()) {
- children[num_children++] = child00;
- }
- else {
- children[num_children++] = child00->get_child(0);
- children[num_children++] = child00->get_child(1);
- }
- if(child01->is_leaf()) {
- children[num_children++] = child01;
- }
- else {
- children[num_children++] = child01->get_child(0);
- children[num_children++] = child01->get_child(1);
- }
- }
- if(child1->is_leaf()) {
- children[num_children++] = child1;
- }
- else {
- const BVHNode *child10 = child1->get_child(0),
- *child11 = child1->get_child(1);
- if(child10->is_leaf()) {
- children[num_children++] = child10;
- }
- else {
- children[num_children++] = child10->get_child(0);
- children[num_children++] = child10->get_child(1);
- }
- if(child11->is_leaf()) {
- children[num_children++] = child11;
- }
- else {
- children[num_children++] = child11->get_child(0);
- children[num_children++] = child11->get_child(1);
- }
- }
- /* Merge children in subtrees. */
- BVHNode *children4[8];
- for(int i = 0; i < num_children; ++i) {
- children4[i] = bvh_node_merge_children_recursively(children[i]);
- }
- /* Allocate new node. */
- BVHNode *node8 = new InnerNode(node->bounds, children4, num_children);
- /* TODO(sergey): Consider doing this from the InnerNode() constructor.
- * But in order to do this nicely need to think of how to pass all the
- * parameters there. */
- if(node->is_unaligned) {
- node8->is_unaligned = true;
- node8->aligned_space = new Transform();
- *node8->aligned_space = *node->aligned_space;
- }
- return node8;
+ if (node->is_leaf()) {
+ return new LeafNode(*reinterpret_cast<const LeafNode *>(node));
+ }
+ /* Collect nodes of two layer deeper, allowing us to have more childrem in
+ * an inner layer. */
+ assert(node->num_children() <= 2);
+ const BVHNode *children[8];
+ const BVHNode *child0 = node->get_child(0);
+ const BVHNode *child1 = node->get_child(1);
+ int num_children = 0;
+ if (child0->is_leaf()) {
+ children[num_children++] = child0;
+ }
+ else {
+ const BVHNode *child00 = child0->get_child(0), *child01 = child0->get_child(1);
+ if (child00->is_leaf()) {
+ children[num_children++] = child00;
+ }
+ else {
+ children[num_children++] = child00->get_child(0);
+ children[num_children++] = child00->get_child(1);
+ }
+ if (child01->is_leaf()) {
+ children[num_children++] = child01;
+ }
+ else {
+ children[num_children++] = child01->get_child(0);
+ children[num_children++] = child01->get_child(1);
+ }
+ }
+ if (child1->is_leaf()) {
+ children[num_children++] = child1;
+ }
+ else {
+ const BVHNode *child10 = child1->get_child(0), *child11 = child1->get_child(1);
+ if (child10->is_leaf()) {
+ children[num_children++] = child10;
+ }
+ else {
+ children[num_children++] = child10->get_child(0);
+ children[num_children++] = child10->get_child(1);
+ }
+ if (child11->is_leaf()) {
+ children[num_children++] = child11;
+ }
+ else {
+ children[num_children++] = child11->get_child(0);
+ children[num_children++] = child11->get_child(1);
+ }
+ }
+ /* Merge children in subtrees. */
+ BVHNode *children4[8];
+ for (int i = 0; i < num_children; ++i) {
+ children4[i] = bvh_node_merge_children_recursively(children[i]);
+ }
+ /* Allocate new node. */
+ BVHNode *node8 = new InnerNode(node->bounds, children4, num_children);
+ /* TODO(sergey): Consider doing this from the InnerNode() constructor.
+ * But in order to do this nicely need to think of how to pass all the
+ * parameters there. */
+ if (node->is_unaligned) {
+ node8->is_unaligned = true;
+ node8->aligned_space = new Transform();
+ *node8->aligned_space = *node->aligned_space;
+ }
+ return node8;
}
} // namespace
BVHNode *BVH8::widen_children_nodes(const BVHNode *root)
{
- if(root == NULL) {
- return NULL;
- }
- if(root->is_leaf()) {
- return const_cast<BVHNode *>(root);
- }
- BVHNode *root8 = bvh_node_merge_children_recursively(root);
- /* TODO(sergey): Pack children nodes to parents which has less that 4
- * children. */
- return root8;
+ if (root == NULL) {
+ return NULL;
+ }
+ if (root->is_leaf()) {
+ return const_cast<BVHNode *>(root);
+ }
+ BVHNode *root8 = bvh_node_merge_children_recursively(root);
+ /* TODO(sergey): Pack children nodes to parents which has less that 4
+ * children. */
+ return root8;
}
-void BVH8::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf)
+void BVH8::pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
{
- float4 data[BVH_ONODE_LEAF_SIZE];
- memset(data, 0, sizeof(data));
- if(leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
- /* object */
- data[0].x = __int_as_float(~(leaf->lo));
- data[0].y = __int_as_float(0);
- }
- else {
- /* triangle */
- data[0].x = __int_as_float(leaf->lo);
- data[0].y = __int_as_float(leaf->hi);
- }
- data[0].z = __uint_as_float(leaf->visibility);
- if(leaf->num_triangles() != 0) {
- data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
- }
-
- memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4)*BVH_ONODE_LEAF_SIZE);
+ float4 data[BVH_ONODE_LEAF_SIZE];
+ memset(data, 0, sizeof(data));
+ if (leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
+ /* object */
+ data[0].x = __int_as_float(~(leaf->lo));
+ data[0].y = __int_as_float(0);
+ }
+ else {
+ /* triangle */
+ data[0].x = __int_as_float(leaf->lo);
+ data[0].y = __int_as_float(leaf->hi);
+ }
+ data[0].z = __uint_as_float(leaf->visibility);
+ if (leaf->num_triangles() != 0) {
+ data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
+ }
+
+ memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4) * BVH_ONODE_LEAF_SIZE);
}
-void BVH8::pack_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num)
+void BVH8::pack_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num)
{
- bool has_unaligned = false;
- /* Check whether we have to create unaligned node or all nodes are aligned
- * and we can cut some corner here.
- */
- if(params.use_unaligned_nodes) {
- for(int i = 0; i < num; i++) {
- if(en[i].node->is_unaligned) {
- has_unaligned = true;
- break;
- }
- }
- }
- if(has_unaligned) {
- /* There's no unaligned children, pack into AABB node. */
- pack_unaligned_inner(e, en, num);
- }
- else {
- /* Create unaligned node with orientation transform for each of the
- * children.
- */
- pack_aligned_inner(e, en, num);
- }
+ bool has_unaligned = false;
+ /* Check whether we have to create unaligned node or all nodes are aligned
+ * and we can cut some corner here.
+ */
+ if (params.use_unaligned_nodes) {
+ for (int i = 0; i < num; i++) {
+ if (en[i].node->is_unaligned) {
+ has_unaligned = true;
+ break;
+ }
+ }
+ }
+ if (has_unaligned) {
+ /* There's no unaligned children, pack into AABB node. */
+ pack_unaligned_inner(e, en, num);
+ }
+ else {
+ /* Create unaligned node with orientation transform for each of the
+ * children.
+ */
+ pack_aligned_inner(e, en, num);
+ }
}
-void BVH8::pack_aligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num)
+void BVH8::pack_aligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num)
{
- BoundBox bounds[8];
- int child[8];
- for(int i = 0; i < num; ++i) {
- bounds[i] = en[i].node->bounds;
- child[i] = en[i].encodeIdx();
- }
- pack_aligned_node(e.idx,
- bounds,
- child,
- e.node->visibility,
- e.node->time_from,
- e.node->time_to,
- num);
+ BoundBox bounds[8];
+ int child[8];
+ for (int i = 0; i < num; ++i) {
+ bounds[i] = en[i].node->bounds;
+ child[i] = en[i].encodeIdx();
+ }
+ pack_aligned_node(
+ e.idx, bounds, child, e.node->visibility, e.node->time_from, e.node->time_to, num);
}
void BVH8::pack_aligned_node(int idx,
@@ -208,66 +196,64 @@ void BVH8::pack_aligned_node(int idx,
const float time_to,
const int num)
{
- float8 data[8];
- memset(data, 0, sizeof(data));
+ float8 data[8];
+ memset(data, 0, sizeof(data));
- data[0].a = __uint_as_float(visibility & ~PATH_RAY_NODE_UNALIGNED);
- data[0].b = time_from;
- data[0].c = time_to;
+ data[0].a = __uint_as_float(visibility & ~PATH_RAY_NODE_UNALIGNED);
+ data[0].b = time_from;
+ data[0].c = time_to;
- for(int i = 0; i < num; i++) {
- float3 bb_min = bounds[i].min;
- float3 bb_max = bounds[i].max;
+ for (int i = 0; i < num; i++) {
+ float3 bb_min = bounds[i].min;
+ float3 bb_max = bounds[i].max;
- data[1][i] = bb_min.x;
- data[2][i] = bb_max.x;
- data[3][i] = bb_min.y;
- data[4][i] = bb_max.y;
- data[5][i] = bb_min.z;
- data[6][i] = bb_max.z;
+ data[1][i] = bb_min.x;
+ data[2][i] = bb_max.x;
+ data[3][i] = bb_min.y;
+ data[4][i] = bb_max.y;
+ data[5][i] = bb_min.z;
+ data[6][i] = bb_max.z;
- data[7][i] = __int_as_float(child[i]);
- }
+ data[7][i] = __int_as_float(child[i]);
+ }
- for(int i = num; i < 8; i++) {
- /* We store BB which would never be recorded as intersection
- * so kernel might safely assume there are always 4 child nodes.
- */
- data[1][i] = FLT_MAX;
- data[2][i] = -FLT_MAX;
+ for (int i = num; i < 8; i++) {
+ /* We store BB which would never be recorded as intersection
+ * so kernel might safely assume there are always 4 child nodes.
+ */
+ data[1][i] = FLT_MAX;
+ data[2][i] = -FLT_MAX;
- data[3][i] = FLT_MAX;
- data[4][i] = -FLT_MAX;
+ data[3][i] = FLT_MAX;
+ data[4][i] = -FLT_MAX;
- data[5][i] = FLT_MAX;
- data[6][i] = -FLT_MAX;
+ data[5][i] = FLT_MAX;
+ data[6][i] = -FLT_MAX;
- data[7][i] = __int_as_float(0);
- }
+ data[7][i] = __int_as_float(0);
+ }
- memcpy(&pack.nodes[idx], data, sizeof(float4)*BVH_ONODE_SIZE);
+ memcpy(&pack.nodes[idx], data, sizeof(float4) * BVH_ONODE_SIZE);
}
-void BVH8::pack_unaligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num)
+void BVH8::pack_unaligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num)
{
- Transform aligned_space[8];
- BoundBox bounds[8];
- int child[8];
- for(int i = 0; i < num; ++i) {
- aligned_space[i] = en[i].node->get_aligned_space();
- bounds[i] = en[i].node->bounds;
- child[i] = en[i].encodeIdx();
- }
- pack_unaligned_node(e.idx,
- aligned_space,
- bounds,
- child,
- e.node->visibility,
- e.node->time_from,
- e.node->time_to,
- num);
+ Transform aligned_space[8];
+ BoundBox bounds[8];
+ int child[8];
+ for (int i = 0; i < num; ++i) {
+ aligned_space[i] = en[i].node->get_aligned_space();
+ bounds[i] = en[i].node->bounds;
+ child[i] = en[i].encodeIdx();
+ }
+ pack_unaligned_node(e.idx,
+ aligned_space,
+ bounds,
+ child,
+ e.node->visibility,
+ e.node->time_from,
+ e.node->time_to,
+ num);
}
void BVH8::pack_unaligned_node(int idx,
@@ -279,283 +265,275 @@ void BVH8::pack_unaligned_node(int idx,
const float time_to,
const int num)
{
- float8 data[BVH_UNALIGNED_ONODE_SIZE];
- memset(data, 0, sizeof(data));
+ float8 data[BVH_UNALIGNED_ONODE_SIZE];
+ memset(data, 0, sizeof(data));
- data[0].a = __uint_as_float(visibility | PATH_RAY_NODE_UNALIGNED);
- data[0].b = time_from;
- data[0].c = time_to;
+ data[0].a = __uint_as_float(visibility | PATH_RAY_NODE_UNALIGNED);
+ data[0].b = time_from;
+ data[0].c = time_to;
- for(int i = 0; i < num; i++) {
- Transform space = BVHUnaligned::compute_node_transform(
- bounds[i],
- aligned_space[i]);
+ for (int i = 0; i < num; i++) {
+ Transform space = BVHUnaligned::compute_node_transform(bounds[i], aligned_space[i]);
- data[1][i] = space.x.x;
- data[2][i] = space.x.y;
- data[3][i] = space.x.z;
+ data[1][i] = space.x.x;
+ data[2][i] = space.x.y;
+ data[3][i] = space.x.z;
- data[4][i] = space.y.x;
- data[5][i] = space.y.y;
- data[6][i] = space.y.z;
+ data[4][i] = space.y.x;
+ data[5][i] = space.y.y;
+ data[6][i] = space.y.z;
- data[7][i] = space.z.x;
- data[8][i] = space.z.y;
- data[9][i] = space.z.z;
+ data[7][i] = space.z.x;
+ data[8][i] = space.z.y;
+ data[9][i] = space.z.z;
- data[10][i] = space.x.w;
- data[11][i] = space.y.w;
- data[12][i] = space.z.w;
+ data[10][i] = space.x.w;
+ data[11][i] = space.y.w;
+ data[12][i] = space.z.w;
- data[13][i] = __int_as_float(child[i]);
- }
+ data[13][i] = __int_as_float(child[i]);
+ }
- for(int i = num; i < 8; i++) {
- /* We store BB which would never be recorded as intersection
- * so kernel might safely assume there are always 4 child nodes.
- */
+ for (int i = num; i < 8; i++) {
+ /* We store BB which would never be recorded as intersection
+ * so kernel might safely assume there are always 4 child nodes.
+ */
- data[1][i] = NAN;
- data[2][i] = NAN;
- data[3][i] = NAN;
+ data[1][i] = NAN;
+ data[2][i] = NAN;
+ data[3][i] = NAN;
- data[4][i] = NAN;
- data[5][i] = NAN;
- data[6][i] = NAN;
+ data[4][i] = NAN;
+ data[5][i] = NAN;
+ data[6][i] = NAN;
- data[7][i] = NAN;
- data[8][i] = NAN;
- data[9][i] = NAN;
+ data[7][i] = NAN;
+ data[8][i] = NAN;
+ data[9][i] = NAN;
- data[10][i] = NAN;
- data[11][i] = NAN;
- data[12][i] = NAN;
+ data[10][i] = NAN;
+ data[11][i] = NAN;
+ data[12][i] = NAN;
- data[13][i] = __int_as_float(0);
- }
+ data[13][i] = __int_as_float(0);
+ }
- memcpy(&pack.nodes[idx], data, sizeof(float4)*BVH_UNALIGNED_ONODE_SIZE);
+ memcpy(&pack.nodes[idx], data, sizeof(float4) * BVH_UNALIGNED_ONODE_SIZE);
}
/* Quad SIMD Nodes */
void BVH8::pack_nodes(const BVHNode *root)
{
- /* Calculate size of the arrays required. */
- const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
- const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
- assert(num_leaf_nodes <= num_nodes);
- const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
- size_t node_size;
- if(params.use_unaligned_nodes) {
- const size_t num_unaligned_nodes =
- root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
- node_size = (num_unaligned_nodes * BVH_UNALIGNED_ONODE_SIZE) +
- (num_inner_nodes - num_unaligned_nodes) * BVH_ONODE_SIZE;
- }
- else {
- node_size = num_inner_nodes * BVH_ONODE_SIZE;
- }
- /* Resize arrays. */
- pack.nodes.clear();
- pack.leaf_nodes.clear();
- /* For top level BVH, first merge existing BVH's so we know the offsets. */
- if(params.top_level) {
- pack_instances(node_size, num_leaf_nodes*BVH_ONODE_LEAF_SIZE);
- }
- else {
- pack.nodes.resize(node_size);
- pack.leaf_nodes.resize(num_leaf_nodes*BVH_ONODE_LEAF_SIZE);
- }
-
- int nextNodeIdx = 0, nextLeafNodeIdx = 0;
-
- vector<BVHStackEntry> stack;
- stack.reserve(BVHParams::MAX_DEPTH*2);
- if(root->is_leaf()) {
- stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
- }
- else {
- stack.push_back(BVHStackEntry(root, nextNodeIdx));
- nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_ONODE_SIZE
- : BVH_ONODE_SIZE;
- }
-
- while(stack.size()) {
- BVHStackEntry e = stack.back();
- stack.pop_back();
-
- if(e.node->is_leaf()) {
- /* leaf node */
- const LeafNode *leaf = reinterpret_cast<const LeafNode*>(e.node);
- pack_leaf(e, leaf);
- }
- else {
- /* Inner node. */
- /* Collect nodes. */
- const BVHNode *children[8];
- int num_children = e.node->num_children();
- /* Push entries on the stack. */
- for(int i = 0; i < num_children; ++i) {
- int idx;
- children[i] = e.node->get_child(i);
- if(children[i]->is_leaf()) {
- idx = nextLeafNodeIdx++;
- }
- else {
- idx = nextNodeIdx;
- nextNodeIdx += children[i]->has_unaligned()
- ? BVH_UNALIGNED_ONODE_SIZE
- : BVH_ONODE_SIZE;
- }
- stack.push_back(BVHStackEntry(children[i], idx));
- }
- /* Set node. */
- pack_inner(e, &stack[stack.size() - num_children], num_children);
- }
- }
-
- assert(node_size == nextNodeIdx);
- /* Root index to start traversal at, to handle case of single leaf node. */
- pack.root_index = (root->is_leaf()) ? -1 : 0;
+ /* Calculate size of the arrays required. */
+ const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
+ const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
+ assert(num_leaf_nodes <= num_nodes);
+ const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
+ size_t node_size;
+ if (params.use_unaligned_nodes) {
+ const size_t num_unaligned_nodes = root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
+ node_size = (num_unaligned_nodes * BVH_UNALIGNED_ONODE_SIZE) +
+ (num_inner_nodes - num_unaligned_nodes) * BVH_ONODE_SIZE;
+ }
+ else {
+ node_size = num_inner_nodes * BVH_ONODE_SIZE;
+ }
+ /* Resize arrays. */
+ pack.nodes.clear();
+ pack.leaf_nodes.clear();
+ /* For top level BVH, first merge existing BVH's so we know the offsets. */
+ if (params.top_level) {
+ pack_instances(node_size, num_leaf_nodes * BVH_ONODE_LEAF_SIZE);
+ }
+ else {
+ pack.nodes.resize(node_size);
+ pack.leaf_nodes.resize(num_leaf_nodes * BVH_ONODE_LEAF_SIZE);
+ }
+
+ int nextNodeIdx = 0, nextLeafNodeIdx = 0;
+
+ vector<BVHStackEntry> stack;
+ stack.reserve(BVHParams::MAX_DEPTH * 2);
+ if (root->is_leaf()) {
+ stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
+ }
+ else {
+ stack.push_back(BVHStackEntry(root, nextNodeIdx));
+ nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_ONODE_SIZE : BVH_ONODE_SIZE;
+ }
+
+ while (stack.size()) {
+ BVHStackEntry e = stack.back();
+ stack.pop_back();
+
+ if (e.node->is_leaf()) {
+ /* leaf node */
+ const LeafNode *leaf = reinterpret_cast<const LeafNode *>(e.node);
+ pack_leaf(e, leaf);
+ }
+ else {
+ /* Inner node. */
+ /* Collect nodes. */
+ const BVHNode *children[8];
+ int num_children = e.node->num_children();
+ /* Push entries on the stack. */
+ for (int i = 0; i < num_children; ++i) {
+ int idx;
+ children[i] = e.node->get_child(i);
+ if (children[i]->is_leaf()) {
+ idx = nextLeafNodeIdx++;
+ }
+ else {
+ idx = nextNodeIdx;
+ nextNodeIdx += children[i]->has_unaligned() ? BVH_UNALIGNED_ONODE_SIZE : BVH_ONODE_SIZE;
+ }
+ stack.push_back(BVHStackEntry(children[i], idx));
+ }
+ /* Set node. */
+ pack_inner(e, &stack[stack.size() - num_children], num_children);
+ }
+ }
+
+ assert(node_size == nextNodeIdx);
+ /* Root index to start traversal at, to handle case of single leaf node. */
+ pack.root_index = (root->is_leaf()) ? -1 : 0;
}
void BVH8::refit_nodes()
{
- assert(!params.top_level);
+ assert(!params.top_level);
- BoundBox bbox = BoundBox::empty;
- uint visibility = 0;
- refit_node(0, (pack.root_index == -1)? true: false, bbox, visibility);
+ BoundBox bbox = BoundBox::empty;
+ uint visibility = 0;
+ refit_node(0, (pack.root_index == -1) ? true : false, bbox, visibility);
}
-void BVH8::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
+void BVH8::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
{
- if(leaf) {
- int4 *data = &pack.leaf_nodes[idx];
- int4 c = data[0];
- /* Refit leaf node. */
- for(int prim = c.x; prim < c.y; prim++) {
- int pidx = pack.prim_index[prim];
- int tob = pack.prim_object[prim];
- Object *ob = objects[tob];
-
- if(pidx == -1) {
- /* Object instance. */
- bbox.grow(ob->bounds);
- }
- else {
- /* Primitives. */
- const Mesh *mesh = ob->mesh;
-
- if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
- /* Curves. */
- int str_offset = (params.top_level) ? mesh->curve_offset : 0;
- Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
- int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
-
- curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
-
- visibility |= PATH_RAY_CURVE;
-
- /* Motion curves. */
- if(mesh->use_motion_blur) {
- Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr) {
- size_t mesh_size = mesh->curve_keys.size();
- size_t steps = mesh->motion_steps - 1;
- float3 *key_steps = attr->data_float3();
-
- for(size_t i = 0; i < steps; i++) {
- curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
- }
- }
- }
- }
- else {
- /* Triangles. */
- int tri_offset = (params.top_level) ? mesh->tri_offset : 0;
- Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
- const float3 *vpos = &mesh->verts[0];
-
- triangle.bounds_grow(vpos, bbox);
-
- /* Motion triangles. */
- if(mesh->use_motion_blur) {
- Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr) {
- size_t mesh_size = mesh->verts.size();
- size_t steps = mesh->motion_steps - 1;
- float3 *vert_steps = attr->data_float3();
-
- for(size_t i = 0; i < steps; i++) {
- triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
- }
- }
- }
- }
- }
-
- visibility |= ob->visibility;
- }
-
- float4 leaf_data[BVH_ONODE_LEAF_SIZE];
- leaf_data[0].x = __int_as_float(c.x);
- leaf_data[0].y = __int_as_float(c.y);
- leaf_data[0].z = __uint_as_float(visibility);
- leaf_data[0].w = __uint_as_float(c.w);
- memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4)*BVH_ONODE_LEAF_SIZE);
- }
- else {
- float8 *data = (float8*)&pack.nodes[idx];
- bool is_unaligned = (__float_as_uint(data[0].a) & PATH_RAY_NODE_UNALIGNED) != 0;
- /* Refit inner node, set bbox from children. */
- BoundBox child_bbox[8] = { BoundBox::empty, BoundBox::empty,
- BoundBox::empty, BoundBox::empty,
- BoundBox::empty, BoundBox::empty,
- BoundBox::empty, BoundBox::empty };
- int child[8];
- uint child_visibility[8] = { 0 };
- int num_nodes = 0;
-
- for(int i = 0; i < 8; ++i) {
- child[i] = __float_as_int(data[(is_unaligned) ? 13: 7][i]);
-
- if(child[i] != 0) {
- refit_node((child[i] < 0)? -child[i]-1: child[i], (child[i] < 0),
- child_bbox[i], child_visibility[i]);
- ++num_nodes;
- bbox.grow(child_bbox[i]);
- visibility |= child_visibility[i];
- }
- }
-
- if(is_unaligned) {
- Transform aligned_space[8] = { transform_identity(), transform_identity(),
- transform_identity(), transform_identity(),
- transform_identity(), transform_identity(),
- transform_identity(), transform_identity()};
- pack_unaligned_node(idx,
- aligned_space,
- child_bbox,
- child,
- visibility,
- 0.0f,
- 1.0f,
- num_nodes);
- }
- else {
- pack_aligned_node(idx,
- child_bbox,
- child,
- visibility,
- 0.0f,
- 1.0f,
- num_nodes);
- }
- }
+ if (leaf) {
+ int4 *data = &pack.leaf_nodes[idx];
+ int4 c = data[0];
+ /* Refit leaf node. */
+ for (int prim = c.x; prim < c.y; prim++) {
+ int pidx = pack.prim_index[prim];
+ int tob = pack.prim_object[prim];
+ Object *ob = objects[tob];
+
+ if (pidx == -1) {
+ /* Object instance. */
+ bbox.grow(ob->bounds);
+ }
+ else {
+ /* Primitives. */
+ const Mesh *mesh = ob->mesh;
+
+ if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
+ /* Curves. */
+ int str_offset = (params.top_level) ? mesh->curve_offset : 0;
+ Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
+ int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
+
+ curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
+
+ visibility |= PATH_RAY_CURVE;
+
+ /* Motion curves. */
+ if (mesh->use_motion_blur) {
+ Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr) {
+ size_t mesh_size = mesh->curve_keys.size();
+ size_t steps = mesh->motion_steps - 1;
+ float3 *key_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps; i++) {
+ curve.bounds_grow(k, key_steps + i * mesh_size, &mesh->curve_radius[0], bbox);
+ }
+ }
+ }
+ }
+ else {
+ /* Triangles. */
+ int tri_offset = (params.top_level) ? mesh->tri_offset : 0;
+ Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
+ const float3 *vpos = &mesh->verts[0];
+
+ triangle.bounds_grow(vpos, bbox);
+
+ /* Motion triangles. */
+ if (mesh->use_motion_blur) {
+ Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr) {
+ size_t mesh_size = mesh->verts.size();
+ size_t steps = mesh->motion_steps - 1;
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps; i++) {
+ triangle.bounds_grow(vert_steps + i * mesh_size, bbox);
+ }
+ }
+ }
+ }
+ }
+
+ visibility |= ob->visibility;
+ }
+
+ float4 leaf_data[BVH_ONODE_LEAF_SIZE];
+ leaf_data[0].x = __int_as_float(c.x);
+ leaf_data[0].y = __int_as_float(c.y);
+ leaf_data[0].z = __uint_as_float(visibility);
+ leaf_data[0].w = __uint_as_float(c.w);
+ memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4) * BVH_ONODE_LEAF_SIZE);
+ }
+ else {
+ float8 *data = (float8 *)&pack.nodes[idx];
+ bool is_unaligned = (__float_as_uint(data[0].a) & PATH_RAY_NODE_UNALIGNED) != 0;
+ /* Refit inner node, set bbox from children. */
+ BoundBox child_bbox[8] = {BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty};
+ int child[8];
+ uint child_visibility[8] = {0};
+ int num_nodes = 0;
+
+ for (int i = 0; i < 8; ++i) {
+ child[i] = __float_as_int(data[(is_unaligned) ? 13 : 7][i]);
+
+ if (child[i] != 0) {
+ refit_node((child[i] < 0) ? -child[i] - 1 : child[i],
+ (child[i] < 0),
+ child_bbox[i],
+ child_visibility[i]);
+ ++num_nodes;
+ bbox.grow(child_bbox[i]);
+ visibility |= child_visibility[i];
+ }
+ }
+
+ if (is_unaligned) {
+ Transform aligned_space[8] = {transform_identity(),
+ transform_identity(),
+ transform_identity(),
+ transform_identity(),
+ transform_identity(),
+ transform_identity(),
+ transform_identity(),
+ transform_identity()};
+ pack_unaligned_node(
+ idx, aligned_space, child_bbox, child, visibility, 0.0f, 1.0f, num_nodes);
+ }
+ else {
+ pack_aligned_node(idx, child_bbox, child, visibility, 0.0f, 1.0f, num_nodes);
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh8.h b/intern/cycles/bvh/bvh8.h
index 277e2f2d653..fc07eadcada 100644
--- a/intern/cycles/bvh/bvh8.h
+++ b/intern/cycles/bvh/bvh8.h
@@ -45,8 +45,8 @@ class LeafNode;
class Object;
class Progress;
-#define BVH_ONODE_SIZE 16
-#define BVH_ONODE_LEAF_SIZE 1
+#define BVH_ONODE_SIZE 16
+#define BVH_ONODE_LEAF_SIZE 1
#define BVH_UNALIGNED_ONODE_SIZE 28
/* BVH8
@@ -54,48 +54,44 @@ class Progress;
* Octo BVH, with each node having eight children, to use with SIMD instructions.
*/
class BVH8 : public BVH {
-protected:
- /* constructor */
- friend class BVH;
- BVH8(const BVHParams& params, const vector<Object*>& objects);
+ protected:
+ /* constructor */
+ friend class BVH;
+ BVH8(const BVHParams &params, const vector<Object *> &objects);
- /* Building process. */
- virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
+ /* Building process. */
+ virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
- /* pack */
- void pack_nodes(const BVHNode *root) override;
+ /* pack */
+ void pack_nodes(const BVHNode *root) override;
- void pack_leaf(const BVHStackEntry& e, const LeafNode *leaf);
- void pack_inner(const BVHStackEntry& e, const BVHStackEntry *en, int num);
+ void pack_leaf(const BVHStackEntry &e, const LeafNode *leaf);
+ void pack_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num);
- void pack_aligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num);
- void pack_aligned_node(int idx,
- const BoundBox *bounds,
- const int *child,
- const uint visibility,
- const float time_from,
- const float time_to,
- const int num);
+ void pack_aligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num);
+ void pack_aligned_node(int idx,
+ const BoundBox *bounds,
+ const int *child,
+ const uint visibility,
+ const float time_from,
+ const float time_to,
+ const int num);
- void pack_unaligned_inner(const BVHStackEntry& e,
- const BVHStackEntry *en,
- int num);
- void pack_unaligned_node(int idx,
- const Transform *aligned_space,
- const BoundBox *bounds,
- const int *child,
- const uint visibility,
- const float time_from,
- const float time_to,
- const int num);
+ void pack_unaligned_inner(const BVHStackEntry &e, const BVHStackEntry *en, int num);
+ void pack_unaligned_node(int idx,
+ const Transform *aligned_space,
+ const BoundBox *bounds,
+ const int *child,
+ const uint visibility,
+ const float time_from,
+ const float time_to,
+ const int num);
- /* refit */
- void refit_nodes() override;
- void refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility);
+ /* refit */
+ void refit_nodes() override;
+ void refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility);
};
CCL_NAMESPACE_END
-#endif /* __BVH8_H__ */
+#endif /* __BVH8_H__ */
diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp
index f574f31b358..d51143c578e 100644
--- a/intern/cycles/bvh/bvh_binning.cpp
+++ b/intern/cycles/bvh/bvh_binning.cpp
@@ -29,225 +29,265 @@ CCL_NAMESPACE_BEGIN
/* SSE replacements */
-__forceinline void prefetch_L1 (const void* /*ptr*/) { }
-__forceinline void prefetch_L2 (const void* /*ptr*/) { }
-__forceinline void prefetch_L3 (const void* /*ptr*/) { }
-__forceinline void prefetch_NTA(const void* /*ptr*/) { }
+__forceinline void prefetch_L1(const void * /*ptr*/)
+{
+}
+__forceinline void prefetch_L2(const void * /*ptr*/)
+{
+}
+__forceinline void prefetch_L3(const void * /*ptr*/)
+{
+}
+__forceinline void prefetch_NTA(const void * /*ptr*/)
+{
+}
-template<size_t src> __forceinline float extract(const int4& b)
-{ return b[src]; }
-template<size_t dst> __forceinline const float4 insert(const float4& a, const float b)
-{ float4 r = a; r[dst] = b; return r; }
+template<size_t src> __forceinline float extract(const int4 &b)
+{
+ return b[src];
+}
+template<size_t dst> __forceinline const float4 insert(const float4 &a, const float b)
+{
+ float4 r = a;
+ r[dst] = b;
+ return r;
+}
-__forceinline int get_best_dimension(const float4& bestSAH)
+__forceinline int get_best_dimension(const float4 &bestSAH)
{
- // return (int)__bsf(movemask(reduce_min(bestSAH) == bestSAH));
+ // return (int)__bsf(movemask(reduce_min(bestSAH) == bestSAH));
- float minSAH = min(bestSAH.x, min(bestSAH.y, bestSAH.z));
+ float minSAH = min(bestSAH.x, min(bestSAH.y, bestSAH.z));
- if(bestSAH.x == minSAH) return 0;
- else if(bestSAH.y == minSAH) return 1;
- else return 2;
+ if (bestSAH.x == minSAH)
+ return 0;
+ else if (bestSAH.y == minSAH)
+ return 1;
+ else
+ return 2;
}
/* BVH Object Binning */
-BVHObjectBinning::BVHObjectBinning(const BVHRange& job,
+BVHObjectBinning::BVHObjectBinning(const BVHRange &job,
BVHReference *prims,
const BVHUnaligned *unaligned_heuristic,
const Transform *aligned_space)
-: BVHRange(job),
- splitSAH(FLT_MAX),
- dim(0),
- pos(0),
- unaligned_heuristic_(unaligned_heuristic),
- aligned_space_(aligned_space)
+ : BVHRange(job),
+ splitSAH(FLT_MAX),
+ dim(0),
+ pos(0),
+ unaligned_heuristic_(unaligned_heuristic),
+ aligned_space_(aligned_space)
{
- if(aligned_space_ == NULL) {
- bounds_ = bounds();
- cent_bounds_ = cent_bounds();
- }
- else {
- /* TODO(sergey): With some additional storage we can avoid
- * need in re-calculating this.
- */
- bounds_ = unaligned_heuristic->compute_aligned_boundbox(
- *this,
- prims,
- *aligned_space,
- &cent_bounds_);
- }
-
- /* compute number of bins to use and precompute scaling factor for binning */
- num_bins = min(size_t(MAX_BINS), size_t(4.0f + 0.05f*size()));
- scale = rcp(cent_bounds_.size()) * make_float3((float)num_bins);
-
- /* initialize binning counter and bounds */
- BoundBox bin_bounds[MAX_BINS][4]; /* bounds for every bin in every dimension */
- int4 bin_count[MAX_BINS]; /* number of primitives mapped to bin */
-
- for(size_t i = 0; i < num_bins; i++) {
- bin_count[i] = make_int4(0);
- bin_bounds[i][0] = bin_bounds[i][1] = bin_bounds[i][2] = BoundBox::empty;
- }
-
- /* map geometry to bins, unrolled once */
- {
- ssize_t i;
-
- for(i = 0; i < ssize_t(size()) - 1; i += 2) {
- prefetch_L2(&prims[start() + i + 8]);
-
- /* map even and odd primitive to bin */
- const BVHReference& prim0 = prims[start() + i + 0];
- const BVHReference& prim1 = prims[start() + i + 1];
-
- BoundBox bounds0 = get_prim_bounds(prim0);
- BoundBox bounds1 = get_prim_bounds(prim1);
-
- int4 bin0 = get_bin(bounds0);
- int4 bin1 = get_bin(bounds1);
-
- /* increase bounds for bins for even primitive */
- int b00 = (int)extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(bounds0);
- int b01 = (int)extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(bounds0);
- int b02 = (int)extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(bounds0);
-
- /* increase bounds of bins for odd primitive */
- int b10 = (int)extract<0>(bin1); bin_count[b10][0]++; bin_bounds[b10][0].grow(bounds1);
- int b11 = (int)extract<1>(bin1); bin_count[b11][1]++; bin_bounds[b11][1].grow(bounds1);
- int b12 = (int)extract<2>(bin1); bin_count[b12][2]++; bin_bounds[b12][2].grow(bounds1);
- }
-
- /* for uneven number of primitives */
- if(i < ssize_t(size())) {
- /* map primitive to bin */
- const BVHReference& prim0 = prims[start() + i];
- BoundBox bounds0 = get_prim_bounds(prim0);
- int4 bin0 = get_bin(bounds0);
-
- /* increase bounds of bins */
- int b00 = (int)extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(bounds0);
- int b01 = (int)extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(bounds0);
- int b02 = (int)extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(bounds0);
- }
- }
-
- /* sweep from right to left and compute parallel prefix of merged bounds */
- float4 r_area[MAX_BINS]; /* area of bounds of primitives on the right */
- float4 r_count[MAX_BINS]; /* number of primitives on the right */
- int4 count = make_int4(0);
-
- BoundBox bx = BoundBox::empty;
- BoundBox by = BoundBox::empty;
- BoundBox bz = BoundBox::empty;
-
- for(size_t i = num_bins - 1; i > 0; i--) {
- count = count + bin_count[i];
- r_count[i] = blocks(count);
-
- bx = merge(bx,bin_bounds[i][0]); r_area[i][0] = bx.half_area();
- by = merge(by,bin_bounds[i][1]); r_area[i][1] = by.half_area();
- bz = merge(bz,bin_bounds[i][2]); r_area[i][2] = bz.half_area();
- r_area[i][3] = r_area[i][2];
- }
-
- /* sweep from left to right and compute SAH */
- int4 ii = make_int4(1);
- float4 bestSAH = make_float4(FLT_MAX);
- int4 bestSplit = make_int4(-1);
-
- count = make_int4(0);
-
- bx = BoundBox::empty;
- by = BoundBox::empty;
- bz = BoundBox::empty;
-
- for(size_t i = 1; i < num_bins; i++, ii += make_int4(1)) {
- count = count + bin_count[i-1];
-
- bx = merge(bx,bin_bounds[i-1][0]); float Ax = bx.half_area();
- by = merge(by,bin_bounds[i-1][1]); float Ay = by.half_area();
- bz = merge(bz,bin_bounds[i-1][2]); float Az = bz.half_area();
-
- float4 lCount = blocks(count);
- float4 lArea = make_float4(Ax,Ay,Az,Az);
- float4 sah = lArea*lCount + r_area[i]*r_count[i];
-
- bestSplit = select(sah < bestSAH,ii,bestSplit);
- bestSAH = min(sah,bestSAH);
- }
-
- int4 mask = float3_to_float4(cent_bounds_.size()) <= make_float4(0.0f);
- bestSAH = insert<3>(select(mask, make_float4(FLT_MAX), bestSAH), FLT_MAX);
-
- /* find best dimension */
- dim = get_best_dimension(bestSAH);
- splitSAH = bestSAH[dim];
- pos = bestSplit[dim];
- leafSAH = bounds_.half_area() * blocks(size());
+ if (aligned_space_ == NULL) {
+ bounds_ = bounds();
+ cent_bounds_ = cent_bounds();
+ }
+ else {
+ /* TODO(sergey): With some additional storage we can avoid
+ * need in re-calculating this.
+ */
+ bounds_ = unaligned_heuristic->compute_aligned_boundbox(
+ *this, prims, *aligned_space, &cent_bounds_);
+ }
+
+ /* compute number of bins to use and precompute scaling factor for binning */
+ num_bins = min(size_t(MAX_BINS), size_t(4.0f + 0.05f * size()));
+ scale = rcp(cent_bounds_.size()) * make_float3((float)num_bins);
+
+ /* initialize binning counter and bounds */
+ BoundBox bin_bounds[MAX_BINS][4]; /* bounds for every bin in every dimension */
+ int4 bin_count[MAX_BINS]; /* number of primitives mapped to bin */
+
+ for (size_t i = 0; i < num_bins; i++) {
+ bin_count[i] = make_int4(0);
+ bin_bounds[i][0] = bin_bounds[i][1] = bin_bounds[i][2] = BoundBox::empty;
+ }
+
+ /* map geometry to bins, unrolled once */
+ {
+ ssize_t i;
+
+ for (i = 0; i < ssize_t(size()) - 1; i += 2) {
+ prefetch_L2(&prims[start() + i + 8]);
+
+ /* map even and odd primitive to bin */
+ const BVHReference &prim0 = prims[start() + i + 0];
+ const BVHReference &prim1 = prims[start() + i + 1];
+
+ BoundBox bounds0 = get_prim_bounds(prim0);
+ BoundBox bounds1 = get_prim_bounds(prim1);
+
+ int4 bin0 = get_bin(bounds0);
+ int4 bin1 = get_bin(bounds1);
+
+ /* increase bounds for bins for even primitive */
+ int b00 = (int)extract<0>(bin0);
+ bin_count[b00][0]++;
+ bin_bounds[b00][0].grow(bounds0);
+ int b01 = (int)extract<1>(bin0);
+ bin_count[b01][1]++;
+ bin_bounds[b01][1].grow(bounds0);
+ int b02 = (int)extract<2>(bin0);
+ bin_count[b02][2]++;
+ bin_bounds[b02][2].grow(bounds0);
+
+ /* increase bounds of bins for odd primitive */
+ int b10 = (int)extract<0>(bin1);
+ bin_count[b10][0]++;
+ bin_bounds[b10][0].grow(bounds1);
+ int b11 = (int)extract<1>(bin1);
+ bin_count[b11][1]++;
+ bin_bounds[b11][1].grow(bounds1);
+ int b12 = (int)extract<2>(bin1);
+ bin_count[b12][2]++;
+ bin_bounds[b12][2].grow(bounds1);
+ }
+
+ /* for uneven number of primitives */
+ if (i < ssize_t(size())) {
+ /* map primitive to bin */
+ const BVHReference &prim0 = prims[start() + i];
+ BoundBox bounds0 = get_prim_bounds(prim0);
+ int4 bin0 = get_bin(bounds0);
+
+ /* increase bounds of bins */
+ int b00 = (int)extract<0>(bin0);
+ bin_count[b00][0]++;
+ bin_bounds[b00][0].grow(bounds0);
+ int b01 = (int)extract<1>(bin0);
+ bin_count[b01][1]++;
+ bin_bounds[b01][1].grow(bounds0);
+ int b02 = (int)extract<2>(bin0);
+ bin_count[b02][2]++;
+ bin_bounds[b02][2].grow(bounds0);
+ }
+ }
+
+ /* sweep from right to left and compute parallel prefix of merged bounds */
+ float4 r_area[MAX_BINS]; /* area of bounds of primitives on the right */
+ float4 r_count[MAX_BINS]; /* number of primitives on the right */
+ int4 count = make_int4(0);
+
+ BoundBox bx = BoundBox::empty;
+ BoundBox by = BoundBox::empty;
+ BoundBox bz = BoundBox::empty;
+
+ for (size_t i = num_bins - 1; i > 0; i--) {
+ count = count + bin_count[i];
+ r_count[i] = blocks(count);
+
+ bx = merge(bx, bin_bounds[i][0]);
+ r_area[i][0] = bx.half_area();
+ by = merge(by, bin_bounds[i][1]);
+ r_area[i][1] = by.half_area();
+ bz = merge(bz, bin_bounds[i][2]);
+ r_area[i][2] = bz.half_area();
+ r_area[i][3] = r_area[i][2];
+ }
+
+ /* sweep from left to right and compute SAH */
+ int4 ii = make_int4(1);
+ float4 bestSAH = make_float4(FLT_MAX);
+ int4 bestSplit = make_int4(-1);
+
+ count = make_int4(0);
+
+ bx = BoundBox::empty;
+ by = BoundBox::empty;
+ bz = BoundBox::empty;
+
+ for (size_t i = 1; i < num_bins; i++, ii += make_int4(1)) {
+ count = count + bin_count[i - 1];
+
+ bx = merge(bx, bin_bounds[i - 1][0]);
+ float Ax = bx.half_area();
+ by = merge(by, bin_bounds[i - 1][1]);
+ float Ay = by.half_area();
+ bz = merge(bz, bin_bounds[i - 1][2]);
+ float Az = bz.half_area();
+
+ float4 lCount = blocks(count);
+ float4 lArea = make_float4(Ax, Ay, Az, Az);
+ float4 sah = lArea * lCount + r_area[i] * r_count[i];
+
+ bestSplit = select(sah < bestSAH, ii, bestSplit);
+ bestSAH = min(sah, bestSAH);
+ }
+
+ int4 mask = float3_to_float4(cent_bounds_.size()) <= make_float4(0.0f);
+ bestSAH = insert<3>(select(mask, make_float4(FLT_MAX), bestSAH), FLT_MAX);
+
+ /* find best dimension */
+ dim = get_best_dimension(bestSAH);
+ splitSAH = bestSAH[dim];
+ pos = bestSplit[dim];
+ leafSAH = bounds_.half_area() * blocks(size());
}
-void BVHObjectBinning::split(BVHReference* prims,
- BVHObjectBinning& left_o,
- BVHObjectBinning& right_o) const
+void BVHObjectBinning::split(BVHReference *prims,
+ BVHObjectBinning &left_o,
+ BVHObjectBinning &right_o) const
{
- size_t N = size();
-
- BoundBox lgeom_bounds = BoundBox::empty;
- BoundBox rgeom_bounds = BoundBox::empty;
- BoundBox lcent_bounds = BoundBox::empty;
- BoundBox rcent_bounds = BoundBox::empty;
-
- ssize_t l = 0, r = N-1;
-
- while(l <= r) {
- prefetch_L2(&prims[start() + l + 8]);
- prefetch_L2(&prims[start() + r - 8]);
-
- BVHReference prim = prims[start() + l];
- BoundBox unaligned_bounds = get_prim_bounds(prim);
- float3 unaligned_center = unaligned_bounds.center2();
- float3 center = prim.bounds().center2();
-
- if(get_bin(unaligned_center)[dim] < pos) {
- lgeom_bounds.grow(prim.bounds());
- lcent_bounds.grow(center);
- l++;
- }
- else {
- rgeom_bounds.grow(prim.bounds());
- rcent_bounds.grow(center);
- swap(prims[start()+l],prims[start()+r]);
- r--;
- }
- }
- /* finish */
- if(l != 0 && N-1-r != 0) {
- right_o = BVHObjectBinning(BVHRange(rgeom_bounds, rcent_bounds, start() + l, N-1-r), prims);
- left_o = BVHObjectBinning(BVHRange(lgeom_bounds, lcent_bounds, start(), l), prims);
- return;
- }
-
- /* object medium split if we did not make progress, can happen when all
- * primitives have same centroid */
- lgeom_bounds = BoundBox::empty;
- rgeom_bounds = BoundBox::empty;
- lcent_bounds = BoundBox::empty;
- rcent_bounds = BoundBox::empty;
-
- for(size_t i = 0; i < N/2; i++) {
- lgeom_bounds.grow(prims[start()+i].bounds());
- lcent_bounds.grow(prims[start()+i].bounds().center2());
- }
-
- for(size_t i = N/2; i < N; i++) {
- rgeom_bounds.grow(prims[start()+i].bounds());
- rcent_bounds.grow(prims[start()+i].bounds().center2());
- }
-
- right_o = BVHObjectBinning(BVHRange(rgeom_bounds, rcent_bounds, start() + N/2, N/2 + N%2), prims);
- left_o = BVHObjectBinning(BVHRange(lgeom_bounds, lcent_bounds, start(), N/2), prims);
+ size_t N = size();
+
+ BoundBox lgeom_bounds = BoundBox::empty;
+ BoundBox rgeom_bounds = BoundBox::empty;
+ BoundBox lcent_bounds = BoundBox::empty;
+ BoundBox rcent_bounds = BoundBox::empty;
+
+ ssize_t l = 0, r = N - 1;
+
+ while (l <= r) {
+ prefetch_L2(&prims[start() + l + 8]);
+ prefetch_L2(&prims[start() + r - 8]);
+
+ BVHReference prim = prims[start() + l];
+ BoundBox unaligned_bounds = get_prim_bounds(prim);
+ float3 unaligned_center = unaligned_bounds.center2();
+ float3 center = prim.bounds().center2();
+
+ if (get_bin(unaligned_center)[dim] < pos) {
+ lgeom_bounds.grow(prim.bounds());
+ lcent_bounds.grow(center);
+ l++;
+ }
+ else {
+ rgeom_bounds.grow(prim.bounds());
+ rcent_bounds.grow(center);
+ swap(prims[start() + l], prims[start() + r]);
+ r--;
+ }
+ }
+ /* finish */
+ if (l != 0 && N - 1 - r != 0) {
+ right_o = BVHObjectBinning(BVHRange(rgeom_bounds, rcent_bounds, start() + l, N - 1 - r),
+ prims);
+ left_o = BVHObjectBinning(BVHRange(lgeom_bounds, lcent_bounds, start(), l), prims);
+ return;
+ }
+
+ /* object medium split if we did not make progress, can happen when all
+ * primitives have same centroid */
+ lgeom_bounds = BoundBox::empty;
+ rgeom_bounds = BoundBox::empty;
+ lcent_bounds = BoundBox::empty;
+ rcent_bounds = BoundBox::empty;
+
+ for (size_t i = 0; i < N / 2; i++) {
+ lgeom_bounds.grow(prims[start() + i].bounds());
+ lcent_bounds.grow(prims[start() + i].bounds().center2());
+ }
+
+ for (size_t i = N / 2; i < N; i++) {
+ rgeom_bounds.grow(prims[start() + i].bounds());
+ rcent_bounds.grow(prims[start() + i].bounds().center2());
+ }
+
+ right_o = BVHObjectBinning(BVHRange(rgeom_bounds, rcent_bounds, start() + N / 2, N / 2 + N % 2),
+ prims);
+ left_o = BVHObjectBinning(BVHRange(lgeom_bounds, lcent_bounds, start(), N / 2), prims);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_binning.h b/intern/cycles/bvh/bvh_binning.h
index c2e259b1696..ae6dba2805d 100644
--- a/intern/cycles/bvh/bvh_binning.h
+++ b/intern/cycles/bvh/bvh_binning.h
@@ -34,81 +34,82 @@ class BVHBuild;
* location to different sets. The SAH is evaluated by computing the number of
* blocks occupied by the primitives in the partitions. */
-class BVHObjectBinning : public BVHRange
-{
-public:
- __forceinline BVHObjectBinning() : leafSAH(FLT_MAX) {}
-
- BVHObjectBinning(const BVHRange& job,
- BVHReference *prims,
- const BVHUnaligned *unaligned_heuristic = NULL,
- const Transform *aligned_space = NULL);
-
- void split(BVHReference *prims,
- BVHObjectBinning& left_o,
- BVHObjectBinning& right_o) const;
-
- __forceinline const BoundBox& unaligned_bounds() { return bounds_; }
-
- float splitSAH; /* SAH cost of the best split */
- float leafSAH; /* SAH cost of creating a leaf */
-
-protected:
- int dim; /* best split dimension */
- int pos; /* best split position */
- size_t num_bins; /* actual number of bins to use */
- float3 scale; /* scaling factor to compute bin */
-
- /* Effective bounds and centroid bounds. */
- BoundBox bounds_;
- BoundBox cent_bounds_;
-
- const BVHUnaligned *unaligned_heuristic_;
- const Transform *aligned_space_;
-
- enum { MAX_BINS = 32 };
- enum { LOG_BLOCK_SIZE = 2 };
-
- /* computes the bin numbers for each dimension for a box. */
- __forceinline int4 get_bin(const BoundBox& box) const
- {
- int4 a = make_int4((box.center2() - cent_bounds_.min)*scale - make_float3(0.5f));
- int4 mn = make_int4(0);
- int4 mx = make_int4((int)num_bins-1);
-
- return clamp(a, mn, mx);
- }
-
- /* computes the bin numbers for each dimension for a point. */
- __forceinline int4 get_bin(const float3& c) const
- {
- return make_int4((c - cent_bounds_.min)*scale - make_float3(0.5f));
- }
-
- /* compute the number of blocks occupied for each dimension. */
- __forceinline float4 blocks(const int4& a) const
- {
- return make_float4((a + make_int4((1 << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE);
- }
-
- /* compute the number of blocks occupied in one dimension. */
- __forceinline int blocks(size_t a) const
- {
- return (int)((a+((1LL << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE);
- }
-
- __forceinline BoundBox get_prim_bounds(const BVHReference& prim) const
- {
- if(aligned_space_ == NULL) {
- return prim.bounds();
- }
- else {
- return unaligned_heuristic_->compute_aligned_prim_boundbox(
- prim, *aligned_space_);
- }
- }
+class BVHObjectBinning : public BVHRange {
+ public:
+ __forceinline BVHObjectBinning() : leafSAH(FLT_MAX)
+ {
+ }
+
+ BVHObjectBinning(const BVHRange &job,
+ BVHReference *prims,
+ const BVHUnaligned *unaligned_heuristic = NULL,
+ const Transform *aligned_space = NULL);
+
+ void split(BVHReference *prims, BVHObjectBinning &left_o, BVHObjectBinning &right_o) const;
+
+ __forceinline const BoundBox &unaligned_bounds()
+ {
+ return bounds_;
+ }
+
+ float splitSAH; /* SAH cost of the best split */
+ float leafSAH; /* SAH cost of creating a leaf */
+
+ protected:
+ int dim; /* best split dimension */
+ int pos; /* best split position */
+ size_t num_bins; /* actual number of bins to use */
+ float3 scale; /* scaling factor to compute bin */
+
+ /* Effective bounds and centroid bounds. */
+ BoundBox bounds_;
+ BoundBox cent_bounds_;
+
+ const BVHUnaligned *unaligned_heuristic_;
+ const Transform *aligned_space_;
+
+ enum { MAX_BINS = 32 };
+ enum { LOG_BLOCK_SIZE = 2 };
+
+ /* computes the bin numbers for each dimension for a box. */
+ __forceinline int4 get_bin(const BoundBox &box) const
+ {
+ int4 a = make_int4((box.center2() - cent_bounds_.min) * scale - make_float3(0.5f));
+ int4 mn = make_int4(0);
+ int4 mx = make_int4((int)num_bins - 1);
+
+ return clamp(a, mn, mx);
+ }
+
+ /* computes the bin numbers for each dimension for a point. */
+ __forceinline int4 get_bin(const float3 &c) const
+ {
+ return make_int4((c - cent_bounds_.min) * scale - make_float3(0.5f));
+ }
+
+ /* compute the number of blocks occupied for each dimension. */
+ __forceinline float4 blocks(const int4 &a) const
+ {
+ return make_float4((a + make_int4((1 << LOG_BLOCK_SIZE) - 1)) >> LOG_BLOCK_SIZE);
+ }
+
+ /* compute the number of blocks occupied in one dimension. */
+ __forceinline int blocks(size_t a) const
+ {
+ return (int)((a + ((1LL << LOG_BLOCK_SIZE) - 1)) >> LOG_BLOCK_SIZE);
+ }
+
+ __forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
+ {
+ if (aligned_space_ == NULL) {
+ return prim.bounds();
+ }
+ else {
+ return unaligned_heuristic_->compute_aligned_prim_boundbox(prim, *aligned_space_);
+ }
+ }
};
CCL_NAMESPACE_END
-#endif /* __BVH_BINNING_H__ */
+#endif /* __BVH_BINNING_H__ */
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index c0b3d683e37..1d9b006e8cb 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -41,72 +41,65 @@ CCL_NAMESPACE_BEGIN
/* BVH Build Task */
class BVHBuildTask : public Task {
-public:
- BVHBuildTask(BVHBuild *build,
- InnerNode *node,
- int child,
- const BVHObjectBinning& range,
- int level)
- : range_(range)
- {
- run = function_bind(&BVHBuild::thread_build_node,
- build,
- node,
- child,
- &range_,
- level);
- }
-private:
- BVHObjectBinning range_;
+ public:
+ BVHBuildTask(
+ BVHBuild *build, InnerNode *node, int child, const BVHObjectBinning &range, int level)
+ : range_(range)
+ {
+ run = function_bind(&BVHBuild::thread_build_node, build, node, child, &range_, level);
+ }
+
+ private:
+ BVHObjectBinning range_;
};
class BVHSpatialSplitBuildTask : public Task {
-public:
- BVHSpatialSplitBuildTask(BVHBuild *build,
- InnerNode *node,
- int child,
- const BVHRange& range,
- const vector<BVHReference>& references,
- int level)
- : range_(range),
- references_(references.begin() + range.start(),
- references.begin() + range.end())
- {
- range_.set_start(0);
- run = function_bind(&BVHBuild::thread_build_spatial_split_node,
- build,
- node,
- child,
- &range_,
- &references_,
- level,
- _1);
- }
-private:
- BVHRange range_;
- vector<BVHReference> references_;
+ public:
+ BVHSpatialSplitBuildTask(BVHBuild *build,
+ InnerNode *node,
+ int child,
+ const BVHRange &range,
+ const vector<BVHReference> &references,
+ int level)
+ : range_(range),
+ references_(references.begin() + range.start(), references.begin() + range.end())
+ {
+ range_.set_start(0);
+ run = function_bind(&BVHBuild::thread_build_spatial_split_node,
+ build,
+ node,
+ child,
+ &range_,
+ &references_,
+ level,
+ _1);
+ }
+
+ private:
+ BVHRange range_;
+ vector<BVHReference> references_;
};
/* Constructor / Destructor */
-BVHBuild::BVHBuild(const vector<Object*>& objects_,
- array<int>& prim_type_,
- array<int>& prim_index_,
- array<int>& prim_object_,
- array<float2>& prim_time_,
- const BVHParams& params_,
- Progress& progress_)
- : objects(objects_),
- prim_type(prim_type_),
- prim_index(prim_index_),
- prim_object(prim_object_),
- prim_time(prim_time_),
- params(params_),
- progress(progress_),
- progress_start_time(0.0),
- unaligned_heuristic(objects_)
+BVHBuild::BVHBuild(const vector<Object *> &objects_,
+ array<int> &prim_type_,
+ array<int> &prim_index_,
+ array<int> &prim_object_,
+ array<float2> &prim_time_,
+ const BVHParams &params_,
+ Progress &progress_)
+ : objects(objects_),
+ prim_type(prim_type_),
+ prim_index(prim_index_),
+ prim_object(prim_object_),
+ prim_time(prim_time_),
+ params(params_),
+ progress(progress_),
+ progress_start_time(0.0),
+ unaligned_heuristic(objects_)
{
- spatial_min_overlap = 0.0f;
+ spatial_min_overlap = 0.0f;
}
BVHBuild::~BVHBuild()
@@ -115,467 +108,440 @@ BVHBuild::~BVHBuild()
/* Adding References */
-void BVHBuild::add_reference_triangles(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *mesh, int i)
{
- const Attribute *attr_mP = NULL;
- if(mesh->has_motion_blur()) {
- attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- }
- const size_t num_triangles = mesh->num_triangles();
- for(uint j = 0; j < num_triangles; j++) {
- Mesh::Triangle t = mesh->get_triangle(j);
- const float3 *verts = &mesh->verts[0];
- if(attr_mP == NULL) {
- BoundBox bounds = BoundBox::empty;
- t.bounds_grow(verts, bounds);
- if(bounds.valid() && t.valid(verts)) {
- references.push_back(BVHReference(bounds,
- j,
- i,
- PRIMITIVE_TRIANGLE));
- root.grow(bounds);
- center.grow(bounds.center2());
- }
- }
- else if(params.num_motion_triangle_steps == 0 || params.use_spatial_split) {
- /* Motion triangles, simple case: single node for the whole
- * primitive. Lowest memory footprint and faster BVH build but
- * least optimal ray-tracing.
- */
- /* TODO(sergey): Support motion steps for spatially split BVH. */
- const size_t num_verts = mesh->verts.size();
- const size_t num_steps = mesh->motion_steps;
- const float3 *vert_steps = attr_mP->data_float3();
- BoundBox bounds = BoundBox::empty;
- t.bounds_grow(verts, bounds);
- for(size_t step = 0; step < num_steps - 1; step++) {
- t.bounds_grow(vert_steps + step*num_verts, bounds);
- }
- if(bounds.valid()) {
- references.push_back(
- BVHReference(bounds,
- j,
- i,
- PRIMITIVE_MOTION_TRIANGLE));
- root.grow(bounds);
- center.grow(bounds.center2());
- }
- }
- else {
- /* Motion triangles, trace optimized case: we split triangle
- * primitives into separate nodes for each of the time steps.
- * This way we minimize overlap of neighbor curve primitives.
- */
- const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
- const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
- const size_t num_verts = mesh->verts.size();
- const size_t num_steps = mesh->motion_steps;
- const float3 *vert_steps = attr_mP->data_float3();
- /* Calculate bounding box of the previous time step.
- * Will be reused later to avoid duplicated work on
- * calculating BVH time step boundbox.
- */
- float3 prev_verts[3];
- t.motion_verts(verts,
- vert_steps,
- num_verts,
- num_steps,
- 0.0f,
- prev_verts);
- BoundBox prev_bounds = BoundBox::empty;
- prev_bounds.grow(prev_verts[0]);
- prev_bounds.grow(prev_verts[1]);
- prev_bounds.grow(prev_verts[2]);
- /* Create all primitive time steps, */
- for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
- const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
- float3 curr_verts[3];
- t.motion_verts(verts,
- vert_steps,
- num_verts,
- num_steps,
- curr_time,
- curr_verts);
- BoundBox curr_bounds = BoundBox::empty;
- curr_bounds.grow(curr_verts[0]);
- curr_bounds.grow(curr_verts[1]);
- curr_bounds.grow(curr_verts[2]);
- BoundBox bounds = prev_bounds;
- bounds.grow(curr_bounds);
- if(bounds.valid()) {
- const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
- references.push_back(
- BVHReference(bounds,
- j,
- i,
- PRIMITIVE_MOTION_TRIANGLE,
- prev_time,
- curr_time));
- root.grow(bounds);
- center.grow(bounds.center2());
- }
- /* Current time boundbox becomes previous one for the
- * next time step.
- */
- prev_bounds = curr_bounds;
- }
- }
- }
+ const Attribute *attr_mP = NULL;
+ if (mesh->has_motion_blur()) {
+ attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+ const size_t num_triangles = mesh->num_triangles();
+ for (uint j = 0; j < num_triangles; j++) {
+ Mesh::Triangle t = mesh->get_triangle(j);
+ const float3 *verts = &mesh->verts[0];
+ if (attr_mP == NULL) {
+ BoundBox bounds = BoundBox::empty;
+ t.bounds_grow(verts, bounds);
+ if (bounds.valid() && t.valid(verts)) {
+ references.push_back(BVHReference(bounds, j, i, PRIMITIVE_TRIANGLE));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else if (params.num_motion_triangle_steps == 0 || params.use_spatial_split) {
+ /* Motion triangles, simple case: single node for the whole
+ * primitive. Lowest memory footprint and faster BVH build but
+ * least optimal ray-tracing.
+ */
+ /* TODO(sergey): Support motion steps for spatially split BVH. */
+ const size_t num_verts = mesh->verts.size();
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *vert_steps = attr_mP->data_float3();
+ BoundBox bounds = BoundBox::empty;
+ t.bounds_grow(verts, bounds);
+ for (size_t step = 0; step < num_steps - 1; step++) {
+ t.bounds_grow(vert_steps + step * num_verts, bounds);
+ }
+ if (bounds.valid()) {
+ references.push_back(BVHReference(bounds, j, i, PRIMITIVE_MOTION_TRIANGLE));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else {
+ /* Motion triangles, trace optimized case: we split triangle
+ * primitives into separate nodes for each of the time steps.
+ * This way we minimize overlap of neighbor curve primitives.
+ */
+ const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
+ const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
+ const size_t num_verts = mesh->verts.size();
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *vert_steps = attr_mP->data_float3();
+ /* Calculate bounding box of the previous time step.
+ * Will be reused later to avoid duplicated work on
+ * calculating BVH time step boundbox.
+ */
+ float3 prev_verts[3];
+ t.motion_verts(verts, vert_steps, num_verts, num_steps, 0.0f, prev_verts);
+ BoundBox prev_bounds = BoundBox::empty;
+ prev_bounds.grow(prev_verts[0]);
+ prev_bounds.grow(prev_verts[1]);
+ prev_bounds.grow(prev_verts[2]);
+ /* Create all primitive time steps, */
+ for (int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
+ const float curr_time = (float)(bvh_step)*num_bvh_steps_inv_1;
+ float3 curr_verts[3];
+ t.motion_verts(verts, vert_steps, num_verts, num_steps, curr_time, curr_verts);
+ BoundBox curr_bounds = BoundBox::empty;
+ curr_bounds.grow(curr_verts[0]);
+ curr_bounds.grow(curr_verts[1]);
+ curr_bounds.grow(curr_verts[2]);
+ BoundBox bounds = prev_bounds;
+ bounds.grow(curr_bounds);
+ if (bounds.valid()) {
+ const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
+ references.push_back(
+ BVHReference(bounds, j, i, PRIMITIVE_MOTION_TRIANGLE, prev_time, curr_time));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ /* Current time boundbox becomes previous one for the
+ * next time step.
+ */
+ prev_bounds = curr_bounds;
+ }
+ }
+ }
}
-void BVHBuild::add_reference_curves(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Mesh *mesh, int i)
{
- const Attribute *curve_attr_mP = NULL;
- if(mesh->has_motion_blur()) {
- curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- }
- const size_t num_curves = mesh->num_curves();
- for(uint j = 0; j < num_curves; j++) {
- const Mesh::Curve curve = mesh->get_curve(j);
- const float *curve_radius = &mesh->curve_radius[0];
- for(int k = 0; k < curve.num_keys - 1; k++) {
- if(curve_attr_mP == NULL) {
- /* Really simple logic for static hair. */
- BoundBox bounds = BoundBox::empty;
- curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
- if(bounds.valid()) {
- int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k);
- references.push_back(BVHReference(bounds, j, i, packed_type));
- root.grow(bounds);
- center.grow(bounds.center2());
- }
- }
- else if(params.num_motion_curve_steps == 0 || params.use_spatial_split) {
- /* Simple case of motion curves: single node for the while
- * shutter time. Lowest memory usage but less optimal
- * rendering.
- */
- /* TODO(sergey): Support motion steps for spatially split BVH. */
- BoundBox bounds = BoundBox::empty;
- curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
- const size_t num_keys = mesh->curve_keys.size();
- const size_t num_steps = mesh->motion_steps;
- const float3 *key_steps = curve_attr_mP->data_float3();
- for(size_t step = 0; step < num_steps - 1; step++) {
- curve.bounds_grow(k,
- key_steps + step*num_keys,
- curve_radius,
- bounds);
- }
- if(bounds.valid()) {
- int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
- references.push_back(BVHReference(bounds,
- j,
- i,
- packed_type));
- root.grow(bounds);
- center.grow(bounds.center2());
- }
- }
- else {
- /* Motion curves, trace optimized case: we split curve keys
- * primitives into separate nodes for each of the time steps.
- * This way we minimize overlap of neighbor curve primitives.
- */
- const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
- const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
- const size_t num_steps = mesh->motion_steps;
- const float3 *curve_keys = &mesh->curve_keys[0];
- const float3 *key_steps = curve_attr_mP->data_float3();
- const size_t num_keys = mesh->curve_keys.size();
- /* Calculate bounding box of the previous time step.
- * Will be reused later to avoid duplicated work on
- * calculating BVH time step boundbox.
- */
- float4 prev_keys[4];
- curve.cardinal_motion_keys(curve_keys,
- curve_radius,
- key_steps,
- num_keys,
- num_steps,
- 0.0f,
- k - 1, k, k + 1, k + 2,
- prev_keys);
- BoundBox prev_bounds = BoundBox::empty;
- curve.bounds_grow(prev_keys, prev_bounds);
- /* Create all primitive time steps, */
- for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
- const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
- float4 curr_keys[4];
- curve.cardinal_motion_keys(curve_keys,
- curve_radius,
- key_steps,
- num_keys,
- num_steps,
- curr_time,
- k - 1, k, k + 1, k + 2,
- curr_keys);
- BoundBox curr_bounds = BoundBox::empty;
- curve.bounds_grow(curr_keys, curr_bounds);
- BoundBox bounds = prev_bounds;
- bounds.grow(curr_bounds);
- if(bounds.valid()) {
- const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
- int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
- references.push_back(BVHReference(bounds,
- j,
- i,
- packed_type,
- prev_time,
- curr_time));
- root.grow(bounds);
- center.grow(bounds.center2());
- }
- /* Current time boundbox becomes previous one for the
- * next time step.
- */
- prev_bounds = curr_bounds;
- }
- }
- }
- }
+ const Attribute *curve_attr_mP = NULL;
+ if (mesh->has_motion_blur()) {
+ curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+ const size_t num_curves = mesh->num_curves();
+ for (uint j = 0; j < num_curves; j++) {
+ const Mesh::Curve curve = mesh->get_curve(j);
+ const float *curve_radius = &mesh->curve_radius[0];
+ for (int k = 0; k < curve.num_keys - 1; k++) {
+ if (curve_attr_mP == NULL) {
+ /* Really simple logic for static hair. */
+ BoundBox bounds = BoundBox::empty;
+ curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
+ if (bounds.valid()) {
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k);
+ references.push_back(BVHReference(bounds, j, i, packed_type));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else if (params.num_motion_curve_steps == 0 || params.use_spatial_split) {
+ /* Simple case of motion curves: single node for the while
+ * shutter time. Lowest memory usage but less optimal
+ * rendering.
+ */
+ /* TODO(sergey): Support motion steps for spatially split BVH. */
+ BoundBox bounds = BoundBox::empty;
+ curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
+ const size_t num_keys = mesh->curve_keys.size();
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *key_steps = curve_attr_mP->data_float3();
+ for (size_t step = 0; step < num_steps - 1; step++) {
+ curve.bounds_grow(k, key_steps + step * num_keys, curve_radius, bounds);
+ }
+ if (bounds.valid()) {
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+ references.push_back(BVHReference(bounds, j, i, packed_type));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else {
+ /* Motion curves, trace optimized case: we split curve keys
+ * primitives into separate nodes for each of the time steps.
+ * This way we minimize overlap of neighbor curve primitives.
+ */
+ const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
+ const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *curve_keys = &mesh->curve_keys[0];
+ const float3 *key_steps = curve_attr_mP->data_float3();
+ const size_t num_keys = mesh->curve_keys.size();
+ /* Calculate bounding box of the previous time step.
+ * Will be reused later to avoid duplicated work on
+ * calculating BVH time step boundbox.
+ */
+ float4 prev_keys[4];
+ curve.cardinal_motion_keys(curve_keys,
+ curve_radius,
+ key_steps,
+ num_keys,
+ num_steps,
+ 0.0f,
+ k - 1,
+ k,
+ k + 1,
+ k + 2,
+ prev_keys);
+ BoundBox prev_bounds = BoundBox::empty;
+ curve.bounds_grow(prev_keys, prev_bounds);
+ /* Create all primitive time steps, */
+ for (int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
+ const float curr_time = (float)(bvh_step)*num_bvh_steps_inv_1;
+ float4 curr_keys[4];
+ curve.cardinal_motion_keys(curve_keys,
+ curve_radius,
+ key_steps,
+ num_keys,
+ num_steps,
+ curr_time,
+ k - 1,
+ k,
+ k + 1,
+ k + 2,
+ curr_keys);
+ BoundBox curr_bounds = BoundBox::empty;
+ curve.bounds_grow(curr_keys, curr_bounds);
+ BoundBox bounds = prev_bounds;
+ bounds.grow(curr_bounds);
+ if (bounds.valid()) {
+ const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+ references.push_back(BVHReference(bounds, j, i, packed_type, prev_time, curr_time));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ /* Current time boundbox becomes previous one for the
+ * next time step.
+ */
+ prev_bounds = curr_bounds;
+ }
+ }
+ }
+ }
}
-void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+void BVHBuild::add_reference_mesh(BoundBox &root, BoundBox &center, Mesh *mesh, int i)
{
- if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- add_reference_triangles(root, center, mesh, i);
- }
- if(params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- add_reference_curves(root, center, mesh, i);
- }
+ if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
+ add_reference_triangles(root, center, mesh, i);
+ }
+ if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
+ add_reference_curves(root, center, mesh, i);
+ }
}
-void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i)
+void BVHBuild::add_reference_object(BoundBox &root, BoundBox &center, Object *ob, int i)
{
- references.push_back(BVHReference(ob->bounds, -1, i, 0));
- root.grow(ob->bounds);
- center.grow(ob->bounds.center2());
+ references.push_back(BVHReference(ob->bounds, -1, i, 0));
+ root.grow(ob->bounds);
+ center.grow(ob->bounds.center2());
}
static size_t count_curve_segments(Mesh *mesh)
{
- size_t num = 0, num_curves = mesh->num_curves();
+ size_t num = 0, num_curves = mesh->num_curves();
- for(size_t i = 0; i < num_curves; i++)
- num += mesh->get_curve(i).num_keys - 1;
+ for (size_t i = 0; i < num_curves; i++)
+ num += mesh->get_curve(i).num_keys - 1;
- return num;
+ return num;
}
-void BVHBuild::add_references(BVHRange& root)
+void BVHBuild::add_references(BVHRange &root)
{
- /* reserve space for references */
- size_t num_alloc_references = 0;
-
- foreach(Object *ob, objects) {
- if(params.top_level) {
- if(!ob->is_traceable()) {
- continue;
- }
- if(!ob->mesh->is_instanced()) {
- if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- num_alloc_references += ob->mesh->num_triangles();
- }
- if(params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- num_alloc_references += count_curve_segments(ob->mesh);
- }
- }
- else
- num_alloc_references++;
- }
- else {
- if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- num_alloc_references += ob->mesh->num_triangles();
- }
- if(params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- num_alloc_references += count_curve_segments(ob->mesh);
- }
- }
- }
-
- references.reserve(num_alloc_references);
-
- /* add references from objects */
- BoundBox bounds = BoundBox::empty, center = BoundBox::empty;
- int i = 0;
-
- foreach(Object *ob, objects) {
- if(params.top_level) {
- if(!ob->is_traceable()) {
- ++i;
- continue;
- }
- if(!ob->mesh->is_instanced())
- add_reference_mesh(bounds, center, ob->mesh, i);
- else
- add_reference_object(bounds, center, ob, i);
- }
- else
- add_reference_mesh(bounds, center, ob->mesh, i);
-
- i++;
-
- if(progress.get_cancel()) return;
- }
-
- /* happens mostly on empty meshes */
- if(!bounds.valid())
- bounds.grow(make_float3(0.0f, 0.0f, 0.0f));
-
- root = BVHRange(bounds, center, 0, references.size());
+ /* reserve space for references */
+ size_t num_alloc_references = 0;
+
+ foreach (Object *ob, objects) {
+ if (params.top_level) {
+ if (!ob->is_traceable()) {
+ continue;
+ }
+ if (!ob->mesh->is_instanced()) {
+ if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
+ num_alloc_references += ob->mesh->num_triangles();
+ }
+ if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
+ num_alloc_references += count_curve_segments(ob->mesh);
+ }
+ }
+ else
+ num_alloc_references++;
+ }
+ else {
+ if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
+ num_alloc_references += ob->mesh->num_triangles();
+ }
+ if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
+ num_alloc_references += count_curve_segments(ob->mesh);
+ }
+ }
+ }
+
+ references.reserve(num_alloc_references);
+
+ /* add references from objects */
+ BoundBox bounds = BoundBox::empty, center = BoundBox::empty;
+ int i = 0;
+
+ foreach (Object *ob, objects) {
+ if (params.top_level) {
+ if (!ob->is_traceable()) {
+ ++i;
+ continue;
+ }
+ if (!ob->mesh->is_instanced())
+ add_reference_mesh(bounds, center, ob->mesh, i);
+ else
+ add_reference_object(bounds, center, ob, i);
+ }
+ else
+ add_reference_mesh(bounds, center, ob->mesh, i);
+
+ i++;
+
+ if (progress.get_cancel())
+ return;
+ }
+
+ /* happens mostly on empty meshes */
+ if (!bounds.valid())
+ bounds.grow(make_float3(0.0f, 0.0f, 0.0f));
+
+ root = BVHRange(bounds, center, 0, references.size());
}
/* Build */
-BVHNode* BVHBuild::run()
+BVHNode *BVHBuild::run()
{
- BVHRange root;
-
- /* add references */
- add_references(root);
-
- if(progress.get_cancel())
- return NULL;
-
- /* init spatial splits */
- if(params.top_level) {
- /* NOTE: Technically it is supported by the builder but it's not really
- * optimized for speed yet and not really clear yet if it has measurable
- * improvement on render time. Needs some extra investigation before
- * enabling spatial split for top level BVH.
- */
- params.use_spatial_split = false;
- }
-
- spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha;
- if(params.use_spatial_split) {
- /* NOTE: The API here tries to be as much ready for multi-threaded build
- * as possible, but at the same time it tries not to introduce any
- * changes in behavior for until all refactoring needed for threading is
- * finished.
- *
- * So we currently allocate single storage for now, which is only used by
- * the only thread working on the spatial BVH build.
- */
- spatial_storage.resize(TaskScheduler::num_threads() + 1);
- size_t num_bins = max(root.size(), (int)BVHParams::NUM_SPATIAL_BINS) - 1;
- foreach(BVHSpatialStorage &storage, spatial_storage) {
- storage.right_bounds.clear();
- }
- spatial_storage[0].right_bounds.resize(num_bins);
- }
- spatial_free_index = 0;
-
- need_prim_time = params.num_motion_curve_steps > 0 ||
- params.num_motion_triangle_steps > 0;
-
- /* init progress updates */
- double build_start_time;
- build_start_time = progress_start_time = time_dt();
- progress_count = 0;
- progress_total = references.size();
- progress_original_total = progress_total;
-
- prim_type.resize(references.size());
- prim_index.resize(references.size());
- prim_object.resize(references.size());
- if(need_prim_time) {
- prim_time.resize(references.size());
- }
- else {
- prim_time.resize(0);
- }
-
- /* build recursively */
- BVHNode *rootnode;
-
- if(params.use_spatial_split) {
- /* Perform multithreaded spatial split build. */
- rootnode = build_node(root, &references, 0, 0);
- task_pool.wait_work();
- }
- else {
- /* Perform multithreaded binning build. */
- BVHObjectBinning rootbin(root, (references.size())? &references[0]: NULL);
- rootnode = build_node(rootbin, 0);
- task_pool.wait_work();
- }
-
- /* delete if we canceled */
- if(rootnode) {
- if(progress.get_cancel()) {
- rootnode->deleteSubtree();
- rootnode = NULL;
- VLOG(1) << "BVH build cancelled.";
- }
- else {
- /*rotate(rootnode, 4, 5);*/
- rootnode->update_visibility();
- rootnode->update_time();
- }
- if(rootnode != NULL) {
- VLOG(1) << "BVH build statistics:\n"
- << " Build time: " << time_dt() - build_start_time << "\n"
- << " Total number of nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_NODE_COUNT)) << "\n"
- << " Number of inner nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_INNER_COUNT)) << "\n"
- << " Number of leaf nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_LEAF_COUNT)) << "\n"
- << " Number of unaligned nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_UNALIGNED_COUNT)) << "\n"
- << " Allocation slop factor: "
- << ((prim_type.capacity() != 0)
- ? (float)prim_type.size() / prim_type.capacity()
- : 1.0f) << "\n"
- << " Maximum depth: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_DEPTH)) << "\n";
- }
- }
-
-
- return rootnode;
+ BVHRange root;
+
+ /* add references */
+ add_references(root);
+
+ if (progress.get_cancel())
+ return NULL;
+
+ /* init spatial splits */
+ if (params.top_level) {
+ /* NOTE: Technically it is supported by the builder but it's not really
+ * optimized for speed yet and not really clear yet if it has measurable
+ * improvement on render time. Needs some extra investigation before
+ * enabling spatial split for top level BVH.
+ */
+ params.use_spatial_split = false;
+ }
+
+ spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha;
+ if (params.use_spatial_split) {
+ /* NOTE: The API here tries to be as much ready for multi-threaded build
+ * as possible, but at the same time it tries not to introduce any
+ * changes in behavior for until all refactoring needed for threading is
+ * finished.
+ *
+ * So we currently allocate single storage for now, which is only used by
+ * the only thread working on the spatial BVH build.
+ */
+ spatial_storage.resize(TaskScheduler::num_threads() + 1);
+ size_t num_bins = max(root.size(), (int)BVHParams::NUM_SPATIAL_BINS) - 1;
+ foreach (BVHSpatialStorage &storage, spatial_storage) {
+ storage.right_bounds.clear();
+ }
+ spatial_storage[0].right_bounds.resize(num_bins);
+ }
+ spatial_free_index = 0;
+
+ need_prim_time = params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0;
+
+ /* init progress updates */
+ double build_start_time;
+ build_start_time = progress_start_time = time_dt();
+ progress_count = 0;
+ progress_total = references.size();
+ progress_original_total = progress_total;
+
+ prim_type.resize(references.size());
+ prim_index.resize(references.size());
+ prim_object.resize(references.size());
+ if (need_prim_time) {
+ prim_time.resize(references.size());
+ }
+ else {
+ prim_time.resize(0);
+ }
+
+ /* build recursively */
+ BVHNode *rootnode;
+
+ if (params.use_spatial_split) {
+ /* Perform multithreaded spatial split build. */
+ rootnode = build_node(root, &references, 0, 0);
+ task_pool.wait_work();
+ }
+ else {
+ /* Perform multithreaded binning build. */
+ BVHObjectBinning rootbin(root, (references.size()) ? &references[0] : NULL);
+ rootnode = build_node(rootbin, 0);
+ task_pool.wait_work();
+ }
+
+ /* delete if we canceled */
+ if (rootnode) {
+ if (progress.get_cancel()) {
+ rootnode->deleteSubtree();
+ rootnode = NULL;
+ VLOG(1) << "BVH build cancelled.";
+ }
+ else {
+ /*rotate(rootnode, 4, 5);*/
+ rootnode->update_visibility();
+ rootnode->update_time();
+ }
+ if (rootnode != NULL) {
+ VLOG(1) << "BVH build statistics:\n"
+ << " Build time: " << time_dt() - build_start_time << "\n"
+ << " Total number of nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_NODE_COUNT))
+ << "\n"
+ << " Number of inner nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_INNER_COUNT))
+ << "\n"
+ << " Number of leaf nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_LEAF_COUNT))
+ << "\n"
+ << " Number of unaligned nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_UNALIGNED_COUNT))
+ << "\n"
+ << " Allocation slop factor: "
+ << ((prim_type.capacity() != 0) ? (float)prim_type.size() / prim_type.capacity() :
+ 1.0f)
+ << "\n"
+ << " Maximum depth: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_DEPTH)) << "\n";
+ }
+ }
+
+ return rootnode;
}
void BVHBuild::progress_update()
{
- if(time_dt() - progress_start_time < 0.25)
- return;
+ if (time_dt() - progress_start_time < 0.25)
+ return;
- double progress_start = (double)progress_count/(double)progress_total;
- double duplicates = (double)(progress_total - progress_original_total)/(double)progress_total;
+ double progress_start = (double)progress_count / (double)progress_total;
+ double duplicates = (double)(progress_total - progress_original_total) / (double)progress_total;
- string msg = string_printf("Building BVH %.0f%%, duplicates %.0f%%",
- progress_start * 100.0, duplicates * 100.0);
+ string msg = string_printf(
+ "Building BVH %.0f%%, duplicates %.0f%%", progress_start * 100.0, duplicates * 100.0);
- progress.set_substatus(msg);
- progress_start_time = time_dt();
+ progress.set_substatus(msg);
+ progress_start_time = time_dt();
}
-void BVHBuild::thread_build_node(InnerNode *inner,
- int child,
- BVHObjectBinning *range,
- int level)
+void BVHBuild::thread_build_node(InnerNode *inner, int child, BVHObjectBinning *range, int level)
{
- if(progress.get_cancel())
- return;
+ if (progress.get_cancel())
+ return;
- /* build nodes */
- BVHNode *node = build_node(*range, level);
+ /* build nodes */
+ BVHNode *node = build_node(*range, level);
- /* set child in inner node */
- inner->children[child] = node;
+ /* set child in inner node */
+ inner->children[child] = node;
- /* update progress */
- if(range->size() < THREAD_TASK_SIZE) {
- /*rotate(node, INT_MAX, 5);*/
+ /* update progress */
+ if (range->size() < THREAD_TASK_SIZE) {
+ /*rotate(node, INT_MAX, 5);*/
- thread_scoped_lock lock(build_mutex);
+ thread_scoped_lock lock(build_mutex);
- progress_count += range->size();
- progress_update();
- }
+ progress_count += range->size();
+ progress_update();
+ }
}
void BVHBuild::thread_build_spatial_split_node(InnerNode *inner,
@@ -585,567 +551,528 @@ void BVHBuild::thread_build_spatial_split_node(InnerNode *inner,
int level,
int thread_id)
{
- if(progress.get_cancel()) {
- return;
- }
+ if (progress.get_cancel()) {
+ return;
+ }
- /* build nodes */
- BVHNode *node = build_node(*range, references, level, thread_id);
+ /* build nodes */
+ BVHNode *node = build_node(*range, references, level, thread_id);
- /* set child in inner node */
- inner->children[child] = node;
+ /* set child in inner node */
+ inner->children[child] = node;
}
-bool BVHBuild::range_within_max_leaf_size(const BVHRange& range,
- const vector<BVHReference>& references) const
+bool BVHBuild::range_within_max_leaf_size(const BVHRange &range,
+ const vector<BVHReference> &references) const
{
- size_t size = range.size();
- size_t max_leaf_size = max(params.max_triangle_leaf_size, params.max_curve_leaf_size);
-
- if(size > max_leaf_size)
- return false;
-
- size_t num_triangles = 0;
- size_t num_motion_triangles = 0;
- size_t num_curves = 0;
- size_t num_motion_curves = 0;
-
- for(int i = 0; i < size; i++) {
- const BVHReference& ref = references[range.start() + i];
-
- if(ref.prim_type() & PRIMITIVE_CURVE)
- num_curves++;
- if(ref.prim_type() & PRIMITIVE_MOTION_CURVE)
- num_motion_curves++;
- else if(ref.prim_type() & PRIMITIVE_TRIANGLE)
- num_triangles++;
- else if(ref.prim_type() & PRIMITIVE_MOTION_TRIANGLE)
- num_motion_triangles++;
- }
-
- return (num_triangles <= params.max_triangle_leaf_size) &&
- (num_motion_triangles <= params.max_motion_triangle_leaf_size) &&
- (num_curves <= params.max_curve_leaf_size) &&
- (num_motion_curves <= params.max_motion_curve_leaf_size);
+ size_t size = range.size();
+ size_t max_leaf_size = max(params.max_triangle_leaf_size, params.max_curve_leaf_size);
+
+ if (size > max_leaf_size)
+ return false;
+
+ size_t num_triangles = 0;
+ size_t num_motion_triangles = 0;
+ size_t num_curves = 0;
+ size_t num_motion_curves = 0;
+
+ for (int i = 0; i < size; i++) {
+ const BVHReference &ref = references[range.start() + i];
+
+ if (ref.prim_type() & PRIMITIVE_CURVE)
+ num_curves++;
+ if (ref.prim_type() & PRIMITIVE_MOTION_CURVE)
+ num_motion_curves++;
+ else if (ref.prim_type() & PRIMITIVE_TRIANGLE)
+ num_triangles++;
+ else if (ref.prim_type() & PRIMITIVE_MOTION_TRIANGLE)
+ num_motion_triangles++;
+ }
+
+ return (num_triangles <= params.max_triangle_leaf_size) &&
+ (num_motion_triangles <= params.max_motion_triangle_leaf_size) &&
+ (num_curves <= params.max_curve_leaf_size) &&
+ (num_motion_curves <= params.max_motion_curve_leaf_size);
}
/* multithreaded binning builder */
-BVHNode* BVHBuild::build_node(const BVHObjectBinning& range, int level)
+BVHNode *BVHBuild::build_node(const BVHObjectBinning &range, int level)
{
- size_t size = range.size();
- float leafSAH = params.sah_primitive_cost * range.leafSAH;
- float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_primitive_cost * range.splitSAH;
-
- /* Have at least one inner node on top level, for performance and correct
- * visibility tests, since object instances do not check visibility flag.
- */
- if(!(range.size() > 0 && params.top_level && level == 0)) {
- /* Make leaf node when threshold reached or SAH tells us. */
- if((params.small_enough_for_leaf(size, level)) ||
- (range_within_max_leaf_size(range, references) && leafSAH < splitSAH))
- {
- return create_leaf_node(range, references);
- }
- }
-
- BVHObjectBinning unaligned_range;
- float unalignedSplitSAH = FLT_MAX;
- float unalignedLeafSAH = FLT_MAX;
- Transform aligned_space;
- bool do_unalinged_split = false;
- if(params.use_unaligned_nodes &&
- splitSAH > params.unaligned_split_threshold*leafSAH)
- {
- aligned_space = unaligned_heuristic.compute_aligned_space(
- range, &references[0]);
- unaligned_range = BVHObjectBinning(range,
- &references[0],
- &unaligned_heuristic,
- &aligned_space);
- unalignedSplitSAH = params.sah_node_cost * unaligned_range.unaligned_bounds().half_area() +
- params.sah_primitive_cost * unaligned_range.splitSAH;
- unalignedLeafSAH = params.sah_primitive_cost * unaligned_range.leafSAH;
- if(!(range.size() > 0 && params.top_level && level == 0)) {
- if(unalignedLeafSAH < unalignedSplitSAH && unalignedSplitSAH < splitSAH &&
- range_within_max_leaf_size(range, references))
- {
- return create_leaf_node(range, references);
- }
- }
- /* Check whether unaligned split is better than the regular one. */
- if(unalignedSplitSAH < splitSAH) {
- do_unalinged_split = true;
- }
- }
-
- /* Perform split. */
- BVHObjectBinning left, right;
- if(do_unalinged_split) {
- unaligned_range.split(&references[0], left, right);
- }
- else {
- range.split(&references[0], left, right);
- }
-
- BoundBox bounds;
- if(do_unalinged_split) {
- bounds = unaligned_heuristic.compute_aligned_boundbox(
- range, &references[0], aligned_space);
- }
- else {
- bounds = range.bounds();
- }
-
- /* Create inner node. */
- InnerNode *inner;
- if(range.size() < THREAD_TASK_SIZE) {
- /* local build */
- BVHNode *leftnode = build_node(left, level + 1);
- BVHNode *rightnode = build_node(right, level + 1);
-
- inner = new InnerNode(bounds, leftnode, rightnode);
- }
- else {
- /* Threaded build */
- inner = new InnerNode(bounds);
-
- task_pool.push(new BVHBuildTask(this, inner, 0, left, level + 1), true);
- task_pool.push(new BVHBuildTask(this, inner, 1, right, level + 1), true);
- }
-
- if(do_unalinged_split) {
- inner->set_aligned_space(aligned_space);
- }
-
- return inner;
+ size_t size = range.size();
+ float leafSAH = params.sah_primitive_cost * range.leafSAH;
+ float splitSAH = params.sah_node_cost * range.bounds().half_area() +
+ params.sah_primitive_cost * range.splitSAH;
+
+ /* Have at least one inner node on top level, for performance and correct
+ * visibility tests, since object instances do not check visibility flag.
+ */
+ if (!(range.size() > 0 && params.top_level && level == 0)) {
+ /* Make leaf node when threshold reached or SAH tells us. */
+ if ((params.small_enough_for_leaf(size, level)) ||
+ (range_within_max_leaf_size(range, references) && leafSAH < splitSAH)) {
+ return create_leaf_node(range, references);
+ }
+ }
+
+ BVHObjectBinning unaligned_range;
+ float unalignedSplitSAH = FLT_MAX;
+ float unalignedLeafSAH = FLT_MAX;
+ Transform aligned_space;
+ bool do_unalinged_split = false;
+ if (params.use_unaligned_nodes && splitSAH > params.unaligned_split_threshold * leafSAH) {
+ aligned_space = unaligned_heuristic.compute_aligned_space(range, &references[0]);
+ unaligned_range = BVHObjectBinning(
+ range, &references[0], &unaligned_heuristic, &aligned_space);
+ unalignedSplitSAH = params.sah_node_cost * unaligned_range.unaligned_bounds().half_area() +
+ params.sah_primitive_cost * unaligned_range.splitSAH;
+ unalignedLeafSAH = params.sah_primitive_cost * unaligned_range.leafSAH;
+ if (!(range.size() > 0 && params.top_level && level == 0)) {
+ if (unalignedLeafSAH < unalignedSplitSAH && unalignedSplitSAH < splitSAH &&
+ range_within_max_leaf_size(range, references)) {
+ return create_leaf_node(range, references);
+ }
+ }
+ /* Check whether unaligned split is better than the regular one. */
+ if (unalignedSplitSAH < splitSAH) {
+ do_unalinged_split = true;
+ }
+ }
+
+ /* Perform split. */
+ BVHObjectBinning left, right;
+ if (do_unalinged_split) {
+ unaligned_range.split(&references[0], left, right);
+ }
+ else {
+ range.split(&references[0], left, right);
+ }
+
+ BoundBox bounds;
+ if (do_unalinged_split) {
+ bounds = unaligned_heuristic.compute_aligned_boundbox(range, &references[0], aligned_space);
+ }
+ else {
+ bounds = range.bounds();
+ }
+
+ /* Create inner node. */
+ InnerNode *inner;
+ if (range.size() < THREAD_TASK_SIZE) {
+ /* local build */
+ BVHNode *leftnode = build_node(left, level + 1);
+ BVHNode *rightnode = build_node(right, level + 1);
+
+ inner = new InnerNode(bounds, leftnode, rightnode);
+ }
+ else {
+ /* Threaded build */
+ inner = new InnerNode(bounds);
+
+ task_pool.push(new BVHBuildTask(this, inner, 0, left, level + 1), true);
+ task_pool.push(new BVHBuildTask(this, inner, 1, right, level + 1), true);
+ }
+
+ if (do_unalinged_split) {
+ inner->set_aligned_space(aligned_space);
+ }
+
+ return inner;
}
/* multithreaded spatial split builder */
-BVHNode* BVHBuild::build_node(const BVHRange& range,
+BVHNode *BVHBuild::build_node(const BVHRange &range,
vector<BVHReference> *references,
int level,
int thread_id)
{
- /* Update progress.
- *
- * TODO(sergey): Currently it matches old behavior, but we can move it to the
- * task thread (which will mimic non=split builder) and save some CPU ticks
- * on checking cancel status.
- */
- progress_update();
- if(progress.get_cancel()) {
- return NULL;
- }
-
- /* Small enough or too deep => create leaf. */
- if(!(range.size() > 0 && params.top_level && level == 0)) {
- if(params.small_enough_for_leaf(range.size(), level)) {
- progress_count += range.size();
- return create_leaf_node(range, *references);
- }
- }
-
- /* Perform splitting test. */
- BVHSpatialStorage *storage = &spatial_storage[thread_id];
- BVHMixedSplit split(this, storage, range, references, level);
-
- if(!(range.size() > 0 && params.top_level && level == 0)) {
- if(split.no_split) {
- progress_count += range.size();
- return create_leaf_node(range, *references);
- }
- }
- float leafSAH = params.sah_primitive_cost * split.leafSAH;
- float splitSAH = params.sah_node_cost * range.bounds().half_area() +
- params.sah_primitive_cost * split.nodeSAH;
-
- BVHMixedSplit unaligned_split;
- float unalignedSplitSAH = FLT_MAX;
- /* float unalignedLeafSAH = FLT_MAX; */
- Transform aligned_space;
- bool do_unalinged_split = false;
- if(params.use_unaligned_nodes &&
- splitSAH > params.unaligned_split_threshold*leafSAH)
- {
- aligned_space =
- unaligned_heuristic.compute_aligned_space(range, &references->at(0));
- unaligned_split = BVHMixedSplit(this,
- storage,
- range,
- references,
- level,
- &unaligned_heuristic,
- &aligned_space);
- /* unalignedLeafSAH = params.sah_primitive_cost * split.leafSAH; */
- unalignedSplitSAH = params.sah_node_cost * unaligned_split.bounds.half_area() +
- params.sah_primitive_cost * unaligned_split.nodeSAH;
- /* TOOD(sergey): Check we can create leaf already. */
- /* Check whether unaligned split is better than the regulat one. */
- if(unalignedSplitSAH < splitSAH) {
- do_unalinged_split = true;
- }
- }
-
- /* Do split. */
- BVHRange left, right;
- if(do_unalinged_split) {
- unaligned_split.split(this, left, right, range);
- }
- else {
- split.split(this, left, right, range);
- }
-
- progress_total += left.size() + right.size() - range.size();
-
- BoundBox bounds;
- if(do_unalinged_split) {
- bounds = unaligned_heuristic.compute_aligned_boundbox(
- range, &references->at(0), aligned_space);
- }
- else {
- bounds = range.bounds();
- }
-
- /* Create inner node. */
- InnerNode *inner;
- if(range.size() < THREAD_TASK_SIZE) {
- /* Local build. */
-
- /* Build left node. */
- vector<BVHReference> copy(references->begin() + right.start(),
- references->begin() + right.end());
- right.set_start(0);
-
- BVHNode *leftnode = build_node(left, references, level + 1, thread_id);
-
- /* Build right node. */
- BVHNode *rightnode = build_node(right, &copy, level + 1, thread_id);
-
- inner = new InnerNode(bounds, leftnode, rightnode);
- }
- else {
- /* Threaded build. */
- inner = new InnerNode(bounds);
- task_pool.push(new BVHSpatialSplitBuildTask(this,
- inner,
- 0,
- left,
- *references,
- level + 1),
- true);
- task_pool.push(new BVHSpatialSplitBuildTask(this,
- inner,
- 1,
- right,
- *references,
- level + 1),
- true);
- }
-
- if(do_unalinged_split) {
- inner->set_aligned_space(aligned_space);
- }
-
- return inner;
+ /* Update progress.
+ *
+ * TODO(sergey): Currently it matches old behavior, but we can move it to the
+ * task thread (which will mimic non=split builder) and save some CPU ticks
+ * on checking cancel status.
+ */
+ progress_update();
+ if (progress.get_cancel()) {
+ return NULL;
+ }
+
+ /* Small enough or too deep => create leaf. */
+ if (!(range.size() > 0 && params.top_level && level == 0)) {
+ if (params.small_enough_for_leaf(range.size(), level)) {
+ progress_count += range.size();
+ return create_leaf_node(range, *references);
+ }
+ }
+
+ /* Perform splitting test. */
+ BVHSpatialStorage *storage = &spatial_storage[thread_id];
+ BVHMixedSplit split(this, storage, range, references, level);
+
+ if (!(range.size() > 0 && params.top_level && level == 0)) {
+ if (split.no_split) {
+ progress_count += range.size();
+ return create_leaf_node(range, *references);
+ }
+ }
+ float leafSAH = params.sah_primitive_cost * split.leafSAH;
+ float splitSAH = params.sah_node_cost * range.bounds().half_area() +
+ params.sah_primitive_cost * split.nodeSAH;
+
+ BVHMixedSplit unaligned_split;
+ float unalignedSplitSAH = FLT_MAX;
+ /* float unalignedLeafSAH = FLT_MAX; */
+ Transform aligned_space;
+ bool do_unalinged_split = false;
+ if (params.use_unaligned_nodes && splitSAH > params.unaligned_split_threshold * leafSAH) {
+ aligned_space = unaligned_heuristic.compute_aligned_space(range, &references->at(0));
+ unaligned_split = BVHMixedSplit(
+ this, storage, range, references, level, &unaligned_heuristic, &aligned_space);
+ /* unalignedLeafSAH = params.sah_primitive_cost * split.leafSAH; */
+ unalignedSplitSAH = params.sah_node_cost * unaligned_split.bounds.half_area() +
+ params.sah_primitive_cost * unaligned_split.nodeSAH;
+ /* TOOD(sergey): Check we can create leaf already. */
+ /* Check whether unaligned split is better than the regulat one. */
+ if (unalignedSplitSAH < splitSAH) {
+ do_unalinged_split = true;
+ }
+ }
+
+ /* Do split. */
+ BVHRange left, right;
+ if (do_unalinged_split) {
+ unaligned_split.split(this, left, right, range);
+ }
+ else {
+ split.split(this, left, right, range);
+ }
+
+ progress_total += left.size() + right.size() - range.size();
+
+ BoundBox bounds;
+ if (do_unalinged_split) {
+ bounds = unaligned_heuristic.compute_aligned_boundbox(
+ range, &references->at(0), aligned_space);
+ }
+ else {
+ bounds = range.bounds();
+ }
+
+ /* Create inner node. */
+ InnerNode *inner;
+ if (range.size() < THREAD_TASK_SIZE) {
+ /* Local build. */
+
+ /* Build left node. */
+ vector<BVHReference> copy(references->begin() + right.start(),
+ references->begin() + right.end());
+ right.set_start(0);
+
+ BVHNode *leftnode = build_node(left, references, level + 1, thread_id);
+
+ /* Build right node. */
+ BVHNode *rightnode = build_node(right, &copy, level + 1, thread_id);
+
+ inner = new InnerNode(bounds, leftnode, rightnode);
+ }
+ else {
+ /* Threaded build. */
+ inner = new InnerNode(bounds);
+ task_pool.push(new BVHSpatialSplitBuildTask(this, inner, 0, left, *references, level + 1),
+ true);
+ task_pool.push(new BVHSpatialSplitBuildTask(this, inner, 1, right, *references, level + 1),
+ true);
+ }
+
+ if (do_unalinged_split) {
+ inner->set_aligned_space(aligned_space);
+ }
+
+ return inner;
}
/* Create Nodes */
BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start, int num)
{
- if(num == 0) {
- BoundBox bounds = BoundBox::empty;
- return new LeafNode(bounds, 0, 0, 0);
- }
- else if(num == 1) {
- assert(start < prim_type.size());
- prim_type[start] = ref->prim_type();
- prim_index[start] = ref->prim_index();
- prim_object[start] = ref->prim_object();
- if(need_prim_time) {
- prim_time[start] = make_float2(ref->time_from(), ref->time_to());
- }
-
- const uint visibility = objects[ref->prim_object()]->visibility_for_tracing();
- BVHNode *leaf_node = new LeafNode(ref->bounds(), visibility, start, start+1);
- leaf_node->time_from = ref->time_from();
- leaf_node->time_to = ref->time_to();
- return leaf_node;
- }
- else {
- int mid = num/2;
- BVHNode *leaf0 = create_object_leaf_nodes(ref, start, mid);
- BVHNode *leaf1 = create_object_leaf_nodes(ref+mid, start+mid, num-mid);
-
- BoundBox bounds = BoundBox::empty;
- bounds.grow(leaf0->bounds);
- bounds.grow(leaf1->bounds);
-
- BVHNode *inner_node = new InnerNode(bounds, leaf0, leaf1);
- inner_node->time_from = min(leaf0->time_from, leaf1->time_from);
- inner_node->time_to = max(leaf0->time_to, leaf1->time_to);
- return inner_node;
- }
+ if (num == 0) {
+ BoundBox bounds = BoundBox::empty;
+ return new LeafNode(bounds, 0, 0, 0);
+ }
+ else if (num == 1) {
+ assert(start < prim_type.size());
+ prim_type[start] = ref->prim_type();
+ prim_index[start] = ref->prim_index();
+ prim_object[start] = ref->prim_object();
+ if (need_prim_time) {
+ prim_time[start] = make_float2(ref->time_from(), ref->time_to());
+ }
+
+ const uint visibility = objects[ref->prim_object()]->visibility_for_tracing();
+ BVHNode *leaf_node = new LeafNode(ref->bounds(), visibility, start, start + 1);
+ leaf_node->time_from = ref->time_from();
+ leaf_node->time_to = ref->time_to();
+ return leaf_node;
+ }
+ else {
+ int mid = num / 2;
+ BVHNode *leaf0 = create_object_leaf_nodes(ref, start, mid);
+ BVHNode *leaf1 = create_object_leaf_nodes(ref + mid, start + mid, num - mid);
+
+ BoundBox bounds = BoundBox::empty;
+ bounds.grow(leaf0->bounds);
+ bounds.grow(leaf1->bounds);
+
+ BVHNode *inner_node = new InnerNode(bounds, leaf0, leaf1);
+ inner_node->time_from = min(leaf0->time_from, leaf1->time_from);
+ inner_node->time_to = max(leaf0->time_to, leaf1->time_to);
+ return inner_node;
+ }
}
-BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
- const vector<BVHReference>& references)
+BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHReference> &references)
{
- /* This is a bit overallocating here (considering leaf size into account),
- * but chunk-based re-allocation in vector makes it difficult to use small
- * size of stack storage here. Some tweaks are possible tho.
- *
- * NOTES:
- * - If the size is too big, we'll have inefficient stack usage,
- * and lots of cache misses.
- * - If the size is too small, then we can run out of memory
- * allowed to be used by vector.
- * In practice it wouldn't mean crash, just allocator will fallback
- * to heap which is slower.
- * - Optimistic re-allocation in STL could jump us out of stack usage
- * because re-allocation happens in chunks and size of those chunks we
- * can not control.
- */
- typedef StackAllocator<256, int> LeafStackAllocator;
- typedef StackAllocator<256, float2> LeafTimeStackAllocator;
- typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
-
- vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM_TOTAL];
- vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM_TOTAL];
- vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM_TOTAL];
- vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM_TOTAL];
- vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM_TOTAL];
-
- /* TODO(sergey): In theory we should be able to store references. */
- vector<BVHReference, LeafReferenceStackAllocator> object_references;
-
- uint visibility[PRIMITIVE_NUM_TOTAL] = {0};
- /* NOTE: Keep initializtion in sync with actual number of primitives. */
- BoundBox bounds[PRIMITIVE_NUM_TOTAL] = {BoundBox::empty,
- BoundBox::empty,
- BoundBox::empty,
- BoundBox::empty};
- int ob_num = 0;
- int num_new_prims = 0;
- /* Fill in per-type type/index array. */
- for(int i = 0; i < range.size(); i++) {
- const BVHReference& ref = references[range.start() + i];
- if(ref.prim_index() != -1) {
- int type_index = bitscan(ref.prim_type() & PRIMITIVE_ALL);
- p_ref[type_index].push_back(ref);
- p_type[type_index].push_back(ref.prim_type());
- p_index[type_index].push_back(ref.prim_index());
- p_object[type_index].push_back(ref.prim_object());
- p_time[type_index].push_back(make_float2(ref.time_from(),
- ref.time_to()));
-
- bounds[type_index].grow(ref.bounds());
- visibility[type_index] |= objects[ref.prim_object()]->visibility_for_tracing();
- if(ref.prim_type() & PRIMITIVE_ALL_CURVE) {
- visibility[type_index] |= PATH_RAY_CURVE;
- }
- ++num_new_prims;
- }
- else {
- object_references.push_back(ref);
- ++ob_num;
- }
- }
-
- /* Create leaf nodes for every existing primitive.
- *
- * Here we write primitive types, indices and objects to a temporary array.
- * This way we keep all the heavy memory allocation code outside of the
- * thread lock in the case of spatial split building.
- *
- * TODO(sergey): With some pointer trickery we can write directly to the
- * destination buffers for the non-spatial split BVH.
- */
- BVHNode *leaves[PRIMITIVE_NUM_TOTAL + 1] = {NULL};
- int num_leaves = 0;
- size_t start_index = 0;
- vector<int, LeafStackAllocator> local_prim_type,
- local_prim_index,
- local_prim_object;
- vector<float2, LeafTimeStackAllocator> local_prim_time;
- local_prim_type.resize(num_new_prims);
- local_prim_index.resize(num_new_prims);
- local_prim_object.resize(num_new_prims);
- if(need_prim_time) {
- local_prim_time.resize(num_new_prims);
- }
- for(int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
- int num = (int)p_type[i].size();
- if(num != 0) {
- assert(p_type[i].size() == p_index[i].size());
- assert(p_type[i].size() == p_object[i].size());
- Transform aligned_space;
- bool alignment_found = false;
- for(int j = 0; j < num; ++j) {
- const int index = start_index + j;
- local_prim_type[index] = p_type[i][j];
- local_prim_index[index] = p_index[i][j];
- local_prim_object[index] = p_object[i][j];
- if(need_prim_time) {
- local_prim_time[index] = p_time[i][j];
- }
- if(params.use_unaligned_nodes && !alignment_found) {
- alignment_found =
- unaligned_heuristic.compute_aligned_space(p_ref[i][j],
- &aligned_space);
- }
- }
- LeafNode *leaf_node = new LeafNode(bounds[i],
- visibility[i],
- start_index,
- start_index + num);
- if(true) {
- float time_from = 1.0f, time_to = 0.0f;
- for(int j = 0; j < num; ++j) {
- const BVHReference &ref = p_ref[i][j];
- time_from = min(time_from, ref.time_from());
- time_to = max(time_to, ref.time_to());
- }
- leaf_node->time_from = time_from;
- leaf_node->time_to = time_to;
- }
- if(alignment_found) {
- /* Need to recalculate leaf bounds with new alignment. */
- leaf_node->bounds = BoundBox::empty;
- for(int j = 0; j < num; ++j) {
- const BVHReference &ref = p_ref[i][j];
- BoundBox ref_bounds =
- unaligned_heuristic.compute_aligned_prim_boundbox(
- ref,
- aligned_space);
- leaf_node->bounds.grow(ref_bounds);
- }
- /* Set alignment space. */
- leaf_node->set_aligned_space(aligned_space);
- }
- leaves[num_leaves++] = leaf_node;
- start_index += num;
- }
- }
- /* Get size of new data to be copied to the packed arrays. */
- const int num_new_leaf_data = start_index;
- const size_t new_leaf_data_size = sizeof(int) * num_new_leaf_data;
- /* Copy actual data to the packed array. */
- if(params.use_spatial_split) {
- spatial_spin_lock.lock();
- /* We use first free index in the packed arrays and mode pointer to the
- * end of the current range.
- *
- * This doesn't give deterministic packed arrays, but it shouldn't really
- * matter because order of children in BVH is deterministic.
- */
- start_index = spatial_free_index;
- spatial_free_index += range.size();
- /* Extend an array when needed. */
- const size_t range_end = start_index + range.size();
- if(prim_type.size() < range_end) {
- /* Avoid extra re-allocations by pre-allocating bigger array in an
- * advance.
- */
- if(range_end >= prim_type.capacity()) {
- float progress = (float)progress_count/(float)progress_total;
- float factor = (1.0f - progress);
- const size_t reserve = (size_t)(range_end + (float)range_end*factor);
- prim_type.reserve(reserve);
- prim_index.reserve(reserve);
- prim_object.reserve(reserve);
- if(need_prim_time) {
- prim_time.reserve(reserve);
- }
- }
-
- prim_type.resize(range_end);
- prim_index.resize(range_end);
- prim_object.resize(range_end);
- if(need_prim_time) {
- prim_time.resize(range_end);
- }
- }
- /* Perform actual data copy. */
- if(new_leaf_data_size > 0) {
- memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
- memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
- memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
- if(need_prim_time) {
- memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
- }
- }
- spatial_spin_lock.unlock();
- }
- else {
- /* For the regular BVH builder we simply copy new data starting at the
- * range start. This is totally thread-safe, all threads are living
- * inside of their own range.
- */
- start_index = range.start();
- if(new_leaf_data_size > 0) {
- memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
- memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
- memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
- if(need_prim_time) {
- memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
- }
- }
- }
-
- /* So far leaves were created with the zero-based index in an arrays,
- * here we modify the indices to correspond to actual packed array start
- * index.
- */
- for(int i = 0; i < num_leaves; ++i) {
- LeafNode *leaf = (LeafNode *)leaves[i];
- leaf->lo += start_index;
- leaf->hi += start_index;
- }
-
- /* Create leaf node for object. */
- if(num_leaves == 0 || ob_num) {
- /* Only create object leaf nodes if there are objects or no other
- * nodes created.
- */
- const BVHReference *ref = (ob_num)? &object_references[0]: NULL;
- leaves[num_leaves] = create_object_leaf_nodes(ref,
- start_index + num_new_leaf_data,
- ob_num);
- ++num_leaves;
- }
-
- /* TODO(sergey): Need to take care of alignment when number of leaves
- * is more than 1.
- */
- if(num_leaves == 1) {
- /* Simplest case: single leaf, just return it.
- * In all the rest cases we'll be creating intermediate inner node with
- * an appropriate bounding box.
- */
- return leaves[0];
- }
- else if(num_leaves == 2) {
- return new InnerNode(range.bounds(), leaves[0], leaves[1]);
- }
- else if(num_leaves == 3) {
- BoundBox inner_bounds = merge(leaves[1]->bounds, leaves[2]->bounds);
- BVHNode *inner = new InnerNode(inner_bounds, leaves[1], leaves[2]);
- return new InnerNode(range.bounds(), leaves[0], inner);
- } else {
- /* Should be doing more branches if more primitive types added. */
- assert(num_leaves <= 5);
- BoundBox inner_bounds_a = merge(leaves[0]->bounds, leaves[1]->bounds);
- BoundBox inner_bounds_b = merge(leaves[2]->bounds, leaves[3]->bounds);
- BVHNode *inner_a = new InnerNode(inner_bounds_a, leaves[0], leaves[1]);
- BVHNode *inner_b = new InnerNode(inner_bounds_b, leaves[2], leaves[3]);
- BoundBox inner_bounds_c = merge(inner_a->bounds, inner_b->bounds);
- BVHNode *inner_c = new InnerNode(inner_bounds_c, inner_a, inner_b);
- if(num_leaves == 5) {
- return new InnerNode(range.bounds(), inner_c, leaves[4]);
- }
- return inner_c;
- }
+ /* This is a bit overallocating here (considering leaf size into account),
+ * but chunk-based re-allocation in vector makes it difficult to use small
+ * size of stack storage here. Some tweaks are possible tho.
+ *
+ * NOTES:
+ * - If the size is too big, we'll have inefficient stack usage,
+ * and lots of cache misses.
+ * - If the size is too small, then we can run out of memory
+ * allowed to be used by vector.
+ * In practice it wouldn't mean crash, just allocator will fallback
+ * to heap which is slower.
+ * - Optimistic re-allocation in STL could jump us out of stack usage
+ * because re-allocation happens in chunks and size of those chunks we
+ * can not control.
+ */
+ typedef StackAllocator<256, int> LeafStackAllocator;
+ typedef StackAllocator<256, float2> LeafTimeStackAllocator;
+ typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
+
+ vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM_TOTAL];
+ vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM_TOTAL];
+ vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM_TOTAL];
+ vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM_TOTAL];
+ vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM_TOTAL];
+
+ /* TODO(sergey): In theory we should be able to store references. */
+ vector<BVHReference, LeafReferenceStackAllocator> object_references;
+
+ uint visibility[PRIMITIVE_NUM_TOTAL] = {0};
+ /* NOTE: Keep initializtion in sync with actual number of primitives. */
+ BoundBox bounds[PRIMITIVE_NUM_TOTAL] = {
+ BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty};
+ int ob_num = 0;
+ int num_new_prims = 0;
+ /* Fill in per-type type/index array. */
+ for (int i = 0; i < range.size(); i++) {
+ const BVHReference &ref = references[range.start() + i];
+ if (ref.prim_index() != -1) {
+ int type_index = bitscan(ref.prim_type() & PRIMITIVE_ALL);
+ p_ref[type_index].push_back(ref);
+ p_type[type_index].push_back(ref.prim_type());
+ p_index[type_index].push_back(ref.prim_index());
+ p_object[type_index].push_back(ref.prim_object());
+ p_time[type_index].push_back(make_float2(ref.time_from(), ref.time_to()));
+
+ bounds[type_index].grow(ref.bounds());
+ visibility[type_index] |= objects[ref.prim_object()]->visibility_for_tracing();
+ if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
+ visibility[type_index] |= PATH_RAY_CURVE;
+ }
+ ++num_new_prims;
+ }
+ else {
+ object_references.push_back(ref);
+ ++ob_num;
+ }
+ }
+
+ /* Create leaf nodes for every existing primitive.
+ *
+ * Here we write primitive types, indices and objects to a temporary array.
+ * This way we keep all the heavy memory allocation code outside of the
+ * thread lock in the case of spatial split building.
+ *
+ * TODO(sergey): With some pointer trickery we can write directly to the
+ * destination buffers for the non-spatial split BVH.
+ */
+ BVHNode *leaves[PRIMITIVE_NUM_TOTAL + 1] = {NULL};
+ int num_leaves = 0;
+ size_t start_index = 0;
+ vector<int, LeafStackAllocator> local_prim_type, local_prim_index, local_prim_object;
+ vector<float2, LeafTimeStackAllocator> local_prim_time;
+ local_prim_type.resize(num_new_prims);
+ local_prim_index.resize(num_new_prims);
+ local_prim_object.resize(num_new_prims);
+ if (need_prim_time) {
+ local_prim_time.resize(num_new_prims);
+ }
+ for (int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
+ int num = (int)p_type[i].size();
+ if (num != 0) {
+ assert(p_type[i].size() == p_index[i].size());
+ assert(p_type[i].size() == p_object[i].size());
+ Transform aligned_space;
+ bool alignment_found = false;
+ for (int j = 0; j < num; ++j) {
+ const int index = start_index + j;
+ local_prim_type[index] = p_type[i][j];
+ local_prim_index[index] = p_index[i][j];
+ local_prim_object[index] = p_object[i][j];
+ if (need_prim_time) {
+ local_prim_time[index] = p_time[i][j];
+ }
+ if (params.use_unaligned_nodes && !alignment_found) {
+ alignment_found = unaligned_heuristic.compute_aligned_space(p_ref[i][j], &aligned_space);
+ }
+ }
+ LeafNode *leaf_node = new LeafNode(bounds[i], visibility[i], start_index, start_index + num);
+ if (true) {
+ float time_from = 1.0f, time_to = 0.0f;
+ for (int j = 0; j < num; ++j) {
+ const BVHReference &ref = p_ref[i][j];
+ time_from = min(time_from, ref.time_from());
+ time_to = max(time_to, ref.time_to());
+ }
+ leaf_node->time_from = time_from;
+ leaf_node->time_to = time_to;
+ }
+ if (alignment_found) {
+ /* Need to recalculate leaf bounds with new alignment. */
+ leaf_node->bounds = BoundBox::empty;
+ for (int j = 0; j < num; ++j) {
+ const BVHReference &ref = p_ref[i][j];
+ BoundBox ref_bounds = unaligned_heuristic.compute_aligned_prim_boundbox(ref,
+ aligned_space);
+ leaf_node->bounds.grow(ref_bounds);
+ }
+ /* Set alignment space. */
+ leaf_node->set_aligned_space(aligned_space);
+ }
+ leaves[num_leaves++] = leaf_node;
+ start_index += num;
+ }
+ }
+ /* Get size of new data to be copied to the packed arrays. */
+ const int num_new_leaf_data = start_index;
+ const size_t new_leaf_data_size = sizeof(int) * num_new_leaf_data;
+ /* Copy actual data to the packed array. */
+ if (params.use_spatial_split) {
+ spatial_spin_lock.lock();
+ /* We use first free index in the packed arrays and mode pointer to the
+ * end of the current range.
+ *
+ * This doesn't give deterministic packed arrays, but it shouldn't really
+ * matter because order of children in BVH is deterministic.
+ */
+ start_index = spatial_free_index;
+ spatial_free_index += range.size();
+ /* Extend an array when needed. */
+ const size_t range_end = start_index + range.size();
+ if (prim_type.size() < range_end) {
+ /* Avoid extra re-allocations by pre-allocating bigger array in an
+ * advance.
+ */
+ if (range_end >= prim_type.capacity()) {
+ float progress = (float)progress_count / (float)progress_total;
+ float factor = (1.0f - progress);
+ const size_t reserve = (size_t)(range_end + (float)range_end * factor);
+ prim_type.reserve(reserve);
+ prim_index.reserve(reserve);
+ prim_object.reserve(reserve);
+ if (need_prim_time) {
+ prim_time.reserve(reserve);
+ }
+ }
+
+ prim_type.resize(range_end);
+ prim_index.resize(range_end);
+ prim_object.resize(range_end);
+ if (need_prim_time) {
+ prim_time.resize(range_end);
+ }
+ }
+ /* Perform actual data copy. */
+ if (new_leaf_data_size > 0) {
+ memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
+ memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
+ memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
+ if (need_prim_time) {
+ memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2) * num_new_leaf_data);
+ }
+ }
+ spatial_spin_lock.unlock();
+ }
+ else {
+ /* For the regular BVH builder we simply copy new data starting at the
+ * range start. This is totally thread-safe, all threads are living
+ * inside of their own range.
+ */
+ start_index = range.start();
+ if (new_leaf_data_size > 0) {
+ memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
+ memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
+ memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
+ if (need_prim_time) {
+ memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2) * num_new_leaf_data);
+ }
+ }
+ }
+
+ /* So far leaves were created with the zero-based index in an arrays,
+ * here we modify the indices to correspond to actual packed array start
+ * index.
+ */
+ for (int i = 0; i < num_leaves; ++i) {
+ LeafNode *leaf = (LeafNode *)leaves[i];
+ leaf->lo += start_index;
+ leaf->hi += start_index;
+ }
+
+ /* Create leaf node for object. */
+ if (num_leaves == 0 || ob_num) {
+ /* Only create object leaf nodes if there are objects or no other
+ * nodes created.
+ */
+ const BVHReference *ref = (ob_num) ? &object_references[0] : NULL;
+ leaves[num_leaves] = create_object_leaf_nodes(ref, start_index + num_new_leaf_data, ob_num);
+ ++num_leaves;
+ }
+
+ /* TODO(sergey): Need to take care of alignment when number of leaves
+ * is more than 1.
+ */
+ if (num_leaves == 1) {
+ /* Simplest case: single leaf, just return it.
+ * In all the rest cases we'll be creating intermediate inner node with
+ * an appropriate bounding box.
+ */
+ return leaves[0];
+ }
+ else if (num_leaves == 2) {
+ return new InnerNode(range.bounds(), leaves[0], leaves[1]);
+ }
+ else if (num_leaves == 3) {
+ BoundBox inner_bounds = merge(leaves[1]->bounds, leaves[2]->bounds);
+ BVHNode *inner = new InnerNode(inner_bounds, leaves[1], leaves[2]);
+ return new InnerNode(range.bounds(), leaves[0], inner);
+ }
+ else {
+ /* Should be doing more branches if more primitive types added. */
+ assert(num_leaves <= 5);
+ BoundBox inner_bounds_a = merge(leaves[0]->bounds, leaves[1]->bounds);
+ BoundBox inner_bounds_b = merge(leaves[2]->bounds, leaves[3]->bounds);
+ BVHNode *inner_a = new InnerNode(inner_bounds_a, leaves[0], leaves[1]);
+ BVHNode *inner_b = new InnerNode(inner_bounds_b, leaves[2], leaves[3]);
+ BoundBox inner_bounds_c = merge(inner_a->bounds, inner_b->bounds);
+ BVHNode *inner_c = new InnerNode(inner_bounds_c, inner_a, inner_b);
+ if (num_leaves == 5) {
+ return new InnerNode(range.bounds(), inner_c, leaves[4]);
+ }
+ return inner_c;
+ }
#undef MAX_ITEMS_PER_LEAF
}
@@ -1154,81 +1081,81 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
void BVHBuild::rotate(BVHNode *node, int max_depth, int iterations)
{
- /* in tested scenes, this resulted in slightly slower raytracing, so disabled
- * it for now. could be implementation bug, or depend on the scene */
- if(node)
- for(int i = 0; i < iterations; i++)
- rotate(node, max_depth);
+ /* in tested scenes, this resulted in slightly slower raytracing, so disabled
+ * it for now. could be implementation bug, or depend on the scene */
+ if (node)
+ for (int i = 0; i < iterations; i++)
+ rotate(node, max_depth);
}
void BVHBuild::rotate(BVHNode *node, int max_depth)
{
- /* nothing to rotate if we reached a leaf node. */
- if(node->is_leaf() || max_depth < 0)
- return;
-
- InnerNode *parent = (InnerNode*)node;
-
- /* rotate all children first */
- for(size_t c = 0; c < 2; c++)
- rotate(parent->children[c], max_depth-1);
-
- /* compute current area of all children */
- BoundBox bounds0 = parent->children[0]->bounds;
- BoundBox bounds1 = parent->children[1]->bounds;
-
- float area0 = bounds0.half_area();
- float area1 = bounds1.half_area();
- float4 child_area = make_float4(area0, area1, 0.0f, 0.0f);
-
- /* find best rotation. we pick a target child of a first child, and swap
- * this with an other child. we perform the best such swap. */
- float best_cost = FLT_MAX;
- int best_child = -1, best_target = -1, best_other = -1;
-
- for(size_t c = 0; c < 2; c++) {
- /* ignore leaf nodes as we cannot descent into */
- if(parent->children[c]->is_leaf())
- continue;
-
- InnerNode *child = (InnerNode*)parent->children[c];
- BoundBox& other = (c == 0)? bounds1: bounds0;
-
- /* transpose child bounds */
- BoundBox target0 = child->children[0]->bounds;
- BoundBox target1 = child->children[1]->bounds;
-
- /* compute cost for both possible swaps */
- float cost0 = merge(other, target1).half_area() - child_area[c];
- float cost1 = merge(target0, other).half_area() - child_area[c];
-
- if(min(cost0,cost1) < best_cost) {
- best_child = (int)c;
- best_other = (int)(1-c);
-
- if(cost0 < cost1) {
- best_cost = cost0;
- best_target = 0;
- }
- else {
- best_cost = cost0;
- best_target = 1;
- }
- }
- }
-
- /* if we did not find a swap that improves the SAH then do nothing */
- if(best_cost >= 0)
- return;
-
- assert(best_child == 0 || best_child == 1);
- assert(best_target != -1);
-
- /* perform the best found tree rotation */
- InnerNode *child = (InnerNode*)parent->children[best_child];
-
- swap(parent->children[best_other], child->children[best_target]);
- child->bounds = merge(child->children[0]->bounds, child->children[1]->bounds);
+ /* nothing to rotate if we reached a leaf node. */
+ if (node->is_leaf() || max_depth < 0)
+ return;
+
+ InnerNode *parent = (InnerNode *)node;
+
+ /* rotate all children first */
+ for (size_t c = 0; c < 2; c++)
+ rotate(parent->children[c], max_depth - 1);
+
+ /* compute current area of all children */
+ BoundBox bounds0 = parent->children[0]->bounds;
+ BoundBox bounds1 = parent->children[1]->bounds;
+
+ float area0 = bounds0.half_area();
+ float area1 = bounds1.half_area();
+ float4 child_area = make_float4(area0, area1, 0.0f, 0.0f);
+
+ /* find best rotation. we pick a target child of a first child, and swap
+ * this with an other child. we perform the best such swap. */
+ float best_cost = FLT_MAX;
+ int best_child = -1, best_target = -1, best_other = -1;
+
+ for (size_t c = 0; c < 2; c++) {
+ /* ignore leaf nodes as we cannot descent into */
+ if (parent->children[c]->is_leaf())
+ continue;
+
+ InnerNode *child = (InnerNode *)parent->children[c];
+ BoundBox &other = (c == 0) ? bounds1 : bounds0;
+
+ /* transpose child bounds */
+ BoundBox target0 = child->children[0]->bounds;
+ BoundBox target1 = child->children[1]->bounds;
+
+ /* compute cost for both possible swaps */
+ float cost0 = merge(other, target1).half_area() - child_area[c];
+ float cost1 = merge(target0, other).half_area() - child_area[c];
+
+ if (min(cost0, cost1) < best_cost) {
+ best_child = (int)c;
+ best_other = (int)(1 - c);
+
+ if (cost0 < cost1) {
+ best_cost = cost0;
+ best_target = 0;
+ }
+ else {
+ best_cost = cost0;
+ best_target = 1;
+ }
+ }
+ }
+
+ /* if we did not find a swap that improves the SAH then do nothing */
+ if (best_cost >= 0)
+ return;
+
+ assert(best_child == 0 || best_child == 1);
+ assert(best_target != -1);
+
+ /* perform the best found tree rotation */
+ InnerNode *child = (InnerNode *)parent->children[best_child];
+
+ swap(parent->children[best_other], child->children[best_target]);
+ child->bounds = merge(child->children[0]->bounds, child->children[1]->bounds);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index dd95a5cc0e8..9685e26cfac 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -41,106 +41,101 @@ class Progress;
/* BVH Builder */
-class BVHBuild
-{
-public:
- /* Constructor/Destructor */
- BVHBuild(const vector<Object*>& objects,
- array<int>& prim_type,
- array<int>& prim_index,
- array<int>& prim_object,
- array<float2>& prim_time,
- const BVHParams& params,
- Progress& progress);
- ~BVHBuild();
-
- BVHNode *run();
-
-protected:
- friend class BVHMixedSplit;
- friend class BVHObjectSplit;
- friend class BVHSpatialSplit;
- friend class BVHBuildTask;
- friend class BVHSpatialSplitBuildTask;
- friend class BVHObjectBinning;
-
- /* Adding references. */
- void add_reference_triangles(BoundBox& root, BoundBox& center, Mesh *mesh, int i);
- void add_reference_curves(BoundBox& root, BoundBox& center, Mesh *mesh, int i);
- void add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i);
- void add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i);
- void add_references(BVHRange& root);
-
- /* Building. */
- BVHNode *build_node(const BVHRange& range,
- vector<BVHReference> *references,
- int level,
- int thread_id);
- BVHNode *build_node(const BVHObjectBinning& range, int level);
- BVHNode *create_leaf_node(const BVHRange& range,
- const vector<BVHReference>& references);
- BVHNode *create_object_leaf_nodes(const BVHReference *ref, int start, int num);
-
- bool range_within_max_leaf_size(const BVHRange& range,
- const vector<BVHReference>& references) const;
-
- /* Threads. */
- enum { THREAD_TASK_SIZE = 4096 };
- void thread_build_node(InnerNode *node,
- int child,
- BVHObjectBinning *range,
- int level);
- void thread_build_spatial_split_node(InnerNode *node,
- int child,
- BVHRange *range,
- vector<BVHReference> *references,
- int level,
- int thread_id);
- thread_mutex build_mutex;
-
- /* Progress. */
- void progress_update();
-
- /* Tree rotations. */
- void rotate(BVHNode *node, int max_depth);
- void rotate(BVHNode *node, int max_depth, int iterations);
-
- /* Objects and primitive references. */
- vector<Object*> objects;
- vector<BVHReference> references;
- int num_original_references;
-
- /* Output primitive indexes and objects. */
- array<int>& prim_type;
- array<int>& prim_index;
- array<int>& prim_object;
- array<float2>& prim_time;
-
- bool need_prim_time;
-
- /* Build parameters. */
- BVHParams params;
-
- /* Progress reporting. */
- Progress& progress;
- double progress_start_time;
- size_t progress_count;
- size_t progress_total;
- size_t progress_original_total;
-
- /* Spatial splitting. */
- float spatial_min_overlap;
- vector<BVHSpatialStorage> spatial_storage;
- size_t spatial_free_index;
- thread_spin_lock spatial_spin_lock;
-
- /* Threads. */
- TaskPool task_pool;
-
- /* Unaligned building. */
- BVHUnaligned unaligned_heuristic;
+class BVHBuild {
+ public:
+ /* Constructor/Destructor */
+ BVHBuild(const vector<Object *> &objects,
+ array<int> &prim_type,
+ array<int> &prim_index,
+ array<int> &prim_object,
+ array<float2> &prim_time,
+ const BVHParams &params,
+ Progress &progress);
+ ~BVHBuild();
+
+ BVHNode *run();
+
+ protected:
+ friend class BVHMixedSplit;
+ friend class BVHObjectSplit;
+ friend class BVHSpatialSplit;
+ friend class BVHBuildTask;
+ friend class BVHSpatialSplitBuildTask;
+ friend class BVHObjectBinning;
+
+ /* Adding references. */
+ void add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *mesh, int i);
+ void add_reference_curves(BoundBox &root, BoundBox &center, Mesh *mesh, int i);
+ void add_reference_mesh(BoundBox &root, BoundBox &center, Mesh *mesh, int i);
+ void add_reference_object(BoundBox &root, BoundBox &center, Object *ob, int i);
+ void add_references(BVHRange &root);
+
+ /* Building. */
+ BVHNode *build_node(const BVHRange &range,
+ vector<BVHReference> *references,
+ int level,
+ int thread_id);
+ BVHNode *build_node(const BVHObjectBinning &range, int level);
+ BVHNode *create_leaf_node(const BVHRange &range, const vector<BVHReference> &references);
+ BVHNode *create_object_leaf_nodes(const BVHReference *ref, int start, int num);
+
+ bool range_within_max_leaf_size(const BVHRange &range,
+ const vector<BVHReference> &references) const;
+
+ /* Threads. */
+ enum { THREAD_TASK_SIZE = 4096 };
+ void thread_build_node(InnerNode *node, int child, BVHObjectBinning *range, int level);
+ void thread_build_spatial_split_node(InnerNode *node,
+ int child,
+ BVHRange *range,
+ vector<BVHReference> *references,
+ int level,
+ int thread_id);
+ thread_mutex build_mutex;
+
+ /* Progress. */
+ void progress_update();
+
+ /* Tree rotations. */
+ void rotate(BVHNode *node, int max_depth);
+ void rotate(BVHNode *node, int max_depth, int iterations);
+
+ /* Objects and primitive references. */
+ vector<Object *> objects;
+ vector<BVHReference> references;
+ int num_original_references;
+
+ /* Output primitive indexes and objects. */
+ array<int> &prim_type;
+ array<int> &prim_index;
+ array<int> &prim_object;
+ array<float2> &prim_time;
+
+ bool need_prim_time;
+
+ /* Build parameters. */
+ BVHParams params;
+
+ /* Progress reporting. */
+ Progress &progress;
+ double progress_start_time;
+ size_t progress_count;
+ size_t progress_total;
+ size_t progress_original_total;
+
+ /* Spatial splitting. */
+ float spatial_min_overlap;
+ vector<BVHSpatialStorage> spatial_storage;
+ size_t spatial_free_index;
+ thread_spin_lock spatial_spin_lock;
+
+ /* Threads. */
+ TaskPool task_pool;
+
+ /* Unaligned building. */
+ BVHUnaligned unaligned_heuristic;
};
CCL_NAMESPACE_END
-#endif /* __BVH_BUILD_H__ */
+#endif /* __BVH_BUILD_H__ */
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index fa9993d8ac3..5ef9622aba2 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -34,28 +34,28 @@
#ifdef WITH_EMBREE
-#include <pmmintrin.h>
-#include <xmmintrin.h>
-#include <embree3/rtcore_geometry.h>
+# include <pmmintrin.h>
+# include <xmmintrin.h>
+# include <embree3/rtcore_geometry.h>
-#include "bvh/bvh_embree.h"
+# include "bvh/bvh_embree.h"
/* Kernel includes are necessary so that the filter function for Embree can access the packed BVH. */
-#include "kernel/bvh/bvh_embree.h"
-#include "kernel/kernel_compat_cpu.h"
-#include "kernel/split/kernel_split_data_types.h"
-#include "kernel/kernel_globals.h"
-#include "kernel/kernel_random.h"
-
-#include "render/mesh.h"
-#include "render/object.h"
-#include "util/util_foreach.h"
-#include "util/util_logging.h"
-#include "util/util_progress.h"
+# include "kernel/bvh/bvh_embree.h"
+# include "kernel/kernel_compat_cpu.h"
+# include "kernel/split/kernel_split_data_types.h"
+# include "kernel/kernel_globals.h"
+# include "kernel/kernel_random.h"
+
+# include "render/mesh.h"
+# include "render/object.h"
+# include "util/util_foreach.h"
+# include "util/util_logging.h"
+# include "util/util_progress.h"
CCL_NAMESPACE_BEGIN
-#define IS_HAIR(x) (x & 1)
+# define IS_HAIR(x) (x & 1)
/* This gets called by Embree at every valid ray/object intersection.
* Things like recording subsurface or shadow hits for later evaluation
@@ -64,215 +64,217 @@ CCL_NAMESPACE_BEGIN
*/
static void rtc_filter_func(const RTCFilterFunctionNArguments *args)
{
- /* Current implementation in Cycles assumes only single-ray intersection queries. */
- assert(args->N == 1);
-
- const RTCRay *ray = (RTCRay*)args->ray;
- const RTCHit *hit = (RTCHit*)args->hit;
- CCLIntersectContext *ctx = ((IntersectContext*)args->context)->userRayExt;
- KernelGlobals *kg = ctx->kg;
-
- /* Check if there is backfacing hair to ignore. */
- if(IS_HAIR(hit->geomID) && (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
- && !(kernel_data.curve.curveflags & CURVE_KN_BACKFACING)
- && !(kernel_data.curve.curveflags & CURVE_KN_RIBBONS)) {
- if(dot(make_float3(ray->dir_x, ray->dir_y, ray->dir_z), make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z)) > 0.0f) {
- *args->valid = 0;
- return;
- }
- }
+ /* Current implementation in Cycles assumes only single-ray intersection queries. */
+ assert(args->N == 1);
+
+ const RTCRay *ray = (RTCRay *)args->ray;
+ const RTCHit *hit = (RTCHit *)args->hit;
+ CCLIntersectContext *ctx = ((IntersectContext *)args->context)->userRayExt;
+ KernelGlobals *kg = ctx->kg;
+
+ /* Check if there is backfacing hair to ignore. */
+ if (IS_HAIR(hit->geomID) && (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) &&
+ !(kernel_data.curve.curveflags & CURVE_KN_BACKFACING) &&
+ !(kernel_data.curve.curveflags & CURVE_KN_RIBBONS)) {
+ if (dot(make_float3(ray->dir_x, ray->dir_y, ray->dir_z),
+ make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z)) > 0.0f) {
+ *args->valid = 0;
+ return;
+ }
+ }
}
-static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments* args)
+static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
{
- assert(args->N == 1);
-
- const RTCRay *ray = (RTCRay*)args->ray;
- RTCHit *hit = (RTCHit*)args->hit;
- CCLIntersectContext *ctx = ((IntersectContext*)args->context)->userRayExt;
- KernelGlobals *kg = ctx->kg;
-
- /* For all ray types: Check if there is backfacing hair to ignore */
- if(IS_HAIR(hit->geomID) && (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
- && !(kernel_data.curve.curveflags & CURVE_KN_BACKFACING)
- && !(kernel_data.curve.curveflags & CURVE_KN_RIBBONS)) {
- if(dot(make_float3(ray->dir_x, ray->dir_y, ray->dir_z), make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z)) > 0.0f) {
- *args->valid = 0;
- return;
- }
- }
-
- switch(ctx->type) {
- case CCLIntersectContext::RAY_SHADOW_ALL: {
- /* Append the intersection to the end of the array. */
- if(ctx->num_hits < ctx->max_hits) {
- Intersection current_isect;
- kernel_embree_convert_hit(kg, ray, hit, &current_isect);
- for(size_t i = 0; i < ctx->max_hits; ++i) {
- if(current_isect.object == ctx->isect_s[i].object &&
- current_isect.prim == ctx->isect_s[i].prim &&
- current_isect.t == ctx->isect_s[i].t) {
- /* This intersection was already recorded, skip it. */
- *args->valid = 0;
- break;
- }
- }
- Intersection *isect = &ctx->isect_s[ctx->num_hits];
- ++ctx->num_hits;
- *isect = current_isect;
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- int shader = 0;
- if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
- int flag = kernel_tex_fetch(__shaders, shader & SHADER_MASK).flags;
- /* If no transparent shadows, all light is blocked. */
- if(flag & (SD_HAS_TRANSPARENT_SHADOW)) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- }
- }
- else {
- /* Increase the number of hits beyond ray.max_hits
- * so that the caller can detect this as opaque. */
- ++ctx->num_hits;
- }
- break;
- }
- case CCLIntersectContext::RAY_SSS: {
- /* No intersection information requested, just return a hit. */
- if(ctx->max_hits == 0) {
- break;
- }
-
- /* Ignore curves. */
- if(hit->geomID & 1) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- break;
- }
-
- /* See triangle_intersect_subsurface() for the native equivalent. */
- for(int i = min(ctx->max_hits, ctx->ss_isect->num_hits) - 1; i >= 0; --i) {
- if(ctx->ss_isect->hits[i].t == ray->tfar) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- break;
- }
- }
-
- ++ctx->ss_isect->num_hits;
- int hit_idx;
-
- if(ctx->ss_isect->num_hits <= ctx->max_hits) {
- hit_idx = ctx->ss_isect->num_hits - 1;
- }
- else {
- /* reservoir sampling: if we are at the maximum number of
- * hits, randomly replace element or skip it */
- hit_idx = lcg_step_uint(ctx->lcg_state) % ctx->ss_isect->num_hits;
-
- if(hit_idx >= ctx->max_hits) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- break;
- }
- }
- /* record intersection */
- kernel_embree_convert_local_hit(kg, ray, hit, &ctx->ss_isect->hits[hit_idx], ctx->sss_object_id);
- ctx->ss_isect->Ng[hit_idx].x = hit->Ng_x;
- ctx->ss_isect->Ng[hit_idx].y = hit->Ng_y;
- ctx->ss_isect->Ng[hit_idx].z = hit->Ng_z;
- ctx->ss_isect->Ng[hit_idx] = normalize(ctx->ss_isect->Ng[hit_idx]);
- /* This tells Embree to continue tracing .*/
- *args->valid = 0;
- break;
- }
- case CCLIntersectContext::RAY_VOLUME_ALL: {
- /* Append the intersection to the end of the array. */
- if(ctx->num_hits < ctx->max_hits) {
- Intersection current_isect;
- kernel_embree_convert_hit(kg, ray, hit, &current_isect);
- for(size_t i = 0; i < ctx->max_hits; ++i) {
- if(current_isect.object == ctx->isect_s[i].object &&
- current_isect.prim == ctx->isect_s[i].prim &&
- current_isect.t == ctx->isect_s[i].t) {
- /* This intersection was already recorded, skip it. */
- *args->valid = 0;
- break;
- }
- }
- Intersection *isect = &ctx->isect_s[ctx->num_hits];
- ++ctx->num_hits;
- *isect = current_isect;
- /* Only primitives from volume object. */
- uint tri_object = (isect->object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, isect->prim) : isect->object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- --ctx->num_hits;
- }
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- break;
- }
- }
- case CCLIntersectContext::RAY_REGULAR:
- default:
- /* Nothing to do here. */
- break;
- }
+ assert(args->N == 1);
+
+ const RTCRay *ray = (RTCRay *)args->ray;
+ RTCHit *hit = (RTCHit *)args->hit;
+ CCLIntersectContext *ctx = ((IntersectContext *)args->context)->userRayExt;
+ KernelGlobals *kg = ctx->kg;
+
+ /* For all ray types: Check if there is backfacing hair to ignore */
+ if (IS_HAIR(hit->geomID) && (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) &&
+ !(kernel_data.curve.curveflags & CURVE_KN_BACKFACING) &&
+ !(kernel_data.curve.curveflags & CURVE_KN_RIBBONS)) {
+ if (dot(make_float3(ray->dir_x, ray->dir_y, ray->dir_z),
+ make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z)) > 0.0f) {
+ *args->valid = 0;
+ return;
+ }
+ }
+
+ switch (ctx->type) {
+ case CCLIntersectContext::RAY_SHADOW_ALL: {
+ /* Append the intersection to the end of the array. */
+ if (ctx->num_hits < ctx->max_hits) {
+ Intersection current_isect;
+ kernel_embree_convert_hit(kg, ray, hit, &current_isect);
+ for (size_t i = 0; i < ctx->max_hits; ++i) {
+ if (current_isect.object == ctx->isect_s[i].object &&
+ current_isect.prim == ctx->isect_s[i].prim && current_isect.t == ctx->isect_s[i].t) {
+ /* This intersection was already recorded, skip it. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ Intersection *isect = &ctx->isect_s[ctx->num_hits];
+ ++ctx->num_hits;
+ *isect = current_isect;
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ int shader = 0;
+ if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+ int flag = kernel_tex_fetch(__shaders, shader & SHADER_MASK).flags;
+ /* If no transparent shadows, all light is blocked. */
+ if (flag & (SD_HAS_TRANSPARENT_SHADOW)) {
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ }
+ }
+ else {
+ /* Increase the number of hits beyond ray.max_hits
+ * so that the caller can detect this as opaque. */
+ ++ctx->num_hits;
+ }
+ break;
+ }
+ case CCLIntersectContext::RAY_SSS: {
+ /* No intersection information requested, just return a hit. */
+ if (ctx->max_hits == 0) {
+ break;
+ }
+
+ /* Ignore curves. */
+ if (hit->geomID & 1) {
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
+
+ /* See triangle_intersect_subsurface() for the native equivalent. */
+ for (int i = min(ctx->max_hits, ctx->ss_isect->num_hits) - 1; i >= 0; --i) {
+ if (ctx->ss_isect->hits[i].t == ray->tfar) {
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
+ }
+
+ ++ctx->ss_isect->num_hits;
+ int hit_idx;
+
+ if (ctx->ss_isect->num_hits <= ctx->max_hits) {
+ hit_idx = ctx->ss_isect->num_hits - 1;
+ }
+ else {
+ /* reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it */
+ hit_idx = lcg_step_uint(ctx->lcg_state) % ctx->ss_isect->num_hits;
+
+ if (hit_idx >= ctx->max_hits) {
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ /* record intersection */
+ kernel_embree_convert_local_hit(
+ kg, ray, hit, &ctx->ss_isect->hits[hit_idx], ctx->sss_object_id);
+ ctx->ss_isect->Ng[hit_idx].x = hit->Ng_x;
+ ctx->ss_isect->Ng[hit_idx].y = hit->Ng_y;
+ ctx->ss_isect->Ng[hit_idx].z = hit->Ng_z;
+ ctx->ss_isect->Ng[hit_idx] = normalize(ctx->ss_isect->Ng[hit_idx]);
+ /* This tells Embree to continue tracing .*/
+ *args->valid = 0;
+ break;
+ }
+ case CCLIntersectContext::RAY_VOLUME_ALL: {
+ /* Append the intersection to the end of the array. */
+ if (ctx->num_hits < ctx->max_hits) {
+ Intersection current_isect;
+ kernel_embree_convert_hit(kg, ray, hit, &current_isect);
+ for (size_t i = 0; i < ctx->max_hits; ++i) {
+ if (current_isect.object == ctx->isect_s[i].object &&
+ current_isect.prim == ctx->isect_s[i].prim && current_isect.t == ctx->isect_s[i].t) {
+ /* This intersection was already recorded, skip it. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ Intersection *isect = &ctx->isect_s[ctx->num_hits];
+ ++ctx->num_hits;
+ *isect = current_isect;
+ /* Only primitives from volume object. */
+ uint tri_object = (isect->object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, isect->prim) :
+ isect->object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ --ctx->num_hits;
+ }
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ case CCLIntersectContext::RAY_REGULAR:
+ default:
+ /* Nothing to do here. */
+ break;
+ }
}
static size_t unaccounted_mem = 0;
-static bool rtc_memory_monitor_func(void* userPtr, const ssize_t bytes, const bool)
+static bool rtc_memory_monitor_func(void *userPtr, const ssize_t bytes, const bool)
{
- Stats *stats = (Stats*)userPtr;
- if(stats) {
- if(bytes > 0) {
- stats->mem_alloc(bytes);
- }
- else {
- stats->mem_free(-bytes);
- }
- }
- else {
- /* A stats pointer may not yet be available. Keep track of the memory usage for later. */
- if(bytes >= 0) {
- atomic_add_and_fetch_z(&unaccounted_mem, bytes);
- }
- else {
- atomic_sub_and_fetch_z(&unaccounted_mem, -bytes);
- }
- }
- return true;
+ Stats *stats = (Stats *)userPtr;
+ if (stats) {
+ if (bytes > 0) {
+ stats->mem_alloc(bytes);
+ }
+ else {
+ stats->mem_free(-bytes);
+ }
+ }
+ else {
+ /* A stats pointer may not yet be available. Keep track of the memory usage for later. */
+ if (bytes >= 0) {
+ atomic_add_and_fetch_z(&unaccounted_mem, bytes);
+ }
+ else {
+ atomic_sub_and_fetch_z(&unaccounted_mem, -bytes);
+ }
+ }
+ return true;
}
-static void rtc_error_func(void*, enum RTCError, const char* str)
+static void rtc_error_func(void *, enum RTCError, const char *str)
{
- VLOG(1) << str;
+ VLOG(1) << str;
}
static double progress_start_time = 0.0f;
-static bool rtc_progress_func(void* user_ptr, const double n)
+static bool rtc_progress_func(void *user_ptr, const double n)
{
- Progress *progress = (Progress*)user_ptr;
+ Progress *progress = (Progress *)user_ptr;
- if(time_dt() - progress_start_time < 0.25) {
- return true;
- }
+ if (time_dt() - progress_start_time < 0.25) {
+ return true;
+ }
- string msg = string_printf("Building BVH %.0f%%", n * 100.0);
- progress->set_substatus(msg);
- progress_start_time = time_dt();
+ string msg = string_printf("Building BVH %.0f%%", n * 100.0);
+ progress->set_substatus(msg);
+ progress_start_time = time_dt();
- return !progress->get_cancel();
+ return !progress->get_cancel();
}
/* This is to have a shared device between all BVH instances.
@@ -281,665 +283,679 @@ RTCDevice BVHEmbree::rtc_shared_device = NULL;
int BVHEmbree::rtc_shared_users = 0;
thread_mutex BVHEmbree::rtc_shared_mutex;
-BVHEmbree::BVHEmbree(const BVHParams& params_, const vector<Object*>& objects_)
-: BVH(params_, objects_), scene(NULL), mem_used(0), top_level(NULL), stats(NULL),
- curve_subdivisions(params.curve_subdivisions), build_quality(RTC_BUILD_QUALITY_REFIT),
- use_curves(params_.curve_flags & CURVE_KN_INTERPOLATE),
- use_ribbons(params.curve_flags & CURVE_KN_RIBBONS), dynamic_scene(true)
+BVHEmbree::BVHEmbree(const BVHParams &params_, const vector<Object *> &objects_)
+ : BVH(params_, objects_),
+ scene(NULL),
+ mem_used(0),
+ top_level(NULL),
+ stats(NULL),
+ curve_subdivisions(params.curve_subdivisions),
+ build_quality(RTC_BUILD_QUALITY_REFIT),
+ use_curves(params_.curve_flags & CURVE_KN_INTERPOLATE),
+ use_ribbons(params.curve_flags & CURVE_KN_RIBBONS),
+ dynamic_scene(true)
{
- _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
- _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
- thread_scoped_lock lock(rtc_shared_mutex);
- if(rtc_shared_users == 0) {
- rtc_shared_device = rtcNewDevice("verbose=0");
- /* Check here if Embree was built with the correct flags. */
- ssize_t ret = rtcGetDeviceProperty (rtc_shared_device,RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED);
- if(ret != 1) {
- assert(0);
- VLOG(1) << "Embree is compiled without the RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED flag."\
- "Ray visiblity will not work.";
- }
- ret = rtcGetDeviceProperty (rtc_shared_device,RTC_DEVICE_PROPERTY_FILTER_FUNCTION_SUPPORTED);
- if(ret != 1) {
- assert(0);
- VLOG(1) << "Embree is compiled without the RTC_DEVICE_PROPERTY_FILTER_FUNCTION_SUPPORTED flag."\
- "Renders may not look as expected.";
- }
- ret = rtcGetDeviceProperty (rtc_shared_device,RTC_DEVICE_PROPERTY_CURVE_GEOMETRY_SUPPORTED);
- if(ret != 1) {
- assert(0);
- VLOG(1) << "Embree is compiled without the RTC_DEVICE_PROPERTY_CURVE_GEOMETRY_SUPPORTED flag. "\
- "Line primitives will not be rendered.";
- }
- ret = rtcGetDeviceProperty (rtc_shared_device,RTC_DEVICE_PROPERTY_TRIANGLE_GEOMETRY_SUPPORTED);
- if(ret != 1) {
- assert(0);
- VLOG(1) << "Embree is compiled without the RTC_DEVICE_PROPERTY_TRIANGLE_GEOMETRY_SUPPORTED flag. "\
- "Triangle primitives will not be rendered.";
- }
- ret = rtcGetDeviceProperty (rtc_shared_device,RTC_DEVICE_PROPERTY_BACKFACE_CULLING_ENABLED);
- if(ret != 0) {
- assert(0);
- VLOG(1) << "Embree is compiled with the RTC_DEVICE_PROPERTY_BACKFACE_CULLING_ENABLED flag. "\
- "Renders may not look as expected.";
- }
- }
- ++rtc_shared_users;
-
- rtcSetDeviceErrorFunction(rtc_shared_device, rtc_error_func, NULL);
-
- pack.root_index = -1;
+ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
+ _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
+ thread_scoped_lock lock(rtc_shared_mutex);
+ if (rtc_shared_users == 0) {
+ rtc_shared_device = rtcNewDevice("verbose=0");
+ /* Check here if Embree was built with the correct flags. */
+ ssize_t ret = rtcGetDeviceProperty(rtc_shared_device, RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED);
+ if (ret != 1) {
+ assert(0);
+ VLOG(1) << "Embree is compiled without the RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED flag."
+ "Ray visiblity will not work.";
+ }
+ ret = rtcGetDeviceProperty(rtc_shared_device, RTC_DEVICE_PROPERTY_FILTER_FUNCTION_SUPPORTED);
+ if (ret != 1) {
+ assert(0);
+ VLOG(1)
+ << "Embree is compiled without the RTC_DEVICE_PROPERTY_FILTER_FUNCTION_SUPPORTED flag."
+ "Renders may not look as expected.";
+ }
+ ret = rtcGetDeviceProperty(rtc_shared_device, RTC_DEVICE_PROPERTY_CURVE_GEOMETRY_SUPPORTED);
+ if (ret != 1) {
+ assert(0);
+ VLOG(1)
+ << "Embree is compiled without the RTC_DEVICE_PROPERTY_CURVE_GEOMETRY_SUPPORTED flag. "
+ "Line primitives will not be rendered.";
+ }
+ ret = rtcGetDeviceProperty(rtc_shared_device, RTC_DEVICE_PROPERTY_TRIANGLE_GEOMETRY_SUPPORTED);
+ if (ret != 1) {
+ assert(0);
+ VLOG(1) << "Embree is compiled without the RTC_DEVICE_PROPERTY_TRIANGLE_GEOMETRY_SUPPORTED "
+ "flag. "
+ "Triangle primitives will not be rendered.";
+ }
+ ret = rtcGetDeviceProperty(rtc_shared_device, RTC_DEVICE_PROPERTY_BACKFACE_CULLING_ENABLED);
+ if (ret != 0) {
+ assert(0);
+ VLOG(1) << "Embree is compiled with the RTC_DEVICE_PROPERTY_BACKFACE_CULLING_ENABLED flag. "
+ "Renders may not look as expected.";
+ }
+ }
+ ++rtc_shared_users;
+
+ rtcSetDeviceErrorFunction(rtc_shared_device, rtc_error_func, NULL);
+
+ pack.root_index = -1;
}
BVHEmbree::~BVHEmbree()
{
- if(!params.top_level) {
- destroy(scene);
- }
+ if (!params.top_level) {
+ destroy(scene);
+ }
}
void BVHEmbree::destroy(RTCScene scene)
{
- if(scene) {
- rtcReleaseScene(scene);
- scene = NULL;
- }
- thread_scoped_lock lock(rtc_shared_mutex);
- --rtc_shared_users;
- if(rtc_shared_users == 0) {
- rtcReleaseDevice (rtc_shared_device);
- rtc_shared_device = NULL;
- }
+ if (scene) {
+ rtcReleaseScene(scene);
+ scene = NULL;
+ }
+ thread_scoped_lock lock(rtc_shared_mutex);
+ --rtc_shared_users;
+ if (rtc_shared_users == 0) {
+ rtcReleaseDevice(rtc_shared_device);
+ rtc_shared_device = NULL;
+ }
}
void BVHEmbree::delete_rtcScene()
{
- if(scene) {
- /* When this BVH is used as an instance in a top level BVH, don't delete now
- * Let the top_level BVH know that it should delete it later. */
- if(top_level) {
- top_level->add_delayed_delete_scene(scene);
- }
- else {
- rtcReleaseScene(scene);
- if(delayed_delete_scenes.size()) {
- foreach(RTCScene s, delayed_delete_scenes) {
- rtcReleaseScene(s);
- }
- }
- delayed_delete_scenes.clear();
- }
- scene = NULL;
- }
+ if (scene) {
+ /* When this BVH is used as an instance in a top level BVH, don't delete now
+ * Let the top_level BVH know that it should delete it later. */
+ if (top_level) {
+ top_level->add_delayed_delete_scene(scene);
+ }
+ else {
+ rtcReleaseScene(scene);
+ if (delayed_delete_scenes.size()) {
+ foreach (RTCScene s, delayed_delete_scenes) {
+ rtcReleaseScene(s);
+ }
+ }
+ delayed_delete_scenes.clear();
+ }
+ scene = NULL;
+ }
}
-void BVHEmbree::build(Progress& progress, Stats *stats_)
+void BVHEmbree::build(Progress &progress, Stats *stats_)
{
- assert(rtc_shared_device);
- stats = stats_;
- rtcSetDeviceMemoryMonitorFunction(rtc_shared_device, rtc_memory_monitor_func, stats);
-
- progress.set_substatus("Building BVH");
-
- if(scene) {
- rtcReleaseScene(scene);
- scene = NULL;
- }
-
- const bool dynamic = params.bvh_type == SceneParams::BVH_DYNAMIC;
-
- scene = rtcNewScene(rtc_shared_device);
- const RTCSceneFlags scene_flags = (dynamic ? RTC_SCENE_FLAG_DYNAMIC : RTC_SCENE_FLAG_NONE) |
- RTC_SCENE_FLAG_COMPACT | RTC_SCENE_FLAG_ROBUST;
- rtcSetSceneFlags(scene, scene_flags);
- build_quality = dynamic ? RTC_BUILD_QUALITY_LOW :
- (params.use_spatial_split ? RTC_BUILD_QUALITY_HIGH : RTC_BUILD_QUALITY_MEDIUM);
- rtcSetSceneBuildQuality(scene, build_quality);
-
- /* Count triangles and curves first, reserve arrays once. */
- size_t prim_count = 0;
-
- foreach(Object *ob, objects) {
- if (params.top_level) {
- if (!ob->is_traceable()) {
- continue;
- }
- if (!ob->mesh->is_instanced()) {
- if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- prim_count += ob->mesh->num_triangles();
- }
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
- prim_count += ob->mesh->get_curve(j).num_segments();
- }
- }
- }
- else {
- ++prim_count;
- }
- }
- else {
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) {
- prim_count += ob->mesh->num_triangles();
- }
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
- prim_count += ob->mesh->get_curve(j).num_segments();
- }
- }
- }
- }
-
- pack.prim_object.reserve(prim_count);
- pack.prim_type.reserve(prim_count);
- pack.prim_index.reserve(prim_count);
- pack.prim_tri_index.reserve(prim_count);
-
- int i = 0;
-
- pack.object_node.clear();
-
- foreach(Object *ob, objects) {
- if(params.top_level) {
- if(!ob->is_traceable()) {
- ++i;
- continue;
- }
- if(!ob->mesh->is_instanced()) {
- add_object(ob, i);
- }
- else {
- add_instance(ob, i);
- }
- }
- else {
- add_object(ob, i);
- }
- ++i;
- if(progress.get_cancel()) return;
- }
-
- if(progress.get_cancel()) {
- delete_rtcScene();
- stats = NULL;
- return;
- }
-
- rtcSetSceneProgressMonitorFunction(scene, rtc_progress_func, &progress);
- rtcCommitScene(scene);
-
- pack_primitives();
-
- if(progress.get_cancel()) {
- delete_rtcScene();
- stats = NULL;
- return;
- }
-
- progress.set_substatus("Packing geometry");
- pack_nodes(NULL);
-
- stats = NULL;
+ assert(rtc_shared_device);
+ stats = stats_;
+ rtcSetDeviceMemoryMonitorFunction(rtc_shared_device, rtc_memory_monitor_func, stats);
+
+ progress.set_substatus("Building BVH");
+
+ if (scene) {
+ rtcReleaseScene(scene);
+ scene = NULL;
+ }
+
+ const bool dynamic = params.bvh_type == SceneParams::BVH_DYNAMIC;
+
+ scene = rtcNewScene(rtc_shared_device);
+ const RTCSceneFlags scene_flags = (dynamic ? RTC_SCENE_FLAG_DYNAMIC : RTC_SCENE_FLAG_NONE) |
+ RTC_SCENE_FLAG_COMPACT | RTC_SCENE_FLAG_ROBUST;
+ rtcSetSceneFlags(scene, scene_flags);
+ build_quality = dynamic ? RTC_BUILD_QUALITY_LOW :
+ (params.use_spatial_split ? RTC_BUILD_QUALITY_HIGH :
+ RTC_BUILD_QUALITY_MEDIUM);
+ rtcSetSceneBuildQuality(scene, build_quality);
+
+ /* Count triangles and curves first, reserve arrays once. */
+ size_t prim_count = 0;
+
+ foreach (Object *ob, objects) {
+ if (params.top_level) {
+ if (!ob->is_traceable()) {
+ continue;
+ }
+ if (!ob->mesh->is_instanced()) {
+ if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
+ prim_count += ob->mesh->num_triangles();
+ }
+ if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
+ for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
+ prim_count += ob->mesh->get_curve(j).num_segments();
+ }
+ }
+ }
+ else {
+ ++prim_count;
+ }
+ }
+ else {
+ if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) {
+ prim_count += ob->mesh->num_triangles();
+ }
+ if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
+ for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
+ prim_count += ob->mesh->get_curve(j).num_segments();
+ }
+ }
+ }
+ }
+
+ pack.prim_object.reserve(prim_count);
+ pack.prim_type.reserve(prim_count);
+ pack.prim_index.reserve(prim_count);
+ pack.prim_tri_index.reserve(prim_count);
+
+ int i = 0;
+
+ pack.object_node.clear();
+
+ foreach (Object *ob, objects) {
+ if (params.top_level) {
+ if (!ob->is_traceable()) {
+ ++i;
+ continue;
+ }
+ if (!ob->mesh->is_instanced()) {
+ add_object(ob, i);
+ }
+ else {
+ add_instance(ob, i);
+ }
+ }
+ else {
+ add_object(ob, i);
+ }
+ ++i;
+ if (progress.get_cancel())
+ return;
+ }
+
+ if (progress.get_cancel()) {
+ delete_rtcScene();
+ stats = NULL;
+ return;
+ }
+
+ rtcSetSceneProgressMonitorFunction(scene, rtc_progress_func, &progress);
+ rtcCommitScene(scene);
+
+ pack_primitives();
+
+ if (progress.get_cancel()) {
+ delete_rtcScene();
+ stats = NULL;
+ return;
+ }
+
+ progress.set_substatus("Packing geometry");
+ pack_nodes(NULL);
+
+ stats = NULL;
}
BVHNode *BVHEmbree::widen_children_nodes(const BVHNode * /*root*/)
{
- assert(!"Must not be called.");
- return NULL;
+ assert(!"Must not be called.");
+ return NULL;
}
void BVHEmbree::add_object(Object *ob, int i)
{
- Mesh *mesh = ob->mesh;
- if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) {
- add_triangles(ob, i);
- }
- if(params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) {
- add_curves(ob, i);
- }
+ Mesh *mesh = ob->mesh;
+ if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) {
+ add_triangles(ob, i);
+ }
+ if (params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) {
+ add_curves(ob, i);
+ }
}
void BVHEmbree::add_instance(Object *ob, int i)
{
- if(!ob || !ob->mesh) {
- assert(0);
- return;
- }
- BVHEmbree *instance_bvh = (BVHEmbree*)(ob->mesh->bvh);
-
- if(instance_bvh->top_level != this) {
- instance_bvh->top_level = this;
- }
-
- const size_t num_motion_steps = ob->use_motion() ? ob->motion.size() : 1;
- RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_INSTANCE);
- rtcSetGeometryInstancedScene(geom_id, instance_bvh->scene);
- rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
-
- if(ob->use_motion()) {
- for(size_t step = 0; step < num_motion_steps; ++step) {
- rtcSetGeometryTransform(geom_id, step, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float*)&ob->motion[step]);
- }
- }
- else {
- rtcSetGeometryTransform(geom_id, 0, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float*)&ob->tfm);
- }
-
- pack.prim_index.push_back_slow(-1);
- pack.prim_object.push_back_slow(i);
- pack.prim_type.push_back_slow(PRIMITIVE_NONE);
- pack.prim_tri_index.push_back_slow(-1);
-
- rtcSetGeometryUserData(geom_id, (void*) instance_bvh->scene);
- rtcSetGeometryMask(geom_id, ob->visibility);
-
- rtcCommitGeometry(geom_id);
- rtcAttachGeometryByID(scene, geom_id, i*2);
- rtcReleaseGeometry(geom_id);
+ if (!ob || !ob->mesh) {
+ assert(0);
+ return;
+ }
+ BVHEmbree *instance_bvh = (BVHEmbree *)(ob->mesh->bvh);
+
+ if (instance_bvh->top_level != this) {
+ instance_bvh->top_level = this;
+ }
+
+ const size_t num_motion_steps = ob->use_motion() ? ob->motion.size() : 1;
+ RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_INSTANCE);
+ rtcSetGeometryInstancedScene(geom_id, instance_bvh->scene);
+ rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
+
+ if (ob->use_motion()) {
+ for (size_t step = 0; step < num_motion_steps; ++step) {
+ rtcSetGeometryTransform(
+ geom_id, step, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float *)&ob->motion[step]);
+ }
+ }
+ else {
+ rtcSetGeometryTransform(geom_id, 0, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float *)&ob->tfm);
+ }
+
+ pack.prim_index.push_back_slow(-1);
+ pack.prim_object.push_back_slow(i);
+ pack.prim_type.push_back_slow(PRIMITIVE_NONE);
+ pack.prim_tri_index.push_back_slow(-1);
+
+ rtcSetGeometryUserData(geom_id, (void *)instance_bvh->scene);
+ rtcSetGeometryMask(geom_id, ob->visibility);
+
+ rtcCommitGeometry(geom_id);
+ rtcAttachGeometryByID(scene, geom_id, i * 2);
+ rtcReleaseGeometry(geom_id);
}
void BVHEmbree::add_triangles(Object *ob, int i)
{
- size_t prim_offset = pack.prim_index.size();
- Mesh *mesh = ob->mesh;
- const Attribute *attr_mP = NULL;
- size_t num_motion_steps = 1;
- if(mesh->has_motion_blur()) {
- attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_mP) {
- num_motion_steps = mesh->motion_steps;
- if(num_motion_steps > RTC_MAX_TIME_STEP_COUNT) {
- assert(0);
- num_motion_steps = RTC_MAX_TIME_STEP_COUNT;
- }
- }
- }
-
- const size_t num_triangles = mesh->num_triangles();
- RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_TRIANGLE);
- rtcSetGeometryBuildQuality(geom_id, build_quality);
- rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
-
- unsigned *rtc_indices = (unsigned*)rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_INDEX, 0,
- RTC_FORMAT_UINT3, sizeof (int) * 3, num_triangles);
- assert(rtc_indices);
- if(!rtc_indices) {
- VLOG(1) << "Embree could not create new geometry buffer for mesh " << mesh->name.c_str() << ".\n";
- return;
- }
- for(size_t j = 0; j < num_triangles; ++j) {
- Mesh::Triangle t = mesh->get_triangle(j);
- rtc_indices[j*3] = t.v[0];
- rtc_indices[j*3+1] = t.v[1];
- rtc_indices[j*3+2] = t.v[2];
- }
-
- update_tri_vertex_buffer(geom_id, mesh);
-
- size_t prim_object_size = pack.prim_object.size();
- pack.prim_object.resize(prim_object_size + num_triangles);
- size_t prim_type_size = pack.prim_type.size();
- pack.prim_type.resize(prim_type_size + num_triangles);
- size_t prim_index_size = pack.prim_index.size();
- pack.prim_index.resize(prim_index_size + num_triangles);
- pack.prim_tri_index.resize(prim_index_size + num_triangles);
- int prim_type = (num_motion_steps > 1 ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE);
-
- for(size_t j = 0; j < num_triangles; ++j) {
- pack.prim_object[prim_object_size + j] = i;
- pack.prim_type[prim_type_size + j] = prim_type;
- pack.prim_index[prim_index_size + j] = j;
- pack.prim_tri_index[prim_index_size + j] = j;
- }
-
- rtcSetGeometryUserData(geom_id, (void*) prim_offset);
- rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func);
- rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func);
- rtcSetGeometryMask(geom_id, ob->visibility);
-
- rtcCommitGeometry(geom_id);
- rtcAttachGeometryByID(scene, geom_id, i*2);
- rtcReleaseGeometry(geom_id);
+ size_t prim_offset = pack.prim_index.size();
+ Mesh *mesh = ob->mesh;
+ const Attribute *attr_mP = NULL;
+ size_t num_motion_steps = 1;
+ if (mesh->has_motion_blur()) {
+ attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_mP) {
+ num_motion_steps = mesh->motion_steps;
+ if (num_motion_steps > RTC_MAX_TIME_STEP_COUNT) {
+ assert(0);
+ num_motion_steps = RTC_MAX_TIME_STEP_COUNT;
+ }
+ }
+ }
+
+ const size_t num_triangles = mesh->num_triangles();
+ RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_TRIANGLE);
+ rtcSetGeometryBuildQuality(geom_id, build_quality);
+ rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
+
+ unsigned *rtc_indices = (unsigned *)rtcSetNewGeometryBuffer(
+ geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(int) * 3, num_triangles);
+ assert(rtc_indices);
+ if (!rtc_indices) {
+ VLOG(1) << "Embree could not create new geometry buffer for mesh " << mesh->name.c_str()
+ << ".\n";
+ return;
+ }
+ for (size_t j = 0; j < num_triangles; ++j) {
+ Mesh::Triangle t = mesh->get_triangle(j);
+ rtc_indices[j * 3] = t.v[0];
+ rtc_indices[j * 3 + 1] = t.v[1];
+ rtc_indices[j * 3 + 2] = t.v[2];
+ }
+
+ update_tri_vertex_buffer(geom_id, mesh);
+
+ size_t prim_object_size = pack.prim_object.size();
+ pack.prim_object.resize(prim_object_size + num_triangles);
+ size_t prim_type_size = pack.prim_type.size();
+ pack.prim_type.resize(prim_type_size + num_triangles);
+ size_t prim_index_size = pack.prim_index.size();
+ pack.prim_index.resize(prim_index_size + num_triangles);
+ pack.prim_tri_index.resize(prim_index_size + num_triangles);
+ int prim_type = (num_motion_steps > 1 ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE);
+
+ for (size_t j = 0; j < num_triangles; ++j) {
+ pack.prim_object[prim_object_size + j] = i;
+ pack.prim_type[prim_type_size + j] = prim_type;
+ pack.prim_index[prim_index_size + j] = j;
+ pack.prim_tri_index[prim_index_size + j] = j;
+ }
+
+ rtcSetGeometryUserData(geom_id, (void *)prim_offset);
+ rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func);
+ rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func);
+ rtcSetGeometryMask(geom_id, ob->visibility);
+
+ rtcCommitGeometry(geom_id);
+ rtcAttachGeometryByID(scene, geom_id, i * 2);
+ rtcReleaseGeometry(geom_id);
}
-void BVHEmbree::update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh* mesh)
+void BVHEmbree::update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh)
{
- const Attribute *attr_mP = NULL;
- size_t num_motion_steps = 1;
- int t_mid = 0;
- if(mesh->has_motion_blur()) {
- attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_mP) {
- num_motion_steps = mesh->motion_steps;
- t_mid = (num_motion_steps - 1) / 2;
- if(num_motion_steps > RTC_MAX_TIME_STEP_COUNT) {
- assert(0);
- num_motion_steps = RTC_MAX_TIME_STEP_COUNT;
- }
- }
- }
- const size_t num_verts = mesh->verts.size();
-
- for(int t = 0; t < num_motion_steps; ++t) {
- const float3 *verts;
- if(t == t_mid) {
- verts = &mesh->verts[0];
- }
- else {
- int t_ = (t > t_mid) ? (t - 1) : t;
- verts = &attr_mP->data_float3()[t_ * num_verts];
- }
-
- float *rtc_verts = (float*) rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_VERTEX, t,
- RTC_FORMAT_FLOAT3, sizeof(float) * 3, num_verts + 1);
- assert(rtc_verts);
- if(rtc_verts) {
- for(size_t j = 0; j < num_verts; ++j) {
- rtc_verts[0] = verts[j].x;
- rtc_verts[1] = verts[j].y;
- rtc_verts[2] = verts[j].z;
- rtc_verts += 3;
- }
- }
- }
+ const Attribute *attr_mP = NULL;
+ size_t num_motion_steps = 1;
+ int t_mid = 0;
+ if (mesh->has_motion_blur()) {
+ attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_mP) {
+ num_motion_steps = mesh->motion_steps;
+ t_mid = (num_motion_steps - 1) / 2;
+ if (num_motion_steps > RTC_MAX_TIME_STEP_COUNT) {
+ assert(0);
+ num_motion_steps = RTC_MAX_TIME_STEP_COUNT;
+ }
+ }
+ }
+ const size_t num_verts = mesh->verts.size();
+
+ for (int t = 0; t < num_motion_steps; ++t) {
+ const float3 *verts;
+ if (t == t_mid) {
+ verts = &mesh->verts[0];
+ }
+ else {
+ int t_ = (t > t_mid) ? (t - 1) : t;
+ verts = &attr_mP->data_float3()[t_ * num_verts];
+ }
+
+ float *rtc_verts = (float *)rtcSetNewGeometryBuffer(
+ geom_id, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT3, sizeof(float) * 3, num_verts + 1);
+ assert(rtc_verts);
+ if (rtc_verts) {
+ for (size_t j = 0; j < num_verts; ++j) {
+ rtc_verts[0] = verts[j].x;
+ rtc_verts[1] = verts[j].y;
+ rtc_verts[2] = verts[j].z;
+ rtc_verts += 3;
+ }
+ }
+ }
}
-void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh* mesh)
+void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh)
{
- const Attribute *attr_mP = NULL;
- size_t num_motion_steps = 1;
- if(mesh->has_motion_blur()) {
- attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_mP) {
- num_motion_steps = mesh->motion_steps;
- }
- }
-
- const size_t num_curves = mesh->num_curves();
- size_t num_keys = 0;
- for(size_t j = 0; j < num_curves; ++j) {
- const Mesh::Curve c = mesh->get_curve(j);
- num_keys += c.num_keys;
- }
-
- /* Copy the CV data to Embree */
- const int t_mid = (num_motion_steps - 1) / 2;
- const float *curve_radius = &mesh->curve_radius[0];
- for(int t = 0; t < num_motion_steps; ++t) {
- const float3 *verts;
- if(t == t_mid || attr_mP == NULL) {
- verts = &mesh->curve_keys[0];
- }
- else {
- int t_ = (t > t_mid) ? (t - 1) : t;
- verts = &attr_mP->data_float3()[t_ * num_keys];
- }
-
- float4 *rtc_verts = (float4*)rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_VERTEX, t,
- RTC_FORMAT_FLOAT4, sizeof (float) * 4, num_keys);
- float4 *rtc_tangents = NULL;
- if(use_curves) {
- rtc_tangents = (float4*)rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_TANGENT, t,
- RTC_FORMAT_FLOAT4, sizeof (float) * 4, num_keys);
- assert(rtc_tangents);
- }
- assert(rtc_verts);
- if(rtc_verts) {
- if(use_curves && rtc_tangents) {
- const size_t num_curves = mesh->num_curves();
- for(size_t j = 0; j < num_curves; ++j) {
- Mesh::Curve c = mesh->get_curve(j);
- int fk = c.first_key;
- rtc_verts[0] = float3_to_float4(verts[fk]);
- rtc_verts[0].w = curve_radius[fk];
- rtc_tangents[0] = float3_to_float4(verts[fk + 1] - verts[fk]);
- rtc_tangents[0].w = curve_radius[fk + 1] - curve_radius[fk];
- ++fk;
- int k = 1;
- for(;k < c.num_segments(); ++k, ++fk) {
- rtc_verts[k] = float3_to_float4(verts[fk]);
- rtc_verts[k].w = curve_radius[fk];
- rtc_tangents[k] = float3_to_float4((verts[fk + 1] - verts[fk - 1]) * 0.5f);
- rtc_tangents[k].w = (curve_radius[fk + 1] - curve_radius[fk - 1]) * 0.5f;
- }
- rtc_verts[k] = float3_to_float4(verts[fk]);
- rtc_verts[k].w = curve_radius[fk];
- rtc_tangents[k] = float3_to_float4(verts[fk] - verts[fk - 1]);
- rtc_tangents[k].w = curve_radius[fk] - curve_radius[fk - 1];
- rtc_verts += c.num_keys;
- rtc_tangents += c.num_keys;
- }
- }
- else {
- for(size_t j = 0; j < num_keys; ++j) {
- rtc_verts[j] = float3_to_float4(verts[j]);
- rtc_verts[j].w = curve_radius[j];
- }
- }
- }
- }
+ const Attribute *attr_mP = NULL;
+ size_t num_motion_steps = 1;
+ if (mesh->has_motion_blur()) {
+ attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_mP) {
+ num_motion_steps = mesh->motion_steps;
+ }
+ }
+
+ const size_t num_curves = mesh->num_curves();
+ size_t num_keys = 0;
+ for (size_t j = 0; j < num_curves; ++j) {
+ const Mesh::Curve c = mesh->get_curve(j);
+ num_keys += c.num_keys;
+ }
+
+ /* Copy the CV data to Embree */
+ const int t_mid = (num_motion_steps - 1) / 2;
+ const float *curve_radius = &mesh->curve_radius[0];
+ for (int t = 0; t < num_motion_steps; ++t) {
+ const float3 *verts;
+ if (t == t_mid || attr_mP == NULL) {
+ verts = &mesh->curve_keys[0];
+ }
+ else {
+ int t_ = (t > t_mid) ? (t - 1) : t;
+ verts = &attr_mP->data_float3()[t_ * num_keys];
+ }
+
+ float4 *rtc_verts = (float4 *)rtcSetNewGeometryBuffer(
+ geom_id, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT4, sizeof(float) * 4, num_keys);
+ float4 *rtc_tangents = NULL;
+ if (use_curves) {
+ rtc_tangents = (float4 *)rtcSetNewGeometryBuffer(
+ geom_id, RTC_BUFFER_TYPE_TANGENT, t, RTC_FORMAT_FLOAT4, sizeof(float) * 4, num_keys);
+ assert(rtc_tangents);
+ }
+ assert(rtc_verts);
+ if (rtc_verts) {
+ if (use_curves && rtc_tangents) {
+ const size_t num_curves = mesh->num_curves();
+ for (size_t j = 0; j < num_curves; ++j) {
+ Mesh::Curve c = mesh->get_curve(j);
+ int fk = c.first_key;
+ rtc_verts[0] = float3_to_float4(verts[fk]);
+ rtc_verts[0].w = curve_radius[fk];
+ rtc_tangents[0] = float3_to_float4(verts[fk + 1] - verts[fk]);
+ rtc_tangents[0].w = curve_radius[fk + 1] - curve_radius[fk];
+ ++fk;
+ int k = 1;
+ for (; k < c.num_segments(); ++k, ++fk) {
+ rtc_verts[k] = float3_to_float4(verts[fk]);
+ rtc_verts[k].w = curve_radius[fk];
+ rtc_tangents[k] = float3_to_float4((verts[fk + 1] - verts[fk - 1]) * 0.5f);
+ rtc_tangents[k].w = (curve_radius[fk + 1] - curve_radius[fk - 1]) * 0.5f;
+ }
+ rtc_verts[k] = float3_to_float4(verts[fk]);
+ rtc_verts[k].w = curve_radius[fk];
+ rtc_tangents[k] = float3_to_float4(verts[fk] - verts[fk - 1]);
+ rtc_tangents[k].w = curve_radius[fk] - curve_radius[fk - 1];
+ rtc_verts += c.num_keys;
+ rtc_tangents += c.num_keys;
+ }
+ }
+ else {
+ for (size_t j = 0; j < num_keys; ++j) {
+ rtc_verts[j] = float3_to_float4(verts[j]);
+ rtc_verts[j].w = curve_radius[j];
+ }
+ }
+ }
+ }
}
void BVHEmbree::add_curves(Object *ob, int i)
{
- size_t prim_offset = pack.prim_index.size();
- const Mesh *mesh = ob->mesh;
- const Attribute *attr_mP = NULL;
- size_t num_motion_steps = 1;
- if(mesh->has_motion_blur()) {
- attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_mP) {
- num_motion_steps = mesh->motion_steps;
- }
- }
-
- const size_t num_curves = mesh->num_curves();
- size_t num_segments = 0;
- for(size_t j = 0; j < num_curves; ++j) {
- Mesh::Curve c = mesh->get_curve(j);
- assert(c.num_segments() > 0);
- num_segments += c.num_segments();
- }
-
- /* Make room for Cycles specific data. */
- size_t prim_object_size = pack.prim_object.size();
- pack.prim_object.resize(prim_object_size + num_segments);
- size_t prim_type_size = pack.prim_type.size();
- pack.prim_type.resize(prim_type_size + num_segments);
- size_t prim_index_size = pack.prim_index.size();
- pack.prim_index.resize(prim_index_size + num_segments);
- size_t prim_tri_index_size = pack.prim_index.size();
- pack.prim_tri_index.resize(prim_tri_index_size + num_segments);
-
- enum RTCGeometryType type = (!use_curves) ? RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE :
- (use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE :
- RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE);
-
- RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, type);
- rtcSetGeometryTessellationRate(geom_id, curve_subdivisions);
- unsigned *rtc_indices = (unsigned*) rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_INDEX, 0,
- RTC_FORMAT_UINT, sizeof (int), num_segments);
- size_t rtc_index = 0;
- for(size_t j = 0; j < num_curves; ++j) {
- Mesh::Curve c = mesh->get_curve(j);
- for(size_t k = 0; k < c.num_segments(); ++k) {
- rtc_indices[rtc_index] = c.first_key + k;
- /* Cycles specific data. */
- pack.prim_object[prim_object_size + rtc_index] = i;
- pack.prim_type[prim_type_size + rtc_index] = (PRIMITIVE_PACK_SEGMENT(num_motion_steps > 1 ?
- PRIMITIVE_MOTION_CURVE : PRIMITIVE_CURVE, k));
- pack.prim_index[prim_index_size + rtc_index] = j;
- pack.prim_tri_index[prim_tri_index_size + rtc_index] = rtc_index;
-
- ++rtc_index;
- }
- }
-
- rtcSetGeometryBuildQuality(geom_id, build_quality);
- rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
-
- update_curve_vertex_buffer(geom_id, mesh);
-
- rtcSetGeometryUserData(geom_id, (void*) prim_offset);
- rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func);
- rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func);
- rtcSetGeometryMask(geom_id, ob->visibility);
-
- rtcCommitGeometry(geom_id);
- rtcAttachGeometryByID(scene, geom_id, i * 2 + 1);
- rtcReleaseGeometry(geom_id);
+ size_t prim_offset = pack.prim_index.size();
+ const Mesh *mesh = ob->mesh;
+ const Attribute *attr_mP = NULL;
+ size_t num_motion_steps = 1;
+ if (mesh->has_motion_blur()) {
+ attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_mP) {
+ num_motion_steps = mesh->motion_steps;
+ }
+ }
+
+ const size_t num_curves = mesh->num_curves();
+ size_t num_segments = 0;
+ for (size_t j = 0; j < num_curves; ++j) {
+ Mesh::Curve c = mesh->get_curve(j);
+ assert(c.num_segments() > 0);
+ num_segments += c.num_segments();
+ }
+
+ /* Make room for Cycles specific data. */
+ size_t prim_object_size = pack.prim_object.size();
+ pack.prim_object.resize(prim_object_size + num_segments);
+ size_t prim_type_size = pack.prim_type.size();
+ pack.prim_type.resize(prim_type_size + num_segments);
+ size_t prim_index_size = pack.prim_index.size();
+ pack.prim_index.resize(prim_index_size + num_segments);
+ size_t prim_tri_index_size = pack.prim_index.size();
+ pack.prim_tri_index.resize(prim_tri_index_size + num_segments);
+
+ enum RTCGeometryType type = (!use_curves) ?
+ RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE :
+ (use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE :
+ RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE);
+
+ RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, type);
+ rtcSetGeometryTessellationRate(geom_id, curve_subdivisions);
+ unsigned *rtc_indices = (unsigned *)rtcSetNewGeometryBuffer(
+ geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT, sizeof(int), num_segments);
+ size_t rtc_index = 0;
+ for (size_t j = 0; j < num_curves; ++j) {
+ Mesh::Curve c = mesh->get_curve(j);
+ for (size_t k = 0; k < c.num_segments(); ++k) {
+ rtc_indices[rtc_index] = c.first_key + k;
+ /* Cycles specific data. */
+ pack.prim_object[prim_object_size + rtc_index] = i;
+ pack.prim_type[prim_type_size + rtc_index] = (PRIMITIVE_PACK_SEGMENT(
+ num_motion_steps > 1 ? PRIMITIVE_MOTION_CURVE : PRIMITIVE_CURVE, k));
+ pack.prim_index[prim_index_size + rtc_index] = j;
+ pack.prim_tri_index[prim_tri_index_size + rtc_index] = rtc_index;
+
+ ++rtc_index;
+ }
+ }
+
+ rtcSetGeometryBuildQuality(geom_id, build_quality);
+ rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
+
+ update_curve_vertex_buffer(geom_id, mesh);
+
+ rtcSetGeometryUserData(geom_id, (void *)prim_offset);
+ rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func);
+ rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func);
+ rtcSetGeometryMask(geom_id, ob->visibility);
+
+ rtcCommitGeometry(geom_id);
+ rtcAttachGeometryByID(scene, geom_id, i * 2 + 1);
+ rtcReleaseGeometry(geom_id);
}
void BVHEmbree::pack_nodes(const BVHNode *)
{
- /* Quite a bit of this code is for compatibility with Cycles' native BVH. */
- if(!params.top_level) {
- return;
- }
-
- for(size_t i = 0; i < pack.prim_index.size(); ++i) {
- if(pack.prim_index[i] != -1) {
- if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
- else
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
- }
- }
-
- size_t prim_offset = pack.prim_index.size();
-
- /* reserve */
- size_t prim_index_size = pack.prim_index.size();
- size_t prim_tri_verts_size = pack.prim_tri_verts.size();
-
- size_t pack_prim_index_offset = prim_index_size;
- size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
- size_t object_offset = 0;
-
- map<Mesh*, int> mesh_map;
-
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
- BVH *bvh = mesh->bvh;
-
- if(mesh->need_build_bvh()) {
- if(mesh_map.find(mesh) == mesh_map.end()) {
- prim_index_size += bvh->pack.prim_index.size();
- prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
- mesh_map[mesh] = 1;
- }
- }
- }
-
- mesh_map.clear();
-
- pack.prim_index.resize(prim_index_size);
- pack.prim_type.resize(prim_index_size);
- pack.prim_object.resize(prim_index_size);
- pack.prim_visibility.clear();
- pack.prim_tri_verts.resize(prim_tri_verts_size);
- pack.prim_tri_index.resize(prim_index_size);
- pack.object_node.resize(objects.size());
-
- int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
- int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
- int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
- float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size())? &pack.prim_tri_verts[0]: NULL;
- uint *pack_prim_tri_index = (pack.prim_tri_index.size())? &pack.prim_tri_index[0]: NULL;
-
- /* merge */
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
-
- /* We assume that if mesh doesn't need own BVH it was already included
- * into a top-level BVH and no packing here is needed.
- */
- if(!mesh->need_build_bvh()) {
- pack.object_node[object_offset++] = prim_offset;
- continue;
- }
-
- /* if mesh already added once, don't add it again, but used set
- * node offset for this object */
- map<Mesh*, int>::iterator it = mesh_map.find(mesh);
-
- if(mesh_map.find(mesh) != mesh_map.end()) {
- int noffset = it->second;
- pack.object_node[object_offset++] = noffset;
- continue;
- }
-
- BVHEmbree *bvh = (BVHEmbree*)mesh->bvh;
-
- rtc_memory_monitor_func(stats, unaccounted_mem, true);
- unaccounted_mem = 0;
-
- int mesh_tri_offset = mesh->tri_offset;
- int mesh_curve_offset = mesh->curve_offset;
-
- /* fill in node indexes for instances */
- pack.object_node[object_offset++] = prim_offset;
-
- mesh_map[mesh] = pack.object_node[object_offset-1];
-
- /* merge primitive, object and triangle indexes */
- if(bvh->pack.prim_index.size()) {
- size_t bvh_prim_index_size = bvh->pack.prim_index.size();
- int *bvh_prim_index = &bvh->pack.prim_index[0];
- int *bvh_prim_type = &bvh->pack.prim_type[0];
- uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
-
- for(size_t i = 0; i < bvh_prim_index_size; ++i) {
- if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
- pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
- pack_prim_tri_index[pack_prim_index_offset] = -1;
- }
- else {
- pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
- pack_prim_tri_index[pack_prim_index_offset] =
- bvh_prim_tri_index[i] + pack_prim_tri_verts_offset;
- }
-
- pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
- pack_prim_object[pack_prim_index_offset] = 0;
-
- ++pack_prim_index_offset;
- }
- }
-
- /* Merge triangle vertices data. */
- if(bvh->pack.prim_tri_verts.size()) {
- const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
- memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
- &bvh->pack.prim_tri_verts[0],
- prim_tri_size*sizeof(float4));
- pack_prim_tri_verts_offset += prim_tri_size;
- }
-
- prim_offset += bvh->pack.prim_index.size();
- }
+ /* Quite a bit of this code is for compatibility with Cycles' native BVH. */
+ if (!params.top_level) {
+ return;
+ }
+
+ for (size_t i = 0; i < pack.prim_index.size(); ++i) {
+ if (pack.prim_index[i] != -1) {
+ if (pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
+ else
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ }
+ }
+
+ size_t prim_offset = pack.prim_index.size();
+
+ /* reserve */
+ size_t prim_index_size = pack.prim_index.size();
+ size_t prim_tri_verts_size = pack.prim_tri_verts.size();
+
+ size_t pack_prim_index_offset = prim_index_size;
+ size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
+ size_t object_offset = 0;
+
+ map<Mesh *, int> mesh_map;
+
+ foreach (Object *ob, objects) {
+ Mesh *mesh = ob->mesh;
+ BVH *bvh = mesh->bvh;
+
+ if (mesh->need_build_bvh()) {
+ if (mesh_map.find(mesh) == mesh_map.end()) {
+ prim_index_size += bvh->pack.prim_index.size();
+ prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
+ mesh_map[mesh] = 1;
+ }
+ }
+ }
+
+ mesh_map.clear();
+
+ pack.prim_index.resize(prim_index_size);
+ pack.prim_type.resize(prim_index_size);
+ pack.prim_object.resize(prim_index_size);
+ pack.prim_visibility.clear();
+ pack.prim_tri_verts.resize(prim_tri_verts_size);
+ pack.prim_tri_index.resize(prim_index_size);
+ pack.object_node.resize(objects.size());
+
+ int *pack_prim_index = (pack.prim_index.size()) ? &pack.prim_index[0] : NULL;
+ int *pack_prim_type = (pack.prim_type.size()) ? &pack.prim_type[0] : NULL;
+ int *pack_prim_object = (pack.prim_object.size()) ? &pack.prim_object[0] : NULL;
+ float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size()) ? &pack.prim_tri_verts[0] : NULL;
+ uint *pack_prim_tri_index = (pack.prim_tri_index.size()) ? &pack.prim_tri_index[0] : NULL;
+
+ /* merge */
+ foreach (Object *ob, objects) {
+ Mesh *mesh = ob->mesh;
+
+ /* We assume that if mesh doesn't need own BVH it was already included
+ * into a top-level BVH and no packing here is needed.
+ */
+ if (!mesh->need_build_bvh()) {
+ pack.object_node[object_offset++] = prim_offset;
+ continue;
+ }
+
+ /* if mesh already added once, don't add it again, but used set
+ * node offset for this object */
+ map<Mesh *, int>::iterator it = mesh_map.find(mesh);
+
+ if (mesh_map.find(mesh) != mesh_map.end()) {
+ int noffset = it->second;
+ pack.object_node[object_offset++] = noffset;
+ continue;
+ }
+
+ BVHEmbree *bvh = (BVHEmbree *)mesh->bvh;
+
+ rtc_memory_monitor_func(stats, unaccounted_mem, true);
+ unaccounted_mem = 0;
+
+ int mesh_tri_offset = mesh->tri_offset;
+ int mesh_curve_offset = mesh->curve_offset;
+
+ /* fill in node indexes for instances */
+ pack.object_node[object_offset++] = prim_offset;
+
+ mesh_map[mesh] = pack.object_node[object_offset - 1];
+
+ /* merge primitive, object and triangle indexes */
+ if (bvh->pack.prim_index.size()) {
+ size_t bvh_prim_index_size = bvh->pack.prim_index.size();
+ int *bvh_prim_index = &bvh->pack.prim_index[0];
+ int *bvh_prim_type = &bvh->pack.prim_type[0];
+ uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
+
+ for (size_t i = 0; i < bvh_prim_index_size; ++i) {
+ if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
+ pack_prim_tri_index[pack_prim_index_offset] = -1;
+ }
+ else {
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
+ pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] +
+ pack_prim_tri_verts_offset;
+ }
+
+ pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
+ pack_prim_object[pack_prim_index_offset] = 0;
+
+ ++pack_prim_index_offset;
+ }
+ }
+
+ /* Merge triangle vertices data. */
+ if (bvh->pack.prim_tri_verts.size()) {
+ const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
+ memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
+ &bvh->pack.prim_tri_verts[0],
+ prim_tri_size * sizeof(float4));
+ pack_prim_tri_verts_offset += prim_tri_size;
+ }
+
+ prim_offset += bvh->pack.prim_index.size();
+ }
}
void BVHEmbree::refit_nodes()
{
- /* Update all vertex buffers, then tell Embree to rebuild/-fit the BVHs. */
- unsigned geom_id = 0;
- foreach(Object *ob, objects) {
- if(!params.top_level || (ob->is_traceable() && !ob->mesh->is_instanced())) {
- if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) {
- update_tri_vertex_buffer(rtcGetGeometry(scene, geom_id), ob->mesh);
- rtcCommitGeometry(rtcGetGeometry(scene,geom_id));
- }
-
- if(params.primitive_mask & PRIMITIVE_ALL_CURVE && ob->mesh->num_curves() > 0) {
- update_curve_vertex_buffer(rtcGetGeometry(scene, geom_id+1), ob->mesh);
- rtcCommitGeometry(rtcGetGeometry(scene,geom_id+1));
- }
- }
- geom_id += 2;
- }
- rtcCommitScene(scene);
+ /* Update all vertex buffers, then tell Embree to rebuild/-fit the BVHs. */
+ unsigned geom_id = 0;
+ foreach (Object *ob, objects) {
+ if (!params.top_level || (ob->is_traceable() && !ob->mesh->is_instanced())) {
+ if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) {
+ update_tri_vertex_buffer(rtcGetGeometry(scene, geom_id), ob->mesh);
+ rtcCommitGeometry(rtcGetGeometry(scene, geom_id));
+ }
+
+ if (params.primitive_mask & PRIMITIVE_ALL_CURVE && ob->mesh->num_curves() > 0) {
+ update_curve_vertex_buffer(rtcGetGeometry(scene, geom_id + 1), ob->mesh);
+ rtcCommitGeometry(rtcGetGeometry(scene, geom_id + 1));
+ }
+ }
+ geom_id += 2;
+ }
+ rtcCommitScene(scene);
}
CCL_NAMESPACE_END
-#endif /* WITH_EMBREE */
+#endif /* WITH_EMBREE */
diff --git a/intern/cycles/bvh/bvh_embree.h b/intern/cycles/bvh/bvh_embree.h
index 983b6dc07da..60702713583 100644
--- a/intern/cycles/bvh/bvh_embree.h
+++ b/intern/cycles/bvh/bvh_embree.h
@@ -19,65 +19,68 @@
#ifdef WITH_EMBREE
-#include <embree3/rtcore.h>
-#include <embree3/rtcore_scene.h>
+# include <embree3/rtcore.h>
+# include <embree3/rtcore_scene.h>
-#include "bvh/bvh.h"
-#include "bvh/bvh_params.h"
+# include "bvh/bvh.h"
+# include "bvh/bvh_params.h"
-#include "util/util_thread.h"
-#include "util/util_types.h"
-#include "util/util_vector.h"
+# include "util/util_thread.h"
+# include "util/util_types.h"
+# include "util/util_vector.h"
CCL_NAMESPACE_BEGIN
class Mesh;
-class BVHEmbree : public BVH
-{
-public:
- virtual void build(Progress& progress, Stats *stats) override;
- virtual ~BVHEmbree();
- RTCScene scene;
- static void destroy(RTCScene);
-
- /* Building process. */
- virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
-
-protected:
- friend class BVH;
- BVHEmbree(const BVHParams& params, const vector<Object*>& objects);
-
- virtual void pack_nodes(const BVHNode*) override;
- virtual void refit_nodes() override;
-
- void add_object(Object *ob, int i);
- void add_instance(Object *ob, int i);
- void add_curves(Object *ob, int i);
- void add_triangles(Object *ob, int i);
-
- ssize_t mem_used;
-
- void add_delayed_delete_scene(RTCScene scene) { delayed_delete_scenes.push_back(scene); }
- BVHEmbree *top_level;
-private:
- void delete_rtcScene();
- void update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh* mesh);
- void update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh* mesh);
-
- static RTCDevice rtc_shared_device;
- static int rtc_shared_users;
- static thread_mutex rtc_shared_mutex;
-
- Stats *stats;
- vector<RTCScene> delayed_delete_scenes;
- int curve_subdivisions;
- enum RTCBuildQuality build_quality;
- bool use_curves, use_ribbons, dynamic_scene;
+class BVHEmbree : public BVH {
+ public:
+ virtual void build(Progress &progress, Stats *stats) override;
+ virtual ~BVHEmbree();
+ RTCScene scene;
+ static void destroy(RTCScene);
+
+ /* Building process. */
+ virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
+
+ protected:
+ friend class BVH;
+ BVHEmbree(const BVHParams &params, const vector<Object *> &objects);
+
+ virtual void pack_nodes(const BVHNode *) override;
+ virtual void refit_nodes() override;
+
+ void add_object(Object *ob, int i);
+ void add_instance(Object *ob, int i);
+ void add_curves(Object *ob, int i);
+ void add_triangles(Object *ob, int i);
+
+ ssize_t mem_used;
+
+ void add_delayed_delete_scene(RTCScene scene)
+ {
+ delayed_delete_scenes.push_back(scene);
+ }
+ BVHEmbree *top_level;
+
+ private:
+ void delete_rtcScene();
+ void update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh);
+ void update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh);
+
+ static RTCDevice rtc_shared_device;
+ static int rtc_shared_users;
+ static thread_mutex rtc_shared_mutex;
+
+ Stats *stats;
+ vector<RTCScene> delayed_delete_scenes;
+ int curve_subdivisions;
+ enum RTCBuildQuality build_quality;
+ bool use_curves, use_ribbons, dynamic_scene;
};
CCL_NAMESPACE_END
-#endif /* WITH_EMBREE */
+#endif /* WITH_EMBREE */
-#endif /* __BVH_EMBREE_H__ */
+#endif /* __BVH_EMBREE_H__ */
diff --git a/intern/cycles/bvh/bvh_node.cpp b/intern/cycles/bvh/bvh_node.cpp
index 614fb6be88a..38b554acfbf 100644
--- a/intern/cycles/bvh/bvh_node.cpp
+++ b/intern/cycles/bvh/bvh_node.cpp
@@ -28,199 +28,197 @@ CCL_NAMESPACE_BEGIN
int BVHNode::getSubtreeSize(BVH_STAT stat) const
{
- int cnt = 0;
-
- switch(stat)
- {
- case BVH_STAT_NODE_COUNT:
- cnt = 1;
- break;
- case BVH_STAT_LEAF_COUNT:
- cnt = is_leaf() ? 1 : 0;
- break;
- case BVH_STAT_INNER_COUNT:
- cnt = is_leaf() ? 0 : 1;
- break;
- case BVH_STAT_TRIANGLE_COUNT:
- cnt = is_leaf() ? reinterpret_cast<const LeafNode*>(this)->num_triangles() : 0;
- break;
- case BVH_STAT_CHILDNODE_COUNT:
- cnt = num_children();
- break;
- case BVH_STAT_ALIGNED_COUNT:
- if(!is_unaligned) {
- cnt = 1;
- }
- break;
- case BVH_STAT_UNALIGNED_COUNT:
- if(is_unaligned) {
- cnt = 1;
- }
- break;
- case BVH_STAT_ALIGNED_INNER_COUNT:
- if(!is_leaf()) {
- bool has_unaligned = false;
- for(int j = 0; j < num_children(); j++) {
- has_unaligned |= get_child(j)->is_unaligned;
- }
- cnt += has_unaligned? 0: 1;
- }
- break;
- case BVH_STAT_UNALIGNED_INNER_COUNT:
- if(!is_leaf()) {
- bool has_unaligned = false;
- for(int j = 0; j < num_children(); j++) {
- has_unaligned |= get_child(j)->is_unaligned;
- }
- cnt += has_unaligned? 1: 0;
- }
- break;
- case BVH_STAT_ALIGNED_LEAF_COUNT:
- cnt = (is_leaf() && !is_unaligned) ? 1 : 0;
- break;
- case BVH_STAT_UNALIGNED_LEAF_COUNT:
- cnt = (is_leaf() && is_unaligned) ? 1 : 0;
- break;
- case BVH_STAT_DEPTH:
- if(is_leaf()) {
- cnt = 1;
- }
- else {
- for(int i = 0; i < num_children(); i++) {
- cnt = max(cnt, get_child(i)->getSubtreeSize(stat));
- }
- cnt += 1;
- }
- return cnt;
- default:
- assert(0); /* unknown mode */
- }
-
- if(!is_leaf())
- for(int i = 0; i < num_children(); i++)
- cnt += get_child(i)->getSubtreeSize(stat);
-
- return cnt;
+ int cnt = 0;
+
+ switch (stat) {
+ case BVH_STAT_NODE_COUNT:
+ cnt = 1;
+ break;
+ case BVH_STAT_LEAF_COUNT:
+ cnt = is_leaf() ? 1 : 0;
+ break;
+ case BVH_STAT_INNER_COUNT:
+ cnt = is_leaf() ? 0 : 1;
+ break;
+ case BVH_STAT_TRIANGLE_COUNT:
+ cnt = is_leaf() ? reinterpret_cast<const LeafNode *>(this)->num_triangles() : 0;
+ break;
+ case BVH_STAT_CHILDNODE_COUNT:
+ cnt = num_children();
+ break;
+ case BVH_STAT_ALIGNED_COUNT:
+ if (!is_unaligned) {
+ cnt = 1;
+ }
+ break;
+ case BVH_STAT_UNALIGNED_COUNT:
+ if (is_unaligned) {
+ cnt = 1;
+ }
+ break;
+ case BVH_STAT_ALIGNED_INNER_COUNT:
+ if (!is_leaf()) {
+ bool has_unaligned = false;
+ for (int j = 0; j < num_children(); j++) {
+ has_unaligned |= get_child(j)->is_unaligned;
+ }
+ cnt += has_unaligned ? 0 : 1;
+ }
+ break;
+ case BVH_STAT_UNALIGNED_INNER_COUNT:
+ if (!is_leaf()) {
+ bool has_unaligned = false;
+ for (int j = 0; j < num_children(); j++) {
+ has_unaligned |= get_child(j)->is_unaligned;
+ }
+ cnt += has_unaligned ? 1 : 0;
+ }
+ break;
+ case BVH_STAT_ALIGNED_LEAF_COUNT:
+ cnt = (is_leaf() && !is_unaligned) ? 1 : 0;
+ break;
+ case BVH_STAT_UNALIGNED_LEAF_COUNT:
+ cnt = (is_leaf() && is_unaligned) ? 1 : 0;
+ break;
+ case BVH_STAT_DEPTH:
+ if (is_leaf()) {
+ cnt = 1;
+ }
+ else {
+ for (int i = 0; i < num_children(); i++) {
+ cnt = max(cnt, get_child(i)->getSubtreeSize(stat));
+ }
+ cnt += 1;
+ }
+ return cnt;
+ default:
+ assert(0); /* unknown mode */
+ }
+
+ if (!is_leaf())
+ for (int i = 0; i < num_children(); i++)
+ cnt += get_child(i)->getSubtreeSize(stat);
+
+ return cnt;
}
void BVHNode::deleteSubtree()
{
- for(int i = 0; i < num_children(); i++)
- if(get_child(i))
- get_child(i)->deleteSubtree();
+ for (int i = 0; i < num_children(); i++)
+ if (get_child(i))
+ get_child(i)->deleteSubtree();
- delete this;
+ delete this;
}
-float BVHNode::computeSubtreeSAHCost(const BVHParams& p, float probability) const
+float BVHNode::computeSubtreeSAHCost(const BVHParams &p, float probability) const
{
- float SAH = probability * p.cost(num_children(), num_triangles());
+ float SAH = probability * p.cost(num_children(), num_triangles());
- for(int i = 0; i < num_children(); i++) {
- BVHNode *child = get_child(i);
- SAH += child->computeSubtreeSAHCost(p, probability * child->bounds.safe_area()/bounds.safe_area());
- }
+ for (int i = 0; i < num_children(); i++) {
+ BVHNode *child = get_child(i);
+ SAH += child->computeSubtreeSAHCost(
+ p, probability * child->bounds.safe_area() / bounds.safe_area());
+ }
- return SAH;
+ return SAH;
}
uint BVHNode::update_visibility()
{
- if(!is_leaf() && visibility == 0) {
- InnerNode *inner = (InnerNode*)this;
- BVHNode *child0 = inner->children[0];
- BVHNode *child1 = inner->children[1];
+ if (!is_leaf() && visibility == 0) {
+ InnerNode *inner = (InnerNode *)this;
+ BVHNode *child0 = inner->children[0];
+ BVHNode *child1 = inner->children[1];
- visibility = child0->update_visibility()|child1->update_visibility();
- }
+ visibility = child0->update_visibility() | child1->update_visibility();
+ }
- return visibility;
+ return visibility;
}
void BVHNode::update_time()
{
- if(!is_leaf()) {
- InnerNode *inner = (InnerNode*)this;
- BVHNode *child0 = inner->children[0];
- BVHNode *child1 = inner->children[1];
- child0->update_time();
- child1->update_time();
- time_from = min(child0->time_from, child1->time_from);
- time_to = max(child0->time_to, child1->time_to);
- }
+ if (!is_leaf()) {
+ InnerNode *inner = (InnerNode *)this;
+ BVHNode *child0 = inner->children[0];
+ BVHNode *child1 = inner->children[1];
+ child0->update_time();
+ child1->update_time();
+ time_from = min(child0->time_from, child1->time_from);
+ time_to = max(child0->time_to, child1->time_to);
+ }
}
namespace {
struct DumpTraversalContext {
- /* Descriptor of wile where writing is happening. */
- FILE *stream;
- /* Unique identifier of the node current. */
- int id;
+ /* Descriptor of wile where writing is happening. */
+ FILE *stream;
+ /* Unique identifier of the node current. */
+ int id;
};
-void dump_subtree(DumpTraversalContext *context,
- const BVHNode *node,
- const BVHNode *parent = NULL)
+void dump_subtree(DumpTraversalContext *context, const BVHNode *node, const BVHNode *parent = NULL)
{
- if(node->is_leaf()) {
- fprintf(context->stream,
- " node_%p [label=\"%d\",fillcolor=\"#ccccee\",style=filled]\n",
- node,
- context->id);
- }
- else {
- fprintf(context->stream,
- " node_%p [label=\"%d\",fillcolor=\"#cceecc\",style=filled]\n",
- node,
- context->id);
- }
- if(parent != NULL) {
- fprintf(context->stream, " node_%p -> node_%p;\n", parent, node);
- }
- context->id += 1;
- for(int i = 0; i < node->num_children(); ++i) {
- dump_subtree(context, node->get_child(i), node);
- }
+ if (node->is_leaf()) {
+ fprintf(context->stream,
+ " node_%p [label=\"%d\",fillcolor=\"#ccccee\",style=filled]\n",
+ node,
+ context->id);
+ }
+ else {
+ fprintf(context->stream,
+ " node_%p [label=\"%d\",fillcolor=\"#cceecc\",style=filled]\n",
+ node,
+ context->id);
+ }
+ if (parent != NULL) {
+ fprintf(context->stream, " node_%p -> node_%p;\n", parent, node);
+ }
+ context->id += 1;
+ for (int i = 0; i < node->num_children(); ++i) {
+ dump_subtree(context, node->get_child(i), node);
+ }
}
} // namespace
void BVHNode::dump_graph(const char *filename)
{
- DumpTraversalContext context;
- context.stream = fopen(filename, "w");
- if(context.stream == NULL) {
- return;
- }
- context.id = 0;
- fprintf(context.stream, "digraph BVH {\n");
- dump_subtree(&context, this);
- fprintf(context.stream, "}\n");
- fclose(context.stream);
+ DumpTraversalContext context;
+ context.stream = fopen(filename, "w");
+ if (context.stream == NULL) {
+ return;
+ }
+ context.id = 0;
+ fprintf(context.stream, "digraph BVH {\n");
+ dump_subtree(&context, this);
+ fprintf(context.stream, "}\n");
+ fclose(context.stream);
}
/* Inner Node */
void InnerNode::print(int depth) const
{
- for(int i = 0; i < depth; i++)
- printf(" ");
+ for (int i = 0; i < depth; i++)
+ printf(" ");
- printf("inner node %p\n", (void*)this);
+ printf("inner node %p\n", (void *)this);
- if(children[0])
- children[0]->print(depth+1);
- if(children[1])
- children[1]->print(depth+1);
+ if (children[0])
+ children[0]->print(depth + 1);
+ if (children[1])
+ children[1]->print(depth + 1);
}
void LeafNode::print(int depth) const
{
- for(int i = 0; i < depth; i++)
- printf(" ");
+ for (int i = 0; i < depth; i++)
+ printf(" ");
- printf("leaf node %d to %d\n", lo, hi);
+ printf("leaf node %d to %d\n", lo, hi);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_node.h b/intern/cycles/bvh/bvh_node.h
index d9105d69739..797dd5b694e 100644
--- a/intern/cycles/bvh/bvh_node.h
+++ b/intern/cycles/bvh/bvh_node.h
@@ -24,227 +24,232 @@
CCL_NAMESPACE_BEGIN
enum BVH_STAT {
- BVH_STAT_NODE_COUNT,
- BVH_STAT_INNER_COUNT,
- BVH_STAT_LEAF_COUNT,
- BVH_STAT_TRIANGLE_COUNT,
- BVH_STAT_CHILDNODE_COUNT,
- BVH_STAT_ALIGNED_COUNT,
- BVH_STAT_UNALIGNED_COUNT,
- BVH_STAT_ALIGNED_INNER_COUNT,
- BVH_STAT_UNALIGNED_INNER_COUNT,
- BVH_STAT_ALIGNED_LEAF_COUNT,
- BVH_STAT_UNALIGNED_LEAF_COUNT,
- BVH_STAT_DEPTH,
+ BVH_STAT_NODE_COUNT,
+ BVH_STAT_INNER_COUNT,
+ BVH_STAT_LEAF_COUNT,
+ BVH_STAT_TRIANGLE_COUNT,
+ BVH_STAT_CHILDNODE_COUNT,
+ BVH_STAT_ALIGNED_COUNT,
+ BVH_STAT_UNALIGNED_COUNT,
+ BVH_STAT_ALIGNED_INNER_COUNT,
+ BVH_STAT_UNALIGNED_INNER_COUNT,
+ BVH_STAT_ALIGNED_LEAF_COUNT,
+ BVH_STAT_UNALIGNED_LEAF_COUNT,
+ BVH_STAT_DEPTH,
};
class BVHParams;
-class BVHNode
-{
-public:
- virtual ~BVHNode()
- {
- delete aligned_space;
- }
-
- virtual bool is_leaf() const = 0;
- virtual int num_children() const = 0;
- virtual BVHNode *get_child(int i) const = 0;
- virtual int num_triangles() const { return 0; }
- virtual void print(int depth = 0) const = 0;
-
- inline void set_aligned_space(const Transform& aligned_space)
- {
- is_unaligned = true;
- if(this->aligned_space == NULL) {
- this->aligned_space = new Transform(aligned_space);
- }
- else {
- *this->aligned_space = aligned_space;
- }
- }
-
- inline Transform get_aligned_space() const
- {
- if(aligned_space == NULL) {
- return transform_identity();
- }
- return *aligned_space;
- }
-
- inline bool has_unaligned() const
- {
- if(is_leaf()) {
- return false;
- }
- for(int i = 0; i < num_children(); ++i) {
- if(get_child(i)->is_unaligned) {
- return true;
- }
- }
- return false;
- }
-
- // Subtree functions
- int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const;
- float computeSubtreeSAHCost(const BVHParams& p, float probability = 1.0f) const;
- void deleteSubtree();
-
- uint update_visibility();
- void update_time();
-
- /* Dump the content of the tree as a graphviz file. */
- void dump_graph(const char *filename);
-
- // Properties.
- BoundBox bounds;
- uint visibility;
-
- bool is_unaligned;
-
- /* TODO(sergey): Can be stored as 3x3 matrix, but better to have some
- * utilities and type defines in util_transform first.
- */
- Transform *aligned_space;
-
- float time_from, time_to;
-
-protected:
- explicit BVHNode(const BoundBox& bounds)
- : bounds(bounds),
- visibility(0),
- is_unaligned(false),
- aligned_space(NULL),
- time_from(0.0f),
- time_to(1.0f)
- {
- }
-
- explicit BVHNode(const BVHNode& other)
- : bounds(other.bounds),
- visibility(other.visibility),
- is_unaligned(other.is_unaligned),
- aligned_space(NULL),
- time_from(other.time_from),
- time_to(other.time_to)
- {
- if(other.aligned_space != NULL) {
- assert(other.is_unaligned);
- aligned_space = new Transform();
- *aligned_space = *other.aligned_space;
- }
- else {
- assert(!other.is_unaligned);
- }
- }
+class BVHNode {
+ public:
+ virtual ~BVHNode()
+ {
+ delete aligned_space;
+ }
+
+ virtual bool is_leaf() const = 0;
+ virtual int num_children() const = 0;
+ virtual BVHNode *get_child(int i) const = 0;
+ virtual int num_triangles() const
+ {
+ return 0;
+ }
+ virtual void print(int depth = 0) const = 0;
+
+ inline void set_aligned_space(const Transform &aligned_space)
+ {
+ is_unaligned = true;
+ if (this->aligned_space == NULL) {
+ this->aligned_space = new Transform(aligned_space);
+ }
+ else {
+ *this->aligned_space = aligned_space;
+ }
+ }
+
+ inline Transform get_aligned_space() const
+ {
+ if (aligned_space == NULL) {
+ return transform_identity();
+ }
+ return *aligned_space;
+ }
+
+ inline bool has_unaligned() const
+ {
+ if (is_leaf()) {
+ return false;
+ }
+ for (int i = 0; i < num_children(); ++i) {
+ if (get_child(i)->is_unaligned) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Subtree functions
+ int getSubtreeSize(BVH_STAT stat = BVH_STAT_NODE_COUNT) const;
+ float computeSubtreeSAHCost(const BVHParams &p, float probability = 1.0f) const;
+ void deleteSubtree();
+
+ uint update_visibility();
+ void update_time();
+
+ /* Dump the content of the tree as a graphviz file. */
+ void dump_graph(const char *filename);
+
+ // Properties.
+ BoundBox bounds;
+ uint visibility;
+
+ bool is_unaligned;
+
+ /* TODO(sergey): Can be stored as 3x3 matrix, but better to have some
+ * utilities and type defines in util_transform first.
+ */
+ Transform *aligned_space;
+
+ float time_from, time_to;
+
+ protected:
+ explicit BVHNode(const BoundBox &bounds)
+ : bounds(bounds),
+ visibility(0),
+ is_unaligned(false),
+ aligned_space(NULL),
+ time_from(0.0f),
+ time_to(1.0f)
+ {
+ }
+
+ explicit BVHNode(const BVHNode &other)
+ : bounds(other.bounds),
+ visibility(other.visibility),
+ is_unaligned(other.is_unaligned),
+ aligned_space(NULL),
+ time_from(other.time_from),
+ time_to(other.time_to)
+ {
+ if (other.aligned_space != NULL) {
+ assert(other.is_unaligned);
+ aligned_space = new Transform();
+ *aligned_space = *other.aligned_space;
+ }
+ else {
+ assert(!other.is_unaligned);
+ }
+ }
};
-class InnerNode : public BVHNode
-{
-public:
- static constexpr int kNumMaxChildren = 8;
-
- InnerNode(const BoundBox& bounds,
- BVHNode* child0,
- BVHNode* child1)
- : BVHNode(bounds),
- num_children_(2)
- {
- children[0] = child0;
- children[1] = child1;
- reset_unused_children();
-
- if(child0 && child1) {
- visibility = child0->visibility | child1->visibility;
- }
- else {
- /* Happens on build cancel. */
- visibility = 0;
- }
- }
-
- InnerNode(const BoundBox& bounds,
- BVHNode** children,
- const int num_children)
- : BVHNode(bounds),
- num_children_(num_children)
- {
- visibility = 0;
- time_from = FLT_MAX;
- time_to = -FLT_MAX;
- for(int i = 0; i < num_children; ++i) {
- assert(children[i] != NULL);
- visibility |= children[i]->visibility;
- this->children[i] = children[i];
- time_from = min(time_from, children[i]->time_from);
- time_to = max(time_to, children[i]->time_to);
- }
- reset_unused_children();
- }
-
- /* NOTE: This function is only used during binary BVH builder, and it
- * supposed to be configured to have 2 children which will be filled in in a
- * bit. But this is important to have children reset to NULL. */
- explicit InnerNode(const BoundBox& bounds)
- : BVHNode(bounds),
- num_children_(0)
- {
- reset_unused_children();
- visibility = 0;
- num_children_ = 2;
- }
-
- bool is_leaf() const { return false; }
- int num_children() const { return num_children_; }
- BVHNode *get_child(int i) const
- {
- assert(i >= 0 && i < num_children_);
- return children[i];
- }
- void print(int depth) const;
-
- int num_children_;
- BVHNode *children[kNumMaxChildren];
-
-protected:
- void reset_unused_children()
- {
- for(int i = num_children_; i < kNumMaxChildren; ++i) {
- children[i] = NULL;
- }
- }
+class InnerNode : public BVHNode {
+ public:
+ static constexpr int kNumMaxChildren = 8;
+
+ InnerNode(const BoundBox &bounds, BVHNode *child0, BVHNode *child1)
+ : BVHNode(bounds), num_children_(2)
+ {
+ children[0] = child0;
+ children[1] = child1;
+ reset_unused_children();
+
+ if (child0 && child1) {
+ visibility = child0->visibility | child1->visibility;
+ }
+ else {
+ /* Happens on build cancel. */
+ visibility = 0;
+ }
+ }
+
+ InnerNode(const BoundBox &bounds, BVHNode **children, const int num_children)
+ : BVHNode(bounds), num_children_(num_children)
+ {
+ visibility = 0;
+ time_from = FLT_MAX;
+ time_to = -FLT_MAX;
+ for (int i = 0; i < num_children; ++i) {
+ assert(children[i] != NULL);
+ visibility |= children[i]->visibility;
+ this->children[i] = children[i];
+ time_from = min(time_from, children[i]->time_from);
+ time_to = max(time_to, children[i]->time_to);
+ }
+ reset_unused_children();
+ }
+
+ /* NOTE: This function is only used during binary BVH builder, and it
+ * supposed to be configured to have 2 children which will be filled in in a
+ * bit. But this is important to have children reset to NULL. */
+ explicit InnerNode(const BoundBox &bounds) : BVHNode(bounds), num_children_(0)
+ {
+ reset_unused_children();
+ visibility = 0;
+ num_children_ = 2;
+ }
+
+ bool is_leaf() const
+ {
+ return false;
+ }
+ int num_children() const
+ {
+ return num_children_;
+ }
+ BVHNode *get_child(int i) const
+ {
+ assert(i >= 0 && i < num_children_);
+ return children[i];
+ }
+ void print(int depth) const;
+
+ int num_children_;
+ BVHNode *children[kNumMaxChildren];
+
+ protected:
+ void reset_unused_children()
+ {
+ for (int i = num_children_; i < kNumMaxChildren; ++i) {
+ children[i] = NULL;
+ }
+ }
};
-class LeafNode : public BVHNode
-{
-public:
- LeafNode(const BoundBox& bounds, uint visibility, int lo, int hi)
- : BVHNode(bounds),
- lo(lo),
- hi(hi)
- {
- this->bounds = bounds;
- this->visibility = visibility;
- }
-
- LeafNode(const LeafNode& other)
- : BVHNode(other),
- lo(other.lo),
- hi(other.hi)
- {
- }
-
- bool is_leaf() const { return true; }
- int num_children() const { return 0; }
- BVHNode *get_child(int) const { return NULL; }
- int num_triangles() const { return hi - lo; }
- void print(int depth) const;
-
- int lo;
- int hi;
+class LeafNode : public BVHNode {
+ public:
+ LeafNode(const BoundBox &bounds, uint visibility, int lo, int hi)
+ : BVHNode(bounds), lo(lo), hi(hi)
+ {
+ this->bounds = bounds;
+ this->visibility = visibility;
+ }
+
+ LeafNode(const LeafNode &other) : BVHNode(other), lo(other.lo), hi(other.hi)
+ {
+ }
+
+ bool is_leaf() const
+ {
+ return true;
+ }
+ int num_children() const
+ {
+ return 0;
+ }
+ BVHNode *get_child(int) const
+ {
+ return NULL;
+ }
+ int num_triangles() const
+ {
+ return hi - lo;
+ }
+ void print(int depth) const;
+
+ int lo;
+ int hi;
};
CCL_NAMESPACE_END
-#endif /* __BVH_NODE_H__ */
+#endif /* __BVH_NODE_H__ */
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index 6408d56da80..2731662a39d 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -43,120 +43,121 @@ const char *bvh_layout_name(BVHLayout layout);
/* BVH Parameters */
-class BVHParams
-{
-public:
-
- /* spatial split area threshold */
- bool use_spatial_split;
- float spatial_split_alpha;
-
- /* Unaligned nodes creation threshold */
- float unaligned_split_threshold;
-
- /* SAH costs */
- float sah_node_cost;
- float sah_primitive_cost;
-
- /* number of primitives in leaf */
- int min_leaf_size;
- int max_triangle_leaf_size;
- int max_motion_triangle_leaf_size;
- int max_curve_leaf_size;
- int max_motion_curve_leaf_size;
-
- /* object or mesh level bvh */
- bool top_level;
-
- /* BVH layout to be built. */
- BVHLayout bvh_layout;
-
- /* Mask of primitives to be included into the BVH. */
- int primitive_mask;
-
- /* Use unaligned bounding boxes.
- * Only used for curves BVH.
- */
- bool use_unaligned_nodes;
-
- /* Split time range to this number of steps and create leaf node for each
- * of this time steps.
- *
- * Speeds up rendering of motion curve primitives in the cost of higher
- * memory usage.
- */
- int num_motion_curve_steps;
-
- /* Same as above, but for triangle primitives. */
- int num_motion_triangle_steps;
-
- /* Same as in SceneParams. */
- int bvh_type;
-
- /* These are needed for Embree. */
- int curve_flags;
- int curve_subdivisions;
-
- /* fixed parameters */
- enum {
- MAX_DEPTH = 64,
- MAX_SPATIAL_DEPTH = 48,
- NUM_SPATIAL_BINS = 32
- };
-
- BVHParams()
- {
- use_spatial_split = true;
- spatial_split_alpha = 1e-5f;
-
- unaligned_split_threshold = 0.7f;
-
- /* todo: see if splitting up primitive cost to be separate for triangles
- * and curves can help. so far in tests it doesn't help, but why? */
- sah_node_cost = 1.0f;
- sah_primitive_cost = 1.0f;
-
- min_leaf_size = 1;
- max_triangle_leaf_size = 8;
- max_motion_triangle_leaf_size = 8;
- max_curve_leaf_size = 1;
- max_motion_curve_leaf_size = 4;
-
- top_level = false;
- bvh_layout = BVH_LAYOUT_BVH2;
- use_unaligned_nodes = false;
-
- primitive_mask = PRIMITIVE_ALL;
-
- num_motion_curve_steps = 0;
- num_motion_triangle_steps = 0;
-
- bvh_type = 0;
-
- curve_flags = 0;
- curve_subdivisions = 4;
- }
-
- /* SAH costs */
- __forceinline float cost(int num_nodes, int num_primitives) const
- { return node_cost(num_nodes) + primitive_cost(num_primitives); }
-
- __forceinline float primitive_cost(int n) const
- { return n*sah_primitive_cost; }
-
- __forceinline float node_cost(int n) const
- { return n*sah_node_cost; }
-
- __forceinline bool small_enough_for_leaf(int size, int level)
- { return (size <= min_leaf_size || level >= MAX_DEPTH); }
-
- /* Gets best matching BVH.
- *
- * If the requested layout is supported by the device, it will be used.
- * Otherwise, widest supported layout below that will be used.
- */
- static BVHLayout best_bvh_layout(BVHLayout requested_layout,
- BVHLayoutMask supported_layouts);
+class BVHParams {
+ public:
+ /* spatial split area threshold */
+ bool use_spatial_split;
+ float spatial_split_alpha;
+
+ /* Unaligned nodes creation threshold */
+ float unaligned_split_threshold;
+
+ /* SAH costs */
+ float sah_node_cost;
+ float sah_primitive_cost;
+
+ /* number of primitives in leaf */
+ int min_leaf_size;
+ int max_triangle_leaf_size;
+ int max_motion_triangle_leaf_size;
+ int max_curve_leaf_size;
+ int max_motion_curve_leaf_size;
+
+ /* object or mesh level bvh */
+ bool top_level;
+
+ /* BVH layout to be built. */
+ BVHLayout bvh_layout;
+
+ /* Mask of primitives to be included into the BVH. */
+ int primitive_mask;
+
+ /* Use unaligned bounding boxes.
+ * Only used for curves BVH.
+ */
+ bool use_unaligned_nodes;
+
+ /* Split time range to this number of steps and create leaf node for each
+ * of this time steps.
+ *
+ * Speeds up rendering of motion curve primitives in the cost of higher
+ * memory usage.
+ */
+ int num_motion_curve_steps;
+
+ /* Same as above, but for triangle primitives. */
+ int num_motion_triangle_steps;
+
+ /* Same as in SceneParams. */
+ int bvh_type;
+
+ /* These are needed for Embree. */
+ int curve_flags;
+ int curve_subdivisions;
+
+ /* fixed parameters */
+ enum { MAX_DEPTH = 64, MAX_SPATIAL_DEPTH = 48, NUM_SPATIAL_BINS = 32 };
+
+ BVHParams()
+ {
+ use_spatial_split = true;
+ spatial_split_alpha = 1e-5f;
+
+ unaligned_split_threshold = 0.7f;
+
+ /* todo: see if splitting up primitive cost to be separate for triangles
+ * and curves can help. so far in tests it doesn't help, but why? */
+ sah_node_cost = 1.0f;
+ sah_primitive_cost = 1.0f;
+
+ min_leaf_size = 1;
+ max_triangle_leaf_size = 8;
+ max_motion_triangle_leaf_size = 8;
+ max_curve_leaf_size = 1;
+ max_motion_curve_leaf_size = 4;
+
+ top_level = false;
+ bvh_layout = BVH_LAYOUT_BVH2;
+ use_unaligned_nodes = false;
+
+ primitive_mask = PRIMITIVE_ALL;
+
+ num_motion_curve_steps = 0;
+ num_motion_triangle_steps = 0;
+
+ bvh_type = 0;
+
+ curve_flags = 0;
+ curve_subdivisions = 4;
+ }
+
+ /* SAH costs */
+ __forceinline float cost(int num_nodes, int num_primitives) const
+ {
+ return node_cost(num_nodes) + primitive_cost(num_primitives);
+ }
+
+ __forceinline float primitive_cost(int n) const
+ {
+ return n * sah_primitive_cost;
+ }
+
+ __forceinline float node_cost(int n) const
+ {
+ return n * sah_node_cost;
+ }
+
+ __forceinline bool small_enough_for_leaf(int size, int level)
+ {
+ return (size <= min_leaf_size || level >= MAX_DEPTH);
+ }
+
+ /* Gets best matching BVH.
+ *
+ * If the requested layout is supported by the device, it will be used.
+ * Otherwise, widest supported layout below that will be used.
+ */
+ static BVHLayout best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask supported_layouts);
};
/* BVH Reference
@@ -164,49 +165,65 @@ public:
* Reference to a primitive. Primitive index and object are sneakily packed
* into BoundBox to reduce memory usage and align nicely */
-class BVHReference
-{
-public:
- __forceinline BVHReference() {}
-
- __forceinline BVHReference(const BoundBox& bounds_,
- int prim_index_,
- int prim_object_,
- int prim_type,
- float time_from = 0.0f,
- float time_to = 1.0f)
- : rbounds(bounds_),
- time_from_(time_from),
- time_to_(time_to)
- {
- rbounds.min.w = __int_as_float(prim_index_);
- rbounds.max.w = __int_as_float(prim_object_);
- type = prim_type;
- }
-
- __forceinline const BoundBox& bounds() const { return rbounds; }
- __forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
- __forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
- __forceinline int prim_type() const { return type; }
- __forceinline float time_from() const { return time_from_; }
- __forceinline float time_to() const { return time_to_; }
-
-
- BVHReference& operator=(const BVHReference &arg) {
- if(&arg != this) {
- /* TODO(sergey): Check if it is still faster to memcpy() with
- * modern compilers.
- */
- memcpy((void *)this, &arg, sizeof(BVHReference));
- }
- return *this;
- }
-
-
-protected:
- BoundBox rbounds;
- uint type;
- float time_from_, time_to_;
+class BVHReference {
+ public:
+ __forceinline BVHReference()
+ {
+ }
+
+ __forceinline BVHReference(const BoundBox &bounds_,
+ int prim_index_,
+ int prim_object_,
+ int prim_type,
+ float time_from = 0.0f,
+ float time_to = 1.0f)
+ : rbounds(bounds_), time_from_(time_from), time_to_(time_to)
+ {
+ rbounds.min.w = __int_as_float(prim_index_);
+ rbounds.max.w = __int_as_float(prim_object_);
+ type = prim_type;
+ }
+
+ __forceinline const BoundBox &bounds() const
+ {
+ return rbounds;
+ }
+ __forceinline int prim_index() const
+ {
+ return __float_as_int(rbounds.min.w);
+ }
+ __forceinline int prim_object() const
+ {
+ return __float_as_int(rbounds.max.w);
+ }
+ __forceinline int prim_type() const
+ {
+ return type;
+ }
+ __forceinline float time_from() const
+ {
+ return time_from_;
+ }
+ __forceinline float time_to() const
+ {
+ return time_to_;
+ }
+
+ BVHReference &operator=(const BVHReference &arg)
+ {
+ if (&arg != this) {
+ /* TODO(sergey): Check if it is still faster to memcpy() with
+ * modern compilers.
+ */
+ memcpy((void *)this, &arg, sizeof(BVHReference));
+ }
+ return *this;
+ }
+
+ protected:
+ BoundBox rbounds;
+ uint type;
+ float time_from_, time_to_;
};
/* BVH Range
@@ -215,53 +232,68 @@ protected:
* the reference array of a subset of primitives Again uses trickery to pack
* integers into BoundBox for alignment purposes. */
-class BVHRange
-{
-public:
- __forceinline BVHRange()
- {
- rbounds.min.w = __int_as_float(0);
- rbounds.max.w = __int_as_float(0);
- }
-
- __forceinline BVHRange(const BoundBox& bounds_, int start_, int size_)
- : rbounds(bounds_)
- {
- rbounds.min.w = __int_as_float(start_);
- rbounds.max.w = __int_as_float(size_);
- }
-
- __forceinline BVHRange(const BoundBox& bounds_, const BoundBox& cbounds_, int start_, int size_)
- : rbounds(bounds_), cbounds(cbounds_)
- {
- rbounds.min.w = __int_as_float(start_);
- rbounds.max.w = __int_as_float(size_);
- }
-
- __forceinline void set_start(int start_) { rbounds.min.w = __int_as_float(start_); }
-
- __forceinline const BoundBox& bounds() const { return rbounds; }
- __forceinline const BoundBox& cent_bounds() const { return cbounds; }
- __forceinline int start() const { return __float_as_int(rbounds.min.w); }
- __forceinline int size() const { return __float_as_int(rbounds.max.w); }
- __forceinline int end() const { return start() + size(); }
-
-protected:
- BoundBox rbounds;
- BoundBox cbounds;
+class BVHRange {
+ public:
+ __forceinline BVHRange()
+ {
+ rbounds.min.w = __int_as_float(0);
+ rbounds.max.w = __int_as_float(0);
+ }
+
+ __forceinline BVHRange(const BoundBox &bounds_, int start_, int size_) : rbounds(bounds_)
+ {
+ rbounds.min.w = __int_as_float(start_);
+ rbounds.max.w = __int_as_float(size_);
+ }
+
+ __forceinline BVHRange(const BoundBox &bounds_, const BoundBox &cbounds_, int start_, int size_)
+ : rbounds(bounds_), cbounds(cbounds_)
+ {
+ rbounds.min.w = __int_as_float(start_);
+ rbounds.max.w = __int_as_float(size_);
+ }
+
+ __forceinline void set_start(int start_)
+ {
+ rbounds.min.w = __int_as_float(start_);
+ }
+
+ __forceinline const BoundBox &bounds() const
+ {
+ return rbounds;
+ }
+ __forceinline const BoundBox &cent_bounds() const
+ {
+ return cbounds;
+ }
+ __forceinline int start() const
+ {
+ return __float_as_int(rbounds.min.w);
+ }
+ __forceinline int size() const
+ {
+ return __float_as_int(rbounds.max.w);
+ }
+ __forceinline int end() const
+ {
+ return start() + size();
+ }
+
+ protected:
+ BoundBox rbounds;
+ BoundBox cbounds;
};
/* BVH Spatial Bin */
-struct BVHSpatialBin
-{
- BoundBox bounds;
- int enter;
- int exit;
+struct BVHSpatialBin {
+ BoundBox bounds;
+ int enter;
+ int exit;
- __forceinline BVHSpatialBin()
- {
- }
+ __forceinline BVHSpatialBin()
+ {
+ }
};
/* BVH Spatial Storage
@@ -272,18 +304,18 @@ struct BVHSpatialBin
*/
struct BVHSpatialStorage {
- /* Accumulated bounds when sweeping from right to left. */
- vector<BoundBox> right_bounds;
+ /* Accumulated bounds when sweeping from right to left. */
+ vector<BoundBox> right_bounds;
- /* Bins used for histogram when selecting best split plane. */
- BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS];
+ /* Bins used for histogram when selecting best split plane. */
+ BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS];
- /* Temporary storage for the new references. Used by spatial split to store
- * new references in before they're getting inserted into actual array,
- */
- vector<BVHReference> new_references;
+ /* Temporary storage for the new references. Used by spatial split to store
+ * new references in before they're getting inserted into actual array,
+ */
+ vector<BVHReference> new_references;
};
CCL_NAMESPACE_END
-#endif /* __BVH_PARAMS_H__ */
+#endif /* __BVH_PARAMS_H__ */
diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp
index f4f73ab2f2f..4498a759c08 100644
--- a/intern/cycles/bvh/bvh_sort.cpp
+++ b/intern/cycles/bvh/bvh_sort.cpp
@@ -27,79 +27,77 @@ CCL_NAMESPACE_BEGIN
static const int BVH_SORT_THRESHOLD = 4096;
struct BVHReferenceCompare {
-public:
- int dim;
- const BVHUnaligned *unaligned_heuristic;
- const Transform *aligned_space;
-
- BVHReferenceCompare(int dim,
- const BVHUnaligned *unaligned_heuristic,
- const Transform *aligned_space)
- : dim(dim),
- unaligned_heuristic(unaligned_heuristic),
- aligned_space(aligned_space)
- {
- }
-
- __forceinline BoundBox get_prim_bounds(const BVHReference& prim) const
- {
- return (aligned_space != NULL)
- ? unaligned_heuristic->compute_aligned_prim_boundbox(
- prim, *aligned_space)
- : prim.bounds();
- }
-
- /* Compare two references.
- *
- * Returns value is similar to return value of strcmp().
- */
- __forceinline int compare(const BVHReference& ra,
- const BVHReference& rb) const
- {
- BoundBox ra_bounds = get_prim_bounds(ra),
- rb_bounds = get_prim_bounds(rb);
- float ca = ra_bounds.min[dim] + ra_bounds.max[dim];
- float cb = rb_bounds.min[dim] + rb_bounds.max[dim];
-
- if(ca < cb) return -1;
- else if(ca > cb) return 1;
- else if(ra.prim_object() < rb.prim_object()) return -1;
- else if(ra.prim_object() > rb.prim_object()) return 1;
- else if(ra.prim_index() < rb.prim_index()) return -1;
- else if(ra.prim_index() > rb.prim_index()) return 1;
- else if(ra.prim_type() < rb.prim_type()) return -1;
- else if(ra.prim_type() > rb.prim_type()) return 1;
-
- return 0;
- }
-
- bool operator()(const BVHReference& ra, const BVHReference& rb)
- {
- return (compare(ra, rb) < 0);
- }
+ public:
+ int dim;
+ const BVHUnaligned *unaligned_heuristic;
+ const Transform *aligned_space;
+
+ BVHReferenceCompare(int dim,
+ const BVHUnaligned *unaligned_heuristic,
+ const Transform *aligned_space)
+ : dim(dim), unaligned_heuristic(unaligned_heuristic), aligned_space(aligned_space)
+ {
+ }
+
+ __forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
+ {
+ return (aligned_space != NULL) ?
+ unaligned_heuristic->compute_aligned_prim_boundbox(prim, *aligned_space) :
+ prim.bounds();
+ }
+
+ /* Compare two references.
+ *
+ * Returns value is similar to return value of strcmp().
+ */
+ __forceinline int compare(const BVHReference &ra, const BVHReference &rb) const
+ {
+ BoundBox ra_bounds = get_prim_bounds(ra), rb_bounds = get_prim_bounds(rb);
+ float ca = ra_bounds.min[dim] + ra_bounds.max[dim];
+ float cb = rb_bounds.min[dim] + rb_bounds.max[dim];
+
+ if (ca < cb)
+ return -1;
+ else if (ca > cb)
+ return 1;
+ else if (ra.prim_object() < rb.prim_object())
+ return -1;
+ else if (ra.prim_object() > rb.prim_object())
+ return 1;
+ else if (ra.prim_index() < rb.prim_index())
+ return -1;
+ else if (ra.prim_index() > rb.prim_index())
+ return 1;
+ else if (ra.prim_type() < rb.prim_type())
+ return -1;
+ else if (ra.prim_type() > rb.prim_type())
+ return 1;
+
+ return 0;
+ }
+
+ bool operator()(const BVHReference &ra, const BVHReference &rb)
+ {
+ return (compare(ra, rb) < 0);
+ }
};
static void bvh_reference_sort_threaded(TaskPool *task_pool,
BVHReference *data,
const int job_start,
const int job_end,
- const BVHReferenceCompare& compare);
+ const BVHReferenceCompare &compare);
class BVHSortTask : public Task {
-public:
- BVHSortTask(TaskPool *task_pool,
- BVHReference *data,
- const int job_start,
- const int job_end,
- const BVHReferenceCompare& compare)
- {
- run = function_bind(bvh_reference_sort_threaded,
- task_pool,
- data,
- job_start,
- job_end,
- compare);
- }
+ public:
+ BVHSortTask(TaskPool *task_pool,
+ BVHReference *data,
+ const int job_start,
+ const int job_end,
+ const BVHReferenceCompare &compare)
+ {
+ run = function_bind(bvh_reference_sort_threaded, task_pool, data, job_start, job_end, compare);
+ }
};
/* Multi-threaded reference sort. */
@@ -107,74 +105,71 @@ static void bvh_reference_sort_threaded(TaskPool *task_pool,
BVHReference *data,
const int job_start,
const int job_end,
- const BVHReferenceCompare& compare)
+ const BVHReferenceCompare &compare)
{
- int start = job_start, end = job_end;
- bool have_work = (start < end);
- while(have_work) {
- const int count = job_end - job_start;
- if(count < BVH_SORT_THRESHOLD) {
- /* Number of reference low enough, faster to finish the job
- * in one thread rather than to spawn more threads.
- */
- sort(data+job_start, data+job_end+1, compare);
- break;
- }
- /* Single QSort step.
- * Use median-of-three method for the pivot point.
- */
- int left = start, right = end;
- int center = (left + right) >> 1;
- if(compare.compare(data[left], data[center]) > 0) {
- swap(data[left], data[center]);
- }
- if(compare.compare(data[left], data[right]) > 0) {
- swap(data[left], data[right]);
- }
- if(compare.compare(data[center], data[right]) > 0) {
- swap(data[center], data[right]);
- }
- swap(data[center], data[right - 1]);
- BVHReference median = data[right - 1];
- do {
- while(compare.compare(data[left], median) < 0) {
- ++left;
- }
- while(compare.compare(data[right], median) > 0) {
- --right;
- }
- if(left <= right) {
- swap(data[left], data[right]);
- ++left;
- --right;
- }
- } while(left <= right);
- /* We only create one new task here to reduce downside effects of
- * latency in TaskScheduler.
- * So generally current thread keeps working on the left part of the
- * array, and we create new task for the right side.
- * However, if there's nothing to be done in the left side of the array
- * we don't create any tasks and make it so current thread works on the
- * right side.
- */
- have_work = false;
- if(left < end) {
- if(start < right) {
- task_pool->push(new BVHSortTask(task_pool,
- data,
- left, end,
- compare), true);
- }
- else {
- start = left;
- have_work = true;
- }
- }
- if(start < right) {
- end = right;
- have_work = true;
- }
- }
+ int start = job_start, end = job_end;
+ bool have_work = (start < end);
+ while (have_work) {
+ const int count = job_end - job_start;
+ if (count < BVH_SORT_THRESHOLD) {
+ /* Number of reference low enough, faster to finish the job
+ * in one thread rather than to spawn more threads.
+ */
+ sort(data + job_start, data + job_end + 1, compare);
+ break;
+ }
+ /* Single QSort step.
+ * Use median-of-three method for the pivot point.
+ */
+ int left = start, right = end;
+ int center = (left + right) >> 1;
+ if (compare.compare(data[left], data[center]) > 0) {
+ swap(data[left], data[center]);
+ }
+ if (compare.compare(data[left], data[right]) > 0) {
+ swap(data[left], data[right]);
+ }
+ if (compare.compare(data[center], data[right]) > 0) {
+ swap(data[center], data[right]);
+ }
+ swap(data[center], data[right - 1]);
+ BVHReference median = data[right - 1];
+ do {
+ while (compare.compare(data[left], median) < 0) {
+ ++left;
+ }
+ while (compare.compare(data[right], median) > 0) {
+ --right;
+ }
+ if (left <= right) {
+ swap(data[left], data[right]);
+ ++left;
+ --right;
+ }
+ } while (left <= right);
+ /* We only create one new task here to reduce downside effects of
+ * latency in TaskScheduler.
+ * So generally current thread keeps working on the left part of the
+ * array, and we create new task for the right side.
+ * However, if there's nothing to be done in the left side of the array
+ * we don't create any tasks and make it so current thread works on the
+ * right side.
+ */
+ have_work = false;
+ if (left < end) {
+ if (start < right) {
+ task_pool->push(new BVHSortTask(task_pool, data, left, end, compare), true);
+ }
+ else {
+ start = left;
+ have_work = true;
+ }
+ }
+ if (start < right) {
+ end = right;
+ have_work = true;
+ }
+ }
}
void bvh_reference_sort(int start,
@@ -184,20 +179,20 @@ void bvh_reference_sort(int start,
const BVHUnaligned *unaligned_heuristic,
const Transform *aligned_space)
{
- const int count = end - start;
- BVHReferenceCompare compare(dim, unaligned_heuristic, aligned_space);
- if(count < BVH_SORT_THRESHOLD) {
- /* It is important to not use any mutex if array is small enough,
- * otherwise we end up in situation when we're going to sleep far
- * too often.
- */
- sort(data+start, data+end, compare);
- }
- else {
- TaskPool task_pool;
- bvh_reference_sort_threaded(&task_pool, data, start, end - 1, compare);
- task_pool.wait_work();
- }
+ const int count = end - start;
+ BVHReferenceCompare compare(dim, unaligned_heuristic, aligned_space);
+ if (count < BVH_SORT_THRESHOLD) {
+ /* It is important to not use any mutex if array is small enough,
+ * otherwise we end up in situation when we're going to sleep far
+ * too often.
+ */
+ sort(data + start, data + end, compare);
+ }
+ else {
+ TaskPool task_pool;
+ bvh_reference_sort_threaded(&task_pool, data, start, end - 1, compare);
+ task_pool.wait_work();
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_sort.h b/intern/cycles/bvh/bvh_sort.h
index 6910cc1e9b4..936401d8607 100644
--- a/intern/cycles/bvh/bvh_sort.h
+++ b/intern/cycles/bvh/bvh_sort.h
@@ -35,4 +35,4 @@ void bvh_reference_sort(int start,
CCL_NAMESPACE_END
-#endif /* __BVH_SORT_H__ */
+#endif /* __BVH_SORT_H__ */
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index c55ba40b565..bd261c10d55 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -31,322 +31,314 @@ CCL_NAMESPACE_BEGIN
BVHObjectSplit::BVHObjectSplit(BVHBuild *builder,
BVHSpatialStorage *storage,
- const BVHRange& range,
+ const BVHRange &range,
vector<BVHReference> *references,
float nodeSAH,
const BVHUnaligned *unaligned_heuristic,
const Transform *aligned_space)
-: sah(FLT_MAX),
- dim(0),
- num_left(0),
- left_bounds(BoundBox::empty),
- right_bounds(BoundBox::empty),
- storage_(storage),
- references_(references),
- unaligned_heuristic_(unaligned_heuristic),
- aligned_space_(aligned_space)
+ : sah(FLT_MAX),
+ dim(0),
+ num_left(0),
+ left_bounds(BoundBox::empty),
+ right_bounds(BoundBox::empty),
+ storage_(storage),
+ references_(references),
+ unaligned_heuristic_(unaligned_heuristic),
+ aligned_space_(aligned_space)
{
- const BVHReference *ref_ptr = &references_->at(range.start());
- float min_sah = FLT_MAX;
-
- storage_->right_bounds.resize(range.size());
-
- for(int dim = 0; dim < 3; dim++) {
- /* Sort references. */
- bvh_reference_sort(range.start(),
- range.end(),
- &references_->at(0),
- dim,
- unaligned_heuristic_,
- aligned_space_);
-
- /* sweep right to left and determine bounds. */
- BoundBox right_bounds = BoundBox::empty;
- for(int i = range.size() - 1; i > 0; i--) {
- BoundBox prim_bounds = get_prim_bounds(ref_ptr[i]);
- right_bounds.grow(prim_bounds);
- storage_->right_bounds[i - 1] = right_bounds;
- }
-
- /* sweep left to right and select lowest SAH. */
- BoundBox left_bounds = BoundBox::empty;
-
- for(int i = 1; i < range.size(); i++) {
- BoundBox prim_bounds = get_prim_bounds(ref_ptr[i - 1]);
- left_bounds.grow(prim_bounds);
- right_bounds = storage_->right_bounds[i - 1];
-
- float sah = nodeSAH +
- left_bounds.safe_area() * builder->params.primitive_cost(i) +
- right_bounds.safe_area() * builder->params.primitive_cost(range.size() - i);
-
- if(sah < min_sah) {
- min_sah = sah;
-
- this->sah = sah;
- this->dim = dim;
- this->num_left = i;
- this->left_bounds = left_bounds;
- this->right_bounds = right_bounds;
- }
- }
- }
+ const BVHReference *ref_ptr = &references_->at(range.start());
+ float min_sah = FLT_MAX;
+
+ storage_->right_bounds.resize(range.size());
+
+ for (int dim = 0; dim < 3; dim++) {
+ /* Sort references. */
+ bvh_reference_sort(range.start(),
+ range.end(),
+ &references_->at(0),
+ dim,
+ unaligned_heuristic_,
+ aligned_space_);
+
+ /* sweep right to left and determine bounds. */
+ BoundBox right_bounds = BoundBox::empty;
+ for (int i = range.size() - 1; i > 0; i--) {
+ BoundBox prim_bounds = get_prim_bounds(ref_ptr[i]);
+ right_bounds.grow(prim_bounds);
+ storage_->right_bounds[i - 1] = right_bounds;
+ }
+
+ /* sweep left to right and select lowest SAH. */
+ BoundBox left_bounds = BoundBox::empty;
+
+ for (int i = 1; i < range.size(); i++) {
+ BoundBox prim_bounds = get_prim_bounds(ref_ptr[i - 1]);
+ left_bounds.grow(prim_bounds);
+ right_bounds = storage_->right_bounds[i - 1];
+
+ float sah = nodeSAH + left_bounds.safe_area() * builder->params.primitive_cost(i) +
+ right_bounds.safe_area() * builder->params.primitive_cost(range.size() - i);
+
+ if (sah < min_sah) {
+ min_sah = sah;
+
+ this->sah = sah;
+ this->dim = dim;
+ this->num_left = i;
+ this->left_bounds = left_bounds;
+ this->right_bounds = right_bounds;
+ }
+ }
+ }
}
-void BVHObjectSplit::split(BVHRange& left,
- BVHRange& right,
- const BVHRange& range)
+void BVHObjectSplit::split(BVHRange &left, BVHRange &right, const BVHRange &range)
{
- assert(references_->size() > 0);
- /* sort references according to split */
- bvh_reference_sort(range.start(),
- range.end(),
- &references_->at(0),
- this->dim,
- unaligned_heuristic_,
- aligned_space_);
-
- BoundBox effective_left_bounds, effective_right_bounds;
- const int num_right = range.size() - this->num_left;
- if(aligned_space_ == NULL) {
- effective_left_bounds = left_bounds;
- effective_right_bounds = right_bounds;
- }
- else {
- effective_left_bounds = BoundBox::empty;
- effective_right_bounds = BoundBox::empty;
- for(int i = 0; i < this->num_left; ++i) {
- BoundBox prim_boundbox = references_->at(range.start() + i).bounds();
- effective_left_bounds.grow(prim_boundbox);
- }
- for(int i = 0; i < num_right; ++i) {
- BoundBox prim_boundbox = references_->at(range.start() + this->num_left + i).bounds();
- effective_right_bounds.grow(prim_boundbox);
- }
- }
-
- /* split node ranges */
- left = BVHRange(effective_left_bounds, range.start(), this->num_left);
- right = BVHRange(effective_right_bounds, left.end(), num_right);
+ assert(references_->size() > 0);
+ /* sort references according to split */
+ bvh_reference_sort(range.start(),
+ range.end(),
+ &references_->at(0),
+ this->dim,
+ unaligned_heuristic_,
+ aligned_space_);
+
+ BoundBox effective_left_bounds, effective_right_bounds;
+ const int num_right = range.size() - this->num_left;
+ if (aligned_space_ == NULL) {
+ effective_left_bounds = left_bounds;
+ effective_right_bounds = right_bounds;
+ }
+ else {
+ effective_left_bounds = BoundBox::empty;
+ effective_right_bounds = BoundBox::empty;
+ for (int i = 0; i < this->num_left; ++i) {
+ BoundBox prim_boundbox = references_->at(range.start() + i).bounds();
+ effective_left_bounds.grow(prim_boundbox);
+ }
+ for (int i = 0; i < num_right; ++i) {
+ BoundBox prim_boundbox = references_->at(range.start() + this->num_left + i).bounds();
+ effective_right_bounds.grow(prim_boundbox);
+ }
+ }
+
+ /* split node ranges */
+ left = BVHRange(effective_left_bounds, range.start(), this->num_left);
+ right = BVHRange(effective_right_bounds, left.end(), num_right);
}
/* Spatial Split */
-BVHSpatialSplit::BVHSpatialSplit(const BVHBuild& builder,
+BVHSpatialSplit::BVHSpatialSplit(const BVHBuild &builder,
BVHSpatialStorage *storage,
- const BVHRange& range,
+ const BVHRange &range,
vector<BVHReference> *references,
float nodeSAH,
const BVHUnaligned *unaligned_heuristic,
const Transform *aligned_space)
-: sah(FLT_MAX),
- dim(0),
- pos(0.0f),
- storage_(storage),
- references_(references),
- unaligned_heuristic_(unaligned_heuristic),
- aligned_space_(aligned_space)
+ : sah(FLT_MAX),
+ dim(0),
+ pos(0.0f),
+ storage_(storage),
+ references_(references),
+ unaligned_heuristic_(unaligned_heuristic),
+ aligned_space_(aligned_space)
{
- /* initialize bins. */
- BoundBox range_bounds;
- if(aligned_space == NULL) {
- range_bounds = range.bounds();
- }
- else {
- range_bounds = unaligned_heuristic->compute_aligned_boundbox(
- range,
- &references->at(0),
- *aligned_space);
- }
-
- float3 origin = range_bounds.min;
- float3 binSize = (range_bounds.max - origin) * (1.0f / (float)BVHParams::NUM_SPATIAL_BINS);
- float3 invBinSize = 1.0f / binSize;
-
- for(int dim = 0; dim < 3; dim++) {
- for(int i = 0; i < BVHParams::NUM_SPATIAL_BINS; i++) {
- BVHSpatialBin& bin = storage_->bins[dim][i];
-
- bin.bounds = BoundBox::empty;
- bin.enter = 0;
- bin.exit = 0;
- }
- }
-
- /* chop references into bins. */
- for(unsigned int refIdx = range.start(); refIdx < range.end(); refIdx++) {
- const BVHReference& ref = references_->at(refIdx);
- BoundBox prim_bounds = get_prim_bounds(ref);
- float3 firstBinf = (prim_bounds.min - origin) * invBinSize;
- float3 lastBinf = (prim_bounds.max - origin) * invBinSize;
- int3 firstBin = make_int3((int)firstBinf.x, (int)firstBinf.y, (int)firstBinf.z);
- int3 lastBin = make_int3((int)lastBinf.x, (int)lastBinf.y, (int)lastBinf.z);
-
- firstBin = clamp(firstBin, 0, BVHParams::NUM_SPATIAL_BINS - 1);
- lastBin = clamp(lastBin, firstBin, BVHParams::NUM_SPATIAL_BINS - 1);
-
- for(int dim = 0; dim < 3; dim++) {
- BVHReference currRef(get_prim_bounds(ref),
- ref.prim_index(),
- ref.prim_object(),
- ref.prim_type());
-
- for(int i = firstBin[dim]; i < lastBin[dim]; i++) {
- BVHReference leftRef, rightRef;
-
- split_reference(builder, leftRef, rightRef, currRef, dim, origin[dim] + binSize[dim] * (float)(i + 1));
- storage_->bins[dim][i].bounds.grow(leftRef.bounds());
- currRef = rightRef;
- }
-
- storage_->bins[dim][lastBin[dim]].bounds.grow(currRef.bounds());
- storage_->bins[dim][firstBin[dim]].enter++;
- storage_->bins[dim][lastBin[dim]].exit++;
- }
- }
-
- /* select best split plane. */
- storage_->right_bounds.resize(BVHParams::NUM_SPATIAL_BINS);
- for(int dim = 0; dim < 3; dim++) {
- /* sweep right to left and determine bounds. */
- BoundBox right_bounds = BoundBox::empty;
- for(int i = BVHParams::NUM_SPATIAL_BINS - 1; i > 0; i--) {
- right_bounds.grow(storage_->bins[dim][i].bounds);
- storage_->right_bounds[i - 1] = right_bounds;
- }
-
- /* sweep left to right and select lowest SAH. */
- BoundBox left_bounds = BoundBox::empty;
- int leftNum = 0;
- int rightNum = range.size();
-
- for(int i = 1; i < BVHParams::NUM_SPATIAL_BINS; i++) {
- left_bounds.grow(storage_->bins[dim][i - 1].bounds);
- leftNum += storage_->bins[dim][i - 1].enter;
- rightNum -= storage_->bins[dim][i - 1].exit;
-
- float sah = nodeSAH +
- left_bounds.safe_area() * builder.params.primitive_cost(leftNum) +
- storage_->right_bounds[i - 1].safe_area() * builder.params.primitive_cost(rightNum);
-
- if(sah < this->sah) {
- this->sah = sah;
- this->dim = dim;
- this->pos = origin[dim] + binSize[dim] * (float)i;
- }
- }
- }
+ /* initialize bins. */
+ BoundBox range_bounds;
+ if (aligned_space == NULL) {
+ range_bounds = range.bounds();
+ }
+ else {
+ range_bounds = unaligned_heuristic->compute_aligned_boundbox(
+ range, &references->at(0), *aligned_space);
+ }
+
+ float3 origin = range_bounds.min;
+ float3 binSize = (range_bounds.max - origin) * (1.0f / (float)BVHParams::NUM_SPATIAL_BINS);
+ float3 invBinSize = 1.0f / binSize;
+
+ for (int dim = 0; dim < 3; dim++) {
+ for (int i = 0; i < BVHParams::NUM_SPATIAL_BINS; i++) {
+ BVHSpatialBin &bin = storage_->bins[dim][i];
+
+ bin.bounds = BoundBox::empty;
+ bin.enter = 0;
+ bin.exit = 0;
+ }
+ }
+
+ /* chop references into bins. */
+ for (unsigned int refIdx = range.start(); refIdx < range.end(); refIdx++) {
+ const BVHReference &ref = references_->at(refIdx);
+ BoundBox prim_bounds = get_prim_bounds(ref);
+ float3 firstBinf = (prim_bounds.min - origin) * invBinSize;
+ float3 lastBinf = (prim_bounds.max - origin) * invBinSize;
+ int3 firstBin = make_int3((int)firstBinf.x, (int)firstBinf.y, (int)firstBinf.z);
+ int3 lastBin = make_int3((int)lastBinf.x, (int)lastBinf.y, (int)lastBinf.z);
+
+ firstBin = clamp(firstBin, 0, BVHParams::NUM_SPATIAL_BINS - 1);
+ lastBin = clamp(lastBin, firstBin, BVHParams::NUM_SPATIAL_BINS - 1);
+
+ for (int dim = 0; dim < 3; dim++) {
+ BVHReference currRef(
+ get_prim_bounds(ref), ref.prim_index(), ref.prim_object(), ref.prim_type());
+
+ for (int i = firstBin[dim]; i < lastBin[dim]; i++) {
+ BVHReference leftRef, rightRef;
+
+ split_reference(
+ builder, leftRef, rightRef, currRef, dim, origin[dim] + binSize[dim] * (float)(i + 1));
+ storage_->bins[dim][i].bounds.grow(leftRef.bounds());
+ currRef = rightRef;
+ }
+
+ storage_->bins[dim][lastBin[dim]].bounds.grow(currRef.bounds());
+ storage_->bins[dim][firstBin[dim]].enter++;
+ storage_->bins[dim][lastBin[dim]].exit++;
+ }
+ }
+
+ /* select best split plane. */
+ storage_->right_bounds.resize(BVHParams::NUM_SPATIAL_BINS);
+ for (int dim = 0; dim < 3; dim++) {
+ /* sweep right to left and determine bounds. */
+ BoundBox right_bounds = BoundBox::empty;
+ for (int i = BVHParams::NUM_SPATIAL_BINS - 1; i > 0; i--) {
+ right_bounds.grow(storage_->bins[dim][i].bounds);
+ storage_->right_bounds[i - 1] = right_bounds;
+ }
+
+ /* sweep left to right and select lowest SAH. */
+ BoundBox left_bounds = BoundBox::empty;
+ int leftNum = 0;
+ int rightNum = range.size();
+
+ for (int i = 1; i < BVHParams::NUM_SPATIAL_BINS; i++) {
+ left_bounds.grow(storage_->bins[dim][i - 1].bounds);
+ leftNum += storage_->bins[dim][i - 1].enter;
+ rightNum -= storage_->bins[dim][i - 1].exit;
+
+ float sah = nodeSAH + left_bounds.safe_area() * builder.params.primitive_cost(leftNum) +
+ storage_->right_bounds[i - 1].safe_area() *
+ builder.params.primitive_cost(rightNum);
+
+ if (sah < this->sah) {
+ this->sah = sah;
+ this->dim = dim;
+ this->pos = origin[dim] + binSize[dim] * (float)i;
+ }
+ }
+ }
}
void BVHSpatialSplit::split(BVHBuild *builder,
- BVHRange& left,
- BVHRange& right,
- const BVHRange& range)
+ BVHRange &left,
+ BVHRange &right,
+ const BVHRange &range)
{
- /* Categorize references and compute bounds.
- *
- * Left-hand side: [left_start, left_end[
- * Uncategorized/split: [left_end, right_start[
- * Right-hand side: [right_start, refs.size()[ */
-
- vector<BVHReference>& refs = *references_;
- int left_start = range.start();
- int left_end = left_start;
- int right_start = range.end();
- int right_end = range.end();
- BoundBox left_bounds = BoundBox::empty;
- BoundBox right_bounds = BoundBox::empty;
-
- for(int i = left_end; i < right_start; i++) {
- BoundBox prim_bounds = get_prim_bounds(refs[i]);
- if(prim_bounds.max[this->dim] <= this->pos) {
- /* entirely on the left-hand side */
- left_bounds.grow(prim_bounds);
- swap(refs[i], refs[left_end++]);
- }
- else if(prim_bounds.min[this->dim] >= this->pos) {
- /* entirely on the right-hand side */
- right_bounds.grow(prim_bounds);
- swap(refs[i--], refs[--right_start]);
- }
- }
-
- /* Duplicate or unsplit references intersecting both sides.
- *
- * Duplication happens into a temporary pre-allocated vector in order to
- * reduce number of memmove() calls happening in vector.insert().
- */
- vector<BVHReference>& new_refs = storage_->new_references;
- new_refs.clear();
- new_refs.reserve(right_start - left_end);
- while(left_end < right_start) {
- /* split reference. */
- BVHReference curr_ref(get_prim_bounds(refs[left_end]),
- refs[left_end].prim_index(),
- refs[left_end].prim_object(),
- refs[left_end].prim_type());
- BVHReference lref, rref;
- split_reference(*builder, lref, rref, curr_ref, this->dim, this->pos);
-
- /* compute SAH for duplicate/unsplit candidates. */
- BoundBox lub = left_bounds; // Unsplit to left: new left-hand bounds.
- BoundBox rub = right_bounds; // Unsplit to right: new right-hand bounds.
- BoundBox ldb = left_bounds; // Duplicate: new left-hand bounds.
- BoundBox rdb = right_bounds; // Duplicate: new right-hand bounds.
-
- lub.grow(curr_ref.bounds());
- rub.grow(curr_ref.bounds());
- ldb.grow(lref.bounds());
- rdb.grow(rref.bounds());
-
- float lac = builder->params.primitive_cost(left_end - left_start);
- float rac = builder->params.primitive_cost(right_end - right_start);
- float lbc = builder->params.primitive_cost(left_end - left_start + 1);
- float rbc = builder->params.primitive_cost(right_end - right_start + 1);
-
- float unsplitLeftSAH = lub.safe_area() * lbc + right_bounds.safe_area() * rac;
- float unsplitRightSAH = left_bounds.safe_area() * lac + rub.safe_area() * rbc;
- float duplicateSAH = ldb.safe_area() * lbc + rdb.safe_area() * rbc;
- float minSAH = min(min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH);
-
- if(minSAH == unsplitLeftSAH) {
- /* unsplit to left */
- left_bounds = lub;
- left_end++;
- }
- else if(minSAH == unsplitRightSAH) {
- /* unsplit to right */
- right_bounds = rub;
- swap(refs[left_end], refs[--right_start]);
- }
- else {
- /* duplicate */
- left_bounds = ldb;
- right_bounds = rdb;
- refs[left_end++] = lref;
- new_refs.push_back(rref);
- right_end++;
- }
- }
- /* Insert duplicated references into actual array in one go. */
- if(new_refs.size() != 0) {
- refs.insert(refs.begin() + (right_end - new_refs.size()),
- new_refs.begin(),
- new_refs.end());
- }
- if(aligned_space_ != NULL) {
- left_bounds = right_bounds = BoundBox::empty;
- for(int i = left_start; i < left_end - left_start; ++i) {
- BoundBox prim_boundbox = references_->at(i).bounds();
- left_bounds.grow(prim_boundbox);
- }
- for(int i = right_start; i < right_end - right_start; ++i) {
- BoundBox prim_boundbox = references_->at(i).bounds();
- right_bounds.grow(prim_boundbox);
- }
- }
- left = BVHRange(left_bounds, left_start, left_end - left_start);
- right = BVHRange(right_bounds, right_start, right_end - right_start);
+ /* Categorize references and compute bounds.
+ *
+ * Left-hand side: [left_start, left_end[
+ * Uncategorized/split: [left_end, right_start[
+ * Right-hand side: [right_start, refs.size()[ */
+
+ vector<BVHReference> &refs = *references_;
+ int left_start = range.start();
+ int left_end = left_start;
+ int right_start = range.end();
+ int right_end = range.end();
+ BoundBox left_bounds = BoundBox::empty;
+ BoundBox right_bounds = BoundBox::empty;
+
+ for (int i = left_end; i < right_start; i++) {
+ BoundBox prim_bounds = get_prim_bounds(refs[i]);
+ if (prim_bounds.max[this->dim] <= this->pos) {
+ /* entirely on the left-hand side */
+ left_bounds.grow(prim_bounds);
+ swap(refs[i], refs[left_end++]);
+ }
+ else if (prim_bounds.min[this->dim] >= this->pos) {
+ /* entirely on the right-hand side */
+ right_bounds.grow(prim_bounds);
+ swap(refs[i--], refs[--right_start]);
+ }
+ }
+
+ /* Duplicate or unsplit references intersecting both sides.
+ *
+ * Duplication happens into a temporary pre-allocated vector in order to
+ * reduce number of memmove() calls happening in vector.insert().
+ */
+ vector<BVHReference> &new_refs = storage_->new_references;
+ new_refs.clear();
+ new_refs.reserve(right_start - left_end);
+ while (left_end < right_start) {
+ /* split reference. */
+ BVHReference curr_ref(get_prim_bounds(refs[left_end]),
+ refs[left_end].prim_index(),
+ refs[left_end].prim_object(),
+ refs[left_end].prim_type());
+ BVHReference lref, rref;
+ split_reference(*builder, lref, rref, curr_ref, this->dim, this->pos);
+
+ /* compute SAH for duplicate/unsplit candidates. */
+ BoundBox lub = left_bounds; // Unsplit to left: new left-hand bounds.
+ BoundBox rub = right_bounds; // Unsplit to right: new right-hand bounds.
+ BoundBox ldb = left_bounds; // Duplicate: new left-hand bounds.
+ BoundBox rdb = right_bounds; // Duplicate: new right-hand bounds.
+
+ lub.grow(curr_ref.bounds());
+ rub.grow(curr_ref.bounds());
+ ldb.grow(lref.bounds());
+ rdb.grow(rref.bounds());
+
+ float lac = builder->params.primitive_cost(left_end - left_start);
+ float rac = builder->params.primitive_cost(right_end - right_start);
+ float lbc = builder->params.primitive_cost(left_end - left_start + 1);
+ float rbc = builder->params.primitive_cost(right_end - right_start + 1);
+
+ float unsplitLeftSAH = lub.safe_area() * lbc + right_bounds.safe_area() * rac;
+ float unsplitRightSAH = left_bounds.safe_area() * lac + rub.safe_area() * rbc;
+ float duplicateSAH = ldb.safe_area() * lbc + rdb.safe_area() * rbc;
+ float minSAH = min(min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH);
+
+ if (minSAH == unsplitLeftSAH) {
+ /* unsplit to left */
+ left_bounds = lub;
+ left_end++;
+ }
+ else if (minSAH == unsplitRightSAH) {
+ /* unsplit to right */
+ right_bounds = rub;
+ swap(refs[left_end], refs[--right_start]);
+ }
+ else {
+ /* duplicate */
+ left_bounds = ldb;
+ right_bounds = rdb;
+ refs[left_end++] = lref;
+ new_refs.push_back(rref);
+ right_end++;
+ }
+ }
+ /* Insert duplicated references into actual array in one go. */
+ if (new_refs.size() != 0) {
+ refs.insert(refs.begin() + (right_end - new_refs.size()), new_refs.begin(), new_refs.end());
+ }
+ if (aligned_space_ != NULL) {
+ left_bounds = right_bounds = BoundBox::empty;
+ for (int i = left_start; i < left_end - left_start; ++i) {
+ BoundBox prim_boundbox = references_->at(i).bounds();
+ left_bounds.grow(prim_boundbox);
+ }
+ for (int i = right_start; i < right_end - right_start; ++i) {
+ BoundBox prim_boundbox = references_->at(i).bounds();
+ right_bounds.grow(prim_boundbox);
+ }
+ }
+ left = BVHRange(left_bounds, left_start, left_end - left_start);
+ right = BVHRange(right_bounds, right_start, right_end - right_start);
}
void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh,
@@ -354,36 +346,36 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh,
int prim_index,
int dim,
float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds)
+ BoundBox &left_bounds,
+ BoundBox &right_bounds)
{
- Mesh::Triangle t = mesh->get_triangle(prim_index);
- const float3 *verts = &mesh->verts[0];
- float3 v1 = tfm ? transform_point(tfm, verts[t.v[2]]) : verts[t.v[2]];
- v1 = get_unaligned_point(v1);
-
- for(int i = 0; i < 3; i++) {
- float3 v0 = v1;
- int vindex = t.v[i];
- v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex];
- v1 = get_unaligned_point(v1);
- float v0p = v0[dim];
- float v1p = v1[dim];
-
- /* insert vertex to the boxes it belongs to. */
- if(v0p <= pos)
- left_bounds.grow(v0);
-
- if(v0p >= pos)
- right_bounds.grow(v0);
-
- /* edge intersects the plane => insert intersection to both boxes. */
- if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
- float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
- left_bounds.grow(t);
- right_bounds.grow(t);
- }
- }
+ Mesh::Triangle t = mesh->get_triangle(prim_index);
+ const float3 *verts = &mesh->verts[0];
+ float3 v1 = tfm ? transform_point(tfm, verts[t.v[2]]) : verts[t.v[2]];
+ v1 = get_unaligned_point(v1);
+
+ for (int i = 0; i < 3; i++) {
+ float3 v0 = v1;
+ int vindex = t.v[i];
+ v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex];
+ v1 = get_unaligned_point(v1);
+ float v0p = v0[dim];
+ float v1p = v1[dim];
+
+ /* insert vertex to the boxes it belongs to. */
+ if (v0p <= pos)
+ left_bounds.grow(v0);
+
+ if (v0p >= pos)
+ right_bounds.grow(v0);
+
+ /* edge intersects the plane => insert intersection to both boxes. */
+ if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
+ float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ left_bounds.grow(t);
+ right_bounds.grow(t);
+ }
+ }
}
void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh,
@@ -392,163 +384,125 @@ void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh,
int segment_index,
int dim,
float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds)
+ BoundBox &left_bounds,
+ BoundBox &right_bounds)
{
- /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
- Mesh::Curve curve = mesh->get_curve(prim_index);
- const int k0 = curve.first_key + segment_index;
- const int k1 = k0 + 1;
- float3 v0 = mesh->curve_keys[k0];
- float3 v1 = mesh->curve_keys[k1];
-
- if(tfm != NULL) {
- v0 = transform_point(tfm, v0);
- v1 = transform_point(tfm, v1);
- }
- v0 = get_unaligned_point(v0);
- v1 = get_unaligned_point(v1);
-
- float v0p = v0[dim];
- float v1p = v1[dim];
-
- /* insert vertex to the boxes it belongs to. */
- if(v0p <= pos)
- left_bounds.grow(v0);
-
- if(v0p >= pos)
- right_bounds.grow(v0);
-
- if(v1p <= pos)
- left_bounds.grow(v1);
-
- if(v1p >= pos)
- right_bounds.grow(v1);
-
- /* edge intersects the plane => insert intersection to both boxes. */
- if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
- float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
- left_bounds.grow(t);
- right_bounds.grow(t);
- }
+ /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
+ Mesh::Curve curve = mesh->get_curve(prim_index);
+ const int k0 = curve.first_key + segment_index;
+ const int k1 = k0 + 1;
+ float3 v0 = mesh->curve_keys[k0];
+ float3 v1 = mesh->curve_keys[k1];
+
+ if (tfm != NULL) {
+ v0 = transform_point(tfm, v0);
+ v1 = transform_point(tfm, v1);
+ }
+ v0 = get_unaligned_point(v0);
+ v1 = get_unaligned_point(v1);
+
+ float v0p = v0[dim];
+ float v1p = v1[dim];
+
+ /* insert vertex to the boxes it belongs to. */
+ if (v0p <= pos)
+ left_bounds.grow(v0);
+
+ if (v0p >= pos)
+ right_bounds.grow(v0);
+
+ if (v1p <= pos)
+ left_bounds.grow(v1);
+
+ if (v1p >= pos)
+ right_bounds.grow(v1);
+
+ /* edge intersects the plane => insert intersection to both boxes. */
+ if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
+ float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ left_bounds.grow(t);
+ right_bounds.grow(t);
+ }
}
-void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref,
+void BVHSpatialSplit::split_triangle_reference(const BVHReference &ref,
const Mesh *mesh,
int dim,
float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds)
+ BoundBox &left_bounds,
+ BoundBox &right_bounds)
{
- split_triangle_primitive(mesh,
- NULL,
- ref.prim_index(),
- dim,
- pos,
- left_bounds,
- right_bounds);
+ split_triangle_primitive(mesh, NULL, ref.prim_index(), dim, pos, left_bounds, right_bounds);
}
-void BVHSpatialSplit::split_curve_reference(const BVHReference& ref,
+void BVHSpatialSplit::split_curve_reference(const BVHReference &ref,
const Mesh *mesh,
int dim,
float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds)
+ BoundBox &left_bounds,
+ BoundBox &right_bounds)
{
- split_curve_primitive(mesh,
- NULL,
- ref.prim_index(),
- PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()),
- dim,
- pos,
- left_bounds,
- right_bounds);
+ split_curve_primitive(mesh,
+ NULL,
+ ref.prim_index(),
+ PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()),
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
}
-void BVHSpatialSplit::split_object_reference(const Object *object,
- int dim,
- float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds)
+void BVHSpatialSplit::split_object_reference(
+ const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
{
- Mesh *mesh = object->mesh;
- for(int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) {
- split_triangle_primitive(mesh,
- &object->tfm,
- tri_idx,
- dim,
- pos,
- left_bounds,
- right_bounds);
- }
- for(int curve_idx = 0; curve_idx < mesh->num_curves(); ++curve_idx) {
- Mesh::Curve curve = mesh->get_curve(curve_idx);
- for(int segment_idx = 0;
- segment_idx < curve.num_keys - 1;
- ++segment_idx)
- {
- split_curve_primitive(mesh,
- &object->tfm,
- curve_idx,
- segment_idx,
- dim,
- pos,
- left_bounds,
- right_bounds);
- }
- }
+ Mesh *mesh = object->mesh;
+ for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) {
+ split_triangle_primitive(mesh, &object->tfm, tri_idx, dim, pos, left_bounds, right_bounds);
+ }
+ for (int curve_idx = 0; curve_idx < mesh->num_curves(); ++curve_idx) {
+ Mesh::Curve curve = mesh->get_curve(curve_idx);
+ for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) {
+ split_curve_primitive(
+ mesh, &object->tfm, curve_idx, segment_idx, dim, pos, left_bounds, right_bounds);
+ }
+ }
}
-void BVHSpatialSplit::split_reference(const BVHBuild& builder,
- BVHReference& left,
- BVHReference& right,
- const BVHReference& ref,
+void BVHSpatialSplit::split_reference(const BVHBuild &builder,
+ BVHReference &left,
+ BVHReference &right,
+ const BVHReference &ref,
int dim,
float pos)
{
- /* initialize boundboxes */
- BoundBox left_bounds = BoundBox::empty;
- BoundBox right_bounds = BoundBox::empty;
-
- /* loop over vertices/edges. */
- const Object *ob = builder.objects[ref.prim_object()];
- const Mesh *mesh = ob->mesh;
-
- if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
- split_triangle_reference(ref,
- mesh,
- dim,
- pos,
- left_bounds,
- right_bounds);
- }
- else if(ref.prim_type() & PRIMITIVE_ALL_CURVE) {
- split_curve_reference(ref,
- mesh,
- dim,
- pos,
- left_bounds,
- right_bounds);
- }
- else {
- split_object_reference(ob,
- dim,
- pos,
- left_bounds,
- right_bounds);
- }
-
- /* intersect with original bounds. */
- left_bounds.max[dim] = pos;
- right_bounds.min[dim] = pos;
-
- left_bounds.intersect(ref.bounds());
- right_bounds.intersect(ref.bounds());
-
- /* set references */
- left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
- right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
+ /* initialize boundboxes */
+ BoundBox left_bounds = BoundBox::empty;
+ BoundBox right_bounds = BoundBox::empty;
+
+ /* loop over vertices/edges. */
+ const Object *ob = builder.objects[ref.prim_object()];
+ const Mesh *mesh = ob->mesh;
+
+ if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
+ split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
+ }
+ else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
+ split_curve_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
+ }
+ else {
+ split_object_reference(ob, dim, pos, left_bounds, right_bounds);
+ }
+
+ /* intersect with original bounds. */
+ left_bounds.max[dim] = pos;
+ right_bounds.min[dim] = pos;
+
+ left_bounds.intersect(ref.bounds());
+ right_bounds.intersect(ref.bounds());
+
+ /* set references */
+ left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
+ right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h
index cb47deab211..eddd1c27f49 100644
--- a/intern/cycles/bvh/bvh_split.h
+++ b/intern/cycles/bvh/bvh_split.h
@@ -28,235 +28,211 @@ struct Transform;
/* Object Split */
-class BVHObjectSplit
-{
-public:
- float sah;
- int dim;
- int num_left;
- BoundBox left_bounds;
- BoundBox right_bounds;
-
- BVHObjectSplit() {}
- BVHObjectSplit(BVHBuild *builder,
- BVHSpatialStorage *storage,
- const BVHRange& range,
- vector<BVHReference> *references,
- float nodeSAH,
- const BVHUnaligned *unaligned_heuristic = NULL,
- const Transform *aligned_space = NULL);
-
- void split(BVHRange& left,
- BVHRange& right,
- const BVHRange& range);
-
-protected:
- BVHSpatialStorage *storage_;
- vector<BVHReference> *references_;
- const BVHUnaligned *unaligned_heuristic_;
- const Transform *aligned_space_;
-
- __forceinline BoundBox get_prim_bounds(const BVHReference& prim) const
- {
- if(aligned_space_ == NULL) {
- return prim.bounds();
- }
- else {
- return unaligned_heuristic_->compute_aligned_prim_boundbox(
- prim, *aligned_space_);
- }
- }
+class BVHObjectSplit {
+ public:
+ float sah;
+ int dim;
+ int num_left;
+ BoundBox left_bounds;
+ BoundBox right_bounds;
+
+ BVHObjectSplit()
+ {
+ }
+ BVHObjectSplit(BVHBuild *builder,
+ BVHSpatialStorage *storage,
+ const BVHRange &range,
+ vector<BVHReference> *references,
+ float nodeSAH,
+ const BVHUnaligned *unaligned_heuristic = NULL,
+ const Transform *aligned_space = NULL);
+
+ void split(BVHRange &left, BVHRange &right, const BVHRange &range);
+
+ protected:
+ BVHSpatialStorage *storage_;
+ vector<BVHReference> *references_;
+ const BVHUnaligned *unaligned_heuristic_;
+ const Transform *aligned_space_;
+
+ __forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
+ {
+ if (aligned_space_ == NULL) {
+ return prim.bounds();
+ }
+ else {
+ return unaligned_heuristic_->compute_aligned_prim_boundbox(prim, *aligned_space_);
+ }
+ }
};
/* Spatial Split */
-class BVHSpatialSplit
-{
-public:
- float sah;
- int dim;
- float pos;
-
- BVHSpatialSplit() : sah(FLT_MAX),
- dim(0),
- pos(0.0f),
- storage_(NULL),
- references_(NULL) {}
- BVHSpatialSplit(const BVHBuild& builder,
- BVHSpatialStorage *storage,
- const BVHRange& range,
- vector<BVHReference> *references,
- float nodeSAH,
- const BVHUnaligned *unaligned_heuristic = NULL,
- const Transform *aligned_space = NULL);
-
- void split(BVHBuild *builder,
- BVHRange& left,
- BVHRange& right,
- const BVHRange& range);
-
- void split_reference(const BVHBuild& builder,
- BVHReference& left,
- BVHReference& right,
- const BVHReference& ref,
- int dim,
- float pos);
-
-protected:
- BVHSpatialStorage *storage_;
- vector<BVHReference> *references_;
- const BVHUnaligned *unaligned_heuristic_;
- const Transform *aligned_space_;
-
- /* Lower-level functions which calculates boundaries of left and right nodes
- * needed for spatial split.
- *
- * Operates directly with primitive specified by it's index, reused by higher
- * level splitting functions.
- */
- void split_triangle_primitive(const Mesh *mesh,
- const Transform *tfm,
- int prim_index,
- int dim,
- float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds);
- void split_curve_primitive(const Mesh *mesh,
- const Transform *tfm,
- int prim_index,
- int segment_index,
- int dim,
- float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds);
-
- /* Lower-level functions which calculates boundaries of left and right nodes
- * needed for spatial split.
- *
- * Operates with BVHReference, internally uses lower level API functions.
- */
- void split_triangle_reference(const BVHReference& ref,
- const Mesh *mesh,
- int dim,
- float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds);
- void split_curve_reference(const BVHReference& ref,
- const Mesh *mesh,
- int dim,
- float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds);
- void split_object_reference(const Object *object,
- int dim,
- float pos,
- BoundBox& left_bounds,
- BoundBox& right_bounds);
-
- __forceinline BoundBox get_prim_bounds(const BVHReference& prim) const
- {
- if(aligned_space_ == NULL) {
- return prim.bounds();
- }
- else {
- return unaligned_heuristic_->compute_aligned_prim_boundbox(
- prim, *aligned_space_);
- }
- }
-
- __forceinline float3 get_unaligned_point(const float3& point) const
- {
- if(aligned_space_ == NULL) {
- return point;
- }
- else {
- return transform_point(aligned_space_, point);
- }
- }
+class BVHSpatialSplit {
+ public:
+ float sah;
+ int dim;
+ float pos;
+
+ BVHSpatialSplit() : sah(FLT_MAX), dim(0), pos(0.0f), storage_(NULL), references_(NULL)
+ {
+ }
+ BVHSpatialSplit(const BVHBuild &builder,
+ BVHSpatialStorage *storage,
+ const BVHRange &range,
+ vector<BVHReference> *references,
+ float nodeSAH,
+ const BVHUnaligned *unaligned_heuristic = NULL,
+ const Transform *aligned_space = NULL);
+
+ void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range);
+
+ void split_reference(const BVHBuild &builder,
+ BVHReference &left,
+ BVHReference &right,
+ const BVHReference &ref,
+ int dim,
+ float pos);
+
+ protected:
+ BVHSpatialStorage *storage_;
+ vector<BVHReference> *references_;
+ const BVHUnaligned *unaligned_heuristic_;
+ const Transform *aligned_space_;
+
+ /* Lower-level functions which calculates boundaries of left and right nodes
+ * needed for spatial split.
+ *
+ * Operates directly with primitive specified by it's index, reused by higher
+ * level splitting functions.
+ */
+ void split_triangle_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int dim,
+ float pos,
+ BoundBox &left_bounds,
+ BoundBox &right_bounds);
+ void split_curve_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int segment_index,
+ int dim,
+ float pos,
+ BoundBox &left_bounds,
+ BoundBox &right_bounds);
+
+ /* Lower-level functions which calculates boundaries of left and right nodes
+ * needed for spatial split.
+ *
+ * Operates with BVHReference, internally uses lower level API functions.
+ */
+ void split_triangle_reference(const BVHReference &ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox &left_bounds,
+ BoundBox &right_bounds);
+ void split_curve_reference(const BVHReference &ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox &left_bounds,
+ BoundBox &right_bounds);
+ void split_object_reference(
+ const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds);
+
+ __forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
+ {
+ if (aligned_space_ == NULL) {
+ return prim.bounds();
+ }
+ else {
+ return unaligned_heuristic_->compute_aligned_prim_boundbox(prim, *aligned_space_);
+ }
+ }
+
+ __forceinline float3 get_unaligned_point(const float3 &point) const
+ {
+ if (aligned_space_ == NULL) {
+ return point;
+ }
+ else {
+ return transform_point(aligned_space_, point);
+ }
+ }
};
/* Mixed Object-Spatial Split */
-class BVHMixedSplit
-{
-public:
- BVHObjectSplit object;
- BVHSpatialSplit spatial;
-
- float leafSAH;
- float nodeSAH;
- float minSAH;
-
- bool no_split;
-
- BoundBox bounds;
-
- BVHMixedSplit() {}
-
- __forceinline BVHMixedSplit(BVHBuild *builder,
- BVHSpatialStorage *storage,
- const BVHRange& range,
- vector<BVHReference> *references,
- int level,
- const BVHUnaligned *unaligned_heuristic = NULL,
- const Transform *aligned_space = NULL)
- {
- if(aligned_space == NULL) {
- bounds = range.bounds();
- }
- else {
- bounds = unaligned_heuristic->compute_aligned_boundbox(
- range,
- &references->at(0),
- *aligned_space);
- }
- /* find split candidates. */
- float area = bounds.safe_area();
-
- leafSAH = area * builder->params.primitive_cost(range.size());
- nodeSAH = area * builder->params.node_cost(2);
-
- object = BVHObjectSplit(builder,
- storage,
- range,
- references,
- nodeSAH,
- unaligned_heuristic,
- aligned_space);
-
- if(builder->params.use_spatial_split && level < BVHParams::MAX_SPATIAL_DEPTH) {
- BoundBox overlap = object.left_bounds;
- overlap.intersect(object.right_bounds);
-
- if(overlap.safe_area() >= builder->spatial_min_overlap) {
- spatial = BVHSpatialSplit(*builder,
- storage,
- range,
- references,
- nodeSAH,
- unaligned_heuristic,
- aligned_space);
- }
- }
-
- /* leaf SAH is the lowest => create leaf. */
- minSAH = min(min(leafSAH, object.sah), spatial.sah);
- no_split = (minSAH == leafSAH &&
- builder->range_within_max_leaf_size(range, *references));
- }
-
- __forceinline void split(BVHBuild *builder,
- BVHRange& left,
- BVHRange& right,
- const BVHRange& range)
- {
- if(builder->params.use_spatial_split && minSAH == spatial.sah)
- spatial.split(builder, left, right, range);
- if(!left.size() || !right.size())
- object.split(left, right, range);
- }
+class BVHMixedSplit {
+ public:
+ BVHObjectSplit object;
+ BVHSpatialSplit spatial;
+
+ float leafSAH;
+ float nodeSAH;
+ float minSAH;
+
+ bool no_split;
+
+ BoundBox bounds;
+
+ BVHMixedSplit()
+ {
+ }
+
+ __forceinline BVHMixedSplit(BVHBuild *builder,
+ BVHSpatialStorage *storage,
+ const BVHRange &range,
+ vector<BVHReference> *references,
+ int level,
+ const BVHUnaligned *unaligned_heuristic = NULL,
+ const Transform *aligned_space = NULL)
+ {
+ if (aligned_space == NULL) {
+ bounds = range.bounds();
+ }
+ else {
+ bounds = unaligned_heuristic->compute_aligned_boundbox(
+ range, &references->at(0), *aligned_space);
+ }
+ /* find split candidates. */
+ float area = bounds.safe_area();
+
+ leafSAH = area * builder->params.primitive_cost(range.size());
+ nodeSAH = area * builder->params.node_cost(2);
+
+ object = BVHObjectSplit(
+ builder, storage, range, references, nodeSAH, unaligned_heuristic, aligned_space);
+
+ if (builder->params.use_spatial_split && level < BVHParams::MAX_SPATIAL_DEPTH) {
+ BoundBox overlap = object.left_bounds;
+ overlap.intersect(object.right_bounds);
+
+ if (overlap.safe_area() >= builder->spatial_min_overlap) {
+ spatial = BVHSpatialSplit(
+ *builder, storage, range, references, nodeSAH, unaligned_heuristic, aligned_space);
+ }
+ }
+
+ /* leaf SAH is the lowest => create leaf. */
+ minSAH = min(min(leafSAH, object.sah), spatial.sah);
+ no_split = (minSAH == leafSAH && builder->range_within_max_leaf_size(range, *references));
+ }
+
+ __forceinline void split(BVHBuild *builder,
+ BVHRange &left,
+ BVHRange &right,
+ const BVHRange &range)
+ {
+ if (builder->params.use_spatial_split && minSAH == spatial.sah)
+ spatial.split(builder, left, right, range);
+ if (!left.size() || !right.size())
+ object.split(left, right, range);
+ }
};
CCL_NAMESPACE_END
-#endif /* __BVH_SPLIT_H__ */
+#endif /* __BVH_SPLIT_H__ */
diff --git a/intern/cycles/bvh/bvh_unaligned.cpp b/intern/cycles/bvh/bvh_unaligned.cpp
index 910f82137c5..1843ca403a5 100644
--- a/intern/cycles/bvh/bvh_unaligned.cpp
+++ b/intern/cycles/bvh/bvh_unaligned.cpp
@@ -27,150 +27,137 @@
CCL_NAMESPACE_BEGIN
-
-BVHUnaligned::BVHUnaligned(const vector<Object*>& objects)
- : objects_(objects)
+BVHUnaligned::BVHUnaligned(const vector<Object *> &objects) : objects_(objects)
{
}
-Transform BVHUnaligned::compute_aligned_space(
- const BVHObjectBinning& range,
- const BVHReference *references) const
+Transform BVHUnaligned::compute_aligned_space(const BVHObjectBinning &range,
+ const BVHReference *references) const
{
- for(int i = range.start(); i < range.end(); ++i) {
- const BVHReference& ref = references[i];
- Transform aligned_space;
- /* Use first primitive which defines correct direction to define
- * the orientation space.
- */
- if(compute_aligned_space(ref, &aligned_space)) {
- return aligned_space;
- }
- }
- return transform_identity();
+ for (int i = range.start(); i < range.end(); ++i) {
+ const BVHReference &ref = references[i];
+ Transform aligned_space;
+ /* Use first primitive which defines correct direction to define
+ * the orientation space.
+ */
+ if (compute_aligned_space(ref, &aligned_space)) {
+ return aligned_space;
+ }
+ }
+ return transform_identity();
}
-Transform BVHUnaligned::compute_aligned_space(
- const BVHRange& range,
- const BVHReference *references) const
+Transform BVHUnaligned::compute_aligned_space(const BVHRange &range,
+ const BVHReference *references) const
{
- for(int i = range.start(); i < range.end(); ++i) {
- const BVHReference& ref = references[i];
- Transform aligned_space;
- /* Use first primitive which defines correct direction to define
- * the orientation space.
- */
- if(compute_aligned_space(ref, &aligned_space)) {
- return aligned_space;
- }
- }
- return transform_identity();
+ for (int i = range.start(); i < range.end(); ++i) {
+ const BVHReference &ref = references[i];
+ Transform aligned_space;
+ /* Use first primitive which defines correct direction to define
+ * the orientation space.
+ */
+ if (compute_aligned_space(ref, &aligned_space)) {
+ return aligned_space;
+ }
+ }
+ return transform_identity();
}
-bool BVHUnaligned::compute_aligned_space(const BVHReference& ref,
- Transform *aligned_space) const
+bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *aligned_space) const
{
- const Object *object = objects_[ref.prim_object()];
- const int packed_type = ref.prim_type();
- const int type = (packed_type & PRIMITIVE_ALL);
- if(type & PRIMITIVE_CURVE) {
- const int curve_index = ref.prim_index();
- const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
- const Mesh *mesh = object->mesh;
- const Mesh::Curve& curve = mesh->get_curve(curve_index);
- const int key = curve.first_key + segment;
- const float3 v1 = mesh->curve_keys[key],
- v2 = mesh->curve_keys[key + 1];
- float length;
- const float3 axis = normalize_len(v2 - v1, &length);
- if(length > 1e-6f) {
- *aligned_space = make_transform_frame(axis);
- return true;
- }
- }
- *aligned_space = transform_identity();
- return false;
+ const Object *object = objects_[ref.prim_object()];
+ const int packed_type = ref.prim_type();
+ const int type = (packed_type & PRIMITIVE_ALL);
+ if (type & PRIMITIVE_CURVE) {
+ const int curve_index = ref.prim_index();
+ const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
+ const Mesh *mesh = object->mesh;
+ const Mesh::Curve &curve = mesh->get_curve(curve_index);
+ const int key = curve.first_key + segment;
+ const float3 v1 = mesh->curve_keys[key], v2 = mesh->curve_keys[key + 1];
+ float length;
+ const float3 axis = normalize_len(v2 - v1, &length);
+ if (length > 1e-6f) {
+ *aligned_space = make_transform_frame(axis);
+ return true;
+ }
+ }
+ *aligned_space = transform_identity();
+ return false;
}
-BoundBox BVHUnaligned::compute_aligned_prim_boundbox(
- const BVHReference& prim,
- const Transform& aligned_space) const
+BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim,
+ const Transform &aligned_space) const
{
- BoundBox bounds = BoundBox::empty;
- const Object *object = objects_[prim.prim_object()];
- const int packed_type = prim.prim_type();
- const int type = (packed_type & PRIMITIVE_ALL);
- if(type & PRIMITIVE_CURVE) {
- const int curve_index = prim.prim_index();
- const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
- const Mesh *mesh = object->mesh;
- const Mesh::Curve& curve = mesh->get_curve(curve_index);
- curve.bounds_grow(segment,
- &mesh->curve_keys[0],
- &mesh->curve_radius[0],
- aligned_space,
- bounds);
- }
- else {
- bounds = prim.bounds().transformed(&aligned_space);
- }
- return bounds;
+ BoundBox bounds = BoundBox::empty;
+ const Object *object = objects_[prim.prim_object()];
+ const int packed_type = prim.prim_type();
+ const int type = (packed_type & PRIMITIVE_ALL);
+ if (type & PRIMITIVE_CURVE) {
+ const int curve_index = prim.prim_index();
+ const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
+ const Mesh *mesh = object->mesh;
+ const Mesh::Curve &curve = mesh->get_curve(curve_index);
+ curve.bounds_grow(
+ segment, &mesh->curve_keys[0], &mesh->curve_radius[0], aligned_space, bounds);
+ }
+ else {
+ bounds = prim.bounds().transformed(&aligned_space);
+ }
+ return bounds;
}
-BoundBox BVHUnaligned::compute_aligned_boundbox(
- const BVHObjectBinning& range,
- const BVHReference *references,
- const Transform& aligned_space,
- BoundBox *cent_bounds) const
+BoundBox BVHUnaligned::compute_aligned_boundbox(const BVHObjectBinning &range,
+ const BVHReference *references,
+ const Transform &aligned_space,
+ BoundBox *cent_bounds) const
{
- BoundBox bounds = BoundBox::empty;
- if(cent_bounds != NULL) {
- *cent_bounds = BoundBox::empty;
- }
- for(int i = range.start(); i < range.end(); ++i) {
- const BVHReference& ref = references[i];
- BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
- bounds.grow(ref_bounds);
- if(cent_bounds != NULL) {
- cent_bounds->grow(ref_bounds.center2());
- }
- }
- return bounds;
+ BoundBox bounds = BoundBox::empty;
+ if (cent_bounds != NULL) {
+ *cent_bounds = BoundBox::empty;
+ }
+ for (int i = range.start(); i < range.end(); ++i) {
+ const BVHReference &ref = references[i];
+ BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
+ bounds.grow(ref_bounds);
+ if (cent_bounds != NULL) {
+ cent_bounds->grow(ref_bounds.center2());
+ }
+ }
+ return bounds;
}
-BoundBox BVHUnaligned::compute_aligned_boundbox(
- const BVHRange& range,
- const BVHReference *references,
- const Transform& aligned_space,
- BoundBox *cent_bounds) const
+BoundBox BVHUnaligned::compute_aligned_boundbox(const BVHRange &range,
+ const BVHReference *references,
+ const Transform &aligned_space,
+ BoundBox *cent_bounds) const
{
- BoundBox bounds = BoundBox::empty;
- if(cent_bounds != NULL) {
- *cent_bounds = BoundBox::empty;
- }
- for(int i = range.start(); i < range.end(); ++i) {
- const BVHReference& ref = references[i];
- BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
- bounds.grow(ref_bounds);
- if(cent_bounds != NULL) {
- cent_bounds->grow(ref_bounds.center2());
- }
- }
- return bounds;
+ BoundBox bounds = BoundBox::empty;
+ if (cent_bounds != NULL) {
+ *cent_bounds = BoundBox::empty;
+ }
+ for (int i = range.start(); i < range.end(); ++i) {
+ const BVHReference &ref = references[i];
+ BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
+ bounds.grow(ref_bounds);
+ if (cent_bounds != NULL) {
+ cent_bounds->grow(ref_bounds.center2());
+ }
+ }
+ return bounds;
}
-Transform BVHUnaligned::compute_node_transform(
- const BoundBox& bounds,
- const Transform& aligned_space)
+Transform BVHUnaligned::compute_node_transform(const BoundBox &bounds,
+ const Transform &aligned_space)
{
- Transform space = aligned_space;
- space.x.w -= bounds.min.x;
- space.y.w -= bounds.min.y;
- space.z.w -= bounds.min.z;
- float3 dim = bounds.max - bounds.min;
- return transform_scale(1.0f / max(1e-18f, dim.x),
- 1.0f / max(1e-18f, dim.y),
- 1.0f / max(1e-18f, dim.z)) * space;
+ Transform space = aligned_space;
+ space.x.w -= bounds.min.x;
+ space.y.w -= bounds.min.y;
+ space.z.w -= bounds.min.z;
+ float3 dim = bounds.max - bounds.min;
+ return transform_scale(
+ 1.0f / max(1e-18f, dim.x), 1.0f / max(1e-18f, dim.y), 1.0f / max(1e-18f, dim.z)) *
+ space;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_unaligned.h b/intern/cycles/bvh/bvh_unaligned.h
index bcfb6ed68da..e8a9a25daa8 100644
--- a/intern/cycles/bvh/bvh_unaligned.h
+++ b/intern/cycles/bvh/bvh_unaligned.h
@@ -30,51 +30,44 @@ class Object;
/* Helper class to perform calculations needed for unaligned nodes. */
class BVHUnaligned {
-public:
- BVHUnaligned(const vector<Object*>& objects);
+ public:
+ BVHUnaligned(const vector<Object *> &objects);
- /* Calculate alignment for the oriented node for a given range. */
- Transform compute_aligned_space(
- const BVHObjectBinning& range,
- const BVHReference *references) const;
- Transform compute_aligned_space(
- const BVHRange& range,
- const BVHReference *references) const;
+ /* Calculate alignment for the oriented node for a given range. */
+ Transform compute_aligned_space(const BVHObjectBinning &range,
+ const BVHReference *references) const;
+ Transform compute_aligned_space(const BVHRange &range, const BVHReference *references) const;
- /* Calculate alignment for the oriented node for a given reference.
- *
- * Return true when space was calculated successfully.
- */
- bool compute_aligned_space(const BVHReference& ref,
- Transform *aligned_space) const;
+ /* Calculate alignment for the oriented node for a given reference.
+ *
+ * Return true when space was calculated successfully.
+ */
+ bool compute_aligned_space(const BVHReference &ref, Transform *aligned_space) const;
- /* Calculate primitive's bounding box in given space. */
- BoundBox compute_aligned_prim_boundbox(
- const BVHReference& prim,
- const Transform& aligned_space) const;
+ /* Calculate primitive's bounding box in given space. */
+ BoundBox compute_aligned_prim_boundbox(const BVHReference &prim,
+ const Transform &aligned_space) const;
- /* Calculate bounding box in given space. */
- BoundBox compute_aligned_boundbox(
- const BVHObjectBinning& range,
- const BVHReference *references,
- const Transform& aligned_space,
- BoundBox *cent_bounds = NULL) const;
- BoundBox compute_aligned_boundbox(
- const BVHRange& range,
- const BVHReference *references,
- const Transform& aligned_space,
- BoundBox *cent_bounds = NULL) const;
+ /* Calculate bounding box in given space. */
+ BoundBox compute_aligned_boundbox(const BVHObjectBinning &range,
+ const BVHReference *references,
+ const Transform &aligned_space,
+ BoundBox *cent_bounds = NULL) const;
+ BoundBox compute_aligned_boundbox(const BVHRange &range,
+ const BVHReference *references,
+ const Transform &aligned_space,
+ BoundBox *cent_bounds = NULL) const;
- /* Calculate affine transform for node packing.
- * Bounds will be in the range of 0..1.
- */
- static Transform compute_node_transform(const BoundBox& bounds,
- const Transform& aligned_space);
-protected:
- /* List of objects BVH is being created for. */
- const vector<Object*>& objects_;
+ /* Calculate affine transform for node packing.
+ * Bounds will be in the range of 0..1.
+ */
+ static Transform compute_node_transform(const BoundBox &bounds, const Transform &aligned_space);
+
+ protected:
+ /* List of objects BVH is being created for. */
+ const vector<Object *> &objects_;
};
CCL_NAMESPACE_END
-#endif /* __BVH_UNALIGNED_H__ */
+#endif /* __BVH_UNALIGNED_H__ */
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index d0f473a2939..5bf681792ca 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -2,24 +2,24 @@
# Precompiled libraries tips and hints, for find_package().
if(CYCLES_STANDALONE_REPOSITORY)
- if(APPLE OR WIN32)
- include(precompiled_libs)
- endif()
+ if(APPLE OR WIN32)
+ include(precompiled_libs)
+ endif()
endif()
###########################################################################
# GLUT
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
- set(GLUT_ROOT_PATH ${CYCLES_GLUT})
+ set(GLUT_ROOT_PATH ${CYCLES_GLUT})
- find_package(GLUT)
- message(STATUS "GLUT_FOUND=${GLUT_FOUND}")
+ find_package(GLUT)
+ message(STATUS "GLUT_FOUND=${GLUT_FOUND}")
- include_directories(
- SYSTEM
- ${GLUT_INCLUDE_DIR}
- )
+ include_directories(
+ SYSTEM
+ ${GLUT_INCLUDE_DIR}
+ )
endif()
###########################################################################
@@ -27,125 +27,125 @@ endif()
# Workaround for unconventional variable name use in Blender.
if(NOT CYCLES_STANDALONE_REPOSITORY)
- set(GLEW_INCLUDE_DIR "${GLEW_INCLUDE_PATH}")
+ set(GLEW_INCLUDE_DIR "${GLEW_INCLUDE_PATH}")
endif()
if(WITH_CYCLES_STANDALONE)
- set(CYCLES_APP_GLEW_LIBRARY ${BLENDER_GLEW_LIBRARIES})
+ set(CYCLES_APP_GLEW_LIBRARY ${BLENDER_GLEW_LIBRARIES})
endif()
###########################################################################
# CUDA
if(WITH_CYCLES_CUDA_BINARIES OR NOT WITH_CUDA_DYNLOAD)
- find_package(CUDA) # Try to auto locate CUDA toolkit
- if(CUDA_FOUND)
- message(STATUS "CUDA nvcc = ${CUDA_NVCC_EXECUTABLE}")
- else()
- message(STATUS "CUDA compiler not found, disabling WITH_CYCLES_CUDA_BINARIES")
- set(WITH_CYCLES_CUDA_BINARIES OFF)
- if(NOT WITH_CUDA_DYNLOAD)
- message(STATUS "Additionally falling back to dynamic CUDA load")
- set(WITH_CUDA_DYNLOAD ON)
- endif()
- endif()
+ find_package(CUDA) # Try to auto locate CUDA toolkit
+ if(CUDA_FOUND)
+ message(STATUS "CUDA nvcc = ${CUDA_NVCC_EXECUTABLE}")
+ else()
+ message(STATUS "CUDA compiler not found, disabling WITH_CYCLES_CUDA_BINARIES")
+ set(WITH_CYCLES_CUDA_BINARIES OFF)
+ if(NOT WITH_CUDA_DYNLOAD)
+ message(STATUS "Additionally falling back to dynamic CUDA load")
+ set(WITH_CUDA_DYNLOAD ON)
+ endif()
+ endif()
endif()
# Packages which are being found by Blender when building from inside Blender
# source code. but which we need to take care of when building Cycles from a
# standalone repository
if(CYCLES_STANDALONE_REPOSITORY)
- # PThreads
- # TODO(sergey): Bloody exception, handled in precompiled_libs.cmake.
- if(NOT WIN32)
- set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
- find_package(Threads REQUIRED)
- set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
- endif()
-
- ####
- # OpenGL
-
- # TODO(sergey): We currently re-use the same variable name as we use
- # in Blender. Ideally we need to make it CYCLES_GL_LIBRARIES.
- find_package(OpenGL REQUIRED)
- find_package(GLEW REQUIRED)
- list(APPEND BLENDER_GL_LIBRARIES
- "${OPENGL_gl_LIBRARY}"
- "${OPENGL_glu_LIBRARY}"
- "${GLEW_LIBRARY}"
- )
-
- ####
- # OpenImageIO
- find_package(OpenImageIO REQUIRED)
- if(OPENIMAGEIO_PUGIXML_FOUND)
- set(PUGIXML_INCLUDE_DIR "${OPENIMAGEIO_INCLUDE_DIR/OpenImageIO}")
- set(PUGIXML_LIBRARIES "")
- else()
- find_package(PugiXML REQUIRED)
- endif()
-
- # OIIO usually depends on OpenEXR, so find this library
- # but don't make it required.
- find_package(OpenEXR)
-
- ####
- # OpenShadingLanguage
- if(WITH_CYCLES_OSL)
- find_package(OpenShadingLanguage REQUIRED)
- find_package(LLVM REQUIRED)
- endif()
-
- ####
- # OpenColorIO
- if(WITH_OPENCOLORIO)
- find_package(OpenColorIO REQUIRED)
- endif()
-
- ####
- # Boost
- set(__boost_packages filesystem regex system thread date_time)
- if(WITH_CYCLES_NETWORK)
- list(APPEND __boost_packages serialization)
- endif()
- if(WITH_CYCLES_OSL)
- # TODO(sergey): This is because of the way how our precompiled
- # libraries works, could be different for someone's else libs..
- if(APPLE OR MSVC)
- list(APPEND __boost_packages wave)
- elseif(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6"))
- list(APPEND __boost_packages wave)
- endif()
- endif()
- find_package(Boost 1.48 COMPONENTS ${__boost_packages} REQUIRED)
- if(NOT Boost_FOUND)
- # Try to find non-multithreaded if -mt not found, this flag
- # doesn't matter for us, it has nothing to do with thread
- # safety, but keep it to not disturb build setups.
- set(Boost_USE_MULTITHREADED OFF)
- find_package(Boost 1.48 COMPONENTS ${__boost_packages})
- endif()
- unset(__boost_packages)
- set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
- set(BOOST_LIBRARIES ${Boost_LIBRARIES})
- set(BOOST_LIBPATH ${Boost_LIBRARY_DIRS})
- set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
-
- ####
- # embree
- if(WITH_CYCLES_EMBREE)
- find_package(embree 3.2.4 REQUIRED)
- endif()
-
- ####
- # Logging
- if(WITH_CYCLES_LOGGING)
- find_package(Glog REQUIRED)
- find_package(Gflags REQUIRED)
- endif()
-
- unset(_lib_DIR)
+ # PThreads
+ # TODO(sergey): Bloody exception, handled in precompiled_libs.cmake.
+ if(NOT WIN32)
+ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+ find_package(Threads REQUIRED)
+ set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+ endif()
+
+ ####
+ # OpenGL
+
+ # TODO(sergey): We currently re-use the same variable name as we use
+ # in Blender. Ideally we need to make it CYCLES_GL_LIBRARIES.
+ find_package(OpenGL REQUIRED)
+ find_package(GLEW REQUIRED)
+ list(APPEND BLENDER_GL_LIBRARIES
+ "${OPENGL_gl_LIBRARY}"
+ "${OPENGL_glu_LIBRARY}"
+ "${GLEW_LIBRARY}"
+ )
+
+ ####
+ # OpenImageIO
+ find_package(OpenImageIO REQUIRED)
+ if(OPENIMAGEIO_PUGIXML_FOUND)
+ set(PUGIXML_INCLUDE_DIR "${OPENIMAGEIO_INCLUDE_DIR/OpenImageIO}")
+ set(PUGIXML_LIBRARIES "")
+ else()
+ find_package(PugiXML REQUIRED)
+ endif()
+
+ # OIIO usually depends on OpenEXR, so find this library
+ # but don't make it required.
+ find_package(OpenEXR)
+
+ ####
+ # OpenShadingLanguage
+ if(WITH_CYCLES_OSL)
+ find_package(OpenShadingLanguage REQUIRED)
+ find_package(LLVM REQUIRED)
+ endif()
+
+ ####
+ # OpenColorIO
+ if(WITH_OPENCOLORIO)
+ find_package(OpenColorIO REQUIRED)
+ endif()
+
+ ####
+ # Boost
+ set(__boost_packages filesystem regex system thread date_time)
+ if(WITH_CYCLES_NETWORK)
+ list(APPEND __boost_packages serialization)
+ endif()
+ if(WITH_CYCLES_OSL)
+ # TODO(sergey): This is because of the way how our precompiled
+ # libraries works, could be different for someone's else libs..
+ if(APPLE OR MSVC)
+ list(APPEND __boost_packages wave)
+ elseif(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6"))
+ list(APPEND __boost_packages wave)
+ endif()
+ endif()
+ find_package(Boost 1.48 COMPONENTS ${__boost_packages} REQUIRED)
+ if(NOT Boost_FOUND)
+ # Try to find non-multithreaded if -mt not found, this flag
+ # doesn't matter for us, it has nothing to do with thread
+ # safety, but keep it to not disturb build setups.
+ set(Boost_USE_MULTITHREADED OFF)
+ find_package(Boost 1.48 COMPONENTS ${__boost_packages})
+ endif()
+ unset(__boost_packages)
+ set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
+ set(BOOST_LIBRARIES ${Boost_LIBRARIES})
+ set(BOOST_LIBPATH ${Boost_LIBRARY_DIRS})
+ set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+
+ ####
+ # embree
+ if(WITH_CYCLES_EMBREE)
+ find_package(embree 3.2.4 REQUIRED)
+ endif()
+
+ ####
+ # Logging
+ if(WITH_CYCLES_LOGGING)
+ find_package(Glog REQUIRED)
+ find_package(Gflags REQUIRED)
+ endif()
+
+ unset(_lib_DIR)
else()
- set(LLVM_LIBRARIES ${LLVM_LIBRARY})
+ set(LLVM_LIBRARIES ${LLVM_LIBRARY})
endif()
diff --git a/intern/cycles/cmake/macros.cmake b/intern/cycles/cmake/macros.cmake
index ab8182ba4a7..0efd8bb7ea8 100644
--- a/intern/cycles/cmake/macros.cmake
+++ b/intern/cycles/cmake/macros.cmake
@@ -1,15 +1,15 @@
function(cycles_set_solution_folder target)
- if(WINDOWS_USE_VISUAL_STUDIO_FOLDERS)
- get_filename_component(folderdir ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
- string(REPLACE ${CMAKE_SOURCE_DIR} "" folderdir ${folderdir})
- set_target_properties(${target} PROPERTIES FOLDER ${folderdir})
- endif()
+ if(WINDOWS_USE_VISUAL_STUDIO_FOLDERS)
+ get_filename_component(folderdir ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
+ string(REPLACE ${CMAKE_SOURCE_DIR} "" folderdir ${folderdir})
+ set_target_properties(${target} PROPERTIES FOLDER ${folderdir})
+ endif()
endfunction()
macro(cycles_add_library target library_deps)
- add_library(${target} ${ARGN})
- if(NOT ("${library_deps}" STREQUAL ""))
- target_link_libraries(${target} "${library_deps}")
- endif()
- cycles_set_solution_folder(${target})
+ add_library(${target} ${ARGN})
+ if(NOT ("${library_deps}" STREQUAL ""))
+ target_link_libraries(${target} "${library_deps}")
+ endif()
+ cycles_set_solution_folder(${target})
endmacro()
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index d804a07bcab..75f4a72bee3 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -1,61 +1,61 @@
set(INC
- ..
- ../../glew-mx
+ ..
+ ../../glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_DIR}
- ../../../extern/clew/include
+ ${GLEW_INCLUDE_DIR}
+ ../../../extern/clew/include
)
if(WITH_CUDA_DYNLOAD)
- list(APPEND INC
- ../../../extern/cuew/include
- )
- add_definitions(-DWITH_CUDA_DYNLOAD)
+ list(APPEND INC
+ ../../../extern/cuew/include
+ )
+ add_definitions(-DWITH_CUDA_DYNLOAD)
else()
- list(APPEND INC_SYS
- ${CUDA_TOOLKIT_INCLUDE}
- )
- add_definitions(-DCYCLES_CUDA_NVCC_EXECUTABLE="${CUDA_NVCC_EXECUTABLE}")
+ list(APPEND INC_SYS
+ ${CUDA_TOOLKIT_INCLUDE}
+ )
+ add_definitions(-DCYCLES_CUDA_NVCC_EXECUTABLE="${CUDA_NVCC_EXECUTABLE}")
endif()
set(SRC
- device.cpp
- device_cpu.cpp
- device_cuda.cpp
- device_denoising.cpp
- device_memory.cpp
- device_multi.cpp
- device_opencl.cpp
- device_split_kernel.cpp
- device_task.cpp
+ device.cpp
+ device_cpu.cpp
+ device_cuda.cpp
+ device_denoising.cpp
+ device_memory.cpp
+ device_multi.cpp
+ device_opencl.cpp
+ device_split_kernel.cpp
+ device_task.cpp
)
set(SRC_OPENCL
- opencl/opencl.h
- opencl/memory_manager.h
+ opencl/opencl.h
+ opencl/memory_manager.h
- opencl/opencl_split.cpp
- opencl/opencl_util.cpp
- opencl/memory_manager.cpp
+ opencl/opencl_split.cpp
+ opencl/opencl_util.cpp
+ opencl/memory_manager.cpp
)
if(WITH_CYCLES_NETWORK)
- list(APPEND SRC
- device_network.cpp
- )
+ list(APPEND SRC
+ device_network.cpp
+ )
endif()
set(SRC_HEADERS
- device.h
- device_denoising.h
- device_memory.h
- device_intern.h
- device_network.h
- device_split_kernel.h
- device_task.h
+ device.h
+ device_denoising.h
+ device_memory.h
+ device_intern.h
+ device_network.h
+ device_split_kernel.h
+ device_task.h
)
set(LIB
@@ -63,27 +63,27 @@ set(LIB
)
if(WITH_CUDA_DYNLOAD)
- list(APPEND LIB
- extern_cuew
- )
+ list(APPEND LIB
+ extern_cuew
+ )
else()
- list(APPEND LIB
- ${CUDA_CUDA_LIBRARY}
- )
+ list(APPEND LIB
+ ${CUDA_CUDA_LIBRARY}
+ )
endif()
add_definitions(${GL_DEFINITIONS})
if(WITH_CYCLES_NETWORK)
- add_definitions(-DWITH_NETWORK)
+ add_definitions(-DWITH_NETWORK)
endif()
if(WITH_CYCLES_DEVICE_OPENCL)
- add_definitions(-DWITH_OPENCL)
+ add_definitions(-DWITH_OPENCL)
endif()
if(WITH_CYCLES_DEVICE_CUDA)
- add_definitions(-DWITH_CUDA)
+ add_definitions(-DWITH_CUDA)
endif()
if(WITH_CYCLES_DEVICE_MULTI)
- add_definitions(-DWITH_MULTI)
+ add_definitions(-DWITH_MULTI)
endif()
include_directories(${INC})
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index e74637472ef..16a68e8b855 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -44,572 +44,577 @@ uint Device::devices_initialized_mask = 0;
/* Device Requested Features */
-std::ostream& operator <<(std::ostream &os,
- const DeviceRequestedFeatures& requested_features)
+std::ostream &operator<<(std::ostream &os, const DeviceRequestedFeatures &requested_features)
{
- os << "Experimental features: "
- << (requested_features.experimental ? "On" : "Off") << std::endl;
- os << "Max nodes group: " << requested_features.max_nodes_group << std::endl;
- /* TODO(sergey): Decode bitflag into list of names. */
- os << "Nodes features: " << requested_features.nodes_features << std::endl;
- os << "Use Hair: "
- << string_from_bool(requested_features.use_hair) << std::endl;
- os << "Use Object Motion: "
- << string_from_bool(requested_features.use_object_motion) << std::endl;
- os << "Use Camera Motion: "
- << string_from_bool(requested_features.use_camera_motion) << std::endl;
- os << "Use Baking: "
- << string_from_bool(requested_features.use_baking) << std::endl;
- os << "Use Subsurface: "
- << string_from_bool(requested_features.use_subsurface) << std::endl;
- os << "Use Volume: "
- << string_from_bool(requested_features.use_volume) << std::endl;
- os << "Use Branched Integrator: "
- << string_from_bool(requested_features.use_integrator_branched) << std::endl;
- os << "Use Patch Evaluation: "
- << string_from_bool(requested_features.use_patch_evaluation) << std::endl;
- os << "Use Transparent Shadows: "
- << string_from_bool(requested_features.use_transparent) << std::endl;
- os << "Use Principled BSDF: "
- << string_from_bool(requested_features.use_principled) << std::endl;
- os << "Use Denoising: "
- << string_from_bool(requested_features.use_denoising) << std::endl;
- os << "Use Displacement: "
- << string_from_bool(requested_features.use_true_displacement) << std::endl;
- os << "Use Background Light: "
- << string_from_bool(requested_features.use_background_light) << std::endl;
- return os;
+ os << "Experimental features: " << (requested_features.experimental ? "On" : "Off") << std::endl;
+ os << "Max nodes group: " << requested_features.max_nodes_group << std::endl;
+ /* TODO(sergey): Decode bitflag into list of names. */
+ os << "Nodes features: " << requested_features.nodes_features << std::endl;
+ os << "Use Hair: " << string_from_bool(requested_features.use_hair) << std::endl;
+ os << "Use Object Motion: " << string_from_bool(requested_features.use_object_motion)
+ << std::endl;
+ os << "Use Camera Motion: " << string_from_bool(requested_features.use_camera_motion)
+ << std::endl;
+ os << "Use Baking: " << string_from_bool(requested_features.use_baking) << std::endl;
+ os << "Use Subsurface: " << string_from_bool(requested_features.use_subsurface) << std::endl;
+ os << "Use Volume: " << string_from_bool(requested_features.use_volume) << std::endl;
+ os << "Use Branched Integrator: " << string_from_bool(requested_features.use_integrator_branched)
+ << std::endl;
+ os << "Use Patch Evaluation: " << string_from_bool(requested_features.use_patch_evaluation)
+ << std::endl;
+ os << "Use Transparent Shadows: " << string_from_bool(requested_features.use_transparent)
+ << std::endl;
+ os << "Use Principled BSDF: " << string_from_bool(requested_features.use_principled)
+ << std::endl;
+ os << "Use Denoising: " << string_from_bool(requested_features.use_denoising) << std::endl;
+ os << "Use Displacement: " << string_from_bool(requested_features.use_true_displacement)
+ << std::endl;
+ os << "Use Background Light: " << string_from_bool(requested_features.use_background_light)
+ << std::endl;
+ return os;
}
/* Device */
Device::~Device()
{
- if(!background) {
- if(vertex_buffer != 0) {
- glDeleteBuffers(1, &vertex_buffer);
- }
- if(fallback_shader_program != 0) {
- glDeleteProgram(fallback_shader_program);
- }
- }
+ if (!background) {
+ if (vertex_buffer != 0) {
+ glDeleteBuffers(1, &vertex_buffer);
+ }
+ if (fallback_shader_program != 0) {
+ glDeleteProgram(fallback_shader_program);
+ }
+ }
}
/* TODO move shaders to standalone .glsl file. */
const char *FALLBACK_VERTEX_SHADER =
-"#version 330\n"
-"uniform vec2 fullscreen;\n"
-"in vec2 texCoord;\n"
-"in vec2 pos;\n"
-"out vec2 texCoord_interp;\n"
-"\n"
-"vec2 normalize_coordinates()\n"
-"{\n"
-" return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
-"}\n"
-"\n"
-"void main()\n"
-"{\n"
-" gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
-" texCoord_interp = texCoord;\n"
-"}\n\0";
+ "#version 330\n"
+ "uniform vec2 fullscreen;\n"
+ "in vec2 texCoord;\n"
+ "in vec2 pos;\n"
+ "out vec2 texCoord_interp;\n"
+ "\n"
+ "vec2 normalize_coordinates()\n"
+ "{\n"
+ " return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
+ "}\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
+ " texCoord_interp = texCoord;\n"
+ "}\n\0";
const char *FALLBACK_FRAGMENT_SHADER =
-"#version 330\n"
-"uniform sampler2D image_texture;\n"
-"in vec2 texCoord_interp;\n"
-"out vec4 fragColor;\n"
-"\n"
-"void main()\n"
-"{\n"
-" fragColor = texture(image_texture, texCoord_interp);\n"
-"}\n\0";
+ "#version 330\n"
+ "uniform sampler2D image_texture;\n"
+ "in vec2 texCoord_interp;\n"
+ "out vec4 fragColor;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = texture(image_texture, texCoord_interp);\n"
+ "}\n\0";
static void shader_print_errors(const char *task, const char *log, const char *code)
{
- LOG(ERROR) << "Shader: " << task << " error:";
- LOG(ERROR) << "===== shader string ====";
-
- stringstream stream(code);
- string partial;
-
- int line = 1;
- while(getline(stream, partial, '\n')) {
- if(line < 10) {
- LOG(ERROR) << " " << line << " " << partial;
- }
- else {
- LOG(ERROR) << line << " " << partial;
- }
- line++;
- }
- LOG(ERROR) << log;
+ LOG(ERROR) << "Shader: " << task << " error:";
+ LOG(ERROR) << "===== shader string ====";
+
+ stringstream stream(code);
+ string partial;
+
+ int line = 1;
+ while (getline(stream, partial, '\n')) {
+ if (line < 10) {
+ LOG(ERROR) << " " << line << " " << partial;
+ }
+ else {
+ LOG(ERROR) << line << " " << partial;
+ }
+ line++;
+ }
+ LOG(ERROR) << log;
}
static int bind_fallback_shader(void)
{
- GLint status;
- GLchar log[5000];
- GLsizei length = 0;
- GLuint program = 0;
+ GLint status;
+ GLchar log[5000];
+ GLsizei length = 0;
+ GLuint program = 0;
- struct Shader {
- const char *source;
- GLenum type;
- } shaders[2] = {
- {FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
- {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}
- };
+ struct Shader {
+ const char *source;
+ GLenum type;
+ } shaders[2] = {{FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
+ {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}};
- program = glCreateProgram();
+ program = glCreateProgram();
- for(int i = 0; i < 2; i++) {
- GLuint shader = glCreateShader(shaders[i].type);
+ for (int i = 0; i < 2; i++) {
+ GLuint shader = glCreateShader(shaders[i].type);
- string source_str = shaders[i].source;
- const char *c_str = source_str.c_str();
+ string source_str = shaders[i].source;
+ const char *c_str = source_str.c_str();
- glShaderSource(shader, 1, &c_str, NULL);
- glCompileShader(shader);
+ glShaderSource(shader, 1, &c_str, NULL);
+ glCompileShader(shader);
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if(!status) {
- glGetShaderInfoLog(shader, sizeof(log), &length, log);
- shader_print_errors("compile", log, c_str);
- return 0;
- }
+ if (!status) {
+ glGetShaderInfoLog(shader, sizeof(log), &length, log);
+ shader_print_errors("compile", log, c_str);
+ return 0;
+ }
- glAttachShader(program, shader);
- }
+ glAttachShader(program, shader);
+ }
- /* Link output. */
- glBindFragDataLocation(program, 0, "fragColor");
+ /* Link output. */
+ glBindFragDataLocation(program, 0, "fragColor");
- /* Link and error check. */
- glLinkProgram(program);
+ /* Link and error check. */
+ glLinkProgram(program);
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if(!status) {
- glGetShaderInfoLog(program, sizeof(log), &length, log);
- shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
- shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
- return 0;
- }
+ glGetProgramiv(program, GL_LINK_STATUS, &status);
+ if (!status) {
+ glGetShaderInfoLog(program, sizeof(log), &length, log);
+ shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
+ shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
+ return 0;
+ }
- return program;
+ return program;
}
bool Device::bind_fallback_display_space_shader(const float width, const float height)
{
- if(fallback_status == FALLBACK_SHADER_STATUS_ERROR) {
- return false;
- }
-
- if(fallback_status == FALLBACK_SHADER_STATUS_NONE) {
- fallback_shader_program = bind_fallback_shader();
- fallback_status = FALLBACK_SHADER_STATUS_ERROR;
-
- if(fallback_shader_program == 0) {
- return false;
- }
-
- glUseProgram(fallback_shader_program);
- image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture");
- if(image_texture_location < 0) {
- LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform.";
- return false;
- }
-
- fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen");
- if(fullscreen_location < 0) {
- LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform.";
- return false;
- }
-
- fallback_status = FALLBACK_SHADER_STATUS_SUCCESS;
- }
-
- /* Run this every time. */
- glUseProgram(fallback_shader_program);
- glUniform1i(image_texture_location, 0);
- glUniform2f(fullscreen_location, width, height);
- return true;
+ if (fallback_status == FALLBACK_SHADER_STATUS_ERROR) {
+ return false;
+ }
+
+ if (fallback_status == FALLBACK_SHADER_STATUS_NONE) {
+ fallback_shader_program = bind_fallback_shader();
+ fallback_status = FALLBACK_SHADER_STATUS_ERROR;
+
+ if (fallback_shader_program == 0) {
+ return false;
+ }
+
+ glUseProgram(fallback_shader_program);
+ image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture");
+ if (image_texture_location < 0) {
+ LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform.";
+ return false;
+ }
+
+ fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen");
+ if (fullscreen_location < 0) {
+ LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform.";
+ return false;
+ }
+
+ fallback_status = FALLBACK_SHADER_STATUS_SUCCESS;
+ }
+
+ /* Run this every time. */
+ glUseProgram(fallback_shader_program);
+ glUniform1i(image_texture_location, 0);
+ glUniform2f(fullscreen_location, width, height);
+ return true;
}
-void Device::draw_pixels(
- device_memory& rgba, int y,
- int w, int h, int width, int height,
- int dx, int dy, int dw, int dh,
- bool transparent, const DeviceDrawParams &draw_params)
+void Device::draw_pixels(device_memory &rgba,
+ int y,
+ int w,
+ int h,
+ int width,
+ int height,
+ int dx,
+ int dy,
+ int dw,
+ int dh,
+ bool transparent,
+ const DeviceDrawParams &draw_params)
{
- const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
-
- assert(rgba.type == MEM_PIXELS);
- mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1));
-
- GLuint texid;
- glActiveTexture(GL_TEXTURE0);
- glGenTextures(1, &texid);
- glBindTexture(GL_TEXTURE_2D, texid);
-
- if(rgba.data_type == TYPE_HALF) {
- GLhalf *data_pointer = (GLhalf*)rgba.host_pointer;
- data_pointer += 4 * y * w;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer);
- }
- else {
- uint8_t *data_pointer = (uint8_t*)rgba.host_pointer;
- data_pointer += 4 * y * w;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data_pointer);
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- if(transparent) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- GLint shader_program;
- if(use_fallback_shader) {
- if(!bind_fallback_display_space_shader(dw, dh)) {
- return;
- }
- shader_program = fallback_shader_program;
- }
- else {
- draw_params.bind_display_space_shader_cb();
- glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
- }
-
- if(!vertex_buffer) {
- glGenBuffers(1, &vertex_buffer);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
- /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
-
- float *vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
-
- if(vpointer) {
- /* texture coordinate - vertex pair */
- vpointer[0] = 0.0f;
- vpointer[1] = 0.0f;
- vpointer[2] = dx;
- vpointer[3] = dy;
-
- vpointer[4] = 1.0f;
- vpointer[5] = 0.0f;
- vpointer[6] = (float)width + dx;
- vpointer[7] = dy;
-
- vpointer[8] = 1.0f;
- vpointer[9] = 1.0f;
- vpointer[10] = (float)width + dx;
- vpointer[11] = (float)height + dy;
-
- vpointer[12] = 0.0f;
- vpointer[13] = 1.0f;
- vpointer[14] = dx;
- vpointer[15] = (float)height + dy;
-
- if(vertex_buffer) {
- glUnmapBuffer(GL_ARRAY_BUFFER);
- }
- }
-
- GLuint vertex_array_object;
- GLuint position_attribute, texcoord_attribute;
-
- glGenVertexArrays(1, &vertex_array_object);
- glBindVertexArray(vertex_array_object);
-
- texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
- position_attribute = glGetAttribLocation(shader_program, "pos");
-
- glEnableVertexAttribArray(texcoord_attribute);
- glEnableVertexAttribArray(position_attribute);
-
- glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
- glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- if(vertex_buffer) {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- if(use_fallback_shader) {
- glUseProgram(0);
- }
- else {
- draw_params.unbind_display_space_shader_cb();
- }
-
- glDeleteVertexArrays(1, &vertex_array_object);
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &texid);
-
- if(transparent) {
- glDisable(GL_BLEND);
- }
+ const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
+
+ assert(rgba.type == MEM_PIXELS);
+ mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1));
+
+ GLuint texid;
+ glActiveTexture(GL_TEXTURE0);
+ glGenTextures(1, &texid);
+ glBindTexture(GL_TEXTURE_2D, texid);
+
+ if (rgba.data_type == TYPE_HALF) {
+ GLhalf *data_pointer = (GLhalf *)rgba.host_pointer;
+ data_pointer += 4 * y * w;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer);
+ }
+ else {
+ uint8_t *data_pointer = (uint8_t *)rgba.host_pointer;
+ data_pointer += 4 * y * w;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data_pointer);
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ if (transparent) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ GLint shader_program;
+ if (use_fallback_shader) {
+ if (!bind_fallback_display_space_shader(dw, dh)) {
+ return;
+ }
+ shader_program = fallback_shader_program;
+ }
+ else {
+ draw_params.bind_display_space_shader_cb();
+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
+ }
+
+ if (!vertex_buffer) {
+ glGenBuffers(1, &vertex_buffer);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+ /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
+ glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+ float *vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+ if (vpointer) {
+ /* texture coordinate - vertex pair */
+ vpointer[0] = 0.0f;
+ vpointer[1] = 0.0f;
+ vpointer[2] = dx;
+ vpointer[3] = dy;
+
+ vpointer[4] = 1.0f;
+ vpointer[5] = 0.0f;
+ vpointer[6] = (float)width + dx;
+ vpointer[7] = dy;
+
+ vpointer[8] = 1.0f;
+ vpointer[9] = 1.0f;
+ vpointer[10] = (float)width + dx;
+ vpointer[11] = (float)height + dy;
+
+ vpointer[12] = 0.0f;
+ vpointer[13] = 1.0f;
+ vpointer[14] = dx;
+ vpointer[15] = (float)height + dy;
+
+ if (vertex_buffer) {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ }
+ }
+
+ GLuint vertex_array_object;
+ GLuint position_attribute, texcoord_attribute;
+
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
+
+ texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+ position_attribute = glGetAttribLocation(shader_program, "pos");
+
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
+
+ glVertexAttribPointer(
+ texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute,
+ 2,
+ GL_FLOAT,
+ GL_FALSE,
+ 4 * sizeof(float),
+ (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if (vertex_buffer) {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+
+ if (use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
+ glDeleteVertexArrays(1, &vertex_array_object);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &texid);
+
+ if (transparent) {
+ glDisable(GL_BLEND);
+ }
}
-Device *Device::create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background)
+Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background)
{
- Device *device;
+ Device *device;
- switch(info.type) {
- case DEVICE_CPU:
- device = device_cpu_create(info, stats, profiler, background);
- break;
+ switch (info.type) {
+ case DEVICE_CPU:
+ device = device_cpu_create(info, stats, profiler, background);
+ break;
#ifdef WITH_CUDA
- case DEVICE_CUDA:
- if(device_cuda_init())
- device = device_cuda_create(info, stats, profiler, background);
- else
- device = NULL;
- break;
+ case DEVICE_CUDA:
+ if (device_cuda_init())
+ device = device_cuda_create(info, stats, profiler, background);
+ else
+ device = NULL;
+ break;
#endif
#ifdef WITH_MULTI
- case DEVICE_MULTI:
- device = device_multi_create(info, stats, profiler, background);
- break;
+ case DEVICE_MULTI:
+ device = device_multi_create(info, stats, profiler, background);
+ break;
#endif
#ifdef WITH_NETWORK
- case DEVICE_NETWORK:
- device = device_network_create(info, stats, profiler, "127.0.0.1");
- break;
+ case DEVICE_NETWORK:
+ device = device_network_create(info, stats, profiler, "127.0.0.1");
+ break;
#endif
#ifdef WITH_OPENCL
- case DEVICE_OPENCL:
- if(device_opencl_init())
- device = device_opencl_create(info, stats, profiler, background);
- else
- device = NULL;
- break;
+ case DEVICE_OPENCL:
+ if (device_opencl_init())
+ device = device_opencl_create(info, stats, profiler, background);
+ else
+ device = NULL;
+ break;
#endif
- default:
- return NULL;
- }
+ default:
+ return NULL;
+ }
- return device;
+ return device;
}
DeviceType Device::type_from_string(const char *name)
{
- if(strcmp(name, "CPU") == 0)
- return DEVICE_CPU;
- else if(strcmp(name, "CUDA") == 0)
- return DEVICE_CUDA;
- else if(strcmp(name, "OPENCL") == 0)
- return DEVICE_OPENCL;
- else if(strcmp(name, "NETWORK") == 0)
- return DEVICE_NETWORK;
- else if(strcmp(name, "MULTI") == 0)
- return DEVICE_MULTI;
-
- return DEVICE_NONE;
+ if (strcmp(name, "CPU") == 0)
+ return DEVICE_CPU;
+ else if (strcmp(name, "CUDA") == 0)
+ return DEVICE_CUDA;
+ else if (strcmp(name, "OPENCL") == 0)
+ return DEVICE_OPENCL;
+ else if (strcmp(name, "NETWORK") == 0)
+ return DEVICE_NETWORK;
+ else if (strcmp(name, "MULTI") == 0)
+ return DEVICE_MULTI;
+
+ return DEVICE_NONE;
}
string Device::string_from_type(DeviceType type)
{
- if(type == DEVICE_CPU)
- return "CPU";
- else if(type == DEVICE_CUDA)
- return "CUDA";
- else if(type == DEVICE_OPENCL)
- return "OPENCL";
- else if(type == DEVICE_NETWORK)
- return "NETWORK";
- else if(type == DEVICE_MULTI)
- return "MULTI";
-
- return "";
+ if (type == DEVICE_CPU)
+ return "CPU";
+ else if (type == DEVICE_CUDA)
+ return "CUDA";
+ else if (type == DEVICE_OPENCL)
+ return "OPENCL";
+ else if (type == DEVICE_NETWORK)
+ return "NETWORK";
+ else if (type == DEVICE_MULTI)
+ return "MULTI";
+
+ return "";
}
vector<DeviceType> Device::available_types()
{
- vector<DeviceType> types;
- types.push_back(DEVICE_CPU);
+ vector<DeviceType> types;
+ types.push_back(DEVICE_CPU);
#ifdef WITH_CUDA
- types.push_back(DEVICE_CUDA);
+ types.push_back(DEVICE_CUDA);
#endif
#ifdef WITH_OPENCL
- types.push_back(DEVICE_OPENCL);
+ types.push_back(DEVICE_OPENCL);
#endif
#ifdef WITH_NETWORK
- types.push_back(DEVICE_NETWORK);
+ types.push_back(DEVICE_NETWORK);
#endif
- return types;
+ return types;
}
vector<DeviceInfo> Device::available_devices(uint mask)
{
- /* Lazy initialize devices. On some platforms OpenCL or CUDA drivers can
- * be broken and cause crashes when only trying to get device info, so
- * we don't want to do any initialization until the user chooses to. */
- thread_scoped_lock lock(device_mutex);
- vector<DeviceInfo> devices;
+ /* Lazy initialize devices. On some platforms OpenCL or CUDA drivers can
+ * be broken and cause crashes when only trying to get device info, so
+ * we don't want to do any initialization until the user chooses to. */
+ thread_scoped_lock lock(device_mutex);
+ vector<DeviceInfo> devices;
#ifdef WITH_OPENCL
- if(mask & DEVICE_MASK_OPENCL) {
- if(!(devices_initialized_mask & DEVICE_MASK_OPENCL)) {
- if(device_opencl_init()) {
- device_opencl_info(opencl_devices);
- }
- devices_initialized_mask |= DEVICE_MASK_OPENCL;
- }
- foreach(DeviceInfo& info, opencl_devices) {
- devices.push_back(info);
- }
- }
+ if (mask & DEVICE_MASK_OPENCL) {
+ if (!(devices_initialized_mask & DEVICE_MASK_OPENCL)) {
+ if (device_opencl_init()) {
+ device_opencl_info(opencl_devices);
+ }
+ devices_initialized_mask |= DEVICE_MASK_OPENCL;
+ }
+ foreach (DeviceInfo &info, opencl_devices) {
+ devices.push_back(info);
+ }
+ }
#endif
#ifdef WITH_CUDA
- if(mask & DEVICE_MASK_CUDA) {
- if(!(devices_initialized_mask & DEVICE_MASK_CUDA)) {
- if(device_cuda_init()) {
- device_cuda_info(cuda_devices);
- }
- devices_initialized_mask |= DEVICE_MASK_CUDA;
- }
- foreach(DeviceInfo& info, cuda_devices) {
- devices.push_back(info);
- }
- }
+ if (mask & DEVICE_MASK_CUDA) {
+ if (!(devices_initialized_mask & DEVICE_MASK_CUDA)) {
+ if (device_cuda_init()) {
+ device_cuda_info(cuda_devices);
+ }
+ devices_initialized_mask |= DEVICE_MASK_CUDA;
+ }
+ foreach (DeviceInfo &info, cuda_devices) {
+ devices.push_back(info);
+ }
+ }
#endif
- if(mask & DEVICE_MASK_CPU) {
- if(!(devices_initialized_mask & DEVICE_MASK_CPU)) {
- device_cpu_info(cpu_devices);
- devices_initialized_mask |= DEVICE_MASK_CPU;
- }
- foreach(DeviceInfo& info, cpu_devices) {
- devices.push_back(info);
- }
- }
+ if (mask & DEVICE_MASK_CPU) {
+ if (!(devices_initialized_mask & DEVICE_MASK_CPU)) {
+ device_cpu_info(cpu_devices);
+ devices_initialized_mask |= DEVICE_MASK_CPU;
+ }
+ foreach (DeviceInfo &info, cpu_devices) {
+ devices.push_back(info);
+ }
+ }
#ifdef WITH_NETWORK
- if(mask & DEVICE_MASK_NETWORK) {
- if(!(devices_initialized_mask & DEVICE_MASK_NETWORK)) {
- device_network_info(network_devices);
- devices_initialized_mask |= DEVICE_MASK_NETWORK;
- }
- foreach(DeviceInfo& info, network_devices) {
- devices.push_back(info);
- }
- }
+ if (mask & DEVICE_MASK_NETWORK) {
+ if (!(devices_initialized_mask & DEVICE_MASK_NETWORK)) {
+ device_network_info(network_devices);
+ devices_initialized_mask |= DEVICE_MASK_NETWORK;
+ }
+ foreach (DeviceInfo &info, network_devices) {
+ devices.push_back(info);
+ }
+ }
#endif
- return devices;
+ return devices;
}
string Device::device_capabilities(uint mask)
{
- thread_scoped_lock lock(device_mutex);
- string capabilities = "";
+ thread_scoped_lock lock(device_mutex);
+ string capabilities = "";
- if(mask & DEVICE_MASK_CPU) {
- capabilities += "\nCPU device capabilities: ";
- capabilities += device_cpu_capabilities() + "\n";
- }
+ if (mask & DEVICE_MASK_CPU) {
+ capabilities += "\nCPU device capabilities: ";
+ capabilities += device_cpu_capabilities() + "\n";
+ }
#ifdef WITH_OPENCL
- if(mask & DEVICE_MASK_OPENCL) {
- if(device_opencl_init()) {
- capabilities += "\nOpenCL device capabilities:\n";
- capabilities += device_opencl_capabilities();
- }
- }
+ if (mask & DEVICE_MASK_OPENCL) {
+ if (device_opencl_init()) {
+ capabilities += "\nOpenCL device capabilities:\n";
+ capabilities += device_opencl_capabilities();
+ }
+ }
#endif
#ifdef WITH_CUDA
- if(mask & DEVICE_MASK_CUDA) {
- if(device_cuda_init()) {
- capabilities += "\nCUDA device capabilities:\n";
- capabilities += device_cuda_capabilities();
- }
- }
+ if (mask & DEVICE_MASK_CUDA) {
+ if (device_cuda_init()) {
+ capabilities += "\nCUDA device capabilities:\n";
+ capabilities += device_cuda_capabilities();
+ }
+ }
#endif
- return capabilities;
+ return capabilities;
}
-DeviceInfo Device::get_multi_device(const vector<DeviceInfo>& subdevices, int threads, bool background)
+DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
+ int threads,
+ bool background)
{
- assert(subdevices.size() > 0);
-
- if(subdevices.size() == 1) {
- /* No multi device needed. */
- return subdevices.front();
- }
-
- DeviceInfo info;
- info.type = DEVICE_MULTI;
- info.id = "MULTI";
- info.description = "Multi Device";
- info.num = 0;
-
- info.has_half_images = true;
- info.has_volume_decoupled = true;
- info.has_osl = true;
- info.has_profiling = true;
-
- foreach(const DeviceInfo &device, subdevices) {
- /* Ensure CPU device does not slow down GPU. */
- if(device.type == DEVICE_CPU && subdevices.size() > 1) {
- if(background) {
- int orig_cpu_threads = (threads)? threads: system_cpu_thread_count();
- int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0);
-
- VLOG(1) << "CPU render threads reduced from "
- << orig_cpu_threads << " to " << cpu_threads
- << ", to dedicate to GPU.";
-
- if(cpu_threads >= 1) {
- DeviceInfo cpu_device = device;
- cpu_device.cpu_threads = cpu_threads;
- info.multi_devices.push_back(cpu_device);
- }
- else {
- continue;
- }
- }
- else {
- VLOG(1) << "CPU render threads disabled for interactive render.";
- continue;
- }
- }
- else {
- info.multi_devices.push_back(device);
- }
-
- /* Accumulate device info. */
- info.has_half_images &= device.has_half_images;
- info.has_volume_decoupled &= device.has_volume_decoupled;
- info.has_osl &= device.has_osl;
- info.has_profiling &= device.has_profiling;
- }
-
- return info;
+ assert(subdevices.size() > 0);
+
+ if (subdevices.size() == 1) {
+ /* No multi device needed. */
+ return subdevices.front();
+ }
+
+ DeviceInfo info;
+ info.type = DEVICE_MULTI;
+ info.id = "MULTI";
+ info.description = "Multi Device";
+ info.num = 0;
+
+ info.has_half_images = true;
+ info.has_volume_decoupled = true;
+ info.has_osl = true;
+ info.has_profiling = true;
+
+ foreach (const DeviceInfo &device, subdevices) {
+ /* Ensure CPU device does not slow down GPU. */
+ if (device.type == DEVICE_CPU && subdevices.size() > 1) {
+ if (background) {
+ int orig_cpu_threads = (threads) ? threads : system_cpu_thread_count();
+ int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0);
+
+ VLOG(1) << "CPU render threads reduced from " << orig_cpu_threads << " to " << cpu_threads
+ << ", to dedicate to GPU.";
+
+ if (cpu_threads >= 1) {
+ DeviceInfo cpu_device = device;
+ cpu_device.cpu_threads = cpu_threads;
+ info.multi_devices.push_back(cpu_device);
+ }
+ else {
+ continue;
+ }
+ }
+ else {
+ VLOG(1) << "CPU render threads disabled for interactive render.";
+ continue;
+ }
+ }
+ else {
+ info.multi_devices.push_back(device);
+ }
+
+ /* Accumulate device info. */
+ info.has_half_images &= device.has_half_images;
+ info.has_volume_decoupled &= device.has_volume_decoupled;
+ info.has_osl &= device.has_osl;
+ info.has_profiling &= device.has_profiling;
+ }
+
+ return info;
}
void Device::tag_update()
{
- free_memory();
+ free_memory();
}
void Device::free_memory()
{
- devices_initialized_mask = 0;
- cuda_devices.free_memory();
- opencl_devices.free_memory();
- cpu_devices.free_memory();
- network_devices.free_memory();
+ devices_initialized_mask = 0;
+ cuda_devices.free_memory();
+ opencl_devices.free_memory();
+ cpu_devices.free_memory();
+ network_devices.free_memory();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index aa0a8e434d2..15a0ceb4a19 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -40,384 +40,428 @@ class RenderTile;
/* Device Types */
enum DeviceType {
- DEVICE_NONE = 0,
- DEVICE_CPU,
- DEVICE_OPENCL,
- DEVICE_CUDA,
- DEVICE_NETWORK,
- DEVICE_MULTI
+ DEVICE_NONE = 0,
+ DEVICE_CPU,
+ DEVICE_OPENCL,
+ DEVICE_CUDA,
+ DEVICE_NETWORK,
+ DEVICE_MULTI
};
enum DeviceTypeMask {
- DEVICE_MASK_CPU = (1 << DEVICE_CPU),
- DEVICE_MASK_OPENCL = (1 << DEVICE_OPENCL),
- DEVICE_MASK_CUDA = (1 << DEVICE_CUDA),
- DEVICE_MASK_NETWORK = (1 << DEVICE_NETWORK),
- DEVICE_MASK_ALL = ~0
+ DEVICE_MASK_CPU = (1 << DEVICE_CPU),
+ DEVICE_MASK_OPENCL = (1 << DEVICE_OPENCL),
+ DEVICE_MASK_CUDA = (1 << DEVICE_CUDA),
+ DEVICE_MASK_NETWORK = (1 << DEVICE_NETWORK),
+ DEVICE_MASK_ALL = ~0
};
enum DeviceKernelStatus {
- DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL = 0,
- DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE,
- DEVICE_KERNEL_USING_FEATURE_KERNEL,
- DEVICE_KERNEL_FEATURE_KERNEL_INVALID,
- DEVICE_KERNEL_UNKNOWN,
+ DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL = 0,
+ DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE,
+ DEVICE_KERNEL_USING_FEATURE_KERNEL,
+ DEVICE_KERNEL_FEATURE_KERNEL_INVALID,
+ DEVICE_KERNEL_UNKNOWN,
};
#define DEVICE_MASK(type) (DeviceTypeMask)(1 << type)
class DeviceInfo {
-public:
- DeviceType type;
- string description;
- string id; /* used for user preferences, should stay fixed with changing hardware config */
- int num;
- bool display_device; /* GPU is used as a display device. */
- bool has_half_images; /* Support half-float textures. */
- bool has_volume_decoupled; /* Decoupled volume shading. */
- bool has_osl; /* Support Open Shading Language. */
- bool use_split_kernel; /* Use split or mega kernel. */
- bool has_profiling; /* Supports runtime collection of profiling info. */
- int cpu_threads;
- vector<DeviceInfo> multi_devices;
-
- DeviceInfo()
- {
- type = DEVICE_CPU;
- id = "CPU";
- num = 0;
- cpu_threads = 0;
- display_device = false;
- has_half_images = false;
- has_volume_decoupled = false;
- has_osl = false;
- use_split_kernel = false;
- has_profiling = false;
- }
-
- bool operator==(const DeviceInfo &info) {
- /* Multiple Devices with the same ID would be very bad. */
- assert(id != info.id || (type == info.type && num == info.num && description == info.description));
- return id == info.id;
- }
+ public:
+ DeviceType type;
+ string description;
+ string id; /* used for user preferences, should stay fixed with changing hardware config */
+ int num;
+ bool display_device; /* GPU is used as a display device. */
+ bool has_half_images; /* Support half-float textures. */
+ bool has_volume_decoupled; /* Decoupled volume shading. */
+ bool has_osl; /* Support Open Shading Language. */
+ bool use_split_kernel; /* Use split or mega kernel. */
+ bool has_profiling; /* Supports runtime collection of profiling info. */
+ int cpu_threads;
+ vector<DeviceInfo> multi_devices;
+
+ DeviceInfo()
+ {
+ type = DEVICE_CPU;
+ id = "CPU";
+ num = 0;
+ cpu_threads = 0;
+ display_device = false;
+ has_half_images = false;
+ has_volume_decoupled = false;
+ has_osl = false;
+ use_split_kernel = false;
+ has_profiling = false;
+ }
+
+ bool operator==(const DeviceInfo &info)
+ {
+ /* Multiple Devices with the same ID would be very bad. */
+ assert(id != info.id ||
+ (type == info.type && num == info.num && description == info.description));
+ return id == info.id;
+ }
};
class DeviceRequestedFeatures {
-public:
- /* Use experimental feature set. */
- bool experimental;
-
- /* Selective nodes compilation. */
-
- /* Identifier of a node group up to which all the nodes needs to be
- * compiled in. Nodes from higher group indices will be ignores.
- */
- int max_nodes_group;
-
- /* Features bitfield indicating which features from the requested group
- * will be compiled in. Nodes which corresponds to features which are not
- * in this bitfield will be ignored even if they're in the requested group.
- */
- int nodes_features;
-
- /* BVH/sampling kernel features. */
- bool use_hair;
- bool use_object_motion;
- bool use_camera_motion;
-
- /* Denotes whether baking functionality is needed. */
- bool use_baking;
-
- /* Use subsurface scattering materials. */
- bool use_subsurface;
-
- /* Use volume materials. */
- bool use_volume;
-
- /* Use branched integrator. */
- bool use_integrator_branched;
-
- /* Use OpenSubdiv patch evaluation */
- bool use_patch_evaluation;
-
- /* Use Transparent shadows */
- bool use_transparent;
-
- /* Use various shadow tricks, such as shadow catcher. */
- bool use_shadow_tricks;
-
- /* Per-uber shader usage flags. */
- bool use_principled;
-
- /* Denoising features. */
- bool use_denoising;
-
- /* Use raytracing in shaders. */
- bool use_shader_raytrace;
-
- /* Use true displacement */
- bool use_true_displacement;
-
- /* Use background lights */
- bool use_background_light;
-
- DeviceRequestedFeatures()
- {
- /* TODO(sergey): Find more meaningful defaults. */
- experimental = false;
- max_nodes_group = 0;
- nodes_features = 0;
- use_hair = false;
- use_object_motion = false;
- use_camera_motion = false;
- use_baking = false;
- use_subsurface = false;
- use_volume = false;
- use_integrator_branched = false;
- use_patch_evaluation = false;
- use_transparent = false;
- use_shadow_tricks = false;
- use_principled = false;
- use_denoising = false;
- use_shader_raytrace = false;
- use_true_displacement = false;
- use_background_light = false;
- }
-
- bool modified(const DeviceRequestedFeatures& requested_features)
- {
- return !(experimental == requested_features.experimental &&
- max_nodes_group == requested_features.max_nodes_group &&
- nodes_features == requested_features.nodes_features &&
- use_hair == requested_features.use_hair &&
- use_object_motion == requested_features.use_object_motion &&
- use_camera_motion == requested_features.use_camera_motion &&
- use_baking == requested_features.use_baking &&
- use_subsurface == requested_features.use_subsurface &&
- use_volume == requested_features.use_volume &&
- use_integrator_branched == requested_features.use_integrator_branched &&
- use_patch_evaluation == requested_features.use_patch_evaluation &&
- use_transparent == requested_features.use_transparent &&
- use_shadow_tricks == requested_features.use_shadow_tricks &&
- use_principled == requested_features.use_principled &&
- use_denoising == requested_features.use_denoising &&
- use_shader_raytrace == requested_features.use_shader_raytrace &&
- use_true_displacement == requested_features.use_true_displacement &&
- use_background_light == requested_features.use_background_light);
- }
-
- /* Convert the requested features structure to a build options,
- * which could then be passed to compilers.
- */
- string get_build_options() const
- {
- string build_options = "";
- if(experimental) {
- build_options += "-D__KERNEL_EXPERIMENTAL__ ";
- }
- build_options += "-D__NODES_MAX_GROUP__=" +
- string_printf("%d", max_nodes_group);
- build_options += " -D__NODES_FEATURES__=" +
- string_printf("%d", nodes_features);
- if(!use_hair) {
- build_options += " -D__NO_HAIR__";
- }
- if(!use_object_motion) {
- build_options += " -D__NO_OBJECT_MOTION__";
- }
- if(!use_camera_motion) {
- build_options += " -D__NO_CAMERA_MOTION__";
- }
- if(!use_baking) {
- build_options += " -D__NO_BAKING__";
- }
- if(!use_volume) {
- build_options += " -D__NO_VOLUME__";
- }
- if(!use_subsurface) {
- build_options += " -D__NO_SUBSURFACE__";
- }
- if(!use_integrator_branched) {
- build_options += " -D__NO_BRANCHED_PATH__";
- }
- if(!use_patch_evaluation) {
- build_options += " -D__NO_PATCH_EVAL__";
- }
- if(!use_transparent && !use_volume) {
- build_options += " -D__NO_TRANSPARENT__";
- }
- if(!use_shadow_tricks) {
- build_options += " -D__NO_SHADOW_TRICKS__";
- }
- if(!use_principled) {
- build_options += " -D__NO_PRINCIPLED__";
- }
- if(!use_denoising) {
- build_options += " -D__NO_DENOISING__";
- }
- if(!use_shader_raytrace) {
- build_options += " -D__NO_SHADER_RAYTRACE__";
- }
- return build_options;
- }
+ public:
+ /* Use experimental feature set. */
+ bool experimental;
+
+ /* Selective nodes compilation. */
+
+ /* Identifier of a node group up to which all the nodes needs to be
+ * compiled in. Nodes from higher group indices will be ignores.
+ */
+ int max_nodes_group;
+
+ /* Features bitfield indicating which features from the requested group
+ * will be compiled in. Nodes which corresponds to features which are not
+ * in this bitfield will be ignored even if they're in the requested group.
+ */
+ int nodes_features;
+
+ /* BVH/sampling kernel features. */
+ bool use_hair;
+ bool use_object_motion;
+ bool use_camera_motion;
+
+ /* Denotes whether baking functionality is needed. */
+ bool use_baking;
+
+ /* Use subsurface scattering materials. */
+ bool use_subsurface;
+
+ /* Use volume materials. */
+ bool use_volume;
+
+ /* Use branched integrator. */
+ bool use_integrator_branched;
+
+ /* Use OpenSubdiv patch evaluation */
+ bool use_patch_evaluation;
+
+ /* Use Transparent shadows */
+ bool use_transparent;
+
+ /* Use various shadow tricks, such as shadow catcher. */
+ bool use_shadow_tricks;
+
+ /* Per-uber shader usage flags. */
+ bool use_principled;
+
+ /* Denoising features. */
+ bool use_denoising;
+
+ /* Use raytracing in shaders. */
+ bool use_shader_raytrace;
+
+ /* Use true displacement */
+ bool use_true_displacement;
+
+ /* Use background lights */
+ bool use_background_light;
+
+ DeviceRequestedFeatures()
+ {
+ /* TODO(sergey): Find more meaningful defaults. */
+ experimental = false;
+ max_nodes_group = 0;
+ nodes_features = 0;
+ use_hair = false;
+ use_object_motion = false;
+ use_camera_motion = false;
+ use_baking = false;
+ use_subsurface = false;
+ use_volume = false;
+ use_integrator_branched = false;
+ use_patch_evaluation = false;
+ use_transparent = false;
+ use_shadow_tricks = false;
+ use_principled = false;
+ use_denoising = false;
+ use_shader_raytrace = false;
+ use_true_displacement = false;
+ use_background_light = false;
+ }
+
+ bool modified(const DeviceRequestedFeatures &requested_features)
+ {
+ return !(experimental == requested_features.experimental &&
+ max_nodes_group == requested_features.max_nodes_group &&
+ nodes_features == requested_features.nodes_features &&
+ use_hair == requested_features.use_hair &&
+ use_object_motion == requested_features.use_object_motion &&
+ use_camera_motion == requested_features.use_camera_motion &&
+ use_baking == requested_features.use_baking &&
+ use_subsurface == requested_features.use_subsurface &&
+ use_volume == requested_features.use_volume &&
+ use_integrator_branched == requested_features.use_integrator_branched &&
+ use_patch_evaluation == requested_features.use_patch_evaluation &&
+ use_transparent == requested_features.use_transparent &&
+ use_shadow_tricks == requested_features.use_shadow_tricks &&
+ use_principled == requested_features.use_principled &&
+ use_denoising == requested_features.use_denoising &&
+ use_shader_raytrace == requested_features.use_shader_raytrace &&
+ use_true_displacement == requested_features.use_true_displacement &&
+ use_background_light == requested_features.use_background_light);
+ }
+
+ /* Convert the requested features structure to a build options,
+ * which could then be passed to compilers.
+ */
+ string get_build_options() const
+ {
+ string build_options = "";
+ if (experimental) {
+ build_options += "-D__KERNEL_EXPERIMENTAL__ ";
+ }
+ build_options += "-D__NODES_MAX_GROUP__=" + string_printf("%d", max_nodes_group);
+ build_options += " -D__NODES_FEATURES__=" + string_printf("%d", nodes_features);
+ if (!use_hair) {
+ build_options += " -D__NO_HAIR__";
+ }
+ if (!use_object_motion) {
+ build_options += " -D__NO_OBJECT_MOTION__";
+ }
+ if (!use_camera_motion) {
+ build_options += " -D__NO_CAMERA_MOTION__";
+ }
+ if (!use_baking) {
+ build_options += " -D__NO_BAKING__";
+ }
+ if (!use_volume) {
+ build_options += " -D__NO_VOLUME__";
+ }
+ if (!use_subsurface) {
+ build_options += " -D__NO_SUBSURFACE__";
+ }
+ if (!use_integrator_branched) {
+ build_options += " -D__NO_BRANCHED_PATH__";
+ }
+ if (!use_patch_evaluation) {
+ build_options += " -D__NO_PATCH_EVAL__";
+ }
+ if (!use_transparent && !use_volume) {
+ build_options += " -D__NO_TRANSPARENT__";
+ }
+ if (!use_shadow_tricks) {
+ build_options += " -D__NO_SHADOW_TRICKS__";
+ }
+ if (!use_principled) {
+ build_options += " -D__NO_PRINCIPLED__";
+ }
+ if (!use_denoising) {
+ build_options += " -D__NO_DENOISING__";
+ }
+ if (!use_shader_raytrace) {
+ build_options += " -D__NO_SHADER_RAYTRACE__";
+ }
+ return build_options;
+ }
};
-std::ostream& operator <<(std::ostream &os,
- const DeviceRequestedFeatures& requested_features);
+std::ostream &operator<<(std::ostream &os, const DeviceRequestedFeatures &requested_features);
/* Device */
struct DeviceDrawParams {
- function<void()> bind_display_space_shader_cb;
- function<void()> unbind_display_space_shader_cb;
+ function<void()> bind_display_space_shader_cb;
+ function<void()> unbind_display_space_shader_cb;
};
class Device {
- friend class device_sub_ptr;
-protected:
- enum {
- FALLBACK_SHADER_STATUS_NONE = 0,
- FALLBACK_SHADER_STATUS_ERROR,
- FALLBACK_SHADER_STATUS_SUCCESS,
- };
-
- Device(DeviceInfo& info_, Stats &stats_, Profiler &profiler_, bool background) : background(background),
- vertex_buffer(0),
- fallback_status(FALLBACK_SHADER_STATUS_NONE), fallback_shader_program(0),
- info(info_), stats(stats_), profiler(profiler_) {}
-
- bool background;
- string error_msg;
-
- /* used for real time display */
- unsigned int vertex_buffer;
- int fallback_status, fallback_shader_program;
- int image_texture_location, fullscreen_location;
-
- bool bind_fallback_display_space_shader(const float width, const float height);
-
- virtual device_ptr mem_alloc_sub_ptr(device_memory& /*mem*/, int /*offset*/, int /*size*/)
- {
- /* Only required for devices that implement denoising. */
- assert(false);
- return (device_ptr) 0;
- }
- virtual void mem_free_sub_ptr(device_ptr /*ptr*/) {};
-
-public:
- virtual ~Device();
-
- /* info */
- DeviceInfo info;
- virtual const string& error_message() { return error_msg; }
- bool have_error() { return !error_message().empty(); }
- virtual void set_error(const string& error)
- {
- if(!have_error()) {
- error_msg = error;
- }
- fprintf(stderr, "%s\n", error.c_str());
- fflush(stderr);
- }
- virtual bool show_samples() const { return false; }
- virtual BVHLayoutMask get_bvh_layout_mask() const = 0;
-
- /* statistics */
- Stats &stats;
- Profiler &profiler;
-
- /* memory alignment */
- virtual int mem_sub_ptr_alignment() { return MIN_ALIGNMENT_CPU_DATA_TYPES; }
-
- /* constant memory */
- virtual void const_copy_to(const char *name, void *host, size_t size) = 0;
-
- /* open shading language, only for CPU device */
- virtual void *osl_memory() { return NULL; }
-
- /* load/compile kernels, must be called before adding tasks */
- virtual bool load_kernels(
- const DeviceRequestedFeatures& /*requested_features*/)
- { return true; }
-
- /* Wait for device to become available to upload data and receive tasks
- * This method is used by the OpenCL device to load the
- * optimized kernels or when not (yet) available load the
- * generic kernels (only during foreground rendering) */
- virtual bool wait_for_availability(
- const DeviceRequestedFeatures& /*requested_features*/)
- { return true; }
- /* Check if there are 'better' kernels available to be used
- * We can switch over to these kernels
- * This method is used to determine if we can switch the preview kernels
- * to regular kernels */
- virtual DeviceKernelStatus get_active_kernel_switch_state()
- { return DEVICE_KERNEL_USING_FEATURE_KERNEL; }
-
- /* tasks */
- virtual int get_split_task_count(DeviceTask& task) = 0;
- virtual void task_add(DeviceTask& task) = 0;
- virtual void task_wait() = 0;
- virtual void task_cancel() = 0;
-
- /* opengl drawing */
- virtual void draw_pixels(device_memory& mem, int y,
- int w, int h, int width, int height,
- int dx, int dy, int dw, int dh,
- bool transparent, const DeviceDrawParams &draw_params);
+ friend class device_sub_ptr;
+
+ protected:
+ enum {
+ FALLBACK_SHADER_STATUS_NONE = 0,
+ FALLBACK_SHADER_STATUS_ERROR,
+ FALLBACK_SHADER_STATUS_SUCCESS,
+ };
+
+ Device(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background)
+ : background(background),
+ vertex_buffer(0),
+ fallback_status(FALLBACK_SHADER_STATUS_NONE),
+ fallback_shader_program(0),
+ info(info_),
+ stats(stats_),
+ profiler(profiler_)
+ {
+ }
+
+ bool background;
+ string error_msg;
+
+ /* used for real time display */
+ unsigned int vertex_buffer;
+ int fallback_status, fallback_shader_program;
+ int image_texture_location, fullscreen_location;
+
+ bool bind_fallback_display_space_shader(const float width, const float height);
+
+ virtual device_ptr mem_alloc_sub_ptr(device_memory & /*mem*/, int /*offset*/, int /*size*/)
+ {
+ /* Only required for devices that implement denoising. */
+ assert(false);
+ return (device_ptr)0;
+ }
+ virtual void mem_free_sub_ptr(device_ptr /*ptr*/){};
+
+ public:
+ virtual ~Device();
+
+ /* info */
+ DeviceInfo info;
+ virtual const string &error_message()
+ {
+ return error_msg;
+ }
+ bool have_error()
+ {
+ return !error_message().empty();
+ }
+ virtual void set_error(const string &error)
+ {
+ if (!have_error()) {
+ error_msg = error;
+ }
+ fprintf(stderr, "%s\n", error.c_str());
+ fflush(stderr);
+ }
+ virtual bool show_samples() const
+ {
+ return false;
+ }
+ virtual BVHLayoutMask get_bvh_layout_mask() const = 0;
+
+ /* statistics */
+ Stats &stats;
+ Profiler &profiler;
+
+ /* memory alignment */
+ virtual int mem_sub_ptr_alignment()
+ {
+ return MIN_ALIGNMENT_CPU_DATA_TYPES;
+ }
+
+ /* constant memory */
+ virtual void const_copy_to(const char *name, void *host, size_t size) = 0;
+
+ /* open shading language, only for CPU device */
+ virtual void *osl_memory()
+ {
+ return NULL;
+ }
+
+ /* load/compile kernels, must be called before adding tasks */
+ virtual bool load_kernels(const DeviceRequestedFeatures & /*requested_features*/)
+ {
+ return true;
+ }
+
+ /* Wait for device to become available to upload data and receive tasks
+ * This method is used by the OpenCL device to load the
+ * optimized kernels or when not (yet) available load the
+ * generic kernels (only during foreground rendering) */
+ virtual bool wait_for_availability(const DeviceRequestedFeatures & /*requested_features*/)
+ {
+ return true;
+ }
+ /* Check if there are 'better' kernels available to be used
+ * We can switch over to these kernels
+ * This method is used to determine if we can switch the preview kernels
+ * to regular kernels */
+ virtual DeviceKernelStatus get_active_kernel_switch_state()
+ {
+ return DEVICE_KERNEL_USING_FEATURE_KERNEL;
+ }
+
+ /* tasks */
+ virtual int get_split_task_count(DeviceTask &task) = 0;
+ virtual void task_add(DeviceTask &task) = 0;
+ virtual void task_wait() = 0;
+ virtual void task_cancel() = 0;
+
+ /* opengl drawing */
+ virtual void draw_pixels(device_memory &mem,
+ int y,
+ int w,
+ int h,
+ int width,
+ int height,
+ int dx,
+ int dy,
+ int dw,
+ int dh,
+ bool transparent,
+ const DeviceDrawParams &draw_params);
#ifdef WITH_NETWORK
- /* networking */
- void server_run();
+ /* networking */
+ void server_run();
#endif
- /* multi device */
- virtual void map_tile(Device * /*sub_device*/, RenderTile& /*tile*/) {}
- virtual int device_number(Device * /*sub_device*/) { return 0; }
- virtual void map_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/) {}
- virtual void unmap_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/) {}
-
- /* static */
- static Device *create(DeviceInfo& info, Stats &stats, Profiler& profiler, bool background = true);
-
- static DeviceType type_from_string(const char *name);
- static string string_from_type(DeviceType type);
- static vector<DeviceType> available_types();
- static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL);
- static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL);
- static DeviceInfo get_multi_device(const vector<DeviceInfo>& subdevices,
- int threads,
- bool background);
-
- /* Tag devices lists for update. */
- static void tag_update();
-
- static void free_memory();
-
-protected:
- /* Memory allocation, only accessed through device_memory. */
- friend class MultiDevice;
- friend class DeviceServer;
- friend class device_memory;
-
- virtual void mem_alloc(device_memory& mem) = 0;
- virtual void mem_copy_to(device_memory& mem) = 0;
- virtual void mem_copy_from(device_memory& mem,
- int y, int w, int h, int elem) = 0;
- virtual void mem_zero(device_memory& mem) = 0;
- virtual void mem_free(device_memory& mem) = 0;
-
-private:
- /* Indicted whether device types and devices lists were initialized. */
- static bool need_types_update, need_devices_update;
- static thread_mutex device_mutex;
- static vector<DeviceInfo> cuda_devices;
- static vector<DeviceInfo> opencl_devices;
- static vector<DeviceInfo> cpu_devices;
- static vector<DeviceInfo> network_devices;
- static uint devices_initialized_mask;
+ /* multi device */
+ virtual void map_tile(Device * /*sub_device*/, RenderTile & /*tile*/)
+ {
+ }
+ virtual int device_number(Device * /*sub_device*/)
+ {
+ return 0;
+ }
+ virtual void map_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/)
+ {
+ }
+ virtual void unmap_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/)
+ {
+ }
+
+ /* static */
+ static Device *create(DeviceInfo &info,
+ Stats &stats,
+ Profiler &profiler,
+ bool background = true);
+
+ static DeviceType type_from_string(const char *name);
+ static string string_from_type(DeviceType type);
+ static vector<DeviceType> available_types();
+ static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL);
+ static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL);
+ static DeviceInfo get_multi_device(const vector<DeviceInfo> &subdevices,
+ int threads,
+ bool background);
+
+ /* Tag devices lists for update. */
+ static void tag_update();
+
+ static void free_memory();
+
+ protected:
+ /* Memory allocation, only accessed through device_memory. */
+ friend class MultiDevice;
+ friend class DeviceServer;
+ friend class device_memory;
+
+ virtual void mem_alloc(device_memory &mem) = 0;
+ virtual void mem_copy_to(device_memory &mem) = 0;
+ virtual void mem_copy_from(device_memory &mem, int y, int w, int h, int elem) = 0;
+ virtual void mem_zero(device_memory &mem) = 0;
+ virtual void mem_free(device_memory &mem) = 0;
+
+ private:
+ /* Indicted whether device types and devices lists were initialized. */
+ static bool need_types_update, need_devices_update;
+ static thread_mutex device_mutex;
+ static vector<DeviceInfo> cuda_devices;
+ static vector<DeviceInfo> opencl_devices;
+ static vector<DeviceInfo> cpu_devices;
+ static vector<DeviceInfo> network_devices;
+ static uint devices_initialized_mask;
};
CCL_NAMESPACE_END
-#endif /* __DEVICE_H__ */
+#endif /* __DEVICE_H__ */
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 73f1fc02b08..837a8186064 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -61,1087 +61,1183 @@ class CPUDevice;
/* Has to be outside of the class to be shared across template instantiations. */
static const char *logged_architecture = "";
-template<typename F>
-class KernelFunctions {
-public:
- KernelFunctions()
- {
- kernel = (F)NULL;
- }
-
- KernelFunctions(F kernel_default,
- F kernel_sse2,
- F kernel_sse3,
- F kernel_sse41,
- F kernel_avx,
- F kernel_avx2)
- {
- const char *architecture_name = "default";
- kernel = kernel_default;
-
- /* Silence potential warnings about unused variables
- * when compiling without some architectures. */
- (void) kernel_sse2;
- (void) kernel_sse3;
- (void) kernel_sse41;
- (void) kernel_avx;
- (void) kernel_avx2;
+template<typename F> class KernelFunctions {
+ public:
+ KernelFunctions()
+ {
+ kernel = (F)NULL;
+ }
+
+ KernelFunctions(
+ F kernel_default, F kernel_sse2, F kernel_sse3, F kernel_sse41, F kernel_avx, F kernel_avx2)
+ {
+ const char *architecture_name = "default";
+ kernel = kernel_default;
+
+ /* Silence potential warnings about unused variables
+ * when compiling without some architectures. */
+ (void)kernel_sse2;
+ (void)kernel_sse3;
+ (void)kernel_sse41;
+ (void)kernel_avx;
+ (void)kernel_avx2;
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
- if(DebugFlags().cpu.has_avx2() && system_cpu_support_avx2()) {
- architecture_name = "AVX2";
- kernel = kernel_avx2;
- }
- else
+ if (DebugFlags().cpu.has_avx2() && system_cpu_support_avx2()) {
+ architecture_name = "AVX2";
+ kernel = kernel_avx2;
+ }
+ else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
- if(DebugFlags().cpu.has_avx() && system_cpu_support_avx()) {
- architecture_name = "AVX";
- kernel = kernel_avx;
- }
- else
+ if (DebugFlags().cpu.has_avx() && system_cpu_support_avx()) {
+ architecture_name = "AVX";
+ kernel = kernel_avx;
+ }
+ else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
- if(DebugFlags().cpu.has_sse41() && system_cpu_support_sse41()) {
- architecture_name = "SSE4.1";
- kernel = kernel_sse41;
- }
- else
+ if (DebugFlags().cpu.has_sse41() && system_cpu_support_sse41()) {
+ architecture_name = "SSE4.1";
+ kernel = kernel_sse41;
+ }
+ else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
- if(DebugFlags().cpu.has_sse3() && system_cpu_support_sse3()) {
- architecture_name = "SSE3";
- kernel = kernel_sse3;
- }
- else
+ if (DebugFlags().cpu.has_sse3() && system_cpu_support_sse3()) {
+ architecture_name = "SSE3";
+ kernel = kernel_sse3;
+ }
+ else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
- if(DebugFlags().cpu.has_sse2() && system_cpu_support_sse2()) {
- architecture_name = "SSE2";
- kernel = kernel_sse2;
- }
+ if (DebugFlags().cpu.has_sse2() && system_cpu_support_sse2()) {
+ architecture_name = "SSE2";
+ kernel = kernel_sse2;
+ }
#endif
- if(strcmp(architecture_name, logged_architecture) != 0) {
- VLOG(1) << "Will be using " << architecture_name << " kernels.";
- logged_architecture = architecture_name;
- }
- }
-
- inline F operator()() const {
- assert(kernel);
- return kernel;
- }
-protected:
- F kernel;
+ if (strcmp(architecture_name, logged_architecture) != 0) {
+ VLOG(1) << "Will be using " << architecture_name << " kernels.";
+ logged_architecture = architecture_name;
+ }
+ }
+
+ inline F operator()() const
+ {
+ assert(kernel);
+ return kernel;
+ }
+
+ protected:
+ F kernel;
};
class CPUSplitKernel : public DeviceSplitKernel {
- CPUDevice *device;
-public:
- explicit CPUSplitKernel(CPUDevice *device);
-
- virtual bool enqueue_split_kernel_data_init(const KernelDimensions& dim,
- RenderTile& rtile,
- int num_global_elements,
- device_memory& kernel_globals,
- device_memory& kernel_data_,
- device_memory& split_data,
- device_memory& ray_state,
- device_memory& queue_index,
- device_memory& use_queues_flag,
- device_memory& work_pool_wgs);
-
- virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name,
- const DeviceRequestedFeatures&);
- virtual int2 split_kernel_local_size();
- virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask *task);
- virtual uint64_t state_buffer_size(device_memory& kg, device_memory& data, size_t num_threads);
+ CPUDevice *device;
+
+ public:
+ explicit CPUSplitKernel(CPUDevice *device);
+
+ virtual bool enqueue_split_kernel_data_init(const KernelDimensions &dim,
+ RenderTile &rtile,
+ int num_global_elements,
+ device_memory &kernel_globals,
+ device_memory &kernel_data_,
+ device_memory &split_data,
+ device_memory &ray_state,
+ device_memory &queue_index,
+ device_memory &use_queues_flag,
+ device_memory &work_pool_wgs);
+
+ virtual SplitKernelFunction *get_split_kernel_function(const string &kernel_name,
+ const DeviceRequestedFeatures &);
+ virtual int2 split_kernel_local_size();
+ virtual int2 split_kernel_global_size(device_memory &kg, device_memory &data, DeviceTask *task);
+ virtual uint64_t state_buffer_size(device_memory &kg, device_memory &data, size_t num_threads);
};
-class CPUDevice : public Device
-{
-public:
- TaskPool task_pool;
- KernelGlobals kernel_globals;
+class CPUDevice : public Device {
+ public:
+ TaskPool task_pool;
+ KernelGlobals kernel_globals;
- device_vector<TextureInfo> texture_info;
- bool need_texture_info;
+ device_vector<TextureInfo> texture_info;
+ bool need_texture_info;
#ifdef WITH_OSL
- OSLGlobals osl_globals;
+ OSLGlobals osl_globals;
#endif
- bool use_split_kernel;
-
- DeviceRequestedFeatures requested_features;
-
- KernelFunctions<void(*)(KernelGlobals *, float *, int, int, int, int, int)> path_trace_kernel;
- KernelFunctions<void(*)(KernelGlobals *, uchar4 *, float *, float, int, int, int, int)> convert_to_half_float_kernel;
- KernelFunctions<void(*)(KernelGlobals *, uchar4 *, float *, float, int, int, int, int)> convert_to_byte_kernel;
- KernelFunctions<void(*)(KernelGlobals *, uint4 *, float4 *, int, int, int, int, int)> shader_kernel;
-
- KernelFunctions<void(*)(int, TileInfo*, int, int, float*, float*, float*, float*, float*, int*, int, int)> filter_divide_shadow_kernel;
- KernelFunctions<void(*)(int, TileInfo*, int, int, int, int, float*, float*, float, int*, int, int)> filter_get_feature_kernel;
- KernelFunctions<void(*)(int, int, int, int*, float*, float*, int, int*)> filter_write_feature_kernel;
- KernelFunctions<void(*)(int, int, float*, float*, float*, float*, int*, int)> filter_detect_outliers_kernel;
- KernelFunctions<void(*)(int, int, float*, float*, float*, float*, int*, int)> filter_combine_halves_kernel;
-
- KernelFunctions<void(*)(int, int, float*, float*, float*, float*, int*, int, int, int, float, float)> filter_nlm_calc_difference_kernel;
- KernelFunctions<void(*)(float*, float*, int*, int, int)> filter_nlm_blur_kernel;
- KernelFunctions<void(*)(float*, float*, int*, int, int)> filter_nlm_calc_weight_kernel;
- KernelFunctions<void(*)(int, int, float*, float*, float*, float*, float*, int*, int, int, int)> filter_nlm_update_output_kernel;
- KernelFunctions<void(*)(float*, float*, int*, int)> filter_nlm_normalize_kernel;
-
- KernelFunctions<void(*)(float*, TileInfo*, int, int, int, float*, int*, int*, int, int, bool, int, float)> filter_construct_transform_kernel;
- KernelFunctions<void(*)(int, int, int, float*, float*, float*, int*, float*, float3*, int*, int*, int, int, int, int, bool)> filter_nlm_construct_gramian_kernel;
- KernelFunctions<void(*)(int, int, int, float*, int*, float*, float3*, int*, int)> filter_finalize_kernel;
-
- KernelFunctions<void(*)(KernelGlobals *, ccl_constant KernelData*, ccl_global void*, int, ccl_global char*,
- int, int, int, int, int, int, int, int, ccl_global int*, int,
- ccl_global char*, ccl_global unsigned int*, unsigned int, ccl_global float*)> data_init_kernel;
- unordered_map<string, KernelFunctions<void(*)(KernelGlobals*, KernelData*)> > split_kernels;
+ bool use_split_kernel;
+
+ DeviceRequestedFeatures requested_features;
+
+ KernelFunctions<void (*)(KernelGlobals *, float *, int, int, int, int, int)> path_trace_kernel;
+ KernelFunctions<void (*)(KernelGlobals *, uchar4 *, float *, float, int, int, int, int)>
+ convert_to_half_float_kernel;
+ KernelFunctions<void (*)(KernelGlobals *, uchar4 *, float *, float, int, int, int, int)>
+ convert_to_byte_kernel;
+ KernelFunctions<void (*)(KernelGlobals *, uint4 *, float4 *, int, int, int, int, int)>
+ shader_kernel;
+
+ KernelFunctions<void (*)(
+ int, TileInfo *, int, int, float *, float *, float *, float *, float *, int *, int, int)>
+ filter_divide_shadow_kernel;
+ KernelFunctions<void (*)(
+ int, TileInfo *, int, int, int, int, float *, float *, float, int *, int, int)>
+ filter_get_feature_kernel;
+ KernelFunctions<void (*)(int, int, int, int *, float *, float *, int, int *)>
+ filter_write_feature_kernel;
+ KernelFunctions<void (*)(int, int, float *, float *, float *, float *, int *, int)>
+ filter_detect_outliers_kernel;
+ KernelFunctions<void (*)(int, int, float *, float *, float *, float *, int *, int)>
+ filter_combine_halves_kernel;
+
+ KernelFunctions<void (*)(
+ int, int, float *, float *, float *, float *, int *, int, int, int, float, float)>
+ filter_nlm_calc_difference_kernel;
+ KernelFunctions<void (*)(float *, float *, int *, int, int)> filter_nlm_blur_kernel;
+ KernelFunctions<void (*)(float *, float *, int *, int, int)> filter_nlm_calc_weight_kernel;
+ KernelFunctions<void (*)(
+ int, int, float *, float *, float *, float *, float *, int *, int, int, int)>
+ filter_nlm_update_output_kernel;
+ KernelFunctions<void (*)(float *, float *, int *, int)> filter_nlm_normalize_kernel;
+
+ KernelFunctions<void (*)(
+ float *, TileInfo *, int, int, int, float *, int *, int *, int, int, bool, int, float)>
+ filter_construct_transform_kernel;
+ KernelFunctions<void (*)(int,
+ int,
+ int,
+ float *,
+ float *,
+ float *,
+ int *,
+ float *,
+ float3 *,
+ int *,
+ int *,
+ int,
+ int,
+ int,
+ int,
+ bool)>
+ filter_nlm_construct_gramian_kernel;
+ KernelFunctions<void (*)(int, int, int, float *, int *, float *, float3 *, int *, int)>
+ filter_finalize_kernel;
+
+ KernelFunctions<void (*)(KernelGlobals *,
+ ccl_constant KernelData *,
+ ccl_global void *,
+ int,
+ ccl_global char *,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ ccl_global int *,
+ int,
+ ccl_global char *,
+ ccl_global unsigned int *,
+ unsigned int,
+ ccl_global float *)>
+ data_init_kernel;
+ unordered_map<string, KernelFunctions<void (*)(KernelGlobals *, KernelData *)>> split_kernels;
#define KERNEL_FUNCTIONS(name) \
- KERNEL_NAME_EVAL(cpu, name), \
- KERNEL_NAME_EVAL(cpu_sse2, name), \
- KERNEL_NAME_EVAL(cpu_sse3, name), \
- KERNEL_NAME_EVAL(cpu_sse41, name), \
- KERNEL_NAME_EVAL(cpu_avx, name), \
- KERNEL_NAME_EVAL(cpu_avx2, name)
-
- CPUDevice(DeviceInfo& info_, Stats &stats_, Profiler &profiler_, bool background_)
- : Device(info_, stats_, profiler_, background_),
- texture_info(this, "__texture_info", MEM_TEXTURE),
-#define REGISTER_KERNEL(name) name ## _kernel(KERNEL_FUNCTIONS(name))
- REGISTER_KERNEL(path_trace),
- REGISTER_KERNEL(convert_to_half_float),
- REGISTER_KERNEL(convert_to_byte),
- REGISTER_KERNEL(shader),
- REGISTER_KERNEL(filter_divide_shadow),
- REGISTER_KERNEL(filter_get_feature),
- REGISTER_KERNEL(filter_write_feature),
- REGISTER_KERNEL(filter_detect_outliers),
- REGISTER_KERNEL(filter_combine_halves),
- REGISTER_KERNEL(filter_nlm_calc_difference),
- REGISTER_KERNEL(filter_nlm_blur),
- REGISTER_KERNEL(filter_nlm_calc_weight),
- REGISTER_KERNEL(filter_nlm_update_output),
- REGISTER_KERNEL(filter_nlm_normalize),
- REGISTER_KERNEL(filter_construct_transform),
- REGISTER_KERNEL(filter_nlm_construct_gramian),
- REGISTER_KERNEL(filter_finalize),
- REGISTER_KERNEL(data_init)
+ KERNEL_NAME_EVAL(cpu, name), KERNEL_NAME_EVAL(cpu_sse2, name), \
+ KERNEL_NAME_EVAL(cpu_sse3, name), KERNEL_NAME_EVAL(cpu_sse41, name), \
+ KERNEL_NAME_EVAL(cpu_avx, name), KERNEL_NAME_EVAL(cpu_avx2, name)
+
+ CPUDevice(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background_)
+ : Device(info_, stats_, profiler_, background_),
+ texture_info(this, "__texture_info", MEM_TEXTURE),
+#define REGISTER_KERNEL(name) name##_kernel(KERNEL_FUNCTIONS(name))
+ REGISTER_KERNEL(path_trace),
+ REGISTER_KERNEL(convert_to_half_float),
+ REGISTER_KERNEL(convert_to_byte),
+ REGISTER_KERNEL(shader),
+ REGISTER_KERNEL(filter_divide_shadow),
+ REGISTER_KERNEL(filter_get_feature),
+ REGISTER_KERNEL(filter_write_feature),
+ REGISTER_KERNEL(filter_detect_outliers),
+ REGISTER_KERNEL(filter_combine_halves),
+ REGISTER_KERNEL(filter_nlm_calc_difference),
+ REGISTER_KERNEL(filter_nlm_blur),
+ REGISTER_KERNEL(filter_nlm_calc_weight),
+ REGISTER_KERNEL(filter_nlm_update_output),
+ REGISTER_KERNEL(filter_nlm_normalize),
+ REGISTER_KERNEL(filter_construct_transform),
+ REGISTER_KERNEL(filter_nlm_construct_gramian),
+ REGISTER_KERNEL(filter_finalize),
+ REGISTER_KERNEL(data_init)
#undef REGISTER_KERNEL
- {
- if(info.cpu_threads == 0) {
- info.cpu_threads = TaskScheduler::num_threads();
- }
+ {
+ if (info.cpu_threads == 0) {
+ info.cpu_threads = TaskScheduler::num_threads();
+ }
#ifdef WITH_OSL
- kernel_globals.osl = &osl_globals;
+ kernel_globals.osl = &osl_globals;
#endif
- use_split_kernel = DebugFlags().cpu.split_kernel;
- if(use_split_kernel) {
- VLOG(1) << "Will be using split kernel.";
- }
- need_texture_info = false;
-
-#define REGISTER_SPLIT_KERNEL(name) split_kernels[#name] = KernelFunctions<void(*)(KernelGlobals*, KernelData*)>(KERNEL_FUNCTIONS(name))
- REGISTER_SPLIT_KERNEL(path_init);
- REGISTER_SPLIT_KERNEL(scene_intersect);
- REGISTER_SPLIT_KERNEL(lamp_emission);
- REGISTER_SPLIT_KERNEL(do_volume);
- REGISTER_SPLIT_KERNEL(queue_enqueue);
- REGISTER_SPLIT_KERNEL(indirect_background);
- REGISTER_SPLIT_KERNEL(shader_setup);
- REGISTER_SPLIT_KERNEL(shader_sort);
- REGISTER_SPLIT_KERNEL(shader_eval);
- REGISTER_SPLIT_KERNEL(holdout_emission_blurring_pathtermination_ao);
- REGISTER_SPLIT_KERNEL(subsurface_scatter);
- REGISTER_SPLIT_KERNEL(direct_lighting);
- REGISTER_SPLIT_KERNEL(shadow_blocked_ao);
- REGISTER_SPLIT_KERNEL(shadow_blocked_dl);
- REGISTER_SPLIT_KERNEL(enqueue_inactive);
- REGISTER_SPLIT_KERNEL(next_iteration_setup);
- REGISTER_SPLIT_KERNEL(indirect_subsurface);
- REGISTER_SPLIT_KERNEL(buffer_update);
+ use_split_kernel = DebugFlags().cpu.split_kernel;
+ if (use_split_kernel) {
+ VLOG(1) << "Will be using split kernel.";
+ }
+ need_texture_info = false;
+
+#define REGISTER_SPLIT_KERNEL(name) \
+ split_kernels[#name] = KernelFunctions<void (*)(KernelGlobals *, KernelData *)>( \
+ KERNEL_FUNCTIONS(name))
+ REGISTER_SPLIT_KERNEL(path_init);
+ REGISTER_SPLIT_KERNEL(scene_intersect);
+ REGISTER_SPLIT_KERNEL(lamp_emission);
+ REGISTER_SPLIT_KERNEL(do_volume);
+ REGISTER_SPLIT_KERNEL(queue_enqueue);
+ REGISTER_SPLIT_KERNEL(indirect_background);
+ REGISTER_SPLIT_KERNEL(shader_setup);
+ REGISTER_SPLIT_KERNEL(shader_sort);
+ REGISTER_SPLIT_KERNEL(shader_eval);
+ REGISTER_SPLIT_KERNEL(holdout_emission_blurring_pathtermination_ao);
+ REGISTER_SPLIT_KERNEL(subsurface_scatter);
+ REGISTER_SPLIT_KERNEL(direct_lighting);
+ REGISTER_SPLIT_KERNEL(shadow_blocked_ao);
+ REGISTER_SPLIT_KERNEL(shadow_blocked_dl);
+ REGISTER_SPLIT_KERNEL(enqueue_inactive);
+ REGISTER_SPLIT_KERNEL(next_iteration_setup);
+ REGISTER_SPLIT_KERNEL(indirect_subsurface);
+ REGISTER_SPLIT_KERNEL(buffer_update);
#undef REGISTER_SPLIT_KERNEL
#undef KERNEL_FUNCTIONS
- }
-
- ~CPUDevice()
- {
- task_pool.stop();
- texture_info.free();
- }
-
- virtual bool show_samples() const
- {
- return (info.cpu_threads == 1);
- }
-
- virtual BVHLayoutMask get_bvh_layout_mask() const {
- BVHLayoutMask bvh_layout_mask = BVH_LAYOUT_BVH2;
- if(DebugFlags().cpu.has_sse2() && system_cpu_support_sse2()) {
- bvh_layout_mask |= BVH_LAYOUT_BVH4;
- }
- if(DebugFlags().cpu.has_avx2() && system_cpu_support_avx2()) {
- bvh_layout_mask |= BVH_LAYOUT_BVH8;
- }
+ }
+
+ ~CPUDevice()
+ {
+ task_pool.stop();
+ texture_info.free();
+ }
+
+ virtual bool show_samples() const
+ {
+ return (info.cpu_threads == 1);
+ }
+
+ virtual BVHLayoutMask get_bvh_layout_mask() const
+ {
+ BVHLayoutMask bvh_layout_mask = BVH_LAYOUT_BVH2;
+ if (DebugFlags().cpu.has_sse2() && system_cpu_support_sse2()) {
+ bvh_layout_mask |= BVH_LAYOUT_BVH4;
+ }
+ if (DebugFlags().cpu.has_avx2() && system_cpu_support_avx2()) {
+ bvh_layout_mask |= BVH_LAYOUT_BVH8;
+ }
#ifdef WITH_EMBREE
- bvh_layout_mask |= BVH_LAYOUT_EMBREE;
-#endif /* WITH_EMBREE */
- return bvh_layout_mask;
- }
-
- void load_texture_info()
- {
- if(need_texture_info) {
- texture_info.copy_to_device();
- need_texture_info = false;
- }
- }
-
- void mem_alloc(device_memory& mem)
- {
- if(mem.type == MEM_TEXTURE) {
- assert(!"mem_alloc not supported for textures.");
- }
- else {
- if(mem.name) {
- VLOG(1) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
- }
-
- if(mem.type == MEM_DEVICE_ONLY) {
- assert(!mem.host_pointer);
- size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES;
- void *data = util_aligned_malloc(mem.memory_size(), alignment);
- mem.device_pointer = (device_ptr)data;
- }
- else {
- mem.device_pointer = (device_ptr)mem.host_pointer;
- }
-
- mem.device_size = mem.memory_size();
- stats.mem_alloc(mem.device_size);
- }
- }
-
- void mem_copy_to(device_memory& mem)
- {
- if(mem.type == MEM_TEXTURE) {
- tex_free(mem);
- tex_alloc(mem);
- }
- else if(mem.type == MEM_PIXELS) {
- assert(!"mem_copy_to not supported for pixels.");
- }
- else {
- if(!mem.device_pointer) {
- mem_alloc(mem);
- }
-
- /* copy is no-op */
- }
- }
-
- void mem_copy_from(device_memory& /*mem*/,
- int /*y*/, int /*w*/, int /*h*/,
- int /*elem*/)
- {
- /* no-op */
- }
-
- void mem_zero(device_memory& mem)
- {
- if(!mem.device_pointer) {
- mem_alloc(mem);
- }
-
- if(mem.device_pointer) {
- memset((void*)mem.device_pointer, 0, mem.memory_size());
- }
- }
-
- void mem_free(device_memory& mem)
- {
- if(mem.type == MEM_TEXTURE) {
- tex_free(mem);
- }
- else if(mem.device_pointer) {
- if(mem.type == MEM_DEVICE_ONLY) {
- util_aligned_free((void*)mem.device_pointer);
- }
- mem.device_pointer = 0;
- stats.mem_free(mem.device_size);
- mem.device_size = 0;
- }
- }
-
- virtual device_ptr mem_alloc_sub_ptr(device_memory& mem, int offset, int /*size*/)
- {
- return (device_ptr) (((char*) mem.device_pointer) + mem.memory_elements_size(offset));
- }
-
- void const_copy_to(const char *name, void *host, size_t size)
- {
- kernel_const_copy(&kernel_globals, name, host, size);
- }
-
- void tex_alloc(device_memory& mem)
- {
- VLOG(1) << "Texture allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
-
- if(mem.interpolation == INTERPOLATION_NONE) {
- /* Data texture. */
- kernel_tex_copy(&kernel_globals,
- mem.name,
- mem.host_pointer,
- mem.data_size);
- }
- else {
- /* Image Texture. */
- int flat_slot = 0;
- if(string_startswith(mem.name, "__tex_image")) {
- int pos = string(mem.name).rfind("_");
- flat_slot = atoi(mem.name + pos + 1);
- }
- else {
- assert(0);
- }
-
- if(flat_slot >= texture_info.size()) {
- /* Allocate some slots in advance, to reduce amount
- * of re-allocations. */
- texture_info.resize(flat_slot + 128);
- }
-
- TextureInfo& info = texture_info[flat_slot];
- info.data = (uint64_t)mem.host_pointer;
- info.cl_buffer = 0;
- info.interpolation = mem.interpolation;
- info.extension = mem.extension;
- info.width = mem.data_width;
- info.height = mem.data_height;
- info.depth = mem.data_depth;
-
- need_texture_info = true;
- }
-
- mem.device_pointer = (device_ptr)mem.host_pointer;
- mem.device_size = mem.memory_size();
- stats.mem_alloc(mem.device_size);
- }
-
- void tex_free(device_memory& mem)
- {
- if(mem.device_pointer) {
- mem.device_pointer = 0;
- stats.mem_free(mem.device_size);
- mem.device_size = 0;
- need_texture_info = true;
- }
- }
-
- void *osl_memory()
- {
+ bvh_layout_mask |= BVH_LAYOUT_EMBREE;
+#endif /* WITH_EMBREE */
+ return bvh_layout_mask;
+ }
+
+ void load_texture_info()
+ {
+ if (need_texture_info) {
+ texture_info.copy_to_device();
+ need_texture_info = false;
+ }
+ }
+
+ void mem_alloc(device_memory &mem)
+ {
+ if (mem.type == MEM_TEXTURE) {
+ assert(!"mem_alloc not supported for textures.");
+ }
+ else {
+ if (mem.name) {
+ VLOG(1) << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
+ }
+
+ if (mem.type == MEM_DEVICE_ONLY) {
+ assert(!mem.host_pointer);
+ size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES;
+ void *data = util_aligned_malloc(mem.memory_size(), alignment);
+ mem.device_pointer = (device_ptr)data;
+ }
+ else {
+ mem.device_pointer = (device_ptr)mem.host_pointer;
+ }
+
+ mem.device_size = mem.memory_size();
+ stats.mem_alloc(mem.device_size);
+ }
+ }
+
+ void mem_copy_to(device_memory &mem)
+ {
+ if (mem.type == MEM_TEXTURE) {
+ tex_free(mem);
+ tex_alloc(mem);
+ }
+ else if (mem.type == MEM_PIXELS) {
+ assert(!"mem_copy_to not supported for pixels.");
+ }
+ else {
+ if (!mem.device_pointer) {
+ mem_alloc(mem);
+ }
+
+ /* copy is no-op */
+ }
+ }
+
+ void mem_copy_from(device_memory & /*mem*/, int /*y*/, int /*w*/, int /*h*/, int /*elem*/)
+ {
+ /* no-op */
+ }
+
+ void mem_zero(device_memory &mem)
+ {
+ if (!mem.device_pointer) {
+ mem_alloc(mem);
+ }
+
+ if (mem.device_pointer) {
+ memset((void *)mem.device_pointer, 0, mem.memory_size());
+ }
+ }
+
+ void mem_free(device_memory &mem)
+ {
+ if (mem.type == MEM_TEXTURE) {
+ tex_free(mem);
+ }
+ else if (mem.device_pointer) {
+ if (mem.type == MEM_DEVICE_ONLY) {
+ util_aligned_free((void *)mem.device_pointer);
+ }
+ mem.device_pointer = 0;
+ stats.mem_free(mem.device_size);
+ mem.device_size = 0;
+ }
+ }
+
+ virtual device_ptr mem_alloc_sub_ptr(device_memory &mem, int offset, int /*size*/)
+ {
+ return (device_ptr)(((char *)mem.device_pointer) + mem.memory_elements_size(offset));
+ }
+
+ void const_copy_to(const char *name, void *host, size_t size)
+ {
+ kernel_const_copy(&kernel_globals, name, host, size);
+ }
+
+ void tex_alloc(device_memory &mem)
+ {
+ VLOG(1) << "Texture allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
+
+ if (mem.interpolation == INTERPOLATION_NONE) {
+ /* Data texture. */
+ kernel_tex_copy(&kernel_globals, mem.name, mem.host_pointer, mem.data_size);
+ }
+ else {
+ /* Image Texture. */
+ int flat_slot = 0;
+ if (string_startswith(mem.name, "__tex_image")) {
+ int pos = string(mem.name).rfind("_");
+ flat_slot = atoi(mem.name + pos + 1);
+ }
+ else {
+ assert(0);
+ }
+
+ if (flat_slot >= texture_info.size()) {
+ /* Allocate some slots in advance, to reduce amount
+ * of re-allocations. */
+ texture_info.resize(flat_slot + 128);
+ }
+
+ TextureInfo &info = texture_info[flat_slot];
+ info.data = (uint64_t)mem.host_pointer;
+ info.cl_buffer = 0;
+ info.interpolation = mem.interpolation;
+ info.extension = mem.extension;
+ info.width = mem.data_width;
+ info.height = mem.data_height;
+ info.depth = mem.data_depth;
+
+ need_texture_info = true;
+ }
+
+ mem.device_pointer = (device_ptr)mem.host_pointer;
+ mem.device_size = mem.memory_size();
+ stats.mem_alloc(mem.device_size);
+ }
+
+ void tex_free(device_memory &mem)
+ {
+ if (mem.device_pointer) {
+ mem.device_pointer = 0;
+ stats.mem_free(mem.device_size);
+ mem.device_size = 0;
+ need_texture_info = true;
+ }
+ }
+
+ void *osl_memory()
+ {
#ifdef WITH_OSL
- return &osl_globals;
+ return &osl_globals;
#else
- return NULL;
+ return NULL;
#endif
- }
-
- void thread_run(DeviceTask *task)
- {
- if(task->type == DeviceTask::RENDER) {
- thread_render(*task);
- }
- else if(task->type == DeviceTask::FILM_CONVERT)
- thread_film_convert(*task);
- else if(task->type == DeviceTask::SHADER)
- thread_shader(*task);
- }
-
- class CPUDeviceTask : public DeviceTask {
- public:
- CPUDeviceTask(CPUDevice *device, DeviceTask& task)
- : DeviceTask(task)
- {
- run = function_bind(&CPUDevice::thread_run, device, this);
- }
- };
-
- bool denoising_non_local_means(device_ptr image_ptr, device_ptr guide_ptr, device_ptr variance_ptr, device_ptr out_ptr,
- DenoisingTask *task)
- {
- ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_NON_LOCAL_MEANS);
-
- int4 rect = task->rect;
- int r = task->nlm_state.r;
- int f = task->nlm_state.f;
- float a = task->nlm_state.a;
- float k_2 = task->nlm_state.k_2;
-
- int w = align_up(rect.z-rect.x, 4);
- int h = rect.w-rect.y;
- int stride = task->buffer.stride;
- int channel_offset = task->nlm_state.is_color? task->buffer.pass_stride : 0;
-
- float *temporary_mem = (float*) task->buffer.temporary_mem.device_pointer;
- float *blurDifference = temporary_mem;
- float *difference = temporary_mem + task->buffer.pass_stride;
- float *weightAccum = temporary_mem + 2*task->buffer.pass_stride;
-
- memset(weightAccum, 0, sizeof(float)*w*h);
- memset((float*) out_ptr, 0, sizeof(float)*w*h);
-
- for(int i = 0; i < (2*r+1)*(2*r+1); i++) {
- int dy = i / (2*r+1) - r;
- int dx = i % (2*r+1) - r;
-
- int local_rect[4] = {max(0, -dx), max(0, -dy), rect.z-rect.x - max(0, dx), rect.w-rect.y - max(0, dy)};
- filter_nlm_calc_difference_kernel()(dx, dy,
- (float*) guide_ptr,
- (float*) variance_ptr,
- NULL,
- difference,
- local_rect,
- w, channel_offset,
- 0, a, k_2);
-
- filter_nlm_blur_kernel() (difference, blurDifference, local_rect, w, f);
- filter_nlm_calc_weight_kernel()(blurDifference, difference, local_rect, w, f);
- filter_nlm_blur_kernel() (difference, blurDifference, local_rect, w, f);
-
- filter_nlm_update_output_kernel()(dx, dy,
- blurDifference,
- (float*) image_ptr,
- difference,
- (float*) out_ptr,
- weightAccum,
- local_rect,
- channel_offset,
- stride, f);
- }
-
- int local_rect[4] = {0, 0, rect.z-rect.x, rect.w-rect.y};
- filter_nlm_normalize_kernel()((float*) out_ptr, weightAccum, local_rect, w);
-
- return true;
- }
-
- bool denoising_construct_transform(DenoisingTask *task)
- {
- ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_CONSTRUCT_TRANSFORM);
-
- for(int y = 0; y < task->filter_area.w; y++) {
- for(int x = 0; x < task->filter_area.z; x++) {
- filter_construct_transform_kernel()((float*) task->buffer.mem.device_pointer,
- task->tile_info,
- x + task->filter_area.x,
- y + task->filter_area.y,
- y*task->filter_area.z + x,
- (float*) task->storage.transform.device_pointer,
- (int*) task->storage.rank.device_pointer,
- &task->rect.x,
- task->buffer.pass_stride,
- task->buffer.frame_stride,
- task->buffer.use_time,
- task->radius,
- task->pca_threshold);
- }
- }
- return true;
- }
-
- bool denoising_accumulate(device_ptr color_ptr,
- device_ptr color_variance_ptr,
- device_ptr scale_ptr,
- int frame,
- DenoisingTask *task)
- {
- ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_RECONSTRUCT);
-
- float *temporary_mem = (float*) task->buffer.temporary_mem.device_pointer;
- float *difference = temporary_mem;
- float *blurDifference = temporary_mem + task->buffer.pass_stride;
-
- int r = task->radius;
- int frame_offset = frame * task->buffer.frame_stride;
- for(int i = 0; i < (2*r+1)*(2*r+1); i++) {
- int dy = i / (2*r+1) - r;
- int dx = i % (2*r+1) - r;
-
- int local_rect[4] = {max(0, -dx), max(0, -dy),
- task->reconstruction_state.source_w - max(0, dx),
- task->reconstruction_state.source_h - max(0, dy)};
- filter_nlm_calc_difference_kernel()(dx, dy,
- (float*) color_ptr,
- (float*) color_variance_ptr,
- (float*) scale_ptr,
- difference,
- local_rect,
- task->buffer.stride,
- task->buffer.pass_stride,
- frame_offset,
- 1.0f,
- task->nlm_k_2);
- filter_nlm_blur_kernel()(difference, blurDifference, local_rect, task->buffer.stride, 4);
- filter_nlm_calc_weight_kernel()(blurDifference, difference, local_rect, task->buffer.stride, 4);
- filter_nlm_blur_kernel()(difference, blurDifference, local_rect, task->buffer.stride, 4);
- filter_nlm_construct_gramian_kernel()(dx, dy,
- task->tile_info->frames[frame],
- blurDifference,
- (float*) task->buffer.mem.device_pointer,
- (float*) task->storage.transform.device_pointer,
- (int*) task->storage.rank.device_pointer,
- (float*) task->storage.XtWX.device_pointer,
- (float3*) task->storage.XtWY.device_pointer,
- local_rect,
- &task->reconstruction_state.filter_window.x,
- task->buffer.stride,
- 4,
- task->buffer.pass_stride,
- frame_offset,
- task->buffer.use_time);
- }
-
- return true;
- }
-
- bool denoising_solve(device_ptr output_ptr,
- DenoisingTask *task)
- {
- for(int y = 0; y < task->filter_area.w; y++) {
- for(int x = 0; x < task->filter_area.z; x++) {
- filter_finalize_kernel()(x,
- y,
- y*task->filter_area.z + x,
- (float*) output_ptr,
- (int*) task->storage.rank.device_pointer,
- (float*) task->storage.XtWX.device_pointer,
- (float3*) task->storage.XtWY.device_pointer,
- &task->reconstruction_state.buffer_params.x,
- task->render_buffer.samples);
- }
- }
- return true;
- }
-
- bool denoising_combine_halves(device_ptr a_ptr, device_ptr b_ptr,
- device_ptr mean_ptr, device_ptr variance_ptr,
- int r, int4 rect, DenoisingTask *task)
- {
- ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_COMBINE_HALVES);
-
- for(int y = rect.y; y < rect.w; y++) {
- for(int x = rect.x; x < rect.z; x++) {
- filter_combine_halves_kernel()(x, y,
- (float*) mean_ptr,
- (float*) variance_ptr,
- (float*) a_ptr,
- (float*) b_ptr,
- &rect.x,
- r);
- }
- }
- return true;
- }
-
- bool denoising_divide_shadow(device_ptr a_ptr, device_ptr b_ptr,
- device_ptr sample_variance_ptr, device_ptr sv_variance_ptr,
- device_ptr buffer_variance_ptr, DenoisingTask *task)
- {
- ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_DIVIDE_SHADOW);
-
- for(int y = task->rect.y; y < task->rect.w; y++) {
- for(int x = task->rect.x; x < task->rect.z; x++) {
- filter_divide_shadow_kernel()(task->render_buffer.samples,
- task->tile_info,
- x, y,
- (float*) a_ptr,
- (float*) b_ptr,
- (float*) sample_variance_ptr,
- (float*) sv_variance_ptr,
- (float*) buffer_variance_ptr,
- &task->rect.x,
- task->render_buffer.pass_stride,
- task->render_buffer.offset);
- }
- }
- return true;
- }
-
- bool denoising_get_feature(int mean_offset,
- int variance_offset,
- device_ptr mean_ptr,
- device_ptr variance_ptr,
- float scale,
- DenoisingTask *task)
- {
- ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_GET_FEATURE);
-
- for(int y = task->rect.y; y < task->rect.w; y++) {
- for(int x = task->rect.x; x < task->rect.z; x++) {
- filter_get_feature_kernel()(task->render_buffer.samples,
- task->tile_info,
- mean_offset,
- variance_offset,
- x, y,
- (float*) mean_ptr,
- (float*) variance_ptr,
- scale,
- &task->rect.x,
- task->render_buffer.pass_stride,
- task->render_buffer.offset);
- }
- }
- return true;
- }
-
- bool denoising_write_feature(int out_offset,
- device_ptr from_ptr,
- device_ptr buffer_ptr,
- DenoisingTask *task)
- {
- for(int y = 0; y < task->filter_area.w; y++) {
- for(int x = 0; x < task->filter_area.z; x++) {
- filter_write_feature_kernel()(task->render_buffer.samples,
- x + task->filter_area.x,
- y + task->filter_area.y,
- &task->reconstruction_state.buffer_params.x,
- (float*) from_ptr,
- (float*) buffer_ptr,
- out_offset,
- &task->rect.x);
- }
- }
- return true;
- }
-
- bool denoising_detect_outliers(device_ptr image_ptr,
- device_ptr variance_ptr,
- device_ptr depth_ptr,
- device_ptr output_ptr,
- DenoisingTask *task)
- {
- ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_DETECT_OUTLIERS);
-
- for(int y = task->rect.y; y < task->rect.w; y++) {
- for(int x = task->rect.x; x < task->rect.z; x++) {
- filter_detect_outliers_kernel()(x, y,
- (float*) image_ptr,
- (float*) variance_ptr,
- (float*) depth_ptr,
- (float*) output_ptr,
- &task->rect.x,
- task->buffer.pass_stride);
- }
- }
- return true;
- }
-
- void path_trace(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
- {
- const bool use_coverage = kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE;
-
- scoped_timer timer(&tile.buffers->render_time);
-
- Coverage coverage(kg, tile);
- if(use_coverage) {
- coverage.init_path_trace();
- }
-
- float *render_buffer = (float*)tile.buffer;
- int start_sample = tile.start_sample;
- int end_sample = tile.start_sample + tile.num_samples;
-
- /* Needed for Embree. */
- SIMD_SET_FLUSH_TO_ZERO;
-
- for(int sample = start_sample; sample < end_sample; sample++) {
- if(task.get_cancel() || task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
-
- for(int y = tile.y; y < tile.y + tile.h; y++) {
- for(int x = tile.x; x < tile.x + tile.w; x++) {
- if(use_coverage) {
- coverage.init_pixel(x, y);
- }
- path_trace_kernel()(kg, render_buffer,
- sample, x, y, tile.offset, tile.stride);
- }
- }
-
- tile.sample = sample + 1;
-
- task.update_progress(&tile, tile.w*tile.h);
- }
- if(use_coverage) {
- coverage.finalize();
- }
- }
-
- void denoise(DenoisingTask& denoising, RenderTile &tile)
- {
- ProfilingHelper profiling(denoising.profiler, PROFILING_DENOISING);
-
- tile.sample = tile.start_sample + tile.num_samples;
-
- denoising.functions.construct_transform = function_bind(&CPUDevice::denoising_construct_transform, this, &denoising);
- denoising.functions.accumulate = function_bind(&CPUDevice::denoising_accumulate, this, _1, _2, _3, _4, &denoising);
- denoising.functions.solve = function_bind(&CPUDevice::denoising_solve, this, _1, &denoising);
- denoising.functions.divide_shadow = function_bind(&CPUDevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising);
- denoising.functions.non_local_means = function_bind(&CPUDevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising);
- denoising.functions.combine_halves = function_bind(&CPUDevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising);
- denoising.functions.get_feature = function_bind(&CPUDevice::denoising_get_feature, this, _1, _2, _3, _4, _5, &denoising);
- denoising.functions.write_feature = function_bind(&CPUDevice::denoising_write_feature, this, _1, _2, _3, &denoising);
- denoising.functions.detect_outliers = function_bind(&CPUDevice::denoising_detect_outliers, this, _1, _2, _3, _4, &denoising);
-
- denoising.filter_area = make_int4(tile.x, tile.y, tile.w, tile.h);
- denoising.render_buffer.samples = tile.sample;
- denoising.buffer.gpu_temporary_mem = false;
-
- denoising.run_denoising(&tile);
- }
-
- void thread_render(DeviceTask& task)
- {
- if(task_pool.canceled()) {
- if(task.need_finish_queue == false)
- return;
- }
-
- /* allocate buffer for kernel globals */
- device_only_memory<KernelGlobals> kgbuffer(this, "kernel_globals");
- kgbuffer.alloc_to_device(1);
-
- KernelGlobals *kg = new ((void*) kgbuffer.device_pointer) KernelGlobals(thread_kernel_globals_init());
-
- profiler.add_state(&kg->profiler);
-
- CPUSplitKernel *split_kernel = NULL;
- if(use_split_kernel) {
- split_kernel = new CPUSplitKernel(this);
- if(!split_kernel->load_kernels(requested_features)) {
- thread_kernel_globals_free((KernelGlobals*)kgbuffer.device_pointer);
- kgbuffer.free();
- delete split_kernel;
- return;
- }
- }
-
- RenderTile tile;
- DenoisingTask denoising(this, task);
- denoising.profiler = &kg->profiler;
-
- while(task.acquire_tile(this, tile)) {
- if(tile.task == RenderTile::PATH_TRACE) {
- if(use_split_kernel) {
- device_only_memory<uchar> void_buffer(this, "void_buffer");
- split_kernel->path_trace(&task, tile, kgbuffer, void_buffer);
- }
- else {
- path_trace(task, tile, kg);
- }
- }
- else if(tile.task == RenderTile::DENOISE) {
- denoise(denoising, tile);
- task.update_progress(&tile, tile.w*tile.h);
- }
-
- task.release_tile(tile);
-
- if(task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
- }
-
- profiler.remove_state(&kg->profiler);
-
- thread_kernel_globals_free((KernelGlobals*)kgbuffer.device_pointer);
- kg->~KernelGlobals();
- kgbuffer.free();
- delete split_kernel;
- }
-
- void thread_film_convert(DeviceTask& task)
- {
- float sample_scale = 1.0f/(task.sample + 1);
-
- if(task.rgba_half) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- convert_to_half_float_kernel()(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
- else {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- convert_to_byte_kernel()(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
-
- }
- }
-
- void thread_shader(DeviceTask& task)
- {
- KernelGlobals kg = kernel_globals;
+ }
+
+ void thread_run(DeviceTask *task)
+ {
+ if (task->type == DeviceTask::RENDER) {
+ thread_render(*task);
+ }
+ else if (task->type == DeviceTask::FILM_CONVERT)
+ thread_film_convert(*task);
+ else if (task->type == DeviceTask::SHADER)
+ thread_shader(*task);
+ }
+
+ class CPUDeviceTask : public DeviceTask {
+ public:
+ CPUDeviceTask(CPUDevice *device, DeviceTask &task) : DeviceTask(task)
+ {
+ run = function_bind(&CPUDevice::thread_run, device, this);
+ }
+ };
+
+ bool denoising_non_local_means(device_ptr image_ptr,
+ device_ptr guide_ptr,
+ device_ptr variance_ptr,
+ device_ptr out_ptr,
+ DenoisingTask *task)
+ {
+ ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_NON_LOCAL_MEANS);
+
+ int4 rect = task->rect;
+ int r = task->nlm_state.r;
+ int f = task->nlm_state.f;
+ float a = task->nlm_state.a;
+ float k_2 = task->nlm_state.k_2;
+
+ int w = align_up(rect.z - rect.x, 4);
+ int h = rect.w - rect.y;
+ int stride = task->buffer.stride;
+ int channel_offset = task->nlm_state.is_color ? task->buffer.pass_stride : 0;
+
+ float *temporary_mem = (float *)task->buffer.temporary_mem.device_pointer;
+ float *blurDifference = temporary_mem;
+ float *difference = temporary_mem + task->buffer.pass_stride;
+ float *weightAccum = temporary_mem + 2 * task->buffer.pass_stride;
+
+ memset(weightAccum, 0, sizeof(float) * w * h);
+ memset((float *)out_ptr, 0, sizeof(float) * w * h);
+
+ for (int i = 0; i < (2 * r + 1) * (2 * r + 1); i++) {
+ int dy = i / (2 * r + 1) - r;
+ int dx = i % (2 * r + 1) - r;
+
+ int local_rect[4] = {
+ max(0, -dx), max(0, -dy), rect.z - rect.x - max(0, dx), rect.w - rect.y - max(0, dy)};
+ filter_nlm_calc_difference_kernel()(dx,
+ dy,
+ (float *)guide_ptr,
+ (float *)variance_ptr,
+ NULL,
+ difference,
+ local_rect,
+ w,
+ channel_offset,
+ 0,
+ a,
+ k_2);
+
+ filter_nlm_blur_kernel()(difference, blurDifference, local_rect, w, f);
+ filter_nlm_calc_weight_kernel()(blurDifference, difference, local_rect, w, f);
+ filter_nlm_blur_kernel()(difference, blurDifference, local_rect, w, f);
+
+ filter_nlm_update_output_kernel()(dx,
+ dy,
+ blurDifference,
+ (float *)image_ptr,
+ difference,
+ (float *)out_ptr,
+ weightAccum,
+ local_rect,
+ channel_offset,
+ stride,
+ f);
+ }
+
+ int local_rect[4] = {0, 0, rect.z - rect.x, rect.w - rect.y};
+ filter_nlm_normalize_kernel()((float *)out_ptr, weightAccum, local_rect, w);
+
+ return true;
+ }
+
+ bool denoising_construct_transform(DenoisingTask *task)
+ {
+ ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_CONSTRUCT_TRANSFORM);
+
+ for (int y = 0; y < task->filter_area.w; y++) {
+ for (int x = 0; x < task->filter_area.z; x++) {
+ filter_construct_transform_kernel()((float *)task->buffer.mem.device_pointer,
+ task->tile_info,
+ x + task->filter_area.x,
+ y + task->filter_area.y,
+ y * task->filter_area.z + x,
+ (float *)task->storage.transform.device_pointer,
+ (int *)task->storage.rank.device_pointer,
+ &task->rect.x,
+ task->buffer.pass_stride,
+ task->buffer.frame_stride,
+ task->buffer.use_time,
+ task->radius,
+ task->pca_threshold);
+ }
+ }
+ return true;
+ }
+
+ bool denoising_accumulate(device_ptr color_ptr,
+ device_ptr color_variance_ptr,
+ device_ptr scale_ptr,
+ int frame,
+ DenoisingTask *task)
+ {
+ ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_RECONSTRUCT);
+
+ float *temporary_mem = (float *)task->buffer.temporary_mem.device_pointer;
+ float *difference = temporary_mem;
+ float *blurDifference = temporary_mem + task->buffer.pass_stride;
+
+ int r = task->radius;
+ int frame_offset = frame * task->buffer.frame_stride;
+ for (int i = 0; i < (2 * r + 1) * (2 * r + 1); i++) {
+ int dy = i / (2 * r + 1) - r;
+ int dx = i % (2 * r + 1) - r;
+
+ int local_rect[4] = {max(0, -dx),
+ max(0, -dy),
+ task->reconstruction_state.source_w - max(0, dx),
+ task->reconstruction_state.source_h - max(0, dy)};
+ filter_nlm_calc_difference_kernel()(dx,
+ dy,
+ (float *)color_ptr,
+ (float *)color_variance_ptr,
+ (float *)scale_ptr,
+ difference,
+ local_rect,
+ task->buffer.stride,
+ task->buffer.pass_stride,
+ frame_offset,
+ 1.0f,
+ task->nlm_k_2);
+ filter_nlm_blur_kernel()(difference, blurDifference, local_rect, task->buffer.stride, 4);
+ filter_nlm_calc_weight_kernel()(
+ blurDifference, difference, local_rect, task->buffer.stride, 4);
+ filter_nlm_blur_kernel()(difference, blurDifference, local_rect, task->buffer.stride, 4);
+ filter_nlm_construct_gramian_kernel()(dx,
+ dy,
+ task->tile_info->frames[frame],
+ blurDifference,
+ (float *)task->buffer.mem.device_pointer,
+ (float *)task->storage.transform.device_pointer,
+ (int *)task->storage.rank.device_pointer,
+ (float *)task->storage.XtWX.device_pointer,
+ (float3 *)task->storage.XtWY.device_pointer,
+ local_rect,
+ &task->reconstruction_state.filter_window.x,
+ task->buffer.stride,
+ 4,
+ task->buffer.pass_stride,
+ frame_offset,
+ task->buffer.use_time);
+ }
+
+ return true;
+ }
+
+ bool denoising_solve(device_ptr output_ptr, DenoisingTask *task)
+ {
+ for (int y = 0; y < task->filter_area.w; y++) {
+ for (int x = 0; x < task->filter_area.z; x++) {
+ filter_finalize_kernel()(x,
+ y,
+ y * task->filter_area.z + x,
+ (float *)output_ptr,
+ (int *)task->storage.rank.device_pointer,
+ (float *)task->storage.XtWX.device_pointer,
+ (float3 *)task->storage.XtWY.device_pointer,
+ &task->reconstruction_state.buffer_params.x,
+ task->render_buffer.samples);
+ }
+ }
+ return true;
+ }
+
+ bool denoising_combine_halves(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ int r,
+ int4 rect,
+ DenoisingTask *task)
+ {
+ ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_COMBINE_HALVES);
+
+ for (int y = rect.y; y < rect.w; y++) {
+ for (int x = rect.x; x < rect.z; x++) {
+ filter_combine_halves_kernel()(x,
+ y,
+ (float *)mean_ptr,
+ (float *)variance_ptr,
+ (float *)a_ptr,
+ (float *)b_ptr,
+ &rect.x,
+ r);
+ }
+ }
+ return true;
+ }
+
+ bool denoising_divide_shadow(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr sample_variance_ptr,
+ device_ptr sv_variance_ptr,
+ device_ptr buffer_variance_ptr,
+ DenoisingTask *task)
+ {
+ ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_DIVIDE_SHADOW);
+
+ for (int y = task->rect.y; y < task->rect.w; y++) {
+ for (int x = task->rect.x; x < task->rect.z; x++) {
+ filter_divide_shadow_kernel()(task->render_buffer.samples,
+ task->tile_info,
+ x,
+ y,
+ (float *)a_ptr,
+ (float *)b_ptr,
+ (float *)sample_variance_ptr,
+ (float *)sv_variance_ptr,
+ (float *)buffer_variance_ptr,
+ &task->rect.x,
+ task->render_buffer.pass_stride,
+ task->render_buffer.offset);
+ }
+ }
+ return true;
+ }
+
+ bool denoising_get_feature(int mean_offset,
+ int variance_offset,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ float scale,
+ DenoisingTask *task)
+ {
+ ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_GET_FEATURE);
+
+ for (int y = task->rect.y; y < task->rect.w; y++) {
+ for (int x = task->rect.x; x < task->rect.z; x++) {
+ filter_get_feature_kernel()(task->render_buffer.samples,
+ task->tile_info,
+ mean_offset,
+ variance_offset,
+ x,
+ y,
+ (float *)mean_ptr,
+ (float *)variance_ptr,
+ scale,
+ &task->rect.x,
+ task->render_buffer.pass_stride,
+ task->render_buffer.offset);
+ }
+ }
+ return true;
+ }
+
+ bool denoising_write_feature(int out_offset,
+ device_ptr from_ptr,
+ device_ptr buffer_ptr,
+ DenoisingTask *task)
+ {
+ for (int y = 0; y < task->filter_area.w; y++) {
+ for (int x = 0; x < task->filter_area.z; x++) {
+ filter_write_feature_kernel()(task->render_buffer.samples,
+ x + task->filter_area.x,
+ y + task->filter_area.y,
+ &task->reconstruction_state.buffer_params.x,
+ (float *)from_ptr,
+ (float *)buffer_ptr,
+ out_offset,
+ &task->rect.x);
+ }
+ }
+ return true;
+ }
+
+ bool denoising_detect_outliers(device_ptr image_ptr,
+ device_ptr variance_ptr,
+ device_ptr depth_ptr,
+ device_ptr output_ptr,
+ DenoisingTask *task)
+ {
+ ProfilingHelper profiling(task->profiler, PROFILING_DENOISING_DETECT_OUTLIERS);
+
+ for (int y = task->rect.y; y < task->rect.w; y++) {
+ for (int x = task->rect.x; x < task->rect.z; x++) {
+ filter_detect_outliers_kernel()(x,
+ y,
+ (float *)image_ptr,
+ (float *)variance_ptr,
+ (float *)depth_ptr,
+ (float *)output_ptr,
+ &task->rect.x,
+ task->buffer.pass_stride);
+ }
+ }
+ return true;
+ }
+
+ void path_trace(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
+ {
+ const bool use_coverage = kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE;
+
+ scoped_timer timer(&tile.buffers->render_time);
+
+ Coverage coverage(kg, tile);
+ if (use_coverage) {
+ coverage.init_path_trace();
+ }
+
+ float *render_buffer = (float *)tile.buffer;
+ int start_sample = tile.start_sample;
+ int end_sample = tile.start_sample + tile.num_samples;
+
+ /* Needed for Embree. */
+ SIMD_SET_FLUSH_TO_ZERO;
+
+ for (int sample = start_sample; sample < end_sample; sample++) {
+ if (task.get_cancel() || task_pool.canceled()) {
+ if (task.need_finish_queue == false)
+ break;
+ }
+
+ for (int y = tile.y; y < tile.y + tile.h; y++) {
+ for (int x = tile.x; x < tile.x + tile.w; x++) {
+ if (use_coverage) {
+ coverage.init_pixel(x, y);
+ }
+ path_trace_kernel()(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
+ }
+ }
+
+ tile.sample = sample + 1;
+
+ task.update_progress(&tile, tile.w * tile.h);
+ }
+ if (use_coverage) {
+ coverage.finalize();
+ }
+ }
+
+ void denoise(DenoisingTask &denoising, RenderTile &tile)
+ {
+ ProfilingHelper profiling(denoising.profiler, PROFILING_DENOISING);
+
+ tile.sample = tile.start_sample + tile.num_samples;
+
+ denoising.functions.construct_transform = function_bind(
+ &CPUDevice::denoising_construct_transform, this, &denoising);
+ denoising.functions.accumulate = function_bind(
+ &CPUDevice::denoising_accumulate, this, _1, _2, _3, _4, &denoising);
+ denoising.functions.solve = function_bind(&CPUDevice::denoising_solve, this, _1, &denoising);
+ denoising.functions.divide_shadow = function_bind(
+ &CPUDevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising);
+ denoising.functions.non_local_means = function_bind(
+ &CPUDevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising);
+ denoising.functions.combine_halves = function_bind(
+ &CPUDevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising);
+ denoising.functions.get_feature = function_bind(
+ &CPUDevice::denoising_get_feature, this, _1, _2, _3, _4, _5, &denoising);
+ denoising.functions.write_feature = function_bind(
+ &CPUDevice::denoising_write_feature, this, _1, _2, _3, &denoising);
+ denoising.functions.detect_outliers = function_bind(
+ &CPUDevice::denoising_detect_outliers, this, _1, _2, _3, _4, &denoising);
+
+ denoising.filter_area = make_int4(tile.x, tile.y, tile.w, tile.h);
+ denoising.render_buffer.samples = tile.sample;
+ denoising.buffer.gpu_temporary_mem = false;
+
+ denoising.run_denoising(&tile);
+ }
+
+ void thread_render(DeviceTask &task)
+ {
+ if (task_pool.canceled()) {
+ if (task.need_finish_queue == false)
+ return;
+ }
+
+ /* allocate buffer for kernel globals */
+ device_only_memory<KernelGlobals> kgbuffer(this, "kernel_globals");
+ kgbuffer.alloc_to_device(1);
+
+ KernelGlobals *kg = new ((void *)kgbuffer.device_pointer)
+ KernelGlobals(thread_kernel_globals_init());
+
+ profiler.add_state(&kg->profiler);
+
+ CPUSplitKernel *split_kernel = NULL;
+ if (use_split_kernel) {
+ split_kernel = new CPUSplitKernel(this);
+ if (!split_kernel->load_kernels(requested_features)) {
+ thread_kernel_globals_free((KernelGlobals *)kgbuffer.device_pointer);
+ kgbuffer.free();
+ delete split_kernel;
+ return;
+ }
+ }
+
+ RenderTile tile;
+ DenoisingTask denoising(this, task);
+ denoising.profiler = &kg->profiler;
+
+ while (task.acquire_tile(this, tile)) {
+ if (tile.task == RenderTile::PATH_TRACE) {
+ if (use_split_kernel) {
+ device_only_memory<uchar> void_buffer(this, "void_buffer");
+ split_kernel->path_trace(&task, tile, kgbuffer, void_buffer);
+ }
+ else {
+ path_trace(task, tile, kg);
+ }
+ }
+ else if (tile.task == RenderTile::DENOISE) {
+ denoise(denoising, tile);
+ task.update_progress(&tile, tile.w * tile.h);
+ }
+
+ task.release_tile(tile);
+
+ if (task_pool.canceled()) {
+ if (task.need_finish_queue == false)
+ break;
+ }
+ }
+
+ profiler.remove_state(&kg->profiler);
+
+ thread_kernel_globals_free((KernelGlobals *)kgbuffer.device_pointer);
+ kg->~KernelGlobals();
+ kgbuffer.free();
+ delete split_kernel;
+ }
+
+ void thread_film_convert(DeviceTask &task)
+ {
+ float sample_scale = 1.0f / (task.sample + 1);
+
+ if (task.rgba_half) {
+ for (int y = task.y; y < task.y + task.h; y++)
+ for (int x = task.x; x < task.x + task.w; x++)
+ convert_to_half_float_kernel()(&kernel_globals,
+ (uchar4 *)task.rgba_half,
+ (float *)task.buffer,
+ sample_scale,
+ x,
+ y,
+ task.offset,
+ task.stride);
+ }
+ else {
+ for (int y = task.y; y < task.y + task.h; y++)
+ for (int x = task.x; x < task.x + task.w; x++)
+ convert_to_byte_kernel()(&kernel_globals,
+ (uchar4 *)task.rgba_byte,
+ (float *)task.buffer,
+ sample_scale,
+ x,
+ y,
+ task.offset,
+ task.stride);
+ }
+ }
+
+ void thread_shader(DeviceTask &task)
+ {
+ KernelGlobals kg = kernel_globals;
#ifdef WITH_OSL
- OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
+ OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
#endif
- for(int sample = 0; sample < task.num_samples; sample++) {
- for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
- shader_kernel()(&kg,
- (uint4*)task.shader_input,
- (float4*)task.shader_output,
- task.shader_eval_type,
- task.shader_filter,
- x,
- task.offset,
- sample);
-
- if(task.get_cancel() || task_pool.canceled())
- break;
-
- task.update_progress(NULL);
-
- }
+ for (int sample = 0; sample < task.num_samples; sample++) {
+ for (int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
+ shader_kernel()(&kg,
+ (uint4 *)task.shader_input,
+ (float4 *)task.shader_output,
+ task.shader_eval_type,
+ task.shader_filter,
+ x,
+ task.offset,
+ sample);
+
+ if (task.get_cancel() || task_pool.canceled())
+ break;
+
+ task.update_progress(NULL);
+ }
#ifdef WITH_OSL
- OSLShader::thread_free(&kg);
+ OSLShader::thread_free(&kg);
#endif
- }
-
- int get_split_task_count(DeviceTask& task)
- {
- if(task.type == DeviceTask::SHADER)
- return task.get_subtask_count(info.cpu_threads, 256);
- else
- return task.get_subtask_count(info.cpu_threads);
- }
-
- void task_add(DeviceTask& task)
- {
- /* Load texture info. */
- load_texture_info();
-
- /* split task into smaller ones */
- list<DeviceTask> tasks;
-
- if(task.type == DeviceTask::SHADER)
- task.split(tasks, info.cpu_threads, 256);
- else
- task.split(tasks, info.cpu_threads);
-
- foreach(DeviceTask& task, tasks)
- task_pool.push(new CPUDeviceTask(this, task));
- }
-
- void task_wait()
- {
- task_pool.wait_work();
- }
-
- void task_cancel()
- {
- task_pool.cancel();
- }
-
-protected:
- inline KernelGlobals thread_kernel_globals_init()
- {
- KernelGlobals kg = kernel_globals;
- kg.transparent_shadow_intersections = NULL;
- const int decoupled_count = sizeof(kg.decoupled_volume_steps) /
- sizeof(*kg.decoupled_volume_steps);
- for(int i = 0; i < decoupled_count; ++i) {
- kg.decoupled_volume_steps[i] = NULL;
- }
- kg.decoupled_volume_steps_index = 0;
- kg.coverage_asset = kg.coverage_object = kg.coverage_material = NULL;
+ }
+
+ int get_split_task_count(DeviceTask &task)
+ {
+ if (task.type == DeviceTask::SHADER)
+ return task.get_subtask_count(info.cpu_threads, 256);
+ else
+ return task.get_subtask_count(info.cpu_threads);
+ }
+
+ void task_add(DeviceTask &task)
+ {
+ /* Load texture info. */
+ load_texture_info();
+
+ /* split task into smaller ones */
+ list<DeviceTask> tasks;
+
+ if (task.type == DeviceTask::SHADER)
+ task.split(tasks, info.cpu_threads, 256);
+ else
+ task.split(tasks, info.cpu_threads);
+
+ foreach (DeviceTask &task, tasks)
+ task_pool.push(new CPUDeviceTask(this, task));
+ }
+
+ void task_wait()
+ {
+ task_pool.wait_work();
+ }
+
+ void task_cancel()
+ {
+ task_pool.cancel();
+ }
+
+ protected:
+ inline KernelGlobals thread_kernel_globals_init()
+ {
+ KernelGlobals kg = kernel_globals;
+ kg.transparent_shadow_intersections = NULL;
+ const int decoupled_count = sizeof(kg.decoupled_volume_steps) /
+ sizeof(*kg.decoupled_volume_steps);
+ for (int i = 0; i < decoupled_count; ++i) {
+ kg.decoupled_volume_steps[i] = NULL;
+ }
+ kg.decoupled_volume_steps_index = 0;
+ kg.coverage_asset = kg.coverage_object = kg.coverage_material = NULL;
#ifdef WITH_OSL
- OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
+ OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
#endif
- return kg;
- }
-
- inline void thread_kernel_globals_free(KernelGlobals *kg)
- {
- if(kg == NULL) {
- return;
- }
-
- if(kg->transparent_shadow_intersections != NULL) {
- free(kg->transparent_shadow_intersections);
- }
- const int decoupled_count = sizeof(kg->decoupled_volume_steps) /
- sizeof(*kg->decoupled_volume_steps);
- for(int i = 0; i < decoupled_count; ++i) {
- if(kg->decoupled_volume_steps[i] != NULL) {
- free(kg->decoupled_volume_steps[i]);
- }
- }
+ return kg;
+ }
+
+ inline void thread_kernel_globals_free(KernelGlobals *kg)
+ {
+ if (kg == NULL) {
+ return;
+ }
+
+ if (kg->transparent_shadow_intersections != NULL) {
+ free(kg->transparent_shadow_intersections);
+ }
+ const int decoupled_count = sizeof(kg->decoupled_volume_steps) /
+ sizeof(*kg->decoupled_volume_steps);
+ for (int i = 0; i < decoupled_count; ++i) {
+ if (kg->decoupled_volume_steps[i] != NULL) {
+ free(kg->decoupled_volume_steps[i]);
+ }
+ }
#ifdef WITH_OSL
- OSLShader::thread_free(kg);
+ OSLShader::thread_free(kg);
#endif
- }
+ }
- virtual bool load_kernels(const DeviceRequestedFeatures& requested_features_) {
- requested_features = requested_features_;
+ virtual bool load_kernels(const DeviceRequestedFeatures &requested_features_)
+ {
+ requested_features = requested_features_;
- return true;
- }
+ return true;
+ }
};
/* split kernel */
class CPUSplitKernelFunction : public SplitKernelFunction {
-public:
- CPUDevice* device;
- void (*func)(KernelGlobals *kg, KernelData *data);
-
- CPUSplitKernelFunction(CPUDevice* device) : device(device), func(NULL) {}
- ~CPUSplitKernelFunction() {}
-
- virtual bool enqueue(const KernelDimensions& dim, device_memory& kernel_globals, device_memory& data)
- {
- if(!func) {
- return false;
- }
-
- KernelGlobals *kg = (KernelGlobals*)kernel_globals.device_pointer;
- kg->global_size = make_int2(dim.global_size[0], dim.global_size[1]);
-
- for(int y = 0; y < dim.global_size[1]; y++) {
- for(int x = 0; x < dim.global_size[0]; x++) {
- kg->global_id = make_int2(x, y);
-
- func(kg, (KernelData*)data.device_pointer);
- }
- }
-
- return true;
- }
+ public:
+ CPUDevice *device;
+ void (*func)(KernelGlobals *kg, KernelData *data);
+
+ CPUSplitKernelFunction(CPUDevice *device) : device(device), func(NULL)
+ {
+ }
+ ~CPUSplitKernelFunction()
+ {
+ }
+
+ virtual bool enqueue(const KernelDimensions &dim,
+ device_memory &kernel_globals,
+ device_memory &data)
+ {
+ if (!func) {
+ return false;
+ }
+
+ KernelGlobals *kg = (KernelGlobals *)kernel_globals.device_pointer;
+ kg->global_size = make_int2(dim.global_size[0], dim.global_size[1]);
+
+ for (int y = 0; y < dim.global_size[1]; y++) {
+ for (int x = 0; x < dim.global_size[0]; x++) {
+ kg->global_id = make_int2(x, y);
+
+ func(kg, (KernelData *)data.device_pointer);
+ }
+ }
+
+ return true;
+ }
};
CPUSplitKernel::CPUSplitKernel(CPUDevice *device) : DeviceSplitKernel(device), device(device)
{
}
-bool CPUSplitKernel::enqueue_split_kernel_data_init(const KernelDimensions& dim,
- RenderTile& rtile,
+bool CPUSplitKernel::enqueue_split_kernel_data_init(const KernelDimensions &dim,
+ RenderTile &rtile,
int num_global_elements,
- device_memory& kernel_globals,
- device_memory& data,
- device_memory& split_data,
- device_memory& ray_state,
- device_memory& queue_index,
- device_memory& use_queues_flags,
- device_memory& work_pool_wgs)
+ device_memory &kernel_globals,
+ device_memory &data,
+ device_memory &split_data,
+ device_memory &ray_state,
+ device_memory &queue_index,
+ device_memory &use_queues_flags,
+ device_memory &work_pool_wgs)
{
- KernelGlobals *kg = (KernelGlobals*)kernel_globals.device_pointer;
- kg->global_size = make_int2(dim.global_size[0], dim.global_size[1]);
-
- for(int y = 0; y < dim.global_size[1]; y++) {
- for(int x = 0; x < dim.global_size[0]; x++) {
- kg->global_id = make_int2(x, y);
-
- device->data_init_kernel()((KernelGlobals*)kernel_globals.device_pointer,
- (KernelData*)data.device_pointer,
- (void*)split_data.device_pointer,
- num_global_elements,
- (char*)ray_state.device_pointer,
- rtile.start_sample,
- rtile.start_sample + rtile.num_samples,
- rtile.x,
- rtile.y,
- rtile.w,
- rtile.h,
- rtile.offset,
- rtile.stride,
- (int*)queue_index.device_pointer,
- dim.global_size[0] * dim.global_size[1],
- (char*)use_queues_flags.device_pointer,
- (uint*)work_pool_wgs.device_pointer,
- rtile.num_samples,
- (float*)rtile.buffer);
- }
- }
-
- return true;
+ KernelGlobals *kg = (KernelGlobals *)kernel_globals.device_pointer;
+ kg->global_size = make_int2(dim.global_size[0], dim.global_size[1]);
+
+ for (int y = 0; y < dim.global_size[1]; y++) {
+ for (int x = 0; x < dim.global_size[0]; x++) {
+ kg->global_id = make_int2(x, y);
+
+ device->data_init_kernel()((KernelGlobals *)kernel_globals.device_pointer,
+ (KernelData *)data.device_pointer,
+ (void *)split_data.device_pointer,
+ num_global_elements,
+ (char *)ray_state.device_pointer,
+ rtile.start_sample,
+ rtile.start_sample + rtile.num_samples,
+ rtile.x,
+ rtile.y,
+ rtile.w,
+ rtile.h,
+ rtile.offset,
+ rtile.stride,
+ (int *)queue_index.device_pointer,
+ dim.global_size[0] * dim.global_size[1],
+ (char *)use_queues_flags.device_pointer,
+ (uint *)work_pool_wgs.device_pointer,
+ rtile.num_samples,
+ (float *)rtile.buffer);
+ }
+ }
+
+ return true;
}
-SplitKernelFunction* CPUSplitKernel::get_split_kernel_function(const string& kernel_name,
- const DeviceRequestedFeatures&)
+SplitKernelFunction *CPUSplitKernel::get_split_kernel_function(const string &kernel_name,
+ const DeviceRequestedFeatures &)
{
- CPUSplitKernelFunction *kernel = new CPUSplitKernelFunction(device);
+ CPUSplitKernelFunction *kernel = new CPUSplitKernelFunction(device);
- kernel->func = device->split_kernels[kernel_name]();
- if(!kernel->func) {
- delete kernel;
- return NULL;
- }
+ kernel->func = device->split_kernels[kernel_name]();
+ if (!kernel->func) {
+ delete kernel;
+ return NULL;
+ }
- return kernel;
+ return kernel;
}
int2 CPUSplitKernel::split_kernel_local_size()
{
- return make_int2(1, 1);
+ return make_int2(1, 1);
}
-int2 CPUSplitKernel::split_kernel_global_size(device_memory& /*kg*/, device_memory& /*data*/, DeviceTask * /*task*/) {
- return make_int2(1, 1);
+int2 CPUSplitKernel::split_kernel_global_size(device_memory & /*kg*/,
+ device_memory & /*data*/,
+ DeviceTask * /*task*/)
+{
+ return make_int2(1, 1);
}
-uint64_t CPUSplitKernel::state_buffer_size(device_memory& kernel_globals, device_memory& /*data*/, size_t num_threads) {
- KernelGlobals *kg = (KernelGlobals*)kernel_globals.device_pointer;
+uint64_t CPUSplitKernel::state_buffer_size(device_memory &kernel_globals,
+ device_memory & /*data*/,
+ size_t num_threads)
+{
+ KernelGlobals *kg = (KernelGlobals *)kernel_globals.device_pointer;
- return split_data_buffer_size(kg, num_threads);
+ return split_data_buffer_size(kg, num_threads);
}
-Device *device_cpu_create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background)
+Device *device_cpu_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background)
{
- return new CPUDevice(info, stats, profiler, background);
+ return new CPUDevice(info, stats, profiler, background);
}
-void device_cpu_info(vector<DeviceInfo>& devices)
+void device_cpu_info(vector<DeviceInfo> &devices)
{
- DeviceInfo info;
-
- info.type = DEVICE_CPU;
- info.description = system_cpu_brand_string();
- info.id = "CPU";
- info.num = 0;
- info.has_volume_decoupled = true;
- info.has_osl = true;
- info.has_half_images = true;
- info.has_profiling = true;
-
- devices.insert(devices.begin(), info);
+ DeviceInfo info;
+
+ info.type = DEVICE_CPU;
+ info.description = system_cpu_brand_string();
+ info.id = "CPU";
+ info.num = 0;
+ info.has_volume_decoupled = true;
+ info.has_osl = true;
+ info.has_half_images = true;
+ info.has_profiling = true;
+
+ devices.insert(devices.begin(), info);
}
string device_cpu_capabilities()
{
- string capabilities = "";
- capabilities += system_cpu_support_sse2() ? "SSE2 " : "";
- capabilities += system_cpu_support_sse3() ? "SSE3 " : "";
- capabilities += system_cpu_support_sse41() ? "SSE41 " : "";
- capabilities += system_cpu_support_avx() ? "AVX " : "";
- capabilities += system_cpu_support_avx2() ? "AVX2" : "";
- if(capabilities[capabilities.size() - 1] == ' ')
- capabilities.resize(capabilities.size() - 1);
- return capabilities;
+ string capabilities = "";
+ capabilities += system_cpu_support_sse2() ? "SSE2 " : "";
+ capabilities += system_cpu_support_sse3() ? "SSE3 " : "";
+ capabilities += system_cpu_support_sse41() ? "SSE41 " : "";
+ capabilities += system_cpu_support_avx() ? "AVX " : "";
+ capabilities += system_cpu_support_avx2() ? "AVX2" : "";
+ if (capabilities[capabilities.size() - 1] == ' ')
+ capabilities.resize(capabilities.size() - 1);
+ return capabilities;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 3aa6bce155e..68bc3bd4045 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -62,2144 +62,2242 @@ namespace {
const char *cuewErrorString(CUresult result)
{
- /* We can only give error code here without major code duplication, that
- * should be enough since dynamic loading is only being disabled by folks
- * who knows what they're doing anyway.
- *
- * NOTE: Avoid call from several threads.
- */
- static string error;
- error = string_printf("%d", result);
- return error.c_str();
+ /* We can only give error code here without major code duplication, that
+ * should be enough since dynamic loading is only being disabled by folks
+ * who knows what they're doing anyway.
+ *
+ * NOTE: Avoid call from several threads.
+ */
+ static string error;
+ error = string_printf("%d", result);
+ return error.c_str();
}
const char *cuewCompilerPath()
{
- return CYCLES_CUDA_NVCC_EXECUTABLE;
+ return CYCLES_CUDA_NVCC_EXECUTABLE;
}
int cuewCompilerVersion()
{
- return (CUDA_VERSION / 100) + (CUDA_VERSION % 100 / 10);
+ return (CUDA_VERSION / 100) + (CUDA_VERSION % 100 / 10);
}
-} /* namespace */
-#endif /* WITH_CUDA_DYNLOAD */
+} /* namespace */
+#endif /* WITH_CUDA_DYNLOAD */
class CUDADevice;
class CUDASplitKernel : public DeviceSplitKernel {
- CUDADevice *device;
-public:
- explicit CUDASplitKernel(CUDADevice *device);
-
- virtual uint64_t state_buffer_size(device_memory& kg, device_memory& data, size_t num_threads);
-
- virtual bool enqueue_split_kernel_data_init(const KernelDimensions& dim,
- RenderTile& rtile,
- int num_global_elements,
- device_memory& kernel_globals,
- device_memory& kernel_data_,
- device_memory& split_data,
- device_memory& ray_state,
- device_memory& queue_index,
- device_memory& use_queues_flag,
- device_memory& work_pool_wgs);
-
- virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name,
- const DeviceRequestedFeatures&);
- virtual int2 split_kernel_local_size();
- virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask *task);
+ CUDADevice *device;
+
+ public:
+ explicit CUDASplitKernel(CUDADevice *device);
+
+ virtual uint64_t state_buffer_size(device_memory &kg, device_memory &data, size_t num_threads);
+
+ virtual bool enqueue_split_kernel_data_init(const KernelDimensions &dim,
+ RenderTile &rtile,
+ int num_global_elements,
+ device_memory &kernel_globals,
+ device_memory &kernel_data_,
+ device_memory &split_data,
+ device_memory &ray_state,
+ device_memory &queue_index,
+ device_memory &use_queues_flag,
+ device_memory &work_pool_wgs);
+
+ virtual SplitKernelFunction *get_split_kernel_function(const string &kernel_name,
+ const DeviceRequestedFeatures &);
+ virtual int2 split_kernel_local_size();
+ virtual int2 split_kernel_global_size(device_memory &kg, device_memory &data, DeviceTask *task);
};
/* Utility to push/pop CUDA context. */
class CUDAContextScope {
-public:
- CUDAContextScope(CUDADevice *device);
- ~CUDAContextScope();
+ public:
+ CUDAContextScope(CUDADevice *device);
+ ~CUDAContextScope();
-private:
- CUDADevice *device;
+ private:
+ CUDADevice *device;
};
-class CUDADevice : public Device
-{
-public:
- DedicatedTaskPool task_pool;
- CUdevice cuDevice;
- CUcontext cuContext;
- CUmodule cuModule, cuFilterModule;
- size_t device_texture_headroom;
- size_t device_working_headroom;
- bool move_texture_to_host;
- size_t map_host_used;
- size_t map_host_limit;
- int can_map_host;
- int cuDevId;
- int cuDevArchitecture;
- bool first_error;
- CUDASplitKernel *split_kernel;
-
- struct CUDAMem {
- CUDAMem()
- : texobject(0), array(0), map_host_pointer(0), free_map_host(false) {}
-
- CUtexObject texobject;
- CUarray array;
- void *map_host_pointer;
- bool free_map_host;
- };
- typedef map<device_memory*, CUDAMem> CUDAMemMap;
- CUDAMemMap cuda_mem_map;
-
- struct PixelMem {
- GLuint cuPBO;
- CUgraphicsResource cuPBOresource;
- GLuint cuTexId;
- int w, h;
- };
- map<device_ptr, PixelMem> pixel_mem_map;
-
- /* Bindless Textures */
- device_vector<TextureInfo> texture_info;
- bool need_texture_info;
-
- CUdeviceptr cuda_device_ptr(device_ptr mem)
- {
- return (CUdeviceptr)mem;
- }
-
- static bool have_precompiled_kernels()
- {
- string cubins_path = path_get("lib");
- return path_exists(cubins_path);
- }
-
- virtual bool show_samples() const
- {
- /* The CUDADevice only processes one tile at a time, so showing samples is fine. */
- return true;
- }
-
- virtual BVHLayoutMask get_bvh_layout_mask() const {
- return BVH_LAYOUT_BVH2;
- }
-
-/*#ifdef NDEBUG
+class CUDADevice : public Device {
+ public:
+ DedicatedTaskPool task_pool;
+ CUdevice cuDevice;
+ CUcontext cuContext;
+ CUmodule cuModule, cuFilterModule;
+ size_t device_texture_headroom;
+ size_t device_working_headroom;
+ bool move_texture_to_host;
+ size_t map_host_used;
+ size_t map_host_limit;
+ int can_map_host;
+ int cuDevId;
+ int cuDevArchitecture;
+ bool first_error;
+ CUDASplitKernel *split_kernel;
+
+ struct CUDAMem {
+ CUDAMem() : texobject(0), array(0), map_host_pointer(0), free_map_host(false)
+ {
+ }
+
+ CUtexObject texobject;
+ CUarray array;
+ void *map_host_pointer;
+ bool free_map_host;
+ };
+ typedef map<device_memory *, CUDAMem> CUDAMemMap;
+ CUDAMemMap cuda_mem_map;
+
+ struct PixelMem {
+ GLuint cuPBO;
+ CUgraphicsResource cuPBOresource;
+ GLuint cuTexId;
+ int w, h;
+ };
+ map<device_ptr, PixelMem> pixel_mem_map;
+
+ /* Bindless Textures */
+ device_vector<TextureInfo> texture_info;
+ bool need_texture_info;
+
+ CUdeviceptr cuda_device_ptr(device_ptr mem)
+ {
+ return (CUdeviceptr)mem;
+ }
+
+ static bool have_precompiled_kernels()
+ {
+ string cubins_path = path_get("lib");
+ return path_exists(cubins_path);
+ }
+
+ virtual bool show_samples() const
+ {
+ /* The CUDADevice only processes one tile at a time, so showing samples is fine. */
+ return true;
+ }
+
+ virtual BVHLayoutMask get_bvh_layout_mask() const
+ {
+ return BVH_LAYOUT_BVH2;
+ }
+
+ /*#ifdef NDEBUG
#define cuda_abort()
#else
#define cuda_abort() abort()
#endif*/
- void cuda_error_documentation()
- {
- if(first_error) {
- fprintf(stderr, "\nRefer to the Cycles GPU rendering documentation for possible solutions:\n");
- fprintf(stderr, "https://docs.blender.org/manual/en/dev/render/cycles/gpu_rendering.html\n\n");
- first_error = false;
- }
- }
+ void cuda_error_documentation()
+ {
+ if (first_error) {
+ fprintf(stderr,
+ "\nRefer to the Cycles GPU rendering documentation for possible solutions:\n");
+ fprintf(stderr,
+ "https://docs.blender.org/manual/en/dev/render/cycles/gpu_rendering.html\n\n");
+ first_error = false;
+ }
+ }
#define cuda_assert(stmt) \
- { \
- CUresult result = stmt; \
- \
- if(result != CUDA_SUCCESS) { \
- string message = string_printf("CUDA error: %s in %s, line %d", cuewErrorString(result), #stmt, __LINE__); \
- if(error_msg == "") \
- error_msg = message; \
- fprintf(stderr, "%s\n", message.c_str()); \
- /*cuda_abort();*/ \
- cuda_error_documentation(); \
- } \
- } (void) 0
-
- bool cuda_error_(CUresult result, const string& stmt)
- {
- if(result == CUDA_SUCCESS)
- return false;
-
- string message = string_printf("CUDA error at %s: %s", stmt.c_str(), cuewErrorString(result));
- if(error_msg == "")
- error_msg = message;
- fprintf(stderr, "%s\n", message.c_str());
- cuda_error_documentation();
- return true;
- }
+ { \
+ CUresult result = stmt; \
+\
+ if (result != CUDA_SUCCESS) { \
+ string message = string_printf( \
+ "CUDA error: %s in %s, line %d", cuewErrorString(result), #stmt, __LINE__); \
+ if (error_msg == "") \
+ error_msg = message; \
+ fprintf(stderr, "%s\n", message.c_str()); \
+ /*cuda_abort();*/ \
+ cuda_error_documentation(); \
+ } \
+ } \
+ (void)0
+
+ bool cuda_error_(CUresult result, const string &stmt)
+ {
+ if (result == CUDA_SUCCESS)
+ return false;
+
+ string message = string_printf("CUDA error at %s: %s", stmt.c_str(), cuewErrorString(result));
+ if (error_msg == "")
+ error_msg = message;
+ fprintf(stderr, "%s\n", message.c_str());
+ cuda_error_documentation();
+ return true;
+ }
#define cuda_error(stmt) cuda_error_(stmt, #stmt)
- void cuda_error_message(const string& message)
- {
- if(error_msg == "")
- error_msg = message;
- fprintf(stderr, "%s\n", message.c_str());
- cuda_error_documentation();
- }
-
- CUDADevice(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background_)
- : Device(info, stats, profiler, background_),
- texture_info(this, "__texture_info", MEM_TEXTURE)
- {
- first_error = true;
- background = background_;
-
- cuDevId = info.num;
- cuDevice = 0;
- cuContext = 0;
-
- cuModule = 0;
- cuFilterModule = 0;
-
- split_kernel = NULL;
-
- need_texture_info = false;
-
- device_texture_headroom = 0;
- device_working_headroom = 0;
- move_texture_to_host = false;
- map_host_limit = 0;
- map_host_used = 0;
- can_map_host = 0;
-
- /* Intialize CUDA. */
- if(cuda_error(cuInit(0)))
- return;
-
- /* Setup device and context. */
- if(cuda_error(cuDeviceGet(&cuDevice, cuDevId)))
- return;
-
- /* CU_CTX_MAP_HOST for mapping host memory when out of device memory.
- * CU_CTX_LMEM_RESIZE_TO_MAX for reserving local memory ahead of render,
- * so we can predict which memory to map to host. */
- cuda_assert(cuDeviceGetAttribute(&can_map_host, CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, cuDevice));
-
- unsigned int ctx_flags = CU_CTX_LMEM_RESIZE_TO_MAX;
- if(can_map_host) {
- ctx_flags |= CU_CTX_MAP_HOST;
- init_host_memory();
- }
-
- /* Create context. */
- CUresult result;
-
- if(background) {
- result = cuCtxCreate(&cuContext, ctx_flags, cuDevice);
- }
- else {
- result = cuGLCtxCreate(&cuContext, ctx_flags, cuDevice);
-
- if(result != CUDA_SUCCESS) {
- result = cuCtxCreate(&cuContext, ctx_flags, cuDevice);
- background = true;
- }
- }
-
- if(cuda_error_(result, "cuCtxCreate"))
- return;
-
- int major, minor;
- cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId);
- cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId);
- cuDevArchitecture = major*100 + minor*10;
-
- /* Pop context set by cuCtxCreate. */
- cuCtxPopCurrent(NULL);
- }
-
- ~CUDADevice()
- {
- task_pool.stop();
-
- delete split_kernel;
-
- texture_info.free();
-
- cuda_assert(cuCtxDestroy(cuContext));
- }
-
- bool support_device(const DeviceRequestedFeatures& /*requested_features*/)
- {
- int major, minor;
- cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId);
- cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId);
-
- /* We only support sm_30 and above */
- if(major < 3) {
- cuda_error_message(string_printf("CUDA device supported only with compute capability 3.0 or up, found %d.%d.", major, minor));
- return false;
- }
-
- return true;
- }
-
- bool use_adaptive_compilation()
- {
- return DebugFlags().cuda.adaptive_compile;
- }
-
- bool use_split_kernel()
- {
- return DebugFlags().cuda.split_kernel;
- }
-
- /* Common NVCC flags which stays the same regardless of shading model,
- * kernel sources md5 and only depends on compiler or compilation settings.
- */
- string compile_kernel_get_common_cflags(
- const DeviceRequestedFeatures& requested_features,
- bool filter=false, bool split=false)
- {
- const int machine = system_cpu_bits();
- const string source_path = path_get("source");
- const string include_path = source_path;
- string cflags = string_printf("-m%d "
- "--ptxas-options=\"-v\" "
- "--use_fast_math "
- "-DNVCC "
- "-I\"%s\"",
- machine,
- include_path.c_str());
- if(!filter && use_adaptive_compilation()) {
- cflags += " " + requested_features.get_build_options();
- }
- const char *extra_cflags = getenv("CYCLES_CUDA_EXTRA_CFLAGS");
- if(extra_cflags) {
- cflags += string(" ") + string(extra_cflags);
- }
+ void cuda_error_message(const string &message)
+ {
+ if (error_msg == "")
+ error_msg = message;
+ fprintf(stderr, "%s\n", message.c_str());
+ cuda_error_documentation();
+ }
+
+ CUDADevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background_)
+ : Device(info, stats, profiler, background_),
+ texture_info(this, "__texture_info", MEM_TEXTURE)
+ {
+ first_error = true;
+ background = background_;
+
+ cuDevId = info.num;
+ cuDevice = 0;
+ cuContext = 0;
+
+ cuModule = 0;
+ cuFilterModule = 0;
+
+ split_kernel = NULL;
+
+ need_texture_info = false;
+
+ device_texture_headroom = 0;
+ device_working_headroom = 0;
+ move_texture_to_host = false;
+ map_host_limit = 0;
+ map_host_used = 0;
+ can_map_host = 0;
+
+ /* Intialize CUDA. */
+ if (cuda_error(cuInit(0)))
+ return;
+
+ /* Setup device and context. */
+ if (cuda_error(cuDeviceGet(&cuDevice, cuDevId)))
+ return;
+
+ /* CU_CTX_MAP_HOST for mapping host memory when out of device memory.
+ * CU_CTX_LMEM_RESIZE_TO_MAX for reserving local memory ahead of render,
+ * so we can predict which memory to map to host. */
+ cuda_assert(
+ cuDeviceGetAttribute(&can_map_host, CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, cuDevice));
+
+ unsigned int ctx_flags = CU_CTX_LMEM_RESIZE_TO_MAX;
+ if (can_map_host) {
+ ctx_flags |= CU_CTX_MAP_HOST;
+ init_host_memory();
+ }
+
+ /* Create context. */
+ CUresult result;
+
+ if (background) {
+ result = cuCtxCreate(&cuContext, ctx_flags, cuDevice);
+ }
+ else {
+ result = cuGLCtxCreate(&cuContext, ctx_flags, cuDevice);
+
+ if (result != CUDA_SUCCESS) {
+ result = cuCtxCreate(&cuContext, ctx_flags, cuDevice);
+ background = true;
+ }
+ }
+
+ if (cuda_error_(result, "cuCtxCreate"))
+ return;
+
+ int major, minor;
+ cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId);
+ cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId);
+ cuDevArchitecture = major * 100 + minor * 10;
+
+ /* Pop context set by cuCtxCreate. */
+ cuCtxPopCurrent(NULL);
+ }
+
+ ~CUDADevice()
+ {
+ task_pool.stop();
+
+ delete split_kernel;
+
+ texture_info.free();
+
+ cuda_assert(cuCtxDestroy(cuContext));
+ }
+
+ bool support_device(const DeviceRequestedFeatures & /*requested_features*/)
+ {
+ int major, minor;
+ cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId);
+ cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId);
+
+ /* We only support sm_30 and above */
+ if (major < 3) {
+ cuda_error_message(string_printf(
+ "CUDA device supported only with compute capability 3.0 or up, found %d.%d.",
+ major,
+ minor));
+ return false;
+ }
+
+ return true;
+ }
+
+ bool use_adaptive_compilation()
+ {
+ return DebugFlags().cuda.adaptive_compile;
+ }
+
+ bool use_split_kernel()
+ {
+ return DebugFlags().cuda.split_kernel;
+ }
+
+ /* Common NVCC flags which stays the same regardless of shading model,
+ * kernel sources md5 and only depends on compiler or compilation settings.
+ */
+ string compile_kernel_get_common_cflags(const DeviceRequestedFeatures &requested_features,
+ bool filter = false,
+ bool split = false)
+ {
+ const int machine = system_cpu_bits();
+ const string source_path = path_get("source");
+ const string include_path = source_path;
+ string cflags = string_printf(
+ "-m%d "
+ "--ptxas-options=\"-v\" "
+ "--use_fast_math "
+ "-DNVCC "
+ "-I\"%s\"",
+ machine,
+ include_path.c_str());
+ if (!filter && use_adaptive_compilation()) {
+ cflags += " " + requested_features.get_build_options();
+ }
+ const char *extra_cflags = getenv("CYCLES_CUDA_EXTRA_CFLAGS");
+ if (extra_cflags) {
+ cflags += string(" ") + string(extra_cflags);
+ }
#ifdef WITH_CYCLES_DEBUG
- cflags += " -D__KERNEL_DEBUG__";
+ cflags += " -D__KERNEL_DEBUG__";
#endif
- if(split) {
- cflags += " -D__SPLIT__";
- }
-
- return cflags;
- }
-
- bool compile_check_compiler() {
- const char *nvcc = cuewCompilerPath();
- if(nvcc == NULL) {
- cuda_error_message("CUDA nvcc compiler not found. "
- "Install CUDA toolkit in default location.");
- return false;
- }
- const int cuda_version = cuewCompilerVersion();
- VLOG(1) << "Found nvcc " << nvcc
- << ", CUDA version " << cuda_version
- << ".";
- const int major = cuda_version / 10, minor = cuda_version % 10;
- if(cuda_version == 0) {
- cuda_error_message("CUDA nvcc compiler version could not be parsed.");
- return false;
- }
- if(cuda_version < 80) {
- printf("Unsupported CUDA version %d.%d detected, "
- "you need CUDA 8.0 or newer.\n",
- major, minor);
- return false;
- }
- else if(cuda_version != 101) {
- printf("CUDA version %d.%d detected, build may succeed but only "
- "CUDA 10.1 is officially supported.\n",
- major, minor);
- }
- return true;
- }
-
- string compile_kernel(const DeviceRequestedFeatures& requested_features,
- bool filter=false, bool split=false)
- {
- const char *name, *source;
- if(filter) {
- name = "filter";
- source = "filter.cu";
- }
- else if(split) {
- name = "kernel_split";
- source = "kernel_split.cu";
- }
- else {
- name = "kernel";
- source = "kernel.cu";
- }
- /* Compute cubin name. */
- int major, minor;
- cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId);
- cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId);
-
- /* Attempt to use kernel provided with Blender. */
- if(!use_adaptive_compilation()) {
- const string cubin = path_get(string_printf("lib/%s_sm_%d%d.cubin",
- name, major, minor));
- VLOG(1) << "Testing for pre-compiled kernel " << cubin << ".";
- if(path_exists(cubin)) {
- VLOG(1) << "Using precompiled kernel.";
- return cubin;
- }
- }
-
- const string common_cflags =
- compile_kernel_get_common_cflags(requested_features, filter, split);
-
- /* Try to use locally compiled kernel. */
- const string source_path = path_get("source");
- const string kernel_md5 = path_files_md5_hash(source_path);
-
- /* We include cflags into md5 so changing cuda toolkit or changing other
- * compiler command line arguments makes sure cubin gets re-built.
- */
- const string cubin_md5 = util_md5_string(kernel_md5 + common_cflags);
-
- const string cubin_file = string_printf("cycles_%s_sm%d%d_%s.cubin",
- name, major, minor,
- cubin_md5.c_str());
- const string cubin = path_cache_get(path_join("kernels", cubin_file));
- VLOG(1) << "Testing for locally compiled kernel " << cubin << ".";
- if(path_exists(cubin)) {
- VLOG(1) << "Using locally compiled kernel.";
- return cubin;
- }
+ if (split) {
+ cflags += " -D__SPLIT__";
+ }
+
+ return cflags;
+ }
+
+ bool compile_check_compiler()
+ {
+ const char *nvcc = cuewCompilerPath();
+ if (nvcc == NULL) {
+ cuda_error_message(
+ "CUDA nvcc compiler not found. "
+ "Install CUDA toolkit in default location.");
+ return false;
+ }
+ const int cuda_version = cuewCompilerVersion();
+ VLOG(1) << "Found nvcc " << nvcc << ", CUDA version " << cuda_version << ".";
+ const int major = cuda_version / 10, minor = cuda_version % 10;
+ if (cuda_version == 0) {
+ cuda_error_message("CUDA nvcc compiler version could not be parsed.");
+ return false;
+ }
+ if (cuda_version < 80) {
+ printf(
+ "Unsupported CUDA version %d.%d detected, "
+ "you need CUDA 8.0 or newer.\n",
+ major,
+ minor);
+ return false;
+ }
+ else if (cuda_version != 101) {
+ printf(
+ "CUDA version %d.%d detected, build may succeed but only "
+ "CUDA 10.1 is officially supported.\n",
+ major,
+ minor);
+ }
+ return true;
+ }
+
+ string compile_kernel(const DeviceRequestedFeatures &requested_features,
+ bool filter = false,
+ bool split = false)
+ {
+ const char *name, *source;
+ if (filter) {
+ name = "filter";
+ source = "filter.cu";
+ }
+ else if (split) {
+ name = "kernel_split";
+ source = "kernel_split.cu";
+ }
+ else {
+ name = "kernel";
+ source = "kernel.cu";
+ }
+ /* Compute cubin name. */
+ int major, minor;
+ cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId);
+ cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId);
+
+ /* Attempt to use kernel provided with Blender. */
+ if (!use_adaptive_compilation()) {
+ const string cubin = path_get(string_printf("lib/%s_sm_%d%d.cubin", name, major, minor));
+ VLOG(1) << "Testing for pre-compiled kernel " << cubin << ".";
+ if (path_exists(cubin)) {
+ VLOG(1) << "Using precompiled kernel.";
+ return cubin;
+ }
+ }
+
+ const string common_cflags = compile_kernel_get_common_cflags(
+ requested_features, filter, split);
+
+ /* Try to use locally compiled kernel. */
+ const string source_path = path_get("source");
+ const string kernel_md5 = path_files_md5_hash(source_path);
+
+ /* We include cflags into md5 so changing cuda toolkit or changing other
+ * compiler command line arguments makes sure cubin gets re-built.
+ */
+ const string cubin_md5 = util_md5_string(kernel_md5 + common_cflags);
+
+ const string cubin_file = string_printf(
+ "cycles_%s_sm%d%d_%s.cubin", name, major, minor, cubin_md5.c_str());
+ const string cubin = path_cache_get(path_join("kernels", cubin_file));
+ VLOG(1) << "Testing for locally compiled kernel " << cubin << ".";
+ if (path_exists(cubin)) {
+ VLOG(1) << "Using locally compiled kernel.";
+ return cubin;
+ }
#ifdef _WIN32
- if(have_precompiled_kernels()) {
- if(major < 3) {
- cuda_error_message(string_printf(
- "CUDA device requires compute capability 3.0 or up, "
- "found %d.%d. Your GPU is not supported.",
- major, minor));
- }
- else {
- cuda_error_message(string_printf(
- "CUDA binary kernel for this graphics card compute "
- "capability (%d.%d) not found.",
- major, minor));
- }
- return "";
- }
+ if (have_precompiled_kernels()) {
+ if (major < 3) {
+ cuda_error_message(
+ string_printf("CUDA device requires compute capability 3.0 or up, "
+ "found %d.%d. Your GPU is not supported.",
+ major,
+ minor));
+ }
+ else {
+ cuda_error_message(
+ string_printf("CUDA binary kernel for this graphics card compute "
+ "capability (%d.%d) not found.",
+ major,
+ minor));
+ }
+ return "";
+ }
#endif
- /* Compile. */
- if(!compile_check_compiler()) {
- return "";
- }
- const char *nvcc = cuewCompilerPath();
- const string kernel = path_join(
- path_join(source_path, "kernel"),
- path_join("kernels",
- path_join("cuda", source)));
- double starttime = time_dt();
- printf("Compiling CUDA kernel ...\n");
-
- path_create_directories(cubin);
-
- string command = string_printf("\"%s\" "
- "-arch=sm_%d%d "
- "--cubin \"%s\" "
- "-o \"%s\" "
- "%s ",
- nvcc,
- major, minor,
- kernel.c_str(),
- cubin.c_str(),
- common_cflags.c_str());
-
- printf("%s\n", command.c_str());
-
- if(system(command.c_str()) == -1) {
- cuda_error_message("Failed to execute compilation command, "
- "see console for details.");
- return "";
- }
-
- /* Verify if compilation succeeded */
- if(!path_exists(cubin)) {
- cuda_error_message("CUDA kernel compilation failed, "
- "see console for details.");
- return "";
- }
-
- printf("Kernel compilation finished in %.2lfs.\n", time_dt() - starttime);
-
- return cubin;
- }
-
- bool load_kernels(const DeviceRequestedFeatures& requested_features)
- {
- /* TODO(sergey): Support kernels re-load for CUDA devices.
- *
- * Currently re-loading kernel will invalidate memory pointers,
- * causing problems in cuCtxSynchronize.
- */
- if(cuFilterModule && cuModule) {
- VLOG(1) << "Skipping kernel reload, not currently supported.";
- return true;
- }
-
- /* check if cuda init succeeded */
- if(cuContext == 0)
- return false;
-
- /* check if GPU is supported */
- if(!support_device(requested_features))
- return false;
-
- /* get kernel */
- string cubin = compile_kernel(requested_features, false, use_split_kernel());
- if(cubin == "")
- return false;
-
- string filter_cubin = compile_kernel(requested_features, true, false);
- if(filter_cubin == "")
- return false;
-
- /* open module */
- CUDAContextScope scope(this);
-
- string cubin_data;
- CUresult result;
-
- if(path_read_text(cubin, cubin_data))
- result = cuModuleLoadData(&cuModule, cubin_data.c_str());
- else
- result = CUDA_ERROR_FILE_NOT_FOUND;
-
- if(cuda_error_(result, "cuModuleLoad"))
- cuda_error_message(string_printf("Failed loading CUDA kernel %s.", cubin.c_str()));
-
- if(path_read_text(filter_cubin, cubin_data))
- result = cuModuleLoadData(&cuFilterModule, cubin_data.c_str());
- else
- result = CUDA_ERROR_FILE_NOT_FOUND;
-
- if(cuda_error_(result, "cuModuleLoad"))
- cuda_error_message(string_printf("Failed loading CUDA kernel %s.", filter_cubin.c_str()));
-
- if(result == CUDA_SUCCESS) {
- reserve_local_memory(requested_features);
- }
-
- return (result == CUDA_SUCCESS);
- }
-
- void reserve_local_memory(const DeviceRequestedFeatures& requested_features)
- {
- if(use_split_kernel()) {
- /* Split kernel mostly uses global memory and adaptive compilation,
- * difficult to predict how much is needed currently. */
- return;
- }
-
- /* Together with CU_CTX_LMEM_RESIZE_TO_MAX, this reserves local memory
- * needed for kernel launches, so that we can reliably figure out when
- * to allocate scene data in mapped host memory. */
- CUDAContextScope scope(this);
-
- size_t total = 0, free_before = 0, free_after = 0;
- cuMemGetInfo(&free_before, &total);
-
- /* Get kernel function. */
- CUfunction cuPathTrace;
-
- if(requested_features.use_integrator_branched) {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
- }
- else {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
- }
-
- cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
-
- int min_blocks, num_threads_per_block;
- cuda_assert(cuOccupancyMaxPotentialBlockSize(&min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
-
- /* Launch kernel, using just 1 block appears sufficient to reserve
- * memory for all multiprocessors. It would be good to do this in
- * parallel for the multi GPU case still to make it faster. */
- CUdeviceptr d_work_tiles = 0;
- uint total_work_size = 0;
-
- void *args[] = {&d_work_tiles,
- &total_work_size};
-
- cuda_assert(cuLaunchKernel(cuPathTrace,
- 1, 1, 1,
- num_threads_per_block, 1, 1,
- 0, 0, args, 0));
-
- cuda_assert(cuCtxSynchronize());
-
- cuMemGetInfo(&free_after, &total);
- VLOG(1) << "Local memory reserved "
- << string_human_readable_number(free_before - free_after) << " bytes. ("
- << string_human_readable_size(free_before - free_after) << ")";
+ /* Compile. */
+ if (!compile_check_compiler()) {
+ return "";
+ }
+ const char *nvcc = cuewCompilerPath();
+ const string kernel = path_join(path_join(source_path, "kernel"),
+ path_join("kernels", path_join("cuda", source)));
+ double starttime = time_dt();
+ printf("Compiling CUDA kernel ...\n");
+
+ path_create_directories(cubin);
+
+ string command = string_printf(
+ "\"%s\" "
+ "-arch=sm_%d%d "
+ "--cubin \"%s\" "
+ "-o \"%s\" "
+ "%s ",
+ nvcc,
+ major,
+ minor,
+ kernel.c_str(),
+ cubin.c_str(),
+ common_cflags.c_str());
+
+ printf("%s\n", command.c_str());
+
+ if (system(command.c_str()) == -1) {
+ cuda_error_message(
+ "Failed to execute compilation command, "
+ "see console for details.");
+ return "";
+ }
+
+ /* Verify if compilation succeeded */
+ if (!path_exists(cubin)) {
+ cuda_error_message(
+ "CUDA kernel compilation failed, "
+ "see console for details.");
+ return "";
+ }
+
+ printf("Kernel compilation finished in %.2lfs.\n", time_dt() - starttime);
+
+ return cubin;
+ }
+
+ bool load_kernels(const DeviceRequestedFeatures &requested_features)
+ {
+ /* TODO(sergey): Support kernels re-load for CUDA devices.
+ *
+ * Currently re-loading kernel will invalidate memory pointers,
+ * causing problems in cuCtxSynchronize.
+ */
+ if (cuFilterModule && cuModule) {
+ VLOG(1) << "Skipping kernel reload, not currently supported.";
+ return true;
+ }
+
+ /* check if cuda init succeeded */
+ if (cuContext == 0)
+ return false;
+
+ /* check if GPU is supported */
+ if (!support_device(requested_features))
+ return false;
+
+ /* get kernel */
+ string cubin = compile_kernel(requested_features, false, use_split_kernel());
+ if (cubin == "")
+ return false;
+
+ string filter_cubin = compile_kernel(requested_features, true, false);
+ if (filter_cubin == "")
+ return false;
+
+ /* open module */
+ CUDAContextScope scope(this);
+
+ string cubin_data;
+ CUresult result;
+
+ if (path_read_text(cubin, cubin_data))
+ result = cuModuleLoadData(&cuModule, cubin_data.c_str());
+ else
+ result = CUDA_ERROR_FILE_NOT_FOUND;
+
+ if (cuda_error_(result, "cuModuleLoad"))
+ cuda_error_message(string_printf("Failed loading CUDA kernel %s.", cubin.c_str()));
+
+ if (path_read_text(filter_cubin, cubin_data))
+ result = cuModuleLoadData(&cuFilterModule, cubin_data.c_str());
+ else
+ result = CUDA_ERROR_FILE_NOT_FOUND;
+
+ if (cuda_error_(result, "cuModuleLoad"))
+ cuda_error_message(string_printf("Failed loading CUDA kernel %s.", filter_cubin.c_str()));
+
+ if (result == CUDA_SUCCESS) {
+ reserve_local_memory(requested_features);
+ }
+
+ return (result == CUDA_SUCCESS);
+ }
+
+ void reserve_local_memory(const DeviceRequestedFeatures &requested_features)
+ {
+ if (use_split_kernel()) {
+ /* Split kernel mostly uses global memory and adaptive compilation,
+ * difficult to predict how much is needed currently. */
+ return;
+ }
+
+ /* Together with CU_CTX_LMEM_RESIZE_TO_MAX, this reserves local memory
+ * needed for kernel launches, so that we can reliably figure out when
+ * to allocate scene data in mapped host memory. */
+ CUDAContextScope scope(this);
+
+ size_t total = 0, free_before = 0, free_after = 0;
+ cuMemGetInfo(&free_before, &total);
+
+ /* Get kernel function. */
+ CUfunction cuPathTrace;
+
+ if (requested_features.use_integrator_branched) {
+ cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
+ }
+ else {
+ cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
+ }
+
+ cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
+
+ int min_blocks, num_threads_per_block;
+ cuda_assert(cuOccupancyMaxPotentialBlockSize(
+ &min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
+
+ /* Launch kernel, using just 1 block appears sufficient to reserve
+ * memory for all multiprocessors. It would be good to do this in
+ * parallel for the multi GPU case still to make it faster. */
+ CUdeviceptr d_work_tiles = 0;
+ uint total_work_size = 0;
+
+ void *args[] = {&d_work_tiles, &total_work_size};
+
+ cuda_assert(cuLaunchKernel(cuPathTrace, 1, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
+
+ cuda_assert(cuCtxSynchronize());
+
+ cuMemGetInfo(&free_after, &total);
+ VLOG(1) << "Local memory reserved " << string_human_readable_number(free_before - free_after)
+ << " bytes. (" << string_human_readable_size(free_before - free_after) << ")";
#if 0
- /* For testing mapped host memory, fill up device memory. */
- const size_t keep_mb = 1024;
-
- while(free_after > keep_mb * 1024 * 1024LL) {
- CUdeviceptr tmp;
- cuda_assert(cuMemAlloc(&tmp, 10 * 1024 * 1024LL));
- cuMemGetInfo(&free_after, &total);
- }
+ /* For testing mapped host memory, fill up device memory. */
+ const size_t keep_mb = 1024;
+
+ while(free_after > keep_mb * 1024 * 1024LL) {
+ CUdeviceptr tmp;
+ cuda_assert(cuMemAlloc(&tmp, 10 * 1024 * 1024LL));
+ cuMemGetInfo(&free_after, &total);
+ }
#endif
- }
-
- void init_host_memory()
- {
- /* Limit amount of host mapped memory, because allocating too much can
- * cause system instability. Leave at least half or 4 GB of system
- * memory free, whichever is smaller. */
- size_t default_limit = 4 * 1024 * 1024 * 1024LL;
- size_t system_ram = system_physical_ram();
-
- if(system_ram > 0) {
- if(system_ram / 2 > default_limit) {
- map_host_limit = system_ram - default_limit;
- }
- else {
- map_host_limit = system_ram / 2;
- }
- }
- else {
- VLOG(1) << "Mapped host memory disabled, failed to get system RAM";
- map_host_limit = 0;
- }
-
- /* Amount of device memory to keep is free after texture memory
- * and working memory allocations respectively. We set the working
- * memory limit headroom lower so that some space is left after all
- * texture memory allocations. */
- device_working_headroom = 32 * 1024 * 1024LL; // 32MB
- device_texture_headroom = 128 * 1024 * 1024LL; // 128MB
-
- VLOG(1) << "Mapped host memory limit set to "
- << string_human_readable_number(map_host_limit) << " bytes. ("
- << string_human_readable_size(map_host_limit) << ")";
- }
-
- void load_texture_info()
- {
- if(need_texture_info) {
- texture_info.copy_to_device();
- need_texture_info = false;
- }
- }
-
- void move_textures_to_host(size_t size, bool for_texture)
- {
- /* Signal to reallocate textures in host memory only. */
- move_texture_to_host = true;
-
- while(size > 0) {
- /* Find suitable memory allocation to move. */
- device_memory *max_mem = NULL;
- size_t max_size = 0;
- bool max_is_image = false;
-
- foreach(CUDAMemMap::value_type& pair, cuda_mem_map) {
- device_memory& mem = *pair.first;
- CUDAMem *cmem = &pair.second;
-
- bool is_texture = (mem.type == MEM_TEXTURE) && (&mem != &texture_info);
- bool is_image = is_texture && (mem.data_height > 1);
-
- /* Can't move this type of memory. */
- if(!is_texture || cmem->array) {
- continue;
- }
-
- /* Already in host memory. */
- if(cmem->map_host_pointer) {
- continue;
- }
-
- /* For other textures, only move image textures. */
- if(for_texture && !is_image) {
- continue;
- }
-
- /* Try to move largest allocation, prefer moving images. */
- if(is_image > max_is_image ||
- (is_image == max_is_image && mem.device_size > max_size)) {
- max_is_image = is_image;
- max_size = mem.device_size;
- max_mem = &mem;
- }
- }
-
- /* Move to host memory. This part is mutex protected since
- * multiple CUDA devices could be moving the memory. The
- * first one will do it, and the rest will adopt the pointer. */
- if(max_mem) {
- VLOG(1) << "Move memory from device to host: " << max_mem->name;
-
- static thread_mutex move_mutex;
- thread_scoped_lock lock(move_mutex);
-
- /* Preserve the original device pointer, in case of multi device
- * we can't change it because the pointer mapping would break. */
- device_ptr prev_pointer = max_mem->device_pointer;
- size_t prev_size = max_mem->device_size;
-
- tex_free(*max_mem);
- tex_alloc(*max_mem);
- size = (max_size >= size)? 0: size - max_size;
-
- max_mem->device_pointer = prev_pointer;
- max_mem->device_size = prev_size;
- }
- else {
- break;
- }
- }
-
- /* Update texture info array with new pointers. */
- load_texture_info();
-
- move_texture_to_host = false;
- }
-
- CUDAMem *generic_alloc(device_memory& mem, size_t pitch_padding = 0)
- {
- CUDAContextScope scope(this);
-
- CUdeviceptr device_pointer = 0;
- size_t size = mem.memory_size() + pitch_padding;
-
- CUresult mem_alloc_result = CUDA_ERROR_OUT_OF_MEMORY;
- const char *status = "";
-
- /* First try allocating in device memory, respecting headroom. We make
- * an exception for texture info. It is small and frequently accessed,
- * so treat it as working memory.
- *
- * If there is not enough room for working memory, we will try to move
- * textures to host memory, assuming the performance impact would have
- * been worse for working memory. */
- bool is_texture = (mem.type == MEM_TEXTURE) && (&mem != &texture_info);
- bool is_image = is_texture && (mem.data_height > 1);
-
- size_t headroom = (is_texture)? device_texture_headroom:
- device_working_headroom;
-
- size_t total = 0, free = 0;
- cuMemGetInfo(&free, &total);
-
- /* Move textures to host memory if needed. */
- if(!move_texture_to_host && !is_image && (size + headroom) >= free) {
- move_textures_to_host(size + headroom - free, is_texture);
- cuMemGetInfo(&free, &total);
- }
-
- /* Allocate in device memory. */
- if(!move_texture_to_host && (size + headroom) < free) {
- mem_alloc_result = cuMemAlloc(&device_pointer, size);
- if(mem_alloc_result == CUDA_SUCCESS) {
- status = " in device memory";
- }
- }
-
- /* Fall back to mapped host memory if needed and possible. */
- void *map_host_pointer = 0;
- bool free_map_host = false;
-
- if(mem_alloc_result != CUDA_SUCCESS && can_map_host &&
- map_host_used + size < map_host_limit) {
- if(mem.shared_pointer) {
- /* Another device already allocated host memory. */
- mem_alloc_result = CUDA_SUCCESS;
- map_host_pointer = mem.shared_pointer;
- }
- else {
- /* Allocate host memory ourselves. */
- mem_alloc_result = cuMemHostAlloc(&map_host_pointer, size,
- CU_MEMHOSTALLOC_DEVICEMAP |
- CU_MEMHOSTALLOC_WRITECOMBINED);
- mem.shared_pointer = map_host_pointer;
- free_map_host = true;
- }
-
- if(mem_alloc_result == CUDA_SUCCESS) {
- cuda_assert(cuMemHostGetDevicePointer_v2(&device_pointer, mem.shared_pointer, 0));
- map_host_used += size;
- status = " in host memory";
-
- /* Replace host pointer with our host allocation. Only works if
- * CUDA memory layout is the same and has no pitch padding. Also
- * does not work if we move textures to host during a render,
- * since other devices might be using the memory. */
- if(!move_texture_to_host && pitch_padding == 0 &&
- mem.host_pointer && mem.host_pointer != mem.shared_pointer) {
- memcpy(mem.shared_pointer, mem.host_pointer, size);
- mem.host_free();
- mem.host_pointer = mem.shared_pointer;
- }
- }
- else {
- status = " failed, out of host memory";
- }
- }
- else if(mem_alloc_result != CUDA_SUCCESS) {
- status = " failed, out of device and host memory";
- }
-
- if(mem_alloc_result != CUDA_SUCCESS) {
- cuda_assert(mem_alloc_result);
- }
-
- if(mem.name) {
- VLOG(1) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")"
- << status;
- }
-
- mem.device_pointer = (device_ptr)device_pointer;
- mem.device_size = size;
- stats.mem_alloc(size);
-
- if(!mem.device_pointer) {
- return NULL;
- }
-
- /* Insert into map of allocations. */
- CUDAMem *cmem = &cuda_mem_map[&mem];
- cmem->map_host_pointer = map_host_pointer;
- cmem->free_map_host = free_map_host;
- return cmem;
- }
-
- void generic_copy_to(device_memory& mem)
- {
- if(mem.host_pointer && mem.device_pointer) {
- CUDAContextScope scope(this);
-
- if(mem.host_pointer != mem.shared_pointer) {
- cuda_assert(cuMemcpyHtoD(cuda_device_ptr(mem.device_pointer),
- mem.host_pointer,
- mem.memory_size()));
- }
- }
- }
-
- void generic_free(device_memory& mem)
- {
- if(mem.device_pointer) {
- CUDAContextScope scope(this);
- const CUDAMem& cmem = cuda_mem_map[&mem];
-
- if(cmem.map_host_pointer) {
- /* Free host memory. */
- if(cmem.free_map_host) {
- cuMemFreeHost(cmem.map_host_pointer);
- if(mem.host_pointer == mem.shared_pointer) {
- mem.host_pointer = 0;
- }
- mem.shared_pointer = 0;
- }
-
- map_host_used -= mem.device_size;
- }
- else {
- /* Free device memory. */
- cuMemFree(mem.device_pointer);
- }
-
- stats.mem_free(mem.device_size);
- mem.device_pointer = 0;
- mem.device_size = 0;
-
- cuda_mem_map.erase(cuda_mem_map.find(&mem));
- }
- }
-
- void mem_alloc(device_memory& mem)
- {
- if(mem.type == MEM_PIXELS && !background) {
- pixels_alloc(mem);
- }
- else if(mem.type == MEM_TEXTURE) {
- assert(!"mem_alloc not supported for textures.");
- }
- else {
- generic_alloc(mem);
- }
- }
-
- void mem_copy_to(device_memory& mem)
- {
- if(mem.type == MEM_PIXELS) {
- assert(!"mem_copy_to not supported for pixels.");
- }
- else if(mem.type == MEM_TEXTURE) {
- tex_free(mem);
- tex_alloc(mem);
- }
- else {
- if(!mem.device_pointer) {
- generic_alloc(mem);
- }
-
- generic_copy_to(mem);
- }
- }
-
- void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
- {
- if(mem.type == MEM_PIXELS && !background) {
- pixels_copy_from(mem, y, w, h);
- }
- else if(mem.type == MEM_TEXTURE) {
- assert(!"mem_copy_from not supported for textures.");
- }
- else {
- CUDAContextScope scope(this);
- size_t offset = elem*y*w;
- size_t size = elem*w*h;
-
- if(mem.host_pointer && mem.device_pointer) {
- cuda_assert(cuMemcpyDtoH((uchar*)mem.host_pointer + offset,
- (CUdeviceptr)(mem.device_pointer + offset), size));
- }
- else if(mem.host_pointer) {
- memset((char*)mem.host_pointer + offset, 0, size);
- }
- }
- }
-
- void mem_zero(device_memory& mem)
- {
- if(!mem.device_pointer) {
- mem_alloc(mem);
- }
-
- if(mem.host_pointer) {
- memset(mem.host_pointer, 0, mem.memory_size());
- }
-
- if(mem.device_pointer &&
- (!mem.host_pointer || mem.host_pointer != mem.shared_pointer)) {
- CUDAContextScope scope(this);
- cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()));
- }
- }
-
- void mem_free(device_memory& mem)
- {
- if(mem.type == MEM_PIXELS && !background) {
- pixels_free(mem);
- }
- else if(mem.type == MEM_TEXTURE) {
- tex_free(mem);
- }
- else {
- generic_free(mem);
- }
- }
-
- virtual device_ptr mem_alloc_sub_ptr(device_memory& mem, int offset, int /*size*/)
- {
- return (device_ptr) (((char*) mem.device_pointer) + mem.memory_elements_size(offset));
- }
-
- void const_copy_to(const char *name, void *host, size_t size)
- {
- CUDAContextScope scope(this);
- CUdeviceptr mem;
- size_t bytes;
-
- cuda_assert(cuModuleGetGlobal(&mem, &bytes, cuModule, name));
- //assert(bytes == size);
- cuda_assert(cuMemcpyHtoD(mem, host, size));
- }
-
- void tex_alloc(device_memory& mem)
- {
- CUDAContextScope scope(this);
-
- /* General variables for both architectures */
- string bind_name = mem.name;
- size_t dsize = datatype_size(mem.data_type);
- size_t size = mem.memory_size();
-
- CUaddress_mode address_mode = CU_TR_ADDRESS_MODE_WRAP;
- switch(mem.extension) {
- case EXTENSION_REPEAT:
- address_mode = CU_TR_ADDRESS_MODE_WRAP;
- break;
- case EXTENSION_EXTEND:
- address_mode = CU_TR_ADDRESS_MODE_CLAMP;
- break;
- case EXTENSION_CLIP:
- address_mode = CU_TR_ADDRESS_MODE_BORDER;
- break;
- default:
- assert(0);
- break;
- }
-
- CUfilter_mode filter_mode;
- if(mem.interpolation == INTERPOLATION_CLOSEST) {
- filter_mode = CU_TR_FILTER_MODE_POINT;
- }
- else {
- filter_mode = CU_TR_FILTER_MODE_LINEAR;
- }
-
- /* Data Storage */
- if(mem.interpolation == INTERPOLATION_NONE) {
- generic_alloc(mem);
- generic_copy_to(mem);
-
- CUdeviceptr cumem;
- size_t cubytes;
-
- cuda_assert(cuModuleGetGlobal(&cumem, &cubytes, cuModule, bind_name.c_str()));
-
- if(cubytes == 8) {
- /* 64 bit device pointer */
- uint64_t ptr = mem.device_pointer;
- cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes));
- }
- else {
- /* 32 bit device pointer */
- uint32_t ptr = (uint32_t)mem.device_pointer;
- cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes));
- }
- return;
- }
-
- /* Image Texture Storage */
- CUarray_format_enum format;
- switch(mem.data_type) {
- case TYPE_UCHAR: format = CU_AD_FORMAT_UNSIGNED_INT8; break;
- case TYPE_UINT16: format = CU_AD_FORMAT_UNSIGNED_INT16; break;
- case TYPE_UINT: format = CU_AD_FORMAT_UNSIGNED_INT32; break;
- case TYPE_INT: format = CU_AD_FORMAT_SIGNED_INT32; break;
- case TYPE_FLOAT: format = CU_AD_FORMAT_FLOAT; break;
- case TYPE_HALF: format = CU_AD_FORMAT_HALF; break;
- default: assert(0); return;
- }
-
- CUDAMem *cmem = NULL;
- CUarray array_3d = NULL;
- size_t src_pitch = mem.data_width * dsize * mem.data_elements;
- size_t dst_pitch = src_pitch;
-
- if(mem.data_depth > 1) {
- /* 3D texture using array, there is no API for linear memory. */
- CUDA_ARRAY3D_DESCRIPTOR desc;
-
- desc.Width = mem.data_width;
- desc.Height = mem.data_height;
- desc.Depth = mem.data_depth;
- desc.Format = format;
- desc.NumChannels = mem.data_elements;
- desc.Flags = 0;
-
- VLOG(1) << "Array 3D allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
-
- cuda_assert(cuArray3DCreate(&array_3d, &desc));
-
- if(!array_3d) {
- return;
- }
-
- CUDA_MEMCPY3D param;
- memset(&param, 0, sizeof(param));
- param.dstMemoryType = CU_MEMORYTYPE_ARRAY;
- param.dstArray = array_3d;
- param.srcMemoryType = CU_MEMORYTYPE_HOST;
- param.srcHost = mem.host_pointer;
- param.srcPitch = src_pitch;
- param.WidthInBytes = param.srcPitch;
- param.Height = mem.data_height;
- param.Depth = mem.data_depth;
-
- cuda_assert(cuMemcpy3D(&param));
-
- mem.device_pointer = (device_ptr)array_3d;
- mem.device_size = size;
- stats.mem_alloc(size);
-
- cmem = &cuda_mem_map[&mem];
- cmem->texobject = 0;
- cmem->array = array_3d;
- }
- else if(mem.data_height > 0) {
- /* 2D texture, using pitch aligned linear memory. */
- int alignment = 0;
- cuda_assert(cuDeviceGetAttribute(&alignment, CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT, cuDevice));
- dst_pitch = align_up(src_pitch, alignment);
- size_t dst_size = dst_pitch * mem.data_height;
-
- cmem = generic_alloc(mem, dst_size - mem.memory_size());
- if(!cmem) {
- return;
- }
-
- CUDA_MEMCPY2D param;
- memset(&param, 0, sizeof(param));
- param.dstMemoryType = CU_MEMORYTYPE_DEVICE;
- param.dstDevice = mem.device_pointer;
- param.dstPitch = dst_pitch;
- param.srcMemoryType = CU_MEMORYTYPE_HOST;
- param.srcHost = mem.host_pointer;
- param.srcPitch = src_pitch;
- param.WidthInBytes = param.srcPitch;
- param.Height = mem.data_height;
-
- cuda_assert(cuMemcpy2DUnaligned(&param));
- }
- else {
- /* 1D texture, using linear memory. */
- cmem = generic_alloc(mem);
- if(!cmem) {
- return;
- }
-
- cuda_assert(cuMemcpyHtoD(mem.device_pointer, mem.host_pointer, size));
- }
-
- /* Kepler+, bindless textures. */
- int flat_slot = 0;
- if(string_startswith(mem.name, "__tex_image")) {
- int pos = string(mem.name).rfind("_");
- flat_slot = atoi(mem.name + pos + 1);
- }
- else {
- assert(0);
- }
-
- CUDA_RESOURCE_DESC resDesc;
- memset(&resDesc, 0, sizeof(resDesc));
-
- if(array_3d) {
- resDesc.resType = CU_RESOURCE_TYPE_ARRAY;
- resDesc.res.array.hArray = array_3d;
- resDesc.flags = 0;
- }
- else if(mem.data_height > 0) {
- resDesc.resType = CU_RESOURCE_TYPE_PITCH2D;
- resDesc.res.pitch2D.devPtr = mem.device_pointer;
- resDesc.res.pitch2D.format = format;
- resDesc.res.pitch2D.numChannels = mem.data_elements;
- resDesc.res.pitch2D.height = mem.data_height;
- resDesc.res.pitch2D.width = mem.data_width;
- resDesc.res.pitch2D.pitchInBytes = dst_pitch;
- }
- else {
- resDesc.resType = CU_RESOURCE_TYPE_LINEAR;
- resDesc.res.linear.devPtr = mem.device_pointer;
- resDesc.res.linear.format = format;
- resDesc.res.linear.numChannels = mem.data_elements;
- resDesc.res.linear.sizeInBytes = mem.device_size;
- }
-
- CUDA_TEXTURE_DESC texDesc;
- memset(&texDesc, 0, sizeof(texDesc));
- texDesc.addressMode[0] = address_mode;
- texDesc.addressMode[1] = address_mode;
- texDesc.addressMode[2] = address_mode;
- texDesc.filterMode = filter_mode;
- texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
-
- cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
-
- /* Resize once */
- if(flat_slot >= texture_info.size()) {
- /* Allocate some slots in advance, to reduce amount
- * of re-allocations. */
- texture_info.resize(flat_slot + 128);
- }
-
- /* Set Mapping and tag that we need to (re-)upload to device */
- TextureInfo& info = texture_info[flat_slot];
- info.data = (uint64_t)cmem->texobject;
- info.cl_buffer = 0;
- info.interpolation = mem.interpolation;
- info.extension = mem.extension;
- info.width = mem.data_width;
- info.height = mem.data_height;
- info.depth = mem.data_depth;
- need_texture_info = true;
- }
-
- void tex_free(device_memory& mem)
- {
- if(mem.device_pointer) {
- CUDAContextScope scope(this);
- const CUDAMem& cmem = cuda_mem_map[&mem];
-
- if(cmem.texobject) {
- /* Free bindless texture. */
- cuTexObjectDestroy(cmem.texobject);
- }
-
- if(cmem.array) {
- /* Free array. */
- cuArrayDestroy(cmem.array);
- stats.mem_free(mem.device_size);
- mem.device_pointer = 0;
- mem.device_size = 0;
-
- cuda_mem_map.erase(cuda_mem_map.find(&mem));
- }
- else {
- generic_free(mem);
- }
- }
- }
-
-#define CUDA_GET_BLOCKSIZE(func, w, h) \
- int threads_per_block; \
- cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, func)); \
- int threads = (int)sqrt((float)threads_per_block); \
- int xblocks = ((w) + threads - 1)/threads; \
- int yblocks = ((h) + threads - 1)/threads;
-
-#define CUDA_LAUNCH_KERNEL(func, args) \
- cuda_assert(cuLaunchKernel(func, \
- xblocks, yblocks, 1, \
- threads, threads, 1, \
- 0, 0, args, 0));
+ }
+
+ void init_host_memory()
+ {
+ /* Limit amount of host mapped memory, because allocating too much can
+ * cause system instability. Leave at least half or 4 GB of system
+ * memory free, whichever is smaller. */
+ size_t default_limit = 4 * 1024 * 1024 * 1024LL;
+ size_t system_ram = system_physical_ram();
+
+ if (system_ram > 0) {
+ if (system_ram / 2 > default_limit) {
+ map_host_limit = system_ram - default_limit;
+ }
+ else {
+ map_host_limit = system_ram / 2;
+ }
+ }
+ else {
+ VLOG(1) << "Mapped host memory disabled, failed to get system RAM";
+ map_host_limit = 0;
+ }
+
+ /* Amount of device memory to keep is free after texture memory
+ * and working memory allocations respectively. We set the working
+ * memory limit headroom lower so that some space is left after all
+ * texture memory allocations. */
+ device_working_headroom = 32 * 1024 * 1024LL; // 32MB
+ device_texture_headroom = 128 * 1024 * 1024LL; // 128MB
+
+ VLOG(1) << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
+ << " bytes. (" << string_human_readable_size(map_host_limit) << ")";
+ }
+
+ void load_texture_info()
+ {
+ if (need_texture_info) {
+ texture_info.copy_to_device();
+ need_texture_info = false;
+ }
+ }
+
+ void move_textures_to_host(size_t size, bool for_texture)
+ {
+ /* Signal to reallocate textures in host memory only. */
+ move_texture_to_host = true;
+
+ while (size > 0) {
+ /* Find suitable memory allocation to move. */
+ device_memory *max_mem = NULL;
+ size_t max_size = 0;
+ bool max_is_image = false;
+
+ foreach (CUDAMemMap::value_type &pair, cuda_mem_map) {
+ device_memory &mem = *pair.first;
+ CUDAMem *cmem = &pair.second;
+
+ bool is_texture = (mem.type == MEM_TEXTURE) && (&mem != &texture_info);
+ bool is_image = is_texture && (mem.data_height > 1);
+
+ /* Can't move this type of memory. */
+ if (!is_texture || cmem->array) {
+ continue;
+ }
+
+ /* Already in host memory. */
+ if (cmem->map_host_pointer) {
+ continue;
+ }
+
+ /* For other textures, only move image textures. */
+ if (for_texture && !is_image) {
+ continue;
+ }
+
+ /* Try to move largest allocation, prefer moving images. */
+ if (is_image > max_is_image || (is_image == max_is_image && mem.device_size > max_size)) {
+ max_is_image = is_image;
+ max_size = mem.device_size;
+ max_mem = &mem;
+ }
+ }
+
+ /* Move to host memory. This part is mutex protected since
+ * multiple CUDA devices could be moving the memory. The
+ * first one will do it, and the rest will adopt the pointer. */
+ if (max_mem) {
+ VLOG(1) << "Move memory from device to host: " << max_mem->name;
+
+ static thread_mutex move_mutex;
+ thread_scoped_lock lock(move_mutex);
+
+ /* Preserve the original device pointer, in case of multi device
+ * we can't change it because the pointer mapping would break. */
+ device_ptr prev_pointer = max_mem->device_pointer;
+ size_t prev_size = max_mem->device_size;
+
+ tex_free(*max_mem);
+ tex_alloc(*max_mem);
+ size = (max_size >= size) ? 0 : size - max_size;
+
+ max_mem->device_pointer = prev_pointer;
+ max_mem->device_size = prev_size;
+ }
+ else {
+ break;
+ }
+ }
+
+ /* Update texture info array with new pointers. */
+ load_texture_info();
+
+ move_texture_to_host = false;
+ }
+
+ CUDAMem *generic_alloc(device_memory &mem, size_t pitch_padding = 0)
+ {
+ CUDAContextScope scope(this);
+
+ CUdeviceptr device_pointer = 0;
+ size_t size = mem.memory_size() + pitch_padding;
+
+ CUresult mem_alloc_result = CUDA_ERROR_OUT_OF_MEMORY;
+ const char *status = "";
+
+ /* First try allocating in device memory, respecting headroom. We make
+ * an exception for texture info. It is small and frequently accessed,
+ * so treat it as working memory.
+ *
+ * If there is not enough room for working memory, we will try to move
+ * textures to host memory, assuming the performance impact would have
+ * been worse for working memory. */
+ bool is_texture = (mem.type == MEM_TEXTURE) && (&mem != &texture_info);
+ bool is_image = is_texture && (mem.data_height > 1);
+
+ size_t headroom = (is_texture) ? device_texture_headroom : device_working_headroom;
+
+ size_t total = 0, free = 0;
+ cuMemGetInfo(&free, &total);
+
+ /* Move textures to host memory if needed. */
+ if (!move_texture_to_host && !is_image && (size + headroom) >= free) {
+ move_textures_to_host(size + headroom - free, is_texture);
+ cuMemGetInfo(&free, &total);
+ }
+
+ /* Allocate in device memory. */
+ if (!move_texture_to_host && (size + headroom) < free) {
+ mem_alloc_result = cuMemAlloc(&device_pointer, size);
+ if (mem_alloc_result == CUDA_SUCCESS) {
+ status = " in device memory";
+ }
+ }
+
+ /* Fall back to mapped host memory if needed and possible. */
+ void *map_host_pointer = 0;
+ bool free_map_host = false;
+
+ if (mem_alloc_result != CUDA_SUCCESS && can_map_host &&
+ map_host_used + size < map_host_limit) {
+ if (mem.shared_pointer) {
+ /* Another device already allocated host memory. */
+ mem_alloc_result = CUDA_SUCCESS;
+ map_host_pointer = mem.shared_pointer;
+ }
+ else {
+ /* Allocate host memory ourselves. */
+ mem_alloc_result = cuMemHostAlloc(
+ &map_host_pointer, size, CU_MEMHOSTALLOC_DEVICEMAP | CU_MEMHOSTALLOC_WRITECOMBINED);
+ mem.shared_pointer = map_host_pointer;
+ free_map_host = true;
+ }
+
+ if (mem_alloc_result == CUDA_SUCCESS) {
+ cuda_assert(cuMemHostGetDevicePointer_v2(&device_pointer, mem.shared_pointer, 0));
+ map_host_used += size;
+ status = " in host memory";
+
+ /* Replace host pointer with our host allocation. Only works if
+ * CUDA memory layout is the same and has no pitch padding. Also
+ * does not work if we move textures to host during a render,
+ * since other devices might be using the memory. */
+ if (!move_texture_to_host && pitch_padding == 0 && mem.host_pointer &&
+ mem.host_pointer != mem.shared_pointer) {
+ memcpy(mem.shared_pointer, mem.host_pointer, size);
+ mem.host_free();
+ mem.host_pointer = mem.shared_pointer;
+ }
+ }
+ else {
+ status = " failed, out of host memory";
+ }
+ }
+ else if (mem_alloc_result != CUDA_SUCCESS) {
+ status = " failed, out of device and host memory";
+ }
+
+ if (mem_alloc_result != CUDA_SUCCESS) {
+ cuda_assert(mem_alloc_result);
+ }
+
+ if (mem.name) {
+ VLOG(1) << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")" << status;
+ }
+
+ mem.device_pointer = (device_ptr)device_pointer;
+ mem.device_size = size;
+ stats.mem_alloc(size);
+
+ if (!mem.device_pointer) {
+ return NULL;
+ }
+
+ /* Insert into map of allocations. */
+ CUDAMem *cmem = &cuda_mem_map[&mem];
+ cmem->map_host_pointer = map_host_pointer;
+ cmem->free_map_host = free_map_host;
+ return cmem;
+ }
+
+ void generic_copy_to(device_memory &mem)
+ {
+ if (mem.host_pointer && mem.device_pointer) {
+ CUDAContextScope scope(this);
+
+ if (mem.host_pointer != mem.shared_pointer) {
+ cuda_assert(cuMemcpyHtoD(
+ cuda_device_ptr(mem.device_pointer), mem.host_pointer, mem.memory_size()));
+ }
+ }
+ }
+
+ void generic_free(device_memory &mem)
+ {
+ if (mem.device_pointer) {
+ CUDAContextScope scope(this);
+ const CUDAMem &cmem = cuda_mem_map[&mem];
+
+ if (cmem.map_host_pointer) {
+ /* Free host memory. */
+ if (cmem.free_map_host) {
+ cuMemFreeHost(cmem.map_host_pointer);
+ if (mem.host_pointer == mem.shared_pointer) {
+ mem.host_pointer = 0;
+ }
+ mem.shared_pointer = 0;
+ }
+
+ map_host_used -= mem.device_size;
+ }
+ else {
+ /* Free device memory. */
+ cuMemFree(mem.device_pointer);
+ }
+
+ stats.mem_free(mem.device_size);
+ mem.device_pointer = 0;
+ mem.device_size = 0;
+
+ cuda_mem_map.erase(cuda_mem_map.find(&mem));
+ }
+ }
+
+ void mem_alloc(device_memory &mem)
+ {
+ if (mem.type == MEM_PIXELS && !background) {
+ pixels_alloc(mem);
+ }
+ else if (mem.type == MEM_TEXTURE) {
+ assert(!"mem_alloc not supported for textures.");
+ }
+ else {
+ generic_alloc(mem);
+ }
+ }
+
+ void mem_copy_to(device_memory &mem)
+ {
+ if (mem.type == MEM_PIXELS) {
+ assert(!"mem_copy_to not supported for pixels.");
+ }
+ else if (mem.type == MEM_TEXTURE) {
+ tex_free(mem);
+ tex_alloc(mem);
+ }
+ else {
+ if (!mem.device_pointer) {
+ generic_alloc(mem);
+ }
+
+ generic_copy_to(mem);
+ }
+ }
+
+ void mem_copy_from(device_memory &mem, int y, int w, int h, int elem)
+ {
+ if (mem.type == MEM_PIXELS && !background) {
+ pixels_copy_from(mem, y, w, h);
+ }
+ else if (mem.type == MEM_TEXTURE) {
+ assert(!"mem_copy_from not supported for textures.");
+ }
+ else {
+ CUDAContextScope scope(this);
+ size_t offset = elem * y * w;
+ size_t size = elem * w * h;
+
+ if (mem.host_pointer && mem.device_pointer) {
+ cuda_assert(cuMemcpyDtoH(
+ (uchar *)mem.host_pointer + offset, (CUdeviceptr)(mem.device_pointer + offset), size));
+ }
+ else if (mem.host_pointer) {
+ memset((char *)mem.host_pointer + offset, 0, size);
+ }
+ }
+ }
+
+ void mem_zero(device_memory &mem)
+ {
+ if (!mem.device_pointer) {
+ mem_alloc(mem);
+ }
+
+ if (mem.host_pointer) {
+ memset(mem.host_pointer, 0, mem.memory_size());
+ }
+
+ if (mem.device_pointer && (!mem.host_pointer || mem.host_pointer != mem.shared_pointer)) {
+ CUDAContextScope scope(this);
+ cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()));
+ }
+ }
+
+ void mem_free(device_memory &mem)
+ {
+ if (mem.type == MEM_PIXELS && !background) {
+ pixels_free(mem);
+ }
+ else if (mem.type == MEM_TEXTURE) {
+ tex_free(mem);
+ }
+ else {
+ generic_free(mem);
+ }
+ }
+
+ virtual device_ptr mem_alloc_sub_ptr(device_memory &mem, int offset, int /*size*/)
+ {
+ return (device_ptr)(((char *)mem.device_pointer) + mem.memory_elements_size(offset));
+ }
+
+ void const_copy_to(const char *name, void *host, size_t size)
+ {
+ CUDAContextScope scope(this);
+ CUdeviceptr mem;
+ size_t bytes;
+
+ cuda_assert(cuModuleGetGlobal(&mem, &bytes, cuModule, name));
+ //assert(bytes == size);
+ cuda_assert(cuMemcpyHtoD(mem, host, size));
+ }
+
+ void tex_alloc(device_memory &mem)
+ {
+ CUDAContextScope scope(this);
+
+ /* General variables for both architectures */
+ string bind_name = mem.name;
+ size_t dsize = datatype_size(mem.data_type);
+ size_t size = mem.memory_size();
+
+ CUaddress_mode address_mode = CU_TR_ADDRESS_MODE_WRAP;
+ switch (mem.extension) {
+ case EXTENSION_REPEAT:
+ address_mode = CU_TR_ADDRESS_MODE_WRAP;
+ break;
+ case EXTENSION_EXTEND:
+ address_mode = CU_TR_ADDRESS_MODE_CLAMP;
+ break;
+ case EXTENSION_CLIP:
+ address_mode = CU_TR_ADDRESS_MODE_BORDER;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ CUfilter_mode filter_mode;
+ if (mem.interpolation == INTERPOLATION_CLOSEST) {
+ filter_mode = CU_TR_FILTER_MODE_POINT;
+ }
+ else {
+ filter_mode = CU_TR_FILTER_MODE_LINEAR;
+ }
+
+ /* Data Storage */
+ if (mem.interpolation == INTERPOLATION_NONE) {
+ generic_alloc(mem);
+ generic_copy_to(mem);
+
+ CUdeviceptr cumem;
+ size_t cubytes;
+
+ cuda_assert(cuModuleGetGlobal(&cumem, &cubytes, cuModule, bind_name.c_str()));
+
+ if (cubytes == 8) {
+ /* 64 bit device pointer */
+ uint64_t ptr = mem.device_pointer;
+ cuda_assert(cuMemcpyHtoD(cumem, (void *)&ptr, cubytes));
+ }
+ else {
+ /* 32 bit device pointer */
+ uint32_t ptr = (uint32_t)mem.device_pointer;
+ cuda_assert(cuMemcpyHtoD(cumem, (void *)&ptr, cubytes));
+ }
+ return;
+ }
+
+ /* Image Texture Storage */
+ CUarray_format_enum format;
+ switch (mem.data_type) {
+ case TYPE_UCHAR:
+ format = CU_AD_FORMAT_UNSIGNED_INT8;
+ break;
+ case TYPE_UINT16:
+ format = CU_AD_FORMAT_UNSIGNED_INT16;
+ break;
+ case TYPE_UINT:
+ format = CU_AD_FORMAT_UNSIGNED_INT32;
+ break;
+ case TYPE_INT:
+ format = CU_AD_FORMAT_SIGNED_INT32;
+ break;
+ case TYPE_FLOAT:
+ format = CU_AD_FORMAT_FLOAT;
+ break;
+ case TYPE_HALF:
+ format = CU_AD_FORMAT_HALF;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ CUDAMem *cmem = NULL;
+ CUarray array_3d = NULL;
+ size_t src_pitch = mem.data_width * dsize * mem.data_elements;
+ size_t dst_pitch = src_pitch;
+
+ if (mem.data_depth > 1) {
+ /* 3D texture using array, there is no API for linear memory. */
+ CUDA_ARRAY3D_DESCRIPTOR desc;
+
+ desc.Width = mem.data_width;
+ desc.Height = mem.data_height;
+ desc.Depth = mem.data_depth;
+ desc.Format = format;
+ desc.NumChannels = mem.data_elements;
+ desc.Flags = 0;
+
+ VLOG(1) << "Array 3D allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
+
+ cuda_assert(cuArray3DCreate(&array_3d, &desc));
+
+ if (!array_3d) {
+ return;
+ }
+
+ CUDA_MEMCPY3D param;
+ memset(&param, 0, sizeof(param));
+ param.dstMemoryType = CU_MEMORYTYPE_ARRAY;
+ param.dstArray = array_3d;
+ param.srcMemoryType = CU_MEMORYTYPE_HOST;
+ param.srcHost = mem.host_pointer;
+ param.srcPitch = src_pitch;
+ param.WidthInBytes = param.srcPitch;
+ param.Height = mem.data_height;
+ param.Depth = mem.data_depth;
+
+ cuda_assert(cuMemcpy3D(&param));
+
+ mem.device_pointer = (device_ptr)array_3d;
+ mem.device_size = size;
+ stats.mem_alloc(size);
+
+ cmem = &cuda_mem_map[&mem];
+ cmem->texobject = 0;
+ cmem->array = array_3d;
+ }
+ else if (mem.data_height > 0) {
+ /* 2D texture, using pitch aligned linear memory. */
+ int alignment = 0;
+ cuda_assert(
+ cuDeviceGetAttribute(&alignment, CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT, cuDevice));
+ dst_pitch = align_up(src_pitch, alignment);
+ size_t dst_size = dst_pitch * mem.data_height;
+
+ cmem = generic_alloc(mem, dst_size - mem.memory_size());
+ if (!cmem) {
+ return;
+ }
+
+ CUDA_MEMCPY2D param;
+ memset(&param, 0, sizeof(param));
+ param.dstMemoryType = CU_MEMORYTYPE_DEVICE;
+ param.dstDevice = mem.device_pointer;
+ param.dstPitch = dst_pitch;
+ param.srcMemoryType = CU_MEMORYTYPE_HOST;
+ param.srcHost = mem.host_pointer;
+ param.srcPitch = src_pitch;
+ param.WidthInBytes = param.srcPitch;
+ param.Height = mem.data_height;
+
+ cuda_assert(cuMemcpy2DUnaligned(&param));
+ }
+ else {
+ /* 1D texture, using linear memory. */
+ cmem = generic_alloc(mem);
+ if (!cmem) {
+ return;
+ }
+
+ cuda_assert(cuMemcpyHtoD(mem.device_pointer, mem.host_pointer, size));
+ }
+
+ /* Kepler+, bindless textures. */
+ int flat_slot = 0;
+ if (string_startswith(mem.name, "__tex_image")) {
+ int pos = string(mem.name).rfind("_");
+ flat_slot = atoi(mem.name + pos + 1);
+ }
+ else {
+ assert(0);
+ }
+
+ CUDA_RESOURCE_DESC resDesc;
+ memset(&resDesc, 0, sizeof(resDesc));
+
+ if (array_3d) {
+ resDesc.resType = CU_RESOURCE_TYPE_ARRAY;
+ resDesc.res.array.hArray = array_3d;
+ resDesc.flags = 0;
+ }
+ else if (mem.data_height > 0) {
+ resDesc.resType = CU_RESOURCE_TYPE_PITCH2D;
+ resDesc.res.pitch2D.devPtr = mem.device_pointer;
+ resDesc.res.pitch2D.format = format;
+ resDesc.res.pitch2D.numChannels = mem.data_elements;
+ resDesc.res.pitch2D.height = mem.data_height;
+ resDesc.res.pitch2D.width = mem.data_width;
+ resDesc.res.pitch2D.pitchInBytes = dst_pitch;
+ }
+ else {
+ resDesc.resType = CU_RESOURCE_TYPE_LINEAR;
+ resDesc.res.linear.devPtr = mem.device_pointer;
+ resDesc.res.linear.format = format;
+ resDesc.res.linear.numChannels = mem.data_elements;
+ resDesc.res.linear.sizeInBytes = mem.device_size;
+ }
+
+ CUDA_TEXTURE_DESC texDesc;
+ memset(&texDesc, 0, sizeof(texDesc));
+ texDesc.addressMode[0] = address_mode;
+ texDesc.addressMode[1] = address_mode;
+ texDesc.addressMode[2] = address_mode;
+ texDesc.filterMode = filter_mode;
+ texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
+
+ cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
+
+ /* Resize once */
+ if (flat_slot >= texture_info.size()) {
+ /* Allocate some slots in advance, to reduce amount
+ * of re-allocations. */
+ texture_info.resize(flat_slot + 128);
+ }
+
+ /* Set Mapping and tag that we need to (re-)upload to device */
+ TextureInfo &info = texture_info[flat_slot];
+ info.data = (uint64_t)cmem->texobject;
+ info.cl_buffer = 0;
+ info.interpolation = mem.interpolation;
+ info.extension = mem.extension;
+ info.width = mem.data_width;
+ info.height = mem.data_height;
+ info.depth = mem.data_depth;
+ need_texture_info = true;
+ }
+
+ void tex_free(device_memory &mem)
+ {
+ if (mem.device_pointer) {
+ CUDAContextScope scope(this);
+ const CUDAMem &cmem = cuda_mem_map[&mem];
+
+ if (cmem.texobject) {
+ /* Free bindless texture. */
+ cuTexObjectDestroy(cmem.texobject);
+ }
+
+ if (cmem.array) {
+ /* Free array. */
+ cuArrayDestroy(cmem.array);
+ stats.mem_free(mem.device_size);
+ mem.device_pointer = 0;
+ mem.device_size = 0;
+
+ cuda_mem_map.erase(cuda_mem_map.find(&mem));
+ }
+ else {
+ generic_free(mem);
+ }
+ }
+ }
+
+#define CUDA_GET_BLOCKSIZE(func, w, h) \
+ int threads_per_block; \
+ cuda_assert( \
+ cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, func)); \
+ int threads = (int)sqrt((float)threads_per_block); \
+ int xblocks = ((w) + threads - 1) / threads; \
+ int yblocks = ((h) + threads - 1) / threads;
+
+#define CUDA_LAUNCH_KERNEL(func, args) \
+ cuda_assert(cuLaunchKernel(func, xblocks, yblocks, 1, threads, threads, 1, 0, 0, args, 0));
/* Similar as above, but for 1-dimensional blocks. */
-#define CUDA_GET_BLOCKSIZE_1D(func, w, h) \
- int threads_per_block; \
- cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, func)); \
- int xblocks = ((w) + threads_per_block - 1)/threads_per_block; \
- int yblocks = h;
-
-#define CUDA_LAUNCH_KERNEL_1D(func, args) \
- cuda_assert(cuLaunchKernel(func, \
- xblocks, yblocks, 1, \
- threads_per_block, 1, 1, \
- 0, 0, args, 0));
-
- bool denoising_non_local_means(device_ptr image_ptr, device_ptr guide_ptr, device_ptr variance_ptr, device_ptr out_ptr,
- DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- int stride = task->buffer.stride;
- int w = task->buffer.width;
- int h = task->buffer.h;
- int r = task->nlm_state.r;
- int f = task->nlm_state.f;
- float a = task->nlm_state.a;
- float k_2 = task->nlm_state.k_2;
-
- int pass_stride = task->buffer.pass_stride;
- int num_shifts = (2*r+1)*(2*r+1);
- int channel_offset = task->nlm_state.is_color? task->buffer.pass_stride : 0;
- int frame_offset = 0;
-
- if(have_error())
- return false;
-
- CUdeviceptr difference = cuda_device_ptr(task->buffer.temporary_mem.device_pointer);
- CUdeviceptr blurDifference = difference + sizeof(float)*pass_stride*num_shifts;
- CUdeviceptr weightAccum = difference + 2*sizeof(float)*pass_stride*num_shifts;
- CUdeviceptr scale_ptr = 0;
-
- cuda_assert(cuMemsetD8(weightAccum, 0, sizeof(float)*pass_stride));
- cuda_assert(cuMemsetD8(out_ptr, 0, sizeof(float)*pass_stride));
-
- {
- CUfunction cuNLMCalcDifference, cuNLMBlur, cuNLMCalcWeight, cuNLMUpdateOutput;
- cuda_assert(cuModuleGetFunction(&cuNLMCalcDifference, cuFilterModule, "kernel_cuda_filter_nlm_calc_difference"));
- cuda_assert(cuModuleGetFunction(&cuNLMBlur, cuFilterModule, "kernel_cuda_filter_nlm_blur"));
- cuda_assert(cuModuleGetFunction(&cuNLMCalcWeight, cuFilterModule, "kernel_cuda_filter_nlm_calc_weight"));
- cuda_assert(cuModuleGetFunction(&cuNLMUpdateOutput, cuFilterModule, "kernel_cuda_filter_nlm_update_output"));
-
- cuda_assert(cuFuncSetCacheConfig(cuNLMCalcDifference, CU_FUNC_CACHE_PREFER_L1));
- cuda_assert(cuFuncSetCacheConfig(cuNLMBlur, CU_FUNC_CACHE_PREFER_L1));
- cuda_assert(cuFuncSetCacheConfig(cuNLMCalcWeight, CU_FUNC_CACHE_PREFER_L1));
- cuda_assert(cuFuncSetCacheConfig(cuNLMUpdateOutput, CU_FUNC_CACHE_PREFER_L1));
-
- CUDA_GET_BLOCKSIZE_1D(cuNLMCalcDifference, w*h, num_shifts);
-
- void *calc_difference_args[] = {&guide_ptr, &variance_ptr, &scale_ptr, &difference, &w, &h, &stride, &pass_stride, &r, &channel_offset, &frame_offset, &a, &k_2};
- void *blur_args[] = {&difference, &blurDifference, &w, &h, &stride, &pass_stride, &r, &f};
- void *calc_weight_args[] = {&blurDifference, &difference, &w, &h, &stride, &pass_stride, &r, &f};
- void *update_output_args[] = {&blurDifference, &image_ptr, &out_ptr, &weightAccum, &w, &h, &stride, &pass_stride, &channel_offset, &r, &f};
-
- CUDA_LAUNCH_KERNEL_1D(cuNLMCalcDifference, calc_difference_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMCalcWeight, calc_weight_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMUpdateOutput, update_output_args);
- }
-
- {
- CUfunction cuNLMNormalize;
- cuda_assert(cuModuleGetFunction(&cuNLMNormalize, cuFilterModule, "kernel_cuda_filter_nlm_normalize"));
- cuda_assert(cuFuncSetCacheConfig(cuNLMNormalize, CU_FUNC_CACHE_PREFER_L1));
- void *normalize_args[] = {&out_ptr, &weightAccum, &w, &h, &stride};
- CUDA_GET_BLOCKSIZE(cuNLMNormalize, w, h);
- CUDA_LAUNCH_KERNEL(cuNLMNormalize, normalize_args);
- cuda_assert(cuCtxSynchronize());
- }
-
- return !have_error();
- }
-
- bool denoising_construct_transform(DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- CUfunction cuFilterConstructTransform;
- cuda_assert(cuModuleGetFunction(&cuFilterConstructTransform, cuFilterModule, "kernel_cuda_filter_construct_transform"));
- cuda_assert(cuFuncSetCacheConfig(cuFilterConstructTransform, CU_FUNC_CACHE_PREFER_SHARED));
- CUDA_GET_BLOCKSIZE(cuFilterConstructTransform,
- task->storage.w,
- task->storage.h);
-
- void *args[] = {&task->buffer.mem.device_pointer,
- &task->tile_info_mem.device_pointer,
- &task->storage.transform.device_pointer,
- &task->storage.rank.device_pointer,
- &task->filter_area,
- &task->rect,
- &task->radius,
- &task->pca_threshold,
- &task->buffer.pass_stride,
- &task->buffer.frame_stride,
- &task->buffer.use_time};
- CUDA_LAUNCH_KERNEL(cuFilterConstructTransform, args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- bool denoising_accumulate(device_ptr color_ptr,
- device_ptr color_variance_ptr,
- device_ptr scale_ptr,
- int frame,
- DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- int r = task->radius;
- int f = 4;
- float a = 1.0f;
- float k_2 = task->nlm_k_2;
-
- int w = task->reconstruction_state.source_w;
- int h = task->reconstruction_state.source_h;
- int stride = task->buffer.stride;
- int frame_offset = frame * task->buffer.frame_stride;
- int t = task->tile_info->frames[frame];
-
- int pass_stride = task->buffer.pass_stride;
- int num_shifts = (2*r+1)*(2*r+1);
-
- if(have_error())
- return false;
-
- CUdeviceptr difference = cuda_device_ptr(task->buffer.temporary_mem.device_pointer);
- CUdeviceptr blurDifference = difference + sizeof(float)*pass_stride*num_shifts;
-
- CUfunction cuNLMCalcDifference, cuNLMBlur, cuNLMCalcWeight, cuNLMConstructGramian;
- cuda_assert(cuModuleGetFunction(&cuNLMCalcDifference, cuFilterModule, "kernel_cuda_filter_nlm_calc_difference"));
- cuda_assert(cuModuleGetFunction(&cuNLMBlur, cuFilterModule, "kernel_cuda_filter_nlm_blur"));
- cuda_assert(cuModuleGetFunction(&cuNLMCalcWeight, cuFilterModule, "kernel_cuda_filter_nlm_calc_weight"));
- cuda_assert(cuModuleGetFunction(&cuNLMConstructGramian, cuFilterModule, "kernel_cuda_filter_nlm_construct_gramian"));
-
- cuda_assert(cuFuncSetCacheConfig(cuNLMCalcDifference, CU_FUNC_CACHE_PREFER_L1));
- cuda_assert(cuFuncSetCacheConfig(cuNLMBlur, CU_FUNC_CACHE_PREFER_L1));
- cuda_assert(cuFuncSetCacheConfig(cuNLMCalcWeight, CU_FUNC_CACHE_PREFER_L1));
- cuda_assert(cuFuncSetCacheConfig(cuNLMConstructGramian, CU_FUNC_CACHE_PREFER_SHARED));
-
- CUDA_GET_BLOCKSIZE_1D(cuNLMCalcDifference,
- task->reconstruction_state.source_w * task->reconstruction_state.source_h,
- num_shifts);
-
- void *calc_difference_args[] = {&color_ptr,
- &color_variance_ptr,
- &scale_ptr,
- &difference,
- &w, &h,
- &stride, &pass_stride,
- &r, &pass_stride,
- &frame_offset,
- &a, &k_2};
- void *blur_args[] = {&difference, &blurDifference, &w, &h, &stride, &pass_stride, &r, &f};
- void *calc_weight_args[] = {&blurDifference, &difference, &w, &h, &stride, &pass_stride, &r, &f};
- void *construct_gramian_args[] = {&t,
- &blurDifference,
- &task->buffer.mem.device_pointer,
- &task->storage.transform.device_pointer,
- &task->storage.rank.device_pointer,
- &task->storage.XtWX.device_pointer,
- &task->storage.XtWY.device_pointer,
- &task->reconstruction_state.filter_window,
- &w, &h, &stride,
- &pass_stride, &r,
- &f,
- &frame_offset,
- &task->buffer.use_time};
-
- CUDA_LAUNCH_KERNEL_1D(cuNLMCalcDifference, calc_difference_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMCalcWeight, calc_weight_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
- CUDA_LAUNCH_KERNEL_1D(cuNLMConstructGramian, construct_gramian_args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- bool denoising_solve(device_ptr output_ptr,
- DenoisingTask *task)
- {
- CUfunction cuFinalize;
- cuda_assert(cuModuleGetFunction(&cuFinalize, cuFilterModule, "kernel_cuda_filter_finalize"));
- cuda_assert(cuFuncSetCacheConfig(cuFinalize, CU_FUNC_CACHE_PREFER_L1));
- void *finalize_args[] = {&output_ptr,
- &task->storage.rank.device_pointer,
- &task->storage.XtWX.device_pointer,
- &task->storage.XtWY.device_pointer,
- &task->filter_area,
- &task->reconstruction_state.buffer_params.x,
- &task->render_buffer.samples};
- CUDA_GET_BLOCKSIZE(cuFinalize,
- task->reconstruction_state.source_w,
- task->reconstruction_state.source_h);
- CUDA_LAUNCH_KERNEL(cuFinalize, finalize_args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- bool denoising_combine_halves(device_ptr a_ptr, device_ptr b_ptr,
- device_ptr mean_ptr, device_ptr variance_ptr,
- int r, int4 rect, DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- CUfunction cuFilterCombineHalves;
- cuda_assert(cuModuleGetFunction(&cuFilterCombineHalves, cuFilterModule, "kernel_cuda_filter_combine_halves"));
- cuda_assert(cuFuncSetCacheConfig(cuFilterCombineHalves, CU_FUNC_CACHE_PREFER_L1));
- CUDA_GET_BLOCKSIZE(cuFilterCombineHalves,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- void *args[] = {&mean_ptr,
- &variance_ptr,
- &a_ptr,
- &b_ptr,
- &rect,
- &r};
- CUDA_LAUNCH_KERNEL(cuFilterCombineHalves, args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- bool denoising_divide_shadow(device_ptr a_ptr, device_ptr b_ptr,
- device_ptr sample_variance_ptr, device_ptr sv_variance_ptr,
- device_ptr buffer_variance_ptr, DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- CUfunction cuFilterDivideShadow;
- cuda_assert(cuModuleGetFunction(&cuFilterDivideShadow, cuFilterModule, "kernel_cuda_filter_divide_shadow"));
- cuda_assert(cuFuncSetCacheConfig(cuFilterDivideShadow, CU_FUNC_CACHE_PREFER_L1));
- CUDA_GET_BLOCKSIZE(cuFilterDivideShadow,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- void *args[] = {&task->render_buffer.samples,
- &task->tile_info_mem.device_pointer,
- &a_ptr,
- &b_ptr,
- &sample_variance_ptr,
- &sv_variance_ptr,
- &buffer_variance_ptr,
- &task->rect,
- &task->render_buffer.pass_stride,
- &task->render_buffer.offset};
- CUDA_LAUNCH_KERNEL(cuFilterDivideShadow, args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- bool denoising_get_feature(int mean_offset,
- int variance_offset,
- device_ptr mean_ptr,
- device_ptr variance_ptr,
- float scale,
- DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- CUfunction cuFilterGetFeature;
- cuda_assert(cuModuleGetFunction(&cuFilterGetFeature, cuFilterModule, "kernel_cuda_filter_get_feature"));
- cuda_assert(cuFuncSetCacheConfig(cuFilterGetFeature, CU_FUNC_CACHE_PREFER_L1));
- CUDA_GET_BLOCKSIZE(cuFilterGetFeature,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- void *args[] = {&task->render_buffer.samples,
- &task->tile_info_mem.device_pointer,
- &mean_offset,
- &variance_offset,
- &mean_ptr,
- &variance_ptr,
- &scale,
- &task->rect,
- &task->render_buffer.pass_stride,
- &task->render_buffer.offset};
- CUDA_LAUNCH_KERNEL(cuFilterGetFeature, args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- bool denoising_write_feature(int out_offset,
- device_ptr from_ptr,
- device_ptr buffer_ptr,
- DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- CUfunction cuFilterWriteFeature;
- cuda_assert(cuModuleGetFunction(&cuFilterWriteFeature, cuFilterModule, "kernel_cuda_filter_write_feature"));
- cuda_assert(cuFuncSetCacheConfig(cuFilterWriteFeature, CU_FUNC_CACHE_PREFER_L1));
- CUDA_GET_BLOCKSIZE(cuFilterWriteFeature,
- task->filter_area.z,
- task->filter_area.w);
-
- void *args[] = {&task->render_buffer.samples,
- &task->reconstruction_state.buffer_params,
- &task->filter_area,
- &from_ptr,
- &buffer_ptr,
- &out_offset,
- &task->rect};
- CUDA_LAUNCH_KERNEL(cuFilterWriteFeature, args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- bool denoising_detect_outliers(device_ptr image_ptr,
- device_ptr variance_ptr,
- device_ptr depth_ptr,
- device_ptr output_ptr,
- DenoisingTask *task)
- {
- if(have_error())
- return false;
-
- CUDAContextScope scope(this);
-
- CUfunction cuFilterDetectOutliers;
- cuda_assert(cuModuleGetFunction(&cuFilterDetectOutliers, cuFilterModule, "kernel_cuda_filter_detect_outliers"));
- cuda_assert(cuFuncSetCacheConfig(cuFilterDetectOutliers, CU_FUNC_CACHE_PREFER_L1));
- CUDA_GET_BLOCKSIZE(cuFilterDetectOutliers,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- void *args[] = {&image_ptr,
- &variance_ptr,
- &depth_ptr,
- &output_ptr,
- &task->rect,
- &task->buffer.pass_stride};
-
- CUDA_LAUNCH_KERNEL(cuFilterDetectOutliers, args);
- cuda_assert(cuCtxSynchronize());
-
- return !have_error();
- }
-
- void denoise(RenderTile &rtile, DenoisingTask& denoising)
- {
- denoising.functions.construct_transform = function_bind(&CUDADevice::denoising_construct_transform, this, &denoising);
- denoising.functions.accumulate = function_bind(&CUDADevice::denoising_accumulate, this, _1, _2, _3, _4, &denoising);
- denoising.functions.solve = function_bind(&CUDADevice::denoising_solve, this, _1, &denoising);
- denoising.functions.divide_shadow = function_bind(&CUDADevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising);
- denoising.functions.non_local_means = function_bind(&CUDADevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising);
- denoising.functions.combine_halves = function_bind(&CUDADevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising);
- denoising.functions.get_feature = function_bind(&CUDADevice::denoising_get_feature, this, _1, _2, _3, _4, _5, &denoising);
- denoising.functions.write_feature = function_bind(&CUDADevice::denoising_write_feature, this, _1, _2, _3, &denoising);
- denoising.functions.detect_outliers = function_bind(&CUDADevice::denoising_detect_outliers, this, _1, _2, _3, _4, &denoising);
-
- denoising.filter_area = make_int4(rtile.x, rtile.y, rtile.w, rtile.h);
- denoising.render_buffer.samples = rtile.sample;
- denoising.buffer.gpu_temporary_mem = true;
-
- denoising.run_denoising(&rtile);
- }
-
- void path_trace(DeviceTask& task, RenderTile& rtile, device_vector<WorkTile>& work_tiles)
- {
- scoped_timer timer(&rtile.buffers->render_time);
-
- if(have_error())
- return;
-
- CUDAContextScope scope(this);
- CUfunction cuPathTrace;
-
- /* Get kernel function. */
- if(task.integrator_branched) {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
- }
- else {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
- }
-
- if(have_error()) {
- return;
- }
-
- cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
-
- /* Allocate work tile. */
- work_tiles.alloc(1);
-
- WorkTile *wtile = work_tiles.data();
- wtile->x = rtile.x;
- wtile->y = rtile.y;
- wtile->w = rtile.w;
- wtile->h = rtile.h;
- wtile->offset = rtile.offset;
- wtile->stride = rtile.stride;
- wtile->buffer = (float*)cuda_device_ptr(rtile.buffer);
-
- /* Prepare work size. More step samples render faster, but for now we
- * remain conservative for GPUs connected to a display to avoid driver
- * timeouts and display freezing. */
- int min_blocks, num_threads_per_block;
- cuda_assert(cuOccupancyMaxPotentialBlockSize(&min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
- if(!info.display_device) {
- min_blocks *= 8;
- }
-
- uint step_samples = divide_up(min_blocks * num_threads_per_block, wtile->w * wtile->h);
-
- /* Render all samples. */
- int start_sample = rtile.start_sample;
- int end_sample = rtile.start_sample + rtile.num_samples;
-
- for(int sample = start_sample; sample < end_sample; sample += step_samples) {
- /* Setup and copy work tile to device. */
- wtile->start_sample = sample;
- wtile->num_samples = min(step_samples, end_sample - sample);
- work_tiles.copy_to_device();
-
- CUdeviceptr d_work_tiles = cuda_device_ptr(work_tiles.device_pointer);
- uint total_work_size = wtile->w * wtile->h * wtile->num_samples;
- uint num_blocks = divide_up(total_work_size, num_threads_per_block);
-
- /* Launch kernel. */
- void *args[] = {&d_work_tiles,
- &total_work_size};
-
- cuda_assert(cuLaunchKernel(cuPathTrace,
- num_blocks, 1, 1,
- num_threads_per_block, 1, 1,
- 0, 0, args, 0));
-
- cuda_assert(cuCtxSynchronize());
-
- /* Update progress. */
- rtile.sample = sample + wtile->num_samples;
- task.update_progress(&rtile, rtile.w*rtile.h*wtile->num_samples);
-
- if(task.get_cancel()) {
- if(task.need_finish_queue == false)
- break;
- }
- }
- }
-
- void film_convert(DeviceTask& task, device_ptr buffer, device_ptr rgba_byte, device_ptr rgba_half)
- {
- if(have_error())
- return;
-
- CUDAContextScope scope(this);
-
- CUfunction cuFilmConvert;
- CUdeviceptr d_rgba = map_pixels((rgba_byte)? rgba_byte: rgba_half);
- CUdeviceptr d_buffer = cuda_device_ptr(buffer);
-
- /* get kernel function */
- if(rgba_half) {
- cuda_assert(cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_half_float"));
- }
- else {
- cuda_assert(cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_byte"));
- }
-
-
- float sample_scale = 1.0f/(task.sample + 1);
-
- /* pass in parameters */
- void *args[] = {&d_rgba,
- &d_buffer,
- &sample_scale,
- &task.x,
- &task.y,
- &task.w,
- &task.h,
- &task.offset,
- &task.stride};
-
- /* launch kernel */
- int threads_per_block;
- cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, cuFilmConvert));
-
- int xthreads = (int)sqrt(threads_per_block);
- int ythreads = (int)sqrt(threads_per_block);
- int xblocks = (task.w + xthreads - 1)/xthreads;
- int yblocks = (task.h + ythreads - 1)/ythreads;
-
- cuda_assert(cuFuncSetCacheConfig(cuFilmConvert, CU_FUNC_CACHE_PREFER_L1));
-
- cuda_assert(cuLaunchKernel(cuFilmConvert,
- xblocks , yblocks, 1, /* blocks */
- xthreads, ythreads, 1, /* threads */
- 0, 0, args, 0));
-
- unmap_pixels((rgba_byte)? rgba_byte: rgba_half);
-
- cuda_assert(cuCtxSynchronize());
- }
-
- void shader(DeviceTask& task)
- {
- if(have_error())
- return;
-
- CUDAContextScope scope(this);
-
- CUfunction cuShader;
- CUdeviceptr d_input = cuda_device_ptr(task.shader_input);
- CUdeviceptr d_output = cuda_device_ptr(task.shader_output);
-
- /* get kernel function */
- if(task.shader_eval_type >= SHADER_EVAL_BAKE) {
- cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_bake"));
- }
- else if(task.shader_eval_type == SHADER_EVAL_DISPLACE) {
- cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_displace"));
- }
- else {
- cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_background"));
- }
-
- /* do tasks in smaller chunks, so we can cancel it */
- const int shader_chunk_size = 65536;
- const int start = task.shader_x;
- const int end = task.shader_x + task.shader_w;
- int offset = task.offset;
-
- bool canceled = false;
- for(int sample = 0; sample < task.num_samples && !canceled; sample++) {
- for(int shader_x = start; shader_x < end; shader_x += shader_chunk_size) {
- int shader_w = min(shader_chunk_size, end - shader_x);
-
- /* pass in parameters */
- void *args[8];
- int arg = 0;
- args[arg++] = &d_input;
- args[arg++] = &d_output;
- args[arg++] = &task.shader_eval_type;
- if(task.shader_eval_type >= SHADER_EVAL_BAKE) {
- args[arg++] = &task.shader_filter;
- }
- args[arg++] = &shader_x;
- args[arg++] = &shader_w;
- args[arg++] = &offset;
- args[arg++] = &sample;
-
- /* launch kernel */
- int threads_per_block;
- cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, cuShader));
-
- int xblocks = (shader_w + threads_per_block - 1)/threads_per_block;
-
- cuda_assert(cuFuncSetCacheConfig(cuShader, CU_FUNC_CACHE_PREFER_L1));
- cuda_assert(cuLaunchKernel(cuShader,
- xblocks , 1, 1, /* blocks */
- threads_per_block, 1, 1, /* threads */
- 0, 0, args, 0));
-
- cuda_assert(cuCtxSynchronize());
-
- if(task.get_cancel()) {
- canceled = true;
- break;
- }
- }
-
- task.update_progress(NULL);
- }
- }
-
- CUdeviceptr map_pixels(device_ptr mem)
- {
- if(!background) {
- PixelMem pmem = pixel_mem_map[mem];
- CUdeviceptr buffer;
-
- size_t bytes;
- cuda_assert(cuGraphicsMapResources(1, &pmem.cuPBOresource, 0));
- cuda_assert(cuGraphicsResourceGetMappedPointer(&buffer, &bytes, pmem.cuPBOresource));
-
- return buffer;
- }
-
- return cuda_device_ptr(mem);
- }
-
- void unmap_pixels(device_ptr mem)
- {
- if(!background) {
- PixelMem pmem = pixel_mem_map[mem];
-
- cuda_assert(cuGraphicsUnmapResources(1, &pmem.cuPBOresource, 0));
- }
- }
-
- void pixels_alloc(device_memory& mem)
- {
- PixelMem pmem;
-
- pmem.w = mem.data_width;
- pmem.h = mem.data_height;
-
- CUDAContextScope scope(this);
-
- glGenBuffers(1, &pmem.cuPBO);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
- if(mem.data_type == TYPE_HALF)
- glBufferData(GL_PIXEL_UNPACK_BUFFER, pmem.w*pmem.h*sizeof(GLhalf)*4, NULL, GL_DYNAMIC_DRAW);
- else
- glBufferData(GL_PIXEL_UNPACK_BUFFER, pmem.w*pmem.h*sizeof(uint8_t)*4, NULL, GL_DYNAMIC_DRAW);
-
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-
- glActiveTexture(GL_TEXTURE0);
- glGenTextures(1, &pmem.cuTexId);
- glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
- if(mem.data_type == TYPE_HALF)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, pmem.w, pmem.h, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
- else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, pmem.w, pmem.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- CUresult result = cuGraphicsGLRegisterBuffer(&pmem.cuPBOresource, pmem.cuPBO, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
-
- if(result == CUDA_SUCCESS) {
- mem.device_pointer = pmem.cuTexId;
- pixel_mem_map[mem.device_pointer] = pmem;
-
- mem.device_size = mem.memory_size();
- stats.mem_alloc(mem.device_size);
-
- return;
- }
- else {
- /* failed to register buffer, fallback to no interop */
- glDeleteBuffers(1, &pmem.cuPBO);
- glDeleteTextures(1, &pmem.cuTexId);
-
- background = true;
- }
- }
-
- void pixels_copy_from(device_memory& mem, int y, int w, int h)
- {
- PixelMem pmem = pixel_mem_map[mem.device_pointer];
-
- CUDAContextScope scope(this);
-
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
- uchar *pixels = (uchar*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_ONLY);
- size_t offset = sizeof(uchar)*4*y*w;
- memcpy((uchar*)mem.host_pointer + offset, pixels + offset, sizeof(uchar)*4*w*h);
- glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- }
-
- void pixels_free(device_memory& mem)
- {
- if(mem.device_pointer) {
- PixelMem pmem = pixel_mem_map[mem.device_pointer];
-
- CUDAContextScope scope(this);
-
- cuda_assert(cuGraphicsUnregisterResource(pmem.cuPBOresource));
- glDeleteBuffers(1, &pmem.cuPBO);
- glDeleteTextures(1, &pmem.cuTexId);
-
- pixel_mem_map.erase(pixel_mem_map.find(mem.device_pointer));
- mem.device_pointer = 0;
-
- stats.mem_free(mem.device_size);
- mem.device_size = 0;
- }
- }
-
- void draw_pixels(
- device_memory& mem, int y,
- int w, int h, int width, int height,
- int dx, int dy, int dw, int dh, bool transparent,
- const DeviceDrawParams &draw_params)
- {
- assert(mem.type == MEM_PIXELS);
-
- if(!background) {
- const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
- PixelMem pmem = pixel_mem_map[mem.device_pointer];
- float *vpointer;
-
- CUDAContextScope scope(this);
-
- /* for multi devices, this assumes the inefficient method that we allocate
- * all pixels on the device even though we only render to a subset */
- size_t offset = 4*y*w;
-
- if(mem.data_type == TYPE_HALF)
- offset *= sizeof(GLhalf);
- else
- offset *= sizeof(uint8_t);
-
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
- if(mem.data_type == TYPE_HALF) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_HALF_FLOAT, (void*)offset);
- }
- else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)offset);
- }
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-
- if(transparent) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- GLint shader_program;
- if(use_fallback_shader) {
- if(!bind_fallback_display_space_shader(dw, dh)) {
- return;
- }
- shader_program = fallback_shader_program;
- }
- else {
- draw_params.bind_display_space_shader_cb();
- glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
- }
-
- if(!vertex_buffer) {
- glGenBuffers(1, &vertex_buffer);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
- /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
-
- vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
-
- if(vpointer) {
- /* texture coordinate - vertex pair */
- vpointer[0] = 0.0f;
- vpointer[1] = 0.0f;
- vpointer[2] = dx;
- vpointer[3] = dy;
-
- vpointer[4] = (float)w/(float)pmem.w;
- vpointer[5] = 0.0f;
- vpointer[6] = (float)width + dx;
- vpointer[7] = dy;
-
- vpointer[8] = (float)w/(float)pmem.w;
- vpointer[9] = (float)h/(float)pmem.h;
- vpointer[10] = (float)width + dx;
- vpointer[11] = (float)height + dy;
-
- vpointer[12] = 0.0f;
- vpointer[13] = (float)h/(float)pmem.h;
- vpointer[14] = dx;
- vpointer[15] = (float)height + dy;
-
- glUnmapBuffer(GL_ARRAY_BUFFER);
- }
-
- GLuint vertex_array_object;
- GLuint position_attribute, texcoord_attribute;
-
- glGenVertexArrays(1, &vertex_array_object);
- glBindVertexArray(vertex_array_object);
-
- texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
- position_attribute = glGetAttribLocation(shader_program, "pos");
-
- glEnableVertexAttribArray(texcoord_attribute);
- glEnableVertexAttribArray(position_attribute);
-
- glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
- glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- if(use_fallback_shader) {
- glUseProgram(0);
- }
- else {
- draw_params.unbind_display_space_shader_cb();
- }
-
- if(transparent) {
- glDisable(GL_BLEND);
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- return;
- }
-
- Device::draw_pixels(mem, y, w, h, width, height, dx, dy, dw, dh, transparent, draw_params);
- }
-
- void thread_run(DeviceTask *task)
- {
- CUDAContextScope scope(this);
-
- if(task->type == DeviceTask::RENDER) {
- DeviceRequestedFeatures requested_features;
- if(use_split_kernel()) {
- if(split_kernel == NULL) {
- split_kernel = new CUDASplitKernel(this);
- split_kernel->load_kernels(requested_features);
- }
- }
-
- device_vector<WorkTile> work_tiles(this, "work_tiles", MEM_READ_ONLY);
-
- /* keep rendering tiles until done */
- RenderTile tile;
- DenoisingTask denoising(this, *task);
-
- while(task->acquire_tile(this, tile)) {
- if(tile.task == RenderTile::PATH_TRACE) {
- if(use_split_kernel()) {
- device_only_memory<uchar> void_buffer(this, "void_buffer");
- split_kernel->path_trace(task, tile, void_buffer, void_buffer);
- }
- else {
- path_trace(*task, tile, work_tiles);
- }
- }
- else if(tile.task == RenderTile::DENOISE) {
- tile.sample = tile.start_sample + tile.num_samples;
-
- denoise(tile, denoising);
-
- task->update_progress(&tile, tile.w*tile.h);
- }
-
- task->release_tile(tile);
-
- if(task->get_cancel()) {
- if(task->need_finish_queue == false)
- break;
- }
- }
-
- work_tiles.free();
- }
- else if(task->type == DeviceTask::SHADER) {
- shader(*task);
-
- cuda_assert(cuCtxSynchronize());
- }
- }
-
- class CUDADeviceTask : public DeviceTask {
- public:
- CUDADeviceTask(CUDADevice *device, DeviceTask& task)
- : DeviceTask(task)
- {
- run = function_bind(&CUDADevice::thread_run, device, this);
- }
- };
-
- int get_split_task_count(DeviceTask& /*task*/)
- {
- return 1;
- }
-
- void task_add(DeviceTask& task)
- {
- CUDAContextScope scope(this);
-
- /* Load texture info. */
- load_texture_info();
-
- /* Synchronize all memory copies before executing task. */
- cuda_assert(cuCtxSynchronize());
-
- if(task.type == DeviceTask::FILM_CONVERT) {
- /* must be done in main thread due to opengl access */
- film_convert(task, task.buffer, task.rgba_byte, task.rgba_half);
- }
- else {
- task_pool.push(new CUDADeviceTask(this, task));
- }
- }
-
- void task_wait()
- {
- task_pool.wait();
- }
-
- void task_cancel()
- {
- task_pool.cancel();
- }
-
- friend class CUDASplitKernelFunction;
- friend class CUDASplitKernel;
- friend class CUDAContextScope;
+#define CUDA_GET_BLOCKSIZE_1D(func, w, h) \
+ int threads_per_block; \
+ cuda_assert( \
+ cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, func)); \
+ int xblocks = ((w) + threads_per_block - 1) / threads_per_block; \
+ int yblocks = h;
+
+#define CUDA_LAUNCH_KERNEL_1D(func, args) \
+ cuda_assert(cuLaunchKernel(func, xblocks, yblocks, 1, threads_per_block, 1, 1, 0, 0, args, 0));
+
+ bool denoising_non_local_means(device_ptr image_ptr,
+ device_ptr guide_ptr,
+ device_ptr variance_ptr,
+ device_ptr out_ptr,
+ DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ int stride = task->buffer.stride;
+ int w = task->buffer.width;
+ int h = task->buffer.h;
+ int r = task->nlm_state.r;
+ int f = task->nlm_state.f;
+ float a = task->nlm_state.a;
+ float k_2 = task->nlm_state.k_2;
+
+ int pass_stride = task->buffer.pass_stride;
+ int num_shifts = (2 * r + 1) * (2 * r + 1);
+ int channel_offset = task->nlm_state.is_color ? task->buffer.pass_stride : 0;
+ int frame_offset = 0;
+
+ if (have_error())
+ return false;
+
+ CUdeviceptr difference = cuda_device_ptr(task->buffer.temporary_mem.device_pointer);
+ CUdeviceptr blurDifference = difference + sizeof(float) * pass_stride * num_shifts;
+ CUdeviceptr weightAccum = difference + 2 * sizeof(float) * pass_stride * num_shifts;
+ CUdeviceptr scale_ptr = 0;
+
+ cuda_assert(cuMemsetD8(weightAccum, 0, sizeof(float) * pass_stride));
+ cuda_assert(cuMemsetD8(out_ptr, 0, sizeof(float) * pass_stride));
+
+ {
+ CUfunction cuNLMCalcDifference, cuNLMBlur, cuNLMCalcWeight, cuNLMUpdateOutput;
+ cuda_assert(cuModuleGetFunction(
+ &cuNLMCalcDifference, cuFilterModule, "kernel_cuda_filter_nlm_calc_difference"));
+ cuda_assert(cuModuleGetFunction(&cuNLMBlur, cuFilterModule, "kernel_cuda_filter_nlm_blur"));
+ cuda_assert(cuModuleGetFunction(
+ &cuNLMCalcWeight, cuFilterModule, "kernel_cuda_filter_nlm_calc_weight"));
+ cuda_assert(cuModuleGetFunction(
+ &cuNLMUpdateOutput, cuFilterModule, "kernel_cuda_filter_nlm_update_output"));
+
+ cuda_assert(cuFuncSetCacheConfig(cuNLMCalcDifference, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuNLMBlur, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuNLMCalcWeight, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuNLMUpdateOutput, CU_FUNC_CACHE_PREFER_L1));
+
+ CUDA_GET_BLOCKSIZE_1D(cuNLMCalcDifference, w * h, num_shifts);
+
+ void *calc_difference_args[] = {&guide_ptr,
+ &variance_ptr,
+ &scale_ptr,
+ &difference,
+ &w,
+ &h,
+ &stride,
+ &pass_stride,
+ &r,
+ &channel_offset,
+ &frame_offset,
+ &a,
+ &k_2};
+ void *blur_args[] = {&difference, &blurDifference, &w, &h, &stride, &pass_stride, &r, &f};
+ void *calc_weight_args[] = {
+ &blurDifference, &difference, &w, &h, &stride, &pass_stride, &r, &f};
+ void *update_output_args[] = {&blurDifference,
+ &image_ptr,
+ &out_ptr,
+ &weightAccum,
+ &w,
+ &h,
+ &stride,
+ &pass_stride,
+ &channel_offset,
+ &r,
+ &f};
+
+ CUDA_LAUNCH_KERNEL_1D(cuNLMCalcDifference, calc_difference_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMCalcWeight, calc_weight_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMUpdateOutput, update_output_args);
+ }
+
+ {
+ CUfunction cuNLMNormalize;
+ cuda_assert(cuModuleGetFunction(
+ &cuNLMNormalize, cuFilterModule, "kernel_cuda_filter_nlm_normalize"));
+ cuda_assert(cuFuncSetCacheConfig(cuNLMNormalize, CU_FUNC_CACHE_PREFER_L1));
+ void *normalize_args[] = {&out_ptr, &weightAccum, &w, &h, &stride};
+ CUDA_GET_BLOCKSIZE(cuNLMNormalize, w, h);
+ CUDA_LAUNCH_KERNEL(cuNLMNormalize, normalize_args);
+ cuda_assert(cuCtxSynchronize());
+ }
+
+ return !have_error();
+ }
+
+ bool denoising_construct_transform(DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuFilterConstructTransform;
+ cuda_assert(cuModuleGetFunction(
+ &cuFilterConstructTransform, cuFilterModule, "kernel_cuda_filter_construct_transform"));
+ cuda_assert(cuFuncSetCacheConfig(cuFilterConstructTransform, CU_FUNC_CACHE_PREFER_SHARED));
+ CUDA_GET_BLOCKSIZE(cuFilterConstructTransform, task->storage.w, task->storage.h);
+
+ void *args[] = {&task->buffer.mem.device_pointer,
+ &task->tile_info_mem.device_pointer,
+ &task->storage.transform.device_pointer,
+ &task->storage.rank.device_pointer,
+ &task->filter_area,
+ &task->rect,
+ &task->radius,
+ &task->pca_threshold,
+ &task->buffer.pass_stride,
+ &task->buffer.frame_stride,
+ &task->buffer.use_time};
+ CUDA_LAUNCH_KERNEL(cuFilterConstructTransform, args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ bool denoising_accumulate(device_ptr color_ptr,
+ device_ptr color_variance_ptr,
+ device_ptr scale_ptr,
+ int frame,
+ DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ int r = task->radius;
+ int f = 4;
+ float a = 1.0f;
+ float k_2 = task->nlm_k_2;
+
+ int w = task->reconstruction_state.source_w;
+ int h = task->reconstruction_state.source_h;
+ int stride = task->buffer.stride;
+ int frame_offset = frame * task->buffer.frame_stride;
+ int t = task->tile_info->frames[frame];
+
+ int pass_stride = task->buffer.pass_stride;
+ int num_shifts = (2 * r + 1) * (2 * r + 1);
+
+ if (have_error())
+ return false;
+
+ CUdeviceptr difference = cuda_device_ptr(task->buffer.temporary_mem.device_pointer);
+ CUdeviceptr blurDifference = difference + sizeof(float) * pass_stride * num_shifts;
+
+ CUfunction cuNLMCalcDifference, cuNLMBlur, cuNLMCalcWeight, cuNLMConstructGramian;
+ cuda_assert(cuModuleGetFunction(
+ &cuNLMCalcDifference, cuFilterModule, "kernel_cuda_filter_nlm_calc_difference"));
+ cuda_assert(cuModuleGetFunction(&cuNLMBlur, cuFilterModule, "kernel_cuda_filter_nlm_blur"));
+ cuda_assert(cuModuleGetFunction(
+ &cuNLMCalcWeight, cuFilterModule, "kernel_cuda_filter_nlm_calc_weight"));
+ cuda_assert(cuModuleGetFunction(
+ &cuNLMConstructGramian, cuFilterModule, "kernel_cuda_filter_nlm_construct_gramian"));
+
+ cuda_assert(cuFuncSetCacheConfig(cuNLMCalcDifference, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuNLMBlur, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuNLMCalcWeight, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuNLMConstructGramian, CU_FUNC_CACHE_PREFER_SHARED));
+
+ CUDA_GET_BLOCKSIZE_1D(cuNLMCalcDifference,
+ task->reconstruction_state.source_w *
+ task->reconstruction_state.source_h,
+ num_shifts);
+
+ void *calc_difference_args[] = {&color_ptr,
+ &color_variance_ptr,
+ &scale_ptr,
+ &difference,
+ &w,
+ &h,
+ &stride,
+ &pass_stride,
+ &r,
+ &pass_stride,
+ &frame_offset,
+ &a,
+ &k_2};
+ void *blur_args[] = {&difference, &blurDifference, &w, &h, &stride, &pass_stride, &r, &f};
+ void *calc_weight_args[] = {
+ &blurDifference, &difference, &w, &h, &stride, &pass_stride, &r, &f};
+ void *construct_gramian_args[] = {&t,
+ &blurDifference,
+ &task->buffer.mem.device_pointer,
+ &task->storage.transform.device_pointer,
+ &task->storage.rank.device_pointer,
+ &task->storage.XtWX.device_pointer,
+ &task->storage.XtWY.device_pointer,
+ &task->reconstruction_state.filter_window,
+ &w,
+ &h,
+ &stride,
+ &pass_stride,
+ &r,
+ &f,
+ &frame_offset,
+ &task->buffer.use_time};
+
+ CUDA_LAUNCH_KERNEL_1D(cuNLMCalcDifference, calc_difference_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMCalcWeight, calc_weight_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMBlur, blur_args);
+ CUDA_LAUNCH_KERNEL_1D(cuNLMConstructGramian, construct_gramian_args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ bool denoising_solve(device_ptr output_ptr, DenoisingTask *task)
+ {
+ CUfunction cuFinalize;
+ cuda_assert(cuModuleGetFunction(&cuFinalize, cuFilterModule, "kernel_cuda_filter_finalize"));
+ cuda_assert(cuFuncSetCacheConfig(cuFinalize, CU_FUNC_CACHE_PREFER_L1));
+ void *finalize_args[] = {&output_ptr,
+ &task->storage.rank.device_pointer,
+ &task->storage.XtWX.device_pointer,
+ &task->storage.XtWY.device_pointer,
+ &task->filter_area,
+ &task->reconstruction_state.buffer_params.x,
+ &task->render_buffer.samples};
+ CUDA_GET_BLOCKSIZE(
+ cuFinalize, task->reconstruction_state.source_w, task->reconstruction_state.source_h);
+ CUDA_LAUNCH_KERNEL(cuFinalize, finalize_args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ bool denoising_combine_halves(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ int r,
+ int4 rect,
+ DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuFilterCombineHalves;
+ cuda_assert(cuModuleGetFunction(
+ &cuFilterCombineHalves, cuFilterModule, "kernel_cuda_filter_combine_halves"));
+ cuda_assert(cuFuncSetCacheConfig(cuFilterCombineHalves, CU_FUNC_CACHE_PREFER_L1));
+ CUDA_GET_BLOCKSIZE(
+ cuFilterCombineHalves, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ void *args[] = {&mean_ptr, &variance_ptr, &a_ptr, &b_ptr, &rect, &r};
+ CUDA_LAUNCH_KERNEL(cuFilterCombineHalves, args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ bool denoising_divide_shadow(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr sample_variance_ptr,
+ device_ptr sv_variance_ptr,
+ device_ptr buffer_variance_ptr,
+ DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuFilterDivideShadow;
+ cuda_assert(cuModuleGetFunction(
+ &cuFilterDivideShadow, cuFilterModule, "kernel_cuda_filter_divide_shadow"));
+ cuda_assert(cuFuncSetCacheConfig(cuFilterDivideShadow, CU_FUNC_CACHE_PREFER_L1));
+ CUDA_GET_BLOCKSIZE(
+ cuFilterDivideShadow, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ void *args[] = {&task->render_buffer.samples,
+ &task->tile_info_mem.device_pointer,
+ &a_ptr,
+ &b_ptr,
+ &sample_variance_ptr,
+ &sv_variance_ptr,
+ &buffer_variance_ptr,
+ &task->rect,
+ &task->render_buffer.pass_stride,
+ &task->render_buffer.offset};
+ CUDA_LAUNCH_KERNEL(cuFilterDivideShadow, args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ bool denoising_get_feature(int mean_offset,
+ int variance_offset,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ float scale,
+ DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuFilterGetFeature;
+ cuda_assert(cuModuleGetFunction(
+ &cuFilterGetFeature, cuFilterModule, "kernel_cuda_filter_get_feature"));
+ cuda_assert(cuFuncSetCacheConfig(cuFilterGetFeature, CU_FUNC_CACHE_PREFER_L1));
+ CUDA_GET_BLOCKSIZE(
+ cuFilterGetFeature, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ void *args[] = {&task->render_buffer.samples,
+ &task->tile_info_mem.device_pointer,
+ &mean_offset,
+ &variance_offset,
+ &mean_ptr,
+ &variance_ptr,
+ &scale,
+ &task->rect,
+ &task->render_buffer.pass_stride,
+ &task->render_buffer.offset};
+ CUDA_LAUNCH_KERNEL(cuFilterGetFeature, args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ bool denoising_write_feature(int out_offset,
+ device_ptr from_ptr,
+ device_ptr buffer_ptr,
+ DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuFilterWriteFeature;
+ cuda_assert(cuModuleGetFunction(
+ &cuFilterWriteFeature, cuFilterModule, "kernel_cuda_filter_write_feature"));
+ cuda_assert(cuFuncSetCacheConfig(cuFilterWriteFeature, CU_FUNC_CACHE_PREFER_L1));
+ CUDA_GET_BLOCKSIZE(cuFilterWriteFeature, task->filter_area.z, task->filter_area.w);
+
+ void *args[] = {&task->render_buffer.samples,
+ &task->reconstruction_state.buffer_params,
+ &task->filter_area,
+ &from_ptr,
+ &buffer_ptr,
+ &out_offset,
+ &task->rect};
+ CUDA_LAUNCH_KERNEL(cuFilterWriteFeature, args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ bool denoising_detect_outliers(device_ptr image_ptr,
+ device_ptr variance_ptr,
+ device_ptr depth_ptr,
+ device_ptr output_ptr,
+ DenoisingTask *task)
+ {
+ if (have_error())
+ return false;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuFilterDetectOutliers;
+ cuda_assert(cuModuleGetFunction(
+ &cuFilterDetectOutliers, cuFilterModule, "kernel_cuda_filter_detect_outliers"));
+ cuda_assert(cuFuncSetCacheConfig(cuFilterDetectOutliers, CU_FUNC_CACHE_PREFER_L1));
+ CUDA_GET_BLOCKSIZE(
+ cuFilterDetectOutliers, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ void *args[] = {&image_ptr,
+ &variance_ptr,
+ &depth_ptr,
+ &output_ptr,
+ &task->rect,
+ &task->buffer.pass_stride};
+
+ CUDA_LAUNCH_KERNEL(cuFilterDetectOutliers, args);
+ cuda_assert(cuCtxSynchronize());
+
+ return !have_error();
+ }
+
+ void denoise(RenderTile &rtile, DenoisingTask &denoising)
+ {
+ denoising.functions.construct_transform = function_bind(
+ &CUDADevice::denoising_construct_transform, this, &denoising);
+ denoising.functions.accumulate = function_bind(
+ &CUDADevice::denoising_accumulate, this, _1, _2, _3, _4, &denoising);
+ denoising.functions.solve = function_bind(&CUDADevice::denoising_solve, this, _1, &denoising);
+ denoising.functions.divide_shadow = function_bind(
+ &CUDADevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising);
+ denoising.functions.non_local_means = function_bind(
+ &CUDADevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising);
+ denoising.functions.combine_halves = function_bind(
+ &CUDADevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising);
+ denoising.functions.get_feature = function_bind(
+ &CUDADevice::denoising_get_feature, this, _1, _2, _3, _4, _5, &denoising);
+ denoising.functions.write_feature = function_bind(
+ &CUDADevice::denoising_write_feature, this, _1, _2, _3, &denoising);
+ denoising.functions.detect_outliers = function_bind(
+ &CUDADevice::denoising_detect_outliers, this, _1, _2, _3, _4, &denoising);
+
+ denoising.filter_area = make_int4(rtile.x, rtile.y, rtile.w, rtile.h);
+ denoising.render_buffer.samples = rtile.sample;
+ denoising.buffer.gpu_temporary_mem = true;
+
+ denoising.run_denoising(&rtile);
+ }
+
+ void path_trace(DeviceTask &task, RenderTile &rtile, device_vector<WorkTile> &work_tiles)
+ {
+ scoped_timer timer(&rtile.buffers->render_time);
+
+ if (have_error())
+ return;
+
+ CUDAContextScope scope(this);
+ CUfunction cuPathTrace;
+
+ /* Get kernel function. */
+ if (task.integrator_branched) {
+ cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
+ }
+ else {
+ cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
+ }
+
+ if (have_error()) {
+ return;
+ }
+
+ cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
+
+ /* Allocate work tile. */
+ work_tiles.alloc(1);
+
+ WorkTile *wtile = work_tiles.data();
+ wtile->x = rtile.x;
+ wtile->y = rtile.y;
+ wtile->w = rtile.w;
+ wtile->h = rtile.h;
+ wtile->offset = rtile.offset;
+ wtile->stride = rtile.stride;
+ wtile->buffer = (float *)cuda_device_ptr(rtile.buffer);
+
+ /* Prepare work size. More step samples render faster, but for now we
+ * remain conservative for GPUs connected to a display to avoid driver
+ * timeouts and display freezing. */
+ int min_blocks, num_threads_per_block;
+ cuda_assert(cuOccupancyMaxPotentialBlockSize(
+ &min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
+ if (!info.display_device) {
+ min_blocks *= 8;
+ }
+
+ uint step_samples = divide_up(min_blocks * num_threads_per_block, wtile->w * wtile->h);
+
+ /* Render all samples. */
+ int start_sample = rtile.start_sample;
+ int end_sample = rtile.start_sample + rtile.num_samples;
+
+ for (int sample = start_sample; sample < end_sample; sample += step_samples) {
+ /* Setup and copy work tile to device. */
+ wtile->start_sample = sample;
+ wtile->num_samples = min(step_samples, end_sample - sample);
+ work_tiles.copy_to_device();
+
+ CUdeviceptr d_work_tiles = cuda_device_ptr(work_tiles.device_pointer);
+ uint total_work_size = wtile->w * wtile->h * wtile->num_samples;
+ uint num_blocks = divide_up(total_work_size, num_threads_per_block);
+
+ /* Launch kernel. */
+ void *args[] = {&d_work_tiles, &total_work_size};
+
+ cuda_assert(cuLaunchKernel(
+ cuPathTrace, num_blocks, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
+
+ cuda_assert(cuCtxSynchronize());
+
+ /* Update progress. */
+ rtile.sample = sample + wtile->num_samples;
+ task.update_progress(&rtile, rtile.w * rtile.h * wtile->num_samples);
+
+ if (task.get_cancel()) {
+ if (task.need_finish_queue == false)
+ break;
+ }
+ }
+ }
+
+ void film_convert(DeviceTask &task,
+ device_ptr buffer,
+ device_ptr rgba_byte,
+ device_ptr rgba_half)
+ {
+ if (have_error())
+ return;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuFilmConvert;
+ CUdeviceptr d_rgba = map_pixels((rgba_byte) ? rgba_byte : rgba_half);
+ CUdeviceptr d_buffer = cuda_device_ptr(buffer);
+
+ /* get kernel function */
+ if (rgba_half) {
+ cuda_assert(
+ cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_half_float"));
+ }
+ else {
+ cuda_assert(cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_byte"));
+ }
+
+ float sample_scale = 1.0f / (task.sample + 1);
+
+ /* pass in parameters */
+ void *args[] = {&d_rgba,
+ &d_buffer,
+ &sample_scale,
+ &task.x,
+ &task.y,
+ &task.w,
+ &task.h,
+ &task.offset,
+ &task.stride};
+
+ /* launch kernel */
+ int threads_per_block;
+ cuda_assert(cuFuncGetAttribute(
+ &threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, cuFilmConvert));
+
+ int xthreads = (int)sqrt(threads_per_block);
+ int ythreads = (int)sqrt(threads_per_block);
+ int xblocks = (task.w + xthreads - 1) / xthreads;
+ int yblocks = (task.h + ythreads - 1) / ythreads;
+
+ cuda_assert(cuFuncSetCacheConfig(cuFilmConvert, CU_FUNC_CACHE_PREFER_L1));
+
+ cuda_assert(cuLaunchKernel(cuFilmConvert,
+ xblocks,
+ yblocks,
+ 1, /* blocks */
+ xthreads,
+ ythreads,
+ 1, /* threads */
+ 0,
+ 0,
+ args,
+ 0));
+
+ unmap_pixels((rgba_byte) ? rgba_byte : rgba_half);
+
+ cuda_assert(cuCtxSynchronize());
+ }
+
+ void shader(DeviceTask &task)
+ {
+ if (have_error())
+ return;
+
+ CUDAContextScope scope(this);
+
+ CUfunction cuShader;
+ CUdeviceptr d_input = cuda_device_ptr(task.shader_input);
+ CUdeviceptr d_output = cuda_device_ptr(task.shader_output);
+
+ /* get kernel function */
+ if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
+ cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_bake"));
+ }
+ else if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
+ cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_displace"));
+ }
+ else {
+ cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_background"));
+ }
+
+ /* do tasks in smaller chunks, so we can cancel it */
+ const int shader_chunk_size = 65536;
+ const int start = task.shader_x;
+ const int end = task.shader_x + task.shader_w;
+ int offset = task.offset;
+
+ bool canceled = false;
+ for (int sample = 0; sample < task.num_samples && !canceled; sample++) {
+ for (int shader_x = start; shader_x < end; shader_x += shader_chunk_size) {
+ int shader_w = min(shader_chunk_size, end - shader_x);
+
+ /* pass in parameters */
+ void *args[8];
+ int arg = 0;
+ args[arg++] = &d_input;
+ args[arg++] = &d_output;
+ args[arg++] = &task.shader_eval_type;
+ if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
+ args[arg++] = &task.shader_filter;
+ }
+ args[arg++] = &shader_x;
+ args[arg++] = &shader_w;
+ args[arg++] = &offset;
+ args[arg++] = &sample;
+
+ /* launch kernel */
+ int threads_per_block;
+ cuda_assert(cuFuncGetAttribute(
+ &threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, cuShader));
+
+ int xblocks = (shader_w + threads_per_block - 1) / threads_per_block;
+
+ cuda_assert(cuFuncSetCacheConfig(cuShader, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuLaunchKernel(cuShader,
+ xblocks,
+ 1,
+ 1, /* blocks */
+ threads_per_block,
+ 1,
+ 1, /* threads */
+ 0,
+ 0,
+ args,
+ 0));
+
+ cuda_assert(cuCtxSynchronize());
+
+ if (task.get_cancel()) {
+ canceled = true;
+ break;
+ }
+ }
+
+ task.update_progress(NULL);
+ }
+ }
+
+ CUdeviceptr map_pixels(device_ptr mem)
+ {
+ if (!background) {
+ PixelMem pmem = pixel_mem_map[mem];
+ CUdeviceptr buffer;
+
+ size_t bytes;
+ cuda_assert(cuGraphicsMapResources(1, &pmem.cuPBOresource, 0));
+ cuda_assert(cuGraphicsResourceGetMappedPointer(&buffer, &bytes, pmem.cuPBOresource));
+
+ return buffer;
+ }
+
+ return cuda_device_ptr(mem);
+ }
+
+ void unmap_pixels(device_ptr mem)
+ {
+ if (!background) {
+ PixelMem pmem = pixel_mem_map[mem];
+
+ cuda_assert(cuGraphicsUnmapResources(1, &pmem.cuPBOresource, 0));
+ }
+ }
+
+ void pixels_alloc(device_memory &mem)
+ {
+ PixelMem pmem;
+
+ pmem.w = mem.data_width;
+ pmem.h = mem.data_height;
+
+ CUDAContextScope scope(this);
+
+ glGenBuffers(1, &pmem.cuPBO);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
+ if (mem.data_type == TYPE_HALF)
+ glBufferData(
+ GL_PIXEL_UNPACK_BUFFER, pmem.w * pmem.h * sizeof(GLhalf) * 4, NULL, GL_DYNAMIC_DRAW);
+ else
+ glBufferData(
+ GL_PIXEL_UNPACK_BUFFER, pmem.w * pmem.h * sizeof(uint8_t) * 4, NULL, GL_DYNAMIC_DRAW);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ glActiveTexture(GL_TEXTURE0);
+ glGenTextures(1, &pmem.cuTexId);
+ glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
+ if (mem.data_type == TYPE_HALF)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, pmem.w, pmem.h, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, pmem.w, pmem.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ CUresult result = cuGraphicsGLRegisterBuffer(
+ &pmem.cuPBOresource, pmem.cuPBO, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
+
+ if (result == CUDA_SUCCESS) {
+ mem.device_pointer = pmem.cuTexId;
+ pixel_mem_map[mem.device_pointer] = pmem;
+
+ mem.device_size = mem.memory_size();
+ stats.mem_alloc(mem.device_size);
+
+ return;
+ }
+ else {
+ /* failed to register buffer, fallback to no interop */
+ glDeleteBuffers(1, &pmem.cuPBO);
+ glDeleteTextures(1, &pmem.cuTexId);
+
+ background = true;
+ }
+ }
+
+ void pixels_copy_from(device_memory &mem, int y, int w, int h)
+ {
+ PixelMem pmem = pixel_mem_map[mem.device_pointer];
+
+ CUDAContextScope scope(this);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
+ uchar *pixels = (uchar *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_ONLY);
+ size_t offset = sizeof(uchar) * 4 * y * w;
+ memcpy((uchar *)mem.host_pointer + offset, pixels + offset, sizeof(uchar) * 4 * w * h);
+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ }
+
+ void pixels_free(device_memory &mem)
+ {
+ if (mem.device_pointer) {
+ PixelMem pmem = pixel_mem_map[mem.device_pointer];
+
+ CUDAContextScope scope(this);
+
+ cuda_assert(cuGraphicsUnregisterResource(pmem.cuPBOresource));
+ glDeleteBuffers(1, &pmem.cuPBO);
+ glDeleteTextures(1, &pmem.cuTexId);
+
+ pixel_mem_map.erase(pixel_mem_map.find(mem.device_pointer));
+ mem.device_pointer = 0;
+
+ stats.mem_free(mem.device_size);
+ mem.device_size = 0;
+ }
+ }
+
+ void draw_pixels(device_memory &mem,
+ int y,
+ int w,
+ int h,
+ int width,
+ int height,
+ int dx,
+ int dy,
+ int dw,
+ int dh,
+ bool transparent,
+ const DeviceDrawParams &draw_params)
+ {
+ assert(mem.type == MEM_PIXELS);
+
+ if (!background) {
+ const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
+ PixelMem pmem = pixel_mem_map[mem.device_pointer];
+ float *vpointer;
+
+ CUDAContextScope scope(this);
+
+ /* for multi devices, this assumes the inefficient method that we allocate
+ * all pixels on the device even though we only render to a subset */
+ size_t offset = 4 * y * w;
+
+ if (mem.data_type == TYPE_HALF)
+ offset *= sizeof(GLhalf);
+ else
+ offset *= sizeof(uint8_t);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
+ if (mem.data_type == TYPE_HALF) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_HALF_FLOAT, (void *)offset);
+ }
+ else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void *)offset);
+ }
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ if (transparent) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ GLint shader_program;
+ if (use_fallback_shader) {
+ if (!bind_fallback_display_space_shader(dw, dh)) {
+ return;
+ }
+ shader_program = fallback_shader_program;
+ }
+ else {
+ draw_params.bind_display_space_shader_cb();
+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
+ }
+
+ if (!vertex_buffer) {
+ glGenBuffers(1, &vertex_buffer);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+ /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
+ glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+ vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+ if (vpointer) {
+ /* texture coordinate - vertex pair */
+ vpointer[0] = 0.0f;
+ vpointer[1] = 0.0f;
+ vpointer[2] = dx;
+ vpointer[3] = dy;
+
+ vpointer[4] = (float)w / (float)pmem.w;
+ vpointer[5] = 0.0f;
+ vpointer[6] = (float)width + dx;
+ vpointer[7] = dy;
+
+ vpointer[8] = (float)w / (float)pmem.w;
+ vpointer[9] = (float)h / (float)pmem.h;
+ vpointer[10] = (float)width + dx;
+ vpointer[11] = (float)height + dy;
+
+ vpointer[12] = 0.0f;
+ vpointer[13] = (float)h / (float)pmem.h;
+ vpointer[14] = dx;
+ vpointer[15] = (float)height + dy;
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ }
+
+ GLuint vertex_array_object;
+ GLuint position_attribute, texcoord_attribute;
+
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
+
+ texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+ position_attribute = glGetAttribLocation(shader_program, "pos");
+
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
+
+ glVertexAttribPointer(
+ texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute,
+ 2,
+ GL_FLOAT,
+ GL_FALSE,
+ 4 * sizeof(float),
+ (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if (use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
+ if (transparent) {
+ glDisable(GL_BLEND);
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ return;
+ }
+
+ Device::draw_pixels(mem, y, w, h, width, height, dx, dy, dw, dh, transparent, draw_params);
+ }
+
+ void thread_run(DeviceTask *task)
+ {
+ CUDAContextScope scope(this);
+
+ if (task->type == DeviceTask::RENDER) {
+ DeviceRequestedFeatures requested_features;
+ if (use_split_kernel()) {
+ if (split_kernel == NULL) {
+ split_kernel = new CUDASplitKernel(this);
+ split_kernel->load_kernels(requested_features);
+ }
+ }
+
+ device_vector<WorkTile> work_tiles(this, "work_tiles", MEM_READ_ONLY);
+
+ /* keep rendering tiles until done */
+ RenderTile tile;
+ DenoisingTask denoising(this, *task);
+
+ while (task->acquire_tile(this, tile)) {
+ if (tile.task == RenderTile::PATH_TRACE) {
+ if (use_split_kernel()) {
+ device_only_memory<uchar> void_buffer(this, "void_buffer");
+ split_kernel->path_trace(task, tile, void_buffer, void_buffer);
+ }
+ else {
+ path_trace(*task, tile, work_tiles);
+ }
+ }
+ else if (tile.task == RenderTile::DENOISE) {
+ tile.sample = tile.start_sample + tile.num_samples;
+
+ denoise(tile, denoising);
+
+ task->update_progress(&tile, tile.w * tile.h);
+ }
+
+ task->release_tile(tile);
+
+ if (task->get_cancel()) {
+ if (task->need_finish_queue == false)
+ break;
+ }
+ }
+
+ work_tiles.free();
+ }
+ else if (task->type == DeviceTask::SHADER) {
+ shader(*task);
+
+ cuda_assert(cuCtxSynchronize());
+ }
+ }
+
+ class CUDADeviceTask : public DeviceTask {
+ public:
+ CUDADeviceTask(CUDADevice *device, DeviceTask &task) : DeviceTask(task)
+ {
+ run = function_bind(&CUDADevice::thread_run, device, this);
+ }
+ };
+
+ int get_split_task_count(DeviceTask & /*task*/)
+ {
+ return 1;
+ }
+
+ void task_add(DeviceTask &task)
+ {
+ CUDAContextScope scope(this);
+
+ /* Load texture info. */
+ load_texture_info();
+
+ /* Synchronize all memory copies before executing task. */
+ cuda_assert(cuCtxSynchronize());
+
+ if (task.type == DeviceTask::FILM_CONVERT) {
+ /* must be done in main thread due to opengl access */
+ film_convert(task, task.buffer, task.rgba_byte, task.rgba_half);
+ }
+ else {
+ task_pool.push(new CUDADeviceTask(this, task));
+ }
+ }
+
+ void task_wait()
+ {
+ task_pool.wait();
+ }
+
+ void task_cancel()
+ {
+ task_pool.cancel();
+ }
+
+ friend class CUDASplitKernelFunction;
+ friend class CUDASplitKernel;
+ friend class CUDAContextScope;
};
/* redefine the cuda_assert macro so it can be used outside of the CUDADevice class
@@ -2207,496 +2305,501 @@ public:
*/
#undef cuda_assert
#define cuda_assert(stmt) \
- { \
- CUresult result = stmt; \
- \
- if(result != CUDA_SUCCESS) { \
- string message = string_printf("CUDA error: %s in %s", cuewErrorString(result), #stmt); \
- if(device->error_msg == "") \
- device->error_msg = message; \
- fprintf(stderr, "%s\n", message.c_str()); \
- /*cuda_abort();*/ \
- device->cuda_error_documentation(); \
- } \
- } (void) 0
-
+ { \
+ CUresult result = stmt; \
+\
+ if (result != CUDA_SUCCESS) { \
+ string message = string_printf("CUDA error: %s in %s", cuewErrorString(result), #stmt); \
+ if (device->error_msg == "") \
+ device->error_msg = message; \
+ fprintf(stderr, "%s\n", message.c_str()); \
+ /*cuda_abort();*/ \
+ device->cuda_error_documentation(); \
+ } \
+ } \
+ (void)0
/* CUDA context scope. */
-CUDAContextScope::CUDAContextScope(CUDADevice *device)
-: device(device)
+CUDAContextScope::CUDAContextScope(CUDADevice *device) : device(device)
{
- cuda_assert(cuCtxPushCurrent(device->cuContext));
+ cuda_assert(cuCtxPushCurrent(device->cuContext));
}
CUDAContextScope::~CUDAContextScope()
{
- cuda_assert(cuCtxPopCurrent(NULL));
+ cuda_assert(cuCtxPopCurrent(NULL));
}
/* split kernel */
-class CUDASplitKernelFunction : public SplitKernelFunction{
- CUDADevice* device;
- CUfunction func;
-public:
- CUDASplitKernelFunction(CUDADevice *device, CUfunction func) : device(device), func(func) {}
-
- /* enqueue the kernel, returns false if there is an error */
- bool enqueue(const KernelDimensions &dim, device_memory &/*kg*/, device_memory &/*data*/)
- {
- return enqueue(dim, NULL);
- }
-
- /* enqueue the kernel, returns false if there is an error */
- bool enqueue(const KernelDimensions &dim, void *args[])
- {
- if(device->have_error())
- return false;
-
- CUDAContextScope scope(device);
-
- /* we ignore dim.local_size for now, as this is faster */
- int threads_per_block;
- cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, func));
-
- int xblocks = (dim.global_size[0]*dim.global_size[1] + threads_per_block - 1)/threads_per_block;
-
- cuda_assert(cuFuncSetCacheConfig(func, CU_FUNC_CACHE_PREFER_L1));
-
- cuda_assert(cuLaunchKernel(func,
- xblocks, 1, 1, /* blocks */
- threads_per_block, 1, 1, /* threads */
- 0, 0, args, 0));
-
- return !device->have_error();
- }
+class CUDASplitKernelFunction : public SplitKernelFunction {
+ CUDADevice *device;
+ CUfunction func;
+
+ public:
+ CUDASplitKernelFunction(CUDADevice *device, CUfunction func) : device(device), func(func)
+ {
+ }
+
+ /* enqueue the kernel, returns false if there is an error */
+ bool enqueue(const KernelDimensions &dim, device_memory & /*kg*/, device_memory & /*data*/)
+ {
+ return enqueue(dim, NULL);
+ }
+
+ /* enqueue the kernel, returns false if there is an error */
+ bool enqueue(const KernelDimensions &dim, void *args[])
+ {
+ if (device->have_error())
+ return false;
+
+ CUDAContextScope scope(device);
+
+ /* we ignore dim.local_size for now, as this is faster */
+ int threads_per_block;
+ cuda_assert(
+ cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, func));
+
+ int xblocks = (dim.global_size[0] * dim.global_size[1] + threads_per_block - 1) /
+ threads_per_block;
+
+ cuda_assert(cuFuncSetCacheConfig(func, CU_FUNC_CACHE_PREFER_L1));
+
+ cuda_assert(cuLaunchKernel(func,
+ xblocks,
+ 1,
+ 1, /* blocks */
+ threads_per_block,
+ 1,
+ 1, /* threads */
+ 0,
+ 0,
+ args,
+ 0));
+
+ return !device->have_error();
+ }
};
CUDASplitKernel::CUDASplitKernel(CUDADevice *device) : DeviceSplitKernel(device), device(device)
{
}
-uint64_t CUDASplitKernel::state_buffer_size(device_memory& /*kg*/, device_memory& /*data*/, size_t num_threads)
+uint64_t CUDASplitKernel::state_buffer_size(device_memory & /*kg*/,
+ device_memory & /*data*/,
+ size_t num_threads)
{
- CUDAContextScope scope(device);
+ CUDAContextScope scope(device);
- device_vector<uint64_t> size_buffer(device, "size_buffer", MEM_READ_WRITE);
- size_buffer.alloc(1);
- size_buffer.zero_to_device();
+ device_vector<uint64_t> size_buffer(device, "size_buffer", MEM_READ_WRITE);
+ size_buffer.alloc(1);
+ size_buffer.zero_to_device();
- uint threads = num_threads;
- CUdeviceptr d_size = device->cuda_device_ptr(size_buffer.device_pointer);
+ uint threads = num_threads;
+ CUdeviceptr d_size = device->cuda_device_ptr(size_buffer.device_pointer);
- struct args_t {
- uint* num_threads;
- CUdeviceptr* size;
- };
+ struct args_t {
+ uint *num_threads;
+ CUdeviceptr *size;
+ };
- args_t args = {
- &threads,
- &d_size
- };
+ args_t args = {&threads, &d_size};
- CUfunction state_buffer_size;
- cuda_assert(cuModuleGetFunction(&state_buffer_size, device->cuModule, "kernel_cuda_state_buffer_size"));
+ CUfunction state_buffer_size;
+ cuda_assert(
+ cuModuleGetFunction(&state_buffer_size, device->cuModule, "kernel_cuda_state_buffer_size"));
- cuda_assert(cuLaunchKernel(state_buffer_size,
- 1, 1, 1,
- 1, 1, 1,
- 0, 0, (void**)&args, 0));
+ cuda_assert(cuLaunchKernel(state_buffer_size, 1, 1, 1, 1, 1, 1, 0, 0, (void **)&args, 0));
- size_buffer.copy_from_device(0, 1, 1);
- size_t size = size_buffer[0];
- size_buffer.free();
+ size_buffer.copy_from_device(0, 1, 1);
+ size_t size = size_buffer[0];
+ size_buffer.free();
- return size;
+ return size;
}
-bool CUDASplitKernel::enqueue_split_kernel_data_init(const KernelDimensions& dim,
- RenderTile& rtile,
- int num_global_elements,
- device_memory& /*kernel_globals*/,
- device_memory& /*kernel_data*/,
- device_memory& split_data,
- device_memory& ray_state,
- device_memory& queue_index,
- device_memory& use_queues_flag,
- device_memory& work_pool_wgs)
+bool CUDASplitKernel::enqueue_split_kernel_data_init(const KernelDimensions &dim,
+ RenderTile &rtile,
+ int num_global_elements,
+ device_memory & /*kernel_globals*/,
+ device_memory & /*kernel_data*/,
+ device_memory &split_data,
+ device_memory &ray_state,
+ device_memory &queue_index,
+ device_memory &use_queues_flag,
+ device_memory &work_pool_wgs)
{
- CUDAContextScope scope(device);
-
- CUdeviceptr d_split_data = device->cuda_device_ptr(split_data.device_pointer);
- CUdeviceptr d_ray_state = device->cuda_device_ptr(ray_state.device_pointer);
- CUdeviceptr d_queue_index = device->cuda_device_ptr(queue_index.device_pointer);
- CUdeviceptr d_use_queues_flag = device->cuda_device_ptr(use_queues_flag.device_pointer);
- CUdeviceptr d_work_pool_wgs = device->cuda_device_ptr(work_pool_wgs.device_pointer);
-
- CUdeviceptr d_buffer = device->cuda_device_ptr(rtile.buffer);
-
- int end_sample = rtile.start_sample + rtile.num_samples;
- int queue_size = dim.global_size[0] * dim.global_size[1];
-
- struct args_t {
- CUdeviceptr* split_data_buffer;
- int* num_elements;
- CUdeviceptr* ray_state;
- int* start_sample;
- int* end_sample;
- int* sx;
- int* sy;
- int* sw;
- int* sh;
- int* offset;
- int* stride;
- CUdeviceptr* queue_index;
- int* queuesize;
- CUdeviceptr* use_queues_flag;
- CUdeviceptr* work_pool_wgs;
- int* num_samples;
- CUdeviceptr* buffer;
- };
-
- args_t args = {
- &d_split_data,
- &num_global_elements,
- &d_ray_state,
- &rtile.start_sample,
- &end_sample,
- &rtile.x,
- &rtile.y,
- &rtile.w,
- &rtile.h,
- &rtile.offset,
- &rtile.stride,
- &d_queue_index,
- &queue_size,
- &d_use_queues_flag,
- &d_work_pool_wgs,
- &rtile.num_samples,
- &d_buffer
- };
-
- CUfunction data_init;
- cuda_assert(cuModuleGetFunction(&data_init, device->cuModule, "kernel_cuda_path_trace_data_init"));
- if(device->have_error()) {
- return false;
- }
-
- CUDASplitKernelFunction(device, data_init).enqueue(dim, (void**)&args);
-
- return !device->have_error();
+ CUDAContextScope scope(device);
+
+ CUdeviceptr d_split_data = device->cuda_device_ptr(split_data.device_pointer);
+ CUdeviceptr d_ray_state = device->cuda_device_ptr(ray_state.device_pointer);
+ CUdeviceptr d_queue_index = device->cuda_device_ptr(queue_index.device_pointer);
+ CUdeviceptr d_use_queues_flag = device->cuda_device_ptr(use_queues_flag.device_pointer);
+ CUdeviceptr d_work_pool_wgs = device->cuda_device_ptr(work_pool_wgs.device_pointer);
+
+ CUdeviceptr d_buffer = device->cuda_device_ptr(rtile.buffer);
+
+ int end_sample = rtile.start_sample + rtile.num_samples;
+ int queue_size = dim.global_size[0] * dim.global_size[1];
+
+ struct args_t {
+ CUdeviceptr *split_data_buffer;
+ int *num_elements;
+ CUdeviceptr *ray_state;
+ int *start_sample;
+ int *end_sample;
+ int *sx;
+ int *sy;
+ int *sw;
+ int *sh;
+ int *offset;
+ int *stride;
+ CUdeviceptr *queue_index;
+ int *queuesize;
+ CUdeviceptr *use_queues_flag;
+ CUdeviceptr *work_pool_wgs;
+ int *num_samples;
+ CUdeviceptr *buffer;
+ };
+
+ args_t args = {&d_split_data,
+ &num_global_elements,
+ &d_ray_state,
+ &rtile.start_sample,
+ &end_sample,
+ &rtile.x,
+ &rtile.y,
+ &rtile.w,
+ &rtile.h,
+ &rtile.offset,
+ &rtile.stride,
+ &d_queue_index,
+ &queue_size,
+ &d_use_queues_flag,
+ &d_work_pool_wgs,
+ &rtile.num_samples,
+ &d_buffer};
+
+ CUfunction data_init;
+ cuda_assert(
+ cuModuleGetFunction(&data_init, device->cuModule, "kernel_cuda_path_trace_data_init"));
+ if (device->have_error()) {
+ return false;
+ }
+
+ CUDASplitKernelFunction(device, data_init).enqueue(dim, (void **)&args);
+
+ return !device->have_error();
}
-SplitKernelFunction* CUDASplitKernel::get_split_kernel_function(const string& kernel_name,
- const DeviceRequestedFeatures&)
+SplitKernelFunction *CUDASplitKernel::get_split_kernel_function(const string &kernel_name,
+ const DeviceRequestedFeatures &)
{
- CUDAContextScope scope(device);
- CUfunction func;
-
- cuda_assert(cuModuleGetFunction(&func, device->cuModule, (string("kernel_cuda_") + kernel_name).data()));
- if(device->have_error()) {
- device->cuda_error_message(string_printf("kernel \"kernel_cuda_%s\" not found in module", kernel_name.data()));
- return NULL;
- }
-
- return new CUDASplitKernelFunction(device, func);
+ CUDAContextScope scope(device);
+ CUfunction func;
+
+ cuda_assert(
+ cuModuleGetFunction(&func, device->cuModule, (string("kernel_cuda_") + kernel_name).data()));
+ if (device->have_error()) {
+ device->cuda_error_message(
+ string_printf("kernel \"kernel_cuda_%s\" not found in module", kernel_name.data()));
+ return NULL;
+ }
+
+ return new CUDASplitKernelFunction(device, func);
}
int2 CUDASplitKernel::split_kernel_local_size()
{
- return make_int2(32, 1);
+ return make_int2(32, 1);
}
-int2 CUDASplitKernel::split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask * /*task*/)
+int2 CUDASplitKernel::split_kernel_global_size(device_memory &kg,
+ device_memory &data,
+ DeviceTask * /*task*/)
{
- CUDAContextScope scope(device);
- size_t free;
- size_t total;
+ CUDAContextScope scope(device);
+ size_t free;
+ size_t total;
- cuda_assert(cuMemGetInfo(&free, &total));
+ cuda_assert(cuMemGetInfo(&free, &total));
- VLOG(1) << "Maximum device allocation size: "
- << string_human_readable_number(free) << " bytes. ("
- << string_human_readable_size(free) << ").";
+ VLOG(1) << "Maximum device allocation size: " << string_human_readable_number(free)
+ << " bytes. (" << string_human_readable_size(free) << ").";
- size_t num_elements = max_elements_for_max_buffer_size(kg, data, free / 2);
- size_t side = round_down((int)sqrt(num_elements), 32);
- int2 global_size = make_int2(side, round_down(num_elements / side, 16));
- VLOG(1) << "Global size: " << global_size << ".";
- return global_size;
+ size_t num_elements = max_elements_for_max_buffer_size(kg, data, free / 2);
+ size_t side = round_down((int)sqrt(num_elements), 32);
+ int2 global_size = make_int2(side, round_down(num_elements / side, 16));
+ VLOG(1) << "Global size: " << global_size << ".";
+ return global_size;
}
bool device_cuda_init()
{
#ifdef WITH_CUDA_DYNLOAD
- static bool initialized = false;
- static bool result = false;
-
- if(initialized)
- return result;
-
- initialized = true;
- int cuew_result = cuewInit(CUEW_INIT_CUDA);
- if(cuew_result == CUEW_SUCCESS) {
- VLOG(1) << "CUEW initialization succeeded";
- if(CUDADevice::have_precompiled_kernels()) {
- VLOG(1) << "Found precompiled kernels";
- result = true;
- }
-#ifndef _WIN32
- else if(cuewCompilerPath() != NULL) {
- VLOG(1) << "Found CUDA compiler " << cuewCompilerPath();
- result = true;
- }
- else {
- VLOG(1) << "Neither precompiled kernels nor CUDA compiler was found,"
- << " unable to use CUDA";
- }
-#endif
- }
- else {
- VLOG(1) << "CUEW initialization failed: "
- << ((cuew_result == CUEW_ERROR_ATEXIT_FAILED)
- ? "Error setting up atexit() handler"
- : "Error opening the library");
- }
-
- return result;
+ static bool initialized = false;
+ static bool result = false;
+
+ if (initialized)
+ return result;
+
+ initialized = true;
+ int cuew_result = cuewInit(CUEW_INIT_CUDA);
+ if (cuew_result == CUEW_SUCCESS) {
+ VLOG(1) << "CUEW initialization succeeded";
+ if (CUDADevice::have_precompiled_kernels()) {
+ VLOG(1) << "Found precompiled kernels";
+ result = true;
+ }
+# ifndef _WIN32
+ else if (cuewCompilerPath() != NULL) {
+ VLOG(1) << "Found CUDA compiler " << cuewCompilerPath();
+ result = true;
+ }
+ else {
+ VLOG(1) << "Neither precompiled kernels nor CUDA compiler was found,"
+ << " unable to use CUDA";
+ }
+# endif
+ }
+ else {
+ VLOG(1) << "CUEW initialization failed: "
+ << ((cuew_result == CUEW_ERROR_ATEXIT_FAILED) ? "Error setting up atexit() handler" :
+ "Error opening the library");
+ }
+
+ return result;
#else /* WITH_CUDA_DYNLOAD */
- return true;
-#endif /* WITH_CUDA_DYNLOAD */
+ return true;
+#endif /* WITH_CUDA_DYNLOAD */
}
-Device *device_cuda_create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background)
+Device *device_cuda_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background)
{
- return new CUDADevice(info, stats, profiler, background);
+ return new CUDADevice(info, stats, profiler, background);
}
static CUresult device_cuda_safe_init()
{
#ifdef _WIN32
- __try {
- return cuInit(0);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- /* Ignore crashes inside the CUDA driver and hope we can
- * survive even with corrupted CUDA installs. */
- fprintf(stderr, "Cycles CUDA: driver crashed, continuing without CUDA.\n");
- }
-
- return CUDA_ERROR_NO_DEVICE;
+ __try {
+ return cuInit(0);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ /* Ignore crashes inside the CUDA driver and hope we can
+ * survive even with corrupted CUDA installs. */
+ fprintf(stderr, "Cycles CUDA: driver crashed, continuing without CUDA.\n");
+ }
+
+ return CUDA_ERROR_NO_DEVICE;
#else
- return cuInit(0);
+ return cuInit(0);
#endif
}
-void device_cuda_info(vector<DeviceInfo>& devices)
+void device_cuda_info(vector<DeviceInfo> &devices)
{
- CUresult result = device_cuda_safe_init();
- if(result != CUDA_SUCCESS) {
- if(result != CUDA_ERROR_NO_DEVICE)
- fprintf(stderr, "CUDA cuInit: %s\n", cuewErrorString(result));
- return;
- }
-
- int count = 0;
- result = cuDeviceGetCount(&count);
- if(result != CUDA_SUCCESS) {
- fprintf(stderr, "CUDA cuDeviceGetCount: %s\n", cuewErrorString(result));
- return;
- }
-
- vector<DeviceInfo> display_devices;
-
- for(int num = 0; num < count; num++) {
- char name[256];
-
- result = cuDeviceGetName(name, 256, num);
- if(result != CUDA_SUCCESS) {
- fprintf(stderr, "CUDA cuDeviceGetName: %s\n", cuewErrorString(result));
- continue;
- }
-
- int major;
- cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, num);
- if(major < 3) {
- VLOG(1) << "Ignoring device \"" << name
- << "\", this graphics card is no longer supported.";
- continue;
- }
-
- DeviceInfo info;
-
- info.type = DEVICE_CUDA;
- info.description = string(name);
- info.num = num;
-
- info.has_half_images = (major >= 3);
- info.has_volume_decoupled = false;
-
- int pci_location[3] = {0, 0, 0};
- cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num);
- cuDeviceGetAttribute(&pci_location[1], CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, num);
- cuDeviceGetAttribute(&pci_location[2], CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, num);
- info.id = string_printf("CUDA_%s_%04x:%02x:%02x",
- name,
- (unsigned int)pci_location[0],
- (unsigned int)pci_location[1],
- (unsigned int)pci_location[2]);
-
- /* If device has a kernel timeout and no compute preemption, we assume
- * it is connected to a display and will freeze the display while doing
- * computations. */
- int timeout_attr = 0, preempt_attr = 0;
- cuDeviceGetAttribute(&timeout_attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num);
- cuDeviceGetAttribute(&preempt_attr, CU_DEVICE_ATTRIBUTE_COMPUTE_PREEMPTION_SUPPORTED, num);
-
- if(timeout_attr && !preempt_attr) {
- VLOG(1) << "Device is recognized as display.";
- info.description += " (Display)";
- info.display_device = true;
- display_devices.push_back(info);
- }
- else {
- devices.push_back(info);
- }
- VLOG(1) << "Added device \"" << name << "\" with id \"" << info.id << "\".";
- }
-
- if(!display_devices.empty())
- devices.insert(devices.end(), display_devices.begin(), display_devices.end());
+ CUresult result = device_cuda_safe_init();
+ if (result != CUDA_SUCCESS) {
+ if (result != CUDA_ERROR_NO_DEVICE)
+ fprintf(stderr, "CUDA cuInit: %s\n", cuewErrorString(result));
+ return;
+ }
+
+ int count = 0;
+ result = cuDeviceGetCount(&count);
+ if (result != CUDA_SUCCESS) {
+ fprintf(stderr, "CUDA cuDeviceGetCount: %s\n", cuewErrorString(result));
+ return;
+ }
+
+ vector<DeviceInfo> display_devices;
+
+ for (int num = 0; num < count; num++) {
+ char name[256];
+
+ result = cuDeviceGetName(name, 256, num);
+ if (result != CUDA_SUCCESS) {
+ fprintf(stderr, "CUDA cuDeviceGetName: %s\n", cuewErrorString(result));
+ continue;
+ }
+
+ int major;
+ cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, num);
+ if (major < 3) {
+ VLOG(1) << "Ignoring device \"" << name << "\", this graphics card is no longer supported.";
+ continue;
+ }
+
+ DeviceInfo info;
+
+ info.type = DEVICE_CUDA;
+ info.description = string(name);
+ info.num = num;
+
+ info.has_half_images = (major >= 3);
+ info.has_volume_decoupled = false;
+
+ int pci_location[3] = {0, 0, 0};
+ cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num);
+ cuDeviceGetAttribute(&pci_location[1], CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, num);
+ cuDeviceGetAttribute(&pci_location[2], CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, num);
+ info.id = string_printf("CUDA_%s_%04x:%02x:%02x",
+ name,
+ (unsigned int)pci_location[0],
+ (unsigned int)pci_location[1],
+ (unsigned int)pci_location[2]);
+
+ /* If device has a kernel timeout and no compute preemption, we assume
+ * it is connected to a display and will freeze the display while doing
+ * computations. */
+ int timeout_attr = 0, preempt_attr = 0;
+ cuDeviceGetAttribute(&timeout_attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num);
+ cuDeviceGetAttribute(&preempt_attr, CU_DEVICE_ATTRIBUTE_COMPUTE_PREEMPTION_SUPPORTED, num);
+
+ if (timeout_attr && !preempt_attr) {
+ VLOG(1) << "Device is recognized as display.";
+ info.description += " (Display)";
+ info.display_device = true;
+ display_devices.push_back(info);
+ }
+ else {
+ devices.push_back(info);
+ }
+ VLOG(1) << "Added device \"" << name << "\" with id \"" << info.id << "\".";
+ }
+
+ if (!display_devices.empty())
+ devices.insert(devices.end(), display_devices.begin(), display_devices.end());
}
string device_cuda_capabilities()
{
- CUresult result = device_cuda_safe_init();
- if(result != CUDA_SUCCESS) {
- if(result != CUDA_ERROR_NO_DEVICE) {
- return string("Error initializing CUDA: ") + cuewErrorString(result);
- }
- return "No CUDA device found\n";
- }
-
- int count;
- result = cuDeviceGetCount(&count);
- if(result != CUDA_SUCCESS) {
- return string("Error getting devices: ") + cuewErrorString(result);
- }
-
- string capabilities = "";
- for(int num = 0; num < count; num++) {
- char name[256];
- if(cuDeviceGetName(name, 256, num) != CUDA_SUCCESS) {
- continue;
- }
- capabilities += string("\t") + name + "\n";
- int value;
+ CUresult result = device_cuda_safe_init();
+ if (result != CUDA_SUCCESS) {
+ if (result != CUDA_ERROR_NO_DEVICE) {
+ return string("Error initializing CUDA: ") + cuewErrorString(result);
+ }
+ return "No CUDA device found\n";
+ }
+
+ int count;
+ result = cuDeviceGetCount(&count);
+ if (result != CUDA_SUCCESS) {
+ return string("Error getting devices: ") + cuewErrorString(result);
+ }
+
+ string capabilities = "";
+ for (int num = 0; num < count; num++) {
+ char name[256];
+ if (cuDeviceGetName(name, 256, num) != CUDA_SUCCESS) {
+ continue;
+ }
+ capabilities += string("\t") + name + "\n";
+ int value;
#define GET_ATTR(attr) \
- { \
- if(cuDeviceGetAttribute(&value, \
- CU_DEVICE_ATTRIBUTE_##attr, \
- num) == CUDA_SUCCESS) \
- { \
- capabilities += string_printf("\t\tCU_DEVICE_ATTRIBUTE_" #attr "\t\t\t%d\n", \
- value); \
- } \
- } (void) 0
- /* TODO(sergey): Strip all attributes which are not useful for us
- * or does not depend on the driver.
- */
- GET_ATTR(MAX_THREADS_PER_BLOCK);
- GET_ATTR(MAX_BLOCK_DIM_X);
- GET_ATTR(MAX_BLOCK_DIM_Y);
- GET_ATTR(MAX_BLOCK_DIM_Z);
- GET_ATTR(MAX_GRID_DIM_X);
- GET_ATTR(MAX_GRID_DIM_Y);
- GET_ATTR(MAX_GRID_DIM_Z);
- GET_ATTR(MAX_SHARED_MEMORY_PER_BLOCK);
- GET_ATTR(SHARED_MEMORY_PER_BLOCK);
- GET_ATTR(TOTAL_CONSTANT_MEMORY);
- GET_ATTR(WARP_SIZE);
- GET_ATTR(MAX_PITCH);
- GET_ATTR(MAX_REGISTERS_PER_BLOCK);
- GET_ATTR(REGISTERS_PER_BLOCK);
- GET_ATTR(CLOCK_RATE);
- GET_ATTR(TEXTURE_ALIGNMENT);
- GET_ATTR(GPU_OVERLAP);
- GET_ATTR(MULTIPROCESSOR_COUNT);
- GET_ATTR(KERNEL_EXEC_TIMEOUT);
- GET_ATTR(INTEGRATED);
- GET_ATTR(CAN_MAP_HOST_MEMORY);
- GET_ATTR(COMPUTE_MODE);
- GET_ATTR(MAXIMUM_TEXTURE1D_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_HEIGHT);
- GET_ATTR(MAXIMUM_TEXTURE3D_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE3D_HEIGHT);
- GET_ATTR(MAXIMUM_TEXTURE3D_DEPTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_HEIGHT);
- GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_LAYERS);
- GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_HEIGHT);
- GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES);
- GET_ATTR(SURFACE_ALIGNMENT);
- GET_ATTR(CONCURRENT_KERNELS);
- GET_ATTR(ECC_ENABLED);
- GET_ATTR(TCC_DRIVER);
- GET_ATTR(MEMORY_CLOCK_RATE);
- GET_ATTR(GLOBAL_MEMORY_BUS_WIDTH);
- GET_ATTR(L2_CACHE_SIZE);
- GET_ATTR(MAX_THREADS_PER_MULTIPROCESSOR);
- GET_ATTR(ASYNC_ENGINE_COUNT);
- GET_ATTR(UNIFIED_ADDRESSING);
- GET_ATTR(MAXIMUM_TEXTURE1D_LAYERED_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE1D_LAYERED_LAYERS);
- GET_ATTR(CAN_TEX2D_GATHER);
- GET_ATTR(MAXIMUM_TEXTURE2D_GATHER_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_GATHER_HEIGHT);
- GET_ATTR(MAXIMUM_TEXTURE3D_WIDTH_ALTERNATE);
- GET_ATTR(MAXIMUM_TEXTURE3D_HEIGHT_ALTERNATE);
- GET_ATTR(MAXIMUM_TEXTURE3D_DEPTH_ALTERNATE);
- GET_ATTR(TEXTURE_PITCH_ALIGNMENT);
- GET_ATTR(MAXIMUM_TEXTURECUBEMAP_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURECUBEMAP_LAYERED_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURECUBEMAP_LAYERED_LAYERS);
- GET_ATTR(MAXIMUM_SURFACE1D_WIDTH);
- GET_ATTR(MAXIMUM_SURFACE2D_WIDTH);
- GET_ATTR(MAXIMUM_SURFACE2D_HEIGHT);
- GET_ATTR(MAXIMUM_SURFACE3D_WIDTH);
- GET_ATTR(MAXIMUM_SURFACE3D_HEIGHT);
- GET_ATTR(MAXIMUM_SURFACE3D_DEPTH);
- GET_ATTR(MAXIMUM_SURFACE1D_LAYERED_WIDTH);
- GET_ATTR(MAXIMUM_SURFACE1D_LAYERED_LAYERS);
- GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_WIDTH);
- GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_HEIGHT);
- GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_LAYERS);
- GET_ATTR(MAXIMUM_SURFACECUBEMAP_WIDTH);
- GET_ATTR(MAXIMUM_SURFACECUBEMAP_LAYERED_WIDTH);
- GET_ATTR(MAXIMUM_SURFACECUBEMAP_LAYERED_LAYERS);
- GET_ATTR(MAXIMUM_TEXTURE1D_LINEAR_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_HEIGHT);
- GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_PITCH);
- GET_ATTR(MAXIMUM_TEXTURE2D_MIPMAPPED_WIDTH);
- GET_ATTR(MAXIMUM_TEXTURE2D_MIPMAPPED_HEIGHT);
- GET_ATTR(COMPUTE_CAPABILITY_MAJOR);
- GET_ATTR(COMPUTE_CAPABILITY_MINOR);
- GET_ATTR(MAXIMUM_TEXTURE1D_MIPMAPPED_WIDTH);
- GET_ATTR(STREAM_PRIORITIES_SUPPORTED);
- GET_ATTR(GLOBAL_L1_CACHE_SUPPORTED);
- GET_ATTR(LOCAL_L1_CACHE_SUPPORTED);
- GET_ATTR(MAX_SHARED_MEMORY_PER_MULTIPROCESSOR);
- GET_ATTR(MAX_REGISTERS_PER_MULTIPROCESSOR);
- GET_ATTR(MANAGED_MEMORY);
- GET_ATTR(MULTI_GPU_BOARD);
- GET_ATTR(MULTI_GPU_BOARD_GROUP_ID);
+ { \
+ if (cuDeviceGetAttribute(&value, CU_DEVICE_ATTRIBUTE_##attr, num) == CUDA_SUCCESS) { \
+ capabilities += string_printf("\t\tCU_DEVICE_ATTRIBUTE_" #attr "\t\t\t%d\n", value); \
+ } \
+ } \
+ (void)0
+ /* TODO(sergey): Strip all attributes which are not useful for us
+ * or does not depend on the driver.
+ */
+ GET_ATTR(MAX_THREADS_PER_BLOCK);
+ GET_ATTR(MAX_BLOCK_DIM_X);
+ GET_ATTR(MAX_BLOCK_DIM_Y);
+ GET_ATTR(MAX_BLOCK_DIM_Z);
+ GET_ATTR(MAX_GRID_DIM_X);
+ GET_ATTR(MAX_GRID_DIM_Y);
+ GET_ATTR(MAX_GRID_DIM_Z);
+ GET_ATTR(MAX_SHARED_MEMORY_PER_BLOCK);
+ GET_ATTR(SHARED_MEMORY_PER_BLOCK);
+ GET_ATTR(TOTAL_CONSTANT_MEMORY);
+ GET_ATTR(WARP_SIZE);
+ GET_ATTR(MAX_PITCH);
+ GET_ATTR(MAX_REGISTERS_PER_BLOCK);
+ GET_ATTR(REGISTERS_PER_BLOCK);
+ GET_ATTR(CLOCK_RATE);
+ GET_ATTR(TEXTURE_ALIGNMENT);
+ GET_ATTR(GPU_OVERLAP);
+ GET_ATTR(MULTIPROCESSOR_COUNT);
+ GET_ATTR(KERNEL_EXEC_TIMEOUT);
+ GET_ATTR(INTEGRATED);
+ GET_ATTR(CAN_MAP_HOST_MEMORY);
+ GET_ATTR(COMPUTE_MODE);
+ GET_ATTR(MAXIMUM_TEXTURE1D_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE3D_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE3D_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE3D_DEPTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES);
+ GET_ATTR(SURFACE_ALIGNMENT);
+ GET_ATTR(CONCURRENT_KERNELS);
+ GET_ATTR(ECC_ENABLED);
+ GET_ATTR(TCC_DRIVER);
+ GET_ATTR(MEMORY_CLOCK_RATE);
+ GET_ATTR(GLOBAL_MEMORY_BUS_WIDTH);
+ GET_ATTR(L2_CACHE_SIZE);
+ GET_ATTR(MAX_THREADS_PER_MULTIPROCESSOR);
+ GET_ATTR(ASYNC_ENGINE_COUNT);
+ GET_ATTR(UNIFIED_ADDRESSING);
+ GET_ATTR(MAXIMUM_TEXTURE1D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE1D_LAYERED_LAYERS);
+ GET_ATTR(CAN_TEX2D_GATHER);
+ GET_ATTR(MAXIMUM_TEXTURE2D_GATHER_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_GATHER_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE3D_WIDTH_ALTERNATE);
+ GET_ATTR(MAXIMUM_TEXTURE3D_HEIGHT_ALTERNATE);
+ GET_ATTR(MAXIMUM_TEXTURE3D_DEPTH_ALTERNATE);
+ GET_ATTR(TEXTURE_PITCH_ALIGNMENT);
+ GET_ATTR(MAXIMUM_TEXTURECUBEMAP_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURECUBEMAP_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURECUBEMAP_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_SURFACE1D_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE2D_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE2D_HEIGHT);
+ GET_ATTR(MAXIMUM_SURFACE3D_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE3D_HEIGHT);
+ GET_ATTR(MAXIMUM_SURFACE3D_DEPTH);
+ GET_ATTR(MAXIMUM_SURFACE1D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE1D_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_HEIGHT);
+ GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_SURFACECUBEMAP_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACECUBEMAP_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACECUBEMAP_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_TEXTURE1D_LINEAR_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_PITCH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_MIPMAPPED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_MIPMAPPED_HEIGHT);
+ GET_ATTR(COMPUTE_CAPABILITY_MAJOR);
+ GET_ATTR(COMPUTE_CAPABILITY_MINOR);
+ GET_ATTR(MAXIMUM_TEXTURE1D_MIPMAPPED_WIDTH);
+ GET_ATTR(STREAM_PRIORITIES_SUPPORTED);
+ GET_ATTR(GLOBAL_L1_CACHE_SUPPORTED);
+ GET_ATTR(LOCAL_L1_CACHE_SUPPORTED);
+ GET_ATTR(MAX_SHARED_MEMORY_PER_MULTIPROCESSOR);
+ GET_ATTR(MAX_REGISTERS_PER_MULTIPROCESSOR);
+ GET_ATTR(MANAGED_MEMORY);
+ GET_ATTR(MULTI_GPU_BOARD);
+ GET_ATTR(MULTI_GPU_BOARD_GROUP_ID);
#undef GET_ATTR
- capabilities += "\n";
- }
+ capabilities += "\n";
+ }
- return capabilities;
+ return capabilities;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_denoising.cpp b/intern/cycles/device/device_denoising.cpp
index 1bb144ef85a..05a7fb8ae4d 100644
--- a/intern/cycles/device/device_denoising.cpp
+++ b/intern/cycles/device/device_denoising.cpp
@@ -21,314 +21,329 @@
CCL_NAMESPACE_BEGIN
DenoisingTask::DenoisingTask(Device *device, const DeviceTask &task)
-: tile_info_mem(device, "denoising tile info mem", MEM_READ_WRITE),
- profiler(NULL),
- storage(device),
- buffer(device),
- device(device)
+ : tile_info_mem(device, "denoising tile info mem", MEM_READ_WRITE),
+ profiler(NULL),
+ storage(device),
+ buffer(device),
+ device(device)
{
- radius = task.denoising.radius;
- nlm_k_2 = powf(2.0f, lerp(-5.0f, 3.0f, task.denoising.strength));
- if(task.denoising.relative_pca) {
- pca_threshold = -powf(10.0f, lerp(-8.0f, 0.0f, task.denoising.feature_strength));
- }
- else {
- pca_threshold = powf(10.0f, lerp(-5.0f, 3.0f, task.denoising.feature_strength));
- }
-
- render_buffer.frame_stride = task.frame_stride;
- render_buffer.pass_stride = task.pass_stride;
- render_buffer.offset = task.pass_denoising_data;
-
- target_buffer.pass_stride = task.target_pass_stride;
- target_buffer.denoising_clean_offset = task.pass_denoising_clean;
- target_buffer.offset = 0;
-
- functions.map_neighbor_tiles = function_bind(task.map_neighbor_tiles, _1, device);
- functions.unmap_neighbor_tiles = function_bind(task.unmap_neighbor_tiles, _1, device);
-
- tile_info = (TileInfo*) tile_info_mem.alloc(sizeof(TileInfo)/sizeof(int));
- tile_info->from_render = task.denoising_from_render? 1 : 0;
-
- tile_info->frames[0] = 0;
- tile_info->num_frames = min(task.denoising_frames.size() + 1, DENOISE_MAX_FRAMES);
- for(int i = 1; i < tile_info->num_frames; i++) {
- tile_info->frames[i] = task.denoising_frames[i-1];
- }
-
- write_passes = task.denoising_write_passes;
- do_filter = task.denoising_do_filter;
+ radius = task.denoising.radius;
+ nlm_k_2 = powf(2.0f, lerp(-5.0f, 3.0f, task.denoising.strength));
+ if (task.denoising.relative_pca) {
+ pca_threshold = -powf(10.0f, lerp(-8.0f, 0.0f, task.denoising.feature_strength));
+ }
+ else {
+ pca_threshold = powf(10.0f, lerp(-5.0f, 3.0f, task.denoising.feature_strength));
+ }
+
+ render_buffer.frame_stride = task.frame_stride;
+ render_buffer.pass_stride = task.pass_stride;
+ render_buffer.offset = task.pass_denoising_data;
+
+ target_buffer.pass_stride = task.target_pass_stride;
+ target_buffer.denoising_clean_offset = task.pass_denoising_clean;
+ target_buffer.offset = 0;
+
+ functions.map_neighbor_tiles = function_bind(task.map_neighbor_tiles, _1, device);
+ functions.unmap_neighbor_tiles = function_bind(task.unmap_neighbor_tiles, _1, device);
+
+ tile_info = (TileInfo *)tile_info_mem.alloc(sizeof(TileInfo) / sizeof(int));
+ tile_info->from_render = task.denoising_from_render ? 1 : 0;
+
+ tile_info->frames[0] = 0;
+ tile_info->num_frames = min(task.denoising_frames.size() + 1, DENOISE_MAX_FRAMES);
+ for (int i = 1; i < tile_info->num_frames; i++) {
+ tile_info->frames[i] = task.denoising_frames[i - 1];
+ }
+
+ write_passes = task.denoising_write_passes;
+ do_filter = task.denoising_do_filter;
}
DenoisingTask::~DenoisingTask()
{
- storage.XtWX.free();
- storage.XtWY.free();
- storage.transform.free();
- storage.rank.free();
- buffer.mem.free();
- buffer.temporary_mem.free();
- tile_info_mem.free();
+ storage.XtWX.free();
+ storage.XtWY.free();
+ storage.transform.free();
+ storage.rank.free();
+ buffer.mem.free();
+ buffer.temporary_mem.free();
+ tile_info_mem.free();
}
void DenoisingTask::set_render_buffer(RenderTile *rtiles)
{
- for(int i = 0; i < 9; i++) {
- tile_info->offsets[i] = rtiles[i].offset;
- tile_info->strides[i] = rtiles[i].stride;
- tile_info->buffers[i] = rtiles[i].buffer;
- }
- tile_info->x[0] = rtiles[3].x;
- tile_info->x[1] = rtiles[4].x;
- tile_info->x[2] = rtiles[5].x;
- tile_info->x[3] = rtiles[5].x + rtiles[5].w;
- tile_info->y[0] = rtiles[1].y;
- tile_info->y[1] = rtiles[4].y;
- tile_info->y[2] = rtiles[7].y;
- tile_info->y[3] = rtiles[7].y + rtiles[7].h;
-
- target_buffer.offset = rtiles[9].offset;
- target_buffer.stride = rtiles[9].stride;
- target_buffer.ptr = rtiles[9].buffer;
-
- if(write_passes && rtiles[9].buffers) {
- target_buffer.denoising_output_offset = rtiles[9].buffers->params.get_denoising_prefiltered_offset();
- }
- else {
- target_buffer.denoising_output_offset = 0;
- }
-
- tile_info_mem.copy_to_device();
+ for (int i = 0; i < 9; i++) {
+ tile_info->offsets[i] = rtiles[i].offset;
+ tile_info->strides[i] = rtiles[i].stride;
+ tile_info->buffers[i] = rtiles[i].buffer;
+ }
+ tile_info->x[0] = rtiles[3].x;
+ tile_info->x[1] = rtiles[4].x;
+ tile_info->x[2] = rtiles[5].x;
+ tile_info->x[3] = rtiles[5].x + rtiles[5].w;
+ tile_info->y[0] = rtiles[1].y;
+ tile_info->y[1] = rtiles[4].y;
+ tile_info->y[2] = rtiles[7].y;
+ tile_info->y[3] = rtiles[7].y + rtiles[7].h;
+
+ target_buffer.offset = rtiles[9].offset;
+ target_buffer.stride = rtiles[9].stride;
+ target_buffer.ptr = rtiles[9].buffer;
+
+ if (write_passes && rtiles[9].buffers) {
+ target_buffer.denoising_output_offset =
+ rtiles[9].buffers->params.get_denoising_prefiltered_offset();
+ }
+ else {
+ target_buffer.denoising_output_offset = 0;
+ }
+
+ tile_info_mem.copy_to_device();
}
void DenoisingTask::setup_denoising_buffer()
{
- /* Expand filter_area by radius pixels and clamp the result to the extent of the neighboring tiles */
- rect = rect_from_shape(filter_area.x, filter_area.y, filter_area.z, filter_area.w);
- rect = rect_expand(rect, radius);
- rect = rect_clip(rect, make_int4(tile_info->x[0], tile_info->y[0], tile_info->x[3], tile_info->y[3]));
-
- buffer.use_intensity = write_passes || (tile_info->num_frames > 1);
- buffer.passes = buffer.use_intensity? 15 : 14;
- buffer.width = rect.z - rect.x;
- buffer.stride = align_up(buffer.width, 4);
- buffer.h = rect.w - rect.y;
- int alignment_floats = divide_up(device->mem_sub_ptr_alignment(), sizeof(float));
- buffer.pass_stride = align_up(buffer.stride * buffer.h, alignment_floats);
- buffer.frame_stride = buffer.pass_stride * buffer.passes;
- /* Pad the total size by four floats since the SIMD kernels might go a bit over the end. */
- int mem_size = align_up(tile_info->num_frames * buffer.frame_stride + 4, alignment_floats);
- buffer.mem.alloc_to_device(mem_size, false);
- buffer.use_time = (tile_info->num_frames > 1);
-
- /* CPUs process shifts sequentially while GPUs process them in parallel. */
- int num_layers;
- if(buffer.gpu_temporary_mem) {
- /* Shadowing prefiltering uses a radius of 6, so allocate at least that much. */
- int max_radius = max(radius, 6);
- int num_shifts = (2*max_radius + 1) * (2*max_radius + 1);
- num_layers = 2*num_shifts + 1;
- }
- else {
- num_layers = 3;
- }
- /* Allocate two layers per shift as well as one for the weight accumulation. */
- buffer.temporary_mem.alloc_to_device(num_layers * buffer.pass_stride);
+ /* Expand filter_area by radius pixels and clamp the result to the extent of the neighboring tiles */
+ rect = rect_from_shape(filter_area.x, filter_area.y, filter_area.z, filter_area.w);
+ rect = rect_expand(rect, radius);
+ rect = rect_clip(rect,
+ make_int4(tile_info->x[0], tile_info->y[0], tile_info->x[3], tile_info->y[3]));
+
+ buffer.use_intensity = write_passes || (tile_info->num_frames > 1);
+ buffer.passes = buffer.use_intensity ? 15 : 14;
+ buffer.width = rect.z - rect.x;
+ buffer.stride = align_up(buffer.width, 4);
+ buffer.h = rect.w - rect.y;
+ int alignment_floats = divide_up(device->mem_sub_ptr_alignment(), sizeof(float));
+ buffer.pass_stride = align_up(buffer.stride * buffer.h, alignment_floats);
+ buffer.frame_stride = buffer.pass_stride * buffer.passes;
+ /* Pad the total size by four floats since the SIMD kernels might go a bit over the end. */
+ int mem_size = align_up(tile_info->num_frames * buffer.frame_stride + 4, alignment_floats);
+ buffer.mem.alloc_to_device(mem_size, false);
+ buffer.use_time = (tile_info->num_frames > 1);
+
+ /* CPUs process shifts sequentially while GPUs process them in parallel. */
+ int num_layers;
+ if (buffer.gpu_temporary_mem) {
+ /* Shadowing prefiltering uses a radius of 6, so allocate at least that much. */
+ int max_radius = max(radius, 6);
+ int num_shifts = (2 * max_radius + 1) * (2 * max_radius + 1);
+ num_layers = 2 * num_shifts + 1;
+ }
+ else {
+ num_layers = 3;
+ }
+ /* Allocate two layers per shift as well as one for the weight accumulation. */
+ buffer.temporary_mem.alloc_to_device(num_layers * buffer.pass_stride);
}
void DenoisingTask::prefilter_shadowing()
{
- device_ptr null_ptr = (device_ptr) 0;
-
- device_sub_ptr unfiltered_a (buffer.mem, 0, buffer.pass_stride);
- device_sub_ptr unfiltered_b (buffer.mem, 1*buffer.pass_stride, buffer.pass_stride);
- device_sub_ptr sample_var (buffer.mem, 2*buffer.pass_stride, buffer.pass_stride);
- device_sub_ptr sample_var_var (buffer.mem, 3*buffer.pass_stride, buffer.pass_stride);
- device_sub_ptr buffer_var (buffer.mem, 5*buffer.pass_stride, buffer.pass_stride);
- device_sub_ptr filtered_var (buffer.mem, 6*buffer.pass_stride, buffer.pass_stride);
-
- /* Get the A/B unfiltered passes, the combined sample variance, the estimated variance of the sample variance and the buffer variance. */
- functions.divide_shadow(*unfiltered_a, *unfiltered_b, *sample_var, *sample_var_var, *buffer_var);
-
- /* Smooth the (generally pretty noisy) buffer variance using the spatial information from the sample variance. */
- nlm_state.set_parameters(6, 3, 4.0f, 1.0f, false);
- functions.non_local_means(*buffer_var, *sample_var, *sample_var_var, *filtered_var);
-
- /* Reuse memory, the previous data isn't needed anymore. */
- device_ptr filtered_a = *buffer_var,
- filtered_b = *sample_var;
- /* Use the smoothed variance to filter the two shadow half images using each other for weight calculation. */
- nlm_state.set_parameters(5, 3, 1.0f, 0.25f, false);
- functions.non_local_means(*unfiltered_a, *unfiltered_b, *filtered_var, filtered_a);
- functions.non_local_means(*unfiltered_b, *unfiltered_a, *filtered_var, filtered_b);
-
- device_ptr residual_var = *sample_var_var;
- /* Estimate the residual variance between the two filtered halves. */
- functions.combine_halves(filtered_a, filtered_b, null_ptr, residual_var, 2, rect);
-
- device_ptr final_a = *unfiltered_a,
- final_b = *unfiltered_b;
- /* Use the residual variance for a second filter pass. */
- nlm_state.set_parameters(4, 2, 1.0f, 0.5f, false);
- functions.non_local_means(filtered_a, filtered_b, residual_var, final_a);
- functions.non_local_means(filtered_b, filtered_a, residual_var, final_b);
-
- /* Combine the two double-filtered halves to a final shadow feature. */
- device_sub_ptr shadow_pass(buffer.mem, 4*buffer.pass_stride, buffer.pass_stride);
- functions.combine_halves(final_a, final_b, *shadow_pass, null_ptr, 0, rect);
+ device_ptr null_ptr = (device_ptr)0;
+
+ device_sub_ptr unfiltered_a(buffer.mem, 0, buffer.pass_stride);
+ device_sub_ptr unfiltered_b(buffer.mem, 1 * buffer.pass_stride, buffer.pass_stride);
+ device_sub_ptr sample_var(buffer.mem, 2 * buffer.pass_stride, buffer.pass_stride);
+ device_sub_ptr sample_var_var(buffer.mem, 3 * buffer.pass_stride, buffer.pass_stride);
+ device_sub_ptr buffer_var(buffer.mem, 5 * buffer.pass_stride, buffer.pass_stride);
+ device_sub_ptr filtered_var(buffer.mem, 6 * buffer.pass_stride, buffer.pass_stride);
+
+ /* Get the A/B unfiltered passes, the combined sample variance, the estimated variance of the sample variance and the buffer variance. */
+ functions.divide_shadow(*unfiltered_a, *unfiltered_b, *sample_var, *sample_var_var, *buffer_var);
+
+ /* Smooth the (generally pretty noisy) buffer variance using the spatial information from the sample variance. */
+ nlm_state.set_parameters(6, 3, 4.0f, 1.0f, false);
+ functions.non_local_means(*buffer_var, *sample_var, *sample_var_var, *filtered_var);
+
+ /* Reuse memory, the previous data isn't needed anymore. */
+ device_ptr filtered_a = *buffer_var, filtered_b = *sample_var;
+ /* Use the smoothed variance to filter the two shadow half images using each other for weight calculation. */
+ nlm_state.set_parameters(5, 3, 1.0f, 0.25f, false);
+ functions.non_local_means(*unfiltered_a, *unfiltered_b, *filtered_var, filtered_a);
+ functions.non_local_means(*unfiltered_b, *unfiltered_a, *filtered_var, filtered_b);
+
+ device_ptr residual_var = *sample_var_var;
+ /* Estimate the residual variance between the two filtered halves. */
+ functions.combine_halves(filtered_a, filtered_b, null_ptr, residual_var, 2, rect);
+
+ device_ptr final_a = *unfiltered_a, final_b = *unfiltered_b;
+ /* Use the residual variance for a second filter pass. */
+ nlm_state.set_parameters(4, 2, 1.0f, 0.5f, false);
+ functions.non_local_means(filtered_a, filtered_b, residual_var, final_a);
+ functions.non_local_means(filtered_b, filtered_a, residual_var, final_b);
+
+ /* Combine the two double-filtered halves to a final shadow feature. */
+ device_sub_ptr shadow_pass(buffer.mem, 4 * buffer.pass_stride, buffer.pass_stride);
+ functions.combine_halves(final_a, final_b, *shadow_pass, null_ptr, 0, rect);
}
void DenoisingTask::prefilter_features()
{
- device_sub_ptr unfiltered (buffer.mem, 8*buffer.pass_stride, buffer.pass_stride);
- device_sub_ptr variance (buffer.mem, 9*buffer.pass_stride, buffer.pass_stride);
-
- int mean_from[] = { 0, 1, 2, 12, 6, 7, 8 };
- int variance_from[] = { 3, 4, 5, 13, 9, 10, 11};
- int pass_to[] = { 1, 2, 3, 0, 5, 6, 7};
- for(int pass = 0; pass < 7; pass++) {
- device_sub_ptr feature_pass(buffer.mem, pass_to[pass]*buffer.pass_stride, buffer.pass_stride);
- /* Get the unfiltered pass and its variance from the RenderBuffers. */
- functions.get_feature(mean_from[pass], variance_from[pass], *unfiltered, *variance, 1.0f / render_buffer.samples);
- /* Smooth the pass and store the result in the denoising buffers. */
- nlm_state.set_parameters(2, 2, 1.0f, 0.25f, false);
- functions.non_local_means(*unfiltered, *unfiltered, *variance, *feature_pass);
- }
+ device_sub_ptr unfiltered(buffer.mem, 8 * buffer.pass_stride, buffer.pass_stride);
+ device_sub_ptr variance(buffer.mem, 9 * buffer.pass_stride, buffer.pass_stride);
+
+ int mean_from[] = {0, 1, 2, 12, 6, 7, 8};
+ int variance_from[] = {3, 4, 5, 13, 9, 10, 11};
+ int pass_to[] = {1, 2, 3, 0, 5, 6, 7};
+ for (int pass = 0; pass < 7; pass++) {
+ device_sub_ptr feature_pass(
+ buffer.mem, pass_to[pass] * buffer.pass_stride, buffer.pass_stride);
+ /* Get the unfiltered pass and its variance from the RenderBuffers. */
+ functions.get_feature(mean_from[pass],
+ variance_from[pass],
+ *unfiltered,
+ *variance,
+ 1.0f / render_buffer.samples);
+ /* Smooth the pass and store the result in the denoising buffers. */
+ nlm_state.set_parameters(2, 2, 1.0f, 0.25f, false);
+ functions.non_local_means(*unfiltered, *unfiltered, *variance, *feature_pass);
+ }
}
void DenoisingTask::prefilter_color()
{
- int mean_from[] = {20, 21, 22};
- int variance_from[] = {23, 24, 25};
- int mean_to[] = { 8, 9, 10};
- int variance_to[] = {11, 12, 13};
- int num_color_passes = 3;
-
- device_only_memory<float> temporary_color(device, "denoising temporary color");
- temporary_color.alloc_to_device(3*buffer.pass_stride, false);
-
- for(int pass = 0; pass < num_color_passes; pass++) {
- device_sub_ptr color_pass(temporary_color, pass*buffer.pass_stride, buffer.pass_stride);
- device_sub_ptr color_var_pass(buffer.mem, variance_to[pass]*buffer.pass_stride, buffer.pass_stride);
- functions.get_feature(mean_from[pass], variance_from[pass], *color_pass, *color_var_pass, 1.0f / render_buffer.samples);
- }
-
- device_sub_ptr depth_pass (buffer.mem, 0, buffer.pass_stride);
- device_sub_ptr color_var_pass(buffer.mem, variance_to[0]*buffer.pass_stride, 3*buffer.pass_stride);
- device_sub_ptr output_pass (buffer.mem, mean_to[0]*buffer.pass_stride, 3*buffer.pass_stride);
- functions.detect_outliers(temporary_color.device_pointer, *color_var_pass, *depth_pass, *output_pass);
-
- if(buffer.use_intensity) {
- device_sub_ptr intensity_pass(buffer.mem, 14*buffer.pass_stride, buffer.pass_stride);
- nlm_state.set_parameters(radius, 4, 2.0f, nlm_k_2*4.0f, true);
- functions.non_local_means(*output_pass, *output_pass, *color_var_pass, *intensity_pass);
- }
+ int mean_from[] = {20, 21, 22};
+ int variance_from[] = {23, 24, 25};
+ int mean_to[] = {8, 9, 10};
+ int variance_to[] = {11, 12, 13};
+ int num_color_passes = 3;
+
+ device_only_memory<float> temporary_color(device, "denoising temporary color");
+ temporary_color.alloc_to_device(3 * buffer.pass_stride, false);
+
+ for (int pass = 0; pass < num_color_passes; pass++) {
+ device_sub_ptr color_pass(temporary_color, pass * buffer.pass_stride, buffer.pass_stride);
+ device_sub_ptr color_var_pass(
+ buffer.mem, variance_to[pass] * buffer.pass_stride, buffer.pass_stride);
+ functions.get_feature(mean_from[pass],
+ variance_from[pass],
+ *color_pass,
+ *color_var_pass,
+ 1.0f / render_buffer.samples);
+ }
+
+ device_sub_ptr depth_pass(buffer.mem, 0, buffer.pass_stride);
+ device_sub_ptr color_var_pass(
+ buffer.mem, variance_to[0] * buffer.pass_stride, 3 * buffer.pass_stride);
+ device_sub_ptr output_pass(buffer.mem, mean_to[0] * buffer.pass_stride, 3 * buffer.pass_stride);
+ functions.detect_outliers(
+ temporary_color.device_pointer, *color_var_pass, *depth_pass, *output_pass);
+
+ if (buffer.use_intensity) {
+ device_sub_ptr intensity_pass(buffer.mem, 14 * buffer.pass_stride, buffer.pass_stride);
+ nlm_state.set_parameters(radius, 4, 2.0f, nlm_k_2 * 4.0f, true);
+ functions.non_local_means(*output_pass, *output_pass, *color_var_pass, *intensity_pass);
+ }
}
void DenoisingTask::load_buffer()
{
- device_ptr null_ptr = (device_ptr) 0;
-
- int original_offset = render_buffer.offset;
-
- int num_passes = buffer.use_intensity? 15 : 14;
- for(int i = 0; i < tile_info->num_frames; i++) {
- for(int pass = 0; pass < num_passes; pass++) {
- device_sub_ptr to_pass(buffer.mem, i*buffer.frame_stride + pass*buffer.pass_stride, buffer.pass_stride);
- bool is_variance = (pass >= 11) && (pass <= 13);
- functions.get_feature(pass, -1, *to_pass, null_ptr, is_variance? (1.0f / render_buffer.samples) : 1.0f);
- }
- render_buffer.offset += render_buffer.frame_stride;
- }
-
- render_buffer.offset = original_offset;
+ device_ptr null_ptr = (device_ptr)0;
+
+ int original_offset = render_buffer.offset;
+
+ int num_passes = buffer.use_intensity ? 15 : 14;
+ for (int i = 0; i < tile_info->num_frames; i++) {
+ for (int pass = 0; pass < num_passes; pass++) {
+ device_sub_ptr to_pass(
+ buffer.mem, i * buffer.frame_stride + pass * buffer.pass_stride, buffer.pass_stride);
+ bool is_variance = (pass >= 11) && (pass <= 13);
+ functions.get_feature(
+ pass, -1, *to_pass, null_ptr, is_variance ? (1.0f / render_buffer.samples) : 1.0f);
+ }
+ render_buffer.offset += render_buffer.frame_stride;
+ }
+
+ render_buffer.offset = original_offset;
}
void DenoisingTask::write_buffer()
{
- reconstruction_state.buffer_params = make_int4(target_buffer.offset,
- target_buffer.stride,
- target_buffer.pass_stride,
- target_buffer.denoising_clean_offset);
- int num_passes = buffer.use_intensity? 15 : 14;
- for(int pass = 0; pass < num_passes; pass++) {
- device_sub_ptr from_pass(buffer.mem, pass*buffer.pass_stride, buffer.pass_stride);
- int out_offset = pass + target_buffer.denoising_output_offset;
- functions.write_feature(out_offset, *from_pass, target_buffer.ptr);
- }
+ reconstruction_state.buffer_params = make_int4(target_buffer.offset,
+ target_buffer.stride,
+ target_buffer.pass_stride,
+ target_buffer.denoising_clean_offset);
+ int num_passes = buffer.use_intensity ? 15 : 14;
+ for (int pass = 0; pass < num_passes; pass++) {
+ device_sub_ptr from_pass(buffer.mem, pass * buffer.pass_stride, buffer.pass_stride);
+ int out_offset = pass + target_buffer.denoising_output_offset;
+ functions.write_feature(out_offset, *from_pass, target_buffer.ptr);
+ }
}
void DenoisingTask::construct_transform()
{
- storage.w = filter_area.z;
- storage.h = filter_area.w;
+ storage.w = filter_area.z;
+ storage.h = filter_area.w;
- storage.transform.alloc_to_device(storage.w*storage.h*TRANSFORM_SIZE, false);
- storage.rank.alloc_to_device(storage.w*storage.h, false);
+ storage.transform.alloc_to_device(storage.w * storage.h * TRANSFORM_SIZE, false);
+ storage.rank.alloc_to_device(storage.w * storage.h, false);
- functions.construct_transform();
+ functions.construct_transform();
}
void DenoisingTask::reconstruct()
{
- storage.XtWX.alloc_to_device(storage.w*storage.h*XTWX_SIZE, false);
- storage.XtWY.alloc_to_device(storage.w*storage.h*XTWY_SIZE, false);
- storage.XtWX.zero_to_device();
- storage.XtWY.zero_to_device();
-
- reconstruction_state.filter_window = rect_from_shape(filter_area.x-rect.x, filter_area.y-rect.y, storage.w, storage.h);
- int tile_coordinate_offset = filter_area.y*target_buffer.stride + filter_area.x;
- reconstruction_state.buffer_params = make_int4(target_buffer.offset + tile_coordinate_offset,
- target_buffer.stride,
- target_buffer.pass_stride,
- target_buffer.denoising_clean_offset);
- reconstruction_state.source_w = rect.z-rect.x;
- reconstruction_state.source_h = rect.w-rect.y;
-
- device_sub_ptr color_ptr (buffer.mem, 8*buffer.pass_stride, 3*buffer.pass_stride);
- device_sub_ptr color_var_ptr(buffer.mem, 11*buffer.pass_stride, 3*buffer.pass_stride);
- for(int f = 0; f < tile_info->num_frames; f++) {
- device_ptr scale_ptr = 0;
- device_sub_ptr *scale_sub_ptr = NULL;
- if(tile_info->frames[f] != 0 && (tile_info->num_frames > 1)) {
- scale_sub_ptr = new device_sub_ptr(buffer.mem, 14*buffer.pass_stride, buffer.pass_stride);
- scale_ptr = **scale_sub_ptr;
- }
-
- functions.accumulate(*color_ptr, *color_var_ptr, scale_ptr, f);
- delete scale_sub_ptr;
- }
- functions.solve(target_buffer.ptr);
+ storage.XtWX.alloc_to_device(storage.w * storage.h * XTWX_SIZE, false);
+ storage.XtWY.alloc_to_device(storage.w * storage.h * XTWY_SIZE, false);
+ storage.XtWX.zero_to_device();
+ storage.XtWY.zero_to_device();
+
+ reconstruction_state.filter_window = rect_from_shape(
+ filter_area.x - rect.x, filter_area.y - rect.y, storage.w, storage.h);
+ int tile_coordinate_offset = filter_area.y * target_buffer.stride + filter_area.x;
+ reconstruction_state.buffer_params = make_int4(target_buffer.offset + tile_coordinate_offset,
+ target_buffer.stride,
+ target_buffer.pass_stride,
+ target_buffer.denoising_clean_offset);
+ reconstruction_state.source_w = rect.z - rect.x;
+ reconstruction_state.source_h = rect.w - rect.y;
+
+ device_sub_ptr color_ptr(buffer.mem, 8 * buffer.pass_stride, 3 * buffer.pass_stride);
+ device_sub_ptr color_var_ptr(buffer.mem, 11 * buffer.pass_stride, 3 * buffer.pass_stride);
+ for (int f = 0; f < tile_info->num_frames; f++) {
+ device_ptr scale_ptr = 0;
+ device_sub_ptr *scale_sub_ptr = NULL;
+ if (tile_info->frames[f] != 0 && (tile_info->num_frames > 1)) {
+ scale_sub_ptr = new device_sub_ptr(buffer.mem, 14 * buffer.pass_stride, buffer.pass_stride);
+ scale_ptr = **scale_sub_ptr;
+ }
+
+ functions.accumulate(*color_ptr, *color_var_ptr, scale_ptr, f);
+ delete scale_sub_ptr;
+ }
+ functions.solve(target_buffer.ptr);
}
void DenoisingTask::run_denoising(RenderTile *tile)
{
- RenderTile rtiles[10];
- rtiles[4] = *tile;
- functions.map_neighbor_tiles(rtiles);
- set_render_buffer(rtiles);
-
- setup_denoising_buffer();
-
- if(tile_info->from_render) {
- prefilter_shadowing();
- prefilter_features();
- prefilter_color();
- }
- else {
- load_buffer();
- }
-
- if(do_filter) {
- construct_transform();
- reconstruct();
- }
-
- if(write_passes) {
- write_buffer();
- }
-
- functions.unmap_neighbor_tiles(rtiles);
+ RenderTile rtiles[10];
+ rtiles[4] = *tile;
+ functions.map_neighbor_tiles(rtiles);
+ set_render_buffer(rtiles);
+
+ setup_denoising_buffer();
+
+ if (tile_info->from_render) {
+ prefilter_shadowing();
+ prefilter_features();
+ prefilter_color();
+ }
+ else {
+ load_buffer();
+ }
+
+ if (do_filter) {
+ construct_transform();
+ reconstruct();
+ }
+
+ if (write_passes) {
+ write_buffer();
+ }
+
+ functions.unmap_neighbor_tiles(rtiles);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_denoising.h b/intern/cycles/device/device_denoising.h
index 5869aa05390..bd1d0193dbd 100644
--- a/intern/cycles/device/device_denoising.h
+++ b/intern/cycles/device/device_denoising.h
@@ -28,165 +28,169 @@
CCL_NAMESPACE_BEGIN
class DenoisingTask {
-public:
- /* Parameters of the denoising algorithm. */
- int radius;
- float nlm_k_2;
- float pca_threshold;
-
- /* Parameters of the RenderBuffers. */
- struct RenderBuffers {
- int offset;
- int pass_stride;
- int frame_stride;
- int samples;
- } render_buffer;
-
- /* Pointer and parameters of the target buffer. */
- struct TargetBuffer {
- int offset;
- int stride;
- int pass_stride;
- int denoising_clean_offset;
- int denoising_output_offset;
- device_ptr ptr;
- } target_buffer;
-
- TileInfo *tile_info;
- device_vector<int> tile_info_mem;
-
- ProfilingState *profiler;
-
- int4 rect;
- int4 filter_area;
-
- bool write_passes;
- bool do_filter;
-
- struct DeviceFunctions {
- function<bool(device_ptr image_ptr, /* Contains the values that are smoothed. */
- device_ptr guide_ptr, /* Contains the values that are used to calculate weights. */
- device_ptr variance_ptr, /* Contains the variance of the guide image. */
- device_ptr out_ptr /* The filtered output is written into this image. */
- )> non_local_means;
- function<bool(device_ptr color_ptr,
- device_ptr color_variance_ptr,
- device_ptr scale_ptr,
- int frame
- )> accumulate;
- function<bool(device_ptr output_ptr)> solve;
- function<bool()> construct_transform;
-
- function<bool(device_ptr a_ptr,
- device_ptr b_ptr,
- device_ptr mean_ptr,
- device_ptr variance_ptr,
- int r,
- int4 rect
- )> combine_halves;
- function<bool(device_ptr a_ptr,
- device_ptr b_ptr,
- device_ptr sample_variance_ptr,
- device_ptr sv_variance_ptr,
- device_ptr buffer_variance_ptr
- )> divide_shadow;
- function<bool(int mean_offset,
- int variance_offset,
- device_ptr mean_ptr,
- device_ptr variance_ptr,
- float scale
- )> get_feature;
- function<bool(device_ptr image_ptr,
- device_ptr variance_ptr,
- device_ptr depth_ptr,
- device_ptr output_ptr
- )> detect_outliers;
- function<bool(int out_offset,
- device_ptr frop_ptr,
- device_ptr buffer_ptr
- )> write_feature;
- function<void(RenderTile *rtiles)> map_neighbor_tiles;
- function<void(RenderTile *rtiles)> unmap_neighbor_tiles;
- } functions;
-
- /* Stores state of the current Reconstruction operation,
- * which is accessed by the device in order to perform the operation. */
- struct ReconstructionState {
- int4 filter_window;
- int4 buffer_params;
-
- int source_w;
- int source_h;
- } reconstruction_state;
-
- /* Stores state of the current NLM operation,
- * which is accessed by the device in order to perform the operation. */
- struct NLMState {
- int r; /* Search radius of the filter. */
- int f; /* Patch size of the filter. */
- float a; /* Variance compensation factor in the MSE estimation. */
- float k_2; /* Squared value of the k parameter of the filter. */
- bool is_color;
-
- void set_parameters(int r_, int f_, float a_, float k_2_, bool is_color_) { r = r_; f = f_; a = a_, k_2 = k_2_; is_color = is_color_; }
- } nlm_state;
-
- struct Storage {
- device_only_memory<float> transform;
- device_only_memory<int> rank;
- device_only_memory<float> XtWX;
- device_only_memory<float3> XtWY;
- int w;
- int h;
-
- Storage(Device *device)
- : transform(device, "denoising transform"),
- rank(device, "denoising rank"),
- XtWX(device, "denoising XtWX"),
- XtWY(device, "denoising XtWY")
- {}
- } storage;
-
- DenoisingTask(Device *device, const DeviceTask &task);
- ~DenoisingTask();
-
- void run_denoising(RenderTile *tile);
-
- struct DenoiseBuffers {
- int pass_stride;
- int passes;
- int stride;
- int h;
- int width;
- int frame_stride;
- device_only_memory<float> mem;
- device_only_memory<float> temporary_mem;
- bool use_time;
- bool use_intensity;
-
- bool gpu_temporary_mem;
-
- DenoiseBuffers(Device *device)
- : mem(device, "denoising pixel buffer"),
- temporary_mem(device, "denoising temporary mem")
- {}
- } buffer;
-
-protected:
- Device *device;
-
- void set_render_buffer(RenderTile *rtiles);
- void setup_denoising_buffer();
- void prefilter_shadowing();
- void prefilter_features();
- void prefilter_color();
- void construct_transform();
- void reconstruct();
-
- void load_buffer();
- void write_buffer();
+ public:
+ /* Parameters of the denoising algorithm. */
+ int radius;
+ float nlm_k_2;
+ float pca_threshold;
+
+ /* Parameters of the RenderBuffers. */
+ struct RenderBuffers {
+ int offset;
+ int pass_stride;
+ int frame_stride;
+ int samples;
+ } render_buffer;
+
+ /* Pointer and parameters of the target buffer. */
+ struct TargetBuffer {
+ int offset;
+ int stride;
+ int pass_stride;
+ int denoising_clean_offset;
+ int denoising_output_offset;
+ device_ptr ptr;
+ } target_buffer;
+
+ TileInfo *tile_info;
+ device_vector<int> tile_info_mem;
+
+ ProfilingState *profiler;
+
+ int4 rect;
+ int4 filter_area;
+
+ bool write_passes;
+ bool do_filter;
+
+ struct DeviceFunctions {
+ function<bool(
+ device_ptr image_ptr, /* Contains the values that are smoothed. */
+ device_ptr guide_ptr, /* Contains the values that are used to calculate weights. */
+ device_ptr variance_ptr, /* Contains the variance of the guide image. */
+ device_ptr out_ptr /* The filtered output is written into this image. */
+ )>
+ non_local_means;
+ function<bool(
+ device_ptr color_ptr, device_ptr color_variance_ptr, device_ptr scale_ptr, int frame)>
+ accumulate;
+ function<bool(device_ptr output_ptr)> solve;
+ function<bool()> construct_transform;
+
+ function<bool(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ int r,
+ int4 rect)>
+ combine_halves;
+ function<bool(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr sample_variance_ptr,
+ device_ptr sv_variance_ptr,
+ device_ptr buffer_variance_ptr)>
+ divide_shadow;
+ function<bool(int mean_offset,
+ int variance_offset,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ float scale)>
+ get_feature;
+ function<bool(device_ptr image_ptr,
+ device_ptr variance_ptr,
+ device_ptr depth_ptr,
+ device_ptr output_ptr)>
+ detect_outliers;
+ function<bool(int out_offset, device_ptr frop_ptr, device_ptr buffer_ptr)> write_feature;
+ function<void(RenderTile *rtiles)> map_neighbor_tiles;
+ function<void(RenderTile *rtiles)> unmap_neighbor_tiles;
+ } functions;
+
+ /* Stores state of the current Reconstruction operation,
+ * which is accessed by the device in order to perform the operation. */
+ struct ReconstructionState {
+ int4 filter_window;
+ int4 buffer_params;
+
+ int source_w;
+ int source_h;
+ } reconstruction_state;
+
+ /* Stores state of the current NLM operation,
+ * which is accessed by the device in order to perform the operation. */
+ struct NLMState {
+ int r; /* Search radius of the filter. */
+ int f; /* Patch size of the filter. */
+ float a; /* Variance compensation factor in the MSE estimation. */
+ float k_2; /* Squared value of the k parameter of the filter. */
+ bool is_color;
+
+ void set_parameters(int r_, int f_, float a_, float k_2_, bool is_color_)
+ {
+ r = r_;
+ f = f_;
+ a = a_, k_2 = k_2_;
+ is_color = is_color_;
+ }
+ } nlm_state;
+
+ struct Storage {
+ device_only_memory<float> transform;
+ device_only_memory<int> rank;
+ device_only_memory<float> XtWX;
+ device_only_memory<float3> XtWY;
+ int w;
+ int h;
+
+ Storage(Device *device)
+ : transform(device, "denoising transform"),
+ rank(device, "denoising rank"),
+ XtWX(device, "denoising XtWX"),
+ XtWY(device, "denoising XtWY")
+ {
+ }
+ } storage;
+
+ DenoisingTask(Device *device, const DeviceTask &task);
+ ~DenoisingTask();
+
+ void run_denoising(RenderTile *tile);
+
+ struct DenoiseBuffers {
+ int pass_stride;
+ int passes;
+ int stride;
+ int h;
+ int width;
+ int frame_stride;
+ device_only_memory<float> mem;
+ device_only_memory<float> temporary_mem;
+ bool use_time;
+ bool use_intensity;
+
+ bool gpu_temporary_mem;
+
+ DenoiseBuffers(Device *device)
+ : mem(device, "denoising pixel buffer"), temporary_mem(device, "denoising temporary mem")
+ {
+ }
+ } buffer;
+
+ protected:
+ Device *device;
+
+ void set_render_buffer(RenderTile *rtiles);
+ void setup_denoising_buffer();
+ void prefilter_shadowing();
+ void prefilter_features();
+ void prefilter_color();
+ void construct_transform();
+ void reconstruct();
+
+ void load_buffer();
+ void write_buffer();
};
CCL_NAMESPACE_END
-#endif /* __DEVICE_DENOISING_H__ */
+#endif /* __DEVICE_DENOISING_H__ */
diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h
index 94df1e009eb..c393a3f9cda 100644
--- a/intern/cycles/device/device_intern.h
+++ b/intern/cycles/device/device_intern.h
@@ -21,19 +21,22 @@ CCL_NAMESPACE_BEGIN
class Device;
-Device *device_cpu_create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background);
+Device *device_cpu_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
bool device_opencl_init();
-Device *device_opencl_create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background);
-bool device_opencl_compile_kernel(const vector<string>& parameters);
+Device *device_opencl_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
+bool device_opencl_compile_kernel(const vector<string> &parameters);
bool device_cuda_init();
-Device *device_cuda_create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background);
-Device *device_network_create(DeviceInfo& info, Stats &stats, Profiler &profiler, const char *address);
-Device *device_multi_create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background);
-
-void device_cpu_info(vector<DeviceInfo>& devices);
-void device_opencl_info(vector<DeviceInfo>& devices);
-void device_cuda_info(vector<DeviceInfo>& devices);
-void device_network_info(vector<DeviceInfo>& devices);
+Device *device_cuda_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
+Device *device_network_create(DeviceInfo &info,
+ Stats &stats,
+ Profiler &profiler,
+ const char *address);
+Device *device_multi_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
+
+void device_cpu_info(vector<DeviceInfo> &devices);
+void device_opencl_info(vector<DeviceInfo> &devices);
+void device_cuda_info(vector<DeviceInfo> &devices);
+void device_network_info(vector<DeviceInfo> &devices);
string device_cpu_capabilities();
string device_opencl_capabilities();
@@ -41,4 +44,4 @@ string device_cuda_capabilities();
CCL_NAMESPACE_END
-#endif /* __DEVICE_INTERN_H__ */
+#endif /* __DEVICE_INTERN_H__ */
diff --git a/intern/cycles/device/device_memory.cpp b/intern/cycles/device/device_memory.cpp
index a8d29896553..859535307f4 100644
--- a/intern/cycles/device/device_memory.cpp
+++ b/intern/cycles/device/device_memory.cpp
@@ -22,21 +22,21 @@ CCL_NAMESPACE_BEGIN
/* Device Memory */
device_memory::device_memory(Device *device, const char *name, MemoryType type)
-: data_type(device_type_traits<uchar>::data_type),
- data_elements(device_type_traits<uchar>::num_elements),
- data_size(0),
- device_size(0),
- data_width(0),
- data_height(0),
- data_depth(0),
- type(type),
- name(name),
- interpolation(INTERPOLATION_NONE),
- extension(EXTENSION_REPEAT),
- device(device),
- device_pointer(0),
- host_pointer(0),
- shared_pointer(0)
+ : data_type(device_type_traits<uchar>::data_type),
+ data_elements(device_type_traits<uchar>::num_elements),
+ data_size(0),
+ device_size(0),
+ data_width(0),
+ data_height(0),
+ data_depth(0),
+ type(type),
+ name(name),
+ interpolation(INTERPOLATION_NONE),
+ extension(EXTENSION_REPEAT),
+ device(device),
+ device_pointer(0),
+ host_pointer(0),
+ shared_pointer(0)
{
}
@@ -46,95 +46,94 @@ device_memory::~device_memory()
void *device_memory::host_alloc(size_t size)
{
- if(!size) {
- return 0;
- }
+ if (!size) {
+ return 0;
+ }
- void *ptr = util_aligned_malloc(size, MIN_ALIGNMENT_CPU_DATA_TYPES);
+ void *ptr = util_aligned_malloc(size, MIN_ALIGNMENT_CPU_DATA_TYPES);
- if(ptr) {
- util_guarded_mem_alloc(size);
- }
- else {
- throw std::bad_alloc();
- }
+ if (ptr) {
+ util_guarded_mem_alloc(size);
+ }
+ else {
+ throw std::bad_alloc();
+ }
- return ptr;
+ return ptr;
}
void device_memory::host_free()
{
- if(host_pointer) {
- util_guarded_mem_free(memory_size());
- util_aligned_free((void*)host_pointer);
- host_pointer = 0;
- }
+ if (host_pointer) {
+ util_guarded_mem_free(memory_size());
+ util_aligned_free((void *)host_pointer);
+ host_pointer = 0;
+ }
}
void device_memory::device_alloc()
{
- assert(!device_pointer && type != MEM_TEXTURE);
- device->mem_alloc(*this);
+ assert(!device_pointer && type != MEM_TEXTURE);
+ device->mem_alloc(*this);
}
void device_memory::device_free()
{
- if(device_pointer) {
- device->mem_free(*this);
- }
+ if (device_pointer) {
+ device->mem_free(*this);
+ }
}
void device_memory::device_copy_to()
{
- if(host_pointer) {
- device->mem_copy_to(*this);
- }
+ if (host_pointer) {
+ device->mem_copy_to(*this);
+ }
}
void device_memory::device_copy_from(int y, int w, int h, int elem)
{
- assert(type != MEM_TEXTURE && type != MEM_READ_ONLY);
- device->mem_copy_from(*this, y, w, h, elem);
+ assert(type != MEM_TEXTURE && type != MEM_READ_ONLY);
+ device->mem_copy_from(*this, y, w, h, elem);
}
void device_memory::device_zero()
{
- if(data_size) {
- device->mem_zero(*this);
- }
+ if (data_size) {
+ device->mem_zero(*this);
+ }
}
void device_memory::swap_device(Device *new_device,
size_t new_device_size,
device_ptr new_device_ptr)
{
- original_device = device;
- original_device_size = device_size;
- original_device_ptr = device_pointer;
+ original_device = device;
+ original_device_size = device_size;
+ original_device_ptr = device_pointer;
- device = new_device;
- device_size = new_device_size;
- device_pointer = new_device_ptr;
+ device = new_device;
+ device_size = new_device_size;
+ device_pointer = new_device_ptr;
}
void device_memory::restore_device()
{
- device = original_device;
- device_size = original_device_size;
- device_pointer = original_device_ptr;
+ device = original_device;
+ device_size = original_device_size;
+ device_pointer = original_device_ptr;
}
/* Device Sub Ptr */
-device_sub_ptr::device_sub_ptr(device_memory& mem, int offset, int size)
-: device(mem.device)
+device_sub_ptr::device_sub_ptr(device_memory &mem, int offset, int size) : device(mem.device)
{
- ptr = device->mem_alloc_sub_ptr(mem, offset, size);
+ ptr = device->mem_alloc_sub_ptr(mem, offset, size);
}
device_sub_ptr::~device_sub_ptr()
{
- device->mem_free_sub_ptr(ptr);
+ device->mem_free_sub_ptr(ptr);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index e43834bdc8d..f50184efba7 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -31,152 +31,155 @@ CCL_NAMESPACE_BEGIN
class Device;
-enum MemoryType {
- MEM_READ_ONLY,
- MEM_READ_WRITE,
- MEM_DEVICE_ONLY,
- MEM_TEXTURE,
- MEM_PIXELS
-};
+enum MemoryType { MEM_READ_ONLY, MEM_READ_WRITE, MEM_DEVICE_ONLY, MEM_TEXTURE, MEM_PIXELS };
/* Supported Data Types */
enum DataType {
- TYPE_UNKNOWN,
- TYPE_UCHAR,
- TYPE_UINT16,
- TYPE_UINT,
- TYPE_INT,
- TYPE_FLOAT,
- TYPE_HALF,
- TYPE_UINT64,
+ TYPE_UNKNOWN,
+ TYPE_UCHAR,
+ TYPE_UINT16,
+ TYPE_UINT,
+ TYPE_INT,
+ TYPE_FLOAT,
+ TYPE_HALF,
+ TYPE_UINT64,
};
static inline size_t datatype_size(DataType datatype)
{
- switch(datatype) {
- case TYPE_UNKNOWN: return 1;
- case TYPE_UCHAR: return sizeof(uchar);
- case TYPE_FLOAT: return sizeof(float);
- case TYPE_UINT: return sizeof(uint);
- case TYPE_UINT16: return sizeof(uint16_t);
- case TYPE_INT: return sizeof(int);
- case TYPE_HALF: return sizeof(half);
- case TYPE_UINT64: return sizeof(uint64_t);
- default: return 0;
- }
+ switch (datatype) {
+ case TYPE_UNKNOWN:
+ return 1;
+ case TYPE_UCHAR:
+ return sizeof(uchar);
+ case TYPE_FLOAT:
+ return sizeof(float);
+ case TYPE_UINT:
+ return sizeof(uint);
+ case TYPE_UINT16:
+ return sizeof(uint16_t);
+ case TYPE_INT:
+ return sizeof(int);
+ case TYPE_HALF:
+ return sizeof(half);
+ case TYPE_UINT64:
+ return sizeof(uint64_t);
+ default:
+ return 0;
+ }
}
/* Traits for data types */
template<typename T> struct device_type_traits {
- static const DataType data_type = TYPE_UNKNOWN;
- static const int num_elements = sizeof(T);
+ static const DataType data_type = TYPE_UNKNOWN;
+ static const int num_elements = sizeof(T);
};
template<> struct device_type_traits<uchar> {
- static const DataType data_type = TYPE_UCHAR;
- static const int num_elements = 1;
+ static const DataType data_type = TYPE_UCHAR;
+ static const int num_elements = 1;
};
template<> struct device_type_traits<uchar2> {
- static const DataType data_type = TYPE_UCHAR;
- static const int num_elements = 2;
+ static const DataType data_type = TYPE_UCHAR;
+ static const int num_elements = 2;
};
template<> struct device_type_traits<uchar3> {
- static const DataType data_type = TYPE_UCHAR;
- static const int num_elements = 3;
+ static const DataType data_type = TYPE_UCHAR;
+ static const int num_elements = 3;
};
template<> struct device_type_traits<uchar4> {
- static const DataType data_type = TYPE_UCHAR;
- static const int num_elements = 4;
+ static const DataType data_type = TYPE_UCHAR;
+ static const int num_elements = 4;
};
template<> struct device_type_traits<uint> {
- static const DataType data_type = TYPE_UINT;
- static const int num_elements = 1;
+ static const DataType data_type = TYPE_UINT;
+ static const int num_elements = 1;
};
template<> struct device_type_traits<uint2> {
- static const DataType data_type = TYPE_UINT;
- static const int num_elements = 2;
+ static const DataType data_type = TYPE_UINT;
+ static const int num_elements = 2;
};
template<> struct device_type_traits<uint3> {
- static const DataType data_type = TYPE_UINT;
- static const int num_elements = 3;
+ static const DataType data_type = TYPE_UINT;
+ static const int num_elements = 3;
};
template<> struct device_type_traits<uint4> {
- static const DataType data_type = TYPE_UINT;
- static const int num_elements = 4;
+ static const DataType data_type = TYPE_UINT;
+ static const int num_elements = 4;
};
template<> struct device_type_traits<int> {
- static const DataType data_type = TYPE_INT;
- static const int num_elements = 1;
+ static const DataType data_type = TYPE_INT;
+ static const int num_elements = 1;
};
template<> struct device_type_traits<int2> {
- static const DataType data_type = TYPE_INT;
- static const int num_elements = 2;
+ static const DataType data_type = TYPE_INT;
+ static const int num_elements = 2;
};
template<> struct device_type_traits<int3> {
- static const DataType data_type = TYPE_INT;
- static const int num_elements = 3;
+ static const DataType data_type = TYPE_INT;
+ static const int num_elements = 3;
};
template<> struct device_type_traits<int4> {
- static const DataType data_type = TYPE_INT;
- static const int num_elements = 4;
+ static const DataType data_type = TYPE_INT;
+ static const int num_elements = 4;
};
template<> struct device_type_traits<float> {
- static const DataType data_type = TYPE_FLOAT;
- static const int num_elements = 1;
+ static const DataType data_type = TYPE_FLOAT;
+ static const int num_elements = 1;
};
template<> struct device_type_traits<float2> {
- static const DataType data_type = TYPE_FLOAT;
- static const int num_elements = 2;
+ static const DataType data_type = TYPE_FLOAT;
+ static const int num_elements = 2;
};
template<> struct device_type_traits<float3> {
- static const DataType data_type = TYPE_FLOAT;
- static const int num_elements = 4;
+ static const DataType data_type = TYPE_FLOAT;
+ static const int num_elements = 4;
};
template<> struct device_type_traits<float4> {
- static const DataType data_type = TYPE_FLOAT;
- static const int num_elements = 4;
+ static const DataType data_type = TYPE_FLOAT;
+ static const int num_elements = 4;
};
template<> struct device_type_traits<half> {
- static const DataType data_type = TYPE_HALF;
- static const int num_elements = 1;
+ static const DataType data_type = TYPE_HALF;
+ static const int num_elements = 1;
};
template<> struct device_type_traits<ushort4> {
- static const DataType data_type = TYPE_UINT16;
- static const int num_elements = 4;
+ static const DataType data_type = TYPE_UINT16;
+ static const int num_elements = 4;
};
template<> struct device_type_traits<uint16_t> {
- static const DataType data_type = TYPE_UINT16;
- static const int num_elements = 1;
+ static const DataType data_type = TYPE_UINT16;
+ static const int num_elements = 1;
};
template<> struct device_type_traits<half4> {
- static const DataType data_type = TYPE_HALF;
- static const int num_elements = 4;
+ static const DataType data_type = TYPE_HALF;
+ static const int num_elements = 4;
};
template<> struct device_type_traits<uint64_t> {
- static const DataType data_type = TYPE_UINT64;
- static const int num_elements = 1;
+ static const DataType data_type = TYPE_UINT64;
+ static const int num_elements = 1;
};
/* Device Memory
@@ -184,64 +187,67 @@ template<> struct device_type_traits<uint64_t> {
* Base class for all device memory. This should not be allocated directly,
* instead the appropriate subclass can be used. */
-class device_memory
-{
-public:
- size_t memory_size() { return data_size*data_elements*datatype_size(data_type); }
- size_t memory_elements_size(int elements) {
- return elements*data_elements*datatype_size(data_type);
- }
-
- /* Data information. */
- DataType data_type;
- int data_elements;
- size_t data_size;
- size_t device_size;
- size_t data_width;
- size_t data_height;
- size_t data_depth;
- MemoryType type;
- const char *name;
- InterpolationType interpolation;
- ExtensionType extension;
-
- /* Pointers. */
- Device *device;
- device_ptr device_pointer;
- void *host_pointer;
- void *shared_pointer;
-
- virtual ~device_memory();
-
- void swap_device(Device *new_device, size_t new_device_size, device_ptr new_device_ptr);
- void restore_device();
-
-protected:
- friend class CUDADevice;
-
- /* Only create through subclasses. */
- device_memory(Device *device, const char *name, MemoryType type);
-
- /* No copying allowed. */
- device_memory(const device_memory&);
- device_memory& operator = (const device_memory&);
-
- /* Host allocation on the device. All host_pointer memory should be
- * allocated with these functions, for devices that support using
- * the same pointer for host and device. */
- void *host_alloc(size_t size);
- void host_free();
-
- /* Device memory allocation and copying. */
- void device_alloc();
- void device_free();
- void device_copy_to();
- void device_copy_from(int y, int w, int h, int elem);
- void device_zero();
-
- device_ptr original_device_ptr;
- size_t original_device_size;
- Device *original_device;
+class device_memory {
+ public:
+ size_t memory_size()
+ {
+ return data_size * data_elements * datatype_size(data_type);
+ }
+ size_t memory_elements_size(int elements)
+ {
+ return elements * data_elements * datatype_size(data_type);
+ }
+
+ /* Data information. */
+ DataType data_type;
+ int data_elements;
+ size_t data_size;
+ size_t device_size;
+ size_t data_width;
+ size_t data_height;
+ size_t data_depth;
+ MemoryType type;
+ const char *name;
+ InterpolationType interpolation;
+ ExtensionType extension;
+
+ /* Pointers. */
+ Device *device;
+ device_ptr device_pointer;
+ void *host_pointer;
+ void *shared_pointer;
+
+ virtual ~device_memory();
+
+ void swap_device(Device *new_device, size_t new_device_size, device_ptr new_device_ptr);
+ void restore_device();
+
+ protected:
+ friend class CUDADevice;
+
+ /* Only create through subclasses. */
+ device_memory(Device *device, const char *name, MemoryType type);
+
+ /* No copying allowed. */
+ device_memory(const device_memory &);
+ device_memory &operator=(const device_memory &);
+
+ /* Host allocation on the device. All host_pointer memory should be
+ * allocated with these functions, for devices that support using
+ * the same pointer for host and device. */
+ void *host_alloc(size_t size);
+ void host_free();
+
+ /* Device memory allocation and copying. */
+ void device_alloc();
+ void device_free();
+ void device_copy_to();
+ void device_copy_from(int y, int w, int h, int elem);
+ void device_zero();
+
+ device_ptr original_device_ptr;
+ size_t original_device_size;
+ Device *original_device;
};
/* Device Only Memory
@@ -249,51 +255,49 @@ protected:
* Working memory only needed by the device, with no corresponding allocation
* on the host. Only used internally in the device implementations. */
-template<typename T>
-class device_only_memory : public device_memory
-{
-public:
- device_only_memory(Device *device, const char *name)
- : device_memory(device, name, MEM_DEVICE_ONLY)
- {
- data_type = device_type_traits<T>::data_type;
- data_elements = max(device_type_traits<T>::num_elements, 1);
- }
-
- virtual ~device_only_memory()
- {
- free();
- }
-
- void alloc_to_device(size_t num, bool shrink_to_fit = true)
- {
- size_t new_size = num;
- bool reallocate;
-
- if(shrink_to_fit) {
- reallocate = (data_size != new_size);
- }
- else {
- reallocate = (data_size < new_size);
- }
-
- if(reallocate) {
- device_free();
- data_size = new_size;
- device_alloc();
- }
- }
-
- void free()
- {
- device_free();
- data_size = 0;
- }
-
- void zero_to_device()
- {
- device_zero();
- }
+template<typename T> class device_only_memory : public device_memory {
+ public:
+ device_only_memory(Device *device, const char *name)
+ : device_memory(device, name, MEM_DEVICE_ONLY)
+ {
+ data_type = device_type_traits<T>::data_type;
+ data_elements = max(device_type_traits<T>::num_elements, 1);
+ }
+
+ virtual ~device_only_memory()
+ {
+ free();
+ }
+
+ void alloc_to_device(size_t num, bool shrink_to_fit = true)
+ {
+ size_t new_size = num;
+ bool reallocate;
+
+ if (shrink_to_fit) {
+ reallocate = (data_size != new_size);
+ }
+ else {
+ reallocate = (data_size < new_size);
+ }
+
+ if (reallocate) {
+ device_free();
+ data_size = new_size;
+ device_alloc();
+ }
+ }
+
+ void free()
+ {
+ device_free();
+ data_size = 0;
+ }
+
+ void zero_to_device()
+ {
+ device_zero();
+ }
};
/* Device Vector
@@ -307,135 +311,134 @@ public:
* automatically attached to kernel globals, using the provided name
* matching an entry in kernel_textures.h. */
-template<typename T> class device_vector : public device_memory
-{
-public:
- device_vector(Device *device, const char *name, MemoryType type)
- : device_memory(device, name, type)
- {
- data_type = device_type_traits<T>::data_type;
- data_elements = device_type_traits<T>::num_elements;
-
- assert(data_elements > 0);
- }
-
- virtual ~device_vector()
- {
- free();
- }
-
- /* Host memory allocation. */
- T *alloc(size_t width, size_t height = 0, size_t depth = 0)
- {
- size_t new_size = size(width, height, depth);
-
- if(new_size != data_size) {
- device_free();
- host_free();
- host_pointer = host_alloc(sizeof(T)*new_size);
- assert(device_pointer == 0);
- }
-
- data_size = new_size;
- data_width = width;
- data_height = height;
- data_depth = depth;
-
- return data();
- }
-
- /* Host memory resize. Only use this if the original data needs to be
- * preserved, it is faster to call alloc() if it can be discarded. */
- T *resize(size_t width, size_t height = 0, size_t depth = 0)
- {
- size_t new_size = size(width, height, depth);
-
- if(new_size != data_size) {
- void *new_ptr = host_alloc(sizeof(T)*new_size);
-
- if(new_size && data_size) {
- size_t min_size = ((new_size < data_size)? new_size: data_size);
- memcpy((T*)new_ptr, (T*)host_pointer, sizeof(T)*min_size);
- }
-
- device_free();
- host_free();
- host_pointer = new_ptr;
- assert(device_pointer == 0);
- }
-
- data_size = new_size;
- data_width = width;
- data_height = height;
- data_depth = depth;
-
- return data();
- }
-
- /* Take over data from an existing array. */
- void steal_data(array<T>& from)
- {
- device_free();
- host_free();
-
- data_size = from.size();
- data_width = 0;
- data_height = 0;
- data_depth = 0;
- host_pointer = from.steal_pointer();
- assert(device_pointer == 0);
- }
-
- /* Free device and host memory. */
- void free()
- {
- device_free();
- host_free();
-
- data_size = 0;
- data_width = 0;
- data_height = 0;
- data_depth = 0;
- host_pointer = 0;
- assert(device_pointer == 0);
- }
-
- size_t size()
- {
- return data_size;
- }
-
- T* data()
- {
- return (T*)host_pointer;
- }
-
- T& operator[](size_t i)
- {
- assert(i < data_size);
- return data()[i];
- }
-
- void copy_to_device()
- {
- device_copy_to();
- }
-
- void copy_from_device(int y, int w, int h)
- {
- device_copy_from(y, w, h, sizeof(T));
- }
-
- void zero_to_device()
- {
- device_zero();
- }
-
-protected:
- size_t size(size_t width, size_t height, size_t depth)
- {
- return width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth);
- }
+template<typename T> class device_vector : public device_memory {
+ public:
+ device_vector(Device *device, const char *name, MemoryType type)
+ : device_memory(device, name, type)
+ {
+ data_type = device_type_traits<T>::data_type;
+ data_elements = device_type_traits<T>::num_elements;
+
+ assert(data_elements > 0);
+ }
+
+ virtual ~device_vector()
+ {
+ free();
+ }
+
+ /* Host memory allocation. */
+ T *alloc(size_t width, size_t height = 0, size_t depth = 0)
+ {
+ size_t new_size = size(width, height, depth);
+
+ if (new_size != data_size) {
+ device_free();
+ host_free();
+ host_pointer = host_alloc(sizeof(T) * new_size);
+ assert(device_pointer == 0);
+ }
+
+ data_size = new_size;
+ data_width = width;
+ data_height = height;
+ data_depth = depth;
+
+ return data();
+ }
+
+ /* Host memory resize. Only use this if the original data needs to be
+ * preserved, it is faster to call alloc() if it can be discarded. */
+ T *resize(size_t width, size_t height = 0, size_t depth = 0)
+ {
+ size_t new_size = size(width, height, depth);
+
+ if (new_size != data_size) {
+ void *new_ptr = host_alloc(sizeof(T) * new_size);
+
+ if (new_size && data_size) {
+ size_t min_size = ((new_size < data_size) ? new_size : data_size);
+ memcpy((T *)new_ptr, (T *)host_pointer, sizeof(T) * min_size);
+ }
+
+ device_free();
+ host_free();
+ host_pointer = new_ptr;
+ assert(device_pointer == 0);
+ }
+
+ data_size = new_size;
+ data_width = width;
+ data_height = height;
+ data_depth = depth;
+
+ return data();
+ }
+
+ /* Take over data from an existing array. */
+ void steal_data(array<T> &from)
+ {
+ device_free();
+ host_free();
+
+ data_size = from.size();
+ data_width = 0;
+ data_height = 0;
+ data_depth = 0;
+ host_pointer = from.steal_pointer();
+ assert(device_pointer == 0);
+ }
+
+ /* Free device and host memory. */
+ void free()
+ {
+ device_free();
+ host_free();
+
+ data_size = 0;
+ data_width = 0;
+ data_height = 0;
+ data_depth = 0;
+ host_pointer = 0;
+ assert(device_pointer == 0);
+ }
+
+ size_t size()
+ {
+ return data_size;
+ }
+
+ T *data()
+ {
+ return (T *)host_pointer;
+ }
+
+ T &operator[](size_t i)
+ {
+ assert(i < data_size);
+ return data()[i];
+ }
+
+ void copy_to_device()
+ {
+ device_copy_to();
+ }
+
+ void copy_from_device(int y, int w, int h)
+ {
+ device_copy_from(y, w, h, sizeof(T));
+ }
+
+ void zero_to_device()
+ {
+ device_zero();
+ }
+
+ protected:
+ size_t size(size_t width, size_t height, size_t depth)
+ {
+ return width * ((height == 0) ? 1 : height) * ((depth == 0) ? 1 : depth);
+ }
};
/* Pixel Memory
@@ -443,28 +446,26 @@ protected:
* Device memory to efficiently draw as pixels to the screen in interactive
* rendering. Only copying pixels from the device is supported, not copying to. */
-template<typename T> class device_pixels : public device_vector<T>
-{
-public:
- device_pixels(Device *device, const char *name)
- : device_vector<T>(device, name, MEM_PIXELS)
- {
- }
-
- void alloc_to_device(size_t width, size_t height, size_t depth = 0)
- {
- device_vector<T>::alloc(width, height, depth);
-
- if(!device_memory::device_pointer) {
- device_memory::device_alloc();
- }
- }
-
- T *copy_from_device(int y, int w, int h)
- {
- device_memory::device_copy_from(y, w, h, sizeof(T));
- return device_vector<T>::data();
- }
+template<typename T> class device_pixels : public device_vector<T> {
+ public:
+ device_pixels(Device *device, const char *name) : device_vector<T>(device, name, MEM_PIXELS)
+ {
+ }
+
+ void alloc_to_device(size_t width, size_t height, size_t depth = 0)
+ {
+ device_vector<T>::alloc(width, height, depth);
+
+ if (!device_memory::device_pointer) {
+ device_memory::device_alloc();
+ }
+ }
+
+ T *copy_from_device(int y, int w, int h)
+ {
+ device_memory::device_copy_from(y, w, h, sizeof(T));
+ return device_vector<T>::data();
+ }
};
/* Device Sub Memory
@@ -476,25 +477,24 @@ public:
* Note: some devices require offset and size of the sub_ptr to be properly
* aligned to device->mem_address_alingment(). */
-class device_sub_ptr
-{
-public:
- device_sub_ptr(device_memory& mem, int offset, int size);
- ~device_sub_ptr();
+class device_sub_ptr {
+ public:
+ device_sub_ptr(device_memory &mem, int offset, int size);
+ ~device_sub_ptr();
- device_ptr operator*() const
- {
- return ptr;
- }
+ device_ptr operator*() const
+ {
+ return ptr;
+ }
-protected:
- /* No copying. */
- device_sub_ptr& operator = (const device_sub_ptr&);
+ protected:
+ /* No copying. */
+ device_sub_ptr &operator=(const device_sub_ptr &);
- Device *device;
- device_ptr ptr;
+ Device *device;
+ device_ptr ptr;
};
CCL_NAMESPACE_END
-#endif /* __DEVICE_MEMORY_H__ */
+#endif /* __DEVICE_MEMORY_H__ */
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index bdb7c87fa57..4a40e106115 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -31,391 +31,406 @@
CCL_NAMESPACE_BEGIN
-class MultiDevice : public Device
-{
-public:
- struct SubDevice {
- explicit SubDevice(Device *device_)
- : device(device_) {}
-
- Device *device;
- map<device_ptr, device_ptr> ptr_map;
- };
-
- list<SubDevice> devices;
- device_ptr unique_key;
-
- MultiDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background_)
- : Device(info, stats, profiler, background_), unique_key(1)
- {
- foreach(DeviceInfo& subinfo, info.multi_devices) {
- Device *device = Device::create(subinfo, sub_stats_, profiler, background);
-
- /* Always add CPU devices at the back since GPU devices can change
- * host memory pointers, which CPU uses as device pointer. */
- if(subinfo.type == DEVICE_CPU) {
- devices.push_back(SubDevice(device));
- }
- else {
- devices.push_front(SubDevice(device));
- }
- }
+class MultiDevice : public Device {
+ public:
+ struct SubDevice {
+ explicit SubDevice(Device *device_) : device(device_)
+ {
+ }
+
+ Device *device;
+ map<device_ptr, device_ptr> ptr_map;
+ };
+
+ list<SubDevice> devices;
+ device_ptr unique_key;
+
+ MultiDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background_)
+ : Device(info, stats, profiler, background_), unique_key(1)
+ {
+ foreach (DeviceInfo &subinfo, info.multi_devices) {
+ Device *device = Device::create(subinfo, sub_stats_, profiler, background);
+
+ /* Always add CPU devices at the back since GPU devices can change
+ * host memory pointers, which CPU uses as device pointer. */
+ if (subinfo.type == DEVICE_CPU) {
+ devices.push_back(SubDevice(device));
+ }
+ else {
+ devices.push_front(SubDevice(device));
+ }
+ }
#ifdef WITH_NETWORK
- /* try to add network devices */
- ServerDiscovery discovery(true);
- time_sleep(1.0);
+ /* try to add network devices */
+ ServerDiscovery discovery(true);
+ time_sleep(1.0);
- vector<string> servers = discovery.get_server_list();
+ vector<string> servers = discovery.get_server_list();
- foreach(string& server, servers) {
- Device *device = device_network_create(info, stats, profiler, server.c_str());
- if(device)
- devices.push_back(SubDevice(device));
- }
+ foreach (string &server, servers) {
+ Device *device = device_network_create(info, stats, profiler, server.c_str());
+ if (device)
+ devices.push_back(SubDevice(device));
+ }
#endif
- }
-
- ~MultiDevice()
- {
- foreach(SubDevice& sub, devices)
- delete sub.device;
- }
-
- const string& error_message()
- {
- foreach(SubDevice& sub, devices) {
- if(sub.device->error_message() != "") {
- if(error_msg == "")
- error_msg = sub.device->error_message();
- break;
- }
- }
-
- return error_msg;
- }
-
- virtual bool show_samples() const
- {
- if(devices.size() > 1) {
- return false;
- }
- return devices.front().device->show_samples();
- }
-
- virtual BVHLayoutMask get_bvh_layout_mask() const {
- BVHLayoutMask bvh_layout_mask = BVH_LAYOUT_ALL;
- foreach(const SubDevice& sub_device, devices) {
- bvh_layout_mask &= sub_device.device->get_bvh_layout_mask();
- }
- return bvh_layout_mask;
- }
-
- bool load_kernels(const DeviceRequestedFeatures& requested_features)
- {
- foreach(SubDevice& sub, devices)
- if(!sub.device->load_kernels(requested_features))
- return false;
-
- return true;
- }
-
- bool wait_for_availability(const DeviceRequestedFeatures& requested_features)
- {
- foreach(SubDevice& sub, devices)
- if(!sub.device->wait_for_availability(requested_features))
- return false;
-
- return true;
- }
-
- DeviceKernelStatus get_active_kernel_switch_state()
- {
- DeviceKernelStatus result = DEVICE_KERNEL_USING_FEATURE_KERNEL;
-
- foreach(SubDevice& sub, devices) {
- DeviceKernelStatus subresult = sub.device->get_active_kernel_switch_state();
- switch (subresult) {
- case DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL:
- result = subresult;
- break;
-
- case DEVICE_KERNEL_FEATURE_KERNEL_INVALID:
- case DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE:
- return subresult;
-
- case DEVICE_KERNEL_USING_FEATURE_KERNEL:
- case DEVICE_KERNEL_UNKNOWN:
- break;
- }
- }
- return result;
- }
-
- void mem_alloc(device_memory& mem)
- {
- device_ptr key = unique_key++;
-
- foreach(SubDevice& sub, devices) {
- mem.device = sub.device;
- mem.device_pointer = 0;
- mem.device_size = 0;
-
- sub.device->mem_alloc(mem);
- sub.ptr_map[key] = mem.device_pointer;
- }
-
- mem.device = this;
- mem.device_pointer = key;
- stats.mem_alloc(mem.device_size);
- }
-
- void mem_copy_to(device_memory& mem)
- {
- device_ptr existing_key = mem.device_pointer;
- device_ptr key = (existing_key)? existing_key: unique_key++;
- size_t existing_size = mem.device_size;
-
- foreach(SubDevice& sub, devices) {
- mem.device = sub.device;
- mem.device_pointer = (existing_key)? sub.ptr_map[existing_key]: 0;
- mem.device_size = existing_size;
-
- sub.device->mem_copy_to(mem);
- sub.ptr_map[key] = mem.device_pointer;
- }
-
- mem.device = this;
- mem.device_pointer = key;
- stats.mem_alloc(mem.device_size - existing_size);
- }
-
- void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
- {
- device_ptr key = mem.device_pointer;
- int i = 0, sub_h = h/devices.size();
-
- foreach(SubDevice& sub, devices) {
- int sy = y + i*sub_h;
- int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h;
-
- mem.device = sub.device;
- mem.device_pointer = sub.ptr_map[key];
-
- sub.device->mem_copy_from(mem, sy, w, sh, elem);
- i++;
- }
-
- mem.device = this;
- mem.device_pointer = key;
- }
-
- void mem_zero(device_memory& mem)
- {
- device_ptr existing_key = mem.device_pointer;
- device_ptr key = (existing_key)? existing_key: unique_key++;
- size_t existing_size = mem.device_size;
-
- foreach(SubDevice& sub, devices) {
- mem.device = sub.device;
- mem.device_pointer = (existing_key)? sub.ptr_map[existing_key]: 0;
- mem.device_size = existing_size;
-
- sub.device->mem_zero(mem);
- sub.ptr_map[key] = mem.device_pointer;
- }
-
- mem.device = this;
- mem.device_pointer = key;
- stats.mem_alloc(mem.device_size - existing_size);
- }
-
- void mem_free(device_memory& mem)
- {
- device_ptr key = mem.device_pointer;
- size_t existing_size = mem.device_size;
-
- foreach(SubDevice& sub, devices) {
- mem.device = sub.device;
- mem.device_pointer = sub.ptr_map[key];
- mem.device_size = existing_size;
-
- sub.device->mem_free(mem);
- sub.ptr_map.erase(sub.ptr_map.find(key));
- }
-
- mem.device = this;
- mem.device_pointer = 0;
- mem.device_size = 0;
- stats.mem_free(existing_size);
- }
-
- void const_copy_to(const char *name, void *host, size_t size)
- {
- foreach(SubDevice& sub, devices)
- sub.device->const_copy_to(name, host, size);
- }
-
- void draw_pixels(
- device_memory& rgba, int y,
- int w, int h, int width, int height,
- int dx, int dy, int dw, int dh,
- bool transparent, const DeviceDrawParams &draw_params)
- {
- device_ptr key = rgba.device_pointer;
- int i = 0, sub_h = h/devices.size();
- int sub_height = height/devices.size();
-
- foreach(SubDevice& sub, devices) {
- int sy = y + i*sub_h;
- int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h;
- int sheight = (i == (int)devices.size() - 1)? height - sub_height*i: sub_height;
- int sdy = dy + i*sub_height;
- /* adjust math for w/width */
-
- rgba.device_pointer = sub.ptr_map[key];
- sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, dx, sdy, dw, dh, transparent, draw_params);
- i++;
- }
-
- rgba.device_pointer = key;
- }
-
- void map_tile(Device *sub_device, RenderTile& tile)
- {
- foreach(SubDevice& sub, devices) {
- if(sub.device == sub_device) {
- if(tile.buffer) tile.buffer = sub.ptr_map[tile.buffer];
- }
- }
- }
-
- int device_number(Device *sub_device)
- {
- int i = 0;
-
- foreach(SubDevice& sub, devices) {
- if(sub.device == sub_device)
- return i;
- i++;
- }
-
- return -1;
- }
-
- void map_neighbor_tiles(Device *sub_device, RenderTile *tiles)
- {
- for(int i = 0; i < 9; i++) {
- if(!tiles[i].buffers) {
- continue;
- }
-
- /* If the tile was rendered on another device, copy its memory to
- * to the current device now, for the duration of the denoising task.
- * Note that this temporarily modifies the RenderBuffers and calls
- * the device, so this function is not thread safe. */
- device_vector<float> &mem = tiles[i].buffers->buffer;
- if(mem.device != sub_device) {
- /* Only copy from device to host once. This is faster, but
- * also required for the case where a CPU thread is denoising
- * a tile rendered on the GPU. In that case we have to avoid
- * overwriting the buffer being denoised by the CPU thread. */
- if(!tiles[i].buffers->map_neighbor_copied) {
- tiles[i].buffers->map_neighbor_copied = true;
- mem.copy_from_device(0, mem.data_size, 1);
- }
-
- mem.swap_device(sub_device, 0, 0);
-
- mem.copy_to_device();
- tiles[i].buffer = mem.device_pointer;
- tiles[i].device_size = mem.device_size;
-
- mem.restore_device();
- }
- }
- }
-
- void unmap_neighbor_tiles(Device * sub_device, RenderTile * tiles)
- {
- /* Copy denoised result back to the host. */
- device_vector<float> &mem = tiles[9].buffers->buffer;
- mem.swap_device(sub_device, tiles[9].device_size, tiles[9].buffer);
- mem.copy_from_device(0, mem.data_size, 1);
- mem.restore_device();
- /* Copy denoised result to the original device. */
- mem.copy_to_device();
-
- for(int i = 0; i < 9; i++) {
- if(!tiles[i].buffers) {
- continue;
- }
-
- device_vector<float> &mem = tiles[i].buffers->buffer;
- if(mem.device != sub_device) {
- mem.swap_device(sub_device, tiles[i].device_size, tiles[i].buffer);
- sub_device->mem_free(mem);
- mem.restore_device();
- }
- }
- }
-
- int get_split_task_count(DeviceTask& task)
- {
- int total_tasks = 0;
- list<DeviceTask> tasks;
- task.split(tasks, devices.size());
- foreach(SubDevice& sub, devices) {
- if(!tasks.empty()) {
- DeviceTask subtask = tasks.front();
- tasks.pop_front();
-
- total_tasks += sub.device->get_split_task_count(subtask);
- }
- }
- return total_tasks;
- }
-
- void task_add(DeviceTask& task)
- {
- list<DeviceTask> tasks;
- task.split(tasks, devices.size());
-
- foreach(SubDevice& sub, devices) {
- if(!tasks.empty()) {
- DeviceTask subtask = tasks.front();
- tasks.pop_front();
-
- if(task.buffer) subtask.buffer = sub.ptr_map[task.buffer];
- if(task.rgba_byte) subtask.rgba_byte = sub.ptr_map[task.rgba_byte];
- if(task.rgba_half) subtask.rgba_half = sub.ptr_map[task.rgba_half];
- if(task.shader_input) subtask.shader_input = sub.ptr_map[task.shader_input];
- if(task.shader_output) subtask.shader_output = sub.ptr_map[task.shader_output];
-
- sub.device->task_add(subtask);
- }
- }
- }
-
- void task_wait()
- {
- foreach(SubDevice& sub, devices)
- sub.device->task_wait();
- }
-
- void task_cancel()
- {
- foreach(SubDevice& sub, devices)
- sub.device->task_cancel();
- }
-
-protected:
- Stats sub_stats_;
+ }
+
+ ~MultiDevice()
+ {
+ foreach (SubDevice &sub, devices)
+ delete sub.device;
+ }
+
+ const string &error_message()
+ {
+ foreach (SubDevice &sub, devices) {
+ if (sub.device->error_message() != "") {
+ if (error_msg == "")
+ error_msg = sub.device->error_message();
+ break;
+ }
+ }
+
+ return error_msg;
+ }
+
+ virtual bool show_samples() const
+ {
+ if (devices.size() > 1) {
+ return false;
+ }
+ return devices.front().device->show_samples();
+ }
+
+ virtual BVHLayoutMask get_bvh_layout_mask() const
+ {
+ BVHLayoutMask bvh_layout_mask = BVH_LAYOUT_ALL;
+ foreach (const SubDevice &sub_device, devices) {
+ bvh_layout_mask &= sub_device.device->get_bvh_layout_mask();
+ }
+ return bvh_layout_mask;
+ }
+
+ bool load_kernels(const DeviceRequestedFeatures &requested_features)
+ {
+ foreach (SubDevice &sub, devices)
+ if (!sub.device->load_kernels(requested_features))
+ return false;
+
+ return true;
+ }
+
+ bool wait_for_availability(const DeviceRequestedFeatures &requested_features)
+ {
+ foreach (SubDevice &sub, devices)
+ if (!sub.device->wait_for_availability(requested_features))
+ return false;
+
+ return true;
+ }
+
+ DeviceKernelStatus get_active_kernel_switch_state()
+ {
+ DeviceKernelStatus result = DEVICE_KERNEL_USING_FEATURE_KERNEL;
+
+ foreach (SubDevice &sub, devices) {
+ DeviceKernelStatus subresult = sub.device->get_active_kernel_switch_state();
+ switch (subresult) {
+ case DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL:
+ result = subresult;
+ break;
+
+ case DEVICE_KERNEL_FEATURE_KERNEL_INVALID:
+ case DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE:
+ return subresult;
+
+ case DEVICE_KERNEL_USING_FEATURE_KERNEL:
+ case DEVICE_KERNEL_UNKNOWN:
+ break;
+ }
+ }
+ return result;
+ }
+
+ void mem_alloc(device_memory &mem)
+ {
+ device_ptr key = unique_key++;
+
+ foreach (SubDevice &sub, devices) {
+ mem.device = sub.device;
+ mem.device_pointer = 0;
+ mem.device_size = 0;
+
+ sub.device->mem_alloc(mem);
+ sub.ptr_map[key] = mem.device_pointer;
+ }
+
+ mem.device = this;
+ mem.device_pointer = key;
+ stats.mem_alloc(mem.device_size);
+ }
+
+ void mem_copy_to(device_memory &mem)
+ {
+ device_ptr existing_key = mem.device_pointer;
+ device_ptr key = (existing_key) ? existing_key : unique_key++;
+ size_t existing_size = mem.device_size;
+
+ foreach (SubDevice &sub, devices) {
+ mem.device = sub.device;
+ mem.device_pointer = (existing_key) ? sub.ptr_map[existing_key] : 0;
+ mem.device_size = existing_size;
+
+ sub.device->mem_copy_to(mem);
+ sub.ptr_map[key] = mem.device_pointer;
+ }
+
+ mem.device = this;
+ mem.device_pointer = key;
+ stats.mem_alloc(mem.device_size - existing_size);
+ }
+
+ void mem_copy_from(device_memory &mem, int y, int w, int h, int elem)
+ {
+ device_ptr key = mem.device_pointer;
+ int i = 0, sub_h = h / devices.size();
+
+ foreach (SubDevice &sub, devices) {
+ int sy = y + i * sub_h;
+ int sh = (i == (int)devices.size() - 1) ? h - sub_h * i : sub_h;
+
+ mem.device = sub.device;
+ mem.device_pointer = sub.ptr_map[key];
+
+ sub.device->mem_copy_from(mem, sy, w, sh, elem);
+ i++;
+ }
+
+ mem.device = this;
+ mem.device_pointer = key;
+ }
+
+ void mem_zero(device_memory &mem)
+ {
+ device_ptr existing_key = mem.device_pointer;
+ device_ptr key = (existing_key) ? existing_key : unique_key++;
+ size_t existing_size = mem.device_size;
+
+ foreach (SubDevice &sub, devices) {
+ mem.device = sub.device;
+ mem.device_pointer = (existing_key) ? sub.ptr_map[existing_key] : 0;
+ mem.device_size = existing_size;
+
+ sub.device->mem_zero(mem);
+ sub.ptr_map[key] = mem.device_pointer;
+ }
+
+ mem.device = this;
+ mem.device_pointer = key;
+ stats.mem_alloc(mem.device_size - existing_size);
+ }
+
+ void mem_free(device_memory &mem)
+ {
+ device_ptr key = mem.device_pointer;
+ size_t existing_size = mem.device_size;
+
+ foreach (SubDevice &sub, devices) {
+ mem.device = sub.device;
+ mem.device_pointer = sub.ptr_map[key];
+ mem.device_size = existing_size;
+
+ sub.device->mem_free(mem);
+ sub.ptr_map.erase(sub.ptr_map.find(key));
+ }
+
+ mem.device = this;
+ mem.device_pointer = 0;
+ mem.device_size = 0;
+ stats.mem_free(existing_size);
+ }
+
+ void const_copy_to(const char *name, void *host, size_t size)
+ {
+ foreach (SubDevice &sub, devices)
+ sub.device->const_copy_to(name, host, size);
+ }
+
+ void draw_pixels(device_memory &rgba,
+ int y,
+ int w,
+ int h,
+ int width,
+ int height,
+ int dx,
+ int dy,
+ int dw,
+ int dh,
+ bool transparent,
+ const DeviceDrawParams &draw_params)
+ {
+ device_ptr key = rgba.device_pointer;
+ int i = 0, sub_h = h / devices.size();
+ int sub_height = height / devices.size();
+
+ foreach (SubDevice &sub, devices) {
+ int sy = y + i * sub_h;
+ int sh = (i == (int)devices.size() - 1) ? h - sub_h * i : sub_h;
+ int sheight = (i == (int)devices.size() - 1) ? height - sub_height * i : sub_height;
+ int sdy = dy + i * sub_height;
+ /* adjust math for w/width */
+
+ rgba.device_pointer = sub.ptr_map[key];
+ sub.device->draw_pixels(
+ rgba, sy, w, sh, width, sheight, dx, sdy, dw, dh, transparent, draw_params);
+ i++;
+ }
+
+ rgba.device_pointer = key;
+ }
+
+ void map_tile(Device *sub_device, RenderTile &tile)
+ {
+ foreach (SubDevice &sub, devices) {
+ if (sub.device == sub_device) {
+ if (tile.buffer)
+ tile.buffer = sub.ptr_map[tile.buffer];
+ }
+ }
+ }
+
+ int device_number(Device *sub_device)
+ {
+ int i = 0;
+
+ foreach (SubDevice &sub, devices) {
+ if (sub.device == sub_device)
+ return i;
+ i++;
+ }
+
+ return -1;
+ }
+
+ void map_neighbor_tiles(Device *sub_device, RenderTile *tiles)
+ {
+ for (int i = 0; i < 9; i++) {
+ if (!tiles[i].buffers) {
+ continue;
+ }
+
+ /* If the tile was rendered on another device, copy its memory to
+ * to the current device now, for the duration of the denoising task.
+ * Note that this temporarily modifies the RenderBuffers and calls
+ * the device, so this function is not thread safe. */
+ device_vector<float> &mem = tiles[i].buffers->buffer;
+ if (mem.device != sub_device) {
+ /* Only copy from device to host once. This is faster, but
+ * also required for the case where a CPU thread is denoising
+ * a tile rendered on the GPU. In that case we have to avoid
+ * overwriting the buffer being denoised by the CPU thread. */
+ if (!tiles[i].buffers->map_neighbor_copied) {
+ tiles[i].buffers->map_neighbor_copied = true;
+ mem.copy_from_device(0, mem.data_size, 1);
+ }
+
+ mem.swap_device(sub_device, 0, 0);
+
+ mem.copy_to_device();
+ tiles[i].buffer = mem.device_pointer;
+ tiles[i].device_size = mem.device_size;
+
+ mem.restore_device();
+ }
+ }
+ }
+
+ void unmap_neighbor_tiles(Device *sub_device, RenderTile *tiles)
+ {
+ /* Copy denoised result back to the host. */
+ device_vector<float> &mem = tiles[9].buffers->buffer;
+ mem.swap_device(sub_device, tiles[9].device_size, tiles[9].buffer);
+ mem.copy_from_device(0, mem.data_size, 1);
+ mem.restore_device();
+ /* Copy denoised result to the original device. */
+ mem.copy_to_device();
+
+ for (int i = 0; i < 9; i++) {
+ if (!tiles[i].buffers) {
+ continue;
+ }
+
+ device_vector<float> &mem = tiles[i].buffers->buffer;
+ if (mem.device != sub_device) {
+ mem.swap_device(sub_device, tiles[i].device_size, tiles[i].buffer);
+ sub_device->mem_free(mem);
+ mem.restore_device();
+ }
+ }
+ }
+
+ int get_split_task_count(DeviceTask &task)
+ {
+ int total_tasks = 0;
+ list<DeviceTask> tasks;
+ task.split(tasks, devices.size());
+ foreach (SubDevice &sub, devices) {
+ if (!tasks.empty()) {
+ DeviceTask subtask = tasks.front();
+ tasks.pop_front();
+
+ total_tasks += sub.device->get_split_task_count(subtask);
+ }
+ }
+ return total_tasks;
+ }
+
+ void task_add(DeviceTask &task)
+ {
+ list<DeviceTask> tasks;
+ task.split(tasks, devices.size());
+
+ foreach (SubDevice &sub, devices) {
+ if (!tasks.empty()) {
+ DeviceTask subtask = tasks.front();
+ tasks.pop_front();
+
+ if (task.buffer)
+ subtask.buffer = sub.ptr_map[task.buffer];
+ if (task.rgba_byte)
+ subtask.rgba_byte = sub.ptr_map[task.rgba_byte];
+ if (task.rgba_half)
+ subtask.rgba_half = sub.ptr_map[task.rgba_half];
+ if (task.shader_input)
+ subtask.shader_input = sub.ptr_map[task.shader_input];
+ if (task.shader_output)
+ subtask.shader_output = sub.ptr_map[task.shader_output];
+
+ sub.device->task_add(subtask);
+ }
+ }
+ }
+
+ void task_wait()
+ {
+ foreach (SubDevice &sub, devices)
+ sub.device->task_wait();
+ }
+
+ void task_cancel()
+ {
+ foreach (SubDevice &sub, devices)
+ sub.device->task_cancel();
+ }
+
+ protected:
+ Stats sub_stats_;
};
-Device *device_multi_create(DeviceInfo& info, Stats &stats, Profiler& profiler, bool background)
+Device *device_multi_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background)
{
- return new MultiDevice(info, stats, profiler, background);
+ return new MultiDevice(info, stats, profiler, background);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index 6736480e95a..80334ad8f22 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -33,767 +33,776 @@ typedef map<device_ptr, DataVector> DataMap;
typedef vector<RenderTile> TileList;
/* search a list of tiles and find the one that matches the passed render tile */
-static TileList::iterator tile_list_find(TileList& tile_list, RenderTile& tile)
+static TileList::iterator tile_list_find(TileList &tile_list, RenderTile &tile)
{
- for(TileList::iterator it = tile_list.begin(); it != tile_list.end(); ++it)
- if(tile.x == it->x && tile.y == it->y && tile.start_sample == it->start_sample)
- return it;
- return tile_list.end();
+ for (TileList::iterator it = tile_list.begin(); it != tile_list.end(); ++it)
+ if (tile.x == it->x && tile.y == it->y && tile.start_sample == it->start_sample)
+ return it;
+ return tile_list.end();
}
-class NetworkDevice : public Device
-{
-public:
- boost::asio::io_service io_service;
- tcp::socket socket;
- device_ptr mem_counter;
- DeviceTask the_task; /* todo: handle multiple tasks */
-
- thread_mutex rpc_lock;
-
- virtual bool show_samples() const
- {
- return false;
- }
-
- NetworkDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, const char *address)
- : Device(info, stats, profiler, true), socket(io_service)
- {
- error_func = NetworkError();
- stringstream portstr;
- portstr << SERVER_PORT;
-
- tcp::resolver resolver(io_service);
- tcp::resolver::query query(address, portstr.str());
- tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
- tcp::resolver::iterator end;
+class NetworkDevice : public Device {
+ public:
+ boost::asio::io_service io_service;
+ tcp::socket socket;
+ device_ptr mem_counter;
+ DeviceTask the_task; /* todo: handle multiple tasks */
+
+ thread_mutex rpc_lock;
+
+ virtual bool show_samples() const
+ {
+ return false;
+ }
+
+ NetworkDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, const char *address)
+ : Device(info, stats, profiler, true), socket(io_service)
+ {
+ error_func = NetworkError();
+ stringstream portstr;
+ portstr << SERVER_PORT;
+
+ tcp::resolver resolver(io_service);
+ tcp::resolver::query query(address, portstr.str());
+ tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
+ tcp::resolver::iterator end;
+
+ boost::system::error_code error = boost::asio::error::host_not_found;
+ while (error && endpoint_iterator != end) {
+ socket.close();
+ socket.connect(*endpoint_iterator++, error);
+ }
- boost::system::error_code error = boost::asio::error::host_not_found;
- while(error && endpoint_iterator != end)
- {
- socket.close();
- socket.connect(*endpoint_iterator++, error);
- }
-
- if(error)
- error_func.network_error(error.message());
+ if (error)
+ error_func.network_error(error.message());
- mem_counter = 0;
- }
+ mem_counter = 0;
+ }
- ~NetworkDevice()
- {
- RPCSend snd(socket, &error_func, "stop");
- snd.write();
- }
-
- virtual BVHLayoutMask get_bvh_layout_mask() const {
- return BVH_LAYOUT_BVH2;
- }
-
- void mem_alloc(device_memory& mem)
- {
- if(mem.name) {
- VLOG(1) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
- }
-
- thread_scoped_lock lock(rpc_lock);
+ ~NetworkDevice()
+ {
+ RPCSend snd(socket, &error_func, "stop");
+ snd.write();
+ }
- mem.device_pointer = ++mem_counter;
+ virtual BVHLayoutMask get_bvh_layout_mask() const
+ {
+ return BVH_LAYOUT_BVH2;
+ }
- RPCSend snd(socket, &error_func, "mem_alloc");
- snd.add(mem);
- snd.write();
- }
+ void mem_alloc(device_memory &mem)
+ {
+ if (mem.name) {
+ VLOG(1) << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
+ }
- void mem_copy_to(device_memory& mem)
- {
- thread_scoped_lock lock(rpc_lock);
+ thread_scoped_lock lock(rpc_lock);
- RPCSend snd(socket, &error_func, "mem_copy_to");
+ mem.device_pointer = ++mem_counter;
- snd.add(mem);
- snd.write();
- snd.write_buffer(mem.host_pointer, mem.memory_size());
- }
+ RPCSend snd(socket, &error_func, "mem_alloc");
+ snd.add(mem);
+ snd.write();
+ }
- void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
- {
- thread_scoped_lock lock(rpc_lock);
+ void mem_copy_to(device_memory &mem)
+ {
+ thread_scoped_lock lock(rpc_lock);
- size_t data_size = mem.memory_size();
+ RPCSend snd(socket, &error_func, "mem_copy_to");
- RPCSend snd(socket, &error_func, "mem_copy_from");
+ snd.add(mem);
+ snd.write();
+ snd.write_buffer(mem.host_pointer, mem.memory_size());
+ }
- snd.add(mem);
- snd.add(y);
- snd.add(w);
- snd.add(h);
- snd.add(elem);
- snd.write();
+ void mem_copy_from(device_memory &mem, int y, int w, int h, int elem)
+ {
+ thread_scoped_lock lock(rpc_lock);
- RPCReceive rcv(socket, &error_func);
- rcv.read_buffer(mem.host_pointer, data_size);
- }
+ size_t data_size = mem.memory_size();
- void mem_zero(device_memory& mem)
- {
- thread_scoped_lock lock(rpc_lock);
+ RPCSend snd(socket, &error_func, "mem_copy_from");
- RPCSend snd(socket, &error_func, "mem_zero");
+ snd.add(mem);
+ snd.add(y);
+ snd.add(w);
+ snd.add(h);
+ snd.add(elem);
+ snd.write();
- snd.add(mem);
- snd.write();
- }
+ RPCReceive rcv(socket, &error_func);
+ rcv.read_buffer(mem.host_pointer, data_size);
+ }
- void mem_free(device_memory& mem)
- {
- if(mem.device_pointer) {
- thread_scoped_lock lock(rpc_lock);
-
- RPCSend snd(socket, &error_func, "mem_free");
-
- snd.add(mem);
- snd.write();
-
- mem.device_pointer = 0;
- }
- }
+ void mem_zero(device_memory &mem)
+ {
+ thread_scoped_lock lock(rpc_lock);
- void const_copy_to(const char *name, void *host, size_t size)
- {
- thread_scoped_lock lock(rpc_lock);
+ RPCSend snd(socket, &error_func, "mem_zero");
- RPCSend snd(socket, &error_func, "const_copy_to");
+ snd.add(mem);
+ snd.write();
+ }
- string name_string(name);
-
- snd.add(name_string);
- snd.add(size);
- snd.write();
- snd.write_buffer(host, size);
- }
-
- bool load_kernels(const DeviceRequestedFeatures& requested_features)
- {
- if(error_func.have_error())
- return false;
-
- thread_scoped_lock lock(rpc_lock);
-
- RPCSend snd(socket, &error_func, "load_kernels");
- snd.add(requested_features.experimental);
- snd.add(requested_features.max_closure);
- snd.add(requested_features.max_nodes_group);
- snd.add(requested_features.nodes_features);
- snd.write();
-
- bool result;
- RPCReceive rcv(socket, &error_func);
- rcv.read(result);
-
- return result;
- }
-
- void task_add(DeviceTask& task)
- {
- thread_scoped_lock lock(rpc_lock);
-
- the_task = task;
-
- RPCSend snd(socket, &error_func, "task_add");
- snd.add(task);
- snd.write();
- }
-
- void task_wait()
- {
- thread_scoped_lock lock(rpc_lock);
-
- RPCSend snd(socket, &error_func, "task_wait");
- snd.write();
-
- lock.unlock();
-
- TileList the_tiles;
-
- /* todo: run this threaded for connecting to multiple clients */
- for(;;) {
- if(error_func.have_error())
- break;
-
- RenderTile tile;
-
- lock.lock();
- RPCReceive rcv(socket, &error_func);
-
- if(rcv.name == "acquire_tile") {
- lock.unlock();
-
- /* todo: watch out for recursive calls! */
- if(the_task.acquire_tile(this, tile)) { /* write return as bool */
- the_tiles.push_back(tile);
-
- lock.lock();
- RPCSend snd(socket, &error_func, "acquire_tile");
- snd.add(tile);
- snd.write();
- lock.unlock();
- }
- else {
- lock.lock();
- RPCSend snd(socket, &error_func, "acquire_tile_none");
- snd.write();
- lock.unlock();
- }
- }
- else if(rcv.name == "release_tile") {
- rcv.read(tile);
- lock.unlock();
-
- TileList::iterator it = tile_list_find(the_tiles, tile);
- if(it != the_tiles.end()) {
- tile.buffers = it->buffers;
- the_tiles.erase(it);
- }
-
- assert(tile.buffers != NULL);
-
- the_task.release_tile(tile);
-
- lock.lock();
- RPCSend snd(socket, &error_func, "release_tile");
- snd.write();
- lock.unlock();
- }
- else if(rcv.name == "task_wait_done") {
- lock.unlock();
- break;
- }
- else
- lock.unlock();
- }
- }
-
- void task_cancel()
- {
- thread_scoped_lock lock(rpc_lock);
- RPCSend snd(socket, &error_func, "task_cancel");
- snd.write();
- }
-
- int get_split_task_count(DeviceTask&)
- {
- return 1;
- }
-
-private:
- NetworkError error_func;
+ void mem_free(device_memory &mem)
+ {
+ if (mem.device_pointer) {
+ thread_scoped_lock lock(rpc_lock);
+
+ RPCSend snd(socket, &error_func, "mem_free");
+
+ snd.add(mem);
+ snd.write();
+
+ mem.device_pointer = 0;
+ }
+ }
+
+ void const_copy_to(const char *name, void *host, size_t size)
+ {
+ thread_scoped_lock lock(rpc_lock);
+
+ RPCSend snd(socket, &error_func, "const_copy_to");
+
+ string name_string(name);
+
+ snd.add(name_string);
+ snd.add(size);
+ snd.write();
+ snd.write_buffer(host, size);
+ }
+
+ bool load_kernels(const DeviceRequestedFeatures &requested_features)
+ {
+ if (error_func.have_error())
+ return false;
+
+ thread_scoped_lock lock(rpc_lock);
+
+ RPCSend snd(socket, &error_func, "load_kernels");
+ snd.add(requested_features.experimental);
+ snd.add(requested_features.max_closure);
+ snd.add(requested_features.max_nodes_group);
+ snd.add(requested_features.nodes_features);
+ snd.write();
+
+ bool result;
+ RPCReceive rcv(socket, &error_func);
+ rcv.read(result);
+
+ return result;
+ }
+
+ void task_add(DeviceTask &task)
+ {
+ thread_scoped_lock lock(rpc_lock);
+
+ the_task = task;
+
+ RPCSend snd(socket, &error_func, "task_add");
+ snd.add(task);
+ snd.write();
+ }
+
+ void task_wait()
+ {
+ thread_scoped_lock lock(rpc_lock);
+
+ RPCSend snd(socket, &error_func, "task_wait");
+ snd.write();
+
+ lock.unlock();
+
+ TileList the_tiles;
+
+ /* todo: run this threaded for connecting to multiple clients */
+ for (;;) {
+ if (error_func.have_error())
+ break;
+
+ RenderTile tile;
+
+ lock.lock();
+ RPCReceive rcv(socket, &error_func);
+
+ if (rcv.name == "acquire_tile") {
+ lock.unlock();
+
+ /* todo: watch out for recursive calls! */
+ if (the_task.acquire_tile(this, tile)) { /* write return as bool */
+ the_tiles.push_back(tile);
+
+ lock.lock();
+ RPCSend snd(socket, &error_func, "acquire_tile");
+ snd.add(tile);
+ snd.write();
+ lock.unlock();
+ }
+ else {
+ lock.lock();
+ RPCSend snd(socket, &error_func, "acquire_tile_none");
+ snd.write();
+ lock.unlock();
+ }
+ }
+ else if (rcv.name == "release_tile") {
+ rcv.read(tile);
+ lock.unlock();
+
+ TileList::iterator it = tile_list_find(the_tiles, tile);
+ if (it != the_tiles.end()) {
+ tile.buffers = it->buffers;
+ the_tiles.erase(it);
+ }
+
+ assert(tile.buffers != NULL);
+
+ the_task.release_tile(tile);
+
+ lock.lock();
+ RPCSend snd(socket, &error_func, "release_tile");
+ snd.write();
+ lock.unlock();
+ }
+ else if (rcv.name == "task_wait_done") {
+ lock.unlock();
+ break;
+ }
+ else
+ lock.unlock();
+ }
+ }
+
+ void task_cancel()
+ {
+ thread_scoped_lock lock(rpc_lock);
+ RPCSend snd(socket, &error_func, "task_cancel");
+ snd.write();
+ }
+
+ int get_split_task_count(DeviceTask &)
+ {
+ return 1;
+ }
+
+ private:
+ NetworkError error_func;
};
-Device *device_network_create(DeviceInfo& info, Stats &stats, Profiler &profiler, const char *address)
+Device *device_network_create(DeviceInfo &info,
+ Stats &stats,
+ Profiler &profiler,
+ const char *address)
{
- return new NetworkDevice(info, stats, profiler, address);
+ return new NetworkDevice(info, stats, profiler, address);
}
-void device_network_info(vector<DeviceInfo>& devices)
+void device_network_info(vector<DeviceInfo> &devices)
{
- DeviceInfo info;
+ DeviceInfo info;
- info.type = DEVICE_NETWORK;
- info.description = "Network Device";
- info.id = "NETWORK";
- info.num = 0;
+ info.type = DEVICE_NETWORK;
+ info.description = "Network Device";
+ info.id = "NETWORK";
+ info.num = 0;
- /* todo: get this info from device */
- info.has_volume_decoupled = false;
- info.has_osl = false;
+ /* todo: get this info from device */
+ info.has_volume_decoupled = false;
+ info.has_osl = false;
- devices.push_back(info);
+ devices.push_back(info);
}
class DeviceServer {
-public:
- thread_mutex rpc_lock;
-
- void network_error(const string &message) {
- error_func.network_error(message);
- }
-
- bool have_error() { return error_func.have_error(); }
-
- DeviceServer(Device *device_, tcp::socket& socket_)
- : device(device_), socket(socket_), stop(false), blocked_waiting(false)
- {
- error_func = NetworkError();
- }
-
- void listen()
- {
- /* receive remote function calls */
- for(;;) {
- listen_step();
-
- if(stop)
- break;
- }
- }
-
-protected:
- void listen_step()
- {
- thread_scoped_lock lock(rpc_lock);
- RPCReceive rcv(socket, &error_func);
-
- if(rcv.name == "stop")
- stop = true;
- else
- process(rcv, lock);
- }
-
- /* create a memory buffer for a device buffer and insert it into mem_data */
- DataVector &data_vector_insert(device_ptr client_pointer, size_t data_size)
- {
- /* create a new DataVector and insert it into mem_data */
- pair<DataMap::iterator,bool> data_ins = mem_data.insert(
- DataMap::value_type(client_pointer, DataVector()));
-
- /* make sure it was a unique insertion */
- assert(data_ins.second);
-
- /* get a reference to the inserted vector */
- DataVector &data_v = data_ins.first->second;
-
- /* size the vector */
- data_v.resize(data_size);
-
- return data_v;
- }
-
- DataVector &data_vector_find(device_ptr client_pointer)
- {
- DataMap::iterator i = mem_data.find(client_pointer);
- assert(i != mem_data.end());
- return i->second;
- }
-
- /* setup mapping and reverse mapping of client_pointer<->real_pointer */
- void pointer_mapping_insert(device_ptr client_pointer, device_ptr real_pointer)
- {
- pair<PtrMap::iterator,bool> mapins;
-
- /* insert mapping from client pointer to our real device pointer */
- mapins = ptr_map.insert(PtrMap::value_type(client_pointer, real_pointer));
- assert(mapins.second);
-
- /* insert reverse mapping from real our device pointer to client pointer */
- mapins = ptr_imap.insert(PtrMap::value_type(real_pointer, client_pointer));
- assert(mapins.second);
- }
-
- device_ptr device_ptr_from_client_pointer(device_ptr client_pointer)
- {
- PtrMap::iterator i = ptr_map.find(client_pointer);
- assert(i != ptr_map.end());
- return i->second;
- }
-
- device_ptr device_ptr_from_client_pointer_erase(device_ptr client_pointer)
- {
- PtrMap::iterator i = ptr_map.find(client_pointer);
- assert(i != ptr_map.end());
-
- device_ptr result = i->second;
-
- /* erase the mapping */
- ptr_map.erase(i);
-
- /* erase the reverse mapping */
- PtrMap::iterator irev = ptr_imap.find(result);
- assert(irev != ptr_imap.end());
- ptr_imap.erase(irev);
-
- /* erase the data vector */
- DataMap::iterator idata = mem_data.find(client_pointer);
- assert(idata != mem_data.end());
- mem_data.erase(idata);
-
- return result;
- }
-
- /* note that the lock must be already acquired upon entry.
- * This is necessary because the caller often peeks at
- * the header and delegates control to here when it doesn't
- * specifically handle the current RPC.
- * The lock must be unlocked before returning */
- void process(RPCReceive& rcv, thread_scoped_lock &lock)
- {
- if(rcv.name == "mem_alloc") {
- string name;
- network_device_memory mem(device);
- rcv.read(mem, name);
- lock.unlock();
-
- /* Allocate host side data buffer. */
- size_t data_size = mem.memory_size();
- device_ptr client_pointer = mem.device_pointer;
-
- DataVector &data_v = data_vector_insert(client_pointer, data_size);
- mem.host_pointer = (data_size)? (void*)&(data_v[0]): 0;
-
- /* Perform the allocation on the actual device. */
- device->mem_alloc(mem);
-
- /* Store a mapping to/from client_pointer and real device pointer. */
- pointer_mapping_insert(client_pointer, mem.device_pointer);
- }
- else if(rcv.name == "mem_copy_to") {
- string name;
- network_device_memory mem(device);
- rcv.read(mem, name);
- lock.unlock();
-
- size_t data_size = mem.memory_size();
- device_ptr client_pointer = mem.device_pointer;
-
- if(client_pointer) {
- /* Lookup existing host side data buffer. */
- DataVector &data_v = data_vector_find(client_pointer);
- mem.host_pointer = (void*)&data_v[0];
-
- /* Translate the client pointer to a real device pointer. */
- mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
- }
- else {
- /* Allocate host side data buffer. */
- DataVector &data_v = data_vector_insert(client_pointer, data_size);
- mem.host_pointer = (data_size)? (void*)&(data_v[0]): 0;
- }
-
- /* Copy data from network into memory buffer. */
- rcv.read_buffer((uint8_t*)mem.host_pointer, data_size);
-
- /* Copy the data from the memory buffer to the device buffer. */
- device->mem_copy_to(mem);
-
- if(!client_pointer) {
- /* Store a mapping to/from client_pointer and real device pointer. */
- pointer_mapping_insert(client_pointer, mem.device_pointer);
- }
- }
- else if(rcv.name == "mem_copy_from") {
- string name;
- network_device_memory mem(device);
- int y, w, h, elem;
-
- rcv.read(mem, name);
- rcv.read(y);
- rcv.read(w);
- rcv.read(h);
- rcv.read(elem);
-
- device_ptr client_pointer = mem.device_pointer;
- mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
-
- DataVector &data_v = data_vector_find(client_pointer);
-
- mem.host_pointer = (device_ptr)&(data_v[0]);
-
- device->mem_copy_from(mem, y, w, h, elem);
-
- size_t data_size = mem.memory_size();
-
- RPCSend snd(socket, &error_func, "mem_copy_from");
- snd.write();
- snd.write_buffer((uint8_t*)mem.host_pointer, data_size);
- lock.unlock();
- }
- else if(rcv.name == "mem_zero") {
- string name;
- network_device_memory mem(device);
- rcv.read(mem, name);
- lock.unlock();
-
- size_t data_size = mem.memory_size();
- device_ptr client_pointer = mem.device_pointer;
-
- if(client_pointer) {
- /* Lookup existing host side data buffer. */
- DataVector &data_v = data_vector_find(client_pointer);
- mem.host_pointer = (void*)&data_v[0];
-
- /* Translate the client pointer to a real device pointer. */
- mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
- }
- else {
- /* Allocate host side data buffer. */
- DataVector &data_v = data_vector_insert(client_pointer, data_size);
- mem.host_pointer = (void*)? (device_ptr)&(data_v[0]): 0;
- }
-
- /* Zero memory. */
- device->mem_zero(mem);
-
- if(!client_pointer) {
- /* Store a mapping to/from client_pointer and real device pointer. */
- pointer_mapping_insert(client_pointer, mem.device_pointer);
- }
- }
- else if(rcv.name == "mem_free") {
- string name;
- network_device_memory mem(device);
-
- rcv.read(mem, name);
- lock.unlock();
-
- device_ptr client_pointer = mem.device_pointer;
-
- mem.device_pointer = device_ptr_from_client_pointer_erase(client_pointer);
-
- device->mem_free(mem);
- }
- else if(rcv.name == "const_copy_to") {
- string name_string;
- size_t size;
-
- rcv.read(name_string);
- rcv.read(size);
-
- vector<char> host_vector(size);
- rcv.read_buffer(&host_vector[0], size);
- lock.unlock();
-
- device->const_copy_to(name_string.c_str(), &host_vector[0], size);
- }
- else if(rcv.name == "load_kernels") {
- DeviceRequestedFeatures requested_features;
- rcv.read(requested_features.experimental);
- rcv.read(requested_features.max_closure);
- rcv.read(requested_features.max_nodes_group);
- rcv.read(requested_features.nodes_features);
-
- bool result;
- result = device->load_kernels(requested_features);
- RPCSend snd(socket, &error_func, "load_kernels");
- snd.add(result);
- snd.write();
- lock.unlock();
- }
- else if(rcv.name == "task_add") {
- DeviceTask task;
-
- rcv.read(task);
- lock.unlock();
-
- if(task.buffer)
- task.buffer = device_ptr_from_client_pointer(task.buffer);
-
- if(task.rgba_half)
- task.rgba_half = device_ptr_from_client_pointer(task.rgba_half);
-
- if(task.rgba_byte)
- task.rgba_byte = device_ptr_from_client_pointer(task.rgba_byte);
-
- if(task.shader_input)
- task.shader_input = device_ptr_from_client_pointer(task.shader_input);
-
- if(task.shader_output)
- task.shader_output = device_ptr_from_client_pointer(task.shader_output);
-
- task.acquire_tile = function_bind(&DeviceServer::task_acquire_tile, this, _1, _2);
- task.release_tile = function_bind(&DeviceServer::task_release_tile, this, _1);
- task.update_progress_sample = function_bind(&DeviceServer::task_update_progress_sample, this);
- task.update_tile_sample = function_bind(&DeviceServer::task_update_tile_sample, this, _1);
- task.get_cancel = function_bind(&DeviceServer::task_get_cancel, this);
-
- device->task_add(task);
- }
- else if(rcv.name == "task_wait") {
- lock.unlock();
-
- blocked_waiting = true;
- device->task_wait();
- blocked_waiting = false;
-
- lock.lock();
- RPCSend snd(socket, &error_func, "task_wait_done");
- snd.write();
- lock.unlock();
- }
- else if(rcv.name == "task_cancel") {
- lock.unlock();
- device->task_cancel();
- }
- else if(rcv.name == "acquire_tile") {
- AcquireEntry entry;
- entry.name = rcv.name;
- rcv.read(entry.tile);
- acquire_queue.push_back(entry);
- lock.unlock();
- }
- else if(rcv.name == "acquire_tile_none") {
- AcquireEntry entry;
- entry.name = rcv.name;
- acquire_queue.push_back(entry);
- lock.unlock();
- }
- else if(rcv.name == "release_tile") {
- AcquireEntry entry;
- entry.name = rcv.name;
- acquire_queue.push_back(entry);
- lock.unlock();
- }
- else {
- cout << "Error: unexpected RPC receive call \"" + rcv.name + "\"\n";
- lock.unlock();
- }
- }
-
- bool task_acquire_tile(Device *, RenderTile& tile)
- {
- thread_scoped_lock acquire_lock(acquire_mutex);
-
- bool result = false;
-
- RPCSend snd(socket, &error_func, "acquire_tile");
- snd.write();
-
- do {
- if(blocked_waiting)
- listen_step();
-
- /* todo: avoid busy wait loop */
- thread_scoped_lock lock(rpc_lock);
-
- if(!acquire_queue.empty()) {
- AcquireEntry entry = acquire_queue.front();
- acquire_queue.pop_front();
-
- if(entry.name == "acquire_tile") {
- tile = entry.tile;
-
- if(tile.buffer) tile.buffer = ptr_map[tile.buffer];
-
- result = true;
- break;
- }
- else if(entry.name == "acquire_tile_none") {
- break;
- }
- else {
- cout << "Error: unexpected acquire RPC receive call \"" + entry.name + "\"\n";
- }
- }
- } while(acquire_queue.empty() && !stop && !have_error());
-
- return result;
- }
-
- void task_update_progress_sample()
- {
- ; /* skip */
- }
-
- void task_update_tile_sample(RenderTile&)
- {
- ; /* skip */
- }
-
- void task_release_tile(RenderTile& tile)
- {
- thread_scoped_lock acquire_lock(acquire_mutex);
-
- if(tile.buffer) tile.buffer = ptr_imap[tile.buffer];
-
- {
- thread_scoped_lock lock(rpc_lock);
- RPCSend snd(socket, &error_func, "release_tile");
- snd.add(tile);
- snd.write();
- lock.unlock();
- }
-
- do {
- if(blocked_waiting)
- listen_step();
-
- /* todo: avoid busy wait loop */
- thread_scoped_lock lock(rpc_lock);
-
- if(!acquire_queue.empty()) {
- AcquireEntry entry = acquire_queue.front();
- acquire_queue.pop_front();
-
- if(entry.name == "release_tile") {
- lock.unlock();
- break;
- }
- else {
- cout << "Error: unexpected release RPC receive call \"" + entry.name + "\"\n";
- }
- }
- } while(acquire_queue.empty() && !stop);
- }
-
- bool task_get_cancel()
- {
- return false;
- }
-
- /* properties */
- Device *device;
- tcp::socket& socket;
-
- /* mapping of remote to local pointer */
- PtrMap ptr_map;
- PtrMap ptr_imap;
- DataMap mem_data;
-
- struct AcquireEntry {
- string name;
- RenderTile tile;
- };
-
- thread_mutex acquire_mutex;
- list<AcquireEntry> acquire_queue;
-
- bool stop;
- bool blocked_waiting;
-private:
- NetworkError error_func;
-
- /* todo: free memory and device (osl) on network error */
-
+ public:
+ thread_mutex rpc_lock;
+
+ void network_error(const string &message)
+ {
+ error_func.network_error(message);
+ }
+
+ bool have_error()
+ {
+ return error_func.have_error();
+ }
+
+ DeviceServer(Device *device_, tcp::socket &socket_)
+ : device(device_), socket(socket_), stop(false), blocked_waiting(false)
+ {
+ error_func = NetworkError();
+ }
+
+ void listen()
+ {
+ /* receive remote function calls */
+ for (;;) {
+ listen_step();
+
+ if (stop)
+ break;
+ }
+ }
+
+ protected:
+ void listen_step()
+ {
+ thread_scoped_lock lock(rpc_lock);
+ RPCReceive rcv(socket, &error_func);
+
+ if (rcv.name == "stop")
+ stop = true;
+ else
+ process(rcv, lock);
+ }
+
+ /* create a memory buffer for a device buffer and insert it into mem_data */
+ DataVector &data_vector_insert(device_ptr client_pointer, size_t data_size)
+ {
+ /* create a new DataVector and insert it into mem_data */
+ pair<DataMap::iterator, bool> data_ins = mem_data.insert(
+ DataMap::value_type(client_pointer, DataVector()));
+
+ /* make sure it was a unique insertion */
+ assert(data_ins.second);
+
+ /* get a reference to the inserted vector */
+ DataVector &data_v = data_ins.first->second;
+
+ /* size the vector */
+ data_v.resize(data_size);
+
+ return data_v;
+ }
+
+ DataVector &data_vector_find(device_ptr client_pointer)
+ {
+ DataMap::iterator i = mem_data.find(client_pointer);
+ assert(i != mem_data.end());
+ return i->second;
+ }
+
+ /* setup mapping and reverse mapping of client_pointer<->real_pointer */
+ void pointer_mapping_insert(device_ptr client_pointer, device_ptr real_pointer)
+ {
+ pair<PtrMap::iterator, bool> mapins;
+
+ /* insert mapping from client pointer to our real device pointer */
+ mapins = ptr_map.insert(PtrMap::value_type(client_pointer, real_pointer));
+ assert(mapins.second);
+
+ /* insert reverse mapping from real our device pointer to client pointer */
+ mapins = ptr_imap.insert(PtrMap::value_type(real_pointer, client_pointer));
+ assert(mapins.second);
+ }
+
+ device_ptr device_ptr_from_client_pointer(device_ptr client_pointer)
+ {
+ PtrMap::iterator i = ptr_map.find(client_pointer);
+ assert(i != ptr_map.end());
+ return i->second;
+ }
+
+ device_ptr device_ptr_from_client_pointer_erase(device_ptr client_pointer)
+ {
+ PtrMap::iterator i = ptr_map.find(client_pointer);
+ assert(i != ptr_map.end());
+
+ device_ptr result = i->second;
+
+ /* erase the mapping */
+ ptr_map.erase(i);
+
+ /* erase the reverse mapping */
+ PtrMap::iterator irev = ptr_imap.find(result);
+ assert(irev != ptr_imap.end());
+ ptr_imap.erase(irev);
+
+ /* erase the data vector */
+ DataMap::iterator idata = mem_data.find(client_pointer);
+ assert(idata != mem_data.end());
+ mem_data.erase(idata);
+
+ return result;
+ }
+
+ /* note that the lock must be already acquired upon entry.
+ * This is necessary because the caller often peeks at
+ * the header and delegates control to here when it doesn't
+ * specifically handle the current RPC.
+ * The lock must be unlocked before returning */
+ void process(RPCReceive &rcv, thread_scoped_lock &lock)
+ {
+ if (rcv.name == "mem_alloc") {
+ string name;
+ network_device_memory mem(device);
+ rcv.read(mem, name);
+ lock.unlock();
+
+ /* Allocate host side data buffer. */
+ size_t data_size = mem.memory_size();
+ device_ptr client_pointer = mem.device_pointer;
+
+ DataVector &data_v = data_vector_insert(client_pointer, data_size);
+ mem.host_pointer = (data_size) ? (void *)&(data_v[0]) : 0;
+
+ /* Perform the allocation on the actual device. */
+ device->mem_alloc(mem);
+
+ /* Store a mapping to/from client_pointer and real device pointer. */
+ pointer_mapping_insert(client_pointer, mem.device_pointer);
+ }
+ else if (rcv.name == "mem_copy_to") {
+ string name;
+ network_device_memory mem(device);
+ rcv.read(mem, name);
+ lock.unlock();
+
+ size_t data_size = mem.memory_size();
+ device_ptr client_pointer = mem.device_pointer;
+
+ if (client_pointer) {
+ /* Lookup existing host side data buffer. */
+ DataVector &data_v = data_vector_find(client_pointer);
+ mem.host_pointer = (void *)&data_v[0];
+
+ /* Translate the client pointer to a real device pointer. */
+ mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
+ }
+ else {
+ /* Allocate host side data buffer. */
+ DataVector &data_v = data_vector_insert(client_pointer, data_size);
+ mem.host_pointer = (data_size) ? (void *)&(data_v[0]) : 0;
+ }
+
+ /* Copy data from network into memory buffer. */
+ rcv.read_buffer((uint8_t *)mem.host_pointer, data_size);
+
+ /* Copy the data from the memory buffer to the device buffer. */
+ device->mem_copy_to(mem);
+
+ if (!client_pointer) {
+ /* Store a mapping to/from client_pointer and real device pointer. */
+ pointer_mapping_insert(client_pointer, mem.device_pointer);
+ }
+ }
+ else if (rcv.name == "mem_copy_from") {
+ string name;
+ network_device_memory mem(device);
+ int y, w, h, elem;
+
+ rcv.read(mem, name);
+ rcv.read(y);
+ rcv.read(w);
+ rcv.read(h);
+ rcv.read(elem);
+
+ device_ptr client_pointer = mem.device_pointer;
+ mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
+
+ DataVector &data_v = data_vector_find(client_pointer);
+
+ mem.host_pointer = (device_ptr) & (data_v[0]);
+
+ device->mem_copy_from(mem, y, w, h, elem);
+
+ size_t data_size = mem.memory_size();
+
+ RPCSend snd(socket, &error_func, "mem_copy_from");
+ snd.write();
+ snd.write_buffer((uint8_t *)mem.host_pointer, data_size);
+ lock.unlock();
+ }
+ else if (rcv.name == "mem_zero") {
+ string name;
+ network_device_memory mem(device);
+ rcv.read(mem, name);
+ lock.unlock();
+
+ size_t data_size = mem.memory_size();
+ device_ptr client_pointer = mem.device_pointer;
+
+ if (client_pointer) {
+ /* Lookup existing host side data buffer. */
+ DataVector &data_v = data_vector_find(client_pointer);
+ mem.host_pointer = (void *)&data_v[0];
+
+ /* Translate the client pointer to a real device pointer. */
+ mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
+ }
+ else {
+ /* Allocate host side data buffer. */
+ DataVector &data_v = data_vector_insert(client_pointer, data_size);
+ mem.host_pointer = (void *) ? (device_ptr) & (data_v[0]) : 0;
+ }
+
+ /* Zero memory. */
+ device->mem_zero(mem);
+
+ if (!client_pointer) {
+ /* Store a mapping to/from client_pointer and real device pointer. */
+ pointer_mapping_insert(client_pointer, mem.device_pointer);
+ }
+ }
+ else if (rcv.name == "mem_free") {
+ string name;
+ network_device_memory mem(device);
+
+ rcv.read(mem, name);
+ lock.unlock();
+
+ device_ptr client_pointer = mem.device_pointer;
+
+ mem.device_pointer = device_ptr_from_client_pointer_erase(client_pointer);
+
+ device->mem_free(mem);
+ }
+ else if (rcv.name == "const_copy_to") {
+ string name_string;
+ size_t size;
+
+ rcv.read(name_string);
+ rcv.read(size);
+
+ vector<char> host_vector(size);
+ rcv.read_buffer(&host_vector[0], size);
+ lock.unlock();
+
+ device->const_copy_to(name_string.c_str(), &host_vector[0], size);
+ }
+ else if (rcv.name == "load_kernels") {
+ DeviceRequestedFeatures requested_features;
+ rcv.read(requested_features.experimental);
+ rcv.read(requested_features.max_closure);
+ rcv.read(requested_features.max_nodes_group);
+ rcv.read(requested_features.nodes_features);
+
+ bool result;
+ result = device->load_kernels(requested_features);
+ RPCSend snd(socket, &error_func, "load_kernels");
+ snd.add(result);
+ snd.write();
+ lock.unlock();
+ }
+ else if (rcv.name == "task_add") {
+ DeviceTask task;
+
+ rcv.read(task);
+ lock.unlock();
+
+ if (task.buffer)
+ task.buffer = device_ptr_from_client_pointer(task.buffer);
+
+ if (task.rgba_half)
+ task.rgba_half = device_ptr_from_client_pointer(task.rgba_half);
+
+ if (task.rgba_byte)
+ task.rgba_byte = device_ptr_from_client_pointer(task.rgba_byte);
+
+ if (task.shader_input)
+ task.shader_input = device_ptr_from_client_pointer(task.shader_input);
+
+ if (task.shader_output)
+ task.shader_output = device_ptr_from_client_pointer(task.shader_output);
+
+ task.acquire_tile = function_bind(&DeviceServer::task_acquire_tile, this, _1, _2);
+ task.release_tile = function_bind(&DeviceServer::task_release_tile, this, _1);
+ task.update_progress_sample = function_bind(&DeviceServer::task_update_progress_sample,
+ this);
+ task.update_tile_sample = function_bind(&DeviceServer::task_update_tile_sample, this, _1);
+ task.get_cancel = function_bind(&DeviceServer::task_get_cancel, this);
+
+ device->task_add(task);
+ }
+ else if (rcv.name == "task_wait") {
+ lock.unlock();
+
+ blocked_waiting = true;
+ device->task_wait();
+ blocked_waiting = false;
+
+ lock.lock();
+ RPCSend snd(socket, &error_func, "task_wait_done");
+ snd.write();
+ lock.unlock();
+ }
+ else if (rcv.name == "task_cancel") {
+ lock.unlock();
+ device->task_cancel();
+ }
+ else if (rcv.name == "acquire_tile") {
+ AcquireEntry entry;
+ entry.name = rcv.name;
+ rcv.read(entry.tile);
+ acquire_queue.push_back(entry);
+ lock.unlock();
+ }
+ else if (rcv.name == "acquire_tile_none") {
+ AcquireEntry entry;
+ entry.name = rcv.name;
+ acquire_queue.push_back(entry);
+ lock.unlock();
+ }
+ else if (rcv.name == "release_tile") {
+ AcquireEntry entry;
+ entry.name = rcv.name;
+ acquire_queue.push_back(entry);
+ lock.unlock();
+ }
+ else {
+ cout << "Error: unexpected RPC receive call \"" + rcv.name + "\"\n";
+ lock.unlock();
+ }
+ }
+
+ bool task_acquire_tile(Device *, RenderTile &tile)
+ {
+ thread_scoped_lock acquire_lock(acquire_mutex);
+
+ bool result = false;
+
+ RPCSend snd(socket, &error_func, "acquire_tile");
+ snd.write();
+
+ do {
+ if (blocked_waiting)
+ listen_step();
+
+ /* todo: avoid busy wait loop */
+ thread_scoped_lock lock(rpc_lock);
+
+ if (!acquire_queue.empty()) {
+ AcquireEntry entry = acquire_queue.front();
+ acquire_queue.pop_front();
+
+ if (entry.name == "acquire_tile") {
+ tile = entry.tile;
+
+ if (tile.buffer)
+ tile.buffer = ptr_map[tile.buffer];
+
+ result = true;
+ break;
+ }
+ else if (entry.name == "acquire_tile_none") {
+ break;
+ }
+ else {
+ cout << "Error: unexpected acquire RPC receive call \"" + entry.name + "\"\n";
+ }
+ }
+ } while (acquire_queue.empty() && !stop && !have_error());
+
+ return result;
+ }
+
+ void task_update_progress_sample()
+ {
+ ; /* skip */
+ }
+
+ void task_update_tile_sample(RenderTile &)
+ {
+ ; /* skip */
+ }
+
+ void task_release_tile(RenderTile &tile)
+ {
+ thread_scoped_lock acquire_lock(acquire_mutex);
+
+ if (tile.buffer)
+ tile.buffer = ptr_imap[tile.buffer];
+
+ {
+ thread_scoped_lock lock(rpc_lock);
+ RPCSend snd(socket, &error_func, "release_tile");
+ snd.add(tile);
+ snd.write();
+ lock.unlock();
+ }
+
+ do {
+ if (blocked_waiting)
+ listen_step();
+
+ /* todo: avoid busy wait loop */
+ thread_scoped_lock lock(rpc_lock);
+
+ if (!acquire_queue.empty()) {
+ AcquireEntry entry = acquire_queue.front();
+ acquire_queue.pop_front();
+
+ if (entry.name == "release_tile") {
+ lock.unlock();
+ break;
+ }
+ else {
+ cout << "Error: unexpected release RPC receive call \"" + entry.name + "\"\n";
+ }
+ }
+ } while (acquire_queue.empty() && !stop);
+ }
+
+ bool task_get_cancel()
+ {
+ return false;
+ }
+
+ /* properties */
+ Device *device;
+ tcp::socket &socket;
+
+ /* mapping of remote to local pointer */
+ PtrMap ptr_map;
+ PtrMap ptr_imap;
+ DataMap mem_data;
+
+ struct AcquireEntry {
+ string name;
+ RenderTile tile;
+ };
+
+ thread_mutex acquire_mutex;
+ list<AcquireEntry> acquire_queue;
+
+ bool stop;
+ bool blocked_waiting;
+
+ private:
+ NetworkError error_func;
+
+ /* todo: free memory and device (osl) on network error */
};
void Device::server_run()
{
- try {
- /* starts thread that responds to discovery requests */
- ServerDiscovery discovery;
-
- for(;;) {
- /* accept connection */
- boost::asio::io_service io_service;
- tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
-
- tcp::socket socket(io_service);
- acceptor.accept(socket);
-
- string remote_address = socket.remote_endpoint().address().to_string();
- printf("Connected to remote client at: %s\n", remote_address.c_str());
-
- DeviceServer server(this, socket);
- server.listen();
-
- printf("Disconnected.\n");
- }
- }
- catch(exception& e) {
- fprintf(stderr, "Network server exception: %s\n", e.what());
- }
+ try {
+ /* starts thread that responds to discovery requests */
+ ServerDiscovery discovery;
+
+ for (;;) {
+ /* accept connection */
+ boost::asio::io_service io_service;
+ tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
+
+ tcp::socket socket(io_service);
+ acceptor.accept(socket);
+
+ string remote_address = socket.remote_endpoint().address().to_string();
+ printf("Connected to remote client at: %s\n", remote_address.c_str());
+
+ DeviceServer server(this, socket);
+ server.listen();
+
+ printf("Disconnected.\n");
+ }
+ }
+ catch (exception &e) {
+ fprintf(stderr, "Network server exception: %s\n", e.what());
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h
index 67626ae177f..5b69b815cc6 100644
--- a/intern/cycles/device/device_network.h
+++ b/intern/cycles/device/device_network.h
@@ -19,35 +19,35 @@
#ifdef WITH_NETWORK
-#include <boost/archive/text_iarchive.hpp>
-#include <boost/archive/text_oarchive.hpp>
-#include <boost/archive/binary_iarchive.hpp>
-#include <boost/archive/binary_oarchive.hpp>
-#include <boost/array.hpp>
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/serialization/vector.hpp>
-#include <boost/thread.hpp>
-
-#include <iostream>
-#include <sstream>
-#include <deque>
-
-#include "render/buffers.h"
-
-#include "util/util_foreach.h"
-#include "util/util_list.h"
-#include "util/util_map.h"
-#include "util/util_param.h"
-#include "util/util_string.h"
+# include <boost/archive/text_iarchive.hpp>
+# include <boost/archive/text_oarchive.hpp>
+# include <boost/archive/binary_iarchive.hpp>
+# include <boost/archive/binary_oarchive.hpp>
+# include <boost/array.hpp>
+# include <boost/asio.hpp>
+# include <boost/bind.hpp>
+# include <boost/serialization/vector.hpp>
+# include <boost/thread.hpp>
+
+# include <iostream>
+# include <sstream>
+# include <deque>
+
+# include "render/buffers.h"
+
+# include "util/util_foreach.h"
+# include "util/util_list.h"
+# include "util/util_map.h"
+# include "util/util_param.h"
+# include "util/util_string.h"
CCL_NAMESPACE_BEGIN
-using std::cout;
using std::cerr;
+using std::cout;
+using std::exception;
using std::hex;
using std::setw;
-using std::exception;
using boost::asio::ip::tcp;
@@ -56,436 +56,435 @@ static const int DISCOVER_PORT = 5121;
static const string DISCOVER_REQUEST_MSG = "REQUEST_RENDER_SERVER_IP";
static const string DISCOVER_REPLY_MSG = "REPLY_RENDER_SERVER_IP";
-#if 0
+# if 0
typedef boost::archive::text_oarchive o_archive;
typedef boost::archive::text_iarchive i_archive;
-#else
+# else
typedef boost::archive::binary_oarchive o_archive;
typedef boost::archive::binary_iarchive i_archive;
-#endif
+# endif
/* Serialization of device memory */
-class network_device_memory : public device_memory
-{
-public:
- network_device_memory(Device *device)
- : device_memory(device, "", MEM_READ_ONLY)
- {
- }
+class network_device_memory : public device_memory {
+ public:
+ network_device_memory(Device *device) : device_memory(device, "", MEM_READ_ONLY)
+ {
+ }
- ~network_device_memory()
- {
- device_pointer = 0;
- };
+ ~network_device_memory()
+ {
+ device_pointer = 0;
+ };
- vector<char> local_data;
+ vector<char> local_data;
};
/* Common netowrk error function / object for both DeviceNetwork and DeviceServer*/
class NetworkError {
-public:
- NetworkError() {
- error = "";
- error_count = 0;
- }
-
- ~NetworkError() {}
-
- void network_error(const string& message) {
- error = message;
- error_count += 1;
- }
-
- bool have_error() {
- return true ? error_count > 0 : false;
- }
-
-private:
- string error;
- int error_count;
+ public:
+ NetworkError()
+ {
+ error = "";
+ error_count = 0;
+ }
+
+ ~NetworkError()
+ {
+ }
+
+ void network_error(const string &message)
+ {
+ error = message;
+ error_count += 1;
+ }
+
+ bool have_error()
+ {
+ return true ? error_count > 0 : false;
+ }
+
+ private:
+ string error;
+ int error_count;
};
-
/* Remote procedure call Send */
class RPCSend {
-public:
- RPCSend(tcp::socket& socket_, NetworkError* e, const string& name_ = "")
- : name(name_), socket(socket_), archive(archive_stream), sent(false)
- {
- archive & name_;
- error_func = e;
- fprintf(stderr, "rpc send %s\n", name.c_str());
- }
-
- ~RPCSend()
- {
- }
-
- void add(const device_memory& mem)
- {
- archive & mem.data_type & mem.data_elements & mem.data_size;
- archive & mem.data_width & mem.data_height & mem.data_depth & mem.device_pointer;
- archive & mem.type & string(mem.name);
- archive & mem.interpolation & mem.extension;
- archive & mem.device_pointer;
- }
-
- template<typename T> void add(const T& data)
- {
- archive & data;
- }
-
- void add(const DeviceTask& task)
- {
- int type = (int)task.type;
- archive & type & task.x & task.y & task.w & task.h;
- archive & task.rgba_byte & task.rgba_half & task.buffer & task.sample & task.num_samples;
- archive & task.offset & task.stride;
- archive & task.shader_input & task.shader_output & task.shader_eval_type;
- archive & task.shader_x & task.shader_w;
- archive & task.need_finish_queue;
- }
-
- void add(const RenderTile& tile)
- {
- archive & tile.x & tile.y & tile.w & tile.h;
- archive & tile.start_sample & tile.num_samples & tile.sample;
- archive & tile.resolution & tile.offset & tile.stride;
- archive & tile.buffer;
- }
-
- void write()
- {
- boost::system::error_code error;
-
- /* get string from stream */
- string archive_str = archive_stream.str();
-
- /* first send fixed size header with size of following data */
- ostringstream header_stream;
- header_stream << setw(8) << hex << archive_str.size();
- string header_str = header_stream.str();
-
- boost::asio::write(socket,
- boost::asio::buffer(header_str),
- boost::asio::transfer_all(), error);
-
- if(error.value())
- error_func->network_error(error.message());
-
- /* then send actual data */
- boost::asio::write(socket,
- boost::asio::buffer(archive_str),
- boost::asio::transfer_all(), error);
-
- if(error.value())
- error_func->network_error(error.message());
-
- sent = true;
- }
-
- void write_buffer(void *buffer, size_t size)
- {
- boost::system::error_code error;
-
- boost::asio::write(socket,
- boost::asio::buffer(buffer, size),
- boost::asio::transfer_all(), error);
-
- if(error.value())
- error_func->network_error(error.message());
- }
-
-protected:
- string name;
- tcp::socket& socket;
- ostringstream archive_stream;
- o_archive archive;
- bool sent;
- NetworkError *error_func;
+ public:
+ RPCSend(tcp::socket &socket_, NetworkError *e, const string &name_ = "")
+ : name(name_), socket(socket_), archive(archive_stream), sent(false)
+ {
+ archive &name_;
+ error_func = e;
+ fprintf(stderr, "rpc send %s\n", name.c_str());
+ }
+
+ ~RPCSend()
+ {
+ }
+
+ void add(const device_memory &mem)
+ {
+ archive &mem.data_type &mem.data_elements &mem.data_size;
+ archive &mem.data_width &mem.data_height &mem.data_depth &mem.device_pointer;
+ archive &mem.type &string(mem.name);
+ archive &mem.interpolation &mem.extension;
+ archive &mem.device_pointer;
+ }
+
+ template<typename T> void add(const T &data)
+ {
+ archive &data;
+ }
+
+ void add(const DeviceTask &task)
+ {
+ int type = (int)task.type;
+ archive &type &task.x &task.y &task.w &task.h;
+ archive &task.rgba_byte &task.rgba_half &task.buffer &task.sample &task.num_samples;
+ archive &task.offset &task.stride;
+ archive &task.shader_input &task.shader_output &task.shader_eval_type;
+ archive &task.shader_x &task.shader_w;
+ archive &task.need_finish_queue;
+ }
+
+ void add(const RenderTile &tile)
+ {
+ archive &tile.x &tile.y &tile.w &tile.h;
+ archive &tile.start_sample &tile.num_samples &tile.sample;
+ archive &tile.resolution &tile.offset &tile.stride;
+ archive &tile.buffer;
+ }
+
+ void write()
+ {
+ boost::system::error_code error;
+
+ /* get string from stream */
+ string archive_str = archive_stream.str();
+
+ /* first send fixed size header with size of following data */
+ ostringstream header_stream;
+ header_stream << setw(8) << hex << archive_str.size();
+ string header_str = header_stream.str();
+
+ boost::asio::write(
+ socket, boost::asio::buffer(header_str), boost::asio::transfer_all(), error);
+
+ if (error.value())
+ error_func->network_error(error.message());
+
+ /* then send actual data */
+ boost::asio::write(
+ socket, boost::asio::buffer(archive_str), boost::asio::transfer_all(), error);
+
+ if (error.value())
+ error_func->network_error(error.message());
+
+ sent = true;
+ }
+
+ void write_buffer(void *buffer, size_t size)
+ {
+ boost::system::error_code error;
+
+ boost::asio::write(
+ socket, boost::asio::buffer(buffer, size), boost::asio::transfer_all(), error);
+
+ if (error.value())
+ error_func->network_error(error.message());
+ }
+
+ protected:
+ string name;
+ tcp::socket &socket;
+ ostringstream archive_stream;
+ o_archive archive;
+ bool sent;
+ NetworkError *error_func;
};
/* Remote procedure call Receive */
class RPCReceive {
-public:
- RPCReceive(tcp::socket& socket_, NetworkError* e )
- : socket(socket_), archive_stream(NULL), archive(NULL)
- {
- error_func = e;
- /* read head with fixed size */
- vector<char> header(8);
- boost::system::error_code error;
- size_t len = boost::asio::read(socket, boost::asio::buffer(header), error);
-
- if(error.value()) {
- error_func->network_error(error.message());
- }
-
- /* verify if we got something */
- if(len == header.size()) {
- /* decode header */
- string header_str(&header[0], header.size());
- istringstream header_stream(header_str);
-
- size_t data_size;
-
- if((header_stream >> hex >> data_size)) {
-
- vector<char> data(data_size);
- size_t len = boost::asio::read(socket, boost::asio::buffer(data), error);
-
- if(error.value())
- error_func->network_error(error.message());
-
-
- if(len == data_size) {
- archive_str = (data.size())? string(&data[0], data.size()): string("");
-
- archive_stream = new istringstream(archive_str);
- archive = new i_archive(*archive_stream);
-
- *archive & name;
- fprintf(stderr, "rpc receive %s\n", name.c_str());
- }
- else {
- error_func->network_error("Network receive error: data size doesn't match header");
- }
- }
- else {
- error_func->network_error("Network receive error: can't decode data size from header");
- }
- }
- else {
- error_func->network_error("Network receive error: invalid header size");
- }
- }
-
- ~RPCReceive()
- {
- delete archive;
- delete archive_stream;
- }
-
- void read(network_device_memory& mem, string& name)
- {
- *archive & mem.data_type & mem.data_elements & mem.data_size;
- *archive & mem.data_width & mem.data_height & mem.data_depth & mem.device_pointer;
- *archive & mem.type & name;
- *archive & mem.interpolation & mem.extension;
- *archive & mem.device_pointer;
-
- mem.name = name.c_str();
- mem.host_pointer = 0;
-
- /* Can't transfer OpenGL texture over network. */
- if(mem.type == MEM_PIXELS) {
- mem.type = MEM_READ_WRITE;
- }
- }
-
- template<typename T> void read(T& data)
- {
- *archive & data;
- }
-
- void read_buffer(void *buffer, size_t size)
- {
- boost::system::error_code error;
- size_t len = boost::asio::read(socket, boost::asio::buffer(buffer, size), error);
-
- if(error.value()) {
- error_func->network_error(error.message());
- }
-
- if(len != size)
- cout << "Network receive error: buffer size doesn't match expected size\n";
- }
-
- void read(DeviceTask& task)
- {
- int type;
-
- *archive & type & task.x & task.y & task.w & task.h;
- *archive & task.rgba_byte & task.rgba_half & task.buffer & task.sample & task.num_samples;
- *archive & task.offset & task.stride;
- *archive & task.shader_input & task.shader_output & task.shader_eval_type;
- *archive & task.shader_x & task.shader_w;
- *archive & task.need_finish_queue;
-
- task.type = (DeviceTask::Type)type;
- }
-
- void read(RenderTile& tile)
- {
- *archive & tile.x & tile.y & tile.w & tile.h;
- *archive & tile.start_sample & tile.num_samples & tile.sample;
- *archive & tile.resolution & tile.offset & tile.stride;
- *archive & tile.buffer;
-
- tile.buffers = NULL;
- }
-
- string name;
-
-protected:
- tcp::socket& socket;
- string archive_str;
- istringstream *archive_stream;
- i_archive *archive;
- NetworkError *error_func;
+ public:
+ RPCReceive(tcp::socket &socket_, NetworkError *e)
+ : socket(socket_), archive_stream(NULL), archive(NULL)
+ {
+ error_func = e;
+ /* read head with fixed size */
+ vector<char> header(8);
+ boost::system::error_code error;
+ size_t len = boost::asio::read(socket, boost::asio::buffer(header), error);
+
+ if (error.value()) {
+ error_func->network_error(error.message());
+ }
+
+ /* verify if we got something */
+ if (len == header.size()) {
+ /* decode header */
+ string header_str(&header[0], header.size());
+ istringstream header_stream(header_str);
+
+ size_t data_size;
+
+ if ((header_stream >> hex >> data_size)) {
+
+ vector<char> data(data_size);
+ size_t len = boost::asio::read(socket, boost::asio::buffer(data), error);
+
+ if (error.value())
+ error_func->network_error(error.message());
+
+ if (len == data_size) {
+ archive_str = (data.size()) ? string(&data[0], data.size()) : string("");
+
+ archive_stream = new istringstream(archive_str);
+ archive = new i_archive(*archive_stream);
+
+ *archive &name;
+ fprintf(stderr, "rpc receive %s\n", name.c_str());
+ }
+ else {
+ error_func->network_error("Network receive error: data size doesn't match header");
+ }
+ }
+ else {
+ error_func->network_error("Network receive error: can't decode data size from header");
+ }
+ }
+ else {
+ error_func->network_error("Network receive error: invalid header size");
+ }
+ }
+
+ ~RPCReceive()
+ {
+ delete archive;
+ delete archive_stream;
+ }
+
+ void read(network_device_memory &mem, string &name)
+ {
+ *archive &mem.data_type &mem.data_elements &mem.data_size;
+ *archive &mem.data_width &mem.data_height &mem.data_depth &mem.device_pointer;
+ *archive &mem.type &name;
+ *archive &mem.interpolation &mem.extension;
+ *archive &mem.device_pointer;
+
+ mem.name = name.c_str();
+ mem.host_pointer = 0;
+
+ /* Can't transfer OpenGL texture over network. */
+ if (mem.type == MEM_PIXELS) {
+ mem.type = MEM_READ_WRITE;
+ }
+ }
+
+ template<typename T> void read(T &data)
+ {
+ *archive &data;
+ }
+
+ void read_buffer(void *buffer, size_t size)
+ {
+ boost::system::error_code error;
+ size_t len = boost::asio::read(socket, boost::asio::buffer(buffer, size), error);
+
+ if (error.value()) {
+ error_func->network_error(error.message());
+ }
+
+ if (len != size)
+ cout << "Network receive error: buffer size doesn't match expected size\n";
+ }
+
+ void read(DeviceTask &task)
+ {
+ int type;
+
+ *archive &type &task.x &task.y &task.w &task.h;
+ *archive &task.rgba_byte &task.rgba_half &task.buffer &task.sample &task.num_samples;
+ *archive &task.offset &task.stride;
+ *archive &task.shader_input &task.shader_output &task.shader_eval_type;
+ *archive &task.shader_x &task.shader_w;
+ *archive &task.need_finish_queue;
+
+ task.type = (DeviceTask::Type)type;
+ }
+
+ void read(RenderTile &tile)
+ {
+ *archive &tile.x &tile.y &tile.w &tile.h;
+ *archive &tile.start_sample &tile.num_samples &tile.sample;
+ *archive &tile.resolution &tile.offset &tile.stride;
+ *archive &tile.buffer;
+
+ tile.buffers = NULL;
+ }
+
+ string name;
+
+ protected:
+ tcp::socket &socket;
+ string archive_str;
+ istringstream *archive_stream;
+ i_archive *archive;
+ NetworkError *error_func;
};
/* Server auto discovery */
class ServerDiscovery {
-public:
- explicit ServerDiscovery(bool discover = false)
- : listen_socket(io_service), collect_servers(false)
- {
- /* setup listen socket */
- listen_endpoint.address(boost::asio::ip::address_v4::any());
- listen_endpoint.port(DISCOVER_PORT);
-
- listen_socket.open(listen_endpoint.protocol());
-
- boost::asio::socket_base::reuse_address option(true);
- listen_socket.set_option(option);
-
- listen_socket.bind(listen_endpoint);
-
- /* setup receive callback */
- async_receive();
-
- /* start server discovery */
- if(discover) {
- collect_servers = true;
- servers.clear();
-
- broadcast_message(DISCOVER_REQUEST_MSG);
- }
-
- /* start thread */
- work = new boost::asio::io_service::work(io_service);
- thread = new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service));
- }
-
- ~ServerDiscovery()
- {
- io_service.stop();
- thread->join();
- delete thread;
- delete work;
- }
-
- vector<string> get_server_list()
- {
- vector<string> result;
-
- mutex.lock();
- result = vector<string>(servers.begin(), servers.end());
- mutex.unlock();
-
- return result;
- }
-
-private:
- void handle_receive_from(const boost::system::error_code& error, size_t size)
- {
- if(error) {
- cout << "Server discovery receive error: " << error.message() << "\n";
- return;
- }
-
- if(size > 0) {
- string msg = string(receive_buffer, size);
-
- /* handle incoming message */
- if(collect_servers) {
- if(msg == DISCOVER_REPLY_MSG) {
- string address = receive_endpoint.address().to_string();
-
- mutex.lock();
-
- /* add address if it's not already in the list */
- bool found = std::find(servers.begin(), servers.end(),
- address) != servers.end();
-
- if(!found)
- servers.push_back(address);
-
- mutex.unlock();
- }
- }
- else {
- /* reply to request */
- if(msg == DISCOVER_REQUEST_MSG)
- broadcast_message(DISCOVER_REPLY_MSG);
- }
- }
-
- async_receive();
- }
-
- void async_receive()
- {
- listen_socket.async_receive_from(
- boost::asio::buffer(receive_buffer), receive_endpoint,
- boost::bind(&ServerDiscovery::handle_receive_from, this,
- boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
- }
-
- void broadcast_message(const string& msg)
- {
- /* setup broadcast socket */
- boost::asio::ip::udp::socket socket(io_service);
-
- socket.open(boost::asio::ip::udp::v4());
-
- boost::asio::socket_base::broadcast option(true);
- socket.set_option(option);
-
- boost::asio::ip::udp::endpoint broadcast_endpoint(
- boost::asio::ip::address::from_string("255.255.255.255"), DISCOVER_PORT);
-
- /* broadcast message */
- socket.send_to(boost::asio::buffer(msg), broadcast_endpoint);
- }
-
- /* network service and socket */
- boost::asio::io_service io_service;
- boost::asio::ip::udp::endpoint listen_endpoint;
- boost::asio::ip::udp::socket listen_socket;
-
- /* threading */
- boost::thread *thread;
- boost::asio::io_service::work *work;
- boost::mutex mutex;
-
- /* buffer and endpoint for receiving messages */
- char receive_buffer[256];
- boost::asio::ip::udp::endpoint receive_endpoint;
-
- // os, version, devices, status, host name, group name, ip as far as fields go
- struct ServerInfo {
- string cycles_version;
- string os;
- int device_count;
- string status;
- string host_name;
- string group_name;
- string host_addr;
- };
-
- /* collection of server addresses in list */
- bool collect_servers;
- vector<string> servers;
+ public:
+ explicit ServerDiscovery(bool discover = false)
+ : listen_socket(io_service), collect_servers(false)
+ {
+ /* setup listen socket */
+ listen_endpoint.address(boost::asio::ip::address_v4::any());
+ listen_endpoint.port(DISCOVER_PORT);
+
+ listen_socket.open(listen_endpoint.protocol());
+
+ boost::asio::socket_base::reuse_address option(true);
+ listen_socket.set_option(option);
+
+ listen_socket.bind(listen_endpoint);
+
+ /* setup receive callback */
+ async_receive();
+
+ /* start server discovery */
+ if (discover) {
+ collect_servers = true;
+ servers.clear();
+
+ broadcast_message(DISCOVER_REQUEST_MSG);
+ }
+
+ /* start thread */
+ work = new boost::asio::io_service::work(io_service);
+ thread = new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service));
+ }
+
+ ~ServerDiscovery()
+ {
+ io_service.stop();
+ thread->join();
+ delete thread;
+ delete work;
+ }
+
+ vector<string> get_server_list()
+ {
+ vector<string> result;
+
+ mutex.lock();
+ result = vector<string>(servers.begin(), servers.end());
+ mutex.unlock();
+
+ return result;
+ }
+
+ private:
+ void handle_receive_from(const boost::system::error_code &error, size_t size)
+ {
+ if (error) {
+ cout << "Server discovery receive error: " << error.message() << "\n";
+ return;
+ }
+
+ if (size > 0) {
+ string msg = string(receive_buffer, size);
+
+ /* handle incoming message */
+ if (collect_servers) {
+ if (msg == DISCOVER_REPLY_MSG) {
+ string address = receive_endpoint.address().to_string();
+
+ mutex.lock();
+
+ /* add address if it's not already in the list */
+ bool found = std::find(servers.begin(), servers.end(), address) != servers.end();
+
+ if (!found)
+ servers.push_back(address);
+
+ mutex.unlock();
+ }
+ }
+ else {
+ /* reply to request */
+ if (msg == DISCOVER_REQUEST_MSG)
+ broadcast_message(DISCOVER_REPLY_MSG);
+ }
+ }
+
+ async_receive();
+ }
+
+ void async_receive()
+ {
+ listen_socket.async_receive_from(boost::asio::buffer(receive_buffer),
+ receive_endpoint,
+ boost::bind(&ServerDiscovery::handle_receive_from,
+ this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ }
+
+ void broadcast_message(const string &msg)
+ {
+ /* setup broadcast socket */
+ boost::asio::ip::udp::socket socket(io_service);
+
+ socket.open(boost::asio::ip::udp::v4());
+
+ boost::asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+ boost::asio::ip::udp::endpoint broadcast_endpoint(
+ boost::asio::ip::address::from_string("255.255.255.255"), DISCOVER_PORT);
+
+ /* broadcast message */
+ socket.send_to(boost::asio::buffer(msg), broadcast_endpoint);
+ }
+
+ /* network service and socket */
+ boost::asio::io_service io_service;
+ boost::asio::ip::udp::endpoint listen_endpoint;
+ boost::asio::ip::udp::socket listen_socket;
+
+ /* threading */
+ boost::thread *thread;
+ boost::asio::io_service::work *work;
+ boost::mutex mutex;
+
+ /* buffer and endpoint for receiving messages */
+ char receive_buffer[256];
+ boost::asio::ip::udp::endpoint receive_endpoint;
+
+ // os, version, devices, status, host name, group name, ip as far as fields go
+ struct ServerInfo {
+ string cycles_version;
+ string os;
+ int device_count;
+ string status;
+ string host_name;
+ string group_name;
+ string host_addr;
+ };
+
+ /* collection of server addresses in list */
+ bool collect_servers;
+ vector<string> servers;
};
CCL_NAMESPACE_END
#endif
-#endif /* __DEVICE_NETWORK_H__ */
+#endif /* __DEVICE_NETWORK_H__ */
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 4cefaa217f1..99a8d2438d6 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -16,218 +16,211 @@
#ifdef WITH_OPENCL
-#include "device/opencl/opencl.h"
+# include "device/opencl/opencl.h"
-#include "device/device_intern.h"
+# include "device/device_intern.h"
-#include "util/util_foreach.h"
-#include "util/util_logging.h"
-#include "util/util_set.h"
-#include "util/util_string.h"
+# include "util/util_foreach.h"
+# include "util/util_logging.h"
+# include "util/util_set.h"
+# include "util/util_string.h"
CCL_NAMESPACE_BEGIN
-Device *device_opencl_create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background)
+Device *device_opencl_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background)
{
- return opencl_create_split_device(info, stats, profiler, background);
+ return opencl_create_split_device(info, stats, profiler, background);
}
bool device_opencl_init()
{
- static bool initialized = false;
- static bool result = false;
-
- if(initialized)
- return result;
-
- initialized = true;
-
- if(OpenCLInfo::device_type() != 0) {
- int clew_result = clewInit();
- if(clew_result == CLEW_SUCCESS) {
- VLOG(1) << "CLEW initialization succeeded.";
- result = true;
- }
- else {
- VLOG(1) << "CLEW initialization failed: "
- << ((clew_result == CLEW_ERROR_ATEXIT_FAILED)
- ? "Error setting up atexit() handler"
- : "Error opening the library");
- }
- }
- else {
- VLOG(1) << "Skip initializing CLEW, platform is force disabled.";
- result = false;
- }
-
- return result;
+ static bool initialized = false;
+ static bool result = false;
+
+ if (initialized)
+ return result;
+
+ initialized = true;
+
+ if (OpenCLInfo::device_type() != 0) {
+ int clew_result = clewInit();
+ if (clew_result == CLEW_SUCCESS) {
+ VLOG(1) << "CLEW initialization succeeded.";
+ result = true;
+ }
+ else {
+ VLOG(1) << "CLEW initialization failed: "
+ << ((clew_result == CLEW_ERROR_ATEXIT_FAILED) ? "Error setting up atexit() handler" :
+ "Error opening the library");
+ }
+ }
+ else {
+ VLOG(1) << "Skip initializing CLEW, platform is force disabled.";
+ result = false;
+ }
+
+ return result;
}
-
static cl_int device_opencl_get_num_platforms_safe(cl_uint *num_platforms)
{
-#ifdef _WIN32
- __try {
- return clGetPlatformIDs(0, NULL, num_platforms);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- /* Ignore crashes inside the OpenCL driver and hope we can
- * survive even with corrupted OpenCL installs. */
- fprintf(stderr, "Cycles OpenCL: driver crashed, continuing without OpenCL.\n");
- }
-
- *num_platforms = 0;
- return CL_DEVICE_NOT_FOUND;
-#else
- return clGetPlatformIDs(0, NULL, num_platforms);
-#endif
+# ifdef _WIN32
+ __try {
+ return clGetPlatformIDs(0, NULL, num_platforms);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ /* Ignore crashes inside the OpenCL driver and hope we can
+ * survive even with corrupted OpenCL installs. */
+ fprintf(stderr, "Cycles OpenCL: driver crashed, continuing without OpenCL.\n");
+ }
+
+ *num_platforms = 0;
+ return CL_DEVICE_NOT_FOUND;
+# else
+ return clGetPlatformIDs(0, NULL, num_platforms);
+# endif
}
-void device_opencl_info(vector<DeviceInfo>& devices)
+void device_opencl_info(vector<DeviceInfo> &devices)
{
- cl_uint num_platforms = 0;
- device_opencl_get_num_platforms_safe(&num_platforms);
- if(num_platforms == 0) {
- return;
- }
-
- vector<OpenCLPlatformDevice> usable_devices;
- OpenCLInfo::get_usable_devices(&usable_devices);
- /* Devices are numbered consecutively across platforms. */
- int num_devices = 0;
- set<string> unique_ids;
- foreach(OpenCLPlatformDevice& platform_device, usable_devices) {
- /* Compute unique ID for persistent user preferences. */
- const string& platform_name = platform_device.platform_name;
- const string& device_name = platform_device.device_name;
- string hardware_id = platform_device.hardware_id;
- if(hardware_id == "") {
- hardware_id = string_printf("ID_%d", num_devices);
- }
- string id = string("OPENCL_") + platform_name + "_" + device_name + "_" + hardware_id;
-
- /* Hardware ID might not be unique, add device number in that case. */
- if(unique_ids.find(id) != unique_ids.end()) {
- id += string_printf("_ID_%d", num_devices);
- }
- unique_ids.insert(id);
-
- /* Create DeviceInfo. */
- DeviceInfo info;
- info.type = DEVICE_OPENCL;
- info.description = string_remove_trademark(string(device_name));
- info.num = num_devices;
- /* We don't know if it's used for display, but assume it is. */
- info.display_device = true;
- info.use_split_kernel = true;
- info.has_volume_decoupled = false;
- info.id = id;
-
- /* Check OpenCL extensions */
- info.has_half_images = platform_device.device_extensions.find("cl_khr_fp16") != string::npos;
-
- devices.push_back(info);
- num_devices++;
- }
+ cl_uint num_platforms = 0;
+ device_opencl_get_num_platforms_safe(&num_platforms);
+ if (num_platforms == 0) {
+ return;
+ }
+
+ vector<OpenCLPlatformDevice> usable_devices;
+ OpenCLInfo::get_usable_devices(&usable_devices);
+ /* Devices are numbered consecutively across platforms. */
+ int num_devices = 0;
+ set<string> unique_ids;
+ foreach (OpenCLPlatformDevice &platform_device, usable_devices) {
+ /* Compute unique ID for persistent user preferences. */
+ const string &platform_name = platform_device.platform_name;
+ const string &device_name = platform_device.device_name;
+ string hardware_id = platform_device.hardware_id;
+ if (hardware_id == "") {
+ hardware_id = string_printf("ID_%d", num_devices);
+ }
+ string id = string("OPENCL_") + platform_name + "_" + device_name + "_" + hardware_id;
+
+ /* Hardware ID might not be unique, add device number in that case. */
+ if (unique_ids.find(id) != unique_ids.end()) {
+ id += string_printf("_ID_%d", num_devices);
+ }
+ unique_ids.insert(id);
+
+ /* Create DeviceInfo. */
+ DeviceInfo info;
+ info.type = DEVICE_OPENCL;
+ info.description = string_remove_trademark(string(device_name));
+ info.num = num_devices;
+ /* We don't know if it's used for display, but assume it is. */
+ info.display_device = true;
+ info.use_split_kernel = true;
+ info.has_volume_decoupled = false;
+ info.id = id;
+
+ /* Check OpenCL extensions */
+ info.has_half_images = platform_device.device_extensions.find("cl_khr_fp16") != string::npos;
+
+ devices.push_back(info);
+ num_devices++;
+ }
}
string device_opencl_capabilities()
{
- if(OpenCLInfo::device_type() == 0) {
- return "All OpenCL devices are forced to be OFF";
- }
- string result = "";
- string error_msg = ""; /* Only used by opencl_assert(), but in the future
- * it could also be nicely reported to the console.
- */
- cl_uint num_platforms = 0;
- opencl_assert(device_opencl_get_num_platforms_safe(&num_platforms));
- if(num_platforms == 0) {
- return "No OpenCL platforms found\n";
- }
- result += string_printf("Number of platforms: %u\n", num_platforms);
-
- vector<cl_platform_id> platform_ids;
- platform_ids.resize(num_platforms);
- opencl_assert(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
-
- typedef char cl_string[1024];
-
-#define APPEND_INFO(func, id, name, what, type) \
- do { \
- type data; \
- memset(&data, 0, sizeof(data)); \
- opencl_assert(func(id, what, sizeof(data), &data, NULL)); \
- result += string_printf("%s: %s\n", name, to_string(data).c_str()); \
- } while(false)
-#define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
- do { \
- char data[1024] = "\0"; \
- size_t length = 0; \
- if(func(id, what, sizeof(data), &data, &length) == CL_SUCCESS) { \
- if(length != 0 && data[0] != '\0') { \
- result += string_printf("%s: %s\n", name, data); \
- } \
- } \
- } while(false)
-#define APPEND_PLATFORM_INFO(id, name, what, type) \
- APPEND_INFO(clGetPlatformInfo, id, "\tPlatform " name, what, type)
-#define APPEND_DEVICE_INFO(id, name, what, type) \
- APPEND_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what, type)
-#define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \
- APPEND_STRING_EXTENSION_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what)
-
- vector<cl_device_id> device_ids;
- for(cl_uint platform = 0; platform < num_platforms; ++platform) {
- cl_platform_id platform_id = platform_ids[platform];
-
- result += string_printf("Platform #%u\n", platform);
-
- APPEND_PLATFORM_INFO(platform_id, "Name", CL_PLATFORM_NAME, cl_string);
- APPEND_PLATFORM_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR, cl_string);
- APPEND_PLATFORM_INFO(platform_id, "Version", CL_PLATFORM_VERSION, cl_string);
- APPEND_PLATFORM_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE, cl_string);
- APPEND_PLATFORM_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS, cl_string);
-
- cl_uint num_devices = 0;
- opencl_assert(clGetDeviceIDs(platform_ids[platform],
- CL_DEVICE_TYPE_ALL,
- 0,
- NULL,
- &num_devices));
- result += string_printf("\tNumber of devices: %u\n", num_devices);
-
- device_ids.resize(num_devices);
- opencl_assert(clGetDeviceIDs(platform_ids[platform],
- CL_DEVICE_TYPE_ALL,
- num_devices,
- &device_ids[0],
- NULL));
- for(cl_uint device = 0; device < num_devices; ++device) {
- cl_device_id device_id = device_ids[device];
-
- result += string_printf("\t\tDevice: #%u\n", device);
-
- APPEND_DEVICE_INFO(device_id, "Name", CL_DEVICE_NAME, cl_string);
- APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD);
- APPEND_DEVICE_INFO(device_id, "Vendor", CL_DEVICE_VENDOR, cl_string);
- APPEND_DEVICE_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION, cl_string);
- APPEND_DEVICE_INFO(device_id, "Profile", CL_DEVICE_PROFILE, cl_string);
- APPEND_DEVICE_INFO(device_id, "Version", CL_DEVICE_VERSION, cl_string);
- APPEND_DEVICE_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS, cl_string);
- APPEND_DEVICE_INFO(device_id, "Max clock frequency (MHz)", CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint);
- APPEND_DEVICE_INFO(device_id, "Max compute units", CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint);
- APPEND_DEVICE_INFO(device_id, "Max work group size", CL_DEVICE_MAX_WORK_GROUP_SIZE, size_t);
- }
- }
-
-#undef APPEND_STRING_INFO
-#undef APPEND_PLATFORM_STRING_INFO
-#undef APPEND_DEVICE_STRING_INFO
-
- return result;
+ if (OpenCLInfo::device_type() == 0) {
+ return "All OpenCL devices are forced to be OFF";
+ }
+ string result = "";
+ string error_msg = ""; /* Only used by opencl_assert(), but in the future
+ * it could also be nicely reported to the console.
+ */
+ cl_uint num_platforms = 0;
+ opencl_assert(device_opencl_get_num_platforms_safe(&num_platforms));
+ if (num_platforms == 0) {
+ return "No OpenCL platforms found\n";
+ }
+ result += string_printf("Number of platforms: %u\n", num_platforms);
+
+ vector<cl_platform_id> platform_ids;
+ platform_ids.resize(num_platforms);
+ opencl_assert(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
+
+ typedef char cl_string[1024];
+
+# define APPEND_INFO(func, id, name, what, type) \
+ do { \
+ type data; \
+ memset(&data, 0, sizeof(data)); \
+ opencl_assert(func(id, what, sizeof(data), &data, NULL)); \
+ result += string_printf("%s: %s\n", name, to_string(data).c_str()); \
+ } while (false)
+# define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
+ do { \
+ char data[1024] = "\0"; \
+ size_t length = 0; \
+ if (func(id, what, sizeof(data), &data, &length) == CL_SUCCESS) { \
+ if (length != 0 && data[0] != '\0') { \
+ result += string_printf("%s: %s\n", name, data); \
+ } \
+ } \
+ } while (false)
+# define APPEND_PLATFORM_INFO(id, name, what, type) \
+ APPEND_INFO(clGetPlatformInfo, id, "\tPlatform " name, what, type)
+# define APPEND_DEVICE_INFO(id, name, what, type) \
+ APPEND_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what, type)
+# define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \
+ APPEND_STRING_EXTENSION_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what)
+
+ vector<cl_device_id> device_ids;
+ for (cl_uint platform = 0; platform < num_platforms; ++platform) {
+ cl_platform_id platform_id = platform_ids[platform];
+
+ result += string_printf("Platform #%u\n", platform);
+
+ APPEND_PLATFORM_INFO(platform_id, "Name", CL_PLATFORM_NAME, cl_string);
+ APPEND_PLATFORM_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR, cl_string);
+ APPEND_PLATFORM_INFO(platform_id, "Version", CL_PLATFORM_VERSION, cl_string);
+ APPEND_PLATFORM_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE, cl_string);
+ APPEND_PLATFORM_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS, cl_string);
+
+ cl_uint num_devices = 0;
+ opencl_assert(
+ clGetDeviceIDs(platform_ids[platform], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices));
+ result += string_printf("\tNumber of devices: %u\n", num_devices);
+
+ device_ids.resize(num_devices);
+ opencl_assert(clGetDeviceIDs(
+ platform_ids[platform], CL_DEVICE_TYPE_ALL, num_devices, &device_ids[0], NULL));
+ for (cl_uint device = 0; device < num_devices; ++device) {
+ cl_device_id device_id = device_ids[device];
+
+ result += string_printf("\t\tDevice: #%u\n", device);
+
+ APPEND_DEVICE_INFO(device_id, "Name", CL_DEVICE_NAME, cl_string);
+ APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD);
+ APPEND_DEVICE_INFO(device_id, "Vendor", CL_DEVICE_VENDOR, cl_string);
+ APPEND_DEVICE_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION, cl_string);
+ APPEND_DEVICE_INFO(device_id, "Profile", CL_DEVICE_PROFILE, cl_string);
+ APPEND_DEVICE_INFO(device_id, "Version", CL_DEVICE_VERSION, cl_string);
+ APPEND_DEVICE_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS, cl_string);
+ APPEND_DEVICE_INFO(
+ device_id, "Max clock frequency (MHz)", CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint);
+ APPEND_DEVICE_INFO(device_id, "Max compute units", CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint);
+ APPEND_DEVICE_INFO(device_id, "Max work group size", CL_DEVICE_MAX_WORK_GROUP_SIZE, size_t);
+ }
+ }
+
+# undef APPEND_STRING_INFO
+# undef APPEND_PLATFORM_STRING_INFO
+# undef APPEND_DEVICE_STRING_INFO
+
+ return result;
}
CCL_NAMESPACE_END
-#endif /* WITH_OPENCL */
+#endif /* WITH_OPENCL */
diff --git a/intern/cycles/device/device_split_kernel.cpp b/intern/cycles/device/device_split_kernel.cpp
index ee566e57918..42e597a34d7 100644
--- a/intern/cycles/device/device_split_kernel.cpp
+++ b/intern/cycles/device/device_split_kernel.cpp
@@ -27,299 +27,304 @@ CCL_NAMESPACE_BEGIN
static const double alpha = 0.1; /* alpha for rolling average */
DeviceSplitKernel::DeviceSplitKernel(Device *device)
-: device(device),
- split_data(device, "split_data"),
- ray_state(device, "ray_state", MEM_READ_WRITE),
- queue_index(device, "queue_index"),
- use_queues_flag(device, "use_queues_flag"),
- work_pool_wgs(device, "work_pool_wgs"),
- kernel_data_initialized(false)
+ : device(device),
+ split_data(device, "split_data"),
+ ray_state(device, "ray_state", MEM_READ_WRITE),
+ queue_index(device, "queue_index"),
+ use_queues_flag(device, "use_queues_flag"),
+ work_pool_wgs(device, "work_pool_wgs"),
+ kernel_data_initialized(false)
{
- avg_time_per_sample = 0.0;
-
- kernel_path_init = NULL;
- kernel_scene_intersect = NULL;
- kernel_lamp_emission = NULL;
- kernel_do_volume = NULL;
- kernel_queue_enqueue = NULL;
- kernel_indirect_background = NULL;
- kernel_shader_setup = NULL;
- kernel_shader_sort = NULL;
- kernel_shader_eval = NULL;
- kernel_holdout_emission_blurring_pathtermination_ao = NULL;
- kernel_subsurface_scatter = NULL;
- kernel_direct_lighting = NULL;
- kernel_shadow_blocked_ao = NULL;
- kernel_shadow_blocked_dl = NULL;
- kernel_enqueue_inactive = NULL;
- kernel_next_iteration_setup = NULL;
- kernel_indirect_subsurface = NULL;
- kernel_buffer_update = NULL;
+ avg_time_per_sample = 0.0;
+
+ kernel_path_init = NULL;
+ kernel_scene_intersect = NULL;
+ kernel_lamp_emission = NULL;
+ kernel_do_volume = NULL;
+ kernel_queue_enqueue = NULL;
+ kernel_indirect_background = NULL;
+ kernel_shader_setup = NULL;
+ kernel_shader_sort = NULL;
+ kernel_shader_eval = NULL;
+ kernel_holdout_emission_blurring_pathtermination_ao = NULL;
+ kernel_subsurface_scatter = NULL;
+ kernel_direct_lighting = NULL;
+ kernel_shadow_blocked_ao = NULL;
+ kernel_shadow_blocked_dl = NULL;
+ kernel_enqueue_inactive = NULL;
+ kernel_next_iteration_setup = NULL;
+ kernel_indirect_subsurface = NULL;
+ kernel_buffer_update = NULL;
}
DeviceSplitKernel::~DeviceSplitKernel()
{
- split_data.free();
- ray_state.free();
- use_queues_flag.free();
- queue_index.free();
- work_pool_wgs.free();
-
- delete kernel_path_init;
- delete kernel_scene_intersect;
- delete kernel_lamp_emission;
- delete kernel_do_volume;
- delete kernel_queue_enqueue;
- delete kernel_indirect_background;
- delete kernel_shader_setup;
- delete kernel_shader_sort;
- delete kernel_shader_eval;
- delete kernel_holdout_emission_blurring_pathtermination_ao;
- delete kernel_subsurface_scatter;
- delete kernel_direct_lighting;
- delete kernel_shadow_blocked_ao;
- delete kernel_shadow_blocked_dl;
- delete kernel_enqueue_inactive;
- delete kernel_next_iteration_setup;
- delete kernel_indirect_subsurface;
- delete kernel_buffer_update;
+ split_data.free();
+ ray_state.free();
+ use_queues_flag.free();
+ queue_index.free();
+ work_pool_wgs.free();
+
+ delete kernel_path_init;
+ delete kernel_scene_intersect;
+ delete kernel_lamp_emission;
+ delete kernel_do_volume;
+ delete kernel_queue_enqueue;
+ delete kernel_indirect_background;
+ delete kernel_shader_setup;
+ delete kernel_shader_sort;
+ delete kernel_shader_eval;
+ delete kernel_holdout_emission_blurring_pathtermination_ao;
+ delete kernel_subsurface_scatter;
+ delete kernel_direct_lighting;
+ delete kernel_shadow_blocked_ao;
+ delete kernel_shadow_blocked_dl;
+ delete kernel_enqueue_inactive;
+ delete kernel_next_iteration_setup;
+ delete kernel_indirect_subsurface;
+ delete kernel_buffer_update;
}
-bool DeviceSplitKernel::load_kernels(const DeviceRequestedFeatures& requested_features)
+bool DeviceSplitKernel::load_kernels(const DeviceRequestedFeatures &requested_features)
{
#define LOAD_KERNEL(name) \
- kernel_##name = get_split_kernel_function(#name, requested_features); \
- if(!kernel_##name) { \
- device->set_error(string("Split kernel error: failed to load kernel_") + #name); \
- return false; \
- }
-
- LOAD_KERNEL(path_init);
- LOAD_KERNEL(scene_intersect);
- LOAD_KERNEL(lamp_emission);
- if (requested_features.use_volume) {
- LOAD_KERNEL(do_volume);
- }
- LOAD_KERNEL(queue_enqueue);
- LOAD_KERNEL(indirect_background);
- LOAD_KERNEL(shader_setup);
- LOAD_KERNEL(shader_sort);
- LOAD_KERNEL(shader_eval);
- LOAD_KERNEL(holdout_emission_blurring_pathtermination_ao);
- LOAD_KERNEL(subsurface_scatter);
- LOAD_KERNEL(direct_lighting);
- LOAD_KERNEL(shadow_blocked_ao);
- LOAD_KERNEL(shadow_blocked_dl);
- LOAD_KERNEL(enqueue_inactive);
- LOAD_KERNEL(next_iteration_setup);
- LOAD_KERNEL(indirect_subsurface);
- LOAD_KERNEL(buffer_update);
+ kernel_##name = get_split_kernel_function(#name, requested_features); \
+ if (!kernel_##name) { \
+ device->set_error(string("Split kernel error: failed to load kernel_") + #name); \
+ return false; \
+ }
+
+ LOAD_KERNEL(path_init);
+ LOAD_KERNEL(scene_intersect);
+ LOAD_KERNEL(lamp_emission);
+ if (requested_features.use_volume) {
+ LOAD_KERNEL(do_volume);
+ }
+ LOAD_KERNEL(queue_enqueue);
+ LOAD_KERNEL(indirect_background);
+ LOAD_KERNEL(shader_setup);
+ LOAD_KERNEL(shader_sort);
+ LOAD_KERNEL(shader_eval);
+ LOAD_KERNEL(holdout_emission_blurring_pathtermination_ao);
+ LOAD_KERNEL(subsurface_scatter);
+ LOAD_KERNEL(direct_lighting);
+ LOAD_KERNEL(shadow_blocked_ao);
+ LOAD_KERNEL(shadow_blocked_dl);
+ LOAD_KERNEL(enqueue_inactive);
+ LOAD_KERNEL(next_iteration_setup);
+ LOAD_KERNEL(indirect_subsurface);
+ LOAD_KERNEL(buffer_update);
#undef LOAD_KERNEL
- /* Re-initialiaze kernel-dependent data when kernels change. */
- kernel_data_initialized = false;
+ /* Re-initialiaze kernel-dependent data when kernels change. */
+ kernel_data_initialized = false;
- return true;
+ return true;
}
-size_t DeviceSplitKernel::max_elements_for_max_buffer_size(device_memory& kg, device_memory& data, uint64_t max_buffer_size)
+size_t DeviceSplitKernel::max_elements_for_max_buffer_size(device_memory &kg,
+ device_memory &data,
+ uint64_t max_buffer_size)
{
- uint64_t size_per_element = state_buffer_size(kg, data, 1024) / 1024;
- VLOG(1) << "Split state element size: "
- << string_human_readable_number(size_per_element) << " bytes. ("
- << string_human_readable_size(size_per_element) << ").";
- return max_buffer_size / size_per_element;
+ uint64_t size_per_element = state_buffer_size(kg, data, 1024) / 1024;
+ VLOG(1) << "Split state element size: " << string_human_readable_number(size_per_element)
+ << " bytes. (" << string_human_readable_size(size_per_element) << ").";
+ return max_buffer_size / size_per_element;
}
bool DeviceSplitKernel::path_trace(DeviceTask *task,
- RenderTile& tile,
- device_memory& kgbuffer,
- device_memory& kernel_data)
+ RenderTile &tile,
+ device_memory &kgbuffer,
+ device_memory &kernel_data)
{
- if(device->have_error()) {
- return false;
- }
+ if (device->have_error()) {
+ return false;
+ }
- /* Allocate all required global memory once. */
- if(!kernel_data_initialized) {
- kernel_data_initialized = true;
+ /* Allocate all required global memory once. */
+ if (!kernel_data_initialized) {
+ kernel_data_initialized = true;
- /* Set local size */
- int2 lsize = split_kernel_local_size();
- local_size[0] = lsize[0];
- local_size[1] = lsize[1];
+ /* Set local size */
+ int2 lsize = split_kernel_local_size();
+ local_size[0] = lsize[0];
+ local_size[1] = lsize[1];
- /* Set global size */
- int2 gsize = split_kernel_global_size(kgbuffer, kernel_data, task);
+ /* Set global size */
+ int2 gsize = split_kernel_global_size(kgbuffer, kernel_data, task);
- /* Make sure that set work size is a multiple of local
- * work size dimensions.
- */
- global_size[0] = round_up(gsize[0], local_size[0]);
- global_size[1] = round_up(gsize[1], local_size[1]);
+ /* Make sure that set work size is a multiple of local
+ * work size dimensions.
+ */
+ global_size[0] = round_up(gsize[0], local_size[0]);
+ global_size[1] = round_up(gsize[1], local_size[1]);
- int num_global_elements = global_size[0] * global_size[1];
- assert(num_global_elements % WORK_POOL_SIZE == 0);
+ int num_global_elements = global_size[0] * global_size[1];
+ assert(num_global_elements % WORK_POOL_SIZE == 0);
- /* Calculate max groups */
+ /* Calculate max groups */
- /* Denotes the maximum work groups possible w.r.t. current requested tile size. */
- unsigned int work_pool_size = (device->info.type == DEVICE_CPU) ? WORK_POOL_SIZE_CPU : WORK_POOL_SIZE_GPU;
- unsigned int max_work_groups = num_global_elements / work_pool_size + 1;
+ /* Denotes the maximum work groups possible w.r.t. current requested tile size. */
+ unsigned int work_pool_size = (device->info.type == DEVICE_CPU) ? WORK_POOL_SIZE_CPU :
+ WORK_POOL_SIZE_GPU;
+ unsigned int max_work_groups = num_global_elements / work_pool_size + 1;
- /* Allocate work_pool_wgs memory. */
- work_pool_wgs.alloc_to_device(max_work_groups);
- queue_index.alloc_to_device(NUM_QUEUES);
- use_queues_flag.alloc_to_device(1);
- split_data.alloc_to_device(state_buffer_size(kgbuffer, kernel_data, num_global_elements));
- ray_state.alloc(num_global_elements);
- }
+ /* Allocate work_pool_wgs memory. */
+ work_pool_wgs.alloc_to_device(max_work_groups);
+ queue_index.alloc_to_device(NUM_QUEUES);
+ use_queues_flag.alloc_to_device(1);
+ split_data.alloc_to_device(state_buffer_size(kgbuffer, kernel_data, num_global_elements));
+ ray_state.alloc(num_global_elements);
+ }
- /* Number of elements in the global state buffer */
- int num_global_elements = global_size[0] * global_size[1];
+ /* Number of elements in the global state buffer */
+ int num_global_elements = global_size[0] * global_size[1];
#define ENQUEUE_SPLIT_KERNEL(name, global_size, local_size) \
- if(device->have_error()) { \
- return false; \
- } \
- if(!kernel_##name->enqueue(KernelDimensions(global_size, local_size), kgbuffer, kernel_data)) { \
- return false; \
- }
-
- tile.sample = tile.start_sample;
-
- /* for exponential increase between tile updates */
- int time_multiplier = 1;
-
- while(tile.sample < tile.start_sample + tile.num_samples) {
- /* to keep track of how long it takes to run a number of samples */
- double start_time = time_dt();
-
- /* initial guess to start rolling average */
- const int initial_num_samples = 1;
- /* approx number of samples per second */
- int samples_per_second = (avg_time_per_sample > 0.0) ?
- int(double(time_multiplier) / avg_time_per_sample) + 1 : initial_num_samples;
-
- RenderTile subtile = tile;
- subtile.start_sample = tile.sample;
- subtile.num_samples = min(samples_per_second, tile.start_sample + tile.num_samples - tile.sample);
-
- if(device->have_error()) {
- return false;
- }
-
- /* reset state memory here as global size for data_init
- * kernel might not be large enough to do in kernel
- */
- work_pool_wgs.zero_to_device();
- split_data.zero_to_device();
- ray_state.zero_to_device();
-
- if(!enqueue_split_kernel_data_init(KernelDimensions(global_size, local_size),
- subtile,
- num_global_elements,
- kgbuffer,
- kernel_data,
- split_data,
- ray_state,
- queue_index,
- use_queues_flag,
- work_pool_wgs))
- {
- return false;
- }
-
- ENQUEUE_SPLIT_KERNEL(path_init, global_size, local_size);
-
- bool activeRaysAvailable = true;
- double cancel_time = DBL_MAX;
-
- while(activeRaysAvailable) {
- /* Do path-iteration in host [Enqueue Path-iteration kernels. */
- for(int PathIter = 0; PathIter < 16; PathIter++) {
- ENQUEUE_SPLIT_KERNEL(scene_intersect, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(lamp_emission, global_size, local_size);
- if (kernel_do_volume) {
- ENQUEUE_SPLIT_KERNEL(do_volume, global_size, local_size);
- }
- ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(indirect_background, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(shader_setup, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(shader_sort, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(shader_eval, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(holdout_emission_blurring_pathtermination_ao, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(subsurface_scatter, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(direct_lighting, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(shadow_blocked_ao, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(shadow_blocked_dl, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(enqueue_inactive, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(next_iteration_setup, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(indirect_subsurface, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size);
- ENQUEUE_SPLIT_KERNEL(buffer_update, global_size, local_size);
-
- if(task->get_cancel() && cancel_time == DBL_MAX) {
- /* Wait up to twice as many seconds for current samples to finish
- * to avoid artifacts in render result from ending too soon.
- */
- cancel_time = time_dt() + 2.0 * time_multiplier;
- }
-
- if(time_dt() > cancel_time) {
- return true;
- }
- }
-
- /* Decide if we should exit path-iteration in host. */
- ray_state.copy_from_device(0, global_size[0] * global_size[1], 1);
-
- activeRaysAvailable = false;
-
- for(int rayStateIter = 0; rayStateIter < global_size[0] * global_size[1]; ++rayStateIter) {
- if(!IS_STATE(ray_state.data(), rayStateIter, RAY_INACTIVE)) {
- if(IS_STATE(ray_state.data(), rayStateIter, RAY_INVALID)) {
- /* Something went wrong, abort to avoid looping endlessly. */
- device->set_error("Split kernel error: invalid ray state");
- return false;
- }
-
- /* Not all rays are RAY_INACTIVE. */
- activeRaysAvailable = true;
- break;
- }
- }
-
- if(time_dt() > cancel_time) {
- return true;
- }
- }
-
- double time_per_sample = ((time_dt()-start_time) / subtile.num_samples);
-
- if(avg_time_per_sample == 0.0) {
- /* start rolling average */
- avg_time_per_sample = time_per_sample;
- }
- else {
- avg_time_per_sample = alpha*time_per_sample + (1.0-alpha)*avg_time_per_sample;
- }
+ if (device->have_error()) { \
+ return false; \
+ } \
+ if (!kernel_##name->enqueue( \
+ KernelDimensions(global_size, local_size), kgbuffer, kernel_data)) { \
+ return false; \
+ }
+
+ tile.sample = tile.start_sample;
+
+ /* for exponential increase between tile updates */
+ int time_multiplier = 1;
+
+ while (tile.sample < tile.start_sample + tile.num_samples) {
+ /* to keep track of how long it takes to run a number of samples */
+ double start_time = time_dt();
+
+ /* initial guess to start rolling average */
+ const int initial_num_samples = 1;
+ /* approx number of samples per second */
+ int samples_per_second = (avg_time_per_sample > 0.0) ?
+ int(double(time_multiplier) / avg_time_per_sample) + 1 :
+ initial_num_samples;
+
+ RenderTile subtile = tile;
+ subtile.start_sample = tile.sample;
+ subtile.num_samples = min(samples_per_second,
+ tile.start_sample + tile.num_samples - tile.sample);
+
+ if (device->have_error()) {
+ return false;
+ }
+
+ /* reset state memory here as global size for data_init
+ * kernel might not be large enough to do in kernel
+ */
+ work_pool_wgs.zero_to_device();
+ split_data.zero_to_device();
+ ray_state.zero_to_device();
+
+ if (!enqueue_split_kernel_data_init(KernelDimensions(global_size, local_size),
+ subtile,
+ num_global_elements,
+ kgbuffer,
+ kernel_data,
+ split_data,
+ ray_state,
+ queue_index,
+ use_queues_flag,
+ work_pool_wgs)) {
+ return false;
+ }
+
+ ENQUEUE_SPLIT_KERNEL(path_init, global_size, local_size);
+
+ bool activeRaysAvailable = true;
+ double cancel_time = DBL_MAX;
+
+ while (activeRaysAvailable) {
+ /* Do path-iteration in host [Enqueue Path-iteration kernels. */
+ for (int PathIter = 0; PathIter < 16; PathIter++) {
+ ENQUEUE_SPLIT_KERNEL(scene_intersect, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(lamp_emission, global_size, local_size);
+ if (kernel_do_volume) {
+ ENQUEUE_SPLIT_KERNEL(do_volume, global_size, local_size);
+ }
+ ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(indirect_background, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(shader_setup, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(shader_sort, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(shader_eval, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(
+ holdout_emission_blurring_pathtermination_ao, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(subsurface_scatter, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(direct_lighting, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(shadow_blocked_ao, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(shadow_blocked_dl, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(enqueue_inactive, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(next_iteration_setup, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(indirect_subsurface, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size);
+ ENQUEUE_SPLIT_KERNEL(buffer_update, global_size, local_size);
+
+ if (task->get_cancel() && cancel_time == DBL_MAX) {
+ /* Wait up to twice as many seconds for current samples to finish
+ * to avoid artifacts in render result from ending too soon.
+ */
+ cancel_time = time_dt() + 2.0 * time_multiplier;
+ }
+
+ if (time_dt() > cancel_time) {
+ return true;
+ }
+ }
+
+ /* Decide if we should exit path-iteration in host. */
+ ray_state.copy_from_device(0, global_size[0] * global_size[1], 1);
+
+ activeRaysAvailable = false;
+
+ for (int rayStateIter = 0; rayStateIter < global_size[0] * global_size[1]; ++rayStateIter) {
+ if (!IS_STATE(ray_state.data(), rayStateIter, RAY_INACTIVE)) {
+ if (IS_STATE(ray_state.data(), rayStateIter, RAY_INVALID)) {
+ /* Something went wrong, abort to avoid looping endlessly. */
+ device->set_error("Split kernel error: invalid ray state");
+ return false;
+ }
+
+ /* Not all rays are RAY_INACTIVE. */
+ activeRaysAvailable = true;
+ break;
+ }
+ }
+
+ if (time_dt() > cancel_time) {
+ return true;
+ }
+ }
+
+ double time_per_sample = ((time_dt() - start_time) / subtile.num_samples);
+
+ if (avg_time_per_sample == 0.0) {
+ /* start rolling average */
+ avg_time_per_sample = time_per_sample;
+ }
+ else {
+ avg_time_per_sample = alpha * time_per_sample + (1.0 - alpha) * avg_time_per_sample;
+ }
#undef ENQUEUE_SPLIT_KERNEL
- tile.sample += subtile.num_samples;
- task->update_progress(&tile, tile.w*tile.h*subtile.num_samples);
+ tile.sample += subtile.num_samples;
+ task->update_progress(&tile, tile.w * tile.h * subtile.num_samples);
- time_multiplier = min(time_multiplier << 1, 10);
+ time_multiplier = min(time_multiplier << 1, 10);
- if(task->get_cancel()) {
- return true;
- }
- }
+ if (task->get_cancel()) {
+ return true;
+ }
+ }
- return true;
+ return true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_split_kernel.h b/intern/cycles/device/device_split_kernel.h
index 622733b843f..c9fb2ac844f 100644
--- a/intern/cycles/device/device_split_kernel.h
+++ b/intern/cycles/device/device_split_kernel.h
@@ -27,106 +27,115 @@ CCL_NAMESPACE_BEGIN
* Since some bytes may be needed for aligning chunks of memory;
* This is the amount of memory that we dedicate for that purpose.
*/
-#define DATA_ALLOCATION_MEM_FACTOR 5000000 //5MB
+#define DATA_ALLOCATION_MEM_FACTOR 5000000 //5MB
/* Types used for split kernel */
class KernelDimensions {
-public:
- size_t global_size[2];
- size_t local_size[2];
-
- KernelDimensions(size_t global_size_[2], size_t local_size_[2])
- {
- memcpy(global_size, global_size_, sizeof(global_size));
- memcpy(local_size, local_size_, sizeof(local_size));
- }
+ public:
+ size_t global_size[2];
+ size_t local_size[2];
+
+ KernelDimensions(size_t global_size_[2], size_t local_size_[2])
+ {
+ memcpy(global_size, global_size_, sizeof(global_size));
+ memcpy(local_size, local_size_, sizeof(local_size));
+ }
};
class SplitKernelFunction {
-public:
- virtual ~SplitKernelFunction() {}
+ public:
+ virtual ~SplitKernelFunction()
+ {
+ }
- /* enqueue the kernel, returns false if there is an error */
- virtual bool enqueue(const KernelDimensions& dim, device_memory& kg, device_memory& data) = 0;
+ /* enqueue the kernel, returns false if there is an error */
+ virtual bool enqueue(const KernelDimensions &dim, device_memory &kg, device_memory &data) = 0;
};
class DeviceSplitKernel {
-private:
- Device *device;
-
- SplitKernelFunction *kernel_path_init;
- SplitKernelFunction *kernel_scene_intersect;
- SplitKernelFunction *kernel_lamp_emission;
- SplitKernelFunction *kernel_do_volume;
- SplitKernelFunction *kernel_queue_enqueue;
- SplitKernelFunction *kernel_indirect_background;
- SplitKernelFunction *kernel_shader_setup;
- SplitKernelFunction *kernel_shader_sort;
- SplitKernelFunction *kernel_shader_eval;
- SplitKernelFunction *kernel_holdout_emission_blurring_pathtermination_ao;
- SplitKernelFunction *kernel_subsurface_scatter;
- SplitKernelFunction *kernel_direct_lighting;
- SplitKernelFunction *kernel_shadow_blocked_ao;
- SplitKernelFunction *kernel_shadow_blocked_dl;
- SplitKernelFunction *kernel_enqueue_inactive;
- SplitKernelFunction *kernel_next_iteration_setup;
- SplitKernelFunction *kernel_indirect_subsurface;
- SplitKernelFunction *kernel_buffer_update;
-
- /* Global memory variables [porting]; These memory is used for
- * co-operation between different kernels; Data written by one
- * kernel will be available to another kernel via this global
- * memory.
- */
- device_only_memory<uchar> split_data;
- device_vector<uchar> ray_state;
- device_only_memory<int> queue_index; /* Array of size num_queues that tracks the size of each queue. */
-
- /* Flag to make sceneintersect and lampemission kernel use queues. */
- device_only_memory<char> use_queues_flag;
-
- /* Approximate time it takes to complete one sample */
- double avg_time_per_sample;
-
- /* Work pool with respect to each work group. */
- device_only_memory<unsigned int> work_pool_wgs;
-
- /* Cached kernel-dependent data, initialized once. */
- bool kernel_data_initialized;
- size_t local_size[2];
- size_t global_size[2];
-
-public:
- explicit DeviceSplitKernel(Device* device);
- virtual ~DeviceSplitKernel();
-
- bool load_kernels(const DeviceRequestedFeatures& requested_features);
- bool path_trace(DeviceTask *task,
- RenderTile& rtile,
- device_memory& kgbuffer,
- device_memory& kernel_data);
-
- virtual uint64_t state_buffer_size(device_memory& kg, device_memory& data, size_t num_threads) = 0;
- size_t max_elements_for_max_buffer_size(device_memory& kg, device_memory& data, uint64_t max_buffer_size);
-
- virtual bool enqueue_split_kernel_data_init(const KernelDimensions& dim,
- RenderTile& rtile,
- int num_global_elements,
- device_memory& kernel_globals,
- device_memory& kernel_data_,
- device_memory& split_data,
- device_memory& ray_state,
- device_memory& queue_index,
- device_memory& use_queues_flag,
- device_memory& work_pool_wgs) = 0;
-
- virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name,
- const DeviceRequestedFeatures&) = 0;
- virtual int2 split_kernel_local_size() = 0;
- virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask *task) = 0;
+ private:
+ Device *device;
+
+ SplitKernelFunction *kernel_path_init;
+ SplitKernelFunction *kernel_scene_intersect;
+ SplitKernelFunction *kernel_lamp_emission;
+ SplitKernelFunction *kernel_do_volume;
+ SplitKernelFunction *kernel_queue_enqueue;
+ SplitKernelFunction *kernel_indirect_background;
+ SplitKernelFunction *kernel_shader_setup;
+ SplitKernelFunction *kernel_shader_sort;
+ SplitKernelFunction *kernel_shader_eval;
+ SplitKernelFunction *kernel_holdout_emission_blurring_pathtermination_ao;
+ SplitKernelFunction *kernel_subsurface_scatter;
+ SplitKernelFunction *kernel_direct_lighting;
+ SplitKernelFunction *kernel_shadow_blocked_ao;
+ SplitKernelFunction *kernel_shadow_blocked_dl;
+ SplitKernelFunction *kernel_enqueue_inactive;
+ SplitKernelFunction *kernel_next_iteration_setup;
+ SplitKernelFunction *kernel_indirect_subsurface;
+ SplitKernelFunction *kernel_buffer_update;
+
+ /* Global memory variables [porting]; These memory is used for
+ * co-operation between different kernels; Data written by one
+ * kernel will be available to another kernel via this global
+ * memory.
+ */
+ device_only_memory<uchar> split_data;
+ device_vector<uchar> ray_state;
+ device_only_memory<int>
+ queue_index; /* Array of size num_queues that tracks the size of each queue. */
+
+ /* Flag to make sceneintersect and lampemission kernel use queues. */
+ device_only_memory<char> use_queues_flag;
+
+ /* Approximate time it takes to complete one sample */
+ double avg_time_per_sample;
+
+ /* Work pool with respect to each work group. */
+ device_only_memory<unsigned int> work_pool_wgs;
+
+ /* Cached kernel-dependent data, initialized once. */
+ bool kernel_data_initialized;
+ size_t local_size[2];
+ size_t global_size[2];
+
+ public:
+ explicit DeviceSplitKernel(Device *device);
+ virtual ~DeviceSplitKernel();
+
+ bool load_kernels(const DeviceRequestedFeatures &requested_features);
+ bool path_trace(DeviceTask *task,
+ RenderTile &rtile,
+ device_memory &kgbuffer,
+ device_memory &kernel_data);
+
+ virtual uint64_t state_buffer_size(device_memory &kg,
+ device_memory &data,
+ size_t num_threads) = 0;
+ size_t max_elements_for_max_buffer_size(device_memory &kg,
+ device_memory &data,
+ uint64_t max_buffer_size);
+
+ virtual bool enqueue_split_kernel_data_init(const KernelDimensions &dim,
+ RenderTile &rtile,
+ int num_global_elements,
+ device_memory &kernel_globals,
+ device_memory &kernel_data_,
+ device_memory &split_data,
+ device_memory &ray_state,
+ device_memory &queue_index,
+ device_memory &use_queues_flag,
+ device_memory &work_pool_wgs) = 0;
+
+ virtual SplitKernelFunction *get_split_kernel_function(const string &kernel_name,
+ const DeviceRequestedFeatures &) = 0;
+ virtual int2 split_kernel_local_size() = 0;
+ virtual int2 split_kernel_global_size(device_memory &kg,
+ device_memory &data,
+ DeviceTask *task) = 0;
};
CCL_NAMESPACE_END
-#endif /* __DEVICE_SPLIT_KERNEL_H__ */
+#endif /* __DEVICE_SPLIT_KERNEL_H__ */
diff --git a/intern/cycles/device/device_task.cpp b/intern/cycles/device/device_task.cpp
index 8310863886c..376ad06a734 100644
--- a/intern/cycles/device/device_task.cpp
+++ b/intern/cycles/device/device_task.cpp
@@ -29,100 +29,111 @@ CCL_NAMESPACE_BEGIN
/* Device Task */
DeviceTask::DeviceTask(Type type_)
-: type(type_), x(0), y(0), w(0), h(0), rgba_byte(0), rgba_half(0), buffer(0),
- sample(0), num_samples(1),
- shader_input(0), shader_output(0),
- shader_eval_type(0), shader_filter(0), shader_x(0), shader_w(0)
+ : type(type_),
+ x(0),
+ y(0),
+ w(0),
+ h(0),
+ rgba_byte(0),
+ rgba_half(0),
+ buffer(0),
+ sample(0),
+ num_samples(1),
+ shader_input(0),
+ shader_output(0),
+ shader_eval_type(0),
+ shader_filter(0),
+ shader_x(0),
+ shader_w(0)
{
- last_update_time = time_dt();
+ last_update_time = time_dt();
}
int DeviceTask::get_subtask_count(int num, int max_size)
{
- if(max_size != 0) {
- int max_size_num;
-
- if(type == SHADER) {
- max_size_num = (shader_w + max_size - 1)/max_size;
- }
- else {
- max_size = max(1, max_size/w);
- max_size_num = (h + max_size - 1)/max_size;
- }
-
- num = max(max_size_num, num);
- }
-
- if(type == SHADER) {
- num = min(shader_w, num);
- }
- else if(type == RENDER) {
- }
- else {
- num = min(h, num);
- }
-
- return num;
+ if (max_size != 0) {
+ int max_size_num;
+
+ if (type == SHADER) {
+ max_size_num = (shader_w + max_size - 1) / max_size;
+ }
+ else {
+ max_size = max(1, max_size / w);
+ max_size_num = (h + max_size - 1) / max_size;
+ }
+
+ num = max(max_size_num, num);
+ }
+
+ if (type == SHADER) {
+ num = min(shader_w, num);
+ }
+ else if (type == RENDER) {
+ }
+ else {
+ num = min(h, num);
+ }
+
+ return num;
}
-void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
+void DeviceTask::split(list<DeviceTask> &tasks, int num, int max_size)
{
- num = get_subtask_count(num, max_size);
-
- if(type == SHADER) {
- for(int i = 0; i < num; i++) {
- int tx = shader_x + (shader_w/num)*i;
- int tw = (i == num-1)? shader_w - i*(shader_w/num): shader_w/num;
-
- DeviceTask task = *this;
-
- task.shader_x = tx;
- task.shader_w = tw;
-
- tasks.push_back(task);
- }
- }
- else if(type == RENDER) {
- for(int i = 0; i < num; i++)
- tasks.push_back(*this);
- }
- else {
- for(int i = 0; i < num; i++) {
- int ty = y + (h/num)*i;
- int th = (i == num-1)? h - i*(h/num): h/num;
-
- DeviceTask task = *this;
-
- task.y = ty;
- task.h = th;
-
- tasks.push_back(task);
- }
- }
+ num = get_subtask_count(num, max_size);
+
+ if (type == SHADER) {
+ for (int i = 0; i < num; i++) {
+ int tx = shader_x + (shader_w / num) * i;
+ int tw = (i == num - 1) ? shader_w - i * (shader_w / num) : shader_w / num;
+
+ DeviceTask task = *this;
+
+ task.shader_x = tx;
+ task.shader_w = tw;
+
+ tasks.push_back(task);
+ }
+ }
+ else if (type == RENDER) {
+ for (int i = 0; i < num; i++)
+ tasks.push_back(*this);
+ }
+ else {
+ for (int i = 0; i < num; i++) {
+ int ty = y + (h / num) * i;
+ int th = (i == num - 1) ? h - i * (h / num) : h / num;
+
+ DeviceTask task = *this;
+
+ task.y = ty;
+ task.h = th;
+
+ tasks.push_back(task);
+ }
+ }
}
void DeviceTask::update_progress(RenderTile *rtile, int pixel_samples)
{
- if((type != RENDER) &&
- (type != SHADER))
- return;
-
- if(update_progress_sample) {
- if(pixel_samples == -1) {
- pixel_samples = shader_w;
- }
- update_progress_sample(pixel_samples, rtile? rtile->sample : 0);
- }
-
- if(update_tile_sample) {
- double current_time = time_dt();
-
- if(current_time - last_update_time >= 1.0) {
- update_tile_sample(*rtile);
-
- last_update_time = current_time;
- }
- }
+ if ((type != RENDER) && (type != SHADER))
+ return;
+
+ if (update_progress_sample) {
+ if (pixel_samples == -1) {
+ pixel_samples = shader_w;
+ }
+ update_progress_sample(pixel_samples, rtile ? rtile->sample : 0);
+ }
+
+ if (update_tile_sample) {
+ double current_time = time_dt();
+
+ if (current_time - last_update_time >= 1.0) {
+ update_tile_sample(*rtile);
+
+ last_update_time = current_time;
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h
index f1fd4246868..5cc2e5e25db 100644
--- a/intern/cycles/device/device_task.h
+++ b/intern/cycles/device/device_task.h
@@ -33,87 +33,88 @@ class RenderTile;
class Tile;
class DenoiseParams {
-public:
- /* Pixel radius for neighbouring pixels to take into account. */
- int radius;
- /* Controls neighbor pixel weighting for the denoising filter. */
- float strength;
- /* Preserve more or less detail based on feature passes. */
- float feature_strength;
- /* When removing pixels that don't carry information, use a relative threshold instead of an absolute one. */
- bool relative_pca;
- /* How many frames before and after the current center frame are included. */
- int neighbor_frames;
- /* Clamp the input to the range of +-1e8. Should be enough for any legitimate data. */
- bool clamp_input;
-
- DenoiseParams()
- {
- radius = 8;
- strength = 0.5f;
- feature_strength = 0.5f;
- relative_pca = false;
- neighbor_frames = 2;
- clamp_input = true;
- }
+ public:
+ /* Pixel radius for neighbouring pixels to take into account. */
+ int radius;
+ /* Controls neighbor pixel weighting for the denoising filter. */
+ float strength;
+ /* Preserve more or less detail based on feature passes. */
+ float feature_strength;
+ /* When removing pixels that don't carry information, use a relative threshold instead of an absolute one. */
+ bool relative_pca;
+ /* How many frames before and after the current center frame are included. */
+ int neighbor_frames;
+ /* Clamp the input to the range of +-1e8. Should be enough for any legitimate data. */
+ bool clamp_input;
+
+ DenoiseParams()
+ {
+ radius = 8;
+ strength = 0.5f;
+ feature_strength = 0.5f;
+ relative_pca = false;
+ neighbor_frames = 2;
+ clamp_input = true;
+ }
};
class DeviceTask : public Task {
-public:
- typedef enum { RENDER, FILM_CONVERT, SHADER } Type;
- Type type;
-
- int x, y, w, h;
- device_ptr rgba_byte;
- device_ptr rgba_half;
- device_ptr buffer;
- int sample;
- int num_samples;
- int offset, stride;
-
- device_ptr shader_input;
- device_ptr shader_output;
- int shader_eval_type;
- int shader_filter;
- int shader_x, shader_w;
-
- int passes_size;
-
- explicit DeviceTask(Type type = RENDER);
-
- int get_subtask_count(int num, int max_size = 0);
- void split(list<DeviceTask>& tasks, int num, int max_size = 0);
-
- void update_progress(RenderTile *rtile, int pixel_samples = -1);
-
- function<bool(Device *device, RenderTile&)> acquire_tile;
- function<void(long, int)> update_progress_sample;
- function<void(RenderTile&)> update_tile_sample;
- function<void(RenderTile&)> release_tile;
- function<bool()> get_cancel;
- function<void(RenderTile*, Device*)> map_neighbor_tiles;
- function<void(RenderTile*, Device*)> unmap_neighbor_tiles;
-
- DenoiseParams denoising;
- bool denoising_from_render;
- vector<int> denoising_frames;
-
- bool denoising_do_filter;
- bool denoising_write_passes;
-
- int pass_stride;
- int frame_stride;
- int target_pass_stride;
- int pass_denoising_data;
- int pass_denoising_clean;
-
- bool need_finish_queue;
- bool integrator_branched;
- int2 requested_tile_size;
-protected:
- double last_update_time;
+ public:
+ typedef enum { RENDER, FILM_CONVERT, SHADER } Type;
+ Type type;
+
+ int x, y, w, h;
+ device_ptr rgba_byte;
+ device_ptr rgba_half;
+ device_ptr buffer;
+ int sample;
+ int num_samples;
+ int offset, stride;
+
+ device_ptr shader_input;
+ device_ptr shader_output;
+ int shader_eval_type;
+ int shader_filter;
+ int shader_x, shader_w;
+
+ int passes_size;
+
+ explicit DeviceTask(Type type = RENDER);
+
+ int get_subtask_count(int num, int max_size = 0);
+ void split(list<DeviceTask> &tasks, int num, int max_size = 0);
+
+ void update_progress(RenderTile *rtile, int pixel_samples = -1);
+
+ function<bool(Device *device, RenderTile &)> acquire_tile;
+ function<void(long, int)> update_progress_sample;
+ function<void(RenderTile &)> update_tile_sample;
+ function<void(RenderTile &)> release_tile;
+ function<bool()> get_cancel;
+ function<void(RenderTile *, Device *)> map_neighbor_tiles;
+ function<void(RenderTile *, Device *)> unmap_neighbor_tiles;
+
+ DenoiseParams denoising;
+ bool denoising_from_render;
+ vector<int> denoising_frames;
+
+ bool denoising_do_filter;
+ bool denoising_write_passes;
+
+ int pass_stride;
+ int frame_stride;
+ int target_pass_stride;
+ int pass_denoising_data;
+ int pass_denoising_clean;
+
+ bool need_finish_queue;
+ bool integrator_branched;
+ int2 requested_tile_size;
+
+ protected:
+ double last_update_time;
};
CCL_NAMESPACE_END
-#endif /* __DEVICE_TASK_H__ */
+#endif /* __DEVICE_TASK_H__ */
diff --git a/intern/cycles/device/opencl/memory_manager.cpp b/intern/cycles/device/opencl/memory_manager.cpp
index 9cb105982aa..f85aadce1c2 100644
--- a/intern/cycles/device/opencl/memory_manager.cpp
+++ b/intern/cycles/device/opencl/memory_manager.cpp
@@ -16,241 +16,246 @@
#ifdef WITH_OPENCL
-#include "util/util_foreach.h"
+# include "util/util_foreach.h"
-#include "device/opencl/opencl.h"
-#include "device/opencl/memory_manager.h"
+# include "device/opencl/opencl.h"
+# include "device/opencl/memory_manager.h"
CCL_NAMESPACE_BEGIN
-void MemoryManager::DeviceBuffer::add_allocation(Allocation& allocation)
+void MemoryManager::DeviceBuffer::add_allocation(Allocation &allocation)
{
- allocations.push_back(&allocation);
+ allocations.push_back(&allocation);
}
void MemoryManager::DeviceBuffer::update_device_memory(OpenCLDevice *device)
{
- bool need_realloc = false;
-
- /* Calculate total size and remove any freed. */
- size_t total_size = 0;
-
- for(int i = allocations.size()-1; i >= 0; i--) {
- Allocation* allocation = allocations[i];
-
- /* Remove allocations that have been freed. */
- if(!allocation->mem || allocation->mem->memory_size() == 0) {
- allocation->device_buffer = NULL;
- allocation->size = 0;
-
- allocations.erase(allocations.begin()+i);
-
- need_realloc = true;
-
- continue;
- }
-
- /* Get actual size for allocation. */
- size_t alloc_size = align_up(allocation->mem->memory_size(), 16);
-
- if(allocation->size != alloc_size) {
- /* Allocation is either new or resized. */
- allocation->size = alloc_size;
- allocation->needs_copy_to_device = true;
-
- need_realloc = true;
- }
-
- total_size += alloc_size;
- }
-
- if(need_realloc) {
- cl_ulong max_buffer_size;
- clGetDeviceInfo(device->cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_buffer_size, NULL);
-
- if(total_size > max_buffer_size) {
- device->set_error("Scene too complex to fit in available memory.");
- return;
- }
-
- device_only_memory<uchar> *new_buffer =
- new device_only_memory<uchar>(device, "memory manager buffer");
-
- new_buffer->alloc_to_device(total_size);
-
- size_t offset = 0;
-
- foreach(Allocation* allocation, allocations) {
- if(allocation->needs_copy_to_device) {
- /* Copy from host to device. */
- opencl_device_assert(device, clEnqueueWriteBuffer(device->cqCommandQueue,
- CL_MEM_PTR(new_buffer->device_pointer),
- CL_FALSE,
- offset,
- allocation->mem->memory_size(),
- allocation->mem->host_pointer,
- 0, NULL, NULL
- ));
-
- allocation->needs_copy_to_device = false;
- }
- else {
- /* Fast copy from memory already on device. */
- opencl_device_assert(device, clEnqueueCopyBuffer(device->cqCommandQueue,
- CL_MEM_PTR(buffer->device_pointer),
- CL_MEM_PTR(new_buffer->device_pointer),
- allocation->desc.offset,
- offset,
- allocation->mem->memory_size(),
- 0, NULL, NULL
- ));
- }
-
- allocation->desc.offset = offset;
- offset += allocation->size;
- }
-
- delete buffer;
-
- buffer = new_buffer;
- }
- else {
- assert(total_size == buffer->data_size);
-
- size_t offset = 0;
-
- foreach(Allocation* allocation, allocations) {
- if(allocation->needs_copy_to_device) {
- /* Copy from host to device. */
- opencl_device_assert(device, clEnqueueWriteBuffer(device->cqCommandQueue,
- CL_MEM_PTR(buffer->device_pointer),
- CL_FALSE,
- offset,
- allocation->mem->memory_size(),
- allocation->mem->host_pointer,
- 0, NULL, NULL
- ));
-
- allocation->needs_copy_to_device = false;
- }
-
- offset += allocation->size;
- }
- }
-
- /* Not really necessary, but seems to improve responsiveness for some reason. */
- clFinish(device->cqCommandQueue);
+ bool need_realloc = false;
+
+ /* Calculate total size and remove any freed. */
+ size_t total_size = 0;
+
+ for (int i = allocations.size() - 1; i >= 0; i--) {
+ Allocation *allocation = allocations[i];
+
+ /* Remove allocations that have been freed. */
+ if (!allocation->mem || allocation->mem->memory_size() == 0) {
+ allocation->device_buffer = NULL;
+ allocation->size = 0;
+
+ allocations.erase(allocations.begin() + i);
+
+ need_realloc = true;
+
+ continue;
+ }
+
+ /* Get actual size for allocation. */
+ size_t alloc_size = align_up(allocation->mem->memory_size(), 16);
+
+ if (allocation->size != alloc_size) {
+ /* Allocation is either new or resized. */
+ allocation->size = alloc_size;
+ allocation->needs_copy_to_device = true;
+
+ need_realloc = true;
+ }
+
+ total_size += alloc_size;
+ }
+
+ if (need_realloc) {
+ cl_ulong max_buffer_size;
+ clGetDeviceInfo(
+ device->cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_buffer_size, NULL);
+
+ if (total_size > max_buffer_size) {
+ device->set_error("Scene too complex to fit in available memory.");
+ return;
+ }
+
+ device_only_memory<uchar> *new_buffer = new device_only_memory<uchar>(device,
+ "memory manager buffer");
+
+ new_buffer->alloc_to_device(total_size);
+
+ size_t offset = 0;
+
+ foreach (Allocation *allocation, allocations) {
+ if (allocation->needs_copy_to_device) {
+ /* Copy from host to device. */
+ opencl_device_assert(device,
+ clEnqueueWriteBuffer(device->cqCommandQueue,
+ CL_MEM_PTR(new_buffer->device_pointer),
+ CL_FALSE,
+ offset,
+ allocation->mem->memory_size(),
+ allocation->mem->host_pointer,
+ 0,
+ NULL,
+ NULL));
+
+ allocation->needs_copy_to_device = false;
+ }
+ else {
+ /* Fast copy from memory already on device. */
+ opencl_device_assert(device,
+ clEnqueueCopyBuffer(device->cqCommandQueue,
+ CL_MEM_PTR(buffer->device_pointer),
+ CL_MEM_PTR(new_buffer->device_pointer),
+ allocation->desc.offset,
+ offset,
+ allocation->mem->memory_size(),
+ 0,
+ NULL,
+ NULL));
+ }
+
+ allocation->desc.offset = offset;
+ offset += allocation->size;
+ }
+
+ delete buffer;
+
+ buffer = new_buffer;
+ }
+ else {
+ assert(total_size == buffer->data_size);
+
+ size_t offset = 0;
+
+ foreach (Allocation *allocation, allocations) {
+ if (allocation->needs_copy_to_device) {
+ /* Copy from host to device. */
+ opencl_device_assert(device,
+ clEnqueueWriteBuffer(device->cqCommandQueue,
+ CL_MEM_PTR(buffer->device_pointer),
+ CL_FALSE,
+ offset,
+ allocation->mem->memory_size(),
+ allocation->mem->host_pointer,
+ 0,
+ NULL,
+ NULL));
+
+ allocation->needs_copy_to_device = false;
+ }
+
+ offset += allocation->size;
+ }
+ }
+
+ /* Not really necessary, but seems to improve responsiveness for some reason. */
+ clFinish(device->cqCommandQueue);
}
void MemoryManager::DeviceBuffer::free(OpenCLDevice *)
{
- buffer->free();
+ buffer->free();
}
-MemoryManager::DeviceBuffer* MemoryManager::smallest_device_buffer()
+MemoryManager::DeviceBuffer *MemoryManager::smallest_device_buffer()
{
- DeviceBuffer* smallest = device_buffers;
+ DeviceBuffer *smallest = device_buffers;
- foreach(DeviceBuffer& device_buffer, device_buffers) {
- if(device_buffer.size < smallest->size) {
- smallest = &device_buffer;
- }
- }
+ foreach (DeviceBuffer &device_buffer, device_buffers) {
+ if (device_buffer.size < smallest->size) {
+ smallest = &device_buffer;
+ }
+ }
- return smallest;
+ return smallest;
}
-MemoryManager::MemoryManager(OpenCLDevice *device)
-: device(device), need_update(false)
+MemoryManager::MemoryManager(OpenCLDevice *device) : device(device), need_update(false)
{
- foreach(DeviceBuffer& device_buffer, device_buffers) {
- device_buffer.buffer =
- new device_only_memory<uchar>(device, "memory manager buffer");
- }
+ foreach (DeviceBuffer &device_buffer, device_buffers) {
+ device_buffer.buffer = new device_only_memory<uchar>(device, "memory manager buffer");
+ }
}
void MemoryManager::free()
{
- foreach(DeviceBuffer& device_buffer, device_buffers) {
- device_buffer.free(device);
- }
+ foreach (DeviceBuffer &device_buffer, device_buffers) {
+ device_buffer.free(device);
+ }
}
-void MemoryManager::alloc(const char *name, device_memory& mem)
+void MemoryManager::alloc(const char *name, device_memory &mem)
{
- Allocation& allocation = allocations[name];
+ Allocation &allocation = allocations[name];
- allocation.mem = &mem;
- allocation.needs_copy_to_device = true;
+ allocation.mem = &mem;
+ allocation.needs_copy_to_device = true;
- if(!allocation.device_buffer) {
- DeviceBuffer* device_buffer = smallest_device_buffer();
- allocation.device_buffer = device_buffer;
+ if (!allocation.device_buffer) {
+ DeviceBuffer *device_buffer = smallest_device_buffer();
+ allocation.device_buffer = device_buffer;
- allocation.desc.device_buffer = device_buffer - device_buffers;
+ allocation.desc.device_buffer = device_buffer - device_buffers;
- device_buffer->add_allocation(allocation);
+ device_buffer->add_allocation(allocation);
- device_buffer->size += mem.memory_size();
- }
+ device_buffer->size += mem.memory_size();
+ }
- need_update = true;
+ need_update = true;
}
-bool MemoryManager::free(device_memory& mem)
+bool MemoryManager::free(device_memory &mem)
{
- foreach(AllocationsMap::value_type& value, allocations) {
- Allocation& allocation = value.second;
- if(allocation.mem == &mem) {
+ foreach (AllocationsMap::value_type &value, allocations) {
+ Allocation &allocation = value.second;
+ if (allocation.mem == &mem) {
- allocation.device_buffer->size -= mem.memory_size();
+ allocation.device_buffer->size -= mem.memory_size();
- allocation.mem = NULL;
- allocation.needs_copy_to_device = false;
+ allocation.mem = NULL;
+ allocation.needs_copy_to_device = false;
- need_update = true;
- return true;
- }
- }
+ need_update = true;
+ return true;
+ }
+ }
- return false;
+ return false;
}
MemoryManager::BufferDescriptor MemoryManager::get_descriptor(string name)
{
- update_device_memory();
+ update_device_memory();
- Allocation& allocation = allocations[name];
- return allocation.desc;
+ Allocation &allocation = allocations[name];
+ return allocation.desc;
}
void MemoryManager::update_device_memory()
{
- if(!need_update) {
- return;
- }
+ if (!need_update) {
+ return;
+ }
- need_update = false;
+ need_update = false;
- foreach(DeviceBuffer& device_buffer, device_buffers) {
- device_buffer.update_device_memory(device);
- }
+ foreach (DeviceBuffer &device_buffer, device_buffers) {
+ device_buffer.update_device_memory(device);
+ }
}
void MemoryManager::set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg)
{
- update_device_memory();
-
- foreach(DeviceBuffer& device_buffer, device_buffers) {
- if(device_buffer.buffer->device_pointer) {
- device->kernel_set_args(kernel, (*narg)++, *device_buffer.buffer);
- }
- else {
- device->kernel_set_args(kernel, (*narg)++, device->null_mem);
- }
- }
+ update_device_memory();
+
+ foreach (DeviceBuffer &device_buffer, device_buffers) {
+ if (device_buffer.buffer->device_pointer) {
+ device->kernel_set_args(kernel, (*narg)++, *device_buffer.buffer);
+ }
+ else {
+ device->kernel_set_args(kernel, (*narg)++, device->null_mem);
+ }
+ }
}
CCL_NAMESPACE_END
-#endif /* WITH_OPENCL */
+#endif /* WITH_OPENCL */
diff --git a/intern/cycles/device/opencl/memory_manager.h b/intern/cycles/device/opencl/memory_manager.h
index 8fcc4440369..2fbc97a0756 100644
--- a/intern/cycles/device/opencl/memory_manager.h
+++ b/intern/cycles/device/opencl/memory_manager.h
@@ -29,78 +29,77 @@ CCL_NAMESPACE_BEGIN
class OpenCLDevice;
class MemoryManager {
-public:
- static const int NUM_DEVICE_BUFFERS = 8;
+ public:
+ static const int NUM_DEVICE_BUFFERS = 8;
- struct BufferDescriptor {
- uint device_buffer;
- cl_ulong offset;
- };
+ struct BufferDescriptor {
+ uint device_buffer;
+ cl_ulong offset;
+ };
-private:
- struct DeviceBuffer;
+ private:
+ struct DeviceBuffer;
- struct Allocation {
- device_memory *mem;
+ struct Allocation {
+ device_memory *mem;
- DeviceBuffer *device_buffer;
- size_t size; /* Size of actual allocation, may be larger than requested. */
+ DeviceBuffer *device_buffer;
+ size_t size; /* Size of actual allocation, may be larger than requested. */
- BufferDescriptor desc;
+ BufferDescriptor desc;
- bool needs_copy_to_device;
+ bool needs_copy_to_device;
- Allocation() : mem(NULL), device_buffer(NULL), size(0), needs_copy_to_device(false)
- {
- }
- };
+ Allocation() : mem(NULL), device_buffer(NULL), size(0), needs_copy_to_device(false)
+ {
+ }
+ };
- struct DeviceBuffer {
- device_only_memory<uchar> *buffer;
- vector<Allocation*> allocations;
- size_t size; /* Size of all allocations. */
+ struct DeviceBuffer {
+ device_only_memory<uchar> *buffer;
+ vector<Allocation *> allocations;
+ size_t size; /* Size of all allocations. */
- DeviceBuffer()
- : buffer(NULL), size(0)
- {
- }
+ DeviceBuffer() : buffer(NULL), size(0)
+ {
+ }
- ~DeviceBuffer()
- {
- delete buffer;
- buffer = NULL;
- }
+ ~DeviceBuffer()
+ {
+ delete buffer;
+ buffer = NULL;
+ }
- void add_allocation(Allocation& allocation);
+ void add_allocation(Allocation &allocation);
- void update_device_memory(OpenCLDevice *device);
+ void update_device_memory(OpenCLDevice *device);
- void free(OpenCLDevice *device);
- };
+ void free(OpenCLDevice *device);
+ };
- OpenCLDevice *device;
+ OpenCLDevice *device;
- DeviceBuffer device_buffers[NUM_DEVICE_BUFFERS];
+ DeviceBuffer device_buffers[NUM_DEVICE_BUFFERS];
- typedef unordered_map<string, Allocation> AllocationsMap;
- AllocationsMap allocations;
+ typedef unordered_map<string, Allocation> AllocationsMap;
+ AllocationsMap allocations;
- bool need_update;
+ bool need_update;
- DeviceBuffer* smallest_device_buffer();
+ DeviceBuffer *smallest_device_buffer();
-public:
- MemoryManager(OpenCLDevice *device);
+ public:
+ MemoryManager(OpenCLDevice *device);
- void free(); /* Free all memory. */
+ void free(); /* Free all memory. */
- void alloc(const char *name, device_memory& mem);
- bool free(device_memory& mem);
+ void alloc(const char *name, device_memory &mem);
+ bool free(device_memory &mem);
- BufferDescriptor get_descriptor(string name);
+ BufferDescriptor get_descriptor(string name);
- void update_device_memory();
- void set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg);
+ void update_device_memory();
+ void set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/opencl/opencl.h b/intern/cycles/device/opencl/opencl.h
index 89761293638..e7bafa0b8a8 100644
--- a/intern/cycles/device/opencl/opencl.h
+++ b/intern/cycles/device/opencl/opencl.h
@@ -16,645 +16,641 @@
#ifdef WITH_OPENCL
-#include "device/device.h"
-#include "device/device_denoising.h"
-#include "device/device_split_kernel.h"
+# include "device/device.h"
+# include "device/device_denoising.h"
+# include "device/device_split_kernel.h"
-#include "util/util_map.h"
-#include "util/util_param.h"
-#include "util/util_string.h"
+# include "util/util_map.h"
+# include "util/util_param.h"
+# include "util/util_string.h"
-#include "clew.h"
+# include "clew.h"
-#include "device/opencl/memory_manager.h"
+# include "device/opencl/memory_manager.h"
CCL_NAMESPACE_BEGIN
/* Disable workarounds, seems to be working fine on latest drivers. */
-#define CYCLES_DISABLE_DRIVER_WORKAROUNDS
+# define CYCLES_DISABLE_DRIVER_WORKAROUNDS
/* Define CYCLES_DISABLE_DRIVER_WORKAROUNDS to disable workaounds for testing */
-#ifndef CYCLES_DISABLE_DRIVER_WORKAROUNDS
+# ifndef CYCLES_DISABLE_DRIVER_WORKAROUNDS
/* Work around AMD driver hangs by ensuring each command is finished before doing anything else. */
-# undef clEnqueueNDRangeKernel
-# define clEnqueueNDRangeKernel(a, b, c, d, e, f, g, h, i) \
- CLEW_GET_FUN(__clewEnqueueNDRangeKernel)(a, b, c, d, e, f, g, h, i); \
- clFinish(a);
+# undef clEnqueueNDRangeKernel
+# define clEnqueueNDRangeKernel(a, b, c, d, e, f, g, h, i) \
+ CLEW_GET_FUN(__clewEnqueueNDRangeKernel)(a, b, c, d, e, f, g, h, i); \
+ clFinish(a);
-# undef clEnqueueWriteBuffer
-# define clEnqueueWriteBuffer(a, b, c, d, e, f, g, h, i) \
- CLEW_GET_FUN(__clewEnqueueWriteBuffer)(a, b, c, d, e, f, g, h, i); \
- clFinish(a);
+# undef clEnqueueWriteBuffer
+# define clEnqueueWriteBuffer(a, b, c, d, e, f, g, h, i) \
+ CLEW_GET_FUN(__clewEnqueueWriteBuffer)(a, b, c, d, e, f, g, h, i); \
+ clFinish(a);
-# undef clEnqueueReadBuffer
-# define clEnqueueReadBuffer(a, b, c, d, e, f, g, h, i) \
- CLEW_GET_FUN(__clewEnqueueReadBuffer)(a, b, c, d, e, f, g, h, i); \
- clFinish(a);
-#endif /* CYCLES_DISABLE_DRIVER_WORKAROUNDS */
+# undef clEnqueueReadBuffer
+# define clEnqueueReadBuffer(a, b, c, d, e, f, g, h, i) \
+ CLEW_GET_FUN(__clewEnqueueReadBuffer)(a, b, c, d, e, f, g, h, i); \
+ clFinish(a);
+# endif /* CYCLES_DISABLE_DRIVER_WORKAROUNDS */
-#define CL_MEM_PTR(p) ((cl_mem)(uintptr_t)(p))
+# define CL_MEM_PTR(p) ((cl_mem)(uintptr_t)(p))
struct OpenCLPlatformDevice {
- OpenCLPlatformDevice(cl_platform_id platform_id,
- const string& platform_name,
- cl_device_id device_id,
- cl_device_type device_type,
- const string& device_name,
- const string& hardware_id,
- const string& device_extensions)
- : platform_id(platform_id),
- platform_name(platform_name),
- device_id(device_id),
- device_type(device_type),
- device_name(device_name),
- hardware_id(hardware_id),
- device_extensions(device_extensions) {}
- cl_platform_id platform_id;
- string platform_name;
- cl_device_id device_id;
- cl_device_type device_type;
- string device_name;
- string hardware_id;
- string device_extensions;
+ OpenCLPlatformDevice(cl_platform_id platform_id,
+ const string &platform_name,
+ cl_device_id device_id,
+ cl_device_type device_type,
+ const string &device_name,
+ const string &hardware_id,
+ const string &device_extensions)
+ : platform_id(platform_id),
+ platform_name(platform_name),
+ device_id(device_id),
+ device_type(device_type),
+ device_name(device_name),
+ hardware_id(hardware_id),
+ device_extensions(device_extensions)
+ {
+ }
+ cl_platform_id platform_id;
+ string platform_name;
+ cl_device_id device_id;
+ cl_device_type device_type;
+ string device_name;
+ string hardware_id;
+ string device_extensions;
};
/* Contains all static OpenCL helper functions. */
-class OpenCLInfo
-{
-public:
- static cl_device_type device_type();
- static bool use_debug();
- static bool device_supported(const string& platform_name,
- const cl_device_id device_id);
- static bool platform_version_check(cl_platform_id platform,
- string *error = NULL);
- static bool device_version_check(cl_device_id device,
- string *error = NULL);
- static string get_hardware_id(const string& platform_name,
- cl_device_id device_id);
- static void get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices,
- bool force_all = false);
-
- /* ** Some handy shortcuts to low level cl*GetInfo() functions. ** */
-
- /* Platform information. */
- static bool get_num_platforms(cl_uint *num_platforms, cl_int *error = NULL);
- static cl_uint get_num_platforms();
-
- static bool get_platforms(vector<cl_platform_id> *platform_ids,
- cl_int *error = NULL);
- static vector<cl_platform_id> get_platforms();
-
- static bool get_platform_name(cl_platform_id platform_id,
- string *platform_name);
- static string get_platform_name(cl_platform_id platform_id);
-
- static bool get_num_platform_devices(cl_platform_id platform_id,
- cl_device_type device_type,
- cl_uint *num_devices,
- cl_int *error = NULL);
- static cl_uint get_num_platform_devices(cl_platform_id platform_id,
- cl_device_type device_type);
-
- static bool get_platform_devices(cl_platform_id platform_id,
- cl_device_type device_type,
- vector<cl_device_id> *device_ids,
- cl_int* error = NULL);
- static vector<cl_device_id> get_platform_devices(cl_platform_id platform_id,
- cl_device_type device_type);
-
- /* Device information. */
- static bool get_device_name(cl_device_id device_id,
- string *device_name,
- cl_int* error = NULL);
-
- static string get_device_name(cl_device_id device_id);
-
- static bool get_device_extensions(cl_device_id device_id,
- string *device_extensions,
- cl_int* error = NULL);
-
- static string get_device_extensions(cl_device_id device_id);
-
- static bool get_device_type(cl_device_id device_id,
- cl_device_type *device_type,
- cl_int* error = NULL);
- static cl_device_type get_device_type(cl_device_id device_id);
-
- static bool get_driver_version(cl_device_id device_id,
- int *major,
- int *minor,
- cl_int* error = NULL);
-
- static int mem_sub_ptr_alignment(cl_device_id device_id);
-
- /* Get somewhat more readable device name.
- * Main difference is AMD OpenCL here which only gives code name
- * for the regular device name. This will give more sane device
- * name using some extensions.
- */
- static string get_readable_device_name(cl_device_id device_id);
+class OpenCLInfo {
+ public:
+ static cl_device_type device_type();
+ static bool use_debug();
+ static bool device_supported(const string &platform_name, const cl_device_id device_id);
+ static bool platform_version_check(cl_platform_id platform, string *error = NULL);
+ static bool device_version_check(cl_device_id device, string *error = NULL);
+ static string get_hardware_id(const string &platform_name, cl_device_id device_id);
+ static void get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices,
+ bool force_all = false);
+
+ /* ** Some handy shortcuts to low level cl*GetInfo() functions. ** */
+
+ /* Platform information. */
+ static bool get_num_platforms(cl_uint *num_platforms, cl_int *error = NULL);
+ static cl_uint get_num_platforms();
+
+ static bool get_platforms(vector<cl_platform_id> *platform_ids, cl_int *error = NULL);
+ static vector<cl_platform_id> get_platforms();
+
+ static bool get_platform_name(cl_platform_id platform_id, string *platform_name);
+ static string get_platform_name(cl_platform_id platform_id);
+
+ static bool get_num_platform_devices(cl_platform_id platform_id,
+ cl_device_type device_type,
+ cl_uint *num_devices,
+ cl_int *error = NULL);
+ static cl_uint get_num_platform_devices(cl_platform_id platform_id, cl_device_type device_type);
+
+ static bool get_platform_devices(cl_platform_id platform_id,
+ cl_device_type device_type,
+ vector<cl_device_id> *device_ids,
+ cl_int *error = NULL);
+ static vector<cl_device_id> get_platform_devices(cl_platform_id platform_id,
+ cl_device_type device_type);
+
+ /* Device information. */
+ static bool get_device_name(cl_device_id device_id, string *device_name, cl_int *error = NULL);
+
+ static string get_device_name(cl_device_id device_id);
+
+ static bool get_device_extensions(cl_device_id device_id,
+ string *device_extensions,
+ cl_int *error = NULL);
+
+ static string get_device_extensions(cl_device_id device_id);
+
+ static bool get_device_type(cl_device_id device_id,
+ cl_device_type *device_type,
+ cl_int *error = NULL);
+ static cl_device_type get_device_type(cl_device_id device_id);
+
+ static bool get_driver_version(cl_device_id device_id,
+ int *major,
+ int *minor,
+ cl_int *error = NULL);
+
+ static int mem_sub_ptr_alignment(cl_device_id device_id);
+
+ /* Get somewhat more readable device name.
+ * Main difference is AMD OpenCL here which only gives code name
+ * for the regular device name. This will give more sane device
+ * name using some extensions.
+ */
+ static string get_readable_device_name(cl_device_id device_id);
};
/* Thread safe cache for contexts and programs.
*/
-class OpenCLCache
-{
- struct Slot
- {
- struct ProgramEntry
- {
- ProgramEntry();
- ProgramEntry(const ProgramEntry& rhs);
- ~ProgramEntry();
- cl_program program;
- thread_mutex *mutex;
- };
-
- Slot();
- Slot(const Slot& rhs);
- ~Slot();
-
- thread_mutex *context_mutex;
- cl_context context;
- typedef map<ustring, ProgramEntry> EntryMap;
- EntryMap programs;
-
- };
-
- /* key is combination of platform ID and device ID */
- typedef pair<cl_platform_id, cl_device_id> PlatformDevicePair;
-
- /* map of Slot objects */
- typedef map<PlatformDevicePair, Slot> CacheMap;
- CacheMap cache;
-
- /* MD5 hash of the kernel source. */
- string kernel_md5;
-
- thread_mutex cache_lock;
- thread_mutex kernel_md5_lock;
-
- /* lazy instantiate */
- static OpenCLCache& global_instance();
-
-public:
-
- enum ProgramName {
- OCL_DEV_BASE_PROGRAM,
- OCL_DEV_MEGAKERNEL_PROGRAM,
- };
-
- /* Lookup context in the cache. If this returns NULL, slot_locker
- * will be holding a lock for the cache. slot_locker should refer to a
- * default constructed thread_scoped_lock. */
- static cl_context get_context(cl_platform_id platform,
- cl_device_id device,
- thread_scoped_lock& slot_locker);
- /* Same as above. */
- static cl_program get_program(cl_platform_id platform,
- cl_device_id device,
- ustring key,
- thread_scoped_lock& slot_locker);
-
- /* Store context in the cache. You MUST have tried to get the item before storing to it. */
- static void store_context(cl_platform_id platform,
- cl_device_id device,
- cl_context context,
- thread_scoped_lock& slot_locker);
- /* Same as above. */
- static void store_program(cl_platform_id platform,
- cl_device_id device,
- cl_program program,
- ustring key,
- thread_scoped_lock& slot_locker);
-
- static string get_kernel_md5();
+class OpenCLCache {
+ struct Slot {
+ struct ProgramEntry {
+ ProgramEntry();
+ ProgramEntry(const ProgramEntry &rhs);
+ ~ProgramEntry();
+ cl_program program;
+ thread_mutex *mutex;
+ };
+
+ Slot();
+ Slot(const Slot &rhs);
+ ~Slot();
+
+ thread_mutex *context_mutex;
+ cl_context context;
+ typedef map<ustring, ProgramEntry> EntryMap;
+ EntryMap programs;
+ };
+
+ /* key is combination of platform ID and device ID */
+ typedef pair<cl_platform_id, cl_device_id> PlatformDevicePair;
+
+ /* map of Slot objects */
+ typedef map<PlatformDevicePair, Slot> CacheMap;
+ CacheMap cache;
+
+ /* MD5 hash of the kernel source. */
+ string kernel_md5;
+
+ thread_mutex cache_lock;
+ thread_mutex kernel_md5_lock;
+
+ /* lazy instantiate */
+ static OpenCLCache &global_instance();
+
+ public:
+ enum ProgramName {
+ OCL_DEV_BASE_PROGRAM,
+ OCL_DEV_MEGAKERNEL_PROGRAM,
+ };
+
+ /* Lookup context in the cache. If this returns NULL, slot_locker
+ * will be holding a lock for the cache. slot_locker should refer to a
+ * default constructed thread_scoped_lock. */
+ static cl_context get_context(cl_platform_id platform,
+ cl_device_id device,
+ thread_scoped_lock &slot_locker);
+ /* Same as above. */
+ static cl_program get_program(cl_platform_id platform,
+ cl_device_id device,
+ ustring key,
+ thread_scoped_lock &slot_locker);
+
+ /* Store context in the cache. You MUST have tried to get the item before storing to it. */
+ static void store_context(cl_platform_id platform,
+ cl_device_id device,
+ cl_context context,
+ thread_scoped_lock &slot_locker);
+ /* Same as above. */
+ static void store_program(cl_platform_id platform,
+ cl_device_id device,
+ cl_program program,
+ ustring key,
+ thread_scoped_lock &slot_locker);
+
+ static string get_kernel_md5();
};
-#define opencl_device_assert(device, stmt) \
- { \
- cl_int err = stmt; \
- \
- if(err != CL_SUCCESS) { \
- string message = string_printf("OpenCL error: %s in %s (%s:%d)", clewErrorString(err), #stmt, __FILE__, __LINE__); \
- if((device)->error_message() == "") \
- (device)->set_error(message); \
- fprintf(stderr, "%s\n", message.c_str()); \
- } \
- } (void) 0
-
-#define opencl_assert(stmt) \
- { \
- cl_int err = stmt; \
- \
- if(err != CL_SUCCESS) { \
- string message = string_printf("OpenCL error: %s in %s (%s:%d)", clewErrorString(err), #stmt, __FILE__, __LINE__); \
- if(error_msg == "") \
- error_msg = message; \
- fprintf(stderr, "%s\n", message.c_str()); \
- } \
- } (void) 0
-
-class OpenCLDevice : public Device
-{
-public:
- DedicatedTaskPool task_pool;
-
- /* Task pool for required kernels (base, AO kernels during foreground rendering) */
- TaskPool load_required_kernel_task_pool;
- /* Task pool for optional kernels (feature kernels during foreground rendering) */
- TaskPool load_kernel_task_pool;
- cl_context cxContext;
- cl_command_queue cqCommandQueue;
- cl_platform_id cpPlatform;
- cl_device_id cdDevice;
- cl_int ciErr;
- int device_num;
- bool use_preview_kernels;
-
- class OpenCLProgram {
- public:
- OpenCLProgram() : loaded(false), needs_compiling(true), program(NULL), device(NULL) {}
- OpenCLProgram(OpenCLDevice *device,
- const string& program_name,
- const string& kernel_name,
- const string& kernel_build_options,
- bool use_stdout = true);
- ~OpenCLProgram();
-
- void add_kernel(ustring name);
-
- /* Try to load the program from device cache or disk */
- bool load();
- /* Compile the kernel (first separate, failback to local) */
- void compile();
- /* Create the OpenCL kernels after loading or compiling */
- void create_kernels();
-
- bool is_loaded() const { return loaded; }
- const string& get_log() const { return log; }
- void report_error();
-
- /* Wait until this kernel is available to be used
- * It will return true when the kernel is available.
- * It will return false when the kernel is not available
- * or could not be loaded. */
- bool wait_for_availability();
-
- cl_kernel operator()();
- cl_kernel operator()(ustring name);
-
- void release();
-
- private:
- bool build_kernel(const string *debug_src);
- /* Build the program by calling the own process.
- * This is required for multithreaded OpenCL compilation, since most Frameworks serialize
- * build calls internally if they come from the same process.
- * If that is not supported, this function just returns false.
- */
- bool compile_separate(const string& clbin);
- /* Build the program by calling OpenCL directly. */
- bool compile_kernel(const string *debug_src);
- /* Loading and saving the program from/to disk. */
- bool load_binary(const string& clbin, const string *debug_src = NULL);
- bool save_binary(const string& clbin);
-
- void add_log(const string& msg, bool is_debug);
- void add_error(const string& msg);
-
- bool loaded;
- bool needs_compiling;
-
- cl_program program;
- OpenCLDevice *device;
-
- /* Used for the OpenCLCache key. */
- string program_name;
-
- string kernel_file, kernel_build_options, device_md5;
-
- bool use_stdout;
- string log, error_msg;
- string compile_output;
-
- map<ustring, cl_kernel> kernels;
- };
-
- /* Container for all types of split programs. */
- class OpenCLSplitPrograms {
- public:
- OpenCLDevice *device;
- OpenCLProgram program_split;
- OpenCLProgram program_lamp_emission;
- OpenCLProgram program_do_volume;
- OpenCLProgram program_indirect_background;
- OpenCLProgram program_shader_eval;
- OpenCLProgram program_holdout_emission_blurring_pathtermination_ao;
- OpenCLProgram program_subsurface_scatter;
- OpenCLProgram program_direct_lighting;
- OpenCLProgram program_shadow_blocked_ao;
- OpenCLProgram program_shadow_blocked_dl;
-
- OpenCLSplitPrograms(OpenCLDevice *device);
- ~OpenCLSplitPrograms();
-
- /* Load the kernels and put the created kernels in the given `programs`
- * paramter. */
- void load_kernels(vector<OpenCLProgram*> &programs,
- const DeviceRequestedFeatures& requested_features,
- bool is_preview=false);
- };
-
- DeviceSplitKernel *split_kernel;
-
- OpenCLProgram base_program;
- OpenCLProgram bake_program;
- OpenCLProgram displace_program;
- OpenCLProgram background_program;
- OpenCLProgram denoising_program;
-
- OpenCLSplitPrograms kernel_programs;
- OpenCLSplitPrograms preview_programs;
-
- typedef map<string, device_vector<uchar>*> ConstMemMap;
- typedef map<string, device_ptr> MemMap;
-
- ConstMemMap const_mem_map;
- MemMap mem_map;
- device_ptr null_mem;
-
- bool device_initialized;
- string platform_name;
- string device_name;
-
- bool opencl_error(cl_int err);
- void opencl_error(const string& message);
- void opencl_assert_err(cl_int err, const char* where);
-
- OpenCLDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background);
- ~OpenCLDevice();
-
- static void CL_CALLBACK context_notify_callback(const char *err_info,
- const void * /*private_info*/, size_t /*cb*/, void *user_data);
-
- bool opencl_version_check();
- OpenCLSplitPrograms* get_split_programs();
-
- string device_md5_hash(string kernel_custom_build_options = "");
- bool load_kernels(const DeviceRequestedFeatures& requested_features);
- void load_required_kernels(const DeviceRequestedFeatures& requested_features);
- void load_preview_kernels();
-
- bool wait_for_availability(const DeviceRequestedFeatures& requested_features);
- DeviceKernelStatus get_active_kernel_switch_state();
-
- /* Get the name of the opencl program for the given kernel */
- const string get_opencl_program_name(const string& kernel_name);
- /* Get the program file name to compile (*.cl) for the given kernel */
- const string get_opencl_program_filename(const string& kernel_name);
- string get_build_options(const DeviceRequestedFeatures& requested_features,
- const string& opencl_program_name,
- bool preview_kernel=false);
- /* Enable the default features to reduce recompilation events */
- void enable_default_features(DeviceRequestedFeatures& features);
-
- void mem_alloc(device_memory& mem);
- void mem_copy_to(device_memory& mem);
- void mem_copy_from(device_memory& mem, int y, int w, int h, int elem);
- void mem_zero(device_memory& mem);
- void mem_free(device_memory& mem);
-
- int mem_sub_ptr_alignment();
-
- void const_copy_to(const char *name, void *host, size_t size);
- void tex_alloc(device_memory& mem);
- void tex_free(device_memory& mem);
-
- size_t global_size_round_up(int group_size, int global_size);
- void enqueue_kernel(cl_kernel kernel, size_t w, size_t h,
- bool x_workgroups = false,
- size_t max_workgroup_size = -1);
- void set_kernel_arg_mem(cl_kernel kernel, cl_uint *narg, const char *name);
- void set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg);
-
- void film_convert(DeviceTask& task, device_ptr buffer, device_ptr rgba_byte, device_ptr rgba_half);
- void shader(DeviceTask& task);
-
- void denoise(RenderTile& tile, DenoisingTask& denoising);
-
- class OpenCLDeviceTask : public DeviceTask {
- public:
- OpenCLDeviceTask(OpenCLDevice *device, DeviceTask& task)
- : DeviceTask(task)
- {
- run = function_bind(&OpenCLDevice::thread_run,
- device,
- this);
- }
- };
-
- int get_split_task_count(DeviceTask& /*task*/)
- {
- return 1;
- }
-
- void task_add(DeviceTask& task)
- {
- task_pool.push(new OpenCLDeviceTask(this, task));
- }
-
- void task_wait()
- {
- task_pool.wait();
- }
-
- void task_cancel()
- {
- task_pool.cancel();
- }
-
- void thread_run(DeviceTask *task);
-
- virtual BVHLayoutMask get_bvh_layout_mask() const {
- return BVH_LAYOUT_BVH2;
- }
-
- virtual bool show_samples() const {
- return true;
- }
-
-
-protected:
- string kernel_build_options(const string *debug_src = NULL);
-
- void mem_zero_kernel(device_ptr ptr, size_t size);
-
- bool denoising_non_local_means(device_ptr image_ptr,
- device_ptr guide_ptr,
- device_ptr variance_ptr,
- device_ptr out_ptr,
- DenoisingTask *task);
- bool denoising_construct_transform(DenoisingTask *task);
- bool denoising_accumulate(device_ptr color_ptr,
- device_ptr color_variance_ptr,
- device_ptr scale_ptr,
- int frame,
- DenoisingTask *task);
- bool denoising_solve(device_ptr output_ptr,
- DenoisingTask *task);
- bool denoising_combine_halves(device_ptr a_ptr,
- device_ptr b_ptr,
- device_ptr mean_ptr,
- device_ptr variance_ptr,
- int r, int4 rect,
- DenoisingTask *task);
- bool denoising_divide_shadow(device_ptr a_ptr,
- device_ptr b_ptr,
- device_ptr sample_variance_ptr,
- device_ptr sv_variance_ptr,
- device_ptr buffer_variance_ptr,
- DenoisingTask *task);
- bool denoising_get_feature(int mean_offset,
- int variance_offset,
- device_ptr mean_ptr,
- device_ptr variance_ptr,
- float scale,
- DenoisingTask *task);
- bool denoising_write_feature(int to_offset,
- device_ptr from_ptr,
- device_ptr buffer_ptr,
- DenoisingTask *task);
- bool denoising_detect_outliers(device_ptr image_ptr,
- device_ptr variance_ptr,
- device_ptr depth_ptr,
- device_ptr output_ptr,
- DenoisingTask *task);
-
- device_ptr mem_alloc_sub_ptr(device_memory& mem, int offset, int size);
- void mem_free_sub_ptr(device_ptr ptr);
-
- class ArgumentWrapper {
- public:
- ArgumentWrapper() : size(0), pointer(NULL)
- {
- }
-
- ArgumentWrapper(device_memory& argument) : size(sizeof(void*)),
- pointer((void*)(&argument.device_pointer))
- {
- }
-
- template<typename T>
- ArgumentWrapper(device_vector<T>& argument) : size(sizeof(void*)),
- pointer((void*)(&argument.device_pointer))
- {
- }
-
- template<typename T>
- ArgumentWrapper(device_only_memory<T>& argument) : size(sizeof(void*)),
- pointer((void*)(&argument.device_pointer))
- {
- }
- template<typename T>
- ArgumentWrapper(T& argument) : size(sizeof(argument)),
- pointer(&argument)
- {
- }
-
- ArgumentWrapper(int argument) : size(sizeof(int)),
- int_value(argument),
- pointer(&int_value)
- {
- }
-
- ArgumentWrapper(float argument) : size(sizeof(float)),
- float_value(argument),
- pointer(&float_value)
- {
- }
-
- size_t size;
- int int_value;
- float float_value;
- void *pointer;
- };
-
- /* TODO(sergey): In the future we can use variadic templates, once
- * C++0x is allowed. Should allow to clean this up a bit.
- */
- int kernel_set_args(cl_kernel kernel,
- int start_argument_index,
- const ArgumentWrapper& arg1 = ArgumentWrapper(),
- const ArgumentWrapper& arg2 = ArgumentWrapper(),
- const ArgumentWrapper& arg3 = ArgumentWrapper(),
- const ArgumentWrapper& arg4 = ArgumentWrapper(),
- const ArgumentWrapper& arg5 = ArgumentWrapper(),
- const ArgumentWrapper& arg6 = ArgumentWrapper(),
- const ArgumentWrapper& arg7 = ArgumentWrapper(),
- const ArgumentWrapper& arg8 = ArgumentWrapper(),
- const ArgumentWrapper& arg9 = ArgumentWrapper(),
- const ArgumentWrapper& arg10 = ArgumentWrapper(),
- const ArgumentWrapper& arg11 = ArgumentWrapper(),
- const ArgumentWrapper& arg12 = ArgumentWrapper(),
- const ArgumentWrapper& arg13 = ArgumentWrapper(),
- const ArgumentWrapper& arg14 = ArgumentWrapper(),
- const ArgumentWrapper& arg15 = ArgumentWrapper(),
- const ArgumentWrapper& arg16 = ArgumentWrapper(),
- const ArgumentWrapper& arg17 = ArgumentWrapper(),
- const ArgumentWrapper& arg18 = ArgumentWrapper(),
- const ArgumentWrapper& arg19 = ArgumentWrapper(),
- const ArgumentWrapper& arg20 = ArgumentWrapper(),
- const ArgumentWrapper& arg21 = ArgumentWrapper(),
- const ArgumentWrapper& arg22 = ArgumentWrapper(),
- const ArgumentWrapper& arg23 = ArgumentWrapper(),
- const ArgumentWrapper& arg24 = ArgumentWrapper(),
- const ArgumentWrapper& arg25 = ArgumentWrapper(),
- const ArgumentWrapper& arg26 = ArgumentWrapper(),
- const ArgumentWrapper& arg27 = ArgumentWrapper(),
- const ArgumentWrapper& arg28 = ArgumentWrapper(),
- const ArgumentWrapper& arg29 = ArgumentWrapper(),
- const ArgumentWrapper& arg30 = ArgumentWrapper(),
- const ArgumentWrapper& arg31 = ArgumentWrapper(),
- const ArgumentWrapper& arg32 = ArgumentWrapper(),
- const ArgumentWrapper& arg33 = ArgumentWrapper());
-
- void release_kernel_safe(cl_kernel kernel);
- void release_mem_object_safe(cl_mem mem);
- void release_program_safe(cl_program program);
-
- /* ** Those guys are for workign around some compiler-specific bugs ** */
-
- cl_program load_cached_kernel(
- ustring key,
- thread_scoped_lock& cache_locker);
-
- void store_cached_kernel(
- cl_program program,
- ustring key,
- thread_scoped_lock& cache_locker);
-
-private:
- MemoryManager memory_manager;
- friend class MemoryManager;
-
- static_assert_align(TextureInfo, 16);
- device_vector<TextureInfo> texture_info;
-
- typedef map<string, device_memory*> TexturesMap;
- TexturesMap textures;
-
- bool textures_need_update;
-
-protected:
- void flush_texture_buffers();
-
- friend class OpenCLSplitKernel;
- friend class OpenCLSplitKernelFunction;
+# define opencl_device_assert(device, stmt) \
+ { \
+ cl_int err = stmt; \
+\
+ if (err != CL_SUCCESS) { \
+ string message = string_printf( \
+ "OpenCL error: %s in %s (%s:%d)", clewErrorString(err), #stmt, __FILE__, __LINE__); \
+ if ((device)->error_message() == "") \
+ (device)->set_error(message); \
+ fprintf(stderr, "%s\n", message.c_str()); \
+ } \
+ } \
+ (void)0
+
+# define opencl_assert(stmt) \
+ { \
+ cl_int err = stmt; \
+\
+ if (err != CL_SUCCESS) { \
+ string message = string_printf( \
+ "OpenCL error: %s in %s (%s:%d)", clewErrorString(err), #stmt, __FILE__, __LINE__); \
+ if (error_msg == "") \
+ error_msg = message; \
+ fprintf(stderr, "%s\n", message.c_str()); \
+ } \
+ } \
+ (void)0
+
+class OpenCLDevice : public Device {
+ public:
+ DedicatedTaskPool task_pool;
+
+ /* Task pool for required kernels (base, AO kernels during foreground rendering) */
+ TaskPool load_required_kernel_task_pool;
+ /* Task pool for optional kernels (feature kernels during foreground rendering) */
+ TaskPool load_kernel_task_pool;
+ cl_context cxContext;
+ cl_command_queue cqCommandQueue;
+ cl_platform_id cpPlatform;
+ cl_device_id cdDevice;
+ cl_int ciErr;
+ int device_num;
+ bool use_preview_kernels;
+
+ class OpenCLProgram {
+ public:
+ OpenCLProgram() : loaded(false), needs_compiling(true), program(NULL), device(NULL)
+ {
+ }
+ OpenCLProgram(OpenCLDevice *device,
+ const string &program_name,
+ const string &kernel_name,
+ const string &kernel_build_options,
+ bool use_stdout = true);
+ ~OpenCLProgram();
+
+ void add_kernel(ustring name);
+
+ /* Try to load the program from device cache or disk */
+ bool load();
+ /* Compile the kernel (first separate, failback to local) */
+ void compile();
+ /* Create the OpenCL kernels after loading or compiling */
+ void create_kernels();
+
+ bool is_loaded() const
+ {
+ return loaded;
+ }
+ const string &get_log() const
+ {
+ return log;
+ }
+ void report_error();
+
+ /* Wait until this kernel is available to be used
+ * It will return true when the kernel is available.
+ * It will return false when the kernel is not available
+ * or could not be loaded. */
+ bool wait_for_availability();
+
+ cl_kernel operator()();
+ cl_kernel operator()(ustring name);
+
+ void release();
+
+ private:
+ bool build_kernel(const string *debug_src);
+ /* Build the program by calling the own process.
+ * This is required for multithreaded OpenCL compilation, since most Frameworks serialize
+ * build calls internally if they come from the same process.
+ * If that is not supported, this function just returns false.
+ */
+ bool compile_separate(const string &clbin);
+ /* Build the program by calling OpenCL directly. */
+ bool compile_kernel(const string *debug_src);
+ /* Loading and saving the program from/to disk. */
+ bool load_binary(const string &clbin, const string *debug_src = NULL);
+ bool save_binary(const string &clbin);
+
+ void add_log(const string &msg, bool is_debug);
+ void add_error(const string &msg);
+
+ bool loaded;
+ bool needs_compiling;
+
+ cl_program program;
+ OpenCLDevice *device;
+
+ /* Used for the OpenCLCache key. */
+ string program_name;
+
+ string kernel_file, kernel_build_options, device_md5;
+
+ bool use_stdout;
+ string log, error_msg;
+ string compile_output;
+
+ map<ustring, cl_kernel> kernels;
+ };
+
+ /* Container for all types of split programs. */
+ class OpenCLSplitPrograms {
+ public:
+ OpenCLDevice *device;
+ OpenCLProgram program_split;
+ OpenCLProgram program_lamp_emission;
+ OpenCLProgram program_do_volume;
+ OpenCLProgram program_indirect_background;
+ OpenCLProgram program_shader_eval;
+ OpenCLProgram program_holdout_emission_blurring_pathtermination_ao;
+ OpenCLProgram program_subsurface_scatter;
+ OpenCLProgram program_direct_lighting;
+ OpenCLProgram program_shadow_blocked_ao;
+ OpenCLProgram program_shadow_blocked_dl;
+
+ OpenCLSplitPrograms(OpenCLDevice *device);
+ ~OpenCLSplitPrograms();
+
+ /* Load the kernels and put the created kernels in the given `programs`
+ * paramter. */
+ void load_kernels(vector<OpenCLProgram *> &programs,
+ const DeviceRequestedFeatures &requested_features,
+ bool is_preview = false);
+ };
+
+ DeviceSplitKernel *split_kernel;
+
+ OpenCLProgram base_program;
+ OpenCLProgram bake_program;
+ OpenCLProgram displace_program;
+ OpenCLProgram background_program;
+ OpenCLProgram denoising_program;
+
+ OpenCLSplitPrograms kernel_programs;
+ OpenCLSplitPrograms preview_programs;
+
+ typedef map<string, device_vector<uchar> *> ConstMemMap;
+ typedef map<string, device_ptr> MemMap;
+
+ ConstMemMap const_mem_map;
+ MemMap mem_map;
+ device_ptr null_mem;
+
+ bool device_initialized;
+ string platform_name;
+ string device_name;
+
+ bool opencl_error(cl_int err);
+ void opencl_error(const string &message);
+ void opencl_assert_err(cl_int err, const char *where);
+
+ OpenCLDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
+ ~OpenCLDevice();
+
+ static void CL_CALLBACK context_notify_callback(const char *err_info,
+ const void * /*private_info*/,
+ size_t /*cb*/,
+ void *user_data);
+
+ bool opencl_version_check();
+ OpenCLSplitPrograms *get_split_programs();
+
+ string device_md5_hash(string kernel_custom_build_options = "");
+ bool load_kernels(const DeviceRequestedFeatures &requested_features);
+ void load_required_kernels(const DeviceRequestedFeatures &requested_features);
+ void load_preview_kernels();
+
+ bool wait_for_availability(const DeviceRequestedFeatures &requested_features);
+ DeviceKernelStatus get_active_kernel_switch_state();
+
+ /* Get the name of the opencl program for the given kernel */
+ const string get_opencl_program_name(const string &kernel_name);
+ /* Get the program file name to compile (*.cl) for the given kernel */
+ const string get_opencl_program_filename(const string &kernel_name);
+ string get_build_options(const DeviceRequestedFeatures &requested_features,
+ const string &opencl_program_name,
+ bool preview_kernel = false);
+ /* Enable the default features to reduce recompilation events */
+ void enable_default_features(DeviceRequestedFeatures &features);
+
+ void mem_alloc(device_memory &mem);
+ void mem_copy_to(device_memory &mem);
+ void mem_copy_from(device_memory &mem, int y, int w, int h, int elem);
+ void mem_zero(device_memory &mem);
+ void mem_free(device_memory &mem);
+
+ int mem_sub_ptr_alignment();
+
+ void const_copy_to(const char *name, void *host, size_t size);
+ void tex_alloc(device_memory &mem);
+ void tex_free(device_memory &mem);
+
+ size_t global_size_round_up(int group_size, int global_size);
+ void enqueue_kernel(cl_kernel kernel,
+ size_t w,
+ size_t h,
+ bool x_workgroups = false,
+ size_t max_workgroup_size = -1);
+ void set_kernel_arg_mem(cl_kernel kernel, cl_uint *narg, const char *name);
+ void set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg);
+
+ void film_convert(DeviceTask &task,
+ device_ptr buffer,
+ device_ptr rgba_byte,
+ device_ptr rgba_half);
+ void shader(DeviceTask &task);
+
+ void denoise(RenderTile &tile, DenoisingTask &denoising);
+
+ class OpenCLDeviceTask : public DeviceTask {
+ public:
+ OpenCLDeviceTask(OpenCLDevice *device, DeviceTask &task) : DeviceTask(task)
+ {
+ run = function_bind(&OpenCLDevice::thread_run, device, this);
+ }
+ };
+
+ int get_split_task_count(DeviceTask & /*task*/)
+ {
+ return 1;
+ }
+
+ void task_add(DeviceTask &task)
+ {
+ task_pool.push(new OpenCLDeviceTask(this, task));
+ }
+
+ void task_wait()
+ {
+ task_pool.wait();
+ }
+
+ void task_cancel()
+ {
+ task_pool.cancel();
+ }
+
+ void thread_run(DeviceTask *task);
+
+ virtual BVHLayoutMask get_bvh_layout_mask() const
+ {
+ return BVH_LAYOUT_BVH2;
+ }
+
+ virtual bool show_samples() const
+ {
+ return true;
+ }
+
+ protected:
+ string kernel_build_options(const string *debug_src = NULL);
+
+ void mem_zero_kernel(device_ptr ptr, size_t size);
+
+ bool denoising_non_local_means(device_ptr image_ptr,
+ device_ptr guide_ptr,
+ device_ptr variance_ptr,
+ device_ptr out_ptr,
+ DenoisingTask *task);
+ bool denoising_construct_transform(DenoisingTask *task);
+ bool denoising_accumulate(device_ptr color_ptr,
+ device_ptr color_variance_ptr,
+ device_ptr scale_ptr,
+ int frame,
+ DenoisingTask *task);
+ bool denoising_solve(device_ptr output_ptr, DenoisingTask *task);
+ bool denoising_combine_halves(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ int r,
+ int4 rect,
+ DenoisingTask *task);
+ bool denoising_divide_shadow(device_ptr a_ptr,
+ device_ptr b_ptr,
+ device_ptr sample_variance_ptr,
+ device_ptr sv_variance_ptr,
+ device_ptr buffer_variance_ptr,
+ DenoisingTask *task);
+ bool denoising_get_feature(int mean_offset,
+ int variance_offset,
+ device_ptr mean_ptr,
+ device_ptr variance_ptr,
+ float scale,
+ DenoisingTask *task);
+ bool denoising_write_feature(int to_offset,
+ device_ptr from_ptr,
+ device_ptr buffer_ptr,
+ DenoisingTask *task);
+ bool denoising_detect_outliers(device_ptr image_ptr,
+ device_ptr variance_ptr,
+ device_ptr depth_ptr,
+ device_ptr output_ptr,
+ DenoisingTask *task);
+
+ device_ptr mem_alloc_sub_ptr(device_memory &mem, int offset, int size);
+ void mem_free_sub_ptr(device_ptr ptr);
+
+ class ArgumentWrapper {
+ public:
+ ArgumentWrapper() : size(0), pointer(NULL)
+ {
+ }
+
+ ArgumentWrapper(device_memory &argument)
+ : size(sizeof(void *)), pointer((void *)(&argument.device_pointer))
+ {
+ }
+
+ template<typename T>
+ ArgumentWrapper(device_vector<T> &argument)
+ : size(sizeof(void *)), pointer((void *)(&argument.device_pointer))
+ {
+ }
+
+ template<typename T>
+ ArgumentWrapper(device_only_memory<T> &argument)
+ : size(sizeof(void *)), pointer((void *)(&argument.device_pointer))
+ {
+ }
+ template<typename T> ArgumentWrapper(T &argument) : size(sizeof(argument)), pointer(&argument)
+ {
+ }
+
+ ArgumentWrapper(int argument) : size(sizeof(int)), int_value(argument), pointer(&int_value)
+ {
+ }
+
+ ArgumentWrapper(float argument)
+ : size(sizeof(float)), float_value(argument), pointer(&float_value)
+ {
+ }
+
+ size_t size;
+ int int_value;
+ float float_value;
+ void *pointer;
+ };
+
+ /* TODO(sergey): In the future we can use variadic templates, once
+ * C++0x is allowed. Should allow to clean this up a bit.
+ */
+ int kernel_set_args(cl_kernel kernel,
+ int start_argument_index,
+ const ArgumentWrapper &arg1 = ArgumentWrapper(),
+ const ArgumentWrapper &arg2 = ArgumentWrapper(),
+ const ArgumentWrapper &arg3 = ArgumentWrapper(),
+ const ArgumentWrapper &arg4 = ArgumentWrapper(),
+ const ArgumentWrapper &arg5 = ArgumentWrapper(),
+ const ArgumentWrapper &arg6 = ArgumentWrapper(),
+ const ArgumentWrapper &arg7 = ArgumentWrapper(),
+ const ArgumentWrapper &arg8 = ArgumentWrapper(),
+ const ArgumentWrapper &arg9 = ArgumentWrapper(),
+ const ArgumentWrapper &arg10 = ArgumentWrapper(),
+ const ArgumentWrapper &arg11 = ArgumentWrapper(),
+ const ArgumentWrapper &arg12 = ArgumentWrapper(),
+ const ArgumentWrapper &arg13 = ArgumentWrapper(),
+ const ArgumentWrapper &arg14 = ArgumentWrapper(),
+ const ArgumentWrapper &arg15 = ArgumentWrapper(),
+ const ArgumentWrapper &arg16 = ArgumentWrapper(),
+ const ArgumentWrapper &arg17 = ArgumentWrapper(),
+ const ArgumentWrapper &arg18 = ArgumentWrapper(),
+ const ArgumentWrapper &arg19 = ArgumentWrapper(),
+ const ArgumentWrapper &arg20 = ArgumentWrapper(),
+ const ArgumentWrapper &arg21 = ArgumentWrapper(),
+ const ArgumentWrapper &arg22 = ArgumentWrapper(),
+ const ArgumentWrapper &arg23 = ArgumentWrapper(),
+ const ArgumentWrapper &arg24 = ArgumentWrapper(),
+ const ArgumentWrapper &arg25 = ArgumentWrapper(),
+ const ArgumentWrapper &arg26 = ArgumentWrapper(),
+ const ArgumentWrapper &arg27 = ArgumentWrapper(),
+ const ArgumentWrapper &arg28 = ArgumentWrapper(),
+ const ArgumentWrapper &arg29 = ArgumentWrapper(),
+ const ArgumentWrapper &arg30 = ArgumentWrapper(),
+ const ArgumentWrapper &arg31 = ArgumentWrapper(),
+ const ArgumentWrapper &arg32 = ArgumentWrapper(),
+ const ArgumentWrapper &arg33 = ArgumentWrapper());
+
+ void release_kernel_safe(cl_kernel kernel);
+ void release_mem_object_safe(cl_mem mem);
+ void release_program_safe(cl_program program);
+
+ /* ** Those guys are for workign around some compiler-specific bugs ** */
+
+ cl_program load_cached_kernel(ustring key, thread_scoped_lock &cache_locker);
+
+ void store_cached_kernel(cl_program program, ustring key, thread_scoped_lock &cache_locker);
+
+ private:
+ MemoryManager memory_manager;
+ friend class MemoryManager;
+
+ static_assert_align(TextureInfo, 16);
+ device_vector<TextureInfo> texture_info;
+
+ typedef map<string, device_memory *> TexturesMap;
+ TexturesMap textures;
+
+ bool textures_need_update;
+
+ protected:
+ void flush_texture_buffers();
+
+ friend class OpenCLSplitKernel;
+ friend class OpenCLSplitKernelFunction;
};
-Device *opencl_create_split_device(DeviceInfo& info, Stats& stats, Profiler &profiler, bool background);
+Device *opencl_create_split_device(DeviceInfo &info,
+ Stats &stats,
+ Profiler &profiler,
+ bool background);
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/opencl/opencl_split.cpp b/intern/cycles/device/opencl/opencl_split.cpp
index 489d10b7087..70b1a643044 100644
--- a/intern/cycles/device/opencl/opencl_split.cpp
+++ b/intern/cycles/device/opencl/opencl_split.cpp
@@ -16,273 +16,278 @@
#ifdef WITH_OPENCL
-#include "device/opencl/opencl.h"
+# include "device/opencl/opencl.h"
-#include "kernel/kernel_types.h"
-#include "kernel/split/kernel_split_data_types.h"
+# include "kernel/kernel_types.h"
+# include "kernel/split/kernel_split_data_types.h"
-#include "util/util_algorithm.h"
-#include "util/util_debug.h"
-#include "util/util_foreach.h"
-#include "util/util_logging.h"
-#include "util/util_md5.h"
-#include "util/util_path.h"
-#include "util/util_time.h"
+# include "util/util_algorithm.h"
+# include "util/util_debug.h"
+# include "util/util_foreach.h"
+# include "util/util_logging.h"
+# include "util/util_md5.h"
+# include "util/util_path.h"
+# include "util/util_time.h"
CCL_NAMESPACE_BEGIN
struct texture_slot_t {
- texture_slot_t(const string& name, int slot)
- : name(name),
- slot(slot) {
- }
- string name;
- int slot;
+ texture_slot_t(const string &name, int slot) : name(name), slot(slot)
+ {
+ }
+ string name;
+ int slot;
};
static const string NON_SPLIT_KERNELS =
- "denoising "
- "base "
- "background "
- "displace ";
+ "denoising "
+ "base "
+ "background "
+ "displace ";
static const string SPLIT_BUNDLE_KERNELS =
- "data_init "
- "path_init "
- "state_buffer_size "
- "scene_intersect "
- "queue_enqueue "
- "shader_setup "
- "shader_sort "
- "enqueue_inactive "
- "next_iteration_setup "
- "indirect_subsurface "
- "buffer_update";
-
-const string OpenCLDevice::get_opencl_program_name(const string& kernel_name)
+ "data_init "
+ "path_init "
+ "state_buffer_size "
+ "scene_intersect "
+ "queue_enqueue "
+ "shader_setup "
+ "shader_sort "
+ "enqueue_inactive "
+ "next_iteration_setup "
+ "indirect_subsurface "
+ "buffer_update";
+
+const string OpenCLDevice::get_opencl_program_name(const string &kernel_name)
{
- if (NON_SPLIT_KERNELS.find(kernel_name) != std::string::npos) {
- return kernel_name;
- }
- else if (SPLIT_BUNDLE_KERNELS.find(kernel_name) != std::string::npos) {
- return "split_bundle";
- }
- else {
- return "split_" + kernel_name;
- }
+ if (NON_SPLIT_KERNELS.find(kernel_name) != std::string::npos) {
+ return kernel_name;
+ }
+ else if (SPLIT_BUNDLE_KERNELS.find(kernel_name) != std::string::npos) {
+ return "split_bundle";
+ }
+ else {
+ return "split_" + kernel_name;
+ }
}
-const string OpenCLDevice::get_opencl_program_filename(const string& kernel_name)
+const string OpenCLDevice::get_opencl_program_filename(const string &kernel_name)
{
- if (kernel_name == "denoising") {
- return "filter.cl";
- }
- else if (SPLIT_BUNDLE_KERNELS.find(kernel_name) != std::string::npos) {
- return "kernel_split_bundle.cl";
- }
- else {
- return "kernel_" + kernel_name + ".cl";
- }
+ if (kernel_name == "denoising") {
+ return "filter.cl";
+ }
+ else if (SPLIT_BUNDLE_KERNELS.find(kernel_name) != std::string::npos) {
+ return "kernel_split_bundle.cl";
+ }
+ else {
+ return "kernel_" + kernel_name + ".cl";
+ }
}
/* Enable features that we always want to compile to reduce recompilation events */
-void OpenCLDevice::enable_default_features(DeviceRequestedFeatures& features)
+void OpenCLDevice::enable_default_features(DeviceRequestedFeatures &features)
{
- features.use_transparent = true;
- features.use_shadow_tricks = true;
- features.use_principled = true;
- features.use_denoising = true;
-
- if (!background)
- {
- features.max_nodes_group = NODE_GROUP_LEVEL_MAX;
- features.nodes_features = NODE_FEATURE_ALL;
- features.use_hair = true;
- features.use_subsurface = true;
- features.use_camera_motion = false;
- features.use_object_motion = false;
- }
+ features.use_transparent = true;
+ features.use_shadow_tricks = true;
+ features.use_principled = true;
+ features.use_denoising = true;
+
+ if (!background) {
+ features.max_nodes_group = NODE_GROUP_LEVEL_MAX;
+ features.nodes_features = NODE_FEATURE_ALL;
+ features.use_hair = true;
+ features.use_subsurface = true;
+ features.use_camera_motion = false;
+ features.use_object_motion = false;
+ }
}
-string OpenCLDevice::get_build_options(const DeviceRequestedFeatures& requested_features, const string& opencl_program_name, bool preview_kernel)
+string OpenCLDevice::get_build_options(const DeviceRequestedFeatures &requested_features,
+ const string &opencl_program_name,
+ bool preview_kernel)
{
- /* first check for non-split kernel programs */
- if (opencl_program_name == "base" || opencl_program_name == "denoising") {
- return "";
- }
- else if (opencl_program_name == "bake") {
- /* Note: get_build_options for bake is only requested when baking is enabled.
- * displace and background are always requested.
- * `__SPLIT_KERNEL__` must not be present in the compile directives for bake */
- DeviceRequestedFeatures features(requested_features);
- enable_default_features(features);
- features.use_denoising = false;
- features.use_object_motion = false;
- features.use_camera_motion = false;
- features.use_hair = true;
- features.use_subsurface = true;
- features.max_nodes_group = NODE_GROUP_LEVEL_MAX;
- features.nodes_features = NODE_FEATURE_ALL;
- features.use_integrator_branched = false;
- return features.get_build_options();
- }
- else if (opencl_program_name == "displace") {
- /* As displacement does not use any nodes from the Shading group (eg BSDF).
- * We disable all features that are related to shading. */
- DeviceRequestedFeatures features(requested_features);
- enable_default_features(features);
- features.use_denoising = false;
- features.use_object_motion = false;
- features.use_camera_motion = false;
- features.use_baking = false;
- features.use_transparent = false;
- features.use_shadow_tricks = false;
- features.use_subsurface = false;
- features.use_volume = false;
- features.nodes_features &= ~NODE_FEATURE_VOLUME;
- features.use_denoising = false;
- features.use_principled = false;
- features.use_integrator_branched = false;
- return features.get_build_options();
- }
- else if (opencl_program_name == "background") {
- /* Background uses Background shading
- * It is save to disable shadow features, subsurface and volumetric. */
- DeviceRequestedFeatures features(requested_features);
- enable_default_features(features);
- features.use_baking = false;
- features.use_object_motion = false;
- features.use_camera_motion = false;
- features.use_transparent = false;
- features.use_shadow_tricks = false;
- features.use_denoising = false;
- /* NOTE: currently possible to use surface nodes like `Hair Info`, `Bump` node.
- * Perhaps we should remove them in UI as it does not make any sense when
- * rendering background. */
- features.nodes_features &= ~NODE_FEATURE_VOLUME;
- features.use_subsurface = false;
- features.use_volume = false;
- features.use_shader_raytrace = false;
- features.use_patch_evaluation = false;
- features.use_integrator_branched = false;
- return features.get_build_options();
- }
-
- string build_options = "-D__SPLIT_KERNEL__ ";
- /* Set compute device build option. */
- cl_device_type device_type;
- OpenCLInfo::get_device_type(this->cdDevice, &device_type, &this->ciErr);
- assert(this->ciErr == CL_SUCCESS);
- if(device_type == CL_DEVICE_TYPE_GPU) {
- build_options += "-D__COMPUTE_DEVICE_GPU__ ";
- }
-
- DeviceRequestedFeatures nofeatures;
- enable_default_features(nofeatures);
-
- /* Add program specific optimized compile directives */
- if (preview_kernel) {
- DeviceRequestedFeatures preview_features;
- preview_features.use_hair = true;
- build_options += "-D__KERNEL_AO_PREVIEW__ ";
- build_options += preview_features.get_build_options();
- }
- else if (opencl_program_name == "split_do_volume" && !requested_features.use_volume) {
- build_options += nofeatures.get_build_options();
- }
- else {
- DeviceRequestedFeatures features(requested_features);
- enable_default_features(features);
-
- /* Always turn off baking at this point. Baking is only usefull when building the bake kernel.
- * this also makes sure that the kernels that are build during baking can be reused
- * when not doing any baking. */
- features.use_baking = false;
-
- /* Do not vary on shaders when program doesn't do any shading.
- * We have bundled them in a single program. */
- if (opencl_program_name == "split_bundle") {
- features.max_nodes_group = 0;
- features.nodes_features = 0;
- features.use_shader_raytrace = false;
- }
-
- /* No specific settings, just add the regular ones */
- build_options += features.get_build_options();
- }
-
- return build_options;
+ /* first check for non-split kernel programs */
+ if (opencl_program_name == "base" || opencl_program_name == "denoising") {
+ return "";
+ }
+ else if (opencl_program_name == "bake") {
+ /* Note: get_build_options for bake is only requested when baking is enabled.
+ * displace and background are always requested.
+ * `__SPLIT_KERNEL__` must not be present in the compile directives for bake */
+ DeviceRequestedFeatures features(requested_features);
+ enable_default_features(features);
+ features.use_denoising = false;
+ features.use_object_motion = false;
+ features.use_camera_motion = false;
+ features.use_hair = true;
+ features.use_subsurface = true;
+ features.max_nodes_group = NODE_GROUP_LEVEL_MAX;
+ features.nodes_features = NODE_FEATURE_ALL;
+ features.use_integrator_branched = false;
+ return features.get_build_options();
+ }
+ else if (opencl_program_name == "displace") {
+ /* As displacement does not use any nodes from the Shading group (eg BSDF).
+ * We disable all features that are related to shading. */
+ DeviceRequestedFeatures features(requested_features);
+ enable_default_features(features);
+ features.use_denoising = false;
+ features.use_object_motion = false;
+ features.use_camera_motion = false;
+ features.use_baking = false;
+ features.use_transparent = false;
+ features.use_shadow_tricks = false;
+ features.use_subsurface = false;
+ features.use_volume = false;
+ features.nodes_features &= ~NODE_FEATURE_VOLUME;
+ features.use_denoising = false;
+ features.use_principled = false;
+ features.use_integrator_branched = false;
+ return features.get_build_options();
+ }
+ else if (opencl_program_name == "background") {
+ /* Background uses Background shading
+ * It is save to disable shadow features, subsurface and volumetric. */
+ DeviceRequestedFeatures features(requested_features);
+ enable_default_features(features);
+ features.use_baking = false;
+ features.use_object_motion = false;
+ features.use_camera_motion = false;
+ features.use_transparent = false;
+ features.use_shadow_tricks = false;
+ features.use_denoising = false;
+ /* NOTE: currently possible to use surface nodes like `Hair Info`, `Bump` node.
+ * Perhaps we should remove them in UI as it does not make any sense when
+ * rendering background. */
+ features.nodes_features &= ~NODE_FEATURE_VOLUME;
+ features.use_subsurface = false;
+ features.use_volume = false;
+ features.use_shader_raytrace = false;
+ features.use_patch_evaluation = false;
+ features.use_integrator_branched = false;
+ return features.get_build_options();
+ }
+
+ string build_options = "-D__SPLIT_KERNEL__ ";
+ /* Set compute device build option. */
+ cl_device_type device_type;
+ OpenCLInfo::get_device_type(this->cdDevice, &device_type, &this->ciErr);
+ assert(this->ciErr == CL_SUCCESS);
+ if (device_type == CL_DEVICE_TYPE_GPU) {
+ build_options += "-D__COMPUTE_DEVICE_GPU__ ";
+ }
+
+ DeviceRequestedFeatures nofeatures;
+ enable_default_features(nofeatures);
+
+ /* Add program specific optimized compile directives */
+ if (preview_kernel) {
+ DeviceRequestedFeatures preview_features;
+ preview_features.use_hair = true;
+ build_options += "-D__KERNEL_AO_PREVIEW__ ";
+ build_options += preview_features.get_build_options();
+ }
+ else if (opencl_program_name == "split_do_volume" && !requested_features.use_volume) {
+ build_options += nofeatures.get_build_options();
+ }
+ else {
+ DeviceRequestedFeatures features(requested_features);
+ enable_default_features(features);
+
+ /* Always turn off baking at this point. Baking is only usefull when building the bake kernel.
+ * this also makes sure that the kernels that are build during baking can be reused
+ * when not doing any baking. */
+ features.use_baking = false;
+
+ /* Do not vary on shaders when program doesn't do any shading.
+ * We have bundled them in a single program. */
+ if (opencl_program_name == "split_bundle") {
+ features.max_nodes_group = 0;
+ features.nodes_features = 0;
+ features.use_shader_raytrace = false;
+ }
+
+ /* No specific settings, just add the regular ones */
+ build_options += features.get_build_options();
+ }
+
+ return build_options;
}
OpenCLDevice::OpenCLSplitPrograms::OpenCLSplitPrograms(OpenCLDevice *device_)
{
- device = device_;
+ device = device_;
}
OpenCLDevice::OpenCLSplitPrograms::~OpenCLSplitPrograms()
{
- program_split.release();
- program_lamp_emission.release();
- program_do_volume.release();
- program_indirect_background.release();
- program_shader_eval.release();
- program_holdout_emission_blurring_pathtermination_ao.release();
- program_subsurface_scatter.release();
- program_direct_lighting.release();
- program_shadow_blocked_ao.release();
- program_shadow_blocked_dl.release();
+ program_split.release();
+ program_lamp_emission.release();
+ program_do_volume.release();
+ program_indirect_background.release();
+ program_shader_eval.release();
+ program_holdout_emission_blurring_pathtermination_ao.release();
+ program_subsurface_scatter.release();
+ program_direct_lighting.release();
+ program_shadow_blocked_ao.release();
+ program_shadow_blocked_dl.release();
}
-void OpenCLDevice::OpenCLSplitPrograms::load_kernels(vector<OpenCLProgram*> &programs, const DeviceRequestedFeatures& requested_features, bool is_preview)
+void OpenCLDevice::OpenCLSplitPrograms::load_kernels(
+ vector<OpenCLProgram *> &programs,
+ const DeviceRequestedFeatures &requested_features,
+ bool is_preview)
{
- if (!requested_features.use_baking) {
-#define ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(kernel_name) program_split.add_kernel(ustring("path_trace_"#kernel_name));
-#define ADD_SPLIT_KERNEL_PROGRAM(kernel_name) \
- const string program_name_##kernel_name = "split_"#kernel_name; \
- program_##kernel_name = \
- OpenCLDevice::OpenCLProgram(device, \
- program_name_##kernel_name, \
- "kernel_"#kernel_name".cl", \
- device->get_build_options(requested_features, program_name_##kernel_name, is_preview)); \
- program_##kernel_name.add_kernel(ustring("path_trace_"#kernel_name)); \
- programs.push_back(&program_##kernel_name);
-
- /* Ordered with most complex kernels first, to reduce overall compile time. */
- ADD_SPLIT_KERNEL_PROGRAM(subsurface_scatter);
- if (requested_features.use_volume || is_preview) {
- ADD_SPLIT_KERNEL_PROGRAM(do_volume);
- }
- ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_dl);
- ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_ao);
- ADD_SPLIT_KERNEL_PROGRAM(holdout_emission_blurring_pathtermination_ao);
- ADD_SPLIT_KERNEL_PROGRAM(lamp_emission);
- ADD_SPLIT_KERNEL_PROGRAM(direct_lighting);
- ADD_SPLIT_KERNEL_PROGRAM(indirect_background);
- ADD_SPLIT_KERNEL_PROGRAM(shader_eval);
-
- /* Quick kernels bundled in a single program to reduce overhead of starting
- * Blender processes. */
- program_split = OpenCLDevice::OpenCLProgram(device,
- "split_bundle" ,
- "kernel_split_bundle.cl",
- device->get_build_options(requested_features, "split_bundle", is_preview));
-
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(data_init);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(state_buffer_size);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(path_init);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(scene_intersect);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(queue_enqueue);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(shader_setup);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(shader_sort);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(enqueue_inactive);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(next_iteration_setup);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(indirect_subsurface);
- ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(buffer_update);
- programs.push_back(&program_split);
-
-#undef ADD_SPLIT_KERNEL_PROGRAM
-#undef ADD_SPLIT_KERNEL_BUNDLE_PROGRAM
- }
+ if (!requested_features.use_baking) {
+# define ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(kernel_name) \
+ program_split.add_kernel(ustring("path_trace_" #kernel_name));
+# define ADD_SPLIT_KERNEL_PROGRAM(kernel_name) \
+ const string program_name_##kernel_name = "split_" #kernel_name; \
+ program_##kernel_name = OpenCLDevice::OpenCLProgram( \
+ device, \
+ program_name_##kernel_name, \
+ "kernel_" #kernel_name ".cl", \
+ device->get_build_options(requested_features, program_name_##kernel_name, is_preview)); \
+ program_##kernel_name.add_kernel(ustring("path_trace_" #kernel_name)); \
+ programs.push_back(&program_##kernel_name);
+
+ /* Ordered with most complex kernels first, to reduce overall compile time. */
+ ADD_SPLIT_KERNEL_PROGRAM(subsurface_scatter);
+ if (requested_features.use_volume || is_preview) {
+ ADD_SPLIT_KERNEL_PROGRAM(do_volume);
+ }
+ ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_dl);
+ ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_ao);
+ ADD_SPLIT_KERNEL_PROGRAM(holdout_emission_blurring_pathtermination_ao);
+ ADD_SPLIT_KERNEL_PROGRAM(lamp_emission);
+ ADD_SPLIT_KERNEL_PROGRAM(direct_lighting);
+ ADD_SPLIT_KERNEL_PROGRAM(indirect_background);
+ ADD_SPLIT_KERNEL_PROGRAM(shader_eval);
+
+ /* Quick kernels bundled in a single program to reduce overhead of starting
+ * Blender processes. */
+ program_split = OpenCLDevice::OpenCLProgram(
+ device,
+ "split_bundle",
+ "kernel_split_bundle.cl",
+ device->get_build_options(requested_features, "split_bundle", is_preview));
+
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(data_init);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(state_buffer_size);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(path_init);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(scene_intersect);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(queue_enqueue);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(shader_setup);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(shader_sort);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(enqueue_inactive);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(next_iteration_setup);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(indirect_subsurface);
+ ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(buffer_update);
+ programs.push_back(&program_split);
+
+# undef ADD_SPLIT_KERNEL_PROGRAM
+# undef ADD_SPLIT_KERNEL_BUNDLE_PROGRAM
+ }
}
namespace {
@@ -291,1126 +296,1108 @@ namespace {
* fetch its size.
*/
typedef struct KernelGlobalsDummy {
- ccl_constant KernelData *data;
- ccl_global char *buffers[8];
+ ccl_constant KernelData *data;
+ ccl_global char *buffers[8];
-#define KERNEL_TEX(type, name) \
- TextureInfo name;
+# define KERNEL_TEX(type, name) TextureInfo name;
# include "kernel/kernel_textures.h"
-#undef KERNEL_TEX
- SplitData split_data;
- SplitParams split_param_data;
+# undef KERNEL_TEX
+ SplitData split_data;
+ SplitParams split_param_data;
} KernelGlobalsDummy;
} // namespace
-
struct CachedSplitMemory {
- int id;
- device_memory *split_data;
- device_memory *ray_state;
- device_memory *queue_index;
- device_memory *use_queues_flag;
- device_memory *work_pools;
- device_ptr *buffer;
+ int id;
+ device_memory *split_data;
+ device_memory *ray_state;
+ device_memory *queue_index;
+ device_memory *use_queues_flag;
+ device_memory *work_pools;
+ device_ptr *buffer;
};
class OpenCLSplitKernelFunction : public SplitKernelFunction {
-public:
- OpenCLDevice* device;
- OpenCLDevice::OpenCLProgram program;
- CachedSplitMemory& cached_memory;
- int cached_id;
-
- OpenCLSplitKernelFunction(OpenCLDevice* device, CachedSplitMemory& cached_memory) :
- device(device), cached_memory(cached_memory), cached_id(cached_memory.id-1)
- {
- }
-
- ~OpenCLSplitKernelFunction()
- {
- program.release();
- }
-
- virtual bool enqueue(const KernelDimensions& dim, device_memory& kg, device_memory& data)
- {
- if(cached_id != cached_memory.id) {
- cl_uint start_arg_index =
- device->kernel_set_args(program(),
- 0,
- kg,
- data,
- *cached_memory.split_data,
- *cached_memory.ray_state);
-
- device->set_kernel_arg_buffers(program(), &start_arg_index);
-
- start_arg_index +=
- device->kernel_set_args(program(),
- start_arg_index,
- *cached_memory.queue_index,
- *cached_memory.use_queues_flag,
- *cached_memory.work_pools,
- *cached_memory.buffer);
-
- cached_id = cached_memory.id;
- }
-
- device->ciErr = clEnqueueNDRangeKernel(device->cqCommandQueue,
- program(),
- 2,
- NULL,
- dim.global_size,
- dim.local_size,
- 0,
- NULL,
- NULL);
-
- device->opencl_assert_err(device->ciErr, "clEnqueueNDRangeKernel");
-
- if(device->ciErr != CL_SUCCESS) {
- string message = string_printf("OpenCL error: %s in clEnqueueNDRangeKernel()",
- clewErrorString(device->ciErr));
- device->opencl_error(message);
- return false;
- }
-
- return true;
- }
+ public:
+ OpenCLDevice *device;
+ OpenCLDevice::OpenCLProgram program;
+ CachedSplitMemory &cached_memory;
+ int cached_id;
+
+ OpenCLSplitKernelFunction(OpenCLDevice *device, CachedSplitMemory &cached_memory)
+ : device(device), cached_memory(cached_memory), cached_id(cached_memory.id - 1)
+ {
+ }
+
+ ~OpenCLSplitKernelFunction()
+ {
+ program.release();
+ }
+
+ virtual bool enqueue(const KernelDimensions &dim, device_memory &kg, device_memory &data)
+ {
+ if (cached_id != cached_memory.id) {
+ cl_uint start_arg_index = device->kernel_set_args(
+ program(), 0, kg, data, *cached_memory.split_data, *cached_memory.ray_state);
+
+ device->set_kernel_arg_buffers(program(), &start_arg_index);
+
+ start_arg_index += device->kernel_set_args(program(),
+ start_arg_index,
+ *cached_memory.queue_index,
+ *cached_memory.use_queues_flag,
+ *cached_memory.work_pools,
+ *cached_memory.buffer);
+
+ cached_id = cached_memory.id;
+ }
+
+ device->ciErr = clEnqueueNDRangeKernel(device->cqCommandQueue,
+ program(),
+ 2,
+ NULL,
+ dim.global_size,
+ dim.local_size,
+ 0,
+ NULL,
+ NULL);
+
+ device->opencl_assert_err(device->ciErr, "clEnqueueNDRangeKernel");
+
+ if (device->ciErr != CL_SUCCESS) {
+ string message = string_printf("OpenCL error: %s in clEnqueueNDRangeKernel()",
+ clewErrorString(device->ciErr));
+ device->opencl_error(message);
+ return false;
+ }
+
+ return true;
+ }
};
class OpenCLSplitKernel : public DeviceSplitKernel {
- OpenCLDevice *device;
- CachedSplitMemory cached_memory;
-public:
- explicit OpenCLSplitKernel(OpenCLDevice *device) : DeviceSplitKernel(device), device(device) {
- }
-
- virtual SplitKernelFunction* get_split_kernel_function(const string& kernel_name,
- const DeviceRequestedFeatures& requested_features)
- {
- OpenCLSplitKernelFunction* kernel = new OpenCLSplitKernelFunction(device, cached_memory);
-
- const string program_name = device->get_opencl_program_name(kernel_name);
- kernel->program =
- OpenCLDevice::OpenCLProgram(device,
- program_name,
- device->get_opencl_program_filename(kernel_name),
- device->get_build_options(requested_features,
- program_name,
- device->use_preview_kernels));
-
- kernel->program.add_kernel(ustring("path_trace_" + kernel_name));
- kernel->program.load();
-
- if(!kernel->program.is_loaded()) {
- delete kernel;
- return NULL;
- }
-
- return kernel;
- }
-
- virtual uint64_t state_buffer_size(device_memory& kg, device_memory& data, size_t num_threads)
- {
- device_vector<uint64_t> size_buffer(device, "size_buffer", MEM_READ_WRITE);
- size_buffer.alloc(1);
- size_buffer.zero_to_device();
-
- uint threads = num_threads;
- OpenCLDevice::OpenCLSplitPrograms *programs = device->get_split_programs();
- cl_kernel kernel_state_buffer_size = programs->program_split(ustring("path_trace_state_buffer_size"));
- device->kernel_set_args(kernel_state_buffer_size, 0, kg, data, threads, size_buffer);
-
- size_t global_size = 64;
- device->ciErr = clEnqueueNDRangeKernel(device->cqCommandQueue,
- kernel_state_buffer_size,
- 1,
- NULL,
- &global_size,
- NULL,
- 0,
- NULL,
- NULL);
-
- device->opencl_assert_err(device->ciErr, "clEnqueueNDRangeKernel");
-
- size_buffer.copy_from_device(0, 1, 1);
- size_t size = size_buffer[0];
- size_buffer.free();
-
- if(device->ciErr != CL_SUCCESS) {
- string message = string_printf("OpenCL error: %s in clEnqueueNDRangeKernel()",
- clewErrorString(device->ciErr));
- device->opencl_error(message);
- return 0;
- }
-
- return size;
- }
-
- virtual bool enqueue_split_kernel_data_init(const KernelDimensions& dim,
- RenderTile& rtile,
- int num_global_elements,
- device_memory& kernel_globals,
- device_memory& kernel_data,
- device_memory& split_data,
- device_memory& ray_state,
- device_memory& queue_index,
- device_memory& use_queues_flag,
- device_memory& work_pool_wgs
- )
- {
- cl_int dQueue_size = dim.global_size[0] * dim.global_size[1];
-
- /* Set the range of samples to be processed for every ray in
- * path-regeneration logic.
- */
- cl_int start_sample = rtile.start_sample;
- cl_int end_sample = rtile.start_sample + rtile.num_samples;
-
- OpenCLDevice::OpenCLSplitPrograms *programs = device->get_split_programs();
- cl_kernel kernel_data_init = programs->program_split(ustring("path_trace_data_init"));
-
- cl_uint start_arg_index =
- device->kernel_set_args(kernel_data_init,
- 0,
- kernel_globals,
- kernel_data,
- split_data,
- num_global_elements,
- ray_state);
-
- device->set_kernel_arg_buffers(kernel_data_init, &start_arg_index);
-
- start_arg_index +=
- device->kernel_set_args(kernel_data_init,
- start_arg_index,
- start_sample,
- end_sample,
- rtile.x,
- rtile.y,
- rtile.w,
- rtile.h,
- rtile.offset,
- rtile.stride,
- queue_index,
- dQueue_size,
- use_queues_flag,
- work_pool_wgs,
- rtile.num_samples,
- rtile.buffer);
-
- /* Enqueue ckPathTraceKernel_data_init kernel. */
- device->ciErr = clEnqueueNDRangeKernel(device->cqCommandQueue,
- kernel_data_init,
- 2,
- NULL,
- dim.global_size,
- dim.local_size,
- 0,
- NULL,
- NULL);
-
- device->opencl_assert_err(device->ciErr, "clEnqueueNDRangeKernel");
-
- if(device->ciErr != CL_SUCCESS) {
- string message = string_printf("OpenCL error: %s in clEnqueueNDRangeKernel()",
- clewErrorString(device->ciErr));
- device->opencl_error(message);
- return false;
- }
-
- cached_memory.split_data = &split_data;
- cached_memory.ray_state = &ray_state;
- cached_memory.queue_index = &queue_index;
- cached_memory.use_queues_flag = &use_queues_flag;
- cached_memory.work_pools = &work_pool_wgs;
- cached_memory.buffer = &rtile.buffer;
- cached_memory.id++;
-
- return true;
- }
-
- virtual int2 split_kernel_local_size()
- {
- return make_int2(64, 1);
- }
-
- virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask * /*task*/)
- {
- cl_device_type type = OpenCLInfo::get_device_type(device->cdDevice);
- /* Use small global size on CPU devices as it seems to be much faster. */
- if(type == CL_DEVICE_TYPE_CPU) {
- VLOG(1) << "Global size: (64, 64).";
- return make_int2(64, 64);
- }
-
- cl_ulong max_buffer_size;
- clGetDeviceInfo(device->cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_buffer_size, NULL);
-
- if(DebugFlags().opencl.mem_limit) {
- max_buffer_size = min(max_buffer_size,
- cl_ulong(DebugFlags().opencl.mem_limit - device->stats.mem_used));
- }
-
- VLOG(1) << "Maximum device allocation size: "
- << string_human_readable_number(max_buffer_size) << " bytes. ("
- << string_human_readable_size(max_buffer_size) << ").";
-
- /* Limit to 2gb, as we shouldn't need more than that and some devices may support much more. */
- max_buffer_size = min(max_buffer_size / 2, (cl_ulong)2l*1024*1024*1024);
-
- size_t num_elements = max_elements_for_max_buffer_size(kg, data, max_buffer_size);
- int2 global_size = make_int2(max(round_down((int)sqrt(num_elements), 64), 64), (int)sqrt(num_elements));
- VLOG(1) << "Global size: " << global_size << ".";
- return global_size;
- }
+ OpenCLDevice *device;
+ CachedSplitMemory cached_memory;
+
+ public:
+ explicit OpenCLSplitKernel(OpenCLDevice *device) : DeviceSplitKernel(device), device(device)
+ {
+ }
+
+ virtual SplitKernelFunction *get_split_kernel_function(
+ const string &kernel_name, const DeviceRequestedFeatures &requested_features)
+ {
+ OpenCLSplitKernelFunction *kernel = new OpenCLSplitKernelFunction(device, cached_memory);
+
+ const string program_name = device->get_opencl_program_name(kernel_name);
+ kernel->program = OpenCLDevice::OpenCLProgram(
+ device,
+ program_name,
+ device->get_opencl_program_filename(kernel_name),
+ device->get_build_options(requested_features, program_name, device->use_preview_kernels));
+
+ kernel->program.add_kernel(ustring("path_trace_" + kernel_name));
+ kernel->program.load();
+
+ if (!kernel->program.is_loaded()) {
+ delete kernel;
+ return NULL;
+ }
+
+ return kernel;
+ }
+
+ virtual uint64_t state_buffer_size(device_memory &kg, device_memory &data, size_t num_threads)
+ {
+ device_vector<uint64_t> size_buffer(device, "size_buffer", MEM_READ_WRITE);
+ size_buffer.alloc(1);
+ size_buffer.zero_to_device();
+
+ uint threads = num_threads;
+ OpenCLDevice::OpenCLSplitPrograms *programs = device->get_split_programs();
+ cl_kernel kernel_state_buffer_size = programs->program_split(
+ ustring("path_trace_state_buffer_size"));
+ device->kernel_set_args(kernel_state_buffer_size, 0, kg, data, threads, size_buffer);
+
+ size_t global_size = 64;
+ device->ciErr = clEnqueueNDRangeKernel(device->cqCommandQueue,
+ kernel_state_buffer_size,
+ 1,
+ NULL,
+ &global_size,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+
+ device->opencl_assert_err(device->ciErr, "clEnqueueNDRangeKernel");
+
+ size_buffer.copy_from_device(0, 1, 1);
+ size_t size = size_buffer[0];
+ size_buffer.free();
+
+ if (device->ciErr != CL_SUCCESS) {
+ string message = string_printf("OpenCL error: %s in clEnqueueNDRangeKernel()",
+ clewErrorString(device->ciErr));
+ device->opencl_error(message);
+ return 0;
+ }
+
+ return size;
+ }
+
+ virtual bool enqueue_split_kernel_data_init(const KernelDimensions &dim,
+ RenderTile &rtile,
+ int num_global_elements,
+ device_memory &kernel_globals,
+ device_memory &kernel_data,
+ device_memory &split_data,
+ device_memory &ray_state,
+ device_memory &queue_index,
+ device_memory &use_queues_flag,
+ device_memory &work_pool_wgs)
+ {
+ cl_int dQueue_size = dim.global_size[0] * dim.global_size[1];
+
+ /* Set the range of samples to be processed for every ray in
+ * path-regeneration logic.
+ */
+ cl_int start_sample = rtile.start_sample;
+ cl_int end_sample = rtile.start_sample + rtile.num_samples;
+
+ OpenCLDevice::OpenCLSplitPrograms *programs = device->get_split_programs();
+ cl_kernel kernel_data_init = programs->program_split(ustring("path_trace_data_init"));
+
+ cl_uint start_arg_index = device->kernel_set_args(kernel_data_init,
+ 0,
+ kernel_globals,
+ kernel_data,
+ split_data,
+ num_global_elements,
+ ray_state);
+
+ device->set_kernel_arg_buffers(kernel_data_init, &start_arg_index);
+
+ start_arg_index += device->kernel_set_args(kernel_data_init,
+ start_arg_index,
+ start_sample,
+ end_sample,
+ rtile.x,
+ rtile.y,
+ rtile.w,
+ rtile.h,
+ rtile.offset,
+ rtile.stride,
+ queue_index,
+ dQueue_size,
+ use_queues_flag,
+ work_pool_wgs,
+ rtile.num_samples,
+ rtile.buffer);
+
+ /* Enqueue ckPathTraceKernel_data_init kernel. */
+ device->ciErr = clEnqueueNDRangeKernel(device->cqCommandQueue,
+ kernel_data_init,
+ 2,
+ NULL,
+ dim.global_size,
+ dim.local_size,
+ 0,
+ NULL,
+ NULL);
+
+ device->opencl_assert_err(device->ciErr, "clEnqueueNDRangeKernel");
+
+ if (device->ciErr != CL_SUCCESS) {
+ string message = string_printf("OpenCL error: %s in clEnqueueNDRangeKernel()",
+ clewErrorString(device->ciErr));
+ device->opencl_error(message);
+ return false;
+ }
+
+ cached_memory.split_data = &split_data;
+ cached_memory.ray_state = &ray_state;
+ cached_memory.queue_index = &queue_index;
+ cached_memory.use_queues_flag = &use_queues_flag;
+ cached_memory.work_pools = &work_pool_wgs;
+ cached_memory.buffer = &rtile.buffer;
+ cached_memory.id++;
+
+ return true;
+ }
+
+ virtual int2 split_kernel_local_size()
+ {
+ return make_int2(64, 1);
+ }
+
+ virtual int2 split_kernel_global_size(device_memory &kg,
+ device_memory &data,
+ DeviceTask * /*task*/)
+ {
+ cl_device_type type = OpenCLInfo::get_device_type(device->cdDevice);
+ /* Use small global size on CPU devices as it seems to be much faster. */
+ if (type == CL_DEVICE_TYPE_CPU) {
+ VLOG(1) << "Global size: (64, 64).";
+ return make_int2(64, 64);
+ }
+
+ cl_ulong max_buffer_size;
+ clGetDeviceInfo(
+ device->cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_buffer_size, NULL);
+
+ if (DebugFlags().opencl.mem_limit) {
+ max_buffer_size = min(max_buffer_size,
+ cl_ulong(DebugFlags().opencl.mem_limit - device->stats.mem_used));
+ }
+
+ VLOG(1) << "Maximum device allocation size: " << string_human_readable_number(max_buffer_size)
+ << " bytes. (" << string_human_readable_size(max_buffer_size) << ").";
+
+ /* Limit to 2gb, as we shouldn't need more than that and some devices may support much more. */
+ max_buffer_size = min(max_buffer_size / 2, (cl_ulong)2l * 1024 * 1024 * 1024);
+
+ size_t num_elements = max_elements_for_max_buffer_size(kg, data, max_buffer_size);
+ int2 global_size = make_int2(max(round_down((int)sqrt(num_elements), 64), 64),
+ (int)sqrt(num_elements));
+ VLOG(1) << "Global size: " << global_size << ".";
+ return global_size;
+ }
};
bool OpenCLDevice::opencl_error(cl_int err)
{
- if(err != CL_SUCCESS) {
- string message = string_printf("OpenCL error (%d): %s", err, clewErrorString(err));
- if(error_msg == "")
- error_msg = message;
- fprintf(stderr, "%s\n", message.c_str());
- return true;
- }
-
- return false;
+ if (err != CL_SUCCESS) {
+ string message = string_printf("OpenCL error (%d): %s", err, clewErrorString(err));
+ if (error_msg == "")
+ error_msg = message;
+ fprintf(stderr, "%s\n", message.c_str());
+ return true;
+ }
+
+ return false;
}
-void OpenCLDevice::opencl_error(const string& message)
+void OpenCLDevice::opencl_error(const string &message)
{
- if(error_msg == "")
- error_msg = message;
- fprintf(stderr, "%s\n", message.c_str());
+ if (error_msg == "")
+ error_msg = message;
+ fprintf(stderr, "%s\n", message.c_str());
}
-void OpenCLDevice::opencl_assert_err(cl_int err, const char* where)
+void OpenCLDevice::opencl_assert_err(cl_int err, const char *where)
{
- if(err != CL_SUCCESS) {
- string message = string_printf("OpenCL error (%d): %s in %s", err, clewErrorString(err), where);
- if(error_msg == "")
- error_msg = message;
- fprintf(stderr, "%s\n", message.c_str());
-#ifndef NDEBUG
- abort();
-#endif
- }
+ if (err != CL_SUCCESS) {
+ string message = string_printf(
+ "OpenCL error (%d): %s in %s", err, clewErrorString(err), where);
+ if (error_msg == "")
+ error_msg = message;
+ fprintf(stderr, "%s\n", message.c_str());
+# ifndef NDEBUG
+ abort();
+# endif
+ }
}
-OpenCLDevice::OpenCLDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background)
-: Device(info, stats, profiler, background),
- kernel_programs(this),
- preview_programs(this),
- memory_manager(this),
- texture_info(this, "__texture_info", MEM_TEXTURE)
+OpenCLDevice::OpenCLDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background)
+ : Device(info, stats, profiler, background),
+ kernel_programs(this),
+ preview_programs(this),
+ memory_manager(this),
+ texture_info(this, "__texture_info", MEM_TEXTURE)
{
- cpPlatform = NULL;
- cdDevice = NULL;
- cxContext = NULL;
- cqCommandQueue = NULL;
- null_mem = 0;
- device_initialized = false;
- textures_need_update = true;
- use_preview_kernels = !background;
-
- vector<OpenCLPlatformDevice> usable_devices;
- OpenCLInfo::get_usable_devices(&usable_devices);
- if(usable_devices.size() == 0) {
- opencl_error("OpenCL: no devices found.");
- return;
- }
- assert(info.num < usable_devices.size());
- OpenCLPlatformDevice& platform_device = usable_devices[info.num];
- device_num = info.num;
- cpPlatform = platform_device.platform_id;
- cdDevice = platform_device.device_id;
- platform_name = platform_device.platform_name;
- device_name = platform_device.device_name;
- VLOG(2) << "Creating new Cycles device for OpenCL platform "
- << platform_name << ", device "
- << device_name << ".";
-
- {
- /* try to use cached context */
- thread_scoped_lock cache_locker;
- cxContext = OpenCLCache::get_context(cpPlatform, cdDevice, cache_locker);
-
- if(cxContext == NULL) {
- /* create context properties array to specify platform */
- const cl_context_properties context_props[] = {
- CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform,
- 0, 0
- };
-
- /* create context */
- cxContext = clCreateContext(context_props, 1, &cdDevice,
- context_notify_callback, cdDevice, &ciErr);
-
- if(opencl_error(ciErr)) {
- opencl_error("OpenCL: clCreateContext failed");
- return;
- }
-
- /* cache it */
- OpenCLCache::store_context(cpPlatform, cdDevice, cxContext, cache_locker);
- }
- }
-
- cqCommandQueue = clCreateCommandQueue(cxContext, cdDevice, 0, &ciErr);
- if(opencl_error(ciErr)) {
- opencl_error("OpenCL: Error creating command queue");
- return;
- }
-
- null_mem = (device_ptr)clCreateBuffer(cxContext, CL_MEM_READ_ONLY, 1, NULL, &ciErr);
- if(opencl_error(ciErr)) {
- opencl_error("OpenCL: Error creating memory buffer for NULL");
- return;
- }
-
- /* Allocate this right away so that texture_info is placed at offset 0 in the device memory buffers */
- texture_info.resize(1);
- memory_manager.alloc("texture_info", texture_info);
-
- device_initialized = true;
-
- split_kernel = new OpenCLSplitKernel(this);
- if (!background) {
- load_preview_kernels();
- }
+ cpPlatform = NULL;
+ cdDevice = NULL;
+ cxContext = NULL;
+ cqCommandQueue = NULL;
+ null_mem = 0;
+ device_initialized = false;
+ textures_need_update = true;
+ use_preview_kernels = !background;
+
+ vector<OpenCLPlatformDevice> usable_devices;
+ OpenCLInfo::get_usable_devices(&usable_devices);
+ if (usable_devices.size() == 0) {
+ opencl_error("OpenCL: no devices found.");
+ return;
+ }
+ assert(info.num < usable_devices.size());
+ OpenCLPlatformDevice &platform_device = usable_devices[info.num];
+ device_num = info.num;
+ cpPlatform = platform_device.platform_id;
+ cdDevice = platform_device.device_id;
+ platform_name = platform_device.platform_name;
+ device_name = platform_device.device_name;
+ VLOG(2) << "Creating new Cycles device for OpenCL platform " << platform_name << ", device "
+ << device_name << ".";
+
+ {
+ /* try to use cached context */
+ thread_scoped_lock cache_locker;
+ cxContext = OpenCLCache::get_context(cpPlatform, cdDevice, cache_locker);
+
+ if (cxContext == NULL) {
+ /* create context properties array to specify platform */
+ const cl_context_properties context_props[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, 0, 0};
+
+ /* create context */
+ cxContext = clCreateContext(
+ context_props, 1, &cdDevice, context_notify_callback, cdDevice, &ciErr);
+
+ if (opencl_error(ciErr)) {
+ opencl_error("OpenCL: clCreateContext failed");
+ return;
+ }
+
+ /* cache it */
+ OpenCLCache::store_context(cpPlatform, cdDevice, cxContext, cache_locker);
+ }
+ }
+
+ cqCommandQueue = clCreateCommandQueue(cxContext, cdDevice, 0, &ciErr);
+ if (opencl_error(ciErr)) {
+ opencl_error("OpenCL: Error creating command queue");
+ return;
+ }
+
+ null_mem = (device_ptr)clCreateBuffer(cxContext, CL_MEM_READ_ONLY, 1, NULL, &ciErr);
+ if (opencl_error(ciErr)) {
+ opencl_error("OpenCL: Error creating memory buffer for NULL");
+ return;
+ }
+
+ /* Allocate this right away so that texture_info is placed at offset 0 in the device memory buffers */
+ texture_info.resize(1);
+ memory_manager.alloc("texture_info", texture_info);
+
+ device_initialized = true;
+
+ split_kernel = new OpenCLSplitKernel(this);
+ if (!background) {
+ load_preview_kernels();
+ }
}
OpenCLDevice::~OpenCLDevice()
{
- task_pool.stop();
- load_required_kernel_task_pool.stop();
- load_kernel_task_pool.stop();
+ task_pool.stop();
+ load_required_kernel_task_pool.stop();
+ load_kernel_task_pool.stop();
- memory_manager.free();
+ memory_manager.free();
- if(null_mem)
- clReleaseMemObject(CL_MEM_PTR(null_mem));
+ if (null_mem)
+ clReleaseMemObject(CL_MEM_PTR(null_mem));
- ConstMemMap::iterator mt;
- for(mt = const_mem_map.begin(); mt != const_mem_map.end(); mt++) {
- delete mt->second;
- }
+ ConstMemMap::iterator mt;
+ for (mt = const_mem_map.begin(); mt != const_mem_map.end(); mt++) {
+ delete mt->second;
+ }
- base_program.release();
- bake_program.release();
- displace_program.release();
- background_program.release();
- denoising_program.release();
+ base_program.release();
+ bake_program.release();
+ displace_program.release();
+ background_program.release();
+ denoising_program.release();
- if(cqCommandQueue)
- clReleaseCommandQueue(cqCommandQueue);
- if(cxContext)
- clReleaseContext(cxContext);
+ if (cqCommandQueue)
+ clReleaseCommandQueue(cqCommandQueue);
+ if (cxContext)
+ clReleaseContext(cxContext);
- delete split_kernel;
+ delete split_kernel;
}
void CL_CALLBACK OpenCLDevice::context_notify_callback(const char *err_info,
- const void * /*private_info*/, size_t /*cb*/, void *user_data)
+ const void * /*private_info*/,
+ size_t /*cb*/,
+ void *user_data)
{
- string device_name = OpenCLInfo::get_device_name((cl_device_id)user_data);
- fprintf(stderr, "OpenCL error (%s): %s\n", device_name.c_str(), err_info);
+ string device_name = OpenCLInfo::get_device_name((cl_device_id)user_data);
+ fprintf(stderr, "OpenCL error (%s): %s\n", device_name.c_str(), err_info);
}
bool OpenCLDevice::opencl_version_check()
{
- string error;
- if(!OpenCLInfo::platform_version_check(cpPlatform, &error)) {
- opencl_error(error);
- return false;
- }
- if(!OpenCLInfo::device_version_check(cdDevice, &error)) {
- opencl_error(error);
- return false;
- }
- return true;
+ string error;
+ if (!OpenCLInfo::platform_version_check(cpPlatform, &error)) {
+ opencl_error(error);
+ return false;
+ }
+ if (!OpenCLInfo::device_version_check(cdDevice, &error)) {
+ opencl_error(error);
+ return false;
+ }
+ return true;
}
string OpenCLDevice::device_md5_hash(string kernel_custom_build_options)
{
- MD5Hash md5;
- char version[256], driver[256], name[256], vendor[256];
+ MD5Hash md5;
+ char version[256], driver[256], name[256], vendor[256];
- clGetPlatformInfo(cpPlatform, CL_PLATFORM_VENDOR, sizeof(vendor), &vendor, NULL);
- clGetDeviceInfo(cdDevice, CL_DEVICE_VERSION, sizeof(version), &version, NULL);
- clGetDeviceInfo(cdDevice, CL_DEVICE_NAME, sizeof(name), &name, NULL);
- clGetDeviceInfo(cdDevice, CL_DRIVER_VERSION, sizeof(driver), &driver, NULL);
+ clGetPlatformInfo(cpPlatform, CL_PLATFORM_VENDOR, sizeof(vendor), &vendor, NULL);
+ clGetDeviceInfo(cdDevice, CL_DEVICE_VERSION, sizeof(version), &version, NULL);
+ clGetDeviceInfo(cdDevice, CL_DEVICE_NAME, sizeof(name), &name, NULL);
+ clGetDeviceInfo(cdDevice, CL_DRIVER_VERSION, sizeof(driver), &driver, NULL);
- md5.append((uint8_t*)vendor, strlen(vendor));
- md5.append((uint8_t*)version, strlen(version));
- md5.append((uint8_t*)name, strlen(name));
- md5.append((uint8_t*)driver, strlen(driver));
+ md5.append((uint8_t *)vendor, strlen(vendor));
+ md5.append((uint8_t *)version, strlen(version));
+ md5.append((uint8_t *)name, strlen(name));
+ md5.append((uint8_t *)driver, strlen(driver));
- string options = kernel_build_options();
- options += kernel_custom_build_options;
- md5.append((uint8_t*)options.c_str(), options.size());
+ string options = kernel_build_options();
+ options += kernel_custom_build_options;
+ md5.append((uint8_t *)options.c_str(), options.size());
- return md5.get_hex();
+ return md5.get_hex();
}
-bool OpenCLDevice::load_kernels(const DeviceRequestedFeatures& requested_features)
+bool OpenCLDevice::load_kernels(const DeviceRequestedFeatures &requested_features)
{
- VLOG(2) << "Loading kernels for platform " << platform_name
- << ", device " << device_name << ".";
- /* Verify if device was initialized. */
- if(!device_initialized) {
- fprintf(stderr, "OpenCL: failed to initialize device.\n");
- return false;
- }
-
- /* Verify we have right opencl version. */
- if(!opencl_version_check())
- return false;
-
- load_required_kernels(requested_features);
-
- vector<OpenCLProgram*> programs;
- kernel_programs.load_kernels(programs, requested_features, false);
-
- if (!requested_features.use_baking && requested_features.use_denoising) {
- denoising_program = OpenCLProgram(this, "denoising", "filter.cl", get_build_options(requested_features, "denoising"));
- denoising_program.add_kernel(ustring("filter_divide_shadow"));
- denoising_program.add_kernel(ustring("filter_get_feature"));
- denoising_program.add_kernel(ustring("filter_write_feature"));
- denoising_program.add_kernel(ustring("filter_detect_outliers"));
- denoising_program.add_kernel(ustring("filter_combine_halves"));
- denoising_program.add_kernel(ustring("filter_construct_transform"));
- denoising_program.add_kernel(ustring("filter_nlm_calc_difference"));
- denoising_program.add_kernel(ustring("filter_nlm_blur"));
- denoising_program.add_kernel(ustring("filter_nlm_calc_weight"));
- denoising_program.add_kernel(ustring("filter_nlm_update_output"));
- denoising_program.add_kernel(ustring("filter_nlm_normalize"));
- denoising_program.add_kernel(ustring("filter_nlm_construct_gramian"));
- denoising_program.add_kernel(ustring("filter_finalize"));
- programs.push_back(&denoising_program);
- }
-
- load_required_kernel_task_pool.wait_work();
-
- /* Parallel compilation of Cycles kernels, this launches multiple
- * processes to workaround OpenCL frameworks serializing the calls
- * internally within a single process. */
- foreach(OpenCLProgram *program, programs) {
- if (!program->load()) {
- load_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
- }
- }
- return true;
+ VLOG(2) << "Loading kernels for platform " << platform_name << ", device " << device_name << ".";
+ /* Verify if device was initialized. */
+ if (!device_initialized) {
+ fprintf(stderr, "OpenCL: failed to initialize device.\n");
+ return false;
+ }
+
+ /* Verify we have right opencl version. */
+ if (!opencl_version_check())
+ return false;
+
+ load_required_kernels(requested_features);
+
+ vector<OpenCLProgram *> programs;
+ kernel_programs.load_kernels(programs, requested_features, false);
+
+ if (!requested_features.use_baking && requested_features.use_denoising) {
+ denoising_program = OpenCLProgram(
+ this, "denoising", "filter.cl", get_build_options(requested_features, "denoising"));
+ denoising_program.add_kernel(ustring("filter_divide_shadow"));
+ denoising_program.add_kernel(ustring("filter_get_feature"));
+ denoising_program.add_kernel(ustring("filter_write_feature"));
+ denoising_program.add_kernel(ustring("filter_detect_outliers"));
+ denoising_program.add_kernel(ustring("filter_combine_halves"));
+ denoising_program.add_kernel(ustring("filter_construct_transform"));
+ denoising_program.add_kernel(ustring("filter_nlm_calc_difference"));
+ denoising_program.add_kernel(ustring("filter_nlm_blur"));
+ denoising_program.add_kernel(ustring("filter_nlm_calc_weight"));
+ denoising_program.add_kernel(ustring("filter_nlm_update_output"));
+ denoising_program.add_kernel(ustring("filter_nlm_normalize"));
+ denoising_program.add_kernel(ustring("filter_nlm_construct_gramian"));
+ denoising_program.add_kernel(ustring("filter_finalize"));
+ programs.push_back(&denoising_program);
+ }
+
+ load_required_kernel_task_pool.wait_work();
+
+ /* Parallel compilation of Cycles kernels, this launches multiple
+ * processes to workaround OpenCL frameworks serializing the calls
+ * internally within a single process. */
+ foreach (OpenCLProgram *program, programs) {
+ if (!program->load()) {
+ load_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
+ }
+ }
+ return true;
}
-void OpenCLDevice::load_required_kernels(const DeviceRequestedFeatures& requested_features)
+void OpenCLDevice::load_required_kernels(const DeviceRequestedFeatures &requested_features)
{
- vector<OpenCLProgram*> programs;
- base_program = OpenCLProgram(this, "base", "kernel_base.cl", get_build_options(requested_features, "base"));
- base_program.add_kernel(ustring("convert_to_byte"));
- base_program.add_kernel(ustring("convert_to_half_float"));
- base_program.add_kernel(ustring("zero_buffer"));
- programs.push_back(&base_program);
-
- if (requested_features.use_true_displacement) {
- displace_program = OpenCLProgram(this, "displace", "kernel_displace.cl", get_build_options(requested_features, "displace"));
- displace_program.add_kernel(ustring("displace"));
- programs.push_back(&displace_program);
- }
-
- if (requested_features.use_background_light) {
- background_program = OpenCLProgram(this, "background", "kernel_background.cl", get_build_options(requested_features, "background"));
- background_program.add_kernel(ustring("background"));
- programs.push_back(&background_program);
- }
-
- if (requested_features.use_baking) {
- bake_program = OpenCLProgram(this, "bake", "kernel_bake.cl", get_build_options(requested_features, "bake"));
- bake_program.add_kernel(ustring("bake"));
- programs.push_back(&bake_program);
- }
-
- foreach(OpenCLProgram *program, programs) {
- if (!program->load()) {
- load_required_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
- }
- }
+ vector<OpenCLProgram *> programs;
+ base_program = OpenCLProgram(
+ this, "base", "kernel_base.cl", get_build_options(requested_features, "base"));
+ base_program.add_kernel(ustring("convert_to_byte"));
+ base_program.add_kernel(ustring("convert_to_half_float"));
+ base_program.add_kernel(ustring("zero_buffer"));
+ programs.push_back(&base_program);
+
+ if (requested_features.use_true_displacement) {
+ displace_program = OpenCLProgram(
+ this, "displace", "kernel_displace.cl", get_build_options(requested_features, "displace"));
+ displace_program.add_kernel(ustring("displace"));
+ programs.push_back(&displace_program);
+ }
+
+ if (requested_features.use_background_light) {
+ background_program = OpenCLProgram(this,
+ "background",
+ "kernel_background.cl",
+ get_build_options(requested_features, "background"));
+ background_program.add_kernel(ustring("background"));
+ programs.push_back(&background_program);
+ }
+
+ if (requested_features.use_baking) {
+ bake_program = OpenCLProgram(
+ this, "bake", "kernel_bake.cl", get_build_options(requested_features, "bake"));
+ bake_program.add_kernel(ustring("bake"));
+ programs.push_back(&bake_program);
+ }
+
+ foreach (OpenCLProgram *program, programs) {
+ if (!program->load()) {
+ load_required_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
+ }
+ }
}
void OpenCLDevice::load_preview_kernels()
{
- DeviceRequestedFeatures no_features;
- vector<OpenCLProgram*> programs;
- preview_programs.load_kernels(programs, no_features, true);
-
- foreach(OpenCLProgram *program, programs) {
- if (!program->load()) {
- load_required_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
- }
- }
+ DeviceRequestedFeatures no_features;
+ vector<OpenCLProgram *> programs;
+ preview_programs.load_kernels(programs, no_features, true);
+
+ foreach (OpenCLProgram *program, programs) {
+ if (!program->load()) {
+ load_required_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
+ }
+ }
}
-bool OpenCLDevice::wait_for_availability(const DeviceRequestedFeatures& requested_features)
+bool OpenCLDevice::wait_for_availability(const DeviceRequestedFeatures &requested_features)
{
- if (background) {
- load_kernel_task_pool.wait_work();
- use_preview_kernels = false;
- }
- else {
- /* We use a device setting to determine to load preview kernels or not
- * Better to check on device level than per kernel as mixing preview and
- * non-preview kernels does not work due to different data types */
- if (use_preview_kernels) {
- use_preview_kernels = !load_kernel_task_pool.finished();
- }
- }
- return split_kernel->load_kernels(requested_features);
+ if (background) {
+ load_kernel_task_pool.wait_work();
+ use_preview_kernels = false;
+ }
+ else {
+ /* We use a device setting to determine to load preview kernels or not
+ * Better to check on device level than per kernel as mixing preview and
+ * non-preview kernels does not work due to different data types */
+ if (use_preview_kernels) {
+ use_preview_kernels = !load_kernel_task_pool.finished();
+ }
+ }
+ return split_kernel->load_kernels(requested_features);
}
-OpenCLDevice::OpenCLSplitPrograms* OpenCLDevice::get_split_programs()
+OpenCLDevice::OpenCLSplitPrograms *OpenCLDevice::get_split_programs()
{
- return use_preview_kernels?&preview_programs:&kernel_programs;
+ return use_preview_kernels ? &preview_programs : &kernel_programs;
}
DeviceKernelStatus OpenCLDevice::get_active_kernel_switch_state()
{
- /* Do not switch kernels for background renderings
- * We do foreground rendering but use the preview kernels
- * Check for the optimized kernels
- *
- * This works also the other way around, where we are using
- * optimized kernels but new ones are being compiled due
- * to other features that are needed */
- if (background) {
- /* The if-statements below would find the same result,
- * But as the `finished` method uses a mutex we added
- * this as an early exit */
- return DEVICE_KERNEL_USING_FEATURE_KERNEL;
- }
-
- bool other_kernels_finished = load_kernel_task_pool.finished();
- if (use_preview_kernels) {
- if (other_kernels_finished) {
- return DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE;
- }
- else {
- return DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL;
- }
- }
- else {
- if (other_kernels_finished) {
- return DEVICE_KERNEL_USING_FEATURE_KERNEL;
- }
- else {
- return DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
- }
- }
+ /* Do not switch kernels for background renderings
+ * We do foreground rendering but use the preview kernels
+ * Check for the optimized kernels
+ *
+ * This works also the other way around, where we are using
+ * optimized kernels but new ones are being compiled due
+ * to other features that are needed */
+ if (background) {
+ /* The if-statements below would find the same result,
+ * But as the `finished` method uses a mutex we added
+ * this as an early exit */
+ return DEVICE_KERNEL_USING_FEATURE_KERNEL;
+ }
+
+ bool other_kernels_finished = load_kernel_task_pool.finished();
+ if (use_preview_kernels) {
+ if (other_kernels_finished) {
+ return DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE;
+ }
+ else {
+ return DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL;
+ }
+ }
+ else {
+ if (other_kernels_finished) {
+ return DEVICE_KERNEL_USING_FEATURE_KERNEL;
+ }
+ else {
+ return DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
+ }
+ }
}
-void OpenCLDevice::mem_alloc(device_memory& mem)
+void OpenCLDevice::mem_alloc(device_memory &mem)
{
- if(mem.name) {
- VLOG(1) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
- }
-
- size_t size = mem.memory_size();
-
- /* check there is enough memory available for the allocation */
- cl_ulong max_alloc_size = 0;
- clGetDeviceInfo(cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_alloc_size, NULL);
-
- if(DebugFlags().opencl.mem_limit) {
- max_alloc_size = min(max_alloc_size,
- cl_ulong(DebugFlags().opencl.mem_limit - stats.mem_used));
- }
-
- if(size > max_alloc_size) {
- string error = "Scene too complex to fit in available memory.";
- if(mem.name != NULL) {
- error += string_printf(" (allocating buffer %s failed.)", mem.name);
- }
- set_error(error);
-
- return;
- }
-
- cl_mem_flags mem_flag;
- void *mem_ptr = NULL;
-
- if(mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE)
- mem_flag = CL_MEM_READ_ONLY;
- else
- mem_flag = CL_MEM_READ_WRITE;
-
- /* Zero-size allocation might be invoked by render, but not really
- * supported by OpenCL. Using NULL as device pointer also doesn't really
- * work for some reason, so for the time being we'll use special case
- * will null_mem buffer.
- */
- if(size != 0) {
- mem.device_pointer = (device_ptr)clCreateBuffer(cxContext,
- mem_flag,
- size,
- mem_ptr,
- &ciErr);
- opencl_assert_err(ciErr, "clCreateBuffer");
- }
- else {
- mem.device_pointer = null_mem;
- }
-
- stats.mem_alloc(size);
- mem.device_size = size;
+ if (mem.name) {
+ VLOG(1) << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
+ }
+
+ size_t size = mem.memory_size();
+
+ /* check there is enough memory available for the allocation */
+ cl_ulong max_alloc_size = 0;
+ clGetDeviceInfo(cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_alloc_size, NULL);
+
+ if (DebugFlags().opencl.mem_limit) {
+ max_alloc_size = min(max_alloc_size, cl_ulong(DebugFlags().opencl.mem_limit - stats.mem_used));
+ }
+
+ if (size > max_alloc_size) {
+ string error = "Scene too complex to fit in available memory.";
+ if (mem.name != NULL) {
+ error += string_printf(" (allocating buffer %s failed.)", mem.name);
+ }
+ set_error(error);
+
+ return;
+ }
+
+ cl_mem_flags mem_flag;
+ void *mem_ptr = NULL;
+
+ if (mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE)
+ mem_flag = CL_MEM_READ_ONLY;
+ else
+ mem_flag = CL_MEM_READ_WRITE;
+
+ /* Zero-size allocation might be invoked by render, but not really
+ * supported by OpenCL. Using NULL as device pointer also doesn't really
+ * work for some reason, so for the time being we'll use special case
+ * will null_mem buffer.
+ */
+ if (size != 0) {
+ mem.device_pointer = (device_ptr)clCreateBuffer(cxContext, mem_flag, size, mem_ptr, &ciErr);
+ opencl_assert_err(ciErr, "clCreateBuffer");
+ }
+ else {
+ mem.device_pointer = null_mem;
+ }
+
+ stats.mem_alloc(size);
+ mem.device_size = size;
}
-void OpenCLDevice::mem_copy_to(device_memory& mem)
+void OpenCLDevice::mem_copy_to(device_memory &mem)
{
- if(mem.type == MEM_TEXTURE) {
- tex_free(mem);
- tex_alloc(mem);
- }
- else {
- if(!mem.device_pointer) {
- mem_alloc(mem);
- }
-
- /* this is blocking */
- size_t size = mem.memory_size();
- if(size != 0) {
- opencl_assert(clEnqueueWriteBuffer(cqCommandQueue,
- CL_MEM_PTR(mem.device_pointer),
- CL_TRUE,
- 0,
- size,
- mem.host_pointer,
- 0,
- NULL, NULL));
- }
- }
+ if (mem.type == MEM_TEXTURE) {
+ tex_free(mem);
+ tex_alloc(mem);
+ }
+ else {
+ if (!mem.device_pointer) {
+ mem_alloc(mem);
+ }
+
+ /* this is blocking */
+ size_t size = mem.memory_size();
+ if (size != 0) {
+ opencl_assert(clEnqueueWriteBuffer(cqCommandQueue,
+ CL_MEM_PTR(mem.device_pointer),
+ CL_TRUE,
+ 0,
+ size,
+ mem.host_pointer,
+ 0,
+ NULL,
+ NULL));
+ }
+ }
}
-void OpenCLDevice::mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
+void OpenCLDevice::mem_copy_from(device_memory &mem, int y, int w, int h, int elem)
{
- size_t offset = elem*y*w;
- size_t size = elem*w*h;
- assert(size != 0);
- opencl_assert(clEnqueueReadBuffer(cqCommandQueue,
- CL_MEM_PTR(mem.device_pointer),
- CL_TRUE,
- offset,
- size,
- (uchar*)mem.host_pointer + offset,
- 0,
- NULL, NULL));
+ size_t offset = elem * y * w;
+ size_t size = elem * w * h;
+ assert(size != 0);
+ opencl_assert(clEnqueueReadBuffer(cqCommandQueue,
+ CL_MEM_PTR(mem.device_pointer),
+ CL_TRUE,
+ offset,
+ size,
+ (uchar *)mem.host_pointer + offset,
+ 0,
+ NULL,
+ NULL));
}
void OpenCLDevice::mem_zero_kernel(device_ptr mem, size_t size)
{
- base_program.wait_for_availability();
- cl_kernel ckZeroBuffer = base_program(ustring("zero_buffer"));
-
- size_t global_size[] = {1024, 1024};
- size_t num_threads = global_size[0] * global_size[1];
-
- cl_mem d_buffer = CL_MEM_PTR(mem);
- cl_ulong d_offset = 0;
- cl_ulong d_size = 0;
-
- while(d_offset < size) {
- d_size = std::min<cl_ulong>(num_threads*sizeof(float4), size - d_offset);
-
- kernel_set_args(ckZeroBuffer, 0, d_buffer, d_size, d_offset);
-
- ciErr = clEnqueueNDRangeKernel(cqCommandQueue,
- ckZeroBuffer,
- 2,
- NULL,
- global_size,
- NULL,
- 0,
- NULL,
- NULL);
- opencl_assert_err(ciErr, "clEnqueueNDRangeKernel");
-
- d_offset += d_size;
- }
+ base_program.wait_for_availability();
+ cl_kernel ckZeroBuffer = base_program(ustring("zero_buffer"));
+
+ size_t global_size[] = {1024, 1024};
+ size_t num_threads = global_size[0] * global_size[1];
+
+ cl_mem d_buffer = CL_MEM_PTR(mem);
+ cl_ulong d_offset = 0;
+ cl_ulong d_size = 0;
+
+ while (d_offset < size) {
+ d_size = std::min<cl_ulong>(num_threads * sizeof(float4), size - d_offset);
+
+ kernel_set_args(ckZeroBuffer, 0, d_buffer, d_size, d_offset);
+
+ ciErr = clEnqueueNDRangeKernel(
+ cqCommandQueue, ckZeroBuffer, 2, NULL, global_size, NULL, 0, NULL, NULL);
+ opencl_assert_err(ciErr, "clEnqueueNDRangeKernel");
+
+ d_offset += d_size;
+ }
}
-void OpenCLDevice::mem_zero(device_memory& mem)
+void OpenCLDevice::mem_zero(device_memory &mem)
{
- if(!mem.device_pointer) {
- mem_alloc(mem);
- }
-
- if(mem.device_pointer) {
- if(base_program.is_loaded()) {
- mem_zero_kernel(mem.device_pointer, mem.memory_size());
- }
-
- if(mem.host_pointer) {
- memset(mem.host_pointer, 0, mem.memory_size());
- }
-
- if(!base_program.is_loaded()) {
- void* zero = mem.host_pointer;
-
- if(!mem.host_pointer) {
- zero = util_aligned_malloc(mem.memory_size(), 16);
- memset(zero, 0, mem.memory_size());
- }
-
- opencl_assert(clEnqueueWriteBuffer(cqCommandQueue,
- CL_MEM_PTR(mem.device_pointer),
- CL_TRUE,
- 0,
- mem.memory_size(),
- zero,
- 0,
- NULL, NULL));
-
- if(!mem.host_pointer) {
- util_aligned_free(zero);
- }
- }
- }
+ if (!mem.device_pointer) {
+ mem_alloc(mem);
+ }
+
+ if (mem.device_pointer) {
+ if (base_program.is_loaded()) {
+ mem_zero_kernel(mem.device_pointer, mem.memory_size());
+ }
+
+ if (mem.host_pointer) {
+ memset(mem.host_pointer, 0, mem.memory_size());
+ }
+
+ if (!base_program.is_loaded()) {
+ void *zero = mem.host_pointer;
+
+ if (!mem.host_pointer) {
+ zero = util_aligned_malloc(mem.memory_size(), 16);
+ memset(zero, 0, mem.memory_size());
+ }
+
+ opencl_assert(clEnqueueWriteBuffer(cqCommandQueue,
+ CL_MEM_PTR(mem.device_pointer),
+ CL_TRUE,
+ 0,
+ mem.memory_size(),
+ zero,
+ 0,
+ NULL,
+ NULL));
+
+ if (!mem.host_pointer) {
+ util_aligned_free(zero);
+ }
+ }
+ }
}
-void OpenCLDevice::mem_free(device_memory& mem)
+void OpenCLDevice::mem_free(device_memory &mem)
{
- if(mem.type == MEM_TEXTURE) {
- tex_free(mem);
- }
- else {
- if(mem.device_pointer) {
- if(mem.device_pointer != null_mem) {
- opencl_assert(clReleaseMemObject(CL_MEM_PTR(mem.device_pointer)));
- }
- mem.device_pointer = 0;
-
- stats.mem_free(mem.device_size);
- mem.device_size = 0;
- }
- }
+ if (mem.type == MEM_TEXTURE) {
+ tex_free(mem);
+ }
+ else {
+ if (mem.device_pointer) {
+ if (mem.device_pointer != null_mem) {
+ opencl_assert(clReleaseMemObject(CL_MEM_PTR(mem.device_pointer)));
+ }
+ mem.device_pointer = 0;
+
+ stats.mem_free(mem.device_size);
+ mem.device_size = 0;
+ }
+ }
}
int OpenCLDevice::mem_sub_ptr_alignment()
{
- return OpenCLInfo::mem_sub_ptr_alignment(cdDevice);
+ return OpenCLInfo::mem_sub_ptr_alignment(cdDevice);
}
-device_ptr OpenCLDevice::mem_alloc_sub_ptr(device_memory& mem, int offset, int size)
+device_ptr OpenCLDevice::mem_alloc_sub_ptr(device_memory &mem, int offset, int size)
{
- cl_mem_flags mem_flag;
- if(mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE)
- mem_flag = CL_MEM_READ_ONLY;
- else
- mem_flag = CL_MEM_READ_WRITE;
-
- cl_buffer_region info;
- info.origin = mem.memory_elements_size(offset);
- info.size = mem.memory_elements_size(size);
-
- device_ptr sub_buf = (device_ptr) clCreateSubBuffer(CL_MEM_PTR(mem.device_pointer),
- mem_flag,
- CL_BUFFER_CREATE_TYPE_REGION,
- &info,
- &ciErr);
- opencl_assert_err(ciErr, "clCreateSubBuffer");
- return sub_buf;
+ cl_mem_flags mem_flag;
+ if (mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE)
+ mem_flag = CL_MEM_READ_ONLY;
+ else
+ mem_flag = CL_MEM_READ_WRITE;
+
+ cl_buffer_region info;
+ info.origin = mem.memory_elements_size(offset);
+ info.size = mem.memory_elements_size(size);
+
+ device_ptr sub_buf = (device_ptr)clCreateSubBuffer(
+ CL_MEM_PTR(mem.device_pointer), mem_flag, CL_BUFFER_CREATE_TYPE_REGION, &info, &ciErr);
+ opencl_assert_err(ciErr, "clCreateSubBuffer");
+ return sub_buf;
}
void OpenCLDevice::mem_free_sub_ptr(device_ptr device_pointer)
{
- if(device_pointer && device_pointer != null_mem) {
- opencl_assert(clReleaseMemObject(CL_MEM_PTR(device_pointer)));
- }
+ if (device_pointer && device_pointer != null_mem) {
+ opencl_assert(clReleaseMemObject(CL_MEM_PTR(device_pointer)));
+ }
}
void OpenCLDevice::const_copy_to(const char *name, void *host, size_t size)
{
- ConstMemMap::iterator i = const_mem_map.find(name);
- device_vector<uchar> *data;
-
- if(i == const_mem_map.end()) {
- data = new device_vector<uchar>(this, name, MEM_READ_ONLY);
- data->alloc(size);
- const_mem_map.insert(ConstMemMap::value_type(name, data));
- }
- else {
- data = i->second;
- }
-
- memcpy(data->data(), host, size);
- data->copy_to_device();
+ ConstMemMap::iterator i = const_mem_map.find(name);
+ device_vector<uchar> *data;
+
+ if (i == const_mem_map.end()) {
+ data = new device_vector<uchar>(this, name, MEM_READ_ONLY);
+ data->alloc(size);
+ const_mem_map.insert(ConstMemMap::value_type(name, data));
+ }
+ else {
+ data = i->second;
+ }
+
+ memcpy(data->data(), host, size);
+ data->copy_to_device();
}
-void OpenCLDevice::tex_alloc(device_memory& mem)
+void OpenCLDevice::tex_alloc(device_memory &mem)
{
- VLOG(1) << "Texture allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
-
- memory_manager.alloc(mem.name, mem);
- /* Set the pointer to non-null to keep code that inspects its value from thinking its unallocated. */
- mem.device_pointer = 1;
- textures[mem.name] = &mem;
- textures_need_update = true;
+ VLOG(1) << "Texture allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
+
+ memory_manager.alloc(mem.name, mem);
+ /* Set the pointer to non-null to keep code that inspects its value from thinking its unallocated. */
+ mem.device_pointer = 1;
+ textures[mem.name] = &mem;
+ textures_need_update = true;
}
-void OpenCLDevice::tex_free(device_memory& mem)
+void OpenCLDevice::tex_free(device_memory &mem)
{
- if(mem.device_pointer) {
- mem.device_pointer = 0;
-
- if(memory_manager.free(mem)) {
- textures_need_update = true;
- }
-
- foreach(TexturesMap::value_type& value, textures) {
- if(value.second == &mem) {
- textures.erase(value.first);
- break;
- }
- }
- }
+ if (mem.device_pointer) {
+ mem.device_pointer = 0;
+
+ if (memory_manager.free(mem)) {
+ textures_need_update = true;
+ }
+
+ foreach (TexturesMap::value_type &value, textures) {
+ if (value.second == &mem) {
+ textures.erase(value.first);
+ break;
+ }
+ }
+ }
}
size_t OpenCLDevice::global_size_round_up(int group_size, int global_size)
{
- int r = global_size % group_size;
- return global_size + ((r == 0)? 0: group_size - r);
+ int r = global_size % group_size;
+ return global_size + ((r == 0) ? 0 : group_size - r);
}
-void OpenCLDevice::enqueue_kernel(cl_kernel kernel, size_t w, size_t h, bool x_workgroups, size_t max_workgroup_size)
+void OpenCLDevice::enqueue_kernel(
+ cl_kernel kernel, size_t w, size_t h, bool x_workgroups, size_t max_workgroup_size)
{
- size_t workgroup_size, max_work_items[3];
-
- clGetKernelWorkGroupInfo(kernel, cdDevice,
- CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &workgroup_size, NULL);
- clGetDeviceInfo(cdDevice,
- CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t)*3, max_work_items, NULL);
-
- if(max_workgroup_size > 0 && workgroup_size > max_workgroup_size) {
- workgroup_size = max_workgroup_size;
- }
-
- /* Try to divide evenly over 2 dimensions. */
- size_t local_size[2];
- if(x_workgroups) {
- local_size[0] = workgroup_size;
- local_size[1] = 1;
- }
- else {
- size_t sqrt_workgroup_size = max((size_t)sqrt((double)workgroup_size), 1);
- local_size[0] = local_size[1] = sqrt_workgroup_size;
- }
-
- /* Some implementations have max size 1 on 2nd dimension. */
- if(local_size[1] > max_work_items[1]) {
- local_size[0] = workgroup_size/max_work_items[1];
- local_size[1] = max_work_items[1];
- }
-
- size_t global_size[2] = {global_size_round_up(local_size[0], w),
- global_size_round_up(local_size[1], h)};
-
- /* Vertical size of 1 is coming from bake/shade kernels where we should
- * not round anything up because otherwise we'll either be doing too
- * much work per pixel (if we don't check global ID on Y axis) or will
- * be checking for global ID to always have Y of 0.
- */
- if(h == 1) {
- global_size[h] = 1;
- }
-
- /* run kernel */
- opencl_assert(clEnqueueNDRangeKernel(cqCommandQueue, kernel, 2, NULL, global_size, NULL, 0, NULL, NULL));
- opencl_assert(clFlush(cqCommandQueue));
+ size_t workgroup_size, max_work_items[3];
+
+ clGetKernelWorkGroupInfo(
+ kernel, cdDevice, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &workgroup_size, NULL);
+ clGetDeviceInfo(
+ cdDevice, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t) * 3, max_work_items, NULL);
+
+ if (max_workgroup_size > 0 && workgroup_size > max_workgroup_size) {
+ workgroup_size = max_workgroup_size;
+ }
+
+ /* Try to divide evenly over 2 dimensions. */
+ size_t local_size[2];
+ if (x_workgroups) {
+ local_size[0] = workgroup_size;
+ local_size[1] = 1;
+ }
+ else {
+ size_t sqrt_workgroup_size = max((size_t)sqrt((double)workgroup_size), 1);
+ local_size[0] = local_size[1] = sqrt_workgroup_size;
+ }
+
+ /* Some implementations have max size 1 on 2nd dimension. */
+ if (local_size[1] > max_work_items[1]) {
+ local_size[0] = workgroup_size / max_work_items[1];
+ local_size[1] = max_work_items[1];
+ }
+
+ size_t global_size[2] = {global_size_round_up(local_size[0], w),
+ global_size_round_up(local_size[1], h)};
+
+ /* Vertical size of 1 is coming from bake/shade kernels where we should
+ * not round anything up because otherwise we'll either be doing too
+ * much work per pixel (if we don't check global ID on Y axis) or will
+ * be checking for global ID to always have Y of 0.
+ */
+ if (h == 1) {
+ global_size[h] = 1;
+ }
+
+ /* run kernel */
+ opencl_assert(
+ clEnqueueNDRangeKernel(cqCommandQueue, kernel, 2, NULL, global_size, NULL, 0, NULL, NULL));
+ opencl_assert(clFlush(cqCommandQueue));
}
void OpenCLDevice::set_kernel_arg_mem(cl_kernel kernel, cl_uint *narg, const char *name)
{
- cl_mem ptr;
-
- MemMap::iterator i = mem_map.find(name);
- if(i != mem_map.end()) {
- ptr = CL_MEM_PTR(i->second);
- }
- else {
- /* work around NULL not working, even though the spec says otherwise */
- ptr = CL_MEM_PTR(null_mem);
- }
-
- opencl_assert(clSetKernelArg(kernel, (*narg)++, sizeof(ptr), (void*)&ptr));
+ cl_mem ptr;
+
+ MemMap::iterator i = mem_map.find(name);
+ if (i != mem_map.end()) {
+ ptr = CL_MEM_PTR(i->second);
+ }
+ else {
+ /* work around NULL not working, even though the spec says otherwise */
+ ptr = CL_MEM_PTR(null_mem);
+ }
+
+ opencl_assert(clSetKernelArg(kernel, (*narg)++, sizeof(ptr), (void *)&ptr));
}
void OpenCLDevice::set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg)
{
- flush_texture_buffers();
+ flush_texture_buffers();
- memory_manager.set_kernel_arg_buffers(kernel, narg);
+ memory_manager.set_kernel_arg_buffers(kernel, narg);
}
void OpenCLDevice::flush_texture_buffers()
{
- if(!textures_need_update) {
- return;
- }
- textures_need_update = false;
-
- /* Setup slots for textures. */
- int num_slots = 0;
-
- vector<texture_slot_t> texture_slots;
-
-#define KERNEL_TEX(type, name) \
- if(textures.find(#name) != textures.end()) { \
- texture_slots.push_back(texture_slot_t(#name, num_slots)); \
- } \
- num_slots++;
-#include "kernel/kernel_textures.h"
-
- int num_data_slots = num_slots;
-
- foreach(TexturesMap::value_type& tex, textures) {
- string name = tex.first;
-
- if(string_startswith(name, "__tex_image")) {
- int pos = name.rfind("_");
- int id = atoi(name.data() + pos + 1);
- texture_slots.push_back(texture_slot_t(name,
- num_data_slots + id));
- num_slots = max(num_slots, num_data_slots + id + 1);
- }
- }
-
- /* Realloc texture descriptors buffer. */
- memory_manager.free(texture_info);
- texture_info.resize(num_slots);
- memory_manager.alloc("texture_info", texture_info);
-
- /* Fill in descriptors */
- foreach(texture_slot_t& slot, texture_slots) {
- TextureInfo& info = texture_info[slot.slot];
-
- MemoryManager::BufferDescriptor desc = memory_manager.get_descriptor(slot.name);
- info.data = desc.offset;
- info.cl_buffer = desc.device_buffer;
-
- if(string_startswith(slot.name, "__tex_image")) {
- device_memory *mem = textures[slot.name];
-
- info.width = mem->data_width;
- info.height = mem->data_height;
- info.depth = mem->data_depth;
-
- info.interpolation = mem->interpolation;
- info.extension = mem->extension;
- }
- }
-
- /* Force write of descriptors. */
- memory_manager.free(texture_info);
- memory_manager.alloc("texture_info", texture_info);
-}
+ if (!textures_need_update) {
+ return;
+ }
+ textures_need_update = false;
+
+ /* Setup slots for textures. */
+ int num_slots = 0;
+
+ vector<texture_slot_t> texture_slots;
+
+# define KERNEL_TEX(type, name) \
+ if (textures.find(#name) != textures.end()) { \
+ texture_slots.push_back(texture_slot_t(#name, num_slots)); \
+ } \
+ num_slots++;
+# include "kernel/kernel_textures.h"
+
+ int num_data_slots = num_slots;
+
+ foreach (TexturesMap::value_type &tex, textures) {
+ string name = tex.first;
+
+ if (string_startswith(name, "__tex_image")) {
+ int pos = name.rfind("_");
+ int id = atoi(name.data() + pos + 1);
+ texture_slots.push_back(texture_slot_t(name, num_data_slots + id));
+ num_slots = max(num_slots, num_data_slots + id + 1);
+ }
+ }
+
+ /* Realloc texture descriptors buffer. */
+ memory_manager.free(texture_info);
+ texture_info.resize(num_slots);
+ memory_manager.alloc("texture_info", texture_info);
+
+ /* Fill in descriptors */
+ foreach (texture_slot_t &slot, texture_slots) {
+ TextureInfo &info = texture_info[slot.slot];
+
+ MemoryManager::BufferDescriptor desc = memory_manager.get_descriptor(slot.name);
+ info.data = desc.offset;
+ info.cl_buffer = desc.device_buffer;
+ if (string_startswith(slot.name, "__tex_image")) {
+ device_memory *mem = textures[slot.name];
+
+ info.width = mem->data_width;
+ info.height = mem->data_height;
+ info.depth = mem->data_depth;
+
+ info.interpolation = mem->interpolation;
+ info.extension = mem->extension;
+ }
+ }
+
+ /* Force write of descriptors. */
+ memory_manager.free(texture_info);
+ memory_manager.alloc("texture_info", texture_info);
+}
void OpenCLDevice::thread_run(DeviceTask *task)
{
- flush_texture_buffers();
-
- if(task->type == DeviceTask::FILM_CONVERT) {
- film_convert(*task, task->buffer, task->rgba_byte, task->rgba_half);
- }
- else if(task->type == DeviceTask::SHADER) {
- shader(*task);
- }
- else if(task->type == DeviceTask::RENDER) {
- RenderTile tile;
- DenoisingTask denoising(this, *task);
-
- /* Allocate buffer for kernel globals */
- device_only_memory<KernelGlobalsDummy> kgbuffer(this, "kernel_globals");
- kgbuffer.alloc_to_device(1);
-
- /* Keep rendering tiles until done. */
- while(task->acquire_tile(this, tile)) {
- if(tile.task == RenderTile::PATH_TRACE) {
- assert(tile.task == RenderTile::PATH_TRACE);
- scoped_timer timer(&tile.buffers->render_time);
-
- split_kernel->path_trace(task,
- tile,
- kgbuffer,
- *const_mem_map["__data"]);
-
- /* Complete kernel execution before release tile. */
- /* This helps in multi-device render;
- * The device that reaches the critical-section function
- * release_tile waits (stalling other devices from entering
- * release_tile) for all kernels to complete. If device1 (a
- * slow-render device) reaches release_tile first then it would
- * stall device2 (a fast-render device) from proceeding to render
- * next tile.
- */
- clFinish(cqCommandQueue);
- }
- else if(tile.task == RenderTile::DENOISE) {
- tile.sample = tile.start_sample + tile.num_samples;
- denoise(tile, denoising);
- task->update_progress(&tile, tile.w*tile.h);
- }
-
- task->release_tile(tile);
- }
-
- kgbuffer.free();
- }
+ flush_texture_buffers();
+
+ if (task->type == DeviceTask::FILM_CONVERT) {
+ film_convert(*task, task->buffer, task->rgba_byte, task->rgba_half);
+ }
+ else if (task->type == DeviceTask::SHADER) {
+ shader(*task);
+ }
+ else if (task->type == DeviceTask::RENDER) {
+ RenderTile tile;
+ DenoisingTask denoising(this, *task);
+
+ /* Allocate buffer for kernel globals */
+ device_only_memory<KernelGlobalsDummy> kgbuffer(this, "kernel_globals");
+ kgbuffer.alloc_to_device(1);
+
+ /* Keep rendering tiles until done. */
+ while (task->acquire_tile(this, tile)) {
+ if (tile.task == RenderTile::PATH_TRACE) {
+ assert(tile.task == RenderTile::PATH_TRACE);
+ scoped_timer timer(&tile.buffers->render_time);
+
+ split_kernel->path_trace(task, tile, kgbuffer, *const_mem_map["__data"]);
+
+ /* Complete kernel execution before release tile. */
+ /* This helps in multi-device render;
+ * The device that reaches the critical-section function
+ * release_tile waits (stalling other devices from entering
+ * release_tile) for all kernels to complete. If device1 (a
+ * slow-render device) reaches release_tile first then it would
+ * stall device2 (a fast-render device) from proceeding to render
+ * next tile.
+ */
+ clFinish(cqCommandQueue);
+ }
+ else if (tile.task == RenderTile::DENOISE) {
+ tile.sample = tile.start_sample + tile.num_samples;
+ denoise(tile, denoising);
+ task->update_progress(&tile, tile.w * tile.h);
+ }
+
+ task->release_tile(tile);
+ }
+
+ kgbuffer.free();
+ }
}
-void OpenCLDevice::film_convert(DeviceTask& task, device_ptr buffer, device_ptr rgba_byte, device_ptr rgba_half)
+void OpenCLDevice::film_convert(DeviceTask &task,
+ device_ptr buffer,
+ device_ptr rgba_byte,
+ device_ptr rgba_half)
{
- /* cast arguments to cl types */
- cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
- cl_mem d_rgba = (rgba_byte)? CL_MEM_PTR(rgba_byte): CL_MEM_PTR(rgba_half);
- cl_mem d_buffer = CL_MEM_PTR(buffer);
- cl_int d_x = task.x;
- cl_int d_y = task.y;
- cl_int d_w = task.w;
- cl_int d_h = task.h;
- cl_float d_sample_scale = 1.0f/(task.sample + 1);
- cl_int d_offset = task.offset;
- cl_int d_stride = task.stride;
-
-
- cl_kernel ckFilmConvertKernel = (rgba_byte)? base_program(ustring("convert_to_byte")): base_program(ustring("convert_to_half_float"));
-
- cl_uint start_arg_index =
- kernel_set_args(ckFilmConvertKernel,
- 0,
- d_data,
- d_rgba,
- d_buffer);
-
- set_kernel_arg_buffers(ckFilmConvertKernel, &start_arg_index);
-
- start_arg_index += kernel_set_args(ckFilmConvertKernel,
- start_arg_index,
- d_sample_scale,
- d_x,
- d_y,
- d_w,
- d_h,
- d_offset,
- d_stride);
-
- enqueue_kernel(ckFilmConvertKernel, d_w, d_h);
+ /* cast arguments to cl types */
+ cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
+ cl_mem d_rgba = (rgba_byte) ? CL_MEM_PTR(rgba_byte) : CL_MEM_PTR(rgba_half);
+ cl_mem d_buffer = CL_MEM_PTR(buffer);
+ cl_int d_x = task.x;
+ cl_int d_y = task.y;
+ cl_int d_w = task.w;
+ cl_int d_h = task.h;
+ cl_float d_sample_scale = 1.0f / (task.sample + 1);
+ cl_int d_offset = task.offset;
+ cl_int d_stride = task.stride;
+
+ cl_kernel ckFilmConvertKernel = (rgba_byte) ? base_program(ustring("convert_to_byte")) :
+ base_program(ustring("convert_to_half_float"));
+
+ cl_uint start_arg_index = kernel_set_args(ckFilmConvertKernel, 0, d_data, d_rgba, d_buffer);
+
+ set_kernel_arg_buffers(ckFilmConvertKernel, &start_arg_index);
+
+ start_arg_index += kernel_set_args(ckFilmConvertKernel,
+ start_arg_index,
+ d_sample_scale,
+ d_x,
+ d_y,
+ d_w,
+ d_h,
+ d_offset,
+ d_stride);
+
+ enqueue_kernel(ckFilmConvertKernel, d_w, d_h);
}
bool OpenCLDevice::denoising_non_local_means(device_ptr image_ptr,
@@ -1419,123 +1406,119 @@ bool OpenCLDevice::denoising_non_local_means(device_ptr image_ptr,
device_ptr out_ptr,
DenoisingTask *task)
{
- int stride = task->buffer.stride;
- int w = task->buffer.width;
- int h = task->buffer.h;
- int r = task->nlm_state.r;
- int f = task->nlm_state.f;
- float a = task->nlm_state.a;
- float k_2 = task->nlm_state.k_2;
-
- int pass_stride = task->buffer.pass_stride;
- int num_shifts = (2*r+1)*(2*r+1);
- int channel_offset = task->nlm_state.is_color? task->buffer.pass_stride : 0;
-
- device_sub_ptr difference(task->buffer.temporary_mem, 0, pass_stride*num_shifts);
- device_sub_ptr blurDifference(task->buffer.temporary_mem, pass_stride*num_shifts, pass_stride*num_shifts);
- device_sub_ptr weightAccum(task->buffer.temporary_mem, 2*pass_stride*num_shifts, pass_stride);
- cl_mem weightAccum_mem = CL_MEM_PTR(*weightAccum);
- cl_mem difference_mem = CL_MEM_PTR(*difference);
- cl_mem blurDifference_mem = CL_MEM_PTR(*blurDifference);
-
- cl_mem image_mem = CL_MEM_PTR(image_ptr);
- cl_mem guide_mem = CL_MEM_PTR(guide_ptr);
- cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
- cl_mem out_mem = CL_MEM_PTR(out_ptr);
- cl_mem scale_mem = NULL;
-
- mem_zero_kernel(*weightAccum, sizeof(float)*pass_stride);
- mem_zero_kernel(out_ptr, sizeof(float)*pass_stride);
-
- cl_kernel ckNLMCalcDifference = denoising_program(ustring("filter_nlm_calc_difference"));
- cl_kernel ckNLMBlur = denoising_program(ustring("filter_nlm_blur"));
- cl_kernel ckNLMCalcWeight = denoising_program(ustring("filter_nlm_calc_weight"));
- cl_kernel ckNLMUpdateOutput = denoising_program(ustring("filter_nlm_update_output"));
- cl_kernel ckNLMNormalize = denoising_program(ustring("filter_nlm_normalize"));
-
- kernel_set_args(ckNLMCalcDifference, 0,
- guide_mem,
- variance_mem,
- scale_mem,
- difference_mem,
- w, h, stride,
- pass_stride,
- r, channel_offset,
- 0, a, k_2);
- kernel_set_args(ckNLMBlur, 0,
- difference_mem,
- blurDifference_mem,
- w, h, stride,
- pass_stride,
- r, f);
- kernel_set_args(ckNLMCalcWeight, 0,
- blurDifference_mem,
- difference_mem,
- w, h, stride,
- pass_stride,
- r, f);
- kernel_set_args(ckNLMUpdateOutput, 0,
- blurDifference_mem,
- image_mem,
- out_mem,
- weightAccum_mem,
- w, h, stride,
- pass_stride,
- channel_offset,
- r, f);
-
- enqueue_kernel(ckNLMCalcDifference, w*h, num_shifts, true);
- enqueue_kernel(ckNLMBlur, w*h, num_shifts, true);
- enqueue_kernel(ckNLMCalcWeight, w*h, num_shifts, true);
- enqueue_kernel(ckNLMBlur, w*h, num_shifts, true);
- enqueue_kernel(ckNLMUpdateOutput, w*h, num_shifts, true);
-
- kernel_set_args(ckNLMNormalize, 0,
- out_mem, weightAccum_mem, w, h, stride);
- enqueue_kernel(ckNLMNormalize, w, h);
-
- return true;
+ int stride = task->buffer.stride;
+ int w = task->buffer.width;
+ int h = task->buffer.h;
+ int r = task->nlm_state.r;
+ int f = task->nlm_state.f;
+ float a = task->nlm_state.a;
+ float k_2 = task->nlm_state.k_2;
+
+ int pass_stride = task->buffer.pass_stride;
+ int num_shifts = (2 * r + 1) * (2 * r + 1);
+ int channel_offset = task->nlm_state.is_color ? task->buffer.pass_stride : 0;
+
+ device_sub_ptr difference(task->buffer.temporary_mem, 0, pass_stride * num_shifts);
+ device_sub_ptr blurDifference(
+ task->buffer.temporary_mem, pass_stride * num_shifts, pass_stride * num_shifts);
+ device_sub_ptr weightAccum(
+ task->buffer.temporary_mem, 2 * pass_stride * num_shifts, pass_stride);
+ cl_mem weightAccum_mem = CL_MEM_PTR(*weightAccum);
+ cl_mem difference_mem = CL_MEM_PTR(*difference);
+ cl_mem blurDifference_mem = CL_MEM_PTR(*blurDifference);
+
+ cl_mem image_mem = CL_MEM_PTR(image_ptr);
+ cl_mem guide_mem = CL_MEM_PTR(guide_ptr);
+ cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
+ cl_mem out_mem = CL_MEM_PTR(out_ptr);
+ cl_mem scale_mem = NULL;
+
+ mem_zero_kernel(*weightAccum, sizeof(float) * pass_stride);
+ mem_zero_kernel(out_ptr, sizeof(float) * pass_stride);
+
+ cl_kernel ckNLMCalcDifference = denoising_program(ustring("filter_nlm_calc_difference"));
+ cl_kernel ckNLMBlur = denoising_program(ustring("filter_nlm_blur"));
+ cl_kernel ckNLMCalcWeight = denoising_program(ustring("filter_nlm_calc_weight"));
+ cl_kernel ckNLMUpdateOutput = denoising_program(ustring("filter_nlm_update_output"));
+ cl_kernel ckNLMNormalize = denoising_program(ustring("filter_nlm_normalize"));
+
+ kernel_set_args(ckNLMCalcDifference,
+ 0,
+ guide_mem,
+ variance_mem,
+ scale_mem,
+ difference_mem,
+ w,
+ h,
+ stride,
+ pass_stride,
+ r,
+ channel_offset,
+ 0,
+ a,
+ k_2);
+ kernel_set_args(
+ ckNLMBlur, 0, difference_mem, blurDifference_mem, w, h, stride, pass_stride, r, f);
+ kernel_set_args(
+ ckNLMCalcWeight, 0, blurDifference_mem, difference_mem, w, h, stride, pass_stride, r, f);
+ kernel_set_args(ckNLMUpdateOutput,
+ 0,
+ blurDifference_mem,
+ image_mem,
+ out_mem,
+ weightAccum_mem,
+ w,
+ h,
+ stride,
+ pass_stride,
+ channel_offset,
+ r,
+ f);
+
+ enqueue_kernel(ckNLMCalcDifference, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMBlur, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMCalcWeight, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMBlur, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMUpdateOutput, w * h, num_shifts, true);
+
+ kernel_set_args(ckNLMNormalize, 0, out_mem, weightAccum_mem, w, h, stride);
+ enqueue_kernel(ckNLMNormalize, w, h);
+
+ return true;
}
bool OpenCLDevice::denoising_construct_transform(DenoisingTask *task)
{
- cl_mem buffer_mem = CL_MEM_PTR(task->buffer.mem.device_pointer);
- cl_mem transform_mem = CL_MEM_PTR(task->storage.transform.device_pointer);
- cl_mem rank_mem = CL_MEM_PTR(task->storage.rank.device_pointer);
- cl_mem tile_info_mem = CL_MEM_PTR(task->tile_info_mem.device_pointer);
-
- char use_time = task->buffer.use_time? 1 : 0;
-
- cl_kernel ckFilterConstructTransform = denoising_program(ustring("filter_construct_transform"));
-
- int arg_ofs = kernel_set_args(ckFilterConstructTransform, 0,
- buffer_mem,
- tile_info_mem);
- cl_mem buffers[9];
- for(int i = 0; i < 9; i++) {
- buffers[i] = CL_MEM_PTR(task->tile_info->buffers[i]);
- arg_ofs += kernel_set_args(ckFilterConstructTransform,
- arg_ofs,
- buffers[i]);
- }
- kernel_set_args(ckFilterConstructTransform,
- arg_ofs,
- transform_mem,
- rank_mem,
- task->filter_area,
- task->rect,
- task->buffer.pass_stride,
- task->buffer.frame_stride,
- use_time,
- task->radius,
- task->pca_threshold);
-
- enqueue_kernel(ckFilterConstructTransform,
- task->storage.w,
- task->storage.h,
- 256);
-
- return true;
+ cl_mem buffer_mem = CL_MEM_PTR(task->buffer.mem.device_pointer);
+ cl_mem transform_mem = CL_MEM_PTR(task->storage.transform.device_pointer);
+ cl_mem rank_mem = CL_MEM_PTR(task->storage.rank.device_pointer);
+ cl_mem tile_info_mem = CL_MEM_PTR(task->tile_info_mem.device_pointer);
+
+ char use_time = task->buffer.use_time ? 1 : 0;
+
+ cl_kernel ckFilterConstructTransform = denoising_program(ustring("filter_construct_transform"));
+
+ int arg_ofs = kernel_set_args(ckFilterConstructTransform, 0, buffer_mem, tile_info_mem);
+ cl_mem buffers[9];
+ for (int i = 0; i < 9; i++) {
+ buffers[i] = CL_MEM_PTR(task->tile_info->buffers[i]);
+ arg_ofs += kernel_set_args(ckFilterConstructTransform, arg_ofs, buffers[i]);
+ }
+ kernel_set_args(ckFilterConstructTransform,
+ arg_ofs,
+ transform_mem,
+ rank_mem,
+ task->filter_area,
+ task->rect,
+ task->buffer.pass_stride,
+ task->buffer.frame_stride,
+ use_time,
+ task->radius,
+ task->pca_threshold);
+
+ enqueue_kernel(ckFilterConstructTransform, task->storage.w, task->storage.h, 256);
+
+ return true;
}
bool OpenCLDevice::denoising_accumulate(device_ptr color_ptr,
@@ -1544,136 +1527,130 @@ bool OpenCLDevice::denoising_accumulate(device_ptr color_ptr,
int frame,
DenoisingTask *task)
{
- cl_mem color_mem = CL_MEM_PTR(color_ptr);
- cl_mem color_variance_mem = CL_MEM_PTR(color_variance_ptr);
- cl_mem scale_mem = CL_MEM_PTR(scale_ptr);
-
- cl_mem buffer_mem = CL_MEM_PTR(task->buffer.mem.device_pointer);
- cl_mem transform_mem = CL_MEM_PTR(task->storage.transform.device_pointer);
- cl_mem rank_mem = CL_MEM_PTR(task->storage.rank.device_pointer);
- cl_mem XtWX_mem = CL_MEM_PTR(task->storage.XtWX.device_pointer);
- cl_mem XtWY_mem = CL_MEM_PTR(task->storage.XtWY.device_pointer);
-
- cl_kernel ckNLMCalcDifference = denoising_program(ustring("filter_nlm_calc_difference"));
- cl_kernel ckNLMBlur = denoising_program(ustring("filter_nlm_blur"));
- cl_kernel ckNLMCalcWeight = denoising_program(ustring("filter_nlm_calc_weight"));
- cl_kernel ckNLMConstructGramian = denoising_program(ustring("filter_nlm_construct_gramian"));
-
- int w = task->reconstruction_state.source_w;
- int h = task->reconstruction_state.source_h;
- int stride = task->buffer.stride;
- int frame_offset = frame * task->buffer.frame_stride;
- int t = task->tile_info->frames[frame];
- char use_time = task->buffer.use_time? 1 : 0;
-
- int r = task->radius;
- int pass_stride = task->buffer.pass_stride;
- int num_shifts = (2*r+1)*(2*r+1);
-
- device_sub_ptr difference(task->buffer.temporary_mem, 0, pass_stride*num_shifts);
- device_sub_ptr blurDifference(task->buffer.temporary_mem, pass_stride*num_shifts, pass_stride*num_shifts);
- cl_mem difference_mem = CL_MEM_PTR(*difference);
- cl_mem blurDifference_mem = CL_MEM_PTR(*blurDifference);
-
- kernel_set_args(ckNLMCalcDifference, 0,
- color_mem,
- color_variance_mem,
- scale_mem,
- difference_mem,
- w, h, stride,
- pass_stride,
- r,
- pass_stride,
- frame_offset,
- 1.0f, task->nlm_k_2);
- kernel_set_args(ckNLMBlur, 0,
- difference_mem,
- blurDifference_mem,
- w, h, stride,
- pass_stride,
- r, 4);
- kernel_set_args(ckNLMCalcWeight, 0,
- blurDifference_mem,
- difference_mem,
- w, h, stride,
- pass_stride,
- r, 4);
- kernel_set_args(ckNLMConstructGramian, 0,
- t,
- blurDifference_mem,
- buffer_mem,
- transform_mem,
- rank_mem,
- XtWX_mem,
- XtWY_mem,
- task->reconstruction_state.filter_window,
- w, h, stride,
- pass_stride,
- r, 4,
- frame_offset,
- use_time);
-
- enqueue_kernel(ckNLMCalcDifference, w*h, num_shifts, true);
- enqueue_kernel(ckNLMBlur, w*h, num_shifts, true);
- enqueue_kernel(ckNLMCalcWeight, w*h, num_shifts, true);
- enqueue_kernel(ckNLMBlur, w*h, num_shifts, true);
- enqueue_kernel(ckNLMConstructGramian, w*h, num_shifts, true, 256);
-
- return true;
+ cl_mem color_mem = CL_MEM_PTR(color_ptr);
+ cl_mem color_variance_mem = CL_MEM_PTR(color_variance_ptr);
+ cl_mem scale_mem = CL_MEM_PTR(scale_ptr);
+
+ cl_mem buffer_mem = CL_MEM_PTR(task->buffer.mem.device_pointer);
+ cl_mem transform_mem = CL_MEM_PTR(task->storage.transform.device_pointer);
+ cl_mem rank_mem = CL_MEM_PTR(task->storage.rank.device_pointer);
+ cl_mem XtWX_mem = CL_MEM_PTR(task->storage.XtWX.device_pointer);
+ cl_mem XtWY_mem = CL_MEM_PTR(task->storage.XtWY.device_pointer);
+
+ cl_kernel ckNLMCalcDifference = denoising_program(ustring("filter_nlm_calc_difference"));
+ cl_kernel ckNLMBlur = denoising_program(ustring("filter_nlm_blur"));
+ cl_kernel ckNLMCalcWeight = denoising_program(ustring("filter_nlm_calc_weight"));
+ cl_kernel ckNLMConstructGramian = denoising_program(ustring("filter_nlm_construct_gramian"));
+
+ int w = task->reconstruction_state.source_w;
+ int h = task->reconstruction_state.source_h;
+ int stride = task->buffer.stride;
+ int frame_offset = frame * task->buffer.frame_stride;
+ int t = task->tile_info->frames[frame];
+ char use_time = task->buffer.use_time ? 1 : 0;
+
+ int r = task->radius;
+ int pass_stride = task->buffer.pass_stride;
+ int num_shifts = (2 * r + 1) * (2 * r + 1);
+
+ device_sub_ptr difference(task->buffer.temporary_mem, 0, pass_stride * num_shifts);
+ device_sub_ptr blurDifference(
+ task->buffer.temporary_mem, pass_stride * num_shifts, pass_stride * num_shifts);
+ cl_mem difference_mem = CL_MEM_PTR(*difference);
+ cl_mem blurDifference_mem = CL_MEM_PTR(*blurDifference);
+
+ kernel_set_args(ckNLMCalcDifference,
+ 0,
+ color_mem,
+ color_variance_mem,
+ scale_mem,
+ difference_mem,
+ w,
+ h,
+ stride,
+ pass_stride,
+ r,
+ pass_stride,
+ frame_offset,
+ 1.0f,
+ task->nlm_k_2);
+ kernel_set_args(
+ ckNLMBlur, 0, difference_mem, blurDifference_mem, w, h, stride, pass_stride, r, 4);
+ kernel_set_args(
+ ckNLMCalcWeight, 0, blurDifference_mem, difference_mem, w, h, stride, pass_stride, r, 4);
+ kernel_set_args(ckNLMConstructGramian,
+ 0,
+ t,
+ blurDifference_mem,
+ buffer_mem,
+ transform_mem,
+ rank_mem,
+ XtWX_mem,
+ XtWY_mem,
+ task->reconstruction_state.filter_window,
+ w,
+ h,
+ stride,
+ pass_stride,
+ r,
+ 4,
+ frame_offset,
+ use_time);
+
+ enqueue_kernel(ckNLMCalcDifference, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMBlur, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMCalcWeight, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMBlur, w * h, num_shifts, true);
+ enqueue_kernel(ckNLMConstructGramian, w * h, num_shifts, true, 256);
+
+ return true;
}
-bool OpenCLDevice::denoising_solve(device_ptr output_ptr,
- DenoisingTask *task)
+bool OpenCLDevice::denoising_solve(device_ptr output_ptr, DenoisingTask *task)
{
- cl_kernel ckFinalize = denoising_program(ustring("filter_finalize"));
-
- cl_mem output_mem = CL_MEM_PTR(output_ptr);
- cl_mem rank_mem = CL_MEM_PTR(task->storage.rank.device_pointer);
- cl_mem XtWX_mem = CL_MEM_PTR(task->storage.XtWX.device_pointer);
- cl_mem XtWY_mem = CL_MEM_PTR(task->storage.XtWY.device_pointer);
-
- int w = task->reconstruction_state.source_w;
- int h = task->reconstruction_state.source_h;
-
- kernel_set_args(ckFinalize, 0,
- output_mem,
- rank_mem,
- XtWX_mem,
- XtWY_mem,
- task->filter_area,
- task->reconstruction_state.buffer_params,
- task->render_buffer.samples);
- enqueue_kernel(ckFinalize, w, h);
-
- return true;
+ cl_kernel ckFinalize = denoising_program(ustring("filter_finalize"));
+
+ cl_mem output_mem = CL_MEM_PTR(output_ptr);
+ cl_mem rank_mem = CL_MEM_PTR(task->storage.rank.device_pointer);
+ cl_mem XtWX_mem = CL_MEM_PTR(task->storage.XtWX.device_pointer);
+ cl_mem XtWY_mem = CL_MEM_PTR(task->storage.XtWY.device_pointer);
+
+ int w = task->reconstruction_state.source_w;
+ int h = task->reconstruction_state.source_h;
+
+ kernel_set_args(ckFinalize,
+ 0,
+ output_mem,
+ rank_mem,
+ XtWX_mem,
+ XtWY_mem,
+ task->filter_area,
+ task->reconstruction_state.buffer_params,
+ task->render_buffer.samples);
+ enqueue_kernel(ckFinalize, w, h);
+
+ return true;
}
bool OpenCLDevice::denoising_combine_halves(device_ptr a_ptr,
device_ptr b_ptr,
device_ptr mean_ptr,
device_ptr variance_ptr,
- int r, int4 rect,
+ int r,
+ int4 rect,
DenoisingTask *task)
{
- cl_mem a_mem = CL_MEM_PTR(a_ptr);
- cl_mem b_mem = CL_MEM_PTR(b_ptr);
- cl_mem mean_mem = CL_MEM_PTR(mean_ptr);
- cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
-
- cl_kernel ckFilterCombineHalves = denoising_program(ustring("filter_combine_halves"));
-
- kernel_set_args(ckFilterCombineHalves, 0,
- mean_mem,
- variance_mem,
- a_mem,
- b_mem,
- rect,
- r);
- enqueue_kernel(ckFilterCombineHalves,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- return true;
+ cl_mem a_mem = CL_MEM_PTR(a_ptr);
+ cl_mem b_mem = CL_MEM_PTR(b_ptr);
+ cl_mem mean_mem = CL_MEM_PTR(mean_ptr);
+ cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
+
+ cl_kernel ckFilterCombineHalves = denoising_program(ustring("filter_combine_halves"));
+
+ kernel_set_args(ckFilterCombineHalves, 0, mean_mem, variance_mem, a_mem, b_mem, rect, r);
+ enqueue_kernel(ckFilterCombineHalves, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ return true;
}
bool OpenCLDevice::denoising_divide_shadow(device_ptr a_ptr,
@@ -1683,39 +1660,36 @@ bool OpenCLDevice::denoising_divide_shadow(device_ptr a_ptr,
device_ptr buffer_variance_ptr,
DenoisingTask *task)
{
- cl_mem a_mem = CL_MEM_PTR(a_ptr);
- cl_mem b_mem = CL_MEM_PTR(b_ptr);
- cl_mem sample_variance_mem = CL_MEM_PTR(sample_variance_ptr);
- cl_mem sv_variance_mem = CL_MEM_PTR(sv_variance_ptr);
- cl_mem buffer_variance_mem = CL_MEM_PTR(buffer_variance_ptr);
-
- cl_mem tile_info_mem = CL_MEM_PTR(task->tile_info_mem.device_pointer);
-
- cl_kernel ckFilterDivideShadow = denoising_program(ustring("filter_divide_shadow"));
-
- int arg_ofs = kernel_set_args(ckFilterDivideShadow, 0,
- task->render_buffer.samples,
- tile_info_mem);
- cl_mem buffers[9];
- for(int i = 0; i < 9; i++) {
- buffers[i] = CL_MEM_PTR(task->tile_info->buffers[i]);
- arg_ofs += kernel_set_args(ckFilterDivideShadow, arg_ofs,
- buffers[i]);
- }
- kernel_set_args(ckFilterDivideShadow, arg_ofs,
- a_mem,
- b_mem,
- sample_variance_mem,
- sv_variance_mem,
- buffer_variance_mem,
- task->rect,
- task->render_buffer.pass_stride,
- task->render_buffer.offset);
- enqueue_kernel(ckFilterDivideShadow,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- return true;
+ cl_mem a_mem = CL_MEM_PTR(a_ptr);
+ cl_mem b_mem = CL_MEM_PTR(b_ptr);
+ cl_mem sample_variance_mem = CL_MEM_PTR(sample_variance_ptr);
+ cl_mem sv_variance_mem = CL_MEM_PTR(sv_variance_ptr);
+ cl_mem buffer_variance_mem = CL_MEM_PTR(buffer_variance_ptr);
+
+ cl_mem tile_info_mem = CL_MEM_PTR(task->tile_info_mem.device_pointer);
+
+ cl_kernel ckFilterDivideShadow = denoising_program(ustring("filter_divide_shadow"));
+
+ int arg_ofs = kernel_set_args(
+ ckFilterDivideShadow, 0, task->render_buffer.samples, tile_info_mem);
+ cl_mem buffers[9];
+ for (int i = 0; i < 9; i++) {
+ buffers[i] = CL_MEM_PTR(task->tile_info->buffers[i]);
+ arg_ofs += kernel_set_args(ckFilterDivideShadow, arg_ofs, buffers[i]);
+ }
+ kernel_set_args(ckFilterDivideShadow,
+ arg_ofs,
+ a_mem,
+ b_mem,
+ sample_variance_mem,
+ sv_variance_mem,
+ buffer_variance_mem,
+ task->rect,
+ task->render_buffer.pass_stride,
+ task->render_buffer.offset);
+ enqueue_kernel(ckFilterDivideShadow, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ return true;
}
bool OpenCLDevice::denoising_get_feature(int mean_offset,
@@ -1725,36 +1699,32 @@ bool OpenCLDevice::denoising_get_feature(int mean_offset,
float scale,
DenoisingTask *task)
{
- cl_mem mean_mem = CL_MEM_PTR(mean_ptr);
- cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
-
- cl_mem tile_info_mem = CL_MEM_PTR(task->tile_info_mem.device_pointer);
-
- cl_kernel ckFilterGetFeature = denoising_program(ustring("filter_get_feature"));
-
- int arg_ofs = kernel_set_args(ckFilterGetFeature, 0,
- task->render_buffer.samples,
- tile_info_mem);
- cl_mem buffers[9];
- for(int i = 0; i < 9; i++) {
- buffers[i] = CL_MEM_PTR(task->tile_info->buffers[i]);
- arg_ofs += kernel_set_args(ckFilterGetFeature, arg_ofs,
- buffers[i]);
- }
- kernel_set_args(ckFilterGetFeature, arg_ofs,
- mean_offset,
- variance_offset,
- mean_mem,
- variance_mem,
- scale,
- task->rect,
- task->render_buffer.pass_stride,
- task->render_buffer.offset);
- enqueue_kernel(ckFilterGetFeature,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- return true;
+ cl_mem mean_mem = CL_MEM_PTR(mean_ptr);
+ cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
+
+ cl_mem tile_info_mem = CL_MEM_PTR(task->tile_info_mem.device_pointer);
+
+ cl_kernel ckFilterGetFeature = denoising_program(ustring("filter_get_feature"));
+
+ int arg_ofs = kernel_set_args(ckFilterGetFeature, 0, task->render_buffer.samples, tile_info_mem);
+ cl_mem buffers[9];
+ for (int i = 0; i < 9; i++) {
+ buffers[i] = CL_MEM_PTR(task->tile_info->buffers[i]);
+ arg_ofs += kernel_set_args(ckFilterGetFeature, arg_ofs, buffers[i]);
+ }
+ kernel_set_args(ckFilterGetFeature,
+ arg_ofs,
+ mean_offset,
+ variance_offset,
+ mean_mem,
+ variance_mem,
+ scale,
+ task->rect,
+ task->render_buffer.pass_stride,
+ task->render_buffer.offset);
+ enqueue_kernel(ckFilterGetFeature, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ return true;
}
bool OpenCLDevice::denoising_write_feature(int out_offset,
@@ -1762,24 +1732,23 @@ bool OpenCLDevice::denoising_write_feature(int out_offset,
device_ptr buffer_ptr,
DenoisingTask *task)
{
- cl_mem from_mem = CL_MEM_PTR(from_ptr);
- cl_mem buffer_mem = CL_MEM_PTR(buffer_ptr);
-
- cl_kernel ckFilterWriteFeature = denoising_program(ustring("filter_write_feature"));
-
- kernel_set_args(ckFilterWriteFeature, 0,
- task->render_buffer.samples,
- task->reconstruction_state.buffer_params,
- task->filter_area,
- from_mem,
- buffer_mem,
- out_offset,
- task->rect);
- enqueue_kernel(ckFilterWriteFeature,
- task->filter_area.z,
- task->filter_area.w);
-
- return true;
+ cl_mem from_mem = CL_MEM_PTR(from_ptr);
+ cl_mem buffer_mem = CL_MEM_PTR(buffer_ptr);
+
+ cl_kernel ckFilterWriteFeature = denoising_program(ustring("filter_write_feature"));
+
+ kernel_set_args(ckFilterWriteFeature,
+ 0,
+ task->render_buffer.samples,
+ task->reconstruction_state.buffer_params,
+ task->filter_area,
+ from_mem,
+ buffer_mem,
+ out_offset,
+ task->rect);
+ enqueue_kernel(ckFilterWriteFeature, task->filter_area.z, task->filter_area.w);
+
+ return true;
}
bool OpenCLDevice::denoising_detect_outliers(device_ptr image_ptr,
@@ -1788,155 +1757,155 @@ bool OpenCLDevice::denoising_detect_outliers(device_ptr image_ptr,
device_ptr output_ptr,
DenoisingTask *task)
{
- cl_mem image_mem = CL_MEM_PTR(image_ptr);
- cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
- cl_mem depth_mem = CL_MEM_PTR(depth_ptr);
- cl_mem output_mem = CL_MEM_PTR(output_ptr);
-
- cl_kernel ckFilterDetectOutliers = denoising_program(ustring("filter_detect_outliers"));
-
- kernel_set_args(ckFilterDetectOutliers, 0,
- image_mem,
- variance_mem,
- depth_mem,
- output_mem,
- task->rect,
- task->buffer.pass_stride);
- enqueue_kernel(ckFilterDetectOutliers,
- task->rect.z-task->rect.x,
- task->rect.w-task->rect.y);
-
- return true;
+ cl_mem image_mem = CL_MEM_PTR(image_ptr);
+ cl_mem variance_mem = CL_MEM_PTR(variance_ptr);
+ cl_mem depth_mem = CL_MEM_PTR(depth_ptr);
+ cl_mem output_mem = CL_MEM_PTR(output_ptr);
+
+ cl_kernel ckFilterDetectOutliers = denoising_program(ustring("filter_detect_outliers"));
+
+ kernel_set_args(ckFilterDetectOutliers,
+ 0,
+ image_mem,
+ variance_mem,
+ depth_mem,
+ output_mem,
+ task->rect,
+ task->buffer.pass_stride);
+ enqueue_kernel(ckFilterDetectOutliers, task->rect.z - task->rect.x, task->rect.w - task->rect.y);
+
+ return true;
}
-void OpenCLDevice::denoise(RenderTile &rtile, DenoisingTask& denoising)
+void OpenCLDevice::denoise(RenderTile &rtile, DenoisingTask &denoising)
{
- denoising.functions.construct_transform = function_bind(&OpenCLDevice::denoising_construct_transform, this, &denoising);
- denoising.functions.accumulate = function_bind(&OpenCLDevice::denoising_accumulate, this, _1, _2, _3, _4, &denoising);
- denoising.functions.solve = function_bind(&OpenCLDevice::denoising_solve, this, _1, &denoising);
- denoising.functions.divide_shadow = function_bind(&OpenCLDevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising);
- denoising.functions.non_local_means = function_bind(&OpenCLDevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising);
- denoising.functions.combine_halves = function_bind(&OpenCLDevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising);
- denoising.functions.get_feature = function_bind(&OpenCLDevice::denoising_get_feature, this, _1, _2, _3, _4, _5, &denoising);
- denoising.functions.write_feature = function_bind(&OpenCLDevice::denoising_write_feature, this, _1, _2, _3, &denoising);
- denoising.functions.detect_outliers = function_bind(&OpenCLDevice::denoising_detect_outliers, this, _1, _2, _3, _4, &denoising);
-
- denoising.filter_area = make_int4(rtile.x, rtile.y, rtile.w, rtile.h);
- denoising.render_buffer.samples = rtile.sample;
- denoising.buffer.gpu_temporary_mem = true;
-
- denoising.run_denoising(&rtile);
+ denoising.functions.construct_transform = function_bind(
+ &OpenCLDevice::denoising_construct_transform, this, &denoising);
+ denoising.functions.accumulate = function_bind(
+ &OpenCLDevice::denoising_accumulate, this, _1, _2, _3, _4, &denoising);
+ denoising.functions.solve = function_bind(&OpenCLDevice::denoising_solve, this, _1, &denoising);
+ denoising.functions.divide_shadow = function_bind(
+ &OpenCLDevice::denoising_divide_shadow, this, _1, _2, _3, _4, _5, &denoising);
+ denoising.functions.non_local_means = function_bind(
+ &OpenCLDevice::denoising_non_local_means, this, _1, _2, _3, _4, &denoising);
+ denoising.functions.combine_halves = function_bind(
+ &OpenCLDevice::denoising_combine_halves, this, _1, _2, _3, _4, _5, _6, &denoising);
+ denoising.functions.get_feature = function_bind(
+ &OpenCLDevice::denoising_get_feature, this, _1, _2, _3, _4, _5, &denoising);
+ denoising.functions.write_feature = function_bind(
+ &OpenCLDevice::denoising_write_feature, this, _1, _2, _3, &denoising);
+ denoising.functions.detect_outliers = function_bind(
+ &OpenCLDevice::denoising_detect_outliers, this, _1, _2, _3, _4, &denoising);
+
+ denoising.filter_area = make_int4(rtile.x, rtile.y, rtile.w, rtile.h);
+ denoising.render_buffer.samples = rtile.sample;
+ denoising.buffer.gpu_temporary_mem = true;
+
+ denoising.run_denoising(&rtile);
}
-void OpenCLDevice::shader(DeviceTask& task)
+void OpenCLDevice::shader(DeviceTask &task)
{
- /* cast arguments to cl types */
- cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
- cl_mem d_input = CL_MEM_PTR(task.shader_input);
- cl_mem d_output = CL_MEM_PTR(task.shader_output);
- cl_int d_shader_eval_type = task.shader_eval_type;
- cl_int d_shader_filter = task.shader_filter;
- cl_int d_shader_x = task.shader_x;
- cl_int d_shader_w = task.shader_w;
- cl_int d_offset = task.offset;
-
- OpenCLDevice::OpenCLProgram *program = &background_program;
- if(task.shader_eval_type >= SHADER_EVAL_BAKE) {
- program = &bake_program;
- }
- else if(task.shader_eval_type == SHADER_EVAL_DISPLACE) {
- program = &displace_program;
- }
- program->wait_for_availability();
- cl_kernel kernel = (*program)();
-
- cl_uint start_arg_index =
- kernel_set_args(kernel,
- 0,
- d_data,
- d_input,
- d_output);
-
- set_kernel_arg_buffers(kernel, &start_arg_index);
-
- start_arg_index += kernel_set_args(kernel,
- start_arg_index,
- d_shader_eval_type);
- if(task.shader_eval_type >= SHADER_EVAL_BAKE) {
- start_arg_index += kernel_set_args(kernel,
- start_arg_index,
- d_shader_filter);
- }
- start_arg_index += kernel_set_args(kernel,
- start_arg_index,
- d_shader_x,
- d_shader_w,
- d_offset);
-
- for(int sample = 0; sample < task.num_samples; sample++) {
-
- if(task.get_cancel())
- break;
-
- kernel_set_args(kernel, start_arg_index, sample);
-
- enqueue_kernel(kernel, task.shader_w, 1);
-
- clFinish(cqCommandQueue);
-
- task.update_progress(NULL);
- }
+ /* cast arguments to cl types */
+ cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
+ cl_mem d_input = CL_MEM_PTR(task.shader_input);
+ cl_mem d_output = CL_MEM_PTR(task.shader_output);
+ cl_int d_shader_eval_type = task.shader_eval_type;
+ cl_int d_shader_filter = task.shader_filter;
+ cl_int d_shader_x = task.shader_x;
+ cl_int d_shader_w = task.shader_w;
+ cl_int d_offset = task.offset;
+
+ OpenCLDevice::OpenCLProgram *program = &background_program;
+ if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
+ program = &bake_program;
+ }
+ else if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
+ program = &displace_program;
+ }
+ program->wait_for_availability();
+ cl_kernel kernel = (*program)();
+
+ cl_uint start_arg_index = kernel_set_args(kernel, 0, d_data, d_input, d_output);
+
+ set_kernel_arg_buffers(kernel, &start_arg_index);
+
+ start_arg_index += kernel_set_args(kernel, start_arg_index, d_shader_eval_type);
+ if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
+ start_arg_index += kernel_set_args(kernel, start_arg_index, d_shader_filter);
+ }
+ start_arg_index += kernel_set_args(kernel, start_arg_index, d_shader_x, d_shader_w, d_offset);
+
+ for (int sample = 0; sample < task.num_samples; sample++) {
+
+ if (task.get_cancel())
+ break;
+
+ kernel_set_args(kernel, start_arg_index, sample);
+
+ enqueue_kernel(kernel, task.shader_w, 1);
+
+ clFinish(cqCommandQueue);
+
+ task.update_progress(NULL);
+ }
}
string OpenCLDevice::kernel_build_options(const string *debug_src)
{
- string build_options = "-cl-no-signed-zeros -cl-mad-enable ";
-
- if(platform_name == "NVIDIA CUDA") {
- build_options += "-D__KERNEL_OPENCL_NVIDIA__ "
- "-cl-nv-maxrregcount=32 "
- "-cl-nv-verbose ";
-
- uint compute_capability_major, compute_capability_minor;
- clGetDeviceInfo(cdDevice, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV,
- sizeof(cl_uint), &compute_capability_major, NULL);
- clGetDeviceInfo(cdDevice, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV,
- sizeof(cl_uint), &compute_capability_minor, NULL);
-
- build_options += string_printf("-D__COMPUTE_CAPABILITY__=%u ",
- compute_capability_major * 100 +
- compute_capability_minor * 10);
- }
-
- else if(platform_name == "Apple")
- build_options += "-D__KERNEL_OPENCL_APPLE__ ";
-
- else if(platform_name == "AMD Accelerated Parallel Processing")
- build_options += "-D__KERNEL_OPENCL_AMD__ ";
-
- else if(platform_name == "Intel(R) OpenCL") {
- build_options += "-D__KERNEL_OPENCL_INTEL_CPU__ ";
-
- /* Options for gdb source level kernel debugging.
- * this segfaults on linux currently.
- */
- if(OpenCLInfo::use_debug() && debug_src)
- build_options += "-g -s \"" + *debug_src + "\" ";
- }
-
- if(info.has_half_images) {
- build_options += "-D__KERNEL_CL_KHR_FP16__ ";
- }
-
- if(OpenCLInfo::use_debug()) {
- build_options += "-D__KERNEL_OPENCL_DEBUG__ ";
- }
-
-#ifdef WITH_CYCLES_DEBUG
- build_options += "-D__KERNEL_DEBUG__ ";
-#endif
-
- return build_options;
+ string build_options = "-cl-no-signed-zeros -cl-mad-enable ";
+
+ if (platform_name == "NVIDIA CUDA") {
+ build_options +=
+ "-D__KERNEL_OPENCL_NVIDIA__ "
+ "-cl-nv-maxrregcount=32 "
+ "-cl-nv-verbose ";
+
+ uint compute_capability_major, compute_capability_minor;
+ clGetDeviceInfo(cdDevice,
+ CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV,
+ sizeof(cl_uint),
+ &compute_capability_major,
+ NULL);
+ clGetDeviceInfo(cdDevice,
+ CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV,
+ sizeof(cl_uint),
+ &compute_capability_minor,
+ NULL);
+
+ build_options += string_printf("-D__COMPUTE_CAPABILITY__=%u ",
+ compute_capability_major * 100 + compute_capability_minor * 10);
+ }
+
+ else if (platform_name == "Apple")
+ build_options += "-D__KERNEL_OPENCL_APPLE__ ";
+
+ else if (platform_name == "AMD Accelerated Parallel Processing")
+ build_options += "-D__KERNEL_OPENCL_AMD__ ";
+
+ else if (platform_name == "Intel(R) OpenCL") {
+ build_options += "-D__KERNEL_OPENCL_INTEL_CPU__ ";
+
+ /* Options for gdb source level kernel debugging.
+ * this segfaults on linux currently.
+ */
+ if (OpenCLInfo::use_debug() && debug_src)
+ build_options += "-g -s \"" + *debug_src + "\" ";
+ }
+
+ if (info.has_half_images) {
+ build_options += "-D__KERNEL_CL_KHR_FP16__ ";
+ }
+
+ if (OpenCLInfo::use_debug()) {
+ build_options += "-D__KERNEL_OPENCL_DEBUG__ ";
+ }
+
+# ifdef WITH_CYCLES_DEBUG
+ build_options += "-D__KERNEL_DEBUG__ ";
+# endif
+
+ return build_options;
}
/* TODO(sergey): In the future we can use variadic templates, once
@@ -1944,137 +1913,130 @@ string OpenCLDevice::kernel_build_options(const string *debug_src)
*/
int OpenCLDevice::kernel_set_args(cl_kernel kernel,
int start_argument_index,
- const ArgumentWrapper& arg1,
- const ArgumentWrapper& arg2,
- const ArgumentWrapper& arg3,
- const ArgumentWrapper& arg4,
- const ArgumentWrapper& arg5,
- const ArgumentWrapper& arg6,
- const ArgumentWrapper& arg7,
- const ArgumentWrapper& arg8,
- const ArgumentWrapper& arg9,
- const ArgumentWrapper& arg10,
- const ArgumentWrapper& arg11,
- const ArgumentWrapper& arg12,
- const ArgumentWrapper& arg13,
- const ArgumentWrapper& arg14,
- const ArgumentWrapper& arg15,
- const ArgumentWrapper& arg16,
- const ArgumentWrapper& arg17,
- const ArgumentWrapper& arg18,
- const ArgumentWrapper& arg19,
- const ArgumentWrapper& arg20,
- const ArgumentWrapper& arg21,
- const ArgumentWrapper& arg22,
- const ArgumentWrapper& arg23,
- const ArgumentWrapper& arg24,
- const ArgumentWrapper& arg25,
- const ArgumentWrapper& arg26,
- const ArgumentWrapper& arg27,
- const ArgumentWrapper& arg28,
- const ArgumentWrapper& arg29,
- const ArgumentWrapper& arg30,
- const ArgumentWrapper& arg31,
- const ArgumentWrapper& arg32,
- const ArgumentWrapper& arg33)
+ const ArgumentWrapper &arg1,
+ const ArgumentWrapper &arg2,
+ const ArgumentWrapper &arg3,
+ const ArgumentWrapper &arg4,
+ const ArgumentWrapper &arg5,
+ const ArgumentWrapper &arg6,
+ const ArgumentWrapper &arg7,
+ const ArgumentWrapper &arg8,
+ const ArgumentWrapper &arg9,
+ const ArgumentWrapper &arg10,
+ const ArgumentWrapper &arg11,
+ const ArgumentWrapper &arg12,
+ const ArgumentWrapper &arg13,
+ const ArgumentWrapper &arg14,
+ const ArgumentWrapper &arg15,
+ const ArgumentWrapper &arg16,
+ const ArgumentWrapper &arg17,
+ const ArgumentWrapper &arg18,
+ const ArgumentWrapper &arg19,
+ const ArgumentWrapper &arg20,
+ const ArgumentWrapper &arg21,
+ const ArgumentWrapper &arg22,
+ const ArgumentWrapper &arg23,
+ const ArgumentWrapper &arg24,
+ const ArgumentWrapper &arg25,
+ const ArgumentWrapper &arg26,
+ const ArgumentWrapper &arg27,
+ const ArgumentWrapper &arg28,
+ const ArgumentWrapper &arg29,
+ const ArgumentWrapper &arg30,
+ const ArgumentWrapper &arg31,
+ const ArgumentWrapper &arg32,
+ const ArgumentWrapper &arg33)
{
- int current_arg_index = 0;
-#define FAKE_VARARG_HANDLE_ARG(arg) \
- do { \
- if(arg.pointer != NULL) { \
- opencl_assert(clSetKernelArg( \
- kernel, \
- start_argument_index + current_arg_index, \
- arg.size, arg.pointer)); \
- ++current_arg_index; \
- } \
- else { \
- return current_arg_index; \
- } \
- } while(false)
- FAKE_VARARG_HANDLE_ARG(arg1);
- FAKE_VARARG_HANDLE_ARG(arg2);
- FAKE_VARARG_HANDLE_ARG(arg3);
- FAKE_VARARG_HANDLE_ARG(arg4);
- FAKE_VARARG_HANDLE_ARG(arg5);
- FAKE_VARARG_HANDLE_ARG(arg6);
- FAKE_VARARG_HANDLE_ARG(arg7);
- FAKE_VARARG_HANDLE_ARG(arg8);
- FAKE_VARARG_HANDLE_ARG(arg9);
- FAKE_VARARG_HANDLE_ARG(arg10);
- FAKE_VARARG_HANDLE_ARG(arg11);
- FAKE_VARARG_HANDLE_ARG(arg12);
- FAKE_VARARG_HANDLE_ARG(arg13);
- FAKE_VARARG_HANDLE_ARG(arg14);
- FAKE_VARARG_HANDLE_ARG(arg15);
- FAKE_VARARG_HANDLE_ARG(arg16);
- FAKE_VARARG_HANDLE_ARG(arg17);
- FAKE_VARARG_HANDLE_ARG(arg18);
- FAKE_VARARG_HANDLE_ARG(arg19);
- FAKE_VARARG_HANDLE_ARG(arg20);
- FAKE_VARARG_HANDLE_ARG(arg21);
- FAKE_VARARG_HANDLE_ARG(arg22);
- FAKE_VARARG_HANDLE_ARG(arg23);
- FAKE_VARARG_HANDLE_ARG(arg24);
- FAKE_VARARG_HANDLE_ARG(arg25);
- FAKE_VARARG_HANDLE_ARG(arg26);
- FAKE_VARARG_HANDLE_ARG(arg27);
- FAKE_VARARG_HANDLE_ARG(arg28);
- FAKE_VARARG_HANDLE_ARG(arg29);
- FAKE_VARARG_HANDLE_ARG(arg30);
- FAKE_VARARG_HANDLE_ARG(arg31);
- FAKE_VARARG_HANDLE_ARG(arg32);
- FAKE_VARARG_HANDLE_ARG(arg33);
-#undef FAKE_VARARG_HANDLE_ARG
- return current_arg_index;
+ int current_arg_index = 0;
+# define FAKE_VARARG_HANDLE_ARG(arg) \
+ do { \
+ if (arg.pointer != NULL) { \
+ opencl_assert(clSetKernelArg( \
+ kernel, start_argument_index + current_arg_index, arg.size, arg.pointer)); \
+ ++current_arg_index; \
+ } \
+ else { \
+ return current_arg_index; \
+ } \
+ } while (false)
+ FAKE_VARARG_HANDLE_ARG(arg1);
+ FAKE_VARARG_HANDLE_ARG(arg2);
+ FAKE_VARARG_HANDLE_ARG(arg3);
+ FAKE_VARARG_HANDLE_ARG(arg4);
+ FAKE_VARARG_HANDLE_ARG(arg5);
+ FAKE_VARARG_HANDLE_ARG(arg6);
+ FAKE_VARARG_HANDLE_ARG(arg7);
+ FAKE_VARARG_HANDLE_ARG(arg8);
+ FAKE_VARARG_HANDLE_ARG(arg9);
+ FAKE_VARARG_HANDLE_ARG(arg10);
+ FAKE_VARARG_HANDLE_ARG(arg11);
+ FAKE_VARARG_HANDLE_ARG(arg12);
+ FAKE_VARARG_HANDLE_ARG(arg13);
+ FAKE_VARARG_HANDLE_ARG(arg14);
+ FAKE_VARARG_HANDLE_ARG(arg15);
+ FAKE_VARARG_HANDLE_ARG(arg16);
+ FAKE_VARARG_HANDLE_ARG(arg17);
+ FAKE_VARARG_HANDLE_ARG(arg18);
+ FAKE_VARARG_HANDLE_ARG(arg19);
+ FAKE_VARARG_HANDLE_ARG(arg20);
+ FAKE_VARARG_HANDLE_ARG(arg21);
+ FAKE_VARARG_HANDLE_ARG(arg22);
+ FAKE_VARARG_HANDLE_ARG(arg23);
+ FAKE_VARARG_HANDLE_ARG(arg24);
+ FAKE_VARARG_HANDLE_ARG(arg25);
+ FAKE_VARARG_HANDLE_ARG(arg26);
+ FAKE_VARARG_HANDLE_ARG(arg27);
+ FAKE_VARARG_HANDLE_ARG(arg28);
+ FAKE_VARARG_HANDLE_ARG(arg29);
+ FAKE_VARARG_HANDLE_ARG(arg30);
+ FAKE_VARARG_HANDLE_ARG(arg31);
+ FAKE_VARARG_HANDLE_ARG(arg32);
+ FAKE_VARARG_HANDLE_ARG(arg33);
+# undef FAKE_VARARG_HANDLE_ARG
+ return current_arg_index;
}
void OpenCLDevice::release_kernel_safe(cl_kernel kernel)
{
- if(kernel) {
- clReleaseKernel(kernel);
- }
+ if (kernel) {
+ clReleaseKernel(kernel);
+ }
}
void OpenCLDevice::release_mem_object_safe(cl_mem mem)
{
- if(mem != NULL) {
- clReleaseMemObject(mem);
- }
+ if (mem != NULL) {
+ clReleaseMemObject(mem);
+ }
}
void OpenCLDevice::release_program_safe(cl_program program)
{
- if(program) {
- clReleaseProgram(program);
- }
+ if (program) {
+ clReleaseProgram(program);
+ }
}
/* ** Those guys are for workign around some compiler-specific bugs ** */
-cl_program OpenCLDevice::load_cached_kernel(ustring key,
- thread_scoped_lock& cache_locker)
+cl_program OpenCLDevice::load_cached_kernel(ustring key, thread_scoped_lock &cache_locker)
{
- return OpenCLCache::get_program(cpPlatform,
- cdDevice,
- key,
- cache_locker);
+ return OpenCLCache::get_program(cpPlatform, cdDevice, key, cache_locker);
}
void OpenCLDevice::store_cached_kernel(cl_program program,
ustring key,
- thread_scoped_lock& cache_locker)
+ thread_scoped_lock &cache_locker)
{
- OpenCLCache::store_program(cpPlatform,
- cdDevice,
- program,
- key,
- cache_locker);
+ OpenCLCache::store_program(cpPlatform, cdDevice, program, key, cache_locker);
}
-Device *opencl_create_split_device(DeviceInfo& info, Stats& stats, Profiler &profiler, bool background)
+Device *opencl_create_split_device(DeviceInfo &info,
+ Stats &stats,
+ Profiler &profiler,
+ bool background)
{
- return new OpenCLDevice(info, stats, profiler, background);
+ return new OpenCLDevice(info, stats, profiler, background);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp
index 5a1e12af8ab..cc40ad42b06 100644
--- a/intern/cycles/device/opencl/opencl_util.cpp
+++ b/intern/cycles/device/opencl/opencl_util.cpp
@@ -16,1059 +16,1017 @@
#ifdef WITH_OPENCL
-#include "device/opencl/opencl.h"
-#include "device/device_intern.h"
+# include "device/opencl/opencl.h"
+# include "device/device_intern.h"
-#include "util/util_debug.h"
-#include "util/util_logging.h"
-#include "util/util_md5.h"
-#include "util/util_path.h"
-#include "util/util_time.h"
-#include "util/util_system.h"
+# include "util/util_debug.h"
+# include "util/util_logging.h"
+# include "util/util_md5.h"
+# include "util/util_path.h"
+# include "util/util_time.h"
+# include "util/util_system.h"
using std::cerr;
using std::endl;
CCL_NAMESPACE_BEGIN
-OpenCLCache::Slot::ProgramEntry::ProgramEntry()
- : program(NULL),
- mutex(NULL)
+OpenCLCache::Slot::ProgramEntry::ProgramEntry() : program(NULL), mutex(NULL)
{
}
-OpenCLCache::Slot::ProgramEntry::ProgramEntry(const ProgramEntry& rhs)
- : program(rhs.program),
- mutex(NULL)
+OpenCLCache::Slot::ProgramEntry::ProgramEntry(const ProgramEntry &rhs)
+ : program(rhs.program), mutex(NULL)
{
}
OpenCLCache::Slot::ProgramEntry::~ProgramEntry()
{
- delete mutex;
+ delete mutex;
}
-OpenCLCache::Slot::Slot()
- : context_mutex(NULL),
- context(NULL)
+OpenCLCache::Slot::Slot() : context_mutex(NULL), context(NULL)
{
}
-OpenCLCache::Slot::Slot(const Slot& rhs)
- : context_mutex(NULL),
- context(NULL),
- programs(rhs.programs)
+OpenCLCache::Slot::Slot(const Slot &rhs)
+ : context_mutex(NULL), context(NULL), programs(rhs.programs)
{
}
OpenCLCache::Slot::~Slot()
{
- delete context_mutex;
+ delete context_mutex;
}
-OpenCLCache& OpenCLCache::global_instance()
+OpenCLCache &OpenCLCache::global_instance()
{
- static OpenCLCache instance;
- return instance;
+ static OpenCLCache instance;
+ return instance;
}
cl_context OpenCLCache::get_context(cl_platform_id platform,
cl_device_id device,
- thread_scoped_lock& slot_locker)
+ thread_scoped_lock &slot_locker)
{
- assert(platform != NULL);
+ assert(platform != NULL);
- OpenCLCache& self = global_instance();
+ OpenCLCache &self = global_instance();
- thread_scoped_lock cache_lock(self.cache_lock);
+ thread_scoped_lock cache_lock(self.cache_lock);
- pair<CacheMap::iterator,bool> ins = self.cache.insert(
- CacheMap::value_type(PlatformDevicePair(platform, device), Slot()));
+ pair<CacheMap::iterator, bool> ins = self.cache.insert(
+ CacheMap::value_type(PlatformDevicePair(platform, device), Slot()));
- Slot &slot = ins.first->second;
+ Slot &slot = ins.first->second;
- /* create slot lock only while holding cache lock */
- if(!slot.context_mutex)
- slot.context_mutex = new thread_mutex;
+ /* create slot lock only while holding cache lock */
+ if (!slot.context_mutex)
+ slot.context_mutex = new thread_mutex;
- /* need to unlock cache before locking slot, to allow store to complete */
- cache_lock.unlock();
+ /* need to unlock cache before locking slot, to allow store to complete */
+ cache_lock.unlock();
- /* lock the slot */
- slot_locker = thread_scoped_lock(*slot.context_mutex);
+ /* lock the slot */
+ slot_locker = thread_scoped_lock(*slot.context_mutex);
- /* If the thing isn't cached */
- if(slot.context == NULL) {
- /* return with the caller's lock holder holding the slot lock */
- return NULL;
- }
+ /* If the thing isn't cached */
+ if (slot.context == NULL) {
+ /* return with the caller's lock holder holding the slot lock */
+ return NULL;
+ }
- /* the item was already cached, release the slot lock */
- slot_locker.unlock();
+ /* the item was already cached, release the slot lock */
+ slot_locker.unlock();
- cl_int ciErr = clRetainContext(slot.context);
- assert(ciErr == CL_SUCCESS);
- (void) ciErr;
+ cl_int ciErr = clRetainContext(slot.context);
+ assert(ciErr == CL_SUCCESS);
+ (void)ciErr;
- return slot.context;
+ return slot.context;
}
cl_program OpenCLCache::get_program(cl_platform_id platform,
cl_device_id device,
ustring key,
- thread_scoped_lock& slot_locker)
+ thread_scoped_lock &slot_locker)
{
- assert(platform != NULL);
+ assert(platform != NULL);
- OpenCLCache& self = global_instance();
+ OpenCLCache &self = global_instance();
- thread_scoped_lock cache_lock(self.cache_lock);
+ thread_scoped_lock cache_lock(self.cache_lock);
- pair<CacheMap::iterator,bool> ins = self.cache.insert(
- CacheMap::value_type(PlatformDevicePair(platform, device), Slot()));
+ pair<CacheMap::iterator, bool> ins = self.cache.insert(
+ CacheMap::value_type(PlatformDevicePair(platform, device), Slot()));
- Slot &slot = ins.first->second;
+ Slot &slot = ins.first->second;
- pair<Slot::EntryMap::iterator,bool> ins2 = slot.programs.insert(
- Slot::EntryMap::value_type(key, Slot::ProgramEntry()));
+ pair<Slot::EntryMap::iterator, bool> ins2 = slot.programs.insert(
+ Slot::EntryMap::value_type(key, Slot::ProgramEntry()));
- Slot::ProgramEntry &entry = ins2.first->second;
+ Slot::ProgramEntry &entry = ins2.first->second;
- /* create slot lock only while holding cache lock */
- if(!entry.mutex)
- entry.mutex = new thread_mutex;
+ /* create slot lock only while holding cache lock */
+ if (!entry.mutex)
+ entry.mutex = new thread_mutex;
- /* need to unlock cache before locking slot, to allow store to complete */
- cache_lock.unlock();
+ /* need to unlock cache before locking slot, to allow store to complete */
+ cache_lock.unlock();
- /* lock the slot */
- slot_locker = thread_scoped_lock(*entry.mutex);
+ /* lock the slot */
+ slot_locker = thread_scoped_lock(*entry.mutex);
- /* If the thing isn't cached */
- if(entry.program == NULL) {
- /* return with the caller's lock holder holding the slot lock */
- return NULL;
- }
+ /* If the thing isn't cached */
+ if (entry.program == NULL) {
+ /* return with the caller's lock holder holding the slot lock */
+ return NULL;
+ }
- /* the item was already cached, release the slot lock */
- slot_locker.unlock();
+ /* the item was already cached, release the slot lock */
+ slot_locker.unlock();
- cl_int ciErr = clRetainProgram(entry.program);
- assert(ciErr == CL_SUCCESS);
- (void) ciErr;
+ cl_int ciErr = clRetainProgram(entry.program);
+ assert(ciErr == CL_SUCCESS);
+ (void)ciErr;
- return entry.program;
+ return entry.program;
}
void OpenCLCache::store_context(cl_platform_id platform,
cl_device_id device,
cl_context context,
- thread_scoped_lock& slot_locker)
+ thread_scoped_lock &slot_locker)
{
- assert(platform != NULL);
- assert(device != NULL);
- assert(context != NULL);
+ assert(platform != NULL);
+ assert(device != NULL);
+ assert(context != NULL);
- OpenCLCache &self = global_instance();
+ OpenCLCache &self = global_instance();
- thread_scoped_lock cache_lock(self.cache_lock);
- CacheMap::iterator i = self.cache.find(PlatformDevicePair(platform, device));
- cache_lock.unlock();
+ thread_scoped_lock cache_lock(self.cache_lock);
+ CacheMap::iterator i = self.cache.find(PlatformDevicePair(platform, device));
+ cache_lock.unlock();
- Slot &slot = i->second;
+ Slot &slot = i->second;
- /* sanity check */
- assert(i != self.cache.end());
- assert(slot.context == NULL);
+ /* sanity check */
+ assert(i != self.cache.end());
+ assert(slot.context == NULL);
- slot.context = context;
+ slot.context = context;
- /* unlock the slot */
- slot_locker.unlock();
+ /* unlock the slot */
+ slot_locker.unlock();
- /* increment reference count in OpenCL.
- * The caller is going to release the object when done with it. */
- cl_int ciErr = clRetainContext(context);
- assert(ciErr == CL_SUCCESS);
- (void) ciErr;
+ /* increment reference count in OpenCL.
+ * The caller is going to release the object when done with it. */
+ cl_int ciErr = clRetainContext(context);
+ assert(ciErr == CL_SUCCESS);
+ (void)ciErr;
}
void OpenCLCache::store_program(cl_platform_id platform,
cl_device_id device,
cl_program program,
ustring key,
- thread_scoped_lock& slot_locker)
+ thread_scoped_lock &slot_locker)
{
- assert(platform != NULL);
- assert(device != NULL);
- assert(program != NULL);
+ assert(platform != NULL);
+ assert(device != NULL);
+ assert(program != NULL);
- OpenCLCache &self = global_instance();
+ OpenCLCache &self = global_instance();
- thread_scoped_lock cache_lock(self.cache_lock);
+ thread_scoped_lock cache_lock(self.cache_lock);
- CacheMap::iterator i = self.cache.find(PlatformDevicePair(platform, device));
- assert(i != self.cache.end());
- Slot &slot = i->second;
+ CacheMap::iterator i = self.cache.find(PlatformDevicePair(platform, device));
+ assert(i != self.cache.end());
+ Slot &slot = i->second;
- Slot::EntryMap::iterator i2 = slot.programs.find(key);
- assert(i2 != slot.programs.end());
- Slot::ProgramEntry &entry = i2->second;
+ Slot::EntryMap::iterator i2 = slot.programs.find(key);
+ assert(i2 != slot.programs.end());
+ Slot::ProgramEntry &entry = i2->second;
- assert(entry.program == NULL);
+ assert(entry.program == NULL);
- cache_lock.unlock();
+ cache_lock.unlock();
- entry.program = program;
+ entry.program = program;
- /* unlock the slot */
- slot_locker.unlock();
+ /* unlock the slot */
+ slot_locker.unlock();
- /* Increment reference count in OpenCL.
- * The caller is going to release the object when done with it.
- */
- cl_int ciErr = clRetainProgram(program);
- assert(ciErr == CL_SUCCESS);
- (void) ciErr;
+ /* Increment reference count in OpenCL.
+ * The caller is going to release the object when done with it.
+ */
+ cl_int ciErr = clRetainProgram(program);
+ assert(ciErr == CL_SUCCESS);
+ (void)ciErr;
}
string OpenCLCache::get_kernel_md5()
{
- OpenCLCache &self = global_instance();
- thread_scoped_lock lock(self.kernel_md5_lock);
+ OpenCLCache &self = global_instance();
+ thread_scoped_lock lock(self.kernel_md5_lock);
- if(self.kernel_md5.empty()) {
- self.kernel_md5 = path_files_md5_hash(path_get("source"));
- }
- return self.kernel_md5;
+ if (self.kernel_md5.empty()) {
+ self.kernel_md5 = path_files_md5_hash(path_get("source"));
+ }
+ return self.kernel_md5;
}
-static string get_program_source(const string& kernel_file)
+static string get_program_source(const string &kernel_file)
{
- string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
- /* We compile kernels consisting of many files. unfortunately OpenCL
- * kernel caches do not seem to recognize changes in included files.
- * so we force recompile on changes by adding the md5 hash of all files.
- */
- source = path_source_replace_includes(source, path_get("source"));
- source += "\n// " + util_md5_string(source) + "\n";
- return source;
+ string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
+ /* We compile kernels consisting of many files. unfortunately OpenCL
+ * kernel caches do not seem to recognize changes in included files.
+ * so we force recompile on changes by adding the md5 hash of all files.
+ */
+ source = path_source_replace_includes(source, path_get("source"));
+ source += "\n// " + util_md5_string(source) + "\n";
+ return source;
}
OpenCLDevice::OpenCLProgram::OpenCLProgram(OpenCLDevice *device,
- const string& program_name,
- const string& kernel_file,
- const string& kernel_build_options,
- bool use_stdout)
- : device(device),
- program_name(program_name),
- kernel_file(kernel_file),
- kernel_build_options(kernel_build_options),
- use_stdout(use_stdout)
+ const string &program_name,
+ const string &kernel_file,
+ const string &kernel_build_options,
+ bool use_stdout)
+ : device(device),
+ program_name(program_name),
+ kernel_file(kernel_file),
+ kernel_build_options(kernel_build_options),
+ use_stdout(use_stdout)
{
- loaded = false;
- needs_compiling = true;
- program = NULL;
+ loaded = false;
+ needs_compiling = true;
+ program = NULL;
}
OpenCLDevice::OpenCLProgram::~OpenCLProgram()
{
- release();
+ release();
}
void OpenCLDevice::OpenCLProgram::release()
{
- for(map<ustring, cl_kernel>::iterator kernel = kernels.begin(); kernel != kernels.end(); ++kernel) {
- if(kernel->second) {
- clReleaseKernel(kernel->second);
- kernel->second = NULL;
- }
- }
- if(program) {
- clReleaseProgram(program);
- program = NULL;
- }
+ for (map<ustring, cl_kernel>::iterator kernel = kernels.begin(); kernel != kernels.end();
+ ++kernel) {
+ if (kernel->second) {
+ clReleaseKernel(kernel->second);
+ kernel->second = NULL;
+ }
+ }
+ if (program) {
+ clReleaseProgram(program);
+ program = NULL;
+ }
}
-void OpenCLDevice::OpenCLProgram::add_log(const string& msg, bool debug)
+void OpenCLDevice::OpenCLProgram::add_log(const string &msg, bool debug)
{
- if(!use_stdout) {
- log += msg + "\n";
- }
- else if(!debug) {
- printf("%s\n", msg.c_str());
- fflush(stdout);
- }
- else {
- VLOG(2) << msg;
- }
+ if (!use_stdout) {
+ log += msg + "\n";
+ }
+ else if (!debug) {
+ printf("%s\n", msg.c_str());
+ fflush(stdout);
+ }
+ else {
+ VLOG(2) << msg;
+ }
}
-void OpenCLDevice::OpenCLProgram::add_error(const string& msg)
+void OpenCLDevice::OpenCLProgram::add_error(const string &msg)
{
- if(use_stdout) {
- fprintf(stderr, "%s\n", msg.c_str());
- }
- if(error_msg == "") {
- error_msg += "\n";
- }
- error_msg += msg;
+ if (use_stdout) {
+ fprintf(stderr, "%s\n", msg.c_str());
+ }
+ if (error_msg == "") {
+ error_msg += "\n";
+ }
+ error_msg += msg;
}
void OpenCLDevice::OpenCLProgram::add_kernel(ustring name)
{
- if(!kernels.count(name)) {
- kernels[name] = NULL;
- }
+ if (!kernels.count(name)) {
+ kernels[name] = NULL;
+ }
}
bool OpenCLDevice::OpenCLProgram::build_kernel(const string *debug_src)
{
- string build_options;
- build_options = device->kernel_build_options(debug_src) + kernel_build_options;
+ string build_options;
+ build_options = device->kernel_build_options(debug_src) + kernel_build_options;
- VLOG(1) << "Build options passed to clBuildProgram: '"
- << build_options << "'.";
- cl_int ciErr = clBuildProgram(program, 0, NULL, build_options.c_str(), NULL, NULL);
+ VLOG(1) << "Build options passed to clBuildProgram: '" << build_options << "'.";
+ cl_int ciErr = clBuildProgram(program, 0, NULL, build_options.c_str(), NULL, NULL);
- /* show warnings even if build is successful */
- size_t ret_val_size = 0;
+ /* show warnings even if build is successful */
+ size_t ret_val_size = 0;
- clGetProgramBuildInfo(program, device->cdDevice, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
+ clGetProgramBuildInfo(program, device->cdDevice, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
- if(ciErr != CL_SUCCESS) {
- add_error(string("OpenCL build failed with error ") + clewErrorString(ciErr) + ", errors in console.");
- }
+ if (ciErr != CL_SUCCESS) {
+ add_error(string("OpenCL build failed with error ") + clewErrorString(ciErr) +
+ ", errors in console.");
+ }
- if(ret_val_size > 1) {
- vector<char> build_log(ret_val_size + 1);
- clGetProgramBuildInfo(program, device->cdDevice, CL_PROGRAM_BUILD_LOG, ret_val_size, &build_log[0], NULL);
+ if (ret_val_size > 1) {
+ vector<char> build_log(ret_val_size + 1);
+ clGetProgramBuildInfo(
+ program, device->cdDevice, CL_PROGRAM_BUILD_LOG, ret_val_size, &build_log[0], NULL);
- build_log[ret_val_size] = '\0';
- /* Skip meaningless empty output from the NVidia compiler. */
- if(!(ret_val_size == 2 && build_log[0] == '\n')) {
- add_log(string("OpenCL program ") + program_name + " build output: " + string(&build_log[0]), ciErr == CL_SUCCESS);
- }
- }
+ build_log[ret_val_size] = '\0';
+ /* Skip meaningless empty output from the NVidia compiler. */
+ if (!(ret_val_size == 2 && build_log[0] == '\n')) {
+ add_log(string("OpenCL program ") + program_name + " build output: " + string(&build_log[0]),
+ ciErr == CL_SUCCESS);
+ }
+ }
- return (ciErr == CL_SUCCESS);
+ return (ciErr == CL_SUCCESS);
}
bool OpenCLDevice::OpenCLProgram::compile_kernel(const string *debug_src)
{
- string source = get_program_source(kernel_file);
+ string source = get_program_source(kernel_file);
- if(debug_src) {
- path_write_text(*debug_src, source);
- }
+ if (debug_src) {
+ path_write_text(*debug_src, source);
+ }
- size_t source_len = source.size();
- const char *source_str = source.c_str();
- cl_int ciErr;
+ size_t source_len = source.size();
+ const char *source_str = source.c_str();
+ cl_int ciErr;
- program = clCreateProgramWithSource(device->cxContext,
- 1,
- &source_str,
- &source_len,
- &ciErr);
+ program = clCreateProgramWithSource(device->cxContext, 1, &source_str, &source_len, &ciErr);
- if(ciErr != CL_SUCCESS) {
- add_error(string("OpenCL program creation failed: ") + clewErrorString(ciErr));
- return false;
- }
+ if (ciErr != CL_SUCCESS) {
+ add_error(string("OpenCL program creation failed: ") + clewErrorString(ciErr));
+ return false;
+ }
- double starttime = time_dt();
- add_log(string("Cycles: compiling OpenCL program ") + program_name + "...", false);
- add_log(string("Build flags: ") + kernel_build_options, true);
+ double starttime = time_dt();
+ add_log(string("Cycles: compiling OpenCL program ") + program_name + "...", false);
+ add_log(string("Build flags: ") + kernel_build_options, true);
- if(!build_kernel(debug_src))
- return false;
+ if (!build_kernel(debug_src))
+ return false;
- double elapsed = time_dt() - starttime;
- add_log(string_printf("Kernel compilation of %s finished in %.2lfs.", program_name.c_str(), elapsed), false);
+ double elapsed = time_dt() - starttime;
+ add_log(
+ string_printf("Kernel compilation of %s finished in %.2lfs.", program_name.c_str(), elapsed),
+ false);
- return true;
+ return true;
}
-static void escape_python_string(string& str)
+static void escape_python_string(string &str)
{
- /* Escape string to be passed as a Python raw string with '' quotes'. */
- string_replace(str, "'", "\'");
+ /* Escape string to be passed as a Python raw string with '' quotes'. */
+ string_replace(str, "'", "\'");
}
-bool OpenCLDevice::OpenCLProgram::compile_separate(const string& clbin)
+bool OpenCLDevice::OpenCLProgram::compile_separate(const string &clbin)
{
- vector<string> args;
- args.push_back("--background");
- args.push_back("--factory-startup");
- args.push_back("--python-expr");
-
- int device_platform_id = device->device_num;
- string device_name = device->device_name;
- string platform_name = device->platform_name;
- string build_options = device->kernel_build_options(NULL) + kernel_build_options;
- string kernel_file_escaped = kernel_file;
- string clbin_escaped = clbin;
-
- escape_python_string(device_name);
- escape_python_string(platform_name);
- escape_python_string(build_options);
- escape_python_string(kernel_file_escaped);
- escape_python_string(clbin_escaped);
-
- args.push_back(
- string_printf(
- "import _cycles; _cycles.opencl_compile(r'%d', r'%s', r'%s', r'%s', r'%s', r'%s')",
- device_platform_id,
- device_name.c_str(),
- platform_name.c_str(),
- build_options.c_str(),
- kernel_file_escaped.c_str(),
- clbin_escaped.c_str()));
-
- double starttime = time_dt();
- add_log(string("Cycles: compiling OpenCL program ") + program_name + "...", false);
- add_log(string("Build flags: ") + kernel_build_options, true);
- if(!system_call_self(args) || !path_exists(clbin)) {
- return false;
- }
-
- double elapsed = time_dt() - starttime;
- add_log(string_printf("Kernel compilation of %s finished in %.2lfs.", program_name.c_str(), elapsed), false);
-
- return load_binary(clbin);
+ vector<string> args;
+ args.push_back("--background");
+ args.push_back("--factory-startup");
+ args.push_back("--python-expr");
+
+ int device_platform_id = device->device_num;
+ string device_name = device->device_name;
+ string platform_name = device->platform_name;
+ string build_options = device->kernel_build_options(NULL) + kernel_build_options;
+ string kernel_file_escaped = kernel_file;
+ string clbin_escaped = clbin;
+
+ escape_python_string(device_name);
+ escape_python_string(platform_name);
+ escape_python_string(build_options);
+ escape_python_string(kernel_file_escaped);
+ escape_python_string(clbin_escaped);
+
+ args.push_back(string_printf(
+ "import _cycles; _cycles.opencl_compile(r'%d', r'%s', r'%s', r'%s', r'%s', r'%s')",
+ device_platform_id,
+ device_name.c_str(),
+ platform_name.c_str(),
+ build_options.c_str(),
+ kernel_file_escaped.c_str(),
+ clbin_escaped.c_str()));
+
+ double starttime = time_dt();
+ add_log(string("Cycles: compiling OpenCL program ") + program_name + "...", false);
+ add_log(string("Build flags: ") + kernel_build_options, true);
+ if (!system_call_self(args) || !path_exists(clbin)) {
+ return false;
+ }
+
+ double elapsed = time_dt() - starttime;
+ add_log(
+ string_printf("Kernel compilation of %s finished in %.2lfs.", program_name.c_str(), elapsed),
+ false);
+
+ return load_binary(clbin);
}
/* Compile opencl kernel. This method is called from the _cycles Python
* module compile kernels. Parameters must match function above. */
-bool device_opencl_compile_kernel(const vector<string>& parameters)
+bool device_opencl_compile_kernel(const vector<string> &parameters)
{
- int device_platform_id = std::stoi(parameters[0]);
- const string& device_name = parameters[1];
- const string& platform_name = parameters[2];
- const string& build_options = parameters[3];
- const string& kernel_file = parameters[4];
- const string& binary_path = parameters[5];
-
- if(clewInit() != CLEW_SUCCESS) {
- return false;
- }
-
- vector<OpenCLPlatformDevice> usable_devices;
- OpenCLInfo::get_usable_devices(&usable_devices);
- if(device_platform_id >= usable_devices.size()) {
- return false;
- }
-
- OpenCLPlatformDevice& platform_device = usable_devices[device_platform_id];
- if(platform_device.platform_name != platform_name ||
- platform_device.device_name != device_name)
- {
- return false;
- }
-
- cl_platform_id platform = platform_device.platform_id;
- cl_device_id device = platform_device.device_id;
- const cl_context_properties context_props[] = {
- CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
- 0, 0
- };
-
- cl_int err;
- cl_context context = clCreateContext(context_props, 1, &device, NULL, NULL, &err);
- if(err != CL_SUCCESS) {
- return false;
- }
-
- string source = get_program_source(kernel_file);
- size_t source_len = source.size();
- const char *source_str = source.c_str();
- cl_program program = clCreateProgramWithSource(context, 1, &source_str, &source_len, &err);
- bool result = false;
-
- if(err == CL_SUCCESS) {
- err = clBuildProgram(program, 0, NULL, build_options.c_str(), NULL, NULL);
-
- if(err == CL_SUCCESS) {
- size_t size = 0;
- clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL);
- if(size > 0) {
- vector<uint8_t> binary(size);
- uint8_t *bytes = &binary[0];
- clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(uint8_t*), &bytes, NULL);
- result = path_write_binary(binary_path, binary);
- }
- }
- clReleaseProgram(program);
- }
-
- clReleaseContext(context);
-
- return result;
+ int device_platform_id = std::stoi(parameters[0]);
+ const string &device_name = parameters[1];
+ const string &platform_name = parameters[2];
+ const string &build_options = parameters[3];
+ const string &kernel_file = parameters[4];
+ const string &binary_path = parameters[5];
+
+ if (clewInit() != CLEW_SUCCESS) {
+ return false;
+ }
+
+ vector<OpenCLPlatformDevice> usable_devices;
+ OpenCLInfo::get_usable_devices(&usable_devices);
+ if (device_platform_id >= usable_devices.size()) {
+ return false;
+ }
+
+ OpenCLPlatformDevice &platform_device = usable_devices[device_platform_id];
+ if (platform_device.platform_name != platform_name ||
+ platform_device.device_name != device_name) {
+ return false;
+ }
+
+ cl_platform_id platform = platform_device.platform_id;
+ cl_device_id device = platform_device.device_id;
+ const cl_context_properties context_props[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0, 0};
+
+ cl_int err;
+ cl_context context = clCreateContext(context_props, 1, &device, NULL, NULL, &err);
+ if (err != CL_SUCCESS) {
+ return false;
+ }
+
+ string source = get_program_source(kernel_file);
+ size_t source_len = source.size();
+ const char *source_str = source.c_str();
+ cl_program program = clCreateProgramWithSource(context, 1, &source_str, &source_len, &err);
+ bool result = false;
+
+ if (err == CL_SUCCESS) {
+ err = clBuildProgram(program, 0, NULL, build_options.c_str(), NULL, NULL);
+
+ if (err == CL_SUCCESS) {
+ size_t size = 0;
+ clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL);
+ if (size > 0) {
+ vector<uint8_t> binary(size);
+ uint8_t *bytes = &binary[0];
+ clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(uint8_t *), &bytes, NULL);
+ result = path_write_binary(binary_path, binary);
+ }
+ }
+ clReleaseProgram(program);
+ }
+
+ clReleaseContext(context);
+
+ return result;
}
-bool OpenCLDevice::OpenCLProgram::load_binary(const string& clbin,
- const string *debug_src)
+bool OpenCLDevice::OpenCLProgram::load_binary(const string &clbin, const string *debug_src)
{
- /* read binary into memory */
- vector<uint8_t> binary;
+ /* read binary into memory */
+ vector<uint8_t> binary;
- if(!path_read_binary(clbin, binary)) {
- add_error(string_printf("OpenCL failed to read cached binary %s.", clbin.c_str()));
- return false;
- }
+ if (!path_read_binary(clbin, binary)) {
+ add_error(string_printf("OpenCL failed to read cached binary %s.", clbin.c_str()));
+ return false;
+ }
- /* create program */
- cl_int status, ciErr;
- size_t size = binary.size();
- const uint8_t *bytes = &binary[0];
+ /* create program */
+ cl_int status, ciErr;
+ size_t size = binary.size();
+ const uint8_t *bytes = &binary[0];
- program = clCreateProgramWithBinary(device->cxContext, 1, &device->cdDevice,
- &size, &bytes, &status, &ciErr);
+ program = clCreateProgramWithBinary(
+ device->cxContext, 1, &device->cdDevice, &size, &bytes, &status, &ciErr);
- if(status != CL_SUCCESS || ciErr != CL_SUCCESS) {
- add_error(string("OpenCL failed create program from cached binary ") + clbin + ": "
- + clewErrorString(status) + " " + clewErrorString(ciErr));
- return false;
- }
+ if (status != CL_SUCCESS || ciErr != CL_SUCCESS) {
+ add_error(string("OpenCL failed create program from cached binary ") + clbin + ": " +
+ clewErrorString(status) + " " + clewErrorString(ciErr));
+ return false;
+ }
- if(!build_kernel(debug_src))
- return false;
+ if (!build_kernel(debug_src))
+ return false;
- return true;
+ return true;
}
-bool OpenCLDevice::OpenCLProgram::save_binary(const string& clbin)
+bool OpenCLDevice::OpenCLProgram::save_binary(const string &clbin)
{
- size_t size = 0;
- clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL);
+ size_t size = 0;
+ clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL);
- if(!size)
- return false;
+ if (!size)
+ return false;
- vector<uint8_t> binary(size);
- uint8_t *bytes = &binary[0];
+ vector<uint8_t> binary(size);
+ uint8_t *bytes = &binary[0];
- clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(uint8_t*), &bytes, NULL);
+ clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(uint8_t *), &bytes, NULL);
- return path_write_binary(clbin, binary);
+ return path_write_binary(clbin, binary);
}
bool OpenCLDevice::OpenCLProgram::load()
{
- loaded = false;
- string device_md5 = device->device_md5_hash(kernel_build_options);
-
- /* Try to use cached kernel. */
- thread_scoped_lock cache_locker;
- ustring cache_key(program_name + device_md5);
- program = device->load_cached_kernel(cache_key,
- cache_locker);
- if (!program) {
- add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
-
- /* need to create source to get md5 */
- string source = get_program_source(kernel_file);
-
- string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" + util_md5_string(source);
- basename = path_cache_get(path_join("kernels", basename));
- string clbin = basename + ".clbin";
-
- /* If binary kernel exists already, try use it. */
- if(path_exists(clbin) && load_binary(clbin)) {
- /* Kernel loaded from binary, nothing to do. */
- add_log(string("Loaded program from ") + clbin + ".", true);
-
- /* Cache the program. */
- device->store_cached_kernel(program,
- cache_key,
- cache_locker);
- }
- else {
- add_log(string("OpenCL program ") + program_name + " not found on disk.", true);
- cache_locker.unlock();
- }
- }
-
- if (program) {
- create_kernels();
- loaded = true;
- needs_compiling = false;
- }
-
- return loaded;
+ loaded = false;
+ string device_md5 = device->device_md5_hash(kernel_build_options);
+
+ /* Try to use cached kernel. */
+ thread_scoped_lock cache_locker;
+ ustring cache_key(program_name + device_md5);
+ program = device->load_cached_kernel(cache_key, cache_locker);
+ if (!program) {
+ add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
+
+ /* need to create source to get md5 */
+ string source = get_program_source(kernel_file);
+
+ string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" +
+ util_md5_string(source);
+ basename = path_cache_get(path_join("kernels", basename));
+ string clbin = basename + ".clbin";
+
+ /* If binary kernel exists already, try use it. */
+ if (path_exists(clbin) && load_binary(clbin)) {
+ /* Kernel loaded from binary, nothing to do. */
+ add_log(string("Loaded program from ") + clbin + ".", true);
+
+ /* Cache the program. */
+ device->store_cached_kernel(program, cache_key, cache_locker);
+ }
+ else {
+ add_log(string("OpenCL program ") + program_name + " not found on disk.", true);
+ cache_locker.unlock();
+ }
+ }
+
+ if (program) {
+ create_kernels();
+ loaded = true;
+ needs_compiling = false;
+ }
+
+ return loaded;
}
void OpenCLDevice::OpenCLProgram::compile()
{
- assert(device);
-
- string device_md5 = device->device_md5_hash(kernel_build_options);
-
- /* Try to use cached kernel. */
- thread_scoped_lock cache_locker;
- ustring cache_key(program_name + device_md5);
- program = device->load_cached_kernel(cache_key,
- cache_locker);
-
- if (!program)
- {
-
- add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
-
- /* need to create source to get md5 */
- string source = get_program_source(kernel_file);
-
- string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" + util_md5_string(source);
- basename = path_cache_get(path_join("kernels", basename));
- string clbin = basename + ".clbin";
-
- /* path to preprocessed source for debugging */
- string clsrc, *debug_src = NULL;
-
- if(OpenCLInfo::use_debug()) {
- clsrc = basename + ".cl";
- debug_src = &clsrc;
- }
-
- /* If binary kernel exists already, try use it. */
- if(compile_separate(clbin)) {
- add_log(string("Built and loaded program from ") + clbin + ".", true);
- loaded = true;
- }
- else {
- add_log(string("Separate-process building of ") + clbin + " failed, will fall back to regular building.", true);
-
- /* If does not exist or loading binary failed, compile kernel. */
- if(!compile_kernel(debug_src)) {
- needs_compiling = false;
- return;
- }
-
- /* Save binary for reuse. */
- if(!save_binary(clbin)) {
- add_log(string("Saving compiled OpenCL kernel to ") + clbin + " failed!", true);
- }
- }
-
- /* Cache the program. */
- device->store_cached_kernel(program,
- cache_key,
- cache_locker);
- }
-
- create_kernels();
- needs_compiling = false;
- loaded = true;
+ assert(device);
+
+ string device_md5 = device->device_md5_hash(kernel_build_options);
+
+ /* Try to use cached kernel. */
+ thread_scoped_lock cache_locker;
+ ustring cache_key(program_name + device_md5);
+ program = device->load_cached_kernel(cache_key, cache_locker);
+
+ if (!program) {
+
+ add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
+
+ /* need to create source to get md5 */
+ string source = get_program_source(kernel_file);
+
+ string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" +
+ util_md5_string(source);
+ basename = path_cache_get(path_join("kernels", basename));
+ string clbin = basename + ".clbin";
+
+ /* path to preprocessed source for debugging */
+ string clsrc, *debug_src = NULL;
+
+ if (OpenCLInfo::use_debug()) {
+ clsrc = basename + ".cl";
+ debug_src = &clsrc;
+ }
+
+ /* If binary kernel exists already, try use it. */
+ if (compile_separate(clbin)) {
+ add_log(string("Built and loaded program from ") + clbin + ".", true);
+ loaded = true;
+ }
+ else {
+ add_log(string("Separate-process building of ") + clbin +
+ " failed, will fall back to regular building.",
+ true);
+
+ /* If does not exist or loading binary failed, compile kernel. */
+ if (!compile_kernel(debug_src)) {
+ needs_compiling = false;
+ return;
+ }
+
+ /* Save binary for reuse. */
+ if (!save_binary(clbin)) {
+ add_log(string("Saving compiled OpenCL kernel to ") + clbin + " failed!", true);
+ }
+ }
+
+ /* Cache the program. */
+ device->store_cached_kernel(program, cache_key, cache_locker);
+ }
+
+ create_kernels();
+ needs_compiling = false;
+ loaded = true;
}
void OpenCLDevice::OpenCLProgram::create_kernels()
{
- for(map<ustring, cl_kernel>::iterator kernel = kernels.begin(); kernel != kernels.end(); ++kernel) {
- assert(kernel->second == NULL);
- cl_int ciErr;
- string name = "kernel_ocl_" + kernel->first.string();
- kernel->second = clCreateKernel(program, name.c_str(), &ciErr);
- if(device->opencl_error(ciErr)) {
- add_error(string("Error getting kernel ") + name + " from program " + program_name + ": " + clewErrorString(ciErr));
- return;
- }
- }
+ for (map<ustring, cl_kernel>::iterator kernel = kernels.begin(); kernel != kernels.end();
+ ++kernel) {
+ assert(kernel->second == NULL);
+ cl_int ciErr;
+ string name = "kernel_ocl_" + kernel->first.string();
+ kernel->second = clCreateKernel(program, name.c_str(), &ciErr);
+ if (device->opencl_error(ciErr)) {
+ add_error(string("Error getting kernel ") + name + " from program " + program_name + ": " +
+ clewErrorString(ciErr));
+ return;
+ }
+ }
}
bool OpenCLDevice::OpenCLProgram::wait_for_availability()
{
- add_log(string("Waiting for availability of ") + program_name + ".", true);
- while (needs_compiling) {
- time_sleep(0.1);
- }
- return loaded;
+ add_log(string("Waiting for availability of ") + program_name + ".", true);
+ while (needs_compiling) {
+ time_sleep(0.1);
+ }
+ return loaded;
}
void OpenCLDevice::OpenCLProgram::report_error()
{
- /* If loaded is true, there was no error. */
- if(loaded) return;
- /* if use_stdout is true, the error was already reported. */
- if(use_stdout) return;
-
- cerr << error_msg << endl;
- if(!compile_output.empty()) {
- cerr << "OpenCL kernel build output for " << program_name << ":" << endl;
- cerr << compile_output << endl;
- }
+ /* If loaded is true, there was no error. */
+ if (loaded)
+ return;
+ /* if use_stdout is true, the error was already reported. */
+ if (use_stdout)
+ return;
+
+ cerr << error_msg << endl;
+ if (!compile_output.empty()) {
+ cerr << "OpenCL kernel build output for " << program_name << ":" << endl;
+ cerr << compile_output << endl;
+ }
}
cl_kernel OpenCLDevice::OpenCLProgram::operator()()
{
- assert(kernels.size() == 1);
- return kernels.begin()->second;
+ assert(kernels.size() == 1);
+ return kernels.begin()->second;
}
cl_kernel OpenCLDevice::OpenCLProgram::operator()(ustring name)
{
- assert(kernels.count(name));
- return kernels[name];
+ assert(kernels.count(name));
+ return kernels[name];
}
cl_device_type OpenCLInfo::device_type()
{
- switch(DebugFlags().opencl.device_type)
- {
- case DebugFlags::OpenCL::DEVICE_NONE:
- return 0;
- case DebugFlags::OpenCL::DEVICE_ALL:
- return CL_DEVICE_TYPE_ALL;
- case DebugFlags::OpenCL::DEVICE_DEFAULT:
- return CL_DEVICE_TYPE_DEFAULT;
- case DebugFlags::OpenCL::DEVICE_CPU:
- return CL_DEVICE_TYPE_CPU;
- case DebugFlags::OpenCL::DEVICE_GPU:
- return CL_DEVICE_TYPE_GPU;
- case DebugFlags::OpenCL::DEVICE_ACCELERATOR:
- return CL_DEVICE_TYPE_ACCELERATOR;
- default:
- return CL_DEVICE_TYPE_ALL;
- }
+ switch (DebugFlags().opencl.device_type) {
+ case DebugFlags::OpenCL::DEVICE_NONE:
+ return 0;
+ case DebugFlags::OpenCL::DEVICE_ALL:
+ return CL_DEVICE_TYPE_ALL;
+ case DebugFlags::OpenCL::DEVICE_DEFAULT:
+ return CL_DEVICE_TYPE_DEFAULT;
+ case DebugFlags::OpenCL::DEVICE_CPU:
+ return CL_DEVICE_TYPE_CPU;
+ case DebugFlags::OpenCL::DEVICE_GPU:
+ return CL_DEVICE_TYPE_GPU;
+ case DebugFlags::OpenCL::DEVICE_ACCELERATOR:
+ return CL_DEVICE_TYPE_ACCELERATOR;
+ default:
+ return CL_DEVICE_TYPE_ALL;
+ }
}
bool OpenCLInfo::use_debug()
{
- return DebugFlags().opencl.debug;
+ return DebugFlags().opencl.debug;
}
-bool OpenCLInfo::device_supported(const string& platform_name,
- const cl_device_id device_id)
+bool OpenCLInfo::device_supported(const string &platform_name, const cl_device_id device_id)
{
- cl_device_type device_type;
- if(!get_device_type(device_id, &device_type)) {
- return false;
- }
- string device_name;
- if(!get_device_name(device_id, &device_name)) {
- return false;
- }
-
- int driver_major = 0;
- int driver_minor = 0;
- if(!get_driver_version(device_id, &driver_major, &driver_minor)) {
- return false;
- }
- VLOG(3) << "OpenCL driver version " << driver_major << "." << driver_minor;
-
- /* It is possible tyo have Iris GPU on AMD/Apple OpenCL framework
- * (aka, it will not be on Intel framework). This isn't supported
- * and needs an explicit blacklist.
- */
- if(strstr(device_name.c_str(), "Iris")) {
- return false;
- }
- if(platform_name == "AMD Accelerated Parallel Processing" &&
- device_type == CL_DEVICE_TYPE_GPU)
- {
- if(driver_major < 2236) {
- VLOG(1) << "AMD driver version " << driver_major << "." << driver_minor << " not supported.";
- return false;
- }
- const char *blacklist[] = {
- /* GCN 1 */
- "Tahiti", "Pitcairn", "Capeverde", "Oland", "Hainan",
- NULL
- };
- for(int i = 0; blacklist[i] != NULL; i++) {
- if(device_name == blacklist[i]) {
- VLOG(1) << "AMD device " << device_name << " not supported";
- return false;
- }
- }
- return true;
- }
- if(platform_name == "Apple" && device_type == CL_DEVICE_TYPE_GPU) {
- return false;
- }
- return false;
+ cl_device_type device_type;
+ if (!get_device_type(device_id, &device_type)) {
+ return false;
+ }
+ string device_name;
+ if (!get_device_name(device_id, &device_name)) {
+ return false;
+ }
+
+ int driver_major = 0;
+ int driver_minor = 0;
+ if (!get_driver_version(device_id, &driver_major, &driver_minor)) {
+ return false;
+ }
+ VLOG(3) << "OpenCL driver version " << driver_major << "." << driver_minor;
+
+ /* It is possible tyo have Iris GPU on AMD/Apple OpenCL framework
+ * (aka, it will not be on Intel framework). This isn't supported
+ * and needs an explicit blacklist.
+ */
+ if (strstr(device_name.c_str(), "Iris")) {
+ return false;
+ }
+ if (platform_name == "AMD Accelerated Parallel Processing" &&
+ device_type == CL_DEVICE_TYPE_GPU) {
+ if (driver_major < 2236) {
+ VLOG(1) << "AMD driver version " << driver_major << "." << driver_minor << " not supported.";
+ return false;
+ }
+ const char *blacklist[] = {/* GCN 1 */
+ "Tahiti",
+ "Pitcairn",
+ "Capeverde",
+ "Oland",
+ "Hainan",
+ NULL};
+ for (int i = 0; blacklist[i] != NULL; i++) {
+ if (device_name == blacklist[i]) {
+ VLOG(1) << "AMD device " << device_name << " not supported";
+ return false;
+ }
+ }
+ return true;
+ }
+ if (platform_name == "Apple" && device_type == CL_DEVICE_TYPE_GPU) {
+ return false;
+ }
+ return false;
}
-bool OpenCLInfo::platform_version_check(cl_platform_id platform,
- string *error)
+bool OpenCLInfo::platform_version_check(cl_platform_id platform, string *error)
{
- const int req_major = 1, req_minor = 1;
- int major, minor;
- char version[256];
- clGetPlatformInfo(platform,
- CL_PLATFORM_VERSION,
- sizeof(version),
- &version,
- NULL);
- if(sscanf(version, "OpenCL %d.%d", &major, &minor) < 2) {
- if(error != NULL) {
- *error = string_printf("OpenCL: failed to parse platform version string (%s).", version);
- }
- return false;
- }
- if(!((major == req_major && minor >= req_minor) || (major > req_major))) {
- if(error != NULL) {
- *error = string_printf("OpenCL: platform version 1.1 or later required, found %d.%d", major, minor);
- }
- return false;
- }
- if(error != NULL) {
- *error = "";
- }
- return true;
+ const int req_major = 1, req_minor = 1;
+ int major, minor;
+ char version[256];
+ clGetPlatformInfo(platform, CL_PLATFORM_VERSION, sizeof(version), &version, NULL);
+ if (sscanf(version, "OpenCL %d.%d", &major, &minor) < 2) {
+ if (error != NULL) {
+ *error = string_printf("OpenCL: failed to parse platform version string (%s).", version);
+ }
+ return false;
+ }
+ if (!((major == req_major && minor >= req_minor) || (major > req_major))) {
+ if (error != NULL) {
+ *error = string_printf(
+ "OpenCL: platform version 1.1 or later required, found %d.%d", major, minor);
+ }
+ return false;
+ }
+ if (error != NULL) {
+ *error = "";
+ }
+ return true;
}
-bool OpenCLInfo::device_version_check(cl_device_id device,
- string *error)
+bool OpenCLInfo::device_version_check(cl_device_id device, string *error)
{
- const int req_major = 1, req_minor = 1;
- int major, minor;
- char version[256];
- clGetDeviceInfo(device,
- CL_DEVICE_OPENCL_C_VERSION,
- sizeof(version),
- &version,
- NULL);
- if(sscanf(version, "OpenCL C %d.%d", &major, &minor) < 2) {
- if(error != NULL) {
- *error = string_printf("OpenCL: failed to parse OpenCL C version string (%s).", version);
- }
- return false;
- }
- if(!((major == req_major && minor >= req_minor) || (major > req_major))) {
- if(error != NULL) {
- *error = string_printf("OpenCL: C version 1.1 or later required, found %d.%d", major, minor);
- }
- return false;
- }
- if(error != NULL) {
- *error = "";
- }
- return true;
+ const int req_major = 1, req_minor = 1;
+ int major, minor;
+ char version[256];
+ clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, sizeof(version), &version, NULL);
+ if (sscanf(version, "OpenCL C %d.%d", &major, &minor) < 2) {
+ if (error != NULL) {
+ *error = string_printf("OpenCL: failed to parse OpenCL C version string (%s).", version);
+ }
+ return false;
+ }
+ if (!((major == req_major && minor >= req_minor) || (major > req_major))) {
+ if (error != NULL) {
+ *error = string_printf("OpenCL: C version 1.1 or later required, found %d.%d", major, minor);
+ }
+ return false;
+ }
+ if (error != NULL) {
+ *error = "";
+ }
+ return true;
}
-string OpenCLInfo::get_hardware_id(const string& platform_name, cl_device_id device_id)
+string OpenCLInfo::get_hardware_id(const string &platform_name, cl_device_id device_id)
{
- if(platform_name == "AMD Accelerated Parallel Processing" || platform_name == "Apple") {
- /* Use cl_amd_device_topology extension. */
- cl_char topology[24];
- if(clGetDeviceInfo(device_id, 0x4037, sizeof(topology), topology, NULL) == CL_SUCCESS && topology[0] == 1) {
- return string_printf("%02x:%02x.%01x",
- (unsigned int)topology[21],
- (unsigned int)topology[22],
- (unsigned int)topology[23]);
- }
- }
- else if(platform_name == "NVIDIA CUDA") {
- /* Use two undocumented options of the cl_nv_device_attribute_query extension. */
- cl_int bus_id, slot_id;
- if(clGetDeviceInfo(device_id, 0x4008, sizeof(cl_int), &bus_id, NULL) == CL_SUCCESS &&
- clGetDeviceInfo(device_id, 0x4009, sizeof(cl_int), &slot_id, NULL) == CL_SUCCESS) {
- return string_printf("%02x:%02x.%01x",
- (unsigned int)(bus_id),
- (unsigned int)(slot_id >> 3),
- (unsigned int)(slot_id & 0x7));
- }
- }
- /* No general way to get a hardware ID from OpenCL => give up. */
- return "";
+ if (platform_name == "AMD Accelerated Parallel Processing" || platform_name == "Apple") {
+ /* Use cl_amd_device_topology extension. */
+ cl_char topology[24];
+ if (clGetDeviceInfo(device_id, 0x4037, sizeof(topology), topology, NULL) == CL_SUCCESS &&
+ topology[0] == 1) {
+ return string_printf("%02x:%02x.%01x",
+ (unsigned int)topology[21],
+ (unsigned int)topology[22],
+ (unsigned int)topology[23]);
+ }
+ }
+ else if (platform_name == "NVIDIA CUDA") {
+ /* Use two undocumented options of the cl_nv_device_attribute_query extension. */
+ cl_int bus_id, slot_id;
+ if (clGetDeviceInfo(device_id, 0x4008, sizeof(cl_int), &bus_id, NULL) == CL_SUCCESS &&
+ clGetDeviceInfo(device_id, 0x4009, sizeof(cl_int), &slot_id, NULL) == CL_SUCCESS) {
+ return string_printf("%02x:%02x.%01x",
+ (unsigned int)(bus_id),
+ (unsigned int)(slot_id >> 3),
+ (unsigned int)(slot_id & 0x7));
+ }
+ }
+ /* No general way to get a hardware ID from OpenCL => give up. */
+ return "";
}
-void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices,
- bool force_all)
+void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices, bool force_all)
{
- const cl_device_type device_type = OpenCLInfo::device_type();
- static bool first_time = true;
-#define FIRST_VLOG(severity) if(first_time) VLOG(severity)
-
- usable_devices->clear();
-
- if(device_type == 0) {
- FIRST_VLOG(2) << "OpenCL devices are forced to be disabled.";
- first_time = false;
- return;
- }
-
- cl_int error;
- vector<cl_device_id> device_ids;
- vector<cl_platform_id> platform_ids;
-
- /* Get platforms. */
- if(!get_platforms(&platform_ids, &error)) {
- FIRST_VLOG(2) << "Error fetching platforms:"
- << string(clewErrorString(error));
- first_time = false;
- return;
- }
- if(platform_ids.size() == 0) {
- FIRST_VLOG(2) << "No OpenCL platforms were found.";
- first_time = false;
- return;
- }
- /* Devices are numbered consecutively across platforms. */
- for(int platform = 0; platform < platform_ids.size(); platform++) {
- cl_platform_id platform_id = platform_ids[platform];
- string platform_name;
- if(!get_platform_name(platform_id, &platform_name)) {
- FIRST_VLOG(2) << "Failed to get platform name, ignoring.";
- continue;
- }
- FIRST_VLOG(2) << "Enumerating devices for platform "
- << platform_name << ".";
- if(!platform_version_check(platform_id)) {
- FIRST_VLOG(2) << "Ignoring platform " << platform_name
- << " due to too old compiler version.";
- continue;
- }
- if(!get_platform_devices(platform_id,
- device_type,
- &device_ids,
- &error))
- {
- FIRST_VLOG(2) << "Ignoring platform " << platform_name
- << ", failed to fetch of devices: "
- << string(clewErrorString(error));
- continue;
- }
- if(device_ids.size() == 0) {
- FIRST_VLOG(2) << "Ignoring platform " << platform_name
- << ", it has no devices.";
- continue;
- }
- for(int num = 0; num < device_ids.size(); num++) {
- const cl_device_id device_id = device_ids[num];
- string device_name;
- if(!get_device_name(device_id, &device_name, &error)) {
- FIRST_VLOG(2) << "Failed to fetch device name: "
- << string(clewErrorString(error))
- << ", ignoring.";
- continue;
- }
- if(!device_version_check(device_id)) {
- FIRST_VLOG(2) << "Ignoring device " << device_name
- << " due to old compiler version.";
- continue;
- }
- if(force_all ||
- device_supported(platform_name, device_id))
- {
- cl_device_type device_type;
- if(!get_device_type(device_id, &device_type, &error)) {
- FIRST_VLOG(2) << "Ignoring device " << device_name
- << ", failed to fetch device type:"
- << string(clewErrorString(error));
- continue;
- }
- string readable_device_name =
- get_readable_device_name(device_id);
- if(readable_device_name != device_name) {
- FIRST_VLOG(2) << "Using more readable device name: "
- << readable_device_name;
- }
- FIRST_VLOG(2) << "Adding new device "
- << readable_device_name << ".";
- string hardware_id = get_hardware_id(platform_name, device_id);
- string device_extensions = get_device_extensions(device_id);
- usable_devices->push_back(OpenCLPlatformDevice(
- platform_id,
- platform_name,
- device_id,
- device_type,
- readable_device_name,
- hardware_id,
- device_extensions));
- }
- else {
- FIRST_VLOG(2) << "Ignoring device " << device_name
- << ", not officially supported yet.";
- }
- }
- }
- first_time = false;
+ const cl_device_type device_type = OpenCLInfo::device_type();
+ static bool first_time = true;
+# define FIRST_VLOG(severity) \
+ if (first_time) \
+ VLOG(severity)
+
+ usable_devices->clear();
+
+ if (device_type == 0) {
+ FIRST_VLOG(2) << "OpenCL devices are forced to be disabled.";
+ first_time = false;
+ return;
+ }
+
+ cl_int error;
+ vector<cl_device_id> device_ids;
+ vector<cl_platform_id> platform_ids;
+
+ /* Get platforms. */
+ if (!get_platforms(&platform_ids, &error)) {
+ FIRST_VLOG(2) << "Error fetching platforms:" << string(clewErrorString(error));
+ first_time = false;
+ return;
+ }
+ if (platform_ids.size() == 0) {
+ FIRST_VLOG(2) << "No OpenCL platforms were found.";
+ first_time = false;
+ return;
+ }
+ /* Devices are numbered consecutively across platforms. */
+ for (int platform = 0; platform < platform_ids.size(); platform++) {
+ cl_platform_id platform_id = platform_ids[platform];
+ string platform_name;
+ if (!get_platform_name(platform_id, &platform_name)) {
+ FIRST_VLOG(2) << "Failed to get platform name, ignoring.";
+ continue;
+ }
+ FIRST_VLOG(2) << "Enumerating devices for platform " << platform_name << ".";
+ if (!platform_version_check(platform_id)) {
+ FIRST_VLOG(2) << "Ignoring platform " << platform_name
+ << " due to too old compiler version.";
+ continue;
+ }
+ if (!get_platform_devices(platform_id, device_type, &device_ids, &error)) {
+ FIRST_VLOG(2) << "Ignoring platform " << platform_name
+ << ", failed to fetch of devices: " << string(clewErrorString(error));
+ continue;
+ }
+ if (device_ids.size() == 0) {
+ FIRST_VLOG(2) << "Ignoring platform " << platform_name << ", it has no devices.";
+ continue;
+ }
+ for (int num = 0; num < device_ids.size(); num++) {
+ const cl_device_id device_id = device_ids[num];
+ string device_name;
+ if (!get_device_name(device_id, &device_name, &error)) {
+ FIRST_VLOG(2) << "Failed to fetch device name: " << string(clewErrorString(error))
+ << ", ignoring.";
+ continue;
+ }
+ if (!device_version_check(device_id)) {
+ FIRST_VLOG(2) << "Ignoring device " << device_name << " due to old compiler version.";
+ continue;
+ }
+ if (force_all || device_supported(platform_name, device_id)) {
+ cl_device_type device_type;
+ if (!get_device_type(device_id, &device_type, &error)) {
+ FIRST_VLOG(2) << "Ignoring device " << device_name
+ << ", failed to fetch device type:" << string(clewErrorString(error));
+ continue;
+ }
+ string readable_device_name = get_readable_device_name(device_id);
+ if (readable_device_name != device_name) {
+ FIRST_VLOG(2) << "Using more readable device name: " << readable_device_name;
+ }
+ FIRST_VLOG(2) << "Adding new device " << readable_device_name << ".";
+ string hardware_id = get_hardware_id(platform_name, device_id);
+ string device_extensions = get_device_extensions(device_id);
+ usable_devices->push_back(OpenCLPlatformDevice(platform_id,
+ platform_name,
+ device_id,
+ device_type,
+ readable_device_name,
+ hardware_id,
+ device_extensions));
+ }
+ else {
+ FIRST_VLOG(2) << "Ignoring device " << device_name << ", not officially supported yet.";
+ }
+ }
+ }
+ first_time = false;
}
-bool OpenCLInfo::get_platforms(vector<cl_platform_id> *platform_ids,
- cl_int *error)
+bool OpenCLInfo::get_platforms(vector<cl_platform_id> *platform_ids, cl_int *error)
{
- /* Reset from possible previous state. */
- platform_ids->resize(0);
- cl_uint num_platforms;
- if(!get_num_platforms(&num_platforms, error)) {
- return false;
- }
- /* Get actual platforms. */
- cl_int err;
- platform_ids->resize(num_platforms);
- if((err = clGetPlatformIDs(num_platforms,
- &platform_ids->at(0),
- NULL)) != CL_SUCCESS) {
- if(error != NULL) {
- *error = err;
- }
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- return true;
+ /* Reset from possible previous state. */
+ platform_ids->resize(0);
+ cl_uint num_platforms;
+ if (!get_num_platforms(&num_platforms, error)) {
+ return false;
+ }
+ /* Get actual platforms. */
+ cl_int err;
+ platform_ids->resize(num_platforms);
+ if ((err = clGetPlatformIDs(num_platforms, &platform_ids->at(0), NULL)) != CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
}
vector<cl_platform_id> OpenCLInfo::get_platforms()
{
- vector<cl_platform_id> platform_ids;
- get_platforms(&platform_ids);
- return platform_ids;
+ vector<cl_platform_id> platform_ids;
+ get_platforms(&platform_ids);
+ return platform_ids;
}
bool OpenCLInfo::get_num_platforms(cl_uint *num_platforms, cl_int *error)
{
- cl_int err;
- if((err = clGetPlatformIDs(0, NULL, num_platforms)) != CL_SUCCESS) {
- if(error != NULL) {
- *error = err;
- }
- *num_platforms = 0;
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- return true;
+ cl_int err;
+ if ((err = clGetPlatformIDs(0, NULL, num_platforms)) != CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ *num_platforms = 0;
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
}
cl_uint OpenCLInfo::get_num_platforms()
{
- cl_uint num_platforms;
- if(!get_num_platforms(&num_platforms)) {
- return 0;
- }
- return num_platforms;
+ cl_uint num_platforms;
+ if (!get_num_platforms(&num_platforms)) {
+ return 0;
+ }
+ return num_platforms;
}
-bool OpenCLInfo::get_platform_name(cl_platform_id platform_id,
- string *platform_name)
+bool OpenCLInfo::get_platform_name(cl_platform_id platform_id, string *platform_name)
{
- char buffer[256];
- if(clGetPlatformInfo(platform_id,
- CL_PLATFORM_NAME,
- sizeof(buffer),
- &buffer,
- NULL) != CL_SUCCESS)
- {
- *platform_name = "";
- return false;
- }
- *platform_name = buffer;
- return true;
+ char buffer[256];
+ if (clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sizeof(buffer), &buffer, NULL) !=
+ CL_SUCCESS) {
+ *platform_name = "";
+ return false;
+ }
+ *platform_name = buffer;
+ return true;
}
string OpenCLInfo::get_platform_name(cl_platform_id platform_id)
{
- string platform_name;
- if(!get_platform_name(platform_id, &platform_name)) {
- return "";
- }
- return platform_name;
+ string platform_name;
+ if (!get_platform_name(platform_id, &platform_name)) {
+ return "";
+ }
+ return platform_name;
}
bool OpenCLInfo::get_num_platform_devices(cl_platform_id platform_id,
@@ -1076,266 +1034,222 @@ bool OpenCLInfo::get_num_platform_devices(cl_platform_id platform_id,
cl_uint *num_devices,
cl_int *error)
{
- cl_int err;
- if((err = clGetDeviceIDs(platform_id,
- device_type,
- 0,
- NULL,
- num_devices)) != CL_SUCCESS)
- {
- if(error != NULL) {
- *error = err;
- }
- *num_devices = 0;
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- return true;
+ cl_int err;
+ if ((err = clGetDeviceIDs(platform_id, device_type, 0, NULL, num_devices)) != CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ *num_devices = 0;
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
}
cl_uint OpenCLInfo::get_num_platform_devices(cl_platform_id platform_id,
cl_device_type device_type)
{
- cl_uint num_devices;
- if(!get_num_platform_devices(platform_id,
- device_type,
- &num_devices))
- {
- return 0;
- }
- return num_devices;
+ cl_uint num_devices;
+ if (!get_num_platform_devices(platform_id, device_type, &num_devices)) {
+ return 0;
+ }
+ return num_devices;
}
bool OpenCLInfo::get_platform_devices(cl_platform_id platform_id,
cl_device_type device_type,
vector<cl_device_id> *device_ids,
- cl_int* error)
+ cl_int *error)
{
- /* Reset from possible previous state. */
- device_ids->resize(0);
- /* Get number of devices to pre-allocate memory. */
- cl_uint num_devices;
- if(!get_num_platform_devices(platform_id,
- device_type,
- &num_devices,
- error))
- {
- return false;
- }
- /* Get actual device list. */
- device_ids->resize(num_devices);
- cl_int err;
- if((err = clGetDeviceIDs(platform_id,
- device_type,
- num_devices,
- &device_ids->at(0),
- NULL)) != CL_SUCCESS)
- {
- if(error != NULL) {
- *error = err;
- }
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- return true;
+ /* Reset from possible previous state. */
+ device_ids->resize(0);
+ /* Get number of devices to pre-allocate memory. */
+ cl_uint num_devices;
+ if (!get_num_platform_devices(platform_id, device_type, &num_devices, error)) {
+ return false;
+ }
+ /* Get actual device list. */
+ device_ids->resize(num_devices);
+ cl_int err;
+ if ((err = clGetDeviceIDs(platform_id, device_type, num_devices, &device_ids->at(0), NULL)) !=
+ CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
}
vector<cl_device_id> OpenCLInfo::get_platform_devices(cl_platform_id platform_id,
cl_device_type device_type)
{
- vector<cl_device_id> devices;
- get_platform_devices(platform_id, device_type, &devices);
- return devices;
+ vector<cl_device_id> devices;
+ get_platform_devices(platform_id, device_type, &devices);
+ return devices;
}
-bool OpenCLInfo::get_device_name(cl_device_id device_id,
- string *device_name,
- cl_int* error)
+bool OpenCLInfo::get_device_name(cl_device_id device_id, string *device_name, cl_int *error)
{
- char buffer[1024];
- cl_int err;
- if((err = clGetDeviceInfo(device_id,
- CL_DEVICE_NAME,
- sizeof(buffer),
- &buffer,
- NULL)) != CL_SUCCESS)
- {
- if(error != NULL) {
- *error = err;
- }
- *device_name = "";
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- *device_name = buffer;
- return true;
+ char buffer[1024];
+ cl_int err;
+ if ((err = clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(buffer), &buffer, NULL)) !=
+ CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ *device_name = "";
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ *device_name = buffer;
+ return true;
}
string OpenCLInfo::get_device_name(cl_device_id device_id)
{
- string device_name;
- if(!get_device_name(device_id, &device_name)) {
- return "";
- }
- return device_name;
+ string device_name;
+ if (!get_device_name(device_id, &device_name)) {
+ return "";
+ }
+ return device_name;
}
bool OpenCLInfo::get_device_extensions(cl_device_id device_id,
- string *device_extensions,
- cl_int* error)
+ string *device_extensions,
+ cl_int *error)
{
- char buffer[1024];
- cl_int err;
- if((err = clGetDeviceInfo(device_id,
- CL_DEVICE_EXTENSIONS,
- sizeof(buffer),
- &buffer,
- NULL)) != CL_SUCCESS)
- {
- if(error != NULL) {
- *error = err;
- }
- *device_extensions = "";
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- *device_extensions = buffer;
- return true;
+ char buffer[1024];
+ cl_int err;
+ if ((err = clGetDeviceInfo(device_id, CL_DEVICE_EXTENSIONS, sizeof(buffer), &buffer, NULL)) !=
+ CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ *device_extensions = "";
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ *device_extensions = buffer;
+ return true;
}
string OpenCLInfo::get_device_extensions(cl_device_id device_id)
{
- string device_extensions;
- if(!get_device_extensions(device_id, &device_extensions)) {
- return "";
- }
- return device_extensions;
+ string device_extensions;
+ if (!get_device_extensions(device_id, &device_extensions)) {
+ return "";
+ }
+ return device_extensions;
}
bool OpenCLInfo::get_device_type(cl_device_id device_id,
cl_device_type *device_type,
- cl_int* error)
+ cl_int *error)
{
- cl_int err;
- if((err = clGetDeviceInfo(device_id,
- CL_DEVICE_TYPE,
- sizeof(cl_device_type),
- device_type,
- NULL)) != CL_SUCCESS)
- {
- if(error != NULL) {
- *error = err;
- }
- *device_type = 0;
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- return true;
+ cl_int err;
+ if ((err = clGetDeviceInfo(
+ device_id, CL_DEVICE_TYPE, sizeof(cl_device_type), device_type, NULL)) != CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ *device_type = 0;
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
}
cl_device_type OpenCLInfo::get_device_type(cl_device_id device_id)
{
- cl_device_type device_type;
- if(!get_device_type(device_id, &device_type)) {
- return 0;
- }
- return device_type;
+ cl_device_type device_type;
+ if (!get_device_type(device_id, &device_type)) {
+ return 0;
+ }
+ return device_type;
}
string OpenCLInfo::get_readable_device_name(cl_device_id device_id)
{
- string name = "";
- char board_name[1024];
- size_t length = 0;
- if(clGetDeviceInfo(device_id,
- CL_DEVICE_BOARD_NAME_AMD,
- sizeof(board_name),
- &board_name,
- &length) == CL_SUCCESS)
- {
- if(length != 0 && board_name[0] != '\0') {
- name = board_name;
- }
- }
-
- /* Fallback to standard device name API. */
- if(name.empty()) {
- name = get_device_name(device_id);
- }
-
- /* Special exception for AMD Vega, need to be able to tell
- * Vega 56 from 64 apart.
- */
- if(name == "Radeon RX Vega") {
- cl_int max_compute_units = 0;
- if(clGetDeviceInfo(device_id,
- CL_DEVICE_MAX_COMPUTE_UNITS,
- sizeof(max_compute_units),
- &max_compute_units,
- NULL) == CL_SUCCESS)
- {
- name += " " + to_string(max_compute_units);
- }
- }
-
- /* Distinguish from our native CPU device. */
- if(get_device_type(device_id) & CL_DEVICE_TYPE_CPU) {
- name += " (OpenCL)";
- }
-
- return name;
+ string name = "";
+ char board_name[1024];
+ size_t length = 0;
+ if (clGetDeviceInfo(
+ device_id, CL_DEVICE_BOARD_NAME_AMD, sizeof(board_name), &board_name, &length) ==
+ CL_SUCCESS) {
+ if (length != 0 && board_name[0] != '\0') {
+ name = board_name;
+ }
+ }
+
+ /* Fallback to standard device name API. */
+ if (name.empty()) {
+ name = get_device_name(device_id);
+ }
+
+ /* Special exception for AMD Vega, need to be able to tell
+ * Vega 56 from 64 apart.
+ */
+ if (name == "Radeon RX Vega") {
+ cl_int max_compute_units = 0;
+ if (clGetDeviceInfo(device_id,
+ CL_DEVICE_MAX_COMPUTE_UNITS,
+ sizeof(max_compute_units),
+ &max_compute_units,
+ NULL) == CL_SUCCESS) {
+ name += " " + to_string(max_compute_units);
+ }
+ }
+
+ /* Distinguish from our native CPU device. */
+ if (get_device_type(device_id) & CL_DEVICE_TYPE_CPU) {
+ name += " (OpenCL)";
+ }
+
+ return name;
}
-bool OpenCLInfo::get_driver_version(cl_device_id device_id,
- int *major,
- int *minor,
- cl_int* error)
+bool OpenCLInfo::get_driver_version(cl_device_id device_id, int *major, int *minor, cl_int *error)
{
- char buffer[1024];
- cl_int err;
- if((err = clGetDeviceInfo(device_id,
- CL_DRIVER_VERSION,
- sizeof(buffer),
- &buffer,
- NULL)) != CL_SUCCESS)
- {
- if(error != NULL) {
- *error = err;
- }
- return false;
- }
- if(error != NULL) {
- *error = CL_SUCCESS;
- }
- if(sscanf(buffer, "%d.%d", major, minor) < 2) {
- VLOG(1) << string_printf("OpenCL: failed to parse driver version string (%s).", buffer);
- return false;
- }
- return true;
+ char buffer[1024];
+ cl_int err;
+ if ((err = clGetDeviceInfo(device_id, CL_DRIVER_VERSION, sizeof(buffer), &buffer, NULL)) !=
+ CL_SUCCESS) {
+ if (error != NULL) {
+ *error = err;
+ }
+ return false;
+ }
+ if (error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ if (sscanf(buffer, "%d.%d", major, minor) < 2) {
+ VLOG(1) << string_printf("OpenCL: failed to parse driver version string (%s).", buffer);
+ return false;
+ }
+ return true;
}
int OpenCLInfo::mem_sub_ptr_alignment(cl_device_id device_id)
{
- int base_align_bits;
- if(clGetDeviceInfo(device_id,
- CL_DEVICE_MEM_BASE_ADDR_ALIGN,
- sizeof(int),
- &base_align_bits,
- NULL) == CL_SUCCESS)
- {
- return base_align_bits/8;
- }
- return 1;
+ int base_align_bits;
+ if (clGetDeviceInfo(
+ device_id, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(int), &base_align_bits, NULL) ==
+ CL_SUCCESS) {
+ return base_align_bits / 8;
+ }
+ return 1;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/doc/license/CMakeLists.txt b/intern/cycles/doc/license/CMakeLists.txt
index 2f8fe92ad5c..2d8651b6ea1 100644
--- a/intern/cycles/doc/license/CMakeLists.txt
+++ b/intern/cycles/doc/license/CMakeLists.txt
@@ -1,11 +1,11 @@
set(LICENSES
- Apache_2.0.txt
- ILM.txt
- NVidia.txt
- OSL.txt
- Sobol.txt
- readme.txt
+ Apache_2.0.txt
+ ILM.txt
+ NVidia.txt
+ OSL.txt
+ Sobol.txt
+ readme.txt
)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${LICENSES}" ${CYCLES_INSTALL_PATH}/license)
diff --git a/intern/cycles/graph/CMakeLists.txt b/intern/cycles/graph/CMakeLists.txt
index bd2b2728a29..c6c46941598 100644
--- a/intern/cycles/graph/CMakeLists.txt
+++ b/intern/cycles/graph/CMakeLists.txt
@@ -1,19 +1,19 @@
set(INC
- ..
+ ..
)
set(SRC
- node.cpp
- node_type.cpp
- node_xml.cpp
+ node.cpp
+ node_type.cpp
+ node_xml.cpp
)
set(SRC_HEADERS
- node.h
- node_enum.h
- node_type.h
- node_xml.h
+ node.h
+ node_enum.h
+ node_type.h
+ node_xml.h
)
set(LIB
diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp
index 19fe0a168ea..fc7daaeeaa6 100644
--- a/intern/cycles/graph/node.cpp
+++ b/intern/cycles/graph/node.cpp
@@ -26,550 +26,645 @@ CCL_NAMESPACE_BEGIN
/* Node Type */
-Node::Node(const NodeType *type_, ustring name_)
-: name(name_), type(type_)
+Node::Node(const NodeType *type_, ustring name_) : name(name_), type(type_)
{
- assert(type);
+ assert(type);
- /* assign non-empty name, convenient for debugging */
- if(name.empty()) {
- name = type->name;
- }
+ /* assign non-empty name, convenient for debugging */
+ if (name.empty()) {
+ name = type->name;
+ }
- /* initialize default values */
- foreach(const SocketType& socket, type->inputs) {
- set_default_value(socket);
- }
+ /* initialize default values */
+ foreach (const SocketType &socket, type->inputs) {
+ set_default_value(socket);
+ }
}
Node::~Node()
{
}
-template<typename T>
-static T& get_socket_value(const Node *node, const SocketType& socket)
+template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket)
{
- return (T&)*(((char*)node) + socket.struct_offset);
+ return (T &)*(((char *)node) + socket.struct_offset);
}
#ifndef NDEBUG
-static bool is_socket_float3(const SocketType& socket)
+static bool is_socket_float3(const SocketType &socket)
{
- return socket.type == SocketType::COLOR ||
- socket.type == SocketType::POINT ||
- socket.type == SocketType::VECTOR ||
- socket.type == SocketType::NORMAL;
+ return socket.type == SocketType::COLOR || socket.type == SocketType::POINT ||
+ socket.type == SocketType::VECTOR || socket.type == SocketType::NORMAL;
}
-static bool is_socket_array_float3(const SocketType& socket)
+static bool is_socket_array_float3(const SocketType &socket)
{
- return socket.type == SocketType::COLOR_ARRAY ||
- socket.type == SocketType::POINT_ARRAY ||
- socket.type == SocketType::VECTOR_ARRAY ||
- socket.type == SocketType::NORMAL_ARRAY;
+ return socket.type == SocketType::COLOR_ARRAY || socket.type == SocketType::POINT_ARRAY ||
+ socket.type == SocketType::VECTOR_ARRAY || socket.type == SocketType::NORMAL_ARRAY;
}
#endif
/* set values */
-void Node::set(const SocketType& input, bool value)
+void Node::set(const SocketType &input, bool value)
{
- assert(input.type == SocketType::BOOLEAN);
- get_socket_value<bool>(this, input) = value;
+ assert(input.type == SocketType::BOOLEAN);
+ get_socket_value<bool>(this, input) = value;
}
-void Node::set(const SocketType& input, int value)
+void Node::set(const SocketType &input, int value)
{
- assert((input.type == SocketType::INT || input.type == SocketType::ENUM));
- get_socket_value<int>(this, input) = value;
+ assert((input.type == SocketType::INT || input.type == SocketType::ENUM));
+ get_socket_value<int>(this, input) = value;
}
-void Node::set(const SocketType& input, uint value)
+void Node::set(const SocketType &input, uint value)
{
- assert(input.type == SocketType::UINT);
- get_socket_value<uint>(this, input) = value;
+ assert(input.type == SocketType::UINT);
+ get_socket_value<uint>(this, input) = value;
}
-void Node::set(const SocketType& input, float value)
+void Node::set(const SocketType &input, float value)
{
- assert(input.type == SocketType::FLOAT);
- get_socket_value<float>(this, input) = value;
+ assert(input.type == SocketType::FLOAT);
+ get_socket_value<float>(this, input) = value;
}
-void Node::set(const SocketType& input, float2 value)
+void Node::set(const SocketType &input, float2 value)
{
- assert(input.type == SocketType::FLOAT);
- get_socket_value<float2>(this, input) = value;
+ assert(input.type == SocketType::FLOAT);
+ get_socket_value<float2>(this, input) = value;
}
-void Node::set(const SocketType& input, float3 value)
+void Node::set(const SocketType &input, float3 value)
{
- assert(is_socket_float3(input));
- get_socket_value<float3>(this, input) = value;
+ assert(is_socket_float3(input));
+ get_socket_value<float3>(this, input) = value;
}
-void Node::set(const SocketType& input, const char *value)
+void Node::set(const SocketType &input, const char *value)
{
- set(input, ustring(value));
+ set(input, ustring(value));
}
-void Node::set(const SocketType& input, ustring value)
+void Node::set(const SocketType &input, ustring value)
{
- if(input.type == SocketType::STRING) {
- get_socket_value<ustring>(this, input) = value;
- }
- else if(input.type == SocketType::ENUM) {
- const NodeEnum& enm = *input.enum_values;
- if(enm.exists(value)) {
- get_socket_value<int>(this, input) = enm[value];
- }
- else {
- assert(0);
- }
- }
- else {
- assert(0);
- }
+ if (input.type == SocketType::STRING) {
+ get_socket_value<ustring>(this, input) = value;
+ }
+ else if (input.type == SocketType::ENUM) {
+ const NodeEnum &enm = *input.enum_values;
+ if (enm.exists(value)) {
+ get_socket_value<int>(this, input) = enm[value];
+ }
+ else {
+ assert(0);
+ }
+ }
+ else {
+ assert(0);
+ }
}
-void Node::set(const SocketType& input, const Transform& value)
+void Node::set(const SocketType &input, const Transform &value)
{
- assert(input.type == SocketType::TRANSFORM);
- get_socket_value<Transform>(this, input) = value;
+ assert(input.type == SocketType::TRANSFORM);
+ get_socket_value<Transform>(this, input) = value;
}
-void Node::set(const SocketType& input, Node *value)
+void Node::set(const SocketType &input, Node *value)
{
- assert(input.type == SocketType::TRANSFORM);
- get_socket_value<Node*>(this, input) = value;
+ assert(input.type == SocketType::TRANSFORM);
+ get_socket_value<Node *>(this, input) = value;
}
/* set array values */
-void Node::set(const SocketType& input, array<bool>& value)
+void Node::set(const SocketType &input, array<bool> &value)
{
- assert(input.type == SocketType::BOOLEAN_ARRAY);
- get_socket_value<array<bool> >(this, input).steal_data(value);
+ assert(input.type == SocketType::BOOLEAN_ARRAY);
+ get_socket_value<array<bool>>(this, input).steal_data(value);
}
-void Node::set(const SocketType& input, array<int>& value)
+void Node::set(const SocketType &input, array<int> &value)
{
- assert(input.type == SocketType::INT_ARRAY);
- get_socket_value<array<int> >(this, input).steal_data(value);
+ assert(input.type == SocketType::INT_ARRAY);
+ get_socket_value<array<int>>(this, input).steal_data(value);
}
-void Node::set(const SocketType& input, array<float>& value)
+void Node::set(const SocketType &input, array<float> &value)
{
- assert(input.type == SocketType::FLOAT_ARRAY);
- get_socket_value<array<float> >(this, input).steal_data(value);
+ assert(input.type == SocketType::FLOAT_ARRAY);
+ get_socket_value<array<float>>(this, input).steal_data(value);
}
-void Node::set(const SocketType& input, array<float2>& value)
+void Node::set(const SocketType &input, array<float2> &value)
{
- assert(input.type == SocketType::FLOAT_ARRAY);
- get_socket_value<array<float2> >(this, input).steal_data(value);
+ assert(input.type == SocketType::FLOAT_ARRAY);
+ get_socket_value<array<float2>>(this, input).steal_data(value);
}
-void Node::set(const SocketType& input, array<float3>& value)
+void Node::set(const SocketType &input, array<float3> &value)
{
- assert(is_socket_array_float3(input));
- get_socket_value<array<float3> >(this, input).steal_data(value);
+ assert(is_socket_array_float3(input));
+ get_socket_value<array<float3>>(this, input).steal_data(value);
}
-void Node::set(const SocketType& input, array<ustring>& value)
+void Node::set(const SocketType &input, array<ustring> &value)
{
- assert(input.type == SocketType::STRING_ARRAY);
- get_socket_value<array<ustring> >(this, input).steal_data(value);
+ assert(input.type == SocketType::STRING_ARRAY);
+ get_socket_value<array<ustring>>(this, input).steal_data(value);
}
-void Node::set(const SocketType& input, array<Transform>& value)
+void Node::set(const SocketType &input, array<Transform> &value)
{
- assert(input.type == SocketType::TRANSFORM_ARRAY);
- get_socket_value<array<Transform> >(this, input).steal_data(value);
+ assert(input.type == SocketType::TRANSFORM_ARRAY);
+ get_socket_value<array<Transform>>(this, input).steal_data(value);
}
-void Node::set(const SocketType& input, array<Node*>& value)
+void Node::set(const SocketType &input, array<Node *> &value)
{
- assert(input.type == SocketType::TRANSFORM_ARRAY);
- get_socket_value<array<Node*> >(this, input).steal_data(value);
+ assert(input.type == SocketType::TRANSFORM_ARRAY);
+ get_socket_value<array<Node *>>(this, input).steal_data(value);
}
/* get values */
-bool Node::get_bool(const SocketType& input) const
+bool Node::get_bool(const SocketType &input) const
{
- assert(input.type == SocketType::BOOLEAN);
- return get_socket_value<bool>(this, input);
+ assert(input.type == SocketType::BOOLEAN);
+ return get_socket_value<bool>(this, input);
}
-int Node::get_int(const SocketType& input) const
+int Node::get_int(const SocketType &input) const
{
- assert(input.type == SocketType::INT || input.type == SocketType::ENUM);
- return get_socket_value<int>(this, input);
+ assert(input.type == SocketType::INT || input.type == SocketType::ENUM);
+ return get_socket_value<int>(this, input);
}
-uint Node::get_uint(const SocketType& input) const
+uint Node::get_uint(const SocketType &input) const
{
- assert(input.type == SocketType::UINT);
- return get_socket_value<uint>(this, input);
+ assert(input.type == SocketType::UINT);
+ return get_socket_value<uint>(this, input);
}
-float Node::get_float(const SocketType& input) const
+float Node::get_float(const SocketType &input) const
{
- assert(input.type == SocketType::FLOAT);
- return get_socket_value<float>(this, input);
+ assert(input.type == SocketType::FLOAT);
+ return get_socket_value<float>(this, input);
}
-float2 Node::get_float2(const SocketType& input) const
+float2 Node::get_float2(const SocketType &input) const
{
- assert(input.type == SocketType::FLOAT);
- return get_socket_value<float2>(this, input);
+ assert(input.type == SocketType::FLOAT);
+ return get_socket_value<float2>(this, input);
}
-float3 Node::get_float3(const SocketType& input) const
+float3 Node::get_float3(const SocketType &input) const
{
- assert(is_socket_float3(input));
- return get_socket_value<float3>(this, input);
+ assert(is_socket_float3(input));
+ return get_socket_value<float3>(this, input);
}
-ustring Node::get_string(const SocketType& input) const
+ustring Node::get_string(const SocketType &input) const
{
- if(input.type == SocketType::STRING) {
- return get_socket_value<ustring>(this, input);
- }
- else if(input.type == SocketType::ENUM) {
- const NodeEnum& enm = *input.enum_values;
- int intvalue = get_socket_value<int>(this, input);
- return (enm.exists(intvalue)) ? enm[intvalue] : ustring();
- }
- else {
- assert(0);
- return ustring();
- }
+ if (input.type == SocketType::STRING) {
+ return get_socket_value<ustring>(this, input);
+ }
+ else if (input.type == SocketType::ENUM) {
+ const NodeEnum &enm = *input.enum_values;
+ int intvalue = get_socket_value<int>(this, input);
+ return (enm.exists(intvalue)) ? enm[intvalue] : ustring();
+ }
+ else {
+ assert(0);
+ return ustring();
+ }
}
-Transform Node::get_transform(const SocketType& input) const
+Transform Node::get_transform(const SocketType &input) const
{
- assert(input.type == SocketType::TRANSFORM);
- return get_socket_value<Transform>(this, input);
+ assert(input.type == SocketType::TRANSFORM);
+ return get_socket_value<Transform>(this, input);
}
-Node *Node::get_node(const SocketType& input) const
+Node *Node::get_node(const SocketType &input) const
{
- assert(input.type == SocketType::NODE);
- return get_socket_value<Node*>(this, input);
+ assert(input.type == SocketType::NODE);
+ return get_socket_value<Node *>(this, input);
}
/* get array values */
-const array<bool>& Node::get_bool_array(const SocketType& input) const
+const array<bool> &Node::get_bool_array(const SocketType &input) const
{
- assert(input.type == SocketType::BOOLEAN_ARRAY);
- return get_socket_value<array<bool> >(this, input);
+ assert(input.type == SocketType::BOOLEAN_ARRAY);
+ return get_socket_value<array<bool>>(this, input);
}
-const array<int>& Node::get_int_array(const SocketType& input) const
+const array<int> &Node::get_int_array(const SocketType &input) const
{
- assert(input.type == SocketType::INT_ARRAY);
- return get_socket_value<array<int> >(this, input);
+ assert(input.type == SocketType::INT_ARRAY);
+ return get_socket_value<array<int>>(this, input);
}
-const array<float>& Node::get_float_array(const SocketType& input) const
+const array<float> &Node::get_float_array(const SocketType &input) const
{
- assert(input.type == SocketType::FLOAT_ARRAY);
- return get_socket_value<array<float> >(this, input);
+ assert(input.type == SocketType::FLOAT_ARRAY);
+ return get_socket_value<array<float>>(this, input);
}
-const array<float2>& Node::get_float2_array(const SocketType& input) const
+const array<float2> &Node::get_float2_array(const SocketType &input) const
{
- assert(input.type == SocketType::FLOAT_ARRAY);
- return get_socket_value<array<float2> >(this, input);
+ assert(input.type == SocketType::FLOAT_ARRAY);
+ return get_socket_value<array<float2>>(this, input);
}
-const array<float3>& Node::get_float3_array(const SocketType& input) const
+const array<float3> &Node::get_float3_array(const SocketType &input) const
{
- assert(is_socket_array_float3(input));
- return get_socket_value<array<float3> >(this, input);
+ assert(is_socket_array_float3(input));
+ return get_socket_value<array<float3>>(this, input);
}
-const array<ustring>& Node::get_string_array(const SocketType& input) const
+const array<ustring> &Node::get_string_array(const SocketType &input) const
{
- assert(input.type == SocketType::STRING_ARRAY);
- return get_socket_value<array<ustring> >(this, input);
+ assert(input.type == SocketType::STRING_ARRAY);
+ return get_socket_value<array<ustring>>(this, input);
}
-const array<Transform>& Node::get_transform_array(const SocketType& input) const
+const array<Transform> &Node::get_transform_array(const SocketType &input) const
{
- assert(input.type == SocketType::TRANSFORM_ARRAY);
- return get_socket_value<array<Transform> >(this, input);
+ assert(input.type == SocketType::TRANSFORM_ARRAY);
+ return get_socket_value<array<Transform>>(this, input);
}
-const array<Node*>& Node::get_node_array(const SocketType& input) const
+const array<Node *> &Node::get_node_array(const SocketType &input) const
{
- assert(input.type == SocketType::NODE_ARRAY);
- return get_socket_value<array<Node*> >(this, input);
+ assert(input.type == SocketType::NODE_ARRAY);
+ return get_socket_value<array<Node *>>(this, input);
}
/* generic value operations */
-bool Node::has_default_value(const SocketType& input) const
+bool Node::has_default_value(const SocketType &input) const
{
- const void *src = input.default_value;
- void *dst = &get_socket_value<char>(this, input);
- return memcmp(dst, src, input.size()) == 0;
+ const void *src = input.default_value;
+ void *dst = &get_socket_value<char>(this, input);
+ return memcmp(dst, src, input.size()) == 0;
}
-void Node::set_default_value(const SocketType& socket)
+void Node::set_default_value(const SocketType &socket)
{
- const void *src = socket.default_value;
- void *dst = ((char*)this) + socket.struct_offset;
- memcpy(dst, src, socket.size());
+ const void *src = socket.default_value;
+ void *dst = ((char *)this) + socket.struct_offset;
+ memcpy(dst, src, socket.size());
}
template<typename T>
-static void copy_array(const Node *node, const SocketType& socket, const Node *other, const SocketType& other_socket)
-{
- const array<T>* src = (const array<T>*)(((char*)other) + other_socket.struct_offset);
- array<T>* dst = (array<T>*)(((char*)node) + socket.struct_offset);
- *dst = *src;
-}
-
-void Node::copy_value(const SocketType& socket, const Node& other, const SocketType& other_socket)
-{
- assert(socket.type == other_socket.type);
-
- if(socket.is_array()) {
- switch(socket.type) {
- case SocketType::BOOLEAN_ARRAY: copy_array<bool>(this, socket, &other, other_socket); break;
- case SocketType::FLOAT_ARRAY: copy_array<float>(this, socket, &other, other_socket); break;
- case SocketType::INT_ARRAY: copy_array<int>(this, socket, &other, other_socket); break;
- case SocketType::COLOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
- case SocketType::VECTOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
- case SocketType::POINT_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
- case SocketType::NORMAL_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
- case SocketType::POINT2_ARRAY: copy_array<float2>(this, socket, &other, other_socket); break;
- case SocketType::STRING_ARRAY: copy_array<ustring>(this, socket, &other, other_socket); break;
- case SocketType::TRANSFORM_ARRAY: copy_array<Transform>(this, socket, &other, other_socket); break;
- case SocketType::NODE_ARRAY: copy_array<void*>(this, socket, &other, other_socket); break;
- default: assert(0); break;
- }
- }
- else {
- const void *src = ((char*)&other) + other_socket.struct_offset;
- void *dst = ((char*)this) + socket.struct_offset;
- memcpy(dst, src, socket.size());
- }
+static void copy_array(const Node *node,
+ const SocketType &socket,
+ const Node *other,
+ const SocketType &other_socket)
+{
+ const array<T> *src = (const array<T> *)(((char *)other) + other_socket.struct_offset);
+ array<T> *dst = (array<T> *)(((char *)node) + socket.struct_offset);
+ *dst = *src;
+}
+
+void Node::copy_value(const SocketType &socket, const Node &other, const SocketType &other_socket)
+{
+ assert(socket.type == other_socket.type);
+
+ if (socket.is_array()) {
+ switch (socket.type) {
+ case SocketType::BOOLEAN_ARRAY:
+ copy_array<bool>(this, socket, &other, other_socket);
+ break;
+ case SocketType::FLOAT_ARRAY:
+ copy_array<float>(this, socket, &other, other_socket);
+ break;
+ case SocketType::INT_ARRAY:
+ copy_array<int>(this, socket, &other, other_socket);
+ break;
+ case SocketType::COLOR_ARRAY:
+ copy_array<float3>(this, socket, &other, other_socket);
+ break;
+ case SocketType::VECTOR_ARRAY:
+ copy_array<float3>(this, socket, &other, other_socket);
+ break;
+ case SocketType::POINT_ARRAY:
+ copy_array<float3>(this, socket, &other, other_socket);
+ break;
+ case SocketType::NORMAL_ARRAY:
+ copy_array<float3>(this, socket, &other, other_socket);
+ break;
+ case SocketType::POINT2_ARRAY:
+ copy_array<float2>(this, socket, &other, other_socket);
+ break;
+ case SocketType::STRING_ARRAY:
+ copy_array<ustring>(this, socket, &other, other_socket);
+ break;
+ case SocketType::TRANSFORM_ARRAY:
+ copy_array<Transform>(this, socket, &other, other_socket);
+ break;
+ case SocketType::NODE_ARRAY:
+ copy_array<void *>(this, socket, &other, other_socket);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ else {
+ const void *src = ((char *)&other) + other_socket.struct_offset;
+ void *dst = ((char *)this) + socket.struct_offset;
+ memcpy(dst, src, socket.size());
+ }
}
template<typename T>
-static bool is_array_equal(const Node *node, const Node *other, const SocketType& socket)
+static bool is_array_equal(const Node *node, const Node *other, const SocketType &socket)
{
- const array<T>* a = (const array<T>*)(((char*)node) + socket.struct_offset);
- const array<T>* b = (const array<T>*)(((char*)other) + socket.struct_offset);
- return *a == *b;
+ const array<T> *a = (const array<T> *)(((char *)node) + socket.struct_offset);
+ const array<T> *b = (const array<T> *)(((char *)other) + socket.struct_offset);
+ return *a == *b;
}
template<typename T>
-static bool is_value_equal(const Node *node, const Node *other, const SocketType& socket)
-{
- const T *a = (const T*)(((char*)node) + socket.struct_offset);
- const T *b = (const T*)(((char*)other) + socket.struct_offset);
- return *a == *b;
-}
-
-bool Node::equals_value(const Node& other, const SocketType& socket) const
-{
- switch(socket.type) {
- case SocketType::BOOLEAN: return is_value_equal<bool>(this, &other, socket);
- case SocketType::FLOAT: return is_value_equal<float>(this, &other, socket);
- case SocketType::INT: return is_value_equal<int>(this, &other, socket);
- case SocketType::UINT: return is_value_equal<uint>(this, &other, socket);
- case SocketType::COLOR: return is_value_equal<float3>(this, &other, socket);
- case SocketType::VECTOR: return is_value_equal<float3>(this, &other, socket);
- case SocketType::POINT: return is_value_equal<float3>(this, &other, socket);
- case SocketType::NORMAL: return is_value_equal<float3>(this, &other, socket);
- case SocketType::POINT2: return is_value_equal<float2>(this, &other, socket);
- case SocketType::CLOSURE: return true;
- case SocketType::STRING: return is_value_equal<ustring>(this, &other, socket);
- case SocketType::ENUM: return is_value_equal<int>(this, &other, socket);
- case SocketType::TRANSFORM: return is_value_equal<Transform>(this, &other, socket);
- case SocketType::NODE: return is_value_equal<void*>(this, &other, socket);
-
- case SocketType::BOOLEAN_ARRAY: return is_array_equal<bool>(this, &other, socket);
- case SocketType::FLOAT_ARRAY: return is_array_equal<float>(this, &other, socket);
- case SocketType::INT_ARRAY: return is_array_equal<int>(this, &other, socket);
- case SocketType::COLOR_ARRAY: return is_array_equal<float3>(this, &other, socket);
- case SocketType::VECTOR_ARRAY: return is_array_equal<float3>(this, &other, socket);
- case SocketType::POINT_ARRAY: return is_array_equal<float3>(this, &other, socket);
- case SocketType::NORMAL_ARRAY: return is_array_equal<float3>(this, &other, socket);
- case SocketType::POINT2_ARRAY: return is_array_equal<float2>(this, &other, socket);
- case SocketType::STRING_ARRAY: return is_array_equal<ustring>(this, &other, socket);
- case SocketType::TRANSFORM_ARRAY: return is_array_equal<Transform>(this, &other, socket);
- case SocketType::NODE_ARRAY: return is_array_equal<void*>(this, &other, socket);
-
- case SocketType::UNDEFINED: return true;
- }
-
- return true;
+static bool is_value_equal(const Node *node, const Node *other, const SocketType &socket)
+{
+ const T *a = (const T *)(((char *)node) + socket.struct_offset);
+ const T *b = (const T *)(((char *)other) + socket.struct_offset);
+ return *a == *b;
+}
+
+bool Node::equals_value(const Node &other, const SocketType &socket) const
+{
+ switch (socket.type) {
+ case SocketType::BOOLEAN:
+ return is_value_equal<bool>(this, &other, socket);
+ case SocketType::FLOAT:
+ return is_value_equal<float>(this, &other, socket);
+ case SocketType::INT:
+ return is_value_equal<int>(this, &other, socket);
+ case SocketType::UINT:
+ return is_value_equal<uint>(this, &other, socket);
+ case SocketType::COLOR:
+ return is_value_equal<float3>(this, &other, socket);
+ case SocketType::VECTOR:
+ return is_value_equal<float3>(this, &other, socket);
+ case SocketType::POINT:
+ return is_value_equal<float3>(this, &other, socket);
+ case SocketType::NORMAL:
+ return is_value_equal<float3>(this, &other, socket);
+ case SocketType::POINT2:
+ return is_value_equal<float2>(this, &other, socket);
+ case SocketType::CLOSURE:
+ return true;
+ case SocketType::STRING:
+ return is_value_equal<ustring>(this, &other, socket);
+ case SocketType::ENUM:
+ return is_value_equal<int>(this, &other, socket);
+ case SocketType::TRANSFORM:
+ return is_value_equal<Transform>(this, &other, socket);
+ case SocketType::NODE:
+ return is_value_equal<void *>(this, &other, socket);
+
+ case SocketType::BOOLEAN_ARRAY:
+ return is_array_equal<bool>(this, &other, socket);
+ case SocketType::FLOAT_ARRAY:
+ return is_array_equal<float>(this, &other, socket);
+ case SocketType::INT_ARRAY:
+ return is_array_equal<int>(this, &other, socket);
+ case SocketType::COLOR_ARRAY:
+ return is_array_equal<float3>(this, &other, socket);
+ case SocketType::VECTOR_ARRAY:
+ return is_array_equal<float3>(this, &other, socket);
+ case SocketType::POINT_ARRAY:
+ return is_array_equal<float3>(this, &other, socket);
+ case SocketType::NORMAL_ARRAY:
+ return is_array_equal<float3>(this, &other, socket);
+ case SocketType::POINT2_ARRAY:
+ return is_array_equal<float2>(this, &other, socket);
+ case SocketType::STRING_ARRAY:
+ return is_array_equal<ustring>(this, &other, socket);
+ case SocketType::TRANSFORM_ARRAY:
+ return is_array_equal<Transform>(this, &other, socket);
+ case SocketType::NODE_ARRAY:
+ return is_array_equal<void *>(this, &other, socket);
+
+ case SocketType::UNDEFINED:
+ return true;
+ }
+
+ return true;
}
/* equals */
-bool Node::equals(const Node& other) const
+bool Node::equals(const Node &other) const
{
- assert(type == other.type);
+ assert(type == other.type);
- foreach(const SocketType& socket, type->inputs) {
- if(!equals_value(other, socket))
- return false;
- }
+ foreach (const SocketType &socket, type->inputs) {
+ if (!equals_value(other, socket))
+ return false;
+ }
- return true;
+ return true;
}
/* Hash */
namespace {
-template<typename T>
-void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+template<typename T> void value_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
{
- md5.append(((uint8_t*)node) + socket.struct_offset, socket.size());
+ md5.append(((uint8_t *)node) + socket.struct_offset, socket.size());
}
-void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+void float3_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
{
- /* Don't compare 4th element used for padding. */
- md5.append(((uint8_t*)node) + socket.struct_offset, sizeof(float) * 3);
+ /* Don't compare 4th element used for padding. */
+ md5.append(((uint8_t *)node) + socket.struct_offset, sizeof(float) * 3);
}
-template<typename T>
-void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+template<typename T> void array_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
{
- const array<T>& a = *(const array<T>*)(((char*)node) + socket.struct_offset);
- for(size_t i = 0; i < a.size(); i++) {
- md5.append((uint8_t*)&a[i], sizeof(T));
- }
+ const array<T> &a = *(const array<T> *)(((char *)node) + socket.struct_offset);
+ for (size_t i = 0; i < a.size(); i++) {
+ md5.append((uint8_t *)&a[i], sizeof(T));
+ }
}
-void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+void float3_array_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
{
- /* Don't compare 4th element used for padding. */
- const array<float3>& a = *(const array<float3>*)(((char*)node) + socket.struct_offset);
- for(size_t i = 0; i < a.size(); i++) {
- md5.append((uint8_t*)&a[i], sizeof(float) * 3);
- }
+ /* Don't compare 4th element used for padding. */
+ const array<float3> &a = *(const array<float3> *)(((char *)node) + socket.struct_offset);
+ for (size_t i = 0; i < a.size(); i++) {
+ md5.append((uint8_t *)&a[i], sizeof(float) * 3);
+ }
}
} // namespace
-void Node::hash(MD5Hash& md5)
-{
- md5.append(type->name.string());
-
- foreach(const SocketType& socket, type->inputs) {
- md5.append(socket.name.string());
-
- switch(socket.type) {
- case SocketType::BOOLEAN: value_hash<bool>(this, socket, md5); break;
- case SocketType::FLOAT: value_hash<float>(this, socket, md5); break;
- case SocketType::INT: value_hash<int>(this, socket, md5); break;
- case SocketType::UINT: value_hash<uint>(this, socket, md5); break;
- case SocketType::COLOR: float3_hash(this, socket, md5); break;
- case SocketType::VECTOR: float3_hash(this, socket, md5); break;
- case SocketType::POINT: float3_hash(this, socket, md5); break;
- case SocketType::NORMAL: float3_hash(this, socket, md5); break;
- case SocketType::POINT2: value_hash<float2>(this, socket, md5); break;
- case SocketType::CLOSURE: break;
- case SocketType::STRING: value_hash<ustring>(this, socket, md5); break;
- case SocketType::ENUM: value_hash<int>(this, socket, md5); break;
- case SocketType::TRANSFORM: value_hash<Transform>(this, socket, md5); break;
- case SocketType::NODE: value_hash<void*>(this, socket, md5); break;
-
- case SocketType::BOOLEAN_ARRAY: array_hash<bool>(this, socket, md5); break;
- case SocketType::FLOAT_ARRAY: array_hash<float>(this, socket, md5); break;
- case SocketType::INT_ARRAY: array_hash<int>(this, socket, md5); break;
- case SocketType::COLOR_ARRAY: float3_array_hash(this, socket, md5); break;
- case SocketType::VECTOR_ARRAY: float3_array_hash(this, socket, md5); break;
- case SocketType::POINT_ARRAY: float3_array_hash(this, socket, md5); break;
- case SocketType::NORMAL_ARRAY: float3_array_hash(this, socket, md5); break;
- case SocketType::POINT2_ARRAY: array_hash<float2>(this, socket, md5); break;
- case SocketType::STRING_ARRAY: array_hash<ustring>(this, socket, md5); break;
- case SocketType::TRANSFORM_ARRAY: array_hash<Transform>(this, socket, md5); break;
- case SocketType::NODE_ARRAY: array_hash<void*>(this, socket, md5); break;
-
- case SocketType::UNDEFINED: break;
- }
- }
+void Node::hash(MD5Hash &md5)
+{
+ md5.append(type->name.string());
+
+ foreach (const SocketType &socket, type->inputs) {
+ md5.append(socket.name.string());
+
+ switch (socket.type) {
+ case SocketType::BOOLEAN:
+ value_hash<bool>(this, socket, md5);
+ break;
+ case SocketType::FLOAT:
+ value_hash<float>(this, socket, md5);
+ break;
+ case SocketType::INT:
+ value_hash<int>(this, socket, md5);
+ break;
+ case SocketType::UINT:
+ value_hash<uint>(this, socket, md5);
+ break;
+ case SocketType::COLOR:
+ float3_hash(this, socket, md5);
+ break;
+ case SocketType::VECTOR:
+ float3_hash(this, socket, md5);
+ break;
+ case SocketType::POINT:
+ float3_hash(this, socket, md5);
+ break;
+ case SocketType::NORMAL:
+ float3_hash(this, socket, md5);
+ break;
+ case SocketType::POINT2:
+ value_hash<float2>(this, socket, md5);
+ break;
+ case SocketType::CLOSURE:
+ break;
+ case SocketType::STRING:
+ value_hash<ustring>(this, socket, md5);
+ break;
+ case SocketType::ENUM:
+ value_hash<int>(this, socket, md5);
+ break;
+ case SocketType::TRANSFORM:
+ value_hash<Transform>(this, socket, md5);
+ break;
+ case SocketType::NODE:
+ value_hash<void *>(this, socket, md5);
+ break;
+
+ case SocketType::BOOLEAN_ARRAY:
+ array_hash<bool>(this, socket, md5);
+ break;
+ case SocketType::FLOAT_ARRAY:
+ array_hash<float>(this, socket, md5);
+ break;
+ case SocketType::INT_ARRAY:
+ array_hash<int>(this, socket, md5);
+ break;
+ case SocketType::COLOR_ARRAY:
+ float3_array_hash(this, socket, md5);
+ break;
+ case SocketType::VECTOR_ARRAY:
+ float3_array_hash(this, socket, md5);
+ break;
+ case SocketType::POINT_ARRAY:
+ float3_array_hash(this, socket, md5);
+ break;
+ case SocketType::NORMAL_ARRAY:
+ float3_array_hash(this, socket, md5);
+ break;
+ case SocketType::POINT2_ARRAY:
+ array_hash<float2>(this, socket, md5);
+ break;
+ case SocketType::STRING_ARRAY:
+ array_hash<ustring>(this, socket, md5);
+ break;
+ case SocketType::TRANSFORM_ARRAY:
+ array_hash<Transform>(this, socket, md5);
+ break;
+ case SocketType::NODE_ARRAY:
+ array_hash<void *>(this, socket, md5);
+ break;
+
+ case SocketType::UNDEFINED:
+ break;
+ }
+ }
}
namespace {
-template<typename T>
-size_t array_size_in_bytes(const Node *node, const SocketType& socket)
+template<typename T> size_t array_size_in_bytes(const Node *node, const SocketType &socket)
{
- const array<T>& a = *(const array<T>*)(((char*)node) + socket.struct_offset);
- return a.size() * sizeof(T);
+ const array<T> &a = *(const array<T> *)(((char *)node) + socket.struct_offset);
+ return a.size() * sizeof(T);
}
} // namespace
size_t Node::get_total_size_in_bytes() const
{
- size_t total_size = 0;
- foreach(const SocketType& socket, type->inputs) {
- switch(socket.type) {
- case SocketType::BOOLEAN:
- case SocketType::FLOAT:
- case SocketType::INT:
- case SocketType::UINT:
- case SocketType::COLOR:
- case SocketType::VECTOR:
- case SocketType::POINT:
- case SocketType::NORMAL:
- case SocketType::POINT2:
- case SocketType::CLOSURE:
- case SocketType::STRING:
- case SocketType::ENUM:
- case SocketType::TRANSFORM:
- case SocketType::NODE:
- total_size += socket.size();
- break;
-
- case SocketType::BOOLEAN_ARRAY:
- total_size += array_size_in_bytes<bool>(this, socket);
- break;
- case SocketType::FLOAT_ARRAY:
- total_size += array_size_in_bytes<float>(this, socket);
- break;
- case SocketType::INT_ARRAY:
- total_size += array_size_in_bytes<int>(this, socket);
- break;
- case SocketType::COLOR_ARRAY:
- total_size += array_size_in_bytes<float3>(this, socket);
- break;
- case SocketType::VECTOR_ARRAY:
- total_size += array_size_in_bytes<float3>(this, socket);
- break;
- case SocketType::POINT_ARRAY:
- total_size += array_size_in_bytes<float3>(this, socket);
- break;
- case SocketType::NORMAL_ARRAY:
- total_size += array_size_in_bytes<float3>(this, socket);
- break;
- case SocketType::POINT2_ARRAY:
- total_size += array_size_in_bytes<float2>(this, socket);
- break;
- case SocketType::STRING_ARRAY:
- total_size += array_size_in_bytes<ustring>(this, socket);
- break;
- case SocketType::TRANSFORM_ARRAY:
- total_size += array_size_in_bytes<Transform>(this, socket);
- break;
- case SocketType::NODE_ARRAY:
- total_size += array_size_in_bytes<void*>(this, socket);
- break;
-
- case SocketType::UNDEFINED: break;
- }
- }
- return total_size;
+ size_t total_size = 0;
+ foreach (const SocketType &socket, type->inputs) {
+ switch (socket.type) {
+ case SocketType::BOOLEAN:
+ case SocketType::FLOAT:
+ case SocketType::INT:
+ case SocketType::UINT:
+ case SocketType::COLOR:
+ case SocketType::VECTOR:
+ case SocketType::POINT:
+ case SocketType::NORMAL:
+ case SocketType::POINT2:
+ case SocketType::CLOSURE:
+ case SocketType::STRING:
+ case SocketType::ENUM:
+ case SocketType::TRANSFORM:
+ case SocketType::NODE:
+ total_size += socket.size();
+ break;
+
+ case SocketType::BOOLEAN_ARRAY:
+ total_size += array_size_in_bytes<bool>(this, socket);
+ break;
+ case SocketType::FLOAT_ARRAY:
+ total_size += array_size_in_bytes<float>(this, socket);
+ break;
+ case SocketType::INT_ARRAY:
+ total_size += array_size_in_bytes<int>(this, socket);
+ break;
+ case SocketType::COLOR_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::VECTOR_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::POINT_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::NORMAL_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::POINT2_ARRAY:
+ total_size += array_size_in_bytes<float2>(this, socket);
+ break;
+ case SocketType::STRING_ARRAY:
+ total_size += array_size_in_bytes<ustring>(this, socket);
+ break;
+ case SocketType::TRANSFORM_ARRAY:
+ total_size += array_size_in_bytes<Transform>(this, socket);
+ break;
+ case SocketType::NODE_ARRAY:
+ total_size += array_size_in_bytes<void *>(this, socket);
+ break;
+
+ case SocketType::UNDEFINED:
+ break;
+ }
+ }
+ return total_size;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h
index d50a3786139..226c49b387a 100644
--- a/intern/cycles/graph/node.h
+++ b/intern/cycles/graph/node.h
@@ -31,72 +31,71 @@ struct Transform;
/* Node */
-struct Node
-{
- explicit Node(const NodeType *type, ustring name = ustring());
- virtual ~Node();
-
- /* set values */
- void set(const SocketType& input, bool value);
- void set(const SocketType& input, int value);
- void set(const SocketType& input, uint value);
- void set(const SocketType& input, float value);
- void set(const SocketType& input, float2 value);
- void set(const SocketType& input, float3 value);
- void set(const SocketType& input, const char *value);
- void set(const SocketType& input, ustring value);
- void set(const SocketType& input, const Transform& value);
- void set(const SocketType& input, Node *value);
-
- /* set array values. the memory from the input array will taken over
- * by the node and the input array will be empty after return */
- void set(const SocketType& input, array<bool>& value);
- void set(const SocketType& input, array<int>& value);
- void set(const SocketType& input, array<float>& value);
- void set(const SocketType& input, array<float2>& value);
- void set(const SocketType& input, array<float3>& value);
- void set(const SocketType& input, array<ustring>& value);
- void set(const SocketType& input, array<Transform>& value);
- void set(const SocketType& input, array<Node*>& value);
-
- /* get values */
- bool get_bool(const SocketType& input) const;
- int get_int(const SocketType& input) const;
- uint get_uint(const SocketType& input) const;
- float get_float(const SocketType& input) const;
- float2 get_float2(const SocketType& input) const;
- float3 get_float3(const SocketType& input) const;
- ustring get_string(const SocketType& input) const;
- Transform get_transform(const SocketType& input) const;
- Node *get_node(const SocketType& input) const;
-
- /* get array values */
- const array<bool>& get_bool_array(const SocketType& input) const;
- const array<int>& get_int_array(const SocketType& input) const;
- const array<float>& get_float_array(const SocketType& input) const;
- const array<float2>& get_float2_array(const SocketType& input) const;
- const array<float3>& get_float3_array(const SocketType& input) const;
- const array<ustring>& get_string_array(const SocketType& input) const;
- const array<Transform>& get_transform_array(const SocketType& input) const;
- const array<Node*>& get_node_array(const SocketType& input) const;
-
- /* generic values operations */
- bool has_default_value(const SocketType& input) const;
- void set_default_value(const SocketType& input);
- bool equals_value(const Node& other, const SocketType& input) const;
- void copy_value(const SocketType& input, const Node& other, const SocketType& other_input);
-
- /* equals */
- bool equals(const Node& other) const;
-
- /* compute hash of node and its socket values */
- void hash(MD5Hash& md5);
-
- /* Get total size of this node. */
- size_t get_total_size_in_bytes() const;
-
- ustring name;
- const NodeType *type;
+struct Node {
+ explicit Node(const NodeType *type, ustring name = ustring());
+ virtual ~Node();
+
+ /* set values */
+ void set(const SocketType &input, bool value);
+ void set(const SocketType &input, int value);
+ void set(const SocketType &input, uint value);
+ void set(const SocketType &input, float value);
+ void set(const SocketType &input, float2 value);
+ void set(const SocketType &input, float3 value);
+ void set(const SocketType &input, const char *value);
+ void set(const SocketType &input, ustring value);
+ void set(const SocketType &input, const Transform &value);
+ void set(const SocketType &input, Node *value);
+
+ /* set array values. the memory from the input array will taken over
+ * by the node and the input array will be empty after return */
+ void set(const SocketType &input, array<bool> &value);
+ void set(const SocketType &input, array<int> &value);
+ void set(const SocketType &input, array<float> &value);
+ void set(const SocketType &input, array<float2> &value);
+ void set(const SocketType &input, array<float3> &value);
+ void set(const SocketType &input, array<ustring> &value);
+ void set(const SocketType &input, array<Transform> &value);
+ void set(const SocketType &input, array<Node *> &value);
+
+ /* get values */
+ bool get_bool(const SocketType &input) const;
+ int get_int(const SocketType &input) const;
+ uint get_uint(const SocketType &input) const;
+ float get_float(const SocketType &input) const;
+ float2 get_float2(const SocketType &input) const;
+ float3 get_float3(const SocketType &input) const;
+ ustring get_string(const SocketType &input) const;
+ Transform get_transform(const SocketType &input) const;
+ Node *get_node(const SocketType &input) const;
+
+ /* get array values */
+ const array<bool> &get_bool_array(const SocketType &input) const;
+ const array<int> &get_int_array(const SocketType &input) const;
+ const array<float> &get_float_array(const SocketType &input) const;
+ const array<float2> &get_float2_array(const SocketType &input) const;
+ const array<float3> &get_float3_array(const SocketType &input) const;
+ const array<ustring> &get_string_array(const SocketType &input) const;
+ const array<Transform> &get_transform_array(const SocketType &input) const;
+ const array<Node *> &get_node_array(const SocketType &input) const;
+
+ /* generic values operations */
+ bool has_default_value(const SocketType &input) const;
+ void set_default_value(const SocketType &input);
+ bool equals_value(const Node &other, const SocketType &input) const;
+ void copy_value(const SocketType &input, const Node &other, const SocketType &other_input);
+
+ /* equals */
+ bool equals(const Node &other) const;
+
+ /* compute hash of node and its socket values */
+ void hash(MD5Hash &md5);
+
+ /* Get total size of this node. */
+ size_t get_total_size_in_bytes() const;
+
+ ustring name;
+ const NodeType *type;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node_enum.h b/intern/cycles/graph/node_enum.h
index 705aec9a918..d3ed0928a4f 100644
--- a/intern/cycles/graph/node_enum.h
+++ b/intern/cycles/graph/node_enum.h
@@ -26,25 +26,50 @@ CCL_NAMESPACE_BEGIN
* Utility class for enum values. */
struct NodeEnum {
- bool empty() const { return left.empty(); }
- void insert(const char *x, int y) {
- left[ustring(x)] = y;
- right[y] = ustring(x);
- }
+ bool empty() const
+ {
+ return left.empty();
+ }
+ void insert(const char *x, int y)
+ {
+ left[ustring(x)] = y;
+ right[y] = ustring(x);
+ }
- bool exists(ustring x) const { return left.find(x) != left.end(); }
- bool exists(int y) const { return right.find(y) != right.end(); }
+ bool exists(ustring x) const
+ {
+ return left.find(x) != left.end();
+ }
+ bool exists(int y) const
+ {
+ return right.find(y) != right.end();
+ }
- int operator[](const char *x) const { return left.find(ustring(x))->second; }
- int operator[](ustring x) const { return left.find(x)->second; }
- ustring operator[](int y) const { return right.find(y)->second; }
+ int operator[](const char *x) const
+ {
+ return left.find(ustring(x))->second;
+ }
+ int operator[](ustring x) const
+ {
+ return left.find(x)->second;
+ }
+ ustring operator[](int y) const
+ {
+ return right.find(y)->second;
+ }
- unordered_map<ustring, int, ustringHash>::const_iterator begin() const { return left.begin(); }
- unordered_map<ustring, int, ustringHash>::const_iterator end() const { return left.end(); }
+ unordered_map<ustring, int, ustringHash>::const_iterator begin() const
+ {
+ return left.begin();
+ }
+ unordered_map<ustring, int, ustringHash>::const_iterator end() const
+ {
+ return left.end();
+ }
-private:
- unordered_map<ustring, int, ustringHash> left;
- unordered_map<int, ustring> right;
+ private:
+ unordered_map<ustring, int, ustringHash> left;
+ unordered_map<int, ustring> right;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node_type.cpp b/intern/cycles/graph/node_type.cpp
index e045777e969..f46d4e48026 100644
--- a/intern/cycles/graph/node_type.cpp
+++ b/intern/cycles/graph/node_type.cpp
@@ -24,107 +24,118 @@ CCL_NAMESPACE_BEGIN
size_t SocketType::size() const
{
- return size(type);
+ return size(type);
}
bool SocketType::is_array() const
{
- return (type >= BOOLEAN_ARRAY);
+ return (type >= BOOLEAN_ARRAY);
}
size_t SocketType::size(Type type)
{
- switch(type)
- {
- case UNDEFINED: return 0;
-
- case BOOLEAN: return sizeof(bool);
- case FLOAT: return sizeof(float);
- case INT: return sizeof(int);
- case UINT: return sizeof(uint);
- case COLOR: return sizeof(float3);
- case VECTOR: return sizeof(float3);
- case POINT: return sizeof(float3);
- case NORMAL: return sizeof(float3);
- case POINT2: return sizeof(float2);
- case CLOSURE: return 0;
- case STRING: return sizeof(ustring);
- case ENUM: return sizeof(int);
- case TRANSFORM: return sizeof(Transform);
- case NODE: return sizeof(void*);
-
- case BOOLEAN_ARRAY: return sizeof(array<bool>);
- case FLOAT_ARRAY: return sizeof(array<float>);
- case INT_ARRAY: return sizeof(array<int>);
- case COLOR_ARRAY: return sizeof(array<float3>);
- case VECTOR_ARRAY: return sizeof(array<float3>);
- case POINT_ARRAY: return sizeof(array<float3>);
- case NORMAL_ARRAY: return sizeof(array<float3>);
- case POINT2_ARRAY: return sizeof(array<float2>);
- case STRING_ARRAY: return sizeof(array<ustring>);
- case TRANSFORM_ARRAY: return sizeof(array<Transform>);
- case NODE_ARRAY: return sizeof(array<void*>);
- }
-
- assert(0);
- return 0;
+ switch (type) {
+ case UNDEFINED:
+ return 0;
+
+ case BOOLEAN:
+ return sizeof(bool);
+ case FLOAT:
+ return sizeof(float);
+ case INT:
+ return sizeof(int);
+ case UINT:
+ return sizeof(uint);
+ case COLOR:
+ return sizeof(float3);
+ case VECTOR:
+ return sizeof(float3);
+ case POINT:
+ return sizeof(float3);
+ case NORMAL:
+ return sizeof(float3);
+ case POINT2:
+ return sizeof(float2);
+ case CLOSURE:
+ return 0;
+ case STRING:
+ return sizeof(ustring);
+ case ENUM:
+ return sizeof(int);
+ case TRANSFORM:
+ return sizeof(Transform);
+ case NODE:
+ return sizeof(void *);
+
+ case BOOLEAN_ARRAY:
+ return sizeof(array<bool>);
+ case FLOAT_ARRAY:
+ return sizeof(array<float>);
+ case INT_ARRAY:
+ return sizeof(array<int>);
+ case COLOR_ARRAY:
+ return sizeof(array<float3>);
+ case VECTOR_ARRAY:
+ return sizeof(array<float3>);
+ case POINT_ARRAY:
+ return sizeof(array<float3>);
+ case NORMAL_ARRAY:
+ return sizeof(array<float3>);
+ case POINT2_ARRAY:
+ return sizeof(array<float2>);
+ case STRING_ARRAY:
+ return sizeof(array<ustring>);
+ case TRANSFORM_ARRAY:
+ return sizeof(array<Transform>);
+ case NODE_ARRAY:
+ return sizeof(array<void *>);
+ }
+
+ assert(0);
+ return 0;
}
size_t SocketType::max_size()
{
- return sizeof(Transform);
+ return sizeof(Transform);
}
void *SocketType::zero_default_value()
{
- static Transform zero_transform = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
- return &zero_transform;
+ static Transform zero_transform = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
+ return &zero_transform;
}
ustring SocketType::type_name(Type type)
{
- static ustring names[] = {
- ustring("undefined"),
-
- ustring("boolean"),
- ustring("float"),
- ustring("int"),
- ustring("uint"),
- ustring("color"),
- ustring("vector"),
- ustring("point"),
- ustring("normal"),
- ustring("point2"),
- ustring("closure"),
- ustring("string"),
- ustring("enum"),
- ustring("transform"),
- ustring("node"),
-
- ustring("array_boolean"),
- ustring("array_float"),
- ustring("array_int"),
- ustring("array_color"),
- ustring("array_vector"),
- ustring("array_point"),
- ustring("array_normal"),
- ustring("array_point2"),
- ustring("array_string"),
- ustring("array_transform"),
- ustring("array_node")};
-
- return names[(int)type];
+ static ustring names[] = {ustring("undefined"),
+
+ ustring("boolean"), ustring("float"),
+ ustring("int"), ustring("uint"),
+ ustring("color"), ustring("vector"),
+ ustring("point"), ustring("normal"),
+ ustring("point2"), ustring("closure"),
+ ustring("string"), ustring("enum"),
+ ustring("transform"), ustring("node"),
+
+ ustring("array_boolean"), ustring("array_float"),
+ ustring("array_int"), ustring("array_color"),
+ ustring("array_vector"), ustring("array_point"),
+ ustring("array_normal"), ustring("array_point2"),
+ ustring("array_string"), ustring("array_transform"),
+ ustring("array_node")};
+
+ return names[(int)type];
}
bool SocketType::is_float3(Type type)
{
- return (type == COLOR || type == VECTOR || type == POINT || type == NORMAL);
+ return (type == COLOR || type == VECTOR || type == POINT || type == NORMAL);
}
/* Node Type */
-NodeType::NodeType(Type type_)
-: type(type_)
+NodeType::NodeType(Type type_) : type(type_)
{
}
@@ -132,88 +143,94 @@ NodeType::~NodeType()
{
}
-void NodeType::register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset,
- const void *default_value, const NodeEnum *enum_values,
- const NodeType **node_type, int flags, int extra_flags)
+void NodeType::register_input(ustring name,
+ ustring ui_name,
+ SocketType::Type type,
+ int struct_offset,
+ const void *default_value,
+ const NodeEnum *enum_values,
+ const NodeType **node_type,
+ int flags,
+ int extra_flags)
{
- SocketType socket;
- socket.name = name;
- socket.ui_name = ui_name;
- socket.type = type;
- socket.struct_offset = struct_offset;
- socket.default_value = default_value;
- socket.enum_values = enum_values;
- socket.node_type = node_type;
- socket.flags = flags | extra_flags;
- inputs.push_back(socket);
+ SocketType socket;
+ socket.name = name;
+ socket.ui_name = ui_name;
+ socket.type = type;
+ socket.struct_offset = struct_offset;
+ socket.default_value = default_value;
+ socket.enum_values = enum_values;
+ socket.node_type = node_type;
+ socket.flags = flags | extra_flags;
+ inputs.push_back(socket);
}
void NodeType::register_output(ustring name, ustring ui_name, SocketType::Type type)
{
- SocketType socket;
- socket.name = name;
- socket.ui_name = ui_name;
- socket.type = type;
- socket.struct_offset = 0;
- socket.default_value = NULL;
- socket.enum_values = NULL;
- socket.node_type = NULL;
- socket.flags = SocketType::LINKABLE;
- outputs.push_back(socket);
+ SocketType socket;
+ socket.name = name;
+ socket.ui_name = ui_name;
+ socket.type = type;
+ socket.struct_offset = 0;
+ socket.default_value = NULL;
+ socket.enum_values = NULL;
+ socket.node_type = NULL;
+ socket.flags = SocketType::LINKABLE;
+ outputs.push_back(socket);
}
const SocketType *NodeType::find_input(ustring name) const
{
- foreach(const SocketType& socket, inputs) {
- if(socket.name == name) {
- return &socket;
- }
- }
+ foreach (const SocketType &socket, inputs) {
+ if (socket.name == name) {
+ return &socket;
+ }
+ }
- return NULL;
+ return NULL;
}
const SocketType *NodeType::find_output(ustring name) const
{
- foreach(const SocketType& socket, outputs) {
- if(socket.name == name) {
- return &socket;
- }
- }
+ foreach (const SocketType &socket, outputs) {
+ if (socket.name == name) {
+ return &socket;
+ }
+ }
- return NULL;
+ return NULL;
}
/* Node Type Registry */
-unordered_map<ustring, NodeType, ustringHash>& NodeType::types()
+unordered_map<ustring, NodeType, ustringHash> &NodeType::types()
{
- static unordered_map<ustring, NodeType, ustringHash> _types;
- return _types;
+ static unordered_map<ustring, NodeType, ustringHash> _types;
+ return _types;
}
NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_)
{
- ustring name(name_);
+ ustring name(name_);
- if(types().find(name) != types().end()) {
- fprintf(stderr, "Node type %s registered twice!\n", name_);
- assert(0);
- return NULL;
- }
+ if (types().find(name) != types().end()) {
+ fprintf(stderr, "Node type %s registered twice!\n", name_);
+ assert(0);
+ return NULL;
+ }
- types()[name] = NodeType(type_);
+ types()[name] = NodeType(type_);
- NodeType *type = &types()[name];
- type->name = name;
- type->create = create_;
- return type;
+ NodeType *type = &types()[name];
+ type->name = name;
+ type->create = create_;
+ return type;
}
const NodeType *NodeType::find(ustring name)
{
- unordered_map<ustring, NodeType, ustringHash>::iterator it = types().find(name);
- return (it == types().end()) ? NULL : &it->second;
+ unordered_map<ustring, NodeType, ustringHash>::iterator it = types().find(name);
+ return (it == types().end()) ? NULL : &it->second;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h
index 7d6abae2314..e9496a42658 100644
--- a/intern/cycles/graph/node_type.h
+++ b/intern/cycles/graph/node_type.h
@@ -30,236 +30,349 @@ struct NodeType;
/* Socket Type */
-struct SocketType
-{
- enum Type
- {
- UNDEFINED,
+struct SocketType {
+ enum Type {
+ UNDEFINED,
- BOOLEAN,
- FLOAT,
- INT,
- UINT,
- COLOR,
- VECTOR,
- POINT,
- NORMAL,
- POINT2,
- CLOSURE,
- STRING,
- ENUM,
- TRANSFORM,
- NODE,
+ BOOLEAN,
+ FLOAT,
+ INT,
+ UINT,
+ COLOR,
+ VECTOR,
+ POINT,
+ NORMAL,
+ POINT2,
+ CLOSURE,
+ STRING,
+ ENUM,
+ TRANSFORM,
+ NODE,
- BOOLEAN_ARRAY,
- FLOAT_ARRAY,
- INT_ARRAY,
- COLOR_ARRAY,
- VECTOR_ARRAY,
- POINT_ARRAY,
- NORMAL_ARRAY,
- POINT2_ARRAY,
- STRING_ARRAY,
- TRANSFORM_ARRAY,
- NODE_ARRAY,
- };
+ BOOLEAN_ARRAY,
+ FLOAT_ARRAY,
+ INT_ARRAY,
+ COLOR_ARRAY,
+ VECTOR_ARRAY,
+ POINT_ARRAY,
+ NORMAL_ARRAY,
+ POINT2_ARRAY,
+ STRING_ARRAY,
+ TRANSFORM_ARRAY,
+ NODE_ARRAY,
+ };
- enum Flags {
- LINKABLE = (1 << 0),
- ANIMATABLE = (1 << 1),
+ enum Flags {
+ LINKABLE = (1 << 0),
+ ANIMATABLE = (1 << 1),
- SVM_INTERNAL = (1 << 2),
- OSL_INTERNAL = (1 << 3),
- INTERNAL = (1 << 2) | (1 << 3),
+ SVM_INTERNAL = (1 << 2),
+ OSL_INTERNAL = (1 << 3),
+ INTERNAL = (1 << 2) | (1 << 3),
- LINK_TEXTURE_GENERATED = (1 << 4),
- LINK_TEXTURE_NORMAL = (1 << 5),
- LINK_TEXTURE_UV = (1 << 6),
- LINK_INCOMING = (1 << 7),
- LINK_NORMAL = (1 << 8),
- LINK_POSITION = (1 << 9),
- LINK_TANGENT = (1 << 10),
- DEFAULT_LINK_MASK = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10)
- };
+ LINK_TEXTURE_GENERATED = (1 << 4),
+ LINK_TEXTURE_NORMAL = (1 << 5),
+ LINK_TEXTURE_UV = (1 << 6),
+ LINK_INCOMING = (1 << 7),
+ LINK_NORMAL = (1 << 8),
+ LINK_POSITION = (1 << 9),
+ LINK_TANGENT = (1 << 10),
+ DEFAULT_LINK_MASK = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10)
+ };
- ustring name;
- Type type;
- int struct_offset;
- const void *default_value;
- const NodeEnum *enum_values;
- const NodeType **node_type;
- int flags;
- ustring ui_name;
+ ustring name;
+ Type type;
+ int struct_offset;
+ const void *default_value;
+ const NodeEnum *enum_values;
+ const NodeType **node_type;
+ int flags;
+ ustring ui_name;
- size_t size() const;
- bool is_array() const;
- static size_t size(Type type);
- static size_t max_size();
- static ustring type_name(Type type);
- static void *zero_default_value();
- static bool is_float3(Type type);
+ size_t size() const;
+ bool is_array() const;
+ static size_t size(Type type);
+ static size_t max_size();
+ static ustring type_name(Type type);
+ static void *zero_default_value();
+ static bool is_float3(Type type);
};
/* Node Type */
-struct NodeType
-{
- enum Type {
- NONE,
- SHADER
- };
+struct NodeType {
+ enum Type { NONE, SHADER };
- explicit NodeType(Type type = NONE);
- ~NodeType();
+ explicit NodeType(Type type = NONE);
+ ~NodeType();
- void register_input(ustring name, ustring ui_name, SocketType::Type type,
- int struct_offset, const void *default_value,
- const NodeEnum *enum_values = NULL,
- const NodeType **node_type = NULL,
- int flags = 0, int extra_flags = 0);
- void register_output(ustring name, ustring ui_name, SocketType::Type type);
+ void register_input(ustring name,
+ ustring ui_name,
+ SocketType::Type type,
+ int struct_offset,
+ const void *default_value,
+ const NodeEnum *enum_values = NULL,
+ const NodeType **node_type = NULL,
+ int flags = 0,
+ int extra_flags = 0);
+ void register_output(ustring name, ustring ui_name, SocketType::Type type);
- const SocketType *find_input(ustring name) const;
- const SocketType *find_output(ustring name) const;
+ const SocketType *find_input(ustring name) const;
+ const SocketType *find_output(ustring name) const;
- typedef Node *(*CreateFunc)(const NodeType *type);
+ typedef Node *(*CreateFunc)(const NodeType *type);
- ustring name;
- Type type;
- vector<SocketType, std::allocator<SocketType> > inputs;
- vector<SocketType, std::allocator<SocketType> > outputs;
- CreateFunc create;
+ ustring name;
+ Type type;
+ vector<SocketType, std::allocator<SocketType>> inputs;
+ vector<SocketType, std::allocator<SocketType>> outputs;
+ CreateFunc create;
- static NodeType *add(const char *name, CreateFunc create, Type type = NONE);
- static const NodeType *find(ustring name);
- static unordered_map<ustring, NodeType, ustringHash>& types();
+ static NodeType *add(const char *name, CreateFunc create, Type type = NONE);
+ static const NodeType *find(ustring name);
+ static unordered_map<ustring, NodeType, ustringHash> &types();
};
/* Node Definition Macros */
-#define NODE_DECLARE \
-template<typename T> \
-static const NodeType *register_type(); \
-static Node *create(const NodeType *type); \
-static const NodeType *node_type;
+#define NODE_DECLARE \
+ template<typename T> static const NodeType *register_type(); \
+ static Node *create(const NodeType *type); \
+ static const NodeType *node_type;
-#define NODE_DEFINE(structname) \
-const NodeType *structname::node_type = structname::register_type<structname>(); \
-Node *structname::create(const NodeType*) { return new structname(); } \
-template<typename T> \
-const NodeType *structname::register_type()
+#define NODE_DEFINE(structname) \
+ const NodeType *structname::node_type = structname::register_type<structname>(); \
+ Node *structname::create(const NodeType *) \
+ { \
+ return new structname(); \
+ } \
+ template<typename T> const NodeType *structname::register_type()
/* Sock Definition Macros */
#define SOCKET_OFFSETOF(T, name) (((char *)&(((T *)1)->name)) - (char *)1)
#define SOCKET_SIZEOF(T, name) (sizeof(((T *)1)->name))
#define SOCKET_DEFINE(name, ui_name, default_value, datatype, TYPE, flags, ...) \
- { \
- static datatype defval = default_value; \
- CHECK_TYPE(((T *)1)->name, datatype); \
- type->register_input(ustring(#name), ustring(ui_name), TYPE, SOCKET_OFFSETOF(T, name), &defval, NULL, NULL, flags, ##__VA_ARGS__); \
- }
+ { \
+ static datatype defval = default_value; \
+ CHECK_TYPE(((T *)1)->name, datatype); \
+ type->register_input(ustring(#name), \
+ ustring(ui_name), \
+ TYPE, \
+ SOCKET_OFFSETOF(T, name), \
+ &defval, \
+ NULL, \
+ NULL, \
+ flags, \
+ ##__VA_ARGS__); \
+ }
#define SOCKET_BOOLEAN(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, bool, SocketType::BOOLEAN, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, bool, SocketType::BOOLEAN, 0, ##__VA_ARGS__)
#define SOCKET_INT(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, int, SocketType::INT, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, int, SocketType::INT, 0, ##__VA_ARGS__)
#define SOCKET_UINT(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, uint, SocketType::UINT, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, uint, SocketType::UINT, 0, ##__VA_ARGS__)
#define SOCKET_FLOAT(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float, SocketType::FLOAT, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, float, SocketType::FLOAT, 0, ##__VA_ARGS__)
#define SOCKET_COLOR(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::COLOR, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::COLOR, 0, ##__VA_ARGS__)
#define SOCKET_VECTOR(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::VECTOR, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::VECTOR, 0, ##__VA_ARGS__)
#define SOCKET_POINT(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::POINT, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::POINT, 0, ##__VA_ARGS__)
#define SOCKET_NORMAL(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::NORMAL, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::NORMAL, 0, ##__VA_ARGS__)
#define SOCKET_POINT2(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float2, SocketType::POINT2, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, float2, SocketType::POINT2, 0, ##__VA_ARGS__)
#define SOCKET_STRING(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, ustring, SocketType::STRING, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, ustring, SocketType::STRING, 0, ##__VA_ARGS__)
#define SOCKET_TRANSFORM(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, Transform, SocketType::TRANSFORM, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, Transform, SocketType::TRANSFORM, 0, ##__VA_ARGS__)
#define SOCKET_ENUM(name, ui_name, values, default_value, ...) \
- { \
- static int defval = default_value; \
- assert(SOCKET_SIZEOF(T, name) == sizeof(int)); \
- type->register_input(ustring(#name), ustring(ui_name), SocketType::ENUM, SOCKET_OFFSETOF(T, name), &defval, &values, NULL, ##__VA_ARGS__); \
- }
+ { \
+ static int defval = default_value; \
+ assert(SOCKET_SIZEOF(T, name) == sizeof(int)); \
+ type->register_input(ustring(#name), \
+ ustring(ui_name), \
+ SocketType::ENUM, \
+ SOCKET_OFFSETOF(T, name), \
+ &defval, \
+ &values, \
+ NULL, \
+ ##__VA_ARGS__); \
+ }
#define SOCKET_NODE(name, ui_name, node_type, ...) \
- { \
- static Node *defval = NULL; \
- assert(SOCKET_SIZEOF(T, name) == sizeof(Node*)); \
- type->register_input(ustring(#name), ustring(ui_name), SocketType::NODE, SOCKET_OFFSETOF(T, name), &defval, NULL, node_type, ##__VA_ARGS__); \
- }
+ { \
+ static Node *defval = NULL; \
+ assert(SOCKET_SIZEOF(T, name) == sizeof(Node *)); \
+ type->register_input(ustring(#name), \
+ ustring(ui_name), \
+ SocketType::NODE, \
+ SOCKET_OFFSETOF(T, name), \
+ &defval, \
+ NULL, \
+ node_type, \
+ ##__VA_ARGS__); \
+ }
#define SOCKET_BOOLEAN_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<bool>, SocketType::BOOLEAN_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<bool>, SocketType::BOOLEAN_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_INT_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<int>, SocketType::INT_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, ui_name, default_value, array<int>, SocketType::INT_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<float>, SocketType::FLOAT_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<float>, SocketType::FLOAT_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_COLOR_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<float3>, SocketType::COLOR_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<float3>, SocketType::COLOR_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_VECTOR_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<float3>, SocketType::VECTOR_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<float3>, SocketType::VECTOR_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_POINT_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<float3>, SocketType::POINT_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<float3>, SocketType::POINT_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_NORMAL_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<float3>, SocketType::NORMAL_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<float3>, SocketType::NORMAL_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_POINT2_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<float2>, SocketType::POINT2_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<float2>, SocketType::POINT2_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_STRING_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<ustring>, SocketType::STRING_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, array<ustring>, SocketType::STRING_ARRAY, 0, ##__VA_ARGS__)
#define SOCKET_TRANSFORM_ARRAY(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, array<Transform>, SocketType::TRANSFORM_ARRAY, 0, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ array<Transform>, \
+ SocketType::TRANSFORM_ARRAY, \
+ 0, \
+ ##__VA_ARGS__)
#define SOCKET_NODE_ARRAY(name, ui_name, node_type, ...) \
- { \
- static Node *defval = NULL; \
- assert(SOCKET_SIZEOF(T, name) == sizeof(Node*)); \
- type->register_input(ustring(#name), ustring(ui_name), SocketType::NODE_ARRAY, SOCKET_OFFSETOF(T, name), &defval, NULL, node_type, ##__VA_ARGS__); \
- }
+ { \
+ static Node *defval = NULL; \
+ assert(SOCKET_SIZEOF(T, name) == sizeof(Node *)); \
+ type->register_input(ustring(#name), \
+ ustring(ui_name), \
+ SocketType::NODE_ARRAY, \
+ SOCKET_OFFSETOF(T, name), \
+ &defval, \
+ NULL, \
+ node_type, \
+ ##__VA_ARGS__); \
+ }
#define SOCKET_IN_BOOLEAN(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, bool, SocketType::BOOLEAN, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ bool, \
+ SocketType::BOOLEAN, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_IN_INT(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, int, SocketType::INT, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE( \
+ name, ui_name, default_value, int, SocketType::INT, SocketType::LINKABLE, ##__VA_ARGS__)
#define SOCKET_IN_FLOAT(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float, SocketType::FLOAT, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ float, \
+ SocketType::FLOAT, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_IN_COLOR(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::COLOR, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ float3, \
+ SocketType::COLOR, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_IN_VECTOR(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::VECTOR, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ float3, \
+ SocketType::VECTOR, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_IN_POINT(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::POINT, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ float3, \
+ SocketType::POINT, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_IN_NORMAL(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, float3, SocketType::NORMAL, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ float3, \
+ SocketType::NORMAL, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_IN_STRING(name, ui_name, default_value, ...) \
- SOCKET_DEFINE(name, ui_name, default_value, ustring, SocketType::STRING, SocketType::LINKABLE, ##__VA_ARGS__)
+ SOCKET_DEFINE(name, \
+ ui_name, \
+ default_value, \
+ ustring, \
+ SocketType::STRING, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_IN_CLOSURE(name, ui_name, ...) \
- type->register_input(ustring(#name), ustring(ui_name), SocketType::CLOSURE, 0, NULL, NULL, NULL, SocketType::LINKABLE, ##__VA_ARGS__)
+ type->register_input(ustring(#name), \
+ ustring(ui_name), \
+ SocketType::CLOSURE, \
+ 0, \
+ NULL, \
+ NULL, \
+ NULL, \
+ SocketType::LINKABLE, \
+ ##__VA_ARGS__)
#define SOCKET_OUT_BOOLEAN(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::BOOLEAN); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::BOOLEAN); \
+ }
#define SOCKET_OUT_INT(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::INT); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::INT); \
+ }
#define SOCKET_OUT_FLOAT(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::FLOAT); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::FLOAT); \
+ }
#define SOCKET_OUT_COLOR(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::COLOR); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::COLOR); \
+ }
#define SOCKET_OUT_VECTOR(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::VECTOR); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::VECTOR); \
+ }
#define SOCKET_OUT_POINT(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::POINT); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::POINT); \
+ }
#define SOCKET_OUT_NORMAL(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::NORMAL); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::NORMAL); \
+ }
#define SOCKET_OUT_CLOSURE(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::CLOSURE); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::CLOSURE); \
+ }
#define SOCKET_OUT_STRING(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::STRING); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::STRING); \
+ }
#define SOCKET_OUT_ENUM(name, ui_name) \
- { type->register_output(ustring(#name), ustring(ui_name), SocketType::ENUM); }
+ { \
+ type->register_output(ustring(#name), ustring(ui_name), SocketType::ENUM); \
+ }
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node_xml.cpp b/intern/cycles/graph/node_xml.cpp
index f228da282e9..a96970cc904 100644
--- a/intern/cycles/graph/node_xml.cpp
+++ b/intern/cycles/graph/node_xml.cpp
@@ -24,437 +24,409 @@ CCL_NAMESPACE_BEGIN
static bool xml_read_boolean(const char *value)
{
- return string_iequals(value, "true") || (atoi(value) != 0);
+ return string_iequals(value, "true") || (atoi(value) != 0);
}
static const char *xml_write_boolean(bool value)
{
- return (value) ? "true" : "false";
+ return (value) ? "true" : "false";
}
template<int VECTOR_SIZE, typename T>
-static void xml_read_float_array(T& value, xml_attribute attr)
+static void xml_read_float_array(T &value, xml_attribute attr)
{
- vector<string> tokens;
- string_split(tokens, attr.value());
+ vector<string> tokens;
+ string_split(tokens, attr.value());
- if(tokens.size() % VECTOR_SIZE != 0) {
- return;
- }
+ if (tokens.size() % VECTOR_SIZE != 0) {
+ return;
+ }
- value.resize(tokens.size() / VECTOR_SIZE);
- for(size_t i = 0; i < value.size(); i++) {
- float *value_float = (float*)&value[i];
+ value.resize(tokens.size() / VECTOR_SIZE);
+ for (size_t i = 0; i < value.size(); i++) {
+ float *value_float = (float *)&value[i];
- for(size_t j = 0; j < VECTOR_SIZE; j++)
- value_float[j] = (float)atof(tokens[i * VECTOR_SIZE + j].c_str());
- }
+ for (size_t j = 0; j < VECTOR_SIZE; j++)
+ value_float[j] = (float)atof(tokens[i * VECTOR_SIZE + j].c_str());
+ }
}
-void xml_read_node(XMLReader& reader, Node *node, xml_node xml_node)
+void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
{
- xml_attribute name_attr = xml_node.attribute("name");
- if(name_attr) {
- node->name = ustring(name_attr.value());
- }
+ xml_attribute name_attr = xml_node.attribute("name");
+ if (name_attr) {
+ node->name = ustring(name_attr.value());
+ }
- foreach(const SocketType& socket, node->type->inputs) {
- if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
- continue;
- }
- if(socket.flags & SocketType::INTERNAL) {
- continue;
- }
+ foreach (const SocketType &socket, node->type->inputs) {
+ if (socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
+ continue;
+ }
+ if (socket.flags & SocketType::INTERNAL) {
+ continue;
+ }
- xml_attribute attr = xml_node.attribute(socket.name.c_str());
+ xml_attribute attr = xml_node.attribute(socket.name.c_str());
- if(!attr) {
- continue;
- }
+ if (!attr) {
+ continue;
+ }
- switch(socket.type)
- {
- case SocketType::BOOLEAN:
- {
- node->set(socket, xml_read_boolean(attr.value()));
- break;
- }
- case SocketType::BOOLEAN_ARRAY:
- {
- vector<string> tokens;
- string_split(tokens, attr.value());
+ switch (socket.type) {
+ case SocketType::BOOLEAN: {
+ node->set(socket, xml_read_boolean(attr.value()));
+ break;
+ }
+ case SocketType::BOOLEAN_ARRAY: {
+ vector<string> tokens;
+ string_split(tokens, attr.value());
- array<bool> value;
- value.resize(tokens.size());
- for(size_t i = 0; i < value.size(); i++)
- value[i] = xml_read_boolean(tokens[i].c_str());
- node->set(socket, value);
- break;
- }
- case SocketType::FLOAT:
- {
- node->set(socket, (float)atof(attr.value()));
- break;
- }
- case SocketType::FLOAT_ARRAY:
- {
- array<float> value;
- xml_read_float_array<1>(value, attr);
- node->set(socket, value);
- break;
- }
- case SocketType::INT:
- {
- node->set(socket, (int)atoi(attr.value()));
- break;
- }
- case SocketType::UINT:
- {
- node->set(socket, (uint)atoi(attr.value()));
- break;
- }
- case SocketType::INT_ARRAY:
- {
- vector<string> tokens;
- string_split(tokens, attr.value());
+ array<bool> value;
+ value.resize(tokens.size());
+ for (size_t i = 0; i < value.size(); i++)
+ value[i] = xml_read_boolean(tokens[i].c_str());
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::FLOAT: {
+ node->set(socket, (float)atof(attr.value()));
+ break;
+ }
+ case SocketType::FLOAT_ARRAY: {
+ array<float> value;
+ xml_read_float_array<1>(value, attr);
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::INT: {
+ node->set(socket, (int)atoi(attr.value()));
+ break;
+ }
+ case SocketType::UINT: {
+ node->set(socket, (uint)atoi(attr.value()));
+ break;
+ }
+ case SocketType::INT_ARRAY: {
+ vector<string> tokens;
+ string_split(tokens, attr.value());
- array<int> value;
- value.resize(tokens.size());
- for(size_t i = 0; i < value.size(); i++) {
- value[i] = (int)atoi(attr.value());
- }
- node->set(socket, value);
- break;
- }
- case SocketType::COLOR:
- case SocketType::VECTOR:
- case SocketType::POINT:
- case SocketType::NORMAL:
- {
- array<float3> value;
- xml_read_float_array<3>(value, attr);
- if(value.size() == 1) {
- node->set(socket, value[0]);
- }
- break;
- }
- case SocketType::COLOR_ARRAY:
- case SocketType::VECTOR_ARRAY:
- case SocketType::POINT_ARRAY:
- case SocketType::NORMAL_ARRAY:
- {
- array<float3> value;
- xml_read_float_array<3>(value, attr);
- node->set(socket, value);
- break;
- }
- case SocketType::POINT2:
- {
- array<float2> value;
- xml_read_float_array<2>(value, attr);
- if(value.size() == 1) {
- node->set(socket, value[0]);
- }
- break;
- }
- case SocketType::POINT2_ARRAY:
- {
- array<float2> value;
- xml_read_float_array<2>(value, attr);
- node->set(socket, value);
- break;
- }
- case SocketType::STRING:
- {
- node->set(socket, attr.value());
- break;
- }
- case SocketType::ENUM:
- {
- ustring value(attr.value());
- if(socket.enum_values->exists(value)) {
- node->set(socket, value);
- }
- else {
- fprintf(stderr, "Unknown value \"%s\" for attribute \"%s\".\n", value.c_str(), socket.name.c_str());
- }
- break;
- }
- case SocketType::STRING_ARRAY:
- {
- vector<string> tokens;
- string_split(tokens, attr.value());
+ array<int> value;
+ value.resize(tokens.size());
+ for (size_t i = 0; i < value.size(); i++) {
+ value[i] = (int)atoi(attr.value());
+ }
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::COLOR:
+ case SocketType::VECTOR:
+ case SocketType::POINT:
+ case SocketType::NORMAL: {
+ array<float3> value;
+ xml_read_float_array<3>(value, attr);
+ if (value.size() == 1) {
+ node->set(socket, value[0]);
+ }
+ break;
+ }
+ case SocketType::COLOR_ARRAY:
+ case SocketType::VECTOR_ARRAY:
+ case SocketType::POINT_ARRAY:
+ case SocketType::NORMAL_ARRAY: {
+ array<float3> value;
+ xml_read_float_array<3>(value, attr);
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::POINT2: {
+ array<float2> value;
+ xml_read_float_array<2>(value, attr);
+ if (value.size() == 1) {
+ node->set(socket, value[0]);
+ }
+ break;
+ }
+ case SocketType::POINT2_ARRAY: {
+ array<float2> value;
+ xml_read_float_array<2>(value, attr);
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::STRING: {
+ node->set(socket, attr.value());
+ break;
+ }
+ case SocketType::ENUM: {
+ ustring value(attr.value());
+ if (socket.enum_values->exists(value)) {
+ node->set(socket, value);
+ }
+ else {
+ fprintf(stderr,
+ "Unknown value \"%s\" for attribute \"%s\".\n",
+ value.c_str(),
+ socket.name.c_str());
+ }
+ break;
+ }
+ case SocketType::STRING_ARRAY: {
+ vector<string> tokens;
+ string_split(tokens, attr.value());
- array<ustring> value;
- value.resize(tokens.size());
- for(size_t i = 0; i < value.size(); i++) {
- value[i] = ustring(tokens[i]);
- }
- node->set(socket, value);
- break;
- }
- case SocketType::TRANSFORM:
- {
- array<Transform> value;
- xml_read_float_array<12>(value, attr);
- if(value.size() == 1) {
- node->set(socket, value[0]);
- }
- break;
- }
- case SocketType::TRANSFORM_ARRAY:
- {
- array<Transform> value;
- xml_read_float_array<12>(value, attr);
- node->set(socket, value);
- break;
- }
- case SocketType::NODE:
- {
- ustring value(attr.value());
- map<ustring, Node*>::iterator it = reader.node_map.find(value);
- if(it != reader.node_map.end())
- {
- Node *value_node = it->second;
- if(value_node->type == *(socket.node_type))
- node->set(socket, it->second);
- }
- break;
- }
- case SocketType::NODE_ARRAY:
- {
- vector<string> tokens;
- string_split(tokens, attr.value());
+ array<ustring> value;
+ value.resize(tokens.size());
+ for (size_t i = 0; i < value.size(); i++) {
+ value[i] = ustring(tokens[i]);
+ }
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::TRANSFORM: {
+ array<Transform> value;
+ xml_read_float_array<12>(value, attr);
+ if (value.size() == 1) {
+ node->set(socket, value[0]);
+ }
+ break;
+ }
+ case SocketType::TRANSFORM_ARRAY: {
+ array<Transform> value;
+ xml_read_float_array<12>(value, attr);
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::NODE: {
+ ustring value(attr.value());
+ map<ustring, Node *>::iterator it = reader.node_map.find(value);
+ if (it != reader.node_map.end()) {
+ Node *value_node = it->second;
+ if (value_node->type == *(socket.node_type))
+ node->set(socket, it->second);
+ }
+ break;
+ }
+ case SocketType::NODE_ARRAY: {
+ vector<string> tokens;
+ string_split(tokens, attr.value());
- array<Node*> value;
- value.resize(tokens.size());
- for(size_t i = 0; i < value.size(); i++)
- {
- map<ustring, Node*>::iterator it = reader.node_map.find(ustring(tokens[i]));
- if(it != reader.node_map.end())
- {
- Node *value_node = it->second;
- value[i] = (value_node->type == *(socket.node_type)) ? value_node : NULL;
- }
- else
- {
- value[i] = NULL;
- }
- }
- node->set(socket, value);
- break;
- }
- case SocketType::CLOSURE:
- case SocketType::UNDEFINED:
- break;
- }
- }
+ array<Node *> value;
+ value.resize(tokens.size());
+ for (size_t i = 0; i < value.size(); i++) {
+ map<ustring, Node *>::iterator it = reader.node_map.find(ustring(tokens[i]));
+ if (it != reader.node_map.end()) {
+ Node *value_node = it->second;
+ value[i] = (value_node->type == *(socket.node_type)) ? value_node : NULL;
+ }
+ else {
+ value[i] = NULL;
+ }
+ }
+ node->set(socket, value);
+ break;
+ }
+ case SocketType::CLOSURE:
+ case SocketType::UNDEFINED:
+ break;
+ }
+ }
- if(!node->name.empty())
- reader.node_map[node->name] = node;
+ if (!node->name.empty())
+ reader.node_map[node->name] = node;
}
xml_node xml_write_node(Node *node, xml_node xml_root)
{
- xml_node xml_node = xml_root.append_child(node->type->name.c_str());
+ xml_node xml_node = xml_root.append_child(node->type->name.c_str());
- xml_node.append_attribute("name") = node->name.c_str();
+ xml_node.append_attribute("name") = node->name.c_str();
- foreach(const SocketType& socket, node->type->inputs) {
- if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
- continue;
- }
- if(socket.flags & SocketType::INTERNAL) {
- continue;
- }
- if(node->has_default_value(socket)) {
- continue;
- }
+ foreach (const SocketType &socket, node->type->inputs) {
+ if (socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
+ continue;
+ }
+ if (socket.flags & SocketType::INTERNAL) {
+ continue;
+ }
+ if (node->has_default_value(socket)) {
+ continue;
+ }
- xml_attribute attr = xml_node.append_attribute(socket.name.c_str());
+ xml_attribute attr = xml_node.append_attribute(socket.name.c_str());
- switch(socket.type)
- {
- case SocketType::BOOLEAN:
- {
- attr = xml_write_boolean(node->get_bool(socket));
- break;
- }
- case SocketType::BOOLEAN_ARRAY:
- {
- std::stringstream ss;
- const array<bool>& value = node->get_bool_array(socket);
- for(size_t i = 0; i < value.size(); i++) {
- ss << xml_write_boolean(value[i]);
- if(i != value.size() - 1)
- ss << " ";
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::FLOAT:
- {
- attr = (double)node->get_float(socket);
- break;
- }
- case SocketType::FLOAT_ARRAY:
- {
- std::stringstream ss;
- const array<float>& value = node->get_float_array(socket);
- for(size_t i = 0; i < value.size(); i++) {
- ss << value[i];
- if(i != value.size() - 1) {
- ss << " ";
- }
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::INT:
- {
- attr = node->get_int(socket);
- break;
- }
- case SocketType::UINT:
- {
- attr = node->get_uint(socket);
- break;
- }
- case SocketType::INT_ARRAY:
- {
- std::stringstream ss;
- const array<int>& value = node->get_int_array(socket);
- for(size_t i = 0; i < value.size(); i++) {
- ss << value[i];
- if(i != value.size() - 1) {
- ss << " ";
- }
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::COLOR:
- case SocketType::VECTOR:
- case SocketType::POINT:
- case SocketType::NORMAL:
- {
- float3 value = node->get_float3(socket);
- attr = string_printf("%g %g %g", (double)value.x, (double)value.y, (double)value.z).c_str();
- break;
- }
- case SocketType::COLOR_ARRAY:
- case SocketType::VECTOR_ARRAY:
- case SocketType::POINT_ARRAY:
- case SocketType::NORMAL_ARRAY:
- {
- std::stringstream ss;
- const array<float3>& value = node->get_float3_array(socket);
- for(size_t i = 0; i < value.size(); i++) {
- ss << string_printf("%g %g %g", (double)value[i].x, (double)value[i].y, (double)value[i].z);
- if(i != value.size() - 1) {
- ss << " ";
- }
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::POINT2:
- {
- float2 value = node->get_float2(socket);
- attr = string_printf("%g %g", (double)value.x, (double)value.y).c_str();
- break;
- }
- case SocketType::POINT2_ARRAY:
- {
- std::stringstream ss;
- const array<float2>& value = node->get_float2_array(socket);
- for(size_t i = 0; i < value.size(); i++) {
- ss << string_printf("%g %g", (double)value[i].x, (double)value[i].y);
- if(i != value.size() - 1) {
- ss << " ";
- }
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::STRING:
- case SocketType::ENUM:
- {
- attr = node->get_string(socket).c_str();
- break;
- }
- case SocketType::STRING_ARRAY:
- {
- std::stringstream ss;
- const array<ustring>& value = node->get_string_array(socket);
- for(size_t i = 0; i < value.size(); i++) {
- ss << value[i];
- if(i != value.size() - 1) {
- ss << " ";
- }
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::TRANSFORM:
- {
- Transform tfm = node->get_transform(socket);
- std::stringstream ss;
- for(int i = 0; i < 3; i++) {
- ss << string_printf("%g %g %g %g ", (double)tfm[i][0], (double)tfm[i][1], (double)tfm[i][2], (double)tfm[i][3]);
- }
- ss << string_printf("%g %g %g %g", 0.0, 0.0, 0.0, 1.0);
- attr = ss.str().c_str();
- break;
- }
- case SocketType::TRANSFORM_ARRAY:
- {
- std::stringstream ss;
- const array<Transform>& value = node->get_transform_array(socket);
- for(size_t j = 0; j < value.size(); j++) {
- const Transform& tfm = value[j];
+ switch (socket.type) {
+ case SocketType::BOOLEAN: {
+ attr = xml_write_boolean(node->get_bool(socket));
+ break;
+ }
+ case SocketType::BOOLEAN_ARRAY: {
+ std::stringstream ss;
+ const array<bool> &value = node->get_bool_array(socket);
+ for (size_t i = 0; i < value.size(); i++) {
+ ss << xml_write_boolean(value[i]);
+ if (i != value.size() - 1)
+ ss << " ";
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::FLOAT: {
+ attr = (double)node->get_float(socket);
+ break;
+ }
+ case SocketType::FLOAT_ARRAY: {
+ std::stringstream ss;
+ const array<float> &value = node->get_float_array(socket);
+ for (size_t i = 0; i < value.size(); i++) {
+ ss << value[i];
+ if (i != value.size() - 1) {
+ ss << " ";
+ }
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::INT: {
+ attr = node->get_int(socket);
+ break;
+ }
+ case SocketType::UINT: {
+ attr = node->get_uint(socket);
+ break;
+ }
+ case SocketType::INT_ARRAY: {
+ std::stringstream ss;
+ const array<int> &value = node->get_int_array(socket);
+ for (size_t i = 0; i < value.size(); i++) {
+ ss << value[i];
+ if (i != value.size() - 1) {
+ ss << " ";
+ }
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::COLOR:
+ case SocketType::VECTOR:
+ case SocketType::POINT:
+ case SocketType::NORMAL: {
+ float3 value = node->get_float3(socket);
+ attr =
+ string_printf("%g %g %g", (double)value.x, (double)value.y, (double)value.z).c_str();
+ break;
+ }
+ case SocketType::COLOR_ARRAY:
+ case SocketType::VECTOR_ARRAY:
+ case SocketType::POINT_ARRAY:
+ case SocketType::NORMAL_ARRAY: {
+ std::stringstream ss;
+ const array<float3> &value = node->get_float3_array(socket);
+ for (size_t i = 0; i < value.size(); i++) {
+ ss << string_printf(
+ "%g %g %g", (double)value[i].x, (double)value[i].y, (double)value[i].z);
+ if (i != value.size() - 1) {
+ ss << " ";
+ }
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::POINT2: {
+ float2 value = node->get_float2(socket);
+ attr = string_printf("%g %g", (double)value.x, (double)value.y).c_str();
+ break;
+ }
+ case SocketType::POINT2_ARRAY: {
+ std::stringstream ss;
+ const array<float2> &value = node->get_float2_array(socket);
+ for (size_t i = 0; i < value.size(); i++) {
+ ss << string_printf("%g %g", (double)value[i].x, (double)value[i].y);
+ if (i != value.size() - 1) {
+ ss << " ";
+ }
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::STRING:
+ case SocketType::ENUM: {
+ attr = node->get_string(socket).c_str();
+ break;
+ }
+ case SocketType::STRING_ARRAY: {
+ std::stringstream ss;
+ const array<ustring> &value = node->get_string_array(socket);
+ for (size_t i = 0; i < value.size(); i++) {
+ ss << value[i];
+ if (i != value.size() - 1) {
+ ss << " ";
+ }
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::TRANSFORM: {
+ Transform tfm = node->get_transform(socket);
+ std::stringstream ss;
+ for (int i = 0; i < 3; i++) {
+ ss << string_printf("%g %g %g %g ",
+ (double)tfm[i][0],
+ (double)tfm[i][1],
+ (double)tfm[i][2],
+ (double)tfm[i][3]);
+ }
+ ss << string_printf("%g %g %g %g", 0.0, 0.0, 0.0, 1.0);
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::TRANSFORM_ARRAY: {
+ std::stringstream ss;
+ const array<Transform> &value = node->get_transform_array(socket);
+ for (size_t j = 0; j < value.size(); j++) {
+ const Transform &tfm = value[j];
- for(int i = 0; i < 3; i++) {
- ss << string_printf("%g %g %g %g ", (double)tfm[i][0], (double)tfm[i][1], (double)tfm[i][2], (double)tfm[i][3]);
- }
- ss << string_printf("%g %g %g %g", 0.0, 0.0, 0.0, 1.0);
- if(j != value.size() - 1) {
- ss << " ";
- }
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::NODE:
- {
- Node *value = node->get_node(socket);
- if(value) {
- attr = value->name.c_str();
- }
- break;
- }
- case SocketType::NODE_ARRAY:
- {
- std::stringstream ss;
- const array<Node*>& value = node->get_node_array(socket);
- for(size_t i = 0; i < value.size(); i++) {
- if(value[i]) {
- ss << value[i]->name.c_str();
- }
- if(i != value.size() - 1) {
- ss << " ";
- }
- }
- attr = ss.str().c_str();
- break;
- }
- case SocketType::CLOSURE:
- case SocketType::UNDEFINED:
- break;
- }
- }
+ for (int i = 0; i < 3; i++) {
+ ss << string_printf("%g %g %g %g ",
+ (double)tfm[i][0],
+ (double)tfm[i][1],
+ (double)tfm[i][2],
+ (double)tfm[i][3]);
+ }
+ ss << string_printf("%g %g %g %g", 0.0, 0.0, 0.0, 1.0);
+ if (j != value.size() - 1) {
+ ss << " ";
+ }
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::NODE: {
+ Node *value = node->get_node(socket);
+ if (value) {
+ attr = value->name.c_str();
+ }
+ break;
+ }
+ case SocketType::NODE_ARRAY: {
+ std::stringstream ss;
+ const array<Node *> &value = node->get_node_array(socket);
+ for (size_t i = 0; i < value.size(); i++) {
+ if (value[i]) {
+ ss << value[i]->name.c_str();
+ }
+ if (i != value.size() - 1) {
+ ss << " ";
+ }
+ }
+ attr = ss.str().c_str();
+ break;
+ }
+ case SocketType::CLOSURE:
+ case SocketType::UNDEFINED:
+ break;
+ }
+ }
- return xml_node;
+ return xml_node;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node_xml.h b/intern/cycles/graph/node_xml.h
index 5fecf40f96c..15bbf5d5621 100644
--- a/intern/cycles/graph/node_xml.h
+++ b/intern/cycles/graph/node_xml.h
@@ -25,10 +25,10 @@
CCL_NAMESPACE_BEGIN
struct XMLReader {
- map<ustring, Node*> node_map;
+ map<ustring, Node *> node_map;
};
-void xml_read_node(XMLReader& reader, Node *node, xml_node xml_node);
+void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node);
xml_node xml_write_node(Node *node, xml_node xml_root);
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 01552dff9bb..8a8fee108ae 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -1,7 +1,7 @@
remove_extra_strict_flags()
set(INC
- ..
+ ..
)
set(INC_SYS
@@ -9,328 +9,328 @@ set(INC_SYS
)
set(SRC_CPU_KERNELS
- kernels/cpu/kernel.cpp
- kernels/cpu/kernel_sse2.cpp
- kernels/cpu/kernel_sse3.cpp
- kernels/cpu/kernel_sse41.cpp
- kernels/cpu/kernel_avx.cpp
- kernels/cpu/kernel_avx2.cpp
- kernels/cpu/kernel_split.cpp
- kernels/cpu/kernel_split_sse2.cpp
- kernels/cpu/kernel_split_sse3.cpp
- kernels/cpu/kernel_split_sse41.cpp
- kernels/cpu/kernel_split_avx.cpp
- kernels/cpu/kernel_split_avx2.cpp
- kernels/cpu/filter.cpp
- kernels/cpu/filter_sse2.cpp
- kernels/cpu/filter_sse3.cpp
- kernels/cpu/filter_sse41.cpp
- kernels/cpu/filter_avx.cpp
- kernels/cpu/filter_avx2.cpp
+ kernels/cpu/kernel.cpp
+ kernels/cpu/kernel_sse2.cpp
+ kernels/cpu/kernel_sse3.cpp
+ kernels/cpu/kernel_sse41.cpp
+ kernels/cpu/kernel_avx.cpp
+ kernels/cpu/kernel_avx2.cpp
+ kernels/cpu/kernel_split.cpp
+ kernels/cpu/kernel_split_sse2.cpp
+ kernels/cpu/kernel_split_sse3.cpp
+ kernels/cpu/kernel_split_sse41.cpp
+ kernels/cpu/kernel_split_avx.cpp
+ kernels/cpu/kernel_split_avx2.cpp
+ kernels/cpu/filter.cpp
+ kernels/cpu/filter_sse2.cpp
+ kernels/cpu/filter_sse3.cpp
+ kernels/cpu/filter_sse41.cpp
+ kernels/cpu/filter_avx.cpp
+ kernels/cpu/filter_avx2.cpp
)
set(SRC_CUDA_KERNELS
- kernels/cuda/kernel.cu
- kernels/cuda/kernel_split.cu
- kernels/cuda/filter.cu
+ kernels/cuda/kernel.cu
+ kernels/cuda/kernel_split.cu
+ kernels/cuda/filter.cu
)
set(SRC_OPENCL_KERNELS
- kernels/opencl/kernel_bake.cl
- kernels/opencl/kernel_base.cl
- kernels/opencl/kernel_displace.cl
- kernels/opencl/kernel_background.cl
- kernels/opencl/kernel_state_buffer_size.cl
- kernels/opencl/kernel_split_bundle.cl
- kernels/opencl/kernel_data_init.cl
- kernels/opencl/kernel_path_init.cl
- kernels/opencl/kernel_queue_enqueue.cl
- kernels/opencl/kernel_scene_intersect.cl
- kernels/opencl/kernel_lamp_emission.cl
- kernels/opencl/kernel_do_volume.cl
- kernels/opencl/kernel_indirect_background.cl
- kernels/opencl/kernel_shader_setup.cl
- kernels/opencl/kernel_shader_sort.cl
- kernels/opencl/kernel_shader_eval.cl
- kernels/opencl/kernel_holdout_emission_blurring_pathtermination_ao.cl
- kernels/opencl/kernel_subsurface_scatter.cl
- kernels/opencl/kernel_direct_lighting.cl
- kernels/opencl/kernel_shadow_blocked_ao.cl
- kernels/opencl/kernel_shadow_blocked_dl.cl
- kernels/opencl/kernel_enqueue_inactive.cl
- kernels/opencl/kernel_next_iteration_setup.cl
- kernels/opencl/kernel_indirect_subsurface.cl
- kernels/opencl/kernel_buffer_update.cl
- kernels/opencl/filter.cl
+ kernels/opencl/kernel_bake.cl
+ kernels/opencl/kernel_base.cl
+ kernels/opencl/kernel_displace.cl
+ kernels/opencl/kernel_background.cl
+ kernels/opencl/kernel_state_buffer_size.cl
+ kernels/opencl/kernel_split_bundle.cl
+ kernels/opencl/kernel_data_init.cl
+ kernels/opencl/kernel_path_init.cl
+ kernels/opencl/kernel_queue_enqueue.cl
+ kernels/opencl/kernel_scene_intersect.cl
+ kernels/opencl/kernel_lamp_emission.cl
+ kernels/opencl/kernel_do_volume.cl
+ kernels/opencl/kernel_indirect_background.cl
+ kernels/opencl/kernel_shader_setup.cl
+ kernels/opencl/kernel_shader_sort.cl
+ kernels/opencl/kernel_shader_eval.cl
+ kernels/opencl/kernel_holdout_emission_blurring_pathtermination_ao.cl
+ kernels/opencl/kernel_subsurface_scatter.cl
+ kernels/opencl/kernel_direct_lighting.cl
+ kernels/opencl/kernel_shadow_blocked_ao.cl
+ kernels/opencl/kernel_shadow_blocked_dl.cl
+ kernels/opencl/kernel_enqueue_inactive.cl
+ kernels/opencl/kernel_next_iteration_setup.cl
+ kernels/opencl/kernel_indirect_subsurface.cl
+ kernels/opencl/kernel_buffer_update.cl
+ kernels/opencl/filter.cl
)
set(SRC_BVH_HEADERS
- bvh/bvh.h
- bvh/bvh_nodes.h
- bvh/bvh_shadow_all.h
- bvh/bvh_local.h
- bvh/bvh_traversal.h
- bvh/bvh_types.h
- bvh/bvh_volume.h
- bvh/bvh_volume_all.h
- bvh/qbvh_nodes.h
- bvh/qbvh_shadow_all.h
- bvh/qbvh_local.h
- bvh/qbvh_traversal.h
- bvh/qbvh_volume.h
- bvh/qbvh_volume_all.h
- bvh/obvh_nodes.h
- bvh/obvh_shadow_all.h
- bvh/obvh_local.h
- bvh/obvh_traversal.h
- bvh/obvh_volume.h
- bvh/obvh_volume_all.h
- bvh/bvh_embree.h
+ bvh/bvh.h
+ bvh/bvh_nodes.h
+ bvh/bvh_shadow_all.h
+ bvh/bvh_local.h
+ bvh/bvh_traversal.h
+ bvh/bvh_types.h
+ bvh/bvh_volume.h
+ bvh/bvh_volume_all.h
+ bvh/qbvh_nodes.h
+ bvh/qbvh_shadow_all.h
+ bvh/qbvh_local.h
+ bvh/qbvh_traversal.h
+ bvh/qbvh_volume.h
+ bvh/qbvh_volume_all.h
+ bvh/obvh_nodes.h
+ bvh/obvh_shadow_all.h
+ bvh/obvh_local.h
+ bvh/obvh_traversal.h
+ bvh/obvh_volume.h
+ bvh/obvh_volume_all.h
+ bvh/bvh_embree.h
)
set(SRC_HEADERS
- kernel_accumulate.h
- kernel_bake.h
- kernel_camera.h
- kernel_color.h
- kernel_compat_cpu.h
- kernel_compat_cuda.h
- kernel_compat_opencl.h
- kernel_differential.h
- kernel_emission.h
- kernel_film.h
- kernel_globals.h
- kernel_id_passes.h
- kernel_jitter.h
- kernel_light.h
- kernel_math.h
- kernel_montecarlo.h
- kernel_passes.h
- kernel_path.h
- kernel_path_branched.h
- kernel_path_common.h
- kernel_path_state.h
- kernel_path_surface.h
- kernel_path_subsurface.h
- kernel_path_volume.h
- kernel_profiling.h
- kernel_projection.h
- kernel_queues.h
- kernel_random.h
- kernel_shader.h
- kernel_shadow.h
- kernel_subsurface.h
- kernel_textures.h
- kernel_types.h
- kernel_volume.h
- kernel_work_stealing.h
+ kernel_accumulate.h
+ kernel_bake.h
+ kernel_camera.h
+ kernel_color.h
+ kernel_compat_cpu.h
+ kernel_compat_cuda.h
+ kernel_compat_opencl.h
+ kernel_differential.h
+ kernel_emission.h
+ kernel_film.h
+ kernel_globals.h
+ kernel_id_passes.h
+ kernel_jitter.h
+ kernel_light.h
+ kernel_math.h
+ kernel_montecarlo.h
+ kernel_passes.h
+ kernel_path.h
+ kernel_path_branched.h
+ kernel_path_common.h
+ kernel_path_state.h
+ kernel_path_surface.h
+ kernel_path_subsurface.h
+ kernel_path_volume.h
+ kernel_profiling.h
+ kernel_projection.h
+ kernel_queues.h
+ kernel_random.h
+ kernel_shader.h
+ kernel_shadow.h
+ kernel_subsurface.h
+ kernel_textures.h
+ kernel_types.h
+ kernel_volume.h
+ kernel_work_stealing.h
)
set(SRC_KERNELS_CPU_HEADERS
- kernel.h
- kernels/cpu/kernel_cpu.h
- kernels/cpu/kernel_cpu_impl.h
- kernels/cpu/kernel_cpu_image.h
- kernels/cpu/filter_cpu.h
- kernels/cpu/filter_cpu_impl.h
+ kernel.h
+ kernels/cpu/kernel_cpu.h
+ kernels/cpu/kernel_cpu_impl.h
+ kernels/cpu/kernel_cpu_image.h
+ kernels/cpu/filter_cpu.h
+ kernels/cpu/filter_cpu_impl.h
)
set(SRC_KERNELS_CUDA_HEADERS
- kernels/cuda/kernel_config.h
- kernels/cuda/kernel_cuda_image.h
+ kernels/cuda/kernel_config.h
+ kernels/cuda/kernel_cuda_image.h
)
set(SRC_KERNELS_OPENCL_HEADERS
- kernels/opencl/kernel_split_function.h
- kernels/opencl/kernel_opencl_image.h
+ kernels/opencl/kernel_split_function.h
+ kernels/opencl/kernel_opencl_image.h
)
set(SRC_CLOSURE_HEADERS
- closure/alloc.h
- closure/bsdf.h
- closure/bsdf_ashikhmin_velvet.h
- closure/bsdf_diffuse.h
- closure/bsdf_diffuse_ramp.h
- closure/bsdf_microfacet.h
- closure/bsdf_microfacet_multi.h
- closure/bsdf_microfacet_multi_impl.h
- closure/bsdf_oren_nayar.h
- closure/bsdf_phong_ramp.h
- closure/bsdf_reflection.h
- closure/bsdf_refraction.h
- closure/bsdf_toon.h
- closure/bsdf_transparent.h
- closure/bsdf_util.h
- closure/bsdf_ashikhmin_shirley.h
- closure/bsdf_hair.h
- closure/bssrdf.h
- closure/emissive.h
- closure/volume.h
- closure/bsdf_principled_diffuse.h
- closure/bsdf_principled_sheen.h
+ closure/alloc.h
+ closure/bsdf.h
+ closure/bsdf_ashikhmin_velvet.h
+ closure/bsdf_diffuse.h
+ closure/bsdf_diffuse_ramp.h
+ closure/bsdf_microfacet.h
+ closure/bsdf_microfacet_multi.h
+ closure/bsdf_microfacet_multi_impl.h
+ closure/bsdf_oren_nayar.h
+ closure/bsdf_phong_ramp.h
+ closure/bsdf_reflection.h
+ closure/bsdf_refraction.h
+ closure/bsdf_toon.h
+ closure/bsdf_transparent.h
+ closure/bsdf_util.h
+ closure/bsdf_ashikhmin_shirley.h
+ closure/bsdf_hair.h
+ closure/bssrdf.h
+ closure/emissive.h
+ closure/volume.h
+ closure/bsdf_principled_diffuse.h
+ closure/bsdf_principled_sheen.h
closure/bsdf_hair_principled.h
)
set(SRC_SVM_HEADERS
- svm/svm.h
- svm/svm_ao.h
- svm/svm_attribute.h
- svm/svm_bevel.h
- svm/svm_blackbody.h
- svm/svm_bump.h
- svm/svm_camera.h
- svm/svm_closure.h
- svm/svm_convert.h
- svm/svm_checker.h
- svm/svm_color_util.h
- svm/svm_brick.h
- svm/svm_displace.h
- svm/svm_fresnel.h
- svm/svm_wireframe.h
- svm/svm_wavelength.h
- svm/svm_gamma.h
- svm/svm_brightness.h
- svm/svm_geometry.h
- svm/svm_gradient.h
- svm/svm_hsv.h
- svm/svm_ies.h
- svm/svm_image.h
- svm/svm_invert.h
- svm/svm_light_path.h
- svm/svm_magic.h
- svm/svm_mapping.h
- svm/svm_math.h
- svm/svm_math_util.h
- svm/svm_mix.h
- svm/svm_musgrave.h
- svm/svm_noise.h
- svm/svm_noisetex.h
- svm/svm_normal.h
- svm/svm_ramp.h
- svm/svm_ramp_util.h
- svm/svm_sepcomb_hsv.h
- svm/svm_sepcomb_vector.h
- svm/svm_sky.h
- svm/svm_tex_coord.h
- svm/svm_texture.h
- svm/svm_types.h
- svm/svm_value.h
- svm/svm_vector_transform.h
- svm/svm_voronoi.h
- svm/svm_voxel.h
- svm/svm_wave.h
+ svm/svm.h
+ svm/svm_ao.h
+ svm/svm_attribute.h
+ svm/svm_bevel.h
+ svm/svm_blackbody.h
+ svm/svm_bump.h
+ svm/svm_camera.h
+ svm/svm_closure.h
+ svm/svm_convert.h
+ svm/svm_checker.h
+ svm/svm_color_util.h
+ svm/svm_brick.h
+ svm/svm_displace.h
+ svm/svm_fresnel.h
+ svm/svm_wireframe.h
+ svm/svm_wavelength.h
+ svm/svm_gamma.h
+ svm/svm_brightness.h
+ svm/svm_geometry.h
+ svm/svm_gradient.h
+ svm/svm_hsv.h
+ svm/svm_ies.h
+ svm/svm_image.h
+ svm/svm_invert.h
+ svm/svm_light_path.h
+ svm/svm_magic.h
+ svm/svm_mapping.h
+ svm/svm_math.h
+ svm/svm_math_util.h
+ svm/svm_mix.h
+ svm/svm_musgrave.h
+ svm/svm_noise.h
+ svm/svm_noisetex.h
+ svm/svm_normal.h
+ svm/svm_ramp.h
+ svm/svm_ramp_util.h
+ svm/svm_sepcomb_hsv.h
+ svm/svm_sepcomb_vector.h
+ svm/svm_sky.h
+ svm/svm_tex_coord.h
+ svm/svm_texture.h
+ svm/svm_types.h
+ svm/svm_value.h
+ svm/svm_vector_transform.h
+ svm/svm_voronoi.h
+ svm/svm_voxel.h
+ svm/svm_wave.h
)
set(SRC_GEOM_HEADERS
- geom/geom.h
- geom/geom_attribute.h
- geom/geom_curve.h
- geom/geom_curve_intersect.h
- geom/geom_motion_curve.h
- geom/geom_motion_triangle.h
- geom/geom_motion_triangle_intersect.h
- geom/geom_motion_triangle_shader.h
- geom/geom_object.h
- geom/geom_patch.h
- geom/geom_primitive.h
- geom/geom_subd_triangle.h
- geom/geom_triangle.h
- geom/geom_triangle_intersect.h
- geom/geom_volume.h
+ geom/geom.h
+ geom/geom_attribute.h
+ geom/geom_curve.h
+ geom/geom_curve_intersect.h
+ geom/geom_motion_curve.h
+ geom/geom_motion_triangle.h
+ geom/geom_motion_triangle_intersect.h
+ geom/geom_motion_triangle_shader.h
+ geom/geom_object.h
+ geom/geom_patch.h
+ geom/geom_primitive.h
+ geom/geom_subd_triangle.h
+ geom/geom_triangle.h
+ geom/geom_triangle_intersect.h
+ geom/geom_volume.h
)
set(SRC_FILTER_HEADERS
- filter/filter.h
- filter/filter_defines.h
- filter/filter_features.h
- filter/filter_features_sse.h
- filter/filter_kernel.h
- filter/filter_nlm_cpu.h
- filter/filter_nlm_gpu.h
- filter/filter_prefilter.h
- filter/filter_reconstruction.h
- filter/filter_transform.h
- filter/filter_transform_gpu.h
- filter/filter_transform_sse.h
+ filter/filter.h
+ filter/filter_defines.h
+ filter/filter_features.h
+ filter/filter_features_sse.h
+ filter/filter_kernel.h
+ filter/filter_nlm_cpu.h
+ filter/filter_nlm_gpu.h
+ filter/filter_prefilter.h
+ filter/filter_reconstruction.h
+ filter/filter_transform.h
+ filter/filter_transform_gpu.h
+ filter/filter_transform_sse.h
)
set(SRC_UTIL_HEADERS
- ../util/util_atomic.h
- ../util/util_color.h
- ../util/util_defines.h
- ../util/util_half.h
- ../util/util_hash.h
- ../util/util_math.h
- ../util/util_math_fast.h
- ../util/util_math_intersect.h
- ../util/util_math_float2.h
- ../util/util_math_float3.h
- ../util/util_math_float4.h
- ../util/util_math_int2.h
- ../util/util_math_int3.h
- ../util/util_math_int4.h
- ../util/util_math_matrix.h
- ../util/util_projection.h
- ../util/util_rect.h
- ../util/util_static_assert.h
- ../util/util_transform.h
- ../util/util_texture.h
- ../util/util_types.h
- ../util/util_types_float2.h
- ../util/util_types_float2_impl.h
- ../util/util_types_float3.h
- ../util/util_types_float3_impl.h
- ../util/util_types_float4.h
- ../util/util_types_float4_impl.h
- ../util/util_types_float8.h
- ../util/util_types_float8_impl.h
- ../util/util_types_int2.h
- ../util/util_types_int2_impl.h
- ../util/util_types_int3.h
- ../util/util_types_int3_impl.h
- ../util/util_types_int4.h
- ../util/util_types_int4_impl.h
- ../util/util_types_uchar2.h
- ../util/util_types_uchar2_impl.h
- ../util/util_types_uchar3.h
- ../util/util_types_uchar3_impl.h
- ../util/util_types_uchar4.h
- ../util/util_types_uchar4_impl.h
- ../util/util_types_uint2.h
- ../util/util_types_uint2_impl.h
- ../util/util_types_uint3.h
- ../util/util_types_uint3_impl.h
- ../util/util_types_uint4.h
- ../util/util_types_uint4_impl.h
- ../util/util_types_ushort4.h
- ../util/util_types_vector3.h
- ../util/util_types_vector3_impl.h
+ ../util/util_atomic.h
+ ../util/util_color.h
+ ../util/util_defines.h
+ ../util/util_half.h
+ ../util/util_hash.h
+ ../util/util_math.h
+ ../util/util_math_fast.h
+ ../util/util_math_intersect.h
+ ../util/util_math_float2.h
+ ../util/util_math_float3.h
+ ../util/util_math_float4.h
+ ../util/util_math_int2.h
+ ../util/util_math_int3.h
+ ../util/util_math_int4.h
+ ../util/util_math_matrix.h
+ ../util/util_projection.h
+ ../util/util_rect.h
+ ../util/util_static_assert.h
+ ../util/util_transform.h
+ ../util/util_texture.h
+ ../util/util_types.h
+ ../util/util_types_float2.h
+ ../util/util_types_float2_impl.h
+ ../util/util_types_float3.h
+ ../util/util_types_float3_impl.h
+ ../util/util_types_float4.h
+ ../util/util_types_float4_impl.h
+ ../util/util_types_float8.h
+ ../util/util_types_float8_impl.h
+ ../util/util_types_int2.h
+ ../util/util_types_int2_impl.h
+ ../util/util_types_int3.h
+ ../util/util_types_int3_impl.h
+ ../util/util_types_int4.h
+ ../util/util_types_int4_impl.h
+ ../util/util_types_uchar2.h
+ ../util/util_types_uchar2_impl.h
+ ../util/util_types_uchar3.h
+ ../util/util_types_uchar3_impl.h
+ ../util/util_types_uchar4.h
+ ../util/util_types_uchar4_impl.h
+ ../util/util_types_uint2.h
+ ../util/util_types_uint2_impl.h
+ ../util/util_types_uint3.h
+ ../util/util_types_uint3_impl.h
+ ../util/util_types_uint4.h
+ ../util/util_types_uint4_impl.h
+ ../util/util_types_ushort4.h
+ ../util/util_types_vector3.h
+ ../util/util_types_vector3_impl.h
)
set(SRC_SPLIT_HEADERS
- split/kernel_branched.h
- split/kernel_buffer_update.h
- split/kernel_data_init.h
- split/kernel_direct_lighting.h
- split/kernel_do_volume.h
- split/kernel_enqueue_inactive.h
- split/kernel_holdout_emission_blurring_pathtermination_ao.h
- split/kernel_indirect_background.h
- split/kernel_indirect_subsurface.h
- split/kernel_lamp_emission.h
- split/kernel_next_iteration_setup.h
- split/kernel_path_init.h
- split/kernel_queue_enqueue.h
- split/kernel_scene_intersect.h
- split/kernel_shader_setup.h
- split/kernel_shader_sort.h
- split/kernel_shader_eval.h
- split/kernel_shadow_blocked_ao.h
- split/kernel_shadow_blocked_dl.h
- split/kernel_split_common.h
- split/kernel_split_data.h
- split/kernel_split_data_types.h
- split/kernel_subsurface_scatter.h
+ split/kernel_branched.h
+ split/kernel_buffer_update.h
+ split/kernel_data_init.h
+ split/kernel_direct_lighting.h
+ split/kernel_do_volume.h
+ split/kernel_enqueue_inactive.h
+ split/kernel_holdout_emission_blurring_pathtermination_ao.h
+ split/kernel_indirect_background.h
+ split/kernel_indirect_subsurface.h
+ split/kernel_lamp_emission.h
+ split/kernel_next_iteration_setup.h
+ split/kernel_path_init.h
+ split/kernel_queue_enqueue.h
+ split/kernel_scene_intersect.h
+ split/kernel_shader_setup.h
+ split/kernel_shader_sort.h
+ split/kernel_shader_eval.h
+ split/kernel_shadow_blocked_ao.h
+ split/kernel_shadow_blocked_dl.h
+ split/kernel_split_common.h
+ split/kernel_split_data.h
+ split/kernel_split_data_types.h
+ split/kernel_subsurface_scatter.h
)
set(LIB
@@ -340,145 +340,145 @@ set(LIB
# CUDA module
if(WITH_CYCLES_CUDA_BINARIES)
- # 64 bit only
- set(CUDA_BITS 64)
-
- # CUDA version
- execute_process(COMMAND ${CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
- string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR "${NVCC_OUT}")
- string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR "${NVCC_OUT}")
- set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
-
- # warn for other versions
- if(CUDA_VERSION MATCHES "101")
- else()
- message(WARNING
- "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
- "build may succeed but only CUDA 10.1 is officially supported")
- endif()
-
- # build for each arch
- set(cuda_sources kernels/cuda/kernel.cu kernels/cuda/kernel_split.cu
- ${SRC_HEADERS}
- ${SRC_KERNELS_CUDA_HEADERS}
- ${SRC_BVH_HEADERS}
- ${SRC_SVM_HEADERS}
- ${SRC_GEOM_HEADERS}
- ${SRC_CLOSURE_HEADERS}
- ${SRC_UTIL_HEADERS}
- )
- set(cuda_filter_sources kernels/cuda/filter.cu
- ${SRC_HEADERS}
- ${SRC_KERNELS_CUDA_HEADERS}
- ${SRC_FILTER_HEADERS}
- ${SRC_UTIL_HEADERS}
- )
- set(cuda_cubins)
-
- macro(CYCLES_CUDA_KERNEL_ADD arch prev_arch name flags sources experimental)
- set(cuda_cubin ${name}_${arch}.cubin)
-
- set(kernel_sources ${sources})
- if(NOT ${prev_arch} STREQUAL "none")
- set(kernel_sources ${kernel_sources} ${name}_${prev_arch}.cubin)
- endif()
-
- set(cuda_kernel_src "/kernels/cuda/${name}.cu")
-
- set(cuda_flags
- -D CCL_NAMESPACE_BEGIN=
- -D CCL_NAMESPACE_END=
- -D NVCC
- -m ${CUDA_BITS}
- -I ${CMAKE_CURRENT_SOURCE_DIR}/..
- -I ${CMAKE_CURRENT_SOURCE_DIR}/kernels/cuda
- --use_fast_math
- -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin})
-
- if(${experimental})
- set(cuda_flags ${cuda_flags} -D __KERNEL_EXPERIMENTAL__)
- set(name ${name}_experimental)
- endif()
-
- if(WITH_CYCLES_DEBUG)
- set(cuda_flags ${cuda_flags} -D __KERNEL_DEBUG__)
- endif()
-
- if(WITH_CYCLES_CUBIN_COMPILER)
- string(SUBSTRING ${arch} 3 -1 CUDA_ARCH)
-
- # Needed to find libnvrtc-builtins.so. Can't do it from inside
- # cycles_cubin_cc since the env variable is read before main()
- if(APPLE)
- set(CUBIN_CC_ENV ${CMAKE_COMMAND}
- -E env DYLD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib")
- elseif(UNIX)
- set(CUBIN_CC_ENV ${CMAKE_COMMAND}
- -E env LD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib64")
- endif()
-
- add_custom_command(
- OUTPUT ${cuda_cubin}
- COMMAND ${CUBIN_CC_ENV}
- "$<TARGET_FILE:cycles_cubin_cc>"
- -target ${CUDA_ARCH}
- -i ${CMAKE_CURRENT_SOURCE_DIR}${cuda_kernel_src}
- ${cuda_flags}
- -v
- -cuda-toolkit-dir "${CUDA_TOOLKIT_ROOT_DIR}"
- DEPENDS ${kernel_sources} cycles_cubin_cc)
- else()
- add_custom_command(
- OUTPUT ${cuda_cubin}
- COMMAND ${CUDA_NVCC_EXECUTABLE}
- -arch=${arch}
- ${CUDA_NVCC_FLAGS}
- --cubin
- ${CMAKE_CURRENT_SOURCE_DIR}${cuda_kernel_src}
- --ptxas-options="-v"
- ${cuda_flags}
- DEPENDS ${kernel_sources})
- endif()
- delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib)
- list(APPEND cuda_cubins ${cuda_cubin})
-
- unset(cuda_debug_flags)
- endmacro()
-
- set(prev_arch "none")
- foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
- if(${arch} MATCHES "sm_2.")
- message(STATUS "CUDA binaries for ${arch} are no longer supported, skipped.")
- elseif(${arch} MATCHES "sm_7." AND ${CUDA_VERSION} LESS 100)
- message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
- else()
- # Compile regular kernel
- CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} filter "" "${cuda_filter_sources}" FALSE)
- CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} kernel "" "${cuda_sources}" FALSE)
-
- if(WITH_CYCLES_CUDA_SPLIT_KERNEL_BINARIES)
- # Compile split kernel
- CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} kernel_split "-D __SPLIT__" "${cuda_sources}" FALSE)
- endif()
-
- if(WITH_CYCLES_CUDA_BUILD_SERIAL)
- set(prev_arch ${arch})
- endif()
- endif()
- endforeach()
-
- add_custom_target(cycles_kernel_cuda ALL DEPENDS ${cuda_cubins})
- cycles_set_solution_folder(cycles_kernel_cuda)
+ # 64 bit only
+ set(CUDA_BITS 64)
+
+ # CUDA version
+ execute_process(COMMAND ${CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
+ string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR "${NVCC_OUT}")
+ string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR "${NVCC_OUT}")
+ set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
+
+ # warn for other versions
+ if(CUDA_VERSION MATCHES "101")
+ else()
+ message(WARNING
+ "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
+ "build may succeed but only CUDA 10.1 is officially supported")
+ endif()
+
+ # build for each arch
+ set(cuda_sources kernels/cuda/kernel.cu kernels/cuda/kernel_split.cu
+ ${SRC_HEADERS}
+ ${SRC_KERNELS_CUDA_HEADERS}
+ ${SRC_BVH_HEADERS}
+ ${SRC_SVM_HEADERS}
+ ${SRC_GEOM_HEADERS}
+ ${SRC_CLOSURE_HEADERS}
+ ${SRC_UTIL_HEADERS}
+ )
+ set(cuda_filter_sources kernels/cuda/filter.cu
+ ${SRC_HEADERS}
+ ${SRC_KERNELS_CUDA_HEADERS}
+ ${SRC_FILTER_HEADERS}
+ ${SRC_UTIL_HEADERS}
+ )
+ set(cuda_cubins)
+
+ macro(CYCLES_CUDA_KERNEL_ADD arch prev_arch name flags sources experimental)
+ set(cuda_cubin ${name}_${arch}.cubin)
+
+ set(kernel_sources ${sources})
+ if(NOT ${prev_arch} STREQUAL "none")
+ set(kernel_sources ${kernel_sources} ${name}_${prev_arch}.cubin)
+ endif()
+
+ set(cuda_kernel_src "/kernels/cuda/${name}.cu")
+
+ set(cuda_flags
+ -D CCL_NAMESPACE_BEGIN=
+ -D CCL_NAMESPACE_END=
+ -D NVCC
+ -m ${CUDA_BITS}
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/..
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/kernels/cuda
+ --use_fast_math
+ -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin})
+
+ if(${experimental})
+ set(cuda_flags ${cuda_flags} -D __KERNEL_EXPERIMENTAL__)
+ set(name ${name}_experimental)
+ endif()
+
+ if(WITH_CYCLES_DEBUG)
+ set(cuda_flags ${cuda_flags} -D __KERNEL_DEBUG__)
+ endif()
+
+ if(WITH_CYCLES_CUBIN_COMPILER)
+ string(SUBSTRING ${arch} 3 -1 CUDA_ARCH)
+
+ # Needed to find libnvrtc-builtins.so. Can't do it from inside
+ # cycles_cubin_cc since the env variable is read before main()
+ if(APPLE)
+ set(CUBIN_CC_ENV ${CMAKE_COMMAND}
+ -E env DYLD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib")
+ elseif(UNIX)
+ set(CUBIN_CC_ENV ${CMAKE_COMMAND}
+ -E env LD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib64")
+ endif()
+
+ add_custom_command(
+ OUTPUT ${cuda_cubin}
+ COMMAND ${CUBIN_CC_ENV}
+ "$<TARGET_FILE:cycles_cubin_cc>"
+ -target ${CUDA_ARCH}
+ -i ${CMAKE_CURRENT_SOURCE_DIR}${cuda_kernel_src}
+ ${cuda_flags}
+ -v
+ -cuda-toolkit-dir "${CUDA_TOOLKIT_ROOT_DIR}"
+ DEPENDS ${kernel_sources} cycles_cubin_cc)
+ else()
+ add_custom_command(
+ OUTPUT ${cuda_cubin}
+ COMMAND ${CUDA_NVCC_EXECUTABLE}
+ -arch=${arch}
+ ${CUDA_NVCC_FLAGS}
+ --cubin
+ ${CMAKE_CURRENT_SOURCE_DIR}${cuda_kernel_src}
+ --ptxas-options="-v"
+ ${cuda_flags}
+ DEPENDS ${kernel_sources})
+ endif()
+ delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib)
+ list(APPEND cuda_cubins ${cuda_cubin})
+
+ unset(cuda_debug_flags)
+ endmacro()
+
+ set(prev_arch "none")
+ foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
+ if(${arch} MATCHES "sm_2.")
+ message(STATUS "CUDA binaries for ${arch} are no longer supported, skipped.")
+ elseif(${arch} MATCHES "sm_7." AND ${CUDA_VERSION} LESS 100)
+ message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
+ else()
+ # Compile regular kernel
+ CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} filter "" "${cuda_filter_sources}" FALSE)
+ CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} kernel "" "${cuda_sources}" FALSE)
+
+ if(WITH_CYCLES_CUDA_SPLIT_KERNEL_BINARIES)
+ # Compile split kernel
+ CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} kernel_split "-D __SPLIT__" "${cuda_sources}" FALSE)
+ endif()
+
+ if(WITH_CYCLES_CUDA_BUILD_SERIAL)
+ set(prev_arch ${arch})
+ endif()
+ endif()
+ endforeach()
+
+ add_custom_target(cycles_kernel_cuda ALL DEPENDS ${cuda_cubins})
+ cycles_set_solution_folder(cycles_kernel_cuda)
endif()
# OSL module
if(WITH_CYCLES_OSL)
- list(APPEND LIB
- cycles_kernel_osl
- )
- add_subdirectory(osl)
- add_subdirectory(shaders)
+ list(APPEND LIB
+ cycles_kernel_osl
+ )
+ add_subdirectory(osl)
+ add_subdirectory(shaders)
endif()
# CPU module
@@ -491,56 +491,56 @@ set_source_files_properties(kernels/cpu/kernel_split.cpp PROPERTIES COMPILE_FLAG
set_source_files_properties(kernels/cpu/filter.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_KERNEL_FLAGS}")
if(CXX_HAS_SSE)
- set_source_files_properties(kernels/cpu/kernel_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/kernel_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/kernel_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/kernel_split_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/kernel_split_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/kernel_split_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/filter_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/filter_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/filter_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_split_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_split_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_split_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/filter_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/filter_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/filter_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
endif()
if(CXX_HAS_AVX)
- set_source_files_properties(kernels/cpu/kernel_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/kernel_split_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/filter_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_split_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/filter_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
endif()
if(CXX_HAS_AVX2)
- set_source_files_properties(kernels/cpu/kernel_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/kernel_split_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
- set_source_files_properties(kernels/cpu/filter_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/kernel_split_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
+ set_source_files_properties(kernels/cpu/filter_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
endif()
cycles_add_library(cycles_kernel "${LIB}"
- ${SRC_CPU_KERNELS}
- ${SRC_CUDA_KERNELS}
- ${SRC_OPENCL_KERNELS}
- ${SRC_HEADERS}
- ${SRC_KERNELS_CPU_HEADERS}
- ${SRC_KERNELS_CUDA_HEADERS}
- ${SRC_KERNELS_OPENCL_HEADERS}
- ${SRC_BVH_HEADERS}
- ${SRC_CLOSURE_HEADERS}
- ${SRC_FILTER_HEADERS}
- ${SRC_SVM_HEADERS}
- ${SRC_GEOM_HEADERS}
- ${SRC_SPLIT_HEADERS}
+ ${SRC_CPU_KERNELS}
+ ${SRC_CUDA_KERNELS}
+ ${SRC_OPENCL_KERNELS}
+ ${SRC_HEADERS}
+ ${SRC_KERNELS_CPU_HEADERS}
+ ${SRC_KERNELS_CUDA_HEADERS}
+ ${SRC_KERNELS_OPENCL_HEADERS}
+ ${SRC_BVH_HEADERS}
+ ${SRC_CLOSURE_HEADERS}
+ ${SRC_FILTER_HEADERS}
+ ${SRC_SVM_HEADERS}
+ ${SRC_GEOM_HEADERS}
+ ${SRC_SPLIT_HEADERS}
)
if(WITH_CYCLES_CUDA)
- add_dependencies(cycles_kernel cycles_kernel_cuda)
+ add_dependencies(cycles_kernel cycles_kernel_cuda)
endif()
# OpenCL kernel
#set(KERNEL_PREPROCESSED ${CMAKE_CURRENT_BINARY_DIR}/kernel_preprocessed.cl)
#add_custom_command(
-# OUTPUT ${KERNEL_PREPROCESSED}
-# COMMAND gcc -x c++ -E ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cl -I ${CMAKE_CURRENT_SOURCE_DIR}/../util/ -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -o ${KERNEL_PREPROCESSED}
-# DEPENDS ${SRC_KERNEL} ${SRC_UTIL_HEADERS})
+# OUTPUT ${KERNEL_PREPROCESSED}
+# COMMAND gcc -x c++ -E ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cl -I ${CMAKE_CURRENT_SOURCE_DIR}/../util/ -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -o ${KERNEL_PREPROCESSED}
+# DEPENDS ${SRC_KERNEL} ${SRC_UTIL_HEADERS})
#add_custom_target(cycles_kernel_preprocess ALL DEPENDS ${KERNEL_PREPROCESSED})
#delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${KERNEL_PREPROCESSED}" ${CYCLES_INSTALL_PATH}/kernel)
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index e5f807833f3..13e72ed299f 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -57,19 +57,19 @@ CCL_NAMESPACE_BEGIN
#if defined(__HAIR__)
# define BVH_FUNCTION_NAME bvh_intersect_hair
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_HAIR_MINIMUM_WIDTH
# include "kernel/bvh/bvh_traversal.h"
#endif
#if defined(__OBJECT_MOTION__)
# define BVH_FUNCTION_NAME bvh_intersect_motion
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION
# include "kernel/bvh/bvh_traversal.h"
#endif
#if defined(__HAIR__) && defined(__OBJECT_MOTION__)
# define BVH_FUNCTION_NAME bvh_intersect_hair_motion
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_HAIR_MINIMUM_WIDTH | BVH_MOTION
# include "kernel/bvh/bvh_traversal.h"
#endif
@@ -82,10 +82,10 @@ CCL_NAMESPACE_BEGIN
# if defined(__OBJECT_MOTION__)
# define BVH_FUNCTION_NAME bvh_intersect_local_motion
-# define BVH_FUNCTION_FEATURES BVH_MOTION|BVH_HAIR
+# define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_HAIR
# include "kernel/bvh/bvh_local.h"
# endif
-#endif /* __BVH_LOCAL__ */
+#endif /* __BVH_LOCAL__ */
/* Volume BVH traversal */
@@ -96,16 +96,16 @@ CCL_NAMESPACE_BEGIN
# if defined(__INSTANCING__)
# define BVH_FUNCTION_NAME bvh_intersect_volume_instancing
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR
# include "kernel/bvh/bvh_volume.h"
# endif
# if defined(__OBJECT_MOTION__)
# define BVH_FUNCTION_NAME bvh_intersect_volume_motion
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION | BVH_HAIR
# include "kernel/bvh/bvh_volume.h"
# endif
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
/* Record all intersections - Shadow BVH traversal */
@@ -122,22 +122,22 @@ CCL_NAMESPACE_BEGIN
# if defined(__HAIR__)
# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR
# include "kernel/bvh/bvh_shadow_all.h"
# endif
# if defined(__OBJECT_MOTION__)
# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_motion
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION
# include "kernel/bvh/bvh_shadow_all.h"
# endif
# if defined(__HAIR__) && defined(__OBJECT_MOTION__)
# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair_motion
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_MOTION
# include "kernel/bvh/bvh_shadow_all.h"
# endif
-#endif /* __SHADOW_RECORD_ALL__ */
+#endif /* __SHADOW_RECORD_ALL__ */
/* Record all intersections - Volume BVH traversal */
@@ -148,16 +148,16 @@ CCL_NAMESPACE_BEGIN
# if defined(__INSTANCING__)
# define BVH_FUNCTION_NAME bvh_intersect_volume_all_instancing
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR
# include "kernel/bvh/bvh_volume_all.h"
# endif
# if defined(__OBJECT_MOTION__)
# define BVH_FUNCTION_NAME bvh_intersect_volume_all_motion
-# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR
+# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION | BVH_HAIR
# include "kernel/bvh/bvh_volume_all.h"
# endif
-#endif /* __VOLUME_RECORD_ALL__ */
+#endif /* __VOLUME_RECORD_ALL__ */
#undef BVH_FEATURE
#undef BVH_NAME_JOIN
@@ -166,15 +166,15 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline bool scene_intersect_valid(const Ray *ray)
{
- /* NOTE: Due to some vectorization code non-finite origin point might
- * cause lots of false-positive intersections which will overflow traversal
- * stack.
- * This code is a quick way to perform early output, to avoid crashes in
- * such cases.
- * From production scenes so far it seems it's enough to test first element
- * only.
- */
- return isfinite(ray->P.x);
+ /* NOTE: Due to some vectorization code non-finite origin point might
+ * cause lots of false-positive intersections which will overflow traversal
+ * stack.
+ * This code is a quick way to perform early output, to avoid crashes in
+ * such cases.
+ * From production scenes so far it seems it's enough to test first element
+ * only.
+ */
+ return isfinite(ray->P.x);
}
/* Note: ray is passed by value to work around a possible CUDA compiler bug. */
@@ -186,59 +186,60 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
float difl,
float extmax)
{
- PROFILING_INIT(kg, PROFILING_INTERSECT);
+ PROFILING_INIT(kg, PROFILING_INTERSECT);
- if(!scene_intersect_valid(&ray)) {
- return false;
- }
+ if (!scene_intersect_valid(&ray)) {
+ return false;
+ }
#ifdef __EMBREE__
- if(kernel_data.bvh.scene) {
- isect->t = ray.t;
- CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
- IntersectContext rtc_ctx(&ctx);
- RTCRayHit ray_hit;
- kernel_embree_setup_rayhit(ray, ray_hit, visibility);
- rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
- if(ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID && ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) {
- kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect);
- return true;
- }
- return false;
- }
-#endif /* __EMBREE__ */
+ if (kernel_data.bvh.scene) {
+ isect->t = ray.t;
+ CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
+ IntersectContext rtc_ctx(&ctx);
+ RTCRayHit ray_hit;
+ kernel_embree_setup_rayhit(ray, ray_hit, visibility);
+ rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
+ if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID &&
+ ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) {
+ kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect);
+ return true;
+ }
+ return false;
+ }
+#endif /* __EMBREE__ */
#ifdef __OBJECT_MOTION__
- if(kernel_data.bvh.have_motion) {
+ if (kernel_data.bvh.have_motion) {
# ifdef __HAIR__
- if(kernel_data.bvh.have_curves)
- return bvh_intersect_hair_motion(kg, &ray, isect, visibility, lcg_state, difl, extmax);
-# endif /* __HAIR__ */
+ if (kernel_data.bvh.have_curves)
+ return bvh_intersect_hair_motion(kg, &ray, isect, visibility, lcg_state, difl, extmax);
+# endif /* __HAIR__ */
- return bvh_intersect_motion(kg, &ray, isect, visibility);
- }
-#endif /* __OBJECT_MOTION__ */
+ return bvh_intersect_motion(kg, &ray, isect, visibility);
+ }
+#endif /* __OBJECT_MOTION__ */
#ifdef __HAIR__
- if(kernel_data.bvh.have_curves)
- return bvh_intersect_hair(kg, &ray, isect, visibility, lcg_state, difl, extmax);
-#endif /* __HAIR__ */
+ if (kernel_data.bvh.have_curves)
+ return bvh_intersect_hair(kg, &ray, isect, visibility, lcg_state, difl, extmax);
+#endif /* __HAIR__ */
#ifdef __KERNEL_CPU__
# ifdef __INSTANCING__
- if(kernel_data.bvh.have_instancing)
- return bvh_intersect_instancing(kg, &ray, isect, visibility);
-# endif /* __INSTANCING__ */
+ if (kernel_data.bvh.have_instancing)
+ return bvh_intersect_instancing(kg, &ray, isect, visibility);
+# endif /* __INSTANCING__ */
- return bvh_intersect(kg, &ray, isect, visibility);
-#else /* __KERNEL_CPU__ */
+ return bvh_intersect(kg, &ray, isect, visibility);
+#else /* __KERNEL_CPU__ */
# ifdef __INSTANCING__
- return bvh_intersect_instancing(kg, &ray, isect, visibility);
+ return bvh_intersect_instancing(kg, &ray, isect, visibility);
# else
- return bvh_intersect(kg, &ray, isect, visibility);
-# endif /* __INSTANCING__ */
+ return bvh_intersect(kg, &ray, isect, visibility);
+# endif /* __INSTANCING__ */
-#endif /* __KERNEL_CPU__ */
+#endif /* __KERNEL_CPU__ */
}
#ifdef __BVH_LOCAL__
@@ -250,77 +251,61 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg,
uint *lcg_state,
int max_hits)
{
- PROFILING_INIT(kg, PROFILING_INTERSECT_LOCAL);
+ PROFILING_INIT(kg, PROFILING_INTERSECT_LOCAL);
- if(!scene_intersect_valid(&ray)) {
- local_isect->num_hits = 0;
- return false;
- }
-#ifdef __EMBREE__
- if(kernel_data.bvh.scene) {
- CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS);
- ctx.lcg_state = lcg_state;
- ctx.max_hits = max_hits;
- ctx.ss_isect = local_isect;
- local_isect->num_hits = 0;
- ctx.sss_object_id = local_object;
- IntersectContext rtc_ctx(&ctx);
- RTCRay rtc_ray;
- kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY);
-
- /* Get the Embree scene for this intersection. */
- RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2);
- if(geom) {
- float3 P = ray.P;
- float3 dir = ray.D;
- float3 idir = ray.D;
- const int object_flag = kernel_tex_fetch(__object_flag, local_object);
- if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- Transform ob_itfm;
- rtc_ray.tfar = bvh_instance_motion_push(kg,
- local_object,
- &ray,
- &P,
- &dir,
- &idir,
- ray.t,
- &ob_itfm);
- /* bvh_instance_motion_push() returns the inverse transform but
- * it's not needed here. */
- (void) ob_itfm;
-
- rtc_ray.org_x = P.x;
- rtc_ray.org_y = P.y;
- rtc_ray.org_z = P.z;
- rtc_ray.dir_x = dir.x;
- rtc_ray.dir_y = dir.y;
- rtc_ray.dir_z = dir.z;
- }
- RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom);
- if(scene) {
- rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray);
- }
- }
-
- return local_isect->num_hits > 0;
- }
-#endif /* __EMBREE__ */
-#ifdef __OBJECT_MOTION__
- if(kernel_data.bvh.have_motion) {
- return bvh_intersect_local_motion(kg,
- &ray,
- local_isect,
- local_object,
- lcg_state,
- max_hits);
- }
-#endif /* __OBJECT_MOTION__ */
- return bvh_intersect_local(kg,
- &ray,
- local_isect,
- local_object,
- lcg_state,
- max_hits);
+ if (!scene_intersect_valid(&ray)) {
+ local_isect->num_hits = 0;
+ return false;
+ }
+# ifdef __EMBREE__
+ if (kernel_data.bvh.scene) {
+ CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS);
+ ctx.lcg_state = lcg_state;
+ ctx.max_hits = max_hits;
+ ctx.ss_isect = local_isect;
+ local_isect->num_hits = 0;
+ ctx.sss_object_id = local_object;
+ IntersectContext rtc_ctx(&ctx);
+ RTCRay rtc_ray;
+ kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY);
+
+ /* Get the Embree scene for this intersection. */
+ RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2);
+ if (geom) {
+ float3 P = ray.P;
+ float3 dir = ray.D;
+ float3 idir = ray.D;
+ const int object_flag = kernel_tex_fetch(__object_flag, local_object);
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ Transform ob_itfm;
+ rtc_ray.tfar = bvh_instance_motion_push(
+ kg, local_object, &ray, &P, &dir, &idir, ray.t, &ob_itfm);
+ /* bvh_instance_motion_push() returns the inverse transform but
+ * it's not needed here. */
+ (void)ob_itfm;
+
+ rtc_ray.org_x = P.x;
+ rtc_ray.org_y = P.y;
+ rtc_ray.org_z = P.z;
+ rtc_ray.dir_x = dir.x;
+ rtc_ray.dir_y = dir.y;
+ rtc_ray.dir_z = dir.z;
+ }
+ RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom);
+ if (scene) {
+ rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray);
+ }
+ }
+
+ return local_isect->num_hits > 0;
+ }
+# endif /* __EMBREE__ */
+# ifdef __OBJECT_MOTION__
+ if (kernel_data.bvh.have_motion) {
+ return bvh_intersect_local_motion(kg, &ray, local_isect, local_object, lcg_state, max_hits);
+ }
+# endif /* __OBJECT_MOTION__ */
+ return bvh_intersect_local(kg, &ray, local_isect, local_object, lcg_state, max_hits);
}
#endif
@@ -332,82 +317,57 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
uint max_hits,
uint *num_hits)
{
- PROFILING_INIT(kg, PROFILING_INTERSECT_SHADOW_ALL);
+ PROFILING_INIT(kg, PROFILING_INTERSECT_SHADOW_ALL);
- if(!scene_intersect_valid(ray)) {
- *num_hits = 0;
- return false;
- }
+ if (!scene_intersect_valid(ray)) {
+ *num_hits = 0;
+ return false;
+ }
# ifdef __EMBREE__
- if(kernel_data.bvh.scene) {
- CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL);
- ctx.isect_s = isect;
- ctx.max_hits = max_hits;
- ctx.num_hits = 0;
- IntersectContext rtc_ctx(&ctx);
- RTCRay rtc_ray;
- kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW);
- rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
-
- if(ctx.num_hits > max_hits) {
- return true;
- }
- *num_hits = ctx.num_hits;
- return rtc_ray.tfar == -INFINITY;
- }
+ if (kernel_data.bvh.scene) {
+ CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL);
+ ctx.isect_s = isect;
+ ctx.max_hits = max_hits;
+ ctx.num_hits = 0;
+ IntersectContext rtc_ctx(&ctx);
+ RTCRay rtc_ray;
+ kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW);
+ rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
+
+ if (ctx.num_hits > max_hits) {
+ return true;
+ }
+ *num_hits = ctx.num_hits;
+ return rtc_ray.tfar == -INFINITY;
+ }
# endif
# ifdef __OBJECT_MOTION__
- if(kernel_data.bvh.have_motion) {
+ if (kernel_data.bvh.have_motion) {
# ifdef __HAIR__
- if(kernel_data.bvh.have_curves) {
- return bvh_intersect_shadow_all_hair_motion(kg,
- ray,
- isect,
- visibility,
- max_hits,
- num_hits);
- }
-# endif /* __HAIR__ */
-
- return bvh_intersect_shadow_all_motion(kg,
- ray,
- isect,
- visibility,
- max_hits,
- num_hits);
- }
-# endif /* __OBJECT_MOTION__ */
+ if (kernel_data.bvh.have_curves) {
+ return bvh_intersect_shadow_all_hair_motion(kg, ray, isect, visibility, max_hits, num_hits);
+ }
+# endif /* __HAIR__ */
+
+ return bvh_intersect_shadow_all_motion(kg, ray, isect, visibility, max_hits, num_hits);
+ }
+# endif /* __OBJECT_MOTION__ */
# ifdef __HAIR__
- if(kernel_data.bvh.have_curves) {
- return bvh_intersect_shadow_all_hair(kg,
- ray,
- isect,
- visibility,
- max_hits,
- num_hits);
- }
-# endif /* __HAIR__ */
+ if (kernel_data.bvh.have_curves) {
+ return bvh_intersect_shadow_all_hair(kg, ray, isect, visibility, max_hits, num_hits);
+ }
+# endif /* __HAIR__ */
# ifdef __INSTANCING__
- if(kernel_data.bvh.have_instancing) {
- return bvh_intersect_shadow_all_instancing(kg,
- ray,
- isect,
- visibility,
- max_hits,
- num_hits);
- }
-# endif /* __INSTANCING__ */
-
- return bvh_intersect_shadow_all(kg,
- ray,
- isect,
- visibility,
- max_hits,
- num_hits);
+ if (kernel_data.bvh.have_instancing) {
+ return bvh_intersect_shadow_all_instancing(kg, ray, isect, visibility, max_hits, num_hits);
+ }
+# endif /* __INSTANCING__ */
+
+ return bvh_intersect_shadow_all(kg, ray, isect, visibility, max_hits, num_hits);
}
-#endif /* __SHADOW_RECORD_ALL__ */
+#endif /* __SHADOW_RECORD_ALL__ */
#ifdef __VOLUME__
ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg,
@@ -415,31 +375,31 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg,
Intersection *isect,
const uint visibility)
{
- PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME);
+ PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME);
- if(!scene_intersect_valid(ray)) {
- return false;
- }
+ if (!scene_intersect_valid(ray)) {
+ return false;
+ }
# ifdef __OBJECT_MOTION__
- if(kernel_data.bvh.have_motion) {
- return bvh_intersect_volume_motion(kg, ray, isect, visibility);
- }
-# endif /* __OBJECT_MOTION__ */
+ if (kernel_data.bvh.have_motion) {
+ return bvh_intersect_volume_motion(kg, ray, isect, visibility);
+ }
+# endif /* __OBJECT_MOTION__ */
# ifdef __KERNEL_CPU__
# ifdef __INSTANCING__
- if(kernel_data.bvh.have_instancing)
- return bvh_intersect_volume_instancing(kg, ray, isect, visibility);
-# endif /* __INSTANCING__ */
- return bvh_intersect_volume(kg, ray, isect, visibility);
-# else /* __KERNEL_CPU__ */
+ if (kernel_data.bvh.have_instancing)
+ return bvh_intersect_volume_instancing(kg, ray, isect, visibility);
+# endif /* __INSTANCING__ */
+ return bvh_intersect_volume(kg, ray, isect, visibility);
+# else /* __KERNEL_CPU__ */
# ifdef __INSTANCING__
- return bvh_intersect_volume_instancing(kg, ray, isect, visibility);
+ return bvh_intersect_volume_instancing(kg, ray, isect, visibility);
# else
- return bvh_intersect_volume(kg, ray, isect, visibility);
-# endif /* __INSTANCING__ */
-# endif /* __KERNEL_CPU__ */
+ return bvh_intersect_volume(kg, ray, isect, visibility);
+# endif /* __INSTANCING__ */
+# endif /* __KERNEL_CPU__ */
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
#ifdef __VOLUME_RECORD_ALL__
ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
@@ -448,37 +408,36 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
const uint max_hits,
const uint visibility)
{
- PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME_ALL);
+ PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME_ALL);
- if(!scene_intersect_valid(ray)) {
- return false;
- }
+ if (!scene_intersect_valid(ray)) {
+ return false;
+ }
# ifdef __EMBREE__
- if(kernel_data.bvh.scene) {
- CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL);
- ctx.isect_s = isect;
- ctx.max_hits = max_hits;
- ctx.num_hits = 0;
- IntersectContext rtc_ctx(&ctx);
- RTCRay rtc_ray;
- kernel_embree_setup_ray(*ray, rtc_ray, visibility);
- rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
- return rtc_ray.tfar == -INFINITY;
- }
+ if (kernel_data.bvh.scene) {
+ CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL);
+ ctx.isect_s = isect;
+ ctx.max_hits = max_hits;
+ ctx.num_hits = 0;
+ IntersectContext rtc_ctx(&ctx);
+ RTCRay rtc_ray;
+ kernel_embree_setup_ray(*ray, rtc_ray, visibility);
+ rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
+ return rtc_ray.tfar == -INFINITY;
+ }
# endif
# ifdef __OBJECT_MOTION__
- if(kernel_data.bvh.have_motion) {
- return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility);
- }
-# endif /* __OBJECT_MOTION__ */
+ if (kernel_data.bvh.have_motion) {
+ return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility);
+ }
+# endif /* __OBJECT_MOTION__ */
# ifdef __INSTANCING__
- if(kernel_data.bvh.have_instancing)
- return bvh_intersect_volume_all_instancing(kg, ray, isect, max_hits, visibility);
-# endif /* __INSTANCING__ */
- return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility);
+ if (kernel_data.bvh.have_instancing)
+ return bvh_intersect_volume_all_instancing(kg, ray, isect, max_hits, visibility);
+# endif /* __INSTANCING__ */
+ return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility);
}
-#endif /* __VOLUME_RECORD_ALL__ */
-
+#endif /* __VOLUME_RECORD_ALL__ */
/* Ray offset to avoid self intersection.
*
@@ -488,48 +447,48 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
{
#ifdef __INTERSECTION_REFINE__
- const float epsilon_f = 1e-5f;
- /* ideally this should match epsilon_f, but instancing and motion blur
- * precision makes it problematic */
- const float epsilon_test = 1.0f;
- const int epsilon_i = 32;
-
- float3 res;
-
- /* x component */
- if(fabsf(P.x) < epsilon_test) {
- res.x = P.x + Ng.x*epsilon_f;
- }
- else {
- uint ix = __float_as_uint(P.x);
- ix += ((ix ^ __float_as_uint(Ng.x)) >> 31)? -epsilon_i: epsilon_i;
- res.x = __uint_as_float(ix);
- }
-
- /* y component */
- if(fabsf(P.y) < epsilon_test) {
- res.y = P.y + Ng.y*epsilon_f;
- }
- else {
- uint iy = __float_as_uint(P.y);
- iy += ((iy ^ __float_as_uint(Ng.y)) >> 31)? -epsilon_i: epsilon_i;
- res.y = __uint_as_float(iy);
- }
-
- /* z component */
- if(fabsf(P.z) < epsilon_test) {
- res.z = P.z + Ng.z*epsilon_f;
- }
- else {
- uint iz = __float_as_uint(P.z);
- iz += ((iz ^ __float_as_uint(Ng.z)) >> 31)? -epsilon_i: epsilon_i;
- res.z = __uint_as_float(iz);
- }
-
- return res;
+ const float epsilon_f = 1e-5f;
+ /* ideally this should match epsilon_f, but instancing and motion blur
+ * precision makes it problematic */
+ const float epsilon_test = 1.0f;
+ const int epsilon_i = 32;
+
+ float3 res;
+
+ /* x component */
+ if (fabsf(P.x) < epsilon_test) {
+ res.x = P.x + Ng.x * epsilon_f;
+ }
+ else {
+ uint ix = __float_as_uint(P.x);
+ ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
+ res.x = __uint_as_float(ix);
+ }
+
+ /* y component */
+ if (fabsf(P.y) < epsilon_test) {
+ res.y = P.y + Ng.y * epsilon_f;
+ }
+ else {
+ uint iy = __float_as_uint(P.y);
+ iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
+ res.y = __uint_as_float(iy);
+ }
+
+ /* z component */
+ if (fabsf(P.z) < epsilon_test) {
+ res.z = P.z + Ng.z * epsilon_f;
+ }
+ else {
+ uint iz = __float_as_uint(P.z);
+ iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
+ res.z = __uint_as_float(iz);
+ }
+
+ return res;
#else
- const float epsilon_f = 1e-4f;
- return P + epsilon_f*Ng;
+ const float epsilon_f = 1e-4f;
+ return P + epsilon_f * Ng;
#endif
}
@@ -537,40 +496,40 @@ ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
/* ToDo: Move to another file? */
ccl_device int intersections_compare(const void *a, const void *b)
{
- const Intersection *isect_a = (const Intersection*)a;
- const Intersection *isect_b = (const Intersection*)b;
-
- if(isect_a->t < isect_b->t)
- return -1;
- else if(isect_a->t > isect_b->t)
- return 1;
- else
- return 0;
+ const Intersection *isect_a = (const Intersection *)a;
+ const Intersection *isect_b = (const Intersection *)b;
+
+ if (isect_a->t < isect_b->t)
+ return -1;
+ else if (isect_a->t > isect_b->t)
+ return 1;
+ else
+ return 0;
}
#endif
#if defined(__SHADOW_RECORD_ALL__)
ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
{
-#ifdef __KERNEL_GPU__
- /* Use bubble sort which has more friendly memory pattern on GPU. */
- bool swapped;
- do {
- swapped = false;
- for(int j = 0; j < num_hits - 1; ++j) {
- if(hits[j].t > hits[j + 1].t) {
- struct Intersection tmp = hits[j];
- hits[j] = hits[j + 1];
- hits[j + 1] = tmp;
- swapped = true;
- }
- }
- --num_hits;
- } while(swapped);
-#else
- qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
-#endif
+# ifdef __KERNEL_GPU__
+ /* Use bubble sort which has more friendly memory pattern on GPU. */
+ bool swapped;
+ do {
+ swapped = false;
+ for (int j = 0; j < num_hits - 1; ++j) {
+ if (hits[j].t > hits[j + 1].t) {
+ struct Intersection tmp = hits[j];
+ hits[j] = hits[j + 1];
+ hits[j + 1] = tmp;
+ swapped = true;
+ }
+ }
+ --num_hits;
+ } while (swapped);
+# else
+ qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
+# endif
}
-#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
+#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/bvh/bvh_embree.h b/intern/cycles/kernel/bvh/bvh_embree.h
index bfc911a1e76..661bba54fd4 100644
--- a/intern/cycles/kernel/bvh/bvh_embree.h
+++ b/intern/cycles/kernel/bvh/bvh_embree.h
@@ -24,103 +24,120 @@
CCL_NAMESPACE_BEGIN
-struct CCLIntersectContext {
- typedef enum {
- RAY_REGULAR = 0,
- RAY_SHADOW_ALL = 1,
- RAY_SSS = 2,
- RAY_VOLUME_ALL = 3,
+struct CCLIntersectContext {
+ typedef enum {
+ RAY_REGULAR = 0,
+ RAY_SHADOW_ALL = 1,
+ RAY_SSS = 2,
+ RAY_VOLUME_ALL = 3,
- } RayType;
+ } RayType;
- KernelGlobals *kg;
- RayType type;
+ KernelGlobals *kg;
+ RayType type;
- /* for shadow rays */
- Intersection *isect_s;
- int max_hits;
- int num_hits;
+ /* for shadow rays */
+ Intersection *isect_s;
+ int max_hits;
+ int num_hits;
- /* for SSS Rays: */
- LocalIntersection *ss_isect;
- int sss_object_id;
- uint *lcg_state;
+ /* for SSS Rays: */
+ LocalIntersection *ss_isect;
+ int sss_object_id;
+ uint *lcg_state;
- CCLIntersectContext(KernelGlobals *kg_, RayType type_)
- {
- kg = kg_;
- type = type_;
- max_hits = 1;
- num_hits = 0;
- isect_s = NULL;
- ss_isect = NULL;
- sss_object_id = -1;
- lcg_state = NULL;
- }
+ CCLIntersectContext(KernelGlobals *kg_, RayType type_)
+ {
+ kg = kg_;
+ type = type_;
+ max_hits = 1;
+ num_hits = 0;
+ isect_s = NULL;
+ ss_isect = NULL;
+ sss_object_id = -1;
+ lcg_state = NULL;
+ }
};
-class IntersectContext
-{
-public:
- IntersectContext(CCLIntersectContext* ctx)
- {
- rtcInitIntersectContext(&context);
- userRayExt = ctx;
- }
- RTCIntersectContext context;
- CCLIntersectContext* userRayExt;
+class IntersectContext {
+ public:
+ IntersectContext(CCLIntersectContext *ctx)
+ {
+ rtcInitIntersectContext(&context);
+ userRayExt = ctx;
+ }
+ RTCIntersectContext context;
+ CCLIntersectContext *userRayExt;
};
-ccl_device_inline void kernel_embree_setup_ray(const Ray& ray, RTCRay& rtc_ray, const uint visibility)
+ccl_device_inline void kernel_embree_setup_ray(const Ray &ray,
+ RTCRay &rtc_ray,
+ const uint visibility)
{
- rtc_ray.org_x = ray.P.x;
- rtc_ray.org_y = ray.P.y;
- rtc_ray.org_z = ray.P.z;
- rtc_ray.dir_x = ray.D.x;
- rtc_ray.dir_y = ray.D.y;
- rtc_ray.dir_z = ray.D.z;
- rtc_ray.tnear = 0.0f;
- rtc_ray.tfar = ray.t;
- rtc_ray.time = ray.time;
- rtc_ray.mask = visibility;
+ rtc_ray.org_x = ray.P.x;
+ rtc_ray.org_y = ray.P.y;
+ rtc_ray.org_z = ray.P.z;
+ rtc_ray.dir_x = ray.D.x;
+ rtc_ray.dir_y = ray.D.y;
+ rtc_ray.dir_z = ray.D.z;
+ rtc_ray.tnear = 0.0f;
+ rtc_ray.tfar = ray.t;
+ rtc_ray.time = ray.time;
+ rtc_ray.mask = visibility;
}
-ccl_device_inline void kernel_embree_setup_rayhit(const Ray& ray, RTCRayHit& rayhit, const uint visibility)
+ccl_device_inline void kernel_embree_setup_rayhit(const Ray &ray,
+ RTCRayHit &rayhit,
+ const uint visibility)
{
- kernel_embree_setup_ray(ray, rayhit.ray, visibility);
- rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
- rayhit.hit.primID = RTC_INVALID_GEOMETRY_ID;
+ kernel_embree_setup_ray(ray, rayhit.ray, visibility);
+ rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
+ rayhit.hit.primID = RTC_INVALID_GEOMETRY_ID;
}
-ccl_device_inline void kernel_embree_convert_hit(KernelGlobals *kg, const RTCRay *ray, const RTCHit *hit, Intersection *isect)
+ccl_device_inline void kernel_embree_convert_hit(KernelGlobals *kg,
+ const RTCRay *ray,
+ const RTCHit *hit,
+ Intersection *isect)
{
- bool is_hair = hit->geomID & 1;
- isect->u = is_hair ? hit->u : 1.0f - hit->v - hit->u;
- isect->v = is_hair ? hit->v : hit->u;
- isect->t = ray->tfar;
- isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z);
- if(hit->instID[0] != RTC_INVALID_GEOMETRY_ID) {
- RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(rtcGetGeometry(kernel_data.bvh.scene, hit->instID[0]));
- isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)) + kernel_tex_fetch(__object_node, hit->instID[0]/2);
- isect->object = hit->instID[0]/2;
- }
- else {
- isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(kernel_data.bvh.scene, hit->geomID));
- isect->object = OBJECT_NONE;
- }
- isect->type = kernel_tex_fetch(__prim_type, isect->prim);
+ bool is_hair = hit->geomID & 1;
+ isect->u = is_hair ? hit->u : 1.0f - hit->v - hit->u;
+ isect->v = is_hair ? hit->v : hit->u;
+ isect->t = ray->tfar;
+ isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z);
+ if (hit->instID[0] != RTC_INVALID_GEOMETRY_ID) {
+ RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(
+ rtcGetGeometry(kernel_data.bvh.scene, hit->instID[0]));
+ isect->prim = hit->primID +
+ (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)) +
+ kernel_tex_fetch(__object_node, hit->instID[0] / 2);
+ isect->object = hit->instID[0] / 2;
+ }
+ else {
+ isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(
+ rtcGetGeometry(kernel_data.bvh.scene, hit->geomID));
+ isect->object = OBJECT_NONE;
+ }
+ isect->type = kernel_tex_fetch(__prim_type, isect->prim);
}
-ccl_device_inline void kernel_embree_convert_local_hit(KernelGlobals *kg, const RTCRay *ray, const RTCHit *hit, Intersection *isect, int local_object_id)
+ccl_device_inline void kernel_embree_convert_local_hit(KernelGlobals *kg,
+ const RTCRay *ray,
+ const RTCHit *hit,
+ Intersection *isect,
+ int local_object_id)
{
- isect->u = 1.0f - hit->v - hit->u;
- isect->v = hit->u;
- isect->t = ray->tfar;
- isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z);
- RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(rtcGetGeometry(kernel_data.bvh.scene, local_object_id * 2));
- isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)) + kernel_tex_fetch(__object_node, local_object_id);
- isect->object = local_object_id;
- isect->type = kernel_tex_fetch(__prim_type, isect->prim);
+ isect->u = 1.0f - hit->v - hit->u;
+ isect->v = hit->u;
+ isect->t = ray->tfar;
+ isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z);
+ RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(
+ rtcGetGeometry(kernel_data.bvh.scene, local_object_id * 2));
+ isect->prim = hit->primID +
+ (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)) +
+ kernel_tex_fetch(__object_node, local_object_id);
+ isect->object = local_object_id;
+ isect->type = kernel_tex_fetch(__prim_type, isect->prim);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/bvh/bvh_local.h b/intern/cycles/kernel/bvh/bvh_local.h
index 3bdc9293a6c..7a069ef1108 100644
--- a/intern/cycles/kernel/bvh/bvh_local.h
+++ b/intern/cycles/kernel/bvh/bvh_local.h
@@ -43,208 +43,201 @@ ccl_device
#else
ccl_device_inline
#endif
-bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
- const Ray *ray,
- LocalIntersection *local_isect,
- int local_object,
- uint *lcg_state,
- int max_hits)
+ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ LocalIntersection *local_isect,
+ int local_object,
+ uint *lcg_state,
+ int max_hits)
{
- /* todo:
- * - test if pushing distance on the stack helps (for non shadow rays)
- * - separate version for shadow rays
- * - likely and unlikely for if() statements
- * - test restrict attribute for pointers
- */
+ /* todo:
+ * - test if pushing distance on the stack helps (for non shadow rays)
+ * - separate version for shadow rays
+ * - likely and unlikely for if() statements
+ * - test restrict attribute for pointers
+ */
- /* traversal stack in CUDA thread-local memory */
- int traversal_stack[BVH_STACK_SIZE];
- traversal_stack[0] = ENTRYPOINT_SENTINEL;
+ /* traversal stack in CUDA thread-local memory */
+ int traversal_stack[BVH_STACK_SIZE];
+ traversal_stack[0] = ENTRYPOINT_SENTINEL;
- /* traversal variables in registers */
- int stack_ptr = 0;
- int node_addr = kernel_tex_fetch(__object_node, local_object);
+ /* traversal variables in registers */
+ int stack_ptr = 0;
+ int node_addr = kernel_tex_fetch(__object_node, local_object);
- /* ray parameters in registers */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = ray->t;
+ /* ray parameters in registers */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = ray->t;
- if(local_isect != NULL) {
- local_isect->num_hits = 0;
- }
- kernel_assert((local_isect == NULL) == (max_hits == 0));
+ if (local_isect != NULL) {
+ local_isect->num_hits = 0;
+ }
+ kernel_assert((local_isect == NULL) == (max_hits == 0));
- const int object_flag = kernel_tex_fetch(__object_flag, local_object);
- if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ const int object_flag = kernel_tex_fetch(__object_flag, local_object);
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
- isect_t = bvh_instance_motion_push(kg,
- local_object,
- ray,
- &P,
- &dir,
- &idir,
- isect_t,
- &ob_itfm);
+ Transform ob_itfm;
+ isect_t = bvh_instance_motion_push(kg, local_object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
#else
- isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
#endif
- object = local_object;
- }
+ object = local_object;
+ }
#if defined(__KERNEL_SSE2__)
- const shuffle_swap_t shuf_identity = shuffle_swap_identity();
- const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
- const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
- ssef Psplat[3], idirsplat[3];
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+ ssef Psplat[3], idirsplat[3];
# if BVH_FEATURE(BVH_HAIR)
- ssef tnear(0.0f), tfar(isect_t);
+ ssef tnear(0.0f), tfar(isect_t);
# endif
- shuffle_swap_t shufflexyz[3];
+ shuffle_swap_t shufflexyz[3];
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- ssef tsplat(0.0f, 0.0f, -isect_t, -isect_t);
+ ssef tsplat(0.0f, 0.0f, -isect_t, -isect_t);
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
- /* traversal loop */
- do {
- do {
- /* traverse internal nodes */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- int node_addr_child1, traverse_mask;
- float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* traversal loop */
+ do {
+ do {
+ /* traverse internal nodes */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ int node_addr_child1, traverse_mask;
+ float dist[2];
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#if !defined(__KERNEL_SSE2__)
- traverse_mask = NODE_INTERSECT(kg,
- P,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
# if BVH_FEATURE(BVH_HAIR)
- dir,
+ dir,
# endif
- idir,
- isect_t,
- node_addr,
- PATH_RAY_ALL_VISIBILITY,
- dist);
+ idir,
+ isect_t,
+ node_addr,
+ PATH_RAY_ALL_VISIBILITY,
+ dist);
#else // __KERNEL_SSE2__
- traverse_mask = NODE_INTERSECT(kg,
- P,
- dir,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
+ dir,
# if BVH_FEATURE(BVH_HAIR)
- tnear,
- tfar,
+ tnear,
+ tfar,
# endif
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- node_addr,
- PATH_RAY_ALL_VISIBILITY,
- dist);
+ tsplat,
+ Psplat,
+ idirsplat,
+ shufflexyz,
+ node_addr,
+ PATH_RAY_ALL_VISIBILITY,
+ dist);
#endif // __KERNEL_SSE2__
- node_addr = __float_as_int(cnodes.z);
- node_addr_child1 = __float_as_int(cnodes.w);
+ node_addr = __float_as_int(cnodes.z);
+ node_addr_child1 = __float_as_int(cnodes.w);
- if(traverse_mask == 3) {
- /* Both children were intersected, push the farther one. */
- bool is_closest_child1 = (dist[1] < dist[0]);
- if(is_closest_child1) {
- int tmp = node_addr;
- node_addr = node_addr_child1;
- node_addr_child1 = tmp;
- }
+ if (traverse_mask == 3) {
+ /* Both children were intersected, push the farther one. */
+ bool is_closest_child1 = (dist[1] < dist[0]);
+ if (is_closest_child1) {
+ int tmp = node_addr;
+ node_addr = node_addr_child1;
+ node_addr_child1 = tmp;
+ }
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = node_addr_child1;
- }
- else {
- /* One child was intersected. */
- if(traverse_mask == 2) {
- node_addr = node_addr_child1;
- }
- else if(traverse_mask == 0) {
- /* Neither child was intersected. */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
- }
- }
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = node_addr_child1;
+ }
+ else {
+ /* One child was intersected. */
+ if (traverse_mask == 2) {
+ node_addr = node_addr_child1;
+ }
+ else if (traverse_mask == 0) {
+ /* Neither child was intersected. */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+ }
+ }
- /* if node is leaf, fetch triangle list */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
- int prim_addr = __float_as_int(leaf.x);
+ /* if node is leaf, fetch triangle list */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ int prim_addr = __float_as_int(leaf.x);
- const int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
+ const int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
- /* pop */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
+ /* pop */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
- /* primitive intersection */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- /* intersect ray against primitive */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits)) {
- return true;
- }
- }
- break;
- }
+ /* primitive intersection */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* intersect ray against primitive */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- /* intersect ray against primitive */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(motion_triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- ray->time,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits)) {
- return true;
- }
- }
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* intersect ray against primitive */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (motion_triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ ray->time,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
+ }
+ break;
+ }
#endif
- default: {
- break;
- }
- }
- }
- } while(node_addr != ENTRYPOINT_SENTINEL);
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ default: {
+ break;
+ }
+ }
+ }
+ } while (node_addr != ENTRYPOINT_SENTINEL);
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return false;
+ return false;
}
ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
@@ -254,35 +247,20 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
uint *lcg_state,
int max_hits)
{
- switch(kernel_data.bvh.bvh_layout) {
+ switch (kernel_data.bvh.bvh_layout) {
#ifdef __KERNEL_AVX2__
- case BVH_LAYOUT_BVH8:
- return BVH_FUNCTION_FULL_NAME(OBVH)(kg,
- ray,
- local_isect,
- local_object,
- lcg_state,
- max_hits);
+ case BVH_LAYOUT_BVH8:
+ return BVH_FUNCTION_FULL_NAME(OBVH)(kg, ray, local_isect, local_object, lcg_state, max_hits);
#endif
#ifdef __QBVH__
- case BVH_LAYOUT_BVH4:
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- local_isect,
- local_object,
- lcg_state,
- max_hits);
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg, ray, local_isect, local_object, lcg_state, max_hits);
#endif
- case BVH_LAYOUT_BVH2:
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- local_isect,
- local_object,
- lcg_state,
- max_hits);
- }
- kernel_assert(!"Should not happen");
- return false;
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg, ray, local_isect, local_object, lcg_state, max_hits);
+ }
+ kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_nodes.h b/intern/cycles/kernel/bvh/bvh_nodes.h
index 060b3934a41..042630121c8 100644
--- a/intern/cycles/kernel/bvh/bvh_nodes.h
+++ b/intern/cycles/kernel/bvh/bvh_nodes.h
@@ -20,12 +20,12 @@ ccl_device_forceinline Transform bvh_unaligned_node_fetch_space(KernelGlobals *k
int node_addr,
int child)
{
- Transform space;
- const int child_addr = node_addr + child * 3;
- space.x = kernel_tex_fetch(__bvh_nodes, child_addr+1);
- space.y = kernel_tex_fetch(__bvh_nodes, child_addr+2);
- space.z = kernel_tex_fetch(__bvh_nodes, child_addr+3);
- return space;
+ Transform space;
+ const int child_addr = node_addr + child * 3;
+ space.x = kernel_tex_fetch(__bvh_nodes, child_addr + 1);
+ space.y = kernel_tex_fetch(__bvh_nodes, child_addr + 2);
+ space.z = kernel_tex_fetch(__bvh_nodes, child_addr + 3);
+ return space;
}
#if !defined(__KERNEL_SSE2__)
@@ -38,42 +38,41 @@ ccl_device_forceinline int bvh_aligned_node_intersect(KernelGlobals *kg,
float dist[2])
{
- /* fetch node data */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- float4 node0 = kernel_tex_fetch(__bvh_nodes, node_addr+1);
- float4 node1 = kernel_tex_fetch(__bvh_nodes, node_addr+2);
- float4 node2 = kernel_tex_fetch(__bvh_nodes, node_addr+3);
-
- /* intersect ray against child nodes */
- float c0lox = (node0.x - P.x) * idir.x;
- float c0hix = (node0.z - P.x) * idir.x;
- float c0loy = (node1.x - P.y) * idir.y;
- float c0hiy = (node1.z - P.y) * idir.y;
- float c0loz = (node2.x - P.z) * idir.z;
- float c0hiz = (node2.z - P.z) * idir.z;
- float c0min = max4(0.0f, min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz));
- float c0max = min4(t, max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz));
-
- float c1lox = (node0.y - P.x) * idir.x;
- float c1hix = (node0.w - P.x) * idir.x;
- float c1loy = (node1.y - P.y) * idir.y;
- float c1hiy = (node1.w - P.y) * idir.y;
- float c1loz = (node2.y - P.z) * idir.z;
- float c1hiz = (node2.w - P.z) * idir.z;
- float c1min = max4(0.0f, min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz));
- float c1max = min4(t, max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz));
-
- dist[0] = c0min;
- dist[1] = c1min;
-
-#ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- return (((c0max >= c0min) && (__float_as_uint(cnodes.x) & visibility))? 1: 0) |
- (((c1max >= c1min) && (__float_as_uint(cnodes.y) & visibility))? 2: 0);
-#else
- return ((c0max >= c0min)? 1: 0) |
- ((c1max >= c1min)? 2: 0);
-#endif
+ /* fetch node data */
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 node0 = kernel_tex_fetch(__bvh_nodes, node_addr + 1);
+ float4 node1 = kernel_tex_fetch(__bvh_nodes, node_addr + 2);
+ float4 node2 = kernel_tex_fetch(__bvh_nodes, node_addr + 3);
+
+ /* intersect ray against child nodes */
+ float c0lox = (node0.x - P.x) * idir.x;
+ float c0hix = (node0.z - P.x) * idir.x;
+ float c0loy = (node1.x - P.y) * idir.y;
+ float c0hiy = (node1.z - P.y) * idir.y;
+ float c0loz = (node2.x - P.z) * idir.z;
+ float c0hiz = (node2.z - P.z) * idir.z;
+ float c0min = max4(0.0f, min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz));
+ float c0max = min4(t, max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz));
+
+ float c1lox = (node0.y - P.x) * idir.x;
+ float c1hix = (node0.w - P.x) * idir.x;
+ float c1loy = (node1.y - P.y) * idir.y;
+ float c1hiy = (node1.w - P.y) * idir.y;
+ float c1loz = (node2.y - P.z) * idir.z;
+ float c1hiz = (node2.w - P.z) * idir.z;
+ float c1min = max4(0.0f, min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz));
+ float c1max = min4(t, max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz));
+
+ dist[0] = c0min;
+ dist[1] = c1min;
+
+# ifdef __VISIBILITY_FLAG__
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ return (((c0max >= c0min) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
+ (((c1max >= c1min) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
+# else
+ return ((c0max >= c0min) ? 1 : 0) | ((c1max >= c1min) ? 2 : 0);
+# endif
}
ccl_device_forceinline int bvh_aligned_node_intersect_robust(KernelGlobals *kg,
@@ -87,118 +86,115 @@ ccl_device_forceinline int bvh_aligned_node_intersect_robust(KernelGlobals *kg,
float dist[2])
{
- /* fetch node data */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- float4 node0 = kernel_tex_fetch(__bvh_nodes, node_addr+1);
- float4 node1 = kernel_tex_fetch(__bvh_nodes, node_addr+2);
- float4 node2 = kernel_tex_fetch(__bvh_nodes, node_addr+3);
-
- /* intersect ray against child nodes */
- float c0lox = (node0.x - P.x) * idir.x;
- float c0hix = (node0.z - P.x) * idir.x;
- float c0loy = (node1.x - P.y) * idir.y;
- float c0hiy = (node1.z - P.y) * idir.y;
- float c0loz = (node2.x - P.z) * idir.z;
- float c0hiz = (node2.z - P.z) * idir.z;
- float c0min = max4(0.0f, min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz));
- float c0max = min4(t, max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz));
-
- float c1lox = (node0.y - P.x) * idir.x;
- float c1hix = (node0.w - P.x) * idir.x;
- float c1loy = (node1.y - P.y) * idir.y;
- float c1hiy = (node1.w - P.y) * idir.y;
- float c1loz = (node2.y - P.z) * idir.z;
- float c1hiz = (node2.w - P.z) * idir.z;
- float c1min = max4(0.0f, min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz));
- float c1max = min4(t, max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz));
-
- if(difl != 0.0f) {
- float hdiff = 1.0f + difl;
- float ldiff = 1.0f - difl;
- if(__float_as_int(cnodes.z) & PATH_RAY_CURVE) {
- c0min = max(ldiff * c0min, c0min - extmax);
- c0max = min(hdiff * c0max, c0max + extmax);
- }
- if(__float_as_int(cnodes.w) & PATH_RAY_CURVE) {
- c1min = max(ldiff * c1min, c1min - extmax);
- c1max = min(hdiff * c1max, c1max + extmax);
- }
- }
-
- dist[0] = c0min;
- dist[1] = c1min;
-
-#ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- return (((c0max >= c0min) && (__float_as_uint(cnodes.x) & visibility))? 1: 0) |
- (((c1max >= c1min) && (__float_as_uint(cnodes.y) & visibility))? 2: 0);
-#else
- return ((c0max >= c0min)? 1: 0) |
- ((c1max >= c1min)? 2: 0);
-#endif
+ /* fetch node data */
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 node0 = kernel_tex_fetch(__bvh_nodes, node_addr + 1);
+ float4 node1 = kernel_tex_fetch(__bvh_nodes, node_addr + 2);
+ float4 node2 = kernel_tex_fetch(__bvh_nodes, node_addr + 3);
+
+ /* intersect ray against child nodes */
+ float c0lox = (node0.x - P.x) * idir.x;
+ float c0hix = (node0.z - P.x) * idir.x;
+ float c0loy = (node1.x - P.y) * idir.y;
+ float c0hiy = (node1.z - P.y) * idir.y;
+ float c0loz = (node2.x - P.z) * idir.z;
+ float c0hiz = (node2.z - P.z) * idir.z;
+ float c0min = max4(0.0f, min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz));
+ float c0max = min4(t, max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz));
+
+ float c1lox = (node0.y - P.x) * idir.x;
+ float c1hix = (node0.w - P.x) * idir.x;
+ float c1loy = (node1.y - P.y) * idir.y;
+ float c1hiy = (node1.w - P.y) * idir.y;
+ float c1loz = (node2.y - P.z) * idir.z;
+ float c1hiz = (node2.w - P.z) * idir.z;
+ float c1min = max4(0.0f, min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz));
+ float c1max = min4(t, max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz));
+
+ if (difl != 0.0f) {
+ float hdiff = 1.0f + difl;
+ float ldiff = 1.0f - difl;
+ if (__float_as_int(cnodes.z) & PATH_RAY_CURVE) {
+ c0min = max(ldiff * c0min, c0min - extmax);
+ c0max = min(hdiff * c0max, c0max + extmax);
+ }
+ if (__float_as_int(cnodes.w) & PATH_RAY_CURVE) {
+ c1min = max(ldiff * c1min, c1min - extmax);
+ c1max = min(hdiff * c1max, c1max + extmax);
+ }
+ }
+
+ dist[0] = c0min;
+ dist[1] = c1min;
+
+# ifdef __VISIBILITY_FLAG__
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ return (((c0max >= c0min) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
+ (((c1max >= c1min) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
+# else
+ return ((c0max >= c0min) ? 1 : 0) | ((c1max >= c1min) ? 2 : 0);
+# endif
}
-ccl_device_forceinline bool bvh_unaligned_node_intersect_child(
- KernelGlobals *kg,
- const float3 P,
- const float3 dir,
- const float t,
- int node_addr,
- int child,
- float dist[2])
+ccl_device_forceinline bool bvh_unaligned_node_intersect_child(KernelGlobals *kg,
+ const float3 P,
+ const float3 dir,
+ const float t,
+ int node_addr,
+ int child,
+ float dist[2])
{
- Transform space = bvh_unaligned_node_fetch_space(kg, node_addr, child);
- float3 aligned_dir = transform_direction(&space, dir);
- float3 aligned_P = transform_point(&space, P);
- float3 nrdir = -bvh_inverse_direction(aligned_dir);
- float3 lower_xyz = aligned_P * nrdir;
- float3 upper_xyz = lower_xyz - nrdir;
- const float near_x = min(lower_xyz.x, upper_xyz.x);
- const float near_y = min(lower_xyz.y, upper_xyz.y);
- const float near_z = min(lower_xyz.z, upper_xyz.z);
- const float far_x = max(lower_xyz.x, upper_xyz.x);
- const float far_y = max(lower_xyz.y, upper_xyz.y);
- const float far_z = max(lower_xyz.z, upper_xyz.z);
- const float tnear = max4(0.0f, near_x, near_y, near_z);
- const float tfar = min4(t, far_x, far_y, far_z);
- *dist = tnear;
- return tnear <= tfar;
+ Transform space = bvh_unaligned_node_fetch_space(kg, node_addr, child);
+ float3 aligned_dir = transform_direction(&space, dir);
+ float3 aligned_P = transform_point(&space, P);
+ float3 nrdir = -bvh_inverse_direction(aligned_dir);
+ float3 lower_xyz = aligned_P * nrdir;
+ float3 upper_xyz = lower_xyz - nrdir;
+ const float near_x = min(lower_xyz.x, upper_xyz.x);
+ const float near_y = min(lower_xyz.y, upper_xyz.y);
+ const float near_z = min(lower_xyz.z, upper_xyz.z);
+ const float far_x = max(lower_xyz.x, upper_xyz.x);
+ const float far_y = max(lower_xyz.y, upper_xyz.y);
+ const float far_z = max(lower_xyz.z, upper_xyz.z);
+ const float tnear = max4(0.0f, near_x, near_y, near_z);
+ const float tfar = min4(t, far_x, far_y, far_z);
+ *dist = tnear;
+ return tnear <= tfar;
}
-ccl_device_forceinline bool bvh_unaligned_node_intersect_child_robust(
- KernelGlobals *kg,
- const float3 P,
- const float3 dir,
- const float t,
- const float difl,
- int node_addr,
- int child,
- float dist[2])
+ccl_device_forceinline bool bvh_unaligned_node_intersect_child_robust(KernelGlobals *kg,
+ const float3 P,
+ const float3 dir,
+ const float t,
+ const float difl,
+ int node_addr,
+ int child,
+ float dist[2])
{
- Transform space = bvh_unaligned_node_fetch_space(kg, node_addr, child);
- float3 aligned_dir = transform_direction(&space, dir);
- float3 aligned_P = transform_point(&space, P);
- float3 nrdir = -bvh_inverse_direction(aligned_dir);
- float3 tLowerXYZ = aligned_P * nrdir;
- float3 tUpperXYZ = tLowerXYZ - nrdir;
- const float near_x = min(tLowerXYZ.x, tUpperXYZ.x);
- const float near_y = min(tLowerXYZ.y, tUpperXYZ.y);
- const float near_z = min(tLowerXYZ.z, tUpperXYZ.z);
- const float far_x = max(tLowerXYZ.x, tUpperXYZ.x);
- const float far_y = max(tLowerXYZ.y, tUpperXYZ.y);
- const float far_z = max(tLowerXYZ.z, tUpperXYZ.z);
- const float tnear = max4(0.0f, near_x, near_y, near_z);
- const float tfar = min4(t, far_x, far_y, far_z);
- *dist = tnear;
- if(difl != 0.0f) {
- /* TODO(sergey): Same as for QBVH, needs a proper use. */
- const float round_down = 1.0f - difl;
- const float round_up = 1.0f + difl;
- return round_down*tnear <= round_up*tfar;
- }
- else {
- return tnear <= tfar;
- }
+ Transform space = bvh_unaligned_node_fetch_space(kg, node_addr, child);
+ float3 aligned_dir = transform_direction(&space, dir);
+ float3 aligned_P = transform_point(&space, P);
+ float3 nrdir = -bvh_inverse_direction(aligned_dir);
+ float3 tLowerXYZ = aligned_P * nrdir;
+ float3 tUpperXYZ = tLowerXYZ - nrdir;
+ const float near_x = min(tLowerXYZ.x, tUpperXYZ.x);
+ const float near_y = min(tLowerXYZ.y, tUpperXYZ.y);
+ const float near_z = min(tLowerXYZ.z, tUpperXYZ.z);
+ const float far_x = max(tLowerXYZ.x, tUpperXYZ.x);
+ const float far_y = max(tLowerXYZ.y, tUpperXYZ.y);
+ const float far_z = max(tLowerXYZ.z, tUpperXYZ.z);
+ const float tnear = max4(0.0f, near_x, near_y, near_z);
+ const float tfar = min4(t, far_x, far_y, far_z);
+ *dist = tnear;
+ if (difl != 0.0f) {
+ /* TODO(sergey): Same as for QBVH, needs a proper use. */
+ const float round_down = 1.0f - difl;
+ const float round_up = 1.0f + difl;
+ return round_down * tnear <= round_up * tfar;
+ }
+ else {
+ return tnear <= tfar;
+ }
}
ccl_device_forceinline int bvh_unaligned_node_intersect(KernelGlobals *kg,
@@ -210,25 +206,25 @@ ccl_device_forceinline int bvh_unaligned_node_intersect(KernelGlobals *kg,
const uint visibility,
float dist[2])
{
- int mask = 0;
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- if(bvh_unaligned_node_intersect_child(kg, P, dir, t, node_addr, 0, &dist[0])) {
-#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(cnodes.x) & visibility))
-#endif
- {
- mask |= 1;
- }
- }
- if(bvh_unaligned_node_intersect_child(kg, P, dir, t, node_addr, 1, &dist[1])) {
-#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(cnodes.y) & visibility))
-#endif
- {
- mask |= 2;
- }
- }
- return mask;
+ int mask = 0;
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ if (bvh_unaligned_node_intersect_child(kg, P, dir, t, node_addr, 0, &dist[0])) {
+# ifdef __VISIBILITY_FLAG__
+ if ((__float_as_uint(cnodes.x) & visibility))
+# endif
+ {
+ mask |= 1;
+ }
+ }
+ if (bvh_unaligned_node_intersect_child(kg, P, dir, t, node_addr, 1, &dist[1])) {
+# ifdef __VISIBILITY_FLAG__
+ if ((__float_as_uint(cnodes.y) & visibility))
+# endif
+ {
+ mask |= 2;
+ }
+ }
+ return mask;
}
ccl_device_forceinline int bvh_unaligned_node_intersect_robust(KernelGlobals *kg,
@@ -242,25 +238,25 @@ ccl_device_forceinline int bvh_unaligned_node_intersect_robust(KernelGlobals *kg
const uint visibility,
float dist[2])
{
- int mask = 0;
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- if(bvh_unaligned_node_intersect_child_robust(kg, P, dir, t, difl, node_addr, 0, &dist[0])) {
-#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(cnodes.x) & visibility))
-#endif
- {
- mask |= 1;
- }
- }
- if(bvh_unaligned_node_intersect_child_robust(kg, P, dir, t, difl, node_addr, 1, &dist[1])) {
-#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(cnodes.y) & visibility))
-#endif
- {
- mask |= 2;
- }
- }
- return mask;
+ int mask = 0;
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ if (bvh_unaligned_node_intersect_child_robust(kg, P, dir, t, difl, node_addr, 0, &dist[0])) {
+# ifdef __VISIBILITY_FLAG__
+ if ((__float_as_uint(cnodes.x) & visibility))
+# endif
+ {
+ mask |= 1;
+ }
+ }
+ if (bvh_unaligned_node_intersect_child_robust(kg, P, dir, t, difl, node_addr, 1, &dist[1])) {
+# ifdef __VISIBILITY_FLAG__
+ if ((__float_as_uint(cnodes.y) & visibility))
+# endif
+ {
+ mask |= 2;
+ }
+ }
+ return mask;
}
ccl_device_forceinline int bvh_node_intersect(KernelGlobals *kg,
@@ -272,26 +268,13 @@ ccl_device_forceinline int bvh_node_intersect(KernelGlobals *kg,
const uint visibility,
float dist[2])
{
- float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return bvh_unaligned_node_intersect(kg,
- P,
- dir,
- idir,
- t,
- node_addr,
- visibility,
- dist);
- }
- else {
- return bvh_aligned_node_intersect(kg,
- P,
- idir,
- t,
- node_addr,
- visibility,
- dist);
- }
+ float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return bvh_unaligned_node_intersect(kg, P, dir, idir, t, node_addr, visibility, dist);
+ }
+ else {
+ return bvh_aligned_node_intersect(kg, P, idir, t, node_addr, visibility, dist);
+ }
}
ccl_device_forceinline int bvh_node_intersect_robust(KernelGlobals *kg,
@@ -305,279 +288,244 @@ ccl_device_forceinline int bvh_node_intersect_robust(KernelGlobals *kg,
const uint visibility,
float dist[2])
{
- float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return bvh_unaligned_node_intersect_robust(kg,
- P,
- dir,
- idir,
- t,
- difl,
- extmax,
- node_addr,
- visibility,
- dist);
- }
- else {
- return bvh_aligned_node_intersect_robust(kg,
- P,
- idir,
- t,
- difl,
- extmax,
- node_addr,
- visibility,
- dist);
- }
+ float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return bvh_unaligned_node_intersect_robust(
+ kg, P, dir, idir, t, difl, extmax, node_addr, visibility, dist);
+ }
+ else {
+ return bvh_aligned_node_intersect_robust(
+ kg, P, idir, t, difl, extmax, node_addr, visibility, dist);
+ }
}
-#else /* !defined(__KERNEL_SSE2__) */
-
-int ccl_device_forceinline bvh_aligned_node_intersect(
- KernelGlobals *kg,
- const float3& P,
- const float3& dir,
- const ssef& tsplat,
- const ssef Psplat[3],
- const ssef idirsplat[3],
- const shuffle_swap_t shufflexyz[3],
- const int node_addr,
- const uint visibility,
- float dist[2])
+#else /* !defined(__KERNEL_SSE2__) */
+
+int ccl_device_forceinline bvh_aligned_node_intersect(KernelGlobals *kg,
+ const float3 &P,
+ const float3 &dir,
+ const ssef &tsplat,
+ const ssef Psplat[3],
+ const ssef idirsplat[3],
+ const shuffle_swap_t shufflexyz[3],
+ const int node_addr,
+ const uint visibility,
+ float dist[2])
{
- /* Intersect two child bounding boxes, SSE3 version adapted from Embree */
- const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+ /* Intersect two child bounding boxes, SSE3 version adapted from Embree */
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
- /* fetch node data */
- const ssef *bvh_nodes = (ssef*)kg->__bvh_nodes.data + node_addr;
+ /* fetch node data */
+ const ssef *bvh_nodes = (ssef *)kg->__bvh_nodes.data + node_addr;
- /* intersect ray against child nodes */
- const ssef tminmaxx = (shuffle_swap(bvh_nodes[1], shufflexyz[0]) - Psplat[0]) * idirsplat[0];
- const ssef tminmaxy = (shuffle_swap(bvh_nodes[2], shufflexyz[1]) - Psplat[1]) * idirsplat[1];
- const ssef tminmaxz = (shuffle_swap(bvh_nodes[3], shufflexyz[2]) - Psplat[2]) * idirsplat[2];
+ /* intersect ray against child nodes */
+ const ssef tminmaxx = (shuffle_swap(bvh_nodes[1], shufflexyz[0]) - Psplat[0]) * idirsplat[0];
+ const ssef tminmaxy = (shuffle_swap(bvh_nodes[2], shufflexyz[1]) - Psplat[1]) * idirsplat[1];
+ const ssef tminmaxz = (shuffle_swap(bvh_nodes[3], shufflexyz[2]) - Psplat[2]) * idirsplat[2];
- /* calculate { c0min, c1min, -c0max, -c1max} */
- ssef minmax = max(max(tminmaxx, tminmaxy), max(tminmaxz, tsplat));
- const ssef tminmax = minmax ^ pn;
- const sseb lrhit = tminmax <= shuffle<2, 3, 0, 1>(tminmax);
+ /* calculate { c0min, c1min, -c0max, -c1max} */
+ ssef minmax = max(max(tminmaxx, tminmaxy), max(tminmaxz, tsplat));
+ const ssef tminmax = minmax ^ pn;
+ const sseb lrhit = tminmax <= shuffle<2, 3, 0, 1>(tminmax);
- dist[0] = tminmax[0];
- dist[1] = tminmax[1];
+ dist[0] = tminmax[0];
+ dist[1] = tminmax[1];
- int mask = movemask(lrhit);
+ int mask = movemask(lrhit);
# ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility))? 1: 0) |
- (((mask & 2) && (__float_as_uint(cnodes.y) & visibility))? 2: 0);
- return cmask;
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
+ (((mask & 2) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
+ return cmask;
# else
- return mask & 3;
+ return mask & 3;
# endif
}
-ccl_device_forceinline int bvh_aligned_node_intersect_robust(
- KernelGlobals *kg,
- const float3& P,
- const float3& dir,
- const ssef& tsplat,
- const ssef Psplat[3],
- const ssef idirsplat[3],
- const shuffle_swap_t shufflexyz[3],
- const float difl,
- const float extmax,
- const int nodeAddr,
- const uint visibility,
- float dist[2])
+ccl_device_forceinline int bvh_aligned_node_intersect_robust(KernelGlobals *kg,
+ const float3 &P,
+ const float3 &dir,
+ const ssef &tsplat,
+ const ssef Psplat[3],
+ const ssef idirsplat[3],
+ const shuffle_swap_t shufflexyz[3],
+ const float difl,
+ const float extmax,
+ const int nodeAddr,
+ const uint visibility,
+ float dist[2])
{
- /* Intersect two child bounding boxes, SSE3 version adapted from Embree */
- const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
-
- /* fetch node data */
- const ssef *bvh_nodes = (ssef*)kg->__bvh_nodes.data + nodeAddr;
-
- /* intersect ray against child nodes */
- const ssef tminmaxx = (shuffle_swap(bvh_nodes[1], shufflexyz[0]) - Psplat[0]) * idirsplat[0];
- const ssef tminmaxy = (shuffle_swap(bvh_nodes[2], shufflexyz[1]) - Psplat[1]) * idirsplat[1];
- const ssef tminmaxz = (shuffle_swap(bvh_nodes[3], shufflexyz[2]) - Psplat[2]) * idirsplat[2];
-
- /* calculate { c0min, c1min, -c0max, -c1max} */
- ssef minmax = max(max(tminmaxx, tminmaxy), max(tminmaxz, tsplat));
- const ssef tminmax = minmax ^ pn;
-
- if(difl != 0.0f) {
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr+0);
- float4 *tminmaxview = (float4*)&tminmax;
- float& c0min = tminmaxview->x, &c1min = tminmaxview->y;
- float& c0max = tminmaxview->z, &c1max = tminmaxview->w;
- float hdiff = 1.0f + difl;
- float ldiff = 1.0f - difl;
- if(__float_as_int(cnodes.x) & PATH_RAY_CURVE) {
- c0min = max(ldiff * c0min, c0min - extmax);
- c0max = min(hdiff * c0max, c0max + extmax);
- }
- if(__float_as_int(cnodes.y) & PATH_RAY_CURVE) {
- c1min = max(ldiff * c1min, c1min - extmax);
- c1max = min(hdiff * c1max, c1max + extmax);
- }
- }
-
- const sseb lrhit = tminmax <= shuffle<2, 3, 0, 1>(tminmax);
-
- dist[0] = tminmax[0];
- dist[1] = tminmax[1];
-
- int mask = movemask(lrhit);
+ /* Intersect two child bounding boxes, SSE3 version adapted from Embree */
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+
+ /* fetch node data */
+ const ssef *bvh_nodes = (ssef *)kg->__bvh_nodes.data + nodeAddr;
+
+ /* intersect ray against child nodes */
+ const ssef tminmaxx = (shuffle_swap(bvh_nodes[1], shufflexyz[0]) - Psplat[0]) * idirsplat[0];
+ const ssef tminmaxy = (shuffle_swap(bvh_nodes[2], shufflexyz[1]) - Psplat[1]) * idirsplat[1];
+ const ssef tminmaxz = (shuffle_swap(bvh_nodes[3], shufflexyz[2]) - Psplat[2]) * idirsplat[2];
+
+ /* calculate { c0min, c1min, -c0max, -c1max} */
+ ssef minmax = max(max(tminmaxx, tminmaxy), max(tminmaxz, tsplat));
+ const ssef tminmax = minmax ^ pn;
+
+ if (difl != 0.0f) {
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr + 0);
+ float4 *tminmaxview = (float4 *)&tminmax;
+ float &c0min = tminmaxview->x, &c1min = tminmaxview->y;
+ float &c0max = tminmaxview->z, &c1max = tminmaxview->w;
+ float hdiff = 1.0f + difl;
+ float ldiff = 1.0f - difl;
+ if (__float_as_int(cnodes.x) & PATH_RAY_CURVE) {
+ c0min = max(ldiff * c0min, c0min - extmax);
+ c0max = min(hdiff * c0max, c0max + extmax);
+ }
+ if (__float_as_int(cnodes.y) & PATH_RAY_CURVE) {
+ c1min = max(ldiff * c1min, c1min - extmax);
+ c1max = min(hdiff * c1max, c1max + extmax);
+ }
+ }
+
+ const sseb lrhit = tminmax <= shuffle<2, 3, 0, 1>(tminmax);
+
+ dist[0] = tminmax[0];
+ dist[1] = tminmax[1];
+
+ int mask = movemask(lrhit);
# ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr+0);
- int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility))? 1: 0) |
- (((mask & 2) && (__float_as_uint(cnodes.y) & visibility))? 2: 0);
- return cmask;
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr + 0);
+ int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
+ (((mask & 2) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
+ return cmask;
# else
- return mask & 3;
+ return mask & 3;
# endif
}
ccl_device_forceinline int bvh_unaligned_node_intersect(KernelGlobals *kg,
const float3 P,
const float3 dir,
- const ssef& isect_near,
- const ssef& isect_far,
+ const ssef &isect_near,
+ const ssef &isect_far,
const int node_addr,
const uint visibility,
float dist[2])
{
- Transform space0 = bvh_unaligned_node_fetch_space(kg, node_addr, 0);
- Transform space1 = bvh_unaligned_node_fetch_space(kg, node_addr, 1);
-
- float3 aligned_dir0 = transform_direction(&space0, dir),
- aligned_dir1 = transform_direction(&space1, dir);
- float3 aligned_P0 = transform_point(&space0, P),
- aligned_P1 = transform_point(&space1, P);
- float3 nrdir0 = -bvh_inverse_direction(aligned_dir0),
- nrdir1 = -bvh_inverse_direction(aligned_dir1);
-
- ssef lower_x = ssef(aligned_P0.x * nrdir0.x,
- aligned_P1.x * nrdir1.x,
- 0.0f, 0.0f),
- lower_y = ssef(aligned_P0.y * nrdir0.y,
- aligned_P1.y * nrdir1.y,
- 0.0f,
- 0.0f),
- lower_z = ssef(aligned_P0.z * nrdir0.z,
- aligned_P1.z * nrdir1.z,
- 0.0f,
- 0.0f);
-
- ssef upper_x = lower_x - ssef(nrdir0.x, nrdir1.x, 0.0f, 0.0f),
- upper_y = lower_y - ssef(nrdir0.y, nrdir1.y, 0.0f, 0.0f),
- upper_z = lower_z - ssef(nrdir0.z, nrdir1.z, 0.0f, 0.0f);
-
- ssef tnear_x = min(lower_x, upper_x);
- ssef tnear_y = min(lower_y, upper_y);
- ssef tnear_z = min(lower_z, upper_z);
- ssef tfar_x = max(lower_x, upper_x);
- ssef tfar_y = max(lower_y, upper_y);
- ssef tfar_z = max(lower_z, upper_z);
-
- const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- sseb vmask = tnear <= tfar;
- dist[0] = tnear.f[0];
- dist[1] = tnear.f[1];
-
- int mask = (int)movemask(vmask);
+ Transform space0 = bvh_unaligned_node_fetch_space(kg, node_addr, 0);
+ Transform space1 = bvh_unaligned_node_fetch_space(kg, node_addr, 1);
+
+ float3 aligned_dir0 = transform_direction(&space0, dir),
+ aligned_dir1 = transform_direction(&space1, dir);
+ float3 aligned_P0 = transform_point(&space0, P), aligned_P1 = transform_point(&space1, P);
+ float3 nrdir0 = -bvh_inverse_direction(aligned_dir0),
+ nrdir1 = -bvh_inverse_direction(aligned_dir1);
+
+ ssef lower_x = ssef(aligned_P0.x * nrdir0.x, aligned_P1.x * nrdir1.x, 0.0f, 0.0f),
+ lower_y = ssef(aligned_P0.y * nrdir0.y, aligned_P1.y * nrdir1.y, 0.0f, 0.0f),
+ lower_z = ssef(aligned_P0.z * nrdir0.z, aligned_P1.z * nrdir1.z, 0.0f, 0.0f);
+
+ ssef upper_x = lower_x - ssef(nrdir0.x, nrdir1.x, 0.0f, 0.0f),
+ upper_y = lower_y - ssef(nrdir0.y, nrdir1.y, 0.0f, 0.0f),
+ upper_z = lower_z - ssef(nrdir0.z, nrdir1.z, 0.0f, 0.0f);
+
+ ssef tnear_x = min(lower_x, upper_x);
+ ssef tnear_y = min(lower_y, upper_y);
+ ssef tnear_z = min(lower_z, upper_z);
+ ssef tfar_x = max(lower_x, upper_x);
+ ssef tfar_y = max(lower_y, upper_y);
+ ssef tfar_z = max(lower_z, upper_z);
+
+ const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ sseb vmask = tnear <= tfar;
+ dist[0] = tnear.f[0];
+ dist[1] = tnear.f[1];
+
+ int mask = (int)movemask(vmask);
# ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility))? 1: 0) |
- (((mask & 2) && (__float_as_uint(cnodes.y) & visibility))? 2: 0);
- return cmask;
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
+ (((mask & 2) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
+ return cmask;
# else
- return mask & 3;
+ return mask & 3;
# endif
}
ccl_device_forceinline int bvh_unaligned_node_intersect_robust(KernelGlobals *kg,
const float3 P,
const float3 dir,
- const ssef& isect_near,
- const ssef& isect_far,
+ const ssef &isect_near,
+ const ssef &isect_far,
const float difl,
const int node_addr,
const uint visibility,
float dist[2])
{
- Transform space0 = bvh_unaligned_node_fetch_space(kg, node_addr, 0);
- Transform space1 = bvh_unaligned_node_fetch_space(kg, node_addr, 1);
-
- float3 aligned_dir0 = transform_direction(&space0, dir),
- aligned_dir1 = transform_direction(&space1, dir);
- float3 aligned_P0 = transform_point(&space0, P),
- aligned_P1 = transform_point(&space1, P);
- float3 nrdir0 = -bvh_inverse_direction(aligned_dir0),
- nrdir1 = -bvh_inverse_direction(aligned_dir1);
-
- ssef lower_x = ssef(aligned_P0.x * nrdir0.x,
- aligned_P1.x * nrdir1.x,
- 0.0f, 0.0f),
- lower_y = ssef(aligned_P0.y * nrdir0.y,
- aligned_P1.y * nrdir1.y,
- 0.0f,
- 0.0f),
- lower_z = ssef(aligned_P0.z * nrdir0.z,
- aligned_P1.z * nrdir1.z,
- 0.0f,
- 0.0f);
-
- ssef upper_x = lower_x - ssef(nrdir0.x, nrdir1.x, 0.0f, 0.0f),
- upper_y = lower_y - ssef(nrdir0.y, nrdir1.y, 0.0f, 0.0f),
- upper_z = lower_z - ssef(nrdir0.z, nrdir1.z, 0.0f, 0.0f);
-
- ssef tnear_x = min(lower_x, upper_x);
- ssef tnear_y = min(lower_y, upper_y);
- ssef tnear_z = min(lower_z, upper_z);
- ssef tfar_x = max(lower_x, upper_x);
- ssef tfar_y = max(lower_y, upper_y);
- ssef tfar_z = max(lower_z, upper_z);
-
- const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- sseb vmask;
- if(difl != 0.0f) {
- const float round_down = 1.0f - difl;
- const float round_up = 1.0f + difl;
- vmask = round_down*tnear <= round_up*tfar;
- }
- else {
- vmask = tnear <= tfar;
- }
-
- dist[0] = tnear.f[0];
- dist[1] = tnear.f[1];
-
- int mask = (int)movemask(vmask);
+ Transform space0 = bvh_unaligned_node_fetch_space(kg, node_addr, 0);
+ Transform space1 = bvh_unaligned_node_fetch_space(kg, node_addr, 1);
+
+ float3 aligned_dir0 = transform_direction(&space0, dir),
+ aligned_dir1 = transform_direction(&space1, dir);
+ float3 aligned_P0 = transform_point(&space0, P), aligned_P1 = transform_point(&space1, P);
+ float3 nrdir0 = -bvh_inverse_direction(aligned_dir0),
+ nrdir1 = -bvh_inverse_direction(aligned_dir1);
+
+ ssef lower_x = ssef(aligned_P0.x * nrdir0.x, aligned_P1.x * nrdir1.x, 0.0f, 0.0f),
+ lower_y = ssef(aligned_P0.y * nrdir0.y, aligned_P1.y * nrdir1.y, 0.0f, 0.0f),
+ lower_z = ssef(aligned_P0.z * nrdir0.z, aligned_P1.z * nrdir1.z, 0.0f, 0.0f);
+
+ ssef upper_x = lower_x - ssef(nrdir0.x, nrdir1.x, 0.0f, 0.0f),
+ upper_y = lower_y - ssef(nrdir0.y, nrdir1.y, 0.0f, 0.0f),
+ upper_z = lower_z - ssef(nrdir0.z, nrdir1.z, 0.0f, 0.0f);
+
+ ssef tnear_x = min(lower_x, upper_x);
+ ssef tnear_y = min(lower_y, upper_y);
+ ssef tnear_z = min(lower_z, upper_z);
+ ssef tfar_x = max(lower_x, upper_x);
+ ssef tfar_y = max(lower_y, upper_y);
+ ssef tfar_z = max(lower_z, upper_z);
+
+ const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ sseb vmask;
+ if (difl != 0.0f) {
+ const float round_down = 1.0f - difl;
+ const float round_up = 1.0f + difl;
+ vmask = round_down * tnear <= round_up * tfar;
+ }
+ else {
+ vmask = tnear <= tfar;
+ }
+
+ dist[0] = tnear.f[0];
+ dist[1] = tnear.f[1];
+
+ int mask = (int)movemask(vmask);
# ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility))? 1: 0) |
- (((mask & 2) && (__float_as_uint(cnodes.y) & visibility))? 2: 0);
- return cmask;
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ int cmask = (((mask & 1) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
+ (((mask & 2) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
+ return cmask;
# else
- return mask & 3;
+ return mask & 3;
# endif
}
ccl_device_forceinline int bvh_node_intersect(KernelGlobals *kg,
- const float3& P,
- const float3& dir,
- const ssef& isect_near,
- const ssef& isect_far,
- const ssef& tsplat,
+ const float3 &P,
+ const float3 &dir,
+ const ssef &isect_near,
+ const ssef &isect_far,
+ const ssef &tsplat,
const ssef Psplat[3],
const ssef idirsplat[3],
const shuffle_swap_t shufflexyz[3],
@@ -585,37 +533,23 @@ ccl_device_forceinline int bvh_node_intersect(KernelGlobals *kg,
const uint visibility,
float dist[2])
{
- float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return bvh_unaligned_node_intersect(kg,
- P,
- dir,
- isect_near,
- isect_far,
- node_addr,
- visibility,
- dist);
- }
- else {
- return bvh_aligned_node_intersect(kg,
- P,
- dir,
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- node_addr,
- visibility,
- dist);
- }
+ float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return bvh_unaligned_node_intersect(
+ kg, P, dir, isect_near, isect_far, node_addr, visibility, dist);
+ }
+ else {
+ return bvh_aligned_node_intersect(
+ kg, P, dir, tsplat, Psplat, idirsplat, shufflexyz, node_addr, visibility, dist);
+ }
}
ccl_device_forceinline int bvh_node_intersect_robust(KernelGlobals *kg,
- const float3& P,
- const float3& dir,
- const ssef& isect_near,
- const ssef& isect_far,
- const ssef& tsplat,
+ const float3 &P,
+ const float3 &dir,
+ const ssef &isect_near,
+ const ssef &isect_far,
+ const ssef &tsplat,
const ssef Psplat[3],
const ssef idirsplat[3],
const shuffle_swap_t shufflexyz[3],
@@ -625,31 +559,24 @@ ccl_device_forceinline int bvh_node_intersect_robust(KernelGlobals *kg,
const uint visibility,
float dist[2])
{
- float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return bvh_unaligned_node_intersect_robust(kg,
- P,
- dir,
- isect_near,
- isect_far,
- difl,
- node_addr,
- visibility,
- dist);
- }
- else {
- return bvh_aligned_node_intersect_robust(kg,
- P,
- dir,
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- difl,
- extmax,
- node_addr,
- visibility,
- dist);
- }
+ float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return bvh_unaligned_node_intersect_robust(
+ kg, P, dir, isect_near, isect_far, difl, node_addr, visibility, dist);
+ }
+ else {
+ return bvh_aligned_node_intersect_robust(kg,
+ P,
+ dir,
+ tsplat,
+ Psplat,
+ idirsplat,
+ shufflexyz,
+ difl,
+ extmax,
+ node_addr,
+ visibility,
+ dist);
+ }
}
-#endif /* !defined(__KERNEL_SSE2__) */
+#endif /* !defined(__KERNEL_SSE2__) */
diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h
index d8e089711ee..b362779549c 100644
--- a/intern/cycles/kernel/bvh/bvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h
@@ -19,9 +19,9 @@
#ifdef __QBVH__
# include "kernel/bvh/qbvh_shadow_all.h"
-#ifdef __KERNEL_AVX2__
-# include "kernel/bvh/obvh_shadow_all.h"
-#endif
+# ifdef __KERNEL_AVX2__
+# include "kernel/bvh/obvh_shadow_all.h"
+# endif
#endif
#if BVH_FEATURE(BVH_HAIR)
@@ -44,350 +44,340 @@ ccl_device
#else
ccl_device_inline
#endif
-bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
- const Ray *ray,
- Intersection *isect_array,
- const uint visibility,
- const uint max_hits,
- uint *num_hits)
+ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ const uint visibility,
+ const uint max_hits,
+ uint *num_hits)
{
- /* todo:
- * - likely and unlikely for if() statements
- * - test restrict attribute for pointers
- */
-
- /* traversal stack in CUDA thread-local memory */
- int traversal_stack[BVH_STACK_SIZE];
- traversal_stack[0] = ENTRYPOINT_SENTINEL;
-
- /* traversal variables in registers */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* ray parameters in registers */
- const float tmax = ray->t;
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = tmax;
+ /* todo:
+ * - likely and unlikely for if() statements
+ * - test restrict attribute for pointers
+ */
+
+ /* traversal stack in CUDA thread-local memory */
+ int traversal_stack[BVH_STACK_SIZE];
+ traversal_stack[0] = ENTRYPOINT_SENTINEL;
+
+ /* traversal variables in registers */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* ray parameters in registers */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
#if BVH_FEATURE(BVH_INSTANCING)
- int num_hits_in_instance = 0;
+ int num_hits_in_instance = 0;
#endif
- *num_hits = 0;
- isect_array->t = tmax;
+ *num_hits = 0;
+ isect_array->t = tmax;
#if defined(__KERNEL_SSE2__)
- const shuffle_swap_t shuf_identity = shuffle_swap_identity();
- const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
- const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
- ssef Psplat[3], idirsplat[3];
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+ ssef Psplat[3], idirsplat[3];
# if BVH_FEATURE(BVH_HAIR)
- ssef tnear(0.0f), tfar(isect_t);
+ ssef tnear(0.0f), tfar(isect_t);
# endif
- shuffle_swap_t shufflexyz[3];
+ shuffle_swap_t shufflexyz[3];
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- ssef tsplat(0.0f, 0.0f, -isect_t, -isect_t);
+ ssef tsplat(0.0f, 0.0f, -isect_t, -isect_t);
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
-#endif /* __KERNEL_SSE2__ */
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+#endif /* __KERNEL_SSE2__ */
- /* traversal loop */
- do {
- do {
- /* traverse internal nodes */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- int node_addr_child1, traverse_mask;
- float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* traversal loop */
+ do {
+ do {
+ /* traverse internal nodes */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ int node_addr_child1, traverse_mask;
+ float dist[2];
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#if !defined(__KERNEL_SSE2__)
- traverse_mask = NODE_INTERSECT(kg,
- P,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
# if BVH_FEATURE(BVH_HAIR)
- dir,
+ dir,
# endif
- idir,
- isect_t,
- node_addr,
- visibility,
- dist);
+ idir,
+ isect_t,
+ node_addr,
+ visibility,
+ dist);
#else // __KERNEL_SSE2__
- traverse_mask = NODE_INTERSECT(kg,
- P,
- dir,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
+ dir,
# if BVH_FEATURE(BVH_HAIR)
- tnear,
- tfar,
+ tnear,
+ tfar,
# endif
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- node_addr,
- visibility,
- dist);
+ tsplat,
+ Psplat,
+ idirsplat,
+ shufflexyz,
+ node_addr,
+ visibility,
+ dist);
#endif // __KERNEL_SSE2__
- node_addr = __float_as_int(cnodes.z);
- node_addr_child1 = __float_as_int(cnodes.w);
-
- if(traverse_mask == 3) {
- /* Both children were intersected, push the farther one. */
- bool is_closest_child1 = (dist[1] < dist[0]);
- if(is_closest_child1) {
- int tmp = node_addr;
- node_addr = node_addr_child1;
- node_addr_child1 = tmp;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = node_addr_child1;
- }
- else {
- /* One child was intersected. */
- if(traverse_mask == 2) {
- node_addr = node_addr_child1;
- }
- else if(traverse_mask == 0) {
- /* Neither child was intersected. */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
- }
- }
-
- /* if node is leaf, fetch triangle list */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
- int prim_addr = __float_as_int(leaf.x);
+ node_addr = __float_as_int(cnodes.z);
+ node_addr_child1 = __float_as_int(cnodes.w);
+
+ if (traverse_mask == 3) {
+ /* Both children were intersected, push the farther one. */
+ bool is_closest_child1 = (dist[1] < dist[0]);
+ if (is_closest_child1) {
+ int tmp = node_addr;
+ node_addr = node_addr_child1;
+ node_addr_child1 = tmp;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = node_addr_child1;
+ }
+ else {
+ /* One child was intersected. */
+ if (traverse_mask == 2) {
+ node_addr = node_addr_child1;
+ }
+ else if (traverse_mask == 0) {
+ /* Neither child was intersected. */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+ }
+ }
+
+ /* if node is leaf, fetch triangle list */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- const int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- const uint p_type = type & PRIMITIVE_ALL;
-
- /* pop */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
-
- /* primitive intersection */
- while(prim_addr < prim_addr2) {
- kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
- bool hit;
-
- /* todo: specialized intersect functions which don't fill in
- * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
- * might give a few % performance improvement */
-
- switch(p_type) {
- case PRIMITIVE_TRIANGLE: {
- hit = triangle_intersect(kg,
- isect_array,
- P,
- dir,
- visibility,
- object,
- prim_addr);
- break;
- }
+ const int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+
+ /* pop */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+
+ /* primitive intersection */
+ while (prim_addr < prim_addr2) {
+ kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
+ bool hit;
+
+ /* todo: specialized intersect functions which don't fill in
+ * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
+ * might give a few % performance improvement */
+
+ switch (p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- hit = motion_triangle_intersect(kg,
- isect_array,
- P,
- dir,
- ray->time,
- visibility,
- object,
- prim_addr);
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ hit = motion_triangle_intersect(
+ kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
+ break;
+ }
#endif
#if BVH_FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = cardinal_curve_intersect(kg,
- isect_array,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
- }
- else {
- hit = curve_intersect(kg,
- isect_array,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
- }
- break;
- }
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ if (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
+ hit = cardinal_curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0,
+ 0);
+ }
+ else {
+ hit = curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0,
+ 0);
+ }
+ break;
+ }
#endif
- default: {
- hit = false;
- break;
- }
- }
+ default: {
+ hit = false;
+ break;
+ }
+ }
- /* shadow ray early termination */
- if(hit) {
- /* detect if this surface has a shader with transparent shadows */
+ /* shadow ray early termination */
+ if (hit) {
+ /* detect if this surface has a shader with transparent shadows */
- /* todo: optimize so primitive visibility flag indicates if
- * the primitive has a transparent shadow shader? */
- int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
- int shader = 0;
+ /* todo: optimize so primitive visibility flag indicates if
+ * the primitive has a transparent shadow shader? */
+ int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
+ int shader = 0;
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
+ if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
#endif
- {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
#ifdef __HAIR__
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
#endif
- int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
-
- /* if no transparent shadows, all light is blocked */
- if(!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
- return true;
- }
- /* if maximum number of hits reached, block all light */
- else if(*num_hits == max_hits) {
- return true;
- }
-
- /* move on to next entry in intersections array */
- isect_array++;
- (*num_hits)++;
+ int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+
+ /* if no transparent shadows, all light is blocked */
+ if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ return true;
+ }
+ /* if maximum number of hits reached, block all light */
+ else if (*num_hits == max_hits) {
+ return true;
+ }
+
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
#endif
- isect_array->t = isect_t;
- }
+ isect_array->t = isect_t;
+ }
- prim_addr++;
- }
- }
+ prim_addr++;
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
+ else {
+ /* instance push */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
# if BVH_FEATURE(BVH_MOTION)
- isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
+ isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
# else
- isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
# endif
- num_hits_in_instance = 0;
- isect_array->t = isect_t;
+ num_hits_in_instance = 0;
+ isect_array->t = isect_t;
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
+ tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect_t);
+ tfar = ssef(isect_t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
- node_addr = kernel_tex_fetch(__object_node, object);
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
- if(num_hits_in_instance) {
- float t_fac;
+ /* Instance pop. */
+ if (num_hits_in_instance) {
+ float t_fac;
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
# else
- bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
# endif
- /* scale isect->t to adjust for instancing */
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
- else {
+ /* scale isect->t to adjust for instancing */
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+ else {
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
# else
- bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
# endif
- }
+ }
- isect_t = tmax;
- isect_array->t = isect_t;
+ isect_t = tmax;
+ isect_array->t = isect_t;
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
+ tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect_t);
+ tfar = ssef(isect_t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return false;
+ return false;
}
ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
@@ -397,35 +387,20 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
const uint max_hits,
uint *num_hits)
{
- switch(kernel_data.bvh.bvh_layout) {
+ switch (kernel_data.bvh.bvh_layout) {
#ifdef __KERNEL_AVX2__
- case BVH_LAYOUT_BVH8:
- return BVH_FUNCTION_FULL_NAME(OBVH)(kg,
- ray,
- isect_array,
- visibility,
- max_hits,
- num_hits);
+ case BVH_LAYOUT_BVH8:
+ return BVH_FUNCTION_FULL_NAME(OBVH)(kg, ray, isect_array, visibility, max_hits, num_hits);
#endif
#ifdef __QBVH__
- case BVH_LAYOUT_BVH4:
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect_array,
- visibility,
- max_hits,
- num_hits);
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg, ray, isect_array, visibility, max_hits, num_hits);
#endif
- case BVH_LAYOUT_BVH2:
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect_array,
- visibility,
- max_hits,
- num_hits);
- }
- kernel_assert(!"Should not happen");
- return false;
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg, ray, isect_array, visibility, max_hits, num_hits);
+ }
+ kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_traversal.h b/intern/cycles/kernel/bvh/bvh_traversal.h
index 76d4cab663d..34a06d003bb 100644
--- a/intern/cycles/kernel/bvh/bvh_traversal.h
+++ b/intern/cycles/kernel/bvh/bvh_traversal.h
@@ -47,374 +47,362 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
Intersection *isect,
const uint visibility
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- , uint *lcg_state,
+ ,
+ uint *lcg_state,
float difl,
float extmax
#endif
- )
+)
{
- /* todo:
- * - test if pushing distance on the stack helps (for non shadow rays)
- * - separate version for shadow rays
- * - likely and unlikely for if() statements
- * - test restrict attribute for pointers
- */
-
- /* traversal stack in CUDA thread-local memory */
- int traversal_stack[BVH_STACK_SIZE];
- traversal_stack[0] = ENTRYPOINT_SENTINEL;
-
- /* traversal variables in registers */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* ray parameters in registers */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
+ /* todo:
+ * - test if pushing distance on the stack helps (for non shadow rays)
+ * - separate version for shadow rays
+ * - likely and unlikely for if() statements
+ * - test restrict attribute for pointers
+ */
+
+ /* traversal stack in CUDA thread-local memory */
+ int traversal_stack[BVH_STACK_SIZE];
+ traversal_stack[0] = ENTRYPOINT_SENTINEL;
+
+ /* traversal variables in registers */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* ray parameters in registers */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- isect->t = ray->t;
- isect->u = 0.0f;
- isect->v = 0.0f;
- isect->prim = PRIM_NONE;
- isect->object = OBJECT_NONE;
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
- BVH_DEBUG_INIT();
+ BVH_DEBUG_INIT();
#if defined(__KERNEL_SSE2__)
- const shuffle_swap_t shuf_identity = shuffle_swap_identity();
- const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
- const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
- ssef Psplat[3], idirsplat[3];
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+ ssef Psplat[3], idirsplat[3];
# if BVH_FEATURE(BVH_HAIR)
- ssef tnear(0.0f), tfar(isect->t);
+ ssef tnear(0.0f), tfar(isect->t);
# endif
- shuffle_swap_t shufflexyz[3];
+ shuffle_swap_t shufflexyz[3];
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- ssef tsplat(0.0f, 0.0f, -isect->t, -isect->t);
+ ssef tsplat(0.0f, 0.0f, -isect->t, -isect->t);
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
- /* traversal loop */
- do {
- do {
- /* traverse internal nodes */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- int node_addr_child1, traverse_mask;
- float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* traversal loop */
+ do {
+ do {
+ /* traverse internal nodes */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ int node_addr_child1, traverse_mask;
+ float dist[2];
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#if !defined(__KERNEL_SSE2__)
# if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- if(difl != 0.0f) {
- traverse_mask = NODE_INTERSECT_ROBUST(kg,
- P,
+ if (difl != 0.0f) {
+ traverse_mask = NODE_INTERSECT_ROBUST(kg,
+ P,
# if BVH_FEATURE(BVH_HAIR)
- dir,
+ dir,
# endif
- idir,
- isect->t,
- difl,
- extmax,
- node_addr,
- visibility,
- dist);
- }
- else
+ idir,
+ isect->t,
+ difl,
+ extmax,
+ node_addr,
+ visibility,
+ dist);
+ }
+ else
# endif
- {
- traverse_mask = NODE_INTERSECT(kg,
- P,
-# if BVH_FEATURE(BVH_HAIR)
- dir,
-# endif
- idir,
- isect->t,
- node_addr,
- visibility,
- dist);
- }
+ {
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
+# if BVH_FEATURE(BVH_HAIR)
+ dir,
+# endif
+ idir,
+ isect->t,
+ node_addr,
+ visibility,
+ dist);
+ }
#else // __KERNEL_SSE2__
# if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- if(difl != 0.0f) {
- traverse_mask = NODE_INTERSECT_ROBUST(kg,
- P,
- dir,
+ if (difl != 0.0f) {
+ traverse_mask = NODE_INTERSECT_ROBUST(kg,
+ P,
+ dir,
# if BVH_FEATURE(BVH_HAIR)
- tnear,
- tfar,
+ tnear,
+ tfar,
# endif
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- difl,
- extmax,
- node_addr,
- visibility,
- dist);
- }
- else
+ tsplat,
+ Psplat,
+ idirsplat,
+ shufflexyz,
+ difl,
+ extmax,
+ node_addr,
+ visibility,
+ dist);
+ }
+ else
# endif
- {
- traverse_mask = NODE_INTERSECT(kg,
- P,
- dir,
-# if BVH_FEATURE(BVH_HAIR)
- tnear,
- tfar,
-# endif
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- node_addr,
- visibility,
- dist);
- }
+ {
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
+ dir,
+# if BVH_FEATURE(BVH_HAIR)
+ tnear,
+ tfar,
+# endif
+ tsplat,
+ Psplat,
+ idirsplat,
+ shufflexyz,
+ node_addr,
+ visibility,
+ dist);
+ }
#endif // __KERNEL_SSE2__
- node_addr = __float_as_int(cnodes.z);
- node_addr_child1 = __float_as_int(cnodes.w);
-
- if(traverse_mask == 3) {
- /* Both children were intersected, push the farther one. */
- bool is_closest_child1 = (dist[1] < dist[0]);
- if(is_closest_child1) {
- int tmp = node_addr;
- node_addr = node_addr_child1;
- node_addr_child1 = tmp;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = node_addr_child1;
- }
- else {
- /* One child was intersected. */
- if(traverse_mask == 2) {
- node_addr = node_addr_child1;
- }
- else if(traverse_mask == 0) {
- /* Neither child was intersected. */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
- }
- BVH_DEBUG_NEXT_NODE();
- }
-
- /* if node is leaf, fetch triangle list */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
- int prim_addr = __float_as_int(leaf.x);
+ node_addr = __float_as_int(cnodes.z);
+ node_addr_child1 = __float_as_int(cnodes.w);
+
+ if (traverse_mask == 3) {
+ /* Both children were intersected, push the farther one. */
+ bool is_closest_child1 = (dist[1] < dist[0]);
+ if (is_closest_child1) {
+ int tmp = node_addr;
+ node_addr = node_addr_child1;
+ node_addr_child1 = tmp;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = node_addr_child1;
+ }
+ else {
+ /* One child was intersected. */
+ if (traverse_mask == 2) {
+ node_addr = node_addr_child1;
+ }
+ else if (traverse_mask == 0) {
+ /* Neither child was intersected. */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+ }
+ BVH_DEBUG_NEXT_NODE();
+ }
+
+ /* if node is leaf, fetch triangle list */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- const int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
-
- /* pop */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
-
- /* primitive intersection */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(triangle_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr))
- {
- /* shadow ray early termination */
+ const int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+
+ /* pop */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+
+ /* primitive intersection */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr)) {
+ /* shadow ray early termination */
#if defined(__KERNEL_SSE2__)
- if(visibility & PATH_RAY_SHADOW_OPAQUE)
- return true;
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ if (visibility & PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect->t);
+ tfar = ssef(isect->t);
# endif
#else
- if(visibility & PATH_RAY_SHADOW_OPAQUE)
- return true;
+ if (visibility & PATH_RAY_SHADOW_OPAQUE)
+ return true;
#endif
- }
- }
- break;
- }
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(motion_triangle_intersect(kg,
- isect,
- P,
- dir,
- ray->time,
- visibility,
- object,
- prim_addr))
- {
- /* shadow ray early termination */
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (motion_triangle_intersect(
+ kg, isect, P, dir, ray->time, visibility, object, prim_addr)) {
+ /* shadow ray early termination */
# if defined(__KERNEL_SSE2__)
- if(visibility & PATH_RAY_SHADOW_OPAQUE)
- return true;
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ if (visibility & PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect->t);
+ tfar = ssef(isect->t);
# endif
# else
- if(visibility & PATH_RAY_SHADOW_OPAQUE)
- return true;
+ if (visibility & PATH_RAY_SHADOW_OPAQUE)
+ return true;
# endif
- }
- }
- break;
- }
-#endif /* BVH_FEATURE(BVH_MOTION) */
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_MOTION) */
#if BVH_FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
- kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
- bool hit;
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = cardinal_curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
- }
- else {
- hit = curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
- }
- if(hit) {
- /* shadow ray early termination */
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
+ bool hit;
+ if (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
+ hit = cardinal_curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
+ }
+ else {
+ hit = curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
+ }
+ if (hit) {
+ /* shadow ray early termination */
# if defined(__KERNEL_SSE2__)
- if(visibility & PATH_RAY_SHADOW_OPAQUE)
- return true;
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ if (visibility & PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect->t);
+ tfar = ssef(isect->t);
# endif
# else
- if(visibility & PATH_RAY_SHADOW_OPAQUE)
- return true;
+ if (visibility & PATH_RAY_SHADOW_OPAQUE)
+ return true;
# endif
- }
- }
- break;
- }
-#endif /* BVH_FEATURE(BVH_HAIR) */
- }
- }
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_HAIR) */
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
+ else {
+ /* instance push */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect->t);
+ tfar = ssef(isect->t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
- node_addr = kernel_tex_fetch(__object_node, object);
+ node_addr = kernel_tex_fetch(__object_node, object);
- BVH_DEBUG_NEXT_INSTANCE();
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ BVH_DEBUG_NEXT_INSTANCE();
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* instance pop */
+ /* instance pop */
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect->t);
+ tfar = ssef(isect->t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return (isect->prim != PRIM_NONE);
+ return (isect->prim != PRIM_NONE);
}
ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
@@ -422,53 +410,57 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
Intersection *isect,
const uint visibility
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- , uint *lcg_state,
+ ,
+ uint *lcg_state,
float difl,
float extmax
#endif
- )
+)
{
- switch(kernel_data.bvh.bvh_layout) {
+ switch (kernel_data.bvh.bvh_layout) {
#ifdef __KERNEL_AVX2__
- case BVH_LAYOUT_BVH8:
- return BVH_FUNCTION_FULL_NAME(OBVH)(kg,
- ray,
- isect,
- visibility
+ case BVH_LAYOUT_BVH8:
+ return BVH_FUNCTION_FULL_NAME(OBVH)(kg,
+ ray,
+ isect,
+ visibility
# if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- , lcg_state,
- difl,
- extmax
+ ,
+ lcg_state,
+ difl,
+ extmax
# endif
- );
+ );
#endif
#ifdef __QBVH__
- case BVH_LAYOUT_BVH4:
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect,
- visibility
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect,
+ visibility
# if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- , lcg_state,
- difl,
- extmax
+ ,
+ lcg_state,
+ difl,
+ extmax
# endif
- );
-#endif /* __QBVH__ */
- case BVH_LAYOUT_BVH2:
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect,
- visibility
+ );
+#endif /* __QBVH__ */
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect,
+ visibility
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- , lcg_state,
- difl,
- extmax
+ ,
+ lcg_state,
+ difl,
+ extmax
#endif
- );
- }
- kernel_assert(!"Should not happen");
- return false;
+ );
+ }
+ kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_types.h b/intern/cycles/kernel/bvh/bvh_types.h
index 4ca0dc2225e..16f3b03f842 100644
--- a/intern/cycles/kernel/bvh/bvh_types.h
+++ b/intern/cycles/kernel/bvh/bvh_types.h
@@ -35,13 +35,13 @@ CCL_NAMESPACE_BEGIN
#define BVH_OSTACK_SIZE 768
/* BVH intersection function variations */
-#define BVH_INSTANCING 1
-#define BVH_MOTION 2
-#define BVH_HAIR 4
-#define BVH_HAIR_MINIMUM_WIDTH 8
+#define BVH_INSTANCING 1
+#define BVH_MOTION 2
+#define BVH_HAIR 4
+#define BVH_HAIR_MINIMUM_WIDTH 8
-#define BVH_NAME_JOIN(x,y) x ## _ ## y
-#define BVH_NAME_EVAL(x,y) BVH_NAME_JOIN(x,y)
+#define BVH_NAME_JOIN(x, y) x##_##y
+#define BVH_NAME_EVAL(x, y) BVH_NAME_JOIN(x, y)
#define BVH_FUNCTION_FULL_NAME(prefix) BVH_NAME_EVAL(prefix, BVH_FUNCTION_NAME)
#define BVH_FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
@@ -49,30 +49,30 @@ CCL_NAMESPACE_BEGIN
/* Debugging heleprs */
#ifdef __KERNEL_DEBUG__
# define BVH_DEBUG_INIT() \
- do { \
- isect->num_traversed_nodes = 0; \
- isect->num_traversed_instances = 0; \
- isect->num_intersections = 0; \
- } while(0)
+ do { \
+ isect->num_traversed_nodes = 0; \
+ isect->num_traversed_instances = 0; \
+ isect->num_intersections = 0; \
+ } while (0)
# define BVH_DEBUG_NEXT_NODE() \
- do { \
- ++isect->num_traversed_nodes; \
- } while(0)
+ do { \
+ ++isect->num_traversed_nodes; \
+ } while (0)
# define BVH_DEBUG_NEXT_INTERSECTION() \
- do { \
- ++isect->num_intersections; \
- } while(0)
+ do { \
+ ++isect->num_intersections; \
+ } while (0)
# define BVH_DEBUG_NEXT_INSTANCE() \
- do { \
- ++isect->num_traversed_instances; \
- } while(0)
-#else /* __KERNEL_DEBUG__ */
+ do { \
+ ++isect->num_traversed_instances; \
+ } while (0)
+#else /* __KERNEL_DEBUG__ */
# define BVH_DEBUG_INIT()
# define BVH_DEBUG_NEXT_NODE()
# define BVH_DEBUG_NEXT_INTERSECTION()
# define BVH_DEBUG_NEXT_INSTANCE()
-#endif /* __KERNEL_DEBUG__ */
+#endif /* __KERNEL_DEBUG__ */
CCL_NAMESPACE_END
-#endif /* __BVH_TYPES__ */
+#endif /* __BVH_TYPES__ */
diff --git a/intern/cycles/kernel/bvh/bvh_volume.h b/intern/cycles/kernel/bvh/bvh_volume.h
index b8257e3493e..c83b0d783f4 100644
--- a/intern/cycles/kernel/bvh/bvh_volume.h
+++ b/intern/cycles/kernel/bvh/bvh_volume.h
@@ -19,9 +19,9 @@
#ifdef __QBVH__
# include "kernel/bvh/qbvh_volume.h"
-#ifdef __KERNEL_AVX2__
-# include "kernel/bvh/obvh_volume.h"
-#endif
+# ifdef __KERNEL_AVX2__
+# include "kernel/bvh/obvh_volume.h"
+# endif
#endif
#if BVH_FEATURE(BVH_HAIR)
@@ -43,267 +43,260 @@ ccl_device
#else
ccl_device_inline
#endif
-bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
- const Ray *ray,
- Intersection *isect,
- const uint visibility)
+ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect,
+ const uint visibility)
{
- /* todo:
- * - test if pushing distance on the stack helps (for non shadow rays)
- * - separate version for shadow rays
- * - likely and unlikely for if() statements
- * - test restrict attribute for pointers
- */
-
- /* traversal stack in CUDA thread-local memory */
- int traversal_stack[BVH_STACK_SIZE];
- traversal_stack[0] = ENTRYPOINT_SENTINEL;
-
- /* traversal variables in registers */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* ray parameters in registers */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
+ /* todo:
+ * - test if pushing distance on the stack helps (for non shadow rays)
+ * - separate version for shadow rays
+ * - likely and unlikely for if() statements
+ * - test restrict attribute for pointers
+ */
+
+ /* traversal stack in CUDA thread-local memory */
+ int traversal_stack[BVH_STACK_SIZE];
+ traversal_stack[0] = ENTRYPOINT_SENTINEL;
+
+ /* traversal variables in registers */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* ray parameters in registers */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- isect->t = ray->t;
- isect->u = 0.0f;
- isect->v = 0.0f;
- isect->prim = PRIM_NONE;
- isect->object = OBJECT_NONE;
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
#if defined(__KERNEL_SSE2__)
- const shuffle_swap_t shuf_identity = shuffle_swap_identity();
- const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
- const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
- ssef Psplat[3], idirsplat[3];
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+ ssef Psplat[3], idirsplat[3];
# if BVH_FEATURE(BVH_HAIR)
- ssef tnear(0.0f), tfar(isect->t);
+ ssef tnear(0.0f), tfar(isect->t);
# endif
- shuffle_swap_t shufflexyz[3];
+ shuffle_swap_t shufflexyz[3];
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- ssef tsplat(0.0f, 0.0f, -isect->t, -isect->t);
+ ssef tsplat(0.0f, 0.0f, -isect->t, -isect->t);
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
- /* traversal loop */
- do {
- do {
- /* traverse internal nodes */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- int node_addr_child1, traverse_mask;
- float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* traversal loop */
+ do {
+ do {
+ /* traverse internal nodes */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ int node_addr_child1, traverse_mask;
+ float dist[2];
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#if !defined(__KERNEL_SSE2__)
- traverse_mask = NODE_INTERSECT(kg,
- P,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
# if BVH_FEATURE(BVH_HAIR)
- dir,
+ dir,
# endif
- idir,
- isect->t,
- node_addr,
- visibility,
- dist);
+ idir,
+ isect->t,
+ node_addr,
+ visibility,
+ dist);
#else // __KERNEL_SSE2__
- traverse_mask = NODE_INTERSECT(kg,
- P,
- dir,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
+ dir,
# if BVH_FEATURE(BVH_HAIR)
- tnear,
- tfar,
+ tnear,
+ tfar,
# endif
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- node_addr,
- visibility,
- dist);
+ tsplat,
+ Psplat,
+ idirsplat,
+ shufflexyz,
+ node_addr,
+ visibility,
+ dist);
#endif // __KERNEL_SSE2__
- node_addr = __float_as_int(cnodes.z);
- node_addr_child1 = __float_as_int(cnodes.w);
-
- if(traverse_mask == 3) {
- /* Both children were intersected, push the farther one. */
- bool is_closest_child1 = (dist[1] < dist[0]);
- if(is_closest_child1) {
- int tmp = node_addr;
- node_addr = node_addr_child1;
- node_addr_child1 = tmp;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = node_addr_child1;
- }
- else {
- /* One child was intersected. */
- if(traverse_mask == 2) {
- node_addr = node_addr_child1;
- }
- else if(traverse_mask == 0) {
- /* Neither child was intersected. */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
- }
- }
-
- /* if node is leaf, fetch triangle list */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
- int prim_addr = __float_as_int(leaf.x);
+ node_addr = __float_as_int(cnodes.z);
+ node_addr_child1 = __float_as_int(cnodes.w);
+
+ if (traverse_mask == 3) {
+ /* Both children were intersected, push the farther one. */
+ bool is_closest_child1 = (dist[1] < dist[0]);
+ if (is_closest_child1) {
+ int tmp = node_addr;
+ node_addr = node_addr_child1;
+ node_addr_child1 = tmp;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = node_addr_child1;
+ }
+ else {
+ /* One child was intersected. */
+ if (traverse_mask == 2) {
+ node_addr = node_addr_child1;
+ }
+ else if (traverse_mask == 0) {
+ /* Neither child was intersected. */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+ }
+ }
+
+ /* if node is leaf, fetch triangle list */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- const int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
-
- /* pop */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
-
- /* primitive intersection */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- /* intersect ray against primitive */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- triangle_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr);
- }
- break;
- }
+ const int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+
+ /* pop */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+
+ /* primitive intersection */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* intersect ray against primitive */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr);
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- /* intersect ray against primitive */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- motion_triangle_intersect(kg,
- isect,
- P,
- dir,
- ray->time,
- visibility,
- object,
- prim_addr);
- }
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* intersect ray against primitive */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ motion_triangle_intersect(
+ kg, isect, P, dir, ray->time, visibility, object, prim_addr);
+ }
+ break;
+ }
#endif
- default: {
- break;
- }
- }
- }
+ default: {
+ break;
+ }
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VOLUME) {
+ else {
+ /* instance push */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_HAS_VOLUME) {
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect->t);
+ tfar = ssef(isect->t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
- }
- else {
- /* pop */
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
+
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* pop */
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* instance pop */
+ /* instance pop */
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect->t);
+ tfar = ssef(isect->t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_MOTION) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_MOTION) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return (isect->prim != PRIM_NONE);
+ return (isect->prim != PRIM_NONE);
}
ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
@@ -311,29 +304,20 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
Intersection *isect,
const uint visibility)
{
- switch(kernel_data.bvh.bvh_layout) {
+ switch (kernel_data.bvh.bvh_layout) {
#ifdef __KERNEL_AVX2__
- case BVH_LAYOUT_BVH8:
- return BVH_FUNCTION_FULL_NAME(OBVH)(kg,
- ray,
- isect,
- visibility);
+ case BVH_LAYOUT_BVH8:
+ return BVH_FUNCTION_FULL_NAME(OBVH)(kg, ray, isect, visibility);
#endif
#ifdef __QBVH__
- case BVH_LAYOUT_BVH4:
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect,
- visibility);
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg, ray, isect, visibility);
#endif
- case BVH_LAYOUT_BVH2:
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect,
- visibility);
- }
- kernel_assert(!"Should not happen");
- return false;
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg, ray, isect, visibility);
+ }
+ kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_volume_all.h b/intern/cycles/kernel/bvh/bvh_volume_all.h
index f3ca4058460..ae8c4d12e8a 100644
--- a/intern/cycles/kernel/bvh/bvh_volume_all.h
+++ b/intern/cycles/kernel/bvh/bvh_volume_all.h
@@ -19,9 +19,9 @@
#ifdef __QBVH__
# include "kernel/bvh/qbvh_volume_all.h"
-#ifdef __KERNEL_AVX2__
-# include "kernel/bvh/obvh_volume_all.h"
-#endif
+# ifdef __KERNEL_AVX2__
+# include "kernel/bvh/obvh_volume_all.h"
+# endif
#endif
#if BVH_FEATURE(BVH_HAIR)
@@ -43,342 +43,337 @@ ccl_device
#else
ccl_device_inline
#endif
-uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
- const Ray *ray,
- Intersection *isect_array,
- const uint max_hits,
- const uint visibility)
+ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ const uint max_hits,
+ const uint visibility)
{
- /* todo:
- * - test if pushing distance on the stack helps (for non shadow rays)
- * - separate version for shadow rays
- * - likely and unlikely for if() statements
- * - test restrict attribute for pointers
- */
-
- /* traversal stack in CUDA thread-local memory */
- int traversal_stack[BVH_STACK_SIZE];
- traversal_stack[0] = ENTRYPOINT_SENTINEL;
-
- /* traversal variables in registers */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* ray parameters in registers */
- const float tmax = ray->t;
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = tmax;
+ /* todo:
+ * - test if pushing distance on the stack helps (for non shadow rays)
+ * - separate version for shadow rays
+ * - likely and unlikely for if() statements
+ * - test restrict attribute for pointers
+ */
+
+ /* traversal stack in CUDA thread-local memory */
+ int traversal_stack[BVH_STACK_SIZE];
+ traversal_stack[0] = ENTRYPOINT_SENTINEL;
+
+ /* traversal variables in registers */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* ray parameters in registers */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
#if BVH_FEATURE(BVH_INSTANCING)
- int num_hits_in_instance = 0;
+ int num_hits_in_instance = 0;
#endif
- uint num_hits = 0;
- isect_array->t = tmax;
+ uint num_hits = 0;
+ isect_array->t = tmax;
#if defined(__KERNEL_SSE2__)
- const shuffle_swap_t shuf_identity = shuffle_swap_identity();
- const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
- const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
- ssef Psplat[3], idirsplat[3];
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+ ssef Psplat[3], idirsplat[3];
# if BVH_FEATURE(BVH_HAIR)
- ssef tnear(0.0f), tfar(isect_t);
+ ssef tnear(0.0f), tfar(isect_t);
# endif
- shuffle_swap_t shufflexyz[3];
+ shuffle_swap_t shufflexyz[3];
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- ssef tsplat(0.0f, 0.0f, -isect_t, -isect_t);
+ ssef tsplat(0.0f, 0.0f, -isect_t, -isect_t);
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
-#endif /* __KERNEL_SSE2__ */
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+#endif /* __KERNEL_SSE2__ */
- /* traversal loop */
- do {
- do {
- /* traverse internal nodes */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- int node_addr_child1, traverse_mask;
- float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* traversal loop */
+ do {
+ do {
+ /* traverse internal nodes */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ int node_addr_child1, traverse_mask;
+ float dist[2];
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#if !defined(__KERNEL_SSE2__)
- traverse_mask = NODE_INTERSECT(kg,
- P,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
# if BVH_FEATURE(BVH_HAIR)
- dir,
+ dir,
# endif
- idir,
- isect_t,
- node_addr,
- visibility,
- dist);
+ idir,
+ isect_t,
+ node_addr,
+ visibility,
+ dist);
#else // __KERNEL_SSE2__
- traverse_mask = NODE_INTERSECT(kg,
- P,
- dir,
+ traverse_mask = NODE_INTERSECT(kg,
+ P,
+ dir,
# if BVH_FEATURE(BVH_HAIR)
- tnear,
- tfar,
+ tnear,
+ tfar,
# endif
- tsplat,
- Psplat,
- idirsplat,
- shufflexyz,
- node_addr,
- visibility,
- dist);
+ tsplat,
+ Psplat,
+ idirsplat,
+ shufflexyz,
+ node_addr,
+ visibility,
+ dist);
#endif // __KERNEL_SSE2__
- node_addr = __float_as_int(cnodes.z);
- node_addr_child1 = __float_as_int(cnodes.w);
-
- if(traverse_mask == 3) {
- /* Both children were intersected, push the farther one. */
- bool is_closest_child1 = (dist[1] < dist[0]);
- if(is_closest_child1) {
- int tmp = node_addr;
- node_addr = node_addr_child1;
- node_addr_child1 = tmp;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = node_addr_child1;
- }
- else {
- /* One child was intersected. */
- if(traverse_mask == 2) {
- node_addr = node_addr_child1;
- }
- else if(traverse_mask == 0) {
- /* Neither child was intersected. */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
- }
- }
-
- /* if node is leaf, fetch triangle list */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
- int prim_addr = __float_as_int(leaf.x);
+ node_addr = __float_as_int(cnodes.z);
+ node_addr_child1 = __float_as_int(cnodes.w);
+
+ if (traverse_mask == 3) {
+ /* Both children were intersected, push the farther one. */
+ bool is_closest_child1 = (dist[1] < dist[0]);
+ if (is_closest_child1) {
+ int tmp = node_addr;
+ node_addr = node_addr_child1;
+ node_addr_child1 = tmp;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = node_addr_child1;
+ }
+ else {
+ /* One child was intersected. */
+ if (traverse_mask == 2) {
+ node_addr = node_addr_child1;
+ }
+ else if (traverse_mask == 0) {
+ /* Neither child was intersected. */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+ }
+ }
+
+ /* if node is leaf, fetch triangle list */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- const int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- bool hit;
-
- /* pop */
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
-
- /* primitive intersection */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- /* intersect ray against primitive */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- hit = triangle_intersect(kg,
- isect_array,
- P,
- dir,
- visibility,
- object,
- prim_addr);
- if(hit) {
- /* Move on to next entry in intersections array. */
- isect_array++;
- num_hits++;
+ const int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ bool hit;
+
+ /* pop */
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+
+ /* primitive intersection */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* intersect ray against primitive */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
+ if (hit) {
+ /* Move on to next entry in intersections array. */
+ isect_array++;
+ num_hits++;
#if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
#endif
- isect_array->t = isect_t;
- if(num_hits == max_hits) {
+ isect_array->t = isect_t;
+ if (num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
- if(object != OBJECT_NONE) {
+ if (object != OBJECT_NONE) {
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- float t_fac = 1.0f / len(transform_direction(&itfm, dir));
+ Transform itfm = object_fetch_transform(
+ kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
# endif
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
-#endif /* BVH_FEATURE(BVH_INSTANCING) */
- return num_hits;
- }
- }
- }
- break;
- }
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+#endif /* BVH_FEATURE(BVH_INSTANCING) */
+ return num_hits;
+ }
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- /* intersect ray against primitive */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- hit = motion_triangle_intersect(kg,
- isect_array,
- P,
- dir,
- ray->time,
- visibility,
- object,
- prim_addr);
- if(hit) {
- /* Move on to next entry in intersections array. */
- isect_array++;
- num_hits++;
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* intersect ray against primitive */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ hit = motion_triangle_intersect(
+ kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
+ if (hit) {
+ /* Move on to next entry in intersections array. */
+ isect_array++;
+ num_hits++;
# if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
# endif
- isect_array->t = isect_t;
- if(num_hits == max_hits) {
+ isect_array->t = isect_t;
+ if (num_hits == max_hits) {
# if BVH_FEATURE(BVH_INSTANCING)
- if(object != OBJECT_NONE) {
+ if (object != OBJECT_NONE) {
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- float t_fac = 1.0f / len(transform_direction(&itfm, dir));
+ Transform itfm = object_fetch_transform(
+ kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
# endif
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
-# endif /* BVH_FEATURE(BVH_INSTANCING) */
- return num_hits;
- }
- }
- }
- break;
- }
-#endif /* BVH_MOTION */
- default: {
- break;
- }
- }
- }
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+# endif /* BVH_FEATURE(BVH_INSTANCING) */
+ return num_hits;
+ }
+ }
+ }
+ break;
+ }
+#endif /* BVH_MOTION */
+ default: {
+ break;
+ }
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VOLUME) {
+ else {
+ /* instance push */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_HAS_VOLUME) {
# if BVH_FEATURE(BVH_MOTION)
- isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
+ isect_t = bvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
# else
- isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
# endif
- num_hits_in_instance = 0;
- isect_array->t = isect_t;
+ num_hits_in_instance = 0;
+ isect_array->t = isect_t;
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
+ tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect_t);
+ tfar = ssef(isect_t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_STACK_SIZE);
- traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
- }
- else {
- /* pop */
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_STACK_SIZE);
+ traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
+
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* pop */
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
- if(num_hits_in_instance) {
- float t_fac;
+ /* Instance pop. */
+ if (num_hits_in_instance) {
+ float t_fac;
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
# else
- bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
# endif
- /* Scale isect->t to adjust for instancing. */
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
- else {
+ /* Scale isect->t to adjust for instancing. */
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+ else {
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
# else
- bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
# endif
- }
+ }
- isect_t = tmax;
- isect_array->t = isect_t;
+ isect_t = tmax;
+ isect_array->t = isect_t;
# if defined(__KERNEL_SSE2__)
- Psplat[0] = ssef(P.x);
- Psplat[1] = ssef(P.y);
- Psplat[2] = ssef(P.z);
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
- tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
+ tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
# if BVH_FEATURE(BVH_HAIR)
- tfar = ssef(isect_t);
+ tfar = ssef(isect_t);
# endif
- gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr];
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr];
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return num_hits;
+ return num_hits;
}
ccl_device_inline uint BVH_FUNCTION_NAME(KernelGlobals *kg,
@@ -387,32 +382,20 @@ ccl_device_inline uint BVH_FUNCTION_NAME(KernelGlobals *kg,
const uint max_hits,
const uint visibility)
{
- switch(kernel_data.bvh.bvh_layout) {
+ switch (kernel_data.bvh.bvh_layout) {
#ifdef __KERNEL_AVX2__
- case BVH_LAYOUT_BVH8:
- return BVH_FUNCTION_FULL_NAME(OBVH)(kg,
- ray,
- isect_array,
- max_hits,
- visibility);
+ case BVH_LAYOUT_BVH8:
+ return BVH_FUNCTION_FULL_NAME(OBVH)(kg, ray, isect_array, max_hits, visibility);
#endif
#ifdef __QBVH__
- case BVH_LAYOUT_BVH4:
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect_array,
- max_hits,
- visibility);
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg, ray, isect_array, max_hits, visibility);
#endif
- case BVH_LAYOUT_BVH2:
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect_array,
- max_hits,
- visibility);
- }
- kernel_assert(!"Should not happen");
- return 0;
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg, ray, isect_array, max_hits, visibility);
+ }
+ kernel_assert(!"Should not happen");
+ return 0;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/obvh_local.h b/intern/cycles/kernel/bvh/obvh_local.h
index f449cefb335..e6bb548bc5b 100644
--- a/intern/cycles/kernel/bvh/obvh_local.h
+++ b/intern/cycles/kernel/bvh/obvh_local.h
@@ -34,372 +34,365 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
uint *lcg_state,
int max_hits)
{
- /* Traversal stack in CUDA thread-local memory. */
- OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+ /* Traversal stack in CUDA thread-local memory. */
+ OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_tex_fetch(__object_node, local_object);
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_tex_fetch(__object_node, local_object);
- /* Ray parameters in registers. */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = ray->t;
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = ray->t;
- if(local_isect != NULL) {
- local_isect->num_hits = 0;
- }
- kernel_assert((local_isect == NULL) == (max_hits == 0));
+ if (local_isect != NULL) {
+ local_isect->num_hits = 0;
+ }
+ kernel_assert((local_isect == NULL) == (max_hits == 0));
- const int object_flag = kernel_tex_fetch(__object_flag, local_object);
- if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ const int object_flag = kernel_tex_fetch(__object_flag, local_object);
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
- isect_t = bvh_instance_motion_push(kg,
- local_object,
- ray,
- &P,
- &dir,
- &idir,
- isect_t,
- &ob_itfm);
+ Transform ob_itfm;
+ isect_t = bvh_instance_motion_push(kg, local_object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
#else
- isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
#endif
- object = local_object;
- }
+ object = local_object;
+ }
- avxf tnear(0.0f), tfar(isect_t);
+ avxf tnear(0.0f), tfar(isect_t);
#if BVH_FEATURE(BVH_HAIR)
- avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
#endif
- avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
+ avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- avxf dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ avxf dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
- if(child_mask != 0) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- avxf cnodes;
+ if (child_mask != 0) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ avxf cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+26);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 26);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+14);
- }
+ {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 14);
+ }
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
- /* Five children are hit, push all onto stack and sort 5
- * stack items, continue with closest child
- */
- r = __bscf(child_mask);
- int c4 = __float_as_int(cnodes[r]);
- float d4 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
- /* Six children are hit, push all onto stack and sort 6
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c5 = __float_as_int(cnodes[r]);
- float d5 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ /* Five children are hit, push all onto stack and sort 5
+ * stack items, continue with closest child
+ */
+ r = __bscf(child_mask);
+ int c4 = __float_as_int(cnodes[r]);
+ float d4 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+ /* Six children are hit, push all onto stack and sort 6
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c5 = __float_as_int(cnodes[r]);
+ float d5 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
- /* Seven children are hit, push all onto stack and sort 7
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c6 = __float_as_int(cnodes[r]);
- float d6 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
- /* Eight children are hit, push all onto stack and sort 8
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c7 = __float_as_int(cnodes[r]);
- float d7 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c7;
- traversal_stack[stack_ptr].dist = d7;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6],
- &traversal_stack[stack_ptr - 7]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ /* Seven children are hit, push all onto stack and sort 7
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c6 = __float_as_int(cnodes[r]);
+ float d6 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+ /* Eight children are hit, push all onto stack and sort 8
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c7 = __float_as_int(cnodes[r]);
+ float d7 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c7;
+ traversal_stack[stack_ptr].dist = d7;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6],
+ &traversal_stack[stack_ptr - 7]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
- int prim_addr = __float_as_int(leaf.x);
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ int prim_addr = __float_as_int(leaf.x);
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
- /* Primitive intersection. */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- /* Intersect ray against primitive, */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits))
- {
- return true;
- }
- }
- break;
- }
+ /* Primitive intersection. */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* Intersect ray against primitive, */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- /* Intersect ray against primitive. */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(motion_triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- ray->time,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits))
- {
- return true;
- }
- }
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* Intersect ray against primitive. */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (motion_triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ ray->time,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
+ }
+ break;
+ }
#endif
- default:
- break;
- }
- }
- } while(node_addr != ENTRYPOINT_SENTINEL);
- } while(node_addr != ENTRYPOINT_SENTINEL);
- return false;
+ default:
+ break;
+ }
+ }
+ } while (node_addr != ENTRYPOINT_SENTINEL);
+ } while (node_addr != ENTRYPOINT_SENTINEL);
+ return false;
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/obvh_nodes.h b/intern/cycles/kernel/bvh/obvh_nodes.h
index 93f35f6dffb..6831562cade 100644
--- a/intern/cycles/kernel/bvh/obvh_nodes.h
+++ b/intern/cycles/kernel/bvh/obvh_nodes.h
@@ -17,11 +17,11 @@
*/
struct OBVHStackItem {
- int addr;
- float dist;
+ int addr;
+ float dist;
};
-ccl_device_inline void obvh_near_far_idx_calc(const float3& idir,
+ccl_device_inline void obvh_near_far_idx_calc(const float3 &idir,
int *ccl_restrict near_x,
int *ccl_restrict near_y,
int *ccl_restrict near_z,
@@ -31,41 +31,73 @@ ccl_device_inline void obvh_near_far_idx_calc(const float3& idir,
{
#ifdef __KERNEL_SSE__
- *near_x = 0; *far_x = 1;
- *near_y = 2; *far_y = 3;
- *near_z = 4; *far_z = 5;
-
- const size_t mask = movemask(ssef(idir.m128));
-
- const int mask_x = mask & 1;
- const int mask_y = (mask & 2) >> 1;
- const int mask_z = (mask & 4) >> 2;
-
- *near_x += mask_x; *far_x -= mask_x;
- *near_y += mask_y; *far_y -= mask_y;
- *near_z += mask_z; *far_z -= mask_z;
+ *near_x = 0;
+ *far_x = 1;
+ *near_y = 2;
+ *far_y = 3;
+ *near_z = 4;
+ *far_z = 5;
+
+ const size_t mask = movemask(ssef(idir.m128));
+
+ const int mask_x = mask & 1;
+ const int mask_y = (mask & 2) >> 1;
+ const int mask_z = (mask & 4) >> 2;
+
+ *near_x += mask_x;
+ *far_x -= mask_x;
+ *near_y += mask_y;
+ *far_y -= mask_y;
+ *near_z += mask_z;
+ *far_z -= mask_z;
#else
- if(idir.x >= 0.0f) { *near_x = 0; *far_x = 1; } else { *near_x = 1; *far_x = 0; }
- if(idir.y >= 0.0f) { *near_y = 2; *far_y = 3; } else { *near_y = 3; *far_y = 2; }
- if(idir.z >= 0.0f) { *near_z = 4; *far_z = 5; } else { *near_z = 5; *far_z = 4; }
+ if (idir.x >= 0.0f) {
+ *near_x = 0;
+ *far_x = 1;
+ }
+ else {
+ *near_x = 1;
+ *far_x = 0;
+ }
+ if (idir.y >= 0.0f) {
+ *near_y = 2;
+ *far_y = 3;
+ }
+ else {
+ *near_y = 3;
+ *far_y = 2;
+ }
+ if (idir.z >= 0.0f) {
+ *near_z = 4;
+ *far_z = 5;
+ }
+ else {
+ *near_z = 5;
+ *far_z = 4;
+ }
#endif
}
-ccl_device_inline void obvh_item_swap(OBVHStackItem *ccl_restrict a,
- OBVHStackItem *ccl_restrict b)
+ccl_device_inline void obvh_item_swap(OBVHStackItem *ccl_restrict a, OBVHStackItem *ccl_restrict b)
{
- OBVHStackItem tmp = *a;
- *a = *b;
- *b = tmp;
+ OBVHStackItem tmp = *a;
+ *a = *b;
+ *b = tmp;
}
ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
OBVHStackItem *ccl_restrict s2,
OBVHStackItem *ccl_restrict s3)
{
- if(s2->dist < s1->dist) { obvh_item_swap(s2, s1); }
- if(s3->dist < s2->dist) { obvh_item_swap(s3, s2); }
- if(s2->dist < s1->dist) { obvh_item_swap(s2, s1); }
+ if (s2->dist < s1->dist) {
+ obvh_item_swap(s2, s1);
+ }
+ if (s3->dist < s2->dist) {
+ obvh_item_swap(s3, s2);
+ }
+ if (s2->dist < s1->dist) {
+ obvh_item_swap(s2, s1);
+ }
}
ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
@@ -73,11 +105,21 @@ ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
OBVHStackItem *ccl_restrict s3,
OBVHStackItem *ccl_restrict s4)
{
- if(s2->dist < s1->dist) { obvh_item_swap(s2, s1); }
- if(s4->dist < s3->dist) { obvh_item_swap(s4, s3); }
- if(s3->dist < s1->dist) { obvh_item_swap(s3, s1); }
- if(s4->dist < s2->dist) { obvh_item_swap(s4, s2); }
- if(s3->dist < s2->dist) { obvh_item_swap(s3, s2); }
+ if (s2->dist < s1->dist) {
+ obvh_item_swap(s2, s1);
+ }
+ if (s4->dist < s3->dist) {
+ obvh_item_swap(s4, s3);
+ }
+ if (s3->dist < s1->dist) {
+ obvh_item_swap(s3, s1);
+ }
+ if (s4->dist < s2->dist) {
+ obvh_item_swap(s4, s2);
+ }
+ if (s3->dist < s2->dist) {
+ obvh_item_swap(s3, s2);
+ }
}
ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
@@ -86,19 +128,19 @@ ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
OBVHStackItem *ccl_restrict s4,
OBVHStackItem *ccl_restrict s5)
{
- obvh_stack_sort(s1, s2, s3, s4);
- if(s5->dist < s4->dist) {
- obvh_item_swap(s4, s5);
- if(s4->dist < s3->dist) {
- obvh_item_swap(s3, s4);
- if(s3->dist < s2->dist) {
- obvh_item_swap(s2, s3);
- if(s2->dist < s1->dist) {
- obvh_item_swap(s1, s2);
- }
- }
- }
- }
+ obvh_stack_sort(s1, s2, s3, s4);
+ if (s5->dist < s4->dist) {
+ obvh_item_swap(s4, s5);
+ if (s4->dist < s3->dist) {
+ obvh_item_swap(s3, s4);
+ if (s3->dist < s2->dist) {
+ obvh_item_swap(s2, s3);
+ if (s2->dist < s1->dist) {
+ obvh_item_swap(s1, s2);
+ }
+ }
+ }
+ }
}
ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
@@ -108,22 +150,22 @@ ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
OBVHStackItem *ccl_restrict s5,
OBVHStackItem *ccl_restrict s6)
{
- obvh_stack_sort(s1, s2, s3, s4, s5);
- if(s6->dist < s5->dist) {
- obvh_item_swap(s5, s6);
- if(s5->dist < s4->dist) {
- obvh_item_swap(s4, s5);
- if(s4->dist < s3->dist) {
- obvh_item_swap(s3, s4);
- if(s3->dist < s2->dist) {
- obvh_item_swap(s2, s3);
- if(s2->dist < s1->dist) {
- obvh_item_swap(s1, s2);
- }
- }
- }
- }
- }
+ obvh_stack_sort(s1, s2, s3, s4, s5);
+ if (s6->dist < s5->dist) {
+ obvh_item_swap(s5, s6);
+ if (s5->dist < s4->dist) {
+ obvh_item_swap(s4, s5);
+ if (s4->dist < s3->dist) {
+ obvh_item_swap(s3, s4);
+ if (s3->dist < s2->dist) {
+ obvh_item_swap(s2, s3);
+ if (s2->dist < s1->dist) {
+ obvh_item_swap(s1, s2);
+ }
+ }
+ }
+ }
+ }
}
ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
@@ -134,25 +176,25 @@ ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
OBVHStackItem *ccl_restrict s6,
OBVHStackItem *ccl_restrict s7)
{
- obvh_stack_sort(s1, s2, s3, s4, s5, s6);
- if(s7->dist < s6->dist) {
- obvh_item_swap(s6, s7);
- if(s6->dist < s5->dist) {
- obvh_item_swap(s5, s6);
- if(s5->dist < s4->dist) {
- obvh_item_swap(s4, s5);
- if(s4->dist < s3->dist) {
- obvh_item_swap(s3, s4);
- if(s3->dist < s2->dist) {
- obvh_item_swap(s2, s3);
- if(s2->dist < s1->dist) {
- obvh_item_swap(s1, s2);
- }
- }
- }
- }
- }
- }
+ obvh_stack_sort(s1, s2, s3, s4, s5, s6);
+ if (s7->dist < s6->dist) {
+ obvh_item_swap(s6, s7);
+ if (s6->dist < s5->dist) {
+ obvh_item_swap(s5, s6);
+ if (s5->dist < s4->dist) {
+ obvh_item_swap(s4, s5);
+ if (s4->dist < s3->dist) {
+ obvh_item_swap(s3, s4);
+ if (s3->dist < s2->dist) {
+ obvh_item_swap(s2, s3);
+ if (s2->dist < s1->dist) {
+ obvh_item_swap(s1, s2);
+ }
+ }
+ }
+ }
+ }
+ }
}
ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
@@ -164,41 +206,41 @@ ccl_device_inline void obvh_stack_sort(OBVHStackItem *ccl_restrict s1,
OBVHStackItem *ccl_restrict s7,
OBVHStackItem *ccl_restrict s8)
{
- obvh_stack_sort(s1, s2, s3, s4, s5, s6, s7);
- if(s8->dist < s7->dist) {
- obvh_item_swap(s7, s8);
- if(s7->dist < s6->dist) {
- obvh_item_swap(s6, s7);
- if(s6->dist < s5->dist) {
- obvh_item_swap(s5, s6);
- if(s5->dist < s4->dist) {
- obvh_item_swap(s4, s5);
- if(s4->dist < s3->dist) {
- obvh_item_swap(s3, s4);
- if(s3->dist < s2->dist) {
- obvh_item_swap(s2, s3);
- if(s2->dist < s1->dist) {
- obvh_item_swap(s1, s2);
- }
- }
- }
- }
- }
- }
- }
+ obvh_stack_sort(s1, s2, s3, s4, s5, s6, s7);
+ if (s8->dist < s7->dist) {
+ obvh_item_swap(s7, s8);
+ if (s7->dist < s6->dist) {
+ obvh_item_swap(s6, s7);
+ if (s6->dist < s5->dist) {
+ obvh_item_swap(s5, s6);
+ if (s5->dist < s4->dist) {
+ obvh_item_swap(s4, s5);
+ if (s4->dist < s3->dist) {
+ obvh_item_swap(s3, s4);
+ if (s3->dist < s2->dist) {
+ obvh_item_swap(s2, s3);
+ if (s2->dist < s1->dist) {
+ obvh_item_swap(s1, s2);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
/* Axis-aligned nodes intersection */
ccl_device_inline int obvh_aligned_node_intersect(KernelGlobals *ccl_restrict kg,
- const avxf& isect_near,
- const avxf& isect_far,
+ const avxf &isect_near,
+ const avxf &isect_far,
#ifdef __KERNEL_AVX2__
- const avx3f& org_idir,
+ const avx3f &org_idir,
#else
- const avx3f& org,
+ const avx3f &org,
#endif
- const avx3f& idir,
+ const avx3f &idir,
const int near_x,
const int near_y,
const int near_z,
@@ -208,213 +250,216 @@ ccl_device_inline int obvh_aligned_node_intersect(KernelGlobals *ccl_restrict kg
const int node_addr,
avxf *ccl_restrict dist)
{
- const int offset = node_addr + 2;
+ const int offset = node_addr + 2;
#ifdef __KERNEL_AVX2__
- const avxf tnear_x = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset+near_x*2), idir.x, org_idir.x);
- const avxf tnear_y = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset+near_y*2), idir.y, org_idir.y);
- const avxf tnear_z = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset+near_z*2), idir.z, org_idir.z);
- const avxf tfar_x = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset+far_x*2), idir.x, org_idir.x);
- const avxf tfar_y = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset+far_y*2), idir.y, org_idir.y);
- const avxf tfar_z = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset+far_z*2), idir.z, org_idir.z);
-
- const avxf tnear = max4(tnear_x, tnear_y, tnear_z, isect_near);
- const avxf tfar = min4(tfar_x, tfar_y, tfar_z, isect_far);
- const avxb vmask = tnear <= tfar;
- int mask = (int)movemask(vmask);
- *dist = tnear;
- return mask;
+ const avxf tnear_x = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + near_x * 2), idir.x, org_idir.x);
+ const avxf tnear_y = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + near_y * 2), idir.y, org_idir.y);
+ const avxf tnear_z = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + near_z * 2), idir.z, org_idir.z);
+ const avxf tfar_x = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + far_x * 2), idir.x, org_idir.x);
+ const avxf tfar_y = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + far_y * 2), idir.y, org_idir.y);
+ const avxf tfar_z = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + far_z * 2), idir.z, org_idir.z);
+
+ const avxf tnear = max4(tnear_x, tnear_y, tnear_z, isect_near);
+ const avxf tfar = min4(tfar_x, tfar_y, tfar_z, isect_far);
+ const avxb vmask = tnear <= tfar;
+ int mask = (int)movemask(vmask);
+ *dist = tnear;
+ return mask;
#else
- return 0;
+ return 0;
#endif
}
-ccl_device_inline int obvh_aligned_node_intersect_robust(
- KernelGlobals *ccl_restrict kg,
- const avxf& isect_near,
- const avxf& isect_far,
+ccl_device_inline int obvh_aligned_node_intersect_robust(KernelGlobals *ccl_restrict kg,
+ const avxf &isect_near,
+ const avxf &isect_far,
#ifdef __KERNEL_AVX2__
- const avx3f& P_idir,
+ const avx3f &P_idir,
#else
- const avx3f& P,
+ const avx3f &P,
#endif
- const avx3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- const float difl,
- avxf *ccl_restrict dist)
+ const avx3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ const float difl,
+ avxf *ccl_restrict dist)
{
- const int offset = node_addr + 2;
+ const int offset = node_addr + 2;
#ifdef __KERNEL_AVX2__
- const avxf tnear_x = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset + near_x * 2), idir.x, P_idir.x);
- const avxf tfar_x = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset + far_x * 2), idir.x, P_idir.x);
- const avxf tnear_y = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset + near_y * 2), idir.y, P_idir.y);
- const avxf tfar_y = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset + far_y * 2), idir.y, P_idir.y);
- const avxf tnear_z = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset + near_z * 2), idir.z, P_idir.z);
- const avxf tfar_z = msub(kernel_tex_fetch_avxf(__bvh_nodes, offset + far_z * 2), idir.z, P_idir.z);
-
- const float round_down = 1.0f - difl;
- const float round_up = 1.0f + difl;
- const avxf tnear = max4(tnear_x, tnear_y, tnear_z, isect_near);
- const avxf tfar = min4(tfar_x, tfar_y, tfar_z, isect_far);
- const avxb vmask = round_down*tnear <= round_up*tfar;
- int mask = (int)movemask(vmask);
- *dist = tnear;
- return mask;
+ const avxf tnear_x = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + near_x * 2), idir.x, P_idir.x);
+ const avxf tfar_x = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + far_x * 2), idir.x, P_idir.x);
+ const avxf tnear_y = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + near_y * 2), idir.y, P_idir.y);
+ const avxf tfar_y = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + far_y * 2), idir.y, P_idir.y);
+ const avxf tnear_z = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + near_z * 2), idir.z, P_idir.z);
+ const avxf tfar_z = msub(
+ kernel_tex_fetch_avxf(__bvh_nodes, offset + far_z * 2), idir.z, P_idir.z);
+
+ const float round_down = 1.0f - difl;
+ const float round_up = 1.0f + difl;
+ const avxf tnear = max4(tnear_x, tnear_y, tnear_z, isect_near);
+ const avxf tfar = min4(tfar_x, tfar_y, tfar_z, isect_far);
+ const avxb vmask = round_down * tnear <= round_up * tfar;
+ int mask = (int)movemask(vmask);
+ *dist = tnear;
+ return mask;
#else
- return 0;
+ return 0;
#endif
}
/* Unaligned nodes intersection */
-ccl_device_inline int obvh_unaligned_node_intersect(
- KernelGlobals *ccl_restrict kg,
- const avxf& isect_near,
- const avxf& isect_far,
+ccl_device_inline int obvh_unaligned_node_intersect(KernelGlobals *ccl_restrict kg,
+ const avxf &isect_near,
+ const avxf &isect_far,
#ifdef __KERNEL_AVX2__
- const avx3f& org_idir,
+ const avx3f &org_idir,
#endif
- const avx3f& org,
- const avx3f& dir,
- const avx3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- avxf *ccl_restrict dist)
+ const avx3f &org,
+ const avx3f &dir,
+ const avx3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ avxf *ccl_restrict dist)
{
- const int offset = node_addr;
- const avxf tfm_x_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+2);
- const avxf tfm_x_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+4);
- const avxf tfm_x_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+6);
-
- const avxf tfm_y_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+8);
- const avxf tfm_y_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+10);
- const avxf tfm_y_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+12);
-
- const avxf tfm_z_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+14);
- const avxf tfm_z_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+16);
- const avxf tfm_z_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+18);
-
- const avxf tfm_t_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+20);
- const avxf tfm_t_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+22);
- const avxf tfm_t_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+24);
-
- const avxf aligned_dir_x = dir.x*tfm_x_x + dir.y*tfm_x_y + dir.z*tfm_x_z,
- aligned_dir_y = dir.x*tfm_y_x + dir.y*tfm_y_y + dir.z*tfm_y_z,
- aligned_dir_z = dir.x*tfm_z_x + dir.y*tfm_z_y + dir.z*tfm_z_z;
-
- const avxf aligned_P_x = org.x*tfm_x_x + org.y*tfm_x_y + org.z*tfm_x_z + tfm_t_x,
- aligned_P_y = org.x*tfm_y_x + org.y*tfm_y_y + org.z*tfm_y_z + tfm_t_y,
- aligned_P_z = org.x*tfm_z_x + org.y*tfm_z_y + org.z*tfm_z_z + tfm_t_z;
-
- const avxf neg_one(-1.0f);
- const avxf nrdir_x = neg_one / aligned_dir_x,
- nrdir_y = neg_one / aligned_dir_y,
- nrdir_z = neg_one / aligned_dir_z;
-
- const avxf tlower_x = aligned_P_x * nrdir_x,
- tlower_y = aligned_P_y * nrdir_y,
- tlower_z = aligned_P_z * nrdir_z;
-
- const avxf tupper_x = tlower_x - nrdir_x,
- tupper_y = tlower_y - nrdir_y,
- tupper_z = tlower_z - nrdir_z;
-
- const avxf tnear_x = min(tlower_x, tupper_x);
- const avxf tnear_y = min(tlower_y, tupper_y);
- const avxf tnear_z = min(tlower_z, tupper_z);
- const avxf tfar_x = max(tlower_x, tupper_x);
- const avxf tfar_y = max(tlower_y, tupper_y);
- const avxf tfar_z = max(tlower_z, tupper_z);
- const avxf tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const avxf tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- const avxb vmask = tnear <= tfar;
- *dist = tnear;
- return movemask(vmask);
+ const int offset = node_addr;
+ const avxf tfm_x_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 2);
+ const avxf tfm_x_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 4);
+ const avxf tfm_x_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 6);
+
+ const avxf tfm_y_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 8);
+ const avxf tfm_y_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 10);
+ const avxf tfm_y_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 12);
+
+ const avxf tfm_z_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 14);
+ const avxf tfm_z_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 16);
+ const avxf tfm_z_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 18);
+
+ const avxf tfm_t_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 20);
+ const avxf tfm_t_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 22);
+ const avxf tfm_t_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 24);
+
+ const avxf aligned_dir_x = dir.x * tfm_x_x + dir.y * tfm_x_y + dir.z * tfm_x_z,
+ aligned_dir_y = dir.x * tfm_y_x + dir.y * tfm_y_y + dir.z * tfm_y_z,
+ aligned_dir_z = dir.x * tfm_z_x + dir.y * tfm_z_y + dir.z * tfm_z_z;
+
+ const avxf aligned_P_x = org.x * tfm_x_x + org.y * tfm_x_y + org.z * tfm_x_z + tfm_t_x,
+ aligned_P_y = org.x * tfm_y_x + org.y * tfm_y_y + org.z * tfm_y_z + tfm_t_y,
+ aligned_P_z = org.x * tfm_z_x + org.y * tfm_z_y + org.z * tfm_z_z + tfm_t_z;
+
+ const avxf neg_one(-1.0f);
+ const avxf nrdir_x = neg_one / aligned_dir_x, nrdir_y = neg_one / aligned_dir_y,
+ nrdir_z = neg_one / aligned_dir_z;
+
+ const avxf tlower_x = aligned_P_x * nrdir_x, tlower_y = aligned_P_y * nrdir_y,
+ tlower_z = aligned_P_z * nrdir_z;
+
+ const avxf tupper_x = tlower_x - nrdir_x, tupper_y = tlower_y - nrdir_y,
+ tupper_z = tlower_z - nrdir_z;
+
+ const avxf tnear_x = min(tlower_x, tupper_x);
+ const avxf tnear_y = min(tlower_y, tupper_y);
+ const avxf tnear_z = min(tlower_z, tupper_z);
+ const avxf tfar_x = max(tlower_x, tupper_x);
+ const avxf tfar_y = max(tlower_y, tupper_y);
+ const avxf tfar_z = max(tlower_z, tupper_z);
+ const avxf tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const avxf tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ const avxb vmask = tnear <= tfar;
+ *dist = tnear;
+ return movemask(vmask);
}
-ccl_device_inline int obvh_unaligned_node_intersect_robust(
- KernelGlobals *ccl_restrict kg,
- const avxf& isect_near,
- const avxf& isect_far,
+ccl_device_inline int obvh_unaligned_node_intersect_robust(KernelGlobals *ccl_restrict kg,
+ const avxf &isect_near,
+ const avxf &isect_far,
#ifdef __KERNEL_AVX2__
- const avx3f& P_idir,
+ const avx3f &P_idir,
#endif
- const avx3f& P,
- const avx3f& dir,
- const avx3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- const float difl,
- avxf *ccl_restrict dist)
+ const avx3f &P,
+ const avx3f &dir,
+ const avx3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ const float difl,
+ avxf *ccl_restrict dist)
{
- const int offset = node_addr;
- const avxf tfm_x_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+2);
- const avxf tfm_x_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+4);
- const avxf tfm_x_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+6);
-
- const avxf tfm_y_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+8);
- const avxf tfm_y_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+10);
- const avxf tfm_y_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+12);
-
- const avxf tfm_z_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+14);
- const avxf tfm_z_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+16);
- const avxf tfm_z_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+18);
-
- const avxf tfm_t_x = kernel_tex_fetch_avxf(__bvh_nodes, offset+20);
- const avxf tfm_t_y = kernel_tex_fetch_avxf(__bvh_nodes, offset+22);
- const avxf tfm_t_z = kernel_tex_fetch_avxf(__bvh_nodes, offset+24);
-
- const avxf aligned_dir_x = dir.x*tfm_x_x + dir.y*tfm_x_y + dir.z*tfm_x_z,
- aligned_dir_y = dir.x*tfm_y_x + dir.y*tfm_y_y + dir.z*tfm_y_z,
- aligned_dir_z = dir.x*tfm_z_x + dir.y*tfm_z_y + dir.z*tfm_z_z;
-
- const avxf aligned_P_x = P.x*tfm_x_x + P.y*tfm_x_y + P.z*tfm_x_z + tfm_t_x,
- aligned_P_y = P.x*tfm_y_x + P.y*tfm_y_y + P.z*tfm_y_z + tfm_t_y,
- aligned_P_z = P.x*tfm_z_x + P.y*tfm_z_y + P.z*tfm_z_z + tfm_t_z;
-
- const avxf neg_one(-1.0f);
- const avxf nrdir_x = neg_one / aligned_dir_x,
- nrdir_y = neg_one / aligned_dir_y,
- nrdir_z = neg_one / aligned_dir_z;
-
- const avxf tlower_x = aligned_P_x * nrdir_x,
- tlower_y = aligned_P_y * nrdir_y,
- tlower_z = aligned_P_z * nrdir_z;
-
- const avxf tupper_x = tlower_x - nrdir_x,
- tupper_y = tlower_y - nrdir_y,
- tupper_z = tlower_z - nrdir_z;
-
- const float round_down = 1.0f - difl;
- const float round_up = 1.0f + difl;
-
- const avxf tnear_x = min(tlower_x, tupper_x);
- const avxf tnear_y = min(tlower_y, tupper_y);
- const avxf tnear_z = min(tlower_z, tupper_z);
- const avxf tfar_x = max(tlower_x, tupper_x);
- const avxf tfar_y = max(tlower_y, tupper_y);
- const avxf tfar_z = max(tlower_z, tupper_z);
-
- const avxf tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const avxf tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- const avxb vmask = round_down*tnear <= round_up*tfar;
- *dist = tnear;
- return movemask(vmask);
+ const int offset = node_addr;
+ const avxf tfm_x_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 2);
+ const avxf tfm_x_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 4);
+ const avxf tfm_x_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 6);
+
+ const avxf tfm_y_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 8);
+ const avxf tfm_y_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 10);
+ const avxf tfm_y_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 12);
+
+ const avxf tfm_z_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 14);
+ const avxf tfm_z_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 16);
+ const avxf tfm_z_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 18);
+
+ const avxf tfm_t_x = kernel_tex_fetch_avxf(__bvh_nodes, offset + 20);
+ const avxf tfm_t_y = kernel_tex_fetch_avxf(__bvh_nodes, offset + 22);
+ const avxf tfm_t_z = kernel_tex_fetch_avxf(__bvh_nodes, offset + 24);
+
+ const avxf aligned_dir_x = dir.x * tfm_x_x + dir.y * tfm_x_y + dir.z * tfm_x_z,
+ aligned_dir_y = dir.x * tfm_y_x + dir.y * tfm_y_y + dir.z * tfm_y_z,
+ aligned_dir_z = dir.x * tfm_z_x + dir.y * tfm_z_y + dir.z * tfm_z_z;
+
+ const avxf aligned_P_x = P.x * tfm_x_x + P.y * tfm_x_y + P.z * tfm_x_z + tfm_t_x,
+ aligned_P_y = P.x * tfm_y_x + P.y * tfm_y_y + P.z * tfm_y_z + tfm_t_y,
+ aligned_P_z = P.x * tfm_z_x + P.y * tfm_z_y + P.z * tfm_z_z + tfm_t_z;
+
+ const avxf neg_one(-1.0f);
+ const avxf nrdir_x = neg_one / aligned_dir_x, nrdir_y = neg_one / aligned_dir_y,
+ nrdir_z = neg_one / aligned_dir_z;
+
+ const avxf tlower_x = aligned_P_x * nrdir_x, tlower_y = aligned_P_y * nrdir_y,
+ tlower_z = aligned_P_z * nrdir_z;
+
+ const avxf tupper_x = tlower_x - nrdir_x, tupper_y = tlower_y - nrdir_y,
+ tupper_z = tlower_z - nrdir_z;
+
+ const float round_down = 1.0f - difl;
+ const float round_up = 1.0f + difl;
+
+ const avxf tnear_x = min(tlower_x, tupper_x);
+ const avxf tnear_y = min(tlower_y, tupper_y);
+ const avxf tnear_z = min(tlower_z, tupper_z);
+ const avxf tfar_x = max(tlower_x, tupper_x);
+ const avxf tfar_y = max(tlower_y, tupper_y);
+ const avxf tfar_z = max(tlower_z, tupper_z);
+
+ const avxf tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const avxf tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ const avxb vmask = round_down * tnear <= round_up * tfar;
+ *dist = tnear;
+ return movemask(vmask);
}
/* Intersectors wrappers.
@@ -422,111 +467,125 @@ ccl_device_inline int obvh_unaligned_node_intersect_robust(
* They'll check node type and call appropriate intersection code.
*/
-ccl_device_inline int obvh_node_intersect(
- KernelGlobals *ccl_restrict kg,
- const avxf& isect_near,
- const avxf& isect_far,
+ccl_device_inline int obvh_node_intersect(KernelGlobals *ccl_restrict kg,
+ const avxf &isect_near,
+ const avxf &isect_far,
#ifdef __KERNEL_AVX2__
- const avx3f& org_idir,
+ const avx3f &org_idir,
#endif
- const avx3f& org,
- const avx3f& dir,
- const avx3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- avxf *ccl_restrict dist)
+ const avx3f &org,
+ const avx3f &dir,
+ const avx3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ avxf *ccl_restrict dist)
{
- const int offset = node_addr;
- const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return obvh_unaligned_node_intersect(kg,
- isect_near,
- isect_far,
+ const int offset = node_addr;
+ const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return obvh_unaligned_node_intersect(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- org_idir,
+ org_idir,
#endif
- org,
- dir,
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- dist);
- }
- else {
- return obvh_aligned_node_intersect(kg,
- isect_near,
- isect_far,
+ org,
+ dir,
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ dist);
+ }
+ else {
+ return obvh_aligned_node_intersect(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- org_idir,
+ org_idir,
#else
- org,
+ org,
#endif
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- dist);
- }
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ dist);
+ }
}
-ccl_device_inline int obvh_node_intersect_robust(
- KernelGlobals *ccl_restrict kg,
- const avxf& isect_near,
- const avxf& isect_far,
+ccl_device_inline int obvh_node_intersect_robust(KernelGlobals *ccl_restrict kg,
+ const avxf &isect_near,
+ const avxf &isect_far,
#ifdef __KERNEL_AVX2__
- const avx3f& P_idir,
+ const avx3f &P_idir,
#endif
- const avx3f& P,
- const avx3f& dir,
- const avx3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- const float difl,
- avxf *ccl_restrict dist)
+ const avx3f &P,
+ const avx3f &dir,
+ const avx3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ const float difl,
+ avxf *ccl_restrict dist)
{
- const int offset = node_addr;
- const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return obvh_unaligned_node_intersect_robust(kg,
- isect_near,
- isect_far,
+ const int offset = node_addr;
+ const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return obvh_unaligned_node_intersect_robust(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- P_idir,
+ P_idir,
#endif
- P,
- dir,
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- difl,
- dist);
- }
- else {
- return obvh_aligned_node_intersect_robust(kg,
- isect_near,
- isect_far,
+ P,
+ dir,
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ difl,
+ dist);
+ }
+ else {
+ return obvh_aligned_node_intersect_robust(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- P_idir,
+ P_idir,
#else
- P,
+ P,
#endif
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- difl,
- dist);
- }
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ difl,
+ dist);
+ }
}
diff --git a/intern/cycles/kernel/bvh/obvh_shadow_all.h b/intern/cycles/kernel/bvh/obvh_shadow_all.h
index 10d5422c31c..98efb003788 100644
--- a/intern/cycles/kernel/bvh/obvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/obvh_shadow_all.h
@@ -36,645 +36,635 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
const uint max_hits,
uint *num_hits)
{
- /* TODO(sergey):
- * - Test if pushing distance on the stack helps.
- * - Likely and unlikely for if() statements.
- * - Test restrict attribute for pointers.
- */
-
- /* Traversal stack in CUDA thread-local memory. */
- OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
-
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* Ray parameters in registers. */
- const float tmax = ray->t;
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = tmax;
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps.
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- *num_hits = 0;
- isect_array->t = tmax;
+ *num_hits = 0;
+ isect_array->t = tmax;
#if BVH_FEATURE(BVH_INSTANCING)
- int num_hits_in_instance = 0;
+ int num_hits_in_instance = 0;
#endif
- avxf tnear(0.0f), tfar(isect_t);
+ avxf tnear(0.0f), tfar(isect_t);
#if BVH_FEATURE(BVH_HAIR)
- avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
#endif
- avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
+ avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
-
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- (void) inodes;
-
- if(false
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ (void)inodes;
+
+ if (false
#ifdef __VISIBILITY_FLAG__
- || ((__float_as_uint(inodes.x) & PATH_RAY_SHADOW) == 0)
+ || ((__float_as_uint(inodes.x) & PATH_RAY_SHADOW) == 0)
#endif
#if BVH_FEATURE(BVH_MOTION)
- || UNLIKELY(ray->time < inodes.y)
- || UNLIKELY(ray->time > inodes.z)
+ || UNLIKELY(ray->time < inodes.y) || UNLIKELY(ray->time > inodes.z)
#endif
- ) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- avxf dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ ) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ avxf dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
-//#if !defined(__KERNEL_AVX2__)
- org4,
+ //#if !defined(__KERNEL_AVX2__)
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
-
- if(child_mask != 0) {
- avxf cnodes;
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+
+ if (child_mask != 0) {
+ avxf cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+26);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 26);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+14);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
-
- /* Five children are hit, push all onto stack and sort 5
- * stack items, continue with closest child
- */
- r = __bscf(child_mask);
- int c4 = __float_as_int(cnodes[r]);
- float d4 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Six children are hit, push all onto stack and sort 6
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c5 = __float_as_int(cnodes[r]);
- float d5 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
-
- /* Seven children are hit, push all onto stack and sort 7
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c6 = __float_as_int(cnodes[r]);
- float d6 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Eight children are hit, push all onto stack and sort 8
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c7 = __float_as_int(cnodes[r]);
- float d7 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c7;
- traversal_stack[stack_ptr].dist = d7;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6],
- &traversal_stack[stack_ptr - 7]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
+ {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 14);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+
+ /* Five children are hit, push all onto stack and sort 5
+ * stack items, continue with closest child
+ */
+ r = __bscf(child_mask);
+ int c4 = __float_as_int(cnodes[r]);
+ float d4 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Six children are hit, push all onto stack and sort 6
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c5 = __float_as_int(cnodes[r]);
+ float d5 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+
+ /* Seven children are hit, push all onto stack and sort 7
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c6 = __float_as_int(cnodes[r]);
+ float d6 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Eight children are hit, push all onto stack and sort 8
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c7 = __float_as_int(cnodes[r]);
+ float d7 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c7;
+ traversal_stack[stack_ptr].dist = d7;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6],
+ &traversal_stack[stack_ptr - 7]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(leaf.z) & PATH_RAY_SHADOW) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ if ((__float_as_uint(leaf.z) & PATH_RAY_SHADOW) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
#endif
- int prim_addr = __float_as_int(leaf.x);
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- const uint p_type = type & PRIMITIVE_ALL;
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
-
- /* Primitive intersection. */
- if(p_type == PRIMITIVE_TRIANGLE) {
- int prim_count = prim_addr2 - prim_addr;
- if(prim_count < 3) {
- while(prim_addr < prim_addr2) {
- kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
- int hit = triangle_intersect(kg,
- isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr);
- /* Shadow ray early termination. */
- if(hit) {
- /* detect if this surface has a shader with transparent shadows */
-
- /* todo: optimize so primitive visibility flag indicates if
- * the primitive has a transparent shadow shader? */
- int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
- int shader = 0;
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ if (p_type == PRIMITIVE_TRIANGLE) {
+ int prim_count = prim_addr2 - prim_addr;
+ if (prim_count < 3) {
+ while (prim_addr < prim_addr2) {
+ kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) ==
+ p_type);
+ int hit = triangle_intersect(
+ kg, isect_array, P, dir, PATH_RAY_SHADOW, object, prim_addr);
+ /* Shadow ray early termination. */
+ if (hit) {
+ /* detect if this surface has a shader with transparent shadows */
+
+ /* todo: optimize so primitive visibility flag indicates if
+ * the primitive has a transparent shadow shader? */
+ int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
+ int shader = 0;
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
+ if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
#endif
- {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
#ifdef __HAIR__
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
#endif
- int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
-
- /* if no transparent shadows, all light is blocked */
- if(!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
- return true;
- }
- /* if maximum number of hits reached, block all light */
- else if(*num_hits == max_hits) {
- return true;
- }
-
- /* move on to next entry in intersections array */
- isect_array++;
- (*num_hits)++;
+ int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+
+ /* if no transparent shadows, all light is blocked */
+ if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ return true;
+ }
+ /* if maximum number of hits reached, block all light */
+ else if (*num_hits == max_hits) {
+ return true;
+ }
+
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
#endif
- isect_array->t = isect_t;
- }
+ isect_array->t = isect_t;
+ }
- prim_addr++;
- } //while
- } else {
- kernel_assert((kernel_tex_fetch(__prim_type, (prim_addr)) & PRIMITIVE_ALL) == p_type);
+ prim_addr++;
+ } //while
+ }
+ else {
+ kernel_assert((kernel_tex_fetch(__prim_type, (prim_addr)) & PRIMITIVE_ALL) ==
+ p_type);
#if BVH_FEATURE(BVH_INSTANCING)
- int* nhiptr = &num_hits_in_instance;
+ int *nhiptr = &num_hits_in_instance;
#else
- int nhi= 0;
- int *nhiptr = &nhi;
+ int nhi = 0;
+ int *nhiptr = &nhi;
#endif
- int result = triangle_intersect8(kg,
- &isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr,
- prim_count,
- num_hits,
- max_hits,
- nhiptr,
- isect_t);
- if(result == 2) {
- return true;
- }
- } // prim_count
- } // PRIMITIVE_TRIANGLE
- else {
- while(prim_addr < prim_addr2) {
- kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
+ int result = triangle_intersect8(kg,
+ &isect_array,
+ P,
+ dir,
+ PATH_RAY_SHADOW,
+ object,
+ prim_addr,
+ prim_count,
+ num_hits,
+ max_hits,
+ nhiptr,
+ isect_t);
+ if (result == 2) {
+ return true;
+ }
+ } // prim_count
+ } // PRIMITIVE_TRIANGLE
+ else {
+ while (prim_addr < prim_addr2) {
+ kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
#ifdef __SHADOW_TRICKS__
- uint tri_object = (object == OBJECT_NONE)
- ? kernel_tex_fetch(__prim_object, prim_addr)
- : object;
- if(tri_object == skip_object) {
- ++prim_addr;
- continue;
- }
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ if (tri_object == skip_object) {
+ ++prim_addr;
+ continue;
+ }
#endif
- bool hit;
+ bool hit;
- /* todo: specialized intersect functions which don't fill in
- * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
- * might give a few % performance improvement */
+ /* todo: specialized intersect functions which don't fill in
+ * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
+ * might give a few % performance improvement */
- switch(p_type) {
+ switch (p_type) {
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- hit = motion_triangle_intersect(kg,
- isect_array,
- P,
- dir,
- ray->time,
- PATH_RAY_SHADOW,
- object,
- prim_addr);
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ hit = motion_triangle_intersect(
+ kg, isect_array, P, dir, ray->time, PATH_RAY_SHADOW, object, prim_addr);
+ break;
+ }
#endif
#if BVH_FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = cardinal_curve_intersect(kg,
- isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
- }
- else {
- hit = curve_intersect(kg,
- isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
- }
- break;
- }
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ if (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
+ hit = cardinal_curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ PATH_RAY_SHADOW,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0,
+ 0);
+ }
+ else {
+ hit = curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ PATH_RAY_SHADOW,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0,
+ 0);
+ }
+ break;
+ }
#endif
- default: {
- hit = false;
- break;
- }
- }
+ default: {
+ hit = false;
+ break;
+ }
+ }
- /* Shadow ray early termination. */
- if(hit) {
- /* detect if this surface has a shader with transparent shadows */
+ /* Shadow ray early termination. */
+ if (hit) {
+ /* detect if this surface has a shader with transparent shadows */
- /* todo: optimize so primitive visibility flag indicates if
- * the primitive has a transparent shadow shader? */
- int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
- int shader = 0;
+ /* todo: optimize so primitive visibility flag indicates if
+ * the primitive has a transparent shadow shader? */
+ int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
+ int shader = 0;
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
+ if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
#endif
- {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
#ifdef __HAIR__
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
#endif
- int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
-
- /* if no transparent shadows, all light is blocked */
- if(!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
- return true;
- }
- /* if maximum number of hits reached, block all light */
- else if(*num_hits == max_hits) {
- return true;
- }
-
- /* move on to next entry in intersections array */
- isect_array++;
- (*num_hits)++;
+ int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+
+ /* if no transparent shadows, all light is blocked */
+ if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ return true;
+ }
+ /* if maximum number of hits reached, block all light */
+ else if (*num_hits == max_hits) {
+ return true;
+ }
+
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
#endif
- isect_array->t = isect_t;
- }
+ isect_array->t = isect_t;
+ }
- prim_addr++;
- }//while prim
- }
- }
+ prim_addr++;
+ } //while prim
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
# if BVH_FEATURE(BVH_MOTION)
- isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
+ isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
# else
- isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
# endif
- num_hits_in_instance = 0;
- isect_array->t = isect_t;
+ num_hits_in_instance = 0;
+ isect_array->t = isect_t;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect_t);
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect_t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
- if(num_hits_in_instance) {
- float t_fac;
+ /* Instance pop. */
+ if (num_hits_in_instance) {
+ float t_fac;
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
# else
- bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
# endif
- /* Scale isect->t to adjust for instancing. */
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
- else {
+ /* Scale isect->t to adjust for instancing. */
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+ else {
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
# else
- bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
# endif
- }
+ }
- isect_t = tmax;
- isect_array->t = isect_t;
+ isect_t = tmax;
+ isect_array->t = isect_t;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect_t);
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect_t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return false;
+ return false;
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/obvh_traversal.h b/intern/cycles/kernel/bvh/obvh_traversal.h
index 5df7a3be515..86b1de48aaa 100644
--- a/intern/cycles/kernel/bvh/obvh_traversal.h
+++ b/intern/cycles/kernel/bvh/obvh_traversal.h
@@ -37,598 +37,583 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
Intersection *isect,
const uint visibility
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- ,uint *lcg_state,
+ ,
+ uint *lcg_state,
float difl,
float extmax
#endif
- )
+)
{
- /* Traversal stack in CUDA thread-local memory. */
- OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
- traversal_stack[0].dist = -FLT_MAX;
-
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
- float node_dist = -FLT_MAX;
-
- /* Ray parameters in registers. */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
+ /* Traversal stack in CUDA thread-local memory. */
+ OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+ traversal_stack[0].dist = -FLT_MAX;
+
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+ float node_dist = -FLT_MAX;
+
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- isect->t = ray->t;
- isect->u = 0.0f;
- isect->v = 0.0f;
- isect->prim = PRIM_NONE;
- isect->object = OBJECT_NONE;
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
- BVH_DEBUG_INIT();
- avxf tnear(0.0f), tfar(ray->t);
+ BVH_DEBUG_INIT();
+ avxf tnear(0.0f), tfar(ray->t);
#if BVH_FEATURE(BVH_HAIR)
- avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
#endif
- avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- avx3f P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ avx3f P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- avx3f org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ avx3f org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- (void) inodes;
-
- if(UNLIKELY(node_dist > isect->t)
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ (void)inodes;
+
+ if (UNLIKELY(node_dist > isect->t)
#if BVH_FEATURE(BVH_MOTION)
- || UNLIKELY(ray->time < inodes.y)
- || UNLIKELY(ray->time > inodes.z)
+ || UNLIKELY(ray->time < inodes.y) || UNLIKELY(ray->time > inodes.z)
#endif
#ifdef __VISIBILITY_FLAG__
- || (__float_as_uint(inodes.x) & visibility) == 0
+ || (__float_as_uint(inodes.x) & visibility) == 0
#endif
- )
- {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
+ ) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
- int child_mask;
- avxf dist;
+ int child_mask;
+ avxf dist;
- BVH_DEBUG_NEXT_NODE();
+ BVH_DEBUG_NEXT_NODE();
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- if(difl != 0.0f) {
- /* NOTE: We extend all the child BB instead of fetching
- * and checking visibility flags for each of the,
- *
- * Need to test if doing opposite would be any faster.
- */
- child_mask = NODE_INTERSECT_ROBUST(kg,
- tnear,
- tfar,
+ if (difl != 0.0f) {
+ /* NOTE: We extend all the child BB instead of fetching
+ * and checking visibility flags for each of the,
+ *
+ * Need to test if doing opposite would be any faster.
+ */
+ child_mask = NODE_INTERSECT_ROBUST(kg,
+ tnear,
+ tfar,
# ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
# endif
# if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
# endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- difl,
- &dist);
- }
- else
-#endif /* BVH_HAIR_MINIMUM_WIDTH */
- {
- child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ difl,
+ &dist);
+ }
+ else
+#endif /* BVH_HAIR_MINIMUM_WIDTH */
+ {
+ child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
- }
-
- if(child_mask != 0) {
- avxf cnodes;
- /* TODO(sergey): Investigate whether moving cnodes upwards
- * gives a speedup (will be different cache pattern but will
- * avoid extra check here).
- */
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+ }
+
+ if (child_mask != 0) {
+ avxf cnodes;
+ /* TODO(sergey): Investigate whether moving cnodes upwards
+ * gives a speedup (will be different cache pattern but will
+ * avoid extra check here).
+ */
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+26);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 26);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+14);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- float d0 = ((float*)&dist)[r];
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- node_dist = d0;
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- node_dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- node_dist = d0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
-
- /* Five children are hit, push all onto stack and sort 5
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c4 = __float_as_int(cnodes[r]);
- float d4 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4]);
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
-
- /* Six children are hit, push all onto stack and sort 6
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c5 = __float_as_int(cnodes[r]);
- float d5 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5]);
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
-
- /* Seven children are hit, push all onto stack and sort 7
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c6 = __float_as_int(cnodes[r]);
- float d6 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6]);
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
-
- /* Eight children are hit, push all onto stack and sort 8
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c7 = __float_as_int(cnodes[r]);
- float d7 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c7;
- traversal_stack[stack_ptr].dist = d7;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6],
- &traversal_stack[stack_ptr - 7]);
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
-
-
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
+ {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 14);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ float d0 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ node_dist = d0;
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ node_dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ node_dist = d0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+
+ /* Five children are hit, push all onto stack and sort 5
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c4 = __float_as_int(cnodes[r]);
+ float d4 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Six children are hit, push all onto stack and sort 6
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c5 = __float_as_int(cnodes[r]);
+ float d5 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+
+ /* Seven children are hit, push all onto stack and sort 7
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c6 = __float_as_int(cnodes[r]);
+ float d6 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Eight children are hit, push all onto stack and sort 8
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c7 = __float_as_int(cnodes[r]);
+ float d7 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c7;
+ traversal_stack[stack_ptr].dist = d7;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6],
+ &traversal_stack[stack_ptr - 7]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
#ifdef __VISIBILITY_FLAG__
- if(UNLIKELY((node_dist > isect->t) ||
- ((__float_as_uint(leaf.z) & visibility) == 0)))
+ if (UNLIKELY((node_dist > isect->t) || ((__float_as_uint(leaf.z) & visibility) == 0)))
#else
- if(UNLIKELY((node_dist > isect->t)))
+ if (UNLIKELY((node_dist > isect->t)))
#endif
- {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
- int prim_addr = __float_as_int(leaf.x);
+ {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
-
- /* Primitive intersection. */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- int prim_count = prim_addr2 - prim_addr;
- if(prim_count < 3) {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(triangle_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr))
- {
- tfar = avxf(isect->t);
- /* Shadow ray early termination. */
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
- return true;
- }
- }
- }//for
- }
- else {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(triangle_intersect8(kg,
- &isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- prim_count,
- 0,
- 0,
- NULL,
- 0.0f))
- {
- tfar = avxf(isect->t);
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
- return true;
- }
- }
- }//prim count
- break;
- }
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ int prim_count = prim_addr2 - prim_addr;
+ if (prim_count < 3) {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr)) {
+ tfar = avxf(isect->t);
+ /* Shadow ray early termination. */
+ if (visibility == PATH_RAY_SHADOW_OPAQUE) {
+ return true;
+ }
+ }
+ } //for
+ }
+ else {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (triangle_intersect8(kg,
+ &isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ prim_count,
+ 0,
+ 0,
+ NULL,
+ 0.0f)) {
+ tfar = avxf(isect->t);
+ if (visibility == PATH_RAY_SHADOW_OPAQUE) {
+ return true;
+ }
+ }
+ } //prim count
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(motion_triangle_intersect(kg,
- isect,
- P,
- dir,
- ray->time,
- visibility,
- object,
- prim_addr))
- {
- tfar = avxf(isect->t);
- /* Shadow ray early termination. */
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
- return true;
- }
- }
- }
- break;
- }
-#endif /* BVH_FEATURE(BVH_MOTION) */
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (motion_triangle_intersect(
+ kg, isect, P, dir, ray->time, visibility, object, prim_addr)) {
+ tfar = avxf(isect->t);
+ /* Shadow ray early termination. */
+ if (visibility == PATH_RAY_SHADOW_OPAQUE) {
+ return true;
+ }
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_MOTION) */
#if BVH_FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
- kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
- bool hit;
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = cardinal_curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
- }
- else {
- hit = curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
- }
- if(hit) {
- tfar = avxf(isect->t);
- /* Shadow ray early termination. */
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
- return true;
- }
- }
- }
- break;
- }
-#endif /* BVH_FEATURE(BVH_HAIR) */
- }
- }
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
+ bool hit;
+ if (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
+ hit = cardinal_curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
+ }
+ else {
+ hit = curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
+ }
+ if (hit) {
+ tfar = avxf(isect->t);
+ /* Shadow ray early termination. */
+ if (visibility == PATH_RAY_SHADOW_OPAQUE) {
+ return true;
+ }
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_HAIR) */
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
# if BVH_FEATURE(BVH_MOTION)
- qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist, &ob_itfm);
+ qbvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist, &ob_itfm);
# else
- qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist);
+ qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist);
# endif
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect->t);
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
- traversal_stack[stack_ptr].dist = -FLT_MAX;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
+ traversal_stack[stack_ptr].dist = -FLT_MAX;
- node_addr = kernel_tex_fetch(__object_node, object);
+ node_addr = kernel_tex_fetch(__object_node, object);
- BVH_DEBUG_NEXT_INSTANCE();
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ BVH_DEBUG_NEXT_INSTANCE();
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
+ /* Instance pop. */
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect->t);
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return (isect->prim != PRIM_NONE);
+ return (isect->prim != PRIM_NONE);
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/obvh_volume.h b/intern/cycles/kernel/bvh/obvh_volume.h
index e66d499dccc..fb41ae783ab 100644
--- a/intern/cycles/kernel/bvh/obvh_volume.h
+++ b/intern/cycles/kernel/bvh/obvh_volume.h
@@ -33,444 +33,448 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
Intersection *isect,
const uint visibility)
{
- /* Traversal stack in CUDA thread-local memory. */
- OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+ /* Traversal stack in CUDA thread-local memory. */
+ OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
- /* Ray parameters in registers. */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- isect->t = ray->t;
- isect->u = 0.0f;
- isect->v = 0.0f;
- isect->prim = PRIM_NONE;
- isect->object = OBJECT_NONE;
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
- avxf tnear(0.0f), tfar(ray->t);
+ avxf tnear(0.0f), tfar(ray->t);
#if BVH_FEATURE(BVH_HAIR)
- avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
#endif
- avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
+ avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(inodes.x) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ if ((__float_as_uint(inodes.x) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
#endif
- avxf dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ avxf dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
-
- if(child_mask != 0) {
- avxf cnodes;
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+
+ if (child_mask != 0) {
+ avxf cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+26);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 26);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+14);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
-
- /* Five children are hit, push all onto stack and sort 5
- * stack items, continue with closest child
- */
- r = __bscf(child_mask);
- int c4 = __float_as_int(cnodes[r]);
- float d4 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Six children are hit, push all onto stack and sort 6
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c5 = __float_as_int(cnodes[r]);
- float d5 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
-
- /* Seven children are hit, push all onto stack and sort 7
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c6 = __float_as_int(cnodes[r]);
- float d6 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Eight children are hit, push all onto stack and sort 8
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c7 = __float_as_int(cnodes[r]);
- float d7 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c7;
- traversal_stack[stack_ptr].dist = d7;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6],
- &traversal_stack[stack_ptr - 7]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
-
- if((__float_as_uint(leaf.z) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- int prim_addr = __float_as_int(leaf.x);
+ {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 14);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+
+ /* Five children are hit, push all onto stack and sort 5
+ * stack items, continue with closest child
+ */
+ r = __bscf(child_mask);
+ int c4 = __float_as_int(cnodes[r]);
+ float d4 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Six children are hit, push all onto stack and sort 6
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c5 = __float_as_int(cnodes[r]);
+ float d5 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+
+ /* Seven children are hit, push all onto stack and sort 7
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c6 = __float_as_int(cnodes[r]);
+ float d6 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Eight children are hit, push all onto stack and sort 8
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c7 = __float_as_int(cnodes[r]);
+ float d7 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c7;
+ traversal_stack[stack_ptr].dist = d7;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6],
+ &traversal_stack[stack_ptr - 7]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+
+ if ((__float_as_uint(leaf.z) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- const uint p_type = type & PRIMITIVE_ALL;
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
-
- /* Primitive intersection. */
- switch(p_type) {
- case PRIMITIVE_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr);
- }
- break;
- }
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ switch (p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr);
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, prim_addr);
- }
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ motion_triangle_intersect(
+ kg, isect, P, dir, ray->time, visibility, object, prim_addr);
+ }
+ break;
+ }
#endif
- }
- }
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VOLUME) {
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_HAS_VOLUME) {
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect->t);
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
- }
- else {
- /* Pop. */
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
+
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* Pop. */
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
+ /* Instance pop. */
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect->t);
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return (isect->prim != PRIM_NONE);
+ return (isect->prim != PRIM_NONE);
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/obvh_volume_all.h b/intern/cycles/kernel/bvh/obvh_volume_all.h
index 5476f79712a..56e2afd4a11 100644
--- a/intern/cycles/kernel/bvh/obvh_volume_all.h
+++ b/intern/cycles/kernel/bvh/obvh_volume_all.h
@@ -34,514 +34,518 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
const uint max_hits,
const uint visibility)
{
- /* Traversal stack in CUDA thread-local memory. */
- OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
-
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* Ray parameters in registers. */
- const float tmax = ray->t;
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = tmax;
+ /* Traversal stack in CUDA thread-local memory. */
+ OBVHStackItem traversal_stack[BVH_OSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- uint num_hits = 0;
- isect_array->t = tmax;
+ uint num_hits = 0;
+ isect_array->t = tmax;
#if BVH_FEATURE(BVH_INSTANCING)
- int num_hits_in_instance = 0;
+ int num_hits_in_instance = 0;
#endif
- avxf tnear(0.0f), tfar(isect_t);
+ avxf tnear(0.0f), tfar(isect_t);
#if BVH_FEATURE(BVH_HAIR)
- avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
#endif
- avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ avx3f idir4(avxf(idir.x), avxf(idir.y), avxf(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ avx3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
+ avx3f org4(avxf(P.x), avxf(P.y), avxf(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(inodes.x) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ if ((__float_as_uint(inodes.x) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
#endif
- avxf dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ avxf dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
-
- if(child_mask != 0) {
- avxf cnodes;
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+
+ if (child_mask != 0) {
+ avxf cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+26);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 26);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr+14);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
-
- /* Five children are hit, push all onto stack and sort 5
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c4 = __float_as_int(cnodes[r]);
- float d4 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Six children are hit, push all onto stack and sort 6
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c5 = __float_as_int(cnodes[r]);
- float d5 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c5;
- traversal_stack[stack_ptr].dist = d5;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c4;
- traversal_stack[stack_ptr].dist = d4;
-
- /* Seven children are hit, push all onto stack and sort 7
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c6 = __float_as_int(cnodes[r]);
- float d6 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Eight children are hit, push all onto stack and sort 8
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c7 = __float_as_int(cnodes[r]);
- float d7 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c7;
- traversal_stack[stack_ptr].dist = d7;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c6;
- traversal_stack[stack_ptr].dist = d6;
- obvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3],
- &traversal_stack[stack_ptr - 4],
- &traversal_stack[stack_ptr - 5],
- &traversal_stack[stack_ptr - 6],
- &traversal_stack[stack_ptr - 7]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
-
- if((__float_as_uint(leaf.z) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- int prim_addr = __float_as_int(leaf.x);
+ {
+ cnodes = kernel_tex_fetch_avxf(__bvh_nodes, node_addr + 14);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+
+ /* Five children are hit, push all onto stack and sort 5
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c4 = __float_as_int(cnodes[r]);
+ float d4 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Six children are hit, push all onto stack and sort 6
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c5 = __float_as_int(cnodes[r]);
+ float d5 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c5;
+ traversal_stack[stack_ptr].dist = d5;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c4;
+ traversal_stack[stack_ptr].dist = d4;
+
+ /* Seven children are hit, push all onto stack and sort 7
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c6 = __float_as_int(cnodes[r]);
+ float d6 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Eight children are hit, push all onto stack and sort 8
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c7 = __float_as_int(cnodes[r]);
+ float d7 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c7;
+ traversal_stack[stack_ptr].dist = d7;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c6;
+ traversal_stack[stack_ptr].dist = d6;
+ obvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3],
+ &traversal_stack[stack_ptr - 4],
+ &traversal_stack[stack_ptr - 5],
+ &traversal_stack[stack_ptr - 6],
+ &traversal_stack[stack_ptr - 7]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+
+ if ((__float_as_uint(leaf.z) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- const uint p_type = type & PRIMITIVE_ALL;
- bool hit;
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
-
- /* Primitive intersection. */
- switch(p_type) {
- case PRIMITIVE_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
- if(hit) {
- /* Move on to next entry in intersections array. */
- isect_array++;
- num_hits++;
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+ bool hit;
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ switch (p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
+ if (hit) {
+ /* Move on to next entry in intersections array. */
+ isect_array++;
+ num_hits++;
#if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
#endif
- isect_array->t = isect_t;
- if(num_hits == max_hits) {
+ isect_array->t = isect_t;
+ if (num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- float t_fac = 1.0f / len(transform_direction(&itfm, dir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
# endif
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
-#endif /* BVH_FEATURE(BVH_INSTANCING) */
- return num_hits;
- }
- }
- }
- break;
- }
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+#endif /* BVH_FEATURE(BVH_INSTANCING) */
+ return num_hits;
+ }
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
- if(hit) {
- /* Move on to next entry in intersections array. */
- isect_array++;
- num_hits++;
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ hit = motion_triangle_intersect(
+ kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
+ if (hit) {
+ /* Move on to next entry in intersections array. */
+ isect_array++;
+ num_hits++;
# if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
# endif
- isect_array->t = isect_t;
- if(num_hits == max_hits) {
+ isect_array->t = isect_t;
+ if (num_hits == max_hits) {
# if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- float t_fac = 1.0f / len(transform_direction(&itfm, dir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
# endif
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
-# endif /* BVH_FEATURE(BVH_INSTANCING) */
- return num_hits;
- }
- }
- }
- break;
- }
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+# endif /* BVH_FEATURE(BVH_INSTANCING) */
+ return num_hits;
+ }
+ }
+ }
+ break;
+ }
#endif
- }
- }
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VOLUME) {
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_HAS_VOLUME) {
# if BVH_FEATURE(BVH_MOTION)
- isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
+ isect_t = bvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
# else
- isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
# endif
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect_t);
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect_t);
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- num_hits_in_instance = 0;
- isect_array->t = isect_t;
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
- }
- else {
- /* Pop. */
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ num_hits_in_instance = 0;
+ isect_array->t = isect_t;
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_OSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
+
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* Pop. */
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
- if(num_hits_in_instance) {
- float t_fac;
+ /* Instance pop. */
+ if (num_hits_in_instance) {
+ float t_fac;
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
# else
- bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
# endif
- /* Scale isect->t to adjust for instancing. */
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
- else {
+ /* Scale isect->t to adjust for instancing. */
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+ else {
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
# else
- bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
# endif
- }
+ }
- isect_t = tmax;
- isect_array->t = isect_t;
+ isect_t = tmax;
+ isect_array->t = isect_t;
- obvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = avxf(isect_t);
+ obvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = avxf(isect_t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
+ dir4 = avx3f(avxf(dir.x), avxf(dir.y), avxf(dir.z));
# endif
- idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
+ idir4 = avx3f(avxf(idir.x), avxf(idir.y), avxf(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = avx3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
+ org4 = avx3f(avxf(P.x), avxf(P.y), avxf(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return num_hits;
+ return num_hits;
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/qbvh_local.h b/intern/cycles/kernel/bvh/qbvh_local.h
index 661182e31b3..b21f79bd3a0 100644
--- a/intern/cycles/kernel/bvh/qbvh_local.h
+++ b/intern/cycles/kernel/bvh/qbvh_local.h
@@ -35,262 +35,257 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
uint *lcg_state,
int max_hits)
{
- /* TODO(sergey):
- * - Test if pushing distance on the stack helps (for non shadow rays).
- * - Separate version for shadow rays.
- * - Likely and unlikely for if() statements.
- * - SSE for hair.
- * - Test restrict attribute for pointers.
- */
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps (for non shadow rays).
+ * - Separate version for shadow rays.
+ * - Likely and unlikely for if() statements.
+ * - SSE for hair.
+ * - Test restrict attribute for pointers.
+ */
- /* Traversal stack in CUDA thread-local memory. */
- QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_tex_fetch(__object_node, local_object);
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_tex_fetch(__object_node, local_object);
- /* Ray parameters in registers. */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = ray->t;
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = ray->t;
- if(local_isect != NULL) {
- local_isect->num_hits = 0;
- }
- kernel_assert((local_isect == NULL) == (max_hits == 0));
+ if (local_isect != NULL) {
+ local_isect->num_hits = 0;
+ }
+ kernel_assert((local_isect == NULL) == (max_hits == 0));
- const int object_flag = kernel_tex_fetch(__object_flag, local_object);
- if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ const int object_flag = kernel_tex_fetch(__object_flag, local_object);
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
- isect_t = bvh_instance_motion_push(kg,
- local_object,
- ray,
- &P,
- &dir,
- &idir,
- isect_t,
- &ob_itfm);
+ Transform ob_itfm;
+ isect_t = bvh_instance_motion_push(kg, local_object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
#else
- isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
#endif
- object = local_object;
- }
+ object = local_object;
+ }
- ssef tnear(0.0f), tfar(isect_t);
+ ssef tnear(0.0f), tfar(isect_t);
#if BVH_FEATURE(BVH_HAIR)
- sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
#endif
- sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
+ sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- ssef dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ ssef dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
- if(child_mask != 0) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- float4 cnodes;
+ if (child_mask != 0) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+13);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 13);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+7);
- }
+ {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 7);
+ }
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- }
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ }
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
- int prim_addr = __float_as_int(leaf.x);
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ int prim_addr = __float_as_int(leaf.x);
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
- /* Primitive intersection. */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- /* Intersect ray against primitive, */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits)) {
- return true;
- }
- }
- break;
- }
+ /* Primitive intersection. */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* Intersect ray against primitive, */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- /* Intersect ray against primitive. */
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(motion_triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- ray->time,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits)) {
- return true;
- }
- }
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* Intersect ray against primitive. */
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (motion_triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ ray->time,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
+ }
+ break;
+ }
#endif
- default:
- break;
- }
- }
- } while(node_addr != ENTRYPOINT_SENTINEL);
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ default:
+ break;
+ }
+ }
+ } while (node_addr != ENTRYPOINT_SENTINEL);
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return false;
+ return false;
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/qbvh_nodes.h b/intern/cycles/kernel/bvh/qbvh_nodes.h
index 2e622af1758..7c1d8c8c72e 100644
--- a/intern/cycles/kernel/bvh/qbvh_nodes.h
+++ b/intern/cycles/kernel/bvh/qbvh_nodes.h
@@ -17,11 +17,11 @@
*/
struct QBVHStackItem {
- int addr;
- float dist;
+ int addr;
+ float dist;
};
-ccl_device_inline void qbvh_near_far_idx_calc(const float3& idir,
+ccl_device_inline void qbvh_near_far_idx_calc(const float3 &idir,
int *ccl_restrict near_x,
int *ccl_restrict near_y,
int *ccl_restrict near_z,
@@ -31,44 +31,76 @@ ccl_device_inline void qbvh_near_far_idx_calc(const float3& idir,
{
#ifdef __KERNEL_SSE__
- *near_x = 0; *far_x = 1;
- *near_y = 2; *far_y = 3;
- *near_z = 4; *far_z = 5;
-
- const size_t mask = movemask(ssef(idir.m128));
-
- const int mask_x = mask & 1;
- const int mask_y = (mask & 2) >> 1;
- const int mask_z = (mask & 4) >> 2;
-
- *near_x += mask_x; *far_x -= mask_x;
- *near_y += mask_y; *far_y -= mask_y;
- *near_z += mask_z; *far_z -= mask_z;
+ *near_x = 0;
+ *far_x = 1;
+ *near_y = 2;
+ *far_y = 3;
+ *near_z = 4;
+ *far_z = 5;
+
+ const size_t mask = movemask(ssef(idir.m128));
+
+ const int mask_x = mask & 1;
+ const int mask_y = (mask & 2) >> 1;
+ const int mask_z = (mask & 4) >> 2;
+
+ *near_x += mask_x;
+ *far_x -= mask_x;
+ *near_y += mask_y;
+ *far_y -= mask_y;
+ *near_z += mask_z;
+ *far_z -= mask_z;
#else
- if(idir.x >= 0.0f) { *near_x = 0; *far_x = 1; } else { *near_x = 1; *far_x = 0; }
- if(idir.y >= 0.0f) { *near_y = 2; *far_y = 3; } else { *near_y = 3; *far_y = 2; }
- if(idir.z >= 0.0f) { *near_z = 4; *far_z = 5; } else { *near_z = 5; *far_z = 4; }
+ if (idir.x >= 0.0f) {
+ *near_x = 0;
+ *far_x = 1;
+ }
+ else {
+ *near_x = 1;
+ *far_x = 0;
+ }
+ if (idir.y >= 0.0f) {
+ *near_y = 2;
+ *far_y = 3;
+ }
+ else {
+ *near_y = 3;
+ *far_y = 2;
+ }
+ if (idir.z >= 0.0f) {
+ *near_z = 4;
+ *far_z = 5;
+ }
+ else {
+ *near_z = 5;
+ *far_z = 4;
+ }
#endif
}
/* TOOD(sergey): Investigate if using intrinsics helps for both
* stack item swap and float comparison.
*/
-ccl_device_inline void qbvh_item_swap(QBVHStackItem *ccl_restrict a,
- QBVHStackItem *ccl_restrict b)
+ccl_device_inline void qbvh_item_swap(QBVHStackItem *ccl_restrict a, QBVHStackItem *ccl_restrict b)
{
- QBVHStackItem tmp = *a;
- *a = *b;
- *b = tmp;
+ QBVHStackItem tmp = *a;
+ *a = *b;
+ *b = tmp;
}
ccl_device_inline void qbvh_stack_sort(QBVHStackItem *ccl_restrict s1,
QBVHStackItem *ccl_restrict s2,
QBVHStackItem *ccl_restrict s3)
{
- if(s2->dist < s1->dist) { qbvh_item_swap(s2, s1); }
- if(s3->dist < s2->dist) { qbvh_item_swap(s3, s2); }
- if(s2->dist < s1->dist) { qbvh_item_swap(s2, s1); }
+ if (s2->dist < s1->dist) {
+ qbvh_item_swap(s2, s1);
+ }
+ if (s3->dist < s2->dist) {
+ qbvh_item_swap(s3, s2);
+ }
+ if (s2->dist < s1->dist) {
+ qbvh_item_swap(s2, s1);
+ }
}
ccl_device_inline void qbvh_stack_sort(QBVHStackItem *ccl_restrict s1,
@@ -76,279 +108,283 @@ ccl_device_inline void qbvh_stack_sort(QBVHStackItem *ccl_restrict s1,
QBVHStackItem *ccl_restrict s3,
QBVHStackItem *ccl_restrict s4)
{
- if(s2->dist < s1->dist) { qbvh_item_swap(s2, s1); }
- if(s4->dist < s3->dist) { qbvh_item_swap(s4, s3); }
- if(s3->dist < s1->dist) { qbvh_item_swap(s3, s1); }
- if(s4->dist < s2->dist) { qbvh_item_swap(s4, s2); }
- if(s3->dist < s2->dist) { qbvh_item_swap(s3, s2); }
+ if (s2->dist < s1->dist) {
+ qbvh_item_swap(s2, s1);
+ }
+ if (s4->dist < s3->dist) {
+ qbvh_item_swap(s4, s3);
+ }
+ if (s3->dist < s1->dist) {
+ qbvh_item_swap(s3, s1);
+ }
+ if (s4->dist < s2->dist) {
+ qbvh_item_swap(s4, s2);
+ }
+ if (s3->dist < s2->dist) {
+ qbvh_item_swap(s3, s2);
+ }
}
/* Axis-aligned nodes intersection */
//ccl_device_inline int qbvh_aligned_node_intersect(KernelGlobals *ccl_restrict kg,
static int qbvh_aligned_node_intersect(KernelGlobals *ccl_restrict kg,
- const ssef& isect_near,
- const ssef& isect_far,
+ const ssef &isect_near,
+ const ssef &isect_far,
#ifdef __KERNEL_AVX2__
- const sse3f& org_idir,
+ const sse3f &org_idir,
#else
- const sse3f& org,
+ const sse3f &org,
#endif
- const sse3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- ssef *ccl_restrict dist)
+ const sse3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ ssef *ccl_restrict dist)
{
- const int offset = node_addr + 1;
+ const int offset = node_addr + 1;
#ifdef __KERNEL_AVX2__
- const ssef tnear_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x), idir.x, org_idir.x);
- const ssef tnear_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y), idir.y, org_idir.y);
- const ssef tnear_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z), idir.z, org_idir.z);
- const ssef tfar_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x), idir.x, org_idir.x);
- const ssef tfar_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y), idir.y, org_idir.y);
- const ssef tfar_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z), idir.z, org_idir.z);
+ const ssef tnear_x = msub(
+ kernel_tex_fetch_ssef(__bvh_nodes, offset + near_x), idir.x, org_idir.x);
+ const ssef tnear_y = msub(
+ kernel_tex_fetch_ssef(__bvh_nodes, offset + near_y), idir.y, org_idir.y);
+ const ssef tnear_z = msub(
+ kernel_tex_fetch_ssef(__bvh_nodes, offset + near_z), idir.z, org_idir.z);
+ const ssef tfar_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + far_x), idir.x, org_idir.x);
+ const ssef tfar_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + far_y), idir.y, org_idir.y);
+ const ssef tfar_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + far_z), idir.z, org_idir.z);
#else
- const ssef tnear_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x) - org.x) * idir.x;
- const ssef tnear_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y) - org.y) * idir.y;
- const ssef tnear_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z) - org.z) * idir.z;
- const ssef tfar_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x) - org.x) * idir.x;
- const ssef tfar_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y) - org.y) * idir.y;
- const ssef tfar_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z) - org.z) * idir.z;
+ const ssef tnear_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset + near_x) - org.x) * idir.x;
+ const ssef tnear_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset + near_y) - org.y) * idir.y;
+ const ssef tnear_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset + near_z) - org.z) * idir.z;
+ const ssef tfar_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset + far_x) - org.x) * idir.x;
+ const ssef tfar_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset + far_y) - org.y) * idir.y;
+ const ssef tfar_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset + far_z) - org.z) * idir.z;
#endif
#ifdef __KERNEL_SSE41__
- const ssef tnear = maxi(maxi(tnear_x, tnear_y), maxi(tnear_z, isect_near));
- const ssef tfar = mini(mini(tfar_x, tfar_y), mini(tfar_z, isect_far));
- const sseb vmask = cast(tnear) > cast(tfar);
- int mask = (int)movemask(vmask)^0xf;
+ const ssef tnear = maxi(maxi(tnear_x, tnear_y), maxi(tnear_z, isect_near));
+ const ssef tfar = mini(mini(tfar_x, tfar_y), mini(tfar_z, isect_far));
+ const sseb vmask = cast(tnear) > cast(tfar);
+ int mask = (int)movemask(vmask) ^ 0xf;
#else
- const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- const sseb vmask = tnear <= tfar;
- int mask = (int)movemask(vmask);
+ const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ const sseb vmask = tnear <= tfar;
+ int mask = (int)movemask(vmask);
#endif
- *dist = tnear;
- return mask;
+ *dist = tnear;
+ return mask;
}
-ccl_device_inline int qbvh_aligned_node_intersect_robust(
- KernelGlobals *ccl_restrict kg,
- const ssef& isect_near,
- const ssef& isect_far,
+ccl_device_inline int qbvh_aligned_node_intersect_robust(KernelGlobals *ccl_restrict kg,
+ const ssef &isect_near,
+ const ssef &isect_far,
#ifdef __KERNEL_AVX2__
- const sse3f& P_idir,
+ const sse3f &P_idir,
#else
- const sse3f& P,
+ const sse3f &P,
#endif
- const sse3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- const float difl,
- ssef *ccl_restrict dist)
+ const sse3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ const float difl,
+ ssef *ccl_restrict dist)
{
- const int offset = node_addr + 1;
+ const int offset = node_addr + 1;
#ifdef __KERNEL_AVX2__
- const ssef tnear_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x), idir.x, P_idir.x);
- const ssef tnear_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y), idir.y, P_idir.y);
- const ssef tnear_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z), idir.z, P_idir.z);
- const ssef tfar_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x), idir.x, P_idir.x);
- const ssef tfar_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y), idir.y, P_idir.y);
- const ssef tfar_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z), idir.z, P_idir.z);
+ const ssef tnear_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + near_x), idir.x, P_idir.x);
+ const ssef tnear_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + near_y), idir.y, P_idir.y);
+ const ssef tnear_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + near_z), idir.z, P_idir.z);
+ const ssef tfar_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + far_x), idir.x, P_idir.x);
+ const ssef tfar_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + far_y), idir.y, P_idir.y);
+ const ssef tfar_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset + far_z), idir.z, P_idir.z);
#else
- const ssef tnear_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x) - P.x) * idir.x;
- const ssef tnear_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y) - P.y) * idir.y;
- const ssef tnear_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z) - P.z) * idir.z;
- const ssef tfar_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x) - P.x) * idir.x;
- const ssef tfar_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y) - P.y) * idir.y;
- const ssef tfar_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z) - P.z) * idir.z;
+ const ssef tnear_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset + near_x) - P.x) * idir.x;
+ const ssef tnear_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset + near_y) - P.y) * idir.y;
+ const ssef tnear_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset + near_z) - P.z) * idir.z;
+ const ssef tfar_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset + far_x) - P.x) * idir.x;
+ const ssef tfar_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset + far_y) - P.y) * idir.y;
+ const ssef tfar_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset + far_z) - P.z) * idir.z;
#endif
- const float round_down = 1.0f - difl;
- const float round_up = 1.0f + difl;
- const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- const sseb vmask = round_down*tnear <= round_up*tfar;
- *dist = tnear;
- return (int)movemask(vmask);
+ const float round_down = 1.0f - difl;
+ const float round_up = 1.0f + difl;
+ const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ const sseb vmask = round_down * tnear <= round_up * tfar;
+ *dist = tnear;
+ return (int)movemask(vmask);
}
/* Unaligned nodes intersection */
-ccl_device_inline int qbvh_unaligned_node_intersect(
- KernelGlobals *ccl_restrict kg,
- const ssef& isect_near,
- const ssef& isect_far,
+ccl_device_inline int qbvh_unaligned_node_intersect(KernelGlobals *ccl_restrict kg,
+ const ssef &isect_near,
+ const ssef &isect_far,
#ifdef __KERNEL_AVX2__
- const sse3f& org_idir,
+ const sse3f &org_idir,
#endif
- const sse3f& org,
- const sse3f& dir,
- const sse3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- ssef *ccl_restrict dist)
+ const sse3f &org,
+ const sse3f &dir,
+ const sse3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ ssef *ccl_restrict dist)
{
- const int offset = node_addr;
- const ssef tfm_x_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+1);
- const ssef tfm_x_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+2);
- const ssef tfm_x_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+3);
+ const int offset = node_addr;
+ const ssef tfm_x_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 1);
+ const ssef tfm_x_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 2);
+ const ssef tfm_x_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 3);
- const ssef tfm_y_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+4);
- const ssef tfm_y_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+5);
- const ssef tfm_y_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+6);
+ const ssef tfm_y_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 4);
+ const ssef tfm_y_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 5);
+ const ssef tfm_y_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 6);
- const ssef tfm_z_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+7);
- const ssef tfm_z_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+8);
- const ssef tfm_z_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+9);
+ const ssef tfm_z_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 7);
+ const ssef tfm_z_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 8);
+ const ssef tfm_z_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 9);
- const ssef tfm_t_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+10);
- const ssef tfm_t_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+11);
- const ssef tfm_t_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+12);
+ const ssef tfm_t_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 10);
+ const ssef tfm_t_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 11);
+ const ssef tfm_t_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 12);
- const ssef aligned_dir_x = dir.x*tfm_x_x + dir.y*tfm_x_y + dir.z*tfm_x_z,
- aligned_dir_y = dir.x*tfm_y_x + dir.y*tfm_y_y + dir.z*tfm_y_z,
- aligned_dir_z = dir.x*tfm_z_x + dir.y*tfm_z_y + dir.z*tfm_z_z;
+ const ssef aligned_dir_x = dir.x * tfm_x_x + dir.y * tfm_x_y + dir.z * tfm_x_z,
+ aligned_dir_y = dir.x * tfm_y_x + dir.y * tfm_y_y + dir.z * tfm_y_z,
+ aligned_dir_z = dir.x * tfm_z_x + dir.y * tfm_z_y + dir.z * tfm_z_z;
- const ssef aligned_P_x = org.x*tfm_x_x + org.y*tfm_x_y + org.z*tfm_x_z + tfm_t_x,
- aligned_P_y = org.x*tfm_y_x + org.y*tfm_y_y + org.z*tfm_y_z + tfm_t_y,
- aligned_P_z = org.x*tfm_z_x + org.y*tfm_z_y + org.z*tfm_z_z + tfm_t_z;
+ const ssef aligned_P_x = org.x * tfm_x_x + org.y * tfm_x_y + org.z * tfm_x_z + tfm_t_x,
+ aligned_P_y = org.x * tfm_y_x + org.y * tfm_y_y + org.z * tfm_y_z + tfm_t_y,
+ aligned_P_z = org.x * tfm_z_x + org.y * tfm_z_y + org.z * tfm_z_z + tfm_t_z;
- const ssef neg_one(-1.0f, -1.0f, -1.0f, -1.0f);
- const ssef nrdir_x = neg_one / aligned_dir_x,
- nrdir_y = neg_one / aligned_dir_y,
- nrdir_z = neg_one / aligned_dir_z;
+ const ssef neg_one(-1.0f, -1.0f, -1.0f, -1.0f);
+ const ssef nrdir_x = neg_one / aligned_dir_x, nrdir_y = neg_one / aligned_dir_y,
+ nrdir_z = neg_one / aligned_dir_z;
- const ssef tlower_x = aligned_P_x * nrdir_x,
- tlower_y = aligned_P_y * nrdir_y,
- tlower_z = aligned_P_z * nrdir_z;
+ const ssef tlower_x = aligned_P_x * nrdir_x, tlower_y = aligned_P_y * nrdir_y,
+ tlower_z = aligned_P_z * nrdir_z;
- const ssef tupper_x = tlower_x - nrdir_x,
- tupper_y = tlower_y - nrdir_y,
- tupper_z = tlower_z - nrdir_z;
+ const ssef tupper_x = tlower_x - nrdir_x, tupper_y = tlower_y - nrdir_y,
+ tupper_z = tlower_z - nrdir_z;
#ifdef __KERNEL_SSE41__
- const ssef tnear_x = mini(tlower_x, tupper_x);
- const ssef tnear_y = mini(tlower_y, tupper_y);
- const ssef tnear_z = mini(tlower_z, tupper_z);
- const ssef tfar_x = maxi(tlower_x, tupper_x);
- const ssef tfar_y = maxi(tlower_y, tupper_y);
- const ssef tfar_z = maxi(tlower_z, tupper_z);
- const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- const sseb vmask = tnear <= tfar;
- *dist = tnear;
- return movemask(vmask);
+ const ssef tnear_x = mini(tlower_x, tupper_x);
+ const ssef tnear_y = mini(tlower_y, tupper_y);
+ const ssef tnear_z = mini(tlower_z, tupper_z);
+ const ssef tfar_x = maxi(tlower_x, tupper_x);
+ const ssef tfar_y = maxi(tlower_y, tupper_y);
+ const ssef tfar_z = maxi(tlower_z, tupper_z);
+ const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ const sseb vmask = tnear <= tfar;
+ *dist = tnear;
+ return movemask(vmask);
#else
- const ssef tnear_x = min(tlower_x, tupper_x);
- const ssef tnear_y = min(tlower_y, tupper_y);
- const ssef tnear_z = min(tlower_z, tupper_z);
- const ssef tfar_x = max(tlower_x, tupper_x);
- const ssef tfar_y = max(tlower_y, tupper_y);
- const ssef tfar_z = max(tlower_z, tupper_z);
- const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- const sseb vmask = tnear <= tfar;
- *dist = tnear;
- return movemask(vmask);
+ const ssef tnear_x = min(tlower_x, tupper_x);
+ const ssef tnear_y = min(tlower_y, tupper_y);
+ const ssef tnear_z = min(tlower_z, tupper_z);
+ const ssef tfar_x = max(tlower_x, tupper_x);
+ const ssef tfar_y = max(tlower_y, tupper_y);
+ const ssef tfar_z = max(tlower_z, tupper_z);
+ const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ const sseb vmask = tnear <= tfar;
+ *dist = tnear;
+ return movemask(vmask);
#endif
}
-ccl_device_inline int qbvh_unaligned_node_intersect_robust(
- KernelGlobals *ccl_restrict kg,
- const ssef& isect_near,
- const ssef& isect_far,
+ccl_device_inline int qbvh_unaligned_node_intersect_robust(KernelGlobals *ccl_restrict kg,
+ const ssef &isect_near,
+ const ssef &isect_far,
#ifdef __KERNEL_AVX2__
- const sse3f& P_idir,
+ const sse3f &P_idir,
#endif
- const sse3f& P,
- const sse3f& dir,
- const sse3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- const float difl,
- ssef *ccl_restrict dist)
+ const sse3f &P,
+ const sse3f &dir,
+ const sse3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ const float difl,
+ ssef *ccl_restrict dist)
{
- const int offset = node_addr;
- const ssef tfm_x_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+1);
- const ssef tfm_x_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+2);
- const ssef tfm_x_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+3);
+ const int offset = node_addr;
+ const ssef tfm_x_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 1);
+ const ssef tfm_x_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 2);
+ const ssef tfm_x_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 3);
- const ssef tfm_y_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+4);
- const ssef tfm_y_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+5);
- const ssef tfm_y_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+6);
+ const ssef tfm_y_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 4);
+ const ssef tfm_y_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 5);
+ const ssef tfm_y_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 6);
- const ssef tfm_z_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+7);
- const ssef tfm_z_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+8);
- const ssef tfm_z_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+9);
+ const ssef tfm_z_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 7);
+ const ssef tfm_z_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 8);
+ const ssef tfm_z_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 9);
- const ssef tfm_t_x = kernel_tex_fetch_ssef(__bvh_nodes, offset+10);
- const ssef tfm_t_y = kernel_tex_fetch_ssef(__bvh_nodes, offset+11);
- const ssef tfm_t_z = kernel_tex_fetch_ssef(__bvh_nodes, offset+12);
+ const ssef tfm_t_x = kernel_tex_fetch_ssef(__bvh_nodes, offset + 10);
+ const ssef tfm_t_y = kernel_tex_fetch_ssef(__bvh_nodes, offset + 11);
+ const ssef tfm_t_z = kernel_tex_fetch_ssef(__bvh_nodes, offset + 12);
- const ssef aligned_dir_x = dir.x*tfm_x_x + dir.y*tfm_x_y + dir.z*tfm_x_z,
- aligned_dir_y = dir.x*tfm_y_x + dir.y*tfm_y_y + dir.z*tfm_y_z,
- aligned_dir_z = dir.x*tfm_z_x + dir.y*tfm_z_y + dir.z*tfm_z_z;
+ const ssef aligned_dir_x = dir.x * tfm_x_x + dir.y * tfm_x_y + dir.z * tfm_x_z,
+ aligned_dir_y = dir.x * tfm_y_x + dir.y * tfm_y_y + dir.z * tfm_y_z,
+ aligned_dir_z = dir.x * tfm_z_x + dir.y * tfm_z_y + dir.z * tfm_z_z;
- const ssef aligned_P_x = P.x*tfm_x_x + P.y*tfm_x_y + P.z*tfm_x_z + tfm_t_x,
- aligned_P_y = P.x*tfm_y_x + P.y*tfm_y_y + P.z*tfm_y_z + tfm_t_y,
- aligned_P_z = P.x*tfm_z_x + P.y*tfm_z_y + P.z*tfm_z_z + tfm_t_z;
+ const ssef aligned_P_x = P.x * tfm_x_x + P.y * tfm_x_y + P.z * tfm_x_z + tfm_t_x,
+ aligned_P_y = P.x * tfm_y_x + P.y * tfm_y_y + P.z * tfm_y_z + tfm_t_y,
+ aligned_P_z = P.x * tfm_z_x + P.y * tfm_z_y + P.z * tfm_z_z + tfm_t_z;
- const ssef neg_one(-1.0f, -1.0f, -1.0f, -1.0f);
- const ssef nrdir_x = neg_one / aligned_dir_x,
- nrdir_y = neg_one / aligned_dir_y,
- nrdir_z = neg_one / aligned_dir_z;
+ const ssef neg_one(-1.0f, -1.0f, -1.0f, -1.0f);
+ const ssef nrdir_x = neg_one / aligned_dir_x, nrdir_y = neg_one / aligned_dir_y,
+ nrdir_z = neg_one / aligned_dir_z;
- const ssef tlower_x = aligned_P_x * nrdir_x,
- tlower_y = aligned_P_y * nrdir_y,
- tlower_z = aligned_P_z * nrdir_z;
+ const ssef tlower_x = aligned_P_x * nrdir_x, tlower_y = aligned_P_y * nrdir_y,
+ tlower_z = aligned_P_z * nrdir_z;
- const ssef tupper_x = tlower_x - nrdir_x,
- tupper_y = tlower_y - nrdir_y,
- tupper_z = tlower_z - nrdir_z;
+ const ssef tupper_x = tlower_x - nrdir_x, tupper_y = tlower_y - nrdir_y,
+ tupper_z = tlower_z - nrdir_z;
- const float round_down = 1.0f - difl;
- const float round_up = 1.0f + difl;
+ const float round_down = 1.0f - difl;
+ const float round_up = 1.0f + difl;
#ifdef __KERNEL_SSE41__
- const ssef tnear_x = mini(tlower_x, tupper_x);
- const ssef tnear_y = mini(tlower_y, tupper_y);
- const ssef tnear_z = mini(tlower_z, tupper_z);
- const ssef tfar_x = maxi(tlower_x, tupper_x);
- const ssef tfar_y = maxi(tlower_y, tupper_y);
- const ssef tfar_z = maxi(tlower_z, tupper_z);
+ const ssef tnear_x = mini(tlower_x, tupper_x);
+ const ssef tnear_y = mini(tlower_y, tupper_y);
+ const ssef tnear_z = mini(tlower_z, tupper_z);
+ const ssef tfar_x = maxi(tlower_x, tupper_x);
+ const ssef tfar_y = maxi(tlower_y, tupper_y);
+ const ssef tfar_z = maxi(tlower_z, tupper_z);
#else
- const ssef tnear_x = min(tlower_x, tupper_x);
- const ssef tnear_y = min(tlower_y, tupper_y);
- const ssef tnear_z = min(tlower_z, tupper_z);
- const ssef tfar_x = max(tlower_x, tupper_x);
- const ssef tfar_y = max(tlower_y, tupper_y);
- const ssef tfar_z = max(tlower_z, tupper_z);
+ const ssef tnear_x = min(tlower_x, tupper_x);
+ const ssef tnear_y = min(tlower_y, tupper_y);
+ const ssef tnear_z = min(tlower_z, tupper_z);
+ const ssef tfar_x = max(tlower_x, tupper_x);
+ const ssef tfar_y = max(tlower_y, tupper_y);
+ const ssef tfar_z = max(tlower_z, tupper_z);
#endif
- const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
- const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
- const sseb vmask = round_down*tnear <= round_up*tfar;
- *dist = tnear;
- return movemask(vmask);
+ const ssef tnear = max4(isect_near, tnear_x, tnear_y, tnear_z);
+ const ssef tfar = min4(isect_far, tfar_x, tfar_y, tfar_z);
+ const sseb vmask = round_down * tnear <= round_up * tfar;
+ *dist = tnear;
+ return movemask(vmask);
}
/* Intersectors wrappers.
@@ -356,111 +392,125 @@ ccl_device_inline int qbvh_unaligned_node_intersect_robust(
* They'll check node type and call appropriate intersection code.
*/
-ccl_device_inline int qbvh_node_intersect(
- KernelGlobals *ccl_restrict kg,
- const ssef& isect_near,
- const ssef& isect_far,
+ccl_device_inline int qbvh_node_intersect(KernelGlobals *ccl_restrict kg,
+ const ssef &isect_near,
+ const ssef &isect_far,
#ifdef __KERNEL_AVX2__
- const sse3f& org_idir,
+ const sse3f &org_idir,
#endif
- const sse3f& org,
- const sse3f& dir,
- const sse3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- ssef *ccl_restrict dist)
+ const sse3f &org,
+ const sse3f &dir,
+ const sse3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ ssef *ccl_restrict dist)
{
- const int offset = node_addr;
- const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return qbvh_unaligned_node_intersect(kg,
- isect_near,
- isect_far,
+ const int offset = node_addr;
+ const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return qbvh_unaligned_node_intersect(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- org_idir,
+ org_idir,
#endif
- org,
- dir,
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- dist);
- }
- else {
- return qbvh_aligned_node_intersect(kg,
- isect_near,
- isect_far,
+ org,
+ dir,
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ dist);
+ }
+ else {
+ return qbvh_aligned_node_intersect(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- org_idir,
+ org_idir,
#else
- org,
+ org,
#endif
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- dist);
- }
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ dist);
+ }
}
-ccl_device_inline int qbvh_node_intersect_robust(
- KernelGlobals *ccl_restrict kg,
- const ssef& isect_near,
- const ssef& isect_far,
+ccl_device_inline int qbvh_node_intersect_robust(KernelGlobals *ccl_restrict kg,
+ const ssef &isect_near,
+ const ssef &isect_far,
#ifdef __KERNEL_AVX2__
- const sse3f& P_idir,
+ const sse3f &P_idir,
#endif
- const sse3f& P,
- const sse3f& dir,
- const sse3f& idir,
- const int near_x,
- const int near_y,
- const int near_z,
- const int far_x,
- const int far_y,
- const int far_z,
- const int node_addr,
- const float difl,
- ssef *ccl_restrict dist)
+ const sse3f &P,
+ const sse3f &dir,
+ const sse3f &idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int node_addr,
+ const float difl,
+ ssef *ccl_restrict dist)
{
- const int offset = node_addr;
- const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
- if(__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
- return qbvh_unaligned_node_intersect_robust(kg,
- isect_near,
- isect_far,
+ const int offset = node_addr;
+ const float4 node = kernel_tex_fetch(__bvh_nodes, offset);
+ if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
+ return qbvh_unaligned_node_intersect_robust(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- P_idir,
+ P_idir,
#endif
- P,
- dir,
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- difl,
- dist);
- }
- else {
- return qbvh_aligned_node_intersect_robust(kg,
- isect_near,
- isect_far,
+ P,
+ dir,
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ difl,
+ dist);
+ }
+ else {
+ return qbvh_aligned_node_intersect_robust(kg,
+ isect_near,
+ isect_far,
#ifdef __KERNEL_AVX2__
- P_idir,
+ P_idir,
#else
- P,
+ P,
#endif
- idir,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- difl,
- dist);
- }
+ idir,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ difl,
+ dist);
+ }
}
diff --git a/intern/cycles/kernel/bvh/qbvh_shadow_all.h b/intern/cycles/kernel/bvh/qbvh_shadow_all.h
index dd977fb9e74..49e607bfbd0 100644
--- a/intern/cycles/kernel/bvh/qbvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/qbvh_shadow_all.h
@@ -36,439 +36,424 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
const uint max_hits,
uint *num_hits)
{
- /* TODO(sergey):
- * - Test if pushing distance on the stack helps.
- * - Likely and unlikely for if() statements.
- * - Test restrict attribute for pointers.
- */
-
- /* Traversal stack in CUDA thread-local memory. */
- QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
-
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* Ray parameters in registers. */
- const float tmax = ray->t;
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = tmax;
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps.
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- *num_hits = 0;
- isect_array->t = tmax;
-
+ *num_hits = 0;
+ isect_array->t = tmax;
#if BVH_FEATURE(BVH_INSTANCING)
- int num_hits_in_instance = 0;
+ int num_hits_in_instance = 0;
#endif
- ssef tnear(0.0f), tfar(isect_t);
+ ssef tnear(0.0f), tfar(isect_t);
#if BVH_FEATURE(BVH_HAIR)
- sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
#endif
- sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
+ sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
-
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- (void) inodes;
-
- if(false
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ (void)inodes;
+
+ if (false
#ifdef __VISIBILITY_FLAG__
- || ((__float_as_uint(inodes.x) & visibility) == 0)
+ || ((__float_as_uint(inodes.x) & visibility) == 0)
#endif
#if BVH_FEATURE(BVH_MOTION)
- || UNLIKELY(ray->time < inodes.y)
- || UNLIKELY(ray->time > inodes.z)
+ || UNLIKELY(ray->time < inodes.y) || UNLIKELY(ray->time > inodes.z)
#endif
- ) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- ssef dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ ) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ ssef dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
-
- if(child_mask != 0) {
- float4 cnodes;
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+
+ if (child_mask != 0) {
+ float4 cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+13);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 13);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+7);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- }
-
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
+ {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 7);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(leaf.z) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ if ((__float_as_uint(leaf.z) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
#endif
- int prim_addr = __float_as_int(leaf.x);
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- const uint p_type = type & PRIMITIVE_ALL;
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
-
- /* Primitive intersection. */
- while(prim_addr < prim_addr2) {
- kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
- bool hit;
-
- /* todo: specialized intersect functions which don't fill in
- * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
- * might give a few % performance improvement */
-
- switch(p_type) {
- case PRIMITIVE_TRIANGLE: {
- hit = triangle_intersect(kg,
- isect_array,
- P,
- dir,
- visibility,
- object,
- prim_addr);
- break;
- }
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ while (prim_addr < prim_addr2) {
+ kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
+ bool hit;
+
+ /* todo: specialized intersect functions which don't fill in
+ * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
+ * might give a few % performance improvement */
+
+ switch (p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- hit = motion_triangle_intersect(kg,
- isect_array,
- P,
- dir,
- ray->time,
- visibility,
- object,
- prim_addr);
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ hit = motion_triangle_intersect(
+ kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
+ break;
+ }
#endif
#if BVH_FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = cardinal_curve_intersect(kg,
- isect_array,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
- }
- else {
- hit = curve_intersect(kg,
- isect_array,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
- }
- break;
- }
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ if (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
+ hit = cardinal_curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0,
+ 0);
+ }
+ else {
+ hit = curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0,
+ 0);
+ }
+ break;
+ }
#endif
- default: {
- hit = false;
- break;
- }
- }
+ default: {
+ hit = false;
+ break;
+ }
+ }
- /* Shadow ray early termination. */
- if(hit) {
- /* detect if this surface has a shader with transparent shadows */
+ /* Shadow ray early termination. */
+ if (hit) {
+ /* detect if this surface has a shader with transparent shadows */
- /* todo: optimize so primitive visibility flag indicates if
- * the primitive has a transparent shadow shader? */
- int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
- int shader = 0;
+ /* todo: optimize so primitive visibility flag indicates if
+ * the primitive has a transparent shadow shader? */
+ int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
+ int shader = 0;
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
+ if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
#endif
- {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
#ifdef __HAIR__
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
#endif
- int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
-
- /* if no transparent shadows, all light is blocked */
- if(!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
- return true;
- }
- /* if maximum number of hits reached, block all light */
- else if(*num_hits == max_hits) {
- return true;
- }
-
- /* move on to next entry in intersections array */
- isect_array++;
- (*num_hits)++;
+ int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+
+ /* if no transparent shadows, all light is blocked */
+ if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ return true;
+ }
+ /* if maximum number of hits reached, block all light */
+ else if (*num_hits == max_hits) {
+ return true;
+ }
+
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
#endif
- isect_array->t = isect_t;
- }
+ isect_array->t = isect_t;
+ }
- prim_addr++;
- }
- }
+ prim_addr++;
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
# if BVH_FEATURE(BVH_MOTION)
- isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
+ isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
# else
- isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
# endif
- num_hits_in_instance = 0;
- isect_array->t = isect_t;
+ num_hits_in_instance = 0;
+ isect_array->t = isect_t;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect_t);
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect_t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
- if(num_hits_in_instance) {
- float t_fac;
+ /* Instance pop. */
+ if (num_hits_in_instance) {
+ float t_fac;
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
# else
- bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
# endif
- /* Scale isect->t to adjust for instancing. */
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
- else {
+ /* Scale isect->t to adjust for instancing. */
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+ else {
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
# else
- bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
# endif
- }
+ }
- isect_t = tmax;
- isect_array->t = isect_t;
+ isect_t = tmax;
+ isect_array->t = isect_t;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect_t);
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect_t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return false;
+ return false;
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/qbvh_traversal.h b/intern/cycles/kernel/bvh/qbvh_traversal.h
index 40cd57aad34..9ee0f7b5933 100644
--- a/intern/cycles/kernel/bvh/qbvh_traversal.h
+++ b/intern/cycles/kernel/bvh/qbvh_traversal.h
@@ -37,457 +37,446 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
Intersection *isect,
const uint visibility
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- ,uint *lcg_state,
+ ,
+ uint *lcg_state,
float difl,
float extmax
#endif
- )
+)
{
- /* TODO(sergey):
- * - Test if pushing distance on the stack helps (for non shadow rays).
- * - Separate version for shadow rays.
- * - Likely and unlikely for if() statements.
- * - Test restrict attribute for pointers.
- */
-
- /* Traversal stack in CUDA thread-local memory. */
- QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
- traversal_stack[0].dist = -FLT_MAX;
-
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
- float node_dist = -FLT_MAX;
-
- /* Ray parameters in registers. */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps (for non shadow rays).
+ * - Separate version for shadow rays.
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+ traversal_stack[0].dist = -FLT_MAX;
+
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+ float node_dist = -FLT_MAX;
+
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- isect->t = ray->t;
- isect->u = 0.0f;
- isect->v = 0.0f;
- isect->prim = PRIM_NONE;
- isect->object = OBJECT_NONE;
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
- BVH_DEBUG_INIT();
+ BVH_DEBUG_INIT();
- ssef tnear(0.0f), tfar(ray->t);
+ ssef tnear(0.0f), tfar(ray->t);
#if BVH_FEATURE(BVH_HAIR)
- sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
#endif
- sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- sse3f P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ sse3f P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- sse3f org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ sse3f org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
-
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
- (void) inodes;
-
- if(UNLIKELY(node_dist > isect->t)
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ (void)inodes;
+
+ if (UNLIKELY(node_dist > isect->t)
#if BVH_FEATURE(BVH_MOTION)
- || UNLIKELY(ray->time < inodes.y)
- || UNLIKELY(ray->time > inodes.z)
+ || UNLIKELY(ray->time < inodes.y) || UNLIKELY(ray->time > inodes.z)
#endif
#ifdef __VISIBILITY_FLAG__
- || (__float_as_uint(inodes.x) & visibility) == 0
+ || (__float_as_uint(inodes.x) & visibility) == 0
#endif
- )
- {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
+ ) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
- int child_mask;
- ssef dist;
+ int child_mask;
+ ssef dist;
- BVH_DEBUG_NEXT_NODE();
+ BVH_DEBUG_NEXT_NODE();
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- if(difl != 0.0f) {
- /* NOTE: We extend all the child BB instead of fetching
- * and checking visibility flags for each of the,
- *
- * Need to test if doing opposite would be any faster.
- */
- child_mask = NODE_INTERSECT_ROBUST(kg,
- tnear,
- tfar,
+ if (difl != 0.0f) {
+ /* NOTE: We extend all the child BB instead of fetching
+ * and checking visibility flags for each of the,
+ *
+ * Need to test if doing opposite would be any faster.
+ */
+ child_mask = NODE_INTERSECT_ROBUST(kg,
+ tnear,
+ tfar,
# ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
# endif
# if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
# endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- difl,
- &dist);
- }
- else
-#endif /* BVH_HAIR_MINIMUM_WIDTH */
- {
- child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ difl,
+ &dist);
+ }
+ else
+#endif /* BVH_HAIR_MINIMUM_WIDTH */
+ {
+ child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
- }
-
- if(child_mask != 0) {
- float4 cnodes;
- /* TODO(sergey): Investigate whether moving cnodes upwards
- * gives a speedup (will be different cache pattern but will
- * avoid extra check here).
- */
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+ }
+
+ if (child_mask != 0) {
+ float4 cnodes;
+ /* TODO(sergey): Investigate whether moving cnodes upwards
+ * gives a speedup (will be different cache pattern but will
+ * avoid extra check here).
+ */
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+13);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 13);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+7);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- float d0 = ((float*)&dist)[r];
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- node_dist = d0;
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- node_dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- node_dist = d0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- }
-
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
+ {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 7);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ float d0 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ node_dist = d0;
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ node_dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ node_dist = d0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
#ifdef __VISIBILITY_FLAG__
- if(UNLIKELY((node_dist > isect->t) ||
- ((__float_as_uint(leaf.z) & visibility) == 0)))
+ if (UNLIKELY((node_dist > isect->t) || ((__float_as_uint(leaf.z) & visibility) == 0)))
#else
- if(UNLIKELY((node_dist > isect->t)))
+ if (UNLIKELY((node_dist > isect->t)))
#endif
- {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- continue;
- }
+ {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ continue;
+ }
- int prim_addr = __float_as_int(leaf.x);
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
-
- /* Primitive intersection. */
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(triangle_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr)) {
- tfar = ssef(isect->t);
- /* Shadow ray early termination. */
- if(visibility & PATH_RAY_SHADOW_OPAQUE) {
- return true;
- }
- }
- }
- break;
- }
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ switch (type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr)) {
+ tfar = ssef(isect->t);
+ /* Shadow ray early termination. */
+ if (visibility & PATH_RAY_SHADOW_OPAQUE) {
+ return true;
+ }
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if(motion_triangle_intersect(kg,
- isect,
- P,
- dir,
- ray->time,
- visibility,
- object,
- prim_addr)) {
- tfar = ssef(isect->t);
- /* Shadow ray early termination. */
- if(visibility & PATH_RAY_SHADOW_OPAQUE) {
- return true;
- }
- }
- }
- break;
- }
-#endif /* BVH_FEATURE(BVH_MOTION) */
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ if (motion_triangle_intersect(
+ kg, isect, P, dir, ray->time, visibility, object, prim_addr)) {
+ tfar = ssef(isect->t);
+ /* Shadow ray early termination. */
+ if (visibility & PATH_RAY_SHADOW_OPAQUE) {
+ return true;
+ }
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_MOTION) */
#if BVH_FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- BVH_DEBUG_NEXT_INTERSECTION();
- const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
- kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
- bool hit;
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = cardinal_curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
- }
- else {
- hit = curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
- }
- if(hit) {
- tfar = ssef(isect->t);
- /* Shadow ray early termination. */
- if(visibility & PATH_RAY_SHADOW_OPAQUE) {
- return true;
- }
- }
- }
- break;
- }
-#endif /* BVH_FEATURE(BVH_HAIR) */
- }
- }
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ BVH_DEBUG_NEXT_INTERSECTION();
+ const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
+ bool hit;
+ if (kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
+ hit = cardinal_curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
+ }
+ else {
+ hit = curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
+ }
+ if (hit) {
+ tfar = ssef(isect->t);
+ /* Shadow ray early termination. */
+ if (visibility & PATH_RAY_SHADOW_OPAQUE) {
+ return true;
+ }
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_HAIR) */
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
# if BVH_FEATURE(BVH_MOTION)
- qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist, &ob_itfm);
+ qbvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist, &ob_itfm);
# else
- qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist);
+ qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &node_dist);
# endif
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect->t);
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
- traversal_stack[stack_ptr].dist = -FLT_MAX;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
+ traversal_stack[stack_ptr].dist = -FLT_MAX;
- node_addr = kernel_tex_fetch(__object_node, object);
+ node_addr = kernel_tex_fetch(__object_node, object);
- BVH_DEBUG_NEXT_INSTANCE();
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ BVH_DEBUG_NEXT_INSTANCE();
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
+ /* Instance pop. */
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect->t);
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- node_dist = traversal_stack[stack_ptr].dist;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ node_dist = traversal_stack[stack_ptr].dist;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return (isect->prim != PRIM_NONE);
+ return (isect->prim != PRIM_NONE);
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/qbvh_volume.h b/intern/cycles/kernel/bvh/qbvh_volume.h
index 6790bfa6c83..e4eaed04467 100644
--- a/intern/cycles/kernel/bvh/qbvh_volume.h
+++ b/intern/cycles/kernel/bvh/qbvh_volume.h
@@ -33,331 +33,335 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
Intersection *isect,
const uint visibility)
{
- /* TODO(sergey):
- * - Test if pushing distance on the stack helps.
- * - Likely and unlikely for if() statements.
- * - Test restrict attribute for pointers.
- */
-
- /* Traversal stack in CUDA thread-local memory. */
- QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
-
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* Ray parameters in registers. */
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps.
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- isect->t = ray->t;
- isect->u = 0.0f;
- isect->v = 0.0f;
- isect->prim = PRIM_NONE;
- isect->object = OBJECT_NONE;
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
- ssef tnear(0.0f), tfar(ray->t);
+ ssef tnear(0.0f), tfar(ray->t);
#if BVH_FEATURE(BVH_HAIR)
- sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
#endif
- sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
+ sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(inodes.x) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ if ((__float_as_uint(inodes.x) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
#endif
- ssef dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ ssef dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
-
- if(child_mask != 0) {
- float4 cnodes;
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+
+ if (child_mask != 0) {
+ float4 cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+13);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 13);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+7);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- }
-
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
-
- if((__float_as_uint(leaf.z) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- int prim_addr = __float_as_int(leaf.x);
+ {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 7);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+
+ if ((__float_as_uint(leaf.z) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- const uint p_type = type & PRIMITIVE_ALL;
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
-
- /* Primitive intersection. */
- switch(p_type) {
- case PRIMITIVE_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr);
- }
- break;
- }
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ switch (p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ triangle_intersect(kg, isect, P, dir, visibility, object, prim_addr);
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, prim_addr);
- }
- break;
- }
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ motion_triangle_intersect(
+ kg, isect, P, dir, ray->time, visibility, object, prim_addr);
+ }
+ break;
+ }
#endif
- }
- }
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VOLUME) {
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_HAS_VOLUME) {
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect->t);
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
- }
- else {
- /* Pop. */
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
+
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* Pop. */
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
+ /* Instance pop. */
# if BVH_FEATURE(BVH_MOTION)
- isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
+ isect->t = bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, isect->t, &ob_itfm);
# else
- isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
+ isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
# endif
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect->t);
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect->t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return (isect->prim != PRIM_NONE);
+ return (isect->prim != PRIM_NONE);
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/bvh/qbvh_volume_all.h b/intern/cycles/kernel/bvh/qbvh_volume_all.h
index 63d79b6fe34..eddc48c487e 100644
--- a/intern/cycles/kernel/bvh/qbvh_volume_all.h
+++ b/intern/cycles/kernel/bvh/qbvh_volume_all.h
@@ -34,405 +34,411 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
const uint max_hits,
const uint visibility)
{
- /* TODO(sergey):
- * - Test if pushing distance on the stack helps.
- * - Likely and unlikely for if() statements.
- * - Test restrict attribute for pointers.
- */
-
- /* Traversal stack in CUDA thread-local memory. */
- QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
- traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
-
- /* Traversal variables in registers. */
- int stack_ptr = 0;
- int node_addr = kernel_data.bvh.root;
-
- /* Ray parameters in registers. */
- const float tmax = ray->t;
- float3 P = ray->P;
- float3 dir = bvh_clamp_direction(ray->D);
- float3 idir = bvh_inverse_direction(dir);
- int object = OBJECT_NONE;
- float isect_t = tmax;
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps.
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversal_stack[BVH_QSTACK_SIZE];
+ traversal_stack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stack_ptr = 0;
+ int node_addr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_itfm;
+ Transform ob_itfm;
#endif
- uint num_hits = 0;
- isect_array->t = tmax;
+ uint num_hits = 0;
+ isect_array->t = tmax;
#if BVH_FEATURE(BVH_INSTANCING)
- int num_hits_in_instance = 0;
+ int num_hits_in_instance = 0;
#endif
- ssef tnear(0.0f), tfar(isect_t);
+ ssef tnear(0.0f), tfar(isect_t);
#if BVH_FEATURE(BVH_HAIR)
- sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
#endif
- sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
#ifdef __KERNEL_AVX2__
- float3 P_idir = P*idir;
- sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
+ float3 P_idir = P * idir;
+ sse3f P_idir4(P_idir.x, P_idir.y, P_idir.z);
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
+ sse3f org4(ssef(P.x), ssef(P.y), ssef(P.z));
#endif
- /* Offsets to select the side that becomes the lower or upper bound. */
- int near_x, near_y, near_z;
- int far_x, far_y, far_z;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
- /* Traversal loop. */
- do {
- do {
- /* Traverse internal nodes. */
- while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
- float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0);
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
+ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(inodes.x) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
+ if ((__float_as_uint(inodes.x) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
#endif
- ssef dist;
- int child_mask = NODE_INTERSECT(kg,
- tnear,
- tfar,
+ ssef dist;
+ int child_mask = NODE_INTERSECT(kg,
+ tnear,
+ tfar,
#ifdef __KERNEL_AVX2__
- P_idir4,
+ P_idir4,
#endif
#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4,
+ org4,
#endif
#if BVH_FEATURE(BVH_HAIR)
- dir4,
+ dir4,
#endif
- idir4,
- near_x, near_y, near_z,
- far_x, far_y, far_z,
- node_addr,
- &dist);
-
- if(child_mask != 0) {
- float4 cnodes;
+ idir4,
+ near_x,
+ near_y,
+ near_z,
+ far_x,
+ far_y,
+ far_z,
+ node_addr,
+ &dist);
+
+ if (child_mask != 0) {
+ float4 cnodes;
#if BVH_FEATURE(BVH_HAIR)
- if(__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+13);
- }
- else
+ if (__float_as_uint(inodes.x) & PATH_RAY_NODE_UNALIGNED) {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 13);
+ }
+ else
#endif
- {
- cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+7);
- }
-
- /* One child is hit, continue with that child. */
- int r = __bscf(child_mask);
- if(child_mask == 0) {
- node_addr = __float_as_int(cnodes[r]);
- continue;
- }
-
- /* Two children are hit, push far child, and continue with
- * closer child.
- */
- int c0 = __float_as_int(cnodes[r]);
- float d0 = ((float*)&dist)[r];
- r = __bscf(child_mask);
- int c1 = __float_as_int(cnodes[r]);
- float d1 = ((float*)&dist)[r];
- if(child_mask == 0) {
- if(d1 < d0) {
- node_addr = c1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
- continue;
- }
- else {
- node_addr = c0;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- continue;
- }
- }
-
- /* Here starts the slow path for 3 or 4 hit children. We push
- * all nodes onto the stack to sort them there.
- */
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c1;
- traversal_stack[stack_ptr].dist = d1;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c0;
- traversal_stack[stack_ptr].dist = d0;
-
- /* Three children are hit, push all onto stack and sort 3
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c2 = __float_as_int(cnodes[r]);
- float d2 = ((float*)&dist)[r];
- if(child_mask == 0) {
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2]);
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- /* Four children are hit, push all onto stack and sort 4
- * stack items, continue with closest child.
- */
- r = __bscf(child_mask);
- int c3 = __float_as_int(cnodes[r]);
- float d3 = ((float*)&dist)[r];
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c3;
- traversal_stack[stack_ptr].dist = d3;
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = c2;
- traversal_stack[stack_ptr].dist = d2;
- qbvh_stack_sort(&traversal_stack[stack_ptr],
- &traversal_stack[stack_ptr - 1],
- &traversal_stack[stack_ptr - 2],
- &traversal_stack[stack_ptr - 3]);
- }
-
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-
- /* If node is leaf, fetch triangle list. */
- if(node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
-
- if((__float_as_uint(leaf.z) & visibility) == 0) {
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- continue;
- }
-
- int prim_addr = __float_as_int(leaf.x);
+ {
+ cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 7);
+ }
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(child_mask);
+ if (child_mask == 0) {
+ node_addr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float *)&dist)[r];
+ r = __bscf(child_mask);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ if (d1 < d0) {
+ node_addr = c1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+ continue;
+ }
+ else {
+ node_addr = c0;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c1;
+ traversal_stack[stack_ptr].dist = d1;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c0;
+ traversal_stack[stack_ptr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float *)&dist)[r];
+ if (child_mask == 0) {
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2]);
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(child_mask);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float *)&dist)[r];
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c3;
+ traversal_stack[stack_ptr].dist = d3;
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = c2;
+ traversal_stack[stack_ptr].dist = d2;
+ qbvh_stack_sort(&traversal_stack[stack_ptr],
+ &traversal_stack[stack_ptr - 1],
+ &traversal_stack[stack_ptr - 2],
+ &traversal_stack[stack_ptr - 3]);
+ }
+
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if (node_addr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+
+ if ((__float_as_uint(leaf.z) & visibility) == 0) {
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ continue;
+ }
+
+ int prim_addr = __float_as_int(leaf.x);
#if BVH_FEATURE(BVH_INSTANCING)
- if(prim_addr >= 0) {
+ if (prim_addr >= 0) {
#endif
- int prim_addr2 = __float_as_int(leaf.y);
- const uint type = __float_as_int(leaf.w);
- const uint p_type = type & PRIMITIVE_ALL;
- bool hit;
-
- /* Pop. */
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
-
- /* Primitive intersection. */
- switch(p_type) {
- case PRIMITIVE_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
- if(hit) {
- /* Move on to next entry in intersections array. */
- isect_array++;
- num_hits++;
+ int prim_addr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+ bool hit;
+
+ /* Pop. */
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+
+ /* Primitive intersection. */
+ switch (p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
+ if (hit) {
+ /* Move on to next entry in intersections array. */
+ isect_array++;
+ num_hits++;
#if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
#endif
- isect_array->t = isect_t;
- if(num_hits == max_hits) {
+ isect_array->t = isect_t;
+ if (num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
- if(object != OBJECT_NONE) {
+ if (object != OBJECT_NONE) {
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- float t_fac = 1.0f / len(transform_direction(&itfm, dir));
+ Transform itfm = object_fetch_transform(
+ kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
# endif
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
-#endif /* BVH_FEATURE(BVH_INSTANCING) */
- return num_hits;
- }
- }
- }
- break;
- }
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+#endif /* BVH_FEATURE(BVH_INSTANCING) */
+ return num_hits;
+ }
+ }
+ }
+ break;
+ }
#if BVH_FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- for(; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- /* Only primitives from volume object. */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
- /* Intersect ray against primitive. */
- hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
- if(hit) {
- /* Move on to next entry in intersections array. */
- isect_array++;
- num_hits++;
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for (; prim_addr < prim_addr2; prim_addr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ hit = motion_triangle_intersect(
+ kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
+ if (hit) {
+ /* Move on to next entry in intersections array. */
+ isect_array++;
+ num_hits++;
# if BVH_FEATURE(BVH_INSTANCING)
- num_hits_in_instance++;
+ num_hits_in_instance++;
# endif
- isect_array->t = isect_t;
- if(num_hits == max_hits) {
+ isect_array->t = isect_t;
+ if (num_hits == max_hits) {
# if BVH_FEATURE(BVH_INSTANCING)
- if(object != OBJECT_NONE) {
+ if (object != OBJECT_NONE) {
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- float t_fac = 1.0f / len(transform_direction(&itfm, dir));
+ Transform itfm = object_fetch_transform(
+ kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
# endif
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
-# endif /* BVH_FEATURE(BVH_INSTANCING) */
- return num_hits;
- }
- }
- }
- break;
- }
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+# endif /* BVH_FEATURE(BVH_INSTANCING) */
+ return num_hits;
+ }
+ }
+ }
+ break;
+ }
#endif
- }
- }
+ }
+ }
#if BVH_FEATURE(BVH_INSTANCING)
- else {
- /* Instance push. */
- object = kernel_tex_fetch(__prim_object, -prim_addr-1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VOLUME) {
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_HAS_VOLUME) {
# if BVH_FEATURE(BVH_MOTION)
- isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
+ isect_t = bvh_instance_motion_push(
+ kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
# else
- isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
+ isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
# endif
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect_t);
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect_t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- num_hits_in_instance = 0;
- isect_array->t = isect_t;
-
- ++stack_ptr;
- kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
- traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
-
- node_addr = kernel_tex_fetch(__object_node, object);
- }
- else {
- /* Pop. */
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
- }
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ num_hits_in_instance = 0;
+ isect_array->t = isect_t;
+
+ ++stack_ptr;
+ kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
+ traversal_stack[stack_ptr].addr = ENTRYPOINT_SENTINEL;
+
+ node_addr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* Pop. */
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
#if BVH_FEATURE(BVH_INSTANCING)
- if(stack_ptr >= 0) {
- kernel_assert(object != OBJECT_NONE);
+ if (stack_ptr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
- /* Instance pop. */
- if(num_hits_in_instance) {
- float t_fac;
+ /* Instance pop. */
+ if (num_hits_in_instance) {
+ float t_fac;
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
# else
- bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
# endif
- /* Scale isect->t to adjust for instancing. */
- for(int i = 0; i < num_hits_in_instance; i++) {
- (isect_array-i-1)->t *= t_fac;
- }
- }
- else {
+ /* Scale isect->t to adjust for instancing. */
+ for (int i = 0; i < num_hits_in_instance; i++) {
+ (isect_array - i - 1)->t *= t_fac;
+ }
+ }
+ else {
# if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
# else
- bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
# endif
- }
+ }
- isect_t = tmax;
- isect_array->t = isect_t;
+ isect_t = tmax;
+ isect_array->t = isect_t;
- qbvh_near_far_idx_calc(idir,
- &near_x, &near_y, &near_z,
- &far_x, &far_y, &far_z);
- tfar = ssef(isect_t);
+ qbvh_near_far_idx_calc(idir, &near_x, &near_y, &near_z, &far_x, &far_y, &far_z);
+ tfar = ssef(isect_t);
# if BVH_FEATURE(BVH_HAIR)
- dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
+ dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z));
# endif
- idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
# ifdef __KERNEL_AVX2__
- P_idir = P*idir;
- P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+ P_idir = P * idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
# endif
# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__)
- org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+ org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
# endif
- object = OBJECT_NONE;
- node_addr = traversal_stack[stack_ptr].addr;
- --stack_ptr;
- }
-#endif /* FEATURE(BVH_INSTANCING) */
- } while(node_addr != ENTRYPOINT_SENTINEL);
+ object = OBJECT_NONE;
+ node_addr = traversal_stack[stack_ptr].addr;
+ --stack_ptr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while (node_addr != ENTRYPOINT_SENTINEL);
- return num_hits;
+ return num_hits;
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h
index acccba9ecec..341d1e16eb1 100644
--- a/intern/cycles/kernel/closure/alloc.h
+++ b/intern/cycles/kernel/closure/alloc.h
@@ -18,69 +18,72 @@ CCL_NAMESPACE_BEGIN
ccl_device ShaderClosure *closure_alloc(ShaderData *sd, int size, ClosureType type, float3 weight)
{
- kernel_assert(size <= sizeof(ShaderClosure));
+ kernel_assert(size <= sizeof(ShaderClosure));
- if(sd->num_closure_left == 0)
- return NULL;
+ if (sd->num_closure_left == 0)
+ return NULL;
- ShaderClosure *sc = &sd->closure[sd->num_closure];
+ ShaderClosure *sc = &sd->closure[sd->num_closure];
- sc->type = type;
- sc->weight = weight;
+ sc->type = type;
+ sc->weight = weight;
- sd->num_closure++;
- sd->num_closure_left--;
+ sd->num_closure++;
+ sd->num_closure_left--;
- return sc;
+ return sc;
}
ccl_device ccl_addr_space void *closure_alloc_extra(ShaderData *sd, int size)
{
- /* Allocate extra space for closure that need more parameters. We allocate
- * in chunks of sizeof(ShaderClosure) starting from the end of the closure
- * array.
- *
- * This lets us keep the same fast array iteration over closures, as we
- * found linked list iteration and iteration with skipping to be slower. */
- int num_extra = ((size + sizeof(ShaderClosure) - 1) / sizeof(ShaderClosure));
-
- if(num_extra > sd->num_closure_left) {
- /* Remove previous closure if it was allocated. */
- sd->num_closure--;
- sd->num_closure_left++;
- return NULL;
- }
-
- sd->num_closure_left -= num_extra;
- return (ccl_addr_space void*)(sd->closure + sd->num_closure + sd->num_closure_left);
+ /* Allocate extra space for closure that need more parameters. We allocate
+ * in chunks of sizeof(ShaderClosure) starting from the end of the closure
+ * array.
+ *
+ * This lets us keep the same fast array iteration over closures, as we
+ * found linked list iteration and iteration with skipping to be slower. */
+ int num_extra = ((size + sizeof(ShaderClosure) - 1) / sizeof(ShaderClosure));
+
+ if (num_extra > sd->num_closure_left) {
+ /* Remove previous closure if it was allocated. */
+ sd->num_closure--;
+ sd->num_closure_left++;
+ return NULL;
+ }
+
+ sd->num_closure_left -= num_extra;
+ return (ccl_addr_space void *)(sd->closure + sd->num_closure + sd->num_closure_left);
}
ccl_device_inline ShaderClosure *bsdf_alloc(ShaderData *sd, int size, float3 weight)
{
- ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
+ ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
- if(sc == NULL)
- return NULL;
+ if (sc == NULL)
+ return NULL;
- float sample_weight = fabsf(average(weight));
- sc->sample_weight = sample_weight;
- return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL;
+ float sample_weight = fabsf(average(weight));
+ sc->sample_weight = sample_weight;
+ return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL;
}
#ifdef __OSL__
-ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd, int size, float3 weight, void *data)
+ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
+ int size,
+ float3 weight,
+ void *data)
{
- ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
+ ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
- if(!sc)
- return NULL;
+ if (!sc)
+ return NULL;
- memcpy((void *)sc, data, size);
+ memcpy((void *)sc, data, size);
- float sample_weight = fabsf(average(weight));
- sc->weight = weight;
- sc->sample_weight = sample_weight;
- return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL;
+ float sample_weight = fabsf(average(weight));
+ sc->weight = weight;
+ sc->sample_weight = sample_weight;
+ return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL;
}
#endif
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 3a9629ea9d7..5e26f90a878 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -39,38 +39,38 @@ CCL_NAMESPACE_BEGIN
* 0 for singular closures and 1 otherwise. */
ccl_device_inline float bsdf_get_specular_roughness_squared(const ShaderClosure *sc)
{
- if(CLOSURE_IS_BSDF_SINGULAR(sc->type)) {
- return 0.0f;
- }
+ if (CLOSURE_IS_BSDF_SINGULAR(sc->type)) {
+ return 0.0f;
+ }
- if(CLOSURE_IS_BSDF_MICROFACET(sc->type)) {
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)sc;
- return bsdf->alpha_x*bsdf->alpha_y;
- }
+ if (CLOSURE_IS_BSDF_MICROFACET(sc->type)) {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
+ return bsdf->alpha_x * bsdf->alpha_y;
+ }
- return 1.0f;
+ return 1.0f;
}
ccl_device_inline float bsdf_get_roughness_squared(const ShaderClosure *sc)
{
- /* This version includes diffuse, mainly for baking Principled BSDF
- * where specular and metallic zero otherwise does not bake the
- * specified roughness parameter. */
- if(sc->type == CLOSURE_BSDF_OREN_NAYAR_ID) {
- OrenNayarBsdf *bsdf = (OrenNayarBsdf*)sc;
- return sqr(sqr(bsdf->roughness));
- }
+ /* This version includes diffuse, mainly for baking Principled BSDF
+ * where specular and metallic zero otherwise does not bake the
+ * specified roughness parameter. */
+ if (sc->type == CLOSURE_BSDF_OREN_NAYAR_ID) {
+ OrenNayarBsdf *bsdf = (OrenNayarBsdf *)sc;
+ return sqr(sqr(bsdf->roughness));
+ }
- if(sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
- PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)sc;
- return sqr(sqr(bsdf->roughness));
- }
+ if (sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
+ PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)sc;
+ return sqr(sqr(bsdf->roughness));
+ }
- if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
- return 0.0f;
- }
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
+ return 0.0f;
+ }
- return bsdf_get_specular_roughness_squared(sc);
+ return bsdf_get_specular_roughness_squared(sc);
}
ccl_device_inline int bsdf_sample(KernelGlobals *kg,
@@ -83,133 +83,349 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
differential3 *domega_in,
float *pdf)
{
- int label;
+ int label;
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_ID:
- label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_ID:
+ label = bsdf_diffuse_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#ifdef __OSL__
- case CLOSURE_BSDF_PHONG_RAMP_ID:
- label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
- label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#endif
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- label = bsdf_microfacet_multi_ggx_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- label = bsdf_microfacet_multi_ggx_glass_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- label = bsdf_microfacet_beckmann_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
- label = bsdf_ashikhmin_shirley_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- label = bsdf_diffuse_toon_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- label = bsdf_glossy_toon_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- label = bsdf_hair_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- label = bsdf_hair_transmission_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- label = bsdf_principled_hair_sample(kg, sc, sd, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
- label = bsdf_principled_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- label = bsdf_principled_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#endif /* __PRINCIPLED__ */
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ label = bsdf_oren_nayar_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+# ifdef __OSL__
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ label = bsdf_phong_ramp_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ label = bsdf_diffuse_ramp_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+# endif
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ label = bsdf_translucent_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ label = bsdf_reflection_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ label = bsdf_refraction_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ label = bsdf_transparent_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ label = bsdf_microfacet_ggx_sample(kg,
+ sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ label = bsdf_microfacet_multi_ggx_sample(kg,
+ sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf,
+ &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ label = bsdf_microfacet_multi_ggx_glass_sample(kg,
+ sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf,
+ &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ label = bsdf_microfacet_beckmann_sample(kg,
+ sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
+ label = bsdf_ashikhmin_shirley_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ label = bsdf_ashikhmin_velvet_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ label = bsdf_diffuse_toon_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ label = bsdf_glossy_toon_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ label = bsdf_hair_reflection_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ label = bsdf_hair_transmission_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ label = bsdf_principled_hair_sample(
+ kg, sc, sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+# ifdef __PRINCIPLED__
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+ label = bsdf_principled_diffuse_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ label = bsdf_principled_sheen_sample(sc,
+ sd->Ng,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+# endif /* __PRINCIPLED__ */
#endif
#ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- label = volume_henyey_greenstein_sample(sc, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
+ case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
+ label = volume_henyey_greenstein_sample(sc,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
#endif
- default:
- label = LABEL_NONE;
- break;
- }
+ default:
+ label = LABEL_NONE;
+ break;
+ }
- /* Test if BSDF sample should be treated as transparent for background. */
- if(label & LABEL_TRANSMIT) {
- float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold;
+ /* Test if BSDF sample should be treated as transparent for background. */
+ if (label & LABEL_TRANSMIT) {
+ float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold;
- if(threshold_squared >= 0.0f) {
- if(bsdf_get_specular_roughness_squared(sc) <= threshold_squared) {
- label |= LABEL_TRANSMIT_TRANSPARENT;
- }
- }
- }
+ if (threshold_squared >= 0.0f) {
+ if (bsdf_get_specular_roughness_squared(sc) <= threshold_squared) {
+ label |= LABEL_TRANSMIT_TRANSPARENT;
+ }
+ }
+ }
- return label;
+ return label;
}
#ifndef __KERNEL_CUDA__
@@ -217,285 +433,288 @@ ccl_device
#else
ccl_device_inline
#endif
-float3 bsdf_eval(KernelGlobals *kg,
- ShaderData *sd,
- const ShaderClosure *sc,
- const float3 omega_in,
- float *pdf)
+ float3
+ bsdf_eval(KernelGlobals *kg,
+ ShaderData *sd,
+ const ShaderClosure *sc,
+ const float3 omega_in,
+ float *pdf)
{
- float3 eval;
+ float3 eval;
- if(dot(sd->Ng, omega_in) >= 0.0f) {
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_ID:
- eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ if (dot(sd->Ng, omega_in) >= 0.0f) {
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_ID:
+ eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __OSL__
- case CLOSURE_BSDF_PHONG_RAMP_ID:
- eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
- eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#endif
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_eval_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_glass_eval_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
- eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- eval = bsdf_diffuse_toon_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- eval = bsdf_glossy_toon_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- eval = bsdf_hair_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- eval = bsdf_hair_transmission_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
- eval = bsdf_principled_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- eval = bsdf_principled_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#endif /* __PRINCIPLED__ */
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+# ifdef __OSL__
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+# endif
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_eval_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_glass_eval_reflect(
+ sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
+ eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ eval = bsdf_diffuse_toon_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ eval = bsdf_glossy_toon_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ eval = bsdf_hair_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ eval = bsdf_hair_transmission_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+# ifdef __PRINCIPLED__
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+ eval = bsdf_principled_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ eval = bsdf_principled_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+# endif /* __PRINCIPLED__ */
#endif
#ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
- break;
+ case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
+ eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
+ break;
#endif
- default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
- break;
- }
- }
- else {
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_ID:
- eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
+ default:
+ eval = make_float3(0.0f, 0.0f, 0.0f);
+ break;
+ }
+ }
+ else {
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_ID:
+ eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_eval_transmit(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_glass_eval_transmit(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
- eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- eval = bsdf_diffuse_toon_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- eval = bsdf_glossy_toon_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- eval = bsdf_hair_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- eval = bsdf_hair_transmission_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
- eval = bsdf_principled_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- eval = bsdf_principled_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#endif /* __PRINCIPLED__ */
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_eval_transmit(sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_glass_eval_transmit(
+ sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
+ eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ eval = bsdf_diffuse_toon_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ eval = bsdf_glossy_toon_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ eval = bsdf_hair_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ eval = bsdf_hair_transmission_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+# ifdef __PRINCIPLED__
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+ eval = bsdf_principled_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ eval = bsdf_principled_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+# endif /* __PRINCIPLED__ */
#endif
#ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
- break;
+ case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
+ eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
+ break;
#endif
- default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
- break;
- }
- }
+ default:
+ eval = make_float3(0.0f, 0.0f, 0.0f);
+ break;
+ }
+ }
- return eval;
+ return eval;
}
ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
{
- /* ToDo: do we want to blur volume closures? */
+ /* ToDo: do we want to blur volume closures? */
#ifdef __SVM__
- switch(sc->type) {
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- bsdf_microfacet_multi_ggx_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- bsdf_microfacet_ggx_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- bsdf_microfacet_beckmann_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
- bsdf_ashikhmin_shirley_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- bsdf_principled_hair_blur(sc, roughness);
- break;
- default:
- break;
- }
+ switch (sc->type) {
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ bsdf_microfacet_multi_ggx_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ bsdf_microfacet_ggx_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ bsdf_microfacet_beckmann_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
+ bsdf_ashikhmin_shirley_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ bsdf_principled_hair_blur(sc, roughness);
+ break;
+ default:
+ break;
+ }
#endif
}
ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b)
{
#ifdef __SVM__
- switch(a->type) {
- case CLOSURE_BSDF_TRANSPARENT_ID:
- return true;
- case CLOSURE_BSDF_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_ID:
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- return bsdf_diffuse_merge(a, b);
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- return bsdf_oren_nayar_merge(a, b);
- case CLOSURE_BSDF_REFLECTION_ID:
- case CLOSURE_BSDF_REFRACTION_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
- return bsdf_microfacet_merge(a, b);
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- return bsdf_ashikhmin_velvet_merge(a, b);
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- return bsdf_toon_merge(a, b);
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- return bsdf_hair_merge(a, b);
-#ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
- return bsdf_principled_diffuse_merge(a, b);
-#endif
-#ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- return volume_henyey_greenstein_merge(a, b);
-#endif
- default:
- return false;
- }
+ switch (a->type) {
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ return true;
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_ID:
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ return bsdf_diffuse_merge(a, b);
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ return bsdf_oren_nayar_merge(a, b);
+ case CLOSURE_BSDF_REFLECTION_ID:
+ case CLOSURE_BSDF_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
+ return bsdf_microfacet_merge(a, b);
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ return bsdf_ashikhmin_velvet_merge(a, b);
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ return bsdf_toon_merge(a, b);
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ return bsdf_hair_merge(a, b);
+# ifdef __PRINCIPLED__
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+ return bsdf_principled_diffuse_merge(a, b);
+# endif
+# ifdef __VOLUME__
+ case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
+ return volume_henyey_greenstein_merge(a, b);
+# endif
+ default:
+ return false;
+ }
#else
- return false;
+ return false;
#endif
}
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index 4e7425bd800..b3b1c37748d 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -33,203 +33,226 @@ CCL_NAMESPACE_BEGIN
ccl_device int bsdf_ashikhmin_shirley_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_ashikhmin_shirley_aniso_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
- bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
+ bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
+ bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
- bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_ashikhmin_shirley_blur(ShaderClosure *sc, float roughness)
{
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)sc;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
- bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
- bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
+ bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
+ bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float roughness)
{
- return 2.0f / (roughness*roughness) - 2.0f;
+ return 2.0f / (roughness * roughness) - 2.0f;
}
-ccl_device_forceinline float3 bsdf_ashikhmin_shirley_eval_reflect(
- const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- float *pdf)
+ccl_device_forceinline float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float3 N = bsdf->N;
-
- float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */
- float NdotO = dot(N, omega_in); /* and consequently we use for O omaga_in ;) */
-
- float out = 0.0f;
-
- if(fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- if(NdotI > 0.0f && NdotO > 0.0f) {
- NdotI = fmaxf(NdotI, 1e-6f);
- NdotO = fmaxf(NdotO, 1e-6f);
- float3 H = normalize(omega_in + I);
- float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f);
- float HdotN = fmaxf(dot(H, N), 1e-6f);
-
- float pump = 1.0f / fmaxf(1e-6f, (HdotI*fmaxf(NdotO, NdotI))); /* pump from original paper (first derivative disc., but cancels the HdotI in the pdf nicely) */
- /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */ /* pump from d-brdf paper */
-
- float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
- float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
-
- if(n_x == n_y) {
- /* isotropic */
- float e = n_x;
- float lobe = powf(HdotN, e);
- float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
-
- out = NdotO * norm * lobe * pump;
- *pdf = norm * lobe / HdotI; /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper) */
- }
- else {
- /* anisotropic */
- float3 X, Y;
- make_orthonormals_tangent(N, bsdf->T, &X, &Y);
-
- float HdotX = dot(H, X);
- float HdotY = dot(H, Y);
- float lobe;
- if(HdotN < 1.0f) {
- float e = (n_x * HdotX*HdotX + n_y * HdotY*HdotY) / (1.0f - HdotN*HdotN);
- lobe = powf(HdotN, e);
- }
- else {
- lobe = 1.0f;
- }
- float norm = sqrtf((n_x + 1.0f)*(n_y + 1.0f)) / (8.0f * M_PI_F);
-
- out = NdotO * norm * lobe * pump;
- *pdf = norm * lobe / HdotI;
- }
- }
-
- return make_float3(out, out, out);
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float3 N = bsdf->N;
+
+ float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */
+ float NdotO = dot(N, omega_in); /* and consequently we use for O omaga_in ;) */
+
+ float out = 0.0f;
+
+ if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ if (NdotI > 0.0f && NdotO > 0.0f) {
+ NdotI = fmaxf(NdotI, 1e-6f);
+ NdotO = fmaxf(NdotO, 1e-6f);
+ float3 H = normalize(omega_in + I);
+ float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f);
+ float HdotN = fmaxf(dot(H, N), 1e-6f);
+
+ float pump =
+ 1.0f /
+ fmaxf(
+ 1e-6f,
+ (HdotI *
+ fmaxf(
+ NdotO,
+ NdotI))); /* pump from original paper (first derivative disc., but cancels the HdotI in the pdf nicely) */
+ /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */ /* pump from d-brdf paper */
+
+ float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
+ float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
+
+ if (n_x == n_y) {
+ /* isotropic */
+ float e = n_x;
+ float lobe = powf(HdotN, e);
+ float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
+
+ out = NdotO * norm * lobe * pump;
+ *pdf =
+ norm * lobe /
+ HdotI; /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper) */
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y;
+ make_orthonormals_tangent(N, bsdf->T, &X, &Y);
+
+ float HdotX = dot(H, X);
+ float HdotY = dot(H, Y);
+ float lobe;
+ if (HdotN < 1.0f) {
+ float e = (n_x * HdotX * HdotX + n_y * HdotY * HdotY) / (1.0f - HdotN * HdotN);
+ lobe = powf(HdotN, e);
+ }
+ else {
+ lobe = 1.0f;
+ }
+ float norm = sqrtf((n_x + 1.0f) * (n_y + 1.0f)) / (8.0f * M_PI_F);
+
+ out = NdotO * norm * lobe * pump;
+ *pdf = norm * lobe / HdotI;
+ }
+ }
+
+ return make_float3(out, out, out);
}
-ccl_device float3 bsdf_ashikhmin_shirley_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_ashikhmin_shirley_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, float n_y, float randu, float randv, float *phi, float *cos_theta)
+ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(
+ float n_x, float n_y, float randu, float randv, float *phi, float *cos_theta)
{
- *phi = atanf(sqrtf((n_x + 1.0f) / (n_y + 1.0f)) * tanf(M_PI_2_F * randu));
- float cos_phi = cosf(*phi);
- float sin_phi = sinf(*phi);
- *cos_theta = powf(randv, 1.0f / (n_x * cos_phi*cos_phi + n_y * sin_phi*sin_phi + 1.0f));
+ *phi = atanf(sqrtf((n_x + 1.0f) / (n_y + 1.0f)) * tanf(M_PI_2_F * randu));
+ float cos_phi = cosf(*phi);
+ float sin_phi = sinf(*phi);
+ *cos_theta = powf(randv, 1.0f / (n_x * cos_phi * cos_phi + n_y * sin_phi * sin_phi + 1.0f));
}
-ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float3 N = bsdf->N;
- int label = LABEL_REFLECT | LABEL_GLOSSY;
-
- float NdotI = dot(N, I);
- if(NdotI > 0.0f) {
-
- float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
- float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
-
- /* get x,y basis on the surface for anisotropy */
- float3 X, Y;
-
- if(n_x == n_y)
- make_orthonormals(N, &X, &Y);
- else
- make_orthonormals_tangent(N, bsdf->T, &X, &Y);
-
- /* sample spherical coords for h in tangent space */
- float phi;
- float cos_theta;
- if(n_x == n_y) {
- /* isotropic sampling */
- phi = M_2PI_F * randu;
- cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
- }
- else {
- /* anisotropic sampling */
- if(randu < 0.25f) { /* first quadrant */
- float remapped_randu = 4.0f * randu;
- bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- }
- else if(randu < 0.5f) { /* second quadrant */
- float remapped_randu = 4.0f * (.5f - randu);
- bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = M_PI_F - phi;
- }
- else if(randu < 0.75f) { /* third quadrant */
- float remapped_randu = 4.0f * (randu - 0.5f);
- bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = M_PI_F + phi;
- }
- else { /* fourth quadrant */
- float remapped_randu = 4.0f * (1.0f - randu);
- bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = 2.0f * M_PI_F - phi;
- }
- }
-
- /* get half vector in tangent space */
- float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta*cos_theta));
- float cos_phi = cosf(phi);
- float sin_phi = sinf(phi); /* no sqrt(1-cos^2) here b/c it causes artifacts */
- float3 h = make_float3(
- sin_theta * cos_phi,
- sin_theta * sin_phi,
- cos_theta
- );
-
- /* half vector to world space */
- float3 H = h.x*X + h.y*Y + h.z*N;
- float HdotI = dot(H, I);
- if(HdotI < 0.0f) H = -H;
-
- /* reflect I on H to get omega_in */
- *omega_in = -I + (2.0f * HdotI) * H;
-
- if(fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
- /* Some high number for MIS. */
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
- label = LABEL_REFLECT | LABEL_SINGULAR;
- }
- else {
- /* leave the rest to eval_reflect */
- *eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
- }
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float3 N = bsdf->N;
+ int label = LABEL_REFLECT | LABEL_GLOSSY;
+
+ float NdotI = dot(N, I);
+ if (NdotI > 0.0f) {
+
+ float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
+ float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
+
+ /* get x,y basis on the surface for anisotropy */
+ float3 X, Y;
+
+ if (n_x == n_y)
+ make_orthonormals(N, &X, &Y);
+ else
+ make_orthonormals_tangent(N, bsdf->T, &X, &Y);
+
+ /* sample spherical coords for h in tangent space */
+ float phi;
+ float cos_theta;
+ if (n_x == n_y) {
+ /* isotropic sampling */
+ phi = M_2PI_F * randu;
+ cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
+ }
+ else {
+ /* anisotropic sampling */
+ if (randu < 0.25f) { /* first quadrant */
+ float remapped_randu = 4.0f * randu;
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ }
+ else if (randu < 0.5f) { /* second quadrant */
+ float remapped_randu = 4.0f * (.5f - randu);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = M_PI_F - phi;
+ }
+ else if (randu < 0.75f) { /* third quadrant */
+ float remapped_randu = 4.0f * (randu - 0.5f);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = M_PI_F + phi;
+ }
+ else { /* fourth quadrant */
+ float remapped_randu = 4.0f * (1.0f - randu);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = 2.0f * M_PI_F - phi;
+ }
+ }
+
+ /* get half vector in tangent space */
+ float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta));
+ float cos_phi = cosf(phi);
+ float sin_phi = sinf(phi); /* no sqrt(1-cos^2) here b/c it causes artifacts */
+ float3 h = make_float3(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
+
+ /* half vector to world space */
+ float3 H = h.x * X + h.y * Y + h.z * N;
+ float HdotI = dot(H, I);
+ if (HdotI < 0.0f)
+ H = -H;
+
+ /* reflect I on H to get omega_in */
+ *omega_in = -I + (2.0f * HdotI) * H;
+
+ if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
+ /* Some high number for MIS. */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ label = LABEL_REFLECT | LABEL_SINGULAR;
+ }
+ else {
+ /* leave the rest to eval_reflect */
+ *eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
+ }
#ifdef __RAY_DIFFERENTIALS__
- /* just do the reflection thing for now */
- *domega_in_dx = (2.0f * dot(N, dIdx)) * N - dIdx;
- *domega_in_dy = (2.0f * dot(N, dIdy)) * N - dIdy;
+ /* just do the reflection thing for now */
+ *domega_in_dx = (2.0f * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2.0f * dot(N, dIdy)) * N - dIdy;
#endif
- }
+ }
- return label;
+ return label;
}
-
CCL_NAMESPACE_END
-#endif /* __BSDF_ASHIKHMIN_SHIRLEY_H__ */
+#endif /* __BSDF_ASHIKHMIN_SHIRLEY_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 80fd9ba2b37..8122bcc1424 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -36,126 +36,142 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct VelvetBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float sigma;
- float invsigma2;
+ float sigma;
+ float invsigma2;
} VelvetBsdf;
ccl_device int bsdf_ashikhmin_velvet_setup(VelvetBsdf *bsdf)
{
- float sigma = fmaxf(bsdf->sigma, 0.01f);
- bsdf->invsigma2 = 1.0f/(sigma * sigma);
+ float sigma = fmaxf(bsdf->sigma, 0.01f);
+ bsdf->invsigma2 = 1.0f / (sigma * sigma);
- bsdf->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
+ bsdf->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device bool bsdf_ashikhmin_velvet_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const VelvetBsdf *bsdf_a = (const VelvetBsdf*)a;
- const VelvetBsdf *bsdf_b = (const VelvetBsdf*)b;
+ const VelvetBsdf *bsdf_a = (const VelvetBsdf *)a;
+ const VelvetBsdf *bsdf_b = (const VelvetBsdf *)b;
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) &&
- (bsdf_a->sigma == bsdf_b->sigma);
+ return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->sigma == bsdf_b->sigma);
}
-ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const VelvetBsdf *bsdf = (const VelvetBsdf*)sc;
- float m_invsigma2 = bsdf->invsigma2;
- float3 N = bsdf->N;
+ const VelvetBsdf *bsdf = (const VelvetBsdf *)sc;
+ float m_invsigma2 = bsdf->invsigma2;
+ float3 N = bsdf->N;
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
- if(cosNO > 0 && cosNI > 0) {
- float3 H = normalize(omega_in + I);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
+ if (cosNO > 0 && cosNI > 0) {
+ float3 H = normalize(omega_in + I);
- float cosNH = dot(N, H);
- float cosHO = fabsf(dot(I, H));
+ float cosNH = dot(N, H);
+ float cosHO = fabsf(dot(I, H));
- if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f))
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f))
+ return make_float3(0.0f, 0.0f, 0.0f);
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
+ float cosNHdivHO = cosNH / cosHO;
+ cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
- float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
- float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
+ float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
+ float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
- float sinNH2 = 1 - cosNH * cosNH;
- float sinNH4 = sinNH2 * sinNH2;
- float cotangent2 = (cosNH * cosNH) / sinNH2;
+ float sinNH2 = 1 - cosNH * cosNH;
+ float sinNH4 = sinNH2 * sinNH2;
+ float cotangent2 = (cosNH * cosNH) / sinNH2;
- float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
- float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically
+ float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
+ float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically
- float out = 0.25f * (D * G) / cosNO;
+ float out = 0.25f * (D * G) / cosNO;
- *pdf = 0.5f * M_1_PI_F;
- return make_float3(out, out, out);
- }
+ *pdf = 0.5f * M_1_PI_F;
+ return make_float3(out, out, out);
+ }
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const VelvetBsdf *bsdf = (const VelvetBsdf*)sc;
- float m_invsigma2 = bsdf->invsigma2;
- float3 N = bsdf->N;
+ const VelvetBsdf *bsdf = (const VelvetBsdf *)sc;
+ float m_invsigma2 = bsdf->invsigma2;
+ float3 N = bsdf->N;
- // we are viewing the surface from above - send a ray out with uniform
- // distribution over the hemisphere
- sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
+ // we are viewing the surface from above - send a ray out with uniform
+ // distribution over the hemisphere
+ sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0) {
- float3 H = normalize(*omega_in + I);
+ if (dot(Ng, *omega_in) > 0) {
+ float3 H = normalize(*omega_in + I);
- float cosNI = dot(N, *omega_in);
- float cosNO = dot(N, I);
- float cosNH = dot(N, H);
- float cosHO = fabsf(dot(I, H));
+ float cosNI = dot(N, *omega_in);
+ float cosNO = dot(N, I);
+ float cosNH = dot(N, H);
+ float cosHO = fabsf(dot(I, H));
- if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) {
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
+ if (fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f) {
+ float cosNHdivHO = cosNH / cosHO;
+ cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
- float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
- float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
+ float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
+ float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
- float sinNH2 = 1 - cosNH * cosNH;
- float sinNH4 = sinNH2 * sinNH2;
- float cotangent2 = (cosNH * cosNH) / sinNH2;
+ float sinNH2 = 1 - cosNH * cosNH;
+ float sinNH4 = sinNH2 * sinNH2;
+ float cotangent2 = (cosNH * cosNH) / sinNH2;
- float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
- float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically
+ float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
+ float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically
- float power = 0.25f * (D * G) / cosNO;
+ float power = 0.25f * (D * G) / cosNO;
- *eval = make_float3(power, power, power);
+ *eval = make_float3(power, power, power);
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the retroreflective bounce
- *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
- *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
+ // TODO: find a better approximation for the retroreflective bounce
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
#endif
- }
- else
- *pdf = 0.0f;
- }
- else
- *pdf = 0.0f;
-
- return LABEL_REFLECT|LABEL_DIFFUSE;
+ }
+ else
+ *pdf = 0.0f;
+ }
+ else
+ *pdf = 0.0f;
+
+ return LABEL_REFLECT | LABEL_DIFFUSE;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_ASHIKHMIN_VELVET_H__ */
+#endif /* __BSDF_ASHIKHMIN_VELVET_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index 946c460a70e..76b50548455 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -36,107 +36,141 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct DiffuseBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
} DiffuseBsdf;
/* DIFFUSE */
ccl_device int bsdf_diffuse_setup(DiffuseBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_DIFFUSE_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_DIFFUSE_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device bool bsdf_diffuse_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const DiffuseBsdf *bsdf_a = (const DiffuseBsdf*)a;
- const DiffuseBsdf *bsdf_b = (const DiffuseBsdf*)b;
+ const DiffuseBsdf *bsdf_a = (const DiffuseBsdf *)a;
+ const DiffuseBsdf *bsdf_b = (const DiffuseBsdf *)b;
- return (isequal_float3(bsdf_a->N, bsdf_b->N));
+ return (isequal_float3(bsdf_a->N, bsdf_b->N));
}
-ccl_device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const DiffuseBsdf *bsdf = (const DiffuseBsdf*)sc;
- float3 N = bsdf->N;
+ const DiffuseBsdf *bsdf = (const DiffuseBsdf *)sc;
+ float3 N = bsdf->N;
- float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
- *pdf = cos_pi;
- return make_float3(cos_pi, cos_pi, cos_pi);
+ float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
+ *pdf = cos_pi;
+ return make_float3(cos_pi, cos_pi, cos_pi);
}
-ccl_device float3 bsdf_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_diffuse_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_diffuse_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const DiffuseBsdf *bsdf = (const DiffuseBsdf*)sc;
- float3 N = bsdf->N;
+ const DiffuseBsdf *bsdf = (const DiffuseBsdf *)sc;
+ float3 N = bsdf->N;
- // distribution over the hemisphere
- sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ // distribution over the hemisphere
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0.0f) {
- *eval = make_float3(*pdf, *pdf, *pdf);
+ if (dot(Ng, *omega_in) > 0.0f) {
+ *eval = make_float3(*pdf, *pdf, *pdf);
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
- *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
+ // TODO: find a better approximation for the diffuse bounce
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
#endif
- }
- else
- *pdf = 0.0f;
+ }
+ else
+ *pdf = 0.0f;
- return LABEL_REFLECT|LABEL_DIFFUSE;
+ return LABEL_REFLECT | LABEL_DIFFUSE;
}
/* TRANSLUCENT */
ccl_device int bsdf_translucent_setup(DiffuseBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_TRANSLUCENT_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_TRANSLUCENT_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_translucent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_translucent_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const DiffuseBsdf *bsdf = (const DiffuseBsdf*)sc;
- float3 N = bsdf->N;
+ const DiffuseBsdf *bsdf = (const DiffuseBsdf *)sc;
+ float3 N = bsdf->N;
- float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F;
- *pdf = cos_pi;
- return make_float3 (cos_pi, cos_pi, cos_pi);
+ float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F;
+ *pdf = cos_pi;
+ return make_float3(cos_pi, cos_pi, cos_pi);
}
-ccl_device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_translucent_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const DiffuseBsdf *bsdf = (const DiffuseBsdf*)sc;
- float3 N = bsdf->N;
-
- // we are viewing the surface from the right side - send a ray out with cosine
- // distribution over the hemisphere
- sample_cos_hemisphere (-N, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) < 0) {
- *eval = make_float3(*pdf, *pdf, *pdf);
+ const DiffuseBsdf *bsdf = (const DiffuseBsdf *)sc;
+ float3 N = bsdf->N;
+
+ // we are viewing the surface from the right side - send a ray out with cosine
+ // distribution over the hemisphere
+ sample_cos_hemisphere(-N, randu, randv, omega_in, pdf);
+ if (dot(Ng, *omega_in) < 0) {
+ *eval = make_float3(*pdf, *pdf, *pdf);
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
- *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+ // TODO: find a better approximation for the diffuse bounce
+ *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+ *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
#endif
- }
- else {
- *pdf = 0;
- }
- return LABEL_TRANSMIT|LABEL_DIFFUSE;
+ }
+ else {
+ *pdf = 0;
+ }
+ return LABEL_TRANSMIT | LABEL_DIFFUSE;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_DIFFUSE_H__ */
+#endif /* __BSDF_DIFFUSE_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index ca33a5b275c..9d13eb8d4e0 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -38,73 +38,90 @@ CCL_NAMESPACE_BEGIN
#ifdef __OSL__
typedef ccl_addr_space struct DiffuseRampBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float3 *colors;
+ float3 *colors;
} DiffuseRampBsdf;
ccl_device float3 bsdf_diffuse_ramp_get_color(const float3 colors[8], float pos)
{
- int MAXCOLORS = 8;
-
- float npos = pos * (float)(MAXCOLORS - 1);
- int ipos = float_to_int(npos);
- if(ipos < 0)
- return colors[0];
- if(ipos >= (MAXCOLORS - 1))
- return colors[MAXCOLORS - 1];
- float offset = npos - (float)ipos;
- return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
+ int MAXCOLORS = 8;
+
+ float npos = pos * (float)(MAXCOLORS - 1);
+ int ipos = float_to_int(npos);
+ if (ipos < 0)
+ return colors[0];
+ if (ipos >= (MAXCOLORS - 1))
+ return colors[MAXCOLORS - 1];
+ float offset = npos - (float)ipos;
+ return colors[ipos] * (1.0f - offset) + colors[ipos + 1] * offset;
}
ccl_device int bsdf_diffuse_ramp_setup(DiffuseRampBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_diffuse_ramp_blur(ShaderClosure *sc, float roughness)
{
}
-ccl_device float3 bsdf_diffuse_ramp_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_diffuse_ramp_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf*)sc;
- float3 N = bsdf->N;
+ const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc;
+ float3 N = bsdf->N;
- float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
- *pdf = cos_pi * M_1_PI_F;
- return bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F;
+ float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
+ *pdf = cos_pi * M_1_PI_F;
+ return bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F;
}
-ccl_device float3 bsdf_diffuse_ramp_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_diffuse_ramp_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_diffuse_ramp_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_diffuse_ramp_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf*)sc;
- float3 N = bsdf->N;
-
- // distribution over the hemisphere
- sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
-
- if(dot(Ng, *omega_in) > 0.0f) {
- *eval = bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F;
-#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
- *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
-#endif
- }
- else
- *pdf = 0.0f;
-
- return LABEL_REFLECT|LABEL_DIFFUSE;
+ const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc;
+ float3 N = bsdf->N;
+
+ // distribution over the hemisphere
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+
+ if (dot(Ng, *omega_in) > 0.0f) {
+ *eval = bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F;
+# ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
+# endif
+ }
+ else
+ *pdf = 0.0f;
+
+ return LABEL_REFLECT | LABEL_DIFFUSE;
}
-#endif /* __OSL__ */
+#endif /* __OSL__ */
CCL_NAMESPACE_END
-#endif /* __BSDF_DIFFUSE_RAMP_H__ */
+#endif /* __BSDF_DIFFUSE_RAMP_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index e1a0cfaa3f5..6b2a9a97d30 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -36,245 +36,276 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct HairBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float3 T;
- float roughness1;
- float roughness2;
- float offset;
+ float3 T;
+ float roughness1;
+ float roughness2;
+ float offset;
} HairBsdf;
ccl_device int bsdf_hair_reflection_setup(HairBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_HAIR_REFLECTION_ID;
- bsdf->roughness1 = clamp(bsdf->roughness1, 0.001f, 1.0f);
- bsdf->roughness2 = clamp(bsdf->roughness2, 0.001f, 1.0f);
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_HAIR_REFLECTION_ID;
+ bsdf->roughness1 = clamp(bsdf->roughness1, 0.001f, 1.0f);
+ bsdf->roughness2 = clamp(bsdf->roughness2, 0.001f, 1.0f);
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_hair_transmission_setup(HairBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
- bsdf->roughness1 = clamp(bsdf->roughness1, 0.001f, 1.0f);
- bsdf->roughness2 = clamp(bsdf->roughness2, 0.001f, 1.0f);
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
+ bsdf->roughness1 = clamp(bsdf->roughness1, 0.001f, 1.0f);
+ bsdf->roughness2 = clamp(bsdf->roughness2, 0.001f, 1.0f);
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device bool bsdf_hair_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const HairBsdf *bsdf_a = (const HairBsdf*)a;
- const HairBsdf *bsdf_b = (const HairBsdf*)b;
+ const HairBsdf *bsdf_a = (const HairBsdf *)a;
+ const HairBsdf *bsdf_b = (const HairBsdf *)b;
- return (isequal_float3(bsdf_a->T, bsdf_b->T)) &&
- (bsdf_a->roughness1 == bsdf_b->roughness1) &&
- (bsdf_a->roughness2 == bsdf_b->roughness2) &&
- (bsdf_a->offset == bsdf_b->offset);
+ return (isequal_float3(bsdf_a->T, bsdf_b->T)) && (bsdf_a->roughness1 == bsdf_b->roughness1) &&
+ (bsdf_a->roughness2 == bsdf_b->roughness2) && (bsdf_a->offset == bsdf_b->offset);
}
-ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const HairBsdf *bsdf = (const HairBsdf*)sc;
- float offset = bsdf->offset;
- float3 Tg = bsdf->T;
- float roughness1 = bsdf->roughness1;
- float roughness2 = bsdf->roughness2;
+ const HairBsdf *bsdf = (const HairBsdf *)sc;
+ float offset = bsdf->offset;
+ float3 Tg = bsdf->T;
+ float roughness1 = bsdf->roughness1;
+ float roughness2 = bsdf->roughness2;
- float Iz = dot(Tg, I);
- float3 locy = normalize(I - Tg * Iz);
+ float Iz = dot(Tg, I);
+ float3 locy = normalize(I - Tg * Iz);
- float theta_r = M_PI_2_F - fast_acosf(Iz);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
- float omega_in_z = dot(Tg, omega_in);
- float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
+ float omega_in_z = dot(Tg, omega_in);
+ float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
- float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
- float cosphi_i = dot(omega_in_y, locy);
+ float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
+ float cosphi_i = dot(omega_in_y, locy);
- if(M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) {
- *pdf = 0.0f;
- return make_float3(*pdf, *pdf, *pdf);
- }
+ if (M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) {
+ *pdf = 0.0f;
+ return make_float3(*pdf, *pdf, *pdf);
+ }
- float roughness1_inv = 1.0f / roughness1;
- float roughness2_inv = 1.0f / roughness2;
- float phi_i = fast_acosf(cosphi_i) * roughness2_inv;
- phi_i = fabsf(phi_i) < M_PI_F ? phi_i : M_PI_F;
- float costheta_i = fast_cosf(theta_i);
+ float roughness1_inv = 1.0f / roughness1;
+ float roughness2_inv = 1.0f / roughness2;
+ float phi_i = fast_acosf(cosphi_i) * roughness2_inv;
+ phi_i = fabsf(phi_i) < M_PI_F ? phi_i : M_PI_F;
+ float costheta_i = fast_cosf(theta_i);
- float a_R = fast_atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
- float b_R = fast_atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
+ float a_R = fast_atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
+ float b_R = fast_atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
- float theta_h = (theta_i + theta_r) * 0.5f;
- float t = theta_h - offset;
+ float theta_h = (theta_i + theta_r) * 0.5f;
+ float t = theta_h - offset;
- float phi_pdf = fast_cosf(phi_i * 0.5f) * 0.25f * roughness2_inv;
- float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)* costheta_i);
- *pdf = phi_pdf * theta_pdf;
+ float phi_pdf = fast_cosf(phi_i * 0.5f) * 0.25f * roughness2_inv;
+ float theta_pdf = roughness1 /
+ (2 * (t * t + roughness1 * roughness1) * (a_R - b_R) * costheta_i);
+ *pdf = phi_pdf * theta_pdf;
- return make_float3(*pdf, *pdf, *pdf);
+ return make_float3(*pdf, *pdf, *pdf);
}
-ccl_device float3 bsdf_hair_transmission_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_hair_transmission_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-
-ccl_device float3 bsdf_hair_reflection_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_hair_reflection_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_hair_transmission_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_hair_transmission_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const HairBsdf *bsdf = (const HairBsdf*)sc;
- float offset = bsdf->offset;
- float3 Tg = bsdf->T;
- float roughness1 = bsdf->roughness1;
- float roughness2 = bsdf->roughness2;
- float Iz = dot(Tg, I);
- float3 locy = normalize(I - Tg * Iz);
+ const HairBsdf *bsdf = (const HairBsdf *)sc;
+ float offset = bsdf->offset;
+ float3 Tg = bsdf->T;
+ float roughness1 = bsdf->roughness1;
+ float roughness2 = bsdf->roughness2;
+ float Iz = dot(Tg, I);
+ float3 locy = normalize(I - Tg * Iz);
- float theta_r = M_PI_2_F - fast_acosf(Iz);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
- float omega_in_z = dot(Tg, omega_in);
- float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
+ float omega_in_z = dot(Tg, omega_in);
+ float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
- float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
- float phi_i = fast_acosf(dot(omega_in_y, locy));
+ float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
+ float phi_i = fast_acosf(dot(omega_in_y, locy));
- if(M_PI_2_F - fabsf(theta_i) < 0.001f) {
- *pdf = 0.0f;
- return make_float3(*pdf, *pdf, *pdf);
- }
+ if (M_PI_2_F - fabsf(theta_i) < 0.001f) {
+ *pdf = 0.0f;
+ return make_float3(*pdf, *pdf, *pdf);
+ }
- float costheta_i = fast_cosf(theta_i);
+ float costheta_i = fast_cosf(theta_i);
- float roughness1_inv = 1.0f / roughness1;
- float a_TT = fast_atan2f(((M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
- float b_TT = fast_atan2f(((-M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
- float c_TT = 2 * fast_atan2f(M_PI_2_F / roughness2, 1.0f);
+ float roughness1_inv = 1.0f / roughness1;
+ float a_TT = fast_atan2f(((M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
+ float b_TT = fast_atan2f(((-M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
+ float c_TT = 2 * fast_atan2f(M_PI_2_F / roughness2, 1.0f);
- float theta_h = (theta_i + theta_r) / 2;
- float t = theta_h - offset;
- float phi = fabsf(phi_i);
+ float theta_h = (theta_i + theta_r) / 2;
+ float t = theta_h - offset;
+ float phi = fabsf(phi_i);
- float p = M_PI_F - phi;
- float theta_pdf = roughness1 / (2 * (t*t + roughness1 * roughness1) * (a_TT - b_TT)*costheta_i);
- float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
+ float p = M_PI_F - phi;
+ float theta_pdf = roughness1 /
+ (2 * (t * t + roughness1 * roughness1) * (a_TT - b_TT) * costheta_i);
+ float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
- *pdf = phi_pdf * theta_pdf;
- return make_float3(*pdf, *pdf, *pdf);
+ *pdf = phi_pdf * theta_pdf;
+ return make_float3(*pdf, *pdf, *pdf);
}
-ccl_device int bsdf_hair_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_hair_reflection_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const HairBsdf *bsdf = (const HairBsdf*)sc;
- float offset = bsdf->offset;
- float3 Tg = bsdf->T;
- float roughness1 = bsdf->roughness1;
- float roughness2 = bsdf->roughness2;
- float Iz = dot(Tg, I);
- float3 locy = normalize(I - Tg * Iz);
- float3 locx = cross(locy, Tg);
- float theta_r = M_PI_2_F - fast_acosf(Iz);
+ const HairBsdf *bsdf = (const HairBsdf *)sc;
+ float offset = bsdf->offset;
+ float3 Tg = bsdf->T;
+ float roughness1 = bsdf->roughness1;
+ float roughness2 = bsdf->roughness2;
+ float Iz = dot(Tg, I);
+ float3 locy = normalize(I - Tg * Iz);
+ float3 locx = cross(locy, Tg);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
- float roughness1_inv = 1.0f / roughness1;
- float a_R = fast_atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
- float b_R = fast_atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
+ float roughness1_inv = 1.0f / roughness1;
+ float a_R = fast_atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
+ float b_R = fast_atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
- float t = roughness1 * tanf(randu * (a_R - b_R) + b_R);
+ float t = roughness1 * tanf(randu * (a_R - b_R) + b_R);
- float theta_h = t + offset;
- float theta_i = 2 * theta_h - theta_r;
+ float theta_h = t + offset;
+ float theta_i = 2 * theta_h - theta_r;
- float costheta_i, sintheta_i;
- fast_sincosf(theta_i, &sintheta_i, &costheta_i);
+ float costheta_i, sintheta_i;
+ fast_sincosf(theta_i, &sintheta_i, &costheta_i);
- float phi = 2 * safe_asinf(1 - 2 * randv) * roughness2;
+ float phi = 2 * safe_asinf(1 - 2 * randv) * roughness2;
- float phi_pdf = fast_cosf(phi * 0.5f) * 0.25f / roughness2;
+ float phi_pdf = fast_cosf(phi * 0.5f) * 0.25f / roughness2;
- float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)*costheta_i);
+ float theta_pdf = roughness1 /
+ (2 * (t * t + roughness1 * roughness1) * (a_R - b_R) * costheta_i);
- float sinphi, cosphi;
- fast_sincosf(phi, &sinphi, &cosphi);
- *omega_in =(cosphi * costheta_i) * locy -
- (sinphi * costheta_i) * locx +
- ( sintheta_i) * Tg;
+ float sinphi, cosphi;
+ fast_sincosf(phi, &sinphi, &cosphi);
+ *omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
- //differentials - TODO: find a better approximation for the reflective bounce
+ //differentials - TODO: find a better approximation for the reflective bounce
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx;
- *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy;
+ *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx;
+ *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy;
#endif
- *pdf = fabsf(phi_pdf * theta_pdf);
- if(M_PI_2_F - fabsf(theta_i) < 0.001f)
- *pdf = 0.0f;
+ *pdf = fabsf(phi_pdf * theta_pdf);
+ if (M_PI_2_F - fabsf(theta_i) < 0.001f)
+ *pdf = 0.0f;
- *eval = make_float3(*pdf, *pdf, *pdf);
+ *eval = make_float3(*pdf, *pdf, *pdf);
- return LABEL_REFLECT|LABEL_GLOSSY;
+ return LABEL_REFLECT | LABEL_GLOSSY;
}
-ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const HairBsdf *bsdf = (const HairBsdf*)sc;
- float offset = bsdf->offset;
- float3 Tg = bsdf->T;
- float roughness1 = bsdf->roughness1;
- float roughness2 = bsdf->roughness2;
- float Iz = dot(Tg, I);
- float3 locy = normalize(I - Tg * Iz);
- float3 locx = cross(locy, Tg);
- float theta_r = M_PI_2_F - fast_acosf(Iz);
-
- float roughness1_inv = 1.0f / roughness1;
- float a_TT = fast_atan2f(((M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
- float b_TT = fast_atan2f(((-M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
- float c_TT = 2 * fast_atan2f(M_PI_2_F / roughness2, 1.0f);
-
- float t = roughness1 * tanf(randu * (a_TT - b_TT) + b_TT);
-
- float theta_h = t + offset;
- float theta_i = 2 * theta_h - theta_r;
-
- float costheta_i, sintheta_i;
- fast_sincosf(theta_i, &sintheta_i, &costheta_i);
-
- float p = roughness2 * tanf(c_TT * (randv - 0.5f));
- float phi = p + M_PI_F;
- float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_TT - b_TT) * costheta_i);
- float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
-
- float sinphi, cosphi;
- fast_sincosf(phi, &sinphi, &cosphi);
- *omega_in =(cosphi * costheta_i) * locy -
- (sinphi * costheta_i) * locx +
- ( sintheta_i) * Tg;
-
- //differentials - TODO: find a better approximation for the transmission bounce
+ const HairBsdf *bsdf = (const HairBsdf *)sc;
+ float offset = bsdf->offset;
+ float3 Tg = bsdf->T;
+ float roughness1 = bsdf->roughness1;
+ float roughness2 = bsdf->roughness2;
+ float Iz = dot(Tg, I);
+ float3 locy = normalize(I - Tg * Iz);
+ float3 locx = cross(locy, Tg);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
+
+ float roughness1_inv = 1.0f / roughness1;
+ float a_TT = fast_atan2f(((M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
+ float b_TT = fast_atan2f(((-M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
+ float c_TT = 2 * fast_atan2f(M_PI_2_F / roughness2, 1.0f);
+
+ float t = roughness1 * tanf(randu * (a_TT - b_TT) + b_TT);
+
+ float theta_h = t + offset;
+ float theta_i = 2 * theta_h - theta_r;
+
+ float costheta_i, sintheta_i;
+ fast_sincosf(theta_i, &sintheta_i, &costheta_i);
+
+ float p = roughness2 * tanf(c_TT * (randv - 0.5f));
+ float phi = p + M_PI_F;
+ float theta_pdf = roughness1 /
+ (2 * (t * t + roughness1 * roughness1) * (a_TT - b_TT) * costheta_i);
+ float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
+
+ float sinphi, cosphi;
+ fast_sincosf(phi, &sinphi, &cosphi);
+ *omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
+
+ //differentials - TODO: find a better approximation for the transmission bounce
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx;
- *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy;
+ *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx;
+ *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy;
#endif
- *pdf = fabsf(phi_pdf * theta_pdf);
- if(M_PI_2_F - fabsf(theta_i) < 0.001f) {
- *pdf = 0.0f;
- }
+ *pdf = fabsf(phi_pdf * theta_pdf);
+ if (M_PI_2_F - fabsf(theta_i) < 0.001f) {
+ *pdf = 0.0f;
+ }
- *eval = make_float3(*pdf, *pdf, *pdf);
+ *eval = make_float3(*pdf, *pdf, *pdf);
- /* TODO(sergey): Should always be negative, but seems some precision issue
- * is involved here.
- */
- kernel_assert(dot(locy, *omega_in) < 1e-4f);
+ /* TODO(sergey): Should always be negative, but seems some precision issue
+ * is involved here.
+ */
+ kernel_assert(dot(locy, *omega_in) < 1e-4f);
- return LABEL_TRANSMIT|LABEL_GLOSSY;
+ return LABEL_TRANSMIT | LABEL_GLOSSY;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_HAIR_H__ */
+#endif /* __BSDF_HAIR_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index 68335ee887a..a4bba2fbf6c 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -15,251 +15,245 @@
*/
#ifdef __KERNEL_CPU__
-#include <fenv.h>
+# include <fenv.h>
#endif
#include "kernel/kernel_color.h"
#ifndef __BSDF_HAIR_PRINCIPLED_H__
-#define __BSDF_HAIR_PRINCIPLED_H__
+# define __BSDF_HAIR_PRINCIPLED_H__
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct PrincipledHairExtra {
- /* Geometry data. */
- float4 geom;
+ /* Geometry data. */
+ float4 geom;
} PrincipledHairExtra;
typedef ccl_addr_space struct PrincipledHairBSDF {
- SHADER_CLOSURE_BASE;
-
- /* Absorption coefficient. */
- float3 sigma;
- /* Variance of the underlying logistic distribution. */
- float v;
- /* Scale factor of the underlying logistic distribution. */
- float s;
- /* Cuticle tilt angle. */
- float alpha;
- /* IOR. */
- float eta;
- /* Effective variance for the diffuse bounce only. */
- float m0_roughness;
-
- /* Extra closure. */
- PrincipledHairExtra *extra;
+ SHADER_CLOSURE_BASE;
+
+ /* Absorption coefficient. */
+ float3 sigma;
+ /* Variance of the underlying logistic distribution. */
+ float v;
+ /* Scale factor of the underlying logistic distribution. */
+ float s;
+ /* Cuticle tilt angle. */
+ float alpha;
+ /* IOR. */
+ float eta;
+ /* Effective variance for the diffuse bounce only. */
+ float m0_roughness;
+
+ /* Extra closure. */
+ PrincipledHairExtra *extra;
} PrincipledHairBSDF;
-static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairBSDF), "PrincipledHairBSDF is too large!");
-static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairExtra), "PrincipledHairExtra is too large!");
+static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairBSDF),
+ "PrincipledHairBSDF is too large!");
+static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairExtra),
+ "PrincipledHairExtra is too large!");
ccl_device_inline float cos_from_sin(const float s)
{
- return safe_sqrtf(1.0f - s*s);
+ return safe_sqrtf(1.0f - s * s);
}
/* Gives the change in direction in the normal plane for the given angles and p-th-order scattering. */
ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
{
- return 2.0f * p * gamma_t - 2.0f * gamma_o + p * M_PI_F;
+ return 2.0f * p * gamma_t - 2.0f * gamma_o + p * M_PI_F;
}
/* Remaps the given angle to [-pi, pi]. */
ccl_device_inline float wrap_angle(float a)
{
- while(a > M_PI_F) {
- a -= M_2PI_F;
- }
- while(a < -M_PI_F) {
- a += M_2PI_F;
- }
- return a;
+ while (a > M_PI_F) {
+ a -= M_2PI_F;
+ }
+ while (a < -M_PI_F) {
+ a += M_2PI_F;
+ }
+ return a;
}
/* Logistic distribution function. */
ccl_device_inline float logistic(float x, float s)
{
- float v = expf(-fabsf(x)/s);
- return v / (s * sqr(1.0f + v));
+ float v = expf(-fabsf(x) / s);
+ return v / (s * sqr(1.0f + v));
}
/* Logistic cumulative density function. */
ccl_device_inline float logistic_cdf(float x, float s)
{
- float arg = -x/s;
- /* expf() overflows if arg >= 89.0. */
- if(arg > 88.0f) {
- return 0.0f;
- }
- else {
- return 1.0f / (1.0f + expf(arg));
- }
+ float arg = -x / s;
+ /* expf() overflows if arg >= 89.0. */
+ if (arg > 88.0f) {
+ return 0.0f;
+ }
+ else {
+ return 1.0f / (1.0f + expf(arg));
+ }
}
/* Numerical approximation to the Bessel function of the first kind. */
ccl_device_inline float bessel_I0(float x)
{
- x = sqr(x);
- float val = 1.0f + 0.25f*x;
- float pow_x_2i = sqr(x);
- uint64_t i_fac_2 = 1;
- int pow_4_i = 16;
- for(int i = 2; i < 10; i++) {
- i_fac_2 *= i*i;
- float newval = val + pow_x_2i / (pow_4_i * i_fac_2);
- if(val == newval) {
- return val;
- }
- val = newval;
- pow_x_2i *= x;
- pow_4_i *= 4;
- }
- return val;
+ x = sqr(x);
+ float val = 1.0f + 0.25f * x;
+ float pow_x_2i = sqr(x);
+ uint64_t i_fac_2 = 1;
+ int pow_4_i = 16;
+ for (int i = 2; i < 10; i++) {
+ i_fac_2 *= i * i;
+ float newval = val + pow_x_2i / (pow_4_i * i_fac_2);
+ if (val == newval) {
+ return val;
+ }
+ val = newval;
+ pow_x_2i *= x;
+ pow_4_i *= 4;
+ }
+ return val;
}
/* Logarithm of the Bessel function of the first kind. */
ccl_device_inline float log_bessel_I0(float x)
{
- if(x > 12.0f) {
- /* log(1/x) == -log(x) iff x > 0.
- * This is only used with positive cosines */
- return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x));
- }
- else {
- return logf(bessel_I0(x));
- }
+ if (x > 12.0f) {
+ /* log(1/x) == -log(x) iff x > 0.
+ * This is only used with positive cosines */
+ return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x));
+ }
+ else {
+ return logf(bessel_I0(x));
+ }
}
/* Logistic distribution limited to the interval [-pi, pi]. */
ccl_device_inline float trimmed_logistic(float x, float s)
{
- /* The logistic distribution is symmetric and centered around zero,
- * so logistic_cdf(x, s) = 1 - logistic_cdf(-x, s).
- * Therefore, logistic_cdf(x, s)-logistic_cdf(-x, s) = 1 - 2*logistic_cdf(-x, s) */
- float scaling_fac = 1.0f - 2.0f*logistic_cdf(-M_PI_F, s);
- float val = logistic(x, s);
- return safe_divide(val, scaling_fac);
+ /* The logistic distribution is symmetric and centered around zero,
+ * so logistic_cdf(x, s) = 1 - logistic_cdf(-x, s).
+ * Therefore, logistic_cdf(x, s)-logistic_cdf(-x, s) = 1 - 2*logistic_cdf(-x, s) */
+ float scaling_fac = 1.0f - 2.0f * logistic_cdf(-M_PI_F, s);
+ float val = logistic(x, s);
+ return safe_divide(val, scaling_fac);
}
/* Sampling function for the trimmed logistic function. */
ccl_device_inline float sample_trimmed_logistic(float u, float s)
{
- float cdf_minuspi = logistic_cdf(-M_PI_F, s);
- float x = -s*logf(1.0f / (u*(1.0f - 2.0f*cdf_minuspi) + cdf_minuspi) - 1.0f);
- return clamp(x, -M_PI_F, M_PI_F);
+ float cdf_minuspi = logistic_cdf(-M_PI_F, s);
+ float x = -s * logf(1.0f / (u * (1.0f - 2.0f * cdf_minuspi) + cdf_minuspi) - 1.0f);
+ return clamp(x, -M_PI_F, M_PI_F);
}
/* Azimuthal scattering function Np. */
-ccl_device_inline float azimuthal_scattering(float phi,
- int p,
- float s,
- float gamma_o,
- float gamma_t)
+ccl_device_inline float azimuthal_scattering(
+ float phi, int p, float s, float gamma_o, float gamma_t)
{
- float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t));
- float val = trimmed_logistic(phi_o, s);
- return val;
+ float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t));
+ float val = trimmed_logistic(phi_o, s);
+ return val;
}
/* Longitudinal scattering function Mp. */
-ccl_device_inline float longitudinal_scattering(float sin_theta_i,
- float cos_theta_i,
- float sin_theta_o,
- float cos_theta_o,
- float v)
+ccl_device_inline float longitudinal_scattering(
+ float sin_theta_i, float cos_theta_i, float sin_theta_o, float cos_theta_o, float v)
{
- float inv_v = 1.0f/v;
- float cos_arg = cos_theta_i * cos_theta_o * inv_v;
- float sin_arg = sin_theta_i * sin_theta_o * inv_v;
- if(v <= 0.1f) {
- float i0 = log_bessel_I0(cos_arg);
- float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f*inv_v));
- return val;
- }
- else {
- float i0 = bessel_I0(cos_arg);
- float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v);
- return val;
- }
+ float inv_v = 1.0f / v;
+ float cos_arg = cos_theta_i * cos_theta_o * inv_v;
+ float sin_arg = sin_theta_i * sin_theta_o * inv_v;
+ if (v <= 0.1f) {
+ float i0 = log_bessel_I0(cos_arg);
+ float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f * inv_v));
+ return val;
+ }
+ else {
+ float i0 = bessel_I0(cos_arg);
+ float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v);
+ return val;
+ }
}
/* Combine the three values using their luminances. */
ccl_device_inline float4 combine_with_energy(KernelGlobals *kg, float3 c)
{
- return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c));
+ return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c));
}
-#ifdef __HAIR__
+# ifdef __HAIR__
/* Set up the hair closure. */
ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bsdf)
{
- bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
- bsdf->v = clamp(bsdf->v, 0.001f, 1.0f);
- bsdf->s = clamp(bsdf->s, 0.001f, 1.0f);
- /* Apply Primary Reflection Roughness modifier. */
- bsdf->m0_roughness = clamp(bsdf->m0_roughness*bsdf->v, 0.001f, 1.0f);
-
- /* Map from roughness_u and roughness_v to variance and scale factor. */
- bsdf->v = sqr(0.726f*bsdf->v + 0.812f*sqr(bsdf->v) + 3.700f*pow20(bsdf->v));
- bsdf->s = (0.265f*bsdf->s + 1.194f*sqr(bsdf->s) + 5.372f*pow22(bsdf->s))*M_SQRT_PI_8_F;
- bsdf->m0_roughness = sqr(0.726f*bsdf->m0_roughness + 0.812f*sqr(bsdf->m0_roughness) + 3.700f*pow20(bsdf->m0_roughness));
-
- /* Compute local frame, aligned to curve tangent and ray direction. */
- float3 X = safe_normalize(sd->dPdu);
- float3 Y = safe_normalize(cross(X, sd->I));
- float3 Z = safe_normalize(cross(X, Y));
- /* TODO: the solution below works where sd->Ng is the normal
- * pointing from the center of the curve to the shading point.
- * It doesn't work for triangles, see https://developer.blender.org/T43625 */
-
- /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at
- * the center, to grazing the other edge. This is the sine of the angle
- * between sd->Ng and Z, as seen from the tangent X. */
-
- /* TODO: we convert this value to a cosine later and discard the sign, so
- * we could probably save some operations. */
- float h = dot(cross(sd->Ng, X), Z);
-
- kernel_assert(fabsf(h) < 1.0f + 1e-4f);
- kernel_assert(isfinite3_safe(Y));
- kernel_assert(isfinite_safe(h));
-
- bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
-
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG;
+ bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
+ bsdf->v = clamp(bsdf->v, 0.001f, 1.0f);
+ bsdf->s = clamp(bsdf->s, 0.001f, 1.0f);
+ /* Apply Primary Reflection Roughness modifier. */
+ bsdf->m0_roughness = clamp(bsdf->m0_roughness * bsdf->v, 0.001f, 1.0f);
+
+ /* Map from roughness_u and roughness_v to variance and scale factor. */
+ bsdf->v = sqr(0.726f * bsdf->v + 0.812f * sqr(bsdf->v) + 3.700f * pow20(bsdf->v));
+ bsdf->s = (0.265f * bsdf->s + 1.194f * sqr(bsdf->s) + 5.372f * pow22(bsdf->s)) * M_SQRT_PI_8_F;
+ bsdf->m0_roughness = sqr(0.726f * bsdf->m0_roughness + 0.812f * sqr(bsdf->m0_roughness) +
+ 3.700f * pow20(bsdf->m0_roughness));
+
+ /* Compute local frame, aligned to curve tangent and ray direction. */
+ float3 X = safe_normalize(sd->dPdu);
+ float3 Y = safe_normalize(cross(X, sd->I));
+ float3 Z = safe_normalize(cross(X, Y));
+ /* TODO: the solution below works where sd->Ng is the normal
+ * pointing from the center of the curve to the shading point.
+ * It doesn't work for triangles, see https://developer.blender.org/T43625 */
+
+ /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at
+ * the center, to grazing the other edge. This is the sine of the angle
+ * between sd->Ng and Z, as seen from the tangent X. */
+
+ /* TODO: we convert this value to a cosine later and discard the sign, so
+ * we could probably save some operations. */
+ float h = dot(cross(sd->Ng, X), Z);
+
+ kernel_assert(fabsf(h) < 1.0f + 1e-4f);
+ kernel_assert(isfinite3_safe(Y));
+ kernel_assert(isfinite_safe(h));
+
+ bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
+
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
-#endif /* __HAIR__ */
+# endif /* __HAIR__ */
/* Given the Fresnel term and transmittance, generate the attenuation terms for each bounce. */
-ccl_device_inline void hair_attenuation(KernelGlobals *kg,
- float f,
- float3 T,
- float4 *Ap)
+ccl_device_inline void hair_attenuation(KernelGlobals *kg, float f, float3 T, float4 *Ap)
{
- /* Primary specular (R). */
- Ap[0] = make_float4(f, f, f, f);
+ /* Primary specular (R). */
+ Ap[0] = make_float4(f, f, f, f);
- /* Transmission (TT). */
- float3 col = sqr(1.0f - f) * T;
- Ap[1] = combine_with_energy(kg, col);
+ /* Transmission (TT). */
+ float3 col = sqr(1.0f - f) * T;
+ Ap[1] = combine_with_energy(kg, col);
- /* Secondary specular (TRT). */
- col *= T*f;
- Ap[2] = combine_with_energy(kg, col);
+ /* Secondary specular (TRT). */
+ col *= T * f;
+ Ap[2] = combine_with_energy(kg, col);
- /* Residual component (TRRT+). */
- col *= safe_divide_color(T*f, make_float3(1.0f, 1.0f, 1.0f) - T*f);
- Ap[3] = combine_with_energy(kg, col);
+ /* Residual component (TRRT+). */
+ col *= safe_divide_color(T * f, make_float3(1.0f, 1.0f, 1.0f) - T * f);
+ Ap[3] = combine_with_energy(kg, col);
- /* Normalize sampling weights. */
- float totweight = Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w;
- float fac = safe_divide(1.0f, totweight);
+ /* Normalize sampling weights. */
+ float totweight = Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w;
+ float fac = safe_divide(1.0f, totweight);
- Ap[0].w *= fac;
- Ap[1].w *= fac;
- Ap[2].w *= fac;
- Ap[3].w *= fac;
+ Ap[0].w *= fac;
+ Ap[1].w *= fac;
+ Ap[2].w *= fac;
+ Ap[3].w *= fac;
}
/* Given the tilt angle, generate the rotated theta_i for the different bounces. */
@@ -268,19 +262,19 @@ ccl_device_inline void hair_alpha_angles(float sin_theta_i,
float alpha,
float *angles)
{
- float sin_1alpha = sinf(alpha);
- float cos_1alpha = cos_from_sin(sin_1alpha);
- float sin_2alpha = 2.0f*sin_1alpha*cos_1alpha;
- float cos_2alpha = sqr(cos_1alpha) - sqr(sin_1alpha);
- float sin_4alpha = 2.0f*sin_2alpha*cos_2alpha;
- float cos_4alpha = sqr(cos_2alpha) - sqr(sin_2alpha);
-
- angles[0] = sin_theta_i*cos_2alpha + cos_theta_i*sin_2alpha;
- angles[1] = fabsf(cos_theta_i*cos_2alpha - sin_theta_i*sin_2alpha);
- angles[2] = sin_theta_i*cos_1alpha - cos_theta_i*sin_1alpha;
- angles[3] = fabsf(cos_theta_i*cos_1alpha + sin_theta_i*sin_1alpha);
- angles[4] = sin_theta_i*cos_4alpha - cos_theta_i*sin_4alpha;
- angles[5] = fabsf(cos_theta_i*cos_4alpha + sin_theta_i*sin_4alpha);
+ float sin_1alpha = sinf(alpha);
+ float cos_1alpha = cos_from_sin(sin_1alpha);
+ float sin_2alpha = 2.0f * sin_1alpha * cos_1alpha;
+ float cos_2alpha = sqr(cos_1alpha) - sqr(sin_1alpha);
+ float sin_4alpha = 2.0f * sin_2alpha * cos_2alpha;
+ float cos_4alpha = sqr(cos_2alpha) - sqr(sin_2alpha);
+
+ angles[0] = sin_theta_i * cos_2alpha + cos_theta_i * sin_2alpha;
+ angles[1] = fabsf(cos_theta_i * cos_2alpha - sin_theta_i * sin_2alpha);
+ angles[2] = sin_theta_i * cos_1alpha - cos_theta_i * sin_1alpha;
+ angles[3] = fabsf(cos_theta_i * cos_1alpha + sin_theta_i * sin_1alpha);
+ angles[4] = sin_theta_i * cos_4alpha - cos_theta_i * sin_4alpha;
+ angles[5] = fabsf(cos_theta_i * cos_4alpha + sin_theta_i * sin_4alpha);
}
/* Evaluation function for our shader. */
@@ -290,75 +284,75 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals *kg,
const float3 omega_in,
float *pdf)
{
- kernel_assert(isfinite3_safe(sd->P) && isfinite_safe(sd->ray_length));
+ kernel_assert(isfinite3_safe(sd->P) && isfinite_safe(sd->ray_length));
- const PrincipledHairBSDF *bsdf = (const PrincipledHairBSDF*) sc;
- float3 Y = float4_to_float3(bsdf->extra->geom);
+ const PrincipledHairBSDF *bsdf = (const PrincipledHairBSDF *)sc;
+ float3 Y = float4_to_float3(bsdf->extra->geom);
- float3 X = safe_normalize(sd->dPdu);
- kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
- float3 Z = safe_normalize(cross(X, Y));
+ float3 X = safe_normalize(sd->dPdu);
+ kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
+ float3 Z = safe_normalize(cross(X, Y));
- float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
- float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+ float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
+ float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
- float sin_theta_o = wo.x;
- float cos_theta_o = cos_from_sin(sin_theta_o);
- float phi_o = atan2f(wo.z, wo.y);
+ float sin_theta_o = wo.x;
+ float cos_theta_o = cos_from_sin(sin_theta_o);
+ float phi_o = atan2f(wo.z, wo.y);
- float sin_theta_t = sin_theta_o / bsdf->eta;
- float cos_theta_t = cos_from_sin(sin_theta_t);
+ float sin_theta_t = sin_theta_o / bsdf->eta;
+ float cos_theta_t = cos_from_sin(sin_theta_t);
- float sin_gamma_o = bsdf->extra->geom.w;
- float cos_gamma_o = cos_from_sin(sin_gamma_o);
- float gamma_o = safe_asinf(sin_gamma_o);
+ float sin_gamma_o = bsdf->extra->geom.w;
+ float cos_gamma_o = cos_from_sin(sin_gamma_o);
+ float gamma_o = safe_asinf(sin_gamma_o);
- float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
- float cos_gamma_t = cos_from_sin(sin_gamma_t);
- float gamma_t = safe_asinf(sin_gamma_t);
+ float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
+ float cos_gamma_t = cos_from_sin(sin_gamma_t);
+ float gamma_t = safe_asinf(sin_gamma_t);
- float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
- float4 Ap[4];
- hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
+ float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ float4 Ap[4];
+ hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
- float sin_theta_i = wi.x;
- float cos_theta_i = cos_from_sin(sin_theta_i);
- float phi_i = atan2f(wi.z, wi.y);
+ float sin_theta_i = wi.x;
+ float cos_theta_i = cos_from_sin(sin_theta_i);
+ float phi_i = atan2f(wi.z, wi.y);
- float phi = phi_i - phi_o;
+ float phi = phi_i - phi_o;
- float angles[6];
- hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
+ float angles[6];
+ hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
- float4 F;
- float Mp, Np;
+ float4 F;
+ float Mp, Np;
- /* Primary specular (R). */
- Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
- Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
- F = Ap[0] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
+ /* Primary specular (R). */
+ Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
+ Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
+ F = Ap[0] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
- /* Transmission (TT). */
- Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f*bsdf->v);
- Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
- F += Ap[1] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
+ /* Transmission (TT). */
+ Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
+ Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
+ F += Ap[1] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
- /* Secondary specular (TRT). */
- Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f*bsdf->v);
- Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
- F += Ap[2] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
+ /* Secondary specular (TRT). */
+ Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
+ F += Ap[2] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
- /* Residual component (TRRT+). */
- Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f*bsdf->v);
- Np = M_1_2PI_F;
- F += Ap[3] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
+ /* Residual component (TRRT+). */
+ Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ Np = M_1_2PI_F;
+ F += Ap[3] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
- *pdf = F.w;
- return float4_to_float3(F);
+ *pdf = F.w;
+ return float4_to_float3(F);
}
/* Sampling function for the hair shader. */
@@ -373,130 +367,131 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals *kg,
float3 *domega_in_dy,
float *pdf)
{
- PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*) sc;
-
- float3 Y = float4_to_float3(bsdf->extra->geom);
-
- float3 X = safe_normalize(sd->dPdu);
- kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
- float3 Z = safe_normalize(cross(X, Y));
-
- float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
-
- float2 u[2];
- u[0] = make_float2(randu, randv);
- u[1].x = lcg_step_float_addrspace(&sd->lcg_state);
- u[1].y = lcg_step_float_addrspace(&sd->lcg_state);
-
- float sin_theta_o = wo.x;
- float cos_theta_o = cos_from_sin(sin_theta_o);
- float phi_o = atan2f(wo.z, wo.y);
-
- float sin_theta_t = sin_theta_o / bsdf->eta;
- float cos_theta_t = cos_from_sin(sin_theta_t);
-
- float sin_gamma_o = bsdf->extra->geom.w;
- float cos_gamma_o = cos_from_sin(sin_gamma_o);
- float gamma_o = safe_asinf(sin_gamma_o);
-
- float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
- float cos_gamma_t = cos_from_sin(sin_gamma_t);
- float gamma_t = safe_asinf(sin_gamma_t);
-
- float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
- float4 Ap[4];
- hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
-
- int p = 0;
- for(; p < 3; p++) {
- if(u[0].x < Ap[p].w) {
- break;
- }
- u[0].x -= Ap[p].w;
- }
-
- float v = bsdf->v;
- if(p == 1) {
- v *= 0.25f;
- }
- if(p >= 2) {
- v *= 4.0f;
- }
-
- u[1].x = max(u[1].x, 1e-5f);
- float fac = 1.0f + v*logf(u[1].x + (1.0f - u[1].x)*expf(-2.0f/v));
- float sin_theta_i = -fac * sin_theta_o + cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
- float cos_theta_i = cos_from_sin(sin_theta_i);
-
- float angles[6];
- if(p < 3) {
- hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles);
- sin_theta_i = angles[2*p];
- cos_theta_i = angles[2*p+1];
- }
-
- float phi;
- if(p < 3) {
- phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(u[0].y, bsdf->s);
- }
- else {
- phi = M_2PI_F*u[0].y;
- }
- float phi_i = phi_o + phi;
-
- hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
-
- float4 F;
- float Mp, Np;
-
- /* Primary specular (R). */
- Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
- Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
- F = Ap[0] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
-
- /* Transmission (TT). */
- Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f*bsdf->v);
- Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
- F += Ap[1] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
-
- /* Secondary specular (TRT). */
- Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f*bsdf->v);
- Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
- F += Ap[2] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
-
- /* Residual component (TRRT+). */
- Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f*bsdf->v);
- Np = M_1_2PI_F;
- F += Ap[3] * Mp * Np;
- kernel_assert(isfinite3_safe(float4_to_float3(F)));
-
- *eval = float4_to_float3(F);
- *pdf = F.w;
-
- *omega_in = X*sin_theta_i + Y*cos_theta_i*cosf(phi_i) + Z*cos_theta_i*sinf(phi_i);
-
-#ifdef __RAY_DIFFERENTIALS__
- float3 N = safe_normalize(sd->I + *omega_in);
- *domega_in_dx = (2 * dot(N, sd->dI.dx)) * N - sd->dI.dx;
- *domega_in_dy = (2 * dot(N, sd->dI.dy)) * N - sd->dI.dy;
-#endif
-
- return LABEL_GLOSSY|((p == 0)? LABEL_REFLECT : LABEL_TRANSMIT);
+ PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
+
+ float3 Y = float4_to_float3(bsdf->extra->geom);
+
+ float3 X = safe_normalize(sd->dPdu);
+ kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
+ float3 Z = safe_normalize(cross(X, Y));
+
+ float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
+
+ float2 u[2];
+ u[0] = make_float2(randu, randv);
+ u[1].x = lcg_step_float_addrspace(&sd->lcg_state);
+ u[1].y = lcg_step_float_addrspace(&sd->lcg_state);
+
+ float sin_theta_o = wo.x;
+ float cos_theta_o = cos_from_sin(sin_theta_o);
+ float phi_o = atan2f(wo.z, wo.y);
+
+ float sin_theta_t = sin_theta_o / bsdf->eta;
+ float cos_theta_t = cos_from_sin(sin_theta_t);
+
+ float sin_gamma_o = bsdf->extra->geom.w;
+ float cos_gamma_o = cos_from_sin(sin_gamma_o);
+ float gamma_o = safe_asinf(sin_gamma_o);
+
+ float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
+ float cos_gamma_t = cos_from_sin(sin_gamma_t);
+ float gamma_t = safe_asinf(sin_gamma_t);
+
+ float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ float4 Ap[4];
+ hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
+
+ int p = 0;
+ for (; p < 3; p++) {
+ if (u[0].x < Ap[p].w) {
+ break;
+ }
+ u[0].x -= Ap[p].w;
+ }
+
+ float v = bsdf->v;
+ if (p == 1) {
+ v *= 0.25f;
+ }
+ if (p >= 2) {
+ v *= 4.0f;
+ }
+
+ u[1].x = max(u[1].x, 1e-5f);
+ float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
+ float sin_theta_i = -fac * sin_theta_o +
+ cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
+ float cos_theta_i = cos_from_sin(sin_theta_i);
+
+ float angles[6];
+ if (p < 3) {
+ hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles);
+ sin_theta_i = angles[2 * p];
+ cos_theta_i = angles[2 * p + 1];
+ }
+
+ float phi;
+ if (p < 3) {
+ phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(u[0].y, bsdf->s);
+ }
+ else {
+ phi = M_2PI_F * u[0].y;
+ }
+ float phi_i = phi_o + phi;
+
+ hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
+
+ float4 F;
+ float Mp, Np;
+
+ /* Primary specular (R). */
+ Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
+ Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
+ F = Ap[0] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
+
+ /* Transmission (TT). */
+ Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
+ Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
+ F += Ap[1] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
+
+ /* Secondary specular (TRT). */
+ Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
+ F += Ap[2] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
+
+ /* Residual component (TRRT+). */
+ Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ Np = M_1_2PI_F;
+ F += Ap[3] * Mp * Np;
+ kernel_assert(isfinite3_safe(float4_to_float3(F)));
+
+ *eval = float4_to_float3(F);
+ *pdf = F.w;
+
+ *omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
+
+# ifdef __RAY_DIFFERENTIALS__
+ float3 N = safe_normalize(sd->I + *omega_in);
+ *domega_in_dx = (2 * dot(N, sd->dI.dx)) * N - sd->dI.dx;
+ *domega_in_dy = (2 * dot(N, sd->dI.dy)) * N - sd->dI.dy;
+# endif
+
+ return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT);
}
/* Implements Filter Glossy by capping the effective roughness. */
ccl_device void bsdf_principled_hair_blur(ShaderClosure *sc, float roughness)
{
- PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)sc;
+ PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
- bsdf->v = fmaxf(roughness, bsdf->v);
- bsdf->s = fmaxf(roughness, bsdf->s);
- bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
+ bsdf->v = fmaxf(roughness, bsdf->v);
+ bsdf->s = fmaxf(roughness, bsdf->s);
+ bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
}
CCL_NAMESPACE_END
-#endif /* __BSDF_HAIR_PRINCIPLED_H__ */
+#endif /* __BSDF_HAIR_PRINCIPLED_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 32b6e50b09a..b4da3123f28 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -36,95 +36,98 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct MicrofacetExtra {
- float3 color, cspec0;
- float clearcoat;
+ float3 color, cspec0;
+ float clearcoat;
} MicrofacetExtra;
typedef ccl_addr_space struct MicrofacetBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float alpha_x, alpha_y, ior;
- MicrofacetExtra *extra;
- float3 T;
+ float alpha_x, alpha_y, ior;
+ MicrofacetExtra *extra;
+ float3 T;
} MicrofacetBsdf;
/* Beckmann and GGX microfacet importance sampling. */
-ccl_device_inline void microfacet_beckmann_sample_slopes(
- KernelGlobals *kg,
- const float cos_theta_i, const float sin_theta_i,
- float randu, float randv, float *slope_x, float *slope_y,
- float *G1i)
+ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals *kg,
+ const float cos_theta_i,
+ const float sin_theta_i,
+ float randu,
+ float randv,
+ float *slope_x,
+ float *slope_y,
+ float *G1i)
{
- /* special case (normal incidence) */
- if(cos_theta_i >= 0.99999f) {
- const float r = sqrtf(-logf(randu));
- const float phi = M_2PI_F * randv;
- *slope_x = r * cosf(phi);
- *slope_y = r * sinf(phi);
- *G1i = 1.0f;
- return;
- }
-
- /* precomputations */
- const float tan_theta_i = sin_theta_i/cos_theta_i;
- const float inv_a = tan_theta_i;
- const float cot_theta_i = 1.0f/tan_theta_i;
- const float erf_a = fast_erff(cot_theta_i);
- const float exp_a2 = expf(-cot_theta_i*cot_theta_i);
- const float SQRT_PI_INV = 0.56418958354f;
- const float Lambda = 0.5f*(erf_a - 1.0f) + (0.5f*SQRT_PI_INV)*(exp_a2*inv_a);
- const float G1 = 1.0f/(1.0f + Lambda); /* masking */
-
- *G1i = G1;
+ /* special case (normal incidence) */
+ if (cos_theta_i >= 0.99999f) {
+ const float r = sqrtf(-logf(randu));
+ const float phi = M_2PI_F * randv;
+ *slope_x = r * cosf(phi);
+ *slope_y = r * sinf(phi);
+ *G1i = 1.0f;
+ return;
+ }
+
+ /* precomputations */
+ const float tan_theta_i = sin_theta_i / cos_theta_i;
+ const float inv_a = tan_theta_i;
+ const float cot_theta_i = 1.0f / tan_theta_i;
+ const float erf_a = fast_erff(cot_theta_i);
+ const float exp_a2 = expf(-cot_theta_i * cot_theta_i);
+ const float SQRT_PI_INV = 0.56418958354f;
+ const float Lambda = 0.5f * (erf_a - 1.0f) + (0.5f * SQRT_PI_INV) * (exp_a2 * inv_a);
+ const float G1 = 1.0f / (1.0f + Lambda); /* masking */
+
+ *G1i = G1;
#if defined(__KERNEL_GPU__)
- /* Based on paper from Wenzel Jakob
- * An Improved Visible Normal Sampling Routine for the Beckmann Distribution
- *
- * http://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf
- *
- * Reformulation from OpenShadingLanguage which avoids using inverse
- * trigonometric functions.
- */
-
- /* Sample slope X.
- *
- * Compute a coarse approximation using the approximation:
- * exp(-ierf(x)^2) ~= 1 - x * x
- * solve y = 1 + b + K * (1 - b * b)
- */
- float K = tan_theta_i * SQRT_PI_INV;
- float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a));
- float y_exact = randu * (1.0f + erf_a + K * exp_a2);
- float b = K > 0 ? (0.5f - sqrtf(K * (K - y_approx + 1.0f) + 0.25f)) / K : y_approx - 1.0f;
-
- /* Perform newton step to refine toward the true root. */
- float inv_erf = fast_ierff(b);
- float value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact;
- /* Check if we are close enough already,
- * this also avoids NaNs as we get close to the root.
- */
- if(fabsf(value) > 1e-6f) {
- b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 1. */
- inv_erf = fast_ierff(b);
- value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact;
- b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 2. */
- /* Compute the slope from the refined value. */
- *slope_x = fast_ierff(b);
- }
- else {
- /* We are close enough already. */
- *slope_x = inv_erf;
- }
- *slope_y = fast_ierff(2.0f*randv - 1.0f);
+ /* Based on paper from Wenzel Jakob
+ * An Improved Visible Normal Sampling Routine for the Beckmann Distribution
+ *
+ * http://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf
+ *
+ * Reformulation from OpenShadingLanguage which avoids using inverse
+ * trigonometric functions.
+ */
+
+ /* Sample slope X.
+ *
+ * Compute a coarse approximation using the approximation:
+ * exp(-ierf(x)^2) ~= 1 - x * x
+ * solve y = 1 + b + K * (1 - b * b)
+ */
+ float K = tan_theta_i * SQRT_PI_INV;
+ float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a));
+ float y_exact = randu * (1.0f + erf_a + K * exp_a2);
+ float b = K > 0 ? (0.5f - sqrtf(K * (K - y_approx + 1.0f) + 0.25f)) / K : y_approx - 1.0f;
+
+ /* Perform newton step to refine toward the true root. */
+ float inv_erf = fast_ierff(b);
+ float value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact;
+ /* Check if we are close enough already,
+ * this also avoids NaNs as we get close to the root.
+ */
+ if (fabsf(value) > 1e-6f) {
+ b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 1. */
+ inv_erf = fast_ierff(b);
+ value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact;
+ b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 2. */
+ /* Compute the slope from the refined value. */
+ *slope_x = fast_ierff(b);
+ }
+ else {
+ /* We are close enough already. */
+ *slope_x = inv_erf;
+ }
+ *slope_y = fast_ierff(2.0f * randv - 1.0f);
#else
- /* Use precomputed table on CPU, it gives better perfomance. */
- int beckmann_table_offset = kernel_data.tables.beckmann_offset;
+ /* Use precomputed table on CPU, it gives better perfomance. */
+ int beckmann_table_offset = kernel_data.tables.beckmann_offset;
- *slope_x = lookup_table_read_2D(kg, randu, cos_theta_i,
- beckmann_table_offset, BECKMANN_TABLE_SIZE, BECKMANN_TABLE_SIZE);
- *slope_y = fast_ierff(2.0f*randv - 1.0f);
+ *slope_x = lookup_table_read_2D(
+ kg, randu, cos_theta_i, beckmann_table_offset, BECKMANN_TABLE_SIZE, BECKMANN_TABLE_SIZE);
+ *slope_y = fast_ierff(2.0f * randv - 1.0f);
#endif
}
@@ -134,103 +137,109 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(
* E. Heitz and E. d'Eon, EGSR 2014
*/
-ccl_device_inline void microfacet_ggx_sample_slopes(
- const float cos_theta_i, const float sin_theta_i,
- float randu, float randv, float *slope_x, float *slope_y,
- float *G1i)
+ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i,
+ const float sin_theta_i,
+ float randu,
+ float randv,
+ float *slope_x,
+ float *slope_y,
+ float *G1i)
{
- /* special case (normal incidence) */
- if(cos_theta_i >= 0.99999f) {
- const float r = sqrtf(randu/(1.0f - randu));
- const float phi = M_2PI_F * randv;
- *slope_x = r * cosf(phi);
- *slope_y = r * sinf(phi);
- *G1i = 1.0f;
-
- return;
- }
-
- /* precomputations */
- const float tan_theta_i = sin_theta_i/cos_theta_i;
- const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i*tan_theta_i));
-
- *G1i = 1.0f/G1_inv;
-
- /* sample slope_x */
- const float A = 2.0f*randu*G1_inv - 1.0f;
- const float AA = A*A;
- const float tmp = 1.0f/(AA - 1.0f);
- const float B = tan_theta_i;
- const float BB = B*B;
- const float D = safe_sqrtf(BB*(tmp*tmp) - (AA - BB)*tmp);
- const float slope_x_1 = B*tmp - D;
- const float slope_x_2 = B*tmp + D;
- *slope_x = (A < 0.0f || slope_x_2*tan_theta_i > 1.0f)? slope_x_1: slope_x_2;
-
- /* sample slope_y */
- float S;
-
- if(randv > 0.5f) {
- S = 1.0f;
- randv = 2.0f*(randv - 0.5f);
- }
- else {
- S = -1.0f;
- randv = 2.0f*(0.5f - randv);
- }
-
- const float z = (randv*(randv*(randv*0.27385f - 0.73369f) + 0.46341f)) / (randv*(randv*(randv*0.093073f + 0.309420f) - 1.000000f) + 0.597999f);
- *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x)*(*slope_x));
+ /* special case (normal incidence) */
+ if (cos_theta_i >= 0.99999f) {
+ const float r = sqrtf(randu / (1.0f - randu));
+ const float phi = M_2PI_F * randv;
+ *slope_x = r * cosf(phi);
+ *slope_y = r * sinf(phi);
+ *G1i = 1.0f;
+
+ return;
+ }
+
+ /* precomputations */
+ const float tan_theta_i = sin_theta_i / cos_theta_i;
+ const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i));
+
+ *G1i = 1.0f / G1_inv;
+
+ /* sample slope_x */
+ const float A = 2.0f * randu * G1_inv - 1.0f;
+ const float AA = A * A;
+ const float tmp = 1.0f / (AA - 1.0f);
+ const float B = tan_theta_i;
+ const float BB = B * B;
+ const float D = safe_sqrtf(BB * (tmp * tmp) - (AA - BB) * tmp);
+ const float slope_x_1 = B * tmp - D;
+ const float slope_x_2 = B * tmp + D;
+ *slope_x = (A < 0.0f || slope_x_2 * tan_theta_i > 1.0f) ? slope_x_1 : slope_x_2;
+
+ /* sample slope_y */
+ float S;
+
+ if (randv > 0.5f) {
+ S = 1.0f;
+ randv = 2.0f * (randv - 0.5f);
+ }
+ else {
+ S = -1.0f;
+ randv = 2.0f * (0.5f - randv);
+ }
+
+ const float z = (randv * (randv * (randv * 0.27385f - 0.73369f) + 0.46341f)) /
+ (randv * (randv * (randv * 0.093073f + 0.309420f) - 1.000000f) + 0.597999f);
+ *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x) * (*slope_x));
}
-ccl_device_forceinline float3 microfacet_sample_stretched(
- KernelGlobals *kg, const float3 omega_i,
- const float alpha_x, const float alpha_y,
- const float randu, const float randv,
- bool beckmann, float *G1i)
+ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals *kg,
+ const float3 omega_i,
+ const float alpha_x,
+ const float alpha_y,
+ const float randu,
+ const float randv,
+ bool beckmann,
+ float *G1i)
{
- /* 1. stretch omega_i */
- float3 omega_i_ = make_float3(alpha_x * omega_i.x, alpha_y * omega_i.y, omega_i.z);
- omega_i_ = normalize(omega_i_);
-
- /* get polar coordinates of omega_i_ */
- float costheta_ = 1.0f;
- float sintheta_ = 0.0f;
- float cosphi_ = 1.0f;
- float sinphi_ = 0.0f;
-
- if(omega_i_.z < 0.99999f) {
- costheta_ = omega_i_.z;
- sintheta_ = safe_sqrtf(1.0f - costheta_*costheta_);
-
- float invlen = 1.0f/sintheta_;
- cosphi_ = omega_i_.x * invlen;
- sinphi_ = omega_i_.y * invlen;
- }
-
- /* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */
- float slope_x, slope_y;
-
- if(beckmann) {
- microfacet_beckmann_sample_slopes(kg, costheta_, sintheta_,
- randu, randv, &slope_x, &slope_y, G1i);
- }
- else {
- microfacet_ggx_sample_slopes(costheta_, sintheta_,
- randu, randv, &slope_x, &slope_y, G1i);
- }
-
- /* 3. rotate */
- float tmp = cosphi_*slope_x - sinphi_*slope_y;
- slope_y = sinphi_*slope_x + cosphi_*slope_y;
- slope_x = tmp;
-
- /* 4. unstretch */
- slope_x = alpha_x * slope_x;
- slope_y = alpha_y * slope_y;
-
- /* 5. compute normal */
- return normalize(make_float3(-slope_x, -slope_y, 1.0f));
+ /* 1. stretch omega_i */
+ float3 omega_i_ = make_float3(alpha_x * omega_i.x, alpha_y * omega_i.y, omega_i.z);
+ omega_i_ = normalize(omega_i_);
+
+ /* get polar coordinates of omega_i_ */
+ float costheta_ = 1.0f;
+ float sintheta_ = 0.0f;
+ float cosphi_ = 1.0f;
+ float sinphi_ = 0.0f;
+
+ if (omega_i_.z < 0.99999f) {
+ costheta_ = omega_i_.z;
+ sintheta_ = safe_sqrtf(1.0f - costheta_ * costheta_);
+
+ float invlen = 1.0f / sintheta_;
+ cosphi_ = omega_i_.x * invlen;
+ sinphi_ = omega_i_.y * invlen;
+ }
+
+ /* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */
+ float slope_x, slope_y;
+
+ if (beckmann) {
+ microfacet_beckmann_sample_slopes(
+ kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i);
+ }
+ else {
+ microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i);
+ }
+
+ /* 3. rotate */
+ float tmp = cosphi_ * slope_x - sinphi_ * slope_y;
+ slope_y = sinphi_ * slope_x + cosphi_ * slope_y;
+ slope_x = tmp;
+
+ /* 4. unstretch */
+ slope_x = alpha_x * slope_x;
+ slope_y = alpha_y * slope_y;
+
+ /* 5. compute normal */
+ return normalize(make_float3(-slope_x, -slope_y, 1.0f));
}
/* Calculate the reflection color
@@ -240,27 +249,29 @@ ccl_device_forceinline float3 microfacet_sample_stretched(
*
* Else it is simply white
*/
-ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, float3 L, float3 H) {
- float3 F = make_float3(1.0f, 1.0f, 1.0f);
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID
- || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID
- || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
+ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, float3 L, float3 H)
+{
+ float3 F = make_float3(1.0f, 1.0f, 1.0f);
+ bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
+ bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID ||
+ bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
- if(use_fresnel) {
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ if (use_fresnel) {
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0);
- }
+ F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0);
+ }
- return F;
+ return F;
}
ccl_device_forceinline float D_GTR1(float NdotH, float alpha)
{
- if(alpha >= 1.0f) return M_1_PI_F;
- float alpha2 = alpha*alpha;
- float t = 1.0f + (alpha2 - 1.0f) * NdotH*NdotH;
- return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t);
+ if (alpha >= 1.0f)
+ return M_1_PI_F;
+ float alpha2 = alpha * alpha;
+ float t = 1.0f + (alpha2 - 1.0f) * NdotH * NdotH;
+ return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t);
}
/* GGX microfacet with Smith shadow-masking from:
@@ -278,483 +289,511 @@ ccl_device_forceinline float D_GTR1(float NdotH, float alpha)
ccl_device int bsdf_microfacet_ggx_setup(MicrofacetBsdf *bsdf)
{
- bsdf->extra = NULL;
+ bsdf->extra = NULL;
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
{
- bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
- bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
- bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
+ bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
+ bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
+ bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
+ bsdf->sample_weight *= F;
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
{
- bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
- bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
- bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
+ bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
+ bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
+ bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= 0.25f * bsdf->extra->clearcoat * F;
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
+ bsdf->sample_weight *= 0.25f * bsdf->extra->clearcoat * F;
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device bool bsdf_microfacet_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const MicrofacetBsdf *bsdf_a = (const MicrofacetBsdf*)a;
- const MicrofacetBsdf *bsdf_b = (const MicrofacetBsdf*)b;
-
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) &&
- (bsdf_a->alpha_x == bsdf_b->alpha_x) &&
- (bsdf_a->alpha_y == bsdf_b->alpha_y) &&
- (isequal_float3(bsdf_a->T, bsdf_b->T)) &&
- (bsdf_a->ior == bsdf_b->ior) &&
- ((bsdf_a->extra == NULL && bsdf_b->extra == NULL) ||
- ((bsdf_a->extra && bsdf_b->extra) &&
- (isequal_float3(bsdf_a->extra->color, bsdf_b->extra->color)) &&
- (isequal_float3(bsdf_a->extra->cspec0, bsdf_b->extra->cspec0)) &&
- (bsdf_a->extra->clearcoat == bsdf_b->extra->clearcoat)));
+ const MicrofacetBsdf *bsdf_a = (const MicrofacetBsdf *)a;
+ const MicrofacetBsdf *bsdf_b = (const MicrofacetBsdf *)b;
+
+ return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->alpha_x == bsdf_b->alpha_x) &&
+ (bsdf_a->alpha_y == bsdf_b->alpha_y) && (isequal_float3(bsdf_a->T, bsdf_b->T)) &&
+ (bsdf_a->ior == bsdf_b->ior) &&
+ ((bsdf_a->extra == NULL && bsdf_b->extra == NULL) ||
+ ((bsdf_a->extra && bsdf_b->extra) &&
+ (isequal_float3(bsdf_a->extra->color, bsdf_b->extra->color)) &&
+ (isequal_float3(bsdf_a->extra->cspec0, bsdf_b->extra->cspec0)) &&
+ (bsdf_a->extra->clearcoat == bsdf_b->extra->clearcoat)));
}
ccl_device int bsdf_microfacet_ggx_aniso_setup(MicrofacetBsdf *bsdf)
{
- bsdf->extra = NULL;
+ bsdf->extra = NULL;
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = saturate(bsdf->alpha_y);
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = saturate(bsdf->alpha_y);
- bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
{
- bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
- bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
- bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
+ bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
+ bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
+ bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
+ bsdf->sample_weight *= F;
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = saturate(bsdf->alpha_y);
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = saturate(bsdf->alpha_y);
- bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_refraction_setup(MicrofacetBsdf *bsdf)
{
- bsdf->extra = NULL;
+ bsdf->extra = NULL;
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
{
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)sc;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
- bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
- bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
+ bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
+ bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
-ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if(m_refractive || alpha_x*alpha_y <= 1e-7f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if(cosNI > 0 && cosNO > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if(alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 33: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
-
- if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- /* use GTR1 for clearcoat */
- D = D_GTR1(cosThetaM, bsdf->alpha_x);
-
- /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
- alpha2 = 0.0625f;
- }
- else {
- /* use GTR2 otherwise */
- D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- }
-
- /* eq. 34: now calculate G1(i,m) and G1(o,m) */
- G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- }
- else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
-
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x/(local_m.z*alpha_x);
- float slope_y = -local_m.y/(local_m.z*alpha_y);
- float slope_len = 1 + slope_x*slope_x + slope_y*slope_y;
-
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
-
- D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
-
- /* G1(i,m) and G1(o,m) */
- float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
- float cosPhiO = dot(I, X);
- float sinPhiO = dot(I, Y);
-
- float alphaO2 = (cosPhiO*cosPhiO)*(alpha_x*alpha_x) + (sinPhiO*sinPhiO)*(alpha_y*alpha_y);
- alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO;
-
- G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
-
- float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
- float cosPhiI = dot(omega_in, X);
- float sinPhiI = dot(omega_in, Y);
-
- float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y);
- alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI;
-
- G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
- }
-
- float G = G1o * G1i;
-
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
-
- float3 F = reflection_color(bsdf, omega_in, m);
- if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- F *= 0.25f * bsdf->extra->clearcoat;
- }
-
- float3 out = F * G * common;
-
- /* eq. 2 in distribution of visible normals sampling
- * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
-
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * pdf = pm * 0.25 / dot(m, I); */
- *pdf = G1o * common;
-
- return out;
- }
-
- return make_float3(0.0f, 0.0f, 0.0f);
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ float3 N = bsdf->N;
+
+ if (m_refractive || alpha_x * alpha_y <= 1e-7f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
+
+ if (cosNI > 0 && cosNO > 0) {
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
+
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 33: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ /* use GTR1 for clearcoat */
+ D = D_GTR1(cosThetaM, bsdf->alpha_x);
+
+ /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
+ alpha2 = 0.0625f;
+ }
+ else {
+ /* use GTR2 otherwise */
+ D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ }
+
+ /* eq. 34: now calculate G1(i,m) and G1(o,m) */
+ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
+
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+
+ D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
+
+ /* G1(i,m) and G1(o,m) */
+ float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
+ float cosPhiO = dot(I, X);
+ float sinPhiO = dot(I, Y);
+
+ float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
+ (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
+ alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
+
+ G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
+
+ float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
+ float cosPhiI = dot(omega_in, X);
+ float sinPhiI = dot(omega_in, Y);
+
+ float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
+ (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
+ alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
+
+ G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
+ }
+
+ float G = G1o * G1i;
+
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
+
+ float3 F = reflection_color(bsdf, omega_in, m);
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ F *= 0.25f * bsdf->extra->clearcoat;
+ }
+
+ float3 out = F * G * common;
+
+ /* eq. 2 in distribution of visible normals sampling
+ * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * pdf = pm * 0.25 / dot(m, I); */
+ *pdf = G1o * common;
+
+ return out;
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ float m_eta = bsdf->ior;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ float3 N = bsdf->N;
- if(!m_refractive || alpha_x*alpha_y <= 1e-7f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (!m_refractive || alpha_x * alpha_y <= 1e-7f)
+ return make_float3(0.0f, 0.0f, 0.0f);
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
- if(cosNO <= 0 || cosNI >= 0)
- return make_float3(0.0f, 0.0f, 0.0f); /* vectors on same side -- not possible */
+ if (cosNO <= 0 || cosNI >= 0)
+ return make_float3(0.0f, 0.0f, 0.0f); /* vectors on same side -- not possible */
- /* compute half-vector of the refraction (eq. 16) */
- float3 ht = -(m_eta * omega_in + I);
- float3 Ht = normalize(ht);
- float cosHO = dot(Ht, I);
- float cosHI = dot(Ht, omega_in);
+ /* compute half-vector of the refraction (eq. 16) */
+ float3 ht = -(m_eta * omega_in + I);
+ float3 Ht = normalize(ht);
+ float cosHO = dot(Ht, I);
+ float cosHI = dot(Ht, omega_in);
- float D, G1o, G1i;
+ float D, G1o, G1i;
- /* eq. 33: first we calculate D(m) with m=Ht: */
- float alpha2 = alpha_x * alpha_y;
- float cosThetaM = dot(N, Ht);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ /* eq. 33: first we calculate D(m) with m=Ht: */
+ float alpha2 = alpha_x * alpha_y;
+ float cosThetaM = dot(N, Ht);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- /* eq. 34: now calculate G1(i,m) and G1(o,m) */
- G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ /* eq. 34: now calculate G1(i,m) and G1(o,m) */
+ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G = G1o * G1i;
+ float G = G1o * G1i;
- /* probability */
- float Ht2 = dot(ht, ht);
+ /* probability */
+ float Ht2 = dot(ht, ht);
- /* eq. 2 in distribution of visible normals sampling
- * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+ /* eq. 2 in distribution of visible normals sampling
+ * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
- /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
- * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
- float common = D * (m_eta * m_eta) / (cosNO * Ht2);
- float out = G * fabsf(cosHI * cosHO) * common;
- *pdf = G1o * fabsf(cosHO * cosHI) * common;
+ /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
+ * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
+ float common = D * (m_eta * m_eta) / (cosNO * Ht2);
+ float out = G * fabsf(cosHI * cosHO) * common;
+ *pdf = G1o * fabsf(cosHO * cosHI) * common;
- return make_float3(out, out, out);
+ return make_float3(out, out, out);
}
-ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg,
+ const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
- int label;
-
- float cosNO = dot(N, I);
- if(cosNO > 0) {
- float3 X, Y, Z = N;
-
- if(alpha_x == alpha_y)
- make_orthonormals(Z, &X, &Y);
- else
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
-
- /* importance sampling with distribution of visible normals. vectors are
- * transformed to local space before and after */
- float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
- float3 local_m;
- float G1o;
-
- local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_y,
- randu, randv, false, &G1o);
-
- float3 m = X*local_m.x + Y*local_m.y + Z*local_m.z;
- float cosThetaM = local_m.z;
-
- /* reflection or refraction? */
- if(!m_refractive) {
- float cosMO = dot(m, I);
- label = LABEL_REFLECT | LABEL_GLOSSY;
-
- if(cosMO > 0) {
- /* eq. 39 - compute actual reflected direction */
- *omega_in = 2 * cosMO * m - I;
-
- if(dot(Ng, *omega_in) > 0) {
- if(alpha_x*alpha_y <= 1e-7f) {
- /* some high number for MIS */
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
-
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID
- || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID
- || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
-
- /* if fresnel is used, calculate the color with reflection_color(...) */
- if(use_fresnel) {
- *eval *= reflection_color(bsdf, *omega_in, m);
- }
-
- label = LABEL_REFLECT | LABEL_SINGULAR;
- }
- else {
- /* microfacet normal is visible to this ray */
- /* eq. 33 */
- float alpha2 = alpha_x * alpha_y;
- float D, G1i;
-
- if(alpha_x == alpha_y) {
- /* isotropic */
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = 1/(cosThetaM2) - 1;
-
- /* eval BRDF*cosNI */
- float cosNI = dot(N, *omega_in);
-
- if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- /* use GTR1 for clearcoat */
- D = D_GTR1(cosThetaM, bsdf->alpha_x);
-
- /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
- alpha2 = 0.0625f;
-
- /* recalculate G1o */
- G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- }
- else {
- /* use GTR2 otherwise */
- D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- }
-
- /* eq. 34: now calculate G1(i,m) */
- G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- }
- else {
- /* anisotropic distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x/(local_m.z*alpha_x);
- float slope_y = -local_m.y/(local_m.z*alpha_y);
- float slope_len = 1 + slope_x*slope_x + slope_y*slope_y;
-
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
-
- D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
-
- /* calculate G1(i,m) */
- float cosNI = dot(N, *omega_in);
-
- float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
- float cosPhiI = dot(*omega_in, X);
- float sinPhiI = dot(*omega_in, Y);
-
- float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y);
- alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI;
-
- G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
- }
-
- /* see eval function for derivation */
- float common = (G1o * D) * 0.25f / cosNO;
- *pdf = common;
-
- float3 F = reflection_color(bsdf, *omega_in, m);
-
- *eval = G1i * common * F;
- }
-
- if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- *eval *= 0.25f * bsdf->extra->clearcoat;
- }
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ float3 N = bsdf->N;
+ int label;
+
+ float cosNO = dot(N, I);
+ if (cosNO > 0) {
+ float3 X, Y, Z = N;
+
+ if (alpha_x == alpha_y)
+ make_orthonormals(Z, &X, &Y);
+ else
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+
+ /* importance sampling with distribution of visible normals. vectors are
+ * transformed to local space before and after */
+ float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
+ float3 local_m;
+ float G1o;
+
+ local_m = microfacet_sample_stretched(
+ kg, local_I, alpha_x, alpha_y, randu, randv, false, &G1o);
+
+ float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z;
+ float cosThetaM = local_m.z;
+
+ /* reflection or refraction? */
+ if (!m_refractive) {
+ float cosMO = dot(m, I);
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+
+ if (cosMO > 0) {
+ /* eq. 39 - compute actual reflected direction */
+ *omega_in = 2 * cosMO * m - I;
+
+ if (dot(Ng, *omega_in) > 0) {
+ if (alpha_x * alpha_y <= 1e-7f) {
+ /* some high number for MIS */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+
+ bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
+ bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID ||
+ bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
+
+ /* if fresnel is used, calculate the color with reflection_color(...) */
+ if (use_fresnel) {
+ *eval *= reflection_color(bsdf, *omega_in, m);
+ }
+
+ label = LABEL_REFLECT | LABEL_SINGULAR;
+ }
+ else {
+ /* microfacet normal is visible to this ray */
+ /* eq. 33 */
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1i;
+
+ if (alpha_x == alpha_y) {
+ /* isotropic */
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = 1 / (cosThetaM2)-1;
+
+ /* eval BRDF*cosNI */
+ float cosNI = dot(N, *omega_in);
+
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ /* use GTR1 for clearcoat */
+ D = D_GTR1(cosThetaM, bsdf->alpha_x);
+
+ /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
+ alpha2 = 0.0625f;
+
+ /* recalculate G1o */
+ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ }
+ else {
+ /* use GTR2 otherwise */
+ D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ }
+
+ /* eq. 34: now calculate G1(i,m) */
+ G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ }
+ else {
+ /* anisotropic distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
+
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+
+ D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
+
+ /* calculate G1(i,m) */
+ float cosNI = dot(N, *omega_in);
+
+ float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
+ float cosPhiI = dot(*omega_in, X);
+ float sinPhiI = dot(*omega_in, Y);
+
+ float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
+ (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
+ alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
+
+ G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
+ }
+
+ /* see eval function for derivation */
+ float common = (G1o * D) * 0.25f / cosNO;
+ *pdf = common;
+
+ float3 F = reflection_color(bsdf, *omega_in, m);
+
+ *eval = G1i * common * F;
+ }
+
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ *eval *= 0.25f * bsdf->extra->clearcoat;
+ }
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
- *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
+ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
+ *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
#endif
- }
- }
- }
- else {
- label = LABEL_TRANSMIT | LABEL_GLOSSY;
-
- /* CAUTION: the i and o variables are inverted relative to the paper
- * eq. 39 - compute actual refractive direction */
- float3 R, T;
+ }
+ }
+ }
+ else {
+ label = LABEL_TRANSMIT | LABEL_GLOSSY;
+
+ /* CAUTION: the i and o variables are inverted relative to the paper
+ * eq. 39 - compute actual refractive direction */
+ float3 R, T;
#ifdef __RAY_DIFFERENTIALS__
- float3 dRdx, dRdy, dTdx, dTdy;
+ float3 dRdx, dRdy, dTdx, dTdy;
#endif
- float m_eta = bsdf->ior, fresnel;
- bool inside;
-
- fresnel = fresnel_dielectric(m_eta, m, I, &R, &T,
+ float m_eta = bsdf->ior, fresnel;
+ bool inside;
+
+ fresnel = fresnel_dielectric(m_eta,
+ m,
+ I,
+ &R,
+ &T,
#ifdef __RAY_DIFFERENTIALS__
- dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx,
+ dIdy,
+ &dRdx,
+ &dRdy,
+ &dTdx,
+ &dTdy,
#endif
- &inside);
+ &inside);
- if(!inside && fresnel != 1.0f) {
+ if (!inside && fresnel != 1.0f) {
- *omega_in = T;
+ *omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = dTdx;
- *domega_in_dy = dTdy;
+ *domega_in_dx = dTdx;
+ *domega_in_dy = dTdy;
#endif
- if(alpha_x*alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
- /* some high number for MIS */
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
- label = LABEL_TRANSMIT | LABEL_SINGULAR;
- }
- else {
- /* eq. 33 */
- float alpha2 = alpha_x * alpha_y;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = 1/(cosThetaM2) - 1;
- float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
-
- /* eval BRDF*cosNI */
- float cosNI = dot(N, *omega_in);
-
- /* eq. 34: now calculate G1(i,m) */
- float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
-
- /* eq. 21 */
- float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, I);
- float Ht2 = m_eta * cosHI + cosHO;
- Ht2 *= Ht2;
-
- /* see eval function for derivation */
- float common = (G1o * D) * (m_eta * m_eta) / (cosNO * Ht2);
- float out = G1i * fabsf(cosHI * cosHO) * common;
- *pdf = cosHO * fabsf(cosHI) * common;
-
- *eval = make_float3(out, out, out);
- }
- }
- }
- }
- else {
- label = (m_refractive) ? LABEL_TRANSMIT|LABEL_GLOSSY : LABEL_REFLECT|LABEL_GLOSSY;
- }
- return label;
+ if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
+ /* some high number for MIS */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ label = LABEL_TRANSMIT | LABEL_SINGULAR;
+ }
+ else {
+ /* eq. 33 */
+ float alpha2 = alpha_x * alpha_y;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = 1 / (cosThetaM2)-1;
+ float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+
+ /* eval BRDF*cosNI */
+ float cosNI = dot(N, *omega_in);
+
+ /* eq. 34: now calculate G1(i,m) */
+ float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+
+ /* eq. 21 */
+ float cosHI = dot(m, *omega_in);
+ float cosHO = dot(m, I);
+ float Ht2 = m_eta * cosHI + cosHO;
+ Ht2 *= Ht2;
+
+ /* see eval function for derivation */
+ float common = (G1o * D) * (m_eta * m_eta) / (cosNO * Ht2);
+ float out = G1i * fabsf(cosHI * cosHO) * common;
+ *pdf = cosHO * fabsf(cosHI) * common;
+
+ *eval = make_float3(out, out, out);
+ }
+ }
+ }
+ }
+ else {
+ label = (m_refractive) ? LABEL_TRANSMIT | LABEL_GLOSSY : LABEL_REFLECT | LABEL_GLOSSY;
+ }
+ return label;
}
/* Beckmann microfacet with Smith shadow-masking from:
@@ -764,364 +803,392 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
ccl_device int bsdf_microfacet_beckmann_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_beckmann_aniso_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = saturate(bsdf->alpha_y);
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = saturate(bsdf->alpha_y);
- bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_beckmann_refraction_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_x = saturate(bsdf->alpha_x);
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness)
{
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)sc;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
- bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
- bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
+ bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
+ bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
ccl_device_inline float bsdf_beckmann_G1(float alpha, float cos_n)
{
- cos_n *= cos_n;
- float invA = alpha * safe_sqrtf((1.0f - cos_n) / cos_n);
- if(invA < 0.625f) {
- return 1.0f;
- }
-
- float a = 1.0f / invA;
- return ((2.181f*a + 3.535f)*a) / ((2.577f*a + 2.276f)*a + 1.0f);
+ cos_n *= cos_n;
+ float invA = alpha * safe_sqrtf((1.0f - cos_n) / cos_n);
+ if (invA < 0.625f) {
+ return 1.0f;
+ }
+
+ float a = 1.0f / invA;
+ return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
}
-ccl_device_inline float bsdf_beckmann_aniso_G1(float alpha_x, float alpha_y, float cos_n, float cos_phi, float sin_phi)
+ccl_device_inline float bsdf_beckmann_aniso_G1(
+ float alpha_x, float alpha_y, float cos_n, float cos_phi, float sin_phi)
{
- cos_n *= cos_n;
- sin_phi *= sin_phi;
- cos_phi *= cos_phi;
- alpha_x *= alpha_x;
- alpha_y *= alpha_y;
-
- float alphaO2 = (cos_phi*alpha_x + sin_phi*alpha_y) / (cos_phi + sin_phi);
- float invA = safe_sqrtf(alphaO2 * (1 - cos_n) / cos_n);
- if(invA < 0.625f) {
- return 1.0f;
- }
-
- float a = 1.0f / invA;
- return ((2.181f*a + 3.535f)*a) / ((2.577f*a + 2.276f)*a + 1.0f);
+ cos_n *= cos_n;
+ sin_phi *= sin_phi;
+ cos_phi *= cos_phi;
+ alpha_x *= alpha_x;
+ alpha_y *= alpha_y;
+
+ float alphaO2 = (cos_phi * alpha_x + sin_phi * alpha_y) / (cos_phi + sin_phi);
+ float invA = safe_sqrtf(alphaO2 * (1 - cos_n) / cos_n);
+ if (invA < 0.625f) {
+ return 1.0f;
+ }
+
+ float a = 1.0f / invA;
+ return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
}
-ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if(m_refractive || alpha_x*alpha_y <= 1e-7f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if(cosNO > 0 && cosNI > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
-
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if(alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 25: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_G1(alpha_x, cosNO);
- G1i = bsdf_beckmann_G1(alpha_x, cosNI);
- }
- else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
-
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x/(local_m.z*alpha_x);
- float slope_y = -local_m.y/(local_m.z*alpha_y);
-
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
-
- D = expf(-slope_x*slope_x - slope_y*slope_y) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
- G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
- }
-
- float G = G1o * G1i;
-
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
- float out = G * common;
-
- /* eq. 2 in distribution of visible normals sampling
- * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
-
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * pdf = pm * 0.25 / dot(m, I); */
- *pdf = G1o * common;
-
- return make_float3(out, out, out);
- }
-
- return make_float3(0.0f, 0.0f, 0.0f);
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ float3 N = bsdf->N;
+
+ if (m_refractive || alpha_x * alpha_y <= 1e-7f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
+
+ if (cosNO > 0 && cosNI > 0) {
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
+
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
+
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 25: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_G1(alpha_x, cosNO);
+ G1i = bsdf_beckmann_G1(alpha_x, cosNI);
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
+
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+
+ D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
+ G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
+ }
+
+ float G = G1o * G1i;
+
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
+ float out = G * common;
+
+ /* eq. 2 in distribution of visible normals sampling
+ * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * pdf = pm * 0.25 / dot(m, I); */
+ *pdf = G1o * common;
+
+ return make_float3(out, out, out);
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if(!m_refractive || alpha_x*alpha_y <= 1e-7f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if(cosNO <= 0 || cosNI >= 0)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- /* compute half-vector of the refraction (eq. 16) */
- float3 ht = -(m_eta * omega_in + I);
- float3 Ht = normalize(ht);
- float cosHO = dot(Ht, I);
- float cosHI = dot(Ht, omega_in);
-
- /* eq. 25: first we calculate D(m) with m=Ht: */
- float alpha2 = alpha_x * alpha_y;
- float cosThetaM = min(dot(N, Ht), 1.0f);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
- float G1o = bsdf_beckmann_G1(alpha_x, cosNO);
- float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
- float G = G1o * G1i;
-
- /* probability */
- float Ht2 = dot(ht, ht);
-
- /* eq. 2 in distribution of visible normals sampling
- * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
-
- /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
- * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
- float common = D * (m_eta * m_eta) / (cosNO * Ht2);
- float out = G * fabsf(cosHI * cosHO) * common;
- *pdf = G1o * fabsf(cosHO * cosHI) * common;
-
- return make_float3(out, out, out);
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ float m_eta = bsdf->ior;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ float3 N = bsdf->N;
+
+ if (!m_refractive || alpha_x * alpha_y <= 1e-7f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
+
+ if (cosNO <= 0 || cosNI >= 0)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ /* compute half-vector of the refraction (eq. 16) */
+ float3 ht = -(m_eta * omega_in + I);
+ float3 Ht = normalize(ht);
+ float cosHO = dot(Ht, I);
+ float cosHI = dot(Ht, omega_in);
+
+ /* eq. 25: first we calculate D(m) with m=Ht: */
+ float alpha2 = alpha_x * alpha_y;
+ float cosThetaM = min(dot(N, Ht), 1.0f);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
+ float G1o = bsdf_beckmann_G1(alpha_x, cosNO);
+ float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
+ float G = G1o * G1i;
+
+ /* probability */
+ float Ht2 = dot(ht, ht);
+
+ /* eq. 2 in distribution of visible normals sampling
+ * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+
+ /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
+ * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
+ float common = D * (m_eta * m_eta) / (cosNO * Ht2);
+ float out = G * fabsf(cosHI * cosHO) * common;
+ *pdf = G1o * fabsf(cosHO * cosHI) * common;
+
+ return make_float3(out, out, out);
}
-ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg,
+ const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
- int label;
-
- float cosNO = dot(N, I);
- if(cosNO > 0) {
- float3 X, Y, Z = N;
-
- if(alpha_x == alpha_y)
- make_orthonormals(Z, &X, &Y);
- else
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
-
- /* importance sampling with distribution of visible normals. vectors are
- * transformed to local space before and after */
- float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
- float3 local_m;
- float G1o;
-
- local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x,
- randu, randv, true, &G1o);
-
- float3 m = X*local_m.x + Y*local_m.y + Z*local_m.z;
- float cosThetaM = local_m.z;
-
- /* reflection or refraction? */
- if(!m_refractive) {
- label = LABEL_REFLECT | LABEL_GLOSSY;
- float cosMO = dot(m, I);
-
- if(cosMO > 0) {
- /* eq. 39 - compute actual reflected direction */
- *omega_in = 2 * cosMO * m - I;
-
- if(dot(Ng, *omega_in) > 0) {
- if(alpha_x*alpha_y <= 1e-7f) {
- /* some high number for MIS */
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
- label = LABEL_REFLECT | LABEL_SINGULAR;
- }
- else {
- /* microfacet normal is visible to this ray
- * eq. 25 */
- float alpha2 = alpha_x * alpha_y;
- float D, G1i;
-
- if(alpha_x == alpha_y) {
- /* istropic distribution */
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = 1/(cosThetaM2) - 1;
- D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* eval BRDF*cosNI */
- float cosNI = dot(N, *omega_in);
-
- /* eq. 26, 27: now calculate G1(i,m) */
- G1i = bsdf_beckmann_G1(alpha_x, cosNI);
- }
- else {
- /* anisotropic distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x/(local_m.z*alpha_x);
- float slope_y = -local_m.y/(local_m.z*alpha_y);
-
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
-
- D = expf(-slope_x*slope_x - slope_y*slope_y) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* G1(i,m) */
- G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, dot(*omega_in, N), dot(*omega_in, X), dot(*omega_in, Y));
- }
-
- float G = G1o * G1i;
-
- /* see eval function for derivation */
- float common = D * 0.25f / cosNO;
- float out = G * common;
- *pdf = G1o * common;
-
- *eval = make_float3(out, out, out);
- }
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ float3 N = bsdf->N;
+ int label;
+
+ float cosNO = dot(N, I);
+ if (cosNO > 0) {
+ float3 X, Y, Z = N;
+
+ if (alpha_x == alpha_y)
+ make_orthonormals(Z, &X, &Y);
+ else
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+
+ /* importance sampling with distribution of visible normals. vectors are
+ * transformed to local space before and after */
+ float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
+ float3 local_m;
+ float G1o;
+
+ local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, &G1o);
+
+ float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z;
+ float cosThetaM = local_m.z;
+
+ /* reflection or refraction? */
+ if (!m_refractive) {
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ float cosMO = dot(m, I);
+
+ if (cosMO > 0) {
+ /* eq. 39 - compute actual reflected direction */
+ *omega_in = 2 * cosMO * m - I;
+
+ if (dot(Ng, *omega_in) > 0) {
+ if (alpha_x * alpha_y <= 1e-7f) {
+ /* some high number for MIS */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ label = LABEL_REFLECT | LABEL_SINGULAR;
+ }
+ else {
+ /* microfacet normal is visible to this ray
+ * eq. 25 */
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1i;
+
+ if (alpha_x == alpha_y) {
+ /* istropic distribution */
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = 1 / (cosThetaM2)-1;
+ D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* eval BRDF*cosNI */
+ float cosNI = dot(N, *omega_in);
+
+ /* eq. 26, 27: now calculate G1(i,m) */
+ G1i = bsdf_beckmann_G1(alpha_x, cosNI);
+ }
+ else {
+ /* anisotropic distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
+
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+
+ D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* G1(i,m) */
+ G1i = bsdf_beckmann_aniso_G1(
+ alpha_x, alpha_y, dot(*omega_in, N), dot(*omega_in, X), dot(*omega_in, Y));
+ }
+
+ float G = G1o * G1i;
+
+ /* see eval function for derivation */
+ float common = D * 0.25f / cosNO;
+ float out = G * common;
+ *pdf = G1o * common;
+
+ *eval = make_float3(out, out, out);
+ }
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
- *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
+ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
+ *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
#endif
- }
- }
- }
- else {
- label = LABEL_TRANSMIT | LABEL_GLOSSY;
-
- /* CAUTION: the i and o variables are inverted relative to the paper
- * eq. 39 - compute actual refractive direction */
- float3 R, T;
+ }
+ }
+ }
+ else {
+ label = LABEL_TRANSMIT | LABEL_GLOSSY;
+
+ /* CAUTION: the i and o variables are inverted relative to the paper
+ * eq. 39 - compute actual refractive direction */
+ float3 R, T;
#ifdef __RAY_DIFFERENTIALS__
- float3 dRdx, dRdy, dTdx, dTdy;
+ float3 dRdx, dRdy, dTdx, dTdy;
#endif
- float m_eta = bsdf->ior, fresnel;
- bool inside;
-
- fresnel = fresnel_dielectric(m_eta, m, I, &R, &T,
+ float m_eta = bsdf->ior, fresnel;
+ bool inside;
+
+ fresnel = fresnel_dielectric(m_eta,
+ m,
+ I,
+ &R,
+ &T,
#ifdef __RAY_DIFFERENTIALS__
- dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx,
+ dIdy,
+ &dRdx,
+ &dRdy,
+ &dTdx,
+ &dTdy,
#endif
- &inside);
+ &inside);
- if(!inside && fresnel != 1.0f) {
- *omega_in = T;
+ if (!inside && fresnel != 1.0f) {
+ *omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = dTdx;
- *domega_in_dy = dTdy;
+ *domega_in_dx = dTdx;
+ *domega_in_dy = dTdy;
#endif
- if(alpha_x*alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
- /* some high number for MIS */
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
- label = LABEL_TRANSMIT | LABEL_SINGULAR;
- }
- else {
- /* eq. 33 */
- float alpha2 = alpha_x * alpha_y;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = 1/(cosThetaM2) - 1;
- float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* eval BRDF*cosNI */
- float cosNI = dot(N, *omega_in);
-
- /* eq. 26, 27: now calculate G1(i,m) */
- float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
- float G = G1o * G1i;
-
- /* eq. 21 */
- float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, I);
- float Ht2 = m_eta * cosHI + cosHO;
- Ht2 *= Ht2;
-
- /* see eval function for derivation */
- float common = D * (m_eta * m_eta) / (cosNO * Ht2);
- float out = G * fabsf(cosHI * cosHO) * common;
- *pdf = G1o * cosHO * fabsf(cosHI) * common;
-
- *eval = make_float3(out, out, out);
- }
- }
- }
- }
- else {
- label = (m_refractive) ? LABEL_TRANSMIT|LABEL_GLOSSY : LABEL_REFLECT|LABEL_GLOSSY;
- }
- return label;
+ if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
+ /* some high number for MIS */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ label = LABEL_TRANSMIT | LABEL_SINGULAR;
+ }
+ else {
+ /* eq. 33 */
+ float alpha2 = alpha_x * alpha_y;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = 1 / (cosThetaM2)-1;
+ float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* eval BRDF*cosNI */
+ float cosNI = dot(N, *omega_in);
+
+ /* eq. 26, 27: now calculate G1(i,m) */
+ float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
+ float G = G1o * G1i;
+
+ /* eq. 21 */
+ float cosHI = dot(m, *omega_in);
+ float cosHO = dot(m, I);
+ float Ht2 = m_eta * cosHI + cosHO;
+ Ht2 *= Ht2;
+
+ /* see eval function for derivation */
+ float common = D * (m_eta * m_eta) / (cosNO * Ht2);
+ float out = G * fabsf(cosHI * cosHO) * common;
+ *pdf = G1o * cosHO * fabsf(cosHI) * common;
+
+ *eval = make_float3(out, out, out);
+ }
+ }
+ }
+ }
+ else {
+ label = (m_refractive) ? LABEL_TRANSMIT | LABEL_GLOSSY : LABEL_REFLECT | LABEL_GLOSSY;
+ }
+ return label;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_MICROFACET_H__ */
+#endif /* __BSDF_MICROFACET_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 2f2c35d5d1f..2cc1a9c5299 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -23,149 +23,168 @@ CCL_NAMESPACE_BEGIN
/* Isotropic GGX microfacet distribution */
ccl_device_forceinline float D_ggx(float3 wm, float alpha)
{
- wm.z *= wm.z;
- alpha *= alpha;
- float tmp = (1.0f - wm.z) + alpha * wm.z;
- return alpha / max(M_PI_F * tmp*tmp, 1e-7f);
+ wm.z *= wm.z;
+ alpha *= alpha;
+ float tmp = (1.0f - wm.z) + alpha * wm.z;
+ return alpha / max(M_PI_F * tmp * tmp, 1e-7f);
}
/* Anisotropic GGX microfacet distribution */
ccl_device_forceinline float D_ggx_aniso(const float3 wm, const float2 alpha)
{
- float slope_x = -wm.x/alpha.x;
- float slope_y = -wm.y/alpha.y;
- float tmp = wm.z*wm.z + slope_x*slope_x + slope_y*slope_y;
+ float slope_x = -wm.x / alpha.x;
+ float slope_y = -wm.y / alpha.y;
+ float tmp = wm.z * wm.z + slope_x * slope_x + slope_y * slope_y;
- return 1.0f / max(M_PI_F * tmp*tmp * alpha.x*alpha.y, 1e-7f);
+ return 1.0f / max(M_PI_F * tmp * tmp * alpha.x * alpha.y, 1e-7f);
}
/* Sample slope distribution (based on page 14 of the supplemental implementation). */
-ccl_device_forceinline float2 mf_sampleP22_11(const float cosI, const float randx, const float randy)
-{
- if(cosI > 0.9999f || fabsf(cosI) < 1e-6f) {
- const float r = sqrtf(randx / max(1.0f - randx, 1e-7f));
- const float phi = M_2PI_F * randy;
- return make_float2(r*cosf(phi), r*sinf(phi));
- }
-
- const float sinI = safe_sqrtf(1.0f - cosI*cosI);
- const float tanI = sinI/cosI;
- const float projA = 0.5f * (cosI + 1.0f);
- if(projA < 0.0001f)
- return make_float2(0.0f, 0.0f);
- const float A = 2.0f*randx*projA / cosI - 1.0f;
- float tmp = A*A-1.0f;
- if(fabsf(tmp) < 1e-7f)
- return make_float2(0.0f, 0.0f);
- tmp = 1.0f / tmp;
- const float D = safe_sqrtf(tanI*tanI*tmp*tmp - (A*A-tanI*tanI)*tmp);
-
- const float slopeX2 = tanI*tmp + D;
- const float slopeX = (A < 0.0f || slopeX2 > 1.0f/tanI)? (tanI*tmp - D) : slopeX2;
-
- float U2;
- if(randy >= 0.5f)
- U2 = 2.0f*(randy - 0.5f);
- else
- U2 = 2.0f*(0.5f - randy);
- const float z = (U2*(U2*(U2*0.27385f-0.73369f)+0.46341f)) / (U2*(U2*(U2*0.093073f+0.309420f)-1.0f)+0.597999f);
- const float slopeY = z * sqrtf(1.0f + slopeX*slopeX);
-
- if(randy >= 0.5f)
- return make_float2(slopeX, slopeY);
- else
- return make_float2(slopeX, -slopeY);
+ccl_device_forceinline float2 mf_sampleP22_11(const float cosI,
+ const float randx,
+ const float randy)
+{
+ if (cosI > 0.9999f || fabsf(cosI) < 1e-6f) {
+ const float r = sqrtf(randx / max(1.0f - randx, 1e-7f));
+ const float phi = M_2PI_F * randy;
+ return make_float2(r * cosf(phi), r * sinf(phi));
+ }
+
+ const float sinI = safe_sqrtf(1.0f - cosI * cosI);
+ const float tanI = sinI / cosI;
+ const float projA = 0.5f * (cosI + 1.0f);
+ if (projA < 0.0001f)
+ return make_float2(0.0f, 0.0f);
+ const float A = 2.0f * randx * projA / cosI - 1.0f;
+ float tmp = A * A - 1.0f;
+ if (fabsf(tmp) < 1e-7f)
+ return make_float2(0.0f, 0.0f);
+ tmp = 1.0f / tmp;
+ const float D = safe_sqrtf(tanI * tanI * tmp * tmp - (A * A - tanI * tanI) * tmp);
+
+ const float slopeX2 = tanI * tmp + D;
+ const float slopeX = (A < 0.0f || slopeX2 > 1.0f / tanI) ? (tanI * tmp - D) : slopeX2;
+
+ float U2;
+ if (randy >= 0.5f)
+ U2 = 2.0f * (randy - 0.5f);
+ else
+ U2 = 2.0f * (0.5f - randy);
+ const float z = (U2 * (U2 * (U2 * 0.27385f - 0.73369f) + 0.46341f)) /
+ (U2 * (U2 * (U2 * 0.093073f + 0.309420f) - 1.0f) + 0.597999f);
+ const float slopeY = z * sqrtf(1.0f + slopeX * slopeX);
+
+ if (randy >= 0.5f)
+ return make_float2(slopeX, slopeY);
+ else
+ return make_float2(slopeX, -slopeY);
}
/* Visible normal sampling for the GGX distribution (based on page 7 of the supplemental implementation). */
-ccl_device_forceinline float3 mf_sample_vndf(const float3 wi, const float2 alpha, const float randx, const float randy)
+ccl_device_forceinline float3 mf_sample_vndf(const float3 wi,
+ const float2 alpha,
+ const float randx,
+ const float randy)
{
- const float3 wi_11 = normalize(make_float3(alpha.x*wi.x, alpha.y*wi.y, wi.z));
- const float2 slope_11 = mf_sampleP22_11(wi_11.z, randx, randy);
+ const float3 wi_11 = normalize(make_float3(alpha.x * wi.x, alpha.y * wi.y, wi.z));
+ const float2 slope_11 = mf_sampleP22_11(wi_11.z, randx, randy);
- const float3 cossin_phi = safe_normalize(make_float3(wi_11.x, wi_11.y, 0.0f));
- const float slope_x = alpha.x*(cossin_phi.x * slope_11.x - cossin_phi.y * slope_11.y);
- const float slope_y = alpha.y*(cossin_phi.y * slope_11.x + cossin_phi.x * slope_11.y);
+ const float3 cossin_phi = safe_normalize(make_float3(wi_11.x, wi_11.y, 0.0f));
+ const float slope_x = alpha.x * (cossin_phi.x * slope_11.x - cossin_phi.y * slope_11.y);
+ const float slope_y = alpha.y * (cossin_phi.y * slope_11.x + cossin_phi.x * slope_11.y);
- kernel_assert(isfinite(slope_x));
- return normalize(make_float3(-slope_x, -slope_y, 1.0f));
+ kernel_assert(isfinite(slope_x));
+ return normalize(make_float3(-slope_x, -slope_y, 1.0f));
}
/* === Phase functions: Glossy and Glass === */
/* Phase function for reflective materials. */
-ccl_device_forceinline float3 mf_sample_phase_glossy(const float3 wi, float3 *weight, const float3 wm)
+ccl_device_forceinline float3 mf_sample_phase_glossy(const float3 wi,
+ float3 *weight,
+ const float3 wm)
{
- return -wi + 2.0f * wm * dot(wi, wm);
+ return -wi + 2.0f * wm * dot(wi, wm);
}
-ccl_device_forceinline float3 mf_eval_phase_glossy(const float3 w, const float lambda, const float3 wo, const float2 alpha)
+ccl_device_forceinline float3 mf_eval_phase_glossy(const float3 w,
+ const float lambda,
+ const float3 wo,
+ const float2 alpha)
{
- if(w.z > 0.9999f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (w.z > 0.9999f)
+ return make_float3(0.0f, 0.0f, 0.0f);
- const float3 wh = normalize(wo - w);
- if(wh.z < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ const float3 wh = normalize(wo - w);
+ if (wh.z < 0.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
- float pArea = (w.z < -0.9999f)? 1.0f: lambda*w.z;
+ float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z;
- const float dotW_WH = dot(-w, wh);
- if(dotW_WH < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ const float dotW_WH = dot(-w, wh);
+ if (dotW_WH < 0.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
- float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f);
- if(alpha.x == alpha.y)
- phase *= D_ggx(wh, alpha.x);
- else
- phase *= D_ggx_aniso(wh, alpha);
+ float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f);
+ if (alpha.x == alpha.y)
+ phase *= D_ggx(wh, alpha.x);
+ else
+ phase *= D_ggx_aniso(wh, alpha);
- return make_float3(phase, phase, phase);
+ return make_float3(phase, phase, phase);
}
/* Phase function for dielectric transmissive materials, including both reflection and refraction according to the dielectric fresnel term. */
-ccl_device_forceinline float3 mf_sample_phase_glass(const float3 wi, const float eta, const float3 wm, const float randV, bool *outside)
-{
- float cosI = dot(wi, wm);
- float f = fresnel_dielectric_cos(cosI, eta);
- if(randV < f) {
- *outside = true;
- return -wi + 2.0f * wm * cosI;
- }
- *outside = false;
- float inv_eta = 1.0f/eta;
- float cosT = -safe_sqrtf(1.0f - (1.0f - cosI*cosI) * inv_eta*inv_eta);
- return normalize(wm*(cosI*inv_eta + cosT) - wi*inv_eta);
-}
-
-ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w, const float lambda, const float3 wo, const bool wo_outside, const float2 alpha, const float eta)
-{
- if(w.z > 0.9999f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float pArea = (w.z < -0.9999f)? 1.0f: lambda*w.z;
- float v;
- if(wo_outside) {
- const float3 wh = normalize(wo - w);
- if(wh.z < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- const float dotW_WH = dot(-w, wh);
- v = fresnel_dielectric_cos(dotW_WH, eta) * max(0.0f, dotW_WH) * D_ggx(wh, alpha.x) * 0.25f / (pArea * dotW_WH);
- }
- else {
- float3 wh = normalize(wo*eta - w);
- if(wh.z < 0.0f)
- wh = -wh;
- const float dotW_WH = dot(-w, wh), dotWO_WH = dot(wo, wh);
- if(dotW_WH < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float temp = dotW_WH + eta*dotWO_WH;
- v = (1.0f - fresnel_dielectric_cos(dotW_WH, eta)) * max(0.0f, dotW_WH) * max(0.0f, -dotWO_WH) * D_ggx(wh, alpha.x) / (pArea * temp * temp);
- }
-
- return make_float3(v, v, v);
+ccl_device_forceinline float3 mf_sample_phase_glass(
+ const float3 wi, const float eta, const float3 wm, const float randV, bool *outside)
+{
+ float cosI = dot(wi, wm);
+ float f = fresnel_dielectric_cos(cosI, eta);
+ if (randV < f) {
+ *outside = true;
+ return -wi + 2.0f * wm * cosI;
+ }
+ *outside = false;
+ float inv_eta = 1.0f / eta;
+ float cosT = -safe_sqrtf(1.0f - (1.0f - cosI * cosI) * inv_eta * inv_eta);
+ return normalize(wm * (cosI * inv_eta + cosT) - wi * inv_eta);
+}
+
+ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w,
+ const float lambda,
+ const float3 wo,
+ const bool wo_outside,
+ const float2 alpha,
+ const float eta)
+{
+ if (w.z > 0.9999f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z;
+ float v;
+ if (wo_outside) {
+ const float3 wh = normalize(wo - w);
+ if (wh.z < 0.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ const float dotW_WH = dot(-w, wh);
+ v = fresnel_dielectric_cos(dotW_WH, eta) * max(0.0f, dotW_WH) * D_ggx(wh, alpha.x) * 0.25f /
+ (pArea * dotW_WH);
+ }
+ else {
+ float3 wh = normalize(wo * eta - w);
+ if (wh.z < 0.0f)
+ wh = -wh;
+ const float dotW_WH = dot(-w, wh), dotWO_WH = dot(wo, wh);
+ if (dotW_WH < 0.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float temp = dotW_WH + eta * dotWO_WH;
+ v = (1.0f - fresnel_dielectric_cos(dotW_WH, eta)) * max(0.0f, dotW_WH) * max(0.0f, -dotWO_WH) *
+ D_ggx(wh, alpha.x) / (pArea * temp * temp);
+ }
+
+ return make_float3(v, v, v);
}
/* === Utility functions for the random walks === */
@@ -173,64 +192,65 @@ ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w, const float la
/* Smith Lambda function for GGX (based on page 12 of the supplemental implementation). */
ccl_device_forceinline float mf_lambda(const float3 w, const float2 alpha)
{
- if(w.z > 0.9999f)
- return 0.0f;
- else if(w.z < -0.9999f)
- return -0.9999f;
+ if (w.z > 0.9999f)
+ return 0.0f;
+ else if (w.z < -0.9999f)
+ return -0.9999f;
- const float inv_wz2 = 1.0f / max(w.z*w.z, 1e-7f);
- const float2 wa = make_float2(w.x, w.y)*alpha;
- float v = sqrtf(1.0f + dot(wa, wa) * inv_wz2);
- if(w.z <= 0.0f)
- v = -v;
+ const float inv_wz2 = 1.0f / max(w.z * w.z, 1e-7f);
+ const float2 wa = make_float2(w.x, w.y) * alpha;
+ float v = sqrtf(1.0f + dot(wa, wa) * inv_wz2);
+ if (w.z <= 0.0f)
+ v = -v;
- return 0.5f*(v - 1.0f);
+ return 0.5f * (v - 1.0f);
}
/* Height distribution CDF (based on page 4 of the supplemental implementation). */
ccl_device_forceinline float mf_invC1(const float h)
{
- return 2.0f * saturate(h) - 1.0f;
+ return 2.0f * saturate(h) - 1.0f;
}
ccl_device_forceinline float mf_C1(const float h)
{
- return saturate(0.5f * (h + 1.0f));
+ return saturate(0.5f * (h + 1.0f));
}
/* Masking function (based on page 16 of the supplemental implementation). */
ccl_device_forceinline float mf_G1(const float3 w, const float C1, const float lambda)
{
- if(w.z > 0.9999f)
- return 1.0f;
- if(w.z < 1e-5f)
- return 0.0f;
- return powf(C1, lambda);
+ if (w.z > 0.9999f)
+ return 1.0f;
+ if (w.z < 1e-5f)
+ return 0.0f;
+ return powf(C1, lambda);
}
/* Sampling from the visible height distribution (based on page 17 of the supplemental implementation). */
-ccl_device_forceinline bool mf_sample_height(const float3 w, float *h, float *C1, float *G1, float *lambda, const float U)
-{
- if(w.z > 0.9999f)
- return false;
- if(w.z < -0.9999f) {
- *C1 *= U;
- *h = mf_invC1(*C1);
- *G1 = mf_G1(w, *C1, *lambda);
- }
- else if(fabsf(w.z) >= 0.0001f) {
- if(U > 1.0f - *G1)
- return false;
- if(*lambda >= 0.0f) {
- *C1 = 1.0f;
- }
- else {
- *C1 *= powf(1.0f-U, -1.0f / *lambda);
- }
- *h = mf_invC1(*C1);
- *G1 = mf_G1(w, *C1, *lambda);
- }
- return true;
+ccl_device_forceinline bool mf_sample_height(
+ const float3 w, float *h, float *C1, float *G1, float *lambda, const float U)
+{
+ if (w.z > 0.9999f)
+ return false;
+ if (w.z < -0.9999f) {
+ *C1 *= U;
+ *h = mf_invC1(*C1);
+ *G1 = mf_G1(w, *C1, *lambda);
+ }
+ else if (fabsf(w.z) >= 0.0001f) {
+ if (U > 1.0f - *G1)
+ return false;
+ if (*lambda >= 0.0f) {
+ *C1 = 1.0f;
+ }
+ else {
+ *C1 *= powf(1.0f - U, -1.0f / *lambda);
+ }
+ *h = mf_invC1(*C1);
+ *G1 = mf_G1(w, *C1, *lambda);
+ }
+ return true;
}
/* === PDF approximations for the different phase functions. ===
@@ -240,80 +260,92 @@ ccl_device_forceinline bool mf_sample_height(const float3 w, float *h, float *C1
* the missing energy is then approximated as a diffuse reflection for the PDF. */
ccl_device_forceinline float mf_ggx_albedo(float r)
{
- float albedo = 0.806495f*expf(-1.98712f*r*r) + 0.199531f;
- albedo -= ((((((1.76741f*r - 8.43891f)*r + 15.784f)*r - 14.398f)*r + 6.45221f)*r - 1.19722f)*r + 0.027803f)*r + 0.00568739f;
- return saturate(albedo);
+ float albedo = 0.806495f * expf(-1.98712f * r * r) + 0.199531f;
+ albedo -= ((((((1.76741f * r - 8.43891f) * r + 15.784f) * r - 14.398f) * r + 6.45221f) * r -
+ 1.19722f) *
+ r +
+ 0.027803f) *
+ r +
+ 0.00568739f;
+ return saturate(albedo);
}
ccl_device_inline float mf_ggx_transmission_albedo(float a, float ior)
{
- if(ior < 1.0f) {
- ior = 1.0f/ior;
- }
- a = saturate(a);
- ior = clamp(ior, 1.0f, 3.0f);
- float I_1 = 0.0476898f*expf(-0.978352f*(ior-0.65657f)*(ior-0.65657f)) - 0.033756f*ior + 0.993261f;
- float R_1 = (((0.116991f*a - 0.270369f)*a + 0.0501366f)*a - 0.00411511f)*a + 1.00008f;
- float I_2 = (((-2.08704f*ior + 26.3298f)*ior - 127.906f)*ior + 292.958f)*ior - 287.946f + 199.803f/(ior*ior) - 101.668f/(ior*ior*ior);
- float R_2 = ((((5.3725f*a -24.9307f)*a + 22.7437f)*a - 3.40751f)*a + 0.0986325f)*a + 0.00493504f;
-
- return saturate(1.0f + I_2*R_2*0.0019127f - (1.0f - I_1)*(1.0f - R_1)*9.3205f);
+ if (ior < 1.0f) {
+ ior = 1.0f / ior;
+ }
+ a = saturate(a);
+ ior = clamp(ior, 1.0f, 3.0f);
+ float I_1 = 0.0476898f * expf(-0.978352f * (ior - 0.65657f) * (ior - 0.65657f)) -
+ 0.033756f * ior + 0.993261f;
+ float R_1 = (((0.116991f * a - 0.270369f) * a + 0.0501366f) * a - 0.00411511f) * a + 1.00008f;
+ float I_2 = (((-2.08704f * ior + 26.3298f) * ior - 127.906f) * ior + 292.958f) * ior - 287.946f +
+ 199.803f / (ior * ior) - 101.668f / (ior * ior * ior);
+ float R_2 = ((((5.3725f * a - 24.9307f) * a + 22.7437f) * a - 3.40751f) * a + 0.0986325f) * a +
+ 0.00493504f;
+
+ return saturate(1.0f + I_2 * R_2 * 0.0019127f - (1.0f - I_1) * (1.0f - R_1) * 9.3205f);
}
ccl_device_forceinline float mf_ggx_pdf(const float3 wi, const float3 wo, const float alpha)
{
- float D = D_ggx(normalize(wi+wo), alpha);
- float lambda = mf_lambda(wi, make_float2(alpha, alpha));
- float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f);
+ float D = D_ggx(normalize(wi + wo), alpha);
+ float lambda = mf_lambda(wi, make_float2(alpha, alpha));
+ float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f);
- float multiscatter = wo.z * M_1_PI_F;
+ float multiscatter = wo.z * M_1_PI_F;
- float albedo = mf_ggx_albedo(alpha);
- return albedo*singlescatter + (1.0f - albedo)*multiscatter;
+ float albedo = mf_ggx_albedo(alpha);
+ return albedo * singlescatter + (1.0f - albedo) * multiscatter;
}
ccl_device_forceinline float mf_ggx_aniso_pdf(const float3 wi, const float3 wo, const float2 alpha)
{
- float D = D_ggx_aniso(normalize(wi+wo), alpha);
- float lambda = mf_lambda(wi, alpha);
- float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f);
+ float D = D_ggx_aniso(normalize(wi + wo), alpha);
+ float lambda = mf_lambda(wi, alpha);
+ float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f);
- float multiscatter = wo.z * M_1_PI_F;
+ float multiscatter = wo.z * M_1_PI_F;
- float albedo = mf_ggx_albedo(sqrtf(alpha.x*alpha.y));
- return albedo*singlescatter + (1.0f - albedo)*multiscatter;
+ float albedo = mf_ggx_albedo(sqrtf(alpha.x * alpha.y));
+ return albedo * singlescatter + (1.0f - albedo) * multiscatter;
}
-ccl_device_forceinline float mf_glass_pdf(const float3 wi, const float3 wo, const float alpha, const float eta)
+ccl_device_forceinline float mf_glass_pdf(const float3 wi,
+ const float3 wo,
+ const float alpha,
+ const float eta)
{
- bool reflective = (wi.z*wo.z > 0.0f);
-
- float wh_len;
- float3 wh = normalize_len(wi + (reflective? wo : (wo*eta)), &wh_len);
- if(wh.z < 0.0f)
- wh = -wh;
- float3 r_wi = (wi.z < 0.0f)? -wi: wi;
- float lambda = mf_lambda(r_wi, make_float2(alpha, alpha));
- float D = D_ggx(wh, alpha);
- float fresnel = fresnel_dielectric_cos(dot(r_wi, wh), eta);
-
- float multiscatter = fabsf(wo.z * M_1_PI_F);
- if(reflective) {
- float singlescatter = 0.25f * D / max((1.0f + lambda) * r_wi.z, 1e-7f);
- float albedo = mf_ggx_albedo(alpha);
- return fresnel * (albedo*singlescatter + (1.0f - albedo)*multiscatter);
- }
- else {
- float singlescatter = fabsf(dot(r_wi, wh)*dot(wo, wh) * D * eta*eta / max((1.0f + lambda) * r_wi.z * wh_len*wh_len, 1e-7f));
- float albedo = mf_ggx_transmission_albedo(alpha, eta);
- return (1.0f - fresnel) * (albedo*singlescatter + (1.0f - albedo)*multiscatter);
- }
+ bool reflective = (wi.z * wo.z > 0.0f);
+
+ float wh_len;
+ float3 wh = normalize_len(wi + (reflective ? wo : (wo * eta)), &wh_len);
+ if (wh.z < 0.0f)
+ wh = -wh;
+ float3 r_wi = (wi.z < 0.0f) ? -wi : wi;
+ float lambda = mf_lambda(r_wi, make_float2(alpha, alpha));
+ float D = D_ggx(wh, alpha);
+ float fresnel = fresnel_dielectric_cos(dot(r_wi, wh), eta);
+
+ float multiscatter = fabsf(wo.z * M_1_PI_F);
+ if (reflective) {
+ float singlescatter = 0.25f * D / max((1.0f + lambda) * r_wi.z, 1e-7f);
+ float albedo = mf_ggx_albedo(alpha);
+ return fresnel * (albedo * singlescatter + (1.0f - albedo) * multiscatter);
+ }
+ else {
+ float singlescatter = fabsf(dot(r_wi, wh) * dot(wo, wh) * D * eta * eta /
+ max((1.0f + lambda) * r_wi.z * wh_len * wh_len, 1e-7f));
+ float albedo = mf_ggx_transmission_albedo(alpha, eta);
+ return (1.0f - fresnel) * (albedo * singlescatter + (1.0f - albedo) * multiscatter);
+ }
}
/* === Actual random walk implementations, one version of mf_eval and mf_sample per phase function. === */
-#define MF_NAME_JOIN(x,y) x ## _ ## y
-#define MF_NAME_EVAL(x,y) MF_NAME_JOIN(x,y)
+#define MF_NAME_JOIN(x, y) x##_##y
+#define MF_NAME_EVAL(x, y) MF_NAME_JOIN(x, y)
#define MF_FUNCTION_FULL_NAME(prefix) MF_NAME_EVAL(prefix, MF_PHASE_FUNCTION)
#define MF_PHASE_FUNCTION glass
@@ -326,10 +358,10 @@ ccl_device_forceinline float mf_glass_pdf(const float3 wi, const float3 wo, cons
ccl_device void bsdf_microfacet_multi_ggx_blur(ShaderClosure *sc, float roughness)
{
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)sc;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
- bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
- bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
+ bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
+ bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
/* === Closure implementations === */
@@ -338,293 +370,395 @@ ccl_device void bsdf_microfacet_multi_ggx_blur(ShaderClosure *sc, float roughnes
ccl_device int bsdf_microfacet_multi_ggx_common_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
- bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
- bsdf->extra->color.x = saturate(bsdf->extra->color.x);
- bsdf->extra->color.y = saturate(bsdf->extra->color.y);
- bsdf->extra->color.z = saturate(bsdf->extra->color.z);
- bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
- bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
- bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
+ bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
+ bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
+ bsdf->extra->color.x = saturate(bsdf->extra->color.x);
+ bsdf->extra->color.y = saturate(bsdf->extra->color.y);
+ bsdf->extra->color.z = saturate(bsdf->extra->color.z);
+ bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
+ bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
+ bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
ccl_device int bsdf_microfacet_multi_ggx_aniso_setup(MicrofacetBsdf *bsdf)
{
- if(is_zero(bsdf->T))
- bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
+ if (is_zero(bsdf->T))
+ bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
- bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
- return bsdf_microfacet_multi_ggx_common_setup(bsdf);
+ return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
-ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
+ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf,
+ const ShaderData *sd)
{
- if(is_zero(bsdf->T))
- bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
+ if (is_zero(bsdf->T))
+ bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
- bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
+ bsdf->sample_weight *= F;
- return bsdf_microfacet_multi_ggx_common_setup(bsdf);
+ return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
- return bsdf_microfacet_multi_ggx_common_setup(bsdf);
+ return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
{
- bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->alpha_y = bsdf->alpha_x;
- bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
+ bsdf->sample_weight *= F;
- return bsdf_microfacet_multi_ggx_common_setup(bsdf);
+ return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_y = bsdf->alpha_x;
-
- bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
+ bsdf->alpha_y = bsdf->alpha_x;
- return bsdf_microfacet_multi_ggx_common_setup(bsdf);
-}
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
-ccl_device float3 bsdf_microfacet_multi_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) {
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
-ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) {
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
-
- if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
-
- bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
- float3 X, Y, Z;
- Z = bsdf->N;
- if(is_aniso)
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- else
- make_orthonormals(Z, &X, &Y);
-
- float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
- float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
-
- if(is_aniso)
- *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
- else
- *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
- return mf_eval_glossy(localI, localO, true, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior, use_fresnel, bsdf->extra->cspec0);
+ccl_device float3 bsdf_microfacet_multi_ggx_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf,
+ ccl_addr_space uint *lcg_state)
+{
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, ccl_addr_space uint *lcg_state)
+ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf,
+ ccl_addr_space uint *lcg_state)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+
+ if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+
+ bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
+
+ bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
+ float3 X, Y, Z;
+ Z = bsdf->N;
+ if (is_aniso)
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ else
+ make_orthonormals(Z, &X, &Y);
+
+ float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
+ float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+
+ if (is_aniso)
+ *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
+ else
+ *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
+ return mf_eval_glossy(localI,
+ localO,
+ true,
+ bsdf->extra->color,
+ bsdf->alpha_x,
+ bsdf->alpha_y,
+ lcg_state,
+ bsdf->ior,
+ use_fresnel,
+ bsdf->extra->cspec0);
+}
+
+ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg,
+ const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf,
+ ccl_addr_space uint *lcg_state)
+{
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
- float3 X, Y, Z;
- Z = bsdf->N;
+ float3 X, Y, Z;
+ Z = bsdf->N;
- if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) {
- *omega_in = 2*dot(Z, I)*Z - I;
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
+ *omega_in = 2 * dot(Z, I) * Z - I;
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
- *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
+ *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
+ *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
#endif
- return LABEL_REFLECT|LABEL_SINGULAR;
- }
-
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
-
- bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
- if(is_aniso)
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- else
- make_orthonormals(Z, &X, &Y);
-
- float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
- float3 localO;
-
- *eval = mf_sample_glossy(localI, &localO, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior, use_fresnel, bsdf->extra->cspec0);
- if(is_aniso)
- *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
- else
- *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
- *eval *= *pdf;
-
- *omega_in = X*localO.x + Y*localO.y + Z*localO.z;
+ return LABEL_REFLECT | LABEL_SINGULAR;
+ }
+
+ bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
+
+ bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
+ if (is_aniso)
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ else
+ make_orthonormals(Z, &X, &Y);
+
+ float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
+ float3 localO;
+
+ *eval = mf_sample_glossy(localI,
+ &localO,
+ bsdf->extra->color,
+ bsdf->alpha_x,
+ bsdf->alpha_y,
+ lcg_state,
+ bsdf->ior,
+ use_fresnel,
+ bsdf->extra->cspec0);
+ if (is_aniso)
+ *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
+ else
+ *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
+ *eval *= *pdf;
+
+ *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
- *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
+ *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
+ *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
#endif
- return LABEL_REFLECT|LABEL_GLOSSY;
+ return LABEL_REFLECT | LABEL_GLOSSY;
}
/* Multiscattering GGX Glass closure */
ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf)
{
- bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
- bsdf->alpha_y = bsdf->alpha_x;
- bsdf->ior = max(0.0f, bsdf->ior);
- bsdf->extra->color.x = saturate(bsdf->extra->color.x);
- bsdf->extra->color.y = saturate(bsdf->extra->color.y);
- bsdf->extra->color.z = saturate(bsdf->extra->color.z);
+ bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->ior = max(0.0f, bsdf->ior);
+ bsdf->extra->color.x = saturate(bsdf->extra->color.x);
+ bsdf->extra->color.y = saturate(bsdf->extra->color.y);
+ bsdf->extra->color.z = saturate(bsdf->extra->color.z);
- bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
-ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
+ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(MicrofacetBsdf *bsdf,
+ const ShaderData *sd)
{
- bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
- bsdf->alpha_y = bsdf->alpha_x;
- bsdf->ior = max(0.0f, bsdf->ior);
- bsdf->extra->color.x = saturate(bsdf->extra->color.x);
- bsdf->extra->color.y = saturate(bsdf->extra->color.y);
- bsdf->extra->color.z = saturate(bsdf->extra->color.z);
- bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
- bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
- bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
-
- bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID;
-
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
-
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG;
-}
-
-ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) {
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
-
- if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-
- float3 X, Y, Z;
- Z = bsdf->N;
- make_orthonormals(Z, &X, &Y);
-
- float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
- float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
-
- *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
- return mf_eval_glass(localI, localO, false, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior, false, bsdf->extra->color);
-}
-
-ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) {
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
-
- if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
-
- float3 X, Y, Z;
- Z = bsdf->N;
- make_orthonormals(Z, &X, &Y);
-
- float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
- float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
-
- *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
- return mf_eval_glass(localI, localO, true, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior, use_fresnel, bsdf->extra->cspec0);
-}
-
-ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, ccl_addr_space uint *lcg_state)
+ bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
+ bsdf->ior = max(0.0f, bsdf->ior);
+ bsdf->extra->color.x = saturate(bsdf->extra->color.x);
+ bsdf->extra->color.y = saturate(bsdf->extra->color.y);
+ bsdf->extra->color.z = saturate(bsdf->extra->color.z);
+ bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
+ bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
+ bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
+
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID;
+
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
+ bsdf->sample_weight *= F;
+
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
+}
+
+ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf,
+ ccl_addr_space uint *lcg_state)
+{
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+
+ if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+
+ float3 X, Y, Z;
+ Z = bsdf->N;
+ make_orthonormals(Z, &X, &Y);
+
+ float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
+ float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+
+ *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
+ return mf_eval_glass(localI,
+ localO,
+ false,
+ bsdf->extra->color,
+ bsdf->alpha_x,
+ bsdf->alpha_y,
+ lcg_state,
+ bsdf->ior,
+ false,
+ bsdf->extra->color);
+}
+
+ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf,
+ ccl_addr_space uint *lcg_state)
+{
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+
+ if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+
+ bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
+
+ float3 X, Y, Z;
+ Z = bsdf->N;
+ make_orthonormals(Z, &X, &Y);
+
+ float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
+ float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+
+ *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
+ return mf_eval_glass(localI,
+ localO,
+ true,
+ bsdf->extra->color,
+ bsdf->alpha_x,
+ bsdf->alpha_y,
+ lcg_state,
+ bsdf->ior,
+ use_fresnel,
+ bsdf->extra->cspec0);
+}
+
+ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg,
+ const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf,
+ ccl_addr_space uint *lcg_state)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
- float3 X, Y, Z;
- Z = bsdf->N;
+ float3 X, Y, Z;
+ Z = bsdf->N;
- if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) {
- float3 R, T;
+ if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
+ float3 R, T;
#ifdef __RAY_DIFFERENTIALS__
- float3 dRdx, dRdy, dTdx, dTdy;
+ float3 dRdx, dRdy, dTdx, dTdy;
#endif
- bool inside;
- float fresnel = fresnel_dielectric(bsdf->ior, Z, I, &R, &T,
+ bool inside;
+ float fresnel = fresnel_dielectric(bsdf->ior,
+ Z,
+ I,
+ &R,
+ &T,
#ifdef __RAY_DIFFERENTIALS__
- dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx,
+ dIdy,
+ &dRdx,
+ &dRdy,
+ &dTdx,
+ &dTdy,
#endif
- &inside);
+ &inside);
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
- if(randu < fresnel) {
- *omega_in = R;
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ if (randu < fresnel) {
+ *omega_in = R;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = dRdx;
- *domega_in_dy = dRdy;
+ *domega_in_dx = dRdx;
+ *domega_in_dy = dRdy;
#endif
- return LABEL_REFLECT|LABEL_SINGULAR;
- }
- else {
- *omega_in = T;
+ return LABEL_REFLECT | LABEL_SINGULAR;
+ }
+ else {
+ *omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = dTdx;
- *domega_in_dy = dTdy;
+ *domega_in_dx = dTdx;
+ *domega_in_dy = dTdy;
#endif
- return LABEL_TRANSMIT|LABEL_SINGULAR;
- }
- }
-
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
-
- make_orthonormals(Z, &X, &Y);
-
- float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
- float3 localO;
-
- *eval = mf_sample_glass(localI, &localO, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior, use_fresnel, bsdf->extra->cspec0);
- *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
- *eval *= *pdf;
-
- *omega_in = X*localO.x + Y*localO.y + Z*localO.z;
- if(localO.z*localI.z > 0.0f) {
+ return LABEL_TRANSMIT | LABEL_SINGULAR;
+ }
+ }
+
+ bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
+
+ make_orthonormals(Z, &X, &Y);
+
+ float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
+ float3 localO;
+
+ *eval = mf_sample_glass(localI,
+ &localO,
+ bsdf->extra->color,
+ bsdf->alpha_x,
+ bsdf->alpha_y,
+ lcg_state,
+ bsdf->ior,
+ use_fresnel,
+ bsdf->extra->cspec0);
+ *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
+ *eval *= *pdf;
+
+ *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
+ if (localO.z * localI.z > 0.0f) {
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
- *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
+ *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
+ *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
#endif
- return LABEL_REFLECT|LABEL_GLOSSY;
- }
- else {
+ return LABEL_REFLECT | LABEL_GLOSSY;
+ }
+ else {
#ifdef __RAY_DIFFERENTIALS__
- float cosI = dot(Z, I);
- float dnp = max(sqrtf(1.0f - (bsdf->ior * bsdf->ior * (1.0f - cosI*cosI))), 1e-7f);
- *domega_in_dx = -(bsdf->ior * dIdx) + ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdx, Z)) * Z;
- *domega_in_dy = -(bsdf->ior * dIdy) + ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdy, Z)) * Z;
+ float cosI = dot(Z, I);
+ float dnp = max(sqrtf(1.0f - (bsdf->ior * bsdf->ior * (1.0f - cosI * cosI))), 1e-7f);
+ *domega_in_dx = -(bsdf->ior * dIdx) +
+ ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdx, Z)) * Z;
+ *domega_in_dy = -(bsdf->ior * dIdy) +
+ ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdy, Z)) * Z;
#endif
- return LABEL_TRANSMIT|LABEL_GLOSSY;
- }
+ return LABEL_TRANSMIT | LABEL_GLOSSY;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
index 5d300ef6db5..79247ee8057 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
@@ -25,247 +25,251 @@
* energy is used. In combination with MIS, that is enough to produce an unbiased result, although
* the balance heuristic isn't necessarily optimal anymore.
*/
-ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
- float3 wi,
- float3 wo,
- const bool wo_outside,
- const float3 color,
- const float alpha_x,
- const float alpha_y,
- ccl_addr_space uint *lcg_state,
- const float eta,
- bool use_fresnel,
- const float3 cspec0)
+ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
+ float3 wo,
+ const bool wo_outside,
+ const float3 color,
+ const float alpha_x,
+ const float alpha_y,
+ ccl_addr_space uint *lcg_state,
+ const float eta,
+ bool use_fresnel,
+ const float3 cspec0)
{
- /* Evaluating for a shallower incoming direction produces less noise, and the properties of the BSDF guarantee reciprocity. */
- bool swapped = false;
+ /* Evaluating for a shallower incoming direction produces less noise, and the properties of the BSDF guarantee reciprocity. */
+ bool swapped = false;
#ifdef MF_MULTI_GLASS
- if(wi.z*wo.z < 0.0f) {
- /* Glass transmission is a special case and requires the directions to change hemisphere. */
- if(-wo.z < wi.z) {
- swapped = true;
- float3 tmp = -wo;
- wo = -wi;
- wi = tmp;
- }
- }
- else
+ if (wi.z * wo.z < 0.0f) {
+ /* Glass transmission is a special case and requires the directions to change hemisphere. */
+ if (-wo.z < wi.z) {
+ swapped = true;
+ float3 tmp = -wo;
+ wo = -wi;
+ wi = tmp;
+ }
+ }
+ else
#endif
- if(wo.z < wi.z) {
- swapped = true;
- float3 tmp = wo;
- wo = wi;
- wi = tmp;
- }
+ if (wo.z < wi.z) {
+ swapped = true;
+ float3 tmp = wo;
+ wo = wi;
+ wi = tmp;
+ }
- if(wi.z < 1e-5f || (wo.z < 1e-5f && wo_outside) || (wo.z > -1e-5f && !wo_outside))
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (wi.z < 1e-5f || (wo.z < 1e-5f && wo_outside) || (wo.z > -1e-5f && !wo_outside))
+ return make_float3(0.0f, 0.0f, 0.0f);
- const float2 alpha = make_float2(alpha_x, alpha_y);
+ const float2 alpha = make_float2(alpha_x, alpha_y);
- float lambda_r = mf_lambda(-wi, alpha);
- float shadowing_lambda = mf_lambda(wo_outside? wo: -wo, alpha);
+ float lambda_r = mf_lambda(-wi, alpha);
+ float shadowing_lambda = mf_lambda(wo_outside ? wo : -wo, alpha);
- /* Analytically compute single scattering for lower noise. */
- float3 eval;
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- const float3 wh = normalize(wi+wo);
+ /* Analytically compute single scattering for lower noise. */
+ float3 eval;
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ const float3 wh = normalize(wi + wo);
#ifdef MF_MULTI_GLASS
- eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta);
- if(wo_outside)
- eval *= -lambda_r / (shadowing_lambda - lambda_r);
- else
- eval *= -lambda_r * beta(-lambda_r, shadowing_lambda+1.0f);
-#else /* MF_MULTI_GLOSSY */
- const float G2 = 1.0f / (1.0f - (lambda_r + 1.0f) + shadowing_lambda);
- float val = G2 * 0.25f / wi.z;
- if(alpha.x == alpha.y)
- val *= D_ggx(wh, alpha.x);
- else
- val *= D_ggx_aniso(wh, alpha);
- eval = make_float3(val, val, val);
+ eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta);
+ if (wo_outside)
+ eval *= -lambda_r / (shadowing_lambda - lambda_r);
+ else
+ eval *= -lambda_r * beta(-lambda_r, shadowing_lambda + 1.0f);
+#else /* MF_MULTI_GLOSSY */
+ const float G2 = 1.0f / (1.0f - (lambda_r + 1.0f) + shadowing_lambda);
+ float val = G2 * 0.25f / wi.z;
+ if (alpha.x == alpha.y)
+ val *= D_ggx(wh, alpha.x);
+ else
+ val *= D_ggx_aniso(wh, alpha);
+ eval = make_float3(val, val, val);
#endif
- float F0 = fresnel_dielectric_cos(1.0f, eta);
- if(use_fresnel) {
- throughput = interpolate_fresnel_color(wi, wh, eta, F0, cspec0);
+ float F0 = fresnel_dielectric_cos(1.0f, eta);
+ if (use_fresnel) {
+ throughput = interpolate_fresnel_color(wi, wh, eta, F0, cspec0);
- eval *= throughput;
- }
+ eval *= throughput;
+ }
- float3 wr = -wi;
- float hr = 1.0f;
- float C1_r = 1.0f;
- float G1_r = 0.0f;
- bool outside = true;
+ float3 wr = -wi;
+ float hr = 1.0f;
+ float C1_r = 1.0f;
+ float G1_r = 0.0f;
+ bool outside = true;
- for(int order = 0; order < 10; order++) {
- /* Sample microfacet height. */
- float height_rand = lcg_step_float_addrspace(lcg_state);
- if(!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand))
- break;
- /* Sample microfacet normal. */
- float vndf_rand_y = lcg_step_float_addrspace(lcg_state);
- float vndf_rand_x = lcg_step_float_addrspace(lcg_state);
- float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y);
+ for (int order = 0; order < 10; order++) {
+ /* Sample microfacet height. */
+ float height_rand = lcg_step_float_addrspace(lcg_state);
+ if (!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand))
+ break;
+ /* Sample microfacet normal. */
+ float vndf_rand_y = lcg_step_float_addrspace(lcg_state);
+ float vndf_rand_x = lcg_step_float_addrspace(lcg_state);
+ float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y);
#ifdef MF_MULTI_GLASS
- if(order == 0 && use_fresnel) {
- /* Evaluate amount of scattering towards wo on this microfacet. */
- float3 phase;
- if(outside)
- phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
- else
- phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta);
+ if (order == 0 && use_fresnel) {
+ /* Evaluate amount of scattering towards wo on this microfacet. */
+ float3 phase;
+ if (outside)
+ phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
+ else
+ phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta);
- eval = throughput * phase * mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
- }
+ eval = throughput * phase *
+ mf_G1(wo_outside ? wo : -wo,
+ mf_C1((outside == wo_outside) ? hr : -hr),
+ shadowing_lambda);
+ }
#endif
- if(order > 0) {
- /* Evaluate amount of scattering towards wo on this microfacet. */
- float3 phase;
+ if (order > 0) {
+ /* Evaluate amount of scattering towards wo on this microfacet. */
+ float3 phase;
#ifdef MF_MULTI_GLASS
- if(outside)
- phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
- else
- phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f/eta);
-#else /* MF_MULTI_GLOSSY */
- phase = mf_eval_phase_glossy(wr, lambda_r, wo, alpha) * throughput;
+ if (outside)
+ phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
+ else
+ phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta);
+#else /* MF_MULTI_GLOSSY */
+ phase = mf_eval_phase_glossy(wr, lambda_r, wo, alpha) * throughput;
#endif
- eval += throughput * phase * mf_G1(wo_outside? wo: -wo, mf_C1((outside == wo_outside)? hr: -hr), shadowing_lambda);
- }
- if(order+1 < 10) {
- /* Bounce from the microfacet. */
+ eval += throughput * phase *
+ mf_G1(wo_outside ? wo : -wo,
+ mf_C1((outside == wo_outside) ? hr : -hr),
+ shadowing_lambda);
+ }
+ if (order + 1 < 10) {
+ /* Bounce from the microfacet. */
#ifdef MF_MULTI_GLASS
- bool next_outside;
- float3 wi_prev = -wr;
- float phase_rand = lcg_step_float_addrspace(lcg_state);
- wr = mf_sample_phase_glass(-wr, outside? eta: 1.0f/eta, wm, phase_rand, &next_outside);
- if(!next_outside) {
- outside = !outside;
- wr = -wr;
- hr = -hr;
- }
+ bool next_outside;
+ float3 wi_prev = -wr;
+ float phase_rand = lcg_step_float_addrspace(lcg_state);
+ wr = mf_sample_phase_glass(-wr, outside ? eta : 1.0f / eta, wm, phase_rand, &next_outside);
+ if (!next_outside) {
+ outside = !outside;
+ wr = -wr;
+ hr = -hr;
+ }
- if(use_fresnel && !next_outside) {
- throughput *= color;
- }
- else if(use_fresnel && order > 0) {
- throughput *= interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
- }
-#else /* MF_MULTI_GLOSSY */
- if(use_fresnel && order > 0) {
- throughput *= interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
- }
- wr = mf_sample_phase_glossy(-wr, &throughput, wm);
+ if (use_fresnel && !next_outside) {
+ throughput *= color;
+ }
+ else if (use_fresnel && order > 0) {
+ throughput *= interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
+ }
+#else /* MF_MULTI_GLOSSY */
+ if (use_fresnel && order > 0) {
+ throughput *= interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
+ }
+ wr = mf_sample_phase_glossy(-wr, &throughput, wm);
#endif
- lambda_r = mf_lambda(wr, alpha);
+ lambda_r = mf_lambda(wr, alpha);
- if(!use_fresnel)
- throughput *= color;
+ if (!use_fresnel)
+ throughput *= color;
- C1_r = mf_C1(hr);
- G1_r = mf_G1(wr, C1_r, lambda_r);
- }
- }
+ C1_r = mf_C1(hr);
+ G1_r = mf_G1(wr, C1_r, lambda_r);
+ }
+ }
- if(swapped)
- eval *= fabsf(wi.z / wo.z);
- return eval;
+ if (swapped)
+ eval *= fabsf(wi.z / wo.z);
+ return eval;
}
/* Perform a random walk on the microsurface starting from wi, returning the direction in which the walk
* escaped the surface in wo. The function returns the throughput between wi and wo.
* Without reflection losses due to coloring or fresnel absorption in conductors, the sampling is optimal.
*/
-ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(
- float3 wi,
- float3 *wo,
- const float3 color,
- const float alpha_x,
- const float alpha_y,
- ccl_addr_space uint *lcg_state,
- const float eta,
- bool use_fresnel,
- const float3 cspec0)
+ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
+ float3 *wo,
+ const float3 color,
+ const float alpha_x,
+ const float alpha_y,
+ ccl_addr_space uint *lcg_state,
+ const float eta,
+ bool use_fresnel,
+ const float3 cspec0)
{
- const float2 alpha = make_float2(alpha_x, alpha_y);
+ const float2 alpha = make_float2(alpha_x, alpha_y);
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- float3 wr = -wi;
- float lambda_r = mf_lambda(wr, alpha);
- float hr = 1.0f;
- float C1_r = 1.0f;
- float G1_r = 0.0f;
- bool outside = true;
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ float3 wr = -wi;
+ float lambda_r = mf_lambda(wr, alpha);
+ float hr = 1.0f;
+ float C1_r = 1.0f;
+ float G1_r = 0.0f;
+ bool outside = true;
- float F0 = fresnel_dielectric_cos(1.0f, eta);
- if(use_fresnel) {
- throughput = interpolate_fresnel_color(wi, normalize(wi + wr), eta, F0, cspec0);
- }
+ float F0 = fresnel_dielectric_cos(1.0f, eta);
+ if (use_fresnel) {
+ throughput = interpolate_fresnel_color(wi, normalize(wi + wr), eta, F0, cspec0);
+ }
- int order;
- for(order = 0; order < 10; order++) {
- /* Sample microfacet height. */
- float height_rand = lcg_step_float_addrspace(lcg_state);
- if(!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand)) {
- /* The random walk has left the surface. */
- *wo = outside? wr: -wr;
- return throughput;
- }
- /* Sample microfacet normal. */
- float vndf_rand_y = lcg_step_float_addrspace(lcg_state);
- float vndf_rand_x = lcg_step_float_addrspace(lcg_state);
- float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y);
+ int order;
+ for (order = 0; order < 10; order++) {
+ /* Sample microfacet height. */
+ float height_rand = lcg_step_float_addrspace(lcg_state);
+ if (!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand)) {
+ /* The random walk has left the surface. */
+ *wo = outside ? wr : -wr;
+ return throughput;
+ }
+ /* Sample microfacet normal. */
+ float vndf_rand_y = lcg_step_float_addrspace(lcg_state);
+ float vndf_rand_x = lcg_step_float_addrspace(lcg_state);
+ float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y);
- /* First-bounce color is already accounted for in mix weight. */
- if(!use_fresnel && order > 0)
- throughput *= color;
+ /* First-bounce color is already accounted for in mix weight. */
+ if (!use_fresnel && order > 0)
+ throughput *= color;
- /* Bounce from the microfacet. */
+ /* Bounce from the microfacet. */
#ifdef MF_MULTI_GLASS
- bool next_outside;
- float3 wi_prev = -wr;
- float phase_rand = lcg_step_float_addrspace(lcg_state);
- wr = mf_sample_phase_glass(-wr, outside? eta: 1.0f/eta, wm, phase_rand, &next_outside);
- if(!next_outside) {
- hr = -hr;
- wr = -wr;
- outside = !outside;
- }
+ bool next_outside;
+ float3 wi_prev = -wr;
+ float phase_rand = lcg_step_float_addrspace(lcg_state);
+ wr = mf_sample_phase_glass(-wr, outside ? eta : 1.0f / eta, wm, phase_rand, &next_outside);
+ if (!next_outside) {
+ hr = -hr;
+ wr = -wr;
+ outside = !outside;
+ }
- if(use_fresnel) {
- if(!next_outside) {
- throughput *= color;
- }
- else {
- float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
+ if (use_fresnel) {
+ if (!next_outside) {
+ throughput *= color;
+ }
+ else {
+ float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
- if(order == 0)
- throughput = t_color;
- else
- throughput *= t_color;
- }
- }
-#else /* MF_MULTI_GLOSSY */
- if(use_fresnel) {
- float3 t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
+ if (order == 0)
+ throughput = t_color;
+ else
+ throughput *= t_color;
+ }
+ }
+#else /* MF_MULTI_GLOSSY */
+ if (use_fresnel) {
+ float3 t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
- if(order == 0)
- throughput = t_color;
- else
- throughput *= t_color;
- }
- wr = mf_sample_phase_glossy(-wr, &throughput, wm);
+ if (order == 0)
+ throughput = t_color;
+ else
+ throughput *= t_color;
+ }
+ wr = mf_sample_phase_glossy(-wr, &throughput, wm);
#endif
- /* Update random walk parameters. */
- lambda_r = mf_lambda(wr, alpha);
- G1_r = mf_G1(wr, C1_r, lambda_r);
- }
- *wo = make_float3(0.0f, 0.0f, 1.0f);
- return make_float3(0.0f, 0.0f, 0.0f);
+ /* Update random walk parameters. */
+ lambda_r = mf_lambda(wr, alpha);
+ G1_r = mf_G1(wr, C1_r, lambda_r);
+ }
+ *wo = make_float3(0.0f, 0.0f, 1.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
#undef MF_MULTI_GLASS
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index 3446d1609d9..104ed5b2818 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -20,92 +20,110 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct OrenNayarBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float roughness;
- float a;
- float b;
+ float roughness;
+ float a;
+ float b;
} OrenNayarBsdf;
-ccl_device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, float3 v, float3 l)
+ccl_device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc,
+ float3 n,
+ float3 v,
+ float3 l)
{
- const OrenNayarBsdf *bsdf = (const OrenNayarBsdf*)sc;
- float nl = max(dot(n, l), 0.0f);
- float nv = max(dot(n, v), 0.0f);
- float t = dot(l, v) - nl * nv;
-
- if(t > 0.0f)
- t /= max(nl, nv) + FLT_MIN;
- float is = nl * (bsdf->a + bsdf->b * t);
- return make_float3(is, is, is);
+ const OrenNayarBsdf *bsdf = (const OrenNayarBsdf *)sc;
+ float nl = max(dot(n, l), 0.0f);
+ float nv = max(dot(n, v), 0.0f);
+ float t = dot(l, v) - nl * nv;
+
+ if (t > 0.0f)
+ t /= max(nl, nv) + FLT_MIN;
+ float is = nl * (bsdf->a + bsdf->b * t);
+ return make_float3(is, is, is);
}
ccl_device int bsdf_oren_nayar_setup(OrenNayarBsdf *bsdf)
{
- float sigma = bsdf->roughness;
+ float sigma = bsdf->roughness;
- bsdf->type = CLOSURE_BSDF_OREN_NAYAR_ID;
+ bsdf->type = CLOSURE_BSDF_OREN_NAYAR_ID;
- sigma = saturate(sigma);
+ sigma = saturate(sigma);
- float div = 1.0f / (M_PI_F + ((3.0f * M_PI_F - 4.0f) / 6.0f) * sigma);
+ float div = 1.0f / (M_PI_F + ((3.0f * M_PI_F - 4.0f) / 6.0f) * sigma);
- bsdf->a = 1.0f * div;
- bsdf->b = sigma * div;
+ bsdf->a = 1.0f * div;
+ bsdf->b = sigma * div;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device bool bsdf_oren_nayar_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const OrenNayarBsdf *bsdf_a = (const OrenNayarBsdf*)a;
- const OrenNayarBsdf *bsdf_b = (const OrenNayarBsdf*)b;
+ const OrenNayarBsdf *bsdf_a = (const OrenNayarBsdf *)a;
+ const OrenNayarBsdf *bsdf_b = (const OrenNayarBsdf *)b;
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) &&
- (bsdf_a->roughness == bsdf_b->roughness);
+ return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->roughness == bsdf_b->roughness);
}
-ccl_device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const OrenNayarBsdf *bsdf = (const OrenNayarBsdf*)sc;
- if(dot(bsdf->N, omega_in) > 0.0f) {
- *pdf = 0.5f * M_1_PI_F;
- return bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, omega_in);
- }
- else {
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ const OrenNayarBsdf *bsdf = (const OrenNayarBsdf *)sc;
+ if (dot(bsdf->N, omega_in) > 0.0f) {
+ *pdf = 0.5f * M_1_PI_F;
+ return bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, omega_in);
+ }
+ else {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
-ccl_device float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const OrenNayarBsdf *bsdf = (const OrenNayarBsdf*)sc;
- sample_uniform_hemisphere(bsdf->N, randu, randv, omega_in, pdf);
+ const OrenNayarBsdf *bsdf = (const OrenNayarBsdf *)sc;
+ sample_uniform_hemisphere(bsdf->N, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0.0f) {
- *eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, *omega_in);
+ if (dot(Ng, *omega_in) > 0.0f) {
+ *eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, *omega_in);
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the bounce
- *domega_in_dx = (2.0f * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
- *domega_in_dy = (2.0f * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
+ // TODO: find a better approximation for the bounce
+ *domega_in_dx = (2.0f * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
+ *domega_in_dy = (2.0f * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
#endif
- }
- else {
- *pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
- }
+ }
+ else {
+ *pdf = 0.0f;
+ *eval = make_float3(0.0f, 0.0f, 0.0f);
+ }
- return LABEL_REFLECT|LABEL_DIFFUSE;
+ return LABEL_REFLECT | LABEL_DIFFUSE;
}
-
CCL_NAMESPACE_END
-#endif /* __BSDF_OREN_NAYAR_H__ */
+#endif /* __BSDF_OREN_NAYAR_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index 83da05ac435..b6fd0e68681 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -38,105 +38,118 @@ CCL_NAMESPACE_BEGIN
#ifdef __OSL__
typedef ccl_addr_space struct PhongRampBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float exponent;
- float3 *colors;
+ float exponent;
+ float3 *colors;
} PhongRampBsdf;
ccl_device float3 bsdf_phong_ramp_get_color(const float3 colors[8], float pos)
{
- int MAXCOLORS = 8;
-
- float npos = pos * (float)(MAXCOLORS - 1);
- int ipos = float_to_int(npos);
- if(ipos < 0)
- return colors[0];
- if(ipos >= (MAXCOLORS - 1))
- return colors[MAXCOLORS - 1];
- float offset = npos - (float)ipos;
- return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
+ int MAXCOLORS = 8;
+
+ float npos = pos * (float)(MAXCOLORS - 1);
+ int ipos = float_to_int(npos);
+ if (ipos < 0)
+ return colors[0];
+ if (ipos >= (MAXCOLORS - 1))
+ return colors[MAXCOLORS - 1];
+ float offset = npos - (float)ipos;
+ return colors[ipos] * (1.0f - offset) + colors[ipos + 1] * offset;
}
ccl_device int bsdf_phong_ramp_setup(PhongRampBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_PHONG_RAMP_ID;
- bsdf->exponent = max(bsdf->exponent, 0.0f);
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_PHONG_RAMP_ID;
+ bsdf->exponent = max(bsdf->exponent, 0.0f);
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_phong_ramp_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_phong_ramp_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const PhongRampBsdf *bsdf = (const PhongRampBsdf*)sc;
- float m_exponent = bsdf->exponent;
- float cosNI = dot(bsdf->N, omega_in);
- float cosNO = dot(bsdf->N, I);
-
- if(cosNI > 0 && cosNO > 0) {
- // reflect the view vector
- float3 R = (2 * cosNO) * bsdf->N - I;
- float cosRI = dot(R, omega_in);
- if(cosRI > 0) {
- float cosp = powf(cosRI, m_exponent);
- float common = 0.5f * M_1_PI_F * cosp;
- float out = cosNI * (m_exponent + 2) * common;
- *pdf = (m_exponent + 1) * common;
- return bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
- }
- }
-
- return make_float3(0.0f, 0.0f, 0.0f);
+ const PhongRampBsdf *bsdf = (const PhongRampBsdf *)sc;
+ float m_exponent = bsdf->exponent;
+ float cosNI = dot(bsdf->N, omega_in);
+ float cosNO = dot(bsdf->N, I);
+
+ if (cosNI > 0 && cosNO > 0) {
+ // reflect the view vector
+ float3 R = (2 * cosNO) * bsdf->N - I;
+ float cosRI = dot(R, omega_in);
+ if (cosRI > 0) {
+ float cosp = powf(cosRI, m_exponent);
+ float common = 0.5f * M_1_PI_F * cosp;
+ float out = cosNI * (m_exponent + 2) * common;
+ *pdf = (m_exponent + 1) * common;
+ return bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
+ }
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_phong_ramp_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_phong_ramp_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const PhongRampBsdf *bsdf = (const PhongRampBsdf*)sc;
- float cosNO = dot(bsdf->N, I);
- float m_exponent = bsdf->exponent;
-
- if(cosNO > 0) {
- // reflect the view vector
- float3 R = (2 * cosNO) * bsdf->N - I;
-
-#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
- *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
-#endif
-
- float3 T, B;
- make_orthonormals (R, &T, &B);
- float phi = M_2PI_F * randu;
- float cosTheta = powf(randv, 1 / (m_exponent + 1));
- float sinTheta2 = 1 - cosTheta * cosTheta;
- float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
- *omega_in = (cosf(phi) * sinTheta) * T +
- (sinf(phi) * sinTheta) * B +
- ( cosTheta) * R;
- if(dot(Ng, *omega_in) > 0.0f)
- {
- // common terms for pdf and eval
- float cosNI = dot(bsdf->N, *omega_in);
- // make sure the direction we chose is still in the right hemisphere
- if(cosNI > 0)
- {
- float cosp = powf(cosTheta, m_exponent);
- float common = 0.5f * M_1_PI_F * cosp;
- *pdf = (m_exponent + 1) * common;
- float out = cosNI * (m_exponent + 2) * common;
- *eval = bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
- }
- }
- }
- return LABEL_REFLECT|LABEL_GLOSSY;
+ const PhongRampBsdf *bsdf = (const PhongRampBsdf *)sc;
+ float cosNO = dot(bsdf->N, I);
+ float m_exponent = bsdf->exponent;
+
+ if (cosNO > 0) {
+ // reflect the view vector
+ float3 R = (2 * cosNO) * bsdf->N - I;
+
+# ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
+ *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
+# endif
+
+ float3 T, B;
+ make_orthonormals(R, &T, &B);
+ float phi = M_2PI_F * randu;
+ float cosTheta = powf(randv, 1 / (m_exponent + 1));
+ float sinTheta2 = 1 - cosTheta * cosTheta;
+ float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
+ *omega_in = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + (cosTheta)*R;
+ if (dot(Ng, *omega_in) > 0.0f) {
+ // common terms for pdf and eval
+ float cosNI = dot(bsdf->N, *omega_in);
+ // make sure the direction we chose is still in the right hemisphere
+ if (cosNI > 0) {
+ float cosp = powf(cosTheta, m_exponent);
+ float common = 0.5f * M_1_PI_F * cosp;
+ *pdf = (m_exponent + 1) * common;
+ float out = cosNI * (m_exponent + 2) * common;
+ *eval = bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
+ }
+ }
+ }
+ return LABEL_REFLECT | LABEL_GLOSSY;
}
-#endif /* __OSL__ */
+#endif /* __OSL__ */
CCL_NAMESPACE_END
-#endif /* __BSDF_PHONG_RAMP_H__ */
+#endif /* __BSDF_PHONG_RAMP_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
index 2f65fd54be2..d7795974ef5 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
@@ -25,101 +25,113 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct PrincipledDiffuseBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float roughness;
+ float roughness;
} PrincipledDiffuseBsdf;
-ccl_device float3 calculate_principled_diffuse_brdf(const PrincipledDiffuseBsdf *bsdf,
- float3 N, float3 V, float3 L, float3 H, float *pdf)
+ccl_device float3 calculate_principled_diffuse_brdf(
+ const PrincipledDiffuseBsdf *bsdf, float3 N, float3 V, float3 L, float3 H, float *pdf)
{
- float NdotL = max(dot(N, L), 0.0f);
- float NdotV = max(dot(N, V), 0.0f);
+ float NdotL = max(dot(N, L), 0.0f);
+ float NdotV = max(dot(N, V), 0.0f);
- if(NdotL < 0 || NdotV < 0) {
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (NdotL < 0 || NdotV < 0) {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
- float LdotH = dot(L, H);
+ float LdotH = dot(L, H);
- float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
- const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * bsdf->roughness;
- float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV);
+ float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
+ const float Fd90 = 0.5f + 2.0f * LdotH * LdotH * bsdf->roughness;
+ float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV);
- float value = M_1_PI_F * NdotL * Fd;
+ float value = M_1_PI_F * NdotL * Fd;
- return make_float3(value, value, value);
+ return make_float3(value, value, value);
}
ccl_device int bsdf_principled_diffuse_setup(PrincipledDiffuseBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device bool bsdf_principled_diffuse_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const PrincipledDiffuseBsdf *bsdf_a = (const PrincipledDiffuseBsdf*)a;
- const PrincipledDiffuseBsdf *bsdf_b = (const PrincipledDiffuseBsdf*)b;
+ const PrincipledDiffuseBsdf *bsdf_a = (const PrincipledDiffuseBsdf *)a;
+ const PrincipledDiffuseBsdf *bsdf_b = (const PrincipledDiffuseBsdf *)b;
- return (isequal_float3(bsdf_a->N, bsdf_b->N) && bsdf_a->roughness == bsdf_b->roughness);
+ return (isequal_float3(bsdf_a->N, bsdf_b->N) && bsdf_a->roughness == bsdf_b->roughness);
}
-ccl_device float3 bsdf_principled_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I,
- const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_principled_diffuse_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const PrincipledDiffuseBsdf *bsdf = (const PrincipledDiffuseBsdf *)sc;
-
- float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
- float3 H = normalize(L + V);
-
- if(dot(N, omega_in) > 0.0f) {
- *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
- return calculate_principled_diffuse_brdf(bsdf, N, V, L, H, pdf);
- }
- else {
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ const PrincipledDiffuseBsdf *bsdf = (const PrincipledDiffuseBsdf *)sc;
+
+ float3 N = bsdf->N;
+ float3 V = I; // outgoing
+ float3 L = omega_in; // incoming
+ float3 H = normalize(L + V);
+
+ if (dot(N, omega_in) > 0.0f) {
+ *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
+ return calculate_principled_diffuse_brdf(bsdf, N, V, L, H, pdf);
+ }
+ else {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
-ccl_device float3 bsdf_principled_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I,
- const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_principled_diffuse_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
ccl_device int bsdf_principled_diffuse_sample(const ShaderClosure *sc,
- float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
- float3 *eval, float3 *omega_in, float3 *domega_in_dx,
- float3 *domega_in_dy, float *pdf)
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const PrincipledDiffuseBsdf *bsdf = (const PrincipledDiffuseBsdf *)sc;
+ const PrincipledDiffuseBsdf *bsdf = (const PrincipledDiffuseBsdf *)sc;
- float3 N = bsdf->N;
+ float3 N = bsdf->N;
- sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0) {
- float3 H = normalize(I + *omega_in);
+ if (dot(Ng, *omega_in) > 0) {
+ float3 H = normalize(I + *omega_in);
- *eval = calculate_principled_diffuse_brdf(bsdf, N, I, *omega_in, H, pdf);
+ *eval = calculate_principled_diffuse_brdf(bsdf, N, I, *omega_in, H, pdf);
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
- *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+ // TODO: find a better approximation for the diffuse bounce
+ *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+ *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
#endif
- }
- else {
- *pdf = 0.0f;
- }
- return LABEL_REFLECT|LABEL_DIFFUSE;
+ }
+ else {
+ *pdf = 0.0f;
+ }
+ return LABEL_REFLECT | LABEL_DIFFUSE;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_PRINCIPLED_DIFFUSE_H__ */
+#endif /* __BSDF_PRINCIPLED_DIFFUSE_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_principled_sheen.h b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
index ccdcb1babd2..bc522095b3b 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_sheen.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
@@ -25,87 +25,99 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct PrincipledSheenBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
} PrincipledSheenBsdf;
-ccl_device float3 calculate_principled_sheen_brdf(const PrincipledSheenBsdf *bsdf,
- float3 N, float3 V, float3 L, float3 H, float *pdf)
+ccl_device float3 calculate_principled_sheen_brdf(
+ const PrincipledSheenBsdf *bsdf, float3 N, float3 V, float3 L, float3 H, float *pdf)
{
- float NdotL = dot(N, L);
- float NdotV = dot(N, V);
+ float NdotL = dot(N, L);
+ float NdotV = dot(N, V);
- if(NdotL < 0 || NdotV < 0) {
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (NdotL < 0 || NdotV < 0) {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
- float LdotH = dot(L, H);
+ float LdotH = dot(L, H);
- float value = schlick_fresnel(LdotH) * NdotL;
+ float value = schlick_fresnel(LdotH) * NdotL;
- return make_float3(value, value, value);
+ return make_float3(value, value, value);
}
ccl_device int bsdf_principled_sheen_setup(PrincipledSheenBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_PRINCIPLED_SHEEN_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ bsdf->type = CLOSURE_BSDF_PRINCIPLED_SHEEN_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_principled_sheen_eval_reflect(const ShaderClosure *sc, const float3 I,
- const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_principled_sheen_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
-
- float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
- float3 H = normalize(L + V);
-
- if(dot(N, omega_in) > 0.0f) {
- *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
- return calculate_principled_sheen_brdf(bsdf, N, V, L, H, pdf);
- }
- else {
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
+
+ float3 N = bsdf->N;
+ float3 V = I; // outgoing
+ float3 L = omega_in; // incoming
+ float3 H = normalize(L + V);
+
+ if (dot(N, omega_in) > 0.0f) {
+ *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
+ return calculate_principled_sheen_brdf(bsdf, N, V, L, H, pdf);
+ }
+ else {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
-ccl_device float3 bsdf_principled_sheen_eval_transmit(const ShaderClosure *sc, const float3 I,
- const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_principled_sheen_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
ccl_device int bsdf_principled_sheen_sample(const ShaderClosure *sc,
- float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
- float3 *eval, float3 *omega_in, float3 *domega_in_dx,
- float3 *domega_in_dy, float *pdf)
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
+ const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
- float3 N = bsdf->N;
+ float3 N = bsdf->N;
- sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0) {
- float3 H = normalize(I + *omega_in);
+ if (dot(Ng, *omega_in) > 0) {
+ float3 H = normalize(I + *omega_in);
- *eval = calculate_principled_sheen_brdf(bsdf, N, I, *omega_in, H, pdf);
+ *eval = calculate_principled_sheen_brdf(bsdf, N, I, *omega_in, H, pdf);
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
- *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+ // TODO: find a better approximation for the diffuse bounce
+ *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+ *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
#endif
- }
- else {
- *pdf = 0.0f;
- }
- return LABEL_REFLECT|LABEL_DIFFUSE;
+ }
+ else {
+ *pdf = 0.0f;
+ }
+ return LABEL_REFLECT | LABEL_DIFFUSE;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_PRINCIPLED_SHEEN_H__ */
+#endif /* __BSDF_PRINCIPLED_SHEEN_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index 94f1c283af7..c24ba170915 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -39,42 +39,59 @@ CCL_NAMESPACE_BEGIN
ccl_device int bsdf_reflection_setup(MicrofacetBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_REFLECTION_ID;
- return SD_BSDF;
+ bsdf->type = CLOSURE_BSDF_REFLECTION_ID;
+ return SD_BSDF;
}
-ccl_device float3 bsdf_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_reflection_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_reflection_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float3 N = bsdf->N;
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float3 N = bsdf->N;
- // only one direction is possible
- float cosNO = dot(N, I);
- if(cosNO > 0) {
- *omega_in = (2 * cosNO) * N - I;
- if(dot(Ng, *omega_in) > 0) {
+ // only one direction is possible
+ float cosNO = dot(N, I);
+ if (cosNO > 0) {
+ *omega_in = (2 * cosNO) * N - I;
+ if (dot(Ng, *omega_in) > 0) {
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx;
- *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy;
+ *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx;
+ *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy;
#endif
- /* Some high number for MIS. */
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
- }
- }
- return LABEL_REFLECT|LABEL_SINGULAR;
+ /* Some high number for MIS. */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ }
+ }
+ return LABEL_REFLECT | LABEL_SINGULAR;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_REFLECTION_H__ */
+#endif /* __BSDF_REFLECTION_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h
index abdd01c7a1d..d4fbe86dac0 100644
--- a/intern/cycles/kernel/closure/bsdf_refraction.h
+++ b/intern/cycles/kernel/closure/bsdf_refraction.h
@@ -39,51 +39,77 @@ CCL_NAMESPACE_BEGIN
ccl_device int bsdf_refraction_setup(MicrofacetBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_REFRACTION_ID;
- return SD_BSDF;
+ bsdf->type = CLOSURE_BSDF_REFRACTION_ID;
+ return SD_BSDF;
}
-ccl_device float3 bsdf_refraction_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_refraction_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_refraction_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_refraction_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_refraction_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_refraction_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
- float m_eta = bsdf->ior;
- float3 N = bsdf->N;
+ const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
+ float m_eta = bsdf->ior;
+ float3 N = bsdf->N;
- float3 R, T;
+ float3 R, T;
#ifdef __RAY_DIFFERENTIALS__
- float3 dRdx, dRdy, dTdx, dTdy;
+ float3 dRdx, dRdy, dTdx, dTdy;
#endif
- bool inside;
- float fresnel;
- fresnel = fresnel_dielectric(m_eta, N, I, &R, &T,
+ bool inside;
+ float fresnel;
+ fresnel = fresnel_dielectric(m_eta,
+ N,
+ I,
+ &R,
+ &T,
#ifdef __RAY_DIFFERENTIALS__
- dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx,
+ dIdy,
+ &dRdx,
+ &dRdy,
+ &dTdx,
+ &dTdy,
#endif
- &inside);
+ &inside);
- if(!inside && fresnel != 1.0f) {
- /* Some high number for MIS. */
- *pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
- *omega_in = T;
+ if (!inside && fresnel != 1.0f) {
+ /* Some high number for MIS. */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = dTdx;
- *domega_in_dy = dTdy;
+ *domega_in_dx = dTdx;
+ *domega_in_dy = dTdy;
#endif
- }
- return LABEL_TRANSMIT|LABEL_SINGULAR;
+ }
+ return LABEL_TRANSMIT | LABEL_SINGULAR;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_REFRACTION_H__ */
+#endif /* __BSDF_REFRACTION_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
index 097a56f22eb..f37fd228087 100644
--- a/intern/cycles/kernel/closure/bsdf_toon.h
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -36,183 +36,215 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct ToonBsdf {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float size;
- float smooth;
+ float size;
+ float smooth;
} ToonBsdf;
/* DIFFUSE TOON */
ccl_device int bsdf_diffuse_toon_setup(ToonBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_DIFFUSE_TOON_ID;
- bsdf->size = saturate(bsdf->size);
- bsdf->smooth = saturate(bsdf->smooth);
+ bsdf->type = CLOSURE_BSDF_DIFFUSE_TOON_ID;
+ bsdf->size = saturate(bsdf->size);
+ bsdf->smooth = saturate(bsdf->smooth);
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device bool bsdf_toon_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const ToonBsdf *bsdf_a = (const ToonBsdf*)a;
- const ToonBsdf *bsdf_b = (const ToonBsdf*)b;
+ const ToonBsdf *bsdf_a = (const ToonBsdf *)a;
+ const ToonBsdf *bsdf_b = (const ToonBsdf *)b;
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) &&
- (bsdf_a->size == bsdf_b->size) &&
- (bsdf_a->smooth == bsdf_b->smooth);
+ return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->size == bsdf_b->size) &&
+ (bsdf_a->smooth == bsdf_b->smooth);
}
ccl_device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
{
- float is;
+ float is;
- if(angle < max_angle)
- is = 1.0f;
- else if(angle < (max_angle + smooth) && smooth != 0.0f)
- is = (1.0f - (angle - max_angle)/smooth);
- else
- is = 0.0f;
+ if (angle < max_angle)
+ is = 1.0f;
+ else if (angle < (max_angle + smooth) && smooth != 0.0f)
+ is = (1.0f - (angle - max_angle) / smooth);
+ else
+ is = 0.0f;
- return make_float3(is, is, is);
+ return make_float3(is, is, is);
}
ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
{
- return fminf(max_angle + smooth, M_PI_2_F);
+ return fminf(max_angle + smooth, M_PI_2_F);
}
-ccl_device float3 bsdf_diffuse_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_diffuse_toon_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const ToonBsdf *bsdf = (const ToonBsdf*)sc;
- float max_angle = bsdf->size*M_PI_2_F;
- float smooth = bsdf->smooth*M_PI_2_F;
- float angle = safe_acosf(fmaxf(dot(bsdf->N, omega_in), 0.0f));
+ const ToonBsdf *bsdf = (const ToonBsdf *)sc;
+ float max_angle = bsdf->size * M_PI_2_F;
+ float smooth = bsdf->smooth * M_PI_2_F;
+ float angle = safe_acosf(fmaxf(dot(bsdf->N, omega_in), 0.0f));
- float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
- if(eval.x > 0.0f) {
- float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ if (eval.x > 0.0f) {
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
- *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
- return *pdf * eval;
- }
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return *pdf * eval;
+ }
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_diffuse_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_diffuse_toon_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_diffuse_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_diffuse_toon_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const ToonBsdf *bsdf = (const ToonBsdf*)sc;
- float max_angle = bsdf->size*M_PI_2_F;
- float smooth = bsdf->smooth*M_PI_2_F;
- float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
- float angle = sample_angle*randu;
+ const ToonBsdf *bsdf = (const ToonBsdf *)sc;
+ float max_angle = bsdf->size * M_PI_2_F;
+ float smooth = bsdf->smooth * M_PI_2_F;
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float angle = sample_angle * randu;
- if(sample_angle > 0.0f) {
- sample_uniform_cone(bsdf->N, sample_angle, randu, randv, omega_in, pdf);
+ if (sample_angle > 0.0f) {
+ sample_uniform_cone(bsdf->N, sample_angle, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0.0f) {
- *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+ if (dot(Ng, *omega_in) > 0.0f) {
+ *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the bounce
- *domega_in_dx = (2.0f * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
- *domega_in_dy = (2.0f * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
+ // TODO: find a better approximation for the bounce
+ *domega_in_dx = (2.0f * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
+ *domega_in_dy = (2.0f * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
#endif
- }
- else
- *pdf = 0.0f;
- }
-
- return LABEL_REFLECT | LABEL_DIFFUSE;
+ }
+ else
+ *pdf = 0.0f;
+ }
+ return LABEL_REFLECT | LABEL_DIFFUSE;
}
/* GLOSSY TOON */
ccl_device int bsdf_glossy_toon_setup(ToonBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_GLOSSY_TOON_ID;
- bsdf->size = saturate(bsdf->size);
- bsdf->smooth = saturate(bsdf->smooth);
+ bsdf->type = CLOSURE_BSDF_GLOSSY_TOON_ID;
+ bsdf->size = saturate(bsdf->size);
+ bsdf->smooth = saturate(bsdf->smooth);
- return SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_glossy_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_glossy_toon_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- const ToonBsdf *bsdf = (const ToonBsdf*)sc;
- float max_angle = bsdf->size*M_PI_2_F;
- float smooth = bsdf->smooth*M_PI_2_F;
- float cosNI = dot(bsdf->N, omega_in);
- float cosNO = dot(bsdf->N, I);
+ const ToonBsdf *bsdf = (const ToonBsdf *)sc;
+ float max_angle = bsdf->size * M_PI_2_F;
+ float smooth = bsdf->smooth * M_PI_2_F;
+ float cosNI = dot(bsdf->N, omega_in);
+ float cosNO = dot(bsdf->N, I);
- if(cosNI > 0 && cosNO > 0) {
- /* reflect the view vector */
- float3 R = (2 * cosNO) * bsdf->N - I;
- float cosRI = dot(R, omega_in);
+ if (cosNI > 0 && cosNO > 0) {
+ /* reflect the view vector */
+ float3 R = (2 * cosNO) * bsdf->N - I;
+ float cosRI = dot(R, omega_in);
- float angle = safe_acosf(fmaxf(cosRI, 0.0f));
+ float angle = safe_acosf(fmaxf(cosRI, 0.0f));
- float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
- float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
- *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
- return *pdf * eval;
- }
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return *pdf * eval;
+ }
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_glossy_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_glossy_toon_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_glossy_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_glossy_toon_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const ToonBsdf *bsdf = (const ToonBsdf*)sc;
- float max_angle = bsdf->size*M_PI_2_F;
- float smooth = bsdf->smooth*M_PI_2_F;
- float cosNO = dot(bsdf->N, I);
+ const ToonBsdf *bsdf = (const ToonBsdf *)sc;
+ float max_angle = bsdf->size * M_PI_2_F;
+ float smooth = bsdf->smooth * M_PI_2_F;
+ float cosNO = dot(bsdf->N, I);
- if(cosNO > 0) {
- /* reflect the view vector */
- float3 R = (2 * cosNO) * bsdf->N - I;
+ if (cosNO > 0) {
+ /* reflect the view vector */
+ float3 R = (2 * cosNO) * bsdf->N - I;
- float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
- float angle = sample_angle*randu;
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float angle = sample_angle * randu;
- sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf);
+ sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0.0f) {
- float cosNI = dot(bsdf->N, *omega_in);
+ if (dot(Ng, *omega_in) > 0.0f) {
+ float cosNI = dot(bsdf->N, *omega_in);
- /* make sure the direction we chose is still in the right hemisphere */
- if(cosNI > 0) {
- *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+ /* make sure the direction we chose is still in the right hemisphere */
+ if (cosNI > 0) {
+ *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
- *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
+ *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
+ *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
#endif
- }
- else
- *pdf = 0.0f;
- }
- else
- *pdf = 0.0f;
- }
-
- return LABEL_GLOSSY | LABEL_REFLECT;
+ }
+ else
+ *pdf = 0.0f;
+ }
+ else
+ *pdf = 0.0f;
+ }
+
+ return LABEL_GLOSSY | LABEL_REFLECT;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_TOON_H__ */
+#endif /* __BSDF_TOON_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index 060dff69f52..4e5513499e8 100644
--- a/intern/cycles/kernel/closure/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -37,73 +37,91 @@ CCL_NAMESPACE_BEGIN
ccl_device void bsdf_transparent_setup(ShaderData *sd, const float3 weight, int path_flag)
{
- /* Check cutoff weight. */
- float sample_weight = fabsf(average(weight));
- if(!(sample_weight >= CLOSURE_WEIGHT_CUTOFF)) {
- return;
- }
+ /* Check cutoff weight. */
+ float sample_weight = fabsf(average(weight));
+ if (!(sample_weight >= CLOSURE_WEIGHT_CUTOFF)) {
+ return;
+ }
- if(sd->flag & SD_TRANSPARENT) {
- sd->closure_transparent_extinction += weight;
+ if (sd->flag & SD_TRANSPARENT) {
+ sd->closure_transparent_extinction += weight;
- /* Add weight to existing transparent BSDF. */
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ /* Add weight to existing transparent BSDF. */
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
- sc->weight += weight;
- sc->sample_weight += sample_weight;
- break;
- }
- }
- }
- else {
- sd->flag |= SD_BSDF|SD_TRANSPARENT;
- sd->closure_transparent_extinction = weight;
+ if (sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
+ sc->weight += weight;
+ sc->sample_weight += sample_weight;
+ break;
+ }
+ }
+ }
+ else {
+ sd->flag |= SD_BSDF | SD_TRANSPARENT;
+ sd->closure_transparent_extinction = weight;
- if(path_flag & PATH_RAY_TERMINATE) {
- /* In this case the number of closures is set to zero to disable
- * all others, but we still want to get transparency so increase
- * the number just for this. */
- sd->num_closure_left = 1;
- }
+ if (path_flag & PATH_RAY_TERMINATE) {
+ /* In this case the number of closures is set to zero to disable
+ * all others, but we still want to get transparency so increase
+ * the number just for this. */
+ sd->num_closure_left = 1;
+ }
- /* Create new transparent BSDF. */
- ShaderClosure *bsdf = closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_BSDF_TRANSPARENT_ID, weight);
+ /* Create new transparent BSDF. */
+ ShaderClosure *bsdf = closure_alloc(
+ sd, sizeof(ShaderClosure), CLOSURE_BSDF_TRANSPARENT_ID, weight);
- if(bsdf) {
- bsdf->sample_weight = sample_weight;
- bsdf->N = sd->N;
- }
- else if(path_flag & PATH_RAY_TERMINATE) {
- sd->num_closure_left = 0;
- }
- }
+ if (bsdf) {
+ bsdf->sample_weight = sample_weight;
+ bsdf->N = sd->N;
+ }
+ else if (path_flag & PATH_RAY_TERMINATE) {
+ sd->num_closure_left = 0;
+ }
+ }
}
-ccl_device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_transparent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_transparent_sample(const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- // only one direction is possible
- *omega_in = -I;
+ // only one direction is possible
+ *omega_in = -I;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = -dIdx;
- *domega_in_dy = -dIdy;
+ *domega_in_dx = -dIdx;
+ *domega_in_dy = -dIdy;
#endif
- *pdf = 1;
- *eval = make_float3(1, 1, 1);
- return LABEL_TRANSMIT|LABEL_TRANSPARENT;
+ *pdf = 1;
+ *eval = make_float3(1, 1, 1);
+ return LABEL_TRANSMIT | LABEL_TRANSPARENT;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_TRANSPARENT_H__ */
+#endif /* __BSDF_TRANSPARENT_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
index 4f3453675c7..a9a27edd7de 100644
--- a/intern/cycles/kernel/closure/bsdf_util.h
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -35,127 +35,134 @@
CCL_NAMESPACE_BEGIN
-ccl_device float fresnel_dielectric(
- float eta, const float3 N,
- const float3 I, float3 *R, float3 *T,
+ccl_device float fresnel_dielectric(float eta,
+ const float3 N,
+ const float3 I,
+ float3 *R,
+ float3 *T,
#ifdef __RAY_DIFFERENTIALS__
- const float3 dIdx, const float3 dIdy,
- float3 *dRdx, float3 *dRdy,
- float3 *dTdx, float3 *dTdy,
+ const float3 dIdx,
+ const float3 dIdy,
+ float3 *dRdx,
+ float3 *dRdy,
+ float3 *dTdx,
+ float3 *dTdy,
#endif
- bool *is_inside)
+ bool *is_inside)
{
- float cos = dot(N, I), neta;
- float3 Nn;
+ float cos = dot(N, I), neta;
+ float3 Nn;
- // check which side of the surface we are on
- if(cos > 0) {
- // we are on the outside of the surface, going in
- neta = 1 / eta;
- Nn = N;
- *is_inside = false;
- }
- else {
- // we are inside the surface
- cos = -cos;
- neta = eta;
- Nn = -N;
- *is_inside = true;
- }
+ // check which side of the surface we are on
+ if (cos > 0) {
+ // we are on the outside of the surface, going in
+ neta = 1 / eta;
+ Nn = N;
+ *is_inside = false;
+ }
+ else {
+ // we are inside the surface
+ cos = -cos;
+ neta = eta;
+ Nn = -N;
+ *is_inside = true;
+ }
- // compute reflection
- *R = (2 * cos)* Nn - I;
+ // compute reflection
+ *R = (2 * cos) * Nn - I;
#ifdef __RAY_DIFFERENTIALS__
- *dRdx = (2 * dot(Nn, dIdx)) * Nn - dIdx;
- *dRdy = (2 * dot(Nn, dIdy)) * Nn - dIdy;
+ *dRdx = (2 * dot(Nn, dIdx)) * Nn - dIdx;
+ *dRdy = (2 * dot(Nn, dIdy)) * Nn - dIdy;
#endif
- float arg = 1 -(neta * neta *(1 -(cos * cos)));
- if(arg < 0) {
- *T = make_float3(0.0f, 0.0f, 0.0f);
+ float arg = 1 - (neta * neta * (1 - (cos * cos)));
+ if (arg < 0) {
+ *T = make_float3(0.0f, 0.0f, 0.0f);
#ifdef __RAY_DIFFERENTIALS__
- *dTdx = make_float3(0.0f, 0.0f, 0.0f);
- *dTdy = make_float3(0.0f, 0.0f, 0.0f);
+ *dTdx = make_float3(0.0f, 0.0f, 0.0f);
+ *dTdy = make_float3(0.0f, 0.0f, 0.0f);
#endif
- return 1; // total internal reflection
- }
- else {
- float dnp = max(sqrtf(arg), 1e-7f);
- float nK = (neta * cos)- dnp;
- *T = -(neta * I)+(nK * Nn);
+ return 1; // total internal reflection
+ }
+ else {
+ float dnp = max(sqrtf(arg), 1e-7f);
+ float nK = (neta * cos) - dnp;
+ *T = -(neta * I) + (nK * Nn);
#ifdef __RAY_DIFFERENTIALS__
- *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
- *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
+ *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
+ *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
#endif
- // compute Fresnel terms
- float cosTheta1 = cos; // N.R
- float cosTheta2 = -dot(Nn, *T);
- float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
- float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
- return 0.5f * (pPara * pPara + pPerp * pPerp);
- }
+ // compute Fresnel terms
+ float cosTheta1 = cos; // N.R
+ float cosTheta2 = -dot(Nn, *T);
+ float pPara = (cosTheta1 - eta * cosTheta2) / (cosTheta1 + eta * cosTheta2);
+ float pPerp = (eta * cosTheta1 - cosTheta2) / (eta * cosTheta1 + cosTheta2);
+ return 0.5f * (pPara * pPara + pPerp * pPerp);
+ }
}
ccl_device float fresnel_dielectric_cos(float cosi, float eta)
{
- // compute fresnel reflectance without explicitly computing
- // the refracted direction
- float c = fabsf(cosi);
- float g = eta * eta - 1 + c * c;
- if(g > 0) {
- g = sqrtf(g);
- float A = (g - c)/(g + c);
- float B = (c *(g + c)- 1)/(c *(g - c)+ 1);
- return 0.5f * A * A *(1 + B * B);
- }
- return 1.0f; // TIR(no refracted component)
+ // compute fresnel reflectance without explicitly computing
+ // the refracted direction
+ float c = fabsf(cosi);
+ float g = eta * eta - 1 + c * c;
+ if (g > 0) {
+ g = sqrtf(g);
+ float A = (g - c) / (g + c);
+ float B = (c * (g + c) - 1) / (c * (g - c) + 1);
+ return 0.5f * A * A * (1 + B * B);
+ }
+ return 1.0f; // TIR(no refracted component)
}
ccl_device float3 fresnel_conductor(float cosi, const float3 eta, const float3 k)
{
- float3 cosi2 = make_float3(cosi*cosi, cosi*cosi, cosi*cosi);
- float3 one = make_float3(1.0f, 1.0f, 1.0f);
- float3 tmp_f = eta * eta + k * k;
- float3 tmp = tmp_f * cosi2;
- float3 Rparl2 = (tmp - (2.0f * eta * cosi) + one) /
- (tmp + (2.0f * eta * cosi) + one);
- float3 Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi2) /
- (tmp_f + (2.0f * eta * cosi) + cosi2);
- return(Rparl2 + Rperp2) * 0.5f;
+ float3 cosi2 = make_float3(cosi * cosi, cosi * cosi, cosi * cosi);
+ float3 one = make_float3(1.0f, 1.0f, 1.0f);
+ float3 tmp_f = eta * eta + k * k;
+ float3 tmp = tmp_f * cosi2;
+ float3 Rparl2 = (tmp - (2.0f * eta * cosi) + one) / (tmp + (2.0f * eta * cosi) + one);
+ float3 Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi2) / (tmp_f + (2.0f * eta * cosi) + cosi2);
+ return (Rparl2 + Rperp2) * 0.5f;
}
ccl_device float schlick_fresnel(float u)
{
- float m = clamp(1.0f - u, 0.0f, 1.0f);
- float m2 = m * m;
- return m2 * m2 * m; // pow(m, 5)
+ float m = clamp(1.0f - u, 0.0f, 1.0f);
+ float m2 = m * m;
+ return m2 * m2 * m; // pow(m, 5)
}
ccl_device float smooth_step(float edge0, float edge1, float x)
{
- float result;
- if(x < edge0) result = 0.0f;
- else if(x >= edge1) result = 1.0f;
- else {
- float t = (x - edge0)/(edge1 - edge0);
- result = (3.0f-2.0f*t)*(t*t);
- }
- return result;
+ float result;
+ if (x < edge0)
+ result = 0.0f;
+ else if (x >= edge1)
+ result = 1.0f;
+ else {
+ float t = (x - edge0) / (edge1 - edge0);
+ result = (3.0f - 2.0f * t) * (t * t);
+ }
+ return result;
}
/* Calculate the fresnel color which is a blend between white and the F0 color (cspec0) */
-ccl_device_forceinline float3 interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0) {
- /* Calculate the fresnel interpolation factor
- * The value from fresnel_dielectric_cos(...) has to be normalized because
- * the cspec0 keeps the F0 color
- */
- float F0_norm = 1.0f / (1.0f - F0);
- float FH = (fresnel_dielectric_cos(dot(L, H), ior) - F0) * F0_norm;
+ccl_device_forceinline float3
+interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0)
+{
+ /* Calculate the fresnel interpolation factor
+ * The value from fresnel_dielectric_cos(...) has to be normalized because
+ * the cspec0 keeps the F0 color
+ */
+ float F0_norm = 1.0f / (1.0f - F0);
+ float FH = (fresnel_dielectric_cos(dot(L, H), ior) - F0) * F0_norm;
- /* Blend between white and a specular color with respect to the fresnel */
- return cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
+ /* Blend between white and a specular color with respect to the fresnel */
+ return cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
}
CCL_NAMESPACE_END
-#endif /* __BSDF_UTIL_H__ */
+#endif /* __BSDF_UTIL_H__ */
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h
index 98c7f23c288..57804eca269 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -20,14 +20,14 @@
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct Bssrdf {
- SHADER_CLOSURE_BASE;
-
- float3 radius;
- float3 albedo;
- float sharpness;
- float texture_blur;
- float roughness;
- float channels;
+ SHADER_CLOSURE_BASE;
+
+ float3 radius;
+ float3 albedo;
+ float sharpness;
+ float texture_blur;
+ float roughness;
+ float channels;
} Bssrdf;
/* Planar Truncated Gaussian
@@ -41,41 +41,41 @@ typedef ccl_addr_space struct Bssrdf {
ccl_device float bssrdf_gaussian_eval(const float radius, float r)
{
- /* integrate (2*pi*r * exp(-r*r/(2*v)))/(2*pi*v)) from 0 to Rm
- * = 1 - exp(-Rm*Rm/(2*v)) */
- const float v = radius*radius*(0.25f*0.25f);
- const float Rm = sqrtf(v*GAUSS_TRUNCATE);
+ /* integrate (2*pi*r * exp(-r*r/(2*v)))/(2*pi*v)) from 0 to Rm
+ * = 1 - exp(-Rm*Rm/(2*v)) */
+ const float v = radius * radius * (0.25f * 0.25f);
+ const float Rm = sqrtf(v * GAUSS_TRUNCATE);
- if(r >= Rm)
- return 0.0f;
+ if (r >= Rm)
+ return 0.0f;
- return expf(-r*r/(2.0f*v))/(2.0f*M_PI_F*v);
+ return expf(-r * r / (2.0f * v)) / (2.0f * M_PI_F * v);
}
ccl_device float bssrdf_gaussian_pdf(const float radius, float r)
{
- /* 1.0 - expf(-Rm*Rm/(2*v)) simplified */
- const float area_truncated = 1.0f - expf(-0.5f*GAUSS_TRUNCATE);
+ /* 1.0 - expf(-Rm*Rm/(2*v)) simplified */
+ const float area_truncated = 1.0f - expf(-0.5f * GAUSS_TRUNCATE);
- return bssrdf_gaussian_eval(radius, r) * (1.0f/(area_truncated));
+ return bssrdf_gaussian_eval(radius, r) * (1.0f / (area_truncated));
}
ccl_device void bssrdf_gaussian_sample(const float radius, float xi, float *r, float *h)
{
- /* xi = integrate (2*pi*r * exp(-r*r/(2*v)))/(2*pi*v)) = -exp(-r^2/(2*v))
- * r = sqrt(-2*v*logf(xi)) */
- const float v = radius*radius*(0.25f*0.25f);
- const float Rm = sqrtf(v*GAUSS_TRUNCATE);
+ /* xi = integrate (2*pi*r * exp(-r*r/(2*v)))/(2*pi*v)) = -exp(-r^2/(2*v))
+ * r = sqrt(-2*v*logf(xi)) */
+ const float v = radius * radius * (0.25f * 0.25f);
+ const float Rm = sqrtf(v * GAUSS_TRUNCATE);
- /* 1.0 - expf(-Rm*Rm/(2*v)) simplified */
- const float area_truncated = 1.0f - expf(-0.5f*GAUSS_TRUNCATE);
+ /* 1.0 - expf(-Rm*Rm/(2*v)) simplified */
+ const float area_truncated = 1.0f - expf(-0.5f * GAUSS_TRUNCATE);
- /* r(xi) */
- const float r_squared = -2.0f*v*logf(1.0f - xi*area_truncated);
- *r = sqrtf(r_squared);
+ /* r(xi) */
+ const float r_squared = -2.0f * v * logf(1.0f - xi * area_truncated);
+ *r = sqrtf(r_squared);
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm*Rm - r_squared);
+ /* h^2 + r^2 = Rm^2 */
+ *h = safe_sqrtf(Rm * Rm - r_squared);
}
/* Planar Cubic BSSRDF falloff
@@ -87,97 +87,97 @@ ccl_device void bssrdf_gaussian_sample(const float radius, float xi, float *r, f
ccl_device float bssrdf_cubic_eval(const float radius, const float sharpness, float r)
{
- if(sharpness == 0.0f) {
- const float Rm = radius;
-
- if(r >= Rm)
- return 0.0f;
-
- /* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */
- const float Rm5 = (Rm*Rm) * (Rm*Rm) * Rm;
- const float f = Rm - r;
- const float num = f*f*f;
-
- return (10.0f * num) / (Rm5 * M_PI_F);
-
- }
- else {
- float Rm = radius*(1.0f + sharpness);
-
- if(r >= Rm)
- return 0.0f;
-
- /* custom variation with extra sharpness, to match the previous code */
- const float y = 1.0f/(1.0f + sharpness);
- float Rmy, ry, ryinv;
-
- if(sharpness == 1.0f) {
- Rmy = sqrtf(Rm);
- ry = sqrtf(r);
- ryinv = (ry > 0.0f)? 1.0f/ry: 0.0f;
- }
- else {
- Rmy = powf(Rm, y);
- ry = powf(r, y);
- ryinv = (r > 0.0f)? powf(r, y - 1.0f): 0.0f;
- }
-
- const float Rmy5 = (Rmy*Rmy) * (Rmy*Rmy) * Rmy;
- const float f = Rmy - ry;
- const float num = f*(f*f)*(y*ryinv);
-
- return (10.0f * num) / (Rmy5 * M_PI_F);
- }
+ if (sharpness == 0.0f) {
+ const float Rm = radius;
+
+ if (r >= Rm)
+ return 0.0f;
+
+ /* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */
+ const float Rm5 = (Rm * Rm) * (Rm * Rm) * Rm;
+ const float f = Rm - r;
+ const float num = f * f * f;
+
+ return (10.0f * num) / (Rm5 * M_PI_F);
+ }
+ else {
+ float Rm = radius * (1.0f + sharpness);
+
+ if (r >= Rm)
+ return 0.0f;
+
+ /* custom variation with extra sharpness, to match the previous code */
+ const float y = 1.0f / (1.0f + sharpness);
+ float Rmy, ry, ryinv;
+
+ if (sharpness == 1.0f) {
+ Rmy = sqrtf(Rm);
+ ry = sqrtf(r);
+ ryinv = (ry > 0.0f) ? 1.0f / ry : 0.0f;
+ }
+ else {
+ Rmy = powf(Rm, y);
+ ry = powf(r, y);
+ ryinv = (r > 0.0f) ? powf(r, y - 1.0f) : 0.0f;
+ }
+
+ const float Rmy5 = (Rmy * Rmy) * (Rmy * Rmy) * Rmy;
+ const float f = Rmy - ry;
+ const float num = f * (f * f) * (y * ryinv);
+
+ return (10.0f * num) / (Rmy5 * M_PI_F);
+ }
}
ccl_device float bssrdf_cubic_pdf(const float radius, const float sharpness, float r)
{
- return bssrdf_cubic_eval(radius, sharpness, r);
+ return bssrdf_cubic_eval(radius, sharpness, r);
}
/* solve 10x^2 - 20x^3 + 15x^4 - 4x^5 - xi == 0 */
ccl_device_forceinline float bssrdf_cubic_quintic_root_find(float xi)
{
- /* newton-raphson iteration, usually succeeds in 2-4 iterations, except
- * outside 0.02 ... 0.98 where it can go up to 10, so overall performance
- * should not be too bad */
- const float tolerance = 1e-6f;
- const int max_iteration_count = 10;
- float x = 0.25f;
- int i;
+ /* newton-raphson iteration, usually succeeds in 2-4 iterations, except
+ * outside 0.02 ... 0.98 where it can go up to 10, so overall performance
+ * should not be too bad */
+ const float tolerance = 1e-6f;
+ const int max_iteration_count = 10;
+ float x = 0.25f;
+ int i;
- for(i = 0; i < max_iteration_count; i++) {
- float x2 = x*x;
- float x3 = x2*x;
- float nx = (1.0f - x);
+ for (i = 0; i < max_iteration_count; i++) {
+ float x2 = x * x;
+ float x3 = x2 * x;
+ float nx = (1.0f - x);
- float f = 10.0f*x2 - 20.0f*x3 + 15.0f*x2*x2 - 4.0f*x2*x3 - xi;
- float f_ = 20.0f*(x*nx)*(nx*nx);
+ float f = 10.0f * x2 - 20.0f * x3 + 15.0f * x2 * x2 - 4.0f * x2 * x3 - xi;
+ float f_ = 20.0f * (x * nx) * (nx * nx);
- if(fabsf(f) < tolerance || f_ == 0.0f)
- break;
+ if (fabsf(f) < tolerance || f_ == 0.0f)
+ break;
- x = saturate(x - f/f_);
- }
+ x = saturate(x - f / f_);
+ }
- return x;
+ return x;
}
-ccl_device void bssrdf_cubic_sample(const float radius, const float sharpness, float xi, float *r, float *h)
+ccl_device void bssrdf_cubic_sample(
+ const float radius, const float sharpness, float xi, float *r, float *h)
{
- float Rm = radius;
- float r_ = bssrdf_cubic_quintic_root_find(xi);
+ float Rm = radius;
+ float r_ = bssrdf_cubic_quintic_root_find(xi);
- if(sharpness != 0.0f) {
- r_ = powf(r_, 1.0f + sharpness);
- Rm *= (1.0f + sharpness);
- }
+ if (sharpness != 0.0f) {
+ r_ = powf(r_, 1.0f + sharpness);
+ Rm *= (1.0f + sharpness);
+ }
- r_ *= Rm;
- *r = r_;
+ r_ *= Rm;
+ *r = r_;
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm*Rm - r_*r_);
+ /* h^2 + r^2 = Rm^2 */
+ *h = safe_sqrtf(Rm * Rm - r_ * r_);
}
/* Approximate Reflectance Profiles
@@ -188,13 +188,13 @@ ccl_device void bssrdf_cubic_sample(const float radius, const float sharpness, f
* the mean free length, but still not too big so sampling is still
* effective. Might need some further tweaks.
*/
-#define BURLEY_TRUNCATE 16.0f
-#define BURLEY_TRUNCATE_CDF 0.9963790093708328f // cdf(BURLEY_TRUNCATE)
+#define BURLEY_TRUNCATE 16.0f
+#define BURLEY_TRUNCATE_CDF 0.9963790093708328f // cdf(BURLEY_TRUNCATE)
ccl_device_inline float bssrdf_burley_fitting(float A)
{
- /* Diffuse surface transmission, equation (6). */
- return 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f);
+ /* Diffuse surface transmission, equation (6). */
+ return 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f);
}
/* Scale mean free path length so it gives similar looking result
@@ -202,45 +202,44 @@ ccl_device_inline float bssrdf_burley_fitting(float A)
*/
ccl_device_inline float3 bssrdf_burley_compatible_mfp(float3 r)
{
- return 0.25f * M_1_PI_F * r;
+ return 0.25f * M_1_PI_F * r;
}
ccl_device void bssrdf_burley_setup(Bssrdf *bssrdf)
{
- /* Mean free path length. */
- const float3 l = bssrdf_burley_compatible_mfp(bssrdf->radius);
- /* Surface albedo. */
- const float3 A = bssrdf->albedo;
- const float3 s = make_float3(bssrdf_burley_fitting(A.x),
- bssrdf_burley_fitting(A.y),
- bssrdf_burley_fitting(A.z));
-
- bssrdf->radius = l / s;
+ /* Mean free path length. */
+ const float3 l = bssrdf_burley_compatible_mfp(bssrdf->radius);
+ /* Surface albedo. */
+ const float3 A = bssrdf->albedo;
+ const float3 s = make_float3(
+ bssrdf_burley_fitting(A.x), bssrdf_burley_fitting(A.y), bssrdf_burley_fitting(A.z));
+
+ bssrdf->radius = l / s;
}
ccl_device float bssrdf_burley_eval(const float d, float r)
{
- const float Rm = BURLEY_TRUNCATE * d;
-
- if(r >= Rm)
- return 0.0f;
-
- /* Burley refletance profile, equation (3).
- *
- * NOTES:
- * - Surface albedo is already included into sc->weight, no need to
- * multiply by this term here.
- * - This is normalized diffuse model, so the equation is mutliplied
- * by 2*pi, which also matches cdf().
- */
- float exp_r_3_d = expf(-r / (3.0f * d));
- float exp_r_d = exp_r_3_d * exp_r_3_d * exp_r_3_d;
- return (exp_r_d + exp_r_3_d) / (4.0f*d);
+ const float Rm = BURLEY_TRUNCATE * d;
+
+ if (r >= Rm)
+ return 0.0f;
+
+ /* Burley refletance profile, equation (3).
+ *
+ * NOTES:
+ * - Surface albedo is already included into sc->weight, no need to
+ * multiply by this term here.
+ * - This is normalized diffuse model, so the equation is mutliplied
+ * by 2*pi, which also matches cdf().
+ */
+ float exp_r_3_d = expf(-r / (3.0f * d));
+ float exp_r_d = exp_r_3_d * exp_r_3_d * exp_r_3_d;
+ return (exp_r_d + exp_r_3_d) / (4.0f * d);
}
ccl_device float bssrdf_burley_pdf(const float d, float r)
{
- return bssrdf_burley_eval(d, r) * (1.0f/BURLEY_TRUNCATE_CDF);
+ return bssrdf_burley_eval(d, r) * (1.0f / BURLEY_TRUNCATE_CDF);
}
/* Find the radius for desired CDF value.
@@ -249,52 +248,49 @@ ccl_device float bssrdf_burley_pdf(const float d, float r)
*/
ccl_device_forceinline float bssrdf_burley_root_find(float xi)
{
- const float tolerance = 1e-6f;
- const int max_iteration_count = 10;
- /* Do initial guess based on manual curve fitting, this allows us to reduce
- * number of iterations to maximum 4 across the [0..1] range. We keep maximum
- * number of iteration higher just to be sure we didn't miss root in some
- * corner case.
- */
- float r;
- if(xi <= 0.9f) {
- r = expf(xi * xi * 2.4f) - 1.0f;
- }
- else {
- /* TODO(sergey): Some nicer curve fit is possible here. */
- r = 15.0f;
- }
- /* Solve against scaled radius. */
- for(int i = 0; i < max_iteration_count; i++) {
- float exp_r_3 = expf(-r / 3.0f);
- float exp_r = exp_r_3 * exp_r_3 * exp_r_3;
- float f = 1.0f - 0.25f * exp_r - 0.75f * exp_r_3 - xi;
- float f_ = 0.25f * exp_r + 0.25f * exp_r_3;
-
- if(fabsf(f) < tolerance || f_ == 0.0f) {
- break;
- }
-
- r = r - f/f_;
- if(r < 0.0f) {
- r = 0.0f;
- }
- }
- return r;
+ const float tolerance = 1e-6f;
+ const int max_iteration_count = 10;
+ /* Do initial guess based on manual curve fitting, this allows us to reduce
+ * number of iterations to maximum 4 across the [0..1] range. We keep maximum
+ * number of iteration higher just to be sure we didn't miss root in some
+ * corner case.
+ */
+ float r;
+ if (xi <= 0.9f) {
+ r = expf(xi * xi * 2.4f) - 1.0f;
+ }
+ else {
+ /* TODO(sergey): Some nicer curve fit is possible here. */
+ r = 15.0f;
+ }
+ /* Solve against scaled radius. */
+ for (int i = 0; i < max_iteration_count; i++) {
+ float exp_r_3 = expf(-r / 3.0f);
+ float exp_r = exp_r_3 * exp_r_3 * exp_r_3;
+ float f = 1.0f - 0.25f * exp_r - 0.75f * exp_r_3 - xi;
+ float f_ = 0.25f * exp_r + 0.25f * exp_r_3;
+
+ if (fabsf(f) < tolerance || f_ == 0.0f) {
+ break;
+ }
+
+ r = r - f / f_;
+ if (r < 0.0f) {
+ r = 0.0f;
+ }
+ }
+ return r;
}
-ccl_device void bssrdf_burley_sample(const float d,
- float xi,
- float *r,
- float *h)
+ccl_device void bssrdf_burley_sample(const float d, float xi, float *r, float *h)
{
- const float Rm = BURLEY_TRUNCATE * d;
- const float r_ = bssrdf_burley_root_find(xi * BURLEY_TRUNCATE_CDF) * d;
+ const float Rm = BURLEY_TRUNCATE * d;
+ const float r_ = bssrdf_burley_root_find(xi * BURLEY_TRUNCATE_CDF) * d;
- *r = r_;
+ *r = r_;
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm*Rm - r_*r_);
+ /* h^2 + r^2 = Rm^2 */
+ *h = safe_sqrtf(Rm * Rm - r_ * r_);
}
/* None BSSRDF falloff
@@ -303,200 +299,195 @@ ccl_device void bssrdf_burley_sample(const float d,
ccl_device float bssrdf_none_eval(const float radius, float r)
{
- const float Rm = radius;
- return (r < Rm)? 1.0f: 0.0f;
+ const float Rm = radius;
+ return (r < Rm) ? 1.0f : 0.0f;
}
ccl_device float bssrdf_none_pdf(const float radius, float r)
{
- /* integrate (2*pi*r)/(pi*Rm*Rm) from 0 to Rm = 1 */
- const float Rm = radius;
- const float area = (M_PI_F*Rm*Rm);
+ /* integrate (2*pi*r)/(pi*Rm*Rm) from 0 to Rm = 1 */
+ const float Rm = radius;
+ const float area = (M_PI_F * Rm * Rm);
- return bssrdf_none_eval(radius, r) / area;
+ return bssrdf_none_eval(radius, r) / area;
}
ccl_device void bssrdf_none_sample(const float radius, float xi, float *r, float *h)
{
- /* xi = integrate (2*pi*r)/(pi*Rm*Rm) = r^2/Rm^2
- * r = sqrt(xi)*Rm */
- const float Rm = radius;
- const float r_ = sqrtf(xi)*Rm;
+ /* xi = integrate (2*pi*r)/(pi*Rm*Rm) = r^2/Rm^2
+ * r = sqrt(xi)*Rm */
+ const float Rm = radius;
+ const float r_ = sqrtf(xi) * Rm;
- *r = r_;
+ *r = r_;
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm*Rm - r_*r_);
+ /* h^2 + r^2 = Rm^2 */
+ *h = safe_sqrtf(Rm * Rm - r_ * r_);
}
/* Generic */
ccl_device_inline Bssrdf *bssrdf_alloc(ShaderData *sd, float3 weight)
{
- Bssrdf *bssrdf = (Bssrdf*)closure_alloc(sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight);
+ Bssrdf *bssrdf = (Bssrdf *)closure_alloc(sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight);
- if(bssrdf == NULL) {
- return NULL;
- }
+ if (bssrdf == NULL) {
+ return NULL;
+ }
- float sample_weight = fabsf(average(weight));
- bssrdf->sample_weight = sample_weight;
- return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL;
+ float sample_weight = fabsf(average(weight));
+ bssrdf->sample_weight = sample_weight;
+ return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL;
}
ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type)
{
- int flag = 0;
- int bssrdf_channels = 3;
- float3 diffuse_weight = make_float3(0.0f, 0.0f, 0.0f);
-
- /* Verify if the radii are large enough to sample without precision issues. */
- if(bssrdf->radius.x < BSSRDF_MIN_RADIUS) {
- diffuse_weight.x = bssrdf->weight.x;
- bssrdf->weight.x = 0.0f;
- bssrdf->radius.x = 0.0f;
- bssrdf_channels--;
- }
- if(bssrdf->radius.y < BSSRDF_MIN_RADIUS) {
- diffuse_weight.y = bssrdf->weight.y;
- bssrdf->weight.y = 0.0f;
- bssrdf->radius.y = 0.0f;
- bssrdf_channels--;
- }
- if(bssrdf->radius.z < BSSRDF_MIN_RADIUS) {
- diffuse_weight.z = bssrdf->weight.z;
- bssrdf->weight.z = 0.0f;
- bssrdf->radius.z = 0.0f;
- bssrdf_channels--;
- }
-
- if(bssrdf_channels < 3) {
- /* Add diffuse BSDF if any radius too small. */
+ int flag = 0;
+ int bssrdf_channels = 3;
+ float3 diffuse_weight = make_float3(0.0f, 0.0f, 0.0f);
+
+ /* Verify if the radii are large enough to sample without precision issues. */
+ if (bssrdf->radius.x < BSSRDF_MIN_RADIUS) {
+ diffuse_weight.x = bssrdf->weight.x;
+ bssrdf->weight.x = 0.0f;
+ bssrdf->radius.x = 0.0f;
+ bssrdf_channels--;
+ }
+ if (bssrdf->radius.y < BSSRDF_MIN_RADIUS) {
+ diffuse_weight.y = bssrdf->weight.y;
+ bssrdf->weight.y = 0.0f;
+ bssrdf->radius.y = 0.0f;
+ bssrdf_channels--;
+ }
+ if (bssrdf->radius.z < BSSRDF_MIN_RADIUS) {
+ diffuse_weight.z = bssrdf->weight.z;
+ bssrdf->weight.z = 0.0f;
+ bssrdf->radius.z = 0.0f;
+ bssrdf_channels--;
+ }
+
+ if (bssrdf_channels < 3) {
+ /* Add diffuse BSDF if any radius too small. */
#ifdef __PRINCIPLED__
- if(type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
- type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
- {
- float roughness = bssrdf->roughness;
- float3 N = bssrdf->N;
-
- PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diffuse_weight);
-
- if(bsdf) {
- bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID;
- bsdf->N = N;
- bsdf->roughness = roughness;
- flag |= bsdf_principled_diffuse_setup(bsdf);
- }
- }
- else
-#endif /* __PRINCIPLED__ */
- {
- DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), diffuse_weight);
-
- if(bsdf) {
- bsdf->type = CLOSURE_BSDF_BSSRDF_ID;
- bsdf->N = bssrdf->N;
- flag |= bsdf_diffuse_setup(bsdf);
- }
- }
- }
-
- /* Setup BSSRDF if radius is large enough. */
- if(bssrdf_channels > 0) {
- bssrdf->type = type;
- bssrdf->channels = bssrdf_channels;
- bssrdf->sample_weight = fabsf(average(bssrdf->weight)) * bssrdf->channels;
- bssrdf->texture_blur = saturate(bssrdf->texture_blur);
- bssrdf->sharpness = saturate(bssrdf->sharpness);
-
- if(type == CLOSURE_BSSRDF_BURLEY_ID ||
- type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
- type == CLOSURE_BSSRDF_RANDOM_WALK_ID ||
- type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
- {
- bssrdf_burley_setup(bssrdf);
- }
-
- flag |= SD_BSSRDF;
- }
- else {
- bssrdf->type = type;
- bssrdf->sample_weight = 0.0f;
- }
-
- return flag;
+ if (type == CLOSURE_BSSRDF_PRINCIPLED_ID || type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) {
+ float roughness = bssrdf->roughness;
+ float3 N = bssrdf->N;
+
+ PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc(
+ sd, sizeof(PrincipledDiffuseBsdf), diffuse_weight);
+
+ if (bsdf) {
+ bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID;
+ bsdf->N = N;
+ bsdf->roughness = roughness;
+ flag |= bsdf_principled_diffuse_setup(bsdf);
+ }
+ }
+ else
+#endif /* __PRINCIPLED__ */
+ {
+ DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), diffuse_weight);
+
+ if (bsdf) {
+ bsdf->type = CLOSURE_BSDF_BSSRDF_ID;
+ bsdf->N = bssrdf->N;
+ flag |= bsdf_diffuse_setup(bsdf);
+ }
+ }
+ }
+
+ /* Setup BSSRDF if radius is large enough. */
+ if (bssrdf_channels > 0) {
+ bssrdf->type = type;
+ bssrdf->channels = bssrdf_channels;
+ bssrdf->sample_weight = fabsf(average(bssrdf->weight)) * bssrdf->channels;
+ bssrdf->texture_blur = saturate(bssrdf->texture_blur);
+ bssrdf->sharpness = saturate(bssrdf->sharpness);
+
+ if (type == CLOSURE_BSSRDF_BURLEY_ID || type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
+ type == CLOSURE_BSSRDF_RANDOM_WALK_ID ||
+ type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) {
+ bssrdf_burley_setup(bssrdf);
+ }
+
+ flag |= SD_BSSRDF;
+ }
+ else {
+ bssrdf->type = type;
+ bssrdf->sample_weight = 0.0f;
+ }
+
+ return flag;
}
ccl_device void bssrdf_sample(const ShaderClosure *sc, float xi, float *r, float *h)
{
- const Bssrdf *bssrdf = (const Bssrdf*)sc;
- float radius;
-
- /* Sample color channel and reuse random number. Only a subset of channels
- * may be used if their radius was too small to handle as BSSRDF. */
- xi *= bssrdf->channels;
-
- if(xi < 1.0f) {
- radius = (bssrdf->radius.x > 0.0f)? bssrdf->radius.x:
- (bssrdf->radius.y > 0.0f)? bssrdf->radius.y:
- bssrdf->radius.z;
- }
- else if(xi < 2.0f) {
- xi -= 1.0f;
- radius = (bssrdf->radius.x > 0.0f)? bssrdf->radius.y:
- bssrdf->radius.z;
- }
- else {
- xi -= 2.0f;
- radius = bssrdf->radius.z;
- }
-
- /* Sample BSSRDF. */
- if(bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) {
- bssrdf_cubic_sample(radius, bssrdf->sharpness, xi, r, h);
- }
- else if(bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID){
- bssrdf_gaussian_sample(radius, xi, r, h);
- }
- else { /*if(bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID || bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/
- bssrdf_burley_sample(radius, xi, r, h);
- }
+ const Bssrdf *bssrdf = (const Bssrdf *)sc;
+ float radius;
+
+ /* Sample color channel and reuse random number. Only a subset of channels
+ * may be used if their radius was too small to handle as BSSRDF. */
+ xi *= bssrdf->channels;
+
+ if (xi < 1.0f) {
+ radius = (bssrdf->radius.x > 0.0f) ?
+ bssrdf->radius.x :
+ (bssrdf->radius.y > 0.0f) ? bssrdf->radius.y : bssrdf->radius.z;
+ }
+ else if (xi < 2.0f) {
+ xi -= 1.0f;
+ radius = (bssrdf->radius.x > 0.0f) ? bssrdf->radius.y : bssrdf->radius.z;
+ }
+ else {
+ xi -= 2.0f;
+ radius = bssrdf->radius.z;
+ }
+
+ /* Sample BSSRDF. */
+ if (bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) {
+ bssrdf_cubic_sample(radius, bssrdf->sharpness, xi, r, h);
+ }
+ else if (bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID) {
+ bssrdf_gaussian_sample(radius, xi, r, h);
+ }
+ else { /*if(bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID || bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/
+ bssrdf_burley_sample(radius, xi, r, h);
+ }
}
ccl_device float bssrdf_channel_pdf(const Bssrdf *bssrdf, float radius, float r)
{
- if(radius == 0.0f) {
- return 0.0f;
- }
- else if(bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) {
- return bssrdf_cubic_pdf(radius, bssrdf->sharpness, r);
- }
- else if(bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID) {
- return bssrdf_gaussian_pdf(radius, r);
- }
- else { /*if(bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID || bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/
- return bssrdf_burley_pdf(radius, r);
- }
+ if (radius == 0.0f) {
+ return 0.0f;
+ }
+ else if (bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) {
+ return bssrdf_cubic_pdf(radius, bssrdf->sharpness, r);
+ }
+ else if (bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID) {
+ return bssrdf_gaussian_pdf(radius, r);
+ }
+ else { /*if(bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID || bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/
+ return bssrdf_burley_pdf(radius, r);
+ }
}
ccl_device_forceinline float3 bssrdf_eval(const ShaderClosure *sc, float r)
{
- const Bssrdf *bssrdf = (const Bssrdf*)sc;
+ const Bssrdf *bssrdf = (const Bssrdf *)sc;
- return make_float3(
- bssrdf_channel_pdf(bssrdf, bssrdf->radius.x, r),
- bssrdf_channel_pdf(bssrdf, bssrdf->radius.y, r),
- bssrdf_channel_pdf(bssrdf, bssrdf->radius.z, r));
+ return make_float3(bssrdf_channel_pdf(bssrdf, bssrdf->radius.x, r),
+ bssrdf_channel_pdf(bssrdf, bssrdf->radius.y, r),
+ bssrdf_channel_pdf(bssrdf, bssrdf->radius.z, r));
}
ccl_device_forceinline float bssrdf_pdf(const ShaderClosure *sc, float r)
{
- const Bssrdf *bssrdf = (const Bssrdf*)sc;
- float3 pdf = bssrdf_eval(sc, r);
+ const Bssrdf *bssrdf = (const Bssrdf *)sc;
+ float3 pdf = bssrdf_eval(sc, r);
- return (pdf.x + pdf.y + pdf.z) / bssrdf->channels;
+ return (pdf.x + pdf.y + pdf.z) / bssrdf->channels;
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_BSSRDF_H__ */
+#endif /* __KERNEL_BSSRDF_H__ */
diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h
index a7f4a2a7327..911382e6865 100644
--- a/intern/cycles/kernel/closure/emissive.h
+++ b/intern/cycles/kernel/closure/emissive.h
@@ -36,26 +36,26 @@ CCL_NAMESPACE_BEGIN
ccl_device void background_setup(ShaderData *sd, const float3 weight)
{
- if(sd->flag & SD_EMISSION) {
- sd->closure_emission_background += weight;
- }
- else {
- sd->flag |= SD_EMISSION;
- sd->closure_emission_background = weight;
- }
+ if (sd->flag & SD_EMISSION) {
+ sd->closure_emission_background += weight;
+ }
+ else {
+ sd->flag |= SD_EMISSION;
+ sd->closure_emission_background = weight;
+ }
}
/* EMISSION CLOSURE */
ccl_device void emission_setup(ShaderData *sd, const float3 weight)
{
- if(sd->flag & SD_EMISSION) {
- sd->closure_emission_background += weight;
- }
- else {
- sd->flag |= SD_EMISSION;
- sd->closure_emission_background = weight;
- }
+ if (sd->flag & SD_EMISSION) {
+ sd->closure_emission_background += weight;
+ }
+ else {
+ sd->flag |= SD_EMISSION;
+ sd->closure_emission_background = weight;
+ }
}
/* return the probability distribution function in the direction I,
@@ -63,21 +63,21 @@ ccl_device void emission_setup(ShaderData *sd, const float3 weight)
* the PDF computed by sample(). */
ccl_device float emissive_pdf(const float3 Ng, const float3 I)
{
- float cosNO = fabsf(dot(Ng, I));
- return (cosNO > 0.0f)? 1.0f: 0.0f;
+ float cosNO = fabsf(dot(Ng, I));
+ return (cosNO > 0.0f) ? 1.0f : 0.0f;
}
-ccl_device void emissive_sample(const float3 Ng, float randu, float randv,
- float3 *omega_out, float *pdf)
+ccl_device void emissive_sample(
+ const float3 Ng, float randu, float randv, float3 *omega_out, float *pdf)
{
- /* todo: not implemented and used yet */
+ /* todo: not implemented and used yet */
}
ccl_device float3 emissive_simple_eval(const float3 Ng, const float3 I)
{
- float res = emissive_pdf(Ng, I);
+ float res = emissive_pdf(Ng, I);
- return make_float3(res, res, res);
+ return make_float3(res, res, res);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 872d06c936a..473bc0e8a82 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -23,21 +23,21 @@ CCL_NAMESPACE_BEGIN
ccl_device void volume_extinction_setup(ShaderData *sd, float3 weight)
{
- if(sd->flag & SD_EXTINCTION) {
- sd->closure_transparent_extinction += weight;
- }
- else {
- sd->flag |= SD_EXTINCTION;
- sd->closure_transparent_extinction = weight;
- }
+ if (sd->flag & SD_EXTINCTION) {
+ sd->closure_transparent_extinction += weight;
+ }
+ else {
+ sd->flag |= SD_EXTINCTION;
+ sd->closure_transparent_extinction = weight;
+ }
}
/* HENYEY-GREENSTEIN CLOSURE */
typedef ccl_addr_space struct HenyeyGreensteinVolume {
- SHADER_CLOSURE_BASE;
+ SHADER_CLOSURE_BASE;
- float g;
+ float g;
} HenyeyGreensteinVolume;
/* Given cosine between rays, return probability density that a photon bounces
@@ -45,119 +45,152 @@ typedef ccl_addr_space struct HenyeyGreensteinVolume {
* uniform sphere. g=0 uniform diffuse-like, g=1 close to sharp single ray. */
ccl_device float single_peaked_henyey_greenstein(float cos_theta, float g)
{
- return ((1.0f - g * g) / safe_powf(1.0f + g * g - 2.0f * g * cos_theta, 1.5f)) * (M_1_PI_F * 0.25f);
+ return ((1.0f - g * g) / safe_powf(1.0f + g * g - 2.0f * g * cos_theta, 1.5f)) *
+ (M_1_PI_F * 0.25f);
};
ccl_device int volume_henyey_greenstein_setup(HenyeyGreensteinVolume *volume)
{
- volume->type = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
+ volume->type = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
- /* clamp anisotropy to avoid delta function */
- volume->g = signf(volume->g) * min(fabsf(volume->g), 1.0f - 1e-3f);
+ /* clamp anisotropy to avoid delta function */
+ volume->g = signf(volume->g) * min(fabsf(volume->g), 1.0f - 1e-3f);
- return SD_SCATTER;
+ return SD_SCATTER;
}
ccl_device bool volume_henyey_greenstein_merge(const ShaderClosure *a, const ShaderClosure *b)
{
- const HenyeyGreensteinVolume *volume_a = (const HenyeyGreensteinVolume*)a;
- const HenyeyGreensteinVolume *volume_b = (const HenyeyGreensteinVolume*)b;
+ const HenyeyGreensteinVolume *volume_a = (const HenyeyGreensteinVolume *)a;
+ const HenyeyGreensteinVolume *volume_b = (const HenyeyGreensteinVolume *)b;
- return (volume_a->g == volume_b->g);
+ return (volume_a->g == volume_b->g);
}
-ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
+ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc,
+ const float3 I,
+ float3 omega_in,
+ float *pdf)
{
- const HenyeyGreensteinVolume *volume = (const HenyeyGreensteinVolume*)sc;
- float g = volume->g;
-
- /* note that I points towards the viewer */
- if(fabsf(g) < 1e-3f) {
- *pdf = M_1_PI_F * 0.25f;
- }
- else {
- float cos_theta = dot(-I, omega_in);
- *pdf = single_peaked_henyey_greenstein(cos_theta, g);
- }
-
- return make_float3(*pdf, *pdf, *pdf);
+ const HenyeyGreensteinVolume *volume = (const HenyeyGreensteinVolume *)sc;
+ float g = volume->g;
+
+ /* note that I points towards the viewer */
+ if (fabsf(g) < 1e-3f) {
+ *pdf = M_1_PI_F * 0.25f;
+ }
+ else {
+ float cos_theta = dot(-I, omega_in);
+ *pdf = single_peaked_henyey_greenstein(cos_theta, g);
+ }
+
+ return make_float3(*pdf, *pdf, *pdf);
}
-ccl_device float3 henyey_greenstrein_sample(float3 D, float g, float randu, float randv, float *pdf)
+ccl_device float3
+henyey_greenstrein_sample(float3 D, float g, float randu, float randv, float *pdf)
{
- /* match pdf for small g */
- float cos_theta;
- bool isotropic = fabsf(g) < 1e-3f;
-
- if(isotropic) {
- cos_theta = (1.0f - 2.0f * randu);
- if(pdf) {
- *pdf = M_1_PI_F * 0.25f;
- }
- }
- else {
- float k = (1.0f - g * g) / (1.0f - g + 2.0f * g * randu);
- cos_theta = (1.0f + g * g - k * k) / (2.0f * g);
- if(pdf) {
- *pdf = single_peaked_henyey_greenstein(cos_theta, g);
- }
- }
-
- float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
- float phi = M_2PI_F * randv;
- float3 dir = make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cos_theta);
-
- float3 T, B;
- make_orthonormals(D, &T, &B);
- dir = dir.x * T + dir.y * B + dir.z * D;
-
- return dir;
+ /* match pdf for small g */
+ float cos_theta;
+ bool isotropic = fabsf(g) < 1e-3f;
+
+ if (isotropic) {
+ cos_theta = (1.0f - 2.0f * randu);
+ if (pdf) {
+ *pdf = M_1_PI_F * 0.25f;
+ }
+ }
+ else {
+ float k = (1.0f - g * g) / (1.0f - g + 2.0f * g * randu);
+ cos_theta = (1.0f + g * g - k * k) / (2.0f * g);
+ if (pdf) {
+ *pdf = single_peaked_henyey_greenstein(cos_theta, g);
+ }
+ }
+
+ float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
+ float phi = M_2PI_F * randv;
+ float3 dir = make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cos_theta);
+
+ float3 T, B;
+ make_orthonormals(D, &T, &B);
+ dir = dir.x * T + dir.y * B + dir.z * D;
+
+ return dir;
}
-ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
- float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ float3 *domega_in_dx,
+ float3 *domega_in_dy,
+ float *pdf)
{
- const HenyeyGreensteinVolume *volume = (const HenyeyGreensteinVolume*)sc;
- float g = volume->g;
+ const HenyeyGreensteinVolume *volume = (const HenyeyGreensteinVolume *)sc;
+ float g = volume->g;
- /* note that I points towards the viewer and so is used negated */
- *omega_in = henyey_greenstrein_sample(-I, g, randu, randv, pdf);
- *eval = make_float3(*pdf, *pdf, *pdf); /* perfect importance sampling */
+ /* note that I points towards the viewer and so is used negated */
+ *omega_in = henyey_greenstrein_sample(-I, g, randu, randv, pdf);
+ *eval = make_float3(*pdf, *pdf, *pdf); /* perfect importance sampling */
#ifdef __RAY_DIFFERENTIALS__
- /* todo: implement ray differential estimation */
- *domega_in_dx = make_float3(0.0f, 0.0f, 0.0f);
- *domega_in_dy = make_float3(0.0f, 0.0f, 0.0f);
+ /* todo: implement ray differential estimation */
+ *domega_in_dx = make_float3(0.0f, 0.0f, 0.0f);
+ *domega_in_dy = make_float3(0.0f, 0.0f, 0.0f);
#endif
- return LABEL_VOLUME_SCATTER;
+ return LABEL_VOLUME_SCATTER;
}
/* VOLUME CLOSURE */
-ccl_device float3 volume_phase_eval(const ShaderData *sd, const ShaderClosure *sc, float3 omega_in, float *pdf)
+ccl_device float3 volume_phase_eval(const ShaderData *sd,
+ const ShaderClosure *sc,
+ float3 omega_in,
+ float *pdf)
{
- kernel_assert(sc->type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID);
+ kernel_assert(sc->type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID);
- return volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
+ return volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
}
-ccl_device int volume_phase_sample(const ShaderData *sd, const ShaderClosure *sc, float randu,
- float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
+ccl_device int volume_phase_sample(const ShaderData *sd,
+ const ShaderClosure *sc,
+ float randu,
+ float randv,
+ float3 *eval,
+ float3 *omega_in,
+ differential3 *domega_in,
+ float *pdf)
{
- int label;
-
- switch(sc->type) {
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- label = volume_henyey_greenstein_sample(sc, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- default:
- *eval = make_float3(0.0f, 0.0f, 0.0f);
- label = LABEL_NONE;
- break;
- }
-
- return label;
+ int label;
+
+ switch (sc->type) {
+ case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
+ label = volume_henyey_greenstein_sample(sc,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+ break;
+ default:
+ *eval = make_float3(0.0f, 0.0f, 0.0f);
+ label = LABEL_NONE;
+ break;
+ }
+
+ return label;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/filter/filter.h b/intern/cycles/kernel/filter/filter.h
index 4209d69ee73..b067e53a8bf 100644
--- a/intern/cycles/kernel/filter/filter.h
+++ b/intern/cycles/kernel/filter/filter.h
@@ -25,8 +25,8 @@
CCL_NAMESPACE_BEGIN
-#define KERNEL_NAME_JOIN(x, y, z) x ## _ ## y ## _ ## z
-#define KERNEL_NAME_EVAL(arch, name) KERNEL_NAME_JOIN(kernel, arch, name)
+#define KERNEL_NAME_JOIN(x, y, z) x##_##y##_##z
+#define KERNEL_NAME_EVAL(arch, name) KERNEL_NAME_JOIN(kernel, arch, name)
#define KERNEL_FUNCTION_FULL_NAME(name) KERNEL_NAME_EVAL(KERNEL_ARCH, name)
#define KERNEL_ARCH cpu
@@ -49,4 +49,4 @@ CCL_NAMESPACE_BEGIN
CCL_NAMESPACE_END
-#endif /* __FILTER_H__ */
+#endif /* __FILTER_H__ */
diff --git a/intern/cycles/kernel/filter/filter_defines.h b/intern/cycles/kernel/filter/filter_defines.h
index cb04aac35f4..0e51eeef92f 100644
--- a/intern/cycles/kernel/filter/filter_defines.h
+++ b/intern/cycles/kernel/filter/filter_defines.h
@@ -18,59 +18,56 @@
#define __FILTER_DEFINES_H__
#define DENOISE_FEATURES 11
-#define TRANSFORM_SIZE (DENOISE_FEATURES*DENOISE_FEATURES)
-#define XTWX_SIZE (((DENOISE_FEATURES+1)*(DENOISE_FEATURES+2))/2)
-#define XTWY_SIZE (DENOISE_FEATURES+1)
+#define TRANSFORM_SIZE (DENOISE_FEATURES * DENOISE_FEATURES)
+#define XTWX_SIZE (((DENOISE_FEATURES + 1) * (DENOISE_FEATURES + 2)) / 2)
+#define XTWY_SIZE (DENOISE_FEATURES + 1)
#define DENOISE_MAX_FRAMES 16
typedef struct TileInfo {
- int offsets[9];
- int strides[9];
- int x[4];
- int y[4];
- int from_render;
- int frames[DENOISE_MAX_FRAMES];
- int num_frames;
- /* TODO(lukas): CUDA doesn't have uint64_t... */
+ int offsets[9];
+ int strides[9];
+ int x[4];
+ int y[4];
+ int from_render;
+ int frames[DENOISE_MAX_FRAMES];
+ int num_frames;
+ /* TODO(lukas): CUDA doesn't have uint64_t... */
#ifdef __KERNEL_OPENCL__
- ccl_global float *buffers[9];
+ ccl_global float *buffers[9];
#else
- long long int buffers[9];
+ long long int buffers[9];
#endif
} TileInfo;
#ifdef __KERNEL_OPENCL__
-# define CCL_FILTER_TILE_INFO ccl_global TileInfo* tile_info, \
- ccl_global float *tile_buffer_1, \
- ccl_global float *tile_buffer_2, \
- ccl_global float *tile_buffer_3, \
- ccl_global float *tile_buffer_4, \
- ccl_global float *tile_buffer_5, \
- ccl_global float *tile_buffer_6, \
- ccl_global float *tile_buffer_7, \
- ccl_global float *tile_buffer_8, \
- ccl_global float *tile_buffer_9
-# define CCL_FILTER_TILE_INFO_ARG tile_info, \
- tile_buffer_1, tile_buffer_2, tile_buffer_3, \
- tile_buffer_4, tile_buffer_5, tile_buffer_6, \
- tile_buffer_7, tile_buffer_8, tile_buffer_9
-# define ccl_get_tile_buffer(id) (id == 0 ? tile_buffer_1 \
- : id == 1 ? tile_buffer_2 \
- : id == 2 ? tile_buffer_3 \
- : id == 3 ? tile_buffer_4 \
- : id == 4 ? tile_buffer_5 \
- : id == 5 ? tile_buffer_6 \
- : id == 6 ? tile_buffer_7 \
- : id == 7 ? tile_buffer_8 \
- : tile_buffer_9)
+# define CCL_FILTER_TILE_INFO \
+ ccl_global TileInfo *tile_info, ccl_global float *tile_buffer_1, \
+ ccl_global float *tile_buffer_2, ccl_global float *tile_buffer_3, \
+ ccl_global float *tile_buffer_4, ccl_global float *tile_buffer_5, \
+ ccl_global float *tile_buffer_6, ccl_global float *tile_buffer_7, \
+ ccl_global float *tile_buffer_8, ccl_global float *tile_buffer_9
+# define CCL_FILTER_TILE_INFO_ARG \
+ tile_info, tile_buffer_1, tile_buffer_2, tile_buffer_3, tile_buffer_4, tile_buffer_5, \
+ tile_buffer_6, tile_buffer_7, tile_buffer_8, tile_buffer_9
+# define ccl_get_tile_buffer(id) \
+ (id == 0 ? tile_buffer_1 : \
+ id == 1 ? \
+ tile_buffer_2 : \
+ id == 2 ? \
+ tile_buffer_3 : \
+ id == 3 ? tile_buffer_4 : \
+ id == 4 ? tile_buffer_5 : \
+ id == 5 ? tile_buffer_6 : \
+ id == 6 ? tile_buffer_7 : \
+ id == 7 ? tile_buffer_8 : tile_buffer_9)
#else
# ifdef __KERNEL_CUDA__
-# define CCL_FILTER_TILE_INFO ccl_global TileInfo* tile_info
+# define CCL_FILTER_TILE_INFO ccl_global TileInfo *tile_info
# else
-# define CCL_FILTER_TILE_INFO TileInfo* tile_info
+# define CCL_FILTER_TILE_INFO TileInfo *tile_info
# endif
# define ccl_get_tile_buffer(id) (tile_info->buffers[id])
#endif
-#endif /* __FILTER_DEFINES_H__*/
+#endif /* __FILTER_DEFINES_H__*/
diff --git a/intern/cycles/kernel/filter/filter_features.h b/intern/cycles/kernel/filter/filter_features.h
index e1ea6487aa9..809ccfe8be6 100644
--- a/intern/cycles/kernel/filter/filter_features.h
+++ b/intern/cycles/kernel/filter/filter_features.h
@@ -14,22 +14,25 @@
* limitations under the License.
*/
- CCL_NAMESPACE_BEGIN
+CCL_NAMESPACE_BEGIN
#define ccl_get_feature(buffer, pass) (buffer)[(pass)*pass_stride]
/* Loop over the pixels in the range [low.x, high.x) x [low.y, high.y).+ * pixel_buffer always points to the current pixel in the first pass.
* Repeat the loop for every secondary frame if there are any. */
-#define FOR_PIXEL_WINDOW for(int frame = 0; frame < tile_info->num_frames; frame++) { \
- pixel.z = tile_info->frames[frame]; \
- pixel_buffer = buffer + (low.y - rect.y)*buffer_w + (low.x - rect.x) + frame*frame_stride; \
- for(pixel.y = low.y; pixel.y < high.y; pixel.y++) { \
- for(pixel.x = low.x; pixel.x < high.x; pixel.x++, pixel_buffer++) {
+#define FOR_PIXEL_WINDOW \
+ for (int frame = 0; frame < tile_info->num_frames; frame++) { \
+ pixel.z = tile_info->frames[frame]; \
+ pixel_buffer = buffer + (low.y - rect.y) * buffer_w + (low.x - rect.x) + \
+ frame * frame_stride; \
+ for (pixel.y = low.y; pixel.y < high.y; pixel.y++) { \
+ for (pixel.x = low.x; pixel.x < high.x; pixel.x++, pixel_buffer++) {
-#define END_FOR_PIXEL_WINDOW } \
- pixel_buffer += buffer_w - (high.x - low.x); \
- } \
- }
+#define END_FOR_PIXEL_WINDOW \
+ } \
+ pixel_buffer += buffer_w - (high.x - low.x); \
+ } \
+ }
ccl_device_inline void filter_get_features(int3 pixel,
const ccl_global float *ccl_restrict buffer,
@@ -38,24 +41,24 @@ ccl_device_inline void filter_get_features(int3 pixel,
const float *ccl_restrict mean,
int pass_stride)
{
- features[0] = pixel.x;
- features[1] = pixel.y;
- features[2] = fabsf(ccl_get_feature(buffer, 0));
- features[3] = ccl_get_feature(buffer, 1);
- features[4] = ccl_get_feature(buffer, 2);
- features[5] = ccl_get_feature(buffer, 3);
- features[6] = ccl_get_feature(buffer, 4);
- features[7] = ccl_get_feature(buffer, 5);
- features[8] = ccl_get_feature(buffer, 6);
- features[9] = ccl_get_feature(buffer, 7);
- if(use_time) {
- features[10] = pixel.z;
- }
- if(mean) {
- for(int i = 0; i < (use_time? 11 : 10); i++) {
- features[i] -= mean[i];
- }
- }
+ features[0] = pixel.x;
+ features[1] = pixel.y;
+ features[2] = fabsf(ccl_get_feature(buffer, 0));
+ features[3] = ccl_get_feature(buffer, 1);
+ features[4] = ccl_get_feature(buffer, 2);
+ features[5] = ccl_get_feature(buffer, 3);
+ features[6] = ccl_get_feature(buffer, 4);
+ features[7] = ccl_get_feature(buffer, 5);
+ features[8] = ccl_get_feature(buffer, 6);
+ features[9] = ccl_get_feature(buffer, 7);
+ if (use_time) {
+ features[10] = pixel.z;
+ }
+ if (mean) {
+ for (int i = 0; i < (use_time ? 11 : 10); i++) {
+ features[i] -= mean[i];
+ }
+ }
}
ccl_device_inline void filter_get_feature_scales(int3 pixel,
@@ -65,38 +68,39 @@ ccl_device_inline void filter_get_feature_scales(int3 pixel,
const float *ccl_restrict mean,
int pass_stride)
{
- scales[0] = fabsf(pixel.x - mean[0]);
- scales[1] = fabsf(pixel.y - mean[1]);
- scales[2] = fabsf(fabsf(ccl_get_feature(buffer, 0)) - mean[2]);
- scales[3] = len_squared(make_float3(ccl_get_feature(buffer, 1) - mean[3],
- ccl_get_feature(buffer, 2) - mean[4],
- ccl_get_feature(buffer, 3) - mean[5]));
- scales[4] = fabsf(ccl_get_feature(buffer, 4) - mean[6]);
- scales[5] = len_squared(make_float3(ccl_get_feature(buffer, 5) - mean[7],
- ccl_get_feature(buffer, 6) - mean[8],
- ccl_get_feature(buffer, 7) - mean[9]));
- if(use_time) {
- scales[6] = fabsf(pixel.z - mean[10]);
- }
+ scales[0] = fabsf(pixel.x - mean[0]);
+ scales[1] = fabsf(pixel.y - mean[1]);
+ scales[2] = fabsf(fabsf(ccl_get_feature(buffer, 0)) - mean[2]);
+ scales[3] = len_squared(make_float3(ccl_get_feature(buffer, 1) - mean[3],
+ ccl_get_feature(buffer, 2) - mean[4],
+ ccl_get_feature(buffer, 3) - mean[5]));
+ scales[4] = fabsf(ccl_get_feature(buffer, 4) - mean[6]);
+ scales[5] = len_squared(make_float3(ccl_get_feature(buffer, 5) - mean[7],
+ ccl_get_feature(buffer, 6) - mean[8],
+ ccl_get_feature(buffer, 7) - mean[9]));
+ if (use_time) {
+ scales[6] = fabsf(pixel.z - mean[10]);
+ }
}
ccl_device_inline void filter_calculate_scale(float *scale, bool use_time)
{
- scale[0] = 1.0f/max(scale[0], 0.01f);
- scale[1] = 1.0f/max(scale[1], 0.01f);
- scale[2] = 1.0f/max(scale[2], 0.01f);
- if(use_time) {
- scale[10] = 1.0f/max(scale[6], 0.01f);
- }
- scale[6] = 1.0f/max(scale[4], 0.01f);
- scale[7] = scale[8] = scale[9] = 1.0f/max(sqrtf(scale[5]), 0.01f);
- scale[3] = scale[4] = scale[5] = 1.0f/max(sqrtf(scale[3]), 0.01f);
+ scale[0] = 1.0f / max(scale[0], 0.01f);
+ scale[1] = 1.0f / max(scale[1], 0.01f);
+ scale[2] = 1.0f / max(scale[2], 0.01f);
+ if (use_time) {
+ scale[10] = 1.0f / max(scale[6], 0.01f);
+ }
+ scale[6] = 1.0f / max(scale[4], 0.01f);
+ scale[7] = scale[8] = scale[9] = 1.0f / max(sqrtf(scale[5]), 0.01f);
+ scale[3] = scale[4] = scale[5] = 1.0f / max(sqrtf(scale[3]), 0.01f);
}
ccl_device_inline float3 filter_get_color(const ccl_global float *ccl_restrict buffer,
int pass_stride)
{
- return make_float3(ccl_get_feature(buffer, 8), ccl_get_feature(buffer, 9), ccl_get_feature(buffer, 10));
+ return make_float3(
+ ccl_get_feature(buffer, 8), ccl_get_feature(buffer, 9), ccl_get_feature(buffer, 10));
}
ccl_device_inline void design_row_add(float *design_row,
@@ -107,42 +111,44 @@ ccl_device_inline void design_row_add(float *design_row,
float feature,
int transform_row_stride)
{
- for(int i = 0; i < rank; i++) {
- design_row[1+i] += transform[(row*transform_row_stride + i)*stride]*feature;
- }
+ for (int i = 0; i < rank; i++) {
+ design_row[1 + i] += transform[(row * transform_row_stride + i) * stride] * feature;
+ }
}
/* Fill the design row. */
-ccl_device_inline void filter_get_design_row_transform(int3 p_pixel,
- const ccl_global float *ccl_restrict p_buffer,
- int3 q_pixel,
- const ccl_global float *ccl_restrict q_buffer,
- int pass_stride,
- int rank,
- float *design_row,
- const ccl_global float *ccl_restrict transform,
- int stride,
- bool use_time)
+ccl_device_inline void filter_get_design_row_transform(
+ int3 p_pixel,
+ const ccl_global float *ccl_restrict p_buffer,
+ int3 q_pixel,
+ const ccl_global float *ccl_restrict q_buffer,
+ int pass_stride,
+ int rank,
+ float *design_row,
+ const ccl_global float *ccl_restrict transform,
+ int stride,
+ bool use_time)
{
- int num_features = use_time? 11 : 10;
+ int num_features = use_time ? 11 : 10;
- design_row[0] = 1.0f;
- math_vector_zero(design_row+1, rank);
+ design_row[0] = 1.0f;
+ math_vector_zero(design_row + 1, rank);
-#define DESIGN_ROW_ADD(I, F) design_row_add(design_row, rank, transform, stride, I, F, num_features);
- DESIGN_ROW_ADD(0, q_pixel.x - p_pixel.x);
- DESIGN_ROW_ADD(1, q_pixel.y - p_pixel.y);
- DESIGN_ROW_ADD(2, fabsf(ccl_get_feature(q_buffer, 0)) - fabsf(ccl_get_feature(p_buffer, 0)));
- DESIGN_ROW_ADD(3, ccl_get_feature(q_buffer, 1) - ccl_get_feature(p_buffer, 1));
- DESIGN_ROW_ADD(4, ccl_get_feature(q_buffer, 2) - ccl_get_feature(p_buffer, 2));
- DESIGN_ROW_ADD(5, ccl_get_feature(q_buffer, 3) - ccl_get_feature(p_buffer, 3));
- DESIGN_ROW_ADD(6, ccl_get_feature(q_buffer, 4) - ccl_get_feature(p_buffer, 4));
- DESIGN_ROW_ADD(7, ccl_get_feature(q_buffer, 5) - ccl_get_feature(p_buffer, 5));
- DESIGN_ROW_ADD(8, ccl_get_feature(q_buffer, 6) - ccl_get_feature(p_buffer, 6));
- DESIGN_ROW_ADD(9, ccl_get_feature(q_buffer, 7) - ccl_get_feature(p_buffer, 7));
- if(use_time) {
- DESIGN_ROW_ADD(10, q_pixel.z - p_pixel.z)
- }
+#define DESIGN_ROW_ADD(I, F) \
+ design_row_add(design_row, rank, transform, stride, I, F, num_features);
+ DESIGN_ROW_ADD(0, q_pixel.x - p_pixel.x);
+ DESIGN_ROW_ADD(1, q_pixel.y - p_pixel.y);
+ DESIGN_ROW_ADD(2, fabsf(ccl_get_feature(q_buffer, 0)) - fabsf(ccl_get_feature(p_buffer, 0)));
+ DESIGN_ROW_ADD(3, ccl_get_feature(q_buffer, 1) - ccl_get_feature(p_buffer, 1));
+ DESIGN_ROW_ADD(4, ccl_get_feature(q_buffer, 2) - ccl_get_feature(p_buffer, 2));
+ DESIGN_ROW_ADD(5, ccl_get_feature(q_buffer, 3) - ccl_get_feature(p_buffer, 3));
+ DESIGN_ROW_ADD(6, ccl_get_feature(q_buffer, 4) - ccl_get_feature(p_buffer, 4));
+ DESIGN_ROW_ADD(7, ccl_get_feature(q_buffer, 5) - ccl_get_feature(p_buffer, 5));
+ DESIGN_ROW_ADD(8, ccl_get_feature(q_buffer, 6) - ccl_get_feature(p_buffer, 6));
+ DESIGN_ROW_ADD(9, ccl_get_feature(q_buffer, 7) - ccl_get_feature(p_buffer, 7));
+ if (use_time) {
+ DESIGN_ROW_ADD(10, q_pixel.z - p_pixel.z)
+ }
#undef DESIGN_ROW_ADD
}
diff --git a/intern/cycles/kernel/filter/filter_features_sse.h b/intern/cycles/kernel/filter/filter_features_sse.h
index 5dd001ffb93..1e0d6e93453 100644
--- a/intern/cycles/kernel/filter/filter_features_sse.h
+++ b/intern/cycles/kernel/filter/filter_features_sse.h
@@ -22,22 +22,27 @@ CCL_NAMESPACE_BEGIN
* pixel_buffer always points to the first of the 4 current pixel in the first pass.
* x4 and y4 contain the coordinates of the four pixels, active_pixels contains a mask that's set for all pixels within the window.
* Repeat the loop for every secondary frame if there are any. */
-#define FOR_PIXEL_WINDOW_SSE for(int frame = 0; frame < tile_info->num_frames; frame++) { \
- pixel.z = tile_info->frames[frame]; \
- pixel_buffer = buffer + (low.y - rect.y)*buffer_w + (low.x - rect.x) + frame*frame_stride; \
- float4 t4 = make_float4(pixel.z); \
- for(pixel.y = low.y; pixel.y < high.y; pixel.y++) { \
- float4 y4 = make_float4(pixel.y); \
- for(pixel.x = low.x; pixel.x < high.x; pixel.x += 4, pixel_buffer += 4) { \
- float4 x4 = make_float4(pixel.x) + make_float4(0.0f, 1.0f, 2.0f, 3.0f); \
- int4 active_pixels = x4 < make_float4(high.x);
+#define FOR_PIXEL_WINDOW_SSE \
+ for (int frame = 0; frame < tile_info->num_frames; frame++) { \
+ pixel.z = tile_info->frames[frame]; \
+ pixel_buffer = buffer + (low.y - rect.y) * buffer_w + (low.x - rect.x) + \
+ frame * frame_stride; \
+ float4 t4 = make_float4(pixel.z); \
+ for (pixel.y = low.y; pixel.y < high.y; pixel.y++) { \
+ float4 y4 = make_float4(pixel.y); \
+ for (pixel.x = low.x; pixel.x < high.x; pixel.x += 4, pixel_buffer += 4) { \
+ float4 x4 = make_float4(pixel.x) + make_float4(0.0f, 1.0f, 2.0f, 3.0f); \
+ int4 active_pixels = x4 < make_float4(high.x);
-#define END_FOR_PIXEL_WINDOW_SSE } \
- pixel_buffer += buffer_w - (high.x - low.x); \
- } \
- }
+#define END_FOR_PIXEL_WINDOW_SSE \
+ } \
+ pixel_buffer += buffer_w - (high.x - low.x); \
+ } \
+ }
-ccl_device_inline void filter_get_features_sse(float4 x, float4 y, float4 t,
+ccl_device_inline void filter_get_features_sse(float4 x,
+ float4 y,
+ float4 t,
int4 active_pixels,
const float *ccl_restrict buffer,
float4 *features,
@@ -45,33 +50,35 @@ ccl_device_inline void filter_get_features_sse(float4 x, float4 y, float4 t,
const float4 *ccl_restrict mean,
int pass_stride)
{
- int num_features = use_time? 11 : 10;
+ int num_features = use_time ? 11 : 10;
- features[0] = x;
- features[1] = y;
- features[2] = fabs(ccl_get_feature_sse(0));
- features[3] = ccl_get_feature_sse(1);
- features[4] = ccl_get_feature_sse(2);
- features[5] = ccl_get_feature_sse(3);
- features[6] = ccl_get_feature_sse(4);
- features[7] = ccl_get_feature_sse(5);
- features[8] = ccl_get_feature_sse(6);
- features[9] = ccl_get_feature_sse(7);
- if(use_time) {
- features[10] = t;
- }
+ features[0] = x;
+ features[1] = y;
+ features[2] = fabs(ccl_get_feature_sse(0));
+ features[3] = ccl_get_feature_sse(1);
+ features[4] = ccl_get_feature_sse(2);
+ features[5] = ccl_get_feature_sse(3);
+ features[6] = ccl_get_feature_sse(4);
+ features[7] = ccl_get_feature_sse(5);
+ features[8] = ccl_get_feature_sse(6);
+ features[9] = ccl_get_feature_sse(7);
+ if (use_time) {
+ features[10] = t;
+ }
- if(mean) {
- for(int i = 0; i < num_features; i++) {
- features[i] = features[i] - mean[i];
- }
- }
- for(int i = 0; i < num_features; i++) {
- features[i] = mask(active_pixels, features[i]);
- }
+ if (mean) {
+ for (int i = 0; i < num_features; i++) {
+ features[i] = features[i] - mean[i];
+ }
+ }
+ for (int i = 0; i < num_features; i++) {
+ features[i] = mask(active_pixels, features[i]);
+ }
}
-ccl_device_inline void filter_get_feature_scales_sse(float4 x, float4 y, float4 t,
+ccl_device_inline void filter_get_feature_scales_sse(float4 x,
+ float4 y,
+ float4 t,
int4 active_pixels,
const float *ccl_restrict buffer,
float4 *scales,
@@ -79,36 +86,34 @@ ccl_device_inline void filter_get_feature_scales_sse(float4 x, float4 y, float4
const float4 *ccl_restrict mean,
int pass_stride)
{
- scales[0] = fabs(x - mean[0]);
- scales[1] = fabs(y - mean[1]);
- scales[2] = fabs(fabs(ccl_get_feature_sse(0)) - mean[2]);
- scales[3] = sqr(ccl_get_feature_sse(1) - mean[3]) +
- sqr(ccl_get_feature_sse(2) - mean[4]) +
- sqr(ccl_get_feature_sse(3) - mean[5]);
- scales[4] = fabs(ccl_get_feature_sse(4) - mean[6]);
- scales[5] = sqr(ccl_get_feature_sse(5) - mean[7]) +
- sqr(ccl_get_feature_sse(6) - mean[8]) +
- sqr(ccl_get_feature_sse(7) - mean[9]);
- if(use_time) {
- scales[6] = fabs(t - mean[10]);
- }
+ scales[0] = fabs(x - mean[0]);
+ scales[1] = fabs(y - mean[1]);
+ scales[2] = fabs(fabs(ccl_get_feature_sse(0)) - mean[2]);
+ scales[3] = sqr(ccl_get_feature_sse(1) - mean[3]) + sqr(ccl_get_feature_sse(2) - mean[4]) +
+ sqr(ccl_get_feature_sse(3) - mean[5]);
+ scales[4] = fabs(ccl_get_feature_sse(4) - mean[6]);
+ scales[5] = sqr(ccl_get_feature_sse(5) - mean[7]) + sqr(ccl_get_feature_sse(6) - mean[8]) +
+ sqr(ccl_get_feature_sse(7) - mean[9]);
+ if (use_time) {
+ scales[6] = fabs(t - mean[10]);
+ }
- for(int i = 0; i < (use_time? 7 : 6); i++)
- scales[i] = mask(active_pixels, scales[i]);
+ for (int i = 0; i < (use_time ? 7 : 6); i++)
+ scales[i] = mask(active_pixels, scales[i]);
}
ccl_device_inline void filter_calculate_scale_sse(float4 *scale, bool use_time)
{
- scale[0] = rcp(max(reduce_max(scale[0]), make_float4(0.01f)));
- scale[1] = rcp(max(reduce_max(scale[1]), make_float4(0.01f)));
- scale[2] = rcp(max(reduce_max(scale[2]), make_float4(0.01f)));
- if(use_time) {
- scale[10] = rcp(max(reduce_max(scale[6]), make_float4(0.01f)));;
- }
- scale[6] = rcp(max(reduce_max(scale[4]), make_float4(0.01f)));
- scale[7] = scale[8] = scale[9] = rcp(max(reduce_max(sqrt(scale[5])), make_float4(0.01f)));
- scale[3] = scale[4] = scale[5] = rcp(max(reduce_max(sqrt(scale[3])), make_float4(0.01f)));
+ scale[0] = rcp(max(reduce_max(scale[0]), make_float4(0.01f)));
+ scale[1] = rcp(max(reduce_max(scale[1]), make_float4(0.01f)));
+ scale[2] = rcp(max(reduce_max(scale[2]), make_float4(0.01f)));
+ if (use_time) {
+ scale[10] = rcp(max(reduce_max(scale[6]), make_float4(0.01f)));
+ ;
+ }
+ scale[6] = rcp(max(reduce_max(scale[4]), make_float4(0.01f)));
+ scale[7] = scale[8] = scale[9] = rcp(max(reduce_max(sqrt(scale[5])), make_float4(0.01f)));
+ scale[3] = scale[4] = scale[5] = rcp(max(reduce_max(sqrt(scale[3])), make_float4(0.01f)));
}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/filter/filter_nlm_cpu.h b/intern/cycles/kernel/filter/filter_nlm_cpu.h
index 9eb3c603a4a..a94266a8786 100644
--- a/intern/cycles/kernel/filter/filter_nlm_cpu.h
+++ b/intern/cycles/kernel/filter/filter_nlm_cpu.h
@@ -16,10 +16,11 @@
CCL_NAMESPACE_BEGIN
-#define load4_a(buf, ofs) (*((float4*) ((buf) + (ofs))))
-#define load4_u(buf, ofs) load_float4((buf)+(ofs))
+#define load4_a(buf, ofs) (*((float4 *)((buf) + (ofs))))
+#define load4_u(buf, ofs) load_float4((buf) + (ofs))
-ccl_device_inline void kernel_filter_nlm_calc_difference(int dx, int dy,
+ccl_device_inline void kernel_filter_nlm_calc_difference(int dx,
+ int dy,
const float *ccl_restrict weight_image,
const float *ccl_restrict variance_image,
const float *ccl_restrict scale_image,
@@ -31,122 +32,117 @@ ccl_device_inline void kernel_filter_nlm_calc_difference(int dx, int dy,
float a,
float k_2)
{
- /* Strides need to be aligned to 16 bytes. */
- kernel_assert((stride % 4) == 0 && (channel_offset % 4) == 0);
-
- int aligned_lowx = rect.x & (~3);
- const int numChannels = (channel_offset > 0)? 3 : 1;
- const float4 channel_fac = make_float4(1.0f / numChannels);
-
- for(int y = rect.y; y < rect.w; y++) {
- int idx_p = y*stride + aligned_lowx;
- int idx_q = (y+dy)*stride + aligned_lowx + dx + frame_offset;
- for(int x = aligned_lowx; x < rect.z; x += 4, idx_p += 4, idx_q += 4) {
- float4 diff = make_float4(0.0f);
- float4 scale_fac;
- if(scale_image) {
- scale_fac = clamp(load4_a(scale_image, idx_p) / load4_u(scale_image, idx_q),
- make_float4(0.25f), make_float4(4.0f));
- }
- else {
- scale_fac = make_float4(1.0f);
- }
- for(int c = 0, chan_ofs = 0; c < numChannels; c++, chan_ofs += channel_offset) {
- /* idx_p is guaranteed to be aligned, but idx_q isn't. */
- float4 color_p = load4_a(weight_image, idx_p + chan_ofs);
- float4 color_q = scale_fac*load4_u(weight_image, idx_q + chan_ofs);
- float4 cdiff = color_p - color_q;
- float4 var_p = load4_a(variance_image, idx_p + chan_ofs);
- float4 var_q = sqr(scale_fac)*load4_u(variance_image, idx_q + chan_ofs);
- diff += (cdiff*cdiff - a*(var_p + min(var_p, var_q))) / (make_float4(1e-8f) + k_2*(var_p+var_q));
- }
- load4_a(difference_image, idx_p) = diff*channel_fac;
- }
- }
+ /* Strides need to be aligned to 16 bytes. */
+ kernel_assert((stride % 4) == 0 && (channel_offset % 4) == 0);
+
+ int aligned_lowx = rect.x & (~3);
+ const int numChannels = (channel_offset > 0) ? 3 : 1;
+ const float4 channel_fac = make_float4(1.0f / numChannels);
+
+ for (int y = rect.y; y < rect.w; y++) {
+ int idx_p = y * stride + aligned_lowx;
+ int idx_q = (y + dy) * stride + aligned_lowx + dx + frame_offset;
+ for (int x = aligned_lowx; x < rect.z; x += 4, idx_p += 4, idx_q += 4) {
+ float4 diff = make_float4(0.0f);
+ float4 scale_fac;
+ if (scale_image) {
+ scale_fac = clamp(load4_a(scale_image, idx_p) / load4_u(scale_image, idx_q),
+ make_float4(0.25f),
+ make_float4(4.0f));
+ }
+ else {
+ scale_fac = make_float4(1.0f);
+ }
+ for (int c = 0, chan_ofs = 0; c < numChannels; c++, chan_ofs += channel_offset) {
+ /* idx_p is guaranteed to be aligned, but idx_q isn't. */
+ float4 color_p = load4_a(weight_image, idx_p + chan_ofs);
+ float4 color_q = scale_fac * load4_u(weight_image, idx_q + chan_ofs);
+ float4 cdiff = color_p - color_q;
+ float4 var_p = load4_a(variance_image, idx_p + chan_ofs);
+ float4 var_q = sqr(scale_fac) * load4_u(variance_image, idx_q + chan_ofs);
+ diff += (cdiff * cdiff - a * (var_p + min(var_p, var_q))) /
+ (make_float4(1e-8f) + k_2 * (var_p + var_q));
+ }
+ load4_a(difference_image, idx_p) = diff * channel_fac;
+ }
+ }
}
-ccl_device_inline void kernel_filter_nlm_blur(const float *ccl_restrict difference_image,
- float *out_image,
- int4 rect,
- int stride,
- int f)
+ccl_device_inline void kernel_filter_nlm_blur(
+ const float *ccl_restrict difference_image, float *out_image, int4 rect, int stride, int f)
{
- int aligned_lowx = round_down(rect.x, 4);
- for(int y = rect.y; y < rect.w; y++) {
- const int low = max(rect.y, y-f);
- const int high = min(rect.w, y+f+1);
- for(int x = aligned_lowx; x < rect.z; x += 4) {
- load4_a(out_image, y*stride + x) = make_float4(0.0f);
- }
- for(int y1 = low; y1 < high; y1++) {
- for(int x = aligned_lowx; x < rect.z; x += 4) {
- load4_a(out_image, y*stride + x) += load4_a(difference_image, y1*stride + x);
- }
- }
- float fac = 1.0f/(high - low);
- for(int x = aligned_lowx; x < rect.z; x += 4) {
- load4_a(out_image, y*stride + x) *= fac;
- }
- }
+ int aligned_lowx = round_down(rect.x, 4);
+ for (int y = rect.y; y < rect.w; y++) {
+ const int low = max(rect.y, y - f);
+ const int high = min(rect.w, y + f + 1);
+ for (int x = aligned_lowx; x < rect.z; x += 4) {
+ load4_a(out_image, y * stride + x) = make_float4(0.0f);
+ }
+ for (int y1 = low; y1 < high; y1++) {
+ for (int x = aligned_lowx; x < rect.z; x += 4) {
+ load4_a(out_image, y * stride + x) += load4_a(difference_image, y1 * stride + x);
+ }
+ }
+ float fac = 1.0f / (high - low);
+ for (int x = aligned_lowx; x < rect.z; x += 4) {
+ load4_a(out_image, y * stride + x) *= fac;
+ }
+ }
}
-ccl_device_inline void nlm_blur_horizontal(const float *ccl_restrict difference_image,
- float *out_image,
- int4 rect,
- int stride,
- int f)
+ccl_device_inline void nlm_blur_horizontal(
+ const float *ccl_restrict difference_image, float *out_image, int4 rect, int stride, int f)
{
- int aligned_lowx = round_down(rect.x, 4);
- for(int y = rect.y; y < rect.w; y++) {
- for(int x = aligned_lowx; x < rect.z; x += 4) {
- load4_a(out_image, y*stride + x) = make_float4(0.0f);
- }
- }
-
- for(int dx = -f; dx <= f; dx++) {
- aligned_lowx = round_down(rect.x - min(0, dx), 4);
- int highx = rect.z - max(0, dx);
- int4 lowx4 = make_int4(rect.x - min(0, dx));
- int4 highx4 = make_int4(rect.z - max(0, dx));
- for(int y = rect.y; y < rect.w; y++) {
- for(int x = aligned_lowx; x < highx; x += 4) {
- int4 x4 = make_int4(x) + make_int4(0, 1, 2, 3);
- int4 active = (x4 >= lowx4) & (x4 < highx4);
-
- float4 diff = load4_u(difference_image, y*stride + x + dx);
- load4_a(out_image, y*stride + x) += mask(active, diff);
- }
- }
- }
-
- aligned_lowx = round_down(rect.x, 4);
- for(int y = rect.y; y < rect.w; y++) {
- for(int x = aligned_lowx; x < rect.z; x += 4) {
- float4 x4 = make_float4(x) + make_float4(0.0f, 1.0f, 2.0f, 3.0f);
- float4 low = max(make_float4(rect.x), x4 - make_float4(f));
- float4 high = min(make_float4(rect.z), x4 + make_float4(f+1));
- load4_a(out_image, y*stride + x) *= rcp(high - low);
- }
- }
+ int aligned_lowx = round_down(rect.x, 4);
+ for (int y = rect.y; y < rect.w; y++) {
+ for (int x = aligned_lowx; x < rect.z; x += 4) {
+ load4_a(out_image, y * stride + x) = make_float4(0.0f);
+ }
+ }
+
+ for (int dx = -f; dx <= f; dx++) {
+ aligned_lowx = round_down(rect.x - min(0, dx), 4);
+ int highx = rect.z - max(0, dx);
+ int4 lowx4 = make_int4(rect.x - min(0, dx));
+ int4 highx4 = make_int4(rect.z - max(0, dx));
+ for (int y = rect.y; y < rect.w; y++) {
+ for (int x = aligned_lowx; x < highx; x += 4) {
+ int4 x4 = make_int4(x) + make_int4(0, 1, 2, 3);
+ int4 active = (x4 >= lowx4) & (x4 < highx4);
+
+ float4 diff = load4_u(difference_image, y * stride + x + dx);
+ load4_a(out_image, y * stride + x) += mask(active, diff);
+ }
+ }
+ }
+
+ aligned_lowx = round_down(rect.x, 4);
+ for (int y = rect.y; y < rect.w; y++) {
+ for (int x = aligned_lowx; x < rect.z; x += 4) {
+ float4 x4 = make_float4(x) + make_float4(0.0f, 1.0f, 2.0f, 3.0f);
+ float4 low = max(make_float4(rect.x), x4 - make_float4(f));
+ float4 high = min(make_float4(rect.z), x4 + make_float4(f + 1));
+ load4_a(out_image, y * stride + x) *= rcp(high - low);
+ }
+ }
}
-ccl_device_inline void kernel_filter_nlm_calc_weight(const float *ccl_restrict difference_image,
- float *out_image,
- int4 rect,
- int stride,
- int f)
+ccl_device_inline void kernel_filter_nlm_calc_weight(
+ const float *ccl_restrict difference_image, float *out_image, int4 rect, int stride, int f)
{
- nlm_blur_horizontal(difference_image, out_image, rect, stride, f);
-
- int aligned_lowx = round_down(rect.x, 4);
- for(int y = rect.y; y < rect.w; y++) {
- for(int x = aligned_lowx; x < rect.z; x += 4) {
- load4_a(out_image, y*stride + x) = fast_expf4(-max(load4_a(out_image, y*stride + x), make_float4(0.0f)));
- }
- }
+ nlm_blur_horizontal(difference_image, out_image, rect, stride, f);
+
+ int aligned_lowx = round_down(rect.x, 4);
+ for (int y = rect.y; y < rect.w; y++) {
+ for (int x = aligned_lowx; x < rect.z; x += 4) {
+ load4_a(out_image, y * stride + x) = fast_expf4(
+ -max(load4_a(out_image, y * stride + x), make_float4(0.0f)));
+ }
+ }
}
-ccl_device_inline void kernel_filter_nlm_update_output(int dx, int dy,
+ccl_device_inline void kernel_filter_nlm_update_output(int dx,
+ int dy,
const float *ccl_restrict difference_image,
const float *ccl_restrict image,
float *temp_image,
@@ -157,33 +153,36 @@ ccl_device_inline void kernel_filter_nlm_update_output(int dx, int dy,
int stride,
int f)
{
- nlm_blur_horizontal(difference_image, temp_image, rect, stride, f);
+ nlm_blur_horizontal(difference_image, temp_image, rect, stride, f);
- int aligned_lowx = round_down(rect.x, 4);
- for(int y = rect.y; y < rect.w; y++) {
- for(int x = aligned_lowx; x < rect.z; x += 4) {
- int4 x4 = make_int4(x) + make_int4(0, 1, 2, 3);
- int4 active = (x4 >= make_int4(rect.x)) & (x4 < make_int4(rect.z));
+ int aligned_lowx = round_down(rect.x, 4);
+ for (int y = rect.y; y < rect.w; y++) {
+ for (int x = aligned_lowx; x < rect.z; x += 4) {
+ int4 x4 = make_int4(x) + make_int4(0, 1, 2, 3);
+ int4 active = (x4 >= make_int4(rect.x)) & (x4 < make_int4(rect.z));
- int idx_p = y*stride + x, idx_q = (y+dy)*stride + (x+dx);
+ int idx_p = y * stride + x, idx_q = (y + dy) * stride + (x + dx);
- float4 weight = load4_a(temp_image, idx_p);
- load4_a(accum_image, idx_p) += mask(active, weight);
+ float4 weight = load4_a(temp_image, idx_p);
+ load4_a(accum_image, idx_p) += mask(active, weight);
- float4 val = load4_u(image, idx_q);
- if(channel_offset) {
- val += load4_u(image, idx_q + channel_offset);
- val += load4_u(image, idx_q + 2*channel_offset);
- val *= 1.0f/3.0f;
- }
+ float4 val = load4_u(image, idx_q);
+ if (channel_offset) {
+ val += load4_u(image, idx_q + channel_offset);
+ val += load4_u(image, idx_q + 2 * channel_offset);
+ val *= 1.0f / 3.0f;
+ }
- load4_a(out_image, idx_p) += mask(active, weight*val);
- }
- }
+ load4_a(out_image, idx_p) += mask(active, weight * val);
+ }
+ }
}
-ccl_device_inline void kernel_filter_nlm_construct_gramian(int dx, int dy, int t,
- const float *ccl_restrict difference_image,
+ccl_device_inline void kernel_filter_nlm_construct_gramian(int dx,
+ int dy,
+ int t,
+ const float *ccl_restrict
+ difference_image,
const float *ccl_restrict buffer,
float *transform,
int *rank,
@@ -191,40 +190,49 @@ ccl_device_inline void kernel_filter_nlm_construct_gramian(int dx, int dy, int t
float3 *XtWY,
int4 rect,
int4 filter_window,
- int stride, int f,
+ int stride,
+ int f,
int pass_stride,
int frame_offset,
bool use_time)
{
- int4 clip_area = rect_clip(rect, filter_window);
- /* fy and fy are in filter-window-relative coordinates, while x and y are in feature-window-relative coordinates. */
- for(int y = clip_area.y; y < clip_area.w; y++) {
- for(int x = clip_area.x; x < clip_area.z; x++) {
- const int low = max(rect.x, x-f);
- const int high = min(rect.z, x+f+1);
- float sum = 0.0f;
- for(int x1 = low; x1 < high; x1++) {
- sum += difference_image[y*stride + x1];
- }
- float weight = sum * (1.0f/(high - low));
-
- int storage_ofs = coord_to_local_index(filter_window, x, y);
- float *l_transform = transform + storage_ofs*TRANSFORM_SIZE;
- float *l_XtWX = XtWX + storage_ofs*XTWX_SIZE;
- float3 *l_XtWY = XtWY + storage_ofs*XTWY_SIZE;
- int *l_rank = rank + storage_ofs;
-
- kernel_filter_construct_gramian(x, y, 1,
- dx, dy, t,
- stride,
- pass_stride,
- frame_offset,
- use_time,
- buffer,
- l_transform, l_rank,
- weight, l_XtWX, l_XtWY, 0);
- }
- }
+ int4 clip_area = rect_clip(rect, filter_window);
+ /* fy and fy are in filter-window-relative coordinates, while x and y are in feature-window-relative coordinates. */
+ for (int y = clip_area.y; y < clip_area.w; y++) {
+ for (int x = clip_area.x; x < clip_area.z; x++) {
+ const int low = max(rect.x, x - f);
+ const int high = min(rect.z, x + f + 1);
+ float sum = 0.0f;
+ for (int x1 = low; x1 < high; x1++) {
+ sum += difference_image[y * stride + x1];
+ }
+ float weight = sum * (1.0f / (high - low));
+
+ int storage_ofs = coord_to_local_index(filter_window, x, y);
+ float *l_transform = transform + storage_ofs * TRANSFORM_SIZE;
+ float *l_XtWX = XtWX + storage_ofs * XTWX_SIZE;
+ float3 *l_XtWY = XtWY + storage_ofs * XTWY_SIZE;
+ int *l_rank = rank + storage_ofs;
+
+ kernel_filter_construct_gramian(x,
+ y,
+ 1,
+ dx,
+ dy,
+ t,
+ stride,
+ pass_stride,
+ frame_offset,
+ use_time,
+ buffer,
+ l_transform,
+ l_rank,
+ weight,
+ l_XtWX,
+ l_XtWY,
+ 0);
+ }
+ }
}
ccl_device_inline void kernel_filter_nlm_normalize(float *out_image,
@@ -232,11 +240,11 @@ ccl_device_inline void kernel_filter_nlm_normalize(float *out_image,
int4 rect,
int w)
{
- for(int y = rect.y; y < rect.w; y++) {
- for(int x = rect.x; x < rect.z; x++) {
- out_image[y*w+x] /= accum_image[y*w+x];
- }
- }
+ for (int y = rect.y; y < rect.w; y++) {
+ for (int x = rect.x; x < rect.z; x++) {
+ out_image[y * w + x] /= accum_image[y * w + x];
+ }
+ }
}
#undef load4_a
diff --git a/intern/cycles/kernel/filter/filter_nlm_gpu.h b/intern/cycles/kernel/filter/filter_nlm_gpu.h
index 12636393243..650c743f34f 100644
--- a/intern/cycles/kernel/filter/filter_nlm_gpu.h
+++ b/intern/cycles/kernel/filter/filter_nlm_gpu.h
@@ -24,203 +24,232 @@ CCL_NAMESPACE_BEGIN
* Window is the rect that should be processed.
* co is filled with (x, y, dx, dy).
*/
-ccl_device_inline bool get_nlm_coords_window(int w, int h, int r, int stride,
- int4 *rect, int4 *co, int *ofs,
- int4 window)
+ccl_device_inline bool get_nlm_coords_window(
+ int w, int h, int r, int stride, int4 *rect, int4 *co, int *ofs, int4 window)
{
- /* Determine the pixel offset that this thread should apply. */
- int s = 2*r+1;
- int si = ccl_global_id(1);
- int sx = si % s;
- int sy = si / s;
- if(sy >= s) {
- return false;
- }
-
- /* Pixels still need to lie inside the denoising buffer after applying the offset,
- * so determine the area for which this is the case. */
- int dx = sx - r;
- int dy = sy - r;
-
- *rect = make_int4(max(0, -dx), max(0, -dy),
- w - max(0, dx), h - max(0, dy));
-
- /* Find the intersection of the area that we want to process (window) and the area
- * that can be processed (rect) to get the final area for this offset. */
- int4 clip_area = rect_clip(window, *rect);
-
- /* If the radius is larger than one of the sides of the window,
- * there will be shifts for which there is no usable pixel at all. */
- if(!rect_is_valid(clip_area)) {
- return false;
- }
-
- /* Map the linear thread index to pixels inside the clip area. */
- int x, y;
- if(!local_index_to_coord(clip_area, ccl_global_id(0), &x, &y)) {
- return false;
- }
-
- *co = make_int4(x, y, dx, dy);
-
- *ofs = (sy*s + sx) * stride;
-
- return true;
+ /* Determine the pixel offset that this thread should apply. */
+ int s = 2 * r + 1;
+ int si = ccl_global_id(1);
+ int sx = si % s;
+ int sy = si / s;
+ if (sy >= s) {
+ return false;
+ }
+
+ /* Pixels still need to lie inside the denoising buffer after applying the offset,
+ * so determine the area for which this is the case. */
+ int dx = sx - r;
+ int dy = sy - r;
+
+ *rect = make_int4(max(0, -dx), max(0, -dy), w - max(0, dx), h - max(0, dy));
+
+ /* Find the intersection of the area that we want to process (window) and the area
+ * that can be processed (rect) to get the final area for this offset. */
+ int4 clip_area = rect_clip(window, *rect);
+
+ /* If the radius is larger than one of the sides of the window,
+ * there will be shifts for which there is no usable pixel at all. */
+ if (!rect_is_valid(clip_area)) {
+ return false;
+ }
+
+ /* Map the linear thread index to pixels inside the clip area. */
+ int x, y;
+ if (!local_index_to_coord(clip_area, ccl_global_id(0), &x, &y)) {
+ return false;
+ }
+
+ *co = make_int4(x, y, dx, dy);
+
+ *ofs = (sy * s + sx) * stride;
+
+ return true;
}
-ccl_device_inline bool get_nlm_coords(int w, int h, int r, int stride,
- int4 *rect, int4 *co, int *ofs)
+ccl_device_inline bool get_nlm_coords(
+ int w, int h, int r, int stride, int4 *rect, int4 *co, int *ofs)
{
- return get_nlm_coords_window(w, h, r, stride, rect, co, ofs, make_int4(0, 0, w, h));
+ return get_nlm_coords_window(w, h, r, stride, rect, co, ofs, make_int4(0, 0, w, h));
}
-ccl_device_inline void kernel_filter_nlm_calc_difference(int x, int y,
- int dx, int dy,
- const ccl_global float *ccl_restrict weight_image,
- const ccl_global float *ccl_restrict variance_image,
- const ccl_global float *ccl_restrict scale_image,
- ccl_global float *difference_image,
- int4 rect, int stride,
- int channel_offset,
- int frame_offset,
- float a, float k_2)
+ccl_device_inline void kernel_filter_nlm_calc_difference(
+ int x,
+ int y,
+ int dx,
+ int dy,
+ const ccl_global float *ccl_restrict weight_image,
+ const ccl_global float *ccl_restrict variance_image,
+ const ccl_global float *ccl_restrict scale_image,
+ ccl_global float *difference_image,
+ int4 rect,
+ int stride,
+ int channel_offset,
+ int frame_offset,
+ float a,
+ float k_2)
{
- int idx_p = y*stride + x, idx_q = (y+dy)*stride + (x+dx) + frame_offset;
- int numChannels = channel_offset? 3 : 1;
-
- float diff = 0.0f;
- float scale_fac = 1.0f;
- if(scale_image) {
- scale_fac = clamp(scale_image[idx_p] / scale_image[idx_q], 0.25f, 4.0f);
- }
-
- for(int c = 0; c < numChannels; c++, idx_p += channel_offset, idx_q += channel_offset) {
- float cdiff = weight_image[idx_p] - scale_fac*weight_image[idx_q];
- float pvar = variance_image[idx_p];
- float qvar = sqr(scale_fac)*variance_image[idx_q];
- diff += (cdiff*cdiff - a*(pvar + min(pvar, qvar))) / (1e-8f + k_2*(pvar+qvar));
- }
- if(numChannels > 1) {
- diff *= 1.0f/numChannels;
- }
- difference_image[y*stride + x] = diff;
+ int idx_p = y * stride + x, idx_q = (y + dy) * stride + (x + dx) + frame_offset;
+ int numChannels = channel_offset ? 3 : 1;
+
+ float diff = 0.0f;
+ float scale_fac = 1.0f;
+ if (scale_image) {
+ scale_fac = clamp(scale_image[idx_p] / scale_image[idx_q], 0.25f, 4.0f);
+ }
+
+ for (int c = 0; c < numChannels; c++, idx_p += channel_offset, idx_q += channel_offset) {
+ float cdiff = weight_image[idx_p] - scale_fac * weight_image[idx_q];
+ float pvar = variance_image[idx_p];
+ float qvar = sqr(scale_fac) * variance_image[idx_q];
+ diff += (cdiff * cdiff - a * (pvar + min(pvar, qvar))) / (1e-8f + k_2 * (pvar + qvar));
+ }
+ if (numChannels > 1) {
+ diff *= 1.0f / numChannels;
+ }
+ difference_image[y * stride + x] = diff;
}
-ccl_device_inline void kernel_filter_nlm_blur(int x, int y,
- const ccl_global float *ccl_restrict difference_image,
+ccl_device_inline void kernel_filter_nlm_blur(int x,
+ int y,
+ const ccl_global float *ccl_restrict
+ difference_image,
ccl_global float *out_image,
- int4 rect, int stride, int f)
+ int4 rect,
+ int stride,
+ int f)
{
- float sum = 0.0f;
- const int low = max(rect.y, y-f);
- const int high = min(rect.w, y+f+1);
- for(int y1 = low; y1 < high; y1++) {
- sum += difference_image[y1*stride + x];
- }
- sum *= 1.0f/(high-low);
- out_image[y*stride + x] = sum;
+ float sum = 0.0f;
+ const int low = max(rect.y, y - f);
+ const int high = min(rect.w, y + f + 1);
+ for (int y1 = low; y1 < high; y1++) {
+ sum += difference_image[y1 * stride + x];
+ }
+ sum *= 1.0f / (high - low);
+ out_image[y * stride + x] = sum;
}
-ccl_device_inline void kernel_filter_nlm_calc_weight(int x, int y,
- const ccl_global float *ccl_restrict difference_image,
+ccl_device_inline void kernel_filter_nlm_calc_weight(int x,
+ int y,
+ const ccl_global float *ccl_restrict
+ difference_image,
ccl_global float *out_image,
- int4 rect, int stride, int f)
+ int4 rect,
+ int stride,
+ int f)
{
- float sum = 0.0f;
- const int low = max(rect.x, x-f);
- const int high = min(rect.z, x+f+1);
- for(int x1 = low; x1 < high; x1++) {
- sum += difference_image[y*stride + x1];
- }
- sum *= 1.0f/(high-low);
- out_image[y*stride + x] = fast_expf(-max(sum, 0.0f));
+ float sum = 0.0f;
+ const int low = max(rect.x, x - f);
+ const int high = min(rect.z, x + f + 1);
+ for (int x1 = low; x1 < high; x1++) {
+ sum += difference_image[y * stride + x1];
+ }
+ sum *= 1.0f / (high - low);
+ out_image[y * stride + x] = fast_expf(-max(sum, 0.0f));
}
-ccl_device_inline void kernel_filter_nlm_update_output(int x, int y,
- int dx, int dy,
- const ccl_global float *ccl_restrict difference_image,
+ccl_device_inline void kernel_filter_nlm_update_output(int x,
+ int y,
+ int dx,
+ int dy,
+ const ccl_global float *ccl_restrict
+ difference_image,
const ccl_global float *ccl_restrict image,
ccl_global float *out_image,
ccl_global float *accum_image,
- int4 rect, int channel_offset,
- int stride, int f)
+ int4 rect,
+ int channel_offset,
+ int stride,
+ int f)
{
- float sum = 0.0f;
- const int low = max(rect.x, x-f);
- const int high = min(rect.z, x+f+1);
- for(int x1 = low; x1 < high; x1++) {
- sum += difference_image[y*stride + x1];
- }
- sum *= 1.0f/(high-low);
-
- int idx_p = y*stride + x, idx_q = (y+dy)*stride + (x+dx);
- if(out_image) {
- atomic_add_and_fetch_float(accum_image + idx_p, sum);
-
- float val = image[idx_q];
- if(channel_offset) {
- val += image[idx_q + channel_offset];
- val += image[idx_q + 2*channel_offset];
- val *= 1.0f/3.0f;
- }
- atomic_add_and_fetch_float(out_image + idx_p, sum*val);
- }
- else {
- accum_image[idx_p] = sum;
- }
+ float sum = 0.0f;
+ const int low = max(rect.x, x - f);
+ const int high = min(rect.z, x + f + 1);
+ for (int x1 = low; x1 < high; x1++) {
+ sum += difference_image[y * stride + x1];
+ }
+ sum *= 1.0f / (high - low);
+
+ int idx_p = y * stride + x, idx_q = (y + dy) * stride + (x + dx);
+ if (out_image) {
+ atomic_add_and_fetch_float(accum_image + idx_p, sum);
+
+ float val = image[idx_q];
+ if (channel_offset) {
+ val += image[idx_q + channel_offset];
+ val += image[idx_q + 2 * channel_offset];
+ val *= 1.0f / 3.0f;
+ }
+ atomic_add_and_fetch_float(out_image + idx_p, sum * val);
+ }
+ else {
+ accum_image[idx_p] = sum;
+ }
}
-ccl_device_inline void kernel_filter_nlm_construct_gramian(int x, int y,
- int dx, int dy, int t,
- const ccl_global float *ccl_restrict difference_image,
- const ccl_global float *ccl_restrict buffer,
- const ccl_global float *ccl_restrict transform,
- ccl_global int *rank,
- ccl_global float *XtWX,
- ccl_global float3 *XtWY,
- int4 rect,
- int4 filter_window,
- int stride, int f,
- int pass_stride,
- int frame_offset,
- bool use_time,
- int localIdx)
+ccl_device_inline void kernel_filter_nlm_construct_gramian(
+ int x,
+ int y,
+ int dx,
+ int dy,
+ int t,
+ const ccl_global float *ccl_restrict difference_image,
+ const ccl_global float *ccl_restrict buffer,
+ const ccl_global float *ccl_restrict transform,
+ ccl_global int *rank,
+ ccl_global float *XtWX,
+ ccl_global float3 *XtWY,
+ int4 rect,
+ int4 filter_window,
+ int stride,
+ int f,
+ int pass_stride,
+ int frame_offset,
+ bool use_time,
+ int localIdx)
{
- const int low = max(rect.x, x-f);
- const int high = min(rect.z, x+f+1);
- float sum = 0.0f;
- for(int x1 = low; x1 < high; x1++) {
- sum += difference_image[y*stride + x1];
- }
- float weight = sum * (1.0f/(high - low));
-
- /* Reconstruction data is only stored for pixels inside the filter window,
- * so compute the pixels's index in there. */
- int storage_ofs = coord_to_local_index(filter_window, x, y);
- transform += storage_ofs;
- rank += storage_ofs;
- XtWX += storage_ofs;
- XtWY += storage_ofs;
-
- kernel_filter_construct_gramian(x, y,
- rect_size(filter_window),
- dx, dy, t,
- stride,
- pass_stride,
- frame_offset,
- use_time,
- buffer,
- transform, rank,
- weight, XtWX, XtWY,
- localIdx);
+ const int low = max(rect.x, x - f);
+ const int high = min(rect.z, x + f + 1);
+ float sum = 0.0f;
+ for (int x1 = low; x1 < high; x1++) {
+ sum += difference_image[y * stride + x1];
+ }
+ float weight = sum * (1.0f / (high - low));
+
+ /* Reconstruction data is only stored for pixels inside the filter window,
+ * so compute the pixels's index in there. */
+ int storage_ofs = coord_to_local_index(filter_window, x, y);
+ transform += storage_ofs;
+ rank += storage_ofs;
+ XtWX += storage_ofs;
+ XtWY += storage_ofs;
+
+ kernel_filter_construct_gramian(x,
+ y,
+ rect_size(filter_window),
+ dx,
+ dy,
+ t,
+ stride,
+ pass_stride,
+ frame_offset,
+ use_time,
+ buffer,
+ transform,
+ rank,
+ weight,
+ XtWX,
+ XtWY,
+ localIdx);
}
-ccl_device_inline void kernel_filter_nlm_normalize(int x, int y,
+ccl_device_inline void kernel_filter_nlm_normalize(int x,
+ int y,
ccl_global float *out_image,
- const ccl_global float *ccl_restrict accum_image,
+ const ccl_global float *ccl_restrict
+ accum_image,
int stride)
{
- out_image[y*stride + x] /= accum_image[y*stride + x];
+ out_image[y * stride + x] /= accum_image[y * stride + x];
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/filter/filter_prefilter.h b/intern/cycles/kernel/filter/filter_prefilter.h
index e24f4feb28d..8211311313d 100644
--- a/intern/cycles/kernel/filter/filter_prefilter.h
+++ b/intern/cycles/kernel/filter/filter_prefilter.h
@@ -27,7 +27,8 @@ CCL_NAMESPACE_BEGIN
*/
ccl_device void kernel_filter_divide_shadow(int sample,
CCL_FILTER_TILE_INFO,
- int x, int y,
+ int x,
+ int y,
ccl_global float *unfilteredA,
ccl_global float *unfilteredB,
ccl_global float *sampleVariance,
@@ -37,37 +38,39 @@ ccl_device void kernel_filter_divide_shadow(int sample,
int buffer_pass_stride,
int buffer_denoising_offset)
{
- int xtile = (x < tile_info->x[1])? 0: ((x < tile_info->x[2])? 1: 2);
- int ytile = (y < tile_info->y[1])? 0: ((y < tile_info->y[2])? 1: 2);
- int tile = ytile*3+xtile;
+ int xtile = (x < tile_info->x[1]) ? 0 : ((x < tile_info->x[2]) ? 1 : 2);
+ int ytile = (y < tile_info->y[1]) ? 0 : ((y < tile_info->y[2]) ? 1 : 2);
+ int tile = ytile * 3 + xtile;
- int offset = tile_info->offsets[tile];
- int stride = tile_info->strides[tile];
- const ccl_global float *ccl_restrict center_buffer = (ccl_global float*) ccl_get_tile_buffer(tile);
- center_buffer += (y*stride + x + offset)*buffer_pass_stride;
- center_buffer += buffer_denoising_offset + 14;
+ int offset = tile_info->offsets[tile];
+ int stride = tile_info->strides[tile];
+ const ccl_global float *ccl_restrict center_buffer = (ccl_global float *)ccl_get_tile_buffer(
+ tile);
+ center_buffer += (y * stride + x + offset) * buffer_pass_stride;
+ center_buffer += buffer_denoising_offset + 14;
- int buffer_w = align_up(rect.z - rect.x, 4);
- int idx = (y-rect.y)*buffer_w + (x - rect.x);
- unfilteredA[idx] = center_buffer[1] / max(center_buffer[0], 1e-7f);
- unfilteredB[idx] = center_buffer[4] / max(center_buffer[3], 1e-7f);
+ int buffer_w = align_up(rect.z - rect.x, 4);
+ int idx = (y - rect.y) * buffer_w + (x - rect.x);
+ unfilteredA[idx] = center_buffer[1] / max(center_buffer[0], 1e-7f);
+ unfilteredB[idx] = center_buffer[4] / max(center_buffer[3], 1e-7f);
- float varA = center_buffer[2];
- float varB = center_buffer[5];
- int odd_sample = (sample+1)/2;
- int even_sample = sample/2;
+ float varA = center_buffer[2];
+ float varB = center_buffer[5];
+ int odd_sample = (sample + 1) / 2;
+ int even_sample = sample / 2;
- /* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
- * update does not work efficiently with atomics in the kernel. */
- varA = max(0.0f, varA - unfilteredA[idx]*unfilteredA[idx]*odd_sample);
- varB = max(0.0f, varB - unfilteredB[idx]*unfilteredB[idx]*even_sample);
+ /* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
+ * update does not work efficiently with atomics in the kernel. */
+ varA = max(0.0f, varA - unfilteredA[idx] * unfilteredA[idx] * odd_sample);
+ varB = max(0.0f, varB - unfilteredB[idx] * unfilteredB[idx] * even_sample);
- varA /= max(odd_sample - 1, 1);
- varB /= max(even_sample - 1, 1);
+ varA /= max(odd_sample - 1, 1);
+ varB /= max(even_sample - 1, 1);
- sampleVariance[idx] = 0.5f*(varA + varB) / sample;
- sampleVarianceV[idx] = 0.5f * (varA - varB) * (varA - varB) / (sample*sample);
- bufferVariance[idx] = 0.5f * (unfilteredA[idx] - unfilteredB[idx]) * (unfilteredA[idx] - unfilteredB[idx]);
+ sampleVariance[idx] = 0.5f * (varA + varB) / sample;
+ sampleVarianceV[idx] = 0.5f * (varA - varB) * (varA - varB) / (sample * sample);
+ bufferVariance[idx] = 0.5f * (unfilteredA[idx] - unfilteredB[idx]) *
+ (unfilteredA[idx] - unfilteredB[idx]);
}
/* Load a regular feature from the render buffers into the denoise buffer.
@@ -80,55 +83,65 @@ ccl_device void kernel_filter_divide_shadow(int sample,
*/
ccl_device void kernel_filter_get_feature(int sample,
CCL_FILTER_TILE_INFO,
- int m_offset, int v_offset,
- int x, int y,
+ int m_offset,
+ int v_offset,
+ int x,
+ int y,
ccl_global float *mean,
ccl_global float *variance,
float scale,
- int4 rect, int buffer_pass_stride,
+ int4 rect,
+ int buffer_pass_stride,
int buffer_denoising_offset)
{
- int xtile = (x < tile_info->x[1])? 0: ((x < tile_info->x[2])? 1: 2);
- int ytile = (y < tile_info->y[1])? 0: ((y < tile_info->y[2])? 1: 2);
- int tile = ytile*3+xtile;
- ccl_global float *center_buffer = ((ccl_global float*) ccl_get_tile_buffer(tile)) + (tile_info->offsets[tile] + y*tile_info->strides[tile] + x)*buffer_pass_stride + buffer_denoising_offset;
+ int xtile = (x < tile_info->x[1]) ? 0 : ((x < tile_info->x[2]) ? 1 : 2);
+ int ytile = (y < tile_info->y[1]) ? 0 : ((y < tile_info->y[2]) ? 1 : 2);
+ int tile = ytile * 3 + xtile;
+ ccl_global float *center_buffer = ((ccl_global float *)ccl_get_tile_buffer(tile)) +
+ (tile_info->offsets[tile] + y * tile_info->strides[tile] + x) *
+ buffer_pass_stride +
+ buffer_denoising_offset;
- int buffer_w = align_up(rect.z - rect.x, 4);
- int idx = (y-rect.y)*buffer_w + (x - rect.x);
+ int buffer_w = align_up(rect.z - rect.x, 4);
+ int idx = (y - rect.y) * buffer_w + (x - rect.x);
- float val = scale * center_buffer[m_offset];
- mean[idx] = val;
+ float val = scale * center_buffer[m_offset];
+ mean[idx] = val;
- if(v_offset >= 0) {
- if(sample > 1) {
- /* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
- * update does not work efficiently with atomics in the kernel. */
- variance[idx] = max(0.0f, (center_buffer[v_offset] - val*val*sample) / (sample * (sample-1)));
- }
- else {
- /* Can't compute variance with single sample, just set it very high. */
- variance[idx] = 1e10f;
- }
- }
+ if (v_offset >= 0) {
+ if (sample > 1) {
+ /* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
+ * update does not work efficiently with atomics in the kernel. */
+ variance[idx] = max(
+ 0.0f, (center_buffer[v_offset] - val * val * sample) / (sample * (sample - 1)));
+ }
+ else {
+ /* Can't compute variance with single sample, just set it very high. */
+ variance[idx] = 1e10f;
+ }
+ }
}
ccl_device void kernel_filter_write_feature(int sample,
- int x, int y,
+ int x,
+ int y,
int4 buffer_params,
ccl_global float *from,
ccl_global float *buffer,
int out_offset,
int4 rect)
{
- ccl_global float *combined_buffer = buffer + (y*buffer_params.y + x + buffer_params.x)*buffer_params.z;
+ ccl_global float *combined_buffer = buffer + (y * buffer_params.y + x + buffer_params.x) *
+ buffer_params.z;
- int buffer_w = align_up(rect.z - rect.x, 4);
- int idx = (y-rect.y)*buffer_w + (x - rect.x);
+ int buffer_w = align_up(rect.z - rect.x, 4);
+ int idx = (y - rect.y) * buffer_w + (x - rect.x);
- combined_buffer[out_offset] = from[idx];
+ combined_buffer[out_offset] = from[idx];
}
-ccl_device void kernel_filter_detect_outliers(int x, int y,
+ccl_device void kernel_filter_detect_outliers(int x,
+ int y,
ccl_global float *image,
ccl_global float *variance,
ccl_global float *depth,
@@ -136,123 +149,131 @@ ccl_device void kernel_filter_detect_outliers(int x, int y,
int4 rect,
int pass_stride)
{
- int buffer_w = align_up(rect.z - rect.x, 4);
+ int buffer_w = align_up(rect.z - rect.x, 4);
- int n = 0;
- float values[25];
- float pixel_variance, max_variance = 0.0f;
- for(int y1 = max(y-2, rect.y); y1 < min(y+3, rect.w); y1++) {
- for(int x1 = max(x-2, rect.x); x1 < min(x+3, rect.z); x1++) {
- int idx = (y1-rect.y)*buffer_w + (x1-rect.x);
- float3 color = make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]);
- color = max(color, make_float3(0.0f, 0.0f, 0.0f));
- float L = average(color);
+ int n = 0;
+ float values[25];
+ float pixel_variance, max_variance = 0.0f;
+ for (int y1 = max(y - 2, rect.y); y1 < min(y + 3, rect.w); y1++) {
+ for (int x1 = max(x - 2, rect.x); x1 < min(x + 3, rect.z); x1++) {
+ int idx = (y1 - rect.y) * buffer_w + (x1 - rect.x);
+ float3 color = make_float3(
+ image[idx], image[idx + pass_stride], image[idx + 2 * pass_stride]);
+ color = max(color, make_float3(0.0f, 0.0f, 0.0f));
+ float L = average(color);
- /* Find the position of L. */
- int i;
- for(i = 0; i < n; i++) {
- if(values[i] > L) break;
- }
- /* Make space for L by shifting all following values to the right. */
- for(int j = n; j > i; j--) {
- values[j] = values[j-1];
- }
- /* Insert L. */
- values[i] = L;
- n++;
+ /* Find the position of L. */
+ int i;
+ for (i = 0; i < n; i++) {
+ if (values[i] > L)
+ break;
+ }
+ /* Make space for L by shifting all following values to the right. */
+ for (int j = n; j > i; j--) {
+ values[j] = values[j - 1];
+ }
+ /* Insert L. */
+ values[i] = L;
+ n++;
- float3 pixel_var = make_float3(variance[idx], variance[idx+pass_stride], variance[idx+2*pass_stride]);
- float var = average(pixel_var);
- if((x1 == x) && (y1 == y)) {
- pixel_variance = (pixel_var.x < 0.0f || pixel_var.y < 0.0f || pixel_var.z < 0.0f)? -1.0f : var;
- }
- else {
- max_variance = max(max_variance, var);
- }
- }
- }
+ float3 pixel_var = make_float3(
+ variance[idx], variance[idx + pass_stride], variance[idx + 2 * pass_stride]);
+ float var = average(pixel_var);
+ if ((x1 == x) && (y1 == y)) {
+ pixel_variance = (pixel_var.x < 0.0f || pixel_var.y < 0.0f || pixel_var.z < 0.0f) ? -1.0f :
+ var;
+ }
+ else {
+ max_variance = max(max_variance, var);
+ }
+ }
+ }
- max_variance += 1e-4f;
+ max_variance += 1e-4f;
- int idx = (y-rect.y)*buffer_w + (x-rect.x);
- float3 color = make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]);
- color = max(color, make_float3(0.0f, 0.0f, 0.0f));
- float L = average(color);
+ int idx = (y - rect.y) * buffer_w + (x - rect.x);
+ float3 color = make_float3(image[idx], image[idx + pass_stride], image[idx + 2 * pass_stride]);
+ color = max(color, make_float3(0.0f, 0.0f, 0.0f));
+ float L = average(color);
- float ref = 2.0f*values[(int)(n*0.75f)];
+ float ref = 2.0f * values[(int)(n * 0.75f)];
- /* Slightly offset values to avoid false positives in (almost) black areas. */
- max_variance += 1e-5f;
- ref -= 1e-5f;
+ /* Slightly offset values to avoid false positives in (almost) black areas. */
+ max_variance += 1e-5f;
+ ref -= 1e-5f;
- if(L > ref) {
- /* The pixel appears to be an outlier.
- * However, it may just be a legitimate highlight. Therefore, it is checked how likely it is that the pixel
- * should actually be at the reference value:
- * If the reference is within the 3-sigma interval, the pixel is assumed to be a statistical outlier.
- * Otherwise, it is very unlikely that the pixel should be darker, which indicates a legitimate highlight.
- */
+ if (L > ref) {
+ /* The pixel appears to be an outlier.
+ * However, it may just be a legitimate highlight. Therefore, it is checked how likely it is that the pixel
+ * should actually be at the reference value:
+ * If the reference is within the 3-sigma interval, the pixel is assumed to be a statistical outlier.
+ * Otherwise, it is very unlikely that the pixel should be darker, which indicates a legitimate highlight.
+ */
- if(pixel_variance < 0.0f || pixel_variance > 9.0f * max_variance) {
- depth[idx] = -depth[idx];
- color *= ref/L;
- variance[idx] = variance[idx + pass_stride] = variance[idx + 2*pass_stride] = max_variance;
- }
- else {
- float stddev = sqrtf(pixel_variance);
- if(L - 3*stddev < ref) {
- /* The pixel is an outlier, so negate the depth value to mark it as one.
- * Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */
- depth[idx] = -depth[idx];
- float fac = ref/L;
- color *= fac;
- variance[idx ] *= fac*fac;
- variance[idx + pass_stride] *= fac*fac;
- variance[idx+2*pass_stride] *= fac*fac;
- }
- }
- }
- out[idx ] = color.x;
- out[idx + pass_stride] = color.y;
- out[idx+2*pass_stride] = color.z;
+ if (pixel_variance < 0.0f || pixel_variance > 9.0f * max_variance) {
+ depth[idx] = -depth[idx];
+ color *= ref / L;
+ variance[idx] = variance[idx + pass_stride] = variance[idx + 2 * pass_stride] = max_variance;
+ }
+ else {
+ float stddev = sqrtf(pixel_variance);
+ if (L - 3 * stddev < ref) {
+ /* The pixel is an outlier, so negate the depth value to mark it as one.
+ * Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */
+ depth[idx] = -depth[idx];
+ float fac = ref / L;
+ color *= fac;
+ variance[idx] *= fac * fac;
+ variance[idx + pass_stride] *= fac * fac;
+ variance[idx + 2 * pass_stride] *= fac * fac;
+ }
+ }
+ }
+ out[idx] = color.x;
+ out[idx + pass_stride] = color.y;
+ out[idx + 2 * pass_stride] = color.z;
}
/* Combine A/B buffers.
* Calculates the combined mean and the buffer variance. */
-ccl_device void kernel_filter_combine_halves(int x, int y,
+ccl_device void kernel_filter_combine_halves(int x,
+ int y,
ccl_global float *mean,
ccl_global float *variance,
ccl_global float *a,
ccl_global float *b,
- int4 rect, int r)
+ int4 rect,
+ int r)
{
- int buffer_w = align_up(rect.z - rect.x, 4);
- int idx = (y-rect.y)*buffer_w + (x - rect.x);
+ int buffer_w = align_up(rect.z - rect.x, 4);
+ int idx = (y - rect.y) * buffer_w + (x - rect.x);
- if(mean) mean[idx] = 0.5f * (a[idx]+b[idx]);
- if(variance) {
- if(r == 0) variance[idx] = 0.25f * (a[idx]-b[idx])*(a[idx]-b[idx]);
- else {
- variance[idx] = 0.0f;
- float values[25];
- int numValues = 0;
- for(int py = max(y-r, rect.y); py < min(y+r+1, rect.w); py++) {
- for(int px = max(x-r, rect.x); px < min(x+r+1, rect.z); px++) {
- int pidx = (py-rect.y)*buffer_w + (px-rect.x);
- values[numValues++] = 0.25f * (a[pidx]-b[pidx])*(a[pidx]-b[pidx]);
- }
- }
- /* Insertion-sort the variances (fast enough for 25 elements). */
- for(int i = 1; i < numValues; i++) {
- float v = values[i];
- int j;
- for(j = i-1; j >= 0 && values[j] > v; j--)
- values[j+1] = values[j];
- values[j+1] = v;
- }
- variance[idx] = values[(7*numValues)/8];
- }
- }
+ if (mean)
+ mean[idx] = 0.5f * (a[idx] + b[idx]);
+ if (variance) {
+ if (r == 0)
+ variance[idx] = 0.25f * (a[idx] - b[idx]) * (a[idx] - b[idx]);
+ else {
+ variance[idx] = 0.0f;
+ float values[25];
+ int numValues = 0;
+ for (int py = max(y - r, rect.y); py < min(y + r + 1, rect.w); py++) {
+ for (int px = max(x - r, rect.x); px < min(x + r + 1, rect.z); px++) {
+ int pidx = (py - rect.y) * buffer_w + (px - rect.x);
+ values[numValues++] = 0.25f * (a[pidx] - b[pidx]) * (a[pidx] - b[pidx]);
+ }
+ }
+ /* Insertion-sort the variances (fast enough for 25 elements). */
+ for (int i = 1; i < numValues; i++) {
+ float v = values[i];
+ int j;
+ for (j = i - 1; j >= 0 && values[j] > v; j--)
+ values[j + 1] = values[j];
+ values[j + 1] = v;
+ }
+ variance[idx] = values[(7 * numValues) / 8];
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/filter/filter_reconstruction.h b/intern/cycles/kernel/filter/filter_reconstruction.h
index ceda8f71f98..850f20584da 100644
--- a/intern/cycles/kernel/filter/filter_reconstruction.h
+++ b/intern/cycles/kernel/filter/filter_reconstruction.h
@@ -16,63 +16,75 @@
CCL_NAMESPACE_BEGIN
-ccl_device_inline void kernel_filter_construct_gramian(int x, int y,
+ccl_device_inline void kernel_filter_construct_gramian(int x,
+ int y,
int storage_stride,
- int dx, int dy, int t,
+ int dx,
+ int dy,
+ int t,
int buffer_stride,
int pass_stride,
int frame_offset,
bool use_time,
const ccl_global float *ccl_restrict buffer,
- const ccl_global float *ccl_restrict transform,
+ const ccl_global float *ccl_restrict
+ transform,
ccl_global int *rank,
float weight,
ccl_global float *XtWX,
ccl_global float3 *XtWY,
int localIdx)
{
- if(weight < 1e-3f) {
- return;
- }
+ if (weight < 1e-3f) {
+ return;
+ }
- int p_offset = y * buffer_stride + x;
- int q_offset = (y+dy) * buffer_stride + (x+dx) + frame_offset;
+ int p_offset = y * buffer_stride + x;
+ int q_offset = (y + dy) * buffer_stride + (x + dx) + frame_offset;
#ifdef __KERNEL_GPU__
- const int stride = storage_stride;
+ const int stride = storage_stride;
#else
- const int stride = 1;
- (void) storage_stride;
+ const int stride = 1;
+ (void)storage_stride;
#endif
#ifdef __KERNEL_CUDA__
- ccl_local float shared_design_row[(DENOISE_FEATURES+1)*CCL_MAX_LOCAL_SIZE];
- ccl_local_param float *design_row = shared_design_row + localIdx*(DENOISE_FEATURES+1);
+ ccl_local float shared_design_row[(DENOISE_FEATURES + 1) * CCL_MAX_LOCAL_SIZE];
+ ccl_local_param float *design_row = shared_design_row + localIdx * (DENOISE_FEATURES + 1);
#else
- float design_row[DENOISE_FEATURES+1];
+ float design_row[DENOISE_FEATURES + 1];
#endif
- float3 q_color = filter_get_color(buffer + q_offset, pass_stride);
+ float3 q_color = filter_get_color(buffer + q_offset, pass_stride);
- /* If the pixel was flagged as an outlier during prefiltering, skip it. */
- if(ccl_get_feature(buffer + q_offset, 0) < 0.0f) {
- return;
- }
+ /* If the pixel was flagged as an outlier during prefiltering, skip it. */
+ if (ccl_get_feature(buffer + q_offset, 0) < 0.0f) {
+ return;
+ }
- filter_get_design_row_transform(make_int3(x, y, t), buffer + p_offset,
- make_int3(x+dx, y+dy, t), buffer + q_offset,
- pass_stride, *rank, design_row, transform, stride, use_time);
+ filter_get_design_row_transform(make_int3(x, y, t),
+ buffer + p_offset,
+ make_int3(x + dx, y + dy, t),
+ buffer + q_offset,
+ pass_stride,
+ *rank,
+ design_row,
+ transform,
+ stride,
+ use_time);
#ifdef __KERNEL_GPU__
- math_trimatrix_add_gramian_strided(XtWX, (*rank)+1, design_row, weight, stride);
- math_vec3_add_strided(XtWY, (*rank)+1, design_row, weight * q_color, stride);
+ math_trimatrix_add_gramian_strided(XtWX, (*rank) + 1, design_row, weight, stride);
+ math_vec3_add_strided(XtWY, (*rank) + 1, design_row, weight * q_color, stride);
#else
- math_trimatrix_add_gramian(XtWX, (*rank)+1, design_row, weight);
- math_vec3_add(XtWY, (*rank)+1, design_row, weight * q_color);
+ math_trimatrix_add_gramian(XtWX, (*rank) + 1, design_row, weight);
+ math_vec3_add(XtWY, (*rank) + 1, design_row, weight * q_color);
#endif
}
-ccl_device_inline void kernel_filter_finalize(int x, int y,
+ccl_device_inline void kernel_filter_finalize(int x,
+ int y,
ccl_global float *buffer,
ccl_global int *rank,
int storage_stride,
@@ -82,47 +94,47 @@ ccl_device_inline void kernel_filter_finalize(int x, int y,
int sample)
{
#ifdef __KERNEL_GPU__
- const int stride = storage_stride;
+ const int stride = storage_stride;
#else
- const int stride = 1;
- (void) storage_stride;
+ const int stride = 1;
+ (void)storage_stride;
#endif
- if(XtWX[0] < 1e-3f) {
- /* There is not enough information to determine a denoised result.
- * As a fallback, keep the original value of the pixel. */
- return;
- }
-
- /* The weighted average of pixel colors (essentially, the NLM-filtered image).
- * In case the solution of the linear model fails due to numerical issues or
- * returns non-sensical negative values, fall back to this value. */
- float3 mean_color = XtWY[0]/XtWX[0];
-
- math_trimatrix_vec3_solve(XtWX, XtWY, (*rank)+1, stride);
-
- float3 final_color = XtWY[0];
- if(!isfinite3_safe(final_color) ||
- (final_color.x < -0.01f || final_color.y < -0.01f || final_color.z < -0.01f))
- {
- final_color = mean_color;
- }
-
- /* Clamp pixel value to positive values. */
- final_color = max(final_color, make_float3(0.0f, 0.0f, 0.0f));
-
- ccl_global float *combined_buffer = buffer + (y*buffer_params.y + x + buffer_params.x)*buffer_params.z;
- if(buffer_params.w >= 0) {
- final_color *= sample;
- if(buffer_params.w > 0) {
- final_color.x += combined_buffer[buffer_params.w+0];
- final_color.y += combined_buffer[buffer_params.w+1];
- final_color.z += combined_buffer[buffer_params.w+2];
- }
- }
- combined_buffer[0] = final_color.x;
- combined_buffer[1] = final_color.y;
- combined_buffer[2] = final_color.z;
+ if (XtWX[0] < 1e-3f) {
+ /* There is not enough information to determine a denoised result.
+ * As a fallback, keep the original value of the pixel. */
+ return;
+ }
+
+ /* The weighted average of pixel colors (essentially, the NLM-filtered image).
+ * In case the solution of the linear model fails due to numerical issues or
+ * returns non-sensical negative values, fall back to this value. */
+ float3 mean_color = XtWY[0] / XtWX[0];
+
+ math_trimatrix_vec3_solve(XtWX, XtWY, (*rank) + 1, stride);
+
+ float3 final_color = XtWY[0];
+ if (!isfinite3_safe(final_color) ||
+ (final_color.x < -0.01f || final_color.y < -0.01f || final_color.z < -0.01f)) {
+ final_color = mean_color;
+ }
+
+ /* Clamp pixel value to positive values. */
+ final_color = max(final_color, make_float3(0.0f, 0.0f, 0.0f));
+
+ ccl_global float *combined_buffer = buffer + (y * buffer_params.y + x + buffer_params.x) *
+ buffer_params.z;
+ if (buffer_params.w >= 0) {
+ final_color *= sample;
+ if (buffer_params.w > 0) {
+ final_color.x += combined_buffer[buffer_params.w + 0];
+ final_color.y += combined_buffer[buffer_params.w + 1];
+ final_color.z += combined_buffer[buffer_params.w + 2];
+ }
+ }
+ combined_buffer[0] = final_color.x;
+ combined_buffer[1] = final_color.y;
+ combined_buffer[2] = final_color.z;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/filter/filter_transform.h b/intern/cycles/kernel/filter/filter_transform.h
index 94e27bb02fd..69e3c7c458d 100644
--- a/intern/cycles/kernel/filter/filter_transform.h
+++ b/intern/cycles/kernel/filter/filter_transform.h
@@ -18,92 +18,101 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_filter_construct_transform(const float *ccl_restrict buffer,
CCL_FILTER_TILE_INFO,
- int x, int y, int4 rect,
- int pass_stride, int frame_stride,
+ int x,
+ int y,
+ int4 rect,
+ int pass_stride,
+ int frame_stride,
bool use_time,
- float *transform, int *rank,
- int radius, float pca_threshold)
+ float *transform,
+ int *rank,
+ int radius,
+ float pca_threshold)
{
- int buffer_w = align_up(rect.z - rect.x, 4);
-
- float features[DENOISE_FEATURES];
-
- const float *ccl_restrict pixel_buffer;
- int3 pixel;
-
- int num_features = use_time? 11 : 10;
-
- /* === Calculate denoising window. === */
- int2 low = make_int2(max(rect.x, x - radius),
- max(rect.y, y - radius));
- int2 high = make_int2(min(rect.z, x + radius + 1),
- min(rect.w, y + radius + 1));
- int num_pixels = (high.y - low.y) * (high.x - low.x) * tile_info->num_frames;
-
- /* === Shift feature passes to have mean 0. === */
- float feature_means[DENOISE_FEATURES];
- math_vector_zero(feature_means, num_features);
- FOR_PIXEL_WINDOW {
- filter_get_features(pixel, pixel_buffer, features, use_time, NULL, pass_stride);
- math_vector_add(feature_means, features, num_features);
- } END_FOR_PIXEL_WINDOW
-
- math_vector_scale(feature_means, 1.0f / num_pixels, num_features);
-
- /* === Scale the shifted feature passes to a range of [-1; 1], will be baked into the transform later. === */
- float feature_scale[DENOISE_FEATURES];
- math_vector_zero(feature_scale, num_features);
-
- FOR_PIXEL_WINDOW {
- filter_get_feature_scales(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
- math_vector_max(feature_scale, features, num_features);
- } END_FOR_PIXEL_WINDOW
-
- filter_calculate_scale(feature_scale, use_time);
-
- /* === Generate the feature transformation. ===
- * This transformation maps the num_features-dimentional feature space to a reduced feature (r-feature) space
- * which generally has fewer dimensions. This mainly helps to prevent overfitting. */
- float feature_matrix[DENOISE_FEATURES*DENOISE_FEATURES];
- math_matrix_zero(feature_matrix, num_features);
- FOR_PIXEL_WINDOW {
- filter_get_features(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
- math_vector_mul(features, feature_scale, num_features);
- math_matrix_add_gramian(feature_matrix, num_features, features, 1.0f);
- } END_FOR_PIXEL_WINDOW
-
- math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, 1);
- *rank = 0;
- /* Prevent overfitting when a small window is used. */
- int max_rank = min(num_features, num_pixels/3);
- if(pca_threshold < 0.0f) {
- float threshold_energy = 0.0f;
- for(int i = 0; i < num_features; i++) {
- threshold_energy += feature_matrix[i*num_features+i];
- }
- threshold_energy *= 1.0f - (-pca_threshold);
-
- float reduced_energy = 0.0f;
- for(int i = 0; i < max_rank; i++, (*rank)++) {
- if(i >= 2 && reduced_energy >= threshold_energy)
- break;
- float s = feature_matrix[i*num_features+i];
- reduced_energy += s;
- }
- }
- else {
- for(int i = 0; i < max_rank; i++, (*rank)++) {
- float s = feature_matrix[i*num_features+i];
- if(i >= 2 && sqrtf(s) < pca_threshold)
- break;
- }
- }
-
- /* Bake the feature scaling into the transformation matrix. */
- for(int i = 0; i < (*rank); i++) {
- math_vector_mul(transform + i*num_features, feature_scale, num_features);
- }
- math_matrix_transpose(transform, num_features, 1);
+ int buffer_w = align_up(rect.z - rect.x, 4);
+
+ float features[DENOISE_FEATURES];
+
+ const float *ccl_restrict pixel_buffer;
+ int3 pixel;
+
+ int num_features = use_time ? 11 : 10;
+
+ /* === Calculate denoising window. === */
+ int2 low = make_int2(max(rect.x, x - radius), max(rect.y, y - radius));
+ int2 high = make_int2(min(rect.z, x + radius + 1), min(rect.w, y + radius + 1));
+ int num_pixels = (high.y - low.y) * (high.x - low.x) * tile_info->num_frames;
+
+ /* === Shift feature passes to have mean 0. === */
+ float feature_means[DENOISE_FEATURES];
+ math_vector_zero(feature_means, num_features);
+ FOR_PIXEL_WINDOW
+ {
+ filter_get_features(pixel, pixel_buffer, features, use_time, NULL, pass_stride);
+ math_vector_add(feature_means, features, num_features);
+ }
+ END_FOR_PIXEL_WINDOW
+
+ math_vector_scale(feature_means, 1.0f / num_pixels, num_features);
+
+ /* === Scale the shifted feature passes to a range of [-1; 1], will be baked into the transform later. === */
+ float feature_scale[DENOISE_FEATURES];
+ math_vector_zero(feature_scale, num_features);
+
+ FOR_PIXEL_WINDOW
+ {
+ filter_get_feature_scales(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
+ math_vector_max(feature_scale, features, num_features);
+ }
+ END_FOR_PIXEL_WINDOW
+
+ filter_calculate_scale(feature_scale, use_time);
+
+ /* === Generate the feature transformation. ===
+ * This transformation maps the num_features-dimentional feature space to a reduced feature (r-feature) space
+ * which generally has fewer dimensions. This mainly helps to prevent overfitting. */
+ float feature_matrix[DENOISE_FEATURES * DENOISE_FEATURES];
+ math_matrix_zero(feature_matrix, num_features);
+ FOR_PIXEL_WINDOW
+ {
+ filter_get_features(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
+ math_vector_mul(features, feature_scale, num_features);
+ math_matrix_add_gramian(feature_matrix, num_features, features, 1.0f);
+ }
+ END_FOR_PIXEL_WINDOW
+
+ math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, 1);
+ *rank = 0;
+ /* Prevent overfitting when a small window is used. */
+ int max_rank = min(num_features, num_pixels / 3);
+ if (pca_threshold < 0.0f) {
+ float threshold_energy = 0.0f;
+ for (int i = 0; i < num_features; i++) {
+ threshold_energy += feature_matrix[i * num_features + i];
+ }
+ threshold_energy *= 1.0f - (-pca_threshold);
+
+ float reduced_energy = 0.0f;
+ for (int i = 0; i < max_rank; i++, (*rank)++) {
+ if (i >= 2 && reduced_energy >= threshold_energy)
+ break;
+ float s = feature_matrix[i * num_features + i];
+ reduced_energy += s;
+ }
+ }
+ else {
+ for (int i = 0; i < max_rank; i++, (*rank)++) {
+ float s = feature_matrix[i * num_features + i];
+ if (i >= 2 && sqrtf(s) < pca_threshold)
+ break;
+ }
+ }
+
+ /* Bake the feature scaling into the transformation matrix. */
+ for (int i = 0; i < (*rank); i++) {
+ math_vector_mul(transform + i * num_features, feature_scale, num_features);
+ }
+ math_matrix_transpose(transform, num_features, 1);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/filter/filter_transform_gpu.h b/intern/cycles/kernel/filter/filter_transform_gpu.h
index ed8ddcb49b1..89cddfd927f 100644
--- a/intern/cycles/kernel/filter/filter_transform_gpu.h
+++ b/intern/cycles/kernel/filter/filter_transform_gpu.h
@@ -18,106 +18,110 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_filter_construct_transform(const ccl_global float *ccl_restrict buffer,
CCL_FILTER_TILE_INFO,
- int x, int y, int4 rect,
- int pass_stride, int frame_stride,
+ int x,
+ int y,
+ int4 rect,
+ int pass_stride,
+ int frame_stride,
bool use_time,
ccl_global float *transform,
ccl_global int *rank,
- int radius, float pca_threshold,
- int transform_stride, int localIdx)
+ int radius,
+ float pca_threshold,
+ int transform_stride,
+ int localIdx)
{
- int buffer_w = align_up(rect.z - rect.x, 4);
+ int buffer_w = align_up(rect.z - rect.x, 4);
#ifdef __KERNEL_CUDA__
- ccl_local float shared_features[DENOISE_FEATURES*CCL_MAX_LOCAL_SIZE];
- ccl_local_param float *features = shared_features + localIdx*DENOISE_FEATURES;
+ ccl_local float shared_features[DENOISE_FEATURES * CCL_MAX_LOCAL_SIZE];
+ ccl_local_param float *features = shared_features + localIdx * DENOISE_FEATURES;
#else
- float features[DENOISE_FEATURES];
+ float features[DENOISE_FEATURES];
#endif
- int num_features = use_time? 11 : 10;
-
- /* === Calculate denoising window. === */
- int2 low = make_int2(max(rect.x, x - radius),
- max(rect.y, y - radius));
- int2 high = make_int2(min(rect.z, x + radius + 1),
- min(rect.w, y + radius + 1));
- int num_pixels = (high.y - low.y) * (high.x - low.x) * tile_info->num_frames;
- const ccl_global float *ccl_restrict pixel_buffer;
- int3 pixel;
-
-
-
-
- /* === Shift feature passes to have mean 0. === */
- float feature_means[DENOISE_FEATURES];
- math_vector_zero(feature_means, num_features);
- FOR_PIXEL_WINDOW {
- filter_get_features(pixel, pixel_buffer, features, use_time, NULL, pass_stride);
- math_vector_add(feature_means, features, num_features);
- } END_FOR_PIXEL_WINDOW
-
- math_vector_scale(feature_means, 1.0f / num_pixels, num_features);
-
- /* === Scale the shifted feature passes to a range of [-1; 1], will be baked into the transform later. === */
- float feature_scale[DENOISE_FEATURES];
- math_vector_zero(feature_scale, num_features);
-
- FOR_PIXEL_WINDOW {
- filter_get_feature_scales(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
- math_vector_max(feature_scale, features, num_features);
- } END_FOR_PIXEL_WINDOW
-
- filter_calculate_scale(feature_scale, use_time);
-
-
-
- /* === Generate the feature transformation. ===
- * This transformation maps the num_features-dimentional feature space to a reduced feature (r-feature) space
- * which generally has fewer dimensions. This mainly helps to prevent overfitting. */
- float feature_matrix[DENOISE_FEATURES*DENOISE_FEATURES];
- math_matrix_zero(feature_matrix, num_features);
- FOR_PIXEL_WINDOW {
- filter_get_features(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
- math_vector_mul(features, feature_scale, num_features);
- math_matrix_add_gramian(feature_matrix, num_features, features, 1.0f);
- } END_FOR_PIXEL_WINDOW
-
- math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, transform_stride);
- *rank = 0;
- /* Prevent overfitting when a small window is used. */
- int max_rank = min(num_features, num_pixels/3);
- if(pca_threshold < 0.0f) {
- float threshold_energy = 0.0f;
- for(int i = 0; i < num_features; i++) {
- threshold_energy += feature_matrix[i*num_features+i];
- }
- threshold_energy *= 1.0f - (-pca_threshold);
-
- float reduced_energy = 0.0f;
- for(int i = 0; i < max_rank; i++, (*rank)++) {
- if(i >= 2 && reduced_energy >= threshold_energy)
- break;
- float s = feature_matrix[i*num_features+i];
- reduced_energy += s;
- }
- }
- else {
- for(int i = 0; i < max_rank; i++, (*rank)++) {
- float s = feature_matrix[i*num_features+i];
- if(i >= 2 && sqrtf(s) < pca_threshold)
- break;
- }
- }
-
- math_matrix_transpose(transform, num_features, transform_stride);
-
- /* Bake the feature scaling into the transformation matrix. */
- for(int i = 0; i < num_features; i++) {
- for(int j = 0; j < (*rank); j++) {
- transform[(i*num_features + j)*transform_stride] *= feature_scale[i];
- }
- }
+ int num_features = use_time ? 11 : 10;
+
+ /* === Calculate denoising window. === */
+ int2 low = make_int2(max(rect.x, x - radius), max(rect.y, y - radius));
+ int2 high = make_int2(min(rect.z, x + radius + 1), min(rect.w, y + radius + 1));
+ int num_pixels = (high.y - low.y) * (high.x - low.x) * tile_info->num_frames;
+ const ccl_global float *ccl_restrict pixel_buffer;
+ int3 pixel;
+
+ /* === Shift feature passes to have mean 0. === */
+ float feature_means[DENOISE_FEATURES];
+ math_vector_zero(feature_means, num_features);
+ FOR_PIXEL_WINDOW
+ {
+ filter_get_features(pixel, pixel_buffer, features, use_time, NULL, pass_stride);
+ math_vector_add(feature_means, features, num_features);
+ }
+ END_FOR_PIXEL_WINDOW
+
+ math_vector_scale(feature_means, 1.0f / num_pixels, num_features);
+
+ /* === Scale the shifted feature passes to a range of [-1; 1], will be baked into the transform later. === */
+ float feature_scale[DENOISE_FEATURES];
+ math_vector_zero(feature_scale, num_features);
+
+ FOR_PIXEL_WINDOW
+ {
+ filter_get_feature_scales(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
+ math_vector_max(feature_scale, features, num_features);
+ }
+ END_FOR_PIXEL_WINDOW
+
+ filter_calculate_scale(feature_scale, use_time);
+
+ /* === Generate the feature transformation. ===
+ * This transformation maps the num_features-dimentional feature space to a reduced feature (r-feature) space
+ * which generally has fewer dimensions. This mainly helps to prevent overfitting. */
+ float feature_matrix[DENOISE_FEATURES * DENOISE_FEATURES];
+ math_matrix_zero(feature_matrix, num_features);
+ FOR_PIXEL_WINDOW
+ {
+ filter_get_features(pixel, pixel_buffer, features, use_time, feature_means, pass_stride);
+ math_vector_mul(features, feature_scale, num_features);
+ math_matrix_add_gramian(feature_matrix, num_features, features, 1.0f);
+ }
+ END_FOR_PIXEL_WINDOW
+
+ math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, transform_stride);
+ *rank = 0;
+ /* Prevent overfitting when a small window is used. */
+ int max_rank = min(num_features, num_pixels / 3);
+ if (pca_threshold < 0.0f) {
+ float threshold_energy = 0.0f;
+ for (int i = 0; i < num_features; i++) {
+ threshold_energy += feature_matrix[i * num_features + i];
+ }
+ threshold_energy *= 1.0f - (-pca_threshold);
+
+ float reduced_energy = 0.0f;
+ for (int i = 0; i < max_rank; i++, (*rank)++) {
+ if (i >= 2 && reduced_energy >= threshold_energy)
+ break;
+ float s = feature_matrix[i * num_features + i];
+ reduced_energy += s;
+ }
+ }
+ else {
+ for (int i = 0; i < max_rank; i++, (*rank)++) {
+ float s = feature_matrix[i * num_features + i];
+ if (i >= 2 && sqrtf(s) < pca_threshold)
+ break;
+ }
+ }
+
+ math_matrix_transpose(transform, num_features, transform_stride);
+
+ /* Bake the feature scaling into the transformation matrix. */
+ for (int i = 0; i < num_features; i++) {
+ for (int j = 0; j < (*rank); j++) {
+ transform[(i * num_features + j) * transform_stride] *= feature_scale[i];
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/filter/filter_transform_sse.h b/intern/cycles/kernel/filter/filter_transform_sse.h
index 10bd3e477e9..22397b292db 100644
--- a/intern/cycles/kernel/filter/filter_transform_sse.h
+++ b/intern/cycles/kernel/filter/filter_transform_sse.h
@@ -18,98 +18,110 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_filter_construct_transform(const float *ccl_restrict buffer,
CCL_FILTER_TILE_INFO,
- int x, int y, int4 rect,
- int pass_stride, int frame_stride,
+ int x,
+ int y,
+ int4 rect,
+ int pass_stride,
+ int frame_stride,
bool use_time,
- float *transform, int *rank,
- int radius, float pca_threshold)
+ float *transform,
+ int *rank,
+ int radius,
+ float pca_threshold)
{
- int buffer_w = align_up(rect.z - rect.x, 4);
-
- float4 features[DENOISE_FEATURES];
- const float *ccl_restrict pixel_buffer;
- int3 pixel;
-
- int num_features = use_time? 11 : 10;
-
- /* === Calculate denoising window. === */
- int2 low = make_int2(max(rect.x, x - radius),
- max(rect.y, y - radius));
- int2 high = make_int2(min(rect.z, x + radius + 1),
- min(rect.w, y + radius + 1));
- int num_pixels = (high.y - low.y) * (high.x - low.x) * tile_info->num_frames;
-
- /* === Shift feature passes to have mean 0. === */
- float4 feature_means[DENOISE_FEATURES];
- math_vector_zero_sse(feature_means, num_features);
- FOR_PIXEL_WINDOW_SSE {
- filter_get_features_sse(x4, y4, t4, active_pixels, pixel_buffer, features, use_time, NULL, pass_stride);
- math_vector_add_sse(feature_means, num_features, features);
- } END_FOR_PIXEL_WINDOW_SSE
-
- float4 pixel_scale = make_float4(1.0f / num_pixels);
- for(int i = 0; i < num_features; i++) {
- feature_means[i] = reduce_add(feature_means[i]) * pixel_scale;
- }
-
- /* === Scale the shifted feature passes to a range of [-1; 1], will be baked into the transform later. === */
- float4 feature_scale[DENOISE_FEATURES];
- math_vector_zero_sse(feature_scale, num_features);
- FOR_PIXEL_WINDOW_SSE {
- filter_get_feature_scales_sse(x4, y4, t4, active_pixels, pixel_buffer, features, use_time, feature_means, pass_stride);
- math_vector_max_sse(feature_scale, features, num_features);
- } END_FOR_PIXEL_WINDOW_SSE
-
- filter_calculate_scale_sse(feature_scale, use_time);
-
- /* === Generate the feature transformation. ===
- * This transformation maps the num_features-dimentional feature space to a reduced feature (r-feature) space
- * which generally has fewer dimensions. This mainly helps to prevent overfitting. */
- float4 feature_matrix_sse[DENOISE_FEATURES*DENOISE_FEATURES];
- math_matrix_zero_sse(feature_matrix_sse, num_features);
- FOR_PIXEL_WINDOW_SSE {
- filter_get_features_sse(x4, y4, t4, active_pixels, pixel_buffer, features, use_time, feature_means, pass_stride);
- math_vector_mul_sse(features, num_features, feature_scale);
- math_matrix_add_gramian_sse(feature_matrix_sse, num_features, features, make_float4(1.0f));
- } END_FOR_PIXEL_WINDOW_SSE
-
- float feature_matrix[DENOISE_FEATURES*DENOISE_FEATURES];
- math_matrix_hsum(feature_matrix, num_features, feature_matrix_sse);
-
- math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, 1);
-
- *rank = 0;
- /* Prevent overfitting when a small window is used. */
- int max_rank = min(num_features, num_pixels/3);
- if(pca_threshold < 0.0f) {
- float threshold_energy = 0.0f;
- for(int i = 0; i < num_features; i++) {
- threshold_energy += feature_matrix[i*num_features+i];
- }
- threshold_energy *= 1.0f - (-pca_threshold);
-
- float reduced_energy = 0.0f;
- for(int i = 0; i < max_rank; i++, (*rank)++) {
- if(i >= 2 && reduced_energy >= threshold_energy)
- break;
- float s = feature_matrix[i*num_features+i];
- reduced_energy += s;
- }
- }
- else {
- for(int i = 0; i < max_rank; i++, (*rank)++) {
- float s = feature_matrix[i*num_features+i];
- if(i >= 2 && sqrtf(s) < pca_threshold)
- break;
- }
- }
-
- math_matrix_transpose(transform, num_features, 1);
-
- /* Bake the feature scaling into the transformation matrix. */
- for(int i = 0; i < num_features; i++) {
- math_vector_scale(transform + i*num_features, feature_scale[i][0], *rank);
- }
+ int buffer_w = align_up(rect.z - rect.x, 4);
+
+ float4 features[DENOISE_FEATURES];
+ const float *ccl_restrict pixel_buffer;
+ int3 pixel;
+
+ int num_features = use_time ? 11 : 10;
+
+ /* === Calculate denoising window. === */
+ int2 low = make_int2(max(rect.x, x - radius), max(rect.y, y - radius));
+ int2 high = make_int2(min(rect.z, x + radius + 1), min(rect.w, y + radius + 1));
+ int num_pixels = (high.y - low.y) * (high.x - low.x) * tile_info->num_frames;
+
+ /* === Shift feature passes to have mean 0. === */
+ float4 feature_means[DENOISE_FEATURES];
+ math_vector_zero_sse(feature_means, num_features);
+ FOR_PIXEL_WINDOW_SSE
+ {
+ filter_get_features_sse(
+ x4, y4, t4, active_pixels, pixel_buffer, features, use_time, NULL, pass_stride);
+ math_vector_add_sse(feature_means, num_features, features);
+ }
+ END_FOR_PIXEL_WINDOW_SSE
+
+ float4 pixel_scale = make_float4(1.0f / num_pixels);
+ for (int i = 0; i < num_features; i++) {
+ feature_means[i] = reduce_add(feature_means[i]) * pixel_scale;
+ }
+
+ /* === Scale the shifted feature passes to a range of [-1; 1], will be baked into the transform later. === */
+ float4 feature_scale[DENOISE_FEATURES];
+ math_vector_zero_sse(feature_scale, num_features);
+ FOR_PIXEL_WINDOW_SSE
+ {
+ filter_get_feature_scales_sse(
+ x4, y4, t4, active_pixels, pixel_buffer, features, use_time, feature_means, pass_stride);
+ math_vector_max_sse(feature_scale, features, num_features);
+ }
+ END_FOR_PIXEL_WINDOW_SSE
+
+ filter_calculate_scale_sse(feature_scale, use_time);
+
+ /* === Generate the feature transformation. ===
+ * This transformation maps the num_features-dimentional feature space to a reduced feature (r-feature) space
+ * which generally has fewer dimensions. This mainly helps to prevent overfitting. */
+ float4 feature_matrix_sse[DENOISE_FEATURES * DENOISE_FEATURES];
+ math_matrix_zero_sse(feature_matrix_sse, num_features);
+ FOR_PIXEL_WINDOW_SSE
+ {
+ filter_get_features_sse(
+ x4, y4, t4, active_pixels, pixel_buffer, features, use_time, feature_means, pass_stride);
+ math_vector_mul_sse(features, num_features, feature_scale);
+ math_matrix_add_gramian_sse(feature_matrix_sse, num_features, features, make_float4(1.0f));
+ }
+ END_FOR_PIXEL_WINDOW_SSE
+
+ float feature_matrix[DENOISE_FEATURES * DENOISE_FEATURES];
+ math_matrix_hsum(feature_matrix, num_features, feature_matrix_sse);
+
+ math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, 1);
+
+ *rank = 0;
+ /* Prevent overfitting when a small window is used. */
+ int max_rank = min(num_features, num_pixels / 3);
+ if (pca_threshold < 0.0f) {
+ float threshold_energy = 0.0f;
+ for (int i = 0; i < num_features; i++) {
+ threshold_energy += feature_matrix[i * num_features + i];
+ }
+ threshold_energy *= 1.0f - (-pca_threshold);
+
+ float reduced_energy = 0.0f;
+ for (int i = 0; i < max_rank; i++, (*rank)++) {
+ if (i >= 2 && reduced_energy >= threshold_energy)
+ break;
+ float s = feature_matrix[i * num_features + i];
+ reduced_energy += s;
+ }
+ }
+ else {
+ for (int i = 0; i < max_rank; i++, (*rank)++) {
+ float s = feature_matrix[i * num_features + i];
+ if (i >= 2 && sqrtf(s) < pca_threshold)
+ break;
+ }
+ }
+
+ math_matrix_transpose(transform, num_features, 1);
+
+ /* Bake the feature scaling into the transformation matrix. */
+ for (int i = 0; i < num_features; i++) {
+ math_vector_scale(transform + i * num_features, feature_scale[i][0], *rank);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h
index e991f3d685a..456608bfa22 100644
--- a/intern/cycles/kernel/geom/geom_attribute.h
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -30,81 +30,83 @@ ccl_device_inline uint subd_triangle_patch(KernelGlobals *kg, const ShaderData *
ccl_device_inline uint attribute_primitive_type(KernelGlobals *kg, const ShaderData *sd)
{
#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_CURVE) {
- return ATTR_PRIM_CURVE;
- }
- else
+ if (sd->type & PRIMITIVE_ALL_CURVE) {
+ return ATTR_PRIM_CURVE;
+ }
+ else
#endif
- if(subd_triangle_patch(kg, sd) != ~0) {
- return ATTR_PRIM_SUBD;
- }
- else {
- return ATTR_PRIM_TRIANGLE;
- }
+ if (subd_triangle_patch(kg, sd) != ~0) {
+ return ATTR_PRIM_SUBD;
+ }
+ else {
+ return ATTR_PRIM_TRIANGLE;
+ }
}
ccl_device_inline AttributeDescriptor attribute_not_found()
{
- const AttributeDescriptor desc = {ATTR_ELEMENT_NONE, (NodeAttributeType)0, 0, ATTR_STD_NOT_FOUND};
- return desc;
+ const AttributeDescriptor desc = {
+ ATTR_ELEMENT_NONE, (NodeAttributeType)0, 0, ATTR_STD_NOT_FOUND};
+ return desc;
}
/* Find attribute based on ID */
ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int object)
{
- return kernel_tex_fetch(__objects, object).attribute_map_offset;
+ return kernel_tex_fetch(__objects, object).attribute_map_offset;
}
-ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
+ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg,
+ const ShaderData *sd,
+ uint id)
{
- if(sd->object == OBJECT_NONE) {
- return attribute_not_found();
- }
-
- /* for SVM, find attribute by unique id */
- uint attr_offset = object_attribute_map_offset(kg, sd->object);
- attr_offset += attribute_primitive_type(kg, sd);
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id) {
- if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
- return attribute_not_found();
- }
- attr_offset += ATTR_PRIM_TYPES;
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
- }
-
- AttributeDescriptor desc;
- desc.element = (AttributeElement)attr_map.y;
-
- if(sd->prim == PRIM_NONE &&
- desc.element != ATTR_ELEMENT_MESH &&
- desc.element != ATTR_ELEMENT_VOXEL &&
- desc.element != ATTR_ELEMENT_OBJECT)
- {
- return attribute_not_found();
- }
-
- /* return result */
- desc.offset = (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- desc.type = (NodeAttributeType)(attr_map.w & 0xff);
- desc.flags = (AttributeFlag)(attr_map.w >> 8);
-
- return desc;
+ if (sd->object == OBJECT_NONE) {
+ return attribute_not_found();
+ }
+
+ /* for SVM, find attribute by unique id */
+ uint attr_offset = object_attribute_map_offset(kg, sd->object);
+ attr_offset += attribute_primitive_type(kg, sd);
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while (attr_map.x != id) {
+ if (UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
+ return attribute_not_found();
+ }
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ AttributeDescriptor desc;
+ desc.element = (AttributeElement)attr_map.y;
+
+ if (sd->prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
+ desc.element != ATTR_ELEMENT_VOXEL && desc.element != ATTR_ELEMENT_OBJECT) {
+ return attribute_not_found();
+ }
+
+ /* return result */
+ desc.offset = (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+ desc.type = (NodeAttributeType)(attr_map.w & 0xff);
+ desc.flags = (AttributeFlag)(attr_map.w >> 8);
+
+ return desc;
}
/* Transform matrix attribute on meshes */
-ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc)
+ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc)
{
- Transform tfm;
+ Transform tfm;
- tfm.x = kernel_tex_fetch(__attributes_float3, desc.offset + 0);
- tfm.y = kernel_tex_fetch(__attributes_float3, desc.offset + 1);
- tfm.z = kernel_tex_fetch(__attributes_float3, desc.offset + 2);
+ tfm.x = kernel_tex_fetch(__attributes_float3, desc.offset + 0);
+ tfm.y = kernel_tex_fetch(__attributes_float3, desc.offset + 1);
+ tfm.z = kernel_tex_fetch(__attributes_float3, desc.offset + 2);
- return tfm;
+ return tfm;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
index 9b60cf6d56b..e0aacb434eb 100644
--- a/intern/cycles/kernel/geom/geom_curve.h
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -27,169 +27,199 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
{
- float fc = 0.71f;
- float data[4];
- float t2 = t * t;
- data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
- data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
- data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
- data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
- return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+ float fc = 0.71f;
+ float data[4];
+ float t2 = t * t;
+ data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
+ data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
+ data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
+ data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
}
ccl_device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3)
{
- float data[4];
- float fc = 0.71f;
- float t2 = t * t;
- float t3 = t2 * t;
- data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
- data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
- data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
- data[3] = fc * t3 - fc * t2;
- return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+ float data[4];
+ float fc = 0.71f;
+ float t2 = t * t;
+ float t3 = t2 * t;
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
}
/* Reading attributes on various curve elements */
-ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
+ccl_device float curve_attribute_float(
+ KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
{
- if(desc.element == ATTR_ELEMENT_CURVE) {
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-#endif
-
- return kernel_tex_fetch(__attributes_float, desc.offset + sd->prim);
- }
- else if(desc.element == ATTR_ELEMENT_CURVE_KEY || desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
- int k1 = k0 + 1;
-
- float f0 = kernel_tex_fetch(__attributes_float, desc.offset + k0);
- float f1 = kernel_tex_fetch(__attributes_float, desc.offset + k1);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*(f1 - f0);
- if(dy) *dy = 0.0f;
-#endif
-
- return (1.0f - sd->u)*f0 + sd->u*f1;
- }
- else {
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-#endif
-
- return 0.0f;
- }
+ if (desc.element == ATTR_ELEMENT_CURVE) {
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
+# endif
+
+ return kernel_tex_fetch(__attributes_float, desc.offset + sd->prim);
+ }
+ else if (desc.element == ATTR_ELEMENT_CURVE_KEY ||
+ desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float f0 = kernel_tex_fetch(__attributes_float, desc.offset + k0);
+ float f1 = kernel_tex_fetch(__attributes_float, desc.offset + k1);
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = sd->du.dx * (f1 - f0);
+ if (dy)
+ *dy = 0.0f;
+# endif
+
+ return (1.0f - sd->u) * f0 + sd->u * f1;
+ }
+ else {
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
+# endif
+
+ return 0.0f;
+ }
}
-ccl_device float2 curve_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
+ccl_device float2 curve_attribute_float2(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float2 *dx,
+ float2 *dy)
{
- if(desc.element == ATTR_ELEMENT_CURVE) {
- /* idea: we can't derive any useful differentials here, but for tiled
- * mipmap image caching it would be useful to avoid reading the highest
- * detail level always. maybe a derivative based on the hair density
- * could be computed somehow? */
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
-#endif
-
- return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
- }
- else if(desc.element == ATTR_ELEMENT_CURVE_KEY || desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
- int k1 = k0 + 1;
-
- float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + k0);
- float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + k1);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*(f1 - f0);
- if(dy) *dy = make_float2(0.0f, 0.0f);
-#endif
-
- return (1.0f - sd->u)*f0 + sd->u*f1;
- }
- else {
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
-#endif
-
- return make_float2(0.0f, 0.0f);
- }
+ if (desc.element == ATTR_ELEMENT_CURVE) {
+ /* idea: we can't derive any useful differentials here, but for tiled
+ * mipmap image caching it would be useful to avoid reading the highest
+ * detail level always. maybe a derivative based on the hair density
+ * could be computed somehow? */
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+# endif
+
+ return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
+ }
+ else if (desc.element == ATTR_ELEMENT_CURVE_KEY ||
+ desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + k0);
+ float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + k1);
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = sd->du.dx * (f1 - f0);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+# endif
+
+ return (1.0f - sd->u) * f0 + sd->u * f1;
+ }
+ else {
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+# endif
+
+ return make_float2(0.0f, 0.0f);
+ }
}
-ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
+ccl_device float3 curve_attribute_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float3 *dx,
+ float3 *dy)
{
- if(desc.element == ATTR_ELEMENT_CURVE) {
- /* idea: we can't derive any useful differentials here, but for tiled
- * mipmap image caching it would be useful to avoid reading the highest
- * detail level always. maybe a derivative based on the hair density
- * could be computed somehow? */
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim));
- }
- else if(desc.element == ATTR_ELEMENT_CURVE_KEY || desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
- int k1 = k0 + 1;
-
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k0));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k1));
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*(f1 - f0);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
- return (1.0f - sd->u)*f0 + sd->u*f1;
- }
- else {
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (desc.element == ATTR_ELEMENT_CURVE) {
+ /* idea: we can't derive any useful differentials here, but for tiled
+ * mipmap image caching it would be useful to avoid reading the highest
+ * detail level always. maybe a derivative based on the hair density
+ * could be computed somehow? */
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+# endif
+
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim));
+ }
+ else if (desc.element == ATTR_ELEMENT_CURVE_KEY ||
+ desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k0));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k1));
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = sd->du.dx * (f1 - f0);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+# endif
+
+ return (1.0f - sd->u) * f0 + sd->u * f1;
+ }
+ else {
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+# endif
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
/* Curve thickness */
ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
{
- float r = 0.0f;
+ float r = 0.0f;
- if(sd->type & PRIMITIVE_ALL_CURVE) {
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
- int k1 = k0 + 1;
+ if (sd->type & PRIMITIVE_ALL_CURVE) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
- float4 P_curve[2];
+ float4 P_curve[2];
- if(sd->type & PRIMITIVE_CURVE) {
- P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
- P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
- }
- else {
- motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
- }
+ if (sd->type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
+ }
- r = (P_curve[1].w - P_curve[0].w) * sd->u + P_curve[0].w;
- }
+ r = (P_curve[1].w - P_curve[0].w) * sd->u + P_curve[0].w;
+ }
- return r*2.0f;
+ return r * 2.0f;
}
/* Curve location for motion pass, linear interpolation between keys and
@@ -197,89 +227,98 @@ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
ccl_device float3 curve_motion_center_location(KernelGlobals *kg, ShaderData *sd)
{
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
- int k1 = k0 + 1;
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
- float4 P_curve[2];
+ float4 P_curve[2];
- P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
- P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
- return float4_to_float3(P_curve[1]) * sd->u + float4_to_float3(P_curve[0]) * (1.0f - sd->u);
+ return float4_to_float3(P_curve[1]) * sd->u + float4_to_float3(P_curve[0]) * (1.0f - sd->u);
}
/* Curve tangent normal */
ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
{
- float3 tgN = make_float3(0.0f,0.0f,0.0f);
+ float3 tgN = make_float3(0.0f, 0.0f, 0.0f);
- if(sd->type & PRIMITIVE_ALL_CURVE) {
+ if (sd->type & PRIMITIVE_ALL_CURVE) {
- tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu)));
- tgN = normalize(tgN);
+ tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu, -sd->I) / len_squared(sd->dPdu)));
+ tgN = normalize(tgN);
- /* need to find suitable scaled gd for corrected normal */
-#if 0
- tgN = normalize(tgN - gd * sd->dPdu);
-#endif
- }
+ /* need to find suitable scaled gd for corrected normal */
+# if 0
+ tgN = normalize(tgN - gd * sd->dPdu);
+# endif
+ }
- return tgN;
+ return tgN;
}
/* Curve bounds utility function */
-ccl_device_inline void curvebounds(float *lower, float *upper, float *extremta, float *extrema, float *extremtb, float *extremb, float p0, float p1, float p2, float p3)
+ccl_device_inline void curvebounds(float *lower,
+ float *upper,
+ float *extremta,
+ float *extrema,
+ float *extremtb,
+ float *extremb,
+ float p0,
+ float p1,
+ float p2,
+ float p3)
{
- float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
- float ta = -1.0f;
- float tb = -1.0f;
-
- *extremta = -1.0f;
- *extremtb = -1.0f;
- *upper = p0;
- *lower = (p0 + p1) + (p2 + p3);
- *extrema = *upper;
- *extremb = *lower;
-
- if(*lower >= *upper) {
- *upper = *lower;
- *lower = p0;
- }
-
- if(halfdiscroot >= 0) {
- float inv3p3 = (1.0f/3.0f)/p3;
- halfdiscroot = sqrtf(halfdiscroot);
- ta = (-p2 - halfdiscroot) * inv3p3;
- tb = (-p2 + halfdiscroot) * inv3p3;
- }
-
- float t2;
- float t3;
-
- if(ta > 0.0f && ta < 1.0f) {
- t2 = ta * ta;
- t3 = t2 * ta;
- *extremta = ta;
- *extrema = p3 * t3 + p2 * t2 + p1 * ta + p0;
-
- *upper = fmaxf(*extrema, *upper);
- *lower = fminf(*extrema, *lower);
- }
-
- if(tb > 0.0f && tb < 1.0f) {
- t2 = tb * tb;
- t3 = t2 * tb;
- *extremtb = tb;
- *extremb = p3 * t3 + p2 * t2 + p1 * tb + p0;
-
- *upper = fmaxf(*extremb, *upper);
- *lower = fminf(*extremb, *lower);
- }
+ float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
+ float ta = -1.0f;
+ float tb = -1.0f;
+
+ *extremta = -1.0f;
+ *extremtb = -1.0f;
+ *upper = p0;
+ *lower = (p0 + p1) + (p2 + p3);
+ *extrema = *upper;
+ *extremb = *lower;
+
+ if (*lower >= *upper) {
+ *upper = *lower;
+ *lower = p0;
+ }
+
+ if (halfdiscroot >= 0) {
+ float inv3p3 = (1.0f / 3.0f) / p3;
+ halfdiscroot = sqrtf(halfdiscroot);
+ ta = (-p2 - halfdiscroot) * inv3p3;
+ tb = (-p2 + halfdiscroot) * inv3p3;
+ }
+
+ float t2;
+ float t3;
+
+ if (ta > 0.0f && ta < 1.0f) {
+ t2 = ta * ta;
+ t3 = t2 * ta;
+ *extremta = ta;
+ *extrema = p3 * t3 + p2 * t2 + p1 * ta + p0;
+
+ *upper = fmaxf(*extrema, *upper);
+ *lower = fminf(*extrema, *lower);
+ }
+
+ if (tb > 0.0f && tb < 1.0f) {
+ t2 = tb * tb;
+ t3 = t2 * tb;
+ *extremtb = tb;
+ *extremb = p3 * t3 + p2 * t2 + p1 * tb + p0;
+
+ *upper = fmaxf(*extremb, *upper);
+ *lower = fminf(*extremb, *lower);
+ }
}
-#endif /* __HAIR__ */
+#endif /* __HAIR__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_curve_intersect.h b/intern/cycles/kernel/geom/geom_curve_intersect.h
index 5cf8713e3a8..5fd277c2f99 100644
--- a/intern/cycles/kernel/geom/geom_curve_intersect.h
+++ b/intern/cycles/kernel/geom/geom_curve_intersect.h
@@ -18,484 +18,534 @@ CCL_NAMESPACE_BEGIN
#ifdef __HAIR__
-#ifdef __KERNEL_SSE2__
+# ifdef __KERNEL_SSE2__
ccl_device_inline ssef transform_point_T3(const ssef t[3], const ssef &a)
{
- return madd(shuffle<0>(a), t[0], madd(shuffle<1>(a), t[1], shuffle<2>(a) * t[2]));
+ return madd(shuffle<0>(a), t[0], madd(shuffle<1>(a), t[1], shuffle<2>(a) * t[2]));
}
-#endif
+# endif
/* On CPU pass P and dir by reference to aligned vector. */
-ccl_device_forceinline bool cardinal_curve_intersect(
- KernelGlobals *kg,
- Intersection *isect,
- const float3 ccl_ref P,
- const float3 ccl_ref dir,
- uint visibility,
- int object,
- int curveAddr,
- float time,
- int type,
- uint *lcg_state,
- float difl,
- float extmax)
+ccl_device_forceinline bool cardinal_curve_intersect(KernelGlobals *kg,
+ Intersection *isect,
+ const float3 ccl_ref P,
+ const float3 ccl_ref dir,
+ uint visibility,
+ int object,
+ int curveAddr,
+ float time,
+ int type,
+ uint *lcg_state,
+ float difl,
+ float extmax)
{
- const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
-
- if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
- if(time < prim_time.x || time > prim_time.y) {
- return false;
- }
- }
-
- int segment = PRIMITIVE_UNPACK_SEGMENT(type);
- float epsilon = 0.0f;
- float r_st, r_en;
-
- int depth = kernel_data.curve.subdivisions;
- int flags = kernel_data.curve.curveflags;
- int prim = kernel_tex_fetch(__prim_index, curveAddr);
-
-#ifdef __KERNEL_SSE2__
- ssef vdir = load4f(dir);
- ssef vcurve_coef[4];
- const float3 *curve_coef = (float3 *)vcurve_coef;
-
- {
- ssef dtmp = vdir * vdir;
- ssef d_ss = mm_sqrt(dtmp + shuffle<2>(dtmp));
- ssef rd_ss = load1f_first(1.0f) / d_ss;
-
- ssei v00vec = load4i((ssei *)&kg->__curves.data[prim]);
- int2 &v00 = (int2 &)v00vec;
-
- int k0 = v00.x + segment;
- int k1 = k0 + 1;
- int ka = max(k0 - 1, v00.x);
- int kb = min(k1 + 1, v00.x + v00.y - 1);
-
-#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && (!defined(_MSC_VER) || _MSC_VER > 1800)
- avxf P_curve_0_1, P_curve_2_3;
- if(is_curve_primitive) {
- P_curve_0_1 = _mm256_loadu2_m128(&kg->__curve_keys.data[k0].x, &kg->__curve_keys.data[ka].x);
- P_curve_2_3 = _mm256_loadu2_m128(&kg->__curve_keys.data[kb].x, &kg->__curve_keys.data[k1].x);
- }
- else {
- int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
- motion_cardinal_curve_keys_avx(kg, fobject, prim, time, ka, k0, k1, kb, &P_curve_0_1,&P_curve_2_3);
- }
-#else /* __KERNEL_AVX2__ */
- ssef P_curve[4];
-
- if(is_curve_primitive) {
- P_curve[0] = load4f(&kg->__curve_keys.data[ka].x);
- P_curve[1] = load4f(&kg->__curve_keys.data[k0].x);
- P_curve[2] = load4f(&kg->__curve_keys.data[k1].x);
- P_curve[3] = load4f(&kg->__curve_keys.data[kb].x);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4*)&P_curve);
- }
-#endif /* __KERNEL_AVX2__ */
-
- ssef rd_sgn = set_sign_bit<0, 1, 1, 1>(shuffle<0>(rd_ss));
- ssef mul_zxxy = shuffle<2, 0, 0, 1>(vdir) * rd_sgn;
- ssef mul_yz = shuffle<1, 2, 1, 2>(vdir) * mul_zxxy;
- ssef mul_shuf = shuffle<0, 1, 2, 3>(mul_zxxy, mul_yz);
- ssef vdir0 = vdir & cast(ssei(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0));
-
- ssef htfm0 = shuffle<0, 2, 0, 3>(mul_shuf, vdir0);
- ssef htfm1 = shuffle<1, 0, 1, 3>(load1f_first(extract<0>(d_ss)), vdir0);
- ssef htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0);
-
-#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && (!defined(_MSC_VER) || _MSC_VER > 1800)
- const avxf vPP = _mm256_broadcast_ps(&P.m128);
- const avxf htfm00 = avxf(htfm0.m128, htfm0.m128);
- const avxf htfm11 = avxf(htfm1.m128, htfm1.m128);
- const avxf htfm22 = avxf(htfm2.m128, htfm2.m128);
-
- const avxf p01 = madd(shuffle<0>(P_curve_0_1 - vPP),
- htfm00,
- madd(shuffle<1>(P_curve_0_1 - vPP),
- htfm11,
- shuffle<2>(P_curve_0_1 - vPP) * htfm22));
- const avxf p23 = madd(shuffle<0>(P_curve_2_3 - vPP),
- htfm00,
- madd(shuffle<1>(P_curve_2_3 - vPP),
- htfm11,
- shuffle<2>(P_curve_2_3 - vPP)*htfm22));
-
- const ssef p0 = _mm256_castps256_ps128(p01);
- const ssef p1 = _mm256_extractf128_ps(p01, 1);
- const ssef p2 = _mm256_castps256_ps128(p23);
- const ssef p3 = _mm256_extractf128_ps(p23, 1);
-
- const ssef P_curve_1 = _mm256_extractf128_ps(P_curve_0_1, 1);
- r_st = ((float4 &)P_curve_1).w;
- const ssef P_curve_2 = _mm256_castps256_ps128(P_curve_2_3);
- r_en = ((float4 &)P_curve_2).w;
-#else /* __KERNEL_AVX2__ */
- ssef htfm[] = { htfm0, htfm1, htfm2 };
- ssef vP = load4f(P);
- ssef p0 = transform_point_T3(htfm, P_curve[0] - vP);
- ssef p1 = transform_point_T3(htfm, P_curve[1] - vP);
- ssef p2 = transform_point_T3(htfm, P_curve[2] - vP);
- ssef p3 = transform_point_T3(htfm, P_curve[3] - vP);
-
- r_st = ((float4 &)P_curve[1]).w;
- r_en = ((float4 &)P_curve[2]).w;
-#endif /* __KERNEL_AVX2__ */
-
- float fc = 0.71f;
- ssef vfc = ssef(fc);
- ssef vfcxp3 = vfc * p3;
-
- vcurve_coef[0] = p1;
- vcurve_coef[1] = vfc * (p2 - p0);
- vcurve_coef[2] = madd(ssef(fc * 2.0f), p0, madd(ssef(fc - 3.0f), p1, msub(ssef(3.0f - 2.0f * fc), p2, vfcxp3)));
- vcurve_coef[3] = msub(ssef(fc - 2.0f), p2 - p1, msub(vfc, p0, vfcxp3));
-
- }
-#else
- float3 curve_coef[4];
-
- /* curve Intersection check */
- /* obtain curve parameters */
- {
- /* ray transform created - this should be created at beginning of intersection loop */
- Transform htfm;
- float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
- htfm = make_transform(
- dir.z / d, 0, -dir.x /d, 0,
- -dir.x * dir.y /d, d, -dir.y * dir.z /d, 0,
- dir.x, dir.y, dir.z, 0);
-
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int k0 = __float_as_int(v00.x) + segment;
- int k1 = k0 + 1;
-
- int ka = max(k0 - 1,__float_as_int(v00.x));
- int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
-
- float4 P_curve[4];
-
- if(is_curve_primitive) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, P_curve);
- }
-
- float3 p0 = transform_point(&htfm, float4_to_float3(P_curve[0]) - P);
- float3 p1 = transform_point(&htfm, float4_to_float3(P_curve[1]) - P);
- float3 p2 = transform_point(&htfm, float4_to_float3(P_curve[2]) - P);
- float3 p3 = transform_point(&htfm, float4_to_float3(P_curve[3]) - P);
-
- float fc = 0.71f;
- curve_coef[0] = p1;
- curve_coef[1] = -fc*p0 + fc*p2;
- curve_coef[2] = 2.0f * fc * p0 + (fc - 3.0f) * p1 + (3.0f - 2.0f * fc) * p2 - fc * p3;
- curve_coef[3] = -fc * p0 + (2.0f - fc) * p1 + (fc - 2.0f) * p2 + fc * p3;
- r_st = P_curve[1].w;
- r_en = P_curve[2].w;
- }
-#endif
-
- float r_curr = max(r_st, r_en);
-
- if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
- epsilon = 2 * r_curr;
-
- /* find bounds - this is slow for cubic curves */
- float upper, lower;
-
- float zextrem[4];
- curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
- if(lower - r_curr > isect->t || upper + r_curr < epsilon)
- return false;
-
- /* minimum width extension */
- float mw_extension = min(difl * fabsf(upper), extmax);
- float r_ext = mw_extension + r_curr;
-
- float xextrem[4];
- curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
- if(lower > r_ext || upper < -r_ext)
- return false;
-
- float yextrem[4];
- curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
- if(lower > r_ext || upper < -r_ext)
- return false;
-
- /* setup recurrent loop */
- int level = 1 << depth;
- int tree = 0;
- float resol = 1.0f / (float)level;
- bool hit = false;
-
- /* begin loop */
- while(!(tree >> (depth))) {
- const float i_st = tree * resol;
- const float i_en = i_st + (level * resol);
-
-#ifdef __KERNEL_SSE2__
- ssef vi_st = ssef(i_st), vi_en = ssef(i_en);
- ssef vp_st = madd(madd(madd(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]), vi_st, vcurve_coef[0]);
- ssef vp_en = madd(madd(madd(vcurve_coef[3], vi_en, vcurve_coef[2]), vi_en, vcurve_coef[1]), vi_en, vcurve_coef[0]);
-
- ssef vbmin = min(vp_st, vp_en);
- ssef vbmax = max(vp_st, vp_en);
-
- float3 &bmin = (float3 &)vbmin, &bmax = (float3 &)vbmax;
- float &bminx = bmin.x, &bminy = bmin.y, &bminz = bmin.z;
- float &bmaxx = bmax.x, &bmaxy = bmax.y, &bmaxz = bmax.z;
- float3 &p_st = (float3 &)vp_st, &p_en = (float3 &)vp_en;
-#else
- float3 p_st = ((curve_coef[3] * i_st + curve_coef[2]) * i_st + curve_coef[1]) * i_st + curve_coef[0];
- float3 p_en = ((curve_coef[3] * i_en + curve_coef[2]) * i_en + curve_coef[1]) * i_en + curve_coef[0];
-
- float bminx = min(p_st.x, p_en.x);
- float bmaxx = max(p_st.x, p_en.x);
- float bminy = min(p_st.y, p_en.y);
- float bmaxy = max(p_st.y, p_en.y);
- float bminz = min(p_st.z, p_en.z);
- float bmaxz = max(p_st.z, p_en.z);
-#endif
-
- if(xextrem[0] >= i_st && xextrem[0] <= i_en) {
- bminx = min(bminx,xextrem[1]);
- bmaxx = max(bmaxx,xextrem[1]);
- }
- if(xextrem[2] >= i_st && xextrem[2] <= i_en) {
- bminx = min(bminx,xextrem[3]);
- bmaxx = max(bmaxx,xextrem[3]);
- }
- if(yextrem[0] >= i_st && yextrem[0] <= i_en) {
- bminy = min(bminy,yextrem[1]);
- bmaxy = max(bmaxy,yextrem[1]);
- }
- if(yextrem[2] >= i_st && yextrem[2] <= i_en) {
- bminy = min(bminy,yextrem[3]);
- bmaxy = max(bmaxy,yextrem[3]);
- }
- if(zextrem[0] >= i_st && zextrem[0] <= i_en) {
- bminz = min(bminz,zextrem[1]);
- bmaxz = max(bmaxz,zextrem[1]);
- }
- if(zextrem[2] >= i_st && zextrem[2] <= i_en) {
- bminz = min(bminz,zextrem[3]);
- bmaxz = max(bmaxz,zextrem[3]);
- }
-
- float r1 = r_st + (r_en - r_st) * i_st;
- float r2 = r_st + (r_en - r_st) * i_en;
- r_curr = max(r1, r2);
-
- mw_extension = min(difl * fabsf(bmaxz), extmax);
- float r_ext = mw_extension + r_curr;
- float coverage = 1.0f;
-
- if(bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext|| bmaxx < -r_ext|| bminy > r_ext|| bmaxy < -r_ext) {
- /* the bounding box does not overlap the square centered at O */
- tree += level;
- level = tree & -tree;
- }
- else if(level == 1) {
-
- /* the maximum recursion depth is reached.
- * check if dP0.(Q-P0)>=0 and dPn.(Pn-Q)>=0.
- * dP* is reversed if necessary.*/
- float t = isect->t;
- float u = 0.0f;
- float gd = 0.0f;
-
- if(flags & CURVE_KN_RIBBONS) {
- float3 tg = (p_en - p_st);
-#ifdef __KERNEL_SSE__
- const float3 tg_sq = tg * tg;
- float w = tg_sq.x + tg_sq.y;
-#else
- float w = tg.x * tg.x + tg.y * tg.y;
-#endif
- if(w == 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
-#ifdef __KERNEL_SSE__
- const float3 p_sttg = p_st * tg;
- w = -(p_sttg.x + p_sttg.y) / w;
-#else
- w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
-#endif
- w = saturate(w);
-
- /* compute u on the curve segment */
- u = i_st * (1 - w) + i_en * w;
- r_curr = r_st + (r_en - r_st) * u;
- /* compare x-y distances */
- float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
-
- float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
- if(dot(tg, dp_st)< 0)
- dp_st *= -1;
- if(dot(dp_st, -p_st) + p_curr.z * dp_st.z < 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
- float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
- if(dot(tg, dp_en) < 0)
- dp_en *= -1;
- if(dot(dp_en, p_en) - p_curr.z * dp_en.z < 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- /* compute coverage */
- float r_ext = r_curr;
- coverage = 1.0f;
- if(difl != 0.0f) {
- mw_extension = min(difl * fabsf(bmaxz), extmax);
- r_ext = mw_extension + r_curr;
-#ifdef __KERNEL_SSE__
- const float3 p_curr_sq = p_curr * p_curr;
- const float3 dxxx(_mm_sqrt_ss(_mm_hadd_ps(p_curr_sq.m128, p_curr_sq.m128)));
- float d = dxxx.x;
-#else
- float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y);
-#endif
- float d0 = d - r_curr;
- float d1 = d + r_curr;
- float inv_mw_extension = 1.0f/mw_extension;
- if(d0 >= 0)
- coverage = (min(d1 * inv_mw_extension, 1.0f) - min(d0 * inv_mw_extension, 1.0f)) * 0.5f;
- else // inside
- coverage = (min(d1 * inv_mw_extension, 1.0f) + min(-d0 * inv_mw_extension, 1.0f)) * 0.5f;
- }
-
- if(p_curr.x * p_curr.x + p_curr.y * p_curr.y >= r_ext * r_ext || p_curr.z <= epsilon || isect->t < p_curr.z) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- t = p_curr.z;
-
- /* stochastic fade from minimum width */
- if(difl != 0.0f && lcg_state) {
- if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
- return hit;
- }
- }
- else {
- float l = len(p_en - p_st);
- /* minimum width extension */
- float or1 = r1;
- float or2 = r2;
-
- if(difl != 0.0f) {
- mw_extension = min(len(p_st - P) * difl, extmax);
- or1 = r1 < mw_extension ? mw_extension : r1;
- mw_extension = min(len(p_en - P) * difl, extmax);
- or2 = r2 < mw_extension ? mw_extension : r2;
- }
- /* --- */
- float invl = 1.0f/l;
- float3 tg = (p_en - p_st) * invl;
- gd = (or2 - or1) * invl;
- float difz = -dot(p_st,tg);
- float cyla = 1.0f - (tg.z * tg.z * (1 + gd*gd));
- float invcyla = 1.0f/cyla;
- float halfb = (-p_st.z - tg.z*(difz + gd*(difz*gd + or1)));
- float tcentre = -halfb*invcyla;
- float zcentre = difz + (tg.z * tcentre);
- float3 tdif = - p_st;
- tdif.z += tcentre;
- float tdifz = dot(tdif,tg);
- float tb = 2*(tdif.z - tg.z*(tdifz + gd*(tdifz*gd + or1)));
- float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - or1*or1 - 2*or1*tdifz*gd;
- float td = tb*tb - 4*cyla*tc;
- if(td < 0.0f) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- float rootd = sqrtf(td);
- float correction = (-tb - rootd) * 0.5f * invcyla;
- t = tcentre + correction;
-
- float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
- if(dot(tg, dp_st)< 0)
- dp_st *= -1;
- float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
- if(dot(tg, dp_en) < 0)
- dp_en *= -1;
-
- if(flags & CURVE_KN_BACKFACING && (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f)) {
- correction = (-tb + rootd) * 0.5f * invcyla;
- t = tcentre + correction;
- }
-
- if(dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- float w = (zcentre + (tg.z * correction)) * invl;
- w = saturate(w);
- /* compute u on the curve segment */
- u = i_st * (1 - w) + i_en * w;
-
- /* stochastic fade from minimum width */
- if(difl != 0.0f && lcg_state) {
- r_curr = r1 + (r2 - r1) * w;
- r_ext = or1 + (or2 - or1) * w;
- coverage = r_curr/r_ext;
-
- if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
- return hit;
- }
- }
- /* we found a new intersection */
-
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->t = t;
- isect->u = u;
- isect->v = gd;
- isect->prim = curveAddr;
- isect->object = object;
- isect->type = type;
- hit = true;
- }
-
- tree++;
- level = tree & -tree;
- }
- else {
- /* split the curve into two curves and process */
- level = level >> 1;
- }
- }
-
- return hit;
+ const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
+
+ if (!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
+ const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
+ if (time < prim_time.x || time > prim_time.y) {
+ return false;
+ }
+ }
+
+ int segment = PRIMITIVE_UNPACK_SEGMENT(type);
+ float epsilon = 0.0f;
+ float r_st, r_en;
+
+ int depth = kernel_data.curve.subdivisions;
+ int flags = kernel_data.curve.curveflags;
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+
+# ifdef __KERNEL_SSE2__
+ ssef vdir = load4f(dir);
+ ssef vcurve_coef[4];
+ const float3 *curve_coef = (float3 *)vcurve_coef;
+
+ {
+ ssef dtmp = vdir * vdir;
+ ssef d_ss = mm_sqrt(dtmp + shuffle<2>(dtmp));
+ ssef rd_ss = load1f_first(1.0f) / d_ss;
+
+ ssei v00vec = load4i((ssei *)&kg->__curves.data[prim]);
+ int2 &v00 = (int2 &)v00vec;
+
+ int k0 = v00.x + segment;
+ int k1 = k0 + 1;
+ int ka = max(k0 - 1, v00.x);
+ int kb = min(k1 + 1, v00.x + v00.y - 1);
+
+# if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && \
+ (!defined(_MSC_VER) || _MSC_VER > 1800)
+ avxf P_curve_0_1, P_curve_2_3;
+ if (is_curve_primitive) {
+ P_curve_0_1 = _mm256_loadu2_m128(&kg->__curve_keys.data[k0].x, &kg->__curve_keys.data[ka].x);
+ P_curve_2_3 = _mm256_loadu2_m128(&kg->__curve_keys.data[kb].x, &kg->__curve_keys.data[k1].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
+ motion_cardinal_curve_keys_avx(
+ kg, fobject, prim, time, ka, k0, k1, kb, &P_curve_0_1, &P_curve_2_3);
+ }
+# else /* __KERNEL_AVX2__ */
+ ssef P_curve[4];
+
+ if (is_curve_primitive) {
+ P_curve[0] = load4f(&kg->__curve_keys.data[ka].x);
+ P_curve[1] = load4f(&kg->__curve_keys.data[k0].x);
+ P_curve[2] = load4f(&kg->__curve_keys.data[k1].x);
+ P_curve[3] = load4f(&kg->__curve_keys.data[kb].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4 *)&P_curve);
+ }
+# endif /* __KERNEL_AVX2__ */
+
+ ssef rd_sgn = set_sign_bit<0, 1, 1, 1>(shuffle<0>(rd_ss));
+ ssef mul_zxxy = shuffle<2, 0, 0, 1>(vdir) * rd_sgn;
+ ssef mul_yz = shuffle<1, 2, 1, 2>(vdir) * mul_zxxy;
+ ssef mul_shuf = shuffle<0, 1, 2, 3>(mul_zxxy, mul_yz);
+ ssef vdir0 = vdir & cast(ssei(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0));
+
+ ssef htfm0 = shuffle<0, 2, 0, 3>(mul_shuf, vdir0);
+ ssef htfm1 = shuffle<1, 0, 1, 3>(load1f_first(extract<0>(d_ss)), vdir0);
+ ssef htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0);
+
+# if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && \
+ (!defined(_MSC_VER) || _MSC_VER > 1800)
+ const avxf vPP = _mm256_broadcast_ps(&P.m128);
+ const avxf htfm00 = avxf(htfm0.m128, htfm0.m128);
+ const avxf htfm11 = avxf(htfm1.m128, htfm1.m128);
+ const avxf htfm22 = avxf(htfm2.m128, htfm2.m128);
+
+ const avxf p01 = madd(
+ shuffle<0>(P_curve_0_1 - vPP),
+ htfm00,
+ madd(shuffle<1>(P_curve_0_1 - vPP), htfm11, shuffle<2>(P_curve_0_1 - vPP) * htfm22));
+ const avxf p23 = madd(
+ shuffle<0>(P_curve_2_3 - vPP),
+ htfm00,
+ madd(shuffle<1>(P_curve_2_3 - vPP), htfm11, shuffle<2>(P_curve_2_3 - vPP) * htfm22));
+
+ const ssef p0 = _mm256_castps256_ps128(p01);
+ const ssef p1 = _mm256_extractf128_ps(p01, 1);
+ const ssef p2 = _mm256_castps256_ps128(p23);
+ const ssef p3 = _mm256_extractf128_ps(p23, 1);
+
+ const ssef P_curve_1 = _mm256_extractf128_ps(P_curve_0_1, 1);
+ r_st = ((float4 &)P_curve_1).w;
+ const ssef P_curve_2 = _mm256_castps256_ps128(P_curve_2_3);
+ r_en = ((float4 &)P_curve_2).w;
+# else /* __KERNEL_AVX2__ */
+ ssef htfm[] = {htfm0, htfm1, htfm2};
+ ssef vP = load4f(P);
+ ssef p0 = transform_point_T3(htfm, P_curve[0] - vP);
+ ssef p1 = transform_point_T3(htfm, P_curve[1] - vP);
+ ssef p2 = transform_point_T3(htfm, P_curve[2] - vP);
+ ssef p3 = transform_point_T3(htfm, P_curve[3] - vP);
+
+ r_st = ((float4 &)P_curve[1]).w;
+ r_en = ((float4 &)P_curve[2]).w;
+# endif /* __KERNEL_AVX2__ */
+
+ float fc = 0.71f;
+ ssef vfc = ssef(fc);
+ ssef vfcxp3 = vfc * p3;
+
+ vcurve_coef[0] = p1;
+ vcurve_coef[1] = vfc * (p2 - p0);
+ vcurve_coef[2] = madd(
+ ssef(fc * 2.0f), p0, madd(ssef(fc - 3.0f), p1, msub(ssef(3.0f - 2.0f * fc), p2, vfcxp3)));
+ vcurve_coef[3] = msub(ssef(fc - 2.0f), p2 - p1, msub(vfc, p0, vfcxp3));
+ }
+# else
+ float3 curve_coef[4];
+
+ /* curve Intersection check */
+ /* obtain curve parameters */
+ {
+ /* ray transform created - this should be created at beginning of intersection loop */
+ Transform htfm;
+ float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
+ htfm = make_transform(dir.z / d,
+ 0,
+ -dir.x / d,
+ 0,
+ -dir.x * dir.y / d,
+ d,
+ -dir.y * dir.z / d,
+ 0,
+ dir.x,
+ dir.y,
+ dir.z,
+ 0);
+
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ int ka = max(k0 - 1, __float_as_int(v00.x));
+ int kb = min(k1 + 1, __float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P_curve[4];
+
+ if (is_curve_primitive) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, P_curve);
+ }
+
+ float3 p0 = transform_point(&htfm, float4_to_float3(P_curve[0]) - P);
+ float3 p1 = transform_point(&htfm, float4_to_float3(P_curve[1]) - P);
+ float3 p2 = transform_point(&htfm, float4_to_float3(P_curve[2]) - P);
+ float3 p3 = transform_point(&htfm, float4_to_float3(P_curve[3]) - P);
+
+ float fc = 0.71f;
+ curve_coef[0] = p1;
+ curve_coef[1] = -fc * p0 + fc * p2;
+ curve_coef[2] = 2.0f * fc * p0 + (fc - 3.0f) * p1 + (3.0f - 2.0f * fc) * p2 - fc * p3;
+ curve_coef[3] = -fc * p0 + (2.0f - fc) * p1 + (fc - 2.0f) * p2 + fc * p3;
+ r_st = P_curve[1].w;
+ r_en = P_curve[2].w;
+ }
+# endif
+
+ float r_curr = max(r_st, r_en);
+
+ if ((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
+ epsilon = 2 * r_curr;
+
+ /* find bounds - this is slow for cubic curves */
+ float upper, lower;
+
+ float zextrem[4];
+ curvebounds(&lower,
+ &upper,
+ &zextrem[0],
+ &zextrem[1],
+ &zextrem[2],
+ &zextrem[3],
+ curve_coef[0].z,
+ curve_coef[1].z,
+ curve_coef[2].z,
+ curve_coef[3].z);
+ if (lower - r_curr > isect->t || upper + r_curr < epsilon)
+ return false;
+
+ /* minimum width extension */
+ float mw_extension = min(difl * fabsf(upper), extmax);
+ float r_ext = mw_extension + r_curr;
+
+ float xextrem[4];
+ curvebounds(&lower,
+ &upper,
+ &xextrem[0],
+ &xextrem[1],
+ &xextrem[2],
+ &xextrem[3],
+ curve_coef[0].x,
+ curve_coef[1].x,
+ curve_coef[2].x,
+ curve_coef[3].x);
+ if (lower > r_ext || upper < -r_ext)
+ return false;
+
+ float yextrem[4];
+ curvebounds(&lower,
+ &upper,
+ &yextrem[0],
+ &yextrem[1],
+ &yextrem[2],
+ &yextrem[3],
+ curve_coef[0].y,
+ curve_coef[1].y,
+ curve_coef[2].y,
+ curve_coef[3].y);
+ if (lower > r_ext || upper < -r_ext)
+ return false;
+
+ /* setup recurrent loop */
+ int level = 1 << depth;
+ int tree = 0;
+ float resol = 1.0f / (float)level;
+ bool hit = false;
+
+ /* begin loop */
+ while (!(tree >> (depth))) {
+ const float i_st = tree * resol;
+ const float i_en = i_st + (level * resol);
+
+# ifdef __KERNEL_SSE2__
+ ssef vi_st = ssef(i_st), vi_en = ssef(i_en);
+ ssef vp_st = madd(madd(madd(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]),
+ vi_st,
+ vcurve_coef[0]);
+ ssef vp_en = madd(madd(madd(vcurve_coef[3], vi_en, vcurve_coef[2]), vi_en, vcurve_coef[1]),
+ vi_en,
+ vcurve_coef[0]);
+
+ ssef vbmin = min(vp_st, vp_en);
+ ssef vbmax = max(vp_st, vp_en);
+
+ float3 &bmin = (float3 &)vbmin, &bmax = (float3 &)vbmax;
+ float &bminx = bmin.x, &bminy = bmin.y, &bminz = bmin.z;
+ float &bmaxx = bmax.x, &bmaxy = bmax.y, &bmaxz = bmax.z;
+ float3 &p_st = (float3 &)vp_st, &p_en = (float3 &)vp_en;
+# else
+ float3 p_st = ((curve_coef[3] * i_st + curve_coef[2]) * i_st + curve_coef[1]) * i_st +
+ curve_coef[0];
+ float3 p_en = ((curve_coef[3] * i_en + curve_coef[2]) * i_en + curve_coef[1]) * i_en +
+ curve_coef[0];
+
+ float bminx = min(p_st.x, p_en.x);
+ float bmaxx = max(p_st.x, p_en.x);
+ float bminy = min(p_st.y, p_en.y);
+ float bmaxy = max(p_st.y, p_en.y);
+ float bminz = min(p_st.z, p_en.z);
+ float bmaxz = max(p_st.z, p_en.z);
+# endif
+
+ if (xextrem[0] >= i_st && xextrem[0] <= i_en) {
+ bminx = min(bminx, xextrem[1]);
+ bmaxx = max(bmaxx, xextrem[1]);
+ }
+ if (xextrem[2] >= i_st && xextrem[2] <= i_en) {
+ bminx = min(bminx, xextrem[3]);
+ bmaxx = max(bmaxx, xextrem[3]);
+ }
+ if (yextrem[0] >= i_st && yextrem[0] <= i_en) {
+ bminy = min(bminy, yextrem[1]);
+ bmaxy = max(bmaxy, yextrem[1]);
+ }
+ if (yextrem[2] >= i_st && yextrem[2] <= i_en) {
+ bminy = min(bminy, yextrem[3]);
+ bmaxy = max(bmaxy, yextrem[3]);
+ }
+ if (zextrem[0] >= i_st && zextrem[0] <= i_en) {
+ bminz = min(bminz, zextrem[1]);
+ bmaxz = max(bmaxz, zextrem[1]);
+ }
+ if (zextrem[2] >= i_st && zextrem[2] <= i_en) {
+ bminz = min(bminz, zextrem[3]);
+ bmaxz = max(bmaxz, zextrem[3]);
+ }
+
+ float r1 = r_st + (r_en - r_st) * i_st;
+ float r2 = r_st + (r_en - r_st) * i_en;
+ r_curr = max(r1, r2);
+
+ mw_extension = min(difl * fabsf(bmaxz), extmax);
+ float r_ext = mw_extension + r_curr;
+ float coverage = 1.0f;
+
+ if (bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext || bmaxx < -r_ext ||
+ bminy > r_ext || bmaxy < -r_ext) {
+ /* the bounding box does not overlap the square centered at O */
+ tree += level;
+ level = tree & -tree;
+ }
+ else if (level == 1) {
+
+ /* the maximum recursion depth is reached.
+ * check if dP0.(Q-P0)>=0 and dPn.(Pn-Q)>=0.
+ * dP* is reversed if necessary.*/
+ float t = isect->t;
+ float u = 0.0f;
+ float gd = 0.0f;
+
+ if (flags & CURVE_KN_RIBBONS) {
+ float3 tg = (p_en - p_st);
+# ifdef __KERNEL_SSE__
+ const float3 tg_sq = tg * tg;
+ float w = tg_sq.x + tg_sq.y;
+# else
+ float w = tg.x * tg.x + tg.y * tg.y;
+# endif
+ if (w == 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+# ifdef __KERNEL_SSE__
+ const float3 p_sttg = p_st * tg;
+ w = -(p_sttg.x + p_sttg.y) / w;
+# else
+ w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
+# endif
+ w = saturate(w);
+
+ /* compute u on the curve segment */
+ u = i_st * (1 - w) + i_en * w;
+ r_curr = r_st + (r_en - r_st) * u;
+ /* compare x-y distances */
+ float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u +
+ curve_coef[0];
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if (dot(tg, dp_st) < 0)
+ dp_st *= -1;
+ if (dot(dp_st, -p_st) + p_curr.z * dp_st.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if (dot(tg, dp_en) < 0)
+ dp_en *= -1;
+ if (dot(dp_en, p_en) - p_curr.z * dp_en.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ /* compute coverage */
+ float r_ext = r_curr;
+ coverage = 1.0f;
+ if (difl != 0.0f) {
+ mw_extension = min(difl * fabsf(bmaxz), extmax);
+ r_ext = mw_extension + r_curr;
+# ifdef __KERNEL_SSE__
+ const float3 p_curr_sq = p_curr * p_curr;
+ const float3 dxxx(_mm_sqrt_ss(_mm_hadd_ps(p_curr_sq.m128, p_curr_sq.m128)));
+ float d = dxxx.x;
+# else
+ float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y);
+# endif
+ float d0 = d - r_curr;
+ float d1 = d + r_curr;
+ float inv_mw_extension = 1.0f / mw_extension;
+ if (d0 >= 0)
+ coverage = (min(d1 * inv_mw_extension, 1.0f) - min(d0 * inv_mw_extension, 1.0f)) *
+ 0.5f;
+ else // inside
+ coverage = (min(d1 * inv_mw_extension, 1.0f) + min(-d0 * inv_mw_extension, 1.0f)) *
+ 0.5f;
+ }
+
+ if (p_curr.x * p_curr.x + p_curr.y * p_curr.y >= r_ext * r_ext || p_curr.z <= epsilon ||
+ isect->t < p_curr.z) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ t = p_curr.z;
+
+ /* stochastic fade from minimum width */
+ if (difl != 0.0f && lcg_state) {
+ if (coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
+ return hit;
+ }
+ }
+ else {
+ float l = len(p_en - p_st);
+ /* minimum width extension */
+ float or1 = r1;
+ float or2 = r2;
+
+ if (difl != 0.0f) {
+ mw_extension = min(len(p_st - P) * difl, extmax);
+ or1 = r1 < mw_extension ? mw_extension : r1;
+ mw_extension = min(len(p_en - P) * difl, extmax);
+ or2 = r2 < mw_extension ? mw_extension : r2;
+ }
+ /* --- */
+ float invl = 1.0f / l;
+ float3 tg = (p_en - p_st) * invl;
+ gd = (or2 - or1) * invl;
+ float difz = -dot(p_st, tg);
+ float cyla = 1.0f - (tg.z * tg.z * (1 + gd * gd));
+ float invcyla = 1.0f / cyla;
+ float halfb = (-p_st.z - tg.z * (difz + gd * (difz * gd + or1)));
+ float tcentre = -halfb * invcyla;
+ float zcentre = difz + (tg.z * tcentre);
+ float3 tdif = -p_st;
+ tdif.z += tcentre;
+ float tdifz = dot(tdif, tg);
+ float tb = 2 * (tdif.z - tg.z * (tdifz + gd * (tdifz * gd + or1)));
+ float tc = dot(tdif, tdif) - tdifz * tdifz * (1 + gd * gd) - or1 * or1 -
+ 2 * or1 * tdifz * gd;
+ float td = tb * tb - 4 * cyla * tc;
+ if (td < 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ float rootd = sqrtf(td);
+ float correction = (-tb - rootd) * 0.5f * invcyla;
+ t = tcentre + correction;
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if (dot(tg, dp_st) < 0)
+ dp_st *= -1;
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if (dot(tg, dp_en) < 0)
+ dp_en *= -1;
+
+ if (flags & CURVE_KN_BACKFACING &&
+ (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 ||
+ isect->t < t || t <= 0.0f)) {
+ correction = (-tb + rootd) * 0.5f * invcyla;
+ t = tcentre + correction;
+ }
+
+ if (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 ||
+ isect->t < t || t <= 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ float w = (zcentre + (tg.z * correction)) * invl;
+ w = saturate(w);
+ /* compute u on the curve segment */
+ u = i_st * (1 - w) + i_en * w;
+
+ /* stochastic fade from minimum width */
+ if (difl != 0.0f && lcg_state) {
+ r_curr = r1 + (r2 - r1) * w;
+ r_ext = or1 + (or2 - or1) * w;
+ coverage = r_curr / r_ext;
+
+ if (coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
+ return hit;
+ }
+ }
+ /* we found a new intersection */
+
+# ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if (kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+# endif
+ {
+ /* record intersection */
+ isect->t = t;
+ isect->u = u;
+ isect->v = gd;
+ isect->prim = curveAddr;
+ isect->object = object;
+ isect->type = type;
+ hit = true;
+ }
+
+ tree++;
+ level = tree & -tree;
+ }
+ else {
+ /* split the curve into two curves and process */
+ level = level >> 1;
+ }
+ }
+
+ return hit;
}
ccl_device_forceinline bool curve_intersect(KernelGlobals *kg,
@@ -511,245 +561,247 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals *kg,
float difl,
float extmax)
{
- /* define few macros to minimize code duplication for SSE */
-#ifndef __KERNEL_SSE2__
-# define len3_squared(x) len_squared(x)
-# define len3(x) len(x)
-# define dot3(x, y) dot(x, y)
-#endif
-
- const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
-
- if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
- if(time < prim_time.x || time > prim_time.y) {
- return false;
- }
- }
-
- int segment = PRIMITIVE_UNPACK_SEGMENT(type);
- /* curve Intersection check */
- int flags = kernel_data.curve.curveflags;
-
- int prim = kernel_tex_fetch(__prim_index, curveAddr);
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int cnum = __float_as_int(v00.x);
- int k0 = cnum + segment;
- int k1 = k0 + 1;
-
-#ifndef __KERNEL_SSE2__
- float4 P_curve[2];
-
- if(is_curve_primitive) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_curve_keys(kg, fobject, prim, time, k0, k1, P_curve);
- }
-
- float or1 = P_curve[0].w;
- float or2 = P_curve[1].w;
- float3 p1 = float4_to_float3(P_curve[0]);
- float3 p2 = float4_to_float3(P_curve[1]);
-
- /* minimum width extension */
- float r1 = or1;
- float r2 = or2;
- float3 dif = P - p1;
- float3 dif_second = P - p2;
- if(difl != 0.0f) {
- float pixelsize = min(len3(dif) * difl, extmax);
- r1 = or1 < pixelsize ? pixelsize : or1;
- pixelsize = min(len3(dif_second) * difl, extmax);
- r2 = or2 < pixelsize ? pixelsize : or2;
- }
- /* --- */
-
- float3 p21_diff = p2 - p1;
- float3 sphere_dif1 = (dif + dif_second) * 0.5f;
- float3 dir = direction;
- float sphere_b_tmp = dot3(dir, sphere_dif1);
- float3 sphere_dif2 = sphere_dif1 - sphere_b_tmp * dir;
-#else
- ssef P_curve[2];
-
- if(is_curve_primitive) {
- P_curve[0] = load4f(&kg->__curve_keys.data[k0].x);
- P_curve[1] = load4f(&kg->__curve_keys.data[k1].x);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_curve_keys(kg, fobject, prim, time, k0, k1, (float4*)&P_curve);
- }
-
- const ssef or12 = shuffle<3, 3, 3, 3>(P_curve[0], P_curve[1]);
-
- ssef r12 = or12;
- const ssef vP = load4f(P);
- const ssef dif = vP - P_curve[0];
- const ssef dif_second = vP - P_curve[1];
- if(difl != 0.0f) {
- const ssef len1_sq = len3_squared_splat(dif);
- const ssef len2_sq = len3_squared_splat(dif_second);
- const ssef len12 = mm_sqrt(shuffle<0, 0, 0, 0>(len1_sq, len2_sq));
- const ssef pixelsize12 = min(len12 * difl, ssef(extmax));
- r12 = max(or12, pixelsize12);
- }
- float or1 = extract<0>(or12), or2 = extract<0>(shuffle<2>(or12));
- float r1 = extract<0>(r12), r2 = extract<0>(shuffle<2>(r12));
-
- const ssef p21_diff = P_curve[1] - P_curve[0];
- const ssef sphere_dif1 = (dif + dif_second) * 0.5f;
- const ssef dir = load4f(direction);
- const ssef sphere_b_tmp = dot3_splat(dir, sphere_dif1);
- const ssef sphere_dif2 = nmadd(sphere_b_tmp, dir, sphere_dif1);
-#endif
-
- float mr = max(r1, r2);
- float l = len3(p21_diff);
- float invl = 1.0f / l;
- float sp_r = mr + 0.5f * l;
-
- float sphere_b = dot3(dir, sphere_dif2);
- float sdisc = sphere_b * sphere_b - len3_squared(sphere_dif2) + sp_r * sp_r;
-
- if(sdisc < 0.0f)
- return false;
-
- /* obtain parameters and test midpoint distance for suitable modes */
-#ifndef __KERNEL_SSE2__
- float3 tg = p21_diff * invl;
-#else
- const ssef tg = p21_diff * invl;
-#endif
- float gd = (r2 - r1) * invl;
-
- float dirz = dot3(dir, tg);
- float difz = dot3(dif, tg);
-
- float a = 1.0f - (dirz*dirz*(1 + gd*gd));
-
- float halfb = dot3(dir, dif) - dirz*(difz + gd*(difz*gd + r1));
-
- float tcentre = -halfb/a;
- float zcentre = difz + (dirz * tcentre);
-
- if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
- return false;
- if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
- return false;
-
- /* test minimum separation */
-#ifndef __KERNEL_SSE2__
- float3 cprod = cross(tg, dir);
- float cprod2sq = len3_squared(cross(tg, dif));
-#else
- const ssef cprod = cross(tg, dir);
- float cprod2sq = len3_squared(cross_zxy(tg, dif));
-#endif
- float cprodsq = len3_squared(cprod);
- float distscaled = dot3(cprod, dif);
-
- if(cprodsq == 0)
- distscaled = cprod2sq;
- else
- distscaled = (distscaled*distscaled)/cprodsq;
-
- if(distscaled > mr*mr)
- return false;
-
- /* calculate true intersection */
-#ifndef __KERNEL_SSE2__
- float3 tdif = dif + tcentre * dir;
-#else
- const ssef tdif = madd(ssef(tcentre), dir, dif);
-#endif
- float tdifz = dot3(tdif, tg);
- float tdifma = tdifz*gd + r1;
- float tb = 2*(dot3(dir, tdif) - dirz*(tdifz + gd*tdifma));
- float tc = dot3(tdif, tdif) - tdifz*tdifz - tdifma*tdifma;
- float td = tb*tb - 4*a*tc;
-
- if(td < 0.0f)
- return false;
-
- float rootd = 0.0f;
- float correction = 0.0f;
- if(flags & CURVE_KN_ACCURATE) {
- rootd = sqrtf(td);
- correction = ((-tb - rootd)/(2*a));
- }
-
- float t = tcentre + correction;
-
- if(t < isect->t) {
-
- if(flags & CURVE_KN_INTERSECTCORRECTION) {
- rootd = sqrtf(td);
- correction = ((-tb - rootd)/(2*a));
- t = tcentre + correction;
- }
-
- float z = zcentre + (dirz * correction);
- // bool backface = false;
-
- if(flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
- // backface = true;
- correction = ((-tb + rootd)/(2*a));
- t = tcentre + correction;
- z = zcentre + (dirz * correction);
- }
-
- /* stochastic fade from minimum width */
- float adjradius = or1 + z * (or2 - or1) * invl;
- adjradius = adjradius / (r1 + z * gd);
- if(lcg_state && adjradius != 1.0f) {
- if(lcg_step_float(lcg_state) > adjradius)
- return false;
- }
- /* --- */
-
- if(t > 0.0f && t < isect->t && z >= 0 && z <= l) {
-
- if(flags & CURVE_KN_ENCLOSEFILTER) {
- float enc_ratio = 1.01f;
- if((difz > -r1 * enc_ratio) && (dot3(dif_second, tg) < r2 * enc_ratio)) {
- float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
- float c2 = dot3(dif, dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
- if(a2*c2 < 0.0f)
- return false;
- }
- }
-
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->t = t;
- isect->u = z*invl;
- isect->v = gd;
- isect->prim = curveAddr;
- isect->object = object;
- isect->type = type;
-
- return true;
- }
- }
- }
-
- return false;
-
-#ifndef __KERNEL_SSE2__
-# undef len3_squared
-# undef len3
-# undef dot3
-#endif
+ /* define few macros to minimize code duplication for SSE */
+# ifndef __KERNEL_SSE2__
+# define len3_squared(x) len_squared(x)
+# define len3(x) len(x)
+# define dot3(x, y) dot(x, y)
+# endif
+
+ const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
+
+ if (!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
+ const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
+ if (time < prim_time.x || time > prim_time.y) {
+ return false;
+ }
+ }
+
+ int segment = PRIMITIVE_UNPACK_SEGMENT(type);
+ /* curve Intersection check */
+ int flags = kernel_data.curve.curveflags;
+
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int cnum = __float_as_int(v00.x);
+ int k0 = cnum + segment;
+ int k1 = k0 + 1;
+
+# ifndef __KERNEL_SSE2__
+ float4 P_curve[2];
+
+ if (is_curve_primitive) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, P_curve);
+ }
+
+ float or1 = P_curve[0].w;
+ float or2 = P_curve[1].w;
+ float3 p1 = float4_to_float3(P_curve[0]);
+ float3 p2 = float4_to_float3(P_curve[1]);
+
+ /* minimum width extension */
+ float r1 = or1;
+ float r2 = or2;
+ float3 dif = P - p1;
+ float3 dif_second = P - p2;
+ if (difl != 0.0f) {
+ float pixelsize = min(len3(dif) * difl, extmax);
+ r1 = or1 < pixelsize ? pixelsize : or1;
+ pixelsize = min(len3(dif_second) * difl, extmax);
+ r2 = or2 < pixelsize ? pixelsize : or2;
+ }
+ /* --- */
+
+ float3 p21_diff = p2 - p1;
+ float3 sphere_dif1 = (dif + dif_second) * 0.5f;
+ float3 dir = direction;
+ float sphere_b_tmp = dot3(dir, sphere_dif1);
+ float3 sphere_dif2 = sphere_dif1 - sphere_b_tmp * dir;
+# else
+ ssef P_curve[2];
+
+ if (is_curve_primitive) {
+ P_curve[0] = load4f(&kg->__curve_keys.data[k0].x);
+ P_curve[1] = load4f(&kg->__curve_keys.data[k1].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, (float4 *)&P_curve);
+ }
+
+ const ssef or12 = shuffle<3, 3, 3, 3>(P_curve[0], P_curve[1]);
+
+ ssef r12 = or12;
+ const ssef vP = load4f(P);
+ const ssef dif = vP - P_curve[0];
+ const ssef dif_second = vP - P_curve[1];
+ if (difl != 0.0f) {
+ const ssef len1_sq = len3_squared_splat(dif);
+ const ssef len2_sq = len3_squared_splat(dif_second);
+ const ssef len12 = mm_sqrt(shuffle<0, 0, 0, 0>(len1_sq, len2_sq));
+ const ssef pixelsize12 = min(len12 * difl, ssef(extmax));
+ r12 = max(or12, pixelsize12);
+ }
+ float or1 = extract<0>(or12), or2 = extract<0>(shuffle<2>(or12));
+ float r1 = extract<0>(r12), r2 = extract<0>(shuffle<2>(r12));
+
+ const ssef p21_diff = P_curve[1] - P_curve[0];
+ const ssef sphere_dif1 = (dif + dif_second) * 0.5f;
+ const ssef dir = load4f(direction);
+ const ssef sphere_b_tmp = dot3_splat(dir, sphere_dif1);
+ const ssef sphere_dif2 = nmadd(sphere_b_tmp, dir, sphere_dif1);
+# endif
+
+ float mr = max(r1, r2);
+ float l = len3(p21_diff);
+ float invl = 1.0f / l;
+ float sp_r = mr + 0.5f * l;
+
+ float sphere_b = dot3(dir, sphere_dif2);
+ float sdisc = sphere_b * sphere_b - len3_squared(sphere_dif2) + sp_r * sp_r;
+
+ if (sdisc < 0.0f)
+ return false;
+
+ /* obtain parameters and test midpoint distance for suitable modes */
+# ifndef __KERNEL_SSE2__
+ float3 tg = p21_diff * invl;
+# else
+ const ssef tg = p21_diff * invl;
+# endif
+ float gd = (r2 - r1) * invl;
+
+ float dirz = dot3(dir, tg);
+ float difz = dot3(dif, tg);
+
+ float a = 1.0f - (dirz * dirz * (1 + gd * gd));
+
+ float halfb = dot3(dir, dif) - dirz * (difz + gd * (difz * gd + r1));
+
+ float tcentre = -halfb / a;
+ float zcentre = difz + (dirz * tcentre);
+
+ if ((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
+ return false;
+ if ((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) &&
+ !(flags & CURVE_KN_INTERSECTCORRECTION))
+ return false;
+
+ /* test minimum separation */
+# ifndef __KERNEL_SSE2__
+ float3 cprod = cross(tg, dir);
+ float cprod2sq = len3_squared(cross(tg, dif));
+# else
+ const ssef cprod = cross(tg, dir);
+ float cprod2sq = len3_squared(cross_zxy(tg, dif));
+# endif
+ float cprodsq = len3_squared(cprod);
+ float distscaled = dot3(cprod, dif);
+
+ if (cprodsq == 0)
+ distscaled = cprod2sq;
+ else
+ distscaled = (distscaled * distscaled) / cprodsq;
+
+ if (distscaled > mr * mr)
+ return false;
+
+ /* calculate true intersection */
+# ifndef __KERNEL_SSE2__
+ float3 tdif = dif + tcentre * dir;
+# else
+ const ssef tdif = madd(ssef(tcentre), dir, dif);
+# endif
+ float tdifz = dot3(tdif, tg);
+ float tdifma = tdifz * gd + r1;
+ float tb = 2 * (dot3(dir, tdif) - dirz * (tdifz + gd * tdifma));
+ float tc = dot3(tdif, tdif) - tdifz * tdifz - tdifma * tdifma;
+ float td = tb * tb - 4 * a * tc;
+
+ if (td < 0.0f)
+ return false;
+
+ float rootd = 0.0f;
+ float correction = 0.0f;
+ if (flags & CURVE_KN_ACCURATE) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd) / (2 * a));
+ }
+
+ float t = tcentre + correction;
+
+ if (t < isect->t) {
+
+ if (flags & CURVE_KN_INTERSECTCORRECTION) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd) / (2 * a));
+ t = tcentre + correction;
+ }
+
+ float z = zcentre + (dirz * correction);
+ // bool backface = false;
+
+ if (flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
+ // backface = true;
+ correction = ((-tb + rootd) / (2 * a));
+ t = tcentre + correction;
+ z = zcentre + (dirz * correction);
+ }
+
+ /* stochastic fade from minimum width */
+ float adjradius = or1 + z * (or2 - or1) * invl;
+ adjradius = adjradius / (r1 + z * gd);
+ if (lcg_state && adjradius != 1.0f) {
+ if (lcg_step_float(lcg_state) > adjradius)
+ return false;
+ }
+ /* --- */
+
+ if (t > 0.0f && t < isect->t && z >= 0 && z <= l) {
+
+ if (flags & CURVE_KN_ENCLOSEFILTER) {
+ float enc_ratio = 1.01f;
+ if ((difz > -r1 * enc_ratio) && (dot3(dif_second, tg) < r2 * enc_ratio)) {
+ float a2 = 1.0f - (dirz * dirz * (1 + gd * gd * enc_ratio * enc_ratio));
+ float c2 = dot3(dif, dif) - difz * difz * (1 + gd * gd * enc_ratio * enc_ratio) -
+ r1 * r1 * enc_ratio * enc_ratio - 2 * r1 * difz * gd * enc_ratio;
+ if (a2 * c2 < 0.0f)
+ return false;
+ }
+ }
+
+# ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if (kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+# endif
+ {
+ /* record intersection */
+ isect->t = t;
+ isect->u = z * invl;
+ isect->v = gd;
+ isect->prim = curveAddr;
+ isect->object = object;
+ isect->type = type;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+
+# ifndef __KERNEL_SSE2__
+# undef len3_squared
+# undef len3
+# undef dot3
+# endif
}
ccl_device_inline float3 curve_refine(KernelGlobals *kg,
@@ -757,154 +809,154 @@ ccl_device_inline float3 curve_refine(KernelGlobals *kg,
const Intersection *isect,
const Ray *ray)
{
- int flag = kernel_data.curve.curveflags;
- float t = isect->t;
- float3 P = ray->P;
- float3 D = ray->D;
-
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
-
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
- int k1 = k0 + 1;
-
- float3 tg;
-
- if(flag & CURVE_KN_INTERPOLATE) {
- int ka = max(k0 - 1,__float_as_int(v00.x));
- int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
-
- float4 P_curve[4];
-
- if(sd->type & PRIMITIVE_CURVE) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
- }
- else {
- motion_cardinal_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
- }
-
- float3 p[4];
- p[0] = float4_to_float3(P_curve[0]);
- p[1] = float4_to_float3(P_curve[1]);
- p[2] = float4_to_float3(P_curve[2]);
- p[3] = float4_to_float3(P_curve[3]);
-
- P = P + D*t;
-
-#ifdef __UV__
- sd->u = isect->u;
- sd->v = 0.0f;
-#endif
-
- tg = normalize(curvetangent(isect->u, p[0], p[1], p[2], p[3]));
-
- if(kernel_data.curve.curveflags & CURVE_KN_RIBBONS) {
- sd->Ng = normalize(-(D - tg * (dot(tg, D))));
- }
- else {
-#ifdef __EMBREE__
- if(kernel_data.bvh.scene) {
- sd->Ng = normalize(isect->Ng);
- }
- else
-#endif
- {
- /* direction from inside to surface of curve */
- float3 p_curr = curvepoint(isect->u, p[0], p[1], p[2], p[3]);
- sd->Ng = normalize(P - p_curr);
-
- /* adjustment for changing radius */
- float gd = isect->v;
-
- if(gd != 0.0f) {
- sd->Ng = sd->Ng - gd * tg;
- sd->Ng = normalize(sd->Ng);
- }
- }
- }
-
- /* todo: sometimes the normal is still so that this is detected as
- * backfacing even if cull backfaces is enabled */
-
- sd->N = sd->Ng;
- }
- else {
- float4 P_curve[2];
-
- if(sd->type & PRIMITIVE_CURVE) {
- P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
- P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
- }
- else {
- motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
- }
-
- float l = 1.0f;
- tg = normalize_len(float4_to_float3(P_curve[1] - P_curve[0]), &l);
-
- P = P + D*t;
-
- float3 dif = P - float4_to_float3(P_curve[0]);
-
-#ifdef __UV__
- sd->u = dot(dif,tg)/l;
- sd->v = 0.0f;
-#endif
-
- if(flag & CURVE_KN_TRUETANGENTGNORMAL) {
- sd->Ng = -(D - tg * dot(tg, D));
- sd->Ng = normalize(sd->Ng);
- }
- else {
- float gd = isect->v;
-
- /* direction from inside to surface of curve */
- float denom = fmaxf(P_curve[0].w + sd->u * l * gd, 1e-8f);
- sd->Ng = (dif - tg * sd->u * l) / denom;
-
- /* adjustment for changing radius */
- if(gd != 0.0f) {
- sd->Ng = sd->Ng - gd * tg;
- }
-
- sd->Ng = normalize(sd->Ng);
- }
-
- sd->N = sd->Ng;
- }
-
-#ifdef __DPDU__
- /* dPdu/dPdv */
- sd->dPdu = tg;
- sd->dPdv = cross(tg, sd->Ng);
-#endif
-
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- }
-
- return P;
+ int flag = kernel_data.curve.curveflags;
+ float t = isect->t;
+ float3 P = ray->P;
+ float3 D = ray->D;
+
+ if (isect->object != OBJECT_NONE) {
+# ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+# else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+# endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D * t);
+ D = normalize_len(D, &t);
+ }
+
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float3 tg;
+
+ if (flag & CURVE_KN_INTERPOLATE) {
+ int ka = max(k0 - 1, __float_as_int(v00.x));
+ int kb = min(k1 + 1, __float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P_curve[4];
+
+ if (sd->type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ motion_cardinal_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
+ }
+
+ float3 p[4];
+ p[0] = float4_to_float3(P_curve[0]);
+ p[1] = float4_to_float3(P_curve[1]);
+ p[2] = float4_to_float3(P_curve[2]);
+ p[3] = float4_to_float3(P_curve[3]);
+
+ P = P + D * t;
+
+# ifdef __UV__
+ sd->u = isect->u;
+ sd->v = 0.0f;
+# endif
+
+ tg = normalize(curvetangent(isect->u, p[0], p[1], p[2], p[3]));
+
+ if (kernel_data.curve.curveflags & CURVE_KN_RIBBONS) {
+ sd->Ng = normalize(-(D - tg * (dot(tg, D))));
+ }
+ else {
+# ifdef __EMBREE__
+ if (kernel_data.bvh.scene) {
+ sd->Ng = normalize(isect->Ng);
+ }
+ else
+# endif
+ {
+ /* direction from inside to surface of curve */
+ float3 p_curr = curvepoint(isect->u, p[0], p[1], p[2], p[3]);
+ sd->Ng = normalize(P - p_curr);
+
+ /* adjustment for changing radius */
+ float gd = isect->v;
+
+ if (gd != 0.0f) {
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+ }
+
+ /* todo: sometimes the normal is still so that this is detected as
+ * backfacing even if cull backfaces is enabled */
+
+ sd->N = sd->Ng;
+ }
+ else {
+ float4 P_curve[2];
+
+ if (sd->type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
+ }
+
+ float l = 1.0f;
+ tg = normalize_len(float4_to_float3(P_curve[1] - P_curve[0]), &l);
+
+ P = P + D * t;
+
+ float3 dif = P - float4_to_float3(P_curve[0]);
+
+# ifdef __UV__
+ sd->u = dot(dif, tg) / l;
+ sd->v = 0.0f;
+# endif
+
+ if (flag & CURVE_KN_TRUETANGENTGNORMAL) {
+ sd->Ng = -(D - tg * dot(tg, D));
+ sd->Ng = normalize(sd->Ng);
+ }
+ else {
+ float gd = isect->v;
+
+ /* direction from inside to surface of curve */
+ float denom = fmaxf(P_curve[0].w + sd->u * l * gd, 1e-8f);
+ sd->Ng = (dif - tg * sd->u * l) / denom;
+
+ /* adjustment for changing radius */
+ if (gd != 0.0f) {
+ sd->Ng = sd->Ng - gd * tg;
+ }
+
+ sd->Ng = normalize(sd->Ng);
+ }
+
+ sd->N = sd->Ng;
+ }
+
+# ifdef __DPDU__
+ /* dPdu/dPdv */
+ sd->dPdu = tg;
+ sd->dPdv = cross(tg, sd->Ng);
+# endif
+
+ if (isect->object != OBJECT_NONE) {
+# ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+# else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+# endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
}
#endif
diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h
index 5cc22ae2155..7380c506bf4 100644
--- a/intern/cycles/kernel/geom/geom_motion_curve.h
+++ b/intern/cycles/kernel/geom/geom_motion_curve.h
@@ -25,96 +25,116 @@ CCL_NAMESPACE_BEGIN
#ifdef __HAIR__
-ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
+ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg,
+ int object,
+ uint id,
+ AttributeElement *elem)
{
- /* todo: find a better (faster) solution for this, maybe store offset per object.
- *
- * NOTE: currently it's not a bottleneck because in test scenes the loop below runs
- * zero iterations and rendering is really slow with motion curves. For until other
- * areas are speed up it's probably not so crucial to optimize this out.
- */
- uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_CURVE;
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id) {
- attr_offset += ATTR_PRIM_TYPES;
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
- }
-
- *elem = (AttributeElement)attr_map.y;
-
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+ /* todo: find a better (faster) solution for this, maybe store offset per object.
+ *
+ * NOTE: currently it's not a bottleneck because in test scenes the loop below runs
+ * zero iterations and rendering is really slow with motion curves. For until other
+ * areas are speed up it's probably not so crucial to optimize this out.
+ */
+ uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_CURVE;
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while (attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ *elem = (AttributeElement)attr_map.y;
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
}
-ccl_device_inline void motion_curve_keys_for_step(KernelGlobals *kg, int offset, int numkeys, int numsteps, int step, int k0, int k1, float4 keys[2])
+ccl_device_inline void motion_curve_keys_for_step(KernelGlobals *kg,
+ int offset,
+ int numkeys,
+ int numsteps,
+ int step,
+ int k0,
+ int k1,
+ float4 keys[2])
{
- if(step == numsteps) {
- /* center step: regular key location */
- keys[0] = kernel_tex_fetch(__curve_keys, k0);
- keys[1] = kernel_tex_fetch(__curve_keys, k1);
- }
- else {
- /* center step is not stored in this array */
- if(step > numsteps)
- step--;
-
- offset += step*numkeys;
-
- keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
- keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
- }
+ if (step == numsteps) {
+ /* center step: regular key location */
+ keys[0] = kernel_tex_fetch(__curve_keys, k0);
+ keys[1] = kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ /* center step is not stored in this array */
+ if (step > numsteps)
+ step--;
+
+ offset += step * numkeys;
+
+ keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
+ keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
+ }
}
/* return 2 curve key locations */
-ccl_device_inline void motion_curve_keys(KernelGlobals *kg, int object, int prim, float time, int k0, int k1, float4 keys[2])
+ccl_device_inline void motion_curve_keys(
+ KernelGlobals *kg, int object, int prim, float time, int k0, int k1, float4 keys[2])
{
- /* get motion info */
- int numsteps, numkeys;
- object_motion_info(kg, object, &numsteps, NULL, &numkeys);
+ /* get motion info */
+ int numsteps, numkeys;
+ object_motion_info(kg, object, &numsteps, NULL, &numkeys);
- /* figure out which steps we need to fetch and their interpolation factor */
- int maxstep = numsteps*2;
- int step = min((int)(time*maxstep), maxstep-1);
- float t = time*maxstep - step;
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps * 2;
+ int step = min((int)(time * maxstep), maxstep - 1);
+ float t = time * maxstep - step;
- /* find attribute */
- AttributeElement elem;
- int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
- kernel_assert(offset != ATTR_STD_NOT_FOUND);
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
- /* fetch key coordinates */
- float4 next_keys[2];
+ /* fetch key coordinates */
+ float4 next_keys[2];
- motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, keys);
- motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step+1, k0, k1, next_keys);
+ motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, keys);
+ motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step + 1, k0, k1, next_keys);
- /* interpolate between steps */
- keys[0] = (1.0f - t)*keys[0] + t*next_keys[0];
- keys[1] = (1.0f - t)*keys[1] + t*next_keys[1];
+ /* interpolate between steps */
+ keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
+ keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
}
-ccl_device_inline void motion_cardinal_curve_keys_for_step(KernelGlobals *kg, int offset, int numkeys, int numsteps, int step, int k0, int k1, int k2, int k3, float4 keys[4])
+ccl_device_inline void motion_cardinal_curve_keys_for_step(KernelGlobals *kg,
+ int offset,
+ int numkeys,
+ int numsteps,
+ int step,
+ int k0,
+ int k1,
+ int k2,
+ int k3,
+ float4 keys[4])
{
- if(step == numsteps) {
- /* center step: regular key location */
- keys[0] = kernel_tex_fetch(__curve_keys, k0);
- keys[1] = kernel_tex_fetch(__curve_keys, k1);
- keys[2] = kernel_tex_fetch(__curve_keys, k2);
- keys[3] = kernel_tex_fetch(__curve_keys, k3);
- }
- else {
- /* center step is not stored in this array */
- if(step > numsteps)
- step--;
-
- offset += step*numkeys;
-
- keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
- keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
- keys[2] = kernel_tex_fetch(__attributes_float3, offset + k2);
- keys[3] = kernel_tex_fetch(__attributes_float3, offset + k3);
- }
+ if (step == numsteps) {
+ /* center step: regular key location */
+ keys[0] = kernel_tex_fetch(__curve_keys, k0);
+ keys[1] = kernel_tex_fetch(__curve_keys, k1);
+ keys[2] = kernel_tex_fetch(__curve_keys, k2);
+ keys[3] = kernel_tex_fetch(__curve_keys, k3);
+ }
+ else {
+ /* center step is not stored in this array */
+ if (step > numsteps)
+ step--;
+
+ offset += step * numkeys;
+
+ keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
+ keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
+ keys[2] = kernel_tex_fetch(__attributes_float3, offset + k2);
+ keys[3] = kernel_tex_fetch(__attributes_float3, offset + k3);
+ }
}
/* return 2 curve key locations */
@@ -122,37 +142,41 @@ ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg,
int object,
int prim,
float time,
- int k0, int k1, int k2, int k3,
+ int k0,
+ int k1,
+ int k2,
+ int k3,
float4 keys[4])
{
- /* get motion info */
- int numsteps, numkeys;
- object_motion_info(kg, object, &numsteps, NULL, &numkeys);
-
- /* figure out which steps we need to fetch and their interpolation factor */
- int maxstep = numsteps*2;
- int step = min((int)(time*maxstep), maxstep-1);
- float t = time*maxstep - step;
-
- /* find attribute */
- AttributeElement elem;
- int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
- kernel_assert(offset != ATTR_STD_NOT_FOUND);
-
- /* fetch key coordinates */
- float4 next_keys[4];
-
- motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys);
- motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step+1, k0, k1, k2, k3, next_keys);
-
- /* interpolate between steps */
- keys[0] = (1.0f - t)*keys[0] + t*next_keys[0];
- keys[1] = (1.0f - t)*keys[1] + t*next_keys[1];
- keys[2] = (1.0f - t)*keys[2] + t*next_keys[2];
- keys[3] = (1.0f - t)*keys[3] + t*next_keys[3];
+ /* get motion info */
+ int numsteps, numkeys;
+ object_motion_info(kg, object, &numsteps, NULL, &numkeys);
+
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps * 2;
+ int step = min((int)(time * maxstep), maxstep - 1);
+ float t = time * maxstep - step;
+
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch key coordinates */
+ float4 next_keys[4];
+
+ motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys);
+ motion_cardinal_curve_keys_for_step(
+ kg, offset, numkeys, numsteps, step + 1, k0, k1, k2, k3, next_keys);
+
+ /* interpolate between steps */
+ keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
+ keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
+ keys[2] = (1.0f - t) * keys[2] + t * next_keys[2];
+ keys[3] = (1.0f - t) * keys[3] + t * next_keys[3];
}
-#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__)
+# if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__)
/* Similar to above, but returns keys as pair of two AVX registers with each
* holding two float4.
*/
@@ -160,56 +184,44 @@ ccl_device_inline void motion_cardinal_curve_keys_avx(KernelGlobals *kg,
int object,
int prim,
float time,
- int k0, int k1,
- int k2, int k3,
+ int k0,
+ int k1,
+ int k2,
+ int k3,
avxf *out_keys_0_1,
avxf *out_keys_2_3)
{
- /* Get motion info. */
- int numsteps, numkeys;
- object_motion_info(kg, object, &numsteps, NULL, &numkeys);
-
- /* Figure out which steps we need to fetch and their interpolation factor. */
- int maxstep = numsteps * 2;
- int step = min((int)(time*maxstep), maxstep - 1);
- float t = time*maxstep - step;
-
- /* Find attribute. */
- AttributeElement elem;
- int offset = find_attribute_curve_motion(kg,
- object,
- ATTR_STD_MOTION_VERTEX_POSITION,
- &elem);
- kernel_assert(offset != ATTR_STD_NOT_FOUND);
-
- /* Fetch key coordinates. */
- float4 next_keys[4];
- float4 keys[4];
- motion_cardinal_curve_keys_for_step(kg,
- offset,
- numkeys,
- numsteps,
- step,
- k0, k1, k2, k3,
- keys);
- motion_cardinal_curve_keys_for_step(kg,
- offset,
- numkeys,
- numsteps,
- step + 1,
- k0, k1, k2, k3,
- next_keys);
-
- const avxf keys_0_1 = avxf(keys[0].m128, keys[1].m128);
- const avxf keys_2_3 = avxf(keys[2].m128, keys[3].m128);
- const avxf next_keys_0_1 = avxf(next_keys[0].m128, next_keys[1].m128);
- const avxf next_keys_2_3 = avxf(next_keys[2].m128, next_keys[3].m128);
-
- /* Interpolate between steps. */
- *out_keys_0_1 = (1.0f - t) * keys_0_1 + t*next_keys_0_1;
- *out_keys_2_3 = (1.0f - t) * keys_2_3 + t*next_keys_2_3;
+ /* Get motion info. */
+ int numsteps, numkeys;
+ object_motion_info(kg, object, &numsteps, NULL, &numkeys);
+
+ /* Figure out which steps we need to fetch and their interpolation factor. */
+ int maxstep = numsteps * 2;
+ int step = min((int)(time * maxstep), maxstep - 1);
+ float t = time * maxstep - step;
+
+ /* Find attribute. */
+ AttributeElement elem;
+ int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* Fetch key coordinates. */
+ float4 next_keys[4];
+ float4 keys[4];
+ motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys);
+ motion_cardinal_curve_keys_for_step(
+ kg, offset, numkeys, numsteps, step + 1, k0, k1, k2, k3, next_keys);
+
+ const avxf keys_0_1 = avxf(keys[0].m128, keys[1].m128);
+ const avxf keys_2_3 = avxf(keys[2].m128, keys[3].m128);
+ const avxf next_keys_0_1 = avxf(next_keys[0].m128, next_keys[1].m128);
+ const avxf next_keys_2_3 = avxf(next_keys[2].m128, next_keys[3].m128);
+
+ /* Interpolate between steps. */
+ *out_keys_0_1 = (1.0f - t) * keys_0_1 + t * next_keys_0_1;
+ *out_keys_2_3 = (1.0f - t) * keys_2_3 + t * next_keys_2_3;
}
-#endif
+# endif
#endif
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h
index 64f6d027b99..53d6b92dd7e 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -29,127 +29,145 @@ CCL_NAMESPACE_BEGIN
/* Time interpolation of vertex positions and normals */
-ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
+ccl_device_inline int find_attribute_motion(KernelGlobals *kg,
+ int object,
+ uint id,
+ AttributeElement *elem)
{
- /* todo: find a better (faster) solution for this, maybe store offset per object */
- uint attr_offset = object_attribute_map_offset(kg, object);
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ /* todo: find a better (faster) solution for this, maybe store offset per object */
+ uint attr_offset = object_attribute_map_offset(kg, object);
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
- while(attr_map.x != id) {
- attr_offset += ATTR_PRIM_TYPES;
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
- }
+ while (attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
- *elem = (AttributeElement)attr_map.y;
+ *elem = (AttributeElement)attr_map.y;
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
}
-ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, uint4 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3])
+ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg,
+ uint4 tri_vindex,
+ int offset,
+ int numverts,
+ int numsteps,
+ int step,
+ float3 verts[3])
{
- if(step == numsteps) {
- /* center step: regular vertex location */
- verts[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
- verts[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
- verts[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
- }
- else {
- /* center step not store in this array */
- if(step > numsteps)
- step--;
-
- offset += step*numverts;
-
- verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
- verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
- verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
- }
+ if (step == numsteps) {
+ /* center step: regular vertex location */
+ verts[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 0));
+ verts[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 1));
+ verts[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 2));
+ }
+ else {
+ /* center step not store in this array */
+ if (step > numsteps)
+ step--;
+
+ offset += step * numverts;
+
+ verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
+ verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
+ verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
+ }
}
-ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, uint4 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3])
+ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg,
+ uint4 tri_vindex,
+ int offset,
+ int numverts,
+ int numsteps,
+ int step,
+ float3 normals[3])
{
- if(step == numsteps) {
- /* center step: regular vertex location */
- normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
- normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
- normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
- }
- else {
- /* center step is not stored in this array */
- if(step > numsteps)
- step--;
-
- offset += step*numverts;
-
- normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
- normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
- normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
- }
+ if (step == numsteps) {
+ /* center step: regular vertex location */
+ normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
+ normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
+ normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
+ }
+ else {
+ /* center step is not stored in this array */
+ if (step > numsteps)
+ step--;
+
+ offset += step * numverts;
+
+ normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
+ normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
+ normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
+ }
}
-ccl_device_inline void motion_triangle_vertices(KernelGlobals *kg, int object, int prim, float time, float3 verts[3])
+ccl_device_inline void motion_triangle_vertices(
+ KernelGlobals *kg, int object, int prim, float time, float3 verts[3])
{
- /* get motion info */
- int numsteps, numverts;
- object_motion_info(kg, object, &numsteps, &numverts, NULL);
-
- /* figure out which steps we need to fetch and their interpolation factor */
- int maxstep = numsteps*2;
- int step = min((int)(time*maxstep), maxstep-1);
- float t = time*maxstep - step;
-
- /* find attribute */
- AttributeElement elem;
- int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
- kernel_assert(offset != ATTR_STD_NOT_FOUND);
-
- /* fetch vertex coordinates */
- float3 next_verts[3];
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
-
- motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
- motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts);
-
- /* interpolate between steps */
- verts[0] = (1.0f - t)*verts[0] + t*next_verts[0];
- verts[1] = (1.0f - t)*verts[1] + t*next_verts[1];
- verts[2] = (1.0f - t)*verts[2] + t*next_verts[2];
+ /* get motion info */
+ int numsteps, numverts;
+ object_motion_info(kg, object, &numsteps, &numverts, NULL);
+
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps * 2;
+ int step = min((int)(time * maxstep), maxstep - 1);
+ float t = time * maxstep - step;
+
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch vertex coordinates */
+ float3 next_verts[3];
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
+
+ /* interpolate between steps */
+ verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
+ verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
+ verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
}
-ccl_device_inline float3 motion_triangle_smooth_normal(KernelGlobals *kg, float3 Ng, int object, int prim, float u, float v, float time)
+ccl_device_inline float3 motion_triangle_smooth_normal(
+ KernelGlobals *kg, float3 Ng, int object, int prim, float u, float v, float time)
{
- /* get motion info */
- int numsteps, numverts;
- object_motion_info(kg, object, &numsteps, &numverts, NULL);
-
- /* figure out which steps we need to fetch and their interpolation factor */
- int maxstep = numsteps*2;
- int step = min((int)(time*maxstep), maxstep-1);
- float t = time*maxstep - step;
-
- /* find attribute */
- AttributeElement elem;
- int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_NORMAL, &elem);
- kernel_assert(offset != ATTR_STD_NOT_FOUND);
-
- /* fetch normals */
- float3 normals[3], next_normals[3];
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
-
- motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
- motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_normals);
-
- /* interpolate between steps */
- normals[0] = (1.0f - t)*normals[0] + t*next_normals[0];
- normals[1] = (1.0f - t)*normals[1] + t*next_normals[1];
- normals[2] = (1.0f - t)*normals[2] + t*next_normals[2];
-
- /* interpolate between vertices */
- float w = 1.0f - u - v;
- float3 N = safe_normalize(u*normals[0] + v*normals[1] + w*normals[2]);
-
- return is_zero(N)? Ng: N;
+ /* get motion info */
+ int numsteps, numverts;
+ object_motion_info(kg, object, &numsteps, &numverts, NULL);
+
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps * 2;
+ int step = min((int)(time * maxstep), maxstep - 1);
+ float t = time * maxstep - step;
+
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_NORMAL, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch normals */
+ float3 normals[3], next_normals[3];
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+
+ motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
+ motion_triangle_normals_for_step(
+ kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
+
+ /* interpolate between steps */
+ normals[0] = (1.0f - t) * normals[0] + t * next_normals[0];
+ normals[1] = (1.0f - t) * normals[1] + t * next_normals[1];
+ normals[2] = (1.0f - t) * normals[2] + t * next_normals[2];
+
+ /* interpolate between vertices */
+ float w = 1.0f - u - v;
+ float3 N = safe_normalize(u * normals[0] + v * normals[1] + w * normals[2]);
+
+ return is_zero(N) ? Ng : N;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
index ec7bfad7349..49d4829af38 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
@@ -32,64 +32,57 @@ CCL_NAMESPACE_BEGIN
* a closer distance.
*/
-ccl_device_inline float3 motion_triangle_refine(KernelGlobals *kg,
- ShaderData *sd,
- const Intersection *isect,
- const Ray *ray,
- float3 verts[3])
+ccl_device_inline float3 motion_triangle_refine(
+ KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float3 verts[3])
{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
#ifdef __INTERSECTION_REFINE__
- if(isect->object != OBJECT_NONE) {
- if(UNLIKELY(t == 0.0f)) {
- return P;
- }
+ if (isect->object != OBJECT_NONE) {
+ if (UNLIKELY(t == 0.0f)) {
+ return P;
+ }
# ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
+ Transform tfm = sd->ob_itfm;
# else
- Transform tfm = object_fetch_transform(kg,
- isect->object,
- OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
# endif
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D * t);
+ D = normalize_len(D, &t);
+ }
- P = P + D*t;
+ P = P + D * t;
- /* Compute refined intersection distance. */
- const float3 e1 = verts[0] - verts[2];
- const float3 e2 = verts[1] - verts[2];
- const float3 s1 = cross(D, e2);
+ /* Compute refined intersection distance. */
+ const float3 e1 = verts[0] - verts[2];
+ const float3 e2 = verts[1] - verts[2];
+ const float3 s1 = cross(D, e2);
- const float invdivisor = 1.0f/dot(s1, e1);
- const float3 d = P - verts[2];
- const float3 s2 = cross(d, e1);
- float rt = dot(e2, s2)*invdivisor;
+ const float invdivisor = 1.0f / dot(s1, e1);
+ const float3 d = P - verts[2];
+ const float3 s2 = cross(d, e1);
+ float rt = dot(e2, s2) * invdivisor;
- /* Compute refined position. */
- P = P + D*rt;
+ /* Compute refined position. */
+ P = P + D * rt;
- if(isect->object != OBJECT_NONE) {
+ if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
+ Transform tfm = sd->ob_tfm;
# else
- Transform tfm = object_fetch_transform(kg,
- isect->object,
- OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
# endif
- P = transform_point(&tfm, P);
- }
+ P = transform_point(&tfm, P);
+ }
- return P;
+ return P;
#else
- return P + D*t;
+ return P + D * t;
#endif
}
@@ -103,116 +96,112 @@ ccl_device_noinline
# else
ccl_device_inline
# endif
-float3 motion_triangle_refine_local(KernelGlobals *kg,
- ShaderData *sd,
- const Intersection *isect,
- const Ray *ray,
- float3 verts[3])
+ float3
+ motion_triangle_refine_local(KernelGlobals *kg,
+ ShaderData *sd,
+ const Intersection *isect,
+ const Ray *ray,
+ float3 verts[3])
{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
# ifdef __INTERSECTION_REFINE__
- if(isect->object != OBJECT_NONE) {
+ if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
+ Transform tfm = sd->ob_itfm;
# else
- Transform tfm = object_fetch_transform(kg,
- isect->object,
- OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
# endif
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D);
- D = normalize(D);
- }
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D);
+ D = normalize(D);
+ }
- P = P + D*t;
+ P = P + D * t;
- /* compute refined intersection distance */
- const float3 e1 = verts[0] - verts[2];
- const float3 e2 = verts[1] - verts[2];
- const float3 s1 = cross(D, e2);
+ /* compute refined intersection distance */
+ const float3 e1 = verts[0] - verts[2];
+ const float3 e2 = verts[1] - verts[2];
+ const float3 s1 = cross(D, e2);
- const float invdivisor = 1.0f/dot(s1, e1);
- const float3 d = P - verts[2];
- const float3 s2 = cross(d, e1);
- float rt = dot(e2, s2)*invdivisor;
+ const float invdivisor = 1.0f / dot(s1, e1);
+ const float3 d = P - verts[2];
+ const float3 s2 = cross(d, e1);
+ float rt = dot(e2, s2) * invdivisor;
- P = P + D*rt;
+ P = P + D * rt;
- if(isect->object != OBJECT_NONE) {
+ if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
+ Transform tfm = sd->ob_tfm;
# else
- Transform tfm = object_fetch_transform(kg,
- isect->object,
- OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
# endif
- P = transform_point(&tfm, P);
- }
+ P = transform_point(&tfm, P);
+ }
- return P;
+ return P;
# else /* __INTERSECTION_REFINE__ */
- return P + D*t;
-# endif /* __INTERSECTION_REFINE__ */
+ return P + D * t;
+# endif /* __INTERSECTION_REFINE__ */
}
-#endif /* __BVH_LOCAL__ */
-
+#endif /* __BVH_LOCAL__ */
/* Ray intersection. We simply compute the vertex positions at the given ray
* time and do a ray intersection with the resulting triangle.
*/
-ccl_device_inline bool motion_triangle_intersect(
- KernelGlobals *kg,
- Intersection *isect,
- float3 P,
- float3 dir,
- float time,
- uint visibility,
- int object,
- int prim_addr)
+ccl_device_inline bool motion_triangle_intersect(KernelGlobals *kg,
+ Intersection *isect,
+ float3 P,
+ float3 dir,
+ float time,
+ uint visibility,
+ int object,
+ int prim_addr)
{
- /* Primitive index for vertex location lookup. */
- int prim = kernel_tex_fetch(__prim_index, prim_addr);
- int fobject = (object == OBJECT_NONE)
- ? kernel_tex_fetch(__prim_object, prim_addr)
- : object;
- /* Get vertex locations for intersection. */
- float3 verts[3];
- motion_triangle_vertices(kg, fobject, prim, time, verts);
- /* Ray-triangle intersection, unoptimized. */
- float t, u, v;
- if(ray_triangle_intersect(P,
- dir,
- isect->t,
+ /* Primitive index for vertex location lookup. */
+ int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, prim_addr) : object;
+ /* Get vertex locations for intersection. */
+ float3 verts[3];
+ motion_triangle_vertices(kg, fobject, prim, time, verts);
+ /* Ray-triangle intersection, unoptimized. */
+ float t, u, v;
+ if (ray_triangle_intersect(P,
+ dir,
+ isect->t,
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- (ssef*)verts,
+ (ssef *)verts,
#else
- verts[0], verts[1], verts[2],
+ verts[0],
+ verts[1],
+ verts[2],
#endif
- &u, &v, &t))
- {
+ &u,
+ &v,
+ &t)) {
#ifdef __VISIBILITY_FLAG__
- /* Visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags.
- */
- if(kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
+ /* Visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags.
+ */
+ if (kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
#endif
- {
- isect->t = t;
- isect->u = u;
- isect->v = v;
- isect->prim = prim_addr;
- isect->object = object;
- isect->type = PRIMITIVE_MOTION_TRIANGLE;
- return true;
- }
- }
- return false;
+ {
+ isect->t = t;
+ isect->u = u;
+ isect->v = v;
+ isect->prim = prim_addr;
+ isect->object = object;
+ isect->type = PRIMITIVE_MOTION_TRIANGLE;
+ return true;
+ }
+ }
+ return false;
}
/* Special ray intersection routines for local intersections. In that case we
@@ -221,101 +210,102 @@ ccl_device_inline bool motion_triangle_intersect(
* Returns whether traversal should be stopped.
*/
#ifdef __BVH_LOCAL__
-ccl_device_inline bool motion_triangle_intersect_local(
- KernelGlobals *kg,
- LocalIntersection *local_isect,
- float3 P,
- float3 dir,
- float time,
- int object,
- int local_object,
- int prim_addr,
- float tmax,
- uint *lcg_state,
- int max_hits)
+ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals *kg,
+ LocalIntersection *local_isect,
+ float3 P,
+ float3 dir,
+ float time,
+ int object,
+ int local_object,
+ int prim_addr,
+ float tmax,
+ uint *lcg_state,
+ int max_hits)
{
- /* Only intersect with matching object, for instanced objects we
- * already know we are only intersecting the right object. */
- if(object == OBJECT_NONE) {
- if(kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
- return false;
- }
- }
-
- /* Primitive index for vertex location lookup. */
- int prim = kernel_tex_fetch(__prim_index, prim_addr);
- /* Get vertex locations for intersection. */
- float3 verts[3];
- motion_triangle_vertices(kg, local_object, prim, time, verts);
- /* Ray-triangle intersection, unoptimized. */
- float t, u, v;
- if(!ray_triangle_intersect(P,
- dir,
- tmax,
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- (ssef*)verts,
-#else
- verts[0], verts[1], verts[2],
-#endif
- &u, &v, &t))
- {
- return false;
- }
-
- /* If no actual hit information is requested, just return here. */
- if(max_hits == 0) {
- return true;
- }
-
- int hit;
- if(lcg_state) {
- /* Record up to max_hits intersections. */
- for(int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
- if(local_isect->hits[i].t == t) {
- return false;
- }
- }
-
- local_isect->num_hits++;
-
- if(local_isect->num_hits <= max_hits) {
- hit = local_isect->num_hits - 1;
- }
- else {
- /* Reservoir sampling: if we are at the maximum number of
- * hits, randomly replace element or skip it.
- */
- hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
-
- if(hit >= max_hits)
- return false;
- }
- }
- else {
- /* Record closest intersection only. */
- if(local_isect->num_hits && t > local_isect->hits[0].t) {
- return false;
- }
-
- hit = 0;
- local_isect->num_hits = 1;
- }
-
- /* Record intersection. */
- Intersection *isect = &local_isect->hits[hit];
- isect->t = t;
- isect->u = u;
- isect->v = v;
- isect->prim = prim_addr;
- isect->object = object;
- isect->type = PRIMITIVE_MOTION_TRIANGLE;
-
- /* Record geometric normal. */
- local_isect->Ng[hit] = normalize(cross(verts[1] - verts[0],
- verts[2] - verts[0]));
-
- return false;
+ /* Only intersect with matching object, for instanced objects we
+ * already know we are only intersecting the right object. */
+ if (object == OBJECT_NONE) {
+ if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+ return false;
+ }
+ }
+
+ /* Primitive index for vertex location lookup. */
+ int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ /* Get vertex locations for intersection. */
+ float3 verts[3];
+ motion_triangle_vertices(kg, local_object, prim, time, verts);
+ /* Ray-triangle intersection, unoptimized. */
+ float t, u, v;
+ if (!ray_triangle_intersect(P,
+ dir,
+ tmax,
+# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
+ (ssef *)verts,
+# else
+ verts[0],
+ verts[1],
+ verts[2],
+# endif
+ &u,
+ &v,
+ &t)) {
+ return false;
+ }
+
+ /* If no actual hit information is requested, just return here. */
+ if (max_hits == 0) {
+ return true;
+ }
+
+ int hit;
+ if (lcg_state) {
+ /* Record up to max_hits intersections. */
+ for (int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
+ if (local_isect->hits[i].t == t) {
+ return false;
+ }
+ }
+
+ local_isect->num_hits++;
+
+ if (local_isect->num_hits <= max_hits) {
+ hit = local_isect->num_hits - 1;
+ }
+ else {
+ /* Reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it.
+ */
+ hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
+
+ if (hit >= max_hits)
+ return false;
+ }
+ }
+ else {
+ /* Record closest intersection only. */
+ if (local_isect->num_hits && t > local_isect->hits[0].t) {
+ return false;
+ }
+
+ hit = 0;
+ local_isect->num_hits = 1;
+ }
+
+ /* Record intersection. */
+ Intersection *isect = &local_isect->hits[hit];
+ isect->t = t;
+ isect->u = u;
+ isect->v = v;
+ isect->prim = prim_addr;
+ isect->object = object;
+ isect->type = PRIMITIVE_MOTION_TRIANGLE;
+
+ /* Record geometric normal. */
+ local_isect->Ng[hit] = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
+
+ return false;
}
-#endif /* __BVH_LOCAL__ */
+#endif /* __BVH_LOCAL__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
index e91a4be96ba..5333e82b346 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
@@ -32,91 +32,80 @@ CCL_NAMESPACE_BEGIN
* normals */
/* return 3 triangle vertex normals */
-ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg,
- ShaderData *sd, const
- Intersection *isect,
- const Ray *ray,
- bool is_local)
+ccl_device_noinline void motion_triangle_shader_setup(
+ KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool is_local)
{
- /* Get shader. */
- sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
- /* Get motion info. */
- /* TODO(sergey): This logic is really similar to motion_triangle_vertices(),
- * can we de-duplicate something here?
- */
- int numsteps, numverts;
- object_motion_info(kg, sd->object, &numsteps, &numverts, NULL);
- /* Figure out which steps we need to fetch and their interpolation factor. */
- int maxstep = numsteps*2;
- int step = min((int)(sd->time*maxstep), maxstep-1);
- float t = sd->time*maxstep - step;
- /* Find attribute. */
- AttributeElement elem;
- int offset = find_attribute_motion(kg, sd->object,
- ATTR_STD_MOTION_VERTEX_POSITION,
- &elem);
- kernel_assert(offset != ATTR_STD_NOT_FOUND);
- /* Fetch vertex coordinates. */
- float3 verts[3], next_verts[3];
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
- motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts);
- /* Interpolate between steps. */
- verts[0] = (1.0f - t)*verts[0] + t*next_verts[0];
- verts[1] = (1.0f - t)*verts[1] + t*next_verts[1];
- verts[2] = (1.0f - t)*verts[2] + t*next_verts[2];
- /* Compute refined position. */
+ /* Get shader. */
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+ /* Get motion info. */
+ /* TODO(sergey): This logic is really similar to motion_triangle_vertices(),
+ * can we de-duplicate something here?
+ */
+ int numsteps, numverts;
+ object_motion_info(kg, sd->object, &numsteps, &numverts, NULL);
+ /* Figure out which steps we need to fetch and their interpolation factor. */
+ int maxstep = numsteps * 2;
+ int step = min((int)(sd->time * maxstep), maxstep - 1);
+ float t = sd->time * maxstep - step;
+ /* Find attribute. */
+ AttributeElement elem;
+ int offset = find_attribute_motion(kg, sd->object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+ /* Fetch vertex coordinates. */
+ float3 verts[3], next_verts[3];
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
+ /* Interpolate between steps. */
+ verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
+ verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
+ verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
+ /* Compute refined position. */
#ifdef __BVH_LOCAL__
- if(is_local) {
- sd->P = motion_triangle_refine_local(kg,
- sd,
- isect,
- ray,
- verts);
- }
- else
-#endif /* __BVH_LOCAL__*/
- {
- sd->P = motion_triangle_refine(kg, sd, isect, ray, verts);
- }
- /* Compute face normal. */
- float3 Ng;
- if(sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
- Ng = normalize(cross(verts[2] - verts[0], verts[1] - verts[0]));
- }
- else {
- Ng = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
- }
- sd->Ng = Ng;
- sd->N = Ng;
- /* Compute derivatives of P w.r.t. uv. */
+ if (is_local) {
+ sd->P = motion_triangle_refine_local(kg, sd, isect, ray, verts);
+ }
+ else
+#endif /* __BVH_LOCAL__*/
+ {
+ sd->P = motion_triangle_refine(kg, sd, isect, ray, verts);
+ }
+ /* Compute face normal. */
+ float3 Ng;
+ if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
+ Ng = normalize(cross(verts[2] - verts[0], verts[1] - verts[0]));
+ }
+ else {
+ Ng = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
+ }
+ sd->Ng = Ng;
+ sd->N = Ng;
+ /* Compute derivatives of P w.r.t. uv. */
#ifdef __DPDU__
- sd->dPdu = (verts[0] - verts[2]);
- sd->dPdv = (verts[1] - verts[2]);
+ sd->dPdu = (verts[0] - verts[2]);
+ sd->dPdv = (verts[1] - verts[2]);
#endif
- /* Compute smooth normal. */
- if(sd->shader & SHADER_SMOOTH_NORMAL) {
- /* Find attribute. */
- AttributeElement elem;
- int offset = find_attribute_motion(kg,
- sd->object,
- ATTR_STD_MOTION_VERTEX_NORMAL,
- &elem);
- kernel_assert(offset != ATTR_STD_NOT_FOUND);
- /* Fetch vertex coordinates. */
- float3 normals[3], next_normals[3];
- motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
- motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_normals);
- /* Interpolate between steps. */
- normals[0] = (1.0f - t)*normals[0] + t*next_normals[0];
- normals[1] = (1.0f - t)*normals[1] + t*next_normals[1];
- normals[2] = (1.0f - t)*normals[2] + t*next_normals[2];
- /* Interpolate between vertices. */
- float u = sd->u;
- float v = sd->v;
- float w = 1.0f - u - v;
- sd->N = (u*normals[0] + v*normals[1] + w*normals[2]);
- }
+ /* Compute smooth normal. */
+ if (sd->shader & SHADER_SMOOTH_NORMAL) {
+ /* Find attribute. */
+ AttributeElement elem;
+ int offset = find_attribute_motion(kg, sd->object, ATTR_STD_MOTION_VERTEX_NORMAL, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+ /* Fetch vertex coordinates. */
+ float3 normals[3], next_normals[3];
+ motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
+ motion_triangle_normals_for_step(
+ kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
+ /* Interpolate between steps. */
+ normals[0] = (1.0f - t) * normals[0] + t * next_normals[0];
+ normals[1] = (1.0f - t) * normals[1] + t * next_normals[1];
+ normals[2] = (1.0f - t) * normals[2] + t * next_normals[2];
+ /* Interpolate between vertices. */
+ float u = sd->u;
+ float v = sd->v;
+ float w = 1.0f - u - v;
+ sd->N = (u * normals[0] + v * normals[1] + w * normals[2]);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 669c932d720..2792fd64c61 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -27,131 +27,143 @@ CCL_NAMESPACE_BEGIN
/* Object attributes, for now a fixed size and contents */
enum ObjectTransform {
- OBJECT_TRANSFORM = 0,
- OBJECT_INVERSE_TRANSFORM = 1,
+ OBJECT_TRANSFORM = 0,
+ OBJECT_INVERSE_TRANSFORM = 1,
};
-enum ObjectVectorTransform {
- OBJECT_PASS_MOTION_PRE = 0,
- OBJECT_PASS_MOTION_POST = 1
-};
+enum ObjectVectorTransform { OBJECT_PASS_MOTION_PRE = 0, OBJECT_PASS_MOTION_POST = 1 };
/* Object to world space transformation */
-ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
+ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg,
+ int object,
+ enum ObjectTransform type)
{
- if(type == OBJECT_INVERSE_TRANSFORM) {
- return kernel_tex_fetch(__objects, object).itfm;
- }
- else {
- return kernel_tex_fetch(__objects, object).tfm;
- }
+ if (type == OBJECT_INVERSE_TRANSFORM) {
+ return kernel_tex_fetch(__objects, object).itfm;
+ }
+ else {
+ return kernel_tex_fetch(__objects, object).tfm;
+ }
}
/* Lamp to world space transformation */
ccl_device_inline Transform lamp_fetch_transform(KernelGlobals *kg, int lamp, bool inverse)
{
- if(inverse) {
- return kernel_tex_fetch(__lights, lamp).itfm;
- }
- else {
- return kernel_tex_fetch(__lights, lamp).tfm;
- }
+ if (inverse) {
+ return kernel_tex_fetch(__lights, lamp).itfm;
+ }
+ else {
+ return kernel_tex_fetch(__lights, lamp).tfm;
+ }
}
/* Object to world space transformation for motion vectors */
-ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type)
+ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals *kg,
+ int object,
+ enum ObjectVectorTransform type)
{
- int offset = object*OBJECT_MOTION_PASS_SIZE + (int)type;
- return kernel_tex_fetch(__object_motion_pass, offset);
+ int offset = object * OBJECT_MOTION_PASS_SIZE + (int)type;
+ return kernel_tex_fetch(__object_motion_pass, offset);
}
/* Motion blurred object transformations */
#ifdef __OBJECT_MOTION__
-ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
-{
- const uint motion_offset = kernel_tex_fetch(__objects, object).motion_offset;
- const ccl_global DecomposedTransform *motion = &kernel_tex_fetch(__object_motion, motion_offset);
- const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 + 1;
-
- Transform tfm;
-#ifdef __EMBREE__
- if(kernel_data.bvh.scene) {
- transform_motion_array_interpolate_straight(&tfm, motion, num_steps, time);
- }
- else
-#endif
- transform_motion_array_interpolate(&tfm, motion, num_steps, time);
+ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg,
+ int object,
+ float time)
+{
+ const uint motion_offset = kernel_tex_fetch(__objects, object).motion_offset;
+ const ccl_global DecomposedTransform *motion = &kernel_tex_fetch(__object_motion, motion_offset);
+ const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 + 1;
+
+ Transform tfm;
+# ifdef __EMBREE__
+ if (kernel_data.bvh.scene) {
+ transform_motion_array_interpolate_straight(&tfm, motion, num_steps, time);
+ }
+ else
+# endif
+ transform_motion_array_interpolate(&tfm, motion, num_steps, time);
- return tfm;
+ return tfm;
}
-ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg, int object, float time, Transform *itfm)
+ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg,
+ int object,
+ float time,
+ Transform *itfm)
{
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_MOTION) {
- /* if we do motion blur */
- Transform tfm = object_fetch_transform_motion(kg, object, time);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_MOTION) {
+ /* if we do motion blur */
+ Transform tfm = object_fetch_transform_motion(kg, object, time);
- if(itfm)
- *itfm = transform_quick_inverse(tfm);
+ if (itfm)
+ *itfm = transform_quick_inverse(tfm);
- return tfm;
- }
- else {
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- if(itfm)
- *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ return tfm;
+ }
+ else {
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ if (itfm)
+ *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- return tfm;
- }
+ return tfm;
+ }
}
#endif
/* Transform position from object to world space */
-ccl_device_inline void object_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P)
+ccl_device_inline void object_position_transform(KernelGlobals *kg,
+ const ShaderData *sd,
+ float3 *P)
{
#ifdef __OBJECT_MOTION__
- *P = transform_point_auto(&sd->ob_tfm, *P);
+ *P = transform_point_auto(&sd->ob_tfm, *P);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
- *P = transform_point(&tfm, *P);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
+ *P = transform_point(&tfm, *P);
#endif
}
/* Transform position from world to object space */
-ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P)
+ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg,
+ const ShaderData *sd,
+ float3 *P)
{
#ifdef __OBJECT_MOTION__
- *P = transform_point_auto(&sd->ob_itfm, *P);
+ *P = transform_point_auto(&sd->ob_itfm, *P);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- *P = transform_point(&tfm, *P);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
+ *P = transform_point(&tfm, *P);
#endif
}
/* Transform normal from world to object space */
-ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
+ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg,
+ const ShaderData *sd,
+ float3 *N)
{
#ifdef __OBJECT_MOTION__
- if((sd->object != OBJECT_NONE) || (sd->type == PRIMITIVE_LAMP)) {
- *N = normalize(transform_direction_transposed_auto(&sd->ob_tfm, *N));
- }
+ if ((sd->object != OBJECT_NONE) || (sd->type == PRIMITIVE_LAMP)) {
+ *N = normalize(transform_direction_transposed_auto(&sd->ob_tfm, *N));
+ }
#else
- if(sd->object != OBJECT_NONE) {
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
- *N = normalize(transform_direction_transposed(&tfm, *N));
- }
- else if(sd->type == PRIMITIVE_LAMP) {
- Transform tfm = lamp_fetch_transform(kg, sd->lamp, false);
- *N = normalize(transform_direction_transposed(&tfm, *N));
- }
+ if (sd->object != OBJECT_NONE) {
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
+ *N = normalize(transform_direction_transposed(&tfm, *N));
+ }
+ else if (sd->type == PRIMITIVE_LAMP) {
+ Transform tfm = lamp_fetch_transform(kg, sd->lamp, false);
+ *N = normalize(transform_direction_transposed(&tfm, *N));
+ }
#endif
}
@@ -160,10 +172,10 @@ ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const
ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
{
#ifdef __OBJECT_MOTION__
- *N = normalize(transform_direction_transposed_auto(&sd->ob_itfm, *N));
+ *N = normalize(transform_direction_transposed_auto(&sd->ob_itfm, *N));
#else
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- *N = normalize(transform_direction_transposed(&tfm, *N));
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
+ *N = normalize(transform_direction_transposed(&tfm, *N));
#endif
}
@@ -172,22 +184,24 @@ ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderDa
ccl_device_inline void object_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
{
#ifdef __OBJECT_MOTION__
- *D = transform_direction_auto(&sd->ob_tfm, *D);
+ *D = transform_direction_auto(&sd->ob_tfm, *D);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
- *D = transform_direction(&tfm, *D);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
+ *D = transform_direction(&tfm, *D);
#endif
}
/* Transform direction vector from world to object space */
-ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
+ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg,
+ const ShaderData *sd,
+ float3 *D)
{
#ifdef __OBJECT_MOTION__
- *D = transform_direction_auto(&sd->ob_itfm, *D);
+ *D = transform_direction_auto(&sd->ob_itfm, *D);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- *D = transform_direction(&tfm, *D);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
+ *D = transform_direction(&tfm, *D);
#endif
}
@@ -195,14 +209,14 @@ ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, const Sha
ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd)
{
- if(sd->object == OBJECT_NONE)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (sd->object == OBJECT_NONE)
+ return make_float3(0.0f, 0.0f, 0.0f);
#ifdef __OBJECT_MOTION__
- return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w);
+ return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
- return make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
+ return make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
#endif
}
@@ -210,218 +224,211 @@ ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd
ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
{
- return kernel_tex_fetch(__objects, object).surface_area;
+ return kernel_tex_fetch(__objects, object).surface_area;
}
/* Pass ID number of object */
ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return 0.0f;
+ if (object == OBJECT_NONE)
+ return 0.0f;
- return kernel_tex_fetch(__objects, object).pass_id;
+ return kernel_tex_fetch(__objects, object).pass_id;
}
/* Per lamp random number for shader variation */
ccl_device_inline float lamp_random_number(KernelGlobals *kg, int lamp)
{
- if(lamp == LAMP_NONE)
- return 0.0f;
+ if (lamp == LAMP_NONE)
+ return 0.0f;
- return kernel_tex_fetch(__lights, lamp).random;
+ return kernel_tex_fetch(__lights, lamp).random;
}
/* Per object random number for shader variation */
ccl_device_inline float object_random_number(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return 0.0f;
+ if (object == OBJECT_NONE)
+ return 0.0f;
- return kernel_tex_fetch(__objects, object).random_number;
+ return kernel_tex_fetch(__objects, object).random_number;
}
/* Particle ID from which this object was generated */
ccl_device_inline int object_particle_id(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return 0;
+ if (object == OBJECT_NONE)
+ return 0;
- return kernel_tex_fetch(__objects, object).particle_index;
+ return kernel_tex_fetch(__objects, object).particle_index;
}
/* Generated texture coordinate on surface from where object was instanced */
ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (object == OBJECT_NONE)
+ return make_float3(0.0f, 0.0f, 0.0f);
- const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
- return make_float3(kobject->dupli_generated[0],
- kobject->dupli_generated[1],
- kobject->dupli_generated[2]);
+ const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+ return make_float3(
+ kobject->dupli_generated[0], kobject->dupli_generated[1], kobject->dupli_generated[2]);
}
/* UV texture coordinate on surface from where object was instanced */
ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (object == OBJECT_NONE)
+ return make_float3(0.0f, 0.0f, 0.0f);
- const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
- return make_float3(kobject->dupli_uv[0],
- kobject->dupli_uv[1],
- 0.0f);
+ const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+ return make_float3(kobject->dupli_uv[0], kobject->dupli_uv[1], 0.0f);
}
/* Information about mesh for motion blurred triangles and curves */
-ccl_device_inline void object_motion_info(KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys)
+ccl_device_inline void object_motion_info(
+ KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys)
{
- if(numkeys) {
- *numkeys = kernel_tex_fetch(__objects, object).numkeys;
- }
+ if (numkeys) {
+ *numkeys = kernel_tex_fetch(__objects, object).numkeys;
+ }
- if(numsteps)
- *numsteps = kernel_tex_fetch(__objects, object).numsteps;
- if(numverts)
- *numverts = kernel_tex_fetch(__objects, object).numverts;
+ if (numsteps)
+ *numsteps = kernel_tex_fetch(__objects, object).numsteps;
+ if (numverts)
+ *numverts = kernel_tex_fetch(__objects, object).numverts;
}
/* Offset to an objects patch map */
ccl_device_inline uint object_patch_map_offset(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return 0;
+ if (object == OBJECT_NONE)
+ return 0;
- return kernel_tex_fetch(__objects, object).patch_map_offset;
+ return kernel_tex_fetch(__objects, object).patch_map_offset;
}
/* Pass ID for shader */
ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd)
{
- return kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).pass_id;
+ return kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).pass_id;
}
/* Cryptomatte ID */
ccl_device_inline float object_cryptomatte_id(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return 0.0f;
+ if (object == OBJECT_NONE)
+ return 0.0f;
- return kernel_tex_fetch(__objects, object).cryptomatte_object;
+ return kernel_tex_fetch(__objects, object).cryptomatte_object;
}
ccl_device_inline float object_cryptomatte_asset_id(KernelGlobals *kg, int object)
{
- if(object == OBJECT_NONE)
- return 0;
+ if (object == OBJECT_NONE)
+ return 0;
- return kernel_tex_fetch(__objects, object).cryptomatte_asset;
+ return kernel_tex_fetch(__objects, object).cryptomatte_asset;
}
/* Particle data from which object was instanced */
ccl_device_inline uint particle_index(KernelGlobals *kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).index;
+ return kernel_tex_fetch(__particles, particle).index;
}
ccl_device float particle_age(KernelGlobals *kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).age;
+ return kernel_tex_fetch(__particles, particle).age;
}
ccl_device float particle_lifetime(KernelGlobals *kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).lifetime;
+ return kernel_tex_fetch(__particles, particle).lifetime;
}
ccl_device float particle_size(KernelGlobals *kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).size;
+ return kernel_tex_fetch(__particles, particle).size;
}
ccl_device float4 particle_rotation(KernelGlobals *kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).rotation;
+ return kernel_tex_fetch(__particles, particle).rotation;
}
ccl_device float3 particle_location(KernelGlobals *kg, int particle)
{
- return float4_to_float3(kernel_tex_fetch(__particles, particle).location);
+ return float4_to_float3(kernel_tex_fetch(__particles, particle).location);
}
ccl_device float3 particle_velocity(KernelGlobals *kg, int particle)
{
- return float4_to_float3(kernel_tex_fetch(__particles, particle).velocity);
+ return float4_to_float3(kernel_tex_fetch(__particles, particle).velocity);
}
ccl_device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
{
- return float4_to_float3(kernel_tex_fetch(__particles, particle).angular_velocity);
+ return float4_to_float3(kernel_tex_fetch(__particles, particle).angular_velocity);
}
/* Object intersection in BVH */
ccl_device_inline float3 bvh_clamp_direction(float3 dir)
{
- /* clamp absolute values by exp2f(-80.0f) to avoid division by zero when calculating inverse direction */
+ /* clamp absolute values by exp2f(-80.0f) to avoid division by zero when calculating inverse direction */
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
- const ssef oopes(8.271806E-25f,8.271806E-25f,8.271806E-25f,0.0f);
- const ssef mask = _mm_cmpgt_ps(fabs(dir), oopes);
- const ssef signdir = signmsk(dir.m128) | oopes;
+ const ssef oopes(8.271806E-25f, 8.271806E-25f, 8.271806E-25f, 0.0f);
+ const ssef mask = _mm_cmpgt_ps(fabs(dir), oopes);
+ const ssef signdir = signmsk(dir.m128) | oopes;
# ifndef __KERNEL_AVX__
- ssef res = mask & ssef(dir);
- res = _mm_or_ps(res,_mm_andnot_ps(mask, signdir));
+ ssef res = mask & ssef(dir);
+ res = _mm_or_ps(res, _mm_andnot_ps(mask, signdir));
# else
- ssef res = _mm_blendv_ps(signdir, dir, mask);
+ ssef res = _mm_blendv_ps(signdir, dir, mask);
# endif
- return float3(res);
+ return float3(res);
#else /* __KERNEL_SSE__ && __KERNEL_SSE2__ */
- const float ooeps = 8.271806E-25f;
- return make_float3((fabsf(dir.x) > ooeps)? dir.x: copysignf(ooeps, dir.x),
- (fabsf(dir.y) > ooeps)? dir.y: copysignf(ooeps, dir.y),
- (fabsf(dir.z) > ooeps)? dir.z: copysignf(ooeps, dir.z));
-#endif /* __KERNEL_SSE__ && __KERNEL_SSE2__ */
+ const float ooeps = 8.271806E-25f;
+ return make_float3((fabsf(dir.x) > ooeps) ? dir.x : copysignf(ooeps, dir.x),
+ (fabsf(dir.y) > ooeps) ? dir.y : copysignf(ooeps, dir.y),
+ (fabsf(dir.z) > ooeps) ? dir.z : copysignf(ooeps, dir.z));
+#endif /* __KERNEL_SSE__ && __KERNEL_SSE2__ */
}
ccl_device_inline float3 bvh_inverse_direction(float3 dir)
{
- return rcp(dir);
+ return rcp(dir);
}
/* Transform ray into object space to enter static object in BVH */
-ccl_device_inline float bvh_instance_push(KernelGlobals *kg,
- int object,
- const Ray *ray,
- float3 *P,
- float3 *dir,
- float3 *idir,
- float t)
+ccl_device_inline float bvh_instance_push(
+ KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float t)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- *P = transform_point(&tfm, ray->P);
+ *P = transform_point(&tfm, ray->P);
- float len;
- *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len));
- *idir = bvh_inverse_direction(*dir);
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
- if(t != FLT_MAX) {
- t *= len;
- }
+ if (t != FLT_MAX) {
+ t *= len;
+ }
- return t;
+ return t;
}
#ifdef __QBVH__
@@ -440,85 +447,85 @@ ccl_device_inline void qbvh_instance_push(KernelGlobals *kg,
float *t,
float *t1)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- *P = transform_point(&tfm, ray->P);
+ *P = transform_point(&tfm, ray->P);
- float len;
- *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len));
- *idir = bvh_inverse_direction(*dir);
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
- if(*t != FLT_MAX)
- *t *= len;
+ if (*t != FLT_MAX)
+ *t *= len;
- if(*t1 != -FLT_MAX)
- *t1 *= len;
+ if (*t1 != -FLT_MAX)
+ *t1 *= len;
}
#endif
/* Transorm ray to exit static object in BVH */
-ccl_device_inline float bvh_instance_pop(KernelGlobals *kg,
- int object,
- const Ray *ray,
- float3 *P,
- float3 *dir,
- float3 *idir,
- float t)
+ccl_device_inline float bvh_instance_pop(
+ KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float t)
{
- if(t != FLT_MAX) {
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- t /= len(transform_direction(&tfm, ray->D));
- }
+ if (t != FLT_MAX) {
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ t /= len(transform_direction(&tfm, ray->D));
+ }
- *P = ray->P;
- *dir = bvh_clamp_direction(ray->D);
- *idir = bvh_inverse_direction(*dir);
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
- return t;
+ return t;
}
/* Same as above, but returns scale factor to apply to multiple intersection distances */
-ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac)
+ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg,
+ int object,
+ const Ray *ray,
+ float3 *P,
+ float3 *dir,
+ float3 *idir,
+ float *t_fac)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
- *t_fac = 1.0f / len(transform_direction(&tfm, ray->D));
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ *t_fac = 1.0f / len(transform_direction(&tfm, ray->D));
- *P = ray->P;
- *dir = bvh_clamp_direction(ray->D);
- *idir = bvh_inverse_direction(*dir);
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
}
-
#ifdef __OBJECT_MOTION__
/* Transform ray into object space to enter motion blurred object in BVH */
ccl_device_inline float bvh_instance_motion_push(KernelGlobals *kg,
- int object,
- const Ray *ray,
- float3 *P,
- float3 *dir,
- float3 *idir,
- float t,
- Transform *itfm)
+ int object,
+ const Ray *ray,
+ float3 *P,
+ float3 *dir,
+ float3 *idir,
+ float t,
+ Transform *itfm)
{
- object_fetch_transform_motion_test(kg, object, ray->time, itfm);
+ object_fetch_transform_motion_test(kg, object, ray->time, itfm);
- *P = transform_point(itfm, ray->P);
+ *P = transform_point(itfm, ray->P);
- float len;
- *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len));
- *idir = bvh_inverse_direction(*dir);
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
- if(t != FLT_MAX) {
- t *= len;
- }
+ if (t != FLT_MAX) {
+ t *= len;
+ }
- return t;
+ return t;
}
-#ifdef __QBVH__
+# ifdef __QBVH__
/* Same as above, but optimized for QBVH scene intersection,
* which needs to modify two max distances.
*
@@ -535,21 +542,21 @@ ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg,
float *t1,
Transform *itfm)
{
- object_fetch_transform_motion_test(kg, object, ray->time, itfm);
+ object_fetch_transform_motion_test(kg, object, ray->time, itfm);
- *P = transform_point(itfm, ray->P);
+ *P = transform_point(itfm, ray->P);
- float len;
- *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len));
- *idir = bvh_inverse_direction(*dir);
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
- if(*t != FLT_MAX)
- *t *= len;
+ if (*t != FLT_MAX)
+ *t *= len;
- if(*t1 != -FLT_MAX)
- *t1 *= len;
+ if (*t1 != -FLT_MAX)
+ *t1 *= len;
}
-#endif
+# endif
/* Transorm ray to exit motion blurred object in BVH */
@@ -562,15 +569,15 @@ ccl_device_inline float bvh_instance_motion_pop(KernelGlobals *kg,
float t,
Transform *itfm)
{
- if(t != FLT_MAX) {
- t /= len(transform_direction(itfm, ray->D));
- }
+ if (t != FLT_MAX) {
+ t /= len(transform_direction(itfm, ray->D));
+ }
- *P = ray->P;
- *dir = bvh_clamp_direction(ray->D);
- *idir = bvh_inverse_direction(*dir);
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
- return t;
+ return t;
}
/* Same as above, but returns scale factor to apply to multiple intersection distances */
@@ -584,10 +591,10 @@ ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg,
float *t_fac,
Transform *itfm)
{
- *t_fac = 1.0f / len(transform_direction(itfm, ray->D));
- *P = ray->P;
- *dir = bvh_clamp_direction(ray->D);
- *idir = bvh_inverse_direction(*dir);
+ *t_fac = 1.0f / len(transform_direction(itfm, ray->D));
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
}
#endif
@@ -599,30 +606,30 @@ ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg,
#ifdef __KERNEL_OPENCL__
ccl_device_inline void object_position_transform_addrspace(KernelGlobals *kg,
- const ShaderData *sd,
- ccl_addr_space float3 *P)
+ const ShaderData *sd,
+ ccl_addr_space float3 *P)
{
- float3 private_P = *P;
- object_position_transform(kg, sd, &private_P);
- *P = private_P;
+ float3 private_P = *P;
+ object_position_transform(kg, sd, &private_P);
+ *P = private_P;
}
ccl_device_inline void object_dir_transform_addrspace(KernelGlobals *kg,
const ShaderData *sd,
ccl_addr_space float3 *D)
{
- float3 private_D = *D;
- object_dir_transform(kg, sd, &private_D);
- *D = private_D;
+ float3 private_D = *D;
+ object_dir_transform(kg, sd, &private_D);
+ *D = private_D;
}
ccl_device_inline void object_normal_transform_addrspace(KernelGlobals *kg,
const ShaderData *sd,
ccl_addr_space float3 *N)
{
- float3 private_N = *N;
- object_normal_transform(kg, sd, &private_N);
- *N = private_N;
+ float3 private_N = *N;
+ object_normal_transform(kg, sd, &private_N);
+ *N = private_N;
}
#endif
diff --git a/intern/cycles/kernel/geom/geom_patch.h b/intern/cycles/kernel/geom/geom_patch.h
index edb82172959..df19199f68e 100644
--- a/intern/cycles/kernel/geom/geom_patch.h
+++ b/intern/cycles/kernel/geom/geom_patch.h
@@ -27,342 +27,394 @@
CCL_NAMESPACE_BEGIN
typedef struct PatchHandle {
- int array_index, patch_index, vert_index;
+ int array_index, patch_index, vert_index;
} PatchHandle;
ccl_device_inline int patch_map_resolve_quadrant(float median, float *u, float *v)
{
- int quadrant = -1;
-
- if(*u < median) {
- if(*v < median) {
- quadrant = 0;
- }
- else {
- quadrant = 1;
- *v -= median;
- }
- }
- else {
- if(*v < median) {
- quadrant = 3;
- }
- else {
- quadrant = 2;
- *v -= median;
- }
- *u -= median;
- }
-
- return quadrant;
+ int quadrant = -1;
+
+ if (*u < median) {
+ if (*v < median) {
+ quadrant = 0;
+ }
+ else {
+ quadrant = 1;
+ *v -= median;
+ }
+ }
+ else {
+ if (*v < median) {
+ quadrant = 3;
+ }
+ else {
+ quadrant = 2;
+ *v -= median;
+ }
+ *u -= median;
+ }
+
+ return quadrant;
}
/* retrieve PatchHandle from patch coords */
-ccl_device_inline PatchHandle patch_map_find_patch(KernelGlobals *kg, int object, int patch, float u, float v)
+ccl_device_inline PatchHandle
+patch_map_find_patch(KernelGlobals *kg, int object, int patch, float u, float v)
{
- PatchHandle handle;
+ PatchHandle handle;
- kernel_assert((u >= 0.0f) && (u <= 1.0f) && (v >= 0.0f) && (v <= 1.0f));
+ kernel_assert((u >= 0.0f) && (u <= 1.0f) && (v >= 0.0f) && (v <= 1.0f));
- int node = (object_patch_map_offset(kg, object) + patch)/2;
- float median = 0.5f;
+ int node = (object_patch_map_offset(kg, object) + patch) / 2;
+ float median = 0.5f;
- for(int depth = 0; depth < 0xff; depth++) {
- float delta = median * 0.5f;
+ for (int depth = 0; depth < 0xff; depth++) {
+ float delta = median * 0.5f;
- int quadrant = patch_map_resolve_quadrant(median, &u, &v);
- kernel_assert(quadrant >= 0);
+ int quadrant = patch_map_resolve_quadrant(median, &u, &v);
+ kernel_assert(quadrant >= 0);
- uint child = kernel_tex_fetch(__patches, node + quadrant);
+ uint child = kernel_tex_fetch(__patches, node + quadrant);
- /* is the quadrant a hole? */
- if(!(child & PATCH_MAP_NODE_IS_SET)) {
- handle.array_index = -1;
- return handle;
- }
+ /* is the quadrant a hole? */
+ if (!(child & PATCH_MAP_NODE_IS_SET)) {
+ handle.array_index = -1;
+ return handle;
+ }
- uint index = child & PATCH_MAP_NODE_INDEX_MASK;
+ uint index = child & PATCH_MAP_NODE_INDEX_MASK;
- if(child & PATCH_MAP_NODE_IS_LEAF) {
- handle.array_index = kernel_tex_fetch(__patches, index + 0);
- handle.patch_index = kernel_tex_fetch(__patches, index + 1);
- handle.vert_index = kernel_tex_fetch(__patches, index + 2);
+ if (child & PATCH_MAP_NODE_IS_LEAF) {
+ handle.array_index = kernel_tex_fetch(__patches, index + 0);
+ handle.patch_index = kernel_tex_fetch(__patches, index + 1);
+ handle.vert_index = kernel_tex_fetch(__patches, index + 2);
- return handle;
- } else {
- node = index;
- }
+ return handle;
+ }
+ else {
+ node = index;
+ }
- median = delta;
- }
+ median = delta;
+ }
- /* no leaf found */
- kernel_assert(0);
+ /* no leaf found */
+ kernel_assert(0);
- handle.array_index = -1;
- return handle;
+ handle.array_index = -1;
+ return handle;
}
ccl_device_inline void patch_eval_bspline_weights(float t, float *point, float *deriv)
{
- /* The four uniform cubic B-Spline basis functions evaluated at t */
- float inv_6 = 1.0f / 6.0f;
-
- float t2 = t * t;
- float t3 = t * t2;
-
- point[0] = inv_6 * (1.0f - 3.0f*(t - t2) - t3);
- point[1] = inv_6 * (4.0f - 6.0f*t2 + 3.0f*t3);
- point[2] = inv_6 * (1.0f + 3.0f*(t + t2 - t3));
- point[3] = inv_6 * t3;
-
- /* Derivatives of the above four basis functions at t */
- deriv[0] = -0.5f*t2 + t - 0.5f;
- deriv[1] = 1.5f*t2 - 2.0f*t;
- deriv[2] = -1.5f*t2 + t + 0.5f;
- deriv[3] = 0.5f*t2;
+ /* The four uniform cubic B-Spline basis functions evaluated at t */
+ float inv_6 = 1.0f / 6.0f;
+
+ float t2 = t * t;
+ float t3 = t * t2;
+
+ point[0] = inv_6 * (1.0f - 3.0f * (t - t2) - t3);
+ point[1] = inv_6 * (4.0f - 6.0f * t2 + 3.0f * t3);
+ point[2] = inv_6 * (1.0f + 3.0f * (t + t2 - t3));
+ point[3] = inv_6 * t3;
+
+ /* Derivatives of the above four basis functions at t */
+ deriv[0] = -0.5f * t2 + t - 0.5f;
+ deriv[1] = 1.5f * t2 - 2.0f * t;
+ deriv[2] = -1.5f * t2 + t + 0.5f;
+ deriv[3] = 0.5f * t2;
}
ccl_device_inline void patch_eval_adjust_boundary_weights(uint bits, float *s, float *t)
{
- int boundary = ((bits >> 8) & 0xf);
-
- if(boundary & 1) {
- t[2] -= t[0];
- t[1] += 2*t[0];
- t[0] = 0;
- }
-
- if(boundary & 2) {
- s[1] -= s[3];
- s[2] += 2*s[3];
- s[3] = 0;
- }
-
- if(boundary & 4) {
- t[1] -= t[3];
- t[2] += 2*t[3];
- t[3] = 0;
- }
-
- if(boundary & 8) {
- s[2] -= s[0];
- s[1] += 2*s[0];
- s[0] = 0;
- }
+ int boundary = ((bits >> 8) & 0xf);
+
+ if (boundary & 1) {
+ t[2] -= t[0];
+ t[1] += 2 * t[0];
+ t[0] = 0;
+ }
+
+ if (boundary & 2) {
+ s[1] -= s[3];
+ s[2] += 2 * s[3];
+ s[3] = 0;
+ }
+
+ if (boundary & 4) {
+ t[1] -= t[3];
+ t[2] += 2 * t[3];
+ t[3] = 0;
+ }
+
+ if (boundary & 8) {
+ s[2] -= s[0];
+ s[1] += 2 * s[0];
+ s[0] = 0;
+ }
}
ccl_device_inline int patch_eval_depth(uint patch_bits)
{
- return (patch_bits & 0xf);
+ return (patch_bits & 0xf);
}
ccl_device_inline float patch_eval_param_fraction(uint patch_bits)
{
- bool non_quad_root = (patch_bits >> 4) & 0x1;
- int depth = patch_eval_depth(patch_bits);
-
- if(non_quad_root) {
- return 1.0f / (float)(1 << (depth-1));
- }
- else {
- return 1.0f / (float)(1 << depth);
- }
+ bool non_quad_root = (patch_bits >> 4) & 0x1;
+ int depth = patch_eval_depth(patch_bits);
+
+ if (non_quad_root) {
+ return 1.0f / (float)(1 << (depth - 1));
+ }
+ else {
+ return 1.0f / (float)(1 << depth);
+ }
}
ccl_device_inline void patch_eval_normalize_coords(uint patch_bits, float *u, float *v)
{
- float frac = patch_eval_param_fraction(patch_bits);
+ float frac = patch_eval_param_fraction(patch_bits);
- int iu = (patch_bits >> 22) & 0x3ff;
- int iv = (patch_bits >> 12) & 0x3ff;
+ int iu = (patch_bits >> 22) & 0x3ff;
+ int iv = (patch_bits >> 12) & 0x3ff;
- /* top left corner */
- float pu = (float)iu*frac;
- float pv = (float)iv*frac;
+ /* top left corner */
+ float pu = (float)iu * frac;
+ float pv = (float)iv * frac;
- /* normalize uv coordinates */
- *u = (*u - pu) / frac;
- *v = (*v - pv) / frac;
+ /* normalize uv coordinates */
+ *u = (*u - pu) / frac;
+ *v = (*v - pv) / frac;
}
/* retrieve patch control indices */
-ccl_device_inline int patch_eval_indices(KernelGlobals *kg, const PatchHandle *handle, int channel,
+ccl_device_inline int patch_eval_indices(KernelGlobals *kg,
+ const PatchHandle *handle,
+ int channel,
int indices[PATCH_MAX_CONTROL_VERTS])
{
- int index_base = kernel_tex_fetch(__patches, handle->array_index + 2) + handle->vert_index;
+ int index_base = kernel_tex_fetch(__patches, handle->array_index + 2) + handle->vert_index;
- /* XXX: regular patches only */
- for(int i = 0; i < 16; i++) {
- indices[i] = kernel_tex_fetch(__patches, index_base + i);
- }
+ /* XXX: regular patches only */
+ for (int i = 0; i < 16; i++) {
+ indices[i] = kernel_tex_fetch(__patches, index_base + i);
+ }
- return 16;
+ return 16;
}
/* evaluate patch basis functions */
-ccl_device_inline void patch_eval_basis(KernelGlobals *kg, const PatchHandle *handle, float u, float v,
- float weights[PATCH_MAX_CONTROL_VERTS],
- float weights_du[PATCH_MAX_CONTROL_VERTS],
- float weights_dv[PATCH_MAX_CONTROL_VERTS])
+ccl_device_inline void patch_eval_basis(KernelGlobals *kg,
+ const PatchHandle *handle,
+ float u,
+ float v,
+ float weights[PATCH_MAX_CONTROL_VERTS],
+ float weights_du[PATCH_MAX_CONTROL_VERTS],
+ float weights_dv[PATCH_MAX_CONTROL_VERTS])
{
- uint patch_bits = kernel_tex_fetch(__patches, handle->patch_index + 1); /* read patch param */
- float d_scale = 1 << patch_eval_depth(patch_bits);
+ uint patch_bits = kernel_tex_fetch(__patches, handle->patch_index + 1); /* read patch param */
+ float d_scale = 1 << patch_eval_depth(patch_bits);
- bool non_quad_root = (patch_bits >> 4) & 0x1;
- if(non_quad_root) {
- d_scale *= 0.5f;
- }
+ bool non_quad_root = (patch_bits >> 4) & 0x1;
+ if (non_quad_root) {
+ d_scale *= 0.5f;
+ }
- patch_eval_normalize_coords(patch_bits, &u, &v);
+ patch_eval_normalize_coords(patch_bits, &u, &v);
- /* XXX: regular patches only for now. */
+ /* XXX: regular patches only for now. */
- float s[4], t[4], ds[4], dt[4];
+ float s[4], t[4], ds[4], dt[4];
- patch_eval_bspline_weights(u, s, ds);
- patch_eval_bspline_weights(v, t, dt);
+ patch_eval_bspline_weights(u, s, ds);
+ patch_eval_bspline_weights(v, t, dt);
- patch_eval_adjust_boundary_weights(patch_bits, s, t);
- patch_eval_adjust_boundary_weights(patch_bits, ds, dt);
+ patch_eval_adjust_boundary_weights(patch_bits, s, t);
+ patch_eval_adjust_boundary_weights(patch_bits, ds, dt);
- for(int k = 0; k < 4; k++) {
- for(int l = 0; l < 4; l++) {
- weights[4*k+l] = s[l] * t[k];
- weights_du[4*k+l] = ds[l] * t[k] * d_scale;
- weights_dv[4*k+l] = s[l] * dt[k] * d_scale;
- }
- }
+ for (int k = 0; k < 4; k++) {
+ for (int l = 0; l < 4; l++) {
+ weights[4 * k + l] = s[l] * t[k];
+ weights_du[4 * k + l] = ds[l] * t[k] * d_scale;
+ weights_dv[4 * k + l] = s[l] * dt[k] * d_scale;
+ }
+ }
}
/* generic function for evaluating indices and weights from patch coords */
-ccl_device_inline int patch_eval_control_verts(KernelGlobals *kg, int object, int patch, float u, float v, int channel,
- int indices[PATCH_MAX_CONTROL_VERTS],
- float weights[PATCH_MAX_CONTROL_VERTS],
- float weights_du[PATCH_MAX_CONTROL_VERTS],
- float weights_dv[PATCH_MAX_CONTROL_VERTS])
+ccl_device_inline int patch_eval_control_verts(KernelGlobals *kg,
+ int object,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ int indices[PATCH_MAX_CONTROL_VERTS],
+ float weights[PATCH_MAX_CONTROL_VERTS],
+ float weights_du[PATCH_MAX_CONTROL_VERTS],
+ float weights_dv[PATCH_MAX_CONTROL_VERTS])
{
- PatchHandle handle = patch_map_find_patch(kg, object, patch, u, v);
- kernel_assert(handle.array_index >= 0);
+ PatchHandle handle = patch_map_find_patch(kg, object, patch, u, v);
+ kernel_assert(handle.array_index >= 0);
- int num_control = patch_eval_indices(kg, &handle, channel, indices);
- patch_eval_basis(kg, &handle, u, v, weights, weights_du, weights_dv);
+ int num_control = patch_eval_indices(kg, &handle, channel, indices);
+ patch_eval_basis(kg, &handle, u, v, weights, weights_du, weights_dv);
- return num_control;
+ return num_control;
}
/* functions for evaluating attributes on patches */
-ccl_device float patch_eval_float(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float *du, float* dv)
+ccl_device float patch_eval_float(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float *du,
+ float *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float val = 0.0f;
- if(du) *du = 0.0f;
- if(dv) *dv = 0.0f;
-
- for(int i = 0; i < num_control; i++) {
- float v = kernel_tex_fetch(__attributes_float, offset + indices[i]);
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float val = 0.0f;
+ if (du)
+ *du = 0.0f;
+ if (dv)
+ *dv = 0.0f;
+
+ for (int i = 0; i < num_control; i++) {
+ float v = kernel_tex_fetch(__attributes_float, offset + indices[i]);
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
-ccl_device float2 patch_eval_float2(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float2 *du, float2 *dv)
+ccl_device float2 patch_eval_float2(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float2 *du,
+ float2 *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float2 val = make_float2(0.0f, 0.0f);
- if(du) *du = make_float2(0.0f, 0.0f);
- if(dv) *dv = make_float2(0.0f, 0.0f);
-
- for(int i = 0; i < num_control; i++) {
- float2 v = kernel_tex_fetch(__attributes_float2, offset + indices[i]);
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float2 val = make_float2(0.0f, 0.0f);
+ if (du)
+ *du = make_float2(0.0f, 0.0f);
+ if (dv)
+ *dv = make_float2(0.0f, 0.0f);
+
+ for (int i = 0; i < num_control; i++) {
+ float2 v = kernel_tex_fetch(__attributes_float2, offset + indices[i]);
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
-ccl_device float3 patch_eval_float3(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float3 *du, float3 *dv)
+ccl_device float3 patch_eval_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float3 *du,
+ float3 *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float3 val = make_float3(0.0f, 0.0f, 0.0f);
- if(du) *du = make_float3(0.0f, 0.0f, 0.0f);
- if(dv) *dv = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < num_control; i++) {
- float3 v = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + indices[i]));
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float3 val = make_float3(0.0f, 0.0f, 0.0f);
+ if (du)
+ *du = make_float3(0.0f, 0.0f, 0.0f);
+ if (dv)
+ *dv = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < num_control; i++) {
+ float3 v = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + indices[i]));
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
-ccl_device float3 patch_eval_uchar4(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float3 *du, float3 *dv)
+ccl_device float3 patch_eval_uchar4(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float3 *du,
+ float3 *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float3 val = make_float3(0.0f, 0.0f, 0.0f);
- if(du) *du = make_float3(0.0f, 0.0f, 0.0f);
- if(dv) *dv = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < num_control; i++) {
- float3 v = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, offset + indices[i]));
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float3 val = make_float3(0.0f, 0.0f, 0.0f);
+ if (du)
+ *du = make_float3(0.0f, 0.0f, 0.0f);
+ if (dv)
+ *dv = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < num_control; i++) {
+ float3 v = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, offset + indices[i]));
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index 95d9d1050fb..7f2b52a24c4 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -22,57 +22,59 @@
CCL_NAMESPACE_BEGIN
/* Generic primitive attribute reading functions */
-ccl_device_inline float primitive_attribute_float(KernelGlobals *kg,
- const ShaderData *sd,
- const AttributeDescriptor desc,
- float *dx, float *dy)
+ccl_device_inline float primitive_attribute_float(
+ KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
{
- if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
- if(subd_triangle_patch(kg, sd) == ~0)
- return triangle_attribute_float(kg, sd, desc, dx, dy);
- else
- return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
- }
+ if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if (subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
+ }
#ifdef __HAIR__
- else if(sd->type & PRIMITIVE_ALL_CURVE) {
- return curve_attribute_float(kg, sd, desc, dx, dy);
- }
+ else if (sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float(kg, sd, desc, dx, dy);
+ }
#endif
#ifdef __VOLUME__
- else if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
- return volume_attribute_float(kg, sd, desc);
- }
+ else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
+ return volume_attribute_float(kg, sd, desc);
+ }
#endif
- else {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
- return 0.0f;
- }
+ else {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
+ return 0.0f;
+ }
}
-ccl_device_inline float primitive_surface_attribute_float(KernelGlobals *kg,
- const ShaderData *sd,
- const AttributeDescriptor desc,
- float *dx, float *dy)
+ccl_device_inline float primitive_surface_attribute_float(
+ KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
{
- if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
- if(subd_triangle_patch(kg, sd) == ~0)
- return triangle_attribute_float(kg, sd, desc, dx, dy);
- else
- return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
- }
+ if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if (subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
+ }
#ifdef __HAIR__
- else if(sd->type & PRIMITIVE_ALL_CURVE) {
- return curve_attribute_float(kg, sd, desc, dx, dy);
- }
+ else if (sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float(kg, sd, desc, dx, dy);
+ }
#endif
- else {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
- return 0.0f;
- }
+ else {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
+ return 0.0f;
+ }
}
#ifdef __VOLUME__
@@ -80,120 +82,136 @@ ccl_device_inline float primitive_volume_attribute_float(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc)
{
- if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
- return volume_attribute_float(kg, sd, desc);
- }
- else {
- return 0.0f;
- }
+ if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float(kg, sd, desc);
+ }
+ else {
+ return 0.0f;
+ }
}
#endif
ccl_device_inline float2 primitive_attribute_float2(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc,
- float2 *dx, float2 *dy)
+ float2 *dx,
+ float2 *dy)
{
- if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
- if(subd_triangle_patch(kg, sd) == ~0)
- return triangle_attribute_float2(kg, sd, desc, dx, dy);
- else
- return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
- }
+ if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if (subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float2(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
+ }
#ifdef __HAIR__
- else if(sd->type & PRIMITIVE_ALL_CURVE) {
- return curve_attribute_float2(kg, sd, desc, dx, dy);
- }
+ else if (sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float2(kg, sd, desc, dx, dy);
+ }
#endif
#ifdef __VOLUME__
- else if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
- kernel_assert(0);
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
- return make_float2(0.0f, 0.0f);
- }
+ else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
+ kernel_assert(0);
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+ return make_float2(0.0f, 0.0f);
+ }
#endif
- else {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
- return make_float2(0.0f, 0.0f);
- }
+ else {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+ return make_float2(0.0f, 0.0f);
+ }
}
ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc,
- float3 *dx, float3 *dy)
+ float3 *dx,
+ float3 *dy)
{
- if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
- if(subd_triangle_patch(kg, sd) == ~0)
- return triangle_attribute_float3(kg, sd, desc, dx, dy);
- else
- return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
- }
+ if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if (subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float3(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
+ }
#ifdef __HAIR__
- else if(sd->type & PRIMITIVE_ALL_CURVE) {
- return curve_attribute_float3(kg, sd, desc, dx, dy);
- }
+ else if (sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float3(kg, sd, desc, dx, dy);
+ }
#endif
#ifdef __VOLUME__
- else if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
- return volume_attribute_float3(kg, sd, desc);
- }
+ else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return volume_attribute_float3(kg, sd, desc);
+ }
#endif
- else {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ else {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc,
- float2 *dx, float2 *dy)
+ float2 *dx,
+ float2 *dy)
{
- if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
- if(subd_triangle_patch(kg, sd) == ~0)
- return triangle_attribute_float2(kg, sd, desc, dx, dy);
- else
- return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
- }
+ if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if (subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float2(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
+ }
#ifdef __HAIR__
- else if(sd->type & PRIMITIVE_ALL_CURVE) {
- return curve_attribute_float2(kg, sd, desc, dx, dy);
- }
+ else if (sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float2(kg, sd, desc, dx, dy);
+ }
#endif
- else {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
- return make_float2(0.0f, 0.0f);
- }
+ else {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+ return make_float2(0.0f, 0.0f);
+ }
}
ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc,
- float3 *dx, float3 *dy)
+ float3 *dx,
+ float3 *dy)
{
- if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
- if(subd_triangle_patch(kg, sd) == ~0)
- return triangle_attribute_float3(kg, sd, desc, dx, dy);
- else
- return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
- }
+ if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if (subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float3(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
+ }
#ifdef __HAIR__
- else if(sd->type & PRIMITIVE_ALL_CURVE) {
- return curve_attribute_float3(kg, sd, desc, dx, dy);
- }
+ else if (sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float3(kg, sd, desc, dx, dy);
+ }
#endif
- else {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ else {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
#ifdef __VOLUME__
@@ -201,12 +219,12 @@ ccl_device_inline float3 primitive_volume_attribute_float3(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc)
{
- if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
- return volume_attribute_float3(kg, sd, desc);
- }
- else {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float3(kg, sd, desc);
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
#endif
@@ -214,33 +232,33 @@ ccl_device_inline float3 primitive_volume_attribute_float3(KernelGlobals *kg,
ccl_device_inline float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
{
- const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_UV);
+ const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_UV);
- if(desc.offset == ATTR_STD_NOT_FOUND)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (desc.offset == ATTR_STD_NOT_FOUND)
+ return make_float3(0.0f, 0.0f, 0.0f);
- float2 uv = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
- return make_float3(uv.x, uv.y, 1.0f);
+ float2 uv = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
+ return make_float3(uv.x, uv.y, 1.0f);
}
/* Ptex coordinates */
ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id)
{
- /* storing ptex data as attributes is not memory efficient but simple for tests */
- const AttributeDescriptor desc_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID);
- const AttributeDescriptor desc_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV);
+ /* storing ptex data as attributes is not memory efficient but simple for tests */
+ const AttributeDescriptor desc_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID);
+ const AttributeDescriptor desc_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV);
- if(desc_face_id.offset == ATTR_STD_NOT_FOUND || desc_uv.offset == ATTR_STD_NOT_FOUND)
- return false;
+ if (desc_face_id.offset == ATTR_STD_NOT_FOUND || desc_uv.offset == ATTR_STD_NOT_FOUND)
+ return false;
- float3 uv3 = primitive_surface_attribute_float3(kg, sd, desc_uv, NULL, NULL);
- float face_id_f = primitive_surface_attribute_float(kg, sd, desc_face_id, NULL, NULL);
+ float3 uv3 = primitive_surface_attribute_float3(kg, sd, desc_uv, NULL, NULL);
+ float face_id_f = primitive_surface_attribute_float(kg, sd, desc_face_id, NULL, NULL);
- *uv = make_float2(uv3.x, uv3.y);
- *face_id = (int)face_id_f;
+ *uv = make_float2(uv3.x, uv3.y);
+ *face_id = (int)face_id_f;
- return true;
+ return true;
}
/* Surface tangent */
@@ -248,125 +266,125 @@ ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, in
ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_CURVE)
+ if (sd->type & PRIMITIVE_ALL_CURVE)
# ifdef __DPDU__
- return normalize(sd->dPdu);
+ return normalize(sd->dPdu);
# else
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
# endif
#endif
- /* try to create spherical tangent from generated coordinates */
- const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED);
-
- if(desc.offset != ATTR_STD_NOT_FOUND) {
- float3 data = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
- data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
- object_normal_transform(kg, sd, &data);
- return cross(sd->N, normalize(cross(data, sd->N)));
- }
- else {
- /* otherwise use surface derivatives */
+ /* try to create spherical tangent from generated coordinates */
+ const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED);
+
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ float3 data = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
+ data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
+ object_normal_transform(kg, sd, &data);
+ return cross(sd->N, normalize(cross(data, sd->N)));
+ }
+ else {
+ /* otherwise use surface derivatives */
#ifdef __DPDU__
- return normalize(sd->dPdu);
+ return normalize(sd->dPdu);
#else
- return make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
#endif
- }
+ }
}
/* Motion vector for motion pass */
ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
{
- /* center position */
- float3 center;
+ /* center position */
+ float3 center;
#ifdef __HAIR__
- bool is_curve_primitive = sd->type & PRIMITIVE_ALL_CURVE;
- if(is_curve_primitive) {
- center = curve_motion_center_location(kg, sd);
-
- if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_position_transform(kg, sd, &center);
- }
- }
- else
+ bool is_curve_primitive = sd->type & PRIMITIVE_ALL_CURVE;
+ if (is_curve_primitive) {
+ center = curve_motion_center_location(kg, sd);
+
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_position_transform(kg, sd, &center);
+ }
+ }
+ else
#endif
- center = sd->P;
+ center = sd->P;
- float3 motion_pre = center, motion_post = center;
+ float3 motion_pre = center, motion_post = center;
- /* deformation motion */
- AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_MOTION_VERTEX_POSITION);
+ /* deformation motion */
+ AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_MOTION_VERTEX_POSITION);
- if(desc.offset != ATTR_STD_NOT_FOUND) {
- /* get motion info */
- int numverts, numkeys;
- object_motion_info(kg, sd->object, NULL, &numverts, &numkeys);
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ /* get motion info */
+ int numverts, numkeys;
+ object_motion_info(kg, sd->object, NULL, &numverts, &numkeys);
- /* lookup attributes */
- motion_pre = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
+ /* lookup attributes */
+ motion_pre = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
- desc.offset += (sd->type & PRIMITIVE_ALL_TRIANGLE)? numverts: numkeys;
- motion_post = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
+ desc.offset += (sd->type & PRIMITIVE_ALL_TRIANGLE) ? numverts : numkeys;
+ motion_post = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
#ifdef __HAIR__
- if(is_curve_primitive && (sd->object_flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {
- object_position_transform(kg, sd, &motion_pre);
- object_position_transform(kg, sd, &motion_post);
- }
+ if (is_curve_primitive && (sd->object_flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {
+ object_position_transform(kg, sd, &motion_pre);
+ object_position_transform(kg, sd, &motion_post);
+ }
#endif
- }
-
- /* object motion. note that depending on the mesh having motion vectors, this
- * transformation was set match the world/object space of motion_pre/post */
- Transform tfm;
-
- tfm = object_fetch_motion_pass_transform(kg, sd->object, OBJECT_PASS_MOTION_PRE);
- motion_pre = transform_point(&tfm, motion_pre);
-
- tfm = object_fetch_motion_pass_transform(kg, sd->object, OBJECT_PASS_MOTION_POST);
- motion_post = transform_point(&tfm, motion_post);
-
- float3 motion_center;
-
- /* camera motion, for perspective/orthographic motion.pre/post will be a
- * world-to-raster matrix, for panorama it's world-to-camera */
- if(kernel_data.cam.type != CAMERA_PANORAMA) {
- ProjectionTransform projection = kernel_data.cam.worldtoraster;
- motion_center = transform_perspective(&projection, center);
-
- projection = kernel_data.cam.perspective_pre;
- motion_pre = transform_perspective(&projection, motion_pre);
-
- projection = kernel_data.cam.perspective_post;
- motion_post = transform_perspective(&projection, motion_post);
- }
- else {
- tfm = kernel_data.cam.worldtocamera;
- motion_center = normalize(transform_point(&tfm, center));
- motion_center = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_center));
- motion_center.x *= kernel_data.cam.width;
- motion_center.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion_pass_pre;
- motion_pre = normalize(transform_point(&tfm, motion_pre));
- motion_pre = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_pre));
- motion_pre.x *= kernel_data.cam.width;
- motion_pre.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion_pass_post;
- motion_post = normalize(transform_point(&tfm, motion_post));
- motion_post = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_post));
- motion_post.x *= kernel_data.cam.width;
- motion_post.y *= kernel_data.cam.height;
- }
-
- motion_pre = motion_pre - motion_center;
- motion_post = motion_center - motion_post;
-
- return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
+ }
+
+ /* object motion. note that depending on the mesh having motion vectors, this
+ * transformation was set match the world/object space of motion_pre/post */
+ Transform tfm;
+
+ tfm = object_fetch_motion_pass_transform(kg, sd->object, OBJECT_PASS_MOTION_PRE);
+ motion_pre = transform_point(&tfm, motion_pre);
+
+ tfm = object_fetch_motion_pass_transform(kg, sd->object, OBJECT_PASS_MOTION_POST);
+ motion_post = transform_point(&tfm, motion_post);
+
+ float3 motion_center;
+
+ /* camera motion, for perspective/orthographic motion.pre/post will be a
+ * world-to-raster matrix, for panorama it's world-to-camera */
+ if (kernel_data.cam.type != CAMERA_PANORAMA) {
+ ProjectionTransform projection = kernel_data.cam.worldtoraster;
+ motion_center = transform_perspective(&projection, center);
+
+ projection = kernel_data.cam.perspective_pre;
+ motion_pre = transform_perspective(&projection, motion_pre);
+
+ projection = kernel_data.cam.perspective_post;
+ motion_post = transform_perspective(&projection, motion_post);
+ }
+ else {
+ tfm = kernel_data.cam.worldtocamera;
+ motion_center = normalize(transform_point(&tfm, center));
+ motion_center = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_center));
+ motion_center.x *= kernel_data.cam.width;
+ motion_center.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion_pass_pre;
+ motion_pre = normalize(transform_point(&tfm, motion_pre));
+ motion_pre = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_pre));
+ motion_pre.x *= kernel_data.cam.width;
+ motion_pre.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion_pass_post;
+ motion_post = normalize(transform_point(&tfm, motion_post));
+ motion_post = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_post));
+ motion_post.x *= kernel_data.cam.width;
+ motion_post.y *= kernel_data.cam.height;
+ }
+
+ motion_pre = motion_pre - motion_center;
+ motion_post = motion_center - motion_post;
+
+ return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_subd_triangle.h b/intern/cycles/kernel/geom/geom_subd_triangle.h
index 251e070c21f..8d5b3c12833 100644
--- a/intern/cycles/kernel/geom/geom_subd_triangle.h
+++ b/intern/cycles/kernel/geom/geom_subd_triangle.h
@@ -22,455 +22,492 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline uint subd_triangle_patch(KernelGlobals *kg, const ShaderData *sd)
{
- return (sd->prim != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, sd->prim) : ~0;
+ return (sd->prim != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, sd->prim) : ~0;
}
/* UV coords of triangle within patch */
-ccl_device_inline void subd_triangle_patch_uv(KernelGlobals *kg, const ShaderData *sd, float2 uv[3])
+ccl_device_inline void subd_triangle_patch_uv(KernelGlobals *kg,
+ const ShaderData *sd,
+ float2 uv[3])
{
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- uv[0] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.x);
- uv[1] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.y);
- uv[2] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.z);
+ uv[0] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.x);
+ uv[1] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.y);
+ uv[2] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.z);
}
/* Vertex indices of patch */
ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals *kg, int patch)
{
- uint4 indices;
+ uint4 indices;
- indices.x = kernel_tex_fetch(__patches, patch+0);
- indices.y = kernel_tex_fetch(__patches, patch+1);
- indices.z = kernel_tex_fetch(__patches, patch+2);
- indices.w = kernel_tex_fetch(__patches, patch+3);
+ indices.x = kernel_tex_fetch(__patches, patch + 0);
+ indices.y = kernel_tex_fetch(__patches, patch + 1);
+ indices.z = kernel_tex_fetch(__patches, patch + 2);
+ indices.w = kernel_tex_fetch(__patches, patch + 3);
- return indices;
+ return indices;
}
/* Originating face for patch */
ccl_device_inline uint subd_triangle_patch_face(KernelGlobals *kg, int patch)
{
- return kernel_tex_fetch(__patches, patch+4);
+ return kernel_tex_fetch(__patches, patch + 4);
}
/* Number of corners on originating face */
ccl_device_inline uint subd_triangle_patch_num_corners(KernelGlobals *kg, int patch)
{
- return kernel_tex_fetch(__patches, patch+5) & 0xffff;
+ return kernel_tex_fetch(__patches, patch + 5) & 0xffff;
}
/* Indices of the four corners that are used by the patch */
ccl_device_inline void subd_triangle_patch_corners(KernelGlobals *kg, int patch, int corners[4])
{
- uint4 data;
-
- data.x = kernel_tex_fetch(__patches, patch+4);
- data.y = kernel_tex_fetch(__patches, patch+5);
- data.z = kernel_tex_fetch(__patches, patch+6);
- data.w = kernel_tex_fetch(__patches, patch+7);
-
- int num_corners = data.y & 0xffff;
-
- if(num_corners == 4) {
- /* quad */
- corners[0] = data.z;
- corners[1] = data.z+1;
- corners[2] = data.z+2;
- corners[3] = data.z+3;
- }
- else {
- /* ngon */
- int c = data.y >> 16;
-
- corners[0] = data.z + c;
- corners[1] = data.z + mod(c+1, num_corners);
- corners[2] = data.w;
- corners[3] = data.z + mod(c-1, num_corners);
- }
+ uint4 data;
+
+ data.x = kernel_tex_fetch(__patches, patch + 4);
+ data.y = kernel_tex_fetch(__patches, patch + 5);
+ data.z = kernel_tex_fetch(__patches, patch + 6);
+ data.w = kernel_tex_fetch(__patches, patch + 7);
+
+ int num_corners = data.y & 0xffff;
+
+ if (num_corners == 4) {
+ /* quad */
+ corners[0] = data.z;
+ corners[1] = data.z + 1;
+ corners[2] = data.z + 2;
+ corners[3] = data.z + 3;
+ }
+ else {
+ /* ngon */
+ int c = data.y >> 16;
+
+ corners[0] = data.z + c;
+ corners[1] = data.z + mod(c + 1, num_corners);
+ corners[2] = data.w;
+ corners[3] = data.z + mod(c - 1, num_corners);
+ }
}
/* Reading attributes on various subdivision triangle elements */
-ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
+ccl_device_noinline float subd_triangle_attribute_float(
+ KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd);
#ifdef __PATCH_EVAL__
- if(desc.flags & ATTR_SUBDIVIDED) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- float2 dpdu = uv[0] - uv[2];
- float2 dpdv = uv[1] - uv[2];
-
- /* p is [s, t] */
- float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
-
- float a, dads, dadt;
- a = patch_eval_float(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+ if (desc.flags & ATTR_SUBDIVIDED) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ float2 dpdu = uv[0] - uv[2];
+ float2 dpdv = uv[1] - uv[2];
+
+ /* p is [s, t] */
+ float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
+
+ float a, dads, dadt;
+ a = patch_eval_float(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx || dy) {
+ float dsdu = dpdu.x;
+ float dtdu = dpdu.y;
+ float dsdv = dpdv.x;
+ float dtdv = dpdv.y;
+
+ if (dx) {
+ float dudx = sd->du.dx;
+ float dvdx = sd->dv.dx;
+
+ float dsdx = dsdu * dudx + dsdv * dvdx;
+ float dtdx = dtdu * dudx + dtdv * dvdx;
+
+ *dx = dads * dsdx + dadt * dtdx;
+ }
+ if (dy) {
+ float dudy = sd->du.dy;
+ float dvdy = sd->dv.dy;
+
+ float dsdy = dsdu * dudy + dsdv * dvdy;
+ float dtdy = dtdu * dudy + dtdv * dvdy;
+
+ *dy = dads * dsdy + dadt * dtdy;
+ }
+ }
+# endif
+
+ return a;
+ }
+ else
+#endif /* __PATCH_EVAL__ */
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
+
+ return kernel_tex_fetch(__attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ uint4 v = subd_triangle_patch_indices(kg, patch);
+
+ float f0 = kernel_tex_fetch(__attributes_float, desc.offset + v.x);
+ float f1 = kernel_tex_fetch(__attributes_float, desc.offset + v.y);
+ float f2 = kernel_tex_fetch(__attributes_float, desc.offset + v.z);
+ float f3 = kernel_tex_fetch(__attributes_float, desc.offset + v.w);
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx || dy) {
- float dsdu = dpdu.x;
- float dtdu = dpdu.y;
- float dsdv = dpdv.x;
- float dtdv = dpdv.y;
-
- if(dx) {
- float dudx = sd->du.dx;
- float dvdx = sd->dv.dx;
-
- float dsdx = dsdu*dudx + dsdv*dvdx;
- float dtdx = dtdu*dudx + dtdv*dvdx;
-
- *dx = dads*dsdx + dadt*dtdx;
- }
- if(dy) {
- float dudy = sd->du.dy;
- float dvdy = sd->dv.dy;
-
- float dsdy = dsdu*dudy + dsdv*dvdy;
- float dtdy = dtdu*dudy + dtdv*dvdy;
-
- *dy = dads*dsdy + dadt*dtdy;
- }
- }
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return a;
- }
- else
-#endif /* __PATCH_EVAL__ */
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
- return kernel_tex_fetch(__attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
+ int corners[4];
+ subd_triangle_patch_corners(kg, patch, corners);
- uint4 v = subd_triangle_patch_indices(kg, patch);
+ float f0 = kernel_tex_fetch(__attributes_float, corners[0] + desc.offset);
+ float f1 = kernel_tex_fetch(__attributes_float, corners[1] + desc.offset);
+ float f2 = kernel_tex_fetch(__attributes_float, corners[2] + desc.offset);
+ float f3 = kernel_tex_fetch(__attributes_float, corners[3] + desc.offset);
- float f0 = kernel_tex_fetch(__attributes_float, desc.offset + v.x);
- float f1 = kernel_tex_fetch(__attributes_float, desc.offset + v.y);
- float f2 = kernel_tex_fetch(__attributes_float, desc.offset + v.z);
- float f3 = kernel_tex_fetch(__attributes_float, desc.offset + v.w);
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- int corners[4];
- subd_triangle_patch_corners(kg, patch, corners);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
- float f0 = kernel_tex_fetch(__attributes_float, corners[0] + desc.offset);
- float f1 = kernel_tex_fetch(__attributes_float, corners[1] + desc.offset);
- float f2 = kernel_tex_fetch(__attributes_float, corners[2] + desc.offset);
- float f3 = kernel_tex_fetch(__attributes_float, corners[3] + desc.offset);
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
-#endif
-
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-
- return 0.0f;
- }
+ return 0.0f;
+ }
}
-ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
+ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float2 *dx,
+ float2 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd);
#ifdef __PATCH_EVAL__
- if(desc.flags & ATTR_SUBDIVIDED) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- float2 dpdu = uv[0] - uv[2];
- float2 dpdv = uv[1] - uv[2];
-
- /* p is [s, t] */
- float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
-
- float2 a, dads, dadt;
-
- a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx || dy) {
- float dsdu = dpdu.x;
- float dtdu = dpdu.y;
- float dsdv = dpdv.x;
- float dtdv = dpdv.y;
-
- if(dx) {
- float dudx = sd->du.dx;
- float dvdx = sd->dv.dx;
-
- float dsdx = dsdu*dudx + dsdv*dvdx;
- float dtdx = dtdu*dudx + dtdv*dvdx;
-
- *dx = dads*dsdx + dadt*dtdx;
- }
- if(dy) {
- float dudy = sd->du.dy;
- float dvdy = sd->dv.dy;
-
- float dsdy = dsdu*dudy + dsdv*dvdy;
- float dtdy = dtdu*dudy + dtdv*dvdy;
-
- *dy = dads*dsdy + dadt*dtdy;
- }
- }
-#endif
-
- return a;
- }
- else
-#endif /* __PATCH_EVAL__ */
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
-
- return kernel_tex_fetch(__attributes_float2, desc.offset + subd_triangle_patch_face(kg, patch));
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- uint4 v = subd_triangle_patch_indices(kg, patch);
-
- float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + v.x);
- float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + v.y);
- float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + v.z);
- float2 f3 = kernel_tex_fetch(__attributes_float2, desc.offset + v.w);
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ if (desc.flags & ATTR_SUBDIVIDED) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ float2 dpdu = uv[0] - uv[2];
+ float2 dpdv = uv[1] - uv[2];
+
+ /* p is [s, t] */
+ float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
+
+ float2 a, dads, dadt;
+
+ a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx || dy) {
+ float dsdu = dpdu.x;
+ float dtdu = dpdu.y;
+ float dsdv = dpdv.x;
+ float dtdv = dpdv.y;
+
+ if (dx) {
+ float dudx = sd->du.dx;
+ float dvdx = sd->dv.dx;
+
+ float dsdx = dsdu * dudx + dsdv * dvdx;
+ float dtdx = dtdu * dudx + dtdv * dvdx;
+
+ *dx = dads * dsdx + dadt * dtdx;
+ }
+ if (dy) {
+ float dudy = sd->du.dy;
+ float dvdy = sd->dv.dy;
+
+ float dsdy = dsdu * dudy + dsdv * dvdy;
+ float dtdy = dtdu * dudy + dtdv * dvdy;
+
+ *dy = dads * dsdy + dadt * dtdy;
+ }
+ }
+# endif
+
+ return a;
+ }
+ else
+#endif /* __PATCH_EVAL__ */
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+
+ return kernel_tex_fetch(__attributes_float2,
+ desc.offset + subd_triangle_patch_face(kg, patch));
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ uint4 v = subd_triangle_patch_indices(kg, patch);
+
+ float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + v.x);
+ float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + v.y);
+ float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + v.z);
+ float2 f3 = kernel_tex_fetch(__attributes_float2, desc.offset + v.w);
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
- int corners[4];
- subd_triangle_patch_corners(kg, patch, corners);
+ int corners[4];
+ subd_triangle_patch_corners(kg, patch, corners);
- float2 f0, f1, f2, f3;
+ float2 f0, f1, f2, f3;
- f0 = kernel_tex_fetch(__attributes_float2, corners[0] + desc.offset);
- f1 = kernel_tex_fetch(__attributes_float2, corners[1] + desc.offset);
- f2 = kernel_tex_fetch(__attributes_float2, corners[2] + desc.offset);
- f3 = kernel_tex_fetch(__attributes_float2, corners[3] + desc.offset);
+ f0 = kernel_tex_fetch(__attributes_float2, corners[0] + desc.offset);
+ f1 = kernel_tex_fetch(__attributes_float2, corners[1] + desc.offset);
+ f2 = kernel_tex_fetch(__attributes_float2, corners[2] + desc.offset);
+ f3 = kernel_tex_fetch(__attributes_float2, corners[3] + desc.offset);
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
- float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
- return make_float2(0.0f, 0.0f);
- }
+ return make_float2(0.0f, 0.0f);
+ }
}
-ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
+ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float3 *dx,
+ float3 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd);
#ifdef __PATCH_EVAL__
- if(desc.flags & ATTR_SUBDIVIDED) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- float2 dpdu = uv[0] - uv[2];
- float2 dpdv = uv[1] - uv[2];
-
- /* p is [s, t] */
- float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
-
- float3 a, dads, dadt;
-
- if(desc.element == ATTR_ELEMENT_CORNER_BYTE) {
- a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
- }
- else {
- a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
- }
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx || dy) {
- float dsdu = dpdu.x;
- float dtdu = dpdu.y;
- float dsdv = dpdv.x;
- float dtdv = dpdv.y;
-
- if(dx) {
- float dudx = sd->du.dx;
- float dvdx = sd->dv.dx;
-
- float dsdx = dsdu*dudx + dsdv*dvdx;
- float dtdx = dtdu*dudx + dtdv*dvdx;
-
- *dx = dads*dsdx + dadt*dtdx;
- }
- if(dy) {
- float dudy = sd->du.dy;
- float dvdy = sd->dv.dy;
-
- float dsdy = dsdu*dudy + dsdv*dvdy;
- float dtdy = dtdu*dudy + dtdv*dvdy;
-
- *dy = dads*dsdy + dadt*dtdy;
- }
- }
-#endif
-
- return a;
- }
- else
-#endif /* __PATCH_EVAL__ */
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch)));
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- uint4 v = subd_triangle_patch_indices(kg, patch);
-
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.x));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.y));
- float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.z));
- float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.w));
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ if (desc.flags & ATTR_SUBDIVIDED) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ float2 dpdu = uv[0] - uv[2];
+ float2 dpdv = uv[1] - uv[2];
+
+ /* p is [s, t] */
+ float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
+
+ float3 a, dads, dadt;
+
+ if (desc.element == ATTR_ELEMENT_CORNER_BYTE) {
+ a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+ }
+ else {
+ a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+ }
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx || dy) {
+ float dsdu = dpdu.x;
+ float dtdu = dpdu.y;
+ float dsdv = dpdv.x;
+ float dtdv = dpdv.y;
+
+ if (dx) {
+ float dudx = sd->du.dx;
+ float dvdx = sd->dv.dx;
+
+ float dsdx = dsdu * dudx + dsdv * dvdx;
+ float dtdx = dtdu * dudx + dtdv * dvdx;
+
+ *dx = dads * dsdx + dadt * dtdx;
+ }
+ if (dy) {
+ float dudy = sd->du.dy;
+ float dvdy = sd->dv.dy;
+
+ float dsdy = dsdu * dudy + dsdv * dvdy;
+ float dtdy = dtdu * dudy + dtdv * dvdy;
+
+ *dy = dads * dsdy + dadt * dtdy;
+ }
+ }
+# endif
+
+ return a;
+ }
+ else
+#endif /* __PATCH_EVAL__ */
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+ return float4_to_float3(
+ kernel_tex_fetch(__attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch)));
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ uint4 v = subd_triangle_patch_indices(kg, patch);
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.x));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.y));
+ float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.z));
+ float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.w));
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- int corners[4];
- subd_triangle_patch_corners(kg, patch, corners);
-
- float3 f0, f1, f2, f3;
-
- if(desc.element == ATTR_ELEMENT_CORNER) {
- f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset));
- f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset));
- f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset));
- f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset));
- }
- else {
- f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset));
- f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset));
- f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset));
- f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset));
- }
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ int corners[4];
+ subd_triangle_patch_corners(kg, patch, corners);
+
+ float3 f0, f1, f2, f3;
+
+ if (desc.element == ATTR_ELEMENT_CORNER) {
+ f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset));
+ f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset));
+ f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset));
+ f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset));
+ }
+ else {
+ f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset));
+ f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset));
+ f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset));
+ f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset));
+ }
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index 300227c38e6..9938c0ba2c3 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -25,227 +25,268 @@ CCL_NAMESPACE_BEGIN
/* normal on triangle */
ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd)
{
- /* load triangle vertices */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- const float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
- const float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
- const float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
-
- /* return normal */
- if(sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
- return normalize(cross(v2 - v0, v1 - v0));
- }
- else {
- return normalize(cross(v1 - v0, v2 - v0));
- }
+ /* load triangle vertices */
+ const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ const float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 0));
+ const float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 1));
+ const float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 2));
+
+ /* return normal */
+ if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
+ return normalize(cross(v2 - v0, v1 - v0));
+ }
+ else {
+ return normalize(cross(v1 - v0, v2 - v0));
+ }
}
/* point and normal on triangle */
-ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int prim, float u, float v, float3 *P, float3 *Ng, int *shader)
+ccl_device_inline void triangle_point_normal(
+ KernelGlobals *kg, int object, int prim, float u, float v, float3 *P, float3 *Ng, int *shader)
{
- /* load triangle vertices */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
- float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
- float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
- /* compute point */
- float t = 1.0f - u - v;
- *P = (u*v0 + v*v1 + t*v2);
- /* get object flags */
- int object_flag = kernel_tex_fetch(__object_flag, object);
- /* compute normal */
- if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
- *Ng = normalize(cross(v2 - v0, v1 - v0));
- }
- else {
- *Ng = normalize(cross(v1 - v0, v2 - v0));
- }
- /* shader`*/
- *shader = kernel_tex_fetch(__tri_shader, prim);
+ /* load triangle vertices */
+ const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+ float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 0));
+ float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 1));
+ float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 2));
+ /* compute point */
+ float t = 1.0f - u - v;
+ *P = (u * v0 + v * v1 + t * v2);
+ /* get object flags */
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ /* compute normal */
+ if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
+ *Ng = normalize(cross(v2 - v0, v1 - v0));
+ }
+ else {
+ *Ng = normalize(cross(v1 - v0, v2 - v0));
+ }
+ /* shader`*/
+ *shader = kernel_tex_fetch(__tri_shader, prim);
}
/* Triangle vertex locations */
ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3])
{
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- P[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
- P[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
- P[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
+ const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+ P[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 0));
+ P[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 1));
+ P[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 2));
}
/* Interpolate smooth vertex normal from vertices */
-ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, float3 Ng, int prim, float u, float v)
+ccl_device_inline float3
+triangle_smooth_normal(KernelGlobals *kg, float3 Ng, int prim, float u, float v)
{
- /* load triangle vertices */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
- float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
- float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
+ /* load triangle vertices */
+ const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+ float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
+ float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
+ float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
- float3 N = safe_normalize((1.0f - u - v)*n2 + u*n0 + v*n1);
+ float3 N = safe_normalize((1.0f - u - v) * n2 + u * n0 + v * n1);
- return is_zero(N)? Ng: N;
+ return is_zero(N) ? Ng : N;
}
/* Ray differentials on triangle */
-ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, ccl_addr_space float3 *dPdu, ccl_addr_space float3 *dPdv)
+ccl_device_inline void triangle_dPdudv(KernelGlobals *kg,
+ int prim,
+ ccl_addr_space float3 *dPdu,
+ ccl_addr_space float3 *dPdv)
{
- /* fetch triangle vertex coordinates */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- const float3 p0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
- const float3 p1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
- const float3 p2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
-
- /* compute derivatives of P w.r.t. uv */
- *dPdu = (p0 - p2);
- *dPdv = (p1 - p2);
+ /* fetch triangle vertex coordinates */
+ const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+ const float3 p0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 0));
+ const float3 p1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 1));
+ const float3 p2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 2));
+
+ /* compute derivatives of P w.r.t. uv */
+ *dPdu = (p0 - p2);
+ *dPdv = (p1 - p2);
}
/* Reading attributes on various triangle elements */
-ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
+ccl_device float triangle_attribute_float(
+ KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
{
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
- return kernel_tex_fetch(__attributes_float, desc.offset + sd->prim);
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ return kernel_tex_fetch(__attributes_float, desc.offset + sd->prim);
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- float f0 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.x);
- float f1 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.y);
- float f2 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.z);
+ float f0 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.x);
+ float f1 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.y);
+ float f2 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.z);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+ if (dx)
+ *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2;
+ if (dy)
+ *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2;
#endif
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER) {
- int tri = desc.offset + sd->prim*3;
- float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
- float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
- float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
+ return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER) {
+ int tri = desc.offset + sd->prim * 3;
+ float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
+ float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
+ float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+ if (dx)
+ *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2;
+ if (dy)
+ *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2;
#endif
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
+ return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2;
+ }
+ else {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
- return 0.0f;
- }
+ return 0.0f;
+ }
}
-ccl_device float2 triangle_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
+ccl_device float2 triangle_attribute_float2(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float2 *dx,
+ float2 *dy)
{
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
- return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.x);
- float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.y);
- float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.z);
+ float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.x);
+ float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.y);
+ float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.z);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+ if (dx)
+ *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2;
+ if (dy)
+ *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2;
#endif
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER) {
- int tri = desc.offset + sd->prim*3;
- float2 f0, f1, f2;
+ return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER) {
+ int tri = desc.offset + sd->prim * 3;
+ float2 f0, f1, f2;
- if(desc.element == ATTR_ELEMENT_CORNER) {
- f0 = kernel_tex_fetch(__attributes_float2, tri + 0);
- f1 = kernel_tex_fetch(__attributes_float2, tri + 1);
- f2 = kernel_tex_fetch(__attributes_float2, tri + 2);
- }
+ if (desc.element == ATTR_ELEMENT_CORNER) {
+ f0 = kernel_tex_fetch(__attributes_float2, tri + 0);
+ f1 = kernel_tex_fetch(__attributes_float2, tri + 1);
+ f2 = kernel_tex_fetch(__attributes_float2, tri + 2);
+ }
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+ if (dx)
+ *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2;
+ if (dy)
+ *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2;
#endif
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
+ return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2;
+ }
+ else {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
- return make_float2(0.0f, 0.0f);
- }
+ return make_float2(0.0f, 0.0f);
+ }
}
-ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
+ccl_device float3 triangle_attribute_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float3 *dx,
+ float3 *dy)
{
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim));
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
-
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y));
- float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z));
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim));
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+
+ float3 f0 = float4_to_float3(
+ kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x));
+ float3 f1 = float4_to_float3(
+ kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y));
+ float3 f2 = float4_to_float3(
+ kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z));
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+ if (dx)
+ *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2;
+ if (dy)
+ *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2;
#endif
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
- int tri = desc.offset + sd->prim*3;
- float3 f0, f1, f2;
-
- if(desc.element == ATTR_ELEMENT_CORNER) {
- f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
- f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
- f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
- }
- else {
- f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 0));
- f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 1));
- f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 2));
- }
+ return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
+ int tri = desc.offset + sd->prim * 3;
+ float3 f0, f1, f2;
+
+ if (desc.element == ATTR_ELEMENT_CORNER) {
+ f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
+ f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
+ f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
+ }
+ else {
+ f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 0));
+ f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 1));
+ f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 2));
+ }
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+ if (dx)
+ *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2;
+ if (dy)
+ *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2;
#endif
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2;
+ }
+ else {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index 56dbc4473fa..bcad03102d2 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -1,4 +1,4 @@
- /*
+/*
* Copyright 2014, Blender Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,447 +30,464 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
int object,
int prim_addr)
{
- const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
+ const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- const ssef *ssef_verts = (ssef*)&kg->__prim_tri_verts.data[tri_vindex];
+ const ssef *ssef_verts = (ssef *)&kg->__prim_tri_verts.data[tri_vindex];
#else
- const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0),
- tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1),
- tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2);
+ const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 0),
+ tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 1),
+ tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 2);
#endif
- float t, u, v;
- if(ray_triangle_intersect(P,
- dir,
- isect->t,
+ float t, u, v;
+ if (ray_triangle_intersect(P,
+ dir,
+ isect->t,
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- ssef_verts,
+ ssef_verts,
#else
- float4_to_float3(tri_a),
- float4_to_float3(tri_b),
- float4_to_float3(tri_c),
+ float4_to_float3(tri_a),
+ float4_to_float3(tri_b),
+ float4_to_float3(tri_c),
#endif
- &u, &v, &t))
- {
+ &u,
+ &v,
+ &t)) {
#ifdef __VISIBILITY_FLAG__
- /* Visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags.
- */
- if(kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
+ /* Visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags.
+ */
+ if (kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
#endif
- {
- isect->prim = prim_addr;
- isect->object = object;
- isect->type = PRIMITIVE_TRIANGLE;
- isect->u = u;
- isect->v = v;
- isect->t = t;
- return true;
- }
- }
- return false;
+ {
+ isect->prim = prim_addr;
+ isect->object = object;
+ isect->type = PRIMITIVE_TRIANGLE;
+ isect->u = u;
+ isect->v = v;
+ isect->t = t;
+ return true;
+ }
+ }
+ return false;
}
#ifdef __KERNEL_AVX2__
-#define cross256(A,B, C,D) _mm256_fmsub_ps(A,B, _mm256_mul_ps(C,D))
-ccl_device_inline int ray_triangle_intersect8(
- KernelGlobals *kg,
- float3 ray_P,
- float3 ray_dir,
- Intersection **isect,
- uint visibility,
- int object,
- __m256 *triA,
- __m256 *triB,
- __m256 *triC,
- int prim_addr,
- int prim_num,
- uint *num_hits,
- uint max_hits,
- int *num_hits_in_instance,
- float isect_t)
+# define cross256(A, B, C, D) _mm256_fmsub_ps(A, B, _mm256_mul_ps(C, D))
+ccl_device_inline int ray_triangle_intersect8(KernelGlobals *kg,
+ float3 ray_P,
+ float3 ray_dir,
+ Intersection **isect,
+ uint visibility,
+ int object,
+ __m256 *triA,
+ __m256 *triB,
+ __m256 *triC,
+ int prim_addr,
+ int prim_num,
+ uint *num_hits,
+ uint max_hits,
+ int *num_hits_in_instance,
+ float isect_t)
{
- const unsigned char prim_num_mask = (1 << prim_num) - 1;
-
- const __m256i zero256 = _mm256_setzero_si256();
-
- const __m256 Px256 = _mm256_set1_ps(ray_P.x);
- const __m256 Py256 = _mm256_set1_ps(ray_P.y);
- const __m256 Pz256 = _mm256_set1_ps(ray_P.z);
-
- const __m256 dirx256 = _mm256_set1_ps(ray_dir.x);
- const __m256 diry256 = _mm256_set1_ps(ray_dir.y);
- const __m256 dirz256 = _mm256_set1_ps(ray_dir.z);
-
- /* Calculate vertices relative to ray origin. */
- __m256 v0_x_256 = _mm256_sub_ps(triC[0], Px256);
- __m256 v0_y_256 = _mm256_sub_ps(triC[1], Py256);
- __m256 v0_z_256 = _mm256_sub_ps(triC[2], Pz256);
-
- __m256 v1_x_256 = _mm256_sub_ps(triA[0], Px256);
- __m256 v1_y_256 = _mm256_sub_ps(triA[1], Py256);
- __m256 v1_z_256 = _mm256_sub_ps(triA[2], Pz256);
-
- __m256 v2_x_256 = _mm256_sub_ps(triB[0], Px256);
- __m256 v2_y_256 = _mm256_sub_ps(triB[1], Py256);
- __m256 v2_z_256 = _mm256_sub_ps(triB[2], Pz256);
-
- __m256 v0_v1_x_256 = _mm256_add_ps(v0_x_256, v1_x_256);
- __m256 v0_v1_y_256 = _mm256_add_ps(v0_y_256, v1_y_256);
- __m256 v0_v1_z_256 = _mm256_add_ps(v0_z_256, v1_z_256);
-
- __m256 v0_v2_x_256 = _mm256_add_ps(v0_x_256, v2_x_256);
- __m256 v0_v2_y_256 = _mm256_add_ps(v0_y_256, v2_y_256);
- __m256 v0_v2_z_256 = _mm256_add_ps(v0_z_256, v2_z_256);
-
- __m256 v1_v2_x_256 = _mm256_add_ps(v1_x_256, v2_x_256);
- __m256 v1_v2_y_256 = _mm256_add_ps(v1_y_256, v2_y_256);
- __m256 v1_v2_z_256 = _mm256_add_ps(v1_z_256, v2_z_256);
-
- /* Calculate triangle edges. */
- __m256 e0_x_256 = _mm256_sub_ps(v2_x_256, v0_x_256);
- __m256 e0_y_256 = _mm256_sub_ps(v2_y_256, v0_y_256);
- __m256 e0_z_256 = _mm256_sub_ps(v2_z_256, v0_z_256);
-
- __m256 e1_x_256 = _mm256_sub_ps(v0_x_256, v1_x_256);
- __m256 e1_y_256 = _mm256_sub_ps(v0_y_256, v1_y_256);
- __m256 e1_z_256 = _mm256_sub_ps(v0_z_256, v1_z_256);
-
- __m256 e2_x_256 = _mm256_sub_ps(v1_x_256, v2_x_256);
- __m256 e2_y_256 = _mm256_sub_ps(v1_y_256, v2_y_256);
- __m256 e2_z_256 = _mm256_sub_ps(v1_z_256, v2_z_256);
-
- /* Perform edge tests. */
- /* cross (AyBz - AzBy, AzBx -AxBz, AxBy - AyBx) */
- __m256 U_x_256 = cross256(v0_v2_y_256, e0_z_256, v0_v2_z_256, e0_y_256);
- __m256 U_y_256 = cross256(v0_v2_z_256, e0_x_256, v0_v2_x_256, e0_z_256);
- __m256 U_z_256 = cross256(v0_v2_x_256, e0_y_256, v0_v2_y_256, e0_x_256);
- /* vertical dot */
- __m256 U_256 = _mm256_mul_ps(U_x_256, dirx256);
- U_256 = _mm256_fmadd_ps(U_y_256, diry256, U_256);
- U_256 = _mm256_fmadd_ps(U_z_256, dirz256, U_256);
-
- __m256 V_x_256 = cross256(v0_v1_y_256, e1_z_256, v0_v1_z_256, e1_y_256);
- __m256 V_y_256 = cross256(v0_v1_z_256, e1_x_256, v0_v1_x_256, e1_z_256);
- __m256 V_z_256 = cross256(v0_v1_x_256, e1_y_256, v0_v1_y_256, e1_x_256);
- /* vertical dot */
- __m256 V_256 = _mm256_mul_ps(V_x_256, dirx256);
- V_256 = _mm256_fmadd_ps(V_y_256, diry256, V_256);
- V_256 = _mm256_fmadd_ps(V_z_256, dirz256, V_256);
-
- __m256 W_x_256 = cross256(v1_v2_y_256, e2_z_256, v1_v2_z_256, e2_y_256);
- __m256 W_y_256 = cross256(v1_v2_z_256, e2_x_256, v1_v2_x_256, e2_z_256);
- __m256 W_z_256 = cross256(v1_v2_x_256, e2_y_256, v1_v2_y_256, e2_x_256);
- /* vertical dot */
- __m256 W_256 = _mm256_mul_ps(W_x_256, dirx256);
- W_256 = _mm256_fmadd_ps(W_y_256, diry256,W_256);
- W_256 = _mm256_fmadd_ps(W_z_256, dirz256,W_256);
-
- __m256i U_256_1 = _mm256_srli_epi32(_mm256_castps_si256(U_256), 31);
- __m256i V_256_1 = _mm256_srli_epi32(_mm256_castps_si256(V_256), 31);
- __m256i W_256_1 = _mm256_srli_epi32(_mm256_castps_si256(W_256), 31);
- __m256i UVW_256_1 = _mm256_add_epi32(_mm256_add_epi32(U_256_1, V_256_1), W_256_1);
-
- const __m256i one256 = _mm256_set1_epi32(1);
- const __m256i two256 = _mm256_set1_epi32(2);
-
- __m256i mask_minmaxUVW_256 = _mm256_or_si256(
- _mm256_cmpeq_epi32(one256, UVW_256_1),
- _mm256_cmpeq_epi32(two256, UVW_256_1));
-
- unsigned char mask_minmaxUVW_pos = _mm256_movemask_ps(_mm256_castsi256_ps(mask_minmaxUVW_256));
- if((mask_minmaxUVW_pos & prim_num_mask) == prim_num_mask) { //all bits set
- return false;
- }
-
- /* Calculate geometry normal and denominator. */
- __m256 Ng1_x_256 = cross256(e1_y_256, e0_z_256, e1_z_256, e0_y_256);
- __m256 Ng1_y_256 = cross256(e1_z_256, e0_x_256, e1_x_256, e0_z_256);
- __m256 Ng1_z_256 = cross256(e1_x_256, e0_y_256, e1_y_256, e0_x_256);
-
- Ng1_x_256 = _mm256_add_ps(Ng1_x_256, Ng1_x_256);
- Ng1_y_256 = _mm256_add_ps(Ng1_y_256, Ng1_y_256);
- Ng1_z_256 = _mm256_add_ps(Ng1_z_256, Ng1_z_256);
-
- /* vertical dot */
- __m256 den_256 = _mm256_mul_ps(Ng1_x_256, dirx256);
- den_256 = _mm256_fmadd_ps(Ng1_y_256, diry256,den_256);
- den_256 = _mm256_fmadd_ps(Ng1_z_256, dirz256,den_256);
-
- /* Perform depth test. */
- __m256 T_256 = _mm256_mul_ps(Ng1_x_256, v0_x_256);
- T_256 = _mm256_fmadd_ps(Ng1_y_256, v0_y_256,T_256);
- T_256 = _mm256_fmadd_ps(Ng1_z_256, v0_z_256,T_256);
-
- const __m256i c0x80000000 = _mm256_set1_epi32(0x80000000);
- __m256i sign_den_256 = _mm256_and_si256(_mm256_castps_si256(den_256), c0x80000000);
-
- __m256 sign_T_256 = _mm256_castsi256_ps(_mm256_xor_si256(_mm256_castps_si256(T_256), sign_den_256));
-
- unsigned char mask_sign_T = _mm256_movemask_ps(sign_T_256);
- if(((mask_minmaxUVW_pos | mask_sign_T) & prim_num_mask) == prim_num_mask) {
- return false;
- }
-
- __m256 xor_signmask_256 = _mm256_castsi256_ps(_mm256_xor_si256(_mm256_castps_si256(den_256), sign_den_256));
-
- ccl_align(32) float den8[8], U8[8], V8[8], T8[8], sign_T8[8], xor_signmask8[8];
- ccl_align(32) unsigned int mask_minmaxUVW8[8];
-
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
- __m256i mask_final_256 = _mm256_cmpeq_epi32(mask_minmaxUVW_256, zero256);
- __m256i maskden256 = _mm256_cmpeq_epi32(_mm256_castps_si256(den_256), zero256);
- __m256i mask0 = _mm256_cmpgt_epi32(zero256, _mm256_castps_si256(sign_T_256));
- __m256 rayt_256 = _mm256_set1_ps((*isect)->t);
- __m256i mask1 = _mm256_cmpgt_epi32(_mm256_castps_si256(sign_T_256),
- _mm256_castps_si256(
- _mm256_mul_ps(_mm256_castsi256_ps(_mm256_xor_si256(_mm256_castps_si256(den_256), sign_den_256)), rayt_256)
- )
- );
- mask0 = _mm256_or_si256(mask1, mask0);
- mask_final_256 = _mm256_andnot_si256(mask0, mask_final_256); //(~mask_minmaxUVW_pos) &(~mask)
- mask_final_256 = _mm256_andnot_si256(maskden256, mask_final_256); //(~mask_minmaxUVW_pos) &(~mask) & (~maskden)
- unsigned char mask_final = _mm256_movemask_ps(_mm256_castsi256_ps(mask_final_256));
- if((mask_final & prim_num_mask) == 0) {
- return false;
- }
- const int i = __bsf(mask_final);
- __m256 inv_den_256 = _mm256_rcp_ps(den_256);
- U_256 = _mm256_mul_ps(U_256, inv_den_256);
- V_256 = _mm256_mul_ps(V_256, inv_den_256);
- T_256 = _mm256_mul_ps(T_256, inv_den_256);
- _mm256_store_ps(U8, U_256);
- _mm256_store_ps(V8, V_256);
- _mm256_store_ps(T8, T_256);
- /* NOTE: Here we assume visibility for all triangles in the node is
- * the same. */
- (*isect)->u = U8[i];
- (*isect)->v = V8[i];
- (*isect)->t = T8[i];
- (*isect)->prim = (prim_addr + i);
- (*isect)->object = object;
- (*isect)->type = PRIMITIVE_TRIANGLE;
- return true;
- }
- else {
- _mm256_store_ps(den8, den_256);
- _mm256_store_ps(U8, U_256);
- _mm256_store_ps(V8, V_256);
- _mm256_store_ps(T8, T_256);
-
- _mm256_store_ps(sign_T8, sign_T_256);
- _mm256_store_ps(xor_signmask8, xor_signmask_256);
- _mm256_store_si256((__m256i*)mask_minmaxUVW8, mask_minmaxUVW_256);
-
- int ret = false;
-
- if(visibility == PATH_RAY_SHADOW) {
- for(int i = 0; i < prim_num; i++) {
- if(mask_minmaxUVW8[i]) {
- continue;
- }
-#ifdef __VISIBILITY_FLAG__
- if((kernel_tex_fetch(__prim_visibility, (prim_addr + i)) & visibility) == 0) {
- continue;
- }
-#endif
- if((sign_T8[i] < 0.0f) ||
- (sign_T8[i] > (*isect)->t * xor_signmask8[i]))
- {
- continue;
- }
- if(!den8[i]) {
- continue;
- }
- const float inv_den = 1.0f / den8[i];
- (*isect)->u = U8[i] * inv_den;
- (*isect)->v = V8[i] * inv_den;
- (*isect)->t = T8[i] * inv_den;
- (*isect)->prim = (prim_addr + i);
- (*isect)->object = object;
- (*isect)->type = PRIMITIVE_TRIANGLE;
- const int prim = kernel_tex_fetch(__prim_index, (*isect)->prim);
- int shader = 0;
-#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, (*isect)->prim) & PRIMITIVE_ALL_TRIANGLE)
-#endif
- {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
-#ifdef __HAIR__
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
-#endif
- const int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
- /* If no transparent shadows, all light is blocked. */
- if(!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
- return 2;
- }
- /* If maximum number of hits reached, block all light. */
- else if(num_hits == NULL || *num_hits == max_hits) {
- return 2;
- }
- /* Move on to next entry in intersections array. */
- ret = true;
- (*isect)++;
- (*num_hits)++;
- (*num_hits_in_instance)++;
- (*isect)->t = isect_t;
- }
- }
- else {
- for(int i = 0; i < prim_num; i++) {
- if(mask_minmaxUVW8[i]) {
- continue;
- }
-#ifdef __VISIBILITY_FLAG__
- if((kernel_tex_fetch(__prim_visibility, (prim_addr + i)) & visibility) == 0) {
- continue;
- }
-#endif
- if((sign_T8[i] < 0.0f) ||
- (sign_T8[i] > (*isect)->t * xor_signmask8[i]))
- {
- continue;
- }
- if(!den8[i]) {
- continue;
- }
- const float inv_den = 1.0f / den8[i];
- (*isect)->u = U8[i] * inv_den;
- (*isect)->v = V8[i] * inv_den;
- (*isect)->t = T8[i] * inv_den;
- (*isect)->prim = (prim_addr + i);
- (*isect)->object = object;
- (*isect)->type = PRIMITIVE_TRIANGLE;
- ret = true;
- }
- }
- return ret;
- }
+ const unsigned char prim_num_mask = (1 << prim_num) - 1;
+
+ const __m256i zero256 = _mm256_setzero_si256();
+
+ const __m256 Px256 = _mm256_set1_ps(ray_P.x);
+ const __m256 Py256 = _mm256_set1_ps(ray_P.y);
+ const __m256 Pz256 = _mm256_set1_ps(ray_P.z);
+
+ const __m256 dirx256 = _mm256_set1_ps(ray_dir.x);
+ const __m256 diry256 = _mm256_set1_ps(ray_dir.y);
+ const __m256 dirz256 = _mm256_set1_ps(ray_dir.z);
+
+ /* Calculate vertices relative to ray origin. */
+ __m256 v0_x_256 = _mm256_sub_ps(triC[0], Px256);
+ __m256 v0_y_256 = _mm256_sub_ps(triC[1], Py256);
+ __m256 v0_z_256 = _mm256_sub_ps(triC[2], Pz256);
+
+ __m256 v1_x_256 = _mm256_sub_ps(triA[0], Px256);
+ __m256 v1_y_256 = _mm256_sub_ps(triA[1], Py256);
+ __m256 v1_z_256 = _mm256_sub_ps(triA[2], Pz256);
+
+ __m256 v2_x_256 = _mm256_sub_ps(triB[0], Px256);
+ __m256 v2_y_256 = _mm256_sub_ps(triB[1], Py256);
+ __m256 v2_z_256 = _mm256_sub_ps(triB[2], Pz256);
+
+ __m256 v0_v1_x_256 = _mm256_add_ps(v0_x_256, v1_x_256);
+ __m256 v0_v1_y_256 = _mm256_add_ps(v0_y_256, v1_y_256);
+ __m256 v0_v1_z_256 = _mm256_add_ps(v0_z_256, v1_z_256);
+
+ __m256 v0_v2_x_256 = _mm256_add_ps(v0_x_256, v2_x_256);
+ __m256 v0_v2_y_256 = _mm256_add_ps(v0_y_256, v2_y_256);
+ __m256 v0_v2_z_256 = _mm256_add_ps(v0_z_256, v2_z_256);
+
+ __m256 v1_v2_x_256 = _mm256_add_ps(v1_x_256, v2_x_256);
+ __m256 v1_v2_y_256 = _mm256_add_ps(v1_y_256, v2_y_256);
+ __m256 v1_v2_z_256 = _mm256_add_ps(v1_z_256, v2_z_256);
+
+ /* Calculate triangle edges. */
+ __m256 e0_x_256 = _mm256_sub_ps(v2_x_256, v0_x_256);
+ __m256 e0_y_256 = _mm256_sub_ps(v2_y_256, v0_y_256);
+ __m256 e0_z_256 = _mm256_sub_ps(v2_z_256, v0_z_256);
+
+ __m256 e1_x_256 = _mm256_sub_ps(v0_x_256, v1_x_256);
+ __m256 e1_y_256 = _mm256_sub_ps(v0_y_256, v1_y_256);
+ __m256 e1_z_256 = _mm256_sub_ps(v0_z_256, v1_z_256);
+
+ __m256 e2_x_256 = _mm256_sub_ps(v1_x_256, v2_x_256);
+ __m256 e2_y_256 = _mm256_sub_ps(v1_y_256, v2_y_256);
+ __m256 e2_z_256 = _mm256_sub_ps(v1_z_256, v2_z_256);
+
+ /* Perform edge tests. */
+ /* cross (AyBz - AzBy, AzBx -AxBz, AxBy - AyBx) */
+ __m256 U_x_256 = cross256(v0_v2_y_256, e0_z_256, v0_v2_z_256, e0_y_256);
+ __m256 U_y_256 = cross256(v0_v2_z_256, e0_x_256, v0_v2_x_256, e0_z_256);
+ __m256 U_z_256 = cross256(v0_v2_x_256, e0_y_256, v0_v2_y_256, e0_x_256);
+ /* vertical dot */
+ __m256 U_256 = _mm256_mul_ps(U_x_256, dirx256);
+ U_256 = _mm256_fmadd_ps(U_y_256, diry256, U_256);
+ U_256 = _mm256_fmadd_ps(U_z_256, dirz256, U_256);
+
+ __m256 V_x_256 = cross256(v0_v1_y_256, e1_z_256, v0_v1_z_256, e1_y_256);
+ __m256 V_y_256 = cross256(v0_v1_z_256, e1_x_256, v0_v1_x_256, e1_z_256);
+ __m256 V_z_256 = cross256(v0_v1_x_256, e1_y_256, v0_v1_y_256, e1_x_256);
+ /* vertical dot */
+ __m256 V_256 = _mm256_mul_ps(V_x_256, dirx256);
+ V_256 = _mm256_fmadd_ps(V_y_256, diry256, V_256);
+ V_256 = _mm256_fmadd_ps(V_z_256, dirz256, V_256);
+
+ __m256 W_x_256 = cross256(v1_v2_y_256, e2_z_256, v1_v2_z_256, e2_y_256);
+ __m256 W_y_256 = cross256(v1_v2_z_256, e2_x_256, v1_v2_x_256, e2_z_256);
+ __m256 W_z_256 = cross256(v1_v2_x_256, e2_y_256, v1_v2_y_256, e2_x_256);
+ /* vertical dot */
+ __m256 W_256 = _mm256_mul_ps(W_x_256, dirx256);
+ W_256 = _mm256_fmadd_ps(W_y_256, diry256, W_256);
+ W_256 = _mm256_fmadd_ps(W_z_256, dirz256, W_256);
+
+ __m256i U_256_1 = _mm256_srli_epi32(_mm256_castps_si256(U_256), 31);
+ __m256i V_256_1 = _mm256_srli_epi32(_mm256_castps_si256(V_256), 31);
+ __m256i W_256_1 = _mm256_srli_epi32(_mm256_castps_si256(W_256), 31);
+ __m256i UVW_256_1 = _mm256_add_epi32(_mm256_add_epi32(U_256_1, V_256_1), W_256_1);
+
+ const __m256i one256 = _mm256_set1_epi32(1);
+ const __m256i two256 = _mm256_set1_epi32(2);
+
+ __m256i mask_minmaxUVW_256 = _mm256_or_si256(_mm256_cmpeq_epi32(one256, UVW_256_1),
+ _mm256_cmpeq_epi32(two256, UVW_256_1));
+
+ unsigned char mask_minmaxUVW_pos = _mm256_movemask_ps(_mm256_castsi256_ps(mask_minmaxUVW_256));
+ if ((mask_minmaxUVW_pos & prim_num_mask) == prim_num_mask) { //all bits set
+ return false;
+ }
+
+ /* Calculate geometry normal and denominator. */
+ __m256 Ng1_x_256 = cross256(e1_y_256, e0_z_256, e1_z_256, e0_y_256);
+ __m256 Ng1_y_256 = cross256(e1_z_256, e0_x_256, e1_x_256, e0_z_256);
+ __m256 Ng1_z_256 = cross256(e1_x_256, e0_y_256, e1_y_256, e0_x_256);
+
+ Ng1_x_256 = _mm256_add_ps(Ng1_x_256, Ng1_x_256);
+ Ng1_y_256 = _mm256_add_ps(Ng1_y_256, Ng1_y_256);
+ Ng1_z_256 = _mm256_add_ps(Ng1_z_256, Ng1_z_256);
+
+ /* vertical dot */
+ __m256 den_256 = _mm256_mul_ps(Ng1_x_256, dirx256);
+ den_256 = _mm256_fmadd_ps(Ng1_y_256, diry256, den_256);
+ den_256 = _mm256_fmadd_ps(Ng1_z_256, dirz256, den_256);
+
+ /* Perform depth test. */
+ __m256 T_256 = _mm256_mul_ps(Ng1_x_256, v0_x_256);
+ T_256 = _mm256_fmadd_ps(Ng1_y_256, v0_y_256, T_256);
+ T_256 = _mm256_fmadd_ps(Ng1_z_256, v0_z_256, T_256);
+
+ const __m256i c0x80000000 = _mm256_set1_epi32(0x80000000);
+ __m256i sign_den_256 = _mm256_and_si256(_mm256_castps_si256(den_256), c0x80000000);
+
+ __m256 sign_T_256 = _mm256_castsi256_ps(
+ _mm256_xor_si256(_mm256_castps_si256(T_256), sign_den_256));
+
+ unsigned char mask_sign_T = _mm256_movemask_ps(sign_T_256);
+ if (((mask_minmaxUVW_pos | mask_sign_T) & prim_num_mask) == prim_num_mask) {
+ return false;
+ }
+
+ __m256 xor_signmask_256 = _mm256_castsi256_ps(
+ _mm256_xor_si256(_mm256_castps_si256(den_256), sign_den_256));
+
+ ccl_align(32) float den8[8], U8[8], V8[8], T8[8], sign_T8[8], xor_signmask8[8];
+ ccl_align(32) unsigned int mask_minmaxUVW8[8];
+
+ if (visibility == PATH_RAY_SHADOW_OPAQUE) {
+ __m256i mask_final_256 = _mm256_cmpeq_epi32(mask_minmaxUVW_256, zero256);
+ __m256i maskden256 = _mm256_cmpeq_epi32(_mm256_castps_si256(den_256), zero256);
+ __m256i mask0 = _mm256_cmpgt_epi32(zero256, _mm256_castps_si256(sign_T_256));
+ __m256 rayt_256 = _mm256_set1_ps((*isect)->t);
+ __m256i mask1 = _mm256_cmpgt_epi32(
+ _mm256_castps_si256(sign_T_256),
+ _mm256_castps_si256(_mm256_mul_ps(
+ _mm256_castsi256_ps(_mm256_xor_si256(_mm256_castps_si256(den_256), sign_den_256)),
+ rayt_256)));
+ mask0 = _mm256_or_si256(mask1, mask0);
+ mask_final_256 = _mm256_andnot_si256(mask0, mask_final_256); //(~mask_minmaxUVW_pos) &(~mask)
+ mask_final_256 = _mm256_andnot_si256(
+ maskden256, mask_final_256); //(~mask_minmaxUVW_pos) &(~mask) & (~maskden)
+ unsigned char mask_final = _mm256_movemask_ps(_mm256_castsi256_ps(mask_final_256));
+ if ((mask_final & prim_num_mask) == 0) {
+ return false;
+ }
+ const int i = __bsf(mask_final);
+ __m256 inv_den_256 = _mm256_rcp_ps(den_256);
+ U_256 = _mm256_mul_ps(U_256, inv_den_256);
+ V_256 = _mm256_mul_ps(V_256, inv_den_256);
+ T_256 = _mm256_mul_ps(T_256, inv_den_256);
+ _mm256_store_ps(U8, U_256);
+ _mm256_store_ps(V8, V_256);
+ _mm256_store_ps(T8, T_256);
+ /* NOTE: Here we assume visibility for all triangles in the node is
+ * the same. */
+ (*isect)->u = U8[i];
+ (*isect)->v = V8[i];
+ (*isect)->t = T8[i];
+ (*isect)->prim = (prim_addr + i);
+ (*isect)->object = object;
+ (*isect)->type = PRIMITIVE_TRIANGLE;
+ return true;
+ }
+ else {
+ _mm256_store_ps(den8, den_256);
+ _mm256_store_ps(U8, U_256);
+ _mm256_store_ps(V8, V_256);
+ _mm256_store_ps(T8, T_256);
+
+ _mm256_store_ps(sign_T8, sign_T_256);
+ _mm256_store_ps(xor_signmask8, xor_signmask_256);
+ _mm256_store_si256((__m256i *)mask_minmaxUVW8, mask_minmaxUVW_256);
+
+ int ret = false;
+
+ if (visibility == PATH_RAY_SHADOW) {
+ for (int i = 0; i < prim_num; i++) {
+ if (mask_minmaxUVW8[i]) {
+ continue;
+ }
+# ifdef __VISIBILITY_FLAG__
+ if ((kernel_tex_fetch(__prim_visibility, (prim_addr + i)) & visibility) == 0) {
+ continue;
+ }
+# endif
+ if ((sign_T8[i] < 0.0f) || (sign_T8[i] > (*isect)->t * xor_signmask8[i])) {
+ continue;
+ }
+ if (!den8[i]) {
+ continue;
+ }
+ const float inv_den = 1.0f / den8[i];
+ (*isect)->u = U8[i] * inv_den;
+ (*isect)->v = V8[i] * inv_den;
+ (*isect)->t = T8[i] * inv_den;
+ (*isect)->prim = (prim_addr + i);
+ (*isect)->object = object;
+ (*isect)->type = PRIMITIVE_TRIANGLE;
+ const int prim = kernel_tex_fetch(__prim_index, (*isect)->prim);
+ int shader = 0;
+# ifdef __HAIR__
+ if (kernel_tex_fetch(__prim_type, (*isect)->prim) & PRIMITIVE_ALL_TRIANGLE)
+# endif
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
+# ifdef __HAIR__
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+# endif
+ const int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+ /* If no transparent shadows, all light is blocked. */
+ if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ return 2;
+ }
+ /* If maximum number of hits reached, block all light. */
+ else if (num_hits == NULL || *num_hits == max_hits) {
+ return 2;
+ }
+ /* Move on to next entry in intersections array. */
+ ret = true;
+ (*isect)++;
+ (*num_hits)++;
+ (*num_hits_in_instance)++;
+ (*isect)->t = isect_t;
+ }
+ }
+ else {
+ for (int i = 0; i < prim_num; i++) {
+ if (mask_minmaxUVW8[i]) {
+ continue;
+ }
+# ifdef __VISIBILITY_FLAG__
+ if ((kernel_tex_fetch(__prim_visibility, (prim_addr + i)) & visibility) == 0) {
+ continue;
+ }
+# endif
+ if ((sign_T8[i] < 0.0f) || (sign_T8[i] > (*isect)->t * xor_signmask8[i])) {
+ continue;
+ }
+ if (!den8[i]) {
+ continue;
+ }
+ const float inv_den = 1.0f / den8[i];
+ (*isect)->u = U8[i] * inv_den;
+ (*isect)->v = V8[i] * inv_den;
+ (*isect)->t = T8[i] * inv_den;
+ (*isect)->prim = (prim_addr + i);
+ (*isect)->object = object;
+ (*isect)->type = PRIMITIVE_TRIANGLE;
+ ret = true;
+ }
+ }
+ return ret;
+ }
}
-ccl_device_inline int triangle_intersect8(
- KernelGlobals *kg,
- Intersection **isect,
- float3 P,
- float3 dir,
- uint visibility,
- int object,
- int prim_addr,
- int prim_num,
- uint *num_hits,
- uint max_hits,
- int *num_hits_in_instance,
- float isect_t)
- {
- __m128 tri_a[8], tri_b[8], tri_c[8];
- __m256 tritmp[12], tri[12];
- __m256 triA[3], triB[3], triC[3];
-
- int i, r;
-
- uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
- for(i = 0; i < prim_num; i++) {
- tri_a[i] = *(__m128*)&kg->__prim_tri_verts.data[tri_vindex++];
- tri_b[i] = *(__m128*)&kg->__prim_tri_verts.data[tri_vindex++];
- tri_c[i] = *(__m128*)&kg->__prim_tri_verts.data[tri_vindex++];
- }
- //create 9 or 12 placeholders
- tri[0] = _mm256_castps128_ps256(tri_a[0]); //_mm256_zextps128_ps256
- tri[1] = _mm256_castps128_ps256(tri_b[0]);//_mm256_zextps128_ps256
- tri[2] = _mm256_castps128_ps256(tri_c[0]);//_mm256_zextps128_ps256
-
- tri[3] = _mm256_castps128_ps256(tri_a[1]); //_mm256_zextps128_ps256
- tri[4] = _mm256_castps128_ps256(tri_b[1]);//_mm256_zextps128_ps256
- tri[5] = _mm256_castps128_ps256(tri_c[1]);//_mm256_zextps128_ps256
-
- tri[6] = _mm256_castps128_ps256(tri_a[2]); //_mm256_zextps128_ps256
- tri[7] = _mm256_castps128_ps256(tri_b[2]);//_mm256_zextps128_ps256
- tri[8] = _mm256_castps128_ps256(tri_c[2]);//_mm256_zextps128_ps256
-
- if(prim_num > 3) {
- tri[9] = _mm256_castps128_ps256(tri_a[3]); //_mm256_zextps128_ps256
- tri[10] = _mm256_castps128_ps256(tri_b[3]);//_mm256_zextps128_ps256
- tri[11] = _mm256_castps128_ps256(tri_c[3]);//_mm256_zextps128_ps256
- }
-
- for(i = 4, r = 0; i < prim_num; i ++, r += 3) {
- tri[r] = _mm256_insertf128_ps(tri[r] , tri_a[i], 1);
- tri[r + 1] = _mm256_insertf128_ps(tri[r + 1], tri_b[i], 1);
- tri[r + 2] = _mm256_insertf128_ps(tri[r + 2], tri_c[i], 1);
- }
-
- //------------------------------------------------
- //0! Xa0 Ya0 Za0 1 Xa4 Ya4 Za4 1
- //1! Xb0 Yb0 Zb0 1 Xb4 Yb4 Zb4 1
- //2! Xc0 Yc0 Zc0 1 Xc4 Yc4 Zc4 1
-
- //3! Xa1 Ya1 Za1 1 Xa5 Ya5 Za5 1
- //4! Xb1 Yb1 Zb1 1 Xb5 Yb5 Zb5 1
- //5! Xc1 Yc1 Zc1 1 Xc5 Yc5 Zc5 1
-
- //6! Xa2 Ya2 Za2 1 Xa6 Ya6 Za6 1
- //7! Xb2 Yb2 Zb2 1 Xb6 Yb6 Zb6 1
- //8! Xc2 Yc2 Zc2 1 Xc6 Yc6 Zc6 1
-
- //9! Xa3 Ya3 Za3 1 Xa7 Ya7 Za7 1
- //10! Xb3 Yb3 Zb3 1 Xb7 Yb7 Zb7 1
- //11! Xc3 Yc3 Zc3 1 Xc7 Yc7 Zc7 1
-
- //"transpose"
- tritmp[0] = _mm256_unpacklo_ps(tri[0], tri[3]); //0! Xa0 Xa1 Ya0 Ya1 Xa4 Xa5 Ya4 Ya5
- tritmp[1] = _mm256_unpackhi_ps(tri[0], tri[3]); //1! Za0 Za1 1 1 Za4 Za5 1 1
-
- tritmp[2] = _mm256_unpacklo_ps(tri[6], tri[9]); //2! Xa2 Xa3 Ya2 Ya3 Xa6 Xa7 Ya6 Ya7
- tritmp[3] = _mm256_unpackhi_ps(tri[6], tri[9]); //3! Za2 Za3 1 1 Za6 Za7 1 1
-
- tritmp[4] = _mm256_unpacklo_ps(tri[1], tri[4]); //4! Xb0 Xb1 Yb0 Yb1 Xb4 Xb5 Yb4 Yb5
- tritmp[5] = _mm256_unpackhi_ps(tri[1], tri[4]); //5! Zb0 Zb1 1 1 Zb4 Zb5 1 1
-
- tritmp[6] = _mm256_unpacklo_ps(tri[7], tri[10]); //6! Xb2 Xb3 Yb2 Yb3 Xb6 Xb7 Yb6 Yb7
- tritmp[7] = _mm256_unpackhi_ps(tri[7], tri[10]); //7! Zb2 Zb3 1 1 Zb6 Zb7 1 1
-
- tritmp[8] = _mm256_unpacklo_ps(tri[2], tri[5]); //8! Xc0 Xc1 Yc0 Yc1 Xc4 Xc5 Yc4 Yc5
- tritmp[9] = _mm256_unpackhi_ps(tri[2], tri[5]); //9! Zc0 Zc1 1 1 Zc4 Zc5 1 1
-
- tritmp[10] = _mm256_unpacklo_ps(tri[8], tri[11]); //10! Xc2 Xc3 Yc2 Yc3 Xc6 Xc7 Yc6 Yc7
- tritmp[11] = _mm256_unpackhi_ps(tri[8], tri[11]); //11! Zc2 Zc3 1 1 Zc6 Zc7 1 1
-
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- triA[0] = _mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(tritmp[0]), _mm256_castps_pd(tritmp[2]))); // Xa0 Xa1 Xa2 Xa3 Xa4 Xa5 Xa6 Xa7
- triA[1] = _mm256_castpd_ps(_mm256_unpackhi_pd(_mm256_castps_pd(tritmp[0]), _mm256_castps_pd(tritmp[2]))); // Ya0 Ya1 Ya2 Ya3 Ya4 Ya5 Ya6 Ya7
- triA[2] = _mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(tritmp[1]), _mm256_castps_pd(tritmp[3]))); // Za0 Za1 Za2 Za3 Za4 Za5 Za6 Za7
-
- triB[0] = _mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(tritmp[4]), _mm256_castps_pd(tritmp[6]))); // Xb0 Xb1 Xb2 Xb3 Xb4 Xb5 Xb5 Xb7
- triB[1] = _mm256_castpd_ps(_mm256_unpackhi_pd(_mm256_castps_pd(tritmp[4]), _mm256_castps_pd(tritmp[6]))); // Yb0 Yb1 Yb2 Yb3 Yb4 Yb5 Yb5 Yb7
- triB[2] = _mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(tritmp[5]), _mm256_castps_pd(tritmp[7]))); // Zb0 Zb1 Zb2 Zb3 Zb4 Zb5 Zb5 Zb7
-
- triC[0] = _mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(tritmp[8]), _mm256_castps_pd(tritmp[10]))); //Xc0 Xc1 Xc2 Xc3 Xc4 Xc5 Xc6 Xc7
- triC[1] = _mm256_castpd_ps(_mm256_unpackhi_pd(_mm256_castps_pd(tritmp[8]), _mm256_castps_pd(tritmp[10]))); //Yc0 Yc1 Yc2 Yc3 Yc4 Yc5 Yc6 Yc7
- triC[2] = _mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(tritmp[9]), _mm256_castps_pd(tritmp[11]))); //Zc0 Zc1 Zc2 Zc3 Zc4 Zc5 Zc6 Zc7
-
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- int result = ray_triangle_intersect8(kg, P,
- dir,
- isect,
- visibility, object,
- triA,
- triB,
- triC,
- prim_addr,
- prim_num,
- num_hits,
- max_hits,
- num_hits_in_instance,
- isect_t);
- return result;
+ccl_device_inline int triangle_intersect8(KernelGlobals *kg,
+ Intersection **isect,
+ float3 P,
+ float3 dir,
+ uint visibility,
+ int object,
+ int prim_addr,
+ int prim_num,
+ uint *num_hits,
+ uint max_hits,
+ int *num_hits_in_instance,
+ float isect_t)
+{
+ __m128 tri_a[8], tri_b[8], tri_c[8];
+ __m256 tritmp[12], tri[12];
+ __m256 triA[3], triB[3], triC[3];
+
+ int i, r;
+
+ uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
+ for (i = 0; i < prim_num; i++) {
+ tri_a[i] = *(__m128 *)&kg->__prim_tri_verts.data[tri_vindex++];
+ tri_b[i] = *(__m128 *)&kg->__prim_tri_verts.data[tri_vindex++];
+ tri_c[i] = *(__m128 *)&kg->__prim_tri_verts.data[tri_vindex++];
+ }
+ //create 9 or 12 placeholders
+ tri[0] = _mm256_castps128_ps256(tri_a[0]); //_mm256_zextps128_ps256
+ tri[1] = _mm256_castps128_ps256(tri_b[0]); //_mm256_zextps128_ps256
+ tri[2] = _mm256_castps128_ps256(tri_c[0]); //_mm256_zextps128_ps256
+
+ tri[3] = _mm256_castps128_ps256(tri_a[1]); //_mm256_zextps128_ps256
+ tri[4] = _mm256_castps128_ps256(tri_b[1]); //_mm256_zextps128_ps256
+ tri[5] = _mm256_castps128_ps256(tri_c[1]); //_mm256_zextps128_ps256
+
+ tri[6] = _mm256_castps128_ps256(tri_a[2]); //_mm256_zextps128_ps256
+ tri[7] = _mm256_castps128_ps256(tri_b[2]); //_mm256_zextps128_ps256
+ tri[8] = _mm256_castps128_ps256(tri_c[2]); //_mm256_zextps128_ps256
+
+ if (prim_num > 3) {
+ tri[9] = _mm256_castps128_ps256(tri_a[3]); //_mm256_zextps128_ps256
+ tri[10] = _mm256_castps128_ps256(tri_b[3]); //_mm256_zextps128_ps256
+ tri[11] = _mm256_castps128_ps256(tri_c[3]); //_mm256_zextps128_ps256
+ }
+
+ for (i = 4, r = 0; i < prim_num; i++, r += 3) {
+ tri[r] = _mm256_insertf128_ps(tri[r], tri_a[i], 1);
+ tri[r + 1] = _mm256_insertf128_ps(tri[r + 1], tri_b[i], 1);
+ tri[r + 2] = _mm256_insertf128_ps(tri[r + 2], tri_c[i], 1);
+ }
+
+ //------------------------------------------------
+ //0! Xa0 Ya0 Za0 1 Xa4 Ya4 Za4 1
+ //1! Xb0 Yb0 Zb0 1 Xb4 Yb4 Zb4 1
+ //2! Xc0 Yc0 Zc0 1 Xc4 Yc4 Zc4 1
+
+ //3! Xa1 Ya1 Za1 1 Xa5 Ya5 Za5 1
+ //4! Xb1 Yb1 Zb1 1 Xb5 Yb5 Zb5 1
+ //5! Xc1 Yc1 Zc1 1 Xc5 Yc5 Zc5 1
+
+ //6! Xa2 Ya2 Za2 1 Xa6 Ya6 Za6 1
+ //7! Xb2 Yb2 Zb2 1 Xb6 Yb6 Zb6 1
+ //8! Xc2 Yc2 Zc2 1 Xc6 Yc6 Zc6 1
+
+ //9! Xa3 Ya3 Za3 1 Xa7 Ya7 Za7 1
+ //10! Xb3 Yb3 Zb3 1 Xb7 Yb7 Zb7 1
+ //11! Xc3 Yc3 Zc3 1 Xc7 Yc7 Zc7 1
+
+ //"transpose"
+ tritmp[0] = _mm256_unpacklo_ps(tri[0], tri[3]); //0! Xa0 Xa1 Ya0 Ya1 Xa4 Xa5 Ya4 Ya5
+ tritmp[1] = _mm256_unpackhi_ps(tri[0], tri[3]); //1! Za0 Za1 1 1 Za4 Za5 1 1
+
+ tritmp[2] = _mm256_unpacklo_ps(tri[6], tri[9]); //2! Xa2 Xa3 Ya2 Ya3 Xa6 Xa7 Ya6 Ya7
+ tritmp[3] = _mm256_unpackhi_ps(tri[6], tri[9]); //3! Za2 Za3 1 1 Za6 Za7 1 1
+
+ tritmp[4] = _mm256_unpacklo_ps(tri[1], tri[4]); //4! Xb0 Xb1 Yb0 Yb1 Xb4 Xb5 Yb4 Yb5
+ tritmp[5] = _mm256_unpackhi_ps(tri[1], tri[4]); //5! Zb0 Zb1 1 1 Zb4 Zb5 1 1
+
+ tritmp[6] = _mm256_unpacklo_ps(tri[7], tri[10]); //6! Xb2 Xb3 Yb2 Yb3 Xb6 Xb7 Yb6 Yb7
+ tritmp[7] = _mm256_unpackhi_ps(tri[7], tri[10]); //7! Zb2 Zb3 1 1 Zb6 Zb7 1 1
+
+ tritmp[8] = _mm256_unpacklo_ps(tri[2], tri[5]); //8! Xc0 Xc1 Yc0 Yc1 Xc4 Xc5 Yc4 Yc5
+ tritmp[9] = _mm256_unpackhi_ps(tri[2], tri[5]); //9! Zc0 Zc1 1 1 Zc4 Zc5 1 1
+
+ tritmp[10] = _mm256_unpacklo_ps(tri[8], tri[11]); //10! Xc2 Xc3 Yc2 Yc3 Xc6 Xc7 Yc6 Yc7
+ tritmp[11] = _mm256_unpackhi_ps(tri[8], tri[11]); //11! Zc2 Zc3 1 1 Zc6 Zc7 1 1
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+ triA[0] = _mm256_castpd_ps(
+ _mm256_unpacklo_pd(_mm256_castps_pd(tritmp[0]),
+ _mm256_castps_pd(tritmp[2]))); // Xa0 Xa1 Xa2 Xa3 Xa4 Xa5 Xa6 Xa7
+ triA[1] = _mm256_castpd_ps(
+ _mm256_unpackhi_pd(_mm256_castps_pd(tritmp[0]),
+ _mm256_castps_pd(tritmp[2]))); // Ya0 Ya1 Ya2 Ya3 Ya4 Ya5 Ya6 Ya7
+ triA[2] = _mm256_castpd_ps(
+ _mm256_unpacklo_pd(_mm256_castps_pd(tritmp[1]),
+ _mm256_castps_pd(tritmp[3]))); // Za0 Za1 Za2 Za3 Za4 Za5 Za6 Za7
+
+ triB[0] = _mm256_castpd_ps(
+ _mm256_unpacklo_pd(_mm256_castps_pd(tritmp[4]),
+ _mm256_castps_pd(tritmp[6]))); // Xb0 Xb1 Xb2 Xb3 Xb4 Xb5 Xb5 Xb7
+ triB[1] = _mm256_castpd_ps(
+ _mm256_unpackhi_pd(_mm256_castps_pd(tritmp[4]),
+ _mm256_castps_pd(tritmp[6]))); // Yb0 Yb1 Yb2 Yb3 Yb4 Yb5 Yb5 Yb7
+ triB[2] = _mm256_castpd_ps(
+ _mm256_unpacklo_pd(_mm256_castps_pd(tritmp[5]),
+ _mm256_castps_pd(tritmp[7]))); // Zb0 Zb1 Zb2 Zb3 Zb4 Zb5 Zb5 Zb7
+
+ triC[0] = _mm256_castpd_ps(
+ _mm256_unpacklo_pd(_mm256_castps_pd(tritmp[8]),
+ _mm256_castps_pd(tritmp[10]))); //Xc0 Xc1 Xc2 Xc3 Xc4 Xc5 Xc6 Xc7
+ triC[1] = _mm256_castpd_ps(
+ _mm256_unpackhi_pd(_mm256_castps_pd(tritmp[8]),
+ _mm256_castps_pd(tritmp[10]))); //Yc0 Yc1 Yc2 Yc3 Yc4 Yc5 Yc6 Yc7
+ triC[2] = _mm256_castpd_ps(
+ _mm256_unpacklo_pd(_mm256_castps_pd(tritmp[9]),
+ _mm256_castps_pd(tritmp[11]))); //Zc0 Zc1 Zc2 Zc3 Zc4 Zc5 Zc6 Zc7
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+ int result = ray_triangle_intersect8(kg,
+ P,
+ dir,
+ isect,
+ visibility,
+ object,
+ triA,
+ triB,
+ triC,
+ prim_addr,
+ prim_num,
+ num_hits,
+ max_hits,
+ num_hits_in_instance,
+ isect_t);
+ return result;
}
-#endif /* __KERNEL_AVX2__ */
+#endif /* __KERNEL_AVX2__ */
/* Special ray intersection routines for subsurface scattering. In that case we
* only want to intersect with primitives in the same object, and if case of
@@ -479,106 +496,108 @@ ccl_device_inline int triangle_intersect8(
*/
#ifdef __BVH_LOCAL__
-ccl_device_inline bool triangle_intersect_local(
- KernelGlobals *kg,
- LocalIntersection *local_isect,
- float3 P,
- float3 dir,
- int object,
- int local_object,
- int prim_addr,
- float tmax,
- uint *lcg_state,
- int max_hits)
+ccl_device_inline bool triangle_intersect_local(KernelGlobals *kg,
+ LocalIntersection *local_isect,
+ float3 P,
+ float3 dir,
+ int object,
+ int local_object,
+ int prim_addr,
+ float tmax,
+ uint *lcg_state,
+ int max_hits)
{
- /* Only intersect with matching object, for instanced objects we
- * already know we are only intersecting the right object. */
- if(object == OBJECT_NONE) {
- if(kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
- return false;
- }
- }
-
- const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- const ssef *ssef_verts = (ssef*)&kg->__prim_tri_verts.data[tri_vindex];
-#else
- const float3 tri_a = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+0)),
- tri_b = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+1)),
- tri_c = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+2));
-#endif
- float t, u, v;
- if(!ray_triangle_intersect(P,
- dir,
- tmax,
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- ssef_verts,
-#else
- tri_a, tri_b, tri_c,
-#endif
- &u, &v, &t))
- {
- return false;
- }
-
- /* If no actual hit information is requested, just return here. */
- if(max_hits == 0) {
- return true;
- }
-
- int hit;
- if(lcg_state) {
- /* Record up to max_hits intersections. */
- for(int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
- if(local_isect->hits[i].t == t) {
- return false;
- }
- }
-
- local_isect->num_hits++;
-
- if(local_isect->num_hits <= max_hits) {
- hit = local_isect->num_hits - 1;
- }
- else {
- /* reservoir sampling: if we are at the maximum number of
- * hits, randomly replace element or skip it */
- hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
-
- if(hit >= max_hits)
- return false;
- }
- }
- else {
- /* Record closest intersection only. */
- if(local_isect->num_hits && t > local_isect->hits[0].t) {
- return false;
- }
-
- hit = 0;
- local_isect->num_hits = 1;
- }
-
- /* Record intersection. */
- Intersection *isect = &local_isect->hits[hit];
- isect->prim = prim_addr;
- isect->object = object;
- isect->type = PRIMITIVE_TRIANGLE;
- isect->u = u;
- isect->v = v;
- isect->t = t;
-
- /* Record geometric normal. */
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- const float3 tri_a = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+0)),
- tri_b = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+1)),
- tri_c = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+2));
-#endif
- local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
+ /* Only intersect with matching object, for instanced objects we
+ * already know we are only intersecting the right object. */
+ if (object == OBJECT_NONE) {
+ if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+ return false;
+ }
+ }
+
+ const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
+# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
+ const ssef *ssef_verts = (ssef *)&kg->__prim_tri_verts.data[tri_vindex];
+# else
+ const float3 tri_a = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex + 0)),
+ tri_b = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex + 1)),
+ tri_c = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex + 2));
+# endif
+ float t, u, v;
+ if (!ray_triangle_intersect(P,
+ dir,
+ tmax,
+# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
+ ssef_verts,
+# else
+ tri_a,
+ tri_b,
+ tri_c,
+# endif
+ &u,
+ &v,
+ &t)) {
+ return false;
+ }
+
+ /* If no actual hit information is requested, just return here. */
+ if (max_hits == 0) {
+ return true;
+ }
+
+ int hit;
+ if (lcg_state) {
+ /* Record up to max_hits intersections. */
+ for (int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
+ if (local_isect->hits[i].t == t) {
+ return false;
+ }
+ }
+
+ local_isect->num_hits++;
+
+ if (local_isect->num_hits <= max_hits) {
+ hit = local_isect->num_hits - 1;
+ }
+ else {
+ /* reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it */
+ hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
+
+ if (hit >= max_hits)
+ return false;
+ }
+ }
+ else {
+ /* Record closest intersection only. */
+ if (local_isect->num_hits && t > local_isect->hits[0].t) {
+ return false;
+ }
+
+ hit = 0;
+ local_isect->num_hits = 1;
+ }
+
+ /* Record intersection. */
+ Intersection *isect = &local_isect->hits[hit];
+ isect->prim = prim_addr;
+ isect->object = object;
+ isect->type = PRIMITIVE_TRIANGLE;
+ isect->u = u;
+ isect->v = v;
+ isect->t = t;
+
+ /* Record geometric normal. */
+# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
+ const float3 tri_a = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex + 0)),
+ tri_b = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex + 1)),
+ tri_c = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex + 2));
+# endif
+ local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
- return false;
+ return false;
}
-#endif /* __BVH_LOCAL__ */
+#endif /* __BVH_LOCAL__ */
/* Refine triangle intersection to more precise hit point. For rays that travel
* far the precision is often not so good, this reintersects the primitive from
@@ -596,61 +615,61 @@ ccl_device_inline float3 triangle_refine(KernelGlobals *kg,
const Intersection *isect,
const Ray *ray)
{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
#ifdef __INTERSECTION_REFINE__
- if(isect->object != OBJECT_NONE) {
- if(UNLIKELY(t == 0.0f)) {
- return P;
- }
+ if (isect->object != OBJECT_NONE) {
+ if (UNLIKELY(t == 0.0f)) {
+ return P;
+ }
# ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
+ Transform tfm = sd->ob_itfm;
# else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
# endif
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
-
- P = P + D*t;
-
- const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim);
- const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0),
- tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1),
- tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2);
- float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
- float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
- float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
- float3 qvec = cross(tvec, edge1);
- float3 pvec = cross(D, edge2);
- float det = dot(edge1, pvec);
- if(det != 0.0f) {
- /* If determinant is zero it means ray lies in the plane of
- * the triangle. It is possible in theory due to watertight
- * nature of triangle intersection. For such cases we simply
- * don't refine intersection hoping it'll go all fine.
- */
- float rt = dot(edge2, qvec) / det;
- P = P + D*rt;
- }
-
- if(isect->object != OBJECT_NONE) {
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D * t);
+ D = normalize_len(D, &t);
+ }
+
+ P = P + D * t;
+
+ const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim);
+ const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 0),
+ tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 1),
+ tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 2);
+ float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
+ float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
+ float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
+ float3 qvec = cross(tvec, edge1);
+ float3 pvec = cross(D, edge2);
+ float det = dot(edge1, pvec);
+ if (det != 0.0f) {
+ /* If determinant is zero it means ray lies in the plane of
+ * the triangle. It is possible in theory due to watertight
+ * nature of triangle intersection. For such cases we simply
+ * don't refine intersection hoping it'll go all fine.
+ */
+ float rt = dot(edge2, qvec) / det;
+ P = P + D * rt;
+ }
+
+ if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
+ Transform tfm = sd->ob_tfm;
# else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
# endif
- P = transform_point(&tfm, P);
- }
+ P = transform_point(&tfm, P);
+ }
- return P;
+ return P;
#else
- return P + D*t;
+ return P + D * t;
#endif
}
@@ -662,61 +681,57 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
const Intersection *isect,
const Ray *ray)
{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
- if(isect->object != OBJECT_NONE) {
+ if (isect->object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
+ Transform tfm = sd->ob_itfm;
#else
- Transform tfm = object_fetch_transform(kg,
- isect->object,
- OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
#endif
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D);
- D = normalize(D);
- }
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D);
+ D = normalize(D);
+ }
- P = P + D*t;
+ P = P + D * t;
#ifdef __INTERSECTION_REFINE__
- const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim);
- const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0),
- tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1),
- tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2);
- float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
- float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
- float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
- float3 qvec = cross(tvec, edge1);
- float3 pvec = cross(D, edge2);
- float det = dot(edge1, pvec);
- if(det != 0.0f) {
- /* If determinant is zero it means ray lies in the plane of
- * the triangle. It is possible in theory due to watertight
- * nature of triangle intersection. For such cases we simply
- * don't refine intersection hoping it'll go all fine.
- */
- float rt = dot(edge2, qvec) / det;
- P = P + D*rt;
- }
-#endif /* __INTERSECTION_REFINE__ */
-
- if(isect->object != OBJECT_NONE) {
+ const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim);
+ const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 0),
+ tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 1),
+ tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 2);
+ float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
+ float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
+ float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
+ float3 qvec = cross(tvec, edge1);
+ float3 pvec = cross(D, edge2);
+ float det = dot(edge1, pvec);
+ if (det != 0.0f) {
+ /* If determinant is zero it means ray lies in the plane of
+ * the triangle. It is possible in theory due to watertight
+ * nature of triangle intersection. For such cases we simply
+ * don't refine intersection hoping it'll go all fine.
+ */
+ float rt = dot(edge2, qvec) / det;
+ P = P + D * rt;
+ }
+#endif /* __INTERSECTION_REFINE__ */
+
+ if (isect->object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
+ Transform tfm = sd->ob_tfm;
#else
- Transform tfm = object_fetch_transform(kg,
- isect->object,
- OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
#endif
- P = transform_point(&tfm, P);
- }
+ P = transform_point(&tfm, P);
+ }
- return P;
+ return P;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
index 1977d263ece..96cf35a40dc 100644
--- a/intern/cycles/kernel/geom/geom_volume.h
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -33,41 +33,47 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals *kg,
const ShaderData *sd,
float3 P)
{
- /* todo: optimize this so it's just a single matrix multiplication when
- * possible (not motion blur), or perhaps even just translation + scale */
- const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM);
+ /* todo: optimize this so it's just a single matrix multiplication when
+ * possible (not motion blur), or perhaps even just translation + scale */
+ const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM);
- object_inverse_position_transform(kg, sd, &P);
+ object_inverse_position_transform(kg, sd, &P);
- if(desc.offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, desc);
- P = transform_point(&tfm, P);
- }
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ Transform tfm = primitive_attribute_matrix(kg, sd, desc);
+ P = transform_point(&tfm, P);
+ }
- return P;
+ return P;
}
-ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc)
+ccl_device float volume_attribute_float(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc)
{
- float3 P = volume_normalized_position(kg, sd, sd->P);
- InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC)? INTERPOLATION_CUBIC: INTERPOLATION_NONE;
- float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
- return average(float4_to_float3(r));
+ float3 P = volume_normalized_position(kg, sd, sd->P);
+ InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
+ INTERPOLATION_NONE;
+ float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
+ return average(float4_to_float3(r));
}
-ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc)
+ccl_device float3 volume_attribute_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc)
{
- float3 P = volume_normalized_position(kg, sd, sd->P);
- InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC)? INTERPOLATION_CUBIC: INTERPOLATION_NONE;
- float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
+ float3 P = volume_normalized_position(kg, sd, sd->P);
+ InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
+ INTERPOLATION_NONE;
+ float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
- if(r.w > 1e-6f && r.w != 1.0f) {
- /* For RGBA colors, unpremultiply after interpolation. */
- return float4_to_float3(r) / r.w;
- }
- else {
- return float4_to_float3(r);
- }
+ if (r.w > 1e-6f && r.w != 1.0f) {
+ /* For RGBA colors, unpremultiply after interpolation. */
+ return float4_to_float3(r) / r.w;
+ }
+ else {
+ return float4_to_float3(r);
+ }
}
#endif
diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h
index 1c8c91d15e6..dfdd8843f29 100644
--- a/intern/cycles/kernel/kernel.h
+++ b/intern/cycles/kernel/kernel.h
@@ -24,8 +24,8 @@
CCL_NAMESPACE_BEGIN
-#define KERNEL_NAME_JOIN(x, y, z) x ## _ ## y ## _ ## z
-#define KERNEL_NAME_EVAL(arch, name) KERNEL_NAME_JOIN(kernel, arch, name)
+#define KERNEL_NAME_JOIN(x, y, z) x##_##y##_##z
+#define KERNEL_NAME_EVAL(arch, name) KERNEL_NAME_JOIN(kernel, arch, name)
#define KERNEL_FUNCTION_FULL_NAME(name) KERNEL_NAME_EVAL(KERNEL_ARCH, name)
struct KernelGlobals;
@@ -38,10 +38,7 @@ void *kernel_osl_memory(KernelGlobals *kg);
bool kernel_osl_use(KernelGlobals *kg);
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size);
-void kernel_tex_copy(KernelGlobals *kg,
- const char *name,
- void *mem,
- size_t size);
+void kernel_tex_copy(KernelGlobals *kg, const char *name, void *mem, size_t size);
#define KERNEL_ARCH cpu
#include "kernel/kernels/cpu/kernel_cpu.h"
@@ -63,4 +60,4 @@ void kernel_tex_copy(KernelGlobals *kg,
CCL_NAMESPACE_END
-#endif /* __KERNEL_H__ */
+#endif /* __KERNEL_H__ */
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 86ad6e1a061..b9d723222a1 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -21,149 +21,150 @@ CCL_NAMESPACE_BEGIN
* BSDF evaluation result, split per BSDF type. This is used to accumulate
* render passes separately. */
-ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg,
- const ShaderData *sd);
+ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, const ShaderData *sd);
-ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass)
+ccl_device_inline void bsdf_eval_init(BsdfEval *eval,
+ ClosureType type,
+ float3 value,
+ int use_light_pass)
{
#ifdef __PASSES__
- eval->use_light_pass = use_light_pass;
-
- if(eval->use_light_pass) {
- eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
- eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
- eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
- eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
- eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
- eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
-
- if(type == CLOSURE_BSDF_TRANSPARENT_ID)
- eval->transparent = value;
- else if(CLOSURE_IS_BSDF_DIFFUSE(type))
- eval->diffuse = value;
- else if(CLOSURE_IS_BSDF_GLOSSY(type))
- eval->glossy = value;
- else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
- eval->transmission = value;
- else if(CLOSURE_IS_BSDF_BSSRDF(type))
- eval->subsurface = value;
- else if(CLOSURE_IS_PHASE(type))
- eval->scatter = value;
- }
- else
-#endif
- {
- eval->diffuse = value;
- }
+ eval->use_light_pass = use_light_pass;
+
+ if (eval->use_light_pass) {
+ eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
+ eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
+ eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
+ eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
+
+ if (type == CLOSURE_BSDF_TRANSPARENT_ID)
+ eval->transparent = value;
+ else if (CLOSURE_IS_BSDF_DIFFUSE(type))
+ eval->diffuse = value;
+ else if (CLOSURE_IS_BSDF_GLOSSY(type))
+ eval->glossy = value;
+ else if (CLOSURE_IS_BSDF_TRANSMISSION(type))
+ eval->transmission = value;
+ else if (CLOSURE_IS_BSDF_BSSRDF(type))
+ eval->subsurface = value;
+ else if (CLOSURE_IS_PHASE(type))
+ eval->scatter = value;
+ }
+ else
+#endif
+ {
+ eval->diffuse = value;
+ }
#ifdef __SHADOW_TRICKS__
- eval->sum_no_mis = make_float3(0.0f, 0.0f, 0.0f);
+ eval->sum_no_mis = make_float3(0.0f, 0.0f, 0.0f);
#endif
}
-ccl_device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value, float mis_weight)
+ccl_device_inline void bsdf_eval_accum(BsdfEval *eval,
+ ClosureType type,
+ float3 value,
+ float mis_weight)
{
#ifdef __SHADOW_TRICKS__
- eval->sum_no_mis += value;
+ eval->sum_no_mis += value;
#endif
- value *= mis_weight;
+ value *= mis_weight;
#ifdef __PASSES__
- if(eval->use_light_pass) {
- if(CLOSURE_IS_BSDF_DIFFUSE(type))
- eval->diffuse += value;
- else if(CLOSURE_IS_BSDF_GLOSSY(type))
- eval->glossy += value;
- else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
- eval->transmission += value;
- else if(CLOSURE_IS_BSDF_BSSRDF(type))
- eval->subsurface += value;
- else if(CLOSURE_IS_PHASE(type))
- eval->scatter += value;
-
- /* skipping transparent, this function is used by for eval(), will be zero then */
- }
- else
-#endif
- {
- eval->diffuse += value;
- }
+ if (eval->use_light_pass) {
+ if (CLOSURE_IS_BSDF_DIFFUSE(type))
+ eval->diffuse += value;
+ else if (CLOSURE_IS_BSDF_GLOSSY(type))
+ eval->glossy += value;
+ else if (CLOSURE_IS_BSDF_TRANSMISSION(type))
+ eval->transmission += value;
+ else if (CLOSURE_IS_BSDF_BSSRDF(type))
+ eval->subsurface += value;
+ else if (CLOSURE_IS_PHASE(type))
+ eval->scatter += value;
+
+ /* skipping transparent, this function is used by for eval(), will be zero then */
+ }
+ else
+#endif
+ {
+ eval->diffuse += value;
+ }
}
ccl_device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
{
#ifdef __PASSES__
- if(eval->use_light_pass) {
- return is_zero(eval->diffuse)
- && is_zero(eval->glossy)
- && is_zero(eval->transmission)
- && is_zero(eval->transparent)
- && is_zero(eval->subsurface)
- && is_zero(eval->scatter);
- }
- else
-#endif
- {
- return is_zero(eval->diffuse);
- }
+ if (eval->use_light_pass) {
+ return is_zero(eval->diffuse) && is_zero(eval->glossy) && is_zero(eval->transmission) &&
+ is_zero(eval->transparent) && is_zero(eval->subsurface) && is_zero(eval->scatter);
+ }
+ else
+#endif
+ {
+ return is_zero(eval->diffuse);
+ }
}
ccl_device_inline void bsdf_eval_mis(BsdfEval *eval, float value)
{
#ifdef __PASSES__
- if(eval->use_light_pass) {
- eval->diffuse *= value;
- eval->glossy *= value;
- eval->transmission *= value;
- eval->subsurface *= value;
- eval->scatter *= value;
-
- /* skipping transparent, this function is used by for eval(), will be zero then */
- }
- else
-#endif
- {
- eval->diffuse *= value;
- }
+ if (eval->use_light_pass) {
+ eval->diffuse *= value;
+ eval->glossy *= value;
+ eval->transmission *= value;
+ eval->subsurface *= value;
+ eval->scatter *= value;
+
+ /* skipping transparent, this function is used by for eval(), will be zero then */
+ }
+ else
+#endif
+ {
+ eval->diffuse *= value;
+ }
}
ccl_device_inline void bsdf_eval_mul(BsdfEval *eval, float value)
{
#ifdef __SHADOW_TRICKS__
- eval->sum_no_mis *= value;
+ eval->sum_no_mis *= value;
#endif
- bsdf_eval_mis(eval, value);
+ bsdf_eval_mis(eval, value);
}
ccl_device_inline void bsdf_eval_mul3(BsdfEval *eval, float3 value)
{
#ifdef __SHADOW_TRICKS__
- eval->sum_no_mis *= value;
+ eval->sum_no_mis *= value;
#endif
#ifdef __PASSES__
- if(eval->use_light_pass) {
- eval->diffuse *= value;
- eval->glossy *= value;
- eval->transmission *= value;
- eval->subsurface *= value;
- eval->scatter *= value;
-
- /* skipping transparent, this function is used by for eval(), will be zero then */
- }
- else
- eval->diffuse *= value;
+ if (eval->use_light_pass) {
+ eval->diffuse *= value;
+ eval->glossy *= value;
+ eval->transmission *= value;
+ eval->subsurface *= value;
+ eval->scatter *= value;
+
+ /* skipping transparent, this function is used by for eval(), will be zero then */
+ }
+ else
+ eval->diffuse *= value;
#else
- eval->diffuse *= value;
+ eval->diffuse *= value;
#endif
}
ccl_device_inline float3 bsdf_eval_sum(const BsdfEval *eval)
{
#ifdef __PASSES__
- if(eval->use_light_pass) {
- return eval->diffuse + eval->glossy + eval->transmission + eval->subsurface + eval->scatter;
- }
- else
+ if (eval->use_light_pass) {
+ return eval->diffuse + eval->glossy + eval->transmission + eval->subsurface + eval->scatter;
+ }
+ else
#endif
- return eval->diffuse;
+ return eval->diffuse;
}
/* Path Radiance
@@ -175,115 +176,113 @@ ccl_device_inline float3 bsdf_eval_sum(const BsdfEval *eval)
ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
{
- /* clear all */
+ /* clear all */
#ifdef __PASSES__
- L->use_light_pass = use_light_pass;
-
- if(use_light_pass) {
- L->indirect = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
-
- L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
- L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
- L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
-
- L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
-
- L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
-
- L->transparent = 0.0f;
- L->emission = make_float3(0.0f, 0.0f, 0.0f);
- L->background = make_float3(0.0f, 0.0f, 0.0f);
- L->ao = make_float3(0.0f, 0.0f, 0.0f);
- L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- L->mist = 0.0f;
-
- L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
- L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
- L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
- L->state.direct = make_float3(0.0f, 0.0f, 0.0f);
- }
- else
-#endif
- {
- L->transparent = 0.0f;
- L->emission = make_float3(0.0f, 0.0f, 0.0f);
- }
+ L->use_light_pass = use_light_pass;
+
+ if (use_light_pass) {
+ L->indirect = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->transparent = 0.0f;
+ L->emission = make_float3(0.0f, 0.0f, 0.0f);
+ L->background = make_float3(0.0f, 0.0f, 0.0f);
+ L->ao = make_float3(0.0f, 0.0f, 0.0f);
+ L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ L->mist = 0.0f;
+
+ L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.direct = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ else
+#endif
+ {
+ L->transparent = 0.0f;
+ L->emission = make_float3(0.0f, 0.0f, 0.0f);
+ }
#ifdef __SHADOW_TRICKS__
- L->path_total = make_float3(0.0f, 0.0f, 0.0f);
- L->path_total_shaded = make_float3(0.0f, 0.0f, 0.0f);
- L->shadow_background_color = make_float3(0.0f, 0.0f, 0.0f);
- L->shadow_throughput = 0.0f;
- L->shadow_transparency = 1.0f;
- L->has_shadow_catcher = 0;
+ L->path_total = make_float3(0.0f, 0.0f, 0.0f);
+ L->path_total_shaded = make_float3(0.0f, 0.0f, 0.0f);
+ L->shadow_background_color = make_float3(0.0f, 0.0f, 0.0f);
+ L->shadow_throughput = 0.0f;
+ L->shadow_transparency = 1.0f;
+ L->has_shadow_catcher = 0;
#endif
#ifdef __DENOISING_FEATURES__
- L->denoising_normal = make_float3(0.0f, 0.0f, 0.0f);
- L->denoising_albedo = make_float3(0.0f, 0.0f, 0.0f);
- L->denoising_depth = 0.0f;
+ L->denoising_normal = make_float3(0.0f, 0.0f, 0.0f);
+ L->denoising_albedo = make_float3(0.0f, 0.0f, 0.0f);
+ L->denoising_depth = 0.0f;
#endif
#ifdef __KERNEL_DEBUG__
- L->debug_data.num_bvh_traversed_nodes = 0;
- L->debug_data.num_bvh_traversed_instances = 0;
- L->debug_data.num_bvh_intersections = 0;
- L->debug_data.num_ray_bounces = 0;
+ L->debug_data.num_bvh_traversed_nodes = 0;
+ L->debug_data.num_bvh_traversed_instances = 0;
+ L->debug_data.num_bvh_intersections = 0;
+ L->debug_data.num_ray_bounces = 0;
#endif
}
-ccl_device_inline void path_radiance_bsdf_bounce(
- KernelGlobals *kg,
- PathRadianceState *L_state,
- ccl_addr_space float3 *throughput,
- BsdfEval *bsdf_eval,
- float bsdf_pdf, int bounce, int bsdf_label)
+ccl_device_inline void path_radiance_bsdf_bounce(KernelGlobals *kg,
+ PathRadianceState *L_state,
+ ccl_addr_space float3 *throughput,
+ BsdfEval *bsdf_eval,
+ float bsdf_pdf,
+ int bounce,
+ int bsdf_label)
{
- float inverse_pdf = 1.0f/bsdf_pdf;
+ float inverse_pdf = 1.0f / bsdf_pdf;
#ifdef __PASSES__
- if(kernel_data.film.use_light_pass) {
- if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
- /* first on directly visible surface */
- float3 value = *throughput*inverse_pdf;
-
- L_state->diffuse = bsdf_eval->diffuse*value;
- L_state->glossy = bsdf_eval->glossy*value;
- L_state->transmission = bsdf_eval->transmission*value;
- L_state->subsurface = bsdf_eval->subsurface*value;
- L_state->scatter = bsdf_eval->scatter*value;
-
- *throughput = L_state->diffuse +
- L_state->glossy +
- L_state->transmission +
- L_state->subsurface +
- L_state->scatter;
-
- L_state->direct = *throughput;
- }
- else {
- /* transparent bounce before first hit, or indirectly visible through BSDF */
- float3 sum = (bsdf_eval_sum(bsdf_eval) + bsdf_eval->transparent) * inverse_pdf;
- *throughput *= sum;
- }
- }
- else
-#endif
- {
- *throughput *= bsdf_eval->diffuse*inverse_pdf;
- }
+ if (kernel_data.film.use_light_pass) {
+ if (bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
+ /* first on directly visible surface */
+ float3 value = *throughput * inverse_pdf;
+
+ L_state->diffuse = bsdf_eval->diffuse * value;
+ L_state->glossy = bsdf_eval->glossy * value;
+ L_state->transmission = bsdf_eval->transmission * value;
+ L_state->subsurface = bsdf_eval->subsurface * value;
+ L_state->scatter = bsdf_eval->scatter * value;
+
+ *throughput = L_state->diffuse + L_state->glossy + L_state->transmission +
+ L_state->subsurface + L_state->scatter;
+
+ L_state->direct = *throughput;
+ }
+ else {
+ /* transparent bounce before first hit, or indirectly visible through BSDF */
+ float3 sum = (bsdf_eval_sum(bsdf_eval) + bsdf_eval->transparent) * inverse_pdf;
+ *throughput *= sum;
+ }
+ }
+ else
+#endif
+ {
+ *throughput *= bsdf_eval->diffuse * inverse_pdf;
+ }
}
ccl_device_inline void path_radiance_accum_emission(PathRadiance *L,
@@ -292,25 +291,25 @@ ccl_device_inline void path_radiance_accum_emission(PathRadiance *L,
float3 value)
{
#ifdef __SHADOW_TRICKS__
- if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- return;
- }
+ if (state->flag & PATH_RAY_SHADOW_CATCHER) {
+ return;
+ }
#endif
#ifdef __PASSES__
- if(L->use_light_pass) {
- if(state->bounce == 0)
- L->emission += throughput*value;
- else if(state->bounce == 1)
- L->direct_emission += throughput*value;
- else
- L->indirect += throughput*value;
- }
- else
-#endif
- {
- L->emission += throughput*value;
- }
+ if (L->use_light_pass) {
+ if (state->bounce == 0)
+ L->emission += throughput * value;
+ else if (state->bounce == 1)
+ L->direct_emission += throughput * value;
+ else
+ L->indirect += throughput * value;
+ }
+ else
+#endif
+ {
+ L->emission += throughput * value;
+ }
}
ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
@@ -320,57 +319,56 @@ ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
float3 bsdf,
float3 ao)
{
- /* Store AO pass. */
- if(L->use_light_pass && state->bounce == 0) {
- L->ao += alpha*throughput*ao;
- }
+ /* Store AO pass. */
+ if (L->use_light_pass && state->bounce == 0) {
+ L->ao += alpha * throughput * ao;
+ }
#ifdef __SHADOW_TRICKS__
- /* For shadow catcher, accumulate ratio. */
- if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
- float3 light = throughput * bsdf;
- L->path_total += light;
- L->path_total_shaded += ao * light;
+ /* For shadow catcher, accumulate ratio. */
+ if (state->flag & PATH_RAY_STORE_SHADOW_INFO) {
+ float3 light = throughput * bsdf;
+ L->path_total += light;
+ L->path_total_shaded += ao * light;
- if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- return;
- }
- }
+ if (state->flag & PATH_RAY_SHADOW_CATCHER) {
+ return;
+ }
+ }
#endif
#ifdef __PASSES__
- if(L->use_light_pass) {
- if(state->bounce == 0) {
- /* Directly visible lighting. */
- L->direct_diffuse += throughput*bsdf*ao;
- }
- else {
- /* Indirectly visible lighting after BSDF bounce. */
- L->indirect += throughput*bsdf*ao;
- }
- }
- else
-#endif
- {
- L->emission += throughput*bsdf*ao;
- }
+ if (L->use_light_pass) {
+ if (state->bounce == 0) {
+ /* Directly visible lighting. */
+ L->direct_diffuse += throughput * bsdf * ao;
+ }
+ else {
+ /* Indirectly visible lighting after BSDF bounce. */
+ L->indirect += throughput * bsdf * ao;
+ }
+ }
+ else
+#endif
+ {
+ L->emission += throughput * bsdf * ao;
+ }
}
-ccl_device_inline void path_radiance_accum_total_ao(
- PathRadiance *L,
- ccl_addr_space PathState *state,
- float3 throughput,
- float3 bsdf)
+ccl_device_inline void path_radiance_accum_total_ao(PathRadiance *L,
+ ccl_addr_space PathState *state,
+ float3 throughput,
+ float3 bsdf)
{
#ifdef __SHADOW_TRICKS__
- if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
- L->path_total += throughput * bsdf;
- }
+ if (state->flag & PATH_RAY_STORE_SHADOW_INFO) {
+ L->path_total += throughput * bsdf;
+ }
#else
- (void) L;
- (void) state;
- (void) throughput;
- (void) bsdf;
+ (void)L;
+ (void)state;
+ (void)throughput;
+ (void)bsdf;
#endif
}
@@ -383,171 +381,166 @@ ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
bool is_lamp)
{
#ifdef __SHADOW_TRICKS__
- if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
- float3 light = throughput * bsdf_eval->sum_no_mis;
- L->path_total += light;
- L->path_total_shaded += shadow * light;
+ if (state->flag & PATH_RAY_STORE_SHADOW_INFO) {
+ float3 light = throughput * bsdf_eval->sum_no_mis;
+ L->path_total += light;
+ L->path_total_shaded += shadow * light;
- if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- return;
- }
- }
+ if (state->flag & PATH_RAY_SHADOW_CATCHER) {
+ return;
+ }
+ }
#endif
#ifdef __PASSES__
- if(L->use_light_pass) {
- if(state->bounce == 0) {
- /* directly visible lighting */
- L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
- L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
- L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
- L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
- L->direct_scatter += throughput*bsdf_eval->scatter*shadow;
-
- if(is_lamp) {
- L->shadow.x += shadow.x*shadow_fac;
- L->shadow.y += shadow.y*shadow_fac;
- L->shadow.z += shadow.z*shadow_fac;
- }
- }
- else {
- /* indirectly visible lighting after BSDF bounce */
- L->indirect += throughput*bsdf_eval_sum(bsdf_eval)*shadow;
- }
- }
- else
-#endif
- {
- L->emission += throughput*bsdf_eval->diffuse*shadow;
- }
+ if (L->use_light_pass) {
+ if (state->bounce == 0) {
+ /* directly visible lighting */
+ L->direct_diffuse += throughput * bsdf_eval->diffuse * shadow;
+ L->direct_glossy += throughput * bsdf_eval->glossy * shadow;
+ L->direct_transmission += throughput * bsdf_eval->transmission * shadow;
+ L->direct_subsurface += throughput * bsdf_eval->subsurface * shadow;
+ L->direct_scatter += throughput * bsdf_eval->scatter * shadow;
+
+ if (is_lamp) {
+ L->shadow.x += shadow.x * shadow_fac;
+ L->shadow.y += shadow.y * shadow_fac;
+ L->shadow.z += shadow.z * shadow_fac;
+ }
+ }
+ else {
+ /* indirectly visible lighting after BSDF bounce */
+ L->indirect += throughput * bsdf_eval_sum(bsdf_eval) * shadow;
+ }
+ }
+ else
+#endif
+ {
+ L->emission += throughput * bsdf_eval->diffuse * shadow;
+ }
}
-ccl_device_inline void path_radiance_accum_total_light(
- PathRadiance *L,
- ccl_addr_space PathState *state,
- float3 throughput,
- const BsdfEval *bsdf_eval)
+ccl_device_inline void path_radiance_accum_total_light(PathRadiance *L,
+ ccl_addr_space PathState *state,
+ float3 throughput,
+ const BsdfEval *bsdf_eval)
{
#ifdef __SHADOW_TRICKS__
- if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
- L->path_total += throughput * bsdf_eval->sum_no_mis;
- }
+ if (state->flag & PATH_RAY_STORE_SHADOW_INFO) {
+ L->path_total += throughput * bsdf_eval->sum_no_mis;
+ }
#else
- (void) L;
- (void) state;
- (void) throughput;
- (void) bsdf_eval;
+ (void)L;
+ (void)state;
+ (void)throughput;
+ (void)bsdf_eval;
#endif
}
-ccl_device_inline void path_radiance_accum_background(
- PathRadiance *L,
- ccl_addr_space PathState *state,
- float3 throughput,
- float3 value)
+ccl_device_inline void path_radiance_accum_background(PathRadiance *L,
+ ccl_addr_space PathState *state,
+ float3 throughput,
+ float3 value)
{
#ifdef __SHADOW_TRICKS__
- if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
- L->path_total += throughput * value;
- L->path_total_shaded += throughput * value * L->shadow_transparency;
+ if (state->flag & PATH_RAY_STORE_SHADOW_INFO) {
+ L->path_total += throughput * value;
+ L->path_total_shaded += throughput * value * L->shadow_transparency;
- if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- return;
- }
- }
+ if (state->flag & PATH_RAY_SHADOW_CATCHER) {
+ return;
+ }
+ }
#endif
#ifdef __PASSES__
- if(L->use_light_pass) {
- if(state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)
- L->background += throughput*value;
- else if(state->bounce == 1)
- L->direct_emission += throughput*value;
- else
- L->indirect += throughput*value;
- }
- else
-#endif
- {
- L->emission += throughput*value;
- }
+ if (L->use_light_pass) {
+ if (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)
+ L->background += throughput * value;
+ else if (state->bounce == 1)
+ L->direct_emission += throughput * value;
+ else
+ L->indirect += throughput * value;
+ }
+ else
+#endif
+ {
+ L->emission += throughput * value;
+ }
#ifdef __DENOISING_FEATURES__
- L->denoising_albedo += state->denoising_feature_weight * value;
-#endif /* __DENOISING_FEATURES__ */
+ L->denoising_albedo += state->denoising_feature_weight * value;
+#endif /* __DENOISING_FEATURES__ */
}
-ccl_device_inline void path_radiance_accum_transparent(
- PathRadiance *L,
- ccl_addr_space PathState *state,
- float3 throughput)
+ccl_device_inline void path_radiance_accum_transparent(PathRadiance *L,
+ ccl_addr_space PathState *state,
+ float3 throughput)
{
- L->transparent += average(throughput);
+ L->transparent += average(throughput);
}
#ifdef __SHADOW_TRICKS__
-ccl_device_inline void path_radiance_accum_shadowcatcher(
- PathRadiance *L,
- float3 throughput,
- float3 background)
+ccl_device_inline void path_radiance_accum_shadowcatcher(PathRadiance *L,
+ float3 throughput,
+ float3 background)
{
- L->shadow_throughput += average(throughput);
- L->shadow_background_color += throughput * background;
- L->has_shadow_catcher = 1;
+ L->shadow_throughput += average(throughput);
+ L->shadow_background_color += throughput * background;
+ L->has_shadow_catcher = 1;
}
#endif
ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
{
#ifdef __PASSES__
- /* this division is a bit ugly, but means we only have to keep track of
- * only a single throughput further along the path, here we recover just
- * the indirect path that is not influenced by any particular BSDF type */
- if(L->use_light_pass) {
- L->direct_emission = safe_divide_color(L->direct_emission, L->state.direct);
- L->direct_diffuse += L->state.diffuse*L->direct_emission;
- L->direct_glossy += L->state.glossy*L->direct_emission;
- L->direct_transmission += L->state.transmission*L->direct_emission;
- L->direct_subsurface += L->state.subsurface*L->direct_emission;
- L->direct_scatter += L->state.scatter*L->direct_emission;
-
- L->indirect = safe_divide_color(L->indirect, L->state.direct);
- L->indirect_diffuse += L->state.diffuse*L->indirect;
- L->indirect_glossy += L->state.glossy*L->indirect;
- L->indirect_transmission += L->state.transmission*L->indirect;
- L->indirect_subsurface += L->state.subsurface*L->indirect;
- L->indirect_scatter += L->state.scatter*L->indirect;
- }
+ /* this division is a bit ugly, but means we only have to keep track of
+ * only a single throughput further along the path, here we recover just
+ * the indirect path that is not influenced by any particular BSDF type */
+ if (L->use_light_pass) {
+ L->direct_emission = safe_divide_color(L->direct_emission, L->state.direct);
+ L->direct_diffuse += L->state.diffuse * L->direct_emission;
+ L->direct_glossy += L->state.glossy * L->direct_emission;
+ L->direct_transmission += L->state.transmission * L->direct_emission;
+ L->direct_subsurface += L->state.subsurface * L->direct_emission;
+ L->direct_scatter += L->state.scatter * L->direct_emission;
+
+ L->indirect = safe_divide_color(L->indirect, L->state.direct);
+ L->indirect_diffuse += L->state.diffuse * L->indirect;
+ L->indirect_glossy += L->state.glossy * L->indirect;
+ L->indirect_transmission += L->state.transmission * L->indirect;
+ L->indirect_subsurface += L->state.subsurface * L->indirect;
+ L->indirect_scatter += L->state.scatter * L->indirect;
+ }
#endif
}
ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
{
#ifdef __PASSES__
- if(L->use_light_pass) {
- L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
- L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
- L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
+ if (L->use_light_pass) {
+ L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect = make_float3(0.0f, 0.0f, 0.0f);
- }
+ L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect = make_float3(0.0f, 0.0f, 0.0f);
+ }
#endif
}
-ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
- const PathRadiance *L_src)
+ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L, const PathRadiance *L_src)
{
#ifdef __PASSES__
- if(L->use_light_pass) {
- L->state = L_src->state;
+ if (L->use_light_pass) {
+ L->state = L_src->state;
- L->direct_emission = L_src->direct_emission;
- L->indirect = L_src->indirect;
- }
+ L->direct_emission = L_src->direct_emission;
+ L->indirect = L_src->indirect;
+ }
#endif
}
@@ -557,213 +550,219 @@ ccl_device_inline void path_radiance_sum_shadowcatcher(KernelGlobals *kg,
float3 *L_sum,
float *alpha)
{
- /* Calculate current shadow of the path. */
- float path_total = average(L->path_total);
- float shadow;
-
- if(UNLIKELY(!isfinite_safe(path_total))) {
- kernel_assert(!"Non-finite total radiance along the path");
- shadow = 0.0f;
- }
- else if(path_total == 0.0f) {
- shadow = L->shadow_transparency;
- }
- else {
- float path_total_shaded = average(L->path_total_shaded);
- shadow = path_total_shaded / path_total;
- }
-
- /* Calculate final light sum and transparency for shadow catcher object. */
- if(kernel_data.background.transparent) {
- *alpha -= L->shadow_throughput * shadow;
- }
- else {
- L->shadow_background_color *= shadow;
- *L_sum += L->shadow_background_color;
- }
+ /* Calculate current shadow of the path. */
+ float path_total = average(L->path_total);
+ float shadow;
+
+ if (UNLIKELY(!isfinite_safe(path_total))) {
+ kernel_assert(!"Non-finite total radiance along the path");
+ shadow = 0.0f;
+ }
+ else if (path_total == 0.0f) {
+ shadow = L->shadow_transparency;
+ }
+ else {
+ float path_total_shaded = average(L->path_total_shaded);
+ shadow = path_total_shaded / path_total;
+ }
+
+ /* Calculate final light sum and transparency for shadow catcher object. */
+ if (kernel_data.background.transparent) {
+ *alpha -= L->shadow_throughput * shadow;
+ }
+ else {
+ L->shadow_background_color *= shadow;
+ *L_sum += L->shadow_background_color;
+ }
}
#endif
-ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L, float *alpha)
+ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg,
+ PathRadiance *L,
+ float *alpha)
{
- float3 L_sum;
- /* Light Passes are used */
+ float3 L_sum;
+ /* Light Passes are used */
#ifdef __PASSES__
- float3 L_direct, L_indirect;
- float clamp_direct = kernel_data.integrator.sample_clamp_direct;
- float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
- if(L->use_light_pass) {
- path_radiance_sum_indirect(L);
-
- L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission;
- L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter;
-
- if(!kernel_data.background.transparent)
- L_direct += L->background;
-
- L_sum = L_direct + L_indirect;
- float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
-
- /* Reject invalid value */
- if(!isfinite_safe(sum)) {
- kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
- L_sum = make_float3(0.0f, 0.0f, 0.0f);
-
- L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
-
- L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
-
- L->emission = make_float3(0.0f, 0.0f, 0.0f);
- }
-
- /* Clamp direct and indirect samples */
-#ifdef __CLAMP_SAMPLE__
- else if(sum > clamp_direct || sum > clamp_indirect) {
- float scale;
-
- /* Direct */
- float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
- if(sum_direct > clamp_direct) {
- scale = clamp_direct/sum_direct;
- L_direct *= scale;
-
- L->direct_diffuse *= scale;
- L->direct_glossy *= scale;
- L->direct_transmission *= scale;
- L->direct_subsurface *= scale;
- L->direct_scatter *= scale;
- L->emission *= scale;
- L->background *= scale;
- }
-
- /* Indirect */
- float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
- if(sum_indirect > clamp_indirect) {
- scale = clamp_indirect/sum_indirect;
- L_indirect *= scale;
-
- L->indirect_diffuse *= scale;
- L->indirect_glossy *= scale;
- L->indirect_transmission *= scale;
- L->indirect_subsurface *= scale;
- L->indirect_scatter *= scale;
- }
-
- /* Sum again, after clamping */
- L_sum = L_direct + L_indirect;
- }
-#endif
- }
-
- /* No Light Passes */
- else
-#endif
- {
- L_sum = L->emission;
-
- /* Reject invalid value */
- float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
- if(!isfinite_safe(sum)) {
- kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
- L_sum = make_float3(0.0f, 0.0f, 0.0f);
- }
- }
-
- /* Compute alpha. */
- *alpha = 1.0f - L->transparent;
-
- /* Add shadow catcher contributions. */
+ float3 L_direct, L_indirect;
+ float clamp_direct = kernel_data.integrator.sample_clamp_direct;
+ float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
+ if (L->use_light_pass) {
+ path_radiance_sum_indirect(L);
+
+ L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission +
+ L->direct_subsurface + L->direct_scatter + L->emission;
+ L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission +
+ L->indirect_subsurface + L->indirect_scatter;
+
+ if (!kernel_data.background.transparent)
+ L_direct += L->background;
+
+ L_sum = L_direct + L_indirect;
+ float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
+
+ /* Reject invalid value */
+ if (!isfinite_safe(sum)) {
+ kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
+ L_sum = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->emission = make_float3(0.0f, 0.0f, 0.0f);
+ }
+
+ /* Clamp direct and indirect samples */
+# ifdef __CLAMP_SAMPLE__
+ else if (sum > clamp_direct || sum > clamp_indirect) {
+ float scale;
+
+ /* Direct */
+ float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
+ if (sum_direct > clamp_direct) {
+ scale = clamp_direct / sum_direct;
+ L_direct *= scale;
+
+ L->direct_diffuse *= scale;
+ L->direct_glossy *= scale;
+ L->direct_transmission *= scale;
+ L->direct_subsurface *= scale;
+ L->direct_scatter *= scale;
+ L->emission *= scale;
+ L->background *= scale;
+ }
+
+ /* Indirect */
+ float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
+ if (sum_indirect > clamp_indirect) {
+ scale = clamp_indirect / sum_indirect;
+ L_indirect *= scale;
+
+ L->indirect_diffuse *= scale;
+ L->indirect_glossy *= scale;
+ L->indirect_transmission *= scale;
+ L->indirect_subsurface *= scale;
+ L->indirect_scatter *= scale;
+ }
+
+ /* Sum again, after clamping */
+ L_sum = L_direct + L_indirect;
+ }
+# endif
+ }
+
+ /* No Light Passes */
+ else
+#endif
+ {
+ L_sum = L->emission;
+
+ /* Reject invalid value */
+ float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
+ if (!isfinite_safe(sum)) {
+ kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
+ L_sum = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ /* Compute alpha. */
+ *alpha = 1.0f - L->transparent;
+
+ /* Add shadow catcher contributions. */
#ifdef __SHADOW_TRICKS__
- if(L->has_shadow_catcher) {
- path_radiance_sum_shadowcatcher(kg, L, &L_sum, alpha);
- }
-#endif /* __SHADOW_TRICKS__ */
+ if (L->has_shadow_catcher) {
+ path_radiance_sum_shadowcatcher(kg, L, &L_sum, alpha);
+ }
+#endif /* __SHADOW_TRICKS__ */
- return L_sum;
+ return L_sum;
}
-ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg, PathRadiance *L, float3 *noisy, float3 *clean)
+ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg,
+ PathRadiance *L,
+ float3 *noisy,
+ float3 *clean)
{
#ifdef __PASSES__
- kernel_assert(L->use_light_pass);
-
- *clean = L->emission + L->background;
- *noisy = L->direct_scatter + L->indirect_scatter;
-
-# define ADD_COMPONENT(flag, component) \
- if(kernel_data.film.denoising_flags & flag) \
- *clean += component; \
- else \
- *noisy += component;
-
- ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_DIR, L->direct_diffuse);
- ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_IND, L->indirect_diffuse);
- ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_DIR, L->direct_glossy);
- ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_IND, L->indirect_glossy);
- ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_DIR, L->direct_transmission);
- ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_IND, L->indirect_transmission);
- ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_DIR, L->direct_subsurface);
- ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_IND, L->indirect_subsurface);
+ kernel_assert(L->use_light_pass);
+
+ *clean = L->emission + L->background;
+ *noisy = L->direct_scatter + L->indirect_scatter;
+
+# define ADD_COMPONENT(flag, component) \
+ if (kernel_data.film.denoising_flags & flag) \
+ *clean += component; \
+ else \
+ *noisy += component;
+
+ ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_DIR, L->direct_diffuse);
+ ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_IND, L->indirect_diffuse);
+ ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_DIR, L->direct_glossy);
+ ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_IND, L->indirect_glossy);
+ ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_DIR, L->direct_transmission);
+ ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_IND, L->indirect_transmission);
+ ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_DIR, L->direct_subsurface);
+ ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_IND, L->indirect_subsurface);
# undef ADD_COMPONENT
#else
- *noisy = L->emission;
- *clean = make_float3(0.0f, 0.0f, 0.0f);
+ *noisy = L->emission;
+ *clean = make_float3(0.0f, 0.0f, 0.0f);
#endif
#ifdef __SHADOW_TRICKS__
- if(L->has_shadow_catcher) {
- *noisy += L->shadow_background_color;
- }
+ if (L->has_shadow_catcher) {
+ *noisy += L->shadow_background_color;
+ }
#endif
- *noisy = ensure_finite3(*noisy);
- *clean = ensure_finite3(*clean);
+ *noisy = ensure_finite3(*noisy);
+ *clean = ensure_finite3(*clean);
}
ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample)
{
#ifdef __SPLIT_KERNEL__
# define safe_float3_add(f, v) \
- do { \
- ccl_global float *p = (ccl_global float*)(&(f)); \
- atomic_add_and_fetch_float(p+0, (v).x); \
- atomic_add_and_fetch_float(p+1, (v).y); \
- atomic_add_and_fetch_float(p+2, (v).z); \
- } while(0)
-# define safe_float_add(f, v) \
- atomic_add_and_fetch_float(&(f), (v))
+ do { \
+ ccl_global float *p = (ccl_global float *)(&(f)); \
+ atomic_add_and_fetch_float(p + 0, (v).x); \
+ atomic_add_and_fetch_float(p + 1, (v).y); \
+ atomic_add_and_fetch_float(p + 2, (v).z); \
+ } while (0)
+# define safe_float_add(f, v) atomic_add_and_fetch_float(&(f), (v))
#else
# define safe_float3_add(f, v) (f) += (v)
# define safe_float_add(f, v) (f) += (v)
-#endif /* __SPLIT_KERNEL__ */
+#endif /* __SPLIT_KERNEL__ */
#ifdef __PASSES__
- safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse);
- safe_float3_add(L->direct_glossy, L_sample->direct_glossy);
- safe_float3_add(L->direct_transmission, L_sample->direct_transmission);
- safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface);
- safe_float3_add(L->direct_scatter, L_sample->direct_scatter);
-
- safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse);
- safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy);
- safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission);
- safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface);
- safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter);
-
- safe_float3_add(L->background, L_sample->background);
- safe_float3_add(L->ao, L_sample->ao);
- safe_float3_add(L->shadow, L_sample->shadow);
- safe_float_add(L->mist, L_sample->mist);
-#endif /* __PASSES__ */
- safe_float3_add(L->emission, L_sample->emission);
+ safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse);
+ safe_float3_add(L->direct_glossy, L_sample->direct_glossy);
+ safe_float3_add(L->direct_transmission, L_sample->direct_transmission);
+ safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface);
+ safe_float3_add(L->direct_scatter, L_sample->direct_scatter);
+
+ safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse);
+ safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy);
+ safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission);
+ safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface);
+ safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter);
+
+ safe_float3_add(L->background, L_sample->background);
+ safe_float3_add(L->ao, L_sample->ao);
+ safe_float3_add(L->shadow, L_sample->shadow);
+ safe_float_add(L->mist, L_sample->mist);
+#endif /* __PASSES__ */
+ safe_float3_add(L->emission, L_sample->emission);
#undef safe_float_add
#undef safe_float3_add
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 37c163f2538..10b71bc6bdf 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -18,191 +18,172 @@ CCL_NAMESPACE_BEGIN
#ifdef __BAKING__
-ccl_device_inline void compute_light_pass(KernelGlobals *kg,
- ShaderData *sd,
- PathRadiance *L,
- uint rng_hash,
- int pass_filter,
- int sample)
+ccl_device_inline void compute_light_pass(
+ KernelGlobals *kg, ShaderData *sd, PathRadiance *L, uint rng_hash, int pass_filter, int sample)
{
- kernel_assert(kernel_data.film.use_light_pass);
-
- PathRadiance L_sample;
- PathState state;
- Ray ray;
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
-
- /* emission and indirect shader data memory used by various functions */
- ShaderData emission_sd, indirect_sd;
-
- ray.P = sd->P + sd->Ng;
- ray.D = -sd->Ng;
- ray.t = FLT_MAX;
-#ifdef __CAMERA_MOTION__
- ray.time = 0.5f;
-#endif
-
- /* init radiance */
- path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
-
- /* init path state */
- path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
-
- /* evaluate surface shader */
- shader_eval_surface(kg, sd, &state, state.flag);
-
- /* TODO, disable more closures we don't need besides transparent */
- shader_bsdf_disable_transparency(kg, sd);
-
-#ifdef __BRANCHED_PATH__
- if(!kernel_data.integrator.branched) {
- /* regular path tracer */
-#endif
-
- /* sample ambient occlusion */
- if(pass_filter & BAKE_FILTER_AO) {
- kernel_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd));
- }
-
- /* sample emission */
- if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
- float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(&L_sample, &state, throughput, emission);
- }
-
- bool is_sss_sample = false;
-
-#ifdef __SUBSURFACE__
- /* sample subsurface scattering */
- if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
- /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
- SubsurfaceIndirectRays ss_indirect;
- kernel_path_subsurface_init_indirect(&ss_indirect);
- if(kernel_path_subsurface_scatter(kg,
- sd,
- &emission_sd,
- &L_sample,
- &state,
- &ray,
- &throughput,
- &ss_indirect))
- {
- while(ss_indirect.num_rays) {
- kernel_path_subsurface_setup_indirect(kg,
- &ss_indirect,
- &state,
- &ray,
- &L_sample,
- &throughput);
- kernel_path_indirect(kg,
- &indirect_sd,
- &emission_sd,
- &ray,
- throughput,
- &state,
- &L_sample);
- }
- is_sss_sample = true;
- }
- }
-#endif
-
- /* sample light and BSDF */
- if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
- kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
-
- if(kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample.state, &ray)) {
-#ifdef __LAMP_MIS__
- state.ray_t = 0.0f;
-#endif
- /* compute indirect light */
- kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
-
- /* sum and reset indirect light pass variables for the next samples */
- path_radiance_sum_indirect(&L_sample);
- path_radiance_reset_indirect(&L_sample);
- }
- }
-#ifdef __BRANCHED_PATH__
- }
- else {
- /* branched path tracer */
-
- /* sample ambient occlusion */
- if(pass_filter & BAKE_FILTER_AO) {
- kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput);
- }
-
- /* sample emission */
- if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
- float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(&L_sample, &state, throughput, emission);
- }
-
-#ifdef __SUBSURFACE__
- /* sample subsurface scattering */
- if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
- /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
- kernel_branched_path_subsurface_scatter(kg, sd, &indirect_sd,
- &emission_sd, &L_sample, &state, &ray, throughput);
- }
-#endif
-
- /* sample light and BSDF */
- if(pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT)) {
-#if defined(__EMISSION__)
- /* direct light */
- if(kernel_data.integrator.use_direct_light) {
- int all = kernel_data.integrator.sample_all_lights_direct;
- kernel_branched_path_surface_connect_light(kg,
- sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all);
- }
-#endif
-
- /* indirect light */
- kernel_branched_path_surface_indirect_light(kg,
- sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample);
- }
- }
-#endif
-
- /* accumulate into master L */
- path_radiance_accum_sample(L, &L_sample);
+ kernel_assert(kernel_data.film.use_light_pass);
+
+ PathRadiance L_sample;
+ PathState state;
+ Ray ray;
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+
+ /* emission and indirect shader data memory used by various functions */
+ ShaderData emission_sd, indirect_sd;
+
+ ray.P = sd->P + sd->Ng;
+ ray.D = -sd->Ng;
+ ray.t = FLT_MAX;
+# ifdef __CAMERA_MOTION__
+ ray.time = 0.5f;
+# endif
+
+ /* init radiance */
+ path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
+
+ /* init path state */
+ path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
+
+ /* evaluate surface shader */
+ shader_eval_surface(kg, sd, &state, state.flag);
+
+ /* TODO, disable more closures we don't need besides transparent */
+ shader_bsdf_disable_transparency(kg, sd);
+
+# ifdef __BRANCHED_PATH__
+ if (!kernel_data.integrator.branched) {
+ /* regular path tracer */
+# endif
+
+ /* sample ambient occlusion */
+ if (pass_filter & BAKE_FILTER_AO) {
+ kernel_path_ao(
+ kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd));
+ }
+
+ /* sample emission */
+ if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+ float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+ path_radiance_accum_emission(&L_sample, &state, throughput, emission);
+ }
+
+ bool is_sss_sample = false;
+
+# ifdef __SUBSURFACE__
+ /* sample subsurface scattering */
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
+ /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
+ SubsurfaceIndirectRays ss_indirect;
+ kernel_path_subsurface_init_indirect(&ss_indirect);
+ if (kernel_path_subsurface_scatter(
+ kg, sd, &emission_sd, &L_sample, &state, &ray, &throughput, &ss_indirect)) {
+ while (ss_indirect.num_rays) {
+ kernel_path_subsurface_setup_indirect(
+ kg, &ss_indirect, &state, &ray, &L_sample, &throughput);
+ kernel_path_indirect(
+ kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
+ }
+ is_sss_sample = true;
+ }
+ }
+# endif
+
+ /* sample light and BSDF */
+ if (!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
+ kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
+
+ if (kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample.state, &ray)) {
+# ifdef __LAMP_MIS__
+ state.ray_t = 0.0f;
+# endif
+ /* compute indirect light */
+ kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
+
+ /* sum and reset indirect light pass variables for the next samples */
+ path_radiance_sum_indirect(&L_sample);
+ path_radiance_reset_indirect(&L_sample);
+ }
+ }
+# ifdef __BRANCHED_PATH__
+ }
+ else {
+ /* branched path tracer */
+
+ /* sample ambient occlusion */
+ if (pass_filter & BAKE_FILTER_AO) {
+ kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput);
+ }
+
+ /* sample emission */
+ if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+ float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+ path_radiance_accum_emission(&L_sample, &state, throughput, emission);
+ }
+
+# ifdef __SUBSURFACE__
+ /* sample subsurface scattering */
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
+ /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
+ kernel_branched_path_subsurface_scatter(
+ kg, sd, &indirect_sd, &emission_sd, &L_sample, &state, &ray, throughput);
+ }
+# endif
+
+ /* sample light and BSDF */
+ if (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT)) {
+# if defined(__EMISSION__)
+ /* direct light */
+ if (kernel_data.integrator.use_direct_light) {
+ int all = kernel_data.integrator.sample_all_lights_direct;
+ kernel_branched_path_surface_connect_light(
+ kg, sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all);
+ }
+# endif
+
+ /* indirect light */
+ kernel_branched_path_surface_indirect_light(
+ kg, sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample);
+ }
+ }
+# endif
+
+ /* accumulate into master L */
+ path_radiance_accum_sample(L, &L_sample);
}
/* this helps with AA but it's not the real solution as it does not AA the geometry
* but it's better than nothing, thus committed */
ccl_device_inline float bake_clamp_mirror_repeat(float u, float max)
{
- /* use mirror repeat (like opengl texture) so that if the barycentric
- * coordinate goes past the end of the triangle it is not always clamped
- * to the same value, gives ugly patterns */
- u /= max;
- float fu = floorf(u);
- u = u - fu;
-
- return ((((int)fu) & 1)? 1.0f - u: u) * max;
+ /* use mirror repeat (like opengl texture) so that if the barycentric
+ * coordinate goes past the end of the triangle it is not always clamped
+ * to the same value, gives ugly patterns */
+ u /= max;
+ float fu = floorf(u);
+ u = u - fu;
+
+ return ((((int)fu) & 1) ? 1.0f - u : u) * max;
}
ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg,
ShaderData *sd,
const ShaderEvalType type)
{
- switch(type) {
- case SHADER_EVAL_DIFFUSE:
- return shader_bsdf_diffuse(kg, sd);
- case SHADER_EVAL_GLOSSY:
- return shader_bsdf_glossy(kg, sd);
- case SHADER_EVAL_TRANSMISSION:
- return shader_bsdf_transmission(kg, sd);
-#ifdef __SUBSURFACE__
- case SHADER_EVAL_SUBSURFACE:
- return shader_bsdf_subsurface(kg, sd);
-#endif
- default:
- kernel_assert(!"Unknown bake type passed to BSDF evaluate");
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ switch (type) {
+ case SHADER_EVAL_DIFFUSE:
+ return shader_bsdf_diffuse(kg, sd);
+ case SHADER_EVAL_GLOSSY:
+ return shader_bsdf_glossy(kg, sd);
+ case SHADER_EVAL_TRANSMISSION:
+ return shader_bsdf_transmission(kg, sd);
+# ifdef __SUBSURFACE__
+ case SHADER_EVAL_SUBSURFACE:
+ return shader_bsdf_subsurface(kg, sd);
+# endif
+ default:
+ kernel_assert(!"Unknown bake type passed to BSDF evaluate");
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
@@ -213,316 +194,301 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
const ShaderEvalType type,
const int pass_filter)
{
- float3 color;
- const bool is_color = (pass_filter & BAKE_FILTER_COLOR) != 0;
- const bool is_direct = (pass_filter & BAKE_FILTER_DIRECT) != 0;
- const bool is_indirect = (pass_filter & BAKE_FILTER_INDIRECT) != 0;
- float3 out = make_float3(0.0f, 0.0f, 0.0f);
-
- if(is_color) {
- if(is_direct || is_indirect) {
- /* Leave direct and diffuse channel colored. */
- color = make_float3(1.0f, 1.0f, 1.0f);
- }
- else {
- /* surface color of the pass only */
- shader_eval_surface(kg, sd, state, 0);
- return kernel_bake_shader_bsdf(kg, sd, type);
- }
- }
- else {
- shader_eval_surface(kg, sd, state, 0);
- color = kernel_bake_shader_bsdf(kg, sd, type);
- }
-
- if(is_direct) {
- out += safe_divide_even_color(direct, color);
- }
-
- if(is_indirect) {
- out += safe_divide_even_color(indirect, color);
- }
-
- return out;
+ float3 color;
+ const bool is_color = (pass_filter & BAKE_FILTER_COLOR) != 0;
+ const bool is_direct = (pass_filter & BAKE_FILTER_DIRECT) != 0;
+ const bool is_indirect = (pass_filter & BAKE_FILTER_INDIRECT) != 0;
+ float3 out = make_float3(0.0f, 0.0f, 0.0f);
+
+ if (is_color) {
+ if (is_direct || is_indirect) {
+ /* Leave direct and diffuse channel colored. */
+ color = make_float3(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ /* surface color of the pass only */
+ shader_eval_surface(kg, sd, state, 0);
+ return kernel_bake_shader_bsdf(kg, sd, type);
+ }
+ }
+ else {
+ shader_eval_surface(kg, sd, state, 0);
+ color = kernel_bake_shader_bsdf(kg, sd, type);
+ }
+
+ if (is_direct) {
+ out += safe_divide_even_color(direct, color);
+ }
+
+ if (is_indirect) {
+ out += safe_divide_even_color(indirect, color);
+ }
+
+ return out;
}
-ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output,
- ShaderEvalType type, int pass_filter, int i, int offset, int sample)
+ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
+ ccl_global uint4 *input,
+ ccl_global float4 *output,
+ ShaderEvalType type,
+ int pass_filter,
+ int i,
+ int offset,
+ int sample)
{
- ShaderData sd;
- PathState state = {0};
- uint4 in = input[i * 2];
- uint4 diff = input[i * 2 + 1];
-
- float3 out = make_float3(0.0f, 0.0f, 0.0f);
-
- int object = in.x;
- int prim = in.y;
-
- if(prim == -1)
- return;
-
- float u = __uint_as_float(in.z);
- float v = __uint_as_float(in.w);
-
- float dudx = __uint_as_float(diff.x);
- float dudy = __uint_as_float(diff.y);
- float dvdx = __uint_as_float(diff.z);
- float dvdy = __uint_as_float(diff.w);
-
- int num_samples = kernel_data.integrator.aa_samples;
-
- /* random number generator */
- uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed);
-
- float filter_x, filter_y;
- if(sample == 0) {
- filter_x = filter_y = 0.5f;
- }
- else {
- path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
- }
-
- /* subpixel u/v offset */
- if(sample > 0) {
- u = bake_clamp_mirror_repeat(u + dudx*(filter_x - 0.5f) + dudy*(filter_y - 0.5f), 1.0f);
- v = bake_clamp_mirror_repeat(v + dvdx*(filter_x - 0.5f) + dvdy*(filter_y - 0.5f), 1.0f - u);
- }
-
- /* triangle */
- int shader;
- float3 P, Ng;
-
- triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
-
- /* light passes */
- PathRadiance L;
- path_radiance_init(&L, kernel_data.film.use_light_pass);
-
- shader_setup_from_sample(kg, &sd,
- P, Ng, Ng,
- shader, object, prim,
- u, v, 1.0f, 0.5f,
- !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
- LAMP_NONE);
- sd.I = sd.N;
-
- /* update differentials */
- sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx;
- sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy;
- sd.du.dx = dudx;
- sd.du.dy = dudy;
- sd.dv.dx = dvdx;
- sd.dv.dy = dvdy;
-
- /* set RNG state for shaders that use sampling */
- state.rng_hash = rng_hash;
- state.rng_offset = 0;
- state.sample = sample;
- state.num_samples = num_samples;
- state.min_ray_pdf = FLT_MAX;
-
- /* light passes if we need more than color */
- if(pass_filter & ~BAKE_FILTER_COLOR)
- compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample);
-
- switch(type) {
- /* data passes */
- case SHADER_EVAL_NORMAL:
- case SHADER_EVAL_ROUGHNESS:
- case SHADER_EVAL_EMISSION:
- {
- if(type != SHADER_EVAL_NORMAL || (sd.flag & SD_HAS_BUMP)) {
- int path_flag = (type == SHADER_EVAL_EMISSION) ? PATH_RAY_EMISSION : 0;
- shader_eval_surface(kg, &sd, &state, path_flag);
- }
-
- if(type == SHADER_EVAL_NORMAL) {
- float3 N = sd.N;
- if(sd.flag & SD_HAS_BUMP) {
- N = shader_bsdf_average_normal(kg, &sd);
- }
-
- /* encoding: normal = (2 * color) - 1 */
- out = N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
- }
- else if(type == SHADER_EVAL_ROUGHNESS) {
- float roughness = shader_bsdf_average_roughness(&sd);
- out = make_float3(roughness, roughness, roughness);
- }
- else {
- out = shader_emissive_eval(&sd);
- }
- break;
- }
- case SHADER_EVAL_UV:
- {
- out = primitive_uv(kg, &sd);
- break;
- }
-#ifdef __PASSES__
- /* light passes */
- case SHADER_EVAL_AO:
- {
- out = L.ao;
- break;
- }
- case SHADER_EVAL_COMBINED:
- {
- if((pass_filter & BAKE_FILTER_COMBINED) == BAKE_FILTER_COMBINED) {
- float alpha;
- out = path_radiance_clamp_and_sum(kg, &L, &alpha);
- break;
- }
-
- if((pass_filter & BAKE_FILTER_DIFFUSE_DIRECT) == BAKE_FILTER_DIFFUSE_DIRECT)
- out += L.direct_diffuse;
- if((pass_filter & BAKE_FILTER_DIFFUSE_INDIRECT) == BAKE_FILTER_DIFFUSE_INDIRECT)
- out += L.indirect_diffuse;
-
- if((pass_filter & BAKE_FILTER_GLOSSY_DIRECT) == BAKE_FILTER_GLOSSY_DIRECT)
- out += L.direct_glossy;
- if((pass_filter & BAKE_FILTER_GLOSSY_INDIRECT) == BAKE_FILTER_GLOSSY_INDIRECT)
- out += L.indirect_glossy;
-
- if((pass_filter & BAKE_FILTER_TRANSMISSION_DIRECT) == BAKE_FILTER_TRANSMISSION_DIRECT)
- out += L.direct_transmission;
- if((pass_filter & BAKE_FILTER_TRANSMISSION_INDIRECT) == BAKE_FILTER_TRANSMISSION_INDIRECT)
- out += L.indirect_transmission;
-
- if((pass_filter & BAKE_FILTER_SUBSURFACE_DIRECT) == BAKE_FILTER_SUBSURFACE_DIRECT)
- out += L.direct_subsurface;
- if((pass_filter & BAKE_FILTER_SUBSURFACE_INDIRECT) == BAKE_FILTER_SUBSURFACE_INDIRECT)
- out += L.indirect_subsurface;
-
- if((pass_filter & BAKE_FILTER_EMISSION) != 0)
- out += L.emission;
-
- break;
- }
- case SHADER_EVAL_SHADOW:
- {
- out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z);
- break;
- }
- case SHADER_EVAL_DIFFUSE:
- {
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_diffuse,
- L.indirect_diffuse,
- type,
- pass_filter);
- break;
- }
- case SHADER_EVAL_GLOSSY:
- {
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_glossy,
- L.indirect_glossy,
- type,
- pass_filter);
- break;
- }
- case SHADER_EVAL_TRANSMISSION:
- {
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_transmission,
- L.indirect_transmission,
- type,
- pass_filter);
- break;
- }
- case SHADER_EVAL_SUBSURFACE:
- {
-#ifdef __SUBSURFACE__
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_subsurface,
- L.indirect_subsurface,
- type,
- pass_filter);
-#endif
- break;
- }
-#endif
-
- /* extra */
- case SHADER_EVAL_ENVIRONMENT:
- {
- /* setup ray */
- Ray ray;
-
- ray.P = make_float3(0.0f, 0.0f, 0.0f);
- ray.D = normalize(P);
- ray.t = 0.0f;
-#ifdef __CAMERA_MOTION__
- ray.time = 0.5f;
-#endif
-
-#ifdef __RAY_DIFFERENTIALS__
- ray.dD = differential3_zero();
- ray.dP = differential3_zero();
-#endif
-
- /* setup shader data */
- shader_setup_from_background(kg, &sd, &ray);
-
- /* evaluate */
- int path_flag = 0; /* we can't know which type of BSDF this is for */
- shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
- out = shader_background_eval(&sd);
- break;
- }
- default:
- {
- /* no real shader, returning the position of the verts for debugging */
- out = normalize(P);
- break;
- }
- }
-
- /* write output */
- const float output_fac = 1.0f/num_samples;
- const float4 scaled_result = make_float4(out.x, out.y, out.z, 1.0f) * output_fac;
-
- output[i] = (sample == 0)? scaled_result: output[i] + scaled_result;
+ ShaderData sd;
+ PathState state = {0};
+ uint4 in = input[i * 2];
+ uint4 diff = input[i * 2 + 1];
+
+ float3 out = make_float3(0.0f, 0.0f, 0.0f);
+
+ int object = in.x;
+ int prim = in.y;
+
+ if (prim == -1)
+ return;
+
+ float u = __uint_as_float(in.z);
+ float v = __uint_as_float(in.w);
+
+ float dudx = __uint_as_float(diff.x);
+ float dudy = __uint_as_float(diff.y);
+ float dvdx = __uint_as_float(diff.z);
+ float dvdy = __uint_as_float(diff.w);
+
+ int num_samples = kernel_data.integrator.aa_samples;
+
+ /* random number generator */
+ uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed);
+
+ float filter_x, filter_y;
+ if (sample == 0) {
+ filter_x = filter_y = 0.5f;
+ }
+ else {
+ path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
+ }
+
+ /* subpixel u/v offset */
+ if (sample > 0) {
+ u = bake_clamp_mirror_repeat(u + dudx * (filter_x - 0.5f) + dudy * (filter_y - 0.5f), 1.0f);
+ v = bake_clamp_mirror_repeat(v + dvdx * (filter_x - 0.5f) + dvdy * (filter_y - 0.5f),
+ 1.0f - u);
+ }
+
+ /* triangle */
+ int shader;
+ float3 P, Ng;
+
+ triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
+
+ /* light passes */
+ PathRadiance L;
+ path_radiance_init(&L, kernel_data.film.use_light_pass);
+
+ shader_setup_from_sample(
+ kg,
+ &sd,
+ P,
+ Ng,
+ Ng,
+ shader,
+ object,
+ prim,
+ u,
+ v,
+ 1.0f,
+ 0.5f,
+ !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
+ LAMP_NONE);
+ sd.I = sd.N;
+
+ /* update differentials */
+ sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx;
+ sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy;
+ sd.du.dx = dudx;
+ sd.du.dy = dudy;
+ sd.dv.dx = dvdx;
+ sd.dv.dy = dvdy;
+
+ /* set RNG state for shaders that use sampling */
+ state.rng_hash = rng_hash;
+ state.rng_offset = 0;
+ state.sample = sample;
+ state.num_samples = num_samples;
+ state.min_ray_pdf = FLT_MAX;
+
+ /* light passes if we need more than color */
+ if (pass_filter & ~BAKE_FILTER_COLOR)
+ compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample);
+
+ switch (type) {
+ /* data passes */
+ case SHADER_EVAL_NORMAL:
+ case SHADER_EVAL_ROUGHNESS:
+ case SHADER_EVAL_EMISSION: {
+ if (type != SHADER_EVAL_NORMAL || (sd.flag & SD_HAS_BUMP)) {
+ int path_flag = (type == SHADER_EVAL_EMISSION) ? PATH_RAY_EMISSION : 0;
+ shader_eval_surface(kg, &sd, &state, path_flag);
+ }
+
+ if (type == SHADER_EVAL_NORMAL) {
+ float3 N = sd.N;
+ if (sd.flag & SD_HAS_BUMP) {
+ N = shader_bsdf_average_normal(kg, &sd);
+ }
+
+ /* encoding: normal = (2 * color) - 1 */
+ out = N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
+ }
+ else if (type == SHADER_EVAL_ROUGHNESS) {
+ float roughness = shader_bsdf_average_roughness(&sd);
+ out = make_float3(roughness, roughness, roughness);
+ }
+ else {
+ out = shader_emissive_eval(&sd);
+ }
+ break;
+ }
+ case SHADER_EVAL_UV: {
+ out = primitive_uv(kg, &sd);
+ break;
+ }
+# ifdef __PASSES__
+ /* light passes */
+ case SHADER_EVAL_AO: {
+ out = L.ao;
+ break;
+ }
+ case SHADER_EVAL_COMBINED: {
+ if ((pass_filter & BAKE_FILTER_COMBINED) == BAKE_FILTER_COMBINED) {
+ float alpha;
+ out = path_radiance_clamp_and_sum(kg, &L, &alpha);
+ break;
+ }
+
+ if ((pass_filter & BAKE_FILTER_DIFFUSE_DIRECT) == BAKE_FILTER_DIFFUSE_DIRECT)
+ out += L.direct_diffuse;
+ if ((pass_filter & BAKE_FILTER_DIFFUSE_INDIRECT) == BAKE_FILTER_DIFFUSE_INDIRECT)
+ out += L.indirect_diffuse;
+
+ if ((pass_filter & BAKE_FILTER_GLOSSY_DIRECT) == BAKE_FILTER_GLOSSY_DIRECT)
+ out += L.direct_glossy;
+ if ((pass_filter & BAKE_FILTER_GLOSSY_INDIRECT) == BAKE_FILTER_GLOSSY_INDIRECT)
+ out += L.indirect_glossy;
+
+ if ((pass_filter & BAKE_FILTER_TRANSMISSION_DIRECT) == BAKE_FILTER_TRANSMISSION_DIRECT)
+ out += L.direct_transmission;
+ if ((pass_filter & BAKE_FILTER_TRANSMISSION_INDIRECT) == BAKE_FILTER_TRANSMISSION_INDIRECT)
+ out += L.indirect_transmission;
+
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE_DIRECT) == BAKE_FILTER_SUBSURFACE_DIRECT)
+ out += L.direct_subsurface;
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE_INDIRECT) == BAKE_FILTER_SUBSURFACE_INDIRECT)
+ out += L.indirect_subsurface;
+
+ if ((pass_filter & BAKE_FILTER_EMISSION) != 0)
+ out += L.emission;
+
+ break;
+ }
+ case SHADER_EVAL_SHADOW: {
+ out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z);
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE: {
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_diffuse, L.indirect_diffuse, type, pass_filter);
+ break;
+ }
+ case SHADER_EVAL_GLOSSY: {
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_glossy, L.indirect_glossy, type, pass_filter);
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION: {
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_transmission, L.indirect_transmission, type, pass_filter);
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE: {
+# ifdef __SUBSURFACE__
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_subsurface, L.indirect_subsurface, type, pass_filter);
+# endif
+ break;
+ }
+# endif
+
+ /* extra */
+ case SHADER_EVAL_ENVIRONMENT: {
+ /* setup ray */
+ Ray ray;
+
+ ray.P = make_float3(0.0f, 0.0f, 0.0f);
+ ray.D = normalize(P);
+ ray.t = 0.0f;
+# ifdef __CAMERA_MOTION__
+ ray.time = 0.5f;
+# endif
+
+# ifdef __RAY_DIFFERENTIALS__
+ ray.dD = differential3_zero();
+ ray.dP = differential3_zero();
+# endif
+
+ /* setup shader data */
+ shader_setup_from_background(kg, &sd, &ray);
+
+ /* evaluate */
+ int path_flag = 0; /* we can't know which type of BSDF this is for */
+ shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
+ out = shader_background_eval(&sd);
+ break;
+ }
+ default: {
+ /* no real shader, returning the position of the verts for debugging */
+ out = normalize(P);
+ break;
+ }
+ }
+
+ /* write output */
+ const float output_fac = 1.0f / num_samples;
+ const float4 scaled_result = make_float4(out.x, out.y, out.z, 1.0f) * output_fac;
+
+ output[i] = (sample == 0) ? scaled_result : output[i] + scaled_result;
}
-#endif /* __BAKING__ */
+#endif /* __BAKING__ */
ccl_device void kernel_displace_evaluate(KernelGlobals *kg,
ccl_global uint4 *input,
ccl_global float4 *output,
int i)
{
- ShaderData sd;
- PathState state = {0};
- uint4 in = input[i];
+ ShaderData sd;
+ PathState state = {0};
+ uint4 in = input[i];
- /* setup shader data */
- int object = in.x;
- int prim = in.y;
- float u = __uint_as_float(in.z);
- float v = __uint_as_float(in.w);
+ /* setup shader data */
+ int object = in.x;
+ int prim = in.y;
+ float u = __uint_as_float(in.z);
+ float v = __uint_as_float(in.w);
- shader_setup_from_displace(kg, &sd, object, prim, u, v);
+ shader_setup_from_displace(kg, &sd, object, prim, u, v);
- /* evaluate */
- float3 P = sd.P;
- shader_eval_displacement(kg, &sd, &state);
- float3 D = sd.P - P;
+ /* evaluate */
+ float3 P = sd.P;
+ shader_eval_displacement(kg, &sd, &state);
+ float3 D = sd.P - P;
- object_inverse_dir_transform(kg, &sd, &D);
+ object_inverse_dir_transform(kg, &sd, &D);
- /* write output */
- output[i] += make_float4(D.x, D.y, D.z, 0.0f);
+ /* write output */
+ output[i] += make_float4(D.x, D.y, D.z, 0.0f);
}
ccl_device void kernel_background_evaluate(KernelGlobals *kg,
@@ -530,37 +496,37 @@ ccl_device void kernel_background_evaluate(KernelGlobals *kg,
ccl_global float4 *output,
int i)
{
- ShaderData sd;
- PathState state = {0};
- uint4 in = input[i];
-
- /* setup ray */
- Ray ray;
- float u = __uint_as_float(in.x);
- float v = __uint_as_float(in.y);
-
- ray.P = make_float3(0.0f, 0.0f, 0.0f);
- ray.D = equirectangular_to_direction(u, v);
- ray.t = 0.0f;
+ ShaderData sd;
+ PathState state = {0};
+ uint4 in = input[i];
+
+ /* setup ray */
+ Ray ray;
+ float u = __uint_as_float(in.x);
+ float v = __uint_as_float(in.y);
+
+ ray.P = make_float3(0.0f, 0.0f, 0.0f);
+ ray.D = equirectangular_to_direction(u, v);
+ ray.t = 0.0f;
#ifdef __CAMERA_MOTION__
- ray.time = 0.5f;
+ ray.time = 0.5f;
#endif
#ifdef __RAY_DIFFERENTIALS__
- ray.dD = differential3_zero();
- ray.dP = differential3_zero();
+ ray.dD = differential3_zero();
+ ray.dP = differential3_zero();
#endif
- /* setup shader data */
- shader_setup_from_background(kg, &sd, &ray);
+ /* setup shader data */
+ shader_setup_from_background(kg, &sd, &ray);
- /* evaluate */
- int path_flag = 0; /* we can't know which type of BSDF this is for */
- shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
- float3 color = shader_background_eval(&sd);
+ /* evaluate */
+ int path_flag = 0; /* we can't know which type of BSDF this is for */
+ shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
+ float3 color = shader_background_eval(&sd);
- /* write output */
- output[i] += make_float4(color.x, color.y, color.z, 0.0f);
+ /* write output */
+ output[i] += make_float4(color.x, color.y, color.z, 0.0f);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index b73ad47dad3..1085930c33a 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -20,209 +20,217 @@ CCL_NAMESPACE_BEGIN
ccl_device float2 camera_sample_aperture(ccl_constant KernelCamera *cam, float u, float v)
{
- float blades = cam->blades;
- float2 bokeh;
-
- if(blades == 0.0f) {
- /* sample disk */
- bokeh = concentric_sample_disk(u, v);
- }
- else {
- /* sample polygon */
- float rotation = cam->bladesrotation;
- bokeh = regular_polygon_sample(blades, rotation, u, v);
- }
-
- /* anamorphic lens bokeh */
- bokeh.x *= cam->inv_aperture_ratio;
-
- return bokeh;
+ float blades = cam->blades;
+ float2 bokeh;
+
+ if (blades == 0.0f) {
+ /* sample disk */
+ bokeh = concentric_sample_disk(u, v);
+ }
+ else {
+ /* sample polygon */
+ float rotation = cam->bladesrotation;
+ bokeh = regular_polygon_sample(blades, rotation, u, v);
+ }
+
+ /* anamorphic lens bokeh */
+ bokeh.x *= cam->inv_aperture_ratio;
+
+ return bokeh;
}
-ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, ccl_addr_space Ray *ray)
+ccl_device void camera_sample_perspective(KernelGlobals *kg,
+ float raster_x,
+ float raster_y,
+ float lens_u,
+ float lens_v,
+ ccl_addr_space Ray *ray)
{
- /* create ray form raster position */
- ProjectionTransform rastertocamera = kernel_data.cam.rastertocamera;
- float3 raster = make_float3(raster_x, raster_y, 0.0f);
- float3 Pcamera = transform_perspective(&rastertocamera, raster);
+ /* create ray form raster position */
+ ProjectionTransform rastertocamera = kernel_data.cam.rastertocamera;
+ float3 raster = make_float3(raster_x, raster_y, 0.0f);
+ float3 Pcamera = transform_perspective(&rastertocamera, raster);
#ifdef __CAMERA_MOTION__
- if(kernel_data.cam.have_perspective_motion) {
- /* TODO(sergey): Currently we interpolate projected coordinate which
- * gives nice looking result and which is simple, but is in fact a bit
- * different comparing to constructing projective matrix from an
- * interpolated field of view.
- */
- if(ray->time < 0.5f) {
- ProjectionTransform rastertocamera_pre = kernel_data.cam.perspective_pre;
- float3 Pcamera_pre =
- transform_perspective(&rastertocamera_pre, raster);
- Pcamera = interp(Pcamera_pre, Pcamera, ray->time * 2.0f);
- }
- else {
- ProjectionTransform rastertocamera_post = kernel_data.cam.perspective_post;
- float3 Pcamera_post =
- transform_perspective(&rastertocamera_post, raster);
- Pcamera = interp(Pcamera, Pcamera_post, (ray->time - 0.5f) * 2.0f);
- }
- }
+ if (kernel_data.cam.have_perspective_motion) {
+ /* TODO(sergey): Currently we interpolate projected coordinate which
+ * gives nice looking result and which is simple, but is in fact a bit
+ * different comparing to constructing projective matrix from an
+ * interpolated field of view.
+ */
+ if (ray->time < 0.5f) {
+ ProjectionTransform rastertocamera_pre = kernel_data.cam.perspective_pre;
+ float3 Pcamera_pre = transform_perspective(&rastertocamera_pre, raster);
+ Pcamera = interp(Pcamera_pre, Pcamera, ray->time * 2.0f);
+ }
+ else {
+ ProjectionTransform rastertocamera_post = kernel_data.cam.perspective_post;
+ float3 Pcamera_post = transform_perspective(&rastertocamera_post, raster);
+ Pcamera = interp(Pcamera, Pcamera_post, (ray->time - 0.5f) * 2.0f);
+ }
+ }
#endif
- float3 P = make_float3(0.0f, 0.0f, 0.0f);
- float3 D = Pcamera;
+ float3 P = make_float3(0.0f, 0.0f, 0.0f);
+ float3 D = Pcamera;
- /* modify ray for depth of field */
- float aperturesize = kernel_data.cam.aperturesize;
+ /* modify ray for depth of field */
+ float aperturesize = kernel_data.cam.aperturesize;
- if(aperturesize > 0.0f) {
- /* sample point on aperture */
- float2 lensuv = camera_sample_aperture(&kernel_data.cam, lens_u, lens_v)*aperturesize;
+ if (aperturesize > 0.0f) {
+ /* sample point on aperture */
+ float2 lensuv = camera_sample_aperture(&kernel_data.cam, lens_u, lens_v) * aperturesize;
- /* compute point on plane of focus */
- float ft = kernel_data.cam.focaldistance/D.z;
- float3 Pfocus = D*ft;
+ /* compute point on plane of focus */
+ float ft = kernel_data.cam.focaldistance / D.z;
+ float3 Pfocus = D * ft;
- /* update ray for effect of lens */
- P = make_float3(lensuv.x, lensuv.y, 0.0f);
- D = normalize(Pfocus - P);
- }
+ /* update ray for effect of lens */
+ P = make_float3(lensuv.x, lensuv.y, 0.0f);
+ D = normalize(Pfocus - P);
+ }
- /* transform ray from camera to world */
- Transform cameratoworld = kernel_data.cam.cameratoworld;
+ /* transform ray from camera to world */
+ Transform cameratoworld = kernel_data.cam.cameratoworld;
#ifdef __CAMERA_MOTION__
- if(kernel_data.cam.num_motion_steps) {
- transform_motion_array_interpolate(
- &cameratoworld,
- kernel_tex_array(__camera_motion),
- kernel_data.cam.num_motion_steps,
- ray->time);
- }
+ if (kernel_data.cam.num_motion_steps) {
+ transform_motion_array_interpolate(&cameratoworld,
+ kernel_tex_array(__camera_motion),
+ kernel_data.cam.num_motion_steps,
+ ray->time);
+ }
#endif
- P = transform_point(&cameratoworld, P);
- D = normalize(transform_direction(&cameratoworld, D));
+ P = transform_point(&cameratoworld, P);
+ D = normalize(transform_direction(&cameratoworld, D));
- bool use_stereo = kernel_data.cam.interocular_offset != 0.0f;
- if(!use_stereo) {
- /* No stereo */
- ray->P = P;
- ray->D = D;
+ bool use_stereo = kernel_data.cam.interocular_offset != 0.0f;
+ if (!use_stereo) {
+ /* No stereo */
+ ray->P = P;
+ ray->D = D;
#ifdef __RAY_DIFFERENTIALS__
- float3 Dcenter = transform_direction(&cameratoworld, Pcamera);
+ float3 Dcenter = transform_direction(&cameratoworld, Pcamera);
- ray->dP = differential3_zero();
- ray->dD.dx = normalize(Dcenter + float4_to_float3(kernel_data.cam.dx)) - normalize(Dcenter);
- ray->dD.dy = normalize(Dcenter + float4_to_float3(kernel_data.cam.dy)) - normalize(Dcenter);
+ ray->dP = differential3_zero();
+ ray->dD.dx = normalize(Dcenter + float4_to_float3(kernel_data.cam.dx)) - normalize(Dcenter);
+ ray->dD.dy = normalize(Dcenter + float4_to_float3(kernel_data.cam.dy)) - normalize(Dcenter);
#endif
- }
- else {
- /* Spherical stereo */
- spherical_stereo_transform(&kernel_data.cam, &P, &D);
- ray->P = P;
- ray->D = D;
+ }
+ else {
+ /* Spherical stereo */
+ spherical_stereo_transform(&kernel_data.cam, &P, &D);
+ ray->P = P;
+ ray->D = D;
#ifdef __RAY_DIFFERENTIALS__
- /* Ray differentials, computed from scratch using the raster coordinates
- * because we don't want to be affected by depth of field. We compute
- * ray origin and direction for the center and two neighbouring pixels
- * and simply take their differences. */
- float3 Pnostereo = transform_point(&cameratoworld, make_float3(0.0f, 0.0f, 0.0f));
-
- float3 Pcenter = Pnostereo;
- float3 Dcenter = Pcamera;
- Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
- spherical_stereo_transform(&kernel_data.cam, &Pcenter, &Dcenter);
-
- float3 Px = Pnostereo;
- float3 Dx = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
- Dx = normalize(transform_direction(&cameratoworld, Dx));
- spherical_stereo_transform(&kernel_data.cam, &Px, &Dx);
-
- ray->dP.dx = Px - Pcenter;
- ray->dD.dx = Dx - Dcenter;
-
- float3 Py = Pnostereo;
- float3 Dy = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
- Dy = normalize(transform_direction(&cameratoworld, Dy));
- spherical_stereo_transform(&kernel_data.cam, &Py, &Dy);
-
- ray->dP.dy = Py - Pcenter;
- ray->dD.dy = Dy - Dcenter;
+ /* Ray differentials, computed from scratch using the raster coordinates
+ * because we don't want to be affected by depth of field. We compute
+ * ray origin and direction for the center and two neighbouring pixels
+ * and simply take their differences. */
+ float3 Pnostereo = transform_point(&cameratoworld, make_float3(0.0f, 0.0f, 0.0f));
+
+ float3 Pcenter = Pnostereo;
+ float3 Dcenter = Pcamera;
+ Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
+ spherical_stereo_transform(&kernel_data.cam, &Pcenter, &Dcenter);
+
+ float3 Px = Pnostereo;
+ float3 Dx = transform_perspective(&rastertocamera,
+ make_float3(raster_x + 1.0f, raster_y, 0.0f));
+ Dx = normalize(transform_direction(&cameratoworld, Dx));
+ spherical_stereo_transform(&kernel_data.cam, &Px, &Dx);
+
+ ray->dP.dx = Px - Pcenter;
+ ray->dD.dx = Dx - Dcenter;
+
+ float3 Py = Pnostereo;
+ float3 Dy = transform_perspective(&rastertocamera,
+ make_float3(raster_x, raster_y + 1.0f, 0.0f));
+ Dy = normalize(transform_direction(&cameratoworld, Dy));
+ spherical_stereo_transform(&kernel_data.cam, &Py, &Dy);
+
+ ray->dP.dy = Py - Pcenter;
+ ray->dD.dy = Dy - Dcenter;
#endif
- }
+ }
#ifdef __CAMERA_CLIPPING__
- /* clipping */
- float z_inv = 1.0f / normalize(Pcamera).z;
- float nearclip = kernel_data.cam.nearclip * z_inv;
- ray->P += nearclip * ray->D;
- ray->dP.dx += nearclip * ray->dD.dx;
- ray->dP.dy += nearclip * ray->dD.dy;
- ray->t = kernel_data.cam.cliplength * z_inv;
+ /* clipping */
+ float z_inv = 1.0f / normalize(Pcamera).z;
+ float nearclip = kernel_data.cam.nearclip * z_inv;
+ ray->P += nearclip * ray->D;
+ ray->dP.dx += nearclip * ray->dD.dx;
+ ray->dP.dy += nearclip * ray->dD.dy;
+ ray->t = kernel_data.cam.cliplength * z_inv;
#else
- ray->t = FLT_MAX;
+ ray->t = FLT_MAX;
#endif
}
/* Orthographic Camera */
-ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, ccl_addr_space Ray *ray)
+ccl_device void camera_sample_orthographic(KernelGlobals *kg,
+ float raster_x,
+ float raster_y,
+ float lens_u,
+ float lens_v,
+ ccl_addr_space Ray *ray)
{
- /* create ray form raster position */
- ProjectionTransform rastertocamera = kernel_data.cam.rastertocamera;
- float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
-
- float3 P;
- float3 D = make_float3(0.0f, 0.0f, 1.0f);
-
- /* modify ray for depth of field */
- float aperturesize = kernel_data.cam.aperturesize;
-
- if(aperturesize > 0.0f) {
- /* sample point on aperture */
- float2 lensuv = camera_sample_aperture(&kernel_data.cam, lens_u, lens_v)*aperturesize;
-
- /* compute point on plane of focus */
- float3 Pfocus = D * kernel_data.cam.focaldistance;
-
- /* update ray for effect of lens */
- float3 lensuvw = make_float3(lensuv.x, lensuv.y, 0.0f);
- P = Pcamera + lensuvw;
- D = normalize(Pfocus - lensuvw);
- }
- else {
- P = Pcamera;
- }
- /* transform ray from camera to world */
- Transform cameratoworld = kernel_data.cam.cameratoworld;
+ /* create ray form raster position */
+ ProjectionTransform rastertocamera = kernel_data.cam.rastertocamera;
+ float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+
+ float3 P;
+ float3 D = make_float3(0.0f, 0.0f, 1.0f);
+
+ /* modify ray for depth of field */
+ float aperturesize = kernel_data.cam.aperturesize;
+
+ if (aperturesize > 0.0f) {
+ /* sample point on aperture */
+ float2 lensuv = camera_sample_aperture(&kernel_data.cam, lens_u, lens_v) * aperturesize;
+
+ /* compute point on plane of focus */
+ float3 Pfocus = D * kernel_data.cam.focaldistance;
+
+ /* update ray for effect of lens */
+ float3 lensuvw = make_float3(lensuv.x, lensuv.y, 0.0f);
+ P = Pcamera + lensuvw;
+ D = normalize(Pfocus - lensuvw);
+ }
+ else {
+ P = Pcamera;
+ }
+ /* transform ray from camera to world */
+ Transform cameratoworld = kernel_data.cam.cameratoworld;
#ifdef __CAMERA_MOTION__
- if(kernel_data.cam.num_motion_steps) {
- transform_motion_array_interpolate(
- &cameratoworld,
- kernel_tex_array(__camera_motion),
- kernel_data.cam.num_motion_steps,
- ray->time);
- }
+ if (kernel_data.cam.num_motion_steps) {
+ transform_motion_array_interpolate(&cameratoworld,
+ kernel_tex_array(__camera_motion),
+ kernel_data.cam.num_motion_steps,
+ ray->time);
+ }
#endif
- ray->P = transform_point(&cameratoworld, P);
- ray->D = normalize(transform_direction(&cameratoworld, D));
+ ray->P = transform_point(&cameratoworld, P);
+ ray->D = normalize(transform_direction(&cameratoworld, D));
#ifdef __RAY_DIFFERENTIALS__
- /* ray differential */
- ray->dP.dx = float4_to_float3(kernel_data.cam.dx);
- ray->dP.dy = float4_to_float3(kernel_data.cam.dy);
+ /* ray differential */
+ ray->dP.dx = float4_to_float3(kernel_data.cam.dx);
+ ray->dP.dy = float4_to_float3(kernel_data.cam.dy);
- ray->dD = differential3_zero();
+ ray->dD = differential3_zero();
#endif
#ifdef __CAMERA_CLIPPING__
- /* clipping */
- ray->t = kernel_data.cam.cliplength;
+ /* clipping */
+ ray->t = kernel_data.cam.cliplength;
#else
- ray->t = FLT_MAX;
+ ray->t = FLT_MAX;
#endif
}
@@ -230,242 +238,244 @@ ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, fl
ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
const ccl_global DecomposedTransform *cam_motion,
- float raster_x, float raster_y,
- float lens_u, float lens_v,
+ float raster_x,
+ float raster_y,
+ float lens_u,
+ float lens_v,
ccl_addr_space Ray *ray)
{
- ProjectionTransform rastertocamera = cam->rastertocamera;
- float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+ ProjectionTransform rastertocamera = cam->rastertocamera;
+ float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
- /* create ray form raster position */
- float3 P = make_float3(0.0f, 0.0f, 0.0f);
- float3 D = panorama_to_direction(cam, Pcamera.x, Pcamera.y);
+ /* create ray form raster position */
+ float3 P = make_float3(0.0f, 0.0f, 0.0f);
+ float3 D = panorama_to_direction(cam, Pcamera.x, Pcamera.y);
- /* indicates ray should not receive any light, outside of the lens */
- if(is_zero(D)) {
- ray->t = 0.0f;
- return;
- }
+ /* indicates ray should not receive any light, outside of the lens */
+ if (is_zero(D)) {
+ ray->t = 0.0f;
+ return;
+ }
- /* modify ray for depth of field */
- float aperturesize = cam->aperturesize;
+ /* modify ray for depth of field */
+ float aperturesize = cam->aperturesize;
- if(aperturesize > 0.0f) {
- /* sample point on aperture */
- float2 lensuv = camera_sample_aperture(cam, lens_u, lens_v)*aperturesize;
+ if (aperturesize > 0.0f) {
+ /* sample point on aperture */
+ float2 lensuv = camera_sample_aperture(cam, lens_u, lens_v) * aperturesize;
- /* compute point on plane of focus */
- float3 Dfocus = normalize(D);
- float3 Pfocus = Dfocus * cam->focaldistance;
+ /* compute point on plane of focus */
+ float3 Dfocus = normalize(D);
+ float3 Pfocus = Dfocus * cam->focaldistance;
- /* calculate orthonormal coordinates perpendicular to Dfocus */
- float3 U, V;
- U = normalize(make_float3(1.0f, 0.0f, 0.0f) - Dfocus.x * Dfocus);
- V = normalize(cross(Dfocus, U));
+ /* calculate orthonormal coordinates perpendicular to Dfocus */
+ float3 U, V;
+ U = normalize(make_float3(1.0f, 0.0f, 0.0f) - Dfocus.x * Dfocus);
+ V = normalize(cross(Dfocus, U));
- /* update ray for effect of lens */
- P = U * lensuv.x + V * lensuv.y;
- D = normalize(Pfocus - P);
- }
+ /* update ray for effect of lens */
+ P = U * lensuv.x + V * lensuv.y;
+ D = normalize(Pfocus - P);
+ }
- /* transform ray from camera to world */
- Transform cameratoworld = cam->cameratoworld;
+ /* transform ray from camera to world */
+ Transform cameratoworld = cam->cameratoworld;
#ifdef __CAMERA_MOTION__
- if(cam->num_motion_steps) {
- transform_motion_array_interpolate(
- &cameratoworld,
- cam_motion,
- cam->num_motion_steps,
- ray->time);
- }
+ if (cam->num_motion_steps) {
+ transform_motion_array_interpolate(
+ &cameratoworld, cam_motion, cam->num_motion_steps, ray->time);
+ }
#endif
- P = transform_point(&cameratoworld, P);
- D = normalize(transform_direction(&cameratoworld, D));
+ P = transform_point(&cameratoworld, P);
+ D = normalize(transform_direction(&cameratoworld, D));
- /* Stereo transform */
- bool use_stereo = cam->interocular_offset != 0.0f;
- if(use_stereo) {
- spherical_stereo_transform(cam, &P, &D);
- }
+ /* Stereo transform */
+ bool use_stereo = cam->interocular_offset != 0.0f;
+ if (use_stereo) {
+ spherical_stereo_transform(cam, &P, &D);
+ }
- ray->P = P;
- ray->D = D;
+ ray->P = P;
+ ray->D = D;
#ifdef __RAY_DIFFERENTIALS__
- /* Ray differentials, computed from scratch using the raster coordinates
- * because we don't want to be affected by depth of field. We compute
- * ray origin and direction for the center and two neighbouring pixels
- * and simply take their differences. */
- float3 Pcenter = Pcamera;
- float3 Dcenter = panorama_to_direction(cam, Pcenter.x, Pcenter.y);
- Pcenter = transform_point(&cameratoworld, Pcenter);
- Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
- if(use_stereo) {
- spherical_stereo_transform(cam, &Pcenter, &Dcenter);
- }
-
- float3 Px = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
- float3 Dx = panorama_to_direction(cam, Px.x, Px.y);
- Px = transform_point(&cameratoworld, Px);
- Dx = normalize(transform_direction(&cameratoworld, Dx));
- if(use_stereo) {
- spherical_stereo_transform(cam, &Px, &Dx);
- }
-
- ray->dP.dx = Px - Pcenter;
- ray->dD.dx = Dx - Dcenter;
-
- float3 Py = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
- float3 Dy = panorama_to_direction(cam, Py.x, Py.y);
- Py = transform_point(&cameratoworld, Py);
- Dy = normalize(transform_direction(&cameratoworld, Dy));
- if(use_stereo) {
- spherical_stereo_transform(cam, &Py, &Dy);
- }
-
- ray->dP.dy = Py - Pcenter;
- ray->dD.dy = Dy - Dcenter;
+ /* Ray differentials, computed from scratch using the raster coordinates
+ * because we don't want to be affected by depth of field. We compute
+ * ray origin and direction for the center and two neighbouring pixels
+ * and simply take their differences. */
+ float3 Pcenter = Pcamera;
+ float3 Dcenter = panorama_to_direction(cam, Pcenter.x, Pcenter.y);
+ Pcenter = transform_point(&cameratoworld, Pcenter);
+ Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
+ if (use_stereo) {
+ spherical_stereo_transform(cam, &Pcenter, &Dcenter);
+ }
+
+ float3 Px = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
+ float3 Dx = panorama_to_direction(cam, Px.x, Px.y);
+ Px = transform_point(&cameratoworld, Px);
+ Dx = normalize(transform_direction(&cameratoworld, Dx));
+ if (use_stereo) {
+ spherical_stereo_transform(cam, &Px, &Dx);
+ }
+
+ ray->dP.dx = Px - Pcenter;
+ ray->dD.dx = Dx - Dcenter;
+
+ float3 Py = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
+ float3 Dy = panorama_to_direction(cam, Py.x, Py.y);
+ Py = transform_point(&cameratoworld, Py);
+ Dy = normalize(transform_direction(&cameratoworld, Dy));
+ if (use_stereo) {
+ spherical_stereo_transform(cam, &Py, &Dy);
+ }
+
+ ray->dP.dy = Py - Pcenter;
+ ray->dD.dy = Dy - Dcenter;
#endif
#ifdef __CAMERA_CLIPPING__
- /* clipping */
- float nearclip = cam->nearclip;
- ray->P += nearclip * ray->D;
- ray->dP.dx += nearclip * ray->dD.dx;
- ray->dP.dy += nearclip * ray->dD.dy;
- ray->t = cam->cliplength;
+ /* clipping */
+ float nearclip = cam->nearclip;
+ ray->P += nearclip * ray->D;
+ ray->dP.dx += nearclip * ray->dD.dx;
+ ray->dP.dy += nearclip * ray->dD.dy;
+ ray->t = cam->cliplength;
#else
- ray->t = FLT_MAX;
+ ray->t = FLT_MAX;
#endif
}
/* Common */
ccl_device_inline void camera_sample(KernelGlobals *kg,
- int x, int y,
- float filter_u, float filter_v,
- float lens_u, float lens_v,
+ int x,
+ int y,
+ float filter_u,
+ float filter_v,
+ float lens_u,
+ float lens_v,
float time,
ccl_addr_space Ray *ray)
{
- /* pixel filter */
- int filter_table_offset = kernel_data.film.filter_table_offset;
- float raster_x = x + lookup_table_read(kg, filter_u, filter_table_offset, FILTER_TABLE_SIZE);
- float raster_y = y + lookup_table_read(kg, filter_v, filter_table_offset, FILTER_TABLE_SIZE);
+ /* pixel filter */
+ int filter_table_offset = kernel_data.film.filter_table_offset;
+ float raster_x = x + lookup_table_read(kg, filter_u, filter_table_offset, FILTER_TABLE_SIZE);
+ float raster_y = y + lookup_table_read(kg, filter_v, filter_table_offset, FILTER_TABLE_SIZE);
#ifdef __CAMERA_MOTION__
- /* motion blur */
- if(kernel_data.cam.shuttertime == -1.0f) {
- ray->time = 0.5f;
- }
- else {
- /* TODO(sergey): Such lookup is unneeded when there's rolling shutter
- * effect in use but rolling shutter duration is set to 0.0.
- */
- const int shutter_table_offset = kernel_data.cam.shutter_table_offset;
- ray->time = lookup_table_read(kg, time, shutter_table_offset, SHUTTER_TABLE_SIZE);
- /* TODO(sergey): Currently single rolling shutter effect type only
- * where scanlines are acquired from top to bottom and whole scanline
- * is acquired at once (no delay in acquisition happens between pixels
- * of single scanline).
- *
- * Might want to support more models in the future.
- */
- if(kernel_data.cam.rolling_shutter_type) {
- /* Time corresponding to a fully rolling shutter only effect:
- * top of the frame is time 0.0, bottom of the frame is time 1.0.
- */
- const float time = 1.0f - (float)y / kernel_data.cam.height;
- const float duration = kernel_data.cam.rolling_shutter_duration;
- if(duration != 0.0f) {
- /* This isn't fully physical correct, but lets us to have simple
- * controls in the interface. The idea here is basically sort of
- * linear interpolation between how much rolling shutter effect
- * exist on the frame and how much of it is a motion blur effect.
- */
- ray->time = (ray->time - 0.5f) * duration;
- ray->time += (time - 0.5f) * (1.0f - duration) + 0.5f;
- }
- else {
- ray->time = time;
- }
- }
- }
+ /* motion blur */
+ if (kernel_data.cam.shuttertime == -1.0f) {
+ ray->time = 0.5f;
+ }
+ else {
+ /* TODO(sergey): Such lookup is unneeded when there's rolling shutter
+ * effect in use but rolling shutter duration is set to 0.0.
+ */
+ const int shutter_table_offset = kernel_data.cam.shutter_table_offset;
+ ray->time = lookup_table_read(kg, time, shutter_table_offset, SHUTTER_TABLE_SIZE);
+ /* TODO(sergey): Currently single rolling shutter effect type only
+ * where scanlines are acquired from top to bottom and whole scanline
+ * is acquired at once (no delay in acquisition happens between pixels
+ * of single scanline).
+ *
+ * Might want to support more models in the future.
+ */
+ if (kernel_data.cam.rolling_shutter_type) {
+ /* Time corresponding to a fully rolling shutter only effect:
+ * top of the frame is time 0.0, bottom of the frame is time 1.0.
+ */
+ const float time = 1.0f - (float)y / kernel_data.cam.height;
+ const float duration = kernel_data.cam.rolling_shutter_duration;
+ if (duration != 0.0f) {
+ /* This isn't fully physical correct, but lets us to have simple
+ * controls in the interface. The idea here is basically sort of
+ * linear interpolation between how much rolling shutter effect
+ * exist on the frame and how much of it is a motion blur effect.
+ */
+ ray->time = (ray->time - 0.5f) * duration;
+ ray->time += (time - 0.5f) * (1.0f - duration) + 0.5f;
+ }
+ else {
+ ray->time = time;
+ }
+ }
+ }
#endif
- /* sample */
- if(kernel_data.cam.type == CAMERA_PERSPECTIVE) {
- camera_sample_perspective(kg, raster_x, raster_y, lens_u, lens_v, ray);
- }
- else if(kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
- camera_sample_orthographic(kg, raster_x, raster_y, lens_u, lens_v, ray);
- }
- else {
- const ccl_global DecomposedTransform *cam_motion = kernel_tex_array(__camera_motion);
- camera_sample_panorama(&kernel_data.cam, cam_motion, raster_x, raster_y, lens_u, lens_v, ray);
- }
+ /* sample */
+ if (kernel_data.cam.type == CAMERA_PERSPECTIVE) {
+ camera_sample_perspective(kg, raster_x, raster_y, lens_u, lens_v, ray);
+ }
+ else if (kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
+ camera_sample_orthographic(kg, raster_x, raster_y, lens_u, lens_v, ray);
+ }
+ else {
+ const ccl_global DecomposedTransform *cam_motion = kernel_tex_array(__camera_motion);
+ camera_sample_panorama(&kernel_data.cam, cam_motion, raster_x, raster_y, lens_u, lens_v, ray);
+ }
}
/* Utilities */
ccl_device_inline float3 camera_position(KernelGlobals *kg)
{
- Transform cameratoworld = kernel_data.cam.cameratoworld;
- return make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
+ Transform cameratoworld = kernel_data.cam.cameratoworld;
+ return make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
}
ccl_device_inline float camera_distance(KernelGlobals *kg, float3 P)
{
- Transform cameratoworld = kernel_data.cam.cameratoworld;
- float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
-
- if(kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
- float3 camD = make_float3(cameratoworld.x.z, cameratoworld.y.z, cameratoworld.z.z);
- return fabsf(dot((P - camP), camD));
- }
- else
- return len(P - camP);
+ Transform cameratoworld = kernel_data.cam.cameratoworld;
+ float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
+
+ if (kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
+ float3 camD = make_float3(cameratoworld.x.z, cameratoworld.y.z, cameratoworld.z.z);
+ return fabsf(dot((P - camP), camD));
+ }
+ else
+ return len(P - camP);
}
ccl_device_inline float3 camera_direction_from_point(KernelGlobals *kg, float3 P)
{
- Transform cameratoworld = kernel_data.cam.cameratoworld;
-
- if(kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
- float3 camD = make_float3(cameratoworld.x.z, cameratoworld.y.z, cameratoworld.z.z);
- return -camD;
- }
- else {
- float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
- return normalize(camP - P);
- }
+ Transform cameratoworld = kernel_data.cam.cameratoworld;
+
+ if (kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
+ float3 camD = make_float3(cameratoworld.x.z, cameratoworld.y.z, cameratoworld.z.z);
+ return -camD;
+ }
+ else {
+ float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
+ return normalize(camP - P);
+ }
}
ccl_device_inline float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P)
{
- if(kernel_data.cam.type != CAMERA_PANORAMA) {
- /* perspective / ortho */
- if(sd->object == PRIM_NONE && kernel_data.cam.type == CAMERA_PERSPECTIVE)
- P += camera_position(kg);
-
- ProjectionTransform tfm = kernel_data.cam.worldtondc;
- return transform_perspective(&tfm, P);
- }
- else {
- /* panorama */
- Transform tfm = kernel_data.cam.worldtocamera;
-
- if(sd->object != OBJECT_NONE)
- P = normalize(transform_point(&tfm, P));
- else
- P = normalize(transform_direction(&tfm, P));
-
- float2 uv = direction_to_panorama(&kernel_data.cam, P);
-
- return make_float3(uv.x, uv.y, 0.0f);
- }
+ if (kernel_data.cam.type != CAMERA_PANORAMA) {
+ /* perspective / ortho */
+ if (sd->object == PRIM_NONE && kernel_data.cam.type == CAMERA_PERSPECTIVE)
+ P += camera_position(kg);
+
+ ProjectionTransform tfm = kernel_data.cam.worldtondc;
+ return transform_perspective(&tfm, P);
+ }
+ else {
+ /* panorama */
+ Transform tfm = kernel_data.cam.worldtocamera;
+
+ if (sd->object != OBJECT_NONE)
+ P = normalize(transform_point(&tfm, P));
+ else
+ P = normalize(transform_direction(&tfm, P));
+
+ float2 uv = direction_to_panorama(&kernel_data.cam, P);
+
+ return make_float3(uv.x, uv.y, 0.0f);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_color.h b/intern/cycles/kernel/kernel_color.h
index ea478a8a5d3..5eb1bdad02e 100644
--- a/intern/cycles/kernel/kernel_color.h
+++ b/intern/cycles/kernel/kernel_color.h
@@ -23,16 +23,16 @@ CCL_NAMESPACE_BEGIN
ccl_device float3 xyz_to_rgb(KernelGlobals *kg, float3 xyz)
{
- return make_float3(dot(float4_to_float3(kernel_data.film.xyz_to_r), xyz),
- dot(float4_to_float3(kernel_data.film.xyz_to_g), xyz),
- dot(float4_to_float3(kernel_data.film.xyz_to_b), xyz));
+ return make_float3(dot(float4_to_float3(kernel_data.film.xyz_to_r), xyz),
+ dot(float4_to_float3(kernel_data.film.xyz_to_g), xyz),
+ dot(float4_to_float3(kernel_data.film.xyz_to_b), xyz));
}
ccl_device float linear_rgb_to_gray(KernelGlobals *kg, float3 c)
{
- return dot(c, float4_to_float3(kernel_data.film.rgb_to_y));
+ return dot(c, float4_to_float3(kernel_data.film.rgb_to_y));
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_COLOR_H__ */
+#endif /* __KERNEL_COLOR_H__ */
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 4ee80850402..e8fedca4489 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -55,9 +55,9 @@
/* On x86_64, versions of glibc < 2.16 have an issue where expf is
* much slower than the double version. This was fixed in glibc 2.16.
*/
-#if !defined(__KERNEL_GPU__) && defined(__x86_64__) && defined(__x86_64__) && \
- defined(__GNU_LIBRARY__) && defined(__GLIBC__ ) && defined(__GLIBC_MINOR__) && \
- (__GLIBC__ <= 2 && __GLIBC_MINOR__ < 16)
+#if !defined(__KERNEL_GPU__) && defined(__x86_64__) && defined(__x86_64__) && \
+ defined(__GNU_LIBRARY__) && defined(__GLIBC__) && defined(__GLIBC_MINOR__) && \
+ (__GLIBC__ <= 2 && __GLIBC_MINOR__ < 16)
# define expf(x) ((float)exp((double)(x)))
#endif
@@ -71,41 +71,41 @@ CCL_NAMESPACE_BEGIN
/* Texture types to be compatible with CUDA textures. These are really just
* simple arrays and after inlining fetch hopefully revert to being a simple
* pointer lookup. */
-template<typename T> struct texture {
- ccl_always_inline const T& fetch(int index)
- {
- kernel_assert(index >= 0 && index < width);
- return data[index];
- }
+template<typename T> struct texture {
+ ccl_always_inline const T &fetch(int index)
+ {
+ kernel_assert(index >= 0 && index < width);
+ return data[index];
+ }
#if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
- /* Reads 256 bytes but indexes in blocks of 128 bytes to maintain
- * compatibility with existing indicies and data structures.
- */
- ccl_always_inline avxf fetch_avxf(const int index)
- {
- kernel_assert(index >= 0 && (index+1) < width);
- ssef *ssef_data = (ssef*)data;
- ssef *ssef_node_data = &ssef_data[index];
- return _mm256_loadu_ps((float *)ssef_node_data);
- }
+ /* Reads 256 bytes but indexes in blocks of 128 bytes to maintain
+ * compatibility with existing indicies and data structures.
+ */
+ ccl_always_inline avxf fetch_avxf(const int index)
+ {
+ kernel_assert(index >= 0 && (index + 1) < width);
+ ssef *ssef_data = (ssef *)data;
+ ssef *ssef_node_data = &ssef_data[index];
+ return _mm256_loadu_ps((float *)ssef_node_data);
+ }
#endif
#ifdef __KERNEL_SSE2__
- ccl_always_inline ssef fetch_ssef(int index)
- {
- kernel_assert(index >= 0 && index < width);
- return ((ssef*)data)[index];
- }
-
- ccl_always_inline ssei fetch_ssei(int index)
- {
- kernel_assert(index >= 0 && index < width);
- return ((ssei*)data)[index];
- }
+ ccl_always_inline ssef fetch_ssef(int index)
+ {
+ kernel_assert(index >= 0 && index < width);
+ return ((ssef *)data)[index];
+ }
+
+ ccl_always_inline ssei fetch_ssei(int index)
+ {
+ kernel_assert(index >= 0 && index < width);
+ return ((ssei *)data)[index];
+ }
#endif
- T *data;
- int width;
+ T *data;
+ int width;
};
/* Macros to handle different memory storage on different devices */
@@ -124,33 +124,33 @@ typedef vector3<sseb> sse3b;
typedef vector3<ssef> sse3f;
typedef vector3<ssei> sse3i;
-ccl_device_inline void print_sse3b(const char *label, sse3b& a)
+ccl_device_inline void print_sse3b(const char *label, sse3b &a)
{
- print_sseb(label, a.x);
- print_sseb(label, a.y);
- print_sseb(label, a.z);
+ print_sseb(label, a.x);
+ print_sseb(label, a.y);
+ print_sseb(label, a.z);
}
-ccl_device_inline void print_sse3f(const char *label, sse3f& a)
+ccl_device_inline void print_sse3f(const char *label, sse3f &a)
{
- print_ssef(label, a.x);
- print_ssef(label, a.y);
- print_ssef(label, a.z);
+ print_ssef(label, a.x);
+ print_ssef(label, a.y);
+ print_ssef(label, a.z);
}
-ccl_device_inline void print_sse3i(const char *label, sse3i& a)
+ccl_device_inline void print_sse3i(const char *label, sse3i &a)
{
- print_ssei(label, a.x);
- print_ssei(label, a.y);
- print_ssei(label, a.z);
+ print_ssei(label, a.x);
+ print_ssei(label, a.y);
+ print_ssei(label, a.z);
}
-#if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
+# if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
typedef vector3<avxf> avx3f;
-#endif
+# endif
#endif
CCL_NAMESPACE_END
-#endif /* __KERNEL_COMPAT_CPU_H__ */
+#endif /* __KERNEL_COMPAT_CPU_H__ */
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 8ed96bbae64..469b81d120b 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -42,22 +42,22 @@ typedef unsigned long long CUtexObject;
__device__ half __float2half(const float f)
{
- half val;
- asm("{ cvt.rn.f16.f32 %0, %1;}\n" : "=h"(val) : "f"(f));
- return val;
+ half val;
+ asm("{ cvt.rn.f16.f32 %0, %1;}\n" : "=h"(val) : "f"(f));
+ return val;
}
/* Qualifier wrappers for different names on different devices */
-#define ccl_device __device__ __inline__
+#define ccl_device __device__ __inline__
#if __CUDA_ARCH__ < 500
-# define ccl_device_inline __device__ __forceinline__
-# define ccl_device_forceinline __device__ __forceinline__
+# define ccl_device_inline __device__ __forceinline__
+# define ccl_device_forceinline __device__ __forceinline__
#else
-# define ccl_device_inline __device__ __inline__
-# define ccl_device_forceinline __device__ __forceinline__
+# define ccl_device_inline __device__ __inline__
+# define ccl_device_forceinline __device__ __forceinline__
#endif
-#define ccl_device_noinline __device__ __noinline__
+#define ccl_device_noinline __device__ __noinline__
#define ccl_global
#define ccl_static_constant __constant__
#define ccl_constant const
@@ -75,8 +75,7 @@ __device__ half __float2half(const float f)
#define ATTR_FALLTHROUGH
-#define CCL_MAX_LOCAL_SIZE (CUDA_THREADS_BLOCK_WIDTH*CUDA_THREADS_BLOCK_WIDTH)
-
+#define CCL_MAX_LOCAL_SIZE (CUDA_THREADS_BLOCK_WIDTH * CUDA_THREADS_BLOCK_WIDTH)
/* No assert supported for CUDA */
@@ -91,46 +90,62 @@ __device__ half __float2half(const float f)
ccl_device_inline uint ccl_local_id(uint d)
{
- switch(d) {
- case 0: return threadIdx.x;
- case 1: return threadIdx.y;
- case 2: return threadIdx.z;
- default: return 0;
- }
+ switch (d) {
+ case 0:
+ return threadIdx.x;
+ case 1:
+ return threadIdx.y;
+ case 2:
+ return threadIdx.z;
+ default:
+ return 0;
+ }
}
#define ccl_global_id(d) (ccl_group_id(d) * ccl_local_size(d) + ccl_local_id(d))
ccl_device_inline uint ccl_local_size(uint d)
{
- switch(d) {
- case 0: return blockDim.x;
- case 1: return blockDim.y;
- case 2: return blockDim.z;
- default: return 0;
- }
+ switch (d) {
+ case 0:
+ return blockDim.x;
+ case 1:
+ return blockDim.y;
+ case 2:
+ return blockDim.z;
+ default:
+ return 0;
+ }
}
#define ccl_global_size(d) (ccl_num_groups(d) * ccl_local_size(d))
ccl_device_inline uint ccl_group_id(uint d)
{
- switch(d) {
- case 0: return blockIdx.x;
- case 1: return blockIdx.y;
- case 2: return blockIdx.z;
- default: return 0;
- }
+ switch (d) {
+ case 0:
+ return blockIdx.x;
+ case 1:
+ return blockIdx.y;
+ case 2:
+ return blockIdx.z;
+ default:
+ return 0;
+ }
}
ccl_device_inline uint ccl_num_groups(uint d)
{
- switch(d) {
- case 0: return gridDim.x;
- case 1: return gridDim.y;
- case 2: return gridDim.z;
- default: return 0;
- }
+ switch (d) {
+ case 0:
+ return gridDim.x;
+ case 1:
+ return gridDim.y;
+ case 2:
+ return gridDim.z;
+ default:
+ return 0;
+ }
}
/* Textures */
@@ -150,4 +165,4 @@ ccl_device_inline uint ccl_num_groups(uint d)
#define logf(x) __logf(((float)(x)))
#define expf(x) __expf(((float)(x)))
-#endif /* __KERNEL_COMPAT_CUDA_H__ */
+#endif /* __KERNEL_COMPAT_CUDA_H__ */
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index d3d0934a626..e040ea88d7c 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -134,7 +134,7 @@
# define expf(x) native_exp(((float)(x)))
# define sqrtf(x) native_sqrt(((float)(x)))
# define logf(x) native_log(((float)(x)))
-# define rcp(x) native_recip(x)
+# define rcp(x) native_recip(x)
#else
# define sinf(x) sin(((float)(x)))
# define cosf(x) cos(((float)(x)))
@@ -142,12 +142,13 @@
# define expf(x) exp(((float)(x)))
# define sqrtf(x) sqrt(((float)(x)))
# define logf(x) log(((float)(x)))
-# define rcp(x) recip(x)
+# define rcp(x) recip(x)
#endif
/* data lookup defines */
#define kernel_data (*kg->data)
-#define kernel_tex_array(tex) ((const ccl_global tex##_t*)(kg->buffers[kg->tex.cl_buffer] + kg->tex.data))
+#define kernel_tex_array(tex) \
+ ((const ccl_global tex##_t *)(kg->buffers[kg->tex.cl_buffer] + kg->tex.data))
#define kernel_tex_fetch(tex, index) kernel_tex_array(tex)[(index)]
/* define NULL */
@@ -155,10 +156,10 @@
/* enable extensions */
#ifdef __KERNEL_CL_KHR_FP16__
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+# pragma OPENCL EXTENSION cl_khr_fp16 : enable
#endif
#include "util/util_half.h"
#include "util/util_types.h"
-#endif /* __KERNEL_COMPAT_OPENCL_H__ */
+#endif /* __KERNEL_COMPAT_OPENCL_H__ */
diff --git a/intern/cycles/kernel/kernel_differential.h b/intern/cycles/kernel/kernel_differential.h
index 924d96c72e5..8513de0d843 100644
--- a/intern/cycles/kernel/kernel_differential.h
+++ b/intern/cycles/kernel/kernel_differential.h
@@ -18,88 +18,98 @@ CCL_NAMESPACE_BEGIN
/* See "Tracing Ray Differentials", Homan Igehy, 1999. */
-ccl_device void differential_transfer(ccl_addr_space differential3 *dP_, const differential3 dP, float3 D, const differential3 dD, float3 Ng, float t)
+ccl_device void differential_transfer(ccl_addr_space differential3 *dP_,
+ const differential3 dP,
+ float3 D,
+ const differential3 dD,
+ float3 Ng,
+ float t)
{
- /* ray differential transfer through homogeneous medium, to
- * compute dPdx/dy at a shading point from the incoming ray */
+ /* ray differential transfer through homogeneous medium, to
+ * compute dPdx/dy at a shading point from the incoming ray */
- float3 tmp = D/dot(D, Ng);
- float3 tmpx = dP.dx + t*dD.dx;
- float3 tmpy = dP.dy + t*dD.dy;
+ float3 tmp = D / dot(D, Ng);
+ float3 tmpx = dP.dx + t * dD.dx;
+ float3 tmpy = dP.dy + t * dD.dy;
- dP_->dx = tmpx - dot(tmpx, Ng)*tmp;
- dP_->dy = tmpy - dot(tmpy, Ng)*tmp;
+ dP_->dx = tmpx - dot(tmpx, Ng) * tmp;
+ dP_->dy = tmpy - dot(tmpy, Ng) * tmp;
}
ccl_device void differential_incoming(ccl_addr_space differential3 *dI, const differential3 dD)
{
- /* compute dIdx/dy at a shading point, we just need to negate the
- * differential of the ray direction */
+ /* compute dIdx/dy at a shading point, we just need to negate the
+ * differential of the ray direction */
- dI->dx = -dD.dx;
- dI->dy = -dD.dy;
+ dI->dx = -dD.dx;
+ dI->dy = -dD.dy;
}
-ccl_device void differential_dudv(ccl_addr_space differential *du, ccl_addr_space differential *dv, float3 dPdu, float3 dPdv, differential3 dP, float3 Ng)
+ccl_device void differential_dudv(ccl_addr_space differential *du,
+ ccl_addr_space differential *dv,
+ float3 dPdu,
+ float3 dPdv,
+ differential3 dP,
+ float3 Ng)
{
- /* now we have dPdx/dy from the ray differential transfer, and dPdu/dv
- * from the primitive, we can compute dudx/dy and dvdx/dy. these are
- * mainly used for differentials of arbitrary mesh attributes. */
-
- /* find most stable axis to project to 2D */
- float xn = fabsf(Ng.x);
- float yn = fabsf(Ng.y);
- float zn = fabsf(Ng.z);
-
- if(zn < xn || zn < yn) {
- if(yn < xn || yn < zn) {
- dPdu.x = dPdu.y;
- dPdv.x = dPdv.y;
- dP.dx.x = dP.dx.y;
- dP.dy.x = dP.dy.y;
- }
-
- dPdu.y = dPdu.z;
- dPdv.y = dPdv.z;
- dP.dx.y = dP.dx.z;
- dP.dy.y = dP.dy.z;
- }
-
- /* using Cramer's rule, we solve for dudx and dvdx in a 2x2 linear system,
- * and the same for dudy and dvdy. the denominator is the same for both
- * solutions, so we compute it only once.
- *
- * dP.dx = dPdu * dudx + dPdv * dvdx;
- * dP.dy = dPdu * dudy + dPdv * dvdy; */
-
- float det = (dPdu.x*dPdv.y - dPdv.x*dPdu.y);
-
- if(det != 0.0f)
- det = 1.0f/det;
-
- du->dx = (dP.dx.x*dPdv.y - dP.dx.y*dPdv.x)*det;
- dv->dx = (dP.dx.y*dPdu.x - dP.dx.x*dPdu.y)*det;
-
- du->dy = (dP.dy.x*dPdv.y - dP.dy.y*dPdv.x)*det;
- dv->dy = (dP.dy.y*dPdu.x - dP.dy.x*dPdu.y)*det;
+ /* now we have dPdx/dy from the ray differential transfer, and dPdu/dv
+ * from the primitive, we can compute dudx/dy and dvdx/dy. these are
+ * mainly used for differentials of arbitrary mesh attributes. */
+
+ /* find most stable axis to project to 2D */
+ float xn = fabsf(Ng.x);
+ float yn = fabsf(Ng.y);
+ float zn = fabsf(Ng.z);
+
+ if (zn < xn || zn < yn) {
+ if (yn < xn || yn < zn) {
+ dPdu.x = dPdu.y;
+ dPdv.x = dPdv.y;
+ dP.dx.x = dP.dx.y;
+ dP.dy.x = dP.dy.y;
+ }
+
+ dPdu.y = dPdu.z;
+ dPdv.y = dPdv.z;
+ dP.dx.y = dP.dx.z;
+ dP.dy.y = dP.dy.z;
+ }
+
+ /* using Cramer's rule, we solve for dudx and dvdx in a 2x2 linear system,
+ * and the same for dudy and dvdy. the denominator is the same for both
+ * solutions, so we compute it only once.
+ *
+ * dP.dx = dPdu * dudx + dPdv * dvdx;
+ * dP.dy = dPdu * dudy + dPdv * dvdy; */
+
+ float det = (dPdu.x * dPdv.y - dPdv.x * dPdu.y);
+
+ if (det != 0.0f)
+ det = 1.0f / det;
+
+ du->dx = (dP.dx.x * dPdv.y - dP.dx.y * dPdv.x) * det;
+ dv->dx = (dP.dx.y * dPdu.x - dP.dx.x * dPdu.y) * det;
+
+ du->dy = (dP.dy.x * dPdv.y - dP.dy.y * dPdv.x) * det;
+ dv->dy = (dP.dy.y * dPdu.x - dP.dy.x * dPdu.y) * det;
}
ccl_device differential differential_zero()
{
- differential d;
- d.dx = 0.0f;
- d.dy = 0.0f;
+ differential d;
+ d.dx = 0.0f;
+ d.dy = 0.0f;
- return d;
+ return d;
}
ccl_device differential3 differential3_zero()
{
- differential3 d;
- d.dx = make_float3(0.0f, 0.0f, 0.0f);
- d.dy = make_float3(0.0f, 0.0f, 0.0f);
+ differential3 d;
+ d.dx = make_float3(0.0f, 0.0f, 0.0f);
+ d.dy = make_float3(0.0f, 0.0f, 0.0f);
- return d;
+ return d;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 80bb8d48caf..f2eaa7b50a5 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -26,61 +26,71 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
float t,
float time)
{
- /* setup shading at emitter */
- float3 eval;
-
- if(shader_constant_emission_eval(kg, ls->shader, &eval)) {
- if((ls->prim != PRIM_NONE) && dot(ls->Ng, I) < 0.0f) {
- ls->Ng = -ls->Ng;
- }
- }
- else {
- /* Setup shader data and call shader_eval_surface once, better
- * for GPU coherence and compile times. */
+ /* setup shading at emitter */
+ float3 eval;
+
+ if (shader_constant_emission_eval(kg, ls->shader, &eval)) {
+ if ((ls->prim != PRIM_NONE) && dot(ls->Ng, I) < 0.0f) {
+ ls->Ng = -ls->Ng;
+ }
+ }
+ else {
+ /* Setup shader data and call shader_eval_surface once, better
+ * for GPU coherence and compile times. */
#ifdef __BACKGROUND_MIS__
- if(ls->type == LIGHT_BACKGROUND) {
- Ray ray;
- ray.D = ls->D;
- ray.P = ls->P;
- ray.t = 1.0f;
- ray.time = time;
- ray.dP = differential3_zero();
- ray.dD = dI;
-
- shader_setup_from_background(kg, emission_sd, &ray);
- }
- else
+ if (ls->type == LIGHT_BACKGROUND) {
+ Ray ray;
+ ray.D = ls->D;
+ ray.P = ls->P;
+ ray.t = 1.0f;
+ ray.time = time;
+ ray.dP = differential3_zero();
+ ray.dD = dI;
+
+ shader_setup_from_background(kg, emission_sd, &ray);
+ }
+ else
#endif
- {
- shader_setup_from_sample(kg, emission_sd,
- ls->P, ls->Ng, I,
- ls->shader, ls->object, ls->prim,
- ls->u, ls->v, t, time, false, ls->lamp);
-
- ls->Ng = emission_sd->Ng;
- }
-
- /* No proper path flag, we're evaluating this for all closures. that's
- * weak but we'd have to do multiple evaluations otherwise. */
- path_state_modify_bounce(state, true);
- shader_eval_surface(kg, emission_sd, state, PATH_RAY_EMISSION);
- path_state_modify_bounce(state, false);
-
- /* Evaluate closures. */
+ {
+ shader_setup_from_sample(kg,
+ emission_sd,
+ ls->P,
+ ls->Ng,
+ I,
+ ls->shader,
+ ls->object,
+ ls->prim,
+ ls->u,
+ ls->v,
+ t,
+ time,
+ false,
+ ls->lamp);
+
+ ls->Ng = emission_sd->Ng;
+ }
+
+ /* No proper path flag, we're evaluating this for all closures. that's
+ * weak but we'd have to do multiple evaluations otherwise. */
+ path_state_modify_bounce(state, true);
+ shader_eval_surface(kg, emission_sd, state, PATH_RAY_EMISSION);
+ path_state_modify_bounce(state, false);
+
+ /* Evaluate closures. */
#ifdef __BACKGROUND_MIS__
- if (ls->type == LIGHT_BACKGROUND) {
- eval = shader_background_eval(emission_sd);
- }
- else
+ if (ls->type == LIGHT_BACKGROUND) {
+ eval = shader_background_eval(emission_sd);
+ }
+ else
#endif
- {
- eval = shader_emissive_eval(emission_sd);
- }
- }
+ {
+ eval = shader_emissive_eval(emission_sd);
+ }
+ }
- eval *= ls->eval_fac;
+ eval *= ls->eval_fac;
- return eval;
+ return eval;
}
ccl_device_noinline bool direct_emission(KernelGlobals *kg,
@@ -93,132 +103,128 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg,
bool *is_lamp,
float rand_terminate)
{
- if(ls->pdf == 0.0f)
- return false;
+ if (ls->pdf == 0.0f)
+ return false;
- /* todo: implement */
- differential3 dD = differential3_zero();
+ /* todo: implement */
+ differential3 dD = differential3_zero();
- /* evaluate closure */
+ /* evaluate closure */
- float3 light_eval = direct_emissive_eval(kg,
- emission_sd,
- ls,
- state,
- -ls->D,
- dD,
- ls->t,
- sd->time);
+ float3 light_eval = direct_emissive_eval(
+ kg, emission_sd, ls, state, -ls->D, dD, ls->t, sd->time);
- if(is_zero(light_eval))
- return false;
+ if (is_zero(light_eval))
+ return false;
- /* evaluate BSDF at shading point */
+ /* evaluate BSDF at shading point */
#ifdef __VOLUME__
- if(sd->prim != PRIM_NONE)
- shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
- else {
- float bsdf_pdf;
- shader_volume_phase_eval(kg, sd, ls->D, eval, &bsdf_pdf);
- if(ls->shader & SHADER_USE_MIS) {
- /* Multiple importance sampling. */
- float mis_weight = power_heuristic(ls->pdf, bsdf_pdf);
- light_eval *= mis_weight;
- }
- }
+ if (sd->prim != PRIM_NONE)
+ shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
+ else {
+ float bsdf_pdf;
+ shader_volume_phase_eval(kg, sd, ls->D, eval, &bsdf_pdf);
+ if (ls->shader & SHADER_USE_MIS) {
+ /* Multiple importance sampling. */
+ float mis_weight = power_heuristic(ls->pdf, bsdf_pdf);
+ light_eval *= mis_weight;
+ }
+ }
#else
- shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
+ shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
#endif
- bsdf_eval_mul3(eval, light_eval/ls->pdf);
+ bsdf_eval_mul3(eval, light_eval / ls->pdf);
#ifdef __PASSES__
- /* use visibility flag to skip lights */
- if(ls->shader & SHADER_EXCLUDE_ANY) {
- if(ls->shader & SHADER_EXCLUDE_DIFFUSE) {
- eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
- eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
- }
- if(ls->shader & SHADER_EXCLUDE_GLOSSY)
- eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
- if(ls->shader & SHADER_EXCLUDE_TRANSMIT)
- eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
- if(ls->shader & SHADER_EXCLUDE_SCATTER)
- eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
- }
+ /* use visibility flag to skip lights */
+ if (ls->shader & SHADER_EXCLUDE_ANY) {
+ if (ls->shader & SHADER_EXCLUDE_DIFFUSE) {
+ eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ if (ls->shader & SHADER_EXCLUDE_GLOSSY)
+ eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
+ if (ls->shader & SHADER_EXCLUDE_TRANSMIT)
+ eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
+ if (ls->shader & SHADER_EXCLUDE_SCATTER)
+ eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
+ }
#endif
- if(bsdf_eval_is_zero(eval))
- return false;
+ if (bsdf_eval_is_zero(eval))
+ return false;
- if(kernel_data.integrator.light_inv_rr_threshold > 0.0f
+ if (kernel_data.integrator.light_inv_rr_threshold > 0.0f
#ifdef __SHADOW_TRICKS__
- && (state->flag & PATH_RAY_SHADOW_CATCHER) == 0
+ && (state->flag & PATH_RAY_SHADOW_CATCHER) == 0
#endif
- )
- {
- float probability = max3(fabs(bsdf_eval_sum(eval))) * kernel_data.integrator.light_inv_rr_threshold;
- if(probability < 1.0f) {
- if(rand_terminate >= probability) {
- return false;
- }
- bsdf_eval_mul(eval, 1.0f / probability);
- }
- }
-
- if(ls->shader & SHADER_CAST_SHADOW) {
- /* setup ray */
- bool transmit = (dot(sd->Ng, ls->D) < 0.0f);
- ray->P = ray_offset(sd->P, (transmit)? -sd->Ng: sd->Ng);
-
- if(ls->t == FLT_MAX) {
- /* distant light */
- ray->D = ls->D;
- ray->t = ls->t;
- }
- else {
- /* other lights, avoid self-intersection */
- ray->D = ray_offset(ls->P, ls->Ng) - ray->P;
- ray->D = normalize_len(ray->D, &ray->t);
- }
-
- ray->dP = sd->dP;
- ray->dD = differential3_zero();
- }
- else {
- /* signal to not cast shadow ray */
- ray->t = 0.0f;
- }
-
- /* return if it's a lamp for shadow pass */
- *is_lamp = (ls->prim == PRIM_NONE && ls->type != LIGHT_BACKGROUND);
-
- return true;
+ ) {
+ float probability = max3(fabs(bsdf_eval_sum(eval))) *
+ kernel_data.integrator.light_inv_rr_threshold;
+ if (probability < 1.0f) {
+ if (rand_terminate >= probability) {
+ return false;
+ }
+ bsdf_eval_mul(eval, 1.0f / probability);
+ }
+ }
+
+ if (ls->shader & SHADER_CAST_SHADOW) {
+ /* setup ray */
+ bool transmit = (dot(sd->Ng, ls->D) < 0.0f);
+ ray->P = ray_offset(sd->P, (transmit) ? -sd->Ng : sd->Ng);
+
+ if (ls->t == FLT_MAX) {
+ /* distant light */
+ ray->D = ls->D;
+ ray->t = ls->t;
+ }
+ else {
+ /* other lights, avoid self-intersection */
+ ray->D = ray_offset(ls->P, ls->Ng) - ray->P;
+ ray->D = normalize_len(ray->D, &ray->t);
+ }
+
+ ray->dP = sd->dP;
+ ray->dD = differential3_zero();
+ }
+ else {
+ /* signal to not cast shadow ray */
+ ray->t = 0.0f;
+ }
+
+ /* return if it's a lamp for shadow pass */
+ *is_lamp = (ls->prim == PRIM_NONE && ls->type != LIGHT_BACKGROUND);
+
+ return true;
}
/* Indirect Primitive Emission */
-ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
+ccl_device_noinline float3 indirect_primitive_emission(
+ KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
{
- /* evaluate emissive closure */
- float3 L = shader_emissive_eval(sd);
+ /* evaluate emissive closure */
+ float3 L = shader_emissive_eval(sd);
#ifdef __HAIR__
- if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE))
+ if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) &&
+ (sd->type & PRIMITIVE_ALL_TRIANGLE))
#else
- if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS))
+ if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS))
#endif
- {
- /* multiple importance sampling, get triangle light pdf,
- * and compute weight with respect to BSDF pdf */
- float pdf = triangle_light_pdf(kg, sd, t);
- float mis_weight = power_heuristic(bsdf_pdf, pdf);
+ {
+ /* multiple importance sampling, get triangle light pdf,
+ * and compute weight with respect to BSDF pdf */
+ float pdf = triangle_light_pdf(kg, sd, t);
+ float mis_weight = power_heuristic(bsdf_pdf, pdf);
- return L*mis_weight;
- }
+ return L * mis_weight;
+ }
- return L;
+ return L;
}
/* Indirect Lamp Emission */
@@ -229,60 +235,55 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg,
Ray *ray,
float3 *emission)
{
- bool hit_lamp = false;
+ bool hit_lamp = false;
- *emission = make_float3(0.0f, 0.0f, 0.0f);
+ *emission = make_float3(0.0f, 0.0f, 0.0f);
- for(int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
- LightSample ls;
+ for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
+ LightSample ls;
- if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
- continue;
+ if (!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
+ continue;
#ifdef __PASSES__
- /* use visibility flag to skip lights */
- if(ls.shader & SHADER_EXCLUDE_ANY) {
- if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
- ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
- ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) ||
- ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
- ((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
- continue;
- }
+ /* use visibility flag to skip lights */
+ if (ls.shader & SHADER_EXCLUDE_ANY) {
+ if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
+ ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
+ ((state->flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
+ (PATH_RAY_GLOSSY | PATH_RAY_REFLECT))) ||
+ ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
+ ((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
+ continue;
+ }
#endif
- float3 L = direct_emissive_eval(kg,
- emission_sd,
- &ls,
- state,
- -ray->D,
- ray->dD,
- ls.t,
- ray->time);
+ float3 L = direct_emissive_eval(
+ kg, emission_sd, &ls, state, -ray->D, ray->dD, ls.t, ray->time);
#ifdef __VOLUME__
- if(state->volume_stack[0].shader != SHADER_NONE) {
- /* shadow attenuation */
- Ray volume_ray = *ray;
- volume_ray.t = ls.t;
- float3 volume_tp = make_float3(1.0f, 1.0f, 1.0f);
- kernel_volume_shadow(kg, emission_sd, state, &volume_ray, &volume_tp);
- L *= volume_tp;
- }
+ if (state->volume_stack[0].shader != SHADER_NONE) {
+ /* shadow attenuation */
+ Ray volume_ray = *ray;
+ volume_ray.t = ls.t;
+ float3 volume_tp = make_float3(1.0f, 1.0f, 1.0f);
+ kernel_volume_shadow(kg, emission_sd, state, &volume_ray, &volume_tp);
+ L *= volume_tp;
+ }
#endif
- if(!(state->flag & PATH_RAY_MIS_SKIP)) {
- /* multiple importance sampling, get regular light pdf,
- * and compute weight with respect to BSDF pdf */
- float mis_weight = power_heuristic(state->ray_pdf, ls.pdf);
- L *= mis_weight;
- }
+ if (!(state->flag & PATH_RAY_MIS_SKIP)) {
+ /* multiple importance sampling, get regular light pdf,
+ * and compute weight with respect to BSDF pdf */
+ float mis_weight = power_heuristic(state->ray_pdf, ls.pdf);
+ L *= mis_weight;
+ }
- *emission += L;
- hit_lamp = true;
- }
+ *emission += L;
+ hit_lamp = true;
+ }
- return hit_lamp;
+ return hit_lamp;
}
/* Indirect Background */
@@ -293,55 +294,55 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
ccl_addr_space Ray *ray)
{
#ifdef __BACKGROUND__
- int shader = kernel_data.background.surface_shader;
-
- /* Use visibility flag to skip lights. */
- if(shader & SHADER_EXCLUDE_ANY) {
- if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
- ((shader & SHADER_EXCLUDE_GLOSSY) &&
- ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) ||
- ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
- ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) ||
- ((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-
-
- /* Evaluate background shader. */
- float3 L;
- if(!shader_constant_emission_eval(kg, shader, &L)) {
+ int shader = kernel_data.background.surface_shader;
+
+ /* Use visibility flag to skip lights. */
+ if (shader & SHADER_EXCLUDE_ANY) {
+ if (((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
+ ((shader & SHADER_EXCLUDE_GLOSSY) &&
+ ((state->flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
+ (PATH_RAY_GLOSSY | PATH_RAY_REFLECT))) ||
+ ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
+ ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) ||
+ ((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+
+ /* Evaluate background shader. */
+ float3 L;
+ if (!shader_constant_emission_eval(kg, shader, &L)) {
# ifdef __SPLIT_KERNEL__
- Ray priv_ray = *ray;
- shader_setup_from_background(kg, emission_sd, &priv_ray);
+ Ray priv_ray = *ray;
+ shader_setup_from_background(kg, emission_sd, &priv_ray);
# else
- shader_setup_from_background(kg, emission_sd, ray);
+ shader_setup_from_background(kg, emission_sd, ray);
# endif
- path_state_modify_bounce(state, true);
- shader_eval_surface(kg, emission_sd, state, state->flag | PATH_RAY_EMISSION);
- path_state_modify_bounce(state, false);
+ path_state_modify_bounce(state, true);
+ shader_eval_surface(kg, emission_sd, state, state->flag | PATH_RAY_EMISSION);
+ path_state_modify_bounce(state, false);
- L = shader_background_eval(emission_sd);
- }
+ L = shader_background_eval(emission_sd);
+ }
- /* Background MIS weights. */
-#ifdef __BACKGROUND_MIS__
- /* Check if background light exists or if we should skip pdf. */
- int res_x = kernel_data.integrator.pdf_background_res_x;
+ /* Background MIS weights. */
+# ifdef __BACKGROUND_MIS__
+ /* Check if background light exists or if we should skip pdf. */
+ int res_x = kernel_data.integrator.pdf_background_res_x;
- if(!(state->flag & PATH_RAY_MIS_SKIP) && res_x) {
- /* multiple importance sampling, get background light pdf for ray
- * direction, and compute weight with respect to BSDF pdf */
- float pdf = background_light_pdf(kg, ray->P, ray->D);
- float mis_weight = power_heuristic(state->ray_pdf, pdf);
+ if (!(state->flag & PATH_RAY_MIS_SKIP) && res_x) {
+ /* multiple importance sampling, get background light pdf for ray
+ * direction, and compute weight with respect to BSDF pdf */
+ float pdf = background_light_pdf(kg, ray->P, ray->D);
+ float mis_weight = power_heuristic(state->ray_pdf, pdf);
- return L*mis_weight;
- }
-#endif
+ return L * mis_weight;
+ }
+# endif
- return L;
+ return L;
#else
- return make_float3(0.8f, 0.8f, 0.8f);
+ return make_float3(0.8f, 0.8f, 0.8f);
#endif
}
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index b5f151d8663..d20f1adf663 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -18,72 +18,82 @@ CCL_NAMESPACE_BEGIN
ccl_device float4 film_map(KernelGlobals *kg, float4 irradiance, float scale)
{
- float exposure = kernel_data.film.exposure;
- float4 result = irradiance*scale;
+ float exposure = kernel_data.film.exposure;
+ float4 result = irradiance * scale;
- /* conversion to srgb */
- result.x = color_linear_to_srgb(result.x*exposure);
- result.y = color_linear_to_srgb(result.y*exposure);
- result.z = color_linear_to_srgb(result.z*exposure);
+ /* conversion to srgb */
+ result.x = color_linear_to_srgb(result.x * exposure);
+ result.y = color_linear_to_srgb(result.y * exposure);
+ result.z = color_linear_to_srgb(result.z * exposure);
- /* clamp since alpha might be > 1.0 due to russian roulette */
- result.w = saturate(result.w);
+ /* clamp since alpha might be > 1.0 due to russian roulette */
+ result.w = saturate(result.w);
- return result;
+ return result;
}
ccl_device uchar4 film_float_to_byte(float4 color)
{
- uchar4 result;
+ uchar4 result;
- /* simple float to byte conversion */
- result.x = (uchar)(saturate(color.x)*255.0f);
- result.y = (uchar)(saturate(color.y)*255.0f);
- result.z = (uchar)(saturate(color.z)*255.0f);
- result.w = (uchar)(saturate(color.w)*255.0f);
+ /* simple float to byte conversion */
+ result.x = (uchar)(saturate(color.x) * 255.0f);
+ result.y = (uchar)(saturate(color.y) * 255.0f);
+ result.z = (uchar)(saturate(color.z) * 255.0f);
+ result.w = (uchar)(saturate(color.w) * 255.0f);
- return result;
+ return result;
}
ccl_device void kernel_film_convert_to_byte(KernelGlobals *kg,
- ccl_global uchar4 *rgba, ccl_global float *buffer,
- float sample_scale, int x, int y, int offset, int stride)
+ ccl_global uchar4 *rgba,
+ ccl_global float *buffer,
+ float sample_scale,
+ int x,
+ int y,
+ int offset,
+ int stride)
{
- /* buffer offset */
- int index = offset + x + y*stride;
+ /* buffer offset */
+ int index = offset + x + y * stride;
- rgba += index;
- buffer += index*kernel_data.film.pass_stride;
+ rgba += index;
+ buffer += index * kernel_data.film.pass_stride;
- /* map colors */
- float4 irradiance = *((ccl_global float4*)buffer);
- float4 float_result = film_map(kg, irradiance, sample_scale);
- uchar4 byte_result = film_float_to_byte(float_result);
+ /* map colors */
+ float4 irradiance = *((ccl_global float4 *)buffer);
+ float4 float_result = film_map(kg, irradiance, sample_scale);
+ uchar4 byte_result = film_float_to_byte(float_result);
- *rgba = byte_result;
+ *rgba = byte_result;
}
ccl_device void kernel_film_convert_to_half_float(KernelGlobals *kg,
- ccl_global uchar4 *rgba, ccl_global float *buffer,
- float sample_scale, int x, int y, int offset, int stride)
+ ccl_global uchar4 *rgba,
+ ccl_global float *buffer,
+ float sample_scale,
+ int x,
+ int y,
+ int offset,
+ int stride)
{
- /* buffer offset */
- int index = offset + x + y*stride;
+ /* buffer offset */
+ int index = offset + x + y * stride;
- ccl_global float4 *in = (ccl_global float4*)(buffer + index*kernel_data.film.pass_stride);
- ccl_global half *out = (ccl_global half*)rgba + index*4;
+ ccl_global float4 *in = (ccl_global float4 *)(buffer + index * kernel_data.film.pass_stride);
+ ccl_global half *out = (ccl_global half *)rgba + index * 4;
- float exposure = kernel_data.film.exposure;
+ float exposure = kernel_data.film.exposure;
- float4 rgba_in = *in;
+ float4 rgba_in = *in;
- if(exposure != 1.0f) {
- rgba_in.x *= exposure;
- rgba_in.y *= exposure;
- rgba_in.z *= exposure;
- }
+ if (exposure != 1.0f) {
+ rgba_in.x *= exposure;
+ rgba_in.y *= exposure;
+ rgba_in.z *= exposure;
+ }
- float4_store_half(out, rgba_in, sample_scale);
+ float4_store_half(out, rgba_in, sample_scale);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h
index 59f1e252d21..9dbf3b7ea2e 100644
--- a/intern/cycles/kernel/kernel_globals.h
+++ b/intern/cycles/kernel/kernel_globals.h
@@ -54,41 +54,41 @@ typedef struct KernelGlobals {
# define KERNEL_TEX(type, name) texture<type> name;
# include "kernel/kernel_textures.h"
- KernelData __data;
+ KernelData __data;
# ifdef __OSL__
- /* On the CPU, we also have the OSL globals here. Most data structures are shared
- * with SVM, the difference is in the shaders and object/mesh attributes. */
- OSLGlobals *osl;
- OSLShadingSystem *osl_ss;
- OSLThreadData *osl_tdata;
+ /* On the CPU, we also have the OSL globals here. Most data structures are shared
+ * with SVM, the difference is in the shaders and object/mesh attributes. */
+ OSLGlobals *osl;
+ OSLShadingSystem *osl_ss;
+ OSLThreadData *osl_tdata;
# endif
- /* **** Run-time data **** */
+ /* **** Run-time data **** */
- /* Heap-allocated storage for transparent shadows intersections. */
- Intersection *transparent_shadow_intersections;
+ /* Heap-allocated storage for transparent shadows intersections. */
+ Intersection *transparent_shadow_intersections;
- /* Storage for decoupled volume steps. */
- VolumeStep *decoupled_volume_steps[2];
- int decoupled_volume_steps_index;
+ /* Storage for decoupled volume steps. */
+ VolumeStep *decoupled_volume_steps[2];
+ int decoupled_volume_steps_index;
- /* A buffer for storing per-pixel coverage for Cryptomatte. */
- CoverageMap *coverage_object;
- CoverageMap *coverage_material;
- CoverageMap *coverage_asset;
+ /* A buffer for storing per-pixel coverage for Cryptomatte. */
+ CoverageMap *coverage_object;
+ CoverageMap *coverage_material;
+ CoverageMap *coverage_asset;
- /* split kernel */
- SplitData split_data;
- SplitParams split_param_data;
+ /* split kernel */
+ SplitData split_data;
+ SplitParams split_param_data;
- int2 global_size;
- int2 global_id;
+ int2 global_size;
+ int2 global_id;
- ProfilingState profiler;
+ ProfilingState profiler;
} KernelGlobals;
-#endif /* __KERNEL_CPU__ */
+#endif /* __KERNEL_CPU__ */
/* For CUDA, constant memory textures must be globals, so we can't put them
* into a struct. As a result we don't actually use this struct and use actual
@@ -99,124 +99,117 @@ typedef struct KernelGlobals {
__constant__ KernelData __data;
typedef struct KernelGlobals {
- /* NOTE: Keep the size in sync with SHADOW_STACK_MAX_HITS. */
- Intersection hits_stack[64];
+ /* NOTE: Keep the size in sync with SHADOW_STACK_MAX_HITS. */
+ Intersection hits_stack[64];
} KernelGlobals;
# define KERNEL_TEX(type, name) const __constant__ __device__ type *name;
# include "kernel/kernel_textures.h"
-#endif /* __KERNEL_CUDA__ */
+#endif /* __KERNEL_CUDA__ */
/* OpenCL */
#ifdef __KERNEL_OPENCL__
-# define KERNEL_TEX(type, name) \
-typedef type name##_t;
+# define KERNEL_TEX(type, name) typedef type name##_t;
# include "kernel/kernel_textures.h"
typedef ccl_addr_space struct KernelGlobals {
- ccl_constant KernelData *data;
- ccl_global char *buffers[8];
+ ccl_constant KernelData *data;
+ ccl_global char *buffers[8];
-# define KERNEL_TEX(type, name) \
- TextureInfo name;
+# define KERNEL_TEX(type, name) TextureInfo name;
# include "kernel/kernel_textures.h"
# ifdef __SPLIT_KERNEL__
- SplitData split_data;
- SplitParams split_param_data;
+ SplitData split_data;
+ SplitParams split_param_data;
# endif
} KernelGlobals;
-#define KERNEL_BUFFER_PARAMS \
- ccl_global char *buffer0, \
- ccl_global char *buffer1, \
- ccl_global char *buffer2, \
- ccl_global char *buffer3, \
- ccl_global char *buffer4, \
- ccl_global char *buffer5, \
- ccl_global char *buffer6, \
- ccl_global char *buffer7
+# define KERNEL_BUFFER_PARAMS \
+ ccl_global char *buffer0, ccl_global char *buffer1, ccl_global char *buffer2, \
+ ccl_global char *buffer3, ccl_global char *buffer4, ccl_global char *buffer5, \
+ ccl_global char *buffer6, ccl_global char *buffer7
-#define KERNEL_BUFFER_ARGS buffer0, buffer1, buffer2, buffer3, buffer4, buffer5, buffer6, buffer7
+# define KERNEL_BUFFER_ARGS buffer0, buffer1, buffer2, buffer3, buffer4, buffer5, buffer6, buffer7
ccl_device_inline void kernel_set_buffer_pointers(KernelGlobals *kg, KERNEL_BUFFER_PARAMS)
{
-#ifdef __SPLIT_KERNEL__
- if(ccl_local_id(0) + ccl_local_id(1) == 0)
-#endif
- {
- kg->buffers[0] = buffer0;
- kg->buffers[1] = buffer1;
- kg->buffers[2] = buffer2;
- kg->buffers[3] = buffer3;
- kg->buffers[4] = buffer4;
- kg->buffers[5] = buffer5;
- kg->buffers[6] = buffer6;
- kg->buffers[7] = buffer7;
- }
+# ifdef __SPLIT_KERNEL__
+ if (ccl_local_id(0) + ccl_local_id(1) == 0)
+# endif
+ {
+ kg->buffers[0] = buffer0;
+ kg->buffers[1] = buffer1;
+ kg->buffers[2] = buffer2;
+ kg->buffers[3] = buffer3;
+ kg->buffers[4] = buffer4;
+ kg->buffers[5] = buffer5;
+ kg->buffers[6] = buffer6;
+ kg->buffers[7] = buffer7;
+ }
# ifdef __SPLIT_KERNEL__
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
# endif
}
ccl_device_inline void kernel_set_buffer_info(KernelGlobals *kg)
{
# ifdef __SPLIT_KERNEL__
- if(ccl_local_id(0) + ccl_local_id(1) == 0)
+ if (ccl_local_id(0) + ccl_local_id(1) == 0)
# endif
- {
- ccl_global TextureInfo *info = (ccl_global TextureInfo*)kg->buffers[0];
+ {
+ ccl_global TextureInfo *info = (ccl_global TextureInfo *)kg->buffers[0];
-# define KERNEL_TEX(type, name) \
- kg->name = *(info++);
+# define KERNEL_TEX(type, name) kg->name = *(info++);
# include "kernel/kernel_textures.h"
- }
+ }
# ifdef __SPLIT_KERNEL__
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
# endif
}
-#endif /* __KERNEL_OPENCL__ */
+#endif /* __KERNEL_OPENCL__ */
/* Interpolated lookup table access */
ccl_device float lookup_table_read(KernelGlobals *kg, float x, int offset, int size)
{
- x = saturate(x)*(size-1);
+ x = saturate(x) * (size - 1);
- int index = min(float_to_int(x), size-1);
- int nindex = min(index+1, size-1);
- float t = x - index;
+ int index = min(float_to_int(x), size - 1);
+ int nindex = min(index + 1, size - 1);
+ float t = x - index;
- float data0 = kernel_tex_fetch(__lookup_table, index + offset);
- if(t == 0.0f)
- return data0;
+ float data0 = kernel_tex_fetch(__lookup_table, index + offset);
+ if (t == 0.0f)
+ return data0;
- float data1 = kernel_tex_fetch(__lookup_table, nindex + offset);
- return (1.0f - t)*data0 + t*data1;
+ float data1 = kernel_tex_fetch(__lookup_table, nindex + offset);
+ return (1.0f - t) * data0 + t * data1;
}
-ccl_device float lookup_table_read_2D(KernelGlobals *kg, float x, float y, int offset, int xsize, int ysize)
+ccl_device float lookup_table_read_2D(
+ KernelGlobals *kg, float x, float y, int offset, int xsize, int ysize)
{
- y = saturate(y)*(ysize-1);
+ y = saturate(y) * (ysize - 1);
- int index = min(float_to_int(y), ysize-1);
- int nindex = min(index+1, ysize-1);
- float t = y - index;
+ int index = min(float_to_int(y), ysize - 1);
+ int nindex = min(index + 1, ysize - 1);
+ float t = y - index;
- float data0 = lookup_table_read(kg, x, offset + xsize*index, xsize);
- if(t == 0.0f)
- return data0;
+ float data0 = lookup_table_read(kg, x, offset + xsize * index, xsize);
+ if (t == 0.0f)
+ return data0;
- float data1 = lookup_table_read(kg, x, offset + xsize*nindex, xsize);
- return (1.0f - t)*data0 + t*data1;
+ float data1 = lookup_table_read(kg, x, offset + xsize * nindex, xsize);
+ return (1.0f - t) * data0 + t * data1;
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_GLOBALS_H__ */
+#endif /* __KERNEL_GLOBALS_H__ */
diff --git a/intern/cycles/kernel/kernel_id_passes.h b/intern/cycles/kernel/kernel_id_passes.h
index 0cd65b1f2e8..c1f4e39e5e7 100644
--- a/intern/cycles/kernel/kernel_id_passes.h
+++ b/intern/cycles/kernel/kernel_id_passes.h
@@ -16,78 +16,83 @@
CCL_NAMESPACE_BEGIN
-ccl_device_inline void kernel_write_id_slots(ccl_global float *buffer, int num_slots, float id, float weight)
+ccl_device_inline void kernel_write_id_slots(ccl_global float *buffer,
+ int num_slots,
+ float id,
+ float weight)
{
- kernel_assert(id != ID_NONE);
- if(weight == 0.0f) {
- return;
- }
+ kernel_assert(id != ID_NONE);
+ if (weight == 0.0f) {
+ return;
+ }
- for(int slot = 0; slot < num_slots; slot++) {
- ccl_global float2 *id_buffer = (ccl_global float2*)buffer;
+ for (int slot = 0; slot < num_slots; slot++) {
+ ccl_global float2 *id_buffer = (ccl_global float2 *)buffer;
#ifdef __ATOMIC_PASS_WRITE__
- /* If the loop reaches an empty slot, the ID isn't in any slot yet - so add it! */
- if(id_buffer[slot].x == ID_NONE) {
- /* Use an atomic to claim this slot.
- * If a different thread got here first, try again from this slot on. */
- float old_id = atomic_compare_and_swap_float(buffer+slot*2, ID_NONE, id);
- if(old_id != ID_NONE && old_id != id) {
- continue;
- }
- atomic_add_and_fetch_float(buffer+slot*2+1, weight);
- break;
- }
- /* If there already is a slot for that ID, add the weight.
- * If no slot was found, add it to the last. */
- else if(id_buffer[slot].x == id || slot == num_slots - 1) {
- atomic_add_and_fetch_float(buffer+slot*2+1, weight);
- break;
- }
+ /* If the loop reaches an empty slot, the ID isn't in any slot yet - so add it! */
+ if (id_buffer[slot].x == ID_NONE) {
+ /* Use an atomic to claim this slot.
+ * If a different thread got here first, try again from this slot on. */
+ float old_id = atomic_compare_and_swap_float(buffer + slot * 2, ID_NONE, id);
+ if (old_id != ID_NONE && old_id != id) {
+ continue;
+ }
+ atomic_add_and_fetch_float(buffer + slot * 2 + 1, weight);
+ break;
+ }
+ /* If there already is a slot for that ID, add the weight.
+ * If no slot was found, add it to the last. */
+ else if (id_buffer[slot].x == id || slot == num_slots - 1) {
+ atomic_add_and_fetch_float(buffer + slot * 2 + 1, weight);
+ break;
+ }
#else /* __ATOMIC_PASS_WRITE__ */
- /* If the loop reaches an empty slot, the ID isn't in any slot yet - so add it! */
- if(id_buffer[slot].x == ID_NONE) {
- id_buffer[slot].x = id;
- id_buffer[slot].y = weight;
- break;
- }
- /* If there already is a slot for that ID, add the weight.
- * If no slot was found, add it to the last. */
- else if(id_buffer[slot].x == id || slot == num_slots - 1) {
- id_buffer[slot].y += weight;
- break;
- }
-#endif /* __ATOMIC_PASS_WRITE__ */
- }
+ /* If the loop reaches an empty slot, the ID isn't in any slot yet - so add it! */
+ if (id_buffer[slot].x == ID_NONE) {
+ id_buffer[slot].x = id;
+ id_buffer[slot].y = weight;
+ break;
+ }
+ /* If there already is a slot for that ID, add the weight.
+ * If no slot was found, add it to the last. */
+ else if (id_buffer[slot].x == id || slot == num_slots - 1) {
+ id_buffer[slot].y += weight;
+ break;
+ }
+#endif /* __ATOMIC_PASS_WRITE__ */
+ }
}
ccl_device_inline void kernel_sort_id_slots(ccl_global float *buffer, int num_slots)
{
- ccl_global float2 *id_buffer = (ccl_global float2*)buffer;
- for(int slot = 1; slot < num_slots; ++slot) {
- if(id_buffer[slot].x == ID_NONE) {
- return;
- }
- /* Since we're dealing with a tiny number of elements, insertion sort should be fine. */
- int i = slot;
- while(i > 0 && id_buffer[i].y > id_buffer[i - 1].y) {
- float2 swap = id_buffer[i];
- id_buffer[i] = id_buffer[i - 1];
- id_buffer[i - 1] = swap;
- --i;
- }
- }
+ ccl_global float2 *id_buffer = (ccl_global float2 *)buffer;
+ for (int slot = 1; slot < num_slots; ++slot) {
+ if (id_buffer[slot].x == ID_NONE) {
+ return;
+ }
+ /* Since we're dealing with a tiny number of elements, insertion sort should be fine. */
+ int i = slot;
+ while (i > 0 && id_buffer[i].y > id_buffer[i - 1].y) {
+ float2 swap = id_buffer[i];
+ id_buffer[i] = id_buffer[i - 1];
+ id_buffer[i - 1] = swap;
+ --i;
+ }
+ }
}
#ifdef __KERNEL_GPU__
/* post-sorting for Cryptomatte */
-ccl_device void kernel_cryptomatte_post(KernelGlobals *kg, ccl_global float *buffer, uint sample, int x, int y, int offset, int stride)
+ccl_device void kernel_cryptomatte_post(
+ KernelGlobals *kg, ccl_global float *buffer, uint sample, int x, int y, int offset, int stride)
{
- if(sample - 1 == kernel_data.integrator.aa_samples) {
- int index = offset + x + y * stride;
- int pass_stride = kernel_data.film.pass_stride;
- ccl_global float *cryptomatte_buffer = buffer + index * pass_stride + kernel_data.film.pass_cryptomatte;
- kernel_sort_id_slots(cryptomatte_buffer, 2 * kernel_data.film.cryptomatte_depth);
- }
+ if (sample - 1 == kernel_data.integrator.aa_samples) {
+ int index = offset + x + y * stride;
+ int pass_stride = kernel_data.film.pass_stride;
+ ccl_global float *cryptomatte_buffer = buffer + index * pass_stride +
+ kernel_data.film.pass_cryptomatte;
+ kernel_sort_id_slots(cryptomatte_buffer, 2 * kernel_data.film.cryptomatte_depth);
+ }
}
#endif
diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h
index 3bde96b078c..f7270a14940 100644
--- a/intern/cycles/kernel/kernel_jitter.h
+++ b/intern/cycles/kernel/kernel_jitter.h
@@ -26,202 +26,202 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline bool cmj_is_pow2(int i)
{
- return (i > 1) && ((i & (i - 1)) == 0);
+ return (i > 1) && ((i & (i - 1)) == 0);
}
ccl_device_inline int cmj_fast_mod_pow2(int a, int b)
{
- return (a & (b - 1));
+ return (a & (b - 1));
}
/* b must be > 1 */
ccl_device_inline int cmj_fast_div_pow2(int a, int b)
{
- kernel_assert(b > 1);
+ kernel_assert(b > 1);
#if defined(__KERNEL_SSE2__)
# ifdef _MSC_VER
- unsigned long ctz;
- _BitScanForward(&ctz, b);
- return a >> ctz;
+ unsigned long ctz;
+ _BitScanForward(&ctz, b);
+ return a >> ctz;
# else
- return a >> __builtin_ctz(b);
+ return a >> __builtin_ctz(b);
# endif
#elif defined(__KERNEL_CUDA__)
- return a >> (__ffs(b) - 1);
+ return a >> (__ffs(b) - 1);
#else
- return a/b;
+ return a / b;
#endif
}
ccl_device_inline uint cmj_w_mask(uint w)
{
- kernel_assert(w > 1);
+ kernel_assert(w > 1);
#if defined(__KERNEL_SSE2__)
# ifdef _MSC_VER
- unsigned long leading_zero;
- _BitScanReverse(&leading_zero, w);
- return ((1 << (1 + leading_zero)) - 1);
+ unsigned long leading_zero;
+ _BitScanReverse(&leading_zero, w);
+ return ((1 << (1 + leading_zero)) - 1);
# else
- return ((1 << (32 - __builtin_clz(w))) - 1);
+ return ((1 << (32 - __builtin_clz(w))) - 1);
# endif
#elif defined(__KERNEL_CUDA__)
- return ((1 << (32 - __clz(w))) - 1);
+ return ((1 << (32 - __clz(w))) - 1);
#else
- w |= w >> 1;
- w |= w >> 2;
- w |= w >> 4;
- w |= w >> 8;
- w |= w >> 16;
+ w |= w >> 1;
+ w |= w >> 2;
+ w |= w >> 4;
+ w |= w >> 8;
+ w |= w >> 16;
- return w;
+ return w;
#endif
}
ccl_device_inline uint cmj_permute(uint i, uint l, uint p)
{
- uint w = l - 1;
-
- if((l & w) == 0) {
- /* l is a power of two (fast) */
- i ^= p;
- i *= 0xe170893d;
- i ^= p >> 16;
- i ^= (i & w) >> 4;
- i ^= p >> 8;
- i *= 0x0929eb3f;
- i ^= p >> 23;
- i ^= (i & w) >> 1;
- i *= 1 | p >> 27;
- i *= 0x6935fa69;
- i ^= (i & w) >> 11;
- i *= 0x74dcb303;
- i ^= (i & w) >> 2;
- i *= 0x9e501cc3;
- i ^= (i & w) >> 2;
- i *= 0xc860a3df;
- i &= w;
- i ^= i >> 5;
-
- return (i + p) & w;
- }
- else {
- /* l is not a power of two (slow) */
- w = cmj_w_mask(w);
-
- do {
- i ^= p;
- i *= 0xe170893d;
- i ^= p >> 16;
- i ^= (i & w) >> 4;
- i ^= p >> 8;
- i *= 0x0929eb3f;
- i ^= p >> 23;
- i ^= (i & w) >> 1;
- i *= 1 | p >> 27;
- i *= 0x6935fa69;
- i ^= (i & w) >> 11;
- i *= 0x74dcb303;
- i ^= (i & w) >> 2;
- i *= 0x9e501cc3;
- i ^= (i & w) >> 2;
- i *= 0xc860a3df;
- i &= w;
- i ^= i >> 5;
- } while(i >= l);
-
- return (i + p) % l;
- }
+ uint w = l - 1;
+
+ if ((l & w) == 0) {
+ /* l is a power of two (fast) */
+ i ^= p;
+ i *= 0xe170893d;
+ i ^= p >> 16;
+ i ^= (i & w) >> 4;
+ i ^= p >> 8;
+ i *= 0x0929eb3f;
+ i ^= p >> 23;
+ i ^= (i & w) >> 1;
+ i *= 1 | p >> 27;
+ i *= 0x6935fa69;
+ i ^= (i & w) >> 11;
+ i *= 0x74dcb303;
+ i ^= (i & w) >> 2;
+ i *= 0x9e501cc3;
+ i ^= (i & w) >> 2;
+ i *= 0xc860a3df;
+ i &= w;
+ i ^= i >> 5;
+
+ return (i + p) & w;
+ }
+ else {
+ /* l is not a power of two (slow) */
+ w = cmj_w_mask(w);
+
+ do {
+ i ^= p;
+ i *= 0xe170893d;
+ i ^= p >> 16;
+ i ^= (i & w) >> 4;
+ i ^= p >> 8;
+ i *= 0x0929eb3f;
+ i ^= p >> 23;
+ i ^= (i & w) >> 1;
+ i *= 1 | p >> 27;
+ i *= 0x6935fa69;
+ i ^= (i & w) >> 11;
+ i *= 0x74dcb303;
+ i ^= (i & w) >> 2;
+ i *= 0x9e501cc3;
+ i ^= (i & w) >> 2;
+ i *= 0xc860a3df;
+ i &= w;
+ i ^= i >> 5;
+ } while (i >= l);
+
+ return (i + p) % l;
+ }
}
ccl_device_inline uint cmj_hash(uint i, uint p)
{
- i ^= p;
- i ^= i >> 17;
- i ^= i >> 10;
- i *= 0xb36534e5;
- i ^= i >> 12;
- i ^= i >> 21;
- i *= 0x93fc4795;
- i ^= 0xdf6e307f;
- i ^= i >> 17;
- i *= 1 | p >> 18;
-
- return i;
+ i ^= p;
+ i ^= i >> 17;
+ i ^= i >> 10;
+ i *= 0xb36534e5;
+ i ^= i >> 12;
+ i ^= i >> 21;
+ i *= 0x93fc4795;
+ i ^= 0xdf6e307f;
+ i ^= i >> 17;
+ i *= 1 | p >> 18;
+
+ return i;
}
ccl_device_inline uint cmj_hash_simple(uint i, uint p)
{
- i = (i ^ 61) ^ p;
- i += i << 3;
- i ^= i >> 4;
- i *= 0x27d4eb2d;
- return i;
+ i = (i ^ 61) ^ p;
+ i += i << 3;
+ i ^= i >> 4;
+ i *= 0x27d4eb2d;
+ return i;
}
ccl_device_inline float cmj_randfloat(uint i, uint p)
{
- return cmj_hash(i, p) * (1.0f / 4294967808.0f);
+ return cmj_hash(i, p) * (1.0f / 4294967808.0f);
}
#ifdef __CMJ__
ccl_device float cmj_sample_1D(int s, int N, int p)
{
- kernel_assert(s < N);
+ kernel_assert(s < N);
- uint x = cmj_permute(s, N, p * 0x68bc21eb);
- float jx = cmj_randfloat(s, p * 0x967a889b);
+ uint x = cmj_permute(s, N, p * 0x68bc21eb);
+ float jx = cmj_randfloat(s, p * 0x967a889b);
- float invN = 1.0f/N;
- return (x + jx)*invN;
+ float invN = 1.0f / N;
+ return (x + jx) * invN;
}
/* TODO(sergey): Do some extra tests and consider moving to util_math.h. */
ccl_device_inline int cmj_isqrt(int value)
{
-#if defined(__KERNEL_CUDA__)
- return float_to_int(__fsqrt_ru(value));
-#elif defined(__KERNEL_GPU__)
- return float_to_int(sqrtf(value));
-#else
- /* This is a work around for fast-math on CPU which might replace sqrtf()
- * with am approximated version.
- */
- return float_to_int(sqrtf(value) + 1e-6f);
-#endif
+# if defined(__KERNEL_CUDA__)
+ return float_to_int(__fsqrt_ru(value));
+# elif defined(__KERNEL_GPU__)
+ return float_to_int(sqrtf(value));
+# else
+ /* This is a work around for fast-math on CPU which might replace sqrtf()
+ * with am approximated version.
+ */
+ return float_to_int(sqrtf(value) + 1e-6f);
+# endif
}
ccl_device void cmj_sample_2D(int s, int N, int p, float *fx, float *fy)
{
- kernel_assert(s < N);
+ kernel_assert(s < N);
- int m = cmj_isqrt(N);
- int n = (N - 1)/m + 1;
- float invN = 1.0f/N;
- float invm = 1.0f/m;
- float invn = 1.0f/n;
+ int m = cmj_isqrt(N);
+ int n = (N - 1) / m + 1;
+ float invN = 1.0f / N;
+ float invm = 1.0f / m;
+ float invn = 1.0f / n;
- s = cmj_permute(s, N, p * 0x51633e2d);
+ s = cmj_permute(s, N, p * 0x51633e2d);
- int sdivm, smodm;
+ int sdivm, smodm;
- if(cmj_is_pow2(m)) {
- sdivm = cmj_fast_div_pow2(s, m);
- smodm = cmj_fast_mod_pow2(s, m);
- }
- else {
- /* Doing s*inmv gives precision issues here. */
- sdivm = s / m;
- smodm = s - sdivm*m;
- }
+ if (cmj_is_pow2(m)) {
+ sdivm = cmj_fast_div_pow2(s, m);
+ smodm = cmj_fast_mod_pow2(s, m);
+ }
+ else {
+ /* Doing s*inmv gives precision issues here. */
+ sdivm = s / m;
+ smodm = s - sdivm * m;
+ }
- uint sx = cmj_permute(smodm, m, p * 0x68bc21eb);
- uint sy = cmj_permute(sdivm, n, p * 0x02e5be93);
+ uint sx = cmj_permute(smodm, m, p * 0x68bc21eb);
+ uint sy = cmj_permute(sdivm, n, p * 0x02e5be93);
- float jx = cmj_randfloat(s, p * 0x967a889b);
- float jy = cmj_randfloat(s, p * 0x368cc8b7);
+ float jx = cmj_randfloat(s, p * 0x967a889b);
+ float jy = cmj_randfloat(s, p * 0x368cc8b7);
- *fx = (sx + (sy + jx)*invn)*invm;
- *fy = (s + jy)*invN;
+ *fx = (sx + (sy + jx) * invn) * invm;
+ *fy = (s + jy) * invN;
}
#endif
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 262d7df1364..5e24f8dedaf 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -19,18 +19,18 @@ CCL_NAMESPACE_BEGIN
/* Light Sample result */
typedef struct LightSample {
- float3 P; /* position on light, or direction for distant light */
- float3 Ng; /* normal on light */
- float3 D; /* direction from shading point to light */
- float t; /* distance to light (FLT_MAX for distant light) */
- float u, v; /* parametric coordinate on primitive */
- float pdf; /* light sampling probability density function */
- float eval_fac; /* intensity multiplier */
- int object; /* object id for triangle/curve lights */
- int prim; /* primitive id for triangle/curve lights */
- int shader; /* shader id */
- int lamp; /* lamp id */
- LightType type; /* type of light */
+ float3 P; /* position on light, or direction for distant light */
+ float3 Ng; /* normal on light */
+ float3 D; /* direction from shading point to light */
+ float t; /* distance to light (FLT_MAX for distant light) */
+ float u, v; /* parametric coordinate on primitive */
+ float pdf; /* light sampling probability density function */
+ float eval_fac; /* intensity multiplier */
+ int object; /* object id for triangle/curve lights */
+ int prim; /* primitive id for triangle/curve lights */
+ int shader; /* shader id */
+ int lamp; /* lamp id */
+ LightType type; /* type of light */
} LightSample;
/* Area light sampling */
@@ -46,130 +46,136 @@ typedef struct LightSample {
*/
ccl_device_inline float rect_light_sample(float3 P,
float3 *light_p,
- float3 axisu, float3 axisv,
- float randu, float randv,
+ float3 axisu,
+ float3 axisv,
+ float randu,
+ float randv,
bool sample_coord)
{
- /* In our name system we're using P for the center,
- * which is o in the paper.
- */
-
- float3 corner = *light_p - axisu * 0.5f - axisv * 0.5f;
- float axisu_len, axisv_len;
- /* Compute local reference system R. */
- float3 x = normalize_len(axisu, &axisu_len);
- float3 y = normalize_len(axisv, &axisv_len);
- float3 z = cross(x, y);
- /* Compute rectangle coords in local reference system. */
- float3 dir = corner - P;
- float z0 = dot(dir, z);
- /* Flip 'z' to make it point against Q. */
- if(z0 > 0.0f) {
- z *= -1.0f;
- z0 *= -1.0f;
- }
- float x0 = dot(dir, x);
- float y0 = dot(dir, y);
- float x1 = x0 + axisu_len;
- float y1 = y0 + axisv_len;
- /* Compute internal angles (gamma_i). */
- float4 diff = make_float4(x0, y1, x1, y0) - make_float4(x1, y0, x0, y1);
- float4 nz = make_float4(y0, x1, y1, x0) * diff;
- nz = nz / sqrt(z0 * z0 * diff * diff + nz * nz);
- float g0 = safe_acosf(-nz.x * nz.y);
- float g1 = safe_acosf(-nz.y * nz.z);
- float g2 = safe_acosf(-nz.z * nz.w);
- float g3 = safe_acosf(-nz.w * nz.x);
- /* Compute predefined constants. */
- float b0 = nz.x;
- float b1 = nz.z;
- float b0sq = b0 * b0;
- float k = M_2PI_F - g2 - g3;
- /* Compute solid angle from internal angles. */
- float S = g0 + g1 - k;
-
- if(sample_coord) {
- /* Compute cu. */
- float au = randu * S + k;
- float fu = (cosf(au) * b0 - b1) / sinf(au);
- float cu = 1.0f / sqrtf(fu * fu + b0sq) * (fu > 0.0f ? 1.0f : -1.0f);
- cu = clamp(cu, -1.0f, 1.0f);
- /* Compute xu. */
- float xu = -(cu * z0) / max(sqrtf(1.0f - cu * cu), 1e-7f);
- xu = clamp(xu, x0, x1);
- /* Compute yv. */
- float z0sq = z0 * z0;
- float y0sq = y0 * y0;
- float y1sq = y1 * y1;
- float d = sqrtf(xu * xu + z0sq);
- float h0 = y0 / sqrtf(d * d + y0sq);
- float h1 = y1 / sqrtf(d * d + y1sq);
- float hv = h0 + randv * (h1 - h0), hv2 = hv * hv;
- float yv = (hv2 < 1.0f - 1e-6f) ? (hv * d) / sqrtf(1.0f - hv2) : y1;
-
- /* Transform (xu, yv, z0) to world coords. */
- *light_p = P + xu * x + yv * y + z0 * z;
- }
-
- /* return pdf */
- if(S != 0.0f)
- return 1.0f / S;
- else
- return 0.0f;
+ /* In our name system we're using P for the center,
+ * which is o in the paper.
+ */
+
+ float3 corner = *light_p - axisu * 0.5f - axisv * 0.5f;
+ float axisu_len, axisv_len;
+ /* Compute local reference system R. */
+ float3 x = normalize_len(axisu, &axisu_len);
+ float3 y = normalize_len(axisv, &axisv_len);
+ float3 z = cross(x, y);
+ /* Compute rectangle coords in local reference system. */
+ float3 dir = corner - P;
+ float z0 = dot(dir, z);
+ /* Flip 'z' to make it point against Q. */
+ if (z0 > 0.0f) {
+ z *= -1.0f;
+ z0 *= -1.0f;
+ }
+ float x0 = dot(dir, x);
+ float y0 = dot(dir, y);
+ float x1 = x0 + axisu_len;
+ float y1 = y0 + axisv_len;
+ /* Compute internal angles (gamma_i). */
+ float4 diff = make_float4(x0, y1, x1, y0) - make_float4(x1, y0, x0, y1);
+ float4 nz = make_float4(y0, x1, y1, x0) * diff;
+ nz = nz / sqrt(z0 * z0 * diff * diff + nz * nz);
+ float g0 = safe_acosf(-nz.x * nz.y);
+ float g1 = safe_acosf(-nz.y * nz.z);
+ float g2 = safe_acosf(-nz.z * nz.w);
+ float g3 = safe_acosf(-nz.w * nz.x);
+ /* Compute predefined constants. */
+ float b0 = nz.x;
+ float b1 = nz.z;
+ float b0sq = b0 * b0;
+ float k = M_2PI_F - g2 - g3;
+ /* Compute solid angle from internal angles. */
+ float S = g0 + g1 - k;
+
+ if (sample_coord) {
+ /* Compute cu. */
+ float au = randu * S + k;
+ float fu = (cosf(au) * b0 - b1) / sinf(au);
+ float cu = 1.0f / sqrtf(fu * fu + b0sq) * (fu > 0.0f ? 1.0f : -1.0f);
+ cu = clamp(cu, -1.0f, 1.0f);
+ /* Compute xu. */
+ float xu = -(cu * z0) / max(sqrtf(1.0f - cu * cu), 1e-7f);
+ xu = clamp(xu, x0, x1);
+ /* Compute yv. */
+ float z0sq = z0 * z0;
+ float y0sq = y0 * y0;
+ float y1sq = y1 * y1;
+ float d = sqrtf(xu * xu + z0sq);
+ float h0 = y0 / sqrtf(d * d + y0sq);
+ float h1 = y1 / sqrtf(d * d + y1sq);
+ float hv = h0 + randv * (h1 - h0), hv2 = hv * hv;
+ float yv = (hv2 < 1.0f - 1e-6f) ? (hv * d) / sqrtf(1.0f - hv2) : y1;
+
+ /* Transform (xu, yv, z0) to world coords. */
+ *light_p = P + xu * x + yv * y + z0 * z;
+ }
+
+ /* return pdf */
+ if (S != 0.0f)
+ return 1.0f / S;
+ else
+ return 0.0f;
}
ccl_device_inline float3 ellipse_sample(float3 ru, float3 rv, float randu, float randv)
{
- to_unit_disk(&randu, &randv);
- return ru*randu + rv*randv;
+ to_unit_disk(&randu, &randv);
+ return ru * randu + rv * randv;
}
ccl_device float3 disk_light_sample(float3 v, float randu, float randv)
{
- float3 ru, rv;
+ float3 ru, rv;
- make_orthonormals(v, &ru, &rv);
+ make_orthonormals(v, &ru, &rv);
- return ellipse_sample(ru, rv, randu, randv);
+ return ellipse_sample(ru, rv, randu, randv);
}
ccl_device float3 distant_light_sample(float3 D, float radius, float randu, float randv)
{
- return normalize(D + disk_light_sample(D, randu, randv)*radius);
+ return normalize(D + disk_light_sample(D, randu, randv) * radius);
}
-ccl_device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
+ccl_device float3
+sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
{
- return disk_light_sample(normalize(P - center), randu, randv)*radius;
+ return disk_light_sample(normalize(P - center), randu, randv) * radius;
}
-ccl_device float spot_light_attenuation(float3 dir, float spot_angle, float spot_smooth, LightSample *ls)
+ccl_device float spot_light_attenuation(float3 dir,
+ float spot_angle,
+ float spot_smooth,
+ LightSample *ls)
{
- float3 I = ls->Ng;
+ float3 I = ls->Ng;
- float attenuation = dot(dir, I);
+ float attenuation = dot(dir, I);
- if(attenuation <= spot_angle) {
- attenuation = 0.0f;
- }
- else {
- float t = attenuation - spot_angle;
+ if (attenuation <= spot_angle) {
+ attenuation = 0.0f;
+ }
+ else {
+ float t = attenuation - spot_angle;
- if(t < spot_smooth && spot_smooth != 0.0f)
- attenuation *= smoothstepf(t/spot_smooth);
- }
+ if (t < spot_smooth && spot_smooth != 0.0f)
+ attenuation *= smoothstepf(t / spot_smooth);
+ }
- return attenuation;
+ return attenuation;
}
ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
{
- float cos_pi = dot(Ng, I);
+ float cos_pi = dot(Ng, I);
- if(cos_pi <= 0.0f)
- return 0.0f;
+ if (cos_pi <= 0.0f)
+ return 0.0f;
- return t*t/cos_pi;
+ return t * t / cos_pi;
}
/* Background Light */
@@ -180,203 +186,219 @@ ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3
* devices, but we're so close to the release so better not screw things
* up for CPU at least.
*/
-#ifdef __KERNEL_GPU__
+# ifdef __KERNEL_GPU__
ccl_device_noinline
-#else
+# else
ccl_device
-#endif
-float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
+# endif
+ float3
+ background_map_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
{
- /* for the following, the CDF values are actually a pair of floats, with the
- * function value as X and the actual CDF as Y. The last entry's function
- * value is the CDF total. */
- int res_x = kernel_data.integrator.pdf_background_res_x;
- int res_y = kernel_data.integrator.pdf_background_res_y;
- int cdf_width = res_x + 1;
-
- /* this is basically std::lower_bound as used by pbrt */
- int first = 0;
- int count = res_y;
-
- while(count > 0) {
- int step = count >> 1;
- int middle = first + step;
-
- if(kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) {
- first = middle + 1;
- count -= step + 1;
- }
- else
- count = step;
- }
-
- int index_v = max(0, first - 1);
- kernel_assert(index_v >= 0 && index_v < res_y);
-
- float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
- float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
-
- /* importance-sampled V direction */
- float dv = inverse_lerp(cdf_v.y, cdf_next_v.y, randv);
- float v = (index_v + dv) / res_y;
-
- /* this is basically std::lower_bound as used by pbrt */
- first = 0;
- count = res_x;
- while(count > 0) {
- int step = count >> 1;
- int middle = first + step;
-
- if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + middle).y < randu) {
- first = middle + 1;
- count -= step + 1;
- }
- else
- count = step;
- }
-
- int index_u = max(0, first - 1);
- kernel_assert(index_u >= 0 && index_u < res_x);
-
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u);
- float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u + 1);
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x);
-
- /* importance-sampled U direction */
- float du = inverse_lerp(cdf_u.y, cdf_next_u.y, randu);
- float u = (index_u + du) / res_x;
-
- /* compute pdf */
- float denom = cdf_last_u.x * cdf_last_v.x;
- float sin_theta = sinf(M_PI_F * v);
-
- if(sin_theta == 0.0f || denom == 0.0f)
- *pdf = 0.0f;
- else
- *pdf = (cdf_u.x * cdf_v.x)/(M_2PI_F * M_PI_F * sin_theta * denom);
-
- /* compute direction */
- return equirectangular_to_direction(u, v);
+ /* for the following, the CDF values are actually a pair of floats, with the
+ * function value as X and the actual CDF as Y. The last entry's function
+ * value is the CDF total. */
+ int res_x = kernel_data.integrator.pdf_background_res_x;
+ int res_y = kernel_data.integrator.pdf_background_res_y;
+ int cdf_width = res_x + 1;
+
+ /* this is basically std::lower_bound as used by pbrt */
+ int first = 0;
+ int count = res_y;
+
+ while (count > 0) {
+ int step = count >> 1;
+ int middle = first + step;
+
+ if (kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) {
+ first = middle + 1;
+ count -= step + 1;
+ }
+ else
+ count = step;
+ }
+
+ int index_v = max(0, first - 1);
+ kernel_assert(index_v >= 0 && index_v < res_y);
+
+ float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
+ float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1);
+ float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
+
+ /* importance-sampled V direction */
+ float dv = inverse_lerp(cdf_v.y, cdf_next_v.y, randv);
+ float v = (index_v + dv) / res_y;
+
+ /* this is basically std::lower_bound as used by pbrt */
+ first = 0;
+ count = res_x;
+ while (count > 0) {
+ int step = count >> 1;
+ int middle = first + step;
+
+ if (kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + middle).y <
+ randu) {
+ first = middle + 1;
+ count -= step + 1;
+ }
+ else
+ count = step;
+ }
+
+ int index_u = max(0, first - 1);
+ kernel_assert(index_u >= 0 && index_u < res_x);
+
+ float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf,
+ index_v * cdf_width + index_u);
+ float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf,
+ index_v * cdf_width + index_u + 1);
+ float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf,
+ index_v * cdf_width + res_x);
+
+ /* importance-sampled U direction */
+ float du = inverse_lerp(cdf_u.y, cdf_next_u.y, randu);
+ float u = (index_u + du) / res_x;
+
+ /* compute pdf */
+ float denom = cdf_last_u.x * cdf_last_v.x;
+ float sin_theta = sinf(M_PI_F * v);
+
+ if (sin_theta == 0.0f || denom == 0.0f)
+ *pdf = 0.0f;
+ else
+ *pdf = (cdf_u.x * cdf_v.x) / (M_2PI_F * M_PI_F * sin_theta * denom);
+
+ /* compute direction */
+ return equirectangular_to_direction(u, v);
}
/* TODO(sergey): Same as above, after the release we should consider using
* 'noinline' for all devices.
*/
-#ifdef __KERNEL_GPU__
+# ifdef __KERNEL_GPU__
ccl_device_noinline
-#else
+# else
ccl_device
-#endif
-float background_map_pdf(KernelGlobals *kg, float3 direction)
+# endif
+ float
+ background_map_pdf(KernelGlobals *kg, float3 direction)
{
- float2 uv = direction_to_equirectangular(direction);
- int res_x = kernel_data.integrator.pdf_background_res_x;
- int res_y = kernel_data.integrator.pdf_background_res_y;
- int cdf_width = res_x + 1;
+ float2 uv = direction_to_equirectangular(direction);
+ int res_x = kernel_data.integrator.pdf_background_res_x;
+ int res_y = kernel_data.integrator.pdf_background_res_y;
+ int cdf_width = res_x + 1;
- float sin_theta = sinf(uv.y * M_PI_F);
+ float sin_theta = sinf(uv.y * M_PI_F);
- if(sin_theta == 0.0f)
- return 0.0f;
+ if (sin_theta == 0.0f)
+ return 0.0f;
- int index_u = clamp(float_to_int(uv.x * res_x), 0, res_x - 1);
- int index_v = clamp(float_to_int(uv.y * res_y), 0, res_y - 1);
+ int index_u = clamp(float_to_int(uv.x * res_x), 0, res_x - 1);
+ int index_v = clamp(float_to_int(uv.y * res_y), 0, res_y - 1);
- /* pdfs in V direction */
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
+ /* pdfs in V direction */
+ float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf,
+ index_v * cdf_width + res_x);
+ float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
- float denom = cdf_last_u.x * cdf_last_v.x;
+ float denom = cdf_last_u.x * cdf_last_v.x;
- if(denom == 0.0f)
- return 0.0f;
+ if (denom == 0.0f)
+ return 0.0f;
- /* pdfs in U direction */
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u);
- float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
+ /* pdfs in U direction */
+ float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf,
+ index_v * cdf_width + index_u);
+ float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
- return (cdf_u.x * cdf_v.x)/(M_2PI_F * M_PI_F * sin_theta * denom);
+ return (cdf_u.x * cdf_v.x) / (M_2PI_F * M_PI_F * sin_theta * denom);
}
-ccl_device_inline bool background_portal_data_fetch_and_check_side(KernelGlobals *kg,
- float3 P,
- int index,
- float3 *lightpos,
- float3 *dir)
+ccl_device_inline bool background_portal_data_fetch_and_check_side(
+ KernelGlobals *kg, float3 P, int index, float3 *lightpos, float3 *dir)
{
- int portal = kernel_data.integrator.portal_offset + index;
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
+ int portal = kernel_data.integrator.portal_offset + index;
+ const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
- *lightpos = make_float3(klight->co[0], klight->co[1], klight->co[2]);
- *dir = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
+ *lightpos = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+ *dir = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
- /* Check whether portal is on the right side. */
- if(dot(*dir, P - *lightpos) > 1e-4f)
- return true;
+ /* Check whether portal is on the right side. */
+ if (dot(*dir, P - *lightpos) > 1e-4f)
+ return true;
- return false;
+ return false;
}
-ccl_device_inline float background_portal_pdf(KernelGlobals *kg,
- float3 P,
- float3 direction,
- int ignore_portal,
- bool *is_possible)
+ccl_device_inline float background_portal_pdf(
+ KernelGlobals *kg, float3 P, float3 direction, int ignore_portal, bool *is_possible)
{
- float portal_pdf = 0.0f;
-
- int num_possible = 0;
- for(int p = 0; p < kernel_data.integrator.num_portals; p++) {
- if(p == ignore_portal)
- continue;
-
- float3 lightpos, dir;
- if(!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
- continue;
-
- /* There's a portal that could be sampled from this position. */
- if(is_possible) {
- *is_possible = true;
- }
- num_possible++;
-
- int portal = kernel_data.integrator.portal_offset + p;
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
- float3 axisu = make_float3(klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
- float3 axisv = make_float3(klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
- bool is_round = (klight->area.invarea < 0.0f);
-
- if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL, NULL, NULL, is_round))
- continue;
-
- if(is_round) {
- float t;
- float3 D = normalize_len(lightpos - P, &t);
- portal_pdf += fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t);
- }
- else {
- portal_pdf += rect_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false);
- }
- }
-
- if(ignore_portal >= 0) {
- /* We have skipped a portal that could be sampled as well. */
- num_possible++;
- }
-
- return (num_possible > 0)? portal_pdf / num_possible: 0.0f;
+ float portal_pdf = 0.0f;
+
+ int num_possible = 0;
+ for (int p = 0; p < kernel_data.integrator.num_portals; p++) {
+ if (p == ignore_portal)
+ continue;
+
+ float3 lightpos, dir;
+ if (!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
+ continue;
+
+ /* There's a portal that could be sampled from this position. */
+ if (is_possible) {
+ *is_possible = true;
+ }
+ num_possible++;
+
+ int portal = kernel_data.integrator.portal_offset + p;
+ const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
+ float3 axisu = make_float3(
+ klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
+ float3 axisv = make_float3(
+ klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
+ bool is_round = (klight->area.invarea < 0.0f);
+
+ if (!ray_quad_intersect(P,
+ direction,
+ 1e-4f,
+ FLT_MAX,
+ lightpos,
+ axisu,
+ axisv,
+ dir,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ is_round))
+ continue;
+
+ if (is_round) {
+ float t;
+ float3 D = normalize_len(lightpos - P, &t);
+ portal_pdf += fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t);
+ }
+ else {
+ portal_pdf += rect_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false);
+ }
+ }
+
+ if (ignore_portal >= 0) {
+ /* We have skipped a portal that could be sampled as well. */
+ num_possible++;
+ }
+
+ return (num_possible > 0) ? portal_pdf / num_possible : 0.0f;
}
ccl_device int background_num_possible_portals(KernelGlobals *kg, float3 P)
{
- int num_possible_portals = 0;
- for(int p = 0; p < kernel_data.integrator.num_portals; p++) {
- float3 lightpos, dir;
- if(background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
- num_possible_portals++;
- }
- return num_possible_portals;
+ int num_possible_portals = 0;
+ for (int p = 0; p < kernel_data.integrator.num_portals; p++) {
+ float3 lightpos, dir;
+ if (background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
+ num_possible_portals++;
+ }
+ return num_possible_portals;
}
ccl_device float3 background_portal_sample(KernelGlobals *kg,
@@ -387,774 +409,754 @@ ccl_device float3 background_portal_sample(KernelGlobals *kg,
int *sampled_portal,
float *pdf)
{
- /* Pick a portal, then re-normalize randv. */
- randv *= num_possible;
- int portal = (int)randv;
- randv -= portal;
-
- /* TODO(sergey): Some smarter way of finding portal to sample
- * is welcome.
- */
- for(int p = 0; p < kernel_data.integrator.num_portals; p++) {
- /* Search for the sampled portal. */
- float3 lightpos, dir;
- if(!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
- continue;
-
- if(portal == 0) {
- /* p is the portal to be sampled. */
- int portal = kernel_data.integrator.portal_offset + p;
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
- float3 axisu = make_float3(klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
- float3 axisv = make_float3(klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
- bool is_round = (klight->area.invarea < 0.0f);
-
- float3 D;
- if(is_round) {
- lightpos += ellipse_sample(axisu*0.5f, axisv*0.5f, randu, randv);
- float t;
- D = normalize_len(lightpos - P, &t);
- *pdf = fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t);
- }
- else {
- *pdf = rect_light_sample(P, &lightpos,
- axisu, axisv,
- randu, randv,
- true);
- D = normalize(lightpos - P);
- }
-
- *pdf /= num_possible;
- *sampled_portal = p;
- return D;
- }
-
- portal--;
- }
-
- return make_float3(0.0f, 0.0f, 0.0f);
+ /* Pick a portal, then re-normalize randv. */
+ randv *= num_possible;
+ int portal = (int)randv;
+ randv -= portal;
+
+ /* TODO(sergey): Some smarter way of finding portal to sample
+ * is welcome.
+ */
+ for (int p = 0; p < kernel_data.integrator.num_portals; p++) {
+ /* Search for the sampled portal. */
+ float3 lightpos, dir;
+ if (!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
+ continue;
+
+ if (portal == 0) {
+ /* p is the portal to be sampled. */
+ int portal = kernel_data.integrator.portal_offset + p;
+ const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
+ float3 axisu = make_float3(
+ klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
+ float3 axisv = make_float3(
+ klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
+ bool is_round = (klight->area.invarea < 0.0f);
+
+ float3 D;
+ if (is_round) {
+ lightpos += ellipse_sample(axisu * 0.5f, axisv * 0.5f, randu, randv);
+ float t;
+ D = normalize_len(lightpos - P, &t);
+ *pdf = fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t);
+ }
+ else {
+ *pdf = rect_light_sample(P, &lightpos, axisu, axisv, randu, randv, true);
+ D = normalize(lightpos - P);
+ }
+
+ *pdf /= num_possible;
+ *sampled_portal = p;
+ return D;
+ }
+
+ portal--;
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device_inline float3 background_light_sample(KernelGlobals *kg,
- float3 P,
- float randu, float randv,
- float *pdf)
+ccl_device_inline float3
+background_light_sample(KernelGlobals *kg, float3 P, float randu, float randv, float *pdf)
{
- /* Probability of sampling portals instead of the map. */
- float portal_sampling_pdf = kernel_data.integrator.portal_pdf;
-
- /* Check if there are portals in the scene which we can sample. */
- if(portal_sampling_pdf > 0.0f) {
- int num_portals = background_num_possible_portals(kg, P);
- if(num_portals > 0) {
- if(portal_sampling_pdf == 1.0f || randu < portal_sampling_pdf) {
- if(portal_sampling_pdf < 1.0f) {
- randu /= portal_sampling_pdf;
- }
- int portal;
- float3 D = background_portal_sample(kg, P, randu, randv, num_portals, &portal, pdf);
- if(num_portals > 1) {
- /* Ignore the chosen portal, its pdf is already included. */
- *pdf += background_portal_pdf(kg, P, D, portal, NULL);
- }
- /* We could also have sampled the map, so combine with MIS. */
- if(portal_sampling_pdf < 1.0f) {
- float cdf_pdf = background_map_pdf(kg, D);
- *pdf = (portal_sampling_pdf * (*pdf)
- + (1.0f - portal_sampling_pdf) * cdf_pdf);
- }
- return D;
- }
- else {
- /* Sample map, but with nonzero portal_sampling_pdf for MIS. */
- randu = (randu - portal_sampling_pdf) / (1.0f - portal_sampling_pdf);
- }
- }
- else {
- /* We can't sample a portal.
- * Check if we can sample the map instead.
- */
- if(portal_sampling_pdf == 1.0f) {
- /* Use uniform as a fallback if we can't sample the map. */
- *pdf = 1.0f / M_4PI_F;
- return sample_uniform_sphere(randu, randv);
- }
- else {
- portal_sampling_pdf = 0.0f;
- }
- }
- }
-
- float3 D = background_map_sample(kg, randu, randv, pdf);
- /* Use MIS if portals could be sampled as well. */
- if(portal_sampling_pdf > 0.0f) {
- float portal_pdf = background_portal_pdf(kg, P, D, -1, NULL);
- *pdf = (portal_sampling_pdf * portal_pdf
- + (1.0f - portal_sampling_pdf) * (*pdf));
- }
- return D;
+ /* Probability of sampling portals instead of the map. */
+ float portal_sampling_pdf = kernel_data.integrator.portal_pdf;
+
+ /* Check if there are portals in the scene which we can sample. */
+ if (portal_sampling_pdf > 0.0f) {
+ int num_portals = background_num_possible_portals(kg, P);
+ if (num_portals > 0) {
+ if (portal_sampling_pdf == 1.0f || randu < portal_sampling_pdf) {
+ if (portal_sampling_pdf < 1.0f) {
+ randu /= portal_sampling_pdf;
+ }
+ int portal;
+ float3 D = background_portal_sample(kg, P, randu, randv, num_portals, &portal, pdf);
+ if (num_portals > 1) {
+ /* Ignore the chosen portal, its pdf is already included. */
+ *pdf += background_portal_pdf(kg, P, D, portal, NULL);
+ }
+ /* We could also have sampled the map, so combine with MIS. */
+ if (portal_sampling_pdf < 1.0f) {
+ float cdf_pdf = background_map_pdf(kg, D);
+ *pdf = (portal_sampling_pdf * (*pdf) + (1.0f - portal_sampling_pdf) * cdf_pdf);
+ }
+ return D;
+ }
+ else {
+ /* Sample map, but with nonzero portal_sampling_pdf for MIS. */
+ randu = (randu - portal_sampling_pdf) / (1.0f - portal_sampling_pdf);
+ }
+ }
+ else {
+ /* We can't sample a portal.
+ * Check if we can sample the map instead.
+ */
+ if (portal_sampling_pdf == 1.0f) {
+ /* Use uniform as a fallback if we can't sample the map. */
+ *pdf = 1.0f / M_4PI_F;
+ return sample_uniform_sphere(randu, randv);
+ }
+ else {
+ portal_sampling_pdf = 0.0f;
+ }
+ }
+ }
+
+ float3 D = background_map_sample(kg, randu, randv, pdf);
+ /* Use MIS if portals could be sampled as well. */
+ if (portal_sampling_pdf > 0.0f) {
+ float portal_pdf = background_portal_pdf(kg, P, D, -1, NULL);
+ *pdf = (portal_sampling_pdf * portal_pdf + (1.0f - portal_sampling_pdf) * (*pdf));
+ }
+ return D;
}
ccl_device float background_light_pdf(KernelGlobals *kg, float3 P, float3 direction)
{
- /* Probability of sampling portals instead of the map. */
- float portal_sampling_pdf = kernel_data.integrator.portal_pdf;
-
- float portal_pdf = 0.0f, map_pdf = 0.0f;
- if(portal_sampling_pdf > 0.0f) {
- /* Evaluate PDF of sampling this direction by portal sampling. */
- bool is_possible = false;
- portal_pdf = background_portal_pdf(kg, P, direction, -1, &is_possible) * portal_sampling_pdf;
- if(!is_possible) {
- /* Portal sampling is not possible here because all portals point to the wrong side.
- * If map sampling is possible, it would be used instead, otherwise fallback sampling is used. */
- if(portal_sampling_pdf == 1.0f) {
- return kernel_data.integrator.pdf_lights / M_4PI_F;
- }
- else {
- /* Force map sampling. */
- portal_sampling_pdf = 0.0f;
- }
- }
- }
- if(portal_sampling_pdf < 1.0f) {
- /* Evaluate PDF of sampling this direction by map sampling. */
- map_pdf = background_map_pdf(kg, direction) * (1.0f - portal_sampling_pdf);
- }
- return (portal_pdf + map_pdf) * kernel_data.integrator.pdf_lights;
+ /* Probability of sampling portals instead of the map. */
+ float portal_sampling_pdf = kernel_data.integrator.portal_pdf;
+
+ float portal_pdf = 0.0f, map_pdf = 0.0f;
+ if (portal_sampling_pdf > 0.0f) {
+ /* Evaluate PDF of sampling this direction by portal sampling. */
+ bool is_possible = false;
+ portal_pdf = background_portal_pdf(kg, P, direction, -1, &is_possible) * portal_sampling_pdf;
+ if (!is_possible) {
+ /* Portal sampling is not possible here because all portals point to the wrong side.
+ * If map sampling is possible, it would be used instead, otherwise fallback sampling is used. */
+ if (portal_sampling_pdf == 1.0f) {
+ return kernel_data.integrator.pdf_lights / M_4PI_F;
+ }
+ else {
+ /* Force map sampling. */
+ portal_sampling_pdf = 0.0f;
+ }
+ }
+ }
+ if (portal_sampling_pdf < 1.0f) {
+ /* Evaluate PDF of sampling this direction by map sampling. */
+ map_pdf = background_map_pdf(kg, direction) * (1.0f - portal_sampling_pdf);
+ }
+ return (portal_pdf + map_pdf) * kernel_data.integrator.pdf_lights;
}
#endif
/* Regular Light */
-ccl_device_inline bool lamp_light_sample(KernelGlobals *kg,
- int lamp,
- float randu, float randv,
- float3 P,
- LightSample *ls)
+ccl_device_inline bool lamp_light_sample(
+ KernelGlobals *kg, int lamp, float randu, float randv, float3 P, LightSample *ls)
{
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
- LightType type = (LightType)klight->type;
- ls->type = type;
- ls->shader = klight->shader_id;
- ls->object = PRIM_NONE;
- ls->prim = PRIM_NONE;
- ls->lamp = lamp;
- ls->u = randu;
- ls->v = randv;
-
- if(type == LIGHT_DISTANT) {
- /* distant light */
- float3 lightD = make_float3(klight->co[0], klight->co[1], klight->co[2]);
- float3 D = lightD;
- float radius = klight->distant.radius;
- float invarea = klight->distant.invarea;
-
- if(radius > 0.0f)
- D = distant_light_sample(D, radius, randu, randv);
-
- ls->P = D;
- ls->Ng = D;
- ls->D = -D;
- ls->t = FLT_MAX;
-
- float costheta = dot(lightD, D);
- ls->pdf = invarea/(costheta*costheta*costheta);
- ls->eval_fac = ls->pdf;
- }
+ const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ LightType type = (LightType)klight->type;
+ ls->type = type;
+ ls->shader = klight->shader_id;
+ ls->object = PRIM_NONE;
+ ls->prim = PRIM_NONE;
+ ls->lamp = lamp;
+ ls->u = randu;
+ ls->v = randv;
+
+ if (type == LIGHT_DISTANT) {
+ /* distant light */
+ float3 lightD = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+ float3 D = lightD;
+ float radius = klight->distant.radius;
+ float invarea = klight->distant.invarea;
+
+ if (radius > 0.0f)
+ D = distant_light_sample(D, radius, randu, randv);
+
+ ls->P = D;
+ ls->Ng = D;
+ ls->D = -D;
+ ls->t = FLT_MAX;
+
+ float costheta = dot(lightD, D);
+ ls->pdf = invarea / (costheta * costheta * costheta);
+ ls->eval_fac = ls->pdf;
+ }
#ifdef __BACKGROUND_MIS__
- else if(type == LIGHT_BACKGROUND) {
- /* infinite area light (e.g. light dome or env light) */
- float3 D = -background_light_sample(kg, P, randu, randv, &ls->pdf);
-
- ls->P = D;
- ls->Ng = D;
- ls->D = -D;
- ls->t = FLT_MAX;
- ls->eval_fac = 1.0f;
- }
+ else if (type == LIGHT_BACKGROUND) {
+ /* infinite area light (e.g. light dome or env light) */
+ float3 D = -background_light_sample(kg, P, randu, randv, &ls->pdf);
+
+ ls->P = D;
+ ls->Ng = D;
+ ls->D = -D;
+ ls->t = FLT_MAX;
+ ls->eval_fac = 1.0f;
+ }
#endif
- else {
- ls->P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
-
- if(type == LIGHT_POINT || type == LIGHT_SPOT) {
- float radius = klight->spot.radius;
-
- if(radius > 0.0f)
- /* sphere light */
- ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
-
- ls->D = normalize_len(ls->P - P, &ls->t);
- ls->Ng = -ls->D;
-
- float invarea = klight->spot.invarea;
- ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
- ls->pdf = invarea;
-
- if(type == LIGHT_SPOT) {
- /* spot light attenuation */
- float3 dir = make_float3(klight->spot.dir[0],
- klight->spot.dir[1],
- klight->spot.dir[2]);
- ls->eval_fac *= spot_light_attenuation(dir,
- klight->spot.spot_angle,
- klight->spot.spot_smooth,
- ls);
- if(ls->eval_fac == 0.0f) {
- return false;
- }
- }
- float2 uv = map_to_sphere(ls->Ng);
- ls->u = uv.x;
- ls->v = uv.y;
-
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
- }
- else {
- /* area light */
- float3 axisu = make_float3(klight->area.axisu[0],
- klight->area.axisu[1],
- klight->area.axisu[2]);
- float3 axisv = make_float3(klight->area.axisv[0],
- klight->area.axisv[1],
- klight->area.axisv[2]);
- float3 D = make_float3(klight->area.dir[0],
- klight->area.dir[1],
- klight->area.dir[2]);
- float invarea = fabsf(klight->area.invarea);
- bool is_round = (klight->area.invarea < 0.0f);
-
- if(dot(ls->P - P, D) > 0.0f) {
- return false;
- }
-
- float3 inplane;
-
- if(is_round) {
- inplane = ellipse_sample(axisu*0.5f, axisv*0.5f, randu, randv);
- ls->P += inplane;
- ls->pdf = invarea;
- }
- else {
- inplane = ls->P;
- ls->pdf = rect_light_sample(P, &ls->P,
- axisu, axisv,
- randu, randv,
- true);
- inplane = ls->P - inplane;
- }
-
- ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f;
- ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f;
-
- ls->Ng = D;
- ls->D = normalize_len(ls->P - P, &ls->t);
-
- ls->eval_fac = 0.25f*invarea;
- if(is_round) {
- ls->pdf *= lamp_light_pdf(kg, D, -ls->D, ls->t);
- }
- }
- }
-
- ls->pdf *= kernel_data.integrator.pdf_lights;
-
- return (ls->pdf > 0.0f);
+ else {
+ ls->P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+
+ if (type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float radius = klight->spot.radius;
+
+ if (radius > 0.0f)
+ /* sphere light */
+ ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
+
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->Ng = -ls->D;
+
+ float invarea = klight->spot.invarea;
+ ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
+ ls->pdf = invarea;
+
+ if (type == LIGHT_SPOT) {
+ /* spot light attenuation */
+ float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+ ls->eval_fac *= spot_light_attenuation(
+ dir, klight->spot.spot_angle, klight->spot.spot_smooth, ls);
+ if (ls->eval_fac == 0.0f) {
+ return false;
+ }
+ }
+ float2 uv = map_to_sphere(ls->Ng);
+ ls->u = uv.x;
+ ls->v = uv.y;
+
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ }
+ else {
+ /* area light */
+ float3 axisu = make_float3(
+ klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
+ float3 axisv = make_float3(
+ klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
+ float3 D = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
+ float invarea = fabsf(klight->area.invarea);
+ bool is_round = (klight->area.invarea < 0.0f);
+
+ if (dot(ls->P - P, D) > 0.0f) {
+ return false;
+ }
+
+ float3 inplane;
+
+ if (is_round) {
+ inplane = ellipse_sample(axisu * 0.5f, axisv * 0.5f, randu, randv);
+ ls->P += inplane;
+ ls->pdf = invarea;
+ }
+ else {
+ inplane = ls->P;
+ ls->pdf = rect_light_sample(P, &ls->P, axisu, axisv, randu, randv, true);
+ inplane = ls->P - inplane;
+ }
+
+ ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f;
+ ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f;
+
+ ls->Ng = D;
+ ls->D = normalize_len(ls->P - P, &ls->t);
+
+ ls->eval_fac = 0.25f * invarea;
+ if (is_round) {
+ ls->pdf *= lamp_light_pdf(kg, D, -ls->D, ls->t);
+ }
+ }
+ }
+
+ ls->pdf *= kernel_data.integrator.pdf_lights;
+
+ return (ls->pdf > 0.0f);
}
-ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
+ccl_device bool lamp_light_eval(
+ KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
{
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
- LightType type = (LightType)klight->type;
- ls->type = type;
- ls->shader = klight->shader_id;
- ls->object = PRIM_NONE;
- ls->prim = PRIM_NONE;
- ls->lamp = lamp;
- /* todo: missing texture coordinates */
- ls->u = 0.0f;
- ls->v = 0.0f;
-
- if(!(ls->shader & SHADER_USE_MIS))
- return false;
-
- if(type == LIGHT_DISTANT) {
- /* distant light */
- float radius = klight->distant.radius;
-
- if(radius == 0.0f)
- return false;
- if(t != FLT_MAX)
- return false;
-
- /* a distant light is infinitely far away, but equivalent to a disk
- * shaped light exactly 1 unit away from the current shading point.
- *
- * radius t^2/cos(theta)
- * <----------> t = sqrt(1^2 + tan(theta)^2)
- * tan(th) area = radius*radius*pi
- * <----->
- * \ | (1 + tan(theta)^2)/cos(theta)
- * \ | (1 + tan(acos(cos(theta)))^2)/cos(theta)
- * t \th| 1 simplifies to
- * \-| 1/(cos(theta)^3)
- * \| magic!
- * P
- */
-
- float3 lightD = make_float3(klight->co[0], klight->co[1], klight->co[2]);
- float costheta = dot(-lightD, D);
- float cosangle = klight->distant.cosangle;
-
- if(costheta < cosangle)
- return false;
-
- ls->P = -D;
- ls->Ng = -D;
- ls->D = D;
- ls->t = FLT_MAX;
-
- /* compute pdf */
- float invarea = klight->distant.invarea;
- ls->pdf = invarea/(costheta*costheta*costheta);
- ls->eval_fac = ls->pdf;
- }
- else if(type == LIGHT_POINT || type == LIGHT_SPOT) {
- float3 lightP = make_float3(klight->co[0], klight->co[1], klight->co[2]);
-
- float radius = klight->spot.radius;
-
- /* sphere light */
- if(radius == 0.0f)
- return false;
-
- if(!ray_aligned_disk_intersect(P, D, t,
- lightP, radius, &ls->P, &ls->t))
- {
- return false;
- }
-
- ls->Ng = -D;
- ls->D = D;
-
- float invarea = klight->spot.invarea;
- ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
- ls->pdf = invarea;
-
- if(type == LIGHT_SPOT) {
- /* spot light attenuation */
- float3 dir = make_float3(klight->spot.dir[0],
- klight->spot.dir[1],
- klight->spot.dir[2]);
- ls->eval_fac *= spot_light_attenuation(dir,
- klight->spot.spot_angle,
- klight->spot.spot_smooth,
- ls);
-
- if(ls->eval_fac == 0.0f)
- return false;
- }
- float2 uv = map_to_sphere(ls->Ng);
- ls->u = uv.x;
- ls->v = uv.y;
-
- /* compute pdf */
- if(ls->t != FLT_MAX)
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
- }
- else if(type == LIGHT_AREA) {
- /* area light */
- float invarea = fabsf(klight->area.invarea);
- bool is_round = (klight->area.invarea < 0.0f);
- if(invarea == 0.0f)
- return false;
-
- float3 axisu = make_float3(klight->area.axisu[0],
- klight->area.axisu[1],
- klight->area.axisu[2]);
- float3 axisv = make_float3(klight->area.axisv[0],
- klight->area.axisv[1],
- klight->area.axisv[2]);
- float3 Ng = make_float3(klight->area.dir[0],
- klight->area.dir[1],
- klight->area.dir[2]);
-
- /* one sided */
- if(dot(D, Ng) >= 0.0f)
- return false;
-
- float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
-
- if(!ray_quad_intersect(P, D, 0.0f, t, light_P,
- axisu, axisv, Ng,
- &ls->P, &ls->t,
- &ls->u, &ls->v,
- is_round))
- {
- return false;
- }
-
- ls->D = D;
- ls->Ng = Ng;
- if(is_round) {
- ls->pdf = invarea * lamp_light_pdf(kg, Ng, -D, ls->t);
- }
- else {
- ls->pdf = rect_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
- }
- ls->eval_fac = 0.25f*invarea;
- }
- else {
- return false;
- }
-
- ls->pdf *= kernel_data.integrator.pdf_lights;
-
- return true;
+ const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ LightType type = (LightType)klight->type;
+ ls->type = type;
+ ls->shader = klight->shader_id;
+ ls->object = PRIM_NONE;
+ ls->prim = PRIM_NONE;
+ ls->lamp = lamp;
+ /* todo: missing texture coordinates */
+ ls->u = 0.0f;
+ ls->v = 0.0f;
+
+ if (!(ls->shader & SHADER_USE_MIS))
+ return false;
+
+ if (type == LIGHT_DISTANT) {
+ /* distant light */
+ float radius = klight->distant.radius;
+
+ if (radius == 0.0f)
+ return false;
+ if (t != FLT_MAX)
+ return false;
+
+ /* a distant light is infinitely far away, but equivalent to a disk
+ * shaped light exactly 1 unit away from the current shading point.
+ *
+ * radius t^2/cos(theta)
+ * <----------> t = sqrt(1^2 + tan(theta)^2)
+ * tan(th) area = radius*radius*pi
+ * <----->
+ * \ | (1 + tan(theta)^2)/cos(theta)
+ * \ | (1 + tan(acos(cos(theta)))^2)/cos(theta)
+ * t \th| 1 simplifies to
+ * \-| 1/(cos(theta)^3)
+ * \| magic!
+ * P
+ */
+
+ float3 lightD = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+ float costheta = dot(-lightD, D);
+ float cosangle = klight->distant.cosangle;
+
+ if (costheta < cosangle)
+ return false;
+
+ ls->P = -D;
+ ls->Ng = -D;
+ ls->D = D;
+ ls->t = FLT_MAX;
+
+ /* compute pdf */
+ float invarea = klight->distant.invarea;
+ ls->pdf = invarea / (costheta * costheta * costheta);
+ ls->eval_fac = ls->pdf;
+ }
+ else if (type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float3 lightP = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+
+ float radius = klight->spot.radius;
+
+ /* sphere light */
+ if (radius == 0.0f)
+ return false;
+
+ if (!ray_aligned_disk_intersect(P, D, t, lightP, radius, &ls->P, &ls->t)) {
+ return false;
+ }
+
+ ls->Ng = -D;
+ ls->D = D;
+
+ float invarea = klight->spot.invarea;
+ ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
+ ls->pdf = invarea;
+
+ if (type == LIGHT_SPOT) {
+ /* spot light attenuation */
+ float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+ ls->eval_fac *= spot_light_attenuation(
+ dir, klight->spot.spot_angle, klight->spot.spot_smooth, ls);
+
+ if (ls->eval_fac == 0.0f)
+ return false;
+ }
+ float2 uv = map_to_sphere(ls->Ng);
+ ls->u = uv.x;
+ ls->v = uv.y;
+
+ /* compute pdf */
+ if (ls->t != FLT_MAX)
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ }
+ else if (type == LIGHT_AREA) {
+ /* area light */
+ float invarea = fabsf(klight->area.invarea);
+ bool is_round = (klight->area.invarea < 0.0f);
+ if (invarea == 0.0f)
+ return false;
+
+ float3 axisu = make_float3(
+ klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
+ float3 axisv = make_float3(
+ klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
+ float3 Ng = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
+
+ /* one sided */
+ if (dot(D, Ng) >= 0.0f)
+ return false;
+
+ float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+
+ if (!ray_quad_intersect(
+ P, D, 0.0f, t, light_P, axisu, axisv, Ng, &ls->P, &ls->t, &ls->u, &ls->v, is_round)) {
+ return false;
+ }
+
+ ls->D = D;
+ ls->Ng = Ng;
+ if (is_round) {
+ ls->pdf = invarea * lamp_light_pdf(kg, Ng, -D, ls->t);
+ }
+ else {
+ ls->pdf = rect_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
+ }
+ ls->eval_fac = 0.25f * invarea;
+ }
+ else {
+ return false;
+ }
+
+ ls->pdf *= kernel_data.integrator.pdf_lights;
+
+ return true;
}
/* Triangle Light */
/* returns true if the triangle is has motion blur or an instancing transform applied */
-ccl_device_inline bool triangle_world_space_vertices(KernelGlobals *kg, int object, int prim, float time, float3 V[3])
+ccl_device_inline bool triangle_world_space_vertices(
+ KernelGlobals *kg, int object, int prim, float time, float3 V[3])
{
- bool has_motion = false;
- const int object_flag = kernel_tex_fetch(__object_flag, object);
+ bool has_motion = false;
+ const int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VERTEX_MOTION && time >= 0.0f) {
- motion_triangle_vertices(kg, object, prim, time, V);
- has_motion = true;
- }
- else {
- triangle_vertices(kg, prim, V);
- }
+ if (object_flag & SD_OBJECT_HAS_VERTEX_MOTION && time >= 0.0f) {
+ motion_triangle_vertices(kg, object, prim, time, V);
+ has_motion = true;
+ }
+ else {
+ triangle_vertices(kg, prim, V);
+ }
#ifdef __INSTANCING__
- if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
# ifdef __OBJECT_MOTION__
- float object_time = (time >= 0.0f) ? time : 0.5f;
- Transform tfm = object_fetch_transform_motion_test(kg, object, object_time, NULL);
+ float object_time = (time >= 0.0f) ? time : 0.5f;
+ Transform tfm = object_fetch_transform_motion_test(kg, object, object_time, NULL);
# else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
# endif
- V[0] = transform_point(&tfm, V[0]);
- V[1] = transform_point(&tfm, V[1]);
- V[2] = transform_point(&tfm, V[2]);
- has_motion = true;
- }
+ V[0] = transform_point(&tfm, V[0]);
+ V[1] = transform_point(&tfm, V[1]);
+ V[2] = transform_point(&tfm, V[2]);
+ has_motion = true;
+ }
#endif
- return has_motion;
+ return has_motion;
}
-ccl_device_inline float triangle_light_pdf_area(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
+ccl_device_inline float triangle_light_pdf_area(KernelGlobals *kg,
+ const float3 Ng,
+ const float3 I,
+ float t)
{
- float pdf = kernel_data.integrator.pdf_triangles;
- float cos_pi = fabsf(dot(Ng, I));
+ float pdf = kernel_data.integrator.pdf_triangles;
+ float cos_pi = fabsf(dot(Ng, I));
- if(cos_pi == 0.0f)
- return 0.0f;
+ if (cos_pi == 0.0f)
+ return 0.0f;
- return t*t*pdf/cos_pi;
+ return t * t * pdf / cos_pi;
}
ccl_device_forceinline float triangle_light_pdf(KernelGlobals *kg, ShaderData *sd, float t)
{
- /* A naive heuristic to decide between costly solid angle sampling
- * and simple area sampling, comparing the distance to the triangle plane
- * to the length of the edges of the triangle. */
-
- float3 V[3];
- bool has_motion = triangle_world_space_vertices(kg, sd->object, sd->prim, sd->time, V);
-
- const float3 e0 = V[1] - V[0];
- const float3 e1 = V[2] - V[0];
- const float3 e2 = V[2] - V[1];
- const float longest_edge_squared = max(len_squared(e0), max(len_squared(e1), len_squared(e2)));
- const float3 N = cross(e0, e1);
- const float distance_to_plane = fabsf(dot(N, sd->I * t))/dot(N, N);
-
- if(longest_edge_squared > distance_to_plane*distance_to_plane) {
- /* sd contains the point on the light source
- * calculate Px, the point that we're shading */
- const float3 Px = sd->P + sd->I * t;
- const float3 v0_p = V[0] - Px;
- const float3 v1_p = V[1] - Px;
- const float3 v2_p = V[2] - Px;
-
- const float3 u01 = safe_normalize(cross(v0_p, v1_p));
- const float3 u02 = safe_normalize(cross(v0_p, v2_p));
- const float3 u12 = safe_normalize(cross(v1_p, v2_p));
-
- const float alpha = fast_acosf(dot(u02, u01));
- const float beta = fast_acosf(-dot(u01, u12));
- const float gamma = fast_acosf(dot(u02, u12));
- const float solid_angle = alpha + beta + gamma - M_PI_F;
-
- /* pdf_triangles is calculated over triangle area, but we're not sampling over its area */
- if(UNLIKELY(solid_angle == 0.0f)) {
- return 0.0f;
- }
- else {
- float area = 1.0f;
- if(has_motion) {
- /* get the center frame vertices, this is what the PDF was calculated from */
- triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
- area = triangle_area(V[0], V[1], V[2]);
- }
- else {
- area = 0.5f * len(N);
- }
- const float pdf = area * kernel_data.integrator.pdf_triangles;
- return pdf / solid_angle;
- }
- }
- else {
- float pdf = triangle_light_pdf_area(kg, sd->Ng, sd->I, t);
- if(has_motion) {
- const float area = 0.5f * len(N);
- if(UNLIKELY(area == 0.0f)) {
- return 0.0f;
- }
- /* scale the PDF.
- * area = the area the sample was taken from
- * area_pre = the are from which pdf_triangles was calculated from */
- triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
- const float area_pre = triangle_area(V[0], V[1], V[2]);
- pdf = pdf * area_pre / area;
- }
- return pdf;
- }
+ /* A naive heuristic to decide between costly solid angle sampling
+ * and simple area sampling, comparing the distance to the triangle plane
+ * to the length of the edges of the triangle. */
+
+ float3 V[3];
+ bool has_motion = triangle_world_space_vertices(kg, sd->object, sd->prim, sd->time, V);
+
+ const float3 e0 = V[1] - V[0];
+ const float3 e1 = V[2] - V[0];
+ const float3 e2 = V[2] - V[1];
+ const float longest_edge_squared = max(len_squared(e0), max(len_squared(e1), len_squared(e2)));
+ const float3 N = cross(e0, e1);
+ const float distance_to_plane = fabsf(dot(N, sd->I * t)) / dot(N, N);
+
+ if (longest_edge_squared > distance_to_plane * distance_to_plane) {
+ /* sd contains the point on the light source
+ * calculate Px, the point that we're shading */
+ const float3 Px = sd->P + sd->I * t;
+ const float3 v0_p = V[0] - Px;
+ const float3 v1_p = V[1] - Px;
+ const float3 v2_p = V[2] - Px;
+
+ const float3 u01 = safe_normalize(cross(v0_p, v1_p));
+ const float3 u02 = safe_normalize(cross(v0_p, v2_p));
+ const float3 u12 = safe_normalize(cross(v1_p, v2_p));
+
+ const float alpha = fast_acosf(dot(u02, u01));
+ const float beta = fast_acosf(-dot(u01, u12));
+ const float gamma = fast_acosf(dot(u02, u12));
+ const float solid_angle = alpha + beta + gamma - M_PI_F;
+
+ /* pdf_triangles is calculated over triangle area, but we're not sampling over its area */
+ if (UNLIKELY(solid_angle == 0.0f)) {
+ return 0.0f;
+ }
+ else {
+ float area = 1.0f;
+ if (has_motion) {
+ /* get the center frame vertices, this is what the PDF was calculated from */
+ triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
+ area = triangle_area(V[0], V[1], V[2]);
+ }
+ else {
+ area = 0.5f * len(N);
+ }
+ const float pdf = area * kernel_data.integrator.pdf_triangles;
+ return pdf / solid_angle;
+ }
+ }
+ else {
+ float pdf = triangle_light_pdf_area(kg, sd->Ng, sd->I, t);
+ if (has_motion) {
+ const float area = 0.5f * len(N);
+ if (UNLIKELY(area == 0.0f)) {
+ return 0.0f;
+ }
+ /* scale the PDF.
+ * area = the area the sample was taken from
+ * area_pre = the are from which pdf_triangles was calculated from */
+ triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
+ const float area_pre = triangle_area(V[0], V[1], V[2]);
+ pdf = pdf * area_pre / area;
+ }
+ return pdf;
+ }
}
-ccl_device_forceinline void triangle_light_sample(KernelGlobals *kg, int prim, int object,
- float randu, float randv, float time, LightSample *ls, const float3 P)
+ccl_device_forceinline void triangle_light_sample(KernelGlobals *kg,
+ int prim,
+ int object,
+ float randu,
+ float randv,
+ float time,
+ LightSample *ls,
+ const float3 P)
{
- /* A naive heuristic to decide between costly solid angle sampling
- * and simple area sampling, comparing the distance to the triangle plane
- * to the length of the edges of the triangle. */
-
- float3 V[3];
- bool has_motion = triangle_world_space_vertices(kg, object, prim, time, V);
-
- const float3 e0 = V[1] - V[0];
- const float3 e1 = V[2] - V[0];
- const float3 e2 = V[2] - V[1];
- const float longest_edge_squared = max(len_squared(e0), max(len_squared(e1), len_squared(e2)));
- const float3 N0 = cross(e0, e1);
- float Nl = 0.0f;
- ls->Ng = safe_normalize_len(N0, &Nl);
- float area = 0.5f * Nl;
-
- /* flip normal if necessary */
- const int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
- ls->Ng = -ls->Ng;
- }
- ls->eval_fac = 1.0f;
- ls->shader = kernel_tex_fetch(__tri_shader, prim);
- ls->object = object;
- ls->prim = prim;
- ls->lamp = LAMP_NONE;
- ls->shader |= SHADER_USE_MIS;
- ls->type = LIGHT_TRIANGLE;
-
- float distance_to_plane = fabsf(dot(N0, V[0] - P)/dot(N0, N0));
-
- if(longest_edge_squared > distance_to_plane*distance_to_plane) {
- /* see James Arvo, "Stratified Sampling of Spherical Triangles"
- * http://www.graphics.cornell.edu/pubs/1995/Arv95c.pdf */
-
- /* project the triangle to the unit sphere
- * and calculate its edges and angles */
- const float3 v0_p = V[0] - P;
- const float3 v1_p = V[1] - P;
- const float3 v2_p = V[2] - P;
-
- const float3 u01 = safe_normalize(cross(v0_p, v1_p));
- const float3 u02 = safe_normalize(cross(v0_p, v2_p));
- const float3 u12 = safe_normalize(cross(v1_p, v2_p));
-
- const float3 A = safe_normalize(v0_p);
- const float3 B = safe_normalize(v1_p);
- const float3 C = safe_normalize(v2_p);
-
- const float cos_alpha = dot(u02, u01);
- const float cos_beta = -dot(u01, u12);
- const float cos_gamma = dot(u02, u12);
-
- /* calculate dihedral angles */
- const float alpha = fast_acosf(cos_alpha);
- const float beta = fast_acosf(cos_beta);
- const float gamma = fast_acosf(cos_gamma);
- /* the area of the unit spherical triangle = solid angle */
- const float solid_angle = alpha + beta + gamma - M_PI_F;
-
- /* precompute a few things
- * these could be re-used to take several samples
- * as they are independent of randu/randv */
- const float cos_c = dot(A, B);
- const float sin_alpha = fast_sinf(alpha);
- const float product = sin_alpha * cos_c;
-
- /* Select a random sub-area of the spherical triangle
- * and calculate the third vertex C_ of that new triangle */
- const float phi = randu * solid_angle - alpha;
- float s, t;
- fast_sincosf(phi, &s, &t);
- const float u = t - cos_alpha;
- const float v = s + product;
-
- const float3 U = safe_normalize(C - dot(C, A) * A);
-
- float q = 1.0f;
- const float det = ((v * s + u * t) * sin_alpha);
- if(det != 0.0f) {
- q = ((v * t - u * s) * cos_alpha - v) / det;
- }
- const float temp = max(1.0f - q*q, 0.0f);
-
- const float3 C_ = safe_normalize(q * A + sqrtf(temp) * U);
-
- /* Finally, select a random point along the edge of the new triangle
- * That point on the spherical triangle is the sampled ray direction */
- const float z = 1.0f - randv * (1.0f - dot(C_, B));
- ls->D = z * B + safe_sqrtf(1.0f - z*z) * safe_normalize(C_ - dot(C_, B) * B);
-
- /* calculate intersection with the planar triangle */
- if(!ray_triangle_intersect(P, ls->D, FLT_MAX,
+ /* A naive heuristic to decide between costly solid angle sampling
+ * and simple area sampling, comparing the distance to the triangle plane
+ * to the length of the edges of the triangle. */
+
+ float3 V[3];
+ bool has_motion = triangle_world_space_vertices(kg, object, prim, time, V);
+
+ const float3 e0 = V[1] - V[0];
+ const float3 e1 = V[2] - V[0];
+ const float3 e2 = V[2] - V[1];
+ const float longest_edge_squared = max(len_squared(e0), max(len_squared(e1), len_squared(e2)));
+ const float3 N0 = cross(e0, e1);
+ float Nl = 0.0f;
+ ls->Ng = safe_normalize_len(N0, &Nl);
+ float area = 0.5f * Nl;
+
+ /* flip normal if necessary */
+ const int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
+ ls->Ng = -ls->Ng;
+ }
+ ls->eval_fac = 1.0f;
+ ls->shader = kernel_tex_fetch(__tri_shader, prim);
+ ls->object = object;
+ ls->prim = prim;
+ ls->lamp = LAMP_NONE;
+ ls->shader |= SHADER_USE_MIS;
+ ls->type = LIGHT_TRIANGLE;
+
+ float distance_to_plane = fabsf(dot(N0, V[0] - P) / dot(N0, N0));
+
+ if (longest_edge_squared > distance_to_plane * distance_to_plane) {
+ /* see James Arvo, "Stratified Sampling of Spherical Triangles"
+ * http://www.graphics.cornell.edu/pubs/1995/Arv95c.pdf */
+
+ /* project the triangle to the unit sphere
+ * and calculate its edges and angles */
+ const float3 v0_p = V[0] - P;
+ const float3 v1_p = V[1] - P;
+ const float3 v2_p = V[2] - P;
+
+ const float3 u01 = safe_normalize(cross(v0_p, v1_p));
+ const float3 u02 = safe_normalize(cross(v0_p, v2_p));
+ const float3 u12 = safe_normalize(cross(v1_p, v2_p));
+
+ const float3 A = safe_normalize(v0_p);
+ const float3 B = safe_normalize(v1_p);
+ const float3 C = safe_normalize(v2_p);
+
+ const float cos_alpha = dot(u02, u01);
+ const float cos_beta = -dot(u01, u12);
+ const float cos_gamma = dot(u02, u12);
+
+ /* calculate dihedral angles */
+ const float alpha = fast_acosf(cos_alpha);
+ const float beta = fast_acosf(cos_beta);
+ const float gamma = fast_acosf(cos_gamma);
+ /* the area of the unit spherical triangle = solid angle */
+ const float solid_angle = alpha + beta + gamma - M_PI_F;
+
+ /* precompute a few things
+ * these could be re-used to take several samples
+ * as they are independent of randu/randv */
+ const float cos_c = dot(A, B);
+ const float sin_alpha = fast_sinf(alpha);
+ const float product = sin_alpha * cos_c;
+
+ /* Select a random sub-area of the spherical triangle
+ * and calculate the third vertex C_ of that new triangle */
+ const float phi = randu * solid_angle - alpha;
+ float s, t;
+ fast_sincosf(phi, &s, &t);
+ const float u = t - cos_alpha;
+ const float v = s + product;
+
+ const float3 U = safe_normalize(C - dot(C, A) * A);
+
+ float q = 1.0f;
+ const float det = ((v * s + u * t) * sin_alpha);
+ if (det != 0.0f) {
+ q = ((v * t - u * s) * cos_alpha - v) / det;
+ }
+ const float temp = max(1.0f - q * q, 0.0f);
+
+ const float3 C_ = safe_normalize(q * A + sqrtf(temp) * U);
+
+ /* Finally, select a random point along the edge of the new triangle
+ * That point on the spherical triangle is the sampled ray direction */
+ const float z = 1.0f - randv * (1.0f - dot(C_, B));
+ ls->D = z * B + safe_sqrtf(1.0f - z * z) * safe_normalize(C_ - dot(C_, B) * B);
+
+ /* calculate intersection with the planar triangle */
+ if (!ray_triangle_intersect(P,
+ ls->D,
+ FLT_MAX,
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- (ssef*)V,
+ (ssef *)V,
#else
- V[0], V[1], V[2],
+ V[0],
+ V[1],
+ V[2],
#endif
- &ls->u, &ls->v, &ls->t)) {
- ls->pdf = 0.0f;
- return;
- }
-
- ls->P = P + ls->D * ls->t;
-
- /* pdf_triangles is calculated over triangle area, but we're sampling over solid angle */
- if(UNLIKELY(solid_angle == 0.0f)) {
- ls->pdf = 0.0f;
- return;
- }
- else {
- if(has_motion) {
- /* get the center frame vertices, this is what the PDF was calculated from */
- triangle_world_space_vertices(kg, object, prim, -1.0f, V);
- area = triangle_area(V[0], V[1], V[2]);
- }
- const float pdf = area * kernel_data.integrator.pdf_triangles;
- ls->pdf = pdf / solid_angle;
- }
- }
- else {
- /* compute random point in triangle */
- randu = sqrtf(randu);
-
- const float u = 1.0f - randu;
- const float v = randv*randu;
- const float t = 1.0f - u - v;
- ls->P = u * V[0] + v * V[1] + t * V[2];
- /* compute incoming direction, distance and pdf */
- ls->D = normalize_len(ls->P - P, &ls->t);
- ls->pdf = triangle_light_pdf_area(kg, ls->Ng, -ls->D, ls->t);
- if(has_motion && area != 0.0f) {
- /* scale the PDF.
- * area = the area the sample was taken from
- * area_pre = the are from which pdf_triangles was calculated from */
- triangle_world_space_vertices(kg, object, prim, -1.0f, V);
- const float area_pre = triangle_area(V[0], V[1], V[2]);
- ls->pdf = ls->pdf * area_pre / area;
- }
- ls->u = u;
- ls->v = v;
- }
+ &ls->u,
+ &ls->v,
+ &ls->t)) {
+ ls->pdf = 0.0f;
+ return;
+ }
+
+ ls->P = P + ls->D * ls->t;
+
+ /* pdf_triangles is calculated over triangle area, but we're sampling over solid angle */
+ if (UNLIKELY(solid_angle == 0.0f)) {
+ ls->pdf = 0.0f;
+ return;
+ }
+ else {
+ if (has_motion) {
+ /* get the center frame vertices, this is what the PDF was calculated from */
+ triangle_world_space_vertices(kg, object, prim, -1.0f, V);
+ area = triangle_area(V[0], V[1], V[2]);
+ }
+ const float pdf = area * kernel_data.integrator.pdf_triangles;
+ ls->pdf = pdf / solid_angle;
+ }
+ }
+ else {
+ /* compute random point in triangle */
+ randu = sqrtf(randu);
+
+ const float u = 1.0f - randu;
+ const float v = randv * randu;
+ const float t = 1.0f - u - v;
+ ls->P = u * V[0] + v * V[1] + t * V[2];
+ /* compute incoming direction, distance and pdf */
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->pdf = triangle_light_pdf_area(kg, ls->Ng, -ls->D, ls->t);
+ if (has_motion && area != 0.0f) {
+ /* scale the PDF.
+ * area = the area the sample was taken from
+ * area_pre = the are from which pdf_triangles was calculated from */
+ triangle_world_space_vertices(kg, object, prim, -1.0f, V);
+ const float area_pre = triangle_area(V[0], V[1], V[2]);
+ ls->pdf = ls->pdf * area_pre / area;
+ }
+ ls->u = u;
+ ls->v = v;
+ }
}
/* Light Distribution */
ccl_device int light_distribution_sample(KernelGlobals *kg, float *randu)
{
- /* This is basically std::upper_bound as used by pbrt, to find a point light or
- * triangle to emit from, proportional to area. a good improvement would be to
- * also sample proportional to power, though it's not so well defined with
- * arbitrary shaders. */
- int first = 0;
- int len = kernel_data.integrator.num_distribution + 1;
- float r = *randu;
-
- while(len > 0) {
- int half_len = len >> 1;
- int middle = first + half_len;
-
- if(r < kernel_tex_fetch(__light_distribution, middle).totarea) {
- len = half_len;
- }
- else {
- first = middle + 1;
- len = len - half_len - 1;
- }
- }
-
- /* Clamping should not be needed but float rounding errors seem to
- * make this fail on rare occasions. */
- int index = clamp(first-1, 0, kernel_data.integrator.num_distribution-1);
-
- /* Rescale to reuse random number. this helps the 2D samples within
- * each area light be stratified as well. */
- float distr_min = kernel_tex_fetch(__light_distribution, index).totarea;
- float distr_max = kernel_tex_fetch(__light_distribution, index+1).totarea;
- *randu = (r - distr_min)/(distr_max - distr_min);
-
- return index;
+ /* This is basically std::upper_bound as used by pbrt, to find a point light or
+ * triangle to emit from, proportional to area. a good improvement would be to
+ * also sample proportional to power, though it's not so well defined with
+ * arbitrary shaders. */
+ int first = 0;
+ int len = kernel_data.integrator.num_distribution + 1;
+ float r = *randu;
+
+ while (len > 0) {
+ int half_len = len >> 1;
+ int middle = first + half_len;
+
+ if (r < kernel_tex_fetch(__light_distribution, middle).totarea) {
+ len = half_len;
+ }
+ else {
+ first = middle + 1;
+ len = len - half_len - 1;
+ }
+ }
+
+ /* Clamping should not be needed but float rounding errors seem to
+ * make this fail on rare occasions. */
+ int index = clamp(first - 1, 0, kernel_data.integrator.num_distribution - 1);
+
+ /* Rescale to reuse random number. this helps the 2D samples within
+ * each area light be stratified as well. */
+ float distr_min = kernel_tex_fetch(__light_distribution, index).totarea;
+ float distr_max = kernel_tex_fetch(__light_distribution, index + 1).totarea;
+ *randu = (r - distr_min) / (distr_max - distr_min);
+
+ return index;
}
/* Generic Light */
ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce)
{
- return (bounce > kernel_tex_fetch(__lights, index).max_bounces);
+ return (bounce > kernel_tex_fetch(__lights, index).max_bounces);
}
-ccl_device_noinline bool light_sample(KernelGlobals *kg,
- float randu,
- float randv,
- float time,
- float3 P,
- int bounce,
- LightSample *ls)
+ccl_device_noinline bool light_sample(
+ KernelGlobals *kg, float randu, float randv, float time, float3 P, int bounce, LightSample *ls)
{
- /* sample index */
- int index = light_distribution_sample(kg, &randu);
-
- /* fetch light data */
- const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch(__light_distribution, index);
- int prim = kdistribution->prim;
-
- if(prim >= 0) {
- int object = kdistribution->mesh_light.object_id;
- int shader_flag = kdistribution->mesh_light.shader_flag;
-
- triangle_light_sample(kg, prim, object, randu, randv, time, ls, P);
- ls->shader |= shader_flag;
- return (ls->pdf > 0.0f);
- }
- else {
- int lamp = -prim-1;
-
- if(UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) {
- return false;
- }
-
- return lamp_light_sample(kg, lamp, randu, randv, P, ls);
- }
+ /* sample index */
+ int index = light_distribution_sample(kg, &randu);
+
+ /* fetch light data */
+ const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch(__light_distribution,
+ index);
+ int prim = kdistribution->prim;
+
+ if (prim >= 0) {
+ int object = kdistribution->mesh_light.object_id;
+ int shader_flag = kdistribution->mesh_light.shader_flag;
+
+ triangle_light_sample(kg, prim, object, randu, randv, time, ls, P);
+ ls->shader |= shader_flag;
+ return (ls->pdf > 0.0f);
+ }
+ else {
+ int lamp = -prim - 1;
+
+ if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) {
+ return false;
+ }
+
+ return lamp_light_sample(kg, lamp, randu, randv, P, ls);
+ }
}
ccl_device int light_select_num_samples(KernelGlobals *kg, int index)
{
- return kernel_tex_fetch(__lights, index).samples;
+ return kernel_tex_fetch(__lights, index).samples;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_math.h b/intern/cycles/kernel/kernel_math.h
index a8a43f3ea4a..96391db7649 100644
--- a/intern/cycles/kernel/kernel_math.h
+++ b/intern/cycles/kernel/kernel_math.h
@@ -25,4 +25,4 @@
#include "util/util_texture.h"
#include "util/util_transform.h"
-#endif /* __KERNEL_MATH_H__ */
+#endif /* __KERNEL_MATH_H__ */
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index dde93844dd3..a933be970c2 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -38,248 +38,245 @@ CCL_NAMESPACE_BEGIN
/* distribute uniform xy on [0,1] over unit disk [-1,1] */
ccl_device void to_unit_disk(float *x, float *y)
{
- float phi = M_2PI_F * (*x);
- float r = sqrtf(*y);
+ float phi = M_2PI_F * (*x);
+ float r = sqrtf(*y);
- *x = r * cosf(phi);
- *y = r * sinf(phi);
+ *x = r * cosf(phi);
+ *y = r * sinf(phi);
}
/* return an orthogonal tangent and bitangent given a normal and tangent that
* may not be exactly orthogonal */
ccl_device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b)
{
- *b = normalize(cross(N, T));
- *a = cross(*b, N);
+ *b = normalize(cross(N, T));
+ *a = cross(*b, N);
}
/* sample direction with cosine weighted distributed in hemisphere */
-ccl_device_inline void sample_cos_hemisphere(const float3 N,
- float randu, float randv, float3 *omega_in, float *pdf)
+ccl_device_inline void sample_cos_hemisphere(
+ const float3 N, float randu, float randv, float3 *omega_in, float *pdf)
{
- to_unit_disk(&randu, &randv);
- float costheta = sqrtf(max(1.0f - randu * randu - randv * randv, 0.0f));
- float3 T, B;
- make_orthonormals(N, &T, &B);
- *omega_in = randu * T + randv * B + costheta * N;
- *pdf = costheta *M_1_PI_F;
+ to_unit_disk(&randu, &randv);
+ float costheta = sqrtf(max(1.0f - randu * randu - randv * randv, 0.0f));
+ float3 T, B;
+ make_orthonormals(N, &T, &B);
+ *omega_in = randu * T + randv * B + costheta * N;
+ *pdf = costheta * M_1_PI_F;
}
/* sample direction uniformly distributed in hemisphere */
-ccl_device_inline void sample_uniform_hemisphere(const float3 N,
- float randu, float randv,
- float3 *omega_in, float *pdf)
+ccl_device_inline void sample_uniform_hemisphere(
+ const float3 N, float randu, float randv, float3 *omega_in, float *pdf)
{
- float z = randu;
- float r = sqrtf(max(0.0f, 1.0f - z*z));
- float phi = M_2PI_F * randv;
- float x = r * cosf(phi);
- float y = r * sinf(phi);
-
- float3 T, B;
- make_orthonormals (N, &T, &B);
- *omega_in = x * T + y * B + z * N;
- *pdf = 0.5f * M_1_PI_F;
+ float z = randu;
+ float r = sqrtf(max(0.0f, 1.0f - z * z));
+ float phi = M_2PI_F * randv;
+ float x = r * cosf(phi);
+ float y = r * sinf(phi);
+
+ float3 T, B;
+ make_orthonormals(N, &T, &B);
+ *omega_in = x * T + y * B + z * N;
+ *pdf = 0.5f * M_1_PI_F;
}
/* sample direction uniformly distributed in cone */
-ccl_device_inline void sample_uniform_cone(const float3 N, float angle,
- float randu, float randv,
- float3 *omega_in, float *pdf)
+ccl_device_inline void sample_uniform_cone(
+ const float3 N, float angle, float randu, float randv, float3 *omega_in, float *pdf)
{
- float z = cosf(angle*randu);
- float r = sqrtf(max(0.0f, 1.0f - z*z));
- float phi = M_2PI_F * randv;
- float x = r * cosf(phi);
- float y = r * sinf(phi);
-
- float3 T, B;
- make_orthonormals (N, &T, &B);
- *omega_in = x * T + y * B + z * N;
- *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(angle));
+ float z = cosf(angle * randu);
+ float r = sqrtf(max(0.0f, 1.0f - z * z));
+ float phi = M_2PI_F * randv;
+ float x = r * cosf(phi);
+ float y = r * sinf(phi);
+
+ float3 T, B;
+ make_orthonormals(N, &T, &B);
+ *omega_in = x * T + y * B + z * N;
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(angle));
}
/* sample uniform point on the surface of a sphere */
ccl_device float3 sample_uniform_sphere(float u1, float u2)
{
- float z = 1.0f - 2.0f*u1;
- float r = sqrtf(fmaxf(0.0f, 1.0f - z*z));
- float phi = M_2PI_F*u2;
- float x = r*cosf(phi);
- float y = r*sinf(phi);
+ float z = 1.0f - 2.0f * u1;
+ float r = sqrtf(fmaxf(0.0f, 1.0f - z * z));
+ float phi = M_2PI_F * u2;
+ float x = r * cosf(phi);
+ float y = r * sinf(phi);
- return make_float3(x, y, z);
+ return make_float3(x, y, z);
}
ccl_device float balance_heuristic(float a, float b)
{
- return (a)/(a + b);
+ return (a) / (a + b);
}
ccl_device float balance_heuristic_3(float a, float b, float c)
{
- return (a)/(a + b + c);
+ return (a) / (a + b + c);
}
ccl_device float power_heuristic(float a, float b)
{
- return (a*a)/(a*a + b*b);
+ return (a * a) / (a * a + b * b);
}
ccl_device float power_heuristic_3(float a, float b, float c)
{
- return (a*a)/(a*a + b*b + c*c);
+ return (a * a) / (a * a + b * b + c * c);
}
ccl_device float max_heuristic(float a, float b)
{
- return (a > b)? 1.0f: 0.0f;
+ return (a > b) ? 1.0f : 0.0f;
}
/* distribute uniform xy on [0,1] over unit disk [-1,1], with concentric mapping
* to better preserve stratification for some RNG sequences */
ccl_device float2 concentric_sample_disk(float u1, float u2)
{
- float phi, r;
- float a = 2.0f*u1 - 1.0f;
- float b = 2.0f*u2 - 1.0f;
-
- if(a == 0.0f && b == 0.0f) {
- return make_float2(0.0f, 0.0f);
- }
- else if(a*a > b*b) {
- r = a;
- phi = M_PI_4_F * (b/a);
- }
- else {
- r = b;
- phi = M_PI_2_F - M_PI_4_F * (a/b);
- }
-
- return make_float2(r*cosf(phi), r*sinf(phi));
+ float phi, r;
+ float a = 2.0f * u1 - 1.0f;
+ float b = 2.0f * u2 - 1.0f;
+
+ if (a == 0.0f && b == 0.0f) {
+ return make_float2(0.0f, 0.0f);
+ }
+ else if (a * a > b * b) {
+ r = a;
+ phi = M_PI_4_F * (b / a);
+ }
+ else {
+ r = b;
+ phi = M_PI_2_F - M_PI_4_F * (a / b);
+ }
+
+ return make_float2(r * cosf(phi), r * sinf(phi));
}
/* sample point in unit polygon with given number of corners and rotation */
ccl_device float2 regular_polygon_sample(float corners, float rotation, float u, float v)
{
- /* sample corner number and reuse u */
- float corner = floorf(u*corners);
- u = u*corners - corner;
+ /* sample corner number and reuse u */
+ float corner = floorf(u * corners);
+ u = u * corners - corner;
- /* uniform sampled triangle weights */
- u = sqrtf(u);
- v = v*u;
- u = 1.0f - u;
+ /* uniform sampled triangle weights */
+ u = sqrtf(u);
+ v = v * u;
+ u = 1.0f - u;
- /* point in triangle */
- float angle = M_PI_F/corners;
- float2 p = make_float2((u + v)*cosf(angle), (u - v)*sinf(angle));
+ /* point in triangle */
+ float angle = M_PI_F / corners;
+ float2 p = make_float2((u + v) * cosf(angle), (u - v) * sinf(angle));
- /* rotate */
- rotation += corner*2.0f*angle;
+ /* rotate */
+ rotation += corner * 2.0f * angle;
- float cr = cosf(rotation);
- float sr = sinf(rotation);
+ float cr = cosf(rotation);
+ float sr = sinf(rotation);
- return make_float2(cr*p.x - sr*p.y, sr*p.x + cr*p.y);
+ return make_float2(cr * p.x - sr * p.y, sr * p.x + cr * p.y);
}
ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
{
- float3 R = 2*dot(N, I)*N - I;
-
- /* Reflection rays may always be at least as shallow as the incoming ray. */
- float threshold = min(0.9f*dot(Ng, I), 0.01f);
- if(dot(Ng, R) >= threshold) {
- return N;
- }
-
- /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane.
- * The X axis is found by normalizing the component of N that's orthogonal to Ng.
- * The Y axis isn't actually needed.
- */
- float NdotNg = dot(N, Ng);
- float3 X = normalize(N - NdotNg*Ng);
-
- /* Calculate N.z and N.x in the local coordinate system.
- *
- * The goal of this computation is to find a N' that is rotated towards Ng just enough
- * to lift R' above the threshold (here called t), therefore dot(R', Ng) = t.
- *
- * According to the standard reflection equation, this means that we want dot(2*dot(N', I)*N' - I, Ng) = t.
- *
- * Since the Z axis of our local coordinate system is Ng, dot(x, Ng) is just x.z, so we get 2*dot(N', I)*N'.z - I.z = t.
- *
- * The rotation is simple to express in the coordinate system we formed - since N lies in the X-Z-plane, we know that
- * N' will also lie in the X-Z-plane, so N'.y = 0 and therefore dot(N', I) = N'.x*I.x + N'.z*I.z .
- *
- * Furthermore, we want N' to be normalized, so N'.x = sqrt(1 - N'.z^2).
- *
- * With these simplifications, we get the final equation 2*(sqrt(1 - N'.z^2)*I.x + N'.z*I.z)*N'.z - I.z = t.
- *
- * The only unknown here is N'.z, so we can solve for that.
- *
- * The equation has four solutions in general:
- *
- * N'.z = +-sqrt(0.5*(+-sqrt(I.x^2*(I.x^2 + I.z^2 - t^2)) + t*I.z + I.x^2 + I.z^2)/(I.x^2 + I.z^2))
- * We can simplify this expression a bit by grouping terms:
- *
- * a = I.x^2 + I.z^2
- * b = sqrt(I.x^2 * (a - t^2))
- * c = I.z*t + a
- * N'.z = +-sqrt(0.5*(+-b + c)/a)
- *
- * Two solutions can immediately be discarded because they're negative so N' would lie in the lower hemisphere.
- */
- float Ix = dot(I, X), Iz = dot(I, Ng);
- float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
- float a = Ix2 + Iz2;
-
- float b = safe_sqrtf(Ix2*(a - sqr(threshold)));
- float c = Iz*threshold + a;
-
- /* Evaluate both solutions.
- * In many cases one can be immediately discarded (if N'.z would be imaginary or larger than one), so check for that first.
- * If no option is viable (might happen in extreme cases like N being in the wrong hemisphere), give up and return Ng. */
- float fac = 0.5f/a;
- float N1_z2 = fac*(b+c), N2_z2 = fac*(-b+c);
- bool valid1 = (N1_z2 > 1e-5f) && (N1_z2 <= (1.0f + 1e-5f));
- bool valid2 = (N2_z2 > 1e-5f) && (N2_z2 <= (1.0f + 1e-5f));
-
- float2 N_new;
- if(valid1 && valid2) {
- /* If both are possible, do the expensive reflection-based check. */
- float2 N1 = make_float2(safe_sqrtf(1.0f - N1_z2), safe_sqrtf(N1_z2));
- float2 N2 = make_float2(safe_sqrtf(1.0f - N2_z2), safe_sqrtf(N2_z2));
-
- float R1 = 2*(N1.x*Ix + N1.y*Iz)*N1.y - Iz;
- float R2 = 2*(N2.x*Ix + N2.y*Iz)*N2.y - Iz;
-
- valid1 = (R1 >= 1e-5f);
- valid2 = (R2 >= 1e-5f);
- if(valid1 && valid2) {
- /* If both solutions are valid, return the one with the shallower reflection since it will be closer to the input
- * (if the original reflection wasn't shallow, we would not be in this part of the function). */
- N_new = (R1 < R2)? N1 : N2;
- }
- else {
- /* If only one reflection is valid (= positive), pick that one. */
- N_new = (R1 > R2)? N1 : N2;
- }
-
- }
- else if(valid1 || valid2) {
- /* Only one solution passes the N'.z criterium, so pick that one. */
- float Nz2 = valid1? N1_z2 : N2_z2;
- N_new = make_float2(safe_sqrtf(1.0f - Nz2), safe_sqrtf(Nz2));
- }
- else {
- return Ng;
- }
-
- return N_new.x*X + N_new.y*Ng;
+ float3 R = 2 * dot(N, I) * N - I;
+
+ /* Reflection rays may always be at least as shallow as the incoming ray. */
+ float threshold = min(0.9f * dot(Ng, I), 0.01f);
+ if (dot(Ng, R) >= threshold) {
+ return N;
+ }
+
+ /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane.
+ * The X axis is found by normalizing the component of N that's orthogonal to Ng.
+ * The Y axis isn't actually needed.
+ */
+ float NdotNg = dot(N, Ng);
+ float3 X = normalize(N - NdotNg * Ng);
+
+ /* Calculate N.z and N.x in the local coordinate system.
+ *
+ * The goal of this computation is to find a N' that is rotated towards Ng just enough
+ * to lift R' above the threshold (here called t), therefore dot(R', Ng) = t.
+ *
+ * According to the standard reflection equation, this means that we want dot(2*dot(N', I)*N' - I, Ng) = t.
+ *
+ * Since the Z axis of our local coordinate system is Ng, dot(x, Ng) is just x.z, so we get 2*dot(N', I)*N'.z - I.z = t.
+ *
+ * The rotation is simple to express in the coordinate system we formed - since N lies in the X-Z-plane, we know that
+ * N' will also lie in the X-Z-plane, so N'.y = 0 and therefore dot(N', I) = N'.x*I.x + N'.z*I.z .
+ *
+ * Furthermore, we want N' to be normalized, so N'.x = sqrt(1 - N'.z^2).
+ *
+ * With these simplifications, we get the final equation 2*(sqrt(1 - N'.z^2)*I.x + N'.z*I.z)*N'.z - I.z = t.
+ *
+ * The only unknown here is N'.z, so we can solve for that.
+ *
+ * The equation has four solutions in general:
+ *
+ * N'.z = +-sqrt(0.5*(+-sqrt(I.x^2*(I.x^2 + I.z^2 - t^2)) + t*I.z + I.x^2 + I.z^2)/(I.x^2 + I.z^2))
+ * We can simplify this expression a bit by grouping terms:
+ *
+ * a = I.x^2 + I.z^2
+ * b = sqrt(I.x^2 * (a - t^2))
+ * c = I.z*t + a
+ * N'.z = +-sqrt(0.5*(+-b + c)/a)
+ *
+ * Two solutions can immediately be discarded because they're negative so N' would lie in the lower hemisphere.
+ */
+ float Ix = dot(I, X), Iz = dot(I, Ng);
+ float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
+ float a = Ix2 + Iz2;
+
+ float b = safe_sqrtf(Ix2 * (a - sqr(threshold)));
+ float c = Iz * threshold + a;
+
+ /* Evaluate both solutions.
+ * In many cases one can be immediately discarded (if N'.z would be imaginary or larger than one), so check for that first.
+ * If no option is viable (might happen in extreme cases like N being in the wrong hemisphere), give up and return Ng. */
+ float fac = 0.5f / a;
+ float N1_z2 = fac * (b + c), N2_z2 = fac * (-b + c);
+ bool valid1 = (N1_z2 > 1e-5f) && (N1_z2 <= (1.0f + 1e-5f));
+ bool valid2 = (N2_z2 > 1e-5f) && (N2_z2 <= (1.0f + 1e-5f));
+
+ float2 N_new;
+ if (valid1 && valid2) {
+ /* If both are possible, do the expensive reflection-based check. */
+ float2 N1 = make_float2(safe_sqrtf(1.0f - N1_z2), safe_sqrtf(N1_z2));
+ float2 N2 = make_float2(safe_sqrtf(1.0f - N2_z2), safe_sqrtf(N2_z2));
+
+ float R1 = 2 * (N1.x * Ix + N1.y * Iz) * N1.y - Iz;
+ float R2 = 2 * (N2.x * Ix + N2.y * Iz) * N2.y - Iz;
+
+ valid1 = (R1 >= 1e-5f);
+ valid2 = (R2 >= 1e-5f);
+ if (valid1 && valid2) {
+ /* If both solutions are valid, return the one with the shallower reflection since it will be closer to the input
+ * (if the original reflection wasn't shallow, we would not be in this part of the function). */
+ N_new = (R1 < R2) ? N1 : N2;
+ }
+ else {
+ /* If only one reflection is valid (= positive), pick that one. */
+ N_new = (R1 > R2) ? N1 : N2;
+ }
+ }
+ else if (valid1 || valid2) {
+ /* Only one solution passes the N'.z criterium, so pick that one. */
+ float Nz2 = valid1 ? N1_z2 : N2_z2;
+ N_new = make_float2(safe_sqrtf(1.0f - Nz2), safe_sqrtf(Nz2));
+ }
+ else {
+ return Ng;
+ }
+
+ return N_new.x * X + N_new.y * Ng;
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_MONTECARLO_CL__ */
+#endif /* __KERNEL_MONTECARLO_CL__ */
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 08e9db05c39..462ec037ee7 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -15,7 +15,7 @@
*/
#if defined(__SPLIT_KERNEL__) || defined(__KERNEL_CUDA__)
-#define __ATOMIC_PASS_WRITE__
+# define __ATOMIC_PASS_WRITE__
#endif
#include "kernel/kernel_id_passes.h"
@@ -24,56 +24,56 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline void kernel_write_pass_float(ccl_global float *buffer, float value)
{
- ccl_global float *buf = buffer;
+ ccl_global float *buf = buffer;
#ifdef __ATOMIC_PASS_WRITE__
- atomic_add_and_fetch_float(buf, value);
+ atomic_add_and_fetch_float(buf, value);
#else
- *buf += value;
+ *buf += value;
#endif
}
ccl_device_inline void kernel_write_pass_float3(ccl_global float *buffer, float3 value)
{
#ifdef __ATOMIC_PASS_WRITE__
- ccl_global float *buf_x = buffer + 0;
- ccl_global float *buf_y = buffer + 1;
- ccl_global float *buf_z = buffer + 2;
+ ccl_global float *buf_x = buffer + 0;
+ ccl_global float *buf_y = buffer + 1;
+ ccl_global float *buf_z = buffer + 2;
- atomic_add_and_fetch_float(buf_x, value.x);
- atomic_add_and_fetch_float(buf_y, value.y);
- atomic_add_and_fetch_float(buf_z, value.z);
+ atomic_add_and_fetch_float(buf_x, value.x);
+ atomic_add_and_fetch_float(buf_y, value.y);
+ atomic_add_and_fetch_float(buf_z, value.z);
#else
- ccl_global float3 *buf = (ccl_global float3*)buffer;
- *buf += value;
+ ccl_global float3 *buf = (ccl_global float3 *)buffer;
+ *buf += value;
#endif
}
ccl_device_inline void kernel_write_pass_float4(ccl_global float *buffer, float4 value)
{
#ifdef __ATOMIC_PASS_WRITE__
- ccl_global float *buf_x = buffer + 0;
- ccl_global float *buf_y = buffer + 1;
- ccl_global float *buf_z = buffer + 2;
- ccl_global float *buf_w = buffer + 3;
-
- atomic_add_and_fetch_float(buf_x, value.x);
- atomic_add_and_fetch_float(buf_y, value.y);
- atomic_add_and_fetch_float(buf_z, value.z);
- atomic_add_and_fetch_float(buf_w, value.w);
+ ccl_global float *buf_x = buffer + 0;
+ ccl_global float *buf_y = buffer + 1;
+ ccl_global float *buf_z = buffer + 2;
+ ccl_global float *buf_w = buffer + 3;
+
+ atomic_add_and_fetch_float(buf_x, value.x);
+ atomic_add_and_fetch_float(buf_y, value.y);
+ atomic_add_and_fetch_float(buf_z, value.z);
+ atomic_add_and_fetch_float(buf_w, value.w);
#else
- ccl_global float4 *buf = (ccl_global float4*)buffer;
- *buf += value;
+ ccl_global float4 *buf = (ccl_global float4 *)buffer;
+ *buf += value;
#endif
}
#ifdef __DENOISING_FEATURES__
ccl_device_inline void kernel_write_pass_float_variance(ccl_global float *buffer, float value)
{
- kernel_write_pass_float(buffer, value);
+ kernel_write_pass_float(buffer, value);
- /* The online one-pass variance update that's used for the megakernel can't easily be implemented
- * with atomics, so for the split kernel the E[x^2] - 1/N * (E[x])^2 fallback is used. */
- kernel_write_pass_float(buffer+1, value*value);
+ /* The online one-pass variance update that's used for the megakernel can't easily be implemented
+ * with atomics, so for the split kernel the E[x^2] - 1/N * (E[x])^2 fallback is used. */
+ kernel_write_pass_float(buffer + 1, value * value);
}
# ifdef __ATOMIC_PASS_WRITE__
@@ -81,36 +81,39 @@ ccl_device_inline void kernel_write_pass_float_variance(ccl_global float *buffer
# else
ccl_device_inline void kernel_write_pass_float3_unaligned(ccl_global float *buffer, float3 value)
{
- buffer[0] += value.x;
- buffer[1] += value.y;
- buffer[2] += value.z;
+ buffer[0] += value.x;
+ buffer[1] += value.y;
+ buffer[2] += value.z;
}
# endif
ccl_device_inline void kernel_write_pass_float3_variance(ccl_global float *buffer, float3 value)
{
- kernel_write_pass_float3_unaligned(buffer, value);
- kernel_write_pass_float3_unaligned(buffer+3, value*value);
+ kernel_write_pass_float3_unaligned(buffer, value);
+ kernel_write_pass_float3_unaligned(buffer + 3, value * value);
}
-ccl_device_inline void kernel_write_denoising_shadow(KernelGlobals *kg, ccl_global float *buffer,
- int sample, float path_total, float path_total_shaded)
+ccl_device_inline void kernel_write_denoising_shadow(KernelGlobals *kg,
+ ccl_global float *buffer,
+ int sample,
+ float path_total,
+ float path_total_shaded)
{
- if(kernel_data.film.pass_denoising_data == 0)
- return;
+ if (kernel_data.film.pass_denoising_data == 0)
+ return;
- buffer += (sample & 1)? DENOISING_PASS_SHADOW_B : DENOISING_PASS_SHADOW_A;
+ buffer += (sample & 1) ? DENOISING_PASS_SHADOW_B : DENOISING_PASS_SHADOW_A;
- path_total = ensure_finite(path_total);
- path_total_shaded = ensure_finite(path_total_shaded);
+ path_total = ensure_finite(path_total);
+ path_total_shaded = ensure_finite(path_total_shaded);
- kernel_write_pass_float(buffer, path_total);
- kernel_write_pass_float(buffer+1, path_total_shaded);
+ kernel_write_pass_float(buffer, path_total);
+ kernel_write_pass_float(buffer + 1, path_total_shaded);
- float value = path_total_shaded / max(path_total, 1e-7f);
- kernel_write_pass_float(buffer+2, value*value);
+ float value = path_total_shaded / max(path_total, 1e-7f);
+ kernel_write_pass_float(buffer + 2, value * value);
}
-#endif /* __DENOISING_FEATURES__ */
+#endif /* __DENOISING_FEATURES__ */
ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg,
ShaderData *sd,
@@ -118,52 +121,52 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg,
PathRadiance *L)
{
#ifdef __DENOISING_FEATURES__
- if(state->denoising_feature_weight == 0.0f) {
- return;
- }
-
- L->denoising_depth += ensure_finite(state->denoising_feature_weight * sd->ray_length);
-
- /* Skip implicitly transparent surfaces. */
- if(sd->flag & SD_HAS_ONLY_VOLUME) {
- return;
- }
-
- float3 normal = make_float3(0.0f, 0.0f, 0.0f);
- float3 albedo = make_float3(0.0f, 0.0f, 0.0f);
- float sum_weight = 0.0f, sum_nonspecular_weight = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type))
- continue;
-
- /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */
- normal += sc->N * sc->sample_weight;
- sum_weight += sc->sample_weight;
- if(bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
- albedo += sc->weight;
- sum_nonspecular_weight += sc->sample_weight;
- }
- }
-
- /* Wait for next bounce if 75% or more sample weight belongs to specular-like closures. */
- if((sum_weight == 0.0f) || (sum_nonspecular_weight*4.0f > sum_weight)) {
- if(sum_weight != 0.0f) {
- normal /= sum_weight;
- }
- L->denoising_normal += ensure_finite3(state->denoising_feature_weight * normal);
- L->denoising_albedo += ensure_finite3(state->denoising_feature_weight * albedo);
-
- state->denoising_feature_weight = 0.0f;
- }
+ if (state->denoising_feature_weight == 0.0f) {
+ return;
+ }
+
+ L->denoising_depth += ensure_finite(state->denoising_feature_weight * sd->ray_length);
+
+ /* Skip implicitly transparent surfaces. */
+ if (sd->flag & SD_HAS_ONLY_VOLUME) {
+ return;
+ }
+
+ float3 normal = make_float3(0.0f, 0.0f, 0.0f);
+ float3 albedo = make_float3(0.0f, 0.0f, 0.0f);
+ float sum_weight = 0.0f, sum_nonspecular_weight = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+
+ if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type))
+ continue;
+
+ /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */
+ normal += sc->N * sc->sample_weight;
+ sum_weight += sc->sample_weight;
+ if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
+ albedo += sc->weight;
+ sum_nonspecular_weight += sc->sample_weight;
+ }
+ }
+
+ /* Wait for next bounce if 75% or more sample weight belongs to specular-like closures. */
+ if ((sum_weight == 0.0f) || (sum_nonspecular_weight * 4.0f > sum_weight)) {
+ if (sum_weight != 0.0f) {
+ normal /= sum_weight;
+ }
+ L->denoising_normal += ensure_finite3(state->denoising_feature_weight * normal);
+ L->denoising_albedo += ensure_finite3(state->denoising_feature_weight * albedo);
+
+ state->denoising_feature_weight = 0.0f;
+ }
#else
- (void) kg;
- (void) sd;
- (void) state;
- (void) L;
-#endif /* __DENOISING_FEATURES__ */
+ (void)kg;
+ (void)sd;
+ (void)state;
+ (void)L;
+#endif /* __DENOISING_FEATURES__ */
}
#ifdef __KERNEL_DEBUG__
@@ -171,203 +174,221 @@ ccl_device_inline void kernel_write_debug_passes(KernelGlobals *kg,
ccl_global float *buffer,
PathRadiance *L)
{
- int flag = kernel_data.film.pass_flag;
- if(flag & PASSMASK(BVH_TRAVERSED_NODES)) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_nodes,
- L->debug_data.num_bvh_traversed_nodes);
- }
- if(flag & PASSMASK(BVH_TRAVERSED_INSTANCES)) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_instances,
- L->debug_data.num_bvh_traversed_instances);
- }
- if(flag & PASSMASK(BVH_INTERSECTIONS)) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_intersections,
- L->debug_data.num_bvh_intersections);
- }
- if(flag & PASSMASK(RAY_BOUNCES)) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_ray_bounces,
- L->debug_data.num_ray_bounces);
- }
+ int flag = kernel_data.film.pass_flag;
+ if (flag & PASSMASK(BVH_TRAVERSED_NODES)) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_nodes,
+ L->debug_data.num_bvh_traversed_nodes);
+ }
+ if (flag & PASSMASK(BVH_TRAVERSED_INSTANCES)) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_instances,
+ L->debug_data.num_bvh_traversed_instances);
+ }
+ if (flag & PASSMASK(BVH_INTERSECTIONS)) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_intersections,
+ L->debug_data.num_bvh_intersections);
+ }
+ if (flag & PASSMASK(RAY_BOUNCES)) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_ray_bounces,
+ L->debug_data.num_ray_bounces);
+ }
}
-#endif /* __KERNEL_DEBUG__ */
+#endif /* __KERNEL_DEBUG__ */
#ifdef __KERNEL_CPU__
-#define WRITE_ID_SLOT(buffer, depth, id, matte_weight, name) kernel_write_id_pass_cpu(buffer, depth * 2, id, matte_weight, kg->coverage_##name)
-ccl_device_inline size_t kernel_write_id_pass_cpu(float *buffer, size_t depth, float id, float matte_weight, CoverageMap *map)
+# define WRITE_ID_SLOT(buffer, depth, id, matte_weight, name) \
+ kernel_write_id_pass_cpu(buffer, depth * 2, id, matte_weight, kg->coverage_##name)
+ccl_device_inline size_t kernel_write_id_pass_cpu(
+ float *buffer, size_t depth, float id, float matte_weight, CoverageMap *map)
{
- if(map) {
- (*map)[id] += matte_weight;
- return 0;
- }
-#else /* __KERNEL_CPU__ */
-#define WRITE_ID_SLOT(buffer, depth, id, matte_weight, name) kernel_write_id_slots_gpu(buffer, depth * 2, id, matte_weight)
-ccl_device_inline size_t kernel_write_id_slots_gpu(ccl_global float *buffer, size_t depth, float id, float matte_weight)
+ if (map) {
+ (*map)[id] += matte_weight;
+ return 0;
+ }
+#else /* __KERNEL_CPU__ */
+# define WRITE_ID_SLOT(buffer, depth, id, matte_weight, name) \
+ kernel_write_id_slots_gpu(buffer, depth * 2, id, matte_weight)
+ccl_device_inline size_t kernel_write_id_slots_gpu(ccl_global float *buffer,
+ size_t depth,
+ float id,
+ float matte_weight)
{
-#endif /* __KERNEL_CPU__ */
- kernel_write_id_slots(buffer, depth, id, matte_weight);
- return depth * 2;
+#endif /* __KERNEL_CPU__ */
+ kernel_write_id_slots(buffer, depth, id, matte_weight);
+ return depth * 2;
}
-ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L,
- ShaderData *sd, ccl_addr_space PathState *state, float3 throughput)
+ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg,
+ ccl_global float *buffer,
+ PathRadiance *L,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ float3 throughput)
{
#ifdef __PASSES__
- int path_flag = state->flag;
-
- if(!(path_flag & PATH_RAY_CAMERA))
- return;
-
- int flag = kernel_data.film.pass_flag;
- int light_flag = kernel_data.film.light_pass_flag;
-
- if(!((flag | light_flag) & PASS_ANY))
- return;
-
- if(!(path_flag & PATH_RAY_SINGLE_PASS_DONE)) {
- if(!(sd->flag & SD_TRANSPARENT) ||
- kernel_data.film.pass_alpha_threshold == 0.0f ||
- average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold)
- {
- if(state->sample == 0) {
- if(flag & PASSMASK(DEPTH)) {
- float depth = camera_distance(kg, sd->P);
- kernel_write_pass_float(buffer + kernel_data.film.pass_depth, depth);
- }
- if(flag & PASSMASK(OBJECT_ID)) {
- float id = object_pass_id(kg, sd->object);
- kernel_write_pass_float(buffer + kernel_data.film.pass_object_id, id);
- }
- if(flag & PASSMASK(MATERIAL_ID)) {
- float id = shader_pass_id(kg, sd);
- kernel_write_pass_float(buffer + kernel_data.film.pass_material_id, id);
- }
- }
-
- if(flag & PASSMASK(NORMAL)) {
- float3 normal = shader_bsdf_average_normal(kg, sd);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, normal);
- }
- if(flag & PASSMASK(UV)) {
- float3 uv = primitive_uv(kg, sd);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, uv);
- }
- if(flag & PASSMASK(MOTION)) {
- float4 speed = primitive_motion_vector(kg, sd);
- kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, speed);
- kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, 1.0f);
- }
-
- state->flag |= PATH_RAY_SINGLE_PASS_DONE;
- }
- }
-
- if(kernel_data.film.cryptomatte_passes) {
- const float matte_weight = average(throughput) * (1.0f - average(shader_bsdf_transparency(kg, sd)));
- if(matte_weight > 0.0f) {
- ccl_global float *cryptomatte_buffer = buffer + kernel_data.film.pass_cryptomatte;
- if(kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
- float id = object_cryptomatte_id(kg, sd->object);
- cryptomatte_buffer += WRITE_ID_SLOT(cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight, object);
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
- float id = shader_cryptomatte_id(kg, sd->shader);
- cryptomatte_buffer += WRITE_ID_SLOT(cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight, material);
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
- float id = object_cryptomatte_asset_id(kg, sd->object);
- cryptomatte_buffer += WRITE_ID_SLOT(cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight, asset);
- }
- }
- }
-
-
- if(light_flag & PASSMASK_COMPONENT(DIFFUSE))
- L->color_diffuse += shader_bsdf_diffuse(kg, sd)*throughput;
- if(light_flag & PASSMASK_COMPONENT(GLOSSY))
- L->color_glossy += shader_bsdf_glossy(kg, sd)*throughput;
- if(light_flag & PASSMASK_COMPONENT(TRANSMISSION))
- L->color_transmission += shader_bsdf_transmission(kg, sd)*throughput;
- if(light_flag & PASSMASK_COMPONENT(SUBSURFACE))
- L->color_subsurface += shader_bsdf_subsurface(kg, sd)*throughput;
-
- if(light_flag & PASSMASK(MIST)) {
- /* bring depth into 0..1 range */
- float mist_start = kernel_data.film.mist_start;
- float mist_inv_depth = kernel_data.film.mist_inv_depth;
-
- float depth = camera_distance(kg, sd->P);
- float mist = saturate((depth - mist_start)*mist_inv_depth);
-
- /* falloff */
- float mist_falloff = kernel_data.film.mist_falloff;
-
- if(mist_falloff == 1.0f)
- ;
- else if(mist_falloff == 2.0f)
- mist = mist*mist;
- else if(mist_falloff == 0.5f)
- mist = sqrtf(mist);
- else
- mist = powf(mist, mist_falloff);
-
- /* modulate by transparency */
- float3 alpha = shader_bsdf_alpha(kg, sd);
- L->mist += (1.0f - mist)*average(throughput*alpha);
- }
+ int path_flag = state->flag;
+
+ if (!(path_flag & PATH_RAY_CAMERA))
+ return;
+
+ int flag = kernel_data.film.pass_flag;
+ int light_flag = kernel_data.film.light_pass_flag;
+
+ if (!((flag | light_flag) & PASS_ANY))
+ return;
+
+ if (!(path_flag & PATH_RAY_SINGLE_PASS_DONE)) {
+ if (!(sd->flag & SD_TRANSPARENT) || kernel_data.film.pass_alpha_threshold == 0.0f ||
+ average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold) {
+ if (state->sample == 0) {
+ if (flag & PASSMASK(DEPTH)) {
+ float depth = camera_distance(kg, sd->P);
+ kernel_write_pass_float(buffer + kernel_data.film.pass_depth, depth);
+ }
+ if (flag & PASSMASK(OBJECT_ID)) {
+ float id = object_pass_id(kg, sd->object);
+ kernel_write_pass_float(buffer + kernel_data.film.pass_object_id, id);
+ }
+ if (flag & PASSMASK(MATERIAL_ID)) {
+ float id = shader_pass_id(kg, sd);
+ kernel_write_pass_float(buffer + kernel_data.film.pass_material_id, id);
+ }
+ }
+
+ if (flag & PASSMASK(NORMAL)) {
+ float3 normal = shader_bsdf_average_normal(kg, sd);
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, normal);
+ }
+ if (flag & PASSMASK(UV)) {
+ float3 uv = primitive_uv(kg, sd);
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, uv);
+ }
+ if (flag & PASSMASK(MOTION)) {
+ float4 speed = primitive_motion_vector(kg, sd);
+ kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, speed);
+ kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, 1.0f);
+ }
+
+ state->flag |= PATH_RAY_SINGLE_PASS_DONE;
+ }
+ }
+
+ if (kernel_data.film.cryptomatte_passes) {
+ const float matte_weight = average(throughput) *
+ (1.0f - average(shader_bsdf_transparency(kg, sd)));
+ if (matte_weight > 0.0f) {
+ ccl_global float *cryptomatte_buffer = buffer + kernel_data.film.pass_cryptomatte;
+ if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
+ float id = object_cryptomatte_id(kg, sd->object);
+ cryptomatte_buffer += WRITE_ID_SLOT(
+ cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight, object);
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
+ float id = shader_cryptomatte_id(kg, sd->shader);
+ cryptomatte_buffer += WRITE_ID_SLOT(
+ cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight, material);
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
+ float id = object_cryptomatte_asset_id(kg, sd->object);
+ cryptomatte_buffer += WRITE_ID_SLOT(
+ cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight, asset);
+ }
+ }
+ }
+
+ if (light_flag & PASSMASK_COMPONENT(DIFFUSE))
+ L->color_diffuse += shader_bsdf_diffuse(kg, sd) * throughput;
+ if (light_flag & PASSMASK_COMPONENT(GLOSSY))
+ L->color_glossy += shader_bsdf_glossy(kg, sd) * throughput;
+ if (light_flag & PASSMASK_COMPONENT(TRANSMISSION))
+ L->color_transmission += shader_bsdf_transmission(kg, sd) * throughput;
+ if (light_flag & PASSMASK_COMPONENT(SUBSURFACE))
+ L->color_subsurface += shader_bsdf_subsurface(kg, sd) * throughput;
+
+ if (light_flag & PASSMASK(MIST)) {
+ /* bring depth into 0..1 range */
+ float mist_start = kernel_data.film.mist_start;
+ float mist_inv_depth = kernel_data.film.mist_inv_depth;
+
+ float depth = camera_distance(kg, sd->P);
+ float mist = saturate((depth - mist_start) * mist_inv_depth);
+
+ /* falloff */
+ float mist_falloff = kernel_data.film.mist_falloff;
+
+ if (mist_falloff == 1.0f)
+ ;
+ else if (mist_falloff == 2.0f)
+ mist = mist * mist;
+ else if (mist_falloff == 0.5f)
+ mist = sqrtf(mist);
+ else
+ mist = powf(mist, mist_falloff);
+
+ /* modulate by transparency */
+ float3 alpha = shader_bsdf_alpha(kg, sd);
+ L->mist += (1.0f - mist) * average(throughput * alpha);
+ }
#endif
}
-ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L)
+ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg,
+ ccl_global float *buffer,
+ PathRadiance *L)
{
#ifdef __PASSES__
- int light_flag = kernel_data.film.light_pass_flag;
-
- if(!kernel_data.film.use_light_pass)
- return;
-
- if(light_flag & PASSMASK(DIFFUSE_INDIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, L->indirect_diffuse);
- if(light_flag & PASSMASK(GLOSSY_INDIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, L->indirect_glossy);
- if(light_flag & PASSMASK(TRANSMISSION_INDIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, L->indirect_transmission);
- if(light_flag & PASSMASK(SUBSURFACE_INDIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_indirect, L->indirect_subsurface);
- if(light_flag & PASSMASK(VOLUME_INDIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_indirect, L->indirect_scatter);
- if(light_flag & PASSMASK(DIFFUSE_DIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, L->direct_diffuse);
- if(light_flag & PASSMASK(GLOSSY_DIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, L->direct_glossy);
- if(light_flag & PASSMASK(TRANSMISSION_DIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, L->direct_transmission);
- if(light_flag & PASSMASK(SUBSURFACE_DIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_direct, L->direct_subsurface);
- if(light_flag & PASSMASK(VOLUME_DIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_direct, L->direct_scatter);
-
- if(light_flag & PASSMASK(EMISSION))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, L->emission);
- if(light_flag & PASSMASK(BACKGROUND))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_background, L->background);
- if(light_flag & PASSMASK(AO))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, L->ao);
-
- if(light_flag & PASSMASK(DIFFUSE_COLOR))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, L->color_diffuse);
- if(light_flag & PASSMASK(GLOSSY_COLOR))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, L->color_glossy);
- if(light_flag & PASSMASK(TRANSMISSION_COLOR))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, L->color_transmission);
- if(light_flag & PASSMASK(SUBSURFACE_COLOR))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_color, L->color_subsurface);
- if(light_flag & PASSMASK(SHADOW)) {
- float4 shadow = L->shadow;
- shadow.w = kernel_data.film.pass_shadow_scale;
- kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, shadow);
- }
- if(light_flag & PASSMASK(MIST))
- kernel_write_pass_float(buffer + kernel_data.film.pass_mist, 1.0f - L->mist);
+ int light_flag = kernel_data.film.light_pass_flag;
+
+ if (!kernel_data.film.use_light_pass)
+ return;
+
+ if (light_flag & PASSMASK(DIFFUSE_INDIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, L->indirect_diffuse);
+ if (light_flag & PASSMASK(GLOSSY_INDIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, L->indirect_glossy);
+ if (light_flag & PASSMASK(TRANSMISSION_INDIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect,
+ L->indirect_transmission);
+ if (light_flag & PASSMASK(SUBSURFACE_INDIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_indirect,
+ L->indirect_subsurface);
+ if (light_flag & PASSMASK(VOLUME_INDIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_indirect, L->indirect_scatter);
+ if (light_flag & PASSMASK(DIFFUSE_DIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, L->direct_diffuse);
+ if (light_flag & PASSMASK(GLOSSY_DIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, L->direct_glossy);
+ if (light_flag & PASSMASK(TRANSMISSION_DIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct,
+ L->direct_transmission);
+ if (light_flag & PASSMASK(SUBSURFACE_DIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_direct,
+ L->direct_subsurface);
+ if (light_flag & PASSMASK(VOLUME_DIRECT))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_direct, L->direct_scatter);
+
+ if (light_flag & PASSMASK(EMISSION))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, L->emission);
+ if (light_flag & PASSMASK(BACKGROUND))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_background, L->background);
+ if (light_flag & PASSMASK(AO))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, L->ao);
+
+ if (light_flag & PASSMASK(DIFFUSE_COLOR))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, L->color_diffuse);
+ if (light_flag & PASSMASK(GLOSSY_COLOR))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, L->color_glossy);
+ if (light_flag & PASSMASK(TRANSMISSION_COLOR))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color,
+ L->color_transmission);
+ if (light_flag & PASSMASK(SUBSURFACE_COLOR))
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_color, L->color_subsurface);
+ if (light_flag & PASSMASK(SHADOW)) {
+ float4 shadow = L->shadow;
+ shadow.w = kernel_data.film.pass_shadow_scale;
+ kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, shadow);
+ }
+ if (light_flag & PASSMASK(MIST))
+ kernel_write_pass_float(buffer + kernel_data.film.pass_mist, 1.0f - L->mist);
#endif
}
@@ -376,60 +397,54 @@ ccl_device_inline void kernel_write_result(KernelGlobals *kg,
int sample,
PathRadiance *L)
{
- PROFILING_INIT(kg, PROFILING_WRITE_RESULT);
- PROFILING_OBJECT(PRIM_NONE);
+ PROFILING_INIT(kg, PROFILING_WRITE_RESULT);
+ PROFILING_OBJECT(PRIM_NONE);
- float alpha;
- float3 L_sum = path_radiance_clamp_and_sum(kg, L, &alpha);
+ float alpha;
+ float3 L_sum = path_radiance_clamp_and_sum(kg, L, &alpha);
- kernel_write_pass_float4(buffer, make_float4(L_sum.x, L_sum.y, L_sum.z, alpha));
+ kernel_write_pass_float4(buffer, make_float4(L_sum.x, L_sum.y, L_sum.z, alpha));
- kernel_write_light_passes(kg, buffer, L);
+ kernel_write_light_passes(kg, buffer, L);
#ifdef __DENOISING_FEATURES__
- if(kernel_data.film.pass_denoising_data) {
+ if (kernel_data.film.pass_denoising_data) {
# ifdef __SHADOW_TRICKS__
- kernel_write_denoising_shadow(kg,
- buffer + kernel_data.film.pass_denoising_data,
- sample,
- average(L->path_total),
- average(L->path_total_shaded));
+ kernel_write_denoising_shadow(kg,
+ buffer + kernel_data.film.pass_denoising_data,
+ sample,
+ average(L->path_total),
+ average(L->path_total_shaded));
# else
- kernel_write_denoising_shadow(kg,
- buffer + kernel_data.film.pass_denoising_data,
- sample,
- 0.0f, 0.0f);
+ kernel_write_denoising_shadow(
+ kg, buffer + kernel_data.film.pass_denoising_data, sample, 0.0f, 0.0f);
# endif
- if(kernel_data.film.pass_denoising_clean) {
- float3 noisy, clean;
- path_radiance_split_denoising(kg, L, &noisy, &clean);
- kernel_write_pass_float3_variance(
- buffer + kernel_data.film.pass_denoising_data + DENOISING_PASS_COLOR,
- noisy);
- kernel_write_pass_float3_unaligned(
- buffer + kernel_data.film.pass_denoising_clean,
- clean);
- }
- else {
- kernel_write_pass_float3_variance(buffer + kernel_data.film.pass_denoising_data + DENOISING_PASS_COLOR,
- ensure_finite3(L_sum));
- }
-
- kernel_write_pass_float3_variance(
- buffer + kernel_data.film.pass_denoising_data + DENOISING_PASS_NORMAL,
- L->denoising_normal);
- kernel_write_pass_float3_variance(
- buffer + kernel_data.film.pass_denoising_data + DENOISING_PASS_ALBEDO,
- L->denoising_albedo);
- kernel_write_pass_float_variance(
- buffer + kernel_data.film.pass_denoising_data + DENOISING_PASS_DEPTH,
- L->denoising_depth);
- }
-#endif /* __DENOISING_FEATURES__ */
-
+ if (kernel_data.film.pass_denoising_clean) {
+ float3 noisy, clean;
+ path_radiance_split_denoising(kg, L, &noisy, &clean);
+ kernel_write_pass_float3_variance(
+ buffer + kernel_data.film.pass_denoising_data + DENOISING_PASS_COLOR, noisy);
+ kernel_write_pass_float3_unaligned(buffer + kernel_data.film.pass_denoising_clean, clean);
+ }
+ else {
+ kernel_write_pass_float3_variance(buffer + kernel_data.film.pass_denoising_data +
+ DENOISING_PASS_COLOR,
+ ensure_finite3(L_sum));
+ }
+
+ kernel_write_pass_float3_variance(buffer + kernel_data.film.pass_denoising_data +
+ DENOISING_PASS_NORMAL,
+ L->denoising_normal);
+ kernel_write_pass_float3_variance(buffer + kernel_data.film.pass_denoising_data +
+ DENOISING_PASS_ALBEDO,
+ L->denoising_albedo);
+ kernel_write_pass_float_variance(
+ buffer + kernel_data.film.pass_denoising_data + DENOISING_PASS_DEPTH, L->denoising_depth);
+ }
+#endif /* __DENOISING_FEATURES__ */
#ifdef __KERNEL_DEBUG__
- kernel_write_debug_passes(kg, buffer, L);
+ kernel_write_debug_passes(kg, buffer, L);
#endif
}
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index a1fc6028293..2be1b745632 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -50,309 +50,298 @@
CCL_NAMESPACE_BEGIN
-ccl_device_forceinline bool kernel_path_scene_intersect(
- KernelGlobals *kg,
- ccl_addr_space PathState *state,
- Ray *ray,
- Intersection *isect,
- PathRadiance *L)
+ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ Intersection *isect,
+ PathRadiance *L)
{
- PROFILING_INIT(kg, PROFILING_SCENE_INTERSECT);
+ PROFILING_INIT(kg, PROFILING_SCENE_INTERSECT);
- uint visibility = path_state_ray_visibility(kg, state);
+ uint visibility = path_state_ray_visibility(kg, state);
- if(path_state_ao_bounce(kg, state)) {
- visibility = PATH_RAY_SHADOW;
- ray->t = kernel_data.background.ao_distance;
- }
+ if (path_state_ao_bounce(kg, state)) {
+ visibility = PATH_RAY_SHADOW;
+ ray->t = kernel_data.background.ao_distance;
+ }
#ifdef __HAIR__
- float difl = 0.0f, extmax = 0.0f;
- uint lcg_state = 0;
+ float difl = 0.0f, extmax = 0.0f;
+ uint lcg_state = 0;
- if(kernel_data.bvh.have_curves) {
- if((kernel_data.cam.resolution == 1) && (state->flag & PATH_RAY_CAMERA)) {
- float3 pixdiff = ray->dD.dx + ray->dD.dy;
- /*pixdiff = pixdiff - dot(pixdiff, ray.D)*ray.D;*/
- difl = kernel_data.curve.minimum_width * len(pixdiff) * 0.5f;
- }
+ if (kernel_data.bvh.have_curves) {
+ if ((kernel_data.cam.resolution == 1) && (state->flag & PATH_RAY_CAMERA)) {
+ float3 pixdiff = ray->dD.dx + ray->dD.dy;
+ /*pixdiff = pixdiff - dot(pixdiff, ray.D)*ray.D;*/
+ difl = kernel_data.curve.minimum_width * len(pixdiff) * 0.5f;
+ }
- extmax = kernel_data.curve.maximum_width;
- lcg_state = lcg_state_init_addrspace(state, 0x51633e2d);
- }
+ extmax = kernel_data.curve.maximum_width;
+ lcg_state = lcg_state_init_addrspace(state, 0x51633e2d);
+ }
- bool hit = scene_intersect(kg, *ray, visibility, isect, &lcg_state, difl, extmax);
+ bool hit = scene_intersect(kg, *ray, visibility, isect, &lcg_state, difl, extmax);
#else
- bool hit = scene_intersect(kg, *ray, visibility, isect, NULL, 0.0f, 0.0f);
-#endif /* __HAIR__ */
+ bool hit = scene_intersect(kg, *ray, visibility, isect, NULL, 0.0f, 0.0f);
+#endif /* __HAIR__ */
#ifdef __KERNEL_DEBUG__
- if(state->flag & PATH_RAY_CAMERA) {
- L->debug_data.num_bvh_traversed_nodes += isect->num_traversed_nodes;
- L->debug_data.num_bvh_traversed_instances += isect->num_traversed_instances;
- L->debug_data.num_bvh_intersections += isect->num_intersections;
- }
- L->debug_data.num_ray_bounces++;
-#endif /* __KERNEL_DEBUG__ */
-
- return hit;
+ if (state->flag & PATH_RAY_CAMERA) {
+ L->debug_data.num_bvh_traversed_nodes += isect->num_traversed_nodes;
+ L->debug_data.num_bvh_traversed_instances += isect->num_traversed_instances;
+ L->debug_data.num_bvh_intersections += isect->num_intersections;
+ }
+ L->debug_data.num_ray_bounces++;
+#endif /* __KERNEL_DEBUG__ */
+
+ return hit;
}
-ccl_device_forceinline void kernel_path_lamp_emission(
- KernelGlobals *kg,
- ccl_addr_space PathState *state,
- Ray *ray,
- float3 throughput,
- ccl_addr_space Intersection *isect,
- ShaderData *emission_sd,
- PathRadiance *L)
+ccl_device_forceinline void kernel_path_lamp_emission(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ float3 throughput,
+ ccl_addr_space Intersection *isect,
+ ShaderData *emission_sd,
+ PathRadiance *L)
{
- PROFILING_INIT(kg, PROFILING_INDIRECT_EMISSION);
+ PROFILING_INIT(kg, PROFILING_INDIRECT_EMISSION);
#ifdef __LAMP_MIS__
- if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
- /* ray starting from previous non-transparent bounce */
- Ray light_ray;
-
- light_ray.P = ray->P - state->ray_t*ray->D;
- state->ray_t += isect->t;
- light_ray.D = ray->D;
- light_ray.t = state->ray_t;
- light_ray.time = ray->time;
- light_ray.dD = ray->dD;
- light_ray.dP = ray->dP;
-
- /* intersect with lamp */
- float3 emission;
-
- if(indirect_lamp_emission(kg, emission_sd, state, &light_ray, &emission))
- path_radiance_accum_emission(L, state, throughput, emission);
- }
-#endif /* __LAMP_MIS__ */
+ if (kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray->P - state->ray_t * ray->D;
+ state->ray_t += isect->t;
+ light_ray.D = ray->D;
+ light_ray.t = state->ray_t;
+ light_ray.time = ray->time;
+ light_ray.dD = ray->dD;
+ light_ray.dP = ray->dP;
+
+ /* intersect with lamp */
+ float3 emission;
+
+ if (indirect_lamp_emission(kg, emission_sd, state, &light_ray, &emission))
+ path_radiance_accum_emission(L, state, throughput, emission);
+ }
+#endif /* __LAMP_MIS__ */
}
-ccl_device_forceinline void kernel_path_background(
- KernelGlobals *kg,
- ccl_addr_space PathState *state,
- ccl_addr_space Ray *ray,
- float3 throughput,
- ShaderData *sd,
- PathRadiance *L)
+ccl_device_forceinline void kernel_path_background(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ ccl_addr_space Ray *ray,
+ float3 throughput,
+ ShaderData *sd,
+ PathRadiance *L)
{
- /* eval background shader if nothing hit */
- if(kernel_data.background.transparent && (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
- L->transparent += average(throughput);
+ /* eval background shader if nothing hit */
+ if (kernel_data.background.transparent && (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
+ L->transparent += average(throughput);
#ifdef __PASSES__
- if(!(kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND)))
-#endif /* __PASSES__ */
- return;
- }
+ if (!(kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND)))
+#endif /* __PASSES__ */
+ return;
+ }
- /* When using the ao bounces approximation, adjust background
- * shader intensity with ao factor. */
- if(path_state_ao_bounce(kg, state)) {
- throughput *= kernel_data.background.ao_bounces_factor;
- }
+ /* When using the ao bounces approximation, adjust background
+ * shader intensity with ao factor. */
+ if (path_state_ao_bounce(kg, state)) {
+ throughput *= kernel_data.background.ao_bounces_factor;
+ }
#ifdef __BACKGROUND__
- /* sample background shader */
- float3 L_background = indirect_background(kg, sd, state, ray);
- path_radiance_accum_background(L, state, throughput, L_background);
-#endif /* __BACKGROUND__ */
+ /* sample background shader */
+ float3 L_background = indirect_background(kg, sd, state, ray);
+ path_radiance_accum_background(L, state, throughput, L_background);
+#endif /* __BACKGROUND__ */
}
#ifndef __SPLIT_KERNEL__
-#ifdef __VOLUME__
-ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
- KernelGlobals *kg,
- ShaderData *sd,
- PathState *state,
- Ray *ray,
- float3 *throughput,
- ccl_addr_space Intersection *isect,
- bool hit,
- ShaderData *emission_sd,
- PathRadiance *L)
+# ifdef __VOLUME__
+ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *kg,
+ ShaderData *sd,
+ PathState *state,
+ Ray *ray,
+ float3 *throughput,
+ ccl_addr_space Intersection *isect,
+ bool hit,
+ ShaderData *emission_sd,
+ PathRadiance *L)
{
- PROFILING_INIT(kg, PROFILING_VOLUME);
-
- /* Sanitize volume stack. */
- if(!hit) {
- kernel_volume_clean_stack(kg, state->volume_stack);
- }
-
- if(state->volume_stack[0].shader == SHADER_NONE) {
- return VOLUME_PATH_ATTENUATED;
- }
-
- /* volume attenuation, emission, scatter */
- Ray volume_ray = *ray;
- volume_ray.t = (hit)? isect->t: FLT_MAX;
-
- bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
-
-# ifdef __VOLUME_DECOUPLED__
- int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
- bool direct = (state->flag & PATH_RAY_CAMERA) != 0;
- bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, direct, sampling_method);
-
- if(decoupled) {
- /* cache steps along volume for repeated sampling */
- VolumeSegment volume_segment;
-
- shader_setup_from_volume(kg, sd, &volume_ray);
- kernel_volume_decoupled_record(kg, state,
- &volume_ray, sd, &volume_segment, heterogeneous);
-
- volume_segment.sampling_method = sampling_method;
-
- /* emission */
- if(volume_segment.closure_flag & SD_EMISSION)
- path_radiance_accum_emission(L, state, *throughput, volume_segment.accum_emission);
-
- /* scattering */
- VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
-
- if(volume_segment.closure_flag & SD_SCATTER) {
- int all = kernel_data.integrator.sample_all_lights_indirect;
-
- /* direct light sampling */
- kernel_branched_path_volume_connect_light(kg, sd,
- emission_sd, *throughput, state, L, all,
- &volume_ray, &volume_segment);
-
- /* indirect sample. if we use distance sampling and take just
- * one sample for direct and indirect light, we could share
- * this computation, but makes code a bit complex */
- float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
- float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
-
- result = kernel_volume_decoupled_scatter(kg,
- state, &volume_ray, sd, throughput,
- rphase, rscatter, &volume_segment, NULL, true);
- }
-
- /* free cached steps */
- kernel_volume_decoupled_free(kg, &volume_segment);
-
- if(result == VOLUME_PATH_SCATTERED) {
- if(kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
- return VOLUME_PATH_SCATTERED;
- else
- return VOLUME_PATH_MISSED;
- }
- else {
- *throughput *= volume_segment.accum_transmittance;
- }
- }
- else
-# endif /* __VOLUME_DECOUPLED__ */
- {
- /* integrate along volume segment with distance sampling */
- VolumeIntegrateResult result = kernel_volume_integrate(
- kg, state, sd, &volume_ray, L, throughput, heterogeneous);
-
-# ifdef __VOLUME_SCATTER__
- if(result == VOLUME_PATH_SCATTERED) {
- /* direct lighting */
- kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
-
- /* indirect light bounce */
- if(kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
- return VOLUME_PATH_SCATTERED;
- else
- return VOLUME_PATH_MISSED;
- }
-# endif /* __VOLUME_SCATTER__ */
- }
-
- return VOLUME_PATH_ATTENUATED;
+ PROFILING_INIT(kg, PROFILING_VOLUME);
+
+ /* Sanitize volume stack. */
+ if (!hit) {
+ kernel_volume_clean_stack(kg, state->volume_stack);
+ }
+
+ if (state->volume_stack[0].shader == SHADER_NONE) {
+ return VOLUME_PATH_ATTENUATED;
+ }
+
+ /* volume attenuation, emission, scatter */
+ Ray volume_ray = *ray;
+ volume_ray.t = (hit) ? isect->t : FLT_MAX;
+
+ bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
+
+# ifdef __VOLUME_DECOUPLED__
+ int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
+ bool direct = (state->flag & PATH_RAY_CAMERA) != 0;
+ bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, direct, sampling_method);
+
+ if (decoupled) {
+ /* cache steps along volume for repeated sampling */
+ VolumeSegment volume_segment;
+
+ shader_setup_from_volume(kg, sd, &volume_ray);
+ kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
+
+ volume_segment.sampling_method = sampling_method;
+
+ /* emission */
+ if (volume_segment.closure_flag & SD_EMISSION)
+ path_radiance_accum_emission(L, state, *throughput, volume_segment.accum_emission);
+
+ /* scattering */
+ VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
+
+ if (volume_segment.closure_flag & SD_SCATTER) {
+ int all = kernel_data.integrator.sample_all_lights_indirect;
+
+ /* direct light sampling */
+ kernel_branched_path_volume_connect_light(
+ kg, sd, emission_sd, *throughput, state, L, all, &volume_ray, &volume_segment);
+
+ /* indirect sample. if we use distance sampling and take just
+ * one sample for direct and indirect light, we could share
+ * this computation, but makes code a bit complex */
+ float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
+ float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
+
+ result = kernel_volume_decoupled_scatter(
+ kg, state, &volume_ray, sd, throughput, rphase, rscatter, &volume_segment, NULL, true);
+ }
+
+ /* free cached steps */
+ kernel_volume_decoupled_free(kg, &volume_segment);
+
+ if (result == VOLUME_PATH_SCATTERED) {
+ if (kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
+ return VOLUME_PATH_SCATTERED;
+ else
+ return VOLUME_PATH_MISSED;
+ }
+ else {
+ *throughput *= volume_segment.accum_transmittance;
+ }
+ }
+ else
+# endif /* __VOLUME_DECOUPLED__ */
+ {
+ /* integrate along volume segment with distance sampling */
+ VolumeIntegrateResult result = kernel_volume_integrate(
+ kg, state, sd, &volume_ray, L, throughput, heterogeneous);
+
+# ifdef __VOLUME_SCATTER__
+ if (result == VOLUME_PATH_SCATTERED) {
+ /* direct lighting */
+ kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
+
+ /* indirect light bounce */
+ if (kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
+ return VOLUME_PATH_SCATTERED;
+ else
+ return VOLUME_PATH_MISSED;
+ }
+# endif /* __VOLUME_SCATTER__ */
+ }
+
+ return VOLUME_PATH_ATTENUATED;
}
-#endif /* __VOLUME__ */
-
-#endif /* __SPLIT_KERNEL__ */
-
-ccl_device_forceinline bool kernel_path_shader_apply(
- KernelGlobals *kg,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- ccl_addr_space Ray *ray,
- float3 throughput,
- ShaderData *emission_sd,
- PathRadiance *L,
- ccl_global float *buffer)
+# endif /* __VOLUME__ */
+
+#endif /* __SPLIT_KERNEL__ */
+
+ccl_device_forceinline bool kernel_path_shader_apply(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ccl_addr_space Ray *ray,
+ float3 throughput,
+ ShaderData *emission_sd,
+ PathRadiance *L,
+ ccl_global float *buffer)
{
- PROFILING_INIT(kg, PROFILING_SHADER_APPLY);
+ PROFILING_INIT(kg, PROFILING_SHADER_APPLY);
#ifdef __SHADOW_TRICKS__
- if((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
- if(state->flag & PATH_RAY_TRANSPARENT_BACKGROUND) {
- state->flag |= (PATH_RAY_SHADOW_CATCHER |
- PATH_RAY_STORE_SHADOW_INFO);
-
- float3 bg = make_float3(0.0f, 0.0f, 0.0f);
- if(!kernel_data.background.transparent) {
- bg = indirect_background(kg, emission_sd, state, ray);
- }
- path_radiance_accum_shadowcatcher(L, throughput, bg);
- }
- }
- else if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- /* Only update transparency after shadow catcher bounce. */
- L->shadow_transparency *=
- average(shader_bsdf_transparency(kg, sd));
- }
-#endif /* __SHADOW_TRICKS__ */
-
- /* holdout */
+ if ((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
+ if (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND) {
+ state->flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_STORE_SHADOW_INFO);
+
+ float3 bg = make_float3(0.0f, 0.0f, 0.0f);
+ if (!kernel_data.background.transparent) {
+ bg = indirect_background(kg, emission_sd, state, ray);
+ }
+ path_radiance_accum_shadowcatcher(L, throughput, bg);
+ }
+ }
+ else if (state->flag & PATH_RAY_SHADOW_CATCHER) {
+ /* Only update transparency after shadow catcher bounce. */
+ L->shadow_transparency *= average(shader_bsdf_transparency(kg, sd));
+ }
+#endif /* __SHADOW_TRICKS__ */
+
+ /* holdout */
#ifdef __HOLDOUT__
- if(((sd->flag & SD_HOLDOUT) ||
- (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
- (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND))
- {
- if(kernel_data.background.transparent) {
- float3 holdout_weight;
- if(sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
- holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
- }
- else {
- holdout_weight = shader_holdout_eval(kg, sd);
- }
- /* any throughput is ok, should all be identical here */
- L->transparent += average(holdout_weight*throughput);
- }
-
- if(sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
- return false;
- }
- }
-#endif /* __HOLDOUT__ */
-
- /* holdout mask objects do not write data passes */
- kernel_write_data_passes(kg, buffer, L, sd, state, throughput);
-
- /* blurring of bsdf after bounces, for rays that have a small likelihood
- * of following this particular path (diffuse, rough glossy) */
- if(kernel_data.integrator.filter_glossy != FLT_MAX) {
- float blur_pdf = kernel_data.integrator.filter_glossy*state->min_ray_pdf;
-
- if(blur_pdf < 1.0f) {
- float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f;
- shader_bsdf_blur(kg, sd, blur_roughness);
- }
- }
+ if (((sd->flag & SD_HOLDOUT) || (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
+ (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
+ if (kernel_data.background.transparent) {
+ float3 holdout_weight;
+ if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
+ holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ holdout_weight = shader_holdout_eval(kg, sd);
+ }
+ /* any throughput is ok, should all be identical here */
+ L->transparent += average(holdout_weight * throughput);
+ }
+
+ if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
+ return false;
+ }
+ }
+#endif /* __HOLDOUT__ */
+
+ /* holdout mask objects do not write data passes */
+ kernel_write_data_passes(kg, buffer, L, sd, state, throughput);
+
+ /* blurring of bsdf after bounces, for rays that have a small likelihood
+ * of following this particular path (diffuse, rough glossy) */
+ if (kernel_data.integrator.filter_glossy != FLT_MAX) {
+ float blur_pdf = kernel_data.integrator.filter_glossy * state->min_ray_pdf;
+
+ if (blur_pdf < 1.0f) {
+ float blur_roughness = sqrtf(1.0f - blur_pdf) * 0.5f;
+ shader_bsdf_blur(kg, sd, blur_roughness);
+ }
+ }
#ifdef __EMISSION__
- /* emission */
- if(sd->flag & SD_EMISSION) {
- float3 emission = indirect_primitive_emission(kg, sd, sd->ray_length, state->flag, state->ray_pdf);
- path_radiance_accum_emission(L, state, throughput, emission);
- }
-#endif /* __EMISSION__ */
-
- return true;
+ /* emission */
+ if (sd->flag & SD_EMISSION) {
+ float3 emission = indirect_primitive_emission(
+ kg, sd, sd->ray_length, state->flag, state->ray_pdf);
+ path_radiance_accum_emission(L, state, throughput, emission);
+ }
+#endif /* __EMISSION__ */
+
+ return true;
}
ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
@@ -363,44 +352,44 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
float3 throughput,
float3 ao_alpha)
{
- PROFILING_INIT(kg, PROFILING_AO);
-
- /* todo: solve correlation */
- float bsdf_u, bsdf_v;
-
- path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
-
- float ao_factor = kernel_data.background.ao_factor;
- float3 ao_N;
- float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N);
- float3 ao_D;
- float ao_pdf;
-
- sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
-
- if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
- Ray light_ray;
- float3 ao_shadow;
-
- light_ray.P = ray_offset(sd->P, sd->Ng);
- light_ray.D = ao_D;
- light_ray.t = kernel_data.background.ao_distance;
- light_ray.time = sd->time;
- light_ray.dP = sd->dP;
- light_ray.dD = differential3_zero();
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
- path_radiance_accum_ao(L, state, throughput, ao_alpha, ao_bsdf, ao_shadow);
- }
- else {
- path_radiance_accum_total_ao(L, state, throughput, ao_bsdf);
- }
- }
+ PROFILING_INIT(kg, PROFILING_AO);
+
+ /* todo: solve correlation */
+ float bsdf_u, bsdf_v;
+
+ path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+
+ float ao_factor = kernel_data.background.ao_factor;
+ float3 ao_N;
+ float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N);
+ float3 ao_D;
+ float ao_pdf;
+
+ sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+
+ if (dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
+ Ray light_ray;
+ float3 ao_shadow;
+
+ light_ray.P = ray_offset(sd->P, sd->Ng);
+ light_ray.D = ao_D;
+ light_ray.t = kernel_data.background.ao_distance;
+ light_ray.time = sd->time;
+ light_ray.dP = sd->dP;
+ light_ray.dD = differential3_zero();
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
+ path_radiance_accum_ao(L, state, throughput, ao_alpha, ao_bsdf, ao_shadow);
+ }
+ else {
+ path_radiance_accum_total_ao(L, state, throughput, ao_bsdf);
+ }
+ }
}
#ifndef __SPLIT_KERNEL__
-#if defined(__BRANCHED_PATH__) || defined(__BAKING__)
+# if defined(__BRANCHED_PATH__) || defined(__BAKING__)
ccl_device void kernel_path_indirect(KernelGlobals *kg,
ShaderData *sd,
@@ -410,369 +399,300 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
PathState *state,
PathRadiance *L)
{
-#ifdef __SUBSURFACE__
- SubsurfaceIndirectRays ss_indirect;
- kernel_path_subsurface_init_indirect(&ss_indirect);
-
- for(;;) {
-#endif /* __SUBSURFACE__ */
-
- /* path iteration */
- for(;;) {
- /* Find intersection with objects in scene. */
- Intersection isect;
- bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
-
- /* Find intersection with lamps and compute emission for MIS. */
- kernel_path_lamp_emission(kg, state, ray, throughput, &isect, sd, L);
-
-#ifdef __VOLUME__
- /* Volume integration. */
- VolumeIntegrateResult result = kernel_path_volume(kg,
- sd,
- state,
- ray,
- &throughput,
- &isect,
- hit,
- emission_sd,
- L);
-
- if(result == VOLUME_PATH_SCATTERED) {
- continue;
- }
- else if(result == VOLUME_PATH_MISSED) {
- break;
- }
-#endif /* __VOLUME__*/
-
- /* Shade background. */
- if(!hit) {
- kernel_path_background(kg, state, ray, throughput, sd, L);
- break;
- }
- else if(path_state_ao_bounce(kg, state)) {
- break;
- }
-
- /* Setup shader data. */
- shader_setup_from_ray(kg, sd, &isect, ray);
-
- /* Skip most work for volume bounding surface. */
-#ifdef __VOLUME__
- if(!(sd->flag & SD_HAS_ONLY_VOLUME)) {
-#endif
-
- /* Evaluate shader. */
- shader_eval_surface(kg, sd, state, state->flag);
- shader_prepare_closures(sd, state);
-
- /* Apply shadow catcher, holdout, emission. */
- if(!kernel_path_shader_apply(kg,
- sd,
- state,
- ray,
- throughput,
- emission_sd,
- L,
- NULL))
- {
- break;
- }
-
- /* path termination. this is a strange place to put the termination, it's
- * mainly due to the mixed in MIS that we use. gives too many unneeded
- * shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_continuation_probability(kg, state, throughput);
-
- if(probability == 0.0f) {
- break;
- }
- else if(probability != 1.0f) {
- float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
-
- if(terminate >= probability)
- break;
-
- throughput /= probability;
- }
-
- kernel_update_denoising_features(kg, sd, state, L);
-
-#ifdef __AO__
- /* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion) {
- kernel_path_ao(kg, sd, emission_sd, L, state, throughput, make_float3(0.0f, 0.0f, 0.0f));
- }
-#endif /* __AO__ */
-
-
-#ifdef __SUBSURFACE__
- /* bssrdf scatter to a different location on the same object, replacing
- * the closures with a diffuse BSDF */
- if(sd->flag & SD_BSSRDF) {
- if(kernel_path_subsurface_scatter(kg,
- sd,
- emission_sd,
- L,
- state,
- ray,
- &throughput,
- &ss_indirect))
- {
- break;
- }
- }
-#endif /* __SUBSURFACE__ */
-
-#if defined(__EMISSION__)
- if(kernel_data.integrator.use_direct_light) {
- int all = (kernel_data.integrator.sample_all_lights_indirect) ||
- (state->flag & PATH_RAY_SHADOW_CATCHER);
- kernel_branched_path_surface_connect_light(kg,
- sd,
- emission_sd,
- state,
- throughput,
- 1.0f,
- L,
- all);
- }
-#endif /* defined(__EMISSION__) */
-
-#ifdef __VOLUME__
- }
-#endif
-
- if(!kernel_path_surface_bounce(kg, sd, &throughput, state, &L->state, ray))
- break;
- }
-
-#ifdef __SUBSURFACE__
- /* Trace indirect subsurface rays by restarting the loop. this uses less
- * stack memory than invoking kernel_path_indirect.
- */
- if(ss_indirect.num_rays) {
- kernel_path_subsurface_setup_indirect(kg,
- &ss_indirect,
- state,
- ray,
- L,
- &throughput);
- }
- else {
- break;
- }
- }
-#endif /* __SUBSURFACE__ */
+# ifdef __SUBSURFACE__
+ SubsurfaceIndirectRays ss_indirect;
+ kernel_path_subsurface_init_indirect(&ss_indirect);
+
+ for (;;) {
+# endif /* __SUBSURFACE__ */
+
+ /* path iteration */
+ for (;;) {
+ /* Find intersection with objects in scene. */
+ Intersection isect;
+ bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
+
+ /* Find intersection with lamps and compute emission for MIS. */
+ kernel_path_lamp_emission(kg, state, ray, throughput, &isect, sd, L);
+
+# ifdef __VOLUME__
+ /* Volume integration. */
+ VolumeIntegrateResult result = kernel_path_volume(
+ kg, sd, state, ray, &throughput, &isect, hit, emission_sd, L);
+
+ if (result == VOLUME_PATH_SCATTERED) {
+ continue;
+ }
+ else if (result == VOLUME_PATH_MISSED) {
+ break;
+ }
+# endif /* __VOLUME__*/
+
+ /* Shade background. */
+ if (!hit) {
+ kernel_path_background(kg, state, ray, throughput, sd, L);
+ break;
+ }
+ else if (path_state_ao_bounce(kg, state)) {
+ break;
+ }
+
+ /* Setup shader data. */
+ shader_setup_from_ray(kg, sd, &isect, ray);
+
+ /* Skip most work for volume bounding surface. */
+# ifdef __VOLUME__
+ if (!(sd->flag & SD_HAS_ONLY_VOLUME)) {
+# endif
+
+ /* Evaluate shader. */
+ shader_eval_surface(kg, sd, state, state->flag);
+ shader_prepare_closures(sd, state);
+
+ /* Apply shadow catcher, holdout, emission. */
+ if (!kernel_path_shader_apply(kg, sd, state, ray, throughput, emission_sd, L, NULL)) {
+ break;
+ }
+
+ /* path termination. this is a strange place to put the termination, it's
+ * mainly due to the mixed in MIS that we use. gives too many unneeded
+ * shader evaluations, only need emission if we are going to terminate */
+ float probability = path_state_continuation_probability(kg, state, throughput);
+
+ if (probability == 0.0f) {
+ break;
+ }
+ else if (probability != 1.0f) {
+ float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
+
+ if (terminate >= probability)
+ break;
+
+ throughput /= probability;
+ }
+
+ kernel_update_denoising_features(kg, sd, state, L);
+
+# ifdef __AO__
+ /* ambient occlusion */
+ if (kernel_data.integrator.use_ambient_occlusion) {
+ kernel_path_ao(kg, sd, emission_sd, L, state, throughput, make_float3(0.0f, 0.0f, 0.0f));
+ }
+# endif /* __AO__ */
+
+# ifdef __SUBSURFACE__
+ /* bssrdf scatter to a different location on the same object, replacing
+ * the closures with a diffuse BSDF */
+ if (sd->flag & SD_BSSRDF) {
+ if (kernel_path_subsurface_scatter(
+ kg, sd, emission_sd, L, state, ray, &throughput, &ss_indirect)) {
+ break;
+ }
+ }
+# endif /* __SUBSURFACE__ */
+
+# if defined(__EMISSION__)
+ if (kernel_data.integrator.use_direct_light) {
+ int all = (kernel_data.integrator.sample_all_lights_indirect) ||
+ (state->flag & PATH_RAY_SHADOW_CATCHER);
+ kernel_branched_path_surface_connect_light(
+ kg, sd, emission_sd, state, throughput, 1.0f, L, all);
+ }
+# endif /* defined(__EMISSION__) */
+
+# ifdef __VOLUME__
+ }
+# endif
+
+ if (!kernel_path_surface_bounce(kg, sd, &throughput, state, &L->state, ray))
+ break;
+ }
+
+# ifdef __SUBSURFACE__
+ /* Trace indirect subsurface rays by restarting the loop. this uses less
+ * stack memory than invoking kernel_path_indirect.
+ */
+ if (ss_indirect.num_rays) {
+ kernel_path_subsurface_setup_indirect(kg, &ss_indirect, state, ray, L, &throughput);
+ }
+ else {
+ break;
+ }
+ }
+# endif /* __SUBSURFACE__ */
}
-#endif /* defined(__BRANCHED_PATH__) || defined(__BAKING__) */
+# endif /* defined(__BRANCHED_PATH__) || defined(__BAKING__) */
-ccl_device_forceinline void kernel_path_integrate(
- KernelGlobals *kg,
- PathState *state,
- float3 throughput,
- Ray *ray,
- PathRadiance *L,
- ccl_global float *buffer,
- ShaderData *emission_sd)
+ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg,
+ PathState *state,
+ float3 throughput,
+ Ray *ray,
+ PathRadiance *L,
+ ccl_global float *buffer,
+ ShaderData *emission_sd)
{
- PROFILING_INIT(kg, PROFILING_PATH_INTEGRATE);
-
- /* Shader data memory used for both volumes and surfaces, saves stack space. */
- ShaderData sd;
-
-#ifdef __SUBSURFACE__
- SubsurfaceIndirectRays ss_indirect;
- kernel_path_subsurface_init_indirect(&ss_indirect);
-
- for(;;) {
-#endif /* __SUBSURFACE__ */
-
- /* path iteration */
- for(;;) {
- /* Find intersection with objects in scene. */
- Intersection isect;
- bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
-
- /* Find intersection with lamps and compute emission for MIS. */
- kernel_path_lamp_emission(kg, state, ray, throughput, &isect, &sd, L);
-
-#ifdef __VOLUME__
- /* Volume integration. */
- VolumeIntegrateResult result = kernel_path_volume(kg,
- &sd,
- state,
- ray,
- &throughput,
- &isect,
- hit,
- emission_sd,
- L);
-
- if(result == VOLUME_PATH_SCATTERED) {
- continue;
- }
- else if(result == VOLUME_PATH_MISSED) {
- break;
- }
-#endif /* __VOLUME__*/
-
- /* Shade background. */
- if(!hit) {
- kernel_path_background(kg, state, ray, throughput, &sd, L);
- break;
- }
- else if(path_state_ao_bounce(kg, state)) {
- break;
- }
-
- /* Setup shader data. */
- shader_setup_from_ray(kg, &sd, &isect, ray);
-
- /* Skip most work for volume bounding surface. */
-#ifdef __VOLUME__
- if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
-#endif
-
- /* Evaluate shader. */
- shader_eval_surface(kg, &sd, state, state->flag);
- shader_prepare_closures(&sd, state);
-
- /* Apply shadow catcher, holdout, emission. */
- if(!kernel_path_shader_apply(kg,
- &sd,
- state,
- ray,
- throughput,
- emission_sd,
- L,
- buffer))
- {
- break;
- }
-
- /* path termination. this is a strange place to put the termination, it's
- * mainly due to the mixed in MIS that we use. gives too many unneeded
- * shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_continuation_probability(kg, state, throughput);
-
- if(probability == 0.0f) {
- break;
- }
- else if(probability != 1.0f) {
- float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
- if(terminate >= probability)
- break;
-
- throughput /= probability;
- }
-
- kernel_update_denoising_features(kg, &sd, state, L);
-
-#ifdef __AO__
- /* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion) {
- kernel_path_ao(kg, &sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, &sd));
- }
-#endif /* __AO__ */
-
-#ifdef __SUBSURFACE__
- /* bssrdf scatter to a different location on the same object, replacing
- * the closures with a diffuse BSDF */
- if(sd.flag & SD_BSSRDF) {
- if(kernel_path_subsurface_scatter(kg,
- &sd,
- emission_sd,
- L,
- state,
- ray,
- &throughput,
- &ss_indirect))
- {
- break;
- }
- }
-#endif /* __SUBSURFACE__ */
-
- /* direct lighting */
- kernel_path_surface_connect_light(kg, &sd, emission_sd, throughput, state, L);
-
-#ifdef __VOLUME__
- }
-#endif
-
- /* compute direct lighting and next bounce */
- if(!kernel_path_surface_bounce(kg, &sd, &throughput, state, &L->state, ray))
- break;
- }
-
-#ifdef __SUBSURFACE__
- /* Trace indirect subsurface rays by restarting the loop. this uses less
- * stack memory than invoking kernel_path_indirect.
- */
- if(ss_indirect.num_rays) {
- kernel_path_subsurface_setup_indirect(kg,
- &ss_indirect,
- state,
- ray,
- L,
- &throughput);
- }
- else {
- break;
- }
- }
-#endif /* __SUBSURFACE__ */
+ PROFILING_INIT(kg, PROFILING_PATH_INTEGRATE);
+
+ /* Shader data memory used for both volumes and surfaces, saves stack space. */
+ ShaderData sd;
+
+# ifdef __SUBSURFACE__
+ SubsurfaceIndirectRays ss_indirect;
+ kernel_path_subsurface_init_indirect(&ss_indirect);
+
+ for (;;) {
+# endif /* __SUBSURFACE__ */
+
+ /* path iteration */
+ for (;;) {
+ /* Find intersection with objects in scene. */
+ Intersection isect;
+ bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
+
+ /* Find intersection with lamps and compute emission for MIS. */
+ kernel_path_lamp_emission(kg, state, ray, throughput, &isect, &sd, L);
+
+# ifdef __VOLUME__
+ /* Volume integration. */
+ VolumeIntegrateResult result = kernel_path_volume(
+ kg, &sd, state, ray, &throughput, &isect, hit, emission_sd, L);
+
+ if (result == VOLUME_PATH_SCATTERED) {
+ continue;
+ }
+ else if (result == VOLUME_PATH_MISSED) {
+ break;
+ }
+# endif /* __VOLUME__*/
+
+ /* Shade background. */
+ if (!hit) {
+ kernel_path_background(kg, state, ray, throughput, &sd, L);
+ break;
+ }
+ else if (path_state_ao_bounce(kg, state)) {
+ break;
+ }
+
+ /* Setup shader data. */
+ shader_setup_from_ray(kg, &sd, &isect, ray);
+
+ /* Skip most work for volume bounding surface. */
+# ifdef __VOLUME__
+ if (!(sd.flag & SD_HAS_ONLY_VOLUME)) {
+# endif
+
+ /* Evaluate shader. */
+ shader_eval_surface(kg, &sd, state, state->flag);
+ shader_prepare_closures(&sd, state);
+
+ /* Apply shadow catcher, holdout, emission. */
+ if (!kernel_path_shader_apply(kg, &sd, state, ray, throughput, emission_sd, L, buffer)) {
+ break;
+ }
+
+ /* path termination. this is a strange place to put the termination, it's
+ * mainly due to the mixed in MIS that we use. gives too many unneeded
+ * shader evaluations, only need emission if we are going to terminate */
+ float probability = path_state_continuation_probability(kg, state, throughput);
+
+ if (probability == 0.0f) {
+ break;
+ }
+ else if (probability != 1.0f) {
+ float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
+ if (terminate >= probability)
+ break;
+
+ throughput /= probability;
+ }
+
+ kernel_update_denoising_features(kg, &sd, state, L);
+
+# ifdef __AO__
+ /* ambient occlusion */
+ if (kernel_data.integrator.use_ambient_occlusion) {
+ kernel_path_ao(kg, &sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, &sd));
+ }
+# endif /* __AO__ */
+
+# ifdef __SUBSURFACE__
+ /* bssrdf scatter to a different location on the same object, replacing
+ * the closures with a diffuse BSDF */
+ if (sd.flag & SD_BSSRDF) {
+ if (kernel_path_subsurface_scatter(
+ kg, &sd, emission_sd, L, state, ray, &throughput, &ss_indirect)) {
+ break;
+ }
+ }
+# endif /* __SUBSURFACE__ */
+
+ /* direct lighting */
+ kernel_path_surface_connect_light(kg, &sd, emission_sd, throughput, state, L);
+
+# ifdef __VOLUME__
+ }
+# endif
+
+ /* compute direct lighting and next bounce */
+ if (!kernel_path_surface_bounce(kg, &sd, &throughput, state, &L->state, ray))
+ break;
+ }
+
+# ifdef __SUBSURFACE__
+ /* Trace indirect subsurface rays by restarting the loop. this uses less
+ * stack memory than invoking kernel_path_indirect.
+ */
+ if (ss_indirect.num_rays) {
+ kernel_path_subsurface_setup_indirect(kg, &ss_indirect, state, ray, L, &throughput);
+ }
+ else {
+ break;
+ }
+ }
+# endif /* __SUBSURFACE__ */
}
-ccl_device void kernel_path_trace(KernelGlobals *kg,
- ccl_global float *buffer,
- int sample, int x, int y, int offset, int stride)
+ccl_device void kernel_path_trace(
+ KernelGlobals *kg, ccl_global float *buffer, int sample, int x, int y, int offset, int stride)
{
- PROFILING_INIT(kg, PROFILING_RAY_SETUP);
+ PROFILING_INIT(kg, PROFILING_RAY_SETUP);
- /* buffer offset */
- int index = offset + x + y*stride;
- int pass_stride = kernel_data.film.pass_stride;
+ /* buffer offset */
+ int index = offset + x + y * stride;
+ int pass_stride = kernel_data.film.pass_stride;
- buffer += index*pass_stride;
+ buffer += index * pass_stride;
- /* Initialize random numbers and sample ray. */
- uint rng_hash;
- Ray ray;
+ /* Initialize random numbers and sample ray. */
+ uint rng_hash;
+ Ray ray;
- kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &ray);
+ kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &ray);
- if(ray.t == 0.0f) {
- return;
- }
+ if (ray.t == 0.0f) {
+ return;
+ }
- /* Initialize state. */
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ /* Initialize state. */
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- PathRadiance L;
- path_radiance_init(&L, kernel_data.film.use_light_pass);
+ PathRadiance L;
+ path_radiance_init(&L, kernel_data.film.use_light_pass);
- ShaderDataTinyStorage emission_sd_storage;
- ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
+ ShaderDataTinyStorage emission_sd_storage;
+ ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
- PathState state;
- path_state_init(kg, emission_sd, &state, rng_hash, sample, &ray);
+ PathState state;
+ path_state_init(kg, emission_sd, &state, rng_hash, sample, &ray);
- /* Integrate. */
- kernel_path_integrate(kg,
- &state,
- throughput,
- &ray,
- &L,
- buffer,
- emission_sd);
+ /* Integrate. */
+ kernel_path_integrate(kg, &state, throughput, &ray, &L, buffer, emission_sd);
- kernel_write_result(kg, buffer, sample, &L);
+ kernel_write_result(kg, buffer, sample, &L);
}
-#endif /* __SPLIT_KERNEL__ */
+#endif /* __SPLIT_KERNEL__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index 21da4d9308b..e8ce61024b3 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -25,297 +25,262 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
ccl_addr_space PathState *state,
float3 throughput)
{
- int num_samples = kernel_data.integrator.ao_samples;
- float num_samples_inv = 1.0f/num_samples;
- float ao_factor = kernel_data.background.ao_factor;
- float3 ao_N;
- float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N);
- float3 ao_alpha = shader_bsdf_alpha(kg, sd);
-
- for(int j = 0; j < num_samples; j++) {
- float bsdf_u, bsdf_v;
- path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
-
- float3 ao_D;
- float ao_pdf;
-
- sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
-
- if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
- Ray light_ray;
- float3 ao_shadow;
-
- light_ray.P = ray_offset(sd->P, sd->Ng);
- light_ray.D = ao_D;
- light_ray.t = kernel_data.background.ao_distance;
- light_ray.time = sd->time;
- light_ray.dP = sd->dP;
- light_ray.dD = differential3_zero();
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
- path_radiance_accum_ao(L, state, throughput*num_samples_inv, ao_alpha, ao_bsdf, ao_shadow);
- }
- else {
- path_radiance_accum_total_ao(L, state, throughput*num_samples_inv, ao_bsdf);
- }
- }
- }
+ int num_samples = kernel_data.integrator.ao_samples;
+ float num_samples_inv = 1.0f / num_samples;
+ float ao_factor = kernel_data.background.ao_factor;
+ float3 ao_N;
+ float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N);
+ float3 ao_alpha = shader_bsdf_alpha(kg, sd);
+
+ for (int j = 0; j < num_samples; j++) {
+ float bsdf_u, bsdf_v;
+ path_branched_rng_2D(
+ kg, state->rng_hash, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+
+ float3 ao_D;
+ float ao_pdf;
+
+ sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+
+ if (dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
+ Ray light_ray;
+ float3 ao_shadow;
+
+ light_ray.P = ray_offset(sd->P, sd->Ng);
+ light_ray.D = ao_D;
+ light_ray.t = kernel_data.background.ao_distance;
+ light_ray.time = sd->time;
+ light_ray.dP = sd->dP;
+ light_ray.dD = differential3_zero();
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
+ path_radiance_accum_ao(
+ L, state, throughput * num_samples_inv, ao_alpha, ao_bsdf, ao_shadow);
+ }
+ else {
+ path_radiance_accum_total_ao(L, state, throughput * num_samples_inv, ao_bsdf);
+ }
+ }
+ }
}
-#ifndef __SPLIT_KERNEL__
-
-#ifdef __VOLUME__
-ccl_device_forceinline void kernel_branched_path_volume(
- KernelGlobals *kg,
- ShaderData *sd,
- PathState *state,
- Ray *ray,
- float3 *throughput,
- ccl_addr_space Intersection *isect,
- bool hit,
- ShaderData *indirect_sd,
- ShaderData *emission_sd,
- PathRadiance *L)
+# ifndef __SPLIT_KERNEL__
+
+# ifdef __VOLUME__
+ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
+ ShaderData *sd,
+ PathState *state,
+ Ray *ray,
+ float3 *throughput,
+ ccl_addr_space Intersection *isect,
+ bool hit,
+ ShaderData *indirect_sd,
+ ShaderData *emission_sd,
+ PathRadiance *L)
{
- /* Sanitize volume stack. */
- if(!hit) {
- kernel_volume_clean_stack(kg, state->volume_stack);
- }
-
- if(state->volume_stack[0].shader == SHADER_NONE) {
- return;
- }
-
- /* volume attenuation, emission, scatter */
- Ray volume_ray = *ray;
- volume_ray.t = (hit)? isect->t: FLT_MAX;
-
- bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
-
-# ifdef __VOLUME_DECOUPLED__
- /* decoupled ray marching only supported on CPU */
- if(kernel_data.integrator.volume_decoupled) {
- /* cache steps along volume for repeated sampling */
- VolumeSegment volume_segment;
-
- shader_setup_from_volume(kg, sd, &volume_ray);
- kernel_volume_decoupled_record(kg, state,
- &volume_ray, sd, &volume_segment, heterogeneous);
-
- /* direct light sampling */
- if(volume_segment.closure_flag & SD_SCATTER) {
- volume_segment.sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
-
- int all = kernel_data.integrator.sample_all_lights_direct;
-
- kernel_branched_path_volume_connect_light(kg, sd,
- emission_sd, *throughput, state, L, all,
- &volume_ray, &volume_segment);
-
- /* indirect light sampling */
- int num_samples = kernel_data.integrator.volume_samples;
- float num_samples_inv = 1.0f/num_samples;
-
- for(int j = 0; j < num_samples; j++) {
- PathState ps = *state;
- Ray pray = *ray;
- float3 tp = *throughput;
-
- /* branch RNG state */
- path_state_branch(&ps, j, num_samples);
-
- /* scatter sample. if we use distance sampling and take just one
- * sample for direct and indirect light, we could share this
- * computation, but makes code a bit complex */
- float rphase = path_state_rng_1D(kg, &ps, PRNG_PHASE_CHANNEL);
- float rscatter = path_state_rng_1D(kg, &ps, PRNG_SCATTER_DISTANCE);
-
- VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
- &ps, &pray, sd, &tp, rphase, rscatter, &volume_segment, NULL, false);
-
- if(result == VOLUME_PATH_SCATTERED &&
- kernel_path_volume_bounce(kg,
- sd,
- &tp,
- &ps,
- &L->state,
- &pray))
- {
- kernel_path_indirect(kg,
- indirect_sd,
- emission_sd,
- &pray,
- tp*num_samples_inv,
- &ps,
- L);
-
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- path_radiance_sum_indirect(L);
- path_radiance_reset_indirect(L);
- }
- }
- }
-
- /* emission and transmittance */
- if(volume_segment.closure_flag & SD_EMISSION)
- path_radiance_accum_emission(L, state, *throughput, volume_segment.accum_emission);
- *throughput *= volume_segment.accum_transmittance;
-
- /* free cached steps */
- kernel_volume_decoupled_free(kg, &volume_segment);
- }
- else
-# endif /* __VOLUME_DECOUPLED__ */
- {
- /* GPU: no decoupled ray marching, scatter probalistically */
- int num_samples = kernel_data.integrator.volume_samples;
- float num_samples_inv = 1.0f/num_samples;
-
- /* todo: we should cache the shader evaluations from stepping
- * through the volume, for now we redo them multiple times */
-
- for(int j = 0; j < num_samples; j++) {
- PathState ps = *state;
- Ray pray = *ray;
- float3 tp = (*throughput) * num_samples_inv;
-
- /* branch RNG state */
- path_state_branch(&ps, j, num_samples);
-
- VolumeIntegrateResult result = kernel_volume_integrate(
- kg, &ps, sd, &volume_ray, L, &tp, heterogeneous);
-
-# ifdef __VOLUME_SCATTER__
- if(result == VOLUME_PATH_SCATTERED) {
- /* todo: support equiangular, MIS and all light sampling.
- * alternatively get decoupled ray marching working on the GPU */
- kernel_path_volume_connect_light(kg, sd, emission_sd, tp, state, L);
-
- if(kernel_path_volume_bounce(kg,
- sd,
- &tp,
- &ps,
- &L->state,
- &pray))
- {
- kernel_path_indirect(kg,
- indirect_sd,
- emission_sd,
- &pray,
- tp,
- &ps,
- L);
-
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- path_radiance_sum_indirect(L);
- path_radiance_reset_indirect(L);
- }
- }
-# endif /* __VOLUME_SCATTER__ */
- }
-
- /* todo: avoid this calculation using decoupled ray marching */
- kernel_volume_shadow(kg, emission_sd, state, &volume_ray, throughput);
- }
+ /* Sanitize volume stack. */
+ if (!hit) {
+ kernel_volume_clean_stack(kg, state->volume_stack);
+ }
+
+ if (state->volume_stack[0].shader == SHADER_NONE) {
+ return;
+ }
+
+ /* volume attenuation, emission, scatter */
+ Ray volume_ray = *ray;
+ volume_ray.t = (hit) ? isect->t : FLT_MAX;
+
+ bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
+
+# ifdef __VOLUME_DECOUPLED__
+ /* decoupled ray marching only supported on CPU */
+ if (kernel_data.integrator.volume_decoupled) {
+ /* cache steps along volume for repeated sampling */
+ VolumeSegment volume_segment;
+
+ shader_setup_from_volume(kg, sd, &volume_ray);
+ kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
+
+ /* direct light sampling */
+ if (volume_segment.closure_flag & SD_SCATTER) {
+ volume_segment.sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
+
+ int all = kernel_data.integrator.sample_all_lights_direct;
+
+ kernel_branched_path_volume_connect_light(
+ kg, sd, emission_sd, *throughput, state, L, all, &volume_ray, &volume_segment);
+
+ /* indirect light sampling */
+ int num_samples = kernel_data.integrator.volume_samples;
+ float num_samples_inv = 1.0f / num_samples;
+
+ for (int j = 0; j < num_samples; j++) {
+ PathState ps = *state;
+ Ray pray = *ray;
+ float3 tp = *throughput;
+
+ /* branch RNG state */
+ path_state_branch(&ps, j, num_samples);
+
+ /* scatter sample. if we use distance sampling and take just one
+ * sample for direct and indirect light, we could share this
+ * computation, but makes code a bit complex */
+ float rphase = path_state_rng_1D(kg, &ps, PRNG_PHASE_CHANNEL);
+ float rscatter = path_state_rng_1D(kg, &ps, PRNG_SCATTER_DISTANCE);
+
+ VolumeIntegrateResult result = kernel_volume_decoupled_scatter(
+ kg, &ps, &pray, sd, &tp, rphase, rscatter, &volume_segment, NULL, false);
+
+ if (result == VOLUME_PATH_SCATTERED &&
+ kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) {
+ kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp * num_samples_inv, &ps, L);
+
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(L);
+ path_radiance_reset_indirect(L);
+ }
+ }
+ }
+
+ /* emission and transmittance */
+ if (volume_segment.closure_flag & SD_EMISSION)
+ path_radiance_accum_emission(L, state, *throughput, volume_segment.accum_emission);
+ *throughput *= volume_segment.accum_transmittance;
+
+ /* free cached steps */
+ kernel_volume_decoupled_free(kg, &volume_segment);
+ }
+ else
+# endif /* __VOLUME_DECOUPLED__ */
+ {
+ /* GPU: no decoupled ray marching, scatter probalistically */
+ int num_samples = kernel_data.integrator.volume_samples;
+ float num_samples_inv = 1.0f / num_samples;
+
+ /* todo: we should cache the shader evaluations from stepping
+ * through the volume, for now we redo them multiple times */
+
+ for (int j = 0; j < num_samples; j++) {
+ PathState ps = *state;
+ Ray pray = *ray;
+ float3 tp = (*throughput) * num_samples_inv;
+
+ /* branch RNG state */
+ path_state_branch(&ps, j, num_samples);
+
+ VolumeIntegrateResult result = kernel_volume_integrate(
+ kg, &ps, sd, &volume_ray, L, &tp, heterogeneous);
+
+# ifdef __VOLUME_SCATTER__
+ if (result == VOLUME_PATH_SCATTERED) {
+ /* todo: support equiangular, MIS and all light sampling.
+ * alternatively get decoupled ray marching working on the GPU */
+ kernel_path_volume_connect_light(kg, sd, emission_sd, tp, state, L);
+
+ if (kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) {
+ kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp, &ps, L);
+
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(L);
+ path_radiance_reset_indirect(L);
+ }
+ }
+# endif /* __VOLUME_SCATTER__ */
+ }
+
+ /* todo: avoid this calculation using decoupled ray marching */
+ kernel_volume_shadow(kg, emission_sd, state, &volume_ray, throughput);
+ }
}
-#endif /* __VOLUME__ */
+# endif /* __VOLUME__ */
/* bounce off surface and integrate indirect light */
ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGlobals *kg,
- ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd,
- float3 throughput, float num_samples_adjust, PathState *state, PathRadiance *L)
+ ShaderData *sd,
+ ShaderData *indirect_sd,
+ ShaderData *emission_sd,
+ float3 throughput,
+ float num_samples_adjust,
+ PathState *state,
+ PathRadiance *L)
{
- float sum_sample_weight = 0.0f;
-#ifdef __DENOISING_FEATURES__
- if(state->denoising_feature_weight > 0.0f) {
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- /* transparency is not handled here, but in outer loop */
- if(!CLOSURE_IS_BSDF(sc->type) || CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
- continue;
- }
-
- sum_sample_weight += sc->sample_weight;
- }
- }
- else {
- sum_sample_weight = 1.0f;
- }
-#endif /* __DENOISING_FEATURES__ */
-
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- /* transparency is not handled here, but in outer loop */
- if(!CLOSURE_IS_BSDF(sc->type) || CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
- continue;
- }
-
- int num_samples;
-
- if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
- num_samples = kernel_data.integrator.diffuse_samples;
- else if(CLOSURE_IS_BSDF_BSSRDF(sc->type))
- num_samples = 1;
- else if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
- num_samples = kernel_data.integrator.glossy_samples;
- else
- num_samples = kernel_data.integrator.transmission_samples;
-
- num_samples = ceil_to_int(num_samples_adjust*num_samples);
-
- float num_samples_inv = num_samples_adjust/num_samples;
-
- for(int j = 0; j < num_samples; j++) {
- PathState ps = *state;
- float3 tp = throughput;
- Ray bsdf_ray;
-#ifdef __SHADOW_TRICKS__
- float shadow_transparency = L->shadow_transparency;
-#endif
-
- ps.rng_hash = cmj_hash(state->rng_hash, i);
-
- if(!kernel_branched_path_surface_bounce(kg,
- sd,
- sc,
- j,
- num_samples,
- &tp,
- &ps,
- &L->state,
- &bsdf_ray,
- sum_sample_weight))
- {
- continue;
- }
-
- ps.rng_hash = state->rng_hash;
-
- kernel_path_indirect(kg,
- indirect_sd,
- emission_sd,
- &bsdf_ray,
- tp*num_samples_inv,
- &ps,
- L);
-
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- path_radiance_sum_indirect(L);
- path_radiance_reset_indirect(L);
-
-#ifdef __SHADOW_TRICKS__
- L->shadow_transparency = shadow_transparency;
-#endif
- }
- }
+ float sum_sample_weight = 0.0f;
+# ifdef __DENOISING_FEATURES__
+ if (state->denoising_feature_weight > 0.0f) {
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ /* transparency is not handled here, but in outer loop */
+ if (!CLOSURE_IS_BSDF(sc->type) || CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
+ continue;
+ }
+
+ sum_sample_weight += sc->sample_weight;
+ }
+ }
+ else {
+ sum_sample_weight = 1.0f;
+ }
+# endif /* __DENOISING_FEATURES__ */
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ /* transparency is not handled here, but in outer loop */
+ if (!CLOSURE_IS_BSDF(sc->type) || CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
+ continue;
+ }
+
+ int num_samples;
+
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type))
+ num_samples = kernel_data.integrator.diffuse_samples;
+ else if (CLOSURE_IS_BSDF_BSSRDF(sc->type))
+ num_samples = 1;
+ else if (CLOSURE_IS_BSDF_GLOSSY(sc->type))
+ num_samples = kernel_data.integrator.glossy_samples;
+ else
+ num_samples = kernel_data.integrator.transmission_samples;
+
+ num_samples = ceil_to_int(num_samples_adjust * num_samples);
+
+ float num_samples_inv = num_samples_adjust / num_samples;
+
+ for (int j = 0; j < num_samples; j++) {
+ PathState ps = *state;
+ float3 tp = throughput;
+ Ray bsdf_ray;
+# ifdef __SHADOW_TRICKS__
+ float shadow_transparency = L->shadow_transparency;
+# endif
+
+ ps.rng_hash = cmj_hash(state->rng_hash, i);
+
+ if (!kernel_branched_path_surface_bounce(
+ kg, sd, sc, j, num_samples, &tp, &ps, &L->state, &bsdf_ray, sum_sample_weight)) {
+ continue;
+ }
+
+ ps.rng_hash = state->rng_hash;
+
+ kernel_path_indirect(kg, indirect_sd, emission_sd, &bsdf_ray, tp * num_samples_inv, &ps, L);
+
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(L);
+ path_radiance_reset_indirect(L);
+
+# ifdef __SHADOW_TRICKS__
+ L->shadow_transparency = shadow_transparency;
+# endif
+ }
+ }
}
-#ifdef __SUBSURFACE__
+# ifdef __SUBSURFACE__
ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
ShaderData *sd,
ShaderData *indirect_sd,
@@ -325,111 +290,81 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
Ray *ray,
float3 throughput)
{
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(!CLOSURE_IS_BSSRDF(sc->type))
- continue;
-
- /* set up random number generator */
- uint lcg_state = lcg_state_init(state, 0x68bc21eb);
- int num_samples = kernel_data.integrator.subsurface_samples * 3;
- float num_samples_inv = 1.0f/num_samples;
- uint bssrdf_rng_hash = cmj_hash(state->rng_hash, i);
-
- /* do subsurface scatter step with copy of shader data, this will
- * replace the BSSRDF with a diffuse BSDF closure */
- for(int j = 0; j < num_samples; j++) {
- PathState hit_state = *state;
- path_state_branch(&hit_state, j, num_samples);
- hit_state.rng_hash = bssrdf_rng_hash;
-
- LocalIntersection ss_isect;
- float bssrdf_u, bssrdf_v;
- path_state_rng_2D(kg, &hit_state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
- int num_hits = subsurface_scatter_multi_intersect(kg,
- &ss_isect,
- sd,
- &hit_state,
- sc,
- &lcg_state,
- bssrdf_u, bssrdf_v,
- true);
-
- hit_state.rng_offset += PRNG_BOUNCE_NUM;
-
-#ifdef __VOLUME__
- Ray volume_ray = *ray;
- bool need_update_volume_stack =
- kernel_data.integrator.use_volumes &&
- sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
-#endif /* __VOLUME__ */
-
- /* compute lighting with the BSDF closure */
- for(int hit = 0; hit < num_hits; hit++) {
- ShaderData bssrdf_sd = *sd;
- Bssrdf *bssrdf = (Bssrdf *)sc;
- ClosureType bssrdf_type = sc->type;
- float bssrdf_roughness = bssrdf->roughness;
- subsurface_scatter_multi_setup(kg,
- &ss_isect,
- hit,
- &bssrdf_sd,
- &hit_state,
- bssrdf_type,
- bssrdf_roughness);
-
-#ifdef __VOLUME__
- if(need_update_volume_stack) {
- /* Setup ray from previous surface point to the new one. */
- float3 P = ray_offset(bssrdf_sd.P, -bssrdf_sd.Ng);
- volume_ray.D = normalize_len(P - volume_ray.P,
- &volume_ray.t);
-
- for(int k = 0; k < VOLUME_STACK_SIZE; k++) {
- hit_state.volume_stack[k] = state->volume_stack[k];
- }
-
- kernel_volume_stack_update_for_subsurface(
- kg,
- emission_sd,
- &volume_ray,
- hit_state.volume_stack);
- }
-#endif /* __VOLUME__ */
-
-#ifdef __EMISSION__
- /* direct light */
- if(kernel_data.integrator.use_direct_light) {
- int all = (kernel_data.integrator.sample_all_lights_direct) ||
- (hit_state.flag & PATH_RAY_SHADOW_CATCHER);
- kernel_branched_path_surface_connect_light(
- kg,
- &bssrdf_sd,
- emission_sd,
- &hit_state,
- throughput,
- num_samples_inv,
- L,
- all);
- }
-#endif /* __EMISSION__ */
-
- /* indirect light */
- kernel_branched_path_surface_indirect_light(
- kg,
- &bssrdf_sd,
- indirect_sd,
- emission_sd,
- throughput,
- num_samples_inv,
- &hit_state,
- L);
- }
- }
- }
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+
+ if (!CLOSURE_IS_BSSRDF(sc->type))
+ continue;
+
+ /* set up random number generator */
+ uint lcg_state = lcg_state_init(state, 0x68bc21eb);
+ int num_samples = kernel_data.integrator.subsurface_samples * 3;
+ float num_samples_inv = 1.0f / num_samples;
+ uint bssrdf_rng_hash = cmj_hash(state->rng_hash, i);
+
+ /* do subsurface scatter step with copy of shader data, this will
+ * replace the BSSRDF with a diffuse BSDF closure */
+ for (int j = 0; j < num_samples; j++) {
+ PathState hit_state = *state;
+ path_state_branch(&hit_state, j, num_samples);
+ hit_state.rng_hash = bssrdf_rng_hash;
+
+ LocalIntersection ss_isect;
+ float bssrdf_u, bssrdf_v;
+ path_state_rng_2D(kg, &hit_state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+ int num_hits = subsurface_scatter_multi_intersect(
+ kg, &ss_isect, sd, &hit_state, sc, &lcg_state, bssrdf_u, bssrdf_v, true);
+
+ hit_state.rng_offset += PRNG_BOUNCE_NUM;
+
+# ifdef __VOLUME__
+ Ray volume_ray = *ray;
+ bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
+ sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
+# endif /* __VOLUME__ */
+
+ /* compute lighting with the BSDF closure */
+ for (int hit = 0; hit < num_hits; hit++) {
+ ShaderData bssrdf_sd = *sd;
+ Bssrdf *bssrdf = (Bssrdf *)sc;
+ ClosureType bssrdf_type = sc->type;
+ float bssrdf_roughness = bssrdf->roughness;
+ subsurface_scatter_multi_setup(
+ kg, &ss_isect, hit, &bssrdf_sd, &hit_state, bssrdf_type, bssrdf_roughness);
+
+# ifdef __VOLUME__
+ if (need_update_volume_stack) {
+ /* Setup ray from previous surface point to the new one. */
+ float3 P = ray_offset(bssrdf_sd.P, -bssrdf_sd.Ng);
+ volume_ray.D = normalize_len(P - volume_ray.P, &volume_ray.t);
+
+ for (int k = 0; k < VOLUME_STACK_SIZE; k++) {
+ hit_state.volume_stack[k] = state->volume_stack[k];
+ }
+
+ kernel_volume_stack_update_for_subsurface(
+ kg, emission_sd, &volume_ray, hit_state.volume_stack);
+ }
+# endif /* __VOLUME__ */
+
+# ifdef __EMISSION__
+ /* direct light */
+ if (kernel_data.integrator.use_direct_light) {
+ int all = (kernel_data.integrator.sample_all_lights_direct) ||
+ (hit_state.flag & PATH_RAY_SHADOW_CATCHER);
+ kernel_branched_path_surface_connect_light(
+ kg, &bssrdf_sd, emission_sd, &hit_state, throughput, num_samples_inv, L, all);
+ }
+# endif /* __EMISSION__ */
+
+ /* indirect light */
+ kernel_branched_path_surface_indirect_light(
+ kg, &bssrdf_sd, indirect_sd, emission_sd, throughput, num_samples_inv, &hit_state, L);
+ }
+ }
+ }
}
-#endif /* __SUBSURFACE__ */
+# endif /* __SUBSURFACE__ */
ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
uint rng_hash,
@@ -438,188 +373,171 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
ccl_global float *buffer,
PathRadiance *L)
{
- /* initialize */
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
-
- path_radiance_init(L, kernel_data.film.use_light_pass);
-
- /* shader data memory used for both volumes and surfaces, saves stack space */
- ShaderData sd;
- /* shader data used by emission, shadows, volume stacks, indirect path */
- ShaderDataTinyStorage emission_sd_storage;
- ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
- ShaderData indirect_sd;
-
- PathState state;
- path_state_init(kg, emission_sd, &state, rng_hash, sample, &ray);
-
- /* Main Loop
- * Here we only handle transparency intersections from the camera ray.
- * Indirect bounces are handled in kernel_branched_path_surface_indirect_light().
- */
- for(;;) {
- /* Find intersection with objects in scene. */
- Intersection isect;
- bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L);
-
-#ifdef __VOLUME__
- /* Volume integration. */
- kernel_branched_path_volume(kg,
- &sd,
- &state,
- &ray,
- &throughput,
- &isect,
- hit,
- &indirect_sd,
- emission_sd,
- L);
-#endif /* __VOLUME__ */
-
- /* Shade background. */
- if(!hit) {
- kernel_path_background(kg, &state, &ray, throughput, &sd, L);
- break;
- }
-
- /* Setup and evaluate shader. */
- shader_setup_from_ray(kg, &sd, &isect, &ray);
-
- /* Skip most work for volume bounding surface. */
-#ifdef __VOLUME__
- if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
-#endif
-
- shader_eval_surface(kg, &sd, &state, state.flag);
- shader_merge_closures(&sd);
-
- /* Apply shadow catcher, holdout, emission. */
- if(!kernel_path_shader_apply(kg,
- &sd,
- &state,
- &ray,
- throughput,
- emission_sd,
- L,
- buffer))
- {
- break;
- }
-
- /* transparency termination */
- if(state.flag & PATH_RAY_TRANSPARENT) {
- /* path termination. this is a strange place to put the termination, it's
- * mainly due to the mixed in MIS that we use. gives too many unneeded
- * shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_continuation_probability(kg, &state, throughput);
-
- if(probability == 0.0f) {
- break;
- }
- else if(probability != 1.0f) {
- float terminate = path_state_rng_1D(kg, &state, PRNG_TERMINATE);
-
- if(terminate >= probability)
- break;
-
- throughput /= probability;
- }
- }
-
- kernel_update_denoising_features(kg, &sd, &state, L);
-
-#ifdef __AO__
- /* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion) {
- kernel_branched_path_ao(kg, &sd, emission_sd, L, &state, throughput);
- }
-#endif /* __AO__ */
-
-#ifdef __SUBSURFACE__
- /* bssrdf scatter to a different location on the same object */
- if(sd.flag & SD_BSSRDF) {
- kernel_branched_path_subsurface_scatter(kg, &sd, &indirect_sd, emission_sd,
- L, &state, &ray, throughput);
- }
-#endif /* __SUBSURFACE__ */
-
- PathState hit_state = state;
-
-#ifdef __EMISSION__
- /* direct light */
- if(kernel_data.integrator.use_direct_light) {
- int all = (kernel_data.integrator.sample_all_lights_direct) ||
- (state.flag & PATH_RAY_SHADOW_CATCHER);
- kernel_branched_path_surface_connect_light(kg,
- &sd, emission_sd, &hit_state, throughput, 1.0f, L, all);
- }
-#endif /* __EMISSION__ */
-
- /* indirect light */
- kernel_branched_path_surface_indirect_light(kg,
- &sd, &indirect_sd, emission_sd, throughput, 1.0f, &hit_state, L);
-
- /* continue in case of transparency */
- throughput *= shader_bsdf_transparency(kg, &sd);
-
- if(is_zero(throughput))
- break;
-
- /* Update Path State */
- path_state_next(kg, &state, LABEL_TRANSPARENT);
-
-#ifdef __VOLUME__
- }
- else {
- if(!path_state_volume_next(kg, &state)) {
- break;
- }
- }
-#endif
-
- ray.P = ray_offset(sd.P, -sd.Ng);
- ray.t -= sd.ray_length; /* clipping works through transparent */
-
-#ifdef __RAY_DIFFERENTIALS__
- ray.dP = sd.dP;
- ray.dD.dx = -sd.dI.dx;
- ray.dD.dy = -sd.dI.dy;
-#endif /* __RAY_DIFFERENTIALS__ */
-
-#ifdef __VOLUME__
- /* enter/exit volume */
- kernel_volume_stack_enter_exit(kg, &sd, state.volume_stack);
-#endif /* __VOLUME__ */
- }
+ /* initialize */
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+
+ path_radiance_init(L, kernel_data.film.use_light_pass);
+
+ /* shader data memory used for both volumes and surfaces, saves stack space */
+ ShaderData sd;
+ /* shader data used by emission, shadows, volume stacks, indirect path */
+ ShaderDataTinyStorage emission_sd_storage;
+ ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
+ ShaderData indirect_sd;
+
+ PathState state;
+ path_state_init(kg, emission_sd, &state, rng_hash, sample, &ray);
+
+ /* Main Loop
+ * Here we only handle transparency intersections from the camera ray.
+ * Indirect bounces are handled in kernel_branched_path_surface_indirect_light().
+ */
+ for (;;) {
+ /* Find intersection with objects in scene. */
+ Intersection isect;
+ bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L);
+
+# ifdef __VOLUME__
+ /* Volume integration. */
+ kernel_branched_path_volume(
+ kg, &sd, &state, &ray, &throughput, &isect, hit, &indirect_sd, emission_sd, L);
+# endif /* __VOLUME__ */
+
+ /* Shade background. */
+ if (!hit) {
+ kernel_path_background(kg, &state, &ray, throughput, &sd, L);
+ break;
+ }
+
+ /* Setup and evaluate shader. */
+ shader_setup_from_ray(kg, &sd, &isect, &ray);
+
+ /* Skip most work for volume bounding surface. */
+# ifdef __VOLUME__
+ if (!(sd.flag & SD_HAS_ONLY_VOLUME)) {
+# endif
+
+ shader_eval_surface(kg, &sd, &state, state.flag);
+ shader_merge_closures(&sd);
+
+ /* Apply shadow catcher, holdout, emission. */
+ if (!kernel_path_shader_apply(kg, &sd, &state, &ray, throughput, emission_sd, L, buffer)) {
+ break;
+ }
+
+ /* transparency termination */
+ if (state.flag & PATH_RAY_TRANSPARENT) {
+ /* path termination. this is a strange place to put the termination, it's
+ * mainly due to the mixed in MIS that we use. gives too many unneeded
+ * shader evaluations, only need emission if we are going to terminate */
+ float probability = path_state_continuation_probability(kg, &state, throughput);
+
+ if (probability == 0.0f) {
+ break;
+ }
+ else if (probability != 1.0f) {
+ float terminate = path_state_rng_1D(kg, &state, PRNG_TERMINATE);
+
+ if (terminate >= probability)
+ break;
+
+ throughput /= probability;
+ }
+ }
+
+ kernel_update_denoising_features(kg, &sd, &state, L);
+
+# ifdef __AO__
+ /* ambient occlusion */
+ if (kernel_data.integrator.use_ambient_occlusion) {
+ kernel_branched_path_ao(kg, &sd, emission_sd, L, &state, throughput);
+ }
+# endif /* __AO__ */
+
+# ifdef __SUBSURFACE__
+ /* bssrdf scatter to a different location on the same object */
+ if (sd.flag & SD_BSSRDF) {
+ kernel_branched_path_subsurface_scatter(
+ kg, &sd, &indirect_sd, emission_sd, L, &state, &ray, throughput);
+ }
+# endif /* __SUBSURFACE__ */
+
+ PathState hit_state = state;
+
+# ifdef __EMISSION__
+ /* direct light */
+ if (kernel_data.integrator.use_direct_light) {
+ int all = (kernel_data.integrator.sample_all_lights_direct) ||
+ (state.flag & PATH_RAY_SHADOW_CATCHER);
+ kernel_branched_path_surface_connect_light(
+ kg, &sd, emission_sd, &hit_state, throughput, 1.0f, L, all);
+ }
+# endif /* __EMISSION__ */
+
+ /* indirect light */
+ kernel_branched_path_surface_indirect_light(
+ kg, &sd, &indirect_sd, emission_sd, throughput, 1.0f, &hit_state, L);
+
+ /* continue in case of transparency */
+ throughput *= shader_bsdf_transparency(kg, &sd);
+
+ if (is_zero(throughput))
+ break;
+
+ /* Update Path State */
+ path_state_next(kg, &state, LABEL_TRANSPARENT);
+
+# ifdef __VOLUME__
+ }
+ else {
+ if (!path_state_volume_next(kg, &state)) {
+ break;
+ }
+ }
+# endif
+
+ ray.P = ray_offset(sd.P, -sd.Ng);
+ ray.t -= sd.ray_length; /* clipping works through transparent */
+
+# ifdef __RAY_DIFFERENTIALS__
+ ray.dP = sd.dP;
+ ray.dD.dx = -sd.dI.dx;
+ ray.dD.dy = -sd.dI.dy;
+# endif /* __RAY_DIFFERENTIALS__ */
+
+# ifdef __VOLUME__
+ /* enter/exit volume */
+ kernel_volume_stack_enter_exit(kg, &sd, state.volume_stack);
+# endif /* __VOLUME__ */
+ }
}
-ccl_device void kernel_branched_path_trace(KernelGlobals *kg,
- ccl_global float *buffer,
- int sample, int x, int y, int offset, int stride)
+ccl_device void kernel_branched_path_trace(
+ KernelGlobals *kg, ccl_global float *buffer, int sample, int x, int y, int offset, int stride)
{
- /* buffer offset */
- int index = offset + x + y*stride;
- int pass_stride = kernel_data.film.pass_stride;
+ /* buffer offset */
+ int index = offset + x + y * stride;
+ int pass_stride = kernel_data.film.pass_stride;
- buffer += index*pass_stride;
+ buffer += index * pass_stride;
- /* initialize random numbers and ray */
- uint rng_hash;
- Ray ray;
+ /* initialize random numbers and ray */
+ uint rng_hash;
+ Ray ray;
- kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &ray);
+ kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &ray);
- /* integrate */
- PathRadiance L;
+ /* integrate */
+ PathRadiance L;
- if(ray.t != 0.0f) {
- kernel_branched_path_integrate(kg, rng_hash, sample, ray, buffer, &L);
- kernel_write_result(kg, buffer, sample, &L);
- }
+ if (ray.t != 0.0f) {
+ kernel_branched_path_integrate(kg, rng_hash, sample, ray, buffer, &L);
+ kernel_write_result(kg, buffer, sample, &L);
+ }
}
-#endif /* __SPLIT_KERNEL__ */
+# endif /* __SPLIT_KERNEL__ */
-#endif /* __BRANCHED_PATH__ */
+#endif /* __BRANCHED_PATH__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path_common.h b/intern/cycles/kernel/kernel_path_common.h
index d83fd474cde..815767595a9 100644
--- a/intern/cycles/kernel/kernel_path_common.h
+++ b/intern/cycles/kernel/kernel_path_common.h
@@ -18,34 +18,31 @@
CCL_NAMESPACE_BEGIN
-ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg,
- int sample,
- int x, int y,
- uint *rng_hash,
- ccl_addr_space Ray *ray)
+ccl_device_inline void kernel_path_trace_setup(
+ KernelGlobals *kg, int sample, int x, int y, uint *rng_hash, ccl_addr_space Ray *ray)
{
- float filter_u;
- float filter_v;
+ float filter_u;
+ float filter_v;
- int num_samples = kernel_data.integrator.aa_samples;
+ int num_samples = kernel_data.integrator.aa_samples;
- path_rng_init(kg, sample, num_samples, rng_hash, x, y, &filter_u, &filter_v);
+ path_rng_init(kg, sample, num_samples, rng_hash, x, y, &filter_u, &filter_v);
- /* sample camera ray */
+ /* sample camera ray */
- float lens_u = 0.0f, lens_v = 0.0f;
+ float lens_u = 0.0f, lens_v = 0.0f;
- if(kernel_data.cam.aperturesize > 0.0f)
- path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v);
+ if (kernel_data.cam.aperturesize > 0.0f)
+ path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v);
- float time = 0.0f;
+ float time = 0.0f;
#ifdef __CAMERA_MOTION__
- if(kernel_data.cam.shuttertime != -1.0f)
- time = path_rng_1D(kg, *rng_hash, sample, num_samples, PRNG_TIME);
+ if (kernel_data.cam.shuttertime != -1.0f)
+ time = path_rng_1D(kg, *rng_hash, sample, num_samples, PRNG_TIME);
#endif
- camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray);
+ camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index e85050df4bb..cdca0b1f9bf 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -23,249 +23,252 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
int sample,
ccl_addr_space Ray *ray)
{
- state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP|PATH_RAY_TRANSPARENT_BACKGROUND;
+ state->flag = PATH_RAY_CAMERA | PATH_RAY_MIS_SKIP | PATH_RAY_TRANSPARENT_BACKGROUND;
- state->rng_hash = rng_hash;
- state->rng_offset = PRNG_BASE_NUM;
- state->sample = sample;
- state->num_samples = kernel_data.integrator.aa_samples;
- state->branch_factor = 1.0f;
+ state->rng_hash = rng_hash;
+ state->rng_offset = PRNG_BASE_NUM;
+ state->sample = sample;
+ state->num_samples = kernel_data.integrator.aa_samples;
+ state->branch_factor = 1.0f;
- state->bounce = 0;
- state->diffuse_bounce = 0;
- state->glossy_bounce = 0;
- state->transmission_bounce = 0;
- state->transparent_bounce = 0;
+ state->bounce = 0;
+ state->diffuse_bounce = 0;
+ state->glossy_bounce = 0;
+ state->transmission_bounce = 0;
+ state->transparent_bounce = 0;
#ifdef __DENOISING_FEATURES__
- if(kernel_data.film.pass_denoising_data) {
- state->flag |= PATH_RAY_STORE_SHADOW_INFO;
- state->denoising_feature_weight = 1.0f;
- }
- else {
- state->denoising_feature_weight = 0.0f;
- }
-#endif /* __DENOISING_FEATURES__ */
-
- state->min_ray_pdf = FLT_MAX;
- state->ray_pdf = 0.0f;
+ if (kernel_data.film.pass_denoising_data) {
+ state->flag |= PATH_RAY_STORE_SHADOW_INFO;
+ state->denoising_feature_weight = 1.0f;
+ }
+ else {
+ state->denoising_feature_weight = 0.0f;
+ }
+#endif /* __DENOISING_FEATURES__ */
+
+ state->min_ray_pdf = FLT_MAX;
+ state->ray_pdf = 0.0f;
#ifdef __LAMP_MIS__
- state->ray_t = 0.0f;
+ state->ray_t = 0.0f;
#endif
#ifdef __VOLUME__
- state->volume_bounce = 0;
- state->volume_bounds_bounce = 0;
-
- if(kernel_data.integrator.use_volumes) {
- /* Initialize volume stack with volume we are inside of. */
- kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
- }
- else {
- state->volume_stack[0].shader = SHADER_NONE;
- }
+ state->volume_bounce = 0;
+ state->volume_bounds_bounce = 0;
+
+ if (kernel_data.integrator.use_volumes) {
+ /* Initialize volume stack with volume we are inside of. */
+ kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
+ }
+ else {
+ state->volume_stack[0].shader = SHADER_NONE;
+ }
#endif
}
-ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label)
+ccl_device_inline void path_state_next(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ int label)
{
- /* ray through transparent keeps same flags from previous ray and is
- * not counted as a regular bounce, transparent has separate max */
- if(label & LABEL_TRANSPARENT) {
- state->flag |= PATH_RAY_TRANSPARENT;
- state->transparent_bounce++;
- if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
- state->flag |= PATH_RAY_TERMINATE_IMMEDIATE;
- }
+ /* ray through transparent keeps same flags from previous ray and is
+ * not counted as a regular bounce, transparent has separate max */
+ if (label & LABEL_TRANSPARENT) {
+ state->flag |= PATH_RAY_TRANSPARENT;
+ state->transparent_bounce++;
+ if (state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
+ state->flag |= PATH_RAY_TERMINATE_IMMEDIATE;
+ }
- if(!kernel_data.integrator.transparent_shadows)
- state->flag |= PATH_RAY_MIS_SKIP;
+ if (!kernel_data.integrator.transparent_shadows)
+ state->flag |= PATH_RAY_MIS_SKIP;
- /* random number generator next bounce */
- state->rng_offset += PRNG_BOUNCE_NUM;
+ /* random number generator next bounce */
+ state->rng_offset += PRNG_BOUNCE_NUM;
- return;
- }
+ return;
+ }
- state->bounce++;
- if(state->bounce >= kernel_data.integrator.max_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
+ state->bounce++;
+ if (state->bounce >= kernel_data.integrator.max_bounce) {
+ state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
+ }
- state->flag &= ~(PATH_RAY_ALL_VISIBILITY|PATH_RAY_MIS_SKIP);
+ state->flag &= ~(PATH_RAY_ALL_VISIBILITY | PATH_RAY_MIS_SKIP);
#ifdef __VOLUME__
- if(label & LABEL_VOLUME_SCATTER) {
- /* volume scatter */
- state->flag |= PATH_RAY_VOLUME_SCATTER;
- state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
-
- state->volume_bounce++;
- if(state->volume_bounce >= kernel_data.integrator.max_volume_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
- else
+ if (label & LABEL_VOLUME_SCATTER) {
+ /* volume scatter */
+ state->flag |= PATH_RAY_VOLUME_SCATTER;
+ state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
+
+ state->volume_bounce++;
+ if (state->volume_bounce >= kernel_data.integrator.max_volume_bounce) {
+ state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
+ }
+ }
+ else
#endif
- {
- /* surface reflection/transmission */
- if(label & LABEL_REFLECT) {
- state->flag |= PATH_RAY_REFLECT;
- state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
-
- if(label & LABEL_DIFFUSE) {
- state->diffuse_bounce++;
- if(state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
- else {
- state->glossy_bounce++;
- if(state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
- }
- else {
- kernel_assert(label & LABEL_TRANSMIT);
-
- state->flag |= PATH_RAY_TRANSMIT;
-
- if(!(label & LABEL_TRANSMIT_TRANSPARENT)) {
- state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
- }
-
- state->transmission_bounce++;
- if(state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
-
- /* diffuse/glossy/singular */
- if(label & LABEL_DIFFUSE) {
- state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR;
- }
- else if(label & LABEL_GLOSSY) {
- state->flag |= PATH_RAY_GLOSSY;
- }
- else {
- kernel_assert(label & LABEL_SINGULAR);
- state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
- }
- }
-
- /* random number generator next bounce */
- state->rng_offset += PRNG_BOUNCE_NUM;
+ {
+ /* surface reflection/transmission */
+ if (label & LABEL_REFLECT) {
+ state->flag |= PATH_RAY_REFLECT;
+ state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
+
+ if (label & LABEL_DIFFUSE) {
+ state->diffuse_bounce++;
+ if (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) {
+ state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
+ }
+ }
+ else {
+ state->glossy_bounce++;
+ if (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) {
+ state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
+ }
+ }
+ }
+ else {
+ kernel_assert(label & LABEL_TRANSMIT);
+
+ state->flag |= PATH_RAY_TRANSMIT;
+
+ if (!(label & LABEL_TRANSMIT_TRANSPARENT)) {
+ state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
+ }
+
+ state->transmission_bounce++;
+ if (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce) {
+ state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
+ }
+ }
+
+ /* diffuse/glossy/singular */
+ if (label & LABEL_DIFFUSE) {
+ state->flag |= PATH_RAY_DIFFUSE | PATH_RAY_DIFFUSE_ANCESTOR;
+ }
+ else if (label & LABEL_GLOSSY) {
+ state->flag |= PATH_RAY_GLOSSY;
+ }
+ else {
+ kernel_assert(label & LABEL_SINGULAR);
+ state->flag |= PATH_RAY_GLOSSY | PATH_RAY_SINGULAR | PATH_RAY_MIS_SKIP;
+ }
+ }
+
+ /* random number generator next bounce */
+ state->rng_offset += PRNG_BOUNCE_NUM;
#ifdef __DENOISING_FEATURES__
- if((state->denoising_feature_weight == 0.0f) && !(state->flag & PATH_RAY_SHADOW_CATCHER)) {
- state->flag &= ~PATH_RAY_STORE_SHADOW_INFO;
- }
+ if ((state->denoising_feature_weight == 0.0f) && !(state->flag & PATH_RAY_SHADOW_CATCHER)) {
+ state->flag &= ~PATH_RAY_STORE_SHADOW_INFO;
+ }
#endif
}
#ifdef __VOLUME__
ccl_device_inline bool path_state_volume_next(KernelGlobals *kg, ccl_addr_space PathState *state)
{
- /* For volume bounding meshes we pass through without counting transparent
- * bounces, only sanity check in case self intersection gets us stuck. */
- state->volume_bounds_bounce++;
- if(state->volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
- return false;
- }
-
- /* Random number generator next bounce. */
- if(state->volume_bounds_bounce > 1) {
- state->rng_offset += PRNG_BOUNCE_NUM;
- }
-
- return true;
+ /* For volume bounding meshes we pass through without counting transparent
+ * bounces, only sanity check in case self intersection gets us stuck. */
+ state->volume_bounds_bounce++;
+ if (state->volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
+ return false;
+ }
+
+ /* Random number generator next bounce. */
+ if (state->volume_bounds_bounce > 1) {
+ state->rng_offset += PRNG_BOUNCE_NUM;
+ }
+
+ return true;
}
#endif
-ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, ccl_addr_space PathState *state)
+ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg,
+ ccl_addr_space PathState *state)
{
- uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
+ uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
- /* for visibility, diffuse/glossy are for reflection only */
- if(flag & PATH_RAY_TRANSMIT)
- flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
- /* todo: this is not supported as its own ray visibility yet */
- if(state->flag & PATH_RAY_VOLUME_SCATTER)
- flag |= PATH_RAY_DIFFUSE;
+ /* for visibility, diffuse/glossy are for reflection only */
+ if (flag & PATH_RAY_TRANSMIT)
+ flag &= ~(PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY);
+ /* todo: this is not supported as its own ray visibility yet */
+ if (state->flag & PATH_RAY_VOLUME_SCATTER)
+ flag |= PATH_RAY_DIFFUSE;
- return flag;
+ return flag;
}
ccl_device_inline float path_state_continuation_probability(KernelGlobals *kg,
ccl_addr_space PathState *state,
const float3 throughput)
{
- if(state->flag & PATH_RAY_TERMINATE_IMMEDIATE) {
- /* Ray is to be terminated immediately. */
- return 0.0f;
- }
- else if(state->flag & PATH_RAY_TRANSPARENT) {
- /* Do at least one bounce without RR. */
- if(state->transparent_bounce <= 1) {
- return 1.0f;
- }
+ if (state->flag & PATH_RAY_TERMINATE_IMMEDIATE) {
+ /* Ray is to be terminated immediately. */
+ return 0.0f;
+ }
+ else if (state->flag & PATH_RAY_TRANSPARENT) {
+ /* Do at least one bounce without RR. */
+ if (state->transparent_bounce <= 1) {
+ return 1.0f;
+ }
#ifdef __SHADOW_TRICKS__
- /* Exception for shadow catcher not working correctly with RR. */
- else if((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
- return 1.0f;
- }
+ /* Exception for shadow catcher not working correctly with RR. */
+ else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
+ return 1.0f;
+ }
#endif
- }
- else {
- /* Do at least one bounce without RR. */
- if(state->bounce <= 1) {
- return 1.0f;
- }
+ }
+ else {
+ /* Do at least one bounce without RR. */
+ if (state->bounce <= 1) {
+ return 1.0f;
+ }
#ifdef __SHADOW_TRICKS__
- /* Exception for shadow catcher not working correctly with RR. */
- else if((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
- return 1.0f;
- }
+ /* Exception for shadow catcher not working correctly with RR. */
+ else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
+ return 1.0f;
+ }
#endif
- }
+ }
- /* Probabilistic termination: use sqrt() to roughly match typical view
- * transform and do path termination a bit later on average. */
- return min(sqrtf(max3(fabs(throughput)) * state->branch_factor), 1.0f);
+ /* Probabilistic termination: use sqrt() to roughly match typical view
+ * transform and do path termination a bit later on average. */
+ return min(sqrtf(max3(fabs(throughput)) * state->branch_factor), 1.0f);
}
/* TODO(DingTo): Find more meaningful name for this */
ccl_device_inline void path_state_modify_bounce(ccl_addr_space PathState *state, bool increase)
{
- /* Modify bounce temporarily for shader eval */
- if(increase)
- state->bounce += 1;
- else
- state->bounce -= 1;
+ /* Modify bounce temporarily for shader eval */
+ if (increase)
+ state->bounce += 1;
+ else
+ state->bounce -= 1;
}
ccl_device_inline bool path_state_ao_bounce(KernelGlobals *kg, ccl_addr_space PathState *state)
{
- if(state->bounce <= kernel_data.integrator.ao_bounces) {
- return false;
- }
+ if (state->bounce <= kernel_data.integrator.ao_bounces) {
+ return false;
+ }
- int bounce = state->bounce - state->transmission_bounce - (state->glossy_bounce > 0);
- return (bounce > kernel_data.integrator.ao_bounces);
+ int bounce = state->bounce - state->transmission_bounce - (state->glossy_bounce > 0);
+ return (bounce > kernel_data.integrator.ao_bounces);
}
ccl_device_inline void path_state_branch(ccl_addr_space PathState *state,
int branch,
int num_branches)
{
- if(num_branches > 1) {
- /* Path is splitting into a branch, adjust so that each branch
- * still gets a unique sample from the same sequence. */
- state->sample = state->sample*num_branches + branch;
- state->num_samples = state->num_samples*num_branches;
- state->branch_factor *= num_branches;
- }
+ if (num_branches > 1) {
+ /* Path is splitting into a branch, adjust so that each branch
+ * still gets a unique sample from the same sequence. */
+ state->sample = state->sample * num_branches + branch;
+ state->num_samples = state->num_samples * num_branches;
+ state->branch_factor *= num_branches;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path_subsurface.h b/intern/cycles/kernel/kernel_path_subsurface.h
index b5a92c74ed5..97d3f292ca3 100644
--- a/intern/cycles/kernel/kernel_path_subsurface.h
+++ b/intern/cycles/kernel/kernel_path_subsurface.h
@@ -22,141 +22,118 @@ ccl_device
# else
ccl_device_inline
# endif
-bool kernel_path_subsurface_scatter(
- KernelGlobals *kg,
- ShaderData *sd,
- ShaderData *emission_sd,
- PathRadiance *L,
- ccl_addr_space PathState *state,
- ccl_addr_space Ray *ray,
- ccl_addr_space float3 *throughput,
- ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
+ bool
+ kernel_path_subsurface_scatter(KernelGlobals *kg,
+ ShaderData *sd,
+ ShaderData *emission_sd,
+ PathRadiance *L,
+ ccl_addr_space PathState *state,
+ ccl_addr_space Ray *ray,
+ ccl_addr_space float3 *throughput,
+ ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
{
- PROFILING_INIT(kg, PROFILING_SUBSURFACE);
-
- float bssrdf_u, bssrdf_v;
- path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
-
- const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u);
-
- /* do bssrdf scatter step if we picked a bssrdf closure */
- if(sc) {
- /* We should never have two consecutive BSSRDF bounces,
- * the second one should be converted to a diffuse BSDF to
- * avoid this.
- */
- kernel_assert(!(state->flag & PATH_RAY_DIFFUSE_ANCESTOR));
-
- uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
-
- LocalIntersection ss_isect;
- int num_hits = subsurface_scatter_multi_intersect(kg,
- &ss_isect,
- sd,
- state,
- sc,
- &lcg_state,
- bssrdf_u, bssrdf_v,
- false);
+ PROFILING_INIT(kg, PROFILING_SUBSURFACE);
+
+ float bssrdf_u, bssrdf_v;
+ path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+
+ const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u);
+
+ /* do bssrdf scatter step if we picked a bssrdf closure */
+ if (sc) {
+ /* We should never have two consecutive BSSRDF bounces,
+ * the second one should be converted to a diffuse BSDF to
+ * avoid this.
+ */
+ kernel_assert(!(state->flag & PATH_RAY_DIFFUSE_ANCESTOR));
+
+ uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
+
+ LocalIntersection ss_isect;
+ int num_hits = subsurface_scatter_multi_intersect(
+ kg, &ss_isect, sd, state, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
# ifdef __VOLUME__
- bool need_update_volume_stack =
- kernel_data.integrator.use_volumes &&
- sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
-# endif /* __VOLUME__ */
-
- /* Closure memory will be overwritten, so read required variables now. */
- Bssrdf *bssrdf = (Bssrdf *)sc;
- ClosureType bssrdf_type = sc->type;
- float bssrdf_roughness = bssrdf->roughness;
-
- /* compute lighting with the BSDF closure */
- for(int hit = 0; hit < num_hits; hit++) {
- /* NOTE: We reuse the existing ShaderData, we assume the path
- * integration loop stops when this function returns true.
- */
- subsurface_scatter_multi_setup(kg,
- &ss_isect,
- hit,
- sd,
- state,
- bssrdf_type,
- bssrdf_roughness);
-
- kernel_path_surface_connect_light(kg, sd, emission_sd, *throughput, state, L);
-
- ccl_addr_space PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays];
- ccl_addr_space Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays];
- ccl_addr_space float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays];
- PathRadianceState *hit_L_state = &ss_indirect->L_state[ss_indirect->num_rays];
-
- *hit_state = *state;
- *hit_ray = *ray;
- *hit_tp = *throughput;
- *hit_L_state = L->state;
-
- hit_state->rng_offset += PRNG_BOUNCE_NUM;
-
- if(kernel_path_surface_bounce(kg,
- sd,
- hit_tp,
- hit_state,
- hit_L_state,
- hit_ray))
- {
+ bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
+ sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
+# endif /* __VOLUME__ */
+
+ /* Closure memory will be overwritten, so read required variables now. */
+ Bssrdf *bssrdf = (Bssrdf *)sc;
+ ClosureType bssrdf_type = sc->type;
+ float bssrdf_roughness = bssrdf->roughness;
+
+ /* compute lighting with the BSDF closure */
+ for (int hit = 0; hit < num_hits; hit++) {
+ /* NOTE: We reuse the existing ShaderData, we assume the path
+ * integration loop stops when this function returns true.
+ */
+ subsurface_scatter_multi_setup(kg, &ss_isect, hit, sd, state, bssrdf_type, bssrdf_roughness);
+
+ kernel_path_surface_connect_light(kg, sd, emission_sd, *throughput, state, L);
+
+ ccl_addr_space PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays];
+ ccl_addr_space Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays];
+ ccl_addr_space float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays];
+ PathRadianceState *hit_L_state = &ss_indirect->L_state[ss_indirect->num_rays];
+
+ *hit_state = *state;
+ *hit_ray = *ray;
+ *hit_tp = *throughput;
+ *hit_L_state = L->state;
+
+ hit_state->rng_offset += PRNG_BOUNCE_NUM;
+
+ if (kernel_path_surface_bounce(kg, sd, hit_tp, hit_state, hit_L_state, hit_ray)) {
# ifdef __LAMP_MIS__
- hit_state->ray_t = 0.0f;
-# endif /* __LAMP_MIS__ */
+ hit_state->ray_t = 0.0f;
+# endif /* __LAMP_MIS__ */
# ifdef __VOLUME__
- if(need_update_volume_stack) {
- Ray volume_ray = *ray;
- /* Setup ray from previous surface point to the new one. */
- volume_ray.D = normalize_len(hit_ray->P - volume_ray.P,
- &volume_ray.t);
-
- kernel_volume_stack_update_for_subsurface(
- kg,
- emission_sd,
- &volume_ray,
- hit_state->volume_stack);
- }
-# endif /* __VOLUME__ */
- ss_indirect->num_rays++;
- }
- }
- return true;
- }
- return false;
+ if (need_update_volume_stack) {
+ Ray volume_ray = *ray;
+ /* Setup ray from previous surface point to the new one. */
+ volume_ray.D = normalize_len(hit_ray->P - volume_ray.P, &volume_ray.t);
+
+ kernel_volume_stack_update_for_subsurface(
+ kg, emission_sd, &volume_ray, hit_state->volume_stack);
+ }
+# endif /* __VOLUME__ */
+ ss_indirect->num_rays++;
+ }
+ }
+ return true;
+ }
+ return false;
}
ccl_device_inline void kernel_path_subsurface_init_indirect(
- ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
+ ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
{
- ss_indirect->num_rays = 0;
+ ss_indirect->num_rays = 0;
}
ccl_device void kernel_path_subsurface_setup_indirect(
- KernelGlobals *kg,
- ccl_addr_space SubsurfaceIndirectRays *ss_indirect,
- ccl_addr_space PathState *state,
- ccl_addr_space Ray *ray,
- PathRadiance *L,
- ccl_addr_space float3 *throughput)
+ KernelGlobals *kg,
+ ccl_addr_space SubsurfaceIndirectRays *ss_indirect,
+ ccl_addr_space PathState *state,
+ ccl_addr_space Ray *ray,
+ PathRadiance *L,
+ ccl_addr_space float3 *throughput)
{
- /* Setup state, ray and throughput for indirect SSS rays. */
- ss_indirect->num_rays--;
+ /* Setup state, ray and throughput for indirect SSS rays. */
+ ss_indirect->num_rays--;
- path_radiance_sum_indirect(L);
- path_radiance_reset_indirect(L);
+ path_radiance_sum_indirect(L);
+ path_radiance_reset_indirect(L);
- *state = ss_indirect->state[ss_indirect->num_rays];
- *ray = ss_indirect->rays[ss_indirect->num_rays];
- L->state = ss_indirect->L_state[ss_indirect->num_rays];
- *throughput = ss_indirect->throughputs[ss_indirect->num_rays];
+ *state = ss_indirect->state[ss_indirect->num_rays];
+ *ray = ss_indirect->rays[ss_indirect->num_rays];
+ L->state = ss_indirect->L_state[ss_indirect->num_rays];
+ *throughput = ss_indirect->throughputs[ss_indirect->num_rays];
- state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM;
+ state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM;
}
-#endif /* __SUBSURFACE__ */
+#endif /* __SUBSURFACE__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h
index 0d18a1e8c77..6251313c5f8 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -16,255 +16,280 @@
CCL_NAMESPACE_BEGIN
-#if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) || defined(__SHADOW_TRICKS__) || defined(__BAKING__)
+#if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) || defined(__SHADOW_TRICKS__) || \
+ defined(__BAKING__)
/* branched path tracing: connect path directly to position on one or more lights and add it to L */
ccl_device_noinline void kernel_branched_path_surface_connect_light(
- KernelGlobals *kg,
- ShaderData *sd,
- ShaderData *emission_sd,
- ccl_addr_space PathState *state,
- float3 throughput,
- float num_samples_adjust,
- PathRadiance *L,
- int sample_all_lights)
+ KernelGlobals *kg,
+ ShaderData *sd,
+ ShaderData *emission_sd,
+ ccl_addr_space PathState *state,
+ float3 throughput,
+ float num_samples_adjust,
+ PathRadiance *L,
+ int sample_all_lights)
{
-#ifdef __EMISSION__
- /* sample illumination from lights to find path contribution */
- if(!(sd->flag & SD_BSDF_HAS_EVAL))
- return;
-
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
-
-# ifdef __OBJECT_MOTION__
- light_ray.time = sd->time;
+# ifdef __EMISSION__
+ /* sample illumination from lights to find path contribution */
+ if (!(sd->flag & SD_BSDF_HAS_EVAL))
+ return;
+
+ Ray light_ray;
+ BsdfEval L_light;
+ bool is_lamp;
+
+# ifdef __OBJECT_MOTION__
+ light_ray.time = sd->time;
+# endif
+
+ if (sample_all_lights) {
+ /* lamp sampling */
+ for (int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+ if (UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
+ continue;
+
+ int num_samples = ceil_to_int(num_samples_adjust * light_select_num_samples(kg, i));
+ float num_samples_inv = num_samples_adjust /
+ (num_samples * kernel_data.integrator.num_all_lights);
+ uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
+
+ for (int j = 0; j < num_samples; j++) {
+ float light_u, light_v;
+ path_branched_rng_2D(
+ kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+ float terminate = path_branched_rng_light_termination(
+ kg, lamp_rng_hash, state, j, num_samples);
+
+ LightSample ls;
+ if (lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
+ /* The sampling probability returned by lamp_light_sample assumes that all lights were sampled.
+ * However, this code only samples lamps, so if the scene also had mesh lights, the real probability is twice as high. */
+ if (kernel_data.integrator.pdf_triangles != 0.0f)
+ ls.pdf *= 2.0f;
+
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L,
+ state,
+ throughput * num_samples_inv,
+ &L_light,
+ shadow,
+ num_samples_inv,
+ is_lamp);
+ }
+ else {
+ path_radiance_accum_total_light(L, state, throughput * num_samples_inv, &L_light);
+ }
+ }
+ }
+ }
+ }
+
+ /* mesh light sampling */
+ if (kernel_data.integrator.pdf_triangles != 0.0f) {
+ int num_samples = ceil_to_int(num_samples_adjust *
+ kernel_data.integrator.mesh_light_samples);
+ float num_samples_inv = num_samples_adjust / num_samples;
+
+ for (int j = 0; j < num_samples; j++) {
+ float light_u, light_v;
+ path_branched_rng_2D(
+ kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+ float terminate = path_branched_rng_light_termination(
+ kg, state->rng_hash, state, j, num_samples);
+
+ /* only sample triangle lights */
+ if (kernel_data.integrator.num_all_lights)
+ light_u = 0.5f * light_u;
+
+ LightSample ls;
+ if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
+ /* Same as above, probability needs to be corrected since the sampling was forced to select a mesh light. */
+ if (kernel_data.integrator.num_all_lights)
+ ls.pdf *= 2.0f;
+
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L,
+ state,
+ throughput * num_samples_inv,
+ &L_light,
+ shadow,
+ num_samples_inv,
+ is_lamp);
+ }
+ else {
+ path_radiance_accum_total_light(L, state, throughput * num_samples_inv, &L_light);
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ /* sample one light at random */
+ float light_u, light_v;
+ path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
+ float terminate = path_state_rng_light_termination(kg, state);
+
+ LightSample ls;
+ if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
+ /* sample random light */
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L,
+ state,
+ throughput * num_samples_adjust,
+ &L_light,
+ shadow,
+ num_samples_adjust,
+ is_lamp);
+ }
+ else {
+ path_radiance_accum_total_light(L, state, throughput * num_samples_adjust, &L_light);
+ }
+ }
+ }
+ }
# endif
-
- if(sample_all_lights) {
- /* lamp sampling */
- for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
- if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
- continue;
-
- int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
- float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
- uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
-
- for(int j = 0; j < num_samples; j++) {
- float light_u, light_v;
- path_branched_rng_2D(kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
- float terminate = path_branched_rng_light_termination(kg, lamp_rng_hash, state, j, num_samples);
-
- LightSample ls;
- if(lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
- /* The sampling probability returned by lamp_light_sample assumes that all lights were sampled.
- * However, this code only samples lamps, so if the scene also had mesh lights, the real probability is twice as high. */
- if(kernel_data.integrator.pdf_triangles != 0.0f)
- ls.pdf *= 2.0f;
-
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
- }
- else {
- path_radiance_accum_total_light(L, state, throughput*num_samples_inv, &L_light);
- }
- }
- }
- }
- }
-
- /* mesh light sampling */
- if(kernel_data.integrator.pdf_triangles != 0.0f) {
- int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
- float num_samples_inv = num_samples_adjust/num_samples;
-
- for(int j = 0; j < num_samples; j++) {
- float light_u, light_v;
- path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
- float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples);
-
- /* only sample triangle lights */
- if(kernel_data.integrator.num_all_lights)
- light_u = 0.5f*light_u;
-
- LightSample ls;
- if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
- /* Same as above, probability needs to be corrected since the sampling was forced to select a mesh light. */
- if(kernel_data.integrator.num_all_lights)
- ls.pdf *= 2.0f;
-
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
- }
- else {
- path_radiance_accum_total_light(L, state, throughput*num_samples_inv, &L_light);
- }
- }
- }
- }
- }
- }
- else {
- /* sample one light at random */
- float light_u, light_v;
- path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
- float terminate = path_state_rng_light_termination(kg, state);
-
- LightSample ls;
- if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
- /* sample random light */
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, is_lamp);
- }
- else {
- path_radiance_accum_total_light(L, state, throughput*num_samples_adjust, &L_light);
- }
- }
- }
- }
-#endif
}
/* branched path tracing: bounce off or through surface to with new direction stored in ray */
-ccl_device bool kernel_branched_path_surface_bounce(
- KernelGlobals *kg,
- ShaderData *sd,
- const ShaderClosure *sc,
- int sample,
- int num_samples,
- ccl_addr_space float3 *throughput,
- ccl_addr_space PathState *state,
- PathRadianceState *L_state,
- ccl_addr_space Ray *ray,
- float sum_sample_weight)
+ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg,
+ ShaderData *sd,
+ const ShaderClosure *sc,
+ int sample,
+ int num_samples,
+ ccl_addr_space float3 *throughput,
+ ccl_addr_space PathState *state,
+ PathRadianceState *L_state,
+ ccl_addr_space Ray *ray,
+ float sum_sample_weight)
{
- /* sample BSDF */
- float bsdf_pdf;
- BsdfEval bsdf_eval;
- float3 bsdf_omega_in;
- differential3 bsdf_domega_in;
- float bsdf_u, bsdf_v;
- path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
- int label;
-
- label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval,
- &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
-
- if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
- return false;
-
- /* modify throughput */
- path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
-
-#ifdef __DENOISING_FEATURES__
- state->denoising_feature_weight *= sc->sample_weight / (sum_sample_weight * num_samples);
-#endif
+ /* sample BSDF */
+ float bsdf_pdf;
+ BsdfEval bsdf_eval;
+ float3 bsdf_omega_in;
+ differential3 bsdf_domega_in;
+ float bsdf_u, bsdf_v;
+ path_branched_rng_2D(
+ kg, state->rng_hash, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+ int label;
+
+ label = shader_bsdf_sample_closure(
+ kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
+
+ if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
+ return false;
+
+ /* modify throughput */
+ path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
+
+# ifdef __DENOISING_FEATURES__
+ state->denoising_feature_weight *= sc->sample_weight / (sum_sample_weight * num_samples);
+# endif
- /* modify path state */
- path_state_next(kg, state, label);
+ /* modify path state */
+ path_state_next(kg, state, label);
- /* setup ray */
- ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng);
- ray->D = normalize(bsdf_omega_in);
- ray->t = FLT_MAX;
-#ifdef __RAY_DIFFERENTIALS__
- ray->dP = sd->dP;
- ray->dD = bsdf_domega_in;
-#endif
-#ifdef __OBJECT_MOTION__
- ray->time = sd->time;
-#endif
+ /* setup ray */
+ ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT) ? -sd->Ng : sd->Ng);
+ ray->D = normalize(bsdf_omega_in);
+ ray->t = FLT_MAX;
+# ifdef __RAY_DIFFERENTIALS__
+ ray->dP = sd->dP;
+ ray->dD = bsdf_domega_in;
+# endif
+# ifdef __OBJECT_MOTION__
+ ray->time = sd->time;
+# endif
-#ifdef __VOLUME__
- /* enter/exit volume */
- if(label & LABEL_TRANSMIT)
- kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
-#endif
+# ifdef __VOLUME__
+ /* enter/exit volume */
+ if (label & LABEL_TRANSMIT)
+ kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
+# endif
- /* branch RNG state */
- path_state_branch(state, sample, num_samples);
+ /* branch RNG state */
+ path_state_branch(state, sample, num_samples);
- /* set MIS state */
- state->min_ray_pdf = fminf(bsdf_pdf, FLT_MAX);
- state->ray_pdf = bsdf_pdf;
-#ifdef __LAMP_MIS__
- state->ray_t = 0.0f;
-#endif
+ /* set MIS state */
+ state->min_ray_pdf = fminf(bsdf_pdf, FLT_MAX);
+ state->ray_pdf = bsdf_pdf;
+# ifdef __LAMP_MIS__
+ state->ray_t = 0.0f;
+# endif
- return true;
+ return true;
}
#endif
/* path tracing: connect path directly to position on a light and add it to L */
ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg,
- ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state,
- PathRadiance *L)
+ ShaderData *sd,
+ ShaderData *emission_sd,
+ float3 throughput,
+ ccl_addr_space PathState *state,
+ PathRadiance *L)
{
- PROFILING_INIT(kg, PROFILING_CONNECT_LIGHT);
+ PROFILING_INIT(kg, PROFILING_CONNECT_LIGHT);
#ifdef __EMISSION__
- if(!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)))
- return;
-
-#ifdef __SHADOW_TRICKS__
- if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- kernel_branched_path_surface_connect_light(kg,
- sd,
- emission_sd,
- state,
- throughput,
- 1.0f,
- L,
- 1);
- return;
- }
-#endif
+ if (!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)))
+ return;
+
+# ifdef __SHADOW_TRICKS__
+ if (state->flag & PATH_RAY_SHADOW_CATCHER) {
+ kernel_branched_path_surface_connect_light(kg, sd, emission_sd, state, throughput, 1.0f, L, 1);
+ return;
+ }
+# endif
- /* sample illumination from lights to find path contribution */
- float light_u, light_v;
- path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
+ /* sample illumination from lights to find path contribution */
+ float light_u, light_v;
+ path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
+ Ray light_ray;
+ BsdfEval L_light;
+ bool is_lamp;
-#ifdef __OBJECT_MOTION__
- light_ray.time = sd->time;
-#endif
+# ifdef __OBJECT_MOTION__
+ light_ray.time = sd->time;
+# endif
- LightSample ls;
- if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
- float terminate = path_state_rng_light_termination(kg, state);
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
- }
- else {
- path_radiance_accum_total_light(L, state, throughput, &L_light);
- }
- }
- }
+ LightSample ls;
+ if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
+ float terminate = path_state_rng_light_termination(kg, state);
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
+ }
+ else {
+ path_radiance_accum_total_light(L, state, throughput, &L_light);
+ }
+ }
+ }
#endif
}
@@ -276,87 +301,87 @@ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
PathRadianceState *L_state,
ccl_addr_space Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SURFACE_BOUNCE);
-
- /* no BSDF? we can stop here */
- if(sd->flag & SD_BSDF) {
- /* sample BSDF */
- float bsdf_pdf;
- BsdfEval bsdf_eval;
- float3 bsdf_omega_in;
- differential3 bsdf_domega_in;
- float bsdf_u, bsdf_v;
- path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
- int label;
-
- label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval,
- &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
-
- if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
- return false;
-
- /* modify throughput */
- path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
-
- /* set labels */
- if(!(label & LABEL_TRANSPARENT)) {
- state->ray_pdf = bsdf_pdf;
+ PROFILING_INIT(kg, PROFILING_SURFACE_BOUNCE);
+
+ /* no BSDF? we can stop here */
+ if (sd->flag & SD_BSDF) {
+ /* sample BSDF */
+ float bsdf_pdf;
+ BsdfEval bsdf_eval;
+ float3 bsdf_omega_in;
+ differential3 bsdf_domega_in;
+ float bsdf_u, bsdf_v;
+ path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+ int label;
+
+ label = shader_bsdf_sample(
+ kg, sd, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
+
+ if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
+ return false;
+
+ /* modify throughput */
+ path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
+
+ /* set labels */
+ if (!(label & LABEL_TRANSPARENT)) {
+ state->ray_pdf = bsdf_pdf;
#ifdef __LAMP_MIS__
- state->ray_t = 0.0f;
+ state->ray_t = 0.0f;
#endif
- state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
- }
+ state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
+ }
- /* update path state */
- path_state_next(kg, state, label);
+ /* update path state */
+ path_state_next(kg, state, label);
- /* setup ray */
- ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng);
- ray->D = normalize(bsdf_omega_in);
+ /* setup ray */
+ ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT) ? -sd->Ng : sd->Ng);
+ ray->D = normalize(bsdf_omega_in);
- if(state->bounce == 0)
- ray->t -= sd->ray_length; /* clipping works through transparent */
- else
- ray->t = FLT_MAX;
+ if (state->bounce == 0)
+ ray->t -= sd->ray_length; /* clipping works through transparent */
+ else
+ ray->t = FLT_MAX;
#ifdef __RAY_DIFFERENTIALS__
- ray->dP = sd->dP;
- ray->dD = bsdf_domega_in;
+ ray->dP = sd->dP;
+ ray->dD = bsdf_domega_in;
#endif
#ifdef __VOLUME__
- /* enter/exit volume */
- if(label & LABEL_TRANSMIT)
- kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
+ /* enter/exit volume */
+ if (label & LABEL_TRANSMIT)
+ kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
#endif
- return true;
- }
+ return true;
+ }
#ifdef __VOLUME__
- else if(sd->flag & SD_HAS_ONLY_VOLUME) {
- if(!path_state_volume_next(kg, state)) {
- return false;
- }
-
- if(state->bounce == 0)
- ray->t -= sd->ray_length; /* clipping works through transparent */
- else
- ray->t = FLT_MAX;
-
- /* setup ray position, direction stays unchanged */
- ray->P = ray_offset(sd->P, -sd->Ng);
-#ifdef __RAY_DIFFERENTIALS__
- ray->dP = sd->dP;
-#endif
+ else if (sd->flag & SD_HAS_ONLY_VOLUME) {
+ if (!path_state_volume_next(kg, state)) {
+ return false;
+ }
+
+ if (state->bounce == 0)
+ ray->t -= sd->ray_length; /* clipping works through transparent */
+ else
+ ray->t = FLT_MAX;
+
+ /* setup ray position, direction stays unchanged */
+ ray->P = ray_offset(sd->P, -sd->Ng);
+# ifdef __RAY_DIFFERENTIALS__
+ ray->dP = sd->dP;
+# endif
- /* enter/exit volume */
- kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
- return true;
- }
+ /* enter/exit volume */
+ kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
+ return true;
+ }
#endif
- else {
- /* no bsdf or volume? */
- return false;
- }
+ else {
+ /* no bsdf or volume? */
+ return false;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h
index d2506fc1e7e..fea4dfc159d 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -18,269 +18,307 @@ CCL_NAMESPACE_BEGIN
#ifdef __VOLUME_SCATTER__
-ccl_device_inline void kernel_path_volume_connect_light(
- KernelGlobals *kg,
- ShaderData *sd,
- ShaderData *emission_sd,
- float3 throughput,
- ccl_addr_space PathState *state,
- PathRadiance *L)
+ccl_device_inline void kernel_path_volume_connect_light(KernelGlobals *kg,
+ ShaderData *sd,
+ ShaderData *emission_sd,
+ float3 throughput,
+ ccl_addr_space PathState *state,
+ PathRadiance *L)
{
-#ifdef __EMISSION__
- if(!kernel_data.integrator.use_direct_light)
- return;
-
- /* sample illumination from lights to find path contribution */
- float light_u, light_v;
- path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
-
- Ray light_ray;
- BsdfEval L_light;
- LightSample ls;
- bool is_lamp;
-
- /* connect to light from given point where shader has been evaluated */
- light_ray.time = sd->time;
-
- if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls))
- {
- float terminate = path_state_rng_light_termination(kg, state);
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
- }
- }
- }
-#endif /* __EMISSION__ */
+# ifdef __EMISSION__
+ if (!kernel_data.integrator.use_direct_light)
+ return;
+
+ /* sample illumination from lights to find path contribution */
+ float light_u, light_v;
+ path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ Ray light_ray;
+ BsdfEval L_light;
+ LightSample ls;
+ bool is_lamp;
+
+ /* connect to light from given point where shader has been evaluated */
+ light_ray.time = sd->time;
+
+ if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
+ float terminate = path_state_rng_light_termination(kg, state);
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
+ }
+ }
+ }
+# endif /* __EMISSION__ */
}
-#ifdef __KERNEL_GPU__
+# ifdef __KERNEL_GPU__
ccl_device_noinline
-#else
+# else
ccl_device
-#endif
-bool kernel_path_volume_bounce(
- KernelGlobals *kg,
- ShaderData *sd,
- ccl_addr_space float3 *throughput,
- ccl_addr_space PathState *state,
- PathRadianceState *L_state,
- ccl_addr_space Ray *ray)
+# endif
+ bool
+ kernel_path_volume_bounce(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space float3 *throughput,
+ ccl_addr_space PathState *state,
+ PathRadianceState *L_state,
+ ccl_addr_space Ray *ray)
{
- /* sample phase function */
- float phase_pdf;
- BsdfEval phase_eval;
- float3 phase_omega_in;
- differential3 phase_domega_in;
- float phase_u, phase_v;
- path_state_rng_2D(kg, state, PRNG_BSDF_U, &phase_u, &phase_v);
- int label;
-
- label = shader_volume_phase_sample(kg, sd, phase_u, phase_v, &phase_eval,
- &phase_omega_in, &phase_domega_in, &phase_pdf);
-
- if(phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval))
- return false;
-
- /* modify throughput */
- path_radiance_bsdf_bounce(kg, L_state, throughput, &phase_eval, phase_pdf, state->bounce, label);
-
- /* set labels */
- state->ray_pdf = phase_pdf;
-#ifdef __LAMP_MIS__
- state->ray_t = 0.0f;
-#endif
- state->min_ray_pdf = fminf(phase_pdf, state->min_ray_pdf);
-
- /* update path state */
- path_state_next(kg, state, label);
-
- /* Russian roulette termination of volume ray scattering. */
- float probability = path_state_continuation_probability(kg, state, *throughput);
-
- if(probability == 0.0f) {
- return false;
- }
- else if(probability != 1.0f) {
- /* Use dimension from the previous bounce, has not been used yet. */
- float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE - PRNG_BOUNCE_NUM);
-
- if(terminate >= probability) {
- return false;
- }
-
- *throughput /= probability;
- }
-
- /* setup ray */
- ray->P = sd->P;
- ray->D = phase_omega_in;
- ray->t = FLT_MAX;
-
-#ifdef __RAY_DIFFERENTIALS__
- ray->dP = sd->dP;
- ray->dD = phase_domega_in;
-#endif
-
- return true;
+ /* sample phase function */
+ float phase_pdf;
+ BsdfEval phase_eval;
+ float3 phase_omega_in;
+ differential3 phase_domega_in;
+ float phase_u, phase_v;
+ path_state_rng_2D(kg, state, PRNG_BSDF_U, &phase_u, &phase_v);
+ int label;
+
+ label = shader_volume_phase_sample(
+ kg, sd, phase_u, phase_v, &phase_eval, &phase_omega_in, &phase_domega_in, &phase_pdf);
+
+ if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval))
+ return false;
+
+ /* modify throughput */
+ path_radiance_bsdf_bounce(kg, L_state, throughput, &phase_eval, phase_pdf, state->bounce, label);
+
+ /* set labels */
+ state->ray_pdf = phase_pdf;
+# ifdef __LAMP_MIS__
+ state->ray_t = 0.0f;
+# endif
+ state->min_ray_pdf = fminf(phase_pdf, state->min_ray_pdf);
+
+ /* update path state */
+ path_state_next(kg, state, label);
+
+ /* Russian roulette termination of volume ray scattering. */
+ float probability = path_state_continuation_probability(kg, state, *throughput);
+
+ if (probability == 0.0f) {
+ return false;
+ }
+ else if (probability != 1.0f) {
+ /* Use dimension from the previous bounce, has not been used yet. */
+ float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE - PRNG_BOUNCE_NUM);
+
+ if (terminate >= probability) {
+ return false;
+ }
+
+ *throughput /= probability;
+ }
+
+ /* setup ray */
+ ray->P = sd->P;
+ ray->D = phase_omega_in;
+ ray->t = FLT_MAX;
+
+# ifdef __RAY_DIFFERENTIALS__
+ ray->dP = sd->dP;
+ ray->dD = phase_domega_in;
+# endif
+
+ return true;
}
-#ifndef __SPLIT_KERNEL__
-ccl_device void kernel_branched_path_volume_connect_light(
- KernelGlobals *kg,
- ShaderData *sd,
- ShaderData *emission_sd,
- float3 throughput,
- ccl_addr_space PathState *state,
- PathRadiance *L,
- bool sample_all_lights,
- Ray *ray,
- const VolumeSegment *segment)
+# ifndef __SPLIT_KERNEL__
+ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg,
+ ShaderData *sd,
+ ShaderData *emission_sd,
+ float3 throughput,
+ ccl_addr_space PathState *state,
+ PathRadiance *L,
+ bool sample_all_lights,
+ Ray *ray,
+ const VolumeSegment *segment)
{
-#ifdef __EMISSION__
- if(!kernel_data.integrator.use_direct_light)
- return;
-
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
-
- light_ray.time = sd->time;
-
- if(sample_all_lights) {
- /* lamp sampling */
- for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
- if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
- continue;
-
- int num_samples = light_select_num_samples(kg, i);
- float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights);
- uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
-
- for(int j = 0; j < num_samples; j++) {
- /* sample random position on given light */
- float light_u, light_v;
- path_branched_rng_2D(kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
-
- LightSample ls;
- lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls);
-
- float3 tp = throughput;
-
- /* sample position on volume segment */
- float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
- float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
-
- VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
- state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
-
- /* todo: split up light_sample so we don't have to call it again with new position */
- if(result == VOLUME_PATH_SCATTERED &&
- lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
- if(kernel_data.integrator.pdf_triangles != 0.0f)
- ls.pdf *= 2.0f;
-
- float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples);
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, tp*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
- }
- }
- }
- }
- }
-
- /* mesh light sampling */
- if(kernel_data.integrator.pdf_triangles != 0.0f) {
- int num_samples = kernel_data.integrator.mesh_light_samples;
- float num_samples_inv = 1.0f/num_samples;
-
- for(int j = 0; j < num_samples; j++) {
- /* sample random position on random triangle */
- float light_u, light_v;
- path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
-
- /* only sample triangle lights */
- if(kernel_data.integrator.num_all_lights)
- light_u = 0.5f*light_u;
-
- LightSample ls;
- light_sample(kg, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
-
- float3 tp = throughput;
-
- /* sample position on volume segment */
- float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
- float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
-
- VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
- state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
-
- /* todo: split up light_sample so we don't have to call it again with new position */
- if(result == VOLUME_PATH_SCATTERED &&
- light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
- if(kernel_data.integrator.num_all_lights)
- ls.pdf *= 2.0f;
-
- float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples);
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, tp*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
- }
- }
- }
- }
- }
- }
- else {
- /* sample random position on random light */
- float light_u, light_v;
- path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
-
- LightSample ls;
- light_sample(kg, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
-
- float3 tp = throughput;
-
- /* sample position on volume segment */
- float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
- float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
-
- VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
- state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
-
- /* todo: split up light_sample so we don't have to call it again with new position */
- if(result == VOLUME_PATH_SCATTERED &&
- light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
- /* sample random light */
- float terminate = path_state_rng_light_termination(kg, state);
- if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, state, tp, &L_light, shadow, 1.0f, is_lamp);
- }
- }
- }
- }
-#endif /* __EMISSION__ */
+# ifdef __EMISSION__
+ if (!kernel_data.integrator.use_direct_light)
+ return;
+
+ Ray light_ray;
+ BsdfEval L_light;
+ bool is_lamp;
+
+ light_ray.time = sd->time;
+
+ if (sample_all_lights) {
+ /* lamp sampling */
+ for (int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+ if (UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
+ continue;
+
+ int num_samples = light_select_num_samples(kg, i);
+ float num_samples_inv = 1.0f / (num_samples * kernel_data.integrator.num_all_lights);
+ uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
+
+ for (int j = 0; j < num_samples; j++) {
+ /* sample random position on given light */
+ float light_u, light_v;
+ path_branched_rng_2D(
+ kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+
+ LightSample ls;
+ lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls);
+
+ float3 tp = throughput;
+
+ /* sample position on volume segment */
+ float rphase = path_branched_rng_1D(
+ kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
+ float rscatter = path_branched_rng_1D(
+ kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
+
+ VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
+ state,
+ ray,
+ sd,
+ &tp,
+ rphase,
+ rscatter,
+ segment,
+ (ls.t != FLT_MAX) ? &ls.P :
+ NULL,
+ false);
+
+ /* todo: split up light_sample so we don't have to call it again with new position */
+ if (result == VOLUME_PATH_SCATTERED &&
+ lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
+ if (kernel_data.integrator.pdf_triangles != 0.0f)
+ ls.pdf *= 2.0f;
+
+ float terminate = path_branched_rng_light_termination(
+ kg, state->rng_hash, state, j, num_samples);
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(
+ L, state, tp * num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
+ }
+ }
+ }
+ }
+ }
+
+ /* mesh light sampling */
+ if (kernel_data.integrator.pdf_triangles != 0.0f) {
+ int num_samples = kernel_data.integrator.mesh_light_samples;
+ float num_samples_inv = 1.0f / num_samples;
+
+ for (int j = 0; j < num_samples; j++) {
+ /* sample random position on random triangle */
+ float light_u, light_v;
+ path_branched_rng_2D(
+ kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+
+ /* only sample triangle lights */
+ if (kernel_data.integrator.num_all_lights)
+ light_u = 0.5f * light_u;
+
+ LightSample ls;
+ light_sample(kg, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
+
+ float3 tp = throughput;
+
+ /* sample position on volume segment */
+ float rphase = path_branched_rng_1D(
+ kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
+ float rscatter = path_branched_rng_1D(
+ kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
+
+ VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
+ state,
+ ray,
+ sd,
+ &tp,
+ rphase,
+ rscatter,
+ segment,
+ (ls.t != FLT_MAX) ? &ls.P :
+ NULL,
+ false);
+
+ /* todo: split up light_sample so we don't have to call it again with new position */
+ if (result == VOLUME_PATH_SCATTERED &&
+ light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
+ if (kernel_data.integrator.num_all_lights)
+ ls.pdf *= 2.0f;
+
+ float terminate = path_branched_rng_light_termination(
+ kg, state->rng_hash, state, j, num_samples);
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(
+ L, state, tp * num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ /* sample random position on random light */
+ float light_u, light_v;
+ path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ LightSample ls;
+ light_sample(kg, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
+
+ float3 tp = throughput;
+
+ /* sample position on volume segment */
+ float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
+ float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
+
+ VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
+ state,
+ ray,
+ sd,
+ &tp,
+ rphase,
+ rscatter,
+ segment,
+ (ls.t != FLT_MAX) ? &ls.P :
+ NULL,
+ false);
+
+ /* todo: split up light_sample so we don't have to call it again with new position */
+ if (result == VOLUME_PATH_SCATTERED &&
+ light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
+ /* sample random light */
+ float terminate = path_state_rng_light_termination(kg, state);
+ if (direct_emission(
+ kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, state, tp, &L_light, shadow, 1.0f, is_lamp);
+ }
+ }
+ }
+ }
+# endif /* __EMISSION__ */
}
-#endif /* __SPLIT_KERNEL__ */
+# endif /* __SPLIT_KERNEL__ */
-#endif /* __VOLUME_SCATTER__ */
+#endif /* __VOLUME_SCATTER__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_profiling.h b/intern/cycles/kernel/kernel_profiling.h
index a46d6376473..780830879d8 100644
--- a/intern/cycles/kernel/kernel_profiling.h
+++ b/intern/cycles/kernel/kernel_profiling.h
@@ -26,15 +26,21 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_CPU__
# define PROFILING_INIT(kg, event) ProfilingHelper profiling_helper(&kg->profiler, event)
# define PROFILING_EVENT(event) profiling_helper.set_event(event)
-# define PROFILING_SHADER(shader) if((shader) != SHADER_NONE) { profiling_helper.set_shader((shader) & SHADER_MASK); }
-# define PROFILING_OBJECT(object) if((object) != PRIM_NONE) { profiling_helper.set_object(object); }
+# define PROFILING_SHADER(shader) \
+ if ((shader) != SHADER_NONE) { \
+ profiling_helper.set_shader((shader)&SHADER_MASK); \
+ }
+# define PROFILING_OBJECT(object) \
+ if ((object) != PRIM_NONE) { \
+ profiling_helper.set_object(object); \
+ }
#else
# define PROFILING_INIT(kg, event)
# define PROFILING_EVENT(event)
# define PROFILING_SHADER(shader)
# define PROFILING_OBJECT(object)
-#endif /* __KERNEL_CPU__ */
+#endif /* __KERNEL_CPU__ */
CCL_NAMESPACE_END
-#endif /* __KERNEL_PROFILING_H__ */
+#endif /* __KERNEL_PROFILING_H__ */
diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h
index 7bad89c831c..f74ced45fd5 100644
--- a/intern/cycles/kernel/kernel_projection.h
+++ b/intern/cycles/kernel/kernel_projection.h
@@ -39,233 +39,223 @@ CCL_NAMESPACE_BEGIN
ccl_device float2 direction_to_spherical(float3 dir)
{
- float theta = safe_acosf(dir.z);
- float phi = atan2f(dir.x, dir.y);
+ float theta = safe_acosf(dir.z);
+ float phi = atan2f(dir.x, dir.y);
- return make_float2(theta, phi);
+ return make_float2(theta, phi);
}
ccl_device float3 spherical_to_direction(float theta, float phi)
{
- float sin_theta = sinf(theta);
- return make_float3(sin_theta*cosf(phi),
- sin_theta*sinf(phi),
- cosf(theta));
+ float sin_theta = sinf(theta);
+ return make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cosf(theta));
}
/* Equirectangular coordinates <-> Cartesian direction */
ccl_device float2 direction_to_equirectangular_range(float3 dir, float4 range)
{
- if(is_zero(dir))
- return make_float2(0.0f, 0.0f);
+ if (is_zero(dir))
+ return make_float2(0.0f, 0.0f);
- float u = (atan2f(dir.y, dir.x) - range.y) / range.x;
- float v = (acosf(dir.z / len(dir)) - range.w) / range.z;
+ float u = (atan2f(dir.y, dir.x) - range.y) / range.x;
+ float v = (acosf(dir.z / len(dir)) - range.w) / range.z;
- return make_float2(u, v);
+ return make_float2(u, v);
}
ccl_device float3 equirectangular_range_to_direction(float u, float v, float4 range)
{
- float phi = range.x*u + range.y;
- float theta = range.z*v + range.w;
- float sin_theta = sinf(theta);
- return make_float3(sin_theta*cosf(phi),
- sin_theta*sinf(phi),
- cosf(theta));
+ float phi = range.x * u + range.y;
+ float theta = range.z * v + range.w;
+ float sin_theta = sinf(theta);
+ return make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cosf(theta));
}
ccl_device float2 direction_to_equirectangular(float3 dir)
{
- return direction_to_equirectangular_range(dir, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F));
+ return direction_to_equirectangular_range(dir, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F));
}
ccl_device float3 equirectangular_to_direction(float u, float v)
{
- return equirectangular_range_to_direction(u, v, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F));
+ return equirectangular_range_to_direction(u, v, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F));
}
/* Fisheye <-> Cartesian direction */
ccl_device float2 direction_to_fisheye(float3 dir, float fov)
{
- float r = atan2f(sqrtf(dir.y*dir.y + dir.z*dir.z), dir.x) / fov;
- float phi = atan2f(dir.z, dir.y);
+ float r = atan2f(sqrtf(dir.y * dir.y + dir.z * dir.z), dir.x) / fov;
+ float phi = atan2f(dir.z, dir.y);
- float u = r * cosf(phi) + 0.5f;
- float v = r * sinf(phi) + 0.5f;
+ float u = r * cosf(phi) + 0.5f;
+ float v = r * sinf(phi) + 0.5f;
- return make_float2(u, v);
+ return make_float2(u, v);
}
ccl_device float3 fisheye_to_direction(float u, float v, float fov)
{
- u = (u - 0.5f) * 2.0f;
- v = (v - 0.5f) * 2.0f;
+ u = (u - 0.5f) * 2.0f;
+ v = (v - 0.5f) * 2.0f;
- float r = sqrtf(u*u + v*v);
+ float r = sqrtf(u * u + v * v);
- if(r > 1.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (r > 1.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
- float phi = safe_acosf((r != 0.0f)? u/r: 0.0f);
- float theta = r * fov * 0.5f;
+ float phi = safe_acosf((r != 0.0f) ? u / r : 0.0f);
+ float theta = r * fov * 0.5f;
- if(v < 0.0f) phi = -phi;
+ if (v < 0.0f)
+ phi = -phi;
- return make_float3(
- cosf(theta),
- -cosf(phi)*sinf(theta),
- sinf(phi)*sinf(theta)
- );
+ return make_float3(cosf(theta), -cosf(phi) * sinf(theta), sinf(phi) * sinf(theta));
}
ccl_device float2 direction_to_fisheye_equisolid(float3 dir, float lens, float width, float height)
{
- float theta = safe_acosf(dir.x);
- float r = 2.0f * lens * sinf(theta * 0.5f);
- float phi = atan2f(dir.z, dir.y);
+ float theta = safe_acosf(dir.x);
+ float r = 2.0f * lens * sinf(theta * 0.5f);
+ float phi = atan2f(dir.z, dir.y);
- float u = r * cosf(phi) / width + 0.5f;
- float v = r * sinf(phi) / height + 0.5f;
+ float u = r * cosf(phi) / width + 0.5f;
+ float v = r * sinf(phi) / height + 0.5f;
- return make_float2(u, v);
+ return make_float2(u, v);
}
-ccl_device_inline float3 fisheye_equisolid_to_direction(float u, float v,
- float lens,
- float fov,
- float width, float height)
+ccl_device_inline float3
+fisheye_equisolid_to_direction(float u, float v, float lens, float fov, float width, float height)
{
- u = (u - 0.5f) * width;
- v = (v - 0.5f) * height;
+ u = (u - 0.5f) * width;
+ v = (v - 0.5f) * height;
- float rmax = 2.0f * lens * sinf(fov * 0.25f);
- float r = sqrtf(u*u + v*v);
+ float rmax = 2.0f * lens * sinf(fov * 0.25f);
+ float r = sqrtf(u * u + v * v);
- if(r > rmax)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (r > rmax)
+ return make_float3(0.0f, 0.0f, 0.0f);
- float phi = safe_acosf((r != 0.0f)? u/r: 0.0f);
- float theta = 2.0f * asinf(r/(2.0f * lens));
+ float phi = safe_acosf((r != 0.0f) ? u / r : 0.0f);
+ float theta = 2.0f * asinf(r / (2.0f * lens));
- if(v < 0.0f) phi = -phi;
+ if (v < 0.0f)
+ phi = -phi;
- return make_float3(
- cosf(theta),
- -cosf(phi)*sinf(theta),
- sinf(phi)*sinf(theta)
- );
+ return make_float3(cosf(theta), -cosf(phi) * sinf(theta), sinf(phi) * sinf(theta));
}
/* Mirror Ball <-> Cartesion direction */
ccl_device float3 mirrorball_to_direction(float u, float v)
{
- /* point on sphere */
- float3 dir;
+ /* point on sphere */
+ float3 dir;
- dir.x = 2.0f*u - 1.0f;
- dir.z = 2.0f*v - 1.0f;
+ dir.x = 2.0f * u - 1.0f;
+ dir.z = 2.0f * v - 1.0f;
- if(dir.x*dir.x + dir.z*dir.z > 1.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ if (dir.x * dir.x + dir.z * dir.z > 1.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
- dir.y = -sqrtf(max(1.0f - dir.x*dir.x - dir.z*dir.z, 0.0f));
+ dir.y = -sqrtf(max(1.0f - dir.x * dir.x - dir.z * dir.z, 0.0f));
- /* reflection */
- float3 I = make_float3(0.0f, -1.0f, 0.0f);
+ /* reflection */
+ float3 I = make_float3(0.0f, -1.0f, 0.0f);
- return 2.0f*dot(dir, I)*dir - I;
+ return 2.0f * dot(dir, I) * dir - I;
}
ccl_device float2 direction_to_mirrorball(float3 dir)
{
- /* inverse of mirrorball_to_direction */
- dir.y -= 1.0f;
+ /* inverse of mirrorball_to_direction */
+ dir.y -= 1.0f;
- float div = 2.0f*sqrtf(max(-0.5f*dir.y, 0.0f));
- if(div > 0.0f)
- dir /= div;
+ float div = 2.0f * sqrtf(max(-0.5f * dir.y, 0.0f));
+ if (div > 0.0f)
+ dir /= div;
- float u = 0.5f*(dir.x + 1.0f);
- float v = 0.5f*(dir.z + 1.0f);
+ float u = 0.5f * (dir.x + 1.0f);
+ float v = 0.5f * (dir.z + 1.0f);
- return make_float2(u, v);
+ return make_float2(u, v);
}
ccl_device_inline float3 panorama_to_direction(ccl_constant KernelCamera *cam, float u, float v)
{
- switch(cam->panorama_type) {
- case PANORAMA_EQUIRECTANGULAR:
- return equirectangular_range_to_direction(u, v, cam->equirectangular_range);
- case PANORAMA_MIRRORBALL:
- return mirrorball_to_direction(u, v);
- case PANORAMA_FISHEYE_EQUIDISTANT:
- return fisheye_to_direction(u, v, cam->fisheye_fov);
- case PANORAMA_FISHEYE_EQUISOLID:
- default:
- return fisheye_equisolid_to_direction(u, v, cam->fisheye_lens,
- cam->fisheye_fov, cam->sensorwidth, cam->sensorheight);
- }
+ switch (cam->panorama_type) {
+ case PANORAMA_EQUIRECTANGULAR:
+ return equirectangular_range_to_direction(u, v, cam->equirectangular_range);
+ case PANORAMA_MIRRORBALL:
+ return mirrorball_to_direction(u, v);
+ case PANORAMA_FISHEYE_EQUIDISTANT:
+ return fisheye_to_direction(u, v, cam->fisheye_fov);
+ case PANORAMA_FISHEYE_EQUISOLID:
+ default:
+ return fisheye_equisolid_to_direction(
+ u, v, cam->fisheye_lens, cam->fisheye_fov, cam->sensorwidth, cam->sensorheight);
+ }
}
ccl_device_inline float2 direction_to_panorama(ccl_constant KernelCamera *cam, float3 dir)
{
- switch(cam->panorama_type) {
- case PANORAMA_EQUIRECTANGULAR:
- return direction_to_equirectangular_range(dir, cam->equirectangular_range);
- case PANORAMA_MIRRORBALL:
- return direction_to_mirrorball(dir);
- case PANORAMA_FISHEYE_EQUIDISTANT:
- return direction_to_fisheye(dir, cam->fisheye_fov);
- case PANORAMA_FISHEYE_EQUISOLID:
- default:
- return direction_to_fisheye_equisolid(dir, cam->fisheye_lens,
- cam->sensorwidth, cam->sensorheight);
- }
+ switch (cam->panorama_type) {
+ case PANORAMA_EQUIRECTANGULAR:
+ return direction_to_equirectangular_range(dir, cam->equirectangular_range);
+ case PANORAMA_MIRRORBALL:
+ return direction_to_mirrorball(dir);
+ case PANORAMA_FISHEYE_EQUIDISTANT:
+ return direction_to_fisheye(dir, cam->fisheye_fov);
+ case PANORAMA_FISHEYE_EQUISOLID:
+ default:
+ return direction_to_fisheye_equisolid(
+ dir, cam->fisheye_lens, cam->sensorwidth, cam->sensorheight);
+ }
}
-ccl_device_inline void spherical_stereo_transform(ccl_constant KernelCamera *cam, float3 *P, float3 *D)
+ccl_device_inline void spherical_stereo_transform(ccl_constant KernelCamera *cam,
+ float3 *P,
+ float3 *D)
{
- float interocular_offset = cam->interocular_offset;
-
- /* Interocular offset of zero means either non stereo, or stereo without
- * spherical stereo. */
- kernel_assert(interocular_offset != 0.0f);
-
- if(cam->pole_merge_angle_to > 0.0f) {
- const float pole_merge_angle_from = cam->pole_merge_angle_from,
- pole_merge_angle_to = cam->pole_merge_angle_to;
- float altitude = fabsf(safe_asinf((*D).z));
- if(altitude > pole_merge_angle_to) {
- interocular_offset = 0.0f;
- }
- else if(altitude > pole_merge_angle_from) {
- float fac = (altitude - pole_merge_angle_from) / (pole_merge_angle_to - pole_merge_angle_from);
- float fade = cosf(fac * M_PI_2_F);
- interocular_offset *= fade;
- }
- }
-
- float3 up = make_float3(0.0f, 0.0f, 1.0f);
- float3 side = normalize(cross(*D, up));
- float3 stereo_offset = side * interocular_offset;
-
- *P += stereo_offset;
-
- /* Convergence distance is FLT_MAX in the case of parallel convergence mode,
- * no need to modify direction in this case either. */
- const float convergence_distance = cam->convergence_distance;
-
- if(convergence_distance != FLT_MAX)
- {
- float3 screen_offset = convergence_distance * (*D);
- *D = normalize(screen_offset - stereo_offset);
- }
+ float interocular_offset = cam->interocular_offset;
+
+ /* Interocular offset of zero means either non stereo, or stereo without
+ * spherical stereo. */
+ kernel_assert(interocular_offset != 0.0f);
+
+ if (cam->pole_merge_angle_to > 0.0f) {
+ const float pole_merge_angle_from = cam->pole_merge_angle_from,
+ pole_merge_angle_to = cam->pole_merge_angle_to;
+ float altitude = fabsf(safe_asinf((*D).z));
+ if (altitude > pole_merge_angle_to) {
+ interocular_offset = 0.0f;
+ }
+ else if (altitude > pole_merge_angle_from) {
+ float fac = (altitude - pole_merge_angle_from) /
+ (pole_merge_angle_to - pole_merge_angle_from);
+ float fade = cosf(fac * M_PI_2_F);
+ interocular_offset *= fade;
+ }
+ }
+
+ float3 up = make_float3(0.0f, 0.0f, 1.0f);
+ float3 side = normalize(cross(*D, up));
+ float3 stereo_offset = side * interocular_offset;
+
+ *P += stereo_offset;
+
+ /* Convergence distance is FLT_MAX in the case of parallel convergence mode,
+ * no need to modify direction in this case either. */
+ const float convergence_distance = cam->convergence_distance;
+
+ if (convergence_distance != FLT_MAX) {
+ float3 screen_offset = convergence_distance * (*D);
+ *D = normalize(screen_offset - stereo_offset);
+ }
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_PROJECTION_CL__ */
+#endif /* __KERNEL_PROJECTION_CL__ */
diff --git a/intern/cycles/kernel/kernel_queues.h b/intern/cycles/kernel/kernel_queues.h
index de8cc4a0cef..91a39fc1465 100644
--- a/intern/cycles/kernel/kernel_queues.h
+++ b/intern/cycles/kernel/kernel_queues.h
@@ -23,24 +23,24 @@ CCL_NAMESPACE_BEGIN
* Queue utility functions for split kernel
*/
#ifdef __KERNEL_OPENCL__
-#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
-#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
+# pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
+# pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#endif
/*
* Enqueue ray index into the queue
*/
ccl_device void enqueue_ray_index(
- int ray_index, /* Ray index to be enqueued. */
- int queue_number, /* Queue in which the ray index should be enqueued. */
- ccl_global int *queues, /* Buffer of all queues. */
- int queue_size, /* Size of each queue. */
- ccl_global int *queue_index) /* Array of size num_queues; Used for atomic increment. */
+ int ray_index, /* Ray index to be enqueued. */
+ int queue_number, /* Queue in which the ray index should be enqueued. */
+ ccl_global int *queues, /* Buffer of all queues. */
+ int queue_size, /* Size of each queue. */
+ ccl_global int *queue_index) /* Array of size num_queues; Used for atomic increment. */
{
- /* This thread's queue index. */
- int my_queue_index = atomic_fetch_and_inc_uint32((ccl_global uint*)&queue_index[queue_number])
- + (queue_number * queue_size);
- queues[my_queue_index] = ray_index;
+ /* This thread's queue index. */
+ int my_queue_index = atomic_fetch_and_inc_uint32((ccl_global uint *)&queue_index[queue_number]) +
+ (queue_number * queue_size);
+ queues[my_queue_index] = ray_index;
}
/*
@@ -51,96 +51,95 @@ ccl_device void enqueue_ray_index(
* is no more ray to allocate to other threads.
*/
ccl_device int get_ray_index(
- KernelGlobals *kg,
- int thread_index, /* Global thread index. */
- int queue_number, /* Queue to operate on. */
- ccl_global int *queues, /* Buffer of all queues. */
- int queuesize, /* Size of a queue. */
- int empty_queue) /* Empty the queue slot as soon as we fetch the ray index. */
+ KernelGlobals *kg,
+ int thread_index, /* Global thread index. */
+ int queue_number, /* Queue to operate on. */
+ ccl_global int *queues, /* Buffer of all queues. */
+ int queuesize, /* Size of a queue. */
+ int empty_queue) /* Empty the queue slot as soon as we fetch the ray index. */
{
- int ray_index = queues[queue_number * queuesize + thread_index];
- if(empty_queue && ray_index != QUEUE_EMPTY_SLOT) {
- queues[queue_number * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
- }
- return ray_index;
+ int ray_index = queues[queue_number * queuesize + thread_index];
+ if (empty_queue && ray_index != QUEUE_EMPTY_SLOT) {
+ queues[queue_number * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
+ }
+ return ray_index;
}
/* The following functions are to realize Local memory variant of enqueue ray index function. */
/* All threads should call this function. */
ccl_device void enqueue_ray_index_local(
- int ray_index, /* Ray index to enqueue. */
- int queue_number, /* Queue in which to enqueue ray index. */
- char enqueue_flag, /* True for threads whose ray index has to be enqueued. */
- int queuesize, /* queue size. */
- ccl_local_param unsigned int *local_queue_atomics, /* To to local queue atomics. */
- ccl_global int *Queue_data, /* Queues. */
- ccl_global int *Queue_index) /* To do global queue atomics. */
+ int ray_index, /* Ray index to enqueue. */
+ int queue_number, /* Queue in which to enqueue ray index. */
+ char enqueue_flag, /* True for threads whose ray index has to be enqueued. */
+ int queuesize, /* queue size. */
+ ccl_local_param unsigned int *local_queue_atomics, /* To to local queue atomics. */
+ ccl_global int *Queue_data, /* Queues. */
+ ccl_global int *Queue_index) /* To do global queue atomics. */
{
- int lidx = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
-
- /* Get local queue id .*/
- unsigned int lqidx;
- if(enqueue_flag) {
- lqidx = atomic_fetch_and_inc_uint32(local_queue_atomics);
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- /* Get global queue offset. */
- if(lidx == 0) {
- *local_queue_atomics = atomic_fetch_and_add_uint32((ccl_global uint*)&Queue_index[queue_number],
- *local_queue_atomics);
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- /* Get global queue index and enqueue ray. */
- if(enqueue_flag) {
- unsigned int my_gqidx = queue_number * queuesize + (*local_queue_atomics) + lqidx;
- Queue_data[my_gqidx] = ray_index;
- }
+ int lidx = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
+
+ /* Get local queue id .*/
+ unsigned int lqidx;
+ if (enqueue_flag) {
+ lqidx = atomic_fetch_and_inc_uint32(local_queue_atomics);
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ /* Get global queue offset. */
+ if (lidx == 0) {
+ *local_queue_atomics = atomic_fetch_and_add_uint32(
+ (ccl_global uint *)&Queue_index[queue_number], *local_queue_atomics);
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ /* Get global queue index and enqueue ray. */
+ if (enqueue_flag) {
+ unsigned int my_gqidx = queue_number * queuesize + (*local_queue_atomics) + lqidx;
+ Queue_data[my_gqidx] = ray_index;
+ }
}
ccl_device unsigned int get_local_queue_index(
- int queue_number, /* Queue in which to enqueue the ray; -1 if no queue */
- ccl_local_param unsigned int *local_queue_atomics)
+ int queue_number, /* Queue in which to enqueue the ray; -1 if no queue */
+ ccl_local_param unsigned int *local_queue_atomics)
{
- int my_lqidx = atomic_fetch_and_inc_uint32(&local_queue_atomics[queue_number]);
- return my_lqidx;
+ int my_lqidx = atomic_fetch_and_inc_uint32(&local_queue_atomics[queue_number]);
+ return my_lqidx;
}
ccl_device unsigned int get_global_per_queue_offset(
- int queue_number,
- ccl_local_param unsigned int *local_queue_atomics,
- ccl_global int* global_queue_atomics)
+ int queue_number,
+ ccl_local_param unsigned int *local_queue_atomics,
+ ccl_global int *global_queue_atomics)
{
- unsigned int queue_offset = atomic_fetch_and_add_uint32((ccl_global uint*)&global_queue_atomics[queue_number],
- local_queue_atomics[queue_number]);
- return queue_offset;
+ unsigned int queue_offset = atomic_fetch_and_add_uint32(
+ (ccl_global uint *)&global_queue_atomics[queue_number], local_queue_atomics[queue_number]);
+ return queue_offset;
}
ccl_device unsigned int get_global_queue_index(
int queue_number,
int queuesize,
unsigned int lqidx,
- ccl_local_param unsigned int * global_per_queue_offset)
+ ccl_local_param unsigned int *global_per_queue_offset)
{
- int my_gqidx = queuesize * queue_number + lqidx + global_per_queue_offset[queue_number];
- return my_gqidx;
+ int my_gqidx = queuesize * queue_number + lqidx + global_per_queue_offset[queue_number];
+ return my_gqidx;
}
-ccl_device int dequeue_ray_index(
- int queue_number,
- ccl_global int *queues,
- int queue_size,
- ccl_global int *queue_index)
+ccl_device int dequeue_ray_index(int queue_number,
+ ccl_global int *queues,
+ int queue_size,
+ ccl_global int *queue_index)
{
- int index = atomic_fetch_and_dec_uint32((ccl_global uint*)&queue_index[queue_number])-1;
+ int index = atomic_fetch_and_dec_uint32((ccl_global uint *)&queue_index[queue_number]) - 1;
- if(index < 0) {
- return QUEUE_EMPTY_SLOT;
- }
+ if (index < 0) {
+ return QUEUE_EMPTY_SLOT;
+ }
- return queues[index + queue_number * queue_size];
+ return queues[index + queue_number * queue_size];
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index 61ddf4a4f81..6779c1f7160 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -23,7 +23,6 @@ CCL_NAMESPACE_BEGIN
* this single threaded on a CPU for repeatable results. */
//#define __DEBUG_CORRELATION__
-
/* High Dimensional Sobol.
*
* Multidimensional sobol with generator matrices. Dimension 0 and 1 are equal
@@ -36,136 +35,138 @@ CCL_NAMESPACE_BEGIN
* progressive pattern that doesn't suffer from this problem, because even
* with this offset some dimensions are quite poor.
*/
-#define SOBOL_SKIP 64
+# define SOBOL_SKIP 64
ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension)
{
- uint result = 0;
- uint i = index + SOBOL_SKIP;
- for(uint j = 0; i; i >>= 1, j++) {
- if(i & 1) {
- result ^= kernel_tex_fetch(__sobol_directions, 32*dimension + j);
- }
- }
- return result;
+ uint result = 0;
+ uint i = index + SOBOL_SKIP;
+ for (uint j = 0; i; i >>= 1, j++) {
+ if (i & 1) {
+ result ^= kernel_tex_fetch(__sobol_directions, 32 * dimension + j);
+ }
+ }
+ return result;
}
-#endif /* __SOBOL__ */
-
+#endif /* __SOBOL__ */
-ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
- uint rng_hash,
- int sample, int num_samples,
- int dimension)
+ccl_device_forceinline float path_rng_1D(
+ KernelGlobals *kg, uint rng_hash, int sample, int num_samples, int dimension)
{
#ifdef __DEBUG_CORRELATION__
- return (float)drand48();
+ return (float)drand48();
#endif
#ifdef __CMJ__
# ifdef __SOBOL__
- if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
+ if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
# endif
- {
- /* Correlated multi-jitter. */
- int p = rng_hash + dimension;
- return cmj_sample_1D(sample, num_samples, p);
- }
+ {
+ /* Correlated multi-jitter. */
+ int p = rng_hash + dimension;
+ return cmj_sample_1D(sample, num_samples, p);
+ }
#endif
#ifdef __SOBOL__
- /* Sobol sequence value using direction vectors. */
- uint result = sobol_dimension(kg, sample, dimension);
- float r = (float)result * (1.0f/(float)0xFFFFFFFF);
+ /* Sobol sequence value using direction vectors. */
+ uint result = sobol_dimension(kg, sample, dimension);
+ float r = (float)result * (1.0f / (float)0xFFFFFFFF);
- /* Cranly-Patterson rotation using rng seed */
- float shift;
+ /* Cranly-Patterson rotation using rng seed */
+ float shift;
- /* Hash rng with dimension to solve correlation issues.
- * See T38710, T50116.
- */
- uint tmp_rng = cmj_hash_simple(dimension, rng_hash);
- shift = tmp_rng * (1.0f/(float)0xFFFFFFFF);
+ /* Hash rng with dimension to solve correlation issues.
+ * See T38710, T50116.
+ */
+ uint tmp_rng = cmj_hash_simple(dimension, rng_hash);
+ shift = tmp_rng * (1.0f / (float)0xFFFFFFFF);
- return r + shift - floorf(r + shift);
+ return r + shift - floorf(r + shift);
#endif
}
ccl_device_forceinline void path_rng_2D(KernelGlobals *kg,
uint rng_hash,
- int sample, int num_samples,
+ int sample,
+ int num_samples,
int dimension,
- float *fx, float *fy)
+ float *fx,
+ float *fy)
{
#ifdef __DEBUG_CORRELATION__
- *fx = (float)drand48();
- *fy = (float)drand48();
- return;
+ *fx = (float)drand48();
+ *fy = (float)drand48();
+ return;
#endif
#ifdef __CMJ__
# ifdef __SOBOL__
- if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
+ if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
# endif
- {
- /* Correlated multi-jitter. */
- int p = rng_hash + dimension;
- cmj_sample_2D(sample, num_samples, p, fx, fy);
- return;
- }
+ {
+ /* Correlated multi-jitter. */
+ int p = rng_hash + dimension;
+ cmj_sample_2D(sample, num_samples, p, fx, fy);
+ return;
+ }
#endif
#ifdef __SOBOL__
- /* Sobol. */
- *fx = path_rng_1D(kg, rng_hash, sample, num_samples, dimension);
- *fy = path_rng_1D(kg, rng_hash, sample, num_samples, dimension + 1);
+ /* Sobol. */
+ *fx = path_rng_1D(kg, rng_hash, sample, num_samples, dimension);
+ *fy = path_rng_1D(kg, rng_hash, sample, num_samples, dimension + 1);
#endif
}
ccl_device_inline void path_rng_init(KernelGlobals *kg,
- int sample, int num_samples,
+ int sample,
+ int num_samples,
uint *rng_hash,
- int x, int y,
- float *fx, float *fy)
+ int x,
+ int y,
+ float *fx,
+ float *fy)
{
- /* load state */
- *rng_hash = hash_int_2d(x, y);
- *rng_hash ^= kernel_data.integrator.seed;
+ /* load state */
+ *rng_hash = hash_int_2d(x, y);
+ *rng_hash ^= kernel_data.integrator.seed;
#ifdef __DEBUG_CORRELATION__
- srand48(*rng_hash + sample);
+ srand48(*rng_hash + sample);
#endif
- if(sample == 0) {
- *fx = 0.5f;
- *fy = 0.5f;
- }
- else {
- path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_FILTER_U, fx, fy);
- }
+ if (sample == 0) {
+ *fx = 0.5f;
+ *fy = 0.5f;
+ }
+ else {
+ path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_FILTER_U, fx, fy);
+ }
}
/* Linear Congruential Generator */
ccl_device uint lcg_step_uint(uint *rng)
{
- /* implicit mod 2^32 */
- *rng = (1103515245*(*rng) + 12345);
- return *rng;
+ /* implicit mod 2^32 */
+ *rng = (1103515245 * (*rng) + 12345);
+ return *rng;
}
ccl_device float lcg_step_float(uint *rng)
{
- /* implicit mod 2^32 */
- *rng = (1103515245*(*rng) + 12345);
- return (float)*rng * (1.0f/(float)0xFFFFFFFF);
+ /* implicit mod 2^32 */
+ *rng = (1103515245 * (*rng) + 12345);
+ return (float)*rng * (1.0f / (float)0xFFFFFFFF);
}
ccl_device uint lcg_init(uint seed)
{
- uint rng = seed;
- lcg_step_uint(&rng);
- return rng;
+ uint rng = seed;
+ lcg_step_uint(&rng);
+ return rng;
}
/* Path Tracing Utility Functions
@@ -181,118 +182,107 @@ ccl_device_inline float path_state_rng_1D(KernelGlobals *kg,
const ccl_addr_space PathState *state,
int dimension)
{
- return path_rng_1D(kg,
- state->rng_hash,
- state->sample, state->num_samples,
- state->rng_offset + dimension);
+ return path_rng_1D(
+ kg, state->rng_hash, state->sample, state->num_samples, state->rng_offset + dimension);
}
-ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
- const ccl_addr_space PathState *state,
- int dimension,
- float *fx, float *fy)
+ccl_device_inline void path_state_rng_2D(
+ KernelGlobals *kg, const ccl_addr_space PathState *state, int dimension, float *fx, float *fy)
{
- path_rng_2D(kg,
- state->rng_hash,
- state->sample, state->num_samples,
- state->rng_offset + dimension,
- fx, fy);
+ path_rng_2D(kg,
+ state->rng_hash,
+ state->sample,
+ state->num_samples,
+ state->rng_offset + dimension,
+ fx,
+ fy);
}
ccl_device_inline float path_state_rng_1D_hash(KernelGlobals *kg,
- const ccl_addr_space PathState *state,
- uint hash)
+ const ccl_addr_space PathState *state,
+ uint hash)
{
- /* Use a hash instead of dimension, this is not great but avoids adding
- * more dimensions to each bounce which reduces quality of dimensions we
- * are already using. */
- return path_rng_1D(kg,
- cmj_hash_simple(state->rng_hash, hash),
- state->sample, state->num_samples,
- state->rng_offset);
+ /* Use a hash instead of dimension, this is not great but avoids adding
+ * more dimensions to each bounce which reduces quality of dimensions we
+ * are already using. */
+ return path_rng_1D(kg,
+ cmj_hash_simple(state->rng_hash, hash),
+ state->sample,
+ state->num_samples,
+ state->rng_offset);
}
-ccl_device_inline float path_branched_rng_1D(
- KernelGlobals *kg,
- uint rng_hash,
- const ccl_addr_space PathState *state,
- int branch,
- int num_branches,
- int dimension)
+ccl_device_inline float path_branched_rng_1D(KernelGlobals *kg,
+ uint rng_hash,
+ const ccl_addr_space PathState *state,
+ int branch,
+ int num_branches,
+ int dimension)
{
- return path_rng_1D(kg,
- rng_hash,
- state->sample * num_branches + branch,
- state->num_samples * num_branches,
- state->rng_offset + dimension);
+ return path_rng_1D(kg,
+ rng_hash,
+ state->sample * num_branches + branch,
+ state->num_samples * num_branches,
+ state->rng_offset + dimension);
}
-ccl_device_inline void path_branched_rng_2D(
- KernelGlobals *kg,
- uint rng_hash,
- const ccl_addr_space PathState *state,
- int branch,
- int num_branches,
- int dimension,
- float *fx, float *fy)
+ccl_device_inline void path_branched_rng_2D(KernelGlobals *kg,
+ uint rng_hash,
+ const ccl_addr_space PathState *state,
+ int branch,
+ int num_branches,
+ int dimension,
+ float *fx,
+ float *fy)
{
- path_rng_2D(kg,
- rng_hash,
- state->sample * num_branches + branch,
- state->num_samples * num_branches,
- state->rng_offset + dimension,
- fx, fy);
+ path_rng_2D(kg,
+ rng_hash,
+ state->sample * num_branches + branch,
+ state->num_samples * num_branches,
+ state->rng_offset + dimension,
+ fx,
+ fy);
}
/* Utitility functions to get light termination value,
* since it might not be needed in many cases.
*/
-ccl_device_inline float path_state_rng_light_termination(
- KernelGlobals *kg,
- const ccl_addr_space PathState *state)
+ccl_device_inline float path_state_rng_light_termination(KernelGlobals *kg,
+ const ccl_addr_space PathState *state)
{
- if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
- return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE);
- }
- return 0.0f;
+ if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
+ return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE);
+ }
+ return 0.0f;
}
-ccl_device_inline float path_branched_rng_light_termination(
- KernelGlobals *kg,
- uint rng_hash,
- const ccl_addr_space PathState *state,
- int branch,
- int num_branches)
+ccl_device_inline float path_branched_rng_light_termination(KernelGlobals *kg,
+ uint rng_hash,
+ const ccl_addr_space PathState *state,
+ int branch,
+ int num_branches)
{
- if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
- return path_branched_rng_1D(kg,
- rng_hash,
- state,
- branch,
- num_branches,
- PRNG_LIGHT_TERMINATE);
- }
- return 0.0f;
+ if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
+ return path_branched_rng_1D(kg, rng_hash, state, branch, num_branches, PRNG_LIGHT_TERMINATE);
+ }
+ return 0.0f;
}
-ccl_device_inline uint lcg_state_init(PathState *state,
- uint scramble)
+ccl_device_inline uint lcg_state_init(PathState *state, uint scramble)
{
- return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble);
+ return lcg_init(state->rng_hash + state->rng_offset + state->sample * scramble);
}
-ccl_device_inline uint lcg_state_init_addrspace(ccl_addr_space PathState *state,
- uint scramble)
+ccl_device_inline uint lcg_state_init_addrspace(ccl_addr_space PathState *state, uint scramble)
{
- return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble);
+ return lcg_init(state->rng_hash + state->rng_offset + state->sample * scramble);
}
-
ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng)
{
- /* Implicit mod 2^32 */
- *rng = (1103515245*(*rng) + 12345);
- return (float)*rng * (1.0f/(float)0xFFFFFFFF);
+ /* Implicit mod 2^32 */
+ *rng = (1103515245 * (*rng) + 12345);
+ return (float)*rng * (1.0f / (float)0xFFFFFFFF);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index b1da523501d..351b623addb 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -37,14 +37,14 @@ CCL_NAMESPACE_BEGIN
#ifdef __OBJECT_MOTION__
ccl_device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
{
- if(sd->object_flag & SD_OBJECT_MOTION) {
- sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
- sd->ob_itfm = transform_quick_inverse(sd->ob_tfm);
- }
- else {
- sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
- sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- }
+ if (sd->object_flag & SD_OBJECT_MOTION) {
+ sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
+ sd->ob_itfm = transform_quick_inverse(sd->ob_tfm);
+ }
+ else {
+ sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
+ sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
+ }
}
#endif
@@ -53,104 +53,104 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg,
const Intersection *isect,
const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
#ifdef __INSTANCING__
- sd->object = (isect->object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
+ sd->object = (isect->object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, isect->prim) :
+ isect->object;
#endif
- sd->lamp = LAMP_NONE;
+ sd->lamp = LAMP_NONE;
- sd->type = isect->type;
- sd->flag = 0;
- sd->object_flag = kernel_tex_fetch(__object_flag,
- sd->object);
+ sd->type = isect->type;
+ sd->flag = 0;
+ sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
- /* matrices and time */
+ /* matrices and time */
#ifdef __OBJECT_MOTION__
- shader_setup_object_transforms(kg, sd, ray->time);
+ shader_setup_object_transforms(kg, sd, ray->time);
#endif
- sd->time = ray->time;
+ sd->time = ray->time;
- sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
- sd->ray_length = isect->t;
+ sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
+ sd->ray_length = isect->t;
#ifdef __UV__
- sd->u = isect->u;
- sd->v = isect->v;
+ sd->u = isect->u;
+ sd->v = isect->v;
#endif
#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_CURVE) {
- /* curve */
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
-
- sd->shader = __float_as_int(curvedata.z);
- sd->P = curve_refine(kg, sd, isect, ray);
- }
- else
+ if (sd->type & PRIMITIVE_ALL_CURVE) {
+ /* curve */
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+
+ sd->shader = __float_as_int(curvedata.z);
+ sd->P = curve_refine(kg, sd, isect, ray);
+ }
+ else
#endif
- if(sd->type & PRIMITIVE_TRIANGLE) {
- /* static triangle */
- float3 Ng = triangle_normal(kg, sd);
- sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ /* static triangle */
+ float3 Ng = triangle_normal(kg, sd);
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
- /* vectors */
- sd->P = triangle_refine(kg, sd, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
+ /* vectors */
+ sd->P = triangle_refine(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
- /* smooth normal */
- if(sd->shader & SHADER_SMOOTH_NORMAL)
- sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
+ /* smooth normal */
+ if (sd->shader & SHADER_SMOOTH_NORMAL)
+ sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
#ifdef __DPDU__
- /* dPdu/dPdv */
- triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+ /* dPdu/dPdv */
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
#endif
- }
- else {
- /* motion triangle */
- motion_triangle_shader_setup(kg, sd, isect, ray, false);
- }
+ }
+ else {
+ /* motion triangle */
+ motion_triangle_shader_setup(kg, sd, isect, ray, false);
+ }
- sd->I = -ray->D;
+ sd->I = -ray->D;
- sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
#ifdef __INSTANCING__
- if(isect->object != OBJECT_NONE) {
- /* instance transform */
- object_normal_transform_auto(kg, sd, &sd->N);
- object_normal_transform_auto(kg, sd, &sd->Ng);
+ if (isect->object != OBJECT_NONE) {
+ /* instance transform */
+ object_normal_transform_auto(kg, sd, &sd->N);
+ object_normal_transform_auto(kg, sd, &sd->Ng);
# ifdef __DPDU__
- object_dir_transform_auto(kg, sd, &sd->dPdu);
- object_dir_transform_auto(kg, sd, &sd->dPdv);
+ object_dir_transform_auto(kg, sd, &sd->dPdu);
+ object_dir_transform_auto(kg, sd, &sd->dPdv);
# endif
- }
+ }
#endif
- /* backfacing test */
- bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
+ /* backfacing test */
+ bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
- if(backfacing) {
- sd->flag |= SD_BACKFACING;
- sd->Ng = -sd->Ng;
- sd->N = -sd->N;
+ if (backfacing) {
+ sd->flag |= SD_BACKFACING;
+ sd->Ng = -sd->Ng;
+ sd->N = -sd->N;
#ifdef __DPDU__
- sd->dPdu = -sd->dPdu;
- sd->dPdv = -sd->dPdv;
+ sd->dPdu = -sd->dPdu;
+ sd->dPdv = -sd->dPdv;
#endif
- }
+ }
#ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
- differential_incoming(&sd->dI, ray->dD);
- differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
+ /* differentials */
+ differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
+ differential_incoming(&sd->dI, ray->dD);
+ differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
#endif
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
/* ShaderData setup from BSSRDF scatter */
@@ -161,86 +161,86 @@ ccl_device
# else
ccl_device_inline
# endif
-void shader_setup_from_subsurface(
- KernelGlobals *kg,
- ShaderData *sd,
- const Intersection *isect,
- const Ray *ray)
+ void
+ shader_setup_from_subsurface(KernelGlobals *kg,
+ ShaderData *sd,
+ const Intersection *isect,
+ const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
- const bool backfacing = sd->flag & SD_BACKFACING;
+ const bool backfacing = sd->flag & SD_BACKFACING;
- /* object, matrices, time, ray_length stay the same */
- sd->flag = 0;
- sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
- sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
- sd->type = isect->type;
+ /* object, matrices, time, ray_length stay the same */
+ sd->flag = 0;
+ sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
+ sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
+ sd->type = isect->type;
# ifdef __UV__
- sd->u = isect->u;
- sd->v = isect->v;
+ sd->u = isect->u;
+ sd->v = isect->v;
# endif
- /* fetch triangle data */
- if(sd->type == PRIMITIVE_TRIANGLE) {
- float3 Ng = triangle_normal(kg, sd);
- sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+ /* fetch triangle data */
+ if (sd->type == PRIMITIVE_TRIANGLE) {
+ float3 Ng = triangle_normal(kg, sd);
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
- /* static triangle */
- sd->P = triangle_refine_local(kg, sd, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
+ /* static triangle */
+ sd->P = triangle_refine_local(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
- if(sd->shader & SHADER_SMOOTH_NORMAL)
- sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
+ if (sd->shader & SHADER_SMOOTH_NORMAL)
+ sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
# ifdef __DPDU__
- /* dPdu/dPdv */
- triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+ /* dPdu/dPdv */
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
# endif
- }
- else {
- /* motion triangle */
- motion_triangle_shader_setup(kg, sd, isect, ray, true);
- }
+ }
+ else {
+ /* motion triangle */
+ motion_triangle_shader_setup(kg, sd, isect, ray, true);
+ }
- sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
# ifdef __INSTANCING__
- if(isect->object != OBJECT_NONE) {
- /* instance transform */
- object_normal_transform_auto(kg, sd, &sd->N);
- object_normal_transform_auto(kg, sd, &sd->Ng);
+ if (isect->object != OBJECT_NONE) {
+ /* instance transform */
+ object_normal_transform_auto(kg, sd, &sd->N);
+ object_normal_transform_auto(kg, sd, &sd->Ng);
# ifdef __DPDU__
- object_dir_transform_auto(kg, sd, &sd->dPdu);
- object_dir_transform_auto(kg, sd, &sd->dPdv);
+ object_dir_transform_auto(kg, sd, &sd->dPdu);
+ object_dir_transform_auto(kg, sd, &sd->dPdv);
# endif
- }
+ }
# endif
- /* backfacing test */
- if(backfacing) {
- sd->flag |= SD_BACKFACING;
- sd->Ng = -sd->Ng;
- sd->N = -sd->N;
+ /* backfacing test */
+ if (backfacing) {
+ sd->flag |= SD_BACKFACING;
+ sd->Ng = -sd->Ng;
+ sd->N = -sd->N;
# ifdef __DPDU__
- sd->dPdu = -sd->dPdu;
- sd->dPdv = -sd->dPdv;
+ sd->dPdu = -sd->dPdu;
+ sd->dPdv = -sd->dPdv;
# endif
- }
+ }
- /* should not get used in principle as the shading will only use a diffuse
- * BSDF, but the shader might still access it */
- sd->I = sd->N;
+ /* should not get used in principle as the shading will only use a diffuse
+ * BSDF, but the shader might still access it */
+ sd->I = sd->N;
# ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
- /* don't modify dP and dI */
+ /* differentials */
+ differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
+ /* don't modify dP and dI */
# endif
- PROFILING_SHADER(sd->shader);
+ PROFILING_SHADER(sd->shader);
}
#endif
@@ -251,194 +251,208 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
const float3 P,
const float3 Ng,
const float3 I,
- int shader, int object, int prim,
- float u, float v, float t,
+ int shader,
+ int object,
+ int prim,
+ float u,
+ float v,
+ float t,
float time,
bool object_space,
int lamp)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
-
- /* vectors */
- sd->P = P;
- sd->N = Ng;
- sd->Ng = Ng;
- sd->I = I;
- sd->shader = shader;
- if(prim != PRIM_NONE)
- sd->type = PRIMITIVE_TRIANGLE;
- else if(lamp != LAMP_NONE)
- sd->type = PRIMITIVE_LAMP;
- else
- sd->type = PRIMITIVE_NONE;
-
- /* primitive */
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+
+ /* vectors */
+ sd->P = P;
+ sd->N = Ng;
+ sd->Ng = Ng;
+ sd->I = I;
+ sd->shader = shader;
+ if (prim != PRIM_NONE)
+ sd->type = PRIMITIVE_TRIANGLE;
+ else if (lamp != LAMP_NONE)
+ sd->type = PRIMITIVE_LAMP;
+ else
+ sd->type = PRIMITIVE_NONE;
+
+ /* primitive */
#ifdef __INSTANCING__
- sd->object = object;
+ sd->object = object;
#endif
- sd->lamp = LAMP_NONE;
- /* currently no access to bvh prim index for strand sd->prim*/
- sd->prim = prim;
+ sd->lamp = LAMP_NONE;
+ /* currently no access to bvh prim index for strand sd->prim*/
+ sd->prim = prim;
#ifdef __UV__
- sd->u = u;
- sd->v = v;
+ sd->u = u;
+ sd->v = v;
#endif
- sd->time = time;
- sd->ray_length = t;
+ sd->time = time;
+ sd->ray_length = t;
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
- sd->object_flag = 0;
- if(sd->object != OBJECT_NONE) {
- sd->object_flag |= kernel_tex_fetch(__object_flag,
- sd->object);
+ sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->object_flag = 0;
+ if (sd->object != OBJECT_NONE) {
+ sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
#ifdef __OBJECT_MOTION__
- shader_setup_object_transforms(kg, sd, time);
- }
- else if(lamp != LAMP_NONE) {
- sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
- sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
- sd->lamp = lamp;
+ shader_setup_object_transforms(kg, sd, time);
+ }
+ else if (lamp != LAMP_NONE) {
+ sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
+ sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
+ sd->lamp = lamp;
#else
- }
- else if(lamp != LAMP_NONE) {
- sd->lamp = lamp;
+ }
+ else if (lamp != LAMP_NONE) {
+ sd->lamp = lamp;
#endif
- }
+ }
- /* transform into world space */
- if(object_space) {
- object_position_transform_auto(kg, sd, &sd->P);
- object_normal_transform_auto(kg, sd, &sd->Ng);
- sd->N = sd->Ng;
- object_dir_transform_auto(kg, sd, &sd->I);
- }
+ /* transform into world space */
+ if (object_space) {
+ object_position_transform_auto(kg, sd, &sd->P);
+ object_normal_transform_auto(kg, sd, &sd->Ng);
+ sd->N = sd->Ng;
+ object_dir_transform_auto(kg, sd, &sd->I);
+ }
- if(sd->type & PRIMITIVE_TRIANGLE) {
- /* smooth normal */
- if(sd->shader & SHADER_SMOOTH_NORMAL) {
- sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ /* smooth normal */
+ if (sd->shader & SHADER_SMOOTH_NORMAL) {
+ sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
#ifdef __INSTANCING__
- if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_normal_transform_auto(kg, sd, &sd->N);
- }
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_normal_transform_auto(kg, sd, &sd->N);
+ }
#endif
- }
+ }
- /* dPdu/dPdv */
+ /* dPdu/dPdv */
#ifdef __DPDU__
- triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
# ifdef __INSTANCING__
- if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_dir_transform_auto(kg, sd, &sd->dPdu);
- object_dir_transform_auto(kg, sd, &sd->dPdv);
- }
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_dir_transform_auto(kg, sd, &sd->dPdu);
+ object_dir_transform_auto(kg, sd, &sd->dPdv);
+ }
# endif
#endif
- }
- else {
+ }
+ else {
#ifdef __DPDU__
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
#endif
- }
+ }
- /* backfacing test */
- if(sd->prim != PRIM_NONE) {
- bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
+ /* backfacing test */
+ if (sd->prim != PRIM_NONE) {
+ bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
- if(backfacing) {
- sd->flag |= SD_BACKFACING;
- sd->Ng = -sd->Ng;
- sd->N = -sd->N;
+ if (backfacing) {
+ sd->flag |= SD_BACKFACING;
+ sd->Ng = -sd->Ng;
+ sd->N = -sd->N;
#ifdef __DPDU__
- sd->dPdu = -sd->dPdu;
- sd->dPdv = -sd->dPdv;
+ sd->dPdu = -sd->dPdu;
+ sd->dPdv = -sd->dPdv;
#endif
- }
- }
+ }
+ }
#ifdef __RAY_DIFFERENTIALS__
- /* no ray differentials here yet */
- sd->dP = differential3_zero();
- sd->dI = differential3_zero();
- sd->du = differential_zero();
- sd->dv = differential_zero();
+ /* no ray differentials here yet */
+ sd->dP = differential3_zero();
+ sd->dI = differential3_zero();
+ sd->du = differential_zero();
+ sd->dv = differential_zero();
#endif
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
/* ShaderData setup for displacement */
-ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
- int object, int prim, float u, float v)
+ccl_device void shader_setup_from_displace(
+ KernelGlobals *kg, ShaderData *sd, int object, int prim, float u, float v)
{
- float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
- int shader;
-
- triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
-
- /* force smooth shading for displacement */
- shader |= SHADER_SMOOTH_NORMAL;
-
- shader_setup_from_sample(kg, sd,
- P, Ng, I,
- shader, object, prim,
- u, v, 0.0f, 0.5f,
- !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
- LAMP_NONE);
+ float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
+ int shader;
+
+ triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
+
+ /* force smooth shading for displacement */
+ shader |= SHADER_SMOOTH_NORMAL;
+
+ shader_setup_from_sample(
+ kg,
+ sd,
+ P,
+ Ng,
+ I,
+ shader,
+ object,
+ prim,
+ u,
+ v,
+ 0.0f,
+ 0.5f,
+ !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
+ LAMP_NONE);
}
/* ShaderData setup from ray into background */
-ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
+ccl_device_inline void shader_setup_from_background(KernelGlobals *kg,
+ ShaderData *sd,
+ const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
-
- /* vectors */
- sd->P = ray->D;
- sd->N = -ray->D;
- sd->Ng = -ray->D;
- sd->I = -ray->D;
- sd->shader = kernel_data.background.surface_shader;
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
- sd->object_flag = 0;
- sd->time = ray->time;
- sd->ray_length = 0.0f;
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+
+ /* vectors */
+ sd->P = ray->D;
+ sd->N = -ray->D;
+ sd->Ng = -ray->D;
+ sd->I = -ray->D;
+ sd->shader = kernel_data.background.surface_shader;
+ sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->object_flag = 0;
+ sd->time = ray->time;
+ sd->ray_length = 0.0f;
#ifdef __INSTANCING__
- sd->object = OBJECT_NONE;
+ sd->object = OBJECT_NONE;
#endif
- sd->lamp = LAMP_NONE;
- sd->prim = PRIM_NONE;
+ sd->lamp = LAMP_NONE;
+ sd->prim = PRIM_NONE;
#ifdef __UV__
- sd->u = 0.0f;
- sd->v = 0.0f;
+ sd->u = 0.0f;
+ sd->v = 0.0f;
#endif
#ifdef __DPDU__
- /* dPdu/dPdv */
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ /* dPdu/dPdv */
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
#endif
#ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- sd->dP = ray->dD;
- differential_incoming(&sd->dI, sd->dP);
- sd->du = differential_zero();
- sd->dv = differential_zero();
+ /* differentials */
+ sd->dP = ray->dD;
+ differential_incoming(&sd->dI, sd->dP);
+ sd->du = differential_zero();
+ sd->dv = differential_zero();
#endif
- /* for NDC coordinates */
- sd->ray_P = ray->P;
+ /* for NDC coordinates */
+ sd->ray_P = ray->P;
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
/* ShaderData setup from point inside volume */
@@ -446,141 +460,145 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
#ifdef __VOLUME__
ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
-
- /* vectors */
- sd->P = ray->P;
- sd->N = -ray->D;
- sd->Ng = -ray->D;
- sd->I = -ray->D;
- sd->shader = SHADER_NONE;
- sd->flag = 0;
- sd->object_flag = 0;
- sd->time = ray->time;
- sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+
+ /* vectors */
+ sd->P = ray->P;
+ sd->N = -ray->D;
+ sd->Ng = -ray->D;
+ sd->I = -ray->D;
+ sd->shader = SHADER_NONE;
+ sd->flag = 0;
+ sd->object_flag = 0;
+ sd->time = ray->time;
+ sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
# ifdef __INSTANCING__
- sd->object = OBJECT_NONE; /* todo: fill this for texture coordinates */
+ sd->object = OBJECT_NONE; /* todo: fill this for texture coordinates */
# endif
- sd->lamp = LAMP_NONE;
- sd->prim = PRIM_NONE;
- sd->type = PRIMITIVE_NONE;
+ sd->lamp = LAMP_NONE;
+ sd->prim = PRIM_NONE;
+ sd->type = PRIMITIVE_NONE;
# ifdef __UV__
- sd->u = 0.0f;
- sd->v = 0.0f;
+ sd->u = 0.0f;
+ sd->v = 0.0f;
# endif
# ifdef __DPDU__
- /* dPdu/dPdv */
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ /* dPdu/dPdv */
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
# endif
# ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- sd->dP = ray->dD;
- differential_incoming(&sd->dI, sd->dP);
- sd->du = differential_zero();
- sd->dv = differential_zero();
+ /* differentials */
+ sd->dP = ray->dD;
+ differential_incoming(&sd->dI, sd->dP);
+ sd->du = differential_zero();
+ sd->dv = differential_zero();
# endif
- /* for NDC coordinates */
- sd->ray_P = ray->P;
- sd->ray_dP = ray->dP;
+ /* for NDC coordinates */
+ sd->ray_P = ray->P;
+ sd->ray_dP = ray->dP;
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
/* Merging */
#if defined(__BRANCHED_PATH__) || defined(__VOLUME__)
ccl_device_inline void shader_merge_closures(ShaderData *sd)
{
- /* merge identical closures, better when we sample a single closure at a time */
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sci = &sd->closure[i];
-
- for(int j = i + 1; j < sd->num_closure; j++) {
- ShaderClosure *scj = &sd->closure[j];
-
- if(sci->type != scj->type)
- continue;
- if(!bsdf_merge(sci, scj))
- continue;
-
- sci->weight += scj->weight;
- sci->sample_weight += scj->sample_weight;
-
- int size = sd->num_closure - (j+1);
- if(size > 0) {
- for(int k = 0; k < size; k++) {
- scj[k] = scj[k+1];
- }
- }
-
- sd->num_closure--;
- kernel_assert(sd->num_closure >= 0);
- j--;
- }
- }
+ /* merge identical closures, better when we sample a single closure at a time */
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sci = &sd->closure[i];
+
+ for (int j = i + 1; j < sd->num_closure; j++) {
+ ShaderClosure *scj = &sd->closure[j];
+
+ if (sci->type != scj->type)
+ continue;
+ if (!bsdf_merge(sci, scj))
+ continue;
+
+ sci->weight += scj->weight;
+ sci->sample_weight += scj->sample_weight;
+
+ int size = sd->num_closure - (j + 1);
+ if (size > 0) {
+ for (int k = 0; k < size; k++) {
+ scj[k] = scj[k + 1];
+ }
+ }
+
+ sd->num_closure--;
+ kernel_assert(sd->num_closure >= 0);
+ j--;
+ }
+ }
}
-#endif /* __BRANCHED_PATH__ || __VOLUME__ */
+#endif /* __BRANCHED_PATH__ || __VOLUME__ */
/* Defensive sampling. */
-ccl_device_inline void shader_prepare_closures(ShaderData *sd,
- ccl_addr_space PathState *state)
+ccl_device_inline void shader_prepare_closures(ShaderData *sd, ccl_addr_space PathState *state)
{
- /* We can likely also do defensive sampling at deeper bounces, particularly
- * for cases like a perfect mirror but possibly also others. This will need
- * a good heuristic. */
- if(state->bounce + state->transparent_bounce == 0 && sd->num_closure > 1) {
- float sum = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- sum += sc->sample_weight;
- }
- }
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- sc->sample_weight = max(sc->sample_weight, 0.125f * sum);
- }
- }
- }
+ /* We can likely also do defensive sampling at deeper bounces, particularly
+ * for cases like a perfect mirror but possibly also others. This will need
+ * a good heuristic. */
+ if (state->bounce + state->transparent_bounce == 0 && sd->num_closure > 1) {
+ float sum = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ sum += sc->sample_weight;
+ }
+ }
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ sc->sample_weight = max(sc->sample_weight, 0.125f * sum);
+ }
+ }
+ }
}
-
/* BSDF */
-ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, ShaderData *sd, const float3 omega_in, float *pdf,
- const ShaderClosure *skip_sc, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
+ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg,
+ ShaderData *sd,
+ const float3 omega_in,
+ float *pdf,
+ const ShaderClosure *skip_sc,
+ BsdfEval *result_eval,
+ float sum_pdf,
+ float sum_sample_weight)
{
- /* this is the veach one-sample model with balance heuristic, some pdf
- * factors drop out when using balance heuristic weighting */
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ /* this is the veach one-sample model with balance heuristic, some pdf
+ * factors drop out when using balance heuristic weighting */
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(sc != skip_sc && CLOSURE_IS_BSDF(sc->type)) {
- float bsdf_pdf = 0.0f;
- float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
+ if (sc != skip_sc && CLOSURE_IS_BSDF(sc->type)) {
+ float bsdf_pdf = 0.0f;
+ float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
- if(bsdf_pdf != 0.0f) {
- bsdf_eval_accum(result_eval, sc->type, eval*sc->weight, 1.0f);
- sum_pdf += bsdf_pdf*sc->sample_weight;
- }
+ if (bsdf_pdf != 0.0f) {
+ bsdf_eval_accum(result_eval, sc->type, eval * sc->weight, 1.0f);
+ sum_pdf += bsdf_pdf * sc->sample_weight;
+ }
- sum_sample_weight += sc->sample_weight;
- }
- }
+ sum_sample_weight += sc->sample_weight;
+ }
+ }
- *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
+ *pdf = (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
}
#ifdef __BRANCHED_PATH__
@@ -591,633 +609,654 @@ ccl_device_inline void _shader_bsdf_multi_eval_branched(KernelGlobals *kg,
float light_pdf,
bool use_mis)
{
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF(sc->type)) {
- float bsdf_pdf = 0.0f;
- float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
- if(bsdf_pdf != 0.0f) {
- float mis_weight = use_mis? power_heuristic(light_pdf, bsdf_pdf): 1.0f;
- bsdf_eval_accum(result_eval,
- sc->type,
- eval * sc->weight,
- mis_weight);
- }
- }
- }
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ float bsdf_pdf = 0.0f;
+ float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
+ if (bsdf_pdf != 0.0f) {
+ float mis_weight = use_mis ? power_heuristic(light_pdf, bsdf_pdf) : 1.0f;
+ bsdf_eval_accum(result_eval, sc->type, eval * sc->weight, mis_weight);
+ }
+ }
+ }
}
-#endif /* __BRANCHED_PATH__ */
-
+#endif /* __BRANCHED_PATH__ */
#ifndef __KERNEL_CUDA__
ccl_device
#else
ccl_device_inline
#endif
-void shader_bsdf_eval(KernelGlobals *kg,
- ShaderData *sd,
- const float3 omega_in,
- BsdfEval *eval,
- float light_pdf,
- bool use_mis)
+ void
+ shader_bsdf_eval(KernelGlobals *kg,
+ ShaderData *sd,
+ const float3 omega_in,
+ BsdfEval *eval,
+ float light_pdf,
+ bool use_mis)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_EVAL);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_EVAL);
- bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
+ bsdf_eval_init(
+ eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
#ifdef __BRANCHED_PATH__
- if(kernel_data.integrator.branched)
- _shader_bsdf_multi_eval_branched(kg, sd, omega_in, eval, light_pdf, use_mis);
- else
+ if (kernel_data.integrator.branched)
+ _shader_bsdf_multi_eval_branched(kg, sd, omega_in, eval, light_pdf, use_mis);
+ else
#endif
- {
- float pdf;
- _shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, NULL, eval, 0.0f, 0.0f);
- if(use_mis) {
- float weight = power_heuristic(light_pdf, pdf);
- bsdf_eval_mis(eval, weight);
- }
- }
+ {
+ float pdf;
+ _shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, NULL, eval, 0.0f, 0.0f);
+ if (use_mis) {
+ float weight = power_heuristic(light_pdf, pdf);
+ bsdf_eval_mis(eval, weight);
+ }
+ }
}
-ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd,
- float *randu)
+ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd, float *randu)
{
- /* Note the sampling here must match shader_bssrdf_pick,
- * since we reuse the same random number. */
- int sampled = 0;
+ /* Note the sampling here must match shader_bssrdf_pick,
+ * since we reuse the same random number. */
+ int sampled = 0;
- if(sd->num_closure > 1) {
- /* Pick a BSDF or based on sample weights. */
- float sum = 0.0f;
+ if (sd->num_closure > 1) {
+ /* Pick a BSDF or based on sample weights. */
+ float sum = 0.0f;
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- sum += sc->sample_weight;
- }
- }
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ sum += sc->sample_weight;
+ }
+ }
- float r = (*randu)*sum;
- float partial_sum = 0.0f;
+ float r = (*randu) * sum;
+ float partial_sum = 0.0f;
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- float next_sum = partial_sum + sc->sample_weight;
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ float next_sum = partial_sum + sc->sample_weight;
- if(r < next_sum) {
- sampled = i;
+ if (r < next_sum) {
+ sampled = i;
- /* Rescale to reuse for direction sample, to better
- * preserve stratifaction. */
- *randu = (r - partial_sum) / sc->sample_weight;
- break;
- }
+ /* Rescale to reuse for direction sample, to better
+ * preserve stratifaction. */
+ *randu = (r - partial_sum) / sc->sample_weight;
+ break;
+ }
- partial_sum = next_sum;
- }
- }
- }
+ partial_sum = next_sum;
+ }
+ }
+ }
- const ShaderClosure *sc = &sd->closure[sampled];
- return CLOSURE_IS_BSDF(sc->type)? sc: NULL;
+ const ShaderClosure *sc = &sd->closure[sampled];
+ return CLOSURE_IS_BSDF(sc->type) ? sc : NULL;
}
ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd,
ccl_addr_space float3 *throughput,
float *randu)
{
- /* Note the sampling here must match shader_bsdf_pick,
- * since we reuse the same random number. */
- int sampled = 0;
-
- if(sd->num_closure > 1) {
- /* Pick a BSDF or BSSRDF or based on sample weights. */
- float sum_bsdf = 0.0f;
- float sum_bssrdf = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF(sc->type)) {
- sum_bsdf += sc->sample_weight;
- }
- else if(CLOSURE_IS_BSSRDF(sc->type)) {
- sum_bssrdf += sc->sample_weight;
- }
- }
-
- float r = (*randu)*(sum_bsdf + sum_bssrdf);
- float partial_sum = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- float next_sum = partial_sum + sc->sample_weight;
-
- if(r < next_sum) {
- if(CLOSURE_IS_BSDF(sc->type)) {
- *throughput *= (sum_bsdf + sum_bssrdf) / sum_bsdf;
- return NULL;
- }
- else {
- *throughput *= (sum_bsdf + sum_bssrdf) / sum_bssrdf;
- sampled = i;
-
- /* Rescale to reuse for direction sample, to better
- * preserve stratifaction. */
- *randu = (r - partial_sum) / sc->sample_weight;
- break;
- }
- }
-
- partial_sum = next_sum;
- }
- }
- }
-
- const ShaderClosure *sc = &sd->closure[sampled];
- return CLOSURE_IS_BSSRDF(sc->type)? sc: NULL;
+ /* Note the sampling here must match shader_bsdf_pick,
+ * since we reuse the same random number. */
+ int sampled = 0;
+
+ if (sd->num_closure > 1) {
+ /* Pick a BSDF or BSSRDF or based on sample weights. */
+ float sum_bsdf = 0.0f;
+ float sum_bssrdf = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ sum_bsdf += sc->sample_weight;
+ }
+ else if (CLOSURE_IS_BSSRDF(sc->type)) {
+ sum_bssrdf += sc->sample_weight;
+ }
+ }
+
+ float r = (*randu) * (sum_bsdf + sum_bssrdf);
+ float partial_sum = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ float next_sum = partial_sum + sc->sample_weight;
+
+ if (r < next_sum) {
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ *throughput *= (sum_bsdf + sum_bssrdf) / sum_bsdf;
+ return NULL;
+ }
+ else {
+ *throughput *= (sum_bsdf + sum_bssrdf) / sum_bssrdf;
+ sampled = i;
+
+ /* Rescale to reuse for direction sample, to better
+ * preserve stratifaction. */
+ *randu = (r - partial_sum) / sc->sample_weight;
+ break;
+ }
+ }
+
+ partial_sum = next_sum;
+ }
+ }
+ }
+
+ const ShaderClosure *sc = &sd->closure[sampled];
+ return CLOSURE_IS_BSSRDF(sc->type) ? sc : NULL;
}
ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
ShaderData *sd,
- float randu, float randv,
+ float randu,
+ float randv,
BsdfEval *bsdf_eval,
float3 *omega_in,
differential3 *domega_in,
float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
- const ShaderClosure *sc = shader_bsdf_pick(sd, &randu);
- if(sc == NULL) {
- *pdf = 0.0f;
- return LABEL_NONE;
- }
+ const ShaderClosure *sc = shader_bsdf_pick(sd, &randu);
+ if (sc == NULL) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
- /* BSSRDF should already have been handled elsewhere. */
- kernel_assert(CLOSURE_IS_BSDF(sc->type));
+ /* BSSRDF should already have been handled elsewhere. */
+ kernel_assert(CLOSURE_IS_BSDF(sc->type));
- int label;
- float3 eval;
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f) {
- bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
+ if (*pdf != 0.0f) {
+ bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight, kernel_data.film.use_light_pass);
- if(sd->num_closure > 1) {
- float sweight = sc->sample_weight;
- _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sc, bsdf_eval, *pdf*sweight, sweight);
- }
- }
+ if (sd->num_closure > 1) {
+ float sweight = sc->sample_weight;
+ _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sc, bsdf_eval, *pdf * sweight, sweight);
+ }
+ }
- return label;
+ return label;
}
-ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg, ShaderData *sd,
- const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval,
- float3 *omega_in, differential3 *domega_in, float *pdf)
+ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg,
+ ShaderData *sd,
+ const ShaderClosure *sc,
+ float randu,
+ float randv,
+ BsdfEval *bsdf_eval,
+ float3 *omega_in,
+ differential3 *domega_in,
+ float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
- int label;
- float3 eval;
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f)
- bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
+ if (*pdf != 0.0f)
+ bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight, kernel_data.film.use_light_pass);
- return label;
+ return label;
}
ccl_device float shader_bsdf_average_roughness(ShaderData *sd)
{
- float roughness = 0.0f;
- float sum_weight = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF(sc->type)) {
- /* sqrt once to undo the squaring from multiplying roughness on the
- * two axes, and once for the squared roughness convention. */
- float weight = fabsf(average(sc->weight));
- roughness += weight * sqrtf(safe_sqrtf(bsdf_get_roughness_squared(sc)));
- sum_weight += weight;
- }
- }
-
- return (sum_weight > 0.0f) ? roughness / sum_weight : 0.0f;
+ float roughness = 0.0f;
+ float sum_weight = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ /* sqrt once to undo the squaring from multiplying roughness on the
+ * two axes, and once for the squared roughness convention. */
+ float weight = fabsf(average(sc->weight));
+ roughness += weight * sqrtf(safe_sqrtf(bsdf_get_roughness_squared(sc)));
+ sum_weight += weight;
+ }
+ }
+
+ return (sum_weight > 0.0f) ? roughness / sum_weight : 0.0f;
}
ccl_device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
{
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF(sc->type))
- bsdf_blur(kg, sc, roughness);
- }
+ if (CLOSURE_IS_BSDF(sc->type))
+ bsdf_blur(kg, sc, roughness);
+ }
}
ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, const ShaderData *sd)
{
- if(sd->flag & SD_HAS_ONLY_VOLUME) {
- return make_float3(1.0f, 1.0f, 1.0f);
- }
- else if(sd->flag & SD_TRANSPARENT) {
- return sd->closure_transparent_extinction;
- }
- else {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (sd->flag & SD_HAS_ONLY_VOLUME) {
+ return make_float3(1.0f, 1.0f, 1.0f);
+ }
+ else if (sd->flag & SD_TRANSPARENT) {
+ return sd->closure_transparent_extinction;
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
ccl_device void shader_bsdf_disable_transparency(KernelGlobals *kg, ShaderData *sd)
{
- if(sd->flag & SD_TRANSPARENT) {
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
- sc->sample_weight = 0.0f;
- sc->weight = make_float3(0.0f, 0.0f, 0.0f);
- }
- }
-
- sd->flag &= ~SD_TRANSPARENT;
- }
+ if (sd->flag & SD_TRANSPARENT) {
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+
+ if (sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
+ sc->sample_weight = 0.0f;
+ sc->weight = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ sd->flag &= ~SD_TRANSPARENT;
+ }
}
ccl_device float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd)
{
- float3 alpha = make_float3(1.0f, 1.0f, 1.0f) - shader_bsdf_transparency(kg, sd);
+ float3 alpha = make_float3(1.0f, 1.0f, 1.0f) - shader_bsdf_transparency(kg, sd);
- alpha = max(alpha, make_float3(0.0f, 0.0f, 0.0f));
- alpha = min(alpha, make_float3(1.0f, 1.0f, 1.0f));
+ alpha = max(alpha, make_float3(0.0f, 0.0f, 0.0f));
+ alpha = min(alpha, make_float3(1.0f, 1.0f, 1.0f));
- return alpha;
+ return alpha;
}
ccl_device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSDF_GLOSSY(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSSRDF(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSSRDF(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_average_normal(KernelGlobals *kg, ShaderData *sd)
{
- float3 N = make_float3(0.0f, 0.0f, 0.0f);
+ float3 N = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type))
- N += sc->N*fabsf(average(sc->weight));
- }
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type))
+ N += sc->N * fabsf(average(sc->weight));
+ }
- return (is_zero(N))? sd->N : normalize(N);
+ return (is_zero(N)) ? sd->N : normalize(N);
}
ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N_)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- float3 N = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 N = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
- const DiffuseBsdf *bsdf = (const DiffuseBsdf*)sc;
- eval += sc->weight*ao_factor;
- N += bsdf->N*fabsf(average(sc->weight));
- }
- }
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
+ const DiffuseBsdf *bsdf = (const DiffuseBsdf *)sc;
+ eval += sc->weight * ao_factor;
+ N += bsdf->N * fabsf(average(sc->weight));
+ }
+ }
- *N_ = (is_zero(N))? sd->N : normalize(N);
- return eval;
+ *N_ = (is_zero(N)) ? sd->N : normalize(N);
+ return eval;
}
#ifdef __SUBSURFACE__
ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_blur_)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- float3 N = make_float3(0.0f, 0.0f, 0.0f);
- float texture_blur = 0.0f, weight_sum = 0.0f;
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 N = make_float3(0.0f, 0.0f, 0.0f);
+ float texture_blur = 0.0f, weight_sum = 0.0f;
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSSRDF(sc->type)) {
- const Bssrdf *bssrdf = (const Bssrdf*)sc;
- float avg_weight = fabsf(average(sc->weight));
+ if (CLOSURE_IS_BSSRDF(sc->type)) {
+ const Bssrdf *bssrdf = (const Bssrdf *)sc;
+ float avg_weight = fabsf(average(sc->weight));
- N += bssrdf->N*avg_weight;
- eval += sc->weight;
- texture_blur += bssrdf->texture_blur*avg_weight;
- weight_sum += avg_weight;
- }
- }
+ N += bssrdf->N * avg_weight;
+ eval += sc->weight;
+ texture_blur += bssrdf->texture_blur * avg_weight;
+ weight_sum += avg_weight;
+ }
+ }
- if(N_)
- *N_ = (is_zero(N))? sd->N: normalize(N);
+ if (N_)
+ *N_ = (is_zero(N)) ? sd->N : normalize(N);
- if(texture_blur_)
- *texture_blur_ = safe_divide(texture_blur, weight_sum);
+ if (texture_blur_)
+ *texture_blur_ = safe_divide(texture_blur, weight_sum);
- return eval;
+ return eval;
}
-#endif /* __SUBSURFACE__ */
+#endif /* __SUBSURFACE__ */
/* Constant emission optimization */
ccl_device bool shader_constant_emission_eval(KernelGlobals *kg, int shader, float3 *eval)
{
- int shader_index = shader & SHADER_MASK;
- int shader_flag = kernel_tex_fetch(__shaders, shader_index).flags;
+ int shader_index = shader & SHADER_MASK;
+ int shader_flag = kernel_tex_fetch(__shaders, shader_index).flags;
- if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
- *eval = make_float3(
- kernel_tex_fetch(__shaders, shader_index).constant_emission[0],
- kernel_tex_fetch(__shaders, shader_index).constant_emission[1],
- kernel_tex_fetch(__shaders, shader_index).constant_emission[2]);
+ if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
+ *eval = make_float3(kernel_tex_fetch(__shaders, shader_index).constant_emission[0],
+ kernel_tex_fetch(__shaders, shader_index).constant_emission[1],
+ kernel_tex_fetch(__shaders, shader_index).constant_emission[2]);
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* Background */
ccl_device float3 shader_background_eval(ShaderData *sd)
{
- if(sd->flag & SD_EMISSION) {
- return sd->closure_emission_background;
- }
- else {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (sd->flag & SD_EMISSION) {
+ return sd->closure_emission_background;
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
/* Emission */
ccl_device float3 shader_emissive_eval(ShaderData *sd)
{
- if(sd->flag & SD_EMISSION) {
- return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
- }
- else {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (sd->flag & SD_EMISSION) {
+ return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
/* Holdout */
ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
{
- float3 weight = make_float3(0.0f, 0.0f, 0.0f);
+ float3 weight = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_HOLDOUT(sc->type))
- weight += sc->weight;
- }
+ if (CLOSURE_IS_HOLDOUT(sc->type))
+ weight += sc->weight;
+ }
- return weight;
+ return weight;
}
/* Surface Evaluation */
-ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
- ccl_addr_space PathState *state, int path_flag)
+ccl_device void shader_eval_surface(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ int path_flag)
{
- PROFILING_INIT(kg, PROFILING_SHADER_EVAL);
-
- /* If path is being terminated, we are tracing a shadow ray or evaluating
- * emission, then we don't need to store closures. The emission and shadow
- * shader data also do not have a closure array to save GPU memory. */
- int max_closures;
- if(path_flag & (PATH_RAY_TERMINATE|PATH_RAY_SHADOW|PATH_RAY_EMISSION)) {
- max_closures = 0;
- }
- else {
- max_closures = kernel_data.integrator.max_closures;
- }
-
- sd->num_closure = 0;
- sd->num_closure_left = max_closures;
+ PROFILING_INIT(kg, PROFILING_SHADER_EVAL);
+
+ /* If path is being terminated, we are tracing a shadow ray or evaluating
+ * emission, then we don't need to store closures. The emission and shadow
+ * shader data also do not have a closure array to save GPU memory. */
+ int max_closures;
+ if (path_flag & (PATH_RAY_TERMINATE | PATH_RAY_SHADOW | PATH_RAY_EMISSION)) {
+ max_closures = 0;
+ }
+ else {
+ max_closures = kernel_data.integrator.max_closures;
+ }
+
+ sd->num_closure = 0;
+ sd->num_closure_left = max_closures;
#ifdef __OSL__
- if(kg->osl) {
- if (sd->object == OBJECT_NONE) {
- OSLShader::eval_background(kg, sd, state, path_flag);
- }
- else {
- OSLShader::eval_surface(kg, sd, state, path_flag);
- }
- }
- else
+ if (kg->osl) {
+ if (sd->object == OBJECT_NONE) {
+ OSLShader::eval_background(kg, sd, state, path_flag);
+ }
+ else {
+ OSLShader::eval_surface(kg, sd, state, path_flag);
+ }
+ }
+ else
#endif
- {
+ {
#ifdef __SVM__
- svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
+ svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
#else
- if(sd->object == OBJECT_NONE) {
- sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f);
- sd->flag |= SD_EMISSION;
- }
- else {
- DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd,
- sizeof(DiffuseBsdf),
- make_float3(0.8f, 0.8f, 0.8f));
- if(bsdf != NULL) {
- bsdf->N = sd->N;
- sd->flag |= bsdf_diffuse_setup(bsdf);
- }
- }
+ if (sd->object == OBJECT_NONE) {
+ sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f);
+ sd->flag |= SD_EMISSION;
+ }
+ else {
+ DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(
+ sd, sizeof(DiffuseBsdf), make_float3(0.8f, 0.8f, 0.8f));
+ if (bsdf != NULL) {
+ bsdf->N = sd->N;
+ sd->flag |= bsdf_diffuse_setup(bsdf);
+ }
+ }
#endif
- }
+ }
- if(sd->flag & SD_BSDF_NEEDS_LCG) {
- sd->lcg_state = lcg_state_init_addrspace(state, 0xb4bc3953);
- }
+ if (sd->flag & SD_BSDF_NEEDS_LCG) {
+ sd->lcg_state = lcg_state_init_addrspace(state, 0xb4bc3953);
+ }
}
/* Volume */
#ifdef __VOLUME__
-ccl_device_inline void _shader_volume_phase_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
- int skip_phase, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
+ccl_device_inline void _shader_volume_phase_multi_eval(const ShaderData *sd,
+ const float3 omega_in,
+ float *pdf,
+ int skip_phase,
+ BsdfEval *result_eval,
+ float sum_pdf,
+ float sum_sample_weight)
{
- for(int i = 0; i < sd->num_closure; i++) {
- if(i == skip_phase)
- continue;
+ for (int i = 0; i < sd->num_closure; i++) {
+ if (i == skip_phase)
+ continue;
- const ShaderClosure *sc = &sd->closure[i];
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_PHASE(sc->type)) {
- float phase_pdf = 0.0f;
- float3 eval = volume_phase_eval(sd, sc, omega_in, &phase_pdf);
+ if (CLOSURE_IS_PHASE(sc->type)) {
+ float phase_pdf = 0.0f;
+ float3 eval = volume_phase_eval(sd, sc, omega_in, &phase_pdf);
- if(phase_pdf != 0.0f) {
- bsdf_eval_accum(result_eval, sc->type, eval, 1.0f);
- sum_pdf += phase_pdf*sc->sample_weight;
- }
+ if (phase_pdf != 0.0f) {
+ bsdf_eval_accum(result_eval, sc->type, eval, 1.0f);
+ sum_pdf += phase_pdf * sc->sample_weight;
+ }
- sum_sample_weight += sc->sample_weight;
- }
- }
+ sum_sample_weight += sc->sample_weight;
+ }
+ }
- *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
+ *pdf = (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
}
-ccl_device void shader_volume_phase_eval(KernelGlobals *kg, const ShaderData *sd,
- const float3 omega_in, BsdfEval *eval, float *pdf)
+ccl_device void shader_volume_phase_eval(
+ KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, BsdfEval *eval, float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_EVAL);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_EVAL);
- bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
+ bsdf_eval_init(
+ eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
- _shader_volume_phase_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+ _shader_volume_phase_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
}
-ccl_device int shader_volume_phase_sample(KernelGlobals *kg, const ShaderData *sd,
- float randu, float randv, BsdfEval *phase_eval,
- float3 *omega_in, differential3 *domega_in, float *pdf)
+ccl_device int shader_volume_phase_sample(KernelGlobals *kg,
+ const ShaderData *sd,
+ float randu,
+ float randv,
+ BsdfEval *phase_eval,
+ float3 *omega_in,
+ differential3 *domega_in,
+ float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
- int sampled = 0;
+ int sampled = 0;
- if(sd->num_closure > 1) {
- /* pick a phase closure based on sample weights */
- float sum = 0.0f;
+ if (sd->num_closure > 1) {
+ /* pick a phase closure based on sample weights */
+ float sum = 0.0f;
- for(sampled = 0; sampled < sd->num_closure; sampled++) {
- const ShaderClosure *sc = &sd->closure[sampled];
+ for (sampled = 0; sampled < sd->num_closure; sampled++) {
+ const ShaderClosure *sc = &sd->closure[sampled];
- if(CLOSURE_IS_PHASE(sc->type))
- sum += sc->sample_weight;
- }
+ if (CLOSURE_IS_PHASE(sc->type))
+ sum += sc->sample_weight;
+ }
- float r = randu*sum;
- float partial_sum = 0.0f;
+ float r = randu * sum;
+ float partial_sum = 0.0f;
- for(sampled = 0; sampled < sd->num_closure; sampled++) {
- const ShaderClosure *sc = &sd->closure[sampled];
+ for (sampled = 0; sampled < sd->num_closure; sampled++) {
+ const ShaderClosure *sc = &sd->closure[sampled];
- if(CLOSURE_IS_PHASE(sc->type)) {
- float next_sum = partial_sum + sc->sample_weight;
+ if (CLOSURE_IS_PHASE(sc->type)) {
+ float next_sum = partial_sum + sc->sample_weight;
- if(r <= next_sum) {
- /* Rescale to reuse for BSDF direction sample. */
- randu = (r - partial_sum) / sc->sample_weight;
- break;
- }
+ if (r <= next_sum) {
+ /* Rescale to reuse for BSDF direction sample. */
+ randu = (r - partial_sum) / sc->sample_weight;
+ break;
+ }
- partial_sum = next_sum;
- }
- }
+ partial_sum = next_sum;
+ }
+ }
- if(sampled == sd->num_closure) {
- *pdf = 0.0f;
- return LABEL_NONE;
- }
- }
+ if (sampled == sd->num_closure) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+ }
- /* todo: this isn't quite correct, we don't weight anisotropy properly
- * depending on color channels, even if this is perhaps not a common case */
- const ShaderClosure *sc = &sd->closure[sampled];
- int label;
- float3 eval;
+ /* todo: this isn't quite correct, we don't weight anisotropy properly
+ * depending on color channels, even if this is perhaps not a common case */
+ const ShaderClosure *sc = &sd->closure[sampled];
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f) {
- bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
- }
+ if (*pdf != 0.0f) {
+ bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
+ }
- return label;
+ return label;
}
-ccl_device int shader_phase_sample_closure(KernelGlobals *kg, const ShaderData *sd,
- const ShaderClosure *sc, float randu, float randv, BsdfEval *phase_eval,
- float3 *omega_in, differential3 *domega_in, float *pdf)
+ccl_device int shader_phase_sample_closure(KernelGlobals *kg,
+ const ShaderData *sd,
+ const ShaderClosure *sc,
+ float randu,
+ float randv,
+ BsdfEval *phase_eval,
+ float3 *omega_in,
+ differential3 *domega_in,
+ float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
- int label;
- float3 eval;
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f)
- bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
+ if (*pdf != 0.0f)
+ bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
- return label;
+ return label;
}
/* Volume Evaluation */
@@ -1228,83 +1267,85 @@ ccl_device_inline void shader_eval_volume(KernelGlobals *kg,
ccl_addr_space VolumeStack *stack,
int path_flag)
{
- /* If path is being terminated, we are tracing a shadow ray or evaluating
- * emission, then we don't need to store closures. The emission and shadow
- * shader data also do not have a closure array to save GPU memory. */
- int max_closures;
- if(path_flag & (PATH_RAY_TERMINATE|PATH_RAY_SHADOW|PATH_RAY_EMISSION)) {
- max_closures = 0;
- }
- else {
- max_closures = kernel_data.integrator.max_closures;
- }
-
- /* reset closures once at the start, we will be accumulating the closures
- * for all volumes in the stack into a single array of closures */
- sd->num_closure = 0;
- sd->num_closure_left = max_closures;
- sd->flag = 0;
- sd->object_flag = 0;
-
- for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
- /* setup shaderdata from stack. it's mostly setup already in
- * shader_setup_from_volume, this switching should be quick */
- sd->object = stack[i].object;
- sd->lamp = LAMP_NONE;
- sd->shader = stack[i].shader;
-
- sd->flag &= ~SD_SHADER_FLAGS;
- sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
- sd->object_flag &= ~SD_OBJECT_FLAGS;
-
- if(sd->object != OBJECT_NONE) {
- sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
-
-#ifdef __OBJECT_MOTION__
- /* todo: this is inefficient for motion blur, we should be
- * caching matrices instead of recomputing them each step */
- shader_setup_object_transforms(kg, sd, sd->time);
-#endif
- }
-
- /* evaluate shader */
-#ifdef __SVM__
-# ifdef __OSL__
- if(kg->osl) {
- OSLShader::eval_volume(kg, sd, state, path_flag);
- }
- else
+ /* If path is being terminated, we are tracing a shadow ray or evaluating
+ * emission, then we don't need to store closures. The emission and shadow
+ * shader data also do not have a closure array to save GPU memory. */
+ int max_closures;
+ if (path_flag & (PATH_RAY_TERMINATE | PATH_RAY_SHADOW | PATH_RAY_EMISSION)) {
+ max_closures = 0;
+ }
+ else {
+ max_closures = kernel_data.integrator.max_closures;
+ }
+
+ /* reset closures once at the start, we will be accumulating the closures
+ * for all volumes in the stack into a single array of closures */
+ sd->num_closure = 0;
+ sd->num_closure_left = max_closures;
+ sd->flag = 0;
+ sd->object_flag = 0;
+
+ for (int i = 0; stack[i].shader != SHADER_NONE; i++) {
+ /* setup shaderdata from stack. it's mostly setup already in
+ * shader_setup_from_volume, this switching should be quick */
+ sd->object = stack[i].object;
+ sd->lamp = LAMP_NONE;
+ sd->shader = stack[i].shader;
+
+ sd->flag &= ~SD_SHADER_FLAGS;
+ sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->object_flag &= ~SD_OBJECT_FLAGS;
+
+ if (sd->object != OBJECT_NONE) {
+ sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
+
+# ifdef __OBJECT_MOTION__
+ /* todo: this is inefficient for motion blur, we should be
+ * caching matrices instead of recomputing them each step */
+ shader_setup_object_transforms(kg, sd, sd->time);
+# endif
+ }
+
+ /* evaluate shader */
+# ifdef __SVM__
+# ifdef __OSL__
+ if (kg->osl) {
+ OSLShader::eval_volume(kg, sd, state, path_flag);
+ }
+ else
+# endif
+ {
+ svm_eval_nodes(kg, sd, state, SHADER_TYPE_VOLUME, path_flag);
+ }
# endif
- {
- svm_eval_nodes(kg, sd, state, SHADER_TYPE_VOLUME, path_flag);
- }
-#endif
- /* merge closures to avoid exceeding number of closures limit */
- if(i > 0)
- shader_merge_closures(sd);
- }
+ /* merge closures to avoid exceeding number of closures limit */
+ if (i > 0)
+ shader_merge_closures(sd);
+ }
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
/* Displacement Evaluation */
-ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state)
+ccl_device void shader_eval_displacement(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state)
{
- sd->num_closure = 0;
- sd->num_closure_left = 0;
+ sd->num_closure = 0;
+ sd->num_closure_left = 0;
- /* this will modify sd->P */
+ /* this will modify sd->P */
#ifdef __SVM__
# ifdef __OSL__
- if(kg->osl)
- OSLShader::eval_displacement(kg, sd, state);
- else
+ if (kg->osl)
+ OSLShader::eval_displacement(kg, sd, state);
+ else
# endif
- {
- svm_eval_nodes(kg, sd, state, SHADER_TYPE_DISPLACEMENT, 0);
- }
+ {
+ svm_eval_nodes(kg, sd, state, SHADER_TYPE_DISPLACEMENT, 0);
+ }
#endif
}
@@ -1313,29 +1354,29 @@ ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ccl_
#ifdef __TRANSPARENT_SHADOWS__
ccl_device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
{
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- int shader = 0;
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ int shader = 0;
-#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
-#endif
- shader = kernel_tex_fetch(__tri_shader, prim);
-#ifdef __HAIR__
- }
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
-#endif
- int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+# ifdef __HAIR__
+ if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
+# endif
+ shader = kernel_tex_fetch(__tri_shader, prim);
+# ifdef __HAIR__
+ }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+# endif
+ int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
- return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
+ return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
}
-#endif /* __TRANSPARENT_SHADOWS__ */
+#endif /* __TRANSPARENT_SHADOWS__ */
ccl_device float shader_cryptomatte_id(KernelGlobals *kg, int shader)
{
- return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).cryptomatte_id;
+ return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).cryptomatte_id;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index fafa3ad4bfa..6af1369feab 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
typedef struct VolumeState {
# ifdef __SPLIT_KERNEL__
# else
- PathState ps;
+ PathState ps;
# endif
} VolumeState;
@@ -28,77 +28,70 @@ typedef struct VolumeState {
# ifdef __SPLIT_KERNEL__
ccl_addr_space
# endif
-ccl_device_inline PathState *shadow_blocked_volume_path_state(
- KernelGlobals *kg,
- VolumeState *volume_state,
- ccl_addr_space PathState *state,
- ShaderData *sd,
- Ray *ray)
+ ccl_device_inline PathState *
+ shadow_blocked_volume_path_state(KernelGlobals *kg,
+ VolumeState *volume_state,
+ ccl_addr_space PathState *state,
+ ShaderData *sd,
+ Ray *ray)
{
# ifdef __SPLIT_KERNEL__
- ccl_addr_space PathState *ps =
- &kernel_split_state.state_shadow[ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0)];
+ ccl_addr_space PathState *ps =
+ &kernel_split_state.state_shadow[ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0)];
# else
- PathState *ps = &volume_state->ps;
+ PathState *ps = &volume_state->ps;
# endif
- *ps = *state;
- /* We are checking for shadow on the "other" side of the surface, so need
- * to discard volume we are currently at.
- */
- if(dot(sd->Ng, ray->D) < 0.0f) {
- kernel_volume_stack_enter_exit(kg, sd, ps->volume_stack);
- }
- return ps;
+ *ps = *state;
+ /* We are checking for shadow on the "other" side of the surface, so need
+ * to discard volume we are currently at.
+ */
+ if (dot(sd->Ng, ray->D) < 0.0f) {
+ kernel_volume_stack_enter_exit(kg, sd, ps->volume_stack);
+ }
+ return ps;
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
/* Attenuate throughput accordingly to the given intersection event.
* Returns true if the throughput is zero and traversal can be aborted.
*/
ccl_device_forceinline bool shadow_handle_transparent_isect(
- KernelGlobals *kg,
- ShaderData *shadow_sd,
- ccl_addr_space PathState *state,
-# ifdef __VOLUME__
- ccl_addr_space struct PathState *volume_state,
-# endif
- Intersection *isect,
- Ray *ray,
- float3 *throughput)
+ KernelGlobals *kg,
+ ShaderData *shadow_sd,
+ ccl_addr_space PathState *state,
+#ifdef __VOLUME__
+ ccl_addr_space struct PathState *volume_state,
+#endif
+ Intersection *isect,
+ Ray *ray,
+ float3 *throughput)
{
#ifdef __VOLUME__
- /* Attenuation between last surface and next surface. */
- if(volume_state->volume_stack[0].shader != SHADER_NONE) {
- Ray segment_ray = *ray;
- segment_ray.t = isect->t;
- kernel_volume_shadow(kg,
- shadow_sd,
- volume_state,
- &segment_ray,
- throughput);
- }
+ /* Attenuation between last surface and next surface. */
+ if (volume_state->volume_stack[0].shader != SHADER_NONE) {
+ Ray segment_ray = *ray;
+ segment_ray.t = isect->t;
+ kernel_volume_shadow(kg, shadow_sd, volume_state, &segment_ray, throughput);
+ }
#endif
- /* Setup shader data at surface. */
- shader_setup_from_ray(kg, shadow_sd, isect, ray);
- /* Attenuation from transparent surface. */
- if(!(shadow_sd->flag & SD_HAS_ONLY_VOLUME)) {
- path_state_modify_bounce(state, true);
- shader_eval_surface(kg,
- shadow_sd,
- state,
- PATH_RAY_SHADOW);
- path_state_modify_bounce(state, false);
- *throughput *= shader_bsdf_transparency(kg, shadow_sd);
- }
- /* Stop if all light is blocked. */
- if(is_zero(*throughput)) {
- return true;
- }
+ /* Setup shader data at surface. */
+ shader_setup_from_ray(kg, shadow_sd, isect, ray);
+ /* Attenuation from transparent surface. */
+ if (!(shadow_sd->flag & SD_HAS_ONLY_VOLUME)) {
+ path_state_modify_bounce(state, true);
+ shader_eval_surface(kg, shadow_sd, state, PATH_RAY_SHADOW);
+ path_state_modify_bounce(state, false);
+ *throughput *= shader_bsdf_transparency(kg, shadow_sd);
+ }
+ /* Stop if all light is blocked. */
+ if (is_zero(*throughput)) {
+ return true;
+ }
#ifdef __VOLUME__
- /* Exit/enter volume. */
- kernel_volume_stack_enter_exit(kg, shadow_sd, volume_state->volume_stack);
+ /* Exit/enter volume. */
+ kernel_volume_stack_enter_exit(kg, shadow_sd, volume_state->volume_stack);
#endif
- return false;
+ return false;
}
/* Special version which only handles opaque shadows. */
@@ -110,19 +103,15 @@ ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
Intersection *isect,
float3 *shadow)
{
- const bool blocked = scene_intersect(kg,
- *ray,
- visibility & PATH_RAY_SHADOW_OPAQUE,
- isect,
- NULL,
- 0.0f, 0.0f);
+ const bool blocked = scene_intersect(
+ kg, *ray, visibility & PATH_RAY_SHADOW_OPAQUE, isect, NULL, 0.0f, 0.0f);
#ifdef __VOLUME__
- if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
- /* Apply attenuation from current volume shader. */
- kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
- }
+ if (!blocked && state->volume_stack[0].shader != SHADER_NONE) {
+ /* Apply attenuation from current volume shader. */
+ kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
+ }
#endif
- return blocked;
+ return blocked;
}
#ifdef __TRANSPARENT_SHADOWS__
@@ -169,94 +158,80 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
uint max_hits,
float3 *shadow)
{
- /* Intersect to find an opaque surface, or record all transparent
- * surface hits.
- */
- uint num_hits;
- const bool blocked = scene_intersect_shadow_all(kg,
- ray,
- hits,
- visibility,
- max_hits,
- &num_hits);
+ /* Intersect to find an opaque surface, or record all transparent
+ * surface hits.
+ */
+ uint num_hits;
+ const bool blocked = scene_intersect_shadow_all(kg, ray, hits, visibility, max_hits, &num_hits);
# ifdef __VOLUME__
- VolumeState volume_state;
+ VolumeState volume_state;
# endif
- /* If no opaque surface found but we did find transparent hits,
- * shade them.
- */
- if(!blocked && num_hits > 0) {
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- float3 Pend = ray->P + ray->D*ray->t;
- float last_t = 0.0f;
- int bounce = state->transparent_bounce;
- Intersection *isect = hits;
+ /* If no opaque surface found but we did find transparent hits,
+ * shade them.
+ */
+ if (!blocked && num_hits > 0) {
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ float3 Pend = ray->P + ray->D * ray->t;
+ float last_t = 0.0f;
+ int bounce = state->transparent_bounce;
+ Intersection *isect = hits;
# ifdef __VOLUME__
# ifdef __SPLIT_KERNEL__
- ccl_addr_space
+ ccl_addr_space
# endif
- PathState *ps = shadow_blocked_volume_path_state(kg,
- &volume_state,
- state,
- sd,
- ray);
+ PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
# endif
- sort_intersections(hits, num_hits);
- for(int hit = 0; hit < num_hits; hit++, isect++) {
- /* Adjust intersection distance for moving ray forward. */
- float new_t = isect->t;
- isect->t -= last_t;
- /* Skip hit if we did not move forward, step by step raytracing
- * would have skipped it as well then.
- */
- if(last_t == new_t) {
- continue;
- }
- last_t = new_t;
- /* Attenuate the throughput. */
- if(shadow_handle_transparent_isect(kg,
- shadow_sd,
- state,
-#ifdef __VOLUME__
- ps,
-#endif
- isect,
- ray,
- &throughput))
- {
- return true;
- }
- /* Move ray forward. */
- ray->P = shadow_sd->P;
- if(ray->t != FLT_MAX) {
- ray->D = normalize_len(Pend - ray->P, &ray->t);
- }
- bounce++;
- }
+ sort_intersections(hits, num_hits);
+ for (int hit = 0; hit < num_hits; hit++, isect++) {
+ /* Adjust intersection distance for moving ray forward. */
+ float new_t = isect->t;
+ isect->t -= last_t;
+ /* Skip hit if we did not move forward, step by step raytracing
+ * would have skipped it as well then.
+ */
+ if (last_t == new_t) {
+ continue;
+ }
+ last_t = new_t;
+ /* Attenuate the throughput. */
+ if (shadow_handle_transparent_isect(kg,
+ shadow_sd,
+ state,
# ifdef __VOLUME__
- /* Attenuation for last line segment towards light. */
- if(ps->volume_stack[0].shader != SHADER_NONE) {
- kernel_volume_shadow(kg, shadow_sd, ps, ray, &throughput);
- }
+ ps,
# endif
- *shadow = throughput;
- return is_zero(throughput);
- }
+ isect,
+ ray,
+ &throughput)) {
+ return true;
+ }
+ /* Move ray forward. */
+ ray->P = shadow_sd->P;
+ if (ray->t != FLT_MAX) {
+ ray->D = normalize_len(Pend - ray->P, &ray->t);
+ }
+ bounce++;
+ }
# ifdef __VOLUME__
- if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
- /* Apply attenuation from current volume shader. */
+ /* Attenuation for last line segment towards light. */
+ if (ps->volume_stack[0].shader != SHADER_NONE) {
+ kernel_volume_shadow(kg, shadow_sd, ps, ray, &throughput);
+ }
+# endif
+ *shadow = throughput;
+ return is_zero(throughput);
+ }
+# ifdef __VOLUME__
+ if (!blocked && state->volume_stack[0].shader != SHADER_NONE) {
+ /* Apply attenuation from current volume shader. */
# ifdef __SPLIT_KERNEL__
- ccl_addr_space
+ ccl_addr_space
# endif
- PathState *ps = shadow_blocked_volume_path_state(kg,
- &volume_state,
- state,
- sd,
- ray);
- kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
- }
+ PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
+ kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
+ }
# endif
- return blocked;
+ return blocked;
}
/* Here we do all device specific trickery before invoking actual traversal
@@ -272,43 +247,36 @@ ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
float3 *shadow)
{
# ifdef __SPLIT_KERNEL__
- Intersection hits_[SHADOW_STACK_MAX_HITS];
- Intersection *hits = &hits_[0];
+ Intersection hits_[SHADOW_STACK_MAX_HITS];
+ Intersection *hits = &hits_[0];
# elif defined(__KERNEL_CUDA__)
- Intersection *hits = kg->hits_stack;
+ Intersection *hits = kg->hits_stack;
# else
- Intersection hits_stack[SHADOW_STACK_MAX_HITS];
- Intersection *hits = hits_stack;
+ Intersection hits_stack[SHADOW_STACK_MAX_HITS];
+ Intersection *hits = hits_stack;
# endif
# ifndef __KERNEL_GPU__
- /* Prefer to use stack but use dynamic allocation if too deep max hits
- * we need max_hits + 1 storage space due to the logic in
- * scene_intersect_shadow_all which will first store and then check if
- * the limit is exceeded.
- *
- * Ignore this on GPU because of slow/unavailable malloc().
- */
- if(max_hits + 1 > SHADOW_STACK_MAX_HITS) {
- if(kg->transparent_shadow_intersections == NULL) {
- const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
- kg->transparent_shadow_intersections =
- (Intersection*)malloc(sizeof(Intersection)*(transparent_max_bounce + 1));
- }
- hits = kg->transparent_shadow_intersections;
- }
-# endif /* __KERNEL_GPU__ */
- /* Invoke actual traversal. */
- return shadow_blocked_transparent_all_loop(kg,
- sd,
- shadow_sd,
- state,
- visibility,
- ray,
- hits,
- max_hits,
- shadow);
+ /* Prefer to use stack but use dynamic allocation if too deep max hits
+ * we need max_hits + 1 storage space due to the logic in
+ * scene_intersect_shadow_all which will first store and then check if
+ * the limit is exceeded.
+ *
+ * Ignore this on GPU because of slow/unavailable malloc().
+ */
+ if (max_hits + 1 > SHADOW_STACK_MAX_HITS) {
+ if (kg->transparent_shadow_intersections == NULL) {
+ const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
+ kg->transparent_shadow_intersections = (Intersection *)malloc(sizeof(Intersection) *
+ (transparent_max_bounce + 1));
+ }
+ hits = kg->transparent_shadow_intersections;
+ }
+# endif /* __KERNEL_GPU__ */
+ /* Invoke actual traversal. */
+ return shadow_blocked_transparent_all_loop(
+ kg, sd, shadow_sd, state, visibility, ray, hits, max_hits, shadow);
}
-# endif /* __SHADOW_RECORD_ALL__ */
+# endif /* __SHADOW_RECORD_ALL__ */
# if defined(__KERNEL_GPU__) || !defined(__SHADOW_RECORD_ALL__)
/* Shadow function to compute how much light is blocked,
@@ -323,130 +291,100 @@ ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
/* This function is only implementing device-independent traversal logic
* which requires some precalculation done.
*/
-ccl_device bool shadow_blocked_transparent_stepped_loop(
- KernelGlobals *kg,
- ShaderData *sd,
- ShaderData *shadow_sd,
- ccl_addr_space PathState *state,
- const uint visibility,
- Ray *ray,
- Intersection *isect,
- const bool blocked,
- const bool is_transparent_isect,
- float3 *shadow)
+ccl_device bool shadow_blocked_transparent_stepped_loop(KernelGlobals *kg,
+ ShaderData *sd,
+ ShaderData *shadow_sd,
+ ccl_addr_space PathState *state,
+ const uint visibility,
+ Ray *ray,
+ Intersection *isect,
+ const bool blocked,
+ const bool is_transparent_isect,
+ float3 *shadow)
{
# ifdef __VOLUME__
- VolumeState volume_state;
+ VolumeState volume_state;
# endif
- if(blocked && is_transparent_isect) {
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- float3 Pend = ray->P + ray->D*ray->t;
- int bounce = state->transparent_bounce;
+ if (blocked && is_transparent_isect) {
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ float3 Pend = ray->P + ray->D * ray->t;
+ int bounce = state->transparent_bounce;
# ifdef __VOLUME__
# ifdef __SPLIT_KERNEL__
- ccl_addr_space
+ ccl_addr_space
# endif
- PathState *ps = shadow_blocked_volume_path_state(kg,
- &volume_state,
- state,
- sd,
- ray);
+ PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
# endif
- for(;;) {
- if(bounce >= kernel_data.integrator.transparent_max_bounce) {
- return true;
- }
- if(!scene_intersect(kg,
- *ray,
- visibility & PATH_RAY_SHADOW_TRANSPARENT,
- isect,
- NULL,
- 0.0f, 0.0f))
- {
- break;
- }
- if(!shader_transparent_shadow(kg, isect)) {
- return true;
- }
- /* Attenuate the throughput. */
- if(shadow_handle_transparent_isect(kg,
- shadow_sd,
- state,
-#ifdef __VOLUME__
- ps,
-#endif
- isect,
- ray,
- &throughput))
- {
- return true;
- }
- /* Move ray forward. */
- ray->P = ray_offset(shadow_sd->P, -shadow_sd->Ng);
- if(ray->t != FLT_MAX) {
- ray->D = normalize_len(Pend - ray->P, &ray->t);
- }
- bounce++;
- }
+ for (;;) {
+ if (bounce >= kernel_data.integrator.transparent_max_bounce) {
+ return true;
+ }
+ if (!scene_intersect(
+ kg, *ray, visibility & PATH_RAY_SHADOW_TRANSPARENT, isect, NULL, 0.0f, 0.0f)) {
+ break;
+ }
+ if (!shader_transparent_shadow(kg, isect)) {
+ return true;
+ }
+ /* Attenuate the throughput. */
+ if (shadow_handle_transparent_isect(kg,
+ shadow_sd,
+ state,
+# ifdef __VOLUME__
+ ps,
+# endif
+ isect,
+ ray,
+ &throughput)) {
+ return true;
+ }
+ /* Move ray forward. */
+ ray->P = ray_offset(shadow_sd->P, -shadow_sd->Ng);
+ if (ray->t != FLT_MAX) {
+ ray->D = normalize_len(Pend - ray->P, &ray->t);
+ }
+ bounce++;
+ }
# ifdef __VOLUME__
- /* Attenuation for last line segment towards light. */
- if(ps->volume_stack[0].shader != SHADER_NONE) {
- kernel_volume_shadow(kg, shadow_sd, ps, ray, &throughput);
- }
+ /* Attenuation for last line segment towards light. */
+ if (ps->volume_stack[0].shader != SHADER_NONE) {
+ kernel_volume_shadow(kg, shadow_sd, ps, ray, &throughput);
+ }
# endif
- *shadow *= throughput;
- return is_zero(throughput);
- }
+ *shadow *= throughput;
+ return is_zero(throughput);
+ }
# ifdef __VOLUME__
- if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
- /* Apply attenuation from current volume shader. */
+ if (!blocked && state->volume_stack[0].shader != SHADER_NONE) {
+ /* Apply attenuation from current volume shader. */
# ifdef __SPLIT_KERNEL__
- ccl_addr_space
+ ccl_addr_space
# endif
- PathState *ps = shadow_blocked_volume_path_state(kg,
- &volume_state,
- state,
- sd,
- ray);
- kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
- }
+ PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
+ kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
+ }
# endif
- return blocked;
+ return blocked;
}
-ccl_device bool shadow_blocked_transparent_stepped(
- KernelGlobals *kg,
- ShaderData *sd,
- ShaderData *shadow_sd,
- ccl_addr_space PathState *state,
- const uint visibility,
- Ray *ray,
- Intersection *isect,
- float3 *shadow)
+ccl_device bool shadow_blocked_transparent_stepped(KernelGlobals *kg,
+ ShaderData *sd,
+ ShaderData *shadow_sd,
+ ccl_addr_space PathState *state,
+ const uint visibility,
+ Ray *ray,
+ Intersection *isect,
+ float3 *shadow)
{
- bool blocked = scene_intersect(kg,
- *ray,
- visibility & PATH_RAY_SHADOW_OPAQUE,
- isect,
- NULL,
- 0.0f, 0.0f);
- bool is_transparent_isect = blocked
- ? shader_transparent_shadow(kg, isect)
- : false;
- return shadow_blocked_transparent_stepped_loop(kg,
- sd,
- shadow_sd,
- state,
- visibility,
- ray,
- isect,
- blocked,
- is_transparent_isect,
- shadow);
+ bool blocked = scene_intersect(
+ kg, *ray, visibility & PATH_RAY_SHADOW_OPAQUE, isect, NULL, 0.0f, 0.0f);
+ bool is_transparent_isect = blocked ? shader_transparent_shadow(kg, isect) : false;
+ return shadow_blocked_transparent_stepped_loop(
+ kg, sd, shadow_sd, state, visibility, ray, isect, blocked, is_transparent_isect, shadow);
}
-# endif /* __KERNEL_GPU__ || !__SHADOW_RECORD_ALL__ */
-#endif /* __TRANSPARENT_SHADOWS__ */
+# endif /* __KERNEL_GPU__ || !__SHADOW_RECORD_ALL__ */
+#endif /* __TRANSPARENT_SHADOWS__ */
ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
ShaderData *sd,
@@ -455,100 +393,65 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
Ray *ray_input,
float3 *shadow)
{
- Ray *ray = ray_input;
- Intersection isect;
- /* Some common early checks. */
- *shadow = make_float3(1.0f, 1.0f, 1.0f);
- if(ray->t == 0.0f) {
- return false;
- }
+ Ray *ray = ray_input;
+ Intersection isect;
+ /* Some common early checks. */
+ *shadow = make_float3(1.0f, 1.0f, 1.0f);
+ if (ray->t == 0.0f) {
+ return false;
+ }
#ifdef __SHADOW_TRICKS__
- const uint visibility = (state->flag & PATH_RAY_SHADOW_CATCHER)
- ? PATH_RAY_SHADOW_NON_CATCHER
- : PATH_RAY_SHADOW;
+ const uint visibility = (state->flag & PATH_RAY_SHADOW_CATCHER) ? PATH_RAY_SHADOW_NON_CATCHER :
+ PATH_RAY_SHADOW;
#else
- const uint visibility = PATH_RAY_SHADOW;
+ const uint visibility = PATH_RAY_SHADOW;
#endif
- /* Do actual shadow shading. */
- /* First of all, we check if integrator requires transparent shadows.
- * if not, we use simplest and fastest ever way to calculate occlusion.
- */
+ /* Do actual shadow shading. */
+ /* First of all, we check if integrator requires transparent shadows.
+ * if not, we use simplest and fastest ever way to calculate occlusion.
+ */
#ifdef __TRANSPARENT_SHADOWS__
- if(!kernel_data.integrator.transparent_shadows)
+ if (!kernel_data.integrator.transparent_shadows)
#endif
- {
- return shadow_blocked_opaque(kg,
- shadow_sd,
- state,
- visibility,
- ray,
- &isect,
- shadow);
- }
+ {
+ return shadow_blocked_opaque(kg, shadow_sd, state, visibility, ray, &isect, shadow);
+ }
#ifdef __TRANSPARENT_SHADOWS__
# ifdef __SHADOW_RECORD_ALL__
- /* For the transparent shadows we try to use record-all logic on the
- * devices which supports this.
- */
- const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
- /* Check transparent bounces here, for volume scatter which can do
- * lighting before surface path termination is checked.
- */
- if(state->transparent_bounce >= transparent_max_bounce) {
- return true;
- }
- const uint max_hits = transparent_max_bounce - state->transparent_bounce - 1;
+ /* For the transparent shadows we try to use record-all logic on the
+ * devices which supports this.
+ */
+ const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
+ /* Check transparent bounces here, for volume scatter which can do
+ * lighting before surface path termination is checked.
+ */
+ if (state->transparent_bounce >= transparent_max_bounce) {
+ return true;
+ }
+ const uint max_hits = transparent_max_bounce - state->transparent_bounce - 1;
# ifdef __KERNEL_GPU__
- /* On GPU we do trickey with tracing opaque ray first, this avoids speed
- * regressions in some files.
- *
- * TODO(sergey): Check why using record-all behavior causes slowdown in such
- * cases. Could that be caused by a higher spill pressure?
- */
- const bool blocked = scene_intersect(kg,
- *ray,
- visibility & PATH_RAY_SHADOW_OPAQUE,
- &isect,
- NULL,
- 0.0f, 0.0f);
- const bool is_transparent_isect = blocked
- ? shader_transparent_shadow(kg, &isect)
- : false;
- if(!blocked || !is_transparent_isect ||
- max_hits + 1 >= SHADOW_STACK_MAX_HITS)
- {
- return shadow_blocked_transparent_stepped_loop(kg,
- sd,
- shadow_sd,
- state,
- visibility,
- ray,
- &isect,
- blocked,
- is_transparent_isect,
- shadow);
- }
-# endif /* __KERNEL_GPU__ */
- return shadow_blocked_transparent_all(kg,
- sd,
- shadow_sd,
- state,
- visibility,
- ray,
- max_hits,
- shadow);
+ /* On GPU we do trickey with tracing opaque ray first, this avoids speed
+ * regressions in some files.
+ *
+ * TODO(sergey): Check why using record-all behavior causes slowdown in such
+ * cases. Could that be caused by a higher spill pressure?
+ */
+ const bool blocked = scene_intersect(
+ kg, *ray, visibility & PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
+ const bool is_transparent_isect = blocked ? shader_transparent_shadow(kg, &isect) : false;
+ if (!blocked || !is_transparent_isect || max_hits + 1 >= SHADOW_STACK_MAX_HITS) {
+ return shadow_blocked_transparent_stepped_loop(
+ kg, sd, shadow_sd, state, visibility, ray, &isect, blocked, is_transparent_isect, shadow);
+ }
+# endif /* __KERNEL_GPU__ */
+ return shadow_blocked_transparent_all(
+ kg, sd, shadow_sd, state, visibility, ray, max_hits, shadow);
# else /* __SHADOW_RECORD_ALL__ */
- /* Fallback to a slowest version which works on all devices. */
- return shadow_blocked_transparent_stepped(kg,
- sd,
- shadow_sd,
- state,
- visibility,
- ray,
- &isect,
- shadow);
-# endif /* __SHADOW_RECORD_ALL__ */
-#endif /* __TRANSPARENT_SHADOWS__ */
+ /* Fallback to a slowest version which works on all devices. */
+ return shadow_blocked_transparent_stepped(
+ kg, sd, shadow_sd, state, visibility, ray, &isect, shadow);
+# endif /* __SHADOW_RECORD_ALL__ */
+#endif /* __TRANSPARENT_SHADOWS__ */
}
#undef SHADOW_STACK_MAX_HITS
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index 96b717530ce..7510e50a962 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -22,317 +22,295 @@ CCL_NAMESPACE_BEGIN
* http://library.imageworks.com/pdfs/imageworks-library-BSSRDF-sampling.pdf
*/
-ccl_device_inline float3 subsurface_scatter_eval(ShaderData *sd,
- const ShaderClosure *sc,
- float disk_r,
- float r,
- bool all)
+ccl_device_inline float3
+subsurface_scatter_eval(ShaderData *sd, const ShaderClosure *sc, float disk_r, float r, bool all)
{
- /* this is the veach one-sample model with balance heuristic, some pdf
- * factors drop out when using balance heuristic weighting */
- float3 eval_sum = make_float3(0.0f, 0.0f, 0.0f);
- float pdf_sum = 0.0f;
- float sample_weight_inv = 0.0f;
+ /* this is the veach one-sample model with balance heuristic, some pdf
+ * factors drop out when using balance heuristic weighting */
+ float3 eval_sum = make_float3(0.0f, 0.0f, 0.0f);
+ float pdf_sum = 0.0f;
+ float sample_weight_inv = 0.0f;
- if(!all) {
- float sample_weight_sum = 0.0f;
+ if (!all) {
+ float sample_weight_sum = 0.0f;
- for(int i = 0; i < sd->num_closure; i++) {
- sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ sc = &sd->closure[i];
- if(CLOSURE_IS_DISK_BSSRDF(sc->type)) {
- sample_weight_sum += sc->sample_weight;
- }
- }
+ if (CLOSURE_IS_DISK_BSSRDF(sc->type)) {
+ sample_weight_sum += sc->sample_weight;
+ }
+ }
- sample_weight_inv = 1.0f/sample_weight_sum;
- }
+ sample_weight_inv = 1.0f / sample_weight_sum;
+ }
- for(int i = 0; i < sd->num_closure; i++) {
- sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ sc = &sd->closure[i];
- if(CLOSURE_IS_DISK_BSSRDF(sc->type)) {
- /* in case of branched path integrate we sample all bssrdf's once,
- * for path trace we pick one, so adjust pdf for that */
- float sample_weight = (all)? 1.0f: sc->sample_weight * sample_weight_inv;
+ if (CLOSURE_IS_DISK_BSSRDF(sc->type)) {
+ /* in case of branched path integrate we sample all bssrdf's once,
+ * for path trace we pick one, so adjust pdf for that */
+ float sample_weight = (all) ? 1.0f : sc->sample_weight * sample_weight_inv;
- /* compute pdf */
- float3 eval = bssrdf_eval(sc, r);
- float pdf = bssrdf_pdf(sc, disk_r);
+ /* compute pdf */
+ float3 eval = bssrdf_eval(sc, r);
+ float pdf = bssrdf_pdf(sc, disk_r);
- eval_sum += sc->weight * eval;
- pdf_sum += sample_weight * pdf;
- }
- }
+ eval_sum += sc->weight * eval;
+ pdf_sum += sample_weight * pdf;
+ }
+ }
- return (pdf_sum > 0.0f)? eval_sum / pdf_sum : make_float3(0.0f, 0.0f, 0.0f);
+ return (pdf_sum > 0.0f) ? eval_sum / pdf_sum : make_float3(0.0f, 0.0f, 0.0f);
}
/* replace closures with a single diffuse bsdf closure after scatter step */
-ccl_device void subsurface_scatter_setup_diffuse_bsdf(KernelGlobals *kg, ShaderData *sd, ClosureType type, float roughness, float3 weight, float3 N)
+ccl_device void subsurface_scatter_setup_diffuse_bsdf(
+ KernelGlobals *kg, ShaderData *sd, ClosureType type, float roughness, float3 weight, float3 N)
{
- sd->flag &= ~SD_CLOSURE_FLAGS;
- sd->num_closure = 0;
- sd->num_closure_left = kernel_data.integrator.max_closures;
+ sd->flag &= ~SD_CLOSURE_FLAGS;
+ sd->num_closure = 0;
+ sd->num_closure_left = kernel_data.integrator.max_closures;
#ifdef __PRINCIPLED__
- if(type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
- type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
- {
- PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->roughness = roughness;
- sd->flag |= bsdf_principled_diffuse_setup(bsdf);
-
- /* replace CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID with this special ID so render passes
- * can recognize it as not being a regular Disney principled diffuse closure */
- bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID;
- }
- }
- else if(CLOSURE_IS_BSDF_BSSRDF(type) ||
- CLOSURE_IS_BSSRDF(type))
-#endif /* __PRINCIPLED__ */
- {
- DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
- sd->flag |= bsdf_diffuse_setup(bsdf);
-
- /* replace CLOSURE_BSDF_DIFFUSE_ID with this special ID so render passes
- * can recognize it as not being a regular diffuse closure */
- bsdf->type = CLOSURE_BSDF_BSSRDF_ID;
- }
- }
+ if (type == CLOSURE_BSSRDF_PRINCIPLED_ID || type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) {
+ PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc(
+ sd, sizeof(PrincipledDiffuseBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->roughness = roughness;
+ sd->flag |= bsdf_principled_diffuse_setup(bsdf);
+
+ /* replace CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID with this special ID so render passes
+ * can recognize it as not being a regular Disney principled diffuse closure */
+ bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID;
+ }
+ }
+ else if (CLOSURE_IS_BSDF_BSSRDF(type) || CLOSURE_IS_BSSRDF(type))
+#endif /* __PRINCIPLED__ */
+ {
+ DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ sd->flag |= bsdf_diffuse_setup(bsdf);
+
+ /* replace CLOSURE_BSDF_DIFFUSE_ID with this special ID so render passes
+ * can recognize it as not being a regular diffuse closure */
+ bsdf->type = CLOSURE_BSDF_BSSRDF_ID;
+ }
+ }
}
/* optionally do blurring of color and/or bump mapping, at the cost of a shader evaluation */
ccl_device float3 subsurface_color_pow(float3 color, float exponent)
{
- color = max(color, make_float3(0.0f, 0.0f, 0.0f));
-
- if(exponent == 1.0f) {
- /* nothing to do */
- }
- else if(exponent == 0.5f) {
- color.x = sqrtf(color.x);
- color.y = sqrtf(color.y);
- color.z = sqrtf(color.z);
- }
- else {
- color.x = powf(color.x, exponent);
- color.y = powf(color.y, exponent);
- color.z = powf(color.z, exponent);
- }
-
- return color;
+ color = max(color, make_float3(0.0f, 0.0f, 0.0f));
+
+ if (exponent == 1.0f) {
+ /* nothing to do */
+ }
+ else if (exponent == 0.5f) {
+ color.x = sqrtf(color.x);
+ color.y = sqrtf(color.y);
+ color.z = sqrtf(color.z);
+ }
+ else {
+ color.x = powf(color.x, exponent);
+ color.y = powf(color.y, exponent);
+ color.z = powf(color.z, exponent);
+ }
+
+ return color;
}
-ccl_device void subsurface_color_bump_blur(KernelGlobals *kg,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- float3 *eval,
- float3 *N)
+ccl_device void subsurface_color_bump_blur(
+ KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, float3 *eval, float3 *N)
{
- /* average color and texture blur at outgoing point */
- float texture_blur;
- float3 out_color = shader_bssrdf_sum(sd, NULL, &texture_blur);
-
- /* do we have bump mapping? */
- bool bump = (sd->flag & SD_HAS_BSSRDF_BUMP) != 0;
-
- if(bump || texture_blur > 0.0f) {
- /* average color and normal at incoming point */
- shader_eval_surface(kg, sd, state, state->flag);
- float3 in_color = shader_bssrdf_sum(sd, (bump)? N: NULL, NULL);
-
- /* we simply divide out the average color and multiply with the average
- * of the other one. we could try to do this per closure but it's quite
- * tricky to match closures between shader evaluations, their number and
- * order may change, this is simpler */
- if(texture_blur > 0.0f) {
- out_color = subsurface_color_pow(out_color, texture_blur);
- in_color = subsurface_color_pow(in_color, texture_blur);
-
- *eval *= safe_divide_color(in_color, out_color);
- }
- }
+ /* average color and texture blur at outgoing point */
+ float texture_blur;
+ float3 out_color = shader_bssrdf_sum(sd, NULL, &texture_blur);
+
+ /* do we have bump mapping? */
+ bool bump = (sd->flag & SD_HAS_BSSRDF_BUMP) != 0;
+
+ if (bump || texture_blur > 0.0f) {
+ /* average color and normal at incoming point */
+ shader_eval_surface(kg, sd, state, state->flag);
+ float3 in_color = shader_bssrdf_sum(sd, (bump) ? N : NULL, NULL);
+
+ /* we simply divide out the average color and multiply with the average
+ * of the other one. we could try to do this per closure but it's quite
+ * tricky to match closures between shader evaluations, their number and
+ * order may change, this is simpler */
+ if (texture_blur > 0.0f) {
+ out_color = subsurface_color_pow(out_color, texture_blur);
+ in_color = subsurface_color_pow(in_color, texture_blur);
+
+ *eval *= safe_divide_color(in_color, out_color);
+ }
+ }
}
/* Subsurface scattering step, from a point on the surface to other
* nearby points on the same object.
*/
-ccl_device_inline int subsurface_scatter_disk(
- KernelGlobals *kg,
- LocalIntersection *ss_isect,
- ShaderData *sd,
- const ShaderClosure *sc,
- uint *lcg_state,
- float disk_u,
- float disk_v,
- bool all)
+ccl_device_inline int subsurface_scatter_disk(KernelGlobals *kg,
+ LocalIntersection *ss_isect,
+ ShaderData *sd,
+ const ShaderClosure *sc,
+ uint *lcg_state,
+ float disk_u,
+ float disk_v,
+ bool all)
{
- /* pick random axis in local frame and point on disk */
- float3 disk_N, disk_T, disk_B;
- float pick_pdf_N, pick_pdf_T, pick_pdf_B;
-
- disk_N = sd->Ng;
- make_orthonormals(disk_N, &disk_T, &disk_B);
-
- if(disk_v < 0.5f) {
- pick_pdf_N = 0.5f;
- pick_pdf_T = 0.25f;
- pick_pdf_B = 0.25f;
- disk_v *= 2.0f;
- }
- else if(disk_v < 0.75f) {
- float3 tmp = disk_N;
- disk_N = disk_T;
- disk_T = tmp;
- pick_pdf_N = 0.25f;
- pick_pdf_T = 0.5f;
- pick_pdf_B = 0.25f;
- disk_v = (disk_v - 0.5f)*4.0f;
- }
- else {
- float3 tmp = disk_N;
- disk_N = disk_B;
- disk_B = tmp;
- pick_pdf_N = 0.25f;
- pick_pdf_T = 0.25f;
- pick_pdf_B = 0.5f;
- disk_v = (disk_v - 0.75f)*4.0f;
- }
-
- /* sample point on disk */
- float phi = M_2PI_F * disk_v;
- float disk_height, disk_r;
-
- bssrdf_sample(sc, disk_u, &disk_r, &disk_height);
-
- float3 disk_P = (disk_r*cosf(phi)) * disk_T + (disk_r*sinf(phi)) * disk_B;
-
- /* create ray */
+ /* pick random axis in local frame and point on disk */
+ float3 disk_N, disk_T, disk_B;
+ float pick_pdf_N, pick_pdf_T, pick_pdf_B;
+
+ disk_N = sd->Ng;
+ make_orthonormals(disk_N, &disk_T, &disk_B);
+
+ if (disk_v < 0.5f) {
+ pick_pdf_N = 0.5f;
+ pick_pdf_T = 0.25f;
+ pick_pdf_B = 0.25f;
+ disk_v *= 2.0f;
+ }
+ else if (disk_v < 0.75f) {
+ float3 tmp = disk_N;
+ disk_N = disk_T;
+ disk_T = tmp;
+ pick_pdf_N = 0.25f;
+ pick_pdf_T = 0.5f;
+ pick_pdf_B = 0.25f;
+ disk_v = (disk_v - 0.5f) * 4.0f;
+ }
+ else {
+ float3 tmp = disk_N;
+ disk_N = disk_B;
+ disk_B = tmp;
+ pick_pdf_N = 0.25f;
+ pick_pdf_T = 0.25f;
+ pick_pdf_B = 0.5f;
+ disk_v = (disk_v - 0.75f) * 4.0f;
+ }
+
+ /* sample point on disk */
+ float phi = M_2PI_F * disk_v;
+ float disk_height, disk_r;
+
+ bssrdf_sample(sc, disk_u, &disk_r, &disk_height);
+
+ float3 disk_P = (disk_r * cosf(phi)) * disk_T + (disk_r * sinf(phi)) * disk_B;
+
+ /* create ray */
#ifdef __SPLIT_KERNEL__
- Ray ray_object = ss_isect->ray;
- Ray *ray = &ray_object;
+ Ray ray_object = ss_isect->ray;
+ Ray *ray = &ray_object;
#else
- Ray *ray = &ss_isect->ray;
+ Ray *ray = &ss_isect->ray;
#endif
- ray->P = sd->P + disk_N*disk_height + disk_P;
- ray->D = -disk_N;
- ray->t = 2.0f*disk_height;
- ray->dP = sd->dP;
- ray->dD = differential3_zero();
- ray->time = sd->time;
-
- /* intersect with the same object. if multiple intersections are found it
- * will use at most BSSRDF_MAX_HITS hits, a random subset of all hits */
- scene_intersect_local(kg,
- *ray,
- ss_isect,
- sd->object,
- lcg_state,
- BSSRDF_MAX_HITS);
- int num_eval_hits = min(ss_isect->num_hits, BSSRDF_MAX_HITS);
-
- for(int hit = 0; hit < num_eval_hits; hit++) {
- /* Quickly retrieve P and Ng without setting up ShaderData. */
- float3 hit_P;
- if(sd->type & PRIMITIVE_TRIANGLE) {
- hit_P = triangle_refine_local(kg,
- sd,
- &ss_isect->hits[hit],
- ray);
- }
+ ray->P = sd->P + disk_N * disk_height + disk_P;
+ ray->D = -disk_N;
+ ray->t = 2.0f * disk_height;
+ ray->dP = sd->dP;
+ ray->dD = differential3_zero();
+ ray->time = sd->time;
+
+ /* intersect with the same object. if multiple intersections are found it
+ * will use at most BSSRDF_MAX_HITS hits, a random subset of all hits */
+ scene_intersect_local(kg, *ray, ss_isect, sd->object, lcg_state, BSSRDF_MAX_HITS);
+ int num_eval_hits = min(ss_isect->num_hits, BSSRDF_MAX_HITS);
+
+ for (int hit = 0; hit < num_eval_hits; hit++) {
+ /* Quickly retrieve P and Ng without setting up ShaderData. */
+ float3 hit_P;
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ hit_P = triangle_refine_local(kg, sd, &ss_isect->hits[hit], ray);
+ }
#ifdef __OBJECT_MOTION__
- else if(sd->type & PRIMITIVE_MOTION_TRIANGLE) {
- float3 verts[3];
- motion_triangle_vertices(
- kg,
- sd->object,
- kernel_tex_fetch(__prim_index, ss_isect->hits[hit].prim),
- sd->time,
- verts);
- hit_P = motion_triangle_refine_local(kg,
- sd,
- &ss_isect->hits[hit],
- ray,
- verts);
- }
-#endif /* __OBJECT_MOTION__ */
- else {
- ss_isect->weight[hit] = make_float3(0.0f, 0.0f, 0.0f);
- continue;
- }
-
- float3 hit_Ng = ss_isect->Ng[hit];
- if(ss_isect->hits[hit].object != OBJECT_NONE) {
- object_normal_transform(kg, sd, &hit_Ng);
- }
-
- /* Probability densities for local frame axes. */
- float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng));
- float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng));
- float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng));
-
- /* Multiple importance sample between 3 axes, power heuristic
- * found to be slightly better than balance heuristic. pdf_N
- * in the MIS weight and denominator cancelled out. */
- float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B));
- if(ss_isect->num_hits > BSSRDF_MAX_HITS) {
- w *= ss_isect->num_hits/(float)BSSRDF_MAX_HITS;
- }
-
- /* Real distance to sampled point. */
- float r = len(hit_P - sd->P);
-
- /* Evaluate profiles. */
- float3 eval = subsurface_scatter_eval(sd, sc, disk_r, r, all) * w;
-
- ss_isect->weight[hit] = eval;
- }
+ else if (sd->type & PRIMITIVE_MOTION_TRIANGLE) {
+ float3 verts[3];
+ motion_triangle_vertices(kg,
+ sd->object,
+ kernel_tex_fetch(__prim_index, ss_isect->hits[hit].prim),
+ sd->time,
+ verts);
+ hit_P = motion_triangle_refine_local(kg, sd, &ss_isect->hits[hit], ray, verts);
+ }
+#endif /* __OBJECT_MOTION__ */
+ else {
+ ss_isect->weight[hit] = make_float3(0.0f, 0.0f, 0.0f);
+ continue;
+ }
+
+ float3 hit_Ng = ss_isect->Ng[hit];
+ if (ss_isect->hits[hit].object != OBJECT_NONE) {
+ object_normal_transform(kg, sd, &hit_Ng);
+ }
+
+ /* Probability densities for local frame axes. */
+ float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng));
+ float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng));
+ float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng));
+
+ /* Multiple importance sample between 3 axes, power heuristic
+ * found to be slightly better than balance heuristic. pdf_N
+ * in the MIS weight and denominator cancelled out. */
+ float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B));
+ if (ss_isect->num_hits > BSSRDF_MAX_HITS) {
+ w *= ss_isect->num_hits / (float)BSSRDF_MAX_HITS;
+ }
+
+ /* Real distance to sampled point. */
+ float r = len(hit_P - sd->P);
+
+ /* Evaluate profiles. */
+ float3 eval = subsurface_scatter_eval(sd, sc, disk_r, r, all) * w;
+
+ ss_isect->weight[hit] = eval;
+ }
#ifdef __SPLIT_KERNEL__
- ss_isect->ray = *ray;
+ ss_isect->ray = *ray;
#endif
- return num_eval_hits;
+ return num_eval_hits;
}
-ccl_device_noinline void subsurface_scatter_multi_setup(
- KernelGlobals *kg,
- LocalIntersection* ss_isect,
- int hit,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- ClosureType type,
- float roughness)
+ccl_device_noinline void subsurface_scatter_multi_setup(KernelGlobals *kg,
+ LocalIntersection *ss_isect,
+ int hit,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ClosureType type,
+ float roughness)
{
#ifdef __SPLIT_KERNEL__
- Ray ray_object = ss_isect->ray;
- Ray *ray = &ray_object;
+ Ray ray_object = ss_isect->ray;
+ Ray *ray = &ray_object;
#else
- Ray *ray = &ss_isect->ray;
+ Ray *ray = &ss_isect->ray;
#endif
- /* Workaround for AMD GPU OpenCL compiler. Most probably cache bypass issue. */
+ /* Workaround for AMD GPU OpenCL compiler. Most probably cache bypass issue. */
#if defined(__SPLIT_KERNEL__) && defined(__KERNEL_OPENCL_AMD__) && defined(__KERNEL_GPU__)
- kernel_split_params.dummy_sd_flag = sd->flag;
+ kernel_split_params.dummy_sd_flag = sd->flag;
#endif
- /* Setup new shading point. */
- shader_setup_from_subsurface(kg, sd, &ss_isect->hits[hit], ray);
+ /* Setup new shading point. */
+ shader_setup_from_subsurface(kg, sd, &ss_isect->hits[hit], ray);
- /* Optionally blur colors and bump mapping. */
- float3 weight = ss_isect->weight[hit];
- float3 N = sd->N;
- subsurface_color_bump_blur(kg, sd, state, &weight, &N);
+ /* Optionally blur colors and bump mapping. */
+ float3 weight = ss_isect->weight[hit];
+ float3 N = sd->N;
+ subsurface_color_bump_blur(kg, sd, state, &weight, &N);
- /* Setup diffuse BSDF. */
- subsurface_scatter_setup_diffuse_bsdf(kg, sd, type, roughness, weight, N);
+ /* Setup diffuse BSDF. */
+ subsurface_scatter_setup_diffuse_bsdf(kg, sd, type, roughness, weight, N);
}
/* Random walk subsurface scattering.
@@ -340,196 +318,178 @@ ccl_device_noinline void subsurface_scatter_multi_setup(
* "Practical and Controllable Subsurface Scattering for Production Path
* Tracing". Matt Jen-Yuan Chiang, Peter Kutz, Brent Burley. SIGGRAPH 2016. */
-ccl_device void subsurface_random_walk_remap(
- const float A,
- const float d,
- float *sigma_t,
- float *sigma_s)
+ccl_device void subsurface_random_walk_remap(const float A,
+ const float d,
+ float *sigma_t,
+ float *sigma_s)
{
- /* Compute attenuation and scattering coefficients from albedo. */
- const float a = 1.0f - expf(A * (-5.09406f + A * (2.61188f - A * 4.31805f)));
- const float s = 1.9f - A + 3.5f * sqr(A - 0.8f);
+ /* Compute attenuation and scattering coefficients from albedo. */
+ const float a = 1.0f - expf(A * (-5.09406f + A * (2.61188f - A * 4.31805f)));
+ const float s = 1.9f - A + 3.5f * sqr(A - 0.8f);
- *sigma_t = 1.0f / fmaxf(d * s, 1e-16f);
- *sigma_s = *sigma_t * a;
+ *sigma_t = 1.0f / fmaxf(d * s, 1e-16f);
+ *sigma_s = *sigma_t * a;
}
-ccl_device void subsurface_random_walk_coefficients(
- const ShaderClosure *sc,
- float3 *sigma_t,
- float3 *sigma_s,
- float3 *weight)
+ccl_device void subsurface_random_walk_coefficients(const ShaderClosure *sc,
+ float3 *sigma_t,
+ float3 *sigma_s,
+ float3 *weight)
{
- const Bssrdf *bssrdf = (const Bssrdf*)sc;
- const float3 A = bssrdf->albedo;
- const float3 d = bssrdf->radius;
- float sigma_t_x, sigma_t_y, sigma_t_z;
- float sigma_s_x, sigma_s_y, sigma_s_z;
+ const Bssrdf *bssrdf = (const Bssrdf *)sc;
+ const float3 A = bssrdf->albedo;
+ const float3 d = bssrdf->radius;
+ float sigma_t_x, sigma_t_y, sigma_t_z;
+ float sigma_s_x, sigma_s_y, sigma_s_z;
- subsurface_random_walk_remap(A.x, d.x, &sigma_t_x, &sigma_s_x);
- subsurface_random_walk_remap(A.y, d.y, &sigma_t_y, &sigma_s_y);
- subsurface_random_walk_remap(A.z, d.z, &sigma_t_z, &sigma_s_z);
+ subsurface_random_walk_remap(A.x, d.x, &sigma_t_x, &sigma_s_x);
+ subsurface_random_walk_remap(A.y, d.y, &sigma_t_y, &sigma_s_y);
+ subsurface_random_walk_remap(A.z, d.z, &sigma_t_z, &sigma_s_z);
- *sigma_t = make_float3(sigma_t_x, sigma_t_y, sigma_t_z);
- *sigma_s = make_float3(sigma_s_x, sigma_s_y, sigma_s_z);
+ *sigma_t = make_float3(sigma_t_x, sigma_t_y, sigma_t_z);
+ *sigma_s = make_float3(sigma_s_x, sigma_s_y, sigma_s_z);
- /* Closure mixing and Fresnel weights separate from albedo. */
- *weight = safe_divide_color(bssrdf->weight, A);
+ /* Closure mixing and Fresnel weights separate from albedo. */
+ *weight = safe_divide_color(bssrdf->weight, A);
}
-ccl_device_noinline bool subsurface_random_walk(
- KernelGlobals *kg,
- LocalIntersection *ss_isect,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- const ShaderClosure *sc,
- const float bssrdf_u,
- const float bssrdf_v)
+ccl_device_noinline bool subsurface_random_walk(KernelGlobals *kg,
+ LocalIntersection *ss_isect,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ const ShaderClosure *sc,
+ const float bssrdf_u,
+ const float bssrdf_v)
{
- /* Sample diffuse surface scatter into the object. */
- float3 D;
- float pdf;
- sample_cos_hemisphere(-sd->N, bssrdf_u, bssrdf_v, &D, &pdf);
- if(dot(-sd->Ng, D) <= 0.0f) {
- return 0;
- }
-
- /* Convert subsurface to volume coefficients. */
- float3 sigma_t, sigma_s;
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- subsurface_random_walk_coefficients(sc, &sigma_t, &sigma_s, &throughput);
-
- /* Setup ray. */
+ /* Sample diffuse surface scatter into the object. */
+ float3 D;
+ float pdf;
+ sample_cos_hemisphere(-sd->N, bssrdf_u, bssrdf_v, &D, &pdf);
+ if (dot(-sd->Ng, D) <= 0.0f) {
+ return 0;
+ }
+
+ /* Convert subsurface to volume coefficients. */
+ float3 sigma_t, sigma_s;
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ subsurface_random_walk_coefficients(sc, &sigma_t, &sigma_s, &throughput);
+
+ /* Setup ray. */
#ifdef __SPLIT_KERNEL__
- Ray ray_object = ss_isect->ray;
- Ray *ray = &ray_object;
+ Ray ray_object = ss_isect->ray;
+ Ray *ray = &ray_object;
#else
- Ray *ray = &ss_isect->ray;
+ Ray *ray = &ss_isect->ray;
#endif
- ray->P = ray_offset(sd->P, -sd->Ng);
- ray->D = D;
- ray->t = FLT_MAX;
- ray->time = sd->time;
-
- /* Modify state for RNGs, decorrelated from other paths. */
- uint prev_rng_offset = state->rng_offset;
- uint prev_rng_hash = state->rng_hash;
- state->rng_hash = cmj_hash(state->rng_hash + state->rng_offset, 0xdeadbeef);
-
- /* Random walk until we hit the surface again. */
- bool hit = false;
-
- for(int bounce = 0; bounce < BSSRDF_MAX_BOUNCES; bounce++) {
- /* Advance random number offset. */
- state->rng_offset += PRNG_BOUNCE_NUM;
-
- if(bounce > 0) {
- /* Sample scattering direction. */
- const float anisotropy = 0.0f;
- float scatter_u, scatter_v;
- path_state_rng_2D(kg, state, PRNG_BSDF_U, &scatter_u, &scatter_v);
- ray->D = henyey_greenstrein_sample(ray->D, anisotropy, scatter_u, scatter_v, NULL);
- }
-
- /* Sample color channel, use MIS with balance heuristic. */
- float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
- float3 albedo = safe_divide_color(sigma_s, sigma_t);
- float3 channel_pdf;
- int channel = kernel_volume_sample_channel(albedo, throughput, rphase, &channel_pdf);
-
- /* Distance sampling. */
- float rdist = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
- float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
- float t = -logf(1.0f - rdist)/sample_sigma_t;
-
- ray->t = t;
- scene_intersect_local(kg, *ray, ss_isect, sd->object, NULL, 1);
- hit = (ss_isect->num_hits > 0);
-
- if(hit) {
- /* Compute world space distance to surface hit. */
- float3 D = ray->D;
- object_inverse_dir_transform(kg, sd, &D);
- D = normalize(D) * ss_isect->hits[0].t;
- object_dir_transform(kg, sd, &D);
- t = len(D);
- }
-
- /* Advance to new scatter location. */
- ray->P += t * ray->D;
-
- /* Update throughput. */
- float3 transmittance = volume_color_transmittance(sigma_t, t);
- float pdf = dot(channel_pdf, (hit)? transmittance: sigma_t * transmittance);
- throughput *= ((hit)? transmittance: sigma_s * transmittance) / pdf;
-
- if(hit) {
- /* If we hit the surface, we are done. */
- break;
- }
-
- /* Russian roulette. */
- float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
- float probability = min(max3(fabs(throughput)), 1.0f);
- if(terminate >= probability) {
- break;
- }
- throughput /= probability;
- }
-
- kernel_assert(isfinite_safe(throughput.x) &&
- isfinite_safe(throughput.y) &&
- isfinite_safe(throughput.z));
-
- state->rng_offset = prev_rng_offset;
- state->rng_hash = prev_rng_hash;
-
- /* Return number of hits in ss_isect. */
- if(!hit) {
- return 0;
- }
-
- /* TODO: gain back performance lost from merging with disk BSSRDF. We
- * only need to return on hit so this indirect ray push/pop overhead
- * is not actually needed, but it does keep the code simpler. */
- ss_isect->weight[0] = throughput;
+ ray->P = ray_offset(sd->P, -sd->Ng);
+ ray->D = D;
+ ray->t = FLT_MAX;
+ ray->time = sd->time;
+
+ /* Modify state for RNGs, decorrelated from other paths. */
+ uint prev_rng_offset = state->rng_offset;
+ uint prev_rng_hash = state->rng_hash;
+ state->rng_hash = cmj_hash(state->rng_hash + state->rng_offset, 0xdeadbeef);
+
+ /* Random walk until we hit the surface again. */
+ bool hit = false;
+
+ for (int bounce = 0; bounce < BSSRDF_MAX_BOUNCES; bounce++) {
+ /* Advance random number offset. */
+ state->rng_offset += PRNG_BOUNCE_NUM;
+
+ if (bounce > 0) {
+ /* Sample scattering direction. */
+ const float anisotropy = 0.0f;
+ float scatter_u, scatter_v;
+ path_state_rng_2D(kg, state, PRNG_BSDF_U, &scatter_u, &scatter_v);
+ ray->D = henyey_greenstrein_sample(ray->D, anisotropy, scatter_u, scatter_v, NULL);
+ }
+
+ /* Sample color channel, use MIS with balance heuristic. */
+ float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
+ float3 albedo = safe_divide_color(sigma_s, sigma_t);
+ float3 channel_pdf;
+ int channel = kernel_volume_sample_channel(albedo, throughput, rphase, &channel_pdf);
+
+ /* Distance sampling. */
+ float rdist = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
+ float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
+ float t = -logf(1.0f - rdist) / sample_sigma_t;
+
+ ray->t = t;
+ scene_intersect_local(kg, *ray, ss_isect, sd->object, NULL, 1);
+ hit = (ss_isect->num_hits > 0);
+
+ if (hit) {
+ /* Compute world space distance to surface hit. */
+ float3 D = ray->D;
+ object_inverse_dir_transform(kg, sd, &D);
+ D = normalize(D) * ss_isect->hits[0].t;
+ object_dir_transform(kg, sd, &D);
+ t = len(D);
+ }
+
+ /* Advance to new scatter location. */
+ ray->P += t * ray->D;
+
+ /* Update throughput. */
+ float3 transmittance = volume_color_transmittance(sigma_t, t);
+ float pdf = dot(channel_pdf, (hit) ? transmittance : sigma_t * transmittance);
+ throughput *= ((hit) ? transmittance : sigma_s * transmittance) / pdf;
+
+ if (hit) {
+ /* If we hit the surface, we are done. */
+ break;
+ }
+
+ /* Russian roulette. */
+ float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
+ float probability = min(max3(fabs(throughput)), 1.0f);
+ if (terminate >= probability) {
+ break;
+ }
+ throughput /= probability;
+ }
+
+ kernel_assert(isfinite_safe(throughput.x) && isfinite_safe(throughput.y) &&
+ isfinite_safe(throughput.z));
+
+ state->rng_offset = prev_rng_offset;
+ state->rng_hash = prev_rng_hash;
+
+ /* Return number of hits in ss_isect. */
+ if (!hit) {
+ return 0;
+ }
+
+ /* TODO: gain back performance lost from merging with disk BSSRDF. We
+ * only need to return on hit so this indirect ray push/pop overhead
+ * is not actually needed, but it does keep the code simpler. */
+ ss_isect->weight[0] = throughput;
#ifdef __SPLIT_KERNEL__
- ss_isect->ray = *ray;
+ ss_isect->ray = *ray;
#endif
- return 1;
+ return 1;
}
-ccl_device_inline int subsurface_scatter_multi_intersect(
- KernelGlobals *kg,
- LocalIntersection *ss_isect,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- const ShaderClosure *sc,
- uint *lcg_state,
- float bssrdf_u,
- float bssrdf_v,
- bool all)
+ccl_device_inline int subsurface_scatter_multi_intersect(KernelGlobals *kg,
+ LocalIntersection *ss_isect,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ const ShaderClosure *sc,
+ uint *lcg_state,
+ float bssrdf_u,
+ float bssrdf_v,
+ bool all)
{
- if(CLOSURE_IS_DISK_BSSRDF(sc->type)) {
- return subsurface_scatter_disk(kg,
- ss_isect,
- sd,
- sc,
- lcg_state,
- bssrdf_u,
- bssrdf_v,
- all);
- }
- else {
- return subsurface_random_walk(kg,
- ss_isect,
- sd,
- state,
- sc,
- bssrdf_u,
- bssrdf_v);
- }
+ if (CLOSURE_IS_DISK_BSSRDF(sc->type)) {
+ return subsurface_scatter_disk(kg, ss_isect, sd, sc, lcg_state, bssrdf_u, bssrdf_v, all);
+ }
+ else {
+ return subsurface_random_walk(kg, ss_isect, sd, state, sc, bssrdf_u, bssrdf_v);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 4b1c8e82dfa..3f62b726b6a 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -42,26 +42,26 @@ CCL_NAMESPACE_BEGIN
/* Constants */
#define OBJECT_MOTION_PASS_SIZE 2
-#define FILTER_TABLE_SIZE 1024
-#define RAMP_TABLE_SIZE 256
-#define SHUTTER_TABLE_SIZE 256
+#define FILTER_TABLE_SIZE 1024
+#define RAMP_TABLE_SIZE 256
+#define SHUTTER_TABLE_SIZE 256
-#define BSSRDF_MIN_RADIUS 1e-8f
-#define BSSRDF_MAX_HITS 4
-#define BSSRDF_MAX_BOUNCES 256
-#define LOCAL_MAX_HITS 4
+#define BSSRDF_MIN_RADIUS 1e-8f
+#define BSSRDF_MAX_HITS 4
+#define BSSRDF_MAX_BOUNCES 256
+#define LOCAL_MAX_HITS 4
-#define VOLUME_BOUNDS_MAX 1024
+#define VOLUME_BOUNDS_MAX 1024
-#define BECKMANN_TABLE_SIZE 256
+#define BECKMANN_TABLE_SIZE 256
-#define SHADER_NONE (~0)
-#define OBJECT_NONE (~0)
-#define PRIM_NONE (~0)
-#define LAMP_NONE (~0)
-#define ID_NONE (0.0f)
+#define SHADER_NONE (~0)
+#define OBJECT_NONE (~0)
+#define PRIM_NONE (~0)
+#define LAMP_NONE (~0)
+#define ID_NONE (0.0f)
-#define VOLUME_STACK_SIZE 32
+#define VOLUME_STACK_SIZE 32
/* Split kernel constants */
#define WORK_POOL_SIZE_GPU 64
@@ -72,7 +72,6 @@ CCL_NAMESPACE_BEGIN
# define WORK_POOL_SIZE WORK_POOL_SIZE_CPU
#endif
-
#define SHADER_SORT_BLOCK_SIZE 2048
#ifdef __KERNEL_OPENCL__
@@ -137,16 +136,16 @@ CCL_NAMESPACE_BEGIN
# endif
# define __VOLUME_DECOUPLED__
# define __VOLUME_RECORD_ALL__
-#endif /* __KERNEL_CPU__ */
+#endif /* __KERNEL_CPU__ */
#ifdef __KERNEL_CUDA__
# ifdef __SPLIT_KERNEL__
# undef __BRANCHED_PATH__
# endif
-#endif /* __KERNEL_CUDA__ */
+#endif /* __KERNEL_CUDA__ */
#ifdef __KERNEL_OPENCL__
-#endif /* __KERNEL_OPENCL__ */
+#endif /* __KERNEL_OPENCL__ */
/* Scene-based selective features compilation. */
#ifdef __NO_CAMERA_MOTION__
@@ -202,273 +201,269 @@ CCL_NAMESPACE_BEGIN
/* Shader Evaluation */
typedef enum ShaderEvalType {
- SHADER_EVAL_DISPLACE,
- SHADER_EVAL_BACKGROUND,
- /* bake types */
- SHADER_EVAL_BAKE, /* no real shade, it's used in the code to
- * differentiate the type of shader eval from the above
- */
- /* data passes */
- SHADER_EVAL_NORMAL,
- SHADER_EVAL_UV,
- SHADER_EVAL_ROUGHNESS,
- SHADER_EVAL_DIFFUSE_COLOR,
- SHADER_EVAL_GLOSSY_COLOR,
- SHADER_EVAL_TRANSMISSION_COLOR,
- SHADER_EVAL_SUBSURFACE_COLOR,
- SHADER_EVAL_EMISSION,
-
- /* light passes */
- SHADER_EVAL_AO,
- SHADER_EVAL_COMBINED,
- SHADER_EVAL_SHADOW,
- SHADER_EVAL_DIFFUSE,
- SHADER_EVAL_GLOSSY,
- SHADER_EVAL_TRANSMISSION,
- SHADER_EVAL_SUBSURFACE,
-
- /* extra */
- SHADER_EVAL_ENVIRONMENT,
+ SHADER_EVAL_DISPLACE,
+ SHADER_EVAL_BACKGROUND,
+ /* bake types */
+ SHADER_EVAL_BAKE, /* no real shade, it's used in the code to
+ * differentiate the type of shader eval from the above
+ */
+ /* data passes */
+ SHADER_EVAL_NORMAL,
+ SHADER_EVAL_UV,
+ SHADER_EVAL_ROUGHNESS,
+ SHADER_EVAL_DIFFUSE_COLOR,
+ SHADER_EVAL_GLOSSY_COLOR,
+ SHADER_EVAL_TRANSMISSION_COLOR,
+ SHADER_EVAL_SUBSURFACE_COLOR,
+ SHADER_EVAL_EMISSION,
+
+ /* light passes */
+ SHADER_EVAL_AO,
+ SHADER_EVAL_COMBINED,
+ SHADER_EVAL_SHADOW,
+ SHADER_EVAL_DIFFUSE,
+ SHADER_EVAL_GLOSSY,
+ SHADER_EVAL_TRANSMISSION,
+ SHADER_EVAL_SUBSURFACE,
+
+ /* extra */
+ SHADER_EVAL_ENVIRONMENT,
} ShaderEvalType;
/* Path Tracing
* note we need to keep the u/v pairs at even values */
enum PathTraceDimension {
- PRNG_FILTER_U = 0,
- PRNG_FILTER_V = 1,
- PRNG_LENS_U = 2,
- PRNG_LENS_V = 3,
- PRNG_TIME = 4,
- PRNG_UNUSED_0 = 5,
- PRNG_UNUSED_1 = 6, /* for some reason (6, 7) is a bad sobol pattern */
- PRNG_UNUSED_2 = 7, /* with a low number of samples (< 64) */
- PRNG_BASE_NUM = 10,
-
- PRNG_BSDF_U = 0,
- PRNG_BSDF_V = 1,
- PRNG_LIGHT_U = 2,
- PRNG_LIGHT_V = 3,
- PRNG_LIGHT_TERMINATE = 4,
- PRNG_TERMINATE = 5,
- PRNG_PHASE_CHANNEL = 6,
- PRNG_SCATTER_DISTANCE = 7,
- PRNG_BOUNCE_NUM = 8,
-
- PRNG_BEVEL_U = 6, /* reuse volume dimension, correlation won't harm */
- PRNG_BEVEL_V = 7,
+ PRNG_FILTER_U = 0,
+ PRNG_FILTER_V = 1,
+ PRNG_LENS_U = 2,
+ PRNG_LENS_V = 3,
+ PRNG_TIME = 4,
+ PRNG_UNUSED_0 = 5,
+ PRNG_UNUSED_1 = 6, /* for some reason (6, 7) is a bad sobol pattern */
+ PRNG_UNUSED_2 = 7, /* with a low number of samples (< 64) */
+ PRNG_BASE_NUM = 10,
+
+ PRNG_BSDF_U = 0,
+ PRNG_BSDF_V = 1,
+ PRNG_LIGHT_U = 2,
+ PRNG_LIGHT_V = 3,
+ PRNG_LIGHT_TERMINATE = 4,
+ PRNG_TERMINATE = 5,
+ PRNG_PHASE_CHANNEL = 6,
+ PRNG_SCATTER_DISTANCE = 7,
+ PRNG_BOUNCE_NUM = 8,
+
+ PRNG_BEVEL_U = 6, /* reuse volume dimension, correlation won't harm */
+ PRNG_BEVEL_V = 7,
};
enum SamplingPattern {
- SAMPLING_PATTERN_SOBOL = 0,
- SAMPLING_PATTERN_CMJ = 1,
+ SAMPLING_PATTERN_SOBOL = 0,
+ SAMPLING_PATTERN_CMJ = 1,
- SAMPLING_NUM_PATTERNS,
+ SAMPLING_NUM_PATTERNS,
};
/* these flags values correspond to raytypes in osl.cpp, so keep them in sync! */
enum PathRayFlag {
- PATH_RAY_CAMERA = (1 << 0),
- PATH_RAY_REFLECT = (1 << 1),
- PATH_RAY_TRANSMIT = (1 << 2),
- PATH_RAY_DIFFUSE = (1 << 3),
- PATH_RAY_GLOSSY = (1 << 4),
- PATH_RAY_SINGULAR = (1 << 5),
- PATH_RAY_TRANSPARENT = (1 << 6),
-
- PATH_RAY_SHADOW_OPAQUE_NON_CATCHER = (1 << 7),
- PATH_RAY_SHADOW_OPAQUE_CATCHER = (1 << 8),
- PATH_RAY_SHADOW_OPAQUE = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER|PATH_RAY_SHADOW_OPAQUE_CATCHER),
- PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER = (1 << 9),
- PATH_RAY_SHADOW_TRANSPARENT_CATCHER = (1 << 10),
- PATH_RAY_SHADOW_TRANSPARENT = (PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER|PATH_RAY_SHADOW_TRANSPARENT_CATCHER),
- PATH_RAY_SHADOW_NON_CATCHER = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER|PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER),
- PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE|PATH_RAY_SHADOW_TRANSPARENT),
-
- PATH_RAY_CURVE = (1 << 11), /* visibility flag to define curve segments */
- PATH_RAY_VOLUME_SCATTER = (1 << 12), /* volume scattering */
-
- /* Special flag to tag unaligned BVH nodes. */
- PATH_RAY_NODE_UNALIGNED = (1 << 13),
-
- PATH_RAY_ALL_VISIBILITY = ((1 << 14)-1),
-
- /* Don't apply multiple importance sampling weights to emission from
- * lamp or surface hits, because they were not direct light sampled. */
- PATH_RAY_MIS_SKIP = (1 << 14),
- /* Diffuse bounce earlier in the path, skip SSS to improve performance
- * and avoid branching twice with disk sampling SSS. */
- PATH_RAY_DIFFUSE_ANCESTOR = (1 << 15),
- /* Single pass has been written. */
- PATH_RAY_SINGLE_PASS_DONE = (1 << 16),
- /* Ray is behind a shadow catcher .*/
- PATH_RAY_SHADOW_CATCHER = (1 << 17),
- /* Store shadow data for shadow catcher or denoising. */
- PATH_RAY_STORE_SHADOW_INFO = (1 << 18),
- /* Zero background alpha, for camera or transparent glass rays. */
- PATH_RAY_TRANSPARENT_BACKGROUND = (1 << 19),
- /* Terminate ray immediately at next bounce. */
- PATH_RAY_TERMINATE_IMMEDIATE = (1 << 20),
- /* Ray is to be terminated, but continue with transparent bounces and
- * emission as long as we encounter them. This is required to make the
- * MIS between direct and indirect light rays match, as shadow rays go
- * through transparent surfaces to reach emisison too. */
- PATH_RAY_TERMINATE_AFTER_TRANSPARENT = (1 << 21),
- /* Ray is to be terminated. */
- PATH_RAY_TERMINATE = (PATH_RAY_TERMINATE_IMMEDIATE|PATH_RAY_TERMINATE_AFTER_TRANSPARENT),
- /* Path and shader is being evaluated for direct lighting emission. */
- PATH_RAY_EMISSION = (1 << 22)
+ PATH_RAY_CAMERA = (1 << 0),
+ PATH_RAY_REFLECT = (1 << 1),
+ PATH_RAY_TRANSMIT = (1 << 2),
+ PATH_RAY_DIFFUSE = (1 << 3),
+ PATH_RAY_GLOSSY = (1 << 4),
+ PATH_RAY_SINGULAR = (1 << 5),
+ PATH_RAY_TRANSPARENT = (1 << 6),
+
+ PATH_RAY_SHADOW_OPAQUE_NON_CATCHER = (1 << 7),
+ PATH_RAY_SHADOW_OPAQUE_CATCHER = (1 << 8),
+ PATH_RAY_SHADOW_OPAQUE = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER | PATH_RAY_SHADOW_OPAQUE_CATCHER),
+ PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER = (1 << 9),
+ PATH_RAY_SHADOW_TRANSPARENT_CATCHER = (1 << 10),
+ PATH_RAY_SHADOW_TRANSPARENT = (PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER |
+ PATH_RAY_SHADOW_TRANSPARENT_CATCHER),
+ PATH_RAY_SHADOW_NON_CATCHER = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER |
+ PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER),
+ PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE | PATH_RAY_SHADOW_TRANSPARENT),
+
+ PATH_RAY_CURVE = (1 << 11), /* visibility flag to define curve segments */
+ PATH_RAY_VOLUME_SCATTER = (1 << 12), /* volume scattering */
+
+ /* Special flag to tag unaligned BVH nodes. */
+ PATH_RAY_NODE_UNALIGNED = (1 << 13),
+
+ PATH_RAY_ALL_VISIBILITY = ((1 << 14) - 1),
+
+ /* Don't apply multiple importance sampling weights to emission from
+ * lamp or surface hits, because they were not direct light sampled. */
+ PATH_RAY_MIS_SKIP = (1 << 14),
+ /* Diffuse bounce earlier in the path, skip SSS to improve performance
+ * and avoid branching twice with disk sampling SSS. */
+ PATH_RAY_DIFFUSE_ANCESTOR = (1 << 15),
+ /* Single pass has been written. */
+ PATH_RAY_SINGLE_PASS_DONE = (1 << 16),
+ /* Ray is behind a shadow catcher .*/
+ PATH_RAY_SHADOW_CATCHER = (1 << 17),
+ /* Store shadow data for shadow catcher or denoising. */
+ PATH_RAY_STORE_SHADOW_INFO = (1 << 18),
+ /* Zero background alpha, for camera or transparent glass rays. */
+ PATH_RAY_TRANSPARENT_BACKGROUND = (1 << 19),
+ /* Terminate ray immediately at next bounce. */
+ PATH_RAY_TERMINATE_IMMEDIATE = (1 << 20),
+ /* Ray is to be terminated, but continue with transparent bounces and
+ * emission as long as we encounter them. This is required to make the
+ * MIS between direct and indirect light rays match, as shadow rays go
+ * through transparent surfaces to reach emisison too. */
+ PATH_RAY_TERMINATE_AFTER_TRANSPARENT = (1 << 21),
+ /* Ray is to be terminated. */
+ PATH_RAY_TERMINATE = (PATH_RAY_TERMINATE_IMMEDIATE | PATH_RAY_TERMINATE_AFTER_TRANSPARENT),
+ /* Path and shader is being evaluated for direct lighting emission. */
+ PATH_RAY_EMISSION = (1 << 22)
};
/* Closure Label */
typedef enum ClosureLabel {
- LABEL_NONE = 0,
- LABEL_TRANSMIT = 1,
- LABEL_REFLECT = 2,
- LABEL_DIFFUSE = 4,
- LABEL_GLOSSY = 8,
- LABEL_SINGULAR = 16,
- LABEL_TRANSPARENT = 32,
- LABEL_VOLUME_SCATTER = 64,
- LABEL_TRANSMIT_TRANSPARENT = 128,
+ LABEL_NONE = 0,
+ LABEL_TRANSMIT = 1,
+ LABEL_REFLECT = 2,
+ LABEL_DIFFUSE = 4,
+ LABEL_GLOSSY = 8,
+ LABEL_SINGULAR = 16,
+ LABEL_TRANSPARENT = 32,
+ LABEL_VOLUME_SCATTER = 64,
+ LABEL_TRANSMIT_TRANSPARENT = 128,
} ClosureLabel;
/* Render Passes */
-#define PASS_NAME_JOIN(a, b) a ## _ ## b
+#define PASS_NAME_JOIN(a, b) a##_##b
#define PASSMASK(pass) (1 << ((PASS_NAME_JOIN(PASS, pass)) % 32))
-#define PASSMASK_COMPONENT(comp) (PASSMASK(PASS_NAME_JOIN(comp, DIRECT)) | \
- PASSMASK(PASS_NAME_JOIN(comp, INDIRECT)) | \
- PASSMASK(PASS_NAME_JOIN(comp, COLOR)))
+#define PASSMASK_COMPONENT(comp) \
+ (PASSMASK(PASS_NAME_JOIN(comp, DIRECT)) | PASSMASK(PASS_NAME_JOIN(comp, INDIRECT)) | \
+ PASSMASK(PASS_NAME_JOIN(comp, COLOR)))
typedef enum PassType {
- PASS_NONE = 0,
-
- /* Main passes */
- PASS_COMBINED = 1,
- PASS_DEPTH,
- PASS_NORMAL,
- PASS_UV,
- PASS_OBJECT_ID,
- PASS_MATERIAL_ID,
- PASS_MOTION,
- PASS_MOTION_WEIGHT,
+ PASS_NONE = 0,
+
+ /* Main passes */
+ PASS_COMBINED = 1,
+ PASS_DEPTH,
+ PASS_NORMAL,
+ PASS_UV,
+ PASS_OBJECT_ID,
+ PASS_MATERIAL_ID,
+ PASS_MOTION,
+ PASS_MOTION_WEIGHT,
#ifdef __KERNEL_DEBUG__
- PASS_BVH_TRAVERSED_NODES,
- PASS_BVH_TRAVERSED_INSTANCES,
- PASS_BVH_INTERSECTIONS,
- PASS_RAY_BOUNCES,
+ PASS_BVH_TRAVERSED_NODES,
+ PASS_BVH_TRAVERSED_INSTANCES,
+ PASS_BVH_INTERSECTIONS,
+ PASS_RAY_BOUNCES,
#endif
- PASS_RENDER_TIME,
- PASS_CRYPTOMATTE,
- PASS_CATEGORY_MAIN_END = 31,
-
- PASS_MIST = 32,
- PASS_EMISSION,
- PASS_BACKGROUND,
- PASS_AO,
- PASS_SHADOW,
- PASS_LIGHT, /* no real pass, used to force use_light_pass */
- PASS_DIFFUSE_DIRECT,
- PASS_DIFFUSE_INDIRECT,
- PASS_DIFFUSE_COLOR,
- PASS_GLOSSY_DIRECT,
- PASS_GLOSSY_INDIRECT,
- PASS_GLOSSY_COLOR,
- PASS_TRANSMISSION_DIRECT,
- PASS_TRANSMISSION_INDIRECT,
- PASS_TRANSMISSION_COLOR,
- PASS_SUBSURFACE_DIRECT,
- PASS_SUBSURFACE_INDIRECT,
- PASS_SUBSURFACE_COLOR,
- PASS_VOLUME_DIRECT,
- PASS_VOLUME_INDIRECT,
- /* No Scatter color since it's tricky to define what it would even mean. */
- PASS_CATEGORY_LIGHT_END = 63,
+ PASS_RENDER_TIME,
+ PASS_CRYPTOMATTE,
+ PASS_CATEGORY_MAIN_END = 31,
+
+ PASS_MIST = 32,
+ PASS_EMISSION,
+ PASS_BACKGROUND,
+ PASS_AO,
+ PASS_SHADOW,
+ PASS_LIGHT, /* no real pass, used to force use_light_pass */
+ PASS_DIFFUSE_DIRECT,
+ PASS_DIFFUSE_INDIRECT,
+ PASS_DIFFUSE_COLOR,
+ PASS_GLOSSY_DIRECT,
+ PASS_GLOSSY_INDIRECT,
+ PASS_GLOSSY_COLOR,
+ PASS_TRANSMISSION_DIRECT,
+ PASS_TRANSMISSION_INDIRECT,
+ PASS_TRANSMISSION_COLOR,
+ PASS_SUBSURFACE_DIRECT,
+ PASS_SUBSURFACE_INDIRECT,
+ PASS_SUBSURFACE_COLOR,
+ PASS_VOLUME_DIRECT,
+ PASS_VOLUME_INDIRECT,
+ /* No Scatter color since it's tricky to define what it would even mean. */
+ PASS_CATEGORY_LIGHT_END = 63,
} PassType;
#define PASS_ANY (~0)
typedef enum CryptomatteType {
- CRYPT_NONE = 0,
- CRYPT_OBJECT = (1 << 0),
- CRYPT_MATERIAL = (1 << 1),
- CRYPT_ASSET = (1 << 2),
- CRYPT_ACCURATE = (1 << 3),
+ CRYPT_NONE = 0,
+ CRYPT_OBJECT = (1 << 0),
+ CRYPT_MATERIAL = (1 << 1),
+ CRYPT_ASSET = (1 << 2),
+ CRYPT_ACCURATE = (1 << 3),
} CryptomatteType;
typedef enum DenoisingPassOffsets {
- DENOISING_PASS_NORMAL = 0,
- DENOISING_PASS_NORMAL_VAR = 3,
- DENOISING_PASS_ALBEDO = 6,
- DENOISING_PASS_ALBEDO_VAR = 9,
- DENOISING_PASS_DEPTH = 12,
- DENOISING_PASS_DEPTH_VAR = 13,
- DENOISING_PASS_SHADOW_A = 14,
- DENOISING_PASS_SHADOW_B = 17,
- DENOISING_PASS_COLOR = 20,
- DENOISING_PASS_COLOR_VAR = 23,
- DENOISING_PASS_CLEAN = 26,
-
- DENOISING_PASS_PREFILTERED_DEPTH = 0,
- DENOISING_PASS_PREFILTERED_NORMAL = 1,
- DENOISING_PASS_PREFILTERED_SHADOWING = 4,
- DENOISING_PASS_PREFILTERED_ALBEDO = 5,
- DENOISING_PASS_PREFILTERED_COLOR = 8,
- DENOISING_PASS_PREFILTERED_VARIANCE = 11,
- DENOISING_PASS_PREFILTERED_INTENSITY = 14,
-
- DENOISING_PASS_SIZE_BASE = 26,
- DENOISING_PASS_SIZE_CLEAN = 3,
- DENOISING_PASS_SIZE_PREFILTERED = 15,
+ DENOISING_PASS_NORMAL = 0,
+ DENOISING_PASS_NORMAL_VAR = 3,
+ DENOISING_PASS_ALBEDO = 6,
+ DENOISING_PASS_ALBEDO_VAR = 9,
+ DENOISING_PASS_DEPTH = 12,
+ DENOISING_PASS_DEPTH_VAR = 13,
+ DENOISING_PASS_SHADOW_A = 14,
+ DENOISING_PASS_SHADOW_B = 17,
+ DENOISING_PASS_COLOR = 20,
+ DENOISING_PASS_COLOR_VAR = 23,
+ DENOISING_PASS_CLEAN = 26,
+
+ DENOISING_PASS_PREFILTERED_DEPTH = 0,
+ DENOISING_PASS_PREFILTERED_NORMAL = 1,
+ DENOISING_PASS_PREFILTERED_SHADOWING = 4,
+ DENOISING_PASS_PREFILTERED_ALBEDO = 5,
+ DENOISING_PASS_PREFILTERED_COLOR = 8,
+ DENOISING_PASS_PREFILTERED_VARIANCE = 11,
+ DENOISING_PASS_PREFILTERED_INTENSITY = 14,
+
+ DENOISING_PASS_SIZE_BASE = 26,
+ DENOISING_PASS_SIZE_CLEAN = 3,
+ DENOISING_PASS_SIZE_PREFILTERED = 15,
} DenoisingPassOffsets;
typedef enum eBakePassFilter {
- BAKE_FILTER_NONE = 0,
- BAKE_FILTER_DIRECT = (1 << 0),
- BAKE_FILTER_INDIRECT = (1 << 1),
- BAKE_FILTER_COLOR = (1 << 2),
- BAKE_FILTER_DIFFUSE = (1 << 3),
- BAKE_FILTER_GLOSSY = (1 << 4),
- BAKE_FILTER_TRANSMISSION = (1 << 5),
- BAKE_FILTER_SUBSURFACE = (1 << 6),
- BAKE_FILTER_EMISSION = (1 << 7),
- BAKE_FILTER_AO = (1 << 8),
+ BAKE_FILTER_NONE = 0,
+ BAKE_FILTER_DIRECT = (1 << 0),
+ BAKE_FILTER_INDIRECT = (1 << 1),
+ BAKE_FILTER_COLOR = (1 << 2),
+ BAKE_FILTER_DIFFUSE = (1 << 3),
+ BAKE_FILTER_GLOSSY = (1 << 4),
+ BAKE_FILTER_TRANSMISSION = (1 << 5),
+ BAKE_FILTER_SUBSURFACE = (1 << 6),
+ BAKE_FILTER_EMISSION = (1 << 7),
+ BAKE_FILTER_AO = (1 << 8),
} eBakePassFilter;
typedef enum BakePassFilterCombos {
- BAKE_FILTER_COMBINED = (
- BAKE_FILTER_DIRECT |
- BAKE_FILTER_INDIRECT |
- BAKE_FILTER_DIFFUSE |
- BAKE_FILTER_GLOSSY |
- BAKE_FILTER_TRANSMISSION |
- BAKE_FILTER_SUBSURFACE |
- BAKE_FILTER_EMISSION |
- BAKE_FILTER_AO),
- BAKE_FILTER_DIFFUSE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_DIFFUSE),
- BAKE_FILTER_GLOSSY_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_GLOSSY),
- BAKE_FILTER_TRANSMISSION_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_TRANSMISSION),
- BAKE_FILTER_SUBSURFACE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_SUBSURFACE),
- BAKE_FILTER_DIFFUSE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_DIFFUSE),
- BAKE_FILTER_GLOSSY_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_GLOSSY),
- BAKE_FILTER_TRANSMISSION_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_TRANSMISSION),
- BAKE_FILTER_SUBSURFACE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_SUBSURFACE),
+ BAKE_FILTER_COMBINED = (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_DIFFUSE |
+ BAKE_FILTER_GLOSSY | BAKE_FILTER_TRANSMISSION | BAKE_FILTER_SUBSURFACE |
+ BAKE_FILTER_EMISSION | BAKE_FILTER_AO),
+ BAKE_FILTER_DIFFUSE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_DIFFUSE),
+ BAKE_FILTER_GLOSSY_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_GLOSSY),
+ BAKE_FILTER_TRANSMISSION_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_TRANSMISSION),
+ BAKE_FILTER_SUBSURFACE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_SUBSURFACE),
+ BAKE_FILTER_DIFFUSE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_DIFFUSE),
+ BAKE_FILTER_GLOSSY_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_GLOSSY),
+ BAKE_FILTER_TRANSMISSION_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_TRANSMISSION),
+ BAKE_FILTER_SUBSURFACE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_SUBSURFACE),
} BakePassFilterCombos;
typedef enum DenoiseFlag {
- DENOISING_CLEAN_DIFFUSE_DIR = (1 << 0),
- DENOISING_CLEAN_DIFFUSE_IND = (1 << 1),
- DENOISING_CLEAN_GLOSSY_DIR = (1 << 2),
- DENOISING_CLEAN_GLOSSY_IND = (1 << 3),
- DENOISING_CLEAN_TRANSMISSION_DIR = (1 << 4),
- DENOISING_CLEAN_TRANSMISSION_IND = (1 << 5),
- DENOISING_CLEAN_SUBSURFACE_DIR = (1 << 6),
- DENOISING_CLEAN_SUBSURFACE_IND = (1 << 7),
- DENOISING_CLEAN_ALL_PASSES = (1 << 8)-1,
+ DENOISING_CLEAN_DIFFUSE_DIR = (1 << 0),
+ DENOISING_CLEAN_DIFFUSE_IND = (1 << 1),
+ DENOISING_CLEAN_GLOSSY_DIR = (1 << 2),
+ DENOISING_CLEAN_GLOSSY_IND = (1 << 3),
+ DENOISING_CLEAN_TRANSMISSION_DIR = (1 << 4),
+ DENOISING_CLEAN_TRANSMISSION_IND = (1 << 5),
+ DENOISING_CLEAN_SUBSURFACE_DIR = (1 << 6),
+ DENOISING_CLEAN_SUBSURFACE_IND = (1 << 7),
+ DENOISING_CLEAN_ALL_PASSES = (1 << 8) - 1,
} DenoiseFlag;
#ifdef __KERNEL_DEBUG__
@@ -476,173 +471,171 @@ typedef enum DenoiseFlag {
* really important here.
*/
typedef struct DebugData {
- int num_bvh_traversed_nodes;
- int num_bvh_traversed_instances;
- int num_bvh_intersections;
- int num_ray_bounces;
+ int num_bvh_traversed_nodes;
+ int num_bvh_traversed_instances;
+ int num_bvh_intersections;
+ int num_ray_bounces;
} DebugData;
#endif
typedef ccl_addr_space struct PathRadianceState {
#ifdef __PASSES__
- float3 diffuse;
- float3 glossy;
- float3 transmission;
- float3 subsurface;
- float3 scatter;
+ float3 diffuse;
+ float3 glossy;
+ float3 transmission;
+ float3 subsurface;
+ float3 scatter;
- float3 direct;
+ float3 direct;
#endif
} PathRadianceState;
typedef ccl_addr_space struct PathRadiance {
#ifdef __PASSES__
- int use_light_pass;
+ int use_light_pass;
#endif
- float transparent;
- float3 emission;
+ float transparent;
+ float3 emission;
#ifdef __PASSES__
- float3 background;
- float3 ao;
-
- float3 indirect;
- float3 direct_emission;
-
- float3 color_diffuse;
- float3 color_glossy;
- float3 color_transmission;
- float3 color_subsurface;
-
- float3 direct_diffuse;
- float3 direct_glossy;
- float3 direct_transmission;
- float3 direct_subsurface;
- float3 direct_scatter;
-
- float3 indirect_diffuse;
- float3 indirect_glossy;
- float3 indirect_transmission;
- float3 indirect_subsurface;
- float3 indirect_scatter;
-
- float4 shadow;
- float mist;
+ float3 background;
+ float3 ao;
+
+ float3 indirect;
+ float3 direct_emission;
+
+ float3 color_diffuse;
+ float3 color_glossy;
+ float3 color_transmission;
+ float3 color_subsurface;
+
+ float3 direct_diffuse;
+ float3 direct_glossy;
+ float3 direct_transmission;
+ float3 direct_subsurface;
+ float3 direct_scatter;
+
+ float3 indirect_diffuse;
+ float3 indirect_glossy;
+ float3 indirect_transmission;
+ float3 indirect_subsurface;
+ float3 indirect_scatter;
+
+ float4 shadow;
+ float mist;
#endif
- struct PathRadianceState state;
+ struct PathRadianceState state;
#ifdef __SHADOW_TRICKS__
- /* Total light reachable across the path, ignoring shadow blocked queries. */
- float3 path_total;
- /* Total light reachable across the path with shadow blocked queries
- * applied here.
- *
- * Dividing this figure by path_total will give estimate of shadow pass.
- */
- float3 path_total_shaded;
-
- /* Color of the background on which shadow is alpha-overed. */
- float3 shadow_background_color;
-
- /* Path radiance sum and throughput at the moment when ray hits shadow
- * catcher object.
- */
- float shadow_throughput;
-
- /* Accumulated transparency along the path after shadow catcher bounce. */
- float shadow_transparency;
-
- /* Indicate if any shadow catcher data is set. */
- int has_shadow_catcher;
+ /* Total light reachable across the path, ignoring shadow blocked queries. */
+ float3 path_total;
+ /* Total light reachable across the path with shadow blocked queries
+ * applied here.
+ *
+ * Dividing this figure by path_total will give estimate of shadow pass.
+ */
+ float3 path_total_shaded;
+
+ /* Color of the background on which shadow is alpha-overed. */
+ float3 shadow_background_color;
+
+ /* Path radiance sum and throughput at the moment when ray hits shadow
+ * catcher object.
+ */
+ float shadow_throughput;
+
+ /* Accumulated transparency along the path after shadow catcher bounce. */
+ float shadow_transparency;
+
+ /* Indicate if any shadow catcher data is set. */
+ int has_shadow_catcher;
#endif
#ifdef __DENOISING_FEATURES__
- float3 denoising_normal;
- float3 denoising_albedo;
- float denoising_depth;
-#endif /* __DENOISING_FEATURES__ */
+ float3 denoising_normal;
+ float3 denoising_albedo;
+ float denoising_depth;
+#endif /* __DENOISING_FEATURES__ */
#ifdef __KERNEL_DEBUG__
- DebugData debug_data;
-#endif /* __KERNEL_DEBUG__ */
+ DebugData debug_data;
+#endif /* __KERNEL_DEBUG__ */
} PathRadiance;
typedef struct BsdfEval {
#ifdef __PASSES__
- int use_light_pass;
+ int use_light_pass;
#endif
- float3 diffuse;
+ float3 diffuse;
#ifdef __PASSES__
- float3 glossy;
- float3 transmission;
- float3 transparent;
- float3 subsurface;
- float3 scatter;
+ float3 glossy;
+ float3 transmission;
+ float3 transparent;
+ float3 subsurface;
+ float3 scatter;
#endif
#ifdef __SHADOW_TRICKS__
- float3 sum_no_mis;
+ float3 sum_no_mis;
#endif
} BsdfEval;
/* Shader Flag */
typedef enum ShaderFlag {
- SHADER_SMOOTH_NORMAL = (1 << 31),
- SHADER_CAST_SHADOW = (1 << 30),
- SHADER_AREA_LIGHT = (1 << 29),
- SHADER_USE_MIS = (1 << 28),
- SHADER_EXCLUDE_DIFFUSE = (1 << 27),
- SHADER_EXCLUDE_GLOSSY = (1 << 26),
- SHADER_EXCLUDE_TRANSMIT = (1 << 25),
- SHADER_EXCLUDE_CAMERA = (1 << 24),
- SHADER_EXCLUDE_SCATTER = (1 << 23),
- SHADER_EXCLUDE_ANY = (SHADER_EXCLUDE_DIFFUSE|SHADER_EXCLUDE_GLOSSY|SHADER_EXCLUDE_TRANSMIT|SHADER_EXCLUDE_CAMERA|SHADER_EXCLUDE_SCATTER),
-
- SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS|SHADER_EXCLUDE_ANY)
+ SHADER_SMOOTH_NORMAL = (1 << 31),
+ SHADER_CAST_SHADOW = (1 << 30),
+ SHADER_AREA_LIGHT = (1 << 29),
+ SHADER_USE_MIS = (1 << 28),
+ SHADER_EXCLUDE_DIFFUSE = (1 << 27),
+ SHADER_EXCLUDE_GLOSSY = (1 << 26),
+ SHADER_EXCLUDE_TRANSMIT = (1 << 25),
+ SHADER_EXCLUDE_CAMERA = (1 << 24),
+ SHADER_EXCLUDE_SCATTER = (1 << 23),
+ SHADER_EXCLUDE_ANY = (SHADER_EXCLUDE_DIFFUSE | SHADER_EXCLUDE_GLOSSY | SHADER_EXCLUDE_TRANSMIT |
+ SHADER_EXCLUDE_CAMERA | SHADER_EXCLUDE_SCATTER),
+
+ SHADER_MASK = ~(SHADER_SMOOTH_NORMAL | SHADER_CAST_SHADOW | SHADER_AREA_LIGHT | SHADER_USE_MIS |
+ SHADER_EXCLUDE_ANY)
} ShaderFlag;
/* Light Type */
typedef enum LightType {
- LIGHT_POINT,
- LIGHT_DISTANT,
- LIGHT_BACKGROUND,
- LIGHT_AREA,
- LIGHT_SPOT,
- LIGHT_TRIANGLE
+ LIGHT_POINT,
+ LIGHT_DISTANT,
+ LIGHT_BACKGROUND,
+ LIGHT_AREA,
+ LIGHT_SPOT,
+ LIGHT_TRIANGLE
} LightType;
/* Camera Type */
-enum CameraType {
- CAMERA_PERSPECTIVE,
- CAMERA_ORTHOGRAPHIC,
- CAMERA_PANORAMA
-};
+enum CameraType { CAMERA_PERSPECTIVE, CAMERA_ORTHOGRAPHIC, CAMERA_PANORAMA };
/* Panorama Type */
enum PanoramaType {
- PANORAMA_EQUIRECTANGULAR = 0,
- PANORAMA_FISHEYE_EQUIDISTANT = 1,
- PANORAMA_FISHEYE_EQUISOLID = 2,
- PANORAMA_MIRRORBALL = 3,
+ PANORAMA_EQUIRECTANGULAR = 0,
+ PANORAMA_FISHEYE_EQUIDISTANT = 1,
+ PANORAMA_FISHEYE_EQUISOLID = 2,
+ PANORAMA_MIRRORBALL = 3,
- PANORAMA_NUM_TYPES,
+ PANORAMA_NUM_TYPES,
};
/* Differential */
typedef struct differential3 {
- float3 dx;
- float3 dy;
+ float3 dx;
+ float3 dy;
} differential3;
typedef struct differential {
- float dx;
- float dy;
+ float dx;
+ float dy;
} differential;
/* Ray */
@@ -657,21 +650,21 @@ typedef struct Ray {
* is fixed.
*/
#ifndef __KERNEL_OPENCL_AMD__
- float3 P; /* origin */
- float3 D; /* direction */
+ float3 P; /* origin */
+ float3 D; /* direction */
- float t; /* length of the ray */
- float time; /* time (for motion blur) */
+ float t; /* length of the ray */
+ float time; /* time (for motion blur) */
#else
- float t; /* length of the ray */
- float time; /* time (for motion blur) */
- float3 P; /* origin */
- float3 D; /* direction */
+ float t; /* length of the ray */
+ float time; /* time (for motion blur) */
+ float3 P; /* origin */
+ float3 D; /* direction */
#endif
#ifdef __RAY_DIFFERENTIALS__
- differential3 dP;
- differential3 dD;
+ differential3 dP;
+ differential3 dD;
#endif
} Ray;
@@ -679,42 +672,42 @@ typedef struct Ray {
typedef struct Intersection {
#ifdef __EMBREE__
- float3 Ng;
+ float3 Ng;
#endif
- float t, u, v;
- int prim;
- int object;
- int type;
+ float t, u, v;
+ int prim;
+ int object;
+ int type;
#ifdef __KERNEL_DEBUG__
- int num_traversed_nodes;
- int num_traversed_instances;
- int num_intersections;
+ int num_traversed_nodes;
+ int num_traversed_instances;
+ int num_intersections;
#endif
} Intersection;
/* Primitives */
typedef enum PrimitiveType {
- PRIMITIVE_NONE = 0,
- PRIMITIVE_TRIANGLE = (1 << 0),
- PRIMITIVE_MOTION_TRIANGLE = (1 << 1),
- PRIMITIVE_CURVE = (1 << 2),
- PRIMITIVE_MOTION_CURVE = (1 << 3),
- /* Lamp primitive is not included below on purpose,
- * since it is no real traceable primitive.
- */
- PRIMITIVE_LAMP = (1 << 4),
-
- PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE|PRIMITIVE_MOTION_TRIANGLE),
- PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE|PRIMITIVE_MOTION_CURVE),
- PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE|PRIMITIVE_MOTION_CURVE),
- PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE|PRIMITIVE_ALL_CURVE),
-
- /* Total number of different traceable primitives.
- * NOTE: This is an actual value, not a bitflag.
- */
- PRIMITIVE_NUM_TOTAL = 4,
+ PRIMITIVE_NONE = 0,
+ PRIMITIVE_TRIANGLE = (1 << 0),
+ PRIMITIVE_MOTION_TRIANGLE = (1 << 1),
+ PRIMITIVE_CURVE = (1 << 2),
+ PRIMITIVE_MOTION_CURVE = (1 << 3),
+ /* Lamp primitive is not included below on purpose,
+ * since it is no real traceable primitive.
+ */
+ PRIMITIVE_LAMP = (1 << 4),
+
+ PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE | PRIMITIVE_MOTION_TRIANGLE),
+ PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE | PRIMITIVE_MOTION_CURVE),
+ PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE | PRIMITIVE_MOTION_CURVE),
+ PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE | PRIMITIVE_ALL_CURVE),
+
+ /* Total number of different traceable primitives.
+ * NOTE: This is an actual value, not a bitflag.
+ */
+ PRIMITIVE_NUM_TOTAL = 4,
} PrimitiveType;
#define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << PRIMITIVE_NUM_TOTAL) | (type))
@@ -723,68 +716,68 @@ typedef enum PrimitiveType {
/* Attributes */
typedef enum AttributePrimitive {
- ATTR_PRIM_TRIANGLE = 0,
- ATTR_PRIM_CURVE,
- ATTR_PRIM_SUBD,
+ ATTR_PRIM_TRIANGLE = 0,
+ ATTR_PRIM_CURVE,
+ ATTR_PRIM_SUBD,
- ATTR_PRIM_TYPES
+ ATTR_PRIM_TYPES
} AttributePrimitive;
typedef enum AttributeElement {
- ATTR_ELEMENT_NONE,
- ATTR_ELEMENT_OBJECT,
- ATTR_ELEMENT_MESH,
- ATTR_ELEMENT_FACE,
- ATTR_ELEMENT_VERTEX,
- ATTR_ELEMENT_VERTEX_MOTION,
- ATTR_ELEMENT_CORNER,
- ATTR_ELEMENT_CORNER_BYTE,
- ATTR_ELEMENT_CURVE,
- ATTR_ELEMENT_CURVE_KEY,
- ATTR_ELEMENT_CURVE_KEY_MOTION,
- ATTR_ELEMENT_VOXEL
+ ATTR_ELEMENT_NONE,
+ ATTR_ELEMENT_OBJECT,
+ ATTR_ELEMENT_MESH,
+ ATTR_ELEMENT_FACE,
+ ATTR_ELEMENT_VERTEX,
+ ATTR_ELEMENT_VERTEX_MOTION,
+ ATTR_ELEMENT_CORNER,
+ ATTR_ELEMENT_CORNER_BYTE,
+ ATTR_ELEMENT_CURVE,
+ ATTR_ELEMENT_CURVE_KEY,
+ ATTR_ELEMENT_CURVE_KEY_MOTION,
+ ATTR_ELEMENT_VOXEL
} AttributeElement;
typedef enum AttributeStandard {
- ATTR_STD_NONE = 0,
- ATTR_STD_VERTEX_NORMAL,
- ATTR_STD_FACE_NORMAL,
- ATTR_STD_UV,
- ATTR_STD_UV_TANGENT,
- ATTR_STD_UV_TANGENT_SIGN,
- ATTR_STD_GENERATED,
- ATTR_STD_GENERATED_TRANSFORM,
- ATTR_STD_POSITION_UNDEFORMED,
- ATTR_STD_POSITION_UNDISPLACED,
- ATTR_STD_MOTION_VERTEX_POSITION,
- ATTR_STD_MOTION_VERTEX_NORMAL,
- ATTR_STD_PARTICLE,
- ATTR_STD_CURVE_INTERCEPT,
- ATTR_STD_CURVE_RANDOM,
- ATTR_STD_PTEX_FACE_ID,
- ATTR_STD_PTEX_UV,
- ATTR_STD_VOLUME_DENSITY,
- ATTR_STD_VOLUME_COLOR,
- ATTR_STD_VOLUME_FLAME,
- ATTR_STD_VOLUME_HEAT,
- ATTR_STD_VOLUME_TEMPERATURE,
- ATTR_STD_VOLUME_VELOCITY,
- ATTR_STD_POINTINESS,
- ATTR_STD_NUM,
-
- ATTR_STD_NOT_FOUND = ~0
+ ATTR_STD_NONE = 0,
+ ATTR_STD_VERTEX_NORMAL,
+ ATTR_STD_FACE_NORMAL,
+ ATTR_STD_UV,
+ ATTR_STD_UV_TANGENT,
+ ATTR_STD_UV_TANGENT_SIGN,
+ ATTR_STD_GENERATED,
+ ATTR_STD_GENERATED_TRANSFORM,
+ ATTR_STD_POSITION_UNDEFORMED,
+ ATTR_STD_POSITION_UNDISPLACED,
+ ATTR_STD_MOTION_VERTEX_POSITION,
+ ATTR_STD_MOTION_VERTEX_NORMAL,
+ ATTR_STD_PARTICLE,
+ ATTR_STD_CURVE_INTERCEPT,
+ ATTR_STD_CURVE_RANDOM,
+ ATTR_STD_PTEX_FACE_ID,
+ ATTR_STD_PTEX_UV,
+ ATTR_STD_VOLUME_DENSITY,
+ ATTR_STD_VOLUME_COLOR,
+ ATTR_STD_VOLUME_FLAME,
+ ATTR_STD_VOLUME_HEAT,
+ ATTR_STD_VOLUME_TEMPERATURE,
+ ATTR_STD_VOLUME_VELOCITY,
+ ATTR_STD_POINTINESS,
+ ATTR_STD_NUM,
+
+ ATTR_STD_NOT_FOUND = ~0
} AttributeStandard;
typedef enum AttributeFlag {
- ATTR_FINAL_SIZE = (1 << 0),
- ATTR_SUBDIVIDED = (1 << 1),
+ ATTR_FINAL_SIZE = (1 << 0),
+ ATTR_SUBDIVIDED = (1 << 1),
} AttributeFlag;
typedef struct AttributeDescriptor {
- AttributeElement element;
- NodeAttributeType type;
- uint flags; /* see enum AttributeFlag */
- int offset;
+ AttributeElement element;
+ NodeAttributeType type;
+ uint flags; /* see enum AttributeFlag */
+ int offset;
} AttributeDescriptor;
/* Closure data */
@@ -794,7 +787,7 @@ typedef struct AttributeDescriptor {
# define MAX_CLOSURE 1
# else
# ifndef __MAX_CLOSURE__
-# define MAX_CLOSURE 64
+# define MAX_CLOSURE 64
# else
# define MAX_CLOSURE __MAX_CLOSURE__
# endif
@@ -815,16 +808,18 @@ typedef struct AttributeDescriptor {
* we assume to be the maximum required alignment for any struct. */
#define SHADER_CLOSURE_BASE \
- float3 weight; \
- ClosureType type; \
- float sample_weight; \
- float3 N
+ float3 weight; \
+ ClosureType type; \
+ float sample_weight; \
+ float3 N
-typedef ccl_addr_space struct ccl_align(16) ShaderClosure {
- SHADER_CLOSURE_BASE;
+typedef ccl_addr_space struct ccl_align(16) ShaderClosure
+{
+ SHADER_CLOSURE_BASE;
- float data[10]; /* pad to 80 bytes */
-} ShaderClosure;
+ float data[10]; /* pad to 80 bytes */
+}
+ShaderClosure;
/* Shader Data
*
@@ -833,272 +828,253 @@ typedef ccl_addr_space struct ccl_align(16) ShaderClosure {
*/
enum ShaderDataFlag {
- /* Runtime flags. */
-
- /* Set when ray hits backside of surface. */
- SD_BACKFACING = (1 << 0),
- /* Shader has non-zero emission. */
- SD_EMISSION = (1 << 1),
- /* Shader has BSDF closure. */
- SD_BSDF = (1 << 2),
- /* Shader has non-singular BSDF closure. */
- SD_BSDF_HAS_EVAL = (1 << 3),
- /* Shader has BSSRDF closure. */
- SD_BSSRDF = (1 << 4),
- /* Shader has holdout closure. */
- SD_HOLDOUT = (1 << 5),
- /* Shader has non-zero volume extinction. */
- SD_EXTINCTION = (1 << 6),
- /* Shader has have volume phase (scatter) closure. */
- SD_SCATTER = (1 << 7),
- /* Shader has transparent closure. */
- SD_TRANSPARENT = (1 << 9),
- /* BSDF requires LCG for evaluation. */
- SD_BSDF_NEEDS_LCG = (1 << 10),
-
- SD_CLOSURE_FLAGS = (SD_EMISSION |
- SD_BSDF |
- SD_BSDF_HAS_EVAL |
- SD_BSSRDF |
- SD_HOLDOUT |
- SD_EXTINCTION |
- SD_SCATTER |
- SD_BSDF_NEEDS_LCG),
-
- /* Shader flags. */
-
- /* direct light sample */
- SD_USE_MIS = (1 << 16),
- /* Has transparent shadow. */
- SD_HAS_TRANSPARENT_SHADOW = (1 << 17),
- /* Has volume shader. */
- SD_HAS_VOLUME = (1 << 18),
- /* Has only volume shader, no surface. */
- SD_HAS_ONLY_VOLUME = (1 << 19),
- /* Has heterogeneous volume. */
- SD_HETEROGENEOUS_VOLUME = (1 << 20),
- /* BSSRDF normal uses bump. */
- SD_HAS_BSSRDF_BUMP = (1 << 21),
- /* Use equiangular volume sampling */
- SD_VOLUME_EQUIANGULAR = (1 << 22),
- /* Use multiple importance volume sampling. */
- SD_VOLUME_MIS = (1 << 23),
- /* Use cubic interpolation for voxels. */
- SD_VOLUME_CUBIC = (1 << 24),
- /* Has data connected to the displacement input or uses bump map. */
- SD_HAS_BUMP = (1 << 25),
- /* Has true displacement. */
- SD_HAS_DISPLACEMENT = (1 << 26),
- /* Has constant emission (value stored in __shaders) */
- SD_HAS_CONSTANT_EMISSION = (1 << 27),
- /* Needs to access attributes */
- SD_NEED_ATTRIBUTES = (1 << 28),
-
- SD_SHADER_FLAGS = (SD_USE_MIS |
- SD_HAS_TRANSPARENT_SHADOW |
- SD_HAS_VOLUME |
- SD_HAS_ONLY_VOLUME |
- SD_HETEROGENEOUS_VOLUME |
- SD_HAS_BSSRDF_BUMP |
- SD_VOLUME_EQUIANGULAR |
- SD_VOLUME_MIS |
- SD_VOLUME_CUBIC |
- SD_HAS_BUMP |
- SD_HAS_DISPLACEMENT |
- SD_HAS_CONSTANT_EMISSION |
- SD_NEED_ATTRIBUTES)
+ /* Runtime flags. */
+
+ /* Set when ray hits backside of surface. */
+ SD_BACKFACING = (1 << 0),
+ /* Shader has non-zero emission. */
+ SD_EMISSION = (1 << 1),
+ /* Shader has BSDF closure. */
+ SD_BSDF = (1 << 2),
+ /* Shader has non-singular BSDF closure. */
+ SD_BSDF_HAS_EVAL = (1 << 3),
+ /* Shader has BSSRDF closure. */
+ SD_BSSRDF = (1 << 4),
+ /* Shader has holdout closure. */
+ SD_HOLDOUT = (1 << 5),
+ /* Shader has non-zero volume extinction. */
+ SD_EXTINCTION = (1 << 6),
+ /* Shader has have volume phase (scatter) closure. */
+ SD_SCATTER = (1 << 7),
+ /* Shader has transparent closure. */
+ SD_TRANSPARENT = (1 << 9),
+ /* BSDF requires LCG for evaluation. */
+ SD_BSDF_NEEDS_LCG = (1 << 10),
+
+ SD_CLOSURE_FLAGS = (SD_EMISSION | SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSSRDF | SD_HOLDOUT |
+ SD_EXTINCTION | SD_SCATTER | SD_BSDF_NEEDS_LCG),
+
+ /* Shader flags. */
+
+ /* direct light sample */
+ SD_USE_MIS = (1 << 16),
+ /* Has transparent shadow. */
+ SD_HAS_TRANSPARENT_SHADOW = (1 << 17),
+ /* Has volume shader. */
+ SD_HAS_VOLUME = (1 << 18),
+ /* Has only volume shader, no surface. */
+ SD_HAS_ONLY_VOLUME = (1 << 19),
+ /* Has heterogeneous volume. */
+ SD_HETEROGENEOUS_VOLUME = (1 << 20),
+ /* BSSRDF normal uses bump. */
+ SD_HAS_BSSRDF_BUMP = (1 << 21),
+ /* Use equiangular volume sampling */
+ SD_VOLUME_EQUIANGULAR = (1 << 22),
+ /* Use multiple importance volume sampling. */
+ SD_VOLUME_MIS = (1 << 23),
+ /* Use cubic interpolation for voxels. */
+ SD_VOLUME_CUBIC = (1 << 24),
+ /* Has data connected to the displacement input or uses bump map. */
+ SD_HAS_BUMP = (1 << 25),
+ /* Has true displacement. */
+ SD_HAS_DISPLACEMENT = (1 << 26),
+ /* Has constant emission (value stored in __shaders) */
+ SD_HAS_CONSTANT_EMISSION = (1 << 27),
+ /* Needs to access attributes */
+ SD_NEED_ATTRIBUTES = (1 << 28),
+
+ SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME |
+ SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR |
+ SD_VOLUME_MIS | SD_VOLUME_CUBIC | SD_HAS_BUMP | SD_HAS_DISPLACEMENT |
+ SD_HAS_CONSTANT_EMISSION | SD_NEED_ATTRIBUTES)
};
- /* Object flags. */
+/* Object flags. */
enum ShaderDataObjectFlag {
- /* Holdout for camera rays. */
- SD_OBJECT_HOLDOUT_MASK = (1 << 0),
- /* Has object motion blur. */
- SD_OBJECT_MOTION = (1 << 1),
- /* Vertices have transform applied. */
- SD_OBJECT_TRANSFORM_APPLIED = (1 << 2),
- /* Vertices have negative scale applied. */
- SD_OBJECT_NEGATIVE_SCALE_APPLIED = (1 << 3),
- /* Object has a volume shader. */
- SD_OBJECT_HAS_VOLUME = (1 << 4),
- /* Object intersects AABB of an object with volume shader. */
- SD_OBJECT_INTERSECTS_VOLUME = (1 << 5),
- /* Has position for motion vertices. */
- SD_OBJECT_HAS_VERTEX_MOTION = (1 << 6),
- /* object is used to catch shadows */
- SD_OBJECT_SHADOW_CATCHER = (1 << 7),
- /* object has volume attributes */
- SD_OBJECT_HAS_VOLUME_ATTRIBUTES = (1 << 8),
-
- SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK |
- SD_OBJECT_MOTION |
- SD_OBJECT_TRANSFORM_APPLIED |
- SD_OBJECT_NEGATIVE_SCALE_APPLIED |
- SD_OBJECT_HAS_VOLUME |
- SD_OBJECT_INTERSECTS_VOLUME |
- SD_OBJECT_SHADOW_CATCHER |
- SD_OBJECT_HAS_VOLUME_ATTRIBUTES)
+ /* Holdout for camera rays. */
+ SD_OBJECT_HOLDOUT_MASK = (1 << 0),
+ /* Has object motion blur. */
+ SD_OBJECT_MOTION = (1 << 1),
+ /* Vertices have transform applied. */
+ SD_OBJECT_TRANSFORM_APPLIED = (1 << 2),
+ /* Vertices have negative scale applied. */
+ SD_OBJECT_NEGATIVE_SCALE_APPLIED = (1 << 3),
+ /* Object has a volume shader. */
+ SD_OBJECT_HAS_VOLUME = (1 << 4),
+ /* Object intersects AABB of an object with volume shader. */
+ SD_OBJECT_INTERSECTS_VOLUME = (1 << 5),
+ /* Has position for motion vertices. */
+ SD_OBJECT_HAS_VERTEX_MOTION = (1 << 6),
+ /* object is used to catch shadows */
+ SD_OBJECT_SHADOW_CATCHER = (1 << 7),
+ /* object has volume attributes */
+ SD_OBJECT_HAS_VOLUME_ATTRIBUTES = (1 << 8),
+
+ SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK | SD_OBJECT_MOTION | SD_OBJECT_TRANSFORM_APPLIED |
+ SD_OBJECT_NEGATIVE_SCALE_APPLIED | SD_OBJECT_HAS_VOLUME |
+ SD_OBJECT_INTERSECTS_VOLUME | SD_OBJECT_SHADOW_CATCHER |
+ SD_OBJECT_HAS_VOLUME_ATTRIBUTES)
};
typedef ccl_addr_space struct ShaderData {
- /* position */
- float3 P;
- /* smooth normal for shading */
- float3 N;
- /* true geometric normal */
- float3 Ng;
- /* view/incoming direction */
- float3 I;
- /* shader id */
- int shader;
- /* booleans describing shader, see ShaderDataFlag */
- int flag;
- /* booleans describing object of the shader, see ShaderDataObjectFlag */
- int object_flag;
-
- /* primitive id if there is one, ~0 otherwise */
- int prim;
-
- /* combined type and curve segment for hair */
- int type;
-
- /* parametric coordinates
- * - barycentric weights for triangles */
- float u;
- float v;
- /* object id if there is one, ~0 otherwise */
- int object;
- /* lamp id if there is one, ~0 otherwise */
- int lamp;
-
- /* motion blur sample time */
- float time;
-
- /* length of the ray being shaded */
- float ray_length;
+ /* position */
+ float3 P;
+ /* smooth normal for shading */
+ float3 N;
+ /* true geometric normal */
+ float3 Ng;
+ /* view/incoming direction */
+ float3 I;
+ /* shader id */
+ int shader;
+ /* booleans describing shader, see ShaderDataFlag */
+ int flag;
+ /* booleans describing object of the shader, see ShaderDataObjectFlag */
+ int object_flag;
+
+ /* primitive id if there is one, ~0 otherwise */
+ int prim;
+
+ /* combined type and curve segment for hair */
+ int type;
+
+ /* parametric coordinates
+ * - barycentric weights for triangles */
+ float u;
+ float v;
+ /* object id if there is one, ~0 otherwise */
+ int object;
+ /* lamp id if there is one, ~0 otherwise */
+ int lamp;
+
+ /* motion blur sample time */
+ float time;
+
+ /* length of the ray being shaded */
+ float ray_length;
#ifdef __RAY_DIFFERENTIALS__
- /* differential of P. these are orthogonal to Ng, not N */
- differential3 dP;
- /* differential of I */
- differential3 dI;
- /* differential of u, v */
- differential du;
- differential dv;
+ /* differential of P. these are orthogonal to Ng, not N */
+ differential3 dP;
+ /* differential of I */
+ differential3 dI;
+ /* differential of u, v */
+ differential du;
+ differential dv;
#endif
#ifdef __DPDU__
- /* differential of P w.r.t. parametric coordinates. note that dPdu is
- * not readily suitable as a tangent for shading on triangles. */
- float3 dPdu;
- float3 dPdv;
+ /* differential of P w.r.t. parametric coordinates. note that dPdu is
+ * not readily suitable as a tangent for shading on triangles. */
+ float3 dPdu;
+ float3 dPdv;
#endif
#ifdef __OBJECT_MOTION__
- /* object <-> world space transformations, cached to avoid
- * re-interpolating them constantly for shading */
- Transform ob_tfm;
- Transform ob_itfm;
+ /* object <-> world space transformations, cached to avoid
+ * re-interpolating them constantly for shading */
+ Transform ob_tfm;
+ Transform ob_itfm;
#endif
- /* ray start position, only set for backgrounds */
- float3 ray_P;
- differential3 ray_dP;
+ /* ray start position, only set for backgrounds */
+ float3 ray_P;
+ differential3 ray_dP;
#ifdef __OSL__
- struct KernelGlobals *osl_globals;
- struct PathState *osl_path_state;
+ struct KernelGlobals *osl_globals;
+ struct PathState *osl_path_state;
#endif
- /* LCG state for closures that require additional random numbers. */
- uint lcg_state;
+ /* LCG state for closures that require additional random numbers. */
+ uint lcg_state;
- /* Closure data, we store a fixed array of closures */
- int num_closure;
- int num_closure_left;
- float randb_closure;
- float3 svm_closure_weight;
+ /* Closure data, we store a fixed array of closures */
+ int num_closure;
+ int num_closure_left;
+ float randb_closure;
+ float3 svm_closure_weight;
- /* Closure weights summed directly, so we can evaluate
- * emission and shadow transparency with MAX_CLOSURE 0. */
- float3 closure_emission_background;
- float3 closure_transparent_extinction;
+ /* Closure weights summed directly, so we can evaluate
+ * emission and shadow transparency with MAX_CLOSURE 0. */
+ float3 closure_emission_background;
+ float3 closure_transparent_extinction;
- /* At the end so we can adjust size in ShaderDataTinyStorage. */
- struct ShaderClosure closure[MAX_CLOSURE];
+ /* At the end so we can adjust size in ShaderDataTinyStorage. */
+ struct ShaderClosure closure[MAX_CLOSURE];
} ShaderData;
typedef ccl_addr_space struct ShaderDataTinyStorage {
- char pad[sizeof(ShaderData) - sizeof(ShaderClosure) * MAX_CLOSURE];
+ char pad[sizeof(ShaderData) - sizeof(ShaderClosure) * MAX_CLOSURE];
} ShaderDataTinyStorage;
-#define AS_SHADER_DATA(shader_data_tiny_storage) ((ShaderData*)shader_data_tiny_storage)
+#define AS_SHADER_DATA(shader_data_tiny_storage) ((ShaderData *)shader_data_tiny_storage)
/* Path State */
#ifdef __VOLUME__
typedef struct VolumeStack {
- int object;
- int shader;
+ int object;
+ int shader;
} VolumeStack;
#endif
typedef struct PathState {
- /* see enum PathRayFlag */
- int flag;
-
- /* random number generator state */
- uint rng_hash; /* per pixel hash */
- int rng_offset; /* dimension offset */
- int sample; /* path sample number */
- int num_samples; /* total number of times this path will be sampled */
- float branch_factor; /* number of branches in indirect paths */
-
- /* bounce counting */
- int bounce;
- int diffuse_bounce;
- int glossy_bounce;
- int transmission_bounce;
- int transparent_bounce;
+ /* see enum PathRayFlag */
+ int flag;
+
+ /* random number generator state */
+ uint rng_hash; /* per pixel hash */
+ int rng_offset; /* dimension offset */
+ int sample; /* path sample number */
+ int num_samples; /* total number of times this path will be sampled */
+ float branch_factor; /* number of branches in indirect paths */
+
+ /* bounce counting */
+ int bounce;
+ int diffuse_bounce;
+ int glossy_bounce;
+ int transmission_bounce;
+ int transparent_bounce;
#ifdef __DENOISING_FEATURES__
- float denoising_feature_weight;
-#endif /* __DENOISING_FEATURES__ */
+ float denoising_feature_weight;
+#endif /* __DENOISING_FEATURES__ */
- /* multiple importance sampling */
- float min_ray_pdf; /* smallest bounce pdf over entire path up to now */
- float ray_pdf; /* last bounce pdf */
+ /* multiple importance sampling */
+ float min_ray_pdf; /* smallest bounce pdf over entire path up to now */
+ float ray_pdf; /* last bounce pdf */
#ifdef __LAMP_MIS__
- float ray_t; /* accumulated distance through transparent surfaces */
+ float ray_t; /* accumulated distance through transparent surfaces */
#endif
- /* volume rendering */
+ /* volume rendering */
#ifdef __VOLUME__
- int volume_bounce;
- int volume_bounds_bounce;
- VolumeStack volume_stack[VOLUME_STACK_SIZE];
+ int volume_bounce;
+ int volume_bounds_bounce;
+ VolumeStack volume_stack[VOLUME_STACK_SIZE];
#endif
} PathState;
/* Struct to gather multiple nearby intersections. */
typedef struct LocalIntersection {
- Ray ray;
- float3 weight[LOCAL_MAX_HITS];
+ Ray ray;
+ float3 weight[LOCAL_MAX_HITS];
- int num_hits;
- struct Intersection hits[LOCAL_MAX_HITS];
- float3 Ng[LOCAL_MAX_HITS];
+ int num_hits;
+ struct Intersection hits[LOCAL_MAX_HITS];
+ float3 Ng[LOCAL_MAX_HITS];
} LocalIntersection;
/* Subsurface */
/* Struct to gather SSS indirect rays and delay tracing them. */
typedef struct SubsurfaceIndirectRays {
- PathState state[BSSRDF_MAX_HITS];
+ PathState state[BSSRDF_MAX_HITS];
- int num_rays;
+ int num_rays;
- struct Ray rays[BSSRDF_MAX_HITS];
- float3 throughputs[BSSRDF_MAX_HITS];
- struct PathRadianceState L_state[BSSRDF_MAX_HITS];
+ struct Ray rays[BSSRDF_MAX_HITS];
+ float3 throughputs[BSSRDF_MAX_HITS];
+ struct PathRadianceState L_state[BSSRDF_MAX_HITS];
} SubsurfaceIndirectRays;
static_assert(BSSRDF_MAX_HITS <= LOCAL_MAX_HITS, "BSSRDF hits too high.");
@@ -1109,424 +1085,424 @@ static_assert(BSSRDF_MAX_HITS <= LOCAL_MAX_HITS, "BSSRDF hits too high.");
* do not use float3 because its size may not be the same on all devices. */
typedef struct KernelCamera {
- /* type */
- int type;
-
- /* panorama */
- int panorama_type;
- float fisheye_fov;
- float fisheye_lens;
- float4 equirectangular_range;
-
- /* stereo */
- float interocular_offset;
- float convergence_distance;
- float pole_merge_angle_from;
- float pole_merge_angle_to;
-
- /* matrices */
- Transform cameratoworld;
- ProjectionTransform rastertocamera;
-
- /* differentials */
- float4 dx;
- float4 dy;
-
- /* depth of field */
- float aperturesize;
- float blades;
- float bladesrotation;
- float focaldistance;
-
- /* motion blur */
- float shuttertime;
- int num_motion_steps, have_perspective_motion;
-
- /* clipping */
- float nearclip;
- float cliplength;
-
- /* sensor size */
- float sensorwidth;
- float sensorheight;
-
- /* render size */
- float width, height;
- int resolution;
-
- /* anamorphic lens bokeh */
- float inv_aperture_ratio;
-
- int is_inside_volume;
-
- /* more matrices */
- ProjectionTransform screentoworld;
- ProjectionTransform rastertoworld;
- ProjectionTransform ndctoworld;
- ProjectionTransform worldtoscreen;
- ProjectionTransform worldtoraster;
- ProjectionTransform worldtondc;
- Transform worldtocamera;
-
- /* Stores changes in the projeciton matrix. Use for camera zoom motion
- * blur and motion pass output for perspective camera. */
- ProjectionTransform perspective_pre;
- ProjectionTransform perspective_post;
-
- /* Transforms for motion pass. */
- Transform motion_pass_pre;
- Transform motion_pass_post;
-
- int shutter_table_offset;
-
- /* Rolling shutter */
- int rolling_shutter_type;
- float rolling_shutter_duration;
-
- int pad;
+ /* type */
+ int type;
+
+ /* panorama */
+ int panorama_type;
+ float fisheye_fov;
+ float fisheye_lens;
+ float4 equirectangular_range;
+
+ /* stereo */
+ float interocular_offset;
+ float convergence_distance;
+ float pole_merge_angle_from;
+ float pole_merge_angle_to;
+
+ /* matrices */
+ Transform cameratoworld;
+ ProjectionTransform rastertocamera;
+
+ /* differentials */
+ float4 dx;
+ float4 dy;
+
+ /* depth of field */
+ float aperturesize;
+ float blades;
+ float bladesrotation;
+ float focaldistance;
+
+ /* motion blur */
+ float shuttertime;
+ int num_motion_steps, have_perspective_motion;
+
+ /* clipping */
+ float nearclip;
+ float cliplength;
+
+ /* sensor size */
+ float sensorwidth;
+ float sensorheight;
+
+ /* render size */
+ float width, height;
+ int resolution;
+
+ /* anamorphic lens bokeh */
+ float inv_aperture_ratio;
+
+ int is_inside_volume;
+
+ /* more matrices */
+ ProjectionTransform screentoworld;
+ ProjectionTransform rastertoworld;
+ ProjectionTransform ndctoworld;
+ ProjectionTransform worldtoscreen;
+ ProjectionTransform worldtoraster;
+ ProjectionTransform worldtondc;
+ Transform worldtocamera;
+
+ /* Stores changes in the projeciton matrix. Use for camera zoom motion
+ * blur and motion pass output for perspective camera. */
+ ProjectionTransform perspective_pre;
+ ProjectionTransform perspective_post;
+
+ /* Transforms for motion pass. */
+ Transform motion_pass_pre;
+ Transform motion_pass_post;
+
+ int shutter_table_offset;
+
+ /* Rolling shutter */
+ int rolling_shutter_type;
+ float rolling_shutter_duration;
+
+ int pad;
} KernelCamera;
static_assert_align(KernelCamera, 16);
typedef struct KernelFilm {
- float exposure;
- int pass_flag;
- int light_pass_flag;
- int pass_stride;
- int use_light_pass;
-
- int pass_combined;
- int pass_depth;
- int pass_normal;
- int pass_motion;
-
- int pass_motion_weight;
- int pass_uv;
- int pass_object_id;
- int pass_material_id;
-
- int pass_diffuse_color;
- int pass_glossy_color;
- int pass_transmission_color;
- int pass_subsurface_color;
-
- int pass_diffuse_indirect;
- int pass_glossy_indirect;
- int pass_transmission_indirect;
- int pass_subsurface_indirect;
- int pass_volume_indirect;
-
- int pass_diffuse_direct;
- int pass_glossy_direct;
- int pass_transmission_direct;
- int pass_subsurface_direct;
- int pass_volume_direct;
-
- int pass_emission;
- int pass_background;
- int pass_ao;
- float pass_alpha_threshold;
-
- int pass_shadow;
- float pass_shadow_scale;
- int filter_table_offset;
- int cryptomatte_passes;
- int cryptomatte_depth;
- int pass_cryptomatte;
-
- int pass_mist;
- float mist_start;
- float mist_inv_depth;
- float mist_falloff;
-
- int pass_denoising_data;
- int pass_denoising_clean;
- int denoising_flags;
-
- /* XYZ to rendering color space transform. float4 instead of float3 to
- * ensure consistent padding/alignment across devices. */
- float4 xyz_to_r;
- float4 xyz_to_g;
- float4 xyz_to_b;
- float4 rgb_to_y;
+ float exposure;
+ int pass_flag;
+ int light_pass_flag;
+ int pass_stride;
+ int use_light_pass;
+
+ int pass_combined;
+ int pass_depth;
+ int pass_normal;
+ int pass_motion;
+
+ int pass_motion_weight;
+ int pass_uv;
+ int pass_object_id;
+ int pass_material_id;
+
+ int pass_diffuse_color;
+ int pass_glossy_color;
+ int pass_transmission_color;
+ int pass_subsurface_color;
+
+ int pass_diffuse_indirect;
+ int pass_glossy_indirect;
+ int pass_transmission_indirect;
+ int pass_subsurface_indirect;
+ int pass_volume_indirect;
+
+ int pass_diffuse_direct;
+ int pass_glossy_direct;
+ int pass_transmission_direct;
+ int pass_subsurface_direct;
+ int pass_volume_direct;
+
+ int pass_emission;
+ int pass_background;
+ int pass_ao;
+ float pass_alpha_threshold;
+
+ int pass_shadow;
+ float pass_shadow_scale;
+ int filter_table_offset;
+ int cryptomatte_passes;
+ int cryptomatte_depth;
+ int pass_cryptomatte;
+
+ int pass_mist;
+ float mist_start;
+ float mist_inv_depth;
+ float mist_falloff;
+
+ int pass_denoising_data;
+ int pass_denoising_clean;
+ int denoising_flags;
+
+ /* XYZ to rendering color space transform. float4 instead of float3 to
+ * ensure consistent padding/alignment across devices. */
+ float4 xyz_to_r;
+ float4 xyz_to_g;
+ float4 xyz_to_b;
+ float4 rgb_to_y;
#ifdef __KERNEL_DEBUG__
- int pass_bvh_traversed_nodes;
- int pass_bvh_traversed_instances;
- int pass_bvh_intersections;
- int pass_ray_bounces;
+ int pass_bvh_traversed_nodes;
+ int pass_bvh_traversed_instances;
+ int pass_bvh_intersections;
+ int pass_ray_bounces;
#endif
} KernelFilm;
static_assert_align(KernelFilm, 16);
typedef struct KernelBackground {
- /* only shader index */
- int surface_shader;
- int volume_shader;
- int transparent;
- float transparent_roughness_squared_threshold;
-
- /* ambient occlusion */
- float ao_factor;
- float ao_distance;
- float ao_bounces_factor;
- float ao_pad;
+ /* only shader index */
+ int surface_shader;
+ int volume_shader;
+ int transparent;
+ float transparent_roughness_squared_threshold;
+
+ /* ambient occlusion */
+ float ao_factor;
+ float ao_distance;
+ float ao_bounces_factor;
+ float ao_pad;
} KernelBackground;
static_assert_align(KernelBackground, 16);
typedef struct KernelIntegrator {
- /* emission */
- int use_direct_light;
- int use_ambient_occlusion;
- int num_distribution;
- int num_all_lights;
- float pdf_triangles;
- float pdf_lights;
- int pdf_background_res_x;
- int pdf_background_res_y;
- float light_inv_rr_threshold;
-
- /* light portals */
- float portal_pdf;
- int num_portals;
- int portal_offset;
-
- /* bounces */
- int max_bounce;
-
- int max_diffuse_bounce;
- int max_glossy_bounce;
- int max_transmission_bounce;
- int max_volume_bounce;
-
- int ao_bounces;
-
- /* transparent */
- int transparent_max_bounce;
- int transparent_shadows;
-
- /* caustics */
- int caustics_reflective;
- int caustics_refractive;
- float filter_glossy;
-
- /* seed */
- int seed;
-
- /* clamp */
- float sample_clamp_direct;
- float sample_clamp_indirect;
-
- /* branched path */
- int branched;
- int volume_decoupled;
- int diffuse_samples;
- int glossy_samples;
- int transmission_samples;
- int ao_samples;
- int mesh_light_samples;
- int subsurface_samples;
- int sample_all_lights_direct;
- int sample_all_lights_indirect;
-
- /* mis */
- int use_lamp_mis;
-
- /* sampler */
- int sampling_pattern;
- int aa_samples;
-
- /* volume render */
- int use_volumes;
- int volume_max_steps;
- float volume_step_size;
- int volume_samples;
-
- int start_sample;
-
- int max_closures;
-
- int pad1, pad2, pad3;
+ /* emission */
+ int use_direct_light;
+ int use_ambient_occlusion;
+ int num_distribution;
+ int num_all_lights;
+ float pdf_triangles;
+ float pdf_lights;
+ int pdf_background_res_x;
+ int pdf_background_res_y;
+ float light_inv_rr_threshold;
+
+ /* light portals */
+ float portal_pdf;
+ int num_portals;
+ int portal_offset;
+
+ /* bounces */
+ int max_bounce;
+
+ int max_diffuse_bounce;
+ int max_glossy_bounce;
+ int max_transmission_bounce;
+ int max_volume_bounce;
+
+ int ao_bounces;
+
+ /* transparent */
+ int transparent_max_bounce;
+ int transparent_shadows;
+
+ /* caustics */
+ int caustics_reflective;
+ int caustics_refractive;
+ float filter_glossy;
+
+ /* seed */
+ int seed;
+
+ /* clamp */
+ float sample_clamp_direct;
+ float sample_clamp_indirect;
+
+ /* branched path */
+ int branched;
+ int volume_decoupled;
+ int diffuse_samples;
+ int glossy_samples;
+ int transmission_samples;
+ int ao_samples;
+ int mesh_light_samples;
+ int subsurface_samples;
+ int sample_all_lights_direct;
+ int sample_all_lights_indirect;
+
+ /* mis */
+ int use_lamp_mis;
+
+ /* sampler */
+ int sampling_pattern;
+ int aa_samples;
+
+ /* volume render */
+ int use_volumes;
+ int volume_max_steps;
+ float volume_step_size;
+ int volume_samples;
+
+ int start_sample;
+
+ int max_closures;
+
+ int pad1, pad2, pad3;
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);
typedef enum KernelBVHLayout {
- BVH_LAYOUT_NONE = 0,
-
- BVH_LAYOUT_BVH2 = (1 << 0),
- BVH_LAYOUT_BVH4 = (1 << 1),
- BVH_LAYOUT_BVH8 = (1 << 2),
- BVH_LAYOUT_EMBREE = (1 << 3),
- BVH_LAYOUT_DEFAULT = BVH_LAYOUT_BVH8,
- BVH_LAYOUT_ALL = (unsigned int)(-1),
+ BVH_LAYOUT_NONE = 0,
+
+ BVH_LAYOUT_BVH2 = (1 << 0),
+ BVH_LAYOUT_BVH4 = (1 << 1),
+ BVH_LAYOUT_BVH8 = (1 << 2),
+ BVH_LAYOUT_EMBREE = (1 << 3),
+ BVH_LAYOUT_DEFAULT = BVH_LAYOUT_BVH8,
+ BVH_LAYOUT_ALL = (unsigned int)(-1),
} KernelBVHLayout;
typedef struct KernelBVH {
- /* Own BVH */
- int root;
- int have_motion;
- int have_curves;
- int have_instancing;
- int bvh_layout;
- int use_bvh_steps;
-
- /* Embree */
+ /* Own BVH */
+ int root;
+ int have_motion;
+ int have_curves;
+ int have_instancing;
+ int bvh_layout;
+ int use_bvh_steps;
+
+ /* Embree */
#ifdef __EMBREE__
- RTCScene scene;
+ RTCScene scene;
# ifndef __KERNEL_64_BIT__
- int pad1;
+ int pad1;
# endif
#else
- int pad1, pad2;
+ int pad1, pad2;
#endif
} KernelBVH;
static_assert_align(KernelBVH, 16);
typedef enum CurveFlag {
- /* runtime flags */
- CURVE_KN_BACKFACING = 1, /* backside of cylinder? */
- CURVE_KN_ENCLOSEFILTER = 2, /* don't consider strands surrounding start point? */
- CURVE_KN_INTERPOLATE = 4, /* render as a curve? */
- CURVE_KN_ACCURATE = 8, /* use accurate intersections test? */
- CURVE_KN_INTERSECTCORRECTION = 16, /* correct for width after determing closest midpoint? */
- CURVE_KN_TRUETANGENTGNORMAL = 32, /* use tangent normal for geometry? */
- CURVE_KN_RIBBONS = 64, /* use flat curve ribbons */
+ /* runtime flags */
+ CURVE_KN_BACKFACING = 1, /* backside of cylinder? */
+ CURVE_KN_ENCLOSEFILTER = 2, /* don't consider strands surrounding start point? */
+ CURVE_KN_INTERPOLATE = 4, /* render as a curve? */
+ CURVE_KN_ACCURATE = 8, /* use accurate intersections test? */
+ CURVE_KN_INTERSECTCORRECTION = 16, /* correct for width after determing closest midpoint? */
+ CURVE_KN_TRUETANGENTGNORMAL = 32, /* use tangent normal for geometry? */
+ CURVE_KN_RIBBONS = 64, /* use flat curve ribbons */
} CurveFlag;
typedef struct KernelCurves {
- int curveflags;
- int subdivisions;
+ int curveflags;
+ int subdivisions;
- float minimum_width;
- float maximum_width;
+ float minimum_width;
+ float maximum_width;
} KernelCurves;
static_assert_align(KernelCurves, 16);
typedef struct KernelTables {
- int beckmann_offset;
- int pad1, pad2, pad3;
+ int beckmann_offset;
+ int pad1, pad2, pad3;
} KernelTables;
static_assert_align(KernelTables, 16);
typedef struct KernelData {
- KernelCamera cam;
- KernelFilm film;
- KernelBackground background;
- KernelIntegrator integrator;
- KernelBVH bvh;
- KernelCurves curve;
- KernelTables tables;
+ KernelCamera cam;
+ KernelFilm film;
+ KernelBackground background;
+ KernelIntegrator integrator;
+ KernelBVH bvh;
+ KernelCurves curve;
+ KernelTables tables;
} KernelData;
static_assert_align(KernelData, 16);
/* Kernel data structures. */
typedef struct KernelObject {
- Transform tfm;
- Transform itfm;
+ Transform tfm;
+ Transform itfm;
- float surface_area;
- float pass_id;
- float random_number;
- int particle_index;
+ float surface_area;
+ float pass_id;
+ float random_number;
+ int particle_index;
- float dupli_generated[3];
- float dupli_uv[2];
+ float dupli_generated[3];
+ float dupli_uv[2];
- int numkeys;
- int numsteps;
- int numverts;
+ int numkeys;
+ int numsteps;
+ int numverts;
- uint patch_map_offset;
- uint attribute_map_offset;
- uint motion_offset;
- uint pad1;
+ uint patch_map_offset;
+ uint attribute_map_offset;
+ uint motion_offset;
+ uint pad1;
- float cryptomatte_object;
- float cryptomatte_asset;
- float pad2, pad3;
+ float cryptomatte_object;
+ float cryptomatte_asset;
+ float pad2, pad3;
} KernelObject;
static_assert_align(KernelObject, 16);
typedef struct KernelSpotLight {
- float radius;
- float invarea;
- float spot_angle;
- float spot_smooth;
- float dir[3];
- float pad;
+ float radius;
+ float invarea;
+ float spot_angle;
+ float spot_smooth;
+ float dir[3];
+ float pad;
} KernelSpotLight;
/* PointLight is SpotLight with only radius and invarea being used. */
typedef struct KernelAreaLight {
- float axisu[3];
- float invarea;
- float axisv[3];
- float pad1;
- float dir[3];
- float pad2;
+ float axisu[3];
+ float invarea;
+ float axisv[3];
+ float pad1;
+ float dir[3];
+ float pad2;
} KernelAreaLight;
typedef struct KernelDistantLight {
- float radius;
- float cosangle;
- float invarea;
- float pad;
+ float radius;
+ float cosangle;
+ float invarea;
+ float pad;
} KernelDistantLight;
typedef struct KernelLight {
- int type;
- float co[3];
- int shader_id;
- int samples;
- float max_bounces;
- float random;
- Transform tfm;
- Transform itfm;
- union {
- KernelSpotLight spot;
- KernelAreaLight area;
- KernelDistantLight distant;
- };
+ int type;
+ float co[3];
+ int shader_id;
+ int samples;
+ float max_bounces;
+ float random;
+ Transform tfm;
+ Transform itfm;
+ union {
+ KernelSpotLight spot;
+ KernelAreaLight area;
+ KernelDistantLight distant;
+ };
} KernelLight;
static_assert_align(KernelLight, 16);
typedef struct KernelLightDistribution {
- float totarea;
- int prim;
- union {
- struct {
- int shader_flag;
- int object_id;
- } mesh_light;
- struct {
- float pad;
- float size;
- } lamp;
- };
+ float totarea;
+ int prim;
+ union {
+ struct {
+ int shader_flag;
+ int object_id;
+ } mesh_light;
+ struct {
+ float pad;
+ float size;
+ } lamp;
+ };
} KernelLightDistribution;
static_assert_align(KernelLightDistribution, 16);
typedef struct KernelParticle {
- int index;
- float age;
- float lifetime;
- float size;
- float4 rotation;
- /* Only xyz are used of the following. float4 instead of float3 are used
- * to ensure consistent padding/alignment across devices. */
- float4 location;
- float4 velocity;
- float4 angular_velocity;
+ int index;
+ float age;
+ float lifetime;
+ float size;
+ float4 rotation;
+ /* Only xyz are used of the following. float4 instead of float3 are used
+ * to ensure consistent padding/alignment across devices. */
+ float4 location;
+ float4 velocity;
+ float4 angular_velocity;
} KernelParticle;
static_assert_align(KernelParticle, 16);
typedef struct KernelShader {
- float constant_emission[3];
- float cryptomatte_id;
- int flags;
- int pass_id;
- int pad2, pad3;
+ float constant_emission[3];
+ float cryptomatte_id;
+ int flags;
+ int pass_id;
+ int pad2, pad3;
} KernelShader;
static_assert_align(KernelShader, 16);
@@ -1545,88 +1521,93 @@ static_assert_align(KernelShader, 16);
/* Queue names */
enum QueueNumber {
- /* All active rays and regenerated rays are enqueued here. */
- QUEUE_ACTIVE_AND_REGENERATED_RAYS = 0,
-
- /* All
- * 1. Background-hit rays,
- * 2. Rays that has exited path-iteration but needs to update output buffer
- * 3. Rays to be regenerated
- * are enqueued here.
- */
- QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
-
- /* All rays for which a shadow ray should be cast to determine radiance
- * contribution for AO are enqueued here.
- */
- QUEUE_SHADOW_RAY_CAST_AO_RAYS,
-
- /* All rays for which a shadow ray should be cast to determine radiance
- * contributing for direct lighting are enqueued here.
- */
- QUEUE_SHADOW_RAY_CAST_DL_RAYS,
-
- /* Rays sorted according to shader->id */
- QUEUE_SHADER_SORTED_RAYS,
+ /* All active rays and regenerated rays are enqueued here. */
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS = 0,
+
+ /* All
+ * 1. Background-hit rays,
+ * 2. Rays that has exited path-iteration but needs to update output buffer
+ * 3. Rays to be regenerated
+ * are enqueued here.
+ */
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+
+ /* All rays for which a shadow ray should be cast to determine radiance
+ * contribution for AO are enqueued here.
+ */
+ QUEUE_SHADOW_RAY_CAST_AO_RAYS,
+
+ /* All rays for which a shadow ray should be cast to determine radiance
+ * contributing for direct lighting are enqueued here.
+ */
+ QUEUE_SHADOW_RAY_CAST_DL_RAYS,
+
+ /* Rays sorted according to shader->id */
+ QUEUE_SHADER_SORTED_RAYS,
#ifdef __BRANCHED_PATH__
- /* All rays moving to next iteration of the indirect loop for light */
- QUEUE_LIGHT_INDIRECT_ITER,
- /* Queue of all inactive rays. These are candidates for sharing work of indirect loops */
- QUEUE_INACTIVE_RAYS,
+ /* All rays moving to next iteration of the indirect loop for light */
+ QUEUE_LIGHT_INDIRECT_ITER,
+ /* Queue of all inactive rays. These are candidates for sharing work of indirect loops */
+ QUEUE_INACTIVE_RAYS,
# ifdef __VOLUME__
- /* All rays moving to next iteration of the indirect loop for volumes */
- QUEUE_VOLUME_INDIRECT_ITER,
+ /* All rays moving to next iteration of the indirect loop for volumes */
+ QUEUE_VOLUME_INDIRECT_ITER,
# endif
# ifdef __SUBSURFACE__
- /* All rays moving to next iteration of the indirect loop for subsurface */
- QUEUE_SUBSURFACE_INDIRECT_ITER,
+ /* All rays moving to next iteration of the indirect loop for subsurface */
+ QUEUE_SUBSURFACE_INDIRECT_ITER,
# endif
-#endif /* __BRANCHED_PATH__ */
+#endif /* __BRANCHED_PATH__ */
- NUM_QUEUES
+ NUM_QUEUES
};
/* We use RAY_STATE_MASK to get ray_state */
#define RAY_STATE_MASK 0x0F
#define RAY_FLAG_MASK 0xF0
enum RayState {
- RAY_INVALID = 0,
- /* Denotes ray is actively involved in path-iteration. */
- RAY_ACTIVE,
- /* Denotes ray has completed processing all samples and is inactive. */
- RAY_INACTIVE,
- /* Denotes ray has exited path-iteration and needs to update output buffer. */
- RAY_UPDATE_BUFFER,
- /* Denotes ray needs to skip most surface shader work. */
- RAY_HAS_ONLY_VOLUME,
- /* Donotes ray has hit background */
- RAY_HIT_BACKGROUND,
- /* Denotes ray has to be regenerated */
- RAY_TO_REGENERATE,
- /* Denotes ray has been regenerated */
- RAY_REGENERATED,
- /* Denotes ray is moving to next iteration of the branched indirect loop */
- RAY_LIGHT_INDIRECT_NEXT_ITER,
- RAY_VOLUME_INDIRECT_NEXT_ITER,
- RAY_SUBSURFACE_INDIRECT_NEXT_ITER,
-
- /* Ray flags */
-
- /* Flags to denote that the ray is currently evaluating the branched indirect loop */
- RAY_BRANCHED_LIGHT_INDIRECT = (1 << 4),
- RAY_BRANCHED_VOLUME_INDIRECT = (1 << 5),
- RAY_BRANCHED_SUBSURFACE_INDIRECT = (1 << 6),
- RAY_BRANCHED_INDIRECT = (RAY_BRANCHED_LIGHT_INDIRECT | RAY_BRANCHED_VOLUME_INDIRECT | RAY_BRANCHED_SUBSURFACE_INDIRECT),
-
- /* Ray is evaluating an iteration of an indirect loop for another thread */
- RAY_BRANCHED_INDIRECT_SHARED = (1 << 7),
+ RAY_INVALID = 0,
+ /* Denotes ray is actively involved in path-iteration. */
+ RAY_ACTIVE,
+ /* Denotes ray has completed processing all samples and is inactive. */
+ RAY_INACTIVE,
+ /* Denotes ray has exited path-iteration and needs to update output buffer. */
+ RAY_UPDATE_BUFFER,
+ /* Denotes ray needs to skip most surface shader work. */
+ RAY_HAS_ONLY_VOLUME,
+ /* Donotes ray has hit background */
+ RAY_HIT_BACKGROUND,
+ /* Denotes ray has to be regenerated */
+ RAY_TO_REGENERATE,
+ /* Denotes ray has been regenerated */
+ RAY_REGENERATED,
+ /* Denotes ray is moving to next iteration of the branched indirect loop */
+ RAY_LIGHT_INDIRECT_NEXT_ITER,
+ RAY_VOLUME_INDIRECT_NEXT_ITER,
+ RAY_SUBSURFACE_INDIRECT_NEXT_ITER,
+
+ /* Ray flags */
+
+ /* Flags to denote that the ray is currently evaluating the branched indirect loop */
+ RAY_BRANCHED_LIGHT_INDIRECT = (1 << 4),
+ RAY_BRANCHED_VOLUME_INDIRECT = (1 << 5),
+ RAY_BRANCHED_SUBSURFACE_INDIRECT = (1 << 6),
+ RAY_BRANCHED_INDIRECT = (RAY_BRANCHED_LIGHT_INDIRECT | RAY_BRANCHED_VOLUME_INDIRECT |
+ RAY_BRANCHED_SUBSURFACE_INDIRECT),
+
+ /* Ray is evaluating an iteration of an indirect loop for another thread */
+ RAY_BRANCHED_INDIRECT_SHARED = (1 << 7),
};
-#define ASSIGN_RAY_STATE(ray_state, ray_index, state) (ray_state[ray_index] = ((ray_state[ray_index] & RAY_FLAG_MASK) | state))
-#define IS_STATE(ray_state, ray_index, state) ((ray_index) != QUEUE_EMPTY_SLOT && ((ray_state)[(ray_index)] & RAY_STATE_MASK) == (state))
-#define ADD_RAY_FLAG(ray_state, ray_index, flag) (ray_state[ray_index] = (ray_state[ray_index] | flag))
-#define REMOVE_RAY_FLAG(ray_state, ray_index, flag) (ray_state[ray_index] = (ray_state[ray_index] & (~flag)))
+#define ASSIGN_RAY_STATE(ray_state, ray_index, state) \
+ (ray_state[ray_index] = ((ray_state[ray_index] & RAY_FLAG_MASK) | state))
+#define IS_STATE(ray_state, ray_index, state) \
+ ((ray_index) != QUEUE_EMPTY_SLOT && ((ray_state)[(ray_index)] & RAY_STATE_MASK) == (state))
+#define ADD_RAY_FLAG(ray_state, ray_index, flag) \
+ (ray_state[ray_index] = (ray_state[ray_index] | flag))
+#define REMOVE_RAY_FLAG(ray_state, ray_index, flag) \
+ (ray_state[ray_index] = (ray_state[ray_index] & (~flag)))
#define IS_FLAG(ray_state, ray_index, flag) (ray_state[ray_index] & flag)
/* Patches */
@@ -1642,17 +1623,17 @@ enum RayState {
/* Work Tiles */
typedef struct WorkTile {
- uint x, y, w, h;
+ uint x, y, w, h;
- uint start_sample;
- uint num_samples;
+ uint start_sample;
+ uint num_samples;
- uint offset;
- uint stride;
+ uint offset;
+ uint stride;
- ccl_global float *buffer;
+ ccl_global float *buffer;
} WorkTile;
CCL_NAMESPACE_END
-#endif /* __KERNEL_TYPES_H__ */
+#endif /* __KERNEL_TYPES_H__ */
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 44c8f795d2c..e024003252f 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -19,9 +19,9 @@ CCL_NAMESPACE_BEGIN
/* Events for probalistic scattering */
typedef enum VolumeIntegrateResult {
- VOLUME_PATH_SCATTERED = 0,
- VOLUME_PATH_ATTENUATED = 1,
- VOLUME_PATH_MISSED = 2
+ VOLUME_PATH_SCATTERED = 0,
+ VOLUME_PATH_ATTENUATED = 1,
+ VOLUME_PATH_MISSED = 2
} VolumeIntegrateResult;
/* Volume shader properties
@@ -30,9 +30,9 @@ typedef enum VolumeIntegrateResult {
* sigma_t = sigma_a + sigma_s */
typedef struct VolumeShaderCoefficients {
- float3 sigma_t;
- float3 sigma_s;
- float3 emission;
+ float3 sigma_t;
+ float3 sigma_s;
+ float3 emission;
} VolumeShaderCoefficients;
#ifdef __VOLUME__
@@ -44,16 +44,16 @@ ccl_device_inline bool volume_shader_extinction_sample(KernelGlobals *kg,
float3 P,
float3 *extinction)
{
- sd->P = P;
- shader_eval_volume(kg, sd, state, state->volume_stack, PATH_RAY_SHADOW);
-
- if(sd->flag & SD_EXTINCTION) {
- *extinction = sd->closure_transparent_extinction;
- return true;
- }
- else {
- return false;
- }
+ sd->P = P;
+ shader_eval_volume(kg, sd, state, state->volume_stack, PATH_RAY_SHADOW);
+
+ if (sd->flag & SD_EXTINCTION) {
+ *extinction = sd->closure_transparent_extinction;
+ return true;
+ }
+ else {
+ return false;
+ }
}
/* evaluate shader to get absorption, scattering and emission at P */
@@ -63,97 +63,97 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals *kg,
float3 P,
VolumeShaderCoefficients *coeff)
{
- sd->P = P;
- shader_eval_volume(kg, sd, state, state->volume_stack, state->flag);
+ sd->P = P;
+ shader_eval_volume(kg, sd, state, state->volume_stack, state->flag);
- if(!(sd->flag & (SD_EXTINCTION|SD_SCATTER|SD_EMISSION)))
- return false;
+ if (!(sd->flag & (SD_EXTINCTION | SD_SCATTER | SD_EMISSION)))
+ return false;
- coeff->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
- coeff->sigma_t = (sd->flag & SD_EXTINCTION)? sd->closure_transparent_extinction:
- make_float3(0.0f, 0.0f, 0.0f);
- coeff->emission = (sd->flag & SD_EMISSION)? sd->closure_emission_background:
- make_float3(0.0f, 0.0f, 0.0f);
+ coeff->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ coeff->sigma_t = (sd->flag & SD_EXTINCTION) ? sd->closure_transparent_extinction :
+ make_float3(0.0f, 0.0f, 0.0f);
+ coeff->emission = (sd->flag & SD_EMISSION) ? sd->closure_emission_background :
+ make_float3(0.0f, 0.0f, 0.0f);
- if(sd->flag & SD_SCATTER) {
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ if (sd->flag & SD_SCATTER) {
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_VOLUME(sc->type))
- coeff->sigma_s += sc->weight;
- }
- }
+ if (CLOSURE_IS_VOLUME(sc->type))
+ coeff->sigma_s += sc->weight;
+ }
+ }
- return true;
+ return true;
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
ccl_device float3 volume_color_transmittance(float3 sigma, float t)
{
- return exp3(-sigma * t);
+ return exp3(-sigma * t);
}
ccl_device float kernel_volume_channel_get(float3 value, int channel)
{
- return (channel == 0)? value.x: ((channel == 1)? value.y: value.z);
+ return (channel == 0) ? value.x : ((channel == 1) ? value.y : value.z);
}
#ifdef __VOLUME__
ccl_device bool volume_stack_is_heterogeneous(KernelGlobals *kg, ccl_addr_space VolumeStack *stack)
{
- for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
- int shader_flag = kernel_tex_fetch(__shaders, (stack[i].shader & SHADER_MASK)).flags;
-
- if(shader_flag & SD_HETEROGENEOUS_VOLUME) {
- return true;
- }
- else if(shader_flag & SD_NEED_ATTRIBUTES) {
- /* We want to render world or objects without any volume grids
- * as homogenous, but can only verify this at runtime since other
- * heterogenous volume objects may be using the same shader. */
- int object = stack[i].object;
- if(object != OBJECT_NONE) {
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_HAS_VOLUME_ATTRIBUTES) {
- return true;
- }
- }
- }
- }
-
- return false;
+ for (int i = 0; stack[i].shader != SHADER_NONE; i++) {
+ int shader_flag = kernel_tex_fetch(__shaders, (stack[i].shader & SHADER_MASK)).flags;
+
+ if (shader_flag & SD_HETEROGENEOUS_VOLUME) {
+ return true;
+ }
+ else if (shader_flag & SD_NEED_ATTRIBUTES) {
+ /* We want to render world or objects without any volume grids
+ * as homogenous, but can only verify this at runtime since other
+ * heterogenous volume objects may be using the same shader. */
+ int object = stack[i].object;
+ if (object != OBJECT_NONE) {
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_HAS_VOLUME_ATTRIBUTES) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
}
ccl_device int volume_stack_sampling_method(KernelGlobals *kg, VolumeStack *stack)
{
- if(kernel_data.integrator.num_all_lights == 0)
- return 0;
+ if (kernel_data.integrator.num_all_lights == 0)
+ return 0;
- int method = -1;
+ int method = -1;
- for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
- int shader_flag = kernel_tex_fetch(__shaders, (stack[i].shader & SHADER_MASK)).flags;
+ for (int i = 0; stack[i].shader != SHADER_NONE; i++) {
+ int shader_flag = kernel_tex_fetch(__shaders, (stack[i].shader & SHADER_MASK)).flags;
- if(shader_flag & SD_VOLUME_MIS) {
- return SD_VOLUME_MIS;
- }
- else if(shader_flag & SD_VOLUME_EQUIANGULAR) {
- if(method == 0)
- return SD_VOLUME_MIS;
+ if (shader_flag & SD_VOLUME_MIS) {
+ return SD_VOLUME_MIS;
+ }
+ else if (shader_flag & SD_VOLUME_EQUIANGULAR) {
+ if (method == 0)
+ return SD_VOLUME_MIS;
- method = SD_VOLUME_EQUIANGULAR;
- }
- else {
- if(method == SD_VOLUME_EQUIANGULAR)
- return SD_VOLUME_MIS;
+ method = SD_VOLUME_EQUIANGULAR;
+ }
+ else {
+ if (method == SD_VOLUME_EQUIANGULAR)
+ return SD_VOLUME_MIS;
- method = 0;
- }
- }
+ method = 0;
+ }
+ }
- return method;
+ return method;
}
ccl_device_inline void kernel_volume_step_init(KernelGlobals *kg,
@@ -162,16 +162,16 @@ ccl_device_inline void kernel_volume_step_init(KernelGlobals *kg,
float *step_size,
float *step_offset)
{
- const int max_steps = kernel_data.integrator.volume_max_steps;
- float step = min(kernel_data.integrator.volume_step_size, t);
+ const int max_steps = kernel_data.integrator.volume_max_steps;
+ float step = min(kernel_data.integrator.volume_step_size, t);
- /* compute exact steps in advance for malloc */
- if(t > max_steps * step) {
- step = t / (float)max_steps;
- }
+ /* compute exact steps in advance for malloc */
+ if (t > max_steps * step) {
+ step = t / (float)max_steps;
+ }
- *step_size = step;
- *step_offset = path_state_rng_1D_hash(kg, state, 0x1e31d8a4) * step;
+ *step_size = step;
+ *step_offset = path_state_rng_1D_hash(kg, state, 0x1e31d8a4) * step;
}
/* Volume Shadows
@@ -187,10 +187,10 @@ ccl_device void kernel_volume_shadow_homogeneous(KernelGlobals *kg,
ShaderData *sd,
float3 *throughput)
{
- float3 sigma_t;
+ float3 sigma_t;
- if(volume_shader_extinction_sample(kg, sd, state, ray->P, &sigma_t))
- *throughput *= volume_color_transmittance(sigma_t, ray->t);
+ if (volume_shader_extinction_sample(kg, sd, state, ray->P, &sigma_t))
+ *throughput *= volume_color_transmittance(sigma_t, ray->t);
}
/* heterogeneous volume: integrate stepping through the volume until we
@@ -201,57 +201,57 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
ShaderData *sd,
float3 *throughput)
{
- float3 tp = *throughput;
- const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
-
- /* prepare for stepping */
- int max_steps = kernel_data.integrator.volume_max_steps;
- float step_offset, step_size;
- kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
-
- /* compute extinction at the start */
- float t = 0.0f;
-
- float3 sum = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < max_steps; i++) {
- /* advance to new position */
- float new_t = min(ray->t, (i+1) * step_size);
-
- /* use random position inside this segment to sample shader, adjust
- * for last step that is shorter than other steps. */
- if(new_t == ray->t) {
- step_offset *= (new_t - t) / step_size;
- }
-
- float3 new_P = ray->P + ray->D * (t + step_offset);
- float3 sigma_t;
-
- /* compute attenuation over segment */
- if(volume_shader_extinction_sample(kg, sd, state, new_P, &sigma_t)) {
- /* Compute expf() only for every Nth step, to save some calculations
- * because exp(a)*exp(b) = exp(a+b), also do a quick tp_eps check then. */
-
- sum += (-sigma_t * (new_t - t));
- if((i & 0x07) == 0) { /* ToDo: Other interval? */
- tp = *throughput * exp3(sum);
-
- /* stop if nearly all light is blocked */
- if(tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps)
- break;
- }
- }
-
- /* stop if at the end of the volume */
- t = new_t;
- if(t == ray->t) {
- /* Update throughput in case we haven't done it above */
- tp = *throughput * exp3(sum);
- break;
- }
- }
-
- *throughput = tp;
+ float3 tp = *throughput;
+ const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
+
+ /* prepare for stepping */
+ int max_steps = kernel_data.integrator.volume_max_steps;
+ float step_offset, step_size;
+ kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
+
+ /* compute extinction at the start */
+ float t = 0.0f;
+
+ float3 sum = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < max_steps; i++) {
+ /* advance to new position */
+ float new_t = min(ray->t, (i + 1) * step_size);
+
+ /* use random position inside this segment to sample shader, adjust
+ * for last step that is shorter than other steps. */
+ if (new_t == ray->t) {
+ step_offset *= (new_t - t) / step_size;
+ }
+
+ float3 new_P = ray->P + ray->D * (t + step_offset);
+ float3 sigma_t;
+
+ /* compute attenuation over segment */
+ if (volume_shader_extinction_sample(kg, sd, state, new_P, &sigma_t)) {
+ /* Compute expf() only for every Nth step, to save some calculations
+ * because exp(a)*exp(b) = exp(a+b), also do a quick tp_eps check then. */
+
+ sum += (-sigma_t * (new_t - t));
+ if ((i & 0x07) == 0) { /* ToDo: Other interval? */
+ tp = *throughput * exp3(sum);
+
+ /* stop if nearly all light is blocked */
+ if (tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps)
+ break;
+ }
+ }
+
+ /* stop if at the end of the volume */
+ t = new_t;
+ if (t == ray->t) {
+ /* Update throughput in case we haven't done it above */
+ tp = *throughput * exp3(sum);
+ break;
+ }
+ }
+
+ *throughput = tp;
}
/* get the volume attenuation over line segment defined by ray, with the
@@ -262,422 +262,433 @@ ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg,
Ray *ray,
float3 *throughput)
{
- shader_setup_from_volume(kg, shadow_sd, ray);
+ shader_setup_from_volume(kg, shadow_sd, ray);
- if(volume_stack_is_heterogeneous(kg, state->volume_stack))
- kernel_volume_shadow_heterogeneous(kg, state, ray, shadow_sd, throughput);
- else
- kernel_volume_shadow_homogeneous(kg, state, ray, shadow_sd, throughput);
+ if (volume_stack_is_heterogeneous(kg, state->volume_stack))
+ kernel_volume_shadow_heterogeneous(kg, state, ray, shadow_sd, throughput);
+ else
+ kernel_volume_shadow_homogeneous(kg, state, ray, shadow_sd, throughput);
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
/* Equi-angular sampling as in:
* "Importance Sampling Techniques for Path Tracing in Participating Media" */
ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, float xi, float *pdf)
{
- float t = ray->t;
-
- float delta = dot((light_P - ray->P) , ray->D);
- float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
- if(UNLIKELY(D == 0.0f)) {
- *pdf = 0.0f;
- return 0.0f;
- }
- float theta_a = -atan2f(delta, D);
- float theta_b = atan2f(t - delta, D);
- float t_ = D * tanf((xi * theta_b) + (1 - xi) * theta_a);
- if(UNLIKELY(theta_b == theta_a)) {
- *pdf = 0.0f;
- return 0.0f;
- }
- *pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
-
- return min(t, delta + t_); /* min is only for float precision errors */
+ float t = ray->t;
+
+ float delta = dot((light_P - ray->P), ray->D);
+ float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
+ if (UNLIKELY(D == 0.0f)) {
+ *pdf = 0.0f;
+ return 0.0f;
+ }
+ float theta_a = -atan2f(delta, D);
+ float theta_b = atan2f(t - delta, D);
+ float t_ = D * tanf((xi * theta_b) + (1 - xi) * theta_a);
+ if (UNLIKELY(theta_b == theta_a)) {
+ *pdf = 0.0f;
+ return 0.0f;
+ }
+ *pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
+
+ return min(t, delta + t_); /* min is only for float precision errors */
}
ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float sample_t)
{
- float delta = dot((light_P - ray->P) , ray->D);
- float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
- if(UNLIKELY(D == 0.0f)) {
- return 0.0f;
- }
+ float delta = dot((light_P - ray->P), ray->D);
+ float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
+ if (UNLIKELY(D == 0.0f)) {
+ return 0.0f;
+ }
- float t = ray->t;
- float t_ = sample_t - delta;
+ float t = ray->t;
+ float t_ = sample_t - delta;
- float theta_a = -atan2f(delta, D);
- float theta_b = atan2f(t - delta, D);
- if(UNLIKELY(theta_b == theta_a)) {
- return 0.0f;
- }
+ float theta_a = -atan2f(delta, D);
+ float theta_b = atan2f(t - delta, D);
+ if (UNLIKELY(theta_b == theta_a)) {
+ return 0.0f;
+ }
- float pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
+ float pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
- return pdf;
+ return pdf;
}
/* Distance sampling */
-ccl_device float kernel_volume_distance_sample(float max_t, float3 sigma_t, int channel, float xi, float3 *transmittance, float3 *pdf)
+ccl_device float kernel_volume_distance_sample(
+ float max_t, float3 sigma_t, int channel, float xi, float3 *transmittance, float3 *pdf)
{
- /* xi is [0, 1[ so log(0) should never happen, division by zero is
- * avoided because sample_sigma_t > 0 when SD_SCATTER is set */
- float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
- float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
- float sample_transmittance = kernel_volume_channel_get(full_transmittance, channel);
+ /* xi is [0, 1[ so log(0) should never happen, division by zero is
+ * avoided because sample_sigma_t > 0 when SD_SCATTER is set */
+ float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
+ float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
+ float sample_transmittance = kernel_volume_channel_get(full_transmittance, channel);
- float sample_t = min(max_t, -logf(1.0f - xi*(1.0f - sample_transmittance))/sample_sigma_t);
+ float sample_t = min(max_t, -logf(1.0f - xi * (1.0f - sample_transmittance)) / sample_sigma_t);
- *transmittance = volume_color_transmittance(sigma_t, sample_t);
- *pdf = safe_divide_color(sigma_t * *transmittance, make_float3(1.0f, 1.0f, 1.0f) - full_transmittance);
+ *transmittance = volume_color_transmittance(sigma_t, sample_t);
+ *pdf = safe_divide_color(sigma_t * *transmittance,
+ make_float3(1.0f, 1.0f, 1.0f) - full_transmittance);
- /* todo: optimization: when taken together with hit/miss decision,
- * the full_transmittance cancels out drops out and xi does not
- * need to be remapped */
+ /* todo: optimization: when taken together with hit/miss decision,
+ * the full_transmittance cancels out drops out and xi does not
+ * need to be remapped */
- return sample_t;
+ return sample_t;
}
ccl_device float3 kernel_volume_distance_pdf(float max_t, float3 sigma_t, float sample_t)
{
- float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
- float3 transmittance = volume_color_transmittance(sigma_t, sample_t);
+ float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
+ float3 transmittance = volume_color_transmittance(sigma_t, sample_t);
- return safe_divide_color(sigma_t * transmittance, make_float3(1.0f, 1.0f, 1.0f) - full_transmittance);
+ return safe_divide_color(sigma_t * transmittance,
+ make_float3(1.0f, 1.0f, 1.0f) - full_transmittance);
}
/* Emission */
-ccl_device float3 kernel_volume_emission_integrate(VolumeShaderCoefficients *coeff, int closure_flag, float3 transmittance, float t)
+ccl_device float3 kernel_volume_emission_integrate(VolumeShaderCoefficients *coeff,
+ int closure_flag,
+ float3 transmittance,
+ float t)
{
- /* integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t
- * this goes to E * t as sigma_t goes to zero
- *
- * todo: we should use an epsilon to avoid precision issues near zero sigma_t */
- float3 emission = coeff->emission;
-
- if(closure_flag & SD_EXTINCTION) {
- float3 sigma_t = coeff->sigma_t;
-
- emission.x *= (sigma_t.x > 0.0f)? (1.0f - transmittance.x)/sigma_t.x: t;
- emission.y *= (sigma_t.y > 0.0f)? (1.0f - transmittance.y)/sigma_t.y: t;
- emission.z *= (sigma_t.z > 0.0f)? (1.0f - transmittance.z)/sigma_t.z: t;
- }
- else
- emission *= t;
-
- return emission;
+ /* integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t
+ * this goes to E * t as sigma_t goes to zero
+ *
+ * todo: we should use an epsilon to avoid precision issues near zero sigma_t */
+ float3 emission = coeff->emission;
+
+ if (closure_flag & SD_EXTINCTION) {
+ float3 sigma_t = coeff->sigma_t;
+
+ emission.x *= (sigma_t.x > 0.0f) ? (1.0f - transmittance.x) / sigma_t.x : t;
+ emission.y *= (sigma_t.y > 0.0f) ? (1.0f - transmittance.y) / sigma_t.y : t;
+ emission.z *= (sigma_t.z > 0.0f) ? (1.0f - transmittance.z) / sigma_t.z : t;
+ }
+ else
+ emission *= t;
+
+ return emission;
}
/* Volume Path */
-ccl_device int kernel_volume_sample_channel(float3 albedo, float3 throughput, float rand, float3 *pdf)
+ccl_device int kernel_volume_sample_channel(float3 albedo,
+ float3 throughput,
+ float rand,
+ float3 *pdf)
{
- /* Sample color channel proportional to throughput and single scattering
- * albedo, to significantly reduce noise with many bounce, following:
- *
- * "Practical and Controllable Subsurface Scattering for Production Path
- * Tracing". Matt Jen-Yuan Chiang, Peter Kutz, Brent Burley. SIGGRAPH 2016. */
- float3 weights = fabs(throughput * albedo);
- float sum_weights = weights.x + weights.y + weights.z;
- float3 weights_pdf;
-
- if(sum_weights > 0.0f) {
- weights_pdf = weights/sum_weights;
- }
- else {
- weights_pdf = make_float3(1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f);
- }
-
- *pdf = weights_pdf;
-
- /* OpenCL does not support -> on float3, so don't use pdf->x. */
- if(rand < weights_pdf.x) {
- return 0;
- }
- else if(rand < weights_pdf.x + weights_pdf.y) {
- return 1;
- }
- else {
- return 2;
- }
+ /* Sample color channel proportional to throughput and single scattering
+ * albedo, to significantly reduce noise with many bounce, following:
+ *
+ * "Practical and Controllable Subsurface Scattering for Production Path
+ * Tracing". Matt Jen-Yuan Chiang, Peter Kutz, Brent Burley. SIGGRAPH 2016. */
+ float3 weights = fabs(throughput * albedo);
+ float sum_weights = weights.x + weights.y + weights.z;
+ float3 weights_pdf;
+
+ if (sum_weights > 0.0f) {
+ weights_pdf = weights / sum_weights;
+ }
+ else {
+ weights_pdf = make_float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
+ }
+
+ *pdf = weights_pdf;
+
+ /* OpenCL does not support -> on float3, so don't use pdf->x. */
+ if (rand < weights_pdf.x) {
+ return 0;
+ }
+ else if (rand < weights_pdf.x + weights_pdf.y) {
+ return 1;
+ }
+ else {
+ return 2;
+ }
}
#ifdef __VOLUME__
/* homogeneous volume: assume shader evaluation at the start gives
* the volume shading coefficient for the entire line segment */
-ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(
- KernelGlobals *kg,
- ccl_addr_space PathState *state,
- Ray *ray,
- ShaderData *sd,
- PathRadiance *L,
- ccl_addr_space float3 *throughput,
- bool probalistic_scatter)
+ccl_device VolumeIntegrateResult
+kernel_volume_integrate_homogeneous(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ ShaderData *sd,
+ PathRadiance *L,
+ ccl_addr_space float3 *throughput,
+ bool probalistic_scatter)
{
- VolumeShaderCoefficients coeff;
-
- if(!volume_shader_sample(kg, sd, state, ray->P, &coeff))
- return VOLUME_PATH_MISSED;
-
- int closure_flag = sd->flag;
- float t = ray->t;
- float3 new_tp;
-
-#ifdef __VOLUME_SCATTER__
- /* randomly scatter, and if we do t is shortened */
- if(closure_flag & SD_SCATTER) {
- /* Sample channel, use MIS with balance heuristic. */
- float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
- float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
- float3 channel_pdf;
- int channel = kernel_volume_sample_channel(albedo, *throughput, rphase, &channel_pdf);
-
- /* decide if we will hit or miss */
- bool scatter = true;
- float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
-
- if(probalistic_scatter) {
- float sample_sigma_t = kernel_volume_channel_get(coeff.sigma_t, channel);
- float sample_transmittance = expf(-sample_sigma_t * t);
-
- if(1.0f - xi >= sample_transmittance) {
- scatter = true;
-
- /* rescale random number so we can reuse it */
- xi = 1.0f - (1.0f - xi - sample_transmittance)/(1.0f - sample_transmittance);
-
- }
- else
- scatter = false;
- }
-
- if(scatter) {
- /* scattering */
- float3 pdf;
- float3 transmittance;
- float sample_t;
-
- /* distance sampling */
- sample_t = kernel_volume_distance_sample(ray->t, coeff.sigma_t, channel, xi, &transmittance, &pdf);
-
- /* modify pdf for hit/miss decision */
- if(probalistic_scatter)
- pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(coeff.sigma_t, t);
-
- new_tp = *throughput * coeff.sigma_s * transmittance / dot(channel_pdf, pdf);
- t = sample_t;
- }
- else {
- /* no scattering */
- float3 transmittance = volume_color_transmittance(coeff.sigma_t, t);
- float pdf = dot(channel_pdf, transmittance);
- new_tp = *throughput * transmittance / pdf;
- }
- }
- else
-#endif
- if(closure_flag & SD_EXTINCTION) {
- /* absorption only, no sampling needed */
- float3 transmittance = volume_color_transmittance(coeff.sigma_t, t);
- new_tp = *throughput * transmittance;
- }
- else {
- new_tp = *throughput;
- }
-
- /* integrate emission attenuated by extinction */
- if(L && (closure_flag & SD_EMISSION)) {
- float3 transmittance = volume_color_transmittance(coeff.sigma_t, ray->t);
- float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, ray->t);
- path_radiance_accum_emission(L, state, *throughput, emission);
- }
-
- /* modify throughput */
- if(closure_flag & SD_EXTINCTION) {
- *throughput = new_tp;
-
- /* prepare to scatter to new direction */
- if(t < ray->t) {
- /* adjust throughput and move to new location */
- sd->P = ray->P + t*ray->D;
-
- return VOLUME_PATH_SCATTERED;
- }
- }
-
- return VOLUME_PATH_ATTENUATED;
+ VolumeShaderCoefficients coeff;
+
+ if (!volume_shader_sample(kg, sd, state, ray->P, &coeff))
+ return VOLUME_PATH_MISSED;
+
+ int closure_flag = sd->flag;
+ float t = ray->t;
+ float3 new_tp;
+
+# ifdef __VOLUME_SCATTER__
+ /* randomly scatter, and if we do t is shortened */
+ if (closure_flag & SD_SCATTER) {
+ /* Sample channel, use MIS with balance heuristic. */
+ float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
+ float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
+ float3 channel_pdf;
+ int channel = kernel_volume_sample_channel(albedo, *throughput, rphase, &channel_pdf);
+
+ /* decide if we will hit or miss */
+ bool scatter = true;
+ float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
+
+ if (probalistic_scatter) {
+ float sample_sigma_t = kernel_volume_channel_get(coeff.sigma_t, channel);
+ float sample_transmittance = expf(-sample_sigma_t * t);
+
+ if (1.0f - xi >= sample_transmittance) {
+ scatter = true;
+
+ /* rescale random number so we can reuse it */
+ xi = 1.0f - (1.0f - xi - sample_transmittance) / (1.0f - sample_transmittance);
+ }
+ else
+ scatter = false;
+ }
+
+ if (scatter) {
+ /* scattering */
+ float3 pdf;
+ float3 transmittance;
+ float sample_t;
+
+ /* distance sampling */
+ sample_t = kernel_volume_distance_sample(
+ ray->t, coeff.sigma_t, channel, xi, &transmittance, &pdf);
+
+ /* modify pdf for hit/miss decision */
+ if (probalistic_scatter)
+ pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(coeff.sigma_t, t);
+
+ new_tp = *throughput * coeff.sigma_s * transmittance / dot(channel_pdf, pdf);
+ t = sample_t;
+ }
+ else {
+ /* no scattering */
+ float3 transmittance = volume_color_transmittance(coeff.sigma_t, t);
+ float pdf = dot(channel_pdf, transmittance);
+ new_tp = *throughput * transmittance / pdf;
+ }
+ }
+ else
+# endif
+ if (closure_flag & SD_EXTINCTION) {
+ /* absorption only, no sampling needed */
+ float3 transmittance = volume_color_transmittance(coeff.sigma_t, t);
+ new_tp = *throughput * transmittance;
+ }
+ else {
+ new_tp = *throughput;
+ }
+
+ /* integrate emission attenuated by extinction */
+ if (L && (closure_flag & SD_EMISSION)) {
+ float3 transmittance = volume_color_transmittance(coeff.sigma_t, ray->t);
+ float3 emission = kernel_volume_emission_integrate(
+ &coeff, closure_flag, transmittance, ray->t);
+ path_radiance_accum_emission(L, state, *throughput, emission);
+ }
+
+ /* modify throughput */
+ if (closure_flag & SD_EXTINCTION) {
+ *throughput = new_tp;
+
+ /* prepare to scatter to new direction */
+ if (t < ray->t) {
+ /* adjust throughput and move to new location */
+ sd->P = ray->P + t * ray->D;
+
+ return VOLUME_PATH_SCATTERED;
+ }
+ }
+
+ return VOLUME_PATH_ATTENUATED;
}
/* heterogeneous volume distance sampling: integrate stepping through the
* volume until we reach the end, get absorbed entirely, or run out of
* iterations. this does probabilistically scatter or get transmitted through
* for path tracing where we don't want to branch. */
-ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
- KernelGlobals *kg,
- ccl_addr_space PathState *state,
- Ray *ray,
- ShaderData *sd,
- PathRadiance *L,
- ccl_addr_space float3 *throughput)
+ccl_device VolumeIntegrateResult
+kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ ShaderData *sd,
+ PathRadiance *L,
+ ccl_addr_space float3 *throughput)
{
- float3 tp = *throughput;
- const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
-
- /* prepare for stepping */
- int max_steps = kernel_data.integrator.volume_max_steps;
- float step_offset, step_size;
- kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
-
- /* compute coefficients at the start */
- float t = 0.0f;
- float3 accum_transmittance = make_float3(1.0f, 1.0f, 1.0f);
-
- /* pick random color channel, we use the Veach one-sample
- * model with balance heuristic for the channels */
- float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
- float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
- bool has_scatter = false;
-
- for(int i = 0; i < max_steps; i++) {
- /* advance to new position */
- float new_t = min(ray->t, (i+1) * step_size);
- float dt = new_t - t;
-
- /* use random position inside this segment to sample shader,
- * for last shorter step we remap it to fit within the segment. */
- if(new_t == ray->t) {
- step_offset *= (new_t - t) / step_size;
- }
-
- float3 new_P = ray->P + ray->D * (t + step_offset);
- VolumeShaderCoefficients coeff;
-
- /* compute segment */
- if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
- int closure_flag = sd->flag;
- float3 new_tp;
- float3 transmittance;
- bool scatter = false;
-
- /* distance sampling */
-#ifdef __VOLUME_SCATTER__
- if((closure_flag & SD_SCATTER) || (has_scatter && (closure_flag & SD_EXTINCTION))) {
- has_scatter = true;
-
- /* Sample channel, use MIS with balance heuristic. */
- float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
- float3 channel_pdf;
- int channel = kernel_volume_sample_channel(albedo, tp, rphase, &channel_pdf);
-
- /* compute transmittance over full step */
- transmittance = volume_color_transmittance(coeff.sigma_t, dt);
-
- /* decide if we will scatter or continue */
- float sample_transmittance = kernel_volume_channel_get(transmittance, channel);
-
- if(1.0f - xi >= sample_transmittance) {
- /* compute sampling distance */
- float sample_sigma_t = kernel_volume_channel_get(coeff.sigma_t, channel);
- float new_dt = -logf(1.0f - xi)/sample_sigma_t;
- new_t = t + new_dt;
-
- /* transmittance and pdf */
- float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
- float3 pdf = coeff.sigma_t * new_transmittance;
-
- /* throughput */
- new_tp = tp * coeff.sigma_s * new_transmittance / dot(channel_pdf, pdf);
- scatter = true;
- }
- else {
- /* throughput */
- float pdf = dot(channel_pdf, transmittance);
- new_tp = tp * transmittance / pdf;
-
- /* remap xi so we can reuse it and keep thing stratified */
- xi = 1.0f - (1.0f - xi)/sample_transmittance;
- }
- }
- else
-#endif
- if(closure_flag & SD_EXTINCTION) {
- /* absorption only, no sampling needed */
- transmittance = volume_color_transmittance(coeff.sigma_t, dt);
- new_tp = tp * transmittance;
- }
- else {
- new_tp = tp;
- }
-
- /* integrate emission attenuated by absorption */
- if(L && (closure_flag & SD_EMISSION)) {
- float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, dt);
- path_radiance_accum_emission(L, state, tp, emission);
- }
-
- /* modify throughput */
- if(closure_flag & SD_EXTINCTION) {
- tp = new_tp;
-
- /* stop if nearly all light blocked */
- if(tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps) {
- tp = make_float3(0.0f, 0.0f, 0.0f);
- break;
- }
- }
-
- /* prepare to scatter to new direction */
- if(scatter) {
- /* adjust throughput and move to new location */
- sd->P = ray->P + new_t*ray->D;
- *throughput = tp;
-
- return VOLUME_PATH_SCATTERED;
- }
- else {
- /* accumulate transmittance */
- accum_transmittance *= transmittance;
- }
- }
-
- /* stop if at the end of the volume */
- t = new_t;
- if(t == ray->t)
- break;
- }
-
- *throughput = tp;
-
- return VOLUME_PATH_ATTENUATED;
+ float3 tp = *throughput;
+ const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
+
+ /* prepare for stepping */
+ int max_steps = kernel_data.integrator.volume_max_steps;
+ float step_offset, step_size;
+ kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
+
+ /* compute coefficients at the start */
+ float t = 0.0f;
+ float3 accum_transmittance = make_float3(1.0f, 1.0f, 1.0f);
+
+ /* pick random color channel, we use the Veach one-sample
+ * model with balance heuristic for the channels */
+ float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
+ float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
+ bool has_scatter = false;
+
+ for (int i = 0; i < max_steps; i++) {
+ /* advance to new position */
+ float new_t = min(ray->t, (i + 1) * step_size);
+ float dt = new_t - t;
+
+ /* use random position inside this segment to sample shader,
+ * for last shorter step we remap it to fit within the segment. */
+ if (new_t == ray->t) {
+ step_offset *= (new_t - t) / step_size;
+ }
+
+ float3 new_P = ray->P + ray->D * (t + step_offset);
+ VolumeShaderCoefficients coeff;
+
+ /* compute segment */
+ if (volume_shader_sample(kg, sd, state, new_P, &coeff)) {
+ int closure_flag = sd->flag;
+ float3 new_tp;
+ float3 transmittance;
+ bool scatter = false;
+
+ /* distance sampling */
+# ifdef __VOLUME_SCATTER__
+ if ((closure_flag & SD_SCATTER) || (has_scatter && (closure_flag & SD_EXTINCTION))) {
+ has_scatter = true;
+
+ /* Sample channel, use MIS with balance heuristic. */
+ float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
+ float3 channel_pdf;
+ int channel = kernel_volume_sample_channel(albedo, tp, rphase, &channel_pdf);
+
+ /* compute transmittance over full step */
+ transmittance = volume_color_transmittance(coeff.sigma_t, dt);
+
+ /* decide if we will scatter or continue */
+ float sample_transmittance = kernel_volume_channel_get(transmittance, channel);
+
+ if (1.0f - xi >= sample_transmittance) {
+ /* compute sampling distance */
+ float sample_sigma_t = kernel_volume_channel_get(coeff.sigma_t, channel);
+ float new_dt = -logf(1.0f - xi) / sample_sigma_t;
+ new_t = t + new_dt;
+
+ /* transmittance and pdf */
+ float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
+ float3 pdf = coeff.sigma_t * new_transmittance;
+
+ /* throughput */
+ new_tp = tp * coeff.sigma_s * new_transmittance / dot(channel_pdf, pdf);
+ scatter = true;
+ }
+ else {
+ /* throughput */
+ float pdf = dot(channel_pdf, transmittance);
+ new_tp = tp * transmittance / pdf;
+
+ /* remap xi so we can reuse it and keep thing stratified */
+ xi = 1.0f - (1.0f - xi) / sample_transmittance;
+ }
+ }
+ else
+# endif
+ if (closure_flag & SD_EXTINCTION) {
+ /* absorption only, no sampling needed */
+ transmittance = volume_color_transmittance(coeff.sigma_t, dt);
+ new_tp = tp * transmittance;
+ }
+ else {
+ new_tp = tp;
+ }
+
+ /* integrate emission attenuated by absorption */
+ if (L && (closure_flag & SD_EMISSION)) {
+ float3 emission = kernel_volume_emission_integrate(
+ &coeff, closure_flag, transmittance, dt);
+ path_radiance_accum_emission(L, state, tp, emission);
+ }
+
+ /* modify throughput */
+ if (closure_flag & SD_EXTINCTION) {
+ tp = new_tp;
+
+ /* stop if nearly all light blocked */
+ if (tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps) {
+ tp = make_float3(0.0f, 0.0f, 0.0f);
+ break;
+ }
+ }
+
+ /* prepare to scatter to new direction */
+ if (scatter) {
+ /* adjust throughput and move to new location */
+ sd->P = ray->P + new_t * ray->D;
+ *throughput = tp;
+
+ return VOLUME_PATH_SCATTERED;
+ }
+ else {
+ /* accumulate transmittance */
+ accum_transmittance *= transmittance;
+ }
+ }
+
+ /* stop if at the end of the volume */
+ t = new_t;
+ if (t == ray->t)
+ break;
+ }
+
+ *throughput = tp;
+
+ return VOLUME_PATH_ATTENUATED;
}
/* get the volume attenuation and emission over line segment defined by
* ray, with the assumption that there are no surfaces blocking light
* between the endpoints. distance sampling is used to decide if we will
* scatter or not. */
-ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(
- KernelGlobals *kg,
- ccl_addr_space PathState *state,
- ShaderData *sd,
- Ray *ray,
- PathRadiance *L,
- ccl_addr_space float3 *throughput,
- bool heterogeneous)
+ccl_device_noinline VolumeIntegrateResult
+kernel_volume_integrate(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ ShaderData *sd,
+ Ray *ray,
+ PathRadiance *L,
+ ccl_addr_space float3 *throughput,
+ bool heterogeneous)
{
- shader_setup_from_volume(kg, sd, ray);
+ shader_setup_from_volume(kg, sd, ray);
- if(heterogeneous)
- return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput);
- else
- return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, true);
+ if (heterogeneous)
+ return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput);
+ else
+ return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, true);
}
-#ifndef __SPLIT_KERNEL__
+# ifndef __SPLIT_KERNEL__
/* Decoupled Volume Sampling
*
* VolumeSegment is list of coefficients and transmittance stored at all steps
@@ -689,26 +700,26 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(
* no support for malloc/free and too much stack usage with a fix size array. */
typedef struct VolumeStep {
- float3 sigma_s; /* scatter coefficient */
- float3 sigma_t; /* extinction coefficient */
- float3 accum_transmittance; /* accumulated transmittance including this step */
- float3 cdf_distance; /* cumulative density function for distance sampling */
- float t; /* distance at end of this step */
- float shade_t; /* jittered distance where shading was done in step */
- int closure_flag; /* shader evaluation closure flags */
+ float3 sigma_s; /* scatter coefficient */
+ float3 sigma_t; /* extinction coefficient */
+ float3 accum_transmittance; /* accumulated transmittance including this step */
+ float3 cdf_distance; /* cumulative density function for distance sampling */
+ float t; /* distance at end of this step */
+ float shade_t; /* jittered distance where shading was done in step */
+ int closure_flag; /* shader evaluation closure flags */
} VolumeStep;
typedef struct VolumeSegment {
- VolumeStep stack_step; /* stack storage for homogeneous step, to avoid malloc */
- VolumeStep *steps; /* recorded steps */
- int numsteps; /* number of steps */
- int closure_flag; /* accumulated closure flags from all steps */
+ VolumeStep stack_step; /* stack storage for homogeneous step, to avoid malloc */
+ VolumeStep *steps; /* recorded steps */
+ int numsteps; /* number of steps */
+ int closure_flag; /* accumulated closure flags from all steps */
- float3 accum_emission; /* accumulated emission at end of segment */
- float3 accum_transmittance; /* accumulated transmittance at end of segment */
- float3 accum_albedo; /* accumulated average albedo over segment */
+ float3 accum_emission; /* accumulated emission at end of segment */
+ float3 accum_transmittance; /* accumulated transmittance at end of segment */
+ float3 accum_albedo; /* accumulated average albedo over segment */
- int sampling_method; /* volume sampling method */
+ int sampling_method; /* volume sampling method */
} VolumeSegment;
/* record volume steps to the end of the volume.
@@ -717,400 +728,412 @@ typedef struct VolumeSegment {
* but the entire segment is needed to do always scattering, rather than probabilistically
* hitting or missing the volume. if we don't know the transmittance at the end of the
* volume we can't generate stratified distance samples up to that transmittance */
-#ifdef __VOLUME_DECOUPLED__
-ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *state,
- Ray *ray, ShaderData *sd, VolumeSegment *segment, bool heterogeneous)
+# ifdef __VOLUME_DECOUPLED__
+ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg,
+ PathState *state,
+ Ray *ray,
+ ShaderData *sd,
+ VolumeSegment *segment,
+ bool heterogeneous)
{
- const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
-
- /* prepare for volume stepping */
- int max_steps;
- float step_size, step_offset;
-
- if(heterogeneous) {
- max_steps = kernel_data.integrator.volume_max_steps;
- kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
-
-#ifdef __KERNEL_CPU__
- /* NOTE: For the branched path tracing it's possible to have direct
- * and indirect light integration both having volume segments allocated.
- * We detect this using index in the pre-allocated memory. Currently we
- * only support two segments allocated at a time, if more needed some
- * modifications to the KernelGlobals will be needed.
- *
- * This gives us restrictions that decoupled record should only happen
- * in the stack manner, meaning if there's subsequent call of decoupled
- * record it'll need to free memory before it's caller frees memory.
- */
- const int index = kg->decoupled_volume_steps_index;
- assert(index < sizeof(kg->decoupled_volume_steps) /
- sizeof(*kg->decoupled_volume_steps));
- if(kg->decoupled_volume_steps[index] == NULL) {
- kg->decoupled_volume_steps[index] =
- (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
- }
- segment->steps = kg->decoupled_volume_steps[index];
- ++kg->decoupled_volume_steps_index;
-#else
- segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
-#endif
- }
- else {
- max_steps = 1;
- step_size = ray->t;
- step_offset = 0.0f;
- segment->steps = &segment->stack_step;
- }
-
- /* init accumulation variables */
- float3 accum_emission = make_float3(0.0f, 0.0f, 0.0f);
- float3 accum_transmittance = make_float3(1.0f, 1.0f, 1.0f);
- float3 accum_albedo = make_float3(0.0f, 0.0f, 0.0f);
- float3 cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
- float t = 0.0f;
-
- segment->numsteps = 0;
- segment->closure_flag = 0;
- bool is_last_step_empty = false;
-
- VolumeStep *step = segment->steps;
-
- for(int i = 0; i < max_steps; i++, step++) {
- /* advance to new position */
- float new_t = min(ray->t, (i+1) * step_size);
- float dt = new_t - t;
-
- /* use random position inside this segment to sample shader,
- * for last shorter step we remap it to fit within the segment. */
- if(new_t == ray->t) {
- step_offset *= (new_t - t) / step_size;
- }
-
- float3 new_P = ray->P + ray->D * (t + step_offset);
- VolumeShaderCoefficients coeff;
-
- /* compute segment */
- if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
- int closure_flag = sd->flag;
- float3 sigma_t = coeff.sigma_t;
-
- /* compute average albedo for channel sampling */
- if(closure_flag & SD_SCATTER) {
- accum_albedo += dt * safe_divide_color(coeff.sigma_s, sigma_t);
- }
-
- /* compute accumulated transmittance */
- float3 transmittance = volume_color_transmittance(sigma_t, dt);
-
- /* compute emission attenuated by absorption */
- if(closure_flag & SD_EMISSION) {
- float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, dt);
- accum_emission += accum_transmittance * emission;
- }
-
- accum_transmittance *= transmittance;
-
- /* compute pdf for distance sampling */
- float3 pdf_distance = dt * accum_transmittance * coeff.sigma_s;
- cdf_distance = cdf_distance + pdf_distance;
-
- /* write step data */
- step->sigma_t = sigma_t;
- step->sigma_s = coeff.sigma_s;
- step->closure_flag = closure_flag;
-
- segment->closure_flag |= closure_flag;
-
- is_last_step_empty = false;
- segment->numsteps++;
- }
- else {
- if(is_last_step_empty) {
- /* consecutive empty step, merge */
- step--;
- }
- else {
- /* store empty step */
- step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
- step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
- step->closure_flag = 0;
-
- segment->numsteps++;
- is_last_step_empty = true;
- }
- }
-
- step->accum_transmittance = accum_transmittance;
- step->cdf_distance = cdf_distance;
- step->t = new_t;
- step->shade_t = t + step_offset;
-
- /* stop if at the end of the volume */
- t = new_t;
- if(t == ray->t)
- break;
-
- /* stop if nearly all light blocked */
- if(accum_transmittance.x < tp_eps && accum_transmittance.y < tp_eps && accum_transmittance.z < tp_eps)
- break;
- }
-
- /* store total emission and transmittance */
- segment->accum_emission = accum_emission;
- segment->accum_transmittance = accum_transmittance;
- segment->accum_albedo = accum_albedo;
-
- /* normalize cumulative density function for distance sampling */
- VolumeStep *last_step = segment->steps + segment->numsteps - 1;
-
- if(!is_zero(last_step->cdf_distance)) {
- VolumeStep *step = &segment->steps[0];
- int numsteps = segment->numsteps;
- float3 inv_cdf_distance_sum = safe_invert_color(last_step->cdf_distance);
-
- for(int i = 0; i < numsteps; i++, step++)
- step->cdf_distance *= inv_cdf_distance_sum;
- }
+ const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
+
+ /* prepare for volume stepping */
+ int max_steps;
+ float step_size, step_offset;
+
+ if (heterogeneous) {
+ max_steps = kernel_data.integrator.volume_max_steps;
+ kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
+
+# ifdef __KERNEL_CPU__
+ /* NOTE: For the branched path tracing it's possible to have direct
+ * and indirect light integration both having volume segments allocated.
+ * We detect this using index in the pre-allocated memory. Currently we
+ * only support two segments allocated at a time, if more needed some
+ * modifications to the KernelGlobals will be needed.
+ *
+ * This gives us restrictions that decoupled record should only happen
+ * in the stack manner, meaning if there's subsequent call of decoupled
+ * record it'll need to free memory before it's caller frees memory.
+ */
+ const int index = kg->decoupled_volume_steps_index;
+ assert(index < sizeof(kg->decoupled_volume_steps) / sizeof(*kg->decoupled_volume_steps));
+ if (kg->decoupled_volume_steps[index] == NULL) {
+ kg->decoupled_volume_steps[index] = (VolumeStep *)malloc(sizeof(VolumeStep) * max_steps);
+ }
+ segment->steps = kg->decoupled_volume_steps[index];
+ ++kg->decoupled_volume_steps_index;
+# else
+ segment->steps = (VolumeStep *)malloc(sizeof(VolumeStep) * max_steps);
+# endif
+ }
+ else {
+ max_steps = 1;
+ step_size = ray->t;
+ step_offset = 0.0f;
+ segment->steps = &segment->stack_step;
+ }
+
+ /* init accumulation variables */
+ float3 accum_emission = make_float3(0.0f, 0.0f, 0.0f);
+ float3 accum_transmittance = make_float3(1.0f, 1.0f, 1.0f);
+ float3 accum_albedo = make_float3(0.0f, 0.0f, 0.0f);
+ float3 cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
+ float t = 0.0f;
+
+ segment->numsteps = 0;
+ segment->closure_flag = 0;
+ bool is_last_step_empty = false;
+
+ VolumeStep *step = segment->steps;
+
+ for (int i = 0; i < max_steps; i++, step++) {
+ /* advance to new position */
+ float new_t = min(ray->t, (i + 1) * step_size);
+ float dt = new_t - t;
+
+ /* use random position inside this segment to sample shader,
+ * for last shorter step we remap it to fit within the segment. */
+ if (new_t == ray->t) {
+ step_offset *= (new_t - t) / step_size;
+ }
+
+ float3 new_P = ray->P + ray->D * (t + step_offset);
+ VolumeShaderCoefficients coeff;
+
+ /* compute segment */
+ if (volume_shader_sample(kg, sd, state, new_P, &coeff)) {
+ int closure_flag = sd->flag;
+ float3 sigma_t = coeff.sigma_t;
+
+ /* compute average albedo for channel sampling */
+ if (closure_flag & SD_SCATTER) {
+ accum_albedo += dt * safe_divide_color(coeff.sigma_s, sigma_t);
+ }
+
+ /* compute accumulated transmittance */
+ float3 transmittance = volume_color_transmittance(sigma_t, dt);
+
+ /* compute emission attenuated by absorption */
+ if (closure_flag & SD_EMISSION) {
+ float3 emission = kernel_volume_emission_integrate(
+ &coeff, closure_flag, transmittance, dt);
+ accum_emission += accum_transmittance * emission;
+ }
+
+ accum_transmittance *= transmittance;
+
+ /* compute pdf for distance sampling */
+ float3 pdf_distance = dt * accum_transmittance * coeff.sigma_s;
+ cdf_distance = cdf_distance + pdf_distance;
+
+ /* write step data */
+ step->sigma_t = sigma_t;
+ step->sigma_s = coeff.sigma_s;
+ step->closure_flag = closure_flag;
+
+ segment->closure_flag |= closure_flag;
+
+ is_last_step_empty = false;
+ segment->numsteps++;
+ }
+ else {
+ if (is_last_step_empty) {
+ /* consecutive empty step, merge */
+ step--;
+ }
+ else {
+ /* store empty step */
+ step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
+ step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ step->closure_flag = 0;
+
+ segment->numsteps++;
+ is_last_step_empty = true;
+ }
+ }
+
+ step->accum_transmittance = accum_transmittance;
+ step->cdf_distance = cdf_distance;
+ step->t = new_t;
+ step->shade_t = t + step_offset;
+
+ /* stop if at the end of the volume */
+ t = new_t;
+ if (t == ray->t)
+ break;
+
+ /* stop if nearly all light blocked */
+ if (accum_transmittance.x < tp_eps && accum_transmittance.y < tp_eps &&
+ accum_transmittance.z < tp_eps)
+ break;
+ }
+
+ /* store total emission and transmittance */
+ segment->accum_emission = accum_emission;
+ segment->accum_transmittance = accum_transmittance;
+ segment->accum_albedo = accum_albedo;
+
+ /* normalize cumulative density function for distance sampling */
+ VolumeStep *last_step = segment->steps + segment->numsteps - 1;
+
+ if (!is_zero(last_step->cdf_distance)) {
+ VolumeStep *step = &segment->steps[0];
+ int numsteps = segment->numsteps;
+ float3 inv_cdf_distance_sum = safe_invert_color(last_step->cdf_distance);
+
+ for (int i = 0; i < numsteps; i++, step++)
+ step->cdf_distance *= inv_cdf_distance_sum;
+ }
}
ccl_device void kernel_volume_decoupled_free(KernelGlobals *kg, VolumeSegment *segment)
{
- if(segment->steps != &segment->stack_step) {
-#ifdef __KERNEL_CPU__
- /* NOTE: We only allow free last allocated segment.
- * No random order of alloc/free is supported.
- */
- assert(kg->decoupled_volume_steps_index > 0);
- assert(segment->steps == kg->decoupled_volume_steps[kg->decoupled_volume_steps_index - 1]);
- --kg->decoupled_volume_steps_index;
-#else
- free(segment->steps);
-#endif
- }
+ if (segment->steps != &segment->stack_step) {
+# ifdef __KERNEL_CPU__
+ /* NOTE: We only allow free last allocated segment.
+ * No random order of alloc/free is supported.
+ */
+ assert(kg->decoupled_volume_steps_index > 0);
+ assert(segment->steps == kg->decoupled_volume_steps[kg->decoupled_volume_steps_index - 1]);
+ --kg->decoupled_volume_steps_index;
+# else
+ free(segment->steps);
+# endif
+ }
}
-#endif /* __VOLUME_DECOUPLED__ */
+# endif /* __VOLUME_DECOUPLED__ */
/* scattering for homogeneous and heterogeneous volumes, using decoupled ray
* marching.
*
* function is expected to return VOLUME_PATH_SCATTERED when probalistic_scatter is false */
-ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
- KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd,
- float3 *throughput, float rphase, float rscatter,
- const VolumeSegment *segment, const float3 *light_P, bool probalistic_scatter)
+ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(KernelGlobals *kg,
+ PathState *state,
+ Ray *ray,
+ ShaderData *sd,
+ float3 *throughput,
+ float rphase,
+ float rscatter,
+ const VolumeSegment *segment,
+ const float3 *light_P,
+ bool probalistic_scatter)
{
- kernel_assert(segment->closure_flag & SD_SCATTER);
-
- /* Sample color channel, use MIS with balance heuristic. */
- float3 channel_pdf;
- int channel = kernel_volume_sample_channel(segment->accum_albedo,
- *throughput,
- rphase,
- &channel_pdf);
-
- float xi = rscatter;
-
- /* probabilistic scattering decision based on transmittance */
- if(probalistic_scatter) {
- float sample_transmittance = kernel_volume_channel_get(segment->accum_transmittance, channel);
-
- if(1.0f - xi >= sample_transmittance) {
- /* rescale random number so we can reuse it */
- xi = 1.0f - (1.0f - xi - sample_transmittance)/(1.0f - sample_transmittance);
- }
- else {
- *throughput /= sample_transmittance;
- return VOLUME_PATH_MISSED;
- }
- }
-
- VolumeStep *step;
- float3 transmittance;
- float pdf, sample_t;
- float mis_weight = 1.0f;
- bool distance_sample = true;
- bool use_mis = false;
-
- if(segment->sampling_method && light_P) {
- if(segment->sampling_method == SD_VOLUME_MIS) {
- /* multiple importance sample: randomly pick between
- * equiangular and distance sampling strategy */
- if(xi < 0.5f) {
- xi *= 2.0f;
- }
- else {
- xi = (xi - 0.5f)*2.0f;
- distance_sample = false;
- }
-
- use_mis = true;
- }
- else {
- /* only equiangular sampling */
- distance_sample = false;
- }
- }
-
- /* distance sampling */
- if(distance_sample) {
- /* find step in cdf */
- step = segment->steps;
-
- float prev_t = 0.0f;
- float3 step_pdf_distance = make_float3(1.0f, 1.0f, 1.0f);
-
- if(segment->numsteps > 1) {
- float prev_cdf = 0.0f;
- float step_cdf = 1.0f;
- float3 prev_cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; ; i++, step++) {
- /* todo: optimize using binary search */
- step_cdf = kernel_volume_channel_get(step->cdf_distance, channel);
-
- if(xi < step_cdf || i == segment->numsteps-1)
- break;
-
- prev_cdf = step_cdf;
- prev_t = step->t;
- prev_cdf_distance = step->cdf_distance;
- }
-
- /* remap xi so we can reuse it */
- xi = (xi - prev_cdf)/(step_cdf - prev_cdf);
-
- /* pdf for picking step */
- step_pdf_distance = step->cdf_distance - prev_cdf_distance;
- }
-
- /* determine range in which we will sample */
- float step_t = step->t - prev_t;
-
- /* sample distance and compute transmittance */
- float3 distance_pdf;
- sample_t = prev_t + kernel_volume_distance_sample(step_t, step->sigma_t, channel, xi, &transmittance, &distance_pdf);
-
- /* modify pdf for hit/miss decision */
- if(probalistic_scatter)
- distance_pdf *= make_float3(1.0f, 1.0f, 1.0f) - segment->accum_transmittance;
-
- pdf = dot(channel_pdf, distance_pdf * step_pdf_distance);
-
- /* multiple importance sampling */
- if(use_mis) {
- float equi_pdf = kernel_volume_equiangular_pdf(ray, *light_P, sample_t);
- mis_weight = 2.0f*power_heuristic(pdf, equi_pdf);
- }
- }
- /* equi-angular sampling */
- else {
- /* sample distance */
- sample_t = kernel_volume_equiangular_sample(ray, *light_P, xi, &pdf);
-
- /* find step in which sampled distance is located */
- step = segment->steps;
-
- float prev_t = 0.0f;
- float3 step_pdf_distance = make_float3(1.0f, 1.0f, 1.0f);
-
- if(segment->numsteps > 1) {
- float3 prev_cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
-
- int numsteps = segment->numsteps;
- int high = numsteps - 1;
- int low = 0;
- int mid;
-
- while(low < high) {
- mid = (low + high) >> 1;
-
- if(sample_t < step[mid].t)
- high = mid;
- else if(sample_t >= step[mid + 1].t)
- low = mid + 1;
- else {
- /* found our interval in step[mid] .. step[mid+1] */
- prev_t = step[mid].t;
- prev_cdf_distance = step[mid].cdf_distance;
- step += mid+1;
- break;
- }
- }
-
- if(low >= numsteps - 1) {
- prev_t = step[numsteps - 1].t;
- prev_cdf_distance = step[numsteps-1].cdf_distance;
- step += numsteps - 1;
- }
-
- /* pdf for picking step with distance sampling */
- step_pdf_distance = step->cdf_distance - prev_cdf_distance;
- }
-
- /* determine range in which we will sample */
- float step_t = step->t - prev_t;
- float step_sample_t = sample_t - prev_t;
-
- /* compute transmittance */
- transmittance = volume_color_transmittance(step->sigma_t, step_sample_t);
-
- /* multiple importance sampling */
- if(use_mis) {
- float3 distance_pdf3 = kernel_volume_distance_pdf(step_t, step->sigma_t, step_sample_t);
- float distance_pdf = dot(channel_pdf, distance_pdf3 * step_pdf_distance);
- mis_weight = 2.0f*power_heuristic(pdf, distance_pdf);
- }
- }
- if(sample_t < 0.0f || pdf == 0.0f) {
- return VOLUME_PATH_MISSED;
- }
-
- /* compute transmittance up to this step */
- if(step != segment->steps)
- transmittance *= (step-1)->accum_transmittance;
-
- /* modify throughput */
- *throughput *= step->sigma_s * transmittance * (mis_weight / pdf);
-
- /* evaluate shader to create closures at shading point */
- if(segment->numsteps > 1) {
- sd->P = ray->P + step->shade_t*ray->D;
-
- VolumeShaderCoefficients coeff;
- volume_shader_sample(kg, sd, state, sd->P, &coeff);
- }
-
- /* move to new position */
- sd->P = ray->P + sample_t*ray->D;
-
- return VOLUME_PATH_SCATTERED;
+ kernel_assert(segment->closure_flag & SD_SCATTER);
+
+ /* Sample color channel, use MIS with balance heuristic. */
+ float3 channel_pdf;
+ int channel = kernel_volume_sample_channel(
+ segment->accum_albedo, *throughput, rphase, &channel_pdf);
+
+ float xi = rscatter;
+
+ /* probabilistic scattering decision based on transmittance */
+ if (probalistic_scatter) {
+ float sample_transmittance = kernel_volume_channel_get(segment->accum_transmittance, channel);
+
+ if (1.0f - xi >= sample_transmittance) {
+ /* rescale random number so we can reuse it */
+ xi = 1.0f - (1.0f - xi - sample_transmittance) / (1.0f - sample_transmittance);
+ }
+ else {
+ *throughput /= sample_transmittance;
+ return VOLUME_PATH_MISSED;
+ }
+ }
+
+ VolumeStep *step;
+ float3 transmittance;
+ float pdf, sample_t;
+ float mis_weight = 1.0f;
+ bool distance_sample = true;
+ bool use_mis = false;
+
+ if (segment->sampling_method && light_P) {
+ if (segment->sampling_method == SD_VOLUME_MIS) {
+ /* multiple importance sample: randomly pick between
+ * equiangular and distance sampling strategy */
+ if (xi < 0.5f) {
+ xi *= 2.0f;
+ }
+ else {
+ xi = (xi - 0.5f) * 2.0f;
+ distance_sample = false;
+ }
+
+ use_mis = true;
+ }
+ else {
+ /* only equiangular sampling */
+ distance_sample = false;
+ }
+ }
+
+ /* distance sampling */
+ if (distance_sample) {
+ /* find step in cdf */
+ step = segment->steps;
+
+ float prev_t = 0.0f;
+ float3 step_pdf_distance = make_float3(1.0f, 1.0f, 1.0f);
+
+ if (segment->numsteps > 1) {
+ float prev_cdf = 0.0f;
+ float step_cdf = 1.0f;
+ float3 prev_cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0;; i++, step++) {
+ /* todo: optimize using binary search */
+ step_cdf = kernel_volume_channel_get(step->cdf_distance, channel);
+
+ if (xi < step_cdf || i == segment->numsteps - 1)
+ break;
+
+ prev_cdf = step_cdf;
+ prev_t = step->t;
+ prev_cdf_distance = step->cdf_distance;
+ }
+
+ /* remap xi so we can reuse it */
+ xi = (xi - prev_cdf) / (step_cdf - prev_cdf);
+
+ /* pdf for picking step */
+ step_pdf_distance = step->cdf_distance - prev_cdf_distance;
+ }
+
+ /* determine range in which we will sample */
+ float step_t = step->t - prev_t;
+
+ /* sample distance and compute transmittance */
+ float3 distance_pdf;
+ sample_t = prev_t + kernel_volume_distance_sample(
+ step_t, step->sigma_t, channel, xi, &transmittance, &distance_pdf);
+
+ /* modify pdf for hit/miss decision */
+ if (probalistic_scatter)
+ distance_pdf *= make_float3(1.0f, 1.0f, 1.0f) - segment->accum_transmittance;
+
+ pdf = dot(channel_pdf, distance_pdf * step_pdf_distance);
+
+ /* multiple importance sampling */
+ if (use_mis) {
+ float equi_pdf = kernel_volume_equiangular_pdf(ray, *light_P, sample_t);
+ mis_weight = 2.0f * power_heuristic(pdf, equi_pdf);
+ }
+ }
+ /* equi-angular sampling */
+ else {
+ /* sample distance */
+ sample_t = kernel_volume_equiangular_sample(ray, *light_P, xi, &pdf);
+
+ /* find step in which sampled distance is located */
+ step = segment->steps;
+
+ float prev_t = 0.0f;
+ float3 step_pdf_distance = make_float3(1.0f, 1.0f, 1.0f);
+
+ if (segment->numsteps > 1) {
+ float3 prev_cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
+
+ int numsteps = segment->numsteps;
+ int high = numsteps - 1;
+ int low = 0;
+ int mid;
+
+ while (low < high) {
+ mid = (low + high) >> 1;
+
+ if (sample_t < step[mid].t)
+ high = mid;
+ else if (sample_t >= step[mid + 1].t)
+ low = mid + 1;
+ else {
+ /* found our interval in step[mid] .. step[mid+1] */
+ prev_t = step[mid].t;
+ prev_cdf_distance = step[mid].cdf_distance;
+ step += mid + 1;
+ break;
+ }
+ }
+
+ if (low >= numsteps - 1) {
+ prev_t = step[numsteps - 1].t;
+ prev_cdf_distance = step[numsteps - 1].cdf_distance;
+ step += numsteps - 1;
+ }
+
+ /* pdf for picking step with distance sampling */
+ step_pdf_distance = step->cdf_distance - prev_cdf_distance;
+ }
+
+ /* determine range in which we will sample */
+ float step_t = step->t - prev_t;
+ float step_sample_t = sample_t - prev_t;
+
+ /* compute transmittance */
+ transmittance = volume_color_transmittance(step->sigma_t, step_sample_t);
+
+ /* multiple importance sampling */
+ if (use_mis) {
+ float3 distance_pdf3 = kernel_volume_distance_pdf(step_t, step->sigma_t, step_sample_t);
+ float distance_pdf = dot(channel_pdf, distance_pdf3 * step_pdf_distance);
+ mis_weight = 2.0f * power_heuristic(pdf, distance_pdf);
+ }
+ }
+ if (sample_t < 0.0f || pdf == 0.0f) {
+ return VOLUME_PATH_MISSED;
+ }
+
+ /* compute transmittance up to this step */
+ if (step != segment->steps)
+ transmittance *= (step - 1)->accum_transmittance;
+
+ /* modify throughput */
+ *throughput *= step->sigma_s * transmittance * (mis_weight / pdf);
+
+ /* evaluate shader to create closures at shading point */
+ if (segment->numsteps > 1) {
+ sd->P = ray->P + step->shade_t * ray->D;
+
+ VolumeShaderCoefficients coeff;
+ volume_shader_sample(kg, sd, state, sd->P, &coeff);
+ }
+
+ /* move to new position */
+ sd->P = ray->P + sample_t * ray->D;
+
+ return VOLUME_PATH_SCATTERED;
}
-#endif /* __SPLIT_KERNEL */
+# endif /* __SPLIT_KERNEL */
/* decide if we need to use decoupled or not */
-ccl_device bool kernel_volume_use_decoupled(KernelGlobals *kg, bool heterogeneous, bool direct, int sampling_method)
+ccl_device bool kernel_volume_use_decoupled(KernelGlobals *kg,
+ bool heterogeneous,
+ bool direct,
+ int sampling_method)
{
- /* decoupled ray marching for heterogeneous volumes not supported on the GPU,
- * which also means equiangular and multiple importance sampling is not
- * support for that case */
- if(!kernel_data.integrator.volume_decoupled)
- return false;
-
-#ifdef __KERNEL_GPU__
- if(heterogeneous)
- return false;
-#endif
-
- /* equiangular and multiple importance sampling only implemented for decoupled */
- if(sampling_method != 0)
- return true;
-
- /* for all light sampling use decoupled, reusing shader evaluations is
- * typically faster in that case */
- if(direct)
- return kernel_data.integrator.sample_all_lights_direct;
- else
- return kernel_data.integrator.sample_all_lights_indirect;
+ /* decoupled ray marching for heterogeneous volumes not supported on the GPU,
+ * which also means equiangular and multiple importance sampling is not
+ * support for that case */
+ if (!kernel_data.integrator.volume_decoupled)
+ return false;
+
+# ifdef __KERNEL_GPU__
+ if (heterogeneous)
+ return false;
+# endif
+
+ /* equiangular and multiple importance sampling only implemented for decoupled */
+ if (sampling_method != 0)
+ return true;
+
+ /* for all light sampling use decoupled, reusing shader evaluations is
+ * typically faster in that case */
+ if (direct)
+ return kernel_data.integrator.sample_all_lights_direct;
+ else
+ return kernel_data.integrator.sample_all_lights_indirect;
}
/* Volume Stack
@@ -1124,242 +1147,231 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg,
ccl_addr_space const Ray *ray,
ccl_addr_space VolumeStack *stack)
{
- /* NULL ray happens in the baker, does it need proper initialization of
- * camera in volume?
- */
- if(!kernel_data.cam.is_inside_volume || ray == NULL) {
- /* Camera is guaranteed to be in the air, only take background volume
- * into account in this case.
- */
- if(kernel_data.background.volume_shader != SHADER_NONE) {
- stack[0].shader = kernel_data.background.volume_shader;
- stack[0].object = PRIM_NONE;
- stack[1].shader = SHADER_NONE;
- }
- else {
- stack[0].shader = SHADER_NONE;
- }
- return;
- }
-
- kernel_assert(state->flag & PATH_RAY_CAMERA);
-
- Ray volume_ray = *ray;
- volume_ray.t = FLT_MAX;
-
- const uint visibility = (state->flag & PATH_RAY_ALL_VISIBILITY);
- int stack_index = 0, enclosed_index = 0;
-
-#ifdef __VOLUME_RECORD_ALL__
- Intersection hits[2*VOLUME_STACK_SIZE + 1];
- uint num_hits = scene_intersect_volume_all(kg,
- &volume_ray,
- hits,
- 2*VOLUME_STACK_SIZE,
- visibility);
- if(num_hits > 0) {
- int enclosed_volumes[VOLUME_STACK_SIZE];
- Intersection *isect = hits;
-
- qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
-
- for(uint hit = 0; hit < num_hits; ++hit, ++isect) {
- shader_setup_from_ray(kg, stack_sd, isect, &volume_ray);
- if(stack_sd->flag & SD_BACKFACING) {
- bool need_add = true;
- for(int i = 0; i < enclosed_index && need_add; ++i) {
- /* If ray exited the volume and never entered to that volume
- * it means that camera is inside such a volume.
- */
- if(enclosed_volumes[i] == stack_sd->object) {
- need_add = false;
- }
- }
- for(int i = 0; i < stack_index && need_add; ++i) {
- /* Don't add intersections twice. */
- if(stack[i].object == stack_sd->object) {
- need_add = false;
- break;
- }
- }
- if(need_add && stack_index < VOLUME_STACK_SIZE - 1) {
- stack[stack_index].object = stack_sd->object;
- stack[stack_index].shader = stack_sd->shader;
- ++stack_index;
- }
- }
- else {
- /* If ray from camera enters the volume, this volume shouldn't
- * be added to the stack on exit.
- */
- enclosed_volumes[enclosed_index++] = stack_sd->object;
- }
- }
- }
-#else
- int enclosed_volumes[VOLUME_STACK_SIZE];
- int step = 0;
-
- while(stack_index < VOLUME_STACK_SIZE - 1 &&
- enclosed_index < VOLUME_STACK_SIZE - 1 &&
- step < 2 * VOLUME_STACK_SIZE)
- {
- Intersection isect;
- if(!scene_intersect_volume(kg, &volume_ray, &isect, visibility)) {
- break;
- }
-
- shader_setup_from_ray(kg, stack_sd, &isect, &volume_ray);
- if(stack_sd->flag & SD_BACKFACING) {
- /* If ray exited the volume and never entered to that volume
- * it means that camera is inside such a volume.
- */
- bool need_add = true;
- for(int i = 0; i < enclosed_index && need_add; ++i) {
- /* If ray exited the volume and never entered to that volume
- * it means that camera is inside such a volume.
- */
- if(enclosed_volumes[i] == stack_sd->object) {
- need_add = false;
- }
- }
- for(int i = 0; i < stack_index && need_add; ++i) {
- /* Don't add intersections twice. */
- if(stack[i].object == stack_sd->object) {
- need_add = false;
- break;
- }
- }
- if(need_add) {
- stack[stack_index].object = stack_sd->object;
- stack[stack_index].shader = stack_sd->shader;
- ++stack_index;
- }
- }
- else {
- /* If ray from camera enters the volume, this volume shouldn't
- * be added to the stack on exit.
- */
- enclosed_volumes[enclosed_index++] = stack_sd->object;
- }
-
- /* Move ray forward. */
- volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
- ++step;
- }
-#endif
- /* stack_index of 0 means quick checks outside of the kernel gave false
- * positive, nothing to worry about, just we've wasted quite a few of
- * ticks just to come into conclusion that camera is in the air.
- *
- * In this case we're doing the same above -- check whether background has
- * volume.
- */
- if(stack_index == 0 && kernel_data.background.volume_shader == SHADER_NONE) {
- stack[0].shader = kernel_data.background.volume_shader;
- stack[0].object = PRIM_NONE;
- stack[1].shader = SHADER_NONE;
- }
- else {
- stack[stack_index].shader = SHADER_NONE;
- }
+ /* NULL ray happens in the baker, does it need proper initialization of
+ * camera in volume?
+ */
+ if (!kernel_data.cam.is_inside_volume || ray == NULL) {
+ /* Camera is guaranteed to be in the air, only take background volume
+ * into account in this case.
+ */
+ if (kernel_data.background.volume_shader != SHADER_NONE) {
+ stack[0].shader = kernel_data.background.volume_shader;
+ stack[0].object = PRIM_NONE;
+ stack[1].shader = SHADER_NONE;
+ }
+ else {
+ stack[0].shader = SHADER_NONE;
+ }
+ return;
+ }
+
+ kernel_assert(state->flag & PATH_RAY_CAMERA);
+
+ Ray volume_ray = *ray;
+ volume_ray.t = FLT_MAX;
+
+ const uint visibility = (state->flag & PATH_RAY_ALL_VISIBILITY);
+ int stack_index = 0, enclosed_index = 0;
+
+# ifdef __VOLUME_RECORD_ALL__
+ Intersection hits[2 * VOLUME_STACK_SIZE + 1];
+ uint num_hits = scene_intersect_volume_all(
+ kg, &volume_ray, hits, 2 * VOLUME_STACK_SIZE, visibility);
+ if (num_hits > 0) {
+ int enclosed_volumes[VOLUME_STACK_SIZE];
+ Intersection *isect = hits;
+
+ qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
+
+ for (uint hit = 0; hit < num_hits; ++hit, ++isect) {
+ shader_setup_from_ray(kg, stack_sd, isect, &volume_ray);
+ if (stack_sd->flag & SD_BACKFACING) {
+ bool need_add = true;
+ for (int i = 0; i < enclosed_index && need_add; ++i) {
+ /* If ray exited the volume and never entered to that volume
+ * it means that camera is inside such a volume.
+ */
+ if (enclosed_volumes[i] == stack_sd->object) {
+ need_add = false;
+ }
+ }
+ for (int i = 0; i < stack_index && need_add; ++i) {
+ /* Don't add intersections twice. */
+ if (stack[i].object == stack_sd->object) {
+ need_add = false;
+ break;
+ }
+ }
+ if (need_add && stack_index < VOLUME_STACK_SIZE - 1) {
+ stack[stack_index].object = stack_sd->object;
+ stack[stack_index].shader = stack_sd->shader;
+ ++stack_index;
+ }
+ }
+ else {
+ /* If ray from camera enters the volume, this volume shouldn't
+ * be added to the stack on exit.
+ */
+ enclosed_volumes[enclosed_index++] = stack_sd->object;
+ }
+ }
+ }
+# else
+ int enclosed_volumes[VOLUME_STACK_SIZE];
+ int step = 0;
+
+ while (stack_index < VOLUME_STACK_SIZE - 1 && enclosed_index < VOLUME_STACK_SIZE - 1 &&
+ step < 2 * VOLUME_STACK_SIZE) {
+ Intersection isect;
+ if (!scene_intersect_volume(kg, &volume_ray, &isect, visibility)) {
+ break;
+ }
+
+ shader_setup_from_ray(kg, stack_sd, &isect, &volume_ray);
+ if (stack_sd->flag & SD_BACKFACING) {
+ /* If ray exited the volume and never entered to that volume
+ * it means that camera is inside such a volume.
+ */
+ bool need_add = true;
+ for (int i = 0; i < enclosed_index && need_add; ++i) {
+ /* If ray exited the volume and never entered to that volume
+ * it means that camera is inside such a volume.
+ */
+ if (enclosed_volumes[i] == stack_sd->object) {
+ need_add = false;
+ }
+ }
+ for (int i = 0; i < stack_index && need_add; ++i) {
+ /* Don't add intersections twice. */
+ if (stack[i].object == stack_sd->object) {
+ need_add = false;
+ break;
+ }
+ }
+ if (need_add) {
+ stack[stack_index].object = stack_sd->object;
+ stack[stack_index].shader = stack_sd->shader;
+ ++stack_index;
+ }
+ }
+ else {
+ /* If ray from camera enters the volume, this volume shouldn't
+ * be added to the stack on exit.
+ */
+ enclosed_volumes[enclosed_index++] = stack_sd->object;
+ }
+
+ /* Move ray forward. */
+ volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
+ ++step;
+ }
+# endif
+ /* stack_index of 0 means quick checks outside of the kernel gave false
+ * positive, nothing to worry about, just we've wasted quite a few of
+ * ticks just to come into conclusion that camera is in the air.
+ *
+ * In this case we're doing the same above -- check whether background has
+ * volume.
+ */
+ if (stack_index == 0 && kernel_data.background.volume_shader == SHADER_NONE) {
+ stack[0].shader = kernel_data.background.volume_shader;
+ stack[0].object = PRIM_NONE;
+ stack[1].shader = SHADER_NONE;
+ }
+ else {
+ stack[stack_index].shader = SHADER_NONE;
+ }
}
-ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg, ShaderData *sd, ccl_addr_space VolumeStack *stack)
+ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space VolumeStack *stack)
{
- /* todo: we should have some way for objects to indicate if they want the
- * world shader to work inside them. excluding it by default is problematic
- * because non-volume objects can't be assumed to be closed manifolds */
-
- if(!(sd->flag & SD_HAS_VOLUME))
- return;
-
- if(sd->flag & SD_BACKFACING) {
- /* exit volume object: remove from stack */
- for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
- if(stack[i].object == sd->object) {
- /* shift back next stack entries */
- do {
- stack[i] = stack[i+1];
- i++;
- }
- while(stack[i].shader != SHADER_NONE);
-
- return;
- }
- }
- }
- else {
- /* enter volume object: add to stack */
- int i;
-
- for(i = 0; stack[i].shader != SHADER_NONE; i++) {
- /* already in the stack? then we have nothing to do */
- if(stack[i].object == sd->object)
- return;
- }
-
- /* if we exceed the stack limit, ignore */
- if(i >= VOLUME_STACK_SIZE-1)
- return;
-
- /* add to the end of the stack */
- stack[i].shader = sd->shader;
- stack[i].object = sd->object;
- stack[i+1].shader = SHADER_NONE;
- }
+ /* todo: we should have some way for objects to indicate if they want the
+ * world shader to work inside them. excluding it by default is problematic
+ * because non-volume objects can't be assumed to be closed manifolds */
+
+ if (!(sd->flag & SD_HAS_VOLUME))
+ return;
+
+ if (sd->flag & SD_BACKFACING) {
+ /* exit volume object: remove from stack */
+ for (int i = 0; stack[i].shader != SHADER_NONE; i++) {
+ if (stack[i].object == sd->object) {
+ /* shift back next stack entries */
+ do {
+ stack[i] = stack[i + 1];
+ i++;
+ } while (stack[i].shader != SHADER_NONE);
+
+ return;
+ }
+ }
+ }
+ else {
+ /* enter volume object: add to stack */
+ int i;
+
+ for (i = 0; stack[i].shader != SHADER_NONE; i++) {
+ /* already in the stack? then we have nothing to do */
+ if (stack[i].object == sd->object)
+ return;
+ }
+
+ /* if we exceed the stack limit, ignore */
+ if (i >= VOLUME_STACK_SIZE - 1)
+ return;
+
+ /* add to the end of the stack */
+ stack[i].shader = sd->shader;
+ stack[i].object = sd->object;
+ stack[i + 1].shader = SHADER_NONE;
+ }
}
-#ifdef __SUBSURFACE__
+# ifdef __SUBSURFACE__
ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg,
ShaderData *stack_sd,
Ray *ray,
ccl_addr_space VolumeStack *stack)
{
- kernel_assert(kernel_data.integrator.use_volumes);
-
- Ray volume_ray = *ray;
-
-# ifdef __VOLUME_RECORD_ALL__
- Intersection hits[2*VOLUME_STACK_SIZE + 1];
- uint num_hits = scene_intersect_volume_all(kg,
- &volume_ray,
- hits,
- 2*VOLUME_STACK_SIZE,
- PATH_RAY_ALL_VISIBILITY);
- if(num_hits > 0) {
- Intersection *isect = hits;
-
- qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
-
- for(uint hit = 0; hit < num_hits; ++hit, ++isect) {
- shader_setup_from_ray(kg, stack_sd, isect, &volume_ray);
- kernel_volume_stack_enter_exit(kg, stack_sd, stack);
- }
- }
-# else
- Intersection isect;
- int step = 0;
- float3 Pend = ray->P + ray->D*ray->t;
- while(step < 2 * VOLUME_STACK_SIZE &&
- scene_intersect_volume(kg,
- &volume_ray,
- &isect,
- PATH_RAY_ALL_VISIBILITY))
- {
- shader_setup_from_ray(kg, stack_sd, &isect, &volume_ray);
- kernel_volume_stack_enter_exit(kg, stack_sd, stack);
-
- /* Move ray forward. */
- volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
- if(volume_ray.t != FLT_MAX) {
- volume_ray.D = normalize_len(Pend - volume_ray.P, &volume_ray.t);
- }
- ++step;
- }
-# endif
+ kernel_assert(kernel_data.integrator.use_volumes);
+
+ Ray volume_ray = *ray;
+
+# ifdef __VOLUME_RECORD_ALL__
+ Intersection hits[2 * VOLUME_STACK_SIZE + 1];
+ uint num_hits = scene_intersect_volume_all(
+ kg, &volume_ray, hits, 2 * VOLUME_STACK_SIZE, PATH_RAY_ALL_VISIBILITY);
+ if (num_hits > 0) {
+ Intersection *isect = hits;
+
+ qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
+
+ for (uint hit = 0; hit < num_hits; ++hit, ++isect) {
+ shader_setup_from_ray(kg, stack_sd, isect, &volume_ray);
+ kernel_volume_stack_enter_exit(kg, stack_sd, stack);
+ }
+ }
+# else
+ Intersection isect;
+ int step = 0;
+ float3 Pend = ray->P + ray->D * ray->t;
+ while (step < 2 * VOLUME_STACK_SIZE &&
+ scene_intersect_volume(kg, &volume_ray, &isect, PATH_RAY_ALL_VISIBILITY)) {
+ shader_setup_from_ray(kg, stack_sd, &isect, &volume_ray);
+ kernel_volume_stack_enter_exit(kg, stack_sd, stack);
+
+ /* Move ray forward. */
+ volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
+ if (volume_ray.t != FLT_MAX) {
+ volume_ray.D = normalize_len(Pend - volume_ray.P, &volume_ray.t);
+ }
+ ++step;
+ }
+# endif
}
-#endif
+# endif
/* Clean stack after the last bounce.
*
@@ -1378,15 +1390,15 @@ ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg,
ccl_device_inline void kernel_volume_clean_stack(KernelGlobals *kg,
ccl_addr_space VolumeStack *volume_stack)
{
- if(kernel_data.background.volume_shader != SHADER_NONE) {
- /* Keep the world's volume in stack. */
- volume_stack[1].shader = SHADER_NONE;
- }
- else {
- volume_stack[0].shader = SHADER_NONE;
- }
+ if (kernel_data.background.volume_shader != SHADER_NONE) {
+ /* Keep the world's volume in stack. */
+ volume_stack[1].shader = SHADER_NONE;
+ }
+ else {
+ volume_stack[0].shader = SHADER_NONE;
+ }
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_work_stealing.h b/intern/cycles/kernel/kernel_work_stealing.h
index 9667156eaf5..799561a7466 100644
--- a/intern/cycles/kernel/kernel_work_stealing.h
+++ b/intern/cycles/kernel/kernel_work_stealing.h
@@ -35,27 +35,26 @@ ccl_device bool get_next_work(KernelGlobals *kg,
uint ray_index,
ccl_private uint *global_work_index)
{
- /* With a small amount of work there may be more threads than work due to
- * rounding up of global size, stop such threads immediately. */
- if(ray_index >= total_work_size) {
- return false;
- }
+ /* With a small amount of work there may be more threads than work due to
+ * rounding up of global size, stop such threads immediately. */
+ if (ray_index >= total_work_size) {
+ return false;
+ }
- /* Increase atomic work index counter in pool. */
- uint pool = ray_index / WORK_POOL_SIZE;
- uint work_index = atomic_fetch_and_inc_uint32(&work_pools[pool]);
+ /* Increase atomic work index counter in pool. */
+ uint pool = ray_index / WORK_POOL_SIZE;
+ uint work_index = atomic_fetch_and_inc_uint32(&work_pools[pool]);
- /* Map per-pool work index to a global work index. */
- uint global_size = ccl_global_size(0) * ccl_global_size(1);
- kernel_assert(global_size % WORK_POOL_SIZE == 0);
- kernel_assert(ray_index < global_size);
+ /* Map per-pool work index to a global work index. */
+ uint global_size = ccl_global_size(0) * ccl_global_size(1);
+ kernel_assert(global_size % WORK_POOL_SIZE == 0);
+ kernel_assert(ray_index < global_size);
- *global_work_index = (work_index / WORK_POOL_SIZE) * global_size
- + (pool * WORK_POOL_SIZE)
- + (work_index % WORK_POOL_SIZE);
+ *global_work_index = (work_index / WORK_POOL_SIZE) * global_size + (pool * WORK_POOL_SIZE) +
+ (work_index % WORK_POOL_SIZE);
- /* Test if all work for this pool is done. */
- return (*global_work_index < total_work_size);
+ /* Test if all work for this pool is done. */
+ return (*global_work_index < total_work_size);
}
#endif
@@ -67,22 +66,22 @@ ccl_device_inline void get_work_pixel(ccl_global const WorkTile *tile,
ccl_private uint *sample)
{
#ifdef __KERNEL_CUDA__
- /* Keeping threads for the same pixel together improves performance on CUDA. */
- uint sample_offset = global_work_index % tile->num_samples;
- uint pixel_offset = global_work_index / tile->num_samples;
-#else /* __KERNEL_CUDA__ */
- uint tile_pixels = tile->w * tile->h;
- uint sample_offset = global_work_index / tile_pixels;
- uint pixel_offset = global_work_index - sample_offset * tile_pixels;
+ /* Keeping threads for the same pixel together improves performance on CUDA. */
+ uint sample_offset = global_work_index % tile->num_samples;
+ uint pixel_offset = global_work_index / tile->num_samples;
+#else /* __KERNEL_CUDA__ */
+ uint tile_pixels = tile->w * tile->h;
+ uint sample_offset = global_work_index / tile_pixels;
+ uint pixel_offset = global_work_index - sample_offset * tile_pixels;
#endif /* __KERNEL_CUDA__ */
- uint y_offset = pixel_offset / tile->w;
- uint x_offset = pixel_offset - y_offset * tile->w;
+ uint y_offset = pixel_offset / tile->w;
+ uint x_offset = pixel_offset - y_offset * tile->w;
- *x = tile->x + x_offset;
- *y = tile->y + y_offset;
- *sample = tile->start_sample + sample_offset;
+ *x = tile->x + x_offset;
+ *y = tile->y + y_offset;
+ *sample = tile->start_sample + sample_offset;
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_WORK_STEALING_H__ */
+#endif /* __KERNEL_WORK_STEALING_H__ */
diff --git a/intern/cycles/kernel/kernels/cpu/filter.cpp b/intern/cycles/kernel/kernels/cpu/filter.cpp
index 2ff1a392dc3..145a6b6ac40 100644
--- a/intern/cycles/kernel/kernels/cpu/filter.cpp
+++ b/intern/cycles/kernel/kernels/cpu/filter.cpp
@@ -53,7 +53,7 @@
/* quiet unused define warnings */
#if defined(__KERNEL_SSE2__)
- /* do nothing */
+/* do nothing */
#endif
#include "kernel/filter/filter.h"
diff --git a/intern/cycles/kernel/kernels/cpu/filter_avx.cpp b/intern/cycles/kernel/kernels/cpu/filter_avx.cpp
index 4a9e6047ecf..1d68214c8e7 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_avx.cpp
+++ b/intern/cycles/kernel/kernels/cpu/filter_avx.cpp
@@ -32,7 +32,7 @@
# define __KERNEL_SSE41__
# define __KERNEL_AVX__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX */
#include "kernel/filter/filter.h"
#define KERNEL_ARCH cpu_avx
diff --git a/intern/cycles/kernel/kernels/cpu/filter_avx2.cpp b/intern/cycles/kernel/kernels/cpu/filter_avx2.cpp
index c22ec576254..b6709fbc529 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_avx2.cpp
+++ b/intern/cycles/kernel/kernels/cpu/filter_avx2.cpp
@@ -33,7 +33,7 @@
# define __KERNEL_AVX__
# define __KERNEL_AVX2__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 */
#include "kernel/filter/filter.h"
#define KERNEL_ARCH cpu_avx2
diff --git a/intern/cycles/kernel/kernels/cpu/filter_cpu.h b/intern/cycles/kernel/kernels/cpu/filter_cpu.h
index 02c85562db8..1423b182ab8 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_cpu.h
+++ b/intern/cycles/kernel/kernels/cpu/filter_cpu.h
@@ -25,7 +25,7 @@ void KERNEL_FUNCTION_FULL_NAME(filter_divide_shadow)(int sample,
float *sampleV,
float *sampleVV,
float *bufferV,
- int* prefilter_rect,
+ int *prefilter_rect,
int buffer_pass_stride,
int buffer_denoising_offset);
@@ -38,7 +38,7 @@ void KERNEL_FUNCTION_FULL_NAME(filter_get_feature)(int sample,
float *mean,
float *variance,
float scale,
- int* prefilter_rect,
+ int *prefilter_rect,
int buffer_pass_stride,
int buffer_denoising_offset);
@@ -49,9 +49,10 @@ void KERNEL_FUNCTION_FULL_NAME(filter_write_feature)(int sample,
float *from,
float *buffer,
int out_offset,
- int* prefilter_rect);
+ int *prefilter_rect);
-void KERNEL_FUNCTION_FULL_NAME(filter_detect_outliers)(int x, int y,
+void KERNEL_FUNCTION_FULL_NAME(filter_detect_outliers)(int x,
+ int y,
ccl_global float *image,
ccl_global float *variance,
ccl_global float *depth,
@@ -59,22 +60,17 @@ void KERNEL_FUNCTION_FULL_NAME(filter_detect_outliers)(int x, int y,
int *rect,
int pass_stride);
-void KERNEL_FUNCTION_FULL_NAME(filter_combine_halves)(int x, int y,
- float *mean,
- float *variance,
- float *a,
- float *b,
- int* prefilter_rect,
- int r);
+void KERNEL_FUNCTION_FULL_NAME(filter_combine_halves)(
+ int x, int y, float *mean, float *variance, float *a, float *b, int *prefilter_rect, int r);
-void KERNEL_FUNCTION_FULL_NAME(filter_construct_transform)(float* buffer,
+void KERNEL_FUNCTION_FULL_NAME(filter_construct_transform)(float *buffer,
TileInfo *tiles,
int x,
int y,
int storage_ofs,
float *transform,
int *rank,
- int* rect,
+ int *rect,
int pass_stride,
int frame_stride,
bool use_time,
@@ -87,24 +83,18 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_difference)(int dx,
float *variance_image,
float *scale_image,
float *difference_image,
- int* rect,
+ int *rect,
int stride,
int channel_offset,
int frame_offset,
float a,
float k_2);
-void KERNEL_FUNCTION_FULL_NAME(filter_nlm_blur)(float *difference_image,
- float *out_image,
- int* rect,
- int stride,
- int f);
+void KERNEL_FUNCTION_FULL_NAME(filter_nlm_blur)(
+ float *difference_image, float *out_image, int *rect, int stride, int f);
-void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_weight)(float *difference_image,
- float *out_image,
- int* rect,
- int stride,
- int f);
+void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_weight)(
+ float *difference_image, float *out_image, int *rect, int stride, int f);
void KERNEL_FUNCTION_FULL_NAME(filter_nlm_update_output)(int dx,
int dy,
@@ -113,7 +103,7 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_update_output)(int dx,
float *temp_image,
float *out_image,
float *accum_image,
- int* rect,
+ int *rect,
int channel_offset,
int stride,
int f);
@@ -137,7 +127,7 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_construct_gramian)(int dx,
void KERNEL_FUNCTION_FULL_NAME(filter_nlm_normalize)(float *out_image,
float *accum_image,
- int* rect,
+ int *rect,
int stride);
void KERNEL_FUNCTION_FULL_NAME(filter_finalize)(int x,
diff --git a/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h b/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h
index c29505880cb..3d4cb87e104 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h
+++ b/intern/cycles/kernel/kernels/cpu/filter_cpu_impl.h
@@ -25,12 +25,12 @@
#include "kernel/filter/filter_kernel.h"
#ifdef KERNEL_STUB
-# define STUB_ASSERT(arch, name) assert(!(#name " kernel stub for architecture " #arch " was called!"))
+# define STUB_ASSERT(arch, name) \
+ assert(!(#name " kernel stub for architecture " #arch " was called!"))
#endif
CCL_NAMESPACE_BEGIN
-
/* Denoise filter */
void KERNEL_FUNCTION_FULL_NAME(filter_divide_shadow)(int sample,
@@ -42,23 +42,25 @@ void KERNEL_FUNCTION_FULL_NAME(filter_divide_shadow)(int sample,
float *sampleVariance,
float *sampleVarianceV,
float *bufferVariance,
- int* prefilter_rect,
+ int *prefilter_rect,
int buffer_pass_stride,
int buffer_denoising_offset)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_divide_shadow);
+ STUB_ASSERT(KERNEL_ARCH, filter_divide_shadow);
#else
- kernel_filter_divide_shadow(sample, tile_info,
- x, y,
- unfilteredA,
- unfilteredB,
- sampleVariance,
- sampleVarianceV,
- bufferVariance,
- load_int4(prefilter_rect),
- buffer_pass_stride,
- buffer_denoising_offset);
+ kernel_filter_divide_shadow(sample,
+ tile_info,
+ x,
+ y,
+ unfilteredA,
+ unfilteredB,
+ sampleVariance,
+ sampleVarianceV,
+ bufferVariance,
+ load_int4(prefilter_rect),
+ buffer_pass_stride,
+ buffer_denoising_offset);
#endif
}
@@ -68,23 +70,28 @@ void KERNEL_FUNCTION_FULL_NAME(filter_get_feature)(int sample,
int v_offset,
int x,
int y,
- float *mean, float *variance,
+ float *mean,
+ float *variance,
float scale,
- int* prefilter_rect,
+ int *prefilter_rect,
int buffer_pass_stride,
int buffer_denoising_offset)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_get_feature);
+ STUB_ASSERT(KERNEL_ARCH, filter_get_feature);
#else
- kernel_filter_get_feature(sample, tile_info,
- m_offset, v_offset,
- x, y,
- mean, variance,
- scale,
- load_int4(prefilter_rect),
- buffer_pass_stride,
- buffer_denoising_offset);
+ kernel_filter_get_feature(sample,
+ tile_info,
+ m_offset,
+ v_offset,
+ x,
+ y,
+ mean,
+ variance,
+ scale,
+ load_int4(prefilter_rect),
+ buffer_pass_stride,
+ buffer_denoising_offset);
#endif
}
@@ -95,16 +102,18 @@ void KERNEL_FUNCTION_FULL_NAME(filter_write_feature)(int sample,
float *from,
float *buffer,
int out_offset,
- int* prefilter_rect)
+ int *prefilter_rect)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_write_feature);
+ STUB_ASSERT(KERNEL_ARCH, filter_write_feature);
#else
- kernel_filter_write_feature(sample, x, y, load_int4(buffer_params), from, buffer, out_offset, load_int4(prefilter_rect));
+ kernel_filter_write_feature(
+ sample, x, y, load_int4(buffer_params), from, buffer, out_offset, load_int4(prefilter_rect));
#endif
}
-void KERNEL_FUNCTION_FULL_NAME(filter_detect_outliers)(int x, int y,
+void KERNEL_FUNCTION_FULL_NAME(filter_detect_outliers)(int x,
+ int y,
ccl_global float *image,
ccl_global float *variance,
ccl_global float *depth,
@@ -113,35 +122,31 @@ void KERNEL_FUNCTION_FULL_NAME(filter_detect_outliers)(int x, int y,
int pass_stride)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_detect_outliers);
+ STUB_ASSERT(KERNEL_ARCH, filter_detect_outliers);
#else
- kernel_filter_detect_outliers(x, y, image, variance, depth, output, load_int4(rect), pass_stride);
+ kernel_filter_detect_outliers(
+ x, y, image, variance, depth, output, load_int4(rect), pass_stride);
#endif
}
-void KERNEL_FUNCTION_FULL_NAME(filter_combine_halves)(int x, int y,
- float *mean,
- float *variance,
- float *a,
- float *b,
- int* prefilter_rect,
- int r)
+void KERNEL_FUNCTION_FULL_NAME(filter_combine_halves)(
+ int x, int y, float *mean, float *variance, float *a, float *b, int *prefilter_rect, int r)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_combine_halves);
+ STUB_ASSERT(KERNEL_ARCH, filter_combine_halves);
#else
- kernel_filter_combine_halves(x, y, mean, variance, a, b, load_int4(prefilter_rect), r);
+ kernel_filter_combine_halves(x, y, mean, variance, a, b, load_int4(prefilter_rect), r);
#endif
}
-void KERNEL_FUNCTION_FULL_NAME(filter_construct_transform)(float* buffer,
+void KERNEL_FUNCTION_FULL_NAME(filter_construct_transform)(float *buffer,
TileInfo *tile_info,
int x,
int y,
int storage_ofs,
float *transform,
int *rank,
- int* prefilter_rect,
+ int *prefilter_rect,
int pass_stride,
int frame_stride,
bool use_time,
@@ -149,21 +154,22 @@ void KERNEL_FUNCTION_FULL_NAME(filter_construct_transform)(float* buffer,
float pca_threshold)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_construct_transform);
+ STUB_ASSERT(KERNEL_ARCH, filter_construct_transform);
#else
- rank += storage_ofs;
- transform += storage_ofs*TRANSFORM_SIZE;
- kernel_filter_construct_transform(buffer,
- tile_info,
- x, y,
- load_int4(prefilter_rect),
- pass_stride,
- frame_stride,
- use_time,
- transform,
- rank,
- radius,
- pca_threshold);
+ rank += storage_ofs;
+ transform += storage_ofs * TRANSFORM_SIZE;
+ kernel_filter_construct_transform(buffer,
+ tile_info,
+ x,
+ y,
+ load_int4(prefilter_rect),
+ pass_stride,
+ frame_stride,
+ use_time,
+ transform,
+ rank,
+ radius,
+ pca_threshold);
#endif
}
@@ -181,44 +187,40 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_difference)(int dx,
float k_2)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_difference);
+ STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_difference);
#else
- kernel_filter_nlm_calc_difference(dx, dy,
- weight_image,
- variance_image,
- scale_image,
- difference_image,
- load_int4(rect),
- stride,
- channel_offset,
- frame_offset,
- a, k_2);
+ kernel_filter_nlm_calc_difference(dx,
+ dy,
+ weight_image,
+ variance_image,
+ scale_image,
+ difference_image,
+ load_int4(rect),
+ stride,
+ channel_offset,
+ frame_offset,
+ a,
+ k_2);
#endif
}
-void KERNEL_FUNCTION_FULL_NAME(filter_nlm_blur)(float *difference_image,
- float *out_image,
- int *rect,
- int stride,
- int f)
+void KERNEL_FUNCTION_FULL_NAME(filter_nlm_blur)(
+ float *difference_image, float *out_image, int *rect, int stride, int f)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_nlm_blur);
+ STUB_ASSERT(KERNEL_ARCH, filter_nlm_blur);
#else
- kernel_filter_nlm_blur(difference_image, out_image, load_int4(rect), stride, f);
+ kernel_filter_nlm_blur(difference_image, out_image, load_int4(rect), stride, f);
#endif
}
-void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_weight)(float *difference_image,
- float *out_image,
- int *rect,
- int stride,
- int f)
+void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_weight)(
+ float *difference_image, float *out_image, int *rect, int stride, int f)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_weight);
+ STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_weight);
#else
- kernel_filter_nlm_calc_weight(difference_image, out_image, load_int4(rect), stride, f);
+ kernel_filter_nlm_calc_weight(difference_image, out_image, load_int4(rect), stride, f);
#endif
}
@@ -235,17 +237,19 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_update_output)(int dx,
int f)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_nlm_update_output);
+ STUB_ASSERT(KERNEL_ARCH, filter_nlm_update_output);
#else
- kernel_filter_nlm_update_output(dx, dy,
- difference_image,
- image,
- temp_image,
- out_image,
- accum_image,
- load_int4(rect),
- channel_offset,
- stride, f);
+ kernel_filter_nlm_update_output(dx,
+ dy,
+ difference_image,
+ image,
+ temp_image,
+ out_image,
+ accum_image,
+ load_int4(rect),
+ channel_offset,
+ stride,
+ f);
#endif
}
@@ -267,19 +271,24 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_construct_gramian)(int dx,
bool use_time)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_nlm_construct_gramian);
+ STUB_ASSERT(KERNEL_ARCH, filter_nlm_construct_gramian);
#else
- kernel_filter_nlm_construct_gramian(dx, dy, t,
- difference_image,
- buffer,
- transform, rank,
- XtWX, XtWY,
- load_int4(rect),
- load_int4(filter_window),
- stride, f,
- pass_stride,
- frame_offset,
- use_time);
+ kernel_filter_nlm_construct_gramian(dx,
+ dy,
+ t,
+ difference_image,
+ buffer,
+ transform,
+ rank,
+ XtWX,
+ XtWY,
+ load_int4(rect),
+ load_int4(filter_window),
+ stride,
+ f,
+ pass_stride,
+ frame_offset,
+ use_time);
#endif
}
@@ -289,9 +298,9 @@ void KERNEL_FUNCTION_FULL_NAME(filter_nlm_normalize)(float *out_image,
int stride)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_nlm_normalize);
+ STUB_ASSERT(KERNEL_ARCH, filter_nlm_normalize);
#else
- kernel_filter_nlm_normalize(out_image, accum_image, load_int4(rect), stride);
+ kernel_filter_nlm_normalize(out_image, accum_image, load_int4(rect), stride);
#endif
}
@@ -306,12 +315,12 @@ void KERNEL_FUNCTION_FULL_NAME(filter_finalize)(int x,
int sample)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, filter_finalize);
+ STUB_ASSERT(KERNEL_ARCH, filter_finalize);
#else
- XtWX += storage_ofs*XTWX_SIZE;
- XtWY += storage_ofs*XTWY_SIZE;
- rank += storage_ofs;
- kernel_filter_finalize(x, y, buffer, rank, 1, XtWX, XtWY, load_int4(buffer_params), sample);
+ XtWX += storage_ofs * XTWX_SIZE;
+ XtWY += storage_ofs * XTWY_SIZE;
+ rank += storage_ofs;
+ kernel_filter_finalize(x, y, buffer, rank, 1, XtWX, XtWY, load_int4(buffer_params), sample);
#endif
}
diff --git a/intern/cycles/kernel/kernels/cpu/filter_sse2.cpp b/intern/cycles/kernel/kernels/cpu/filter_sse2.cpp
index f7c9935f1d0..6c6c3e78696 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_sse2.cpp
+++ b/intern/cycles/kernel/kernels/cpu/filter_sse2.cpp
@@ -27,7 +27,7 @@
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
# define __KERNEL_SSE2__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 */
#include "kernel/filter/filter.h"
#define KERNEL_ARCH cpu_sse2
diff --git a/intern/cycles/kernel/kernels/cpu/filter_sse3.cpp b/intern/cycles/kernel/kernels/cpu/filter_sse3.cpp
index 070b95a3505..e2243000331 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_sse3.cpp
+++ b/intern/cycles/kernel/kernels/cpu/filter_sse3.cpp
@@ -29,7 +29,7 @@
# define __KERNEL_SSE3__
# define __KERNEL_SSSE3__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 */
#include "kernel/filter/filter.h"
#define KERNEL_ARCH cpu_sse3
diff --git a/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp b/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp
index 254025be4e2..068889365e3 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp
+++ b/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp
@@ -31,7 +31,7 @@
# define __KERNEL_SSSE3__
# define __KERNEL_SSE41__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 */
#include "kernel/filter/filter.h"
#define KERNEL_ARCH cpu_sse41
diff --git a/intern/cycles/kernel/kernels/cpu/kernel.cpp b/intern/cycles/kernel/kernels/cpu/kernel.cpp
index de487f6123f..f2146302a27 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel.cpp
@@ -53,7 +53,7 @@
/* quiet unused define warnings */
#if defined(__KERNEL_SSE2__)
- /* do nothing */
+/* do nothing */
#endif
#include "kernel/kernel.h"
@@ -66,29 +66,27 @@ CCL_NAMESPACE_BEGIN
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size)
{
- if(strcmp(name, "__data") == 0)
- memcpy(&kg->__data, host, size);
- else
- assert(0);
+ if (strcmp(name, "__data") == 0)
+ memcpy(&kg->__data, host, size);
+ else
+ assert(0);
}
-void kernel_tex_copy(KernelGlobals *kg,
- const char *name,
- void *mem,
- size_t size)
+void kernel_tex_copy(KernelGlobals *kg, const char *name, void *mem, size_t size)
{
- if(0) {
- }
+ if (0) {
+ }
#define KERNEL_TEX(type, tname) \
- else if(strcmp(name, #tname) == 0) { \
- kg->tname.data = (type*)mem; \
- kg->tname.width = size; \
- }
+ else if (strcmp(name, #tname) == 0) \
+ { \
+ kg->tname.data = (type *)mem; \
+ kg->tname.width = size; \
+ }
#include "kernel/kernel_textures.h"
- else {
- assert(0);
- }
+ else {
+ assert(0);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_avx.cpp b/intern/cycles/kernel/kernels/cpu/kernel_avx.cpp
index a645fb4d8dd..0656fc9dd00 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_avx.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_avx.cpp
@@ -32,7 +32,7 @@
# define __KERNEL_SSE41__
# define __KERNEL_AVX__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_avx
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp b/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp
index 6bbb87727b9..5baafdc699e 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp
@@ -33,7 +33,7 @@
# define __KERNEL_AVX__
# define __KERNEL_AVX2__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_avx2
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
index 6bdb8546a24..f5d981fb71a 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
@@ -16,25 +16,24 @@
/* Templated common declaration part of all CPU kernels. */
-void KERNEL_FUNCTION_FULL_NAME(path_trace)(KernelGlobals *kg,
- float *buffer,
- int sample,
- int x, int y,
- int offset,
- int stride);
+void KERNEL_FUNCTION_FULL_NAME(path_trace)(
+ KernelGlobals *kg, float *buffer, int sample, int x, int y, int offset, int stride);
void KERNEL_FUNCTION_FULL_NAME(convert_to_byte)(KernelGlobals *kg,
uchar4 *rgba,
float *buffer,
float sample_scale,
- int x, int y,
- int offset, int stride);
+ int x,
+ int y,
+ int offset,
+ int stride);
void KERNEL_FUNCTION_FULL_NAME(convert_to_half_float)(KernelGlobals *kg,
uchar4 *rgba,
float *buffer,
float sample_scale,
- int x, int y,
+ int x,
+ int y,
int offset,
int stride);
@@ -49,24 +48,28 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
/* Split kernels */
-void KERNEL_FUNCTION_FULL_NAME(data_init)(
- KernelGlobals *kg,
- ccl_constant KernelData *data,
- ccl_global void *split_data_buffer,
- int num_elements,
- ccl_global char *ray_state,
- int start_sample,
- int end_sample,
- int sx, int sy, int sw, int sh, int offset, int stride,
- ccl_global int *Queue_index,
- int queuesize,
- ccl_global char *use_queues_flag,
- ccl_global unsigned int *work_pool_wgs,
- unsigned int num_samples,
- ccl_global float *buffer);
+void KERNEL_FUNCTION_FULL_NAME(data_init)(KernelGlobals *kg,
+ ccl_constant KernelData *data,
+ ccl_global void *split_data_buffer,
+ int num_elements,
+ ccl_global char *ray_state,
+ int start_sample,
+ int end_sample,
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ int offset,
+ int stride,
+ ccl_global int *Queue_index,
+ int queuesize,
+ ccl_global char *use_queues_flag,
+ ccl_global unsigned int *work_pool_wgs,
+ unsigned int num_samples,
+ ccl_global float *buffer);
#define DECLARE_SPLIT_KERNEL_FUNCTION(name) \
- void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals *kg, KernelData *data);
+ void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals * kg, KernelData * data);
DECLARE_SPLIT_KERNEL_FUNCTION(path_init)
DECLARE_SPLIT_KERNEL_FUNCTION(scene_intersect)
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
index ae4fd85780d..4289e2bbb85 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
@@ -19,523 +19,508 @@
CCL_NAMESPACE_BEGIN
-template<typename T> struct TextureInterpolator {
+template<typename T> struct TextureInterpolator {
#define SET_CUBIC_SPLINE_WEIGHTS(u, t) \
- { \
- u[0] = (((-1.0f/6.0f)* t + 0.5f) * t - 0.5f) * t + (1.0f/6.0f); \
- u[1] = (( 0.5f * t - 1.0f) * t ) * t + (2.0f/3.0f); \
- u[2] = (( -0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f/6.0f); \
- u[3] = (1.0f / 6.0f) * t * t * t; \
- } (void) 0
-
- static ccl_always_inline float4 read(float4 r)
- {
- return r;
- }
-
- static ccl_always_inline float4 read(uchar4 r)
- {
- float f = 1.0f / 255.0f;
- return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
- }
-
- static ccl_always_inline float4 read(uchar r)
- {
- float f = r * (1.0f / 255.0f);
- return make_float4(f, f, f, 1.0f);
- }
-
- static ccl_always_inline float4 read(float r)
- {
- /* TODO(dingto): Optimize this, so interpolation
- * happens on float instead of float4 */
- return make_float4(r, r, r, 1.0f);
- }
-
- static ccl_always_inline float4 read(half4 r)
- {
- return half4_to_float4(r);
- }
-
- static ccl_always_inline float4 read(half r)
- {
- float f = half_to_float(r);
- return make_float4(f, f, f, 1.0f);
- }
-
- static ccl_always_inline float4 read(uint16_t r)
- {
- float f = r*(1.0f/65535.0f);
- return make_float4(f, f, f, 1.0f);
- }
-
- static ccl_always_inline float4 read(ushort4 r)
- {
- float f = 1.0f/65535.0f;
- return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
- }
-
- static ccl_always_inline float4 read(const T *data,
- int x, int y,
- int width, int height)
- {
- if(x < 0 || y < 0 || x >= width || y >= height) {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- return read(data[y * width + x]);
- }
-
- static ccl_always_inline int wrap_periodic(int x, int width)
- {
- x %= width;
- if(x < 0)
- x += width;
- return x;
- }
-
- static ccl_always_inline int wrap_clamp(int x, int width)
- {
- return clamp(x, 0, width-1);
- }
-
- static ccl_always_inline float frac(float x, int *ix)
- {
- int i = float_to_int(x) - ((x < 0.0f)? 1: 0);
- *ix = i;
- return x - (float)i;
- }
-
- /* ******** 2D interpolation ******** */
-
- static ccl_always_inline float4 interp_closest(const TextureInfo& info,
- float x, float y)
- {
- const T *data = (const T*)info.data;
- const int width = info.width;
- const int height = info.height;
- int ix, iy;
- frac(x*(float)width, &ix);
- frac(y*(float)height, &iy);
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- ATTR_FALLTHROUGH;
- case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- return read(data[ix + iy*width]);
- }
-
- static ccl_always_inline float4 interp_linear(const TextureInfo& info,
- float x, float y)
- {
- const T *data = (const T*)info.data;
- const int width = info.width;
- const int height = info.height;
- int ix, iy, nix, niy;
- const float tx = frac(x*(float)width - 0.5f, &ix);
- const float ty = frac(y*(float)height - 0.5f, &iy);
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
- break;
- case EXTENSION_CLIP:
- nix = ix + 1;
- niy = iy + 1;
- break;
- case EXTENSION_EXTEND:
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- return (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, width, height) +
- (1.0f - ty) * tx * read(data, nix, iy, width, height) +
- ty * (1.0f - tx) * read(data, ix, niy, width, height) +
- ty * tx * read(data, nix, niy, width, height);
- }
-
- static ccl_always_inline float4 interp_cubic(const TextureInfo& info,
- float x, float y)
- {
- const T *data = (const T*)info.data;
- const int width = info.width;
- const int height = info.height;
- int ix, iy, nix, niy;
- const float tx = frac(x*(float)width - 0.5f, &ix);
- const float ty = frac(y*(float)height - 0.5f, &iy);
- int pix, piy, nnix, nniy;
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- pix = wrap_periodic(ix-1, width);
- piy = wrap_periodic(iy-1, height);
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
- nnix = wrap_periodic(ix+2, width);
- nniy = wrap_periodic(iy+2, height);
- break;
- case EXTENSION_CLIP:
- pix = ix - 1;
- piy = iy - 1;
- nix = ix + 1;
- niy = iy + 1;
- nnix = ix + 2;
- nniy = iy + 2;
- break;
- case EXTENSION_EXTEND:
- pix = wrap_clamp(ix-1, width);
- piy = wrap_clamp(iy-1, height);
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
- nnix = wrap_clamp(ix+2, width);
- nniy = wrap_clamp(iy+2, height);
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- const int xc[4] = {pix, ix, nix, nnix};
- const int yc[4] = {piy, iy, niy, nniy};
- float u[4], v[4];
- /* Some helper macro to keep code reasonable size,
- * let compiler to inline all the matrix multiplications.
- */
+ { \
+ u[0] = (((-1.0f / 6.0f) * t + 0.5f) * t - 0.5f) * t + (1.0f / 6.0f); \
+ u[1] = ((0.5f * t - 1.0f) * t) * t + (2.0f / 3.0f); \
+ u[2] = ((-0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f / 6.0f); \
+ u[3] = (1.0f / 6.0f) * t * t * t; \
+ } \
+ (void)0
+
+ static ccl_always_inline float4 read(float4 r)
+ {
+ return r;
+ }
+
+ static ccl_always_inline float4 read(uchar4 r)
+ {
+ float f = 1.0f / 255.0f;
+ return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
+ }
+
+ static ccl_always_inline float4 read(uchar r)
+ {
+ float f = r * (1.0f / 255.0f);
+ return make_float4(f, f, f, 1.0f);
+ }
+
+ static ccl_always_inline float4 read(float r)
+ {
+ /* TODO(dingto): Optimize this, so interpolation
+ * happens on float instead of float4 */
+ return make_float4(r, r, r, 1.0f);
+ }
+
+ static ccl_always_inline float4 read(half4 r)
+ {
+ return half4_to_float4(r);
+ }
+
+ static ccl_always_inline float4 read(half r)
+ {
+ float f = half_to_float(r);
+ return make_float4(f, f, f, 1.0f);
+ }
+
+ static ccl_always_inline float4 read(uint16_t r)
+ {
+ float f = r * (1.0f / 65535.0f);
+ return make_float4(f, f, f, 1.0f);
+ }
+
+ static ccl_always_inline float4 read(ushort4 r)
+ {
+ float f = 1.0f / 65535.0f;
+ return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
+ }
+
+ static ccl_always_inline float4 read(const T *data, int x, int y, int width, int height)
+ {
+ if (x < 0 || y < 0 || x >= width || y >= height) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ return read(data[y * width + x]);
+ }
+
+ static ccl_always_inline int wrap_periodic(int x, int width)
+ {
+ x %= width;
+ if (x < 0)
+ x += width;
+ return x;
+ }
+
+ static ccl_always_inline int wrap_clamp(int x, int width)
+ {
+ return clamp(x, 0, width - 1);
+ }
+
+ static ccl_always_inline float frac(float x, int *ix)
+ {
+ int i = float_to_int(x) - ((x < 0.0f) ? 1 : 0);
+ *ix = i;
+ return x - (float)i;
+ }
+
+ /* ******** 2D interpolation ******** */
+
+ static ccl_always_inline float4 interp_closest(const TextureInfo &info, float x, float y)
+ {
+ const T *data = (const T *)info.data;
+ const int width = info.width;
+ const int height = info.height;
+ int ix, iy;
+ frac(x * (float)width, &ix);
+ frac(y * (float)height, &iy);
+ switch (info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ break;
+ case EXTENSION_CLIP:
+ if (x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ ATTR_FALLTHROUGH;
+ case EXTENSION_EXTEND:
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ return read(data[ix + iy * width]);
+ }
+
+ static ccl_always_inline float4 interp_linear(const TextureInfo &info, float x, float y)
+ {
+ const T *data = (const T *)info.data;
+ const int width = info.width;
+ const int height = info.height;
+ int ix, iy, nix, niy;
+ const float tx = frac(x * (float)width - 0.5f, &ix);
+ const float ty = frac(y * (float)height - 0.5f, &iy);
+ switch (info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ nix = wrap_periodic(ix + 1, width);
+ niy = wrap_periodic(iy + 1, height);
+ break;
+ case EXTENSION_CLIP:
+ nix = ix + 1;
+ niy = iy + 1;
+ break;
+ case EXTENSION_EXTEND:
+ nix = wrap_clamp(ix + 1, width);
+ niy = wrap_clamp(iy + 1, height);
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ return (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, width, height) +
+ (1.0f - ty) * tx * read(data, nix, iy, width, height) +
+ ty * (1.0f - tx) * read(data, ix, niy, width, height) +
+ ty * tx * read(data, nix, niy, width, height);
+ }
+
+ static ccl_always_inline float4 interp_cubic(const TextureInfo &info, float x, float y)
+ {
+ const T *data = (const T *)info.data;
+ const int width = info.width;
+ const int height = info.height;
+ int ix, iy, nix, niy;
+ const float tx = frac(x * (float)width - 0.5f, &ix);
+ const float ty = frac(y * (float)height - 0.5f, &iy);
+ int pix, piy, nnix, nniy;
+ switch (info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ pix = wrap_periodic(ix - 1, width);
+ piy = wrap_periodic(iy - 1, height);
+ nix = wrap_periodic(ix + 1, width);
+ niy = wrap_periodic(iy + 1, height);
+ nnix = wrap_periodic(ix + 2, width);
+ nniy = wrap_periodic(iy + 2, height);
+ break;
+ case EXTENSION_CLIP:
+ pix = ix - 1;
+ piy = iy - 1;
+ nix = ix + 1;
+ niy = iy + 1;
+ nnix = ix + 2;
+ nniy = iy + 2;
+ break;
+ case EXTENSION_EXTEND:
+ pix = wrap_clamp(ix - 1, width);
+ piy = wrap_clamp(iy - 1, height);
+ nix = wrap_clamp(ix + 1, width);
+ niy = wrap_clamp(iy + 1, height);
+ nnix = wrap_clamp(ix + 2, width);
+ nniy = wrap_clamp(iy + 2, height);
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ const int xc[4] = {pix, ix, nix, nnix};
+ const int yc[4] = {piy, iy, niy, nniy};
+ float u[4], v[4];
+ /* Some helper macro to keep code reasonable size,
+ * let compiler to inline all the matrix multiplications.
+ */
#define DATA(x, y) (read(data, xc[x], yc[y], width, height))
#define TERM(col) \
- (v[col] * (u[0] * DATA(0, col) + \
- u[1] * DATA(1, col) + \
- u[2] * DATA(2, col) + \
- u[3] * DATA(3, col)))
+ (v[col] * \
+ (u[0] * DATA(0, col) + u[1] * DATA(1, col) + u[2] * DATA(2, col) + u[3] * DATA(3, col)))
- SET_CUBIC_SPLINE_WEIGHTS(u, tx);
- SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
- /* Actual interpolation. */
- return TERM(0) + TERM(1) + TERM(2) + TERM(3);
+ /* Actual interpolation. */
+ return TERM(0) + TERM(1) + TERM(2) + TERM(3);
#undef TERM
#undef DATA
- }
-
- static ccl_always_inline float4 interp(const TextureInfo& info,
- float x, float y)
- {
- if(UNLIKELY(!info.data)) {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- switch(info.interpolation) {
- case INTERPOLATION_CLOSEST:
- return interp_closest(info, x, y);
- case INTERPOLATION_LINEAR:
- return interp_linear(info, x, y);
- default:
- return interp_cubic(info, x, y);
- }
- }
-
- /* ******** 3D interpolation ******** */
-
- static ccl_always_inline float4 interp_3d_closest(const TextureInfo& info,
- float x, float y, float z)
- {
- int width = info.width;
- int height = info.height;
- int depth = info.depth;
- int ix, iy, iz;
-
- frac(x*(float)width, &ix);
- frac(y*(float)height, &iy);
- frac(z*(float)depth, &iz);
-
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- iz = wrap_periodic(iz, depth);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || z < 0.0f ||
- x > 1.0f || y > 1.0f || z > 1.0f)
- {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- ATTR_FALLTHROUGH;
- case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- const T *data = (const T*)info.data;
- return read(data[ix + iy*width + iz*width*height]);
- }
-
- static ccl_always_inline float4 interp_3d_linear(const TextureInfo& info,
- float x, float y, float z)
- {
- int width = info.width;
- int height = info.height;
- int depth = info.depth;
- int ix, iy, iz;
- int nix, niy, niz;
-
- float tx = frac(x*(float)width - 0.5f, &ix);
- float ty = frac(y*(float)height - 0.5f, &iy);
- float tz = frac(z*(float)depth - 0.5f, &iz);
-
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- iz = wrap_periodic(iz, depth);
-
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
- niz = wrap_periodic(iz+1, depth);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || z < 0.0f ||
- x > 1.0f || y > 1.0f || z > 1.0f)
- {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- ATTR_FALLTHROUGH;
- case EXTENSION_EXTEND:
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
- niz = wrap_clamp(iz+1, depth);
-
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- const T *data = (const T*)info.data;
- float4 r;
-
- r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + iz*width*height]);
- r += (1.0f - tz)*(1.0f - ty)*tx*read(data[nix + iy*width + iz*width*height]);
- r += (1.0f - tz)*ty*(1.0f - tx)*read(data[ix + niy*width + iz*width*height]);
- r += (1.0f - tz)*ty*tx*read(data[nix + niy*width + iz*width*height]);
-
- r += tz*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + niz*width*height]);
- r += tz*(1.0f - ty)*tx*read(data[nix + iy*width + niz*width*height]);
- r += tz*ty*(1.0f - tx)*read(data[ix + niy*width + niz*width*height]);
- r += tz*ty*tx*read(data[nix + niy*width + niz*width*height]);
-
- return r;
- }
-
- /* TODO(sergey): For some unspeakable reason both GCC-6 and Clang-3.9 are
- * causing stack overflow issue in this function unless it is inlined.
- *
- * Only happens for AVX2 kernel and global __KERNEL_SSE__ vectorization
- * enabled.
- */
+ }
+
+ static ccl_always_inline float4 interp(const TextureInfo &info, float x, float y)
+ {
+ if (UNLIKELY(!info.data)) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ switch (info.interpolation) {
+ case INTERPOLATION_CLOSEST:
+ return interp_closest(info, x, y);
+ case INTERPOLATION_LINEAR:
+ return interp_linear(info, x, y);
+ default:
+ return interp_cubic(info, x, y);
+ }
+ }
+
+ /* ******** 3D interpolation ******** */
+
+ static ccl_always_inline float4 interp_3d_closest(const TextureInfo &info,
+ float x,
+ float y,
+ float z)
+ {
+ int width = info.width;
+ int height = info.height;
+ int depth = info.depth;
+ int ix, iy, iz;
+
+ frac(x * (float)width, &ix);
+ frac(y * (float)height, &iy);
+ frac(z * (float)depth, &iz);
+
+ switch (info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+ break;
+ case EXTENSION_CLIP:
+ if (x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ ATTR_FALLTHROUGH;
+ case EXTENSION_EXTEND:
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+
+ const T *data = (const T *)info.data;
+ return read(data[ix + iy * width + iz * width * height]);
+ }
+
+ static ccl_always_inline float4 interp_3d_linear(const TextureInfo &info,
+ float x,
+ float y,
+ float z)
+ {
+ int width = info.width;
+ int height = info.height;
+ int depth = info.depth;
+ int ix, iy, iz;
+ int nix, niy, niz;
+
+ float tx = frac(x * (float)width - 0.5f, &ix);
+ float ty = frac(y * (float)height - 0.5f, &iy);
+ float tz = frac(z * (float)depth - 0.5f, &iz);
+
+ switch (info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+
+ nix = wrap_periodic(ix + 1, width);
+ niy = wrap_periodic(iy + 1, height);
+ niz = wrap_periodic(iz + 1, depth);
+ break;
+ case EXTENSION_CLIP:
+ if (x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ ATTR_FALLTHROUGH;
+ case EXTENSION_EXTEND:
+ nix = wrap_clamp(ix + 1, width);
+ niy = wrap_clamp(iy + 1, height);
+ niz = wrap_clamp(iz + 1, depth);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+
+ const T *data = (const T *)info.data;
+ float4 r;
+
+ r = (1.0f - tz) * (1.0f - ty) * (1.0f - tx) *
+ read(data[ix + iy * width + iz * width * height]);
+ r += (1.0f - tz) * (1.0f - ty) * tx * read(data[nix + iy * width + iz * width * height]);
+ r += (1.0f - tz) * ty * (1.0f - tx) * read(data[ix + niy * width + iz * width * height]);
+ r += (1.0f - tz) * ty * tx * read(data[nix + niy * width + iz * width * height]);
+
+ r += tz * (1.0f - ty) * (1.0f - tx) * read(data[ix + iy * width + niz * width * height]);
+ r += tz * (1.0f - ty) * tx * read(data[nix + iy * width + niz * width * height]);
+ r += tz * ty * (1.0f - tx) * read(data[ix + niy * width + niz * width * height]);
+ r += tz * ty * tx * read(data[nix + niy * width + niz * width * height]);
+
+ return r;
+ }
+
+ /* TODO(sergey): For some unspeakable reason both GCC-6 and Clang-3.9 are
+ * causing stack overflow issue in this function unless it is inlined.
+ *
+ * Only happens for AVX2 kernel and global __KERNEL_SSE__ vectorization
+ * enabled.
+ */
#if defined(__GNUC__) || defined(__clang__)
- static ccl_always_inline
+ static ccl_always_inline
#else
- static ccl_never_inline
+ static ccl_never_inline
#endif
- float4 interp_3d_tricubic(const TextureInfo& info, float x, float y, float z)
- {
- int width = info.width;
- int height = info.height;
- int depth = info.depth;
- int ix, iy, iz;
- int nix, niy, niz;
- /* Tricubic b-spline interpolation. */
- const float tx = frac(x*(float)width - 0.5f, &ix);
- const float ty = frac(y*(float)height - 0.5f, &iy);
- const float tz = frac(z*(float)depth - 0.5f, &iz);
- int pix, piy, piz, nnix, nniy, nniz;
-
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- iz = wrap_periodic(iz, depth);
-
- pix = wrap_periodic(ix-1, width);
- piy = wrap_periodic(iy-1, height);
- piz = wrap_periodic(iz-1, depth);
-
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
- niz = wrap_periodic(iz+1, depth);
-
- nnix = wrap_periodic(ix+2, width);
- nniy = wrap_periodic(iy+2, height);
- nniz = wrap_periodic(iz+2, depth);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || z < 0.0f ||
- x > 1.0f || y > 1.0f || z > 1.0f)
- {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- ATTR_FALLTHROUGH;
- case EXTENSION_EXTEND:
- pix = wrap_clamp(ix-1, width);
- piy = wrap_clamp(iy-1, height);
- piz = wrap_clamp(iz-1, depth);
-
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
- niz = wrap_clamp(iz+1, depth);
-
- nnix = wrap_clamp(ix+2, width);
- nniy = wrap_clamp(iy+2, height);
- nniz = wrap_clamp(iz+2, depth);
-
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- const int xc[4] = {pix, ix, nix, nnix};
- const int yc[4] = {width * piy,
- width * iy,
- width * niy,
- width * nniy};
- const int zc[4] = {width * height * piz,
- width * height * iz,
- width * height * niz,
- width * height * nniz};
- float u[4], v[4], w[4];
-
- /* Some helper macro to keep code reasonable size,
- * let compiler to inline all the matrix multiplications.
- */
+ float4
+ interp_3d_tricubic(const TextureInfo &info, float x, float y, float z)
+ {
+ int width = info.width;
+ int height = info.height;
+ int depth = info.depth;
+ int ix, iy, iz;
+ int nix, niy, niz;
+ /* Tricubic b-spline interpolation. */
+ const float tx = frac(x * (float)width - 0.5f, &ix);
+ const float ty = frac(y * (float)height - 0.5f, &iy);
+ const float tz = frac(z * (float)depth - 0.5f, &iz);
+ int pix, piy, piz, nnix, nniy, nniz;
+
+ switch (info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+
+ pix = wrap_periodic(ix - 1, width);
+ piy = wrap_periodic(iy - 1, height);
+ piz = wrap_periodic(iz - 1, depth);
+
+ nix = wrap_periodic(ix + 1, width);
+ niy = wrap_periodic(iy + 1, height);
+ niz = wrap_periodic(iz + 1, depth);
+
+ nnix = wrap_periodic(ix + 2, width);
+ nniy = wrap_periodic(iy + 2, height);
+ nniz = wrap_periodic(iz + 2, depth);
+ break;
+ case EXTENSION_CLIP:
+ if (x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ ATTR_FALLTHROUGH;
+ case EXTENSION_EXTEND:
+ pix = wrap_clamp(ix - 1, width);
+ piy = wrap_clamp(iy - 1, height);
+ piz = wrap_clamp(iz - 1, depth);
+
+ nix = wrap_clamp(ix + 1, width);
+ niy = wrap_clamp(iy + 1, height);
+ niz = wrap_clamp(iz + 1, depth);
+
+ nnix = wrap_clamp(ix + 2, width);
+ nniy = wrap_clamp(iy + 2, height);
+ nniz = wrap_clamp(iz + 2, depth);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+
+ const int xc[4] = {pix, ix, nix, nnix};
+ const int yc[4] = {width * piy, width * iy, width * niy, width * nniy};
+ const int zc[4] = {
+ width * height * piz, width * height * iz, width * height * niz, width * height * nniz};
+ float u[4], v[4], w[4];
+
+ /* Some helper macro to keep code reasonable size,
+ * let compiler to inline all the matrix multiplications.
+ */
#define DATA(x, y, z) (read(data[xc[x] + yc[y] + zc[z]]))
#define COL_TERM(col, row) \
- (v[col] * (u[0] * DATA(0, col, row) + \
- u[1] * DATA(1, col, row) + \
- u[2] * DATA(2, col, row) + \
- u[3] * DATA(3, col, row)))
+ (v[col] * (u[0] * DATA(0, col, row) + u[1] * DATA(1, col, row) + u[2] * DATA(2, col, row) + \
+ u[3] * DATA(3, col, row)))
#define ROW_TERM(row) \
- (w[row] * (COL_TERM(0, row) + \
- COL_TERM(1, row) + \
- COL_TERM(2, row) + \
- COL_TERM(3, row)))
+ (w[row] * (COL_TERM(0, row) + COL_TERM(1, row) + COL_TERM(2, row) + COL_TERM(3, row)))
- SET_CUBIC_SPLINE_WEIGHTS(u, tx);
- SET_CUBIC_SPLINE_WEIGHTS(v, ty);
- SET_CUBIC_SPLINE_WEIGHTS(w, tz);
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+ SET_CUBIC_SPLINE_WEIGHTS(w, tz);
- /* Actual interpolation. */
- const T *data = (const T*)info.data;
- return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
+ /* Actual interpolation. */
+ const T *data = (const T *)info.data;
+ return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
#undef COL_TERM
#undef ROW_TERM
#undef DATA
- }
-
- static ccl_always_inline float4 interp_3d(const TextureInfo& info,
- float x, float y, float z,
- InterpolationType interp)
- {
- if(UNLIKELY(!info.data))
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-
- switch((interp == INTERPOLATION_NONE)? info.interpolation: interp) {
- case INTERPOLATION_CLOSEST:
- return interp_3d_closest(info, x, y, z);
- case INTERPOLATION_LINEAR:
- return interp_3d_linear(info, x, y, z);
- default:
- return interp_3d_tricubic(info, x, y, z);
- }
- }
+ }
+
+ static ccl_always_inline float4
+ interp_3d(const TextureInfo &info, float x, float y, float z, InterpolationType interp)
+ {
+ if (UNLIKELY(!info.data))
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ switch ((interp == INTERPOLATION_NONE) ? info.interpolation : interp) {
+ case INTERPOLATION_CLOSEST:
+ return interp_3d_closest(info, x, y, z);
+ case INTERPOLATION_LINEAR:
+ return interp_3d_linear(info, x, y, z);
+ default:
+ return interp_3d_tricubic(info, x, y, z);
+ }
+ }
#undef SET_CUBIC_SPLINE_WEIGHTS
};
ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
{
- const TextureInfo& info = kernel_tex_fetch(__texture_info, id);
-
- switch(kernel_tex_type(id)) {
- case IMAGE_DATA_TYPE_HALF:
- return TextureInterpolator<half>::interp(info, x, y);
- case IMAGE_DATA_TYPE_BYTE:
- return TextureInterpolator<uchar>::interp(info, x, y);
- case IMAGE_DATA_TYPE_USHORT:
- return TextureInterpolator<uint16_t>::interp(info, x, y);
- case IMAGE_DATA_TYPE_FLOAT:
- return TextureInterpolator<float>::interp(info, x, y);
- case IMAGE_DATA_TYPE_HALF4:
- return TextureInterpolator<half4>::interp(info, x, y);
- case IMAGE_DATA_TYPE_BYTE4:
- return TextureInterpolator<uchar4>::interp(info, x, y);
- case IMAGE_DATA_TYPE_USHORT4:
- return TextureInterpolator<ushort4>::interp(info, x, y);
- case IMAGE_DATA_TYPE_FLOAT4:
- return TextureInterpolator<float4>::interp(info, x, y);
- default:
- assert(0);
- return make_float4(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
- }
+ const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+
+ switch (kernel_tex_type(id)) {
+ case IMAGE_DATA_TYPE_HALF:
+ return TextureInterpolator<half>::interp(info, x, y);
+ case IMAGE_DATA_TYPE_BYTE:
+ return TextureInterpolator<uchar>::interp(info, x, y);
+ case IMAGE_DATA_TYPE_USHORT:
+ return TextureInterpolator<uint16_t>::interp(info, x, y);
+ case IMAGE_DATA_TYPE_FLOAT:
+ return TextureInterpolator<float>::interp(info, x, y);
+ case IMAGE_DATA_TYPE_HALF4:
+ return TextureInterpolator<half4>::interp(info, x, y);
+ case IMAGE_DATA_TYPE_BYTE4:
+ return TextureInterpolator<uchar4>::interp(info, x, y);
+ case IMAGE_DATA_TYPE_USHORT4:
+ return TextureInterpolator<ushort4>::interp(info, x, y);
+ case IMAGE_DATA_TYPE_FLOAT4:
+ return TextureInterpolator<float4>::interp(info, x, y);
+ default:
+ assert(0);
+ return make_float4(
+ TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
+ }
}
-ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
+ccl_device float4 kernel_tex_image_interp_3d(
+ KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
{
- const TextureInfo& info = kernel_tex_fetch(__texture_info, id);
-
- switch(kernel_tex_type(id)) {
- case IMAGE_DATA_TYPE_HALF:
- return TextureInterpolator<half>::interp_3d(info, x, y, z, interp);
- case IMAGE_DATA_TYPE_BYTE:
- return TextureInterpolator<uchar>::interp_3d(info, x, y, z, interp);
- case IMAGE_DATA_TYPE_USHORT:
- return TextureInterpolator<uint16_t>::interp_3d(info, x, y, z, interp);
- case IMAGE_DATA_TYPE_FLOAT:
- return TextureInterpolator<float>::interp_3d(info, x, y, z, interp);
- case IMAGE_DATA_TYPE_HALF4:
- return TextureInterpolator<half4>::interp_3d(info, x, y, z, interp);
- case IMAGE_DATA_TYPE_BYTE4:
- return TextureInterpolator<uchar4>::interp_3d(info, x, y, z, interp);
- case IMAGE_DATA_TYPE_USHORT4:
- return TextureInterpolator<ushort4>::interp_3d(info, x, y, z, interp);
- case IMAGE_DATA_TYPE_FLOAT4:
- return TextureInterpolator<float4>::interp_3d(info, x, y, z, interp);
- default:
- assert(0);
- return make_float4(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
- }
+ const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+
+ switch (kernel_tex_type(id)) {
+ case IMAGE_DATA_TYPE_HALF:
+ return TextureInterpolator<half>::interp_3d(info, x, y, z, interp);
+ case IMAGE_DATA_TYPE_BYTE:
+ return TextureInterpolator<uchar>::interp_3d(info, x, y, z, interp);
+ case IMAGE_DATA_TYPE_USHORT:
+ return TextureInterpolator<uint16_t>::interp_3d(info, x, y, z, interp);
+ case IMAGE_DATA_TYPE_FLOAT:
+ return TextureInterpolator<float>::interp_3d(info, x, y, z, interp);
+ case IMAGE_DATA_TYPE_HALF4:
+ return TextureInterpolator<half4>::interp_3d(info, x, y, z, interp);
+ case IMAGE_DATA_TYPE_BYTE4:
+ return TextureInterpolator<uchar4>::interp_3d(info, x, y, z, interp);
+ case IMAGE_DATA_TYPE_USHORT4:
+ return TextureInterpolator<ushort4>::interp_3d(info, x, y, z, interp);
+ case IMAGE_DATA_TYPE_FLOAT4:
+ return TextureInterpolator<float4>::interp_3d(info, x, y, z, interp);
+ default:
+ assert(0);
+ return make_float4(
+ TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
index 759b7e4c20d..9ca3f46b5b6 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
@@ -58,14 +58,15 @@
# include "kernel/split/kernel_next_iteration_setup.h"
# include "kernel/split/kernel_indirect_subsurface.h"
# include "kernel/split/kernel_buffer_update.h"
-# endif /* __SPLIT_KERNEL__ */
+# endif /* __SPLIT_KERNEL__ */
#else
-# define STUB_ASSERT(arch, name) assert(!(#name " kernel stub for architecture " #arch " was called!"))
+# define STUB_ASSERT(arch, name) \
+ assert(!(#name " kernel stub for architecture " #arch " was called!"))
# ifdef __SPLIT_KERNEL__
# include "kernel/split/kernel_data_init.h"
-# endif /* __SPLIT_KERNEL__ */
-#endif /* KERNEL_STUB */
+# endif /* __SPLIT_KERNEL__ */
+#endif /* KERNEL_STUB */
CCL_NAMESPACE_BEGIN
@@ -73,31 +74,22 @@ CCL_NAMESPACE_BEGIN
/* Path Tracing */
-void KERNEL_FUNCTION_FULL_NAME(path_trace)(KernelGlobals *kg,
- float *buffer,
- int sample,
- int x, int y,
- int offset,
- int stride)
+void KERNEL_FUNCTION_FULL_NAME(path_trace)(
+ KernelGlobals *kg, float *buffer, int sample, int x, int y, int offset, int stride)
{
-#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, path_trace);
-#else
-# ifdef __BRANCHED_PATH__
- if(kernel_data.integrator.branched) {
- kernel_branched_path_trace(kg,
- buffer,
- sample,
- x, y,
- offset,
- stride);
- }
- else
-# endif
- {
- kernel_path_trace(kg, buffer, sample, x, y, offset, stride);
- }
-#endif /* KERNEL_STUB */
+# ifdef KERNEL_STUB
+ STUB_ASSERT(KERNEL_ARCH, path_trace);
+# else
+# ifdef __BRANCHED_PATH__
+ if (kernel_data.integrator.branched) {
+ kernel_branched_path_trace(kg, buffer, sample, x, y, offset, stride);
+ }
+ else
+# endif
+ {
+ kernel_path_trace(kg, buffer, sample, x, y, offset, stride);
+ }
+# endif /* KERNEL_STUB */
}
/* Film */
@@ -106,42 +98,32 @@ void KERNEL_FUNCTION_FULL_NAME(convert_to_byte)(KernelGlobals *kg,
uchar4 *rgba,
float *buffer,
float sample_scale,
- int x, int y,
+ int x,
+ int y,
int offset,
int stride)
{
-#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, convert_to_byte);
-#else
- kernel_film_convert_to_byte(kg,
- rgba,
- buffer,
- sample_scale,
- x, y,
- offset,
- stride);
-#endif /* KERNEL_STUB */
+# ifdef KERNEL_STUB
+ STUB_ASSERT(KERNEL_ARCH, convert_to_byte);
+# else
+ kernel_film_convert_to_byte(kg, rgba, buffer, sample_scale, x, y, offset, stride);
+# endif /* KERNEL_STUB */
}
void KERNEL_FUNCTION_FULL_NAME(convert_to_half_float)(KernelGlobals *kg,
uchar4 *rgba,
float *buffer,
float sample_scale,
- int x, int y,
+ int x,
+ int y,
int offset,
int stride)
{
-#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, convert_to_half_float);
-#else
- kernel_film_convert_to_half_float(kg,
- rgba,
- buffer,
- sample_scale,
- x, y,
- offset,
- stride);
-#endif /* KERNEL_STUB */
+# ifdef KERNEL_STUB
+ STUB_ASSERT(KERNEL_ARCH, convert_to_half_float);
+# else
+ kernel_film_convert_to_half_float(kg, rgba, buffer, sample_scale, x, y, offset, stride);
+# endif /* KERNEL_STUB */
}
/* Shader Evaluate */
@@ -155,60 +137,53 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
int offset,
int sample)
{
-#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, shader);
-#else
- if(type >= SHADER_EVAL_BAKE) {
-# ifdef __BAKING__
- kernel_bake_evaluate(kg,
- input,
- output,
- (ShaderEvalType)type,
- filter,
- i,
- offset,
- sample);
-# endif
- }
- else if(type == SHADER_EVAL_DISPLACE) {
- kernel_displace_evaluate(kg, input, output, i);
- }
- else {
- kernel_background_evaluate(kg, input, output, i);
- }
-#endif /* KERNEL_STUB */
+# ifdef KERNEL_STUB
+ STUB_ASSERT(KERNEL_ARCH, shader);
+# else
+ if (type >= SHADER_EVAL_BAKE) {
+# ifdef __BAKING__
+ kernel_bake_evaluate(kg, input, output, (ShaderEvalType)type, filter, i, offset, sample);
+# endif
+ }
+ else if (type == SHADER_EVAL_DISPLACE) {
+ kernel_displace_evaluate(kg, input, output, i);
+ }
+ else {
+ kernel_background_evaluate(kg, input, output, i);
+ }
+# endif /* KERNEL_STUB */
}
-#else /* __SPLIT_KERNEL__ */
+#else /* __SPLIT_KERNEL__ */
/* Split Kernel Path Tracing */
-#ifdef KERNEL_STUB
-# define DEFINE_SPLIT_KERNEL_FUNCTION(name) \
- void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals *kg, KernelData* /*data*/) \
- { \
- STUB_ASSERT(KERNEL_ARCH, name); \
- }
-
-# define DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(name, type) \
- void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals *kg, KernelData* /*data*/) \
- { \
- STUB_ASSERT(KERNEL_ARCH, name); \
- }
-#else
-# define DEFINE_SPLIT_KERNEL_FUNCTION(name) \
- void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals *kg, KernelData* /*data*/) \
- { \
- kernel_##name(kg); \
- }
-
-# define DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(name, type) \
- void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals *kg, KernelData* /*data*/) \
- { \
- ccl_local type locals; \
- kernel_##name(kg, &locals); \
- }
-#endif /* KERNEL_STUB */
+# ifdef KERNEL_STUB
+# define DEFINE_SPLIT_KERNEL_FUNCTION(name) \
+ void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals * kg, KernelData * /*data*/) \
+ { \
+ STUB_ASSERT(KERNEL_ARCH, name); \
+ }
+
+# define DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(name, type) \
+ void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals * kg, KernelData * /*data*/) \
+ { \
+ STUB_ASSERT(KERNEL_ARCH, name); \
+ }
+# else
+# define DEFINE_SPLIT_KERNEL_FUNCTION(name) \
+ void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals * kg, KernelData * /*data*/) \
+ { \
+ kernel_##name(kg); \
+ }
+
+# define DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(name, type) \
+ void KERNEL_FUNCTION_FULL_NAME(name)(KernelGlobals * kg, KernelData * /*data*/) \
+ { \
+ ccl_local type locals; \
+ kernel_##name(kg, &locals); \
+ }
+# endif /* KERNEL_STUB */
DEFINE_SPLIT_KERNEL_FUNCTION(path_init)
DEFINE_SPLIT_KERNEL_FUNCTION(scene_intersect)
@@ -219,7 +194,8 @@ DEFINE_SPLIT_KERNEL_FUNCTION(indirect_background)
DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(shader_setup, uint)
DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(shader_sort, ShaderSortLocals)
DEFINE_SPLIT_KERNEL_FUNCTION(shader_eval)
-DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(holdout_emission_blurring_pathtermination_ao, BackgroundAOLocals)
+DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(holdout_emission_blurring_pathtermination_ao,
+ BackgroundAOLocals)
DEFINE_SPLIT_KERNEL_FUNCTION(subsurface_scatter)
DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(direct_lighting, uint)
DEFINE_SPLIT_KERNEL_FUNCTION(shadow_blocked_ao)
@@ -228,7 +204,7 @@ DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(enqueue_inactive, uint)
DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(next_iteration_setup, uint)
DEFINE_SPLIT_KERNEL_FUNCTION(indirect_subsurface)
DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(buffer_update, uint)
-#endif /* __SPLIT_KERNEL__ */
+#endif /* __SPLIT_KERNEL__ */
#undef KERNEL_STUB
#undef STUB_ASSERT
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_split.cpp b/intern/cycles/kernel/kernels/cpu/kernel_split.cpp
index c5e199b0a69..989f5e5aaa8 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_split.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_split.cpp
@@ -54,7 +54,7 @@
/* quiet unused define warnings */
#if defined(__KERNEL_SSE2__)
- /* do nothing */
+/* do nothing */
#endif
#include "kernel/kernel.h"
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_split_avx.cpp b/intern/cycles/kernel/kernels/cpu/kernel_split_avx.cpp
index 6ba3425a343..1b2e2516751 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_split_avx.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_split_avx.cpp
@@ -34,7 +34,7 @@
# define __KERNEL_SSE41__
# define __KERNEL_AVX__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_avx
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_split_avx2.cpp b/intern/cycles/kernel/kernels/cpu/kernel_split_avx2.cpp
index 76b2d77ebb8..43b8bfbf864 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_split_avx2.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_split_avx2.cpp
@@ -35,7 +35,7 @@
# define __KERNEL_AVX__
# define __KERNEL_AVX2__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_avx2
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_split_sse2.cpp b/intern/cycles/kernel/kernels/cpu/kernel_split_sse2.cpp
index b468b6f44c8..9743789179d 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_split_sse2.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_split_sse2.cpp
@@ -29,7 +29,7 @@
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
# define __KERNEL_SSE2__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_sse2
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_split_sse3.cpp b/intern/cycles/kernel/kernels/cpu/kernel_split_sse3.cpp
index 3e5792d0b17..1bec7633500 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_split_sse3.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_split_sse3.cpp
@@ -31,7 +31,7 @@
# define __KERNEL_SSE3__
# define __KERNEL_SSSE3__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_sse3
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_split_sse41.cpp b/intern/cycles/kernel/kernels/cpu/kernel_split_sse41.cpp
index 3629f21cd29..c0efc2350e9 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_split_sse41.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_split_sse41.cpp
@@ -32,7 +32,7 @@
# define __KERNEL_SSSE3__
# define __KERNEL_SSE41__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_sse41
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_sse2.cpp b/intern/cycles/kernel/kernels/cpu/kernel_sse2.cpp
index 57530c88710..173be8e93ce 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_sse2.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_sse2.cpp
@@ -27,7 +27,7 @@
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
# define __KERNEL_SSE2__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_sse2
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_sse3.cpp b/intern/cycles/kernel/kernels/cpu/kernel_sse3.cpp
index c607753bc4b..31273fe3344 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_sse3.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_sse3.cpp
@@ -29,7 +29,7 @@
# define __KERNEL_SSE3__
# define __KERNEL_SSSE3__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_sse3
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_sse41.cpp b/intern/cycles/kernel/kernels/cpu/kernel_sse41.cpp
index a278554731c..1d020b7fee6 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_sse41.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel_sse41.cpp
@@ -30,7 +30,7 @@
# define __KERNEL_SSSE3__
# define __KERNEL_SSE41__
# endif
-#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 */
+#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 */
#include "kernel/kernel.h"
#define KERNEL_ARCH cpu_sse41
diff --git a/intern/cycles/kernel/kernels/cuda/kernel_config.h b/intern/cycles/kernel/kernels/cuda/kernel_config.h
index 6d41dc15785..d9f349837a8 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel_config.h
+++ b/intern/cycles/kernel/kernels/cuda/kernel_config.h
@@ -81,7 +81,6 @@
# define CUDA_KERNEL_MAX_REGISTERS 64
# define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 72
-
/* unknown architecture */
#else
# error "Unknown or unsupported CUDA architecture, can't determine launch bounds"
@@ -96,18 +95,19 @@
* given the maximum number of registers per thread. */
#define CUDA_LAUNCH_BOUNDS(threads_block_width, thread_num_registers) \
- __launch_bounds__( \
- threads_block_width*threads_block_width, \
- CUDA_MULTIPRESSOR_MAX_REGISTERS/(threads_block_width*threads_block_width*thread_num_registers) \
- )
+ __launch_bounds__(threads_block_width *threads_block_width, \
+ CUDA_MULTIPRESSOR_MAX_REGISTERS / \
+ (threads_block_width * threads_block_width * thread_num_registers))
/* sanity checks */
-#if CUDA_THREADS_BLOCK_WIDTH*CUDA_THREADS_BLOCK_WIDTH > CUDA_BLOCK_MAX_THREADS
+#if CUDA_THREADS_BLOCK_WIDTH * CUDA_THREADS_BLOCK_WIDTH > CUDA_BLOCK_MAX_THREADS
# error "Maximum number of threads per block exceeded"
#endif
-#if CUDA_MULTIPRESSOR_MAX_REGISTERS/(CUDA_THREADS_BLOCK_WIDTH*CUDA_THREADS_BLOCK_WIDTH*CUDA_KERNEL_MAX_REGISTERS) > CUDA_MULTIPROCESSOR_MAX_BLOCKS
+#if CUDA_MULTIPRESSOR_MAX_REGISTERS / \
+ (CUDA_THREADS_BLOCK_WIDTH * CUDA_THREADS_BLOCK_WIDTH * CUDA_KERNEL_MAX_REGISTERS) > \
+ CUDA_MULTIPROCESSOR_MAX_BLOCKS
# error "Maximum number of blocks per multiprocessor exceeded"
#endif
diff --git a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
index 37cfbbcb235..7c68f08ea10 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
+++ b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
@@ -17,174 +17,165 @@
/* w0, w1, w2, and w3 are the four cubic B-spline basis functions. */
ccl_device float cubic_w0(float a)
{
- return (1.0f/6.0f)*(a*(a*(-a + 3.0f) - 3.0f) + 1.0f);
+ return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f);
}
ccl_device float cubic_w1(float a)
{
- return (1.0f/6.0f)*(a*a*(3.0f*a - 6.0f) + 4.0f);
+ return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f);
}
ccl_device float cubic_w2(float a)
{
- return (1.0f/6.0f)*(a*(a*(-3.0f*a + 3.0f) + 3.0f) + 1.0f);
+ return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f);
}
ccl_device float cubic_w3(float a)
{
- return (1.0f/6.0f)*(a*a*a);
+ return (1.0f / 6.0f) * (a * a * a);
}
/* g0 and g1 are the two amplitude functions. */
ccl_device float cubic_g0(float a)
{
- return cubic_w0(a) + cubic_w1(a);
+ return cubic_w0(a) + cubic_w1(a);
}
ccl_device float cubic_g1(float a)
{
- return cubic_w2(a) + cubic_w3(a);
+ return cubic_w2(a) + cubic_w3(a);
}
/* h0 and h1 are the two offset functions */
ccl_device float cubic_h0(float a)
{
- /* Note +0.5 offset to compensate for CUDA linear filtering convention. */
- return -1.0f + cubic_w1(a) / (cubic_w0(a) + cubic_w1(a)) + 0.5f;
+ /* Note +0.5 offset to compensate for CUDA linear filtering convention. */
+ return -1.0f + cubic_w1(a) / (cubic_w0(a) + cubic_w1(a)) + 0.5f;
}
ccl_device float cubic_h1(float a)
{
- return 1.0f + cubic_w3(a) / (cubic_w2(a) + cubic_w3(a)) + 0.5f;
+ return 1.0f + cubic_w3(a) / (cubic_w2(a) + cubic_w3(a)) + 0.5f;
}
/* Fast bicubic texture lookup using 4 bilinear lookups, adapted from CUDA samples. */
template<typename T>
-ccl_device T kernel_tex_image_interp_bicubic(const TextureInfo& info, CUtexObject tex, float x, float y)
+ccl_device T
+kernel_tex_image_interp_bicubic(const TextureInfo &info, CUtexObject tex, float x, float y)
{
- x = (x * info.width) - 0.5f;
- y = (y * info.height) - 0.5f;
-
- float px = floor(x);
- float py = floor(y);
- float fx = x - px;
- float fy = y - py;
-
- float g0x = cubic_g0(fx);
- float g1x = cubic_g1(fx);
- float x0 = (px + cubic_h0(fx)) / info.width;
- float x1 = (px + cubic_h1(fx)) / info.width;
- float y0 = (py + cubic_h0(fy)) / info.height;
- float y1 = (py + cubic_h1(fy)) / info.height;
-
- return cubic_g0(fy) * (g0x * tex2D<T>(tex, x0, y0) +
- g1x * tex2D<T>(tex, x1, y0)) +
- cubic_g1(fy) * (g0x * tex2D<T>(tex, x0, y1) +
- g1x * tex2D<T>(tex, x1, y1));
+ x = (x * info.width) - 0.5f;
+ y = (y * info.height) - 0.5f;
+
+ float px = floor(x);
+ float py = floor(y);
+ float fx = x - px;
+ float fy = y - py;
+
+ float g0x = cubic_g0(fx);
+ float g1x = cubic_g1(fx);
+ float x0 = (px + cubic_h0(fx)) / info.width;
+ float x1 = (px + cubic_h1(fx)) / info.width;
+ float y0 = (py + cubic_h0(fy)) / info.height;
+ float y1 = (py + cubic_h1(fy)) / info.height;
+
+ return cubic_g0(fy) * (g0x * tex2D<T>(tex, x0, y0) + g1x * tex2D<T>(tex, x1, y0)) +
+ cubic_g1(fy) * (g0x * tex2D<T>(tex, x0, y1) + g1x * tex2D<T>(tex, x1, y1));
}
/* Fast tricubic texture lookup using 8 trilinear lookups. */
template<typename T>
-ccl_device T kernel_tex_image_interp_bicubic_3d(const TextureInfo& info, CUtexObject tex, float x, float y, float z)
+ccl_device T kernel_tex_image_interp_bicubic_3d(
+ const TextureInfo &info, CUtexObject tex, float x, float y, float z)
{
- x = (x * info.width) - 0.5f;
- y = (y * info.height) - 0.5f;
- z = (z * info.depth) - 0.5f;
-
- float px = floor(x);
- float py = floor(y);
- float pz = floor(z);
- float fx = x - px;
- float fy = y - py;
- float fz = z - pz;
-
- float g0x = cubic_g0(fx);
- float g1x = cubic_g1(fx);
- float g0y = cubic_g0(fy);
- float g1y = cubic_g1(fy);
- float g0z = cubic_g0(fz);
- float g1z = cubic_g1(fz);
-
- float x0 = (px + cubic_h0(fx)) / info.width;
- float x1 = (px + cubic_h1(fx)) / info.width;
- float y0 = (py + cubic_h0(fy)) / info.height;
- float y1 = (py + cubic_h1(fy)) / info.height;
- float z0 = (pz + cubic_h0(fz)) / info.depth;
- float z1 = (pz + cubic_h1(fz)) / info.depth;
-
- return g0z * (g0y * (g0x * tex3D<T>(tex, x0, y0, z0) +
- g1x * tex3D<T>(tex, x1, y0, z0)) +
- g1y * (g0x * tex3D<T>(tex, x0, y1, z0) +
- g1x * tex3D<T>(tex, x1, y1, z0))) +
- g1z * (g0y * (g0x * tex3D<T>(tex, x0, y0, z1) +
- g1x * tex3D<T>(tex, x1, y0, z1)) +
- g1y * (g0x * tex3D<T>(tex, x0, y1, z1) +
- g1x * tex3D<T>(tex, x1, y1, z1)));
+ x = (x * info.width) - 0.5f;
+ y = (y * info.height) - 0.5f;
+ z = (z * info.depth) - 0.5f;
+
+ float px = floor(x);
+ float py = floor(y);
+ float pz = floor(z);
+ float fx = x - px;
+ float fy = y - py;
+ float fz = z - pz;
+
+ float g0x = cubic_g0(fx);
+ float g1x = cubic_g1(fx);
+ float g0y = cubic_g0(fy);
+ float g1y = cubic_g1(fy);
+ float g0z = cubic_g0(fz);
+ float g1z = cubic_g1(fz);
+
+ float x0 = (px + cubic_h0(fx)) / info.width;
+ float x1 = (px + cubic_h1(fx)) / info.width;
+ float y0 = (py + cubic_h0(fy)) / info.height;
+ float y1 = (py + cubic_h1(fy)) / info.height;
+ float z0 = (pz + cubic_h0(fz)) / info.depth;
+ float z1 = (pz + cubic_h1(fz)) / info.depth;
+
+ return g0z * (g0y * (g0x * tex3D<T>(tex, x0, y0, z0) + g1x * tex3D<T>(tex, x1, y0, z0)) +
+ g1y * (g0x * tex3D<T>(tex, x0, y1, z0) + g1x * tex3D<T>(tex, x1, y1, z0))) +
+ g1z * (g0y * (g0x * tex3D<T>(tex, x0, y0, z1) + g1x * tex3D<T>(tex, x1, y0, z1)) +
+ g1y * (g0x * tex3D<T>(tex, x0, y1, z1) + g1x * tex3D<T>(tex, x1, y1, z1)));
}
ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
{
- const TextureInfo& info = kernel_tex_fetch(__texture_info, id);
- CUtexObject tex = (CUtexObject)info.data;
-
- /* float4, byte4, ushort4 and half4 */
- const int texture_type = kernel_tex_type(id);
- if(texture_type == IMAGE_DATA_TYPE_FLOAT4 ||
- texture_type == IMAGE_DATA_TYPE_BYTE4 ||
- texture_type == IMAGE_DATA_TYPE_HALF4 ||
- texture_type == IMAGE_DATA_TYPE_USHORT4)
- {
- if(info.interpolation == INTERPOLATION_CUBIC) {
- return kernel_tex_image_interp_bicubic<float4>(info, tex, x, y);
- }
- else {
- return tex2D<float4>(tex, x, y);
- }
- }
- /* float, byte and half */
- else {
- float f;
-
- if(info.interpolation == INTERPOLATION_CUBIC) {
- f = kernel_tex_image_interp_bicubic<float>(info, tex, x, y);
- }
- else {
- f = tex2D<float>(tex, x, y);
- }
-
- return make_float4(f, f, f, 1.0f);
- }
+ const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+ CUtexObject tex = (CUtexObject)info.data;
+
+ /* float4, byte4, ushort4 and half4 */
+ const int texture_type = kernel_tex_type(id);
+ if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 ||
+ texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) {
+ if (info.interpolation == INTERPOLATION_CUBIC) {
+ return kernel_tex_image_interp_bicubic<float4>(info, tex, x, y);
+ }
+ else {
+ return tex2D<float4>(tex, x, y);
+ }
+ }
+ /* float, byte and half */
+ else {
+ float f;
+
+ if (info.interpolation == INTERPOLATION_CUBIC) {
+ f = kernel_tex_image_interp_bicubic<float>(info, tex, x, y);
+ }
+ else {
+ f = tex2D<float>(tex, x, y);
+ }
+
+ return make_float4(f, f, f, 1.0f);
+ }
}
-ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
+ccl_device float4 kernel_tex_image_interp_3d(
+ KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
{
- const TextureInfo& info = kernel_tex_fetch(__texture_info, id);
- CUtexObject tex = (CUtexObject)info.data;
- uint interpolation = (interp == INTERPOLATION_NONE)? info.interpolation: interp;
-
- const int texture_type = kernel_tex_type(id);
- if(texture_type == IMAGE_DATA_TYPE_FLOAT4 ||
- texture_type == IMAGE_DATA_TYPE_BYTE4 ||
- texture_type == IMAGE_DATA_TYPE_HALF4 ||
- texture_type == IMAGE_DATA_TYPE_USHORT4)
- {
- if(interpolation == INTERPOLATION_CUBIC) {
- return kernel_tex_image_interp_bicubic_3d<float4>(info, tex, x, y, z);
- }
- else {
- return tex3D<float4>(tex, x, y, z);
- }
- }
- else {
- float f;
-
- if(interpolation == INTERPOLATION_CUBIC) {
- f = kernel_tex_image_interp_bicubic_3d<float>(info, tex, x, y, z);
- }
- else {
- f = tex3D<float>(tex, x, y, z);
- }
-
- return make_float4(f, f, f, 1.0f);
- }
+ const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+ CUtexObject tex = (CUtexObject)info.data;
+ uint interpolation = (interp == INTERPOLATION_NONE) ? info.interpolation : interp;
+
+ const int texture_type = kernel_tex_type(id);
+ if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 ||
+ texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) {
+ if (interpolation == INTERPOLATION_CUBIC) {
+ return kernel_tex_image_interp_bicubic_3d<float4>(info, tex, x, y, z);
+ }
+ else {
+ return tex3D<float4>(tex, x, y, z);
+ }
+ }
+ else {
+ float f;
+
+ if (interpolation == INTERPOLATION_CUBIC) {
+ f = kernel_tex_image_interp_bicubic_3d<float>(info, tex, x, y, z);
+ }
+ else {
+ f = tex3D<float>(tex, x, y, z);
+ }
+
+ return make_float4(f, f, f, 1.0f);
+ }
}
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
index 79af831c2fb..b6390679331 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
@@ -16,254 +16,257 @@
/* For OpenCL we do manual lookup and interpolation. */
-ccl_device_inline ccl_global TextureInfo* kernel_tex_info(KernelGlobals *kg, uint id) {
- const uint tex_offset = id
-#define KERNEL_TEX(type, name) + 1
+ccl_device_inline ccl_global TextureInfo *kernel_tex_info(KernelGlobals *kg, uint id)
+{
+ const uint tex_offset = id
+#define KERNEL_TEX(type, name) +1
#include "kernel/kernel_textures.h"
- ;
+ ;
- return &((ccl_global TextureInfo*)kg->buffers[0])[tex_offset];
+ return &((ccl_global TextureInfo *)kg->buffers[0])[tex_offset];
}
-#define tex_fetch(type, info, index) ((ccl_global type*)(kg->buffers[info->cl_buffer] + info->data))[(index)]
+#define tex_fetch(type, info, index) \
+ ((ccl_global type *)(kg->buffers[info->cl_buffer] + info->data))[(index)]
ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
{
- x %= width;
- if(x < 0)
- x += width;
- return x;
+ x %= width;
+ if (x < 0)
+ x += width;
+ return x;
}
ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
{
- return clamp(x, 0, width-1);
+ return clamp(x, 0, width - 1);
}
-ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, const ccl_global TextureInfo *info, int id, int offset)
+ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg,
+ const ccl_global TextureInfo *info,
+ int id,
+ int offset)
{
- const int texture_type = kernel_tex_type(id);
-
- /* Float4 */
- if(texture_type == IMAGE_DATA_TYPE_FLOAT4) {
- return tex_fetch(float4, info, offset);
- }
- /* Byte4 */
- else if(texture_type == IMAGE_DATA_TYPE_BYTE4) {
- uchar4 r = tex_fetch(uchar4, info, offset);
- float f = 1.0f/255.0f;
- return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
- }
- /* Ushort4 */
- else if(texture_type == IMAGE_DATA_TYPE_USHORT4) {
- ushort4 r = tex_fetch(ushort4, info, offset);
- float f = 1.0f/65535.f;
- return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
- }
- /* Float */
- else if(texture_type == IMAGE_DATA_TYPE_FLOAT) {
- float f = tex_fetch(float, info, offset);
- return make_float4(f, f, f, 1.0f);
- }
- /* UShort */
- else if(texture_type == IMAGE_DATA_TYPE_USHORT) {
- ushort r = tex_fetch(ushort, info, offset);
- float f = r * (1.0f / 65535.0f);
- return make_float4(f, f, f, 1.0f);
- }
- /* Byte */
+ const int texture_type = kernel_tex_type(id);
+
+ /* Float4 */
+ if (texture_type == IMAGE_DATA_TYPE_FLOAT4) {
+ return tex_fetch(float4, info, offset);
+ }
+ /* Byte4 */
+ else if (texture_type == IMAGE_DATA_TYPE_BYTE4) {
+ uchar4 r = tex_fetch(uchar4, info, offset);
+ float f = 1.0f / 255.0f;
+ return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
+ }
+ /* Ushort4 */
+ else if (texture_type == IMAGE_DATA_TYPE_USHORT4) {
+ ushort4 r = tex_fetch(ushort4, info, offset);
+ float f = 1.0f / 65535.f;
+ return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
+ }
+ /* Float */
+ else if (texture_type == IMAGE_DATA_TYPE_FLOAT) {
+ float f = tex_fetch(float, info, offset);
+ return make_float4(f, f, f, 1.0f);
+ }
+ /* UShort */
+ else if (texture_type == IMAGE_DATA_TYPE_USHORT) {
+ ushort r = tex_fetch(ushort, info, offset);
+ float f = r * (1.0f / 65535.0f);
+ return make_float4(f, f, f, 1.0f);
+ }
+ /* Byte */
#ifdef cl_khr_fp16
- /* half and half4 are optional in OpenCL */
- else if(texture_type == IMAGE_DATA_TYPE_HALF) {
- float f = tex_fetch(half, info, offset);
- return make_float4(f, f, f, 1.0f);
- }
- else if(texture_type == IMAGE_DATA_TYPE_HALF4) {
- half4 r = tex_fetch(half4, info, offset);
- return make_float4(r.x, r.y, r.z, r.w);
- }
+ /* half and half4 are optional in OpenCL */
+ else if (texture_type == IMAGE_DATA_TYPE_HALF) {
+ float f = tex_fetch(half, info, offset);
+ return make_float4(f, f, f, 1.0f);
+ }
+ else if (texture_type == IMAGE_DATA_TYPE_HALF4) {
+ half4 r = tex_fetch(half4, info, offset);
+ return make_float4(r.x, r.y, r.z, r.w);
+ }
#endif
- else {
- uchar r = tex_fetch(uchar, info, offset);
- float f = r * (1.0f/255.0f);
- return make_float4(f, f, f, 1.0f);
- }
+ else {
+ uchar r = tex_fetch(uchar, info, offset);
+ float f = r * (1.0f / 255.0f);
+ return make_float4(f, f, f, 1.0f);
+ }
}
ccl_device_inline float4 svm_image_texture_read_2d(KernelGlobals *kg, int id, int x, int y)
{
- const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
-
- /* Wrap */
- if(info->extension == EXTENSION_REPEAT) {
- x = svm_image_texture_wrap_periodic(x, info->width);
- y = svm_image_texture_wrap_periodic(y, info->height);
- }
- else {
- x = svm_image_texture_wrap_clamp(x, info->width);
- y = svm_image_texture_wrap_clamp(y, info->height);
- }
-
- int offset = x + info->width * y;
- return svm_image_texture_read(kg, info, id, offset);
+ const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
+
+ /* Wrap */
+ if (info->extension == EXTENSION_REPEAT) {
+ x = svm_image_texture_wrap_periodic(x, info->width);
+ y = svm_image_texture_wrap_periodic(y, info->height);
+ }
+ else {
+ x = svm_image_texture_wrap_clamp(x, info->width);
+ y = svm_image_texture_wrap_clamp(y, info->height);
+ }
+
+ int offset = x + info->width * y;
+ return svm_image_texture_read(kg, info, id, offset);
}
ccl_device_inline float4 svm_image_texture_read_3d(KernelGlobals *kg, int id, int x, int y, int z)
{
- const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
-
- /* Wrap */
- if(info->extension == EXTENSION_REPEAT) {
- x = svm_image_texture_wrap_periodic(x, info->width);
- y = svm_image_texture_wrap_periodic(y, info->height);
- z = svm_image_texture_wrap_periodic(z, info->depth);
- }
- else {
- x = svm_image_texture_wrap_clamp(x, info->width);
- y = svm_image_texture_wrap_clamp(y, info->height);
- z = svm_image_texture_wrap_clamp(z, info->depth);
- }
-
- int offset = x + info->width * y + info->width * info->height * z;
- return svm_image_texture_read(kg, info, id, offset);
+ const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
+
+ /* Wrap */
+ if (info->extension == EXTENSION_REPEAT) {
+ x = svm_image_texture_wrap_periodic(x, info->width);
+ y = svm_image_texture_wrap_periodic(y, info->height);
+ z = svm_image_texture_wrap_periodic(z, info->depth);
+ }
+ else {
+ x = svm_image_texture_wrap_clamp(x, info->width);
+ y = svm_image_texture_wrap_clamp(y, info->height);
+ z = svm_image_texture_wrap_clamp(z, info->depth);
+ }
+
+ int offset = x + info->width * y + info->width * info->height * z;
+ return svm_image_texture_read(kg, info, id, offset);
}
-
ccl_device_inline float svm_image_texture_frac(float x, int *ix)
{
- int i = float_to_int(x) - ((x < 0.0f)? 1: 0);
- *ix = i;
- return x - (float)i;
+ int i = float_to_int(x) - ((x < 0.0f) ? 1 : 0);
+ *ix = i;
+ return x - (float)i;
}
#define SET_CUBIC_SPLINE_WEIGHTS(u, t) \
- { \
- u[0] = (((-1.0f/6.0f)* t + 0.5f) * t - 0.5f) * t + (1.0f/6.0f); \
- u[1] = (( 0.5f * t - 1.0f) * t ) * t + (2.0f/3.0f); \
- u[2] = (( -0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f/6.0f); \
- u[3] = (1.0f / 6.0f) * t * t * t; \
- } (void) 0
+ { \
+ u[0] = (((-1.0f / 6.0f) * t + 0.5f) * t - 0.5f) * t + (1.0f / 6.0f); \
+ u[1] = ((0.5f * t - 1.0f) * t) * t + (2.0f / 3.0f); \
+ u[2] = ((-0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f / 6.0f); \
+ u[3] = (1.0f / 6.0f) * t * t * t; \
+ } \
+ (void)0
ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
{
- const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
-
- if(info->extension == EXTENSION_CLIP) {
- if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- }
-
- if(info->interpolation == INTERPOLATION_CLOSEST) {
- /* Closest interpolation. */
- int ix, iy;
- svm_image_texture_frac(x*info->width, &ix);
- svm_image_texture_frac(y*info->height, &iy);
-
- return svm_image_texture_read_2d(kg, id, ix, iy);
- }
- else if(info->interpolation == INTERPOLATION_LINEAR) {
- /* Bilinear interpolation. */
- int ix, iy;
- float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
- float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
-
- float4 r;
- r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read_2d(kg, id, ix, iy);
- r += (1.0f - ty)*tx*svm_image_texture_read_2d(kg, id, ix+1, iy);
- r += ty*(1.0f - tx)*svm_image_texture_read_2d(kg, id, ix, iy+1);
- r += ty*tx*svm_image_texture_read_2d(kg, id, ix+1, iy+1);
- return r;
- }
- else {
- /* Bicubic interpolation. */
- int ix, iy;
- float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
- float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
-
- float u[4], v[4];
- SET_CUBIC_SPLINE_WEIGHTS(u, tx);
- SET_CUBIC_SPLINE_WEIGHTS(v, ty);
-
- float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-
- for(int y = 0; y < 4; y++) {
- for(int x = 0; x < 4; x++) {
- float weight = u[x]*v[y];
- r += weight*svm_image_texture_read_2d(kg, id, ix+x-1, iy+y-1);
- }
- }
- return r;
- }
+ const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
+
+ if (info->extension == EXTENSION_CLIP) {
+ if (x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ if (info->interpolation == INTERPOLATION_CLOSEST) {
+ /* Closest interpolation. */
+ int ix, iy;
+ svm_image_texture_frac(x * info->width, &ix);
+ svm_image_texture_frac(y * info->height, &iy);
+
+ return svm_image_texture_read_2d(kg, id, ix, iy);
+ }
+ else if (info->interpolation == INTERPOLATION_LINEAR) {
+ /* Bilinear interpolation. */
+ int ix, iy;
+ float tx = svm_image_texture_frac(x * info->width - 0.5f, &ix);
+ float ty = svm_image_texture_frac(y * info->height - 0.5f, &iy);
+
+ float4 r;
+ r = (1.0f - ty) * (1.0f - tx) * svm_image_texture_read_2d(kg, id, ix, iy);
+ r += (1.0f - ty) * tx * svm_image_texture_read_2d(kg, id, ix + 1, iy);
+ r += ty * (1.0f - tx) * svm_image_texture_read_2d(kg, id, ix, iy + 1);
+ r += ty * tx * svm_image_texture_read_2d(kg, id, ix + 1, iy + 1);
+ return r;
+ }
+ else {
+ /* Bicubic interpolation. */
+ int ix, iy;
+ float tx = svm_image_texture_frac(x * info->width - 0.5f, &ix);
+ float ty = svm_image_texture_frac(y * info->height - 0.5f, &iy);
+
+ float u[4], v[4];
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+
+ float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ for (int y = 0; y < 4; y++) {
+ for (int x = 0; x < 4; x++) {
+ float weight = u[x] * v[y];
+ r += weight * svm_image_texture_read_2d(kg, id, ix + x - 1, iy + y - 1);
+ }
+ }
+ return r;
+ }
}
-
-ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z, int interp)
+ccl_device float4
+kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z, int interp)
{
- const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
-
- if(info->extension == EXTENSION_CLIP) {
- if(x < 0.0f || y < 0.0f || z < 0.0f ||
- x > 1.0f || y > 1.0f || z > 1.0f)
- {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- }
-
- uint interpolation = (interp == INTERPOLATION_NONE)? info->interpolation: interp;
-
- if(interpolation == INTERPOLATION_CLOSEST) {
- /* Closest interpolation. */
- int ix, iy, iz;
- svm_image_texture_frac(x*info->width, &ix);
- svm_image_texture_frac(y*info->height, &iy);
- svm_image_texture_frac(z*info->depth, &iz);
-
- return svm_image_texture_read_3d(kg, id, ix, iy, iz);
- }
- else if(interpolation == INTERPOLATION_LINEAR) {
- /* Bilinear interpolation. */
- int ix, iy, iz;
- float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
- float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
- float tz = svm_image_texture_frac(z*info->depth - 0.5f, &iz);
-
- float4 r;
- r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy, iz);
- r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read_3d(kg, id, ix+1, iy, iz);
- r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy+1, iz);
- r += (1.0f - tz)*ty*tx*svm_image_texture_read_3d(kg, id, ix+1, iy+1, iz);
-
- r += tz*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy, iz+1);
- r += tz*(1.0f - ty)*tx*svm_image_texture_read_3d(kg, id, ix+1, iy, iz+1);
- r += tz*ty*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy+1, iz+1);
- r += tz*ty*tx*svm_image_texture_read_3d(kg, id, ix+1, iy+1, iz+1);
- return r;
- }
- else {
- /* Bicubic interpolation. */
- int ix, iy, iz;
- float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
- float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
- float tz = svm_image_texture_frac(z*info->depth - 0.5f, &iz);
-
- float u[4], v[4], w[4];
- SET_CUBIC_SPLINE_WEIGHTS(u, tx);
- SET_CUBIC_SPLINE_WEIGHTS(v, ty);
- SET_CUBIC_SPLINE_WEIGHTS(w, tz);
-
- float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-
- for(int z = 0; z < 4; z++) {
- for(int y = 0; y < 4; y++) {
- for(int x = 0; x < 4; x++) {
- float weight = u[x]*v[y]*w[z];
- r += weight*svm_image_texture_read_3d(kg, id, ix+x-1, iy+y-1, iz+z-1);
- }
- }
- }
- return r;
- }
+ const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
+
+ if (info->extension == EXTENSION_CLIP) {
+ if (x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ uint interpolation = (interp == INTERPOLATION_NONE) ? info->interpolation : interp;
+
+ if (interpolation == INTERPOLATION_CLOSEST) {
+ /* Closest interpolation. */
+ int ix, iy, iz;
+ svm_image_texture_frac(x * info->width, &ix);
+ svm_image_texture_frac(y * info->height, &iy);
+ svm_image_texture_frac(z * info->depth, &iz);
+
+ return svm_image_texture_read_3d(kg, id, ix, iy, iz);
+ }
+ else if (interpolation == INTERPOLATION_LINEAR) {
+ /* Bilinear interpolation. */
+ int ix, iy, iz;
+ float tx = svm_image_texture_frac(x * info->width - 0.5f, &ix);
+ float ty = svm_image_texture_frac(y * info->height - 0.5f, &iy);
+ float tz = svm_image_texture_frac(z * info->depth - 0.5f, &iz);
+
+ float4 r;
+ r = (1.0f - tz) * (1.0f - ty) * (1.0f - tx) * svm_image_texture_read_3d(kg, id, ix, iy, iz);
+ r += (1.0f - tz) * (1.0f - ty) * tx * svm_image_texture_read_3d(kg, id, ix + 1, iy, iz);
+ r += (1.0f - tz) * ty * (1.0f - tx) * svm_image_texture_read_3d(kg, id, ix, iy + 1, iz);
+ r += (1.0f - tz) * ty * tx * svm_image_texture_read_3d(kg, id, ix + 1, iy + 1, iz);
+
+ r += tz * (1.0f - ty) * (1.0f - tx) * svm_image_texture_read_3d(kg, id, ix, iy, iz + 1);
+ r += tz * (1.0f - ty) * tx * svm_image_texture_read_3d(kg, id, ix + 1, iy, iz + 1);
+ r += tz * ty * (1.0f - tx) * svm_image_texture_read_3d(kg, id, ix, iy + 1, iz + 1);
+ r += tz * ty * tx * svm_image_texture_read_3d(kg, id, ix + 1, iy + 1, iz + 1);
+ return r;
+ }
+ else {
+ /* Bicubic interpolation. */
+ int ix, iy, iz;
+ float tx = svm_image_texture_frac(x * info->width - 0.5f, &ix);
+ float ty = svm_image_texture_frac(y * info->height - 0.5f, &iy);
+ float tz = svm_image_texture_frac(z * info->depth - 0.5f, &iz);
+
+ float u[4], v[4], w[4];
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+ SET_CUBIC_SPLINE_WEIGHTS(w, tz);
+
+ float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ for (int z = 0; z < 4; z++) {
+ for (int y = 0; y < 4; y++) {
+ for (int x = 0; x < 4; x++) {
+ float weight = u[x] * v[y] * w[z];
+ r += weight * svm_image_texture_read_3d(kg, id, ix + x - 1, iy + y - 1, iz + z - 1);
+ }
+ }
+ }
+ return r;
+ }
}
#undef SET_CUBIC_SPLINE_WEIGHTS
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_split_function.h b/intern/cycles/kernel/kernels/opencl/kernel_split_function.h
index 05e1ddf6da2..e123b4cd6ec 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_split_function.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_split_function.h
@@ -14,50 +14,53 @@
* limitations under the License.
*/
-#define KERNEL_NAME_JOIN(a, b) a ## _ ## b
+#define KERNEL_NAME_JOIN(a, b) a##_##b
#define KERNEL_NAME_EVAL(a, b) KERNEL_NAME_JOIN(a, b)
-__kernel void KERNEL_NAME_EVAL(kernel_ocl_path_trace, KERNEL_NAME)(
- ccl_global char *kg_global,
- ccl_constant KernelData *data,
+__kernel void KERNEL_NAME_EVAL(kernel_ocl_path_trace,
+ KERNEL_NAME)(ccl_global char *kg_global,
+ ccl_constant KernelData *data,
- ccl_global void *split_data_buffer,
- ccl_global char *ray_state,
+ ccl_global void *split_data_buffer,
+ ccl_global char *ray_state,
- KERNEL_BUFFER_PARAMS,
+ KERNEL_BUFFER_PARAMS,
- ccl_global int *queue_index,
- ccl_global char *use_queues_flag,
- ccl_global unsigned int *work_pools,
- ccl_global float *buffer
- )
+ ccl_global int *queue_index,
+ ccl_global char *use_queues_flag,
+ ccl_global unsigned int *work_pools,
+ ccl_global float *buffer)
{
#ifdef LOCALS_TYPE
- ccl_local LOCALS_TYPE locals;
+ ccl_local LOCALS_TYPE locals;
#endif
- KernelGlobals *kg = (KernelGlobals*)kg_global;
+ KernelGlobals *kg = (KernelGlobals *)kg_global;
- if(ccl_local_id(0) + ccl_local_id(1) == 0) {
- kg->data = data;
+ if (ccl_local_id(0) + ccl_local_id(1) == 0) {
+ kg->data = data;
- kernel_split_params.queue_index = queue_index;
- kernel_split_params.use_queues_flag = use_queues_flag;
- kernel_split_params.work_pools = work_pools;
- kernel_split_params.tile.buffer = buffer;
+ kernel_split_params.queue_index = queue_index;
+ kernel_split_params.use_queues_flag = use_queues_flag;
+ kernel_split_params.work_pools = work_pools;
+ kernel_split_params.tile.buffer = buffer;
- split_data_init(kg, &kernel_split_state, ccl_global_size(0)*ccl_global_size(1), split_data_buffer, ray_state);
+ split_data_init(kg,
+ &kernel_split_state,
+ ccl_global_size(0) * ccl_global_size(1),
+ split_data_buffer,
+ ray_state);
+ }
- }
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
- kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
-
- KERNEL_NAME_EVAL(kernel, KERNEL_NAME)(
- kg
+ KERNEL_NAME_EVAL(kernel, KERNEL_NAME)
+ (kg
#ifdef LOCALS_TYPE
- , &locals
+ ,
+ &locals
#endif
- );
+ );
}
#undef KERNEL_NAME_JOIN
diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt
index 0a3d0b974cb..28d9ca854db 100644
--- a/intern/cycles/kernel/osl/CMakeLists.txt
+++ b/intern/cycles/kernel/osl/CMakeLists.txt
@@ -1,6 +1,6 @@
set(INC
- ../..
+ ../..
)
set(INC_SYS
@@ -8,25 +8,25 @@ set(INC_SYS
)
set(SRC
- background.cpp
- bsdf_diffuse_ramp.cpp
- bsdf_phong_ramp.cpp
- emissive.cpp
- osl_bssrdf.cpp
- osl_closures.cpp
- osl_services.cpp
- osl_shader.cpp
+ background.cpp
+ bsdf_diffuse_ramp.cpp
+ bsdf_phong_ramp.cpp
+ emissive.cpp
+ osl_bssrdf.cpp
+ osl_closures.cpp
+ osl_services.cpp
+ osl_shader.cpp
)
set(HEADER_SRC
- osl_closures.h
- osl_globals.h
- osl_services.h
- osl_shader.h
+ osl_closures.h
+ osl_globals.h
+ osl_services.h
+ osl_shader.h
)
set(LIB
- cycles_render
+ cycles_render
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp
index 6924a4144c5..b395227845d 100644
--- a/intern/cycles/kernel/osl/background.cpp
+++ b/intern/cycles/kernel/osl/background.cpp
@@ -51,11 +51,11 @@ using namespace OSL;
/// only the weight is taking into account
///
class GenericBackgroundClosure : public CClosurePrimitive {
-public:
- void setup(ShaderData *sd, int /* path_flag */, float3 weight)
- {
- background_setup(sd, weight);
- }
+ public:
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
+ {
+ background_setup(sd, weight);
+ }
};
/// Holdout closure
@@ -66,31 +66,28 @@ public:
/// used
///
class HoldoutClosure : CClosurePrimitive {
-public:
- void setup(ShaderData *sd, int /* path_flag */, float3 weight)
- {
- closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, weight);
- sd->flag |= SD_HOLDOUT;
- }
+ public:
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
+ {
+ closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, weight);
+ sd->flag |= SD_HOLDOUT;
+ }
};
ClosureParam *closure_background_params()
{
- static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"),
- CLOSURE_FINISH_PARAM(GenericBackgroundClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(GenericBackgroundClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure)
ClosureParam *closure_holdout_params()
{
- static ClosureParam params[] = {
- CLOSURE_FINISH_PARAM(HoldoutClosure)
- };
- return params;
+ static ClosureParam params[] = {CLOSURE_FINISH_PARAM(HoldoutClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure)
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
index ed5d5235a34..c5edc7c9be3 100644
--- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
@@ -47,36 +47,35 @@ CCL_NAMESPACE_BEGIN
using namespace OSL;
class DiffuseRampClosure : public CBSDFClosure {
-public:
- DiffuseRampBsdf params;
- Color3 colors[8];
+ public:
+ DiffuseRampBsdf params;
+ Color3 colors[8];
- void setup(ShaderData *sd, int /* path_flag */, float3 weight)
- {
- DiffuseRampBsdf *bsdf = (DiffuseRampBsdf*)bsdf_alloc_osl(sd, sizeof(DiffuseRampBsdf), weight, &params);
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
+ {
+ DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl(
+ sd, sizeof(DiffuseRampBsdf), weight, &params);
- if(bsdf) {
- bsdf->colors = (float3*)closure_alloc_extra(sd, sizeof(float3)*8);
+ if (bsdf) {
+ bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
- if(bsdf->colors) {
- for(int i = 0; i < 8; i++)
- bsdf->colors[i] = TO_FLOAT3(colors[i]);
+ if (bsdf->colors) {
+ for (int i = 0; i < 8; i++)
+ bsdf->colors[i] = TO_FLOAT3(colors[i]);
- sd->flag |= bsdf_diffuse_ramp_setup(bsdf);
- }
- }
- }
+ sd->flag |= bsdf_diffuse_ramp_setup(bsdf);
+ }
+ }
+ }
};
ClosureParam *closure_bsdf_diffuse_ramp_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, params.N),
- CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
- CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"),
- CLOSURE_FINISH_PARAM(DiffuseRampClosure)
- };
- return params;
+ static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, params.N),
+ CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
+ CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(DiffuseRampClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure)
diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index a8acdb8e342..4b7e59ff932 100644
--- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -46,37 +46,36 @@ CCL_NAMESPACE_BEGIN
using namespace OSL;
class PhongRampClosure : public CBSDFClosure {
-public:
- PhongRampBsdf params;
- Color3 colors[8];
+ public:
+ PhongRampBsdf params;
+ Color3 colors[8];
- void setup(ShaderData *sd, int /* path_flag */, float3 weight)
- {
- PhongRampBsdf *bsdf = (PhongRampBsdf*)bsdf_alloc_osl(sd, sizeof(PhongRampBsdf), weight, &params);
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
+ {
+ PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl(
+ sd, sizeof(PhongRampBsdf), weight, &params);
- if(bsdf) {
- bsdf->colors = (float3*)closure_alloc_extra(sd, sizeof(float3)*8);
+ if (bsdf) {
+ bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
- if(bsdf->colors) {
- for(int i = 0; i < 8; i++)
- bsdf->colors[i] = TO_FLOAT3(colors[i]);
+ if (bsdf->colors) {
+ for (int i = 0; i < 8; i++)
+ bsdf->colors[i] = TO_FLOAT3(colors[i]);
- sd->flag |= bsdf_phong_ramp_setup(bsdf);
- }
- }
- }
+ sd->flag |= bsdf_phong_ramp_setup(bsdf);
+ }
+ }
+ }
};
ClosureParam *closure_bsdf_phong_ramp_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(PhongRampClosure, params.N),
- CLOSURE_FLOAT_PARAM(PhongRampClosure, params.exponent),
- CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
- CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"),
- CLOSURE_FINISH_PARAM(PhongRampClosure)
- };
- return params;
+ static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PhongRampClosure, params.N),
+ CLOSURE_FLOAT_PARAM(PhongRampClosure, params.exponent),
+ CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
+ CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(PhongRampClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_phong_ramp_prepare, PhongRampClosure)
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index c2a848231f2..c29ddb13e2e 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -53,20 +53,18 @@ using namespace OSL;
/// if the provided angles are PI/2, which is the default
///
class GenericEmissiveClosure : public CClosurePrimitive {
-public:
- void setup(ShaderData *sd, int /* path_flag */, float3 weight)
- {
- emission_setup(sd, weight);
- }
+ public:
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
+ {
+ emission_setup(sd, weight);
+ }
};
ClosureParam *closure_emission_params()
{
- static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"),
- CLOSURE_FINISH_PARAM(GenericEmissiveClosure)
- };
- return params;
+ static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(GenericEmissiveClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure)
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp
index 66ec8a996ca..dd52c33071c 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.cpp
+++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp
@@ -56,77 +56,76 @@ static ustring u_random_walk("random_walk");
static ustring u_principled_random_walk("principled_random_walk");
class CBSSRDFClosure : public CClosurePrimitive {
-public:
- Bssrdf params;
- ustring method;
-
- CBSSRDFClosure()
- {
- params.texture_blur = 0.0f;
- params.sharpness = 0.0f;
- params.roughness = 0.0f;
- }
-
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- if(method == u_cubic) {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_CUBIC_ID);
- }
- else if(method == u_gaussian) {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_GAUSSIAN_ID);
- }
- else if(method == u_burley) {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID);
- }
- else if(method == u_principled) {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_ID);
- }
- else if(method == u_random_walk) {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_ID);
- }
- else if(method == u_principled_random_walk) {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
- }
- }
-
- void alloc(ShaderData *sd, int path_flag, float3 weight, ClosureType type)
- {
- Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
-
- if(bssrdf) {
- /* disable in case of diffuse ancestor, can't see it well then and
- * adds considerably noise due to probabilities of continuing path
- * getting lower and lower */
- if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
- params.radius = make_float3(0.0f, 0.0f, 0.0f);
- }
-
- /* create one closure per color channel */
- bssrdf->radius = params.radius;
- bssrdf->albedo = params.albedo;
- bssrdf->texture_blur = params.texture_blur;
- bssrdf->sharpness = params.sharpness;
- bssrdf->N = params.N;
- bssrdf->roughness = params.roughness;
- sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
- }
- }
+ public:
+ Bssrdf params;
+ ustring method;
+
+ CBSSRDFClosure()
+ {
+ params.texture_blur = 0.0f;
+ params.sharpness = 0.0f;
+ params.roughness = 0.0f;
+ }
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ if (method == u_cubic) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_CUBIC_ID);
+ }
+ else if (method == u_gaussian) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_GAUSSIAN_ID);
+ }
+ else if (method == u_burley) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID);
+ }
+ else if (method == u_principled) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_ID);
+ }
+ else if (method == u_random_walk) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_ID);
+ }
+ else if (method == u_principled_random_walk) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
+ }
+ }
+
+ void alloc(ShaderData *sd, int path_flag, float3 weight, ClosureType type)
+ {
+ Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
+
+ if (bssrdf) {
+ /* disable in case of diffuse ancestor, can't see it well then and
+ * adds considerably noise due to probabilities of continuing path
+ * getting lower and lower */
+ if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
+ params.radius = make_float3(0.0f, 0.0f, 0.0f);
+ }
+
+ /* create one closure per color channel */
+ bssrdf->radius = params.radius;
+ bssrdf->albedo = params.albedo;
+ bssrdf->texture_blur = params.texture_blur;
+ bssrdf->sharpness = params.sharpness;
+ bssrdf->N = params.N;
+ bssrdf->roughness = params.roughness;
+ sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
+ }
+ }
};
ClosureParam *closure_bssrdf_params()
{
- static ClosureParam params[] = {
- CLOSURE_STRING_PARAM(CBSSRDFClosure, method),
- CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.N),
- CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.radius),
- CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.albedo),
- CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.texture_blur, "texture_blur"),
- CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.sharpness, "sharpness"),
- CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.roughness, "roughness"),
- CLOSURE_STRING_KEYPARAM(CBSSRDFClosure, label, "label"),
- CLOSURE_FINISH_PARAM(CBSSRDFClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_STRING_PARAM(CBSSRDFClosure, method),
+ CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.radius),
+ CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.albedo),
+ CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.texture_blur, "texture_blur"),
+ CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.sharpness, "sharpness"),
+ CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.roughness, "roughness"),
+ CLOSURE_STRING_KEYPARAM(CBSSRDFClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(CBSSRDFClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bssrdf_prepare, CBSSRDFClosure)
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 169351d5ad9..aa7e2727577 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -71,706 +71,787 @@ using namespace OSL;
/* BSDF class definitions */
BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, DiffuseBsdf, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
-BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
-
-BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N),
-BSDF_CLOSURE_CLASS_END(Translucent, translucent)
-
-BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, OrenNayarBsdf, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N),
- CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness),
-BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
-
-BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, MicrofacetBsdf, LABEL_SINGULAR)
- CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N),
-BSDF_CLOSURE_CLASS_END(Reflection, reflection)
-
-BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR)
- CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N),
- CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior),
-BSDF_CLOSURE_CLASS_END(Refraction, refraction)
-
-BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N),
- CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma),
-BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
-
-BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley_aniso, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
- CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N),
- CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T),
- CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y),
-BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley_aniso)
-
-BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N),
- CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size),
- CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth),
-BSDF_CLOSURE_CLASS_END(DiffuseToon, diffuse_toon)
-
-BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, ToonBsdf, LABEL_GLOSSY)
- CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N),
- CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size),
- CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth),
-BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon)
-
-BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x),
-BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
-
-BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso, microfacet_ggx_aniso, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.N),
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.T),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_y),
-BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso)
-
-BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
- CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x),
-BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
-
-BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso, microfacet_beckmann_aniso, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
- CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.N),
- CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.T),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_y),
-BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso)
-
-BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, MicrofacetBsdf, LABEL_GLOSSY|LABEL_TRANSMIT)
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior),
-BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
-
-BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, MicrofacetBsdf, LABEL_GLOSSY|LABEL_TRANSMIT)
- CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior),
-BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
-
-BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY)
- CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N),
- CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1),
- CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2),
- CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
- CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
-BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection)
-
-BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY)
- CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N),
- CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1),
- CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2),
- CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
- CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
-BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
-
-BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse, principled_diffuse, PrincipledDiffuseBsdf, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N),
- CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness),
-BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse)
-
-BSDF_CLOSURE_CLASS_BEGIN(PrincipledSheen, principled_sheen, PrincipledSheenBsdf, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N),
-BSDF_CLOSURE_CLASS_END(PrincipledSheen, principled_sheen)
-
-/* PRINCIPLED HAIR BSDF */
-class PrincipledHairClosure : public CBSDFClosure {
-public:
- PrincipledHairBSDF params;
-
- PrincipledHairBSDF *alloc(ShaderData *sd, int path_flag, float3 weight)
- {
- PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)bsdf_alloc_osl(sd, sizeof(PrincipledHairBSDF), weight, &params);
- if(!bsdf) {
- return NULL;
- }
-
- PrincipledHairExtra *extra = (PrincipledHairExtra*)closure_alloc_extra(sd, sizeof(PrincipledHairExtra));
- if(!extra) {
- return NULL;
- }
-
- bsdf->extra = extra;
- return bsdf;
- }
-
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- if(!skip(sd, path_flag, LABEL_GLOSSY)) {
- PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0;
- }
- }
+CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
+ BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
+
+ BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE)
+ CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N),
+ BSDF_CLOSURE_CLASS_END(Translucent, translucent)
+
+ BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, OrenNayarBsdf, LABEL_DIFFUSE)
+ CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N),
+ CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness),
+ BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
+
+ BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, MicrofacetBsdf, LABEL_SINGULAR)
+ CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N),
+ BSDF_CLOSURE_CLASS_END(Reflection, reflection)
+
+ BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR)
+ CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N),
+ CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior),
+ BSDF_CLOSURE_CLASS_END(Refraction, refraction)
+
+ BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE)
+ CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N),
+ CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma),
+ BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
+
+ BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley,
+ ashikhmin_shirley_aniso,
+ MicrofacetBsdf,
+ LABEL_GLOSSY | LABEL_REFLECT)
+ CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T),
+ CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y),
+ BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley_aniso)
+
+ BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE)
+ CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N),
+ CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size),
+ CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth),
+ BSDF_CLOSURE_CLASS_END(DiffuseToon, diffuse_toon)
+
+ BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, ToonBsdf, LABEL_GLOSSY)
+ CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N),
+ CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size),
+ CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth),
+ BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon)
+
+ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX,
+ microfacet_ggx,
+ MicrofacetBsdf,
+ LABEL_GLOSSY | LABEL_REFLECT)
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x),
+ BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
+
+ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso,
+ microfacet_ggx_aniso,
+ MicrofacetBsdf,
+ LABEL_GLOSSY | LABEL_REFLECT)
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.T),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_y),
+ BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso)
+
+ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann,
+ microfacet_beckmann,
+ MicrofacetBsdf,
+ LABEL_GLOSSY | LABEL_REFLECT)
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x),
+ BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
+
+ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso,
+ microfacet_beckmann_aniso,
+ MicrofacetBsdf,
+ LABEL_GLOSSY | LABEL_REFLECT)
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.T),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_y),
+ BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso)
+
+ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction,
+ microfacet_ggx_refraction,
+ MicrofacetBsdf,
+ LABEL_GLOSSY | LABEL_TRANSMIT)
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior),
+ BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
+
+ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction,
+ microfacet_beckmann_refraction,
+ MicrofacetBsdf,
+ LABEL_GLOSSY | LABEL_TRANSMIT)
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior),
+ BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
+
+ BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY)
+ CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N),
+ CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1),
+ CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2),
+ CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
+ CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
+ BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection)
+
+ BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY)
+ CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N),
+ CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1),
+ CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2),
+ CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
+ CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
+ BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
+
+ BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse,
+ principled_diffuse,
+ PrincipledDiffuseBsdf,
+ LABEL_DIFFUSE)
+ CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N),
+ CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness),
+ BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse)
+
+ BSDF_CLOSURE_CLASS_BEGIN(PrincipledSheen,
+ principled_sheen,
+ PrincipledSheenBsdf,
+ LABEL_DIFFUSE)
+ CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N),
+ BSDF_CLOSURE_CLASS_END(PrincipledSheen, principled_sheen)
+
+ /* PRINCIPLED HAIR BSDF */
+ class PrincipledHairClosure : public CBSDFClosure {
+ public:
+ PrincipledHairBSDF params;
+
+ PrincipledHairBSDF *alloc(ShaderData *sd, int path_flag, float3 weight)
+ {
+ PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl(
+ sd, sizeof(PrincipledHairBSDF), weight, &params);
+ if (!bsdf) {
+ return NULL;
+ }
+
+ PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra(
+ sd, sizeof(PrincipledHairExtra));
+ if (!extra) {
+ return NULL;
+ }
+
+ bsdf->extra = extra;
+ return bsdf;
+ }
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ if (!skip(sd, path_flag, LABEL_GLOSSY)) {
+ PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0;
+ }
+ }
};
static ClosureParam *closure_bsdf_principled_hair_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N),
- CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.sigma),
- CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v),
- CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s),
- CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness),
- CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha),
- CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta),
- CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"),
- CLOSURE_FINISH_PARAM(PrincipledHairClosure)
- };
-
- return params;
+ static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.sigma),
+ CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v),
+ CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s),
+ CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness),
+ CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha),
+ CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta),
+ CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(PrincipledHairClosure)};
+
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_principled_hair_prepare, PrincipledHairClosure)
/* DISNEY PRINCIPLED CLEARCOAT */
class PrincipledClearcoatClosure : public CBSDFClosure {
-public:
- MicrofacetBsdf params;
- float clearcoat, clearcoat_roughness;
-
- MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
- if(!bsdf) {
- return NULL;
- }
-
- MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
- if(!extra) {
- return NULL;
- }
-
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra = extra;
- bsdf->ior = 1.5f;
- bsdf->alpha_x = clearcoat_roughness;
- bsdf->alpha_y = clearcoat_roughness;
- bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
- bsdf->extra->clearcoat = clearcoat;
- return bsdf;
- }
-
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
- }
+ public:
+ MicrofacetBsdf params;
+ float clearcoat, clearcoat_roughness;
+
+ MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
+ sd, sizeof(MicrofacetBsdf), weight, &params);
+ if (!bsdf) {
+ return NULL;
+ }
+
+ MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
+ if (!extra) {
+ return NULL;
+ }
+
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra = extra;
+ bsdf->ior = 1.5f;
+ bsdf->alpha_x = clearcoat_roughness;
+ bsdf->alpha_y = clearcoat_roughness;
+ bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
+ bsdf->extra->clearcoat = clearcoat;
+ return bsdf;
+ }
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
+ }
};
ClosureParam *closure_bsdf_principled_clearcoat_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N),
- CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat),
- CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness),
- CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"),
- CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N),
+ CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat),
+ CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness),
+ CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_principled_clearcoat_prepare, PrincipledClearcoatClosure)
-
/* Registration */
-static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, OSL::ClosureParam *params, OSL::PrepareClosureFunc prepare)
+static void register_closure(OSL::ShadingSystem *ss,
+ const char *name,
+ int id,
+ OSL::ClosureParam *params,
+ OSL::PrepareClosureFunc prepare)
{
- /* optimization: it's possible to not use a prepare function at all and
- * only initialize the actual class when accessing the closure component
- * data, but then we need to map the id to the class somehow */
+ /* optimization: it's possible to not use a prepare function at all and
+ * only initialize the actual class when accessing the closure component
+ * data, but then we need to map the id to the class somehow */
#if OSL_LIBRARY_VERSION_CODE >= 10900
- ss->register_closure(name, id, params, prepare, NULL);
+ ss->register_closure(name, id, params, prepare, NULL);
#else
- ss->register_closure(name, id, params, prepare, NULL, 16);
+ ss->register_closure(name, id, params, prepare, NULL, 16);
#endif
}
void OSLShader::register_closures(OSLShadingSystem *ss_)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)ss_;
- int id = 0;
-
- register_closure(ss, "diffuse", id++,
- bsdf_diffuse_params(), bsdf_diffuse_prepare);
- register_closure(ss, "oren_nayar", id++,
- bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare);
- register_closure(ss, "translucent", id++,
- bsdf_translucent_params(), bsdf_translucent_prepare);
- register_closure(ss, "reflection", id++,
- bsdf_reflection_params(), bsdf_reflection_prepare);
- register_closure(ss, "refraction", id++,
- bsdf_refraction_params(), bsdf_refraction_prepare);
- register_closure(ss, "transparent", id++,
- closure_bsdf_transparent_params(), closure_bsdf_transparent_prepare);
- register_closure(ss, "microfacet_ggx", id++,
- bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
- register_closure(ss, "microfacet_ggx_aniso", id++,
- bsdf_microfacet_ggx_aniso_params(), bsdf_microfacet_ggx_aniso_prepare);
- register_closure(ss, "microfacet_ggx_refraction", id++,
- bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare);
- register_closure(ss, "microfacet_multi_ggx", id++,
- closure_bsdf_microfacet_multi_ggx_params(), closure_bsdf_microfacet_multi_ggx_prepare);
- register_closure(ss, "microfacet_multi_ggx_glass", id++,
- closure_bsdf_microfacet_multi_ggx_glass_params(), closure_bsdf_microfacet_multi_ggx_glass_prepare);
- register_closure(ss, "microfacet_multi_ggx_aniso", id++,
- closure_bsdf_microfacet_multi_ggx_aniso_params(), closure_bsdf_microfacet_multi_ggx_aniso_prepare);
- register_closure(ss, "microfacet_ggx_fresnel", id++,
- closure_bsdf_microfacet_ggx_fresnel_params(), closure_bsdf_microfacet_ggx_fresnel_prepare);
- register_closure(ss, "microfacet_ggx_aniso_fresnel", id++,
- closure_bsdf_microfacet_ggx_aniso_fresnel_params(), closure_bsdf_microfacet_ggx_aniso_fresnel_prepare);
- register_closure(ss, "microfacet_multi_ggx_fresnel", id++,
- closure_bsdf_microfacet_multi_ggx_fresnel_params(), closure_bsdf_microfacet_multi_ggx_fresnel_prepare);
- register_closure(ss, "microfacet_multi_ggx_glass_fresnel", id++,
- closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(), closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare);
- register_closure(ss, "microfacet_multi_ggx_aniso_fresnel", id++,
- closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(), closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare);
- register_closure(ss, "microfacet_beckmann", id++,
- bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare);
- register_closure(ss, "microfacet_beckmann_aniso", id++,
- bsdf_microfacet_beckmann_aniso_params(), bsdf_microfacet_beckmann_aniso_prepare);
- register_closure(ss, "microfacet_beckmann_refraction", id++,
- bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare);
- register_closure(ss, "ashikhmin_shirley", id++,
- bsdf_ashikhmin_shirley_aniso_params(), bsdf_ashikhmin_shirley_aniso_prepare);
- register_closure(ss, "ashikhmin_velvet", id++,
- bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
- register_closure(ss, "diffuse_toon", id++,
- bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare);
- register_closure(ss, "glossy_toon", id++,
- bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
- register_closure(ss, "principled_diffuse", id++,
- bsdf_principled_diffuse_params(), bsdf_principled_diffuse_prepare);
- register_closure(ss, "principled_sheen", id++,
- bsdf_principled_sheen_params(), bsdf_principled_sheen_prepare);
- register_closure(ss, "principled_clearcoat", id++,
- closure_bsdf_principled_clearcoat_params(), closure_bsdf_principled_clearcoat_prepare);
-
- register_closure(ss, "emission", id++,
- closure_emission_params(), closure_emission_prepare);
- register_closure(ss, "background", id++,
- closure_background_params(), closure_background_prepare);
- register_closure(ss, "holdout", id++,
- closure_holdout_params(), closure_holdout_prepare);
- register_closure(ss, "diffuse_ramp", id++,
- closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare);
- register_closure(ss, "phong_ramp", id++,
- closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
- register_closure(ss, "bssrdf", id++,
- closure_bssrdf_params(), closure_bssrdf_prepare);
-
- register_closure(ss, "hair_reflection", id++,
- bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
- register_closure(ss, "hair_transmission", id++,
- bsdf_hair_transmission_params(), bsdf_hair_transmission_prepare);
-
- register_closure(ss, "principled_hair", id++,
- closure_bsdf_principled_hair_params(), closure_bsdf_principled_hair_prepare);
-
- register_closure(ss, "henyey_greenstein", id++,
- closure_henyey_greenstein_params(), closure_henyey_greenstein_prepare);
- register_closure(ss, "absorption", id++,
- closure_absorption_params(), closure_absorption_prepare);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)ss_;
+ int id = 0;
+
+ register_closure(ss, "diffuse", id++, bsdf_diffuse_params(), bsdf_diffuse_prepare);
+ register_closure(ss, "oren_nayar", id++, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare);
+ register_closure(ss, "translucent", id++, bsdf_translucent_params(), bsdf_translucent_prepare);
+ register_closure(ss, "reflection", id++, bsdf_reflection_params(), bsdf_reflection_prepare);
+ register_closure(ss, "refraction", id++, bsdf_refraction_params(), bsdf_refraction_prepare);
+ register_closure(ss,
+ "transparent",
+ id++,
+ closure_bsdf_transparent_params(),
+ closure_bsdf_transparent_prepare);
+ register_closure(
+ ss, "microfacet_ggx", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
+ register_closure(ss,
+ "microfacet_ggx_aniso",
+ id++,
+ bsdf_microfacet_ggx_aniso_params(),
+ bsdf_microfacet_ggx_aniso_prepare);
+ register_closure(ss,
+ "microfacet_ggx_refraction",
+ id++,
+ bsdf_microfacet_ggx_refraction_params(),
+ bsdf_microfacet_ggx_refraction_prepare);
+ register_closure(ss,
+ "microfacet_multi_ggx",
+ id++,
+ closure_bsdf_microfacet_multi_ggx_params(),
+ closure_bsdf_microfacet_multi_ggx_prepare);
+ register_closure(ss,
+ "microfacet_multi_ggx_glass",
+ id++,
+ closure_bsdf_microfacet_multi_ggx_glass_params(),
+ closure_bsdf_microfacet_multi_ggx_glass_prepare);
+ register_closure(ss,
+ "microfacet_multi_ggx_aniso",
+ id++,
+ closure_bsdf_microfacet_multi_ggx_aniso_params(),
+ closure_bsdf_microfacet_multi_ggx_aniso_prepare);
+ register_closure(ss,
+ "microfacet_ggx_fresnel",
+ id++,
+ closure_bsdf_microfacet_ggx_fresnel_params(),
+ closure_bsdf_microfacet_ggx_fresnel_prepare);
+ register_closure(ss,
+ "microfacet_ggx_aniso_fresnel",
+ id++,
+ closure_bsdf_microfacet_ggx_aniso_fresnel_params(),
+ closure_bsdf_microfacet_ggx_aniso_fresnel_prepare);
+ register_closure(ss,
+ "microfacet_multi_ggx_fresnel",
+ id++,
+ closure_bsdf_microfacet_multi_ggx_fresnel_params(),
+ closure_bsdf_microfacet_multi_ggx_fresnel_prepare);
+ register_closure(ss,
+ "microfacet_multi_ggx_glass_fresnel",
+ id++,
+ closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(),
+ closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare);
+ register_closure(ss,
+ "microfacet_multi_ggx_aniso_fresnel",
+ id++,
+ closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(),
+ closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare);
+ register_closure(ss,
+ "microfacet_beckmann",
+ id++,
+ bsdf_microfacet_beckmann_params(),
+ bsdf_microfacet_beckmann_prepare);
+ register_closure(ss,
+ "microfacet_beckmann_aniso",
+ id++,
+ bsdf_microfacet_beckmann_aniso_params(),
+ bsdf_microfacet_beckmann_aniso_prepare);
+ register_closure(ss,
+ "microfacet_beckmann_refraction",
+ id++,
+ bsdf_microfacet_beckmann_refraction_params(),
+ bsdf_microfacet_beckmann_refraction_prepare);
+ register_closure(ss,
+ "ashikhmin_shirley",
+ id++,
+ bsdf_ashikhmin_shirley_aniso_params(),
+ bsdf_ashikhmin_shirley_aniso_prepare);
+ register_closure(
+ ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
+ register_closure(
+ ss, "diffuse_toon", id++, bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare);
+ register_closure(ss, "glossy_toon", id++, bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
+ register_closure(ss,
+ "principled_diffuse",
+ id++,
+ bsdf_principled_diffuse_params(),
+ bsdf_principled_diffuse_prepare);
+ register_closure(
+ ss, "principled_sheen", id++, bsdf_principled_sheen_params(), bsdf_principled_sheen_prepare);
+ register_closure(ss,
+ "principled_clearcoat",
+ id++,
+ closure_bsdf_principled_clearcoat_params(),
+ closure_bsdf_principled_clearcoat_prepare);
+
+ register_closure(ss, "emission", id++, closure_emission_params(), closure_emission_prepare);
+ register_closure(
+ ss, "background", id++, closure_background_params(), closure_background_prepare);
+ register_closure(ss, "holdout", id++, closure_holdout_params(), closure_holdout_prepare);
+ register_closure(ss,
+ "diffuse_ramp",
+ id++,
+ closure_bsdf_diffuse_ramp_params(),
+ closure_bsdf_diffuse_ramp_prepare);
+ register_closure(
+ ss, "phong_ramp", id++, closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
+ register_closure(ss, "bssrdf", id++, closure_bssrdf_params(), closure_bssrdf_prepare);
+
+ register_closure(
+ ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
+ register_closure(ss,
+ "hair_transmission",
+ id++,
+ bsdf_hair_transmission_params(),
+ bsdf_hair_transmission_prepare);
+
+ register_closure(ss,
+ "principled_hair",
+ id++,
+ closure_bsdf_principled_hair_params(),
+ closure_bsdf_principled_hair_prepare);
+
+ register_closure(ss,
+ "henyey_greenstein",
+ id++,
+ closure_henyey_greenstein_params(),
+ closure_henyey_greenstein_prepare);
+ register_closure(
+ ss, "absorption", id++, closure_absorption_params(), closure_absorption_prepare);
}
/* BSDF Closure */
bool CBSDFClosure::skip(const ShaderData *sd, int path_flag, int scattering)
{
- /* caustic options */
- if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
- KernelGlobals *kg = sd->osl_globals;
-
- if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
- (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT)))
- {
- return true;
- }
- }
-
- return false;
-}
+ /* caustic options */
+ if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
+ KernelGlobals *kg = sd->osl_globals;
+ if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
+ (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) {
+ return true;
+ }
+ }
+
+ return false;
+}
/* GGX closures with Fresnel */
class MicrofacetFresnelClosure : public CBSDFClosure {
-public:
- MicrofacetBsdf params;
- float3 color;
- float3 cspec0;
-
- MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
- {
- /* Technically, the MultiGGX Glass closure may also transmit. However,
- * since this is set statically and only used for caustic flags, this
- * is probably as good as it gets. */
- if(skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
- return NULL;
- }
-
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
- if(!bsdf) {
- return NULL;
- }
-
- MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
- if(!extra) {
- return NULL;
- }
-
- bsdf->extra = extra;
- bsdf->extra->color = color;
- bsdf->extra->cspec0 = cspec0;
- bsdf->extra->clearcoat = 0.0f;
- return bsdf;
- }
+ public:
+ MicrofacetBsdf params;
+ float3 color;
+ float3 cspec0;
+
+ MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
+ {
+ /* Technically, the MultiGGX Glass closure may also transmit. However,
+ * since this is set statically and only used for caustic flags, this
+ * is probably as good as it gets. */
+ if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
+ return NULL;
+ }
+
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
+ sd, sizeof(MicrofacetBsdf), weight, &params);
+ if (!bsdf) {
+ return NULL;
+ }
+
+ MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
+ if (!extra) {
+ return NULL;
+ }
+
+ bsdf->extra = extra;
+ bsdf->extra->color = color;
+ bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->clearcoat = 0.0f;
+ return bsdf;
+ }
};
class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->alpha_y = bsdf->alpha_x;
- sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
- }
+ public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
+ sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
+ }
};
ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
- CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
+ CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresnelClosure);
class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
- }
+ public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
+ }
};
ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.T),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
- CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
- CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.T),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
+ CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
+ return params;
}
-CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_aniso_fresnel_prepare, MicrofacetGGXAnisoFresnelClosure);
-
+CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_aniso_fresnel_prepare,
+ MicrofacetGGXAnisoFresnelClosure);
/* Multiscattering GGX closures */
class MicrofacetMultiClosure : public CBSDFClosure {
-public:
- MicrofacetBsdf params;
- float3 color;
-
- MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
- {
- /* Technically, the MultiGGX closure may also transmit. However,
- * since this is set statically and only used for caustic flags, this
- * is probably as good as it gets. */
- if(skip(sd, path_flag, LABEL_GLOSSY|LABEL_REFLECT)) {
- return NULL;
- }
-
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
- if(!bsdf) {
- return NULL;
- }
-
- MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
- if(!extra) {
- return NULL;
- }
-
- bsdf->extra = extra;
- bsdf->extra->color = color;
- bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->clearcoat = 0.0f;
- return bsdf;
- }
+ public:
+ MicrofacetBsdf params;
+ float3 color;
+
+ MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
+ {
+ /* Technically, the MultiGGX closure may also transmit. However,
+ * since this is set statically and only used for caustic flags, this
+ * is probably as good as it gets. */
+ if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
+ return NULL;
+ }
+
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
+ sd, sizeof(MicrofacetBsdf), weight, &params);
+ if (!bsdf) {
+ return NULL;
+ }
+
+ MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
+ if (!extra) {
+ return NULL;
+ }
+
+ bsdf->extra = extra;
+ bsdf->extra->color = color;
+ bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->clearcoat = 0.0f;
+ return bsdf;
+ }
};
class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- bsdf->ior = 0.0f;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->alpha_y = bsdf->alpha_x;
- sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
- }
+ public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ bsdf->ior = 0.0f;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
+ sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
+ }
};
ClosureParam *closure_bsdf_microfacet_multi_ggx_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
- CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
+ CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_prepare, MicrofacetMultiGGXClosure);
class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- bsdf->ior = 0.0f;
- sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
- }
+ public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ bsdf->ior = 0.0f;
+ sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
+ }
};
ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.T),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
- CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.T),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
+ CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_prepare, MicrofacetMultiGGXAnisoClosure);
class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure {
-public:
- MicrofacetMultiGGXGlassClosure() : MicrofacetMultiClosure() {}
-
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->alpha_y = bsdf->alpha_x;
- sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
- }
+ public:
+ MicrofacetMultiGGXGlassClosure() : MicrofacetMultiClosure()
+ {
+ }
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
+ sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
+ }
};
ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
- CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
+ CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_prepare, MicrofacetMultiGGXGlassClosure);
-
/* Multiscattering GGX closures with Fresnel */
class MicrofacetMultiFresnelClosure : public CBSDFClosure {
-public:
- MicrofacetBsdf params;
- float3 color;
- float3 cspec0;
-
- MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
- {
- /* Technically, the MultiGGX closure may also transmit. However,
- * since this is set statically and only used for caustic flags, this
- * is probably as good as it gets. */
- if(skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
- return NULL;
- }
-
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
- if(!bsdf) {
- return NULL;
- }
-
- MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
- if(!extra) {
- return NULL;
- }
-
- bsdf->extra = extra;
- bsdf->extra->color = color;
- bsdf->extra->cspec0 = cspec0;
- bsdf->extra->clearcoat = 0.0f;
- return bsdf;
- }
+ public:
+ MicrofacetBsdf params;
+ float3 color;
+ float3 cspec0;
+
+ MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
+ {
+ /* Technically, the MultiGGX closure may also transmit. However,
+ * since this is set statically and only used for caustic flags, this
+ * is probably as good as it gets. */
+ if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
+ return NULL;
+ }
+
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
+ sd, sizeof(MicrofacetBsdf), weight, &params);
+ if (!bsdf) {
+ return NULL;
+ }
+
+ MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
+ if (!extra) {
+ return NULL;
+ }
+
+ bsdf->extra = extra;
+ bsdf->extra->color = color;
+ bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->clearcoat = 0.0f;
+ return bsdf;
+ }
};
class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->alpha_y = bsdf->alpha_x;
- sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
- }
+ public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
+ sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
+ }
};
ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
- CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
+ CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
+ return params;
}
-CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare, MicrofacetMultiGGXFresnelClosure);
+CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare,
+ MicrofacetMultiGGXFresnelClosure);
class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
- }
+ public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
+ }
};
ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.T),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
- CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.T),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
+ CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
+ return params;
}
-CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare, MicrofacetMultiGGXAnisoFresnelClosure);
+CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare,
+ MicrofacetMultiGGXAnisoFresnelClosure);
class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosure {
-public:
- MicrofacetMultiGGXGlassFresnelClosure() : MicrofacetMultiFresnelClosure() {}
-
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
- if(!bsdf) {
- return;
- }
-
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->alpha_y = bsdf->alpha_x;
- sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
- }
+ public:
+ MicrofacetMultiGGXGlassFresnelClosure() : MicrofacetMultiFresnelClosure()
+ {
+ }
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
+ if (!bsdf) {
+ return;
+ }
+
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->alpha_y = bsdf->alpha_x;
+ sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
+ }
};
ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
- CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
- CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
- CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
- CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
+ CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
+ CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
+ CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
+ return params;
}
-CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare, MicrofacetMultiGGXGlassFresnelClosure);
+CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare,
+ MicrofacetMultiGGXGlassFresnelClosure);
/* Transparent */
class TransparentClosure : public CBSDFClosure {
-public:
- ShaderClosure params;
- float3 unused;
-
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- bsdf_transparent_setup(sd, weight, path_flag);
- }
+ public:
+ ShaderClosure params;
+ float3 unused;
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ bsdf_transparent_setup(sd, weight, path_flag);
+ }
};
ClosureParam *closure_bsdf_transparent_params()
{
- static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"),
- CLOSURE_FINISH_PARAM(TransparentClosure)
- };
- return params;
+ static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(TransparentClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure)
@@ -778,52 +859,49 @@ CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure)
/* Volume */
class VolumeAbsorptionClosure : public CBSDFClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- volume_extinction_setup(sd, weight);
- }
+ public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ volume_extinction_setup(sd, weight);
+ }
};
ClosureParam *closure_absorption_params()
{
- static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"),
- CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)
- };
- return params;
+ static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_absorption_prepare, VolumeAbsorptionClosure)
class VolumeHenyeyGreensteinClosure : public CBSDFClosure {
-public:
- HenyeyGreensteinVolume params;
+ public:
+ HenyeyGreensteinVolume params;
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- volume_extinction_setup(sd, weight);
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ volume_extinction_setup(sd, weight);
- HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc_osl(sd, sizeof(HenyeyGreensteinVolume), weight, &params);
- if(!volume) {
- return;
- }
+ HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl(
+ sd, sizeof(HenyeyGreensteinVolume), weight, &params);
+ if (!volume) {
+ return;
+ }
- sd->flag |= volume_henyey_greenstein_setup(volume);
- }
+ sd->flag |= volume_henyey_greenstein_setup(volume);
+ }
};
ClosureParam *closure_henyey_greenstein_params()
{
- static ClosureParam params[] = {
- CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
- CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"),
- CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)
- };
- return params;
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
+ CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)};
+ return params;
}
CCLOSURE_PREPARE(closure_henyey_greenstein_prepare, VolumeHenyeyGreensteinClosure)
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 2a50704b569..d3db6b71f5c 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -74,24 +74,34 @@ void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id,
void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *,
+ int id,
+ void *data);
+void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *,
+ int id,
+ void *data);
+void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *,
+ int id,
+ void *data);
+void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *,
+ int id,
+ void *data);
void closure_bsdf_principled_clearcoat_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void *data);
-#define CCLOSURE_PREPARE(name, classname) \
-void name(RendererServices *, int id, void *data) \
-{ \
- memset(data, 0, sizeof(classname)); \
- new (data) classname(); \
-}
+#define CCLOSURE_PREPARE(name, classname) \
+ void name(RendererServices *, int id, void *data) \
+ { \
+ memset(data, 0, sizeof(classname)); \
+ new (data) classname(); \
+ }
#define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname)
#define CLOSURE_FLOAT3_PARAM(st, fld) \
- { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
+ { \
+ TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) \
+ }
#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
@@ -100,50 +110,50 @@ void name(RendererServices *, int id, void *data) \
/* Closure */
class CClosurePrimitive {
-public:
- virtual void setup(ShaderData *sd, int path_flag, float3 weight) = 0;
+ public:
+ virtual void setup(ShaderData *sd, int path_flag, float3 weight) = 0;
- OSL::ustring label;
+ OSL::ustring label;
};
/* BSDF */
class CBSDFClosure : public CClosurePrimitive {
-public:
- bool skip(const ShaderData *sd, int path_flag, int scattering);
+ public:
+ bool skip(const ShaderData *sd, int path_flag, int scattering);
};
#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, structname, TYPE) \
\
-class Upper##Closure : public CBSDFClosure { \
-public: \
- structname params; \
- float3 unused; \
+ class Upper##Closure : public CBSDFClosure { \
+ public: \
+ structname params; \
+ float3 unused; \
\
- void setup(ShaderData *sd, int path_flag, float3 weight) \
- { \
- if(!skip(sd, path_flag, TYPE)) { \
- structname *bsdf = (structname*)bsdf_alloc_osl(sd, sizeof(structname), weight, &params); \
- sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \
- } \
- } \
-}; \
+ void setup(ShaderData *sd, int path_flag, float3 weight) \
+ { \
+ if (!skip(sd, path_flag, TYPE)) { \
+ structname *bsdf = (structname *)bsdf_alloc_osl(sd, sizeof(structname), weight, &params); \
+ sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \
+ } \
+ } \
+ }; \
\
-static ClosureParam *bsdf_##lower##_params() \
-{ \
- static ClosureParam params[] = {
+ static ClosureParam *bsdf_##lower##_params() \
+ { \
+ static ClosureParam params[] = {
/* parameters */
#define BSDF_CLOSURE_CLASS_END(Upper, lower) \
- CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \
- CLOSURE_FINISH_PARAM(Upper##Closure) \
- }; \
- return params; \
-} \
+ CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \
+ } \
+ ; \
+ return params; \
+ } \
\
-CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
+ CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
CCL_NAMESPACE_END
-#endif /* __OSL_CLOSURES_H__ */
+#endif /* __OSL_CLOSURES_H__ */
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 88192fbcccb..641c9967586 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -19,79 +19,79 @@
#ifdef WITH_OSL
-#include <OSL/oslexec.h>
+# include <OSL/oslexec.h>
-#include "util/util_map.h"
-#include "util/util_param.h"
-#include "util/util_thread.h"
-#include "util/util_vector.h"
+# include "util/util_map.h"
+# include "util/util_param.h"
+# include "util/util_thread.h"
+# include "util/util_vector.h"
-#ifndef WIN32
+# ifndef WIN32
using std::isfinite;
-#endif
+# endif
CCL_NAMESPACE_BEGIN
class OSLRenderServices;
struct OSLGlobals {
- OSLGlobals()
- {
- ss = NULL;
- ts = NULL;
- services = NULL;
- use = false;
- }
-
- bool use;
-
- /* shading system */
- OSL::ShadingSystem *ss;
- OSL::TextureSystem *ts;
- OSLRenderServices *services;
-
- /* shader states */
- vector<OSL::ShaderGroupRef> surface_state;
- vector<OSL::ShaderGroupRef> volume_state;
- vector<OSL::ShaderGroupRef> displacement_state;
- vector<OSL::ShaderGroupRef> bump_state;
- OSL::ShaderGroupRef background_state;
-
- /* attributes */
- struct Attribute {
- TypeDesc type;
- AttributeDescriptor desc;
- ParamValue value;
- };
-
- typedef unordered_map<ustring, Attribute, ustringHash> AttributeMap;
- typedef unordered_map<ustring, int, ustringHash> ObjectNameMap;
-
- vector<AttributeMap> attribute_map;
- ObjectNameMap object_name_map;
- vector<ustring> object_names;
+ OSLGlobals()
+ {
+ ss = NULL;
+ ts = NULL;
+ services = NULL;
+ use = false;
+ }
+
+ bool use;
+
+ /* shading system */
+ OSL::ShadingSystem *ss;
+ OSL::TextureSystem *ts;
+ OSLRenderServices *services;
+
+ /* shader states */
+ vector<OSL::ShaderGroupRef> surface_state;
+ vector<OSL::ShaderGroupRef> volume_state;
+ vector<OSL::ShaderGroupRef> displacement_state;
+ vector<OSL::ShaderGroupRef> bump_state;
+ OSL::ShaderGroupRef background_state;
+
+ /* attributes */
+ struct Attribute {
+ TypeDesc type;
+ AttributeDescriptor desc;
+ ParamValue value;
+ };
+
+ typedef unordered_map<ustring, Attribute, ustringHash> AttributeMap;
+ typedef unordered_map<ustring, int, ustringHash> ObjectNameMap;
+
+ vector<AttributeMap> attribute_map;
+ ObjectNameMap object_name_map;
+ vector<ustring> object_names;
};
/* trace() call result */
struct OSLTraceData {
- Ray ray;
- Intersection isect;
- ShaderData sd;
- bool setup;
- bool init;
+ Ray ray;
+ Intersection isect;
+ ShaderData sd;
+ bool setup;
+ bool init;
};
/* thread key for thread specific data lookup */
struct OSLThreadData {
- OSL::ShaderGlobals globals;
- OSL::PerThreadInfo *osl_thread_info;
- OSLTraceData tracedata;
- OSL::ShadingContext *context;
- OIIO::TextureSystem::Perthread *oiio_thread_info;
+ OSL::ShaderGlobals globals;
+ OSL::PerThreadInfo *osl_thread_info;
+ OSLTraceData tracedata;
+ OSL::ShadingContext *context;
+ OIIO::TextureSystem::Perthread *oiio_thread_info;
};
CCL_NAMESPACE_END
#endif
-#endif /* __OSL_GLOBALS_H__ */
+#endif /* __OSL_GLOBALS_H__ */
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 6464d382634..eb9f672fd8a 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -63,16 +63,16 @@ CCL_NAMESPACE_BEGIN
/* RenderServices implementation */
-static void copy_matrix(OSL::Matrix44& m, const Transform& tfm)
+static void copy_matrix(OSL::Matrix44 &m, const Transform &tfm)
{
- ProjectionTransform t = projection_transpose(ProjectionTransform(tfm));
- memcpy((void *)&m, &t, sizeof(m));
+ ProjectionTransform t = projection_transpose(ProjectionTransform(tfm));
+ memcpy((void *)&m, &t, sizeof(m));
}
-static void copy_matrix(OSL::Matrix44& m, const ProjectionTransform& tfm)
+static void copy_matrix(OSL::Matrix44 &m, const ProjectionTransform &tfm)
{
- ProjectionTransform t = projection_transpose(tfm);
- memcpy((void *)&m, &t, sizeof(m));
+ ProjectionTransform t = projection_transpose(tfm);
+ memcpy((void *)&m, &t, sizeof(m));
}
/* static ustrings */
@@ -129,815 +129,846 @@ ustring OSLRenderServices::u_at_ao("@ao");
OSLRenderServices::OSLRenderServices()
{
- kernel_globals = NULL;
- osl_ts = NULL;
+ kernel_globals = NULL;
+ osl_ts = NULL;
#ifdef WITH_PTEX
- size_t maxmem = 16384 * 1024;
- ptex_cache = PtexCache::create(0, maxmem);
+ size_t maxmem = 16384 * 1024;
+ ptex_cache = PtexCache::create(0, maxmem);
#endif
}
OSLRenderServices::~OSLRenderServices()
{
- if(osl_ts) {
- VLOG(2) << "OSL texture system stats:\n"
- << osl_ts->getstats();
- }
+ if (osl_ts) {
+ VLOG(2) << "OSL texture system stats:\n" << osl_ts->getstats();
+ }
#ifdef WITH_PTEX
- ptex_cache->release();
+ ptex_cache->release();
#endif
}
void OSLRenderServices::thread_init(KernelGlobals *kernel_globals_, OSL::TextureSystem *osl_ts_)
{
- kernel_globals = kernel_globals_;
- osl_ts = osl_ts_;
+ kernel_globals = kernel_globals_;
+ osl_ts = osl_ts_;
}
-bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform, float time)
+bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform,
+ float time)
{
- /* this is only used for shader and object space, we don't really have
- * a concept of shader space, so we just use object space for both. */
- if(xform) {
- const ShaderData *sd = (const ShaderData *)xform;
- KernelGlobals *kg = sd->osl_globals;
- int object = sd->object;
-
- if(object != OBJECT_NONE) {
+ /* this is only used for shader and object space, we don't really have
+ * a concept of shader space, so we just use object space for both. */
+ if (xform) {
+ const ShaderData *sd = (const ShaderData *)xform;
+ KernelGlobals *kg = sd->osl_globals;
+ int object = sd->object;
+
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
- Transform tfm;
+ Transform tfm;
- if(time == sd->time)
- tfm = sd->ob_tfm;
- else
- tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
+ if (time == sd->time)
+ tfm = sd->ob_tfm;
+ else
+ tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
#else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
- copy_matrix(result, tfm);
+ copy_matrix(result, tfm);
- return true;
- }
- else if(sd->type == PRIMITIVE_LAMP) {
- copy_matrix(result, sd->ob_tfm);
+ return true;
+ }
+ else if (sd->type == PRIMITIVE_LAMP) {
+ copy_matrix(result, sd->ob_tfm);
- return true;
- }
- }
+ return true;
+ }
+ }
- return false;
+ return false;
}
-bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform, float time)
+bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform,
+ float time)
{
- /* this is only used for shader and object space, we don't really have
- * a concept of shader space, so we just use object space for both. */
- if(xform) {
- const ShaderData *sd = (const ShaderData *)xform;
- KernelGlobals *kg = sd->osl_globals;
- int object = sd->object;
-
- if(object != OBJECT_NONE) {
+ /* this is only used for shader and object space, we don't really have
+ * a concept of shader space, so we just use object space for both. */
+ if (xform) {
+ const ShaderData *sd = (const ShaderData *)xform;
+ KernelGlobals *kg = sd->osl_globals;
+ int object = sd->object;
+
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
- Transform itfm;
+ Transform itfm;
- if(time == sd->time)
- itfm = sd->ob_itfm;
- else
- object_fetch_transform_motion_test(kg, object, time, &itfm);
+ if (time == sd->time)
+ itfm = sd->ob_itfm;
+ else
+ object_fetch_transform_motion_test(kg, object, time, &itfm);
#else
- Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
- copy_matrix(result, itfm);
+ copy_matrix(result, itfm);
- return true;
- }
- else if(sd->type == PRIMITIVE_LAMP) {
- copy_matrix(result, sd->ob_itfm);
+ return true;
+ }
+ else if (sd->type == PRIMITIVE_LAMP) {
+ copy_matrix(result, sd->ob_itfm);
- return true;
- }
- }
+ return true;
+ }
+ }
- return false;
+ return false;
}
-bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from, float time)
+bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ ustring from,
+ float time)
{
- KernelGlobals *kg = kernel_globals;
-
- if(from == u_ndc) {
- copy_matrix(result, kernel_data.cam.ndctoworld);
- return true;
- }
- else if(from == u_raster) {
- copy_matrix(result, kernel_data.cam.rastertoworld);
- return true;
- }
- else if(from == u_screen) {
- copy_matrix(result, kernel_data.cam.screentoworld);
- return true;
- }
- else if(from == u_camera) {
- copy_matrix(result, kernel_data.cam.cameratoworld);
- return true;
- }
- else if(from == u_world) {
- result.makeIdentity();
- return true;
- }
-
- return false;
+ KernelGlobals *kg = kernel_globals;
+
+ if (from == u_ndc) {
+ copy_matrix(result, kernel_data.cam.ndctoworld);
+ return true;
+ }
+ else if (from == u_raster) {
+ copy_matrix(result, kernel_data.cam.rastertoworld);
+ return true;
+ }
+ else if (from == u_screen) {
+ copy_matrix(result, kernel_data.cam.screentoworld);
+ return true;
+ }
+ else if (from == u_camera) {
+ copy_matrix(result, kernel_data.cam.cameratoworld);
+ return true;
+ }
+ else if (from == u_world) {
+ result.makeIdentity();
+ return true;
+ }
+
+ return false;
}
-bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring to, float time)
+bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ ustring to,
+ float time)
{
- KernelGlobals *kg = kernel_globals;
-
- if(to == u_ndc) {
- copy_matrix(result, kernel_data.cam.worldtondc);
- return true;
- }
- else if(to == u_raster) {
- copy_matrix(result, kernel_data.cam.worldtoraster);
- return true;
- }
- else if(to == u_screen) {
- copy_matrix(result, kernel_data.cam.worldtoscreen);
- return true;
- }
- else if(to == u_camera) {
- copy_matrix(result, kernel_data.cam.worldtocamera);
- return true;
- }
- else if(to == u_world) {
- result.makeIdentity();
- return true;
- }
-
- return false;
+ KernelGlobals *kg = kernel_globals;
+
+ if (to == u_ndc) {
+ copy_matrix(result, kernel_data.cam.worldtondc);
+ return true;
+ }
+ else if (to == u_raster) {
+ copy_matrix(result, kernel_data.cam.worldtoraster);
+ return true;
+ }
+ else if (to == u_screen) {
+ copy_matrix(result, kernel_data.cam.worldtoscreen);
+ return true;
+ }
+ else if (to == u_camera) {
+ copy_matrix(result, kernel_data.cam.worldtocamera);
+ return true;
+ }
+ else if (to == u_world) {
+ result.makeIdentity();
+ return true;
+ }
+
+ return false;
}
-bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform)
+bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform)
{
- /* this is only used for shader and object space, we don't really have
- * a concept of shader space, so we just use object space for both. */
- if(xform) {
- const ShaderData *sd = (const ShaderData *)xform;
- int object = sd->object;
+ /* this is only used for shader and object space, we don't really have
+ * a concept of shader space, so we just use object space for both. */
+ if (xform) {
+ const ShaderData *sd = (const ShaderData *)xform;
+ int object = sd->object;
- if(object != OBJECT_NONE) {
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
+ Transform tfm = sd->ob_tfm;
#else
- KernelGlobals *kg = sd->osl_globals;
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ KernelGlobals *kg = sd->osl_globals;
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
- copy_matrix(result, tfm);
+ copy_matrix(result, tfm);
- return true;
- }
- else if(sd->type == PRIMITIVE_LAMP) {
- copy_matrix(result, sd->ob_tfm);
+ return true;
+ }
+ else if (sd->type == PRIMITIVE_LAMP) {
+ copy_matrix(result, sd->ob_tfm);
- return true;
- }
- }
+ return true;
+ }
+ }
- return false;
+ return false;
}
-bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform)
+bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform)
{
- /* this is only used for shader and object space, we don't really have
- * a concept of shader space, so we just use object space for both. */
- if(xform) {
- const ShaderData *sd = (const ShaderData *)xform;
- int object = sd->object;
+ /* this is only used for shader and object space, we don't really have
+ * a concept of shader space, so we just use object space for both. */
+ if (xform) {
+ const ShaderData *sd = (const ShaderData *)xform;
+ int object = sd->object;
- if(object != OBJECT_NONE) {
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
+ Transform tfm = sd->ob_itfm;
#else
- KernelGlobals *kg = sd->osl_globals;
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ KernelGlobals *kg = sd->osl_globals;
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
- copy_matrix(result, tfm);
+ copy_matrix(result, tfm);
- return true;
- }
- else if(sd->type == PRIMITIVE_LAMP) {
- copy_matrix(result, sd->ob_itfm);
+ return true;
+ }
+ else if (sd->type == PRIMITIVE_LAMP) {
+ copy_matrix(result, sd->ob_itfm);
- return true;
- }
- }
+ return true;
+ }
+ }
- return false;
+ return false;
}
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from)
{
- KernelGlobals *kg = kernel_globals;
-
- if(from == u_ndc) {
- copy_matrix(result, kernel_data.cam.ndctoworld);
- return true;
- }
- else if(from == u_raster) {
- copy_matrix(result, kernel_data.cam.rastertoworld);
- return true;
- }
- else if(from == u_screen) {
- copy_matrix(result, kernel_data.cam.screentoworld);
- return true;
- }
- else if(from == u_camera) {
- copy_matrix(result, kernel_data.cam.cameratoworld);
- return true;
- }
-
- return false;
+ KernelGlobals *kg = kernel_globals;
+
+ if (from == u_ndc) {
+ copy_matrix(result, kernel_data.cam.ndctoworld);
+ return true;
+ }
+ else if (from == u_raster) {
+ copy_matrix(result, kernel_data.cam.rastertoworld);
+ return true;
+ }
+ else if (from == u_screen) {
+ copy_matrix(result, kernel_data.cam.screentoworld);
+ return true;
+ }
+ else if (from == u_camera) {
+ copy_matrix(result, kernel_data.cam.cameratoworld);
+ return true;
+ }
+
+ return false;
}
-bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring to)
+bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ ustring to)
{
- KernelGlobals *kg = kernel_globals;
-
- if(to == u_ndc) {
- copy_matrix(result, kernel_data.cam.worldtondc);
- return true;
- }
- else if(to == u_raster) {
- copy_matrix(result, kernel_data.cam.worldtoraster);
- return true;
- }
- else if(to == u_screen) {
- copy_matrix(result, kernel_data.cam.worldtoscreen);
- return true;
- }
- else if(to == u_camera) {
- copy_matrix(result, kernel_data.cam.worldtocamera);
- return true;
- }
-
- return false;
+ KernelGlobals *kg = kernel_globals;
+
+ if (to == u_ndc) {
+ copy_matrix(result, kernel_data.cam.worldtondc);
+ return true;
+ }
+ else if (to == u_raster) {
+ copy_matrix(result, kernel_data.cam.worldtoraster);
+ return true;
+ }
+ else if (to == u_screen) {
+ copy_matrix(result, kernel_data.cam.worldtoscreen);
+ return true;
+ }
+ else if (to == u_camera) {
+ copy_matrix(result, kernel_data.cam.worldtocamera);
+ return true;
+ }
+
+ return false;
}
-bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg, bool derivatives,
- ustring object, TypeDesc type, ustring name,
- int index, void *val)
+bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg,
+ bool derivatives,
+ ustring object,
+ TypeDesc type,
+ ustring name,
+ int index,
+ void *val)
{
- return false;
+ return false;
}
static bool set_attribute_float2(float2 f[3], TypeDesc type, bool derivatives, void *val)
{
- if(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
- type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor)
- {
- float *fval = (float *)val;
-
- fval[0] = f[0].x;
- fval[1] = f[0].y;
- fval[2] = 0.0f;
-
- if(derivatives) {
- fval[3] = f[1].x;
- fval[4] = f[1].y;
- fval[5] = 0.0f;
-
- fval[6] = f[2].x;
- fval[7] = f[2].y;
- fval[8] = 0.0f;
- }
-
- return true;
- }
- else if(type == TypeDesc::TypeFloat) {
- float *fval = (float *)val;
- fval[0] = average(f[0]);
-
- if(derivatives) {
- fval[1] = average(f[1]);
- fval[2] = average(f[2]);
- }
-
- return true;
- }
-
- return false;
+ if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
+ type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) {
+ float *fval = (float *)val;
+
+ fval[0] = f[0].x;
+ fval[1] = f[0].y;
+ fval[2] = 0.0f;
+
+ if (derivatives) {
+ fval[3] = f[1].x;
+ fval[4] = f[1].y;
+ fval[5] = 0.0f;
+
+ fval[6] = f[2].x;
+ fval[7] = f[2].y;
+ fval[8] = 0.0f;
+ }
+
+ return true;
+ }
+ else if (type == TypeDesc::TypeFloat) {
+ float *fval = (float *)val;
+ fval[0] = average(f[0]);
+
+ if (derivatives) {
+ fval[1] = average(f[1]);
+ fval[2] = average(f[2]);
+ }
+
+ return true;
+ }
+
+ return false;
}
static bool set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *val)
{
- if(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
- type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor)
- {
- float *fval = (float *)val;
-
- fval[0] = f[0].x;
- fval[1] = f[0].y;
- fval[2] = f[0].z;
-
- if(derivatives) {
- fval[3] = f[1].x;
- fval[4] = f[1].y;
- fval[5] = f[1].z;
-
- fval[6] = f[2].x;
- fval[7] = f[2].y;
- fval[8] = f[2].z;
- }
-
- return true;
- }
- else if(type == TypeDesc::TypeFloat) {
- float *fval = (float *)val;
- fval[0] = average(f[0]);
-
- if(derivatives) {
- fval[1] = average(f[1]);
- fval[2] = average(f[2]);
- }
-
- return true;
- }
-
- return false;
+ if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
+ type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) {
+ float *fval = (float *)val;
+
+ fval[0] = f[0].x;
+ fval[1] = f[0].y;
+ fval[2] = f[0].z;
+
+ if (derivatives) {
+ fval[3] = f[1].x;
+ fval[4] = f[1].y;
+ fval[5] = f[1].z;
+
+ fval[6] = f[2].x;
+ fval[7] = f[2].y;
+ fval[8] = f[2].z;
+ }
+
+ return true;
+ }
+ else if (type == TypeDesc::TypeFloat) {
+ float *fval = (float *)val;
+ fval[0] = average(f[0]);
+
+ if (derivatives) {
+ fval[1] = average(f[1]);
+ fval[2] = average(f[2]);
+ }
+
+ return true;
+ }
+
+ return false;
}
static bool set_attribute_float3(float3 f, TypeDesc type, bool derivatives, void *val)
{
- float3 fv[3];
+ float3 fv[3];
- fv[0] = f;
- fv[1] = make_float3(0.0f, 0.0f, 0.0f);
- fv[2] = make_float3(0.0f, 0.0f, 0.0f);
+ fv[0] = f;
+ fv[1] = make_float3(0.0f, 0.0f, 0.0f);
+ fv[2] = make_float3(0.0f, 0.0f, 0.0f);
- return set_attribute_float3(fv, type, derivatives, val);
+ return set_attribute_float3(fv, type, derivatives, val);
}
static bool set_attribute_float(float f[3], TypeDesc type, bool derivatives, void *val)
{
- if(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
- type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor)
- {
- float *fval = (float *)val;
- fval[0] = f[0];
- fval[1] = f[1];
- fval[2] = f[2];
-
- if(derivatives) {
- fval[3] = f[1];
- fval[4] = f[1];
- fval[5] = f[1];
-
- fval[6] = f[2];
- fval[7] = f[2];
- fval[8] = f[2];
- }
-
- return true;
- }
- else if(type == TypeDesc::TypeFloat) {
- float *fval = (float *)val;
- fval[0] = f[0];
-
- if(derivatives) {
- fval[1] = f[1];
- fval[2] = f[2];
- }
-
- return true;
- }
-
- return false;
+ if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
+ type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) {
+ float *fval = (float *)val;
+ fval[0] = f[0];
+ fval[1] = f[1];
+ fval[2] = f[2];
+
+ if (derivatives) {
+ fval[3] = f[1];
+ fval[4] = f[1];
+ fval[5] = f[1];
+
+ fval[6] = f[2];
+ fval[7] = f[2];
+ fval[8] = f[2];
+ }
+
+ return true;
+ }
+ else if (type == TypeDesc::TypeFloat) {
+ float *fval = (float *)val;
+ fval[0] = f[0];
+
+ if (derivatives) {
+ fval[1] = f[1];
+ fval[2] = f[2];
+ }
+
+ return true;
+ }
+
+ return false;
}
static bool set_attribute_float(float f, TypeDesc type, bool derivatives, void *val)
{
- float fv[3];
+ float fv[3];
- fv[0] = f;
- fv[1] = 0.0f;
- fv[2] = 0.0f;
+ fv[0] = f;
+ fv[1] = 0.0f;
+ fv[2] = 0.0f;
- return set_attribute_float(fv, type, derivatives, val);
+ return set_attribute_float(fv, type, derivatives, val);
}
static bool set_attribute_int(int i, TypeDesc type, bool derivatives, void *val)
{
- if(type.basetype == TypeDesc::INT && type.aggregate == TypeDesc::SCALAR && type.arraylen == 0) {
- int *ival = (int *)val;
- ival[0] = i;
+ if (type.basetype == TypeDesc::INT && type.aggregate == TypeDesc::SCALAR && type.arraylen == 0) {
+ int *ival = (int *)val;
+ ival[0] = i;
- if(derivatives) {
- ival[1] = 0;
- ival[2] = 0;
- }
+ if (derivatives) {
+ ival[1] = 0;
+ ival[2] = 0;
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
static bool set_attribute_string(ustring str, TypeDesc type, bool derivatives, void *val)
{
- if(type.basetype == TypeDesc::STRING && type.aggregate == TypeDesc::SCALAR && type.arraylen == 0) {
- ustring *sval = (ustring *)val;
- sval[0] = str;
+ if (type.basetype == TypeDesc::STRING && type.aggregate == TypeDesc::SCALAR &&
+ type.arraylen == 0) {
+ ustring *sval = (ustring *)val;
+ sval[0] = str;
- if(derivatives) {
- sval[1] = OSLRenderServices::u_empty;
- sval[2] = OSLRenderServices::u_empty;
- }
+ if (derivatives) {
+ sval[1] = OSLRenderServices::u_empty;
+ sval[2] = OSLRenderServices::u_empty;
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
static bool set_attribute_float3_3(float3 P[3], TypeDesc type, bool derivatives, void *val)
{
- if(type.vecsemantics == TypeDesc::POINT && type.arraylen >= 3) {
- float *fval = (float *)val;
+ if (type.vecsemantics == TypeDesc::POINT && type.arraylen >= 3) {
+ float *fval = (float *)val;
- fval[0] = P[0].x;
- fval[1] = P[0].y;
- fval[2] = P[0].z;
+ fval[0] = P[0].x;
+ fval[1] = P[0].y;
+ fval[2] = P[0].z;
- fval[3] = P[1].x;
- fval[4] = P[1].y;
- fval[5] = P[1].z;
+ fval[3] = P[1].x;
+ fval[4] = P[1].y;
+ fval[5] = P[1].z;
- fval[6] = P[2].x;
- fval[7] = P[2].y;
- fval[8] = P[2].z;
+ fval[6] = P[2].x;
+ fval[7] = P[2].y;
+ fval[8] = P[2].z;
- if(type.arraylen > 3)
- memset(fval + 3*3, 0, sizeof(float)*3*(type.arraylen - 3));
- if(derivatives)
- memset(fval + type.arraylen*3, 0, sizeof(float)*2*3*type.arraylen);
+ if (type.arraylen > 3)
+ memset(fval + 3 * 3, 0, sizeof(float) * 3 * (type.arraylen - 3));
+ if (derivatives)
+ memset(fval + type.arraylen * 3, 0, sizeof(float) * 2 * 3 * type.arraylen);
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-static bool set_attribute_matrix(const Transform& tfm, TypeDesc type, void *val)
+static bool set_attribute_matrix(const Transform &tfm, TypeDesc type, void *val)
{
- if(type == TypeDesc::TypeMatrix) {
- copy_matrix(*(OSL::Matrix44*)val, tfm);
- return true;
- }
+ if (type == TypeDesc::TypeMatrix) {
+ copy_matrix(*(OSL::Matrix44 *)val, tfm);
+ return true;
+ }
- return false;
+ return false;
}
-static bool get_primitive_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
- const TypeDesc& type, bool derivatives, void *val)
+static bool get_primitive_attribute(KernelGlobals *kg,
+ const ShaderData *sd,
+ const OSLGlobals::Attribute &attr,
+ const TypeDesc &type,
+ bool derivatives,
+ void *val)
{
- if(attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
- {
- float3 fval[3];
- fval[0] = primitive_attribute_float3(kg, sd, attr.desc,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
- return set_attribute_float3(fval, type, derivatives, val);
- }
- else if(attr.type == TypeFloat2) {
- float2 fval[2];
- fval[0] = primitive_attribute_float2(kg, sd, attr.desc,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
- return set_attribute_float2(fval, type, derivatives, val);
- }
- else if(attr.type == TypeDesc::TypeFloat) {
- float fval[3];
- fval[0] = primitive_attribute_float(kg, sd, attr.desc,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
- return set_attribute_float(fval, type, derivatives, val);
- }
- else {
- return false;
- }
+ if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
+ attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
+ float3 fval[3];
+ fval[0] = primitive_attribute_float3(
+ kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ return set_attribute_float3(fval, type, derivatives, val);
+ }
+ else if (attr.type == TypeFloat2) {
+ float2 fval[2];
+ fval[0] = primitive_attribute_float2(
+ kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ return set_attribute_float2(fval, type, derivatives, val);
+ }
+ else if (attr.type == TypeDesc::TypeFloat) {
+ float fval[3];
+ fval[0] = primitive_attribute_float(
+ kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ return set_attribute_float(fval, type, derivatives, val);
+ }
+ else {
+ return false;
+ }
}
-static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
- const TypeDesc& type, bool derivatives, void *val)
+static bool get_mesh_attribute(KernelGlobals *kg,
+ const ShaderData *sd,
+ const OSLGlobals::Attribute &attr,
+ const TypeDesc &type,
+ bool derivatives,
+ void *val)
{
- if(attr.type == TypeDesc::TypeMatrix) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc);
- return set_attribute_matrix(tfm, type, val);
- }
- else {
- return false;
- }
+ if (attr.type == TypeDesc::TypeMatrix) {
+ Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc);
+ return set_attribute_matrix(tfm, type, val);
+ }
+ else {
+ return false;
+ }
}
-static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
+static void get_object_attribute(const OSLGlobals::Attribute &attr, bool derivatives, void *val)
{
- size_t datasize = attr.value.datasize();
+ size_t datasize = attr.value.datasize();
- memcpy(val, attr.value.data(), datasize);
- if(derivatives)
- memset((char *)val + datasize, 0, datasize * 2);
+ memcpy(val, attr.value.data(), datasize);
+ if (derivatives)
+ memset((char *)val + datasize, 0, datasize * 2);
}
-bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val)
+bool OSLRenderServices::get_object_standard_attribute(
+ KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val)
{
- /* todo: turn this into hash table? */
-
- /* Object Attributes */
- if(name == u_object_location) {
- float3 f = object_location(kg, sd);
- return set_attribute_float3(f, type, derivatives, val);
- }
- else if(name == u_object_index) {
- float f = object_pass_id(kg, sd->object);
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_geom_dupli_generated) {
- float3 f = object_dupli_generated(kg, sd->object);
- return set_attribute_float3(f, type, derivatives, val);
- }
- else if(name == u_geom_dupli_uv) {
- float3 f = object_dupli_uv(kg, sd->object);
- return set_attribute_float3(f, type, derivatives, val);
- }
- else if(name == u_material_index) {
- float f = shader_pass_id(kg, sd);
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_object_random) {
- float f = object_random_number(kg, sd->object);
- return set_attribute_float(f, type, derivatives, val);
- }
-
- /* Particle Attributes */
- else if(name == u_particle_index) {
- int particle_id = object_particle_id(kg, sd->object);
- float f = particle_index(kg, particle_id);
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_particle_random) {
- int particle_id = object_particle_id(kg, sd->object);
- float f = hash_int_01(particle_index(kg, particle_id));
- return set_attribute_float(f, type, derivatives, val);
- }
-
- else if(name == u_particle_age) {
- int particle_id = object_particle_id(kg, sd->object);
- float f = particle_age(kg, particle_id);
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_particle_lifetime) {
- int particle_id = object_particle_id(kg, sd->object);
- float f = particle_lifetime(kg, particle_id);
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_particle_location) {
- int particle_id = object_particle_id(kg, sd->object);
- float3 f = particle_location(kg, particle_id);
- return set_attribute_float3(f, type, derivatives, val);
- }
-#if 0 /* unsupported */
- else if(name == u_particle_rotation) {
- int particle_id = object_particle_id(kg, sd->object);
- float4 f = particle_rotation(kg, particle_id);
- return set_attribute_float4(f, type, derivatives, val);
- }
+ /* todo: turn this into hash table? */
+
+ /* Object Attributes */
+ if (name == u_object_location) {
+ float3 f = object_location(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == u_object_index) {
+ float f = object_pass_id(kg, sd->object);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_geom_dupli_generated) {
+ float3 f = object_dupli_generated(kg, sd->object);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == u_geom_dupli_uv) {
+ float3 f = object_dupli_uv(kg, sd->object);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == u_material_index) {
+ float f = shader_pass_id(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_object_random) {
+ float f = object_random_number(kg, sd->object);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+
+ /* Particle Attributes */
+ else if (name == u_particle_index) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float f = particle_index(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_particle_random) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float f = hash_int_01(particle_index(kg, particle_id));
+ return set_attribute_float(f, type, derivatives, val);
+ }
+
+ else if (name == u_particle_age) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float f = particle_age(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_particle_lifetime) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float f = particle_lifetime(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_particle_location) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float3 f = particle_location(kg, particle_id);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+#if 0 /* unsupported */
+ else if(name == u_particle_rotation) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float4 f = particle_rotation(kg, particle_id);
+ return set_attribute_float4(f, type, derivatives, val);
+ }
#endif
- else if(name == u_particle_size) {
- int particle_id = object_particle_id(kg, sd->object);
- float f = particle_size(kg, particle_id);
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_particle_velocity) {
- int particle_id = object_particle_id(kg, sd->object);
- float3 f = particle_velocity(kg, particle_id);
- return set_attribute_float3(f, type, derivatives, val);
- }
- else if(name == u_particle_angular_velocity) {
- int particle_id = object_particle_id(kg, sd->object);
- float3 f = particle_angular_velocity(kg, particle_id);
- return set_attribute_float3(f, type, derivatives, val);
- }
-
- /* Geometry Attributes */
- else if(name == u_geom_numpolyvertices) {
- return set_attribute_int(3, type, derivatives, val);
- }
- else if((name == u_geom_trianglevertices || name == u_geom_polyvertices)
- && sd->type & PRIMITIVE_ALL_TRIANGLE)
- {
- float3 P[3];
-
- if(sd->type & PRIMITIVE_TRIANGLE)
- triangle_vertices(kg, sd->prim, P);
- else
- motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P);
-
- if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_position_transform(kg, sd, &P[0]);
- object_position_transform(kg, sd, &P[1]);
- object_position_transform(kg, sd, &P[2]);
- }
-
- return set_attribute_float3_3(P, type, derivatives, val);
- }
- else if(name == u_geom_name) {
- ustring object_name = kg->osl->object_names[sd->object];
- return set_attribute_string(object_name, type, derivatives, val);
- }
- else if(name == u_is_smooth) {
- float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
- return set_attribute_float(f, type, derivatives, val);
- }
- /* Hair Attributes */
- else if(name == u_is_curve) {
- float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_curve_thickness) {
- float f = curve_thickness(kg, sd);
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_curve_tangent_normal) {
- float3 f = curve_tangent_normal(kg, sd);
- return set_attribute_float3(f, type, derivatives, val);
- }
- else
- return false;
+ else if (name == u_particle_size) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float f = particle_size(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_particle_velocity) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float3 f = particle_velocity(kg, particle_id);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == u_particle_angular_velocity) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float3 f = particle_angular_velocity(kg, particle_id);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+
+ /* Geometry Attributes */
+ else if (name == u_geom_numpolyvertices) {
+ return set_attribute_int(3, type, derivatives, val);
+ }
+ else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) &&
+ sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ float3 P[3];
+
+ if (sd->type & PRIMITIVE_TRIANGLE)
+ triangle_vertices(kg, sd->prim, P);
+ else
+ motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P);
+
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_position_transform(kg, sd, &P[0]);
+ object_position_transform(kg, sd, &P[1]);
+ object_position_transform(kg, sd, &P[2]);
+ }
+
+ return set_attribute_float3_3(P, type, derivatives, val);
+ }
+ else if (name == u_geom_name) {
+ ustring object_name = kg->osl->object_names[sd->object];
+ return set_attribute_string(object_name, type, derivatives, val);
+ }
+ else if (name == u_is_smooth) {
+ float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ /* Hair Attributes */
+ else if (name == u_is_curve) {
+ float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_curve_thickness) {
+ float f = curve_thickness(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_curve_tangent_normal) {
+ float3 f = curve_tangent_normal(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else
+ return false;
}
-bool OSLRenderServices::get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val)
+bool OSLRenderServices::get_background_attribute(
+ KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val)
{
- if(name == u_path_ray_length) {
- /* Ray Length */
- float f = sd->ray_length;
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_path_ray_depth) {
- /* Ray Depth */
- PathState *state = sd->osl_path_state;
- int f = state->bounce;
- return set_attribute_int(f, type, derivatives, val);
- }
- else if(name == u_path_diffuse_depth) {
- /* Diffuse Ray Depth */
- PathState *state = sd->osl_path_state;
- int f = state->diffuse_bounce;
- return set_attribute_int(f, type, derivatives, val);
- }
- else if(name == u_path_glossy_depth) {
- /* Glossy Ray Depth */
- PathState *state = sd->osl_path_state;
- int f = state->glossy_bounce;
- return set_attribute_int(f, type, derivatives, val);
- }
- else if(name == u_path_transmission_depth) {
- /* Transmission Ray Depth */
- PathState *state = sd->osl_path_state;
- int f = state->transmission_bounce;
- return set_attribute_int(f, type, derivatives, val);
- }
- else if(name == u_path_transparent_depth) {
- /* Transparent Ray Depth */
- PathState *state = sd->osl_path_state;
- int f = state->transparent_bounce;
- return set_attribute_int(f, type, derivatives, val);
- }
- else if(name == u_path_transmission_depth) {
- /* Transmission Ray Depth */
- PathState *state = sd->osl_path_state;
- int f = state->transmission_bounce;
- return set_attribute_int(f, type, derivatives, val);
- }
- else if(name == u_ndc) {
- /* NDC coordinates with special exception for otho */
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- float3 ndc[3];
-
- if((globals->raytype & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
- ndc[0] = camera_world_to_ndc(kg, sd, sd->ray_P);
-
- if(derivatives) {
- ndc[1] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx) - ndc[0];
- ndc[2] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy) - ndc[0];
- }
- }
- else {
- ndc[0] = camera_world_to_ndc(kg, sd, sd->P);
-
- if(derivatives) {
- ndc[1] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx) - ndc[0];
- ndc[2] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy) - ndc[0];
- }
- }
-
- return set_attribute_float3(ndc, type, derivatives, val);
- }
- else
- return false;
+ if (name == u_path_ray_length) {
+ /* Ray Length */
+ float f = sd->ray_length;
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_path_ray_depth) {
+ /* Ray Depth */
+ PathState *state = sd->osl_path_state;
+ int f = state->bounce;
+ return set_attribute_int(f, type, derivatives, val);
+ }
+ else if (name == u_path_diffuse_depth) {
+ /* Diffuse Ray Depth */
+ PathState *state = sd->osl_path_state;
+ int f = state->diffuse_bounce;
+ return set_attribute_int(f, type, derivatives, val);
+ }
+ else if (name == u_path_glossy_depth) {
+ /* Glossy Ray Depth */
+ PathState *state = sd->osl_path_state;
+ int f = state->glossy_bounce;
+ return set_attribute_int(f, type, derivatives, val);
+ }
+ else if (name == u_path_transmission_depth) {
+ /* Transmission Ray Depth */
+ PathState *state = sd->osl_path_state;
+ int f = state->transmission_bounce;
+ return set_attribute_int(f, type, derivatives, val);
+ }
+ else if (name == u_path_transparent_depth) {
+ /* Transparent Ray Depth */
+ PathState *state = sd->osl_path_state;
+ int f = state->transparent_bounce;
+ return set_attribute_int(f, type, derivatives, val);
+ }
+ else if (name == u_path_transmission_depth) {
+ /* Transmission Ray Depth */
+ PathState *state = sd->osl_path_state;
+ int f = state->transmission_bounce;
+ return set_attribute_int(f, type, derivatives, val);
+ }
+ else if (name == u_ndc) {
+ /* NDC coordinates with special exception for otho */
+ OSLThreadData *tdata = kg->osl_tdata;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ float3 ndc[3];
+
+ if ((globals->raytype & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
+ kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
+ ndc[0] = camera_world_to_ndc(kg, sd, sd->ray_P);
+
+ if (derivatives) {
+ ndc[1] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx) - ndc[0];
+ ndc[2] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy) - ndc[0];
+ }
+ }
+ else {
+ ndc[0] = camera_world_to_ndc(kg, sd, sd->P);
+
+ if (derivatives) {
+ ndc[1] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx) - ndc[0];
+ ndc[2] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy) - ndc[0];
+ }
+ }
+
+ return set_attribute_float3(ndc, type, derivatives, val);
+ }
+ else
+ return false;
}
-bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg, bool derivatives, ustring object_name,
- TypeDesc type, ustring name, void *val)
+bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
+ bool derivatives,
+ ustring object_name,
+ TypeDesc type,
+ ustring name,
+ void *val)
{
- if(sg == NULL || sg->renderstate == NULL)
- return false;
+ if (sg == NULL || sg->renderstate == NULL)
+ return false;
- ShaderData *sd = (ShaderData *)(sg->renderstate);
- return get_attribute(sd, derivatives, object_name, type, name, val);
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ return get_attribute(sd, derivatives, object_name, type, name, val);
}
-bool OSLRenderServices::get_attribute(ShaderData *sd, bool derivatives, ustring object_name,
- TypeDesc type, ustring name, void *val)
+bool OSLRenderServices::get_attribute(
+ ShaderData *sd, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val)
{
- KernelGlobals *kg = sd->osl_globals;
- int prim_type = 0;
- int object;
-
- /* lookup of attribute on another object */
- if(object_name != u_empty) {
- OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
-
- if(it == kg->osl->object_name_map.end())
- return false;
-
- object = it->second;
- }
- else {
- object = sd->object;
- prim_type = attribute_primitive_type(kg, sd);
-
- if(object == OBJECT_NONE)
- return get_background_attribute(kg, sd, name, type, derivatives, val);
- }
-
- /* find attribute on object */
- object = object*ATTR_PRIM_TYPES + prim_type;
- OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
- OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
-
- if(it != attribute_map.end()) {
- const OSLGlobals::Attribute& attr = it->second;
-
- if(attr.desc.element != ATTR_ELEMENT_OBJECT) {
- /* triangle and vertex attributes */
- if(get_primitive_attribute(kg, sd, attr, type, derivatives, val))
- return true;
- else
- return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
- }
- else {
- /* object attribute */
- get_object_attribute(attr, derivatives, val);
- return true;
- }
- }
- else {
- /* not found in attribute, check standard object info */
- bool is_std_object_attribute = get_object_standard_attribute(kg, sd, name, type, derivatives, val);
-
- if(is_std_object_attribute)
- return true;
-
- return get_background_attribute(kg, sd, name, type, derivatives, val);
- }
-
- return false;
+ KernelGlobals *kg = sd->osl_globals;
+ int prim_type = 0;
+ int object;
+
+ /* lookup of attribute on another object */
+ if (object_name != u_empty) {
+ OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
+
+ if (it == kg->osl->object_name_map.end())
+ return false;
+
+ object = it->second;
+ }
+ else {
+ object = sd->object;
+ prim_type = attribute_primitive_type(kg, sd);
+
+ if (object == OBJECT_NONE)
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
+ }
+
+ /* find attribute on object */
+ object = object * ATTR_PRIM_TYPES + prim_type;
+ OSLGlobals::AttributeMap &attribute_map = kg->osl->attribute_map[object];
+ OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
+
+ if (it != attribute_map.end()) {
+ const OSLGlobals::Attribute &attr = it->second;
+
+ if (attr.desc.element != ATTR_ELEMENT_OBJECT) {
+ /* triangle and vertex attributes */
+ if (get_primitive_attribute(kg, sd, attr, type, derivatives, val))
+ return true;
+ else
+ return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
+ }
+ else {
+ /* object attribute */
+ get_object_attribute(attr, derivatives, val);
+ return true;
+ }
+ }
+ else {
+ /* not found in attribute, check standard object info */
+ bool is_std_object_attribute = get_object_standard_attribute(
+ kg, sd, name, type, derivatives, val);
+
+ if (is_std_object_attribute)
+ return true;
+
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
+ }
+
+ return false;
}
-bool OSLRenderServices::get_userdata(bool derivatives, ustring name, TypeDesc type,
- OSL::ShaderGlobals *sg, void *val)
+bool OSLRenderServices::get_userdata(
+ bool derivatives, ustring name, TypeDesc type, OSL::ShaderGlobals *sg, void *val)
{
- return false; /* disabled by lockgeom */
+ return false; /* disabled by lockgeom */
}
TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring filename)
{
- if(filename.length() && filename[0] == '@') {
- /* Dummy, we don't use texture handles for builtin textures but need
- * to tell the OSL runtime optimizer that this is a valid texture. */
- return NULL;
- }
- else {
- return texturesys()->get_texture_handle(filename);
- }
+ if (filename.length() && filename[0] == '@') {
+ /* Dummy, we don't use texture handles for builtin textures but need
+ * to tell the OSL runtime optimizer that this is a valid texture. */
+ return NULL;
+ }
+ else {
+ return texturesys()->get_texture_handle(filename);
+ }
}
bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle)
{
- return texturesys()->good(texture_handle);
+ return texturesys()->good(texture_handle);
}
bool OSLRenderServices::texture(ustring filename,
@@ -945,157 +976,169 @@ bool OSLRenderServices::texture(ustring filename,
TexturePerthread *texture_thread_info,
TextureOpt &options,
OSL::ShaderGlobals *sg,
- float s, float t,
- float dsdx, float dtdx, float dsdy, float dtdy,
+ float s,
+ float t,
+ float dsdx,
+ float dtdx,
+ float dsdy,
+ float dtdy,
int nchannels,
float *result,
float *dresultds,
float *dresultdt,
ustring *errormessage)
{
- OSL::TextureSystem *ts = osl_ts;
- ShaderData *sd = (ShaderData *)(sg->renderstate);
- KernelGlobals *kg = sd->osl_globals;
+ OSL::TextureSystem *ts = osl_ts;
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kg = sd->osl_globals;
- if(texture_thread_info == NULL) {
- OSLThreadData *tdata = kg->osl_tdata;
- texture_thread_info = tdata->oiio_thread_info;
- }
+ if (texture_thread_info == NULL) {
+ OSLThreadData *tdata = kg->osl_tdata;
+ texture_thread_info = tdata->oiio_thread_info;
+ }
#ifdef WITH_PTEX
- /* todo: this is just a quick hack, only works with particular files and options */
- if(string_endswith(filename.string(), ".ptx")) {
- float2 uv;
- int faceid;
+ /* todo: this is just a quick hack, only works with particular files and options */
+ if (string_endswith(filename.string(), ".ptx")) {
+ float2 uv;
+ int faceid;
- if(!primitive_ptex(kg, sd, &uv, &faceid))
- return false;
+ if (!primitive_ptex(kg, sd, &uv, &faceid))
+ return false;
- float u = uv.x;
- float v = uv.y;
- float dudx = 0.0f;
- float dvdx = 0.0f;
- float dudy = 0.0f;
- float dvdy = 0.0f;
+ float u = uv.x;
+ float v = uv.y;
+ float dudx = 0.0f;
+ float dvdx = 0.0f;
+ float dudy = 0.0f;
+ float dvdy = 0.0f;
- Ptex::String error;
- PtexPtr<PtexTexture> r(ptex_cache->get(filename.c_str(), error));
+ Ptex::String error;
+ PtexPtr<PtexTexture> r(ptex_cache->get(filename.c_str(), error));
- if(!r) {
- //std::cerr << error.c_str() << std::endl;
- return false;
- }
+ if (!r) {
+ //std::cerr << error.c_str() << std::endl;
+ return false;
+ }
- bool mipmaplerp = false;
- float sharpness = 1.0f;
- PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness);
- PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts));
+ bool mipmaplerp = false;
+ float sharpness = 1.0f;
+ PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness);
+ PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts));
- f->eval(result, options.firstchannel, nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
+ f->eval(result, options.firstchannel, nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
- for(int c = r->numChannels(); c < nchannels; c++)
- result[c] = result[0];
+ for (int c = r->numChannels(); c < nchannels; c++)
+ result[c] = result[0];
- return true;
- }
+ return true;
+ }
#endif
- bool status = false;
-
- if(filename.length() && filename[0] == '@') {
- if(filename == u_at_bevel) {
- /* Bevel shader hack. */
- if(nchannels >= 3) {
- PathState *state = sd->osl_path_state;
- int num_samples = (int)s;
- float radius = t;
- float3 N = svm_bevel(kg, sd, state, radius, num_samples);
- result[0] = N.x;
- result[1] = N.y;
- result[2] = N.z;
- status = true;
- }
- }
- else if(filename == u_at_ao) {
- /* AO shader hack. */
- PathState *state = sd->osl_path_state;
- int num_samples = (int)s;
- float radius = t;
- float3 N = make_float3(dsdx, dtdx, dsdy);
- int flags = 0;
- if((int)dtdy) {
- flags |= NODE_AO_INSIDE;
- }
- if((int)options.sblur) {
- flags |= NODE_AO_ONLY_LOCAL;
- }
- if((int)options.tblur) {
- flags |= NODE_AO_GLOBAL_RADIUS;
- }
- result[0] = svm_ao(kg, sd, N, state, radius, num_samples, flags);
- status = true;
- }
- else if(filename[1] == 'l') {
- /* IES light. */
- int slot = atoi(filename.c_str() + 2);
- result[0] = kernel_ies_interp(kg, slot, s, t);
- status = true;
- }
- else {
- /* Packed texture. */
- int slot = atoi(filename.c_str() + 2);
- float4 rgba = kernel_tex_image_interp(kg, slot, s, 1.0f - t);
-
- result[0] = rgba[0];
- if(nchannels > 1)
- result[1] = rgba[1];
- if(nchannels > 2)
- result[2] = rgba[2];
- if(nchannels > 3)
- result[3] = rgba[3];
- status = true;
- }
- }
- else {
- if(texture_handle != NULL) {
- status = ts->texture(texture_handle,
- texture_thread_info,
- options,
- s, t,
- dsdx, dtdx,
- dsdy, dtdy,
- nchannels,
- result,
- dresultds, dresultdt);
- }
- else {
- status = ts->texture(filename,
- options,
- s, t,
- dsdx, dtdx,
- dsdy, dtdy,
- nchannels,
- result,
- dresultds, dresultdt);
- }
- }
-
- if(!status) {
- if(nchannels == 3 || nchannels == 4) {
- result[0] = 1.0f;
- result[1] = 0.0f;
- result[2] = 1.0f;
-
- if(nchannels == 4)
- result[3] = 1.0f;
- }
- /* This might be slow, but prevents error messages leak and
- * other nasty stuff happening.
- */
- string err = ts->geterror();
- (void) err;
- }
-
- return status;
+ bool status = false;
+
+ if (filename.length() && filename[0] == '@') {
+ if (filename == u_at_bevel) {
+ /* Bevel shader hack. */
+ if (nchannels >= 3) {
+ PathState *state = sd->osl_path_state;
+ int num_samples = (int)s;
+ float radius = t;
+ float3 N = svm_bevel(kg, sd, state, radius, num_samples);
+ result[0] = N.x;
+ result[1] = N.y;
+ result[2] = N.z;
+ status = true;
+ }
+ }
+ else if (filename == u_at_ao) {
+ /* AO shader hack. */
+ PathState *state = sd->osl_path_state;
+ int num_samples = (int)s;
+ float radius = t;
+ float3 N = make_float3(dsdx, dtdx, dsdy);
+ int flags = 0;
+ if ((int)dtdy) {
+ flags |= NODE_AO_INSIDE;
+ }
+ if ((int)options.sblur) {
+ flags |= NODE_AO_ONLY_LOCAL;
+ }
+ if ((int)options.tblur) {
+ flags |= NODE_AO_GLOBAL_RADIUS;
+ }
+ result[0] = svm_ao(kg, sd, N, state, radius, num_samples, flags);
+ status = true;
+ }
+ else if (filename[1] == 'l') {
+ /* IES light. */
+ int slot = atoi(filename.c_str() + 2);
+ result[0] = kernel_ies_interp(kg, slot, s, t);
+ status = true;
+ }
+ else {
+ /* Packed texture. */
+ int slot = atoi(filename.c_str() + 2);
+ float4 rgba = kernel_tex_image_interp(kg, slot, s, 1.0f - t);
+
+ result[0] = rgba[0];
+ if (nchannels > 1)
+ result[1] = rgba[1];
+ if (nchannels > 2)
+ result[2] = rgba[2];
+ if (nchannels > 3)
+ result[3] = rgba[3];
+ status = true;
+ }
+ }
+ else {
+ if (texture_handle != NULL) {
+ status = ts->texture(texture_handle,
+ texture_thread_info,
+ options,
+ s,
+ t,
+ dsdx,
+ dtdx,
+ dsdy,
+ dtdy,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt);
+ }
+ else {
+ status = ts->texture(filename,
+ options,
+ s,
+ t,
+ dsdx,
+ dtdx,
+ dsdy,
+ dtdy,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt);
+ }
+ }
+
+ if (!status) {
+ if (nchannels == 3 || nchannels == 4) {
+ result[0] = 1.0f;
+ result[1] = 0.0f;
+ result[2] = 1.0f;
+
+ if (nchannels == 4)
+ result[3] = 1.0f;
+ }
+ /* This might be slow, but prevents error messages leak and
+ * other nasty stuff happening.
+ */
+ string err = ts->geterror();
+ (void)err;
+ }
+
+ return status;
}
bool OSLRenderServices::texture3d(ustring filename,
@@ -1114,68 +1157,76 @@ bool OSLRenderServices::texture3d(ustring filename,
float *dresultdr,
ustring *errormessage)
{
- OSL::TextureSystem *ts = osl_ts;
- ShaderData *sd = (ShaderData *)(sg->renderstate);
- KernelGlobals *kg = sd->osl_globals;
-
- if(texture_thread_info == NULL) {
- OSLThreadData *tdata = kg->osl_tdata;
- texture_thread_info = tdata->oiio_thread_info;
- }
-
- bool status;
- if(filename.length() && filename[0] == '@') {
- int slot = atoi(filename.c_str() + 1);
- float4 rgba = kernel_tex_image_interp_3d(kg, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
-
- result[0] = rgba[0];
- if(nchannels > 1)
- result[1] = rgba[1];
- if(nchannels > 2)
- result[2] = rgba[2];
- if(nchannels > 3)
- result[3] = rgba[3];
- status = true;
- }
- else {
- if(texture_handle != NULL) {
- status = ts->texture3d(texture_handle,
- texture_thread_info,
- options,
- P,
- dPdx, dPdy, dPdz,
- nchannels,
- result,
- dresultds, dresultdt, dresultdr);
- }
- else {
- status = ts->texture3d(filename,
- options,
- P,
- dPdx, dPdy, dPdz,
- nchannels,
- result,
- dresultds, dresultdt, dresultdr);
- }
- }
-
- if(!status) {
- if(nchannels == 3 || nchannels == 4) {
- result[0] = 1.0f;
- result[1] = 0.0f;
- result[2] = 1.0f;
-
- if(nchannels == 4)
- result[3] = 1.0f;
- }
- /* This might be slow, but prevents error messages leak and
- * other nasty stuff happening.
- */
- string err = ts->geterror();
- (void) err;
- }
-
- return status;
+ OSL::TextureSystem *ts = osl_ts;
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kg = sd->osl_globals;
+
+ if (texture_thread_info == NULL) {
+ OSLThreadData *tdata = kg->osl_tdata;
+ texture_thread_info = tdata->oiio_thread_info;
+ }
+
+ bool status;
+ if (filename.length() && filename[0] == '@') {
+ int slot = atoi(filename.c_str() + 1);
+ float4 rgba = kernel_tex_image_interp_3d(kg, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
+
+ result[0] = rgba[0];
+ if (nchannels > 1)
+ result[1] = rgba[1];
+ if (nchannels > 2)
+ result[2] = rgba[2];
+ if (nchannels > 3)
+ result[3] = rgba[3];
+ status = true;
+ }
+ else {
+ if (texture_handle != NULL) {
+ status = ts->texture3d(texture_handle,
+ texture_thread_info,
+ options,
+ P,
+ dPdx,
+ dPdy,
+ dPdz,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt,
+ dresultdr);
+ }
+ else {
+ status = ts->texture3d(filename,
+ options,
+ P,
+ dPdx,
+ dPdy,
+ dPdz,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt,
+ dresultdr);
+ }
+ }
+
+ if (!status) {
+ if (nchannels == 3 || nchannels == 4) {
+ result[0] = 1.0f;
+ result[1] = 0.0f;
+ result[2] = 1.0f;
+
+ if (nchannels == 4)
+ result[3] = 1.0f;
+ }
+ /* This might be slow, but prevents error messages leak and
+ * other nasty stuff happening.
+ */
+ string err = ts->geterror();
+ (void)err;
+ }
+
+ return status;
}
bool OSLRenderServices::environment(ustring filename,
@@ -1192,35 +1243,34 @@ bool OSLRenderServices::environment(ustring filename,
float *dresultdt,
ustring *errormessage)
{
- OSL::TextureSystem *ts = osl_ts;
-
- if (thread_info == NULL) {
- ShaderData *sd = (ShaderData *)(sg->renderstate);
- KernelGlobals *kg = sd->osl_globals;
- OSLThreadData *tdata = kg->osl_tdata;
- thread_info = tdata->oiio_thread_info;
- }
-
- if (th == NULL) {
- th = ts->get_texture_handle(filename, thread_info);
- }
-
- bool status = ts->environment(th, thread_info,
- options, R, dRdx, dRdy,
- nchannels, result, dresultds, dresultdt);
-
- if(!status) {
- if(nchannels == 3 || nchannels == 4) {
- result[0] = 1.0f;
- result[1] = 0.0f;
- result[2] = 1.0f;
-
- if(nchannels == 4)
- result[3] = 1.0f;
- }
- }
-
- return status;
+ OSL::TextureSystem *ts = osl_ts;
+
+ if (thread_info == NULL) {
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kg = sd->osl_globals;
+ OSLThreadData *tdata = kg->osl_tdata;
+ thread_info = tdata->oiio_thread_info;
+ }
+
+ if (th == NULL) {
+ th = ts->get_texture_handle(filename, thread_info);
+ }
+
+ bool status = ts->environment(
+ th, thread_info, options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt);
+
+ if (!status) {
+ if (nchannels == 3 || nchannels == 4) {
+ result[0] = 1.0f;
+ result[1] = 0.0f;
+ result[2] = 1.0f;
+
+ if (nchannels == 4)
+ result[3] = 1.0f;
+ }
+ }
+
+ return status;
}
bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg,
@@ -1231,138 +1281,158 @@ bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg,
TypeDesc datatype,
void *data)
{
- OSL::TextureSystem *ts = osl_ts;
- if(filename.length() && filename[0] == '@') {
- /* Special builtin textures. */
- return false;
- }
- else {
- return ts->get_texture_info(filename, subimage, dataname, datatype, data);
- }
+ OSL::TextureSystem *ts = osl_ts;
+ if (filename.length() && filename[0] == '@') {
+ /* Special builtin textures. */
+ return false;
+ }
+ else {
+ return ts->get_texture_info(filename, subimage, dataname, datatype, data);
+ }
}
-int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg, ustring filename, const OSL::Vec3 &center,
- float radius, int max_points, bool sort,
- size_t *out_indices, float *out_distances, int derivs_offset)
+int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg,
+ ustring filename,
+ const OSL::Vec3 &center,
+ float radius,
+ int max_points,
+ bool sort,
+ size_t *out_indices,
+ float *out_distances,
+ int derivs_offset)
{
- return 0;
+ return 0;
}
-int OSLRenderServices::pointcloud_get(OSL::ShaderGlobals *sg, ustring filename, size_t *indices, int count,
- ustring attr_name, TypeDesc attr_type, void *out_data)
+int OSLRenderServices::pointcloud_get(OSL::ShaderGlobals *sg,
+ ustring filename,
+ size_t *indices,
+ int count,
+ ustring attr_name,
+ TypeDesc attr_type,
+ void *out_data)
{
- return 0;
+ return 0;
}
bool OSLRenderServices::pointcloud_write(OSL::ShaderGlobals *sg,
- ustring filename, const OSL::Vec3 &pos,
- int nattribs, const ustring *names,
+ ustring filename,
+ const OSL::Vec3 &pos,
+ int nattribs,
+ const ustring *names,
const TypeDesc *types,
const void **data)
{
- return false;
+ return false;
}
-bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
- const OSL::Vec3 &P, const OSL::Vec3 &dPdx,
- const OSL::Vec3 &dPdy, const OSL::Vec3 &R,
- const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy)
+bool OSLRenderServices::trace(TraceOpt &options,
+ OSL::ShaderGlobals *sg,
+ const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx,
+ const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &R,
+ const OSL::Vec3 &dRdx,
+ const OSL::Vec3 &dRdy)
{
- /* todo: options.shader support, maybe options.traceset */
- ShaderData *sd = (ShaderData *)(sg->renderstate);
-
- /* setup ray */
- Ray ray;
-
- ray.P = TO_FLOAT3(P);
- ray.D = TO_FLOAT3(R);
- ray.t = (options.maxdist == 1.0e30f)? FLT_MAX: options.maxdist - options.mindist;
- ray.time = sd->time;
-
- if(options.mindist == 0.0f) {
- /* avoid self-intersections */
- if(ray.P == sd->P) {
- bool transmit = (dot(sd->Ng, ray.D) < 0.0f);
- ray.P = ray_offset(sd->P, (transmit)? -sd->Ng: sd->Ng);
- }
- }
- else {
- /* offset for minimum distance */
- ray.P += options.mindist*ray.D;
- }
-
- /* ray differentials */
- ray.dP.dx = TO_FLOAT3(dPdx);
- ray.dP.dy = TO_FLOAT3(dPdy);
- ray.dD.dx = TO_FLOAT3(dRdx);
- ray.dD.dy = TO_FLOAT3(dRdy);
-
- /* allocate trace data */
- OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
- tracedata->ray = ray;
- tracedata->setup = false;
- tracedata->init = true;
- tracedata->sd.osl_globals = sd->osl_globals;
-
- /* Raytrace, leaving out shadow opaque to avoid early exit. */
- uint visibility = PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE;
- return scene_intersect(sd->osl_globals, ray, visibility, &tracedata->isect, NULL, 0.0f, 0.0f);
+ /* todo: options.shader support, maybe options.traceset */
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+
+ /* setup ray */
+ Ray ray;
+
+ ray.P = TO_FLOAT3(P);
+ ray.D = TO_FLOAT3(R);
+ ray.t = (options.maxdist == 1.0e30f) ? FLT_MAX : options.maxdist - options.mindist;
+ ray.time = sd->time;
+
+ if (options.mindist == 0.0f) {
+ /* avoid self-intersections */
+ if (ray.P == sd->P) {
+ bool transmit = (dot(sd->Ng, ray.D) < 0.0f);
+ ray.P = ray_offset(sd->P, (transmit) ? -sd->Ng : sd->Ng);
+ }
+ }
+ else {
+ /* offset for minimum distance */
+ ray.P += options.mindist * ray.D;
+ }
+
+ /* ray differentials */
+ ray.dP.dx = TO_FLOAT3(dPdx);
+ ray.dP.dy = TO_FLOAT3(dPdy);
+ ray.dD.dx = TO_FLOAT3(dRdx);
+ ray.dD.dy = TO_FLOAT3(dRdy);
+
+ /* allocate trace data */
+ OSLTraceData *tracedata = (OSLTraceData *)sg->tracedata;
+ tracedata->ray = ray;
+ tracedata->setup = false;
+ tracedata->init = true;
+ tracedata->sd.osl_globals = sd->osl_globals;
+
+ /* Raytrace, leaving out shadow opaque to avoid early exit. */
+ uint visibility = PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE;
+ return scene_intersect(sd->osl_globals, ray, visibility, &tracedata->isect, NULL, 0.0f, 0.0f);
}
-
-bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
- TypeDesc type, void *val, bool derivatives)
+bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg,
+ ustring source,
+ ustring name,
+ TypeDesc type,
+ void *val,
+ bool derivatives)
{
- OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
-
- if(source == u_trace && tracedata->init) {
- if(name == u_hit) {
- return set_attribute_int((tracedata->isect.prim != PRIM_NONE), type, derivatives, val);
- }
- else if(tracedata->isect.prim != PRIM_NONE) {
- if(name == u_hitdist) {
- float f[3] = {tracedata->isect.t, 0.0f, 0.0f};
- return set_attribute_float(f, type, derivatives, val);
- }
- else {
- ShaderData *sd = &tracedata->sd;
- KernelGlobals *kg = sd->osl_globals;
-
- if(!tracedata->setup) {
- /* lazy shader data setup */
- shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray);
- tracedata->setup = true;
- }
-
- if(name == u_N) {
- return set_attribute_float3(sd->N, type, derivatives, val);
- }
- else if(name == u_Ng) {
- return set_attribute_float3(sd->Ng, type, derivatives, val);
- }
- else if(name == u_P) {
- float3 f[3] = {sd->P, sd->dP.dx, sd->dP.dy};
- return set_attribute_float3(f, type, derivatives, val);
- }
- else if(name == u_I) {
- float3 f[3] = {sd->I, sd->dI.dx, sd->dI.dy};
- return set_attribute_float3(f, type, derivatives, val);
- }
- else if(name == u_u) {
- float f[3] = {sd->u, sd->du.dx, sd->du.dy};
- return set_attribute_float(f, type, derivatives, val);
- }
- else if(name == u_v) {
- float f[3] = {sd->v, sd->dv.dx, sd->dv.dy};
- return set_attribute_float(f, type, derivatives, val);
- }
-
- return get_attribute(sd, derivatives, u_empty, type, name, val);
- }
- }
- }
-
- return false;
+ OSLTraceData *tracedata = (OSLTraceData *)sg->tracedata;
+
+ if (source == u_trace && tracedata->init) {
+ if (name == u_hit) {
+ return set_attribute_int((tracedata->isect.prim != PRIM_NONE), type, derivatives, val);
+ }
+ else if (tracedata->isect.prim != PRIM_NONE) {
+ if (name == u_hitdist) {
+ float f[3] = {tracedata->isect.t, 0.0f, 0.0f};
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else {
+ ShaderData *sd = &tracedata->sd;
+ KernelGlobals *kg = sd->osl_globals;
+
+ if (!tracedata->setup) {
+ /* lazy shader data setup */
+ shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray);
+ tracedata->setup = true;
+ }
+
+ if (name == u_N) {
+ return set_attribute_float3(sd->N, type, derivatives, val);
+ }
+ else if (name == u_Ng) {
+ return set_attribute_float3(sd->Ng, type, derivatives, val);
+ }
+ else if (name == u_P) {
+ float3 f[3] = {sd->P, sd->dP.dx, sd->dP.dy};
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == u_I) {
+ float3 f[3] = {sd->I, sd->dI.dx, sd->dI.dy};
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == u_u) {
+ float f[3] = {sd->u, sd->du.dx, sd->du.dy};
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_v) {
+ float f[3] = {sd->v, sd->dv.dx, sd->dv.dy};
+ return set_attribute_float(f, type, derivatives, val);
+ }
+
+ return get_attribute(sd, derivatives, u_empty, type, name, val);
+ }
+ }
+ }
+
+ return false;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 3990a22aefd..2fad5833fc9 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -40,177 +40,229 @@ class Shader;
struct ShaderData;
struct float3;
struct KernelGlobals;
-class OSLRenderServices : public OSL::RendererServices
-{
-public:
- OSLRenderServices();
- ~OSLRenderServices();
-
- void thread_init(KernelGlobals *kernel_globals, OSL::TextureSystem *ts);
-
- bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) override;
- bool get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) override;
-
- bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from, float time) override;
- bool get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring to, float time) override;
-
- bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform) override;
- bool get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform) override;
-
- bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from) override;
- bool get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from) override;
-
- bool get_array_attribute(OSL::ShaderGlobals *sg, bool derivatives,
- ustring object, TypeDesc type, ustring name,
- int index, void *val) override;
- bool get_attribute(OSL::ShaderGlobals *sg, bool derivatives, ustring object,
- TypeDesc type, ustring name, void *val) override;
- bool get_attribute(ShaderData *sd, bool derivatives, ustring object_name,
- TypeDesc type, ustring name, void *val);
-
- bool get_userdata(bool derivatives, ustring name, TypeDesc type,
- OSL::ShaderGlobals *sg, void *val) override;
-
- int pointcloud_search(OSL::ShaderGlobals *sg, ustring filename, const OSL::Vec3 &center,
- float radius, int max_points, bool sort, size_t *out_indices,
- float *out_distances, int derivs_offset) override;
-
- int pointcloud_get(OSL::ShaderGlobals *sg, ustring filename, size_t *indices, int count,
- ustring attr_name, TypeDesc attr_type, void *out_data) override;
-
- bool pointcloud_write(OSL::ShaderGlobals *sg,
- ustring filename, const OSL::Vec3 &pos,
- int nattribs, const ustring *names,
- const TypeDesc *types,
- const void **data) override;
-
- bool trace(TraceOpt &options, OSL::ShaderGlobals *sg,
- const OSL::Vec3 &P, const OSL::Vec3 &dPdx,
- const OSL::Vec3 &dPdy, const OSL::Vec3 &R,
- const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy) override;
-
- bool getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
- TypeDesc type, void *val, bool derivatives) override;
-
- TextureSystem::TextureHandle *get_texture_handle(ustring filename) override;
-
- bool good(TextureSystem::TextureHandle *texture_handle) override;
-
- bool texture(ustring filename,
- TextureSystem::TextureHandle *texture_handle,
- TexturePerthread *texture_thread_info,
- TextureOpt &options,
- OSL::ShaderGlobals *sg,
- float s, float t,
- float dsdx, float dtdx, float dsdy, float dtdy,
- int nchannels,
- float *result,
- float *dresultds,
- float *dresultdt,
- ustring *errormessage) override;
-
- bool texture3d(ustring filename,
- TextureHandle *texture_handle,
- TexturePerthread *texture_thread_info,
- TextureOpt &options,
- OSL::ShaderGlobals *sg,
- const OSL::Vec3 &P,
- const OSL::Vec3 &dPdx,
- const OSL::Vec3 &dPdy,
- const OSL::Vec3 &dPdz,
- int nchannels,
- float *result,
- float *dresultds,
- float *dresultdt,
- float *dresultdr,
- ustring *errormessage) override;
-
- bool environment(ustring filename,
- TextureHandle *texture_handle,
- TexturePerthread *texture_thread_info,
- TextureOpt &options,
- OSL::ShaderGlobals *sg,
- const OSL::Vec3 &R,
- const OSL::Vec3 &dRdx,
- const OSL::Vec3 &dRdy,
- int nchannels,
- float *result,
- float *dresultds,
- float *dresultdt,
- ustring *errormessage) override;
-
- bool get_texture_info(OSL::ShaderGlobals *sg,
- ustring filename,
- TextureHandle *texture_handle,
- int subimage,
- ustring dataname,
- TypeDesc datatype,
- void *data) override;
-
- static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val);
- static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val);
-
- static ustring u_distance;
- static ustring u_index;
- static ustring u_world;
- static ustring u_camera;
- static ustring u_screen;
- static ustring u_raster;
- static ustring u_ndc;
- static ustring u_object_location;
- static ustring u_object_index;
- static ustring u_geom_dupli_generated;
- static ustring u_geom_dupli_uv;
- static ustring u_material_index;
- static ustring u_object_random;
- static ustring u_particle_index;
- static ustring u_particle_random;
- static ustring u_particle_age;
- static ustring u_particle_lifetime;
- static ustring u_particle_location;
- static ustring u_particle_rotation;
- static ustring u_particle_size;
- static ustring u_particle_velocity;
- static ustring u_particle_angular_velocity;
- static ustring u_geom_numpolyvertices;
- static ustring u_geom_trianglevertices;
- static ustring u_geom_polyvertices;
- static ustring u_geom_name;
- static ustring u_geom_undisplaced;
- static ustring u_is_smooth;
- static ustring u_is_curve;
- static ustring u_curve_thickness;
- static ustring u_curve_tangent_normal;
- static ustring u_curve_random;
- static ustring u_path_ray_length;
- static ustring u_path_ray_depth;
- static ustring u_path_diffuse_depth;
- static ustring u_path_glossy_depth;
- static ustring u_path_transparent_depth;
- static ustring u_path_transmission_depth;
- static ustring u_trace;
- static ustring u_hit;
- static ustring u_hitdist;
- static ustring u_N;
- static ustring u_Ng;
- static ustring u_P;
- static ustring u_I;
- static ustring u_u;
- static ustring u_v;
- static ustring u_empty;
- static ustring u_at_bevel;
- static ustring u_at_ao;
-
-private:
- KernelGlobals *kernel_globals;
- OSL::TextureSystem *osl_ts;
+class OSLRenderServices : public OSL::RendererServices {
+ public:
+ OSLRenderServices();
+ ~OSLRenderServices();
+
+ void thread_init(KernelGlobals *kernel_globals, OSL::TextureSystem *ts);
+
+ bool get_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform,
+ float time) override;
+ bool get_inverse_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform,
+ float time) override;
+
+ bool get_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ ustring from,
+ float time) override;
+ bool get_inverse_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ ustring to,
+ float time) override;
+
+ bool get_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform) override;
+ bool get_inverse_matrix(OSL::ShaderGlobals *sg,
+ OSL::Matrix44 &result,
+ OSL::TransformationPtr xform) override;
+
+ bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from) override;
+ bool get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from) override;
+
+ bool get_array_attribute(OSL::ShaderGlobals *sg,
+ bool derivatives,
+ ustring object,
+ TypeDesc type,
+ ustring name,
+ int index,
+ void *val) override;
+ bool get_attribute(OSL::ShaderGlobals *sg,
+ bool derivatives,
+ ustring object,
+ TypeDesc type,
+ ustring name,
+ void *val) override;
+ bool get_attribute(ShaderData *sd,
+ bool derivatives,
+ ustring object_name,
+ TypeDesc type,
+ ustring name,
+ void *val);
+
+ bool get_userdata(
+ bool derivatives, ustring name, TypeDesc type, OSL::ShaderGlobals *sg, void *val) override;
+
+ int pointcloud_search(OSL::ShaderGlobals *sg,
+ ustring filename,
+ const OSL::Vec3 &center,
+ float radius,
+ int max_points,
+ bool sort,
+ size_t *out_indices,
+ float *out_distances,
+ int derivs_offset) override;
+
+ int pointcloud_get(OSL::ShaderGlobals *sg,
+ ustring filename,
+ size_t *indices,
+ int count,
+ ustring attr_name,
+ TypeDesc attr_type,
+ void *out_data) override;
+
+ bool pointcloud_write(OSL::ShaderGlobals *sg,
+ ustring filename,
+ const OSL::Vec3 &pos,
+ int nattribs,
+ const ustring *names,
+ const TypeDesc *types,
+ const void **data) override;
+
+ bool trace(TraceOpt &options,
+ OSL::ShaderGlobals *sg,
+ const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx,
+ const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &R,
+ const OSL::Vec3 &dRdx,
+ const OSL::Vec3 &dRdy) override;
+
+ bool getmessage(OSL::ShaderGlobals *sg,
+ ustring source,
+ ustring name,
+ TypeDesc type,
+ void *val,
+ bool derivatives) override;
+
+ TextureSystem::TextureHandle *get_texture_handle(ustring filename) override;
+
+ bool good(TextureSystem::TextureHandle *texture_handle) override;
+
+ bool texture(ustring filename,
+ TextureSystem::TextureHandle *texture_handle,
+ TexturePerthread *texture_thread_info,
+ TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ float s,
+ float t,
+ float dsdx,
+ float dtdx,
+ float dsdy,
+ float dtdy,
+ int nchannels,
+ float *result,
+ float *dresultds,
+ float *dresultdt,
+ ustring *errormessage) override;
+
+ bool texture3d(ustring filename,
+ TextureHandle *texture_handle,
+ TexturePerthread *texture_thread_info,
+ TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx,
+ const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &dPdz,
+ int nchannels,
+ float *result,
+ float *dresultds,
+ float *dresultdt,
+ float *dresultdr,
+ ustring *errormessage) override;
+
+ bool environment(ustring filename,
+ TextureHandle *texture_handle,
+ TexturePerthread *texture_thread_info,
+ TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ const OSL::Vec3 &R,
+ const OSL::Vec3 &dRdx,
+ const OSL::Vec3 &dRdy,
+ int nchannels,
+ float *result,
+ float *dresultds,
+ float *dresultdt,
+ ustring *errormessage) override;
+
+ bool get_texture_info(OSL::ShaderGlobals *sg,
+ ustring filename,
+ TextureHandle *texture_handle,
+ int subimage,
+ ustring dataname,
+ TypeDesc datatype,
+ void *data) override;
+
+ static bool get_background_attribute(
+ KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val);
+ static bool get_object_standard_attribute(
+ KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val);
+
+ static ustring u_distance;
+ static ustring u_index;
+ static ustring u_world;
+ static ustring u_camera;
+ static ustring u_screen;
+ static ustring u_raster;
+ static ustring u_ndc;
+ static ustring u_object_location;
+ static ustring u_object_index;
+ static ustring u_geom_dupli_generated;
+ static ustring u_geom_dupli_uv;
+ static ustring u_material_index;
+ static ustring u_object_random;
+ static ustring u_particle_index;
+ static ustring u_particle_random;
+ static ustring u_particle_age;
+ static ustring u_particle_lifetime;
+ static ustring u_particle_location;
+ static ustring u_particle_rotation;
+ static ustring u_particle_size;
+ static ustring u_particle_velocity;
+ static ustring u_particle_angular_velocity;
+ static ustring u_geom_numpolyvertices;
+ static ustring u_geom_trianglevertices;
+ static ustring u_geom_polyvertices;
+ static ustring u_geom_name;
+ static ustring u_geom_undisplaced;
+ static ustring u_is_smooth;
+ static ustring u_is_curve;
+ static ustring u_curve_thickness;
+ static ustring u_curve_tangent_normal;
+ static ustring u_curve_random;
+ static ustring u_path_ray_length;
+ static ustring u_path_ray_depth;
+ static ustring u_path_diffuse_depth;
+ static ustring u_path_glossy_depth;
+ static ustring u_path_transparent_depth;
+ static ustring u_path_transmission_depth;
+ static ustring u_trace;
+ static ustring u_hit;
+ static ustring u_hitdist;
+ static ustring u_N;
+ static ustring u_Ng;
+ static ustring u_P;
+ static ustring u_I;
+ static ustring u_u;
+ static ustring u_v;
+ static ustring u_empty;
+ static ustring u_at_bevel;
+ static ustring u_at_ao;
+
+ private:
+ KernelGlobals *kernel_globals;
+ OSL::TextureSystem *osl_ts;
#ifdef WITH_PTEX
- PtexCache *ptex_cache;
+ PtexCache *ptex_cache;
#endif
};
CCL_NAMESPACE_END
-#endif /* __OSL_SERVICES_H__ */
+#endif /* __OSL_SERVICES_H__ */
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index a89bb3fd1a3..3d9c579c9ff 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -33,103 +33,104 @@
#include "render/attribute.h"
-
CCL_NAMESPACE_BEGIN
/* Threads */
-void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OSLGlobals *osl_globals)
+void OSLShader::thread_init(KernelGlobals *kg,
+ KernelGlobals *kernel_globals,
+ OSLGlobals *osl_globals)
{
- /* no osl used? */
- if(!osl_globals->use) {
- kg->osl = NULL;
- return;
- }
+ /* no osl used? */
+ if (!osl_globals->use) {
+ kg->osl = NULL;
+ return;
+ }
- /* per thread kernel data init*/
- kg->osl = osl_globals;
- kg->osl->services->thread_init(kernel_globals, osl_globals->ts);
+ /* per thread kernel data init*/
+ kg->osl = osl_globals;
+ kg->osl->services->thread_init(kernel_globals, osl_globals->ts);
- OSL::ShadingSystem *ss = kg->osl->ss;
- OSLThreadData *tdata = new OSLThreadData();
+ OSL::ShadingSystem *ss = kg->osl->ss;
+ OSLThreadData *tdata = new OSLThreadData();
- memset((void *)&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
- tdata->globals.tracedata = &tdata->tracedata;
- tdata->globals.flipHandedness = false;
- tdata->osl_thread_info = ss->create_thread_info();
- tdata->context = ss->get_context(tdata->osl_thread_info);
+ memset((void *)&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
+ tdata->globals.tracedata = &tdata->tracedata;
+ tdata->globals.flipHandedness = false;
+ tdata->osl_thread_info = ss->create_thread_info();
+ tdata->context = ss->get_context(tdata->osl_thread_info);
- tdata->oiio_thread_info = osl_globals->ts->get_perthread_info();
+ tdata->oiio_thread_info = osl_globals->ts->get_perthread_info();
- kg->osl_ss = (OSLShadingSystem*)ss;
- kg->osl_tdata = tdata;
+ kg->osl_ss = (OSLShadingSystem *)ss;
+ kg->osl_tdata = tdata;
}
void OSLShader::thread_free(KernelGlobals *kg)
{
- if(!kg->osl)
- return;
+ if (!kg->osl)
+ return;
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- ss->release_context(tdata->context);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
+ OSLThreadData *tdata = kg->osl_tdata;
+ ss->release_context(tdata->context);
- ss->destroy_thread_info(tdata->osl_thread_info);
+ ss->destroy_thread_info(tdata->osl_thread_info);
- delete tdata;
+ delete tdata;
- kg->osl = NULL;
- kg->osl_ss = NULL;
- kg->osl_tdata = NULL;
+ kg->osl = NULL;
+ kg->osl_ss = NULL;
+ kg->osl_tdata = NULL;
}
/* Globals */
-static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, PathState *state,
- int path_flag, OSLThreadData *tdata)
+static void shaderdata_to_shaderglobals(
+ KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag, OSLThreadData *tdata)
{
- OSL::ShaderGlobals *globals = &tdata->globals;
-
- /* copy from shader data to shader globals */
- globals->P = TO_VEC3(sd->P);
- globals->dPdx = TO_VEC3(sd->dP.dx);
- globals->dPdy = TO_VEC3(sd->dP.dy);
- globals->I = TO_VEC3(sd->I);
- globals->dIdx = TO_VEC3(sd->dI.dx);
- globals->dIdy = TO_VEC3(sd->dI.dy);
- globals->N = TO_VEC3(sd->N);
- globals->Ng = TO_VEC3(sd->Ng);
- globals->u = sd->u;
- globals->dudx = sd->du.dx;
- globals->dudy = sd->du.dy;
- globals->v = sd->v;
- globals->dvdx = sd->dv.dx;
- globals->dvdy = sd->dv.dy;
- globals->dPdu = TO_VEC3(sd->dPdu);
- globals->dPdv = TO_VEC3(sd->dPdv);
- globals->surfacearea = (sd->object == OBJECT_NONE) ? 1.0f : object_surface_area(kg, sd->object);
- globals->time = sd->time;
-
- /* booleans */
- globals->raytype = path_flag;
- globals->backfacing = (sd->flag & SD_BACKFACING);
-
- /* shader data to be used in services callbacks */
- globals->renderstate = sd;
-
- /* hacky, we leave it to services to fetch actual object matrix */
- globals->shader2common = sd;
- globals->object2common = sd;
-
- /* must be set to NULL before execute */
- globals->Ci = NULL;
-
- /* clear trace data */
- tdata->tracedata.init = false;
-
- /* used by renderservices */
- sd->osl_globals = kg;
- sd->osl_path_state = state;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+
+ /* copy from shader data to shader globals */
+ globals->P = TO_VEC3(sd->P);
+ globals->dPdx = TO_VEC3(sd->dP.dx);
+ globals->dPdy = TO_VEC3(sd->dP.dy);
+ globals->I = TO_VEC3(sd->I);
+ globals->dIdx = TO_VEC3(sd->dI.dx);
+ globals->dIdy = TO_VEC3(sd->dI.dy);
+ globals->N = TO_VEC3(sd->N);
+ globals->Ng = TO_VEC3(sd->Ng);
+ globals->u = sd->u;
+ globals->dudx = sd->du.dx;
+ globals->dudy = sd->du.dy;
+ globals->v = sd->v;
+ globals->dvdx = sd->dv.dx;
+ globals->dvdy = sd->dv.dy;
+ globals->dPdu = TO_VEC3(sd->dPdu);
+ globals->dPdv = TO_VEC3(sd->dPdv);
+ globals->surfacearea = (sd->object == OBJECT_NONE) ? 1.0f : object_surface_area(kg, sd->object);
+ globals->time = sd->time;
+
+ /* booleans */
+ globals->raytype = path_flag;
+ globals->backfacing = (sd->flag & SD_BACKFACING);
+
+ /* shader data to be used in services callbacks */
+ globals->renderstate = sd;
+
+ /* hacky, we leave it to services to fetch actual object matrix */
+ globals->shader2common = sd;
+ globals->object2common = sd;
+
+ /* must be set to NULL before execute */
+ globals->Ci = NULL;
+
+ /* clear trace data */
+ tdata->tracedata.init = false;
+
+ /* used by renderservices */
+ sd->osl_globals = kg;
+ sd->osl_path_state = state;
}
/* Surface */
@@ -139,97 +140,101 @@ static void flatten_surface_closure_tree(ShaderData *sd,
const OSL::ClosureColor *closure,
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
- /* OSL gives us a closure tree, we flatten it into arrays per
- * closure type, for evaluation, sampling, etc later on. */
-
- switch(closure->id) {
- case OSL::ClosureColor::MUL: {
- OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
- break;
- }
- case OSL::ClosureColor::ADD: {
- OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
- flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
- break;
- }
- default: {
- OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
- CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
-
- if(prim) {
+ /* OSL gives us a closure tree, we flatten it into arrays per
+ * closure type, for evaluation, sampling, etc later on. */
+
+ switch (closure->id) {
+ case OSL::ClosureColor::MUL: {
+ OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
+ flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
+ break;
+ }
+ case OSL::ClosureColor::ADD: {
+ OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
+ flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
+ flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
+ break;
+ }
+ default: {
+ OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
+ CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
+
+ if (prim) {
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
- weight = weight*TO_FLOAT3(comp->w);
+ weight = weight * TO_FLOAT3(comp->w);
#endif
- prim->setup(sd, path_flag, weight);
- }
- break;
- }
- }
+ prim->setup(sd, path_flag, weight);
+ }
+ break;
+ }
+ }
}
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag)
{
- /* setup shader globals from shader data */
- OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
-
- /* execute shader for this point */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *octx = tdata->context;
- int shader = sd->shader & SHADER_MASK;
-
- /* automatic bump shader */
- if(kg->osl->bump_state[shader]) {
- /* save state */
- float3 P = sd->P;
- float3 dPdx = sd->dP.dx;
- float3 dPdy = sd->dP.dy;
-
- /* set state as if undisplaced */
- if(sd->flag & SD_HAS_DISPLACEMENT) {
- float data[9];
- bool found = kg->osl->services->get_attribute(sd, true, OSLRenderServices::u_empty, TypeDesc::TypeVector,
- OSLRenderServices::u_geom_undisplaced, data);
- (void) found;
- assert(found);
-
- memcpy(&sd->P, data, sizeof(float)*3);
- memcpy(&sd->dP.dx, data+3, sizeof(float)*3);
- memcpy(&sd->dP.dy, data+6, sizeof(float)*3);
-
- object_position_transform(kg, sd, &sd->P);
- object_dir_transform(kg, sd, &sd->dP.dx);
- object_dir_transform(kg, sd, &sd->dP.dy);
-
- globals->P = TO_VEC3(sd->P);
- globals->dPdx = TO_VEC3(sd->dP.dx);
- globals->dPdy = TO_VEC3(sd->dP.dy);
- }
-
- /* execute bump shader */
- ss->execute(octx, *(kg->osl->bump_state[shader]), *globals);
-
- /* reset state */
- sd->P = P;
- sd->dP.dx = dPdx;
- sd->dP.dy = dPdy;
-
- globals->P = TO_VEC3(P);
- globals->dPdx = TO_VEC3(dPdx);
- globals->dPdy = TO_VEC3(dPdy);
- }
-
- /* surface shader */
- if(kg->osl->surface_state[shader]) {
- ss->execute(octx, *(kg->osl->surface_state[shader]), *globals);
- }
-
- /* flatten closure tree */
- if(globals->Ci)
- flatten_surface_closure_tree(sd, path_flag, globals->Ci);
+ /* setup shader globals from shader data */
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
+
+ /* execute shader for this point */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context;
+ int shader = sd->shader & SHADER_MASK;
+
+ /* automatic bump shader */
+ if (kg->osl->bump_state[shader]) {
+ /* save state */
+ float3 P = sd->P;
+ float3 dPdx = sd->dP.dx;
+ float3 dPdy = sd->dP.dy;
+
+ /* set state as if undisplaced */
+ if (sd->flag & SD_HAS_DISPLACEMENT) {
+ float data[9];
+ bool found = kg->osl->services->get_attribute(sd,
+ true,
+ OSLRenderServices::u_empty,
+ TypeDesc::TypeVector,
+ OSLRenderServices::u_geom_undisplaced,
+ data);
+ (void)found;
+ assert(found);
+
+ memcpy(&sd->P, data, sizeof(float) * 3);
+ memcpy(&sd->dP.dx, data + 3, sizeof(float) * 3);
+ memcpy(&sd->dP.dy, data + 6, sizeof(float) * 3);
+
+ object_position_transform(kg, sd, &sd->P);
+ object_dir_transform(kg, sd, &sd->dP.dx);
+ object_dir_transform(kg, sd, &sd->dP.dy);
+
+ globals->P = TO_VEC3(sd->P);
+ globals->dPdx = TO_VEC3(sd->dP.dx);
+ globals->dPdy = TO_VEC3(sd->dP.dy);
+ }
+
+ /* execute bump shader */
+ ss->execute(octx, *(kg->osl->bump_state[shader]), *globals);
+
+ /* reset state */
+ sd->P = P;
+ sd->dP.dx = dPdx;
+ sd->dP.dy = dPdy;
+
+ globals->P = TO_VEC3(P);
+ globals->dPdx = TO_VEC3(dPdx);
+ globals->dPdy = TO_VEC3(dPdy);
+ }
+
+ /* surface shader */
+ if (kg->osl->surface_state[shader]) {
+ ss->execute(octx, *(kg->osl->surface_state[shader]), *globals);
+ }
+
+ /* flatten closure tree */
+ if (globals->Ci)
+ flatten_surface_closure_tree(sd, path_flag, globals->Ci);
}
/* Background */
@@ -238,56 +243,56 @@ static void flatten_background_closure_tree(ShaderData *sd,
const OSL::ClosureColor *closure,
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
- /* OSL gives us a closure tree, if we are shading for background there
- * is only one supported closure type at the moment, which has no evaluation
- * functions, so we just sum the weights */
-
- switch(closure->id) {
- case OSL::ClosureColor::MUL: {
- OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_background_closure_tree(sd, mul->closure, weight * TO_FLOAT3(mul->weight));
- break;
- }
- case OSL::ClosureColor::ADD: {
- OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
-
- flatten_background_closure_tree(sd, add->closureA, weight);
- flatten_background_closure_tree(sd, add->closureB, weight);
- break;
- }
- default: {
- OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
- CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
-
- if(prim) {
+ /* OSL gives us a closure tree, if we are shading for background there
+ * is only one supported closure type at the moment, which has no evaluation
+ * functions, so we just sum the weights */
+
+ switch (closure->id) {
+ case OSL::ClosureColor::MUL: {
+ OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
+ flatten_background_closure_tree(sd, mul->closure, weight * TO_FLOAT3(mul->weight));
+ break;
+ }
+ case OSL::ClosureColor::ADD: {
+ OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
+
+ flatten_background_closure_tree(sd, add->closureA, weight);
+ flatten_background_closure_tree(sd, add->closureB, weight);
+ break;
+ }
+ default: {
+ OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
+ CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
+
+ if (prim) {
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
- weight = weight*TO_FLOAT3(comp->w);
+ weight = weight * TO_FLOAT3(comp->w);
#endif
- prim->setup(sd, 0, weight);
- }
- break;
- }
- }
+ prim->setup(sd, 0, weight);
+ }
+ break;
+ }
+ }
}
void OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag)
{
- /* setup shader globals from shader data */
- OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
-
- /* execute shader for this point */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *octx = tdata->context;
-
- if(kg->osl->background_state) {
- ss->execute(octx, *(kg->osl->background_state), *globals);
- }
-
- /* return background color immediately */
- if(globals->Ci)
- flatten_background_closure_tree(sd, globals->Ci);
+ /* setup shader globals from shader data */
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
+
+ /* execute shader for this point */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context;
+
+ if (kg->osl->background_state) {
+ ss->execute(octx, *(kg->osl->background_state), *globals);
+ }
+
+ /* return background color immediately */
+ if (globals->Ci)
+ flatten_background_closure_tree(sd, globals->Ci);
}
/* Volume */
@@ -296,112 +301,117 @@ static void flatten_volume_closure_tree(ShaderData *sd,
const OSL::ClosureColor *closure,
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
- /* OSL gives us a closure tree, we flatten it into arrays per
- * closure type, for evaluation, sampling, etc later on. */
-
- switch(closure->id) {
- case OSL::ClosureColor::MUL: {
- OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
- break;
- }
- case OSL::ClosureColor::ADD: {
- OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_volume_closure_tree(sd, add->closureA, weight);
- flatten_volume_closure_tree(sd, add->closureB, weight);
- break;
- }
- default: {
- OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
- CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
-
- if(prim) {
+ /* OSL gives us a closure tree, we flatten it into arrays per
+ * closure type, for evaluation, sampling, etc later on. */
+
+ switch (closure->id) {
+ case OSL::ClosureColor::MUL: {
+ OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
+ flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
+ break;
+ }
+ case OSL::ClosureColor::ADD: {
+ OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
+ flatten_volume_closure_tree(sd, add->closureA, weight);
+ flatten_volume_closure_tree(sd, add->closureB, weight);
+ break;
+ }
+ default: {
+ OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
+ CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
+
+ if (prim) {
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
- weight = weight*TO_FLOAT3(comp->w);
+ weight = weight * TO_FLOAT3(comp->w);
#endif
- prim->setup(sd, 0, weight);
- }
- }
- }
+ prim->setup(sd, 0, weight);
+ }
+ }
+ }
}
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag)
{
- /* setup shader globals from shader data */
- OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
-
- /* execute shader */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *octx = tdata->context;
- int shader = sd->shader & SHADER_MASK;
-
- if(kg->osl->volume_state[shader]) {
- ss->execute(octx, *(kg->osl->volume_state[shader]), *globals);
- }
-
- /* flatten closure tree */
- if(globals->Ci)
- flatten_volume_closure_tree(sd, globals->Ci);
+ /* setup shader globals from shader data */
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
+
+ /* execute shader */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context;
+ int shader = sd->shader & SHADER_MASK;
+
+ if (kg->osl->volume_state[shader]) {
+ ss->execute(octx, *(kg->osl->volume_state[shader]), *globals);
+ }
+
+ /* flatten closure tree */
+ if (globals->Ci)
+ flatten_volume_closure_tree(sd, globals->Ci);
}
/* Displacement */
void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, PathState *state)
{
- /* setup shader globals from shader data */
- OSLThreadData *tdata = kg->osl_tdata;
+ /* setup shader globals from shader data */
+ OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, 0, tdata);
+ shaderdata_to_shaderglobals(kg, sd, state, 0, tdata);
- /* execute shader */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *octx = tdata->context;
- int shader = sd->shader & SHADER_MASK;
+ /* execute shader */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context;
+ int shader = sd->shader & SHADER_MASK;
- if(kg->osl->displacement_state[shader]) {
- ss->execute(octx, *(kg->osl->displacement_state[shader]), *globals);
- }
+ if (kg->osl->displacement_state[shader]) {
+ ss->execute(octx, *(kg->osl->displacement_state[shader]), *globals);
+ }
- /* get back position */
- sd->P = TO_FLOAT3(globals->P);
+ /* get back position */
+ sd->P = TO_FLOAT3(globals->P);
}
/* Attributes */
-int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeDescriptor *desc)
+int OSLShader::find_attribute(KernelGlobals *kg,
+ const ShaderData *sd,
+ uint id,
+ AttributeDescriptor *desc)
{
- /* for OSL, a hash map is used to lookup the attribute by name. */
- int object = sd->object*ATTR_PRIM_TYPES;
+ /* for OSL, a hash map is used to lookup the attribute by name. */
+ int object = sd->object * ATTR_PRIM_TYPES;
#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_CURVE) object += ATTR_PRIM_CURVE;
+ if (sd->type & PRIMITIVE_ALL_CURVE)
+ object += ATTR_PRIM_CURVE;
#endif
- OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
- ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
- OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
-
- if(it != attr_map.end()) {
- const OSLGlobals::Attribute &osl_attr = it->second;
- *desc = osl_attr.desc;
-
- if(sd->prim == PRIM_NONE && (AttributeElement)osl_attr.desc.element != ATTR_ELEMENT_MESH) {
- desc->offset = ATTR_STD_NOT_FOUND;
- return ATTR_STD_NOT_FOUND;
- }
-
- /* return result */
- if(osl_attr.desc.element == ATTR_ELEMENT_NONE) {
- desc->offset = ATTR_STD_NOT_FOUND;
- }
- return desc->offset;
- }
- else {
- desc->offset = ATTR_STD_NOT_FOUND;
- return (int)ATTR_STD_NOT_FOUND;
- }
+ OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
+ ustring stdname(std::string("geom:") +
+ std::string(Attribute::standard_name((AttributeStandard)id)));
+ OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
+
+ if (it != attr_map.end()) {
+ const OSLGlobals::Attribute &osl_attr = it->second;
+ *desc = osl_attr.desc;
+
+ if (sd->prim == PRIM_NONE && (AttributeElement)osl_attr.desc.element != ATTR_ELEMENT_MESH) {
+ desc->offset = ATTR_STD_NOT_FOUND;
+ return ATTR_STD_NOT_FOUND;
+ }
+
+ /* return result */
+ if (osl_attr.desc.element == ATTR_ELEMENT_NONE) {
+ desc->offset = ATTR_STD_NOT_FOUND;
+ }
+ return desc->offset;
+ }
+ else {
+ desc->offset = ATTR_STD_NOT_FOUND;
+ return (int)ATTR_STD_NOT_FOUND;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h
index 9824f966a44..a4fa24d0a90 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/osl_shader.h
@@ -29,7 +29,7 @@
* This means no thread state must be passed along in the kernel itself.
*/
-#include "kernel/kernel_types.h"
+# include "kernel/kernel_types.h"
CCL_NAMESPACE_BEGIN
@@ -44,26 +44,31 @@ struct OSLGlobals;
struct OSLShadingSystem;
class OSLShader {
-public:
- /* init */
- static void register_closures(OSLShadingSystem *ss);
+ public:
+ /* init */
+ static void register_closures(OSLShadingSystem *ss);
- /* per thread data */
- static void thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OSLGlobals *osl_globals);
- static void thread_free(KernelGlobals *kg);
+ /* per thread data */
+ static void thread_init(KernelGlobals *kg,
+ KernelGlobals *kernel_globals,
+ OSLGlobals *osl_globals);
+ static void thread_free(KernelGlobals *kg);
- /* eval */
- static void eval_surface(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag);
- static void eval_background(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag);
- static void eval_volume(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag);
- static void eval_displacement(KernelGlobals *kg, ShaderData *sd, PathState *state);
+ /* eval */
+ static void eval_surface(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag);
+ static void eval_background(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag);
+ static void eval_volume(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag);
+ static void eval_displacement(KernelGlobals *kg, ShaderData *sd, PathState *state);
- /* attributes */
- static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeDescriptor *desc);
+ /* attributes */
+ static int find_attribute(KernelGlobals *kg,
+ const ShaderData *sd,
+ uint id,
+ AttributeDescriptor *desc);
};
CCL_NAMESPACE_END
#endif
-#endif /* __OSL_SHADER_H__ */
+#endif /* __OSL_SHADER_H__ */
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 4740db27d4e..b42b9b2fe64 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -2,102 +2,102 @@
# OSL node shaders
set(SRC_OSL
- node_add_closure.osl
- node_ambient_occlusion.osl
- node_anisotropic_bsdf.osl
- node_attribute.osl
- node_background.osl
- node_bevel.osl
- node_brick_texture.osl
- node_brightness.osl
- node_bump.osl
- node_camera.osl
- node_checker_texture.osl
- node_combine_rgb.osl
- node_combine_hsv.osl
- node_combine_xyz.osl
- node_convert_from_color.osl
- node_convert_from_float.osl
- node_convert_from_int.osl
- node_convert_from_normal.osl
- node_convert_from_point.osl
- node_convert_from_vector.osl
- node_diffuse_bsdf.osl
- node_displacement.osl
- node_vector_displacement.osl
- node_emission.osl
- node_environment_texture.osl
- node_fresnel.osl
- node_gamma.osl
- node_geometry.osl
- node_glass_bsdf.osl
- node_glossy_bsdf.osl
- node_gradient_texture.osl
- node_hair_info.osl
- node_scatter_volume.osl
- node_absorption_volume.osl
- node_principled_volume.osl
- node_holdout.osl
- node_hsv.osl
- node_ies_light.osl
- node_image_texture.osl
- node_invert.osl
- node_layer_weight.osl
- node_light_falloff.osl
- node_light_path.osl
- node_magic_texture.osl
- node_mapping.osl
- node_math.osl
- node_mix.osl
- node_mix_closure.osl
- node_musgrave_texture.osl
- node_noise_texture.osl
- node_normal.osl
- node_normal_map.osl
- node_object_info.osl
- node_output_displacement.osl
- node_output_surface.osl
- node_output_volume.osl
- node_particle_info.osl
- node_refraction_bsdf.osl
- node_rgb_curves.osl
- node_rgb_ramp.osl
- node_separate_rgb.osl
- node_separate_hsv.osl
- node_separate_xyz.osl
- node_set_normal.osl
- node_sky_texture.osl
- node_subsurface_scattering.osl
- node_tangent.osl
- node_texture_coordinate.osl
- node_toon_bsdf.osl
- node_translucent_bsdf.osl
- node_transparent_bsdf.osl
- node_value.osl
- node_vector_curves.osl
- node_vector_math.osl
- node_vector_transform.osl
- node_velvet_bsdf.osl
- node_voronoi_texture.osl
- node_voxel_texture.osl
- node_wavelength.osl
- node_blackbody.osl
- node_wave_texture.osl
- node_wireframe.osl
- node_hair_bsdf.osl
- node_principled_hair_bsdf.osl
- node_uv_map.osl
- node_principled_bsdf.osl
- node_rgb_to_bw.osl
+ node_add_closure.osl
+ node_ambient_occlusion.osl
+ node_anisotropic_bsdf.osl
+ node_attribute.osl
+ node_background.osl
+ node_bevel.osl
+ node_brick_texture.osl
+ node_brightness.osl
+ node_bump.osl
+ node_camera.osl
+ node_checker_texture.osl
+ node_combine_rgb.osl
+ node_combine_hsv.osl
+ node_combine_xyz.osl
+ node_convert_from_color.osl
+ node_convert_from_float.osl
+ node_convert_from_int.osl
+ node_convert_from_normal.osl
+ node_convert_from_point.osl
+ node_convert_from_vector.osl
+ node_diffuse_bsdf.osl
+ node_displacement.osl
+ node_vector_displacement.osl
+ node_emission.osl
+ node_environment_texture.osl
+ node_fresnel.osl
+ node_gamma.osl
+ node_geometry.osl
+ node_glass_bsdf.osl
+ node_glossy_bsdf.osl
+ node_gradient_texture.osl
+ node_hair_info.osl
+ node_scatter_volume.osl
+ node_absorption_volume.osl
+ node_principled_volume.osl
+ node_holdout.osl
+ node_hsv.osl
+ node_ies_light.osl
+ node_image_texture.osl
+ node_invert.osl
+ node_layer_weight.osl
+ node_light_falloff.osl
+ node_light_path.osl
+ node_magic_texture.osl
+ node_mapping.osl
+ node_math.osl
+ node_mix.osl
+ node_mix_closure.osl
+ node_musgrave_texture.osl
+ node_noise_texture.osl
+ node_normal.osl
+ node_normal_map.osl
+ node_object_info.osl
+ node_output_displacement.osl
+ node_output_surface.osl
+ node_output_volume.osl
+ node_particle_info.osl
+ node_refraction_bsdf.osl
+ node_rgb_curves.osl
+ node_rgb_ramp.osl
+ node_separate_rgb.osl
+ node_separate_hsv.osl
+ node_separate_xyz.osl
+ node_set_normal.osl
+ node_sky_texture.osl
+ node_subsurface_scattering.osl
+ node_tangent.osl
+ node_texture_coordinate.osl
+ node_toon_bsdf.osl
+ node_translucent_bsdf.osl
+ node_transparent_bsdf.osl
+ node_value.osl
+ node_vector_curves.osl
+ node_vector_math.osl
+ node_vector_transform.osl
+ node_velvet_bsdf.osl
+ node_voronoi_texture.osl
+ node_voxel_texture.osl
+ node_wavelength.osl
+ node_blackbody.osl
+ node_wave_texture.osl
+ node_wireframe.osl
+ node_hair_bsdf.osl
+ node_principled_hair_bsdf.osl
+ node_uv_map.osl
+ node_principled_bsdf.osl
+ node_rgb_to_bw.osl
)
set(SRC_OSL_HEADERS
- node_color.h
- node_fresnel.h
- node_ramp_util.h
- node_texture.h
- stdosl.h
- oslutil.h
+ node_color.h
+ node_fresnel.h
+ node_ramp_util.h
+ node_texture.h
+ stdosl.h
+ oslutil.h
)
set(SRC_OSO
@@ -106,20 +106,20 @@ set(SRC_OSO
# TODO, add a module to compile OSL
foreach(_file ${SRC_OSL})
- set(_OSL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
- set_source_files_properties(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
- string(REPLACE ".osl" ".oso" _OSO_FILE ${_OSL_FILE})
- string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} _OSO_FILE ${_OSO_FILE})
- add_custom_command(
- OUTPUT ${_OSO_FILE}
- COMMAND ${OSL_COMPILER} -q -O2 -I"${CMAKE_CURRENT_SOURCE_DIR}" -o ${_OSO_FILE} ${_OSL_FILE}
- DEPENDS ${_OSL_FILE} ${SRC_OSL_HEADERS} ${OSL_COMPILER})
- list(APPEND SRC_OSO
- ${_OSO_FILE}
- )
+ set(_OSL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
+ set_source_files_properties(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
+ string(REPLACE ".osl" ".oso" _OSO_FILE ${_OSL_FILE})
+ string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} _OSO_FILE ${_OSO_FILE})
+ add_custom_command(
+ OUTPUT ${_OSO_FILE}
+ COMMAND ${OSL_COMPILER} -q -O2 -I"${CMAKE_CURRENT_SOURCE_DIR}" -o ${_OSO_FILE} ${_OSL_FILE}
+ DEPENDS ${_OSL_FILE} ${SRC_OSL_HEADERS} ${OSL_COMPILER})
+ list(APPEND SRC_OSO
+ ${_OSO_FILE}
+ )
- unset(_OSL_FILE)
- unset(_OSO_FILE)
+ unset(_OSL_FILE)
+ unset(_OSO_FILE)
endforeach()
add_custom_target(cycles_osl_shaders ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS} ${OSL_COMPILER} SOURCES ${SRC_OSL})
diff --git a/intern/cycles/kernel/shaders/node_absorption_volume.osl b/intern/cycles/kernel/shaders/node_absorption_volume.osl
index 18f662ebbbd..e99bd254666 100644
--- a/intern/cycles/kernel/shaders/node_absorption_volume.osl
+++ b/intern/cycles/kernel/shaders/node_absorption_volume.osl
@@ -16,11 +16,9 @@
#include "stdosl.h"
-shader node_absorption_volume(
- color Color = color(0.8, 0.8, 0.8),
- float Density = 1.0,
- output closure color Volume = 0)
+shader node_absorption_volume(color Color = color(0.8, 0.8, 0.8),
+ float Density = 1.0,
+ output closure color Volume = 0)
{
- Volume = ((color(1.0, 1.0, 1.0) - Color) * max(Density, 0.0)) * absorption();
+ Volume = ((color(1.0, 1.0, 1.0) - Color) * max(Density, 0.0)) * absorption();
}
-
diff --git a/intern/cycles/kernel/shaders/node_add_closure.osl b/intern/cycles/kernel/shaders/node_add_closure.osl
index b6596e0b6bd..077e2735e61 100644
--- a/intern/cycles/kernel/shaders/node_add_closure.osl
+++ b/intern/cycles/kernel/shaders/node_add_closure.osl
@@ -16,11 +16,9 @@
#include "stdosl.h"
-shader node_add_closure(
- closure color Closure1 = 0,
- closure color Closure2 = 0,
- output closure color Closure = 0)
+shader node_add_closure(closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
{
- Closure = Closure1 + Closure2;
+ Closure = Closure1 + Closure2;
}
-
diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
index 825cccd59ce..7bf28719e78 100644
--- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
+++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
@@ -16,20 +16,28 @@
#include "stdosl.h"
-shader node_ambient_occlusion(
- color ColorIn = color(1.0, 1.0, 1.0),
- int samples = 16,
- float Distance = 1.0,
- normal Normal = N,
- int inside = 0,
- int only_local = 0,
- output color ColorOut = color(1.0, 1.0, 1.0),
- output float AO = 1.0)
+shader node_ambient_occlusion(color ColorIn = color(1.0, 1.0, 1.0),
+ int samples = 16,
+ float Distance = 1.0,
+ normal Normal = N,
+ int inside = 0,
+ int only_local = 0,
+ output color ColorOut = color(1.0, 1.0, 1.0),
+ output float AO = 1.0)
{
- int global_radius = (Distance == 0.0 && !isconnected(Distance));
+ int global_radius = (Distance == 0.0 && !isconnected(Distance));
- /* Abuse texture call with special @ao token. */
- AO = texture("@ao", samples, Distance, Normal[0], Normal[1], Normal[2], inside, "sblur", only_local, "tblur", global_radius);
- ColorOut = ColorIn * AO;
+ /* Abuse texture call with special @ao token. */
+ AO = texture("@ao",
+ samples,
+ Distance,
+ Normal[0],
+ Normal[1],
+ Normal[2],
+ inside,
+ "sblur",
+ only_local,
+ "tblur",
+ global_radius);
+ ColorOut = ColorIn * AO;
}
-
diff --git a/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl b/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
index 21e28ece65d..165c09eb8e0 100644
--- a/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
@@ -16,45 +16,43 @@
#include "stdosl.h"
-shader node_anisotropic_bsdf(
- color Color = 0.0,
- string distribution = "GGX",
- float Roughness = 0.0,
- float Anisotropy = 0.0,
- float Rotation = 0.0,
- normal Normal = N,
- normal Tangent = normalize(dPdu),
- output closure color BSDF = 0)
+shader node_anisotropic_bsdf(color Color = 0.0,
+ string distribution = "GGX",
+ float Roughness = 0.0,
+ float Anisotropy = 0.0,
+ float Rotation = 0.0,
+ normal Normal = N,
+ normal Tangent = normalize(dPdu),
+ output closure color BSDF = 0)
{
- /* rotate tangent around normal */
- vector T = Tangent;
+ /* rotate tangent around normal */
+ vector T = Tangent;
- if (Rotation != 0.0)
- T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
+ if (Rotation != 0.0)
+ T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
- /* compute roughness */
- float roughness = Roughness * Roughness;
- float roughness_u, roughness_v;
- float aniso = clamp(Anisotropy, -0.99, 0.99);
+ /* compute roughness */
+ float roughness = Roughness * Roughness;
+ float roughness_u, roughness_v;
+ float aniso = clamp(Anisotropy, -0.99, 0.99);
- if (aniso < 0.0) {
- roughness_u = roughness / (1.0 + aniso);
- roughness_v = roughness * (1.0 + aniso);
- }
- else {
- roughness_u = roughness * (1.0 - aniso);
- roughness_v = roughness / (1.0 - aniso);
- }
+ if (aniso < 0.0) {
+ roughness_u = roughness / (1.0 + aniso);
+ roughness_v = roughness * (1.0 + aniso);
+ }
+ else {
+ roughness_u = roughness * (1.0 - aniso);
+ roughness_v = roughness / (1.0 - aniso);
+ }
- if (distribution == "sharp")
- BSDF = Color * reflection(Normal);
- else if (distribution == "beckmann")
- BSDF = Color * microfacet_beckmann_aniso(Normal, T, roughness_u, roughness_v);
- else if (distribution == "GGX")
- BSDF = Color * microfacet_ggx_aniso(Normal, T, roughness_u, roughness_v);
- else if (distribution == "Multiscatter GGX")
- BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color);
- else
- BSDF = Color * ashikhmin_shirley(Normal, T, roughness_u, roughness_v);
+ if (distribution == "sharp")
+ BSDF = Color * reflection(Normal);
+ else if (distribution == "beckmann")
+ BSDF = Color * microfacet_beckmann_aniso(Normal, T, roughness_u, roughness_v);
+ else if (distribution == "GGX")
+ BSDF = Color * microfacet_ggx_aniso(Normal, T, roughness_u, roughness_v);
+ else if (distribution == "Multiscatter GGX")
+ BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color);
+ else
+ BSDF = Color * ashikhmin_shirley(Normal, T, roughness_u, roughness_v);
}
-
diff --git a/intern/cycles/kernel/shaders/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl
index 67183e9ffe0..336543cc130 100644
--- a/intern/cycles/kernel/shaders/node_attribute.osl
+++ b/intern/cycles/kernel/shaders/node_attribute.osl
@@ -16,26 +16,24 @@
#include "stdosl.h"
-shader node_attribute(
- string bump_offset = "center",
- string name = "",
- output point Vector = point(0.0, 0.0, 0.0),
- output color Color = 0.0,
- output float Fac = 0.0)
+shader node_attribute(string bump_offset = "center",
+ string name = "",
+ output point Vector = point(0.0, 0.0, 0.0),
+ output color Color = 0.0,
+ output float Fac = 0.0)
{
- getattribute(name, Color);
- Vector = point(Color);
- getattribute(name, Fac);
+ getattribute(name, Color);
+ Vector = point(Color);
+ getattribute(name, Fac);
- if (bump_offset == "dx") {
- Color += Dx(Color);
- Vector += Dx(Vector);
- Fac += Dx(Fac);
- }
- else if (bump_offset == "dy") {
- Color += Dy(Color);
- Vector += Dy(Vector);
- Fac += Dy(Fac);
- }
+ if (bump_offset == "dx") {
+ Color += Dx(Color);
+ Vector += Dx(Vector);
+ Fac += Dx(Fac);
+ }
+ else if (bump_offset == "dy") {
+ Color += Dy(Color);
+ Vector += Dy(Vector);
+ Fac += Dy(Fac);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_background.osl b/intern/cycles/kernel/shaders/node_background.osl
index 613d4e360fa..6ded0d2c65c 100644
--- a/intern/cycles/kernel/shaders/node_background.osl
+++ b/intern/cycles/kernel/shaders/node_background.osl
@@ -16,11 +16,9 @@
#include "stdosl.h"
-shader node_background(
- color Color = 0.8,
- float Strength = 1.0,
- output closure color Background = 0)
+shader node_background(color Color = 0.8,
+ float Strength = 1.0,
+ output closure color Background = 0)
{
- Background = Color * Strength * background();
+ Background = Color * Strength * background();
}
-
diff --git a/intern/cycles/kernel/shaders/node_bevel.osl b/intern/cycles/kernel/shaders/node_bevel.osl
index 9c4ca15be17..189c20c52e7 100644
--- a/intern/cycles/kernel/shaders/node_bevel.osl
+++ b/intern/cycles/kernel/shaders/node_bevel.osl
@@ -16,16 +16,14 @@
#include "stdosl.h"
-shader node_bevel(
- int samples = 4,
- float Radius = 0.05,
- normal NormalIn = N,
- output normal NormalOut = N)
+shader node_bevel(int samples = 4,
+ float Radius = 0.05,
+ normal NormalIn = N,
+ output normal NormalOut = N)
{
- /* Abuse texture call with special @bevel token. */
- vector bevel_N = (normal)(color)texture("@bevel", samples, Radius);
+ /* Abuse texture call with special @bevel token. */
+ vector bevel_N = (normal)(color)texture("@bevel", samples, Radius);
- /* Preserve input normal. */
- NormalOut = normalize(NormalIn + (bevel_N - N));
+ /* Preserve input normal. */
+ NormalOut = normalize(NormalIn + (bevel_N - N));
}
-
diff --git a/intern/cycles/kernel/shaders/node_blackbody.osl b/intern/cycles/kernel/shaders/node_blackbody.osl
index 1da6894d0f0..8a24bf1e28b 100644
--- a/intern/cycles/kernel/shaders/node_blackbody.osl
+++ b/intern/cycles/kernel/shaders/node_blackbody.osl
@@ -16,16 +16,13 @@
#include "stdosl.h"
-shader node_blackbody(
- float Temperature = 1200.0,
- output color Color = 0.0)
+shader node_blackbody(float Temperature = 1200.0, output color Color = 0.0)
{
- color rgb = blackbody(Temperature);
-
- /* Scale by luminance */
- float l = luminance(rgb);
- if (l != 0.0)
- rgb /= l;
- Color = rgb;
-}
+ color rgb = blackbody(Temperature);
+ /* Scale by luminance */
+ float l = luminance(rgb);
+ if (l != 0.0)
+ rgb /= l;
+ Color = rgb;
+}
diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index 9d2e5b74ce6..0abc3574c48 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -21,85 +21,100 @@
float brick_noise(int ns) /* fast integer noise */
{
- int nn;
- int n = (ns + 1013) & 2147483647;
- n = (n >> 13) ^ n;
- nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 2147483647;
- return 0.5 * ((float)nn / 1073741824.0);
+ int nn;
+ int n = (ns + 1013) & 2147483647;
+ n = (n >> 13) ^ n;
+ nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 2147483647;
+ return 0.5 * ((float)nn / 1073741824.0);
}
-float brick(point p, float mortar_size, float mortar_smooth, float bias,
- float BrickWidth, float row_height, float offset_amount, int offset_frequency,
- float squash_amount, int squash_frequency, output float tint)
+float brick(point p,
+ float mortar_size,
+ float mortar_smooth,
+ float bias,
+ float BrickWidth,
+ float row_height,
+ float offset_amount,
+ int offset_frequency,
+ float squash_amount,
+ int squash_frequency,
+ output float tint)
{
- int bricknum, rownum;
- float offset = 0.0;
- float brick_width = BrickWidth;
- float x, y;
-
- rownum = (int)floor(p[1] / row_height);
-
- if (offset_frequency && squash_frequency) {
- brick_width *= (rownum % squash_frequency) ? 1.0 : squash_amount; /* squash */
- offset = (rownum % offset_frequency) ? 0.0 : (brick_width * offset_amount); /* offset */
- }
-
- bricknum = (int)floor((p[0] + offset) / brick_width);
-
- x = (p[0] + offset) - brick_width * bricknum;
- y = p[1] - row_height * rownum;
-
- tint = clamp((brick_noise((rownum << 16) + (bricknum & 65535)) + bias), 0.0, 1.0);
-
- float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
- if(min_dist >= mortar_size) {
- return 0.0;
- }
- else if(mortar_smooth == 0.0) {
- return 1.0;
- }
- else {
- min_dist = 1.0 - min_dist/mortar_size;
- return smoothstep(0.0, mortar_smooth, min_dist);
- }
+ int bricknum, rownum;
+ float offset = 0.0;
+ float brick_width = BrickWidth;
+ float x, y;
+
+ rownum = (int)floor(p[1] / row_height);
+
+ if (offset_frequency && squash_frequency) {
+ brick_width *= (rownum % squash_frequency) ? 1.0 : squash_amount; /* squash */
+ offset = (rownum % offset_frequency) ? 0.0 : (brick_width * offset_amount); /* offset */
+ }
+
+ bricknum = (int)floor((p[0] + offset) / brick_width);
+
+ x = (p[0] + offset) - brick_width * bricknum;
+ y = p[1] - row_height * rownum;
+
+ tint = clamp((brick_noise((rownum << 16) + (bricknum & 65535)) + bias), 0.0, 1.0);
+
+ float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
+ if (min_dist >= mortar_size) {
+ return 0.0;
+ }
+ else if (mortar_smooth == 0.0) {
+ return 1.0;
+ }
+ else {
+ min_dist = 1.0 - min_dist / mortar_size;
+ return smoothstep(0.0, mortar_smooth, min_dist);
+ }
}
-shader node_brick_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- float offset = 0.5,
- int offset_frequency = 2,
- float squash = 1.0,
- int squash_frequency = 1,
- point Vector = P,
- color Color1 = 0.2,
- color Color2 = 0.8,
- color Mortar = 0.0,
- float Scale = 5.0,
- float MortarSize = 0.02,
- float MortarSmooth = 0.0,
- float Bias = 0.0,
- float BrickWidth = 0.5,
- float RowHeight = 0.25,
- output float Fac = 0.0,
- output color Color = 0.2)
+shader node_brick_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ float offset = 0.5,
+ int offset_frequency = 2,
+ float squash = 1.0,
+ int squash_frequency = 1,
+ point Vector = P,
+ color Color1 = 0.2,
+ color Color2 = 0.8,
+ color Mortar = 0.0,
+ float Scale = 5.0,
+ float MortarSize = 0.02,
+ float MortarSmooth = 0.0,
+ float Bias = 0.0,
+ float BrickWidth = 0.5,
+ float RowHeight = 0.25,
+ output float Fac = 0.0,
+ output color Color = 0.2)
{
- point p = Vector;
-
- if (use_mapping)
- p = transform(mapping, p);
-
- float tint = 0.0;
- color Col = Color1;
-
- Fac = brick(p * Scale, MortarSize, MortarSmooth, Bias, BrickWidth, RowHeight,
- offset, offset_frequency, squash, squash_frequency, tint);
-
- if (Fac != 1.0) {
- float facm = 1.0 - tint;
- Col = facm * Color1 + tint * Color2;
- }
-
- Color = mix(Col, Mortar, Fac);
-}
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ float tint = 0.0;
+ color Col = Color1;
+ Fac = brick(p * Scale,
+ MortarSize,
+ MortarSmooth,
+ Bias,
+ BrickWidth,
+ RowHeight,
+ offset,
+ offset_frequency,
+ squash,
+ squash_frequency,
+ tint);
+
+ if (Fac != 1.0) {
+ float facm = 1.0 - tint;
+ Col = facm * Color1 + tint * Color2;
+ }
+
+ Color = mix(Col, Mortar, Fac);
+}
diff --git a/intern/cycles/kernel/shaders/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl
index 00cfb167885..2defbc4b1db 100644
--- a/intern/cycles/kernel/shaders/node_brightness.osl
+++ b/intern/cycles/kernel/shaders/node_brightness.osl
@@ -16,17 +16,15 @@
#include "stdosl.h"
-shader node_brightness(
- color ColorIn = 0.8,
- float Bright = 0.0,
- float Contrast = 0.0,
- output color ColorOut = 0.8)
+shader node_brightness(color ColorIn = 0.8,
+ float Bright = 0.0,
+ float Contrast = 0.0,
+ output color ColorOut = 0.8)
{
- float a = 1.0 + Contrast;
- float b = Bright - Contrast * 0.5;
+ float a = 1.0 + Contrast;
+ float b = Bright - Contrast * 0.5;
- ColorOut[0] = max(a * ColorIn[0] + b, 0.0);
- ColorOut[1] = max(a * ColorIn[1] + b, 0.0);
- ColorOut[2] = max(a * ColorIn[2] + b, 0.0);
+ ColorOut[0] = max(a * ColorIn[0] + b, 0.0);
+ ColorOut[1] = max(a * ColorIn[1] + b, 0.0);
+ ColorOut[2] = max(a * ColorIn[2] + b, 0.0);
}
-
diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl
index a2a4468d5f3..3697bb37fd9 100644
--- a/intern/cycles/kernel/shaders/node_bump.osl
+++ b/intern/cycles/kernel/shaders/node_bump.osl
@@ -19,52 +19,50 @@
/* "Bump Mapping Unparameterized Surfaces on the GPU"
* Morten S. Mikkelsen, 2010 */
-surface node_bump(
- int invert = 0,
- int use_object_space = 0,
- normal NormalIn = N,
- float Strength = 0.1,
- float Distance = 1.0,
- float SampleCenter = 0.0,
- float SampleX = 0.0,
- float SampleY = 0.0,
- output normal NormalOut = N)
+surface node_bump(int invert = 0,
+ int use_object_space = 0,
+ normal NormalIn = N,
+ float Strength = 0.1,
+ float Distance = 1.0,
+ float SampleCenter = 0.0,
+ float SampleX = 0.0,
+ float SampleY = 0.0,
+ output normal NormalOut = N)
{
- point Ptmp = P;
- normal Normal = NormalIn;
+ point Ptmp = P;
+ normal Normal = NormalIn;
- if (use_object_space) {
- Ptmp = transform("object", Ptmp);
- Normal = normalize(transform("object", Normal));
- }
+ if (use_object_space) {
+ Ptmp = transform("object", Ptmp);
+ Normal = normalize(transform("object", Normal));
+ }
- /* get surface tangents from normal */
- vector dPdx = Dx(Ptmp);
- vector dPdy = Dy(Ptmp);
+ /* get surface tangents from normal */
+ vector dPdx = Dx(Ptmp);
+ vector dPdy = Dy(Ptmp);
- vector Rx = cross(dPdy, Normal);
- vector Ry = cross(Normal, dPdx);
+ vector Rx = cross(dPdy, Normal);
+ vector Ry = cross(Normal, dPdx);
- /* compute surface gradient and determinant */
- float det = dot(dPdx, Rx);
- vector surfgrad = (SampleX - SampleCenter) * Rx + (SampleY - SampleCenter) * Ry;
+ /* compute surface gradient and determinant */
+ float det = dot(dPdx, Rx);
+ vector surfgrad = (SampleX - SampleCenter) * Rx + (SampleY - SampleCenter) * Ry;
- float absdet = fabs(det);
+ float absdet = fabs(det);
- float strength = max(Strength, 0.0);
- float dist = Distance;
+ float strength = max(Strength, 0.0);
+ float dist = Distance;
- if (invert)
- dist *= -1.0;
-
- /* compute and output perturbed normal */
- NormalOut = normalize(absdet * Normal - dist * sign(det) * surfgrad);
- NormalOut = normalize(strength * NormalOut + (1.0 - strength) * Normal);
+ if (invert)
+ dist *= -1.0;
- if (use_object_space) {
- NormalOut = normalize(transform("object", "world", NormalOut));
- }
+ /* compute and output perturbed normal */
+ NormalOut = normalize(absdet * Normal - dist * sign(det) * surfgrad);
+ NormalOut = normalize(strength * NormalOut + (1.0 - strength) * Normal);
- NormalOut = ensure_valid_reflection(Ng, I, NormalOut);
-}
+ if (use_object_space) {
+ NormalOut = normalize(transform("object", "world", NormalOut));
+ }
+ NormalOut = ensure_valid_reflection(Ng, I, NormalOut);
+}
diff --git a/intern/cycles/kernel/shaders/node_camera.osl b/intern/cycles/kernel/shaders/node_camera.osl
index 5e90cb8b8ee..833e9e775fe 100644
--- a/intern/cycles/kernel/shaders/node_camera.osl
+++ b/intern/cycles/kernel/shaders/node_camera.osl
@@ -16,16 +16,14 @@
#include "stdosl.h"
-shader node_camera(
- output vector ViewVector = vector(0.0, 0.0, 0.0),
- output float ViewZDepth = 0.0,
- output float ViewDistance = 0.0)
+shader node_camera(output vector ViewVector = vector(0.0, 0.0, 0.0),
+ output float ViewZDepth = 0.0,
+ output float ViewDistance = 0.0)
{
- ViewVector = (vector)transform("world", "camera", P);
+ ViewVector = (vector)transform("world", "camera", P);
- ViewZDepth = fabs(ViewVector[2]);
- ViewDistance = length(ViewVector);
+ ViewZDepth = fabs(ViewVector[2]);
+ ViewDistance = length(ViewVector);
- ViewVector = normalize(ViewVector);
+ ViewVector = normalize(ViewVector);
}
-
diff --git a/intern/cycles/kernel/shaders/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl
index e745cfaee06..e068f7952ed 100644
--- a/intern/cycles/kernel/shaders/node_checker_texture.osl
+++ b/intern/cycles/kernel/shaders/node_checker_texture.osl
@@ -21,44 +21,43 @@
float checker(point ip)
{
- point p;
- p[0] = (ip[0] + 0.000001) * 0.999999;
- p[1] = (ip[1] + 0.000001) * 0.999999;
- p[2] = (ip[2] + 0.000001) * 0.999999;
-
- int xi = (int)fabs(floor(p[0]));
- int yi = (int)fabs(floor(p[1]));
- int zi = (int)fabs(floor(p[2]));
-
- if ((xi % 2 == yi % 2) == (zi % 2)) {
- return 1.0;
- }
- else {
- return 0.0;
- }
+ point p;
+ p[0] = (ip[0] + 0.000001) * 0.999999;
+ p[1] = (ip[1] + 0.000001) * 0.999999;
+ p[2] = (ip[2] + 0.000001) * 0.999999;
+
+ int xi = (int)fabs(floor(p[0]));
+ int yi = (int)fabs(floor(p[1]));
+ int zi = (int)fabs(floor(p[2]));
+
+ if ((xi % 2 == yi % 2) == (zi % 2)) {
+ return 1.0;
+ }
+ else {
+ return 0.0;
+ }
}
shader node_checker_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- float Scale = 5.0,
- point Vector = P,
- color Color1 = 0.8,
- color Color2 = 0.2,
- output float Fac = 0.0,
- output color Color = 0.0)
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ float Scale = 5.0,
+ point Vector = P,
+ color Color1 = 0.8,
+ color Color2 = 0.2,
+ output float Fac = 0.0,
+ output color Color = 0.0)
{
- point p = Vector;
-
- if (use_mapping)
- p = transform(mapping, p);
-
- Fac = checker(p * Scale);
- if (Fac == 1.0) {
- Color = Color1;
- }
- else {
- Color = Color2;
- }
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Fac = checker(p * Scale);
+ if (Fac == 1.0) {
+ Color = Color1;
+ }
+ else {
+ Color = Color2;
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_color.h b/intern/cycles/kernel/shaders/node_color.h
index fc758bef1fa..276c91843e8 100644
--- a/intern/cycles/kernel/shaders/node_color.h
+++ b/intern/cycles/kernel/shaders/node_color.h
@@ -18,135 +18,146 @@
float color_srgb_to_scene_linear(float c)
{
- if (c < 0.04045)
- return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
- else
- return pow((c + 0.055) * (1.0 / 1.055), 2.4);
+ if (c < 0.04045)
+ return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
+ else
+ return pow((c + 0.055) * (1.0 / 1.055), 2.4);
}
float color_scene_linear_to_srgb(float c)
{
- if (c < 0.0031308)
- return (c < 0.0) ? 0.0 : c * 12.92;
- else
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ if (c < 0.0031308)
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ else
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
}
color color_srgb_to_scene_linear(color c)
{
- return color(
- color_srgb_to_scene_linear(c[0]),
- color_srgb_to_scene_linear(c[1]),
- color_srgb_to_scene_linear(c[2]));
+ return color(color_srgb_to_scene_linear(c[0]),
+ color_srgb_to_scene_linear(c[1]),
+ color_srgb_to_scene_linear(c[2]));
}
color color_scene_linear_to_srgb(color c)
{
- return color(
- color_scene_linear_to_srgb(c[0]),
- color_scene_linear_to_srgb(c[1]),
- color_scene_linear_to_srgb(c[2]));
+ return color(color_scene_linear_to_srgb(c[0]),
+ color_scene_linear_to_srgb(c[1]),
+ color_scene_linear_to_srgb(c[2]));
}
color color_unpremultiply(color c, float alpha)
{
- if (alpha != 1.0 && alpha != 0.0)
- return c / alpha;
+ if (alpha != 1.0 && alpha != 0.0)
+ return c / alpha;
- return c;
+ return c;
}
/* Color Operations */
color xyY_to_xyz(float x, float y, float Y)
{
- float X, Z;
+ float X, Z;
- if (y != 0.0) X = (x / y) * Y;
- else X = 0.0;
+ if (y != 0.0)
+ X = (x / y) * Y;
+ else
+ X = 0.0;
- if (y != 0.0 && Y != 0.0) Z = ((1.0 - x - y) / y) * Y;
- else Z = 0.0;
+ if (y != 0.0 && Y != 0.0)
+ Z = ((1.0 - x - y) / y) * Y;
+ else
+ Z = 0.0;
- return color(X, Y, Z);
+ return color(X, Y, Z);
}
color xyz_to_rgb(float x, float y, float z)
{
- return color( 3.240479 * x + -1.537150 * y + -0.498535 * z,
- -0.969256 * x + 1.875991 * y + 0.041556 * z,
- 0.055648 * x + -0.204043 * y + 1.057311 * z);
+ return color(3.240479 * x + -1.537150 * y + -0.498535 * z,
+ -0.969256 * x + 1.875991 * y + 0.041556 * z,
+ 0.055648 * x + -0.204043 * y + 1.057311 * z);
}
color rgb_to_hsv(color rgb)
{
- float cmax, cmin, h, s, v, cdelta;
- color c;
-
- cmax = max(rgb[0], max(rgb[1], rgb[2]));
- cmin = min(rgb[0], min(rgb[1], rgb[2]));
- cdelta = cmax - cmin;
-
- v = cmax;
-
- if (cmax != 0.0) {
- s = cdelta / cmax;
- }
- else {
- s = 0.0;
- h = 0.0;
- }
-
- if (s == 0.0) {
- h = 0.0;
- }
- else {
- c = (color(cmax, cmax, cmax) - rgb) / cdelta;
-
- if (rgb[0] == cmax) h = c[2] - c[1];
- else if (rgb[1] == cmax) h = 2.0 + c[0] - c[2];
- else h = 4.0 + c[1] - c[0];
-
- h /= 6.0;
-
- if (h < 0.0)
- h += 1.0;
- }
-
- return color(h, s, v);
+ float cmax, cmin, h, s, v, cdelta;
+ color c;
+
+ cmax = max(rgb[0], max(rgb[1], rgb[2]));
+ cmin = min(rgb[0], min(rgb[1], rgb[2]));
+ cdelta = cmax - cmin;
+
+ v = cmax;
+
+ if (cmax != 0.0) {
+ s = cdelta / cmax;
+ }
+ else {
+ s = 0.0;
+ h = 0.0;
+ }
+
+ if (s == 0.0) {
+ h = 0.0;
+ }
+ else {
+ c = (color(cmax, cmax, cmax) - rgb) / cdelta;
+
+ if (rgb[0] == cmax)
+ h = c[2] - c[1];
+ else if (rgb[1] == cmax)
+ h = 2.0 + c[0] - c[2];
+ else
+ h = 4.0 + c[1] - c[0];
+
+ h /= 6.0;
+
+ if (h < 0.0)
+ h += 1.0;
+ }
+
+ return color(h, s, v);
}
color hsv_to_rgb(color hsv)
{
- float i, f, p, q, t, h, s, v;
- color rgb;
-
- h = hsv[0];
- s = hsv[1];
- v = hsv[2];
-
- if (s == 0.0) {
- rgb = color(v, v, v);
- }
- else {
- if (h == 1.0)
- h = 0.0;
-
- h *= 6.0;
- i = floor(h);
- f = h - i;
- rgb = color(f, f, f);
- p = v * (1.0 - s);
- q = v * (1.0 - (s * f));
- t = v * (1.0 - (s * (1.0 - f)));
-
- if (i == 0.0) rgb = color(v, t, p);
- else if (i == 1.0) rgb = color(q, v, p);
- else if (i == 2.0) rgb = color(p, v, t);
- else if (i == 3.0) rgb = color(p, q, v);
- else if (i == 4.0) rgb = color(t, p, v);
- else rgb = color(v, p, q);
- }
-
- return rgb;
+ float i, f, p, q, t, h, s, v;
+ color rgb;
+
+ h = hsv[0];
+ s = hsv[1];
+ v = hsv[2];
+
+ if (s == 0.0) {
+ rgb = color(v, v, v);
+ }
+ else {
+ if (h == 1.0)
+ h = 0.0;
+
+ h *= 6.0;
+ i = floor(h);
+ f = h - i;
+ rgb = color(f, f, f);
+ p = v * (1.0 - s);
+ q = v * (1.0 - (s * f));
+ t = v * (1.0 - (s * (1.0 - f)));
+
+ if (i == 0.0)
+ rgb = color(v, t, p);
+ else if (i == 1.0)
+ rgb = color(q, v, p);
+ else if (i == 2.0)
+ rgb = color(p, v, t);
+ else if (i == 3.0)
+ rgb = color(p, q, v);
+ else if (i == 4.0)
+ rgb = color(t, p, v);
+ else
+ rgb = color(v, p, q);
+ }
+
+ return rgb;
}
diff --git a/intern/cycles/kernel/shaders/node_combine_hsv.osl b/intern/cycles/kernel/shaders/node_combine_hsv.osl
index 6b922bf4e6b..1658cf3d774 100644
--- a/intern/cycles/kernel/shaders/node_combine_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_combine_hsv.osl
@@ -16,12 +16,7 @@
#include "stdosl.h"
-shader node_combine_hsv(
- float H = 0.0,
- float S = 0.0,
- float V = 0.0,
- output color Color = 0.8)
+shader node_combine_hsv(float H = 0.0, float S = 0.0, float V = 0.0, output color Color = 0.8)
{
- Color = color("hsv", H, S, V);
+ Color = color("hsv", H, S, V);
}
-
diff --git a/intern/cycles/kernel/shaders/node_combine_rgb.osl b/intern/cycles/kernel/shaders/node_combine_rgb.osl
index f343fdefd84..aaa95e9c5af 100644
--- a/intern/cycles/kernel/shaders/node_combine_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_combine_rgb.osl
@@ -16,12 +16,7 @@
#include "stdosl.h"
-shader node_combine_rgb(
- float R = 0.0,
- float G = 0.0,
- float B = 0.0,
- output color Image = 0.8)
+shader node_combine_rgb(float R = 0.0, float G = 0.0, float B = 0.0, output color Image = 0.8)
{
- Image = color(R, G, B);
+ Image = color(R, G, B);
}
-
diff --git a/intern/cycles/kernel/shaders/node_combine_xyz.osl b/intern/cycles/kernel/shaders/node_combine_xyz.osl
index 86182056b09..4ab49168704 100644
--- a/intern/cycles/kernel/shaders/node_combine_xyz.osl
+++ b/intern/cycles/kernel/shaders/node_combine_xyz.osl
@@ -16,12 +16,7 @@
#include "stdosl.h"
-shader node_combine_xyz(
- float X = 0.0,
- float Y = 0.0,
- float Z = 0.0,
- output vector Vector = 0.8)
+shader node_combine_xyz(float X = 0.0, float Y = 0.0, float Z = 0.0, output vector Vector = 0.8)
{
- Vector = vector(X, Y, Z);
+ Vector = vector(X, Y, Z);
}
-
diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl
index e95a17f6fa1..7ea9a1e4fb3 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_color.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl
@@ -16,19 +16,17 @@
#include "stdosl.h"
-shader node_convert_from_color(
- color value_color = 0.0,
- output string value_string = "",
- output float value_float = 0.0,
- output int value_int = 0,
- output vector value_vector = vector(0.0, 0.0, 0.0),
- output point value_point = point(0.0, 0.0, 0.0),
- output normal value_normal = normal(0.0, 0.0, 0.0))
+shader node_convert_from_color(color value_color = 0.0,
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
{
- value_float = value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722;
- value_int = (int)(value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722);
- value_vector = vector(value_color[0], value_color[1], value_color[2]);
- value_point = point(value_color[0], value_color[1], value_color[2]);
- value_normal = normal(value_color[0], value_color[1], value_color[2]);
+ value_float = value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722;
+ value_int = (int)(value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722);
+ value_vector = vector(value_color[0], value_color[1], value_color[2]);
+ value_point = point(value_color[0], value_color[1], value_color[2]);
+ value_normal = normal(value_color[0], value_color[1], value_color[2]);
}
-
diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl
index a5c2e3b26ad..13b5dea0838 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_float.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl
@@ -16,19 +16,17 @@
#include "stdosl.h"
-shader node_convert_from_float(
- float value_float = 0.0,
- output string value_string = "",
- output int value_int = 0,
- output color value_color = 0.0,
- output vector value_vector = vector(0.0, 0.0, 0.0),
- output point value_point = point(0.0, 0.0, 0.0),
- output normal value_normal = normal(0.0, 0.0, 0.0))
+shader node_convert_from_float(float value_float = 0.0,
+ output string value_string = "",
+ output int value_int = 0,
+ output color value_color = 0.0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
{
- value_int = (int)value_float;
- value_color = color(value_float, value_float, value_float);
- value_vector = vector(value_float, value_float, value_float);
- value_point = point(value_float, value_float, value_float);
- value_normal = normal(value_float, value_float, value_float);
+ value_int = (int)value_float;
+ value_color = color(value_float, value_float, value_float);
+ value_vector = vector(value_float, value_float, value_float);
+ value_point = point(value_float, value_float, value_float);
+ value_normal = normal(value_float, value_float, value_float);
}
-
diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl
index 0e6ae711210..a59e025d822 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_int.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl
@@ -16,20 +16,18 @@
#include "stdosl.h"
-shader node_convert_from_int(
- int value_int = 0,
- output string value_string = "",
- output float value_float = 0.0,
- output color value_color = 0.0,
- output vector value_vector = vector(0.0, 0.0, 0.0),
- output point value_point = point(0.0, 0.0, 0.0),
- output normal value_normal = normal(0.0, 0.0, 0.0))
+shader node_convert_from_int(int value_int = 0,
+ output string value_string = "",
+ output float value_float = 0.0,
+ output color value_color = 0.0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
{
- float f = (float)value_int;
- value_float = f;
- value_color = color(f, f, f);
- value_vector = vector(f, f, f);
- value_point = point(f, f, f);
- value_normal = normal(f, f, f);
+ float f = (float)value_int;
+ value_float = f;
+ value_color = color(f, f, f);
+ value_vector = vector(f, f, f);
+ value_point = point(f, f, f);
+ value_normal = normal(f, f, f);
}
-
diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
index 7fffa7f6169..7bdd94d1941 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
@@ -16,19 +16,17 @@
#include "stdosl.h"
-shader node_convert_from_normal(
- normal value_normal = normal(0.0, 0.0, 0.0),
- output string value_string = "",
- output float value_float = 0.0,
- output int value_int = 0,
- output vector value_vector = vector(0.0, 0.0, 0.0),
- output color value_color = 0.0,
- output point value_point = point(0.0, 0.0, 0.0))
+shader node_convert_from_normal(normal value_normal = normal(0.0, 0.0, 0.0),
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output color value_color = 0.0,
+ output point value_point = point(0.0, 0.0, 0.0))
{
- value_float = (value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0);
- value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
- value_vector = vector(value_normal[0], value_normal[1], value_normal[2]);
- value_color = color(value_normal[0], value_normal[1], value_normal[2]);
- value_point = point(value_normal[0], value_normal[1], value_normal[2]);
+ value_float = (value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0);
+ value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
+ value_vector = vector(value_normal[0], value_normal[1], value_normal[2]);
+ value_color = color(value_normal[0], value_normal[1], value_normal[2]);
+ value_point = point(value_normal[0], value_normal[1], value_normal[2]);
}
-
diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl
index 9e4930296bb..79c1719e7a7 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_point.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl
@@ -16,19 +16,17 @@
#include "stdosl.h"
-shader node_convert_from_point(
- point value_point = point(0.0, 0.0, 0.0),
- output string value_string = "",
- output float value_float = 0.0,
- output int value_int = 0,
- output vector value_vector = vector(0.0, 0.0, 0.0),
- output color value_color = 0.0,
- output normal value_normal = normal(0.0, 0.0, 0.0))
+shader node_convert_from_point(point value_point = point(0.0, 0.0, 0.0),
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output color value_color = 0.0,
+ output normal value_normal = normal(0.0, 0.0, 0.0))
{
- value_float = (value_point[0] + value_point[1] + value_point[2]) * (1.0 / 3.0);
- value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
- value_vector = vector(value_point[0], value_point[1], value_point[2]);
- value_color = color(value_point[0], value_point[1], value_point[2]);
- value_normal = normal(value_point[0], value_point[1], value_point[2]);
+ value_float = (value_point[0] + value_point[1] + value_point[2]) * (1.0 / 3.0);
+ value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
+ value_vector = vector(value_point[0], value_point[1], value_point[2]);
+ value_color = color(value_point[0], value_point[1], value_point[2]);
+ value_normal = normal(value_point[0], value_point[1], value_point[2]);
}
-
diff --git a/intern/cycles/kernel/shaders/node_convert_from_string.osl b/intern/cycles/kernel/shaders/node_convert_from_string.osl
index cbc6653eada..48d894a6b3e 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_string.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_string.osl
@@ -16,14 +16,12 @@
#include "stdosl.h"
-shader node_convert_from_string(
- string value_string = "",
- output color value_color = color(0.0, 0.0, 0.0),
- output float value_float = 0.0,
- output int value_int = 0,
- output vector value_vector = vector(0.0, 0.0, 0.0),
- output point value_point = point(0.0, 0.0, 0.0),
- output normal value_normal = normal(0.0, 0.0, 0.0))
+shader node_convert_from_string(string value_string = "",
+ output color value_color = color(0.0, 0.0, 0.0),
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
{
}
-
diff --git a/intern/cycles/kernel/shaders/node_convert_from_vector.osl b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
index 8bdca469b90..92ab2313bcb 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_vector.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
@@ -16,19 +16,17 @@
#include "stdosl.h"
-shader node_convert_from_vector(
- vector value_vector = vector(0.0, 0.0, 0.0),
- output string value_string = "",
- output float value_float = 0.0,
- output int value_int = 0,
- output color value_color = color(0.0, 0.0, 0.0),
- output point value_point = point(0.0, 0.0, 0.0),
- output normal value_normal = normal(0.0, 0.0, 0.0))
+shader node_convert_from_vector(vector value_vector = vector(0.0, 0.0, 0.0),
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output color value_color = color(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
{
- value_float = (value_vector[0] + value_vector[1] + value_vector[2]) * (1.0 / 3.0);
- value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
- value_color = color(value_vector[0], value_vector[1], value_vector[2]);
- value_point = point(value_vector[0], value_vector[1], value_vector[2]);
- value_normal = normal(value_vector[0], value_vector[1], value_vector[2]);
+ value_float = (value_vector[0] + value_vector[1] + value_vector[2]) * (1.0 / 3.0);
+ value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
+ value_color = color(value_vector[0], value_vector[1], value_vector[2]);
+ value_point = point(value_vector[0], value_vector[1], value_vector[2]);
+ value_normal = normal(value_vector[0], value_vector[1], value_vector[2]);
}
-
diff --git a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
index 2bef2d65baa..bd5554b838a 100644
--- a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
@@ -16,15 +16,13 @@
#include "stdosl.h"
-shader node_diffuse_bsdf(
- color Color = 0.8,
- float Roughness = 0.0,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_diffuse_bsdf(color Color = 0.8,
+ float Roughness = 0.0,
+ normal Normal = N,
+ output closure color BSDF = 0)
{
- if (Roughness == 0.0)
- BSDF = Color * diffuse(Normal);
- else
- BSDF = Color * oren_nayar(Normal, Roughness);
+ if (Roughness == 0.0)
+ BSDF = Color * diffuse(Normal);
+ else
+ BSDF = Color * oren_nayar(Normal, Roughness);
}
-
diff --git a/intern/cycles/kernel/shaders/node_displacement.osl b/intern/cycles/kernel/shaders/node_displacement.osl
index 89f35841527..a1f3b7b7737 100644
--- a/intern/cycles/kernel/shaders/node_displacement.osl
+++ b/intern/cycles/kernel/shaders/node_displacement.osl
@@ -16,23 +16,21 @@
#include "stdosl.h"
-shader node_displacement(
- string space = "object",
- float Height = 0.0,
- float Midlevel = 0.5,
- float Scale = 1.0,
- normal Normal = N,
- output vector Displacement = vector(0.0, 0.0, 0.0))
+shader node_displacement(string space = "object",
+ float Height = 0.0,
+ float Midlevel = 0.5,
+ float Scale = 1.0,
+ normal Normal = N,
+ output vector Displacement = vector(0.0, 0.0, 0.0))
{
- Displacement = Normal;
- if(space == "object") {
- Displacement = transform("object", Displacement);
- }
+ Displacement = Normal;
+ if (space == "object") {
+ Displacement = transform("object", Displacement);
+ }
- Displacement = normalize(Displacement) * (Height - Midlevel) * Scale;
+ Displacement = normalize(Displacement) * (Height - Midlevel) * Scale;
- if(space == "object") {
- Displacement = transform("object", "world", Displacement);
- }
+ if (space == "object") {
+ Displacement = transform("object", "world", Displacement);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_emission.osl b/intern/cycles/kernel/shaders/node_emission.osl
index c36e2a4c0f3..57973f57ac6 100644
--- a/intern/cycles/kernel/shaders/node_emission.osl
+++ b/intern/cycles/kernel/shaders/node_emission.osl
@@ -16,11 +16,7 @@
#include "stdosl.h"
-shader node_emission(
- color Color = 0.8,
- float Strength = 1.0,
- output closure color Emission = 0)
+shader node_emission(color Color = 0.8, float Strength = 1.0, output closure color Emission = 0)
{
- Emission = (Strength * Color) * emission();
+ Emission = (Strength * Color) * emission();
}
-
diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index 95d9d813969..eb32dad392f 100644
--- a/intern/cycles/kernel/shaders/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -19,63 +19,63 @@
vector environment_texture_direction_to_equirectangular(vector dir)
{
- float u = -atan2(dir[1], dir[0]) / (M_2PI) + 0.5;
- float v = atan2(dir[2], hypot(dir[0], dir[1])) / M_PI + 0.5;
+ float u = -atan2(dir[1], dir[0]) / (M_2PI) + 0.5;
+ float v = atan2(dir[2], hypot(dir[0], dir[1])) / M_PI + 0.5;
- return vector(u, v, 0.0);
+ return vector(u, v, 0.0);
}
vector environment_texture_direction_to_mirrorball(vector idir)
{
- vector dir = idir;
- dir[1] -= 1.0;
+ vector dir = idir;
+ dir[1] -= 1.0;
- float div = 2.0 * sqrt(max(-0.5 * dir[1], 0.0));
- if (div > 0.0)
- dir /= div;
+ float div = 2.0 * sqrt(max(-0.5 * dir[1], 0.0));
+ if (div > 0.0)
+ dir /= div;
- float u = 0.5 * (dir[0] + 1.0);
- float v = 0.5 * (dir[2] + 1.0);
+ float u = 0.5 * (dir[0] + 1.0);
+ float v = 0.5 * (dir[2] + 1.0);
- return vector(u, v, 0.0);
+ return vector(u, v, 0.0);
}
shader node_environment_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- vector Vector = P,
- string filename = "",
- string projection = "equirectangular",
- string interpolation = "linear",
- string color_space = "sRGB",
- int is_float = 1,
- int use_alpha = 1,
- output color Color = 0.0,
- output float Alpha = 1.0)
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ vector Vector = P,
+ string filename = "",
+ string projection = "equirectangular",
+ string interpolation = "linear",
+ string color_space = "sRGB",
+ int is_float = 1,
+ int use_alpha = 1,
+ output color Color = 0.0,
+ output float Alpha = 1.0)
{
- vector p = Vector;
+ vector p = Vector;
- if (use_mapping)
- p = transform(mapping, p);
-
- p = normalize(p);
+ if (use_mapping)
+ p = transform(mapping, p);
- if (projection == "equirectangular")
- p = environment_texture_direction_to_equirectangular(p);
- else
- p = environment_texture_direction_to_mirrorball(p);
+ p = normalize(p);
- /* todo: use environment for better texture filtering of equirectangular */
- Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "interp", interpolation, "alpha", Alpha);
+ if (projection == "equirectangular")
+ p = environment_texture_direction_to_equirectangular(p);
+ else
+ p = environment_texture_direction_to_mirrorball(p);
- if (use_alpha) {
- Color = color_unpremultiply(Color, Alpha);
+ /* todo: use environment for better texture filtering of equirectangular */
+ Color = (color)texture(
+ filename, p[0], 1.0 - p[1], "wrap", "periodic", "interp", interpolation, "alpha", Alpha);
- if (!is_float)
- Color = min(Color, 1.0);
- }
+ if (use_alpha) {
+ Color = color_unpremultiply(Color, Alpha);
- if (color_space == "sRGB")
- Color = color_srgb_to_scene_linear(Color);
-}
+ if (!is_float)
+ Color = min(Color, 1.0);
+ }
+ if (color_space == "sRGB")
+ Color = color_srgb_to_scene_linear(Color);
+}
diff --git a/intern/cycles/kernel/shaders/node_fresnel.h b/intern/cycles/kernel/shaders/node_fresnel.h
index 40793479d8a..ade1d4c6207 100644
--- a/intern/cycles/kernel/shaders/node_fresnel.h
+++ b/intern/cycles/kernel/shaders/node_fresnel.h
@@ -32,33 +32,31 @@
float fresnel_dielectric_cos(float cosi, float eta)
{
- /* compute fresnel reflectance without explicitly computing
- * the refracted direction */
- float c = fabs(cosi);
- float g = eta * eta - 1 + c * c;
- float result;
+ /* compute fresnel reflectance without explicitly computing
+ * the refracted direction */
+ float c = fabs(cosi);
+ float g = eta * eta - 1 + c * c;
+ float result;
- if (g > 0) {
- g = sqrt(g);
- float A = (g - c) / (g + c);
- float B = (c * (g + c) - 1) / (c * (g - c) + 1);
- result = 0.5 * A * A * (1 + B * B);
- }
- else
- result = 1.0; /* TIR (no refracted component) */
+ if (g > 0) {
+ g = sqrt(g);
+ float A = (g - c) / (g + c);
+ float B = (c * (g + c) - 1) / (c * (g - c) + 1);
+ result = 0.5 * A * A * (1 + B * B);
+ }
+ else
+ result = 1.0; /* TIR (no refracted component) */
- return result;
+ return result;
}
color fresnel_conductor(float cosi, color eta, color k)
{
- color cosi2 = color(cosi * cosi);
- color one = color(1, 1, 1);
- color tmp_f = eta * eta + k * k;
- color tmp = tmp_f * cosi2;
- color Rparl2 = (tmp - (2.0 * eta * cosi) + one) /
- (tmp + (2.0 * eta * cosi) + one);
- color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) /
- (tmp_f + (2.0 * eta * cosi) + cosi2);
- return (Rparl2 + Rperp2) * 0.5;
+ color cosi2 = color(cosi * cosi);
+ color one = color(1, 1, 1);
+ color tmp_f = eta * eta + k * k;
+ color tmp = tmp_f * cosi2;
+ color Rparl2 = (tmp - (2.0 * eta * cosi) + one) / (tmp + (2.0 * eta * cosi) + one);
+ color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) / (tmp_f + (2.0 * eta * cosi) + cosi2);
+ return (Rparl2 + Rperp2) * 0.5;
}
diff --git a/intern/cycles/kernel/shaders/node_fresnel.osl b/intern/cycles/kernel/shaders/node_fresnel.osl
index 8bec7b432f5..89250db40f3 100644
--- a/intern/cycles/kernel/shaders/node_fresnel.osl
+++ b/intern/cycles/kernel/shaders/node_fresnel.osl
@@ -17,14 +17,10 @@
#include "stdosl.h"
#include "node_fresnel.h"
-shader node_fresnel(
- float IOR = 1.45,
- normal Normal = N,
- output float Fac = 0.0)
+shader node_fresnel(float IOR = 1.45, normal Normal = N, output float Fac = 0.0)
{
- float f = max(IOR, 1e-5);
- float eta = backfacing() ? 1.0 / f : f;
- float cosi = dot(I, Normal);
- Fac = fresnel_dielectric_cos(cosi, eta);
+ float f = max(IOR, 1e-5);
+ float eta = backfacing() ? 1.0 / f : f;
+ float cosi = dot(I, Normal);
+ Fac = fresnel_dielectric_cos(cosi, eta);
}
-
diff --git a/intern/cycles/kernel/shaders/node_gamma.osl b/intern/cycles/kernel/shaders/node_gamma.osl
index bc4c1b34266..9b9c17dc8af 100644
--- a/intern/cycles/kernel/shaders/node_gamma.osl
+++ b/intern/cycles/kernel/shaders/node_gamma.osl
@@ -16,10 +16,7 @@
#include "stdosl.h"
-shader node_gamma(
- color ColorIn = 0.8,
- float Gamma = 1.0,
- output color ColorOut = 0.0)
+shader node_gamma(color ColorIn = 0.8, float Gamma = 1.0, output color ColorOut = 0.0)
{
- ColorOut = pow(ColorIn, Gamma);
+ ColorOut = pow(ColorIn, Gamma);
}
diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index b0bd7692489..b5c1c6611c1 100644
--- a/intern/cycles/kernel/shaders/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -16,55 +16,53 @@
#include "stdosl.h"
-shader node_geometry(
- normal NormalIn = N,
- string bump_offset = "center",
+shader node_geometry(normal NormalIn = N,
+ string bump_offset = "center",
- output point Position = point(0.0, 0.0, 0.0),
- output normal Normal = normal(0.0, 0.0, 0.0),
- output normal Tangent = normal(0.0, 0.0, 0.0),
- output normal TrueNormal = normal(0.0, 0.0, 0.0),
- output vector Incoming = vector(0.0, 0.0, 0.0),
- output point Parametric = point(0.0, 0.0, 0.0),
- output float Backfacing = 0.0,
- output float Pointiness = 0.0)
+ output point Position = point(0.0, 0.0, 0.0),
+ output normal Normal = normal(0.0, 0.0, 0.0),
+ output normal Tangent = normal(0.0, 0.0, 0.0),
+ output normal TrueNormal = normal(0.0, 0.0, 0.0),
+ output vector Incoming = vector(0.0, 0.0, 0.0),
+ output point Parametric = point(0.0, 0.0, 0.0),
+ output float Backfacing = 0.0,
+ output float Pointiness = 0.0)
{
- Position = P;
- Normal = NormalIn;
- TrueNormal = Ng;
- Incoming = I;
- Parametric = point(u, v, 0.0);
- Backfacing = backfacing();
+ Position = P;
+ Normal = NormalIn;
+ TrueNormal = Ng;
+ Incoming = I;
+ Parametric = point(u, v, 0.0);
+ Backfacing = backfacing();
- if (bump_offset == "dx") {
- Position += Dx(Position);
- Parametric += Dx(Parametric);
- }
- else if (bump_offset == "dy") {
- Position += Dy(Position);
- Parametric += Dy(Parametric);
- }
+ if (bump_offset == "dx") {
+ Position += Dx(Position);
+ Parametric += Dx(Parametric);
+ }
+ else if (bump_offset == "dy") {
+ Position += Dy(Position);
+ Parametric += Dy(Parametric);
+ }
- /* first try to get tangent attribute */
- point generated;
+ /* first try to get tangent attribute */
+ point generated;
- /* try to create spherical tangent from generated coordinates */
- if (getattribute("geom:generated", generated)) {
- normal data = normal(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
- vector T = transform("object", "world", data);
- Tangent = cross(Normal, normalize(cross(T, Normal)));
- }
- else {
- /* otherwise use surface derivatives */
- Tangent = normalize(dPdu);
- }
+ /* try to create spherical tangent from generated coordinates */
+ if (getattribute("geom:generated", generated)) {
+ normal data = normal(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
+ vector T = transform("object", "world", data);
+ Tangent = cross(Normal, normalize(cross(T, Normal)));
+ }
+ else {
+ /* otherwise use surface derivatives */
+ Tangent = normalize(dPdu);
+ }
- getattribute("geom:pointiness", Pointiness);
- if (bump_offset == "dx") {
- Pointiness += Dx(Pointiness);
- }
- else if (bump_offset == "dy") {
- Pointiness += Dy(Pointiness);
- }
+ getattribute("geom:pointiness", Pointiness);
+ if (bump_offset == "dx") {
+ Pointiness += Dx(Pointiness);
+ }
+ else if (bump_offset == "dy") {
+ Pointiness += Dy(Pointiness);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
index 2e713861c58..c0b8a002536 100644
--- a/intern/cycles/kernel/shaders/node_glass_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
@@ -17,29 +17,27 @@
#include "stdosl.h"
#include "node_fresnel.h"
-shader node_glass_bsdf(
- color Color = 0.8,
- string distribution = "sharp",
- float Roughness = 0.2,
- float IOR = 1.45,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_glass_bsdf(color Color = 0.8,
+ string distribution = "sharp",
+ float Roughness = 0.2,
+ float IOR = 1.45,
+ normal Normal = N,
+ output closure color BSDF = 0)
{
- float f = max(IOR, 1e-5);
- float eta = backfacing() ? 1.0 / f : f;
- float cosi = dot(I, Normal);
- float Fr = fresnel_dielectric_cos(cosi, eta);
- float roughness = Roughness * Roughness;
+ float f = max(IOR, 1e-5);
+ float eta = backfacing() ? 1.0 / f : f;
+ float cosi = dot(I, Normal);
+ float Fr = fresnel_dielectric_cos(cosi, eta);
+ float roughness = Roughness * Roughness;
- if (distribution == "sharp")
- BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta));
- else if (distribution == "beckmann")
- BSDF = Color * (Fr * microfacet_beckmann(Normal, roughness) +
- (1.0 - Fr) * microfacet_beckmann_refraction(Normal, roughness, eta));
- else if (distribution == "Multiscatter GGX")
- BSDF = Color * microfacet_multi_ggx_glass(Normal, roughness, eta, Color);
- else if (distribution == "GGX")
- BSDF = Color * (Fr * microfacet_ggx(Normal, roughness) +
- (1.0 - Fr) * microfacet_ggx_refraction(Normal, roughness, eta));
+ if (distribution == "sharp")
+ BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta));
+ else if (distribution == "beckmann")
+ BSDF = Color * (Fr * microfacet_beckmann(Normal, roughness) +
+ (1.0 - Fr) * microfacet_beckmann_refraction(Normal, roughness, eta));
+ else if (distribution == "Multiscatter GGX")
+ BSDF = Color * microfacet_multi_ggx_glass(Normal, roughness, eta, Color);
+ else if (distribution == "GGX")
+ BSDF = Color * (Fr * microfacet_ggx(Normal, roughness) +
+ (1.0 - Fr) * microfacet_ggx_refraction(Normal, roughness, eta));
}
-
diff --git a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
index 7415211b56d..2d40ee8d3f6 100644
--- a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
@@ -17,25 +17,22 @@
#include "stdosl.h"
#include "node_fresnel.h"
-shader node_glossy_bsdf(
- color Color = 0.8,
- string distribution = "GGX",
- float Roughness = 0.2,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_glossy_bsdf(color Color = 0.8,
+ string distribution = "GGX",
+ float Roughness = 0.2,
+ normal Normal = N,
+ output closure color BSDF = 0)
{
- float roughness = Roughness * Roughness;
-
- if (distribution == "sharp")
- BSDF = Color * reflection(Normal);
- else if (distribution == "beckmann")
- BSDF = Color * microfacet_beckmann(Normal, roughness);
- else if (distribution == "GGX")
- BSDF = Color * microfacet_ggx(Normal, roughness);
- else if (distribution == "Multiscatter GGX")
- BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color);
- else
- BSDF = Color * ashikhmin_shirley(Normal, vector(0, 0, 0), roughness, roughness);
+ float roughness = Roughness * Roughness;
+ if (distribution == "sharp")
+ BSDF = Color * reflection(Normal);
+ else if (distribution == "beckmann")
+ BSDF = Color * microfacet_beckmann(Normal, roughness);
+ else if (distribution == "GGX")
+ BSDF = Color * microfacet_ggx(Normal, roughness);
+ else if (distribution == "Multiscatter GGX")
+ BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color);
+ else
+ BSDF = Color * ashikhmin_shirley(Normal, vector(0, 0, 0), roughness, roughness);
}
-
diff --git a/intern/cycles/kernel/shaders/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl
index f458937a18f..52bf466673d 100644
--- a/intern/cycles/kernel/shaders/node_gradient_texture.osl
+++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl
@@ -21,59 +21,58 @@
float gradient(point p, string type)
{
- float x, y, z;
-
- x = p[0];
- y = p[1];
- z = p[2];
+ float x, y, z;
- float result = 0.0;
+ x = p[0];
+ y = p[1];
+ z = p[2];
- if (type == "linear") {
- result = x;
- }
- else if (type == "quadratic") {
- float r = max(x, 0.0);
- result = r * r;
- }
- else if (type == "easing") {
- float r = min(max(x, 0.0), 1.0);
- float t = r * r;
-
- result = (3.0 * t - 2.0 * t * r);
- }
- else if (type == "diagonal") {
- result = (x + y) * 0.5;
- }
- else if (type == "radial") {
- result = atan2(y, x) / M_2PI + 0.5;
- }
- else {
- float r = max(1.0 - sqrt(x * x + y * y + z * z), 0.0);
+ float result = 0.0;
- if (type == "quadratic_sphere")
- result = r * r;
- else if (type == "spherical")
- result = r;
- }
+ if (type == "linear") {
+ result = x;
+ }
+ else if (type == "quadratic") {
+ float r = max(x, 0.0);
+ result = r * r;
+ }
+ else if (type == "easing") {
+ float r = min(max(x, 0.0), 1.0);
+ float t = r * r;
- return result;
+ result = (3.0 * t - 2.0 * t * r);
+ }
+ else if (type == "diagonal") {
+ result = (x + y) * 0.5;
+ }
+ else if (type == "radial") {
+ result = atan2(y, x) / M_2PI + 0.5;
+ }
+ else {
+ float r = max(1.0 - sqrt(x * x + y * y + z * z), 0.0);
+
+ if (type == "quadratic_sphere")
+ result = r * r;
+ else if (type == "spherical")
+ result = r;
+ }
+
+ return result;
}
shader node_gradient_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- string type = "linear",
- point Vector = P,
- output float Fac = 0.0,
- output color Color = 0.0)
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ string type = "linear",
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
{
- point p = Vector;
+ point p = Vector;
- if (use_mapping)
- p = transform(mapping, p);
+ if (use_mapping)
+ p = transform(mapping, p);
- Fac = gradient(p, type);
- Color = color(Fac, Fac, Fac);
+ Fac = gradient(p, type);
+ Color = color(Fac, Fac, Fac);
}
-
diff --git a/intern/cycles/kernel/shaders/node_hair_bsdf.osl b/intern/cycles/kernel/shaders/node_hair_bsdf.osl
index ef8f2fae894..bc912087666 100644
--- a/intern/cycles/kernel/shaders/node_hair_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_hair_bsdf.osl
@@ -18,41 +18,40 @@
#include "stdosl.h"
-shader node_hair_bsdf(
- color Color = 0.8,
- string component = "reflection",
- float Offset = 0.0,
- float RoughnessU = 0.1,
- float RoughnessV = 1.0,
- normal Tangent = normal(0, 0, 0),
- output closure color BSDF = 0)
+shader node_hair_bsdf(color Color = 0.8,
+ string component = "reflection",
+ float Offset = 0.0,
+ float RoughnessU = 0.1,
+ float RoughnessV = 1.0,
+ normal Tangent = normal(0, 0, 0),
+ output closure color BSDF = 0)
{
- float roughnessh = clamp(RoughnessU, 0.001, 1.0);
- float roughnessv = clamp(RoughnessV, 0.001, 1.0);
- float offset = -Offset;
+ float roughnessh = clamp(RoughnessU, 0.001, 1.0);
+ float roughnessv = clamp(RoughnessV, 0.001, 1.0);
+ float offset = -Offset;
- normal T;
- float IsCurve = 0;
- getattribute("geom:is_curve", IsCurve);
+ normal T;
+ float IsCurve = 0;
+ getattribute("geom:is_curve", IsCurve);
- if (isconnected(Tangent)) {
- T = Tangent;
- }
- else if(!IsCurve) {
- T = normalize(dPdv);
- offset = 0.0;
- }
- else {
- T = normalize(dPdu);
- }
+ if (isconnected(Tangent)) {
+ T = Tangent;
+ }
+ else if (!IsCurve) {
+ T = normalize(dPdv);
+ offset = 0.0;
+ }
+ else {
+ T = normalize(dPdu);
+ }
- if (backfacing() && IsCurve) {
- BSDF = transparent();
- }
- else {
- if (component == "reflection")
- BSDF = Color * hair_reflection(Ng, roughnessh, roughnessv, T, offset);
- else
- BSDF = Color * hair_transmission(Ng, roughnessh, roughnessv, T, offset);
- }
+ if (backfacing() && IsCurve) {
+ BSDF = transparent();
+ }
+ else {
+ if (component == "reflection")
+ BSDF = Color * hair_reflection(Ng, roughnessh, roughnessv, T, offset);
+ else
+ BSDF = Color * hair_transmission(Ng, roughnessh, roughnessv, T, offset);
+ }
}
diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl
index 19216f67579..991a27c4103 100644
--- a/intern/cycles/kernel/shaders/node_hair_info.osl
+++ b/intern/cycles/kernel/shaders/node_hair_info.osl
@@ -16,17 +16,15 @@
#include "stdosl.h"
-shader node_hair_info(
- output float IsStrand = 0.0,
- output float Intercept = 0.0,
- output float Thickness = 0.0,
- output normal TangentNormal = N,
- output float Random = 0)
+shader node_hair_info(output float IsStrand = 0.0,
+ output float Intercept = 0.0,
+ output float Thickness = 0.0,
+ output normal TangentNormal = N,
+ output float Random = 0)
{
- getattribute("geom:is_curve", IsStrand);
- getattribute("geom:curve_intercept", Intercept);
- getattribute("geom:curve_thickness", Thickness);
- getattribute("geom:curve_tangent_normal", TangentNormal);
- getattribute("geom:curve_random", Random);
+ getattribute("geom:is_curve", IsStrand);
+ getattribute("geom:curve_intercept", Intercept);
+ getattribute("geom:curve_thickness", Thickness);
+ getattribute("geom:curve_tangent_normal", TangentNormal);
+ getattribute("geom:curve_random", Random);
}
-
diff --git a/intern/cycles/kernel/shaders/node_holdout.osl b/intern/cycles/kernel/shaders/node_holdout.osl
index 78a9f46fd15..b51bc0543a5 100644
--- a/intern/cycles/kernel/shaders/node_holdout.osl
+++ b/intern/cycles/kernel/shaders/node_holdout.osl
@@ -16,9 +16,6 @@
#include "stdosl.h"
-shader node_holdout(
- output closure color Holdout = holdout())
+shader node_holdout(output closure color Holdout = holdout())
{
-
}
-
diff --git a/intern/cycles/kernel/shaders/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl
index d72a87a951f..30c56a20a92 100644
--- a/intern/cycles/kernel/shaders/node_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_hsv.osl
@@ -17,28 +17,26 @@
#include "stdosl.h"
#include "node_color.h"
-shader node_hsv(
- float Hue = 0.5,
- float Saturation = 1.0,
- float Value = 1.0,
- float Fac = 0.5,
- color ColorIn = 0.0,
- output color ColorOut = 0.0)
+shader node_hsv(float Hue = 0.5,
+ float Saturation = 1.0,
+ float Value = 1.0,
+ float Fac = 0.5,
+ color ColorIn = 0.0,
+ output color ColorOut = 0.0)
{
- color Color = rgb_to_hsv(ColorIn);
+ color Color = rgb_to_hsv(ColorIn);
- // remember: fmod doesn't work for negative numbers
- Color[0] = fmod(Color[0] + Hue + 0.5, 1.0);
- Color[1] = clamp(Color[1] * Saturation, 0.0, 1.0);
- Color[2] *= Value;
+ // remember: fmod doesn't work for negative numbers
+ Color[0] = fmod(Color[0] + Hue + 0.5, 1.0);
+ Color[1] = clamp(Color[1] * Saturation, 0.0, 1.0);
+ Color[2] *= Value;
- Color = hsv_to_rgb(Color);
+ Color = hsv_to_rgb(Color);
- // Clamp color to prevent negative values cauzed by oversaturation.
- Color[0] = max(Color[0], 0.0);
- Color[1] = max(Color[1], 0.0);
- Color[2] = max(Color[2], 0.0);
+ // Clamp color to prevent negative values cauzed by oversaturation.
+ Color[0] = max(Color[0], 0.0);
+ Color[1] = max(Color[1], 0.0);
+ Color[2] = max(Color[2], 0.0);
- ColorOut = mix(ColorIn, Color, Fac);
+ ColorOut = mix(ColorIn, Color, Fac);
}
-
diff --git a/intern/cycles/kernel/shaders/node_ies_light.osl b/intern/cycles/kernel/shaders/node_ies_light.osl
index a0954e3a444..ea8c44e09de 100644
--- a/intern/cycles/kernel/shaders/node_ies_light.osl
+++ b/intern/cycles/kernel/shaders/node_ies_light.osl
@@ -19,24 +19,23 @@
/* IES Light */
-shader node_ies_light(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- int slot = 0,
- float Strength = 1.0,
- point Vector = I,
- output float Fac = 0.0)
+shader node_ies_light(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ int slot = 0,
+ float Strength = 1.0,
+ point Vector = I,
+ output float Fac = 0.0)
{
- point p = Vector;
+ point p = Vector;
- if (use_mapping) {
- p = transform(mapping, p);
- }
+ if (use_mapping) {
+ p = transform(mapping, p);
+ }
- p = normalize(p);
+ p = normalize(p);
- float v_angle = acos(-p[2]);
- float h_angle = atan2(p[0], p[1]) + M_PI;
+ float v_angle = acos(-p[2]);
+ float h_angle = atan2(p[0], p[1]) + M_PI;
- Fac = Strength * texture(format("@l%d", slot), h_angle, v_angle);
+ Fac = Strength * texture(format("@l%d", slot), h_angle, v_angle);
}
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 7cd2922dd4f..df5eda39985 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -19,217 +19,217 @@
point texco_remap_square(point co)
{
- return (co - point(0.5, 0.5, 0.5)) * 2.0;
+ return (co - point(0.5, 0.5, 0.5)) * 2.0;
}
point map_to_tube(vector dir)
{
- float u, v;
- v = (dir[2] + 1.0) * 0.5;
- float len = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
- if (len > 0.0) {
- u = (1.0 - (atan2(dir[0] / len, dir[1] / len) / M_PI)) * 0.5;
- }
- else {
- v = u = 0.0; /* To avoid un-initialized variables. */
- }
- return point(u, v, 0.0);
+ float u, v;
+ v = (dir[2] + 1.0) * 0.5;
+ float len = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
+ if (len > 0.0) {
+ u = (1.0 - (atan2(dir[0] / len, dir[1] / len) / M_PI)) * 0.5;
+ }
+ else {
+ v = u = 0.0; /* To avoid un-initialized variables. */
+ }
+ return point(u, v, 0.0);
}
point map_to_sphere(vector dir)
{
- float len = length(dir);
- float v, u;
- if (len > 0.0) {
- if (dir[0] == 0.0 && dir[1] == 0.0) {
- u = 0.0; /* Othwise domain error. */
- }
- else {
- u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0;
- }
- v = 1.0 - acos(dir[2] / len) / M_PI;
- }
- else {
- v = u = 0.0; /* To avoid un-initialized variables. */
- }
- return point(u, v, 0.0);
+ float len = length(dir);
+ float v, u;
+ if (len > 0.0) {
+ if (dir[0] == 0.0 && dir[1] == 0.0) {
+ u = 0.0; /* Othwise domain error. */
+ }
+ else {
+ u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0;
+ }
+ v = 1.0 - acos(dir[2] / len) / M_PI;
+ }
+ else {
+ v = u = 0.0; /* To avoid un-initialized variables. */
+ }
+ return point(u, v, 0.0);
}
color image_texture_lookup(string filename,
string color_space,
- float u, float v,
+ float u,
+ float v,
output float Alpha,
int use_alpha,
int is_float,
string interpolation,
string extension)
{
- color rgb = (color)texture(filename, u, 1.0 - v, "wrap", extension, "interp", interpolation, "alpha", Alpha);
+ color rgb = (color)texture(
+ filename, u, 1.0 - v, "wrap", extension, "interp", interpolation, "alpha", Alpha);
- if (use_alpha) {
- rgb = color_unpremultiply(rgb, Alpha);
-
- if (!is_float)
- rgb = min(rgb, 1.0);
- }
+ if (use_alpha) {
+ rgb = color_unpremultiply(rgb, Alpha);
- if (color_space == "sRGB") {
- rgb = color_srgb_to_scene_linear(rgb);
- }
+ if (!is_float)
+ rgb = min(rgb, 1.0);
+ }
- return rgb;
+ if (color_space == "sRGB") {
+ rgb = color_srgb_to_scene_linear(rgb);
+ }
+
+ return rgb;
}
-shader node_image_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- point Vector = P,
- string filename = "",
- string color_space = "sRGB",
- string projection = "flat",
- string interpolation = "smartcubic",
- string extension = "periodic",
- float projection_blend = 0.0,
- int is_float = 1,
- int use_alpha = 1,
- output color Color = 0.0,
- output float Alpha = 1.0)
+shader node_image_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ point Vector = P,
+ string filename = "",
+ string color_space = "sRGB",
+ string projection = "flat",
+ string interpolation = "smartcubic",
+ string extension = "periodic",
+ float projection_blend = 0.0,
+ int is_float = 1,
+ int use_alpha = 1,
+ output color Color = 0.0,
+ output float Alpha = 1.0)
{
- point p = Vector;
-
- if (use_mapping)
- p = transform(mapping, p);
-
- if (projection == "flat") {
- Color = image_texture_lookup(filename,
- color_space,
- p[0], p[1],
- Alpha,
- use_alpha,
- is_float,
- interpolation,
- extension);
- }
- else if (projection == "box") {
- /* object space normal */
- vector Nob = transform("world", "object", N);
-
- /* project from direction vector to barycentric coordinates in triangles */
- Nob = vector(fabs(Nob[0]), fabs(Nob[1]), fabs(Nob[2]));
- Nob /= (Nob[0] + Nob[1] + Nob[2]);
-
- /* basic idea is to think of this as a triangle, each corner representing
- * one of the 3 faces of the cube. in the corners we have single textures,
- * in between we blend between two textures, and in the middle we a blend
- * between three textures.
- *
- * the Nxyz values are the barycentric coordinates in an equilateral
- * triangle, which in case of blending, in the middle has a smaller
- * equilateral triangle where 3 textures blend. this divides things into
- * 7 zones, with an if () test for each zone */
-
- vector weight = vector(0.0, 0.0, 0.0);
- float blend = projection_blend;
- float limit = 0.5 * (1.0 + blend);
-
- /* first test for corners with single texture */
- if (Nob[0] > limit * (Nob[0] + Nob[1]) && Nob[0] > limit * (Nob[0] + Nob[2])) {
- weight[0] = 1.0;
- }
- else if (Nob[1] > limit * (Nob[0] + Nob[1]) && Nob[1] > limit * (Nob[1] + Nob[2])) {
- weight[1] = 1.0;
- }
- else if (Nob[2] > limit * (Nob[0] + Nob[2]) && Nob[2] > limit * (Nob[1] + Nob[2])) {
- weight[2] = 1.0;
- }
- else if (blend > 0.0) {
- /* in case of blending, test for mixes between two textures */
- if (Nob[2] < (1.0 - limit) * (Nob[1] + Nob[0])) {
- weight[0] = Nob[0] / (Nob[0] + Nob[1]);
- weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight[1] = 1.0 - weight[0];
- }
- else if (Nob[0] < (1.0 - limit) * (Nob[1] + Nob[2])) {
- weight[1] = Nob[1] / (Nob[1] + Nob[2]);
- weight[1] = clamp((weight[1] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight[2] = 1.0 - weight[1];
- }
- else if (Nob[1] < (1.0 - limit) * (Nob[0] + Nob[2])) {
- weight[0] = Nob[0] / (Nob[0] + Nob[2]);
- weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight[2] = 1.0 - weight[0];
- }
- else {
- /* last case, we have a mix between three */
- weight[0] = ((2.0 - limit) * Nob[0] + (limit - 1.0)) / (2.0 * limit - 1.0);
- weight[1] = ((2.0 - limit) * Nob[1] + (limit - 1.0)) / (2.0 * limit - 1.0);
- weight[2] = ((2.0 - limit) * Nob[2] + (limit - 1.0)) / (2.0 * limit - 1.0);
- }
- }
- else {
- /* Desperate mode, no valid choice anyway, fallback to one side.*/
- weight[0] = 1.0;
- }
-
- Color = color(0.0, 0.0, 0.0);
- Alpha = 0.0;
-
- float tmp_alpha;
-
- if (weight[0] > 0.0) {
- Color += weight[0] * image_texture_lookup(filename,
- color_space,
- p[1], p[2],
- tmp_alpha,
- use_alpha,
- is_float,
- interpolation,
- extension);
- Alpha += weight[0] * tmp_alpha;
- }
- if (weight[1] > 0.0) {
- Color += weight[1] * image_texture_lookup(filename,
- color_space,
- p[0], p[2],
- tmp_alpha,
- use_alpha,
- is_float,
- interpolation,
- extension);
- Alpha += weight[1] * tmp_alpha;
- }
- if (weight[2] > 0.0) {
- Color += weight[2] * image_texture_lookup(filename,
- color_space,
- p[1], p[0],
- tmp_alpha,
- use_alpha,
- is_float,
- interpolation,
- extension);
- Alpha += weight[2] * tmp_alpha;
- }
- }
- else if (projection == "sphere") {
- point projected = map_to_sphere(texco_remap_square(p));
- Color = image_texture_lookup(filename,
- color_space,
- projected[0], projected[1],
- Alpha,
- use_alpha,
- is_float,
- interpolation,
- extension);
- }
- else if (projection == "tube") {
- point projected = map_to_tube(texco_remap_square(p));
- Color = image_texture_lookup(filename,
- color_space,
- projected[0], projected[1],
- Alpha,
- use_alpha,
- is_float,
- interpolation,
- extension);
- }
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ if (projection == "flat") {
+ Color = image_texture_lookup(
+ filename, color_space, p[0], p[1], Alpha, use_alpha, is_float, interpolation, extension);
+ }
+ else if (projection == "box") {
+ /* object space normal */
+ vector Nob = transform("world", "object", N);
+
+ /* project from direction vector to barycentric coordinates in triangles */
+ Nob = vector(fabs(Nob[0]), fabs(Nob[1]), fabs(Nob[2]));
+ Nob /= (Nob[0] + Nob[1] + Nob[2]);
+
+ /* basic idea is to think of this as a triangle, each corner representing
+ * one of the 3 faces of the cube. in the corners we have single textures,
+ * in between we blend between two textures, and in the middle we a blend
+ * between three textures.
+ *
+ * the Nxyz values are the barycentric coordinates in an equilateral
+ * triangle, which in case of blending, in the middle has a smaller
+ * equilateral triangle where 3 textures blend. this divides things into
+ * 7 zones, with an if () test for each zone */
+
+ vector weight = vector(0.0, 0.0, 0.0);
+ float blend = projection_blend;
+ float limit = 0.5 * (1.0 + blend);
+
+ /* first test for corners with single texture */
+ if (Nob[0] > limit * (Nob[0] + Nob[1]) && Nob[0] > limit * (Nob[0] + Nob[2])) {
+ weight[0] = 1.0;
+ }
+ else if (Nob[1] > limit * (Nob[0] + Nob[1]) && Nob[1] > limit * (Nob[1] + Nob[2])) {
+ weight[1] = 1.0;
+ }
+ else if (Nob[2] > limit * (Nob[0] + Nob[2]) && Nob[2] > limit * (Nob[1] + Nob[2])) {
+ weight[2] = 1.0;
+ }
+ else if (blend > 0.0) {
+ /* in case of blending, test for mixes between two textures */
+ if (Nob[2] < (1.0 - limit) * (Nob[1] + Nob[0])) {
+ weight[0] = Nob[0] / (Nob[0] + Nob[1]);
+ weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight[1] = 1.0 - weight[0];
+ }
+ else if (Nob[0] < (1.0 - limit) * (Nob[1] + Nob[2])) {
+ weight[1] = Nob[1] / (Nob[1] + Nob[2]);
+ weight[1] = clamp((weight[1] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight[2] = 1.0 - weight[1];
+ }
+ else if (Nob[1] < (1.0 - limit) * (Nob[0] + Nob[2])) {
+ weight[0] = Nob[0] / (Nob[0] + Nob[2]);
+ weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight[2] = 1.0 - weight[0];
+ }
+ else {
+ /* last case, we have a mix between three */
+ weight[0] = ((2.0 - limit) * Nob[0] + (limit - 1.0)) / (2.0 * limit - 1.0);
+ weight[1] = ((2.0 - limit) * Nob[1] + (limit - 1.0)) / (2.0 * limit - 1.0);
+ weight[2] = ((2.0 - limit) * Nob[2] + (limit - 1.0)) / (2.0 * limit - 1.0);
+ }
+ }
+ else {
+ /* Desperate mode, no valid choice anyway, fallback to one side.*/
+ weight[0] = 1.0;
+ }
+
+ Color = color(0.0, 0.0, 0.0);
+ Alpha = 0.0;
+
+ float tmp_alpha;
+
+ if (weight[0] > 0.0) {
+ Color += weight[0] * image_texture_lookup(filename,
+ color_space,
+ p[1],
+ p[2],
+ tmp_alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ extension);
+ Alpha += weight[0] * tmp_alpha;
+ }
+ if (weight[1] > 0.0) {
+ Color += weight[1] * image_texture_lookup(filename,
+ color_space,
+ p[0],
+ p[2],
+ tmp_alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ extension);
+ Alpha += weight[1] * tmp_alpha;
+ }
+ if (weight[2] > 0.0) {
+ Color += weight[2] * image_texture_lookup(filename,
+ color_space,
+ p[1],
+ p[0],
+ tmp_alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ extension);
+ Alpha += weight[2] * tmp_alpha;
+ }
+ }
+ else if (projection == "sphere") {
+ point projected = map_to_sphere(texco_remap_square(p));
+ Color = image_texture_lookup(filename,
+ color_space,
+ projected[0],
+ projected[1],
+ Alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ extension);
+ }
+ else if (projection == "tube") {
+ point projected = map_to_tube(texco_remap_square(p));
+ Color = image_texture_lookup(filename,
+ color_space,
+ projected[0],
+ projected[1],
+ Alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ extension);
+ }
}
diff --git a/intern/cycles/kernel/shaders/node_invert.osl b/intern/cycles/kernel/shaders/node_invert.osl
index b33b0a43d63..c7d41e4e129 100644
--- a/intern/cycles/kernel/shaders/node_invert.osl
+++ b/intern/cycles/kernel/shaders/node_invert.osl
@@ -16,12 +16,8 @@
#include "stdosl.h"
-shader node_invert(
- float Fac = 1.0,
- color ColorIn = 0.8,
- output color ColorOut = 0.8)
+shader node_invert(float Fac = 1.0, color ColorIn = 0.8, output color ColorOut = 0.8)
{
- color ColorInv = color(1.0) - ColorIn;
- ColorOut = mix(ColorIn, ColorInv, Fac);
+ color ColorInv = color(1.0) - ColorIn;
+ ColorOut = mix(ColorIn, ColorInv, Fac);
}
-
diff --git a/intern/cycles/kernel/shaders/node_layer_weight.osl b/intern/cycles/kernel/shaders/node_layer_weight.osl
index f583df25773..7c46f28b41b 100644
--- a/intern/cycles/kernel/shaders/node_layer_weight.osl
+++ b/intern/cycles/kernel/shaders/node_layer_weight.osl
@@ -17,29 +17,28 @@
#include "stdosl.h"
#include "node_fresnel.h"
-shader node_layer_weight(
- float Blend = 0.5,
- normal Normal = N,
- output float Fresnel = 0.0,
- output float Facing = 0.0)
+shader node_layer_weight(float Blend = 0.5,
+ normal Normal = N,
+ output float Fresnel = 0.0,
+ output float Facing = 0.0)
{
- float blend = Blend;
- float cosi = dot(I, Normal);
+ float blend = Blend;
+ float cosi = dot(I, Normal);
- /* Fresnel */
- float eta = max(1.0 - Blend, 1e-5);
- eta = backfacing() ? eta : 1.0 / eta;
- Fresnel = fresnel_dielectric_cos(cosi, eta);
+ /* Fresnel */
+ float eta = max(1.0 - Blend, 1e-5);
+ eta = backfacing() ? eta : 1.0 / eta;
+ Fresnel = fresnel_dielectric_cos(cosi, eta);
- /* Facing */
- Facing = fabs(cosi);
+ /* Facing */
+ Facing = fabs(cosi);
- if (blend != 0.5) {
- blend = clamp(blend, 0.0, 1.0 - 1e-5);
- blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
+ if (blend != 0.5) {
+ blend = clamp(blend, 0.0, 1.0 - 1e-5);
+ blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
- Facing = pow(Facing, blend);
- }
+ Facing = pow(Facing, blend);
+ }
- Facing = 1.0 - Facing;
+ Facing = 1.0 - Facing;
}
diff --git a/intern/cycles/kernel/shaders/node_light_falloff.osl b/intern/cycles/kernel/shaders/node_light_falloff.osl
index a594e33d643..d0d7dd9c5aa 100644
--- a/intern/cycles/kernel/shaders/node_light_falloff.osl
+++ b/intern/cycles/kernel/shaders/node_light_falloff.osl
@@ -16,29 +16,27 @@
#include "stdosl.h"
-shader node_light_falloff(
- float Strength = 0.0,
- float Smooth = 0.0,
- output float Quadratic = 0.0,
- output float Linear = 0.0,
- output float Constant = 0.0)
+shader node_light_falloff(float Strength = 0.0,
+ float Smooth = 0.0,
+ output float Quadratic = 0.0,
+ output float Linear = 0.0,
+ output float Constant = 0.0)
{
- float ray_length = 0.0;
- float strength = Strength;
- getattribute("path:ray_length", ray_length);
+ float ray_length = 0.0;
+ float strength = Strength;
+ getattribute("path:ray_length", ray_length);
- if (Smooth > 0.0) {
- float squared = ray_length * ray_length;
- strength *= squared / (Smooth + squared);
- }
+ if (Smooth > 0.0) {
+ float squared = ray_length * ray_length;
+ strength *= squared / (Smooth + squared);
+ }
- /* Quadratic */
- Quadratic = strength;
-
- /* Linear */
- Linear = (strength * ray_length);
+ /* Quadratic */
+ Quadratic = strength;
- /* Constant */
- Constant = (strength * ray_length * ray_length);
-}
+ /* Linear */
+ Linear = (strength * ray_length);
+ /* Constant */
+ Constant = (strength * ray_length * ray_length);
+}
diff --git a/intern/cycles/kernel/shaders/node_light_path.osl b/intern/cycles/kernel/shaders/node_light_path.osl
index 64fe4c20132..c4a3624a67f 100644
--- a/intern/cycles/kernel/shaders/node_light_path.osl
+++ b/intern/cycles/kernel/shaders/node_light_path.osl
@@ -16,51 +16,49 @@
#include "stdosl.h"
-shader node_light_path(
- output float IsCameraRay = 0.0,
- output float IsShadowRay = 0.0,
- output float IsDiffuseRay = 0.0,
- output float IsGlossyRay = 0.0,
- output float IsSingularRay = 0.0,
- output float IsReflectionRay = 0.0,
- output float IsTransmissionRay = 0.0,
- output float IsVolumeScatterRay = 0.0,
- output float RayLength = 0.0,
- output float RayDepth = 0.0,
- output float DiffuseDepth = 0.0,
- output float GlossyDepth = 0.0,
- output float TransparentDepth = 0.0,
- output float TransmissionDepth = 0.0)
+shader node_light_path(output float IsCameraRay = 0.0,
+ output float IsShadowRay = 0.0,
+ output float IsDiffuseRay = 0.0,
+ output float IsGlossyRay = 0.0,
+ output float IsSingularRay = 0.0,
+ output float IsReflectionRay = 0.0,
+ output float IsTransmissionRay = 0.0,
+ output float IsVolumeScatterRay = 0.0,
+ output float RayLength = 0.0,
+ output float RayDepth = 0.0,
+ output float DiffuseDepth = 0.0,
+ output float GlossyDepth = 0.0,
+ output float TransparentDepth = 0.0,
+ output float TransmissionDepth = 0.0)
{
- IsCameraRay = raytype("camera");
- IsShadowRay = raytype("shadow");
- IsDiffuseRay = raytype("diffuse");
- IsGlossyRay = raytype("glossy");
- IsSingularRay = raytype("singular");
- IsReflectionRay = raytype("reflection");
- IsTransmissionRay = raytype("refraction");
- IsVolumeScatterRay = raytype("volume_scatter");
+ IsCameraRay = raytype("camera");
+ IsShadowRay = raytype("shadow");
+ IsDiffuseRay = raytype("diffuse");
+ IsGlossyRay = raytype("glossy");
+ IsSingularRay = raytype("singular");
+ IsReflectionRay = raytype("reflection");
+ IsTransmissionRay = raytype("refraction");
+ IsVolumeScatterRay = raytype("volume_scatter");
- getattribute("path:ray_length", RayLength);
+ getattribute("path:ray_length", RayLength);
- int ray_depth;
- getattribute("path:ray_depth", ray_depth);
- RayDepth = (float)ray_depth;
+ int ray_depth;
+ getattribute("path:ray_depth", ray_depth);
+ RayDepth = (float)ray_depth;
- int diffuse_depth;
- getattribute("path:diffuse_depth", diffuse_depth);
- DiffuseDepth = (float)diffuse_depth;
+ int diffuse_depth;
+ getattribute("path:diffuse_depth", diffuse_depth);
+ DiffuseDepth = (float)diffuse_depth;
- int glossy_depth;
- getattribute("path:glossy_depth", glossy_depth);
- GlossyDepth = (float)glossy_depth;
+ int glossy_depth;
+ getattribute("path:glossy_depth", glossy_depth);
+ GlossyDepth = (float)glossy_depth;
- int transparent_depth;
- getattribute("path:transparent_depth", transparent_depth);
- TransparentDepth = (float)transparent_depth;
+ int transparent_depth;
+ getattribute("path:transparent_depth", transparent_depth);
+ TransparentDepth = (float)transparent_depth;
- int transmission_depth;
- getattribute("path:transmission_depth", transmission_depth);
- TransmissionDepth = (float)transmission_depth;
+ int transmission_depth;
+ getattribute("path:transmission_depth", transmission_depth);
+ TransmissionDepth = (float)transmission_depth;
}
-
diff --git a/intern/cycles/kernel/shaders/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl
index 8d6af391e04..aa700e575ef 100644
--- a/intern/cycles/kernel/shaders/node_magic_texture.osl
+++ b/intern/cycles/kernel/shaders/node_magic_texture.osl
@@ -21,91 +21,89 @@
color magic(point p, int n, float distortion)
{
- float dist = distortion;
-
- float x = sin(( p[0] + p[1] + p[2]) * 5.0);
- float y = cos((-p[0] + p[1] - p[2]) * 5.0);
- float z = -cos((-p[0] - p[1] + p[2]) * 5.0);
-
- if (n > 0) {
- x *= dist;
- y *= dist;
- z *= dist;
- y = -cos(x - y + z);
- y *= dist;
-
- if (n > 1) {
- x = cos(x - y - z);
- x *= dist;
-
- if (n > 2) {
- z = sin(-x - y - z);
- z *= dist;
-
- if (n > 3) {
- x = -cos(-x + y - z);
- x *= dist;
-
- if (n > 4) {
- y = -sin(-x + y + z);
- y *= dist;
-
- if (n > 5) {
- y = -cos(-x + y + z);
- y *= dist;
-
- if (n > 6) {
- x = cos(x + y + z);
- x *= dist;
-
- if (n > 7) {
- z = sin(x + y - z);
- z *= dist;
-
- if (n > 8) {
- x = -cos(-x - y + z);
- x *= dist;
-
- if (n > 9) {
- y = -sin(x - y + z);
- y *= dist;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (dist != 0.0) {
- dist *= 2.0;
- x /= dist;
- y /= dist;
- z /= dist;
- }
-
- return color(0.5 - x, 0.5 - y, 0.5 - z);
+ float dist = distortion;
+
+ float x = sin((p[0] + p[1] + p[2]) * 5.0);
+ float y = cos((-p[0] + p[1] - p[2]) * 5.0);
+ float z = -cos((-p[0] - p[1] + p[2]) * 5.0);
+
+ if (n > 0) {
+ x *= dist;
+ y *= dist;
+ z *= dist;
+ y = -cos(x - y + z);
+ y *= dist;
+
+ if (n > 1) {
+ x = cos(x - y - z);
+ x *= dist;
+
+ if (n > 2) {
+ z = sin(-x - y - z);
+ z *= dist;
+
+ if (n > 3) {
+ x = -cos(-x + y - z);
+ x *= dist;
+
+ if (n > 4) {
+ y = -sin(-x + y + z);
+ y *= dist;
+
+ if (n > 5) {
+ y = -cos(-x + y + z);
+ y *= dist;
+
+ if (n > 6) {
+ x = cos(x + y + z);
+ x *= dist;
+
+ if (n > 7) {
+ z = sin(x + y - z);
+ z *= dist;
+
+ if (n > 8) {
+ x = -cos(-x - y + z);
+ x *= dist;
+
+ if (n > 9) {
+ y = -sin(x - y + z);
+ y *= dist;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (dist != 0.0) {
+ dist *= 2.0;
+ x /= dist;
+ y /= dist;
+ z /= dist;
+ }
+
+ return color(0.5 - x, 0.5 - y, 0.5 - z);
}
-shader node_magic_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- int depth = 2,
- float Distortion = 5.0,
- float Scale = 5.0,
- point Vector = P,
- output float Fac = 0.0,
- output color Color = 0.0)
+shader node_magic_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ int depth = 2,
+ float Distortion = 5.0,
+ float Scale = 5.0,
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
{
- point p = Vector;
+ point p = Vector;
- if (use_mapping)
- p = transform(mapping, p);
+ if (use_mapping)
+ p = transform(mapping, p);
- Color = magic(p * Scale, depth, Distortion);
- Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
+ Color = magic(p * Scale, depth, Distortion);
+ Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
}
-
diff --git a/intern/cycles/kernel/shaders/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl
index 69106957ee4..f5cc2d1c5dd 100644
--- a/intern/cycles/kernel/shaders/node_mapping.osl
+++ b/intern/cycles/kernel/shaders/node_mapping.osl
@@ -16,18 +16,17 @@
#include "stdosl.h"
-shader node_mapping(
- matrix Matrix = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- point mapping_min = point(0.0, 0.0, 0.0),
- point mapping_max = point(0.0, 0.0, 0.0),
- int use_minmax = 0,
- point VectorIn = point(0.0, 0.0, 0.0),
- output point VectorOut = point(0.0, 0.0, 0.0))
+shader node_mapping(matrix Matrix = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ point mapping_min = point(0.0, 0.0, 0.0),
+ point mapping_max = point(0.0, 0.0, 0.0),
+ int use_minmax = 0,
+ point VectorIn = point(0.0, 0.0, 0.0),
+ output point VectorOut = point(0.0, 0.0, 0.0))
{
- point p = transform(Matrix, VectorIn);
+ point p = transform(Matrix, VectorIn);
- if (use_minmax)
- p = min(max(mapping_min, p), mapping_max);
-
- VectorOut = p;
+ if (use_minmax)
+ p = min(max(mapping_min, p), mapping_max);
+
+ VectorOut = p;
}
diff --git a/intern/cycles/kernel/shaders/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl
index aa9f6e671c3..8830339e05f 100644
--- a/intern/cycles/kernel/shaders/node_math.osl
+++ b/intern/cycles/kernel/shaders/node_math.osl
@@ -18,107 +18,105 @@
float safe_divide(float a, float b)
{
- float result;
+ float result;
- if (b == 0.0)
- result = 0.0;
- else
- result = a / b;
-
- return result;
+ if (b == 0.0)
+ result = 0.0;
+ else
+ result = a / b;
+
+ return result;
}
float safe_modulo(float a, float b)
{
- float result;
+ float result;
+
+ if (b == 0.0)
+ result = 0.0;
+ else
+ result = fmod(a, b);
- if (b == 0.0)
- result = 0.0;
- else
- result = fmod(a, b);
-
- return result;
+ return result;
}
float safe_sqrt(float a)
{
- float result;
+ float result;
- if (a > 0.0)
- result = sqrt(a);
- else
- result = 0.0;
+ if (a > 0.0)
+ result = sqrt(a);
+ else
+ result = 0.0;
- return result;
+ return result;
}
float safe_log(float a, float b)
{
- if (a < 0.0 || b < 0.0)
- return 0.0;
-
- return log(a) / log(b);
+ if (a < 0.0 || b < 0.0)
+ return 0.0;
+
+ return log(a) / log(b);
}
-shader node_math(
- string type = "add",
- int use_clamp = 0,
- float Value1 = 0.0,
- float Value2 = 0.0,
- output float Value = 0.0)
+shader node_math(string type = "add",
+ int use_clamp = 0,
+ float Value1 = 0.0,
+ float Value2 = 0.0,
+ output float Value = 0.0)
{
- /* OSL asin, acos, pow check for values that could give rise to nan */
+ /* OSL asin, acos, pow check for values that could give rise to nan */
- if (type == "add")
- Value = Value1 + Value2;
- else if (type == "subtract")
- Value = Value1 - Value2;
- else if (type == "multiply")
- Value = Value1 * Value2;
- else if (type == "divide")
- Value = safe_divide(Value1, Value2);
- else if (type == "sine")
- Value = sin(Value1);
- else if (type == "cosine")
- Value = cos(Value1);
- else if (type == "tangent")
- Value = tan(Value1);
- else if (type == "arcsine")
- Value = asin(Value1);
- else if (type == "arccosine")
- Value = acos(Value1);
- else if (type == "arctangent")
- Value = atan(Value1);
- else if (type == "power")
- Value = pow(Value1, Value2);
- else if (type == "logarithm")
- Value = safe_log(Value1, Value2);
- else if (type == "minimum")
- Value = min(Value1, Value2);
- else if (type == "maximum")
- Value = max(Value1, Value2);
- else if (type == "round")
- Value = floor(Value1 + 0.5);
- else if (type == "less_than")
- Value = Value1 < Value2;
- else if (type == "greater_than")
- Value = Value1 > Value2;
- else if (type == "modulo")
- Value = safe_modulo(Value1, Value2);
- else if (type == "absolute")
- Value = fabs(Value1);
- else if (type == "arctan2")
- Value = atan2(Value1, Value2);
- else if (type == "floor")
- Value = floor(Value1);
- else if (type == "ceil")
- Value = ceil(Value1);
- else if (type == "fract")
- Value = Value1 - floor(Value1);
- else if (type == "sqrt")
- Value = safe_sqrt(Value1);
+ if (type == "add")
+ Value = Value1 + Value2;
+ else if (type == "subtract")
+ Value = Value1 - Value2;
+ else if (type == "multiply")
+ Value = Value1 * Value2;
+ else if (type == "divide")
+ Value = safe_divide(Value1, Value2);
+ else if (type == "sine")
+ Value = sin(Value1);
+ else if (type == "cosine")
+ Value = cos(Value1);
+ else if (type == "tangent")
+ Value = tan(Value1);
+ else if (type == "arcsine")
+ Value = asin(Value1);
+ else if (type == "arccosine")
+ Value = acos(Value1);
+ else if (type == "arctangent")
+ Value = atan(Value1);
+ else if (type == "power")
+ Value = pow(Value1, Value2);
+ else if (type == "logarithm")
+ Value = safe_log(Value1, Value2);
+ else if (type == "minimum")
+ Value = min(Value1, Value2);
+ else if (type == "maximum")
+ Value = max(Value1, Value2);
+ else if (type == "round")
+ Value = floor(Value1 + 0.5);
+ else if (type == "less_than")
+ Value = Value1 < Value2;
+ else if (type == "greater_than")
+ Value = Value1 > Value2;
+ else if (type == "modulo")
+ Value = safe_modulo(Value1, Value2);
+ else if (type == "absolute")
+ Value = fabs(Value1);
+ else if (type == "arctan2")
+ Value = atan2(Value1, Value2);
+ else if (type == "floor")
+ Value = floor(Value1);
+ else if (type == "ceil")
+ Value = ceil(Value1);
+ else if (type == "fract")
+ Value = Value1 - floor(Value1);
+ else if (type == "sqrt")
+ Value = safe_sqrt(Value1);
- if (use_clamp)
- Value = clamp(Value, 0.0, 1.0);
+ if (use_clamp)
+ Value = clamp(Value, 0.0, 1.0);
}
-
diff --git a/intern/cycles/kernel/shaders/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl
index 0862c34b6e1..8caea6803ed 100644
--- a/intern/cycles/kernel/shaders/node_mix.osl
+++ b/intern/cycles/kernel/shaders/node_mix.osl
@@ -19,311 +19,312 @@
color node_mix_blend(float t, color col1, color col2)
{
- return mix(col1, col2, t);
+ return mix(col1, col2, t);
}
color node_mix_add(float t, color col1, color col2)
{
- return mix(col1, col1 + col2, t);
+ return mix(col1, col1 + col2, t);
}
color node_mix_mul(float t, color col1, color col2)
{
- return mix(col1, col1 * col2, t);
+ return mix(col1, col1 * col2, t);
}
color node_mix_screen(float t, color col1, color col2)
{
- float tm = 1.0 - t;
+ float tm = 1.0 - t;
- return color(1.0) - (color(tm) + t * (color(1.0) - col2)) * (color(1.0) - col1);
+ return color(1.0) - (color(tm) + t * (color(1.0) - col2)) * (color(1.0) - col1);
}
color node_mix_overlay(float t, color col1, color col2)
{
- float tm = 1.0 - t;
-
- color outcol = col1;
-
- if (outcol[0] < 0.5)
- outcol[0] *= tm + 2.0 * t * col2[0];
- else
- outcol[0] = 1.0 - (tm + 2.0 * t * (1.0 - col2[0])) * (1.0 - outcol[0]);
-
- if (outcol[1] < 0.5)
- outcol[1] *= tm + 2.0 * t * col2[1];
- else
- outcol[1] = 1.0 - (tm + 2.0 * t * (1.0 - col2[1])) * (1.0 - outcol[1]);
-
- if (outcol[2] < 0.5)
- outcol[2] *= tm + 2.0 * t * col2[2];
- else
- outcol[2] = 1.0 - (tm + 2.0 * t * (1.0 - col2[2])) * (1.0 - outcol[2]);
-
- return outcol;
+ float tm = 1.0 - t;
+
+ color outcol = col1;
+
+ if (outcol[0] < 0.5)
+ outcol[0] *= tm + 2.0 * t * col2[0];
+ else
+ outcol[0] = 1.0 - (tm + 2.0 * t * (1.0 - col2[0])) * (1.0 - outcol[0]);
+
+ if (outcol[1] < 0.5)
+ outcol[1] *= tm + 2.0 * t * col2[1];
+ else
+ outcol[1] = 1.0 - (tm + 2.0 * t * (1.0 - col2[1])) * (1.0 - outcol[1]);
+
+ if (outcol[2] < 0.5)
+ outcol[2] *= tm + 2.0 * t * col2[2];
+ else
+ outcol[2] = 1.0 - (tm + 2.0 * t * (1.0 - col2[2])) * (1.0 - outcol[2]);
+
+ return outcol;
}
color node_mix_sub(float t, color col1, color col2)
{
- return mix(col1, col1 - col2, t);
+ return mix(col1, col1 - col2, t);
}
color node_mix_div(float t, color col1, color col2)
{
- float tm = 1.0 - t;
+ float tm = 1.0 - t;
- color outcol = col1;
+ color outcol = col1;
- if (col2[0] != 0.0) outcol[0] = tm * outcol[0] + t * outcol[0] / col2[0];
- if (col2[1] != 0.0) outcol[1] = tm * outcol[1] + t * outcol[1] / col2[1];
- if (col2[2] != 0.0) outcol[2] = tm * outcol[2] + t * outcol[2] / col2[2];
+ if (col2[0] != 0.0)
+ outcol[0] = tm * outcol[0] + t * outcol[0] / col2[0];
+ if (col2[1] != 0.0)
+ outcol[1] = tm * outcol[1] + t * outcol[1] / col2[1];
+ if (col2[2] != 0.0)
+ outcol[2] = tm * outcol[2] + t * outcol[2] / col2[2];
- return outcol;
+ return outcol;
}
color node_mix_diff(float t, color col1, color col2)
{
- return mix(col1, abs(col1 - col2), t);
+ return mix(col1, abs(col1 - col2), t);
}
color node_mix_dark(float t, color col1, color col2)
{
- return min(col1, col2) * t + col1 * (1.0 - t);
+ return min(col1, col2) * t + col1 * (1.0 - t);
}
color node_mix_light(float t, color col1, color col2)
{
- return max(col1, col2 * t);
+ return max(col1, col2 * t);
}
color node_mix_dodge(float t, color col1, color col2)
{
- color outcol = col1;
-
- if (outcol[0] != 0.0) {
- float tmp = 1.0 - t * col2[0];
- if (tmp <= 0.0)
- outcol[0] = 1.0;
- else if ((tmp = outcol[0] / tmp) > 1.0)
- outcol[0] = 1.0;
- else
- outcol[0] = tmp;
- }
- if (outcol[1] != 0.0) {
- float tmp = 1.0 - t * col2[1];
- if (tmp <= 0.0)
- outcol[1] = 1.0;
- else if ((tmp = outcol[1] / tmp) > 1.0)
- outcol[1] = 1.0;
- else
- outcol[1] = tmp;
- }
- if (outcol[2] != 0.0) {
- float tmp = 1.0 - t * col2[2];
- if (tmp <= 0.0)
- outcol[2] = 1.0;
- else if ((tmp = outcol[2] / tmp) > 1.0)
- outcol[2] = 1.0;
- else
- outcol[2] = tmp;
- }
-
- return outcol;
+ color outcol = col1;
+
+ if (outcol[0] != 0.0) {
+ float tmp = 1.0 - t * col2[0];
+ if (tmp <= 0.0)
+ outcol[0] = 1.0;
+ else if ((tmp = outcol[0] / tmp) > 1.0)
+ outcol[0] = 1.0;
+ else
+ outcol[0] = tmp;
+ }
+ if (outcol[1] != 0.0) {
+ float tmp = 1.0 - t * col2[1];
+ if (tmp <= 0.0)
+ outcol[1] = 1.0;
+ else if ((tmp = outcol[1] / tmp) > 1.0)
+ outcol[1] = 1.0;
+ else
+ outcol[1] = tmp;
+ }
+ if (outcol[2] != 0.0) {
+ float tmp = 1.0 - t * col2[2];
+ if (tmp <= 0.0)
+ outcol[2] = 1.0;
+ else if ((tmp = outcol[2] / tmp) > 1.0)
+ outcol[2] = 1.0;
+ else
+ outcol[2] = tmp;
+ }
+
+ return outcol;
}
color node_mix_burn(float t, color col1, color col2)
{
- float tmp, tm = 1.0 - t;
-
- color outcol = col1;
-
- tmp = tm + t * col2[0];
- if (tmp <= 0.0)
- outcol[0] = 0.0;
- else if ((tmp = (1.0 - (1.0 - outcol[0]) / tmp)) < 0.0)
- outcol[0] = 0.0;
- else if (tmp > 1.0)
- outcol[0] = 1.0;
- else
- outcol[0] = tmp;
-
- tmp = tm + t * col2[1];
- if (tmp <= 0.0)
- outcol[1] = 0.0;
- else if ((tmp = (1.0 - (1.0 - outcol[1]) / tmp)) < 0.0)
- outcol[1] = 0.0;
- else if (tmp > 1.0)
- outcol[1] = 1.0;
- else
- outcol[1] = tmp;
-
- tmp = tm + t * col2[2];
- if (tmp <= 0.0)
- outcol[2] = 0.0;
- else if ((tmp = (1.0 - (1.0 - outcol[2]) / tmp)) < 0.0)
- outcol[2] = 0.0;
- else if (tmp > 1.0)
- outcol[2] = 1.0;
- else
- outcol[2] = tmp;
-
- return outcol;
+ float tmp, tm = 1.0 - t;
+
+ color outcol = col1;
+
+ tmp = tm + t * col2[0];
+ if (tmp <= 0.0)
+ outcol[0] = 0.0;
+ else if ((tmp = (1.0 - (1.0 - outcol[0]) / tmp)) < 0.0)
+ outcol[0] = 0.0;
+ else if (tmp > 1.0)
+ outcol[0] = 1.0;
+ else
+ outcol[0] = tmp;
+
+ tmp = tm + t * col2[1];
+ if (tmp <= 0.0)
+ outcol[1] = 0.0;
+ else if ((tmp = (1.0 - (1.0 - outcol[1]) / tmp)) < 0.0)
+ outcol[1] = 0.0;
+ else if (tmp > 1.0)
+ outcol[1] = 1.0;
+ else
+ outcol[1] = tmp;
+
+ tmp = tm + t * col2[2];
+ if (tmp <= 0.0)
+ outcol[2] = 0.0;
+ else if ((tmp = (1.0 - (1.0 - outcol[2]) / tmp)) < 0.0)
+ outcol[2] = 0.0;
+ else if (tmp > 1.0)
+ outcol[2] = 1.0;
+ else
+ outcol[2] = tmp;
+
+ return outcol;
}
color node_mix_hue(float t, color col1, color col2)
{
- color outcol = col1;
- color hsv2 = rgb_to_hsv(col2);
+ color outcol = col1;
+ color hsv2 = rgb_to_hsv(col2);
- if (hsv2[1] != 0.0) {
- color hsv = rgb_to_hsv(outcol);
- hsv[0] = hsv2[0];
- color tmp = hsv_to_rgb(hsv);
+ if (hsv2[1] != 0.0) {
+ color hsv = rgb_to_hsv(outcol);
+ hsv[0] = hsv2[0];
+ color tmp = hsv_to_rgb(hsv);
- outcol = mix(outcol, tmp, t);
- }
+ outcol = mix(outcol, tmp, t);
+ }
- return outcol;
+ return outcol;
}
color node_mix_sat(float t, color col1, color col2)
{
- float tm = 1.0 - t;
+ float tm = 1.0 - t;
- color outcol = col1;
+ color outcol = col1;
- color hsv = rgb_to_hsv(outcol);
+ color hsv = rgb_to_hsv(outcol);
- if (hsv[1] != 0.0) {
- color hsv2 = rgb_to_hsv(col2);
+ if (hsv[1] != 0.0) {
+ color hsv2 = rgb_to_hsv(col2);
- hsv[1] = tm * hsv[1] + t * hsv2[1];
- outcol = hsv_to_rgb(hsv);
- }
+ hsv[1] = tm * hsv[1] + t * hsv2[1];
+ outcol = hsv_to_rgb(hsv);
+ }
- return outcol;
+ return outcol;
}
color node_mix_val(float t, color col1, color col2)
{
- float tm = 1.0 - t;
+ float tm = 1.0 - t;
- color hsv = rgb_to_hsv(col1);
- color hsv2 = rgb_to_hsv(col2);
+ color hsv = rgb_to_hsv(col1);
+ color hsv2 = rgb_to_hsv(col2);
- hsv[2] = tm * hsv[2] + t * hsv2[2];
+ hsv[2] = tm * hsv[2] + t * hsv2[2];
- return hsv_to_rgb(hsv);
+ return hsv_to_rgb(hsv);
}
color node_mix_color(float t, color col1, color col2)
{
- color outcol = col1;
- color hsv2 = rgb_to_hsv(col2);
+ color outcol = col1;
+ color hsv2 = rgb_to_hsv(col2);
- if (hsv2[1] != 0.0) {
- color hsv = rgb_to_hsv(outcol);
- hsv[0] = hsv2[0];
- hsv[1] = hsv2[1];
- color tmp = hsv_to_rgb(hsv);
+ if (hsv2[1] != 0.0) {
+ color hsv = rgb_to_hsv(outcol);
+ hsv[0] = hsv2[0];
+ hsv[1] = hsv2[1];
+ color tmp = hsv_to_rgb(hsv);
- outcol = mix(outcol, tmp, t);
- }
+ outcol = mix(outcol, tmp, t);
+ }
- return outcol;
+ return outcol;
}
color node_mix_soft(float t, color col1, color col2)
{
- float tm = 1.0 - t;
+ float tm = 1.0 - t;
- color one = color(1.0);
- color scr = one - (one - col2) * (one - col1);
+ color one = color(1.0);
+ color scr = one - (one - col2) * (one - col1);
- return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr);
+ return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr);
}
color node_mix_linear(float t, color col1, color col2)
{
- color outcol = col1;
-
- if (col2[0] > 0.5)
- outcol[0] = col1[0] + t * (2.0 * (col2[0] - 0.5));
- else
- outcol[0] = col1[0] + t * (2.0 * (col2[0]) - 1.0);
-
- if (col2[1] > 0.5)
- outcol[1] = col1[1] + t * (2.0 * (col2[1] - 0.5));
- else
- outcol[1] = col1[1] + t * (2.0 * (col2[1]) - 1.0);
-
- if (col2[2] > 0.5)
- outcol[2] = col1[2] + t * (2.0 * (col2[2] - 0.5));
- else
- outcol[2] = col1[2] + t * (2.0 * (col2[2]) - 1.0);
-
- return outcol;
+ color outcol = col1;
+
+ if (col2[0] > 0.5)
+ outcol[0] = col1[0] + t * (2.0 * (col2[0] - 0.5));
+ else
+ outcol[0] = col1[0] + t * (2.0 * (col2[0]) - 1.0);
+
+ if (col2[1] > 0.5)
+ outcol[1] = col1[1] + t * (2.0 * (col2[1] - 0.5));
+ else
+ outcol[1] = col1[1] + t * (2.0 * (col2[1]) - 1.0);
+
+ if (col2[2] > 0.5)
+ outcol[2] = col1[2] + t * (2.0 * (col2[2] - 0.5));
+ else
+ outcol[2] = col1[2] + t * (2.0 * (col2[2]) - 1.0);
+
+ return outcol;
}
color node_mix_clamp(color col)
{
- color outcol = col;
+ color outcol = col;
- outcol[0] = clamp(col[0], 0.0, 1.0);
- outcol[1] = clamp(col[1], 0.0, 1.0);
- outcol[2] = clamp(col[2], 0.0, 1.0);
+ outcol[0] = clamp(col[0], 0.0, 1.0);
+ outcol[1] = clamp(col[1], 0.0, 1.0);
+ outcol[2] = clamp(col[2], 0.0, 1.0);
- return outcol;
+ return outcol;
}
-shader node_mix(
- string type = "mix",
- int use_clamp = 0,
- float Fac = 0.5,
- color Color1 = 0.0,
- color Color2 = 0.0,
- output color Color = 0.0)
+shader node_mix(string type = "mix",
+ int use_clamp = 0,
+ float Fac = 0.5,
+ color Color1 = 0.0,
+ color Color2 = 0.0,
+ output color Color = 0.0)
{
- float t = clamp(Fac, 0.0, 1.0);
-
- if (type == "mix")
- Color = node_mix_blend(t, Color1, Color2);
- if (type == "add")
- Color = node_mix_add(t, Color1, Color2);
- if (type == "multiply")
- Color = node_mix_mul(t, Color1, Color2);
- if (type == "screen")
- Color = node_mix_screen(t, Color1, Color2);
- if (type == "overlay")
- Color = node_mix_overlay(t, Color1, Color2);
- if (type == "subtract")
- Color = node_mix_sub(t, Color1, Color2);
- if (type == "divide")
- Color = node_mix_div(t, Color1, Color2);
- if (type == "difference")
- Color = node_mix_diff(t, Color1, Color2);
- if (type == "darken")
- Color = node_mix_dark(t, Color1, Color2);
- if (type == "lighten")
- Color = node_mix_light(t, Color1, Color2);
- if (type == "dodge")
- Color = node_mix_dodge(t, Color1, Color2);
- if (type == "burn")
- Color = node_mix_burn(t, Color1, Color2);
- if (type == "hue")
- Color = node_mix_hue(t, Color1, Color2);
- if (type == "saturation")
- Color = node_mix_sat(t, Color1, Color2);
- if (type == "value")
- Color = node_mix_val (t, Color1, Color2);
- if (type == "color")
- Color = node_mix_color(t, Color1, Color2);
- if (type == "soft_light")
- Color = node_mix_soft(t, Color1, Color2);
- if (type == "linear_light")
- Color = node_mix_linear(t, Color1, Color2);
-
- if (use_clamp)
- Color = node_mix_clamp(Color);
+ float t = clamp(Fac, 0.0, 1.0);
+
+ if (type == "mix")
+ Color = node_mix_blend(t, Color1, Color2);
+ if (type == "add")
+ Color = node_mix_add(t, Color1, Color2);
+ if (type == "multiply")
+ Color = node_mix_mul(t, Color1, Color2);
+ if (type == "screen")
+ Color = node_mix_screen(t, Color1, Color2);
+ if (type == "overlay")
+ Color = node_mix_overlay(t, Color1, Color2);
+ if (type == "subtract")
+ Color = node_mix_sub(t, Color1, Color2);
+ if (type == "divide")
+ Color = node_mix_div(t, Color1, Color2);
+ if (type == "difference")
+ Color = node_mix_diff(t, Color1, Color2);
+ if (type == "darken")
+ Color = node_mix_dark(t, Color1, Color2);
+ if (type == "lighten")
+ Color = node_mix_light(t, Color1, Color2);
+ if (type == "dodge")
+ Color = node_mix_dodge(t, Color1, Color2);
+ if (type == "burn")
+ Color = node_mix_burn(t, Color1, Color2);
+ if (type == "hue")
+ Color = node_mix_hue(t, Color1, Color2);
+ if (type == "saturation")
+ Color = node_mix_sat(t, Color1, Color2);
+ if (type == "value")
+ Color = node_mix_val(t, Color1, Color2);
+ if (type == "color")
+ Color = node_mix_color(t, Color1, Color2);
+ if (type == "soft_light")
+ Color = node_mix_soft(t, Color1, Color2);
+ if (type == "linear_light")
+ Color = node_mix_linear(t, Color1, Color2);
+
+ if (use_clamp)
+ Color = node_mix_clamp(Color);
}
-
diff --git a/intern/cycles/kernel/shaders/node_mix_closure.osl b/intern/cycles/kernel/shaders/node_mix_closure.osl
index 5946dfdaaba..517c59c8786 100644
--- a/intern/cycles/kernel/shaders/node_mix_closure.osl
+++ b/intern/cycles/kernel/shaders/node_mix_closure.osl
@@ -16,13 +16,11 @@
#include "stdosl.h"
-shader node_mix_closure(
- float Fac = 0.5,
- closure color Closure1 = 0,
- closure color Closure2 = 0,
- output closure color Closure = 0)
+shader node_mix_closure(float Fac = 0.5,
+ closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
{
- float t = clamp(Fac, 0.0, 1.0);
- Closure = (1.0 - t) * Closure1 + t * Closure2;
+ float t = clamp(Fac, 0.0, 1.0);
+ Closure = (1.0 - t) * Closure1 + t * Closure2;
}
-
diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index 454b3834081..a7877c43d46 100644
--- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -28,24 +28,24 @@
float noise_musgrave_fBm(point ip, float H, float lacunarity, float octaves)
{
- float rmd;
- float value = 0.0;
- float pwr = 1.0;
- float pwHL = pow(lacunarity, -H);
- int i;
- point p = ip;
-
- for (i = 0; i < (int)octaves; i++) {
- value += safe_noise(p, "signed") * pwr;
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0)
- value += rmd * safe_noise(p, "signed") * pwr;
-
- return value;
+ float rmd;
+ float value = 0.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+ int i;
+ point p = ip;
+
+ for (i = 0; i < (int)octaves; i++) {
+ value += safe_noise(p, "signed") * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0)
+ value += rmd * safe_noise(p, "signed") * pwr;
+
+ return value;
}
/* Musgrave Multifractal
@@ -57,24 +57,24 @@ float noise_musgrave_fBm(point ip, float H, float lacunarity, float octaves)
float noise_musgrave_multi_fractal(point ip, float H, float lacunarity, float octaves)
{
- float rmd;
- float value = 1.0;
- float pwr = 1.0;
- float pwHL = pow(lacunarity, -H);
- int i;
- point p = ip;
-
- for (i = 0; i < (int)octaves; i++) {
- value *= (pwr * safe_noise(p, "signed") + 1.0);
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0)
- value *= (rmd * pwr * safe_noise(p, "signed") + 1.0); /* correct? */
-
- return value;
+ float rmd;
+ float value = 1.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+ int i;
+ point p = ip;
+
+ for (i = 0; i < (int)octaves; i++) {
+ value *= (pwr * safe_noise(p, "signed") + 1.0);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0)
+ value *= (rmd * pwr * safe_noise(p, "signed") + 1.0); /* correct? */
+
+ return value;
}
/* Musgrave Heterogeneous Terrain
@@ -85,32 +85,33 @@ float noise_musgrave_multi_fractal(point ip, float H, float lacunarity, float oc
* offset: raises the terrain from `sea level'
*/
-float noise_musgrave_hetero_terrain(point ip, float H, float lacunarity, float octaves, float offset)
+float noise_musgrave_hetero_terrain(
+ point ip, float H, float lacunarity, float octaves, float offset)
{
- float value, increment, rmd;
- float pwHL = pow(lacunarity, -H);
- float pwr = pwHL;
- int i;
- point p = ip;
-
- /* first unscaled octave of function; later octaves are scaled */
- value = offset + safe_noise(p, "signed");
- p *= lacunarity;
-
- for (i = 1; i < (int)octaves; i++) {
- increment = (safe_noise(p, "signed") + offset) * pwr * value;
- value += increment;
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0) {
- increment = (safe_noise(p, "signed") + offset) * pwr * value;
- value += rmd * increment;
- }
-
- return value;
+ float value, increment, rmd;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+ point p = ip;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ value = offset + safe_noise(p, "signed");
+ p *= lacunarity;
+
+ for (i = 1; i < (int)octaves; i++) {
+ increment = (safe_noise(p, "signed") + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ increment = (safe_noise(p, "signed") + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
}
/* Hybrid Additive/Multiplicative Multifractal Terrain
@@ -121,35 +122,35 @@ float noise_musgrave_hetero_terrain(point ip, float H, float lacunarity, float o
* offset: raises the terrain from `sea level'
*/
-float noise_musgrave_hybrid_multi_fractal(point ip, float H, float lacunarity,
- float octaves, float offset, float gain)
+float noise_musgrave_hybrid_multi_fractal(
+ point ip, float H, float lacunarity, float octaves, float offset, float gain)
{
- float result, signal, weight, rmd;
- float pwHL = pow(lacunarity, -H);
- float pwr = pwHL;
- int i;
- point p = ip;
-
- result = safe_noise(p, "signed") + offset;
- weight = gain * result;
- p *= lacunarity;
-
- for (i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
- if (weight > 1.0)
- weight = 1.0;
-
- signal = (safe_noise(p, "signed") + offset) * pwr;
- pwr *= pwHL;
- result += weight * signal;
- weight *= gain * signal;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0)
- result += rmd * ((safe_noise(p, "signed") + offset) * pwr);
-
- return result;
+ float result, signal, weight, rmd;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+ point p = ip;
+
+ result = safe_noise(p, "signed") + offset;
+ weight = gain * result;
+ p *= lacunarity;
+
+ for (i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
+ if (weight > 1.0)
+ weight = 1.0;
+
+ signal = (safe_noise(p, "signed") + offset) * pwr;
+ pwr *= pwHL;
+ result += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0)
+ result += rmd * ((safe_noise(p, "signed") + offset) * pwr);
+
+ return result;
}
/* Ridged Multifractal Terrain
@@ -160,72 +161,73 @@ float noise_musgrave_hybrid_multi_fractal(point ip, float H, float lacunarity,
* offset: raises the terrain from `sea level'
*/
-float noise_musgrave_ridged_multi_fractal(point ip, float H, float lacunarity,
- float octaves, float offset, float gain)
+float noise_musgrave_ridged_multi_fractal(
+ point ip, float H, float lacunarity, float octaves, float offset, float gain)
{
- float result, signal, weight;
- float pwHL = pow(lacunarity, -H);
- float pwr = pwHL;
- int i;
- point p = ip;
-
- signal = offset - fabs(safe_noise(p, "signed"));
- signal *= signal;
- result = signal;
- weight = 1.0;
-
- for (i = 1; i < (int)octaves; i++) {
- p *= lacunarity;
- weight = clamp(signal * gain, 0.0, 1.0);
- signal = offset - fabs(safe_noise(p, "signed"));
- signal *= signal;
- signal *= weight;
- result += signal * pwr;
- pwr *= pwHL;
- }
-
- return result;
+ float result, signal, weight;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+ point p = ip;
+
+ signal = offset - fabs(safe_noise(p, "signed"));
+ signal *= signal;
+ result = signal;
+ weight = 1.0;
+
+ for (i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = clamp(signal * gain, 0.0, 1.0);
+ signal = offset - fabs(safe_noise(p, "signed"));
+ signal *= signal;
+ signal *= weight;
+ result += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return result;
}
/* Shader */
shader node_musgrave_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- string type = "fBM",
- float Dimension = 2.0,
- float Lacunarity = 1.0,
- float Detail = 2.0,
- float Offset = 0.0,
- float Gain = 1.0,
- float Scale = 5.0,
- point Vector = P,
- output float Fac = 0.0,
- output color Color = 0.0)
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ string type = "fBM",
+ float Dimension = 2.0,
+ float Lacunarity = 1.0,
+ float Detail = 2.0,
+ float Offset = 0.0,
+ float Gain = 1.0,
+ float Scale = 5.0,
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
{
- float dimension = max(Dimension, 1e-5);
- float octaves = clamp(Detail, 0.0, 16.0);
- float lacunarity = max(Lacunarity, 1e-5);
- float intensity = 1.0;
-
- point p = Vector;
-
- if (use_mapping)
- p = transform(mapping, p);
-
- p = p * Scale;
-
- if (type == "multifractal")
- Fac = intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
- else if (type == "fBM")
- Fac = intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
- else if (type == "hybrid_multifractal")
- Fac = intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, Offset, Gain);
- else if (type == "ridged_multifractal")
- Fac = intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, Offset, Gain);
- else if (type == "hetero_terrain")
- Fac = intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, Offset);
-
- Color = color(Fac, Fac, Fac);
+ float dimension = max(Dimension, 1e-5);
+ float octaves = clamp(Detail, 0.0, 16.0);
+ float lacunarity = max(Lacunarity, 1e-5);
+ float intensity = 1.0;
+
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ p = p * Scale;
+
+ if (type == "multifractal")
+ Fac = intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
+ else if (type == "fBM")
+ Fac = intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
+ else if (type == "hybrid_multifractal")
+ Fac = intensity *
+ noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, Offset, Gain);
+ else if (type == "ridged_multifractal")
+ Fac = intensity *
+ noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, Offset, Gain);
+ else if (type == "hetero_terrain")
+ Fac = intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, Offset);
+
+ Color = color(Fac, Fac, Fac);
}
-
diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl
index 42a30897341..2cbd571e206 100644
--- a/intern/cycles/kernel/shaders/node_noise_texture.osl
+++ b/intern/cycles/kernel/shaders/node_noise_texture.osl
@@ -21,41 +21,40 @@
float noise(point ip, float distortion, float detail, output color Color)
{
- point r;
- point p = ip;
- int hard = 0;
-
- if (distortion != 0.0) {
- r[0] = safe_noise(p + point(13.5), "unsigned") * distortion;
- r[1] = safe_noise(p, "unsigned") * distortion;
- r[2] = safe_noise(p - point(13.5), "unsigned") * distortion;
-
- p += r;
- }
-
- float fac = noise_turbulence(p, detail, hard);
-
- Color = color(fac, noise_turbulence(point(p[1], p[0], p[2]), detail, hard),
- noise_turbulence(point(p[1], p[2], p[0]), detail, hard));
-
- return fac;
+ point r;
+ point p = ip;
+ int hard = 0;
+
+ if (distortion != 0.0) {
+ r[0] = safe_noise(p + point(13.5), "unsigned") * distortion;
+ r[1] = safe_noise(p, "unsigned") * distortion;
+ r[2] = safe_noise(p - point(13.5), "unsigned") * distortion;
+
+ p += r;
+ }
+
+ float fac = noise_turbulence(p, detail, hard);
+
+ Color = color(fac,
+ noise_turbulence(point(p[1], p[0], p[2]), detail, hard),
+ noise_turbulence(point(p[1], p[2], p[0]), detail, hard));
+
+ return fac;
}
-shader node_noise_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- float Distortion = 0.0,
- float Scale = 5.0,
- float Detail = 2.0,
- point Vector = P,
- output float Fac = 0.0,
- output color Color = 0.0)
+shader node_noise_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ float Distortion = 0.0,
+ float Scale = 5.0,
+ float Detail = 2.0,
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
{
- point p = Vector;
+ point p = Vector;
- if (use_mapping)
- p = transform(mapping, p);
+ if (use_mapping)
+ p = transform(mapping, p);
- Fac = noise(p * Scale, Distortion, Detail, Color);
+ Fac = noise(p * Scale, Distortion, Detail, Color);
}
-
diff --git a/intern/cycles/kernel/shaders/node_normal.osl b/intern/cycles/kernel/shaders/node_normal.osl
index 7307971eddd..1d20c3e7cac 100644
--- a/intern/cycles/kernel/shaders/node_normal.osl
+++ b/intern/cycles/kernel/shaders/node_normal.osl
@@ -16,13 +16,11 @@
#include "stdosl.h"
-shader node_normal(
- normal direction = normal(0.0, 0.0, 0.0),
- normal NormalIn = normal(0.0, 0.0, 0.0),
- output normal NormalOut = normal(0.0, 0.0, 0.0),
- output float Dot = 1.0)
+shader node_normal(normal direction = normal(0.0, 0.0, 0.0),
+ normal NormalIn = normal(0.0, 0.0, 0.0),
+ output normal NormalOut = normal(0.0, 0.0, 0.0),
+ output float Dot = 1.0)
{
- NormalOut = normalize(direction);
- Dot = dot(NormalOut, normalize(NormalIn));
+ NormalOut = normalize(direction);
+ Dot = dot(NormalOut, normalize(NormalIn));
}
-
diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl
index fda6f12a5da..90b593d00bc 100644
--- a/intern/cycles/kernel/shaders/node_normal_map.osl
+++ b/intern/cycles/kernel/shaders/node_normal_map.osl
@@ -16,79 +16,75 @@
#include "stdosl.h"
-shader node_normal_map(
- normal NormalIn = N,
- float Strength = 1.0,
- color Color = color(0.5, 0.5, 1.0),
- string space = "tangent",
- string attr_name = "geom:tangent",
- string attr_sign_name = "geom:tangent_sign",
- output normal Normal = NormalIn)
+shader node_normal_map(normal NormalIn = N,
+ float Strength = 1.0,
+ color Color = color(0.5, 0.5, 1.0),
+ string space = "tangent",
+ string attr_name = "geom:tangent",
+ string attr_sign_name = "geom:tangent_sign",
+ output normal Normal = NormalIn)
{
- color mcolor = 2.0 * color(Color[0] - 0.5, Color[1] - 0.5, Color[2] - 0.5);
- int is_backfacing = backfacing();
+ color mcolor = 2.0 * color(Color[0] - 0.5, Color[1] - 0.5, Color[2] - 0.5);
+ int is_backfacing = backfacing();
- if (space == "tangent") {
- vector tangent;
- vector ninterp;
- float tangent_sign;
- float is_smooth;
+ if (space == "tangent") {
+ vector tangent;
+ vector ninterp;
+ float tangent_sign;
+ float is_smooth;
- getattribute("geom:is_smooth", is_smooth);
- if (!is_smooth) {
- ninterp = normalize(transform("world", "object", Ng));
+ getattribute("geom:is_smooth", is_smooth);
+ if (!is_smooth) {
+ ninterp = normalize(transform("world", "object", Ng));
- /* the normal is already inverted, which is too soon for the math here */
- if (is_backfacing) {
- ninterp = -ninterp;
- }
- }
+ /* the normal is already inverted, which is too soon for the math here */
+ if (is_backfacing) {
+ ninterp = -ninterp;
+ }
+ }
- // get _unnormalized_ interpolated normal and tangent
- if (getattribute(attr_name, tangent) &&
- getattribute(attr_sign_name, tangent_sign) &&
- (!is_smooth || getattribute("geom:N", ninterp)))
- {
- // apply normal map
- vector B = tangent_sign * cross(ninterp, tangent);
- Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp);
+ // get _unnormalized_ interpolated normal and tangent
+ if (getattribute(attr_name, tangent) && getattribute(attr_sign_name, tangent_sign) &&
+ (!is_smooth || getattribute("geom:N", ninterp))) {
+ // apply normal map
+ vector B = tangent_sign * cross(ninterp, tangent);
+ Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp);
- // transform to world space
- Normal = normalize(transform("object", "world", Normal));
- }
- else {
- Normal = normal(0, 0, 0);
- }
- }
- else if (space == "object") {
- Normal = normalize(transform("object", "world", vector(mcolor)));
- }
- else if (space == "world") {
- Normal = normalize(vector(mcolor));
- }
- else if (space == "blender_object") {
- /* strange blender convention */
- mcolor[1] = -mcolor[1];
- mcolor[2] = -mcolor[2];
-
- Normal = normalize(transform("object", "world", vector(mcolor)));
- }
- else if (space == "blender_world") {
- /* strange blender convention */
- mcolor[1] = -mcolor[1];
- mcolor[2] = -mcolor[2];
-
- Normal = normalize(vector(mcolor));
- }
+ // transform to world space
+ Normal = normalize(transform("object", "world", Normal));
+ }
+ else {
+ Normal = normal(0, 0, 0);
+ }
+ }
+ else if (space == "object") {
+ Normal = normalize(transform("object", "world", vector(mcolor)));
+ }
+ else if (space == "world") {
+ Normal = normalize(vector(mcolor));
+ }
+ else if (space == "blender_object") {
+ /* strange blender convention */
+ mcolor[1] = -mcolor[1];
+ mcolor[2] = -mcolor[2];
- /* invert normal for backfacing polygons */
- if (is_backfacing) {
- Normal = -Normal;
- }
+ Normal = normalize(transform("object", "world", vector(mcolor)));
+ }
+ else if (space == "blender_world") {
+ /* strange blender convention */
+ mcolor[1] = -mcolor[1];
+ mcolor[2] = -mcolor[2];
- if (Strength != 1.0)
- Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0));
+ Normal = normalize(vector(mcolor));
+ }
- Normal = ensure_valid_reflection(Ng, I, Normal);
-}
+ /* invert normal for backfacing polygons */
+ if (is_backfacing) {
+ Normal = -Normal;
+ }
+
+ if (Strength != 1.0)
+ Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0));
+ Normal = ensure_valid_reflection(Ng, I, Normal);
+}
diff --git a/intern/cycles/kernel/shaders/node_object_info.osl b/intern/cycles/kernel/shaders/node_object_info.osl
index dd7c663b8d8..0904a30a53f 100644
--- a/intern/cycles/kernel/shaders/node_object_info.osl
+++ b/intern/cycles/kernel/shaders/node_object_info.osl
@@ -16,15 +16,13 @@
#include "stdosl.h"
-shader node_object_info(
- output point Location = point(0.0, 0.0, 0.0),
- output float ObjectIndex = 0.0,
- output float MaterialIndex = 0.0,
- output float Random = 0.0)
+shader node_object_info(output point Location = point(0.0, 0.0, 0.0),
+ output float ObjectIndex = 0.0,
+ output float MaterialIndex = 0.0,
+ output float Random = 0.0)
{
- getattribute("object:location", Location);
- getattribute("object:index", ObjectIndex);
- getattribute("material:index", MaterialIndex);
- getattribute("object:random", Random);
+ getattribute("object:location", Location);
+ getattribute("object:index", ObjectIndex);
+ getattribute("material:index", MaterialIndex);
+ getattribute("object:random", Random);
}
-
diff --git a/intern/cycles/kernel/shaders/node_output_displacement.osl b/intern/cycles/kernel/shaders/node_output_displacement.osl
index 5dbef0244fe..fa7f603980b 100644
--- a/intern/cycles/kernel/shaders/node_output_displacement.osl
+++ b/intern/cycles/kernel/shaders/node_output_displacement.osl
@@ -18,6 +18,5 @@
displacement node_output_displacement(vector Displacement = 0.0)
{
- P += Displacement;
+ P += Displacement;
}
-
diff --git a/intern/cycles/kernel/shaders/node_output_surface.osl b/intern/cycles/kernel/shaders/node_output_surface.osl
index 2cc4575a8c8..013666145da 100644
--- a/intern/cycles/kernel/shaders/node_output_surface.osl
+++ b/intern/cycles/kernel/shaders/node_output_surface.osl
@@ -18,6 +18,5 @@
surface node_output_surface(closure color Surface = 0)
{
- Ci = Surface;
+ Ci = Surface;
}
-
diff --git a/intern/cycles/kernel/shaders/node_output_volume.osl b/intern/cycles/kernel/shaders/node_output_volume.osl
index f220ba866e3..dd479e751b3 100644
--- a/intern/cycles/kernel/shaders/node_output_volume.osl
+++ b/intern/cycles/kernel/shaders/node_output_volume.osl
@@ -18,6 +18,5 @@
volume node_output_volume(closure color Volume = 0)
{
- Ci = Volume;
+ Ci = Volume;
}
-
diff --git a/intern/cycles/kernel/shaders/node_particle_info.osl b/intern/cycles/kernel/shaders/node_particle_info.osl
index 2a0252d5e45..e286c33a1ff 100644
--- a/intern/cycles/kernel/shaders/node_particle_info.osl
+++ b/intern/cycles/kernel/shaders/node_particle_info.osl
@@ -16,23 +16,21 @@
#include "stdosl.h"
-shader node_particle_info(
- output float Index = 0.0,
- output float Random = 0.0,
- output float Age = 0.0,
- output float Lifetime = 0.0,
- output point Location = point(0.0, 0.0, 0.0),
- output float Size = 0.0,
- output vector Velocity = point(0.0, 0.0, 0.0),
- output vector AngularVelocity = point(0.0, 0.0, 0.0))
+shader node_particle_info(output float Index = 0.0,
+ output float Random = 0.0,
+ output float Age = 0.0,
+ output float Lifetime = 0.0,
+ output point Location = point(0.0, 0.0, 0.0),
+ output float Size = 0.0,
+ output vector Velocity = point(0.0, 0.0, 0.0),
+ output vector AngularVelocity = point(0.0, 0.0, 0.0))
{
- getattribute("particle:index", Index);
- getattribute("particle:random", Random);
- getattribute("particle:age", Age);
- getattribute("particle:lifetime", Lifetime);
- getattribute("particle:location", Location);
- getattribute("particle:size", Size);
- getattribute("particle:velocity", Velocity);
- getattribute("particle:angular_velocity", AngularVelocity);
+ getattribute("particle:index", Index);
+ getattribute("particle:random", Random);
+ getattribute("particle:age", Age);
+ getattribute("particle:lifetime", Lifetime);
+ getattribute("particle:location", Location);
+ getattribute("particle:size", Size);
+ getattribute("particle:velocity", Velocity);
+ getattribute("particle:angular_velocity", AngularVelocity);
}
-
diff --git a/intern/cycles/kernel/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_bsdf.osl
index 6f54ba3a462..657ced9b6e6 100644
--- a/intern/cycles/kernel/shaders/node_principled_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_principled_bsdf.osl
@@ -17,111 +17,144 @@
#include "stdosl.h"
#include "node_fresnel.h"
-shader node_principled_bsdf(
- string distribution = "Multiscatter GGX",
- string subsurface_method = "burley",
- color BaseColor = color(0.8, 0.8, 0.8),
- float Subsurface = 0.0,
- vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
- color SubsurfaceColor = color(0.7, 0.1, 0.1),
- float Metallic = 0.0,
- float Specular = 0.5,
- float SpecularTint = 0.0,
- float Roughness = 0.5,
- float Anisotropic = 0.0,
- float AnisotropicRotation = 0.0,
- float Sheen = 0.0,
- float SheenTint = 0.5,
- float Clearcoat = 0.0,
- float ClearcoatRoughness = 0.03,
- float IOR = 1.45,
- float Transmission = 0.0,
- float TransmissionRoughness = 0.0,
- normal Normal = N,
- normal ClearcoatNormal = N,
- normal Tangent = normalize(dPdu),
- output closure color BSDF = 0)
+shader node_principled_bsdf(string distribution = "Multiscatter GGX",
+ string subsurface_method = "burley",
+ color BaseColor = color(0.8, 0.8, 0.8),
+ float Subsurface = 0.0,
+ vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
+ color SubsurfaceColor = color(0.7, 0.1, 0.1),
+ float Metallic = 0.0,
+ float Specular = 0.5,
+ float SpecularTint = 0.0,
+ float Roughness = 0.5,
+ float Anisotropic = 0.0,
+ float AnisotropicRotation = 0.0,
+ float Sheen = 0.0,
+ float SheenTint = 0.5,
+ float Clearcoat = 0.0,
+ float ClearcoatRoughness = 0.03,
+ float IOR = 1.45,
+ float Transmission = 0.0,
+ float TransmissionRoughness = 0.0,
+ normal Normal = N,
+ normal ClearcoatNormal = N,
+ normal Tangent = normalize(dPdu),
+ output closure color BSDF = 0)
{
- float f = max(IOR, 1e-5);
- float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0));
- float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
- float specular_weight = (1.0 - final_transmission);
-
- vector T = Tangent;
-
- float m_cdlum = luminance(BaseColor);
- color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum : color(0.0, 0.0, 0.0); // normalize lum. to isolate hue+sat
-
- /* rotate tangent */
- if (AnisotropicRotation != 0.0)
- T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
-
- if (diffuse_weight > 1e-5) {
- if (Subsurface > 1e-5) {
- color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
- if (subsurface_method == "burley") {
- BSDF = mixed_ss_base_color * bssrdf("principled", Normal, Subsurface * SubsurfaceRadius, SubsurfaceColor, "roughness", Roughness);
- }
- else {
- BSDF = mixed_ss_base_color * bssrdf("principled_random_walk", Normal, Subsurface * SubsurfaceRadius, mixed_ss_base_color, "roughness", Roughness);
- }
- }
- else {
- BSDF = BaseColor * principled_diffuse(Normal, Roughness);
- }
-
- if (Sheen > 1e-5) {
- color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
-
- BSDF = BSDF + sheen_color * Sheen * principled_sheen(Normal);
- }
-
- BSDF = BSDF * diffuse_weight;
- }
-
- if (specular_weight > 1e-5) {
- float aspect = sqrt(1.0 - Anisotropic * 0.9);
- float r2 = Roughness * Roughness;
-
- float alpha_x = r2 / aspect;
- float alpha_y = r2 * aspect;
-
- color tmp_col = color(1.0, 1.0, 1.0) * (1.0 - SpecularTint) + m_ctint * SpecularTint;
-
- color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
-
- if (distribution == "GGX" || Roughness <= 0.075) {
- BSDF = BSDF + specular_weight * microfacet_ggx_aniso_fresnel(Normal, T, alpha_x, alpha_y, (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, BaseColor, Cspec0);
- } else {
- BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(Normal, T, alpha_x, alpha_y, (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, BaseColor, Cspec0);
- }
- }
-
- if (final_transmission > 1e-5) {
- color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
- float eta = backfacing() ? 1.0 / f : f;
-
- if (distribution == "GGX" || Roughness <= 5e-2) {
- float cosNO = dot(Normal, I);
- float Fr = fresnel_dielectric_cos(cosNO, eta);
-
- float refl_roughness = Roughness;
- if (Roughness <= 1e-2)
- refl_roughness = 0.0;
-
- float transmission_roughness = refl_roughness;
- if (distribution == "GGX")
- transmission_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - TransmissionRoughness);
-
- BSDF = BSDF + final_transmission * (Fr * microfacet_ggx_fresnel(Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
- (1.0 - Fr) * BaseColor * microfacet_ggx_refraction(Normal, transmission_roughness * transmission_roughness, eta));
- } else {
- BSDF = BSDF + final_transmission * microfacet_multi_ggx_glass_fresnel(Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
- }
- }
-
- if (Clearcoat > 1e-5) {
- BSDF = BSDF + principled_clearcoat(ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness);
- }
+ float f = max(IOR, 1e-5);
+ float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0));
+ float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
+ float specular_weight = (1.0 - final_transmission);
+
+ vector T = Tangent;
+
+ float m_cdlum = luminance(BaseColor);
+ color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum :
+ color(0.0, 0.0, 0.0); // normalize lum. to isolate hue+sat
+
+ /* rotate tangent */
+ if (AnisotropicRotation != 0.0)
+ T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
+
+ if (diffuse_weight > 1e-5) {
+ if (Subsurface > 1e-5) {
+ color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
+ if (subsurface_method == "burley") {
+ BSDF = mixed_ss_base_color * bssrdf("principled",
+ Normal,
+ Subsurface * SubsurfaceRadius,
+ SubsurfaceColor,
+ "roughness",
+ Roughness);
+ }
+ else {
+ BSDF = mixed_ss_base_color * bssrdf("principled_random_walk",
+ Normal,
+ Subsurface * SubsurfaceRadius,
+ mixed_ss_base_color,
+ "roughness",
+ Roughness);
+ }
+ }
+ else {
+ BSDF = BaseColor * principled_diffuse(Normal, Roughness);
+ }
+
+ if (Sheen > 1e-5) {
+ color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
+
+ BSDF = BSDF + sheen_color * Sheen * principled_sheen(Normal);
+ }
+
+ BSDF = BSDF * diffuse_weight;
+ }
+
+ if (specular_weight > 1e-5) {
+ float aspect = sqrt(1.0 - Anisotropic * 0.9);
+ float r2 = Roughness * Roughness;
+
+ float alpha_x = r2 / aspect;
+ float alpha_y = r2 * aspect;
+
+ color tmp_col = color(1.0, 1.0, 1.0) * (1.0 - SpecularTint) + m_ctint * SpecularTint;
+
+ color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
+
+ if (distribution == "GGX" || Roughness <= 0.075) {
+ BSDF = BSDF + specular_weight *
+ microfacet_ggx_aniso_fresnel(Normal,
+ T,
+ alpha_x,
+ alpha_y,
+ (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
+ BaseColor,
+ Cspec0);
+ }
+ else {
+ BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(
+ Normal,
+ T,
+ alpha_x,
+ alpha_y,
+ (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
+ BaseColor,
+ Cspec0);
+ }
+ }
+
+ if (final_transmission > 1e-5) {
+ color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
+ float eta = backfacing() ? 1.0 / f : f;
+
+ if (distribution == "GGX" || Roughness <= 5e-2) {
+ float cosNO = dot(Normal, I);
+ float Fr = fresnel_dielectric_cos(cosNO, eta);
+
+ float refl_roughness = Roughness;
+ if (Roughness <= 1e-2)
+ refl_roughness = 0.0;
+
+ float transmission_roughness = refl_roughness;
+ if (distribution == "GGX")
+ transmission_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - TransmissionRoughness);
+
+ BSDF = BSDF +
+ final_transmission *
+ (Fr * microfacet_ggx_fresnel(
+ Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
+ (1.0 - Fr) * BaseColor *
+ microfacet_ggx_refraction(
+ Normal, transmission_roughness * transmission_roughness, eta));
+ }
+ else {
+ BSDF = BSDF +
+ final_transmission * microfacet_multi_ggx_glass_fresnel(
+ Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
+ }
+ }
+
+ if (Clearcoat > 1e-5) {
+ BSDF = BSDF + principled_clearcoat(
+ ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl
index 757a88f8ece..bf986438fca 100644
--- a/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl
@@ -18,88 +18,88 @@
color log3(color a)
{
- return color(log(a[0]), log(a[1]), log(a[2]));
+ return color(log(a[0]), log(a[1]), log(a[2]));
}
color sigma_from_concentration(float eumelanin, float pheomelanin)
{
- return eumelanin*color(0.506, 0.841, 1.653) + pheomelanin*color(0.343, 0.733, 1.924);
+ return eumelanin * color(0.506, 0.841, 1.653) + pheomelanin * color(0.343, 0.733, 1.924);
}
color sigma_from_reflectance(color c, float azimuthal_roughness)
{
- float x = azimuthal_roughness;
- float roughness_fac = (((((0.245*x) + 5.574)*x - 10.73)*x + 2.532)*x - 0.215)*x + 5.969;
- color sigma = log3(c) / roughness_fac;
- return sigma * sigma;
+ float x = azimuthal_roughness;
+ float roughness_fac = (((((0.245 * x) + 5.574) * x - 10.73) * x + 2.532) * x - 0.215) * x +
+ 5.969;
+ color sigma = log3(c) / roughness_fac;
+ return sigma * sigma;
}
-shader node_principled_hair_bsdf(
- color Color = color(0.017513, 0.005763, 0.002059),
- float Melanin = 0.8,
- float MelaninRedness = 1.0,
- float RandomColor = 0.0,
- color Tint = 1.0,
- color AbsorptionCoefficient = color(0.245531, 0.52, 1.365),
- normal Normal = Ng,
- string parametrization = "Absorption coefficient",
- float Offset = radians(2),
- float Roughness = 0.3,
- float RadialRoughness = 0.3,
- float RandomRoughness = 0.0,
- float Coat = 0.0,
- float IOR = 1.55,
- string AttrRandom = "geom:curve_random",
- float Random = 0.0,
+shader node_principled_hair_bsdf(color Color = color(0.017513, 0.005763, 0.002059),
+ float Melanin = 0.8,
+ float MelaninRedness = 1.0,
+ float RandomColor = 0.0,
+ color Tint = 1.0,
+ color AbsorptionCoefficient = color(0.245531, 0.52, 1.365),
+ normal Normal = Ng,
+ string parametrization = "Absorption coefficient",
+ float Offset = radians(2),
+ float Roughness = 0.3,
+ float RadialRoughness = 0.3,
+ float RandomRoughness = 0.0,
+ float Coat = 0.0,
+ float IOR = 1.55,
+ string AttrRandom = "geom:curve_random",
+ float Random = 0.0,
- output closure color BSDF = 0)
+ output closure color BSDF = 0)
{
- /* Get random value from curve in none is specified. */
- float random_value = 0.0;
+ /* Get random value from curve in none is specified. */
+ float random_value = 0.0;
- if (isconnected(Random)) {
- random_value = Random;
- }
- else {
- getattribute(AttrRandom, random_value);
- }
+ if (isconnected(Random)) {
+ random_value = Random;
+ }
+ else {
+ getattribute(AttrRandom, random_value);
+ }
- /* Compute roughness. */
- float factor_random_roughness = 1.0 + 2.0*(random_value - 0.5)*RandomRoughness;
- float m0_roughness = 1.0 - clamp(Coat, 0.0, 1.0);
- float roughness = Roughness*factor_random_roughness;
- float radial_roughness = RadialRoughness*factor_random_roughness;
+ /* Compute roughness. */
+ float factor_random_roughness = 1.0 + 2.0 * (random_value - 0.5) * RandomRoughness;
+ float m0_roughness = 1.0 - clamp(Coat, 0.0, 1.0);
+ float roughness = Roughness * factor_random_roughness;
+ float radial_roughness = RadialRoughness * factor_random_roughness;
- /* Compute absorption. */
- color sigma;
+ /* Compute absorption. */
+ color sigma;
- if (parametrization == "Absorption coefficient") {
- sigma = AbsorptionCoefficient;
- }
- else if (parametrization == "Melanin concentration") {
- /* Randomize melanin. */
- float factor_random_color = 1.0 + 2.0*(random_value - 0.5) * RandomColor;
- float melanin = Melanin * factor_random_color;
+ if (parametrization == "Absorption coefficient") {
+ sigma = AbsorptionCoefficient;
+ }
+ else if (parametrization == "Melanin concentration") {
+ /* Randomize melanin. */
+ float factor_random_color = 1.0 + 2.0 * (random_value - 0.5) * RandomColor;
+ float melanin = Melanin * factor_random_color;
- /* Map melanin 0..inf from more perceptually linear 0..1. */
- melanin = -log(max(1.0 - melanin, 0.0001));
+ /* Map melanin 0..inf from more perceptually linear 0..1. */
+ melanin = -log(max(1.0 - melanin, 0.0001));
- /* Benedikt Bitterli's melanin ratio remapping. */
- float eumelanin = melanin * (1.0 - MelaninRedness);
- float pheomelanin = melanin * MelaninRedness;
- color melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin);
+ /* Benedikt Bitterli's melanin ratio remapping. */
+ float eumelanin = melanin * (1.0 - MelaninRedness);
+ float pheomelanin = melanin * MelaninRedness;
+ color melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin);
- /* Optional tint. */
- color tint_sigma = sigma_from_reflectance(Tint, radial_roughness);
- sigma = melanin_sigma + tint_sigma;
- }
- else if (parametrization == "Direct coloring"){
- sigma = sigma_from_reflectance(Color, radial_roughness);
- }
- else {
- /* Fallback to brownish hair, same as defaults for melanin. */
- sigma = sigma_from_concentration(0.0, 0.8054375);
- }
+ /* Optional tint. */
+ color tint_sigma = sigma_from_reflectance(Tint, radial_roughness);
+ sigma = melanin_sigma + tint_sigma;
+ }
+ else if (parametrization == "Direct coloring") {
+ sigma = sigma_from_reflectance(Color, radial_roughness);
+ }
+ else {
+ /* Fallback to brownish hair, same as defaults for melanin. */
+ sigma = sigma_from_concentration(0.0, 0.8054375);
+ }
- BSDF = principled_hair(Normal, sigma, roughness, radial_roughness, m0_roughness, Offset, IOR);
+ BSDF = principled_hair(Normal, sigma, roughness, radial_roughness, m0_roughness, Offset, IOR);
}
diff --git a/intern/cycles/kernel/shaders/node_principled_volume.osl b/intern/cycles/kernel/shaders/node_principled_volume.osl
index ea8d6ab12c5..39cf6837eb2 100644
--- a/intern/cycles/kernel/shaders/node_principled_volume.osl
+++ b/intern/cycles/kernel/shaders/node_principled_volume.osl
@@ -16,80 +16,78 @@
#include "stdosl.h"
-shader node_principled_volume(
- color Color = color(0.5, 0.5, 0.5),
- float Density = 1.0,
- float Anisotropy = 0.0,
- color AbsorptionColor = color(0.0, 0.0, 0.0),
- float EmissionStrength = 0.0,
- color EmissionColor = color(1.0, 1.0, 1.0),
- float BlackbodyIntensity = 0.0,
- color BlackbodyTint = color(1.0, 1.0, 1.0),
- float Temperature = 1500.0,
- string DensityAttribute = "geom:density",
- string ColorAttribute = "geom:color",
- string TemperatureAttribute = "geom:temperature",
- output closure color Volume = 0)
+shader node_principled_volume(color Color = color(0.5, 0.5, 0.5),
+ float Density = 1.0,
+ float Anisotropy = 0.0,
+ color AbsorptionColor = color(0.0, 0.0, 0.0),
+ float EmissionStrength = 0.0,
+ color EmissionColor = color(1.0, 1.0, 1.0),
+ float BlackbodyIntensity = 0.0,
+ color BlackbodyTint = color(1.0, 1.0, 1.0),
+ float Temperature = 1500.0,
+ string DensityAttribute = "geom:density",
+ string ColorAttribute = "geom:color",
+ string TemperatureAttribute = "geom:temperature",
+ output closure color Volume = 0)
{
- /* Compute density. */
- float primitive_density = 1.0;
- float density = max(Density, 0.0);
+ /* Compute density. */
+ float primitive_density = 1.0;
+ float density = max(Density, 0.0);
- if(density > 1e-5) {
- if(getattribute(DensityAttribute, primitive_density)) {
- density = max(density * primitive_density, 0.0);
- }
- }
+ if (density > 1e-5) {
+ if (getattribute(DensityAttribute, primitive_density)) {
+ density = max(density * primitive_density, 0.0);
+ }
+ }
- if(density > 1e-5) {
- /* Compute scattering color. */
- color scatter_color = Color;
- color primitive_color;
- if(getattribute(ColorAttribute, primitive_color)) {
- scatter_color *= primitive_color;
- }
+ if (density > 1e-5) {
+ /* Compute scattering color. */
+ color scatter_color = Color;
+ color primitive_color;
+ if (getattribute(ColorAttribute, primitive_color)) {
+ scatter_color *= primitive_color;
+ }
- /* Add scattering and absorption closures. */
- color scatter_coeff = scatter_color;
- color absorption_color = sqrt(max(AbsorptionColor, 0.0));
- color absorption_coeff = max(1.0 - scatter_color, 0.0) * max(1.0 - absorption_color, 0.0);
- Volume = scatter_coeff * density * henyey_greenstein(Anisotropy) +
- absorption_coeff * density * absorption();
- }
+ /* Add scattering and absorption closures. */
+ color scatter_coeff = scatter_color;
+ color absorption_color = sqrt(max(AbsorptionColor, 0.0));
+ color absorption_coeff = max(1.0 - scatter_color, 0.0) * max(1.0 - absorption_color, 0.0);
+ Volume = scatter_coeff * density * henyey_greenstein(Anisotropy) +
+ absorption_coeff * density * absorption();
+ }
- /* Compute emission. */
- float emission_strength = max(EmissionStrength, 0.0);
- float blackbody_intensity = BlackbodyIntensity;
+ /* Compute emission. */
+ float emission_strength = max(EmissionStrength, 0.0);
+ float blackbody_intensity = BlackbodyIntensity;
- if(emission_strength > 1e-5) {
- Volume += emission_strength * EmissionColor * emission();
- }
+ if (emission_strength > 1e-5) {
+ Volume += emission_strength * EmissionColor * emission();
+ }
- if(blackbody_intensity > 1e-3) {
- float T = Temperature;
+ if (blackbody_intensity > 1e-3) {
+ float T = Temperature;
- /* Add temperature from attribute if available. */
- float temperature;
- if(getattribute(TemperatureAttribute, temperature)) {
- T *= max(temperature, 0.0);
- }
+ /* Add temperature from attribute if available. */
+ float temperature;
+ if (getattribute(TemperatureAttribute, temperature)) {
+ T *= max(temperature, 0.0);
+ }
- T = max(T, 0.0);
+ T = max(T, 0.0);
- /* Stefan-Boltzman law. */
- float T4 = (T * T) * (T * T);
- float sigma = 5.670373e-8 * 1e-6 / M_PI;
- float intensity = sigma * mix(1.0, T4, blackbody_intensity);
+ /* Stefan-Boltzman law. */
+ float T4 = (T * T) * (T * T);
+ float sigma = 5.670373e-8 * 1e-6 / M_PI;
+ float intensity = sigma * mix(1.0, T4, blackbody_intensity);
- if(intensity > 1e-5) {
- color bb = blackbody(T);
- float l = luminance(bb);
+ if (intensity > 1e-5) {
+ color bb = blackbody(T);
+ float l = luminance(bb);
- if(l != 0.0) {
- bb *= BlackbodyTint * intensity / l;
- Volume += bb * emission();
- }
- }
- }
+ if (l != 0.0) {
+ bb *= BlackbodyTint * intensity / l;
+ Volume += bb * emission();
+ }
+ }
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_ramp_util.h b/intern/cycles/kernel/shaders/node_ramp_util.h
index d07d5a98316..f7fb07b257d 100644
--- a/intern/cycles/kernel/shaders/node_ramp_util.h
+++ b/intern/cycles/kernel/shaders/node_ramp_util.h
@@ -18,72 +18,76 @@
color rgb_ramp_lookup(color ramp[], float at, int interpolate, int extrapolate)
{
- float f = at;
- int table_size = arraylength(ramp);
+ float f = at;
+ int table_size = arraylength(ramp);
- if ((f < 0.0 || f > 1.0) && extrapolate) {
- color t0, dy;
- if (f < 0.0) {
- t0 = ramp[0];
- dy = t0 - ramp[1];
- f = -f;
- }
- else {
- t0 = ramp[table_size - 1];
- dy = t0 - ramp[table_size - 2];
- f = f - 1.0;
- }
- return t0 + dy * f * (table_size - 1);
- }
+ if ((f < 0.0 || f > 1.0) && extrapolate) {
+ color t0, dy;
+ if (f < 0.0) {
+ t0 = ramp[0];
+ dy = t0 - ramp[1];
+ f = -f;
+ }
+ else {
+ t0 = ramp[table_size - 1];
+ dy = t0 - ramp[table_size - 2];
+ f = f - 1.0;
+ }
+ return t0 + dy * f * (table_size - 1);
+ }
- f = clamp(at, 0.0, 1.0) * (table_size - 1);
+ f = clamp(at, 0.0, 1.0) * (table_size - 1);
- /* clamp int as well in case of NaN */
- int i = (int)f;
- if (i < 0) i = 0;
- if (i >= table_size) i = table_size - 1;
- float t = f - (float)i;
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0)
+ i = 0;
+ if (i >= table_size)
+ i = table_size - 1;
+ float t = f - (float)i;
- color result = ramp[i];
+ color result = ramp[i];
- if (interpolate && t > 0.0)
- result = (1.0 - t) * result + t * ramp[i + 1];
+ if (interpolate && t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1];
- return result;
+ return result;
}
float rgb_ramp_lookup(float ramp[], float at, int interpolate, int extrapolate)
{
- float f = at;
- int table_size = arraylength(ramp);
+ float f = at;
+ int table_size = arraylength(ramp);
- if ((f < 0.0 || f > 1.0) && extrapolate) {
- float t0, dy;
- if (f < 0.0) {
- t0 = ramp[0];
- dy = t0 - ramp[1];
- f = -f;
- }
- else {
- t0 = ramp[table_size - 1];
- dy = t0 - ramp[table_size - 2];
- f = f - 1.0;
- }
- return t0 + dy * f * (table_size - 1);
- }
+ if ((f < 0.0 || f > 1.0) && extrapolate) {
+ float t0, dy;
+ if (f < 0.0) {
+ t0 = ramp[0];
+ dy = t0 - ramp[1];
+ f = -f;
+ }
+ else {
+ t0 = ramp[table_size - 1];
+ dy = t0 - ramp[table_size - 2];
+ f = f - 1.0;
+ }
+ return t0 + dy * f * (table_size - 1);
+ }
- f = clamp(at, 0.0, 1.0) * (table_size - 1);
+ f = clamp(at, 0.0, 1.0) * (table_size - 1);
- /* clamp int as well in case of NaN */
- int i = (int)f;
- if (i < 0) i = 0;
- if (i >= table_size) i = table_size - 1;
- float t = f - (float)i;
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0)
+ i = 0;
+ if (i >= table_size)
+ i = table_size - 1;
+ float t = f - (float)i;
- float result = ramp[i];
+ float result = ramp[i];
- if (interpolate && t > 0.0)
- result = (1.0 - t) * result + t * ramp[i + 1];
+ if (interpolate && t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1];
- return result;
+ return result;
}
diff --git a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
index eaab7282243..941d99dd44d 100644
--- a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
@@ -16,23 +16,21 @@
#include "stdosl.h"
-shader node_refraction_bsdf(
- color Color = 0.8,
- string distribution = "sharp",
- float Roughness = 0.2,
- float IOR = 1.45,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_refraction_bsdf(color Color = 0.8,
+ string distribution = "sharp",
+ float Roughness = 0.2,
+ float IOR = 1.45,
+ normal Normal = N,
+ output closure color BSDF = 0)
{
- float f = max(IOR, 1e-5);
- float eta = backfacing() ? 1.0 / f : f;
- float roughness = Roughness * Roughness;
+ float f = max(IOR, 1e-5);
+ float eta = backfacing() ? 1.0 / f : f;
+ float roughness = Roughness * Roughness;
- if (distribution == "sharp")
- BSDF = Color * refraction(Normal, eta);
- else if (distribution == "beckmann")
- BSDF = Color * microfacet_beckmann_refraction(Normal, roughness, eta);
- else if (distribution == "GGX")
- BSDF = Color * microfacet_ggx_refraction(Normal, roughness, eta);
+ if (distribution == "sharp")
+ BSDF = Color * refraction(Normal, eta);
+ else if (distribution == "beckmann")
+ BSDF = Color * microfacet_beckmann_refraction(Normal, roughness, eta);
+ else if (distribution == "GGX")
+ BSDF = Color * microfacet_ggx_refraction(Normal, roughness, eta);
}
-
diff --git a/intern/cycles/kernel/shaders/node_rgb_curves.osl b/intern/cycles/kernel/shaders/node_rgb_curves.osl
index 0d5eeea5c43..e34eb027cc3 100644
--- a/intern/cycles/kernel/shaders/node_rgb_curves.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_curves.osl
@@ -17,25 +17,23 @@
#include "stdosl.h"
#include "node_ramp_util.h"
-shader node_rgb_curves(
- color ramp[] = {0.0},
- float min_x = 0.0,
- float max_x = 1.0,
+shader node_rgb_curves(color ramp[] = {0.0},
+ float min_x = 0.0,
+ float max_x = 1.0,
- color ColorIn = 0.0,
- float Fac = 0.0,
- output color ColorOut = 0.0)
+ color ColorIn = 0.0,
+ float Fac = 0.0,
+ output color ColorOut = 0.0)
{
- color c = (ColorIn - color(min_x, min_x, min_x)) / (max_x - min_x);
+ color c = (ColorIn - color(min_x, min_x, min_x)) / (max_x - min_x);
- color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
- color g = rgb_ramp_lookup(ramp, c[1], 1, 1);
- color b = rgb_ramp_lookup(ramp, c[2], 1, 1);
+ color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
+ color g = rgb_ramp_lookup(ramp, c[1], 1, 1);
+ color b = rgb_ramp_lookup(ramp, c[2], 1, 1);
- ColorOut[0] = r[0];
- ColorOut[1] = g[1];
- ColorOut[2] = b[2];
+ ColorOut[0] = r[0];
+ ColorOut[1] = g[1];
+ ColorOut[2] = b[2];
- ColorOut = mix(ColorIn, ColorOut, Fac);
+ ColorOut = mix(ColorIn, ColorOut, Fac);
}
-
diff --git a/intern/cycles/kernel/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
index 4e7d8fdcf65..c9f9746a4fb 100644
--- a/intern/cycles/kernel/shaders/node_rgb_ramp.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
@@ -17,16 +17,14 @@
#include "stdosl.h"
#include "node_ramp_util.h"
-shader node_rgb_ramp(
- color ramp_color[] = {0.0},
- float ramp_alpha[] = {0.0},
- int interpolate = 1,
+shader node_rgb_ramp(color ramp_color[] = {0.0},
+ float ramp_alpha[] = {0.0},
+ int interpolate = 1,
- float Fac = 0.0,
- output color Color = 0.0,
- output float Alpha = 1.0)
+ float Fac = 0.0,
+ output color Color = 0.0,
+ output float Alpha = 1.0)
{
- Color = rgb_ramp_lookup(ramp_color, Fac, interpolate, 0);
- Alpha = rgb_ramp_lookup(ramp_alpha, Fac, interpolate, 0);
+ Color = rgb_ramp_lookup(ramp_color, Fac, interpolate, 0);
+ Alpha = rgb_ramp_lookup(ramp_alpha, Fac, interpolate, 0);
}
-
diff --git a/intern/cycles/kernel/shaders/node_rgb_to_bw.osl b/intern/cycles/kernel/shaders/node_rgb_to_bw.osl
index 903dfcdc881..837d6caf5fc 100644
--- a/intern/cycles/kernel/shaders/node_rgb_to_bw.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_to_bw.osl
@@ -16,10 +16,7 @@
#include "stdosl.h"
-shader node_rgb_to_bw(
- color Color = 0.0,
- output float Val = 0.0)
+shader node_rgb_to_bw(color Color = 0.0, output float Val = 0.0)
{
- Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722;
+ Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722;
}
-
diff --git a/intern/cycles/kernel/shaders/node_scatter_volume.osl b/intern/cycles/kernel/shaders/node_scatter_volume.osl
index 002e2750fca..fce5716f372 100644
--- a/intern/cycles/kernel/shaders/node_scatter_volume.osl
+++ b/intern/cycles/kernel/shaders/node_scatter_volume.osl
@@ -16,12 +16,10 @@
#include "stdosl.h"
-shader node_scatter_volume(
- color Color = color(0.8, 0.8, 0.8),
- float Density = 1.0,
- float Anisotropy = 0.0,
- output closure color Volume = 0)
+shader node_scatter_volume(color Color = color(0.8, 0.8, 0.8),
+ float Density = 1.0,
+ float Anisotropy = 0.0,
+ output closure color Volume = 0)
{
- Volume = (Color * max(Density, 0.0)) * henyey_greenstein(Anisotropy);
+ Volume = (Color * max(Density, 0.0)) * henyey_greenstein(Anisotropy);
}
-
diff --git a/intern/cycles/kernel/shaders/node_separate_hsv.osl b/intern/cycles/kernel/shaders/node_separate_hsv.osl
index 2a804040294..c77ed1f3755 100644
--- a/intern/cycles/kernel/shaders/node_separate_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_separate_hsv.osl
@@ -17,15 +17,14 @@
#include "stdosl.h"
#include "node_color.h"
-shader node_separate_hsv(
- color Color = 0.8,
- output float H = 0.0,
- output float S = 0.0,
- output float V = 0.0)
+shader node_separate_hsv(color Color = 0.8,
+ output float H = 0.0,
+ output float S = 0.0,
+ output float V = 0.0)
{
- color col = rgb_to_hsv(Color);
-
- H = col[0];
- S = col[1];
- V = col[2];
+ color col = rgb_to_hsv(Color);
+
+ H = col[0];
+ S = col[1];
+ V = col[2];
}
diff --git a/intern/cycles/kernel/shaders/node_separate_rgb.osl b/intern/cycles/kernel/shaders/node_separate_rgb.osl
index 43d9e3aa4b1..ee64add27e2 100644
--- a/intern/cycles/kernel/shaders/node_separate_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_separate_rgb.osl
@@ -16,13 +16,12 @@
#include "stdosl.h"
-shader node_separate_rgb(
- color Image = 0.8,
- output float R = 0.0,
- output float G = 0.0,
- output float B = 0.0)
+shader node_separate_rgb(color Image = 0.8,
+ output float R = 0.0,
+ output float G = 0.0,
+ output float B = 0.0)
{
- R = Image[0];
- G = Image[1];
- B = Image[2];
+ R = Image[0];
+ G = Image[1];
+ B = Image[2];
}
diff --git a/intern/cycles/kernel/shaders/node_separate_xyz.osl b/intern/cycles/kernel/shaders/node_separate_xyz.osl
index e1963a1902f..8a563f5e920 100644
--- a/intern/cycles/kernel/shaders/node_separate_xyz.osl
+++ b/intern/cycles/kernel/shaders/node_separate_xyz.osl
@@ -16,13 +16,12 @@
#include "stdosl.h"
-shader node_separate_xyz(
- vector Vector = 0.8,
- output float X = 0.0,
- output float Y = 0.0,
- output float Z = 0.0)
+shader node_separate_xyz(vector Vector = 0.8,
+ output float X = 0.0,
+ output float Y = 0.0,
+ output float Z = 0.0)
{
- X = Vector[0];
- Y = Vector[1];
- Z = Vector[2];
+ X = Vector[0];
+ Y = Vector[1];
+ Z = Vector[2];
}
diff --git a/intern/cycles/kernel/shaders/node_set_normal.osl b/intern/cycles/kernel/shaders/node_set_normal.osl
index 7ca7ac9350c..9541b829ef7 100644
--- a/intern/cycles/kernel/shaders/node_set_normal.osl
+++ b/intern/cycles/kernel/shaders/node_set_normal.osl
@@ -16,11 +16,8 @@
#include "stdosl.h"
-surface node_set_normal(
- normal Direction = N,
- output normal Normal = N)
+surface node_set_normal(normal Direction = N, output normal Normal = N)
{
- N = Direction;
- Normal = Direction;
+ N = Direction;
+ Normal = Direction;
}
-
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index a6c187d15f2..9b29e5489c2 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -19,115 +19,122 @@
float sky_angle_between(float thetav, float phiv, float theta, float phi)
{
- float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);
+ float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);
- if (cospsi > 1.0)
- return 0.0;
- if (cospsi < -1.0)
- return M_PI;
+ if (cospsi > 1.0)
+ return 0.0;
+ if (cospsi < -1.0)
+ return M_PI;
- return acos(cospsi);
+ return acos(cospsi);
}
vector sky_spherical_coordinates(vector dir)
{
- return vector(acos(dir[2]), atan2(dir[0], dir[1]), 0);
+ return vector(acos(dir[2]), atan2(dir[0], dir[1]), 0);
}
/* Preetham */
float sky_perez_function(float lam[9], float theta, float gamma)
{
- float ctheta = cos(theta);
- float cgamma = cos(gamma);
+ float ctheta = cos(theta);
+ float cgamma = cos(gamma);
- return (1.0 + lam[0] * exp(lam[1] / ctheta)) * (1.0 + lam[2] * exp(lam[3] * gamma) + lam[4] * cgamma * cgamma);
+ return (1.0 + lam[0] * exp(lam[1] / ctheta)) *
+ (1.0 + lam[2] * exp(lam[3] * gamma) + lam[4] * cgamma * cgamma);
}
color sky_radiance_old(normal dir,
- float sunphi, float suntheta, color radiance,
- float config_x[9], float config_y[9], float config_z[9])
+ float sunphi,
+ float suntheta,
+ color radiance,
+ float config_x[9],
+ float config_y[9],
+ float config_z[9])
{
- /* convert vector to spherical coordinates */
- vector spherical = sky_spherical_coordinates(dir);
- float theta = spherical[0];
- float phi = spherical[1];
+ /* convert vector to spherical coordinates */
+ vector spherical = sky_spherical_coordinates(dir);
+ float theta = spherical[0];
+ float phi = spherical[1];
- /* angle between sun direction and dir */
- float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
- /* clamp theta to horizon */
- theta = min(theta, M_PI_2 - 0.001);
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2 - 0.001);
- /* compute xyY color space values */
- float x = radiance[1] * sky_perez_function(config_y, theta, gamma);
- float y = radiance[2] * sky_perez_function(config_z, theta, gamma);
- float Y = radiance[0] * sky_perez_function(config_x, theta, gamma);
+ /* compute xyY color space values */
+ float x = radiance[1] * sky_perez_function(config_y, theta, gamma);
+ float y = radiance[2] * sky_perez_function(config_z, theta, gamma);
+ float Y = radiance[0] * sky_perez_function(config_x, theta, gamma);
- /* convert to RGB */
- color xyz = xyY_to_xyz(x, y, Y);
- return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
+ /* convert to RGB */
+ color xyz = xyY_to_xyz(x, y, Y);
+ return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
}
/* Hosek / Wilkie */
float sky_radiance_internal(float config[9], float theta, float gamma)
{
- float ctheta = cos(theta);
- float cgamma = cos(gamma);
-
- float expM = exp(config[4] * gamma);
- float rayM = cgamma * cgamma;
- float mieM = (1.0 + rayM) / pow((1.0 + config[8] * config[8] - 2.0 * config[8] * cgamma), 1.5);
- float zenith = sqrt(ctheta);
-
- return (1.0 + config[0] * exp(config[1] / (ctheta + 0.01))) *
- (config[2] + config[3] * expM + config[5] * rayM + config[6] * mieM + config[7] * zenith);
+ float ctheta = cos(theta);
+ float cgamma = cos(gamma);
+
+ float expM = exp(config[4] * gamma);
+ float rayM = cgamma * cgamma;
+ float mieM = (1.0 + rayM) / pow((1.0 + config[8] * config[8] - 2.0 * config[8] * cgamma), 1.5);
+ float zenith = sqrt(ctheta);
+
+ return (1.0 + config[0] * exp(config[1] / (ctheta + 0.01))) *
+ (config[2] + config[3] * expM + config[5] * rayM + config[6] * mieM + config[7] * zenith);
}
color sky_radiance_new(normal dir,
- float sunphi, float suntheta, color radiance,
- float config_x[9], float config_y[9], float config_z[9])
+ float sunphi,
+ float suntheta,
+ color radiance,
+ float config_x[9],
+ float config_y[9],
+ float config_z[9])
{
- /* convert vector to spherical coordinates */
- vector spherical = sky_spherical_coordinates(dir);
- float theta = spherical[0];
- float phi = spherical[1];
+ /* convert vector to spherical coordinates */
+ vector spherical = sky_spherical_coordinates(dir);
+ float theta = spherical[0];
+ float phi = spherical[1];
- /* angle between sun direction and dir */
- float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
- /* clamp theta to horizon */
- theta = min(theta, M_PI_2 - 0.001);
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2 - 0.001);
- /* compute xyz color space values */
- float x = sky_radiance_internal(config_x, theta, gamma) * radiance[0];
- float y = sky_radiance_internal(config_y, theta, gamma) * radiance[1];
- float z = sky_radiance_internal(config_z, theta, gamma) * radiance[2];
+ /* compute xyz color space values */
+ float x = sky_radiance_internal(config_x, theta, gamma) * radiance[0];
+ float y = sky_radiance_internal(config_y, theta, gamma) * radiance[1];
+ float z = sky_radiance_internal(config_z, theta, gamma) * radiance[2];
- /* convert to RGB and adjust strength */
- return xyz_to_rgb(x, y, z) * (M_2PI / 683);
+ /* convert to RGB and adjust strength */
+ return xyz_to_rgb(x, y, z) * (M_2PI / 683);
}
-shader node_sky_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- vector Vector = P,
- string type = "hosek_wilkie",
- float theta = 0.0,
- float phi = 0.0,
- color radiance = color(0.0, 0.0, 0.0),
- float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- output color Color = color(0.0, 0.0, 0.0))
+shader node_sky_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ vector Vector = P,
+ string type = "hosek_wilkie",
+ float theta = 0.0,
+ float phi = 0.0,
+ color radiance = color(0.0, 0.0, 0.0),
+ float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ output color Color = color(0.0, 0.0, 0.0))
{
- vector p = Vector;
-
- if (use_mapping)
- p = transform(mapping, p);
-
- if (type == "hosek_wilkie")
- Color = sky_radiance_new(p, phi, theta, radiance, config_x, config_y, config_z);
- else
- Color = sky_radiance_old(p, phi, theta, radiance, config_x, config_y, config_z);
-}
+ vector p = Vector;
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ if (type == "hosek_wilkie")
+ Color = sky_radiance_new(p, phi, theta, radiance, config_x, config_y, config_z);
+ else
+ Color = sky_radiance_old(p, phi, theta, radiance, config_x, config_y, config_z);
+}
diff --git a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
index 0df3256e1fd..e12199d8c3d 100644
--- a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
+++ b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
@@ -16,23 +16,30 @@
#include "stdosl.h"
-shader node_subsurface_scattering(
- color Color = 0.8,
- float Scale = 1.0,
- vector Radius = vector(0.1, 0.1, 0.1),
- float TextureBlur = 0.0,
- float Sharpness = 0.0,
- string falloff = "cubic",
- normal Normal = N,
- output closure color BSSRDF = 0)
+shader node_subsurface_scattering(color Color = 0.8,
+ float Scale = 1.0,
+ vector Radius = vector(0.1, 0.1, 0.1),
+ float TextureBlur = 0.0,
+ float Sharpness = 0.0,
+ string falloff = "cubic",
+ normal Normal = N,
+ output closure color BSSRDF = 0)
{
- if (falloff == "gaussian")
- BSSRDF = Color * bssrdf("gaussian", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
- else if (falloff == "cubic")
- BSSRDF = Color * bssrdf("cubic", Normal, Scale * Radius, Color, "texture_blur", TextureBlur, "sharpness", Sharpness);
- else if (falloff == "burley")
- BSSRDF = Color * bssrdf("burley", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
- else
- BSSRDF = Color * bssrdf("random_walk", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
+ if (falloff == "gaussian")
+ BSSRDF = Color *
+ bssrdf("gaussian", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
+ else if (falloff == "cubic")
+ BSSRDF = Color * bssrdf("cubic",
+ Normal,
+ Scale * Radius,
+ Color,
+ "texture_blur",
+ TextureBlur,
+ "sharpness",
+ Sharpness);
+ else if (falloff == "burley")
+ BSSRDF = Color * bssrdf("burley", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
+ else
+ BSSRDF = Color *
+ bssrdf("random_walk", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
}
-
diff --git a/intern/cycles/kernel/shaders/node_tangent.osl b/intern/cycles/kernel/shaders/node_tangent.osl
index c527070a2c8..44eb9973f3d 100644
--- a/intern/cycles/kernel/shaders/node_tangent.osl
+++ b/intern/cycles/kernel/shaders/node_tangent.osl
@@ -16,33 +16,31 @@
#include "stdosl.h"
-shader node_tangent(
- normal NormalIn = N,
- string attr_name = "geom:tangent",
- string direction_type = "radial",
- string axis = "z",
- output normal Tangent = normalize(dPdu))
+shader node_tangent(normal NormalIn = N,
+ string attr_name = "geom:tangent",
+ string direction_type = "radial",
+ string axis = "z",
+ output normal Tangent = normalize(dPdu))
{
- vector T;
+ vector T;
- if (direction_type == "uv_map") {
- getattribute(attr_name, T);
- }
- else if (direction_type == "radial") {
- point generated;
+ if (direction_type == "uv_map") {
+ getattribute(attr_name, T);
+ }
+ else if (direction_type == "radial") {
+ point generated;
- if (!getattribute("geom:generated", generated))
- generated = P;
+ if (!getattribute("geom:generated", generated))
+ generated = P;
- if (axis == "x")
- T = vector(0.0, -(generated[2] - 0.5), (generated[1] - 0.5));
- else if (axis == "y")
- T = vector(-(generated[2] - 0.5), 0.0, (generated[0] - 0.5));
- else
- T = vector(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
- }
+ if (axis == "x")
+ T = vector(0.0, -(generated[2] - 0.5), (generated[1] - 0.5));
+ else if (axis == "y")
+ T = vector(-(generated[2] - 0.5), 0.0, (generated[0] - 0.5));
+ else
+ T = vector(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
+ }
- T = transform("object", "world", T);
- Tangent = cross(NormalIn, normalize(cross(T, NormalIn)));
+ T = transform("object", "world", T);
+ Tangent = cross(NormalIn, normalize(cross(T, NormalIn)));
}
-
diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index 88305fb320f..e1f3b900ee5 100644
--- a/intern/cycles/kernel/shaders/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -18,148 +18,148 @@
color cellnoise_color(point p)
{
- float r = cellnoise(p);
- float g = cellnoise(point(p[1], p[0], p[2]));
- float b = cellnoise(point(p[1], p[2], p[0]));
+ float r = cellnoise(p);
+ float g = cellnoise(point(p[1], p[0], p[2]));
+ float b = cellnoise(point(p[1], p[2], p[0]));
- return color(r, g, b);
+ return color(r, g, b);
}
void voronoi(point p, float e, float da[4], point pa[4])
{
- /* returns distances in da and point coords in pa */
- int xx, yy, zz, xi, yi, zi;
-
- xi = (int)floor(p[0]);
- yi = (int)floor(p[1]);
- zi = (int)floor(p[2]);
-
- da[0] = 1e10;
- da[1] = 1e10;
- da[2] = 1e10;
- da[3] = 1e10;
-
- for (xx = xi - 1; xx <= xi + 1; xx++) {
- for (yy = yi - 1; yy <= yi + 1; yy++) {
- for (zz = zi - 1; zz <= zi + 1; zz++) {
- point ip = point(xx, yy, zz);
- point vp = (point)cellnoise_color(ip);
- point pd = p - (vp + ip);
- float d = dot(pd, pd);
-
- vp += point(xx, yy, zz);
-
- if (d < da[0]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = da[0];
- da[0] = d;
-
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = pa[0];
- pa[0] = vp;
- }
- else if (d < da[1]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = d;
-
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = vp;
- }
- else if (d < da[2]) {
- da[3] = da[2];
- da[2] = d;
-
- pa[3] = pa[2];
- pa[2] = vp;
- }
- else if (d < da[3]) {
- da[3] = d;
- pa[3] = vp;
- }
- }
- }
- }
+ /* returns distances in da and point coords in pa */
+ int xx, yy, zz, xi, yi, zi;
+
+ xi = (int)floor(p[0]);
+ yi = (int)floor(p[1]);
+ zi = (int)floor(p[2]);
+
+ da[0] = 1e10;
+ da[1] = 1e10;
+ da[2] = 1e10;
+ da[3] = 1e10;
+
+ for (xx = xi - 1; xx <= xi + 1; xx++) {
+ for (yy = yi - 1; yy <= yi + 1; yy++) {
+ for (zz = zi - 1; zz <= zi + 1; zz++) {
+ point ip = point(xx, yy, zz);
+ point vp = (point)cellnoise_color(ip);
+ point pd = p - (vp + ip);
+ float d = dot(pd, pd);
+
+ vp += point(xx, yy, zz);
+
+ if (d < da[0]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = da[0];
+ da[0] = d;
+
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = pa[0];
+ pa[0] = vp;
+ }
+ else if (d < da[1]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = d;
+
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = vp;
+ }
+ else if (d < da[2]) {
+ da[3] = da[2];
+ da[2] = d;
+
+ pa[3] = pa[2];
+ pa[2] = vp;
+ }
+ else if (d < da[3]) {
+ da[3] = d;
+ pa[3] = vp;
+ }
+ }
+ }
+ }
}
/* Noise Bases */
float safe_noise(point p, string type)
{
- float f = 0.0;
+ float f = 0.0;
- /* Perlin noise in range -1..1 */
- if (type == "signed")
- f = noise("perlin", p);
+ /* Perlin noise in range -1..1 */
+ if (type == "signed")
+ f = noise("perlin", p);
- /* Perlin noise in range 0..1 */
- else
- f = noise(p);
+ /* Perlin noise in range 0..1 */
+ else
+ f = noise(p);
- /* can happen for big coordinates, things even out to 0.5 then anyway */
- if (!isfinite(f))
- return 0.5;
+ /* can happen for big coordinates, things even out to 0.5 then anyway */
+ if (!isfinite(f))
+ return 0.5;
- return f;
+ return f;
}
/* Turbulence */
float noise_turbulence(point p, float details, int hard)
{
- float fscale = 1.0;
- float amp = 1.0;
- float sum = 0.0;
- int i, n;
+ float fscale = 1.0;
+ float amp = 1.0;
+ float sum = 0.0;
+ int i, n;
- float octaves = clamp(details, 0.0, 16.0);
- n = (int)octaves;
+ float octaves = clamp(details, 0.0, 16.0);
+ n = (int)octaves;
- for (i = 0; i <= n; i++) {
- float t = safe_noise(fscale * p, "unsigned");
+ for (i = 0; i <= n; i++) {
+ float t = safe_noise(fscale * p, "unsigned");
- if (hard)
- t = fabs(2.0 * t - 1.0);
+ if (hard)
+ t = fabs(2.0 * t - 1.0);
- sum += t * amp;
- amp *= 0.5;
- fscale *= 2.0;
- }
+ sum += t * amp;
+ amp *= 0.5;
+ fscale *= 2.0;
+ }
- float rmd = octaves - floor(octaves);
+ float rmd = octaves - floor(octaves);
- if (rmd != 0.0) {
- float t = safe_noise(fscale * p, "unsigned");
+ if (rmd != 0.0) {
+ float t = safe_noise(fscale * p, "unsigned");
- if (hard)
- t = fabs(2.0 * t - 1.0);
+ if (hard)
+ t = fabs(2.0 * t - 1.0);
- float sum2 = sum + t * amp;
+ float sum2 = sum + t * amp;
- sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
- sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+ sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
+ sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
- return (1.0 - rmd) * sum + rmd * sum2;
- }
- else {
- sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
- return sum;
- }
+ return (1.0 - rmd) * sum + rmd * sum2;
+ }
+ else {
+ sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
+ return sum;
+ }
}
/* Utility */
float nonzero(float f, float eps)
{
- float r;
+ float r;
- if (abs(f) < eps)
- r = sign(f) * eps;
- else
- r = f;
+ if (abs(f) < eps)
+ r = sign(f) * eps;
+ else
+ r = f;
- return r;
+ return r;
}
diff --git a/intern/cycles/kernel/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
index 9e2109fa082..13861653d04 100644
--- a/intern/cycles/kernel/shaders/node_texture_coordinate.osl
+++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
@@ -17,82 +17,81 @@
#include "stdosl.h"
shader node_texture_coordinate(
- normal NormalIn = N,
- int is_background = 0,
- int is_volume = 0,
- int from_dupli = 0,
- int use_transform = 0,
- string bump_offset = "center",
- matrix object_itfm = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ normal NormalIn = N,
+ int is_background = 0,
+ int is_volume = 0,
+ int from_dupli = 0,
+ int use_transform = 0,
+ string bump_offset = "center",
+ matrix object_itfm = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- output point Generated = point(0.0, 0.0, 0.0),
- output point UV = point(0.0, 0.0, 0.0),
- output point Object = point(0.0, 0.0, 0.0),
- output point Camera = point(0.0, 0.0, 0.0),
- output point Window = point(0.0, 0.0, 0.0),
- output normal Normal = normal(0.0, 0.0, 0.0),
- output point Reflection = point(0.0, 0.0, 0.0))
+ output point Generated = point(0.0, 0.0, 0.0),
+ output point UV = point(0.0, 0.0, 0.0),
+ output point Object = point(0.0, 0.0, 0.0),
+ output point Camera = point(0.0, 0.0, 0.0),
+ output point Window = point(0.0, 0.0, 0.0),
+ output normal Normal = normal(0.0, 0.0, 0.0),
+ output point Reflection = point(0.0, 0.0, 0.0))
{
- if (is_background) {
- Generated = P;
- UV = point(0.0, 0.0, 0.0);
- Object = P;
- point Pcam = transform("camera", "world", point(0, 0, 0));
- Camera = transform("camera", P + Pcam);
- getattribute("NDC", Window);
- Normal = NormalIn;
- Reflection = I;
- }
- else {
- if (from_dupli) {
- getattribute("geom:dupli_generated", Generated);
- getattribute("geom:dupli_uv", UV);
- }
- else if (is_volume) {
- Generated = transform("object", P);
+ if (is_background) {
+ Generated = P;
+ UV = point(0.0, 0.0, 0.0);
+ Object = P;
+ point Pcam = transform("camera", "world", point(0, 0, 0));
+ Camera = transform("camera", P + Pcam);
+ getattribute("NDC", Window);
+ Normal = NormalIn;
+ Reflection = I;
+ }
+ else {
+ if (from_dupli) {
+ getattribute("geom:dupli_generated", Generated);
+ getattribute("geom:dupli_uv", UV);
+ }
+ else if (is_volume) {
+ Generated = transform("object", P);
- matrix tfm;
- if (getattribute("geom:generated_transform", tfm))
- Generated = transform(tfm, Generated);
+ matrix tfm;
+ if (getattribute("geom:generated_transform", tfm))
+ Generated = transform(tfm, Generated);
- getattribute("geom:uv", UV);
- }
- else {
- getattribute("geom:generated", Generated);
- getattribute("geom:uv", UV);
- }
+ getattribute("geom:uv", UV);
+ }
+ else {
+ getattribute("geom:generated", Generated);
+ getattribute("geom:uv", UV);
+ }
- if (use_transform) {
- Object = transform(object_itfm, P);
- }
- else {
- Object = transform("object", P);
- }
- Camera = transform("camera", P);
- Window = transform("NDC", P);
- Normal = transform("world", "object", NormalIn);
- Reflection = -reflect(I, NormalIn);
- }
+ if (use_transform) {
+ Object = transform(object_itfm, P);
+ }
+ else {
+ Object = transform("object", P);
+ }
+ Camera = transform("camera", P);
+ Window = transform("NDC", P);
+ Normal = transform("world", "object", NormalIn);
+ Reflection = -reflect(I, NormalIn);
+ }
- if (bump_offset == "dx") {
- if (!from_dupli) {
- Generated += Dx(Generated);
- UV += Dx(UV);
- }
- Object += Dx(Object);
- Camera += Dx(Camera);
- Window += Dx(Window);
- }
- else if (bump_offset == "dy") {
- if (!from_dupli) {
- Generated += Dy(Generated);
- UV += Dy(UV);
- }
- Object += Dy(Object);
- Camera += Dy(Camera);
- Window += Dy(Window);
- }
+ if (bump_offset == "dx") {
+ if (!from_dupli) {
+ Generated += Dx(Generated);
+ UV += Dx(UV);
+ }
+ Object += Dx(Object);
+ Camera += Dx(Camera);
+ Window += Dx(Window);
+ }
+ else if (bump_offset == "dy") {
+ if (!from_dupli) {
+ Generated += Dy(Generated);
+ UV += Dy(UV);
+ }
+ Object += Dy(Object);
+ Camera += Dy(Camera);
+ Window += Dy(Window);
+ }
- Window[2] = 0.0;
+ Window[2] = 0.0;
}
-
diff --git a/intern/cycles/kernel/shaders/node_toon_bsdf.osl b/intern/cycles/kernel/shaders/node_toon_bsdf.osl
index ae68a463e46..ed3a0b25c60 100644
--- a/intern/cycles/kernel/shaders/node_toon_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_toon_bsdf.osl
@@ -16,17 +16,15 @@
#include "stdosl.h"
-shader node_toon_bsdf(
- color Color = 0.8,
- string component = "diffuse",
- float Size = 0.5,
- float Smooth = 0.0,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_toon_bsdf(color Color = 0.8,
+ string component = "diffuse",
+ float Size = 0.5,
+ float Smooth = 0.0,
+ normal Normal = N,
+ output closure color BSDF = 0)
{
- if (component == "diffuse")
- BSDF = Color * diffuse_toon(Normal, Size, Smooth);
- else if (component == "glossy")
- BSDF = Color * glossy_toon(Normal, Size, Smooth);
+ if (component == "diffuse")
+ BSDF = Color * diffuse_toon(Normal, Size, Smooth);
+ else if (component == "glossy")
+ BSDF = Color * glossy_toon(Normal, Size, Smooth);
}
-
diff --git a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
index 94d23d35326..7ce1ab08c59 100644
--- a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
@@ -16,11 +16,7 @@
#include "stdosl.h"
-shader node_translucent_bsdf(
- color Color = 0.8,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_translucent_bsdf(color Color = 0.8, normal Normal = N, output closure color BSDF = 0)
{
- BSDF = Color * translucent(Normal);
+ BSDF = Color * translucent(Normal);
}
-
diff --git a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
index 5d6798f19a6..a735513ba89 100644
--- a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
@@ -16,11 +16,7 @@
#include "stdosl.h"
-shader node_transparent_bsdf(
- color Color = 0.8,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_transparent_bsdf(color Color = 0.8, normal Normal = N, output closure color BSDF = 0)
{
- BSDF = Color * transparent();
+ BSDF = Color * transparent();
}
-
diff --git a/intern/cycles/kernel/shaders/node_uv_map.osl b/intern/cycles/kernel/shaders/node_uv_map.osl
index b46b2e73457..6f2887be63c 100644
--- a/intern/cycles/kernel/shaders/node_uv_map.osl
+++ b/intern/cycles/kernel/shaders/node_uv_map.osl
@@ -16,30 +16,29 @@
#include "stdosl.h"
-shader node_uv_map(
- int from_dupli = 0,
- string attribute = "",
- string bump_offset = "center",
- output point UV = point(0.0, 0.0, 0.0))
+shader node_uv_map(int from_dupli = 0,
+ string attribute = "",
+ string bump_offset = "center",
+ output point UV = point(0.0, 0.0, 0.0))
{
- if (from_dupli) {
- getattribute("geom:dupli_uv", UV);
- }
- else {
- if (attribute == "")
- getattribute("geom:uv", UV);
- else
- getattribute(attribute, UV);
- }
+ if (from_dupli) {
+ getattribute("geom:dupli_uv", UV);
+ }
+ else {
+ if (attribute == "")
+ getattribute("geom:uv", UV);
+ else
+ getattribute(attribute, UV);
+ }
- if (bump_offset == "dx") {
- if (!from_dupli) {
- UV += Dx(UV);
- }
- }
- else if (bump_offset == "dy") {
- if (!from_dupli) {
- UV += Dy(UV);
- }
- }
+ if (bump_offset == "dx") {
+ if (!from_dupli) {
+ UV += Dx(UV);
+ }
+ }
+ else if (bump_offset == "dy") {
+ if (!from_dupli) {
+ UV += Dy(UV);
+ }
+ }
}
diff --git a/intern/cycles/kernel/shaders/node_value.osl b/intern/cycles/kernel/shaders/node_value.osl
index f75388d1f76..398e2c0e392 100644
--- a/intern/cycles/kernel/shaders/node_value.osl
+++ b/intern/cycles/kernel/shaders/node_value.osl
@@ -16,16 +16,14 @@
#include "stdosl.h"
-shader node_value(
- float value_value = 0.0,
- vector vector_value = vector(0.0, 0.0, 0.0),
- color color_value = 0.0,
- output float Value = 0.0,
- output vector Vector = vector(0.0, 0.0, 0.0),
- output color Color = 0.0)
+shader node_value(float value_value = 0.0,
+ vector vector_value = vector(0.0, 0.0, 0.0),
+ color color_value = 0.0,
+ output float Value = 0.0,
+ output vector Vector = vector(0.0, 0.0, 0.0),
+ output color Color = 0.0)
{
- Value = value_value;
- Vector = vector_value;
- Color = color_value;
+ Value = value_value;
+ Vector = vector_value;
+ Color = color_value;
}
-
diff --git a/intern/cycles/kernel/shaders/node_vector_curves.osl b/intern/cycles/kernel/shaders/node_vector_curves.osl
index ff284c48e0a..e8c8036b550 100644
--- a/intern/cycles/kernel/shaders/node_vector_curves.osl
+++ b/intern/cycles/kernel/shaders/node_vector_curves.osl
@@ -17,25 +17,23 @@
#include "stdosl.h"
#include "node_ramp_util.h"
-shader node_vector_curves(
- color ramp[] = {0.0},
- float min_x = 0.0,
- float max_x = 1.0,
+shader node_vector_curves(color ramp[] = {0.0},
+ float min_x = 0.0,
+ float max_x = 1.0,
- vector VectorIn = vector(0.0, 0.0, 0.0),
- float Fac = 0.0,
- output vector VectorOut = vector(0.0, 0.0, 0.0))
+ vector VectorIn = vector(0.0, 0.0, 0.0),
+ float Fac = 0.0,
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
{
- vector c = (VectorIn - vector(min_x, min_x, min_x)) / (max_x - min_x);
+ vector c = (VectorIn - vector(min_x, min_x, min_x)) / (max_x - min_x);
- color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
- color g = rgb_ramp_lookup(ramp, c[0], 1, 1);
- color b = rgb_ramp_lookup(ramp, c[0], 1, 1);
+ color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
+ color g = rgb_ramp_lookup(ramp, c[0], 1, 1);
+ color b = rgb_ramp_lookup(ramp, c[0], 1, 1);
- VectorOut[0] = r[0];
- VectorOut[1] = g[1];
- VectorOut[2] = b[2];
+ VectorOut[0] = r[0];
+ VectorOut[1] = g[1];
+ VectorOut[2] = b[2];
- VectorOut = mix(VectorIn, VectorOut, Fac);
+ VectorOut = mix(VectorIn, VectorOut, Fac);
}
-
diff --git a/intern/cycles/kernel/shaders/node_vector_displacement.osl b/intern/cycles/kernel/shaders/node_vector_displacement.osl
index b19bc228e37..e9bd336347f 100644
--- a/intern/cycles/kernel/shaders/node_vector_displacement.osl
+++ b/intern/cycles/kernel/shaders/node_vector_displacement.osl
@@ -16,45 +16,43 @@
#include "stdosl.h"
-shader node_vector_displacement(
- color Vector = color(0.0, 0.0, 0.0),
- float Midlevel = 0.0,
- float Scale = 1.0,
- string space = "tangent",
- string attr_name = "geom:tangent",
- string attr_sign_name = "geom:tangent_sign",
- output vector Displacement = vector(0.0, 0.0, 0.0))
+shader node_vector_displacement(color Vector = color(0.0, 0.0, 0.0),
+ float Midlevel = 0.0,
+ float Scale = 1.0,
+ string space = "tangent",
+ string attr_name = "geom:tangent",
+ string attr_sign_name = "geom:tangent_sign",
+ output vector Displacement = vector(0.0, 0.0, 0.0))
{
- vector offset = (Vector - vector(Midlevel)) * Scale;
-
- if(space == "tangent") {
- /* Tangent space. */
- vector N_object = normalize(transform("world", "object", N));
-
- vector T_object;
- if(getattribute(attr_name, T_object)) {
- T_object = normalize(T_object);
- }
- else {
- T_object = normalize(dPdu);
- }
-
- vector B_object = normalize(cross(N_object, T_object));
- float tangent_sign;
- if(getattribute(attr_sign_name, tangent_sign)) {
- B_object *= tangent_sign;
- }
-
- Displacement = T_object*offset[0] + N_object*offset[1] + B_object*offset[2];
- }
- else {
- /* Object or world space. */
- Displacement = offset;
- }
-
- if(space != "world") {
- /* Tangent or object space. */
- Displacement = transform("object", "world", Displacement);
- }
+ vector offset = (Vector - vector(Midlevel)) * Scale;
+
+ if (space == "tangent") {
+ /* Tangent space. */
+ vector N_object = normalize(transform("world", "object", N));
+
+ vector T_object;
+ if (getattribute(attr_name, T_object)) {
+ T_object = normalize(T_object);
+ }
+ else {
+ T_object = normalize(dPdu);
+ }
+
+ vector B_object = normalize(cross(N_object, T_object));
+ float tangent_sign;
+ if (getattribute(attr_sign_name, tangent_sign)) {
+ B_object *= tangent_sign;
+ }
+
+ Displacement = T_object * offset[0] + N_object * offset[1] + B_object * offset[2];
+ }
+ else {
+ /* Object or world space. */
+ Displacement = offset;
+ }
+
+ if (space != "world") {
+ /* Tangent or object space. */
+ Displacement = transform("object", "world", Displacement);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_vector_math.osl b/intern/cycles/kernel/shaders/node_vector_math.osl
index a7e3637402e..10bb0c7283c 100644
--- a/intern/cycles/kernel/shaders/node_vector_math.osl
+++ b/intern/cycles/kernel/shaders/node_vector_math.osl
@@ -16,36 +16,34 @@
#include "stdosl.h"
-shader node_vector_math(
- string type = "add",
- vector Vector1 = vector(0.0, 0.0, 0.0),
- vector Vector2 = vector(0.0, 0.0, 0.0),
- output float Value = 0.0,
- output vector Vector = vector(0.0, 0.0, 0.0))
+shader node_vector_math(string type = "add",
+ vector Vector1 = vector(0.0, 0.0, 0.0),
+ vector Vector2 = vector(0.0, 0.0, 0.0),
+ output float Value = 0.0,
+ output vector Vector = vector(0.0, 0.0, 0.0))
{
- if (type == "add") {
- Vector = Vector1 + Vector2;
- Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
- }
- else if (type == "subtract") {
- Vector = Vector1 - Vector2;
- Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
- }
- else if (type == "average") {
- Value = length(Vector1 + Vector2);
- Vector = normalize(Vector1 + Vector2);
- }
- else if (type == "dot_product") {
- Value = dot(Vector1, Vector2);
- }
- else if (type == "cross_product") {
- vector c = cross(Vector1, Vector2);
- Value = length(c);
- Vector = normalize(c);
- }
- else if (type == "normalize") {
- Value = length(Vector1);
- Vector = normalize(Vector1);
- }
+ if (type == "add") {
+ Vector = Vector1 + Vector2;
+ Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
+ }
+ else if (type == "subtract") {
+ Vector = Vector1 - Vector2;
+ Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
+ }
+ else if (type == "average") {
+ Value = length(Vector1 + Vector2);
+ Vector = normalize(Vector1 + Vector2);
+ }
+ else if (type == "dot_product") {
+ Value = dot(Vector1, Vector2);
+ }
+ else if (type == "cross_product") {
+ vector c = cross(Vector1, Vector2);
+ Value = length(c);
+ Vector = normalize(c);
+ }
+ else if (type == "normalize") {
+ Value = length(Vector1);
+ Vector = normalize(Vector1);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_vector_transform.osl b/intern/cycles/kernel/shaders/node_vector_transform.osl
index afb95b340d1..22939577be0 100644
--- a/intern/cycles/kernel/shaders/node_vector_transform.osl
+++ b/intern/cycles/kernel/shaders/node_vector_transform.osl
@@ -16,21 +16,19 @@
#include "stdosl.h"
-shader node_vector_transform(
- string type = "vector",
- string convert_from = "world",
- string convert_to = "object",
- vector VectorIn = vector(0.0, 0.0, 0.0),
- output vector VectorOut = vector(0.0, 0.0, 0.0))
+shader node_vector_transform(string type = "vector",
+ string convert_from = "world",
+ string convert_to = "object",
+ vector VectorIn = vector(0.0, 0.0, 0.0),
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
{
- if (type == "vector" || type == "normal") {
- VectorOut = transform(convert_from, convert_to, VectorIn);
- if (type == "normal")
- VectorOut = normalize(VectorOut);
- }
- else if (type == "point") {
- point Point = (point)VectorIn;
- VectorOut = transform(convert_from, convert_to, Point);
- }
+ if (type == "vector" || type == "normal") {
+ VectorOut = transform(convert_from, convert_to, VectorIn);
+ if (type == "normal")
+ VectorOut = normalize(VectorOut);
+ }
+ else if (type == "point") {
+ point Point = (point)VectorIn;
+ VectorOut = transform(convert_from, convert_to, Point);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
index 456c26998c8..9290b845325 100644
--- a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
@@ -17,14 +17,12 @@
#include "stdosl.h"
#include "node_fresnel.h"
-shader node_velvet_bsdf(
- color Color = 0.8,
- float Sigma = 0.0,
- normal Normal = N,
- output closure color BSDF = 0)
+shader node_velvet_bsdf(color Color = 0.8,
+ float Sigma = 0.0,
+ normal Normal = N,
+ output closure color BSDF = 0)
{
- float sigma = clamp(Sigma, 0.0, 1.0);
+ float sigma = clamp(Sigma, 0.0, 1.0);
- BSDF = Color * ashikhmin_velvet(Normal, sigma);
+ BSDF = Color * ashikhmin_velvet(Normal, sigma);
}
-
diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
index 2e47d74a414..34c86d5b98d 100644
--- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl
+++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
@@ -19,147 +19,146 @@
void voronoi_m(point p, string metric, float e, float da[4], point pa[4])
{
- /* Compute the distance to and the position of the four closest neighbors to p.
- *
- * The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern).
- * The distances and points are returned in ascending order, i.e. da[0] and pa[0] will
- * contain the distance to the closest point and its coordinates respectively.
- */
- int xx, yy, zz, xi, yi, zi;
-
- xi = (int)floor(p[0]);
- yi = (int)floor(p[1]);
- zi = (int)floor(p[2]);
-
- da[0] = 1e10;
- da[1] = 1e10;
- da[2] = 1e10;
- da[3] = 1e10;
-
- for (xx = xi - 1; xx <= xi + 1; xx++) {
- for (yy = yi - 1; yy <= yi + 1; yy++) {
- for (zz = zi - 1; zz <= zi + 1; zz++) {
- point ip = point(xx, yy, zz);
- point vp = (point)cellnoise_color(ip);
- point pd = p - (vp + ip);
-
- float d = 0.0;
- if (metric == "distance") {
- d = dot(pd, pd);
- }
- else if (metric == "manhattan") {
- d = fabs(pd[0]) + fabs(pd[1]) + fabs(pd[2]);
- }
- else if (metric == "chebychev") {
- d = max(fabs(pd[0]), max(fabs(pd[1]), fabs(pd[2])));
- }
- else if (metric == "minkowski") {
- d = pow(pow(fabs(pd[0]), e) + pow(fabs(pd[1]), e) + pow(fabs(pd[2]), e), 1.0/e);
- }
-
- vp += point(xx, yy, zz);
-
- if (d < da[0]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = da[0];
- da[0] = d;
-
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = pa[0];
- pa[0] = vp;
- }
- else if (d < da[1]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = d;
-
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = vp;
- }
- else if (d < da[2]) {
- da[3] = da[2];
- da[2] = d;
-
- pa[3] = pa[2];
- pa[2] = vp;
- }
- else if (d < da[3]) {
- da[3] = d;
- pa[3] = vp;
- }
- }
- }
- }
+ /* Compute the distance to and the position of the four closest neighbors to p.
+ *
+ * The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern).
+ * The distances and points are returned in ascending order, i.e. da[0] and pa[0] will
+ * contain the distance to the closest point and its coordinates respectively.
+ */
+ int xx, yy, zz, xi, yi, zi;
+
+ xi = (int)floor(p[0]);
+ yi = (int)floor(p[1]);
+ zi = (int)floor(p[2]);
+
+ da[0] = 1e10;
+ da[1] = 1e10;
+ da[2] = 1e10;
+ da[3] = 1e10;
+
+ for (xx = xi - 1; xx <= xi + 1; xx++) {
+ for (yy = yi - 1; yy <= yi + 1; yy++) {
+ for (zz = zi - 1; zz <= zi + 1; zz++) {
+ point ip = point(xx, yy, zz);
+ point vp = (point)cellnoise_color(ip);
+ point pd = p - (vp + ip);
+
+ float d = 0.0;
+ if (metric == "distance") {
+ d = dot(pd, pd);
+ }
+ else if (metric == "manhattan") {
+ d = fabs(pd[0]) + fabs(pd[1]) + fabs(pd[2]);
+ }
+ else if (metric == "chebychev") {
+ d = max(fabs(pd[0]), max(fabs(pd[1]), fabs(pd[2])));
+ }
+ else if (metric == "minkowski") {
+ d = pow(pow(fabs(pd[0]), e) + pow(fabs(pd[1]), e) + pow(fabs(pd[2]), e), 1.0 / e);
+ }
+
+ vp += point(xx, yy, zz);
+
+ if (d < da[0]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = da[0];
+ da[0] = d;
+
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = pa[0];
+ pa[0] = vp;
+ }
+ else if (d < da[1]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = d;
+
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = vp;
+ }
+ else if (d < da[2]) {
+ da[3] = da[2];
+ da[2] = d;
+
+ pa[3] = pa[2];
+ pa[2] = vp;
+ }
+ else if (d < da[3]) {
+ da[3] = d;
+ pa[3] = vp;
+ }
+ }
+ }
+ }
}
/* Voronoi */
shader node_voronoi_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- string coloring = "intensity",
- string metric = "distance",
- string feature = "F1",
- float Exponent = 1.0,
- float Scale = 5.0,
- point Vector = P,
- output float Fac = 0.0,
- output color Color = 0.0)
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ string coloring = "intensity",
+ string metric = "distance",
+ string feature = "F1",
+ float Exponent = 1.0,
+ float Scale = 5.0,
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
{
- point p = Vector;
-
- if (use_mapping)
- p = transform(mapping, p);
-
- /* compute distance and point coordinate of 4 nearest neighbours */
- float da[4];
- point pa[4];
-
- /* compute distance and point coordinate of 4 nearest neighbours */
- voronoi_m(p * Scale, metric, Exponent, da, pa);
-
- if (coloring == "intensity") {
- /* Intensity output */
- if (feature == "F1") {
- Fac = fabs(da[0]);
- }
- else if (feature == "F2") {
- Fac = fabs(da[1]);
- }
- else if (feature == "F3") {
- Fac = fabs(da[2]);
- }
- else if (feature == "F4") {
- Fac = fabs(da[3]);
- }
- else if (feature == "F2F1") {
- Fac = fabs(da[1] - da[0]);
- }
- Color = color(Fac);
- }
- else {
- /* Color output */
- if (feature == "F1") {
- Color = pa[0];
- }
- else if (feature == "F2") {
- Color = pa[1];
- }
- else if (feature == "F3") {
- Color = pa[2];
- }
- else if (feature == "F4") {
- Color = pa[3];
- }
- else if (feature == "F2F1") {
- Color = fabs(pa[1] - pa[0]);
- }
-
- Color = cellnoise_color(Color);
- Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
- }
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ /* compute distance and point coordinate of 4 nearest neighbours */
+ float da[4];
+ point pa[4];
+
+ /* compute distance and point coordinate of 4 nearest neighbours */
+ voronoi_m(p * Scale, metric, Exponent, da, pa);
+
+ if (coloring == "intensity") {
+ /* Intensity output */
+ if (feature == "F1") {
+ Fac = fabs(da[0]);
+ }
+ else if (feature == "F2") {
+ Fac = fabs(da[1]);
+ }
+ else if (feature == "F3") {
+ Fac = fabs(da[2]);
+ }
+ else if (feature == "F4") {
+ Fac = fabs(da[3]);
+ }
+ else if (feature == "F2F1") {
+ Fac = fabs(da[1] - da[0]);
+ }
+ Color = color(Fac);
+ }
+ else {
+ /* Color output */
+ if (feature == "F1") {
+ Color = pa[0];
+ }
+ else if (feature == "F2") {
+ Color = pa[1];
+ }
+ else if (feature == "F3") {
+ Color = pa[2];
+ }
+ else if (feature == "F4") {
+ Color = pa[3];
+ }
+ else if (feature == "F2F1") {
+ Color = fabs(pa[1] - pa[0]);
+ }
+
+ Color = cellnoise_color(Color);
+ Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_voxel_texture.osl b/intern/cycles/kernel/shaders/node_voxel_texture.osl
index 9253febd64a..0e4484561d8 100644
--- a/intern/cycles/kernel/shaders/node_voxel_texture.osl
+++ b/intern/cycles/kernel/shaders/node_voxel_texture.osl
@@ -16,32 +16,30 @@
#include "stdosl.h"
-shader node_voxel_texture(
- string filename = "",
- string interpolation = "linear",
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- point Vector = P,
- output float Density = 0,
- output color Color = 0)
+shader node_voxel_texture(string filename = "",
+ string interpolation = "linear",
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ point Vector = P,
+ output float Density = 0,
+ output color Color = 0)
{
- point p = Vector;
- if (use_mapping) {
- p = transform(mapping, p);
- }
- else {
- p = transform("object", Vector);
- matrix tfm;
- if (getattribute("geom:generated_transform", tfm))
- p = transform(tfm, p);
- }
- if (p[0] < 0.0 || p[1] < 0.0 || p[2] < 0.0 ||
- p[0] > 1.0 || p[1] > 1.0 || p[2] > 1.0)
- {
- Density = 0;
- Color = color(0, 0, 0);
- }
- else {
- Color = (color)texture3d(filename, p, "wrap", "periodic", "interp", interpolation, "alpha", Density);
- }
+ point p = Vector;
+ if (use_mapping) {
+ p = transform(mapping, p);
+ }
+ else {
+ p = transform("object", Vector);
+ matrix tfm;
+ if (getattribute("geom:generated_transform", tfm))
+ p = transform(tfm, p);
+ }
+ if (p[0] < 0.0 || p[1] < 0.0 || p[2] < 0.0 || p[0] > 1.0 || p[1] > 1.0 || p[2] > 1.0) {
+ Density = 0;
+ Color = color(0, 0, 0);
+ }
+ else {
+ Color = (color)texture3d(
+ filename, p, "wrap", "periodic", "interp", interpolation, "alpha", Density);
+ }
}
diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl
index 71bc9324705..dfc2dbfb800 100644
--- a/intern/cycles/kernel/shaders/node_wave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_wave_texture.osl
@@ -21,49 +21,47 @@
float wave(point p, string type, string profile, float detail, float distortion, float dscale)
{
- float n = 0.0;
+ float n = 0.0;
- if (type == "bands") {
- n = (p[0] + p[1] + p[2]) * 10.0;
- }
- else if (type == "rings") {
- n = length(p) * 20.0;
- }
+ if (type == "bands") {
+ n = (p[0] + p[1] + p[2]) * 10.0;
+ }
+ else if (type == "rings") {
+ n = length(p) * 20.0;
+ }
- if (distortion != 0.0) {
- n = n + (distortion * noise_turbulence(p * dscale, detail, 0));
- }
+ if (distortion != 0.0) {
+ n = n + (distortion * noise_turbulence(p * dscale, detail, 0));
+ }
- if (profile == "sine") {
- return 0.5 + 0.5 * sin(n);
- }
- else {
- /* Saw profile */
- n /= M_2PI;
- n -= (int) n;
- return (n < 0.0) ? n + 1.0 : n;
- }
+ if (profile == "sine") {
+ return 0.5 + 0.5 * sin(n);
+ }
+ else {
+ /* Saw profile */
+ n /= M_2PI;
+ n -= (int)n;
+ return (n < 0.0) ? n + 1.0 : n;
+ }
}
-shader node_wave_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- string type = "bands",
- string profile = "sine",
- float Scale = 5.0,
- float Distortion = 0.0,
- float Detail = 2.0,
- float DetailScale = 1.0,
- point Vector = P,
- output float Fac = 0.0,
- output color Color = 0.0)
+shader node_wave_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ string type = "bands",
+ string profile = "sine",
+ float Scale = 5.0,
+ float Distortion = 0.0,
+ float Detail = 2.0,
+ float DetailScale = 1.0,
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
{
- point p = Vector;
+ point p = Vector;
- if (use_mapping)
- p = transform(mapping, p);
+ if (use_mapping)
+ p = transform(mapping, p);
- Fac = wave(p * Scale, type, profile, Detail, Distortion, DetailScale);
- Color = Fac;
+ Fac = wave(p * Scale, type, profile, Detail, Distortion, DetailScale);
+ Color = Fac;
}
-
diff --git a/intern/cycles/kernel/shaders/node_wavelength.osl b/intern/cycles/kernel/shaders/node_wavelength.osl
index 79e7043d4bf..c8c6eecb171 100644
--- a/intern/cycles/kernel/shaders/node_wavelength.osl
+++ b/intern/cycles/kernel/shaders/node_wavelength.osl
@@ -16,10 +16,7 @@
#include "stdosl.h"
-shader node_wavelength(
- float Wavelength = 500.0,
- output color Color = 0.0)
+shader node_wavelength(float Wavelength = 500.0, output color Color = 0.0)
{
- Color = wavelength_color(Wavelength);
+ Color = wavelength_color(Wavelength);
}
-
diff --git a/intern/cycles/kernel/shaders/node_wireframe.osl b/intern/cycles/kernel/shaders/node_wireframe.osl
index 5cc214495dd..ea4bd3a4c87 100644
--- a/intern/cycles/kernel/shaders/node_wireframe.osl
+++ b/intern/cycles/kernel/shaders/node_wireframe.osl
@@ -17,25 +17,24 @@
#include "stdosl.h"
#include "oslutil.h"
-shader node_wireframe(
- string bump_offset = "center",
- int use_pixel_size = 0,
- float Size = 0.01,
- output float Fac = 0.0)
+shader node_wireframe(string bump_offset = "center",
+ int use_pixel_size = 0,
+ float Size = 0.01,
+ output float Fac = 0.0)
{
- Fac = wireframe("triangles", Size, use_pixel_size);
- /* TODO(sergey): Since we can't use autodiff here we do algebraic
- * calculation of derivatives by definition. We could probably
- * optimize this a bit by doing some extra calculation in wireframe().
- */
- if (bump_offset == "dx") {
- point dx = Dx(P);
- P -= dx;
- Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dx);
- }
- else if (bump_offset == "dy") {
- point dy = Dy(P);
- P -= dy;
- Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dy);
- }
+ Fac = wireframe("triangles", Size, use_pixel_size);
+ /* TODO(sergey): Since we can't use autodiff here we do algebraic
+ * calculation of derivatives by definition. We could probably
+ * optimize this a bit by doing some extra calculation in wireframe().
+ */
+ if (bump_offset == "dx") {
+ point dx = Dx(P);
+ P -= dx;
+ Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dx);
+ }
+ else if (bump_offset == "dy") {
+ point dy = Dy(P);
+ P -= dy;
+ Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dy);
+ }
}
diff --git a/intern/cycles/kernel/shaders/oslutil.h b/intern/cycles/kernel/shaders/oslutil.h
index 592a8ad12d9..d48bfa4a665 100644
--- a/intern/cycles/kernel/shaders/oslutil.h
+++ b/intern/cycles/kernel/shaders/oslutil.h
@@ -39,57 +39,63 @@
//
float wireframe(string edge_type, float line_width, int raster)
{
- // ray differentials are so big in diffuse context that this function would always return "wire"
- if (raytype("path:diffuse")) return 0.0;
+ // ray differentials are so big in diffuse context that this function would always return "wire"
+ if (raytype("path:diffuse"))
+ return 0.0;
- int np = 0;
- point p[64];
- float pixelWidth = 1;
+ int np = 0;
+ point p[64];
+ float pixelWidth = 1;
- if (edge_type == "triangles")
- {
- np = 3;
- if (!getattribute("geom:trianglevertices", p))
- return 0.0;
- }
- else if (edge_type == "polygons" || edge_type == "patches")
- {
- getattribute("geom:numpolyvertices", np);
- if (np < 3 || !getattribute("geom:polyvertices", p))
- return 0.0;
- }
+ if (edge_type == "triangles") {
+ np = 3;
+ if (!getattribute("geom:trianglevertices", p))
+ return 0.0;
+ }
+ else if (edge_type == "polygons" || edge_type == "patches") {
+ getattribute("geom:numpolyvertices", np);
+ if (np < 3 || !getattribute("geom:polyvertices", p))
+ return 0.0;
+ }
- if (raster)
- {
- // Project the derivatives of P to the viewing plane defined
- // by I so we have a measure of how big is a pixel at this point
- float pixelWidthX = length(Dx(P) - dot(Dx(P), I) * I);
- float pixelWidthY = length(Dy(P) - dot(Dy(P), I) * I);
- // Take the average of both axis' length
- pixelWidth = (pixelWidthX + pixelWidthY) / 2;
- }
+ if (raster) {
+ // Project the derivatives of P to the viewing plane defined
+ // by I so we have a measure of how big is a pixel at this point
+ float pixelWidthX = length(Dx(P) - dot(Dx(P), I) * I);
+ float pixelWidthY = length(Dy(P) - dot(Dy(P), I) * I);
+ // Take the average of both axis' length
+ pixelWidth = (pixelWidthX + pixelWidthY) / 2;
+ }
- // Use half the width as the neighbor face will render the
- // other half. And take the square for fast comparison
- pixelWidth *= 0.5 * line_width;
- pixelWidth *= pixelWidth;
- for (int i = 0; i < np; i++)
- {
- int i2 = i ? i - 1 : np - 1;
- vector dir = P - p[i];
- vector edge = p[i] - p[i2];
- vector crs = cross(edge, dir);
- // At this point dot(crs, crs) / dot(edge, edge) is
- // the square of area / length(edge) == square of the
- // distance to the edge.
- if (dot(crs, crs) < (dot(edge, edge) * pixelWidth))
- return 1;
- }
- return 0;
+ // Use half the width as the neighbor face will render the
+ // other half. And take the square for fast comparison
+ pixelWidth *= 0.5 * line_width;
+ pixelWidth *= pixelWidth;
+ for (int i = 0; i < np; i++) {
+ int i2 = i ? i - 1 : np - 1;
+ vector dir = P - p[i];
+ vector edge = p[i] - p[i2];
+ vector crs = cross(edge, dir);
+ // At this point dot(crs, crs) / dot(edge, edge) is
+ // the square of area / length(edge) == square of the
+ // distance to the edge.
+ if (dot(crs, crs) < (dot(edge, edge) * pixelWidth))
+ return 1;
+ }
+ return 0;
}
-float wireframe(string edge_type, float line_width) { return wireframe(edge_type, line_width, 1); }
-float wireframe(string edge_type) { return wireframe(edge_type, 1.0, 1); }
-float wireframe() { return wireframe("polygons", 1.0, 1); }
+float wireframe(string edge_type, float line_width)
+{
+ return wireframe(edge_type, line_width, 1);
+}
+float wireframe(string edge_type)
+{
+ return wireframe(edge_type, 1.0, 1);
+}
+float wireframe()
+{
+ return wireframe("polygons", 1.0, 1);
+}
-#endif /* CCL_OSLUTIL_H */
+#endif /* CCL_OSLUTIL_H */
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 7136c746321..9b9720ffff9 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -25,124 +25,215 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/////////////////////////////////////////////////////////////////////////////
-
#ifndef CCL_STDOSL_H
#define CCL_STDOSL_H
-
#ifndef M_PI
-#define M_PI 3.1415926535897932 /* pi */
-#define M_PI_2 1.5707963267948966 /* pi/2 */
-#define M_PI_4 0.7853981633974483 /* pi/4 */
-#define M_2_PI 0.6366197723675813 /* 2/pi */
-#define M_2PI 6.2831853071795865 /* 2*pi */
-#define M_4PI 12.566370614359173 /* 4*pi */
-#define M_2_SQRTPI 1.1283791670955126 /* 2/sqrt(pi) */
-#define M_E 2.7182818284590452 /* e (Euler's number) */
-#define M_LN2 0.6931471805599453 /* ln(2) */
-#define M_LN10 2.3025850929940457 /* ln(10) */
-#define M_LOG2E 1.4426950408889634 /* log_2(e) */
-#define M_LOG10E 0.4342944819032518 /* log_10(e) */
-#define M_SQRT2 1.4142135623730950 /* sqrt(2) */
-#define M_SQRT1_2 0.7071067811865475 /* 1/sqrt(2) */
+# define M_PI 3.1415926535897932 /* pi */
+# define M_PI_2 1.5707963267948966 /* pi/2 */
+# define M_PI_4 0.7853981633974483 /* pi/4 */
+# define M_2_PI 0.6366197723675813 /* 2/pi */
+# define M_2PI 6.2831853071795865 /* 2*pi */
+# define M_4PI 12.566370614359173 /* 4*pi */
+# define M_2_SQRTPI 1.1283791670955126 /* 2/sqrt(pi) */
+# define M_E 2.7182818284590452 /* e (Euler's number) */
+# define M_LN2 0.6931471805599453 /* ln(2) */
+# define M_LN10 2.3025850929940457 /* ln(10) */
+# define M_LOG2E 1.4426950408889634 /* log_2(e) */
+# define M_LOG10E 0.4342944819032518 /* log_10(e) */
+# define M_SQRT2 1.4142135623730950 /* sqrt(2) */
+# define M_SQRT1_2 0.7071067811865475 /* 1/sqrt(2) */
#endif
-
-
// Declaration of built-in functions and closures
-#define BUILTIN [[ int builtin = 1 ]]
+#define BUILTIN [[int builtin = 1]]
#define BUILTIN_DERIV [[ int builtin = 1, int deriv = 1 ]]
-#define PERCOMP1(name) \
- normal name (normal x) BUILTIN; \
- vector name (vector x) BUILTIN; \
- point name (point x) BUILTIN; \
- color name (color x) BUILTIN; \
- float name (float x) BUILTIN;
-
-#define PERCOMP2(name) \
- normal name (normal x, normal y) BUILTIN; \
- vector name (vector x, vector y) BUILTIN; \
- point name (point x, point y) BUILTIN; \
- color name (color x, color y) BUILTIN; \
- float name (float x, float y) BUILTIN;
-
-#define PERCOMP2F(name) \
- normal name (normal x, float y) BUILTIN; \
- vector name (vector x, float y) BUILTIN; \
- point name (point x, float y) BUILTIN; \
- color name (color x, float y) BUILTIN; \
- float name (float x, float y) BUILTIN;
-
+#define PERCOMP1(name) \
+ normal name(normal x) BUILTIN; \
+ vector name(vector x) BUILTIN; \
+ point name(point x) BUILTIN; \
+ color name(color x) BUILTIN; \
+ float name(float x) BUILTIN;
+
+#define PERCOMP2(name) \
+ normal name(normal x, normal y) BUILTIN; \
+ vector name(vector x, vector y) BUILTIN; \
+ point name(point x, point y) BUILTIN; \
+ color name(color x, color y) BUILTIN; \
+ float name(float x, float y) BUILTIN;
+
+#define PERCOMP2F(name) \
+ normal name(normal x, float y) BUILTIN; \
+ vector name(vector x, float y) BUILTIN; \
+ point name(point x, float y) BUILTIN; \
+ color name(color x, float y) BUILTIN; \
+ float name(float x, float y) BUILTIN;
// Basic math
-normal degrees (normal x) { return x*(180.0/M_PI); }
-vector degrees (vector x) { return x*(180.0/M_PI); }
-point degrees (point x) { return x*(180.0/M_PI); }
-color degrees (color x) { return x*(180.0/M_PI); }
-float degrees (float x) { return x*(180.0/M_PI); }
-normal radians (normal x) { return x*(M_PI/180.0); }
-vector radians (vector x) { return x*(M_PI/180.0); }
-point radians (point x) { return x*(M_PI/180.0); }
-color radians (color x) { return x*(M_PI/180.0); }
-float radians (float x) { return x*(M_PI/180.0); }
-PERCOMP1 (cos)
-PERCOMP1 (sin)
-PERCOMP1 (tan)
-PERCOMP1 (acos)
-PERCOMP1 (asin)
-PERCOMP1 (atan)
-PERCOMP2 (atan2)
-PERCOMP1 (cosh)
-PERCOMP1 (sinh)
-PERCOMP1 (tanh)
-PERCOMP2F (pow)
-PERCOMP1 (exp)
-PERCOMP1 (exp2)
-PERCOMP1 (expm1)
-PERCOMP1 (log)
-point log (point a, float b) { return log(a)/log(b); }
-vector log (vector a, float b) { return log(a)/log(b); }
-color log (color a, float b) { return log(a)/log(b); }
-float log (float a, float b) { return log(a)/log(b); }
-PERCOMP1 (log2)
-PERCOMP1 (log10)
-PERCOMP1 (logb)
-PERCOMP1 (sqrt)
-PERCOMP1 (inversesqrt)
-float hypot (float a, float b) { return sqrt (a*a + b*b); }
-float hypot (float a, float b, float c) { return sqrt (a*a + b*b + c*c); }
-PERCOMP1 (abs)
-int abs (int x) BUILTIN;
-PERCOMP1 (fabs)
-int fabs (int x) BUILTIN;
-PERCOMP1 (sign)
-PERCOMP1 (floor)
-PERCOMP1 (ceil)
-PERCOMP1 (round)
-PERCOMP1 (trunc)
-PERCOMP2 (fmod)
-PERCOMP2F (fmod)
-int mod (int a, int b) { return a - b*(int)floor(a/b); }
-point mod (point a, point b) { return a - b*floor(a/b); }
-vector mod (vector a, vector b) { return a - b*floor(a/b); }
-normal mod (normal a, normal b) { return a - b*floor(a/b); }
-color mod (color a, color b) { return a - b*floor(a/b); }
-point mod (point a, float b) { return a - b*floor(a/b); }
-vector mod (vector a, float b) { return a - b*floor(a/b); }
-normal mod (normal a, float b) { return a - b*floor(a/b); }
-color mod (color a, float b) { return a - b*floor(a/b); }
-float mod (float a, float b) { return a - b*floor(a/b); }
-PERCOMP2 (min)
-int min (int a, int b) BUILTIN;
-PERCOMP2 (max)
-int max (int a, int b) BUILTIN;
-normal clamp (normal x, normal minval, normal maxval) { return max(min(x,maxval),minval); }
-vector clamp (vector x, vector minval, vector maxval) { return max(min(x,maxval),minval); }
-point clamp (point x, point minval, point maxval) { return max(min(x,maxval),minval); }
-color clamp (color x, color minval, color maxval) { return max(min(x,maxval),minval); }
-float clamp (float x, float minval, float maxval) { return max(min(x,maxval),minval); }
-int clamp (int x, int minval, int maxval) { return max(min(x,maxval),minval); }
+normal degrees(normal x)
+{
+ return x * (180.0 / M_PI);
+}
+vector degrees(vector x)
+{
+ return x * (180.0 / M_PI);
+}
+point degrees(point x)
+{
+ return x * (180.0 / M_PI);
+}
+color degrees(color x)
+{
+ return x * (180.0 / M_PI);
+}
+float degrees(float x)
+{
+ return x * (180.0 / M_PI);
+}
+normal radians(normal x)
+{
+ return x * (M_PI / 180.0);
+}
+vector radians(vector x)
+{
+ return x * (M_PI / 180.0);
+}
+point radians(point x)
+{
+ return x * (M_PI / 180.0);
+}
+color radians(color x)
+{
+ return x * (M_PI / 180.0);
+}
+float radians(float x)
+{
+ return x * (M_PI / 180.0);
+}
+PERCOMP1(cos)
+PERCOMP1(sin)
+PERCOMP1(tan)
+PERCOMP1(acos)
+PERCOMP1(asin)
+PERCOMP1(atan)
+PERCOMP2(atan2)
+PERCOMP1(cosh)
+PERCOMP1(sinh)
+PERCOMP1(tanh)
+PERCOMP2F(pow)
+PERCOMP1(exp)
+PERCOMP1(exp2)
+PERCOMP1(expm1)
+PERCOMP1(log)
+point log(point a, float b)
+{
+ return log(a) / log(b);
+}
+vector log(vector a, float b)
+{
+ return log(a) / log(b);
+}
+color log(color a, float b)
+{
+ return log(a) / log(b);
+}
+float log(float a, float b)
+{
+ return log(a) / log(b);
+}
+PERCOMP1(log2)
+PERCOMP1(log10)
+PERCOMP1(logb)
+PERCOMP1(sqrt)
+PERCOMP1(inversesqrt)
+float hypot(float a, float b)
+{
+ return sqrt(a * a + b * b);
+}
+float hypot(float a, float b, float c)
+{
+ return sqrt(a * a + b * b + c * c);
+}
+PERCOMP1(abs)
+int abs(int x) BUILTIN;
+PERCOMP1(fabs)
+int fabs(int x) BUILTIN;
+PERCOMP1(sign)
+PERCOMP1(floor)
+PERCOMP1(ceil)
+PERCOMP1(round)
+PERCOMP1(trunc)
+PERCOMP2(fmod)
+PERCOMP2F(fmod)
+int mod(int a, int b)
+{
+ return a - b * (int)floor(a / b);
+}
+point mod(point a, point b)
+{
+ return a - b * floor(a / b);
+}
+vector mod(vector a, vector b)
+{
+ return a - b * floor(a / b);
+}
+normal mod(normal a, normal b)
+{
+ return a - b * floor(a / b);
+}
+color mod(color a, color b)
+{
+ return a - b * floor(a / b);
+}
+point mod(point a, float b)
+{
+ return a - b * floor(a / b);
+}
+vector mod(vector a, float b)
+{
+ return a - b * floor(a / b);
+}
+normal mod(normal a, float b)
+{
+ return a - b * floor(a / b);
+}
+color mod(color a, float b)
+{
+ return a - b * floor(a / b);
+}
+float mod(float a, float b)
+{
+ return a - b * floor(a / b);
+}
+PERCOMP2(min)
+int min(int a, int b) BUILTIN;
+PERCOMP2(max)
+int max(int a, int b) BUILTIN;
+normal clamp(normal x, normal minval, normal maxval)
+{
+ return max(min(x, maxval), minval);
+}
+vector clamp(vector x, vector minval, vector maxval)
+{
+ return max(min(x, maxval), minval);
+}
+point clamp(point x, point minval, point maxval)
+{
+ return max(min(x, maxval), minval);
+}
+color clamp(color x, color minval, color maxval)
+{
+ return max(min(x, maxval), minval);
+}
+float clamp(float x, float minval, float maxval)
+{
+ return max(min(x, maxval), minval);
+}
+int clamp(int x, int minval, int maxval)
+{
+ return max(min(x, maxval), minval);
+}
#if 0
normal mix (normal x, normal y, normal a) { return x*(1-a) + y*a; }
normal mix (normal x, normal y, float a) { return x*(1-a) + y*a; }
@@ -154,102 +245,121 @@ color mix (color x, color y, color a) { return x*(1-a) + y*a; }
color mix (color x, color y, float a) { return x*(1-a) + y*a; }
float mix (float x, float y, float a) { return x*(1-a) + y*a; }
#else
-normal mix (normal x, normal y, normal a) BUILTIN;
-normal mix (normal x, normal y, float a) BUILTIN;
-vector mix (vector x, vector y, vector a) BUILTIN;
-vector mix (vector x, vector y, float a) BUILTIN;
-point mix (point x, point y, point a) BUILTIN;
-point mix (point x, point y, float a) BUILTIN;
-color mix (color x, color y, color a) BUILTIN;
-color mix (color x, color y, float a) BUILTIN;
-float mix (float x, float y, float a) BUILTIN;
+normal mix(normal x, normal y, normal a) BUILTIN;
+normal mix(normal x, normal y, float a) BUILTIN;
+vector mix(vector x, vector y, vector a) BUILTIN;
+vector mix(vector x, vector y, float a) BUILTIN;
+point mix(point x, point y, point a) BUILTIN;
+point mix(point x, point y, float a) BUILTIN;
+color mix(color x, color y, color a) BUILTIN;
+color mix(color x, color y, float a) BUILTIN;
+float mix(float x, float y, float a) BUILTIN;
#endif
-int isnan (float x) BUILTIN;
-int isinf (float x) BUILTIN;
-int isfinite (float x) BUILTIN;
-float erf (float x) BUILTIN;
-float erfc (float x) BUILTIN;
+int isnan(float x) BUILTIN;
+int isinf(float x) BUILTIN;
+int isfinite(float x) BUILTIN;
+float erf(float x) BUILTIN;
+float erfc(float x) BUILTIN;
// Vector functions
-vector cross (vector a, vector b) BUILTIN;
-float dot (vector a, vector b) BUILTIN;
-float length (vector v) BUILTIN;
-float distance (point a, point b) BUILTIN;
-float distance (point a, point b, point q)
-{
- vector d = b - a;
- float dd = dot(d, d);
- if(dd == 0.0)
- return distance(q, a);
- float t = dot(q - a, d)/dd;
- return distance(q, a + clamp(t, 0.0, 1.0)*d);
-}
-normal normalize (normal v) BUILTIN;
-vector normalize (vector v) BUILTIN;
-vector faceforward (vector N, vector I, vector Nref) BUILTIN;
-vector faceforward (vector N, vector I) BUILTIN;
-vector reflect (vector I, vector N) { return I - 2*dot(N,I)*N; }
-vector refract (vector I, vector N, float eta) {
- float IdotN = dot (I, N);
- float k = 1 - eta*eta * (1 - IdotN*IdotN);
- return (k < 0) ? vector(0,0,0) : (eta*I - N * (eta*IdotN + sqrt(k)));
-}
-void fresnel (vector I, normal N, float eta,
- output float Kr, output float Kt,
- output vector R, output vector T)
-{
- float sqr(float x) { return x*x; }
- float c = dot(I, N);
- if (c < 0)
- c = -c;
- R = reflect(I, N);
- float g = 1.0 / sqr(eta) - 1.0 + c * c;
- if (g >= 0.0) {
- g = sqrt (g);
- float beta = g - c;
- float F = (c * (g+c) - 1.0) / (c * beta + 1.0);
- F = 0.5 * (1.0 + sqr(F));
- F *= sqr (beta / (g+c));
- Kr = F;
- Kt = (1.0 - Kr) * eta*eta;
- // OPT: the following recomputes some of the above values, but it
- // gives us the same result as if the shader-writer called refract()
- T = refract(I, N, eta);
- } else {
- // total internal reflection
- Kr = 1.0;
- Kt = 0.0;
- T = vector (0,0,0);
- }
+vector cross(vector a, vector b) BUILTIN;
+float dot(vector a, vector b) BUILTIN;
+float length(vector v) BUILTIN;
+float distance(point a, point b) BUILTIN;
+float distance(point a, point b, point q)
+{
+ vector d = b - a;
+ float dd = dot(d, d);
+ if (dd == 0.0)
+ return distance(q, a);
+ float t = dot(q - a, d) / dd;
+ return distance(q, a + clamp(t, 0.0, 1.0) * d);
}
-
-void fresnel (vector I, normal N, float eta,
- output float Kr, output float Kt)
+normal normalize(normal v) BUILTIN;
+vector normalize(vector v) BUILTIN;
+vector faceforward(vector N, vector I, vector Nref) BUILTIN;
+vector faceforward(vector N, vector I) BUILTIN;
+vector reflect(vector I, vector N)
{
- vector R, T;
- fresnel(I, N, eta, Kr, Kt, R, T);
+ return I - 2 * dot(N, I) * N;
+}
+vector refract(vector I, vector N, float eta)
+{
+ float IdotN = dot(I, N);
+ float k = 1 - eta * eta * (1 - IdotN * IdotN);
+ return (k < 0) ? vector(0, 0, 0) : (eta * I - N * (eta * IdotN + sqrt(k)));
+}
+void fresnel(vector I,
+ normal N,
+ float eta,
+ output float Kr,
+ output float Kt,
+ output vector R,
+ output vector T)
+{
+ float sqr(float x)
+ {
+ return x * x;
+ }
+ float c = dot(I, N);
+ if (c < 0)
+ c = -c;
+ R = reflect(I, N);
+ float g = 1.0 / sqr(eta) - 1.0 + c * c;
+ if (g >= 0.0) {
+ g = sqrt(g);
+ float beta = g - c;
+ float F = (c * (g + c) - 1.0) / (c * beta + 1.0);
+ F = 0.5 * (1.0 + sqr(F));
+ F *= sqr(beta / (g + c));
+ Kr = F;
+ Kt = (1.0 - Kr) * eta * eta;
+ // OPT: the following recomputes some of the above values, but it
+ // gives us the same result as if the shader-writer called refract()
+ T = refract(I, N, eta);
+ }
+ else {
+ // total internal reflection
+ Kr = 1.0;
+ Kt = 0.0;
+ T = vector(0, 0, 0);
+ }
}
+void fresnel(vector I, normal N, float eta, output float Kr, output float Kt)
+{
+ vector R, T;
+ fresnel(I, N, eta, Kr, Kt, R, T);
+}
-normal transform (matrix Mto, normal p) BUILTIN;
-vector transform (matrix Mto, vector p) BUILTIN;
-point transform (matrix Mto, point p) BUILTIN;
-normal transform (string from, string to, normal p) BUILTIN;
-vector transform (string from, string to, vector p) BUILTIN;
-point transform (string from, string to, point p) BUILTIN;
-normal transform (string to, normal p) { return transform("common",to,p); }
-vector transform (string to, vector p) { return transform("common",to,p); }
-point transform (string to, point p) { return transform("common",to,p); }
+normal transform(matrix Mto, normal p) BUILTIN;
+vector transform(matrix Mto, vector p) BUILTIN;
+point transform(matrix Mto, point p) BUILTIN;
+normal transform(string from, string to, normal p) BUILTIN;
+vector transform(string from, string to, vector p) BUILTIN;
+point transform(string from, string to, point p) BUILTIN;
+normal transform(string to, normal p)
+{
+ return transform("common", to, p);
+}
+vector transform(string to, vector p)
+{
+ return transform("common", to, p);
+}
+point transform(string to, point p)
+{
+ return transform("common", to, p);
+}
-float transformu (string tounits, float x) BUILTIN;
-float transformu (string fromunits, string tounits, float x) BUILTIN;
+float transformu(string tounits, float x) BUILTIN;
+float transformu(string fromunits, string tounits, float x) BUILTIN;
-point rotate (point p, float angle, point a, point b)
+point rotate(point p, float angle, point a, point b)
{
- vector axis = normalize (b - a);
- float cosang, sinang;
- /* Older OSX has major issues with sincos() function,
+ vector axis = normalize(b - a);
+ float cosang, sinang;
+ /* Older OSX has major issues with sincos() function,
* it's likely a big in OSL or LLVM. For until we've
* updated to new versions of this libraries we'll
* use a workaround to prevent possible crashes on all
@@ -261,317 +371,348 @@ point rotate (point p, float angle, point a, point b)
#if 0
sincos (angle, sinang, cosang);
#else
- sinang = sin (angle);
- cosang = cos (angle);
+ sinang = sin(angle);
+ cosang = cos(angle);
#endif
- float cosang1 = 1.0 - cosang;
- float x = axis[0], y = axis[1], z = axis[2];
- matrix M = matrix (x * x + (1.0 - x * x) * cosang,
- x * y * cosang1 + z * sinang,
- x * z * cosang1 - y * sinang,
- 0.0,
- x * y * cosang1 - z * sinang,
- y * y + (1.0 - y * y) * cosang,
- y * z * cosang1 + x * sinang,
- 0.0,
- x * z * cosang1 + y * sinang,
- y * z * cosang1 - x * sinang,
- z * z + (1.0 - z * z) * cosang,
- 0.0,
- 0.0, 0.0, 0.0, 1.0);
- return transform (M, p-a) + a;
+ float cosang1 = 1.0 - cosang;
+ float x = axis[0], y = axis[1], z = axis[2];
+ matrix M = matrix(x * x + (1.0 - x * x) * cosang,
+ x * y * cosang1 + z * sinang,
+ x * z * cosang1 - y * sinang,
+ 0.0,
+ x * y * cosang1 - z * sinang,
+ y * y + (1.0 - y * y) * cosang,
+ y * z * cosang1 + x * sinang,
+ 0.0,
+ x * z * cosang1 + y * sinang,
+ y * z * cosang1 - x * sinang,
+ z * z + (1.0 - z * z) * cosang,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0);
+ return transform(M, p - a) + a;
}
normal ensure_valid_reflection(normal Ng, vector I, normal N)
{
- /* The implementation here mirrors the one in kernel_montecarlo.h,
+ /* The implementation here mirrors the one in kernel_montecarlo.h,
* check there for an explanation of the algorithm. */
- float sqr(float x) { return x*x; }
-
- vector R = 2*dot(N, I)*N - I;
+ float sqr(float x)
+ {
+ return x * x;
+ }
- float threshold = min(0.9*dot(Ng, I), 0.01);
- if(dot(Ng, R) >= threshold) {
- return N;
- }
+ vector R = 2 * dot(N, I) * N - I;
- float NdotNg = dot(N, Ng);
- vector X = normalize(N - NdotNg*Ng);
+ float threshold = min(0.9 * dot(Ng, I), 0.01);
+ if (dot(Ng, R) >= threshold) {
+ return N;
+ }
- float Ix = dot(I, X), Iz = dot(I, Ng);
- float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
- float a = Ix2 + Iz2;
+ float NdotNg = dot(N, Ng);
+ vector X = normalize(N - NdotNg * Ng);
- float b = sqrt(Ix2*(a - sqr(threshold)));
- float c = Iz*threshold + a;
+ float Ix = dot(I, X), Iz = dot(I, Ng);
+ float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
+ float a = Ix2 + Iz2;
- float fac = 0.5/a;
- float N1_z2 = fac*(b+c), N2_z2 = fac*(-b+c);
- int valid1 = (N1_z2 > 1e-5) && (N1_z2 <= (1.0 + 1e-5));
- int valid2 = (N2_z2 > 1e-5) && (N2_z2 <= (1.0 + 1e-5));
+ float b = sqrt(Ix2 * (a - sqr(threshold)));
+ float c = Iz * threshold + a;
- float N_new_x, N_new_z;
- if(valid1 && valid2) {
- float N1_x = sqrt(1.0 - N1_z2), N1_z = sqrt(N1_z2);
- float N2_x = sqrt(1.0 - N2_z2), N2_z = sqrt(N2_z2);
+ float fac = 0.5 / a;
+ float N1_z2 = fac * (b + c), N2_z2 = fac * (-b + c);
+ int valid1 = (N1_z2 > 1e-5) && (N1_z2 <= (1.0 + 1e-5));
+ int valid2 = (N2_z2 > 1e-5) && (N2_z2 <= (1.0 + 1e-5));
- float R1 = 2*(N1_x*Ix + N1_z*Iz)*N1_z - Iz;
- float R2 = 2*(N2_x*Ix + N2_z*Iz)*N2_z - Iz;
+ float N_new_x, N_new_z;
+ if (valid1 && valid2) {
+ float N1_x = sqrt(1.0 - N1_z2), N1_z = sqrt(N1_z2);
+ float N2_x = sqrt(1.0 - N2_z2), N2_z = sqrt(N2_z2);
- valid1 = (R1 >= 1e-5);
- valid2 = (R2 >= 1e-5);
- if(valid1 && valid2) {
- N_new_x = (R1 < R2)? N1_x : N2_x;
- N_new_z = (R1 < R2)? N1_z : N2_z;
- }
- else {
- N_new_x = (R1 > R2)? N1_x : N2_x;
- N_new_z = (R1 > R2)? N1_z : N2_z;
- }
+ float R1 = 2 * (N1_x * Ix + N1_z * Iz) * N1_z - Iz;
+ float R2 = 2 * (N2_x * Ix + N2_z * Iz) * N2_z - Iz;
- }
- else if(valid1 || valid2) {
- float Nz2 = valid1? N1_z2 : N2_z2;
- N_new_x = sqrt(1.0 - Nz2);
- N_new_z = sqrt(Nz2);
+ valid1 = (R1 >= 1e-5);
+ valid2 = (R2 >= 1e-5);
+ if (valid1 && valid2) {
+ N_new_x = (R1 < R2) ? N1_x : N2_x;
+ N_new_z = (R1 < R2) ? N1_z : N2_z;
}
else {
- return Ng;
+ N_new_x = (R1 > R2) ? N1_x : N2_x;
+ N_new_z = (R1 > R2) ? N1_z : N2_z;
}
-
- return N_new_x*X + N_new_z*Ng;
+ }
+ else if (valid1 || valid2) {
+ float Nz2 = valid1 ? N1_z2 : N2_z2;
+ N_new_x = sqrt(1.0 - Nz2);
+ N_new_z = sqrt(Nz2);
+ }
+ else {
+ return Ng;
+ }
+
+ return N_new_x * X + N_new_z * Ng;
}
-
// Color functions
-float luminance (color c) BUILTIN;
-color blackbody (float temperatureK) BUILTIN;
-color wavelength_color (float wavelength_nm) BUILTIN;
-
-
-color transformc (string to, color x)
-{
- color rgb_to_hsv (color rgb) { // See Foley & van Dam
- float r = rgb[0], g = rgb[1], b = rgb[2];
- float mincomp = min (r, min (g, b));
- float maxcomp = max (r, max (g, b));
- float delta = maxcomp - mincomp; // chroma
- float h, s, v;
- v = maxcomp;
- if (maxcomp > 0)
- s = delta / maxcomp;
- else s = 0;
- if (s <= 0)
- h = 0;
- else {
- if (r >= maxcomp) h = (g-b) / delta;
- else if (g >= maxcomp) h = 2 + (b-r) / delta;
- else h = 4 + (r-g) / delta;
- h /= 6;
- if (h < 0)
- h += 1;
- }
- return color (h, s, v);
- }
-
- color rgb_to_hsl (color rgb) { // See Foley & van Dam
- // First convert rgb to hsv, then to hsl
- float minval = min (rgb[0], min (rgb[1], rgb[2]));
- color hsv = rgb_to_hsv (rgb);
- float maxval = hsv[2]; // v == maxval
- float h = hsv[0], s, l = (minval+maxval) / 2;
- if (minval == maxval)
- s = 0; // special 'achromatic' case, hue is 0
- else if (l <= 0.5)
- s = (maxval - minval) / (maxval + minval);
- else
- s = (maxval - minval) / (2 - maxval - minval);
- return color (h, s, l);
- }
+float luminance(color c) BUILTIN;
+color blackbody(float temperatureK) BUILTIN;
+color wavelength_color(float wavelength_nm) BUILTIN;
- color r;
- if (to == "rgb" || to == "RGB")
- r = x;
- else if (to == "hsv")
- r = rgb_to_hsv (x);
- else if (to == "hsl")
- r = rgb_to_hsl (x);
- else if (to == "YIQ")
- r = color (dot (vector(0.299, 0.587, 0.114), (vector)x),
- dot (vector(0.596, -0.275, -0.321), (vector)x),
- dot (vector(0.212, -0.523, 0.311), (vector)x));
- else if (to == "XYZ")
- r = color (dot (vector(0.412453, 0.357580, 0.180423), (vector)x),
- dot (vector(0.212671, 0.715160, 0.072169), (vector)x),
- dot (vector(0.019334, 0.119193, 0.950227), (vector)x));
+color transformc(string to, color x)
+{
+ color rgb_to_hsv(color rgb)
+ { // See Foley & van Dam
+ float r = rgb[0], g = rgb[1], b = rgb[2];
+ float mincomp = min(r, min(g, b));
+ float maxcomp = max(r, max(g, b));
+ float delta = maxcomp - mincomp; // chroma
+ float h, s, v;
+ v = maxcomp;
+ if (maxcomp > 0)
+ s = delta / maxcomp;
+ else
+ s = 0;
+ if (s <= 0)
+ h = 0;
else {
- error ("Unknown color space \"%s\"", to);
- r = x;
+ if (r >= maxcomp)
+ h = (g - b) / delta;
+ else if (g >= maxcomp)
+ h = 2 + (b - r) / delta;
+ else
+ h = 4 + (r - g) / delta;
+ h /= 6;
+ if (h < 0)
+ h += 1;
}
- return r;
+ return color(h, s, v);
+ }
+
+ color rgb_to_hsl(color rgb)
+ { // See Foley & van Dam
+ // First convert rgb to hsv, then to hsl
+ float minval = min(rgb[0], min(rgb[1], rgb[2]));
+ color hsv = rgb_to_hsv(rgb);
+ float maxval = hsv[2]; // v == maxval
+ float h = hsv[0], s, l = (minval + maxval) / 2;
+ if (minval == maxval)
+ s = 0; // special 'achromatic' case, hue is 0
+ else if (l <= 0.5)
+ s = (maxval - minval) / (maxval + minval);
+ else
+ s = (maxval - minval) / (2 - maxval - minval);
+ return color(h, s, l);
+ }
+
+ color r;
+ if (to == "rgb" || to == "RGB")
+ r = x;
+ else if (to == "hsv")
+ r = rgb_to_hsv(x);
+ else if (to == "hsl")
+ r = rgb_to_hsl(x);
+ else if (to == "YIQ")
+ r = color(dot(vector(0.299, 0.587, 0.114), (vector)x),
+ dot(vector(0.596, -0.275, -0.321), (vector)x),
+ dot(vector(0.212, -0.523, 0.311), (vector)x));
+ else if (to == "XYZ")
+ r = color(dot(vector(0.412453, 0.357580, 0.180423), (vector)x),
+ dot(vector(0.212671, 0.715160, 0.072169), (vector)x),
+ dot(vector(0.019334, 0.119193, 0.950227), (vector)x));
+ else {
+ error("Unknown color space \"%s\"", to);
+ r = x;
+ }
+ return r;
}
-
-color transformc (string from, string to, color x)
-{
- color hsv_to_rgb (color c) { // Reference: Foley & van Dam
- float h = c[0], s = c[1], v = c[2];
- color r;
- if (s < 0.0001) {
- r = v;
- } else {
- h = 6 * (h - floor(h)); // expand to [0..6)
- int hi = (int)h;
- float f = h - hi;
- float p = v * (1-s);
- float q = v * (1-s*f);
- float t = v * (1-s*(1-f));
- if (hi == 0) r = color (v, t, p);
- else if (hi == 1) r = color (q, v, p);
- else if (hi == 2) r = color (p, v, t);
- else if (hi == 3) r = color (p, q, v);
- else if (hi == 4) r = color (t, p, v);
- else r = color (v, p, q);
- }
- return r;
+color transformc(string from, string to, color x)
+{
+ color hsv_to_rgb(color c)
+ { // Reference: Foley & van Dam
+ float h = c[0], s = c[1], v = c[2];
+ color r;
+ if (s < 0.0001) {
+ r = v;
}
-
- color hsl_to_rgb (color c) {
- float h = c[0], s = c[1], l = c[2];
- // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam)
- float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s);
- color r;
- if (v <= 0) {
- r = 0;
- } else {
- float min = 2 * l - v;
- s = (v - min) / v;
- r = hsv_to_rgb (color (h, s, v));
- }
- return r;
+ else {
+ h = 6 * (h - floor(h)); // expand to [0..6)
+ int hi = (int)h;
+ float f = h - hi;
+ float p = v * (1 - s);
+ float q = v * (1 - s * f);
+ float t = v * (1 - s * (1 - f));
+ if (hi == 0)
+ r = color(v, t, p);
+ else if (hi == 1)
+ r = color(q, v, p);
+ else if (hi == 2)
+ r = color(p, v, t);
+ else if (hi == 3)
+ r = color(p, q, v);
+ else if (hi == 4)
+ r = color(t, p, v);
+ else
+ r = color(v, p, q);
}
+ return r;
+ }
+ color hsl_to_rgb(color c)
+ {
+ float h = c[0], s = c[1], l = c[2];
+ // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam)
+ float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s);
color r;
- if (from == "rgb" || from == "RGB")
- r = x;
- else if (from == "hsv")
- r = hsv_to_rgb (x);
- else if (from == "hsl")
- r = hsl_to_rgb (x);
- else if (from == "YIQ")
- r = color (dot (vector(1, 0.9557, 0.6199), (vector)x),
- dot (vector(1, -0.2716, -0.6469), (vector)x),
- dot (vector(1, -1.1082, 1.7051), (vector)x));
- else if (from == "XYZ")
- r = color (dot (vector( 3.240479, -1.537150, -0.498535), (vector)x),
- dot (vector(-0.969256, 1.875991, 0.041556), (vector)x),
- dot (vector( 0.055648, -0.204043, 1.057311), (vector)x));
+ if (v <= 0) {
+ r = 0;
+ }
else {
- error ("Unknown color space \"%s\"", to);
- r = x;
+ float min = 2 * l - v;
+ s = (v - min) / v;
+ r = hsv_to_rgb(color(h, s, v));
}
- return transformc (to, r);
+ return r;
+ }
+
+ color r;
+ if (from == "rgb" || from == "RGB")
+ r = x;
+ else if (from == "hsv")
+ r = hsv_to_rgb(x);
+ else if (from == "hsl")
+ r = hsl_to_rgb(x);
+ else if (from == "YIQ")
+ r = color(dot(vector(1, 0.9557, 0.6199), (vector)x),
+ dot(vector(1, -0.2716, -0.6469), (vector)x),
+ dot(vector(1, -1.1082, 1.7051), (vector)x));
+ else if (from == "XYZ")
+ r = color(dot(vector(3.240479, -1.537150, -0.498535), (vector)x),
+ dot(vector(-0.969256, 1.875991, 0.041556), (vector)x),
+ dot(vector(0.055648, -0.204043, 1.057311), (vector)x));
+ else {
+ error("Unknown color space \"%s\"", to);
+ r = x;
+ }
+ return transformc(to, r);
}
-
-
// Matrix functions
-float determinant (matrix m) BUILTIN;
-matrix transpose (matrix m) BUILTIN;
+float determinant(matrix m) BUILTIN;
+matrix transpose(matrix m) BUILTIN;
+// Pattern generation
+color step(color edge, color x) BUILTIN;
+point step(point edge, point x) BUILTIN;
+vector step(vector edge, vector x) BUILTIN;
+normal step(normal edge, normal x) BUILTIN;
+float step(float edge, float x) BUILTIN;
+float smoothstep(float edge0, float edge1, float x) BUILTIN;
-// Pattern generation
+float linearstep(float edge0, float edge1, float x)
+{
+ float result;
+ if (edge0 != edge1) {
+ float xclamped = clamp(x, edge0, edge1);
+ result = (xclamped - edge0) / (edge1 - edge0);
+ }
+ else { // special case: edges coincide
+ result = step(edge0, x);
+ }
+ return result;
+}
-color step (color edge, color x) BUILTIN;
-point step (point edge, point x) BUILTIN;
-vector step (vector edge, vector x) BUILTIN;
-normal step (normal edge, normal x) BUILTIN;
-float step (float edge, float x) BUILTIN;
-float smoothstep (float edge0, float edge1, float x) BUILTIN;
-
-float linearstep (float edge0, float edge1, float x) {
- float result;
- if (edge0 != edge1) {
- float xclamped = clamp (x, edge0, edge1);
- result = (xclamped - edge0) / (edge1 - edge0);
- } else { // special case: edges coincide
- result = step (edge0, x);
- }
- return result;
-}
-
-float smooth_linearstep (float edge0, float edge1, float x_, float eps_) {
- float result;
- if (edge0 != edge1) {
- float rampup (float x, float r) { return 0.5/r * x*x; }
- float width_inv = 1.0 / (edge1 - edge0);
- float eps = eps_ * width_inv;
- float x = (x_ - edge0) * width_inv;
- if (x <= -eps) result = 0;
- else if (x >= eps && x <= 1.0-eps) result = x;
- else if (x >= 1.0+eps) result = 1;
- else if (x < eps) result = rampup (x+eps, 2.0*eps);
- else /* if (x < 1.0+eps) */ result = 1.0 - rampup (1.0+eps - x, 2.0*eps);
- } else {
- result = step (edge0, x_);
+float smooth_linearstep(float edge0, float edge1, float x_, float eps_)
+{
+ float result;
+ if (edge0 != edge1) {
+ float rampup(float x, float r)
+ {
+ return 0.5 / r * x * x;
}
- return result;
+ float width_inv = 1.0 / (edge1 - edge0);
+ float eps = eps_ * width_inv;
+ float x = (x_ - edge0) * width_inv;
+ if (x <= -eps)
+ result = 0;
+ else if (x >= eps && x <= 1.0 - eps)
+ result = x;
+ else if (x >= 1.0 + eps)
+ result = 1;
+ else if (x < eps)
+ result = rampup(x + eps, 2.0 * eps);
+ else /* if (x < 1.0+eps) */
+ result = 1.0 - rampup(1.0 + eps - x, 2.0 * eps);
+ }
+ else {
+ result = step(edge0, x_);
+ }
+ return result;
}
-float aastep (float edge, float s, float dedge, float ds) {
- // Box filtered AA step
- float width = fabs(dedge) + fabs(ds);
- float halfwidth = 0.5*width;
- float e1 = edge-halfwidth;
- return (s <= e1) ? 0.0 : ((s >= (edge+halfwidth)) ? 1.0 : (s-e1)/width);
+float aastep(float edge, float s, float dedge, float ds)
+{
+ // Box filtered AA step
+ float width = fabs(dedge) + fabs(ds);
+ float halfwidth = 0.5 * width;
+ float e1 = edge - halfwidth;
+ return (s <= e1) ? 0.0 : ((s >= (edge + halfwidth)) ? 1.0 : (s - e1) / width);
}
-float aastep (float edge, float s, float ds) {
- return aastep (edge, s, filterwidth(edge), ds);
+float aastep(float edge, float s, float ds)
+{
+ return aastep(edge, s, filterwidth(edge), ds);
}
-float aastep (float edge, float s) {
- return aastep (edge, s, filterwidth(edge), filterwidth(s));
+float aastep(float edge, float s)
+{
+ return aastep(edge, s, filterwidth(edge), filterwidth(s));
}
-
// Derivatives and area operators
-
// Displacement functions
-
// String functions
-int strlen (string s) BUILTIN;
-int hash (string s) BUILTIN;
-int getchar (string s, int index) BUILTIN;
-int startswith (string s, string prefix) BUILTIN;
-int endswith (string s, string suffix) BUILTIN;
-string substr (string s, int start, int len) BUILTIN;
-string substr (string s, int start) { return substr (s, start, strlen(s)); }
-float stof (string str) BUILTIN;
-int stoi (string str) BUILTIN;
+int strlen(string s) BUILTIN;
+int hash(string s) BUILTIN;
+int getchar(string s, int index) BUILTIN;
+int startswith(string s, string prefix) BUILTIN;
+int endswith(string s, string suffix) BUILTIN;
+string substr(string s, int start, int len) BUILTIN;
+string substr(string s, int start)
+{
+ return substr(s, start, strlen(s));
+}
+float stof(string str) BUILTIN;
+int stoi(string str) BUILTIN;
// Define concat in terms of shorter concat
-string concat (string a, string b, string c) {
- return concat(concat(a,b), c);
+string concat(string a, string b, string c)
+{
+ return concat(concat(a, b), c);
}
-string concat (string a, string b, string c, string d) {
- return concat(concat(a,b,c), d);
+string concat(string a, string b, string c, string d)
+{
+ return concat(concat(a, b, c), d);
}
-string concat (string a, string b, string c, string d, string e) {
- return concat(concat(a,b,c,d), e);
+string concat(string a, string b, string c, string d, string e)
+{
+ return concat(concat(a, b, c, d), e);
}
-string concat (string a, string b, string c, string d, string e, string f) {
- return concat(concat(a,b,c,d,e), f);
+string concat(string a, string b, string c, string d, string e, string f)
+{
+ return concat(concat(a, b, c, d, e), f);
}
-
// Texture
-
// Closures
closure color diffuse(normal N) BUILTIN;
@@ -591,14 +732,18 @@ closure color microfacet_multi_ggx(normal N, float ag, color C) BUILTIN;
closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN;
closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;
closure color microfacet_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
-closure color microfacet_ggx_aniso_fresnel(normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
-closure color microfacet_multi_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
-closure color microfacet_multi_ggx_aniso_fresnel(normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
-closure color microfacet_multi_ggx_glass_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
+closure color microfacet_ggx_aniso_fresnel(
+ normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
+closure color
+microfacet_multi_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
+closure color microfacet_multi_ggx_aniso_fresnel(
+ normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
+closure color
+microfacet_multi_ggx_glass_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
closure color microfacet_beckmann(normal N, float ab) BUILTIN;
closure color microfacet_beckmann_aniso(normal N, vector T, float ax, float ay) BUILTIN;
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
-closure color ashikhmin_shirley(normal N, vector T,float ax, float ay) BUILTIN;
+closure color ashikhmin_shirley(normal N, vector T, float ax, float ay) BUILTIN;
closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
closure color emission() BUILTIN;
closure color background() BUILTIN;
@@ -612,78 +757,97 @@ closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_ro
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN;
// Hair
-closure color hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
-closure color hair_transmission(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
-closure color principled_hair(normal N, color sigma, float roughnessu, float roughnessv, float coat, float alpha, float eta) BUILTIN;
+closure color
+hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
+closure color
+hair_transmission(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
+closure color principled_hair(normal N,
+ color sigma,
+ float roughnessu,
+ float roughnessv,
+ float coat,
+ float alpha,
+ float eta) BUILTIN;
// Volume
closure color henyey_greenstein(float g) BUILTIN;
closure color absorption() BUILTIN;
// OSL 1.5 Microfacet functions
-closure color microfacet(string distribution, normal N, vector U, float xalpha, float yalpha, float eta, int refract) {
- /* GGX */
- if (distribution == "ggx" || distribution == "default") {
- if (!refract) {
- if (xalpha == yalpha) {
- /* Isotropic */
- return microfacet_ggx(N, xalpha);
- }
- else {
- /* Anisotropic */
- return microfacet_ggx_aniso(N, U, xalpha, yalpha);
- }
- }
- else {
- return microfacet_ggx_refraction(N, xalpha, eta);
- }
- }
- /* Beckmann */
- else {
- if (!refract) {
- if (xalpha == yalpha) {
- /* Isotropic */
- return microfacet_beckmann(N, xalpha);
- }
- else {
- /* Anisotropic */
- return microfacet_beckmann_aniso(N, U, xalpha, yalpha);
- }
- }
- else {
- return microfacet_beckmann_refraction(N, xalpha, eta);
- }
- }
-}
-
-closure color microfacet (string distribution, normal N, float alpha, float eta, int refract) {
- return microfacet(distribution, N, vector(0), alpha, alpha, eta, refract);
+closure color microfacet(
+ string distribution, normal N, vector U, float xalpha, float yalpha, float eta, int refract)
+{
+ /* GGX */
+ if (distribution == "ggx" || distribution == "default") {
+ if (!refract) {
+ if (xalpha == yalpha) {
+ /* Isotropic */
+ return microfacet_ggx(N, xalpha);
+ }
+ else {
+ /* Anisotropic */
+ return microfacet_ggx_aniso(N, U, xalpha, yalpha);
+ }
+ }
+ else {
+ return microfacet_ggx_refraction(N, xalpha, eta);
+ }
+ }
+ /* Beckmann */
+ else {
+ if (!refract) {
+ if (xalpha == yalpha) {
+ /* Isotropic */
+ return microfacet_beckmann(N, xalpha);
+ }
+ else {
+ /* Anisotropic */
+ return microfacet_beckmann_aniso(N, U, xalpha, yalpha);
+ }
+ }
+ else {
+ return microfacet_beckmann_refraction(N, xalpha, eta);
+ }
+ }
}
+closure color microfacet(string distribution, normal N, float alpha, float eta, int refract)
+{
+ return microfacet(distribution, N, vector(0), alpha, alpha, eta, refract);
+}
// Renderer state
-int backfacing () BUILTIN;
-int raytype (string typename) BUILTIN;
+int backfacing() BUILTIN;
+int raytype(string typename) BUILTIN;
// the individual 'isFOOray' functions are deprecated
-int iscameraray () { return raytype("camera"); }
-int isdiffuseray () { return raytype("diffuse"); }
-int isglossyray () { return raytype("glossy"); }
-int isshadowray () { return raytype("shadow"); }
-int getmatrix (string fromspace, string tospace, output matrix M) BUILTIN;
-int getmatrix (string fromspace, output matrix M) {
- return getmatrix (fromspace, "common", M);
+int iscameraray()
+{
+ return raytype("camera");
+}
+int isdiffuseray()
+{
+ return raytype("diffuse");
+}
+int isglossyray()
+{
+ return raytype("glossy");
+}
+int isshadowray()
+{
+ return raytype("shadow");
+}
+int getmatrix(string fromspace, string tospace, output matrix M) BUILTIN;
+int getmatrix(string fromspace, output matrix M)
+{
+ return getmatrix(fromspace, "common", M);
}
-
// Miscellaneous
-
-
-
#undef BUILTIN
#undef BUILTIN_DERIV
#undef PERCOMP1
#undef PERCOMP2
#undef PERCOMP2F
-#endif /* CCL_STDOSL_H */
+#endif /* CCL_STDOSL_H */
diff --git a/intern/cycles/kernel/split/kernel_branched.h b/intern/cycles/kernel/split/kernel_branched.h
index ed0a82067f1..e08d87ab618 100644
--- a/intern/cycles/kernel/split/kernel_branched.h
+++ b/intern/cycles/kernel/split/kernel_branched.h
@@ -19,215 +19,213 @@ CCL_NAMESPACE_BEGIN
#ifdef __BRANCHED_PATH__
/* sets up the various state needed to do an indirect loop */
-ccl_device_inline void kernel_split_branched_path_indirect_loop_init(KernelGlobals *kg, int ray_index)
+ccl_device_inline void kernel_split_branched_path_indirect_loop_init(KernelGlobals *kg,
+ int ray_index)
{
- SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
+ SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
- /* save a copy of the state to restore later */
-#define BRANCHED_STORE(name) \
- branched_state->name = kernel_split_state.name[ray_index];
+ /* save a copy of the state to restore later */
+# define BRANCHED_STORE(name) branched_state->name = kernel_split_state.name[ray_index];
- BRANCHED_STORE(path_state);
- BRANCHED_STORE(throughput);
- BRANCHED_STORE(ray);
- BRANCHED_STORE(isect);
- BRANCHED_STORE(ray_state);
+ BRANCHED_STORE(path_state);
+ BRANCHED_STORE(throughput);
+ BRANCHED_STORE(ray);
+ BRANCHED_STORE(isect);
+ BRANCHED_STORE(ray_state);
- *kernel_split_sd(branched_state_sd, ray_index) = *kernel_split_sd(sd, ray_index);
- for(int i = 0; i < kernel_split_sd(branched_state_sd, ray_index)->num_closure; i++) {
- kernel_split_sd(branched_state_sd, ray_index)->closure[i] = kernel_split_sd(sd, ray_index)->closure[i];
- }
+ *kernel_split_sd(branched_state_sd, ray_index) = *kernel_split_sd(sd, ray_index);
+ for (int i = 0; i < kernel_split_sd(branched_state_sd, ray_index)->num_closure; i++) {
+ kernel_split_sd(branched_state_sd, ray_index)->closure[i] =
+ kernel_split_sd(sd, ray_index)->closure[i];
+ }
-#undef BRANCHED_STORE
+# undef BRANCHED_STORE
- /* set loop counters to intial position */
- branched_state->next_closure = 0;
- branched_state->next_sample = 0;
+ /* set loop counters to intial position */
+ branched_state->next_closure = 0;
+ branched_state->next_sample = 0;
}
/* ends an indirect loop and restores the previous state */
-ccl_device_inline void kernel_split_branched_path_indirect_loop_end(KernelGlobals *kg, int ray_index)
+ccl_device_inline void kernel_split_branched_path_indirect_loop_end(KernelGlobals *kg,
+ int ray_index)
{
- SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
+ SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
- /* restore state */
-#define BRANCHED_RESTORE(name) \
- kernel_split_state.name[ray_index] = branched_state->name;
+ /* restore state */
+# define BRANCHED_RESTORE(name) kernel_split_state.name[ray_index] = branched_state->name;
- BRANCHED_RESTORE(path_state);
- BRANCHED_RESTORE(throughput);
- BRANCHED_RESTORE(ray);
- BRANCHED_RESTORE(isect);
- BRANCHED_RESTORE(ray_state);
+ BRANCHED_RESTORE(path_state);
+ BRANCHED_RESTORE(throughput);
+ BRANCHED_RESTORE(ray);
+ BRANCHED_RESTORE(isect);
+ BRANCHED_RESTORE(ray_state);
- *kernel_split_sd(sd, ray_index) = *kernel_split_sd(branched_state_sd, ray_index);
- for(int i = 0; i < kernel_split_sd(branched_state_sd, ray_index)->num_closure; i++) {
- kernel_split_sd(sd, ray_index)->closure[i] = kernel_split_sd(branched_state_sd, ray_index)->closure[i];
- }
+ *kernel_split_sd(sd, ray_index) = *kernel_split_sd(branched_state_sd, ray_index);
+ for (int i = 0; i < kernel_split_sd(branched_state_sd, ray_index)->num_closure; i++) {
+ kernel_split_sd(sd, ray_index)->closure[i] =
+ kernel_split_sd(branched_state_sd, ray_index)->closure[i];
+ }
-#undef BRANCHED_RESTORE
+# undef BRANCHED_RESTORE
- /* leave indirect loop */
- REMOVE_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT);
+ /* leave indirect loop */
+ REMOVE_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT);
}
-ccl_device_inline bool kernel_split_branched_indirect_start_shared(KernelGlobals *kg, int ray_index)
+ccl_device_inline bool kernel_split_branched_indirect_start_shared(KernelGlobals *kg,
+ int ray_index)
{
- ccl_global char *ray_state = kernel_split_state.ray_state;
+ ccl_global char *ray_state = kernel_split_state.ray_state;
- int inactive_ray = dequeue_ray_index(QUEUE_INACTIVE_RAYS,
- kernel_split_state.queue_data, kernel_split_params.queue_size, kernel_split_params.queue_index);
+ int inactive_ray = dequeue_ray_index(QUEUE_INACTIVE_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ kernel_split_params.queue_index);
- if(!IS_STATE(ray_state, inactive_ray, RAY_INACTIVE)) {
- return false;
- }
+ if (!IS_STATE(ray_state, inactive_ray, RAY_INACTIVE)) {
+ return false;
+ }
-#define SPLIT_DATA_ENTRY(type, name, num) \
- if(num) { \
- kernel_split_state.name[inactive_ray] = kernel_split_state.name[ray_index]; \
- }
- SPLIT_DATA_ENTRIES_BRANCHED_SHARED
-#undef SPLIT_DATA_ENTRY
+# define SPLIT_DATA_ENTRY(type, name, num) \
+ if (num) { \
+ kernel_split_state.name[inactive_ray] = kernel_split_state.name[ray_index]; \
+ }
+ SPLIT_DATA_ENTRIES_BRANCHED_SHARED
+# undef SPLIT_DATA_ENTRY
- *kernel_split_sd(sd, inactive_ray) = *kernel_split_sd(sd, ray_index);
- for(int i = 0; i < kernel_split_sd(sd, ray_index)->num_closure; i++) {
- kernel_split_sd(sd, inactive_ray)->closure[i] = kernel_split_sd(sd, ray_index)->closure[i];
- }
+ *kernel_split_sd(sd, inactive_ray) = *kernel_split_sd(sd, ray_index);
+ for (int i = 0; i < kernel_split_sd(sd, ray_index)->num_closure; i++) {
+ kernel_split_sd(sd, inactive_ray)->closure[i] = kernel_split_sd(sd, ray_index)->closure[i];
+ }
- kernel_split_state.branched_state[inactive_ray].shared_sample_count = 0;
- kernel_split_state.branched_state[inactive_ray].original_ray = ray_index;
- kernel_split_state.branched_state[inactive_ray].waiting_on_shared_samples = false;
+ kernel_split_state.branched_state[inactive_ray].shared_sample_count = 0;
+ kernel_split_state.branched_state[inactive_ray].original_ray = ray_index;
+ kernel_split_state.branched_state[inactive_ray].waiting_on_shared_samples = false;
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- PathRadiance *inactive_L = &kernel_split_state.path_radiance[inactive_ray];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ PathRadiance *inactive_L = &kernel_split_state.path_radiance[inactive_ray];
- path_radiance_init(inactive_L, kernel_data.film.use_light_pass);
- path_radiance_copy_indirect(inactive_L, L);
+ path_radiance_init(inactive_L, kernel_data.film.use_light_pass);
+ path_radiance_copy_indirect(inactive_L, L);
- ray_state[inactive_ray] = RAY_REGENERATED;
- ADD_RAY_FLAG(ray_state, inactive_ray, RAY_BRANCHED_INDIRECT_SHARED);
- ADD_RAY_FLAG(ray_state, inactive_ray, IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT));
+ ray_state[inactive_ray] = RAY_REGENERATED;
+ ADD_RAY_FLAG(ray_state, inactive_ray, RAY_BRANCHED_INDIRECT_SHARED);
+ ADD_RAY_FLAG(ray_state, inactive_ray, IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT));
- atomic_fetch_and_inc_uint32((ccl_global uint*)&kernel_split_state.branched_state[ray_index].shared_sample_count);
+ atomic_fetch_and_inc_uint32(
+ (ccl_global uint *)&kernel_split_state.branched_state[ray_index].shared_sample_count);
- return true;
+ return true;
}
/* bounce off surface and integrate indirect light */
-ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(KernelGlobals *kg,
- int ray_index,
- float num_samples_adjust,
- ShaderData *saved_sd,
- bool reset_path_state,
- bool wait_for_shared)
+ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(
+ KernelGlobals *kg,
+ int ray_index,
+ float num_samples_adjust,
+ ShaderData *saved_sd,
+ bool reset_path_state,
+ bool wait_for_shared)
{
- SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
-
- ShaderData *sd = saved_sd;
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- float3 throughput = branched_state->throughput;
- ccl_global PathState *ps = &kernel_split_state.path_state[ray_index];
-
- float sum_sample_weight = 0.0f;
-#ifdef __DENOISING_FEATURES__
- if(ps->denoising_feature_weight > 0.0f) {
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- /* transparency is not handled here, but in outer loop */
- if(!CLOSURE_IS_BSDF(sc->type) || CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
- continue;
- }
-
- sum_sample_weight += sc->sample_weight;
- }
- }
- else {
- sum_sample_weight = 1.0f;
- }
-#endif /* __DENOISING_FEATURES__ */
-
- for(int i = branched_state->next_closure; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(!CLOSURE_IS_BSDF(sc->type))
- continue;
- /* transparency is not handled here, but in outer loop */
- if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID)
- continue;
-
- int num_samples;
-
- if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
- num_samples = kernel_data.integrator.diffuse_samples;
- else if(CLOSURE_IS_BSDF_BSSRDF(sc->type))
- num_samples = 1;
- else if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
- num_samples = kernel_data.integrator.glossy_samples;
- else
- num_samples = kernel_data.integrator.transmission_samples;
-
- num_samples = ceil_to_int(num_samples_adjust*num_samples);
-
- float num_samples_inv = num_samples_adjust/num_samples;
-
- for(int j = branched_state->next_sample; j < num_samples; j++) {
- if(reset_path_state) {
- *ps = branched_state->path_state;
- }
-
- ps->rng_hash = cmj_hash(branched_state->path_state.rng_hash, i);
-
- ccl_global float3 *tp = &kernel_split_state.throughput[ray_index];
- *tp = throughput;
-
- ccl_global Ray *bsdf_ray = &kernel_split_state.ray[ray_index];
-
- if(!kernel_branched_path_surface_bounce(kg,
- sd,
- sc,
- j,
- num_samples,
- tp,
- ps,
- &L->state,
- bsdf_ray,
- sum_sample_weight))
- {
- continue;
- }
-
- ps->rng_hash = branched_state->path_state.rng_hash;
-
- /* update state for next iteration */
- branched_state->next_closure = i;
- branched_state->next_sample = j+1;
-
- /* start the indirect path */
- *tp *= num_samples_inv;
-
- if(kernel_split_branched_indirect_start_shared(kg, ray_index)) {
- continue;
- }
-
- return true;
- }
-
- branched_state->next_sample = 0;
- }
-
- branched_state->next_closure = sd->num_closure;
-
- if(wait_for_shared) {
- branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0);
- if(branched_state->waiting_on_shared_samples) {
- return true;
- }
- }
-
- return false;
+ SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
+
+ ShaderData *sd = saved_sd;
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ float3 throughput = branched_state->throughput;
+ ccl_global PathState *ps = &kernel_split_state.path_state[ray_index];
+
+ float sum_sample_weight = 0.0f;
+# ifdef __DENOISING_FEATURES__
+ if (ps->denoising_feature_weight > 0.0f) {
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ /* transparency is not handled here, but in outer loop */
+ if (!CLOSURE_IS_BSDF(sc->type) || CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
+ continue;
+ }
+
+ sum_sample_weight += sc->sample_weight;
+ }
+ }
+ else {
+ sum_sample_weight = 1.0f;
+ }
+# endif /* __DENOISING_FEATURES__ */
+
+ for (int i = branched_state->next_closure; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ if (!CLOSURE_IS_BSDF(sc->type))
+ continue;
+ /* transparency is not handled here, but in outer loop */
+ if (sc->type == CLOSURE_BSDF_TRANSPARENT_ID)
+ continue;
+
+ int num_samples;
+
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type))
+ num_samples = kernel_data.integrator.diffuse_samples;
+ else if (CLOSURE_IS_BSDF_BSSRDF(sc->type))
+ num_samples = 1;
+ else if (CLOSURE_IS_BSDF_GLOSSY(sc->type))
+ num_samples = kernel_data.integrator.glossy_samples;
+ else
+ num_samples = kernel_data.integrator.transmission_samples;
+
+ num_samples = ceil_to_int(num_samples_adjust * num_samples);
+
+ float num_samples_inv = num_samples_adjust / num_samples;
+
+ for (int j = branched_state->next_sample; j < num_samples; j++) {
+ if (reset_path_state) {
+ *ps = branched_state->path_state;
+ }
+
+ ps->rng_hash = cmj_hash(branched_state->path_state.rng_hash, i);
+
+ ccl_global float3 *tp = &kernel_split_state.throughput[ray_index];
+ *tp = throughput;
+
+ ccl_global Ray *bsdf_ray = &kernel_split_state.ray[ray_index];
+
+ if (!kernel_branched_path_surface_bounce(
+ kg, sd, sc, j, num_samples, tp, ps, &L->state, bsdf_ray, sum_sample_weight)) {
+ continue;
+ }
+
+ ps->rng_hash = branched_state->path_state.rng_hash;
+
+ /* update state for next iteration */
+ branched_state->next_closure = i;
+ branched_state->next_sample = j + 1;
+
+ /* start the indirect path */
+ *tp *= num_samples_inv;
+
+ if (kernel_split_branched_indirect_start_shared(kg, ray_index)) {
+ continue;
+ }
+
+ return true;
+ }
+
+ branched_state->next_sample = 0;
+ }
+
+ branched_state->next_closure = sd->num_closure;
+
+ if (wait_for_shared) {
+ branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0);
+ if (branched_state->waiting_on_shared_samples) {
+ return true;
+ }
+ }
+
+ return false;
}
-#endif /* __BRANCHED_PATH__ */
+#endif /* __BRANCHED_PATH__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_buffer_update.h b/intern/cycles/kernel/split/kernel_buffer_update.h
index 18eec6372f1..e77743350dc 100644
--- a/intern/cycles/kernel/split/kernel_buffer_update.h
+++ b/intern/cycles/kernel/split/kernel_buffer_update.h
@@ -41,132 +41,133 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_buffer_update(KernelGlobals *kg,
ccl_local_param unsigned int *local_queue_atomics)
{
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(ray_index == 0) {
- /* We will empty this queue in this kernel. */
- kernel_split_params.queue_index[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = 0;
- }
- char enqueue_flag = 0;
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ if (ray_index == 0) {
+ /* We will empty this queue in this kernel. */
+ kernel_split_params.queue_index[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = 0;
+ }
+ char enqueue_flag = 0;
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
#ifdef __COMPUTE_DEVICE_GPU__
- /* If we are executing on a GPU device, we exit all threads that are not
- * required.
- *
- * If we are executing on a CPU device, then we need to keep all threads
- * active since we have barrier() calls later in the kernel. CPU devices,
- * expect all threads to execute barrier statement.
- */
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
+ /* If we are executing on a GPU device, we exit all threads that are not
+ * required.
+ *
+ * If we are executing on a CPU device, then we need to keep all threads
+ * active since we have barrier() calls later in the kernel. CPU devices,
+ * expect all threads to execute barrier statement.
+ */
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
#endif
#ifndef __COMPUTE_DEVICE_GPU__
- if(ray_index != QUEUE_EMPTY_SLOT) {
+ if (ray_index != QUEUE_EMPTY_SLOT) {
#endif
- ccl_global char *ray_state = kernel_split_state.ray_state;
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- bool ray_was_updated = false;
-
- if(IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
- ray_was_updated = true;
- uint sample = state->sample;
- uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
- ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset;
-
- /* accumulate result in output buffer */
- kernel_write_result(kg, buffer, sample, L);
-
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_TO_REGENERATE);
- }
-
- if(kernel_data.film.cryptomatte_passes) {
- /* Make sure no thread is writing to the buffers. */
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
- if(ray_was_updated && state->sample - 1 == kernel_data.integrator.aa_samples) {
- uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
- ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset;
- ccl_global float *cryptomatte_buffer = buffer + kernel_data.film.pass_cryptomatte;
- kernel_sort_id_slots(cryptomatte_buffer, 2 * kernel_data.film.cryptomatte_depth);
- }
- }
-
- if(IS_STATE(ray_state, ray_index, RAY_TO_REGENERATE)) {
- /* We have completed current work; So get next work */
- ccl_global uint *work_pools = kernel_split_params.work_pools;
- uint total_work_size = kernel_split_params.total_work_size;
- uint work_index;
-
- if(!get_next_work(kg, work_pools, total_work_size, ray_index, &work_index)) {
- /* If work is invalid, this means no more work is available and the thread may exit */
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_INACTIVE);
- }
-
- if(IS_STATE(ray_state, ray_index, RAY_TO_REGENERATE)) {
- ccl_global WorkTile *tile = &kernel_split_params.tile;
- uint x, y, sample;
- get_work_pixel(tile, work_index, &x, &y, &sample);
-
- /* Store buffer offset for writing to passes. */
- uint buffer_offset = (tile->offset + x + y*tile->stride) * kernel_data.film.pass_stride;
- kernel_split_state.buffer_offset[ray_index] = buffer_offset;
-
- /* Initialize random numbers and ray. */
- uint rng_hash;
- kernel_path_trace_setup(kg, sample, x, y, &rng_hash, ray);
-
- if(ray->t != 0.0f) {
- /* Initialize throughput, path radiance, Ray, PathState;
- * These rays proceed with path-iteration.
- */
- *throughput = make_float3(1.0f, 1.0f, 1.0f);
- path_radiance_init(L, kernel_data.film.use_light_pass);
- path_state_init(kg,
- AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]),
- state,
- rng_hash,
- sample,
- ray);
+ ccl_global char *ray_state = kernel_split_state.ray_state;
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
+ bool ray_was_updated = false;
+
+ if (IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
+ ray_was_updated = true;
+ uint sample = state->sample;
+ uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
+ ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset;
+
+ /* accumulate result in output buffer */
+ kernel_write_result(kg, buffer, sample, L);
+
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_TO_REGENERATE);
+ }
+
+ if (kernel_data.film.cryptomatte_passes) {
+ /* Make sure no thread is writing to the buffers. */
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ if (ray_was_updated && state->sample - 1 == kernel_data.integrator.aa_samples) {
+ uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
+ ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset;
+ ccl_global float *cryptomatte_buffer = buffer + kernel_data.film.pass_cryptomatte;
+ kernel_sort_id_slots(cryptomatte_buffer, 2 * kernel_data.film.cryptomatte_depth);
+ }
+ }
+
+ if (IS_STATE(ray_state, ray_index, RAY_TO_REGENERATE)) {
+ /* We have completed current work; So get next work */
+ ccl_global uint *work_pools = kernel_split_params.work_pools;
+ uint total_work_size = kernel_split_params.total_work_size;
+ uint work_index;
+
+ if (!get_next_work(kg, work_pools, total_work_size, ray_index, &work_index)) {
+ /* If work is invalid, this means no more work is available and the thread may exit */
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_INACTIVE);
+ }
+
+ if (IS_STATE(ray_state, ray_index, RAY_TO_REGENERATE)) {
+ ccl_global WorkTile *tile = &kernel_split_params.tile;
+ uint x, y, sample;
+ get_work_pixel(tile, work_index, &x, &y, &sample);
+
+ /* Store buffer offset for writing to passes. */
+ uint buffer_offset = (tile->offset + x + y * tile->stride) * kernel_data.film.pass_stride;
+ kernel_split_state.buffer_offset[ray_index] = buffer_offset;
+
+ /* Initialize random numbers and ray. */
+ uint rng_hash;
+ kernel_path_trace_setup(kg, sample, x, y, &rng_hash, ray);
+
+ if (ray->t != 0.0f) {
+ /* Initialize throughput, path radiance, Ray, PathState;
+ * These rays proceed with path-iteration.
+ */
+ *throughput = make_float3(1.0f, 1.0f, 1.0f);
+ path_radiance_init(L, kernel_data.film.use_light_pass);
+ path_state_init(kg,
+ AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]),
+ state,
+ rng_hash,
+ sample,
+ ray);
#ifdef __SUBSURFACE__
- kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]);
+ kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]);
#endif
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- enqueue_flag = 1;
- }
- else {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_TO_REGENERATE);
- }
- }
- }
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ enqueue_flag = 1;
+ }
+ else {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_TO_REGENERATE);
+ }
+ }
+ }
#ifndef __COMPUTE_DEVICE_GPU__
- }
+ }
#endif
- /* Enqueue RAY_REGENERATED rays into QUEUE_ACTIVE_AND_REGENERATED_RAYS;
- * These rays will be made active during next SceneIntersectkernel.
- */
- enqueue_ray_index_local(ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- enqueue_flag,
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
+ /* Enqueue RAY_REGENERATED rays into QUEUE_ACTIVE_AND_REGENERATED_RAYS;
+ * These rays will be made active during next SceneIntersectkernel.
+ */
+ enqueue_ray_index_local(ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ enqueue_flag,
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_data_init.h b/intern/cycles/kernel/split/kernel_data_init.h
index 77fb61b80a8..52930843f56 100644
--- a/intern/cycles/kernel/split/kernel_data_init.h
+++ b/intern/cycles/kernel/split/kernel_data_init.h
@@ -28,82 +28,88 @@ ccl_device void kernel_data_init(
#else
void KERNEL_FUNCTION_FULL_NAME(data_init)(
#endif
- KernelGlobals *kg,
- ccl_constant KernelData *data,
- ccl_global void *split_data_buffer,
- int num_elements,
- ccl_global char *ray_state,
+ KernelGlobals *kg,
+ ccl_constant KernelData *data,
+ ccl_global void *split_data_buffer,
+ int num_elements,
+ ccl_global char *ray_state,
#ifdef __KERNEL_OPENCL__
- KERNEL_BUFFER_PARAMS,
+ KERNEL_BUFFER_PARAMS,
#endif
- int start_sample,
- int end_sample,
- int sx, int sy, int sw, int sh, int offset, int stride,
- ccl_global int *Queue_index, /* Tracks the number of elements in queues */
- int queuesize, /* size (capacity) of the queue */
- ccl_global char *use_queues_flag, /* flag to decide if scene-intersect kernel should use queues to fetch ray index */
- ccl_global unsigned int *work_pools, /* Work pool for each work group */
- unsigned int num_samples,
- ccl_global float *buffer)
+ int start_sample,
+ int end_sample,
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ int offset,
+ int stride,
+ ccl_global int *Queue_index, /* Tracks the number of elements in queues */
+ int queuesize, /* size (capacity) of the queue */
+ ccl_global char *
+ use_queues_flag, /* flag to decide if scene-intersect kernel should use queues to fetch ray index */
+ ccl_global unsigned int *work_pools, /* Work pool for each work group */
+ unsigned int num_samples,
+ ccl_global float *buffer)
{
#ifdef KERNEL_STUB
- STUB_ASSERT(KERNEL_ARCH, data_init);
+ STUB_ASSERT(KERNEL_ARCH, data_init);
#else
-#ifdef __KERNEL_OPENCL__
- kg->data = data;
-#endif
+# ifdef __KERNEL_OPENCL__
+ kg->data = data;
+# endif
- kernel_split_params.tile.x = sx;
- kernel_split_params.tile.y = sy;
- kernel_split_params.tile.w = sw;
- kernel_split_params.tile.h = sh;
+ kernel_split_params.tile.x = sx;
+ kernel_split_params.tile.y = sy;
+ kernel_split_params.tile.w = sw;
+ kernel_split_params.tile.h = sh;
- kernel_split_params.tile.start_sample = start_sample;
- kernel_split_params.tile.num_samples = num_samples;
+ kernel_split_params.tile.start_sample = start_sample;
+ kernel_split_params.tile.num_samples = num_samples;
- kernel_split_params.tile.offset = offset;
- kernel_split_params.tile.stride = stride;
+ kernel_split_params.tile.offset = offset;
+ kernel_split_params.tile.stride = stride;
- kernel_split_params.tile.buffer = buffer;
+ kernel_split_params.tile.buffer = buffer;
- kernel_split_params.total_work_size = sw * sh * num_samples;
+ kernel_split_params.total_work_size = sw * sh * num_samples;
- kernel_split_params.work_pools = work_pools;
+ kernel_split_params.work_pools = work_pools;
- kernel_split_params.queue_index = Queue_index;
- kernel_split_params.queue_size = queuesize;
- kernel_split_params.use_queues_flag = use_queues_flag;
+ kernel_split_params.queue_index = Queue_index;
+ kernel_split_params.queue_size = queuesize;
+ kernel_split_params.use_queues_flag = use_queues_flag;
- split_data_init(kg, &kernel_split_state, num_elements, split_data_buffer, ray_state);
+ split_data_init(kg, &kernel_split_state, num_elements, split_data_buffer, ray_state);
-#ifdef __KERNEL_OPENCL__
- kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
- kernel_set_buffer_info(kg);
-#endif
+# ifdef __KERNEL_OPENCL__
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
+ kernel_set_buffer_info(kg);
+# endif
+
+ int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+
+ /* Initialize queue data and queue index. */
+ if (thread_index < queuesize) {
+ for (int i = 0; i < NUM_QUEUES; i++) {
+ kernel_split_state.queue_data[i * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
+ }
+ }
+
+ if (thread_index == 0) {
+ for (int i = 0; i < NUM_QUEUES; i++) {
+ Queue_index[i] = 0;
+ }
- int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
-
- /* Initialize queue data and queue index. */
- if(thread_index < queuesize) {
- for(int i = 0; i < NUM_QUEUES; i++) {
- kernel_split_state.queue_data[i * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
- }
- }
-
- if(thread_index == 0) {
- for(int i = 0; i < NUM_QUEUES; i++) {
- Queue_index[i] = 0;
- }
-
- /* The scene-intersect kernel should not use the queues very first time.
- * since the queue would be empty.
- */
- *use_queues_flag = 0;
- }
-#endif /* KERENL_STUB */
+ /* The scene-intersect kernel should not use the queues very first time.
+ * since the queue would be empty.
+ */
+ *use_queues_flag = 0;
+ }
+#endif /* KERENL_STUB */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_direct_lighting.h b/intern/cycles/kernel/split/kernel_direct_lighting.h
index ca79602c565..b2ca59d60cc 100644
--- a/intern/cycles/kernel/split/kernel_direct_lighting.h
+++ b/intern/cycles/kernel/split/kernel_direct_lighting.h
@@ -43,116 +43,111 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_direct_lighting(KernelGlobals *kg,
ccl_local_param unsigned int *local_queue_atomics)
{
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- char enqueue_flag = 0;
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
-
- if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
-
- /* direct lighting */
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ char enqueue_flag = 0;
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
+
+ if (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+
+ /* direct lighting */
#ifdef __EMISSION__
- bool flag = (kernel_data.integrator.use_direct_light &&
- (sd->flag & SD_BSDF_HAS_EVAL));
+ bool flag = (kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL));
# ifdef __BRANCHED_PATH__
- if(flag && kernel_data.integrator.branched) {
- flag = false;
- enqueue_flag = 1;
- }
-# endif /* __BRANCHED_PATH__ */
+ if (flag && kernel_data.integrator.branched) {
+ flag = false;
+ enqueue_flag = 1;
+ }
+# endif /* __BRANCHED_PATH__ */
# ifdef __SHADOW_TRICKS__
- if(flag && state->flag & PATH_RAY_SHADOW_CATCHER) {
- flag = false;
- enqueue_flag = 1;
- }
-# endif /* __SHADOW_TRICKS__ */
-
- if(flag) {
- /* Sample illumination from lights to find path contribution. */
- float light_u, light_v;
- path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
- float terminate = path_state_rng_light_termination(kg, state);
-
- LightSample ls;
- if(light_sample(kg,
- light_u, light_v,
- sd->time,
- sd->P,
- state->bounce,
- &ls)) {
-
- Ray light_ray;
- light_ray.time = sd->time;
-
- BsdfEval L_light;
- bool is_lamp;
- if(direct_emission(kg,
- sd,
- AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]),
- &ls,
- state,
- &light_ray,
- &L_light,
- &is_lamp,
- terminate))
- {
- /* Write intermediate data to global memory to access from
- * the next kernel.
- */
- kernel_split_state.light_ray[ray_index] = light_ray;
- kernel_split_state.bsdf_eval[ray_index] = L_light;
- kernel_split_state.is_lamp[ray_index] = is_lamp;
- /* Mark ray state for next shadow kernel. */
- enqueue_flag = 1;
- }
- }
- }
-#endif /* __EMISSION__ */
- }
+ if (flag && state->flag & PATH_RAY_SHADOW_CATCHER) {
+ flag = false;
+ enqueue_flag = 1;
+ }
+# endif /* __SHADOW_TRICKS__ */
+
+ if (flag) {
+ /* Sample illumination from lights to find path contribution. */
+ float light_u, light_v;
+ path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
+ float terminate = path_state_rng_light_termination(kg, state);
+
+ LightSample ls;
+ if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
+
+ Ray light_ray;
+ light_ray.time = sd->time;
+
+ BsdfEval L_light;
+ bool is_lamp;
+ if (direct_emission(kg,
+ sd,
+ AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]),
+ &ls,
+ state,
+ &light_ray,
+ &L_light,
+ &is_lamp,
+ terminate)) {
+ /* Write intermediate data to global memory to access from
+ * the next kernel.
+ */
+ kernel_split_state.light_ray[ray_index] = light_ray;
+ kernel_split_state.bsdf_eval[ray_index] = L_light;
+ kernel_split_state.is_lamp[ray_index] = is_lamp;
+ /* Mark ray state for next shadow kernel. */
+ enqueue_flag = 1;
+ }
+ }
+ }
+#endif /* __EMISSION__ */
+ }
#ifdef __EMISSION__
- /* Enqueue RAY_SHADOW_RAY_CAST_DL rays. */
- enqueue_ray_index_local(ray_index,
- QUEUE_SHADOW_RAY_CAST_DL_RAYS,
- enqueue_flag,
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
+ /* Enqueue RAY_SHADOW_RAY_CAST_DL rays. */
+ enqueue_ray_index_local(ray_index,
+ QUEUE_SHADOW_RAY_CAST_DL_RAYS,
+ enqueue_flag,
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
#endif
#ifdef __BRANCHED_PATH__
- /* Enqueue RAY_LIGHT_INDIRECT_NEXT_ITER rays
- * this is the last kernel before next_iteration_setup that uses local atomics so we do this here
- */
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- enqueue_ray_index_local(ray_index,
- QUEUE_LIGHT_INDIRECT_ITER,
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_LIGHT_INDIRECT_NEXT_ITER),
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
-
-#endif /* __BRANCHED_PATH__ */
+ /* Enqueue RAY_LIGHT_INDIRECT_NEXT_ITER rays
+ * this is the last kernel before next_iteration_setup that uses local atomics so we do this here
+ */
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ enqueue_ray_index_local(
+ ray_index,
+ QUEUE_LIGHT_INDIRECT_ITER,
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_LIGHT_INDIRECT_NEXT_ITER),
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
+
+#endif /* __BRANCHED_PATH__ */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_do_volume.h b/intern/cycles/kernel/split/kernel_do_volume.h
index fb5bd3d48dd..45b839db05f 100644
--- a/intern/cycles/kernel/split/kernel_do_volume.h
+++ b/intern/cycles/kernel/split/kernel_do_volume.h
@@ -18,203 +18,210 @@ CCL_NAMESPACE_BEGIN
#if defined(__BRANCHED_PATH__) && defined(__VOLUME__)
-ccl_device_inline void kernel_split_branched_path_volume_indirect_light_init(KernelGlobals *kg, int ray_index)
+ccl_device_inline void kernel_split_branched_path_volume_indirect_light_init(KernelGlobals *kg,
+ int ray_index)
{
- kernel_split_branched_path_indirect_loop_init(kg, ray_index);
+ kernel_split_branched_path_indirect_loop_init(kg, ray_index);
- ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_VOLUME_INDIRECT);
+ ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_VOLUME_INDIRECT);
}
-ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(KernelGlobals *kg, int ray_index)
+ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(KernelGlobals *kg,
+ int ray_index)
{
- SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
+ SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
- /* GPU: no decoupled ray marching, scatter probalistically */
- int num_samples = kernel_data.integrator.volume_samples;
- float num_samples_inv = 1.0f/num_samples;
+ /* GPU: no decoupled ray marching, scatter probalistically */
+ int num_samples = kernel_data.integrator.volume_samples;
+ float num_samples_inv = 1.0f / num_samples;
- Ray volume_ray = branched_state->ray;
- volume_ray.t = (!IS_STATE(&branched_state->ray_state, 0, RAY_HIT_BACKGROUND)) ? branched_state->isect.t : FLT_MAX;
+ Ray volume_ray = branched_state->ray;
+ volume_ray.t = (!IS_STATE(&branched_state->ray_state, 0, RAY_HIT_BACKGROUND)) ?
+ branched_state->isect.t :
+ FLT_MAX;
- bool heterogeneous = volume_stack_is_heterogeneous(kg, branched_state->path_state.volume_stack);
+ bool heterogeneous = volume_stack_is_heterogeneous(kg, branched_state->path_state.volume_stack);
- for(int j = branched_state->next_sample; j < num_samples; j++) {
- ccl_global PathState *ps = &kernel_split_state.path_state[ray_index];
- *ps = branched_state->path_state;
+ for (int j = branched_state->next_sample; j < num_samples; j++) {
+ ccl_global PathState *ps = &kernel_split_state.path_state[ray_index];
+ *ps = branched_state->path_state;
- ccl_global Ray *pray = &kernel_split_state.ray[ray_index];
- *pray = branched_state->ray;
+ ccl_global Ray *pray = &kernel_split_state.ray[ray_index];
+ *pray = branched_state->ray;
- ccl_global float3 *tp = &kernel_split_state.throughput[ray_index];
- *tp = branched_state->throughput * num_samples_inv;
+ ccl_global float3 *tp = &kernel_split_state.throughput[ray_index];
+ *tp = branched_state->throughput * num_samples_inv;
- /* branch RNG state */
- path_state_branch(ps, j, num_samples);
+ /* branch RNG state */
+ path_state_branch(ps, j, num_samples);
- /* integrate along volume segment with distance sampling */
- VolumeIntegrateResult result = kernel_volume_integrate(
- kg, ps, sd, &volume_ray, L, tp, heterogeneous);
+ /* integrate along volume segment with distance sampling */
+ VolumeIntegrateResult result = kernel_volume_integrate(
+ kg, ps, sd, &volume_ray, L, tp, heterogeneous);
# ifdef __VOLUME_SCATTER__
- if(result == VOLUME_PATH_SCATTERED) {
- /* direct lighting */
- kernel_path_volume_connect_light(kg, sd, emission_sd, *tp, &branched_state->path_state, L);
-
- /* indirect light bounce */
- if(!kernel_path_volume_bounce(kg, sd, tp, ps, &L->state, pray)) {
- continue;
- }
-
- /* start the indirect path */
- branched_state->next_closure = 0;
- branched_state->next_sample = j+1;
-
- /* Attempting to share too many samples is slow for volumes as it causes us to
- * loop here more and have many calls to kernel_volume_integrate which evaluates
- * shaders. The many expensive shader evaluations cause the work load to become
- * unbalanced and many threads to become idle in this kernel. Limiting the
- * number of shared samples here helps quite a lot.
- */
- if(branched_state->shared_sample_count < 2) {
- if(kernel_split_branched_indirect_start_shared(kg, ray_index)) {
- continue;
- }
- }
-
- return true;
- }
+ if (result == VOLUME_PATH_SCATTERED) {
+ /* direct lighting */
+ kernel_path_volume_connect_light(kg, sd, emission_sd, *tp, &branched_state->path_state, L);
+
+ /* indirect light bounce */
+ if (!kernel_path_volume_bounce(kg, sd, tp, ps, &L->state, pray)) {
+ continue;
+ }
+
+ /* start the indirect path */
+ branched_state->next_closure = 0;
+ branched_state->next_sample = j + 1;
+
+ /* Attempting to share too many samples is slow for volumes as it causes us to
+ * loop here more and have many calls to kernel_volume_integrate which evaluates
+ * shaders. The many expensive shader evaluations cause the work load to become
+ * unbalanced and many threads to become idle in this kernel. Limiting the
+ * number of shared samples here helps quite a lot.
+ */
+ if (branched_state->shared_sample_count < 2) {
+ if (kernel_split_branched_indirect_start_shared(kg, ray_index)) {
+ continue;
+ }
+ }
+
+ return true;
+ }
# endif
- }
+ }
- branched_state->next_sample = num_samples;
+ branched_state->next_sample = num_samples;
- branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0);
- if(branched_state->waiting_on_shared_samples) {
- return true;
- }
+ branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0);
+ if (branched_state->waiting_on_shared_samples) {
+ return true;
+ }
- kernel_split_branched_path_indirect_loop_end(kg, ray_index);
+ kernel_split_branched_path_indirect_loop_end(kg, ray_index);
- /* todo: avoid this calculation using decoupled ray marching */
- float3 throughput = kernel_split_state.throughput[ray_index];
- kernel_volume_shadow(kg, emission_sd, &kernel_split_state.path_state[ray_index], &volume_ray, &throughput);
- kernel_split_state.throughput[ray_index] = throughput;
+ /* todo: avoid this calculation using decoupled ray marching */
+ float3 throughput = kernel_split_state.throughput[ray_index];
+ kernel_volume_shadow(
+ kg, emission_sd, &kernel_split_state.path_state[ray_index], &volume_ray, &throughput);
+ kernel_split_state.throughput[ray_index] = throughput;
- return false;
+ return false;
}
-#endif /* __BRANCHED_PATH__ && __VOLUME__ */
+#endif /* __BRANCHED_PATH__ && __VOLUME__ */
ccl_device void kernel_do_volume(KernelGlobals *kg)
{
#ifdef __VOLUME__
- /* We will empty this queue in this kernel. */
- if(ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
- kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
+ /* We will empty this queue in this kernel. */
+ if (ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
+ kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
# ifdef __BRANCHED_PATH__
- kernel_split_params.queue_index[QUEUE_VOLUME_INDIRECT_ITER] = 0;
-# endif /* __BRANCHED_PATH__ */
- }
-
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
-
- if(*kernel_split_params.use_queues_flag) {
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
- }
-
- ccl_global char *ray_state = kernel_split_state.ray_state;
-
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
-
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE) ||
- IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
- ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- ccl_global Intersection *isect = &kernel_split_state.isect[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
- ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
-
- bool hit = ! IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND);
-
- /* Sanitize volume stack. */
- if(!hit) {
- kernel_volume_clean_stack(kg, state->volume_stack);
- }
- /* volume attenuation, emission, scatter */
- if(state->volume_stack[0].shader != SHADER_NONE) {
- Ray volume_ray = *ray;
- volume_ray.t = (hit)? isect->t: FLT_MAX;
+ kernel_split_params.queue_index[QUEUE_VOLUME_INDIRECT_ITER] = 0;
+# endif /* __BRANCHED_PATH__ */
+ }
+
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+
+ if (*kernel_split_params.use_queues_flag) {
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+ }
+
+ ccl_global char *ray_state = kernel_split_state.ray_state;
+
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE) ||
+ IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
+ ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ccl_global Intersection *isect = &kernel_split_state.isect[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+ ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
+
+ bool hit = !IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND);
+
+ /* Sanitize volume stack. */
+ if (!hit) {
+ kernel_volume_clean_stack(kg, state->volume_stack);
+ }
+ /* volume attenuation, emission, scatter */
+ if (state->volume_stack[0].shader != SHADER_NONE) {
+ Ray volume_ray = *ray;
+ volume_ray.t = (hit) ? isect->t : FLT_MAX;
# ifdef __BRANCHED_PATH__
- if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
-# endif /* __BRANCHED_PATH__ */
- bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
+ if (!kernel_data.integrator.branched ||
+ IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
+# endif /* __BRANCHED_PATH__ */
+ bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
- {
- /* integrate along volume segment with distance sampling */
- VolumeIntegrateResult result = kernel_volume_integrate(
- kg, state, sd, &volume_ray, L, throughput, heterogeneous);
+ {
+ /* integrate along volume segment with distance sampling */
+ VolumeIntegrateResult result = kernel_volume_integrate(
+ kg, state, sd, &volume_ray, L, throughput, heterogeneous);
# ifdef __VOLUME_SCATTER__
- if(result == VOLUME_PATH_SCATTERED) {
- /* direct lighting */
- kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
-
- /* indirect light bounce */
- if(kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- else {
- kernel_split_path_end(kg, ray_index);
- }
- }
-# endif /* __VOLUME_SCATTER__ */
- }
+ if (result == VOLUME_PATH_SCATTERED) {
+ /* direct lighting */
+ kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
+
+ /* indirect light bounce */
+ if (kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ else {
+ kernel_split_path_end(kg, ray_index);
+ }
+ }
+# endif /* __VOLUME_SCATTER__ */
+ }
# ifdef __BRANCHED_PATH__
- }
- else {
- kernel_split_branched_path_volume_indirect_light_init(kg, ray_index);
-
- if(kernel_split_branched_path_volume_indirect_light_iter(kg, ray_index)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- }
-# endif /* __BRANCHED_PATH__ */
- }
- }
+ }
+ else {
+ kernel_split_branched_path_volume_indirect_light_init(kg, ray_index);
+
+ if (kernel_split_branched_path_volume_indirect_light_iter(kg, ray_index)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ }
+# endif /* __BRANCHED_PATH__ */
+ }
+ }
# ifdef __BRANCHED_PATH__
- /* iter loop */
- ray_index = get_ray_index(kg, ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0),
- QUEUE_VOLUME_INDIRECT_ITER,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
-
- if(IS_STATE(ray_state, ray_index, RAY_VOLUME_INDIRECT_NEXT_ITER)) {
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- path_radiance_sum_indirect(&kernel_split_state.path_radiance[ray_index]);
- path_radiance_reset_indirect(&kernel_split_state.path_radiance[ray_index]);
-
- if(kernel_split_branched_path_volume_indirect_light_iter(kg, ray_index)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- }
-# endif /* __BRANCHED_PATH__ */
-
-#endif /* __VOLUME__ */
+ /* iter loop */
+ ray_index = get_ray_index(kg,
+ ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0),
+ QUEUE_VOLUME_INDIRECT_ITER,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+
+ if (IS_STATE(ray_state, ray_index, RAY_VOLUME_INDIRECT_NEXT_ITER)) {
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(&kernel_split_state.path_radiance[ray_index]);
+ path_radiance_reset_indirect(&kernel_split_state.path_radiance[ray_index]);
+
+ if (kernel_split_branched_path_volume_indirect_light_iter(kg, ray_index)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ }
+# endif /* __BRANCHED_PATH__ */
+
+#endif /* __VOLUME__ */
}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_enqueue_inactive.h b/intern/cycles/kernel/split/kernel_enqueue_inactive.h
index 496355bbc3a..31d2daef616 100644
--- a/intern/cycles/kernel/split/kernel_enqueue_inactive.h
+++ b/intern/cycles/kernel/split/kernel_enqueue_inactive.h
@@ -20,27 +20,27 @@ ccl_device void kernel_enqueue_inactive(KernelGlobals *kg,
ccl_local_param unsigned int *local_queue_atomics)
{
#ifdef __BRANCHED_PATH__
- /* Enqeueue RAY_INACTIVE rays into QUEUE_INACTIVE_RAYS queue. */
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ /* Enqeueue RAY_INACTIVE rays into QUEUE_INACTIVE_RAYS queue. */
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- char enqueue_flag = 0;
- if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_INACTIVE)) {
- enqueue_flag = 1;
- }
+ char enqueue_flag = 0;
+ if (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_INACTIVE)) {
+ enqueue_flag = 1;
+ }
- enqueue_ray_index_local(ray_index,
- QUEUE_INACTIVE_RAYS,
- enqueue_flag,
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
-#endif /* __BRANCHED_PATH__ */
+ enqueue_ray_index_local(ray_index,
+ QUEUE_INACTIVE_RAYS,
+ enqueue_flag,
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
+#endif /* __BRANCHED_PATH__ */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
index f14eecec2f2..63bc5a8e0ce 100644
--- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
+++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
@@ -54,120 +54,112 @@ CCL_NAMESPACE_BEGIN
*/
ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
- KernelGlobals *kg,
- ccl_local_param BackgroundAOLocals *locals)
+ KernelGlobals *kg, ccl_local_param BackgroundAOLocals *locals)
{
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- locals->queue_atomics_bg = 0;
- locals->queue_atomics_ao = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ locals->queue_atomics_bg = 0;
+ locals->queue_atomics_ao = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
#ifdef __AO__
- char enqueue_flag = 0;
+ char enqueue_flag = 0;
#endif
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
#ifdef __COMPUTE_DEVICE_GPU__
- /* If we are executing on a GPU device, we exit all threads that are not
- * required.
- *
- * If we are executing on a CPU device, then we need to keep all threads
- * active since we have barrier() calls later in the kernel. CPU devices,
- * expect all threads to execute barrier statement.
- */
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
-#endif /* __COMPUTE_DEVICE_GPU__ */
+ /* If we are executing on a GPU device, we exit all threads that are not
+ * required.
+ *
+ * If we are executing on a CPU device, then we need to keep all threads
+ * active since we have barrier() calls later in the kernel. CPU devices,
+ * expect all threads to execute barrier statement.
+ */
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
+#endif /* __COMPUTE_DEVICE_GPU__ */
#ifndef __COMPUTE_DEVICE_GPU__
- if(ray_index != QUEUE_EMPTY_SLOT) {
+ if (ray_index != QUEUE_EMPTY_SLOT) {
#endif
- ccl_global PathState *state = 0x0;
- float3 throughput;
-
- ccl_global char *ray_state = kernel_split_state.ray_state;
- ShaderData *sd = kernel_split_sd(sd, ray_index);
-
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
- ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset;
-
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
-
- throughput = kernel_split_state.throughput[ray_index];
- state = &kernel_split_state.path_state[ray_index];
-
- if(!kernel_path_shader_apply(kg,
- sd,
- state,
- ray,
- throughput,
- emission_sd,
- L,
- buffer))
- {
- kernel_split_path_end(kg, ray_index);
- }
- }
-
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- /* Path termination. this is a strange place to put the termination, it's
- * mainly due to the mixed in MIS that we use. gives too many unneeded
- * shader evaluations, only need emission if we are going to terminate.
- */
- float probability = path_state_continuation_probability(kg, state, throughput);
-
- if(probability == 0.0f) {
- kernel_split_path_end(kg, ray_index);
- }
- else if(probability < 1.0f) {
- float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
- if(terminate >= probability) {
- kernel_split_path_end(kg, ray_index);
- }
- else {
- kernel_split_state.throughput[ray_index] = throughput/probability;
- }
- }
-
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- kernel_update_denoising_features(kg, sd, state, L);
- }
- }
+ ccl_global PathState *state = 0x0;
+ float3 throughput;
+
+ ccl_global char *ray_state = kernel_split_state.ray_state;
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
+ uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
+ ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset;
+
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+
+ throughput = kernel_split_state.throughput[ray_index];
+ state = &kernel_split_state.path_state[ray_index];
+
+ if (!kernel_path_shader_apply(kg, sd, state, ray, throughput, emission_sd, L, buffer)) {
+ kernel_split_path_end(kg, ray_index);
+ }
+ }
+
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
+ /* Path termination. this is a strange place to put the termination, it's
+ * mainly due to the mixed in MIS that we use. gives too many unneeded
+ * shader evaluations, only need emission if we are going to terminate.
+ */
+ float probability = path_state_continuation_probability(kg, state, throughput);
+
+ if (probability == 0.0f) {
+ kernel_split_path_end(kg, ray_index);
+ }
+ else if (probability < 1.0f) {
+ float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
+ if (terminate >= probability) {
+ kernel_split_path_end(kg, ray_index);
+ }
+ else {
+ kernel_split_state.throughput[ray_index] = throughput / probability;
+ }
+ }
+
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ kernel_update_denoising_features(kg, sd, state, L);
+ }
+ }
#ifdef __AO__
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- /* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion) {
- enqueue_flag = 1;
- }
- }
-#endif /* __AO__ */
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
+ /* ambient occlusion */
+ if (kernel_data.integrator.use_ambient_occlusion) {
+ enqueue_flag = 1;
+ }
+ }
+#endif /* __AO__ */
#ifndef __COMPUTE_DEVICE_GPU__
- }
+ }
#endif
#ifdef __AO__
- /* Enqueue to-shadow-ray-cast rays. */
- enqueue_ray_index_local(ray_index,
- QUEUE_SHADOW_RAY_CAST_AO_RAYS,
- enqueue_flag,
- kernel_split_params.queue_size,
- &locals->queue_atomics_ao,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
+ /* Enqueue to-shadow-ray-cast rays. */
+ enqueue_ray_index_local(ray_index,
+ QUEUE_SHADOW_RAY_CAST_AO_RAYS,
+ enqueue_flag,
+ kernel_split_params.queue_size,
+ &locals->queue_atomics_ao,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
#endif
}
diff --git a/intern/cycles/kernel/split/kernel_indirect_background.h b/intern/cycles/kernel/split/kernel_indirect_background.h
index 4cf88a02590..b1c65f61e2c 100644
--- a/intern/cycles/kernel/split/kernel_indirect_background.h
+++ b/intern/cycles/kernel/split/kernel_indirect_background.h
@@ -18,48 +18,50 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_indirect_background(KernelGlobals *kg)
{
- ccl_global char *ray_state = kernel_split_state.ray_state;
+ ccl_global char *ray_state = kernel_split_state.ray_state;
- int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- int ray_index;
+ int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ int ray_index;
- if(kernel_data.integrator.ao_bounces != INT_MAX) {
- ray_index = get_ray_index(kg, thread_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
+ if (kernel_data.integrator.ao_bounces != INT_MAX) {
+ ray_index = get_ray_index(kg,
+ thread_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
- if(ray_index != QUEUE_EMPTY_SLOT) {
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- if(path_state_ao_bounce(kg, state)) {
- kernel_split_path_end(kg, ray_index);
- }
- }
- }
- }
+ if (ray_index != QUEUE_EMPTY_SLOT) {
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ if (path_state_ao_bounce(kg, state)) {
+ kernel_split_path_end(kg, ray_index);
+ }
+ }
+ }
+ }
- ray_index = get_ray_index(kg, thread_index,
- QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
+ ray_index = get_ray_index(kg,
+ thread_index,
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
- if(IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- float3 throughput = kernel_split_state.throughput[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
+ if (IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ float3 throughput = kernel_split_state.throughput[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
- kernel_path_background(kg, state, ray, throughput, sd, L);
- kernel_split_path_end(kg, ray_index);
- }
+ kernel_path_background(kg, state, ray, throughput, sd, L);
+ kernel_split_path_end(kg, ray_index);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_indirect_subsurface.h b/intern/cycles/kernel/split/kernel_indirect_subsurface.h
index 236c94e983c..3f48f8d6f56 100644
--- a/intern/cycles/kernel/split/kernel_indirect_subsurface.h
+++ b/intern/cycles/kernel/split/kernel_indirect_subsurface.h
@@ -18,53 +18,50 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_indirect_subsurface(KernelGlobals *kg)
{
- int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(thread_index == 0) {
- /* We will empty both queues in this kernel. */
- kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
- kernel_split_params.queue_index[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = 0;
- }
+ int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ if (thread_index == 0) {
+ /* We will empty both queues in this kernel. */
+ kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
+ kernel_split_params.queue_index[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = 0;
+ }
- int ray_index;
- get_ray_index(kg, thread_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
- ray_index = get_ray_index(kg, thread_index,
- QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
+ int ray_index;
+ get_ray_index(kg,
+ thread_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+ ray_index = get_ray_index(kg,
+ thread_index,
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
#ifdef __SUBSURFACE__
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
- ccl_global char *ray_state = kernel_split_state.ray_state;
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
+ ccl_global char *ray_state = kernel_split_state.ray_state;
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- if(IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
- ccl_addr_space SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
+ if (IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
+ ccl_addr_space SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
- /* Trace indirect subsurface rays by restarting the loop. this uses less
- * stack memory than invoking kernel_path_indirect.
- */
- if(ss_indirect->num_rays) {
- kernel_path_subsurface_setup_indirect(kg,
- ss_indirect,
- state,
- ray,
- L,
- throughput);
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- }
-#endif /* __SUBSURFACE__ */
+ /* Trace indirect subsurface rays by restarting the loop. this uses less
+ * stack memory than invoking kernel_path_indirect.
+ */
+ if (ss_indirect->num_rays) {
+ kernel_path_subsurface_setup_indirect(kg, ss_indirect, state, ray, L, throughput);
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ }
+#endif /* __SUBSURFACE__ */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_lamp_emission.h b/intern/cycles/kernel/split/kernel_lamp_emission.h
index 5b2c554b922..7ecb099208d 100644
--- a/intern/cycles/kernel/split/kernel_lamp_emission.h
+++ b/intern/cycles/kernel/split/kernel_lamp_emission.h
@@ -23,45 +23,45 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_lamp_emission(KernelGlobals *kg)
{
#ifndef __VOLUME__
- /* We will empty this queue in this kernel. */
- if(ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
- kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
- }
+ /* We will empty this queue in this kernel. */
+ if (ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
+ kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
+ }
#endif
- /* Fetch use_queues_flag. */
- char local_use_queues_flag = *kernel_split_params.use_queues_flag;
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ /* Fetch use_queues_flag. */
+ char local_use_queues_flag = *kernel_split_params.use_queues_flag;
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(local_use_queues_flag) {
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ if (local_use_queues_flag) {
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
#ifndef __VOLUME__
- 1
+ 1
#else
- 0
+ 0
#endif
- );
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
- }
+ );
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
+ }
- if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) ||
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND))
- {
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ if (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) ||
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND)) {
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- float3 throughput = kernel_split_state.throughput[ray_index];
- Ray ray = kernel_split_state.ray[ray_index];
- ccl_global Intersection *isect = &kernel_split_state.isect[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
+ float3 throughput = kernel_split_state.throughput[ray_index];
+ Ray ray = kernel_split_state.ray[ray_index];
+ ccl_global Intersection *isect = &kernel_split_state.isect[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
- kernel_path_lamp_emission(kg, state, &ray, throughput, isect, sd, L);
- }
+ kernel_path_lamp_emission(kg, state, &ray, throughput, isect, sd, L);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_next_iteration_setup.h b/intern/cycles/kernel/split/kernel_next_iteration_setup.h
index e388955f1af..781ce869374 100644
--- a/intern/cycles/kernel/split/kernel_next_iteration_setup.h
+++ b/intern/cycles/kernel/split/kernel_next_iteration_setup.h
@@ -48,217 +48,211 @@ CCL_NAMESPACE_BEGIN
#ifdef __BRANCHED_PATH__
ccl_device_inline void kernel_split_branched_indirect_light_init(KernelGlobals *kg, int ray_index)
{
- kernel_split_branched_path_indirect_loop_init(kg, ray_index);
+ kernel_split_branched_path_indirect_loop_init(kg, ray_index);
- ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT);
+ ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT);
}
ccl_device void kernel_split_branched_transparent_bounce(KernelGlobals *kg, int ray_index)
{
- ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
# ifdef __VOLUME__
- if(!(sd->flag & SD_HAS_ONLY_VOLUME)) {
+ if (!(sd->flag & SD_HAS_ONLY_VOLUME)) {
# endif
- /* continue in case of transparency */
- *throughput *= shader_bsdf_transparency(kg, sd);
+ /* continue in case of transparency */
+ *throughput *= shader_bsdf_transparency(kg, sd);
- if(is_zero(*throughput)) {
- kernel_split_path_end(kg, ray_index);
- return;
- }
+ if (is_zero(*throughput)) {
+ kernel_split_path_end(kg, ray_index);
+ return;
+ }
- /* Update Path State */
- path_state_next(kg, state, LABEL_TRANSPARENT);
+ /* Update Path State */
+ path_state_next(kg, state, LABEL_TRANSPARENT);
# ifdef __VOLUME__
- }
- else {
- if(!path_state_volume_next(kg, state)) {
- kernel_split_path_end(kg, ray_index);
- return;
- }
- }
+ }
+ else {
+ if (!path_state_volume_next(kg, state)) {
+ kernel_split_path_end(kg, ray_index);
+ return;
+ }
+ }
# endif
- ray->P = ray_offset(sd->P, -sd->Ng);
- ray->t -= sd->ray_length; /* clipping works through transparent */
+ ray->P = ray_offset(sd->P, -sd->Ng);
+ ray->t -= sd->ray_length; /* clipping works through transparent */
# ifdef __RAY_DIFFERENTIALS__
- ray->dP = sd->dP;
- ray->dD.dx = -sd->dI.dx;
- ray->dD.dy = -sd->dI.dy;
-# endif /* __RAY_DIFFERENTIALS__ */
+ ray->dP = sd->dP;
+ ray->dD.dx = -sd->dI.dx;
+ ray->dD.dy = -sd->dI.dy;
+# endif /* __RAY_DIFFERENTIALS__ */
# ifdef __VOLUME__
- /* enter/exit volume */
- kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
-# endif /* __VOLUME__ */
+ /* enter/exit volume */
+ kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
+# endif /* __VOLUME__ */
}
-#endif /* __BRANCHED_PATH__ */
+#endif /* __BRANCHED_PATH__ */
ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
ccl_local_param unsigned int *local_queue_atomics)
{
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- if(ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
- /* If we are here, then it means that scene-intersect kernel
- * has already been executed atleast once. From the next time,
- * scene-intersect kernel may operate on queues to fetch ray index
- */
- *kernel_split_params.use_queues_flag = 1;
-
- /* Mark queue indices of QUEUE_SHADOW_RAY_CAST_AO_RAYS and
- * QUEUE_SHADOW_RAY_CAST_DL_RAYS queues that were made empty during the
- * previous kernel.
- */
- kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_AO_RAYS] = 0;
- kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_DL_RAYS] = 0;
- }
-
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
-
- ccl_global char *ray_state = kernel_split_state.ray_state;
-
-# ifdef __VOLUME__
- /* Reactivate only volume rays here, most surface work was skipped. */
- if(IS_STATE(ray_state, ray_index, RAY_HAS_ONLY_VOLUME)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_ACTIVE);
- }
-# endif
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ if (ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
+ /* If we are here, then it means that scene-intersect kernel
+ * has already been executed atleast once. From the next time,
+ * scene-intersect kernel may operate on queues to fetch ray index
+ */
+ *kernel_split_params.use_queues_flag = 1;
+
+ /* Mark queue indices of QUEUE_SHADOW_RAY_CAST_AO_RAYS and
+ * QUEUE_SHADOW_RAY_CAST_DL_RAYS queues that were made empty during the
+ * previous kernel.
+ */
+ kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_AO_RAYS] = 0;
+ kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_DL_RAYS] = 0;
+ }
+
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
+
+ ccl_global char *ray_state = kernel_split_state.ray_state;
+
+#ifdef __VOLUME__
+ /* Reactivate only volume rays here, most surface work was skipped. */
+ if (IS_STATE(ray_state, ray_index, RAY_HAS_ONLY_VOLUME)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_ACTIVE);
+ }
+#endif
- bool active = IS_STATE(ray_state, ray_index, RAY_ACTIVE);
- if(active) {
- ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ bool active = IS_STATE(ray_state, ray_index, RAY_ACTIVE);
+ if (active) {
+ ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
#ifdef __BRANCHED_PATH__
- if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
+ if (!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
#endif
- /* Compute direct lighting and next bounce. */
- if(!kernel_path_surface_bounce(kg, sd, throughput, state, &L->state, ray)) {
- kernel_split_path_end(kg, ray_index);
- }
+ /* Compute direct lighting and next bounce. */
+ if (!kernel_path_surface_bounce(kg, sd, throughput, state, &L->state, ray)) {
+ kernel_split_path_end(kg, ray_index);
+ }
#ifdef __BRANCHED_PATH__
- }
- else if(sd->flag & SD_HAS_ONLY_VOLUME) {
- kernel_split_branched_transparent_bounce(kg, ray_index);
- }
- else {
- kernel_split_branched_indirect_light_init(kg, ray_index);
-
- if(kernel_split_branched_path_surface_indirect_light_iter(kg,
- ray_index,
- 1.0f,
- kernel_split_sd(branched_state_sd, ray_index),
- true,
- true))
- {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- else {
- kernel_split_branched_path_indirect_loop_end(kg, ray_index);
- kernel_split_branched_transparent_bounce(kg, ray_index);
- }
- }
-#endif /* __BRANCHED_PATH__ */
- }
-
- /* Enqueue RAY_UPDATE_BUFFER rays. */
- enqueue_ray_index_local(ray_index,
- QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
- IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER) && active,
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
+ }
+ else if (sd->flag & SD_HAS_ONLY_VOLUME) {
+ kernel_split_branched_transparent_bounce(kg, ray_index);
+ }
+ else {
+ kernel_split_branched_indirect_light_init(kg, ray_index);
+
+ if (kernel_split_branched_path_surface_indirect_light_iter(
+ kg, ray_index, 1.0f, kernel_split_sd(branched_state_sd, ray_index), true, true)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ else {
+ kernel_split_branched_path_indirect_loop_end(kg, ray_index);
+ kernel_split_branched_transparent_bounce(kg, ray_index);
+ }
+ }
+#endif /* __BRANCHED_PATH__ */
+ }
+
+ /* Enqueue RAY_UPDATE_BUFFER rays. */
+ enqueue_ray_index_local(ray_index,
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+ IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER) && active,
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
#ifdef __BRANCHED_PATH__
- /* iter loop */
- if(ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
- kernel_split_params.queue_index[QUEUE_LIGHT_INDIRECT_ITER] = 0;
- }
-
- ray_index = get_ray_index(kg, ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0),
- QUEUE_LIGHT_INDIRECT_ITER,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
-
- if(IS_STATE(ray_state, ray_index, RAY_LIGHT_INDIRECT_NEXT_ITER)) {
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
-
- path_radiance_sum_indirect(L);
- path_radiance_reset_indirect(L);
-
- if(kernel_split_branched_path_surface_indirect_light_iter(kg,
- ray_index,
- 1.0f,
- kernel_split_sd(branched_state_sd, ray_index),
- true,
- true))
- {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- else {
- kernel_split_branched_path_indirect_loop_end(kg, ray_index);
- kernel_split_branched_transparent_bounce(kg, ray_index);
- }
- }
+ /* iter loop */
+ if (ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
+ kernel_split_params.queue_index[QUEUE_LIGHT_INDIRECT_ITER] = 0;
+ }
+
+ ray_index = get_ray_index(kg,
+ ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0),
+ QUEUE_LIGHT_INDIRECT_ITER,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+
+ if (IS_STATE(ray_state, ray_index, RAY_LIGHT_INDIRECT_NEXT_ITER)) {
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+
+ path_radiance_sum_indirect(L);
+ path_radiance_reset_indirect(L);
+
+ if (kernel_split_branched_path_surface_indirect_light_iter(
+ kg, ray_index, 1.0f, kernel_split_sd(branched_state_sd, ray_index), true, true)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ else {
+ kernel_split_branched_path_indirect_loop_end(kg, ray_index);
+ kernel_split_branched_transparent_bounce(kg, ray_index);
+ }
+ }
# ifdef __VOLUME__
- /* Enqueue RAY_VOLUME_INDIRECT_NEXT_ITER rays */
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- enqueue_ray_index_local(ray_index,
- QUEUE_VOLUME_INDIRECT_ITER,
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_VOLUME_INDIRECT_NEXT_ITER),
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
-
-# endif /* __VOLUME__ */
+ /* Enqueue RAY_VOLUME_INDIRECT_NEXT_ITER rays */
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ enqueue_ray_index_local(
+ ray_index,
+ QUEUE_VOLUME_INDIRECT_ITER,
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_VOLUME_INDIRECT_NEXT_ITER),
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
+
+# endif /* __VOLUME__ */
# ifdef __SUBSURFACE__
- /* Enqueue RAY_SUBSURFACE_INDIRECT_NEXT_ITER rays */
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
-
- ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- enqueue_ray_index_local(ray_index,
- QUEUE_SUBSURFACE_INDIRECT_ITER,
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_SUBSURFACE_INDIRECT_NEXT_ITER),
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
-# endif /* __SUBSURFACE__ */
-#endif /* __BRANCHED_PATH__ */
+ /* Enqueue RAY_SUBSURFACE_INDIRECT_NEXT_ITER rays */
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+
+ ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ enqueue_ray_index_local(
+ ray_index,
+ QUEUE_SUBSURFACE_INDIRECT_ITER,
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_SUBSURFACE_INDIRECT_NEXT_ITER),
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
+# endif /* __SUBSURFACE__ */
+#endif /* __BRANCHED_PATH__ */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_path_init.h b/intern/cycles/kernel/split/kernel_path_init.h
index fdd54225b07..3faa3208341 100644
--- a/intern/cycles/kernel/split/kernel_path_init.h
+++ b/intern/cycles/kernel/split/kernel_path_init.h
@@ -21,61 +21,59 @@ CCL_NAMESPACE_BEGIN
*
* Ray state of rays outside the tile-boundary will be marked RAY_INACTIVE
*/
-ccl_device void kernel_path_init(KernelGlobals *kg) {
- int ray_index = ccl_global_id(0) + ccl_global_id(1) * ccl_global_size(0);
+ccl_device void kernel_path_init(KernelGlobals *kg)
+{
+ int ray_index = ccl_global_id(0) + ccl_global_id(1) * ccl_global_size(0);
- /* This is the first assignment to ray_state;
- * So we dont use ASSIGN_RAY_STATE macro.
- */
- kernel_split_state.ray_state[ray_index] = RAY_ACTIVE;
+ /* This is the first assignment to ray_state;
+ * So we dont use ASSIGN_RAY_STATE macro.
+ */
+ kernel_split_state.ray_state[ray_index] = RAY_ACTIVE;
- /* Get work. */
- ccl_global uint *work_pools = kernel_split_params.work_pools;
- uint total_work_size = kernel_split_params.total_work_size;
- uint work_index;
+ /* Get work. */
+ ccl_global uint *work_pools = kernel_split_params.work_pools;
+ uint total_work_size = kernel_split_params.total_work_size;
+ uint work_index;
- if(!get_next_work(kg, work_pools, total_work_size, ray_index, &work_index)) {
- /* No more work, mark ray as inactive */
- kernel_split_state.ray_state[ray_index] = RAY_INACTIVE;
+ if (!get_next_work(kg, work_pools, total_work_size, ray_index, &work_index)) {
+ /* No more work, mark ray as inactive */
+ kernel_split_state.ray_state[ray_index] = RAY_INACTIVE;
- return;
- }
+ return;
+ }
- ccl_global WorkTile *tile = &kernel_split_params.tile;
- uint x, y, sample;
- get_work_pixel(tile, work_index, &x, &y, &sample);
+ ccl_global WorkTile *tile = &kernel_split_params.tile;
+ uint x, y, sample;
+ get_work_pixel(tile, work_index, &x, &y, &sample);
- /* Store buffer offset for writing to passes. */
- uint buffer_offset = (tile->offset + x + y*tile->stride) * kernel_data.film.pass_stride;
- kernel_split_state.buffer_offset[ray_index] = buffer_offset;
+ /* Store buffer offset for writing to passes. */
+ uint buffer_offset = (tile->offset + x + y * tile->stride) * kernel_data.film.pass_stride;
+ kernel_split_state.buffer_offset[ray_index] = buffer_offset;
- /* Initialize random numbers and ray. */
- uint rng_hash;
- kernel_path_trace_setup(kg,
- sample,
- x, y,
- &rng_hash,
- &kernel_split_state.ray[ray_index]);
+ /* Initialize random numbers and ray. */
+ uint rng_hash;
+ kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &kernel_split_state.ray[ray_index]);
- if(kernel_split_state.ray[ray_index].t != 0.0f) {
- /* Initialize throughput, path radiance, Ray, PathState;
- * These rays proceed with path-iteration.
- */
- kernel_split_state.throughput[ray_index] = make_float3(1.0f, 1.0f, 1.0f);
- path_radiance_init(&kernel_split_state.path_radiance[ray_index], kernel_data.film.use_light_pass);
- path_state_init(kg,
- AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]),
- &kernel_split_state.path_state[ray_index],
- rng_hash,
- sample,
- &kernel_split_state.ray[ray_index]);
+ if (kernel_split_state.ray[ray_index].t != 0.0f) {
+ /* Initialize throughput, path radiance, Ray, PathState;
+ * These rays proceed with path-iteration.
+ */
+ kernel_split_state.throughput[ray_index] = make_float3(1.0f, 1.0f, 1.0f);
+ path_radiance_init(&kernel_split_state.path_radiance[ray_index],
+ kernel_data.film.use_light_pass);
+ path_state_init(kg,
+ AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]),
+ &kernel_split_state.path_state[ray_index],
+ rng_hash,
+ sample,
+ &kernel_split_state.ray[ray_index]);
#ifdef __SUBSURFACE__
- kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]);
+ kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]);
#endif
- }
- else {
- ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE);
- }
+ }
+ else {
+ ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_queue_enqueue.h b/intern/cycles/kernel/split/kernel_queue_enqueue.h
index df67fabab19..2db87f7a671 100644
--- a/intern/cycles/kernel/split/kernel_queue_enqueue.h
+++ b/intern/cycles/kernel/split/kernel_queue_enqueue.h
@@ -35,58 +35,53 @@ CCL_NAMESPACE_BEGIN
* - QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS will be filled with
* RAY_TO_REGENERATE, RAY_UPDATE_BUFFER, RAY_HIT_BACKGROUND rays.
*/
-ccl_device void kernel_queue_enqueue(KernelGlobals *kg,
- ccl_local_param QueueEnqueueLocals *locals)
+ccl_device void kernel_queue_enqueue(KernelGlobals *kg, ccl_local_param QueueEnqueueLocals *locals)
{
- /* We have only 2 cases (Hit/Not-Hit) */
- int lidx = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ /* We have only 2 cases (Hit/Not-Hit) */
+ int lidx = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(lidx == 0) {
- locals->queue_atomics[0] = 0;
- locals->queue_atomics[1] = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ if (lidx == 0) {
+ locals->queue_atomics[0] = 0;
+ locals->queue_atomics[1] = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- int queue_number = -1;
+ int queue_number = -1;
- if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND) ||
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_UPDATE_BUFFER) ||
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE)) {
- queue_number = QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS;
- }
- else if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) ||
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME) ||
- IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) {
- queue_number = QUEUE_ACTIVE_AND_REGENERATED_RAYS;
- }
+ if (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND) ||
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_UPDATE_BUFFER) ||
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE)) {
+ queue_number = QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS;
+ }
+ else if (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) ||
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME) ||
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) {
+ queue_number = QUEUE_ACTIVE_AND_REGENERATED_RAYS;
+ }
- unsigned int my_lqidx;
- if(queue_number != -1) {
- my_lqidx = get_local_queue_index(queue_number, locals->queue_atomics);
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ unsigned int my_lqidx;
+ if (queue_number != -1) {
+ my_lqidx = get_local_queue_index(queue_number, locals->queue_atomics);
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- if(lidx == 0) {
- locals->queue_atomics[QUEUE_ACTIVE_AND_REGENERATED_RAYS] =
- get_global_per_queue_offset(QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- locals->queue_atomics,
- kernel_split_params.queue_index);
- locals->queue_atomics[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] =
- get_global_per_queue_offset(QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
- locals->queue_atomics,
- kernel_split_params.queue_index);
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ if (lidx == 0) {
+ locals->queue_atomics[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = get_global_per_queue_offset(
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS, locals->queue_atomics, kernel_split_params.queue_index);
+ locals->queue_atomics[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = get_global_per_queue_offset(
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+ locals->queue_atomics,
+ kernel_split_params.queue_index);
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- unsigned int my_gqidx;
- if(queue_number != -1) {
- my_gqidx = get_global_queue_index(queue_number,
- kernel_split_params.queue_size,
- my_lqidx,
- locals->queue_atomics);
- kernel_split_state.queue_data[my_gqidx] = ray_index;
- }
+ unsigned int my_gqidx;
+ if (queue_number != -1) {
+ my_gqidx = get_global_queue_index(
+ queue_number, kernel_split_params.queue_size, my_lqidx, locals->queue_atomics);
+ kernel_split_state.queue_data[my_gqidx] = ray_index;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_scene_intersect.h b/intern/cycles/kernel/split/kernel_scene_intersect.h
index f5378bc172b..5fef3e045f8 100644
--- a/intern/cycles/kernel/split/kernel_scene_intersect.h
+++ b/intern/cycles/kernel/split/kernel_scene_intersect.h
@@ -25,55 +25,56 @@ CCL_NAMESPACE_BEGIN
*/
ccl_device void kernel_scene_intersect(KernelGlobals *kg)
{
- /* Fetch use_queues_flag */
- char local_use_queues_flag = *kernel_split_params.use_queues_flag;
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ /* Fetch use_queues_flag */
+ char local_use_queues_flag = *kernel_split_params.use_queues_flag;
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(local_use_queues_flag) {
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ if (local_use_queues_flag) {
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
- }
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
+ }
- /* All regenerated rays become active here */
- if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) {
+ /* All regenerated rays become active here */
+ if (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) {
#ifdef __BRANCHED_PATH__
- if(kernel_split_state.branched_state[ray_index].waiting_on_shared_samples) {
- kernel_split_path_end(kg, ray_index);
- }
- else
-#endif /* __BRANCHED_PATH__ */
- {
- ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE);
- }
- }
+ if (kernel_split_state.branched_state[ray_index].waiting_on_shared_samples) {
+ kernel_split_path_end(kg, ray_index);
+ }
+ else
+#endif /* __BRANCHED_PATH__ */
+ {
+ ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE);
+ }
+ }
- if(!IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
- return;
- }
+ if (!IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
+ return;
+ }
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- Ray ray = kernel_split_state.ray[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ Ray ray = kernel_split_state.ray[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- Intersection isect;
- bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L);
- kernel_split_state.isect[ray_index] = isect;
+ Intersection isect;
+ bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L);
+ kernel_split_state.isect[ray_index] = isect;
- if(!hit) {
- /* Change the state of rays that hit the background;
- * These rays undergo special processing in the
- * background_bufferUpdate kernel.
- */
- ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND);
- }
+ if (!hit) {
+ /* Change the state of rays that hit the background;
+ * These rays undergo special processing in the
+ * background_bufferUpdate kernel.
+ */
+ ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_shader_eval.h b/intern/cycles/kernel/split/kernel_shader_eval.h
index 2bc2d300699..8e39c9797e5 100644
--- a/intern/cycles/kernel/split/kernel_shader_eval.h
+++ b/intern/cycles/kernel/split/kernel_shader_eval.h
@@ -22,45 +22,46 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_shader_eval(KernelGlobals *kg)
{
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- /* Sorting on cuda split is not implemented */
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ /* Sorting on cuda split is not implemented */
#ifdef __KERNEL_CUDA__
- int queue_index = kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS];
+ int queue_index = kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS];
#else
- int queue_index = kernel_split_params.queue_index[QUEUE_SHADER_SORTED_RAYS];
+ int queue_index = kernel_split_params.queue_index[QUEUE_SHADER_SORTED_RAYS];
#endif
- if(ray_index >= queue_index) {
- return;
- }
- ray_index = get_ray_index(kg, ray_index,
+ if (ray_index >= queue_index) {
+ return;
+ }
+ ray_index = get_ray_index(kg,
+ ray_index,
#ifdef __KERNEL_CUDA__
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
#else
- QUEUE_SHADER_SORTED_RAYS,
+ QUEUE_SHADER_SORTED_RAYS,
#endif
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
- ccl_global char *ray_state = kernel_split_state.ray_state;
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ ccl_global char *ray_state = kernel_split_state.ray_state;
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- shader_eval_surface(kg, kernel_split_sd(sd, ray_index), state, state->flag);
+ shader_eval_surface(kg, kernel_split_sd(sd, ray_index), state, state->flag);
#ifdef __BRANCHED_PATH__
- if(kernel_data.integrator.branched) {
- shader_merge_closures(kernel_split_sd(sd, ray_index));
- }
- else
+ if (kernel_data.integrator.branched) {
+ shader_merge_closures(kernel_split_sd(sd, ray_index));
+ }
+ else
#endif
- {
- shader_prepare_closures(kernel_split_sd(sd, ray_index), state);
- }
- }
+ {
+ shader_prepare_closures(kernel_split_sd(sd, ray_index), state);
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_shader_setup.h b/intern/cycles/kernel/split/kernel_shader_setup.h
index ea3ec2ec83f..da332db2c98 100644
--- a/intern/cycles/kernel/split/kernel_shader_setup.h
+++ b/intern/cycles/kernel/split/kernel_shader_setup.h
@@ -25,54 +25,52 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_shader_setup(KernelGlobals *kg,
ccl_local_param unsigned int *local_queue_atomics)
{
- /* Enqeueue RAY_TO_REGENERATE rays into QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS queue. */
- if(ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
- *local_queue_atomics = 0;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ /* Enqeueue RAY_TO_REGENERATE rays into QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS queue. */
+ if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
+ *local_queue_atomics = 0;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- int queue_index = kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS];
- if(ray_index >= queue_index) {
- return;
- }
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 0);
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ int queue_index = kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS];
+ if (ray_index >= queue_index) {
+ return;
+ }
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 0);
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
- char enqueue_flag = (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE)) ? 1 : 0;
- enqueue_ray_index_local(ray_index,
- QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
- enqueue_flag,
- kernel_split_params.queue_size,
- local_queue_atomics,
- kernel_split_state.queue_data,
- kernel_split_params.queue_index);
+ char enqueue_flag = (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE)) ? 1 :
+ 0;
+ enqueue_ray_index_local(ray_index,
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+ enqueue_flag,
+ kernel_split_params.queue_size,
+ local_queue_atomics,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_index);
- /* Continue on with shader evaluation. */
- if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
- Intersection isect = kernel_split_state.isect[ray_index];
- Ray ray = kernel_split_state.ray[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
+ /* Continue on with shader evaluation. */
+ if (IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
+ Intersection isect = kernel_split_state.isect[ray_index];
+ Ray ray = kernel_split_state.ray[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
- shader_setup_from_ray(kg,
- sd,
- &isect,
- &ray);
+ shader_setup_from_ray(kg, sd, &isect, &ray);
#ifdef __VOLUME__
- if(sd->flag & SD_HAS_ONLY_VOLUME) {
- ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME);
- }
+ if (sd->flag & SD_HAS_ONLY_VOLUME) {
+ ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME);
+ }
#endif
- }
-
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_shader_sort.h b/intern/cycles/kernel/split/kernel_shader_sort.h
index 666355de334..95d33a42014 100644
--- a/intern/cycles/kernel/split/kernel_shader_sort.h
+++ b/intern/cycles/kernel/split/kernel_shader_sort.h
@@ -16,82 +16,82 @@
CCL_NAMESPACE_BEGIN
-
-ccl_device void kernel_shader_sort(KernelGlobals *kg,
- ccl_local_param ShaderSortLocals *locals)
+ccl_device void kernel_shader_sort(KernelGlobals *kg, ccl_local_param ShaderSortLocals *locals)
{
#ifndef __KERNEL_CUDA__
- int tid = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- uint qsize = kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS];
- if(tid == 0) {
- kernel_split_params.queue_index[QUEUE_SHADER_SORTED_RAYS] = qsize;
- }
+ int tid = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ uint qsize = kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS];
+ if (tid == 0) {
+ kernel_split_params.queue_index[QUEUE_SHADER_SORTED_RAYS] = qsize;
+ }
- uint offset = (tid/SHADER_SORT_LOCAL_SIZE)*SHADER_SORT_BLOCK_SIZE;
- if(offset >= qsize) {
- return;
- }
+ uint offset = (tid / SHADER_SORT_LOCAL_SIZE) * SHADER_SORT_BLOCK_SIZE;
+ if (offset >= qsize) {
+ return;
+ }
- int lid = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
- uint input = QUEUE_ACTIVE_AND_REGENERATED_RAYS * (kernel_split_params.queue_size);
- uint output = QUEUE_SHADER_SORTED_RAYS * (kernel_split_params.queue_size);
- ccl_local uint *local_value = &locals->local_value[0];
- ccl_local ushort *local_index = &locals->local_index[0];
+ int lid = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
+ uint input = QUEUE_ACTIVE_AND_REGENERATED_RAYS * (kernel_split_params.queue_size);
+ uint output = QUEUE_SHADER_SORTED_RAYS * (kernel_split_params.queue_size);
+ ccl_local uint *local_value = &locals->local_value[0];
+ ccl_local ushort *local_index = &locals->local_index[0];
- /* copy to local memory */
- for(uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
- uint idx = offset + i + lid;
- uint add = input + idx;
- uint value = (~0);
- if(idx < qsize) {
- int ray_index = kernel_split_state.queue_data[add];
- bool valid = (ray_index != QUEUE_EMPTY_SLOT) && IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE);
- if(valid) {
- value = kernel_split_sd(sd, ray_index)->shader & SHADER_MASK;
- }
- }
- local_value[i + lid] = value;
- local_index[i + lid] = i + lid;
- }
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ /* copy to local memory */
+ for (uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
+ uint idx = offset + i + lid;
+ uint add = input + idx;
+ uint value = (~0);
+ if (idx < qsize) {
+ int ray_index = kernel_split_state.queue_data[add];
+ bool valid = (ray_index != QUEUE_EMPTY_SLOT) &&
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE);
+ if (valid) {
+ value = kernel_split_sd(sd, ray_index)->shader & SHADER_MASK;
+ }
+ }
+ local_value[i + lid] = value;
+ local_index[i + lid] = i + lid;
+ }
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- /* skip sorting for cpu split kernel */
+ /* skip sorting for cpu split kernel */
# ifdef __KERNEL_OPENCL__
- /* bitonic sort */
- for(uint length = 1; length < SHADER_SORT_BLOCK_SIZE; length <<= 1) {
- for(uint inc = length; inc > 0; inc >>= 1) {
- for(uint ii = 0; ii < SHADER_SORT_BLOCK_SIZE; ii += SHADER_SORT_LOCAL_SIZE) {
- uint i = lid + ii;
- bool direction = ((i & (length << 1)) != 0);
- uint j = i ^ inc;
- ushort ioff = local_index[i];
- ushort joff = local_index[j];
- uint iKey = local_value[ioff];
- uint jKey = local_value[joff];
- bool smaller = (jKey < iKey) || (jKey == iKey && j < i);
- bool swap = smaller ^ (j < i) ^ direction;
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
- local_index[i] = (swap) ? joff : ioff;
- local_index[j] = (swap) ? ioff : joff;
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
- }
- }
- }
-# endif /* __KERNEL_OPENCL__ */
+ /* bitonic sort */
+ for (uint length = 1; length < SHADER_SORT_BLOCK_SIZE; length <<= 1) {
+ for (uint inc = length; inc > 0; inc >>= 1) {
+ for (uint ii = 0; ii < SHADER_SORT_BLOCK_SIZE; ii += SHADER_SORT_LOCAL_SIZE) {
+ uint i = lid + ii;
+ bool direction = ((i & (length << 1)) != 0);
+ uint j = i ^ inc;
+ ushort ioff = local_index[i];
+ ushort joff = local_index[j];
+ uint iKey = local_value[ioff];
+ uint jKey = local_value[joff];
+ bool smaller = (jKey < iKey) || (jKey == iKey && j < i);
+ bool swap = smaller ^ (j < i) ^ direction;
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ local_index[i] = (swap) ? joff : ioff;
+ local_index[j] = (swap) ? ioff : joff;
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ }
+ }
+ }
+# endif /* __KERNEL_OPENCL__ */
- /* copy to destination */
- for(uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
- uint idx = offset + i + lid;
- uint lidx = local_index[i + lid];
- uint outi = output + idx;
- uint ini = input + offset + lidx;
- uint value = local_value[lidx];
- if(idx < qsize) {
- kernel_split_state.queue_data[outi] = (value == (~0)) ? QUEUE_EMPTY_SLOT : kernel_split_state.queue_data[ini];
- }
- }
-#endif /* __KERNEL_CUDA__ */
+ /* copy to destination */
+ for (uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
+ uint idx = offset + i + lid;
+ uint lidx = local_index[i + lid];
+ uint outi = output + idx;
+ uint ini = input + offset + lidx;
+ uint value = local_value[lidx];
+ if (idx < qsize) {
+ kernel_split_state.queue_data[outi] = (value == (~0)) ? QUEUE_EMPTY_SLOT :
+ kernel_split_state.queue_data[ini];
+ }
+ }
+#endif /* __KERNEL_CUDA__ */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h b/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h
index fb08112503a..5d772fc597b 100644
--- a/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h
+++ b/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h
@@ -19,35 +19,40 @@ CCL_NAMESPACE_BEGIN
/* Shadow ray cast for AO. */
ccl_device void kernel_shadow_blocked_ao(KernelGlobals *kg)
{
- unsigned int ao_queue_length = kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_AO_RAYS];
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ unsigned int ao_queue_length = kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_AO_RAYS];
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- int ray_index = QUEUE_EMPTY_SLOT;
- int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(thread_index < ao_queue_length) {
- ray_index = get_ray_index(kg, thread_index, QUEUE_SHADOW_RAY_CAST_AO_RAYS,
- kernel_split_state.queue_data, kernel_split_params.queue_size, 1);
- }
+ int ray_index = QUEUE_EMPTY_SLOT;
+ int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ if (thread_index < ao_queue_length) {
+ ray_index = get_ray_index(kg,
+ thread_index,
+ QUEUE_SHADOW_RAY_CAST_AO_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+ }
- if(ray_index == QUEUE_EMPTY_SLOT) {
- return;
- }
+ if (ray_index == QUEUE_EMPTY_SLOT) {
+ return;
+ }
- ShaderData *sd = kernel_split_sd(sd, ray_index);
- ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- float3 throughput = kernel_split_state.throughput[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+ ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ float3 throughput = kernel_split_state.throughput[ray_index];
#ifdef __BRANCHED_PATH__
- if(!kernel_data.integrator.branched || IS_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
+ if (!kernel_data.integrator.branched ||
+ IS_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
#endif
- kernel_path_ao(kg, sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, sd));
+ kernel_path_ao(kg, sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, sd));
#ifdef __BRANCHED_PATH__
- }
- else {
- kernel_branched_path_ao(kg, sd, emission_sd, L, state, throughput);
- }
+ }
+ else {
+ kernel_branched_path_ao(kg, sd, emission_sd, L, state, throughput);
+ }
#endif
}
diff --git a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h
index da072fd5f1a..82990ce9fae 100644
--- a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h
+++ b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h
@@ -19,89 +19,80 @@ CCL_NAMESPACE_BEGIN
/* Shadow ray cast for direct visible light. */
ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg)
{
- unsigned int dl_queue_length = kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_DL_RAYS];
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ unsigned int dl_queue_length = kernel_split_params.queue_index[QUEUE_SHADOW_RAY_CAST_DL_RAYS];
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
- int ray_index = QUEUE_EMPTY_SLOT;
- int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(thread_index < dl_queue_length) {
- ray_index = get_ray_index(kg, thread_index, QUEUE_SHADOW_RAY_CAST_DL_RAYS,
- kernel_split_state.queue_data, kernel_split_params.queue_size, 1);
- }
+ int ray_index = QUEUE_EMPTY_SLOT;
+ int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ if (thread_index < dl_queue_length) {
+ ray_index = get_ray_index(kg,
+ thread_index,
+ QUEUE_SHADOW_RAY_CAST_DL_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+ }
#ifdef __BRANCHED_PATH__
- /* TODO(mai): move this somewhere else? */
- if(thread_index == 0) {
- /* Clear QUEUE_INACTIVE_RAYS before next kernel. */
- kernel_split_params.queue_index[QUEUE_INACTIVE_RAYS] = 0;
- }
-#endif /* __BRANCHED_PATH__ */
+ /* TODO(mai): move this somewhere else? */
+ if (thread_index == 0) {
+ /* Clear QUEUE_INACTIVE_RAYS before next kernel. */
+ kernel_split_params.queue_index[QUEUE_INACTIVE_RAYS] = 0;
+ }
+#endif /* __BRANCHED_PATH__ */
- if(ray_index == QUEUE_EMPTY_SLOT)
- return;
+ if (ray_index == QUEUE_EMPTY_SLOT)
+ return;
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- Ray ray = kernel_split_state.light_ray[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
- float3 throughput = kernel_split_state.throughput[ray_index];
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ Ray ray = kernel_split_state.light_ray[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+ float3 throughput = kernel_split_state.throughput[ray_index];
- BsdfEval L_light = kernel_split_state.bsdf_eval[ray_index];
- ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
- bool is_lamp = kernel_split_state.is_lamp[ray_index];
+ BsdfEval L_light = kernel_split_state.bsdf_eval[ray_index];
+ ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
+ bool is_lamp = kernel_split_state.is_lamp[ray_index];
-# if defined(__BRANCHED_PATH__) || defined(__SHADOW_TRICKS__)
- bool use_branched = false;
- int all = 0;
+#if defined(__BRANCHED_PATH__) || defined(__SHADOW_TRICKS__)
+ bool use_branched = false;
+ int all = 0;
- if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- use_branched = true;
- all = 1;
- }
-# if defined(__BRANCHED_PATH__)
- else if(kernel_data.integrator.branched) {
- use_branched = true;
+ if (state->flag & PATH_RAY_SHADOW_CATCHER) {
+ use_branched = true;
+ all = 1;
+ }
+# if defined(__BRANCHED_PATH__)
+ else if (kernel_data.integrator.branched) {
+ use_branched = true;
- if(IS_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
- all = (kernel_data.integrator.sample_all_lights_indirect);
- }
- else
- {
- all = (kernel_data.integrator.sample_all_lights_direct);
- }
- }
-# endif /* __BRANCHED_PATH__ */
+ if (IS_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
+ all = (kernel_data.integrator.sample_all_lights_indirect);
+ }
+ else {
+ all = (kernel_data.integrator.sample_all_lights_direct);
+ }
+ }
+# endif /* __BRANCHED_PATH__ */
- if(use_branched) {
- kernel_branched_path_surface_connect_light(kg,
- sd,
- emission_sd,
- state,
- throughput,
- 1.0f,
- L,
- all);
- }
- else
-# endif /* defined(__BRANCHED_PATH__) || defined(__SHADOW_TRICKS__)*/
- {
- /* trace shadow ray */
- float3 shadow;
+ if (use_branched) {
+ kernel_branched_path_surface_connect_light(
+ kg, sd, emission_sd, state, throughput, 1.0f, L, all);
+ }
+ else
+#endif /* defined(__BRANCHED_PATH__) || defined(__SHADOW_TRICKS__)*/
+ {
+ /* trace shadow ray */
+ float3 shadow;
- if(!shadow_blocked(kg,
- sd,
- emission_sd,
- state,
- &ray,
- &shadow))
- {
- /* accumulate */
- path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
- }
- else {
- path_radiance_accum_total_light(L, state, throughput, &L_light);
- }
- }
+ if (!shadow_blocked(kg, sd, emission_sd, state, &ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
+ }
+ else {
+ path_radiance_accum_total_light(L, state, throughput, &L_light);
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_split_common.h b/intern/cycles/kernel/split/kernel_split_common.h
index 4b86696691a..384bc952460 100644
--- a/intern/cycles/kernel/split/kernel_split_common.h
+++ b/intern/cycles/kernel/split/kernel_split_common.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef __KERNEL_SPLIT_H__
-#define __KERNEL_SPLIT_H__
+#ifndef __KERNEL_SPLIT_H__
+#define __KERNEL_SPLIT_H__
#include "kernel/kernel_math.h"
#include "kernel/kernel_types.h"
@@ -57,47 +57,48 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline void kernel_split_path_end(KernelGlobals *kg, int ray_index)
{
- ccl_global char *ray_state = kernel_split_state.ray_state;
+ ccl_global char *ray_state = kernel_split_state.ray_state;
#ifdef __BRANCHED_PATH__
# ifdef __SUBSURFACE__
- ccl_addr_space SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
-
- if(ss_indirect->num_rays) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER);
- }
- else
-# endif /* __SUBSURFACE__ */
- if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT_SHARED)) {
- int orig_ray = kernel_split_state.branched_state[ray_index].original_ray;
-
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- PathRadiance *orig_ray_L = &kernel_split_state.path_radiance[orig_ray];
-
- path_radiance_sum_indirect(L);
- path_radiance_accum_sample(orig_ray_L, L);
-
- atomic_fetch_and_dec_uint32((ccl_global uint*)&kernel_split_state.branched_state[orig_ray].shared_sample_count);
-
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_INACTIVE);
- }
- else if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_LIGHT_INDIRECT_NEXT_ITER);
- }
- else if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_VOLUME_INDIRECT)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_VOLUME_INDIRECT_NEXT_ITER);
- }
- else if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_SUBSURFACE_INDIRECT)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_SUBSURFACE_INDIRECT_NEXT_ITER);
- }
- else {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER);
- }
+ ccl_addr_space SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
+
+ if (ss_indirect->num_rays) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER);
+ }
+ else
+# endif /* __SUBSURFACE__ */
+ if (IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT_SHARED)) {
+ int orig_ray = kernel_split_state.branched_state[ray_index].original_ray;
+
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ PathRadiance *orig_ray_L = &kernel_split_state.path_radiance[orig_ray];
+
+ path_radiance_sum_indirect(L);
+ path_radiance_accum_sample(orig_ray_L, L);
+
+ atomic_fetch_and_dec_uint32(
+ (ccl_global uint *)&kernel_split_state.branched_state[orig_ray].shared_sample_count);
+
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_INACTIVE);
+ }
+ else if (IS_FLAG(ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_LIGHT_INDIRECT_NEXT_ITER);
+ }
+ else if (IS_FLAG(ray_state, ray_index, RAY_BRANCHED_VOLUME_INDIRECT)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_VOLUME_INDIRECT_NEXT_ITER);
+ }
+ else if (IS_FLAG(ray_state, ray_index, RAY_BRANCHED_SUBSURFACE_INDIRECT)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_SUBSURFACE_INDIRECT_NEXT_ITER);
+ }
+ else {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER);
+ }
#else
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER);
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER);
#endif
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_SPLIT_H__ */
+#endif /* __KERNEL_SPLIT_H__ */
diff --git a/intern/cycles/kernel/split/kernel_split_data.h b/intern/cycles/kernel/split/kernel_split_data.h
index 3f6b3977d79..433b1221a37 100644
--- a/intern/cycles/kernel/split/kernel_split_data.h
+++ b/intern/cycles/kernel/split/kernel_split_data.h
@@ -24,22 +24,22 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline uint64_t split_data_buffer_size(KernelGlobals *kg, size_t num_elements)
{
- (void) kg; /* Unused on CPU. */
+ (void)kg; /* Unused on CPU. */
- uint64_t size = 0;
-#define SPLIT_DATA_ENTRY(type, name, num) + align_up(num_elements * num * sizeof(type), 16)
- size = size SPLIT_DATA_ENTRIES;
+ uint64_t size = 0;
+#define SPLIT_DATA_ENTRY(type, name, num) +align_up(num_elements *num * sizeof(type), 16)
+ size = size SPLIT_DATA_ENTRIES;
#undef SPLIT_DATA_ENTRY
- uint64_t closure_size = sizeof(ShaderClosure) * (kernel_data.integrator.max_closures-1);
+ uint64_t closure_size = sizeof(ShaderClosure) * (kernel_data.integrator.max_closures - 1);
#ifdef __BRANCHED_PATH__
- size += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
+ size += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
#endif
- size += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
+ size += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
- return size;
+ return size;
}
ccl_device_inline void split_data_init(KernelGlobals *kg,
@@ -48,28 +48,29 @@ ccl_device_inline void split_data_init(KernelGlobals *kg,
ccl_global void *data,
ccl_global char *ray_state)
{
- (void) kg; /* Unused on CPU. */
+ (void)kg; /* Unused on CPU. */
- ccl_global char *p = (ccl_global char*)data;
+ ccl_global char *p = (ccl_global char *)data;
#define SPLIT_DATA_ENTRY(type, name, num) \
- split_data->name = (type*)p; p += align_up(num_elements * num * sizeof(type), 16);
- SPLIT_DATA_ENTRIES;
+ split_data->name = (type *)p; \
+ p += align_up(num_elements * num * sizeof(type), 16);
+ SPLIT_DATA_ENTRIES;
#undef SPLIT_DATA_ENTRY
- uint64_t closure_size = sizeof(ShaderClosure) * (kernel_data.integrator.max_closures-1);
+ uint64_t closure_size = sizeof(ShaderClosure) * (kernel_data.integrator.max_closures - 1);
#ifdef __BRANCHED_PATH__
- split_data->_branched_state_sd = (ShaderData*)p;
- p += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
+ split_data->_branched_state_sd = (ShaderData *)p;
+ p += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
#endif
- split_data->_sd = (ShaderData*)p;
- p += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
+ split_data->_sd = (ShaderData *)p;
+ p += align_up(num_elements * (sizeof(ShaderData) + closure_size), 16);
- split_data->ray_state = ray_state;
+ split_data->ray_state = ray_state;
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_SPLIT_DATA_H__ */
+#endif /* __KERNEL_SPLIT_DATA_H__ */
diff --git a/intern/cycles/kernel/split/kernel_split_data_types.h b/intern/cycles/kernel/split/kernel_split_data_types.h
index 83df1e2a0a6..6ff3f5bdb55 100644
--- a/intern/cycles/kernel/split/kernel_split_data_types.h
+++ b/intern/cycles/kernel/split/kernel_split_data_types.h
@@ -22,17 +22,17 @@ CCL_NAMESPACE_BEGIN
/* parameters used by the split kernels, we use a single struct to avoid passing these to each kernel */
typedef struct SplitParams {
- WorkTile tile;
- uint total_work_size;
+ WorkTile tile;
+ uint total_work_size;
- ccl_global unsigned int *work_pools;
+ ccl_global unsigned int *work_pools;
- ccl_global int *queue_index;
- int queue_size;
- ccl_global char *use_queues_flag;
+ ccl_global int *queue_index;
+ int queue_size;
+ ccl_global char *use_queues_flag;
- /* Place for storing sd->flag. AMD GPU OpenCL compiler workaround */
- int dummy_sd_flag;
+ /* Place for storing sd->flag. AMD GPU OpenCL compiler workaround */
+ int dummy_sd_flag;
} SplitParams;
/* Global memory variables [porting]; These memory is used for
@@ -46,98 +46,98 @@ typedef struct SplitParams {
#ifdef __BRANCHED_PATH__
typedef ccl_global struct SplitBranchedState {
- /* various state that must be kept and restored after an indirect loop */
- PathState path_state;
- float3 throughput;
- Ray ray;
+ /* various state that must be kept and restored after an indirect loop */
+ PathState path_state;
+ float3 throughput;
+ Ray ray;
- Intersection isect;
+ Intersection isect;
- char ray_state;
+ char ray_state;
- /* indirect loop state */
- int next_closure;
- int next_sample;
+ /* indirect loop state */
+ int next_closure;
+ int next_sample;
-#ifdef __SUBSURFACE__
- int ss_next_closure;
- int ss_next_sample;
- int next_hit;
- int num_hits;
-
- uint lcg_state;
- LocalIntersection ss_isect;
-#endif /*__SUBSURFACE__ */
-
- int shared_sample_count; /* number of branched samples shared with other threads */
- int original_ray; /* index of original ray when sharing branched samples */
- bool waiting_on_shared_samples;
+# ifdef __SUBSURFACE__
+ int ss_next_closure;
+ int ss_next_sample;
+ int next_hit;
+ int num_hits;
+
+ uint lcg_state;
+ LocalIntersection ss_isect;
+# endif /*__SUBSURFACE__ */
+
+ int shared_sample_count; /* number of branched samples shared with other threads */
+ int original_ray; /* index of original ray when sharing branched samples */
+ bool waiting_on_shared_samples;
} SplitBranchedState;
-#define SPLIT_DATA_BRANCHED_ENTRIES \
- SPLIT_DATA_ENTRY( SplitBranchedState, branched_state, 1) \
- SPLIT_DATA_ENTRY(ShaderData, _branched_state_sd, 0)
+# define SPLIT_DATA_BRANCHED_ENTRIES \
+ SPLIT_DATA_ENTRY(SplitBranchedState, branched_state, 1) \
+ SPLIT_DATA_ENTRY(ShaderData, _branched_state_sd, 0)
#else
-#define SPLIT_DATA_BRANCHED_ENTRIES
-#endif /* __BRANCHED_PATH__ */
+# define SPLIT_DATA_BRANCHED_ENTRIES
+#endif /* __BRANCHED_PATH__ */
#ifdef __SUBSURFACE__
# define SPLIT_DATA_SUBSURFACE_ENTRIES \
- SPLIT_DATA_ENTRY(ccl_global SubsurfaceIndirectRays, ss_rays, 1)
+ SPLIT_DATA_ENTRY(ccl_global SubsurfaceIndirectRays, ss_rays, 1)
#else
# define SPLIT_DATA_SUBSURFACE_ENTRIES
-#endif /* __SUBSURFACE__ */
+#endif /* __SUBSURFACE__ */
#ifdef __VOLUME__
-# define SPLIT_DATA_VOLUME_ENTRIES \
- SPLIT_DATA_ENTRY(ccl_global PathState, state_shadow, 1)
+# define SPLIT_DATA_VOLUME_ENTRIES SPLIT_DATA_ENTRY(ccl_global PathState, state_shadow, 1)
#else
# define SPLIT_DATA_VOLUME_ENTRIES
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
#define SPLIT_DATA_ENTRIES \
- SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
- SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
- SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \
- SPLIT_DATA_ENTRY(ccl_global PathState, path_state, 1) \
- SPLIT_DATA_ENTRY(ccl_global Intersection, isect, 1) \
- SPLIT_DATA_ENTRY(ccl_global BsdfEval, bsdf_eval, 1) \
- SPLIT_DATA_ENTRY(ccl_global int, is_lamp, 1) \
- SPLIT_DATA_ENTRY(ccl_global Ray, light_ray, 1) \
- SPLIT_DATA_ENTRY(ccl_global int, queue_data, (NUM_QUEUES*2)) /* TODO(mai): this is too large? */ \
- SPLIT_DATA_ENTRY(ccl_global uint, buffer_offset, 1) \
- SPLIT_DATA_ENTRY(ShaderDataTinyStorage, sd_DL_shadow, 1) \
- SPLIT_DATA_SUBSURFACE_ENTRIES \
- SPLIT_DATA_VOLUME_ENTRIES \
- SPLIT_DATA_BRANCHED_ENTRIES \
- SPLIT_DATA_ENTRY(ShaderData, _sd, 0)
+ SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
+ SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
+ SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \
+ SPLIT_DATA_ENTRY(ccl_global PathState, path_state, 1) \
+ SPLIT_DATA_ENTRY(ccl_global Intersection, isect, 1) \
+ SPLIT_DATA_ENTRY(ccl_global BsdfEval, bsdf_eval, 1) \
+ SPLIT_DATA_ENTRY(ccl_global int, is_lamp, 1) \
+ SPLIT_DATA_ENTRY(ccl_global Ray, light_ray, 1) \
+ SPLIT_DATA_ENTRY( \
+ ccl_global int, queue_data, (NUM_QUEUES * 2)) /* TODO(mai): this is too large? */ \
+ SPLIT_DATA_ENTRY(ccl_global uint, buffer_offset, 1) \
+ SPLIT_DATA_ENTRY(ShaderDataTinyStorage, sd_DL_shadow, 1) \
+ SPLIT_DATA_SUBSURFACE_ENTRIES \
+ SPLIT_DATA_VOLUME_ENTRIES \
+ SPLIT_DATA_BRANCHED_ENTRIES \
+ SPLIT_DATA_ENTRY(ShaderData, _sd, 0)
/* entries to be copied to inactive rays when sharing branched samples (TODO: which are actually needed?) */
#define SPLIT_DATA_ENTRIES_BRANCHED_SHARED \
- SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
- SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
- SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \
- SPLIT_DATA_ENTRY(ccl_global PathState, path_state, 1) \
- SPLIT_DATA_ENTRY(ccl_global Intersection, isect, 1) \
- SPLIT_DATA_ENTRY(ccl_global BsdfEval, bsdf_eval, 1) \
- SPLIT_DATA_ENTRY(ccl_global int, is_lamp, 1) \
- SPLIT_DATA_ENTRY(ccl_global Ray, light_ray, 1) \
- SPLIT_DATA_ENTRY(ShaderDataTinyStorage, sd_DL_shadow, 1) \
- SPLIT_DATA_SUBSURFACE_ENTRIES \
- SPLIT_DATA_VOLUME_ENTRIES \
- SPLIT_DATA_BRANCHED_ENTRIES \
- SPLIT_DATA_ENTRY(ShaderData, _sd, 0)
+ SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
+ SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
+ SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \
+ SPLIT_DATA_ENTRY(ccl_global PathState, path_state, 1) \
+ SPLIT_DATA_ENTRY(ccl_global Intersection, isect, 1) \
+ SPLIT_DATA_ENTRY(ccl_global BsdfEval, bsdf_eval, 1) \
+ SPLIT_DATA_ENTRY(ccl_global int, is_lamp, 1) \
+ SPLIT_DATA_ENTRY(ccl_global Ray, light_ray, 1) \
+ SPLIT_DATA_ENTRY(ShaderDataTinyStorage, sd_DL_shadow, 1) \
+ SPLIT_DATA_SUBSURFACE_ENTRIES \
+ SPLIT_DATA_VOLUME_ENTRIES \
+ SPLIT_DATA_BRANCHED_ENTRIES \
+ SPLIT_DATA_ENTRY(ShaderData, _sd, 0)
/* struct that holds pointers to data in the shared state buffer */
typedef struct SplitData {
#define SPLIT_DATA_ENTRY(type, name, num) type *name;
- SPLIT_DATA_ENTRIES
+ SPLIT_DATA_ENTRIES
#undef SPLIT_DATA_ENTRY
- /* this is actually in a separate buffer from the rest of the split state data (so it can be read back from
- * the host easily) but is still used the same as the other data so we have it here in this struct as well
- */
- ccl_global char *ray_state;
+ /* this is actually in a separate buffer from the rest of the split state data (so it can be read back from
+ * the host easily) but is still used the same as the other data so we have it here in this struct as well
+ */
+ ccl_global char *ray_state;
} SplitData;
#ifndef __KERNEL_CUDA__
@@ -148,30 +148,30 @@ __device__ SplitData __split_data;
# define kernel_split_state (__split_data)
__device__ SplitParams __split_param_data;
# define kernel_split_params (__split_param_data)
-#endif /* __KERNEL_CUDA__ */
+#endif /* __KERNEL_CUDA__ */
-#define kernel_split_sd(sd, ray_index) ((ShaderData*) \
- ( \
- ((ccl_global char*)kernel_split_state._##sd) + \
- (sizeof(ShaderData) + sizeof(ShaderClosure)*(kernel_data.integrator.max_closures-1)) * (ray_index) \
- ))
+#define kernel_split_sd(sd, ray_index) \
+ ((ShaderData *)(((ccl_global char *)kernel_split_state._##sd) + \
+ (sizeof(ShaderData) + \
+ sizeof(ShaderClosure) * (kernel_data.integrator.max_closures - 1)) * \
+ (ray_index)))
/* Local storage for queue_enqueue kernel. */
typedef struct QueueEnqueueLocals {
- uint queue_atomics[2];
+ uint queue_atomics[2];
} QueueEnqueueLocals;
/* Local storage for holdout_emission_blurring_pathtermination_ao kernel. */
typedef struct BackgroundAOLocals {
- uint queue_atomics_bg;
- uint queue_atomics_ao;
+ uint queue_atomics_bg;
+ uint queue_atomics_ao;
} BackgroundAOLocals;
typedef struct ShaderSortLocals {
- uint local_value[SHADER_SORT_BLOCK_SIZE];
- ushort local_index[SHADER_SORT_BLOCK_SIZE];
+ uint local_value[SHADER_SORT_BLOCK_SIZE];
+ ushort local_index[SHADER_SORT_BLOCK_SIZE];
} ShaderSortLocals;
CCL_NAMESPACE_END
-#endif /* __KERNEL_SPLIT_DATA_TYPES_H__ */
+#endif /* __KERNEL_SPLIT_DATA_TYPES_H__ */
diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h
index 08769fe303b..ba06ae3bc53 100644
--- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h
+++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h
@@ -18,276 +18,247 @@ CCL_NAMESPACE_BEGIN
#if defined(__BRANCHED_PATH__) && defined(__SUBSURFACE__)
-ccl_device_inline void kernel_split_branched_path_subsurface_indirect_light_init(KernelGlobals *kg, int ray_index)
+ccl_device_inline void kernel_split_branched_path_subsurface_indirect_light_init(KernelGlobals *kg,
+ int ray_index)
{
- kernel_split_branched_path_indirect_loop_init(kg, ray_index);
+ kernel_split_branched_path_indirect_loop_init(kg, ray_index);
- SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
+ SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
- branched_state->ss_next_closure = 0;
- branched_state->ss_next_sample = 0;
+ branched_state->ss_next_closure = 0;
+ branched_state->ss_next_sample = 0;
- branched_state->num_hits = 0;
- branched_state->next_hit = 0;
+ branched_state->num_hits = 0;
+ branched_state->next_hit = 0;
- ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_SUBSURFACE_INDIRECT);
+ ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_SUBSURFACE_INDIRECT);
}
-ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_iter(KernelGlobals *kg, int ray_index)
+ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_iter(
+ KernelGlobals *kg, int ray_index)
{
- SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
-
- ShaderData *sd = kernel_split_sd(branched_state_sd, ray_index);
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
-
- for(int i = branched_state->ss_next_closure; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(!CLOSURE_IS_BSSRDF(sc->type))
- continue;
-
- /* Closure memory will be overwritten, so read required variables now. */
- Bssrdf *bssrdf = (Bssrdf *)sc;
- ClosureType bssrdf_type = sc->type;
- float bssrdf_roughness = bssrdf->roughness;
-
- /* set up random number generator */
- if(branched_state->ss_next_sample == 0 && branched_state->next_hit == 0 &&
- branched_state->next_closure == 0 && branched_state->next_sample == 0)
- {
- branched_state->lcg_state = lcg_state_init_addrspace(&branched_state->path_state,
- 0x68bc21eb);
- }
- int num_samples = kernel_data.integrator.subsurface_samples * 3;
- float num_samples_inv = 1.0f/num_samples;
- uint bssrdf_rng_hash = cmj_hash(branched_state->path_state.rng_hash, i);
-
- /* do subsurface scatter step with copy of shader data, this will
- * replace the BSSRDF with a diffuse BSDF closure */
- for(int j = branched_state->ss_next_sample; j < num_samples; j++) {
- ccl_global PathState *hit_state = &kernel_split_state.path_state[ray_index];
- *hit_state = branched_state->path_state;
- hit_state->rng_hash = bssrdf_rng_hash;
- path_state_branch(hit_state, j, num_samples);
-
- ccl_global LocalIntersection *ss_isect = &branched_state->ss_isect;
- float bssrdf_u, bssrdf_v;
- path_branched_rng_2D(kg,
- bssrdf_rng_hash,
- hit_state,
- j,
- num_samples,
- PRNG_BSDF_U,
- &bssrdf_u,
- &bssrdf_v);
-
- /* intersection is expensive so avoid doing multiple times for the same input */
- if(branched_state->next_hit == 0 && branched_state->next_closure == 0 && branched_state->next_sample == 0) {
- uint lcg_state = branched_state->lcg_state;
- LocalIntersection ss_isect_private;
-
- branched_state->num_hits = subsurface_scatter_multi_intersect(kg,
- &ss_isect_private,
- sd,
- hit_state,
- sc,
- &lcg_state,
- bssrdf_u, bssrdf_v,
- true);
-
- branched_state->lcg_state = lcg_state;
- *ss_isect = ss_isect_private;
- }
-
- hit_state->rng_offset += PRNG_BOUNCE_NUM;
-
-#ifdef __VOLUME__
- Ray volume_ray = branched_state->ray;
- bool need_update_volume_stack =
- kernel_data.integrator.use_volumes &&
- sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
-#endif /* __VOLUME__ */
-
- /* compute lighting with the BSDF closure */
- for(int hit = branched_state->next_hit; hit < branched_state->num_hits; hit++) {
- ShaderData *bssrdf_sd = kernel_split_sd(sd, ray_index);
- *bssrdf_sd = *sd; /* note: copy happens each iteration of inner loop, this is
- * important as the indirect path will write into bssrdf_sd */
-
- LocalIntersection ss_isect_private = *ss_isect;
- subsurface_scatter_multi_setup(kg,
- &ss_isect_private,
- hit,
- bssrdf_sd,
- hit_state,
- bssrdf_type,
- bssrdf_roughness);
- *ss_isect = ss_isect_private;
-
-#ifdef __VOLUME__
- if(need_update_volume_stack) {
- /* Setup ray from previous surface point to the new one. */
- float3 P = ray_offset(bssrdf_sd->P, -bssrdf_sd->Ng);
- volume_ray.D = normalize_len(P - volume_ray.P, &volume_ray.t);
-
- for(int k = 0; k < VOLUME_STACK_SIZE; k++) {
- hit_state->volume_stack[k] = branched_state->path_state.volume_stack[k];
- }
-
- kernel_volume_stack_update_for_subsurface(kg,
- emission_sd,
- &volume_ray,
- hit_state->volume_stack);
- }
-#endif /* __VOLUME__ */
-
-#ifdef __EMISSION__
- if(branched_state->next_closure == 0 && branched_state->next_sample == 0) {
- /* direct light */
- if(kernel_data.integrator.use_direct_light) {
- int all = (kernel_data.integrator.sample_all_lights_direct) ||
- (hit_state->flag & PATH_RAY_SHADOW_CATCHER);
- kernel_branched_path_surface_connect_light(kg,
- bssrdf_sd,
- emission_sd,
- hit_state,
- branched_state->throughput,
- num_samples_inv,
- L,
- all);
- }
- }
-#endif /* __EMISSION__ */
-
- /* indirect light */
- if(kernel_split_branched_path_surface_indirect_light_iter(kg,
- ray_index,
- num_samples_inv,
- bssrdf_sd,
- false,
- false))
- {
- branched_state->ss_next_closure = i;
- branched_state->ss_next_sample = j;
- branched_state->next_hit = hit;
-
- return true;
- }
-
- branched_state->next_closure = 0;
- }
-
- branched_state->next_hit = 0;
- }
-
- branched_state->ss_next_sample = 0;
- }
-
- branched_state->ss_next_closure = sd->num_closure;
-
- branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0);
- if(branched_state->waiting_on_shared_samples) {
- return true;
- }
-
- kernel_split_branched_path_indirect_loop_end(kg, ray_index);
-
- return false;
+ SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
+
+ ShaderData *sd = kernel_split_sd(branched_state_sd, ray_index);
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
+
+ for (int i = branched_state->ss_next_closure; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+
+ if (!CLOSURE_IS_BSSRDF(sc->type))
+ continue;
+
+ /* Closure memory will be overwritten, so read required variables now. */
+ Bssrdf *bssrdf = (Bssrdf *)sc;
+ ClosureType bssrdf_type = sc->type;
+ float bssrdf_roughness = bssrdf->roughness;
+
+ /* set up random number generator */
+ if (branched_state->ss_next_sample == 0 && branched_state->next_hit == 0 &&
+ branched_state->next_closure == 0 && branched_state->next_sample == 0) {
+ branched_state->lcg_state = lcg_state_init_addrspace(&branched_state->path_state,
+ 0x68bc21eb);
+ }
+ int num_samples = kernel_data.integrator.subsurface_samples * 3;
+ float num_samples_inv = 1.0f / num_samples;
+ uint bssrdf_rng_hash = cmj_hash(branched_state->path_state.rng_hash, i);
+
+ /* do subsurface scatter step with copy of shader data, this will
+ * replace the BSSRDF with a diffuse BSDF closure */
+ for (int j = branched_state->ss_next_sample; j < num_samples; j++) {
+ ccl_global PathState *hit_state = &kernel_split_state.path_state[ray_index];
+ *hit_state = branched_state->path_state;
+ hit_state->rng_hash = bssrdf_rng_hash;
+ path_state_branch(hit_state, j, num_samples);
+
+ ccl_global LocalIntersection *ss_isect = &branched_state->ss_isect;
+ float bssrdf_u, bssrdf_v;
+ path_branched_rng_2D(
+ kg, bssrdf_rng_hash, hit_state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+
+ /* intersection is expensive so avoid doing multiple times for the same input */
+ if (branched_state->next_hit == 0 && branched_state->next_closure == 0 &&
+ branched_state->next_sample == 0) {
+ uint lcg_state = branched_state->lcg_state;
+ LocalIntersection ss_isect_private;
+
+ branched_state->num_hits = subsurface_scatter_multi_intersect(
+ kg, &ss_isect_private, sd, hit_state, sc, &lcg_state, bssrdf_u, bssrdf_v, true);
+
+ branched_state->lcg_state = lcg_state;
+ *ss_isect = ss_isect_private;
+ }
+
+ hit_state->rng_offset += PRNG_BOUNCE_NUM;
+
+# ifdef __VOLUME__
+ Ray volume_ray = branched_state->ray;
+ bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
+ sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
+# endif /* __VOLUME__ */
+
+ /* compute lighting with the BSDF closure */
+ for (int hit = branched_state->next_hit; hit < branched_state->num_hits; hit++) {
+ ShaderData *bssrdf_sd = kernel_split_sd(sd, ray_index);
+ *bssrdf_sd = *sd; /* note: copy happens each iteration of inner loop, this is
+ * important as the indirect path will write into bssrdf_sd */
+
+ LocalIntersection ss_isect_private = *ss_isect;
+ subsurface_scatter_multi_setup(
+ kg, &ss_isect_private, hit, bssrdf_sd, hit_state, bssrdf_type, bssrdf_roughness);
+ *ss_isect = ss_isect_private;
+
+# ifdef __VOLUME__
+ if (need_update_volume_stack) {
+ /* Setup ray from previous surface point to the new one. */
+ float3 P = ray_offset(bssrdf_sd->P, -bssrdf_sd->Ng);
+ volume_ray.D = normalize_len(P - volume_ray.P, &volume_ray.t);
+
+ for (int k = 0; k < VOLUME_STACK_SIZE; k++) {
+ hit_state->volume_stack[k] = branched_state->path_state.volume_stack[k];
+ }
+
+ kernel_volume_stack_update_for_subsurface(
+ kg, emission_sd, &volume_ray, hit_state->volume_stack);
+ }
+# endif /* __VOLUME__ */
+
+# ifdef __EMISSION__
+ if (branched_state->next_closure == 0 && branched_state->next_sample == 0) {
+ /* direct light */
+ if (kernel_data.integrator.use_direct_light) {
+ int all = (kernel_data.integrator.sample_all_lights_direct) ||
+ (hit_state->flag & PATH_RAY_SHADOW_CATCHER);
+ kernel_branched_path_surface_connect_light(kg,
+ bssrdf_sd,
+ emission_sd,
+ hit_state,
+ branched_state->throughput,
+ num_samples_inv,
+ L,
+ all);
+ }
+ }
+# endif /* __EMISSION__ */
+
+ /* indirect light */
+ if (kernel_split_branched_path_surface_indirect_light_iter(
+ kg, ray_index, num_samples_inv, bssrdf_sd, false, false)) {
+ branched_state->ss_next_closure = i;
+ branched_state->ss_next_sample = j;
+ branched_state->next_hit = hit;
+
+ return true;
+ }
+
+ branched_state->next_closure = 0;
+ }
+
+ branched_state->next_hit = 0;
+ }
+
+ branched_state->ss_next_sample = 0;
+ }
+
+ branched_state->ss_next_closure = sd->num_closure;
+
+ branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0);
+ if (branched_state->waiting_on_shared_samples) {
+ return true;
+ }
+
+ kernel_split_branched_path_indirect_loop_end(kg, ray_index);
+
+ return false;
}
-#endif /* __BRANCHED_PATH__ && __SUBSURFACE__ */
+#endif /* __BRANCHED_PATH__ && __SUBSURFACE__ */
ccl_device void kernel_subsurface_scatter(KernelGlobals *kg)
{
- int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- if(thread_index == 0) {
- /* We will empty both queues in this kernel. */
- kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
- kernel_split_params.queue_index[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = 0;
- }
-
- int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
- ray_index = get_ray_index(kg, ray_index,
- QUEUE_ACTIVE_AND_REGENERATED_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
- get_ray_index(kg, thread_index,
- QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
+ int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ if (thread_index == 0) {
+ /* We will empty both queues in this kernel. */
+ kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
+ kernel_split_params.queue_index[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = 0;
+ }
+
+ int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
+ ray_index = get_ray_index(kg,
+ ray_index,
+ QUEUE_ACTIVE_AND_REGENERATED_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+ get_ray_index(kg,
+ thread_index,
+ QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
#ifdef __SUBSURFACE__
- ccl_global char *ray_state = kernel_split_state.ray_state;
-
- if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- ccl_global SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
- ShaderData *sd = kernel_split_sd(sd, ray_index);
- ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
-
- if(sd->flag & SD_BSSRDF) {
-
-#ifdef __BRANCHED_PATH__
- if(!kernel_data.integrator.branched ||
- IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT))
- {
-#endif
- if(kernel_path_subsurface_scatter(kg,
- sd,
- emission_sd,
- L,
- state,
- ray,
- throughput,
- ss_indirect))
- {
- kernel_split_path_end(kg, ray_index);
- }
-#ifdef __BRANCHED_PATH__
- }
- else {
- kernel_split_branched_path_subsurface_indirect_light_init(kg, ray_index);
-
- if(kernel_split_branched_path_subsurface_indirect_light_iter(kg, ray_index)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- }
-#endif
- }
- }
+ ccl_global char *ray_state = kernel_split_state.ray_state;
+
+ if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
+ ccl_global SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
+ ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
+
+ if (sd->flag & SD_BSSRDF) {
# ifdef __BRANCHED_PATH__
- if(ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
- kernel_split_params.queue_index[QUEUE_SUBSURFACE_INDIRECT_ITER] = 0;
- }
-
- /* iter loop */
- ray_index = get_ray_index(kg, ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0),
- QUEUE_SUBSURFACE_INDIRECT_ITER,
- kernel_split_state.queue_data,
- kernel_split_params.queue_size,
- 1);
-
- if(IS_STATE(ray_state, ray_index, RAY_SUBSURFACE_INDIRECT_NEXT_ITER)) {
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- path_radiance_sum_indirect(&kernel_split_state.path_radiance[ray_index]);
- path_radiance_reset_indirect(&kernel_split_state.path_radiance[ray_index]);
-
- if(kernel_split_branched_path_subsurface_indirect_light_iter(kg, ray_index)) {
- ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
- }
- }
-# endif /* __BRANCHED_PATH__ */
-
-#endif /* __SUBSURFACE__ */
+ if (!kernel_data.integrator.branched ||
+ IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
+# endif
+ if (kernel_path_subsurface_scatter(
+ kg, sd, emission_sd, L, state, ray, throughput, ss_indirect)) {
+ kernel_split_path_end(kg, ray_index);
+ }
+# ifdef __BRANCHED_PATH__
+ }
+ else {
+ kernel_split_branched_path_subsurface_indirect_light_init(kg, ray_index);
+
+ if (kernel_split_branched_path_subsurface_indirect_light_iter(kg, ray_index)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ }
+# endif
+ }
+ }
+# ifdef __BRANCHED_PATH__
+ if (ccl_global_id(0) == 0 && ccl_global_id(1) == 0) {
+ kernel_split_params.queue_index[QUEUE_SUBSURFACE_INDIRECT_ITER] = 0;
+ }
+
+ /* iter loop */
+ ray_index = get_ray_index(kg,
+ ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0),
+ QUEUE_SUBSURFACE_INDIRECT_ITER,
+ kernel_split_state.queue_data,
+ kernel_split_params.queue_size,
+ 1);
+
+ if (IS_STATE(ray_state, ray_index, RAY_SUBSURFACE_INDIRECT_NEXT_ITER)) {
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(&kernel_split_state.path_radiance[ray_index]);
+ path_radiance_reset_indirect(&kernel_split_state.path_radiance[ray_index]);
+
+ if (kernel_split_branched_path_subsurface_indirect_light_iter(kg, ray_index)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
+ }
+ }
+# endif /* __BRANCHED_PATH__ */
+
+#endif /* __SUBSURFACE__ */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index ccb9aef7a5b..4a386afa5de 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -46,92 +46,102 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline float3 stack_load_float3(float *stack, uint a)
{
- kernel_assert(a+2 < SVM_STACK_SIZE);
+ kernel_assert(a + 2 < SVM_STACK_SIZE);
- return make_float3(stack[a+0], stack[a+1], stack[a+2]);
+ return make_float3(stack[a + 0], stack[a + 1], stack[a + 2]);
}
ccl_device_inline void stack_store_float3(float *stack, uint a, float3 f)
{
- kernel_assert(a+2 < SVM_STACK_SIZE);
+ kernel_assert(a + 2 < SVM_STACK_SIZE);
- stack[a+0] = f.x;
- stack[a+1] = f.y;
- stack[a+2] = f.z;
+ stack[a + 0] = f.x;
+ stack[a + 1] = f.y;
+ stack[a + 2] = f.z;
}
ccl_device_inline float stack_load_float(float *stack, uint a)
{
- kernel_assert(a < SVM_STACK_SIZE);
+ kernel_assert(a < SVM_STACK_SIZE);
- return stack[a];
+ return stack[a];
}
ccl_device_inline float stack_load_float_default(float *stack, uint a, uint value)
{
- return (a == (uint)SVM_STACK_INVALID)? __uint_as_float(value): stack_load_float(stack, a);
+ return (a == (uint)SVM_STACK_INVALID) ? __uint_as_float(value) : stack_load_float(stack, a);
}
ccl_device_inline void stack_store_float(float *stack, uint a, float f)
{
- kernel_assert(a < SVM_STACK_SIZE);
+ kernel_assert(a < SVM_STACK_SIZE);
- stack[a] = f;
+ stack[a] = f;
}
ccl_device_inline int stack_load_int(float *stack, uint a)
{
- kernel_assert(a < SVM_STACK_SIZE);
+ kernel_assert(a < SVM_STACK_SIZE);
- return __float_as_int(stack[a]);
+ return __float_as_int(stack[a]);
}
ccl_device_inline int stack_load_int_default(float *stack, uint a, uint value)
{
- return (a == (uint)SVM_STACK_INVALID)? (int)value: stack_load_int(stack, a);
+ return (a == (uint)SVM_STACK_INVALID) ? (int)value : stack_load_int(stack, a);
}
ccl_device_inline void stack_store_int(float *stack, uint a, int i)
{
- kernel_assert(a < SVM_STACK_SIZE);
+ kernel_assert(a < SVM_STACK_SIZE);
- stack[a] = __int_as_float(i);
+ stack[a] = __int_as_float(i);
}
ccl_device_inline bool stack_valid(uint a)
{
- return a != (uint)SVM_STACK_INVALID;
+ return a != (uint)SVM_STACK_INVALID;
}
/* Reading Nodes */
ccl_device_inline uint4 read_node(KernelGlobals *kg, int *offset)
{
- uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
- (*offset)++;
- return node;
+ uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
+ (*offset)++;
+ return node;
}
ccl_device_inline float4 read_node_float(KernelGlobals *kg, int *offset)
{
- uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
- float4 f = make_float4(__uint_as_float(node.x), __uint_as_float(node.y), __uint_as_float(node.z), __uint_as_float(node.w));
- (*offset)++;
- return f;
+ uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
+ float4 f = make_float4(__uint_as_float(node.x),
+ __uint_as_float(node.y),
+ __uint_as_float(node.z),
+ __uint_as_float(node.w));
+ (*offset)++;
+ return f;
}
ccl_device_inline float4 fetch_node_float(KernelGlobals *kg, int offset)
{
- uint4 node = kernel_tex_fetch(__svm_nodes, offset);
- return make_float4(__uint_as_float(node.x), __uint_as_float(node.y), __uint_as_float(node.z), __uint_as_float(node.w));
+ uint4 node = kernel_tex_fetch(__svm_nodes, offset);
+ return make_float4(__uint_as_float(node.x),
+ __uint_as_float(node.y),
+ __uint_as_float(node.z),
+ __uint_as_float(node.w));
}
ccl_device_inline void decode_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w)
{
- if(x) *x = (i & 0xFF);
- if(y) *y = ((i >> 8) & 0xFF);
- if(z) *z = ((i >> 16) & 0xFF);
- if(w) *w = ((i >> 24) & 0xFF);
+ if (x)
+ *x = (i & 0xFF);
+ if (y)
+ *y = ((i >> 8) & 0xFF);
+ if (z)
+ *z = ((i >> 16) & 0xFF);
+ if (w)
+ *w = ((i >> 24) & 0xFF);
}
CCL_NAMESPACE_END
@@ -194,302 +204,310 @@ CCL_NAMESPACE_BEGIN
#define NODES_FEATURE(feature) ((__NODES_FEATURES__ & (feature)) != 0)
/* Main Interpreter Loop */
-ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, ShaderType type, int path_flag)
+ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ShaderType type,
+ int path_flag)
{
- float stack[SVM_STACK_SIZE];
- int offset = sd->shader & SHADER_MASK;
+ float stack[SVM_STACK_SIZE];
+ int offset = sd->shader & SHADER_MASK;
- while(1) {
- uint4 node = read_node(kg, &offset);
+ while (1) {
+ uint4 node = read_node(kg, &offset);
- switch(node.x) {
+ switch (node.x) {
#if NODES_GROUP(NODE_GROUP_LEVEL_0)
- case NODE_SHADER_JUMP: {
- if(type == SHADER_TYPE_SURFACE) offset = node.y;
- else if(type == SHADER_TYPE_VOLUME) offset = node.z;
- else if(type == SHADER_TYPE_DISPLACEMENT) offset = node.w;
- else return;
- break;
- }
- case NODE_CLOSURE_BSDF:
- svm_node_closure_bsdf(kg, sd, stack, node, type, path_flag, &offset);
- break;
- case NODE_CLOSURE_EMISSION:
- svm_node_closure_emission(sd, stack, node);
- break;
- case NODE_CLOSURE_BACKGROUND:
- svm_node_closure_background(sd, stack, node);
- break;
- case NODE_CLOSURE_SET_WEIGHT:
- svm_node_closure_set_weight(sd, node.y, node.z, node.w);
- break;
- case NODE_CLOSURE_WEIGHT:
- svm_node_closure_weight(sd, stack, node.y);
- break;
- case NODE_EMISSION_WEIGHT:
- svm_node_emission_weight(kg, sd, stack, node);
- break;
- case NODE_MIX_CLOSURE:
- svm_node_mix_closure(sd, stack, node);
- break;
- case NODE_JUMP_IF_ZERO:
- if(stack_load_float(stack, node.z) == 0.0f)
- offset += node.y;
- break;
- case NODE_JUMP_IF_ONE:
- if(stack_load_float(stack, node.z) == 1.0f)
- offset += node.y;
- break;
- case NODE_GEOMETRY:
- svm_node_geometry(kg, sd, stack, node.y, node.z);
- break;
- case NODE_CONVERT:
- svm_node_convert(kg, sd, stack, node.y, node.z, node.w);
- break;
- case NODE_TEX_COORD:
- svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset);
- break;
- case NODE_VALUE_F:
- svm_node_value_f(kg, sd, stack, node.y, node.z);
- break;
- case NODE_VALUE_V:
- svm_node_value_v(kg, sd, stack, node.y, &offset);
- break;
- case NODE_ATTR:
- svm_node_attr(kg, sd, stack, node);
- break;
+ case NODE_SHADER_JUMP: {
+ if (type == SHADER_TYPE_SURFACE)
+ offset = node.y;
+ else if (type == SHADER_TYPE_VOLUME)
+ offset = node.z;
+ else if (type == SHADER_TYPE_DISPLACEMENT)
+ offset = node.w;
+ else
+ return;
+ break;
+ }
+ case NODE_CLOSURE_BSDF:
+ svm_node_closure_bsdf(kg, sd, stack, node, type, path_flag, &offset);
+ break;
+ case NODE_CLOSURE_EMISSION:
+ svm_node_closure_emission(sd, stack, node);
+ break;
+ case NODE_CLOSURE_BACKGROUND:
+ svm_node_closure_background(sd, stack, node);
+ break;
+ case NODE_CLOSURE_SET_WEIGHT:
+ svm_node_closure_set_weight(sd, node.y, node.z, node.w);
+ break;
+ case NODE_CLOSURE_WEIGHT:
+ svm_node_closure_weight(sd, stack, node.y);
+ break;
+ case NODE_EMISSION_WEIGHT:
+ svm_node_emission_weight(kg, sd, stack, node);
+ break;
+ case NODE_MIX_CLOSURE:
+ svm_node_mix_closure(sd, stack, node);
+ break;
+ case NODE_JUMP_IF_ZERO:
+ if (stack_load_float(stack, node.z) == 0.0f)
+ offset += node.y;
+ break;
+ case NODE_JUMP_IF_ONE:
+ if (stack_load_float(stack, node.z) == 1.0f)
+ offset += node.y;
+ break;
+ case NODE_GEOMETRY:
+ svm_node_geometry(kg, sd, stack, node.y, node.z);
+ break;
+ case NODE_CONVERT:
+ svm_node_convert(kg, sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_TEX_COORD:
+ svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset);
+ break;
+ case NODE_VALUE_F:
+ svm_node_value_f(kg, sd, stack, node.y, node.z);
+ break;
+ case NODE_VALUE_V:
+ svm_node_value_v(kg, sd, stack, node.y, &offset);
+ break;
+ case NODE_ATTR:
+ svm_node_attr(kg, sd, stack, node);
+ break;
# if NODES_FEATURE(NODE_FEATURE_BUMP)
- case NODE_GEOMETRY_BUMP_DX:
- svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
- break;
- case NODE_GEOMETRY_BUMP_DY:
- svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z);
- break;
- case NODE_SET_DISPLACEMENT:
- svm_node_set_displacement(kg, sd, stack, node.y);
- break;
- case NODE_DISPLACEMENT:
- svm_node_displacement(kg, sd, stack, node);
- break;
- case NODE_VECTOR_DISPLACEMENT:
- svm_node_vector_displacement(kg, sd, stack, node, &offset);
- break;
-# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */
+ case NODE_GEOMETRY_BUMP_DX:
+ svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
+ break;
+ case NODE_GEOMETRY_BUMP_DY:
+ svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z);
+ break;
+ case NODE_SET_DISPLACEMENT:
+ svm_node_set_displacement(kg, sd, stack, node.y);
+ break;
+ case NODE_DISPLACEMENT:
+ svm_node_displacement(kg, sd, stack, node);
+ break;
+ case NODE_VECTOR_DISPLACEMENT:
+ svm_node_vector_displacement(kg, sd, stack, node, &offset);
+ break;
+# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */
# ifdef __TEXTURES__
- case NODE_TEX_IMAGE:
- svm_node_tex_image(kg, sd, stack, node);
- break;
- case NODE_TEX_IMAGE_BOX:
- svm_node_tex_image_box(kg, sd, stack, node);
- break;
- case NODE_TEX_NOISE:
- svm_node_tex_noise(kg, sd, stack, node, &offset);
- break;
-# endif /* __TEXTURES__ */
+ case NODE_TEX_IMAGE:
+ svm_node_tex_image(kg, sd, stack, node);
+ break;
+ case NODE_TEX_IMAGE_BOX:
+ svm_node_tex_image_box(kg, sd, stack, node);
+ break;
+ case NODE_TEX_NOISE:
+ svm_node_tex_noise(kg, sd, stack, node, &offset);
+ break;
+# endif /* __TEXTURES__ */
# ifdef __EXTRA_NODES__
# if NODES_FEATURE(NODE_FEATURE_BUMP)
- case NODE_SET_BUMP:
- svm_node_set_bump(kg, sd, stack, node);
- break;
- case NODE_ATTR_BUMP_DX:
- svm_node_attr_bump_dx(kg, sd, stack, node);
- break;
- case NODE_ATTR_BUMP_DY:
- svm_node_attr_bump_dy(kg, sd, stack, node);
- break;
- case NODE_TEX_COORD_BUMP_DX:
- svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, &offset);
- break;
- case NODE_TEX_COORD_BUMP_DY:
- svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, &offset);
- break;
- case NODE_CLOSURE_SET_NORMAL:
- svm_node_set_normal(kg, sd, stack, node.y, node.z);
- break;
+ case NODE_SET_BUMP:
+ svm_node_set_bump(kg, sd, stack, node);
+ break;
+ case NODE_ATTR_BUMP_DX:
+ svm_node_attr_bump_dx(kg, sd, stack, node);
+ break;
+ case NODE_ATTR_BUMP_DY:
+ svm_node_attr_bump_dy(kg, sd, stack, node);
+ break;
+ case NODE_TEX_COORD_BUMP_DX:
+ svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, &offset);
+ break;
+ case NODE_TEX_COORD_BUMP_DY:
+ svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, &offset);
+ break;
+ case NODE_CLOSURE_SET_NORMAL:
+ svm_node_set_normal(kg, sd, stack, node.y, node.z);
+ break;
# if NODES_FEATURE(NODE_FEATURE_BUMP_STATE)
- case NODE_ENTER_BUMP_EVAL:
- svm_node_enter_bump_eval(kg, sd, stack, node.y);
- break;
- case NODE_LEAVE_BUMP_EVAL:
- svm_node_leave_bump_eval(kg, sd, stack, node.y);
- break;
-# endif /* NODES_FEATURE(NODE_FEATURE_BUMP_STATE) */
-# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */
- case NODE_HSV:
- svm_node_hsv(kg, sd, stack, node, &offset);
- break;
-# endif /* __EXTRA_NODES__ */
-#endif /* NODES_GROUP(NODE_GROUP_LEVEL_0) */
+ case NODE_ENTER_BUMP_EVAL:
+ svm_node_enter_bump_eval(kg, sd, stack, node.y);
+ break;
+ case NODE_LEAVE_BUMP_EVAL:
+ svm_node_leave_bump_eval(kg, sd, stack, node.y);
+ break;
+# endif /* NODES_FEATURE(NODE_FEATURE_BUMP_STATE) */
+# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */
+ case NODE_HSV:
+ svm_node_hsv(kg, sd, stack, node, &offset);
+ break;
+# endif /* __EXTRA_NODES__ */
+#endif /* NODES_GROUP(NODE_GROUP_LEVEL_0) */
#if NODES_GROUP(NODE_GROUP_LEVEL_1)
- case NODE_CLOSURE_HOLDOUT:
- svm_node_closure_holdout(sd, stack, node);
- break;
- case NODE_FRESNEL:
- svm_node_fresnel(sd, stack, node.y, node.z, node.w);
- break;
- case NODE_LAYER_WEIGHT:
- svm_node_layer_weight(sd, stack, node);
- break;
+ case NODE_CLOSURE_HOLDOUT:
+ svm_node_closure_holdout(sd, stack, node);
+ break;
+ case NODE_FRESNEL:
+ svm_node_fresnel(sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_LAYER_WEIGHT:
+ svm_node_layer_weight(sd, stack, node);
+ break;
# if NODES_FEATURE(NODE_FEATURE_VOLUME)
- case NODE_CLOSURE_VOLUME:
- svm_node_closure_volume(kg, sd, stack, node, type);
- break;
- case NODE_PRINCIPLED_VOLUME:
- svm_node_principled_volume(kg, sd, stack, node, type, path_flag, &offset);
- break;
-# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */
+ case NODE_CLOSURE_VOLUME:
+ svm_node_closure_volume(kg, sd, stack, node, type);
+ break;
+ case NODE_PRINCIPLED_VOLUME:
+ svm_node_principled_volume(kg, sd, stack, node, type, path_flag, &offset);
+ break;
+# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */
# ifdef __EXTRA_NODES__
- case NODE_MATH:
- svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset);
- break;
- case NODE_VECTOR_MATH:
- svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset);
- break;
- case NODE_RGB_RAMP:
- svm_node_rgb_ramp(kg, sd, stack, node, &offset);
- break;
- case NODE_GAMMA:
- svm_node_gamma(sd, stack, node.y, node.z, node.w);
- break;
- case NODE_BRIGHTCONTRAST:
- svm_node_brightness(sd, stack, node.y, node.z, node.w);
- break;
- case NODE_LIGHT_PATH:
- svm_node_light_path(sd, state, stack, node.y, node.z, path_flag);
- break;
- case NODE_OBJECT_INFO:
- svm_node_object_info(kg, sd, stack, node.y, node.z);
- break;
- case NODE_PARTICLE_INFO:
- svm_node_particle_info(kg, sd, stack, node.y, node.z);
- break;
+ case NODE_MATH:
+ svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset);
+ break;
+ case NODE_VECTOR_MATH:
+ svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset);
+ break;
+ case NODE_RGB_RAMP:
+ svm_node_rgb_ramp(kg, sd, stack, node, &offset);
+ break;
+ case NODE_GAMMA:
+ svm_node_gamma(sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_BRIGHTCONTRAST:
+ svm_node_brightness(sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_LIGHT_PATH:
+ svm_node_light_path(sd, state, stack, node.y, node.z, path_flag);
+ break;
+ case NODE_OBJECT_INFO:
+ svm_node_object_info(kg, sd, stack, node.y, node.z);
+ break;
+ case NODE_PARTICLE_INFO:
+ svm_node_particle_info(kg, sd, stack, node.y, node.z);
+ break;
# ifdef __HAIR__
# if NODES_FEATURE(NODE_FEATURE_HAIR)
- case NODE_HAIR_INFO:
- svm_node_hair_info(kg, sd, stack, node.y, node.z);
- break;
-# endif /* NODES_FEATURE(NODE_FEATURE_HAIR) */
-# endif /* __HAIR__ */
-# endif /* __EXTRA_NODES__ */
-#endif /* NODES_GROUP(NODE_GROUP_LEVEL_1) */
+ case NODE_HAIR_INFO:
+ svm_node_hair_info(kg, sd, stack, node.y, node.z);
+ break;
+# endif /* NODES_FEATURE(NODE_FEATURE_HAIR) */
+# endif /* __HAIR__ */
+# endif /* __EXTRA_NODES__ */
+#endif /* NODES_GROUP(NODE_GROUP_LEVEL_1) */
#if NODES_GROUP(NODE_GROUP_LEVEL_2)
- case NODE_MAPPING:
- svm_node_mapping(kg, sd, stack, node.y, node.z, &offset);
- break;
- case NODE_MIN_MAX:
- svm_node_min_max(kg, sd, stack, node.y, node.z, &offset);
- break;
- case NODE_CAMERA:
- svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
- break;
+ case NODE_MAPPING:
+ svm_node_mapping(kg, sd, stack, node.y, node.z, &offset);
+ break;
+ case NODE_MIN_MAX:
+ svm_node_min_max(kg, sd, stack, node.y, node.z, &offset);
+ break;
+ case NODE_CAMERA:
+ svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
+ break;
# ifdef __TEXTURES__
- case NODE_TEX_ENVIRONMENT:
- svm_node_tex_environment(kg, sd, stack, node);
- break;
- case NODE_TEX_SKY:
- svm_node_tex_sky(kg, sd, stack, node, &offset);
- break;
- case NODE_TEX_GRADIENT:
- svm_node_tex_gradient(sd, stack, node);
- break;
- case NODE_TEX_VORONOI:
- svm_node_tex_voronoi(kg, sd, stack, node, &offset);
- break;
- case NODE_TEX_MUSGRAVE:
- svm_node_tex_musgrave(kg, sd, stack, node, &offset);
- break;
- case NODE_TEX_WAVE:
- svm_node_tex_wave(kg, sd, stack, node, &offset);
- break;
- case NODE_TEX_MAGIC:
- svm_node_tex_magic(kg, sd, stack, node, &offset);
- break;
- case NODE_TEX_CHECKER:
- svm_node_tex_checker(kg, sd, stack, node);
- break;
- case NODE_TEX_BRICK:
- svm_node_tex_brick(kg, sd, stack, node, &offset);
- break;
-# endif /* __TEXTURES__ */
+ case NODE_TEX_ENVIRONMENT:
+ svm_node_tex_environment(kg, sd, stack, node);
+ break;
+ case NODE_TEX_SKY:
+ svm_node_tex_sky(kg, sd, stack, node, &offset);
+ break;
+ case NODE_TEX_GRADIENT:
+ svm_node_tex_gradient(sd, stack, node);
+ break;
+ case NODE_TEX_VORONOI:
+ svm_node_tex_voronoi(kg, sd, stack, node, &offset);
+ break;
+ case NODE_TEX_MUSGRAVE:
+ svm_node_tex_musgrave(kg, sd, stack, node, &offset);
+ break;
+ case NODE_TEX_WAVE:
+ svm_node_tex_wave(kg, sd, stack, node, &offset);
+ break;
+ case NODE_TEX_MAGIC:
+ svm_node_tex_magic(kg, sd, stack, node, &offset);
+ break;
+ case NODE_TEX_CHECKER:
+ svm_node_tex_checker(kg, sd, stack, node);
+ break;
+ case NODE_TEX_BRICK:
+ svm_node_tex_brick(kg, sd, stack, node, &offset);
+ break;
+# endif /* __TEXTURES__ */
# ifdef __EXTRA_NODES__
- case NODE_NORMAL:
- svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset);
- break;
- case NODE_LIGHT_FALLOFF:
- svm_node_light_falloff(sd, stack, node);
- break;
- case NODE_IES:
- svm_node_ies(kg, sd, stack, node, &offset);
- break;
-# endif /* __EXTRA_NODES__ */
-#endif /* NODES_GROUP(NODE_GROUP_LEVEL_2) */
+ case NODE_NORMAL:
+ svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset);
+ break;
+ case NODE_LIGHT_FALLOFF:
+ svm_node_light_falloff(sd, stack, node);
+ break;
+ case NODE_IES:
+ svm_node_ies(kg, sd, stack, node, &offset);
+ break;
+# endif /* __EXTRA_NODES__ */
+#endif /* NODES_GROUP(NODE_GROUP_LEVEL_2) */
#if NODES_GROUP(NODE_GROUP_LEVEL_3)
- case NODE_RGB_CURVES:
- case NODE_VECTOR_CURVES:
- svm_node_curves(kg, sd, stack, node, &offset);
- break;
- case NODE_TANGENT:
- svm_node_tangent(kg, sd, stack, node);
- break;
- case NODE_NORMAL_MAP:
- svm_node_normal_map(kg, sd, stack, node);
- break;
+ case NODE_RGB_CURVES:
+ case NODE_VECTOR_CURVES:
+ svm_node_curves(kg, sd, stack, node, &offset);
+ break;
+ case NODE_TANGENT:
+ svm_node_tangent(kg, sd, stack, node);
+ break;
+ case NODE_NORMAL_MAP:
+ svm_node_normal_map(kg, sd, stack, node);
+ break;
# ifdef __EXTRA_NODES__
- case NODE_INVERT:
- svm_node_invert(sd, stack, node.y, node.z, node.w);
- break;
- case NODE_MIX:
- svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset);
- break;
- case NODE_SEPARATE_VECTOR:
- svm_node_separate_vector(sd, stack, node.y, node.z, node.w);
- break;
- case NODE_COMBINE_VECTOR:
- svm_node_combine_vector(sd, stack, node.y, node.z, node.w);
- break;
- case NODE_SEPARATE_HSV:
- svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, &offset);
- break;
- case NODE_COMBINE_HSV:
- svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, &offset);
- break;
- case NODE_VECTOR_TRANSFORM:
- svm_node_vector_transform(kg, sd, stack, node);
- break;
- case NODE_WIREFRAME:
- svm_node_wireframe(kg, sd, stack, node);
- break;
- case NODE_WAVELENGTH:
- svm_node_wavelength(kg, sd, stack, node.y, node.z);
- break;
- case NODE_BLACKBODY:
- svm_node_blackbody(kg, sd, stack, node.y, node.z);
- break;
-# endif /* __EXTRA_NODES__ */
+ case NODE_INVERT:
+ svm_node_invert(sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_MIX:
+ svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset);
+ break;
+ case NODE_SEPARATE_VECTOR:
+ svm_node_separate_vector(sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_COMBINE_VECTOR:
+ svm_node_combine_vector(sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_SEPARATE_HSV:
+ svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, &offset);
+ break;
+ case NODE_COMBINE_HSV:
+ svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, &offset);
+ break;
+ case NODE_VECTOR_TRANSFORM:
+ svm_node_vector_transform(kg, sd, stack, node);
+ break;
+ case NODE_WIREFRAME:
+ svm_node_wireframe(kg, sd, stack, node);
+ break;
+ case NODE_WAVELENGTH:
+ svm_node_wavelength(kg, sd, stack, node.y, node.z);
+ break;
+ case NODE_BLACKBODY:
+ svm_node_blackbody(kg, sd, stack, node.y, node.z);
+ break;
+# endif /* __EXTRA_NODES__ */
# if NODES_FEATURE(NODE_FEATURE_VOLUME)
- case NODE_TEX_VOXEL:
- svm_node_tex_voxel(kg, sd, stack, node, &offset);
- break;
-# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */
+ case NODE_TEX_VOXEL:
+ svm_node_tex_voxel(kg, sd, stack, node, &offset);
+ break;
+# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */
# ifdef __SHADER_RAYTRACE__
- case NODE_BEVEL:
- svm_node_bevel(kg, sd, state, stack, node);
- break;
- case NODE_AMBIENT_OCCLUSION:
- svm_node_ao(kg, sd, state, stack, node);
- break;
-# endif /* __SHADER_RAYTRACE__ */
-#endif /* NODES_GROUP(NODE_GROUP_LEVEL_3) */
- case NODE_END:
- return;
- default:
- kernel_assert(!"Unknown node type was passed to the SVM machine");
- return;
- }
- }
+ case NODE_BEVEL:
+ svm_node_bevel(kg, sd, state, stack, node);
+ break;
+ case NODE_AMBIENT_OCCLUSION:
+ svm_node_ao(kg, sd, state, stack, node);
+ break;
+# endif /* __SHADER_RAYTRACE__ */
+#endif /* NODES_GROUP(NODE_GROUP_LEVEL_3) */
+ case NODE_END:
+ return;
+ default:
+ kernel_assert(!"Unknown node type was passed to the SVM machine");
+ return;
+ }
+ }
}
#undef NODES_GROUP
@@ -497,4 +515,4 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
CCL_NAMESPACE_END
-#endif /* __SVM_H__ */
+#endif /* __SVM_H__ */
diff --git a/intern/cycles/kernel/svm/svm_ao.h b/intern/cycles/kernel/svm/svm_ao.h
index 0744ec1768f..06076175c40 100644
--- a/intern/cycles/kernel/svm/svm_ao.h
+++ b/intern/cycles/kernel/svm/svm_ao.h
@@ -24,95 +24,82 @@ ccl_device_noinline float svm_ao(KernelGlobals *kg,
int num_samples,
int flags)
{
- if(flags & NODE_AO_GLOBAL_RADIUS) {
- max_dist = kernel_data.background.ao_distance;
- }
-
- /* Early out if no sampling needed. */
- if(max_dist <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) {
- return 1.0f;
- }
-
- /* Can't raytrace from shaders like displacement, before BVH exists. */
- if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
- return 1.0f;
- }
-
- if(flags & NODE_AO_INSIDE) {
- N = -N;
- }
-
- float3 T, B;
- make_orthonormals(N, &T, &B);
-
- int unoccluded = 0;
- for(int sample = 0; sample < num_samples; sample++) {
- float disk_u, disk_v;
- path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples,
- PRNG_BEVEL_U, &disk_u, &disk_v);
-
- float2 d = concentric_sample_disk(disk_u, disk_v);
- float3 D = make_float3(d.x, d.y, safe_sqrtf(1.0f - dot(d, d)));
-
- /* Create ray. */
- Ray ray;
- ray.P = ray_offset(sd->P, N);
- ray.D = D.x*T + D.y*B + D.z*N;
- ray.t = max_dist;
- ray.time = sd->time;
- ray.dP = sd->dP;
- ray.dD = differential3_zero();
-
- if(flags & NODE_AO_ONLY_LOCAL) {
- if(!scene_intersect_local(kg,
- ray,
- NULL,
- sd->object,
- NULL,
- 0)) {
- unoccluded++;
- }
- }
- else {
- Intersection isect;
- if(!scene_intersect(kg,
- ray,
- PATH_RAY_SHADOW_OPAQUE,
- &isect,
- NULL,
- 0.0f, 0.0f)) {
- unoccluded++;
- }
- }
- }
-
- return ((float) unoccluded) / num_samples;
+ if (flags & NODE_AO_GLOBAL_RADIUS) {
+ max_dist = kernel_data.background.ao_distance;
+ }
+
+ /* Early out if no sampling needed. */
+ if (max_dist <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) {
+ return 1.0f;
+ }
+
+ /* Can't raytrace from shaders like displacement, before BVH exists. */
+ if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
+ return 1.0f;
+ }
+
+ if (flags & NODE_AO_INSIDE) {
+ N = -N;
+ }
+
+ float3 T, B;
+ make_orthonormals(N, &T, &B);
+
+ int unoccluded = 0;
+ for (int sample = 0; sample < num_samples; sample++) {
+ float disk_u, disk_v;
+ path_branched_rng_2D(
+ kg, state->rng_hash, state, sample, num_samples, PRNG_BEVEL_U, &disk_u, &disk_v);
+
+ float2 d = concentric_sample_disk(disk_u, disk_v);
+ float3 D = make_float3(d.x, d.y, safe_sqrtf(1.0f - dot(d, d)));
+
+ /* Create ray. */
+ Ray ray;
+ ray.P = ray_offset(sd->P, N);
+ ray.D = D.x * T + D.y * B + D.z * N;
+ ray.t = max_dist;
+ ray.time = sd->time;
+ ray.dP = sd->dP;
+ ray.dD = differential3_zero();
+
+ if (flags & NODE_AO_ONLY_LOCAL) {
+ if (!scene_intersect_local(kg, ray, NULL, sd->object, NULL, 0)) {
+ unoccluded++;
+ }
+ }
+ else {
+ Intersection isect;
+ if (!scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f)) {
+ unoccluded++;
+ }
+ }
+ }
+
+ return ((float)unoccluded) / num_samples;
}
-ccl_device void svm_node_ao(KernelGlobals *kg,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- float *stack,
- uint4 node)
+ccl_device void svm_node_ao(
+ KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, float *stack, uint4 node)
{
- uint flags, dist_offset, normal_offset, out_ao_offset;
- decode_node_uchar4(node.y, &flags, &dist_offset, &normal_offset, &out_ao_offset);
+ uint flags, dist_offset, normal_offset, out_ao_offset;
+ decode_node_uchar4(node.y, &flags, &dist_offset, &normal_offset, &out_ao_offset);
- uint color_offset, out_color_offset, samples;
- decode_node_uchar4(node.z, &color_offset, &out_color_offset, &samples, NULL);
+ uint color_offset, out_color_offset, samples;
+ decode_node_uchar4(node.z, &color_offset, &out_color_offset, &samples, NULL);
- float dist = stack_load_float_default(stack, dist_offset, node.w);
- float3 normal = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N;
- float ao = svm_ao(kg, sd, normal, state, dist, samples, flags);
+ float dist = stack_load_float_default(stack, dist_offset, node.w);
+ float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
+ float ao = svm_ao(kg, sd, normal, state, dist, samples, flags);
- if(stack_valid(out_ao_offset)) {
- stack_store_float(stack, out_ao_offset, ao);
- }
+ if (stack_valid(out_ao_offset)) {
+ stack_store_float(stack, out_ao_offset, ao);
+ }
- if(stack_valid(out_color_offset)) {
- float3 color = stack_load_float3(stack, color_offset);
- stack_store_float3(stack, out_color_offset, ao * color);
- }
+ if (stack_valid(out_color_offset)) {
+ float3 color = stack_load_float3(stack, color_offset);
+ stack_store_float3(stack, out_color_offset, ao * color);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index c2366df71d0..a67cfe91a30 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -18,67 +18,66 @@ CCL_NAMESPACE_BEGIN
/* Attribute Node */
-ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
- uint4 node, NodeAttributeType *type,
- uint *out_offset)
+ccl_device AttributeDescriptor svm_node_attr_init(
+ KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, uint *out_offset)
{
- *out_offset = node.z;
- *type = (NodeAttributeType)node.w;
+ *out_offset = node.z;
+ *type = (NodeAttributeType)node.w;
- AttributeDescriptor desc;
+ AttributeDescriptor desc;
- if(sd->object != OBJECT_NONE) {
- desc = find_attribute(kg, sd, node.y);
- if(desc.offset == ATTR_STD_NOT_FOUND) {
- desc = attribute_not_found();
- desc.offset = 0;
- desc.type = (NodeAttributeType)node.w;
- }
- }
- else {
- /* background */
- desc = attribute_not_found();
- desc.offset = 0;
- desc.type = (NodeAttributeType)node.w;
- }
+ if (sd->object != OBJECT_NONE) {
+ desc = find_attribute(kg, sd, node.y);
+ if (desc.offset == ATTR_STD_NOT_FOUND) {
+ desc = attribute_not_found();
+ desc.offset = 0;
+ desc.type = (NodeAttributeType)node.w;
+ }
+ }
+ else {
+ /* background */
+ desc = attribute_not_found();
+ desc.offset = 0;
+ desc.type = (NodeAttributeType)node.w;
+ }
- return desc;
+ return desc;
}
ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- NodeAttributeType type;
- uint out_offset;
- AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
+ NodeAttributeType type;
+ uint out_offset;
+ AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
- /* fetch and store attribute */
- if(desc.type == NODE_ATTR_FLOAT) {
- float f = primitive_attribute_float(kg, sd, desc, NULL, NULL);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, f);
- }
- else {
- stack_store_float3(stack, out_offset, make_float3(f, f, f));
- }
- }
- else if(desc.type == NODE_ATTR_FLOAT2) {
- float2 f = primitive_attribute_float2(kg, sd, desc, NULL, NULL);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, f.x);
- }
- else {
- stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
- }
- }
- else {
- float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, average(f));
- }
- else {
- stack_store_float3(stack, out_offset, f);
- }
- }
+ /* fetch and store attribute */
+ if (desc.type == NODE_ATTR_FLOAT) {
+ float f = primitive_attribute_float(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, f);
+ }
+ else {
+ stack_store_float3(stack, out_offset, make_float3(f, f, f));
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 f = primitive_attribute_float2(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, f.x);
+ }
+ else {
+ stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
+ }
+ }
+ else {
+ float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, average(f));
+ }
+ else {
+ stack_store_float3(stack, out_offset, f);
+ }
+ }
}
#ifndef __KERNEL_CUDA__
@@ -86,43 +85,44 @@ ccl_device
#else
ccl_device_noinline
#endif
-void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
+ void
+ svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- NodeAttributeType type;
- uint out_offset;
- AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
+ NodeAttributeType type;
+ uint out_offset;
+ AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
- /* fetch and store attribute */
- if(desc.type == NODE_ATTR_FLOAT) {
- float dx;
- float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, f+dx);
- }
- else {
- stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
- }
- }
- else if(desc.type == NODE_ATTR_FLOAT2) {
- float2 dx;
- float2 f = primitive_attribute_float2(kg, sd, desc, &dx, NULL);
- if (type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, f.x + dx.x);
- }
- else {
- stack_store_float3(stack, out_offset, make_float3(f.x+dx.x, f.y+dx.y, 0.0f));
- }
- }
- else {
- float3 dx;
- float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, average(f+dx));
- }
- else {
- stack_store_float3(stack, out_offset, f+dx);
- }
- }
+ /* fetch and store attribute */
+ if (desc.type == NODE_ATTR_FLOAT) {
+ float dx;
+ float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, f + dx);
+ }
+ else {
+ stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx));
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 dx;
+ float2 f = primitive_attribute_float2(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, f.x + dx.x);
+ }
+ else {
+ stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
+ }
+ }
+ else {
+ float3 dx;
+ float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, average(f + dx));
+ }
+ else {
+ stack_store_float3(stack, out_offset, f + dx);
+ }
+ }
}
#ifndef __KERNEL_CUDA__
@@ -130,46 +130,44 @@ ccl_device
#else
ccl_device_noinline
#endif
-void svm_node_attr_bump_dy(KernelGlobals *kg,
- ShaderData *sd,
- float *stack,
- uint4 node)
+ void
+ svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- NodeAttributeType type;
- uint out_offset;
- AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
+ NodeAttributeType type;
+ uint out_offset;
+ AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
- /* fetch and store attribute */
- if(desc.type == NODE_ATTR_FLOAT) {
- float dy;
- float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, f+dy);
- }
- else {
- stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
- }
- }
- else if(desc.type == NODE_ATTR_FLOAT2) {
- float2 dy;
- float2 f = primitive_attribute_float2(kg, sd, desc, NULL, &dy);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, f.x + dy.x);
- }
- else {
- stack_store_float3(stack, out_offset, make_float3(f.x+dy.x, f.y+dy.y, 0.0f));
- }
- }
- else {
- float3 dy;
- float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
- if(type == NODE_ATTR_FLOAT) {
- stack_store_float(stack, out_offset, average(f+dy));
- }
- else {
- stack_store_float3(stack, out_offset, f+dy);
- }
- }
+ /* fetch and store attribute */
+ if (desc.type == NODE_ATTR_FLOAT) {
+ float dy;
+ float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, f + dy);
+ }
+ else {
+ stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy));
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 dy;
+ float2 f = primitive_attribute_float2(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, f.x + dy.x);
+ }
+ else {
+ stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
+ }
+ }
+ else {
+ float3 dy;
+ float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, average(f + dy));
+ }
+ else {
+ stack_store_float3(stack, out_offset, f + dy);
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_bevel.h b/intern/cycles/kernel/svm/svm_bevel.h
index b5bb9df422b..fcf28e96e98 100644
--- a/intern/cycles/kernel/svm/svm_bevel.h
+++ b/intern/cycles/kernel/svm/svm_bevel.h
@@ -22,215 +22,196 @@ CCL_NAMESPACE_BEGIN
* http://library.imageworks.com/pdfs/imageworks-library-BSSRDF-sampling.pdf
*/
-ccl_device_noinline float3 svm_bevel(
- KernelGlobals *kg,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- float radius,
- int num_samples)
+ccl_device_noinline float3 svm_bevel(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ float radius,
+ int num_samples)
{
- /* Early out if no sampling needed. */
- if(radius <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) {
- return sd->N;
- }
-
- /* Can't raytrace from shaders like displacement, before BVH exists. */
- if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
- return sd->N;
- }
-
- /* Don't bevel for blurry indirect rays. */
- if(state->min_ray_pdf < 8.0f) {
- return sd->N;
- }
-
- /* Setup for multi intersection. */
- LocalIntersection isect;
- uint lcg_state = lcg_state_init_addrspace(state, 0x64c6a40e);
-
- /* Sample normals from surrounding points on surface. */
- float3 sum_N = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int sample = 0; sample < num_samples; sample++) {
- float disk_u, disk_v;
- path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples,
- PRNG_BEVEL_U, &disk_u, &disk_v);
-
- /* Pick random axis in local frame and point on disk. */
- float3 disk_N, disk_T, disk_B;
- float pick_pdf_N, pick_pdf_T, pick_pdf_B;
-
- disk_N = sd->Ng;
- make_orthonormals(disk_N, &disk_T, &disk_B);
-
- float axisu = disk_u;
-
- if(axisu < 0.5f) {
- pick_pdf_N = 0.5f;
- pick_pdf_T = 0.25f;
- pick_pdf_B = 0.25f;
- disk_u *= 2.0f;
- }
- else if(axisu < 0.75f) {
- float3 tmp = disk_N;
- disk_N = disk_T;
- disk_T = tmp;
- pick_pdf_N = 0.25f;
- pick_pdf_T = 0.5f;
- pick_pdf_B = 0.25f;
- disk_u = (disk_u - 0.5f)*4.0f;
- }
- else {
- float3 tmp = disk_N;
- disk_N = disk_B;
- disk_B = tmp;
- pick_pdf_N = 0.25f;
- pick_pdf_T = 0.25f;
- pick_pdf_B = 0.5f;
- disk_u = (disk_u - 0.75f)*4.0f;
- }
-
- /* Sample point on disk. */
- float phi = M_2PI_F * disk_u;
- float disk_r = disk_v;
- float disk_height;
-
- /* Perhaps find something better than Cubic BSSRDF, but happens to work well. */
- bssrdf_cubic_sample(radius, 0.0f, disk_r, &disk_r, &disk_height);
-
- float3 disk_P = (disk_r*cosf(phi)) * disk_T + (disk_r*sinf(phi)) * disk_B;
-
- /* Create ray. */
- Ray *ray = &isect.ray;
- ray->P = sd->P + disk_N*disk_height + disk_P;
- ray->D = -disk_N;
- ray->t = 2.0f*disk_height;
- ray->dP = sd->dP;
- ray->dD = differential3_zero();
- ray->time = sd->time;
-
- /* Intersect with the same object. if multiple intersections are found it
- * will use at most LOCAL_MAX_HITS hits, a random subset of all hits. */
- scene_intersect_local(kg,
- *ray,
- &isect,
- sd->object,
- &lcg_state,
- LOCAL_MAX_HITS);
-
- int num_eval_hits = min(isect.num_hits, LOCAL_MAX_HITS);
-
- for(int hit = 0; hit < num_eval_hits; hit++) {
- /* Quickly retrieve P and Ng without setting up ShaderData. */
- float3 hit_P;
- if(sd->type & PRIMITIVE_TRIANGLE) {
- hit_P = triangle_refine_local(kg,
- sd,
- &isect.hits[hit],
- ray);
- }
+ /* Early out if no sampling needed. */
+ if (radius <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) {
+ return sd->N;
+ }
+
+ /* Can't raytrace from shaders like displacement, before BVH exists. */
+ if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
+ return sd->N;
+ }
+
+ /* Don't bevel for blurry indirect rays. */
+ if (state->min_ray_pdf < 8.0f) {
+ return sd->N;
+ }
+
+ /* Setup for multi intersection. */
+ LocalIntersection isect;
+ uint lcg_state = lcg_state_init_addrspace(state, 0x64c6a40e);
+
+ /* Sample normals from surrounding points on surface. */
+ float3 sum_N = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int sample = 0; sample < num_samples; sample++) {
+ float disk_u, disk_v;
+ path_branched_rng_2D(
+ kg, state->rng_hash, state, sample, num_samples, PRNG_BEVEL_U, &disk_u, &disk_v);
+
+ /* Pick random axis in local frame and point on disk. */
+ float3 disk_N, disk_T, disk_B;
+ float pick_pdf_N, pick_pdf_T, pick_pdf_B;
+
+ disk_N = sd->Ng;
+ make_orthonormals(disk_N, &disk_T, &disk_B);
+
+ float axisu = disk_u;
+
+ if (axisu < 0.5f) {
+ pick_pdf_N = 0.5f;
+ pick_pdf_T = 0.25f;
+ pick_pdf_B = 0.25f;
+ disk_u *= 2.0f;
+ }
+ else if (axisu < 0.75f) {
+ float3 tmp = disk_N;
+ disk_N = disk_T;
+ disk_T = tmp;
+ pick_pdf_N = 0.25f;
+ pick_pdf_T = 0.5f;
+ pick_pdf_B = 0.25f;
+ disk_u = (disk_u - 0.5f) * 4.0f;
+ }
+ else {
+ float3 tmp = disk_N;
+ disk_N = disk_B;
+ disk_B = tmp;
+ pick_pdf_N = 0.25f;
+ pick_pdf_T = 0.25f;
+ pick_pdf_B = 0.5f;
+ disk_u = (disk_u - 0.75f) * 4.0f;
+ }
+
+ /* Sample point on disk. */
+ float phi = M_2PI_F * disk_u;
+ float disk_r = disk_v;
+ float disk_height;
+
+ /* Perhaps find something better than Cubic BSSRDF, but happens to work well. */
+ bssrdf_cubic_sample(radius, 0.0f, disk_r, &disk_r, &disk_height);
+
+ float3 disk_P = (disk_r * cosf(phi)) * disk_T + (disk_r * sinf(phi)) * disk_B;
+
+ /* Create ray. */
+ Ray *ray = &isect.ray;
+ ray->P = sd->P + disk_N * disk_height + disk_P;
+ ray->D = -disk_N;
+ ray->t = 2.0f * disk_height;
+ ray->dP = sd->dP;
+ ray->dD = differential3_zero();
+ ray->time = sd->time;
+
+ /* Intersect with the same object. if multiple intersections are found it
+ * will use at most LOCAL_MAX_HITS hits, a random subset of all hits. */
+ scene_intersect_local(kg, *ray, &isect, sd->object, &lcg_state, LOCAL_MAX_HITS);
+
+ int num_eval_hits = min(isect.num_hits, LOCAL_MAX_HITS);
+
+ for (int hit = 0; hit < num_eval_hits; hit++) {
+ /* Quickly retrieve P and Ng without setting up ShaderData. */
+ float3 hit_P;
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ hit_P = triangle_refine_local(kg, sd, &isect.hits[hit], ray);
+ }
#ifdef __OBJECT_MOTION__
- else if(sd->type & PRIMITIVE_MOTION_TRIANGLE) {
- float3 verts[3];
- motion_triangle_vertices(
- kg,
- sd->object,
- kernel_tex_fetch(__prim_index, isect.hits[hit].prim),
- sd->time,
- verts);
- hit_P = motion_triangle_refine_local(kg,
- sd,
- &isect.hits[hit],
- ray,
- verts);
- }
-#endif /* __OBJECT_MOTION__ */
-
- /* Get geometric normal. */
- float3 hit_Ng = isect.Ng[hit];
- int object = (isect.hits[hit].object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, isect.hits[hit].prim): isect.hits[hit].object;
- int object_flag = kernel_tex_fetch(__object_flag, object);
- if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
- hit_Ng = -hit_Ng;
- }
-
- /* Compute smooth normal. */
- float3 N = hit_Ng;
- int prim = kernel_tex_fetch(__prim_index, isect.hits[hit].prim);
- int shader = kernel_tex_fetch(__tri_shader, prim);
-
- if(shader & SHADER_SMOOTH_NORMAL) {
- float u = isect.hits[hit].u;
- float v = isect.hits[hit].v;
-
- if(sd->type & PRIMITIVE_TRIANGLE) {
- N = triangle_smooth_normal(kg, N, prim, u, v);
- }
+ else if (sd->type & PRIMITIVE_MOTION_TRIANGLE) {
+ float3 verts[3];
+ motion_triangle_vertices(
+ kg, sd->object, kernel_tex_fetch(__prim_index, isect.hits[hit].prim), sd->time, verts);
+ hit_P = motion_triangle_refine_local(kg, sd, &isect.hits[hit], ray, verts);
+ }
+#endif /* __OBJECT_MOTION__ */
+
+ /* Get geometric normal. */
+ float3 hit_Ng = isect.Ng[hit];
+ int object = (isect.hits[hit].object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, isect.hits[hit].prim) :
+ isect.hits[hit].object;
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
+ hit_Ng = -hit_Ng;
+ }
+
+ /* Compute smooth normal. */
+ float3 N = hit_Ng;
+ int prim = kernel_tex_fetch(__prim_index, isect.hits[hit].prim);
+ int shader = kernel_tex_fetch(__tri_shader, prim);
+
+ if (shader & SHADER_SMOOTH_NORMAL) {
+ float u = isect.hits[hit].u;
+ float v = isect.hits[hit].v;
+
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ N = triangle_smooth_normal(kg, N, prim, u, v);
+ }
#ifdef __OBJECT_MOTION__
- else if(sd->type & PRIMITIVE_MOTION_TRIANGLE) {
- N = motion_triangle_smooth_normal(kg, N, sd->object, prim, u, v, sd->time);
- }
-#endif /* __OBJECT_MOTION__ */
- }
-
- /* Transform normals to world space. */
- if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_normal_transform(kg, sd, &N);
- object_normal_transform(kg, sd, &hit_Ng);
- }
-
- /* Probability densities for local frame axes. */
- float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng));
- float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng));
- float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng));
-
- /* Multiple importance sample between 3 axes, power heuristic
- * found to be slightly better than balance heuristic. pdf_N
- * in the MIS weight and denominator cancelled out. */
- float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B));
- if(isect.num_hits > LOCAL_MAX_HITS) {
- w *= isect.num_hits/(float)LOCAL_MAX_HITS;
- }
-
- /* Real distance to sampled point. */
- float r = len(hit_P - sd->P);
-
- /* Compute weight. */
- float pdf = bssrdf_cubic_pdf(radius, 0.0f, r);
- float disk_pdf = bssrdf_cubic_pdf(radius, 0.0f, disk_r);
-
- w *= pdf / disk_pdf;
-
- /* Sum normal and weight. */
- sum_N += w * N;
- }
- }
-
- /* Normalize. */
- float3 N = safe_normalize(sum_N);
- return is_zero(N) ? sd->N : (sd->flag & SD_BACKFACING) ? -N : N;
+ else if (sd->type & PRIMITIVE_MOTION_TRIANGLE) {
+ N = motion_triangle_smooth_normal(kg, N, sd->object, prim, u, v, sd->time);
+ }
+#endif /* __OBJECT_MOTION__ */
+ }
+
+ /* Transform normals to world space. */
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_normal_transform(kg, sd, &N);
+ object_normal_transform(kg, sd, &hit_Ng);
+ }
+
+ /* Probability densities for local frame axes. */
+ float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng));
+ float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng));
+ float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng));
+
+ /* Multiple importance sample between 3 axes, power heuristic
+ * found to be slightly better than balance heuristic. pdf_N
+ * in the MIS weight and denominator cancelled out. */
+ float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B));
+ if (isect.num_hits > LOCAL_MAX_HITS) {
+ w *= isect.num_hits / (float)LOCAL_MAX_HITS;
+ }
+
+ /* Real distance to sampled point. */
+ float r = len(hit_P - sd->P);
+
+ /* Compute weight. */
+ float pdf = bssrdf_cubic_pdf(radius, 0.0f, r);
+ float disk_pdf = bssrdf_cubic_pdf(radius, 0.0f, disk_r);
+
+ w *= pdf / disk_pdf;
+
+ /* Sum normal and weight. */
+ sum_N += w * N;
+ }
+ }
+
+ /* Normalize. */
+ float3 N = safe_normalize(sum_N);
+ return is_zero(N) ? sd->N : (sd->flag & SD_BACKFACING) ? -N : N;
}
ccl_device void svm_node_bevel(
- KernelGlobals *kg,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- float *stack,
- uint4 node)
+ KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, float *stack, uint4 node)
{
- uint num_samples, radius_offset, normal_offset, out_offset;
- decode_node_uchar4(node.y, &num_samples, &radius_offset, &normal_offset, &out_offset);
+ uint num_samples, radius_offset, normal_offset, out_offset;
+ decode_node_uchar4(node.y, &num_samples, &radius_offset, &normal_offset, &out_offset);
- float radius = stack_load_float(stack, radius_offset);
- float3 bevel_N = svm_bevel(kg, sd, state, radius, num_samples);
+ float radius = stack_load_float(stack, radius_offset);
+ float3 bevel_N = svm_bevel(kg, sd, state, radius, num_samples);
- if(stack_valid(normal_offset)) {
- /* Preserve input normal. */
- float3 ref_N = stack_load_float3(stack, normal_offset);
- bevel_N = normalize(ref_N + (bevel_N - sd->N));
- }
+ if (stack_valid(normal_offset)) {
+ /* Preserve input normal. */
+ float3 ref_N = stack_load_float3(stack, normal_offset);
+ bevel_N = normalize(ref_N + (bevel_N - sd->N));
+ }
- stack_store_float3(stack, out_offset, bevel_N);
+ stack_store_float3(stack, out_offset, bevel_N);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_blackbody.h b/intern/cycles/kernel/svm/svm_blackbody.h
index 51590b18505..adfc50d961e 100644
--- a/intern/cycles/kernel/svm/svm_blackbody.h
+++ b/intern/cycles/kernel/svm/svm_blackbody.h
@@ -34,14 +34,15 @@ CCL_NAMESPACE_BEGIN
/* Blackbody Node */
-ccl_device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset)
+ccl_device void svm_node_blackbody(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset)
{
- /* Input */
- float temperature = stack_load_float(stack, temperature_offset);
+ /* Input */
+ float temperature = stack_load_float(stack, temperature_offset);
- float3 color_rgb = svm_math_blackbody_color(temperature);
+ float3 color_rgb = svm_math_blackbody_color(temperature);
- stack_store_float3(stack, col_offset, color_rgb);
+ stack_store_float3(stack, col_offset, color_rgb);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h
index 744d9ff16c5..b5cbfcc72df 100644
--- a/intern/cycles/kernel/svm/svm_brick.h
+++ b/intern/cycles/kernel/svm/svm_brick.h
@@ -20,101 +20,119 @@ CCL_NAMESPACE_BEGIN
ccl_device_noinline float brick_noise(uint n) /* fast integer noise */
{
- uint nn;
- n = (n + 1013) & 0x7fffffff;
- n = (n >> 13) ^ n;
- nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
- return 0.5f * ((float)nn / 1073741824.0f);
+ uint nn;
+ n = (n + 1013) & 0x7fffffff;
+ n = (n >> 13) ^ n;
+ nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
+ return 0.5f * ((float)nn / 1073741824.0f);
}
-ccl_device_noinline float2 svm_brick(float3 p, float mortar_size, float mortar_smooth, float bias,
- float brick_width, float row_height, float offset_amount, int offset_frequency,
- float squash_amount, int squash_frequency)
+ccl_device_noinline float2 svm_brick(float3 p,
+ float mortar_size,
+ float mortar_smooth,
+ float bias,
+ float brick_width,
+ float row_height,
+ float offset_amount,
+ int offset_frequency,
+ float squash_amount,
+ int squash_frequency)
{
- int bricknum, rownum;
- float offset = 0.0f;
- float x, y;
-
- rownum = floor_to_int(p.y / row_height);
-
- if(offset_frequency && squash_frequency) {
- brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; /* squash */
- offset = (rownum % offset_frequency) ? 0.0f : (brick_width*offset_amount); /* offset */
- }
-
- bricknum = floor_to_int((p.x+offset) / brick_width);
-
- x = (p.x+offset) - brick_width*bricknum;
- y = p.y - row_height*rownum;
-
- float tint = saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias));
- float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
-
- float mortar;
- if(min_dist >= mortar_size) {
- mortar = 0.0f;
- }
- else if(mortar_smooth == 0.0f) {
- mortar = 1.0f;
- }
- else {
- min_dist = 1.0f - min_dist/mortar_size;
- mortar = (min_dist < mortar_smooth)? smoothstepf(min_dist / mortar_smooth) : 1.0f;
- }
-
- return make_float2(tint, mortar);
+ int bricknum, rownum;
+ float offset = 0.0f;
+ float x, y;
+
+ rownum = floor_to_int(p.y / row_height);
+
+ if (offset_frequency && squash_frequency) {
+ brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; /* squash */
+ offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount); /* offset */
+ }
+
+ bricknum = floor_to_int((p.x + offset) / brick_width);
+
+ x = (p.x + offset) - brick_width * bricknum;
+ y = p.y - row_height * rownum;
+
+ float tint = saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias));
+ float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
+
+ float mortar;
+ if (min_dist >= mortar_size) {
+ mortar = 0.0f;
+ }
+ else if (mortar_smooth == 0.0f) {
+ mortar = 1.0f;
+ }
+ else {
+ min_dist = 1.0f - min_dist / mortar_size;
+ mortar = (min_dist < mortar_smooth) ? smoothstepf(min_dist / mortar_smooth) : 1.0f;
+ }
+
+ return make_float2(tint, mortar);
}
-ccl_device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_tex_brick(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint4 node2 = read_node(kg, offset);
- uint4 node3 = read_node(kg, offset);
- uint4 node4 = read_node(kg, offset);
-
- /* Input and Output Sockets */
- uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset;
- uint mortar_size_offset, bias_offset, brick_width_offset, row_height_offset;
- uint color_offset, fac_offset, mortar_smooth_offset;
-
- /* RNA properties */
- uint offset_frequency, squash_frequency;
-
- decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset);
- decode_node_uchar4(node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset);
- decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, &mortar_smooth_offset);
-
- decode_node_uchar4(node2.x, &offset_frequency, &squash_frequency, NULL, NULL);
-
- float3 co = stack_load_float3(stack, co_offset);
-
- float3 color1 = stack_load_float3(stack, color1_offset);
- float3 color2 = stack_load_float3(stack, color2_offset);
- float3 mortar = stack_load_float3(stack, mortar_offset);
-
- float scale = stack_load_float_default(stack, scale_offset, node2.y);
- float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z);
- float mortar_smooth = stack_load_float_default(stack, mortar_smooth_offset, node4.x);
- float bias = stack_load_float_default(stack, bias_offset, node2.w);
- float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x);
- float row_height = stack_load_float_default(stack, row_height_offset, node3.y);
- float offset_amount = __int_as_float(node3.z);
- float squash_amount = __int_as_float(node3.w);
-
- float2 f2 = svm_brick(co*scale, mortar_size, mortar_smooth, bias, brick_width, row_height,
- offset_amount, offset_frequency, squash_amount, squash_frequency);
-
- float tint = f2.x;
- float f = f2.y;
-
- if(f != 1.0f) {
- float facm = 1.0f - tint;
- color1 = facm * color1 + tint * color2;
- }
-
- if(stack_valid(color_offset))
- stack_store_float3(stack, color_offset, color1*(1.0f-f) + mortar*f);
- if(stack_valid(fac_offset))
- stack_store_float(stack, fac_offset, f);
+ uint4 node2 = read_node(kg, offset);
+ uint4 node3 = read_node(kg, offset);
+ uint4 node4 = read_node(kg, offset);
+
+ /* Input and Output Sockets */
+ uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset;
+ uint mortar_size_offset, bias_offset, brick_width_offset, row_height_offset;
+ uint color_offset, fac_offset, mortar_smooth_offset;
+
+ /* RNA properties */
+ uint offset_frequency, squash_frequency;
+
+ decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset);
+ decode_node_uchar4(
+ node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset);
+ decode_node_uchar4(
+ node.w, &row_height_offset, &color_offset, &fac_offset, &mortar_smooth_offset);
+
+ decode_node_uchar4(node2.x, &offset_frequency, &squash_frequency, NULL, NULL);
+
+ float3 co = stack_load_float3(stack, co_offset);
+
+ float3 color1 = stack_load_float3(stack, color1_offset);
+ float3 color2 = stack_load_float3(stack, color2_offset);
+ float3 mortar = stack_load_float3(stack, mortar_offset);
+
+ float scale = stack_load_float_default(stack, scale_offset, node2.y);
+ float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z);
+ float mortar_smooth = stack_load_float_default(stack, mortar_smooth_offset, node4.x);
+ float bias = stack_load_float_default(stack, bias_offset, node2.w);
+ float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x);
+ float row_height = stack_load_float_default(stack, row_height_offset, node3.y);
+ float offset_amount = __int_as_float(node3.z);
+ float squash_amount = __int_as_float(node3.w);
+
+ float2 f2 = svm_brick(co * scale,
+ mortar_size,
+ mortar_smooth,
+ bias,
+ brick_width,
+ row_height,
+ offset_amount,
+ offset_frequency,
+ squash_amount,
+ squash_frequency);
+
+ float tint = f2.x;
+ float f = f2.y;
+
+ if (f != 1.0f) {
+ float facm = 1.0f - tint;
+ color1 = facm * color1 + tint * color2;
+ }
+
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, color1 * (1.0f - f) + mortar * f);
+ if (stack_valid(fac_offset))
+ stack_store_float(stack, fac_offset, f);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_brightness.h b/intern/cycles/kernel/svm/svm_brightness.h
index d71b0ee0b61..dcd75a2fe8f 100644
--- a/intern/cycles/kernel/svm/svm_brightness.h
+++ b/intern/cycles/kernel/svm/svm_brightness.h
@@ -16,19 +16,20 @@
CCL_NAMESPACE_BEGIN
-ccl_device void svm_node_brightness(ShaderData *sd, float *stack, uint in_color, uint out_color, uint node)
+ccl_device void svm_node_brightness(
+ ShaderData *sd, float *stack, uint in_color, uint out_color, uint node)
{
- uint bright_offset, contrast_offset;
- float3 color = stack_load_float3(stack, in_color);
+ uint bright_offset, contrast_offset;
+ float3 color = stack_load_float3(stack, in_color);
- decode_node_uchar4(node, &bright_offset, &contrast_offset, NULL, NULL);
- float brightness = stack_load_float(stack, bright_offset);
- float contrast = stack_load_float(stack, contrast_offset);
+ decode_node_uchar4(node, &bright_offset, &contrast_offset, NULL, NULL);
+ float brightness = stack_load_float(stack, bright_offset);
+ float contrast = stack_load_float(stack, contrast_offset);
- color = svm_brightness_contrast(color, brightness, contrast);
+ color = svm_brightness_contrast(color, brightness, contrast);
- if(stack_valid(out_color))
- stack_store_float3(stack, out_color, color);
+ if (stack_valid(out_color))
+ stack_store_float3(stack, out_color, color);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_bump.h b/intern/cycles/kernel/svm/svm_bump.h
index 35aac174409..c9d430a2bba 100644
--- a/intern/cycles/kernel/svm/svm_bump.h
+++ b/intern/cycles/kernel/svm/svm_bump.h
@@ -18,36 +18,42 @@ CCL_NAMESPACE_BEGIN
/* Bump Eval Nodes */
-ccl_device void svm_node_enter_bump_eval(KernelGlobals *kg, ShaderData *sd, float *stack, uint offset)
+ccl_device void svm_node_enter_bump_eval(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint offset)
{
- /* save state */
- stack_store_float3(stack, offset+0, sd->P);
- stack_store_float3(stack, offset+3, sd->dP.dx);
- stack_store_float3(stack, offset+6, sd->dP.dy);
-
- /* set state as if undisplaced */
- const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POSITION_UNDISPLACED);
-
- if(desc.offset != ATTR_STD_NOT_FOUND) {
- float3 P, dPdx, dPdy;
- P = primitive_surface_attribute_float3(kg, sd, desc, &dPdx, &dPdy);
-
- object_position_transform(kg, sd, &P);
- object_dir_transform(kg, sd, &dPdx);
- object_dir_transform(kg, sd, &dPdy);
-
- sd->P = P;
- sd->dP.dx = dPdx;
- sd->dP.dy = dPdy;
- }
+ /* save state */
+ stack_store_float3(stack, offset + 0, sd->P);
+ stack_store_float3(stack, offset + 3, sd->dP.dx);
+ stack_store_float3(stack, offset + 6, sd->dP.dy);
+
+ /* set state as if undisplaced */
+ const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POSITION_UNDISPLACED);
+
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ float3 P, dPdx, dPdy;
+ P = primitive_surface_attribute_float3(kg, sd, desc, &dPdx, &dPdy);
+
+ object_position_transform(kg, sd, &P);
+ object_dir_transform(kg, sd, &dPdx);
+ object_dir_transform(kg, sd, &dPdy);
+
+ sd->P = P;
+ sd->dP.dx = dPdx;
+ sd->dP.dy = dPdy;
+ }
}
-ccl_device void svm_node_leave_bump_eval(KernelGlobals *kg, ShaderData *sd, float *stack, uint offset)
+ccl_device void svm_node_leave_bump_eval(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint offset)
{
- /* restore state */
- sd->P = stack_load_float3(stack, offset+0);
- sd->dP.dx = stack_load_float3(stack, offset+3);
- sd->dP.dy = stack_load_float3(stack, offset+6);
+ /* restore state */
+ sd->P = stack_load_float3(stack, offset + 0);
+ sd->dP.dx = stack_load_float3(stack, offset + 3);
+ sd->dP.dy = stack_load_float3(stack, offset + 6);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_camera.h b/intern/cycles/kernel/svm/svm_camera.h
index cf90229b53b..21a17acf5f1 100644
--- a/intern/cycles/kernel/svm/svm_camera.h
+++ b/intern/cycles/kernel/svm/svm_camera.h
@@ -16,25 +16,30 @@
CCL_NAMESPACE_BEGIN
-ccl_device void svm_node_camera(KernelGlobals *kg, ShaderData *sd, float *stack, uint out_vector, uint out_zdepth, uint out_distance)
+ccl_device void svm_node_camera(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint out_vector,
+ uint out_zdepth,
+ uint out_distance)
{
- float distance;
- float zdepth;
- float3 vector;
+ float distance;
+ float zdepth;
+ float3 vector;
- Transform tfm = kernel_data.cam.worldtocamera;
- vector = transform_point(&tfm, sd->P);
- zdepth = vector.z;
- distance = len(vector);
+ Transform tfm = kernel_data.cam.worldtocamera;
+ vector = transform_point(&tfm, sd->P);
+ zdepth = vector.z;
+ distance = len(vector);
- if(stack_valid(out_vector))
- stack_store_float3(stack, out_vector, normalize(vector));
+ if (stack_valid(out_vector))
+ stack_store_float3(stack, out_vector, normalize(vector));
- if(stack_valid(out_zdepth))
- stack_store_float(stack, out_zdepth, zdepth);
+ if (stack_valid(out_zdepth))
+ stack_store_float(stack, out_zdepth, zdepth);
- if(stack_valid(out_distance))
- stack_store_float(stack, out_distance, distance);
+ if (stack_valid(out_distance))
+ stack_store_float(stack, out_distance, distance);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_checker.h b/intern/cycles/kernel/svm/svm_checker.h
index 45e6c181e9e..63b4d1e149b 100644
--- a/intern/cycles/kernel/svm/svm_checker.h
+++ b/intern/cycles/kernel/svm/svm_checker.h
@@ -20,37 +20,37 @@ CCL_NAMESPACE_BEGIN
ccl_device_noinline float svm_checker(float3 p)
{
- /* avoid precision issues on unit coordinates */
- p.x = (p.x + 0.000001f)*0.999999f;
- p.y = (p.y + 0.000001f)*0.999999f;
- p.z = (p.z + 0.000001f)*0.999999f;
+ /* avoid precision issues on unit coordinates */
+ p.x = (p.x + 0.000001f) * 0.999999f;
+ p.y = (p.y + 0.000001f) * 0.999999f;
+ p.z = (p.z + 0.000001f) * 0.999999f;
- int xi = abs(float_to_int(floorf(p.x)));
- int yi = abs(float_to_int(floorf(p.y)));
- int zi = abs(float_to_int(floorf(p.z)));
+ int xi = abs(float_to_int(floorf(p.x)));
+ int yi = abs(float_to_int(floorf(p.y)));
+ int zi = abs(float_to_int(floorf(p.z)));
- return ((xi % 2 == yi % 2) == (zi % 2))? 1.0f: 0.0f;
+ return ((xi % 2 == yi % 2) == (zi % 2)) ? 1.0f : 0.0f;
}
ccl_device void svm_node_tex_checker(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- uint co_offset, color1_offset, color2_offset, scale_offset;
- uint color_offset, fac_offset;
+ uint co_offset, color1_offset, color2_offset, scale_offset;
+ uint color_offset, fac_offset;
- decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset);
- decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
+ decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset);
+ decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
- float3 co = stack_load_float3(stack, co_offset);
- float3 color1 = stack_load_float3(stack, color1_offset);
- float3 color2 = stack_load_float3(stack, color2_offset);
- float scale = stack_load_float_default(stack, scale_offset, node.w);
+ float3 co = stack_load_float3(stack, co_offset);
+ float3 color1 = stack_load_float3(stack, color1_offset);
+ float3 color2 = stack_load_float3(stack, color2_offset);
+ float scale = stack_load_float_default(stack, scale_offset, node.w);
- float f = svm_checker(co*scale);
+ float f = svm_checker(co * scale);
- if(stack_valid(color_offset))
- stack_store_float3(stack, color_offset, (f == 1.0f)? color1: color2);
- if(stack_valid(fac_offset))
- stack_store_float(stack, fac_offset, f);
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, (f == 1.0f) ? color1 : color2);
+ if (stack_valid(fac_offset))
+ stack_store_float(stack, fac_offset, f);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index a7e87715ed4..270fe4c8615 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -20,1140 +20,1237 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline float3 sigma_from_concentration(float eumelanin, float pheomelanin)
{
- return eumelanin*make_float3(0.506f, 0.841f, 1.653f) + pheomelanin*make_float3(0.343f, 0.733f, 1.924f);
+ return eumelanin * make_float3(0.506f, 0.841f, 1.653f) +
+ pheomelanin * make_float3(0.343f, 0.733f, 1.924f);
}
ccl_device_inline float3 sigma_from_reflectance(float3 color, float azimuthal_roughness)
{
- float x = azimuthal_roughness;
- float roughness_fac = (((((0.245f*x) + 5.574f)*x - 10.73f)*x + 2.532f)*x - 0.215f)*x + 5.969f;
- float3 sigma = log3(color) / roughness_fac;
- return sigma * sigma;
+ float x = azimuthal_roughness;
+ float roughness_fac = (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x +
+ 5.969f;
+ float3 sigma = log3(color) / roughness_fac;
+ return sigma * sigma;
}
/* Closure Nodes */
-ccl_device void svm_node_glass_setup(ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract)
+ccl_device void svm_node_glass_setup(
+ ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract)
{
- if(type == CLOSURE_BSDF_SHARP_GLASS_ID) {
- if(refract) {
- bsdf->alpha_y = 0.0f;
- bsdf->alpha_x = 0.0f;
- bsdf->ior = eta;
- sd->flag |= bsdf_refraction_setup(bsdf);
- }
- else {
- bsdf->alpha_y = 0.0f;
- bsdf->alpha_x = 0.0f;
- bsdf->ior = 0.0f;
- sd->flag |= bsdf_reflection_setup(bsdf);
- }
- }
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) {
- bsdf->alpha_x = roughness;
- bsdf->alpha_y = roughness;
- bsdf->ior = eta;
-
- if(refract)
- sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
- else
- sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
- }
- else {
- bsdf->alpha_x = roughness;
- bsdf->alpha_y = roughness;
- bsdf->ior = eta;
-
- if(refract)
- sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
- else
- sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
- }
+ if (type == CLOSURE_BSDF_SHARP_GLASS_ID) {
+ if (refract) {
+ bsdf->alpha_y = 0.0f;
+ bsdf->alpha_x = 0.0f;
+ bsdf->ior = eta;
+ sd->flag |= bsdf_refraction_setup(bsdf);
+ }
+ else {
+ bsdf->alpha_y = 0.0f;
+ bsdf->alpha_x = 0.0f;
+ bsdf->ior = 0.0f;
+ sd->flag |= bsdf_reflection_setup(bsdf);
+ }
+ }
+ else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) {
+ bsdf->alpha_x = roughness;
+ bsdf->alpha_y = roughness;
+ bsdf->ior = eta;
+
+ if (refract)
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
+ else
+ sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
+ }
+ else {
+ bsdf->alpha_x = roughness;
+ bsdf->alpha_y = roughness;
+ bsdf->ior = eta;
+
+ if (refract)
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
+ else
+ sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
+ }
}
-ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag, int *offset)
+ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint4 node,
+ ShaderType shader_type,
+ int path_flag,
+ int *offset)
{
- uint type, param1_offset, param2_offset;
+ uint type, param1_offset, param2_offset;
- uint mix_weight_offset;
- decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
- float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
+ uint mix_weight_offset;
+ decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
+ float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
+ 1.0f);
- /* note we read this extra node before weight check, so offset is added */
- uint4 data_node = read_node(kg, offset);
+ /* note we read this extra node before weight check, so offset is added */
+ uint4 data_node = read_node(kg, offset);
- /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */
- if(mix_weight == 0.0f || shader_type != SHADER_TYPE_SURFACE) {
- if(type == CLOSURE_BSDF_PRINCIPLED_ID) {
- /* Read all principled BSDF extra data to get the right offset. */
- read_node(kg, offset);
- read_node(kg, offset);
- read_node(kg, offset);
- read_node(kg, offset);
- }
+ /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */
+ if (mix_weight == 0.0f || shader_type != SHADER_TYPE_SURFACE) {
+ if (type == CLOSURE_BSDF_PRINCIPLED_ID) {
+ /* Read all principled BSDF extra data to get the right offset. */
+ read_node(kg, offset);
+ read_node(kg, offset);
+ read_node(kg, offset);
+ read_node(kg, offset);
+ }
- return;
- }
+ return;
+ }
- float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
+ float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N;
- float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
- float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
+ float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) :
+ __uint_as_float(node.z);
+ float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) :
+ __uint_as_float(node.w);
- switch(type) {
+ switch (type) {
#ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_ID: {
- uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, sheen_offset,
- sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset, eta_offset, transmission_offset,
- anisotropic_rotation_offset, transmission_roughness_offset;
- uint4 data_node2 = read_node(kg, offset);
-
- float3 T = stack_load_float3(stack, data_node.y);
- decode_node_uchar4(data_node.z, &specular_offset, &roughness_offset, &specular_tint_offset, &anisotropic_offset);
- decode_node_uchar4(data_node.w, &sheen_offset, &sheen_tint_offset, &clearcoat_offset, &clearcoat_roughness_offset);
- decode_node_uchar4(data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &transmission_roughness_offset);
-
- // get Disney principled parameters
- float metallic = param1;
- float subsurface = param2;
- float specular = stack_load_float(stack, specular_offset);
- float roughness = stack_load_float(stack, roughness_offset);
- float specular_tint = stack_load_float(stack, specular_tint_offset);
- float anisotropic = stack_load_float(stack, anisotropic_offset);
- float sheen = stack_load_float(stack, sheen_offset);
- float sheen_tint = stack_load_float(stack, sheen_tint_offset);
- float clearcoat = stack_load_float(stack, clearcoat_offset);
- float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
- float transmission = stack_load_float(stack, transmission_offset);
- float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
- float transmission_roughness = stack_load_float(stack, transmission_roughness_offset);
- float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
-
- ClosureType distribution = (ClosureType) data_node2.y;
- ClosureType subsurface_method = (ClosureType) data_node2.z;
-
- /* rotate tangent */
- if(anisotropic_rotation != 0.0f)
- T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
-
- /* calculate ior */
- float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
-
- // calculate fresnel for refraction
- float cosNO = dot(N, sd->I);
- float fresnel = fresnel_dielectric_cos(cosNO, ior);
-
- // calculate weights of the diffuse and specular part
- float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission));
-
- float final_transmission = saturate(transmission) * (1.0f - saturate(metallic));
- float specular_weight = (1.0f - final_transmission);
-
- // get the base color
- uint4 data_base_color = read_node(kg, offset);
- float3 base_color = stack_valid(data_base_color.x) ? stack_load_float3(stack, data_base_color.x) :
- make_float3(__uint_as_float(data_base_color.y), __uint_as_float(data_base_color.z), __uint_as_float(data_base_color.w));
-
- // get the additional clearcoat normal and subsurface scattering radius
- uint4 data_cn_ssr = read_node(kg, offset);
- float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : sd->N;
- float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? stack_load_float3(stack, data_cn_ssr.y) : make_float3(1.0f, 1.0f, 1.0f);
-
- // get the subsurface color
- uint4 data_subsurface_color = read_node(kg, offset);
- float3 subsurface_color = stack_valid(data_subsurface_color.x) ? stack_load_float3(stack, data_subsurface_color.x) :
- make_float3(__uint_as_float(data_subsurface_color.y), __uint_as_float(data_subsurface_color.z), __uint_as_float(data_subsurface_color.w));
-
- float3 weight = sd->svm_closure_weight * mix_weight;
-
-#ifdef __SUBSURFACE__
- float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface);
- float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight;
-
- /* disable in case of diffuse ancestor, can't see it well then and
- * adds considerably noise due to probabilities of continuing path
- * getting lower and lower */
- if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
- subsurface = 0.0f;
-
- /* need to set the base color in this case such that the
- * rays get the correctly mixed color after transmitting
- * the object */
- base_color = mixed_ss_base_color;
- }
-
- /* diffuse */
- if(fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) {
- if(subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
- float3 diff_weight = weight * base_color * diffuse_weight;
-
- PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->roughness = roughness;
-
- /* setup bsdf */
- sd->flag |= bsdf_principled_diffuse_setup(bsdf);
- }
- }
- else if(subsurface > CLOSURE_WEIGHT_CUTOFF) {
- Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight);
-
- if(bssrdf) {
- bssrdf->radius = subsurface_radius * subsurface;
- bssrdf->albedo = (subsurface_method == CLOSURE_BSSRDF_PRINCIPLED_ID)? subsurface_color: mixed_ss_base_color;
- bssrdf->texture_blur = 0.0f;
- bssrdf->sharpness = 0.0f;
- bssrdf->N = N;
- bssrdf->roughness = roughness;
-
- /* setup bsdf */
- sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method);
- }
- }
- }
-#else
- /* diffuse */
- if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
- float3 diff_weight = weight * base_color * diffuse_weight;
-
- PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->roughness = roughness;
-
- /* setup bsdf */
- sd->flag |= bsdf_principled_diffuse_setup(bsdf);
- }
- }
-#endif
-
- /* sheen */
- if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
- float m_cdlum = linear_rgb_to_gray(kg, base_color);
- float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
-
- /* color of the sheen component */
- float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + m_ctint * sheen_tint;
-
- float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight;
-
- PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf*)bsdf_alloc(sd, sizeof(PrincipledSheenBsdf), sheen_weight);
-
- if(bsdf) {
- bsdf->N = N;
-
- /* setup bsdf */
- sd->flag |= bsdf_principled_sheen_setup(bsdf);
- }
- }
-
- /* specular reflection */
+ case CLOSURE_BSDF_PRINCIPLED_ID: {
+ uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
+ sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset,
+ eta_offset, transmission_offset, anisotropic_rotation_offset,
+ transmission_roughness_offset;
+ uint4 data_node2 = read_node(kg, offset);
+
+ float3 T = stack_load_float3(stack, data_node.y);
+ decode_node_uchar4(data_node.z,
+ &specular_offset,
+ &roughness_offset,
+ &specular_tint_offset,
+ &anisotropic_offset);
+ decode_node_uchar4(data_node.w,
+ &sheen_offset,
+ &sheen_tint_offset,
+ &clearcoat_offset,
+ &clearcoat_roughness_offset);
+ decode_node_uchar4(data_node2.x,
+ &eta_offset,
+ &transmission_offset,
+ &anisotropic_rotation_offset,
+ &transmission_roughness_offset);
+
+ // get Disney principled parameters
+ float metallic = param1;
+ float subsurface = param2;
+ float specular = stack_load_float(stack, specular_offset);
+ float roughness = stack_load_float(stack, roughness_offset);
+ float specular_tint = stack_load_float(stack, specular_tint_offset);
+ float anisotropic = stack_load_float(stack, anisotropic_offset);
+ float sheen = stack_load_float(stack, sheen_offset);
+ float sheen_tint = stack_load_float(stack, sheen_tint_offset);
+ float clearcoat = stack_load_float(stack, clearcoat_offset);
+ float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
+ float transmission = stack_load_float(stack, transmission_offset);
+ float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
+ float transmission_roughness = stack_load_float(stack, transmission_roughness_offset);
+ float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
+
+ ClosureType distribution = (ClosureType)data_node2.y;
+ ClosureType subsurface_method = (ClosureType)data_node2.z;
+
+ /* rotate tangent */
+ if (anisotropic_rotation != 0.0f)
+ T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
+
+ /* calculate ior */
+ float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
+
+ // calculate fresnel for refraction
+ float cosNO = dot(N, sd->I);
+ float fresnel = fresnel_dielectric_cos(cosNO, ior);
+
+ // calculate weights of the diffuse and specular part
+ float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission));
+
+ float final_transmission = saturate(transmission) * (1.0f - saturate(metallic));
+ float specular_weight = (1.0f - final_transmission);
+
+ // get the base color
+ uint4 data_base_color = read_node(kg, offset);
+ float3 base_color = stack_valid(data_base_color.x) ?
+ stack_load_float3(stack, data_base_color.x) :
+ make_float3(__uint_as_float(data_base_color.y),
+ __uint_as_float(data_base_color.z),
+ __uint_as_float(data_base_color.w));
+
+ // get the additional clearcoat normal and subsurface scattering radius
+ uint4 data_cn_ssr = read_node(kg, offset);
+ float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ?
+ stack_load_float3(stack, data_cn_ssr.x) :
+ sd->N;
+ float3 subsurface_radius = stack_valid(data_cn_ssr.y) ?
+ stack_load_float3(stack, data_cn_ssr.y) :
+ make_float3(1.0f, 1.0f, 1.0f);
+
+ // get the subsurface color
+ uint4 data_subsurface_color = read_node(kg, offset);
+ float3 subsurface_color = stack_valid(data_subsurface_color.x) ?
+ stack_load_float3(stack, data_subsurface_color.x) :
+ make_float3(__uint_as_float(data_subsurface_color.y),
+ __uint_as_float(data_subsurface_color.z),
+ __uint_as_float(data_subsurface_color.w));
+
+ float3 weight = sd->svm_closure_weight * mix_weight;
+
+# ifdef __SUBSURFACE__
+ float3 mixed_ss_base_color = subsurface_color * subsurface +
+ base_color * (1.0f - subsurface);
+ float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight;
+
+ /* disable in case of diffuse ancestor, can't see it well then and
+ * adds considerably noise due to probabilities of continuing path
+ * getting lower and lower */
+ if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
+ subsurface = 0.0f;
+
+ /* need to set the base color in this case such that the
+ * rays get the correctly mixed color after transmitting
+ * the object */
+ base_color = mixed_ss_base_color;
+ }
+
+ /* diffuse */
+ if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) {
+ if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
+ float3 diff_weight = weight * base_color * diffuse_weight;
+
+ PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc(
+ sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->roughness = roughness;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_principled_diffuse_setup(bsdf);
+ }
+ }
+ else if (subsurface > CLOSURE_WEIGHT_CUTOFF) {
+ Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight);
+
+ if (bssrdf) {
+ bssrdf->radius = subsurface_radius * subsurface;
+ bssrdf->albedo = (subsurface_method == CLOSURE_BSSRDF_PRINCIPLED_ID) ?
+ subsurface_color :
+ mixed_ss_base_color;
+ bssrdf->texture_blur = 0.0f;
+ bssrdf->sharpness = 0.0f;
+ bssrdf->N = N;
+ bssrdf->roughness = roughness;
+
+ /* setup bsdf */
+ sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method);
+ }
+ }
+ }
+# else
+ /* diffuse */
+ if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
+ float3 diff_weight = weight * base_color * diffuse_weight;
+
+ PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc(
+ sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->roughness = roughness;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_principled_diffuse_setup(bsdf);
+ }
+ }
+# endif
+
+ /* sheen */
+ if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
+ float m_cdlum = linear_rgb_to_gray(kg, base_color);
+ float3 m_ctint = m_cdlum > 0.0f ?
+ base_color / m_cdlum :
+ make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
+
+ /* color of the sheen component */
+ float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) +
+ m_ctint * sheen_tint;
+
+ float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight;
+
+ PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc(
+ sd, sizeof(PrincipledSheenBsdf), sheen_weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_principled_sheen_setup(bsdf);
+ }
+ }
+
+ /* specular reflection */
+# ifdef __CAUSTICS_TRICKS__
+ if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
+# endif
+ if (specular_weight > CLOSURE_WEIGHT_CUTOFF &&
+ (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
+ float3 spec_weight = weight * specular_weight;
+
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
+ sd, sizeof(MicrofacetBsdf), spec_weight);
+ MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
+ sd, sizeof(MicrofacetExtra)) :
+ NULL;
+
+ if (bsdf && extra) {
+ bsdf->N = N;
+ bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
+ bsdf->T = T;
+ bsdf->extra = extra;
+
+ float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
+ float r2 = roughness * roughness;
+
+ bsdf->alpha_x = r2 / aspect;
+ bsdf->alpha_y = r2 * aspect;
+
+ float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y +
+ 0.1f * base_color.z; // luminance approx.
+ float3 m_ctint = m_cdlum > 0.0f ?
+ base_color / m_cdlum :
+ make_float3(
+ 0.0f, 0.0f, 0.0f); // normalize lum. to isolate hue+sat
+ float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) +
+ m_ctint * specular_tint;
+
+ bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) +
+ base_color * metallic;
+ bsdf->extra->color = base_color;
+ bsdf->extra->clearcoat = 0.0f;
+
+ /* setup bsdf */
+ if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID ||
+ roughness <= 0.075f) /* use single-scatter GGX */
+ sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
+ else /* use multi-scatter GGX */
+ sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
+ }
+ }
+# ifdef __CAUSTICS_TRICKS__
+ }
+# endif
+
+ /* BSDF */
+# ifdef __CAUSTICS_TRICKS__
+ if (kernel_data.integrator.caustics_reflective ||
+ kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
+# endif
+ if (final_transmission > CLOSURE_WEIGHT_CUTOFF) {
+ float3 glass_weight = weight * final_transmission;
+ float3 cspec0 = base_color * specular_tint +
+ make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
+
+ if (roughness <= 5e-2f ||
+ distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
+ float refl_roughness = roughness;
+
+ /* reflection */
+# ifdef __CAUSTICS_TRICKS__
+ if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
+# endif
+ {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
+ sd, sizeof(MicrofacetBsdf), glass_weight * fresnel);
+ MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
+ sd, sizeof(MicrofacetExtra)) :
+ NULL;
+
+ if (bsdf && extra) {
+ bsdf->N = N;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra = extra;
+
+ bsdf->alpha_x = refl_roughness * refl_roughness;
+ bsdf->alpha_y = refl_roughness * refl_roughness;
+ bsdf->ior = ior;
+
+ bsdf->extra->color = base_color;
+ bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->clearcoat = 0.0f;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
+ }
+ }
+
+ /* refraction */
+# ifdef __CAUSTICS_TRICKS__
+ if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
+# endif
+ {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
+ sd, sizeof(MicrofacetBsdf), base_color * glass_weight * (1.0f - fresnel));
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra = NULL;
+
+ if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
+ transmission_roughness = 1.0f - (1.0f - refl_roughness) *
+ (1.0f - transmission_roughness);
+ else
+ transmission_roughness = refl_roughness;
+
+ bsdf->alpha_x = transmission_roughness * transmission_roughness;
+ bsdf->alpha_y = transmission_roughness * transmission_roughness;
+ bsdf->ior = ior;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
+ }
+ }
+ }
+ else { /* use multi-scatter GGX */
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
+ sd, sizeof(MicrofacetBsdf), glass_weight);
+ MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
+ sd, sizeof(MicrofacetExtra)) :
+ NULL;
+
+ if (bsdf && extra) {
+ bsdf->N = N;
+ bsdf->extra = extra;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+
+ bsdf->alpha_x = roughness * roughness;
+ bsdf->alpha_y = roughness * roughness;
+ bsdf->ior = ior;
+
+ bsdf->extra->color = base_color;
+ bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->clearcoat = 0.0f;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
+ }
+ }
+ }
+# ifdef __CAUSTICS_TRICKS__
+ }
+# endif
+
+ /* clearcoat */
+# ifdef __CAUSTICS_TRICKS__
+ if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
+# endif
+ if (clearcoat > CLOSURE_WEIGHT_CUTOFF) {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
+ MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
+ sd, sizeof(MicrofacetExtra)) :
+ NULL;
+
+ if (bsdf && extra) {
+ bsdf->N = clearcoat_normal;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->ior = 1.5f;
+ bsdf->extra = extra;
+
+ bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
+ bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
+
+ bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
+ bsdf->extra->clearcoat = clearcoat;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
+ }
+ }
+# ifdef __CAUSTICS_TRICKS__
+ }
+# endif
+
+ break;
+ }
+#endif /* __PRINCIPLED__ */
+ case CLOSURE_BSDF_DIFFUSE_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ OrenNayarBsdf *bsdf = (OrenNayarBsdf *)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+
+ float roughness = param1;
+
+ if (roughness == 0.0f) {
+ sd->flag |= bsdf_diffuse_setup((DiffuseBsdf *)bsdf);
+ }
+ else {
+ bsdf->roughness = roughness;
+ sd->flag |= bsdf_oren_nayar_setup(bsdf);
+ }
+ }
+ break;
+ }
+ case CLOSURE_BSDF_TRANSLUCENT_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ sd->flag |= bsdf_translucent_setup(bsdf);
+ }
+ break;
+ }
+ case CLOSURE_BSDF_TRANSPARENT_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ bsdf_transparent_setup(sd, weight, path_flag);
+ break;
+ }
+ case CLOSURE_BSDF_REFLECTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: {
#ifdef __CAUSTICS_TRICKS__
- if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
+ if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
+ break;
#endif
- if(specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
- float3 spec_weight = weight * specular_weight;
-
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight);
- MicrofacetExtra *extra = (bsdf != NULL)
- ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra))
- : NULL;
-
- if(bsdf && extra) {
- bsdf->N = N;
- bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
- bsdf->T = T;
- bsdf->extra = extra;
-
- float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
- float r2 = roughness * roughness;
-
- bsdf->alpha_x = r2 / aspect;
- bsdf->alpha_y = r2 * aspect;
-
- float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx.
- float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : make_float3(0.0f, 0.0f, 0.0f); // normalize lum. to isolate hue+sat
- float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) + m_ctint * specular_tint;
-
- bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic;
- bsdf->extra->color = base_color;
- bsdf->extra->clearcoat = 0.0f;
-
- /* setup bsdf */
- if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */
- sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
- else /* use multi-scatter GGX */
- sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
- }
- }
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
+
+ if (!bsdf) {
+ break;
+ }
+
+ float roughness = sqr(param1);
+
+ bsdf->N = N;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->alpha_x = roughness;
+ bsdf->alpha_y = roughness;
+ bsdf->ior = 0.0f;
+ bsdf->extra = NULL;
+
+ /* setup bsdf */
+ if (type == CLOSURE_BSDF_REFLECTION_ID)
+ sd->flag |= bsdf_reflection_setup(bsdf);
+ else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
+ sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
+ else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID)
+ sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
+ else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
+ kernel_assert(stack_valid(data_node.z));
+ bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
+ if (bsdf->extra) {
+ bsdf->extra->color = stack_load_float3(stack, data_node.z);
+ bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->clearcoat = 0.0f;
+ sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
+ }
+ }
+ else {
+ sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
+ }
+
+ break;
+ }
+ case CLOSURE_BSDF_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
#ifdef __CAUSTICS_TRICKS__
- }
+ if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
+ break;
#endif
-
- /* BSDF */
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra = NULL;
+
+ float eta = fmaxf(param2, 1e-5f);
+ eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
+
+ /* setup bsdf */
+ if (type == CLOSURE_BSDF_REFRACTION_ID) {
+ bsdf->alpha_x = 0.0f;
+ bsdf->alpha_y = 0.0f;
+ bsdf->ior = eta;
+
+ sd->flag |= bsdf_refraction_setup(bsdf);
+ }
+ else {
+ float roughness = sqr(param1);
+ bsdf->alpha_x = roughness;
+ bsdf->alpha_y = roughness;
+ bsdf->ior = eta;
+
+ if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
+ else
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
+ }
+ }
+
+ break;
+ }
+ case CLOSURE_BSDF_SHARP_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
#ifdef __CAUSTICS_TRICKS__
- if(kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
+ if (!kernel_data.integrator.caustics_reflective &&
+ !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) {
+ break;
+ }
#endif
- if(final_transmission > CLOSURE_WEIGHT_CUTOFF) {
- float3 glass_weight = weight * final_transmission;
- float3 cspec0 = base_color * specular_tint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
+ float3 weight = sd->svm_closure_weight * mix_weight;
- if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
- float refl_roughness = roughness;
+ /* index of refraction */
+ float eta = fmaxf(param2, 1e-5f);
+ eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
- /* reflection */
-#ifdef __CAUSTICS_TRICKS__
- if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
-#endif
- {
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*fresnel);
- MicrofacetExtra *extra = (bsdf != NULL)
- ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra))
- : NULL;
-
- if(bsdf && extra) {
- bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra = extra;
-
- bsdf->alpha_x = refl_roughness * refl_roughness;
- bsdf->alpha_y = refl_roughness * refl_roughness;
- bsdf->ior = ior;
-
- bsdf->extra->color = base_color;
- bsdf->extra->cspec0 = cspec0;
- bsdf->extra->clearcoat = 0.0f;
-
- /* setup bsdf */
- sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
- }
- }
-
- /* refraction */
-#ifdef __CAUSTICS_TRICKS__
- if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
-#endif
- {
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), base_color*glass_weight*(1.0f - fresnel));
- if(bsdf) {
- bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra = NULL;
-
- if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
- transmission_roughness = 1.0f - (1.0f - refl_roughness) * (1.0f - transmission_roughness);
- else
- transmission_roughness = refl_roughness;
-
- bsdf->alpha_x = transmission_roughness * transmission_roughness;
- bsdf->alpha_y = transmission_roughness * transmission_roughness;
- bsdf->ior = ior;
-
- /* setup bsdf */
- sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
- }
- }
- }
- else { /* use multi-scatter GGX */
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
- MicrofacetExtra *extra = (bsdf != NULL)
- ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra))
- : NULL;
-
- if(bsdf && extra) {
- bsdf->N = N;
- bsdf->extra = extra;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
-
- bsdf->alpha_x = roughness * roughness;
- bsdf->alpha_y = roughness * roughness;
- bsdf->ior = ior;
-
- bsdf->extra->color = base_color;
- bsdf->extra->cspec0 = cspec0;
- bsdf->extra->clearcoat = 0.0f;
-
- /* setup bsdf */
- sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
- }
- }
- }
-#ifdef __CAUSTICS_TRICKS__
- }
-#endif
+ /* fresnel */
+ float cosNO = dot(N, sd->I);
+ float fresnel = fresnel_dielectric_cos(cosNO, eta);
+ float roughness = sqr(param1);
- /* clearcoat */
+ /* reflection */
#ifdef __CAUSTICS_TRICKS__
- if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
+ if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
#endif
- if(clearcoat > CLOSURE_WEIGHT_CUTOFF) {
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
- MicrofacetExtra *extra = (bsdf != NULL)
- ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra))
- : NULL;
-
- if(bsdf && extra) {
- bsdf->N = clearcoat_normal;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->ior = 1.5f;
- bsdf->extra = extra;
-
- bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
- bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
-
- bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
- bsdf->extra->clearcoat = clearcoat;
-
- /* setup bsdf */
- sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
- }
- }
+ {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
+ sd, sizeof(MicrofacetBsdf), weight * fresnel);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra = NULL;
+ svm_node_glass_setup(sd, bsdf, type, eta, roughness, false);
+ }
+ }
+
+ /* refraction */
#ifdef __CAUSTICS_TRICKS__
- }
+ if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
#endif
-
- break;
- }
-#endif /* __PRINCIPLED__ */
- case CLOSURE_BSDF_DIFFUSE_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
- OrenNayarBsdf *bsdf = (OrenNayarBsdf*)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
-
- float roughness = param1;
-
- if(roughness == 0.0f) {
- sd->flag |= bsdf_diffuse_setup((DiffuseBsdf*)bsdf);
- }
- else {
- bsdf->roughness = roughness;
- sd->flag |= bsdf_oren_nayar_setup(bsdf);
- }
- }
- break;
- }
- case CLOSURE_BSDF_TRANSLUCENT_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
- DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
- sd->flag |= bsdf_translucent_setup(bsdf);
- }
- break;
- }
- case CLOSURE_BSDF_TRANSPARENT_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
- bsdf_transparent_setup(sd, weight, path_flag);
- break;
- }
- case CLOSURE_BSDF_REFLECTION_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: {
+ {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
+ sd, sizeof(MicrofacetBsdf), weight * (1.0f - fresnel));
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra = NULL;
+ svm_node_glass_setup(sd, bsdf, type, eta, roughness, true);
+ }
+ }
+
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
#ifdef __CAUSTICS_TRICKS__
- if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
- break;
+ if (!kernel_data.integrator.caustics_reflective &&
+ !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
+ break;
#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
-
- if(!bsdf) {
- break;
- }
-
- float roughness = sqr(param1);
-
- bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->alpha_x = roughness;
- bsdf->alpha_y = roughness;
- bsdf->ior = 0.0f;
- bsdf->extra = NULL;
-
- /* setup bsdf */
- if(type == CLOSURE_BSDF_REFLECTION_ID)
- sd->flag |= bsdf_reflection_setup(bsdf);
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
- sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
- else if(type == CLOSURE_BSDF_MICROFACET_GGX_ID)
- sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
- else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
- kernel_assert(stack_valid(data_node.z));
- bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
- if(bsdf->extra) {
- bsdf->extra->color = stack_load_float3(stack, data_node.z);
- bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->clearcoat = 0.0f;
- sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
- }
- }
- else {
- sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
- }
-
- break;
- }
- case CLOSURE_BSDF_REFRACTION_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
+ if (!bsdf) {
+ break;
+ }
+
+ MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
+ if (!extra) {
+ break;
+ }
+
+ bsdf->N = N;
+ bsdf->extra = extra;
+ bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+
+ float roughness = sqr(param1);
+ bsdf->alpha_x = roughness;
+ bsdf->alpha_y = roughness;
+ float eta = fmaxf(param2, 1e-5f);
+ bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
+
+ kernel_assert(stack_valid(data_node.z));
+ bsdf->extra->color = stack_load_float3(stack, data_node.z);
+ bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->clearcoat = 0.0f;
+
+ /* setup bsdf */
+ sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
#ifdef __CAUSTICS_TRICKS__
- if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
- break;
+ if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
+ break;
#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra = NULL;
-
- float eta = fmaxf(param2, 1e-5f);
- eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
-
- /* setup bsdf */
- if(type == CLOSURE_BSDF_REFRACTION_ID) {
- bsdf->alpha_x = 0.0f;
- bsdf->alpha_y = 0.0f;
- bsdf->ior = eta;
-
- sd->flag |= bsdf_refraction_setup(bsdf);
- }
- else {
- float roughness = sqr(param1);
- bsdf->alpha_x = roughness;
- bsdf->alpha_y = roughness;
- bsdf->ior = eta;
-
- if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
- sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
- else
- sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
- }
- }
-
- break;
- }
- case CLOSURE_BSDF_SHARP_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->extra = NULL;
+ bsdf->T = stack_load_float3(stack, data_node.y);
+
+ /* rotate tangent */
+ float rotation = stack_load_float(stack, data_node.z);
+
+ if (rotation != 0.0f)
+ bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
+
+ /* compute roughness */
+ float roughness = sqr(param1);
+ float anisotropy = clamp(param2, -0.99f, 0.99f);
+
+ if (anisotropy < 0.0f) {
+ bsdf->alpha_x = roughness / (1.0f + anisotropy);
+ bsdf->alpha_y = roughness * (1.0f + anisotropy);
+ }
+ else {
+ bsdf->alpha_x = roughness * (1.0f - anisotropy);
+ bsdf->alpha_y = roughness / (1.0f - anisotropy);
+ }
+
+ bsdf->ior = 0.0f;
+
+ if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) {
+ sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf);
+ }
+ else if (type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) {
+ sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf);
+ }
+ else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) {
+ kernel_assert(stack_valid(data_node.w));
+ bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
+ if (bsdf->extra) {
+ bsdf->extra->color = stack_load_float3(stack, data_node.w);
+ bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->clearcoat = 0.0f;
+ sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
+ }
+ }
+ else
+ sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf);
+ }
+ break;
+ }
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ VelvetBsdf *bsdf = (VelvetBsdf *)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+
+ bsdf->sigma = saturate(param1);
+ sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
+ }
+ break;
+ }
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
#ifdef __CAUSTICS_TRICKS__
- if(!kernel_data.integrator.caustics_reflective &&
- !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
- {
- break;
- }
+ if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
+ break;
+ ATTR_FALLTHROUGH;
#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
-
- /* index of refraction */
- float eta = fmaxf(param2, 1e-5f);
- eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
-
- /* fresnel */
- float cosNO = dot(N, sd->I);
- float fresnel = fresnel_dielectric_cos(cosNO, eta);
- float roughness = sqr(param1);
-
- /* reflection */
-#ifdef __CAUSTICS_TRICKS__
- if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
-#endif
- {
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*fresnel);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra = NULL;
- svm_node_glass_setup(sd, bsdf, type, eta, roughness, false);
- }
- }
-
- /* refraction */
-#ifdef __CAUSTICS_TRICKS__
- if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
-#endif
- {
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*(1.0f - fresnel));
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra = NULL;
- svm_node_glass_setup(sd, bsdf, type, eta, roughness, true);
- }
- }
-
- break;
- }
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
-#ifdef __CAUSTICS_TRICKS__
- if(!kernel_data.integrator.caustics_reflective && !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
- break;
-#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
- if(!bsdf) {
- break;
- }
-
- MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
- if(!extra) {
- break;
- }
-
- bsdf->N = N;
- bsdf->extra = extra;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
-
- float roughness = sqr(param1);
- bsdf->alpha_x = roughness;
- bsdf->alpha_y = roughness;
- float eta = fmaxf(param2, 1e-5f);
- bsdf->ior = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
-
- kernel_assert(stack_valid(data_node.z));
- bsdf->extra->color = stack_load_float3(stack, data_node.z);
- bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->clearcoat = 0.0f;
-
- /* setup bsdf */
- sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
- break;
- }
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
-#ifdef __CAUSTICS_TRICKS__
- if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
- break;
-#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->extra = NULL;
- bsdf->T = stack_load_float3(stack, data_node.y);
-
- /* rotate tangent */
- float rotation = stack_load_float(stack, data_node.z);
-
- if(rotation != 0.0f)
- bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
-
- /* compute roughness */
- float roughness = sqr(param1);
- float anisotropy = clamp(param2, -0.99f, 0.99f);
-
- if(anisotropy < 0.0f) {
- bsdf->alpha_x = roughness/(1.0f + anisotropy);
- bsdf->alpha_y = roughness*(1.0f + anisotropy);
- }
- else {
- bsdf->alpha_x = roughness*(1.0f - anisotropy);
- bsdf->alpha_y = roughness/(1.0f - anisotropy);
- }
-
- bsdf->ior = 0.0f;
-
- if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) {
- sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf);
- }
- else if(type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) {
- sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf);
- }
- else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) {
- kernel_assert(stack_valid(data_node.w));
- bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
- if(bsdf->extra) {
- bsdf->extra->color = stack_load_float3(stack, data_node.w);
- bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->clearcoat = 0.0f;
- sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
- }
- }
- else
- sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf);
- }
- break;
- }
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
- VelvetBsdf *bsdf = (VelvetBsdf*)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
-
- bsdf->sigma = saturate(param1);
- sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
- }
- break;
- }
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
-#ifdef __CAUSTICS_TRICKS__
- if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
- break;
- ATTR_FALLTHROUGH;
-#endif
- case CLOSURE_BSDF_DIFFUSE_TOON_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
- ToonBsdf *bsdf = (ToonBsdf*)bsdf_alloc(sd, sizeof(ToonBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->size = param1;
- bsdf->smooth = param2;
-
- if(type == CLOSURE_BSDF_DIFFUSE_TOON_ID)
- sd->flag |= bsdf_diffuse_toon_setup(bsdf);
- else
- sd->flag |= bsdf_glossy_toon_setup(bsdf);
- }
- break;
- }
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ ToonBsdf *bsdf = (ToonBsdf *)bsdf_alloc(sd, sizeof(ToonBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->size = param1;
+ bsdf->smooth = param2;
+
+ if (type == CLOSURE_BSDF_DIFFUSE_TOON_ID)
+ sd->flag |= bsdf_diffuse_toon_setup(bsdf);
+ else
+ sd->flag |= bsdf_glossy_toon_setup(bsdf);
+ }
+ break;
+ }
#ifdef __HAIR__
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: {
- uint4 data_node2 = read_node(kg, offset);
- uint4 data_node3 = read_node(kg, offset);
- uint4 data_node4 = read_node(kg, offset);
-
- float3 weight = sd->svm_closure_weight * mix_weight;
-
- uint offset_ofs, ior_ofs, color_ofs, parametrization;
- decode_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, &parametrization);
- float alpha = stack_load_float_default(stack, offset_ofs, data_node.z);
- float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
-
- uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
- decode_node_uchar4(data_node2.x, &coat_ofs, &melanin_ofs, &melanin_redness_ofs, &absorption_coefficient_ofs);
-
- uint tint_ofs, random_ofs, random_color_ofs, random_roughness_ofs;
- decode_node_uchar4(data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &random_roughness_ofs);
-
- const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node4.y);
- float random = 0.0f;
- if(attr_descr_random.offset != ATTR_STD_NOT_FOUND) {
- random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL);
- }
- else {
- random = stack_load_float_default(stack, random_ofs, data_node3.y);
- }
-
-
- PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)bsdf_alloc(sd, sizeof(PrincipledHairBSDF), weight);
- if(bsdf) {
- PrincipledHairExtra *extra = (PrincipledHairExtra*)closure_alloc_extra(sd, sizeof(PrincipledHairExtra));
-
- if(!extra)
- break;
-
- /* Random factors range: [-randomization/2, +randomization/2]. */
- float random_roughness = stack_load_float_default(stack, random_roughness_ofs, data_node3.w);
- float factor_random_roughness = 1.0f + 2.0f*(random - 0.5f)*random_roughness;
- float roughness = param1 * factor_random_roughness;
- float radial_roughness = param2 * factor_random_roughness;
-
- /* Remap Coat value to [0, 100]% of Roughness. */
- float coat = stack_load_float_default(stack, coat_ofs, data_node2.y);
- float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
-
- bsdf->N = N;
- bsdf->v = roughness;
- bsdf->s = radial_roughness;
- bsdf->m0_roughness = m0_roughness;
- bsdf->alpha = alpha;
- bsdf->eta = ior;
- bsdf->extra = extra;
-
- switch(parametrization) {
- case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: {
- float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs);
- bsdf->sigma = absorption_coefficient;
- break;
- }
- case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: {
- float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z);
- float melanin_redness = stack_load_float_default(stack, melanin_redness_ofs, data_node2.w);
-
- /* Randomize melanin. */
- float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z);
- random_color = clamp(random_color, 0.0f, 1.0f);
- float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color;
- melanin *= factor_random_color;
-
- /* Map melanin 0..inf from more perceptually linear 0..1. */
- melanin = -logf(fmaxf(1.0f - melanin, 0.0001f));
-
- /* Benedikt Bitterli's melanin ratio remapping. */
- float eumelanin = melanin * (1.0f - melanin_redness);
- float pheomelanin = melanin * melanin_redness;
- float3 melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin);
-
- /* Optional tint. */
- float3 tint = stack_load_float3(stack, tint_ofs);
- float3 tint_sigma = sigma_from_reflectance(tint, radial_roughness);
-
- bsdf->sigma = melanin_sigma + tint_sigma;
- break;
- }
- case NODE_PRINCIPLED_HAIR_REFLECTANCE: {
- float3 color = stack_load_float3(stack, color_ofs);
- bsdf->sigma = sigma_from_reflectance(color, radial_roughness);
- break;
- }
- default: {
- /* Fallback to brownish hair, same as defaults for melanin. */
- kernel_assert(!"Invalid Principled Hair parametrization!");
- bsdf->sigma = sigma_from_concentration(0.0f, 0.8054375f);
- break;
- }
- }
-
- sd->flag |= bsdf_principled_hair_setup(sd, bsdf);
- }
- break;
- }
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
-
- if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
- /* todo: giving a fixed weight here will cause issues when
- * mixing multiple BSDFS. energy will not be conserved and
- * the throughput can blow up after multiple bounces. we
- * better figure out a way to skip backfaces from rays
- * spawned by transmission from the front */
- bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f), path_flag);
- }
- else {
- HairBsdf *bsdf = (HairBsdf*)bsdf_alloc(sd, sizeof(HairBsdf), weight);
-
- if(bsdf) {
- bsdf->N = N;
- bsdf->roughness1 = param1;
- bsdf->roughness2 = param2;
- bsdf->offset = -stack_load_float(stack, data_node.z);
-
- if(stack_valid(data_node.y)) {
- bsdf->T = normalize(stack_load_float3(stack, data_node.y));
- }
- else if(!(sd->type & PRIMITIVE_ALL_CURVE)) {
- bsdf->T = normalize(sd->dPdv);
- bsdf->offset = 0.0f;
- }
- else
- bsdf->T = normalize(sd->dPdu);
-
- if(type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
- sd->flag |= bsdf_hair_reflection_setup(bsdf);
- }
- else {
- sd->flag |= bsdf_hair_transmission_setup(bsdf);
- }
- }
- }
-
- break;
- }
-#endif /* __HAIR__ */
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: {
+ uint4 data_node2 = read_node(kg, offset);
+ uint4 data_node3 = read_node(kg, offset);
+ uint4 data_node4 = read_node(kg, offset);
+
+ float3 weight = sd->svm_closure_weight * mix_weight;
+
+ uint offset_ofs, ior_ofs, color_ofs, parametrization;
+ decode_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, &parametrization);
+ float alpha = stack_load_float_default(stack, offset_ofs, data_node.z);
+ float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
+
+ uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
+ decode_node_uchar4(data_node2.x,
+ &coat_ofs,
+ &melanin_ofs,
+ &melanin_redness_ofs,
+ &absorption_coefficient_ofs);
+
+ uint tint_ofs, random_ofs, random_color_ofs, random_roughness_ofs;
+ decode_node_uchar4(
+ data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &random_roughness_ofs);
+
+ const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node4.y);
+ float random = 0.0f;
+ if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) {
+ random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL);
+ }
+ else {
+ random = stack_load_float_default(stack, random_ofs, data_node3.y);
+ }
+
+ PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc(
+ sd, sizeof(PrincipledHairBSDF), weight);
+ if (bsdf) {
+ PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra(
+ sd, sizeof(PrincipledHairExtra));
+
+ if (!extra)
+ break;
+
+ /* Random factors range: [-randomization/2, +randomization/2]. */
+ float random_roughness = stack_load_float_default(
+ stack, random_roughness_ofs, data_node3.w);
+ float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness;
+ float roughness = param1 * factor_random_roughness;
+ float radial_roughness = param2 * factor_random_roughness;
+
+ /* Remap Coat value to [0, 100]% of Roughness. */
+ float coat = stack_load_float_default(stack, coat_ofs, data_node2.y);
+ float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
+
+ bsdf->N = N;
+ bsdf->v = roughness;
+ bsdf->s = radial_roughness;
+ bsdf->m0_roughness = m0_roughness;
+ bsdf->alpha = alpha;
+ bsdf->eta = ior;
+ bsdf->extra = extra;
+
+ switch (parametrization) {
+ case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: {
+ float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs);
+ bsdf->sigma = absorption_coefficient;
+ break;
+ }
+ case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: {
+ float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z);
+ float melanin_redness = stack_load_float_default(
+ stack, melanin_redness_ofs, data_node2.w);
+
+ /* Randomize melanin. */
+ float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z);
+ random_color = clamp(random_color, 0.0f, 1.0f);
+ float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color;
+ melanin *= factor_random_color;
+
+ /* Map melanin 0..inf from more perceptually linear 0..1. */
+ melanin = -logf(fmaxf(1.0f - melanin, 0.0001f));
+
+ /* Benedikt Bitterli's melanin ratio remapping. */
+ float eumelanin = melanin * (1.0f - melanin_redness);
+ float pheomelanin = melanin * melanin_redness;
+ float3 melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin);
+
+ /* Optional tint. */
+ float3 tint = stack_load_float3(stack, tint_ofs);
+ float3 tint_sigma = sigma_from_reflectance(tint, radial_roughness);
+
+ bsdf->sigma = melanin_sigma + tint_sigma;
+ break;
+ }
+ case NODE_PRINCIPLED_HAIR_REFLECTANCE: {
+ float3 color = stack_load_float3(stack, color_ofs);
+ bsdf->sigma = sigma_from_reflectance(color, radial_roughness);
+ break;
+ }
+ default: {
+ /* Fallback to brownish hair, same as defaults for melanin. */
+ kernel_assert(!"Invalid Principled Hair parametrization!");
+ bsdf->sigma = sigma_from_concentration(0.0f, 0.8054375f);
+ break;
+ }
+ }
+
+ sd->flag |= bsdf_principled_hair_setup(sd, bsdf);
+ }
+ break;
+ }
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+
+ if (sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
+ /* todo: giving a fixed weight here will cause issues when
+ * mixing multiple BSDFS. energy will not be conserved and
+ * the throughput can blow up after multiple bounces. we
+ * better figure out a way to skip backfaces from rays
+ * spawned by transmission from the front */
+ bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f), path_flag);
+ }
+ else {
+ HairBsdf *bsdf = (HairBsdf *)bsdf_alloc(sd, sizeof(HairBsdf), weight);
+
+ if (bsdf) {
+ bsdf->N = N;
+ bsdf->roughness1 = param1;
+ bsdf->roughness2 = param2;
+ bsdf->offset = -stack_load_float(stack, data_node.z);
+
+ if (stack_valid(data_node.y)) {
+ bsdf->T = normalize(stack_load_float3(stack, data_node.y));
+ }
+ else if (!(sd->type & PRIMITIVE_ALL_CURVE)) {
+ bsdf->T = normalize(sd->dPdv);
+ bsdf->offset = 0.0f;
+ }
+ else
+ bsdf->T = normalize(sd->dPdu);
+
+ if (type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
+ sd->flag |= bsdf_hair_reflection_setup(bsdf);
+ }
+ else {
+ sd->flag |= bsdf_hair_transmission_setup(bsdf);
+ }
+ }
+ }
+
+ break;
+ }
+#endif /* __HAIR__ */
#ifdef __SUBSURFACE__
- case CLOSURE_BSSRDF_CUBIC_ID:
- case CLOSURE_BSSRDF_GAUSSIAN_ID:
- case CLOSURE_BSSRDF_BURLEY_ID:
- case CLOSURE_BSSRDF_RANDOM_WALK_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
- Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
-
- if(bssrdf) {
- /* disable in case of diffuse ancestor, can't see it well then and
- * adds considerably noise due to probabilities of continuing path
- * getting lower and lower */
- if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
- param1 = 0.0f;
-
- bssrdf->radius = stack_load_float3(stack, data_node.z)*param1;
- bssrdf->albedo = sd->svm_closure_weight;
- bssrdf->texture_blur = param2;
- bssrdf->sharpness = stack_load_float(stack, data_node.w);
- bssrdf->N = N;
- bssrdf->roughness = 0.0f;
- sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
- }
-
- break;
- }
+ case CLOSURE_BSSRDF_CUBIC_ID:
+ case CLOSURE_BSSRDF_GAUSSIAN_ID:
+ case CLOSURE_BSSRDF_BURLEY_ID:
+ case CLOSURE_BSSRDF_RANDOM_WALK_ID: {
+ float3 weight = sd->svm_closure_weight * mix_weight;
+ Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
+
+ if (bssrdf) {
+ /* disable in case of diffuse ancestor, can't see it well then and
+ * adds considerably noise due to probabilities of continuing path
+ * getting lower and lower */
+ if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
+ param1 = 0.0f;
+
+ bssrdf->radius = stack_load_float3(stack, data_node.z) * param1;
+ bssrdf->albedo = sd->svm_closure_weight;
+ bssrdf->texture_blur = param2;
+ bssrdf->sharpness = stack_load_float(stack, data_node.w);
+ bssrdf->N = N;
+ bssrdf->roughness = 0.0f;
+ sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
+ }
+
+ break;
+ }
#endif
- default:
- break;
- }
+ default:
+ break;
+ }
}
-ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type)
+ccl_device void svm_node_closure_volume(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type)
{
#ifdef __VOLUME__
- /* Only sum extinction for volumes, variable is shared with surface transparency. */
- if(shader_type != SHADER_TYPE_VOLUME) {
- return;
- }
-
- uint type, density_offset, anisotropy_offset;
-
- uint mix_weight_offset;
- decode_node_uchar4(node.y, &type, &density_offset, &anisotropy_offset, &mix_weight_offset);
- float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
-
- if(mix_weight == 0.0f) {
- return;
- }
-
- float density = (stack_valid(density_offset))? stack_load_float(stack, density_offset): __uint_as_float(node.z);
- density = mix_weight * fmaxf(density, 0.0f);
-
- /* Compute scattering coefficient. */
- float3 weight = sd->svm_closure_weight;
-
- if(type == CLOSURE_VOLUME_ABSORPTION_ID) {
- weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
- }
-
- weight *= density;
-
- /* Add closure for volume scattering. */
- if(type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) {
- HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
-
- if(volume) {
- float anisotropy = (stack_valid(anisotropy_offset))? stack_load_float(stack, anisotropy_offset): __uint_as_float(node.w);
- volume->g = anisotropy; /* g */
- sd->flag |= volume_henyey_greenstein_setup(volume);
- }
- }
-
- /* Sum total extinction weight. */
- volume_extinction_setup(sd, weight);
+ /* Only sum extinction for volumes, variable is shared with surface transparency. */
+ if (shader_type != SHADER_TYPE_VOLUME) {
+ return;
+ }
+
+ uint type, density_offset, anisotropy_offset;
+
+ uint mix_weight_offset;
+ decode_node_uchar4(node.y, &type, &density_offset, &anisotropy_offset, &mix_weight_offset);
+ float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
+ 1.0f);
+
+ if (mix_weight == 0.0f) {
+ return;
+ }
+
+ float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
+ __uint_as_float(node.z);
+ density = mix_weight * fmaxf(density, 0.0f);
+
+ /* Compute scattering coefficient. */
+ float3 weight = sd->svm_closure_weight;
+
+ if (type == CLOSURE_VOLUME_ABSORPTION_ID) {
+ weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
+ }
+
+ weight *= density;
+
+ /* Add closure for volume scattering. */
+ if (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) {
+ HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc(
+ sd, sizeof(HenyeyGreensteinVolume), weight);
+
+ if (volume) {
+ float anisotropy = (stack_valid(anisotropy_offset)) ?
+ stack_load_float(stack, anisotropy_offset) :
+ __uint_as_float(node.w);
+ volume->g = anisotropy; /* g */
+ sd->flag |= volume_henyey_greenstein_setup(volume);
+ }
+ }
+
+ /* Sum total extinction weight. */
+ volume_extinction_setup(sd, weight);
#endif
}
-ccl_device void svm_node_principled_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag, int *offset)
+ccl_device void svm_node_principled_volume(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint4 node,
+ ShaderType shader_type,
+ int path_flag,
+ int *offset)
{
#ifdef __VOLUME__
- uint4 value_node = read_node(kg, offset);
- uint4 attr_node = read_node(kg, offset);
-
- /* Only sum extinction for volumes, variable is shared with surface transparency. */
- if(shader_type != SHADER_TYPE_VOLUME) {
- return;
- }
-
- uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset;
- decode_node_uchar4(node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset);
- float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
-
- if(mix_weight == 0.0f) {
- return;
- }
-
- /* Compute density. */
- float primitive_density = 1.0f;
- float density = (stack_valid(density_offset))? stack_load_float(stack, density_offset): __uint_as_float(value_node.x);
- density = mix_weight * fmaxf(density, 0.0f);
-
- if(density > CLOSURE_WEIGHT_CUTOFF) {
- /* Density and color attribute lookup if available. */
- const AttributeDescriptor attr_density = find_attribute(kg, sd, attr_node.x);
- if(attr_density.offset != ATTR_STD_NOT_FOUND) {
- primitive_density = primitive_volume_attribute_float(kg, sd, attr_density);
- density = fmaxf(density * primitive_density, 0.0f);
- }
- }
-
- if(density > CLOSURE_WEIGHT_CUTOFF) {
- /* Compute scattering color. */
- float3 color = sd->svm_closure_weight;
-
- const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y);
- if(attr_color.offset != ATTR_STD_NOT_FOUND) {
- color *= primitive_volume_attribute_float3(kg, sd, attr_color);
- }
-
- /* Add closure for volume scattering. */
- HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), color * density);
- if(volume) {
- float anisotropy = (stack_valid(anisotropy_offset))? stack_load_float(stack, anisotropy_offset): __uint_as_float(value_node.y);
- volume->g = anisotropy;
- sd->flag |= volume_henyey_greenstein_setup(volume);
- }
-
- /* Add extinction weight. */
- float3 zero = make_float3(0.0f, 0.0f, 0.0f);
- float3 one = make_float3(1.0f, 1.0f, 1.0f);
- float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero);
- float3 absorption = max(one - color, zero) * max(one - absorption_color, zero);
- volume_extinction_setup(sd, (color + absorption) * density);
- }
-
- /* Compute emission. */
- if(path_flag & PATH_RAY_SHADOW) {
- /* Don't need emission for shadows. */
- return;
- }
-
- uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset;
- decode_node_uchar4(node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset);
- float emission = (stack_valid(emission_offset))? stack_load_float(stack, emission_offset): __uint_as_float(value_node.z);
- float blackbody = (stack_valid(blackbody_offset))? stack_load_float(stack, blackbody_offset): __uint_as_float(value_node.w);
-
- if(emission > CLOSURE_WEIGHT_CUTOFF) {
- float3 emission_color = stack_load_float3(stack, emission_color_offset);
- emission_setup(sd, emission * emission_color);
- }
-
- if(blackbody > CLOSURE_WEIGHT_CUTOFF) {
- float T = stack_load_float(stack, temperature_offset);
-
- /* Add flame temperature from attribute if available. */
- const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z);
- if(attr_temperature.offset != ATTR_STD_NOT_FOUND) {
- float temperature = primitive_volume_attribute_float(kg, sd, attr_temperature);
- T *= fmaxf(temperature, 0.0f);
- }
-
- T = fmaxf(T, 0.0f);
-
- /* Stefan-Boltzmann law. */
- float T4 = sqr(sqr(T));
- float sigma = 5.670373e-8f * 1e-6f / M_PI_F;
- float intensity = sigma * mix(1.0f, T4, blackbody);
-
- if(intensity > CLOSURE_WEIGHT_CUTOFF) {
- float3 blackbody_tint = stack_load_float3(stack, node.w);
- float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T);
- emission_setup(sd, bb);
- }
- }
+ uint4 value_node = read_node(kg, offset);
+ uint4 attr_node = read_node(kg, offset);
+
+ /* Only sum extinction for volumes, variable is shared with surface transparency. */
+ if (shader_type != SHADER_TYPE_VOLUME) {
+ return;
+ }
+
+ uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset;
+ decode_node_uchar4(
+ node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset);
+ float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
+ 1.0f);
+
+ if (mix_weight == 0.0f) {
+ return;
+ }
+
+ /* Compute density. */
+ float primitive_density = 1.0f;
+ float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
+ __uint_as_float(value_node.x);
+ density = mix_weight * fmaxf(density, 0.0f);
+
+ if (density > CLOSURE_WEIGHT_CUTOFF) {
+ /* Density and color attribute lookup if available. */
+ const AttributeDescriptor attr_density = find_attribute(kg, sd, attr_node.x);
+ if (attr_density.offset != ATTR_STD_NOT_FOUND) {
+ primitive_density = primitive_volume_attribute_float(kg, sd, attr_density);
+ density = fmaxf(density * primitive_density, 0.0f);
+ }
+ }
+
+ if (density > CLOSURE_WEIGHT_CUTOFF) {
+ /* Compute scattering color. */
+ float3 color = sd->svm_closure_weight;
+
+ const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y);
+ if (attr_color.offset != ATTR_STD_NOT_FOUND) {
+ color *= primitive_volume_attribute_float3(kg, sd, attr_color);
+ }
+
+ /* Add closure for volume scattering. */
+ HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc(
+ sd, sizeof(HenyeyGreensteinVolume), color * density);
+ if (volume) {
+ float anisotropy = (stack_valid(anisotropy_offset)) ?
+ stack_load_float(stack, anisotropy_offset) :
+ __uint_as_float(value_node.y);
+ volume->g = anisotropy;
+ sd->flag |= volume_henyey_greenstein_setup(volume);
+ }
+
+ /* Add extinction weight. */
+ float3 zero = make_float3(0.0f, 0.0f, 0.0f);
+ float3 one = make_float3(1.0f, 1.0f, 1.0f);
+ float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero);
+ float3 absorption = max(one - color, zero) * max(one - absorption_color, zero);
+ volume_extinction_setup(sd, (color + absorption) * density);
+ }
+
+ /* Compute emission. */
+ if (path_flag & PATH_RAY_SHADOW) {
+ /* Don't need emission for shadows. */
+ return;
+ }
+
+ uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset;
+ decode_node_uchar4(
+ node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset);
+ float emission = (stack_valid(emission_offset)) ? stack_load_float(stack, emission_offset) :
+ __uint_as_float(value_node.z);
+ float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(stack, blackbody_offset) :
+ __uint_as_float(value_node.w);
+
+ if (emission > CLOSURE_WEIGHT_CUTOFF) {
+ float3 emission_color = stack_load_float3(stack, emission_color_offset);
+ emission_setup(sd, emission * emission_color);
+ }
+
+ if (blackbody > CLOSURE_WEIGHT_CUTOFF) {
+ float T = stack_load_float(stack, temperature_offset);
+
+ /* Add flame temperature from attribute if available. */
+ const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z);
+ if (attr_temperature.offset != ATTR_STD_NOT_FOUND) {
+ float temperature = primitive_volume_attribute_float(kg, sd, attr_temperature);
+ T *= fmaxf(temperature, 0.0f);
+ }
+
+ T = fmaxf(T, 0.0f);
+
+ /* Stefan-Boltzmann law. */
+ float T4 = sqr(sqr(T));
+ float sigma = 5.670373e-8f * 1e-6f / M_PI_F;
+ float intensity = sigma * mix(1.0f, T4, blackbody);
+
+ if (intensity > CLOSURE_WEIGHT_CUTOFF) {
+ float3 blackbody_tint = stack_load_float3(stack, node.w);
+ float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T);
+ emission_setup(sd, bb);
+ }
+ }
#endif
}
ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
{
- uint mix_weight_offset = node.y;
- float3 weight = sd->svm_closure_weight;
+ uint mix_weight_offset = node.y;
+ float3 weight = sd->svm_closure_weight;
- if(stack_valid(mix_weight_offset)) {
- float mix_weight = stack_load_float(stack, mix_weight_offset);
+ if (stack_valid(mix_weight_offset)) {
+ float mix_weight = stack_load_float(stack, mix_weight_offset);
- if(mix_weight == 0.0f)
- return;
+ if (mix_weight == 0.0f)
+ return;
- weight *= mix_weight;
- }
+ weight *= mix_weight;
+ }
- emission_setup(sd, weight);
+ emission_setup(sd, weight);
}
ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
{
- uint mix_weight_offset = node.y;
- float3 weight = sd->svm_closure_weight;
+ uint mix_weight_offset = node.y;
+ float3 weight = sd->svm_closure_weight;
- if(stack_valid(mix_weight_offset)) {
- float mix_weight = stack_load_float(stack, mix_weight_offset);
+ if (stack_valid(mix_weight_offset)) {
+ float mix_weight = stack_load_float(stack, mix_weight_offset);
- if(mix_weight == 0.0f)
- return;
+ if (mix_weight == 0.0f)
+ return;
- weight *= mix_weight;
- }
+ weight *= mix_weight;
+ }
- background_setup(sd, weight);
+ background_setup(sd, weight);
}
ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
{
- uint mix_weight_offset = node.y;
+ uint mix_weight_offset = node.y;
- if(stack_valid(mix_weight_offset)) {
- float mix_weight = stack_load_float(stack, mix_weight_offset);
+ if (stack_valid(mix_weight_offset)) {
+ float mix_weight = stack_load_float(stack, mix_weight_offset);
- if(mix_weight == 0.0f)
- return;
+ if (mix_weight == 0.0f)
+ return;
- closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight);
- }
- else
- closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight);
+ closure_alloc(
+ sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight);
+ }
+ else
+ closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight);
- sd->flag |= SD_HOLDOUT;
+ sd->flag |= SD_HOLDOUT;
}
/* Closure Nodes */
ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
{
- sd->svm_closure_weight = weight;
+ sd->svm_closure_weight = weight;
}
ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
{
- float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
- svm_node_closure_store_weight(sd, weight);
+ float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
+ svm_node_closure_store_weight(sd, weight);
}
ccl_device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset)
{
- float3 weight = stack_load_float3(stack, weight_offset);
+ float3 weight = stack_load_float3(stack, weight_offset);
- svm_node_closure_store_weight(sd, weight);
+ svm_node_closure_store_weight(sd, weight);
}
-ccl_device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
+ccl_device void svm_node_emission_weight(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint4 node)
{
- uint color_offset = node.y;
- uint strength_offset = node.z;
+ uint color_offset = node.y;
+ uint strength_offset = node.z;
- float strength = stack_load_float(stack, strength_offset);
- float3 weight = stack_load_float3(stack, color_offset)*strength;
+ float strength = stack_load_float(stack, strength_offset);
+ float3 weight = stack_load_float3(stack, color_offset) * strength;
- svm_node_closure_store_weight(sd, weight);
+ svm_node_closure_store_weight(sd, weight);
}
ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node)
{
- /* fetch weight from blend input, previous mix closures,
- * and write to stack to be used by closure nodes later */
- uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
- decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
+ /* fetch weight from blend input, previous mix closures,
+ * and write to stack to be used by closure nodes later */
+ uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
+ decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
- float weight = stack_load_float(stack, weight_offset);
- weight = saturate(weight);
+ float weight = stack_load_float(stack, weight_offset);
+ weight = saturate(weight);
- float in_weight = (stack_valid(in_weight_offset))? stack_load_float(stack, in_weight_offset): 1.0f;
+ float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(stack, in_weight_offset) :
+ 1.0f;
- if(stack_valid(weight1_offset))
- stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight));
- if(stack_valid(weight2_offset))
- stack_store_float(stack, weight2_offset, in_weight*weight);
+ if (stack_valid(weight1_offset))
+ stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight));
+ if (stack_valid(weight2_offset))
+ stack_store_float(stack, weight2_offset, in_weight * weight);
}
/* (Bump) normal */
-ccl_device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
+ccl_device void svm_node_set_normal(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
{
- float3 normal = stack_load_float3(stack, in_direction);
- sd->N = normal;
- stack_store_float3(stack, out_normal, normal);
+ float3 normal = stack_load_float3(stack, in_direction);
+ sd->N = normal;
+ stack_store_float3(stack, out_normal, normal);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_color_util.h b/intern/cycles/kernel/svm/svm_color_util.h
index d5945f915c6..12b59d2616b 100644
--- a/intern/cycles/kernel/svm/svm_color_util.h
+++ b/intern/cycles/kernel/svm/svm_color_util.h
@@ -18,288 +18,310 @@ CCL_NAMESPACE_BEGIN
ccl_device float3 svm_mix_blend(float t, float3 col1, float3 col2)
{
- return interp(col1, col2, t);
+ return interp(col1, col2, t);
}
ccl_device float3 svm_mix_add(float t, float3 col1, float3 col2)
{
- return interp(col1, col1 + col2, t);
+ return interp(col1, col1 + col2, t);
}
ccl_device float3 svm_mix_mul(float t, float3 col1, float3 col2)
{
- return interp(col1, col1 * col2, t);
+ return interp(col1, col1 * col2, t);
}
ccl_device float3 svm_mix_screen(float t, float3 col1, float3 col2)
{
- float tm = 1.0f - t;
- float3 one = make_float3(1.0f, 1.0f, 1.0f);
- float3 tm3 = make_float3(tm, tm, tm);
+ float tm = 1.0f - t;
+ float3 one = make_float3(1.0f, 1.0f, 1.0f);
+ float3 tm3 = make_float3(tm, tm, tm);
- return one - (tm3 + t*(one - col2))*(one - col1);
+ return one - (tm3 + t * (one - col2)) * (one - col1);
}
ccl_device float3 svm_mix_overlay(float t, float3 col1, float3 col2)
{
- float tm = 1.0f - t;
+ float tm = 1.0f - t;
- float3 outcol = col1;
+ float3 outcol = col1;
- if(outcol.x < 0.5f)
- outcol.x *= tm + 2.0f*t*col2.x;
- else
- outcol.x = 1.0f - (tm + 2.0f*t*(1.0f - col2.x))*(1.0f - outcol.x);
+ if (outcol.x < 0.5f)
+ outcol.x *= tm + 2.0f * t * col2.x;
+ else
+ outcol.x = 1.0f - (tm + 2.0f * t * (1.0f - col2.x)) * (1.0f - outcol.x);
- if(outcol.y < 0.5f)
- outcol.y *= tm + 2.0f*t*col2.y;
- else
- outcol.y = 1.0f - (tm + 2.0f*t*(1.0f - col2.y))*(1.0f - outcol.y);
+ if (outcol.y < 0.5f)
+ outcol.y *= tm + 2.0f * t * col2.y;
+ else
+ outcol.y = 1.0f - (tm + 2.0f * t * (1.0f - col2.y)) * (1.0f - outcol.y);
- if(outcol.z < 0.5f)
- outcol.z *= tm + 2.0f*t*col2.z;
- else
- outcol.z = 1.0f - (tm + 2.0f*t*(1.0f - col2.z))*(1.0f - outcol.z);
+ if (outcol.z < 0.5f)
+ outcol.z *= tm + 2.0f * t * col2.z;
+ else
+ outcol.z = 1.0f - (tm + 2.0f * t * (1.0f - col2.z)) * (1.0f - outcol.z);
- return outcol;
+ return outcol;
}
ccl_device float3 svm_mix_sub(float t, float3 col1, float3 col2)
{
- return interp(col1, col1 - col2, t);
+ return interp(col1, col1 - col2, t);
}
ccl_device float3 svm_mix_div(float t, float3 col1, float3 col2)
{
- float tm = 1.0f - t;
+ float tm = 1.0f - t;
- float3 outcol = col1;
+ float3 outcol = col1;
- if(col2.x != 0.0f) outcol.x = tm*outcol.x + t*outcol.x/col2.x;
- if(col2.y != 0.0f) outcol.y = tm*outcol.y + t*outcol.y/col2.y;
- if(col2.z != 0.0f) outcol.z = tm*outcol.z + t*outcol.z/col2.z;
+ if (col2.x != 0.0f)
+ outcol.x = tm * outcol.x + t * outcol.x / col2.x;
+ if (col2.y != 0.0f)
+ outcol.y = tm * outcol.y + t * outcol.y / col2.y;
+ if (col2.z != 0.0f)
+ outcol.z = tm * outcol.z + t * outcol.z / col2.z;
- return outcol;
+ return outcol;
}
ccl_device float3 svm_mix_diff(float t, float3 col1, float3 col2)
{
- return interp(col1, fabs(col1 - col2), t);
+ return interp(col1, fabs(col1 - col2), t);
}
ccl_device float3 svm_mix_dark(float t, float3 col1, float3 col2)
{
- return min(col1, col2)*t + col1*(1.0f - t);
+ return min(col1, col2) * t + col1 * (1.0f - t);
}
ccl_device float3 svm_mix_light(float t, float3 col1, float3 col2)
{
- return max(col1, col2*t);
+ return max(col1, col2 * t);
}
ccl_device float3 svm_mix_dodge(float t, float3 col1, float3 col2)
{
- float3 outcol = col1;
-
- if(outcol.x != 0.0f) {
- float tmp = 1.0f - t*col2.x;
- if(tmp <= 0.0f)
- outcol.x = 1.0f;
- else if((tmp = outcol.x/tmp) > 1.0f)
- outcol.x = 1.0f;
- else
- outcol.x = tmp;
- }
- if(outcol.y != 0.0f) {
- float tmp = 1.0f - t*col2.y;
- if(tmp <= 0.0f)
- outcol.y = 1.0f;
- else if((tmp = outcol.y/tmp) > 1.0f)
- outcol.y = 1.0f;
- else
- outcol.y = tmp;
- }
- if(outcol.z != 0.0f) {
- float tmp = 1.0f - t*col2.z;
- if(tmp <= 0.0f)
- outcol.z = 1.0f;
- else if((tmp = outcol.z/tmp) > 1.0f)
- outcol.z = 1.0f;
- else
- outcol.z = tmp;
- }
-
- return outcol;
+ float3 outcol = col1;
+
+ if (outcol.x != 0.0f) {
+ float tmp = 1.0f - t * col2.x;
+ if (tmp <= 0.0f)
+ outcol.x = 1.0f;
+ else if ((tmp = outcol.x / tmp) > 1.0f)
+ outcol.x = 1.0f;
+ else
+ outcol.x = tmp;
+ }
+ if (outcol.y != 0.0f) {
+ float tmp = 1.0f - t * col2.y;
+ if (tmp <= 0.0f)
+ outcol.y = 1.0f;
+ else if ((tmp = outcol.y / tmp) > 1.0f)
+ outcol.y = 1.0f;
+ else
+ outcol.y = tmp;
+ }
+ if (outcol.z != 0.0f) {
+ float tmp = 1.0f - t * col2.z;
+ if (tmp <= 0.0f)
+ outcol.z = 1.0f;
+ else if ((tmp = outcol.z / tmp) > 1.0f)
+ outcol.z = 1.0f;
+ else
+ outcol.z = tmp;
+ }
+
+ return outcol;
}
ccl_device float3 svm_mix_burn(float t, float3 col1, float3 col2)
{
- float tmp, tm = 1.0f - t;
-
- float3 outcol = col1;
-
- tmp = tm + t*col2.x;
- if(tmp <= 0.0f)
- outcol.x = 0.0f;
- else if((tmp = (1.0f - (1.0f - outcol.x)/tmp)) < 0.0f)
- outcol.x = 0.0f;
- else if(tmp > 1.0f)
- outcol.x = 1.0f;
- else
- outcol.x = tmp;
-
- tmp = tm + t*col2.y;
- if(tmp <= 0.0f)
- outcol.y = 0.0f;
- else if((tmp = (1.0f - (1.0f - outcol.y)/tmp)) < 0.0f)
- outcol.y = 0.0f;
- else if(tmp > 1.0f)
- outcol.y = 1.0f;
- else
- outcol.y = tmp;
-
- tmp = tm + t*col2.z;
- if(tmp <= 0.0f)
- outcol.z = 0.0f;
- else if((tmp = (1.0f - (1.0f - outcol.z)/tmp)) < 0.0f)
- outcol.z = 0.0f;
- else if(tmp > 1.0f)
- outcol.z = 1.0f;
- else
- outcol.z = tmp;
-
- return outcol;
+ float tmp, tm = 1.0f - t;
+
+ float3 outcol = col1;
+
+ tmp = tm + t * col2.x;
+ if (tmp <= 0.0f)
+ outcol.x = 0.0f;
+ else if ((tmp = (1.0f - (1.0f - outcol.x) / tmp)) < 0.0f)
+ outcol.x = 0.0f;
+ else if (tmp > 1.0f)
+ outcol.x = 1.0f;
+ else
+ outcol.x = tmp;
+
+ tmp = tm + t * col2.y;
+ if (tmp <= 0.0f)
+ outcol.y = 0.0f;
+ else if ((tmp = (1.0f - (1.0f - outcol.y) / tmp)) < 0.0f)
+ outcol.y = 0.0f;
+ else if (tmp > 1.0f)
+ outcol.y = 1.0f;
+ else
+ outcol.y = tmp;
+
+ tmp = tm + t * col2.z;
+ if (tmp <= 0.0f)
+ outcol.z = 0.0f;
+ else if ((tmp = (1.0f - (1.0f - outcol.z) / tmp)) < 0.0f)
+ outcol.z = 0.0f;
+ else if (tmp > 1.0f)
+ outcol.z = 1.0f;
+ else
+ outcol.z = tmp;
+
+ return outcol;
}
ccl_device float3 svm_mix_hue(float t, float3 col1, float3 col2)
{
- float3 outcol = col1;
+ float3 outcol = col1;
- float3 hsv2 = rgb_to_hsv(col2);
+ float3 hsv2 = rgb_to_hsv(col2);
- if(hsv2.y != 0.0f) {
- float3 hsv = rgb_to_hsv(outcol);
- hsv.x = hsv2.x;
- float3 tmp = hsv_to_rgb(hsv);
+ if (hsv2.y != 0.0f) {
+ float3 hsv = rgb_to_hsv(outcol);
+ hsv.x = hsv2.x;
+ float3 tmp = hsv_to_rgb(hsv);
- outcol = interp(outcol, tmp, t);
- }
+ outcol = interp(outcol, tmp, t);
+ }
- return outcol;
+ return outcol;
}
ccl_device float3 svm_mix_sat(float t, float3 col1, float3 col2)
{
- float tm = 1.0f - t;
+ float tm = 1.0f - t;
- float3 outcol = col1;
+ float3 outcol = col1;
- float3 hsv = rgb_to_hsv(outcol);
+ float3 hsv = rgb_to_hsv(outcol);
- if(hsv.y != 0.0f) {
- float3 hsv2 = rgb_to_hsv(col2);
+ if (hsv.y != 0.0f) {
+ float3 hsv2 = rgb_to_hsv(col2);
- hsv.y = tm*hsv.y + t*hsv2.y;
- outcol = hsv_to_rgb(hsv);
- }
+ hsv.y = tm * hsv.y + t * hsv2.y;
+ outcol = hsv_to_rgb(hsv);
+ }
- return outcol;
+ return outcol;
}
ccl_device float3 svm_mix_val(float t, float3 col1, float3 col2)
{
- float tm = 1.0f - t;
+ float tm = 1.0f - t;
- float3 hsv = rgb_to_hsv(col1);
- float3 hsv2 = rgb_to_hsv(col2);
+ float3 hsv = rgb_to_hsv(col1);
+ float3 hsv2 = rgb_to_hsv(col2);
- hsv.z = tm*hsv.z + t*hsv2.z;
+ hsv.z = tm * hsv.z + t * hsv2.z;
- return hsv_to_rgb(hsv);
+ return hsv_to_rgb(hsv);
}
ccl_device float3 svm_mix_color(float t, float3 col1, float3 col2)
{
- float3 outcol = col1;
- float3 hsv2 = rgb_to_hsv(col2);
+ float3 outcol = col1;
+ float3 hsv2 = rgb_to_hsv(col2);
- if(hsv2.y != 0.0f) {
- float3 hsv = rgb_to_hsv(outcol);
- hsv.x = hsv2.x;
- hsv.y = hsv2.y;
- float3 tmp = hsv_to_rgb(hsv);
+ if (hsv2.y != 0.0f) {
+ float3 hsv = rgb_to_hsv(outcol);
+ hsv.x = hsv2.x;
+ hsv.y = hsv2.y;
+ float3 tmp = hsv_to_rgb(hsv);
- outcol = interp(outcol, tmp, t);
- }
+ outcol = interp(outcol, tmp, t);
+ }
- return outcol;
+ return outcol;
}
ccl_device float3 svm_mix_soft(float t, float3 col1, float3 col2)
{
- float tm = 1.0f - t;
+ float tm = 1.0f - t;
- float3 one = make_float3(1.0f, 1.0f, 1.0f);
- float3 scr = one - (one - col2)*(one - col1);
+ float3 one = make_float3(1.0f, 1.0f, 1.0f);
+ float3 scr = one - (one - col2) * (one - col1);
- return tm*col1 + t*((one - col1)*col2*col1 + col1*scr);
+ return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr);
}
ccl_device float3 svm_mix_linear(float t, float3 col1, float3 col2)
{
- return col1 + t*(2.0f*col2 + make_float3(-1.0f, -1.0f, -1.0f));
+ return col1 + t * (2.0f * col2 + make_float3(-1.0f, -1.0f, -1.0f));
}
ccl_device float3 svm_mix_clamp(float3 col)
{
- float3 outcol = col;
+ float3 outcol = col;
- outcol.x = saturate(col.x);
- outcol.y = saturate(col.y);
- outcol.z = saturate(col.z);
+ outcol.x = saturate(col.x);
+ outcol.y = saturate(col.y);
+ outcol.z = saturate(col.z);
- return outcol;
+ return outcol;
}
ccl_device_noinline float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2)
{
- float t = saturate(fac);
-
- switch(type) {
- case NODE_MIX_BLEND: return svm_mix_blend(t, c1, c2);
- case NODE_MIX_ADD: return svm_mix_add(t, c1, c2);
- case NODE_MIX_MUL: return svm_mix_mul(t, c1, c2);
- case NODE_MIX_SCREEN: return svm_mix_screen(t, c1, c2);
- case NODE_MIX_OVERLAY: return svm_mix_overlay(t, c1, c2);
- case NODE_MIX_SUB: return svm_mix_sub(t, c1, c2);
- case NODE_MIX_DIV: return svm_mix_div(t, c1, c2);
- case NODE_MIX_DIFF: return svm_mix_diff(t, c1, c2);
- case NODE_MIX_DARK: return svm_mix_dark(t, c1, c2);
- case NODE_MIX_LIGHT: return svm_mix_light(t, c1, c2);
- case NODE_MIX_DODGE: return svm_mix_dodge(t, c1, c2);
- case NODE_MIX_BURN: return svm_mix_burn(t, c1, c2);
- case NODE_MIX_HUE: return svm_mix_hue(t, c1, c2);
- case NODE_MIX_SAT: return svm_mix_sat(t, c1, c2);
- case NODE_MIX_VAL: return svm_mix_val (t, c1, c2);
- case NODE_MIX_COLOR: return svm_mix_color(t, c1, c2);
- case NODE_MIX_SOFT: return svm_mix_soft(t, c1, c2);
- case NODE_MIX_LINEAR: return svm_mix_linear(t, c1, c2);
- case NODE_MIX_CLAMP: return svm_mix_clamp(c1);
- }
-
- return make_float3(0.0f, 0.0f, 0.0f);
+ float t = saturate(fac);
+
+ switch (type) {
+ case NODE_MIX_BLEND:
+ return svm_mix_blend(t, c1, c2);
+ case NODE_MIX_ADD:
+ return svm_mix_add(t, c1, c2);
+ case NODE_MIX_MUL:
+ return svm_mix_mul(t, c1, c2);
+ case NODE_MIX_SCREEN:
+ return svm_mix_screen(t, c1, c2);
+ case NODE_MIX_OVERLAY:
+ return svm_mix_overlay(t, c1, c2);
+ case NODE_MIX_SUB:
+ return svm_mix_sub(t, c1, c2);
+ case NODE_MIX_DIV:
+ return svm_mix_div(t, c1, c2);
+ case NODE_MIX_DIFF:
+ return svm_mix_diff(t, c1, c2);
+ case NODE_MIX_DARK:
+ return svm_mix_dark(t, c1, c2);
+ case NODE_MIX_LIGHT:
+ return svm_mix_light(t, c1, c2);
+ case NODE_MIX_DODGE:
+ return svm_mix_dodge(t, c1, c2);
+ case NODE_MIX_BURN:
+ return svm_mix_burn(t, c1, c2);
+ case NODE_MIX_HUE:
+ return svm_mix_hue(t, c1, c2);
+ case NODE_MIX_SAT:
+ return svm_mix_sat(t, c1, c2);
+ case NODE_MIX_VAL:
+ return svm_mix_val(t, c1, c2);
+ case NODE_MIX_COLOR:
+ return svm_mix_color(t, c1, c2);
+ case NODE_MIX_SOFT:
+ return svm_mix_soft(t, c1, c2);
+ case NODE_MIX_LINEAR:
+ return svm_mix_linear(t, c1, c2);
+ case NODE_MIX_CLAMP:
+ return svm_mix_clamp(c1);
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
}
ccl_device_inline float3 svm_brightness_contrast(float3 color, float brightness, float contrast)
{
- float a = 1.0f + contrast;
- float b = brightness - contrast*0.5f;
+ float a = 1.0f + contrast;
+ float b = brightness - contrast * 0.5f;
- color.x = max(a*color.x + b, 0.0f);
- color.y = max(a*color.y + b, 0.0f);
- color.z = max(a*color.z + b, 0.0f);
+ color.x = max(a * color.x + b, 0.0f);
+ color.y = max(a * color.y + b, 0.0f);
+ color.z = max(a * color.z + b, 0.0f);
- return color;
+ return color;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h
index 63b1dc6865e..5df6c9fb755 100644
--- a/intern/cycles/kernel/svm/svm_convert.h
+++ b/intern/cycles/kernel/svm/svm_convert.h
@@ -18,54 +18,55 @@ CCL_NAMESPACE_BEGIN
/* Conversion Nodes */
-ccl_device void svm_node_convert(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint from, uint to)
+ccl_device void svm_node_convert(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint from, uint to)
{
- switch(type) {
- case NODE_CONVERT_FI: {
- float f = stack_load_float(stack, from);
- stack_store_int(stack, to, float_to_int(f));
- break;
- }
- case NODE_CONVERT_FV: {
- float f = stack_load_float(stack, from);
- stack_store_float3(stack, to, make_float3(f, f, f));
- break;
- }
- case NODE_CONVERT_CF: {
- float3 f = stack_load_float3(stack, from);
- float g = linear_rgb_to_gray(kg, f);
- stack_store_float(stack, to, g);
- break;
- }
- case NODE_CONVERT_CI: {
- float3 f = stack_load_float3(stack, from);
- int i = (int)linear_rgb_to_gray(kg, f);
- stack_store_int(stack, to, i);
- break;
- }
- case NODE_CONVERT_VF: {
- float3 f = stack_load_float3(stack, from);
- float g = average(f);
- stack_store_float(stack, to, g);
- break;
- }
- case NODE_CONVERT_VI: {
- float3 f = stack_load_float3(stack, from);
- int i = (int)average(f);
- stack_store_int(stack, to, i);
- break;
- }
- case NODE_CONVERT_IF: {
- float f = (float)stack_load_int(stack, from);
- stack_store_float(stack, to, f);
- break;
- }
- case NODE_CONVERT_IV: {
- float f = (float)stack_load_int(stack, from);
- stack_store_float3(stack, to, make_float3(f, f, f));
- break;
- }
- }
+ switch (type) {
+ case NODE_CONVERT_FI: {
+ float f = stack_load_float(stack, from);
+ stack_store_int(stack, to, float_to_int(f));
+ break;
+ }
+ case NODE_CONVERT_FV: {
+ float f = stack_load_float(stack, from);
+ stack_store_float3(stack, to, make_float3(f, f, f));
+ break;
+ }
+ case NODE_CONVERT_CF: {
+ float3 f = stack_load_float3(stack, from);
+ float g = linear_rgb_to_gray(kg, f);
+ stack_store_float(stack, to, g);
+ break;
+ }
+ case NODE_CONVERT_CI: {
+ float3 f = stack_load_float3(stack, from);
+ int i = (int)linear_rgb_to_gray(kg, f);
+ stack_store_int(stack, to, i);
+ break;
+ }
+ case NODE_CONVERT_VF: {
+ float3 f = stack_load_float3(stack, from);
+ float g = average(f);
+ stack_store_float(stack, to, g);
+ break;
+ }
+ case NODE_CONVERT_VI: {
+ float3 f = stack_load_float3(stack, from);
+ int i = (int)average(f);
+ stack_store_int(stack, to, i);
+ break;
+ }
+ case NODE_CONVERT_IF: {
+ float f = (float)stack_load_int(stack, from);
+ stack_store_float(stack, to, f);
+ break;
+ }
+ case NODE_CONVERT_IV: {
+ float f = (float)stack_load_int(stack, from);
+ stack_store_float3(stack, to, make_float3(f, f, f));
+ break;
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h
index a69c9fe81f9..f16664a684c 100644
--- a/intern/cycles/kernel/svm/svm_displace.h
+++ b/intern/cycles/kernel/svm/svm_displace.h
@@ -21,144 +21,149 @@ CCL_NAMESPACE_BEGIN
ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
#ifdef __RAY_DIFFERENTIALS__
- /* get normal input */
- uint normal_offset, scale_offset, invert, use_object_space;
- decode_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space);
+ /* get normal input */
+ uint normal_offset, scale_offset, invert, use_object_space;
+ decode_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space);
- float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N;
+ float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
- float3 dPdx = sd->dP.dx;
- float3 dPdy = sd->dP.dy;
+ float3 dPdx = sd->dP.dx;
+ float3 dPdy = sd->dP.dy;
- if(use_object_space) {
- object_inverse_normal_transform(kg, sd, &normal_in);
- object_inverse_dir_transform(kg, sd, &dPdx);
- object_inverse_dir_transform(kg, sd, &dPdy);
- }
+ if (use_object_space) {
+ object_inverse_normal_transform(kg, sd, &normal_in);
+ object_inverse_dir_transform(kg, sd, &dPdx);
+ object_inverse_dir_transform(kg, sd, &dPdy);
+ }
- /* get surface tangents from normal */
- float3 Rx = cross(dPdy, normal_in);
- float3 Ry = cross(normal_in, dPdx);
+ /* get surface tangents from normal */
+ float3 Rx = cross(dPdy, normal_in);
+ float3 Ry = cross(normal_in, dPdx);
- /* get bump values */
- uint c_offset, x_offset, y_offset, strength_offset;
- decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset);
+ /* get bump values */
+ uint c_offset, x_offset, y_offset, strength_offset;
+ decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset);
- float h_c = stack_load_float(stack, c_offset);
- float h_x = stack_load_float(stack, x_offset);
- float h_y = stack_load_float(stack, y_offset);
+ float h_c = stack_load_float(stack, c_offset);
+ float h_x = stack_load_float(stack, x_offset);
+ float h_y = stack_load_float(stack, y_offset);
- /* compute surface gradient and determinant */
- float det = dot(dPdx, Rx);
- float3 surfgrad = (h_x - h_c)*Rx + (h_y - h_c)*Ry;
+ /* compute surface gradient and determinant */
+ float det = dot(dPdx, Rx);
+ float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry;
- float absdet = fabsf(det);
+ float absdet = fabsf(det);
- float strength = stack_load_float(stack, strength_offset);
- float scale = stack_load_float(stack, scale_offset);
+ float strength = stack_load_float(stack, strength_offset);
+ float scale = stack_load_float(stack, scale_offset);
- if(invert)
- scale *= -1.0f;
+ if (invert)
+ scale *= -1.0f;
- strength = max(strength, 0.0f);
+ strength = max(strength, 0.0f);
- /* compute and output perturbed normal */
- float3 normal_out = safe_normalize(absdet*normal_in - scale*signf(det)*surfgrad);
- if(is_zero(normal_out)) {
- normal_out = normal_in;
- }
- else {
- normal_out = normalize(strength*normal_out + (1.0f - strength)*normal_in);
- }
+ /* compute and output perturbed normal */
+ float3 normal_out = safe_normalize(absdet * normal_in - scale * signf(det) * surfgrad);
+ if (is_zero(normal_out)) {
+ normal_out = normal_in;
+ }
+ else {
+ normal_out = normalize(strength * normal_out + (1.0f - strength) * normal_in);
+ }
- if(use_object_space) {
- object_normal_transform(kg, sd, &normal_out);
- }
+ if (use_object_space) {
+ object_normal_transform(kg, sd, &normal_out);
+ }
- normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out);
+ normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out);
- stack_store_float3(stack, node.w, normal_out);
+ stack_store_float3(stack, node.w, normal_out);
#endif
}
/* Displacement Node */
-ccl_device void svm_node_set_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint fac_offset)
+ccl_device void svm_node_set_displacement(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint fac_offset)
{
- float3 dP = stack_load_float3(stack, fac_offset);
- sd->P += dP;
+ float3 dP = stack_load_float3(stack, fac_offset);
+ sd->P += dP;
}
ccl_device void svm_node_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- uint height_offset, midlevel_offset, scale_offset, normal_offset;
- decode_node_uchar4(node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset);
-
- float height = stack_load_float(stack, height_offset);
- float midlevel = stack_load_float(stack, midlevel_offset);
- float scale = stack_load_float(stack, scale_offset);
- float3 normal = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N;
- uint space = node.w;
-
- float3 dP = normal;
-
- if(space == NODE_NORMAL_MAP_OBJECT) {
- /* Object space. */
- object_inverse_normal_transform(kg, sd, &dP);
- dP *= (height - midlevel) * scale;
- object_dir_transform(kg, sd, &dP);
- }
- else {
- /* World space. */
- dP *= (height - midlevel) * scale;
- }
-
- stack_store_float3(stack, node.z, dP);
+ uint height_offset, midlevel_offset, scale_offset, normal_offset;
+ decode_node_uchar4(node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset);
+
+ float height = stack_load_float(stack, height_offset);
+ float midlevel = stack_load_float(stack, midlevel_offset);
+ float scale = stack_load_float(stack, scale_offset);
+ float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
+ uint space = node.w;
+
+ float3 dP = normal;
+
+ if (space == NODE_NORMAL_MAP_OBJECT) {
+ /* Object space. */
+ object_inverse_normal_transform(kg, sd, &dP);
+ dP *= (height - midlevel) * scale;
+ object_dir_transform(kg, sd, &dP);
+ }
+ else {
+ /* World space. */
+ dP *= (height - midlevel) * scale;
+ }
+
+ stack_store_float3(stack, node.z, dP);
}
-ccl_device void svm_node_vector_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_vector_displacement(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint4 data_node = read_node(kg, offset);
- uint space = data_node.x;
-
- uint vector_offset, midlevel_offset,scale_offset, displacement_offset;
- decode_node_uchar4(node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset);
-
- float3 vector = stack_load_float3(stack, vector_offset);
- float midlevel = stack_load_float(stack, midlevel_offset);
- float scale = stack_load_float(stack, scale_offset);
- float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale;
-
- if(space == NODE_NORMAL_MAP_TANGENT) {
- /* Tangent space. */
- float3 normal = sd->N;
- object_inverse_normal_transform(kg, sd, &normal);
-
- const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
- float3 tangent;
- if(attr.offset != ATTR_STD_NOT_FOUND) {
- tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
- }
- else {
- tangent = normalize(sd->dPdu);
- }
-
- float3 bitangent = normalize(cross(normal, tangent));
- const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
- if(attr_sign.offset != ATTR_STD_NOT_FOUND) {
- float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
- bitangent *= sign;
- }
-
- dP = tangent*dP.x + normal*dP.y + bitangent*dP.z;
- }
-
- if(space != NODE_NORMAL_MAP_WORLD) {
- /* Tangent or object space. */
- object_dir_transform(kg, sd, &dP);
- }
-
- stack_store_float3(stack, displacement_offset, dP);
+ uint4 data_node = read_node(kg, offset);
+ uint space = data_node.x;
+
+ uint vector_offset, midlevel_offset, scale_offset, displacement_offset;
+ decode_node_uchar4(
+ node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset);
+
+ float3 vector = stack_load_float3(stack, vector_offset);
+ float midlevel = stack_load_float(stack, midlevel_offset);
+ float scale = stack_load_float(stack, scale_offset);
+ float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale;
+
+ if (space == NODE_NORMAL_MAP_TANGENT) {
+ /* Tangent space. */
+ float3 normal = sd->N;
+ object_inverse_normal_transform(kg, sd, &normal);
+
+ const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
+ float3 tangent;
+ if (attr.offset != ATTR_STD_NOT_FOUND) {
+ tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
+ }
+ else {
+ tangent = normalize(sd->dPdu);
+ }
+
+ float3 bitangent = normalize(cross(normal, tangent));
+ const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
+ if (attr_sign.offset != ATTR_STD_NOT_FOUND) {
+ float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
+ bitangent *= sign;
+ }
+
+ dP = tangent * dP.x + normal * dP.y + bitangent * dP.z;
+ }
+
+ if (space != NODE_NORMAL_MAP_WORLD) {
+ /* Tangent or object space. */
+ object_dir_transform(kg, sd, &dP);
+ }
+
+ stack_store_float3(stack, displacement_offset, dP);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h
index 99dda5fb170..03119991597 100644
--- a/intern/cycles/kernel/svm/svm_fresnel.h
+++ b/intern/cycles/kernel/svm/svm_fresnel.h
@@ -18,56 +18,60 @@ CCL_NAMESPACE_BEGIN
/* Fresnel Node */
-ccl_device void svm_node_fresnel(ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint node)
+ccl_device void svm_node_fresnel(
+ ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint node)
{
- uint normal_offset, out_offset;
- decode_node_uchar4(node, &normal_offset, &out_offset, NULL, NULL);
- float eta = (stack_valid(ior_offset))? stack_load_float(stack, ior_offset): __uint_as_float(ior_value);
- float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N;
+ uint normal_offset, out_offset;
+ decode_node_uchar4(node, &normal_offset, &out_offset, NULL, NULL);
+ float eta = (stack_valid(ior_offset)) ? stack_load_float(stack, ior_offset) :
+ __uint_as_float(ior_value);
+ float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
- eta = fmaxf(eta, 1e-5f);
- eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
+ eta = fmaxf(eta, 1e-5f);
+ eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
- float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
+ float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
- stack_store_float(stack, out_offset, f);
+ stack_store_float(stack, out_offset, f);
}
/* Layer Weight Node */
ccl_device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node)
{
- uint blend_offset = node.y;
- uint blend_value = node.z;
+ uint blend_offset = node.y;
+ uint blend_value = node.z;
- uint type, normal_offset, out_offset;
- decode_node_uchar4(node.w, &type, &normal_offset, &out_offset, NULL);
+ uint type, normal_offset, out_offset;
+ decode_node_uchar4(node.w, &type, &normal_offset, &out_offset, NULL);
- float blend = (stack_valid(blend_offset))? stack_load_float(stack, blend_offset): __uint_as_float(blend_value);
- float3 normal_in = (stack_valid(normal_offset))? stack_load_float3(stack, normal_offset): sd->N;
+ float blend = (stack_valid(blend_offset)) ? stack_load_float(stack, blend_offset) :
+ __uint_as_float(blend_value);
+ float3 normal_in = (stack_valid(normal_offset)) ? stack_load_float3(stack, normal_offset) :
+ sd->N;
- float f;
+ float f;
- if(type == NODE_LAYER_WEIGHT_FRESNEL) {
- float eta = fmaxf(1.0f - blend, 1e-5f);
- eta = (sd->flag & SD_BACKFACING)? eta: 1.0f/eta;
+ if (type == NODE_LAYER_WEIGHT_FRESNEL) {
+ float eta = fmaxf(1.0f - blend, 1e-5f);
+ eta = (sd->flag & SD_BACKFACING) ? eta : 1.0f / eta;
- f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
- }
- else {
- f = fabsf(dot(sd->I, normal_in));
+ f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
+ }
+ else {
+ f = fabsf(dot(sd->I, normal_in));
- if(blend != 0.5f) {
- blend = clamp(blend, 0.0f, 1.0f-1e-5f);
- blend = (blend < 0.5f)? 2.0f*blend: 0.5f/(1.0f - blend);
+ if (blend != 0.5f) {
+ blend = clamp(blend, 0.0f, 1.0f - 1e-5f);
+ blend = (blend < 0.5f) ? 2.0f * blend : 0.5f / (1.0f - blend);
- f = powf(f, blend);
- }
+ f = powf(f, blend);
+ }
- f = 1.0f - f;
- }
+ f = 1.0f - f;
+ }
- stack_store_float(stack, out_offset, f);
+ stack_store_float(stack, out_offset, f);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_gamma.h b/intern/cycles/kernel/svm/svm_gamma.h
index 171945a60bc..65eb08eb0eb 100644
--- a/intern/cycles/kernel/svm/svm_gamma.h
+++ b/intern/cycles/kernel/svm/svm_gamma.h
@@ -16,15 +16,16 @@
CCL_NAMESPACE_BEGIN
-ccl_device void svm_node_gamma(ShaderData *sd, float *stack, uint in_gamma, uint in_color, uint out_color)
+ccl_device void svm_node_gamma(
+ ShaderData *sd, float *stack, uint in_gamma, uint in_color, uint out_color)
{
- float3 color = stack_load_float3(stack, in_color);
- float gamma = stack_load_float(stack, in_gamma);
+ float3 color = stack_load_float3(stack, in_color);
+ float gamma = stack_load_float(stack, in_gamma);
- color = svm_math_gamma_color(color, gamma);
+ color = svm_math_gamma_color(color, gamma);
- if(stack_valid(out_color))
- stack_store_float3(stack, out_color, color);
+ if (stack_valid(out_color))
+ stack_store_float3(stack, out_color, color);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index 05443772505..a9104643299 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -18,192 +18,217 @@ CCL_NAMESPACE_BEGIN
/* Geometry Node */
-ccl_device_inline void svm_node_geometry(KernelGlobals *kg,
- ShaderData *sd,
- float *stack,
- uint type,
- uint out_offset)
+ccl_device_inline void svm_node_geometry(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
- float3 data;
-
- switch(type) {
- case NODE_GEOM_P: data = sd->P; break;
- case NODE_GEOM_N: data = sd->N; break;
+ float3 data;
+
+ switch (type) {
+ case NODE_GEOM_P:
+ data = sd->P;
+ break;
+ case NODE_GEOM_N:
+ data = sd->N;
+ break;
#ifdef __DPDU__
- case NODE_GEOM_T: data = primitive_tangent(kg, sd); break;
+ case NODE_GEOM_T:
+ data = primitive_tangent(kg, sd);
+ break;
#endif
- case NODE_GEOM_I: data = sd->I; break;
- case NODE_GEOM_Ng: data = sd->Ng; break;
+ case NODE_GEOM_I:
+ data = sd->I;
+ break;
+ case NODE_GEOM_Ng:
+ data = sd->Ng;
+ break;
#ifdef __UV__
- case NODE_GEOM_uv: data = make_float3(sd->u, sd->v, 0.0f); break;
+ case NODE_GEOM_uv:
+ data = make_float3(sd->u, sd->v, 0.0f);
+ break;
#endif
- default: data = make_float3(0.0f, 0.0f, 0.0f);
- }
+ default:
+ data = make_float3(0.0f, 0.0f, 0.0f);
+ }
- stack_store_float3(stack, out_offset, data);
+ stack_store_float3(stack, out_offset, data);
}
-ccl_device void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
+ccl_device void svm_node_geometry_bump_dx(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
#ifdef __RAY_DIFFERENTIALS__
- float3 data;
-
- switch(type) {
- case NODE_GEOM_P: data = sd->P + sd->dP.dx; break;
- case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f); break;
- default: svm_node_geometry(kg, sd, stack, type, out_offset); return;
- }
-
- stack_store_float3(stack, out_offset, data);
+ float3 data;
+
+ switch (type) {
+ case NODE_GEOM_P:
+ data = sd->P + sd->dP.dx;
+ break;
+ case NODE_GEOM_uv:
+ data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f);
+ break;
+ default:
+ svm_node_geometry(kg, sd, stack, type, out_offset);
+ return;
+ }
+
+ stack_store_float3(stack, out_offset, data);
#else
- svm_node_geometry(kg, sd, stack, type, out_offset);
+ svm_node_geometry(kg, sd, stack, type, out_offset);
#endif
}
-ccl_device void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
+ccl_device void svm_node_geometry_bump_dy(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
#ifdef __RAY_DIFFERENTIALS__
- float3 data;
-
- switch(type) {
- case NODE_GEOM_P: data = sd->P + sd->dP.dy; break;
- case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f); break;
- default: svm_node_geometry(kg, sd, stack, type, out_offset); return;
- }
-
- stack_store_float3(stack, out_offset, data);
+ float3 data;
+
+ switch (type) {
+ case NODE_GEOM_P:
+ data = sd->P + sd->dP.dy;
+ break;
+ case NODE_GEOM_uv:
+ data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f);
+ break;
+ default:
+ svm_node_geometry(kg, sd, stack, type, out_offset);
+ return;
+ }
+
+ stack_store_float3(stack, out_offset, data);
#else
- svm_node_geometry(kg, sd, stack, type, out_offset);
+ svm_node_geometry(kg, sd, stack, type, out_offset);
#endif
}
/* Object Info */
-ccl_device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
+ccl_device void svm_node_object_info(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
- float data;
-
- switch(type) {
- case NODE_INFO_OB_LOCATION: {
- stack_store_float3(stack, out_offset, object_location(kg, sd));
- return;
- }
- case NODE_INFO_OB_INDEX: data = object_pass_id(kg, sd->object); break;
- case NODE_INFO_MAT_INDEX: data = shader_pass_id(kg, sd); break;
- case NODE_INFO_OB_RANDOM: {
- if(sd->lamp != LAMP_NONE) {
- data = lamp_random_number(kg, sd->lamp);
- }
- else {
- data = object_random_number(kg, sd->object);
- }
- break;
- }
- default: data = 0.0f; break;
- }
-
- stack_store_float(stack, out_offset, data);
+ float data;
+
+ switch (type) {
+ case NODE_INFO_OB_LOCATION: {
+ stack_store_float3(stack, out_offset, object_location(kg, sd));
+ return;
+ }
+ case NODE_INFO_OB_INDEX:
+ data = object_pass_id(kg, sd->object);
+ break;
+ case NODE_INFO_MAT_INDEX:
+ data = shader_pass_id(kg, sd);
+ break;
+ case NODE_INFO_OB_RANDOM: {
+ if (sd->lamp != LAMP_NONE) {
+ data = lamp_random_number(kg, sd->lamp);
+ }
+ else {
+ data = object_random_number(kg, sd->object);
+ }
+ break;
+ }
+ default:
+ data = 0.0f;
+ break;
+ }
+
+ stack_store_float(stack, out_offset, data);
}
/* Particle Info */
-ccl_device void svm_node_particle_info(KernelGlobals *kg,
- ShaderData *sd,
- float *stack,
- uint type,
- uint out_offset)
+ccl_device void svm_node_particle_info(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
- switch(type) {
- case NODE_INFO_PAR_INDEX: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float(stack, out_offset, particle_index(kg, particle_id));
- break;
- }
- case NODE_INFO_PAR_RANDOM: {
- int particle_id = object_particle_id(kg, sd->object);
- float random = hash_int_01(particle_index(kg, particle_id));
- stack_store_float(stack, out_offset, random);
- break;
- }
- case NODE_INFO_PAR_AGE: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float(stack, out_offset, particle_age(kg, particle_id));
- break;
- }
- case NODE_INFO_PAR_LIFETIME: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id));
- break;
- }
- case NODE_INFO_PAR_LOCATION: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float3(stack, out_offset, particle_location(kg, particle_id));
- break;
- }
-#if 0 /* XXX float4 currently not supported in SVM stack */
- case NODE_INFO_PAR_ROTATION: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id));
- break;
- }
+ switch (type) {
+ case NODE_INFO_PAR_INDEX: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float(stack, out_offset, particle_index(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_RANDOM: {
+ int particle_id = object_particle_id(kg, sd->object);
+ float random = hash_int_01(particle_index(kg, particle_id));
+ stack_store_float(stack, out_offset, random);
+ break;
+ }
+ case NODE_INFO_PAR_AGE: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float(stack, out_offset, particle_age(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_LIFETIME: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_LOCATION: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_location(kg, particle_id));
+ break;
+ }
+#if 0 /* XXX float4 currently not supported in SVM stack */
+ case NODE_INFO_PAR_ROTATION: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id));
+ break;
+ }
#endif
- case NODE_INFO_PAR_SIZE: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float(stack, out_offset, particle_size(kg, particle_id));
- break;
- }
- case NODE_INFO_PAR_VELOCITY: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id));
- break;
- }
- case NODE_INFO_PAR_ANGULAR_VELOCITY: {
- int particle_id = object_particle_id(kg, sd->object);
- stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id));
- break;
- }
- }
+ case NODE_INFO_PAR_SIZE: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float(stack, out_offset, particle_size(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_VELOCITY: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_ANGULAR_VELOCITY: {
+ int particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id));
+ break;
+ }
+ }
}
#ifdef __HAIR__
/* Hair Info */
-ccl_device void svm_node_hair_info(KernelGlobals *kg,
- ShaderData *sd,
- float *stack,
- uint type,
- uint out_offset)
+ccl_device void svm_node_hair_info(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
- float data;
- float3 data3;
-
- switch(type) {
- case NODE_INFO_CURVE_IS_STRAND: {
- data = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
- stack_store_float(stack, out_offset, data);
- break;
- }
- case NODE_INFO_CURVE_INTERCEPT:
- break; /* handled as attribute */
- case NODE_INFO_CURVE_RANDOM:
- break; /* handled as attribute */
- case NODE_INFO_CURVE_THICKNESS: {
- data = curve_thickness(kg, sd);
- stack_store_float(stack, out_offset, data);
- break;
- }
- /*case NODE_INFO_CURVE_FADE: {
- data = sd->curve_transparency;
- stack_store_float(stack, out_offset, data);
- break;
- }*/
- case NODE_INFO_CURVE_TANGENT_NORMAL: {
- data3 = curve_tangent_normal(kg, sd);
- stack_store_float3(stack, out_offset, data3);
- break;
- }
- }
+ float data;
+ float3 data3;
+
+ switch (type) {
+ case NODE_INFO_CURVE_IS_STRAND: {
+ data = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
+ stack_store_float(stack, out_offset, data);
+ break;
+ }
+ case NODE_INFO_CURVE_INTERCEPT:
+ break; /* handled as attribute */
+ case NODE_INFO_CURVE_RANDOM:
+ break; /* handled as attribute */
+ case NODE_INFO_CURVE_THICKNESS: {
+ data = curve_thickness(kg, sd);
+ stack_store_float(stack, out_offset, data);
+ break;
+ }
+ /*case NODE_INFO_CURVE_FADE: {
+ data = sd->curve_transparency;
+ stack_store_float(stack, out_offset, data);
+ break;
+ }*/
+ case NODE_INFO_CURVE_TANGENT_NORMAL: {
+ data3 = curve_tangent_normal(kg, sd);
+ stack_store_float3(stack, out_offset, data3);
+ break;
+ }
+ }
}
#endif
diff --git a/intern/cycles/kernel/svm/svm_gradient.h b/intern/cycles/kernel/svm/svm_gradient.h
index 177e0506dee..c315564fbc2 100644
--- a/intern/cycles/kernel/svm/svm_gradient.h
+++ b/intern/cycles/kernel/svm/svm_gradient.h
@@ -20,61 +20,61 @@ CCL_NAMESPACE_BEGIN
ccl_device float svm_gradient(float3 p, NodeGradientType type)
{
- float x, y, z;
+ float x, y, z;
- x = p.x;
- y = p.y;
- z = p.z;
+ x = p.x;
+ y = p.y;
+ z = p.z;
- if(type == NODE_BLEND_LINEAR) {
- return x;
- }
- else if(type == NODE_BLEND_QUADRATIC) {
- float r = fmaxf(x, 0.0f);
- return r*r;
- }
- else if(type == NODE_BLEND_EASING) {
- float r = fminf(fmaxf(x, 0.0f), 1.0f);
- float t = r*r;
+ if (type == NODE_BLEND_LINEAR) {
+ return x;
+ }
+ else if (type == NODE_BLEND_QUADRATIC) {
+ float r = fmaxf(x, 0.0f);
+ return r * r;
+ }
+ else if (type == NODE_BLEND_EASING) {
+ float r = fminf(fmaxf(x, 0.0f), 1.0f);
+ float t = r * r;
- return (3.0f*t - 2.0f*t*r);
- }
- else if(type == NODE_BLEND_DIAGONAL) {
- return (x + y) * 0.5f;
- }
- else if(type == NODE_BLEND_RADIAL) {
- return atan2f(y, x) / M_2PI_F + 0.5f;
- }
- else {
- /* Bias a little bit for the case where p is a unit length vector,
- * to get exactly zero instead of a small random value depending
- * on float precision. */
- float r = fmaxf(0.999999f - sqrtf(x*x + y*y + z*z), 0.0f);
+ return (3.0f * t - 2.0f * t * r);
+ }
+ else if (type == NODE_BLEND_DIAGONAL) {
+ return (x + y) * 0.5f;
+ }
+ else if (type == NODE_BLEND_RADIAL) {
+ return atan2f(y, x) / M_2PI_F + 0.5f;
+ }
+ else {
+ /* Bias a little bit for the case where p is a unit length vector,
+ * to get exactly zero instead of a small random value depending
+ * on float precision. */
+ float r = fmaxf(0.999999f - sqrtf(x * x + y * y + z * z), 0.0f);
- if(type == NODE_BLEND_QUADRATIC_SPHERE)
- return r*r;
- else if(type == NODE_BLEND_SPHERICAL)
- return r;
- }
+ if (type == NODE_BLEND_QUADRATIC_SPHERE)
+ return r * r;
+ else if (type == NODE_BLEND_SPHERICAL)
+ return r;
+ }
- return 0.0f;
+ return 0.0f;
}
ccl_device void svm_node_tex_gradient(ShaderData *sd, float *stack, uint4 node)
{
- uint type, co_offset, color_offset, fac_offset;
+ uint type, co_offset, color_offset, fac_offset;
- decode_node_uchar4(node.y, &type, &co_offset, &fac_offset, &color_offset);
+ decode_node_uchar4(node.y, &type, &co_offset, &fac_offset, &color_offset);
- float3 co = stack_load_float3(stack, co_offset);
+ float3 co = stack_load_float3(stack, co_offset);
- float f = svm_gradient(co, (NodeGradientType)type);
- f = saturate(f);
+ float f = svm_gradient(co, (NodeGradientType)type);
+ f = saturate(f);
- if(stack_valid(fac_offset))
- stack_store_float(stack, fac_offset, f);
- if(stack_valid(color_offset))
- stack_store_float3(stack, color_offset, make_float3(f, f, f));
+ if (stack_valid(fac_offset))
+ stack_store_float(stack, fac_offset, f);
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, make_float3(f, f, f));
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h
index 6f3efa639e2..72379fba870 100644
--- a/intern/cycles/kernel/svm/svm_hsv.h
+++ b/intern/cycles/kernel/svm/svm_hsv.h
@@ -19,43 +19,44 @@
CCL_NAMESPACE_BEGIN
-ccl_device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_hsv(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint in_color_offset, fac_offset, out_color_offset;
- uint hue_offset, sat_offset, val_offset;
- decode_node_uchar4(node.y, &in_color_offset, &fac_offset, &out_color_offset, NULL);
- decode_node_uchar4(node.z, &hue_offset, &sat_offset, &val_offset, NULL);
+ uint in_color_offset, fac_offset, out_color_offset;
+ uint hue_offset, sat_offset, val_offset;
+ decode_node_uchar4(node.y, &in_color_offset, &fac_offset, &out_color_offset, NULL);
+ decode_node_uchar4(node.z, &hue_offset, &sat_offset, &val_offset, NULL);
- float fac = stack_load_float(stack, fac_offset);
- float3 in_color = stack_load_float3(stack, in_color_offset);
- float3 color = in_color;
+ float fac = stack_load_float(stack, fac_offset);
+ float3 in_color = stack_load_float3(stack, in_color_offset);
+ float3 color = in_color;
- float hue = stack_load_float(stack, hue_offset);
- float sat = stack_load_float(stack, sat_offset);
- float val = stack_load_float(stack, val_offset);
+ float hue = stack_load_float(stack, hue_offset);
+ float sat = stack_load_float(stack, sat_offset);
+ float val = stack_load_float(stack, val_offset);
- color = rgb_to_hsv(color);
+ color = rgb_to_hsv(color);
- /* remember: fmod doesn't work for negative numbers here */
- color.x = fmodf(color.x + hue + 0.5f, 1.0f);
- color.y = saturate(color.y * sat);
- color.z *= val;
+ /* remember: fmod doesn't work for negative numbers here */
+ color.x = fmodf(color.x + hue + 0.5f, 1.0f);
+ color.y = saturate(color.y * sat);
+ color.z *= val;
- color = hsv_to_rgb(color);
+ color = hsv_to_rgb(color);
- color.x = fac*color.x + (1.0f - fac)*in_color.x;
- color.y = fac*color.y + (1.0f - fac)*in_color.y;
- color.z = fac*color.z + (1.0f - fac)*in_color.z;
+ color.x = fac * color.x + (1.0f - fac) * in_color.x;
+ color.y = fac * color.y + (1.0f - fac) * in_color.y;
+ color.z = fac * color.z + (1.0f - fac) * in_color.z;
- /* Clamp color to prevent negative values caused by oversaturation. */
- color.x = max(color.x, 0.0f);
- color.y = max(color.y, 0.0f);
- color.z = max(color.z, 0.0f);
+ /* Clamp color to prevent negative values caused by oversaturation. */
+ color.x = max(color.x, 0.0f);
+ color.y = max(color.y, 0.0f);
+ color.z = max(color.z, 0.0f);
- if(stack_valid(out_color_offset))
- stack_store_float3(stack, out_color_offset, color);
+ if (stack_valid(out_color_offset))
+ stack_store_float3(stack, out_color_offset, color);
}
CCL_NAMESPACE_END
-#endif /* __SVM_HSV_H__ */
+#endif /* __SVM_HSV_H__ */
diff --git a/intern/cycles/kernel/svm/svm_ies.h b/intern/cycles/kernel/svm/svm_ies.h
index 6130c3348b0..9434c0c5505 100644
--- a/intern/cycles/kernel/svm/svm_ies.h
+++ b/intern/cycles/kernel/svm/svm_ies.h
@@ -18,93 +18,102 @@ CCL_NAMESPACE_BEGIN
/* IES Light */
-ccl_device_inline float interpolate_ies_vertical(KernelGlobals *kg, int ofs, int v, int v_num, float v_frac, int h)
+ccl_device_inline float interpolate_ies_vertical(
+ KernelGlobals *kg, int ofs, int v, int v_num, float v_frac, int h)
{
- /* Since lookups are performed in spherical coordinates, clamping the coordinates at the low end of v
- * (corresponding to the north pole) would result in artifacts.
- * The proper way of dealing with this would be to lookup the corresponding value on the other side of the pole,
- * but since the horizontal coordinates might be nonuniform, this would require yet another interpolation.
- * Therefore, the assumtion is made that the light is going to be symmetrical, which means that we can just take
- * the corresponding value at the current horizontal coordinate. */
-
-#define IES_LOOKUP(v) kernel_tex_fetch(__ies, ofs+h*v_num+(v))
- /* If v is zero, assume symmetry and read at v=1 instead of v=-1. */
- float a = IES_LOOKUP((v == 0)? 1 : v-1);
- float b = IES_LOOKUP(v);
- float c = IES_LOOKUP(v+1);
- float d = IES_LOOKUP(min(v+2, v_num-1));
+ /* Since lookups are performed in spherical coordinates, clamping the coordinates at the low end of v
+ * (corresponding to the north pole) would result in artifacts.
+ * The proper way of dealing with this would be to lookup the corresponding value on the other side of the pole,
+ * but since the horizontal coordinates might be nonuniform, this would require yet another interpolation.
+ * Therefore, the assumtion is made that the light is going to be symmetrical, which means that we can just take
+ * the corresponding value at the current horizontal coordinate. */
+
+#define IES_LOOKUP(v) kernel_tex_fetch(__ies, ofs + h * v_num + (v))
+ /* If v is zero, assume symmetry and read at v=1 instead of v=-1. */
+ float a = IES_LOOKUP((v == 0) ? 1 : v - 1);
+ float b = IES_LOOKUP(v);
+ float c = IES_LOOKUP(v + 1);
+ float d = IES_LOOKUP(min(v + 2, v_num - 1));
#undef IES_LOOKUP
- return cubic_interp(a, b, c, d, v_frac);
+ return cubic_interp(a, b, c, d, v_frac);
}
-ccl_device_inline float kernel_ies_interp(KernelGlobals *kg, int slot, float h_angle, float v_angle)
+ccl_device_inline float kernel_ies_interp(KernelGlobals *kg,
+ int slot,
+ float h_angle,
+ float v_angle)
{
- /* Find offset of the IES data in the table. */
- int ofs = __float_as_int(kernel_tex_fetch(__ies, slot));
- if(ofs == -1) {
- return 100.0f;
- }
-
- int h_num = __float_as_int(kernel_tex_fetch(__ies, ofs++));
- int v_num = __float_as_int(kernel_tex_fetch(__ies, ofs++));
-
-#define IES_LOOKUP_ANGLE_H(h) kernel_tex_fetch(__ies, ofs+(h))
-#define IES_LOOKUP_ANGLE_V(v) kernel_tex_fetch(__ies, ofs+h_num+(v))
-
- /* Check whether the angle is within the bounds of the IES texture. */
- if(v_angle >= IES_LOOKUP_ANGLE_V(v_num-1)) {
- return 0.0f;
- }
- kernel_assert(v_angle >= IES_LOOKUP_ANGLE_V(0));
- kernel_assert(h_angle >= IES_LOOKUP_ANGLE_H(0));
- kernel_assert(h_angle <= IES_LOOKUP_ANGLE_H(h_num-1));
-
- /* Lookup the angles to find the table position. */
- int h_i, v_i;
- /* TODO(lukas): Consider using bisection. Probably not worth it for the vast majority of IES files. */
- for(h_i = 0; IES_LOOKUP_ANGLE_H(h_i+1) < h_angle; h_i++);
- for(v_i = 0; IES_LOOKUP_ANGLE_V(v_i+1) < v_angle; v_i++);
-
- float h_frac = inverse_lerp(IES_LOOKUP_ANGLE_H(h_i), IES_LOOKUP_ANGLE_H(h_i+1), h_angle);
- float v_frac = inverse_lerp(IES_LOOKUP_ANGLE_V(v_i), IES_LOOKUP_ANGLE_V(v_i+1), v_angle);
+ /* Find offset of the IES data in the table. */
+ int ofs = __float_as_int(kernel_tex_fetch(__ies, slot));
+ if (ofs == -1) {
+ return 100.0f;
+ }
+
+ int h_num = __float_as_int(kernel_tex_fetch(__ies, ofs++));
+ int v_num = __float_as_int(kernel_tex_fetch(__ies, ofs++));
+
+#define IES_LOOKUP_ANGLE_H(h) kernel_tex_fetch(__ies, ofs + (h))
+#define IES_LOOKUP_ANGLE_V(v) kernel_tex_fetch(__ies, ofs + h_num + (v))
+
+ /* Check whether the angle is within the bounds of the IES texture. */
+ if (v_angle >= IES_LOOKUP_ANGLE_V(v_num - 1)) {
+ return 0.0f;
+ }
+ kernel_assert(v_angle >= IES_LOOKUP_ANGLE_V(0));
+ kernel_assert(h_angle >= IES_LOOKUP_ANGLE_H(0));
+ kernel_assert(h_angle <= IES_LOOKUP_ANGLE_H(h_num - 1));
+
+ /* Lookup the angles to find the table position. */
+ int h_i, v_i;
+ /* TODO(lukas): Consider using bisection. Probably not worth it for the vast majority of IES files. */
+ for (h_i = 0; IES_LOOKUP_ANGLE_H(h_i + 1) < h_angle; h_i++)
+ ;
+ for (v_i = 0; IES_LOOKUP_ANGLE_V(v_i + 1) < v_angle; v_i++)
+ ;
+
+ float h_frac = inverse_lerp(IES_LOOKUP_ANGLE_H(h_i), IES_LOOKUP_ANGLE_H(h_i + 1), h_angle);
+ float v_frac = inverse_lerp(IES_LOOKUP_ANGLE_V(v_i), IES_LOOKUP_ANGLE_V(v_i + 1), v_angle);
#undef IES_LOOKUP_ANGLE_H
#undef IES_LOOKUP_ANGLE_V
- /* Skip forward to the actual intensity data. */
- ofs += h_num+v_num;
-
- /* Perform cubic interpolation along the horizontal coordinate to get the intensity value.
- * If h_i is zero, just wrap around since the horizontal angles always go over the full circle.
- * However, the last entry (360°) equals the first one, so we need to wrap around to the one before that. */
- float a = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, (h_i == 0)? h_num-2 : h_i-1);
- float b = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i);
- float c = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i+1);
- /* Same logic here, wrap around to the second element if necessary. */
- float d = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, (h_i+2 == h_num)? 1 : h_i+2);
-
- /* Cubic interpolation can result in negative values, so get rid of them. */
- return max(cubic_interp(a, b, c, d, h_frac), 0.0f);
+ /* Skip forward to the actual intensity data. */
+ ofs += h_num + v_num;
+
+ /* Perform cubic interpolation along the horizontal coordinate to get the intensity value.
+ * If h_i is zero, just wrap around since the horizontal angles always go over the full circle.
+ * However, the last entry (360°) equals the first one, so we need to wrap around to the one before that. */
+ float a = interpolate_ies_vertical(
+ kg, ofs, v_i, v_num, v_frac, (h_i == 0) ? h_num - 2 : h_i - 1);
+ float b = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i);
+ float c = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i + 1);
+ /* Same logic here, wrap around to the second element if necessary. */
+ float d = interpolate_ies_vertical(
+ kg, ofs, v_i, v_num, v_frac, (h_i + 2 == h_num) ? 1 : h_i + 2);
+
+ /* Cubic interpolation can result in negative values, so get rid of them. */
+ return max(cubic_interp(a, b, c, d, h_frac), 0.0f);
}
-ccl_device void svm_node_ies(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_ies(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint vector_offset, strength_offset, fac_offset, dummy, slot = node.z;
- decode_node_uchar4(node.y, &strength_offset, &vector_offset, &fac_offset, &dummy);
+ uint vector_offset, strength_offset, fac_offset, dummy, slot = node.z;
+ decode_node_uchar4(node.y, &strength_offset, &vector_offset, &fac_offset, &dummy);
- float3 vector = stack_load_float3(stack, vector_offset);
- float strength = stack_load_float_default(stack, strength_offset, node.w);
+ float3 vector = stack_load_float3(stack, vector_offset);
+ float strength = stack_load_float_default(stack, strength_offset, node.w);
- vector = normalize(vector);
- float v_angle = safe_acosf(-vector.z);
- float h_angle = atan2f(vector.x, vector.y) + M_PI_F;
+ vector = normalize(vector);
+ float v_angle = safe_acosf(-vector.z);
+ float h_angle = atan2f(vector.x, vector.y) + M_PI_F;
- float fac = strength * kernel_ies_interp(kg, slot, h_angle, v_angle);
+ float fac = strength * kernel_ies_interp(kg, slot, h_angle, v_angle);
- if(stack_valid(fac_offset)) {
- stack_store_float(stack, fac_offset, fac);
- }
+ if (stack_valid(fac_offset)) {
+ stack_store_float(stack, fac_offset, fac);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 81ee79c984e..ee4b8b6e50c 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -16,190 +16,192 @@
CCL_NAMESPACE_BEGIN
-ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha)
+ccl_device float4
+svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha)
{
- float4 r = kernel_tex_image_interp(kg, id, x, y);
- const float alpha = r.w;
-
- if(use_alpha && alpha != 1.0f && alpha != 0.0f) {
- r /= alpha;
- const int texture_type = kernel_tex_type(id);
- if(texture_type == IMAGE_DATA_TYPE_BYTE4 ||
- texture_type == IMAGE_DATA_TYPE_BYTE)
- {
- r = min(r, make_float4(1.0f, 1.0f, 1.0f, 1.0f));
- }
- r.w = alpha;
- }
-
- if(srgb) {
- /* TODO(lukas): Implement proper conversion for image textures. */
- r = color_srgb_to_linear_v4(r);
- }
-
- return r;
+ float4 r = kernel_tex_image_interp(kg, id, x, y);
+ const float alpha = r.w;
+
+ if (use_alpha && alpha != 1.0f && alpha != 0.0f) {
+ r /= alpha;
+ const int texture_type = kernel_tex_type(id);
+ if (texture_type == IMAGE_DATA_TYPE_BYTE4 || texture_type == IMAGE_DATA_TYPE_BYTE) {
+ r = min(r, make_float4(1.0f, 1.0f, 1.0f, 1.0f));
+ }
+ r.w = alpha;
+ }
+
+ if (srgb) {
+ /* TODO(lukas): Implement proper conversion for image textures. */
+ r = color_srgb_to_linear_v4(r);
+ }
+
+ return r;
}
/* Remap coordnate from 0..1 box to -1..-1 */
ccl_device_inline float3 texco_remap_square(float3 co)
{
- return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
+ return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
}
ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- uint id = node.y;
- uint co_offset, out_offset, alpha_offset, srgb;
-
- decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
-
- float3 co = stack_load_float3(stack, co_offset);
- float2 tex_co;
- uint use_alpha = stack_valid(alpha_offset);
- if(node.w == NODE_IMAGE_PROJ_SPHERE) {
- co = texco_remap_square(co);
- tex_co = map_to_sphere(co);
- }
- else if(node.w == NODE_IMAGE_PROJ_TUBE) {
- co = texco_remap_square(co);
- tex_co = map_to_tube(co);
- }
- else {
- tex_co = make_float2(co.x, co.y);
- }
- float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha);
-
- if(stack_valid(out_offset))
- stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
- if(stack_valid(alpha_offset))
- stack_store_float(stack, alpha_offset, f.w);
+ uint id = node.y;
+ uint co_offset, out_offset, alpha_offset, srgb;
+
+ decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
+
+ float3 co = stack_load_float3(stack, co_offset);
+ float2 tex_co;
+ uint use_alpha = stack_valid(alpha_offset);
+ if (node.w == NODE_IMAGE_PROJ_SPHERE) {
+ co = texco_remap_square(co);
+ tex_co = map_to_sphere(co);
+ }
+ else if (node.w == NODE_IMAGE_PROJ_TUBE) {
+ co = texco_remap_square(co);
+ tex_co = map_to_tube(co);
+ }
+ else {
+ tex_co = make_float2(co.x, co.y);
+ }
+ float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha);
+
+ if (stack_valid(out_offset))
+ stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
+ if (stack_valid(alpha_offset))
+ stack_store_float(stack, alpha_offset, f.w);
}
ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- /* get object space normal */
- float3 N = sd->N;
-
- N = sd->N;
- object_inverse_normal_transform(kg, sd, &N);
-
- /* project from direction vector to barycentric coordinates in triangles */
- float3 signed_N = N;
-
- N.x = fabsf(N.x);
- N.y = fabsf(N.y);
- N.z = fabsf(N.z);
-
- N /= (N.x + N.y + N.z);
-
- /* basic idea is to think of this as a triangle, each corner representing
- * one of the 3 faces of the cube. in the corners we have single textures,
- * in between we blend between two textures, and in the middle we a blend
- * between three textures.
- *
- * the Nxyz values are the barycentric coordinates in an equilateral
- * triangle, which in case of blending, in the middle has a smaller
- * equilateral triangle where 3 textures blend. this divides things into
- * 7 zones, with an if() test for each zone */
-
- float3 weight = make_float3(0.0f, 0.0f, 0.0f);
- float blend = __int_as_float(node.w);
- float limit = 0.5f*(1.0f + blend);
-
- /* first test for corners with single texture */
- if(N.x > limit*(N.x + N.y) && N.x > limit*(N.x + N.z)) {
- weight.x = 1.0f;
- }
- else if(N.y > limit*(N.x + N.y) && N.y > limit*(N.y + N.z)) {
- weight.y = 1.0f;
- }
- else if(N.z > limit*(N.x + N.z) && N.z > limit*(N.y + N.z)) {
- weight.z = 1.0f;
- }
- else if(blend > 0.0f) {
- /* in case of blending, test for mixes between two textures */
- if(N.z < (1.0f - limit)*(N.y + N.x)) {
- weight.x = N.x/(N.x + N.y);
- weight.x = saturate((weight.x - 0.5f*(1.0f - blend))/blend);
- weight.y = 1.0f - weight.x;
- }
- else if(N.x < (1.0f - limit)*(N.y + N.z)) {
- weight.y = N.y/(N.y + N.z);
- weight.y = saturate((weight.y - 0.5f*(1.0f - blend))/blend);
- weight.z = 1.0f - weight.y;
- }
- else if(N.y < (1.0f - limit)*(N.x + N.z)) {
- weight.x = N.x/(N.x + N.z);
- weight.x = saturate((weight.x - 0.5f*(1.0f - blend))/blend);
- weight.z = 1.0f - weight.x;
- }
- else {
- /* last case, we have a mix between three */
- weight.x = ((2.0f - limit)*N.x + (limit - 1.0f))/(2.0f*limit - 1.0f);
- weight.y = ((2.0f - limit)*N.y + (limit - 1.0f))/(2.0f*limit - 1.0f);
- weight.z = ((2.0f - limit)*N.z + (limit - 1.0f))/(2.0f*limit - 1.0f);
- }
- }
- else {
- /* Desperate mode, no valid choice anyway, fallback to one side.*/
- weight.x = 1.0f;
- }
-
- /* now fetch textures */
- uint co_offset, out_offset, alpha_offset, srgb;
- decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
-
- float3 co = stack_load_float3(stack, co_offset);
- uint id = node.y;
-
- float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- uint use_alpha = stack_valid(alpha_offset);
-
- /* Map so that no textures are flipped, rotation is somewhat arbitrary. */
- if(weight.x > 0.0f) {
- float2 uv = make_float2((signed_N.x < 0.0f)? 1.0f - co.y: co.y, co.z);
- f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
- }
- if(weight.y > 0.0f) {
- float2 uv = make_float2((signed_N.y > 0.0f)? 1.0f - co.x: co.x, co.z);
- f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
- }
- if(weight.z > 0.0f) {
- float2 uv = make_float2((signed_N.z > 0.0f)? 1.0f - co.y: co.y, co.x);
- f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
- }
-
- if(stack_valid(out_offset))
- stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
- if(stack_valid(alpha_offset))
- stack_store_float(stack, alpha_offset, f.w);
+ /* get object space normal */
+ float3 N = sd->N;
+
+ N = sd->N;
+ object_inverse_normal_transform(kg, sd, &N);
+
+ /* project from direction vector to barycentric coordinates in triangles */
+ float3 signed_N = N;
+
+ N.x = fabsf(N.x);
+ N.y = fabsf(N.y);
+ N.z = fabsf(N.z);
+
+ N /= (N.x + N.y + N.z);
+
+ /* basic idea is to think of this as a triangle, each corner representing
+ * one of the 3 faces of the cube. in the corners we have single textures,
+ * in between we blend between two textures, and in the middle we a blend
+ * between three textures.
+ *
+ * the Nxyz values are the barycentric coordinates in an equilateral
+ * triangle, which in case of blending, in the middle has a smaller
+ * equilateral triangle where 3 textures blend. this divides things into
+ * 7 zones, with an if() test for each zone */
+
+ float3 weight = make_float3(0.0f, 0.0f, 0.0f);
+ float blend = __int_as_float(node.w);
+ float limit = 0.5f * (1.0f + blend);
+
+ /* first test for corners with single texture */
+ if (N.x > limit * (N.x + N.y) && N.x > limit * (N.x + N.z)) {
+ weight.x = 1.0f;
+ }
+ else if (N.y > limit * (N.x + N.y) && N.y > limit * (N.y + N.z)) {
+ weight.y = 1.0f;
+ }
+ else if (N.z > limit * (N.x + N.z) && N.z > limit * (N.y + N.z)) {
+ weight.z = 1.0f;
+ }
+ else if (blend > 0.0f) {
+ /* in case of blending, test for mixes between two textures */
+ if (N.z < (1.0f - limit) * (N.y + N.x)) {
+ weight.x = N.x / (N.x + N.y);
+ weight.x = saturate((weight.x - 0.5f * (1.0f - blend)) / blend);
+ weight.y = 1.0f - weight.x;
+ }
+ else if (N.x < (1.0f - limit) * (N.y + N.z)) {
+ weight.y = N.y / (N.y + N.z);
+ weight.y = saturate((weight.y - 0.5f * (1.0f - blend)) / blend);
+ weight.z = 1.0f - weight.y;
+ }
+ else if (N.y < (1.0f - limit) * (N.x + N.z)) {
+ weight.x = N.x / (N.x + N.z);
+ weight.x = saturate((weight.x - 0.5f * (1.0f - blend)) / blend);
+ weight.z = 1.0f - weight.x;
+ }
+ else {
+ /* last case, we have a mix between three */
+ weight.x = ((2.0f - limit) * N.x + (limit - 1.0f)) / (2.0f * limit - 1.0f);
+ weight.y = ((2.0f - limit) * N.y + (limit - 1.0f)) / (2.0f * limit - 1.0f);
+ weight.z = ((2.0f - limit) * N.z + (limit - 1.0f)) / (2.0f * limit - 1.0f);
+ }
+ }
+ else {
+ /* Desperate mode, no valid choice anyway, fallback to one side.*/
+ weight.x = 1.0f;
+ }
+
+ /* now fetch textures */
+ uint co_offset, out_offset, alpha_offset, srgb;
+ decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
+
+ float3 co = stack_load_float3(stack, co_offset);
+ uint id = node.y;
+
+ float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ uint use_alpha = stack_valid(alpha_offset);
+
+ /* Map so that no textures are flipped, rotation is somewhat arbitrary. */
+ if (weight.x > 0.0f) {
+ float2 uv = make_float2((signed_N.x < 0.0f) ? 1.0f - co.y : co.y, co.z);
+ f += weight.x * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ }
+ if (weight.y > 0.0f) {
+ float2 uv = make_float2((signed_N.y > 0.0f) ? 1.0f - co.x : co.x, co.z);
+ f += weight.y * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ }
+ if (weight.z > 0.0f) {
+ float2 uv = make_float2((signed_N.z > 0.0f) ? 1.0f - co.y : co.y, co.x);
+ f += weight.z * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ }
+
+ if (stack_valid(out_offset))
+ stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
+ if (stack_valid(alpha_offset))
+ stack_store_float(stack, alpha_offset, f.w);
}
-ccl_device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
+ccl_device void svm_node_tex_environment(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint4 node)
{
- uint id = node.y;
- uint co_offset, out_offset, alpha_offset, srgb;
- uint projection = node.w;
+ uint id = node.y;
+ uint co_offset, out_offset, alpha_offset, srgb;
+ uint projection = node.w;
- decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
+ decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
- float3 co = stack_load_float3(stack, co_offset);
- float2 uv;
+ float3 co = stack_load_float3(stack, co_offset);
+ float2 uv;
- co = safe_normalize(co);
+ co = safe_normalize(co);
- if(projection == 0)
- uv = direction_to_equirectangular(co);
- else
- uv = direction_to_mirrorball(co);
+ if (projection == 0)
+ uv = direction_to_equirectangular(co);
+ else
+ uv = direction_to_mirrorball(co);
- uint use_alpha = stack_valid(alpha_offset);
- float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ uint use_alpha = stack_valid(alpha_offset);
+ float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
- if(stack_valid(out_offset))
- stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
- if(stack_valid(alpha_offset))
- stack_store_float(stack, alpha_offset, f.w);
+ if (stack_valid(out_offset))
+ stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
+ if (stack_valid(alpha_offset))
+ stack_store_float(stack, alpha_offset, f.w);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_invert.h b/intern/cycles/kernel/svm/svm_invert.h
index 57cc4281101..02024742b13 100644
--- a/intern/cycles/kernel/svm/svm_invert.h
+++ b/intern/cycles/kernel/svm/svm_invert.h
@@ -18,20 +18,21 @@ CCL_NAMESPACE_BEGIN
ccl_device float invert(float color, float factor)
{
- return factor*(1.0f - color) + (1.0f - factor) * color;
+ return factor * (1.0f - color) + (1.0f - factor) * color;
}
-ccl_device void svm_node_invert(ShaderData *sd, float *stack, uint in_fac, uint in_color, uint out_color)
+ccl_device void svm_node_invert(
+ ShaderData *sd, float *stack, uint in_fac, uint in_color, uint out_color)
{
- float factor = stack_load_float(stack, in_fac);
- float3 color = stack_load_float3(stack, in_color);
+ float factor = stack_load_float(stack, in_fac);
+ float3 color = stack_load_float3(stack, in_color);
- color.x = invert(color.x, factor);
- color.y = invert(color.y, factor);
- color.z = invert(color.z, factor);
+ color.x = invert(color.x, factor);
+ color.y = invert(color.y, factor);
+ color.z = invert(color.z, factor);
- if(stack_valid(out_color))
- stack_store_float3(stack, out_color, color);
+ if (stack_valid(out_color))
+ stack_store_float3(stack, out_color, color);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_light_path.h b/intern/cycles/kernel/svm/svm_light_path.h
index dd4390057cf..65a9a284a17 100644
--- a/intern/cycles/kernel/svm/svm_light_path.h
+++ b/intern/cycles/kernel/svm/svm_light_path.h
@@ -18,59 +18,99 @@ CCL_NAMESPACE_BEGIN
/* Light Path Node */
-ccl_device void svm_node_light_path(ShaderData *sd, ccl_addr_space PathState *state, float *stack, uint type, uint out_offset, int path_flag)
+ccl_device void svm_node_light_path(ShaderData *sd,
+ ccl_addr_space PathState *state,
+ float *stack,
+ uint type,
+ uint out_offset,
+ int path_flag)
{
- float info = 0.0f;
+ float info = 0.0f;
- switch(type) {
- case NODE_LP_camera: info = (path_flag & PATH_RAY_CAMERA)? 1.0f: 0.0f; break;
- case NODE_LP_shadow: info = (path_flag & PATH_RAY_SHADOW)? 1.0f: 0.0f; break;
- case NODE_LP_diffuse: info = (path_flag & PATH_RAY_DIFFUSE)? 1.0f: 0.0f; break;
- case NODE_LP_glossy: info = (path_flag & PATH_RAY_GLOSSY)? 1.0f: 0.0f; break;
- case NODE_LP_singular: info = (path_flag & PATH_RAY_SINGULAR)? 1.0f: 0.0f; break;
- case NODE_LP_reflection: info = (path_flag & PATH_RAY_REFLECT)? 1.0f: 0.0f; break;
- case NODE_LP_transmission: info = (path_flag & PATH_RAY_TRANSMIT)? 1.0f: 0.0f; break;
- case NODE_LP_volume_scatter: info = (path_flag & PATH_RAY_VOLUME_SCATTER)? 1.0f: 0.0f; break;
- case NODE_LP_backfacing: info = (sd->flag & SD_BACKFACING)? 1.0f: 0.0f; break;
- case NODE_LP_ray_length: info = sd->ray_length; break;
- case NODE_LP_ray_depth: info = (float)state->bounce; break;
- case NODE_LP_ray_diffuse: info = (float)state->diffuse_bounce; break;
- case NODE_LP_ray_glossy: info = (float)state->glossy_bounce; break;
- case NODE_LP_ray_transparent: info = (float)state->transparent_bounce; break;
- case NODE_LP_ray_transmission: info = (float)state->transmission_bounce; break;
- }
+ switch (type) {
+ case NODE_LP_camera:
+ info = (path_flag & PATH_RAY_CAMERA) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_shadow:
+ info = (path_flag & PATH_RAY_SHADOW) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_diffuse:
+ info = (path_flag & PATH_RAY_DIFFUSE) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_glossy:
+ info = (path_flag & PATH_RAY_GLOSSY) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_singular:
+ info = (path_flag & PATH_RAY_SINGULAR) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_reflection:
+ info = (path_flag & PATH_RAY_REFLECT) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_transmission:
+ info = (path_flag & PATH_RAY_TRANSMIT) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_volume_scatter:
+ info = (path_flag & PATH_RAY_VOLUME_SCATTER) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_backfacing:
+ info = (sd->flag & SD_BACKFACING) ? 1.0f : 0.0f;
+ break;
+ case NODE_LP_ray_length:
+ info = sd->ray_length;
+ break;
+ case NODE_LP_ray_depth:
+ info = (float)state->bounce;
+ break;
+ case NODE_LP_ray_diffuse:
+ info = (float)state->diffuse_bounce;
+ break;
+ case NODE_LP_ray_glossy:
+ info = (float)state->glossy_bounce;
+ break;
+ case NODE_LP_ray_transparent:
+ info = (float)state->transparent_bounce;
+ break;
+ case NODE_LP_ray_transmission:
+ info = (float)state->transmission_bounce;
+ break;
+ }
- stack_store_float(stack, out_offset, info);
+ stack_store_float(stack, out_offset, info);
}
/* Light Falloff Node */
ccl_device void svm_node_light_falloff(ShaderData *sd, float *stack, uint4 node)
{
- uint strength_offset, out_offset, smooth_offset;
+ uint strength_offset, out_offset, smooth_offset;
- decode_node_uchar4(node.z, &strength_offset, &smooth_offset, &out_offset, NULL);
+ decode_node_uchar4(node.z, &strength_offset, &smooth_offset, &out_offset, NULL);
- float strength = stack_load_float(stack, strength_offset);
- uint type = node.y;
+ float strength = stack_load_float(stack, strength_offset);
+ uint type = node.y;
- switch(type) {
- case NODE_LIGHT_FALLOFF_QUADRATIC: break;
- case NODE_LIGHT_FALLOFF_LINEAR: strength *= sd->ray_length; break;
- case NODE_LIGHT_FALLOFF_CONSTANT: strength *= sd->ray_length*sd->ray_length; break;
- }
+ switch (type) {
+ case NODE_LIGHT_FALLOFF_QUADRATIC:
+ break;
+ case NODE_LIGHT_FALLOFF_LINEAR:
+ strength *= sd->ray_length;
+ break;
+ case NODE_LIGHT_FALLOFF_CONSTANT:
+ strength *= sd->ray_length * sd->ray_length;
+ break;
+ }
- float smooth = stack_load_float(stack, smooth_offset);
+ float smooth = stack_load_float(stack, smooth_offset);
- if(smooth > 0.0f) {
- float squared = sd->ray_length*sd->ray_length;
- /* Distant lamps set the ray length to FLT_MAX, which causes squared to overflow. */
- if(isfinite(squared)) {
- strength *= squared/(smooth + squared);
- }
- }
+ if (smooth > 0.0f) {
+ float squared = sd->ray_length * sd->ray_length;
+ /* Distant lamps set the ray length to FLT_MAX, which causes squared to overflow. */
+ if (isfinite(squared)) {
+ strength *= squared / (smooth + squared);
+ }
+ }
- stack_store_float(stack, out_offset, strength);
+ stack_store_float(stack, out_offset, strength);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_magic.h b/intern/cycles/kernel/svm/svm_magic.h
index 6afaff37acd..115d2e2fe4b 100644
--- a/intern/cycles/kernel/svm/svm_magic.h
+++ b/intern/cycles/kernel/svm/svm_magic.h
@@ -20,92 +20,93 @@ CCL_NAMESPACE_BEGIN
ccl_device_noinline float3 svm_magic(float3 p, int n, float distortion)
{
- float x = sinf((p.x + p.y + p.z)*5.0f);
- float y = cosf((-p.x + p.y - p.z)*5.0f);
- float z = -cosf((-p.x - p.y + p.z)*5.0f);
-
- if(n > 0) {
- x *= distortion;
- y *= distortion;
- z *= distortion;
- y = -cosf(x-y+z);
- y *= distortion;
-
- if(n > 1) {
- x = cosf(x-y-z);
- x *= distortion;
-
- if(n > 2) {
- z = sinf(-x-y-z);
- z *= distortion;
-
- if(n > 3) {
- x = -cosf(-x+y-z);
- x *= distortion;
-
- if(n > 4) {
- y = -sinf(-x+y+z);
- y *= distortion;
-
- if(n > 5) {
- y = -cosf(-x+y+z);
- y *= distortion;
-
- if(n > 6) {
- x = cosf(x+y+z);
- x *= distortion;
-
- if(n > 7) {
- z = sinf(x+y-z);
- z *= distortion;
-
- if(n > 8) {
- x = -cosf(-x-y+z);
- x *= distortion;
-
- if(n > 9) {
- y = -sinf(x-y+z);
- y *= distortion;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- if(distortion != 0.0f) {
- distortion *= 2.0f;
- x /= distortion;
- y /= distortion;
- z /= distortion;
- }
-
- return make_float3(0.5f - x, 0.5f - y, 0.5f - z);
+ float x = sinf((p.x + p.y + p.z) * 5.0f);
+ float y = cosf((-p.x + p.y - p.z) * 5.0f);
+ float z = -cosf((-p.x - p.y + p.z) * 5.0f);
+
+ if (n > 0) {
+ x *= distortion;
+ y *= distortion;
+ z *= distortion;
+ y = -cosf(x - y + z);
+ y *= distortion;
+
+ if (n > 1) {
+ x = cosf(x - y - z);
+ x *= distortion;
+
+ if (n > 2) {
+ z = sinf(-x - y - z);
+ z *= distortion;
+
+ if (n > 3) {
+ x = -cosf(-x + y - z);
+ x *= distortion;
+
+ if (n > 4) {
+ y = -sinf(-x + y + z);
+ y *= distortion;
+
+ if (n > 5) {
+ y = -cosf(-x + y + z);
+ y *= distortion;
+
+ if (n > 6) {
+ x = cosf(x + y + z);
+ x *= distortion;
+
+ if (n > 7) {
+ z = sinf(x + y - z);
+ z *= distortion;
+
+ if (n > 8) {
+ x = -cosf(-x - y + z);
+ x *= distortion;
+
+ if (n > 9) {
+ y = -sinf(x - y + z);
+ y *= distortion;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (distortion != 0.0f) {
+ distortion *= 2.0f;
+ x /= distortion;
+ y /= distortion;
+ z /= distortion;
+ }
+
+ return make_float3(0.5f - x, 0.5f - y, 0.5f - z);
}
-ccl_device void svm_node_tex_magic(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_tex_magic(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint depth;
- uint scale_offset, distortion_offset, co_offset, fac_offset, color_offset;
+ uint depth;
+ uint scale_offset, distortion_offset, co_offset, fac_offset, color_offset;
- decode_node_uchar4(node.y, &depth, &color_offset, &fac_offset, NULL);
- decode_node_uchar4(node.z, &co_offset, &scale_offset, &distortion_offset, NULL);
+ decode_node_uchar4(node.y, &depth, &color_offset, &fac_offset, NULL);
+ decode_node_uchar4(node.z, &co_offset, &scale_offset, &distortion_offset, NULL);
- uint4 node2 = read_node(kg, offset);
- float3 co = stack_load_float3(stack, co_offset);
- float scale = stack_load_float_default(stack, scale_offset, node2.x);
- float distortion = stack_load_float_default(stack, distortion_offset, node2.y);
+ uint4 node2 = read_node(kg, offset);
+ float3 co = stack_load_float3(stack, co_offset);
+ float scale = stack_load_float_default(stack, scale_offset, node2.x);
+ float distortion = stack_load_float_default(stack, distortion_offset, node2.y);
- float3 color = svm_magic(co*scale, depth, distortion);
+ float3 color = svm_magic(co * scale, depth, distortion);
- if(stack_valid(fac_offset))
- stack_store_float(stack, fac_offset, average(color));
- if(stack_valid(color_offset))
- stack_store_float3(stack, color_offset, color);
+ if (stack_valid(fac_offset))
+ stack_store_float(stack, fac_offset, average(color));
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, color);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_mapping.h b/intern/cycles/kernel/svm/svm_mapping.h
index 86181283821..998a29912d4 100644
--- a/intern/cycles/kernel/svm/svm_mapping.h
+++ b/intern/cycles/kernel/svm/svm_mapping.h
@@ -18,28 +18,30 @@ CCL_NAMESPACE_BEGIN
/* Mapping Node */
-ccl_device void svm_node_mapping(KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset)
+ccl_device void svm_node_mapping(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset)
{
- float3 v = stack_load_float3(stack, vec_offset);
+ float3 v = stack_load_float3(stack, vec_offset);
- Transform tfm;
- tfm.x = read_node_float(kg, offset);
- tfm.y = read_node_float(kg, offset);
- tfm.z = read_node_float(kg, offset);
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
- float3 r = transform_point(&tfm, v);
- stack_store_float3(stack, out_offset, r);
+ float3 r = transform_point(&tfm, v);
+ stack_store_float3(stack, out_offset, r);
}
-ccl_device void svm_node_min_max(KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset)
+ccl_device void svm_node_min_max(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset)
{
- float3 v = stack_load_float3(stack, vec_offset);
+ float3 v = stack_load_float3(stack, vec_offset);
- float3 mn = float4_to_float3(read_node_float(kg, offset));
- float3 mx = float4_to_float3(read_node_float(kg, offset));
+ float3 mn = float4_to_float3(read_node_float(kg, offset));
+ float3 mx = float4_to_float3(read_node_float(kg, offset));
- float3 r = min(max(mn, v), mx);
- stack_store_float3(stack, out_offset, r);
+ float3 r = min(max(mn, v), mx);
+ stack_store_float3(stack, out_offset, r);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h
index c9a838361cd..5920913825b 100644
--- a/intern/cycles/kernel/svm/svm_math.h
+++ b/intern/cycles/kernel/svm/svm_math.h
@@ -18,32 +18,46 @@ CCL_NAMESPACE_BEGIN
/* Nodes */
-ccl_device void svm_node_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint f1_offset, uint f2_offset, int *offset)
+ccl_device void svm_node_math(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint itype,
+ uint f1_offset,
+ uint f2_offset,
+ int *offset)
{
- NodeMath type = (NodeMath)itype;
- float f1 = stack_load_float(stack, f1_offset);
- float f2 = stack_load_float(stack, f2_offset);
- float f = svm_math(type, f1, f2);
+ NodeMath type = (NodeMath)itype;
+ float f1 = stack_load_float(stack, f1_offset);
+ float f2 = stack_load_float(stack, f2_offset);
+ float f = svm_math(type, f1, f2);
- uint4 node1 = read_node(kg, offset);
+ uint4 node1 = read_node(kg, offset);
- stack_store_float(stack, node1.y, f);
+ stack_store_float(stack, node1.y, f);
}
-ccl_device void svm_node_vector_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint v1_offset, uint v2_offset, int *offset)
+ccl_device void svm_node_vector_math(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint itype,
+ uint v1_offset,
+ uint v2_offset,
+ int *offset)
{
- NodeVectorMath type = (NodeVectorMath)itype;
- float3 v1 = stack_load_float3(stack, v1_offset);
- float3 v2 = stack_load_float3(stack, v2_offset);
- float f;
- float3 v;
+ NodeVectorMath type = (NodeVectorMath)itype;
+ float3 v1 = stack_load_float3(stack, v1_offset);
+ float3 v2 = stack_load_float3(stack, v2_offset);
+ float f;
+ float3 v;
- svm_vector_math(&f, &v, type, v1, v2);
+ svm_vector_math(&f, &v, type, v1, v2);
- uint4 node1 = read_node(kg, offset);
+ uint4 node1 = read_node(kg, offset);
- if(stack_valid(node1.y)) stack_store_float(stack, node1.y, f);
- if(stack_valid(node1.z)) stack_store_float3(stack, node1.z, v);
+ if (stack_valid(node1.y))
+ stack_store_float(stack, node1.y, f);
+ if (stack_valid(node1.z))
+ stack_store_float3(stack, node1.z, v);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h
index 669b174e4a3..e3544515f1b 100644
--- a/intern/cycles/kernel/svm/svm_math_util.h
+++ b/intern/cycles/kernel/svm/svm_math_util.h
@@ -18,96 +18,97 @@ CCL_NAMESPACE_BEGIN
ccl_device float average_fac(float3 v)
{
- return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f;
+ return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z)) / 3.0f;
}
-ccl_device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2)
+ccl_device void svm_vector_math(
+ float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2)
{
- if(type == NODE_VECTOR_MATH_ADD) {
- *Vector = Vector1 + Vector2;
- *Fac = average_fac(*Vector);
- }
- else if(type == NODE_VECTOR_MATH_SUBTRACT) {
- *Vector = Vector1 - Vector2;
- *Fac = average_fac(*Vector);
- }
- else if(type == NODE_VECTOR_MATH_AVERAGE) {
- *Vector = safe_normalize_len(Vector1 + Vector2, Fac);
- }
- else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) {
- *Fac = dot(Vector1, Vector2);
- *Vector = make_float3(0.0f, 0.0f, 0.0f);
- }
- else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) {
- *Vector = safe_normalize_len(cross(Vector1, Vector2), Fac);
- }
- else if(type == NODE_VECTOR_MATH_NORMALIZE) {
- *Vector = safe_normalize_len(Vector1, Fac);
- }
- else {
- *Fac = 0.0f;
- *Vector = make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (type == NODE_VECTOR_MATH_ADD) {
+ *Vector = Vector1 + Vector2;
+ *Fac = average_fac(*Vector);
+ }
+ else if (type == NODE_VECTOR_MATH_SUBTRACT) {
+ *Vector = Vector1 - Vector2;
+ *Fac = average_fac(*Vector);
+ }
+ else if (type == NODE_VECTOR_MATH_AVERAGE) {
+ *Vector = safe_normalize_len(Vector1 + Vector2, Fac);
+ }
+ else if (type == NODE_VECTOR_MATH_DOT_PRODUCT) {
+ *Fac = dot(Vector1, Vector2);
+ *Vector = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ else if (type == NODE_VECTOR_MATH_CROSS_PRODUCT) {
+ *Vector = safe_normalize_len(cross(Vector1, Vector2), Fac);
+ }
+ else if (type == NODE_VECTOR_MATH_NORMALIZE) {
+ *Vector = safe_normalize_len(Vector1, Fac);
+ }
+ else {
+ *Fac = 0.0f;
+ *Vector = make_float3(0.0f, 0.0f, 0.0f);
+ }
}
ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
{
- float Fac;
-
- if(type == NODE_MATH_ADD)
- Fac = Fac1 + Fac2;
- else if(type == NODE_MATH_SUBTRACT)
- Fac = Fac1 - Fac2;
- else if(type == NODE_MATH_MULTIPLY)
- Fac = Fac1*Fac2;
- else if(type == NODE_MATH_DIVIDE)
- Fac = safe_divide(Fac1, Fac2);
- else if(type == NODE_MATH_SINE)
- Fac = sinf(Fac1);
- else if(type == NODE_MATH_COSINE)
- Fac = cosf(Fac1);
- else if(type == NODE_MATH_TANGENT)
- Fac = tanf(Fac1);
- else if(type == NODE_MATH_ARCSINE)
- Fac = safe_asinf(Fac1);
- else if(type == NODE_MATH_ARCCOSINE)
- Fac = safe_acosf(Fac1);
- else if(type == NODE_MATH_ARCTANGENT)
- Fac = atanf(Fac1);
- else if(type == NODE_MATH_POWER)
- Fac = safe_powf(Fac1, Fac2);
- else if(type == NODE_MATH_LOGARITHM)
- Fac = safe_logf(Fac1, Fac2);
- else if(type == NODE_MATH_MINIMUM)
- Fac = fminf(Fac1, Fac2);
- else if(type == NODE_MATH_MAXIMUM)
- Fac = fmaxf(Fac1, Fac2);
- else if(type == NODE_MATH_ROUND)
- Fac = floorf(Fac1 + 0.5f);
- else if(type == NODE_MATH_LESS_THAN)
- Fac = Fac1 < Fac2;
- else if(type == NODE_MATH_GREATER_THAN)
- Fac = Fac1 > Fac2;
- else if(type == NODE_MATH_MODULO)
- Fac = safe_modulo(Fac1, Fac2);
- else if(type == NODE_MATH_ABSOLUTE)
- Fac = fabsf(Fac1);
- else if(type == NODE_MATH_ARCTAN2)
- Fac = atan2f(Fac1, Fac2);
- else if(type == NODE_MATH_FLOOR)
- Fac = floorf(Fac1);
- else if(type == NODE_MATH_CEIL)
- Fac = ceilf(Fac1);
- else if(type == NODE_MATH_FRACT)
- Fac = Fac1 - floorf(Fac1);
- else if(type == NODE_MATH_SQRT)
- Fac = safe_sqrtf(Fac1);
- else if(type == NODE_MATH_CLAMP)
- Fac = saturate(Fac1);
- else
- Fac = 0.0f;
-
- return Fac;
+ float Fac;
+
+ if (type == NODE_MATH_ADD)
+ Fac = Fac1 + Fac2;
+ else if (type == NODE_MATH_SUBTRACT)
+ Fac = Fac1 - Fac2;
+ else if (type == NODE_MATH_MULTIPLY)
+ Fac = Fac1 * Fac2;
+ else if (type == NODE_MATH_DIVIDE)
+ Fac = safe_divide(Fac1, Fac2);
+ else if (type == NODE_MATH_SINE)
+ Fac = sinf(Fac1);
+ else if (type == NODE_MATH_COSINE)
+ Fac = cosf(Fac1);
+ else if (type == NODE_MATH_TANGENT)
+ Fac = tanf(Fac1);
+ else if (type == NODE_MATH_ARCSINE)
+ Fac = safe_asinf(Fac1);
+ else if (type == NODE_MATH_ARCCOSINE)
+ Fac = safe_acosf(Fac1);
+ else if (type == NODE_MATH_ARCTANGENT)
+ Fac = atanf(Fac1);
+ else if (type == NODE_MATH_POWER)
+ Fac = safe_powf(Fac1, Fac2);
+ else if (type == NODE_MATH_LOGARITHM)
+ Fac = safe_logf(Fac1, Fac2);
+ else if (type == NODE_MATH_MINIMUM)
+ Fac = fminf(Fac1, Fac2);
+ else if (type == NODE_MATH_MAXIMUM)
+ Fac = fmaxf(Fac1, Fac2);
+ else if (type == NODE_MATH_ROUND)
+ Fac = floorf(Fac1 + 0.5f);
+ else if (type == NODE_MATH_LESS_THAN)
+ Fac = Fac1 < Fac2;
+ else if (type == NODE_MATH_GREATER_THAN)
+ Fac = Fac1 > Fac2;
+ else if (type == NODE_MATH_MODULO)
+ Fac = safe_modulo(Fac1, Fac2);
+ else if (type == NODE_MATH_ABSOLUTE)
+ Fac = fabsf(Fac1);
+ else if (type == NODE_MATH_ARCTAN2)
+ Fac = atan2f(Fac1, Fac2);
+ else if (type == NODE_MATH_FLOOR)
+ Fac = floorf(Fac1);
+ else if (type == NODE_MATH_CEIL)
+ Fac = ceilf(Fac1);
+ else if (type == NODE_MATH_FRACT)
+ Fac = Fac1 - floorf(Fac1);
+ else if (type == NODE_MATH_SQRT)
+ Fac = safe_sqrtf(Fac1);
+ else if (type == NODE_MATH_CLAMP)
+ Fac = saturate(Fac1);
+ else
+ Fac = 0.0f;
+
+ return Fac;
}
/* Calculate color in range 800..12000 using an approximation
@@ -117,74 +118,72 @@ ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
*/
ccl_static_constant float blackbody_table_r[6][3] = {
- { 2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f },
- { 3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f },
- { 4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f },
- { 4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f },
- { 4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f },
- { 3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f },
+ {2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f},
+ {3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f},
+ {4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f},
+ {4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f},
+ {4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f},
+ {3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f},
};
ccl_static_constant float blackbody_table_g[6][3] = {
- { -7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f },
- { -1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f },
- { -1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f },
- { -1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f },
- { -1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f },
- { -5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f },
+ {-7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f},
+ {-1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f},
+ {-1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f},
+ {-1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f},
+ {-1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f},
+ {-5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f},
};
ccl_static_constant float blackbody_table_b[6][4] = {
- { 0.0f, 0.0f, 0.0f, 0.0f }, /* zeros should be optimized by compiler */
- { 0.0f, 0.0f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f },
- { -2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f },
- { -2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f },
- { 6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f },
+ {0.0f, 0.0f, 0.0f, 0.0f}, /* zeros should be optimized by compiler */
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {-2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f},
+ {-2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f},
+ {6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f},
};
-
ccl_device float3 svm_math_blackbody_color(float t)
{
- /* TODO(lukas): Reimplement in XYZ. */
-
- if(t >= 12000.0f) {
- return make_float3(0.826270103f, 0.994478524f, 1.56626022f);
- }
- else if(t < 965.0f) {
- /* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */
- return make_float3(4.70366907f, 0.0f, 0.0f);
- }
-
- int i = (t >= 6365.0f)? 5:
- (t >= 3315.0f)? 4:
- (t >= 1902.0f)? 3:
- (t >= 1449.0f)? 2:
- (t >= 1167.0f)? 1: 0;
-
- ccl_constant float *r = blackbody_table_r[i];
- ccl_constant float *g = blackbody_table_g[i];
- ccl_constant float *b = blackbody_table_b[i];
-
- const float t_inv = 1.0f / t;
- return make_float3(r[0] * t_inv + r[1] * t + r[2],
- g[0] * t_inv + g[1] * t + g[2],
- ((b[0] * t + b[1]) * t + b[2]) * t + b[3]);
+ /* TODO(lukas): Reimplement in XYZ. */
+
+ if (t >= 12000.0f) {
+ return make_float3(0.826270103f, 0.994478524f, 1.56626022f);
+ }
+ else if (t < 965.0f) {
+ /* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */
+ return make_float3(4.70366907f, 0.0f, 0.0f);
+ }
+
+ int i = (t >= 6365.0f) ?
+ 5 :
+ (t >= 3315.0f) ? 4 :
+ (t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0;
+
+ ccl_constant float *r = blackbody_table_r[i];
+ ccl_constant float *g = blackbody_table_g[i];
+ ccl_constant float *b = blackbody_table_b[i];
+
+ const float t_inv = 1.0f / t;
+ return make_float3(r[0] * t_inv + r[1] * t + r[2],
+ g[0] * t_inv + g[1] * t + g[2],
+ ((b[0] * t + b[1]) * t + b[2]) * t + b[3]);
}
ccl_device_inline float3 svm_math_gamma_color(float3 color, float gamma)
{
- if(gamma == 0.0f)
- return make_float3(1.0f, 1.0f, 1.0f);
+ if (gamma == 0.0f)
+ return make_float3(1.0f, 1.0f, 1.0f);
- if(color.x > 0.0f)
- color.x = powf(color.x, gamma);
- if(color.y > 0.0f)
- color.y = powf(color.y, gamma);
- if(color.z > 0.0f)
- color.z = powf(color.z, gamma);
+ if (color.x > 0.0f)
+ color.x = powf(color.x, gamma);
+ if (color.y > 0.0f)
+ color.y = powf(color.y, gamma);
+ if (color.z > 0.0f)
+ color.z = powf(color.z, gamma);
- return color;
+ return color;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h
index 903a4dacebf..15114bfd5e4 100644
--- a/intern/cycles/kernel/svm/svm_mix.h
+++ b/intern/cycles/kernel/svm/svm_mix.h
@@ -18,17 +18,23 @@ CCL_NAMESPACE_BEGIN
/* Node */
-ccl_device void svm_node_mix(KernelGlobals *kg, ShaderData *sd, float *stack, uint fac_offset, uint c1_offset, uint c2_offset, int *offset)
+ccl_device void svm_node_mix(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint fac_offset,
+ uint c1_offset,
+ uint c2_offset,
+ int *offset)
{
- /* read extra data */
- uint4 node1 = read_node(kg, offset);
+ /* read extra data */
+ uint4 node1 = read_node(kg, offset);
- float fac = stack_load_float(stack, fac_offset);
- float3 c1 = stack_load_float3(stack, c1_offset);
- float3 c2 = stack_load_float3(stack, c2_offset);
- float3 result = svm_mix((NodeMix)node1.y, fac, c1, c2);
+ float fac = stack_load_float(stack, fac_offset);
+ float3 c1 = stack_load_float3(stack, c1_offset);
+ float3 c2 = stack_load_float3(stack, c2_offset);
+ float3 result = svm_mix((NodeMix)node1.y, fac, c1, c2);
- stack_store_float3(stack, node1.z, result);
+ stack_store_float3(stack, node1.z, result);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_musgrave.h b/intern/cycles/kernel/svm/svm_musgrave.h
index 5d9e12628ca..67fb5ca6241 100644
--- a/intern/cycles/kernel/svm/svm_musgrave.h
+++ b/intern/cycles/kernel/svm/svm_musgrave.h
@@ -27,23 +27,23 @@ CCL_NAMESPACE_BEGIN
ccl_device_noinline float noise_musgrave_fBm(float3 p, float H, float lacunarity, float octaves)
{
- float rmd;
- float value = 0.0f;
- float pwr = 1.0f;
- float pwHL = powf(lacunarity, -H);
- int i;
-
- for(i = 0; i < float_to_int(octaves); i++) {
- value += snoise(p) * pwr;
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floorf(octaves);
- if(rmd != 0.0f)
- value += rmd * snoise(p) * pwr;
-
- return value;
+ float rmd;
+ float value = 0.0f;
+ float pwr = 1.0f;
+ float pwHL = powf(lacunarity, -H);
+ int i;
+
+ for (i = 0; i < float_to_int(octaves); i++) {
+ value += snoise(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f)
+ value += rmd * snoise(p) * pwr;
+
+ return value;
}
/* Musgrave Multifractal
@@ -53,25 +53,28 @@ ccl_device_noinline float noise_musgrave_fBm(float3 p, float H, float lacunarity
* octaves: number of frequencies in the fBm
*/
-ccl_device_noinline float noise_musgrave_multi_fractal(float3 p, float H, float lacunarity, float octaves)
+ccl_device_noinline float noise_musgrave_multi_fractal(float3 p,
+ float H,
+ float lacunarity,
+ float octaves)
{
- float rmd;
- float value = 1.0f;
- float pwr = 1.0f;
- float pwHL = powf(lacunarity, -H);
- int i;
-
- for(i = 0; i < float_to_int(octaves); i++) {
- value *= (pwr * snoise(p) + 1.0f);
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floorf(octaves);
- if(rmd != 0.0f)
- value *= (rmd * pwr * snoise(p) + 1.0f); /* correct? */
-
- return value;
+ float rmd;
+ float value = 1.0f;
+ float pwr = 1.0f;
+ float pwHL = powf(lacunarity, -H);
+ int i;
+
+ for (i = 0; i < float_to_int(octaves); i++) {
+ value *= (pwr * snoise(p) + 1.0f);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f)
+ value *= (rmd * pwr * snoise(p) + 1.0f); /* correct? */
+
+ return value;
}
/* Musgrave Heterogeneous Terrain
@@ -82,31 +85,32 @@ ccl_device_noinline float noise_musgrave_multi_fractal(float3 p, float H, float
* offset: raises the terrain from `sea level'
*/
-ccl_device_noinline float noise_musgrave_hetero_terrain(float3 p, float H, float lacunarity, float octaves, float offset)
+ccl_device_noinline float noise_musgrave_hetero_terrain(
+ float3 p, float H, float lacunarity, float octaves, float offset)
{
- float value, increment, rmd;
- float pwHL = powf(lacunarity, -H);
- float pwr = pwHL;
- int i;
-
- /* first unscaled octave of function; later octaves are scaled */
- value = offset + snoise(p);
- p *= lacunarity;
-
- for(i = 1; i < float_to_int(octaves); i++) {
- increment = (snoise(p) + offset) * pwr * value;
- value += increment;
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floorf(octaves);
- if(rmd != 0.0f) {
- increment = (snoise(p) + offset) * pwr * value;
- value += rmd * increment;
- }
-
- return value;
+ float value, increment, rmd;
+ float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ value = offset + snoise(p);
+ p *= lacunarity;
+
+ for (i = 1; i < float_to_int(octaves); i++) {
+ increment = (snoise(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ increment = (snoise(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
}
/* Hybrid Additive/Multiplicative Multifractal Terrain
@@ -117,33 +121,34 @@ ccl_device_noinline float noise_musgrave_hetero_terrain(float3 p, float H, float
* offset: raises the terrain from `sea level'
*/
-ccl_device_noinline float noise_musgrave_hybrid_multi_fractal(float3 p, float H, float lacunarity, float octaves, float offset, float gain)
+ccl_device_noinline float noise_musgrave_hybrid_multi_fractal(
+ float3 p, float H, float lacunarity, float octaves, float offset, float gain)
{
- float result, signal, weight, rmd;
- float pwHL = powf(lacunarity, -H);
- float pwr = pwHL;
- int i;
-
- result = snoise(p) + offset;
- weight = gain * result;
- p *= lacunarity;
-
- for(i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
- if(weight > 1.0f)
- weight = 1.0f;
-
- signal = (snoise(p) + offset) * pwr;
- pwr *= pwHL;
- result += weight * signal;
- weight *= gain * signal;
- p *= lacunarity;
- }
-
- rmd = octaves - floorf(octaves);
- if(rmd != 0.0f)
- result += rmd * ((snoise(p) + offset) * pwr);
-
- return result;
+ float result, signal, weight, rmd;
+ float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+
+ result = snoise(p) + offset;
+ weight = gain * result;
+ p *= lacunarity;
+
+ for (i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
+ if (weight > 1.0f)
+ weight = 1.0f;
+
+ signal = (snoise(p) + offset) * pwr;
+ pwr *= pwHL;
+ result += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f)
+ result += rmd * ((snoise(p) + offset) * pwr);
+
+ return result;
}
/* Ridged Multifractal Terrain
@@ -154,81 +159,93 @@ ccl_device_noinline float noise_musgrave_hybrid_multi_fractal(float3 p, float H,
* offset: raises the terrain from `sea level'
*/
-ccl_device_noinline float noise_musgrave_ridged_multi_fractal(float3 p, float H, float lacunarity, float octaves, float offset, float gain)
+ccl_device_noinline float noise_musgrave_ridged_multi_fractal(
+ float3 p, float H, float lacunarity, float octaves, float offset, float gain)
{
- float result, signal, weight;
- float pwHL = powf(lacunarity, -H);
- float pwr = pwHL;
- int i;
-
- signal = offset - fabsf(snoise(p));
- signal *= signal;
- result = signal;
- weight = 1.0f;
-
- for(i = 1; i < float_to_int(octaves); i++) {
- p *= lacunarity;
- weight = saturate(signal * gain);
- signal = offset - fabsf(snoise(p));
- signal *= signal;
- signal *= weight;
- result += signal * pwr;
- pwr *= pwHL;
- }
-
- return result;
+ float result, signal, weight;
+ float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+
+ signal = offset - fabsf(snoise(p));
+ signal *= signal;
+ result = signal;
+ weight = 1.0f;
+
+ for (i = 1; i < float_to_int(octaves); i++) {
+ p *= lacunarity;
+ weight = saturate(signal * gain);
+ signal = offset - fabsf(snoise(p));
+ signal *= signal;
+ signal *= weight;
+ result += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return result;
}
/* Shader */
-ccl_device float svm_musgrave(NodeMusgraveType type, float dimension, float lacunarity, float octaves, float offset, float intensity, float gain, float3 p)
+ccl_device float svm_musgrave(NodeMusgraveType type,
+ float dimension,
+ float lacunarity,
+ float octaves,
+ float offset,
+ float intensity,
+ float gain,
+ float3 p)
{
- if(type == NODE_MUSGRAVE_MULTIFRACTAL)
- return intensity*noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
- else if(type == NODE_MUSGRAVE_FBM)
- return intensity*noise_musgrave_fBm(p, dimension, lacunarity, octaves);
- else if(type == NODE_MUSGRAVE_HYBRID_MULTIFRACTAL)
- return intensity*noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
- else if(type == NODE_MUSGRAVE_RIDGED_MULTIFRACTAL)
- return intensity*noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
- else if(type == NODE_MUSGRAVE_HETERO_TERRAIN)
- return intensity*noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
-
- return 0.0f;
+ if (type == NODE_MUSGRAVE_MULTIFRACTAL)
+ return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
+ else if (type == NODE_MUSGRAVE_FBM)
+ return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
+ else if (type == NODE_MUSGRAVE_HYBRID_MULTIFRACTAL)
+ return intensity *
+ noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
+ else if (type == NODE_MUSGRAVE_RIDGED_MULTIFRACTAL)
+ return intensity *
+ noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
+ else if (type == NODE_MUSGRAVE_HETERO_TERRAIN)
+ return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
+
+ return 0.0f;
}
-ccl_device void svm_node_tex_musgrave(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_tex_musgrave(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint4 node2 = read_node(kg, offset);
- uint4 node3 = read_node(kg, offset);
-
- uint type, co_offset, color_offset, fac_offset;
- uint dimension_offset, lacunarity_offset, detail_offset, offset_offset;
- uint gain_offset, scale_offset;
-
- decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset);
- decode_node_uchar4(node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset);
- decode_node_uchar4(node.w, &gain_offset, &scale_offset, NULL, NULL);
-
- float3 co = stack_load_float3(stack, co_offset);
- float dimension = stack_load_float_default(stack, dimension_offset, node2.x);
- float lacunarity = stack_load_float_default(stack, lacunarity_offset, node2.y);
- float detail = stack_load_float_default(stack, detail_offset, node2.z);
- float foffset = stack_load_float_default(stack, offset_offset, node2.w);
- float gain = stack_load_float_default(stack, gain_offset, node3.x);
- float scale = stack_load_float_default(stack, scale_offset, node3.y);
-
- dimension = fmaxf(dimension, 1e-5f);
- detail = clamp(detail, 0.0f, 16.0f);
- lacunarity = fmaxf(lacunarity, 1e-5f);
-
- float f = svm_musgrave((NodeMusgraveType)type,
- dimension, lacunarity, detail, foffset, 1.0f, gain, co*scale);
-
- if(stack_valid(fac_offset))
- stack_store_float(stack, fac_offset, f);
- if(stack_valid(color_offset))
- stack_store_float3(stack, color_offset, make_float3(f, f, f));
+ uint4 node2 = read_node(kg, offset);
+ uint4 node3 = read_node(kg, offset);
+
+ uint type, co_offset, color_offset, fac_offset;
+ uint dimension_offset, lacunarity_offset, detail_offset, offset_offset;
+ uint gain_offset, scale_offset;
+
+ decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset);
+ decode_node_uchar4(
+ node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset);
+ decode_node_uchar4(node.w, &gain_offset, &scale_offset, NULL, NULL);
+
+ float3 co = stack_load_float3(stack, co_offset);
+ float dimension = stack_load_float_default(stack, dimension_offset, node2.x);
+ float lacunarity = stack_load_float_default(stack, lacunarity_offset, node2.y);
+ float detail = stack_load_float_default(stack, detail_offset, node2.z);
+ float foffset = stack_load_float_default(stack, offset_offset, node2.w);
+ float gain = stack_load_float_default(stack, gain_offset, node3.x);
+ float scale = stack_load_float_default(stack, scale_offset, node3.y);
+
+ dimension = fmaxf(dimension, 1e-5f);
+ detail = clamp(detail, 0.0f, 16.0f);
+ lacunarity = fmaxf(lacunarity, 1e-5f);
+
+ float f = svm_musgrave(
+ (NodeMusgraveType)type, dimension, lacunarity, detail, foffset, 1.0f, gain, co * scale);
+
+ if (stack_valid(fac_offset))
+ stack_store_float(stack, fac_offset, f);
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, make_float3(f, f, f));
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
index 8c425ecf326..322579ccfe3 100644
--- a/intern/cycles/kernel/svm/svm_noise.h
+++ b/intern/cycles/kernel/svm/svm_noise.h
@@ -33,280 +33,302 @@
CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_SSE2__
-ccl_device_inline ssei quick_floor_sse(const ssef& x)
+ccl_device_inline ssei quick_floor_sse(const ssef &x)
{
- ssei b = truncatei(x);
- ssei isneg = cast((x < ssef(0.0f)).m128);
- return b + isneg; // unsaturated add 0xffffffff is the same as subtract -1
+ ssei b = truncatei(x);
+ ssei isneg = cast((x < ssef(0.0f)).m128);
+ return b + isneg; // unsaturated add 0xffffffff is the same as subtract -1
}
#endif
ccl_device uint hash(uint kx, uint ky, uint kz)
{
- // define some handy macros
-#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
-#define final(a,b,c) \
-{ \
- c ^= b; c -= rot(b,14); \
- a ^= c; a -= rot(c,11); \
- b ^= a; b -= rot(a,25); \
- c ^= b; c -= rot(b,16); \
- a ^= c; a -= rot(c,4); \
- b ^= a; b -= rot(a,14); \
- c ^= b; c -= rot(b,24); \
-}
- // now hash the data!
- uint a, b, c, len = 3;
- a = b = c = 0xdeadbeef + (len << 2) + 13;
-
- c += kz;
- b += ky;
- a += kx;
- final(a, b, c);
-
- return c;
- // macros not needed anymore
+ // define some handy macros
+#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+#define final(a, b, c) \
+ { \
+ c ^= b; \
+ c -= rot(b, 14); \
+ a ^= c; \
+ a -= rot(c, 11); \
+ b ^= a; \
+ b -= rot(a, 25); \
+ c ^= b; \
+ c -= rot(b, 16); \
+ a ^= c; \
+ a -= rot(c, 4); \
+ b ^= a; \
+ b -= rot(a, 14); \
+ c ^= b; \
+ c -= rot(b, 24); \
+ }
+ // now hash the data!
+ uint a, b, c, len = 3;
+ a = b = c = 0xdeadbeef + (len << 2) + 13;
+
+ c += kz;
+ b += ky;
+ a += kx;
+ final(a, b, c);
+
+ return c;
+ // macros not needed anymore
#undef rot
#undef final
}
#ifdef __KERNEL_SSE2__
-ccl_device_inline ssei hash_sse(const ssei& kx, const ssei& ky, const ssei& kz)
+ccl_device_inline ssei hash_sse(const ssei &kx, const ssei &ky, const ssei &kz)
{
-# define rot(x,k) (((x)<<(k)) | (srl(x, 32-(k))))
-# define xor_rot(a, b, c) do {a = a^b; a = a - rot(b, c);} while(0)
-
- uint len = 3;
- ssei magic = ssei(0xdeadbeef + (len << 2) + 13);
- ssei a = magic + kx;
- ssei b = magic + ky;
- ssei c = magic + kz;
-
- xor_rot(c, b, 14);
- xor_rot(a, c, 11);
- xor_rot(b, a, 25);
- xor_rot(c, b, 16);
- xor_rot(a, c, 4);
- xor_rot(b, a, 14);
- xor_rot(c, b, 24);
-
- return c;
+# define rot(x, k) (((x) << (k)) | (srl(x, 32 - (k))))
+# define xor_rot(a, b, c) \
+ do { \
+ a = a ^ b; \
+ a = a - rot(b, c); \
+ } while (0)
+
+ uint len = 3;
+ ssei magic = ssei(0xdeadbeef + (len << 2) + 13);
+ ssei a = magic + kx;
+ ssei b = magic + ky;
+ ssei c = magic + kz;
+
+ xor_rot(c, b, 14);
+ xor_rot(a, c, 11);
+ xor_rot(b, a, 25);
+ xor_rot(c, b, 16);
+ xor_rot(a, c, 4);
+ xor_rot(b, a, 14);
+ xor_rot(c, b, 24);
+
+ return c;
# undef rot
# undef xor_rot
}
#endif
-#if 0 // unused
+#if 0 // unused
ccl_device int imod(int a, int b)
{
- a %= b;
- return a < 0 ? a + b : a;
+ a %= b;
+ return a < 0 ? a + b : a;
}
ccl_device uint phash(int kx, int ky, int kz, int3 p)
{
- return hash(imod(kx, p.x), imod(ky, p.y), imod(kz, p.z));
+ return hash(imod(kx, p.x), imod(ky, p.y), imod(kz, p.z));
}
#endif
#ifndef __KERNEL_SSE2__
-ccl_device float floorfrac(float x, int* i)
+ccl_device float floorfrac(float x, int *i)
{
- *i = quick_floor_to_int(x);
- return x - *i;
+ *i = quick_floor_to_int(x);
+ return x - *i;
}
#else
-ccl_device_inline ssef floorfrac_sse(const ssef& x, ssei *i)
+ccl_device_inline ssef floorfrac_sse(const ssef &x, ssei *i)
{
- *i = quick_floor_sse(x);
- return x - ssef(*i);
+ *i = quick_floor_sse(x);
+ return x - ssef(*i);
}
#endif
#ifndef __KERNEL_SSE2__
ccl_device float fade(float t)
{
- return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
+ return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
}
#else
ccl_device_inline ssef fade_sse(const ssef *t)
{
- ssef a = madd(*t, ssef(6.0f), ssef(-15.0f));
- ssef b = madd(*t, a, ssef(10.0f));
- return ((*t) * (*t)) * ((*t) * b);
+ ssef a = madd(*t, ssef(6.0f), ssef(-15.0f));
+ ssef b = madd(*t, a, ssef(10.0f));
+ return ((*t) * (*t)) * ((*t) * b);
}
#endif
#ifndef __KERNEL_SSE2__
ccl_device float nerp(float t, float a, float b)
{
- return (1.0f - t) * a + t * b;
+ return (1.0f - t) * a + t * b;
}
#else
-ccl_device_inline ssef nerp_sse(const ssef& t, const ssef& a, const ssef& b)
+ccl_device_inline ssef nerp_sse(const ssef &t, const ssef &a, const ssef &b)
{
- ssef x1 = (ssef(1.0f) - t) * a;
- return madd(t, b, x1);
+ ssef x1 = (ssef(1.0f) - t) * a;
+ return madd(t, b, x1);
}
#endif
#ifndef __KERNEL_SSE2__
ccl_device float grad(int hash, float x, float y, float z)
{
- // use vectors pointing to the edges of the cube
- int h = hash & 15;
- float u = h<8 ? x : y;
- float vt = ((h == 12) | (h == 14)) ? x : z;
- float v = h < 4 ? y : vt;
- return ((h&1) ? -u : u) + ((h&2) ? -v : v);
+ // use vectors pointing to the edges of the cube
+ int h = hash & 15;
+ float u = h < 8 ? x : y;
+ float vt = ((h == 12) | (h == 14)) ? x : z;
+ float v = h < 4 ? y : vt;
+ return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
}
#else
-ccl_device_inline ssef grad_sse(const ssei& hash, const ssef& x, const ssef& y, const ssef& z)
+ccl_device_inline ssef grad_sse(const ssei &hash, const ssef &x, const ssef &y, const ssef &z)
{
- ssei c1 = ssei(1);
- ssei c2 = ssei(2);
+ ssei c1 = ssei(1);
+ ssei c2 = ssei(2);
- ssei h = hash & ssei(15); // h = hash & 15
+ ssei h = hash & ssei(15); // h = hash & 15
- sseb case_ux = h < ssei(8); // 0xffffffff if h < 8 else 0
+ sseb case_ux = h < ssei(8); // 0xffffffff if h < 8 else 0
- ssef u = select(case_ux, x, y); // u = h<8 ? x : y
+ ssef u = select(case_ux, x, y); // u = h<8 ? x : y
- sseb case_vy = h < ssei(4); // 0xffffffff if h < 4 else 0
+ sseb case_vy = h < ssei(4); // 0xffffffff if h < 4 else 0
- sseb case_h12 = h == ssei(12); // 0xffffffff if h == 12 else 0
- sseb case_h14 = h == ssei(14); // 0xffffffff if h == 14 else 0
+ sseb case_h12 = h == ssei(12); // 0xffffffff if h == 12 else 0
+ sseb case_h14 = h == ssei(14); // 0xffffffff if h == 14 else 0
- sseb case_vx = case_h12 | case_h14; // 0xffffffff if h == 12 or h == 14 else 0
+ sseb case_vx = case_h12 | case_h14; // 0xffffffff if h == 12 or h == 14 else 0
- ssef v = select(case_vy, y, select(case_vx, x, z)); // v = h<4 ? y : h == 12 || h == 14 ? x : z
+ ssef v = select(case_vy, y, select(case_vx, x, z)); // v = h<4 ? y : h == 12 || h == 14 ? x : z
- ssei case_uneg = (h & c1) << 31; // 1<<31 if h&1 else 0
- ssef case_uneg_mask = cast(case_uneg); // -0.0 if h&1 else +0.0
- ssef ru = u ^ case_uneg_mask; // -u if h&1 else u (copy float sign)
+ ssei case_uneg = (h & c1) << 31; // 1<<31 if h&1 else 0
+ ssef case_uneg_mask = cast(case_uneg); // -0.0 if h&1 else +0.0
+ ssef ru = u ^ case_uneg_mask; // -u if h&1 else u (copy float sign)
- ssei case_vneg = (h & c2) << 30; // 2<<30 if h&2 else 0
- ssef case_vneg_mask = cast(case_vneg); // -0.0 if h&2 else +0.0
- ssef rv = v ^ case_vneg_mask; // -v if h&2 else v (copy float sign)
+ ssei case_vneg = (h & c2) << 30; // 2<<30 if h&2 else 0
+ ssef case_vneg_mask = cast(case_vneg); // -0.0 if h&2 else +0.0
+ ssef rv = v ^ case_vneg_mask; // -v if h&2 else v (copy float sign)
- ssef r = ru + rv; // ((h&1) ? -u : u) + ((h&2) ? -v : v)
- return r;
+ ssef r = ru + rv; // ((h&1) ? -u : u) + ((h&2) ? -v : v)
+ return r;
}
#endif
#ifndef __KERNEL_SSE2__
ccl_device float scale3(float result)
{
- return 0.9820f * result;
+ return 0.9820f * result;
}
#else
-ccl_device_inline ssef scale3_sse(const ssef& result)
+ccl_device_inline ssef scale3_sse(const ssef &result)
{
- return ssef(0.9820f) * result;
+ return ssef(0.9820f) * result;
}
#endif
#ifndef __KERNEL_SSE2__
ccl_device_noinline float perlin(float x, float y, float z)
{
- int X; float fx = floorfrac(x, &X);
- int Y; float fy = floorfrac(y, &Y);
- int Z; float fz = floorfrac(z, &Z);
-
- float u = fade(fx);
- float v = fade(fy);
- float w = fade(fz);
-
- float result;
-
- result = nerp (w, nerp (v, nerp (u, grad (hash (X , Y , Z ), fx , fy , fz ),
- grad (hash (X+1, Y , Z ), fx-1.0f, fy , fz )),
- nerp (u, grad (hash (X , Y+1, Z ), fx , fy-1.0f, fz ),
- grad (hash (X+1, Y+1, Z ), fx-1.0f, fy-1.0f, fz ))),
- nerp (v, nerp (u, grad (hash (X , Y , Z+1), fx , fy , fz-1.0f ),
- grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )),
- nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ),
- grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f ))));
- float r = scale3(result);
-
- /* can happen for big coordinates, things even out to 0.0 then anyway */
- return (isfinite(r))? r: 0.0f;
+ int X;
+ float fx = floorfrac(x, &X);
+ int Y;
+ float fy = floorfrac(y, &Y);
+ int Z;
+ float fz = floorfrac(z, &Z);
+
+ float u = fade(fx);
+ float v = fade(fy);
+ float w = fade(fz);
+
+ float result;
+
+ result = nerp(
+ w,
+ nerp(v,
+ nerp(u, grad(hash(X, Y, Z), fx, fy, fz), grad(hash(X + 1, Y, Z), fx - 1.0f, fy, fz)),
+ nerp(u,
+ grad(hash(X, Y + 1, Z), fx, fy - 1.0f, fz),
+ grad(hash(X + 1, Y + 1, Z), fx - 1.0f, fy - 1.0f, fz))),
+ nerp(v,
+ nerp(u,
+ grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0f),
+ grad(hash(X + 1, Y, Z + 1), fx - 1.0f, fy, fz - 1.0f)),
+ nerp(u,
+ grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0f, fz - 1.0f),
+ grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0f, fy - 1.0f, fz - 1.0f))));
+ float r = scale3(result);
+
+ /* can happen for big coordinates, things even out to 0.0 then anyway */
+ return (isfinite(r)) ? r : 0.0f;
}
#else
ccl_device_noinline float perlin(float x, float y, float z)
{
- ssef xyz = ssef(x, y, z, 0.0f);
- ssei XYZ;
+ ssef xyz = ssef(x, y, z, 0.0f);
+ ssei XYZ;
- ssef fxyz = floorfrac_sse(xyz, &XYZ);
+ ssef fxyz = floorfrac_sse(xyz, &XYZ);
- ssef uvw = fade_sse(&fxyz);
- ssef u = shuffle<0>(uvw), v = shuffle<1>(uvw), w = shuffle<2>(uvw);
+ ssef uvw = fade_sse(&fxyz);
+ ssef u = shuffle<0>(uvw), v = shuffle<1>(uvw), w = shuffle<2>(uvw);
- ssei XYZ_ofc = XYZ + ssei(1);
- ssei vdy = shuffle<1, 1, 1, 1>(XYZ, XYZ_ofc); // +0, +0, +1, +1
- ssei vdz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ_ofc)); // +0, +1, +0, +1
+ ssei XYZ_ofc = XYZ + ssei(1);
+ ssei vdy = shuffle<1, 1, 1, 1>(XYZ, XYZ_ofc); // +0, +0, +1, +1
+ ssei vdz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ_ofc)); // +0, +1, +0, +1
- ssei h1 = hash_sse(shuffle<0>(XYZ), vdy, vdz); // hash directions 000, 001, 010, 011
- ssei h2 = hash_sse(shuffle<0>(XYZ_ofc), vdy, vdz); // hash directions 100, 101, 110, 111
+ ssei h1 = hash_sse(shuffle<0>(XYZ), vdy, vdz); // hash directions 000, 001, 010, 011
+ ssei h2 = hash_sse(shuffle<0>(XYZ_ofc), vdy, vdz); // hash directions 100, 101, 110, 111
- ssef fxyz_ofc = fxyz - ssef(1.0f);
- ssef vfy = shuffle<1, 1, 1, 1>(fxyz, fxyz_ofc);
- ssef vfz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz_ofc));
+ ssef fxyz_ofc = fxyz - ssef(1.0f);
+ ssef vfy = shuffle<1, 1, 1, 1>(fxyz, fxyz_ofc);
+ ssef vfz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz_ofc));
- ssef g1 = grad_sse(h1, shuffle<0>(fxyz), vfy, vfz);
- ssef g2 = grad_sse(h2, shuffle<0>(fxyz_ofc), vfy, vfz);
- ssef n1 = nerp_sse(u, g1, g2);
+ ssef g1 = grad_sse(h1, shuffle<0>(fxyz), vfy, vfz);
+ ssef g2 = grad_sse(h2, shuffle<0>(fxyz_ofc), vfy, vfz);
+ ssef n1 = nerp_sse(u, g1, g2);
- ssef n1_half = shuffle<2, 3, 2, 3>(n1); // extract 2 floats to a separate vector
- ssef n2 = nerp_sse(v, n1, n1_half); // process nerp([a, b, _, _], [c, d, _, _]) -> [a', b', _, _]
+ ssef n1_half = shuffle<2, 3, 2, 3>(n1); // extract 2 floats to a separate vector
+ ssef n2 = nerp_sse(
+ v, n1, n1_half); // process nerp([a, b, _, _], [c, d, _, _]) -> [a', b', _, _]
- ssef n2_second = shuffle<1>(n2); // extract b to a separate vector
- ssef result = nerp_sse(w, n2, n2_second); // process nerp([a', _, _, _], [b', _, _, _]) -> [a'', _, _, _]
+ ssef n2_second = shuffle<1>(n2); // extract b to a separate vector
+ ssef result = nerp_sse(
+ w, n2, n2_second); // process nerp([a', _, _, _], [b', _, _, _]) -> [a'', _, _, _]
- ssef r = scale3_sse(result);
+ ssef r = scale3_sse(result);
- ssef infmask = cast(ssei(0x7f800000));
- ssef rinfmask = ((r & infmask) == infmask).m128; // 0xffffffff if r is inf/-inf/nan else 0
- ssef rfinite = andnot(rinfmask, r); // 0 if r is inf/-inf/nan else r
- return extract<0>(rfinite);
+ ssef infmask = cast(ssei(0x7f800000));
+ ssef rinfmask = ((r & infmask) == infmask).m128; // 0xffffffff if r is inf/-inf/nan else 0
+ ssef rfinite = andnot(rinfmask, r); // 0 if r is inf/-inf/nan else r
+ return extract<0>(rfinite);
}
#endif
/* perlin noise in range 0..1 */
ccl_device float noise(float3 p)
{
- float r = perlin(p.x, p.y, p.z);
- return 0.5f*r + 0.5f;
+ float r = perlin(p.x, p.y, p.z);
+ return 0.5f * r + 0.5f;
}
/* perlin noise in range -1..1 */
ccl_device float snoise(float3 p)
{
- return perlin(p.x, p.y, p.z);
+ return perlin(p.x, p.y, p.z);
}
/* cell noise */
ccl_device float cellnoise(float3 p)
{
- int3 ip = quick_floor_to_int3(p);
- return bits_to_01(hash(ip.x, ip.y, ip.z));
+ int3 ip = quick_floor_to_int3(p);
+ return bits_to_01(hash(ip.x, ip.y, ip.z));
}
ccl_device float3 cellnoise3(float3 p)
{
- int3 ip = quick_floor_to_int3(p);
+ int3 ip = quick_floor_to_int3(p);
#ifndef __KERNEL_SSE__
- float r = bits_to_01(hash(ip.x, ip.y, ip.z));
- float g = bits_to_01(hash(ip.y, ip.x, ip.z));
- float b = bits_to_01(hash(ip.y, ip.z, ip.x));
- return make_float3(r, g, b);
+ float r = bits_to_01(hash(ip.x, ip.y, ip.z));
+ float g = bits_to_01(hash(ip.y, ip.x, ip.z));
+ float b = bits_to_01(hash(ip.y, ip.z, ip.x));
+ return make_float3(r, g, b);
#else
- ssei ip_yxz = shuffle<1, 0, 2, 3>(ssei(ip.m128));
- ssei ip_xyy = shuffle<0, 1, 1, 3>(ssei(ip.m128));
- ssei ip_zzx = shuffle<2, 2, 0, 3>(ssei(ip.m128));
- ssei bits = hash_sse(ip_xyy, ip_yxz, ip_zzx);
- return float3(uint32_to_float(bits) * ssef(1.0f/(float)0xFFFFFFFF));
+ ssei ip_yxz = shuffle<1, 0, 2, 3>(ssei(ip.m128));
+ ssei ip_xyy = shuffle<0, 1, 1, 3>(ssei(ip.m128));
+ ssei ip_zzx = shuffle<2, 2, 0, 3>(ssei(ip.m128));
+ ssei bits = hash_sse(ip_xyy, ip_yxz, ip_zzx);
+ return float3(uint32_to_float(bits) * ssef(1.0f / (float)0xFFFFFFFF));
#endif
}
diff --git a/intern/cycles/kernel/svm/svm_noisetex.h b/intern/cycles/kernel/svm/svm_noisetex.h
index c02940f96d6..3324e86fcd8 100644
--- a/intern/cycles/kernel/svm/svm_noisetex.h
+++ b/intern/cycles/kernel/svm/svm_noisetex.h
@@ -18,42 +18,43 @@ CCL_NAMESPACE_BEGIN
/* Noise */
-ccl_device void svm_node_tex_noise(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_tex_noise(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset;
+ uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset;
- decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
- decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
+ decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
+ decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
- uint4 node2 = read_node(kg, offset);
+ uint4 node2 = read_node(kg, offset);
- float scale = stack_load_float_default(stack, scale_offset, node2.x);
- float detail = stack_load_float_default(stack, detail_offset, node2.y);
- float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
- float3 p = stack_load_float3(stack, co_offset) * scale;
- int hard = 0;
+ float scale = stack_load_float_default(stack, scale_offset, node2.x);
+ float detail = stack_load_float_default(stack, detail_offset, node2.y);
+ float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
+ float3 p = stack_load_float3(stack, co_offset) * scale;
+ int hard = 0;
- if(distortion != 0.0f) {
- float3 r, offset = make_float3(13.5f, 13.5f, 13.5f);
+ if (distortion != 0.0f) {
+ float3 r, offset = make_float3(13.5f, 13.5f, 13.5f);
- r.x = noise(p + offset) * distortion;
- r.y = noise(p) * distortion;
- r.z = noise(p - offset) * distortion;
+ r.x = noise(p + offset) * distortion;
+ r.y = noise(p) * distortion;
+ r.z = noise(p - offset) * distortion;
- p += r;
- }
+ p += r;
+ }
- float f = noise_turbulence(p, detail, hard);
+ float f = noise_turbulence(p, detail, hard);
- if(stack_valid(fac_offset)) {
- stack_store_float(stack, fac_offset, f);
- }
- if(stack_valid(color_offset)) {
- float3 color = make_float3(f,
- noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard),
- noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard));
- stack_store_float3(stack, color_offset, color);
- }
+ if (stack_valid(fac_offset)) {
+ stack_store_float(stack, fac_offset, f);
+ }
+ if (stack_valid(color_offset)) {
+ float3 color = make_float3(f,
+ noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard),
+ noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard));
+ stack_store_float3(stack, color_offset, color);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_normal.h b/intern/cycles/kernel/svm/svm_normal.h
index fe46d79fe15..4cd3eab0ed2 100644
--- a/intern/cycles/kernel/svm/svm_normal.h
+++ b/intern/cycles/kernel/svm/svm_normal.h
@@ -16,23 +16,29 @@
CCL_NAMESPACE_BEGIN
-ccl_device void svm_node_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_normal_offset, uint out_normal_offset, uint out_dot_offset, int *offset)
+ccl_device void svm_node_normal(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint in_normal_offset,
+ uint out_normal_offset,
+ uint out_dot_offset,
+ int *offset)
{
- /* read extra data */
- uint4 node1 = read_node(kg, offset);
- float3 normal = stack_load_float3(stack, in_normal_offset);
+ /* read extra data */
+ uint4 node1 = read_node(kg, offset);
+ float3 normal = stack_load_float3(stack, in_normal_offset);
- float3 direction;
- direction.x = __int_as_float(node1.x);
- direction.y = __int_as_float(node1.y);
- direction.z = __int_as_float(node1.z);
- direction = normalize(direction);
+ float3 direction;
+ direction.x = __int_as_float(node1.x);
+ direction.y = __int_as_float(node1.y);
+ direction.z = __int_as_float(node1.z);
+ direction = normalize(direction);
- if(stack_valid(out_normal_offset))
- stack_store_float3(stack, out_normal_offset, direction);
+ if (stack_valid(out_normal_offset))
+ stack_store_float3(stack, out_normal_offset, direction);
- if(stack_valid(out_dot_offset))
- stack_store_float(stack, out_dot_offset, dot(direction, normalize(normal)));
+ if (stack_valid(out_dot_offset))
+ stack_store_float(stack, out_dot_offset, dot(direction, normalize(normal)));
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h
index 6f39391057e..6084ee35a1f 100644
--- a/intern/cycles/kernel/svm/svm_ramp.h
+++ b/intern/cycles/kernel/svm/svm_ramp.h
@@ -21,91 +21,84 @@ CCL_NAMESPACE_BEGIN
/* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */
-ccl_device_inline float4 rgb_ramp_lookup(KernelGlobals *kg,
- int offset,
- float f,
- bool interpolate,
- bool extrapolate,
- int table_size)
+ccl_device_inline float4 rgb_ramp_lookup(
+ KernelGlobals *kg, int offset, float f, bool interpolate, bool extrapolate, int table_size)
{
- if((f < 0.0f || f > 1.0f) && extrapolate) {
- float4 t0, dy;
- if(f < 0.0f) {
- t0 = fetch_node_float(kg, offset);
- dy = t0 - fetch_node_float(kg, offset + 1);
- f = -f;
- }
- else {
- t0 = fetch_node_float(kg, offset + table_size - 1);
- dy = t0 - fetch_node_float(kg, offset + table_size - 2);
- f = f - 1.0f;
- }
- return t0 + dy * f * (table_size-1);
- }
-
- f = saturate(f)*(table_size-1);
-
- /* clamp int as well in case of NaN */
- int i = clamp(float_to_int(f), 0, table_size-1);
- float t = f - (float)i;
-
- float4 a = fetch_node_float(kg, offset+i);
-
- if(interpolate && t > 0.0f)
- a = (1.0f - t)*a + t*fetch_node_float(kg, offset+i+1);
-
- return a;
+ if ((f < 0.0f || f > 1.0f) && extrapolate) {
+ float4 t0, dy;
+ if (f < 0.0f) {
+ t0 = fetch_node_float(kg, offset);
+ dy = t0 - fetch_node_float(kg, offset + 1);
+ f = -f;
+ }
+ else {
+ t0 = fetch_node_float(kg, offset + table_size - 1);
+ dy = t0 - fetch_node_float(kg, offset + table_size - 2);
+ f = f - 1.0f;
+ }
+ return t0 + dy * f * (table_size - 1);
+ }
+
+ f = saturate(f) * (table_size - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = clamp(float_to_int(f), 0, table_size - 1);
+ float t = f - (float)i;
+
+ float4 a = fetch_node_float(kg, offset + i);
+
+ if (interpolate && t > 0.0f)
+ a = (1.0f - t) * a + t * fetch_node_float(kg, offset + i + 1);
+
+ return a;
}
-ccl_device void svm_node_rgb_ramp(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_rgb_ramp(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint fac_offset, color_offset, alpha_offset;
- uint interpolate = node.z;
+ uint fac_offset, color_offset, alpha_offset;
+ uint interpolate = node.z;
- decode_node_uchar4(node.y, &fac_offset, &color_offset, &alpha_offset, NULL);
+ decode_node_uchar4(node.y, &fac_offset, &color_offset, &alpha_offset, NULL);
- uint table_size = read_node(kg, offset).x;
+ uint table_size = read_node(kg, offset).x;
- float fac = stack_load_float(stack, fac_offset);
- float4 color = rgb_ramp_lookup(kg, *offset, fac, interpolate, false, table_size);
+ float fac = stack_load_float(stack, fac_offset);
+ float4 color = rgb_ramp_lookup(kg, *offset, fac, interpolate, false, table_size);
- if(stack_valid(color_offset))
- stack_store_float3(stack, color_offset, float4_to_float3(color));
- if(stack_valid(alpha_offset))
- stack_store_float(stack, alpha_offset, color.w);
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, float4_to_float3(color));
+ if (stack_valid(alpha_offset))
+ stack_store_float(stack, alpha_offset, color.w);
- *offset += table_size;
+ *offset += table_size;
}
-ccl_device void svm_node_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_curves(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint fac_offset, color_offset, out_offset;
- decode_node_uchar4(node.y,
- &fac_offset,
- &color_offset,
- &out_offset,
- NULL);
+ uint fac_offset, color_offset, out_offset;
+ decode_node_uchar4(node.y, &fac_offset, &color_offset, &out_offset, NULL);
- uint table_size = read_node(kg, offset).x;
+ uint table_size = read_node(kg, offset).x;
- float fac = stack_load_float(stack, fac_offset);
- float3 color = stack_load_float3(stack, color_offset);
+ float fac = stack_load_float(stack, fac_offset);
+ float3 color = stack_load_float3(stack, color_offset);
- const float min_x = __int_as_float(node.z),
- max_x = __int_as_float(node.w);
- const float range_x = max_x - min_x;
- const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x;
+ const float min_x = __int_as_float(node.z), max_x = __int_as_float(node.w);
+ const float range_x = max_x - min_x;
+ const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x;
- float r = rgb_ramp_lookup(kg, *offset, relpos.x, true, true, table_size).x;
- float g = rgb_ramp_lookup(kg, *offset, relpos.y, true, true, table_size).y;
- float b = rgb_ramp_lookup(kg, *offset, relpos.z, true, true, table_size).z;
+ float r = rgb_ramp_lookup(kg, *offset, relpos.x, true, true, table_size).x;
+ float g = rgb_ramp_lookup(kg, *offset, relpos.y, true, true, table_size).y;
+ float b = rgb_ramp_lookup(kg, *offset, relpos.z, true, true, table_size).z;
- color = (1.0f - fac)*color + fac*make_float3(r, g, b);
- stack_store_float3(stack, out_offset, color);
+ color = (1.0f - fac) * color + fac * make_float3(r, g, b);
+ stack_store_float3(stack, out_offset, color);
- *offset += table_size;
+ *offset += table_size;
}
CCL_NAMESPACE_END
-#endif /* __SVM_RAMP_H__ */
+#endif /* __SVM_RAMP_H__ */
diff --git a/intern/cycles/kernel/svm/svm_ramp_util.h b/intern/cycles/kernel/svm/svm_ramp_util.h
index 847108ff1c2..202596c1fe3 100644
--- a/intern/cycles/kernel/svm/svm_ramp_util.h
+++ b/intern/cycles/kernel/svm/svm_ramp_util.h
@@ -21,78 +21,70 @@ CCL_NAMESPACE_BEGIN
/* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */
-ccl_device_inline float3 rgb_ramp_lookup(const float3 *ramp,
- float f,
- bool interpolate,
- bool extrapolate,
- int table_size)
+ccl_device_inline float3
+rgb_ramp_lookup(const float3 *ramp, float f, bool interpolate, bool extrapolate, int table_size)
{
- if((f < 0.0f || f > 1.0f) && extrapolate) {
- float3 t0, dy;
- if(f < 0.0f) {
- t0 = ramp[0];
- dy = t0 - ramp[1],
- f = -f;
- }
- else {
- t0 = ramp[table_size - 1];
- dy = t0 - ramp[table_size - 2];
- f = f - 1.0f;
- }
- return t0 + dy * f * (table_size - 1);
- }
-
- f = clamp(f, 0.0f, 1.0f) * (table_size - 1);
-
- /* clamp int as well in case of NaN */
- int i = clamp(float_to_int(f), 0, table_size-1);
- float t = f - (float)i;
-
- float3 result = ramp[i];
-
- if(interpolate && t > 0.0f) {
- result = (1.0f - t) * result + t * ramp[i + 1];
- }
-
- return result;
+ if ((f < 0.0f || f > 1.0f) && extrapolate) {
+ float3 t0, dy;
+ if (f < 0.0f) {
+ t0 = ramp[0];
+ dy = t0 - ramp[1], f = -f;
+ }
+ else {
+ t0 = ramp[table_size - 1];
+ dy = t0 - ramp[table_size - 2];
+ f = f - 1.0f;
+ }
+ return t0 + dy * f * (table_size - 1);
+ }
+
+ f = clamp(f, 0.0f, 1.0f) * (table_size - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = clamp(float_to_int(f), 0, table_size - 1);
+ float t = f - (float)i;
+
+ float3 result = ramp[i];
+
+ if (interpolate && t > 0.0f) {
+ result = (1.0f - t) * result + t * ramp[i + 1];
+ }
+
+ return result;
}
-ccl_device float float_ramp_lookup(const float *ramp,
- float f,
- bool interpolate,
- bool extrapolate,
- int table_size)
+ccl_device float float_ramp_lookup(
+ const float *ramp, float f, bool interpolate, bool extrapolate, int table_size)
{
- if((f < 0.0f || f > 1.0f) && extrapolate) {
- float t0, dy;
- if(f < 0.0f) {
- t0 = ramp[0];
- dy = t0 - ramp[1],
- f = -f;
- }
- else {
- t0 = ramp[table_size - 1];
- dy = t0 - ramp[table_size - 2];
- f = f - 1.0f;
- }
- return t0 + dy * f * (table_size - 1);
- }
-
- f = clamp(f, 0.0f, 1.0f) * (table_size - 1);
-
- /* clamp int as well in case of NaN */
- int i = clamp(float_to_int(f), 0, table_size-1);
- float t = f - (float)i;
-
- float result = ramp[i];
-
- if(interpolate && t > 0.0f) {
- result = (1.0f - t) * result + t * ramp[i + 1];
- }
-
- return result;
+ if ((f < 0.0f || f > 1.0f) && extrapolate) {
+ float t0, dy;
+ if (f < 0.0f) {
+ t0 = ramp[0];
+ dy = t0 - ramp[1], f = -f;
+ }
+ else {
+ t0 = ramp[table_size - 1];
+ dy = t0 - ramp[table_size - 2];
+ f = f - 1.0f;
+ }
+ return t0 + dy * f * (table_size - 1);
+ }
+
+ f = clamp(f, 0.0f, 1.0f) * (table_size - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = clamp(float_to_int(f), 0, table_size - 1);
+ float t = f - (float)i;
+
+ float result = ramp[i];
+
+ if (interpolate && t > 0.0f) {
+ result = (1.0f - t) * result + t * ramp[i + 1];
+ }
+
+ return result;
}
CCL_NAMESPACE_END
-#endif /* __SVM_RAMP_UTIL_H__ */
+#endif /* __SVM_RAMP_UTIL_H__ */
diff --git a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
index 1096aed2d97..f501252062e 100644
--- a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
+++ b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
@@ -16,38 +16,50 @@
CCL_NAMESPACE_BEGIN
-ccl_device void svm_node_combine_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint hue_in, uint saturation_in, uint value_in, int *offset)
+ccl_device void svm_node_combine_hsv(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint hue_in,
+ uint saturation_in,
+ uint value_in,
+ int *offset)
{
- uint4 node1 = read_node(kg, offset);
- uint color_out = node1.y;
+ uint4 node1 = read_node(kg, offset);
+ uint color_out = node1.y;
- float hue = stack_load_float(stack, hue_in);
- float saturation = stack_load_float(stack, saturation_in);
- float value = stack_load_float(stack, value_in);
+ float hue = stack_load_float(stack, hue_in);
+ float saturation = stack_load_float(stack, saturation_in);
+ float value = stack_load_float(stack, value_in);
- /* Combine, and convert back to RGB */
- float3 color = hsv_to_rgb(make_float3(hue, saturation, value));
+ /* Combine, and convert back to RGB */
+ float3 color = hsv_to_rgb(make_float3(hue, saturation, value));
- if(stack_valid(color_out))
- stack_store_float3(stack, color_out, color);
+ if (stack_valid(color_out))
+ stack_store_float3(stack, color_out, color);
}
-ccl_device void svm_node_separate_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint color_in, uint hue_out, uint saturation_out, int *offset)
+ccl_device void svm_node_separate_hsv(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint color_in,
+ uint hue_out,
+ uint saturation_out,
+ int *offset)
{
- uint4 node1 = read_node(kg, offset);
- uint value_out = node1.y;
+ uint4 node1 = read_node(kg, offset);
+ uint value_out = node1.y;
- float3 color = stack_load_float3(stack, color_in);
+ float3 color = stack_load_float3(stack, color_in);
- /* Convert to HSV */
- color = rgb_to_hsv(color);
+ /* Convert to HSV */
+ color = rgb_to_hsv(color);
- if(stack_valid(hue_out))
- stack_store_float(stack, hue_out, color.x);
- if(stack_valid(saturation_out))
- stack_store_float(stack, saturation_out, color.y);
- if(stack_valid(value_out))
- stack_store_float(stack, value_out, color.z);
+ if (stack_valid(hue_out))
+ stack_store_float(stack, hue_out, color.x);
+ if (stack_valid(saturation_out))
+ stack_store_float(stack, saturation_out, color.y);
+ if (stack_valid(value_out))
+ stack_store_float(stack, value_out, color.z);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_sepcomb_vector.h b/intern/cycles/kernel/svm/svm_sepcomb_vector.h
index 0d85c0d6f1d..cbf77f1e640 100644
--- a/intern/cycles/kernel/svm/svm_sepcomb_vector.h
+++ b/intern/cycles/kernel/svm/svm_sepcomb_vector.h
@@ -18,26 +18,28 @@ CCL_NAMESPACE_BEGIN
/* Vector combine / separate, used for the RGB and XYZ nodes */
-ccl_device void svm_node_combine_vector(ShaderData *sd, float *stack, uint in_offset, uint vector_index, uint out_offset)
+ccl_device void svm_node_combine_vector(
+ ShaderData *sd, float *stack, uint in_offset, uint vector_index, uint out_offset)
{
- float vector = stack_load_float(stack, in_offset);
+ float vector = stack_load_float(stack, in_offset);
- if(stack_valid(out_offset))
- stack_store_float(stack, out_offset+vector_index, vector);
+ if (stack_valid(out_offset))
+ stack_store_float(stack, out_offset + vector_index, vector);
}
-ccl_device void svm_node_separate_vector(ShaderData *sd, float *stack, uint ivector_offset, uint vector_index, uint out_offset)
+ccl_device void svm_node_separate_vector(
+ ShaderData *sd, float *stack, uint ivector_offset, uint vector_index, uint out_offset)
{
- float3 vector = stack_load_float3(stack, ivector_offset);
+ float3 vector = stack_load_float3(stack, ivector_offset);
- if(stack_valid(out_offset)) {
- if(vector_index == 0)
- stack_store_float(stack, out_offset, vector.x);
- else if(vector_index == 1)
- stack_store_float(stack, out_offset, vector.y);
- else
- stack_store_float(stack, out_offset, vector.z);
- }
+ if (stack_valid(out_offset)) {
+ if (vector_index == 0)
+ stack_store_float(stack, out_offset, vector.x);
+ else if (vector_index == 1)
+ stack_store_float(stack, out_offset, vector.y);
+ else
+ stack_store_float(stack, out_offset, vector.z);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h
index 092f6e045d6..50fe0c8232f 100644
--- a/intern/cycles/kernel/svm/svm_sky.h
+++ b/intern/cycles/kernel/svm/svm_sky.h
@@ -20,8 +20,8 @@ CCL_NAMESPACE_BEGIN
ccl_device float sky_angle_between(float thetav, float phiv, float theta, float phi)
{
- float cospsi = sinf(thetav)*sinf(theta)*cosf(phi - phiv) + cosf(thetav)*cosf(theta);
- return safe_acosf(cospsi);
+ float cospsi = sinf(thetav) * sinf(theta) * cosf(phi - phiv) + cosf(thetav) * cosf(theta);
+ return safe_acosf(cospsi);
}
/*
@@ -30,36 +30,43 @@ ccl_device float sky_angle_between(float thetav, float phiv, float theta, float
*/
ccl_device float sky_perez_function(float *lam, float theta, float gamma)
{
- float ctheta = cosf(theta);
- float cgamma = cosf(gamma);
+ float ctheta = cosf(theta);
+ float cgamma = cosf(gamma);
- return (1.0f + lam[0]*expf(lam[1]/ctheta)) * (1.0f + lam[2]*expf(lam[3]*gamma) + lam[4]*cgamma*cgamma);
+ return (1.0f + lam[0] * expf(lam[1] / ctheta)) *
+ (1.0f + lam[2] * expf(lam[3] * gamma) + lam[4] * cgamma * cgamma);
}
-ccl_device float3 sky_radiance_old(KernelGlobals *kg, float3 dir,
- float sunphi, float suntheta,
- float radiance_x, float radiance_y, float radiance_z,
- float *config_x, float *config_y, float *config_z)
+ccl_device float3 sky_radiance_old(KernelGlobals *kg,
+ float3 dir,
+ float sunphi,
+ float suntheta,
+ float radiance_x,
+ float radiance_y,
+ float radiance_z,
+ float *config_x,
+ float *config_y,
+ float *config_z)
{
- /* convert vector to spherical coordinates */
- float2 spherical = direction_to_spherical(dir);
- float theta = spherical.x;
- float phi = spherical.y;
+ /* convert vector to spherical coordinates */
+ float2 spherical = direction_to_spherical(dir);
+ float theta = spherical.x;
+ float phi = spherical.y;
- /* angle between sun direction and dir */
- float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
- /* clamp theta to horizon */
- theta = min(theta, M_PI_2_F - 0.001f);
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2_F - 0.001f);
- /* compute xyY color space values */
- float x = radiance_y * sky_perez_function(config_y, theta, gamma);
- float y = radiance_z * sky_perez_function(config_z, theta, gamma);
- float Y = radiance_x * sky_perez_function(config_x, theta, gamma);
+ /* compute xyY color space values */
+ float x = radiance_y * sky_perez_function(config_y, theta, gamma);
+ float y = radiance_z * sky_perez_function(config_z, theta, gamma);
+ float Y = radiance_x * sky_perez_function(config_x, theta, gamma);
- /* convert to RGB */
- float3 xyz = xyY_to_xyz(x, y, Y);
- return xyz_to_rgb(kg, xyz);
+ /* convert to RGB */
+ float3 xyz = xyY_to_xyz(x, y, Y);
+ return xyz_to_rgb(kg, xyz);
}
/*
@@ -68,118 +75,142 @@ ccl_device float3 sky_radiance_old(KernelGlobals *kg, float3 dir,
*/
ccl_device float sky_radiance_internal(float *configuration, float theta, float gamma)
{
- float ctheta = cosf(theta);
- float cgamma = cosf(gamma);
-
- float expM = expf(configuration[4] * gamma);
- float rayM = cgamma * cgamma;
- float mieM = (1.0f + rayM) / powf((1.0f + configuration[8]*configuration[8] - 2.0f*configuration[8]*cgamma), 1.5f);
- float zenith = sqrtf(ctheta);
-
- return (1.0f + configuration[0] * expf(configuration[1] / (ctheta + 0.01f))) *
- (configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith);
+ float ctheta = cosf(theta);
+ float cgamma = cosf(gamma);
+
+ float expM = expf(configuration[4] * gamma);
+ float rayM = cgamma * cgamma;
+ float mieM = (1.0f + rayM) / powf((1.0f + configuration[8] * configuration[8] -
+ 2.0f * configuration[8] * cgamma),
+ 1.5f);
+ float zenith = sqrtf(ctheta);
+
+ return (1.0f + configuration[0] * expf(configuration[1] / (ctheta + 0.01f))) *
+ (configuration[2] + configuration[3] * expM + configuration[5] * rayM +
+ configuration[6] * mieM + configuration[7] * zenith);
}
-ccl_device float3 sky_radiance_new(KernelGlobals *kg, float3 dir,
- float sunphi, float suntheta,
- float radiance_x, float radiance_y, float radiance_z,
- float *config_x, float *config_y, float *config_z)
+ccl_device float3 sky_radiance_new(KernelGlobals *kg,
+ float3 dir,
+ float sunphi,
+ float suntheta,
+ float radiance_x,
+ float radiance_y,
+ float radiance_z,
+ float *config_x,
+ float *config_y,
+ float *config_z)
{
- /* convert vector to spherical coordinates */
- float2 spherical = direction_to_spherical(dir);
- float theta = spherical.x;
- float phi = spherical.y;
+ /* convert vector to spherical coordinates */
+ float2 spherical = direction_to_spherical(dir);
+ float theta = spherical.x;
+ float phi = spherical.y;
- /* angle between sun direction and dir */
- float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
- /* clamp theta to horizon */
- theta = min(theta, M_PI_2_F - 0.001f);
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2_F - 0.001f);
- /* compute xyz color space values */
- float x = sky_radiance_internal(config_x, theta, gamma) * radiance_x;
- float y = sky_radiance_internal(config_y, theta, gamma) * radiance_y;
- float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z;
+ /* compute xyz color space values */
+ float x = sky_radiance_internal(config_x, theta, gamma) * radiance_x;
+ float y = sky_radiance_internal(config_y, theta, gamma) * radiance_y;
+ float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z;
- /* convert to RGB and adjust strength */
- return xyz_to_rgb(kg, make_float3(x, y, z)) * (M_2PI_F/683);
+ /* convert to RGB and adjust strength */
+ return xyz_to_rgb(kg, make_float3(x, y, z)) * (M_2PI_F / 683);
}
-ccl_device void svm_node_tex_sky(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_tex_sky(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- /* Define variables */
- float sunphi, suntheta, radiance_x, radiance_y, radiance_z;
- float config_x[9], config_y[9], config_z[9];
-
- /* Load data */
- uint dir_offset = node.y;
- uint out_offset = node.z;
- int sky_model = node.w;
-
- float4 data = read_node_float(kg, offset);
- sunphi = data.x;
- suntheta = data.y;
- radiance_x = data.z;
- radiance_y = data.w;
-
- data = read_node_float(kg, offset);
- radiance_z = data.x;
- config_x[0] = data.y;
- config_x[1] = data.z;
- config_x[2] = data.w;
-
- data = read_node_float(kg, offset);
- config_x[3] = data.x;
- config_x[4] = data.y;
- config_x[5] = data.z;
- config_x[6] = data.w;
-
- data = read_node_float(kg, offset);
- config_x[7] = data.x;
- config_x[8] = data.y;
- config_y[0] = data.z;
- config_y[1] = data.w;
-
- data = read_node_float(kg, offset);
- config_y[2] = data.x;
- config_y[3] = data.y;
- config_y[4] = data.z;
- config_y[5] = data.w;
-
- data = read_node_float(kg, offset);
- config_y[6] = data.x;
- config_y[7] = data.y;
- config_y[8] = data.z;
- config_z[0] = data.w;
-
- data = read_node_float(kg, offset);
- config_z[1] = data.x;
- config_z[2] = data.y;
- config_z[3] = data.z;
- config_z[4] = data.w;
-
- data = read_node_float(kg, offset);
- config_z[5] = data.x;
- config_z[6] = data.y;
- config_z[7] = data.z;
- config_z[8] = data.w;
-
- float3 dir = stack_load_float3(stack, dir_offset);
- float3 f;
-
- /* Compute Sky */
- if(sky_model == 0) {
- f = sky_radiance_old(kg, dir, sunphi, suntheta,
- radiance_x, radiance_y, radiance_z,
- config_x, config_y, config_z);
- }
- else {
- f = sky_radiance_new(kg, dir, sunphi, suntheta,
- radiance_x, radiance_y, radiance_z,
- config_x, config_y, config_z);
- }
-
- stack_store_float3(stack, out_offset, f);
+ /* Define variables */
+ float sunphi, suntheta, radiance_x, radiance_y, radiance_z;
+ float config_x[9], config_y[9], config_z[9];
+
+ /* Load data */
+ uint dir_offset = node.y;
+ uint out_offset = node.z;
+ int sky_model = node.w;
+
+ float4 data = read_node_float(kg, offset);
+ sunphi = data.x;
+ suntheta = data.y;
+ radiance_x = data.z;
+ radiance_y = data.w;
+
+ data = read_node_float(kg, offset);
+ radiance_z = data.x;
+ config_x[0] = data.y;
+ config_x[1] = data.z;
+ config_x[2] = data.w;
+
+ data = read_node_float(kg, offset);
+ config_x[3] = data.x;
+ config_x[4] = data.y;
+ config_x[5] = data.z;
+ config_x[6] = data.w;
+
+ data = read_node_float(kg, offset);
+ config_x[7] = data.x;
+ config_x[8] = data.y;
+ config_y[0] = data.z;
+ config_y[1] = data.w;
+
+ data = read_node_float(kg, offset);
+ config_y[2] = data.x;
+ config_y[3] = data.y;
+ config_y[4] = data.z;
+ config_y[5] = data.w;
+
+ data = read_node_float(kg, offset);
+ config_y[6] = data.x;
+ config_y[7] = data.y;
+ config_y[8] = data.z;
+ config_z[0] = data.w;
+
+ data = read_node_float(kg, offset);
+ config_z[1] = data.x;
+ config_z[2] = data.y;
+ config_z[3] = data.z;
+ config_z[4] = data.w;
+
+ data = read_node_float(kg, offset);
+ config_z[5] = data.x;
+ config_z[6] = data.y;
+ config_z[7] = data.z;
+ config_z[8] = data.w;
+
+ float3 dir = stack_load_float3(stack, dir_offset);
+ float3 f;
+
+ /* Compute Sky */
+ if (sky_model == 0) {
+ f = sky_radiance_old(kg,
+ dir,
+ sunphi,
+ suntheta,
+ radiance_x,
+ radiance_y,
+ radiance_z,
+ config_x,
+ config_y,
+ config_z);
+ }
+ else {
+ f = sky_radiance_new(kg,
+ dir,
+ sunphi,
+ suntheta,
+ radiance_x,
+ radiance_y,
+ radiance_z,
+ config_x,
+ config_y,
+ config_z);
+ }
+
+ stack_store_float3(stack, out_offset, f);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index fe61292d0b0..1fb3e20f9e0 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -18,390 +18,381 @@ CCL_NAMESPACE_BEGIN
/* Texture Coordinate Node */
-ccl_device void svm_node_tex_coord(KernelGlobals *kg,
- ShaderData *sd,
- int path_flag,
- float *stack,
- uint4 node,
- int *offset)
+ccl_device void svm_node_tex_coord(
+ KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
{
- float3 data;
- uint type = node.y;
- uint out_offset = node.z;
-
- switch(type) {
- case NODE_TEXCO_OBJECT: {
- data = sd->P;
- if(node.w == 0) {
- if(sd->object != OBJECT_NONE) {
- object_inverse_position_transform(kg, sd, &data);
- }
- }
- else {
- Transform tfm;
- tfm.x = read_node_float(kg, offset);
- tfm.y = read_node_float(kg, offset);
- tfm.z = read_node_float(kg, offset);
- data = transform_point(&tfm, data);
- }
- break;
- }
- case NODE_TEXCO_NORMAL: {
- data = sd->N;
- object_inverse_normal_transform(kg, sd, &data);
- break;
- }
- case NODE_TEXCO_CAMERA: {
- Transform tfm = kernel_data.cam.worldtocamera;
-
- if(sd->object != OBJECT_NONE)
- data = transform_point(&tfm, sd->P);
- else
- data = transform_point(&tfm, sd->P + camera_position(kg));
- break;
- }
- case NODE_TEXCO_WINDOW: {
- if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
- data = camera_world_to_ndc(kg, sd, sd->ray_P);
- else
- data = camera_world_to_ndc(kg, sd, sd->P);
- data.z = 0.0f;
- break;
- }
- case NODE_TEXCO_REFLECTION: {
- if(sd->object != OBJECT_NONE)
- data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
- else
- data = sd->I;
- break;
- }
- case NODE_TEXCO_DUPLI_GENERATED: {
- data = object_dupli_generated(kg, sd->object);
- break;
- }
- case NODE_TEXCO_DUPLI_UV: {
- data = object_dupli_uv(kg, sd->object);
- break;
- }
- case NODE_TEXCO_VOLUME_GENERATED: {
- data = sd->P;
+ float3 data;
+ uint type = node.y;
+ uint out_offset = node.z;
+
+ switch (type) {
+ case NODE_TEXCO_OBJECT: {
+ data = sd->P;
+ if (node.w == 0) {
+ if (sd->object != OBJECT_NONE) {
+ object_inverse_position_transform(kg, sd, &data);
+ }
+ }
+ else {
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
+ data = transform_point(&tfm, data);
+ }
+ break;
+ }
+ case NODE_TEXCO_NORMAL: {
+ data = sd->N;
+ object_inverse_normal_transform(kg, sd, &data);
+ break;
+ }
+ case NODE_TEXCO_CAMERA: {
+ Transform tfm = kernel_data.cam.worldtocamera;
+
+ if (sd->object != OBJECT_NONE)
+ data = transform_point(&tfm, sd->P);
+ else
+ data = transform_point(&tfm, sd->P + camera_position(kg));
+ break;
+ }
+ case NODE_TEXCO_WINDOW: {
+ if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
+ kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
+ data = camera_world_to_ndc(kg, sd, sd->ray_P);
+ else
+ data = camera_world_to_ndc(kg, sd, sd->P);
+ data.z = 0.0f;
+ break;
+ }
+ case NODE_TEXCO_REFLECTION: {
+ if (sd->object != OBJECT_NONE)
+ data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
+ else
+ data = sd->I;
+ break;
+ }
+ case NODE_TEXCO_DUPLI_GENERATED: {
+ data = object_dupli_generated(kg, sd->object);
+ break;
+ }
+ case NODE_TEXCO_DUPLI_UV: {
+ data = object_dupli_uv(kg, sd->object);
+ break;
+ }
+ case NODE_TEXCO_VOLUME_GENERATED: {
+ data = sd->P;
#ifdef __VOLUME__
- if(sd->object != OBJECT_NONE)
- data = volume_normalized_position(kg, sd, data);
+ if (sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
#endif
- break;
- }
- }
+ break;
+ }
+ }
- stack_store_float3(stack, out_offset, data);
+ stack_store_float3(stack, out_offset, data);
}
-ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg,
- ShaderData *sd,
- int path_flag,
- float *stack,
- uint4 node,
- int *offset)
+ccl_device void svm_node_tex_coord_bump_dx(
+ KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
{
#ifdef __RAY_DIFFERENTIALS__
- float3 data;
- uint type = node.y;
- uint out_offset = node.z;
-
- switch(type) {
- case NODE_TEXCO_OBJECT: {
- data = sd->P + sd->dP.dx;
- if(node.w == 0) {
- if(sd->object != OBJECT_NONE) {
- object_inverse_position_transform(kg, sd, &data);
- }
- }
- else {
- Transform tfm;
- tfm.x = read_node_float(kg, offset);
- tfm.y = read_node_float(kg, offset);
- tfm.z = read_node_float(kg, offset);
- data = transform_point(&tfm, data);
- }
- break;
- }
- case NODE_TEXCO_NORMAL: {
- data = sd->N;
- object_inverse_normal_transform(kg, sd, &data);
- break;
- }
- case NODE_TEXCO_CAMERA: {
- Transform tfm = kernel_data.cam.worldtocamera;
-
- if(sd->object != OBJECT_NONE)
- data = transform_point(&tfm, sd->P + sd->dP.dx);
- else
- data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg));
- break;
- }
- case NODE_TEXCO_WINDOW: {
- if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
- data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx);
- else
- data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx);
- data.z = 0.0f;
- break;
- }
- case NODE_TEXCO_REFLECTION: {
- if(sd->object != OBJECT_NONE)
- data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
- else
- data = sd->I;
- break;
- }
- case NODE_TEXCO_DUPLI_GENERATED: {
- data = object_dupli_generated(kg, sd->object);
- break;
- }
- case NODE_TEXCO_DUPLI_UV: {
- data = object_dupli_uv(kg, sd->object);
- break;
- }
- case NODE_TEXCO_VOLUME_GENERATED: {
- data = sd->P + sd->dP.dx;
-
-#ifdef __VOLUME__
- if(sd->object != OBJECT_NONE)
- data = volume_normalized_position(kg, sd, data);
-#endif
- break;
- }
- }
-
- stack_store_float3(stack, out_offset, data);
+ float3 data;
+ uint type = node.y;
+ uint out_offset = node.z;
+
+ switch (type) {
+ case NODE_TEXCO_OBJECT: {
+ data = sd->P + sd->dP.dx;
+ if (node.w == 0) {
+ if (sd->object != OBJECT_NONE) {
+ object_inverse_position_transform(kg, sd, &data);
+ }
+ }
+ else {
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
+ data = transform_point(&tfm, data);
+ }
+ break;
+ }
+ case NODE_TEXCO_NORMAL: {
+ data = sd->N;
+ object_inverse_normal_transform(kg, sd, &data);
+ break;
+ }
+ case NODE_TEXCO_CAMERA: {
+ Transform tfm = kernel_data.cam.worldtocamera;
+
+ if (sd->object != OBJECT_NONE)
+ data = transform_point(&tfm, sd->P + sd->dP.dx);
+ else
+ data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg));
+ break;
+ }
+ case NODE_TEXCO_WINDOW: {
+ if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
+ kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
+ data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx);
+ else
+ data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx);
+ data.z = 0.0f;
+ break;
+ }
+ case NODE_TEXCO_REFLECTION: {
+ if (sd->object != OBJECT_NONE)
+ data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
+ else
+ data = sd->I;
+ break;
+ }
+ case NODE_TEXCO_DUPLI_GENERATED: {
+ data = object_dupli_generated(kg, sd->object);
+ break;
+ }
+ case NODE_TEXCO_DUPLI_UV: {
+ data = object_dupli_uv(kg, sd->object);
+ break;
+ }
+ case NODE_TEXCO_VOLUME_GENERATED: {
+ data = sd->P + sd->dP.dx;
+
+# ifdef __VOLUME__
+ if (sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+# endif
+ break;
+ }
+ }
+
+ stack_store_float3(stack, out_offset, data);
#else
- svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
+ svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
#endif
}
-ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg,
- ShaderData *sd,
- int path_flag,
- float *stack,
- uint4 node,
- int *offset)
+ccl_device void svm_node_tex_coord_bump_dy(
+ KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
{
#ifdef __RAY_DIFFERENTIALS__
- float3 data;
- uint type = node.y;
- uint out_offset = node.z;
-
- switch(type) {
- case NODE_TEXCO_OBJECT: {
- data = sd->P + sd->dP.dy;
- if(node.w == 0) {
- if(sd->object != OBJECT_NONE) {
- object_inverse_position_transform(kg, sd, &data);
- }
- }
- else {
- Transform tfm;
- tfm.x = read_node_float(kg, offset);
- tfm.y = read_node_float(kg, offset);
- tfm.z = read_node_float(kg, offset);
- data = transform_point(&tfm, data);
- }
- break;
- }
- case NODE_TEXCO_NORMAL: {
- data = sd->N;
- object_inverse_normal_transform(kg, sd, &data);
- break;
- }
- case NODE_TEXCO_CAMERA: {
- Transform tfm = kernel_data.cam.worldtocamera;
-
- if(sd->object != OBJECT_NONE)
- data = transform_point(&tfm, sd->P + sd->dP.dy);
- else
- data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg));
- break;
- }
- case NODE_TEXCO_WINDOW: {
- if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
- data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy);
- else
- data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy);
- data.z = 0.0f;
- break;
- }
- case NODE_TEXCO_REFLECTION: {
- if(sd->object != OBJECT_NONE)
- data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
- else
- data = sd->I;
- break;
- }
- case NODE_TEXCO_DUPLI_GENERATED: {
- data = object_dupli_generated(kg, sd->object);
- break;
- }
- case NODE_TEXCO_DUPLI_UV: {
- data = object_dupli_uv(kg, sd->object);
- break;
- }
- case NODE_TEXCO_VOLUME_GENERATED: {
- data = sd->P + sd->dP.dy;
-
-#ifdef __VOLUME__
- if(sd->object != OBJECT_NONE)
- data = volume_normalized_position(kg, sd, data);
-#endif
- break;
- }
- }
-
- stack_store_float3(stack, out_offset, data);
+ float3 data;
+ uint type = node.y;
+ uint out_offset = node.z;
+
+ switch (type) {
+ case NODE_TEXCO_OBJECT: {
+ data = sd->P + sd->dP.dy;
+ if (node.w == 0) {
+ if (sd->object != OBJECT_NONE) {
+ object_inverse_position_transform(kg, sd, &data);
+ }
+ }
+ else {
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
+ data = transform_point(&tfm, data);
+ }
+ break;
+ }
+ case NODE_TEXCO_NORMAL: {
+ data = sd->N;
+ object_inverse_normal_transform(kg, sd, &data);
+ break;
+ }
+ case NODE_TEXCO_CAMERA: {
+ Transform tfm = kernel_data.cam.worldtocamera;
+
+ if (sd->object != OBJECT_NONE)
+ data = transform_point(&tfm, sd->P + sd->dP.dy);
+ else
+ data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg));
+ break;
+ }
+ case NODE_TEXCO_WINDOW: {
+ if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
+ kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
+ data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy);
+ else
+ data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy);
+ data.z = 0.0f;
+ break;
+ }
+ case NODE_TEXCO_REFLECTION: {
+ if (sd->object != OBJECT_NONE)
+ data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
+ else
+ data = sd->I;
+ break;
+ }
+ case NODE_TEXCO_DUPLI_GENERATED: {
+ data = object_dupli_generated(kg, sd->object);
+ break;
+ }
+ case NODE_TEXCO_DUPLI_UV: {
+ data = object_dupli_uv(kg, sd->object);
+ break;
+ }
+ case NODE_TEXCO_VOLUME_GENERATED: {
+ data = sd->P + sd->dP.dy;
+
+# ifdef __VOLUME__
+ if (sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+# endif
+ break;
+ }
+ }
+
+ stack_store_float3(stack, out_offset, data);
#else
- svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
+ svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
#endif
}
ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- uint color_offset, strength_offset, normal_offset, space;
- decode_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space);
-
- float3 color = stack_load_float3(stack, color_offset);
- color = 2.0f*make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f);
-
- bool is_backfacing = (sd->flag & SD_BACKFACING) != 0;
- float3 N;
-
- if(space == NODE_NORMAL_MAP_TANGENT) {
- /* tangent space */
- if(sd->object == OBJECT_NONE) {
- stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
- return;
- }
-
- /* first try to get tangent attribute */
- const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
- const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
- const AttributeDescriptor attr_normal = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL);
-
- if(attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND || attr_normal.offset == ATTR_STD_NOT_FOUND) {
- stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
- return;
- }
-
- /* get _unnormalized_ interpolated normal and tangent */
- float3 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
- float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
- float3 normal;
-
- if(sd->shader & SHADER_SMOOTH_NORMAL) {
- normal = primitive_surface_attribute_float3(kg, sd, attr_normal, NULL, NULL);
- }
- else {
- normal = sd->Ng;
-
- /* the normal is already inverted, which is too soon for the math here */
- if(is_backfacing) {
- normal = -normal;
- }
-
- object_inverse_normal_transform(kg, sd, &normal);
- }
-
- /* apply normal map */
- float3 B = sign * cross(normal, tangent);
- N = safe_normalize(color.x * tangent + color.y * B + color.z * normal);
-
- /* transform to world space */
- object_normal_transform(kg, sd, &N);
- }
- else {
- /* strange blender convention */
- if(space == NODE_NORMAL_MAP_BLENDER_OBJECT || space == NODE_NORMAL_MAP_BLENDER_WORLD) {
- color.y = -color.y;
- color.z = -color.z;
- }
-
- /* object, world space */
- N = color;
-
- if(space == NODE_NORMAL_MAP_OBJECT || space == NODE_NORMAL_MAP_BLENDER_OBJECT)
- object_normal_transform(kg, sd, &N);
- else
- N = safe_normalize(N);
- }
-
- /* invert normal for backfacing polygons */
- if(is_backfacing) {
- N = -N;
- }
-
- float strength = stack_load_float(stack, strength_offset);
-
- if(strength != 1.0f) {
- strength = max(strength, 0.0f);
- N = safe_normalize(sd->N + (N - sd->N)*strength);
- }
-
- N = ensure_valid_reflection(sd->Ng, sd->I, N);
-
- if(is_zero(N)) {
- N = sd->N;
- }
-
- stack_store_float3(stack, normal_offset, N);
+ uint color_offset, strength_offset, normal_offset, space;
+ decode_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space);
+
+ float3 color = stack_load_float3(stack, color_offset);
+ color = 2.0f * make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f);
+
+ bool is_backfacing = (sd->flag & SD_BACKFACING) != 0;
+ float3 N;
+
+ if (space == NODE_NORMAL_MAP_TANGENT) {
+ /* tangent space */
+ if (sd->object == OBJECT_NONE) {
+ stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
+ return;
+ }
+
+ /* first try to get tangent attribute */
+ const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
+ const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
+ const AttributeDescriptor attr_normal = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL);
+
+ if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND ||
+ attr_normal.offset == ATTR_STD_NOT_FOUND) {
+ stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
+ return;
+ }
+
+ /* get _unnormalized_ interpolated normal and tangent */
+ float3 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
+ float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
+ float3 normal;
+
+ if (sd->shader & SHADER_SMOOTH_NORMAL) {
+ normal = primitive_surface_attribute_float3(kg, sd, attr_normal, NULL, NULL);
+ }
+ else {
+ normal = sd->Ng;
+
+ /* the normal is already inverted, which is too soon for the math here */
+ if (is_backfacing) {
+ normal = -normal;
+ }
+
+ object_inverse_normal_transform(kg, sd, &normal);
+ }
+
+ /* apply normal map */
+ float3 B = sign * cross(normal, tangent);
+ N = safe_normalize(color.x * tangent + color.y * B + color.z * normal);
+
+ /* transform to world space */
+ object_normal_transform(kg, sd, &N);
+ }
+ else {
+ /* strange blender convention */
+ if (space == NODE_NORMAL_MAP_BLENDER_OBJECT || space == NODE_NORMAL_MAP_BLENDER_WORLD) {
+ color.y = -color.y;
+ color.z = -color.z;
+ }
+
+ /* object, world space */
+ N = color;
+
+ if (space == NODE_NORMAL_MAP_OBJECT || space == NODE_NORMAL_MAP_BLENDER_OBJECT)
+ object_normal_transform(kg, sd, &N);
+ else
+ N = safe_normalize(N);
+ }
+
+ /* invert normal for backfacing polygons */
+ if (is_backfacing) {
+ N = -N;
+ }
+
+ float strength = stack_load_float(stack, strength_offset);
+
+ if (strength != 1.0f) {
+ strength = max(strength, 0.0f);
+ N = safe_normalize(sd->N + (N - sd->N) * strength);
+ }
+
+ N = ensure_valid_reflection(sd->Ng, sd->I, N);
+
+ if (is_zero(N)) {
+ N = sd->N;
+ }
+
+ stack_store_float3(stack, normal_offset, N);
}
ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- uint tangent_offset, direction_type, axis;
- decode_node_uchar4(node.y, &tangent_offset, &direction_type, &axis, NULL);
-
- float3 tangent;
- float3 attribute_value;
- const AttributeDescriptor desc = find_attribute(kg, sd, node.z);
- if (desc.offset != ATTR_STD_NOT_FOUND) {
- if(desc.type == NODE_ATTR_FLOAT2) {
- float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
- attribute_value.x = value.x;
- attribute_value.y = value.y;
- attribute_value.z = 0.0f;
- }
- else {
- attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
- }
- }
-
-
- if(direction_type == NODE_TANGENT_UVMAP) {
- /* UV map */
- if(desc.offset == ATTR_STD_NOT_FOUND)
- tangent = make_float3(0.0f, 0.0f, 0.0f);
- else
- tangent = attribute_value;
- }
- else {
- /* radial */
- float3 generated;
-
- if(desc.offset == ATTR_STD_NOT_FOUND)
- generated = sd->P;
- else
- generated = attribute_value;
-
- if(axis == NODE_TANGENT_AXIS_X)
- tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
- else if(axis == NODE_TANGENT_AXIS_Y)
- tangent = make_float3(-(generated.z - 0.5f), 0.0f, (generated.x - 0.5f));
- else
- tangent = make_float3(-(generated.y - 0.5f), (generated.x - 0.5f), 0.0f);
- }
-
- object_normal_transform(kg, sd, &tangent);
- tangent = cross(sd->N, normalize(cross(tangent, sd->N)));
- stack_store_float3(stack, tangent_offset, tangent);
+ uint tangent_offset, direction_type, axis;
+ decode_node_uchar4(node.y, &tangent_offset, &direction_type, &axis, NULL);
+
+ float3 tangent;
+ float3 attribute_value;
+ const AttributeDescriptor desc = find_attribute(kg, sd, node.z);
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
+ attribute_value.x = value.x;
+ attribute_value.y = value.y;
+ attribute_value.z = 0.0f;
+ }
+ else {
+ attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
+ }
+ }
+
+ if (direction_type == NODE_TANGENT_UVMAP) {
+ /* UV map */
+ if (desc.offset == ATTR_STD_NOT_FOUND)
+ tangent = make_float3(0.0f, 0.0f, 0.0f);
+ else
+ tangent = attribute_value;
+ }
+ else {
+ /* radial */
+ float3 generated;
+
+ if (desc.offset == ATTR_STD_NOT_FOUND)
+ generated = sd->P;
+ else
+ generated = attribute_value;
+
+ if (axis == NODE_TANGENT_AXIS_X)
+ tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
+ else if (axis == NODE_TANGENT_AXIS_Y)
+ tangent = make_float3(-(generated.z - 0.5f), 0.0f, (generated.x - 0.5f));
+ else
+ tangent = make_float3(-(generated.y - 0.5f), (generated.x - 0.5f), 0.0f);
+ }
+
+ object_normal_transform(kg, sd, &tangent);
+ tangent = cross(sd->N, normalize(cross(tangent, sd->N)));
+ stack_store_float3(stack, tangent_offset, tangent);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_texture.h b/intern/cycles/kernel/svm/svm_texture.h
index 57729817bdc..290aa85c831 100644
--- a/intern/cycles/kernel/svm/svm_texture.h
+++ b/intern/cycles/kernel/svm/svm_texture.h
@@ -20,44 +20,44 @@ CCL_NAMESPACE_BEGIN
ccl_device_noinline float noise_turbulence(float3 p, float octaves, int hard)
{
- float fscale = 1.0f;
- float amp = 1.0f;
- float sum = 0.0f;
- int i, n;
+ float fscale = 1.0f;
+ float amp = 1.0f;
+ float sum = 0.0f;
+ int i, n;
- octaves = clamp(octaves, 0.0f, 16.0f);
- n = float_to_int(octaves);
+ octaves = clamp(octaves, 0.0f, 16.0f);
+ n = float_to_int(octaves);
- for(i = 0; i <= n; i++) {
- float t = noise(fscale*p);
+ for (i = 0; i <= n; i++) {
+ float t = noise(fscale * p);
- if(hard)
- t = fabsf(2.0f*t - 1.0f);
+ if (hard)
+ t = fabsf(2.0f * t - 1.0f);
- sum += t*amp;
- amp *= 0.5f;
- fscale *= 2.0f;
- }
+ sum += t * amp;
+ amp *= 0.5f;
+ fscale *= 2.0f;
+ }
- float rmd = octaves - floorf(octaves);
+ float rmd = octaves - floorf(octaves);
- if(rmd != 0.0f) {
- float t = noise(fscale*p);
+ if (rmd != 0.0f) {
+ float t = noise(fscale * p);
- if(hard)
- t = fabsf(2.0f*t - 1.0f);
+ if (hard)
+ t = fabsf(2.0f * t - 1.0f);
- float sum2 = sum + t*amp;
+ float sum2 = sum + t * amp;
- sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
- sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1));
+ sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
+ sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
- return (1.0f - rmd)*sum + rmd*sum2;
- }
- else {
- sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
- return sum;
- }
+ return (1.0f - rmd) * sum + rmd * sum2;
+ }
+ else {
+ sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
+ return sum;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 8b15d7bf9f4..d31e4f93696 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -38,498 +38,505 @@ CCL_NAMESPACE_BEGIN
*
* Lower the number of group more often the node is used.
*/
-#define NODE_GROUP_LEVEL_0 0
-#define NODE_GROUP_LEVEL_1 1
-#define NODE_GROUP_LEVEL_2 2
-#define NODE_GROUP_LEVEL_3 3
-#define NODE_GROUP_LEVEL_MAX NODE_GROUP_LEVEL_3
-
-#define NODE_FEATURE_VOLUME (1 << 0)
-#define NODE_FEATURE_HAIR (1 << 1)
-#define NODE_FEATURE_BUMP (1 << 2)
+#define NODE_GROUP_LEVEL_0 0
+#define NODE_GROUP_LEVEL_1 1
+#define NODE_GROUP_LEVEL_2 2
+#define NODE_GROUP_LEVEL_3 3
+#define NODE_GROUP_LEVEL_MAX NODE_GROUP_LEVEL_3
+
+#define NODE_FEATURE_VOLUME (1 << 0)
+#define NODE_FEATURE_HAIR (1 << 1)
+#define NODE_FEATURE_BUMP (1 << 2)
#define NODE_FEATURE_BUMP_STATE (1 << 3)
/* TODO(sergey): Consider using something like ((uint)(-1)).
* Need to check carefully operand types around usage of this
* define first.
*/
-#define NODE_FEATURE_ALL (NODE_FEATURE_VOLUME|NODE_FEATURE_HAIR|NODE_FEATURE_BUMP|NODE_FEATURE_BUMP_STATE)
+#define NODE_FEATURE_ALL \
+ (NODE_FEATURE_VOLUME | NODE_FEATURE_HAIR | NODE_FEATURE_BUMP | NODE_FEATURE_BUMP_STATE)
typedef enum ShaderNodeType {
- NODE_END = 0,
- NODE_CLOSURE_BSDF,
- NODE_CLOSURE_EMISSION,
- NODE_CLOSURE_BACKGROUND,
- NODE_CLOSURE_SET_WEIGHT,
- NODE_CLOSURE_WEIGHT,
- NODE_MIX_CLOSURE,
- NODE_JUMP_IF_ZERO,
- NODE_JUMP_IF_ONE,
- NODE_TEX_IMAGE,
- NODE_TEX_IMAGE_BOX,
- NODE_TEX_SKY,
- NODE_GEOMETRY,
- NODE_GEOMETRY_DUPLI,
- NODE_LIGHT_PATH,
- NODE_VALUE_F,
- NODE_VALUE_V,
- NODE_MIX,
- NODE_ATTR,
- NODE_CONVERT,
- NODE_FRESNEL,
- NODE_WIREFRAME,
- NODE_WAVELENGTH,
- NODE_BLACKBODY,
- NODE_EMISSION_WEIGHT,
- NODE_TEX_GRADIENT,
- NODE_TEX_VORONOI,
- NODE_TEX_MUSGRAVE,
- NODE_TEX_WAVE,
- NODE_TEX_MAGIC,
- NODE_TEX_NOISE,
- NODE_SHADER_JUMP,
- NODE_SET_DISPLACEMENT,
- NODE_GEOMETRY_BUMP_DX,
- NODE_GEOMETRY_BUMP_DY,
- NODE_SET_BUMP,
- NODE_MATH,
- NODE_VECTOR_MATH,
- NODE_VECTOR_TRANSFORM,
- NODE_MAPPING,
- NODE_TEX_COORD,
- NODE_TEX_COORD_BUMP_DX,
- NODE_TEX_COORD_BUMP_DY,
- NODE_ATTR_BUMP_DX,
- NODE_ATTR_BUMP_DY,
- NODE_TEX_ENVIRONMENT,
- NODE_CLOSURE_HOLDOUT,
- NODE_LAYER_WEIGHT,
- NODE_CLOSURE_VOLUME,
- NODE_SEPARATE_VECTOR,
- NODE_COMBINE_VECTOR,
- NODE_SEPARATE_HSV,
- NODE_COMBINE_HSV,
- NODE_HSV,
- NODE_CAMERA,
- NODE_INVERT,
- NODE_NORMAL,
- NODE_GAMMA,
- NODE_TEX_CHECKER,
- NODE_BRIGHTCONTRAST,
- NODE_RGB_RAMP,
- NODE_RGB_CURVES,
- NODE_VECTOR_CURVES,
- NODE_MIN_MAX,
- NODE_LIGHT_FALLOFF,
- NODE_OBJECT_INFO,
- NODE_PARTICLE_INFO,
- NODE_TEX_BRICK,
- NODE_CLOSURE_SET_NORMAL,
- NODE_AMBIENT_OCCLUSION,
- NODE_TANGENT,
- NODE_NORMAL_MAP,
- NODE_HAIR_INFO,
- NODE_UVMAP,
- NODE_TEX_VOXEL,
- NODE_ENTER_BUMP_EVAL,
- NODE_LEAVE_BUMP_EVAL,
- NODE_BEVEL,
- NODE_DISPLACEMENT,
- NODE_VECTOR_DISPLACEMENT,
- NODE_PRINCIPLED_VOLUME,
- NODE_IES,
+ NODE_END = 0,
+ NODE_CLOSURE_BSDF,
+ NODE_CLOSURE_EMISSION,
+ NODE_CLOSURE_BACKGROUND,
+ NODE_CLOSURE_SET_WEIGHT,
+ NODE_CLOSURE_WEIGHT,
+ NODE_MIX_CLOSURE,
+ NODE_JUMP_IF_ZERO,
+ NODE_JUMP_IF_ONE,
+ NODE_TEX_IMAGE,
+ NODE_TEX_IMAGE_BOX,
+ NODE_TEX_SKY,
+ NODE_GEOMETRY,
+ NODE_GEOMETRY_DUPLI,
+ NODE_LIGHT_PATH,
+ NODE_VALUE_F,
+ NODE_VALUE_V,
+ NODE_MIX,
+ NODE_ATTR,
+ NODE_CONVERT,
+ NODE_FRESNEL,
+ NODE_WIREFRAME,
+ NODE_WAVELENGTH,
+ NODE_BLACKBODY,
+ NODE_EMISSION_WEIGHT,
+ NODE_TEX_GRADIENT,
+ NODE_TEX_VORONOI,
+ NODE_TEX_MUSGRAVE,
+ NODE_TEX_WAVE,
+ NODE_TEX_MAGIC,
+ NODE_TEX_NOISE,
+ NODE_SHADER_JUMP,
+ NODE_SET_DISPLACEMENT,
+ NODE_GEOMETRY_BUMP_DX,
+ NODE_GEOMETRY_BUMP_DY,
+ NODE_SET_BUMP,
+ NODE_MATH,
+ NODE_VECTOR_MATH,
+ NODE_VECTOR_TRANSFORM,
+ NODE_MAPPING,
+ NODE_TEX_COORD,
+ NODE_TEX_COORD_BUMP_DX,
+ NODE_TEX_COORD_BUMP_DY,
+ NODE_ATTR_BUMP_DX,
+ NODE_ATTR_BUMP_DY,
+ NODE_TEX_ENVIRONMENT,
+ NODE_CLOSURE_HOLDOUT,
+ NODE_LAYER_WEIGHT,
+ NODE_CLOSURE_VOLUME,
+ NODE_SEPARATE_VECTOR,
+ NODE_COMBINE_VECTOR,
+ NODE_SEPARATE_HSV,
+ NODE_COMBINE_HSV,
+ NODE_HSV,
+ NODE_CAMERA,
+ NODE_INVERT,
+ NODE_NORMAL,
+ NODE_GAMMA,
+ NODE_TEX_CHECKER,
+ NODE_BRIGHTCONTRAST,
+ NODE_RGB_RAMP,
+ NODE_RGB_CURVES,
+ NODE_VECTOR_CURVES,
+ NODE_MIN_MAX,
+ NODE_LIGHT_FALLOFF,
+ NODE_OBJECT_INFO,
+ NODE_PARTICLE_INFO,
+ NODE_TEX_BRICK,
+ NODE_CLOSURE_SET_NORMAL,
+ NODE_AMBIENT_OCCLUSION,
+ NODE_TANGENT,
+ NODE_NORMAL_MAP,
+ NODE_HAIR_INFO,
+ NODE_UVMAP,
+ NODE_TEX_VOXEL,
+ NODE_ENTER_BUMP_EVAL,
+ NODE_LEAVE_BUMP_EVAL,
+ NODE_BEVEL,
+ NODE_DISPLACEMENT,
+ NODE_VECTOR_DISPLACEMENT,
+ NODE_PRINCIPLED_VOLUME,
+ NODE_IES,
} ShaderNodeType;
typedef enum NodeAttributeType {
- NODE_ATTR_FLOAT = 0,
- NODE_ATTR_FLOAT2,
- NODE_ATTR_FLOAT3,
- NODE_ATTR_MATRIX
+ NODE_ATTR_FLOAT = 0,
+ NODE_ATTR_FLOAT2,
+ NODE_ATTR_FLOAT3,
+ NODE_ATTR_MATRIX
} NodeAttributeType;
typedef enum NodeGeometry {
- NODE_GEOM_P = 0,
- NODE_GEOM_N,
- NODE_GEOM_T,
- NODE_GEOM_I,
- NODE_GEOM_Ng,
- NODE_GEOM_uv
+ NODE_GEOM_P = 0,
+ NODE_GEOM_N,
+ NODE_GEOM_T,
+ NODE_GEOM_I,
+ NODE_GEOM_Ng,
+ NODE_GEOM_uv
} NodeGeometry;
typedef enum NodeObjectInfo {
- NODE_INFO_OB_LOCATION,
- NODE_INFO_OB_INDEX,
- NODE_INFO_MAT_INDEX,
- NODE_INFO_OB_RANDOM
+ NODE_INFO_OB_LOCATION,
+ NODE_INFO_OB_INDEX,
+ NODE_INFO_MAT_INDEX,
+ NODE_INFO_OB_RANDOM
} NodeObjectInfo;
typedef enum NodeParticleInfo {
- NODE_INFO_PAR_INDEX,
- NODE_INFO_PAR_RANDOM,
- NODE_INFO_PAR_AGE,
- NODE_INFO_PAR_LIFETIME,
- NODE_INFO_PAR_LOCATION,
- NODE_INFO_PAR_ROTATION,
- NODE_INFO_PAR_SIZE,
- NODE_INFO_PAR_VELOCITY,
- NODE_INFO_PAR_ANGULAR_VELOCITY
+ NODE_INFO_PAR_INDEX,
+ NODE_INFO_PAR_RANDOM,
+ NODE_INFO_PAR_AGE,
+ NODE_INFO_PAR_LIFETIME,
+ NODE_INFO_PAR_LOCATION,
+ NODE_INFO_PAR_ROTATION,
+ NODE_INFO_PAR_SIZE,
+ NODE_INFO_PAR_VELOCITY,
+ NODE_INFO_PAR_ANGULAR_VELOCITY
} NodeParticleInfo;
typedef enum NodeHairInfo {
- NODE_INFO_CURVE_IS_STRAND,
- NODE_INFO_CURVE_INTERCEPT,
- NODE_INFO_CURVE_THICKNESS,
- /*fade for minimum hair width transpency*/
- /*NODE_INFO_CURVE_FADE,*/
- NODE_INFO_CURVE_TANGENT_NORMAL,
- NODE_INFO_CURVE_RANDOM,
+ NODE_INFO_CURVE_IS_STRAND,
+ NODE_INFO_CURVE_INTERCEPT,
+ NODE_INFO_CURVE_THICKNESS,
+ /*fade for minimum hair width transpency*/
+ /*NODE_INFO_CURVE_FADE,*/
+ NODE_INFO_CURVE_TANGENT_NORMAL,
+ NODE_INFO_CURVE_RANDOM,
} NodeHairInfo;
typedef enum NodeLightPath {
- NODE_LP_camera = 0,
- NODE_LP_shadow,
- NODE_LP_diffuse,
- NODE_LP_glossy,
- NODE_LP_singular,
- NODE_LP_reflection,
- NODE_LP_transmission,
- NODE_LP_volume_scatter,
- NODE_LP_backfacing,
- NODE_LP_ray_length,
- NODE_LP_ray_depth,
- NODE_LP_ray_diffuse,
- NODE_LP_ray_glossy,
- NODE_LP_ray_transparent,
- NODE_LP_ray_transmission,
+ NODE_LP_camera = 0,
+ NODE_LP_shadow,
+ NODE_LP_diffuse,
+ NODE_LP_glossy,
+ NODE_LP_singular,
+ NODE_LP_reflection,
+ NODE_LP_transmission,
+ NODE_LP_volume_scatter,
+ NODE_LP_backfacing,
+ NODE_LP_ray_length,
+ NODE_LP_ray_depth,
+ NODE_LP_ray_diffuse,
+ NODE_LP_ray_glossy,
+ NODE_LP_ray_transparent,
+ NODE_LP_ray_transmission,
} NodeLightPath;
typedef enum NodeLightFalloff {
- NODE_LIGHT_FALLOFF_QUADRATIC,
- NODE_LIGHT_FALLOFF_LINEAR,
- NODE_LIGHT_FALLOFF_CONSTANT
+ NODE_LIGHT_FALLOFF_QUADRATIC,
+ NODE_LIGHT_FALLOFF_LINEAR,
+ NODE_LIGHT_FALLOFF_CONSTANT
} NodeLightFalloff;
typedef enum NodeTexCoord {
- NODE_TEXCO_NORMAL,
- NODE_TEXCO_OBJECT,
- NODE_TEXCO_CAMERA,
- NODE_TEXCO_WINDOW,
- NODE_TEXCO_REFLECTION,
- NODE_TEXCO_DUPLI_GENERATED,
- NODE_TEXCO_DUPLI_UV,
- NODE_TEXCO_VOLUME_GENERATED
+ NODE_TEXCO_NORMAL,
+ NODE_TEXCO_OBJECT,
+ NODE_TEXCO_CAMERA,
+ NODE_TEXCO_WINDOW,
+ NODE_TEXCO_REFLECTION,
+ NODE_TEXCO_DUPLI_GENERATED,
+ NODE_TEXCO_DUPLI_UV,
+ NODE_TEXCO_VOLUME_GENERATED
} NodeTexCoord;
typedef enum NodeMix {
- NODE_MIX_BLEND = 0,
- NODE_MIX_ADD,
- NODE_MIX_MUL,
- NODE_MIX_SUB,
- NODE_MIX_SCREEN,
- NODE_MIX_DIV,
- NODE_MIX_DIFF,
- NODE_MIX_DARK,
- NODE_MIX_LIGHT,
- NODE_MIX_OVERLAY,
- NODE_MIX_DODGE,
- NODE_MIX_BURN,
- NODE_MIX_HUE,
- NODE_MIX_SAT,
- NODE_MIX_VAL,
- NODE_MIX_COLOR,
- NODE_MIX_SOFT,
- NODE_MIX_LINEAR,
- NODE_MIX_CLAMP /* used for the clamp UI option */
+ NODE_MIX_BLEND = 0,
+ NODE_MIX_ADD,
+ NODE_MIX_MUL,
+ NODE_MIX_SUB,
+ NODE_MIX_SCREEN,
+ NODE_MIX_DIV,
+ NODE_MIX_DIFF,
+ NODE_MIX_DARK,
+ NODE_MIX_LIGHT,
+ NODE_MIX_OVERLAY,
+ NODE_MIX_DODGE,
+ NODE_MIX_BURN,
+ NODE_MIX_HUE,
+ NODE_MIX_SAT,
+ NODE_MIX_VAL,
+ NODE_MIX_COLOR,
+ NODE_MIX_SOFT,
+ NODE_MIX_LINEAR,
+ NODE_MIX_CLAMP /* used for the clamp UI option */
} NodeMix;
typedef enum NodeMath {
- NODE_MATH_ADD,
- NODE_MATH_SUBTRACT,
- NODE_MATH_MULTIPLY,
- NODE_MATH_DIVIDE,
- NODE_MATH_SINE,
- NODE_MATH_COSINE,
- NODE_MATH_TANGENT,
- NODE_MATH_ARCSINE,
- NODE_MATH_ARCCOSINE,
- NODE_MATH_ARCTANGENT,
- NODE_MATH_POWER,
- NODE_MATH_LOGARITHM,
- NODE_MATH_MINIMUM,
- NODE_MATH_MAXIMUM,
- NODE_MATH_ROUND,
- NODE_MATH_LESS_THAN,
- NODE_MATH_GREATER_THAN,
- NODE_MATH_MODULO,
- NODE_MATH_ABSOLUTE,
- NODE_MATH_ARCTAN2,
- NODE_MATH_FLOOR,
- NODE_MATH_CEIL,
- NODE_MATH_FRACT,
- NODE_MATH_SQRT,
- NODE_MATH_CLAMP /* used for the clamp UI option */
+ NODE_MATH_ADD,
+ NODE_MATH_SUBTRACT,
+ NODE_MATH_MULTIPLY,
+ NODE_MATH_DIVIDE,
+ NODE_MATH_SINE,
+ NODE_MATH_COSINE,
+ NODE_MATH_TANGENT,
+ NODE_MATH_ARCSINE,
+ NODE_MATH_ARCCOSINE,
+ NODE_MATH_ARCTANGENT,
+ NODE_MATH_POWER,
+ NODE_MATH_LOGARITHM,
+ NODE_MATH_MINIMUM,
+ NODE_MATH_MAXIMUM,
+ NODE_MATH_ROUND,
+ NODE_MATH_LESS_THAN,
+ NODE_MATH_GREATER_THAN,
+ NODE_MATH_MODULO,
+ NODE_MATH_ABSOLUTE,
+ NODE_MATH_ARCTAN2,
+ NODE_MATH_FLOOR,
+ NODE_MATH_CEIL,
+ NODE_MATH_FRACT,
+ NODE_MATH_SQRT,
+ NODE_MATH_CLAMP /* used for the clamp UI option */
} NodeMath;
typedef enum NodeVectorMath {
- NODE_VECTOR_MATH_ADD,
- NODE_VECTOR_MATH_SUBTRACT,
- NODE_VECTOR_MATH_AVERAGE,
- NODE_VECTOR_MATH_DOT_PRODUCT,
- NODE_VECTOR_MATH_CROSS_PRODUCT,
- NODE_VECTOR_MATH_NORMALIZE
+ NODE_VECTOR_MATH_ADD,
+ NODE_VECTOR_MATH_SUBTRACT,
+ NODE_VECTOR_MATH_AVERAGE,
+ NODE_VECTOR_MATH_DOT_PRODUCT,
+ NODE_VECTOR_MATH_CROSS_PRODUCT,
+ NODE_VECTOR_MATH_NORMALIZE
} NodeVectorMath;
typedef enum NodeVectorTransformType {
- NODE_VECTOR_TRANSFORM_TYPE_VECTOR,
- NODE_VECTOR_TRANSFORM_TYPE_POINT,
- NODE_VECTOR_TRANSFORM_TYPE_NORMAL
+ NODE_VECTOR_TRANSFORM_TYPE_VECTOR,
+ NODE_VECTOR_TRANSFORM_TYPE_POINT,
+ NODE_VECTOR_TRANSFORM_TYPE_NORMAL
} NodeVectorTransformType;
typedef enum NodeVectorTransformConvertSpace {
- NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD,
- NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT,
- NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA
+ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD,
+ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT,
+ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA
} NodeVectorTransformConvertSpace;
typedef enum NodeConvert {
- NODE_CONVERT_FV,
- NODE_CONVERT_FI,
- NODE_CONVERT_CF,
- NODE_CONVERT_CI,
- NODE_CONVERT_VF,
- NODE_CONVERT_VI,
- NODE_CONVERT_IF,
- NODE_CONVERT_IV
+ NODE_CONVERT_FV,
+ NODE_CONVERT_FI,
+ NODE_CONVERT_CF,
+ NODE_CONVERT_CI,
+ NODE_CONVERT_VF,
+ NODE_CONVERT_VI,
+ NODE_CONVERT_IF,
+ NODE_CONVERT_IV
} NodeConvert;
typedef enum NodeMusgraveType {
- NODE_MUSGRAVE_MULTIFRACTAL,
- NODE_MUSGRAVE_FBM,
- NODE_MUSGRAVE_HYBRID_MULTIFRACTAL,
- NODE_MUSGRAVE_RIDGED_MULTIFRACTAL,
- NODE_MUSGRAVE_HETERO_TERRAIN
+ NODE_MUSGRAVE_MULTIFRACTAL,
+ NODE_MUSGRAVE_FBM,
+ NODE_MUSGRAVE_HYBRID_MULTIFRACTAL,
+ NODE_MUSGRAVE_RIDGED_MULTIFRACTAL,
+ NODE_MUSGRAVE_HETERO_TERRAIN
} NodeMusgraveType;
-typedef enum NodeWaveType {
- NODE_WAVE_BANDS,
- NODE_WAVE_RINGS
-} NodeWaveType;
+typedef enum NodeWaveType { NODE_WAVE_BANDS, NODE_WAVE_RINGS } NodeWaveType;
typedef enum NodeWaveProfiles {
- NODE_WAVE_PROFILE_SIN,
- NODE_WAVE_PROFILE_SAW,
+ NODE_WAVE_PROFILE_SIN,
+ NODE_WAVE_PROFILE_SAW,
} NodeWaveProfile;
-typedef enum NodeSkyType {
- NODE_SKY_OLD,
- NODE_SKY_NEW
-} NodeSkyType;
+typedef enum NodeSkyType { NODE_SKY_OLD, NODE_SKY_NEW } NodeSkyType;
typedef enum NodeGradientType {
- NODE_BLEND_LINEAR,
- NODE_BLEND_QUADRATIC,
- NODE_BLEND_EASING,
- NODE_BLEND_DIAGONAL,
- NODE_BLEND_RADIAL,
- NODE_BLEND_QUADRATIC_SPHERE,
- NODE_BLEND_SPHERICAL
+ NODE_BLEND_LINEAR,
+ NODE_BLEND_QUADRATIC,
+ NODE_BLEND_EASING,
+ NODE_BLEND_DIAGONAL,
+ NODE_BLEND_RADIAL,
+ NODE_BLEND_QUADRATIC_SPHERE,
+ NODE_BLEND_SPHERICAL
} NodeGradientType;
typedef enum NodeVoronoiColoring {
- NODE_VORONOI_INTENSITY,
- NODE_VORONOI_CELLS
+ NODE_VORONOI_INTENSITY,
+ NODE_VORONOI_CELLS
} NodeVoronoiColoring;
typedef enum NodeVoronoiDistanceMetric {
- NODE_VORONOI_DISTANCE,
- NODE_VORONOI_MANHATTAN,
- NODE_VORONOI_CHEBYCHEV,
- NODE_VORONOI_MINKOWSKI
+ NODE_VORONOI_DISTANCE,
+ NODE_VORONOI_MANHATTAN,
+ NODE_VORONOI_CHEBYCHEV,
+ NODE_VORONOI_MINKOWSKI
} NodeVoronoiDistanceMetric;
typedef enum NodeVoronoiFeature {
- NODE_VORONOI_F1,
- NODE_VORONOI_F2,
- NODE_VORONOI_F3,
- NODE_VORONOI_F4,
- NODE_VORONOI_F2F1
+ NODE_VORONOI_F1,
+ NODE_VORONOI_F2,
+ NODE_VORONOI_F3,
+ NODE_VORONOI_F4,
+ NODE_VORONOI_F2F1
} NodeVoronoiFeature;
typedef enum NodeBlendWeightType {
- NODE_LAYER_WEIGHT_FRESNEL,
- NODE_LAYER_WEIGHT_FACING
+ NODE_LAYER_WEIGHT_FRESNEL,
+ NODE_LAYER_WEIGHT_FACING
} NodeBlendWeightType;
typedef enum NodeTangentDirectionType {
- NODE_TANGENT_RADIAL,
- NODE_TANGENT_UVMAP
+ NODE_TANGENT_RADIAL,
+ NODE_TANGENT_UVMAP
} NodeTangentDirectionType;
typedef enum NodeTangentAxis {
- NODE_TANGENT_AXIS_X,
- NODE_TANGENT_AXIS_Y,
- NODE_TANGENT_AXIS_Z
+ NODE_TANGENT_AXIS_X,
+ NODE_TANGENT_AXIS_Y,
+ NODE_TANGENT_AXIS_Z
} NodeTangentAxis;
typedef enum NodeNormalMapSpace {
- NODE_NORMAL_MAP_TANGENT,
- NODE_NORMAL_MAP_OBJECT,
- NODE_NORMAL_MAP_WORLD,
- NODE_NORMAL_MAP_BLENDER_OBJECT,
- NODE_NORMAL_MAP_BLENDER_WORLD,
+ NODE_NORMAL_MAP_TANGENT,
+ NODE_NORMAL_MAP_OBJECT,
+ NODE_NORMAL_MAP_WORLD,
+ NODE_NORMAL_MAP_BLENDER_OBJECT,
+ NODE_NORMAL_MAP_BLENDER_WORLD,
} NodeNormalMapSpace;
typedef enum NodeImageColorSpace {
- NODE_COLOR_SPACE_NONE = 0,
- NODE_COLOR_SPACE_COLOR = 1,
+ NODE_COLOR_SPACE_NONE = 0,
+ NODE_COLOR_SPACE_COLOR = 1,
} NodeImageColorSpace;
typedef enum NodeImageProjection {
- NODE_IMAGE_PROJ_FLAT = 0,
- NODE_IMAGE_PROJ_BOX = 1,
- NODE_IMAGE_PROJ_SPHERE = 2,
- NODE_IMAGE_PROJ_TUBE = 3,
+ NODE_IMAGE_PROJ_FLAT = 0,
+ NODE_IMAGE_PROJ_BOX = 1,
+ NODE_IMAGE_PROJ_SPHERE = 2,
+ NODE_IMAGE_PROJ_TUBE = 3,
} NodeImageProjection;
typedef enum NodeEnvironmentProjection {
- NODE_ENVIRONMENT_EQUIRECTANGULAR = 0,
- NODE_ENVIRONMENT_MIRROR_BALL = 1,
+ NODE_ENVIRONMENT_EQUIRECTANGULAR = 0,
+ NODE_ENVIRONMENT_MIRROR_BALL = 1,
} NodeEnvironmentProjection;
typedef enum NodeBumpOffset {
- NODE_BUMP_OFFSET_CENTER,
- NODE_BUMP_OFFSET_DX,
- NODE_BUMP_OFFSET_DY,
+ NODE_BUMP_OFFSET_CENTER,
+ NODE_BUMP_OFFSET_DX,
+ NODE_BUMP_OFFSET_DY,
} NodeBumpOffset;
typedef enum NodeTexVoxelSpace {
- NODE_TEX_VOXEL_SPACE_OBJECT = 0,
- NODE_TEX_VOXEL_SPACE_WORLD = 1,
+ NODE_TEX_VOXEL_SPACE_OBJECT = 0,
+ NODE_TEX_VOXEL_SPACE_WORLD = 1,
} NodeTexVoxelSpace;
typedef enum NodeAO {
- NODE_AO_ONLY_LOCAL = (1 << 0),
- NODE_AO_INSIDE = (1 << 1),
- NODE_AO_GLOBAL_RADIUS = (1 << 2),
+ NODE_AO_ONLY_LOCAL = (1 << 0),
+ NODE_AO_INSIDE = (1 << 1),
+ NODE_AO_GLOBAL_RADIUS = (1 << 2),
} NodeAO;
typedef enum ShaderType {
- SHADER_TYPE_SURFACE,
- SHADER_TYPE_VOLUME,
- SHADER_TYPE_DISPLACEMENT,
- SHADER_TYPE_BUMP,
+ SHADER_TYPE_SURFACE,
+ SHADER_TYPE_VOLUME,
+ SHADER_TYPE_DISPLACEMENT,
+ SHADER_TYPE_BUMP,
} ShaderType;
typedef enum NodePrincipledHairParametrization {
- NODE_PRINCIPLED_HAIR_REFLECTANCE = 0,
- NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION = 1,
- NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION = 2,
- NODE_PRINCIPLED_HAIR_NUM,
+ NODE_PRINCIPLED_HAIR_REFLECTANCE = 0,
+ NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION = 1,
+ NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION = 2,
+ NODE_PRINCIPLED_HAIR_NUM,
} NodePrincipledHairParametrization;
/* Closure */
typedef enum ClosureType {
- /* Special type, flags generic node as a non-BSDF. */
- CLOSURE_NONE_ID,
-
- CLOSURE_BSDF_ID,
-
- /* Diffuse */
- CLOSURE_BSDF_DIFFUSE_ID,
- CLOSURE_BSDF_OREN_NAYAR_ID,
- CLOSURE_BSDF_DIFFUSE_RAMP_ID,
- CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID,
- CLOSURE_BSDF_PRINCIPLED_SHEEN_ID,
- CLOSURE_BSDF_DIFFUSE_TOON_ID,
-
- /* Glossy */
- CLOSURE_BSDF_REFLECTION_ID,
- CLOSURE_BSDF_MICROFACET_GGX_ID,
- CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID,
- CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID,
- CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
- CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID,
- CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID,
- CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID,
- CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID,
- CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID,
- CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID,
- CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_FRESNEL_ID,
- CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID,
- CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID,
- CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
- CLOSURE_BSDF_PHONG_RAMP_ID,
- CLOSURE_BSDF_GLOSSY_TOON_ID,
- CLOSURE_BSDF_HAIR_REFLECTION_ID,
-
- /* Transmission */
- CLOSURE_BSDF_TRANSLUCENT_ID,
- CLOSURE_BSDF_REFRACTION_ID,
- CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
- CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
- CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID,
- CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID,
- CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID,
- CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID,
- CLOSURE_BSDF_SHARP_GLASS_ID,
- CLOSURE_BSDF_HAIR_PRINCIPLED_ID,
- CLOSURE_BSDF_HAIR_TRANSMISSION_ID,
-
- /* Special cases */
- CLOSURE_BSDF_BSSRDF_ID,
- CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID,
- CLOSURE_BSDF_TRANSPARENT_ID,
-
- /* BSSRDF */
- CLOSURE_BSSRDF_CUBIC_ID,
- CLOSURE_BSSRDF_GAUSSIAN_ID,
- CLOSURE_BSSRDF_PRINCIPLED_ID,
- CLOSURE_BSSRDF_BURLEY_ID,
- CLOSURE_BSSRDF_RANDOM_WALK_ID,
- CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID,
-
- /* Other */
- CLOSURE_HOLDOUT_ID,
-
- /* Volume */
- CLOSURE_VOLUME_ID,
- CLOSURE_VOLUME_ABSORPTION_ID,
- CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID,
-
- CLOSURE_BSDF_PRINCIPLED_ID,
-
- NBUILTIN_CLOSURES
+ /* Special type, flags generic node as a non-BSDF. */
+ CLOSURE_NONE_ID,
+
+ CLOSURE_BSDF_ID,
+
+ /* Diffuse */
+ CLOSURE_BSDF_DIFFUSE_ID,
+ CLOSURE_BSDF_OREN_NAYAR_ID,
+ CLOSURE_BSDF_DIFFUSE_RAMP_ID,
+ CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID,
+ CLOSURE_BSDF_PRINCIPLED_SHEEN_ID,
+ CLOSURE_BSDF_DIFFUSE_TOON_ID,
+
+ /* Glossy */
+ CLOSURE_BSDF_REFLECTION_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID,
+ CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
+ CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID,
+ CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID,
+ CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID,
+ CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID,
+ CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_FRESNEL_ID,
+ CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID,
+ CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID,
+ CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
+ CLOSURE_BSDF_PHONG_RAMP_ID,
+ CLOSURE_BSDF_GLOSSY_TOON_ID,
+ CLOSURE_BSDF_HAIR_REFLECTION_ID,
+
+ /* Transmission */
+ CLOSURE_BSDF_TRANSLUCENT_ID,
+ CLOSURE_BSDF_REFRACTION_ID,
+ CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
+ CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID,
+ CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID,
+ CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID,
+ CLOSURE_BSDF_SHARP_GLASS_ID,
+ CLOSURE_BSDF_HAIR_PRINCIPLED_ID,
+ CLOSURE_BSDF_HAIR_TRANSMISSION_ID,
+
+ /* Special cases */
+ CLOSURE_BSDF_BSSRDF_ID,
+ CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID,
+ CLOSURE_BSDF_TRANSPARENT_ID,
+
+ /* BSSRDF */
+ CLOSURE_BSSRDF_CUBIC_ID,
+ CLOSURE_BSSRDF_GAUSSIAN_ID,
+ CLOSURE_BSSRDF_PRINCIPLED_ID,
+ CLOSURE_BSSRDF_BURLEY_ID,
+ CLOSURE_BSSRDF_RANDOM_WALK_ID,
+ CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID,
+
+ /* Other */
+ CLOSURE_HOLDOUT_ID,
+
+ /* Volume */
+ CLOSURE_VOLUME_ID,
+ CLOSURE_VOLUME_ABSORPTION_ID,
+ CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID,
+
+ CLOSURE_BSDF_PRINCIPLED_ID,
+
+ NBUILTIN_CLOSURES
} ClosureType;
/* watch this, being lazy with memory usage */
#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID)
-#define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)
-#define CLOSURE_IS_BSDF_GLOSSY(type) ((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID )|| (type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID))
-#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
-#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID)
-#define CLOSURE_IS_BSDF_SINGULAR(type) (type == CLOSURE_BSDF_REFLECTION_ID || \
- type == CLOSURE_BSDF_REFRACTION_ID || \
- type == CLOSURE_BSDF_TRANSPARENT_ID)
+#define CLOSURE_IS_BSDF_DIFFUSE(type) \
+ (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)
+#define CLOSURE_IS_BSDF_GLOSSY(type) \
+ ((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID) || \
+ (type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID))
+#define CLOSURE_IS_BSDF_TRANSMISSION(type) \
+ (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
+#define CLOSURE_IS_BSDF_BSSRDF(type) \
+ (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID)
+#define CLOSURE_IS_BSDF_SINGULAR(type) \
+ (type == CLOSURE_BSDF_REFLECTION_ID || type == CLOSURE_BSDF_REFRACTION_ID || \
+ type == CLOSURE_BSDF_TRANSPARENT_ID)
#define CLOSURE_IS_BSDF_TRANSPARENT(type) (type == CLOSURE_BSDF_TRANSPARENT_ID)
-#define CLOSURE_IS_BSDF_MULTISCATTER(type) (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID ||\
- type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \
- type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
-#define CLOSURE_IS_BSDF_MICROFACET(type) ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) ||\
- (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) ||\
- (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID))
+#define CLOSURE_IS_BSDF_MULTISCATTER(type) \
+ (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID || \
+ type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \
+ type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
+#define CLOSURE_IS_BSDF_MICROFACET(type) \
+ ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) || \
+ (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && \
+ type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) || \
+ (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID))
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
-#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
-#define CLOSURE_IS_DISK_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID)
-#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
+#define CLOSURE_IS_BSSRDF(type) \
+ (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
+#define CLOSURE_IS_DISK_BSSRDF(type) \
+ (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID)
+#define CLOSURE_IS_VOLUME(type) \
+ (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
#define CLOSURE_IS_VOLUME_SCATTER(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
#define CLOSURE_IS_VOLUME_ABSORPTION(type) (type == CLOSURE_VOLUME_ABSORPTION_ID)
#define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
#define CLOSURE_IS_PHASE(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
-#define CLOSURE_IS_GLASS(type) (type >= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID)
+#define CLOSURE_IS_GLASS(type) \
+ (type >= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID)
#define CLOSURE_IS_PRINCIPLED(type) (type == CLOSURE_BSDF_PRINCIPLED_ID)
#define CLOSURE_WEIGHT_CUTOFF 1e-5f
CCL_NAMESPACE_END
-#endif /* __SVM_TYPES_H__ */
+#endif /* __SVM_TYPES_H__ */
diff --git a/intern/cycles/kernel/svm/svm_value.h b/intern/cycles/kernel/svm/svm_value.h
index 062aee2956e..5b76f2c8832 100644
--- a/intern/cycles/kernel/svm/svm_value.h
+++ b/intern/cycles/kernel/svm/svm_value.h
@@ -18,18 +18,21 @@ CCL_NAMESPACE_BEGIN
/* Value Nodes */
-ccl_device void svm_node_value_f(KernelGlobals *kg, ShaderData *sd, float *stack, uint ivalue, uint out_offset)
+ccl_device void svm_node_value_f(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint ivalue, uint out_offset)
{
- stack_store_float(stack, out_offset, __uint_as_float(ivalue));
+ stack_store_float(stack, out_offset, __uint_as_float(ivalue));
}
-ccl_device void svm_node_value_v(KernelGlobals *kg, ShaderData *sd, float *stack, uint out_offset, int *offset)
+ccl_device void svm_node_value_v(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint out_offset, int *offset)
{
- /* read extra data */
- uint4 node1 = read_node(kg, offset);
- float3 p = make_float3(__uint_as_float(node1.y), __uint_as_float(node1.z), __uint_as_float(node1.w));
+ /* read extra data */
+ uint4 node1 = read_node(kg, offset);
+ float3 p = make_float3(
+ __uint_as_float(node1.y), __uint_as_float(node1.z), __uint_as_float(node1.w));
- stack_store_float3(stack, out_offset, p);
+ stack_store_float3(stack, out_offset, p);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_vector_transform.h b/intern/cycles/kernel/svm/svm_vector_transform.h
index f6ec36ba41f..7ec0f07f2e4 100644
--- a/intern/cycles/kernel/svm/svm_vector_transform.h
+++ b/intern/cycles/kernel/svm/svm_vector_transform.h
@@ -18,83 +18,90 @@ CCL_NAMESPACE_BEGIN
/* Vector Transform */
-ccl_device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
+ccl_device void svm_node_vector_transform(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint4 node)
{
- uint itype, ifrom, ito;
- uint vector_in, vector_out;
+ uint itype, ifrom, ito;
+ uint vector_in, vector_out;
- decode_node_uchar4(node.y, &itype, &ifrom, &ito, NULL);
- decode_node_uchar4(node.z, &vector_in, &vector_out, NULL, NULL);
+ decode_node_uchar4(node.y, &itype, &ifrom, &ito, NULL);
+ decode_node_uchar4(node.z, &vector_in, &vector_out, NULL, NULL);
- float3 in = stack_load_float3(stack, vector_in);
+ float3 in = stack_load_float3(stack, vector_in);
- NodeVectorTransformType type = (NodeVectorTransformType)itype;
- NodeVectorTransformConvertSpace from = (NodeVectorTransformConvertSpace)ifrom;
- NodeVectorTransformConvertSpace to = (NodeVectorTransformConvertSpace)ito;
+ NodeVectorTransformType type = (NodeVectorTransformType)itype;
+ NodeVectorTransformConvertSpace from = (NodeVectorTransformConvertSpace)ifrom;
+ NodeVectorTransformConvertSpace to = (NodeVectorTransformConvertSpace)ito;
- Transform tfm;
- bool is_object = (sd->object != OBJECT_NONE);
- bool is_direction = (type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR || type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
+ Transform tfm;
+ bool is_object = (sd->object != OBJECT_NONE);
+ bool is_direction = (type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR ||
+ type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
- /* From world */
- if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD) {
- if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) {
- tfm = kernel_data.cam.worldtocamera;
- if(is_direction)
- in = transform_direction(&tfm, in);
- else
- in = transform_point(&tfm, in);
- }
- else if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) {
- if(is_direction)
- object_inverse_dir_transform(kg, sd, &in);
- else
- object_inverse_position_transform(kg, sd, &in);
- }
- }
+ /* From world */
+ if (from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD) {
+ if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) {
+ tfm = kernel_data.cam.worldtocamera;
+ if (is_direction)
+ in = transform_direction(&tfm, in);
+ else
+ in = transform_point(&tfm, in);
+ }
+ else if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) {
+ if (is_direction)
+ object_inverse_dir_transform(kg, sd, &in);
+ else
+ object_inverse_position_transform(kg, sd, &in);
+ }
+ }
- /* From camera */
- else if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) {
- if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) {
- tfm = kernel_data.cam.cameratoworld;
- if(is_direction)
- in = transform_direction(&tfm, in);
- else
- in = transform_point(&tfm, in);
- }
- if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) {
- if(is_direction)
- object_inverse_dir_transform(kg, sd, &in);
- else
- object_inverse_position_transform(kg, sd, &in);
- }
- }
+ /* From camera */
+ else if (from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) {
+ if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD ||
+ to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) {
+ tfm = kernel_data.cam.cameratoworld;
+ if (is_direction)
+ in = transform_direction(&tfm, in);
+ else
+ in = transform_point(&tfm, in);
+ }
+ if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) {
+ if (is_direction)
+ object_inverse_dir_transform(kg, sd, &in);
+ else
+ object_inverse_position_transform(kg, sd, &in);
+ }
+ }
- /* From object */
- else if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) {
- if((to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) && is_object) {
- if(is_direction)
- object_dir_transform(kg, sd, &in);
- else
- object_position_transform(kg, sd, &in);
- }
- if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) {
- tfm = kernel_data.cam.worldtocamera;
- if(is_direction)
- in = transform_direction(&tfm, in);
- else
- in = transform_point(&tfm, in);
- }
- }
+ /* From object */
+ else if (from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) {
+ if ((to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD ||
+ to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) &&
+ is_object) {
+ if (is_direction)
+ object_dir_transform(kg, sd, &in);
+ else
+ object_position_transform(kg, sd, &in);
+ }
+ if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) {
+ tfm = kernel_data.cam.worldtocamera;
+ if (is_direction)
+ in = transform_direction(&tfm, in);
+ else
+ in = transform_point(&tfm, in);
+ }
+ }
- /* Normalize Normal */
- if(type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL)
- in = normalize(in);
+ /* Normalize Normal */
+ if (type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL)
+ in = normalize(in);
- /* Output */
- if(stack_valid(vector_out)) {
- stack_store_float3(stack, vector_out, in);
- }
+ /* Output */
+ if (stack_valid(vector_out)) {
+ stack_store_float3(stack, vector_out, in);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h
index d661df54ead..c311aefaf38 100644
--- a/intern/cycles/kernel/svm/svm_voronoi.h
+++ b/intern/cycles/kernel/svm/svm_voronoi.h
@@ -18,143 +18,167 @@ CCL_NAMESPACE_BEGIN
/* Voronoi */
-ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, float e, float da[4], float3 pa[4])
+ccl_device void voronoi_neighbors(
+ float3 p, NodeVoronoiDistanceMetric distance, float e, float da[4], float3 pa[4])
{
- /* Compute the distance to and the position of the closest neighbors to p.
- *
- * The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern).
- * The distances and points are returned in ascending order, i.e. da[0] and pa[0] will
- * contain the distance to the closest point and its coordinates respectively.
- */
-
- da[0] = 1e10f;
- da[1] = 1e10f;
- da[2] = 1e10f;
- da[3] = 1e10f;
-
- pa[0] = make_float3(0.0f, 0.0f, 0.0f);
- pa[1] = make_float3(0.0f, 0.0f, 0.0f);
- pa[2] = make_float3(0.0f, 0.0f, 0.0f);
- pa[3] = make_float3(0.0f, 0.0f, 0.0f);
-
- int3 xyzi = quick_floor_to_int3(p);
-
- for(int xx = -1; xx <= 1; xx++) {
- for(int yy = -1; yy <= 1; yy++) {
- for(int zz = -1; zz <= 1; zz++) {
- int3 ip = xyzi + make_int3(xx, yy, zz);
- float3 fp = make_float3(ip.x, ip.y, ip.z);
- float3 vp = fp + cellnoise3(fp);
-
- float d;
- switch(distance) {
- case NODE_VORONOI_DISTANCE:
- d = len_squared(p - vp);
- break;
- case NODE_VORONOI_MANHATTAN:
- d = reduce_add(fabs(vp - p));
- break;
- case NODE_VORONOI_CHEBYCHEV:
- d = max3(fabs(vp - p));
- break;
- case NODE_VORONOI_MINKOWSKI: {
- float3 n = fabs(vp - p);
- if(e == 0.5f) {
- d = sqr(reduce_add(sqrt(n)));
- }
- else {
- d = powf(reduce_add(pow3(n, e)), 1.0f/e);
- }
- break;
- }
- }
-
- /* To keep the shortest four distances and associated points we have to keep them in sorted order. */
- if(d < da[0]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = da[0];
- da[0] = d;
-
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = pa[0];
- pa[0] = vp;
- }
- else if(d < da[1]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = d;
-
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = vp;
- }
- else if(d < da[2]) {
- da[3] = da[2];
- da[2] = d;
-
- pa[3] = pa[2];
- pa[2] = vp;
- }
- else if(d < da[3]) {
- da[3] = d;
- pa[3] = vp;
- }
- }
- }
- }
+ /* Compute the distance to and the position of the closest neighbors to p.
+ *
+ * The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern).
+ * The distances and points are returned in ascending order, i.e. da[0] and pa[0] will
+ * contain the distance to the closest point and its coordinates respectively.
+ */
+
+ da[0] = 1e10f;
+ da[1] = 1e10f;
+ da[2] = 1e10f;
+ da[3] = 1e10f;
+
+ pa[0] = make_float3(0.0f, 0.0f, 0.0f);
+ pa[1] = make_float3(0.0f, 0.0f, 0.0f);
+ pa[2] = make_float3(0.0f, 0.0f, 0.0f);
+ pa[3] = make_float3(0.0f, 0.0f, 0.0f);
+
+ int3 xyzi = quick_floor_to_int3(p);
+
+ for (int xx = -1; xx <= 1; xx++) {
+ for (int yy = -1; yy <= 1; yy++) {
+ for (int zz = -1; zz <= 1; zz++) {
+ int3 ip = xyzi + make_int3(xx, yy, zz);
+ float3 fp = make_float3(ip.x, ip.y, ip.z);
+ float3 vp = fp + cellnoise3(fp);
+
+ float d;
+ switch (distance) {
+ case NODE_VORONOI_DISTANCE:
+ d = len_squared(p - vp);
+ break;
+ case NODE_VORONOI_MANHATTAN:
+ d = reduce_add(fabs(vp - p));
+ break;
+ case NODE_VORONOI_CHEBYCHEV:
+ d = max3(fabs(vp - p));
+ break;
+ case NODE_VORONOI_MINKOWSKI: {
+ float3 n = fabs(vp - p);
+ if (e == 0.5f) {
+ d = sqr(reduce_add(sqrt(n)));
+ }
+ else {
+ d = powf(reduce_add(pow3(n, e)), 1.0f / e);
+ }
+ break;
+ }
+ }
+
+ /* To keep the shortest four distances and associated points we have to keep them in sorted order. */
+ if (d < da[0]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = da[0];
+ da[0] = d;
+
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = pa[0];
+ pa[0] = vp;
+ }
+ else if (d < da[1]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = d;
+
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = vp;
+ }
+ else if (d < da[2]) {
+ da[3] = da[2];
+ da[2] = d;
+
+ pa[3] = pa[2];
+ pa[2] = vp;
+ }
+ else if (d < da[3]) {
+ da[3] = d;
+ pa[3] = vp;
+ }
+ }
+ }
+ }
}
-ccl_device void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_tex_voronoi(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint4 node2 = read_node(kg, offset);
-
- uint co_offset, coloring, distance, feature;
- uint scale_offset, e_offset, fac_offset, color_offset;
-
- decode_node_uchar4(node.y, &co_offset, &coloring, &distance, &feature);
- decode_node_uchar4(node.z, &scale_offset, &e_offset, &fac_offset, &color_offset);
-
- float3 co = stack_load_float3(stack, co_offset);
- float scale = stack_load_float_default(stack, scale_offset, node2.x);
- float exponent = stack_load_float_default(stack, e_offset, node2.y);
-
- float dist[4];
- float3 neighbor[4];
- voronoi_neighbors(co*scale, (NodeVoronoiDistanceMetric)distance, exponent, dist, neighbor);
-
- float3 color;
- float fac;
- if(coloring == NODE_VORONOI_INTENSITY) {
- switch(feature) {
- case NODE_VORONOI_F1: fac = dist[0]; break;
- case NODE_VORONOI_F2: fac = dist[1]; break;
- case NODE_VORONOI_F3: fac = dist[2]; break;
- case NODE_VORONOI_F4: fac = dist[3]; break;
- case NODE_VORONOI_F2F1: fac = dist[1] - dist[0]; break;
- }
-
- color = make_float3(fac, fac, fac);
- }
- else {
- /* NODE_VORONOI_CELLS */
- switch(feature) {
- case NODE_VORONOI_F1: color = neighbor[0]; break;
- case NODE_VORONOI_F2: color = neighbor[1]; break;
- case NODE_VORONOI_F3: color = neighbor[2]; break;
- case NODE_VORONOI_F4: color = neighbor[3]; break;
- /* Usefulness of this vector is questionable. Note F2 >= F1 but the
- * individual vector components might not be. */
- case NODE_VORONOI_F2F1: color = fabs(neighbor[1] - neighbor[0]); break;
- }
-
- color = cellnoise3(color);
- fac = average(color);
- }
-
- if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, fac);
- if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, color);
+ uint4 node2 = read_node(kg, offset);
+
+ uint co_offset, coloring, distance, feature;
+ uint scale_offset, e_offset, fac_offset, color_offset;
+
+ decode_node_uchar4(node.y, &co_offset, &coloring, &distance, &feature);
+ decode_node_uchar4(node.z, &scale_offset, &e_offset, &fac_offset, &color_offset);
+
+ float3 co = stack_load_float3(stack, co_offset);
+ float scale = stack_load_float_default(stack, scale_offset, node2.x);
+ float exponent = stack_load_float_default(stack, e_offset, node2.y);
+
+ float dist[4];
+ float3 neighbor[4];
+ voronoi_neighbors(co * scale, (NodeVoronoiDistanceMetric)distance, exponent, dist, neighbor);
+
+ float3 color;
+ float fac;
+ if (coloring == NODE_VORONOI_INTENSITY) {
+ switch (feature) {
+ case NODE_VORONOI_F1:
+ fac = dist[0];
+ break;
+ case NODE_VORONOI_F2:
+ fac = dist[1];
+ break;
+ case NODE_VORONOI_F3:
+ fac = dist[2];
+ break;
+ case NODE_VORONOI_F4:
+ fac = dist[3];
+ break;
+ case NODE_VORONOI_F2F1:
+ fac = dist[1] - dist[0];
+ break;
+ }
+
+ color = make_float3(fac, fac, fac);
+ }
+ else {
+ /* NODE_VORONOI_CELLS */
+ switch (feature) {
+ case NODE_VORONOI_F1:
+ color = neighbor[0];
+ break;
+ case NODE_VORONOI_F2:
+ color = neighbor[1];
+ break;
+ case NODE_VORONOI_F3:
+ color = neighbor[2];
+ break;
+ case NODE_VORONOI_F4:
+ color = neighbor[3];
+ break;
+ /* Usefulness of this vector is questionable. Note F2 >= F1 but the
+ * individual vector components might not be. */
+ case NODE_VORONOI_F2F1:
+ color = fabs(neighbor[1] - neighbor[0]);
+ break;
+ }
+
+ color = cellnoise3(color);
+ fac = average(color);
+ }
+
+ if (stack_valid(fac_offset))
+ stack_store_float(stack, fac_offset, fac);
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, color);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h
index 43b433683e0..26d8cc71d3b 100644
--- a/intern/cycles/kernel/svm/svm_voxel.h
+++ b/intern/cycles/kernel/svm/svm_voxel.h
@@ -19,37 +19,34 @@ CCL_NAMESPACE_BEGIN
/* TODO(sergey): Think of making it more generic volume-type attribute
* sampler.
*/
-ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
- ShaderData *sd,
- float *stack,
- uint4 node,
- int *offset)
+ccl_device void svm_node_tex_voxel(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint co_offset, density_out_offset, color_out_offset, space;
- decode_node_uchar4(node.z, &co_offset, &density_out_offset, &color_out_offset, &space);
+ uint co_offset, density_out_offset, color_out_offset, space;
+ decode_node_uchar4(node.z, &co_offset, &density_out_offset, &color_out_offset, &space);
#ifdef __VOLUME__
- int id = node.y;
- float3 co = stack_load_float3(stack, co_offset);
- if(space == NODE_TEX_VOXEL_SPACE_OBJECT) {
- co = volume_normalized_position(kg, sd, co);
- }
- else {
- kernel_assert(space == NODE_TEX_VOXEL_SPACE_WORLD);
- Transform tfm;
- tfm.x = read_node_float(kg, offset);
- tfm.y = read_node_float(kg, offset);
- tfm.z = read_node_float(kg, offset);
- co = transform_point(&tfm, co);
- }
+ int id = node.y;
+ float3 co = stack_load_float3(stack, co_offset);
+ if (space == NODE_TEX_VOXEL_SPACE_OBJECT) {
+ co = volume_normalized_position(kg, sd, co);
+ }
+ else {
+ kernel_assert(space == NODE_TEX_VOXEL_SPACE_WORLD);
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
+ co = transform_point(&tfm, co);
+ }
- float4 r = kernel_tex_image_interp_3d(kg, id, co.x, co.y, co.z, INTERPOLATION_NONE);
+ float4 r = kernel_tex_image_interp_3d(kg, id, co.x, co.y, co.z, INTERPOLATION_NONE);
#else
- float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
#endif
- if(stack_valid(density_out_offset))
- stack_store_float(stack, density_out_offset, r.w);
- if(stack_valid(color_out_offset))
- stack_store_float3(stack, color_out_offset, make_float3(r.x, r.y, r.z));
+ if (stack_valid(density_out_offset))
+ stack_store_float(stack, density_out_offset, r.w);
+ if (stack_valid(color_out_offset))
+ stack_store_float3(stack, color_out_offset, make_float3(r.x, r.y, r.z));
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_wave.h b/intern/cycles/kernel/svm/svm_wave.h
index 80b63dc80cd..003ad7dc63a 100644
--- a/intern/cycles/kernel/svm/svm_wave.h
+++ b/intern/cycles/kernel/svm/svm_wave.h
@@ -18,48 +18,58 @@ CCL_NAMESPACE_BEGIN
/* Wave */
-ccl_device_noinline float svm_wave(NodeWaveType type, NodeWaveProfile profile, float3 p, float detail, float distortion, float dscale)
+ccl_device_noinline float svm_wave(NodeWaveType type,
+ NodeWaveProfile profile,
+ float3 p,
+ float detail,
+ float distortion,
+ float dscale)
{
- float n;
+ float n;
- if(type == NODE_WAVE_BANDS)
- n = (p.x + p.y + p.z) * 10.0f;
- else /* NODE_WAVE_RINGS */
- n = len(p) * 20.0f;
+ if (type == NODE_WAVE_BANDS)
+ n = (p.x + p.y + p.z) * 10.0f;
+ else /* NODE_WAVE_RINGS */
+ n = len(p) * 20.0f;
- if(distortion != 0.0f)
- n += distortion * noise_turbulence(p*dscale, detail, 0);
+ if (distortion != 0.0f)
+ n += distortion * noise_turbulence(p * dscale, detail, 0);
- if(profile == NODE_WAVE_PROFILE_SIN) {
- return 0.5f + 0.5f * sinf(n);
- }
- else { /* NODE_WAVE_PROFILE_SAW */
- n /= M_2PI_F;
- n -= (int) n;
- return (n < 0.0f)? n + 1.0f: n;
- }
+ if (profile == NODE_WAVE_PROFILE_SIN) {
+ return 0.5f + 0.5f * sinf(n);
+ }
+ else { /* NODE_WAVE_PROFILE_SAW */
+ n /= M_2PI_F;
+ n -= (int)n;
+ return (n < 0.0f) ? n + 1.0f : n;
+ }
}
-ccl_device void svm_node_tex_wave(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+ccl_device void svm_node_tex_wave(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint4 node2 = read_node(kg, offset);
+ uint4 node2 = read_node(kg, offset);
- uint type;
- uint co_offset, scale_offset, detail_offset, dscale_offset, distortion_offset, color_offset, fac_offset;
+ uint type;
+ uint co_offset, scale_offset, detail_offset, dscale_offset, distortion_offset, color_offset,
+ fac_offset;
- decode_node_uchar4(node.y, &type, &color_offset, &fac_offset, &dscale_offset);
- decode_node_uchar4(node.z, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
+ decode_node_uchar4(node.y, &type, &color_offset, &fac_offset, &dscale_offset);
+ decode_node_uchar4(node.z, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
- float3 co = stack_load_float3(stack, co_offset);
- float scale = stack_load_float_default(stack, scale_offset, node2.x);
- float detail = stack_load_float_default(stack, detail_offset, node2.y);
- float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
- float dscale = stack_load_float_default(stack, dscale_offset, node2.w);
+ float3 co = stack_load_float3(stack, co_offset);
+ float scale = stack_load_float_default(stack, scale_offset, node2.x);
+ float detail = stack_load_float_default(stack, detail_offset, node2.y);
+ float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
+ float dscale = stack_load_float_default(stack, dscale_offset, node2.w);
- float f = svm_wave((NodeWaveType)type, (NodeWaveProfile)node.w, co*scale, detail, distortion, dscale);
+ float f = svm_wave(
+ (NodeWaveType)type, (NodeWaveProfile)node.w, co * scale, detail, distortion, dscale);
- if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f);
- if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, make_float3(f, f, f));
+ if (stack_valid(fac_offset))
+ stack_store_float(stack, fac_offset, f);
+ if (stack_valid(color_offset))
+ stack_store_float3(stack, color_offset, make_float3(f, f, f));
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h
index e935fd20690..d6144802559 100644
--- a/intern/cycles/kernel/svm/svm_wavelength.h
+++ b/intern/cycles/kernel/svm/svm_wavelength.h
@@ -10,13 +10,13 @@
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* * Neither the name of Sony Pictures Imageworks nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,64 +35,64 @@ CCL_NAMESPACE_BEGIN
/* Wavelength to RGB */
// CIE colour matching functions xBar, yBar, and zBar for
-// wavelengths from 380 through 780 nanometers, every 5
-// nanometers. For a wavelength lambda in this range:
-// cie_colour_match[(lambda - 380) / 5][0] = xBar
-// cie_colour_match[(lambda - 380) / 5][1] = yBar
-// cie_colour_match[(lambda - 380) / 5][2] = zBar
+// wavelengths from 380 through 780 nanometers, every 5
+// nanometers. For a wavelength lambda in this range:
+// cie_colour_match[(lambda - 380) / 5][0] = xBar
+// cie_colour_match[(lambda - 380) / 5][1] = yBar
+// cie_colour_match[(lambda - 380) / 5][2] = zBar
ccl_static_constant float cie_colour_match[81][3] = {
- {0.0014f,0.0000f,0.0065f}, {0.0022f,0.0001f,0.0105f}, {0.0042f,0.0001f,0.0201f},
- {0.0076f,0.0002f,0.0362f}, {0.0143f,0.0004f,0.0679f}, {0.0232f,0.0006f,0.1102f},
- {0.0435f,0.0012f,0.2074f}, {0.0776f,0.0022f,0.3713f}, {0.1344f,0.0040f,0.6456f},
- {0.2148f,0.0073f,1.0391f}, {0.2839f,0.0116f,1.3856f}, {0.3285f,0.0168f,1.6230f},
- {0.3483f,0.0230f,1.7471f}, {0.3481f,0.0298f,1.7826f}, {0.3362f,0.0380f,1.7721f},
- {0.3187f,0.0480f,1.7441f}, {0.2908f,0.0600f,1.6692f}, {0.2511f,0.0739f,1.5281f},
- {0.1954f,0.0910f,1.2876f}, {0.1421f,0.1126f,1.0419f}, {0.0956f,0.1390f,0.8130f},
- {0.0580f,0.1693f,0.6162f}, {0.0320f,0.2080f,0.4652f}, {0.0147f,0.2586f,0.3533f},
- {0.0049f,0.3230f,0.2720f}, {0.0024f,0.4073f,0.2123f}, {0.0093f,0.5030f,0.1582f},
- {0.0291f,0.6082f,0.1117f}, {0.0633f,0.7100f,0.0782f}, {0.1096f,0.7932f,0.0573f},
- {0.1655f,0.8620f,0.0422f}, {0.2257f,0.9149f,0.0298f}, {0.2904f,0.9540f,0.0203f},
- {0.3597f,0.9803f,0.0134f}, {0.4334f,0.9950f,0.0087f}, {0.5121f,1.0000f,0.0057f},
- {0.5945f,0.9950f,0.0039f}, {0.6784f,0.9786f,0.0027f}, {0.7621f,0.9520f,0.0021f},
- {0.8425f,0.9154f,0.0018f}, {0.9163f,0.8700f,0.0017f}, {0.9786f,0.8163f,0.0014f},
- {1.0263f,0.7570f,0.0011f}, {1.0567f,0.6949f,0.0010f}, {1.0622f,0.6310f,0.0008f},
- {1.0456f,0.5668f,0.0006f}, {1.0026f,0.5030f,0.0003f}, {0.9384f,0.4412f,0.0002f},
- {0.8544f,0.3810f,0.0002f}, {0.7514f,0.3210f,0.0001f}, {0.6424f,0.2650f,0.0000f},
- {0.5419f,0.2170f,0.0000f}, {0.4479f,0.1750f,0.0000f}, {0.3608f,0.1382f,0.0000f},
- {0.2835f,0.1070f,0.0000f}, {0.2187f,0.0816f,0.0000f}, {0.1649f,0.0610f,0.0000f},
- {0.1212f,0.0446f,0.0000f}, {0.0874f,0.0320f,0.0000f}, {0.0636f,0.0232f,0.0000f},
- {0.0468f,0.0170f,0.0000f}, {0.0329f,0.0119f,0.0000f}, {0.0227f,0.0082f,0.0000f},
- {0.0158f,0.0057f,0.0000f}, {0.0114f,0.0041f,0.0000f}, {0.0081f,0.0029f,0.0000f},
- {0.0058f,0.0021f,0.0000f}, {0.0041f,0.0015f,0.0000f}, {0.0029f,0.0010f,0.0000f},
- {0.0020f,0.0007f,0.0000f}, {0.0014f,0.0005f,0.0000f}, {0.0010f,0.0004f,0.0000f},
- {0.0007f,0.0002f,0.0000f}, {0.0005f,0.0002f,0.0000f}, {0.0003f,0.0001f,0.0000f},
- {0.0002f,0.0001f,0.0000f}, {0.0002f,0.0001f,0.0000f}, {0.0001f,0.0000f,0.0000f},
- {0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0000f,0.0000f,0.0000f}
-};
+ {0.0014f, 0.0000f, 0.0065f}, {0.0022f, 0.0001f, 0.0105f}, {0.0042f, 0.0001f, 0.0201f},
+ {0.0076f, 0.0002f, 0.0362f}, {0.0143f, 0.0004f, 0.0679f}, {0.0232f, 0.0006f, 0.1102f},
+ {0.0435f, 0.0012f, 0.2074f}, {0.0776f, 0.0022f, 0.3713f}, {0.1344f, 0.0040f, 0.6456f},
+ {0.2148f, 0.0073f, 1.0391f}, {0.2839f, 0.0116f, 1.3856f}, {0.3285f, 0.0168f, 1.6230f},
+ {0.3483f, 0.0230f, 1.7471f}, {0.3481f, 0.0298f, 1.7826f}, {0.3362f, 0.0380f, 1.7721f},
+ {0.3187f, 0.0480f, 1.7441f}, {0.2908f, 0.0600f, 1.6692f}, {0.2511f, 0.0739f, 1.5281f},
+ {0.1954f, 0.0910f, 1.2876f}, {0.1421f, 0.1126f, 1.0419f}, {0.0956f, 0.1390f, 0.8130f},
+ {0.0580f, 0.1693f, 0.6162f}, {0.0320f, 0.2080f, 0.4652f}, {0.0147f, 0.2586f, 0.3533f},
+ {0.0049f, 0.3230f, 0.2720f}, {0.0024f, 0.4073f, 0.2123f}, {0.0093f, 0.5030f, 0.1582f},
+ {0.0291f, 0.6082f, 0.1117f}, {0.0633f, 0.7100f, 0.0782f}, {0.1096f, 0.7932f, 0.0573f},
+ {0.1655f, 0.8620f, 0.0422f}, {0.2257f, 0.9149f, 0.0298f}, {0.2904f, 0.9540f, 0.0203f},
+ {0.3597f, 0.9803f, 0.0134f}, {0.4334f, 0.9950f, 0.0087f}, {0.5121f, 1.0000f, 0.0057f},
+ {0.5945f, 0.9950f, 0.0039f}, {0.6784f, 0.9786f, 0.0027f}, {0.7621f, 0.9520f, 0.0021f},
+ {0.8425f, 0.9154f, 0.0018f}, {0.9163f, 0.8700f, 0.0017f}, {0.9786f, 0.8163f, 0.0014f},
+ {1.0263f, 0.7570f, 0.0011f}, {1.0567f, 0.6949f, 0.0010f}, {1.0622f, 0.6310f, 0.0008f},
+ {1.0456f, 0.5668f, 0.0006f}, {1.0026f, 0.5030f, 0.0003f}, {0.9384f, 0.4412f, 0.0002f},
+ {0.8544f, 0.3810f, 0.0002f}, {0.7514f, 0.3210f, 0.0001f}, {0.6424f, 0.2650f, 0.0000f},
+ {0.5419f, 0.2170f, 0.0000f}, {0.4479f, 0.1750f, 0.0000f}, {0.3608f, 0.1382f, 0.0000f},
+ {0.2835f, 0.1070f, 0.0000f}, {0.2187f, 0.0816f, 0.0000f}, {0.1649f, 0.0610f, 0.0000f},
+ {0.1212f, 0.0446f, 0.0000f}, {0.0874f, 0.0320f, 0.0000f}, {0.0636f, 0.0232f, 0.0000f},
+ {0.0468f, 0.0170f, 0.0000f}, {0.0329f, 0.0119f, 0.0000f}, {0.0227f, 0.0082f, 0.0000f},
+ {0.0158f, 0.0057f, 0.0000f}, {0.0114f, 0.0041f, 0.0000f}, {0.0081f, 0.0029f, 0.0000f},
+ {0.0058f, 0.0021f, 0.0000f}, {0.0041f, 0.0015f, 0.0000f}, {0.0029f, 0.0010f, 0.0000f},
+ {0.0020f, 0.0007f, 0.0000f}, {0.0014f, 0.0005f, 0.0000f}, {0.0010f, 0.0004f, 0.0000f},
+ {0.0007f, 0.0002f, 0.0000f}, {0.0005f, 0.0002f, 0.0000f}, {0.0003f, 0.0001f, 0.0000f},
+ {0.0002f, 0.0001f, 0.0000f}, {0.0002f, 0.0001f, 0.0000f}, {0.0001f, 0.0000f, 0.0000f},
+ {0.0001f, 0.0000f, 0.0000f}, {0.0001f, 0.0000f, 0.0000f}, {0.0000f, 0.0000f, 0.0000f}};
-ccl_device void svm_node_wavelength(KernelGlobals *kg, ShaderData *sd, float *stack, uint wavelength, uint color_out)
+ccl_device void svm_node_wavelength(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint wavelength, uint color_out)
{
- float lambda_nm = stack_load_float(stack, wavelength);
- float ii = (lambda_nm-380.0f) * (1.0f/5.0f); // scaled 0..80
- int i = float_to_int(ii);
- float3 color;
+ float lambda_nm = stack_load_float(stack, wavelength);
+ float ii = (lambda_nm - 380.0f) * (1.0f / 5.0f); // scaled 0..80
+ int i = float_to_int(ii);
+ float3 color;
- if(i < 0 || i >= 80) {
- color = make_float3(0.0f, 0.0f, 0.0f);
- }
- else {
- ii -= i;
- ccl_constant float *c = cie_colour_match[i];
- color = interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii);
- }
+ if (i < 0 || i >= 80) {
+ color = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ else {
+ ii -= i;
+ ccl_constant float *c = cie_colour_match[i];
+ color = interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii);
+ }
- color = xyz_to_rgb(kg, color);
- color *= 1.0f/2.52f; // Empirical scale from lg to make all comps <= 1
+ color = xyz_to_rgb(kg, color);
+ color *= 1.0f / 2.52f; // Empirical scale from lg to make all comps <= 1
- /* Clamp to zero if values are smaller */
- color = max(color, make_float3(0.0f, 0.0f, 0.0f));
+ /* Clamp to zero if values are smaller */
+ color = max(color, make_float3(0.0f, 0.0f, 0.0f));
- stack_store_float3(stack, color_out, color);
+ stack_store_float3(stack, color_out, color);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h
index 35df9e8a0e7..55e61d0e8c7 100644
--- a/intern/cycles/kernel/svm/svm_wireframe.h
+++ b/intern/cycles/kernel/svm/svm_wireframe.h
@@ -34,103 +34,97 @@ CCL_NAMESPACE_BEGIN
/* Wireframe Node */
-ccl_device_inline float wireframe(KernelGlobals *kg,
- ShaderData *sd,
- float size,
- int pixel_size,
- float3 *P)
+ccl_device_inline float wireframe(
+ KernelGlobals *kg, ShaderData *sd, float size, int pixel_size, float3 *P)
{
#ifdef __HAIR__
- if(sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE)
+ if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE)
#else
- if(sd->prim != PRIM_NONE)
+ if (sd->prim != PRIM_NONE)
#endif
- {
- float3 Co[3];
- float pixelwidth = 1.0f;
+ {
+ float3 Co[3];
+ float pixelwidth = 1.0f;
- /* Triangles */
- int np = 3;
+ /* Triangles */
+ int np = 3;
- if(sd->type & PRIMITIVE_TRIANGLE)
- triangle_vertices(kg, sd->prim, Co);
- else
- motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, Co);
+ if (sd->type & PRIMITIVE_TRIANGLE)
+ triangle_vertices(kg, sd->prim, Co);
+ else
+ motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, Co);
- if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_position_transform(kg, sd, &Co[0]);
- object_position_transform(kg, sd, &Co[1]);
- object_position_transform(kg, sd, &Co[2]);
- }
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_position_transform(kg, sd, &Co[0]);
+ object_position_transform(kg, sd, &Co[1]);
+ object_position_transform(kg, sd, &Co[2]);
+ }
- if(pixel_size) {
- // Project the derivatives of P to the viewing plane defined
- // by I so we have a measure of how big is a pixel at this point
- float pixelwidth_x = len(sd->dP.dx - dot(sd->dP.dx, sd->I) * sd->I);
- float pixelwidth_y = len(sd->dP.dy - dot(sd->dP.dy, sd->I) * sd->I);
- // Take the average of both axis' length
- pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f;
- }
+ if (pixel_size) {
+ // Project the derivatives of P to the viewing plane defined
+ // by I so we have a measure of how big is a pixel at this point
+ float pixelwidth_x = len(sd->dP.dx - dot(sd->dP.dx, sd->I) * sd->I);
+ float pixelwidth_y = len(sd->dP.dy - dot(sd->dP.dy, sd->I) * sd->I);
+ // Take the average of both axis' length
+ pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f;
+ }
- // Use half the width as the neighbor face will render the
- // other half. And take the square for fast comparison
- pixelwidth *= 0.5f * size;
- pixelwidth *= pixelwidth;
- for(int i = 0; i < np; i++) {
- int i2 = i ? i - 1 : np - 1;
- float3 dir = *P - Co[i];
- float3 edge = Co[i] - Co[i2];
- float3 crs = cross(edge, dir);
- // At this point dot(crs, crs) / dot(edge, edge) is
- // the square of area / length(edge) == square of the
- // distance to the edge.
- if(dot(crs, crs) < (dot(edge, edge) * pixelwidth))
- return 1.0f;
- }
- }
- return 0.0f;
+ // Use half the width as the neighbor face will render the
+ // other half. And take the square for fast comparison
+ pixelwidth *= 0.5f * size;
+ pixelwidth *= pixelwidth;
+ for (int i = 0; i < np; i++) {
+ int i2 = i ? i - 1 : np - 1;
+ float3 dir = *P - Co[i];
+ float3 edge = Co[i] - Co[i2];
+ float3 crs = cross(edge, dir);
+ // At this point dot(crs, crs) / dot(edge, edge) is
+ // the square of area / length(edge) == square of the
+ // distance to the edge.
+ if (dot(crs, crs) < (dot(edge, edge) * pixelwidth))
+ return 1.0f;
+ }
+ }
+ return 0.0f;
}
-ccl_device void svm_node_wireframe(KernelGlobals *kg,
- ShaderData *sd,
- float *stack,
- uint4 node)
+ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
- uint in_size = node.y;
- uint out_fac = node.z;
- uint use_pixel_size, bump_offset;
- decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, NULL, NULL);
+ uint in_size = node.y;
+ uint out_fac = node.z;
+ uint use_pixel_size, bump_offset;
+ decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, NULL, NULL);
- /* Input Data */
- float size = stack_load_float(stack, in_size);
- int pixel_size = (int)use_pixel_size;
+ /* Input Data */
+ float size = stack_load_float(stack, in_size);
+ int pixel_size = (int)use_pixel_size;
- /* Calculate wireframe */
+ /* Calculate wireframe */
#ifdef __SPLIT_KERNEL__
- /* TODO(sergey): This is because sd is actually a global space,
- * which makes it difficult to re-use same wireframe() function.
- *
- * With OpenCL 2.0 it's possible to avoid this change, but for until
- * then we'll be living with such an exception.
- */
- float3 P = sd->P;
- float f = wireframe(kg, sd, size, pixel_size, &P);
+ /* TODO(sergey): This is because sd is actually a global space,
+ * which makes it difficult to re-use same wireframe() function.
+ *
+ * With OpenCL 2.0 it's possible to avoid this change, but for until
+ * then we'll be living with such an exception.
+ */
+ float3 P = sd->P;
+ float f = wireframe(kg, sd, size, pixel_size, &P);
#else
- float f = wireframe(kg, sd, size, pixel_size, &sd->P);
+ float f = wireframe(kg, sd, size, pixel_size, &sd->P);
#endif
- /* TODO(sergey): Think of faster way to calculate derivatives. */
- if(bump_offset == NODE_BUMP_OFFSET_DX) {
- float3 Px = sd->P - sd->dP.dx;
- f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx);
- }
- else if(bump_offset == NODE_BUMP_OFFSET_DY) {
- float3 Py = sd->P - sd->dP.dy;
- f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy);
- }
+ /* TODO(sergey): Think of faster way to calculate derivatives. */
+ if (bump_offset == NODE_BUMP_OFFSET_DX) {
+ float3 Px = sd->P - sd->dP.dx;
+ f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx);
+ }
+ else if (bump_offset == NODE_BUMP_OFFSET_DY) {
+ float3 Py = sd->P - sd->dP.dy;
+ f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy);
+ }
- if(stack_valid(out_fac))
- stack_store_float(stack, out_fac, f);
+ if (stack_valid(out_fac))
+ stack_store_float(stack, out_fac, f);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index 140fcb206dc..378957d21f4 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -1,86 +1,86 @@
set(INC
- ..
- ../../glew-mx
+ ..
+ ../../glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_DIR}
+ ${GLEW_INCLUDE_DIR}
)
set(SRC
- attribute.cpp
- background.cpp
- bake.cpp
- buffers.cpp
- camera.cpp
- constant_fold.cpp
- coverage.cpp
- denoising.cpp
- film.cpp
- graph.cpp
- image.cpp
- integrator.cpp
- light.cpp
- merge.cpp
- mesh.cpp
- mesh_displace.cpp
- mesh_subdivision.cpp
- mesh_volume.cpp
- nodes.cpp
- object.cpp
- osl.cpp
- particles.cpp
- curves.cpp
- scene.cpp
- session.cpp
- shader.cpp
- sobol.cpp
- stats.cpp
- svm.cpp
- tables.cpp
- tile.cpp
+ attribute.cpp
+ background.cpp
+ bake.cpp
+ buffers.cpp
+ camera.cpp
+ constant_fold.cpp
+ coverage.cpp
+ denoising.cpp
+ film.cpp
+ graph.cpp
+ image.cpp
+ integrator.cpp
+ light.cpp
+ merge.cpp
+ mesh.cpp
+ mesh_displace.cpp
+ mesh_subdivision.cpp
+ mesh_volume.cpp
+ nodes.cpp
+ object.cpp
+ osl.cpp
+ particles.cpp
+ curves.cpp
+ scene.cpp
+ session.cpp
+ shader.cpp
+ sobol.cpp
+ stats.cpp
+ svm.cpp
+ tables.cpp
+ tile.cpp
)
set(SRC_HEADERS
- attribute.h
- bake.h
- background.h
- buffers.h
- camera.h
- constant_fold.h
- coverage.h
- denoising.h
- film.h
- graph.h
- image.h
- integrator.h
- light.h
- merge.h
- mesh.h
- nodes.h
- object.h
- osl.h
- particles.h
- curves.h
- scene.h
- session.h
- shader.h
- sobol.h
- stats.h
- svm.h
- tables.h
- tile.h
+ attribute.h
+ bake.h
+ background.h
+ buffers.h
+ camera.h
+ constant_fold.h
+ coverage.h
+ denoising.h
+ film.h
+ graph.h
+ image.h
+ integrator.h
+ light.h
+ merge.h
+ mesh.h
+ nodes.h
+ object.h
+ osl.h
+ particles.h
+ curves.h
+ scene.h
+ session.h
+ shader.h
+ sobol.h
+ stats.h
+ svm.h
+ tables.h
+ tile.h
)
set(LIB
- cycles_bvh
+ cycles_bvh
)
if(WITH_CYCLES_OSL)
- list(APPEND LIB
- cycles_kernel_osl
- )
+ list(APPEND LIB
+ cycles_kernel_osl
+ )
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index f7788b6a490..dad6cb4fe6d 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -27,319 +27,316 @@ CCL_NAMESPACE_BEGIN
Attribute::~Attribute()
{
- /* for voxel data, we need to remove the image from the image manager */
- if(element == ATTR_ELEMENT_VOXEL) {
- VoxelAttribute *voxel_data = data_voxel();
+ /* for voxel data, we need to remove the image from the image manager */
+ if (element == ATTR_ELEMENT_VOXEL) {
+ VoxelAttribute *voxel_data = data_voxel();
- if(voxel_data && voxel_data->slot != -1) {
- voxel_data->manager->remove_image(voxel_data->slot);
- }
- }
+ if (voxel_data && voxel_data->slot != -1) {
+ voxel_data->manager->remove_image(voxel_data->slot);
+ }
+ }
}
void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
{
- name = name_;
- type = type_;
- element = element_;
- std = ATTR_STD_NONE;
- flags = 0;
+ name = name_;
+ type = type_;
+ element = element_;
+ std = ATTR_STD_NONE;
+ flags = 0;
- /* string and matrix not supported! */
- assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
- type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
- type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix ||
- type == TypeFloat2);
+ /* string and matrix not supported! */
+ assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
+ type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
+ type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix || type == TypeFloat2);
}
void Attribute::resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only)
{
- if(reserve_only) {
- buffer.reserve(buffer_size(mesh, prim));
- }
- else {
- buffer.resize(buffer_size(mesh, prim), 0);
- }
+ if (reserve_only) {
+ buffer.reserve(buffer_size(mesh, prim));
+ }
+ else {
+ buffer.resize(buffer_size(mesh, prim), 0);
+ }
}
void Attribute::resize(size_t num_elements)
{
- buffer.resize(num_elements * data_sizeof(), 0);
+ buffer.resize(num_elements * data_sizeof(), 0);
}
-void Attribute::add(const float& f)
+void Attribute::add(const float &f)
{
- assert(data_sizeof() == sizeof(float));
+ assert(data_sizeof() == sizeof(float));
- char *data = (char*)&f;
- size_t size = sizeof(f);
+ char *data = (char *)&f;
+ size_t size = sizeof(f);
- for(size_t i = 0; i < size; i++)
- buffer.push_back(data[i]);
+ for (size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
}
-void Attribute::add(const uchar4& f)
+void Attribute::add(const uchar4 &f)
{
- assert(data_sizeof() == sizeof(uchar4));
+ assert(data_sizeof() == sizeof(uchar4));
- char *data = (char*)&f;
- size_t size = sizeof(f);
+ char *data = (char *)&f;
+ size_t size = sizeof(f);
- for(size_t i = 0; i < size; i++)
- buffer.push_back(data[i]);
+ for (size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
}
-void Attribute::add(const float2& f)
+void Attribute::add(const float2 &f)
{
- assert(data_sizeof() == sizeof(float2));
+ assert(data_sizeof() == sizeof(float2));
- char *data = (char*)&f;
- size_t size = sizeof(f);
+ char *data = (char *)&f;
+ size_t size = sizeof(f);
- for(size_t i = 0; i < size; i++)
- buffer.push_back(data[i]);
+ for (size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
}
-void Attribute::add(const float3& f)
+void Attribute::add(const float3 &f)
{
- assert(data_sizeof() == sizeof(float3));
+ assert(data_sizeof() == sizeof(float3));
- char *data = (char*)&f;
- size_t size = sizeof(f);
+ char *data = (char *)&f;
+ size_t size = sizeof(f);
- for(size_t i = 0; i < size; i++)
- buffer.push_back(data[i]);
+ for (size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
}
-void Attribute::add(const Transform& f)
+void Attribute::add(const Transform &f)
{
- assert(data_sizeof() == sizeof(Transform));
+ assert(data_sizeof() == sizeof(Transform));
- char *data = (char*)&f;
- size_t size = sizeof(f);
+ char *data = (char *)&f;
+ size_t size = sizeof(f);
- for(size_t i = 0; i < size; i++)
- buffer.push_back(data[i]);
+ for (size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
}
-void Attribute::add(const VoxelAttribute& f)
+void Attribute::add(const VoxelAttribute &f)
{
- assert(data_sizeof() == sizeof(VoxelAttribute));
+ assert(data_sizeof() == sizeof(VoxelAttribute));
- char *data = (char*)&f;
- size_t size = sizeof(f);
+ char *data = (char *)&f;
+ size_t size = sizeof(f);
- for(size_t i = 0; i < size; i++)
- buffer.push_back(data[i]);
+ for (size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
}
void Attribute::add(const char *data)
{
- size_t size = data_sizeof();
+ size_t size = data_sizeof();
- for(size_t i = 0; i < size; i++)
- buffer.push_back(data[i]);
+ for (size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
}
size_t Attribute::data_sizeof() const
{
- if(element == ATTR_ELEMENT_VOXEL)
- return sizeof(VoxelAttribute);
- else if(element == ATTR_ELEMENT_CORNER_BYTE)
- return sizeof(uchar4);
- else if(type == TypeDesc::TypeFloat)
- return sizeof(float);
- else if(type == TypeFloat2)
- return sizeof(float2);
- else if(type == TypeDesc::TypeMatrix)
- return sizeof(Transform);
- else
- return sizeof(float3);
+ if (element == ATTR_ELEMENT_VOXEL)
+ return sizeof(VoxelAttribute);
+ else if (element == ATTR_ELEMENT_CORNER_BYTE)
+ return sizeof(uchar4);
+ else if (type == TypeDesc::TypeFloat)
+ return sizeof(float);
+ else if (type == TypeFloat2)
+ return sizeof(float2);
+ else if (type == TypeDesc::TypeMatrix)
+ return sizeof(Transform);
+ else
+ return sizeof(float3);
}
size_t Attribute::element_size(Mesh *mesh, AttributePrimitive prim) const
{
- if(flags & ATTR_FINAL_SIZE) {
- return buffer.size() / data_sizeof();
- }
-
- size_t size;
-
- switch(element) {
- case ATTR_ELEMENT_OBJECT:
- case ATTR_ELEMENT_MESH:
- case ATTR_ELEMENT_VOXEL:
- size = 1;
- break;
- case ATTR_ELEMENT_VERTEX:
- size = mesh->verts.size() + mesh->num_ngons;
- if(prim == ATTR_PRIM_SUBD) {
- size -= mesh->num_subd_verts;
- }
- break;
- case ATTR_ELEMENT_VERTEX_MOTION:
- size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1);
- if(prim == ATTR_PRIM_SUBD) {
- size -= mesh->num_subd_verts * (mesh->motion_steps - 1);
- }
- break;
- case ATTR_ELEMENT_FACE:
- if(prim == ATTR_PRIM_TRIANGLE) {
- size = mesh->num_triangles();
- }
- else {
- size = mesh->subd_faces.size() + mesh->num_ngons;
- }
- break;
- case ATTR_ELEMENT_CORNER:
- case ATTR_ELEMENT_CORNER_BYTE:
- if(prim == ATTR_PRIM_TRIANGLE) {
- size = mesh->num_triangles()*3;
- }
- else {
- size = mesh->subd_face_corners.size() + mesh->num_ngons;
- }
- break;
- case ATTR_ELEMENT_CURVE:
- size = mesh->num_curves();
- break;
- case ATTR_ELEMENT_CURVE_KEY:
- size = mesh->curve_keys.size();
- break;
- case ATTR_ELEMENT_CURVE_KEY_MOTION:
- size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
- break;
- default:
- size = 0;
- break;
- }
-
- return size;
+ if (flags & ATTR_FINAL_SIZE) {
+ return buffer.size() / data_sizeof();
+ }
+
+ size_t size;
+
+ switch (element) {
+ case ATTR_ELEMENT_OBJECT:
+ case ATTR_ELEMENT_MESH:
+ case ATTR_ELEMENT_VOXEL:
+ size = 1;
+ break;
+ case ATTR_ELEMENT_VERTEX:
+ size = mesh->verts.size() + mesh->num_ngons;
+ if (prim == ATTR_PRIM_SUBD) {
+ size -= mesh->num_subd_verts;
+ }
+ break;
+ case ATTR_ELEMENT_VERTEX_MOTION:
+ size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1);
+ if (prim == ATTR_PRIM_SUBD) {
+ size -= mesh->num_subd_verts * (mesh->motion_steps - 1);
+ }
+ break;
+ case ATTR_ELEMENT_FACE:
+ if (prim == ATTR_PRIM_TRIANGLE) {
+ size = mesh->num_triangles();
+ }
+ else {
+ size = mesh->subd_faces.size() + mesh->num_ngons;
+ }
+ break;
+ case ATTR_ELEMENT_CORNER:
+ case ATTR_ELEMENT_CORNER_BYTE:
+ if (prim == ATTR_PRIM_TRIANGLE) {
+ size = mesh->num_triangles() * 3;
+ }
+ else {
+ size = mesh->subd_face_corners.size() + mesh->num_ngons;
+ }
+ break;
+ case ATTR_ELEMENT_CURVE:
+ size = mesh->num_curves();
+ break;
+ case ATTR_ELEMENT_CURVE_KEY:
+ size = mesh->curve_keys.size();
+ break;
+ case ATTR_ELEMENT_CURVE_KEY_MOTION:
+ size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
+ break;
+ default:
+ size = 0;
+ break;
+ }
+
+ return size;
}
size_t Attribute::buffer_size(Mesh *mesh, AttributePrimitive prim) const
{
- return element_size(mesh, prim)*data_sizeof();
+ return element_size(mesh, prim) * data_sizeof();
}
bool Attribute::same_storage(TypeDesc a, TypeDesc b)
{
- if(a == b)
- return true;
+ if (a == b)
+ return true;
- if(a == TypeDesc::TypeColor || a == TypeDesc::TypePoint ||
- a == TypeDesc::TypeVector || a == TypeDesc::TypeNormal)
- {
- if(b == TypeDesc::TypeColor || b == TypeDesc::TypePoint ||
- b == TypeDesc::TypeVector || b == TypeDesc::TypeNormal)
- {
- return true;
- }
- }
- return false;
+ if (a == TypeDesc::TypeColor || a == TypeDesc::TypePoint || a == TypeDesc::TypeVector ||
+ a == TypeDesc::TypeNormal) {
+ if (b == TypeDesc::TypeColor || b == TypeDesc::TypePoint || b == TypeDesc::TypeVector ||
+ b == TypeDesc::TypeNormal) {
+ return true;
+ }
+ }
+ return false;
}
-void Attribute::zero_data(void* dst)
+void Attribute::zero_data(void *dst)
{
- memset(dst, 0, data_sizeof());
+ memset(dst, 0, data_sizeof());
}
-void Attribute::add_with_weight(void* dst, void* src, float weight)
+void Attribute::add_with_weight(void *dst, void *src, float weight)
{
- if(element == ATTR_ELEMENT_CORNER_BYTE) {
- for(int i = 0; i < 4; i++) {
- ((uchar*)dst)[i] += uchar(((uchar*)src)[i] * weight);
- }
- }
- else if(same_storage(type, TypeDesc::TypeFloat)) {
- *((float*)dst) += *((float*)src) * weight;
- }
- else if(same_storage(type, TypeDesc::TypeVector)) {
- *((float4*)dst) += *((float4*)src) * weight;
- }
- else {
- assert(!"not implemented for this type");
- }
+ if (element == ATTR_ELEMENT_CORNER_BYTE) {
+ for (int i = 0; i < 4; i++) {
+ ((uchar *)dst)[i] += uchar(((uchar *)src)[i] * weight);
+ }
+ }
+ else if (same_storage(type, TypeDesc::TypeFloat)) {
+ *((float *)dst) += *((float *)src) * weight;
+ }
+ else if (same_storage(type, TypeDesc::TypeVector)) {
+ *((float4 *)dst) += *((float4 *)src) * weight;
+ }
+ else {
+ assert(!"not implemented for this type");
+ }
}
const char *Attribute::standard_name(AttributeStandard std)
{
- switch(std) {
- case ATTR_STD_VERTEX_NORMAL:
- return "N";
- case ATTR_STD_FACE_NORMAL:
- return "Ng";
- case ATTR_STD_UV:
- return "uv";
- case ATTR_STD_GENERATED:
- return "generated";
- case ATTR_STD_GENERATED_TRANSFORM:
- return "generated_transform";
- case ATTR_STD_UV_TANGENT:
- return "tangent";
- case ATTR_STD_UV_TANGENT_SIGN:
- return "tangent_sign";
- case ATTR_STD_POSITION_UNDEFORMED:
- return "undeformed";
- case ATTR_STD_POSITION_UNDISPLACED:
- return "undisplaced";
- case ATTR_STD_MOTION_VERTEX_POSITION:
- return "motion_P";
- case ATTR_STD_MOTION_VERTEX_NORMAL:
- return "motion_N";
- case ATTR_STD_PARTICLE:
- return "particle";
- case ATTR_STD_CURVE_INTERCEPT:
- return "curve_intercept";
- case ATTR_STD_CURVE_RANDOM:
- return "curve_random";
- case ATTR_STD_PTEX_FACE_ID:
- return "ptex_face_id";
- case ATTR_STD_PTEX_UV:
- return "ptex_uv";
- case ATTR_STD_VOLUME_DENSITY:
- return "density";
- case ATTR_STD_VOLUME_COLOR:
- return "color";
- case ATTR_STD_VOLUME_FLAME:
- return "flame";
- case ATTR_STD_VOLUME_HEAT:
- return "heat";
- case ATTR_STD_VOLUME_TEMPERATURE:
- return "temperature";
- case ATTR_STD_VOLUME_VELOCITY:
- return "velocity";
- case ATTR_STD_POINTINESS:
- return "pointiness";
- case ATTR_STD_NOT_FOUND:
- case ATTR_STD_NONE:
- case ATTR_STD_NUM:
- return "";
- }
-
- return "";
+ switch (std) {
+ case ATTR_STD_VERTEX_NORMAL:
+ return "N";
+ case ATTR_STD_FACE_NORMAL:
+ return "Ng";
+ case ATTR_STD_UV:
+ return "uv";
+ case ATTR_STD_GENERATED:
+ return "generated";
+ case ATTR_STD_GENERATED_TRANSFORM:
+ return "generated_transform";
+ case ATTR_STD_UV_TANGENT:
+ return "tangent";
+ case ATTR_STD_UV_TANGENT_SIGN:
+ return "tangent_sign";
+ case ATTR_STD_POSITION_UNDEFORMED:
+ return "undeformed";
+ case ATTR_STD_POSITION_UNDISPLACED:
+ return "undisplaced";
+ case ATTR_STD_MOTION_VERTEX_POSITION:
+ return "motion_P";
+ case ATTR_STD_MOTION_VERTEX_NORMAL:
+ return "motion_N";
+ case ATTR_STD_PARTICLE:
+ return "particle";
+ case ATTR_STD_CURVE_INTERCEPT:
+ return "curve_intercept";
+ case ATTR_STD_CURVE_RANDOM:
+ return "curve_random";
+ case ATTR_STD_PTEX_FACE_ID:
+ return "ptex_face_id";
+ case ATTR_STD_PTEX_UV:
+ return "ptex_uv";
+ case ATTR_STD_VOLUME_DENSITY:
+ return "density";
+ case ATTR_STD_VOLUME_COLOR:
+ return "color";
+ case ATTR_STD_VOLUME_FLAME:
+ return "flame";
+ case ATTR_STD_VOLUME_HEAT:
+ return "heat";
+ case ATTR_STD_VOLUME_TEMPERATURE:
+ return "temperature";
+ case ATTR_STD_VOLUME_VELOCITY:
+ return "velocity";
+ case ATTR_STD_POINTINESS:
+ return "pointiness";
+ case ATTR_STD_NOT_FOUND:
+ case ATTR_STD_NONE:
+ case ATTR_STD_NUM:
+ return "";
+ }
+
+ return "";
}
AttributeStandard Attribute::name_standard(const char *name)
{
- if(name) {
- for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) {
- if(strcmp(name, Attribute::standard_name((AttributeStandard)std)) == 0) {
- return (AttributeStandard)std;
- }
- }
- }
+ if (name) {
+ for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) {
+ if (strcmp(name, Attribute::standard_name((AttributeStandard)std)) == 0) {
+ return (AttributeStandard)std;
+ }
+ }
+ }
- return ATTR_STD_NONE;
+ return ATTR_STD_NONE;
}
/* Attribute Set */
AttributeSet::AttributeSet()
{
- triangle_mesh = NULL;
- curve_mesh = NULL;
- subd_mesh = NULL;
+ triangle_mesh = NULL;
+ curve_mesh = NULL;
+ subd_mesh = NULL;
}
AttributeSet::~AttributeSet()
@@ -348,280 +345,280 @@ AttributeSet::~AttributeSet()
Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element)
{
- Attribute *attr = find(name);
+ Attribute *attr = find(name);
- if(attr) {
- /* return if same already exists */
- if(attr->type == type && attr->element == element)
- return attr;
+ if (attr) {
+ /* return if same already exists */
+ if (attr->type == type && attr->element == element)
+ return attr;
- /* overwrite attribute with same name but different type/element */
- remove(name);
- }
+ /* overwrite attribute with same name but different type/element */
+ remove(name);
+ }
#if __cplusplus >= 201103L
- attributes.emplace_back();
- attr = &attributes.back();
- attr->set(name, type, element);
+ attributes.emplace_back();
+ attr = &attributes.back();
+ attr->set(name, type, element);
#else
- {
- Attribute attr_temp;
- attr_temp.set(name, type, element);
- attributes.push_back(attr_temp);
- attr = &attributes.back();
- }
+ {
+ Attribute attr_temp;
+ attr_temp.set(name, type, element);
+ attributes.push_back(attr_temp);
+ attr = &attributes.back();
+ }
#endif
- /* this is weak .. */
- if(triangle_mesh)
- attr->resize(triangle_mesh, ATTR_PRIM_TRIANGLE, false);
- if(curve_mesh)
- attr->resize(curve_mesh, ATTR_PRIM_CURVE, false);
- if(subd_mesh)
- attr->resize(subd_mesh, ATTR_PRIM_SUBD, false);
+ /* this is weak .. */
+ if (triangle_mesh)
+ attr->resize(triangle_mesh, ATTR_PRIM_TRIANGLE, false);
+ if (curve_mesh)
+ attr->resize(curve_mesh, ATTR_PRIM_CURVE, false);
+ if (subd_mesh)
+ attr->resize(subd_mesh, ATTR_PRIM_SUBD, false);
- return attr;
+ return attr;
}
Attribute *AttributeSet::find(ustring name) const
{
- foreach(const Attribute& attr, attributes)
- if(attr.name == name)
- return (Attribute*)&attr;
+ foreach (const Attribute &attr, attributes)
+ if (attr.name == name)
+ return (Attribute *)&attr;
- return NULL;
+ return NULL;
}
void AttributeSet::remove(ustring name)
{
- Attribute *attr = find(name);
+ Attribute *attr = find(name);
- if(attr) {
- list<Attribute>::iterator it;
+ if (attr) {
+ list<Attribute>::iterator it;
- for(it = attributes.begin(); it != attributes.end(); it++) {
- if(&*it == attr) {
- attributes.erase(it);
- return;
- }
- }
- }
+ for (it = attributes.begin(); it != attributes.end(); it++) {
+ if (&*it == attr) {
+ attributes.erase(it);
+ return;
+ }
+ }
+ }
}
Attribute *AttributeSet::add(AttributeStandard std, ustring name)
{
- Attribute *attr = NULL;
-
- if(name == ustring())
- name = Attribute::standard_name(std);
-
- if(triangle_mesh || subd_mesh) {
- switch(std) {
- case ATTR_STD_VERTEX_NORMAL:
- attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
- break;
- case ATTR_STD_FACE_NORMAL:
- attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_FACE);
- break;
- case ATTR_STD_UV:
- attr = add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
- break;
- case ATTR_STD_UV_TANGENT:
- attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
- break;
- case ATTR_STD_UV_TANGENT_SIGN:
- attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
- break;
- case ATTR_STD_GENERATED:
- case ATTR_STD_POSITION_UNDEFORMED:
- case ATTR_STD_POSITION_UNDISPLACED:
- attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
- break;
- case ATTR_STD_MOTION_VERTEX_POSITION:
- attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
- break;
- case ATTR_STD_MOTION_VERTEX_NORMAL:
- attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX_MOTION);
- break;
- case ATTR_STD_PTEX_FACE_ID:
- attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
- break;
- case ATTR_STD_PTEX_UV:
- attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
- break;
- case ATTR_STD_GENERATED_TRANSFORM:
- attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
- break;
- case ATTR_STD_VOLUME_DENSITY:
- case ATTR_STD_VOLUME_FLAME:
- case ATTR_STD_VOLUME_HEAT:
- case ATTR_STD_VOLUME_TEMPERATURE:
- attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
- break;
- case ATTR_STD_VOLUME_COLOR:
- attr = add(name, TypeDesc::TypeColor, ATTR_ELEMENT_VOXEL);
- break;
- case ATTR_STD_VOLUME_VELOCITY:
- attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_VOXEL);
- break;
- case ATTR_STD_POINTINESS:
- attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
- break;
- default:
- assert(0);
- break;
- }
- }
- else if(curve_mesh) {
- switch(std) {
- case ATTR_STD_UV:
- attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
- break;
- case ATTR_STD_GENERATED:
- attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
- break;
- case ATTR_STD_MOTION_VERTEX_POSITION:
- attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY_MOTION);
- break;
- case ATTR_STD_CURVE_INTERCEPT:
- attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
- break;
- case ATTR_STD_CURVE_RANDOM:
- attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE);
- break;
- case ATTR_STD_GENERATED_TRANSFORM:
- attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
- break;
- case ATTR_STD_POINTINESS:
- attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
- break;
- default:
- assert(0);
- break;
- }
- }
-
- attr->std = std;
-
- return attr;
+ Attribute *attr = NULL;
+
+ if (name == ustring())
+ name = Attribute::standard_name(std);
+
+ if (triangle_mesh || subd_mesh) {
+ switch (std) {
+ case ATTR_STD_VERTEX_NORMAL:
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
+ break;
+ case ATTR_STD_FACE_NORMAL:
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_FACE);
+ break;
+ case ATTR_STD_UV:
+ attr = add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
+ break;
+ case ATTR_STD_UV_TANGENT:
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
+ break;
+ case ATTR_STD_UV_TANGENT_SIGN:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
+ break;
+ case ATTR_STD_GENERATED:
+ case ATTR_STD_POSITION_UNDEFORMED:
+ case ATTR_STD_POSITION_UNDISPLACED:
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ break;
+ case ATTR_STD_MOTION_VERTEX_POSITION:
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
+ break;
+ case ATTR_STD_MOTION_VERTEX_NORMAL:
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX_MOTION);
+ break;
+ case ATTR_STD_PTEX_FACE_ID:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
+ break;
+ case ATTR_STD_PTEX_UV:
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ break;
+ case ATTR_STD_GENERATED_TRANSFORM:
+ attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
+ break;
+ case ATTR_STD_VOLUME_DENSITY:
+ case ATTR_STD_VOLUME_FLAME:
+ case ATTR_STD_VOLUME_HEAT:
+ case ATTR_STD_VOLUME_TEMPERATURE:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
+ break;
+ case ATTR_STD_VOLUME_COLOR:
+ attr = add(name, TypeDesc::TypeColor, ATTR_ELEMENT_VOXEL);
+ break;
+ case ATTR_STD_VOLUME_VELOCITY:
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_VOXEL);
+ break;
+ case ATTR_STD_POINTINESS:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ else if (curve_mesh) {
+ switch (std) {
+ case ATTR_STD_UV:
+ attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
+ break;
+ case ATTR_STD_GENERATED:
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
+ break;
+ case ATTR_STD_MOTION_VERTEX_POSITION:
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY_MOTION);
+ break;
+ case ATTR_STD_CURVE_INTERCEPT:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
+ break;
+ case ATTR_STD_CURVE_RANDOM:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE);
+ break;
+ case ATTR_STD_GENERATED_TRANSFORM:
+ attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
+ break;
+ case ATTR_STD_POINTINESS:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ attr->std = std;
+
+ return attr;
}
Attribute *AttributeSet::find(AttributeStandard std) const
{
- foreach(const Attribute& attr, attributes)
- if(attr.std == std)
- return (Attribute*)&attr;
+ foreach (const Attribute &attr, attributes)
+ if (attr.std == std)
+ return (Attribute *)&attr;
- return NULL;
+ return NULL;
}
void AttributeSet::remove(AttributeStandard std)
{
- Attribute *attr = find(std);
+ Attribute *attr = find(std);
- if(attr) {
- list<Attribute>::iterator it;
+ if (attr) {
+ list<Attribute>::iterator it;
- for(it = attributes.begin(); it != attributes.end(); it++) {
- if(&*it == attr) {
- attributes.erase(it);
- return;
- }
- }
- }
+ for (it = attributes.begin(); it != attributes.end(); it++) {
+ if (&*it == attr) {
+ attributes.erase(it);
+ return;
+ }
+ }
+ }
}
-Attribute *AttributeSet::find(AttributeRequest& req)
+Attribute *AttributeSet::find(AttributeRequest &req)
{
- if(req.std == ATTR_STD_NONE)
- return find(req.name);
- else
- return find(req.std);
+ if (req.std == ATTR_STD_NONE)
+ return find(req.name);
+ else
+ return find(req.std);
}
void AttributeSet::remove(Attribute *attribute)
{
- if(attribute->std == ATTR_STD_NONE) {
- remove(attribute->name);
- }
- else {
- remove(attribute->std);
- }
+ if (attribute->std == ATTR_STD_NONE) {
+ remove(attribute->name);
+ }
+ else {
+ remove(attribute->std);
+ }
}
void AttributeSet::resize(bool reserve_only)
{
- foreach(Attribute& attr, attributes) {
- if(triangle_mesh)
- attr.resize(triangle_mesh, ATTR_PRIM_TRIANGLE, reserve_only);
- if(curve_mesh)
- attr.resize(curve_mesh, ATTR_PRIM_CURVE, reserve_only);
- if(subd_mesh)
- attr.resize(subd_mesh, ATTR_PRIM_SUBD, reserve_only);
- }
+ foreach (Attribute &attr, attributes) {
+ if (triangle_mesh)
+ attr.resize(triangle_mesh, ATTR_PRIM_TRIANGLE, reserve_only);
+ if (curve_mesh)
+ attr.resize(curve_mesh, ATTR_PRIM_CURVE, reserve_only);
+ if (subd_mesh)
+ attr.resize(subd_mesh, ATTR_PRIM_SUBD, reserve_only);
+ }
}
void AttributeSet::clear(bool preserve_voxel_data)
{
- if(preserve_voxel_data) {
- list<Attribute>::iterator it;
+ if (preserve_voxel_data) {
+ list<Attribute>::iterator it;
- for(it = attributes.begin(); it != attributes.end();) {
- if(it->element == ATTR_ELEMENT_VOXEL || it->std == ATTR_STD_GENERATED_TRANSFORM) {
- it++;
- }
- else {
- attributes.erase(it++);
- }
- }
- }
- else {
- attributes.clear();
- }
+ for (it = attributes.begin(); it != attributes.end();) {
+ if (it->element == ATTR_ELEMENT_VOXEL || it->std == ATTR_STD_GENERATED_TRANSFORM) {
+ it++;
+ }
+ else {
+ attributes.erase(it++);
+ }
+ }
+ }
+ else {
+ attributes.clear();
+ }
}
/* AttributeRequest */
AttributeRequest::AttributeRequest(ustring name_)
{
- name = name_;
- std = ATTR_STD_NONE;
+ name = name_;
+ std = ATTR_STD_NONE;
- triangle_type = TypeDesc::TypeFloat;
- triangle_desc.element = ATTR_ELEMENT_NONE;
- triangle_desc.offset = 0;
- triangle_desc.type = NODE_ATTR_FLOAT;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_desc.element = ATTR_ELEMENT_NONE;
+ triangle_desc.offset = 0;
+ triangle_desc.type = NODE_ATTR_FLOAT;
- curve_type = TypeDesc::TypeFloat;
- curve_desc.element = ATTR_ELEMENT_NONE;
- curve_desc.offset = 0;
- curve_desc.type = NODE_ATTR_FLOAT;
+ curve_type = TypeDesc::TypeFloat;
+ curve_desc.element = ATTR_ELEMENT_NONE;
+ curve_desc.offset = 0;
+ curve_desc.type = NODE_ATTR_FLOAT;
- subd_type = TypeDesc::TypeFloat;
- subd_desc.element = ATTR_ELEMENT_NONE;
- subd_desc.offset = 0;
- subd_desc.type = NODE_ATTR_FLOAT;
+ subd_type = TypeDesc::TypeFloat;
+ subd_desc.element = ATTR_ELEMENT_NONE;
+ subd_desc.offset = 0;
+ subd_desc.type = NODE_ATTR_FLOAT;
}
AttributeRequest::AttributeRequest(AttributeStandard std_)
{
- name = ustring();
- std = std_;
+ name = ustring();
+ std = std_;
- triangle_type = TypeDesc::TypeFloat;
- triangle_desc.element = ATTR_ELEMENT_NONE;
- triangle_desc.offset = 0;
- triangle_desc.type = NODE_ATTR_FLOAT;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_desc.element = ATTR_ELEMENT_NONE;
+ triangle_desc.offset = 0;
+ triangle_desc.type = NODE_ATTR_FLOAT;
- curve_type = TypeDesc::TypeFloat;
- curve_desc.element = ATTR_ELEMENT_NONE;
- curve_desc.offset = 0;
- curve_desc.type = NODE_ATTR_FLOAT;
+ curve_type = TypeDesc::TypeFloat;
+ curve_desc.element = ATTR_ELEMENT_NONE;
+ curve_desc.offset = 0;
+ curve_desc.type = NODE_ATTR_FLOAT;
- subd_type = TypeDesc::TypeFloat;
- subd_desc.element = ATTR_ELEMENT_NONE;
- subd_desc.offset = 0;
- subd_desc.type = NODE_ATTR_FLOAT;
+ subd_type = TypeDesc::TypeFloat;
+ subd_desc.element = ATTR_ELEMENT_NONE;
+ subd_desc.offset = 0;
+ subd_desc.type = NODE_ATTR_FLOAT;
}
/* AttributeRequestSet */
@@ -634,101 +631,99 @@ AttributeRequestSet::~AttributeRequestSet()
{
}
-bool AttributeRequestSet::modified(const AttributeRequestSet& other)
+bool AttributeRequestSet::modified(const AttributeRequestSet &other)
{
- if(requests.size() != other.requests.size())
- return true;
+ if (requests.size() != other.requests.size())
+ return true;
- for(size_t i = 0; i < requests.size(); i++) {
- bool found = false;
+ for (size_t i = 0; i < requests.size(); i++) {
+ bool found = false;
- for(size_t j = 0; j < requests.size() && !found; j++)
- if(requests[i].name == other.requests[j].name &&
- requests[i].std == other.requests[j].std)
- {
- found = true;
- }
+ for (size_t j = 0; j < requests.size() && !found; j++)
+ if (requests[i].name == other.requests[j].name && requests[i].std == other.requests[j].std) {
+ found = true;
+ }
- if(!found) {
- return true;
- }
- }
+ if (!found) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
void AttributeRequestSet::add(ustring name)
{
- foreach(AttributeRequest& req, requests) {
- if(req.name == name) {
- return;
- }
- }
+ foreach (AttributeRequest &req, requests) {
+ if (req.name == name) {
+ return;
+ }
+ }
- requests.push_back(AttributeRequest(name));
+ requests.push_back(AttributeRequest(name));
}
void AttributeRequestSet::add(AttributeStandard std)
{
- foreach(AttributeRequest& req, requests)
- if(req.std == std)
- return;
+ foreach (AttributeRequest &req, requests)
+ if (req.std == std)
+ return;
- requests.push_back(AttributeRequest(std));
+ requests.push_back(AttributeRequest(std));
}
-void AttributeRequestSet::add(AttributeRequestSet& reqs)
+void AttributeRequestSet::add(AttributeRequestSet &reqs)
{
- foreach(AttributeRequest& req, reqs.requests) {
- if(req.std == ATTR_STD_NONE)
- add(req.name);
- else
- add(req.std);
- }
+ foreach (AttributeRequest &req, reqs.requests) {
+ if (req.std == ATTR_STD_NONE)
+ add(req.name);
+ else
+ add(req.std);
+ }
}
void AttributeRequestSet::add_standard(ustring name)
{
- if(name.empty()) {
- return;
- }
+ if (name.empty()) {
+ return;
+ }
- AttributeStandard std = Attribute::name_standard(name.c_str());
+ AttributeStandard std = Attribute::name_standard(name.c_str());
- if(std) {
- add(std);
- }
- else {
- add(name);
- }
+ if (std) {
+ add(std);
+ }
+ else {
+ add(name);
+ }
}
bool AttributeRequestSet::find(ustring name)
{
- foreach(AttributeRequest& req, requests)
- if(req.name == name)
- return true;
+ foreach (AttributeRequest &req, requests)
+ if (req.name == name)
+ return true;
- return false;
+ return false;
}
bool AttributeRequestSet::find(AttributeStandard std)
{
- foreach(AttributeRequest& req, requests)
- if(req.std == std)
- return true;
+ foreach (AttributeRequest &req, requests)
+ if (req.std == std)
+ return true;
- return false;
+ return false;
}
size_t AttributeRequestSet::size()
{
- return requests.size();
+ return requests.size();
}
void AttributeRequestSet::clear()
{
- requests.clear();
+ requests.clear();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index ed9e9fe76d6..ebab0fe7f88 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -37,8 +37,8 @@ struct Transform;
/* Attributes for voxels are images */
struct VoxelAttribute {
- ImageManager *manager;
- int slot;
+ ImageManager *manager;
+ int slot;
};
/* Attribute
@@ -47,114 +47,116 @@ struct VoxelAttribute {
* Supported types: Float, Color, Vector, Normal, Point */
class Attribute {
-public:
- ustring name;
- AttributeStandard std;
-
- TypeDesc type;
- vector<char> buffer;
- AttributeElement element;
- uint flags; /* enum AttributeFlag */
-
- Attribute() {}
- ~Attribute();
- void set(ustring name, TypeDesc type, AttributeElement element);
- void resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only);
- void resize(size_t num_elements);
-
- size_t data_sizeof() const;
- size_t element_size(Mesh *mesh, AttributePrimitive prim) const;
- size_t buffer_size(Mesh *mesh, AttributePrimitive prim) const;
-
- char *data()
- {
- return (buffer.size())? &buffer[0]: NULL;
- }
- float2 *data_float2()
- {
- assert(data_sizeof() == sizeof(float2));
- return (float2*)data();
- }
- float3 *data_float3()
- {
- assert(data_sizeof() == sizeof(float3));
- return (float3*)data();
- }
- float4 *data_float4()
- {
- assert(data_sizeof() == sizeof(float4));
- return (float4*)data();
- }
- float *data_float()
- {
- assert(data_sizeof() == sizeof(float));
- return (float*)data();
- }
- uchar4 *data_uchar4()
- {
- assert(data_sizeof() == sizeof(uchar4));
- return (uchar4*)data();
- }
- Transform *data_transform()
- {
- assert(data_sizeof() == sizeof(Transform));
- return (Transform*)data();
- }
- VoxelAttribute *data_voxel()
- {
- assert(data_sizeof() == sizeof(VoxelAttribute));
- return ( VoxelAttribute*)data();
- }
-
- const char *data() const
- {
- return (buffer.size())? &buffer[0]: NULL;
- }
- const float2 *data_float2() const
- {
- assert(data_sizeof() == sizeof(float2));
- return (const float2*)data();
- }
- const float3 *data_float3() const
- {
- assert(data_sizeof() == sizeof(float3));
- return (const float3*)data();
- }
- const float4 *data_float4() const
- {
- assert(data_sizeof() == sizeof(float4));
- return (const float4*)data();
- }
- const float *data_float() const
- {
- assert(data_sizeof() == sizeof(float));
- return (const float*)data();
- }
- const Transform *data_transform() const
- {
- assert(data_sizeof() == sizeof(Transform));
- return (const Transform*)data();
- }
- const VoxelAttribute *data_voxel() const
- {
- assert(data_sizeof() == sizeof(VoxelAttribute));
- return (const VoxelAttribute*)data();
- }
-
- void zero_data(void* dst);
- void add_with_weight(void* dst, void* src, float weight);
-
- void add(const float& f);
- void add(const float2& f);
- void add(const float3& f);
- void add(const uchar4& f);
- void add(const Transform& f);
- void add(const VoxelAttribute& f);
- void add(const char *data);
-
- static bool same_storage(TypeDesc a, TypeDesc b);
- static const char *standard_name(AttributeStandard std);
- static AttributeStandard name_standard(const char *name);
+ public:
+ ustring name;
+ AttributeStandard std;
+
+ TypeDesc type;
+ vector<char> buffer;
+ AttributeElement element;
+ uint flags; /* enum AttributeFlag */
+
+ Attribute()
+ {
+ }
+ ~Attribute();
+ void set(ustring name, TypeDesc type, AttributeElement element);
+ void resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only);
+ void resize(size_t num_elements);
+
+ size_t data_sizeof() const;
+ size_t element_size(Mesh *mesh, AttributePrimitive prim) const;
+ size_t buffer_size(Mesh *mesh, AttributePrimitive prim) const;
+
+ char *data()
+ {
+ return (buffer.size()) ? &buffer[0] : NULL;
+ }
+ float2 *data_float2()
+ {
+ assert(data_sizeof() == sizeof(float2));
+ return (float2 *)data();
+ }
+ float3 *data_float3()
+ {
+ assert(data_sizeof() == sizeof(float3));
+ return (float3 *)data();
+ }
+ float4 *data_float4()
+ {
+ assert(data_sizeof() == sizeof(float4));
+ return (float4 *)data();
+ }
+ float *data_float()
+ {
+ assert(data_sizeof() == sizeof(float));
+ return (float *)data();
+ }
+ uchar4 *data_uchar4()
+ {
+ assert(data_sizeof() == sizeof(uchar4));
+ return (uchar4 *)data();
+ }
+ Transform *data_transform()
+ {
+ assert(data_sizeof() == sizeof(Transform));
+ return (Transform *)data();
+ }
+ VoxelAttribute *data_voxel()
+ {
+ assert(data_sizeof() == sizeof(VoxelAttribute));
+ return (VoxelAttribute *)data();
+ }
+
+ const char *data() const
+ {
+ return (buffer.size()) ? &buffer[0] : NULL;
+ }
+ const float2 *data_float2() const
+ {
+ assert(data_sizeof() == sizeof(float2));
+ return (const float2 *)data();
+ }
+ const float3 *data_float3() const
+ {
+ assert(data_sizeof() == sizeof(float3));
+ return (const float3 *)data();
+ }
+ const float4 *data_float4() const
+ {
+ assert(data_sizeof() == sizeof(float4));
+ return (const float4 *)data();
+ }
+ const float *data_float() const
+ {
+ assert(data_sizeof() == sizeof(float));
+ return (const float *)data();
+ }
+ const Transform *data_transform() const
+ {
+ assert(data_sizeof() == sizeof(Transform));
+ return (const Transform *)data();
+ }
+ const VoxelAttribute *data_voxel() const
+ {
+ assert(data_sizeof() == sizeof(VoxelAttribute));
+ return (const VoxelAttribute *)data();
+ }
+
+ void zero_data(void *dst);
+ void add_with_weight(void *dst, void *src, float weight);
+
+ void add(const float &f);
+ void add(const float2 &f);
+ void add(const float3 &f);
+ void add(const uchar4 &f);
+ void add(const Transform &f);
+ void add(const VoxelAttribute &f);
+ void add(const char *data);
+
+ static bool same_storage(TypeDesc a, TypeDesc b);
+ static const char *standard_name(AttributeStandard std);
+ static AttributeStandard name_standard(const char *name);
};
/* Attribute Set
@@ -162,29 +164,29 @@ public:
* Set of attributes on a mesh. */
class AttributeSet {
-public:
- Mesh *triangle_mesh;
- Mesh *curve_mesh;
- Mesh *subd_mesh;
- list<Attribute> attributes;
+ public:
+ Mesh *triangle_mesh;
+ Mesh *curve_mesh;
+ Mesh *subd_mesh;
+ list<Attribute> attributes;
- AttributeSet();
- ~AttributeSet();
+ AttributeSet();
+ ~AttributeSet();
- Attribute *add(ustring name, TypeDesc type, AttributeElement element);
- Attribute *find(ustring name) const;
- void remove(ustring name);
+ Attribute *add(ustring name, TypeDesc type, AttributeElement element);
+ Attribute *find(ustring name) const;
+ void remove(ustring name);
- Attribute *add(AttributeStandard std, ustring name = ustring());
- Attribute *find(AttributeStandard std) const;
- void remove(AttributeStandard std);
+ Attribute *add(AttributeStandard std, ustring name = ustring());
+ Attribute *find(AttributeStandard std) const;
+ void remove(AttributeStandard std);
- Attribute *find(AttributeRequest& req);
+ Attribute *find(AttributeRequest &req);
- void remove(Attribute *attribute);
+ void remove(Attribute *attribute);
- void resize(bool reserve_only = false);
- void clear(bool preserve_voxel_data = false);
+ void resize(bool reserve_only = false);
+ void clear(bool preserve_voxel_data = false);
};
/* AttributeRequest
@@ -194,16 +196,16 @@ public:
* The attribute is found either by name or by standard attribute type. */
class AttributeRequest {
-public:
- ustring name;
- AttributeStandard std;
+ public:
+ ustring name;
+ AttributeStandard std;
- /* temporary variables used by MeshManager */
- TypeDesc triangle_type, curve_type, subd_type;
- AttributeDescriptor triangle_desc, curve_desc, subd_desc;
+ /* temporary variables used by MeshManager */
+ TypeDesc triangle_type, curve_type, subd_type;
+ AttributeDescriptor triangle_desc, curve_desc, subd_desc;
- explicit AttributeRequest(ustring name_);
- explicit AttributeRequest(AttributeStandard std);
+ explicit AttributeRequest(ustring name_);
+ explicit AttributeRequest(AttributeStandard std);
};
/* AttributeRequestSet
@@ -211,26 +213,26 @@ public:
* Set of attributes requested by a shader. */
class AttributeRequestSet {
-public:
- vector<AttributeRequest> requests;
+ public:
+ vector<AttributeRequest> requests;
- AttributeRequestSet();
- ~AttributeRequestSet();
+ AttributeRequestSet();
+ ~AttributeRequestSet();
- void add(ustring name);
- void add(AttributeStandard std);
- void add(AttributeRequestSet& reqs);
- void add_standard(ustring name);
+ void add(ustring name);
+ void add(AttributeStandard std);
+ void add(AttributeRequestSet &reqs);
+ void add_standard(ustring name);
- bool find(ustring name);
- bool find(AttributeStandard std);
+ bool find(ustring name);
+ bool find(AttributeStandard std);
- size_t size();
- void clear();
+ size_t size();
+ void clear();
- bool modified(const AttributeRequestSet& other);
+ bool modified(const AttributeRequestSet &other);
};
CCL_NAMESPACE_END
-#endif /* __ATTRIBUTE_H__ */
+#endif /* __ATTRIBUTE_H__ */
diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp
index d8a49bf6a5e..b32cc55903d 100644
--- a/intern/cycles/render/background.cpp
+++ b/intern/cycles/render/background.cpp
@@ -30,28 +30,27 @@ CCL_NAMESPACE_BEGIN
NODE_DEFINE(Background)
{
- NodeType* type = NodeType::add("background", create);
+ NodeType *type = NodeType::add("background", create);
- SOCKET_FLOAT(ao_factor, "AO Factor", 0.0f);
- SOCKET_FLOAT(ao_distance, "AO Distance", FLT_MAX);
+ SOCKET_FLOAT(ao_factor, "AO Factor", 0.0f);
+ SOCKET_FLOAT(ao_distance, "AO Distance", FLT_MAX);
- SOCKET_BOOLEAN(use_shader, "Use Shader", true);
- SOCKET_BOOLEAN(use_ao, "Use AO", false);
- SOCKET_UINT(visibility, "Visibility", PATH_RAY_ALL_VISIBILITY);
+ SOCKET_BOOLEAN(use_shader, "Use Shader", true);
+ SOCKET_BOOLEAN(use_ao, "Use AO", false);
+ SOCKET_UINT(visibility, "Visibility", PATH_RAY_ALL_VISIBILITY);
- SOCKET_BOOLEAN(transparent, "Transparent", false);
- SOCKET_BOOLEAN(transparent_glass, "Transparent Glass", false);
- SOCKET_FLOAT(transparent_roughness_threshold, "Transparent Roughness Threshold", 0.0f);
+ SOCKET_BOOLEAN(transparent, "Transparent", false);
+ SOCKET_BOOLEAN(transparent_glass, "Transparent Glass", false);
+ SOCKET_FLOAT(transparent_roughness_threshold, "Transparent Roughness Threshold", 0.0f);
- SOCKET_NODE(shader, "Shader", &Shader::node_type);
+ SOCKET_NODE(shader, "Shader", &Shader::node_type);
- return type;
+ return type;
}
-Background::Background()
-: Node(node_type)
+Background::Background() : Node(node_type)
{
- need_update = true;
+ need_update = true;
}
Background::~Background()
@@ -60,78 +59,79 @@ Background::~Background()
void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
- if(!need_update)
- return;
-
- device_free(device, dscene);
-
- Shader *bg_shader = shader;
-
- if(use_shader) {
- if(!bg_shader)
- bg_shader = scene->default_background;
- }
- else
- bg_shader = scene->default_empty;
-
- /* set shader index and transparent option */
- KernelBackground *kbackground = &dscene->data.background;
-
- kbackground->ao_factor = (use_ao)? ao_factor: 0.0f;
- kbackground->ao_bounces_factor = ao_factor;
- kbackground->ao_distance = ao_distance;
-
- kbackground->transparent = transparent;
- kbackground->surface_shader = scene->shader_manager->get_shader_id(bg_shader);
-
- if(transparent && transparent_glass) {
- /* Square twice, once for principled BSDF convention, and once for
- * faster comparison in kernel with anisotropic roughness. */
- kbackground->transparent_roughness_squared_threshold = sqr(sqr(transparent_roughness_threshold));
- }
- else {
- kbackground->transparent_roughness_squared_threshold = -1.0f;
- }
-
- if(bg_shader->has_volume)
- kbackground->volume_shader = kbackground->surface_shader;
- else
- kbackground->volume_shader = SHADER_NONE;
-
- /* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
- if(bg_shader->graph->nodes.size() <= 1) {
- kbackground->surface_shader |= SHADER_EXCLUDE_ANY;
- }
- /* Background present, check visibilities */
- else {
- if(!(visibility & PATH_RAY_DIFFUSE))
- kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
- if(!(visibility & PATH_RAY_GLOSSY))
- kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
- if(!(visibility & PATH_RAY_TRANSMIT))
- kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
- if(!(visibility & PATH_RAY_VOLUME_SCATTER))
- kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
- if(!(visibility & PATH_RAY_CAMERA))
- kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
- }
-
- need_update = false;
+ if (!need_update)
+ return;
+
+ device_free(device, dscene);
+
+ Shader *bg_shader = shader;
+
+ if (use_shader) {
+ if (!bg_shader)
+ bg_shader = scene->default_background;
+ }
+ else
+ bg_shader = scene->default_empty;
+
+ /* set shader index and transparent option */
+ KernelBackground *kbackground = &dscene->data.background;
+
+ kbackground->ao_factor = (use_ao) ? ao_factor : 0.0f;
+ kbackground->ao_bounces_factor = ao_factor;
+ kbackground->ao_distance = ao_distance;
+
+ kbackground->transparent = transparent;
+ kbackground->surface_shader = scene->shader_manager->get_shader_id(bg_shader);
+
+ if (transparent && transparent_glass) {
+ /* Square twice, once for principled BSDF convention, and once for
+ * faster comparison in kernel with anisotropic roughness. */
+ kbackground->transparent_roughness_squared_threshold = sqr(
+ sqr(transparent_roughness_threshold));
+ }
+ else {
+ kbackground->transparent_roughness_squared_threshold = -1.0f;
+ }
+
+ if (bg_shader->has_volume)
+ kbackground->volume_shader = kbackground->surface_shader;
+ else
+ kbackground->volume_shader = SHADER_NONE;
+
+ /* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
+ if (bg_shader->graph->nodes.size() <= 1) {
+ kbackground->surface_shader |= SHADER_EXCLUDE_ANY;
+ }
+ /* Background present, check visibilities */
+ else {
+ if (!(visibility & PATH_RAY_DIFFUSE))
+ kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
+ if (!(visibility & PATH_RAY_GLOSSY))
+ kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
+ if (!(visibility & PATH_RAY_TRANSMIT))
+ kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
+ if (!(visibility & PATH_RAY_VOLUME_SCATTER))
+ kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
+ if (!(visibility & PATH_RAY_CAMERA))
+ kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
+ }
+
+ need_update = false;
}
void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
}
-bool Background::modified(const Background& background)
+bool Background::modified(const Background &background)
{
- return !Node::equals(background);
+ return !Node::equals(background);
}
void Background::tag_update(Scene *scene)
{
- scene->integrator->tag_update(scene);
- need_update = true;
+ scene->integrator->tag_update(scene);
+ need_update = true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h
index 17c3eaaaaf5..020db7bf6aa 100644
--- a/intern/cycles/render/background.h
+++ b/intern/cycles/render/background.h
@@ -29,34 +29,34 @@ class Scene;
class Shader;
class Background : public Node {
-public:
- NODE_DECLARE
+ public:
+ NODE_DECLARE
- float ao_factor;
- float ao_distance;
+ float ao_factor;
+ float ao_distance;
- bool use_shader;
- bool use_ao;
+ bool use_shader;
+ bool use_ao;
- uint visibility;
- Shader *shader;
+ uint visibility;
+ Shader *shader;
- bool transparent;
- bool transparent_glass;
- float transparent_roughness_threshold;
+ bool transparent;
+ bool transparent_glass;
+ float transparent_roughness_threshold;
- bool need_update;
+ bool need_update;
- Background();
- ~Background();
+ Background();
+ ~Background();
- void device_update(Device *device, DeviceScene *dscene, Scene *scene);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_free(Device *device, DeviceScene *dscene);
- bool modified(const Background& background);
- void tag_update(Scene *scene);
+ bool modified(const Background &background);
+ void tag_update(Scene *scene);
};
CCL_NAMESPACE_END
-#endif /* __BACKGROUND_H__ */
+#endif /* __BACKGROUND_H__ */
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 927e04abc7f..73893921500 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -24,221 +24,220 @@
CCL_NAMESPACE_BEGIN
-BakeData::BakeData(const int object, const size_t tri_offset, const size_t num_pixels):
-m_object(object),
-m_tri_offset(tri_offset),
-m_num_pixels(num_pixels)
+BakeData::BakeData(const int object, const size_t tri_offset, const size_t num_pixels)
+ : m_object(object), m_tri_offset(tri_offset), m_num_pixels(num_pixels)
{
- m_primitive.resize(num_pixels);
- m_u.resize(num_pixels);
- m_v.resize(num_pixels);
- m_dudx.resize(num_pixels);
- m_dudy.resize(num_pixels);
- m_dvdx.resize(num_pixels);
- m_dvdy.resize(num_pixels);
+ m_primitive.resize(num_pixels);
+ m_u.resize(num_pixels);
+ m_v.resize(num_pixels);
+ m_dudx.resize(num_pixels);
+ m_dudy.resize(num_pixels);
+ m_dvdx.resize(num_pixels);
+ m_dvdy.resize(num_pixels);
}
BakeData::~BakeData()
{
- m_primitive.clear();
- m_u.clear();
- m_v.clear();
- m_dudx.clear();
- m_dudy.clear();
- m_dvdx.clear();
- m_dvdy.clear();
+ m_primitive.clear();
+ m_u.clear();
+ m_v.clear();
+ m_dudx.clear();
+ m_dudy.clear();
+ m_dvdx.clear();
+ m_dvdy.clear();
}
void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy)
{
- m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim);
- m_u[i] = uv[0];
- m_v[i] = uv[1];
- m_dudx[i] = dudx;
- m_dudy[i] = dudy;
- m_dvdx[i] = dvdx;
- m_dvdy[i] = dvdy;
+ m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim);
+ m_u[i] = uv[0];
+ m_v[i] = uv[1];
+ m_dudx[i] = dudx;
+ m_dudy[i] = dudy;
+ m_dvdx[i] = dvdx;
+ m_dvdy[i] = dvdy;
}
void BakeData::set_null(int i)
{
- m_primitive[i] = -1;
+ m_primitive[i] = -1;
}
int BakeData::object()
{
- return m_object;
+ return m_object;
}
size_t BakeData::size()
{
- return m_num_pixels;
+ return m_num_pixels;
}
bool BakeData::is_valid(int i)
{
- return m_primitive[i] != -1;
+ return m_primitive[i] != -1;
}
uint4 BakeData::data(int i)
{
- return make_uint4(
- m_object,
- m_primitive[i],
- __float_as_int(m_u[i]),
- __float_as_int(m_v[i])
- );
+ return make_uint4(m_object, m_primitive[i], __float_as_int(m_u[i]), __float_as_int(m_v[i]));
}
uint4 BakeData::differentials(int i)
{
- return make_uint4(
- __float_as_int(m_dudx[i]),
- __float_as_int(m_dudy[i]),
- __float_as_int(m_dvdx[i]),
- __float_as_int(m_dvdy[i])
- );
+ return make_uint4(__float_as_int(m_dudx[i]),
+ __float_as_int(m_dudy[i]),
+ __float_as_int(m_dvdx[i]),
+ __float_as_int(m_dvdy[i]));
}
BakeManager::BakeManager()
{
- m_bake_data = NULL;
- m_is_baking = false;
- need_update = true;
- m_shader_limit = 512 * 512;
+ m_bake_data = NULL;
+ m_is_baking = false;
+ need_update = true;
+ m_shader_limit = 512 * 512;
}
BakeManager::~BakeManager()
{
- if(m_bake_data)
- delete m_bake_data;
+ if (m_bake_data)
+ delete m_bake_data;
}
bool BakeManager::get_baking()
{
- return m_is_baking;
+ return m_is_baking;
}
void BakeManager::set_baking(const bool value)
{
- m_is_baking = value;
+ m_is_baking = value;
}
BakeData *BakeManager::init(const int object, const size_t tri_offset, const size_t num_pixels)
{
- m_bake_data = new BakeData(object, tri_offset, num_pixels);
- return m_bake_data;
+ m_bake_data = new BakeData(object, tri_offset, num_pixels);
+ return m_bake_data;
}
void BakeManager::set_shader_limit(const size_t x, const size_t y)
{
- m_shader_limit = x * y;
- m_shader_limit = (size_t)pow(2, ceil(log(m_shader_limit)/log(2)));
+ m_shader_limit = x * y;
+ m_shader_limit = (size_t)pow(2, ceil(log(m_shader_limit) / log(2)));
}
-bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, const int pass_filter, BakeData *bake_data, float result[])
+bool BakeManager::bake(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress,
+ ShaderEvalType shader_type,
+ const int pass_filter,
+ BakeData *bake_data,
+ float result[])
{
- size_t num_pixels = bake_data->size();
-
- int num_samples = aa_samples(scene, bake_data, shader_type);
-
- /* calculate the total pixel samples for the progress bar */
- total_pixel_samples = 0;
- for(size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
- size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
- total_pixel_samples += shader_size * num_samples;
- }
- progress.reset_sample();
- progress.set_total_pixel_samples(total_pixel_samples);
-
- /* needs to be up to date for baking specific AA samples */
- dscene->data.integrator.aa_samples = num_samples;
- device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
-
- for(size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
- size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
-
- /* setup input for device task */
- device_vector<uint4> d_input(device, "bake_input", MEM_READ_ONLY);
- uint4 *d_input_data = d_input.alloc(shader_size * 2);
- size_t d_input_size = 0;
-
- for(size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
- d_input_data[d_input_size++] = bake_data->data(i);
- d_input_data[d_input_size++] = bake_data->differentials(i);
- }
-
- if(d_input_size == 0) {
- m_is_baking = false;
- return false;
- }
-
- /* run device task */
- device_vector<float4> d_output(device, "bake_output", MEM_READ_WRITE);
- d_output.alloc(shader_size);
- d_output.zero_to_device();
- d_input.copy_to_device();
-
- DeviceTask task(DeviceTask::SHADER);
- task.shader_input = d_input.device_pointer;
- task.shader_output = d_output.device_pointer;
- task.shader_eval_type = shader_type;
- task.shader_filter = pass_filter;
- task.shader_x = 0;
- task.offset = shader_offset;
- task.shader_w = d_output.size();
- task.num_samples = num_samples;
- task.get_cancel = function_bind(&Progress::get_cancel, &progress);
- task.update_progress_sample = function_bind(&Progress::add_samples_update, &progress, _1, _2);
-
- device->task_add(task);
- device->task_wait();
-
- if(progress.get_cancel()) {
- d_input.free();
- d_output.free();
- m_is_baking = false;
- return false;
- }
-
- d_output.copy_from_device(0, 1, d_output.size());
- d_input.free();
-
- /* read result */
- int k = 0;
-
- float4 *offset = d_output.data();
-
- size_t depth = 4;
- for(size_t i=shader_offset; i < (shader_offset + shader_size); i++) {
- size_t index = i * depth;
- float4 out = offset[k++];
-
- if(bake_data->is_valid(i)) {
- for(size_t j=0; j < 4; j++) {
- result[index + j] = out[j];
- }
- }
- }
-
- d_output.free();
- }
-
- m_is_baking = false;
- return true;
+ size_t num_pixels = bake_data->size();
+
+ int num_samples = aa_samples(scene, bake_data, shader_type);
+
+ /* calculate the total pixel samples for the progress bar */
+ total_pixel_samples = 0;
+ for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
+ size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
+ total_pixel_samples += shader_size * num_samples;
+ }
+ progress.reset_sample();
+ progress.set_total_pixel_samples(total_pixel_samples);
+
+ /* needs to be up to date for baking specific AA samples */
+ dscene->data.integrator.aa_samples = num_samples;
+ device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
+
+ for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
+ size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
+
+ /* setup input for device task */
+ device_vector<uint4> d_input(device, "bake_input", MEM_READ_ONLY);
+ uint4 *d_input_data = d_input.alloc(shader_size * 2);
+ size_t d_input_size = 0;
+
+ for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
+ d_input_data[d_input_size++] = bake_data->data(i);
+ d_input_data[d_input_size++] = bake_data->differentials(i);
+ }
+
+ if (d_input_size == 0) {
+ m_is_baking = false;
+ return false;
+ }
+
+ /* run device task */
+ device_vector<float4> d_output(device, "bake_output", MEM_READ_WRITE);
+ d_output.alloc(shader_size);
+ d_output.zero_to_device();
+ d_input.copy_to_device();
+
+ DeviceTask task(DeviceTask::SHADER);
+ task.shader_input = d_input.device_pointer;
+ task.shader_output = d_output.device_pointer;
+ task.shader_eval_type = shader_type;
+ task.shader_filter = pass_filter;
+ task.shader_x = 0;
+ task.offset = shader_offset;
+ task.shader_w = d_output.size();
+ task.num_samples = num_samples;
+ task.get_cancel = function_bind(&Progress::get_cancel, &progress);
+ task.update_progress_sample = function_bind(&Progress::add_samples_update, &progress, _1, _2);
+
+ device->task_add(task);
+ device->task_wait();
+
+ if (progress.get_cancel()) {
+ d_input.free();
+ d_output.free();
+ m_is_baking = false;
+ return false;
+ }
+
+ d_output.copy_from_device(0, 1, d_output.size());
+ d_input.free();
+
+ /* read result */
+ int k = 0;
+
+ float4 *offset = d_output.data();
+
+ size_t depth = 4;
+ for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
+ size_t index = i * depth;
+ float4 out = offset[k++];
+
+ if (bake_data->is_valid(i)) {
+ for (size_t j = 0; j < 4; j++) {
+ result[index + j] = out[j];
+ }
+ }
+ }
+
+ d_output.free();
+ }
+
+ m_is_baking = false;
+ return true;
}
void BakeManager::device_update(Device * /*device*/,
DeviceScene * /*dscene*/,
Scene * /*scene*/,
- Progress& progress)
+ Progress &progress)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- if(progress.get_cancel()) return;
+ if (progress.get_cancel())
+ return;
- need_update = false;
+ need_update = false;
}
void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
@@ -247,51 +246,52 @@ void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
int BakeManager::aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type)
{
- if(type == SHADER_EVAL_UV || type == SHADER_EVAL_ROUGHNESS) {
- return 1;
- }
- else if(type == SHADER_EVAL_NORMAL) {
- /* Only antialias normal if mesh has bump mapping. */
- Object *object = scene->objects[bake_data->object()];
-
- if(object->mesh) {
- foreach(Shader *shader, object->mesh->used_shaders) {
- if(shader->has_bump) {
- return scene->integrator->aa_samples;
- }
- }
- }
-
- return 1;
- }
- else {
- return scene->integrator->aa_samples;
- }
+ if (type == SHADER_EVAL_UV || type == SHADER_EVAL_ROUGHNESS) {
+ return 1;
+ }
+ else if (type == SHADER_EVAL_NORMAL) {
+ /* Only antialias normal if mesh has bump mapping. */
+ Object *object = scene->objects[bake_data->object()];
+
+ if (object->mesh) {
+ foreach (Shader *shader, object->mesh->used_shaders) {
+ if (shader->has_bump) {
+ return scene->integrator->aa_samples;
+ }
+ }
+ }
+
+ return 1;
+ }
+ else {
+ return scene->integrator->aa_samples;
+ }
}
/* Keep it synced with kernel_bake.h logic */
int BakeManager::shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter)
{
- const int component_flags = pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_COLOR);
-
- switch(type) {
- case SHADER_EVAL_AO:
- return BAKE_FILTER_AO;
- case SHADER_EVAL_SHADOW:
- return BAKE_FILTER_DIRECT;
- case SHADER_EVAL_DIFFUSE:
- return BAKE_FILTER_DIFFUSE | component_flags;
- case SHADER_EVAL_GLOSSY:
- return BAKE_FILTER_GLOSSY | component_flags;
- case SHADER_EVAL_TRANSMISSION:
- return BAKE_FILTER_TRANSMISSION | component_flags;
- case SHADER_EVAL_SUBSURFACE:
- return BAKE_FILTER_SUBSURFACE | component_flags;
- case SHADER_EVAL_COMBINED:
- return pass_filter;
- default:
- return 0;
- }
+ const int component_flags = pass_filter &
+ (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_COLOR);
+
+ switch (type) {
+ case SHADER_EVAL_AO:
+ return BAKE_FILTER_AO;
+ case SHADER_EVAL_SHADOW:
+ return BAKE_FILTER_DIRECT;
+ case SHADER_EVAL_DIFFUSE:
+ return BAKE_FILTER_DIFFUSE | component_flags;
+ case SHADER_EVAL_GLOSSY:
+ return BAKE_FILTER_GLOSSY | component_flags;
+ case SHADER_EVAL_TRANSMISSION:
+ return BAKE_FILTER_TRANSMISSION | component_flags;
+ case SHADER_EVAL_SUBSURFACE:
+ return BAKE_FILTER_SUBSURFACE | component_flags;
+ case SHADER_EVAL_COMBINED:
+ return pass_filter;
+ default:
+ return 0;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index fce8f2fa606..88537623efb 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -26,61 +26,68 @@
CCL_NAMESPACE_BEGIN
class BakeData {
-public:
- BakeData(const int object, const size_t tri_offset, const size_t num_pixels);
- ~BakeData();
-
- void set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy);
- void set_null(int i);
- int object();
- size_t size();
- uint4 data(int i);
- uint4 differentials(int i);
- bool is_valid(int i);
-
-private:
- int m_object;
- size_t m_tri_offset;
- size_t m_num_pixels;
- vector<int>m_primitive;
- vector<float>m_u;
- vector<float>m_v;
- vector<float>m_dudx;
- vector<float>m_dudy;
- vector<float>m_dvdx;
- vector<float>m_dvdy;
+ public:
+ BakeData(const int object, const size_t tri_offset, const size_t num_pixels);
+ ~BakeData();
+
+ void set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy);
+ void set_null(int i);
+ int object();
+ size_t size();
+ uint4 data(int i);
+ uint4 differentials(int i);
+ bool is_valid(int i);
+
+ private:
+ int m_object;
+ size_t m_tri_offset;
+ size_t m_num_pixels;
+ vector<int> m_primitive;
+ vector<float> m_u;
+ vector<float> m_v;
+ vector<float> m_dudx;
+ vector<float> m_dudy;
+ vector<float> m_dvdx;
+ vector<float> m_dvdy;
};
class BakeManager {
-public:
- BakeManager();
- ~BakeManager();
+ public:
+ BakeManager();
+ ~BakeManager();
- bool get_baking();
- void set_baking(const bool value);
+ bool get_baking();
+ void set_baking(const bool value);
- BakeData *init(const int object, const size_t tri_offset, const size_t num_pixels);
+ BakeData *init(const int object, const size_t tri_offset, const size_t num_pixels);
- void set_shader_limit(const size_t x, const size_t y);
+ void set_shader_limit(const size_t x, const size_t y);
- bool bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, const int pass_filter, BakeData *bake_data, float result[]);
+ bool bake(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress,
+ ShaderEvalType shader_type,
+ const int pass_filter,
+ BakeData *bake_data,
+ float result[]);
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_free(Device *device, DeviceScene *dscene);
- static int shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter);
- static int aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type);
+ static int shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter);
+ static int aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type);
- bool need_update;
+ bool need_update;
- size_t total_pixel_samples;
+ size_t total_pixel_samples;
-private:
- BakeData *m_bake_data;
- bool m_is_baking;
- size_t m_shader_limit;
+ private:
+ BakeData *m_bake_data;
+ bool m_is_baking;
+ size_t m_shader_limit;
};
CCL_NAMESPACE_END
-#endif /* __BAKE_H__ */
+#endif /* __BAKE_H__ */
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 678105aeeb1..5405aaefc1d 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -32,455 +32,458 @@ CCL_NAMESPACE_BEGIN
BufferParams::BufferParams()
{
- width = 0;
- height = 0;
+ width = 0;
+ height = 0;
- full_x = 0;
- full_y = 0;
- full_width = 0;
- full_height = 0;
+ full_x = 0;
+ full_y = 0;
+ full_width = 0;
+ full_height = 0;
- denoising_data_pass = false;
- denoising_clean_pass = false;
- denoising_prefiltered_pass = false;
+ denoising_data_pass = false;
+ denoising_clean_pass = false;
+ denoising_prefiltered_pass = false;
- Pass::add(PASS_COMBINED, passes);
+ Pass::add(PASS_COMBINED, passes);
}
-void BufferParams::get_offset_stride(int& offset, int& stride)
+void BufferParams::get_offset_stride(int &offset, int &stride)
{
- offset = -(full_x + full_y*width);
- stride = width;
+ offset = -(full_x + full_y * width);
+ stride = width;
}
-bool BufferParams::modified(const BufferParams& params)
+bool BufferParams::modified(const BufferParams &params)
{
- return !(full_x == params.full_x
- && full_y == params.full_y
- && width == params.width
- && height == params.height
- && full_width == params.full_width
- && full_height == params.full_height
- && Pass::equals(passes, params.passes));
+ return !(full_x == params.full_x && full_y == params.full_y && width == params.width &&
+ height == params.height && full_width == params.full_width &&
+ full_height == params.full_height && Pass::equals(passes, params.passes));
}
int BufferParams::get_passes_size()
{
- int size = 0;
+ int size = 0;
- for(size_t i = 0; i < passes.size(); i++)
- size += passes[i].components;
+ for (size_t i = 0; i < passes.size(); i++)
+ size += passes[i].components;
- if(denoising_data_pass) {
- size += DENOISING_PASS_SIZE_BASE;
- if(denoising_clean_pass) size += DENOISING_PASS_SIZE_CLEAN;
- if(denoising_prefiltered_pass) size += DENOISING_PASS_SIZE_PREFILTERED;
- }
+ if (denoising_data_pass) {
+ size += DENOISING_PASS_SIZE_BASE;
+ if (denoising_clean_pass)
+ size += DENOISING_PASS_SIZE_CLEAN;
+ if (denoising_prefiltered_pass)
+ size += DENOISING_PASS_SIZE_PREFILTERED;
+ }
- return align_up(size, 4);
+ return align_up(size, 4);
}
int BufferParams::get_denoising_offset()
{
- int offset = 0;
+ int offset = 0;
- for(size_t i = 0; i < passes.size(); i++)
- offset += passes[i].components;
+ for (size_t i = 0; i < passes.size(); i++)
+ offset += passes[i].components;
- return offset;
+ return offset;
}
int BufferParams::get_denoising_prefiltered_offset()
{
- assert(denoising_prefiltered_pass);
+ assert(denoising_prefiltered_pass);
- int offset = get_denoising_offset();
+ int offset = get_denoising_offset();
- offset += DENOISING_PASS_SIZE_BASE;
- if(denoising_clean_pass) {
- offset += DENOISING_PASS_SIZE_CLEAN;
- }
+ offset += DENOISING_PASS_SIZE_BASE;
+ if (denoising_clean_pass) {
+ offset += DENOISING_PASS_SIZE_CLEAN;
+ }
- return offset;
+ return offset;
}
/* Render Buffer Task */
RenderTile::RenderTile()
{
- x = 0;
- y = 0;
- w = 0;
- h = 0;
+ x = 0;
+ y = 0;
+ w = 0;
+ h = 0;
- sample = 0;
- start_sample = 0;
- num_samples = 0;
- resolution = 0;
+ sample = 0;
+ start_sample = 0;
+ num_samples = 0;
+ resolution = 0;
- offset = 0;
- stride = 0;
+ offset = 0;
+ stride = 0;
- buffer = 0;
+ buffer = 0;
- buffers = NULL;
+ buffers = NULL;
}
/* Render Buffers */
RenderBuffers::RenderBuffers(Device *device)
-: buffer(device, "RenderBuffers", MEM_READ_WRITE),
- map_neighbor_copied(false), render_time(0.0f)
+ : buffer(device, "RenderBuffers", MEM_READ_WRITE),
+ map_neighbor_copied(false),
+ render_time(0.0f)
{
}
RenderBuffers::~RenderBuffers()
{
- buffer.free();
+ buffer.free();
}
-void RenderBuffers::reset(BufferParams& params_)
+void RenderBuffers::reset(BufferParams &params_)
{
- params = params_;
+ params = params_;
- /* re-allocate buffer */
- buffer.alloc(params.width*params.height*params.get_passes_size());
- buffer.zero_to_device();
+ /* re-allocate buffer */
+ buffer.alloc(params.width * params.height * params.get_passes_size());
+ buffer.zero_to_device();
}
void RenderBuffers::zero()
{
- buffer.zero_to_device();
+ buffer.zero_to_device();
}
bool RenderBuffers::copy_from_device()
{
- if(!buffer.device_pointer)
- return false;
+ if (!buffer.device_pointer)
+ return false;
- buffer.copy_from_device(0, params.width * params.get_passes_size(), params.height);
+ buffer.copy_from_device(0, params.width * params.get_passes_size(), params.height);
- return true;
+ return true;
}
-bool RenderBuffers::get_denoising_pass_rect(int type, float exposure, int sample, int components, float *pixels)
+bool RenderBuffers::get_denoising_pass_rect(
+ int type, float exposure, int sample, int components, float *pixels)
{
- if(buffer.data() == NULL) {
- return false;
- }
-
- float scale = 1.0f;
- float alpha_scale = 1.0f/sample;
- if(type == DENOISING_PASS_PREFILTERED_COLOR ||
- type == DENOISING_PASS_CLEAN ||
- type == DENOISING_PASS_PREFILTERED_INTENSITY) {
- scale *= exposure;
- }
- else if(type == DENOISING_PASS_PREFILTERED_VARIANCE) {
- scale *= exposure*exposure * (sample - 1);
- }
-
- int offset;
- if(type == DENOISING_PASS_CLEAN) {
- /* The clean pass isn't changed by prefiltering, so we use the original one there. */
- offset = type + params.get_denoising_offset();
- scale /= sample;
- }
- else if (type == DENOISING_PASS_PREFILTERED_COLOR && !params.denoising_prefiltered_pass) {
- /* If we're not saving the prefiltering result, return the original noisy pass. */
- offset = params.get_denoising_offset() + DENOISING_PASS_COLOR;
- scale /= sample;
- }
- else {
- offset = type + params.get_denoising_prefiltered_offset();
- }
-
- int pass_stride = params.get_passes_size();
- int size = params.width*params.height;
-
- float *in = buffer.data() + offset;
-
- if(components == 1) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
- pixels[0] = in[0]*scale;
- }
- }
- else if(components == 3) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
- pixels[0] = in[0]*scale;
- pixels[1] = in[1]*scale;
- pixels[2] = in[2]*scale;
- }
- }
- else if(components == 4) {
- /* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */
- assert(params.passes[0].type == PASS_COMBINED);
- float *in_combined = buffer.data();
-
- for(int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) {
- pixels[0] = in[0]*scale;
- pixels[1] = in[1]*scale;
- pixels[2] = in[2]*scale;
- pixels[3] = saturate(in_combined[3]*alpha_scale);
- }
- }
- else {
- return false;
- }
-
- return true;
+ if (buffer.data() == NULL) {
+ return false;
+ }
+
+ float scale = 1.0f;
+ float alpha_scale = 1.0f / sample;
+ if (type == DENOISING_PASS_PREFILTERED_COLOR || type == DENOISING_PASS_CLEAN ||
+ type == DENOISING_PASS_PREFILTERED_INTENSITY) {
+ scale *= exposure;
+ }
+ else if (type == DENOISING_PASS_PREFILTERED_VARIANCE) {
+ scale *= exposure * exposure * (sample - 1);
+ }
+
+ int offset;
+ if (type == DENOISING_PASS_CLEAN) {
+ /* The clean pass isn't changed by prefiltering, so we use the original one there. */
+ offset = type + params.get_denoising_offset();
+ scale /= sample;
+ }
+ else if (type == DENOISING_PASS_PREFILTERED_COLOR && !params.denoising_prefiltered_pass) {
+ /* If we're not saving the prefiltering result, return the original noisy pass. */
+ offset = params.get_denoising_offset() + DENOISING_PASS_COLOR;
+ scale /= sample;
+ }
+ else {
+ offset = type + params.get_denoising_prefiltered_offset();
+ }
+
+ int pass_stride = params.get_passes_size();
+ int size = params.width * params.height;
+
+ float *in = buffer.data() + offset;
+
+ if (components == 1) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels++) {
+ pixels[0] = in[0] * scale;
+ }
+ }
+ else if (components == 3) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
+ pixels[0] = in[0] * scale;
+ pixels[1] = in[1] * scale;
+ pixels[2] = in[2] * scale;
+ }
+ }
+ else if (components == 4) {
+ /* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */
+ assert(params.passes[0].type == PASS_COMBINED);
+ float *in_combined = buffer.data();
+
+ for (int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) {
+ pixels[0] = in[0] * scale;
+ pixels[1] = in[1] * scale;
+ pixels[2] = in[2] * scale;
+ pixels[3] = saturate(in_combined[3] * alpha_scale);
+ }
+ }
+ else {
+ return false;
+ }
+
+ return true;
}
-bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int components, float *pixels, const string &name)
+bool RenderBuffers::get_pass_rect(
+ PassType type, float exposure, int sample, int components, float *pixels, const string &name)
{
- if(buffer.data() == NULL) {
- return false;
- }
-
- int pass_offset = 0;
-
- for(size_t j = 0; j < params.passes.size(); j++) {
- Pass& pass = params.passes[j];
-
- if(pass.type != type) {
- pass_offset += pass.components;
- continue;
- }
-
- /* Tell Cryptomatte passes apart by their name. */
- if(pass.type == PASS_CRYPTOMATTE) {
- if(pass.name != name) {
- pass_offset += pass.components;
- continue;
- }
- }
-
- float *in = buffer.data() + pass_offset;
- int pass_stride = params.get_passes_size();
-
- float scale = (pass.filter)? 1.0f/(float)sample: 1.0f;
- float scale_exposure = (pass.exposure)? scale*exposure: scale;
-
- int size = params.width*params.height;
-
- if(components == 1 && type == PASS_RENDER_TIME) {
- /* Render time is not stored by kernel, but measured per tile. */
- float val = (float) (1000.0 * render_time/(params.width * params.height * sample));
- for(int i = 0; i < size; i++, pixels++) {
- pixels[0] = val;
- }
- }
- else if(components == 1) {
- assert(pass.components == components);
-
- /* Scalar */
- if(type == PASS_DEPTH) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
- float f = *in;
- pixels[0] = (f == 0.0f)? 1e10f: f*scale_exposure;
- }
- }
- else if(type == PASS_MIST) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
- float f = *in;
- pixels[0] = saturate(f*scale_exposure);
- }
- }
+ if (buffer.data() == NULL) {
+ return false;
+ }
+
+ int pass_offset = 0;
+
+ for (size_t j = 0; j < params.passes.size(); j++) {
+ Pass &pass = params.passes[j];
+
+ if (pass.type != type) {
+ pass_offset += pass.components;
+ continue;
+ }
+
+ /* Tell Cryptomatte passes apart by their name. */
+ if (pass.type == PASS_CRYPTOMATTE) {
+ if (pass.name != name) {
+ pass_offset += pass.components;
+ continue;
+ }
+ }
+
+ float *in = buffer.data() + pass_offset;
+ int pass_stride = params.get_passes_size();
+
+ float scale = (pass.filter) ? 1.0f / (float)sample : 1.0f;
+ float scale_exposure = (pass.exposure) ? scale * exposure : scale;
+
+ int size = params.width * params.height;
+
+ if (components == 1 && type == PASS_RENDER_TIME) {
+ /* Render time is not stored by kernel, but measured per tile. */
+ float val = (float)(1000.0 * render_time / (params.width * params.height * sample));
+ for (int i = 0; i < size; i++, pixels++) {
+ pixels[0] = val;
+ }
+ }
+ else if (components == 1) {
+ assert(pass.components == components);
+
+ /* Scalar */
+ if (type == PASS_DEPTH) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels++) {
+ float f = *in;
+ pixels[0] = (f == 0.0f) ? 1e10f : f * scale_exposure;
+ }
+ }
+ else if (type == PASS_MIST) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels++) {
+ float f = *in;
+ pixels[0] = saturate(f * scale_exposure);
+ }
+ }
#ifdef WITH_CYCLES_DEBUG
- else if(type == PASS_BVH_TRAVERSED_NODES ||
- type == PASS_BVH_TRAVERSED_INSTANCES ||
- type == PASS_BVH_INTERSECTIONS ||
- type == PASS_RAY_BOUNCES)
- {
- for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
- float f = *in;
- pixels[0] = f*scale;
- }
- }
+ else if (type == PASS_BVH_TRAVERSED_NODES || type == PASS_BVH_TRAVERSED_INSTANCES ||
+ type == PASS_BVH_INTERSECTIONS || type == PASS_RAY_BOUNCES) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels++) {
+ float f = *in;
+ pixels[0] = f * scale;
+ }
+ }
#endif
- else {
- for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
- float f = *in;
- pixels[0] = f*scale_exposure;
- }
- }
- }
- else if(components == 3) {
- assert(pass.components == 4);
-
- /* RGBA */
- if(type == PASS_SHADOW) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
- float4 f = make_float4(in[0], in[1], in[2], in[3]);
- float invw = (f.w > 0.0f)? 1.0f/f.w: 1.0f;
-
- pixels[0] = f.x*invw;
- pixels[1] = f.y*invw;
- pixels[2] = f.z*invw;
- }
- }
- else if(pass.divide_type != PASS_NONE) {
- /* RGB lighting passes that need to divide out color */
- pass_offset = 0;
- for(size_t k = 0; k < params.passes.size(); k++) {
- Pass& color_pass = params.passes[k];
- if(color_pass.type == pass.divide_type)
- break;
- pass_offset += color_pass.components;
- }
-
- float *in_divide = buffer.data() + pass_offset;
-
- for(int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) {
- float3 f = make_float3(in[0], in[1], in[2]);
- float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]);
-
- f = safe_divide_even_color(f*exposure, f_divide);
-
- pixels[0] = f.x;
- pixels[1] = f.y;
- pixels[2] = f.z;
- }
- }
- else {
- /* RGB/vector */
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
- float3 f = make_float3(in[0], in[1], in[2]);
-
- pixels[0] = f.x*scale_exposure;
- pixels[1] = f.y*scale_exposure;
- pixels[2] = f.z*scale_exposure;
- }
- }
- }
- else if(components == 4) {
- assert(pass.components == components);
-
- /* RGBA */
- if(type == PASS_SHADOW) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
- float4 f = make_float4(in[0], in[1], in[2], in[3]);
- float invw = (f.w > 0.0f)? 1.0f/f.w: 1.0f;
-
- pixels[0] = f.x*invw;
- pixels[1] = f.y*invw;
- pixels[2] = f.z*invw;
- pixels[3] = 1.0f;
- }
- }
- else if(type == PASS_MOTION) {
- /* need to normalize by number of samples accumulated for motion */
- pass_offset = 0;
- for(size_t k = 0; k < params.passes.size(); k++) {
- Pass& color_pass = params.passes[k];
- if(color_pass.type == PASS_MOTION_WEIGHT)
- break;
- pass_offset += color_pass.components;
- }
-
- float *in_weight = buffer.data() + pass_offset;
-
- for(int i = 0; i < size; i++, in += pass_stride, in_weight += pass_stride, pixels += 4) {
- float4 f = make_float4(in[0], in[1], in[2], in[3]);
- float w = in_weight[0];
- float invw = (w > 0.0f)? 1.0f/w: 0.0f;
-
- pixels[0] = f.x*invw;
- pixels[1] = f.y*invw;
- pixels[2] = f.z*invw;
- pixels[3] = f.w*invw;
- }
- }
- else if(type == PASS_CRYPTOMATTE) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
- float4 f = make_float4(in[0], in[1], in[2], in[3]);
- /* x and z contain integer IDs, don't rescale them.
- y and w contain matte weights, they get scaled. */
- pixels[0] = f.x;
- pixels[1] = f.y * scale;
- pixels[2] = f.z;
- pixels[3] = f.w * scale;
- }
- }
- else {
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
- float4 f = make_float4(in[0], in[1], in[2], in[3]);
-
- pixels[0] = f.x*scale_exposure;
- pixels[1] = f.y*scale_exposure;
- pixels[2] = f.z*scale_exposure;
-
- /* clamp since alpha might be > 1.0 due to russian roulette */
- pixels[3] = saturate(f.w*scale);
- }
- }
- }
-
- return true;
- }
-
- return false;
+ else {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels++) {
+ float f = *in;
+ pixels[0] = f * scale_exposure;
+ }
+ }
+ }
+ else if (components == 3) {
+ assert(pass.components == 4);
+
+ /* RGBA */
+ if (type == PASS_SHADOW) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
+ float4 f = make_float4(in[0], in[1], in[2], in[3]);
+ float invw = (f.w > 0.0f) ? 1.0f / f.w : 1.0f;
+
+ pixels[0] = f.x * invw;
+ pixels[1] = f.y * invw;
+ pixels[2] = f.z * invw;
+ }
+ }
+ else if (pass.divide_type != PASS_NONE) {
+ /* RGB lighting passes that need to divide out color */
+ pass_offset = 0;
+ for (size_t k = 0; k < params.passes.size(); k++) {
+ Pass &color_pass = params.passes[k];
+ if (color_pass.type == pass.divide_type)
+ break;
+ pass_offset += color_pass.components;
+ }
+
+ float *in_divide = buffer.data() + pass_offset;
+
+ for (int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) {
+ float3 f = make_float3(in[0], in[1], in[2]);
+ float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]);
+
+ f = safe_divide_even_color(f * exposure, f_divide);
+
+ pixels[0] = f.x;
+ pixels[1] = f.y;
+ pixels[2] = f.z;
+ }
+ }
+ else {
+ /* RGB/vector */
+ for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
+ float3 f = make_float3(in[0], in[1], in[2]);
+
+ pixels[0] = f.x * scale_exposure;
+ pixels[1] = f.y * scale_exposure;
+ pixels[2] = f.z * scale_exposure;
+ }
+ }
+ }
+ else if (components == 4) {
+ assert(pass.components == components);
+
+ /* RGBA */
+ if (type == PASS_SHADOW) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
+ float4 f = make_float4(in[0], in[1], in[2], in[3]);
+ float invw = (f.w > 0.0f) ? 1.0f / f.w : 1.0f;
+
+ pixels[0] = f.x * invw;
+ pixels[1] = f.y * invw;
+ pixels[2] = f.z * invw;
+ pixels[3] = 1.0f;
+ }
+ }
+ else if (type == PASS_MOTION) {
+ /* need to normalize by number of samples accumulated for motion */
+ pass_offset = 0;
+ for (size_t k = 0; k < params.passes.size(); k++) {
+ Pass &color_pass = params.passes[k];
+ if (color_pass.type == PASS_MOTION_WEIGHT)
+ break;
+ pass_offset += color_pass.components;
+ }
+
+ float *in_weight = buffer.data() + pass_offset;
+
+ for (int i = 0; i < size; i++, in += pass_stride, in_weight += pass_stride, pixels += 4) {
+ float4 f = make_float4(in[0], in[1], in[2], in[3]);
+ float w = in_weight[0];
+ float invw = (w > 0.0f) ? 1.0f / w : 0.0f;
+
+ pixels[0] = f.x * invw;
+ pixels[1] = f.y * invw;
+ pixels[2] = f.z * invw;
+ pixels[3] = f.w * invw;
+ }
+ }
+ else if (type == PASS_CRYPTOMATTE) {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
+ float4 f = make_float4(in[0], in[1], in[2], in[3]);
+ /* x and z contain integer IDs, don't rescale them.
+ y and w contain matte weights, they get scaled. */
+ pixels[0] = f.x;
+ pixels[1] = f.y * scale;
+ pixels[2] = f.z;
+ pixels[3] = f.w * scale;
+ }
+ }
+ else {
+ for (int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
+ float4 f = make_float4(in[0], in[1], in[2], in[3]);
+
+ pixels[0] = f.x * scale_exposure;
+ pixels[1] = f.y * scale_exposure;
+ pixels[2] = f.z * scale_exposure;
+
+ /* clamp since alpha might be > 1.0 due to russian roulette */
+ pixels[3] = saturate(f.w * scale);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
}
/* Display Buffer */
DisplayBuffer::DisplayBuffer(Device *device, bool linear)
-: draw_width(0),
- draw_height(0),
- transparent(true), /* todo: determine from background */
- half_float(linear),
- rgba_byte(device, "display buffer byte"),
- rgba_half(device, "display buffer half")
+ : draw_width(0),
+ draw_height(0),
+ transparent(true), /* todo: determine from background */
+ half_float(linear),
+ rgba_byte(device, "display buffer byte"),
+ rgba_half(device, "display buffer half")
{
}
DisplayBuffer::~DisplayBuffer()
{
- rgba_byte.free();
- rgba_half.free();
+ rgba_byte.free();
+ rgba_half.free();
}
-void DisplayBuffer::reset(BufferParams& params_)
+void DisplayBuffer::reset(BufferParams &params_)
{
- draw_width = 0;
- draw_height = 0;
-
- params = params_;
-
- /* allocate display pixels */
- if(half_float) {
- rgba_half.alloc_to_device(params.width, params.height);
- }
- else {
- rgba_byte.alloc_to_device(params.width, params.height);
- }
+ draw_width = 0;
+ draw_height = 0;
+
+ params = params_;
+
+ /* allocate display pixels */
+ if (half_float) {
+ rgba_half.alloc_to_device(params.width, params.height);
+ }
+ else {
+ rgba_byte.alloc_to_device(params.width, params.height);
+ }
}
void DisplayBuffer::draw_set(int width, int height)
{
- assert(width <= params.width && height <= params.height);
+ assert(width <= params.width && height <= params.height);
- draw_width = width;
- draw_height = height;
+ draw_width = width;
+ draw_height = height;
}
-void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
+void DisplayBuffer::draw(Device *device, const DeviceDrawParams &draw_params)
{
- if(draw_width != 0 && draw_height != 0) {
- device_memory& rgba = (half_float)? (device_memory&)rgba_half:
- (device_memory&)rgba_byte;
-
- device->draw_pixels(
- rgba, 0,
- draw_width, draw_height, params.width, params.height,
- params.full_x, params.full_y, params.full_width, params.full_height,
- transparent, draw_params);
- }
+ if (draw_width != 0 && draw_height != 0) {
+ device_memory &rgba = (half_float) ? (device_memory &)rgba_half : (device_memory &)rgba_byte;
+
+ device->draw_pixels(rgba,
+ 0,
+ draw_width,
+ draw_height,
+ params.width,
+ params.height,
+ params.full_x,
+ params.full_y,
+ params.full_width,
+ params.full_height,
+ transparent,
+ draw_params);
+ }
}
bool DisplayBuffer::draw_ready()
{
- return (draw_width != 0 && draw_height != 0);
+ return (draw_width != 0 && draw_height != 0);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 0a010718d6d..1c49038cd4b 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -38,59 +38,65 @@ struct float4;
* Size of render buffer and how it fits in the full image (border render). */
class BufferParams {
-public:
- /* width/height of the physical buffer */
- int width;
- int height;
-
- /* offset into and width/height of the full buffer */
- int full_x;
- int full_y;
- int full_width;
- int full_height;
-
- /* passes */
- vector<Pass> passes;
- bool denoising_data_pass;
- /* If only some light path types should be denoised, an additional pass is needed. */
- bool denoising_clean_pass;
- /* When we're prefiltering the passes during rendering, we need to keep both the
- * original and the prefiltered data around because neighboring tiles might still
- * need the original data. */
- bool denoising_prefiltered_pass;
-
- /* functions */
- BufferParams();
-
- void get_offset_stride(int& offset, int& stride);
- bool modified(const BufferParams& params);
- void add_pass(PassType type);
- int get_passes_size();
- int get_denoising_offset();
- int get_denoising_prefiltered_offset();
+ public:
+ /* width/height of the physical buffer */
+ int width;
+ int height;
+
+ /* offset into and width/height of the full buffer */
+ int full_x;
+ int full_y;
+ int full_width;
+ int full_height;
+
+ /* passes */
+ vector<Pass> passes;
+ bool denoising_data_pass;
+ /* If only some light path types should be denoised, an additional pass is needed. */
+ bool denoising_clean_pass;
+ /* When we're prefiltering the passes during rendering, we need to keep both the
+ * original and the prefiltered data around because neighboring tiles might still
+ * need the original data. */
+ bool denoising_prefiltered_pass;
+
+ /* functions */
+ BufferParams();
+
+ void get_offset_stride(int &offset, int &stride);
+ bool modified(const BufferParams &params);
+ void add_pass(PassType type);
+ int get_passes_size();
+ int get_denoising_offset();
+ int get_denoising_prefiltered_offset();
};
/* Render Buffers */
class RenderBuffers {
-public:
- /* buffer parameters */
- BufferParams params;
-
- /* float buffer */
- device_vector<float> buffer;
- bool map_neighbor_copied;
- double render_time;
-
- explicit RenderBuffers(Device *device);
- ~RenderBuffers();
-
- void reset(BufferParams& params);
- void zero();
-
- bool copy_from_device();
- bool get_pass_rect(PassType type, float exposure, int sample, int components, float *pixels, const string &name);
- bool get_denoising_pass_rect(int offset, float exposure, int sample, int components, float *pixels);
+ public:
+ /* buffer parameters */
+ BufferParams params;
+
+ /* float buffer */
+ device_vector<float> buffer;
+ bool map_neighbor_copied;
+ double render_time;
+
+ explicit RenderBuffers(Device *device);
+ ~RenderBuffers();
+
+ void reset(BufferParams &params);
+ void zero();
+
+ bool copy_from_device();
+ bool get_pass_rect(PassType type,
+ float exposure,
+ int sample,
+ int components,
+ float *pixels,
+ const string &name);
+ bool get_denoising_pass_rect(
+ int offset, float exposure, int sample, int components, float *pixels);
};
/* Display Buffer
@@ -99,56 +105,56 @@ public:
* buffers to byte of half float storage */
class DisplayBuffer {
-public:
- /* buffer parameters */
- BufferParams params;
- /* dimensions for how much of the buffer is actually ready for display.
- * with progressive render we can be using only a subset of the buffer.
- * if these are zero, it means nothing can be drawn yet */
- int draw_width, draw_height;
- /* draw alpha channel? */
- bool transparent;
- /* use half float? */
- bool half_float;
- /* byte buffer for converted result */
- device_pixels<uchar4> rgba_byte;
- device_pixels<half4> rgba_half;
-
- DisplayBuffer(Device *device, bool linear = false);
- ~DisplayBuffer();
-
- void reset(BufferParams& params);
-
- void draw_set(int width, int height);
- void draw(Device *device, const DeviceDrawParams& draw_params);
- bool draw_ready();
+ public:
+ /* buffer parameters */
+ BufferParams params;
+ /* dimensions for how much of the buffer is actually ready for display.
+ * with progressive render we can be using only a subset of the buffer.
+ * if these are zero, it means nothing can be drawn yet */
+ int draw_width, draw_height;
+ /* draw alpha channel? */
+ bool transparent;
+ /* use half float? */
+ bool half_float;
+ /* byte buffer for converted result */
+ device_pixels<uchar4> rgba_byte;
+ device_pixels<half4> rgba_half;
+
+ DisplayBuffer(Device *device, bool linear = false);
+ ~DisplayBuffer();
+
+ void reset(BufferParams &params);
+
+ void draw_set(int width, int height);
+ void draw(Device *device, const DeviceDrawParams &draw_params);
+ bool draw_ready();
};
/* Render Tile
* Rendering task on a buffer */
class RenderTile {
-public:
- typedef enum { PATH_TRACE, DENOISE } Task;
+ public:
+ typedef enum { PATH_TRACE, DENOISE } Task;
- Task task;
- int x, y, w, h;
- int start_sample;
- int num_samples;
- int sample;
- int resolution;
- int offset;
- int stride;
- int tile_index;
+ Task task;
+ int x, y, w, h;
+ int start_sample;
+ int num_samples;
+ int sample;
+ int resolution;
+ int offset;
+ int stride;
+ int tile_index;
- device_ptr buffer;
- int device_size;
+ device_ptr buffer;
+ int device_size;
- RenderBuffers *buffers;
+ RenderBuffers *buffers;
- RenderTile();
+ RenderTile();
};
CCL_NAMESPACE_END
-#endif /* __BUFFERS_H__ */
+#endif /* __BUFFERS_H__ */
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 82aeb324a00..9c9070c8a90 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -39,147 +39,148 @@
CCL_NAMESPACE_BEGIN
-static float shutter_curve_eval(float x,
- array<float>& shutter_curve)
+static float shutter_curve_eval(float x, array<float> &shutter_curve)
{
- if(shutter_curve.size() == 0) {
- return 1.0f;
- }
-
- x *= shutter_curve.size();
- int index = (int)x;
- float frac = x - index;
- if(index < shutter_curve.size() - 1) {
- return lerp(shutter_curve[index], shutter_curve[index + 1], frac);
- }
- else {
- return shutter_curve[shutter_curve.size() - 1];
- }
+ if (shutter_curve.size() == 0) {
+ return 1.0f;
+ }
+
+ x *= shutter_curve.size();
+ int index = (int)x;
+ float frac = x - index;
+ if (index < shutter_curve.size() - 1) {
+ return lerp(shutter_curve[index], shutter_curve[index + 1], frac);
+ }
+ else {
+ return shutter_curve[shutter_curve.size() - 1];
+ }
}
NODE_DEFINE(Camera)
{
- NodeType* type = NodeType::add("camera", create);
-
- SOCKET_FLOAT(shuttertime, "Shutter Time", 1.0f);
-
- static NodeEnum motion_position_enum;
- motion_position_enum.insert("start", MOTION_POSITION_START);
- motion_position_enum.insert("center", MOTION_POSITION_CENTER);
- motion_position_enum.insert("end", MOTION_POSITION_END);
- SOCKET_ENUM(motion_position, "Motion Position", motion_position_enum, MOTION_POSITION_CENTER);
-
- static NodeEnum rolling_shutter_type_enum;
- rolling_shutter_type_enum.insert("none", ROLLING_SHUTTER_NONE);
- rolling_shutter_type_enum.insert("top", ROLLING_SHUTTER_TOP);
- SOCKET_ENUM(rolling_shutter_type, "Rolling Shutter Type", rolling_shutter_type_enum, ROLLING_SHUTTER_NONE);
- SOCKET_FLOAT(rolling_shutter_duration, "Rolling Shutter Duration", 0.1f);
-
- SOCKET_FLOAT_ARRAY(shutter_curve, "Shutter Curve", array<float>());
-
- SOCKET_FLOAT(aperturesize, "Aperture Size", 0.0f);
- SOCKET_FLOAT(focaldistance, "Focal Distance", 10.0f);
- SOCKET_UINT(blades, "Blades", 0);
- SOCKET_FLOAT(bladesrotation, "Blades Rotation", 0.0f);
-
- SOCKET_TRANSFORM(matrix, "Matrix", transform_identity());
- SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
-
- SOCKET_FLOAT(aperture_ratio, "Aperture Ratio", 1.0f);
-
- static NodeEnum type_enum;
- type_enum.insert("perspective", CAMERA_PERSPECTIVE);
- type_enum.insert("orthograph", CAMERA_ORTHOGRAPHIC);
- type_enum.insert("panorama", CAMERA_PANORAMA);
- SOCKET_ENUM(type, "Type", type_enum, CAMERA_PERSPECTIVE);
-
- static NodeEnum panorama_type_enum;
- panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR);
- panorama_type_enum.insert("mirrorball", PANORAMA_MIRRORBALL);
- panorama_type_enum.insert("fisheye_equidistant", PANORAMA_FISHEYE_EQUIDISTANT);
- panorama_type_enum.insert("fisheye_equisolid", PANORAMA_FISHEYE_EQUISOLID);
- SOCKET_ENUM(panorama_type, "Panorama Type", panorama_type_enum, PANORAMA_EQUIRECTANGULAR);
-
- SOCKET_FLOAT(fisheye_fov, "Fisheye FOV", M_PI_F);
- SOCKET_FLOAT(fisheye_lens, "Fisheye Lens", 10.5f);
- SOCKET_FLOAT(latitude_min, "Latitude Min", -M_PI_2_F);
- SOCKET_FLOAT(latitude_max, "Latitude Max", M_PI_2_F);
- SOCKET_FLOAT(longitude_min, "Longitude Min", -M_PI_F);
- SOCKET_FLOAT(longitude_max, "Longitude Max", M_PI_F);
- SOCKET_FLOAT(fov, "FOV", M_PI_4_F);
- SOCKET_FLOAT(fov_pre, "FOV Pre", M_PI_4_F);
- SOCKET_FLOAT(fov_post, "FOV Post", M_PI_4_F);
-
- static NodeEnum stereo_eye_enum;
- stereo_eye_enum.insert("none", STEREO_NONE);
- stereo_eye_enum.insert("left", STEREO_LEFT);
- stereo_eye_enum.insert("right", STEREO_RIGHT);
- SOCKET_ENUM(stereo_eye, "Stereo Eye", stereo_eye_enum, STEREO_NONE);
-
- SOCKET_FLOAT(interocular_distance, "Interocular Distance", 0.065f);
- SOCKET_FLOAT(convergence_distance, "Convergence Distance", 30.0f * 0.065f);
-
- SOCKET_BOOLEAN(use_pole_merge, "Use Pole Merge", false);
- SOCKET_FLOAT(pole_merge_angle_from, "Pole Merge Angle From", 60.0f * M_PI_F / 180.0f);
- SOCKET_FLOAT(pole_merge_angle_to, "Pole Merge Angle To", 75.0f * M_PI_F / 180.0f);
-
- SOCKET_FLOAT(sensorwidth, "Sensor Width", 0.036f);
- SOCKET_FLOAT(sensorheight, "Sensor Height", 0.024f);
-
- SOCKET_FLOAT(nearclip, "Near Clip", 1e-5f);
- SOCKET_FLOAT(farclip, "Far Clip", 1e5f);
-
- SOCKET_FLOAT(viewplane.left, "Viewplane Left", 0);
- SOCKET_FLOAT(viewplane.right, "Viewplane Right", 0);
- SOCKET_FLOAT(viewplane.bottom, "Viewplane Bottom", 0);
- SOCKET_FLOAT(viewplane.top, "Viewplane Top", 0);
-
- SOCKET_FLOAT(border.left, "Border Left", 0);
- SOCKET_FLOAT(border.right, "Border Right", 0);
- SOCKET_FLOAT(border.bottom, "Border Bottom", 0);
- SOCKET_FLOAT(border.top, "Border Top", 0);
-
- SOCKET_FLOAT(offscreen_dicing_scale, "Offscreen Dicing Scale", 1.0f);
-
- return type;
+ NodeType *type = NodeType::add("camera", create);
+
+ SOCKET_FLOAT(shuttertime, "Shutter Time", 1.0f);
+
+ static NodeEnum motion_position_enum;
+ motion_position_enum.insert("start", MOTION_POSITION_START);
+ motion_position_enum.insert("center", MOTION_POSITION_CENTER);
+ motion_position_enum.insert("end", MOTION_POSITION_END);
+ SOCKET_ENUM(motion_position, "Motion Position", motion_position_enum, MOTION_POSITION_CENTER);
+
+ static NodeEnum rolling_shutter_type_enum;
+ rolling_shutter_type_enum.insert("none", ROLLING_SHUTTER_NONE);
+ rolling_shutter_type_enum.insert("top", ROLLING_SHUTTER_TOP);
+ SOCKET_ENUM(rolling_shutter_type,
+ "Rolling Shutter Type",
+ rolling_shutter_type_enum,
+ ROLLING_SHUTTER_NONE);
+ SOCKET_FLOAT(rolling_shutter_duration, "Rolling Shutter Duration", 0.1f);
+
+ SOCKET_FLOAT_ARRAY(shutter_curve, "Shutter Curve", array<float>());
+
+ SOCKET_FLOAT(aperturesize, "Aperture Size", 0.0f);
+ SOCKET_FLOAT(focaldistance, "Focal Distance", 10.0f);
+ SOCKET_UINT(blades, "Blades", 0);
+ SOCKET_FLOAT(bladesrotation, "Blades Rotation", 0.0f);
+
+ SOCKET_TRANSFORM(matrix, "Matrix", transform_identity());
+ SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
+
+ SOCKET_FLOAT(aperture_ratio, "Aperture Ratio", 1.0f);
+
+ static NodeEnum type_enum;
+ type_enum.insert("perspective", CAMERA_PERSPECTIVE);
+ type_enum.insert("orthograph", CAMERA_ORTHOGRAPHIC);
+ type_enum.insert("panorama", CAMERA_PANORAMA);
+ SOCKET_ENUM(type, "Type", type_enum, CAMERA_PERSPECTIVE);
+
+ static NodeEnum panorama_type_enum;
+ panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR);
+ panorama_type_enum.insert("mirrorball", PANORAMA_MIRRORBALL);
+ panorama_type_enum.insert("fisheye_equidistant", PANORAMA_FISHEYE_EQUIDISTANT);
+ panorama_type_enum.insert("fisheye_equisolid", PANORAMA_FISHEYE_EQUISOLID);
+ SOCKET_ENUM(panorama_type, "Panorama Type", panorama_type_enum, PANORAMA_EQUIRECTANGULAR);
+
+ SOCKET_FLOAT(fisheye_fov, "Fisheye FOV", M_PI_F);
+ SOCKET_FLOAT(fisheye_lens, "Fisheye Lens", 10.5f);
+ SOCKET_FLOAT(latitude_min, "Latitude Min", -M_PI_2_F);
+ SOCKET_FLOAT(latitude_max, "Latitude Max", M_PI_2_F);
+ SOCKET_FLOAT(longitude_min, "Longitude Min", -M_PI_F);
+ SOCKET_FLOAT(longitude_max, "Longitude Max", M_PI_F);
+ SOCKET_FLOAT(fov, "FOV", M_PI_4_F);
+ SOCKET_FLOAT(fov_pre, "FOV Pre", M_PI_4_F);
+ SOCKET_FLOAT(fov_post, "FOV Post", M_PI_4_F);
+
+ static NodeEnum stereo_eye_enum;
+ stereo_eye_enum.insert("none", STEREO_NONE);
+ stereo_eye_enum.insert("left", STEREO_LEFT);
+ stereo_eye_enum.insert("right", STEREO_RIGHT);
+ SOCKET_ENUM(stereo_eye, "Stereo Eye", stereo_eye_enum, STEREO_NONE);
+
+ SOCKET_FLOAT(interocular_distance, "Interocular Distance", 0.065f);
+ SOCKET_FLOAT(convergence_distance, "Convergence Distance", 30.0f * 0.065f);
+
+ SOCKET_BOOLEAN(use_pole_merge, "Use Pole Merge", false);
+ SOCKET_FLOAT(pole_merge_angle_from, "Pole Merge Angle From", 60.0f * M_PI_F / 180.0f);
+ SOCKET_FLOAT(pole_merge_angle_to, "Pole Merge Angle To", 75.0f * M_PI_F / 180.0f);
+
+ SOCKET_FLOAT(sensorwidth, "Sensor Width", 0.036f);
+ SOCKET_FLOAT(sensorheight, "Sensor Height", 0.024f);
+
+ SOCKET_FLOAT(nearclip, "Near Clip", 1e-5f);
+ SOCKET_FLOAT(farclip, "Far Clip", 1e5f);
+
+ SOCKET_FLOAT(viewplane.left, "Viewplane Left", 0);
+ SOCKET_FLOAT(viewplane.right, "Viewplane Right", 0);
+ SOCKET_FLOAT(viewplane.bottom, "Viewplane Bottom", 0);
+ SOCKET_FLOAT(viewplane.top, "Viewplane Top", 0);
+
+ SOCKET_FLOAT(border.left, "Border Left", 0);
+ SOCKET_FLOAT(border.right, "Border Right", 0);
+ SOCKET_FLOAT(border.bottom, "Border Bottom", 0);
+ SOCKET_FLOAT(border.top, "Border Top", 0);
+
+ SOCKET_FLOAT(offscreen_dicing_scale, "Offscreen Dicing Scale", 1.0f);
+
+ return type;
}
-Camera::Camera()
-: Node(node_type)
+Camera::Camera() : Node(node_type)
{
- shutter_table_offset = TABLE_OFFSET_INVALID;
+ shutter_table_offset = TABLE_OFFSET_INVALID;
- width = 1024;
- height = 512;
- resolution = 1;
+ width = 1024;
+ height = 512;
+ resolution = 1;
- use_perspective_motion = false;
+ use_perspective_motion = false;
- shutter_curve.resize(RAMP_TABLE_SIZE);
- for(int i = 0; i < shutter_curve.size(); ++i) {
- shutter_curve[i] = 1.0f;
- }
+ shutter_curve.resize(RAMP_TABLE_SIZE);
+ for (int i = 0; i < shutter_curve.size(); ++i) {
+ shutter_curve[i] = 1.0f;
+ }
- compute_auto_viewplane();
+ compute_auto_viewplane();
- screentoworld = projection_identity();
- rastertoworld = projection_identity();
- ndctoworld = projection_identity();
- rastertocamera = projection_identity();
- cameratoworld = transform_identity();
- worldtoraster = projection_identity();
+ screentoworld = projection_identity();
+ rastertoworld = projection_identity();
+ ndctoworld = projection_identity();
+ rastertocamera = projection_identity();
+ cameratoworld = transform_identity();
+ worldtoraster = projection_identity();
- full_rastertocamera = projection_identity();
+ full_rastertocamera = projection_identity();
- dx = make_float3(0.0f, 0.0f, 0.0f);
- dy = make_float3(0.0f, 0.0f, 0.0f);
+ dx = make_float3(0.0f, 0.0f, 0.0f);
+ dy = make_float3(0.0f, 0.0f, 0.0f);
- need_update = true;
- need_device_update = true;
- need_flags_update = true;
- previous_need_motion = -1;
+ need_update = true;
+ need_device_update = true;
+ need_flags_update = true;
+ previous_need_motion = -1;
- memset((void *)&kernel_camera, 0, sizeof(kernel_camera));
+ memset((void *)&kernel_camera, 0, sizeof(kernel_camera));
}
Camera::~Camera()
@@ -188,589 +189,577 @@ Camera::~Camera()
void Camera::compute_auto_viewplane()
{
- if(type == CAMERA_PANORAMA) {
- viewplane.left = 0.0f;
- viewplane.right = 1.0f;
- viewplane.bottom = 0.0f;
- viewplane.top = 1.0f;
- }
- else {
- float aspect = (float)width/(float)height;
- if(width >= height) {
- viewplane.left = -aspect;
- viewplane.right = aspect;
- viewplane.bottom = -1.0f;
- viewplane.top = 1.0f;
- }
- else {
- viewplane.left = -1.0f;
- viewplane.right = 1.0f;
- viewplane.bottom = -1.0f/aspect;
- viewplane.top = 1.0f/aspect;
- }
- }
+ if (type == CAMERA_PANORAMA) {
+ viewplane.left = 0.0f;
+ viewplane.right = 1.0f;
+ viewplane.bottom = 0.0f;
+ viewplane.top = 1.0f;
+ }
+ else {
+ float aspect = (float)width / (float)height;
+ if (width >= height) {
+ viewplane.left = -aspect;
+ viewplane.right = aspect;
+ viewplane.bottom = -1.0f;
+ viewplane.top = 1.0f;
+ }
+ else {
+ viewplane.left = -1.0f;
+ viewplane.right = 1.0f;
+ viewplane.bottom = -1.0f / aspect;
+ viewplane.top = 1.0f / aspect;
+ }
+ }
}
void Camera::update(Scene *scene)
{
- Scene::MotionType need_motion = scene->need_motion();
-
- if(previous_need_motion != need_motion) {
- /* scene's motion model could have been changed since previous device
- * camera update this could happen for example in case when one render
- * layer has got motion pass and another not */
- need_device_update = true;
- }
-
- if(!need_update)
- return;
-
- /* Full viewport to camera border in the viewport. */
- Transform fulltoborder = transform_from_viewplane(viewport_camera_border);
- Transform bordertofull = transform_inverse(fulltoborder);
-
- /* ndc to raster */
- Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull;
- Transform full_ndctoraster = transform_scale(full_width, full_height, 1.0f) * bordertofull;
-
- /* raster to screen */
- Transform screentondc = fulltoborder * transform_from_viewplane(viewplane);
-
- Transform screentoraster = ndctoraster * screentondc;
- Transform rastertoscreen = transform_inverse(screentoraster);
- Transform full_screentoraster = full_ndctoraster * screentondc;
- Transform full_rastertoscreen = transform_inverse(full_screentoraster);
-
- /* screen to camera */
- ProjectionTransform cameratoscreen;
- if(type == CAMERA_PERSPECTIVE)
- cameratoscreen = projection_perspective(fov, nearclip, farclip);
- else if(type == CAMERA_ORTHOGRAPHIC)
- cameratoscreen = projection_orthographic(nearclip, farclip);
- else
- cameratoscreen = projection_identity();
-
- ProjectionTransform screentocamera = projection_inverse(cameratoscreen);
-
- rastertocamera = screentocamera * rastertoscreen;
- full_rastertocamera = screentocamera * full_rastertoscreen;
- cameratoraster = screentoraster * cameratoscreen;
-
- cameratoworld = matrix;
- screentoworld = cameratoworld * screentocamera;
- rastertoworld = cameratoworld * rastertocamera;
- ndctoworld = rastertoworld * ndctoraster;
-
- /* note we recompose matrices instead of taking inverses of the above, this
- * is needed to avoid inverting near degenerate matrices that happen due to
- * precision issues with large scenes */
- worldtocamera = transform_inverse(matrix);
- worldtoscreen = cameratoscreen * worldtocamera;
- worldtondc = screentondc * worldtoscreen;
- worldtoraster = ndctoraster * worldtondc;
-
- /* differentials */
- if(type == CAMERA_ORTHOGRAPHIC) {
- dx = transform_perspective_direction(&rastertocamera, make_float3(1, 0, 0));
- dy = transform_perspective_direction(&rastertocamera, make_float3(0, 1, 0));
- full_dx = transform_perspective_direction(&full_rastertocamera, make_float3(1, 0, 0));
- full_dy = transform_perspective_direction(&full_rastertocamera, make_float3(0, 1, 0));
- }
- else if(type == CAMERA_PERSPECTIVE) {
- dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
- transform_perspective(&rastertocamera, make_float3(0, 0, 0));
- dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) -
- transform_perspective(&rastertocamera, make_float3(0, 0, 0));
- full_dx = transform_perspective(&full_rastertocamera, make_float3(1, 0, 0)) -
- transform_perspective(&full_rastertocamera, make_float3(0, 0, 0));
- full_dy = transform_perspective(&full_rastertocamera, make_float3(0, 1, 0)) -
- transform_perspective(&full_rastertocamera, make_float3(0, 0, 0));
- }
- else {
- dx = make_float3(0.0f, 0.0f, 0.0f);
- dy = make_float3(0.0f, 0.0f, 0.0f);
- }
-
- dx = transform_direction(&cameratoworld, dx);
- dy = transform_direction(&cameratoworld, dy);
- full_dx = transform_direction(&cameratoworld, full_dx);
- full_dy = transform_direction(&cameratoworld, full_dy);
-
- if(type == CAMERA_PERSPECTIVE) {
- float3 v = transform_perspective(&full_rastertocamera, make_float3(full_width, full_height, 1.0f));
-
- frustum_right_normal = normalize(make_float3(v.z, 0.0f, -v.x));
- frustum_top_normal = normalize(make_float3(0.0f, v.z, -v.y));
- }
-
- /* Compute kernel camera data. */
- KernelCamera *kcam = &kernel_camera;
-
- /* store matrices */
- kcam->screentoworld = screentoworld;
- kcam->rastertoworld = rastertoworld;
- kcam->rastertocamera = rastertocamera;
- kcam->cameratoworld = cameratoworld;
- kcam->worldtocamera = worldtocamera;
- kcam->worldtoscreen = worldtoscreen;
- kcam->worldtoraster = worldtoraster;
- kcam->worldtondc = worldtondc;
- kcam->ndctoworld = ndctoworld;
-
- /* camera motion */
- kcam->num_motion_steps = 0;
- kcam->have_perspective_motion = 0;
- kernel_camera_motion.clear();
-
- /* Test if any of the transforms are actually different. */
- bool have_motion = false;
- for(size_t i = 0; i < motion.size(); i++) {
- have_motion = have_motion || motion[i] != matrix;
- }
-
- if(need_motion == Scene::MOTION_PASS) {
- /* TODO(sergey): Support perspective (zoom, fov) motion. */
- if(type == CAMERA_PANORAMA) {
- if(have_motion) {
- kcam->motion_pass_pre = transform_inverse(motion[0]);
- kcam->motion_pass_post = transform_inverse(motion[motion.size()-1]);
- }
- else {
- kcam->motion_pass_pre = kcam->worldtocamera;
- kcam->motion_pass_post = kcam->worldtocamera;
- }
- }
- else {
- if(have_motion) {
- kcam->perspective_pre = cameratoraster * transform_inverse(motion[0]);
- kcam->perspective_post = cameratoraster * transform_inverse(motion[motion.size()-1]);
- }
- else {
- kcam->perspective_pre = worldtoraster;
- kcam->perspective_post = worldtoraster;
- }
- }
- }
- else if(need_motion == Scene::MOTION_BLUR) {
- if(have_motion) {
- kernel_camera_motion.resize(motion.size());
- transform_motion_decompose(kernel_camera_motion.data(), motion.data(), motion.size());
- kcam->num_motion_steps = motion.size();
- }
-
- /* TODO(sergey): Support other types of camera. */
- if(use_perspective_motion && type == CAMERA_PERSPECTIVE) {
- /* TODO(sergey): Move to an utility function and de-duplicate with
- * calculation above.
- */
- ProjectionTransform screentocamera_pre =
- projection_inverse(projection_perspective(fov_pre,
- nearclip,
- farclip));
- ProjectionTransform screentocamera_post =
- projection_inverse(projection_perspective(fov_post,
- nearclip,
- farclip));
-
- kcam->perspective_pre = screentocamera_pre * rastertoscreen;
- kcam->perspective_post = screentocamera_post * rastertoscreen;
- kcam->have_perspective_motion = 1;
- }
- }
-
- /* depth of field */
- kcam->aperturesize = aperturesize;
- kcam->focaldistance = focaldistance;
- kcam->blades = (blades < 3)? 0.0f: blades;
- kcam->bladesrotation = bladesrotation;
-
- /* motion blur */
- kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: -1.0f;
-
- /* type */
- kcam->type = type;
-
- /* anamorphic lens bokeh */
- kcam->inv_aperture_ratio = 1.0f / aperture_ratio;
-
- /* panorama */
- kcam->panorama_type = panorama_type;
- kcam->fisheye_fov = fisheye_fov;
- kcam->fisheye_lens = fisheye_lens;
- kcam->equirectangular_range = make_float4(longitude_min - longitude_max, -longitude_min,
- latitude_min - latitude_max, -latitude_min + M_PI_2_F);
-
- switch(stereo_eye) {
- case STEREO_LEFT:
- kcam->interocular_offset = -interocular_distance * 0.5f;
- break;
- case STEREO_RIGHT:
- kcam->interocular_offset = interocular_distance * 0.5f;
- break;
- case STEREO_NONE:
- default:
- kcam->interocular_offset = 0.0f;
- break;
- }
-
- kcam->convergence_distance = convergence_distance;
- if(use_pole_merge) {
- kcam->pole_merge_angle_from = pole_merge_angle_from;
- kcam->pole_merge_angle_to = pole_merge_angle_to;
- }
- else {
- kcam->pole_merge_angle_from = -1.0f;
- kcam->pole_merge_angle_to = -1.0f;
- }
-
- /* sensor size */
- kcam->sensorwidth = sensorwidth;
- kcam->sensorheight = sensorheight;
-
- /* render size */
- kcam->width = width;
- kcam->height = height;
- kcam->resolution = resolution;
-
- /* store differentials */
- kcam->dx = float3_to_float4(dx);
- kcam->dy = float3_to_float4(dy);
-
- /* clipping */
- kcam->nearclip = nearclip;
- kcam->cliplength = (farclip == FLT_MAX)? FLT_MAX: farclip - nearclip;
-
- /* Camera in volume. */
- kcam->is_inside_volume = 0;
-
- /* Rolling shutter effect */
- kcam->rolling_shutter_type = rolling_shutter_type;
- kcam->rolling_shutter_duration = rolling_shutter_duration;
-
- /* Set further update flags */
- need_update = false;
- need_device_update = true;
- need_flags_update = true;
- previous_need_motion = need_motion;
+ Scene::MotionType need_motion = scene->need_motion();
+
+ if (previous_need_motion != need_motion) {
+ /* scene's motion model could have been changed since previous device
+ * camera update this could happen for example in case when one render
+ * layer has got motion pass and another not */
+ need_device_update = true;
+ }
+
+ if (!need_update)
+ return;
+
+ /* Full viewport to camera border in the viewport. */
+ Transform fulltoborder = transform_from_viewplane(viewport_camera_border);
+ Transform bordertofull = transform_inverse(fulltoborder);
+
+ /* ndc to raster */
+ Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull;
+ Transform full_ndctoraster = transform_scale(full_width, full_height, 1.0f) * bordertofull;
+
+ /* raster to screen */
+ Transform screentondc = fulltoborder * transform_from_viewplane(viewplane);
+
+ Transform screentoraster = ndctoraster * screentondc;
+ Transform rastertoscreen = transform_inverse(screentoraster);
+ Transform full_screentoraster = full_ndctoraster * screentondc;
+ Transform full_rastertoscreen = transform_inverse(full_screentoraster);
+
+ /* screen to camera */
+ ProjectionTransform cameratoscreen;
+ if (type == CAMERA_PERSPECTIVE)
+ cameratoscreen = projection_perspective(fov, nearclip, farclip);
+ else if (type == CAMERA_ORTHOGRAPHIC)
+ cameratoscreen = projection_orthographic(nearclip, farclip);
+ else
+ cameratoscreen = projection_identity();
+
+ ProjectionTransform screentocamera = projection_inverse(cameratoscreen);
+
+ rastertocamera = screentocamera * rastertoscreen;
+ full_rastertocamera = screentocamera * full_rastertoscreen;
+ cameratoraster = screentoraster * cameratoscreen;
+
+ cameratoworld = matrix;
+ screentoworld = cameratoworld * screentocamera;
+ rastertoworld = cameratoworld * rastertocamera;
+ ndctoworld = rastertoworld * ndctoraster;
+
+ /* note we recompose matrices instead of taking inverses of the above, this
+ * is needed to avoid inverting near degenerate matrices that happen due to
+ * precision issues with large scenes */
+ worldtocamera = transform_inverse(matrix);
+ worldtoscreen = cameratoscreen * worldtocamera;
+ worldtondc = screentondc * worldtoscreen;
+ worldtoraster = ndctoraster * worldtondc;
+
+ /* differentials */
+ if (type == CAMERA_ORTHOGRAPHIC) {
+ dx = transform_perspective_direction(&rastertocamera, make_float3(1, 0, 0));
+ dy = transform_perspective_direction(&rastertocamera, make_float3(0, 1, 0));
+ full_dx = transform_perspective_direction(&full_rastertocamera, make_float3(1, 0, 0));
+ full_dy = transform_perspective_direction(&full_rastertocamera, make_float3(0, 1, 0));
+ }
+ else if (type == CAMERA_PERSPECTIVE) {
+ dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
+ transform_perspective(&rastertocamera, make_float3(0, 0, 0));
+ dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) -
+ transform_perspective(&rastertocamera, make_float3(0, 0, 0));
+ full_dx = transform_perspective(&full_rastertocamera, make_float3(1, 0, 0)) -
+ transform_perspective(&full_rastertocamera, make_float3(0, 0, 0));
+ full_dy = transform_perspective(&full_rastertocamera, make_float3(0, 1, 0)) -
+ transform_perspective(&full_rastertocamera, make_float3(0, 0, 0));
+ }
+ else {
+ dx = make_float3(0.0f, 0.0f, 0.0f);
+ dy = make_float3(0.0f, 0.0f, 0.0f);
+ }
+
+ dx = transform_direction(&cameratoworld, dx);
+ dy = transform_direction(&cameratoworld, dy);
+ full_dx = transform_direction(&cameratoworld, full_dx);
+ full_dy = transform_direction(&cameratoworld, full_dy);
+
+ if (type == CAMERA_PERSPECTIVE) {
+ float3 v = transform_perspective(&full_rastertocamera,
+ make_float3(full_width, full_height, 1.0f));
+
+ frustum_right_normal = normalize(make_float3(v.z, 0.0f, -v.x));
+ frustum_top_normal = normalize(make_float3(0.0f, v.z, -v.y));
+ }
+
+ /* Compute kernel camera data. */
+ KernelCamera *kcam = &kernel_camera;
+
+ /* store matrices */
+ kcam->screentoworld = screentoworld;
+ kcam->rastertoworld = rastertoworld;
+ kcam->rastertocamera = rastertocamera;
+ kcam->cameratoworld = cameratoworld;
+ kcam->worldtocamera = worldtocamera;
+ kcam->worldtoscreen = worldtoscreen;
+ kcam->worldtoraster = worldtoraster;
+ kcam->worldtondc = worldtondc;
+ kcam->ndctoworld = ndctoworld;
+
+ /* camera motion */
+ kcam->num_motion_steps = 0;
+ kcam->have_perspective_motion = 0;
+ kernel_camera_motion.clear();
+
+ /* Test if any of the transforms are actually different. */
+ bool have_motion = false;
+ for (size_t i = 0; i < motion.size(); i++) {
+ have_motion = have_motion || motion[i] != matrix;
+ }
+
+ if (need_motion == Scene::MOTION_PASS) {
+ /* TODO(sergey): Support perspective (zoom, fov) motion. */
+ if (type == CAMERA_PANORAMA) {
+ if (have_motion) {
+ kcam->motion_pass_pre = transform_inverse(motion[0]);
+ kcam->motion_pass_post = transform_inverse(motion[motion.size() - 1]);
+ }
+ else {
+ kcam->motion_pass_pre = kcam->worldtocamera;
+ kcam->motion_pass_post = kcam->worldtocamera;
+ }
+ }
+ else {
+ if (have_motion) {
+ kcam->perspective_pre = cameratoraster * transform_inverse(motion[0]);
+ kcam->perspective_post = cameratoraster * transform_inverse(motion[motion.size() - 1]);
+ }
+ else {
+ kcam->perspective_pre = worldtoraster;
+ kcam->perspective_post = worldtoraster;
+ }
+ }
+ }
+ else if (need_motion == Scene::MOTION_BLUR) {
+ if (have_motion) {
+ kernel_camera_motion.resize(motion.size());
+ transform_motion_decompose(kernel_camera_motion.data(), motion.data(), motion.size());
+ kcam->num_motion_steps = motion.size();
+ }
+
+ /* TODO(sergey): Support other types of camera. */
+ if (use_perspective_motion && type == CAMERA_PERSPECTIVE) {
+ /* TODO(sergey): Move to an utility function and de-duplicate with
+ * calculation above.
+ */
+ ProjectionTransform screentocamera_pre = projection_inverse(
+ projection_perspective(fov_pre, nearclip, farclip));
+ ProjectionTransform screentocamera_post = projection_inverse(
+ projection_perspective(fov_post, nearclip, farclip));
+
+ kcam->perspective_pre = screentocamera_pre * rastertoscreen;
+ kcam->perspective_post = screentocamera_post * rastertoscreen;
+ kcam->have_perspective_motion = 1;
+ }
+ }
+
+ /* depth of field */
+ kcam->aperturesize = aperturesize;
+ kcam->focaldistance = focaldistance;
+ kcam->blades = (blades < 3) ? 0.0f : blades;
+ kcam->bladesrotation = bladesrotation;
+
+ /* motion blur */
+ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime : -1.0f;
+
+ /* type */
+ kcam->type = type;
+
+ /* anamorphic lens bokeh */
+ kcam->inv_aperture_ratio = 1.0f / aperture_ratio;
+
+ /* panorama */
+ kcam->panorama_type = panorama_type;
+ kcam->fisheye_fov = fisheye_fov;
+ kcam->fisheye_lens = fisheye_lens;
+ kcam->equirectangular_range = make_float4(longitude_min - longitude_max,
+ -longitude_min,
+ latitude_min - latitude_max,
+ -latitude_min + M_PI_2_F);
+
+ switch (stereo_eye) {
+ case STEREO_LEFT:
+ kcam->interocular_offset = -interocular_distance * 0.5f;
+ break;
+ case STEREO_RIGHT:
+ kcam->interocular_offset = interocular_distance * 0.5f;
+ break;
+ case STEREO_NONE:
+ default:
+ kcam->interocular_offset = 0.0f;
+ break;
+ }
+
+ kcam->convergence_distance = convergence_distance;
+ if (use_pole_merge) {
+ kcam->pole_merge_angle_from = pole_merge_angle_from;
+ kcam->pole_merge_angle_to = pole_merge_angle_to;
+ }
+ else {
+ kcam->pole_merge_angle_from = -1.0f;
+ kcam->pole_merge_angle_to = -1.0f;
+ }
+
+ /* sensor size */
+ kcam->sensorwidth = sensorwidth;
+ kcam->sensorheight = sensorheight;
+
+ /* render size */
+ kcam->width = width;
+ kcam->height = height;
+ kcam->resolution = resolution;
+
+ /* store differentials */
+ kcam->dx = float3_to_float4(dx);
+ kcam->dy = float3_to_float4(dy);
+
+ /* clipping */
+ kcam->nearclip = nearclip;
+ kcam->cliplength = (farclip == FLT_MAX) ? FLT_MAX : farclip - nearclip;
+
+ /* Camera in volume. */
+ kcam->is_inside_volume = 0;
+
+ /* Rolling shutter effect */
+ kcam->rolling_shutter_type = rolling_shutter_type;
+ kcam->rolling_shutter_duration = rolling_shutter_duration;
+
+ /* Set further update flags */
+ need_update = false;
+ need_device_update = true;
+ need_flags_update = true;
+ previous_need_motion = need_motion;
}
-void Camera::device_update(Device * /* device */,
- DeviceScene *dscene,
- Scene *scene)
+void Camera::device_update(Device * /* device */, DeviceScene *dscene, Scene *scene)
{
- update(scene);
-
- if(!need_device_update)
- return;
-
- scene->lookup_tables->remove_table(&shutter_table_offset);
- if(kernel_camera.shuttertime != -1.0f) {
- vector<float> shutter_table;
- util_cdf_inverted(SHUTTER_TABLE_SIZE,
- 0.0f,
- 1.0f,
- function_bind(shutter_curve_eval, _1, shutter_curve),
- false,
- shutter_table);
- shutter_table_offset = scene->lookup_tables->add_table(dscene,
- shutter_table);
- kernel_camera.shutter_table_offset = (int)shutter_table_offset;
- }
-
- dscene->data.cam = kernel_camera;
-
- size_t num_motion_steps = kernel_camera_motion.size();
- if(num_motion_steps) {
- DecomposedTransform *camera_motion = dscene->camera_motion.alloc(num_motion_steps);
- memcpy(camera_motion, kernel_camera_motion.data(), sizeof(*camera_motion) * num_motion_steps);
- dscene->camera_motion.copy_to_device();
- }
- else {
- dscene->camera_motion.free();
- }
+ update(scene);
+
+ if (!need_device_update)
+ return;
+
+ scene->lookup_tables->remove_table(&shutter_table_offset);
+ if (kernel_camera.shuttertime != -1.0f) {
+ vector<float> shutter_table;
+ util_cdf_inverted(SHUTTER_TABLE_SIZE,
+ 0.0f,
+ 1.0f,
+ function_bind(shutter_curve_eval, _1, shutter_curve),
+ false,
+ shutter_table);
+ shutter_table_offset = scene->lookup_tables->add_table(dscene, shutter_table);
+ kernel_camera.shutter_table_offset = (int)shutter_table_offset;
+ }
+
+ dscene->data.cam = kernel_camera;
+
+ size_t num_motion_steps = kernel_camera_motion.size();
+ if (num_motion_steps) {
+ DecomposedTransform *camera_motion = dscene->camera_motion.alloc(num_motion_steps);
+ memcpy(camera_motion, kernel_camera_motion.data(), sizeof(*camera_motion) * num_motion_steps);
+ dscene->camera_motion.copy_to_device();
+ }
+ else {
+ dscene->camera_motion.free();
+ }
}
-void Camera::device_update_volume(Device * /*device*/,
- DeviceScene *dscene,
- Scene *scene)
+void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scene *scene)
{
- if(!need_device_update && !need_flags_update) {
- return;
- }
- KernelCamera *kcam = &dscene->data.cam;
- BoundBox viewplane_boundbox = viewplane_bounds_get();
- for(size_t i = 0; i < scene->objects.size(); ++i) {
- Object *object = scene->objects[i];
- if(object->mesh->has_volume &&
- viewplane_boundbox.intersects(object->bounds))
- {
- /* TODO(sergey): Consider adding more grained check. */
- VLOG(1) << "Detected camera inside volume.";
- kcam->is_inside_volume = 1;
- break;
- }
- }
- if(!kcam->is_inside_volume) {
- VLOG(1) << "Camera is outside of the volume.";
- }
- need_device_update = false;
- need_flags_update = false;
+ if (!need_device_update && !need_flags_update) {
+ return;
+ }
+ KernelCamera *kcam = &dscene->data.cam;
+ BoundBox viewplane_boundbox = viewplane_bounds_get();
+ for (size_t i = 0; i < scene->objects.size(); ++i) {
+ Object *object = scene->objects[i];
+ if (object->mesh->has_volume && viewplane_boundbox.intersects(object->bounds)) {
+ /* TODO(sergey): Consider adding more grained check. */
+ VLOG(1) << "Detected camera inside volume.";
+ kcam->is_inside_volume = 1;
+ break;
+ }
+ }
+ if (!kcam->is_inside_volume) {
+ VLOG(1) << "Camera is outside of the volume.";
+ }
+ need_device_update = false;
+ need_flags_update = false;
}
-void Camera::device_free(Device * /*device*/,
- DeviceScene *dscene,
- Scene *scene)
+void Camera::device_free(Device * /*device*/, DeviceScene *dscene, Scene *scene)
{
- scene->lookup_tables->remove_table(&shutter_table_offset);
- dscene->camera_motion.free();
+ scene->lookup_tables->remove_table(&shutter_table_offset);
+ dscene->camera_motion.free();
}
-bool Camera::modified(const Camera& cam)
+bool Camera::modified(const Camera &cam)
{
- return !Node::equals(cam);
+ return !Node::equals(cam);
}
-bool Camera::motion_modified(const Camera& cam)
+bool Camera::motion_modified(const Camera &cam)
{
- return !((motion == cam.motion) &&
- (use_perspective_motion == cam.use_perspective_motion));
+ return !((motion == cam.motion) && (use_perspective_motion == cam.use_perspective_motion));
}
void Camera::tag_update()
{
- need_update = true;
+ need_update = true;
}
float3 Camera::transform_raster_to_world(float raster_x, float raster_y)
{
- float3 D, P;
- if(type == CAMERA_PERSPECTIVE) {
- D = transform_perspective(&rastertocamera,
- make_float3(raster_x, raster_y, 0.0f));
- float3 Pclip = normalize(D);
- P = make_float3(0.0f, 0.0f, 0.0f);
- /* TODO(sergey): Aperture support? */
- P = transform_point(&cameratoworld, P);
- D = normalize(transform_direction(&cameratoworld, D));
- /* TODO(sergey): Clipping is conditional in kernel, and hence it could
- * be mistakes in here, currently leading to wrong camera-in-volume
- * detection.
- */
- P += nearclip * D / Pclip.z;
- }
- else if(type == CAMERA_ORTHOGRAPHIC) {
- D = make_float3(0.0f, 0.0f, 1.0f);
- /* TODO(sergey): Aperture support? */
- P = transform_perspective(&rastertocamera,
- make_float3(raster_x, raster_y, 0.0f));
- P = transform_point(&cameratoworld, P);
- D = normalize(transform_direction(&cameratoworld, D));
- }
- else {
- assert(!"unsupported camera type");
- }
- return P;
+ float3 D, P;
+ if (type == CAMERA_PERSPECTIVE) {
+ D = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+ float3 Pclip = normalize(D);
+ P = make_float3(0.0f, 0.0f, 0.0f);
+ /* TODO(sergey): Aperture support? */
+ P = transform_point(&cameratoworld, P);
+ D = normalize(transform_direction(&cameratoworld, D));
+ /* TODO(sergey): Clipping is conditional in kernel, and hence it could
+ * be mistakes in here, currently leading to wrong camera-in-volume
+ * detection.
+ */
+ P += nearclip * D / Pclip.z;
+ }
+ else if (type == CAMERA_ORTHOGRAPHIC) {
+ D = make_float3(0.0f, 0.0f, 1.0f);
+ /* TODO(sergey): Aperture support? */
+ P = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+ P = transform_point(&cameratoworld, P);
+ D = normalize(transform_direction(&cameratoworld, D));
+ }
+ else {
+ assert(!"unsupported camera type");
+ }
+ return P;
}
BoundBox Camera::viewplane_bounds_get()
{
- /* TODO(sergey): This is all rather stupid, but is there a way to perform
- * checks we need in a more clear and smart fasion?
- */
- BoundBox bounds = BoundBox::empty;
-
- if(type == CAMERA_PANORAMA) {
- if(use_spherical_stereo == false) {
- bounds.grow(make_float3(cameratoworld.x.w,
- cameratoworld.y.w,
- cameratoworld.z.w));
- }
- else {
- float half_eye_distance = interocular_distance * 0.5f;
-
- bounds.grow(make_float3(cameratoworld.x.w + half_eye_distance,
- cameratoworld.y.w,
- cameratoworld.z.w));
-
- bounds.grow(make_float3(cameratoworld.z.w,
- cameratoworld.y.w + half_eye_distance,
- cameratoworld.z.w));
-
- bounds.grow(make_float3(cameratoworld.x.w - half_eye_distance,
- cameratoworld.y.w,
- cameratoworld.z.w));
-
- bounds.grow(make_float3(cameratoworld.x.w,
- cameratoworld.y.w - half_eye_distance,
- cameratoworld.z.w));
- }
- }
- else {
- bounds.grow(transform_raster_to_world(0.0f, 0.0f));
- bounds.grow(transform_raster_to_world(0.0f, (float)height));
- bounds.grow(transform_raster_to_world((float)width, (float)height));
- bounds.grow(transform_raster_to_world((float)width, 0.0f));
- if(type == CAMERA_PERSPECTIVE) {
- /* Center point has the most distance in local Z axis,
- * use it to construct bounding box/
- */
- bounds.grow(transform_raster_to_world(0.5f*width, 0.5f*height));
- }
- }
- return bounds;
+ /* TODO(sergey): This is all rather stupid, but is there a way to perform
+ * checks we need in a more clear and smart fasion?
+ */
+ BoundBox bounds = BoundBox::empty;
+
+ if (type == CAMERA_PANORAMA) {
+ if (use_spherical_stereo == false) {
+ bounds.grow(make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w));
+ }
+ else {
+ float half_eye_distance = interocular_distance * 0.5f;
+
+ bounds.grow(make_float3(
+ cameratoworld.x.w + half_eye_distance, cameratoworld.y.w, cameratoworld.z.w));
+
+ bounds.grow(make_float3(
+ cameratoworld.z.w, cameratoworld.y.w + half_eye_distance, cameratoworld.z.w));
+
+ bounds.grow(make_float3(
+ cameratoworld.x.w - half_eye_distance, cameratoworld.y.w, cameratoworld.z.w));
+
+ bounds.grow(make_float3(
+ cameratoworld.x.w, cameratoworld.y.w - half_eye_distance, cameratoworld.z.w));
+ }
+ }
+ else {
+ bounds.grow(transform_raster_to_world(0.0f, 0.0f));
+ bounds.grow(transform_raster_to_world(0.0f, (float)height));
+ bounds.grow(transform_raster_to_world((float)width, (float)height));
+ bounds.grow(transform_raster_to_world((float)width, 0.0f));
+ if (type == CAMERA_PERSPECTIVE) {
+ /* Center point has the most distance in local Z axis,
+ * use it to construct bounding box/
+ */
+ bounds.grow(transform_raster_to_world(0.5f * width, 0.5f * height));
+ }
+ }
+ return bounds;
}
float Camera::world_to_raster_size(float3 P)
{
- float res = 1.0f;
-
- if(type == CAMERA_ORTHOGRAPHIC) {
- res = min(len(full_dx), len(full_dy));
-
- if(offscreen_dicing_scale > 1.0f) {
- float3 p = transform_point(&worldtocamera, P);
- float3 v = transform_perspective(&full_rastertocamera, make_float3(full_width, full_height, 0.0f));
-
- /* Create point clamped to frustum */
- float3 c;
- c.x = max(-v.x, min(v.x, p.x));
- c.y = max(-v.y, min(v.y, p.y));
- c.z = max(0.0f, p.z);
-
- float f_dist = len(p - c) / sqrtf((v.x*v.x+v.y*v.y)*0.5f);
-
- if(f_dist > 0.0f) {
- res += res * f_dist * (offscreen_dicing_scale - 1.0f);
- }
- }
- }
- else if(type == CAMERA_PERSPECTIVE) {
- /* Calculate as if point is directly ahead of the camera. */
- float3 raster = make_float3(0.5f*full_width, 0.5f*full_height, 0.0f);
- float3 Pcamera = transform_perspective(&full_rastertocamera, raster);
-
- /* dDdx */
- float3 Ddiff = transform_direction(&cameratoworld, Pcamera);
- float3 dx = len_squared(full_dx) < len_squared(full_dy) ? full_dx : full_dy;
- float3 dDdx = normalize(Ddiff + dx) - normalize(Ddiff);
-
- /* dPdx */
- float dist = len(transform_point(&worldtocamera, P));
- float3 D = normalize(Ddiff);
- res = len(dist*dDdx - dot(dist*dDdx, D)*D);
-
- /* Decent approx distance to frustum (doesn't handle corners correctly, but not that big of a deal) */
- float f_dist = 0.0f;
-
- if(offscreen_dicing_scale > 1.0f) {
- float3 p = transform_point(&worldtocamera, P);
-
- /* Distance from the four planes */
- float r = dot(p, frustum_right_normal);
- float t = dot(p, frustum_top_normal);
- p = make_float3(-p.x, -p.y, p.z);
- float l = dot(p, frustum_right_normal);
- float b = dot(p, frustum_top_normal);
- p = make_float3(-p.x, -p.y, p.z);
-
- if(r <= 0.0f && l <= 0.0f && t <= 0.0f && b <= 0.0f) {
- /* Point is inside frustum */
- f_dist = 0.0f;
- }
- else if(r > 0.0f && l > 0.0f && t > 0.0f && b > 0.0f) {
- /* Point is behind frustum */
- f_dist = len(p);
- }
- else {
- /* Point may be behind or off to the side, need to check */
- float3 along_right = make_float3(-frustum_right_normal.z, 0.0f, frustum_right_normal.x);
- float3 along_left = make_float3(frustum_right_normal.z, 0.0f, frustum_right_normal.x);
- float3 along_top = make_float3(0.0f, -frustum_top_normal.z, frustum_top_normal.y);
- float3 along_bottom = make_float3(0.0f, frustum_top_normal.z, frustum_top_normal.y);
-
- float dist[] = {r, l, t, b};
- float3 along[] = {along_right, along_left, along_top, along_bottom};
-
- bool test_o = false;
-
- float *d = dist;
- float3 *a = along;
- for(int i = 0; i < 4; i++, d++, a++) {
- /* Test if we should check this side at all */
- if(*d > 0.0f) {
- if(dot(p, *a) >= 0.0f) {
- /* We are in front of the back edge of this side of the frustum */
- f_dist = max(f_dist, *d);
- }
- else {
- /* Possibly far enough behind the frustum to use distance to origin instead of edge */
- test_o = true;
- }
- }
- }
-
- if(test_o) {
- f_dist = (f_dist > 0) ? min(f_dist, len(p)) : len(p);
- }
- }
-
- if(f_dist > 0.0f) {
- res += len(dDdx - dot(dDdx, D)*D) * f_dist * (offscreen_dicing_scale - 1.0f);
- }
- }
- }
- else if(type == CAMERA_PANORAMA) {
- float3 D = transform_point(&worldtocamera, P);
- float dist = len(D);
-
- Ray ray = {{0}};
-
- /* Distortion can become so great that the results become meaningless, there
- * may be a better way to do this, but calculating differentials from the
- * point directly ahead seems to produce good enough results. */
+ float res = 1.0f;
+
+ if (type == CAMERA_ORTHOGRAPHIC) {
+ res = min(len(full_dx), len(full_dy));
+
+ if (offscreen_dicing_scale > 1.0f) {
+ float3 p = transform_point(&worldtocamera, P);
+ float3 v = transform_perspective(&full_rastertocamera,
+ make_float3(full_width, full_height, 0.0f));
+
+ /* Create point clamped to frustum */
+ float3 c;
+ c.x = max(-v.x, min(v.x, p.x));
+ c.y = max(-v.y, min(v.y, p.y));
+ c.z = max(0.0f, p.z);
+
+ float f_dist = len(p - c) / sqrtf((v.x * v.x + v.y * v.y) * 0.5f);
+
+ if (f_dist > 0.0f) {
+ res += res * f_dist * (offscreen_dicing_scale - 1.0f);
+ }
+ }
+ }
+ else if (type == CAMERA_PERSPECTIVE) {
+ /* Calculate as if point is directly ahead of the camera. */
+ float3 raster = make_float3(0.5f * full_width, 0.5f * full_height, 0.0f);
+ float3 Pcamera = transform_perspective(&full_rastertocamera, raster);
+
+ /* dDdx */
+ float3 Ddiff = transform_direction(&cameratoworld, Pcamera);
+ float3 dx = len_squared(full_dx) < len_squared(full_dy) ? full_dx : full_dy;
+ float3 dDdx = normalize(Ddiff + dx) - normalize(Ddiff);
+
+ /* dPdx */
+ float dist = len(transform_point(&worldtocamera, P));
+ float3 D = normalize(Ddiff);
+ res = len(dist * dDdx - dot(dist * dDdx, D) * D);
+
+ /* Decent approx distance to frustum (doesn't handle corners correctly, but not that big of a deal) */
+ float f_dist = 0.0f;
+
+ if (offscreen_dicing_scale > 1.0f) {
+ float3 p = transform_point(&worldtocamera, P);
+
+ /* Distance from the four planes */
+ float r = dot(p, frustum_right_normal);
+ float t = dot(p, frustum_top_normal);
+ p = make_float3(-p.x, -p.y, p.z);
+ float l = dot(p, frustum_right_normal);
+ float b = dot(p, frustum_top_normal);
+ p = make_float3(-p.x, -p.y, p.z);
+
+ if (r <= 0.0f && l <= 0.0f && t <= 0.0f && b <= 0.0f) {
+ /* Point is inside frustum */
+ f_dist = 0.0f;
+ }
+ else if (r > 0.0f && l > 0.0f && t > 0.0f && b > 0.0f) {
+ /* Point is behind frustum */
+ f_dist = len(p);
+ }
+ else {
+ /* Point may be behind or off to the side, need to check */
+ float3 along_right = make_float3(-frustum_right_normal.z, 0.0f, frustum_right_normal.x);
+ float3 along_left = make_float3(frustum_right_normal.z, 0.0f, frustum_right_normal.x);
+ float3 along_top = make_float3(0.0f, -frustum_top_normal.z, frustum_top_normal.y);
+ float3 along_bottom = make_float3(0.0f, frustum_top_normal.z, frustum_top_normal.y);
+
+ float dist[] = {r, l, t, b};
+ float3 along[] = {along_right, along_left, along_top, along_bottom};
+
+ bool test_o = false;
+
+ float *d = dist;
+ float3 *a = along;
+ for (int i = 0; i < 4; i++, d++, a++) {
+ /* Test if we should check this side at all */
+ if (*d > 0.0f) {
+ if (dot(p, *a) >= 0.0f) {
+ /* We are in front of the back edge of this side of the frustum */
+ f_dist = max(f_dist, *d);
+ }
+ else {
+ /* Possibly far enough behind the frustum to use distance to origin instead of edge */
+ test_o = true;
+ }
+ }
+ }
+
+ if (test_o) {
+ f_dist = (f_dist > 0) ? min(f_dist, len(p)) : len(p);
+ }
+ }
+
+ if (f_dist > 0.0f) {
+ res += len(dDdx - dot(dDdx, D) * D) * f_dist * (offscreen_dicing_scale - 1.0f);
+ }
+ }
+ }
+ else if (type == CAMERA_PANORAMA) {
+ float3 D = transform_point(&worldtocamera, P);
+ float dist = len(D);
+
+ Ray ray = {{0}};
+
+ /* Distortion can become so great that the results become meaningless, there
+ * may be a better way to do this, but calculating differentials from the
+ * point directly ahead seems to produce good enough results. */
#if 0
- float2 dir = direction_to_panorama(&kernel_camera, kernel_camera_motion.data(), normalize(D));
- float3 raster = transform_perspective(&full_cameratoraster, make_float3(dir.x, dir.y, 0.0f));
-
- ray.t = 1.0f;
- camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), raster.x, raster.y, 0.0f, 0.0f, &ray);
- if(ray.t == 0.0f) {
- /* No differentials, just use from directly ahead. */
- camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*full_width, 0.5f*full_height, 0.0f, 0.0f, &ray);
- }
+ float2 dir = direction_to_panorama(&kernel_camera, kernel_camera_motion.data(), normalize(D));
+ float3 raster = transform_perspective(&full_cameratoraster, make_float3(dir.x, dir.y, 0.0f));
+
+ ray.t = 1.0f;
+ camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), raster.x, raster.y, 0.0f, 0.0f, &ray);
+ if(ray.t == 0.0f) {
+ /* No differentials, just use from directly ahead. */
+ camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*full_width, 0.5f*full_height, 0.0f, 0.0f, &ray);
+ }
#else
- camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*full_width, 0.5f*full_height, 0.0f, 0.0f, &ray);
+ camera_sample_panorama(&kernel_camera,
+ kernel_camera_motion.data(),
+ 0.5f * full_width,
+ 0.5f * full_height,
+ 0.0f,
+ 0.0f,
+ &ray);
#endif
- differential_transfer(&ray.dP, ray.dP, ray.D, ray.dD, ray.D, dist);
+ differential_transfer(&ray.dP, ray.dP, ray.D, ray.dD, ray.D, dist);
- return max(len(ray.dP.dx),len(ray.dP.dy));
- }
+ return max(len(ray.dP.dx), len(ray.dP.dy));
+ }
- return res;
+ return res;
}
bool Camera::use_motion() const
{
- return motion.size() > 1;
+ return motion.size() > 1;
}
float Camera::motion_time(int step) const
{
- return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
+ return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
}
int Camera::motion_step(float time) const
{
- if(use_motion()) {
- for(int step = 0; step < motion.size(); step++) {
- if(time == motion_time(step)) {
- return step;
- }
- }
- }
-
- return -1;
+ if (use_motion()) {
+ for (int step = 0; step < motion.size(); step++) {
+ if (time == motion_time(step)) {
+ return step;
+ }
+ }
+ }
+
+ return -1;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 961e8f918ea..0e91fa44a5b 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -40,179 +40,179 @@ class Scene;
*/
class Camera : public Node {
-public:
- NODE_DECLARE
-
- /* Specifies an offset for the shutter's time interval. */
- enum MotionPosition {
- /* Shutter opens at the current frame. */
- MOTION_POSITION_START = 0,
- /* Shutter is fully open at the current frame. */
- MOTION_POSITION_CENTER = 1,
- /* Shutter closes at the current frame. */
- MOTION_POSITION_END = 2,
-
- MOTION_NUM_POSITIONS,
- };
-
- /* Specifies rolling shutter effect. */
- enum RollingShutterType {
- /* No rolling shutter effect. */
- ROLLING_SHUTTER_NONE = 0,
- /* Sensor is being scanned vertically from top to bottom. */
- ROLLING_SHUTTER_TOP = 1,
-
- ROLLING_SHUTTER_NUM_TYPES,
- };
-
- /* Stereo Type */
- enum StereoEye {
- STEREO_NONE,
- STEREO_LEFT,
- STEREO_RIGHT,
- };
-
- /* motion blur */
- float shuttertime;
- MotionPosition motion_position;
- array<float> shutter_curve;
- size_t shutter_table_offset;
-
- /* ** Rolling shutter effect. ** */
- /* Defines rolling shutter effect type. */
- RollingShutterType rolling_shutter_type;
- /* Specifies exposure time of scanlines when using
- * rolling shutter effect.
- */
- float rolling_shutter_duration;
-
- /* depth of field */
- float focaldistance;
- float aperturesize;
- uint blades;
- float bladesrotation;
-
- /* type */
- CameraType type;
- float fov;
-
- /* panorama */
- PanoramaType panorama_type;
- float fisheye_fov;
- float fisheye_lens;
- float latitude_min;
- float latitude_max;
- float longitude_min;
- float longitude_max;
-
- /* panorama stereo */
- StereoEye stereo_eye;
- bool use_spherical_stereo;
- float interocular_distance;
- float convergence_distance;
- bool use_pole_merge;
- float pole_merge_angle_from;
- float pole_merge_angle_to;
-
- /* anamorphic lens bokeh */
- float aperture_ratio;
-
- /* sensor */
- float sensorwidth;
- float sensorheight;
-
- /* clipping */
- float nearclip;
- float farclip;
-
- /* screen */
- int width, height;
- int resolution;
- BoundBox2D viewplane;
- /* width and height change during preview, so we need these for calculating dice rates. */
- int full_width, full_height;
- /* controls how fast the dicing rate falls off for geometry out side of view */
- float offscreen_dicing_scale;
-
- /* border */
- BoundBox2D border;
- BoundBox2D viewport_camera_border;
-
- /* transformation */
- Transform matrix;
-
- /* motion */
- array<Transform> motion;
- bool use_perspective_motion;
- float fov_pre, fov_post;
-
- /* computed camera parameters */
- ProjectionTransform screentoworld;
- ProjectionTransform rastertoworld;
- ProjectionTransform ndctoworld;
- Transform cameratoworld;
-
- ProjectionTransform worldtoraster;
- ProjectionTransform worldtoscreen;
- ProjectionTransform worldtondc;
- Transform worldtocamera;
-
- ProjectionTransform rastertocamera;
- ProjectionTransform cameratoraster;
-
- ProjectionTransform full_rastertocamera;
-
- float3 dx;
- float3 dy;
-
- float3 full_dx;
- float3 full_dy;
-
- float3 frustum_right_normal;
- float3 frustum_top_normal;
-
- /* update */
- bool need_update;
- bool need_device_update;
- bool need_flags_update;
- int previous_need_motion;
-
- /* Kernel camera data, copied here for dicing. */
- KernelCamera kernel_camera;
- array<DecomposedTransform> kernel_camera_motion;
-
- /* functions */
- Camera();
- ~Camera();
-
- void compute_auto_viewplane();
-
- void update(Scene *scene);
-
- void device_update(Device *device, DeviceScene *dscene, Scene *scene);
- void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene);
- void device_free(Device *device, DeviceScene *dscene, Scene *scene);
-
- bool modified(const Camera& cam);
- bool motion_modified(const Camera& cam);
- void tag_update();
-
- /* Public utility functions. */
- BoundBox viewplane_bounds_get();
-
- /* Calculates the width of a pixel at point in world space. */
- float world_to_raster_size(float3 P);
-
- /* Motion blur. */
- float motion_time(int step) const;
- int motion_step(float time) const;
- bool use_motion() const;
-
-private:
- /* Private utility functions. */
- float3 transform_raster_to_world(float raster_x, float raster_y);
+ public:
+ NODE_DECLARE
+
+ /* Specifies an offset for the shutter's time interval. */
+ enum MotionPosition {
+ /* Shutter opens at the current frame. */
+ MOTION_POSITION_START = 0,
+ /* Shutter is fully open at the current frame. */
+ MOTION_POSITION_CENTER = 1,
+ /* Shutter closes at the current frame. */
+ MOTION_POSITION_END = 2,
+
+ MOTION_NUM_POSITIONS,
+ };
+
+ /* Specifies rolling shutter effect. */
+ enum RollingShutterType {
+ /* No rolling shutter effect. */
+ ROLLING_SHUTTER_NONE = 0,
+ /* Sensor is being scanned vertically from top to bottom. */
+ ROLLING_SHUTTER_TOP = 1,
+
+ ROLLING_SHUTTER_NUM_TYPES,
+ };
+
+ /* Stereo Type */
+ enum StereoEye {
+ STEREO_NONE,
+ STEREO_LEFT,
+ STEREO_RIGHT,
+ };
+
+ /* motion blur */
+ float shuttertime;
+ MotionPosition motion_position;
+ array<float> shutter_curve;
+ size_t shutter_table_offset;
+
+ /* ** Rolling shutter effect. ** */
+ /* Defines rolling shutter effect type. */
+ RollingShutterType rolling_shutter_type;
+ /* Specifies exposure time of scanlines when using
+ * rolling shutter effect.
+ */
+ float rolling_shutter_duration;
+
+ /* depth of field */
+ float focaldistance;
+ float aperturesize;
+ uint blades;
+ float bladesrotation;
+
+ /* type */
+ CameraType type;
+ float fov;
+
+ /* panorama */
+ PanoramaType panorama_type;
+ float fisheye_fov;
+ float fisheye_lens;
+ float latitude_min;
+ float latitude_max;
+ float longitude_min;
+ float longitude_max;
+
+ /* panorama stereo */
+ StereoEye stereo_eye;
+ bool use_spherical_stereo;
+ float interocular_distance;
+ float convergence_distance;
+ bool use_pole_merge;
+ float pole_merge_angle_from;
+ float pole_merge_angle_to;
+
+ /* anamorphic lens bokeh */
+ float aperture_ratio;
+
+ /* sensor */
+ float sensorwidth;
+ float sensorheight;
+
+ /* clipping */
+ float nearclip;
+ float farclip;
+
+ /* screen */
+ int width, height;
+ int resolution;
+ BoundBox2D viewplane;
+ /* width and height change during preview, so we need these for calculating dice rates. */
+ int full_width, full_height;
+ /* controls how fast the dicing rate falls off for geometry out side of view */
+ float offscreen_dicing_scale;
+
+ /* border */
+ BoundBox2D border;
+ BoundBox2D viewport_camera_border;
+
+ /* transformation */
+ Transform matrix;
+
+ /* motion */
+ array<Transform> motion;
+ bool use_perspective_motion;
+ float fov_pre, fov_post;
+
+ /* computed camera parameters */
+ ProjectionTransform screentoworld;
+ ProjectionTransform rastertoworld;
+ ProjectionTransform ndctoworld;
+ Transform cameratoworld;
+
+ ProjectionTransform worldtoraster;
+ ProjectionTransform worldtoscreen;
+ ProjectionTransform worldtondc;
+ Transform worldtocamera;
+
+ ProjectionTransform rastertocamera;
+ ProjectionTransform cameratoraster;
+
+ ProjectionTransform full_rastertocamera;
+
+ float3 dx;
+ float3 dy;
+
+ float3 full_dx;
+ float3 full_dy;
+
+ float3 frustum_right_normal;
+ float3 frustum_top_normal;
+
+ /* update */
+ bool need_update;
+ bool need_device_update;
+ bool need_flags_update;
+ int previous_need_motion;
+
+ /* Kernel camera data, copied here for dicing. */
+ KernelCamera kernel_camera;
+ array<DecomposedTransform> kernel_camera_motion;
+
+ /* functions */
+ Camera();
+ ~Camera();
+
+ void compute_auto_viewplane();
+
+ void update(Scene *scene);
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_free(Device *device, DeviceScene *dscene, Scene *scene);
+
+ bool modified(const Camera &cam);
+ bool motion_modified(const Camera &cam);
+ void tag_update();
+
+ /* Public utility functions. */
+ BoundBox viewplane_bounds_get();
+
+ /* Calculates the width of a pixel at point in world space. */
+ float world_to_raster_size(float3 P);
+
+ /* Motion blur. */
+ float motion_time(int step) const;
+ int motion_step(float time) const;
+ bool use_motion() const;
+
+ private:
+ /* Private utility functions. */
+ float3 transform_raster_to_world(float raster_x, float raster_y);
};
CCL_NAMESPACE_END
-#endif /* __CAMERA_H__ */
+#endif /* __CAMERA_H__ */
diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp
index 98c3e99996c..e475ff60eef 100644
--- a/intern/cycles/render/constant_fold.cpp
+++ b/intern/cycles/render/constant_fold.cpp
@@ -22,371 +22,374 @@
CCL_NAMESPACE_BEGIN
-ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output, Scene *scene)
-: graph(graph), node(node), output(output), scene(scene)
+ConstantFolder::ConstantFolder(ShaderGraph *graph,
+ ShaderNode *node,
+ ShaderOutput *output,
+ Scene *scene)
+ : graph(graph), node(node), output(output), scene(scene)
{
}
bool ConstantFolder::all_inputs_constant() const
{
- foreach(ShaderInput *input, node->inputs) {
- if(input->link) {
- return false;
- }
- }
+ foreach (ShaderInput *input, node->inputs) {
+ if (input->link) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
void ConstantFolder::make_constant(float value) const
{
- VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant (" << value << ").";
+ VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant (" << value
+ << ").";
- foreach(ShaderInput *sock, output->links) {
- sock->set(value);
- }
+ foreach (ShaderInput *sock, output->links) {
+ sock->set(value);
+ }
- graph->disconnect(output);
+ graph->disconnect(output);
}
void ConstantFolder::make_constant(float3 value) const
{
- VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant " << value << ".";
+ VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant " << value << ".";
- foreach(ShaderInput *sock, output->links) {
- sock->set(value);
- }
+ foreach (ShaderInput *sock, output->links) {
+ sock->set(value);
+ }
- graph->disconnect(output);
+ graph->disconnect(output);
}
void ConstantFolder::make_constant_clamp(float value, bool clamp) const
{
- make_constant(clamp ? saturate(value) : value);
+ make_constant(clamp ? saturate(value) : value);
}
void ConstantFolder::make_constant_clamp(float3 value, bool clamp) const
{
- if(clamp) {
- value.x = saturate(value.x);
- value.y = saturate(value.y);
- value.z = saturate(value.z);
- }
+ if (clamp) {
+ value.x = saturate(value.x);
+ value.y = saturate(value.y);
+ value.z = saturate(value.z);
+ }
- make_constant(value);
+ make_constant(value);
}
void ConstantFolder::make_zero() const
{
- if(output->type() == SocketType::FLOAT) {
- make_constant(0.0f);
- }
- else if(SocketType::is_float3(output->type())) {
- make_constant(make_float3(0.0f, 0.0f, 0.0f));
- }
- else {
- assert(0);
- }
+ if (output->type() == SocketType::FLOAT) {
+ make_constant(0.0f);
+ }
+ else if (SocketType::is_float3(output->type())) {
+ make_constant(make_float3(0.0f, 0.0f, 0.0f));
+ }
+ else {
+ assert(0);
+ }
}
void ConstantFolder::make_one() const
{
- if(output->type() == SocketType::FLOAT) {
- make_constant(1.0f);
- }
- else if(SocketType::is_float3(output->type())) {
- make_constant(make_float3(1.0f, 1.0f, 1.0f));
- }
- else {
- assert(0);
- }
+ if (output->type() == SocketType::FLOAT) {
+ make_constant(1.0f);
+ }
+ else if (SocketType::is_float3(output->type())) {
+ make_constant(make_float3(1.0f, 1.0f, 1.0f));
+ }
+ else {
+ assert(0);
+ }
}
void ConstantFolder::bypass(ShaderOutput *new_output) const
{
- assert(new_output);
+ assert(new_output);
- VLOG(1) << "Folding " << node->name << "::" << output->name() << " to socket " << new_output->parent->name << "::" << new_output->name() << ".";
+ VLOG(1) << "Folding " << node->name << "::" << output->name() << " to socket "
+ << new_output->parent->name << "::" << new_output->name() << ".";
- /* Remove all outgoing links from socket and connect them to new_output instead.
- * The graph->relink method affects node inputs, so it's not safe to use in constant
- * folding if the node has multiple outputs and will thus be folded multiple times. */
- vector<ShaderInput*> outputs = output->links;
+ /* Remove all outgoing links from socket and connect them to new_output instead.
+ * The graph->relink method affects node inputs, so it's not safe to use in constant
+ * folding if the node has multiple outputs and will thus be folded multiple times. */
+ vector<ShaderInput *> outputs = output->links;
- graph->disconnect(output);
+ graph->disconnect(output);
- foreach(ShaderInput *sock, outputs) {
- graph->connect(new_output, sock);
- }
+ foreach (ShaderInput *sock, outputs) {
+ graph->connect(new_output, sock);
+ }
}
void ConstantFolder::discard() const
{
- assert(output->type() == SocketType::CLOSURE);
+ assert(output->type() == SocketType::CLOSURE);
- VLOG(1) << "Discarding closure " << node->name << ".";
+ VLOG(1) << "Discarding closure " << node->name << ".";
- graph->disconnect(output);
+ graph->disconnect(output);
}
void ConstantFolder::bypass_or_discard(ShaderInput *input) const
{
- assert(input->type() == SocketType::CLOSURE);
-
- if(input->link) {
- bypass(input->link);
- }
- else {
- discard();
- }
+ assert(input->type() == SocketType::CLOSURE);
+
+ if (input->link) {
+ bypass(input->link);
+ }
+ else {
+ discard();
+ }
}
bool ConstantFolder::try_bypass_or_make_constant(ShaderInput *input, bool clamp) const
{
- if(input->type() != output->type()) {
- return false;
- }
- else if(!input->link) {
- if(input->type() == SocketType::FLOAT) {
- make_constant_clamp(node->get_float(input->socket_type), clamp);
- return true;
- }
- else if(SocketType::is_float3(input->type())) {
- make_constant_clamp(node->get_float3(input->socket_type), clamp);
- return true;
- }
- }
- else if(!clamp) {
- bypass(input->link);
- return true;
- }
- else {
- /* disconnect other inputs if we can't fully bypass due to clamp */
- foreach(ShaderInput *other, node->inputs) {
- if(other != input && other->link) {
- graph->disconnect(other);
- }
- }
- }
-
- return false;
+ if (input->type() != output->type()) {
+ return false;
+ }
+ else if (!input->link) {
+ if (input->type() == SocketType::FLOAT) {
+ make_constant_clamp(node->get_float(input->socket_type), clamp);
+ return true;
+ }
+ else if (SocketType::is_float3(input->type())) {
+ make_constant_clamp(node->get_float3(input->socket_type), clamp);
+ return true;
+ }
+ }
+ else if (!clamp) {
+ bypass(input->link);
+ return true;
+ }
+ else {
+ /* disconnect other inputs if we can't fully bypass due to clamp */
+ foreach (ShaderInput *other, node->inputs) {
+ if (other != input && other->link) {
+ graph->disconnect(other);
+ }
+ }
+ }
+
+ return false;
}
bool ConstantFolder::is_zero(ShaderInput *input) const
{
- if(!input->link) {
- if(input->type() == SocketType::FLOAT) {
- return node->get_float(input->socket_type) == 0.0f;
- }
- else if(SocketType::is_float3(input->type())) {
- return node->get_float3(input->socket_type) ==
- make_float3(0.0f, 0.0f, 0.0f);
- }
- }
-
- return false;
+ if (!input->link) {
+ if (input->type() == SocketType::FLOAT) {
+ return node->get_float(input->socket_type) == 0.0f;
+ }
+ else if (SocketType::is_float3(input->type())) {
+ return node->get_float3(input->socket_type) == make_float3(0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ return false;
}
bool ConstantFolder::is_one(ShaderInput *input) const
{
- if(!input->link) {
- if(input->type() == SocketType::FLOAT) {
- return node->get_float(input->socket_type) == 1.0f;
- }
- else if(SocketType::is_float3(input->type())) {
- return node->get_float3(input->socket_type) ==
- make_float3(1.0f, 1.0f, 1.0f);
- }
- }
-
- return false;
+ if (!input->link) {
+ if (input->type() == SocketType::FLOAT) {
+ return node->get_float(input->socket_type) == 1.0f;
+ }
+ else if (SocketType::is_float3(input->type())) {
+ return node->get_float3(input->socket_type) == make_float3(1.0f, 1.0f, 1.0f);
+ }
+ }
+
+ return false;
}
/* Specific nodes */
void ConstantFolder::fold_mix(NodeMix type, bool clamp) const
{
- ShaderInput *fac_in = node->input("Fac");
- ShaderInput *color1_in = node->input("Color1");
- ShaderInput *color2_in = node->input("Color2");
-
- float fac = saturate(node->get_float(fac_in->socket_type));
- bool fac_is_zero = !fac_in->link && fac == 0.0f;
- bool fac_is_one = !fac_in->link && fac == 1.0f;
-
- /* remove no-op node when factor is 0.0 */
- if(fac_is_zero) {
- /* note that some of the modes will clamp out of bounds values even without use_clamp */
- if(!(type == NODE_MIX_LIGHT || type == NODE_MIX_DODGE || type == NODE_MIX_BURN)) {
- if(try_bypass_or_make_constant(color1_in, clamp)) {
- return;
- }
- }
- }
-
- switch(type) {
- case NODE_MIX_BLEND:
- /* remove useless mix colors nodes */
- if(color1_in->link && color2_in->link) {
- if(color1_in->link == color2_in->link) {
- try_bypass_or_make_constant(color1_in, clamp);
- break;
- }
- }
- else if(!color1_in->link && !color2_in->link) {
- float3 color1 = node->get_float3(color1_in->socket_type);
- float3 color2 = node->get_float3(color2_in->socket_type);
- if(color1 == color2) {
- try_bypass_or_make_constant(color1_in, clamp);
- break;
- }
- }
- /* remove no-op mix color node when factor is 1.0 */
- if(fac_is_one) {
- try_bypass_or_make_constant(color2_in, clamp);
- break;
- }
- break;
- case NODE_MIX_ADD:
- /* 0 + X (fac 1) == X */
- if(is_zero(color1_in) && fac_is_one) {
- try_bypass_or_make_constant(color2_in, clamp);
- }
- /* X + 0 (fac ?) == X */
- else if(is_zero(color2_in)) {
- try_bypass_or_make_constant(color1_in, clamp);
- }
- break;
- case NODE_MIX_SUB:
- /* X - 0 (fac ?) == X */
- if(is_zero(color2_in)) {
- try_bypass_or_make_constant(color1_in, clamp);
- }
- /* X - X (fac 1) == 0 */
- else if(color1_in->link && color1_in->link == color2_in->link && fac_is_one) {
- make_zero();
- }
- break;
- case NODE_MIX_MUL:
- /* X * 1 (fac ?) == X, 1 * X (fac 1) == X */
- if(is_one(color1_in) && fac_is_one) {
- try_bypass_or_make_constant(color2_in, clamp);
- }
- else if(is_one(color2_in)) {
- try_bypass_or_make_constant(color1_in, clamp);
- }
- /* 0 * ? (fac ?) == 0, ? * 0 (fac 1) == 0 */
- else if(is_zero(color1_in)) {
- make_zero();
- }
- else if(is_zero(color2_in) && fac_is_one) {
- make_zero();
- }
- break;
- case NODE_MIX_DIV:
- /* X / 1 (fac ?) == X */
- if(is_one(color2_in)) {
- try_bypass_or_make_constant(color1_in, clamp);
- }
- /* 0 / ? (fac ?) == 0 */
- else if(is_zero(color1_in)) {
- make_zero();
- }
- break;
- default:
- break;
- }
+ ShaderInput *fac_in = node->input("Fac");
+ ShaderInput *color1_in = node->input("Color1");
+ ShaderInput *color2_in = node->input("Color2");
+
+ float fac = saturate(node->get_float(fac_in->socket_type));
+ bool fac_is_zero = !fac_in->link && fac == 0.0f;
+ bool fac_is_one = !fac_in->link && fac == 1.0f;
+
+ /* remove no-op node when factor is 0.0 */
+ if (fac_is_zero) {
+ /* note that some of the modes will clamp out of bounds values even without use_clamp */
+ if (!(type == NODE_MIX_LIGHT || type == NODE_MIX_DODGE || type == NODE_MIX_BURN)) {
+ if (try_bypass_or_make_constant(color1_in, clamp)) {
+ return;
+ }
+ }
+ }
+
+ switch (type) {
+ case NODE_MIX_BLEND:
+ /* remove useless mix colors nodes */
+ if (color1_in->link && color2_in->link) {
+ if (color1_in->link == color2_in->link) {
+ try_bypass_or_make_constant(color1_in, clamp);
+ break;
+ }
+ }
+ else if (!color1_in->link && !color2_in->link) {
+ float3 color1 = node->get_float3(color1_in->socket_type);
+ float3 color2 = node->get_float3(color2_in->socket_type);
+ if (color1 == color2) {
+ try_bypass_or_make_constant(color1_in, clamp);
+ break;
+ }
+ }
+ /* remove no-op mix color node when factor is 1.0 */
+ if (fac_is_one) {
+ try_bypass_or_make_constant(color2_in, clamp);
+ break;
+ }
+ break;
+ case NODE_MIX_ADD:
+ /* 0 + X (fac 1) == X */
+ if (is_zero(color1_in) && fac_is_one) {
+ try_bypass_or_make_constant(color2_in, clamp);
+ }
+ /* X + 0 (fac ?) == X */
+ else if (is_zero(color2_in)) {
+ try_bypass_or_make_constant(color1_in, clamp);
+ }
+ break;
+ case NODE_MIX_SUB:
+ /* X - 0 (fac ?) == X */
+ if (is_zero(color2_in)) {
+ try_bypass_or_make_constant(color1_in, clamp);
+ }
+ /* X - X (fac 1) == 0 */
+ else if (color1_in->link && color1_in->link == color2_in->link && fac_is_one) {
+ make_zero();
+ }
+ break;
+ case NODE_MIX_MUL:
+ /* X * 1 (fac ?) == X, 1 * X (fac 1) == X */
+ if (is_one(color1_in) && fac_is_one) {
+ try_bypass_or_make_constant(color2_in, clamp);
+ }
+ else if (is_one(color2_in)) {
+ try_bypass_or_make_constant(color1_in, clamp);
+ }
+ /* 0 * ? (fac ?) == 0, ? * 0 (fac 1) == 0 */
+ else if (is_zero(color1_in)) {
+ make_zero();
+ }
+ else if (is_zero(color2_in) && fac_is_one) {
+ make_zero();
+ }
+ break;
+ case NODE_MIX_DIV:
+ /* X / 1 (fac ?) == X */
+ if (is_one(color2_in)) {
+ try_bypass_or_make_constant(color1_in, clamp);
+ }
+ /* 0 / ? (fac ?) == 0 */
+ else if (is_zero(color1_in)) {
+ make_zero();
+ }
+ break;
+ default:
+ break;
+ }
}
void ConstantFolder::fold_math(NodeMath type, bool clamp) const
{
- ShaderInput *value1_in = node->input("Value1");
- ShaderInput *value2_in = node->input("Value2");
-
- switch(type) {
- case NODE_MATH_ADD:
- /* X + 0 == 0 + X == X */
- if(is_zero(value1_in)) {
- try_bypass_or_make_constant(value2_in, clamp);
- }
- else if(is_zero(value2_in)) {
- try_bypass_or_make_constant(value1_in, clamp);
- }
- break;
- case NODE_MATH_SUBTRACT:
- /* X - 0 == X */
- if(is_zero(value2_in)) {
- try_bypass_or_make_constant(value1_in, clamp);
- }
- break;
- case NODE_MATH_MULTIPLY:
- /* X * 1 == 1 * X == X */
- if(is_one(value1_in)) {
- try_bypass_or_make_constant(value2_in, clamp);
- }
- else if(is_one(value2_in)) {
- try_bypass_or_make_constant(value1_in, clamp);
- }
- /* X * 0 == 0 * X == 0 */
- else if(is_zero(value1_in) || is_zero(value2_in)) {
- make_zero();
- }
- break;
- case NODE_MATH_DIVIDE:
- /* X / 1 == X */
- if(is_one(value2_in)) {
- try_bypass_or_make_constant(value1_in, clamp);
- }
- /* 0 / X == 0 */
- else if(is_zero(value1_in)) {
- make_zero();
- }
- break;
- case NODE_MATH_POWER:
- /* 1 ^ X == X ^ 0 == 1 */
- if(is_one(value1_in) || is_zero(value2_in)) {
- make_one();
- }
- /* X ^ 1 == X */
- else if(is_one(value2_in)) {
- try_bypass_or_make_constant(value1_in, clamp);
- }
- default:
- break;
- }
+ ShaderInput *value1_in = node->input("Value1");
+ ShaderInput *value2_in = node->input("Value2");
+
+ switch (type) {
+ case NODE_MATH_ADD:
+ /* X + 0 == 0 + X == X */
+ if (is_zero(value1_in)) {
+ try_bypass_or_make_constant(value2_in, clamp);
+ }
+ else if (is_zero(value2_in)) {
+ try_bypass_or_make_constant(value1_in, clamp);
+ }
+ break;
+ case NODE_MATH_SUBTRACT:
+ /* X - 0 == X */
+ if (is_zero(value2_in)) {
+ try_bypass_or_make_constant(value1_in, clamp);
+ }
+ break;
+ case NODE_MATH_MULTIPLY:
+ /* X * 1 == 1 * X == X */
+ if (is_one(value1_in)) {
+ try_bypass_or_make_constant(value2_in, clamp);
+ }
+ else if (is_one(value2_in)) {
+ try_bypass_or_make_constant(value1_in, clamp);
+ }
+ /* X * 0 == 0 * X == 0 */
+ else if (is_zero(value1_in) || is_zero(value2_in)) {
+ make_zero();
+ }
+ break;
+ case NODE_MATH_DIVIDE:
+ /* X / 1 == X */
+ if (is_one(value2_in)) {
+ try_bypass_or_make_constant(value1_in, clamp);
+ }
+ /* 0 / X == 0 */
+ else if (is_zero(value1_in)) {
+ make_zero();
+ }
+ break;
+ case NODE_MATH_POWER:
+ /* 1 ^ X == X ^ 0 == 1 */
+ if (is_one(value1_in) || is_zero(value2_in)) {
+ make_one();
+ }
+ /* X ^ 1 == X */
+ else if (is_one(value2_in)) {
+ try_bypass_or_make_constant(value1_in, clamp);
+ }
+ default:
+ break;
+ }
}
void ConstantFolder::fold_vector_math(NodeVectorMath type) const
{
- ShaderInput *vector1_in = node->input("Vector1");
- ShaderInput *vector2_in = node->input("Vector2");
-
- switch(type) {
- case NODE_VECTOR_MATH_ADD:
- /* X + 0 == 0 + X == X */
- if(is_zero(vector1_in)) {
- try_bypass_or_make_constant(vector2_in);
- }
- else if(is_zero(vector2_in)) {
- try_bypass_or_make_constant(vector1_in);
- }
- break;
- case NODE_VECTOR_MATH_SUBTRACT:
- /* X - 0 == X */
- if(is_zero(vector2_in)) {
- try_bypass_or_make_constant(vector1_in);
- }
- break;
- case NODE_VECTOR_MATH_DOT_PRODUCT:
- case NODE_VECTOR_MATH_CROSS_PRODUCT:
- /* X * 0 == 0 * X == 0 */
- if(is_zero(vector1_in) || is_zero(vector2_in)) {
- make_zero();
- }
- break;
- default:
- break;
- }
+ ShaderInput *vector1_in = node->input("Vector1");
+ ShaderInput *vector2_in = node->input("Vector2");
+
+ switch (type) {
+ case NODE_VECTOR_MATH_ADD:
+ /* X + 0 == 0 + X == X */
+ if (is_zero(vector1_in)) {
+ try_bypass_or_make_constant(vector2_in);
+ }
+ else if (is_zero(vector2_in)) {
+ try_bypass_or_make_constant(vector1_in);
+ }
+ break;
+ case NODE_VECTOR_MATH_SUBTRACT:
+ /* X - 0 == X */
+ if (is_zero(vector2_in)) {
+ try_bypass_or_make_constant(vector1_in);
+ }
+ break;
+ case NODE_VECTOR_MATH_DOT_PRODUCT:
+ case NODE_VECTOR_MATH_CROSS_PRODUCT:
+ /* X * 0 == 0 * X == 0 */
+ if (is_zero(vector1_in) || is_zero(vector2_in)) {
+ make_zero();
+ }
+ break;
+ default:
+ break;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/constant_fold.h b/intern/cycles/render/constant_fold.h
index 6ec94b055e3..c14b94868dc 100644
--- a/intern/cycles/render/constant_fold.h
+++ b/intern/cycles/render/constant_fold.h
@@ -29,45 +29,45 @@ class ShaderNode;
class ShaderOutput;
class ConstantFolder {
-public:
- ShaderGraph *const graph;
- ShaderNode *const node;
- ShaderOutput *const output;
+ public:
+ ShaderGraph *const graph;
+ ShaderNode *const node;
+ ShaderOutput *const output;
- Scene *scene;
+ Scene *scene;
- ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output, Scene *scene);
+ ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output, Scene *scene);
- bool all_inputs_constant() const;
+ bool all_inputs_constant() const;
- /* Constant folding helpers */
- void make_constant(float value) const;
- void make_constant(float3 value) const;
- void make_constant_clamp(float value, bool clamp) const;
- void make_constant_clamp(float3 value, bool clamp) const;
- void make_zero() const;
- void make_one() const;
+ /* Constant folding helpers */
+ void make_constant(float value) const;
+ void make_constant(float3 value) const;
+ void make_constant_clamp(float value, bool clamp) const;
+ void make_constant_clamp(float3 value, bool clamp) const;
+ void make_zero() const;
+ void make_one() const;
- /* Bypass node, relinking to another output socket. */
- void bypass(ShaderOutput *output) const;
+ /* Bypass node, relinking to another output socket. */
+ void bypass(ShaderOutput *output) const;
- /* For closure nodes, discard node entirely or bypass to one of its inputs. */
- void discard() const;
- void bypass_or_discard(ShaderInput *input) const;
+ /* For closure nodes, discard node entirely or bypass to one of its inputs. */
+ void discard() const;
+ void bypass_or_discard(ShaderInput *input) const;
- /* Bypass or make constant, unless we can't due to clamp being true. */
- bool try_bypass_or_make_constant(ShaderInput *input, bool clamp = false) const;
+ /* Bypass or make constant, unless we can't due to clamp being true. */
+ bool try_bypass_or_make_constant(ShaderInput *input, bool clamp = false) const;
- /* Test if shader inputs of the current nodes have fixed values. */
- bool is_zero(ShaderInput *input) const;
- bool is_one(ShaderInput *input) const;
+ /* Test if shader inputs of the current nodes have fixed values. */
+ bool is_zero(ShaderInput *input) const;
+ bool is_one(ShaderInput *input) const;
- /* Specific nodes. */
- void fold_mix(NodeMix type, bool clamp) const;
- void fold_math(NodeMath type, bool clamp) const;
- void fold_vector_math(NodeVectorMath type) const;
+ /* Specific nodes. */
+ void fold_mix(NodeMix type, bool clamp) const;
+ void fold_math(NodeMath type, bool clamp) const;
+ void fold_vector_math(NodeVectorMath type) const;
};
CCL_NAMESPACE_END
-#endif /* __CONSTANT_FOLD_H__ */
+#endif /* __CONSTANT_FOLD_H__ */
diff --git a/intern/cycles/render/coverage.cpp b/intern/cycles/render/coverage.cpp
index 72ef4cda3ff..0a29903728a 100644
--- a/intern/cycles/render/coverage.cpp
+++ b/intern/cycles/render/coverage.cpp
@@ -25,119 +25,128 @@
CCL_NAMESPACE_BEGIN
-static bool crypomatte_comp(const pair<float, float>& i, const pair<float, float> j) { return i.first > j.first; }
+static bool crypomatte_comp(const pair<float, float> &i, const pair<float, float> j)
+{
+ return i.first > j.first;
+}
void Coverage::finalize()
{
- int pass_offset = 0;
- if(kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
- finalize_buffer(coverage_object, pass_offset);
- pass_offset += kernel_data.film.cryptomatte_depth * 4;
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
- finalize_buffer(coverage_material, pass_offset);
- pass_offset += kernel_data.film.cryptomatte_depth * 4;
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
- finalize_buffer(coverage_asset, pass_offset);
- }
+ int pass_offset = 0;
+ if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
+ finalize_buffer(coverage_object, pass_offset);
+ pass_offset += kernel_data.film.cryptomatte_depth * 4;
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
+ finalize_buffer(coverage_material, pass_offset);
+ pass_offset += kernel_data.film.cryptomatte_depth * 4;
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
+ finalize_buffer(coverage_asset, pass_offset);
+ }
}
void Coverage::init_path_trace()
{
- kg->coverage_object = kg->coverage_material = kg->coverage_asset = NULL;
+ kg->coverage_object = kg->coverage_material = kg->coverage_asset = NULL;
- if(kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
- if(kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
- coverage_object.clear();
- coverage_object.resize(tile.w * tile.h);
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
- coverage_material.clear();
- coverage_material.resize(tile.w * tile.h);
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
- coverage_asset.clear();
- coverage_asset.resize(tile.w * tile.h);
- }
- }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
+ if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
+ coverage_object.clear();
+ coverage_object.resize(tile.w * tile.h);
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
+ coverage_material.clear();
+ coverage_material.resize(tile.w * tile.h);
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
+ coverage_asset.clear();
+ coverage_asset.resize(tile.w * tile.h);
+ }
+ }
}
void Coverage::init_pixel(int x, int y)
{
- if(kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
- const int pixel_index = tile.w * (y - tile.y) + x - tile.x;
- if(kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
- kg->coverage_object = &coverage_object[pixel_index];
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
- kg->coverage_material = &coverage_material[pixel_index];
- }
- if(kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
- kg->coverage_asset = &coverage_asset[pixel_index];
- }
- }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
+ const int pixel_index = tile.w * (y - tile.y) + x - tile.x;
+ if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
+ kg->coverage_object = &coverage_object[pixel_index];
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
+ kg->coverage_material = &coverage_material[pixel_index];
+ }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
+ kg->coverage_asset = &coverage_asset[pixel_index];
+ }
+ }
}
-void Coverage::finalize_buffer(vector<CoverageMap> & coverage, const int pass_offset)
+void Coverage::finalize_buffer(vector<CoverageMap> &coverage, const int pass_offset)
{
- if(kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
- flatten_buffer(coverage, pass_offset);
- }
- else {
- sort_buffer(pass_offset);
- }
+ if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
+ flatten_buffer(coverage, pass_offset);
+ }
+ else {
+ sort_buffer(pass_offset);
+ }
}
void Coverage::flatten_buffer(vector<CoverageMap> &coverage, const int pass_offset)
{
- /* Sort the coverage map and write it to the output */
- int pixel_index = 0;
- int pass_stride = tile.buffers->params.get_passes_size();
- for(int y = 0; y < tile.h; ++y) {
- for(int x = 0; x < tile.w; ++x) {
- const CoverageMap& pixel = coverage[pixel_index];
- if(!pixel.empty()) {
- /* buffer offset */
- int index = x + y * tile.stride;
- float *buffer = (float*)tile.buffer + index*pass_stride;
+ /* Sort the coverage map and write it to the output */
+ int pixel_index = 0;
+ int pass_stride = tile.buffers->params.get_passes_size();
+ for (int y = 0; y < tile.h; ++y) {
+ for (int x = 0; x < tile.w; ++x) {
+ const CoverageMap &pixel = coverage[pixel_index];
+ if (!pixel.empty()) {
+ /* buffer offset */
+ int index = x + y * tile.stride;
+ float *buffer = (float *)tile.buffer + index * pass_stride;
- /* sort the cryptomatte pixel */
- vector<pair<float, float> > sorted_pixel;
- for(CoverageMap::const_iterator it = pixel.begin(); it != pixel.end(); ++it) {
- sorted_pixel.push_back(std::make_pair(it->second, it->first));
- }
- sort(sorted_pixel.begin(), sorted_pixel.end(), crypomatte_comp);
- int num_slots = 2 * (kernel_data.film.cryptomatte_depth);
- if(sorted_pixel.size() > num_slots) {
- float leftover = 0.0f;
- for(vector<pair<float, float> >::iterator it = sorted_pixel.begin()+num_slots; it != sorted_pixel.end(); ++it) {
- leftover += it->first;
- }
- sorted_pixel[num_slots-1].first += leftover;
- }
- int limit = min(num_slots, sorted_pixel.size());
- for(int i = 0; i < limit; ++i) {
- kernel_write_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset, 2 * (kernel_data.film.cryptomatte_depth), sorted_pixel[i].second, sorted_pixel[i].first);
- }
- }
- ++pixel_index;
- }
- }
+ /* sort the cryptomatte pixel */
+ vector<pair<float, float>> sorted_pixel;
+ for (CoverageMap::const_iterator it = pixel.begin(); it != pixel.end(); ++it) {
+ sorted_pixel.push_back(std::make_pair(it->second, it->first));
+ }
+ sort(sorted_pixel.begin(), sorted_pixel.end(), crypomatte_comp);
+ int num_slots = 2 * (kernel_data.film.cryptomatte_depth);
+ if (sorted_pixel.size() > num_slots) {
+ float leftover = 0.0f;
+ for (vector<pair<float, float>>::iterator it = sorted_pixel.begin() + num_slots;
+ it != sorted_pixel.end();
+ ++it) {
+ leftover += it->first;
+ }
+ sorted_pixel[num_slots - 1].first += leftover;
+ }
+ int limit = min(num_slots, sorted_pixel.size());
+ for (int i = 0; i < limit; ++i) {
+ kernel_write_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset,
+ 2 * (kernel_data.film.cryptomatte_depth),
+ sorted_pixel[i].second,
+ sorted_pixel[i].first);
+ }
+ }
+ ++pixel_index;
+ }
+ }
}
void Coverage::sort_buffer(const int pass_offset)
{
- /* Sort the coverage map and write it to the output */
- int pass_stride = tile.buffers->params.get_passes_size();
- for(int y = 0; y < tile.h; ++y) {
- for(int x = 0; x < tile.w; ++x) {
- /* buffer offset */
- int index = x + y*tile.stride;
- float *buffer = (float*)tile.buffer + index*pass_stride;
- kernel_sort_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset, 2 * (kernel_data.film.cryptomatte_depth));
- }
- }
+ /* Sort the coverage map and write it to the output */
+ int pass_stride = tile.buffers->params.get_passes_size();
+ for (int y = 0; y < tile.h; ++y) {
+ for (int x = 0; x < tile.w; ++x) {
+ /* buffer offset */
+ int index = x + y * tile.stride;
+ float *buffer = (float *)tile.buffer + index * pass_stride;
+ kernel_sort_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset,
+ 2 * (kernel_data.film.cryptomatte_depth));
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/coverage.h b/intern/cycles/render/coverage.h
index 9ee0bce7517..3d1f6a2b040 100644
--- a/intern/cycles/render/coverage.h
+++ b/intern/cycles/render/coverage.h
@@ -22,28 +22,30 @@
#include "util/util_vector.h"
#ifndef __COVERAGE_H__
-#define __COVERAGE_H__
+# define __COVERAGE_H__
CCL_NAMESPACE_BEGIN
class Coverage {
-public:
- Coverage(KernelGlobals *kg_, RenderTile &tile_) : kg(kg_), tile(tile_) { }
- void init_path_trace();
- void init_pixel(int x, int y);
- void finalize();
-private:
- vector<CoverageMap>coverage_object;
- vector<CoverageMap>coverage_material;
- vector<CoverageMap>coverage_asset;
- KernelGlobals *kg;
- RenderTile &tile;
- void finalize_buffer(vector<CoverageMap>&coverage, const int pass_offset);
- void flatten_buffer(vector<CoverageMap>&coverage, const int pass_offset);
- void sort_buffer(const int pass_offset);
-};
+ public:
+ Coverage(KernelGlobals *kg_, RenderTile &tile_) : kg(kg_), tile(tile_)
+ {
+ }
+ void init_path_trace();
+ void init_pixel(int x, int y);
+ void finalize();
+ private:
+ vector<CoverageMap> coverage_object;
+ vector<CoverageMap> coverage_material;
+ vector<CoverageMap> coverage_asset;
+ KernelGlobals *kg;
+ RenderTile &tile;
+ void finalize_buffer(vector<CoverageMap> &coverage, const int pass_offset);
+ void flatten_buffer(vector<CoverageMap> &coverage, const int pass_offset);
+ void sort_buffer(const int pass_offset);
+};
CCL_NAMESPACE_END
-#endif /* __COVERAGE_H__ */
+#endif /* __COVERAGE_H__ */
diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp
index 58b71d3e122..49ab70541c2 100644
--- a/intern/cycles/render/curves.cpp
+++ b/intern/cycles/render/curves.cpp
@@ -31,72 +31,73 @@ CCL_NAMESPACE_BEGIN
void curvebounds(float *lower, float *upper, float3 *p, int dim)
{
- float *p0 = &p[0].x;
- float *p1 = &p[1].x;
- float *p2 = &p[2].x;
- float *p3 = &p[3].x;
-
- float fc = 0.71f;
- float curve_coef[4];
- curve_coef[0] = p1[dim];
- curve_coef[1] = -fc*p0[dim] + fc*p2[dim];
- curve_coef[2] = 2.0f * fc * p0[dim] + (fc - 3.0f) * p1[dim] + (3.0f - 2.0f * fc) * p2[dim] - fc * p3[dim];
- curve_coef[3] = -fc * p0[dim] + (2.0f - fc) * p1[dim] + (fc - 2.0f) * p2[dim] + fc * p3[dim];
-
- float discroot = curve_coef[2] * curve_coef[2] - 3 * curve_coef[3] * curve_coef[1];
- float ta = -1.0f;
- float tb = -1.0f;
-
- if(discroot >= 0) {
- discroot = sqrtf(discroot);
- ta = (-curve_coef[2] - discroot) / (3 * curve_coef[3]);
- tb = (-curve_coef[2] + discroot) / (3 * curve_coef[3]);
- ta = (ta > 1.0f || ta < 0.0f) ? -1.0f : ta;
- tb = (tb > 1.0f || tb < 0.0f) ? -1.0f : tb;
- }
-
- *upper = max(p1[dim],p2[dim]);
- *lower = min(p1[dim],p2[dim]);
-
- float exa = p1[dim];
- float exb = p2[dim];
-
- if(ta >= 0.0f) {
- float t2 = ta * ta;
- float t3 = t2 * ta;
- exa = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * ta + curve_coef[0];
- }
- if(tb >= 0.0f) {
- float t2 = tb * tb;
- float t3 = t2 * tb;
- exb = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * tb + curve_coef[0];
- }
-
- *upper = max(*upper, max(exa,exb));
- *lower = min(*lower, min(exa,exb));
+ float *p0 = &p[0].x;
+ float *p1 = &p[1].x;
+ float *p2 = &p[2].x;
+ float *p3 = &p[3].x;
+
+ float fc = 0.71f;
+ float curve_coef[4];
+ curve_coef[0] = p1[dim];
+ curve_coef[1] = -fc * p0[dim] + fc * p2[dim];
+ curve_coef[2] = 2.0f * fc * p0[dim] + (fc - 3.0f) * p1[dim] + (3.0f - 2.0f * fc) * p2[dim] -
+ fc * p3[dim];
+ curve_coef[3] = -fc * p0[dim] + (2.0f - fc) * p1[dim] + (fc - 2.0f) * p2[dim] + fc * p3[dim];
+
+ float discroot = curve_coef[2] * curve_coef[2] - 3 * curve_coef[3] * curve_coef[1];
+ float ta = -1.0f;
+ float tb = -1.0f;
+
+ if (discroot >= 0) {
+ discroot = sqrtf(discroot);
+ ta = (-curve_coef[2] - discroot) / (3 * curve_coef[3]);
+ tb = (-curve_coef[2] + discroot) / (3 * curve_coef[3]);
+ ta = (ta > 1.0f || ta < 0.0f) ? -1.0f : ta;
+ tb = (tb > 1.0f || tb < 0.0f) ? -1.0f : tb;
+ }
+
+ *upper = max(p1[dim], p2[dim]);
+ *lower = min(p1[dim], p2[dim]);
+
+ float exa = p1[dim];
+ float exb = p2[dim];
+
+ if (ta >= 0.0f) {
+ float t2 = ta * ta;
+ float t3 = t2 * ta;
+ exa = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * ta + curve_coef[0];
+ }
+ if (tb >= 0.0f) {
+ float t2 = tb * tb;
+ float t3 = t2 * tb;
+ exb = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * tb + curve_coef[0];
+ }
+
+ *upper = max(*upper, max(exa, exb));
+ *lower = min(*lower, min(exa, exb));
}
/* Hair System Manager */
CurveSystemManager::CurveSystemManager()
{
- primitive = CURVE_LINE_SEGMENTS;
- curve_shape = CURVE_THICK;
- line_method = CURVE_CORRECTED;
- triangle_method = CURVE_CAMERA_TRIANGLES;
- resolution = 3;
- subdivisions = 3;
-
- minimum_width = 0.0f;
- maximum_width = 0.0f;
-
- use_curves = true;
- use_encasing = true;
- use_backfacing = false;
- use_tangent_normal_geometry = false;
-
- need_update = true;
- need_mesh_update = false;
+ primitive = CURVE_LINE_SEGMENTS;
+ curve_shape = CURVE_THICK;
+ line_method = CURVE_CORRECTED;
+ triangle_method = CURVE_CAMERA_TRIANGLES;
+ resolution = 3;
+ subdivisions = 3;
+
+ minimum_width = 0.0f;
+ maximum_width = 0.0f;
+
+ use_curves = true;
+ use_encasing = true;
+ use_backfacing = false;
+ use_tangent_normal_geometry = false;
+
+ need_update = true;
+ need_mesh_update = false;
}
CurveSystemManager::~CurveSystemManager()
@@ -106,85 +107,82 @@ CurveSystemManager::~CurveSystemManager()
void CurveSystemManager::device_update(Device *device,
DeviceScene *dscene,
Scene * /*scene*/,
- Progress& progress)
+ Progress &progress)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- device_free(device, dscene);
+ device_free(device, dscene);
- progress.set_status("Updating Hair settings", "Copying Hair settings to device");
+ progress.set_status("Updating Hair settings", "Copying Hair settings to device");
- KernelCurves *kcurve = &dscene->data.curve;
+ KernelCurves *kcurve = &dscene->data.curve;
- kcurve->curveflags = 0;
+ kcurve->curveflags = 0;
- if(use_curves) {
- if(primitive == CURVE_SEGMENTS || primitive == CURVE_RIBBONS)
- kcurve->curveflags |= CURVE_KN_INTERPOLATE;
- if(primitive == CURVE_RIBBONS)
- kcurve->curveflags |= CURVE_KN_RIBBONS;
+ if (use_curves) {
+ if (primitive == CURVE_SEGMENTS || primitive == CURVE_RIBBONS)
+ kcurve->curveflags |= CURVE_KN_INTERPOLATE;
+ if (primitive == CURVE_RIBBONS)
+ kcurve->curveflags |= CURVE_KN_RIBBONS;
- if(line_method == CURVE_ACCURATE)
- kcurve->curveflags |= CURVE_KN_ACCURATE;
- else if(line_method == CURVE_CORRECTED)
- kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION;
+ if (line_method == CURVE_ACCURATE)
+ kcurve->curveflags |= CURVE_KN_ACCURATE;
+ else if (line_method == CURVE_CORRECTED)
+ kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION;
- if(use_tangent_normal_geometry)
- kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL;
- if(use_backfacing)
- kcurve->curveflags |= CURVE_KN_BACKFACING;
- if(use_encasing)
- kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER;
+ if (use_tangent_normal_geometry)
+ kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL;
+ if (use_backfacing)
+ kcurve->curveflags |= CURVE_KN_BACKFACING;
+ if (use_encasing)
+ kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER;
- kcurve->minimum_width = minimum_width;
- kcurve->maximum_width = maximum_width;
- kcurve->subdivisions = subdivisions;
- }
+ kcurve->minimum_width = minimum_width;
+ kcurve->maximum_width = maximum_width;
+ kcurve->subdivisions = subdivisions;
+ }
- if(progress.get_cancel()) return;
+ if (progress.get_cancel())
+ return;
- need_update = false;
+ need_update = false;
}
-void CurveSystemManager::device_free(Device * /*device*/,
- DeviceScene * /*dscene*/)
+void CurveSystemManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
-
}
-bool CurveSystemManager::modified(const CurveSystemManager& CurveSystemManager)
+bool CurveSystemManager::modified(const CurveSystemManager &CurveSystemManager)
{
- return !(curve_shape == CurveSystemManager.curve_shape &&
- line_method == CurveSystemManager.line_method &&
- primitive == CurveSystemManager.primitive &&
- use_encasing == CurveSystemManager.use_encasing &&
- use_tangent_normal_geometry == CurveSystemManager.use_tangent_normal_geometry &&
- minimum_width == CurveSystemManager.minimum_width &&
- maximum_width == CurveSystemManager.maximum_width &&
- use_backfacing == CurveSystemManager.use_backfacing &&
- triangle_method == CurveSystemManager.triangle_method &&
- resolution == CurveSystemManager.resolution &&
- use_curves == CurveSystemManager.use_curves &&
- subdivisions == CurveSystemManager.subdivisions);
+ return !(
+ curve_shape == CurveSystemManager.curve_shape &&
+ line_method == CurveSystemManager.line_method && primitive == CurveSystemManager.primitive &&
+ use_encasing == CurveSystemManager.use_encasing &&
+ use_tangent_normal_geometry == CurveSystemManager.use_tangent_normal_geometry &&
+ minimum_width == CurveSystemManager.minimum_width &&
+ maximum_width == CurveSystemManager.maximum_width &&
+ use_backfacing == CurveSystemManager.use_backfacing &&
+ triangle_method == CurveSystemManager.triangle_method &&
+ resolution == CurveSystemManager.resolution && use_curves == CurveSystemManager.use_curves &&
+ subdivisions == CurveSystemManager.subdivisions);
}
-bool CurveSystemManager::modified_mesh(const CurveSystemManager& CurveSystemManager)
+bool CurveSystemManager::modified_mesh(const CurveSystemManager &CurveSystemManager)
{
- return !(primitive == CurveSystemManager.primitive &&
- curve_shape == CurveSystemManager.curve_shape &&
- triangle_method == CurveSystemManager.triangle_method &&
- resolution == CurveSystemManager.resolution &&
- use_curves == CurveSystemManager.use_curves);
+ return !(
+ primitive == CurveSystemManager.primitive && curve_shape == CurveSystemManager.curve_shape &&
+ triangle_method == CurveSystemManager.triangle_method &&
+ resolution == CurveSystemManager.resolution && use_curves == CurveSystemManager.use_curves);
}
void CurveSystemManager::tag_update(Scene * /*scene*/)
{
- need_update = true;
+ need_update = true;
}
void CurveSystemManager::tag_update_mesh()
{
- need_mesh_update = true;
+ need_mesh_update = true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h
index 9db411bc04b..81e7b4ac88d 100644
--- a/intern/cycles/render/curves.h
+++ b/intern/cycles/render/curves.h
@@ -30,93 +30,91 @@ class Scene;
void curvebounds(float *lower, float *upper, float3 *p, int dim);
typedef enum CurvePrimitiveType {
- CURVE_TRIANGLES = 0,
- CURVE_LINE_SEGMENTS = 1,
- CURVE_SEGMENTS = 2,
- CURVE_RIBBONS = 3,
+ CURVE_TRIANGLES = 0,
+ CURVE_LINE_SEGMENTS = 1,
+ CURVE_SEGMENTS = 2,
+ CURVE_RIBBONS = 3,
- CURVE_NUM_PRIMITIVE_TYPES,
+ CURVE_NUM_PRIMITIVE_TYPES,
} CurvePrimitiveType;
typedef enum CurveShapeType {
- CURVE_RIBBON = 0,
- CURVE_THICK = 1,
+ CURVE_RIBBON = 0,
+ CURVE_THICK = 1,
- CURVE_NUM_SHAPE_TYPES,
+ CURVE_NUM_SHAPE_TYPES,
} CurveShapeType;
typedef enum CurveTriangleMethod {
- CURVE_CAMERA_TRIANGLES,
- CURVE_TESSELATED_TRIANGLES
+ CURVE_CAMERA_TRIANGLES,
+ CURVE_TESSELATED_TRIANGLES
} CurveTriangleMethod;
typedef enum CurveLineMethod {
- CURVE_ACCURATE,
- CURVE_CORRECTED,
- CURVE_UNCORRECTED
+ CURVE_ACCURATE,
+ CURVE_CORRECTED,
+ CURVE_UNCORRECTED
} CurveLineMethod;
class ParticleCurveData {
-public:
+ public:
+ ParticleCurveData();
+ ~ParticleCurveData();
- ParticleCurveData();
- ~ParticleCurveData();
+ array<int> psys_firstcurve;
+ array<int> psys_curvenum;
+ array<int> psys_shader;
- array<int> psys_firstcurve;
- array<int> psys_curvenum;
- array<int> psys_shader;
+ array<float> psys_rootradius;
+ array<float> psys_tipradius;
+ array<float> psys_shape;
+ array<bool> psys_closetip;
- array<float> psys_rootradius;
- array<float> psys_tipradius;
- array<float> psys_shape;
- array<bool> psys_closetip;
+ array<int> curve_firstkey;
+ array<int> curve_keynum;
+ array<float> curve_length;
+ array<float2> curve_uv;
+ array<float3> curve_vcol;
- array<int> curve_firstkey;
- array<int> curve_keynum;
- array<float> curve_length;
- array<float2> curve_uv;
- array<float3> curve_vcol;
-
- array<float3> curvekey_co;
- array<float> curvekey_time;
+ array<float3> curvekey_co;
+ array<float> curvekey_time;
};
/* HairSystem Manager */
class CurveSystemManager {
-public:
-
- CurvePrimitiveType primitive;
- CurveShapeType curve_shape;
- CurveLineMethod line_method;
- CurveTriangleMethod triangle_method;
- int resolution;
- int subdivisions;
-
- float minimum_width;
- float maximum_width;
-
- bool use_curves;
- bool use_encasing;
- bool use_backfacing;
- bool use_tangent_normal_geometry;
-
- bool need_update;
- bool need_mesh_update;
-
- CurveSystemManager();
- ~CurveSystemManager();
-
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_free(Device *device, DeviceScene *dscene);
- bool modified(const CurveSystemManager& CurveSystemManager);
- bool modified_mesh(const CurveSystemManager& CurveSystemManager);
-
- void tag_update(Scene *scene);
- void tag_update_mesh();
+ public:
+ CurvePrimitiveType primitive;
+ CurveShapeType curve_shape;
+ CurveLineMethod line_method;
+ CurveTriangleMethod triangle_method;
+ int resolution;
+ int subdivisions;
+
+ float minimum_width;
+ float maximum_width;
+
+ bool use_curves;
+ bool use_encasing;
+ bool use_backfacing;
+ bool use_tangent_normal_geometry;
+
+ bool need_update;
+ bool need_mesh_update;
+
+ CurveSystemManager();
+ ~CurveSystemManager();
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_free(Device *device, DeviceScene *dscene);
+ bool modified(const CurveSystemManager &CurveSystemManager);
+ bool modified_mesh(const CurveSystemManager &CurveSystemManager);
+
+ void tag_update(Scene *scene);
+ void tag_update_mesh();
};
CCL_NAMESPACE_END
-#endif /* __CURVES_H__ */
+#endif /* __CURVES_H__ */
diff --git a/intern/cycles/render/denoising.cpp b/intern/cycles/render/denoising.cpp
index ab74fd8fd38..c4f21d9c771 100644
--- a/intern/cycles/render/denoising.cpp
+++ b/intern/cycles/render/denoising.cpp
@@ -31,55 +31,55 @@ CCL_NAMESPACE_BEGIN
static void print_progress(int num, int total, int frame, int num_frames)
{
- const char *label = "Denoise Frame ";
- int cols = system_console_width();
-
- cols -= strlen(label);
-
- int len = 1;
- for(int x = total; x > 9; x /= 10) {
- len++;
- }
-
- int bars = cols - 2*len - 6;
-
- printf("\r%s", label);
-
- if(num_frames > 1) {
- int frame_len = 1;
- for(int x = num_frames - 1; x > 9; x /= 10) {
- frame_len++;
- }
- bars -= frame_len + 2;
- printf("%*d ", frame_len, frame);
- }
-
- int v = int(float(num)*bars/total);
- printf("[");
- for(int i = 0; i < v; i++) {
- printf("=");
- }
- if(v < bars) {
- printf(">");
- }
- for(int i = v+1; i < bars; i++) {
- printf(" ");
- }
- printf(string_printf("] %%%dd / %d", len, total).c_str(), num);
- fflush(stdout);
+ const char *label = "Denoise Frame ";
+ int cols = system_console_width();
+
+ cols -= strlen(label);
+
+ int len = 1;
+ for (int x = total; x > 9; x /= 10) {
+ len++;
+ }
+
+ int bars = cols - 2 * len - 6;
+
+ printf("\r%s", label);
+
+ if (num_frames > 1) {
+ int frame_len = 1;
+ for (int x = num_frames - 1; x > 9; x /= 10) {
+ frame_len++;
+ }
+ bars -= frame_len + 2;
+ printf("%*d ", frame_len, frame);
+ }
+
+ int v = int(float(num) * bars / total);
+ printf("[");
+ for (int i = 0; i < v; i++) {
+ printf("=");
+ }
+ if (v < bars) {
+ printf(">");
+ }
+ for (int i = v + 1; i < bars; i++) {
+ printf(" ");
+ }
+ printf(string_printf("] %%%dd / %d", len, total).c_str(), num);
+ fflush(stdout);
}
/* Splits in at its last dot, setting suffix to the part after the dot and in to the part before it.
* Returns whether a dot was found. */
static bool split_last_dot(string &in, string &suffix)
{
- size_t pos = in.rfind(".");
- if(pos == string::npos) {
- return false;
- }
- suffix = in.substr(pos+1);
- in = in.substr(0, pos);
- return true;
+ size_t pos = in.rfind(".");
+ if (pos == string::npos) {
+ return false;
+ }
+ suffix = in.substr(pos + 1);
+ in = in.substr(0, pos);
+ return true;
}
/* Separate channel names as generated by Blender.
@@ -87,39 +87,40 @@ static bool split_last_dot(string &in, string &suffix)
* Inputs are expected in the form RenderLayer.Pass.View.Channel, sets renderlayer to "RenderLayer.View"
* Otherwise:
* Inputs are expected in the form RenderLayer.Pass.Channel */
-static bool parse_channel_name(string name, string &renderlayer, string &pass, string &channel, bool multiview_channels)
+static bool parse_channel_name(
+ string name, string &renderlayer, string &pass, string &channel, bool multiview_channels)
{
- if(!split_last_dot(name, channel)) {
- return false;
- }
- string view;
- if(multiview_channels && !split_last_dot(name, view)) {
- return false;
- }
- if(!split_last_dot(name, pass)) {
- return false;
- }
- renderlayer = name;
+ if (!split_last_dot(name, channel)) {
+ return false;
+ }
+ string view;
+ if (multiview_channels && !split_last_dot(name, view)) {
+ return false;
+ }
+ if (!split_last_dot(name, pass)) {
+ return false;
+ }
+ renderlayer = name;
- if(multiview_channels) {
- renderlayer += "." + view;
- }
+ if (multiview_channels) {
+ renderlayer += "." + view;
+ }
- return true;
+ return true;
}
/* Channel Mapping */
struct ChannelMapping {
- int channel;
- string name;
+ int channel;
+ string name;
};
static void fill_mapping(vector<ChannelMapping> &map, int pos, string name, string channels)
{
- for(const char *chan = channels.c_str(); *chan; chan++) {
- map.push_back({pos++, name + "." + *chan});
- }
+ for (const char *chan = channels.c_str(); *chan; chan++) {
+ map.push_back({pos++, name + "." + *chan});
+ }
}
static const int INPUT_NUM_CHANNELS = 15;
@@ -132,131 +133,135 @@ static const int INPUT_DENOISING_VARIANCE = 11;
static const int INPUT_DENOISING_INTENSITY = 14;
static vector<ChannelMapping> input_channels()
{
- vector<ChannelMapping> map;
- fill_mapping(map, INPUT_DENOISING_DEPTH, "Denoising Depth", "Z");
- fill_mapping(map, INPUT_DENOISING_NORMAL, "Denoising Normal", "XYZ");
- fill_mapping(map, INPUT_DENOISING_SHADOWING, "Denoising Shadowing", "X");
- fill_mapping(map, INPUT_DENOISING_ALBEDO, "Denoising Albedo", "RGB");
- fill_mapping(map, INPUT_NOISY_IMAGE, "Noisy Image", "RGB");
- fill_mapping(map, INPUT_DENOISING_VARIANCE, "Denoising Variance", "RGB");
- fill_mapping(map, INPUT_DENOISING_INTENSITY, "Denoising Intensity", "X");
- return map;
+ vector<ChannelMapping> map;
+ fill_mapping(map, INPUT_DENOISING_DEPTH, "Denoising Depth", "Z");
+ fill_mapping(map, INPUT_DENOISING_NORMAL, "Denoising Normal", "XYZ");
+ fill_mapping(map, INPUT_DENOISING_SHADOWING, "Denoising Shadowing", "X");
+ fill_mapping(map, INPUT_DENOISING_ALBEDO, "Denoising Albedo", "RGB");
+ fill_mapping(map, INPUT_NOISY_IMAGE, "Noisy Image", "RGB");
+ fill_mapping(map, INPUT_DENOISING_VARIANCE, "Denoising Variance", "RGB");
+ fill_mapping(map, INPUT_DENOISING_INTENSITY, "Denoising Intensity", "X");
+ return map;
}
static const int OUTPUT_NUM_CHANNELS = 3;
static vector<ChannelMapping> output_channels()
{
- vector<ChannelMapping> map;
- fill_mapping(map, 0, "Combined", "RGB");
- return map;
+ vector<ChannelMapping> map;
+ fill_mapping(map, 0, "Combined", "RGB");
+ return map;
}
/* Renderlayer Handling */
bool DenoiseImageLayer::detect_denoising_channels()
{
- /* Map device input to image channels. */
- input_to_image_channel.clear();
- input_to_image_channel.resize(INPUT_NUM_CHANNELS, -1);
+ /* Map device input to image channels. */
+ input_to_image_channel.clear();
+ input_to_image_channel.resize(INPUT_NUM_CHANNELS, -1);
- foreach(const ChannelMapping& mapping, input_channels()) {
- vector<string>::iterator i = find(channels.begin(), channels.end(), mapping.name);
- if(i == channels.end()) {
- return false;
- }
+ foreach (const ChannelMapping &mapping, input_channels()) {
+ vector<string>::iterator i = find(channels.begin(), channels.end(), mapping.name);
+ if (i == channels.end()) {
+ return false;
+ }
- size_t input_channel = mapping.channel;
- size_t layer_channel = i - channels.begin();
- input_to_image_channel[input_channel] = layer_to_image_channel[layer_channel];
- }
+ size_t input_channel = mapping.channel;
+ size_t layer_channel = i - channels.begin();
+ input_to_image_channel[input_channel] = layer_to_image_channel[layer_channel];
+ }
- /* Map device output to image channels. */
- output_to_image_channel.clear();
- output_to_image_channel.resize(OUTPUT_NUM_CHANNELS, -1);
+ /* Map device output to image channels. */
+ output_to_image_channel.clear();
+ output_to_image_channel.resize(OUTPUT_NUM_CHANNELS, -1);
- foreach(const ChannelMapping& mapping, output_channels()) {
- vector<string>::iterator i = find(channels.begin(), channels.end(), mapping.name);
- if(i == channels.end()) {
- return false;
- }
+ foreach (const ChannelMapping &mapping, output_channels()) {
+ vector<string>::iterator i = find(channels.begin(), channels.end(), mapping.name);
+ if (i == channels.end()) {
+ return false;
+ }
- size_t output_channel = mapping.channel;
- size_t layer_channel = i - channels.begin();
- output_to_image_channel[output_channel] = layer_to_image_channel[layer_channel];
- }
+ size_t output_channel = mapping.channel;
+ size_t layer_channel = i - channels.begin();
+ output_to_image_channel[output_channel] = layer_to_image_channel[layer_channel];
+ }
- /* Check that all buffer channels are correctly set. */
- for(int i = 0; i < INPUT_NUM_CHANNELS; i++) {
- assert(input_to_image_channel[i] >= 0);
- }
- for(int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
- assert(output_to_image_channel[i] >= 0);
- }
+ /* Check that all buffer channels are correctly set. */
+ for (int i = 0; i < INPUT_NUM_CHANNELS; i++) {
+ assert(input_to_image_channel[i] >= 0);
+ }
+ for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
+ assert(output_to_image_channel[i] >= 0);
+ }
- return true;
+ return true;
}
bool DenoiseImageLayer::match_channels(int neighbor,
const std::vector<string> &channelnames,
const std::vector<string> &neighbor_channelnames)
{
- neighbor_input_to_image_channel.resize(neighbor + 1);
- vector<int>& mapping = neighbor_input_to_image_channel[neighbor];
+ neighbor_input_to_image_channel.resize(neighbor + 1);
+ vector<int> &mapping = neighbor_input_to_image_channel[neighbor];
- assert(mapping.size() == 0);
- mapping.resize(input_to_image_channel.size(), -1);
+ assert(mapping.size() == 0);
+ mapping.resize(input_to_image_channel.size(), -1);
- for(int i = 0; i < input_to_image_channel.size(); i++) {
- const string& channel = channelnames[input_to_image_channel[i]];
- std::vector<string>::const_iterator frame_channel = find(neighbor_channelnames.begin(), neighbor_channelnames.end(), channel);
+ for (int i = 0; i < input_to_image_channel.size(); i++) {
+ const string &channel = channelnames[input_to_image_channel[i]];
+ std::vector<string>::const_iterator frame_channel = find(
+ neighbor_channelnames.begin(), neighbor_channelnames.end(), channel);
- if(frame_channel == neighbor_channelnames.end()) {
- return false;
- }
+ if (frame_channel == neighbor_channelnames.end()) {
+ return false;
+ }
- mapping[i] = frame_channel - neighbor_channelnames.begin();
- }
+ mapping[i] = frame_channel - neighbor_channelnames.begin();
+ }
- return true;
+ return true;
}
/* Denoise Task */
-DenoiseTask::DenoiseTask(Device *device, Denoiser *denoiser, int frame, const vector<int>& neighbor_frames)
-: denoiser(denoiser),
- device(device),
- frame(frame),
- neighbor_frames(neighbor_frames),
- current_layer(0),
- input_pixels(device, "filter input buffer", MEM_READ_ONLY),
- num_tiles(0)
+DenoiseTask::DenoiseTask(Device *device,
+ Denoiser *denoiser,
+ int frame,
+ const vector<int> &neighbor_frames)
+ : denoiser(denoiser),
+ device(device),
+ frame(frame),
+ neighbor_frames(neighbor_frames),
+ current_layer(0),
+ input_pixels(device, "filter input buffer", MEM_READ_ONLY),
+ num_tiles(0)
{
- image.samples = denoiser->samples_override;
+ image.samples = denoiser->samples_override;
}
DenoiseTask::~DenoiseTask()
{
- free();
+ free();
}
/* Device callbacks */
bool DenoiseTask::acquire_tile(Device *device, Device *tile_device, RenderTile &tile)
{
- thread_scoped_lock tile_lock(tiles_mutex);
+ thread_scoped_lock tile_lock(tiles_mutex);
- if(tiles.empty()) {
- return false;
- }
+ if (tiles.empty()) {
+ return false;
+ }
- tile = tiles.front();
- tiles.pop_front();
+ tile = tiles.front();
+ tiles.pop_front();
- device->map_tile(tile_device, tile);
+ device->map_tile(tile_device, tile);
- print_progress(num_tiles - tiles.size(), num_tiles, frame, denoiser->num_frames);
+ print_progress(num_tiles - tiles.size(), num_tiles, frame, denoiser->num_frames);
- return true;
+ return true;
}
/* Mapping tiles is required for regular rendering since each tile has its separate memory
@@ -268,87 +273,89 @@ bool DenoiseTask::acquire_tile(Device *device, Device *tile_device, RenderTile &
* a different buffer to avoid having to copy an entire horizontal slice of the image. */
void DenoiseTask::map_neighboring_tiles(RenderTile *tiles, Device *tile_device)
{
- /* Fill tile information. */
- for(int i = 0; i < 9; i++) {
- if(i == 4) {
- continue;
- }
-
- int dx = (i%3)-1;
- int dy = (i/3)-1;
- tiles[i].x = clamp(tiles[4].x + dx *denoiser->tile_size.x, 0, image.width);
- tiles[i].w = clamp(tiles[4].x + (dx+1)*denoiser->tile_size.x, 0, image.width) - tiles[i].x;
- tiles[i].y = clamp(tiles[4].y + dy *denoiser->tile_size.y, 0, image.height);
- tiles[i].h = clamp(tiles[4].y + (dy+1)*denoiser->tile_size.y, 0, image.height) - tiles[i].y;
-
- tiles[i].buffer = tiles[4].buffer;
- tiles[i].offset = tiles[4].offset;
- tiles[i].stride = image.width;
- }
-
- /* Allocate output buffer. */
- device_vector<float> *output_mem = new device_vector<float>(tile_device, "denoising_output", MEM_READ_WRITE);
- output_mem->alloc(OUTPUT_NUM_CHANNELS*tiles[4].w*tiles[4].h);
-
- /* Fill output buffer with noisy image, assumed by kernel_filter_finalize
- * when skipping denoising of some pixels. */
- float *result = output_mem->data();
- float *in = &image.pixels[image.num_channels*(tiles[4].y*image.width + tiles[4].x)];
-
- const DenoiseImageLayer& layer = image.layers[current_layer];
- const int *input_to_image_channel = layer.input_to_image_channel.data();
-
- for(int y = 0; y < tiles[4].h; y++) {
- for(int x = 0; x < tiles[4].w; x++, result += OUTPUT_NUM_CHANNELS) {
- for(int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
- result[i] = in[image.num_channels*x + input_to_image_channel[INPUT_NOISY_IMAGE + i]];
- }
- }
- in += image.num_channels * image.width;
- }
-
- output_mem->copy_to_device();
-
- /* Fill output tile info. */
- tiles[9] = tiles[4];
- tiles[9].buffer = output_mem->device_pointer;
- tiles[9].stride = tiles[9].w;
- tiles[9].offset -= tiles[9].x + tiles[9].y*tiles[9].stride;
-
- thread_scoped_lock output_lock(output_mutex);
- assert(output_pixels.count(tiles[4].tile_index) == 0);
- output_pixels[tiles[9].tile_index] = output_mem;
+ /* Fill tile information. */
+ for (int i = 0; i < 9; i++) {
+ if (i == 4) {
+ continue;
+ }
+
+ int dx = (i % 3) - 1;
+ int dy = (i / 3) - 1;
+ tiles[i].x = clamp(tiles[4].x + dx * denoiser->tile_size.x, 0, image.width);
+ tiles[i].w = clamp(tiles[4].x + (dx + 1) * denoiser->tile_size.x, 0, image.width) - tiles[i].x;
+ tiles[i].y = clamp(tiles[4].y + dy * denoiser->tile_size.y, 0, image.height);
+ tiles[i].h = clamp(tiles[4].y + (dy + 1) * denoiser->tile_size.y, 0, image.height) -
+ tiles[i].y;
+
+ tiles[i].buffer = tiles[4].buffer;
+ tiles[i].offset = tiles[4].offset;
+ tiles[i].stride = image.width;
+ }
+
+ /* Allocate output buffer. */
+ device_vector<float> *output_mem = new device_vector<float>(
+ tile_device, "denoising_output", MEM_READ_WRITE);
+ output_mem->alloc(OUTPUT_NUM_CHANNELS * tiles[4].w * tiles[4].h);
+
+ /* Fill output buffer with noisy image, assumed by kernel_filter_finalize
+ * when skipping denoising of some pixels. */
+ float *result = output_mem->data();
+ float *in = &image.pixels[image.num_channels * (tiles[4].y * image.width + tiles[4].x)];
+
+ const DenoiseImageLayer &layer = image.layers[current_layer];
+ const int *input_to_image_channel = layer.input_to_image_channel.data();
+
+ for (int y = 0; y < tiles[4].h; y++) {
+ for (int x = 0; x < tiles[4].w; x++, result += OUTPUT_NUM_CHANNELS) {
+ for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
+ result[i] = in[image.num_channels * x + input_to_image_channel[INPUT_NOISY_IMAGE + i]];
+ }
+ }
+ in += image.num_channels * image.width;
+ }
+
+ output_mem->copy_to_device();
+
+ /* Fill output tile info. */
+ tiles[9] = tiles[4];
+ tiles[9].buffer = output_mem->device_pointer;
+ tiles[9].stride = tiles[9].w;
+ tiles[9].offset -= tiles[9].x + tiles[9].y * tiles[9].stride;
+
+ thread_scoped_lock output_lock(output_mutex);
+ assert(output_pixels.count(tiles[4].tile_index) == 0);
+ output_pixels[tiles[9].tile_index] = output_mem;
}
void DenoiseTask::unmap_neighboring_tiles(RenderTile *tiles)
{
- thread_scoped_lock output_lock(output_mutex);
- assert(output_pixels.count(tiles[4].tile_index) == 1);
- device_vector<float> *output_mem = output_pixels[tiles[9].tile_index];
- output_pixels.erase(tiles[4].tile_index);
- output_lock.unlock();
+ thread_scoped_lock output_lock(output_mutex);
+ assert(output_pixels.count(tiles[4].tile_index) == 1);
+ device_vector<float> *output_mem = output_pixels[tiles[9].tile_index];
+ output_pixels.erase(tiles[4].tile_index);
+ output_lock.unlock();
- /* Copy denoised pixels from device. */
- output_mem->copy_from_device(0, OUTPUT_NUM_CHANNELS*tiles[9].w, tiles[9].h);
+ /* Copy denoised pixels from device. */
+ output_mem->copy_from_device(0, OUTPUT_NUM_CHANNELS * tiles[9].w, tiles[9].h);
- float *result = output_mem->data();
- float *out = &image.pixels[image.num_channels*(tiles[9].y*image.width + tiles[9].x)];
+ float *result = output_mem->data();
+ float *out = &image.pixels[image.num_channels * (tiles[9].y * image.width + tiles[9].x)];
- const DenoiseImageLayer& layer = image.layers[current_layer];
- const int *output_to_image_channel = layer.output_to_image_channel.data();
+ const DenoiseImageLayer &layer = image.layers[current_layer];
+ const int *output_to_image_channel = layer.output_to_image_channel.data();
- for(int y = 0; y < tiles[9].h; y++) {
- for(int x = 0; x < tiles[9].w; x++, result += OUTPUT_NUM_CHANNELS) {
- for(int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
- out[image.num_channels*x + output_to_image_channel[i]] = result[i];
- }
- }
- out += image.num_channels * image.width;
- }
+ for (int y = 0; y < tiles[9].h; y++) {
+ for (int x = 0; x < tiles[9].w; x++, result += OUTPUT_NUM_CHANNELS) {
+ for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
+ out[image.num_channels * x + output_to_image_channel[i]] = result[i];
+ }
+ }
+ out += image.num_channels * image.width;
+ }
- /* Free device buffer. */
- output_mem->free();
- delete output_mem;
+ /* Free device buffer. */
+ output_mem->free();
+ delete output_mem;
}
void DenoiseTask::release_tile()
@@ -357,542 +364,547 @@ void DenoiseTask::release_tile()
bool DenoiseTask::get_cancel()
{
- return false;
-}
-
-void DenoiseTask::create_task(DeviceTask& task)
-{
- /* Callback functions. */
- task.acquire_tile = function_bind(&DenoiseTask::acquire_tile, this, device, _1, _2);
- task.map_neighbor_tiles = function_bind(&DenoiseTask::map_neighboring_tiles, this, _1, _2);
- task.unmap_neighbor_tiles = function_bind(&DenoiseTask::unmap_neighboring_tiles, this, _1);
- task.release_tile = function_bind(&DenoiseTask::release_tile, this);
- task.get_cancel = function_bind(&DenoiseTask::get_cancel, this);
-
- /* Denoising parameters. */
- task.denoising = denoiser->params;
- task.denoising_do_filter = true;
- task.denoising_write_passes = false;
- task.denoising_from_render = false;
-
- task.denoising_frames.resize(neighbor_frames.size());
- for(int i = 0; i < neighbor_frames.size(); i++) {
- task.denoising_frames[i] = neighbor_frames[i] - frame;
- }
-
- /* Buffer parameters. */
- task.pass_stride = INPUT_NUM_CHANNELS;
- task.target_pass_stride = OUTPUT_NUM_CHANNELS;
- task.pass_denoising_data = 0;
- task.pass_denoising_clean = -1;
- task.frame_stride = image.width * image.height * INPUT_NUM_CHANNELS;
-
- /* Create tiles. */
- thread_scoped_lock tile_lock(tiles_mutex);
- thread_scoped_lock output_lock(output_mutex);
-
- tiles.clear();
- assert(output_pixels.empty());
- output_pixels.clear();
-
- int tiles_x = divide_up(image.width, denoiser->tile_size.x);
- int tiles_y = divide_up(image.height, denoiser->tile_size.y);
-
- for(int ty = 0; ty < tiles_y; ty++) {
- for(int tx = 0; tx < tiles_x; tx++) {
- RenderTile tile;
- tile.x = tx * denoiser->tile_size.x;
- tile.y = ty * denoiser->tile_size.y;
- tile.w = min(image.width - tile.x, denoiser->tile_size.x);
- tile.h = min(image.height - tile.y, denoiser->tile_size.y);
- tile.start_sample = 0;
- tile.num_samples = image.layers[current_layer].samples;
- tile.sample = 0;
- tile.offset = 0;
- tile.stride = image.width;
- tile.tile_index = ty*tiles_x + tx;
- tile.task = RenderTile::DENOISE;
- tile.buffers = NULL;
- tile.buffer = input_pixels.device_pointer;
- tiles.push_back(tile);
- }
- }
-
- num_tiles = tiles.size();
+ return false;
+}
+
+void DenoiseTask::create_task(DeviceTask &task)
+{
+ /* Callback functions. */
+ task.acquire_tile = function_bind(&DenoiseTask::acquire_tile, this, device, _1, _2);
+ task.map_neighbor_tiles = function_bind(&DenoiseTask::map_neighboring_tiles, this, _1, _2);
+ task.unmap_neighbor_tiles = function_bind(&DenoiseTask::unmap_neighboring_tiles, this, _1);
+ task.release_tile = function_bind(&DenoiseTask::release_tile, this);
+ task.get_cancel = function_bind(&DenoiseTask::get_cancel, this);
+
+ /* Denoising parameters. */
+ task.denoising = denoiser->params;
+ task.denoising_do_filter = true;
+ task.denoising_write_passes = false;
+ task.denoising_from_render = false;
+
+ task.denoising_frames.resize(neighbor_frames.size());
+ for (int i = 0; i < neighbor_frames.size(); i++) {
+ task.denoising_frames[i] = neighbor_frames[i] - frame;
+ }
+
+ /* Buffer parameters. */
+ task.pass_stride = INPUT_NUM_CHANNELS;
+ task.target_pass_stride = OUTPUT_NUM_CHANNELS;
+ task.pass_denoising_data = 0;
+ task.pass_denoising_clean = -1;
+ task.frame_stride = image.width * image.height * INPUT_NUM_CHANNELS;
+
+ /* Create tiles. */
+ thread_scoped_lock tile_lock(tiles_mutex);
+ thread_scoped_lock output_lock(output_mutex);
+
+ tiles.clear();
+ assert(output_pixels.empty());
+ output_pixels.clear();
+
+ int tiles_x = divide_up(image.width, denoiser->tile_size.x);
+ int tiles_y = divide_up(image.height, denoiser->tile_size.y);
+
+ for (int ty = 0; ty < tiles_y; ty++) {
+ for (int tx = 0; tx < tiles_x; tx++) {
+ RenderTile tile;
+ tile.x = tx * denoiser->tile_size.x;
+ tile.y = ty * denoiser->tile_size.y;
+ tile.w = min(image.width - tile.x, denoiser->tile_size.x);
+ tile.h = min(image.height - tile.y, denoiser->tile_size.y);
+ tile.start_sample = 0;
+ tile.num_samples = image.layers[current_layer].samples;
+ tile.sample = 0;
+ tile.offset = 0;
+ tile.stride = image.width;
+ tile.tile_index = ty * tiles_x + tx;
+ tile.task = RenderTile::DENOISE;
+ tile.buffers = NULL;
+ tile.buffer = input_pixels.device_pointer;
+ tiles.push_back(tile);
+ }
+ }
+
+ num_tiles = tiles.size();
}
/* Denoiser Operations */
bool DenoiseTask::load_input_pixels(int layer)
{
- int w = image.width;
- int h = image.height;
- int num_pixels = image.width * image.height;
- int frame_stride = num_pixels * INPUT_NUM_CHANNELS;
-
- /* Load center image */
- DenoiseImageLayer& image_layer = image.layers[layer];
-
- float *buffer_data = input_pixels.data();
- image.read_pixels(image_layer, buffer_data);
- buffer_data += frame_stride;
-
- /* Load neighbor images */
- for(int i = 0; i < image.in_neighbors.size(); i++) {
- if(!image.read_neighbor_pixels(i, image_layer, buffer_data)) {
- error = "Failed to read neighbor frame pixels";
- return false;
- }
- buffer_data += frame_stride;
- }
-
- /* Preprocess */
- buffer_data = input_pixels.data();
- for(int neighbor = 0; neighbor < image.in_neighbors.size() + 1; neighbor++) {
- /* Clamp */
- if(denoiser->params.clamp_input) {
- for(int i = 0; i < num_pixels*INPUT_NUM_CHANNELS; i++) {
- buffer_data[i] = clamp(buffer_data[i], -1e8f, 1e8f);
- }
- }
-
- /* Box blur */
- int r = 5 * denoiser->params.radius;
- float *data = buffer_data + 14;
- array<float> temp(num_pixels);
-
- for(int y = 0; y < h; y++) {
- for(int x = 0; x < w; x++) {
- int n = 0;
- float sum = 0.0f;
- for(int dx = max(x - r, 0); dx < min(x + r + 1, w); dx++, n++) {
- sum += data[INPUT_NUM_CHANNELS * (y * w + dx)];
- }
- temp[y * w + x] = sum/n;
- }
- }
-
- for(int y = 0; y < h; y++) {
- for(int x = 0; x < w; x++) {
- int n = 0;
- float sum = 0.0f;
-
- for(int dy = max(y - r, 0); dy < min(y + r + 1, h); dy++, n++) {
- sum += temp[dy * w + x];
- }
-
- data[INPUT_NUM_CHANNELS * (y * w + x)] = sum/n;
- }
- }
-
- buffer_data += frame_stride;
- }
-
- /* Copy to device */
- input_pixels.copy_to_device();
-
- return true;
+ int w = image.width;
+ int h = image.height;
+ int num_pixels = image.width * image.height;
+ int frame_stride = num_pixels * INPUT_NUM_CHANNELS;
+
+ /* Load center image */
+ DenoiseImageLayer &image_layer = image.layers[layer];
+
+ float *buffer_data = input_pixels.data();
+ image.read_pixels(image_layer, buffer_data);
+ buffer_data += frame_stride;
+
+ /* Load neighbor images */
+ for (int i = 0; i < image.in_neighbors.size(); i++) {
+ if (!image.read_neighbor_pixels(i, image_layer, buffer_data)) {
+ error = "Failed to read neighbor frame pixels";
+ return false;
+ }
+ buffer_data += frame_stride;
+ }
+
+ /* Preprocess */
+ buffer_data = input_pixels.data();
+ for (int neighbor = 0; neighbor < image.in_neighbors.size() + 1; neighbor++) {
+ /* Clamp */
+ if (denoiser->params.clamp_input) {
+ for (int i = 0; i < num_pixels * INPUT_NUM_CHANNELS; i++) {
+ buffer_data[i] = clamp(buffer_data[i], -1e8f, 1e8f);
+ }
+ }
+
+ /* Box blur */
+ int r = 5 * denoiser->params.radius;
+ float *data = buffer_data + 14;
+ array<float> temp(num_pixels);
+
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ int n = 0;
+ float sum = 0.0f;
+ for (int dx = max(x - r, 0); dx < min(x + r + 1, w); dx++, n++) {
+ sum += data[INPUT_NUM_CHANNELS * (y * w + dx)];
+ }
+ temp[y * w + x] = sum / n;
+ }
+ }
+
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ int n = 0;
+ float sum = 0.0f;
+
+ for (int dy = max(y - r, 0); dy < min(y + r + 1, h); dy++, n++) {
+ sum += temp[dy * w + x];
+ }
+
+ data[INPUT_NUM_CHANNELS * (y * w + x)] = sum / n;
+ }
+ }
+
+ buffer_data += frame_stride;
+ }
+
+ /* Copy to device */
+ input_pixels.copy_to_device();
+
+ return true;
}
/* Task stages */
bool DenoiseTask::load()
{
- string center_filepath = denoiser->input[frame];
- if(!image.load(center_filepath, error)) {
- return false;
- }
+ string center_filepath = denoiser->input[frame];
+ if (!image.load(center_filepath, error)) {
+ return false;
+ }
- if(!image.load_neighbors(denoiser->input, neighbor_frames, error)) {
- return false;
- }
+ if (!image.load_neighbors(denoiser->input, neighbor_frames, error)) {
+ return false;
+ }
- if(image.layers.empty()) {
- error = "No image layers found to denoise in " + center_filepath;
- return false;
- }
+ if (image.layers.empty()) {
+ error = "No image layers found to denoise in " + center_filepath;
+ return false;
+ }
- /* Allocate device buffer. */
- int num_frames = image.in_neighbors.size() + 1;
- input_pixels.alloc(image.width * INPUT_NUM_CHANNELS, image.height * num_frames);
- input_pixels.zero_to_device();
+ /* Allocate device buffer. */
+ int num_frames = image.in_neighbors.size() + 1;
+ input_pixels.alloc(image.width * INPUT_NUM_CHANNELS, image.height * num_frames);
+ input_pixels.zero_to_device();
- /* Read pixels for first layer. */
- current_layer = 0;
- if(!load_input_pixels(current_layer)) {
- return false;
- }
+ /* Read pixels for first layer. */
+ current_layer = 0;
+ if (!load_input_pixels(current_layer)) {
+ return false;
+ }
- return true;
+ return true;
}
bool DenoiseTask::exec()
{
- for(current_layer = 0; current_layer < image.layers.size(); current_layer++) {
- /* Read pixels for secondary layers, first was already loaded. */
- if(current_layer > 0) {
- if(!load_input_pixels(current_layer)) {
- return false;
- }
- }
+ for (current_layer = 0; current_layer < image.layers.size(); current_layer++) {
+ /* Read pixels for secondary layers, first was already loaded. */
+ if (current_layer > 0) {
+ if (!load_input_pixels(current_layer)) {
+ return false;
+ }
+ }
- /* Run task on device. */
- DeviceTask task(DeviceTask::RENDER);
- create_task(task);
- device->task_add(task);
- device->task_wait();
+ /* Run task on device. */
+ DeviceTask task(DeviceTask::RENDER);
+ create_task(task);
+ device->task_add(task);
+ device->task_wait();
- printf("\n");
- }
+ printf("\n");
+ }
- return true;
+ return true;
}
bool DenoiseTask::save()
{
- bool ok = image.save_output(denoiser->output[frame], error);
- free();
- return ok;
+ bool ok = image.save_output(denoiser->output[frame], error);
+ free();
+ return ok;
}
void DenoiseTask::free()
{
- image.free();
- input_pixels.free();
- assert(output_pixels.empty());
+ image.free();
+ input_pixels.free();
+ assert(output_pixels.empty());
}
/* Denoise Image Storage */
DenoiseImage::DenoiseImage()
{
- width = 0;
- height = 0;
- num_channels = 0;
- samples = 0;
+ width = 0;
+ height = 0;
+ num_channels = 0;
+ samples = 0;
}
DenoiseImage::~DenoiseImage()
{
- free();
+ free();
}
void DenoiseImage::close_input()
{
- in_neighbors.clear();
+ in_neighbors.clear();
}
void DenoiseImage::free()
{
- close_input();
- pixels.clear();
-}
-
-bool DenoiseImage::parse_channels(const ImageSpec &in_spec, string& error)
+ close_input();
+ pixels.clear();
+}
+
+bool DenoiseImage::parse_channels(const ImageSpec &in_spec, string &error)
{
- const std::vector<string> &channels = in_spec.channelnames;
- const ParamValue *multiview = in_spec.find_attribute("multiView");
- const bool multiview_channels = (multiview &&
- multiview->type().basetype == TypeDesc::STRING &&
- multiview->type().arraylen >= 2);
-
- layers.clear();
-
- /* Loop over all the channels in the file, parse their name and sort them
- * by RenderLayer.
- * Channels that can't be parsed are directly passed through to the output. */
- map<string, DenoiseImageLayer> file_layers;
- for(int i = 0; i < channels.size(); i++) {
- string layer, pass, channel;
- if(parse_channel_name(channels[i], layer, pass, channel, multiview_channels)) {
- file_layers[layer].channels.push_back(pass + "." + channel);
- file_layers[layer].layer_to_image_channel.push_back(i);
- }
- }
-
- /* Loop over all detected RenderLayers, check whether they contain a full set of input channels.
- * Any channels that won't be processed internally are also passed through. */
- for(map<string, DenoiseImageLayer>::iterator i = file_layers.begin(); i != file_layers.end(); ++i) {
- const string& name = i->first;
- DenoiseImageLayer& layer = i->second;
-
- /* Check for full pass set. */
- if(!layer.detect_denoising_channels()) {
- continue;
- }
-
- layer.name = name;
- layer.samples = samples;
-
- /* If the sample value isn't set yet, check if there is a layer-specific one in the input file. */
- if(layer.samples < 1) {
- string sample_string = in_spec.get_string_attribute("cycles." + name + ".samples", "");
- if(sample_string != "") {
- if(!sscanf(sample_string.c_str(), "%d", &layer.samples)) {
- error = "Failed to parse samples metadata: " + sample_string;
- return false;
- }
- }
- }
-
- if(layer.samples < 1) {
- error = string_printf("No sample number specified in the file for layer %s or on the command line", name.c_str());
- return false;
- }
-
- layers.push_back(layer);
- }
-
- return true;
-}
-
-void DenoiseImage::read_pixels(const DenoiseImageLayer& layer, float *input_pixels)
-{
- /* Pixels from center file have already been loaded into pixels.
- * We copy a subset into the device input buffer with channels reshuffled. */
- const int *input_to_image_channel = layer.input_to_image_channel.data();
-
- for(int i = 0; i < width * height; i++) {
- for(int j = 0; j < INPUT_NUM_CHANNELS; j++) {
- int image_channel = input_to_image_channel[j];
- input_pixels[i*INPUT_NUM_CHANNELS + j] = pixels[((size_t)i)*num_channels + image_channel];
- }
- }
-}
-
-bool DenoiseImage::read_neighbor_pixels(int neighbor, const DenoiseImageLayer& layer, float *input_pixels)
-{
- /* Load pixels from neighboring frames, and copy them into device buffer
- * with channels reshuffled. */
- size_t num_pixels = (size_t)width * (size_t)height;
- array<float> neighbor_pixels(num_pixels * num_channels);
- if(!in_neighbors[neighbor]->read_image(TypeDesc::FLOAT, neighbor_pixels.data())) {
- return false;
- }
-
- const int *input_to_image_channel = layer.neighbor_input_to_image_channel[neighbor].data();
-
- for(int i = 0; i < width * height; i++) {
- for(int j = 0; j < INPUT_NUM_CHANNELS; j++) {
- int image_channel = input_to_image_channel[j];
- input_pixels[i*INPUT_NUM_CHANNELS + j] = neighbor_pixels[((size_t)i)*num_channels + image_channel];
- }
- }
-
- return true;
-}
-
-bool DenoiseImage::load(const string& in_filepath, string& error)
-{
- if(!Filesystem::is_regular(in_filepath)) {
- error = "Couldn't find file: " + in_filepath;
- return false;
- }
-
- unique_ptr<ImageInput> in(ImageInput::open(in_filepath));
- if(!in) {
- error = "Couldn't open file: " + in_filepath;
- return false;
- }
-
- in_spec = in->spec();
- width = in_spec.width;
- height = in_spec.height;
- num_channels = in_spec.nchannels;
-
- if(!parse_channels(in_spec, error)) {
- return false;
- }
-
- if(layers.size() == 0) {
- error = "Could not find a render layer containing denoising info";
- return false;
- }
-
- size_t num_pixels = (size_t)width * (size_t)height;
- pixels.resize(num_pixels * num_channels);
-
- /* Read all channels into buffer. Reading all channels at once is faster
- * than individually due to interleaved EXR channel storage. */
- if(!in->read_image(TypeDesc::FLOAT, pixels.data())) {
- error = "Failed to read image: " + in_filepath;
- return false;
- }
-
- return true;
-}
-
-bool DenoiseImage::load_neighbors(const vector<string>& filepaths, const vector<int>& frames, string& error)
-{
- if(frames.size() > DENOISE_MAX_FRAMES - 1) {
- error = string_printf("Maximum number of neighbors (%d) exceeded\n", DENOISE_MAX_FRAMES - 1);
- return false;
- }
-
- for(int neighbor = 0; neighbor < frames.size(); neighbor++) {
- int frame = frames[neighbor];
- const string& filepath = filepaths[frame];
-
- if(!Filesystem::is_regular(filepath)) {
- error = "Couldn't find neighbor frame: " + filepath;
- return false;
- }
-
- unique_ptr<ImageInput> in_neighbor(ImageInput::open(filepath));
- if(!in_neighbor) {
- error = "Couldn't open neighbor frame: " + filepath;
- return false;
- }
+ const std::vector<string> &channels = in_spec.channelnames;
+ const ParamValue *multiview = in_spec.find_attribute("multiView");
+ const bool multiview_channels = (multiview && multiview->type().basetype == TypeDesc::STRING &&
+ multiview->type().arraylen >= 2);
+
+ layers.clear();
+
+ /* Loop over all the channels in the file, parse their name and sort them
+ * by RenderLayer.
+ * Channels that can't be parsed are directly passed through to the output. */
+ map<string, DenoiseImageLayer> file_layers;
+ for (int i = 0; i < channels.size(); i++) {
+ string layer, pass, channel;
+ if (parse_channel_name(channels[i], layer, pass, channel, multiview_channels)) {
+ file_layers[layer].channels.push_back(pass + "." + channel);
+ file_layers[layer].layer_to_image_channel.push_back(i);
+ }
+ }
+
+ /* Loop over all detected RenderLayers, check whether they contain a full set of input channels.
+ * Any channels that won't be processed internally are also passed through. */
+ for (map<string, DenoiseImageLayer>::iterator i = file_layers.begin(); i != file_layers.end();
+ ++i) {
+ const string &name = i->first;
+ DenoiseImageLayer &layer = i->second;
+
+ /* Check for full pass set. */
+ if (!layer.detect_denoising_channels()) {
+ continue;
+ }
+
+ layer.name = name;
+ layer.samples = samples;
+
+ /* If the sample value isn't set yet, check if there is a layer-specific one in the input file. */
+ if (layer.samples < 1) {
+ string sample_string = in_spec.get_string_attribute("cycles." + name + ".samples", "");
+ if (sample_string != "") {
+ if (!sscanf(sample_string.c_str(), "%d", &layer.samples)) {
+ error = "Failed to parse samples metadata: " + sample_string;
+ return false;
+ }
+ }
+ }
+
+ if (layer.samples < 1) {
+ error = string_printf(
+ "No sample number specified in the file for layer %s or on the command line",
+ name.c_str());
+ return false;
+ }
+
+ layers.push_back(layer);
+ }
+
+ return true;
+}
+
+void DenoiseImage::read_pixels(const DenoiseImageLayer &layer, float *input_pixels)
+{
+ /* Pixels from center file have already been loaded into pixels.
+ * We copy a subset into the device input buffer with channels reshuffled. */
+ const int *input_to_image_channel = layer.input_to_image_channel.data();
+
+ for (int i = 0; i < width * height; i++) {
+ for (int j = 0; j < INPUT_NUM_CHANNELS; j++) {
+ int image_channel = input_to_image_channel[j];
+ input_pixels[i * INPUT_NUM_CHANNELS + j] =
+ pixels[((size_t)i) * num_channels + image_channel];
+ }
+ }
+}
+
+bool DenoiseImage::read_neighbor_pixels(int neighbor,
+ const DenoiseImageLayer &layer,
+ float *input_pixels)
+{
+ /* Load pixels from neighboring frames, and copy them into device buffer
+ * with channels reshuffled. */
+ size_t num_pixels = (size_t)width * (size_t)height;
+ array<float> neighbor_pixels(num_pixels * num_channels);
+ if (!in_neighbors[neighbor]->read_image(TypeDesc::FLOAT, neighbor_pixels.data())) {
+ return false;
+ }
+
+ const int *input_to_image_channel = layer.neighbor_input_to_image_channel[neighbor].data();
+
+ for (int i = 0; i < width * height; i++) {
+ for (int j = 0; j < INPUT_NUM_CHANNELS; j++) {
+ int image_channel = input_to_image_channel[j];
+ input_pixels[i * INPUT_NUM_CHANNELS + j] =
+ neighbor_pixels[((size_t)i) * num_channels + image_channel];
+ }
+ }
+
+ return true;
+}
+
+bool DenoiseImage::load(const string &in_filepath, string &error)
+{
+ if (!Filesystem::is_regular(in_filepath)) {
+ error = "Couldn't find file: " + in_filepath;
+ return false;
+ }
+
+ unique_ptr<ImageInput> in(ImageInput::open(in_filepath));
+ if (!in) {
+ error = "Couldn't open file: " + in_filepath;
+ return false;
+ }
+
+ in_spec = in->spec();
+ width = in_spec.width;
+ height = in_spec.height;
+ num_channels = in_spec.nchannels;
+
+ if (!parse_channels(in_spec, error)) {
+ return false;
+ }
+
+ if (layers.size() == 0) {
+ error = "Could not find a render layer containing denoising info";
+ return false;
+ }
+
+ size_t num_pixels = (size_t)width * (size_t)height;
+ pixels.resize(num_pixels * num_channels);
+
+ /* Read all channels into buffer. Reading all channels at once is faster
+ * than individually due to interleaved EXR channel storage. */
+ if (!in->read_image(TypeDesc::FLOAT, pixels.data())) {
+ error = "Failed to read image: " + in_filepath;
+ return false;
+ }
+
+ return true;
+}
+
+bool DenoiseImage::load_neighbors(const vector<string> &filepaths,
+ const vector<int> &frames,
+ string &error)
+{
+ if (frames.size() > DENOISE_MAX_FRAMES - 1) {
+ error = string_printf("Maximum number of neighbors (%d) exceeded\n", DENOISE_MAX_FRAMES - 1);
+ return false;
+ }
+
+ for (int neighbor = 0; neighbor < frames.size(); neighbor++) {
+ int frame = frames[neighbor];
+ const string &filepath = filepaths[frame];
- const ImageSpec &neighbor_spec = in_neighbor->spec();
- if(neighbor_spec.width != width || neighbor_spec.height != height) {
- error = "Neighbor frame has different dimensions: " + filepath;
- return false;
- }
-
- foreach(DenoiseImageLayer& layer, layers) {
- if(!layer.match_channels(neighbor,
- in_spec.channelnames,
- neighbor_spec.channelnames))
- {
- error = "Neighbor frame misses denoising data passes: " + filepath;
- return false;
- }
- }
-
- in_neighbors.push_back(std::move(in_neighbor));
- }
-
- return true;
-}
-
-bool DenoiseImage::save_output(const string& out_filepath, string& error)
-{
- /* Save image with identical dimensions, channels and metadata. */
- ImageSpec out_spec = in_spec;
-
- /* Ensure that the output frame contains sample information even if the input didn't. */
- for(int i = 0; i < layers.size(); i++) {
- string name = "cycles." + layers[i].name + ".samples";
- if(!out_spec.find_attribute(name, TypeDesc::STRING)) {
- out_spec.attribute(name, TypeDesc::STRING, string_printf("%d", layers[i].samples));
- }
- }
+ if (!Filesystem::is_regular(filepath)) {
+ error = "Couldn't find neighbor frame: " + filepath;
+ return false;
+ }
+
+ unique_ptr<ImageInput> in_neighbor(ImageInput::open(filepath));
+ if (!in_neighbor) {
+ error = "Couldn't open neighbor frame: " + filepath;
+ return false;
+ }
+
+ const ImageSpec &neighbor_spec = in_neighbor->spec();
+ if (neighbor_spec.width != width || neighbor_spec.height != height) {
+ error = "Neighbor frame has different dimensions: " + filepath;
+ return false;
+ }
+
+ foreach (DenoiseImageLayer &layer, layers) {
+ if (!layer.match_channels(neighbor, in_spec.channelnames, neighbor_spec.channelnames)) {
+ error = "Neighbor frame misses denoising data passes: " + filepath;
+ return false;
+ }
+ }
+
+ in_neighbors.push_back(std::move(in_neighbor));
+ }
+
+ return true;
+}
+
+bool DenoiseImage::save_output(const string &out_filepath, string &error)
+{
+ /* Save image with identical dimensions, channels and metadata. */
+ ImageSpec out_spec = in_spec;
+
+ /* Ensure that the output frame contains sample information even if the input didn't. */
+ for (int i = 0; i < layers.size(); i++) {
+ string name = "cycles." + layers[i].name + ".samples";
+ if (!out_spec.find_attribute(name, TypeDesc::STRING)) {
+ out_spec.attribute(name, TypeDesc::STRING, string_printf("%d", layers[i].samples));
+ }
+ }
- /* We don't need input anymore at this point, and will possibly
- * overwrite the same file. */
- close_input();
-
- /* Write to temporary file path, so we denoise images in place and don't
- * risk destroying files when something goes wrong in file saving. */
- string extension = OIIO::Filesystem::extension(out_filepath);
- string unique_name = ".denoise-tmp-" + OIIO::Filesystem::unique_path();
- string tmp_filepath = out_filepath + unique_name + extension;
- unique_ptr<ImageOutput> out(ImageOutput::create(tmp_filepath));
-
- if(!out) {
- error = "Failed to open temporary file " + tmp_filepath + " for writing";
- return false;
- }
-
- /* Open temporary file and write image buffers. */
- if(!out->open(tmp_filepath, out_spec)) {
- error = "Failed to open file " + tmp_filepath + " for writing: " + out->geterror();
- return false;
- }
-
- bool ok = true;
- if(!out->write_image(TypeDesc::FLOAT, pixels.data())) {
- error = "Failed to write to file " + tmp_filepath + ": " + out->geterror();
- ok = false;
- }
-
- if(!out->close()) {
- error = "Failed to save to file " + tmp_filepath + ": " + out->geterror();
- ok = false;
- }
-
- out.reset();
-
- /* Copy temporary file to outputput filepath. */
- string rename_error;
- if(ok && !OIIO::Filesystem::rename(tmp_filepath, out_filepath, rename_error)) {
- error = "Failed to move denoised image to " + out_filepath + ": " + rename_error;
- ok = false;
- }
-
- if(!ok) {
- OIIO::Filesystem::remove(tmp_filepath);
- }
-
- return ok;
+ /* We don't need input anymore at this point, and will possibly
+ * overwrite the same file. */
+ close_input();
+
+ /* Write to temporary file path, so we denoise images in place and don't
+ * risk destroying files when something goes wrong in file saving. */
+ string extension = OIIO::Filesystem::extension(out_filepath);
+ string unique_name = ".denoise-tmp-" + OIIO::Filesystem::unique_path();
+ string tmp_filepath = out_filepath + unique_name + extension;
+ unique_ptr<ImageOutput> out(ImageOutput::create(tmp_filepath));
+
+ if (!out) {
+ error = "Failed to open temporary file " + tmp_filepath + " for writing";
+ return false;
+ }
+
+ /* Open temporary file and write image buffers. */
+ if (!out->open(tmp_filepath, out_spec)) {
+ error = "Failed to open file " + tmp_filepath + " for writing: " + out->geterror();
+ return false;
+ }
+
+ bool ok = true;
+ if (!out->write_image(TypeDesc::FLOAT, pixels.data())) {
+ error = "Failed to write to file " + tmp_filepath + ": " + out->geterror();
+ ok = false;
+ }
+
+ if (!out->close()) {
+ error = "Failed to save to file " + tmp_filepath + ": " + out->geterror();
+ ok = false;
+ }
+
+ out.reset();
+
+ /* Copy temporary file to outputput filepath. */
+ string rename_error;
+ if (ok && !OIIO::Filesystem::rename(tmp_filepath, out_filepath, rename_error)) {
+ error = "Failed to move denoised image to " + out_filepath + ": " + rename_error;
+ ok = false;
+ }
+
+ if (!ok) {
+ OIIO::Filesystem::remove(tmp_filepath);
+ }
+
+ return ok;
}
/* File pattern handling and outer loop over frames */
-Denoiser::Denoiser(DeviceInfo& device_info)
+Denoiser::Denoiser(DeviceInfo &device_info)
{
- samples_override = 0;
- tile_size = make_int2(64, 64);
+ samples_override = 0;
+ tile_size = make_int2(64, 64);
- num_frames = 0;
+ num_frames = 0;
- /* Initialize task scheduler. */
- TaskScheduler::init();
+ /* Initialize task scheduler. */
+ TaskScheduler::init();
- /* Initialize device. */
- DeviceRequestedFeatures req;
- device = Device::create(device_info, stats, profiler, true);
- device->load_kernels(req);
+ /* Initialize device. */
+ DeviceRequestedFeatures req;
+ device = Device::create(device_info, stats, profiler, true);
+ device->load_kernels(req);
}
Denoiser::~Denoiser()
{
- delete device;
- TaskScheduler::exit();
+ delete device;
+ TaskScheduler::exit();
}
bool Denoiser::run()
{
- assert(input.size() == output.size());
-
- num_frames = output.size();
-
- for(int frame = 0; frame < num_frames; frame++) {
- /* Skip empty output paths. */
- if(output[frame].empty()) {
- continue;
- }
-
- /* Determine neighbor frame numbers that should be used for filtering. */
- vector<int> neighbor_frames;
- for(int f = frame - params.neighbor_frames; f <= frame + params.neighbor_frames; f++) {
- if (f >= 0 && f < num_frames && f != frame) {
- neighbor_frames.push_back(f);
- }
- }
-
- /* Execute task. */
- DenoiseTask task(device, this, frame, neighbor_frames);
- if(!task.load()) {
- error = task.error;
- return false;
- }
-
- if(!task.exec()) {
- error = task.error;
- return false;
- }
-
- if(!task.save()) {
- error = task.error;
- return false;
- }
-
- task.free();
- }
-
- return true;
+ assert(input.size() == output.size());
+
+ num_frames = output.size();
+
+ for (int frame = 0; frame < num_frames; frame++) {
+ /* Skip empty output paths. */
+ if (output[frame].empty()) {
+ continue;
+ }
+
+ /* Determine neighbor frame numbers that should be used for filtering. */
+ vector<int> neighbor_frames;
+ for (int f = frame - params.neighbor_frames; f <= frame + params.neighbor_frames; f++) {
+ if (f >= 0 && f < num_frames && f != frame) {
+ neighbor_frames.push_back(f);
+ }
+ }
+
+ /* Execute task. */
+ DenoiseTask task(device, this, frame, neighbor_frames);
+ if (!task.load()) {
+ error = task.error;
+ return false;
+ }
+
+ if (!task.exec()) {
+ error = task.error;
+ return false;
+ }
+
+ if (!task.save()) {
+ error = task.error;
+ return false;
+ }
+
+ task.free();
+ }
+
+ return true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/denoising.h b/intern/cycles/render/denoising.h
index 5bf1a8dd0fa..dcb842a4603 100644
--- a/intern/cycles/render/denoising.h
+++ b/intern/cycles/render/denoising.h
@@ -35,166 +35,166 @@ CCL_NAMESPACE_BEGIN
/* Denoiser */
class Denoiser {
-public:
- Denoiser(DeviceInfo& device_info);
- ~Denoiser();
+ public:
+ Denoiser(DeviceInfo &device_info);
+ ~Denoiser();
- bool run();
+ bool run();
- /* Error message after running, in case of failure. */
- string error;
+ /* Error message after running, in case of failure. */
+ string error;
- /* Sequential list of frame filepaths to denoise. */
- vector<string> input;
- /* Sequential list of frame filepaths to write result to. Empty entries
- * are skipped, so only a subset of the sequence can be denoised while
- * taking into account all input frames. */
- vector<string> output;
+ /* Sequential list of frame filepaths to denoise. */
+ vector<string> input;
+ /* Sequential list of frame filepaths to write result to. Empty entries
+ * are skipped, so only a subset of the sequence can be denoised while
+ * taking into account all input frames. */
+ vector<string> output;
- /* Sample number override, takes precedence over values from input frames. */
- int samples_override;
- /* Tile size for processing on device. */
- int2 tile_size;
+ /* Sample number override, takes precedence over values from input frames. */
+ int samples_override;
+ /* Tile size for processing on device. */
+ int2 tile_size;
- /* Equivalent to the settings in the regular denoiser. */
- DenoiseParams params;
+ /* Equivalent to the settings in the regular denoiser. */
+ DenoiseParams params;
-protected:
- friend class DenoiseTask;
+ protected:
+ friend class DenoiseTask;
- Stats stats;
- Profiler profiler;
- Device *device;
+ Stats stats;
+ Profiler profiler;
+ Device *device;
- int num_frames;
+ int num_frames;
};
/* Denoise Image Layer */
struct DenoiseImageLayer {
- string name;
- /* All channels belonging to this DenoiseImageLayer. */
- vector<string> channels;
- /* Layer to image channel mapping. */
- vector<int> layer_to_image_channel;
+ string name;
+ /* All channels belonging to this DenoiseImageLayer. */
+ vector<string> channels;
+ /* Layer to image channel mapping. */
+ vector<int> layer_to_image_channel;
- /* Sample amount that was used for rendering this layer. */
- int samples;
+ /* Sample amount that was used for rendering this layer. */
+ int samples;
- /* Device input channel will be copied from image channel input_to_image_channel[i]. */
- vector<int> input_to_image_channel;
+ /* Device input channel will be copied from image channel input_to_image_channel[i]. */
+ vector<int> input_to_image_channel;
- /* input_to_image_channel of the secondary frames, if any are used. */
- vector<vector<int>> neighbor_input_to_image_channel;
+ /* input_to_image_channel of the secondary frames, if any are used. */
+ vector<vector<int>> neighbor_input_to_image_channel;
- /* Write i-th channel of the processing output to output_to_image_channel[i]-th channel of the file. */
- vector<int> output_to_image_channel;
+ /* Write i-th channel of the processing output to output_to_image_channel[i]-th channel of the file. */
+ vector<int> output_to_image_channel;
- /* Detect whether this layer contains a full set of channels and set up the offsets accordingly. */
- bool detect_denoising_channels();
+ /* Detect whether this layer contains a full set of channels and set up the offsets accordingly. */
+ bool detect_denoising_channels();
- /* Map the channels of a secondary frame to the channels that are required for processing,
- * fill neighbor_input_to_image_channel if all are present or return false if a channel are missing. */
- bool match_channels(int neighbor,
- const std::vector<string> &channelnames,
- const std::vector<string> &neighbor_channelnames);
+ /* Map the channels of a secondary frame to the channels that are required for processing,
+ * fill neighbor_input_to_image_channel if all are present or return false if a channel are missing. */
+ bool match_channels(int neighbor,
+ const std::vector<string> &channelnames,
+ const std::vector<string> &neighbor_channelnames);
};
/* Denoise Image Data */
class DenoiseImage {
-public:
- DenoiseImage();
- ~DenoiseImage();
+ public:
+ DenoiseImage();
+ ~DenoiseImage();
- /* Dimensions */
- int width, height, num_channels;
+ /* Dimensions */
+ int width, height, num_channels;
- /* Samples */
- int samples;
+ /* Samples */
+ int samples;
- /* Pixel buffer with interleaved channels. */
- array<float> pixels;
+ /* Pixel buffer with interleaved channels. */
+ array<float> pixels;
- /* Image file handles */
- ImageSpec in_spec;
- vector<unique_ptr<ImageInput>> in_neighbors;
+ /* Image file handles */
+ ImageSpec in_spec;
+ vector<unique_ptr<ImageInput>> in_neighbors;
- /* Render layers */
- vector<DenoiseImageLayer> layers;
+ /* Render layers */
+ vector<DenoiseImageLayer> layers;
- void free();
+ void free();
- /* Open the input image, parse its channels, open the output image and allocate the output buffer. */
- bool load(const string& in_filepath, string& error);
+ /* Open the input image, parse its channels, open the output image and allocate the output buffer. */
+ bool load(const string &in_filepath, string &error);
- /* Load neighboring frames. */
- bool load_neighbors(const vector<string>& filepaths, const vector<int>& frames, string& error);
+ /* Load neighboring frames. */
+ bool load_neighbors(const vector<string> &filepaths, const vector<int> &frames, string &error);
- /* Load subset of pixels from file buffer into input buffer, as needed for denoising
- * on the device. Channels are reshuffled following the provided mapping. */
- void read_pixels(const DenoiseImageLayer& layer, float *input_pixels);
- bool read_neighbor_pixels(int neighbor, const DenoiseImageLayer& layer, float *input_pixels);
+ /* Load subset of pixels from file buffer into input buffer, as needed for denoising
+ * on the device. Channels are reshuffled following the provided mapping. */
+ void read_pixels(const DenoiseImageLayer &layer, float *input_pixels);
+ bool read_neighbor_pixels(int neighbor, const DenoiseImageLayer &layer, float *input_pixels);
- bool save_output(const string& out_filepath, string& error);
+ bool save_output(const string &out_filepath, string &error);
-protected:
- /* Parse input file channels, separate them into DenoiseImageLayers, detect DenoiseImageLayers with full channel sets,
- * fill layers and set up the output channels and passthrough map. */
- bool parse_channels(const ImageSpec &in_spec, string& error);
+ protected:
+ /* Parse input file channels, separate them into DenoiseImageLayers, detect DenoiseImageLayers with full channel sets,
+ * fill layers and set up the output channels and passthrough map. */
+ bool parse_channels(const ImageSpec &in_spec, string &error);
- void close_input();
+ void close_input();
};
/* Denoise Task */
class DenoiseTask {
-public:
- DenoiseTask(Device *device, Denoiser *denoiser, int frame, const vector<int>& neighbor_frames);
- ~DenoiseTask();
-
- /* Task stages */
- bool load();
- bool exec();
- bool save();
- void free();
-
- string error;
-
-protected:
- /* Denoiser parameters and device */
- Denoiser *denoiser;
- Device *device;
-
- /* Frame number to be denoised */
- int frame;
- vector<int> neighbor_frames;
-
- /* Image file data */
- DenoiseImage image;
- int current_layer;
-
- /* Device input buffer */
- device_vector<float> input_pixels;
-
- /* Tiles */
- thread_mutex tiles_mutex;
- list<RenderTile> tiles;
- int num_tiles;
-
- thread_mutex output_mutex;
- map<int, device_vector<float>*> output_pixels;
-
- /* Task handling */
- bool load_input_pixels(int layer);
- void create_task(DeviceTask& task);
-
- /* Device task callbacks */
- bool acquire_tile(Device *device, Device *tile_device, RenderTile &tile);
- void map_neighboring_tiles(RenderTile *tiles, Device *tile_device);
- void unmap_neighboring_tiles(RenderTile *tiles);
- void release_tile();
- bool get_cancel();
+ public:
+ DenoiseTask(Device *device, Denoiser *denoiser, int frame, const vector<int> &neighbor_frames);
+ ~DenoiseTask();
+
+ /* Task stages */
+ bool load();
+ bool exec();
+ bool save();
+ void free();
+
+ string error;
+
+ protected:
+ /* Denoiser parameters and device */
+ Denoiser *denoiser;
+ Device *device;
+
+ /* Frame number to be denoised */
+ int frame;
+ vector<int> neighbor_frames;
+
+ /* Image file data */
+ DenoiseImage image;
+ int current_layer;
+
+ /* Device input buffer */
+ device_vector<float> input_pixels;
+
+ /* Tiles */
+ thread_mutex tiles_mutex;
+ list<RenderTile> tiles;
+ int num_tiles;
+
+ thread_mutex output_mutex;
+ map<int, device_vector<float> *> output_pixels;
+
+ /* Task handling */
+ bool load_input_pixels(int layer);
+ void create_task(DeviceTask &task);
+
+ /* Device task callbacks */
+ bool acquire_tile(Device *device, Device *tile_device, RenderTile &tile);
+ void map_neighboring_tiles(RenderTile *tiles, Device *tile_device);
+ void unmap_neighboring_tiles(RenderTile *tiles);
+ void release_tile();
+ bool get_cancel();
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 1d1668a20d1..d6c44b66117 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -31,277 +31,275 @@ CCL_NAMESPACE_BEGIN
/* Pass */
-static bool compare_pass_order(const Pass& a, const Pass& b)
+static bool compare_pass_order(const Pass &a, const Pass &b)
{
- if(a.components == b.components)
- return (a.type < b.type);
- return (a.components > b.components);
+ if (a.components == b.components)
+ return (a.type < b.type);
+ return (a.components > b.components);
}
-void Pass::add(PassType type, vector<Pass>& passes, const char *name)
+void Pass::add(PassType type, vector<Pass> &passes, const char *name)
{
- for(size_t i = 0; i < passes.size(); i++) {
- if(passes[i].type == type &&
- (name ? (passes[i].name == name) : passes[i].name.empty())) {
- return;
- }
- }
-
- Pass pass;
-
- pass.type = type;
- pass.filter = true;
- pass.exposure = false;
- pass.divide_type = PASS_NONE;
- if(name) {
- pass.name = name;
- }
-
- switch(type) {
- case PASS_NONE:
- pass.components = 0;
- break;
- case PASS_COMBINED:
- pass.components = 4;
- pass.exposure = true;
- break;
- case PASS_DEPTH:
- pass.components = 1;
- pass.filter = false;
- break;
- case PASS_MIST:
- pass.components = 1;
- break;
- case PASS_NORMAL:
- pass.components = 4;
- break;
- case PASS_UV:
- pass.components = 4;
- break;
- case PASS_MOTION:
- pass.components = 4;
- pass.divide_type = PASS_MOTION_WEIGHT;
- break;
- case PASS_MOTION_WEIGHT:
- pass.components = 1;
- break;
- case PASS_OBJECT_ID:
- case PASS_MATERIAL_ID:
- pass.components = 1;
- pass.filter = false;
- break;
-
- case PASS_EMISSION:
- case PASS_BACKGROUND:
- pass.components = 4;
- pass.exposure = true;
- break;
- case PASS_AO:
- pass.components = 4;
- break;
- case PASS_SHADOW:
- pass.components = 4;
- pass.exposure = false;
- break;
- case PASS_LIGHT:
- /* This isn't a real pass, used by baking to see whether
- * light data is needed or not.
- *
- * Set components to 0 so pass sort below happens in a
- * determined way.
- */
- pass.components = 0;
- break;
+ for (size_t i = 0; i < passes.size(); i++) {
+ if (passes[i].type == type && (name ? (passes[i].name == name) : passes[i].name.empty())) {
+ return;
+ }
+ }
+
+ Pass pass;
+
+ pass.type = type;
+ pass.filter = true;
+ pass.exposure = false;
+ pass.divide_type = PASS_NONE;
+ if (name) {
+ pass.name = name;
+ }
+
+ switch (type) {
+ case PASS_NONE:
+ pass.components = 0;
+ break;
+ case PASS_COMBINED:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_DEPTH:
+ pass.components = 1;
+ pass.filter = false;
+ break;
+ case PASS_MIST:
+ pass.components = 1;
+ break;
+ case PASS_NORMAL:
+ pass.components = 4;
+ break;
+ case PASS_UV:
+ pass.components = 4;
+ break;
+ case PASS_MOTION:
+ pass.components = 4;
+ pass.divide_type = PASS_MOTION_WEIGHT;
+ break;
+ case PASS_MOTION_WEIGHT:
+ pass.components = 1;
+ break;
+ case PASS_OBJECT_ID:
+ case PASS_MATERIAL_ID:
+ pass.components = 1;
+ pass.filter = false;
+ break;
+
+ case PASS_EMISSION:
+ case PASS_BACKGROUND:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_AO:
+ pass.components = 4;
+ break;
+ case PASS_SHADOW:
+ pass.components = 4;
+ pass.exposure = false;
+ break;
+ case PASS_LIGHT:
+ /* This isn't a real pass, used by baking to see whether
+ * light data is needed or not.
+ *
+ * Set components to 0 so pass sort below happens in a
+ * determined way.
+ */
+ pass.components = 0;
+ break;
#ifdef WITH_CYCLES_DEBUG
- case PASS_BVH_TRAVERSED_NODES:
- case PASS_BVH_TRAVERSED_INSTANCES:
- case PASS_BVH_INTERSECTIONS:
- case PASS_RAY_BOUNCES:
- pass.components = 1;
- pass.exposure = false;
- break;
+ case PASS_BVH_TRAVERSED_NODES:
+ case PASS_BVH_TRAVERSED_INSTANCES:
+ case PASS_BVH_INTERSECTIONS:
+ case PASS_RAY_BOUNCES:
+ pass.components = 1;
+ pass.exposure = false;
+ break;
#endif
- case PASS_RENDER_TIME:
- /* This pass is handled entirely on the host side. */
- pass.components = 0;
- break;
-
- case PASS_DIFFUSE_COLOR:
- case PASS_GLOSSY_COLOR:
- case PASS_TRANSMISSION_COLOR:
- case PASS_SUBSURFACE_COLOR:
- pass.components = 4;
- break;
- case PASS_DIFFUSE_DIRECT:
- case PASS_DIFFUSE_INDIRECT:
- pass.components = 4;
- pass.exposure = true;
- pass.divide_type = PASS_DIFFUSE_COLOR;
- break;
- case PASS_GLOSSY_DIRECT:
- case PASS_GLOSSY_INDIRECT:
- pass.components = 4;
- pass.exposure = true;
- pass.divide_type = PASS_GLOSSY_COLOR;
- break;
- case PASS_TRANSMISSION_DIRECT:
- case PASS_TRANSMISSION_INDIRECT:
- pass.components = 4;
- pass.exposure = true;
- pass.divide_type = PASS_TRANSMISSION_COLOR;
- break;
- case PASS_SUBSURFACE_DIRECT:
- case PASS_SUBSURFACE_INDIRECT:
- pass.components = 4;
- pass.exposure = true;
- pass.divide_type = PASS_SUBSURFACE_COLOR;
- break;
- case PASS_VOLUME_DIRECT:
- case PASS_VOLUME_INDIRECT:
- pass.components = 4;
- pass.exposure = true;
- break;
- case PASS_CRYPTOMATTE:
- pass.components = 4;
- break;
- default:
- assert(false);
- break;
- }
-
- passes.push_back(pass);
-
- /* order from by components, to ensure alignment so passes with size 4
- * come first and then passes with size 1 */
- sort(&passes[0], &passes[0] + passes.size(), compare_pass_order);
-
- if(pass.divide_type != PASS_NONE)
- Pass::add(pass.divide_type, passes);
+ case PASS_RENDER_TIME:
+ /* This pass is handled entirely on the host side. */
+ pass.components = 0;
+ break;
+
+ case PASS_DIFFUSE_COLOR:
+ case PASS_GLOSSY_COLOR:
+ case PASS_TRANSMISSION_COLOR:
+ case PASS_SUBSURFACE_COLOR:
+ pass.components = 4;
+ break;
+ case PASS_DIFFUSE_DIRECT:
+ case PASS_DIFFUSE_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ pass.divide_type = PASS_DIFFUSE_COLOR;
+ break;
+ case PASS_GLOSSY_DIRECT:
+ case PASS_GLOSSY_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ pass.divide_type = PASS_GLOSSY_COLOR;
+ break;
+ case PASS_TRANSMISSION_DIRECT:
+ case PASS_TRANSMISSION_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ pass.divide_type = PASS_TRANSMISSION_COLOR;
+ break;
+ case PASS_SUBSURFACE_DIRECT:
+ case PASS_SUBSURFACE_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ pass.divide_type = PASS_SUBSURFACE_COLOR;
+ break;
+ case PASS_VOLUME_DIRECT:
+ case PASS_VOLUME_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_CRYPTOMATTE:
+ pass.components = 4;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+
+ passes.push_back(pass);
+
+ /* order from by components, to ensure alignment so passes with size 4
+ * come first and then passes with size 1 */
+ sort(&passes[0], &passes[0] + passes.size(), compare_pass_order);
+
+ if (pass.divide_type != PASS_NONE)
+ Pass::add(pass.divide_type, passes);
}
-bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
+bool Pass::equals(const vector<Pass> &A, const vector<Pass> &B)
{
- if(A.size() != B.size())
- return false;
+ if (A.size() != B.size())
+ return false;
- for(int i = 0; i < A.size(); i++)
- if(A[i].type != B[i].type || A[i].name != B[i].name)
- return false;
+ for (int i = 0; i < A.size(); i++)
+ if (A[i].type != B[i].type || A[i].name != B[i].name)
+ return false;
- return true;
+ return true;
}
-bool Pass::contains(const vector<Pass>& passes, PassType type)
+bool Pass::contains(const vector<Pass> &passes, PassType type)
{
- for(size_t i = 0; i < passes.size(); i++)
- if(passes[i].type == type)
- return true;
+ for (size_t i = 0; i < passes.size(); i++)
+ if (passes[i].type == type)
+ return true;
- return false;
+ return false;
}
/* Pixel Filter */
static float filter_func_box(float /*v*/, float /*width*/)
{
- return 1.0f;
+ return 1.0f;
}
static float filter_func_gaussian(float v, float width)
{
- v *= 6.0f/width;
- return expf(-2.0f*v*v);
+ v *= 6.0f / width;
+ return expf(-2.0f * v * v);
}
static float filter_func_blackman_harris(float v, float width)
{
- v = M_2PI_F * (v / width + 0.5f);
- return 0.35875f - 0.48829f*cosf(v) + 0.14128f*cosf(2.0f*v) - 0.01168f*cosf(3.0f*v);
+ v = M_2PI_F * (v / width + 0.5f);
+ return 0.35875f - 0.48829f * cosf(v) + 0.14128f * cosf(2.0f * v) - 0.01168f * cosf(3.0f * v);
}
static vector<float> filter_table(FilterType type, float width)
{
- vector<float> filter_table(FILTER_TABLE_SIZE);
- float (*filter_func)(float, float) = NULL;
-
- switch(type) {
- case FILTER_BOX:
- filter_func = filter_func_box;
- break;
- case FILTER_GAUSSIAN:
- filter_func = filter_func_gaussian;
- width *= 3.0f;
- break;
- case FILTER_BLACKMAN_HARRIS:
- filter_func = filter_func_blackman_harris;
- width *= 2.0f;
- break;
- default:
- assert(0);
- }
-
- /* Create importance sampling table. */
-
- /* TODO(sergey): With the even filter table size resolution we can not
- * really make it nice symmetric importance map without sampling full range
- * (meaning, we would need to sample full filter range and not use the
- * make_symmetric argument).
- *
- * Current code matches exactly initial filter table code, but we should
- * consider either making FILTER_TABLE_SIZE odd value or sample full filter.
- */
-
- util_cdf_inverted(FILTER_TABLE_SIZE,
- 0.0f,
- width * 0.5f,
- function_bind(filter_func, _1, width),
- true,
- filter_table);
-
- return filter_table;
+ vector<float> filter_table(FILTER_TABLE_SIZE);
+ float (*filter_func)(float, float) = NULL;
+
+ switch (type) {
+ case FILTER_BOX:
+ filter_func = filter_func_box;
+ break;
+ case FILTER_GAUSSIAN:
+ filter_func = filter_func_gaussian;
+ width *= 3.0f;
+ break;
+ case FILTER_BLACKMAN_HARRIS:
+ filter_func = filter_func_blackman_harris;
+ width *= 2.0f;
+ break;
+ default:
+ assert(0);
+ }
+
+ /* Create importance sampling table. */
+
+ /* TODO(sergey): With the even filter table size resolution we can not
+ * really make it nice symmetric importance map without sampling full range
+ * (meaning, we would need to sample full filter range and not use the
+ * make_symmetric argument).
+ *
+ * Current code matches exactly initial filter table code, but we should
+ * consider either making FILTER_TABLE_SIZE odd value or sample full filter.
+ */
+
+ util_cdf_inverted(FILTER_TABLE_SIZE,
+ 0.0f,
+ width * 0.5f,
+ function_bind(filter_func, _1, width),
+ true,
+ filter_table);
+
+ return filter_table;
}
/* Film */
NODE_DEFINE(Film)
{
- NodeType* type = NodeType::add("film", create);
+ NodeType *type = NodeType::add("film", create);
- SOCKET_FLOAT(exposure, "Exposure", 0.8f);
- SOCKET_FLOAT(pass_alpha_threshold, "Pass Alpha Threshold", 0.5f);
+ SOCKET_FLOAT(exposure, "Exposure", 0.8f);
+ SOCKET_FLOAT(pass_alpha_threshold, "Pass Alpha Threshold", 0.5f);
- static NodeEnum filter_enum;
- filter_enum.insert("box", FILTER_BOX);
- filter_enum.insert("gaussian", FILTER_GAUSSIAN);
- filter_enum.insert("blackman_harris", FILTER_BLACKMAN_HARRIS);
+ static NodeEnum filter_enum;
+ filter_enum.insert("box", FILTER_BOX);
+ filter_enum.insert("gaussian", FILTER_GAUSSIAN);
+ filter_enum.insert("blackman_harris", FILTER_BLACKMAN_HARRIS);
- SOCKET_ENUM(filter_type, "Filter Type", filter_enum, FILTER_BOX);
- SOCKET_FLOAT(filter_width, "Filter Width", 1.0f);
+ SOCKET_ENUM(filter_type, "Filter Type", filter_enum, FILTER_BOX);
+ SOCKET_FLOAT(filter_width, "Filter Width", 1.0f);
- SOCKET_FLOAT(mist_start, "Mist Start", 0.0f);
- SOCKET_FLOAT(mist_depth, "Mist Depth", 100.0f);
- SOCKET_FLOAT(mist_falloff, "Mist Falloff", 1.0f);
+ SOCKET_FLOAT(mist_start, "Mist Start", 0.0f);
+ SOCKET_FLOAT(mist_depth, "Mist Depth", 100.0f);
+ SOCKET_FLOAT(mist_falloff, "Mist Falloff", 1.0f);
- SOCKET_BOOLEAN(use_sample_clamp, "Use Sample Clamp", false);
+ SOCKET_BOOLEAN(use_sample_clamp, "Use Sample Clamp", false);
- SOCKET_BOOLEAN(denoising_data_pass, "Generate Denoising Data Pass", false);
- SOCKET_BOOLEAN(denoising_clean_pass, "Generate Denoising Clean Pass", false);
- SOCKET_BOOLEAN(denoising_prefiltered_pass, "Generate Denoising Prefiltered Pass", false);
- SOCKET_INT(denoising_flags, "Denoising Flags", 0);
+ SOCKET_BOOLEAN(denoising_data_pass, "Generate Denoising Data Pass", false);
+ SOCKET_BOOLEAN(denoising_clean_pass, "Generate Denoising Clean Pass", false);
+ SOCKET_BOOLEAN(denoising_prefiltered_pass, "Generate Denoising Prefiltered Pass", false);
+ SOCKET_INT(denoising_flags, "Denoising Flags", 0);
- return type;
+ return type;
}
-Film::Film()
-: Node(node_type)
+Film::Film() : Node(node_type)
{
- Pass::add(PASS_COMBINED, passes);
+ Pass::add(PASS_COMBINED, passes);
- use_light_visibility = false;
- filter_table_offset = TABLE_OFFSET_INVALID;
- cryptomatte_passes = CRYPT_NONE;
+ use_light_visibility = false;
+ filter_table_offset = TABLE_OFFSET_INVALID;
+ cryptomatte_passes = CRYPT_NONE;
- need_update = true;
+ need_update = true;
}
Film::~Film()
@@ -310,233 +308,233 @@ Film::~Film()
void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
- if(!need_update)
- return;
-
- device_free(device, dscene, scene);
-
- KernelFilm *kfilm = &dscene->data.film;
-
- /* update __data */
- kfilm->exposure = exposure;
- kfilm->pass_flag = 0;
- kfilm->light_pass_flag = 0;
- kfilm->pass_stride = 0;
- kfilm->use_light_pass = use_light_visibility || use_sample_clamp;
-
- bool have_cryptomatte = false;
-
- for(size_t i = 0; i < passes.size(); i++) {
- Pass& pass = passes[i];
-
- if(pass.type == PASS_NONE) {
- continue;
- }
-
- /* Can't do motion pass if no motion vectors are available. */
- if (pass.type == PASS_MOTION || pass.type == PASS_MOTION_WEIGHT) {
- if (scene->need_motion() != Scene::MOTION_PASS) {
- kfilm->pass_stride += pass.components;
- continue;
- }
- }
-
- int pass_flag = (1 << (pass.type % 32));
- if(pass.type <= PASS_CATEGORY_MAIN_END) {
- kfilm->pass_flag |= pass_flag;
- }
- else {
- assert(pass.type <= PASS_CATEGORY_LIGHT_END);
- kfilm->use_light_pass = 1;
- kfilm->light_pass_flag |= pass_flag;
- }
-
- switch(pass.type) {
- case PASS_COMBINED:
- kfilm->pass_combined = kfilm->pass_stride;
- break;
- case PASS_DEPTH:
- kfilm->pass_depth = kfilm->pass_stride;
- break;
- case PASS_NORMAL:
- kfilm->pass_normal = kfilm->pass_stride;
- break;
- case PASS_UV:
- kfilm->pass_uv = kfilm->pass_stride;
- break;
- case PASS_MOTION:
- kfilm->pass_motion = kfilm->pass_stride;
- break;
- case PASS_MOTION_WEIGHT:
- kfilm->pass_motion_weight = kfilm->pass_stride;
- break;
- case PASS_OBJECT_ID:
- kfilm->pass_object_id = kfilm->pass_stride;
- break;
- case PASS_MATERIAL_ID:
- kfilm->pass_material_id = kfilm->pass_stride;
- break;
-
- case PASS_MIST:
- kfilm->pass_mist = kfilm->pass_stride;
- break;
- case PASS_EMISSION:
- kfilm->pass_emission = kfilm->pass_stride;
- break;
- case PASS_BACKGROUND:
- kfilm->pass_background = kfilm->pass_stride;
- break;
- case PASS_AO:
- kfilm->pass_ao = kfilm->pass_stride;
- break;
- case PASS_SHADOW:
- kfilm->pass_shadow = kfilm->pass_stride;
- break;
-
- case PASS_LIGHT:
- break;
-
- case PASS_DIFFUSE_COLOR:
- kfilm->pass_diffuse_color = kfilm->pass_stride;
- break;
- case PASS_GLOSSY_COLOR:
- kfilm->pass_glossy_color = kfilm->pass_stride;
- break;
- case PASS_TRANSMISSION_COLOR:
- kfilm->pass_transmission_color = kfilm->pass_stride;
- break;
- case PASS_SUBSURFACE_COLOR:
- kfilm->pass_subsurface_color = kfilm->pass_stride;
- break;
- case PASS_DIFFUSE_INDIRECT:
- kfilm->pass_diffuse_indirect = kfilm->pass_stride;
- break;
- case PASS_GLOSSY_INDIRECT:
- kfilm->pass_glossy_indirect = kfilm->pass_stride;
- break;
- case PASS_TRANSMISSION_INDIRECT:
- kfilm->pass_transmission_indirect = kfilm->pass_stride;
- break;
- case PASS_SUBSURFACE_INDIRECT:
- kfilm->pass_subsurface_indirect = kfilm->pass_stride;
- break;
- case PASS_VOLUME_INDIRECT:
- kfilm->pass_volume_indirect = kfilm->pass_stride;
- break;
- case PASS_DIFFUSE_DIRECT:
- kfilm->pass_diffuse_direct = kfilm->pass_stride;
- break;
- case PASS_GLOSSY_DIRECT:
- kfilm->pass_glossy_direct = kfilm->pass_stride;
- break;
- case PASS_TRANSMISSION_DIRECT:
- kfilm->pass_transmission_direct = kfilm->pass_stride;
- break;
- case PASS_SUBSURFACE_DIRECT:
- kfilm->pass_subsurface_direct = kfilm->pass_stride;
- break;
- case PASS_VOLUME_DIRECT:
- kfilm->pass_volume_direct = kfilm->pass_stride;
- break;
+ if (!need_update)
+ return;
+
+ device_free(device, dscene, scene);
+
+ KernelFilm *kfilm = &dscene->data.film;
+
+ /* update __data */
+ kfilm->exposure = exposure;
+ kfilm->pass_flag = 0;
+ kfilm->light_pass_flag = 0;
+ kfilm->pass_stride = 0;
+ kfilm->use_light_pass = use_light_visibility || use_sample_clamp;
+
+ bool have_cryptomatte = false;
+
+ for (size_t i = 0; i < passes.size(); i++) {
+ Pass &pass = passes[i];
+
+ if (pass.type == PASS_NONE) {
+ continue;
+ }
+
+ /* Can't do motion pass if no motion vectors are available. */
+ if (pass.type == PASS_MOTION || pass.type == PASS_MOTION_WEIGHT) {
+ if (scene->need_motion() != Scene::MOTION_PASS) {
+ kfilm->pass_stride += pass.components;
+ continue;
+ }
+ }
+
+ int pass_flag = (1 << (pass.type % 32));
+ if (pass.type <= PASS_CATEGORY_MAIN_END) {
+ kfilm->pass_flag |= pass_flag;
+ }
+ else {
+ assert(pass.type <= PASS_CATEGORY_LIGHT_END);
+ kfilm->use_light_pass = 1;
+ kfilm->light_pass_flag |= pass_flag;
+ }
+
+ switch (pass.type) {
+ case PASS_COMBINED:
+ kfilm->pass_combined = kfilm->pass_stride;
+ break;
+ case PASS_DEPTH:
+ kfilm->pass_depth = kfilm->pass_stride;
+ break;
+ case PASS_NORMAL:
+ kfilm->pass_normal = kfilm->pass_stride;
+ break;
+ case PASS_UV:
+ kfilm->pass_uv = kfilm->pass_stride;
+ break;
+ case PASS_MOTION:
+ kfilm->pass_motion = kfilm->pass_stride;
+ break;
+ case PASS_MOTION_WEIGHT:
+ kfilm->pass_motion_weight = kfilm->pass_stride;
+ break;
+ case PASS_OBJECT_ID:
+ kfilm->pass_object_id = kfilm->pass_stride;
+ break;
+ case PASS_MATERIAL_ID:
+ kfilm->pass_material_id = kfilm->pass_stride;
+ break;
+
+ case PASS_MIST:
+ kfilm->pass_mist = kfilm->pass_stride;
+ break;
+ case PASS_EMISSION:
+ kfilm->pass_emission = kfilm->pass_stride;
+ break;
+ case PASS_BACKGROUND:
+ kfilm->pass_background = kfilm->pass_stride;
+ break;
+ case PASS_AO:
+ kfilm->pass_ao = kfilm->pass_stride;
+ break;
+ case PASS_SHADOW:
+ kfilm->pass_shadow = kfilm->pass_stride;
+ break;
+
+ case PASS_LIGHT:
+ break;
+
+ case PASS_DIFFUSE_COLOR:
+ kfilm->pass_diffuse_color = kfilm->pass_stride;
+ break;
+ case PASS_GLOSSY_COLOR:
+ kfilm->pass_glossy_color = kfilm->pass_stride;
+ break;
+ case PASS_TRANSMISSION_COLOR:
+ kfilm->pass_transmission_color = kfilm->pass_stride;
+ break;
+ case PASS_SUBSURFACE_COLOR:
+ kfilm->pass_subsurface_color = kfilm->pass_stride;
+ break;
+ case PASS_DIFFUSE_INDIRECT:
+ kfilm->pass_diffuse_indirect = kfilm->pass_stride;
+ break;
+ case PASS_GLOSSY_INDIRECT:
+ kfilm->pass_glossy_indirect = kfilm->pass_stride;
+ break;
+ case PASS_TRANSMISSION_INDIRECT:
+ kfilm->pass_transmission_indirect = kfilm->pass_stride;
+ break;
+ case PASS_SUBSURFACE_INDIRECT:
+ kfilm->pass_subsurface_indirect = kfilm->pass_stride;
+ break;
+ case PASS_VOLUME_INDIRECT:
+ kfilm->pass_volume_indirect = kfilm->pass_stride;
+ break;
+ case PASS_DIFFUSE_DIRECT:
+ kfilm->pass_diffuse_direct = kfilm->pass_stride;
+ break;
+ case PASS_GLOSSY_DIRECT:
+ kfilm->pass_glossy_direct = kfilm->pass_stride;
+ break;
+ case PASS_TRANSMISSION_DIRECT:
+ kfilm->pass_transmission_direct = kfilm->pass_stride;
+ break;
+ case PASS_SUBSURFACE_DIRECT:
+ kfilm->pass_subsurface_direct = kfilm->pass_stride;
+ break;
+ case PASS_VOLUME_DIRECT:
+ kfilm->pass_volume_direct = kfilm->pass_stride;
+ break;
#ifdef WITH_CYCLES_DEBUG
- case PASS_BVH_TRAVERSED_NODES:
- kfilm->pass_bvh_traversed_nodes = kfilm->pass_stride;
- break;
- case PASS_BVH_TRAVERSED_INSTANCES:
- kfilm->pass_bvh_traversed_instances = kfilm->pass_stride;
- break;
- case PASS_BVH_INTERSECTIONS:
- kfilm->pass_bvh_intersections = kfilm->pass_stride;
- break;
- case PASS_RAY_BOUNCES:
- kfilm->pass_ray_bounces = kfilm->pass_stride;
- break;
+ case PASS_BVH_TRAVERSED_NODES:
+ kfilm->pass_bvh_traversed_nodes = kfilm->pass_stride;
+ break;
+ case PASS_BVH_TRAVERSED_INSTANCES:
+ kfilm->pass_bvh_traversed_instances = kfilm->pass_stride;
+ break;
+ case PASS_BVH_INTERSECTIONS:
+ kfilm->pass_bvh_intersections = kfilm->pass_stride;
+ break;
+ case PASS_RAY_BOUNCES:
+ kfilm->pass_ray_bounces = kfilm->pass_stride;
+ break;
#endif
- case PASS_RENDER_TIME:
- break;
- case PASS_CRYPTOMATTE:
- kfilm->pass_cryptomatte = have_cryptomatte ? min(kfilm->pass_cryptomatte, kfilm->pass_stride) : kfilm->pass_stride;
- have_cryptomatte = true;
- break;
- default:
- assert(false);
- break;
- }
-
- kfilm->pass_stride += pass.components;
- }
-
- kfilm->pass_denoising_data = 0;
- kfilm->pass_denoising_clean = 0;
- kfilm->denoising_flags = 0;
- if(denoising_data_pass) {
- kfilm->pass_denoising_data = kfilm->pass_stride;
- kfilm->pass_stride += DENOISING_PASS_SIZE_BASE;
- kfilm->denoising_flags = denoising_flags;
- if(denoising_clean_pass) {
- kfilm->pass_denoising_clean = kfilm->pass_stride;
- kfilm->pass_stride += DENOISING_PASS_SIZE_CLEAN;
- kfilm->use_light_pass = 1;
- }
- if(denoising_prefiltered_pass) {
- kfilm->pass_stride += DENOISING_PASS_SIZE_PREFILTERED;
- }
- }
-
- kfilm->pass_stride = align_up(kfilm->pass_stride, 4);
- kfilm->pass_alpha_threshold = pass_alpha_threshold;
-
- /* update filter table */
- vector<float> table = filter_table(filter_type, filter_width);
- scene->lookup_tables->remove_table(&filter_table_offset);
- filter_table_offset = scene->lookup_tables->add_table(dscene, table);
- kfilm->filter_table_offset = (int)filter_table_offset;
-
- /* mist pass parameters */
- kfilm->mist_start = mist_start;
- kfilm->mist_inv_depth = (mist_depth > 0.0f)? 1.0f/mist_depth: 0.0f;
- kfilm->mist_falloff = mist_falloff;
-
- kfilm->cryptomatte_passes = cryptomatte_passes;
- kfilm->cryptomatte_depth = cryptomatte_depth;
-
- pass_stride = kfilm->pass_stride;
- denoising_data_offset = kfilm->pass_denoising_data;
- denoising_clean_offset = kfilm->pass_denoising_clean;
-
- need_update = false;
+ case PASS_RENDER_TIME:
+ break;
+ case PASS_CRYPTOMATTE:
+ kfilm->pass_cryptomatte = have_cryptomatte ?
+ min(kfilm->pass_cryptomatte, kfilm->pass_stride) :
+ kfilm->pass_stride;
+ have_cryptomatte = true;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+
+ kfilm->pass_stride += pass.components;
+ }
+
+ kfilm->pass_denoising_data = 0;
+ kfilm->pass_denoising_clean = 0;
+ kfilm->denoising_flags = 0;
+ if (denoising_data_pass) {
+ kfilm->pass_denoising_data = kfilm->pass_stride;
+ kfilm->pass_stride += DENOISING_PASS_SIZE_BASE;
+ kfilm->denoising_flags = denoising_flags;
+ if (denoising_clean_pass) {
+ kfilm->pass_denoising_clean = kfilm->pass_stride;
+ kfilm->pass_stride += DENOISING_PASS_SIZE_CLEAN;
+ kfilm->use_light_pass = 1;
+ }
+ if (denoising_prefiltered_pass) {
+ kfilm->pass_stride += DENOISING_PASS_SIZE_PREFILTERED;
+ }
+ }
+
+ kfilm->pass_stride = align_up(kfilm->pass_stride, 4);
+ kfilm->pass_alpha_threshold = pass_alpha_threshold;
+
+ /* update filter table */
+ vector<float> table = filter_table(filter_type, filter_width);
+ scene->lookup_tables->remove_table(&filter_table_offset);
+ filter_table_offset = scene->lookup_tables->add_table(dscene, table);
+ kfilm->filter_table_offset = (int)filter_table_offset;
+
+ /* mist pass parameters */
+ kfilm->mist_start = mist_start;
+ kfilm->mist_inv_depth = (mist_depth > 0.0f) ? 1.0f / mist_depth : 0.0f;
+ kfilm->mist_falloff = mist_falloff;
+
+ kfilm->cryptomatte_passes = cryptomatte_passes;
+ kfilm->cryptomatte_depth = cryptomatte_depth;
+
+ pass_stride = kfilm->pass_stride;
+ denoising_data_offset = kfilm->pass_denoising_data;
+ denoising_clean_offset = kfilm->pass_denoising_clean;
+
+ need_update = false;
}
-void Film::device_free(Device * /*device*/,
- DeviceScene * /*dscene*/,
- Scene *scene)
+void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *scene)
{
- scene->lookup_tables->remove_table(&filter_table_offset);
+ scene->lookup_tables->remove_table(&filter_table_offset);
}
-bool Film::modified(const Film& film)
+bool Film::modified(const Film &film)
{
- return !Node::equals(film) || !Pass::equals(passes, film.passes);
+ return !Node::equals(film) || !Pass::equals(passes, film.passes);
}
-void Film::tag_passes_update(Scene *scene, const vector<Pass>& passes_)
+void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_)
{
- if(Pass::contains(passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) {
- scene->mesh_manager->tag_update(scene);
+ if (Pass::contains(passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) {
+ scene->mesh_manager->tag_update(scene);
- foreach(Shader *shader, scene->shaders)
- shader->need_update_mesh = true;
- }
- else if(Pass::contains(passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION))
- scene->mesh_manager->tag_update(scene);
+ foreach (Shader *shader, scene->shaders)
+ shader->need_update_mesh = true;
+ }
+ else if (Pass::contains(passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION))
+ scene->mesh_manager->tag_update(scene);
- passes = passes_;
+ passes = passes_;
}
void Film::tag_update(Scene * /*scene*/)
{
- need_update = true;
+ need_update = true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index 8330a4cf413..1cfa7c3b77d 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -31,69 +31,69 @@ class DeviceScene;
class Scene;
typedef enum FilterType {
- FILTER_BOX,
- FILTER_GAUSSIAN,
- FILTER_BLACKMAN_HARRIS,
+ FILTER_BOX,
+ FILTER_GAUSSIAN,
+ FILTER_BLACKMAN_HARRIS,
- FILTER_NUM_TYPES,
+ FILTER_NUM_TYPES,
} FilterType;
class Pass {
-public:
- PassType type;
- int components;
- bool filter;
- bool exposure;
- PassType divide_type;
- string name;
-
- static void add(PassType type, vector<Pass>& passes, const char* name = NULL);
- static bool equals(const vector<Pass>& A, const vector<Pass>& B);
- static bool contains(const vector<Pass>& passes, PassType);
+ public:
+ PassType type;
+ int components;
+ bool filter;
+ bool exposure;
+ PassType divide_type;
+ string name;
+
+ static void add(PassType type, vector<Pass> &passes, const char *name = NULL);
+ static bool equals(const vector<Pass> &A, const vector<Pass> &B);
+ static bool contains(const vector<Pass> &passes, PassType);
};
class Film : public Node {
-public:
- NODE_DECLARE
+ public:
+ NODE_DECLARE
- float exposure;
- vector<Pass> passes;
- bool denoising_data_pass;
- bool denoising_clean_pass;
- bool denoising_prefiltered_pass;
- int denoising_flags;
- float pass_alpha_threshold;
+ float exposure;
+ vector<Pass> passes;
+ bool denoising_data_pass;
+ bool denoising_clean_pass;
+ bool denoising_prefiltered_pass;
+ int denoising_flags;
+ float pass_alpha_threshold;
- int pass_stride;
- int denoising_data_offset;
- int denoising_clean_offset;
+ int pass_stride;
+ int denoising_data_offset;
+ int denoising_clean_offset;
- FilterType filter_type;
- float filter_width;
- size_t filter_table_offset;
+ FilterType filter_type;
+ float filter_width;
+ size_t filter_table_offset;
- float mist_start;
- float mist_depth;
- float mist_falloff;
+ float mist_start;
+ float mist_depth;
+ float mist_falloff;
- bool use_light_visibility;
- bool use_sample_clamp;
- CryptomatteType cryptomatte_passes;
- int cryptomatte_depth;
+ bool use_light_visibility;
+ bool use_sample_clamp;
+ CryptomatteType cryptomatte_passes;
+ int cryptomatte_depth;
- bool need_update;
+ bool need_update;
- Film();
- ~Film();
+ Film();
+ ~Film();
- void device_update(Device *device, DeviceScene *dscene, Scene *scene);
- void device_free(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_free(Device *device, DeviceScene *dscene, Scene *scene);
- bool modified(const Film& film);
- void tag_passes_update(Scene *scene, const vector<Pass>& passes_);
- void tag_update(Scene *scene);
+ bool modified(const Film &film);
+ void tag_passes_update(Scene *scene, const vector<Pass> &passes_);
+ void tag_update(Scene *scene);
};
CCL_NAMESPACE_END
-#endif /* __FILM_H__ */
+#endif /* __FILM_H__ */
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index eea1bed58dc..c284c64b5bf 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -33,388 +33,385 @@ namespace {
bool check_node_inputs_has_links(const ShaderNode *node)
{
- foreach(const ShaderInput *in, node->inputs) {
- if(in->link) {
- return true;
- }
- }
- return false;
+ foreach (const ShaderInput *in, node->inputs) {
+ if (in->link) {
+ return true;
+ }
+ }
+ return false;
}
-bool check_node_inputs_traversed(const ShaderNode *node,
- const ShaderNodeSet& done)
+bool check_node_inputs_traversed(const ShaderNode *node, const ShaderNodeSet &done)
{
- foreach(const ShaderInput *in, node->inputs) {
- if(in->link) {
- if(done.find(in->link->parent) == done.end()) {
- return false;
- }
- }
- }
- return true;
+ foreach (const ShaderInput *in, node->inputs) {
+ if (in->link) {
+ if (done.find(in->link->parent) == done.end()) {
+ return false;
+ }
+ }
+ }
+ return true;
}
-} /* namespace */
+} /* namespace */
/* Node */
-ShaderNode::ShaderNode(const NodeType *type)
-: Node(type)
+ShaderNode::ShaderNode(const NodeType *type) : Node(type)
{
- name = type->name;
- id = -1;
- bump = SHADER_BUMP_NONE;
- special_type = SHADER_SPECIAL_TYPE_NONE;
+ name = type->name;
+ id = -1;
+ bump = SHADER_BUMP_NONE;
+ special_type = SHADER_SPECIAL_TYPE_NONE;
- create_inputs_outputs(type);
+ create_inputs_outputs(type);
}
ShaderNode::~ShaderNode()
{
- foreach(ShaderInput *socket, inputs)
- delete socket;
+ foreach (ShaderInput *socket, inputs)
+ delete socket;
- foreach(ShaderOutput *socket, outputs)
- delete socket;
+ foreach (ShaderOutput *socket, outputs)
+ delete socket;
}
void ShaderNode::create_inputs_outputs(const NodeType *type)
{
- foreach(const SocketType& socket, type->inputs) {
- if(socket.flags & SocketType::LINKABLE) {
- inputs.push_back(new ShaderInput(socket, this));
- }
- }
-
- foreach(const SocketType& socket, type->outputs) {
- outputs.push_back(new ShaderOutput(socket, this));
- }
+ foreach (const SocketType &socket, type->inputs) {
+ if (socket.flags & SocketType::LINKABLE) {
+ inputs.push_back(new ShaderInput(socket, this));
+ }
+ }
+
+ foreach (const SocketType &socket, type->outputs) {
+ outputs.push_back(new ShaderOutput(socket, this));
+ }
}
ShaderInput *ShaderNode::input(const char *name)
{
- foreach(ShaderInput *socket, inputs) {
- if(socket->name() == name)
- return socket;
- }
+ foreach (ShaderInput *socket, inputs) {
+ if (socket->name() == name)
+ return socket;
+ }
- return NULL;
+ return NULL;
}
ShaderOutput *ShaderNode::output(const char *name)
{
- foreach(ShaderOutput *socket, outputs)
- if(socket->name() == name)
- return socket;
+ foreach (ShaderOutput *socket, outputs)
+ if (socket->name() == name)
+ return socket;
- return NULL;
+ return NULL;
}
ShaderInput *ShaderNode::input(ustring name)
{
- foreach(ShaderInput *socket, inputs) {
- if(socket->name() == name)
- return socket;
- }
+ foreach (ShaderInput *socket, inputs) {
+ if (socket->name() == name)
+ return socket;
+ }
- return NULL;
+ return NULL;
}
ShaderOutput *ShaderNode::output(ustring name)
{
- foreach(ShaderOutput *socket, outputs)
- if(socket->name() == name)
- return socket;
+ foreach (ShaderOutput *socket, outputs)
+ if (socket->name() == name)
+ return socket;
- return NULL;
+ return NULL;
}
void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- foreach(ShaderInput *input, inputs) {
- if(!input->link) {
- if(input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
- if(shader->has_surface)
- attributes->add(ATTR_STD_GENERATED);
- if(shader->has_volume)
- attributes->add(ATTR_STD_GENERATED_TRANSFORM);
- }
- else if(input->flags() & SocketType::LINK_TEXTURE_UV) {
- if(shader->has_surface)
- attributes->add(ATTR_STD_UV);
- }
- }
- }
+ foreach (ShaderInput *input, inputs) {
+ if (!input->link) {
+ if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
+ if (shader->has_surface)
+ attributes->add(ATTR_STD_GENERATED);
+ if (shader->has_volume)
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ }
+ else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
+ if (shader->has_surface)
+ attributes->add(ATTR_STD_UV);
+ }
+ }
+ }
}
-bool ShaderNode::equals(const ShaderNode& other)
+bool ShaderNode::equals(const ShaderNode &other)
{
- if(type != other.type || bump != other.bump) {
- return false;
- }
-
- assert(inputs.size() == other.inputs.size());
-
- /* Compare unlinkable sockets */
- foreach(const SocketType& socket, type->inputs) {
- if(!(socket.flags & SocketType::LINKABLE)) {
- if(!Node::equals_value(other, socket)) {
- return false;
- }
- }
- }
-
- /* Compare linkable input sockets */
- for(int i = 0; i < inputs.size(); ++i) {
- ShaderInput *input_a = inputs[i],
- *input_b = other.inputs[i];
- if(input_a->link == NULL && input_b->link == NULL) {
- /* Unconnected inputs are expected to have the same value. */
- if(!Node::equals_value(other, input_a->socket_type)) {
- return false;
- }
- }
- else if(input_a->link != NULL && input_b->link != NULL) {
- /* Expect links are to come from the same exact socket. */
- if(input_a->link != input_b->link) {
- return false;
- }
- }
- else {
- /* One socket has a link and another has not, inputs can't be
- * considered equal.
- */
- return false;
- }
- }
-
- return true;
+ if (type != other.type || bump != other.bump) {
+ return false;
+ }
+
+ assert(inputs.size() == other.inputs.size());
+
+ /* Compare unlinkable sockets */
+ foreach (const SocketType &socket, type->inputs) {
+ if (!(socket.flags & SocketType::LINKABLE)) {
+ if (!Node::equals_value(other, socket)) {
+ return false;
+ }
+ }
+ }
+
+ /* Compare linkable input sockets */
+ for (int i = 0; i < inputs.size(); ++i) {
+ ShaderInput *input_a = inputs[i], *input_b = other.inputs[i];
+ if (input_a->link == NULL && input_b->link == NULL) {
+ /* Unconnected inputs are expected to have the same value. */
+ if (!Node::equals_value(other, input_a->socket_type)) {
+ return false;
+ }
+ }
+ else if (input_a->link != NULL && input_b->link != NULL) {
+ /* Expect links are to come from the same exact socket. */
+ if (input_a->link != input_b->link) {
+ return false;
+ }
+ }
+ else {
+ /* One socket has a link and another has not, inputs can't be
+ * considered equal.
+ */
+ return false;
+ }
+ }
+
+ return true;
}
/* Graph */
ShaderGraph::ShaderGraph()
{
- finalized = false;
- simplified = false;
- num_node_ids = 0;
- add(new OutputNode());
+ finalized = false;
+ simplified = false;
+ num_node_ids = 0;
+ add(new OutputNode());
}
ShaderGraph::~ShaderGraph()
{
- clear_nodes();
+ clear_nodes();
}
ShaderNode *ShaderGraph::add(ShaderNode *node)
{
- assert(!finalized);
- simplified = false;
+ assert(!finalized);
+ simplified = false;
- node->id = num_node_ids++;
- nodes.push_back(node);
- return node;
+ node->id = num_node_ids++;
+ nodes.push_back(node);
+ return node;
}
OutputNode *ShaderGraph::output()
{
- return (OutputNode*)nodes.front();
+ return (OutputNode *)nodes.front();
}
void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
{
- assert(!finalized);
- assert(from && to);
-
- if(to->link) {
- fprintf(stderr, "Cycles shader graph connect: input already connected.\n");
- return;
- }
-
- if(from->type() != to->type()) {
- /* can't do automatic conversion from closure */
- if(from->type() == SocketType::CLOSURE) {
- fprintf(stderr, "Cycles shader graph connect: can only connect closure to closure "
- "(%s.%s to %s.%s).\n",
- from->parent->name.c_str(), from->name().c_str(),
- to->parent->name.c_str(), to->name().c_str());
- return;
- }
-
- /* add automatic conversion node in case of type mismatch */
- ShaderNode *convert;
- ShaderInput *convert_in;
-
- if(to->type() == SocketType::CLOSURE) {
- EmissionNode *emission = new EmissionNode();
- emission->color = make_float3(1.0f, 1.0f, 1.0f);
- emission->strength = 1.0f;
- convert = add(emission);
- /* Connect float inputs to Strength to save an additional Falue->Color conversion. */
- if(from->type() == SocketType::FLOAT) {
- convert_in = convert->input("Strength");
- }
- else {
- convert_in = convert->input("Color");
- }
- }
- else {
- convert = add(new ConvertNode(from->type(), to->type(), true));
- convert_in = convert->inputs[0];
- }
-
- connect(from, convert_in);
- connect(convert->outputs[0], to);
- }
- else {
- /* types match, just connect */
- to->link = from;
- from->links.push_back(to);
- }
+ assert(!finalized);
+ assert(from && to);
+
+ if (to->link) {
+ fprintf(stderr, "Cycles shader graph connect: input already connected.\n");
+ return;
+ }
+
+ if (from->type() != to->type()) {
+ /* can't do automatic conversion from closure */
+ if (from->type() == SocketType::CLOSURE) {
+ fprintf(stderr,
+ "Cycles shader graph connect: can only connect closure to closure "
+ "(%s.%s to %s.%s).\n",
+ from->parent->name.c_str(),
+ from->name().c_str(),
+ to->parent->name.c_str(),
+ to->name().c_str());
+ return;
+ }
+
+ /* add automatic conversion node in case of type mismatch */
+ ShaderNode *convert;
+ ShaderInput *convert_in;
+
+ if (to->type() == SocketType::CLOSURE) {
+ EmissionNode *emission = new EmissionNode();
+ emission->color = make_float3(1.0f, 1.0f, 1.0f);
+ emission->strength = 1.0f;
+ convert = add(emission);
+ /* Connect float inputs to Strength to save an additional Falue->Color conversion. */
+ if (from->type() == SocketType::FLOAT) {
+ convert_in = convert->input("Strength");
+ }
+ else {
+ convert_in = convert->input("Color");
+ }
+ }
+ else {
+ convert = add(new ConvertNode(from->type(), to->type(), true));
+ convert_in = convert->inputs[0];
+ }
+
+ connect(from, convert_in);
+ connect(convert->outputs[0], to);
+ }
+ else {
+ /* types match, just connect */
+ to->link = from;
+ from->links.push_back(to);
+ }
}
void ShaderGraph::disconnect(ShaderOutput *from)
{
- assert(!finalized);
- simplified = false;
+ assert(!finalized);
+ simplified = false;
- foreach(ShaderInput *sock, from->links) {
- sock->link = NULL;
- }
+ foreach (ShaderInput *sock, from->links) {
+ sock->link = NULL;
+ }
- from->links.clear();
+ from->links.clear();
}
void ShaderGraph::disconnect(ShaderInput *to)
{
- assert(!finalized);
- assert(to->link);
- simplified = false;
+ assert(!finalized);
+ assert(to->link);
+ simplified = false;
- ShaderOutput *from = to->link;
+ ShaderOutput *from = to->link;
- to->link = NULL;
- from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
+ to->link = NULL;
+ from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to)
{
- simplified = false;
-
- /* Copy because disconnect modifies this list */
- vector<ShaderInput*> outputs = from->links;
-
- /* Bypass node by moving all links from "from" to "to" */
- foreach(ShaderInput *sock, node->inputs) {
- if(sock->link)
- disconnect(sock);
- }
-
- foreach(ShaderInput *sock, outputs) {
- disconnect(sock);
- if(to)
- connect(to, sock);
- }
+ simplified = false;
+
+ /* Copy because disconnect modifies this list */
+ vector<ShaderInput *> outputs = from->links;
+
+ /* Bypass node by moving all links from "from" to "to" */
+ foreach (ShaderInput *sock, node->inputs) {
+ if (sock->link)
+ disconnect(sock);
+ }
+
+ foreach (ShaderInput *sock, outputs) {
+ disconnect(sock);
+ if (to)
+ connect(to, sock);
+ }
}
void ShaderGraph::simplify(Scene *scene)
{
- if(!simplified) {
- default_inputs(scene->shader_manager->use_osl());
- clean(scene);
- refine_bump_nodes();
+ if (!simplified) {
+ default_inputs(scene->shader_manager->use_osl());
+ clean(scene);
+ refine_bump_nodes();
- simplified = true;
- }
+ simplified = true;
+ }
}
-void ShaderGraph::finalize(Scene *scene,
- bool do_bump,
- bool do_simplify,
- bool bump_in_object_space)
+void ShaderGraph::finalize(Scene *scene, bool do_bump, bool do_simplify, bool bump_in_object_space)
{
- /* before compiling, the shader graph may undergo a number of modifications.
- * currently we set default geometry shader inputs, and create automatic bump
- * from displacement. a graph can be finalized only once, and should not be
- * modified afterwards. */
+ /* before compiling, the shader graph may undergo a number of modifications.
+ * currently we set default geometry shader inputs, and create automatic bump
+ * from displacement. a graph can be finalized only once, and should not be
+ * modified afterwards. */
- if(!finalized) {
- simplify(scene);
+ if (!finalized) {
+ simplify(scene);
- if(do_bump)
- bump_from_displacement(bump_in_object_space);
+ if (do_bump)
+ bump_from_displacement(bump_in_object_space);
- ShaderInput *surface_in = output()->input("Surface");
- ShaderInput *volume_in = output()->input("Volume");
+ ShaderInput *surface_in = output()->input("Surface");
+ ShaderInput *volume_in = output()->input("Volume");
- /* todo: make this work when surface and volume closures are tangled up */
+ /* todo: make this work when surface and volume closures are tangled up */
- if(surface_in->link)
- transform_multi_closure(surface_in->link->parent, NULL, false);
- if(volume_in->link)
- transform_multi_closure(volume_in->link->parent, NULL, true);
+ if (surface_in->link)
+ transform_multi_closure(surface_in->link->parent, NULL, false);
+ if (volume_in->link)
+ transform_multi_closure(volume_in->link->parent, NULL, true);
- finalized = true;
- }
- else if(do_simplify) {
- simplify_settings(scene);
- }
+ finalized = true;
+ }
+ else if (do_simplify) {
+ simplify_settings(scene);
+ }
}
-void ShaderGraph::find_dependencies(ShaderNodeSet& dependencies, ShaderInput *input)
+void ShaderGraph::find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input)
{
- /* find all nodes that this input depends on directly and indirectly */
- ShaderNode *node = (input->link)? input->link->parent: NULL;
+ /* find all nodes that this input depends on directly and indirectly */
+ ShaderNode *node = (input->link) ? input->link->parent : NULL;
- if(node != NULL && dependencies.find(node) == dependencies.end()) {
- foreach(ShaderInput *in, node->inputs)
- find_dependencies(dependencies, in);
+ if (node != NULL && dependencies.find(node) == dependencies.end()) {
+ foreach (ShaderInput *in, node->inputs)
+ find_dependencies(dependencies, in);
- dependencies.insert(node);
- }
+ dependencies.insert(node);
+ }
}
void ShaderGraph::clear_nodes()
{
- foreach(ShaderNode *node, nodes) {
- delete node;
- }
- nodes.clear();
+ foreach (ShaderNode *node, nodes) {
+ delete node;
+ }
+ nodes.clear();
}
-void ShaderGraph::copy_nodes(ShaderNodeSet& nodes, ShaderNodeMap& nnodemap)
+void ShaderGraph::copy_nodes(ShaderNodeSet &nodes, ShaderNodeMap &nnodemap)
{
- /* copy a set of nodes, and the links between them. the assumption is
- * made that all nodes that inputs are linked to are in the set too. */
-
- /* copy nodes */
- foreach(ShaderNode *node, nodes) {
- ShaderNode *nnode = node->clone();
- nnodemap[node] = nnode;
-
- /* create new inputs and outputs to recreate links and ensure
- * that we still point to valid SocketType if the NodeType
- * changed in cloning, as it does for OSL nodes */
- nnode->inputs.clear();
- nnode->outputs.clear();
- nnode->create_inputs_outputs(nnode->type);
- }
-
- /* recreate links */
- foreach(ShaderNode *node, nodes) {
- foreach(ShaderInput *input, node->inputs) {
- if(input->link) {
- /* find new input and output */
- ShaderNode *nfrom = nnodemap[input->link->parent];
- ShaderNode *nto = nnodemap[input->parent];
- ShaderOutput *noutput = nfrom->output(input->link->name());
- ShaderInput *ninput = nto->input(input->name());
-
- /* connect */
- connect(noutput, ninput);
- }
- }
- }
+ /* copy a set of nodes, and the links between them. the assumption is
+ * made that all nodes that inputs are linked to are in the set too. */
+
+ /* copy nodes */
+ foreach (ShaderNode *node, nodes) {
+ ShaderNode *nnode = node->clone();
+ nnodemap[node] = nnode;
+
+ /* create new inputs and outputs to recreate links and ensure
+ * that we still point to valid SocketType if the NodeType
+ * changed in cloning, as it does for OSL nodes */
+ nnode->inputs.clear();
+ nnode->outputs.clear();
+ nnode->create_inputs_outputs(nnode->type);
+ }
+
+ /* recreate links */
+ foreach (ShaderNode *node, nodes) {
+ foreach (ShaderInput *input, node->inputs) {
+ if (input->link) {
+ /* find new input and output */
+ ShaderNode *nfrom = nnodemap[input->link->parent];
+ ShaderNode *nto = nnodemap[input->parent];
+ ShaderOutput *noutput = nfrom->output(input->link->name());
+ ShaderInput *ninput = nto->input(input->name());
+
+ /* connect */
+ connect(noutput, ninput);
+ }
+ }
+ }
}
/* Graph simplification */
@@ -427,68 +424,68 @@ void ShaderGraph::copy_nodes(ShaderNodeSet& nodes, ShaderNodeMap& nnodemap)
*/
void ShaderGraph::remove_proxy_nodes()
{
- vector<bool> removed(num_node_ids, false);
- bool any_node_removed = false;
-
- foreach(ShaderNode *node, nodes) {
- if(node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
- ConvertNode *proxy = static_cast<ConvertNode*>(node);
- ShaderInput *input = proxy->inputs[0];
- ShaderOutput *output = proxy->outputs[0];
-
- /* bypass the proxy node */
- if(input->link) {
- relink(proxy, output, input->link);
- }
- else {
- /* Copy because disconnect modifies this list */
- vector<ShaderInput*> links(output->links);
-
- foreach(ShaderInput *to, links) {
- /* remove any autoconvert nodes too if they lead to
- * sockets with an automatically set default value */
- ShaderNode *tonode = to->parent;
-
- if(tonode->special_type == SHADER_SPECIAL_TYPE_AUTOCONVERT) {
- bool all_links_removed = true;
- vector<ShaderInput*> links = tonode->outputs[0]->links;
-
- foreach(ShaderInput *autoin, links) {
- if(autoin->flags() & SocketType::DEFAULT_LINK_MASK)
- disconnect(autoin);
- else
- all_links_removed = false;
- }
-
- if(all_links_removed)
- removed[tonode->id] = true;
- }
-
- disconnect(to);
-
- /* transfer the default input value to the target socket */
- tonode->copy_value(to->socket_type, *proxy, input->socket_type);
- }
- }
-
- removed[proxy->id] = true;
- any_node_removed = true;
- }
- }
-
- /* remove nodes */
- if(any_node_removed) {
- list<ShaderNode*> newnodes;
-
- foreach(ShaderNode *node, nodes) {
- if(!removed[node->id])
- newnodes.push_back(node);
- else
- delete node;
- }
-
- nodes = newnodes;
- }
+ vector<bool> removed(num_node_ids, false);
+ bool any_node_removed = false;
+
+ foreach (ShaderNode *node, nodes) {
+ if (node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
+ ConvertNode *proxy = static_cast<ConvertNode *>(node);
+ ShaderInput *input = proxy->inputs[0];
+ ShaderOutput *output = proxy->outputs[0];
+
+ /* bypass the proxy node */
+ if (input->link) {
+ relink(proxy, output, input->link);
+ }
+ else {
+ /* Copy because disconnect modifies this list */
+ vector<ShaderInput *> links(output->links);
+
+ foreach (ShaderInput *to, links) {
+ /* remove any autoconvert nodes too if they lead to
+ * sockets with an automatically set default value */
+ ShaderNode *tonode = to->parent;
+
+ if (tonode->special_type == SHADER_SPECIAL_TYPE_AUTOCONVERT) {
+ bool all_links_removed = true;
+ vector<ShaderInput *> links = tonode->outputs[0]->links;
+
+ foreach (ShaderInput *autoin, links) {
+ if (autoin->flags() & SocketType::DEFAULT_LINK_MASK)
+ disconnect(autoin);
+ else
+ all_links_removed = false;
+ }
+
+ if (all_links_removed)
+ removed[tonode->id] = true;
+ }
+
+ disconnect(to);
+
+ /* transfer the default input value to the target socket */
+ tonode->copy_value(to->socket_type, *proxy, input->socket_type);
+ }
+ }
+
+ removed[proxy->id] = true;
+ any_node_removed = true;
+ }
+ }
+
+ /* remove nodes */
+ if (any_node_removed) {
+ list<ShaderNode *> newnodes;
+
+ foreach (ShaderNode *node, nodes) {
+ if (!removed[node->id])
+ newnodes.push_back(node);
+ else
+ delete node;
+ }
+
+ nodes = newnodes;
+ }
}
/* Constant folding.
@@ -498,143 +495,143 @@ void ShaderGraph::remove_proxy_nodes()
*/
void ShaderGraph::constant_fold(Scene *scene)
{
- ShaderNodeSet done, scheduled;
- queue<ShaderNode*> traverse_queue;
-
- bool has_displacement = (output()->input("Displacement")->link != NULL);
-
- /* Schedule nodes which doesn't have any dependencies. */
- foreach(ShaderNode *node, nodes) {
- if(!check_node_inputs_has_links(node)) {
- traverse_queue.push(node);
- scheduled.insert(node);
- }
- }
-
- while(!traverse_queue.empty()) {
- ShaderNode *node = traverse_queue.front();
- traverse_queue.pop();
- done.insert(node);
- foreach(ShaderOutput *output, node->outputs) {
- if(output->links.size() == 0) {
- continue;
- }
- /* Schedule node which was depending on the value,
- * when possible. Do it before disconnect.
- */
- foreach(ShaderInput *input, output->links) {
- if(scheduled.find(input->parent) != scheduled.end()) {
- /* Node might not be optimized yet but scheduled already
- * by other dependencies. No need to re-schedule it.
- */
- continue;
- }
- /* Schedule node if its inputs are fully done. */
- if(check_node_inputs_traversed(input->parent, done)) {
- traverse_queue.push(input->parent);
- scheduled.insert(input->parent);
- }
- }
- /* Optimize current node. */
- ConstantFolder folder(this, node, output, scene);
- node->constant_fold(folder);
- }
- }
-
- /* Folding might have removed all nodes connected to the displacement output
- * even tho there is displacement to be applied, so add in a value node if
- * that happens to ensure there is still a valid graph for displacement.
- */
- if(has_displacement && !output()->input("Displacement")->link) {
- ColorNode *value = (ColorNode*)add(new ColorNode());
- value->value = output()->displacement;
-
- connect(value->output("Color"), output()->input("Displacement"));
- }
+ ShaderNodeSet done, scheduled;
+ queue<ShaderNode *> traverse_queue;
+
+ bool has_displacement = (output()->input("Displacement")->link != NULL);
+
+ /* Schedule nodes which doesn't have any dependencies. */
+ foreach (ShaderNode *node, nodes) {
+ if (!check_node_inputs_has_links(node)) {
+ traverse_queue.push(node);
+ scheduled.insert(node);
+ }
+ }
+
+ while (!traverse_queue.empty()) {
+ ShaderNode *node = traverse_queue.front();
+ traverse_queue.pop();
+ done.insert(node);
+ foreach (ShaderOutput *output, node->outputs) {
+ if (output->links.size() == 0) {
+ continue;
+ }
+ /* Schedule node which was depending on the value,
+ * when possible. Do it before disconnect.
+ */
+ foreach (ShaderInput *input, output->links) {
+ if (scheduled.find(input->parent) != scheduled.end()) {
+ /* Node might not be optimized yet but scheduled already
+ * by other dependencies. No need to re-schedule it.
+ */
+ continue;
+ }
+ /* Schedule node if its inputs are fully done. */
+ if (check_node_inputs_traversed(input->parent, done)) {
+ traverse_queue.push(input->parent);
+ scheduled.insert(input->parent);
+ }
+ }
+ /* Optimize current node. */
+ ConstantFolder folder(this, node, output, scene);
+ node->constant_fold(folder);
+ }
+ }
+
+ /* Folding might have removed all nodes connected to the displacement output
+ * even tho there is displacement to be applied, so add in a value node if
+ * that happens to ensure there is still a valid graph for displacement.
+ */
+ if (has_displacement && !output()->input("Displacement")->link) {
+ ColorNode *value = (ColorNode *)add(new ColorNode());
+ value->value = output()->displacement;
+
+ connect(value->output("Color"), output()->input("Displacement"));
+ }
}
/* Simplification. */
void ShaderGraph::simplify_settings(Scene *scene)
{
- foreach(ShaderNode *node, nodes) {
- node->simplify_settings(scene);
- }
+ foreach (ShaderNode *node, nodes) {
+ node->simplify_settings(scene);
+ }
}
/* Deduplicate nodes with same settings. */
void ShaderGraph::deduplicate_nodes()
{
- /* NOTES:
- * - Deduplication happens for nodes which has same exact settings and same
- * exact input links configuration (either connected to same output or has
- * the same exact default value).
- * - Deduplication happens in the bottom-top manner, so we know for fact that
- * all traversed nodes are either can not be deduplicated at all or were
- * already deduplicated.
- */
-
- ShaderNodeSet scheduled, done;
- map<ustring, ShaderNodeSet> candidates;
- queue<ShaderNode*> traverse_queue;
- int num_deduplicated = 0;
-
- /* Schedule nodes which doesn't have any dependencies. */
- foreach(ShaderNode *node, nodes) {
- if(!check_node_inputs_has_links(node)) {
- traverse_queue.push(node);
- scheduled.insert(node);
- }
- }
-
- while(!traverse_queue.empty()) {
- ShaderNode *node = traverse_queue.front();
- traverse_queue.pop();
- done.insert(node);
- /* Schedule the nodes which were depending on the current node. */
- bool has_output_links = false;
- foreach(ShaderOutput *output, node->outputs) {
- foreach(ShaderInput *input, output->links) {
- has_output_links = true;
- if(scheduled.find(input->parent) != scheduled.end()) {
- /* Node might not be optimized yet but scheduled already
- * by other dependencies. No need to re-schedule it.
- */
- continue;
- }
- /* Schedule node if its inputs are fully done. */
- if(check_node_inputs_traversed(input->parent, done)) {
- traverse_queue.push(input->parent);
- scheduled.insert(input->parent);
- }
- }
- }
- /* Only need to care about nodes that are actually used */
- if(!has_output_links) {
- continue;
- }
- /* Try to merge this node with another one. */
- ShaderNode *merge_with = NULL;
- foreach(ShaderNode *other_node, candidates[node->type->name]) {
- if(node != other_node && node->equals(*other_node)) {
- merge_with = other_node;
- break;
- }
- }
- /* If found an equivalent, merge; otherwise keep node for later merges */
- if(merge_with != NULL) {
- for(int i = 0; i < node->outputs.size(); ++i) {
- relink(node, node->outputs[i], merge_with->outputs[i]);
- }
- num_deduplicated++;
- }
- else {
- candidates[node->type->name].insert(node);
- }
- }
-
- if(num_deduplicated > 0) {
- VLOG(1) << "Deduplicated " << num_deduplicated << " nodes.";
- }
+ /* NOTES:
+ * - Deduplication happens for nodes which has same exact settings and same
+ * exact input links configuration (either connected to same output or has
+ * the same exact default value).
+ * - Deduplication happens in the bottom-top manner, so we know for fact that
+ * all traversed nodes are either can not be deduplicated at all or were
+ * already deduplicated.
+ */
+
+ ShaderNodeSet scheduled, done;
+ map<ustring, ShaderNodeSet> candidates;
+ queue<ShaderNode *> traverse_queue;
+ int num_deduplicated = 0;
+
+ /* Schedule nodes which doesn't have any dependencies. */
+ foreach (ShaderNode *node, nodes) {
+ if (!check_node_inputs_has_links(node)) {
+ traverse_queue.push(node);
+ scheduled.insert(node);
+ }
+ }
+
+ while (!traverse_queue.empty()) {
+ ShaderNode *node = traverse_queue.front();
+ traverse_queue.pop();
+ done.insert(node);
+ /* Schedule the nodes which were depending on the current node. */
+ bool has_output_links = false;
+ foreach (ShaderOutput *output, node->outputs) {
+ foreach (ShaderInput *input, output->links) {
+ has_output_links = true;
+ if (scheduled.find(input->parent) != scheduled.end()) {
+ /* Node might not be optimized yet but scheduled already
+ * by other dependencies. No need to re-schedule it.
+ */
+ continue;
+ }
+ /* Schedule node if its inputs are fully done. */
+ if (check_node_inputs_traversed(input->parent, done)) {
+ traverse_queue.push(input->parent);
+ scheduled.insert(input->parent);
+ }
+ }
+ }
+ /* Only need to care about nodes that are actually used */
+ if (!has_output_links) {
+ continue;
+ }
+ /* Try to merge this node with another one. */
+ ShaderNode *merge_with = NULL;
+ foreach (ShaderNode *other_node, candidates[node->type->name]) {
+ if (node != other_node && node->equals(*other_node)) {
+ merge_with = other_node;
+ break;
+ }
+ }
+ /* If found an equivalent, merge; otherwise keep node for later merges */
+ if (merge_with != NULL) {
+ for (int i = 0; i < node->outputs.size(); ++i) {
+ relink(node, node->outputs[i], merge_with->outputs[i]);
+ }
+ num_deduplicated++;
+ }
+ else {
+ candidates[node->type->name].insert(node);
+ }
+ }
+
+ if (num_deduplicated > 0) {
+ VLOG(1) << "Deduplicated " << num_deduplicated << " nodes.";
+ }
}
/* Check whether volume output has meaningful nodes, otherwise
@@ -642,535 +639,536 @@ void ShaderGraph::deduplicate_nodes()
*/
void ShaderGraph::verify_volume_output()
{
- /* Check whether we can optimize the whole volume graph out. */
- ShaderInput *volume_in = output()->input("Volume");
- if(volume_in->link == NULL) {
- return;
- }
- bool has_valid_volume = false;
- ShaderNodeSet scheduled;
- queue<ShaderNode*> traverse_queue;
- /* Schedule volume output. */
- traverse_queue.push(volume_in->link->parent);
- scheduled.insert(volume_in->link->parent);
- /* Traverse down the tree. */
- while(!traverse_queue.empty()) {
- ShaderNode *node = traverse_queue.front();
- traverse_queue.pop();
- /* Node is fully valid for volume, can't optimize anything out. */
- if(node->has_volume_support()) {
- has_valid_volume = true;
- break;
- }
- foreach(ShaderInput *input, node->inputs) {
- if(input->link == NULL) {
- continue;
- }
- if(scheduled.find(input->link->parent) != scheduled.end()) {
- continue;
- }
- traverse_queue.push(input->link->parent);
- scheduled.insert(input->link->parent);
- }
- }
- if(!has_valid_volume) {
- VLOG(1) << "Disconnect meaningless volume output.";
- disconnect(volume_in->link);
- }
+ /* Check whether we can optimize the whole volume graph out. */
+ ShaderInput *volume_in = output()->input("Volume");
+ if (volume_in->link == NULL) {
+ return;
+ }
+ bool has_valid_volume = false;
+ ShaderNodeSet scheduled;
+ queue<ShaderNode *> traverse_queue;
+ /* Schedule volume output. */
+ traverse_queue.push(volume_in->link->parent);
+ scheduled.insert(volume_in->link->parent);
+ /* Traverse down the tree. */
+ while (!traverse_queue.empty()) {
+ ShaderNode *node = traverse_queue.front();
+ traverse_queue.pop();
+ /* Node is fully valid for volume, can't optimize anything out. */
+ if (node->has_volume_support()) {
+ has_valid_volume = true;
+ break;
+ }
+ foreach (ShaderInput *input, node->inputs) {
+ if (input->link == NULL) {
+ continue;
+ }
+ if (scheduled.find(input->link->parent) != scheduled.end()) {
+ continue;
+ }
+ traverse_queue.push(input->link->parent);
+ scheduled.insert(input->link->parent);
+ }
+ }
+ if (!has_valid_volume) {
+ VLOG(1) << "Disconnect meaningless volume output.";
+ disconnect(volume_in->link);
+ }
}
-void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
+void ShaderGraph::break_cycles(ShaderNode *node, vector<bool> &visited, vector<bool> &on_stack)
{
- visited[node->id] = true;
- on_stack[node->id] = true;
-
- foreach(ShaderInput *input, node->inputs) {
- if(input->link) {
- ShaderNode *depnode = input->link->parent;
-
- if(on_stack[depnode->id]) {
- /* break cycle */
- disconnect(input);
- fprintf(stderr, "Cycles shader graph: detected cycle in graph, connection removed.\n");
- }
- else if(!visited[depnode->id]) {
- /* visit dependencies */
- break_cycles(depnode, visited, on_stack);
- }
- }
- }
-
- on_stack[node->id] = false;
+ visited[node->id] = true;
+ on_stack[node->id] = true;
+
+ foreach (ShaderInput *input, node->inputs) {
+ if (input->link) {
+ ShaderNode *depnode = input->link->parent;
+
+ if (on_stack[depnode->id]) {
+ /* break cycle */
+ disconnect(input);
+ fprintf(stderr, "Cycles shader graph: detected cycle in graph, connection removed.\n");
+ }
+ else if (!visited[depnode->id]) {
+ /* visit dependencies */
+ break_cycles(depnode, visited, on_stack);
+ }
+ }
+ }
+
+ on_stack[node->id] = false;
}
void ShaderGraph::compute_displacement_hash()
{
- /* Compute hash of all nodes linked to displacement, to detect if we need
- * to recompute displacement when shader nodes change. */
- ShaderInput *displacement_in = output()->input("Displacement");
-
- if(!displacement_in->link) {
- displacement_hash = "";
- return;
- }
-
- ShaderNodeSet nodes_displace;
- find_dependencies(nodes_displace, displacement_in);
-
- MD5Hash md5;
- foreach(ShaderNode *node, nodes_displace) {
- node->hash(md5);
- foreach(ShaderInput *input, node->inputs) {
- int link_id = (input->link) ? input->link->parent->id : 0;
- md5.append((uint8_t*)&link_id, sizeof(link_id));
- }
- }
-
- displacement_hash = md5.get_hex();
+ /* Compute hash of all nodes linked to displacement, to detect if we need
+ * to recompute displacement when shader nodes change. */
+ ShaderInput *displacement_in = output()->input("Displacement");
+
+ if (!displacement_in->link) {
+ displacement_hash = "";
+ return;
+ }
+
+ ShaderNodeSet nodes_displace;
+ find_dependencies(nodes_displace, displacement_in);
+
+ MD5Hash md5;
+ foreach (ShaderNode *node, nodes_displace) {
+ node->hash(md5);
+ foreach (ShaderInput *input, node->inputs) {
+ int link_id = (input->link) ? input->link->parent->id : 0;
+ md5.append((uint8_t *)&link_id, sizeof(link_id));
+ }
+ }
+
+ displacement_hash = md5.get_hex();
}
void ShaderGraph::clean(Scene *scene)
{
- /* Graph simplification */
-
- /* NOTE: Remove proxy nodes was already done. */
- constant_fold(scene);
- simplify_settings(scene);
- deduplicate_nodes();
- verify_volume_output();
-
- /* we do two things here: find cycles and break them, and remove unused
- * nodes that don't feed into the output. how cycles are broken is
- * undefined, they are invalid input, the important thing is to not crash */
-
- vector<bool> visited(num_node_ids, false);
- vector<bool> on_stack(num_node_ids, false);
-
- /* break cycles */
- break_cycles(output(), visited, on_stack);
-
- /* disconnect unused nodes */
- foreach(ShaderNode *node, nodes) {
- if(!visited[node->id]) {
- foreach(ShaderInput *to, node->inputs) {
- ShaderOutput *from = to->link;
-
- if(from) {
- to->link = NULL;
- from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
- }
- }
- }
- }
-
- /* remove unused nodes */
- list<ShaderNode*> newnodes;
-
- foreach(ShaderNode *node, nodes) {
- if(visited[node->id])
- newnodes.push_back(node);
- else
- delete node;
- }
-
- nodes = newnodes;
+ /* Graph simplification */
+
+ /* NOTE: Remove proxy nodes was already done. */
+ constant_fold(scene);
+ simplify_settings(scene);
+ deduplicate_nodes();
+ verify_volume_output();
+
+ /* we do two things here: find cycles and break them, and remove unused
+ * nodes that don't feed into the output. how cycles are broken is
+ * undefined, they are invalid input, the important thing is to not crash */
+
+ vector<bool> visited(num_node_ids, false);
+ vector<bool> on_stack(num_node_ids, false);
+
+ /* break cycles */
+ break_cycles(output(), visited, on_stack);
+
+ /* disconnect unused nodes */
+ foreach (ShaderNode *node, nodes) {
+ if (!visited[node->id]) {
+ foreach (ShaderInput *to, node->inputs) {
+ ShaderOutput *from = to->link;
+
+ if (from) {
+ to->link = NULL;
+ from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
+ }
+ }
+ }
+ }
+
+ /* remove unused nodes */
+ list<ShaderNode *> newnodes;
+
+ foreach (ShaderNode *node, nodes) {
+ if (visited[node->id])
+ newnodes.push_back(node);
+ else
+ delete node;
+ }
+
+ nodes = newnodes;
}
void ShaderGraph::default_inputs(bool do_osl)
{
- /* nodes can specify default texture coordinates, for now we give
- * everything the position by default, except for the sky texture */
-
- ShaderNode *geom = NULL;
- ShaderNode *texco = NULL;
-
- foreach(ShaderNode *node, nodes) {
- foreach(ShaderInput *input, node->inputs) {
- if(!input->link && (!(input->flags() & SocketType::OSL_INTERNAL) || do_osl)) {
- if(input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
- if(!texco)
- texco = new TextureCoordinateNode();
-
- connect(texco->output("Generated"), input);
- }
- if(input->flags() & SocketType::LINK_TEXTURE_NORMAL) {
- if(!texco)
- texco = new TextureCoordinateNode();
-
- connect(texco->output("Normal"), input);
- }
- else if(input->flags() & SocketType::LINK_TEXTURE_UV) {
- if(!texco)
- texco = new TextureCoordinateNode();
-
- connect(texco->output("UV"), input);
- }
- else if(input->flags() & SocketType::LINK_INCOMING) {
- if(!geom)
- geom = new GeometryNode();
-
- connect(geom->output("Incoming"), input);
- }
- else if(input->flags() & SocketType::LINK_NORMAL) {
- if(!geom)
- geom = new GeometryNode();
-
- connect(geom->output("Normal"), input);
- }
- else if(input->flags() & SocketType::LINK_POSITION) {
- if(!geom)
- geom = new GeometryNode();
-
- connect(geom->output("Position"), input);
- }
- else if(input->flags() & SocketType::LINK_TANGENT) {
- if(!geom)
- geom = new GeometryNode();
-
- connect(geom->output("Tangent"), input);
- }
- }
- }
- }
-
- if(geom)
- add(geom);
- if(texco)
- add(texco);
+ /* nodes can specify default texture coordinates, for now we give
+ * everything the position by default, except for the sky texture */
+
+ ShaderNode *geom = NULL;
+ ShaderNode *texco = NULL;
+
+ foreach (ShaderNode *node, nodes) {
+ foreach (ShaderInput *input, node->inputs) {
+ if (!input->link && (!(input->flags() & SocketType::OSL_INTERNAL) || do_osl)) {
+ if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
+ if (!texco)
+ texco = new TextureCoordinateNode();
+
+ connect(texco->output("Generated"), input);
+ }
+ if (input->flags() & SocketType::LINK_TEXTURE_NORMAL) {
+ if (!texco)
+ texco = new TextureCoordinateNode();
+
+ connect(texco->output("Normal"), input);
+ }
+ else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
+ if (!texco)
+ texco = new TextureCoordinateNode();
+
+ connect(texco->output("UV"), input);
+ }
+ else if (input->flags() & SocketType::LINK_INCOMING) {
+ if (!geom)
+ geom = new GeometryNode();
+
+ connect(geom->output("Incoming"), input);
+ }
+ else if (input->flags() & SocketType::LINK_NORMAL) {
+ if (!geom)
+ geom = new GeometryNode();
+
+ connect(geom->output("Normal"), input);
+ }
+ else if (input->flags() & SocketType::LINK_POSITION) {
+ if (!geom)
+ geom = new GeometryNode();
+
+ connect(geom->output("Position"), input);
+ }
+ else if (input->flags() & SocketType::LINK_TANGENT) {
+ if (!geom)
+ geom = new GeometryNode();
+
+ connect(geom->output("Tangent"), input);
+ }
+ }
+ }
+ }
+
+ if (geom)
+ add(geom);
+ if (texco)
+ add(texco);
}
void ShaderGraph::refine_bump_nodes()
{
- /* we transverse the node graph looking for bump nodes, when we find them,
- * like in bump_from_displacement(), we copy the sub-graph defined from "bump"
- * input to the inputs "center","dx" and "dy" What is in "bump" input is moved
- * to "center" input. */
-
- foreach(ShaderNode *node, nodes) {
- if(node->special_type == SHADER_SPECIAL_TYPE_BUMP && node->input("Height")->link) {
- ShaderInput *bump_input = node->input("Height");
- ShaderNodeSet nodes_bump;
-
- /* make 2 extra copies of the subgraph defined in Bump input */
- ShaderNodeMap nodes_dx;
- ShaderNodeMap nodes_dy;
-
- /* find dependencies for the given input */
- find_dependencies(nodes_bump, bump_input);
-
- copy_nodes(nodes_bump, nodes_dx);
- copy_nodes(nodes_bump, nodes_dy);
-
- /* mark nodes to indicate they are use for bump computation, so
- that any texture coordinates are shifted by dx/dy when sampling */
- foreach(ShaderNode *node, nodes_bump)
- node->bump = SHADER_BUMP_CENTER;
- foreach(NodePair& pair, nodes_dx)
- pair.second->bump = SHADER_BUMP_DX;
- foreach(NodePair& pair, nodes_dy)
- pair.second->bump = SHADER_BUMP_DY;
-
- ShaderOutput *out = bump_input->link;
- ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name());
- ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name());
-
- connect(out_dx, node->input("SampleX"));
- connect(out_dy, node->input("SampleY"));
-
- /* add generated nodes */
- foreach(NodePair& pair, nodes_dx)
- add(pair.second);
- foreach(NodePair& pair, nodes_dy)
- add(pair.second);
-
- /* connect what is connected is bump to samplecenter input*/
- connect(out , node->input("SampleCenter"));
-
- /* bump input is just for connectivity purpose for the graph input,
- * we re-connected this input to samplecenter, so lets disconnect it
- * from bump input */
- disconnect(bump_input);
- }
- }
+ /* we transverse the node graph looking for bump nodes, when we find them,
+ * like in bump_from_displacement(), we copy the sub-graph defined from "bump"
+ * input to the inputs "center","dx" and "dy" What is in "bump" input is moved
+ * to "center" input. */
+
+ foreach (ShaderNode *node, nodes) {
+ if (node->special_type == SHADER_SPECIAL_TYPE_BUMP && node->input("Height")->link) {
+ ShaderInput *bump_input = node->input("Height");
+ ShaderNodeSet nodes_bump;
+
+ /* make 2 extra copies of the subgraph defined in Bump input */
+ ShaderNodeMap nodes_dx;
+ ShaderNodeMap nodes_dy;
+
+ /* find dependencies for the given input */
+ find_dependencies(nodes_bump, bump_input);
+
+ copy_nodes(nodes_bump, nodes_dx);
+ copy_nodes(nodes_bump, nodes_dy);
+
+ /* mark nodes to indicate they are use for bump computation, so
+ that any texture coordinates are shifted by dx/dy when sampling */
+ foreach (ShaderNode *node, nodes_bump)
+ node->bump = SHADER_BUMP_CENTER;
+ foreach (NodePair &pair, nodes_dx)
+ pair.second->bump = SHADER_BUMP_DX;
+ foreach (NodePair &pair, nodes_dy)
+ pair.second->bump = SHADER_BUMP_DY;
+
+ ShaderOutput *out = bump_input->link;
+ ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name());
+ ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name());
+
+ connect(out_dx, node->input("SampleX"));
+ connect(out_dy, node->input("SampleY"));
+
+ /* add generated nodes */
+ foreach (NodePair &pair, nodes_dx)
+ add(pair.second);
+ foreach (NodePair &pair, nodes_dy)
+ add(pair.second);
+
+ /* connect what is connected is bump to samplecenter input*/
+ connect(out, node->input("SampleCenter"));
+
+ /* bump input is just for connectivity purpose for the graph input,
+ * we re-connected this input to samplecenter, so lets disconnect it
+ * from bump input */
+ disconnect(bump_input);
+ }
+ }
}
void ShaderGraph::bump_from_displacement(bool use_object_space)
{
- /* generate bump mapping automatically from displacement. bump mapping is
- * done using a 3-tap filter, computing the displacement at the center,
- * and two other positions shifted by ray differentials.
- *
- * since the input to displacement is a node graph, we need to ensure that
- * all texture coordinates use are shift by the ray differentials. for this
- * reason we make 3 copies of the node subgraph defining the displacement,
- * with each different geometry and texture coordinate nodes that generate
- * different shifted coordinates.
- *
- * these 3 displacement values are then fed into the bump node, which will
- * output the perturbed normal. */
-
- ShaderInput *displacement_in = output()->input("Displacement");
-
- if(!displacement_in->link)
- return;
-
- /* find dependencies for the given input */
- ShaderNodeSet nodes_displace;
- find_dependencies(nodes_displace, displacement_in);
-
- /* copy nodes for 3 bump samples */
- ShaderNodeMap nodes_center;
- ShaderNodeMap nodes_dx;
- ShaderNodeMap nodes_dy;
-
- copy_nodes(nodes_displace, nodes_center);
- copy_nodes(nodes_displace, nodes_dx);
- copy_nodes(nodes_displace, nodes_dy);
-
- /* mark nodes to indicate they are use for bump computation, so
- * that any texture coordinates are shifted by dx/dy when sampling */
- foreach(NodePair& pair, nodes_center)
- pair.second->bump = SHADER_BUMP_CENTER;
- foreach(NodePair& pair, nodes_dx)
- pair.second->bump = SHADER_BUMP_DX;
- foreach(NodePair& pair, nodes_dy)
- pair.second->bump = SHADER_BUMP_DY;
-
- /* add set normal node and connect the bump normal ouput to the set normal
- * output, so it can finally set the shader normal, note we are only doing
- * this for bump from displacement, this will be the only bump allowed to
- * overwrite the shader normal */
- ShaderNode *set_normal = add(new SetNormalNode());
-
- /* add bump node and connect copied graphs to it */
- BumpNode *bump = (BumpNode*)add(new BumpNode());
- bump->use_object_space = use_object_space;
- bump->distance = 1.0f;
-
- ShaderOutput *out = displacement_in->link;
- ShaderOutput *out_center = nodes_center[out->parent]->output(out->name());
- ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name());
- ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name());
-
- /* convert displacement vector to height */
- VectorMathNode *dot_center = (VectorMathNode*)add(new VectorMathNode());
- VectorMathNode *dot_dx = (VectorMathNode*)add(new VectorMathNode());
- VectorMathNode *dot_dy = (VectorMathNode*)add(new VectorMathNode());
-
- dot_center->type = NODE_VECTOR_MATH_DOT_PRODUCT;
- dot_dx->type = NODE_VECTOR_MATH_DOT_PRODUCT;
- dot_dy->type = NODE_VECTOR_MATH_DOT_PRODUCT;
-
- GeometryNode *geom = (GeometryNode*)add(new GeometryNode());
- connect(geom->output("Normal"), dot_center->input("Vector2"));
- connect(geom->output("Normal"), dot_dx->input("Vector2"));
- connect(geom->output("Normal"), dot_dy->input("Vector2"));
-
- connect(out_center, dot_center->input("Vector1"));
- connect(out_dx, dot_dx->input("Vector1"));
- connect(out_dy, dot_dy->input("Vector1"));
-
- connect(dot_center->output("Value"), bump->input("SampleCenter"));
- connect(dot_dx->output("Value"), bump->input("SampleX"));
- connect(dot_dy->output("Value"), bump->input("SampleY"));
-
- /* connect the bump out to the set normal in: */
- connect(bump->output("Normal"), set_normal->input("Direction"));
-
- /* connect to output node */
- connect(set_normal->output("Normal"), output()->input("Normal"));
-
- /* finally, add the copied nodes to the graph. we can't do this earlier
- * because we would create dependency cycles in the above loop */
- foreach(NodePair& pair, nodes_center)
- add(pair.second);
- foreach(NodePair& pair, nodes_dx)
- add(pair.second);
- foreach(NodePair& pair, nodes_dy)
- add(pair.second);
+ /* generate bump mapping automatically from displacement. bump mapping is
+ * done using a 3-tap filter, computing the displacement at the center,
+ * and two other positions shifted by ray differentials.
+ *
+ * since the input to displacement is a node graph, we need to ensure that
+ * all texture coordinates use are shift by the ray differentials. for this
+ * reason we make 3 copies of the node subgraph defining the displacement,
+ * with each different geometry and texture coordinate nodes that generate
+ * different shifted coordinates.
+ *
+ * these 3 displacement values are then fed into the bump node, which will
+ * output the perturbed normal. */
+
+ ShaderInput *displacement_in = output()->input("Displacement");
+
+ if (!displacement_in->link)
+ return;
+
+ /* find dependencies for the given input */
+ ShaderNodeSet nodes_displace;
+ find_dependencies(nodes_displace, displacement_in);
+
+ /* copy nodes for 3 bump samples */
+ ShaderNodeMap nodes_center;
+ ShaderNodeMap nodes_dx;
+ ShaderNodeMap nodes_dy;
+
+ copy_nodes(nodes_displace, nodes_center);
+ copy_nodes(nodes_displace, nodes_dx);
+ copy_nodes(nodes_displace, nodes_dy);
+
+ /* mark nodes to indicate they are use for bump computation, so
+ * that any texture coordinates are shifted by dx/dy when sampling */
+ foreach (NodePair &pair, nodes_center)
+ pair.second->bump = SHADER_BUMP_CENTER;
+ foreach (NodePair &pair, nodes_dx)
+ pair.second->bump = SHADER_BUMP_DX;
+ foreach (NodePair &pair, nodes_dy)
+ pair.second->bump = SHADER_BUMP_DY;
+
+ /* add set normal node and connect the bump normal ouput to the set normal
+ * output, so it can finally set the shader normal, note we are only doing
+ * this for bump from displacement, this will be the only bump allowed to
+ * overwrite the shader normal */
+ ShaderNode *set_normal = add(new SetNormalNode());
+
+ /* add bump node and connect copied graphs to it */
+ BumpNode *bump = (BumpNode *)add(new BumpNode());
+ bump->use_object_space = use_object_space;
+ bump->distance = 1.0f;
+
+ ShaderOutput *out = displacement_in->link;
+ ShaderOutput *out_center = nodes_center[out->parent]->output(out->name());
+ ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name());
+ ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name());
+
+ /* convert displacement vector to height */
+ VectorMathNode *dot_center = (VectorMathNode *)add(new VectorMathNode());
+ VectorMathNode *dot_dx = (VectorMathNode *)add(new VectorMathNode());
+ VectorMathNode *dot_dy = (VectorMathNode *)add(new VectorMathNode());
+
+ dot_center->type = NODE_VECTOR_MATH_DOT_PRODUCT;
+ dot_dx->type = NODE_VECTOR_MATH_DOT_PRODUCT;
+ dot_dy->type = NODE_VECTOR_MATH_DOT_PRODUCT;
+
+ GeometryNode *geom = (GeometryNode *)add(new GeometryNode());
+ connect(geom->output("Normal"), dot_center->input("Vector2"));
+ connect(geom->output("Normal"), dot_dx->input("Vector2"));
+ connect(geom->output("Normal"), dot_dy->input("Vector2"));
+
+ connect(out_center, dot_center->input("Vector1"));
+ connect(out_dx, dot_dx->input("Vector1"));
+ connect(out_dy, dot_dy->input("Vector1"));
+
+ connect(dot_center->output("Value"), bump->input("SampleCenter"));
+ connect(dot_dx->output("Value"), bump->input("SampleX"));
+ connect(dot_dy->output("Value"), bump->input("SampleY"));
+
+ /* connect the bump out to the set normal in: */
+ connect(bump->output("Normal"), set_normal->input("Direction"));
+
+ /* connect to output node */
+ connect(set_normal->output("Normal"), output()->input("Normal"));
+
+ /* finally, add the copied nodes to the graph. we can't do this earlier
+ * because we would create dependency cycles in the above loop */
+ foreach (NodePair &pair, nodes_center)
+ add(pair.second);
+ foreach (NodePair &pair, nodes_dx)
+ add(pair.second);
+ foreach (NodePair &pair, nodes_dy)
+ add(pair.second);
}
void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume)
{
- /* for SVM in multi closure mode, this transforms the shader mix/add part of
- * the graph into nodes that feed weights into closure nodes. this is too
- * avoid building a closure tree and then flattening it, and instead write it
- * directly to an array */
-
- if(node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
- ShaderInput *fin = node->input("Fac");
- ShaderInput *cl1in = node->input("Closure1");
- ShaderInput *cl2in = node->input("Closure2");
- ShaderOutput *weight1_out, *weight2_out;
-
- if(fin) {
- /* mix closure: add node to mix closure weights */
- MixClosureWeightNode *mix_node = new MixClosureWeightNode();
- add(mix_node);
- ShaderInput *fac_in = mix_node->input("Fac");
- ShaderInput *weight_in = mix_node->input("Weight");
-
- if(fin->link)
- connect(fin->link, fac_in);
- else
- mix_node->fac = node->get_float(fin->socket_type);
-
- if(weight_out)
- connect(weight_out, weight_in);
-
- weight1_out = mix_node->output("Weight1");
- weight2_out = mix_node->output("Weight2");
- }
- else {
- /* add closure: just pass on any weights */
- weight1_out = weight_out;
- weight2_out = weight_out;
- }
-
- if(cl1in->link)
- transform_multi_closure(cl1in->link->parent, weight1_out, volume);
- if(cl2in->link)
- transform_multi_closure(cl2in->link->parent, weight2_out, volume);
- }
- else {
- ShaderInput *weight_in = node->input((volume)? "VolumeMixWeight": "SurfaceMixWeight");
-
- /* not a closure node? */
- if(!weight_in)
- return;
-
- /* already has a weight connected to it? add weights */
- float weight_value = node->get_float(weight_in->socket_type);
- if(weight_in->link || weight_value != 0.0f) {
- MathNode *math_node = new MathNode();
- add(math_node);
-
- if(weight_in->link)
- connect(weight_in->link, math_node->input("Value1"));
- else
- math_node->value1 = weight_value;
-
- if(weight_out)
- connect(weight_out, math_node->input("Value2"));
- else
- math_node->value2 = 1.0f;
-
- weight_out = math_node->output("Value");
- if(weight_in->link)
- disconnect(weight_in);
- }
-
- /* connected to closure mix weight */
- if(weight_out)
- connect(weight_out, weight_in);
- else
- node->set(weight_in->socket_type, weight_value + 1.0f);
- }
+ /* for SVM in multi closure mode, this transforms the shader mix/add part of
+ * the graph into nodes that feed weights into closure nodes. this is too
+ * avoid building a closure tree and then flattening it, and instead write it
+ * directly to an array */
+
+ if (node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
+ ShaderInput *fin = node->input("Fac");
+ ShaderInput *cl1in = node->input("Closure1");
+ ShaderInput *cl2in = node->input("Closure2");
+ ShaderOutput *weight1_out, *weight2_out;
+
+ if (fin) {
+ /* mix closure: add node to mix closure weights */
+ MixClosureWeightNode *mix_node = new MixClosureWeightNode();
+ add(mix_node);
+ ShaderInput *fac_in = mix_node->input("Fac");
+ ShaderInput *weight_in = mix_node->input("Weight");
+
+ if (fin->link)
+ connect(fin->link, fac_in);
+ else
+ mix_node->fac = node->get_float(fin->socket_type);
+
+ if (weight_out)
+ connect(weight_out, weight_in);
+
+ weight1_out = mix_node->output("Weight1");
+ weight2_out = mix_node->output("Weight2");
+ }
+ else {
+ /* add closure: just pass on any weights */
+ weight1_out = weight_out;
+ weight2_out = weight_out;
+ }
+
+ if (cl1in->link)
+ transform_multi_closure(cl1in->link->parent, weight1_out, volume);
+ if (cl2in->link)
+ transform_multi_closure(cl2in->link->parent, weight2_out, volume);
+ }
+ else {
+ ShaderInput *weight_in = node->input((volume) ? "VolumeMixWeight" : "SurfaceMixWeight");
+
+ /* not a closure node? */
+ if (!weight_in)
+ return;
+
+ /* already has a weight connected to it? add weights */
+ float weight_value = node->get_float(weight_in->socket_type);
+ if (weight_in->link || weight_value != 0.0f) {
+ MathNode *math_node = new MathNode();
+ add(math_node);
+
+ if (weight_in->link)
+ connect(weight_in->link, math_node->input("Value1"));
+ else
+ math_node->value1 = weight_value;
+
+ if (weight_out)
+ connect(weight_out, math_node->input("Value2"));
+ else
+ math_node->value2 = 1.0f;
+
+ weight_out = math_node->output("Value");
+ if (weight_in->link)
+ disconnect(weight_in);
+ }
+
+ /* connected to closure mix weight */
+ if (weight_out)
+ connect(weight_out, weight_in);
+ else
+ node->set(weight_in->socket_type, weight_value + 1.0f);
+ }
}
int ShaderGraph::get_num_closures()
{
- int num_closures = 0;
- foreach(ShaderNode *node, nodes) {
- ClosureType closure_type = node->get_closure_type();
- if(closure_type == CLOSURE_NONE_ID) {
- continue;
- }
- else if(CLOSURE_IS_BSSRDF(closure_type)) {
- num_closures += 3;
- }
- else if(CLOSURE_IS_GLASS(closure_type)) {
- num_closures += 2;
- }
- else if(CLOSURE_IS_BSDF_MULTISCATTER(closure_type)) {
- num_closures += 2;
- }
- else if(CLOSURE_IS_PRINCIPLED(closure_type)) {
- num_closures += 8;
- }
- else if(CLOSURE_IS_VOLUME(closure_type)) {
- num_closures += VOLUME_STACK_SIZE;
- }
- else if(closure_type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
- num_closures += 4;
- }
- else {
- ++num_closures;
- }
- }
- return num_closures;
+ int num_closures = 0;
+ foreach (ShaderNode *node, nodes) {
+ ClosureType closure_type = node->get_closure_type();
+ if (closure_type == CLOSURE_NONE_ID) {
+ continue;
+ }
+ else if (CLOSURE_IS_BSSRDF(closure_type)) {
+ num_closures += 3;
+ }
+ else if (CLOSURE_IS_GLASS(closure_type)) {
+ num_closures += 2;
+ }
+ else if (CLOSURE_IS_BSDF_MULTISCATTER(closure_type)) {
+ num_closures += 2;
+ }
+ else if (CLOSURE_IS_PRINCIPLED(closure_type)) {
+ num_closures += 8;
+ }
+ else if (CLOSURE_IS_VOLUME(closure_type)) {
+ num_closures += VOLUME_STACK_SIZE;
+ }
+ else if (closure_type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
+ num_closures += 4;
+ }
+ else {
+ ++num_closures;
+ }
+ }
+ return num_closures;
}
void ShaderGraph::dump_graph(const char *filename)
{
- FILE *fd = fopen(filename, "w");
-
- if(fd == NULL) {
- printf("Error opening file for dumping the graph: %s\n", filename);
- return;
- }
-
- fprintf(fd, "digraph shader_graph {\n");
- fprintf(fd, "ranksep=1.5\n");
- fprintf(fd, "rankdir=LR\n");
- fprintf(fd, "splines=false\n");
-
- foreach(ShaderNode *node, nodes) {
- fprintf(fd, "// NODE: %p\n", node);
- fprintf(fd, "\"%p\" [shape=record,label=\"{", node);
- if(node->inputs.size()) {
- fprintf(fd, "{");
- foreach(ShaderInput *socket, node->inputs) {
- if(socket != node->inputs[0]) {
- fprintf(fd, "|");
- }
- fprintf(fd, "<IN_%p>%s", socket, socket->name().c_str());
- }
- fprintf(fd, "}|");
- }
- fprintf(fd, "%s", node->name.c_str());
- if(node->bump == SHADER_BUMP_CENTER) {
- fprintf(fd, " (bump:center)");
- }
- else if(node->bump == SHADER_BUMP_DX) {
- fprintf(fd, " (bump:dx)");
- }
- else if(node->bump == SHADER_BUMP_DY) {
- fprintf(fd, " (bump:dy)");
- }
- if(node->outputs.size()) {
- fprintf(fd, "|{");
- foreach(ShaderOutput *socket, node->outputs) {
- if(socket != node->outputs[0]) {
- fprintf(fd, "|");
- }
- fprintf(fd, "<OUT_%p>%s", socket, socket->name().c_str());
- }
- fprintf(fd, "}");
- }
- fprintf(fd, "}\"]");
- }
-
- foreach(ShaderNode *node, nodes) {
- foreach(ShaderOutput *output, node->outputs) {
- foreach(ShaderInput *input, output->links) {
- fprintf(fd,
- "// CONNECTION: OUT_%p->IN_%p (%s:%s)\n",
- output,
- input,
- output->name().c_str(), input->name().c_str());
- fprintf(fd,
- "\"%p\":\"OUT_%p\":e -> \"%p\":\"IN_%p\":w [label=\"\"]\n",
- output->parent,
- output,
- input->parent,
- input);
- }
- }
- }
-
- fprintf(fd, "}\n");
- fclose(fd);
+ FILE *fd = fopen(filename, "w");
+
+ if (fd == NULL) {
+ printf("Error opening file for dumping the graph: %s\n", filename);
+ return;
+ }
+
+ fprintf(fd, "digraph shader_graph {\n");
+ fprintf(fd, "ranksep=1.5\n");
+ fprintf(fd, "rankdir=LR\n");
+ fprintf(fd, "splines=false\n");
+
+ foreach (ShaderNode *node, nodes) {
+ fprintf(fd, "// NODE: %p\n", node);
+ fprintf(fd, "\"%p\" [shape=record,label=\"{", node);
+ if (node->inputs.size()) {
+ fprintf(fd, "{");
+ foreach (ShaderInput *socket, node->inputs) {
+ if (socket != node->inputs[0]) {
+ fprintf(fd, "|");
+ }
+ fprintf(fd, "<IN_%p>%s", socket, socket->name().c_str());
+ }
+ fprintf(fd, "}|");
+ }
+ fprintf(fd, "%s", node->name.c_str());
+ if (node->bump == SHADER_BUMP_CENTER) {
+ fprintf(fd, " (bump:center)");
+ }
+ else if (node->bump == SHADER_BUMP_DX) {
+ fprintf(fd, " (bump:dx)");
+ }
+ else if (node->bump == SHADER_BUMP_DY) {
+ fprintf(fd, " (bump:dy)");
+ }
+ if (node->outputs.size()) {
+ fprintf(fd, "|{");
+ foreach (ShaderOutput *socket, node->outputs) {
+ if (socket != node->outputs[0]) {
+ fprintf(fd, "|");
+ }
+ fprintf(fd, "<OUT_%p>%s", socket, socket->name().c_str());
+ }
+ fprintf(fd, "}");
+ }
+ fprintf(fd, "}\"]");
+ }
+
+ foreach (ShaderNode *node, nodes) {
+ foreach (ShaderOutput *output, node->outputs) {
+ foreach (ShaderInput *input, output->links) {
+ fprintf(fd,
+ "// CONNECTION: OUT_%p->IN_%p (%s:%s)\n",
+ output,
+ input,
+ output->name().c_str(),
+ input->name().c_str());
+ fprintf(fd,
+ "\"%p\":\"OUT_%p\":e -> \"%p\":\"IN_%p\":w [label=\"\"]\n",
+ output->parent,
+ output,
+ input->parent,
+ input);
+ }
+ }
+ }
+
+ fprintf(fd, "}\n");
+ fclose(fd);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index d14a59b4900..a2c030fd226 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -49,12 +49,7 @@ class MD5Hash;
* For bump mapping, a node may be evaluated multiple times, using different
* samples to reconstruct the normal, this indicates the sample position */
-enum ShaderBump {
- SHADER_BUMP_NONE,
- SHADER_BUMP_CENTER,
- SHADER_BUMP_DX,
- SHADER_BUMP_DY
-};
+enum ShaderBump { SHADER_BUMP_NONE, SHADER_BUMP_CENTER, SHADER_BUMP_DX, SHADER_BUMP_DY };
/* Identifiers for some special node types.
*
@@ -62,16 +57,16 @@ enum ShaderBump {
* Cannot use dynamic_cast, as this is disabled for OSL. */
enum ShaderNodeSpecialType {
- SHADER_SPECIAL_TYPE_NONE,
- SHADER_SPECIAL_TYPE_PROXY,
- SHADER_SPECIAL_TYPE_AUTOCONVERT,
- SHADER_SPECIAL_TYPE_GEOMETRY,
- SHADER_SPECIAL_TYPE_SCRIPT,
- SHADER_SPECIAL_TYPE_IMAGE_SLOT,
- SHADER_SPECIAL_TYPE_CLOSURE,
- SHADER_SPECIAL_TYPE_COMBINE_CLOSURE,
- SHADER_SPECIAL_TYPE_OUTPUT,
- SHADER_SPECIAL_TYPE_BUMP,
+ SHADER_SPECIAL_TYPE_NONE,
+ SHADER_SPECIAL_TYPE_PROXY,
+ SHADER_SPECIAL_TYPE_AUTOCONVERT,
+ SHADER_SPECIAL_TYPE_GEOMETRY,
+ SHADER_SPECIAL_TYPE_SCRIPT,
+ SHADER_SPECIAL_TYPE_IMAGE_SLOT,
+ SHADER_SPECIAL_TYPE_CLOSURE,
+ SHADER_SPECIAL_TYPE_COMBINE_CLOSURE,
+ SHADER_SPECIAL_TYPE_OUTPUT,
+ SHADER_SPECIAL_TYPE_BUMP,
};
/* Input
@@ -81,22 +76,38 @@ enum ShaderNodeSpecialType {
* coordinate. */
class ShaderInput {
-public:
- ShaderInput(const SocketType& socket_type_, ShaderNode* parent_)
- : socket_type(socket_type_), parent(parent_), link(NULL), stack_offset(SVM_STACK_INVALID)
- {}
-
- ustring name() { return socket_type.ui_name; }
- int flags() { return socket_type.flags; }
- SocketType::Type type() { return socket_type.type; }
-
- void set(float f) { ((Node*)parent)->set(socket_type, f); }
- void set(float3 f) { ((Node*)parent)->set(socket_type, f); }
-
- const SocketType& socket_type;
- ShaderNode *parent;
- ShaderOutput *link;
- int stack_offset; /* for SVM compiler */
+ public:
+ ShaderInput(const SocketType &socket_type_, ShaderNode *parent_)
+ : socket_type(socket_type_), parent(parent_), link(NULL), stack_offset(SVM_STACK_INVALID)
+ {
+ }
+
+ ustring name()
+ {
+ return socket_type.ui_name;
+ }
+ int flags()
+ {
+ return socket_type.flags;
+ }
+ SocketType::Type type()
+ {
+ return socket_type.type;
+ }
+
+ void set(float f)
+ {
+ ((Node *)parent)->set(socket_type, f);
+ }
+ void set(float3 f)
+ {
+ ((Node *)parent)->set(socket_type, f);
+ }
+
+ const SocketType &socket_type;
+ ShaderNode *parent;
+ ShaderOutput *link;
+ int stack_offset; /* for SVM compiler */
};
/* Output
@@ -104,18 +115,25 @@ public:
* Output socket for a shader node. */
class ShaderOutput {
-public:
- ShaderOutput(const SocketType& socket_type_, ShaderNode* parent_)
- : socket_type(socket_type_), parent(parent_), stack_offset(SVM_STACK_INVALID)
- {}
-
- ustring name() { return socket_type.ui_name; }
- SocketType::Type type() { return socket_type.type; }
-
- const SocketType& socket_type;
- ShaderNode *parent;
- vector<ShaderInput*> links;
- int stack_offset; /* for SVM compiler */
+ public:
+ ShaderOutput(const SocketType &socket_type_, ShaderNode *parent_)
+ : socket_type(socket_type_), parent(parent_), stack_offset(SVM_STACK_INVALID)
+ {
+ }
+
+ ustring name()
+ {
+ return socket_type.ui_name;
+ }
+ SocketType::Type type()
+ {
+ return socket_type.type;
+ }
+
+ const SocketType &socket_type;
+ ShaderNode *parent;
+ vector<ShaderInput *> links;
+ int stack_offset; /* for SVM compiler */
};
/* Node
@@ -124,115 +142,163 @@ public:
* base class for all node types. */
class ShaderNode : public Node {
-public:
- explicit ShaderNode(const NodeType *type);
- virtual ~ShaderNode();
-
- void create_inputs_outputs(const NodeType *type);
-
- ShaderInput *input(const char *name);
- ShaderOutput *output(const char *name);
- ShaderInput *input(ustring name);
- ShaderOutput *output(ustring name);
-
- virtual ShaderNode *clone() const = 0;
- virtual void attributes(Shader *shader, AttributeRequestSet *attributes);
- virtual void compile(SVMCompiler& compiler) = 0;
- virtual void compile(OSLCompiler& compiler) = 0;
-
- /* ** Node optimization ** */
- /* Check whether the node can be replaced with single constant. */
- virtual void constant_fold(const ConstantFolder& /*folder*/) {}
-
- /* Simplify settings used by artists to the ones which are simpler to
- * evaluate in the kernel but keep the final result unchanged.
- */
- virtual void simplify_settings(Scene * /*scene*/) {};
-
- virtual bool has_surface_emission() { return false; }
- virtual bool has_surface_transparent() { return false; }
- virtual bool has_surface_bssrdf() { return false; }
- virtual bool has_bump() { return false; }
- virtual bool has_bssrdf_bump() { return false; }
- virtual bool has_spatial_varying() { return false; }
- virtual bool has_object_dependency() { return false; }
- virtual bool has_attribute_dependency() { return false; }
- virtual bool has_integrator_dependency() { return false; }
- virtual bool has_volume_support() { return false; }
- virtual bool has_raytrace() { return false; }
- vector<ShaderInput*> inputs;
- vector<ShaderOutput*> outputs;
-
- int id; /* index in graph node array */
- ShaderBump bump; /* for bump mapping utility */
-
- ShaderNodeSpecialType special_type; /* special node type */
-
- /* ** Selective nodes compilation ** */
-
- /* TODO(sergey): More explicitly mention in the function names
- * that those functions are for selective compilation only?
- */
-
- /* Nodes are split into several groups, group of level 0 contains
- * nodes which are most commonly used, further levels are extension
- * of previous one and includes less commonly used nodes.
- */
- virtual int get_group() { return NODE_GROUP_LEVEL_0; }
-
- /* Node feature are used to disable huge nodes inside the group,
- * so it's possible to disable huge nodes inside of the required
- * nodes group.
- */
- virtual int get_feature() { return bump == SHADER_BUMP_NONE ? 0 : NODE_FEATURE_BUMP; }
-
- /* Get closure ID to which the node compiles into. */
- virtual ClosureType get_closure_type() { return CLOSURE_NONE_ID; }
-
- /* Check whether settings of the node equals to another one.
- *
- * This is mainly used to check whether two nodes can be merged
- * together. Meaning, runtime stuff like node id and unbound slots
- * will be ignored for comparison.
- *
- * NOTE: If some node can't be de-duplicated for whatever reason it
- * is to be handled in the subclass.
- */
- virtual bool equals(const ShaderNode& other);
+ public:
+ explicit ShaderNode(const NodeType *type);
+ virtual ~ShaderNode();
+
+ void create_inputs_outputs(const NodeType *type);
+
+ ShaderInput *input(const char *name);
+ ShaderOutput *output(const char *name);
+ ShaderInput *input(ustring name);
+ ShaderOutput *output(ustring name);
+
+ virtual ShaderNode *clone() const = 0;
+ virtual void attributes(Shader *shader, AttributeRequestSet *attributes);
+ virtual void compile(SVMCompiler &compiler) = 0;
+ virtual void compile(OSLCompiler &compiler) = 0;
+
+ /* ** Node optimization ** */
+ /* Check whether the node can be replaced with single constant. */
+ virtual void constant_fold(const ConstantFolder & /*folder*/)
+ {
+ }
+
+ /* Simplify settings used by artists to the ones which are simpler to
+ * evaluate in the kernel but keep the final result unchanged.
+ */
+ virtual void simplify_settings(Scene * /*scene*/){};
+
+ virtual bool has_surface_emission()
+ {
+ return false;
+ }
+ virtual bool has_surface_transparent()
+ {
+ return false;
+ }
+ virtual bool has_surface_bssrdf()
+ {
+ return false;
+ }
+ virtual bool has_bump()
+ {
+ return false;
+ }
+ virtual bool has_bssrdf_bump()
+ {
+ return false;
+ }
+ virtual bool has_spatial_varying()
+ {
+ return false;
+ }
+ virtual bool has_object_dependency()
+ {
+ return false;
+ }
+ virtual bool has_attribute_dependency()
+ {
+ return false;
+ }
+ virtual bool has_integrator_dependency()
+ {
+ return false;
+ }
+ virtual bool has_volume_support()
+ {
+ return false;
+ }
+ virtual bool has_raytrace()
+ {
+ return false;
+ }
+ vector<ShaderInput *> inputs;
+ vector<ShaderOutput *> outputs;
+
+ int id; /* index in graph node array */
+ ShaderBump bump; /* for bump mapping utility */
+
+ ShaderNodeSpecialType special_type; /* special node type */
+
+ /* ** Selective nodes compilation ** */
+
+ /* TODO(sergey): More explicitly mention in the function names
+ * that those functions are for selective compilation only?
+ */
+
+ /* Nodes are split into several groups, group of level 0 contains
+ * nodes which are most commonly used, further levels are extension
+ * of previous one and includes less commonly used nodes.
+ */
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_0;
+ }
+
+ /* Node feature are used to disable huge nodes inside the group,
+ * so it's possible to disable huge nodes inside of the required
+ * nodes group.
+ */
+ virtual int get_feature()
+ {
+ return bump == SHADER_BUMP_NONE ? 0 : NODE_FEATURE_BUMP;
+ }
+
+ /* Get closure ID to which the node compiles into. */
+ virtual ClosureType get_closure_type()
+ {
+ return CLOSURE_NONE_ID;
+ }
+
+ /* Check whether settings of the node equals to another one.
+ *
+ * This is mainly used to check whether two nodes can be merged
+ * together. Meaning, runtime stuff like node id and unbound slots
+ * will be ignored for comparison.
+ *
+ * NOTE: If some node can't be de-duplicated for whatever reason it
+ * is to be handled in the subclass.
+ */
+ virtual bool equals(const ShaderNode &other);
};
-
/* Node definition utility macros */
#define SHADER_NODE_CLASS(type) \
- NODE_DECLARE \
- type(); \
- virtual ShaderNode *clone() const { return new type(*this); } \
- virtual void compile(SVMCompiler& compiler); \
- virtual void compile(OSLCompiler& compiler); \
+ NODE_DECLARE \
+ type(); \
+ virtual ShaderNode *clone() const \
+ { \
+ return new type(*this); \
+ } \
+ virtual void compile(SVMCompiler &compiler); \
+ virtual void compile(OSLCompiler &compiler);
#define SHADER_NODE_NO_CLONE_CLASS(type) \
- NODE_DECLARE \
- type(); \
- virtual void compile(SVMCompiler& compiler); \
- virtual void compile(OSLCompiler& compiler); \
+ NODE_DECLARE \
+ type(); \
+ virtual void compile(SVMCompiler &compiler); \
+ virtual void compile(OSLCompiler &compiler);
#define SHADER_NODE_BASE_CLASS(type) \
- virtual ShaderNode *clone() const { return new type(*this); } \
- virtual void compile(SVMCompiler& compiler); \
- virtual void compile(OSLCompiler& compiler); \
-
-class ShaderNodeIDComparator
-{
-public:
- bool operator()(const ShaderNode *n1, const ShaderNode *n2) const
- {
- return n1->id < n2->id;
- }
+ virtual ShaderNode *clone() const \
+ { \
+ return new type(*this); \
+ } \
+ virtual void compile(SVMCompiler &compiler); \
+ virtual void compile(OSLCompiler &compiler);
+
+class ShaderNodeIDComparator {
+ public:
+ bool operator()(const ShaderNode *n1, const ShaderNode *n2) const
+ {
+ return n1->id < n2->id;
+ }
};
-typedef set<ShaderNode*, ShaderNodeIDComparator> ShaderNodeSet;
-typedef map<ShaderNode*, ShaderNode*, ShaderNodeIDComparator> ShaderNodeMap;
+typedef set<ShaderNode *, ShaderNodeIDComparator> ShaderNodeSet;
+typedef map<ShaderNode *, ShaderNode *, ShaderNodeIDComparator> ShaderNodeMap;
/* Graph
*
@@ -240,57 +306,57 @@ typedef map<ShaderNode*, ShaderNode*, ShaderNodeIDComparator> ShaderNodeMap;
* bump mapping from displacement, and possibly other things in the future. */
class ShaderGraph {
-public:
- list<ShaderNode*> nodes;
- size_t num_node_ids;
- bool finalized;
- bool simplified;
- string displacement_hash;
-
- ShaderGraph();
- ~ShaderGraph();
-
- ShaderNode *add(ShaderNode *node);
- OutputNode *output();
-
- void connect(ShaderOutput *from, ShaderInput *to);
- void disconnect(ShaderOutput *from);
- void disconnect(ShaderInput *to);
- void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
-
- void remove_proxy_nodes();
- void compute_displacement_hash();
- void simplify(Scene *scene);
- void finalize(Scene *scene,
- bool do_bump = false,
- bool do_simplify = false,
- bool bump_in_object_space = false);
-
- int get_num_closures();
-
- void dump_graph(const char *filename);
-
-protected:
- typedef pair<ShaderNode* const, ShaderNode*> NodePair;
-
- void find_dependencies(ShaderNodeSet& dependencies, ShaderInput *input);
- void clear_nodes();
- void copy_nodes(ShaderNodeSet& nodes, ShaderNodeMap& nnodemap);
-
- void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
- void bump_from_displacement(bool use_object_space);
- void refine_bump_nodes();
- void default_inputs(bool do_osl);
- void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
-
- /* Graph simplification routines. */
- void clean(Scene *scene);
- void constant_fold(Scene *scene);
- void simplify_settings(Scene *scene);
- void deduplicate_nodes();
- void verify_volume_output();
+ public:
+ list<ShaderNode *> nodes;
+ size_t num_node_ids;
+ bool finalized;
+ bool simplified;
+ string displacement_hash;
+
+ ShaderGraph();
+ ~ShaderGraph();
+
+ ShaderNode *add(ShaderNode *node);
+ OutputNode *output();
+
+ void connect(ShaderOutput *from, ShaderInput *to);
+ void disconnect(ShaderOutput *from);
+ void disconnect(ShaderInput *to);
+ void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
+
+ void remove_proxy_nodes();
+ void compute_displacement_hash();
+ void simplify(Scene *scene);
+ void finalize(Scene *scene,
+ bool do_bump = false,
+ bool do_simplify = false,
+ bool bump_in_object_space = false);
+
+ int get_num_closures();
+
+ void dump_graph(const char *filename);
+
+ protected:
+ typedef pair<ShaderNode *const, ShaderNode *> NodePair;
+
+ void find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input);
+ void clear_nodes();
+ void copy_nodes(ShaderNodeSet &nodes, ShaderNodeMap &nnodemap);
+
+ void break_cycles(ShaderNode *node, vector<bool> &visited, vector<bool> &on_stack);
+ void bump_from_displacement(bool use_object_space);
+ void refine_bump_nodes();
+ void default_inputs(bool do_osl);
+ void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
+
+ /* Graph simplification routines. */
+ void clean(Scene *scene);
+ void constant_fold(Scene *scene);
+ void simplify_settings(Scene *scene);
+ void deduplicate_nodes();
+ void verify_volume_output();
};
CCL_NAMESPACE_END
-#endif /* __GRAPH_H__ */
+#endif /* __GRAPH_H__ */
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 1edd5865836..ae219e912e0 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -27,7 +27,7 @@
#include "util/util_unique_ptr.h"
#ifdef WITH_OSL
-#include <OSL/oslexec.h>
+# include <OSL/oslexec.h>
#endif
CCL_NAMESPACE_BEGIN
@@ -37,15 +37,15 @@ namespace {
/* Some helpers to silence warning in templated function. */
bool isfinite(uchar /*value*/)
{
- return true;
+ return true;
}
bool isfinite(half /*value*/)
{
- return true;
+ return true;
}
-bool isfinite(uint16_t /*value*/)
+bool isfinite(uint16_t /*value*/)
{
- return true;
+ return true;
}
/* The lower three bits of a device texture slot number indicate its type.
@@ -54,946 +54,888 @@ bool isfinite(uint16_t /*value*/)
*/
int type_index_to_flattened_slot(int slot, ImageDataType type)
{
- return (slot << IMAGE_DATA_TYPE_SHIFT) | (type);
+ return (slot << IMAGE_DATA_TYPE_SHIFT) | (type);
}
int flattened_slot_to_type_index(int flat_slot, ImageDataType *type)
{
- *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK);
- return flat_slot >> IMAGE_DATA_TYPE_SHIFT;
+ *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK);
+ return flat_slot >> IMAGE_DATA_TYPE_SHIFT;
}
-const char* name_from_type(ImageDataType type)
+const char *name_from_type(ImageDataType type)
{
- switch(type) {
- case IMAGE_DATA_TYPE_FLOAT4: return "float4";
- case IMAGE_DATA_TYPE_BYTE4: return "byte4";
- case IMAGE_DATA_TYPE_HALF4: return "half4";
- case IMAGE_DATA_TYPE_FLOAT: return "float";
- case IMAGE_DATA_TYPE_BYTE: return "byte";
- case IMAGE_DATA_TYPE_HALF: return "half";
- case IMAGE_DATA_TYPE_USHORT4: return "ushort4";
- case IMAGE_DATA_TYPE_USHORT: return "ushort";
- case IMAGE_DATA_NUM_TYPES:
- assert(!"System enumerator type, should never be used");
- return "";
- }
- assert(!"Unhandled image data type");
- return "";
+ switch (type) {
+ case IMAGE_DATA_TYPE_FLOAT4:
+ return "float4";
+ case IMAGE_DATA_TYPE_BYTE4:
+ return "byte4";
+ case IMAGE_DATA_TYPE_HALF4:
+ return "half4";
+ case IMAGE_DATA_TYPE_FLOAT:
+ return "float";
+ case IMAGE_DATA_TYPE_BYTE:
+ return "byte";
+ case IMAGE_DATA_TYPE_HALF:
+ return "half";
+ case IMAGE_DATA_TYPE_USHORT4:
+ return "ushort4";
+ case IMAGE_DATA_TYPE_USHORT:
+ return "ushort";
+ case IMAGE_DATA_NUM_TYPES:
+ assert(!"System enumerator type, should never be used");
+ return "";
+ }
+ assert(!"Unhandled image data type");
+ return "";
}
} // namespace
-ImageManager::ImageManager(const DeviceInfo& info)
+ImageManager::ImageManager(const DeviceInfo &info)
{
- need_update = true;
- osl_texture_system = NULL;
- animation_frame = 0;
+ need_update = true;
+ osl_texture_system = NULL;
+ animation_frame = 0;
- /* Set image limits */
- max_num_images = TEX_NUM_MAX;
- has_half_images = info.has_half_images;
+ /* Set image limits */
+ max_num_images = TEX_NUM_MAX;
+ has_half_images = info.has_half_images;
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- tex_num_images[type] = 0;
- }
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ tex_num_images[type] = 0;
+ }
}
ImageManager::~ImageManager()
{
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++)
- assert(!images[type][slot]);
- }
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++)
+ assert(!images[type][slot]);
+ }
}
void ImageManager::set_osl_texture_system(void *texture_system)
{
- osl_texture_system = texture_system;
+ osl_texture_system = texture_system;
}
bool ImageManager::set_animation_frame_update(int frame)
{
- if(frame != animation_frame) {
- animation_frame = frame;
-
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && images[type][slot]->animated)
- return true;
- }
- }
- }
-
- return false;
+ if (frame != animation_frame) {
+ animation_frame = frame;
+
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] && images[type][slot]->animated)
+ return true;
+ }
+ }
+ }
+
+ return false;
}
device_memory *ImageManager::image_memory(int flat_slot)
{
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
- Image *img = images[type][slot];
+ Image *img = images[type][slot];
- return img->mem;
+ return img->mem;
}
-bool ImageManager::get_image_metadata(int flat_slot,
- ImageMetaData& metadata)
+bool ImageManager::get_image_metadata(int flat_slot, ImageMetaData &metadata)
{
- if(flat_slot == -1) {
- return false;
- }
+ if (flat_slot == -1) {
+ return false;
+ }
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
- Image *img = images[type][slot];
- if(img) {
- metadata = img->metadata;
- return true;
- }
+ Image *img = images[type][slot];
+ if (img) {
+ metadata = img->metadata;
+ return true;
+ }
- return false;
+ return false;
}
-bool ImageManager::get_image_metadata(const string& filename,
+bool ImageManager::get_image_metadata(const string &filename,
void *builtin_data,
- ImageMetaData& metadata)
+ ImageMetaData &metadata)
{
- memset(&metadata, 0, sizeof(metadata));
-
- if(builtin_data) {
- if(builtin_image_info_cb) {
- builtin_image_info_cb(filename, builtin_data, metadata);
- }
- else {
- return false;
- }
-
- if(metadata.is_float) {
- metadata.is_linear = true;
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4
- : IMAGE_DATA_TYPE_FLOAT;
- }
- else {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4
- : IMAGE_DATA_TYPE_BYTE;
- }
-
- return true;
- }
-
- /* Perform preliminary checks, with meaningful logging. */
- if(!path_exists(filename)) {
- VLOG(1) << "File '" << filename << "' does not exist.";
- return false;
- }
- if(path_is_directory(filename)) {
- VLOG(1) << "File '" << filename
- << "' is a directory, can't use as image.";
- return false;
- }
-
- unique_ptr<ImageInput> in(ImageInput::create(filename));
-
- if(!in) {
- return false;
- }
-
- ImageSpec spec;
- if(!in->open(filename, spec)) {
- return false;
- }
-
- metadata.width = spec.width;
- metadata.height = spec.height;
- metadata.depth = spec.depth;
-
-
- /* Check the main format, and channel formats. */
- size_t channel_size = spec.format.basesize();
-
- if(spec.format.is_floating_point()) {
- metadata.is_float = true;
- metadata.is_linear = true;
- }
-
- for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
- channel_size = max(channel_size, spec.channelformats[channel].basesize());
- if(spec.channelformats[channel].is_floating_point()) {
- metadata.is_float = true;
- metadata.is_linear = true;
- }
- }
-
- /* check if it's half float */
- if(spec.format == TypeDesc::HALF) {
- metadata.is_half = true;
- }
-
- /* basic color space detection, not great but better than nothing
- * before we do OpenColorIO integration */
- if(metadata.is_float) {
- string colorspace = spec.get_string_attribute("oiio:ColorSpace");
-
- metadata.is_linear = !(colorspace == "sRGB" ||
- colorspace == "GammaCorrected" ||
- (colorspace == "" &&
- (strcmp(in->format_name(), "png") == 0 ||
- strcmp(in->format_name(), "tiff") == 0 ||
- strcmp(in->format_name(), "dpx") == 0 ||
- strcmp(in->format_name(), "jpeg2000") == 0)));
- }
- else {
- metadata.is_linear = false;
- }
-
- /* set type and channels */
- metadata.channels = spec.nchannels;
-
- if(metadata.is_half) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4
- : IMAGE_DATA_TYPE_HALF;
- }
- else if(metadata.is_float) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4
- : IMAGE_DATA_TYPE_FLOAT;
- }
- else if(spec.format == TypeDesc::USHORT) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4
- : IMAGE_DATA_TYPE_USHORT;
- }
- else {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4
- : IMAGE_DATA_TYPE_BYTE;
- }
-
- in->close();
-
- return true;
+ memset(&metadata, 0, sizeof(metadata));
+
+ if (builtin_data) {
+ if (builtin_image_info_cb) {
+ builtin_image_info_cb(filename, builtin_data, metadata);
+ }
+ else {
+ return false;
+ }
+
+ if (metadata.is_float) {
+ metadata.is_linear = true;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
+ }
+ else {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
+ }
+
+ return true;
+ }
+
+ /* Perform preliminary checks, with meaningful logging. */
+ if (!path_exists(filename)) {
+ VLOG(1) << "File '" << filename << "' does not exist.";
+ return false;
+ }
+ if (path_is_directory(filename)) {
+ VLOG(1) << "File '" << filename << "' is a directory, can't use as image.";
+ return false;
+ }
+
+ unique_ptr<ImageInput> in(ImageInput::create(filename));
+
+ if (!in) {
+ return false;
+ }
+
+ ImageSpec spec;
+ if (!in->open(filename, spec)) {
+ return false;
+ }
+
+ metadata.width = spec.width;
+ metadata.height = spec.height;
+ metadata.depth = spec.depth;
+
+ /* Check the main format, and channel formats. */
+ size_t channel_size = spec.format.basesize();
+
+ if (spec.format.is_floating_point()) {
+ metadata.is_float = true;
+ metadata.is_linear = true;
+ }
+
+ for (size_t channel = 0; channel < spec.channelformats.size(); channel++) {
+ channel_size = max(channel_size, spec.channelformats[channel].basesize());
+ if (spec.channelformats[channel].is_floating_point()) {
+ metadata.is_float = true;
+ metadata.is_linear = true;
+ }
+ }
+
+ /* check if it's half float */
+ if (spec.format == TypeDesc::HALF) {
+ metadata.is_half = true;
+ }
+
+ /* basic color space detection, not great but better than nothing
+ * before we do OpenColorIO integration */
+ if (metadata.is_float) {
+ string colorspace = spec.get_string_attribute("oiio:ColorSpace");
+
+ metadata.is_linear = !(
+ colorspace == "sRGB" || colorspace == "GammaCorrected" ||
+ (colorspace == "" &&
+ (strcmp(in->format_name(), "png") == 0 || strcmp(in->format_name(), "tiff") == 0 ||
+ strcmp(in->format_name(), "dpx") == 0 || strcmp(in->format_name(), "jpeg2000") == 0)));
+ }
+ else {
+ metadata.is_linear = false;
+ }
+
+ /* set type and channels */
+ metadata.channels = spec.nchannels;
+
+ if (metadata.is_half) {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
+ }
+ else if (metadata.is_float) {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
+ }
+ else if (spec.format == TypeDesc::USHORT) {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT;
+ }
+ else {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
+ }
+
+ in->close();
+
+ return true;
}
static bool image_equals(ImageManager::Image *image,
- const string& filename,
+ const string &filename,
void *builtin_data,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha)
{
- return image->filename == filename &&
- image->builtin_data == builtin_data &&
- image->interpolation == interpolation &&
- image->extension == extension &&
- image->use_alpha == use_alpha;
+ return image->filename == filename && image->builtin_data == builtin_data &&
+ image->interpolation == interpolation && image->extension == extension &&
+ image->use_alpha == use_alpha;
}
-int ImageManager::add_image(const string& filename,
+int ImageManager::add_image(const string &filename,
void *builtin_data,
bool animated,
float frame,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha,
- ImageMetaData& metadata)
+ ImageMetaData &metadata)
{
- Image *img;
- size_t slot;
-
- get_image_metadata(filename, builtin_data, metadata);
- ImageDataType type = metadata.type;
-
- thread_scoped_lock device_lock(device_mutex);
-
- /* No half textures on OpenCL, use full float instead. */
- if(!has_half_images) {
- if(type == IMAGE_DATA_TYPE_HALF4) {
- type = IMAGE_DATA_TYPE_FLOAT4;
- }
- else if(type == IMAGE_DATA_TYPE_HALF) {
- type = IMAGE_DATA_TYPE_FLOAT;
- }
- }
-
- /* Fnd existing image. */
- for(slot = 0; slot < images[type].size(); slot++) {
- img = images[type][slot];
- if(img && image_equals(img,
- filename,
- builtin_data,
- interpolation,
- extension,
- use_alpha))
- {
- if(img->frame != frame) {
- img->frame = frame;
- img->need_load = true;
- }
- if(img->use_alpha != use_alpha) {
- img->use_alpha = use_alpha;
- img->need_load = true;
- }
- if(!(img->metadata == metadata)) {
- img->metadata = metadata;
- img->need_load = true;
- }
- img->users++;
- return type_index_to_flattened_slot(slot, type);
- }
- }
-
- /* Find free slot. */
- for(slot = 0; slot < images[type].size(); slot++) {
- if(!images[type][slot])
- break;
- }
-
- /* Count if we're over the limit.
- * Very unlikely, since max_num_images is insanely big. But better safe
- * than sorry.
- */
- int tex_count = 0;
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- tex_count += tex_num_images[type];
- }
- if(tex_count > max_num_images) {
- printf("ImageManager::add_image: Reached image limit (%d), "
- "skipping '%s'\n", max_num_images, filename.c_str());
- return -1;
- }
-
- if(slot == images[type].size()) {
- images[type].resize(images[type].size() + 1);
- }
-
- /* Add new image. */
- img = new Image();
- img->filename = filename;
- img->builtin_data = builtin_data;
- img->metadata = metadata;
- img->need_load = true;
- img->animated = animated;
- img->frame = frame;
- img->interpolation = interpolation;
- img->extension = extension;
- img->users = 1;
- img->use_alpha = use_alpha;
- img->mem = NULL;
-
- images[type][slot] = img;
-
- ++tex_num_images[type];
-
- need_update = true;
-
- return type_index_to_flattened_slot(slot, type);
+ Image *img;
+ size_t slot;
+
+ get_image_metadata(filename, builtin_data, metadata);
+ ImageDataType type = metadata.type;
+
+ thread_scoped_lock device_lock(device_mutex);
+
+ /* No half textures on OpenCL, use full float instead. */
+ if (!has_half_images) {
+ if (type == IMAGE_DATA_TYPE_HALF4) {
+ type = IMAGE_DATA_TYPE_FLOAT4;
+ }
+ else if (type == IMAGE_DATA_TYPE_HALF) {
+ type = IMAGE_DATA_TYPE_FLOAT;
+ }
+ }
+
+ /* Fnd existing image. */
+ for (slot = 0; slot < images[type].size(); slot++) {
+ img = images[type][slot];
+ if (img && image_equals(img, filename, builtin_data, interpolation, extension, use_alpha)) {
+ if (img->frame != frame) {
+ img->frame = frame;
+ img->need_load = true;
+ }
+ if (img->use_alpha != use_alpha) {
+ img->use_alpha = use_alpha;
+ img->need_load = true;
+ }
+ if (!(img->metadata == metadata)) {
+ img->metadata = metadata;
+ img->need_load = true;
+ }
+ img->users++;
+ return type_index_to_flattened_slot(slot, type);
+ }
+ }
+
+ /* Find free slot. */
+ for (slot = 0; slot < images[type].size(); slot++) {
+ if (!images[type][slot])
+ break;
+ }
+
+ /* Count if we're over the limit.
+ * Very unlikely, since max_num_images is insanely big. But better safe
+ * than sorry.
+ */
+ int tex_count = 0;
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ tex_count += tex_num_images[type];
+ }
+ if (tex_count > max_num_images) {
+ printf(
+ "ImageManager::add_image: Reached image limit (%d), "
+ "skipping '%s'\n",
+ max_num_images,
+ filename.c_str());
+ return -1;
+ }
+
+ if (slot == images[type].size()) {
+ images[type].resize(images[type].size() + 1);
+ }
+
+ /* Add new image. */
+ img = new Image();
+ img->filename = filename;
+ img->builtin_data = builtin_data;
+ img->metadata = metadata;
+ img->need_load = true;
+ img->animated = animated;
+ img->frame = frame;
+ img->interpolation = interpolation;
+ img->extension = extension;
+ img->users = 1;
+ img->use_alpha = use_alpha;
+ img->mem = NULL;
+
+ images[type][slot] = img;
+
+ ++tex_num_images[type];
+
+ need_update = true;
+
+ return type_index_to_flattened_slot(slot, type);
}
void ImageManager::remove_image(int flat_slot)
{
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
- Image *image = images[type][slot];
- assert(image && image->users >= 1);
+ Image *image = images[type][slot];
+ assert(image && image->users >= 1);
- /* decrement user count */
- image->users--;
+ /* decrement user count */
+ image->users--;
- /* don't remove immediately, rather do it all together later on. one of
- * the reasons for this is that on shader changes we add and remove nodes
- * that use them, but we do not want to reload the image all the time. */
- if(image->users == 0)
- need_update = true;
+ /* don't remove immediately, rather do it all together later on. one of
+ * the reasons for this is that on shader changes we add and remove nodes
+ * that use them, but we do not want to reload the image all the time. */
+ if (image->users == 0)
+ need_update = true;
}
-void ImageManager::remove_image(const string& filename,
+void ImageManager::remove_image(const string &filename,
void *builtin_data,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha)
{
- size_t slot;
-
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && image_equals(images[type][slot],
- filename,
- builtin_data,
- interpolation,
- extension,
- use_alpha))
- {
- remove_image(type_index_to_flattened_slot(slot, (ImageDataType)type));
- return;
- }
- }
- }
+ size_t slot;
+
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] &&
+ image_equals(
+ images[type][slot], filename, builtin_data, interpolation, extension, use_alpha)) {
+ remove_image(type_index_to_flattened_slot(slot, (ImageDataType)type));
+ return;
+ }
+ }
+ }
}
/* TODO(sergey): Deduplicate with the iteration above, but make it pretty,
* without bunch of arguments passing around making code readability even
* more cluttered.
*/
-void ImageManager::tag_reload_image(const string& filename,
+void ImageManager::tag_reload_image(const string &filename,
void *builtin_data,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha)
{
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && image_equals(images[type][slot],
- filename,
- builtin_data,
- interpolation,
- extension,
- use_alpha))
- {
- images[type][slot]->need_load = true;
- break;
- }
- }
- }
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] &&
+ image_equals(
+ images[type][slot], filename, builtin_data, interpolation, extension, use_alpha)) {
+ images[type][slot]->need_load = true;
+ break;
+ }
+ }
+ }
}
-bool ImageManager::file_load_image_generic(Image *img,
- unique_ptr<ImageInput> *in)
+bool ImageManager::file_load_image_generic(Image *img, unique_ptr<ImageInput> *in)
{
- if(img->filename == "")
- return false;
-
- if(!img->builtin_data) {
- /* NOTE: Error logging is done in meta data acquisition. */
- if(!path_exists(img->filename) || path_is_directory(img->filename)) {
- return false;
- }
-
- /* load image from file through OIIO */
- *in = unique_ptr<ImageInput>(ImageInput::create(img->filename));
-
- if(!*in)
- return false;
-
- ImageSpec spec = ImageSpec();
- ImageSpec config = ImageSpec();
-
- if(img->use_alpha == false)
- config.attribute("oiio:UnassociatedAlpha", 1);
-
- if(!(*in)->open(img->filename, spec, config)) {
- return false;
- }
- }
- else {
- /* load image using builtin images callbacks */
- if(!builtin_image_info_cb || !builtin_image_pixels_cb)
- return false;
- }
-
- /* we only handle certain number of components */
- if(!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
- if(*in) {
- (*in)->close();
- }
- return false;
- }
-
- return true;
+ if (img->filename == "")
+ return false;
+
+ if (!img->builtin_data) {
+ /* NOTE: Error logging is done in meta data acquisition. */
+ if (!path_exists(img->filename) || path_is_directory(img->filename)) {
+ return false;
+ }
+
+ /* load image from file through OIIO */
+ *in = unique_ptr<ImageInput>(ImageInput::create(img->filename));
+
+ if (!*in)
+ return false;
+
+ ImageSpec spec = ImageSpec();
+ ImageSpec config = ImageSpec();
+
+ if (img->use_alpha == false)
+ config.attribute("oiio:UnassociatedAlpha", 1);
+
+ if (!(*in)->open(img->filename, spec, config)) {
+ return false;
+ }
+ }
+ else {
+ /* load image using builtin images callbacks */
+ if (!builtin_image_info_cb || !builtin_image_pixels_cb)
+ return false;
+ }
+
+ /* we only handle certain number of components */
+ if (!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
+ if (*in) {
+ (*in)->close();
+ }
+ return false;
+ }
+
+ return true;
}
-template<TypeDesc::BASETYPE FileFormat,
- typename StorageType,
- typename DeviceType>
+template<TypeDesc::BASETYPE FileFormat, typename StorageType, typename DeviceType>
bool ImageManager::file_load_image(Image *img,
ImageDataType type,
int texture_limit,
- device_vector<DeviceType>& tex_img)
+ device_vector<DeviceType> &tex_img)
{
- unique_ptr<ImageInput> in = NULL;
- if(!file_load_image_generic(img, &in)) {
- return false;
- }
-
- /* Get metadata. */
- int width = img->metadata.width;
- int height = img->metadata.height;
- int depth = img->metadata.depth;
- int components = img->metadata.channels;
-
- /* Read RGBA pixels. */
- vector<StorageType> pixels_storage;
- StorageType *pixels;
- const size_t max_size = max(max(width, height), depth);
- if(max_size == 0) {
- /* Don't bother with invalid images. */
- return false;
- }
- if(texture_limit > 0 && max_size > texture_limit) {
- pixels_storage.resize(((size_t)width)*height*depth*4);
- pixels = &pixels_storage[0];
- }
- else {
- thread_scoped_lock device_lock(device_mutex);
- pixels = (StorageType*)tex_img.alloc(width, height, depth);
- }
- if(pixels == NULL) {
- /* Could be that we've run out of memory. */
- return false;
- }
- bool cmyk = false;
- const size_t num_pixels = ((size_t)width) * height * depth;
- if(in) {
- StorageType *readpixels = pixels;
- vector<StorageType> tmppixels;
- if(components > 4) {
- tmppixels.resize(((size_t)width)*height*components);
- readpixels = &tmppixels[0];
- }
- if(depth <= 1) {
- size_t scanlinesize = ((size_t)width)*components*sizeof(StorageType);
- in->read_image(FileFormat,
- (uchar*)readpixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
- }
- else {
- in->read_image(FileFormat, (uchar*)readpixels);
- }
- if(components > 4) {
- size_t dimensions = ((size_t)width)*height;
- for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
- pixels[i*4+3] = tmppixels[i*components+3];
- pixels[i*4+2] = tmppixels[i*components+2];
- pixels[i*4+1] = tmppixels[i*components+1];
- pixels[i*4+0] = tmppixels[i*components+0];
- }
- tmppixels.clear();
- }
- cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
- in->close();
- }
- else {
- if(FileFormat == TypeDesc::FLOAT) {
- builtin_image_float_pixels_cb(img->filename,
- img->builtin_data,
- (float*)&pixels[0],
- num_pixels * components,
- img->metadata.builtin_free_cache);
- }
- else if(FileFormat == TypeDesc::UINT8) {
- builtin_image_pixels_cb(img->filename,
- img->builtin_data,
- (uchar*)&pixels[0],
- num_pixels * components,
- img->metadata.builtin_free_cache);
- }
- else {
- /* TODO(dingto): Support half for ImBuf. */
- }
- }
- /* Check if we actually have a float4 slot, in case components == 1,
- * but device doesn't support single channel textures.
- */
- bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
- type == IMAGE_DATA_TYPE_HALF4 ||
- type == IMAGE_DATA_TYPE_BYTE4 ||
- type == IMAGE_DATA_TYPE_USHORT4);
- if(is_rgba) {
- const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
-
- if(cmyk) {
- /* CMYK */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- float c = util_image_cast_to_float(pixels[i*4+0]);
- float m = util_image_cast_to_float(pixels[i*4+1]);
- float y = util_image_cast_to_float(pixels[i*4+2]);
- float k = util_image_cast_to_float(pixels[i*4+3]);
- pixels[i*4+0] = util_image_cast_from_float<StorageType>((1.0f - c) * (1.0f - k));
- pixels[i*4+1] = util_image_cast_from_float<StorageType>((1.0f - m) * (1.0f - k));
- pixels[i*4+2] = util_image_cast_from_float<StorageType>((1.0f - y) * (1.0f - k));
- pixels[i*4+3] = one;
- }
- }
- else if(components == 2) {
- /* grayscale + alpha */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = pixels[i*2+1];
- pixels[i*4+2] = pixels[i*2+0];
- pixels[i*4+1] = pixels[i*2+0];
- pixels[i*4+0] = pixels[i*2+0];
- }
- }
- else if(components == 3) {
- /* RGB */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = one;
- pixels[i*4+2] = pixels[i*3+2];
- pixels[i*4+1] = pixels[i*3+1];
- pixels[i*4+0] = pixels[i*3+0];
- }
- }
- else if(components == 1) {
- /* grayscale */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = one;
- pixels[i*4+2] = pixels[i];
- pixels[i*4+1] = pixels[i];
- pixels[i*4+0] = pixels[i];
- }
- }
- if(img->use_alpha == false) {
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = one;
- }
- }
- }
- /* Make sure we don't have buggy values. */
- if(FileFormat == TypeDesc::FLOAT) {
- /* For RGBA buffers we put all channels to 0 if either of them is not
- * finite. This way we avoid possible artifacts caused by fully changed
- * hue.
- */
- if(is_rgba) {
- for(size_t i = 0; i < num_pixels; i += 4) {
- StorageType *pixel = &pixels[i*4];
- if(!isfinite(pixel[0]) ||
- !isfinite(pixel[1]) ||
- !isfinite(pixel[2]) ||
- !isfinite(pixel[3]))
- {
- pixel[0] = 0;
- pixel[1] = 0;
- pixel[2] = 0;
- pixel[3] = 0;
- }
- }
- }
- else {
- for(size_t i = 0; i < num_pixels; ++i) {
- StorageType *pixel = &pixels[i];
- if(!isfinite(pixel[0])) {
- pixel[0] = 0;
- }
- }
- }
- }
- /* Scale image down if needed. */
- if(pixels_storage.size() > 0) {
- float scale_factor = 1.0f;
- while(max_size * scale_factor > texture_limit) {
- scale_factor *= 0.5f;
- }
- VLOG(1) << "Scaling image " << img->filename
- << " by a factor of " << scale_factor << ".";
- vector<StorageType> scaled_pixels;
- size_t scaled_width, scaled_height, scaled_depth;
- util_image_resize_pixels(pixels_storage,
- width, height, depth,
- is_rgba ? 4 : 1,
- scale_factor,
- &scaled_pixels,
- &scaled_width, &scaled_height, &scaled_depth);
-
- StorageType *texture_pixels;
-
- {
- thread_scoped_lock device_lock(device_mutex);
- texture_pixels = (StorageType*)tex_img.alloc(scaled_width,
- scaled_height,
- scaled_depth);
- }
-
- memcpy(texture_pixels,
- &scaled_pixels[0],
- scaled_pixels.size() * sizeof(StorageType));
- }
- return true;
+ unique_ptr<ImageInput> in = NULL;
+ if (!file_load_image_generic(img, &in)) {
+ return false;
+ }
+
+ /* Get metadata. */
+ int width = img->metadata.width;
+ int height = img->metadata.height;
+ int depth = img->metadata.depth;
+ int components = img->metadata.channels;
+
+ /* Read RGBA pixels. */
+ vector<StorageType> pixels_storage;
+ StorageType *pixels;
+ const size_t max_size = max(max(width, height), depth);
+ if (max_size == 0) {
+ /* Don't bother with invalid images. */
+ return false;
+ }
+ if (texture_limit > 0 && max_size > texture_limit) {
+ pixels_storage.resize(((size_t)width) * height * depth * 4);
+ pixels = &pixels_storage[0];
+ }
+ else {
+ thread_scoped_lock device_lock(device_mutex);
+ pixels = (StorageType *)tex_img.alloc(width, height, depth);
+ }
+ if (pixels == NULL) {
+ /* Could be that we've run out of memory. */
+ return false;
+ }
+ bool cmyk = false;
+ const size_t num_pixels = ((size_t)width) * height * depth;
+ if (in) {
+ StorageType *readpixels = pixels;
+ vector<StorageType> tmppixels;
+ if (components > 4) {
+ tmppixels.resize(((size_t)width) * height * components);
+ readpixels = &tmppixels[0];
+ }
+ if (depth <= 1) {
+ size_t scanlinesize = ((size_t)width) * components * sizeof(StorageType);
+ in->read_image(FileFormat,
+ (uchar *)readpixels + (height - 1) * scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
+ }
+ else {
+ in->read_image(FileFormat, (uchar *)readpixels);
+ }
+ if (components > 4) {
+ size_t dimensions = ((size_t)width) * height;
+ for (size_t i = dimensions - 1, pixel = 0; pixel < dimensions; pixel++, i--) {
+ pixels[i * 4 + 3] = tmppixels[i * components + 3];
+ pixels[i * 4 + 2] = tmppixels[i * components + 2];
+ pixels[i * 4 + 1] = tmppixels[i * components + 1];
+ pixels[i * 4 + 0] = tmppixels[i * components + 0];
+ }
+ tmppixels.clear();
+ }
+ cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
+ in->close();
+ }
+ else {
+ if (FileFormat == TypeDesc::FLOAT) {
+ builtin_image_float_pixels_cb(img->filename,
+ img->builtin_data,
+ (float *)&pixels[0],
+ num_pixels * components,
+ img->metadata.builtin_free_cache);
+ }
+ else if (FileFormat == TypeDesc::UINT8) {
+ builtin_image_pixels_cb(img->filename,
+ img->builtin_data,
+ (uchar *)&pixels[0],
+ num_pixels * components,
+ img->metadata.builtin_free_cache);
+ }
+ else {
+ /* TODO(dingto): Support half for ImBuf. */
+ }
+ }
+ /* Check if we actually have a float4 slot, in case components == 1,
+ * but device doesn't support single channel textures.
+ */
+ bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 || type == IMAGE_DATA_TYPE_HALF4 ||
+ type == IMAGE_DATA_TYPE_BYTE4 || type == IMAGE_DATA_TYPE_USHORT4);
+ if (is_rgba) {
+ const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
+
+ if (cmyk) {
+ /* CMYK */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ float c = util_image_cast_to_float(pixels[i * 4 + 0]);
+ float m = util_image_cast_to_float(pixels[i * 4 + 1]);
+ float y = util_image_cast_to_float(pixels[i * 4 + 2]);
+ float k = util_image_cast_to_float(pixels[i * 4 + 3]);
+ pixels[i * 4 + 0] = util_image_cast_from_float<StorageType>((1.0f - c) * (1.0f - k));
+ pixels[i * 4 + 1] = util_image_cast_from_float<StorageType>((1.0f - m) * (1.0f - k));
+ pixels[i * 4 + 2] = util_image_cast_from_float<StorageType>((1.0f - y) * (1.0f - k));
+ pixels[i * 4 + 3] = one;
+ }
+ }
+ else if (components == 2) {
+ /* grayscale + alpha */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = pixels[i * 2 + 1];
+ pixels[i * 4 + 2] = pixels[i * 2 + 0];
+ pixels[i * 4 + 1] = pixels[i * 2 + 0];
+ pixels[i * 4 + 0] = pixels[i * 2 + 0];
+ }
+ }
+ else if (components == 3) {
+ /* RGB */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = one;
+ pixels[i * 4 + 2] = pixels[i * 3 + 2];
+ pixels[i * 4 + 1] = pixels[i * 3 + 1];
+ pixels[i * 4 + 0] = pixels[i * 3 + 0];
+ }
+ }
+ else if (components == 1) {
+ /* grayscale */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = one;
+ pixels[i * 4 + 2] = pixels[i];
+ pixels[i * 4 + 1] = pixels[i];
+ pixels[i * 4 + 0] = pixels[i];
+ }
+ }
+ if (img->use_alpha == false) {
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = one;
+ }
+ }
+ }
+ /* Make sure we don't have buggy values. */
+ if (FileFormat == TypeDesc::FLOAT) {
+ /* For RGBA buffers we put all channels to 0 if either of them is not
+ * finite. This way we avoid possible artifacts caused by fully changed
+ * hue.
+ */
+ if (is_rgba) {
+ for (size_t i = 0; i < num_pixels; i += 4) {
+ StorageType *pixel = &pixels[i * 4];
+ if (!isfinite(pixel[0]) || !isfinite(pixel[1]) || !isfinite(pixel[2]) ||
+ !isfinite(pixel[3])) {
+ pixel[0] = 0;
+ pixel[1] = 0;
+ pixel[2] = 0;
+ pixel[3] = 0;
+ }
+ }
+ }
+ else {
+ for (size_t i = 0; i < num_pixels; ++i) {
+ StorageType *pixel = &pixels[i];
+ if (!isfinite(pixel[0])) {
+ pixel[0] = 0;
+ }
+ }
+ }
+ }
+ /* Scale image down if needed. */
+ if (pixels_storage.size() > 0) {
+ float scale_factor = 1.0f;
+ while (max_size * scale_factor > texture_limit) {
+ scale_factor *= 0.5f;
+ }
+ VLOG(1) << "Scaling image " << img->filename << " by a factor of " << scale_factor << ".";
+ vector<StorageType> scaled_pixels;
+ size_t scaled_width, scaled_height, scaled_depth;
+ util_image_resize_pixels(pixels_storage,
+ width,
+ height,
+ depth,
+ is_rgba ? 4 : 1,
+ scale_factor,
+ &scaled_pixels,
+ &scaled_width,
+ &scaled_height,
+ &scaled_depth);
+
+ StorageType *texture_pixels;
+
+ {
+ thread_scoped_lock device_lock(device_mutex);
+ texture_pixels = (StorageType *)tex_img.alloc(scaled_width, scaled_height, scaled_depth);
+ }
+
+ memcpy(texture_pixels, &scaled_pixels[0], scaled_pixels.size() * sizeof(StorageType));
+ }
+ return true;
}
-void ImageManager::device_load_image(Device *device,
- Scene *scene,
- ImageDataType type,
- int slot,
- Progress *progress)
+void ImageManager::device_load_image(
+ Device *device, Scene *scene, ImageDataType type, int slot, Progress *progress)
{
- if(progress->get_cancel())
- return;
-
- Image *img = images[type][slot];
-
- if(osl_texture_system && !img->builtin_data)
- return;
-
- string filename = path_filename(images[type][slot]->filename);
- progress->set_status("Updating Images", "Loading " + filename);
-
- const int texture_limit = scene->params.texture_limit;
-
- /* Slot assignment */
- int flat_slot = type_index_to_flattened_slot(slot, type);
- img->mem_name = string_printf("__tex_image_%s_%03d",
- name_from_type(type), flat_slot);
-
- /* Free previous texture in slot. */
- if(img->mem) {
- thread_scoped_lock device_lock(device_mutex);
- delete img->mem;
- img->mem = NULL;
- }
-
- /* Create new texture. */
- if(type == IMAGE_DATA_TYPE_FLOAT4) {
- device_vector<float4> *tex_img
- = new device_vector<float4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::FLOAT, float>(img,
- type,
- texture_limit,
- *tex_img))
- {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- float *pixels = (float*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- pixels[1] = TEX_IMAGE_MISSING_G;
- pixels[2] = TEX_IMAGE_MISSING_B;
- pixels[3] = TEX_IMAGE_MISSING_A;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_FLOAT) {
- device_vector<float> *tex_img
- = new device_vector<float>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::FLOAT, float>(img,
- type,
- texture_limit,
- *tex_img))
- {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- float *pixels = (float*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_BYTE4) {
- device_vector<uchar4> *tex_img
- = new device_vector<uchar4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::UINT8, uchar>(img,
- type,
- texture_limit,
- *tex_img))
- {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uchar *pixels = (uchar*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 255);
- pixels[1] = (TEX_IMAGE_MISSING_G * 255);
- pixels[2] = (TEX_IMAGE_MISSING_B * 255);
- pixels[3] = (TEX_IMAGE_MISSING_A * 255);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_BYTE) {
- device_vector<uchar> *tex_img
- = new device_vector<uchar>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::UINT8, uchar>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uchar *pixels = (uchar*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 255);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_HALF4) {
- device_vector<half4> *tex_img
- = new device_vector<half4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::HALF, half>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- half *pixels = (half*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- pixels[1] = TEX_IMAGE_MISSING_G;
- pixels[2] = TEX_IMAGE_MISSING_B;
- pixels[3] = TEX_IMAGE_MISSING_A;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_USHORT) {
- device_vector<uint16_t> *tex_img
- = new device_vector<uint16_t>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::USHORT, uint16_t>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_USHORT4) {
- device_vector<ushort4> *tex_img
- = new device_vector<ushort4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::USHORT, uint16_t>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
- pixels[1] = (TEX_IMAGE_MISSING_G * 65535);
- pixels[2] = (TEX_IMAGE_MISSING_B * 65535);
- pixels[3] = (TEX_IMAGE_MISSING_A * 65535);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_HALF) {
- device_vector<half> *tex_img
- = new device_vector<half>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::HALF, half>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- half *pixels = (half*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- img->need_load = false;
+ if (progress->get_cancel())
+ return;
+
+ Image *img = images[type][slot];
+
+ if (osl_texture_system && !img->builtin_data)
+ return;
+
+ string filename = path_filename(images[type][slot]->filename);
+ progress->set_status("Updating Images", "Loading " + filename);
+
+ const int texture_limit = scene->params.texture_limit;
+
+ /* Slot assignment */
+ int flat_slot = type_index_to_flattened_slot(slot, type);
+ img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type), flat_slot);
+
+ /* Free previous texture in slot. */
+ if (img->mem) {
+ thread_scoped_lock device_lock(device_mutex);
+ delete img->mem;
+ img->mem = NULL;
+ }
+
+ /* Create new texture. */
+ if (type == IMAGE_DATA_TYPE_FLOAT4) {
+ device_vector<float4> *tex_img = new device_vector<float4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::FLOAT, float>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ float *pixels = (float *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ pixels[1] = TEX_IMAGE_MISSING_G;
+ pixels[2] = TEX_IMAGE_MISSING_B;
+ pixels[3] = TEX_IMAGE_MISSING_A;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_FLOAT) {
+ device_vector<float> *tex_img = new device_vector<float>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::FLOAT, float>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ float *pixels = (float *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_BYTE4) {
+ device_vector<uchar4> *tex_img = new device_vector<uchar4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::UINT8, uchar>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uchar *pixels = (uchar *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 255);
+ pixels[1] = (TEX_IMAGE_MISSING_G * 255);
+ pixels[2] = (TEX_IMAGE_MISSING_B * 255);
+ pixels[3] = (TEX_IMAGE_MISSING_A * 255);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_BYTE) {
+ device_vector<uchar> *tex_img = new device_vector<uchar>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::UINT8, uchar>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uchar *pixels = (uchar *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 255);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_HALF4) {
+ device_vector<half4> *tex_img = new device_vector<half4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::HALF, half>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ half *pixels = (half *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ pixels[1] = TEX_IMAGE_MISSING_G;
+ pixels[2] = TEX_IMAGE_MISSING_B;
+ pixels[3] = TEX_IMAGE_MISSING_A;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_USHORT) {
+ device_vector<uint16_t> *tex_img = new device_vector<uint16_t>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::USHORT, uint16_t>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uint16_t *pixels = (uint16_t *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_USHORT4) {
+ device_vector<ushort4> *tex_img = new device_vector<ushort4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::USHORT, uint16_t>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uint16_t *pixels = (uint16_t *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
+ pixels[1] = (TEX_IMAGE_MISSING_G * 65535);
+ pixels[2] = (TEX_IMAGE_MISSING_B * 65535);
+ pixels[3] = (TEX_IMAGE_MISSING_A * 65535);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_HALF) {
+ device_vector<half> *tex_img = new device_vector<half>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::HALF, half>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ half *pixels = (half *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ img->need_load = false;
}
void ImageManager::device_free_image(Device *, ImageDataType type, int slot)
{
- Image *img = images[type][slot];
+ Image *img = images[type][slot];
- if(img) {
- if(osl_texture_system && !img->builtin_data) {
+ if (img) {
+ if (osl_texture_system && !img->builtin_data) {
#ifdef WITH_OSL
- ustring filename(images[type][slot]->filename);
- ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
+ ustring filename(images[type][slot]->filename);
+ ((OSL::TextureSystem *)osl_texture_system)->invalidate(filename);
#endif
- }
+ }
- if(img->mem) {
- thread_scoped_lock device_lock(device_mutex);
- delete img->mem;
- }
+ if (img->mem) {
+ thread_scoped_lock device_lock(device_mutex);
+ delete img->mem;
+ }
- delete img;
- images[type][slot] = NULL;
- --tex_num_images[type];
- }
+ delete img;
+ images[type][slot] = NULL;
+ --tex_num_images[type];
+ }
}
-void ImageManager::device_update(Device *device,
- Scene *scene,
- Progress& progress)
+void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
{
- if(!need_update) {
- return;
- }
-
- TaskPool pool;
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(!images[type][slot])
- continue;
-
- if(images[type][slot]->users == 0) {
- device_free_image(device, (ImageDataType)type, slot);
- }
- else if(images[type][slot]->need_load) {
- if(!osl_texture_system || images[type][slot]->builtin_data)
- pool.push(function_bind(&ImageManager::device_load_image,
- this,
- device,
- scene,
- (ImageDataType)type,
- slot,
- &progress));
- }
- }
- }
-
- pool.wait_work();
-
- need_update = false;
+ if (!need_update) {
+ return;
+ }
+
+ TaskPool pool;
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (!images[type][slot])
+ continue;
+
+ if (images[type][slot]->users == 0) {
+ device_free_image(device, (ImageDataType)type, slot);
+ }
+ else if (images[type][slot]->need_load) {
+ if (!osl_texture_system || images[type][slot]->builtin_data)
+ pool.push(function_bind(&ImageManager::device_load_image,
+ this,
+ device,
+ scene,
+ (ImageDataType)type,
+ slot,
+ &progress));
+ }
+ }
+ }
+
+ pool.wait_work();
+
+ need_update = false;
}
void ImageManager::device_update_slot(Device *device,
@@ -1001,87 +943,80 @@ void ImageManager::device_update_slot(Device *device,
int flat_slot,
Progress *progress)
{
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
-
- Image *image = images[type][slot];
- assert(image != NULL);
-
- if(image->users == 0) {
- device_free_image(device, type, slot);
- }
- else if(image->need_load) {
- if(!osl_texture_system || image->builtin_data)
- device_load_image(device,
- scene,
- type,
- slot,
- progress);
- }
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
+
+ Image *image = images[type][slot];
+ assert(image != NULL);
+
+ if (image->users == 0) {
+ device_free_image(device, type, slot);
+ }
+ else if (image->need_load) {
+ if (!osl_texture_system || image->builtin_data)
+ device_load_image(device, scene, type, slot, progress);
+ }
}
-void ImageManager::device_load_builtin(Device *device,
- Scene *scene,
- Progress& progress)
+void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &progress)
{
- /* Load only builtin images, Blender needs this to load evaluated
- * scene data from depsgraph before it is freed. */
- if(!need_update) {
- return;
- }
-
- TaskPool pool;
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(!images[type][slot])
- continue;
-
- if(images[type][slot]->need_load) {
- if(images[type][slot]->builtin_data) {
- pool.push(function_bind(&ImageManager::device_load_image,
- this,
- device,
- scene,
- (ImageDataType)type,
- slot,
- &progress));
- }
- }
- }
- }
-
- pool.wait_work();
+ /* Load only builtin images, Blender needs this to load evaluated
+ * scene data from depsgraph before it is freed. */
+ if (!need_update) {
+ return;
+ }
+
+ TaskPool pool;
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (!images[type][slot])
+ continue;
+
+ if (images[type][slot]->need_load) {
+ if (images[type][slot]->builtin_data) {
+ pool.push(function_bind(&ImageManager::device_load_image,
+ this,
+ device,
+ scene,
+ (ImageDataType)type,
+ slot,
+ &progress));
+ }
+ }
+ }
+ }
+
+ pool.wait_work();
}
void ImageManager::device_free_builtin(Device *device)
{
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && images[type][slot]->builtin_data)
- device_free_image(device, (ImageDataType)type, slot);
- }
- }
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] && images[type][slot]->builtin_data)
+ device_free_image(device, (ImageDataType)type, slot);
+ }
+ }
}
void ImageManager::device_free(Device *device)
{
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- device_free_image(device, (ImageDataType)type, slot);
- }
- images[type].clear();
- }
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ device_free_image(device, (ImageDataType)type, slot);
+ }
+ images[type].clear();
+ }
}
void ImageManager::collect_statistics(RenderStats *stats)
{
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- foreach(const Image *image, images[type]) {
- stats->image.textures.add_entry(
- NamedSizeEntry(path_filename(image->filename),
- image->mem->memory_size()));
- }
- }
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ foreach (const Image *image, images[type]) {
+ stats->image.textures.add_entry(
+ NamedSizeEntry(path_filename(image->filename), image->mem->memory_size()));
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 1403b9050fd..34f046692f6 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -34,150 +34,129 @@ class RenderStats;
class Scene;
class ImageMetaData {
-public:
- /* Must be set by image file or builtin callback. */
- bool is_float, is_half;
- int channels;
- size_t width, height, depth;
- bool builtin_free_cache;
-
- /* Automatically set. */
- ImageDataType type;
- bool is_linear;
-
- bool operator==(const ImageMetaData& other) const
- {
- return is_float == other.is_float &&
- is_half == other.is_half &&
- channels == other.channels &&
- width == other.width &&
- height == other.height &&
- depth == other.depth &&
- type == other.type &&
- is_linear == other.is_linear;
- }
+ public:
+ /* Must be set by image file or builtin callback. */
+ bool is_float, is_half;
+ int channels;
+ size_t width, height, depth;
+ bool builtin_free_cache;
+
+ /* Automatically set. */
+ ImageDataType type;
+ bool is_linear;
+
+ bool operator==(const ImageMetaData &other) const
+ {
+ return is_float == other.is_float && is_half == other.is_half && channels == other.channels &&
+ width == other.width && height == other.height && depth == other.depth &&
+ type == other.type && is_linear == other.is_linear;
+ }
};
class ImageManager {
-public:
- explicit ImageManager(const DeviceInfo& info);
- ~ImageManager();
-
- int add_image(const string& filename,
- void *builtin_data,
- bool animated,
- float frame,
- InterpolationType interpolation,
- ExtensionType extension,
- bool use_alpha,
- ImageMetaData& metadata);
- void remove_image(int flat_slot);
- void remove_image(const string& filename,
- void *builtin_data,
- InterpolationType interpolation,
- ExtensionType extension,
- bool use_alpha);
- void tag_reload_image(const string& filename,
- void *builtin_data,
- InterpolationType interpolation,
- ExtensionType extension,
- bool use_alpha);
- bool get_image_metadata(const string& filename,
- void *builtin_data,
- ImageMetaData& metadata);
- bool get_image_metadata(int flat_slot,
- ImageMetaData& metadata);
-
- void device_update(Device *device,
- Scene *scene,
- Progress& progress);
- void device_update_slot(Device *device,
- Scene *scene,
- int flat_slot,
- Progress *progress);
- void device_free(Device *device);
-
- void device_load_builtin(Device *device,
- Scene *scene,
- Progress& progress);
- void device_free_builtin(Device *device);
-
- void set_osl_texture_system(void *texture_system);
- bool set_animation_frame_update(int frame);
-
- device_memory *image_memory(int flat_slot);
-
- void collect_statistics(RenderStats *stats);
-
- bool need_update;
-
- /* NOTE: Here pixels_size is a size of storage, which equals to
- * width * height * depth.
- * Use this to avoid some nasty memory corruptions.
- */
- function<void(const string &filename,
- void *data,
- ImageMetaData& metadata)> builtin_image_info_cb;
- function<bool(const string &filename,
- void *data,
- unsigned char *pixels,
- const size_t pixels_size,
- const bool free_cache)> builtin_image_pixels_cb;
- function<bool(const string &filename,
- void *data,
- float *pixels,
- const size_t pixels_size,
- const bool free_cache)> builtin_image_float_pixels_cb;
-
- struct Image {
- string filename;
- void *builtin_data;
- ImageMetaData metadata;
-
- bool use_alpha;
- bool need_load;
- bool animated;
- float frame;
- InterpolationType interpolation;
- ExtensionType extension;
-
- string mem_name;
- device_memory *mem;
-
- int users;
- };
-
-private:
- int tex_num_images[IMAGE_DATA_NUM_TYPES];
- int max_num_images;
- bool has_half_images;
-
- thread_mutex device_mutex;
- int animation_frame;
-
- vector<Image*> images[IMAGE_DATA_NUM_TYPES];
- void *osl_texture_system;
-
- bool file_load_image_generic(Image *img, unique_ptr<ImageInput> *in);
-
- template<TypeDesc::BASETYPE FileFormat,
- typename StorageType,
- typename DeviceType>
- bool file_load_image(Image *img,
- ImageDataType type,
- int texture_limit,
- device_vector<DeviceType>& tex_img);
-
- void device_load_image(Device *device,
- Scene *scene,
- ImageDataType type,
- int slot,
- Progress *progress);
- void device_free_image(Device *device,
- ImageDataType type,
- int slot);
+ public:
+ explicit ImageManager(const DeviceInfo &info);
+ ~ImageManager();
+
+ int add_image(const string &filename,
+ void *builtin_data,
+ bool animated,
+ float frame,
+ InterpolationType interpolation,
+ ExtensionType extension,
+ bool use_alpha,
+ ImageMetaData &metadata);
+ void remove_image(int flat_slot);
+ void remove_image(const string &filename,
+ void *builtin_data,
+ InterpolationType interpolation,
+ ExtensionType extension,
+ bool use_alpha);
+ void tag_reload_image(const string &filename,
+ void *builtin_data,
+ InterpolationType interpolation,
+ ExtensionType extension,
+ bool use_alpha);
+ bool get_image_metadata(const string &filename, void *builtin_data, ImageMetaData &metadata);
+ bool get_image_metadata(int flat_slot, ImageMetaData &metadata);
+
+ void device_update(Device *device, Scene *scene, Progress &progress);
+ void device_update_slot(Device *device, Scene *scene, int flat_slot, Progress *progress);
+ void device_free(Device *device);
+
+ void device_load_builtin(Device *device, Scene *scene, Progress &progress);
+ void device_free_builtin(Device *device);
+
+ void set_osl_texture_system(void *texture_system);
+ bool set_animation_frame_update(int frame);
+
+ device_memory *image_memory(int flat_slot);
+
+ void collect_statistics(RenderStats *stats);
+
+ bool need_update;
+
+ /* NOTE: Here pixels_size is a size of storage, which equals to
+ * width * height * depth.
+ * Use this to avoid some nasty memory corruptions.
+ */
+ function<void(const string &filename, void *data, ImageMetaData &metadata)>
+ builtin_image_info_cb;
+ function<bool(const string &filename,
+ void *data,
+ unsigned char *pixels,
+ const size_t pixels_size,
+ const bool free_cache)>
+ builtin_image_pixels_cb;
+ function<bool(const string &filename,
+ void *data,
+ float *pixels,
+ const size_t pixels_size,
+ const bool free_cache)>
+ builtin_image_float_pixels_cb;
+
+ struct Image {
+ string filename;
+ void *builtin_data;
+ ImageMetaData metadata;
+
+ bool use_alpha;
+ bool need_load;
+ bool animated;
+ float frame;
+ InterpolationType interpolation;
+ ExtensionType extension;
+
+ string mem_name;
+ device_memory *mem;
+
+ int users;
+ };
+
+ private:
+ int tex_num_images[IMAGE_DATA_NUM_TYPES];
+ int max_num_images;
+ bool has_half_images;
+
+ thread_mutex device_mutex;
+ int animation_frame;
+
+ vector<Image *> images[IMAGE_DATA_NUM_TYPES];
+ void *osl_texture_system;
+
+ bool file_load_image_generic(Image *img, unique_ptr<ImageInput> *in);
+
+ template<TypeDesc::BASETYPE FileFormat, typename StorageType, typename DeviceType>
+ bool file_load_image(Image *img,
+ ImageDataType type,
+ int texture_limit,
+ device_vector<DeviceType> &tex_img);
+
+ void device_load_image(
+ Device *device, Scene *scene, ImageDataType type, int slot, Progress *progress);
+ void device_free_image(Device *device, ImageDataType type, int slot);
};
CCL_NAMESPACE_END
-#endif /* __IMAGE_H__ */
+#endif /* __IMAGE_H__ */
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index d86eb8fc5d3..d3873dcfe46 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -30,61 +30,60 @@ CCL_NAMESPACE_BEGIN
NODE_DEFINE(Integrator)
{
- NodeType *type = NodeType::add("integrator", create);
-
- SOCKET_INT(max_bounce, "Max Bounce", 7);
-
- SOCKET_INT(max_diffuse_bounce, "Max Diffuse Bounce", 7);
- SOCKET_INT(max_glossy_bounce, "Max Glossy Bounce", 7);
- SOCKET_INT(max_transmission_bounce, "Max Transmission Bounce", 7);
- SOCKET_INT(max_volume_bounce, "Max Volume Bounce", 7);
-
- SOCKET_INT(transparent_max_bounce, "Transparent Max Bounce", 7);
-
- SOCKET_INT(ao_bounces, "AO Bounces", 0);
-
- SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024);
- SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f);
-
- SOCKET_BOOLEAN(caustics_reflective, "Reflective Caustics", true);
- SOCKET_BOOLEAN(caustics_refractive, "Refractive Caustics", true);
- SOCKET_FLOAT(filter_glossy, "Filter Glossy", 0.0f);
- SOCKET_INT(seed, "Seed", 0);
- SOCKET_FLOAT(sample_clamp_direct, "Sample Clamp Direct", 0.0f);
- SOCKET_FLOAT(sample_clamp_indirect, "Sample Clamp Indirect", 0.0f);
- SOCKET_BOOLEAN(motion_blur, "Motion Blur", false);
-
- SOCKET_INT(aa_samples, "AA Samples", 0);
- SOCKET_INT(diffuse_samples, "Diffuse Samples", 1);
- SOCKET_INT(glossy_samples, "Glossy Samples", 1);
- SOCKET_INT(transmission_samples, "Transmission Samples", 1);
- SOCKET_INT(ao_samples, "AO Samples", 1);
- SOCKET_INT(mesh_light_samples, "Mesh Light Samples", 1);
- SOCKET_INT(subsurface_samples, "Subsurface Samples", 1);
- SOCKET_INT(volume_samples, "Volume Samples", 1);
- SOCKET_INT(start_sample, "Start Sample", 0);
-
- SOCKET_BOOLEAN(sample_all_lights_direct, "Sample All Lights Direct", true);
- SOCKET_BOOLEAN(sample_all_lights_indirect, "Sample All Lights Indirect", true);
- SOCKET_FLOAT(light_sampling_threshold, "Light Sampling Threshold", 0.05f);
-
- static NodeEnum method_enum;
- method_enum.insert("path", PATH);
- method_enum.insert("branched_path", BRANCHED_PATH);
- SOCKET_ENUM(method, "Method", method_enum, PATH);
-
- static NodeEnum sampling_pattern_enum;
- sampling_pattern_enum.insert("sobol", SAMPLING_PATTERN_SOBOL);
- sampling_pattern_enum.insert("cmj", SAMPLING_PATTERN_CMJ);
- SOCKET_ENUM(sampling_pattern, "Sampling Pattern", sampling_pattern_enum, SAMPLING_PATTERN_SOBOL);
-
- return type;
+ NodeType *type = NodeType::add("integrator", create);
+
+ SOCKET_INT(max_bounce, "Max Bounce", 7);
+
+ SOCKET_INT(max_diffuse_bounce, "Max Diffuse Bounce", 7);
+ SOCKET_INT(max_glossy_bounce, "Max Glossy Bounce", 7);
+ SOCKET_INT(max_transmission_bounce, "Max Transmission Bounce", 7);
+ SOCKET_INT(max_volume_bounce, "Max Volume Bounce", 7);
+
+ SOCKET_INT(transparent_max_bounce, "Transparent Max Bounce", 7);
+
+ SOCKET_INT(ao_bounces, "AO Bounces", 0);
+
+ SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024);
+ SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f);
+
+ SOCKET_BOOLEAN(caustics_reflective, "Reflective Caustics", true);
+ SOCKET_BOOLEAN(caustics_refractive, "Refractive Caustics", true);
+ SOCKET_FLOAT(filter_glossy, "Filter Glossy", 0.0f);
+ SOCKET_INT(seed, "Seed", 0);
+ SOCKET_FLOAT(sample_clamp_direct, "Sample Clamp Direct", 0.0f);
+ SOCKET_FLOAT(sample_clamp_indirect, "Sample Clamp Indirect", 0.0f);
+ SOCKET_BOOLEAN(motion_blur, "Motion Blur", false);
+
+ SOCKET_INT(aa_samples, "AA Samples", 0);
+ SOCKET_INT(diffuse_samples, "Diffuse Samples", 1);
+ SOCKET_INT(glossy_samples, "Glossy Samples", 1);
+ SOCKET_INT(transmission_samples, "Transmission Samples", 1);
+ SOCKET_INT(ao_samples, "AO Samples", 1);
+ SOCKET_INT(mesh_light_samples, "Mesh Light Samples", 1);
+ SOCKET_INT(subsurface_samples, "Subsurface Samples", 1);
+ SOCKET_INT(volume_samples, "Volume Samples", 1);
+ SOCKET_INT(start_sample, "Start Sample", 0);
+
+ SOCKET_BOOLEAN(sample_all_lights_direct, "Sample All Lights Direct", true);
+ SOCKET_BOOLEAN(sample_all_lights_indirect, "Sample All Lights Indirect", true);
+ SOCKET_FLOAT(light_sampling_threshold, "Light Sampling Threshold", 0.05f);
+
+ static NodeEnum method_enum;
+ method_enum.insert("path", PATH);
+ method_enum.insert("branched_path", BRANCHED_PATH);
+ SOCKET_ENUM(method, "Method", method_enum, PATH);
+
+ static NodeEnum sampling_pattern_enum;
+ sampling_pattern_enum.insert("sobol", SAMPLING_PATTERN_SOBOL);
+ sampling_pattern_enum.insert("cmj", SAMPLING_PATTERN_CMJ);
+ SOCKET_ENUM(sampling_pattern, "Sampling Pattern", sampling_pattern_enum, SAMPLING_PATTERN_SOBOL);
+
+ return type;
}
-Integrator::Integrator()
-: Node(node_type)
+Integrator::Integrator() : Node(node_type)
{
- need_update = true;
+ need_update = true;
}
Integrator::~Integrator()
@@ -93,146 +92,148 @@ Integrator::~Integrator()
void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
- if(!need_update)
- return;
-
- device_free(device, dscene);
-
- KernelIntegrator *kintegrator = &dscene->data.integrator;
-
- /* integrator parameters */
- kintegrator->max_bounce = max_bounce + 1;
-
- kintegrator->max_diffuse_bounce = max_diffuse_bounce + 1;
- kintegrator->max_glossy_bounce = max_glossy_bounce + 1;
- kintegrator->max_transmission_bounce = max_transmission_bounce + 1;
- kintegrator->max_volume_bounce = max_volume_bounce + 1;
-
- kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
-
- if(ao_bounces == 0) {
- kintegrator->ao_bounces = INT_MAX;
- }
- else {
- kintegrator->ao_bounces = ao_bounces - 1;
- }
-
- /* Transparent Shadows
- * We only need to enable transparent shadows, if we actually have
- * transparent shaders in the scene. Otherwise we can disable it
- * to improve performance a bit. */
- kintegrator->transparent_shadows = false;
- foreach(Shader *shader, scene->shaders) {
- /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */
- if((shader->has_surface_transparent && shader->use_transparent_shadow) || shader->has_volume) {
- kintegrator->transparent_shadows = true;
- break;
- }
- }
-
- kintegrator->volume_max_steps = volume_max_steps;
- kintegrator->volume_step_size = volume_step_size;
-
- kintegrator->caustics_reflective = caustics_reflective;
- kintegrator->caustics_refractive = caustics_refractive;
- kintegrator->filter_glossy = (filter_glossy == 0.0f)? FLT_MAX: 1.0f/filter_glossy;
-
- kintegrator->seed = hash_int(seed);
-
- kintegrator->use_ambient_occlusion =
- ((Pass::contains(scene->film->passes, PASS_AO)) || dscene->data.background.ao_factor != 0.0f);
-
- kintegrator->sample_clamp_direct = (sample_clamp_direct == 0.0f)? FLT_MAX: sample_clamp_direct*3.0f;
- kintegrator->sample_clamp_indirect = (sample_clamp_indirect == 0.0f)? FLT_MAX: sample_clamp_indirect*3.0f;
-
- kintegrator->branched = (method == BRANCHED_PATH);
- kintegrator->volume_decoupled = device->info.has_volume_decoupled;
- kintegrator->diffuse_samples = diffuse_samples;
- kintegrator->glossy_samples = glossy_samples;
- kintegrator->transmission_samples = transmission_samples;
- kintegrator->ao_samples = ao_samples;
- kintegrator->mesh_light_samples = mesh_light_samples;
- kintegrator->subsurface_samples = subsurface_samples;
- kintegrator->volume_samples = volume_samples;
- kintegrator->start_sample = start_sample;
-
- if(method == BRANCHED_PATH) {
- kintegrator->sample_all_lights_direct = sample_all_lights_direct;
- kintegrator->sample_all_lights_indirect = sample_all_lights_indirect;
- }
- else {
- kintegrator->sample_all_lights_direct = false;
- kintegrator->sample_all_lights_indirect = false;
- }
-
- kintegrator->sampling_pattern = sampling_pattern;
- kintegrator->aa_samples = aa_samples;
-
- if(light_sampling_threshold > 0.0f) {
- kintegrator->light_inv_rr_threshold = 1.0f / light_sampling_threshold;
- }
- else {
- kintegrator->light_inv_rr_threshold = 0.0f;
- }
-
- /* sobol directions table */
- int max_samples = 1;
-
- if(method == BRANCHED_PATH) {
- foreach(Light *light, scene->lights)
- max_samples = max(max_samples, light->samples);
-
- max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples)));
- max_samples = max(max_samples, max(ao_samples, max(mesh_light_samples, subsurface_samples)));
- max_samples = max(max_samples, volume_samples);
- }
-
- uint total_bounces = max_bounce +
- transparent_max_bounce + 3 +
- VOLUME_BOUNDS_MAX +
- max(BSSRDF_MAX_HITS, BSSRDF_MAX_BOUNCES);
-
- max_samples *= total_bounces;
-
- int dimensions = PRNG_BASE_NUM + max_samples*PRNG_BOUNCE_NUM;
- dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
-
- uint *directions = dscene->sobol_directions.alloc(SOBOL_BITS*dimensions);
-
- sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
-
- dscene->sobol_directions.copy_to_device();
-
- /* Clamping. */
- bool use_sample_clamp = (sample_clamp_direct != 0.0f ||
- sample_clamp_indirect != 0.0f);
- if(use_sample_clamp != scene->film->use_sample_clamp) {
- scene->film->use_sample_clamp = use_sample_clamp;
- scene->film->tag_update(scene);
- }
-
- need_update = false;
+ if (!need_update)
+ return;
+
+ device_free(device, dscene);
+
+ KernelIntegrator *kintegrator = &dscene->data.integrator;
+
+ /* integrator parameters */
+ kintegrator->max_bounce = max_bounce + 1;
+
+ kintegrator->max_diffuse_bounce = max_diffuse_bounce + 1;
+ kintegrator->max_glossy_bounce = max_glossy_bounce + 1;
+ kintegrator->max_transmission_bounce = max_transmission_bounce + 1;
+ kintegrator->max_volume_bounce = max_volume_bounce + 1;
+
+ kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
+
+ if (ao_bounces == 0) {
+ kintegrator->ao_bounces = INT_MAX;
+ }
+ else {
+ kintegrator->ao_bounces = ao_bounces - 1;
+ }
+
+ /* Transparent Shadows
+ * We only need to enable transparent shadows, if we actually have
+ * transparent shaders in the scene. Otherwise we can disable it
+ * to improve performance a bit. */
+ kintegrator->transparent_shadows = false;
+ foreach (Shader *shader, scene->shaders) {
+ /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */
+ if ((shader->has_surface_transparent && shader->use_transparent_shadow) ||
+ shader->has_volume) {
+ kintegrator->transparent_shadows = true;
+ break;
+ }
+ }
+
+ kintegrator->volume_max_steps = volume_max_steps;
+ kintegrator->volume_step_size = volume_step_size;
+
+ kintegrator->caustics_reflective = caustics_reflective;
+ kintegrator->caustics_refractive = caustics_refractive;
+ kintegrator->filter_glossy = (filter_glossy == 0.0f) ? FLT_MAX : 1.0f / filter_glossy;
+
+ kintegrator->seed = hash_int(seed);
+
+ kintegrator->use_ambient_occlusion = ((Pass::contains(scene->film->passes, PASS_AO)) ||
+ dscene->data.background.ao_factor != 0.0f);
+
+ kintegrator->sample_clamp_direct = (sample_clamp_direct == 0.0f) ? FLT_MAX :
+ sample_clamp_direct * 3.0f;
+ kintegrator->sample_clamp_indirect = (sample_clamp_indirect == 0.0f) ?
+ FLT_MAX :
+ sample_clamp_indirect * 3.0f;
+
+ kintegrator->branched = (method == BRANCHED_PATH);
+ kintegrator->volume_decoupled = device->info.has_volume_decoupled;
+ kintegrator->diffuse_samples = diffuse_samples;
+ kintegrator->glossy_samples = glossy_samples;
+ kintegrator->transmission_samples = transmission_samples;
+ kintegrator->ao_samples = ao_samples;
+ kintegrator->mesh_light_samples = mesh_light_samples;
+ kintegrator->subsurface_samples = subsurface_samples;
+ kintegrator->volume_samples = volume_samples;
+ kintegrator->start_sample = start_sample;
+
+ if (method == BRANCHED_PATH) {
+ kintegrator->sample_all_lights_direct = sample_all_lights_direct;
+ kintegrator->sample_all_lights_indirect = sample_all_lights_indirect;
+ }
+ else {
+ kintegrator->sample_all_lights_direct = false;
+ kintegrator->sample_all_lights_indirect = false;
+ }
+
+ kintegrator->sampling_pattern = sampling_pattern;
+ kintegrator->aa_samples = aa_samples;
+
+ if (light_sampling_threshold > 0.0f) {
+ kintegrator->light_inv_rr_threshold = 1.0f / light_sampling_threshold;
+ }
+ else {
+ kintegrator->light_inv_rr_threshold = 0.0f;
+ }
+
+ /* sobol directions table */
+ int max_samples = 1;
+
+ if (method == BRANCHED_PATH) {
+ foreach (Light *light, scene->lights)
+ max_samples = max(max_samples, light->samples);
+
+ max_samples = max(max_samples,
+ max(diffuse_samples, max(glossy_samples, transmission_samples)));
+ max_samples = max(max_samples, max(ao_samples, max(mesh_light_samples, subsurface_samples)));
+ max_samples = max(max_samples, volume_samples);
+ }
+
+ uint total_bounces = max_bounce + transparent_max_bounce + 3 + VOLUME_BOUNDS_MAX +
+ max(BSSRDF_MAX_HITS, BSSRDF_MAX_BOUNCES);
+
+ max_samples *= total_bounces;
+
+ int dimensions = PRNG_BASE_NUM + max_samples * PRNG_BOUNCE_NUM;
+ dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
+
+ uint *directions = dscene->sobol_directions.alloc(SOBOL_BITS * dimensions);
+
+ sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
+
+ dscene->sobol_directions.copy_to_device();
+
+ /* Clamping. */
+ bool use_sample_clamp = (sample_clamp_direct != 0.0f || sample_clamp_indirect != 0.0f);
+ if (use_sample_clamp != scene->film->use_sample_clamp) {
+ scene->film->use_sample_clamp = use_sample_clamp;
+ scene->film->tag_update(scene);
+ }
+
+ need_update = false;
}
void Integrator::device_free(Device *, DeviceScene *dscene)
{
- dscene->sobol_directions.free();
+ dscene->sobol_directions.free();
}
-bool Integrator::modified(const Integrator& integrator)
+bool Integrator::modified(const Integrator &integrator)
{
- return !Node::equals(integrator);
+ return !Node::equals(integrator);
}
void Integrator::tag_update(Scene *scene)
{
- foreach(Shader *shader, scene->shaders) {
- if(shader->has_integrator_dependency) {
- scene->shader_manager->need_update = true;
- break;
- }
- }
- need_update = true;
+ foreach (Shader *shader, scene->shaders) {
+ if (shader->has_integrator_dependency) {
+ scene->shader_manager->need_update = true;
+ break;
+ }
+ }
+ need_update = true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index da4e61d8153..6acc68a7402 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -28,74 +28,74 @@ class DeviceScene;
class Scene;
class Integrator : public Node {
-public:
- NODE_DECLARE
+ public:
+ NODE_DECLARE
- int max_bounce;
+ int max_bounce;
- int max_diffuse_bounce;
- int max_glossy_bounce;
- int max_transmission_bounce;
- int max_volume_bounce;
+ int max_diffuse_bounce;
+ int max_glossy_bounce;
+ int max_transmission_bounce;
+ int max_volume_bounce;
- int transparent_max_bounce;
+ int transparent_max_bounce;
- int ao_bounces;
+ int ao_bounces;
- int volume_max_steps;
- float volume_step_size;
+ int volume_max_steps;
+ float volume_step_size;
- bool caustics_reflective;
- bool caustics_refractive;
- float filter_glossy;
+ bool caustics_reflective;
+ bool caustics_refractive;
+ float filter_glossy;
- int seed;
+ int seed;
- float sample_clamp_direct;
- float sample_clamp_indirect;
- bool motion_blur;
+ float sample_clamp_direct;
+ float sample_clamp_indirect;
+ bool motion_blur;
- /* Maximum number of samples, beyond which we are likely to run into
- * precision issues for sampling patterns. */
- static const int MAX_SAMPLES = (1 << 24);
+ /* Maximum number of samples, beyond which we are likely to run into
+ * precision issues for sampling patterns. */
+ static const int MAX_SAMPLES = (1 << 24);
- int aa_samples;
- int diffuse_samples;
- int glossy_samples;
- int transmission_samples;
- int ao_samples;
- int mesh_light_samples;
- int subsurface_samples;
- int volume_samples;
- int start_sample;
+ int aa_samples;
+ int diffuse_samples;
+ int glossy_samples;
+ int transmission_samples;
+ int ao_samples;
+ int mesh_light_samples;
+ int subsurface_samples;
+ int volume_samples;
+ int start_sample;
- bool sample_all_lights_direct;
- bool sample_all_lights_indirect;
- float light_sampling_threshold;
+ bool sample_all_lights_direct;
+ bool sample_all_lights_indirect;
+ float light_sampling_threshold;
- enum Method {
- BRANCHED_PATH = 0,
- PATH = 1,
+ enum Method {
+ BRANCHED_PATH = 0,
+ PATH = 1,
- NUM_METHODS,
- };
+ NUM_METHODS,
+ };
- Method method;
+ Method method;
- SamplingPattern sampling_pattern;
+ SamplingPattern sampling_pattern;
- bool need_update;
+ bool need_update;
- Integrator();
- ~Integrator();
+ Integrator();
+ ~Integrator();
- void device_update(Device *device, DeviceScene *dscene, Scene *scene);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_free(Device *device, DeviceScene *dscene);
- bool modified(const Integrator& integrator);
- void tag_update(Scene *scene);
+ bool modified(const Integrator &integrator);
+ void tag_update(Scene *scene);
};
CCL_NAMESPACE_END
-#endif /* __INTEGRATOR_H__ */
+#endif /* __INTEGRATOR_H__ */
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 56d60adf71d..d4c233e3bb3 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -34,1002 +34,1016 @@
CCL_NAMESPACE_BEGIN
-static void shade_background_pixels(Device *device, DeviceScene *dscene, int width, int height, vector<float3>& pixels, Progress& progress)
+static void shade_background_pixels(Device *device,
+ DeviceScene *dscene,
+ int width,
+ int height,
+ vector<float3> &pixels,
+ Progress &progress)
{
- /* create input */
- device_vector<uint4> d_input(device, "background_input", MEM_READ_ONLY);
- device_vector<float4> d_output(device, "background_output", MEM_READ_WRITE);
-
- uint4 *d_input_data = d_input.alloc(width*height);
-
- for(int y = 0; y < height; y++) {
- for(int x = 0; x < width; x++) {
- float u = (x + 0.5f)/width;
- float v = (y + 0.5f)/height;
-
- uint4 in = make_uint4(__float_as_int(u), __float_as_int(v), 0, 0);
- d_input_data[x + y*width] = in;
- }
- }
-
- /* compute on device */
- d_output.alloc(width*height);
- d_output.zero_to_device();
- d_input.copy_to_device();
-
- device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
-
- DeviceTask main_task(DeviceTask::SHADER);
- main_task.shader_input = d_input.device_pointer;
- main_task.shader_output = d_output.device_pointer;
- main_task.shader_eval_type = SHADER_EVAL_BACKGROUND;
- main_task.shader_x = 0;
- main_task.shader_w = width*height;
- main_task.num_samples = 1;
- main_task.get_cancel = function_bind(&Progress::get_cancel, &progress);
-
- /* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */
- list<DeviceTask> split_tasks;
- main_task.split(split_tasks, 1, 128*128);
-
- foreach(DeviceTask& task, split_tasks) {
- device->task_add(task);
- device->task_wait();
- d_output.copy_from_device(task.shader_x, 1, task.shader_w);
- }
-
- d_input.free();
-
- float4 *d_output_data = d_output.data();
-
- pixels.resize(width*height);
-
- for(int y = 0; y < height; y++) {
- for(int x = 0; x < width; x++) {
- pixels[y*width + x].x = d_output_data[y*width + x].x;
- pixels[y*width + x].y = d_output_data[y*width + x].y;
- pixels[y*width + x].z = d_output_data[y*width + x].z;
- }
- }
-
- d_output.free();
+ /* create input */
+ device_vector<uint4> d_input(device, "background_input", MEM_READ_ONLY);
+ device_vector<float4> d_output(device, "background_output", MEM_READ_WRITE);
+
+ uint4 *d_input_data = d_input.alloc(width * height);
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ float u = (x + 0.5f) / width;
+ float v = (y + 0.5f) / height;
+
+ uint4 in = make_uint4(__float_as_int(u), __float_as_int(v), 0, 0);
+ d_input_data[x + y * width] = in;
+ }
+ }
+
+ /* compute on device */
+ d_output.alloc(width * height);
+ d_output.zero_to_device();
+ d_input.copy_to_device();
+
+ device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
+
+ DeviceTask main_task(DeviceTask::SHADER);
+ main_task.shader_input = d_input.device_pointer;
+ main_task.shader_output = d_output.device_pointer;
+ main_task.shader_eval_type = SHADER_EVAL_BACKGROUND;
+ main_task.shader_x = 0;
+ main_task.shader_w = width * height;
+ main_task.num_samples = 1;
+ main_task.get_cancel = function_bind(&Progress::get_cancel, &progress);
+
+ /* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */
+ list<DeviceTask> split_tasks;
+ main_task.split(split_tasks, 1, 128 * 128);
+
+ foreach (DeviceTask &task, split_tasks) {
+ device->task_add(task);
+ device->task_wait();
+ d_output.copy_from_device(task.shader_x, 1, task.shader_w);
+ }
+
+ d_input.free();
+
+ float4 *d_output_data = d_output.data();
+
+ pixels.resize(width * height);
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ pixels[y * width + x].x = d_output_data[y * width + x].x;
+ pixels[y * width + x].y = d_output_data[y * width + x].y;
+ pixels[y * width + x].z = d_output_data[y * width + x].z;
+ }
+ }
+
+ d_output.free();
}
/* Light */
NODE_DEFINE(Light)
{
- NodeType* type = NodeType::add("light", create);
+ NodeType *type = NodeType::add("light", create);
- static NodeEnum type_enum;
- type_enum.insert("point", LIGHT_POINT);
- type_enum.insert("distant", LIGHT_DISTANT);
- type_enum.insert("background", LIGHT_BACKGROUND);
- type_enum.insert("area", LIGHT_AREA);
- type_enum.insert("spot", LIGHT_SPOT);
- SOCKET_ENUM(type, "Type", type_enum, LIGHT_POINT);
+ static NodeEnum type_enum;
+ type_enum.insert("point", LIGHT_POINT);
+ type_enum.insert("distant", LIGHT_DISTANT);
+ type_enum.insert("background", LIGHT_BACKGROUND);
+ type_enum.insert("area", LIGHT_AREA);
+ type_enum.insert("spot", LIGHT_SPOT);
+ SOCKET_ENUM(type, "Type", type_enum, LIGHT_POINT);
- SOCKET_POINT(co, "Co", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_POINT(co, "Co", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_VECTOR(dir, "Dir", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_FLOAT(size, "Size", 0.0f);
+ SOCKET_VECTOR(dir, "Dir", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_FLOAT(size, "Size", 0.0f);
- SOCKET_VECTOR(axisu, "Axis U", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_FLOAT(sizeu, "Size U", 1.0f);
- SOCKET_VECTOR(axisv, "Axis V", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_FLOAT(sizev, "Size V", 1.0f);
- SOCKET_BOOLEAN(round, "Round", false);
+ SOCKET_VECTOR(axisu, "Axis U", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_FLOAT(sizeu, "Size U", 1.0f);
+ SOCKET_VECTOR(axisv, "Axis V", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_FLOAT(sizev, "Size V", 1.0f);
+ SOCKET_BOOLEAN(round, "Round", false);
- SOCKET_INT(map_resolution, "Map Resolution", 0);
+ SOCKET_INT(map_resolution, "Map Resolution", 0);
- SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
- SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
+ SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
+ SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
- SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
+ SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
- SOCKET_BOOLEAN(cast_shadow, "Cast Shadow", true);
- SOCKET_BOOLEAN(use_mis, "Use Mis", false);
- SOCKET_BOOLEAN(use_diffuse, "Use Diffuse", true);
- SOCKET_BOOLEAN(use_glossy, "Use Glossy", true);
- SOCKET_BOOLEAN(use_transmission, "Use Transmission", true);
- SOCKET_BOOLEAN(use_scatter, "Use Scatter", true);
+ SOCKET_BOOLEAN(cast_shadow, "Cast Shadow", true);
+ SOCKET_BOOLEAN(use_mis, "Use Mis", false);
+ SOCKET_BOOLEAN(use_diffuse, "Use Diffuse", true);
+ SOCKET_BOOLEAN(use_glossy, "Use Glossy", true);
+ SOCKET_BOOLEAN(use_transmission, "Use Transmission", true);
+ SOCKET_BOOLEAN(use_scatter, "Use Scatter", true);
- SOCKET_INT(samples, "Samples", 1);
- SOCKET_INT(max_bounces, "Max Bounces", 1024);
- SOCKET_UINT(random_id, "Random ID", 0);
+ SOCKET_INT(samples, "Samples", 1);
+ SOCKET_INT(max_bounces, "Max Bounces", 1024);
+ SOCKET_UINT(random_id, "Random ID", 0);
- SOCKET_BOOLEAN(is_portal, "Is Portal", false);
- SOCKET_BOOLEAN(is_enabled, "Is Enabled", true);
+ SOCKET_BOOLEAN(is_portal, "Is Portal", false);
+ SOCKET_BOOLEAN(is_enabled, "Is Enabled", true);
- SOCKET_NODE(shader, "Shader", &Shader::node_type);
+ SOCKET_NODE(shader, "Shader", &Shader::node_type);
- return type;
+ return type;
}
-Light::Light()
-: Node(node_type)
+Light::Light() : Node(node_type)
{
}
void Light::tag_update(Scene *scene)
{
- scene->light_manager->need_update = true;
+ scene->light_manager->need_update = true;
}
bool Light::has_contribution(Scene *scene)
{
- if(is_portal) {
- return false;
- }
- if(type == LIGHT_BACKGROUND) {
- return true;
- }
- return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission;
+ if (is_portal) {
+ return false;
+ }
+ if (type == LIGHT_BACKGROUND) {
+ return true;
+ }
+ return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission;
}
/* Light Manager */
LightManager::LightManager()
{
- need_update = true;
- use_light_visibility = false;
+ need_update = true;
+ use_light_visibility = false;
}
LightManager::~LightManager()
{
- foreach(IESSlot *slot, ies_slots) {
- delete slot;
- }
+ foreach (IESSlot *slot, ies_slots) {
+ delete slot;
+ }
}
bool LightManager::has_background_light(Scene *scene)
{
- foreach(Light *light, scene->lights) {
- if(light->type == LIGHT_BACKGROUND && light->is_enabled) {
- return true;
- }
- }
- return false;
+ foreach (Light *light, scene->lights) {
+ if (light->type == LIGHT_BACKGROUND && light->is_enabled) {
+ return true;
+ }
+ }
+ return false;
}
void LightManager::disable_ineffective_light(Scene *scene)
{
- /* Make all lights enabled by default, and perform some preliminary checks
- * needed for finer-tuning of settings (for example, check whether we've
- * got portals or not).
- */
- bool has_portal = false, has_background = false;
- foreach(Light *light, scene->lights) {
- light->is_enabled = light->has_contribution(scene);
- has_portal |= light->is_portal;
- has_background |= light->type == LIGHT_BACKGROUND;
- }
-
- if(has_background) {
- /* Ignore background light if:
- * - If unsupported on a device
- * - If we don't need it (no HDRs etc.)
- */
- Shader *shader = (scene->background->shader) ? scene->background->shader : scene->default_background;
- bool disable_mis = !(has_portal || shader->has_surface_spatial_varying);
- if(disable_mis) {
- VLOG(1) << "Background MIS has been disabled.\n";
- foreach(Light *light, scene->lights) {
- if(light->type == LIGHT_BACKGROUND) {
- light->is_enabled = false;
- }
- }
- }
- }
+ /* Make all lights enabled by default, and perform some preliminary checks
+ * needed for finer-tuning of settings (for example, check whether we've
+ * got portals or not).
+ */
+ bool has_portal = false, has_background = false;
+ foreach (Light *light, scene->lights) {
+ light->is_enabled = light->has_contribution(scene);
+ has_portal |= light->is_portal;
+ has_background |= light->type == LIGHT_BACKGROUND;
+ }
+
+ if (has_background) {
+ /* Ignore background light if:
+ * - If unsupported on a device
+ * - If we don't need it (no HDRs etc.)
+ */
+ Shader *shader = (scene->background->shader) ? scene->background->shader :
+ scene->default_background;
+ bool disable_mis = !(has_portal || shader->has_surface_spatial_varying);
+ if (disable_mis) {
+ VLOG(1) << "Background MIS has been disabled.\n";
+ foreach (Light *light, scene->lights) {
+ if (light->type == LIGHT_BACKGROUND) {
+ light->is_enabled = false;
+ }
+ }
+ }
+ }
}
-bool LightManager::object_usable_as_light(Object *object) {
- Mesh *mesh = object->mesh;
- /* Skip objects with NaNs */
- if(!object->bounds.valid()) {
- return false;
- }
- /* Skip if we are not visible for BSDFs. */
- if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT))) {
- return false;
- }
- /* Skip if we have no emission shaders. */
- /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll
- * iterate all mesh shaders twice (when counting and when calculating
- * triangle area.
- */
- foreach(const Shader *shader, mesh->used_shaders) {
- if(shader->use_mis && shader->has_surface_emission) {
- return true;
- }
- }
- return false;
+bool LightManager::object_usable_as_light(Object *object)
+{
+ Mesh *mesh = object->mesh;
+ /* Skip objects with NaNs */
+ if (!object->bounds.valid()) {
+ return false;
+ }
+ /* Skip if we are not visible for BSDFs. */
+ if (!(object->visibility & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) {
+ return false;
+ }
+ /* Skip if we have no emission shaders. */
+ /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll
+ * iterate all mesh shaders twice (when counting and when calculating
+ * triangle area.
+ */
+ foreach (const Shader *shader, mesh->used_shaders) {
+ if (shader->use_mis && shader->has_surface_emission) {
+ return true;
+ }
+ }
+ return false;
}
-void LightManager::device_update_distribution(Device *, DeviceScene *dscene, Scene *scene, Progress& progress)
+void LightManager::device_update_distribution(Device *,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
{
- progress.set_status("Updating Lights", "Computing distribution");
-
- /* count */
- size_t num_lights = 0;
- size_t num_portals = 0;
- size_t num_background_lights = 0;
- size_t num_triangles = 0;
-
- bool background_mis = false;
-
- foreach(Light *light, scene->lights) {
- if(light->is_enabled) {
- num_lights++;
- }
- if(light->is_portal) {
- num_portals++;
- }
- }
-
- foreach(Object *object, scene->objects) {
- if(progress.get_cancel()) return;
-
- if(!object_usable_as_light(object)) {
- continue;
- }
- /* Count triangles. */
- Mesh *mesh = object->mesh;
- size_t mesh_num_triangles = mesh->num_triangles();
- for(size_t i = 0; i < mesh_num_triangles; i++) {
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size())
- ? mesh->used_shaders[shader_index]
- : scene->default_surface;
-
- if(shader->use_mis && shader->has_surface_emission) {
- num_triangles++;
- }
- }
- }
-
- size_t num_distribution = num_triangles + num_lights;
- VLOG(1) << "Total " << num_distribution << " of light distribution primitives.";
-
- /* emission area */
- KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1);
- float totarea = 0.0f;
-
- /* triangles */
- size_t offset = 0;
- int j = 0;
-
- foreach(Object *object, scene->objects) {
- if(progress.get_cancel()) return;
-
- if(!object_usable_as_light(object)) {
- j++;
- continue;
- }
- /* Sum area. */
- Mesh *mesh = object->mesh;
- bool transform_applied = mesh->transform_applied;
- Transform tfm = object->tfm;
- int object_id = j;
- int shader_flag = 0;
-
- if(!(object->visibility & PATH_RAY_DIFFUSE)) {
- shader_flag |= SHADER_EXCLUDE_DIFFUSE;
- use_light_visibility = true;
- }
- if(!(object->visibility & PATH_RAY_GLOSSY)) {
- shader_flag |= SHADER_EXCLUDE_GLOSSY;
- use_light_visibility = true;
- }
- if(!(object->visibility & PATH_RAY_TRANSMIT)) {
- shader_flag |= SHADER_EXCLUDE_TRANSMIT;
- use_light_visibility = true;
- }
- if(!(object->visibility & PATH_RAY_VOLUME_SCATTER)) {
- shader_flag |= SHADER_EXCLUDE_SCATTER;
- use_light_visibility = true;
- }
-
- size_t mesh_num_triangles = mesh->num_triangles();
- for(size_t i = 0; i < mesh_num_triangles; i++) {
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size())
- ? mesh->used_shaders[shader_index]
- : scene->default_surface;
-
- if(shader->use_mis && shader->has_surface_emission) {
- distribution[offset].totarea = totarea;
- distribution[offset].prim = i + mesh->tri_offset;
- distribution[offset].mesh_light.shader_flag = shader_flag;
- distribution[offset].mesh_light.object_id = object_id;
- offset++;
-
- Mesh::Triangle t = mesh->get_triangle(i);
- if(!t.valid(&mesh->verts[0])) {
- continue;
- }
- float3 p1 = mesh->verts[t.v[0]];
- float3 p2 = mesh->verts[t.v[1]];
- float3 p3 = mesh->verts[t.v[2]];
-
- if(!transform_applied) {
- p1 = transform_point(&tfm, p1);
- p2 = transform_point(&tfm, p2);
- p3 = transform_point(&tfm, p3);
- }
-
- totarea += triangle_area(p1, p2, p3);
- }
- }
-
- j++;
- }
-
- float trianglearea = totarea;
-
- /* point lights */
- float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
- bool use_lamp_mis = false;
-
- int light_index = 0;
- foreach(Light *light, scene->lights) {
- if(!light->is_enabled)
- continue;
-
- distribution[offset].totarea = totarea;
- distribution[offset].prim = ~light_index;
- distribution[offset].lamp.pad = 1.0f;
- distribution[offset].lamp.size = light->size;
- totarea += lightarea;
-
- if(light->size > 0.0f && light->use_mis)
- use_lamp_mis = true;
- if(light->type == LIGHT_BACKGROUND) {
- num_background_lights++;
- background_mis = light->use_mis;
- }
-
- light_index++;
- offset++;
- }
-
- /* normalize cumulative distribution functions */
- distribution[num_distribution].totarea = totarea;
- distribution[num_distribution].prim = 0.0f;
- distribution[num_distribution].lamp.pad = 0.0f;
- distribution[num_distribution].lamp.size = 0.0f;
-
- if(totarea > 0.0f) {
- for(size_t i = 0; i < num_distribution; i++)
- distribution[i].totarea /= totarea;
- distribution[num_distribution].totarea = 1.0f;
- }
-
- if(progress.get_cancel()) return;
-
- /* update device */
- KernelIntegrator *kintegrator = &dscene->data.integrator;
- KernelFilm *kfilm = &dscene->data.film;
- kintegrator->use_direct_light = (totarea > 0.0f);
-
- if(kintegrator->use_direct_light) {
- /* number of emissives */
- kintegrator->num_distribution = num_distribution;
-
- /* precompute pdfs */
- kintegrator->pdf_triangles = 0.0f;
- kintegrator->pdf_lights = 0.0f;
-
- /* sample one, with 0.5 probability of light or triangle */
- kintegrator->num_all_lights = num_lights;
-
- if(trianglearea > 0.0f) {
- kintegrator->pdf_triangles = 1.0f/trianglearea;
- if(num_lights)
- kintegrator->pdf_triangles *= 0.5f;
- }
-
- if(num_lights) {
- kintegrator->pdf_lights = 1.0f/num_lights;
- if(trianglearea > 0.0f)
- kintegrator->pdf_lights *= 0.5f;
- }
-
- kintegrator->use_lamp_mis = use_lamp_mis;
-
- /* bit of an ugly hack to compensate for emitting triangles influencing
- * amount of samples we get for this pass */
- kfilm->pass_shadow_scale = 1.0f;
-
- if(kintegrator->pdf_triangles != 0.0f)
- kfilm->pass_shadow_scale *= 0.5f;
-
- if(num_background_lights < num_lights)
- kfilm->pass_shadow_scale *= (float)(num_lights - num_background_lights)/(float)num_lights;
-
- /* CDF */
- dscene->light_distribution.copy_to_device();
-
- /* Portals */
- if(num_portals > 0) {
- kintegrator->portal_offset = light_index;
- kintegrator->num_portals = num_portals;
- kintegrator->portal_pdf = background_mis? 0.5f: 1.0f;
- }
- else {
- kintegrator->num_portals = 0;
- kintegrator->portal_offset = 0;
- kintegrator->portal_pdf = 0.0f;
- }
- }
- else {
- dscene->light_distribution.free();
-
- kintegrator->num_distribution = 0;
- kintegrator->num_all_lights = 0;
- kintegrator->pdf_triangles = 0.0f;
- kintegrator->pdf_lights = 0.0f;
- kintegrator->use_lamp_mis = false;
- kintegrator->num_portals = 0;
- kintegrator->portal_offset = 0;
- kintegrator->portal_pdf = 0.0f;
-
- kfilm->pass_shadow_scale = 1.0f;
- }
+ progress.set_status("Updating Lights", "Computing distribution");
+
+ /* count */
+ size_t num_lights = 0;
+ size_t num_portals = 0;
+ size_t num_background_lights = 0;
+ size_t num_triangles = 0;
+
+ bool background_mis = false;
+
+ foreach (Light *light, scene->lights) {
+ if (light->is_enabled) {
+ num_lights++;
+ }
+ if (light->is_portal) {
+ num_portals++;
+ }
+ }
+
+ foreach (Object *object, scene->objects) {
+ if (progress.get_cancel())
+ return;
+
+ if (!object_usable_as_light(object)) {
+ continue;
+ }
+ /* Count triangles. */
+ Mesh *mesh = object->mesh;
+ size_t mesh_num_triangles = mesh->num_triangles();
+ for (size_t i = 0; i < mesh_num_triangles; i++) {
+ int shader_index = mesh->shader[i];
+ Shader *shader = (shader_index < mesh->used_shaders.size()) ?
+ mesh->used_shaders[shader_index] :
+ scene->default_surface;
+
+ if (shader->use_mis && shader->has_surface_emission) {
+ num_triangles++;
+ }
+ }
+ }
+
+ size_t num_distribution = num_triangles + num_lights;
+ VLOG(1) << "Total " << num_distribution << " of light distribution primitives.";
+
+ /* emission area */
+ KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1);
+ float totarea = 0.0f;
+
+ /* triangles */
+ size_t offset = 0;
+ int j = 0;
+
+ foreach (Object *object, scene->objects) {
+ if (progress.get_cancel())
+ return;
+
+ if (!object_usable_as_light(object)) {
+ j++;
+ continue;
+ }
+ /* Sum area. */
+ Mesh *mesh = object->mesh;
+ bool transform_applied = mesh->transform_applied;
+ Transform tfm = object->tfm;
+ int object_id = j;
+ int shader_flag = 0;
+
+ if (!(object->visibility & PATH_RAY_DIFFUSE)) {
+ shader_flag |= SHADER_EXCLUDE_DIFFUSE;
+ use_light_visibility = true;
+ }
+ if (!(object->visibility & PATH_RAY_GLOSSY)) {
+ shader_flag |= SHADER_EXCLUDE_GLOSSY;
+ use_light_visibility = true;
+ }
+ if (!(object->visibility & PATH_RAY_TRANSMIT)) {
+ shader_flag |= SHADER_EXCLUDE_TRANSMIT;
+ use_light_visibility = true;
+ }
+ if (!(object->visibility & PATH_RAY_VOLUME_SCATTER)) {
+ shader_flag |= SHADER_EXCLUDE_SCATTER;
+ use_light_visibility = true;
+ }
+
+ size_t mesh_num_triangles = mesh->num_triangles();
+ for (size_t i = 0; i < mesh_num_triangles; i++) {
+ int shader_index = mesh->shader[i];
+ Shader *shader = (shader_index < mesh->used_shaders.size()) ?
+ mesh->used_shaders[shader_index] :
+ scene->default_surface;
+
+ if (shader->use_mis && shader->has_surface_emission) {
+ distribution[offset].totarea = totarea;
+ distribution[offset].prim = i + mesh->tri_offset;
+ distribution[offset].mesh_light.shader_flag = shader_flag;
+ distribution[offset].mesh_light.object_id = object_id;
+ offset++;
+
+ Mesh::Triangle t = mesh->get_triangle(i);
+ if (!t.valid(&mesh->verts[0])) {
+ continue;
+ }
+ float3 p1 = mesh->verts[t.v[0]];
+ float3 p2 = mesh->verts[t.v[1]];
+ float3 p3 = mesh->verts[t.v[2]];
+
+ if (!transform_applied) {
+ p1 = transform_point(&tfm, p1);
+ p2 = transform_point(&tfm, p2);
+ p3 = transform_point(&tfm, p3);
+ }
+
+ totarea += triangle_area(p1, p2, p3);
+ }
+ }
+
+ j++;
+ }
+
+ float trianglearea = totarea;
+
+ /* point lights */
+ float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
+ bool use_lamp_mis = false;
+
+ int light_index = 0;
+ foreach (Light *light, scene->lights) {
+ if (!light->is_enabled)
+ continue;
+
+ distribution[offset].totarea = totarea;
+ distribution[offset].prim = ~light_index;
+ distribution[offset].lamp.pad = 1.0f;
+ distribution[offset].lamp.size = light->size;
+ totarea += lightarea;
+
+ if (light->size > 0.0f && light->use_mis)
+ use_lamp_mis = true;
+ if (light->type == LIGHT_BACKGROUND) {
+ num_background_lights++;
+ background_mis = light->use_mis;
+ }
+
+ light_index++;
+ offset++;
+ }
+
+ /* normalize cumulative distribution functions */
+ distribution[num_distribution].totarea = totarea;
+ distribution[num_distribution].prim = 0.0f;
+ distribution[num_distribution].lamp.pad = 0.0f;
+ distribution[num_distribution].lamp.size = 0.0f;
+
+ if (totarea > 0.0f) {
+ for (size_t i = 0; i < num_distribution; i++)
+ distribution[i].totarea /= totarea;
+ distribution[num_distribution].totarea = 1.0f;
+ }
+
+ if (progress.get_cancel())
+ return;
+
+ /* update device */
+ KernelIntegrator *kintegrator = &dscene->data.integrator;
+ KernelFilm *kfilm = &dscene->data.film;
+ kintegrator->use_direct_light = (totarea > 0.0f);
+
+ if (kintegrator->use_direct_light) {
+ /* number of emissives */
+ kintegrator->num_distribution = num_distribution;
+
+ /* precompute pdfs */
+ kintegrator->pdf_triangles = 0.0f;
+ kintegrator->pdf_lights = 0.0f;
+
+ /* sample one, with 0.5 probability of light or triangle */
+ kintegrator->num_all_lights = num_lights;
+
+ if (trianglearea > 0.0f) {
+ kintegrator->pdf_triangles = 1.0f / trianglearea;
+ if (num_lights)
+ kintegrator->pdf_triangles *= 0.5f;
+ }
+
+ if (num_lights) {
+ kintegrator->pdf_lights = 1.0f / num_lights;
+ if (trianglearea > 0.0f)
+ kintegrator->pdf_lights *= 0.5f;
+ }
+
+ kintegrator->use_lamp_mis = use_lamp_mis;
+
+ /* bit of an ugly hack to compensate for emitting triangles influencing
+ * amount of samples we get for this pass */
+ kfilm->pass_shadow_scale = 1.0f;
+
+ if (kintegrator->pdf_triangles != 0.0f)
+ kfilm->pass_shadow_scale *= 0.5f;
+
+ if (num_background_lights < num_lights)
+ kfilm->pass_shadow_scale *= (float)(num_lights - num_background_lights) / (float)num_lights;
+
+ /* CDF */
+ dscene->light_distribution.copy_to_device();
+
+ /* Portals */
+ if (num_portals > 0) {
+ kintegrator->portal_offset = light_index;
+ kintegrator->num_portals = num_portals;
+ kintegrator->portal_pdf = background_mis ? 0.5f : 1.0f;
+ }
+ else {
+ kintegrator->num_portals = 0;
+ kintegrator->portal_offset = 0;
+ kintegrator->portal_pdf = 0.0f;
+ }
+ }
+ else {
+ dscene->light_distribution.free();
+
+ kintegrator->num_distribution = 0;
+ kintegrator->num_all_lights = 0;
+ kintegrator->pdf_triangles = 0.0f;
+ kintegrator->pdf_lights = 0.0f;
+ kintegrator->use_lamp_mis = false;
+ kintegrator->num_portals = 0;
+ kintegrator->portal_offset = 0;
+ kintegrator->portal_pdf = 0.0f;
+
+ kfilm->pass_shadow_scale = 1.0f;
+ }
}
-static void background_cdf(int start,
- int end,
- int res_x,
- int res_y,
- const vector<float3> *pixels,
- float2 *cond_cdf)
+static void background_cdf(
+ int start, int end, int res_x, int res_y, const vector<float3> *pixels, float2 *cond_cdf)
{
- int cdf_width = res_x+1;
- /* Conditional CDFs (rows, U direction). */
- for(int i = start; i < end; i++) {
- float sin_theta = sinf(M_PI_F * (i + 0.5f) / res_y);
- float3 env_color = (*pixels)[i * res_x];
- float ave_luminance = average(env_color);
-
- cond_cdf[i * cdf_width].x = ave_luminance * sin_theta;
- cond_cdf[i * cdf_width].y = 0.0f;
-
- for(int j = 1; j < res_x; j++) {
- env_color = (*pixels)[i * res_x + j];
- ave_luminance = average(env_color);
-
- cond_cdf[i * cdf_width + j].x = ave_luminance * sin_theta;
- cond_cdf[i * cdf_width + j].y = cond_cdf[i * cdf_width + j - 1].y + cond_cdf[i * cdf_width + j - 1].x / res_x;
- }
-
- float cdf_total = cond_cdf[i * cdf_width + res_x - 1].y + cond_cdf[i * cdf_width + res_x - 1].x / res_x;
- float cdf_total_inv = 1.0f / cdf_total;
-
- /* stuff the total into the brightness value for the last entry, because
- * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
- cond_cdf[i * cdf_width + res_x].x = cdf_total;
-
- if(cdf_total > 0.0f)
- for(int j = 1; j < res_x; j++)
- cond_cdf[i * cdf_width + j].y *= cdf_total_inv;
-
- cond_cdf[i * cdf_width + res_x].y = 1.0f;
- }
+ int cdf_width = res_x + 1;
+ /* Conditional CDFs (rows, U direction). */
+ for (int i = start; i < end; i++) {
+ float sin_theta = sinf(M_PI_F * (i + 0.5f) / res_y);
+ float3 env_color = (*pixels)[i * res_x];
+ float ave_luminance = average(env_color);
+
+ cond_cdf[i * cdf_width].x = ave_luminance * sin_theta;
+ cond_cdf[i * cdf_width].y = 0.0f;
+
+ for (int j = 1; j < res_x; j++) {
+ env_color = (*pixels)[i * res_x + j];
+ ave_luminance = average(env_color);
+
+ cond_cdf[i * cdf_width + j].x = ave_luminance * sin_theta;
+ cond_cdf[i * cdf_width + j].y = cond_cdf[i * cdf_width + j - 1].y +
+ cond_cdf[i * cdf_width + j - 1].x / res_x;
+ }
+
+ float cdf_total = cond_cdf[i * cdf_width + res_x - 1].y +
+ cond_cdf[i * cdf_width + res_x - 1].x / res_x;
+ float cdf_total_inv = 1.0f / cdf_total;
+
+ /* stuff the total into the brightness value for the last entry, because
+ * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
+ cond_cdf[i * cdf_width + res_x].x = cdf_total;
+
+ if (cdf_total > 0.0f)
+ for (int j = 1; j < res_x; j++)
+ cond_cdf[i * cdf_width + j].y *= cdf_total_inv;
+
+ cond_cdf[i * cdf_width + res_x].y = 1.0f;
+ }
}
void LightManager::device_update_background(Device *device,
DeviceScene *dscene,
Scene *scene,
- Progress& progress)
+ Progress &progress)
{
- KernelIntegrator *kintegrator = &dscene->data.integrator;
- Light *background_light = NULL;
-
- /* find background light */
- foreach(Light *light, scene->lights) {
- if(light->type == LIGHT_BACKGROUND) {
- background_light = light;
- break;
- }
- }
-
- /* no background light found, signal renderer to skip sampling */
- if(!background_light || !background_light->is_enabled) {
- kintegrator->pdf_background_res_x = 0;
- kintegrator->pdf_background_res_y = 0;
- return;
- }
-
- progress.set_status("Updating Lights", "Importance map");
-
- assert(kintegrator->use_direct_light);
-
- /* get the resolution from the light's size (we stuff it in there) */
- int2 res = make_int2(background_light->map_resolution, background_light->map_resolution/2);
- /* If the resolution isn't set manually, try to find an environment texture. */
- if(res.x == 0) {
- Shader *shader = (scene->background->shader) ? scene->background->shader : scene->default_background;
- foreach(ShaderNode *node, shader->graph->nodes) {
- if(node->type == EnvironmentTextureNode::node_type) {
- EnvironmentTextureNode *env = (EnvironmentTextureNode*) node;
- ImageMetaData metadata;
- if(env->image_manager && env->image_manager->get_image_metadata(env->slot, metadata)) {
- res.x = max(res.x, metadata.width);
- res.y = max(res.y, metadata.height);
- }
- }
- }
- if(res.x > 0 && res.y > 0) {
- VLOG(2) << "Automatically set World MIS resolution to " << res.x << " by " << res.y << "\n";
- }
- }
- /* If it's still unknown, just use the default. */
- if(res.x == 0 || res.y == 0) {
- res = make_int2(1024, 512);
- VLOG(2) << "Setting World MIS resolution to default\n";
- }
- kintegrator->pdf_background_res_x = res.x;
- kintegrator->pdf_background_res_y = res.y;
-
- vector<float3> pixels;
- shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
-
- if(progress.get_cancel())
- return;
-
- /* build row distributions and column distribution for the infinite area environment light */
- int cdf_width = res.x+1;
- float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(res.y + 1);
- float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_width * res.y);
-
- double time_start = time_dt();
- if(max(res.x, res.y) < 512) {
- /* Small enough resolution, faster to do single-threaded. */
- background_cdf(0, res.y, res.x, res.y, &pixels, cond_cdf);
- }
- else {
- /* Threaded evaluation for large resolution. */
- const int num_blocks = TaskScheduler::num_threads();
- const int chunk_size = res.y / num_blocks;
- int start_row = 0;
- TaskPool pool;
- for(int i = 0; i < num_blocks; ++i) {
- const int current_chunk_size =
- (i != num_blocks - 1) ? chunk_size
- : (res.y - i * chunk_size);
- pool.push(function_bind(&background_cdf,
- start_row, start_row + current_chunk_size,
- res.x,
- res.y,
- &pixels,
- cond_cdf));
- start_row += current_chunk_size;
- }
- pool.wait_work();
- }
-
- /* marginal CDFs (column, V direction, sum of rows) */
- marg_cdf[0].x = cond_cdf[res.x].x;
- marg_cdf[0].y = 0.0f;
-
- for(int i = 1; i < res.y; i++) {
- marg_cdf[i].x = cond_cdf[i * cdf_width + res.x].x;
- marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res.y;
- }
-
- float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y;
- marg_cdf[res.y].x = cdf_total;
-
- if(cdf_total > 0.0f)
- for(int i = 1; i < res.y; i++)
- marg_cdf[i].y /= cdf_total;
-
- marg_cdf[res.y].y = 1.0f;
-
- VLOG(2) << "Background MIS build time " << time_dt() - time_start << "\n";
-
- /* update device */
- dscene->light_background_marginal_cdf.copy_to_device();
- dscene->light_background_conditional_cdf.copy_to_device();
+ KernelIntegrator *kintegrator = &dscene->data.integrator;
+ Light *background_light = NULL;
+
+ /* find background light */
+ foreach (Light *light, scene->lights) {
+ if (light->type == LIGHT_BACKGROUND) {
+ background_light = light;
+ break;
+ }
+ }
+
+ /* no background light found, signal renderer to skip sampling */
+ if (!background_light || !background_light->is_enabled) {
+ kintegrator->pdf_background_res_x = 0;
+ kintegrator->pdf_background_res_y = 0;
+ return;
+ }
+
+ progress.set_status("Updating Lights", "Importance map");
+
+ assert(kintegrator->use_direct_light);
+
+ /* get the resolution from the light's size (we stuff it in there) */
+ int2 res = make_int2(background_light->map_resolution, background_light->map_resolution / 2);
+ /* If the resolution isn't set manually, try to find an environment texture. */
+ if (res.x == 0) {
+ Shader *shader = (scene->background->shader) ? scene->background->shader :
+ scene->default_background;
+ foreach (ShaderNode *node, shader->graph->nodes) {
+ if (node->type == EnvironmentTextureNode::node_type) {
+ EnvironmentTextureNode *env = (EnvironmentTextureNode *)node;
+ ImageMetaData metadata;
+ if (env->image_manager && env->image_manager->get_image_metadata(env->slot, metadata)) {
+ res.x = max(res.x, metadata.width);
+ res.y = max(res.y, metadata.height);
+ }
+ }
+ }
+ if (res.x > 0 && res.y > 0) {
+ VLOG(2) << "Automatically set World MIS resolution to " << res.x << " by " << res.y << "\n";
+ }
+ }
+ /* If it's still unknown, just use the default. */
+ if (res.x == 0 || res.y == 0) {
+ res = make_int2(1024, 512);
+ VLOG(2) << "Setting World MIS resolution to default\n";
+ }
+ kintegrator->pdf_background_res_x = res.x;
+ kintegrator->pdf_background_res_y = res.y;
+
+ vector<float3> pixels;
+ shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
+
+ if (progress.get_cancel())
+ return;
+
+ /* build row distributions and column distribution for the infinite area environment light */
+ int cdf_width = res.x + 1;
+ float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(res.y + 1);
+ float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_width * res.y);
+
+ double time_start = time_dt();
+ if (max(res.x, res.y) < 512) {
+ /* Small enough resolution, faster to do single-threaded. */
+ background_cdf(0, res.y, res.x, res.y, &pixels, cond_cdf);
+ }
+ else {
+ /* Threaded evaluation for large resolution. */
+ const int num_blocks = TaskScheduler::num_threads();
+ const int chunk_size = res.y / num_blocks;
+ int start_row = 0;
+ TaskPool pool;
+ for (int i = 0; i < num_blocks; ++i) {
+ const int current_chunk_size = (i != num_blocks - 1) ? chunk_size : (res.y - i * chunk_size);
+ pool.push(function_bind(&background_cdf,
+ start_row,
+ start_row + current_chunk_size,
+ res.x,
+ res.y,
+ &pixels,
+ cond_cdf));
+ start_row += current_chunk_size;
+ }
+ pool.wait_work();
+ }
+
+ /* marginal CDFs (column, V direction, sum of rows) */
+ marg_cdf[0].x = cond_cdf[res.x].x;
+ marg_cdf[0].y = 0.0f;
+
+ for (int i = 1; i < res.y; i++) {
+ marg_cdf[i].x = cond_cdf[i * cdf_width + res.x].x;
+ marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res.y;
+ }
+
+ float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y;
+ marg_cdf[res.y].x = cdf_total;
+
+ if (cdf_total > 0.0f)
+ for (int i = 1; i < res.y; i++)
+ marg_cdf[i].y /= cdf_total;
+
+ marg_cdf[res.y].y = 1.0f;
+
+ VLOG(2) << "Background MIS build time " << time_dt() - time_start << "\n";
+
+ /* update device */
+ dscene->light_background_marginal_cdf.copy_to_device();
+ dscene->light_background_conditional_cdf.copy_to_device();
}
-void LightManager::device_update_points(Device *,
- DeviceScene *dscene,
- Scene *scene)
+void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *scene)
{
- int num_scene_lights = scene->lights.size();
-
- int num_lights = 0;
- foreach(Light *light, scene->lights) {
- if(light->is_enabled || light->is_portal) {
- num_lights++;
- }
- }
-
- KernelLight *klights = dscene->lights.alloc(num_lights);
-
- if(num_lights == 0) {
- VLOG(1) << "No effective light, ignoring points update.";
- return;
- }
-
- int light_index = 0;
-
- foreach(Light *light, scene->lights) {
- if(!light->is_enabled) {
- continue;
- }
-
- float3 co = light->co;
- Shader *shader = (light->shader) ? light->shader : scene->default_light;
- int shader_id = scene->shader_manager->get_shader_id(shader);
- int samples = light->samples;
- int max_bounces = light->max_bounces;
- float random = (float)light->random_id * (1.0f/(float)0xFFFFFFFF);
-
- if(!light->cast_shadow)
- shader_id &= ~SHADER_CAST_SHADOW;
-
- if(!light->use_diffuse) {
- shader_id |= SHADER_EXCLUDE_DIFFUSE;
- use_light_visibility = true;
- }
- if(!light->use_glossy) {
- shader_id |= SHADER_EXCLUDE_GLOSSY;
- use_light_visibility = true;
- }
- if(!light->use_transmission) {
- shader_id |= SHADER_EXCLUDE_TRANSMIT;
- use_light_visibility = true;
- }
- if(!light->use_scatter) {
- shader_id |= SHADER_EXCLUDE_SCATTER;
- use_light_visibility = true;
- }
-
- klights[light_index].type = light->type;
- klights[light_index].samples = samples;
-
- if(light->type == LIGHT_POINT) {
- shader_id &= ~SHADER_AREA_LIGHT;
-
- float radius = light->size;
- float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
-
- if(light->use_mis && radius > 0.0f)
- shader_id |= SHADER_USE_MIS;
-
- klights[light_index].co[0] = co.x;
- klights[light_index].co[1] = co.y;
- klights[light_index].co[2] = co.z;
-
- klights[light_index].spot.radius = radius;
- klights[light_index].spot.invarea = invarea;
- }
- else if(light->type == LIGHT_DISTANT) {
- shader_id &= ~SHADER_AREA_LIGHT;
-
- float radius = light->size;
- float angle = atanf(radius);
- float cosangle = cosf(angle);
- float area = M_PI_F*radius*radius;
- float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
- float3 dir = light->dir;
-
- dir = safe_normalize(dir);
-
- if(light->use_mis && area > 0.0f)
- shader_id |= SHADER_USE_MIS;
-
- klights[light_index].co[0] = dir.x;
- klights[light_index].co[1] = dir.y;
- klights[light_index].co[2] = dir.z;
-
- klights[light_index].distant.invarea = invarea;
- klights[light_index].distant.radius = radius;
- klights[light_index].distant.cosangle = cosangle;
- }
- else if(light->type == LIGHT_BACKGROUND) {
- uint visibility = scene->background->visibility;
-
- shader_id &= ~SHADER_AREA_LIGHT;
- shader_id |= SHADER_USE_MIS;
-
- if(!(visibility & PATH_RAY_DIFFUSE)) {
- shader_id |= SHADER_EXCLUDE_DIFFUSE;
- use_light_visibility = true;
- }
- if(!(visibility & PATH_RAY_GLOSSY)) {
- shader_id |= SHADER_EXCLUDE_GLOSSY;
- use_light_visibility = true;
- }
- if(!(visibility & PATH_RAY_TRANSMIT)) {
- shader_id |= SHADER_EXCLUDE_TRANSMIT;
- use_light_visibility = true;
- }
- if(!(visibility & PATH_RAY_VOLUME_SCATTER)) {
- shader_id |= SHADER_EXCLUDE_SCATTER;
- use_light_visibility = true;
- }
- }
- else if(light->type == LIGHT_AREA) {
- float3 axisu = light->axisu*(light->sizeu*light->size);
- float3 axisv = light->axisv*(light->sizev*light->size);
- float area = len(axisu)*len(axisv);
- if(light->round) {
- area *= -M_PI_4_F;
- }
- float invarea = (area != 0.0f)? 1.0f/area: 1.0f;
- float3 dir = light->dir;
-
- dir = safe_normalize(dir);
-
- if(light->use_mis && area != 0.0f)
- shader_id |= SHADER_USE_MIS;
-
- klights[light_index].co[0] = co.x;
- klights[light_index].co[1] = co.y;
- klights[light_index].co[2] = co.z;
-
- klights[light_index].area.axisu[0] = axisu.x;
- klights[light_index].area.axisu[1] = axisu.y;
- klights[light_index].area.axisu[2] = axisu.z;
- klights[light_index].area.axisv[0] = axisv.x;
- klights[light_index].area.axisv[1] = axisv.y;
- klights[light_index].area.axisv[2] = axisv.z;
- klights[light_index].area.invarea = invarea;
- klights[light_index].area.dir[0] = dir.x;
- klights[light_index].area.dir[1] = dir.y;
- klights[light_index].area.dir[2] = dir.z;
- }
- else if(light->type == LIGHT_SPOT) {
- shader_id &= ~SHADER_AREA_LIGHT;
-
- float radius = light->size;
- float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
- float spot_angle = cosf(light->spot_angle*0.5f);
- float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
- float3 dir = light->dir;
-
- dir = safe_normalize(dir);
-
- if(light->use_mis && radius > 0.0f)
- shader_id |= SHADER_USE_MIS;
-
- klights[light_index].co[0] = co.x;
- klights[light_index].co[1] = co.y;
- klights[light_index].co[2] = co.z;
-
- klights[light_index].spot.radius = radius;
- klights[light_index].spot.invarea = invarea;
- klights[light_index].spot.spot_angle = spot_angle;
- klights[light_index].spot.spot_smooth = spot_smooth;
- klights[light_index].spot.dir[0] = dir.x;
- klights[light_index].spot.dir[1] = dir.y;
- klights[light_index].spot.dir[2] = dir.z;
- }
-
- klights[light_index].shader_id = shader_id;
-
- klights[light_index].max_bounces = max_bounces;
- klights[light_index].random = random;
-
- klights[light_index].tfm = light->tfm;
- klights[light_index].itfm = transform_inverse(light->tfm);
-
- light_index++;
- }
-
- /* TODO(sergey): Consider moving portals update to their own function
- * keeping this one more manageable.
- */
- foreach(Light *light, scene->lights) {
- if(!light->is_portal)
- continue;
- assert(light->type == LIGHT_AREA);
-
- float3 co = light->co;
- float3 axisu = light->axisu*(light->sizeu*light->size);
- float3 axisv = light->axisv*(light->sizev*light->size);
- float area = len(axisu)*len(axisv);
- if(light->round) {
- area *= -M_PI_4_F;
- }
- float invarea = (area != 0.0f)? 1.0f/area: 1.0f;
- float3 dir = light->dir;
-
- dir = safe_normalize(dir);
-
- klights[light_index].co[0] = co.x;
- klights[light_index].co[1] = co.y;
- klights[light_index].co[2] = co.z;
-
- klights[light_index].area.axisu[0] = axisu.x;
- klights[light_index].area.axisu[1] = axisu.y;
- klights[light_index].area.axisu[2] = axisu.z;
- klights[light_index].area.axisv[0] = axisv.x;
- klights[light_index].area.axisv[1] = axisv.y;
- klights[light_index].area.axisv[2] = axisv.z;
- klights[light_index].area.invarea = invarea;
- klights[light_index].area.dir[0] = dir.x;
- klights[light_index].area.dir[1] = dir.y;
- klights[light_index].area.dir[2] = dir.z;
- klights[light_index].tfm = light->tfm;
- klights[light_index].itfm = transform_inverse(light->tfm);
-
- light_index++;
- }
-
- VLOG(1) << "Number of lights sent to the device: " << light_index;
-
- VLOG(1) << "Number of lights without contribution: "
- << num_scene_lights - light_index;
-
- dscene->lights.copy_to_device();
+ int num_scene_lights = scene->lights.size();
+
+ int num_lights = 0;
+ foreach (Light *light, scene->lights) {
+ if (light->is_enabled || light->is_portal) {
+ num_lights++;
+ }
+ }
+
+ KernelLight *klights = dscene->lights.alloc(num_lights);
+
+ if (num_lights == 0) {
+ VLOG(1) << "No effective light, ignoring points update.";
+ return;
+ }
+
+ int light_index = 0;
+
+ foreach (Light *light, scene->lights) {
+ if (!light->is_enabled) {
+ continue;
+ }
+
+ float3 co = light->co;
+ Shader *shader = (light->shader) ? light->shader : scene->default_light;
+ int shader_id = scene->shader_manager->get_shader_id(shader);
+ int samples = light->samples;
+ int max_bounces = light->max_bounces;
+ float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF);
+
+ if (!light->cast_shadow)
+ shader_id &= ~SHADER_CAST_SHADOW;
+
+ if (!light->use_diffuse) {
+ shader_id |= SHADER_EXCLUDE_DIFFUSE;
+ use_light_visibility = true;
+ }
+ if (!light->use_glossy) {
+ shader_id |= SHADER_EXCLUDE_GLOSSY;
+ use_light_visibility = true;
+ }
+ if (!light->use_transmission) {
+ shader_id |= SHADER_EXCLUDE_TRANSMIT;
+ use_light_visibility = true;
+ }
+ if (!light->use_scatter) {
+ shader_id |= SHADER_EXCLUDE_SCATTER;
+ use_light_visibility = true;
+ }
+
+ klights[light_index].type = light->type;
+ klights[light_index].samples = samples;
+
+ if (light->type == LIGHT_POINT) {
+ shader_id &= ~SHADER_AREA_LIGHT;
+
+ float radius = light->size;
+ float invarea = (radius > 0.0f) ? 1.0f / (M_PI_F * radius * radius) : 1.0f;
+
+ if (light->use_mis && radius > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
+ klights[light_index].co[0] = co.x;
+ klights[light_index].co[1] = co.y;
+ klights[light_index].co[2] = co.z;
+
+ klights[light_index].spot.radius = radius;
+ klights[light_index].spot.invarea = invarea;
+ }
+ else if (light->type == LIGHT_DISTANT) {
+ shader_id &= ~SHADER_AREA_LIGHT;
+
+ float radius = light->size;
+ float angle = atanf(radius);
+ float cosangle = cosf(angle);
+ float area = M_PI_F * radius * radius;
+ float invarea = (area > 0.0f) ? 1.0f / area : 1.0f;
+ float3 dir = light->dir;
+
+ dir = safe_normalize(dir);
+
+ if (light->use_mis && area > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
+ klights[light_index].co[0] = dir.x;
+ klights[light_index].co[1] = dir.y;
+ klights[light_index].co[2] = dir.z;
+
+ klights[light_index].distant.invarea = invarea;
+ klights[light_index].distant.radius = radius;
+ klights[light_index].distant.cosangle = cosangle;
+ }
+ else if (light->type == LIGHT_BACKGROUND) {
+ uint visibility = scene->background->visibility;
+
+ shader_id &= ~SHADER_AREA_LIGHT;
+ shader_id |= SHADER_USE_MIS;
+
+ if (!(visibility & PATH_RAY_DIFFUSE)) {
+ shader_id |= SHADER_EXCLUDE_DIFFUSE;
+ use_light_visibility = true;
+ }
+ if (!(visibility & PATH_RAY_GLOSSY)) {
+ shader_id |= SHADER_EXCLUDE_GLOSSY;
+ use_light_visibility = true;
+ }
+ if (!(visibility & PATH_RAY_TRANSMIT)) {
+ shader_id |= SHADER_EXCLUDE_TRANSMIT;
+ use_light_visibility = true;
+ }
+ if (!(visibility & PATH_RAY_VOLUME_SCATTER)) {
+ shader_id |= SHADER_EXCLUDE_SCATTER;
+ use_light_visibility = true;
+ }
+ }
+ else if (light->type == LIGHT_AREA) {
+ float3 axisu = light->axisu * (light->sizeu * light->size);
+ float3 axisv = light->axisv * (light->sizev * light->size);
+ float area = len(axisu) * len(axisv);
+ if (light->round) {
+ area *= -M_PI_4_F;
+ }
+ float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
+ float3 dir = light->dir;
+
+ dir = safe_normalize(dir);
+
+ if (light->use_mis && area != 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
+ klights[light_index].co[0] = co.x;
+ klights[light_index].co[1] = co.y;
+ klights[light_index].co[2] = co.z;
+
+ klights[light_index].area.axisu[0] = axisu.x;
+ klights[light_index].area.axisu[1] = axisu.y;
+ klights[light_index].area.axisu[2] = axisu.z;
+ klights[light_index].area.axisv[0] = axisv.x;
+ klights[light_index].area.axisv[1] = axisv.y;
+ klights[light_index].area.axisv[2] = axisv.z;
+ klights[light_index].area.invarea = invarea;
+ klights[light_index].area.dir[0] = dir.x;
+ klights[light_index].area.dir[1] = dir.y;
+ klights[light_index].area.dir[2] = dir.z;
+ }
+ else if (light->type == LIGHT_SPOT) {
+ shader_id &= ~SHADER_AREA_LIGHT;
+
+ float radius = light->size;
+ float invarea = (radius > 0.0f) ? 1.0f / (M_PI_F * radius * radius) : 1.0f;
+ float spot_angle = cosf(light->spot_angle * 0.5f);
+ float spot_smooth = (1.0f - spot_angle) * light->spot_smooth;
+ float3 dir = light->dir;
+
+ dir = safe_normalize(dir);
+
+ if (light->use_mis && radius > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
+ klights[light_index].co[0] = co.x;
+ klights[light_index].co[1] = co.y;
+ klights[light_index].co[2] = co.z;
+
+ klights[light_index].spot.radius = radius;
+ klights[light_index].spot.invarea = invarea;
+ klights[light_index].spot.spot_angle = spot_angle;
+ klights[light_index].spot.spot_smooth = spot_smooth;
+ klights[light_index].spot.dir[0] = dir.x;
+ klights[light_index].spot.dir[1] = dir.y;
+ klights[light_index].spot.dir[2] = dir.z;
+ }
+
+ klights[light_index].shader_id = shader_id;
+
+ klights[light_index].max_bounces = max_bounces;
+ klights[light_index].random = random;
+
+ klights[light_index].tfm = light->tfm;
+ klights[light_index].itfm = transform_inverse(light->tfm);
+
+ light_index++;
+ }
+
+ /* TODO(sergey): Consider moving portals update to their own function
+ * keeping this one more manageable.
+ */
+ foreach (Light *light, scene->lights) {
+ if (!light->is_portal)
+ continue;
+ assert(light->type == LIGHT_AREA);
+
+ float3 co = light->co;
+ float3 axisu = light->axisu * (light->sizeu * light->size);
+ float3 axisv = light->axisv * (light->sizev * light->size);
+ float area = len(axisu) * len(axisv);
+ if (light->round) {
+ area *= -M_PI_4_F;
+ }
+ float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
+ float3 dir = light->dir;
+
+ dir = safe_normalize(dir);
+
+ klights[light_index].co[0] = co.x;
+ klights[light_index].co[1] = co.y;
+ klights[light_index].co[2] = co.z;
+
+ klights[light_index].area.axisu[0] = axisu.x;
+ klights[light_index].area.axisu[1] = axisu.y;
+ klights[light_index].area.axisu[2] = axisu.z;
+ klights[light_index].area.axisv[0] = axisv.x;
+ klights[light_index].area.axisv[1] = axisv.y;
+ klights[light_index].area.axisv[2] = axisv.z;
+ klights[light_index].area.invarea = invarea;
+ klights[light_index].area.dir[0] = dir.x;
+ klights[light_index].area.dir[1] = dir.y;
+ klights[light_index].area.dir[2] = dir.z;
+ klights[light_index].tfm = light->tfm;
+ klights[light_index].itfm = transform_inverse(light->tfm);
+
+ light_index++;
+ }
+
+ VLOG(1) << "Number of lights sent to the device: " << light_index;
+
+ VLOG(1) << "Number of lights without contribution: " << num_scene_lights - light_index;
+
+ dscene->lights.copy_to_device();
}
-void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+void LightManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- VLOG(1) << "Total " << scene->lights.size() << " lights.";
+ VLOG(1) << "Total " << scene->lights.size() << " lights.";
- device_free(device, dscene);
+ device_free(device, dscene);
- use_light_visibility = false;
+ use_light_visibility = false;
- disable_ineffective_light(scene);
+ disable_ineffective_light(scene);
- device_update_points(device, dscene, scene);
- if(progress.get_cancel()) return;
+ device_update_points(device, dscene, scene);
+ if (progress.get_cancel())
+ return;
- device_update_distribution(device, dscene, scene, progress);
- if(progress.get_cancel()) return;
+ device_update_distribution(device, dscene, scene, progress);
+ if (progress.get_cancel())
+ return;
- device_update_background(device, dscene, scene, progress);
- if(progress.get_cancel()) return;
+ device_update_background(device, dscene, scene, progress);
+ if (progress.get_cancel())
+ return;
- device_update_ies(dscene);
- if(progress.get_cancel()) return;
+ device_update_ies(dscene);
+ if (progress.get_cancel())
+ return;
- if(use_light_visibility != scene->film->use_light_visibility) {
- scene->film->use_light_visibility = use_light_visibility;
- scene->film->tag_update(scene);
- }
+ if (use_light_visibility != scene->film->use_light_visibility) {
+ scene->film->use_light_visibility = use_light_visibility;
+ scene->film->tag_update(scene);
+ }
- need_update = false;
+ need_update = false;
}
void LightManager::device_free(Device *, DeviceScene *dscene)
{
- dscene->light_distribution.free();
- dscene->lights.free();
- dscene->light_background_marginal_cdf.free();
- dscene->light_background_conditional_cdf.free();
- dscene->ies_lights.free();
+ dscene->light_distribution.free();
+ dscene->lights.free();
+ dscene->light_background_marginal_cdf.free();
+ dscene->light_background_conditional_cdf.free();
+ dscene->ies_lights.free();
}
void LightManager::tag_update(Scene * /*scene*/)
{
- need_update = true;
+ need_update = true;
}
int LightManager::add_ies_from_file(ustring filename)
{
- string content;
+ string content;
- /* If the file can't be opened, call with an empty line */
- if(filename.empty() || !path_read_text(filename.c_str(), content)) {
- content = "\n";
- }
+ /* If the file can't be opened, call with an empty line */
+ if (filename.empty() || !path_read_text(filename.c_str(), content)) {
+ content = "\n";
+ }
- return add_ies(ustring(content));
+ return add_ies(ustring(content));
}
int LightManager::add_ies(ustring content)
{
- uint hash = hash_string(content.c_str());
-
- thread_scoped_lock ies_lock(ies_mutex);
-
- /* Check whether this IES already has a slot. */
- size_t slot;
- for(slot = 0; slot < ies_slots.size(); slot++) {
- if(ies_slots[slot]->hash == hash) {
- ies_slots[slot]->users++;
- return slot;
- }
- }
-
- /* Try to find an empty slot for the new IES. */
- for(slot = 0; slot < ies_slots.size(); slot++) {
- if(ies_slots[slot]->users == 0 && ies_slots[slot]->hash == 0) {
- break;
- }
- }
-
- /* If there's no free slot, add one. */
- if(slot == ies_slots.size()) {
- ies_slots.push_back(new IESSlot());
- }
-
- ies_slots[slot]->ies.load(content);
- ies_slots[slot]->users = 1;
- ies_slots[slot]->hash = hash;
-
- need_update = true;
-
- return slot;
+ uint hash = hash_string(content.c_str());
+
+ thread_scoped_lock ies_lock(ies_mutex);
+
+ /* Check whether this IES already has a slot. */
+ size_t slot;
+ for (slot = 0; slot < ies_slots.size(); slot++) {
+ if (ies_slots[slot]->hash == hash) {
+ ies_slots[slot]->users++;
+ return slot;
+ }
+ }
+
+ /* Try to find an empty slot for the new IES. */
+ for (slot = 0; slot < ies_slots.size(); slot++) {
+ if (ies_slots[slot]->users == 0 && ies_slots[slot]->hash == 0) {
+ break;
+ }
+ }
+
+ /* If there's no free slot, add one. */
+ if (slot == ies_slots.size()) {
+ ies_slots.push_back(new IESSlot());
+ }
+
+ ies_slots[slot]->ies.load(content);
+ ies_slots[slot]->users = 1;
+ ies_slots[slot]->hash = hash;
+
+ need_update = true;
+
+ return slot;
}
void LightManager::remove_ies(int slot)
{
- thread_scoped_lock ies_lock(ies_mutex);
+ thread_scoped_lock ies_lock(ies_mutex);
- if(slot < 0 || slot >= ies_slots.size()) {
- assert(false);
- return;
- }
+ if (slot < 0 || slot >= ies_slots.size()) {
+ assert(false);
+ return;
+ }
- assert(ies_slots[slot]->users > 0);
- ies_slots[slot]->users--;
+ assert(ies_slots[slot]->users > 0);
+ ies_slots[slot]->users--;
- /* If the slot has no more users, update the device to remove it. */
- need_update |= (ies_slots[slot]->users == 0);
+ /* If the slot has no more users, update the device to remove it. */
+ need_update |= (ies_slots[slot]->users == 0);
}
void LightManager::device_update_ies(DeviceScene *dscene)
{
- /* Clear empty slots. */
- foreach(IESSlot *slot, ies_slots) {
- if(slot->users == 0) {
- slot->hash = 0;
- slot->ies.clear();
- }
- }
-
- /* Shrink the slot table by removing empty slots at the end. */
- int slot_end;
- for(slot_end = ies_slots.size(); slot_end; slot_end--) {
- if(ies_slots[slot_end-1]->users > 0) {
- /* If the preceding slot has users, we found the new end of the table. */
- break;
- }
- else {
- /* The slot will be past the new end of the table, so free it. */
- delete ies_slots[slot_end-1];
- }
- }
- ies_slots.resize(slot_end);
-
- if(ies_slots.size() > 0) {
- int packed_size = 0;
- foreach(IESSlot *slot, ies_slots) {
- packed_size += slot->ies.packed_size();
- }
-
- /* ies_lights starts with an offset table that contains the offset of every slot,
- * or -1 if the slot is invalid.
- * Following that table, the packed valid IES lights are stored. */
- float *data = dscene->ies_lights.alloc(ies_slots.size() + packed_size);
-
- int offset = ies_slots.size();
- for(int i = 0; i < ies_slots.size(); i++) {
- int size = ies_slots[i]->ies.packed_size();
- if(size > 0) {
- data[i] = __int_as_float(offset);
- ies_slots[i]->ies.pack(data + offset);
- offset += size;
- }
- else {
- data[i] = __int_as_float(-1);
- }
- }
-
- dscene->ies_lights.copy_to_device();
- }
+ /* Clear empty slots. */
+ foreach (IESSlot *slot, ies_slots) {
+ if (slot->users == 0) {
+ slot->hash = 0;
+ slot->ies.clear();
+ }
+ }
+
+ /* Shrink the slot table by removing empty slots at the end. */
+ int slot_end;
+ for (slot_end = ies_slots.size(); slot_end; slot_end--) {
+ if (ies_slots[slot_end - 1]->users > 0) {
+ /* If the preceding slot has users, we found the new end of the table. */
+ break;
+ }
+ else {
+ /* The slot will be past the new end of the table, so free it. */
+ delete ies_slots[slot_end - 1];
+ }
+ }
+ ies_slots.resize(slot_end);
+
+ if (ies_slots.size() > 0) {
+ int packed_size = 0;
+ foreach (IESSlot *slot, ies_slots) {
+ packed_size += slot->ies.packed_size();
+ }
+
+ /* ies_lights starts with an offset table that contains the offset of every slot,
+ * or -1 if the slot is invalid.
+ * Following that table, the packed valid IES lights are stored. */
+ float *data = dscene->ies_lights.alloc(ies_slots.size() + packed_size);
+
+ int offset = ies_slots.size();
+ for (int i = 0; i < ies_slots.size(); i++) {
+ int size = ies_slots[i]->ies.packed_size();
+ if (size > 0) {
+ data[i] = __int_as_float(offset);
+ ies_slots[i]->ies.pack(data + offset);
+ offset += size;
+ }
+ else {
+ data[i] = __int_as_float(-1);
+ }
+ }
+
+ dscene->ies_lights.copy_to_device();
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index a627ec9bdc3..66732000f3b 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -36,108 +36,103 @@ class Scene;
class Shader;
class Light : public Node {
-public:
- NODE_DECLARE;
+ public:
+ NODE_DECLARE;
- Light();
+ Light();
- LightType type;
- float3 co;
+ LightType type;
+ float3 co;
- float3 dir;
- float size;
+ float3 dir;
+ float size;
- float3 axisu;
- float sizeu;
- float3 axisv;
- float sizev;
- bool round;
+ float3 axisu;
+ float sizeu;
+ float3 axisv;
+ float sizev;
+ bool round;
- Transform tfm;
+ Transform tfm;
- int map_resolution;
+ int map_resolution;
- float spot_angle;
- float spot_smooth;
+ float spot_angle;
+ float spot_smooth;
- bool cast_shadow;
- bool use_mis;
- bool use_diffuse;
- bool use_glossy;
- bool use_transmission;
- bool use_scatter;
+ bool cast_shadow;
+ bool use_mis;
+ bool use_diffuse;
+ bool use_glossy;
+ bool use_transmission;
+ bool use_scatter;
- bool is_portal;
- bool is_enabled;
+ bool is_portal;
+ bool is_enabled;
- Shader *shader;
- int samples;
- int max_bounces;
- uint random_id;
+ Shader *shader;
+ int samples;
+ int max_bounces;
+ uint random_id;
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene);
- /* Check whether the light has contribution the the scene. */
- bool has_contribution(Scene *scene);
+ /* Check whether the light has contribution the the scene. */
+ bool has_contribution(Scene *scene);
};
class LightManager {
-public:
- bool use_light_visibility;
- bool need_update;
-
- LightManager();
- ~LightManager();
-
- /* IES texture management */
- int add_ies(ustring ies);
- int add_ies_from_file(ustring filename);
- void remove_ies(int slot);
-
- void device_update(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress& progress);
- void device_free(Device *device, DeviceScene *dscene);
-
- void tag_update(Scene *scene);
-
- /* Check whether there is a background light. */
- bool has_background_light(Scene *scene);
-
-protected:
- /* Optimization: disable light which is either unsupported or
- * which doesn't contribute to the scene or which is only used for MIS
- * and scene doesn't need MIS.
- */
- void disable_ineffective_light(Scene *scene);
-
- void device_update_points(Device *device,
- DeviceScene *dscene,
- Scene *scene);
- void device_update_distribution(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress& progress);
- void device_update_background(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress& progress);
- void device_update_ies(DeviceScene *dscene);
-
- /* Check whether light manager can use the object as a light-emissive. */
- bool object_usable_as_light(Object *object);
-
- struct IESSlot {
- IESFile ies;
- uint hash;
- int users;
- };
-
- vector<IESSlot*> ies_slots;
- thread_mutex ies_mutex;
+ public:
+ bool use_light_visibility;
+ bool need_update;
+
+ LightManager();
+ ~LightManager();
+
+ /* IES texture management */
+ int add_ies(ustring ies);
+ int add_ies_from_file(ustring filename);
+ void remove_ies(int slot);
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_free(Device *device, DeviceScene *dscene);
+
+ void tag_update(Scene *scene);
+
+ /* Check whether there is a background light. */
+ bool has_background_light(Scene *scene);
+
+ protected:
+ /* Optimization: disable light which is either unsupported or
+ * which doesn't contribute to the scene or which is only used for MIS
+ * and scene doesn't need MIS.
+ */
+ void disable_ineffective_light(Scene *scene);
+
+ void device_update_points(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_update_distribution(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress);
+ void device_update_background(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress);
+ void device_update_ies(DeviceScene *dscene);
+
+ /* Check whether light manager can use the object as a light-emissive. */
+ bool object_usable_as_light(Object *object);
+
+ struct IESSlot {
+ IESFile ies;
+ uint hash;
+ int users;
+ };
+
+ vector<IESSlot *> ies_slots;
+ thread_mutex ies_mutex;
};
CCL_NAMESPACE_END
-#endif /* __LIGHT_H__ */
+#endif /* __LIGHT_H__ */
diff --git a/intern/cycles/render/merge.cpp b/intern/cycles/render/merge.cpp
index 289bb023d72..cac07e59fe3 100644
--- a/intern/cycles/render/merge.cpp
+++ b/intern/cycles/render/merge.cpp
@@ -32,453 +32,443 @@ CCL_NAMESPACE_BEGIN
/* Merge Image Layer */
enum MergeChannelOp {
- MERGE_CHANNEL_NOP,
- MERGE_CHANNEL_COPY,
- MERGE_CHANNEL_SUM,
- MERGE_CHANNEL_AVERAGE
+ MERGE_CHANNEL_NOP,
+ MERGE_CHANNEL_COPY,
+ MERGE_CHANNEL_SUM,
+ MERGE_CHANNEL_AVERAGE
};
struct MergeImagePass {
- /* Full channel name. */
- string channel_name;
- /* Channel format in the file. */
- TypeDesc format;
- /* Type of operation to perform when merging. */
- MergeChannelOp op;
- /* Offset of layer channels in input image. */
- int offset;
- /* Offset of layer channels in merged image. */
- int merge_offset;
+ /* Full channel name. */
+ string channel_name;
+ /* Channel format in the file. */
+ TypeDesc format;
+ /* Type of operation to perform when merging. */
+ MergeChannelOp op;
+ /* Offset of layer channels in input image. */
+ int offset;
+ /* Offset of layer channels in merged image. */
+ int merge_offset;
};
struct MergeImageLayer {
- /* Layer name. */
- string name;
- /* Passes. */
- vector<MergeImagePass> passes;
- /* Sample amount that was used for rendering this layer. */
- int samples;
+ /* Layer name. */
+ string name;
+ /* Passes. */
+ vector<MergeImagePass> passes;
+ /* Sample amount that was used for rendering this layer. */
+ int samples;
};
/* Merge Image */
struct MergeImage {
- /* OIIO file handle. */
- unique_ptr<ImageInput> in;
- /* Image file path. */
- string filepath;
- /* Render layers. */
- vector<MergeImageLayer> layers;
+ /* OIIO file handle. */
+ unique_ptr<ImageInput> in;
+ /* Image file path. */
+ string filepath;
+ /* Render layers. */
+ vector<MergeImageLayer> layers;
};
/* Channel Parsing */
-static MergeChannelOp parse_channel_operation(const string& pass_name)
+static MergeChannelOp parse_channel_operation(const string &pass_name)
{
- if(pass_name == "Depth" ||
- pass_name == "IndexMA" ||
- pass_name == "IndexOB" ||
- string_startswith(pass_name, "Crypto"))
- {
- return MERGE_CHANNEL_COPY;
- }
- else if(string_startswith(pass_name, "Debug BVH") ||
- string_startswith(pass_name, "Debug Ray") ||
- string_startswith(pass_name, "Debug Render Time"))
- {
- return MERGE_CHANNEL_SUM;
- }
- else {
- return MERGE_CHANNEL_AVERAGE;
- }
+ if (pass_name == "Depth" || pass_name == "IndexMA" || pass_name == "IndexOB" ||
+ string_startswith(pass_name, "Crypto")) {
+ return MERGE_CHANNEL_COPY;
+ }
+ else if (string_startswith(pass_name, "Debug BVH") ||
+ string_startswith(pass_name, "Debug Ray") ||
+ string_startswith(pass_name, "Debug Render Time")) {
+ return MERGE_CHANNEL_SUM;
+ }
+ else {
+ return MERGE_CHANNEL_AVERAGE;
+ }
}
/* Splits in at its last dot, setting suffix to the part after the dot and
* into the part before it. Returns whether a dot was found. */
static bool split_last_dot(string &in, string &suffix)
{
- size_t pos = in.rfind(".");
- if(pos == string::npos) {
- return false;
- }
- suffix = in.substr(pos+1);
- in = in.substr(0, pos);
- return true;
+ size_t pos = in.rfind(".");
+ if (pos == string::npos) {
+ return false;
+ }
+ suffix = in.substr(pos + 1);
+ in = in.substr(0, pos);
+ return true;
}
/* Separate channel names as generated by Blender.
* Multiview format: RenderLayer.Pass.View.Channel
* Otherwise: RenderLayer.Pass.Channel */
-static bool parse_channel_name(string name,
- string &renderlayer,
- string &pass,
- string &channel,
- bool multiview_channels)
+static bool parse_channel_name(
+ string name, string &renderlayer, string &pass, string &channel, bool multiview_channels)
{
- if(!split_last_dot(name, channel)) {
- return false;
- }
- string view;
- if(multiview_channels && !split_last_dot(name, view)) {
- return false;
- }
- if(!split_last_dot(name, pass)) {
- return false;
- }
- renderlayer = name;
-
- if(multiview_channels) {
- renderlayer += "." + view;
- }
-
- return true;
+ if (!split_last_dot(name, channel)) {
+ return false;
+ }
+ string view;
+ if (multiview_channels && !split_last_dot(name, view)) {
+ return false;
+ }
+ if (!split_last_dot(name, pass)) {
+ return false;
+ }
+ renderlayer = name;
+
+ if (multiview_channels) {
+ renderlayer += "." + view;
+ }
+
+ return true;
}
static bool parse_channels(const ImageSpec &in_spec,
- vector<MergeImageLayer>& layers,
- string& error)
+ vector<MergeImageLayer> &layers,
+ string &error)
{
- const ParamValue *multiview = in_spec.find_attribute("multiView");
- const bool multiview_channels = (multiview &&
- multiview->type().basetype == TypeDesc::STRING &&
- multiview->type().arraylen >= 2);
-
- layers.clear();
-
- /* Loop over all the channels in the file, parse their name and sort them
- * by RenderLayer.
- * Channels that can't be parsed are directly passed through to the output. */
- map<string, MergeImageLayer> file_layers;
- for(int i = 0; i < in_spec.nchannels; i++) {
- MergeImagePass pass;
- pass.channel_name = in_spec.channelnames[i];
- pass.format = (in_spec.channelformats.size() > 0) ? in_spec.channelformats[i] : in_spec.format;
- pass.offset = i;
- pass.merge_offset = i;
-
- string layername, passname, channelname;
- if(parse_channel_name(pass.channel_name, layername, passname, channelname, multiview_channels)) {
- /* Channer part of a render layer. */
- pass.op = parse_channel_operation(passname);
- }
- else {
- /* Other channels are added in unnamed layer. */
- layername = "";
- pass.op = parse_channel_operation(pass.channel_name);
- }
-
- file_layers[layername].passes.push_back(pass);
- }
-
- /* Loop over all detected RenderLayers, check whether they contain a full set of input channels.
- * Any channels that won't be processed internally are also passed through. */
- for(auto& i: file_layers) {
- const string& name = i.first;
- MergeImageLayer& layer = i.second;
-
- layer.name = name;
- layer.samples = 0;
-
- /* Determine number of samples from metadata. */
- if(layer.name == "") {
- layer.samples = 1;
- }
- else if(layer.samples < 1) {
- string sample_string = in_spec.get_string_attribute("cycles." + name + ".samples", "");
- if(sample_string != "") {
- if(!sscanf(sample_string.c_str(), "%d", &layer.samples)) {
- error = "Failed to parse samples metadata: " + sample_string;
- return false;
- }
- }
- }
-
- if(layer.samples < 1) {
- error = string_printf("No sample number specified in the file for layer %s or on the command line", name.c_str());
- return false;
- }
-
- layers.push_back(layer);
- }
-
- return true;
+ const ParamValue *multiview = in_spec.find_attribute("multiView");
+ const bool multiview_channels = (multiview && multiview->type().basetype == TypeDesc::STRING &&
+ multiview->type().arraylen >= 2);
+
+ layers.clear();
+
+ /* Loop over all the channels in the file, parse their name and sort them
+ * by RenderLayer.
+ * Channels that can't be parsed are directly passed through to the output. */
+ map<string, MergeImageLayer> file_layers;
+ for (int i = 0; i < in_spec.nchannels; i++) {
+ MergeImagePass pass;
+ pass.channel_name = in_spec.channelnames[i];
+ pass.format = (in_spec.channelformats.size() > 0) ? in_spec.channelformats[i] : in_spec.format;
+ pass.offset = i;
+ pass.merge_offset = i;
+
+ string layername, passname, channelname;
+ if (parse_channel_name(
+ pass.channel_name, layername, passname, channelname, multiview_channels)) {
+ /* Channer part of a render layer. */
+ pass.op = parse_channel_operation(passname);
+ }
+ else {
+ /* Other channels are added in unnamed layer. */
+ layername = "";
+ pass.op = parse_channel_operation(pass.channel_name);
+ }
+
+ file_layers[layername].passes.push_back(pass);
+ }
+
+ /* Loop over all detected RenderLayers, check whether they contain a full set of input channels.
+ * Any channels that won't be processed internally are also passed through. */
+ for (auto &i : file_layers) {
+ const string &name = i.first;
+ MergeImageLayer &layer = i.second;
+
+ layer.name = name;
+ layer.samples = 0;
+
+ /* Determine number of samples from metadata. */
+ if (layer.name == "") {
+ layer.samples = 1;
+ }
+ else if (layer.samples < 1) {
+ string sample_string = in_spec.get_string_attribute("cycles." + name + ".samples", "");
+ if (sample_string != "") {
+ if (!sscanf(sample_string.c_str(), "%d", &layer.samples)) {
+ error = "Failed to parse samples metadata: " + sample_string;
+ return false;
+ }
+ }
+ }
+
+ if (layer.samples < 1) {
+ error = string_printf(
+ "No sample number specified in the file for layer %s or on the command line",
+ name.c_str());
+ return false;
+ }
+
+ layers.push_back(layer);
+ }
+
+ return true;
}
-static bool open_images(const vector<string>& filepaths,
- vector<MergeImage>& images,
- string& error)
+static bool open_images(const vector<string> &filepaths, vector<MergeImage> &images, string &error)
{
- for(const string& filepath: filepaths) {
- unique_ptr<ImageInput> in(ImageInput::open(filepath));
- if(!in) {
- error = "Couldn't open file: " + filepath;
- return false;
- }
-
- MergeImage image;
- image.in = std::move(in);
- image.filepath = filepath;
- if(!parse_channels(image.in->spec(), image.layers, error)) {
- return false;
- }
-
- if(image.layers.size() == 0) {
- error = "Could not find a render layer for merging";
- return false;
- }
-
- if(image.in->spec().deep) {
- error = "Merging deep images not supported.";
- return false;
- }
-
- if(images.size() > 0) {
- const ImageSpec& base_spec = images[0].in->spec();
- const ImageSpec& spec = image.in->spec();
-
- if(base_spec.width != spec.width ||
- base_spec.height != spec.height ||
- base_spec.depth != spec.depth ||
- base_spec.format != spec.format ||
- base_spec.deep != spec.deep)
- {
- error = "Images do not have matching size and data layout.";
- return false;
- }
- }
-
- images.push_back(std::move(image));
- }
-
- return true;
+ for (const string &filepath : filepaths) {
+ unique_ptr<ImageInput> in(ImageInput::open(filepath));
+ if (!in) {
+ error = "Couldn't open file: " + filepath;
+ return false;
+ }
+
+ MergeImage image;
+ image.in = std::move(in);
+ image.filepath = filepath;
+ if (!parse_channels(image.in->spec(), image.layers, error)) {
+ return false;
+ }
+
+ if (image.layers.size() == 0) {
+ error = "Could not find a render layer for merging";
+ return false;
+ }
+
+ if (image.in->spec().deep) {
+ error = "Merging deep images not supported.";
+ return false;
+ }
+
+ if (images.size() > 0) {
+ const ImageSpec &base_spec = images[0].in->spec();
+ const ImageSpec &spec = image.in->spec();
+
+ if (base_spec.width != spec.width || base_spec.height != spec.height ||
+ base_spec.depth != spec.depth || base_spec.format != spec.format ||
+ base_spec.deep != spec.deep) {
+ error = "Images do not have matching size and data layout.";
+ return false;
+ }
+ }
+
+ images.push_back(std::move(image));
+ }
+
+ return true;
}
-static void merge_render_time(ImageSpec& spec,
- const vector<MergeImage>& images,
- const string& name,
+static void merge_render_time(ImageSpec &spec,
+ const vector<MergeImage> &images,
+ const string &name,
const bool average)
{
- double time = 0.0;
+ double time = 0.0;
- for(const MergeImage& image: images) {
- string time_str = image.in->spec().get_string_attribute(name, "");
- time += time_human_readable_to_seconds(time_str);
- }
+ for (const MergeImage &image : images) {
+ string time_str = image.in->spec().get_string_attribute(name, "");
+ time += time_human_readable_to_seconds(time_str);
+ }
- if(average) {
- time /= images.size();
- }
+ if (average) {
+ time /= images.size();
+ }
- spec.attribute(name, TypeDesc::STRING, time_human_readable_from_seconds(time));
+ spec.attribute(name, TypeDesc::STRING, time_human_readable_from_seconds(time));
}
-static void merge_layer_render_time(ImageSpec& spec,
- const vector<MergeImage>& images,
- const string& layer_name,
- const string& time_name,
+static void merge_layer_render_time(ImageSpec &spec,
+ const vector<MergeImage> &images,
+ const string &layer_name,
+ const string &time_name,
const bool average)
{
- string name = "cycles." + layer_name + "." + time_name;
- double time = 0.0;
+ string name = "cycles." + layer_name + "." + time_name;
+ double time = 0.0;
- for(const MergeImage& image: images) {
- string time_str = image.in->spec().get_string_attribute(name, "");
- time += time_human_readable_to_seconds(time_str);
- }
+ for (const MergeImage &image : images) {
+ string time_str = image.in->spec().get_string_attribute(name, "");
+ time += time_human_readable_to_seconds(time_str);
+ }
- if(average) {
- time /= images.size();
- }
+ if (average) {
+ time /= images.size();
+ }
- spec.attribute(name, TypeDesc::STRING, time_human_readable_from_seconds(time));
+ spec.attribute(name, TypeDesc::STRING, time_human_readable_from_seconds(time));
}
-static void merge_channels_metadata(vector<MergeImage>& images,
- ImageSpec& out_spec,
- vector<int>& channel_total_samples)
+static void merge_channels_metadata(vector<MergeImage> &images,
+ ImageSpec &out_spec,
+ vector<int> &channel_total_samples)
{
- /* Based on first image. */
- out_spec = images[0].in->spec();
-
- /* Merge channels and compute offsets. */
- out_spec.nchannels = 0;
- out_spec.channelformats.clear();
- out_spec.channelnames.clear();
-
- for(MergeImage& image: images) {
- for(MergeImageLayer& layer: image.layers) {
- for(MergeImagePass& pass: layer.passes) {
- /* Test if matching channel already exists in merged image. */
- bool found = false;
-
- for(size_t i = 0; i < out_spec.nchannels; i++) {
- if(pass.channel_name == out_spec.channelnames[i]) {
- pass.merge_offset = i;
- channel_total_samples[i] += layer.samples;
- /* First image wins for channels that can't be averaged or summed. */
- if (pass.op == MERGE_CHANNEL_COPY) {
- pass.op = MERGE_CHANNEL_NOP;
- }
- found = true;
- break;
- }
- }
-
- if(!found) {
- /* Add new channel. */
- pass.merge_offset = out_spec.nchannels;
- channel_total_samples.push_back(layer.samples);
-
- out_spec.channelnames.push_back(pass.channel_name);
- out_spec.channelformats.push_back(pass.format);
- out_spec.nchannels++;
- }
- }
- }
- }
-
- /* Merge metadata. */
- merge_render_time(out_spec, images, "RenderTime", false);
-
- map<string, int> layer_num_samples;
- for(MergeImage& image: images) {
- for(MergeImageLayer& layer: image.layers) {
- if(layer.name != "") {
- layer_num_samples[layer.name] += layer.samples;
- }
- }
- }
-
- for(const auto& i: layer_num_samples) {
- string name = "cycles." + i.first + ".samples";
- out_spec.attribute(name, TypeDesc::STRING, string_printf("%d", i.second));
-
- merge_layer_render_time(out_spec, images, i.first, "total_time", false);
- merge_layer_render_time(out_spec, images, i.first, "render_time", false);
- merge_layer_render_time(out_spec, images, i.first, "synchronization_time", true);
- }
+ /* Based on first image. */
+ out_spec = images[0].in->spec();
+
+ /* Merge channels and compute offsets. */
+ out_spec.nchannels = 0;
+ out_spec.channelformats.clear();
+ out_spec.channelnames.clear();
+
+ for (MergeImage &image : images) {
+ for (MergeImageLayer &layer : image.layers) {
+ for (MergeImagePass &pass : layer.passes) {
+ /* Test if matching channel already exists in merged image. */
+ bool found = false;
+
+ for (size_t i = 0; i < out_spec.nchannels; i++) {
+ if (pass.channel_name == out_spec.channelnames[i]) {
+ pass.merge_offset = i;
+ channel_total_samples[i] += layer.samples;
+ /* First image wins for channels that can't be averaged or summed. */
+ if (pass.op == MERGE_CHANNEL_COPY) {
+ pass.op = MERGE_CHANNEL_NOP;
+ }
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ /* Add new channel. */
+ pass.merge_offset = out_spec.nchannels;
+ channel_total_samples.push_back(layer.samples);
+
+ out_spec.channelnames.push_back(pass.channel_name);
+ out_spec.channelformats.push_back(pass.format);
+ out_spec.nchannels++;
+ }
+ }
+ }
+ }
+
+ /* Merge metadata. */
+ merge_render_time(out_spec, images, "RenderTime", false);
+
+ map<string, int> layer_num_samples;
+ for (MergeImage &image : images) {
+ for (MergeImageLayer &layer : image.layers) {
+ if (layer.name != "") {
+ layer_num_samples[layer.name] += layer.samples;
+ }
+ }
+ }
+
+ for (const auto &i : layer_num_samples) {
+ string name = "cycles." + i.first + ".samples";
+ out_spec.attribute(name, TypeDesc::STRING, string_printf("%d", i.second));
+
+ merge_layer_render_time(out_spec, images, i.first, "total_time", false);
+ merge_layer_render_time(out_spec, images, i.first, "render_time", false);
+ merge_layer_render_time(out_spec, images, i.first, "synchronization_time", true);
+ }
}
-static void alloc_pixels(const ImageSpec& spec, array<float>& pixels)
+static void alloc_pixels(const ImageSpec &spec, array<float> &pixels)
{
- const size_t width = spec.width;
- const size_t height = spec.height;
- const size_t num_channels = spec.nchannels;
+ const size_t width = spec.width;
+ const size_t height = spec.height;
+ const size_t num_channels = spec.nchannels;
- const size_t num_pixels = (size_t)width * (size_t)height;
- pixels.resize(num_pixels * num_channels);
+ const size_t num_pixels = (size_t)width * (size_t)height;
+ pixels.resize(num_pixels * num_channels);
}
-static bool merge_pixels(const vector<MergeImage>& images,
- const ImageSpec& out_spec,
- const vector<int>& channel_total_samples,
- array<float>& out_pixels,
- string& error)
+static bool merge_pixels(const vector<MergeImage> &images,
+ const ImageSpec &out_spec,
+ const vector<int> &channel_total_samples,
+ array<float> &out_pixels,
+ string &error)
{
- alloc_pixels(out_spec, out_pixels);
- memset(out_pixels.data(), 0, out_pixels.size() * sizeof(float));
-
- for(const MergeImage& image: images) {
- /* Read all channels into buffer. Reading all channels at once is
- * faster than individually due to interleaved EXR channel storage. */
- array<float> pixels;
- alloc_pixels(image.in->spec(), pixels);
-
- if(!image.in->read_image(TypeDesc::FLOAT, pixels.data())) {
- error = "Failed to read image: " + image.filepath;
- return false;
- }
-
- for(size_t li = 0; li < image.layers.size(); li++) {
- const MergeImageLayer& layer = image.layers[li];
-
- const size_t stride = image.in->spec().nchannels;
- const size_t out_stride = out_spec.nchannels;
- const size_t num_pixels = pixels.size();
-
- for(const MergeImagePass& pass: layer.passes) {
- size_t offset = pass.offset;
- size_t out_offset = pass.merge_offset;
-
- switch(pass.op) {
- case MERGE_CHANNEL_NOP:
- break;
- case MERGE_CHANNEL_COPY:
- for(; offset < num_pixels; offset += stride, out_offset += out_stride) {
- out_pixels[out_offset] = pixels[offset];
- }
- break;
- case MERGE_CHANNEL_SUM:
- for(; offset < num_pixels; offset += stride, out_offset += out_stride) {
- out_pixels[out_offset] += pixels[offset];
- }
- break;
- case MERGE_CHANNEL_AVERAGE:
- /* Weights based on sample metadata. Per channel since not
- * all files are guaranteed to have the same channels. */
- const int total_samples = channel_total_samples[out_offset];
- const float t = (float)layer.samples / (float)total_samples;
-
- for(; offset < num_pixels; offset += stride, out_offset += out_stride) {
- out_pixels[out_offset] += t * pixels[offset];
- }
- break;
- }
- }
- }
- }
-
- return true;
+ alloc_pixels(out_spec, out_pixels);
+ memset(out_pixels.data(), 0, out_pixels.size() * sizeof(float));
+
+ for (const MergeImage &image : images) {
+ /* Read all channels into buffer. Reading all channels at once is
+ * faster than individually due to interleaved EXR channel storage. */
+ array<float> pixels;
+ alloc_pixels(image.in->spec(), pixels);
+
+ if (!image.in->read_image(TypeDesc::FLOAT, pixels.data())) {
+ error = "Failed to read image: " + image.filepath;
+ return false;
+ }
+
+ for (size_t li = 0; li < image.layers.size(); li++) {
+ const MergeImageLayer &layer = image.layers[li];
+
+ const size_t stride = image.in->spec().nchannels;
+ const size_t out_stride = out_spec.nchannels;
+ const size_t num_pixels = pixels.size();
+
+ for (const MergeImagePass &pass : layer.passes) {
+ size_t offset = pass.offset;
+ size_t out_offset = pass.merge_offset;
+
+ switch (pass.op) {
+ case MERGE_CHANNEL_NOP:
+ break;
+ case MERGE_CHANNEL_COPY:
+ for (; offset < num_pixels; offset += stride, out_offset += out_stride) {
+ out_pixels[out_offset] = pixels[offset];
+ }
+ break;
+ case MERGE_CHANNEL_SUM:
+ for (; offset < num_pixels; offset += stride, out_offset += out_stride) {
+ out_pixels[out_offset] += pixels[offset];
+ }
+ break;
+ case MERGE_CHANNEL_AVERAGE:
+ /* Weights based on sample metadata. Per channel since not
+ * all files are guaranteed to have the same channels. */
+ const int total_samples = channel_total_samples[out_offset];
+ const float t = (float)layer.samples / (float)total_samples;
+
+ for (; offset < num_pixels; offset += stride, out_offset += out_stride) {
+ out_pixels[out_offset] += t * pixels[offset];
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return true;
}
-static bool save_output(const string& filepath,
- const ImageSpec& spec,
- const array<float>& pixels,
- string& error)
+static bool save_output(const string &filepath,
+ const ImageSpec &spec,
+ const array<float> &pixels,
+ string &error)
{
- /* Write to temporary file path, so we merge images in place and don't
- * risk destroying files when something goes wrong in file saving. */
- string extension = OIIO::Filesystem::extension(filepath);
- string unique_name = ".merge-tmp-" + OIIO::Filesystem::unique_path();
- string tmp_filepath = filepath + unique_name + extension;
- unique_ptr<ImageOutput> out(ImageOutput::create(tmp_filepath));
-
- if(!out) {
- error = "Failed to open temporary file " + tmp_filepath + " for writing";
- return false;
- }
-
- /* Open temporary file and write image buffers. */
- if(!out->open(tmp_filepath, spec)) {
- error = "Failed to open file " + tmp_filepath + " for writing: " + out->geterror();
- return false;
- }
-
- bool ok = true;
- if(!out->write_image(TypeDesc::FLOAT, pixels.data())) {
- error = "Failed to write to file " + tmp_filepath + ": " + out->geterror();
- ok = false;
- }
-
- if(!out->close()) {
- error = "Failed to save to file " + tmp_filepath + ": " + out->geterror();
- ok = false;
- }
-
- out.reset();
-
- /* Copy temporary file to outputput filepath. */
- string rename_error;
- if(ok && !OIIO::Filesystem::rename(tmp_filepath, filepath, rename_error)) {
- error = "Failed to move merged image to " + filepath + ": " + rename_error;
- ok = false;
- }
-
- if(!ok) {
- OIIO::Filesystem::remove(tmp_filepath);
- }
-
- return ok;
+ /* Write to temporary file path, so we merge images in place and don't
+ * risk destroying files when something goes wrong in file saving. */
+ string extension = OIIO::Filesystem::extension(filepath);
+ string unique_name = ".merge-tmp-" + OIIO::Filesystem::unique_path();
+ string tmp_filepath = filepath + unique_name + extension;
+ unique_ptr<ImageOutput> out(ImageOutput::create(tmp_filepath));
+
+ if (!out) {
+ error = "Failed to open temporary file " + tmp_filepath + " for writing";
+ return false;
+ }
+
+ /* Open temporary file and write image buffers. */
+ if (!out->open(tmp_filepath, spec)) {
+ error = "Failed to open file " + tmp_filepath + " for writing: " + out->geterror();
+ return false;
+ }
+
+ bool ok = true;
+ if (!out->write_image(TypeDesc::FLOAT, pixels.data())) {
+ error = "Failed to write to file " + tmp_filepath + ": " + out->geterror();
+ ok = false;
+ }
+
+ if (!out->close()) {
+ error = "Failed to save to file " + tmp_filepath + ": " + out->geterror();
+ ok = false;
+ }
+
+ out.reset();
+
+ /* Copy temporary file to outputput filepath. */
+ string rename_error;
+ if (ok && !OIIO::Filesystem::rename(tmp_filepath, filepath, rename_error)) {
+ error = "Failed to move merged image to " + filepath + ": " + rename_error;
+ ok = false;
+ }
+
+ if (!ok) {
+ OIIO::Filesystem::remove(tmp_filepath);
+ }
+
+ return ok;
}
/* Image Merger */
@@ -489,38 +479,38 @@ ImageMerger::ImageMerger()
bool ImageMerger::run()
{
- if(input.empty()) {
- error = "No input file paths specified.";
- return false;
- }
- if(output.empty()) {
- error = "No output file path specified.";
- return false;
- }
-
- /* Open images and verify they have matching layout. */
- vector<MergeImage> images;
- if(!open_images(input, images, error)) {
- return false;
- }
-
- /* Merge metadata and setup channels and offsets. */
- ImageSpec out_spec;
- vector<int> channel_total_samples;
- merge_channels_metadata(images, out_spec, channel_total_samples);
-
- /* Merge pixels. */
- array<float> out_pixels;
- if(!merge_pixels(images, out_spec, channel_total_samples, out_pixels, error)) {
- return false;
- }
-
- /* We don't need input anymore at this point, and will possibly
- * overwrite the same file. */
- images.clear();
-
- /* Save output file. */
- return save_output(output, out_spec, out_pixels, error);
+ if (input.empty()) {
+ error = "No input file paths specified.";
+ return false;
+ }
+ if (output.empty()) {
+ error = "No output file path specified.";
+ return false;
+ }
+
+ /* Open images and verify they have matching layout. */
+ vector<MergeImage> images;
+ if (!open_images(input, images, error)) {
+ return false;
+ }
+
+ /* Merge metadata and setup channels and offsets. */
+ ImageSpec out_spec;
+ vector<int> channel_total_samples;
+ merge_channels_metadata(images, out_spec, channel_total_samples);
+
+ /* Merge pixels. */
+ array<float> out_pixels;
+ if (!merge_pixels(images, out_spec, channel_total_samples, out_pixels, error)) {
+ return false;
+ }
+
+ /* We don't need input anymore at this point, and will possibly
+ * overwrite the same file. */
+ images.clear();
+
+ /* Save output file. */
+ return save_output(output, out_spec, out_pixels, error);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/merge.h b/intern/cycles/render/merge.h
index 48900a13c27..87e5d2d4723 100644
--- a/intern/cycles/render/merge.h
+++ b/intern/cycles/render/merge.h
@@ -25,17 +25,17 @@ CCL_NAMESPACE_BEGIN
/* Merge OpenEXR multilayer renders. */
class ImageMerger {
-public:
- ImageMerger();
- bool run();
+ public:
+ ImageMerger();
+ bool run();
- /* Error message after running, in case of failure. */
- string error;
+ /* Error message after running, in case of failure. */
+ string error;
- /* List of image filepaths to merge. */
- vector<string> input;
- /* Output filepath. */
- string output;
+ /* List of image filepaths to merge. */
+ vector<string> input;
+ /* Output filepath. */
+ string output;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index eadbe3eda89..54dacf5d1f4 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -47,11 +47,11 @@ CCL_NAMESPACE_BEGIN
/* Triangle */
-void Mesh::Triangle::bounds_grow(const float3 *verts, BoundBox& bounds) const
+void Mesh::Triangle::bounds_grow(const float3 *verts, BoundBox &bounds) const
{
- bounds.grow(verts[v[0]]);
- bounds.grow(verts[v[1]]);
- bounds.grow(verts[v[2]]);
+ bounds.grow(verts[v[0]]);
+ bounds.grow(verts[v[1]]);
+ bounds.grow(verts[v[2]]);
}
void Mesh::Triangle::motion_verts(const float3 *verts,
@@ -61,29 +61,19 @@ void Mesh::Triangle::motion_verts(const float3 *verts,
float time,
float3 r_verts[3]) const
{
- /* Figure out which steps we need to fetch and their interpolation factor. */
- const size_t max_step = num_steps - 1;
- const size_t step = min((int)(time * max_step), max_step - 1);
- const float t = time*max_step - step;
- /* Fetch vertex coordinates. */
- float3 curr_verts[3];
- float3 next_verts[3];
- verts_for_step(verts,
- vert_steps,
- num_verts,
- num_steps,
- step,
- curr_verts);
- verts_for_step(verts,
- vert_steps,
- num_verts,
- num_steps,
- step + 1,
- next_verts);
- /* Interpolate between steps. */
- r_verts[0] = (1.0f - t)*curr_verts[0] + t*next_verts[0];
- r_verts[1] = (1.0f - t)*curr_verts[1] + t*next_verts[1];
- r_verts[2] = (1.0f - t)*curr_verts[2] + t*next_verts[2];
+ /* Figure out which steps we need to fetch and their interpolation factor. */
+ const size_t max_step = num_steps - 1;
+ const size_t step = min((int)(time * max_step), max_step - 1);
+ const float t = time * max_step - step;
+ /* Fetch vertex coordinates. */
+ float3 curr_verts[3];
+ float3 next_verts[3];
+ verts_for_step(verts, vert_steps, num_verts, num_steps, step, curr_verts);
+ verts_for_step(verts, vert_steps, num_verts, num_steps, step + 1, next_verts);
+ /* Interpolate between steps. */
+ r_verts[0] = (1.0f - t) * curr_verts[0] + t * next_verts[0];
+ r_verts[1] = (1.0f - t) * curr_verts[1] + t * next_verts[1];
+ r_verts[2] = (1.0f - t) * curr_verts[2] + t * next_verts[2];
}
void Mesh::Triangle::verts_for_step(const float3 *verts,
@@ -93,120 +83,121 @@ void Mesh::Triangle::verts_for_step(const float3 *verts,
size_t step,
float3 r_verts[3]) const
{
- const size_t center_step = ((num_steps - 1) / 2);
- if(step == center_step) {
- /* Center step: regular vertex location. */
- r_verts[0] = verts[v[0]];
- r_verts[1] = verts[v[1]];
- r_verts[2] = verts[v[2]];
- }
- else {
- /* Center step not stored in the attribute array array. */
- if(step > center_step) {
- step--;
- }
- size_t offset = step * num_verts;
- r_verts[0] = vert_steps[offset + v[0]];
- r_verts[1] = vert_steps[offset + v[1]];
- r_verts[2] = vert_steps[offset + v[2]];
- }
+ const size_t center_step = ((num_steps - 1) / 2);
+ if (step == center_step) {
+ /* Center step: regular vertex location. */
+ r_verts[0] = verts[v[0]];
+ r_verts[1] = verts[v[1]];
+ r_verts[2] = verts[v[2]];
+ }
+ else {
+ /* Center step not stored in the attribute array array. */
+ if (step > center_step) {
+ step--;
+ }
+ size_t offset = step * num_verts;
+ r_verts[0] = vert_steps[offset + v[0]];
+ r_verts[1] = vert_steps[offset + v[1]];
+ r_verts[2] = vert_steps[offset + v[2]];
+ }
}
float3 Mesh::Triangle::compute_normal(const float3 *verts) const
{
- const float3& v0 = verts[v[0]];
- const float3& v1 = verts[v[1]];
- const float3& v2 = verts[v[2]];
- const float3 norm = cross(v1 - v0, v2 - v0);
- const float normlen = len(norm);
- if(normlen == 0.0f) {
- return make_float3(1.0f, 0.0f, 0.0f);
- }
- return norm / normlen;
+ const float3 &v0 = verts[v[0]];
+ const float3 &v1 = verts[v[1]];
+ const float3 &v2 = verts[v[2]];
+ const float3 norm = cross(v1 - v0, v2 - v0);
+ const float normlen = len(norm);
+ if (normlen == 0.0f) {
+ return make_float3(1.0f, 0.0f, 0.0f);
+ }
+ return norm / normlen;
}
bool Mesh::Triangle::valid(const float3 *verts) const
{
- return isfinite3_safe(verts[v[0]]) &&
- isfinite3_safe(verts[v[1]]) &&
- isfinite3_safe(verts[v[2]]);
+ return isfinite3_safe(verts[v[0]]) && isfinite3_safe(verts[v[1]]) && isfinite3_safe(verts[v[2]]);
}
/* Curve */
-void Mesh::Curve::bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox& bounds) const
+void Mesh::Curve::bounds_grow(const int k,
+ const float3 *curve_keys,
+ const float *curve_radius,
+ BoundBox &bounds) const
{
- float3 P[4];
+ float3 P[4];
- P[0] = curve_keys[max(first_key + k - 1,first_key)];
- P[1] = curve_keys[first_key + k];
- P[2] = curve_keys[first_key + k + 1];
- P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
+ P[0] = curve_keys[max(first_key + k - 1, first_key)];
+ P[1] = curve_keys[first_key + k];
+ P[2] = curve_keys[first_key + k + 1];
+ P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
- float3 lower;
- float3 upper;
+ float3 lower;
+ float3 upper;
- curvebounds(&lower.x, &upper.x, P, 0);
- curvebounds(&lower.y, &upper.y, P, 1);
- curvebounds(&lower.z, &upper.z, P, 2);
+ curvebounds(&lower.x, &upper.x, P, 0);
+ curvebounds(&lower.y, &upper.y, P, 1);
+ curvebounds(&lower.z, &upper.z, P, 2);
- float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
+ float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
- bounds.grow(lower, mr);
- bounds.grow(upper, mr);
+ bounds.grow(lower, mr);
+ bounds.grow(upper, mr);
}
void Mesh::Curve::bounds_grow(const int k,
const float3 *curve_keys,
const float *curve_radius,
- const Transform& aligned_space,
- BoundBox& bounds) const
+ const Transform &aligned_space,
+ BoundBox &bounds) const
{
- float3 P[4];
+ float3 P[4];
- P[0] = curve_keys[max(first_key + k - 1,first_key)];
- P[1] = curve_keys[first_key + k];
- P[2] = curve_keys[first_key + k + 1];
- P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
+ P[0] = curve_keys[max(first_key + k - 1, first_key)];
+ P[1] = curve_keys[first_key + k];
+ P[2] = curve_keys[first_key + k + 1];
+ P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
- P[0] = transform_point(&aligned_space, P[0]);
- P[1] = transform_point(&aligned_space, P[1]);
- P[2] = transform_point(&aligned_space, P[2]);
- P[3] = transform_point(&aligned_space, P[3]);
+ P[0] = transform_point(&aligned_space, P[0]);
+ P[1] = transform_point(&aligned_space, P[1]);
+ P[2] = transform_point(&aligned_space, P[2]);
+ P[3] = transform_point(&aligned_space, P[3]);
- float3 lower;
- float3 upper;
+ float3 lower;
+ float3 upper;
- curvebounds(&lower.x, &upper.x, P, 0);
- curvebounds(&lower.y, &upper.y, P, 1);
- curvebounds(&lower.z, &upper.z, P, 2);
+ curvebounds(&lower.x, &upper.x, P, 0);
+ curvebounds(&lower.y, &upper.y, P, 1);
+ curvebounds(&lower.z, &upper.z, P, 2);
- float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
+ float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
- bounds.grow(lower, mr);
- bounds.grow(upper, mr);
+ bounds.grow(lower, mr);
+ bounds.grow(upper, mr);
}
-void Mesh::Curve::bounds_grow(float4 keys[4], BoundBox& bounds) const
+void Mesh::Curve::bounds_grow(float4 keys[4], BoundBox &bounds) const
{
- float3 P[4] = {
- float4_to_float3(keys[0]),
- float4_to_float3(keys[1]),
- float4_to_float3(keys[2]),
- float4_to_float3(keys[3]),
- };
+ float3 P[4] = {
+ float4_to_float3(keys[0]),
+ float4_to_float3(keys[1]),
+ float4_to_float3(keys[2]),
+ float4_to_float3(keys[3]),
+ };
- float3 lower;
- float3 upper;
+ float3 lower;
+ float3 upper;
- curvebounds(&lower.x, &upper.x, P, 0);
- curvebounds(&lower.y, &upper.y, P, 1);
- curvebounds(&lower.z, &upper.z, P, 2);
+ curvebounds(&lower.x, &upper.x, P, 0);
+ curvebounds(&lower.y, &upper.y, P, 1);
+ curvebounds(&lower.z, &upper.z, P, 2);
- float mr = max(keys[1].w, keys[2].w);
+ float mr = max(keys[1].w, keys[2].w);
- bounds.grow(lower, mr);
- bounds.grow(upper, mr);
+ bounds.grow(lower, mr);
+ bounds.grow(upper, mr);
}
void Mesh::Curve::motion_keys(const float3 *curve_keys,
@@ -215,35 +206,24 @@ void Mesh::Curve::motion_keys(const float3 *curve_keys,
size_t num_curve_keys,
size_t num_steps,
float time,
- size_t k0, size_t k1,
+ size_t k0,
+ size_t k1,
float4 r_keys[2]) const
{
- /* Figure out which steps we need to fetch and their interpolation factor. */
- const size_t max_step = num_steps - 1;
- const size_t step = min((int)(time * max_step), max_step - 1);
- const float t = time*max_step - step;
- /* Fetch vertex coordinates. */
- float4 curr_keys[2];
- float4 next_keys[2];
- keys_for_step(curve_keys,
- curve_radius,
- key_steps,
- num_curve_keys,
- num_steps,
- step,
- k0, k1,
- curr_keys);
- keys_for_step(curve_keys,
- curve_radius,
- key_steps,
- num_curve_keys,
- num_steps,
- step + 1,
- k0, k1,
- next_keys);
- /* Interpolate between steps. */
- r_keys[0] = (1.0f - t)*curr_keys[0] + t*next_keys[0];
- r_keys[1] = (1.0f - t)*curr_keys[1] + t*next_keys[1];
+ /* Figure out which steps we need to fetch and their interpolation factor. */
+ const size_t max_step = num_steps - 1;
+ const size_t step = min((int)(time * max_step), max_step - 1);
+ const float t = time * max_step - step;
+ /* Fetch vertex coordinates. */
+ float4 curr_keys[2];
+ float4 next_keys[2];
+ keys_for_step(
+ curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step, k0, k1, curr_keys);
+ keys_for_step(
+ curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step + 1, k0, k1, next_keys);
+ /* Interpolate between steps. */
+ r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0];
+ r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1];
}
void Mesh::Curve::cardinal_motion_keys(const float3 *curve_keys,
@@ -252,38 +232,46 @@ void Mesh::Curve::cardinal_motion_keys(const float3 *curve_keys,
size_t num_curve_keys,
size_t num_steps,
float time,
- size_t k0, size_t k1,
- size_t k2, size_t k3,
+ size_t k0,
+ size_t k1,
+ size_t k2,
+ size_t k3,
float4 r_keys[4]) const
{
- /* Figure out which steps we need to fetch and their interpolation factor. */
- const size_t max_step = num_steps - 1;
- const size_t step = min((int)(time * max_step), max_step - 1);
- const float t = time*max_step - step;
- /* Fetch vertex coordinates. */
- float4 curr_keys[4];
- float4 next_keys[4];
- cardinal_keys_for_step(curve_keys,
- curve_radius,
- key_steps,
- num_curve_keys,
- num_steps,
- step,
- k0, k1, k2, k3,
- curr_keys);
- cardinal_keys_for_step(curve_keys,
- curve_radius,
- key_steps,
- num_curve_keys,
- num_steps,
- step + 1,
- k0, k1, k2, k3,
- next_keys);
- /* Interpolate between steps. */
- r_keys[0] = (1.0f - t)*curr_keys[0] + t*next_keys[0];
- r_keys[1] = (1.0f - t)*curr_keys[1] + t*next_keys[1];
- r_keys[2] = (1.0f - t)*curr_keys[2] + t*next_keys[2];
- r_keys[3] = (1.0f - t)*curr_keys[3] + t*next_keys[3];
+ /* Figure out which steps we need to fetch and their interpolation factor. */
+ const size_t max_step = num_steps - 1;
+ const size_t step = min((int)(time * max_step), max_step - 1);
+ const float t = time * max_step - step;
+ /* Fetch vertex coordinates. */
+ float4 curr_keys[4];
+ float4 next_keys[4];
+ cardinal_keys_for_step(curve_keys,
+ curve_radius,
+ key_steps,
+ num_curve_keys,
+ num_steps,
+ step,
+ k0,
+ k1,
+ k2,
+ k3,
+ curr_keys);
+ cardinal_keys_for_step(curve_keys,
+ curve_radius,
+ key_steps,
+ num_curve_keys,
+ num_steps,
+ step + 1,
+ k0,
+ k1,
+ k2,
+ k3,
+ next_keys);
+ /* Interpolate between steps. */
+ r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0];
+ r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1];
+ r_keys[2] = (1.0f - t) * curr_keys[2] + t * next_keys[2];
+ r_keys[3] = (1.0f - t) * curr_keys[3] + t * next_keys[3];
}
void Mesh::Curve::keys_for_step(const float3 *curve_keys,
@@ -292,41 +280,42 @@ void Mesh::Curve::keys_for_step(const float3 *curve_keys,
size_t num_curve_keys,
size_t num_steps,
size_t step,
- size_t k0, size_t k1,
+ size_t k0,
+ size_t k1,
float4 r_keys[2]) const
{
- k0 = max(k0, 0);
- k1 = min(k1, num_keys - 1);
- const size_t center_step = ((num_steps - 1) / 2);
- if(step == center_step) {
- /* Center step: regular key location. */
- /* TODO(sergey): Consider adding make_float4(float3, float)
- * function.
- */
- r_keys[0] = make_float4(curve_keys[first_key + k0].x,
- curve_keys[first_key + k0].y,
- curve_keys[first_key + k0].z,
- curve_radius[first_key + k0]);
- r_keys[1] = make_float4(curve_keys[first_key + k1].x,
- curve_keys[first_key + k1].y,
- curve_keys[first_key + k1].z,
- curve_radius[first_key + k1]);
- }
- else {
- /* Center step is not stored in this array. */
- if(step > center_step) {
- step--;
- }
- const size_t offset = first_key + step * num_curve_keys;
- r_keys[0] = make_float4(key_steps[offset + k0].x,
- key_steps[offset + k0].y,
- key_steps[offset + k0].z,
- curve_radius[first_key + k0]);
- r_keys[1] = make_float4(key_steps[offset + k1].x,
- key_steps[offset + k1].y,
- key_steps[offset + k1].z,
- curve_radius[first_key + k1]);
- }
+ k0 = max(k0, 0);
+ k1 = min(k1, num_keys - 1);
+ const size_t center_step = ((num_steps - 1) / 2);
+ if (step == center_step) {
+ /* Center step: regular key location. */
+ /* TODO(sergey): Consider adding make_float4(float3, float)
+ * function.
+ */
+ r_keys[0] = make_float4(curve_keys[first_key + k0].x,
+ curve_keys[first_key + k0].y,
+ curve_keys[first_key + k0].z,
+ curve_radius[first_key + k0]);
+ r_keys[1] = make_float4(curve_keys[first_key + k1].x,
+ curve_keys[first_key + k1].y,
+ curve_keys[first_key + k1].z,
+ curve_radius[first_key + k1]);
+ }
+ else {
+ /* Center step is not stored in this array. */
+ if (step > center_step) {
+ step--;
+ }
+ const size_t offset = first_key + step * num_curve_keys;
+ r_keys[0] = make_float4(key_steps[offset + k0].x,
+ key_steps[offset + k0].y,
+ key_steps[offset + k0].z,
+ curve_radius[first_key + k0]);
+ r_keys[1] = make_float4(key_steps[offset + k1].x,
+ key_steps[offset + k1].y,
+ key_steps[offset + k1].z,
+ curve_radius[first_key + k1]);
+ }
}
void Mesh::Curve::cardinal_keys_for_step(const float3 *curve_keys,
@@ -335,2033 +324,2044 @@ void Mesh::Curve::cardinal_keys_for_step(const float3 *curve_keys,
size_t num_curve_keys,
size_t num_steps,
size_t step,
- size_t k0, size_t k1,
- size_t k2, size_t k3,
+ size_t k0,
+ size_t k1,
+ size_t k2,
+ size_t k3,
float4 r_keys[4]) const
{
- k0 = max(k0, 0);
- k3 = min(k3, num_keys - 1);
- const size_t center_step = ((num_steps - 1) / 2);
- if(step == center_step) {
- /* Center step: regular key location. */
- r_keys[0] = make_float4(curve_keys[first_key + k0].x,
- curve_keys[first_key + k0].y,
- curve_keys[first_key + k0].z,
- curve_radius[first_key + k0]);
- r_keys[1] = make_float4(curve_keys[first_key + k1].x,
- curve_keys[first_key + k1].y,
- curve_keys[first_key + k1].z,
- curve_radius[first_key + k1]);
- r_keys[2] = make_float4(curve_keys[first_key + k2].x,
- curve_keys[first_key + k2].y,
- curve_keys[first_key + k2].z,
- curve_radius[first_key + k2]);
- r_keys[3] = make_float4(curve_keys[first_key + k3].x,
- curve_keys[first_key + k3].y,
- curve_keys[first_key + k3].z,
- curve_radius[first_key + k3]);
- }
- else {
- /* Center step is not stored in this array. */
- if(step > center_step) {
- step--;
- }
- const size_t offset = first_key + step * num_curve_keys;
- r_keys[0] = make_float4(key_steps[offset + k0].x,
- key_steps[offset + k0].y,
- key_steps[offset + k0].z,
- curve_radius[first_key + k0]);
- r_keys[1] = make_float4(key_steps[offset + k1].x,
- key_steps[offset + k1].y,
- key_steps[offset + k1].z,
- curve_radius[first_key + k1]);
- r_keys[2] = make_float4(key_steps[offset + k2].x,
- key_steps[offset + k2].y,
- key_steps[offset + k2].z,
- curve_radius[first_key + k2]);
- r_keys[3] = make_float4(key_steps[offset + k3].x,
- key_steps[offset + k3].y,
- key_steps[offset + k3].z,
- curve_radius[first_key + k3]);
- }
+ k0 = max(k0, 0);
+ k3 = min(k3, num_keys - 1);
+ const size_t center_step = ((num_steps - 1) / 2);
+ if (step == center_step) {
+ /* Center step: regular key location. */
+ r_keys[0] = make_float4(curve_keys[first_key + k0].x,
+ curve_keys[first_key + k0].y,
+ curve_keys[first_key + k0].z,
+ curve_radius[first_key + k0]);
+ r_keys[1] = make_float4(curve_keys[first_key + k1].x,
+ curve_keys[first_key + k1].y,
+ curve_keys[first_key + k1].z,
+ curve_radius[first_key + k1]);
+ r_keys[2] = make_float4(curve_keys[first_key + k2].x,
+ curve_keys[first_key + k2].y,
+ curve_keys[first_key + k2].z,
+ curve_radius[first_key + k2]);
+ r_keys[3] = make_float4(curve_keys[first_key + k3].x,
+ curve_keys[first_key + k3].y,
+ curve_keys[first_key + k3].z,
+ curve_radius[first_key + k3]);
+ }
+ else {
+ /* Center step is not stored in this array. */
+ if (step > center_step) {
+ step--;
+ }
+ const size_t offset = first_key + step * num_curve_keys;
+ r_keys[0] = make_float4(key_steps[offset + k0].x,
+ key_steps[offset + k0].y,
+ key_steps[offset + k0].z,
+ curve_radius[first_key + k0]);
+ r_keys[1] = make_float4(key_steps[offset + k1].x,
+ key_steps[offset + k1].y,
+ key_steps[offset + k1].z,
+ curve_radius[first_key + k1]);
+ r_keys[2] = make_float4(key_steps[offset + k2].x,
+ key_steps[offset + k2].y,
+ key_steps[offset + k2].z,
+ curve_radius[first_key + k2]);
+ r_keys[3] = make_float4(key_steps[offset + k3].x,
+ key_steps[offset + k3].y,
+ key_steps[offset + k3].z,
+ curve_radius[first_key + k3]);
+ }
}
/* SubdFace */
float3 Mesh::SubdFace::normal(const Mesh *mesh) const
{
- float3 v0 = mesh->verts[mesh->subd_face_corners[start_corner+0]];
- float3 v1 = mesh->verts[mesh->subd_face_corners[start_corner+1]];
- float3 v2 = mesh->verts[mesh->subd_face_corners[start_corner+2]];
+ float3 v0 = mesh->verts[mesh->subd_face_corners[start_corner + 0]];
+ float3 v1 = mesh->verts[mesh->subd_face_corners[start_corner + 1]];
+ float3 v2 = mesh->verts[mesh->subd_face_corners[start_corner + 2]];
- return safe_normalize(cross(v1 - v0, v2 - v0));
+ return safe_normalize(cross(v1 - v0, v2 - v0));
}
/* Mesh */
NODE_DEFINE(Mesh)
{
- NodeType* type = NodeType::add("mesh", create);
+ NodeType *type = NodeType::add("mesh", create);
- SOCKET_UINT(motion_steps, "Motion Steps", 3);
- SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false);
+ SOCKET_UINT(motion_steps, "Motion Steps", 3);
+ SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false);
- SOCKET_INT_ARRAY(triangles, "Triangles", array<int>());
- SOCKET_POINT_ARRAY(verts, "Vertices", array<float3>());
- SOCKET_INT_ARRAY(shader, "Shader", array<int>());
- SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>());
+ SOCKET_INT_ARRAY(triangles, "Triangles", array<int>());
+ SOCKET_POINT_ARRAY(verts, "Vertices", array<float3>());
+ SOCKET_INT_ARRAY(shader, "Shader", array<int>());
+ SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>());
- SOCKET_POINT_ARRAY(curve_keys, "Curve Keys", array<float3>());
- SOCKET_FLOAT_ARRAY(curve_radius, "Curve Radius", array<float>());
- SOCKET_INT_ARRAY(curve_first_key, "Curve First Key", array<int>());
- SOCKET_INT_ARRAY(curve_shader, "Curve Shader", array<int>());
+ SOCKET_POINT_ARRAY(curve_keys, "Curve Keys", array<float3>());
+ SOCKET_FLOAT_ARRAY(curve_radius, "Curve Radius", array<float>());
+ SOCKET_INT_ARRAY(curve_first_key, "Curve First Key", array<int>());
+ SOCKET_INT_ARRAY(curve_shader, "Curve Shader", array<int>());
- return type;
+ return type;
}
-Mesh::Mesh()
-: Node(node_type)
+Mesh::Mesh() : Node(node_type)
{
- need_update = true;
- need_update_rebuild = false;
- transform_applied = false;
- transform_negative_scaled = false;
- transform_normal = transform_identity();
- bounds = BoundBox::empty;
+ need_update = true;
+ need_update_rebuild = false;
+ transform_applied = false;
+ transform_negative_scaled = false;
+ transform_normal = transform_identity();
+ bounds = BoundBox::empty;
- bvh = NULL;
+ bvh = NULL;
- tri_offset = 0;
- vert_offset = 0;
+ tri_offset = 0;
+ vert_offset = 0;
- curve_offset = 0;
- curvekey_offset = 0;
+ curve_offset = 0;
+ curvekey_offset = 0;
- patch_offset = 0;
- face_offset = 0;
- corner_offset = 0;
+ patch_offset = 0;
+ face_offset = 0;
+ corner_offset = 0;
- attr_map_offset = 0;
+ attr_map_offset = 0;
- num_subd_verts = 0;
+ num_subd_verts = 0;
- attributes.triangle_mesh = this;
- curve_attributes.curve_mesh = this;
- subd_attributes.subd_mesh = this;
+ attributes.triangle_mesh = this;
+ curve_attributes.curve_mesh = this;
+ subd_attributes.subd_mesh = this;
- geometry_flags = GEOMETRY_NONE;
+ geometry_flags = GEOMETRY_NONE;
- volume_isovalue = 0.001f;
- has_volume = false;
- has_surface_bssrdf = false;
+ volume_isovalue = 0.001f;
+ has_volume = false;
+ has_surface_bssrdf = false;
- num_ngons = 0;
+ num_ngons = 0;
- subdivision_type = SUBDIVISION_NONE;
- subd_params = NULL;
+ subdivision_type = SUBDIVISION_NONE;
+ subd_params = NULL;
- patch_table = NULL;
+ patch_table = NULL;
}
Mesh::~Mesh()
{
- delete bvh;
- delete patch_table;
- delete subd_params;
+ delete bvh;
+ delete patch_table;
+ delete subd_params;
}
void Mesh::resize_mesh(int numverts, int numtris)
{
- verts.resize(numverts);
- triangles.resize(numtris * 3);
- shader.resize(numtris);
- smooth.resize(numtris);
+ verts.resize(numverts);
+ triangles.resize(numtris * 3);
+ shader.resize(numtris);
+ smooth.resize(numtris);
- if(subd_faces.size()) {
- triangle_patch.resize(numtris);
- vert_patch_uv.resize(numverts);
- }
+ if (subd_faces.size()) {
+ triangle_patch.resize(numtris);
+ vert_patch_uv.resize(numverts);
+ }
- attributes.resize();
+ attributes.resize();
}
void Mesh::reserve_mesh(int numverts, int numtris)
{
- /* reserve space to add verts and triangles later */
- verts.reserve(numverts);
- triangles.reserve(numtris * 3);
- shader.reserve(numtris);
- smooth.reserve(numtris);
+ /* reserve space to add verts and triangles later */
+ verts.reserve(numverts);
+ triangles.reserve(numtris * 3);
+ shader.reserve(numtris);
+ smooth.reserve(numtris);
- if(subd_faces.size()) {
- triangle_patch.reserve(numtris);
- vert_patch_uv.reserve(numverts);
- }
+ if (subd_faces.size()) {
+ triangle_patch.reserve(numtris);
+ vert_patch_uv.reserve(numverts);
+ }
- attributes.resize(true);
+ attributes.resize(true);
}
void Mesh::resize_curves(int numcurves, int numkeys)
{
- curve_keys.resize(numkeys);
- curve_radius.resize(numkeys);
- curve_first_key.resize(numcurves);
- curve_shader.resize(numcurves);
+ curve_keys.resize(numkeys);
+ curve_radius.resize(numkeys);
+ curve_first_key.resize(numcurves);
+ curve_shader.resize(numcurves);
- curve_attributes.resize();
+ curve_attributes.resize();
}
void Mesh::reserve_curves(int numcurves, int numkeys)
{
- curve_keys.reserve(numkeys);
- curve_radius.reserve(numkeys);
- curve_first_key.reserve(numcurves);
- curve_shader.reserve(numcurves);
+ curve_keys.reserve(numkeys);
+ curve_radius.reserve(numkeys);
+ curve_first_key.reserve(numcurves);
+ curve_shader.reserve(numcurves);
- curve_attributes.resize(true);
+ curve_attributes.resize(true);
}
void Mesh::resize_subd_faces(int numfaces, int num_ngons_, int numcorners)
{
- subd_faces.resize(numfaces);
- subd_face_corners.resize(numcorners);
- num_ngons = num_ngons_;
+ subd_faces.resize(numfaces);
+ subd_face_corners.resize(numcorners);
+ num_ngons = num_ngons_;
- subd_attributes.resize();
+ subd_attributes.resize();
}
void Mesh::reserve_subd_faces(int numfaces, int num_ngons_, int numcorners)
{
- subd_faces.reserve(numfaces);
- subd_face_corners.reserve(numcorners);
- num_ngons = num_ngons_;
+ subd_faces.reserve(numfaces);
+ subd_face_corners.reserve(numcorners);
+ num_ngons = num_ngons_;
- subd_attributes.resize(true);
+ subd_attributes.resize(true);
}
void Mesh::clear(bool preserve_voxel_data)
{
- /* clear all verts and triangles */
- verts.clear();
- triangles.clear();
- shader.clear();
- smooth.clear();
+ /* clear all verts and triangles */
+ verts.clear();
+ triangles.clear();
+ shader.clear();
+ smooth.clear();
- triangle_patch.clear();
- vert_patch_uv.clear();
+ triangle_patch.clear();
+ vert_patch_uv.clear();
- curve_keys.clear();
- curve_radius.clear();
- curve_first_key.clear();
- curve_shader.clear();
+ curve_keys.clear();
+ curve_radius.clear();
+ curve_first_key.clear();
+ curve_shader.clear();
- subd_faces.clear();
- subd_face_corners.clear();
+ subd_faces.clear();
+ subd_face_corners.clear();
- num_subd_verts = 0;
+ num_subd_verts = 0;
- subd_creases.clear();
+ subd_creases.clear();
- curve_attributes.clear();
- subd_attributes.clear();
- attributes.clear(preserve_voxel_data);
+ curve_attributes.clear();
+ subd_attributes.clear();
+ attributes.clear(preserve_voxel_data);
- used_shaders.clear();
+ used_shaders.clear();
- if(!preserve_voxel_data) {
- geometry_flags = GEOMETRY_NONE;
- }
+ if (!preserve_voxel_data) {
+ geometry_flags = GEOMETRY_NONE;
+ }
- transform_applied = false;
- transform_negative_scaled = false;
- transform_normal = transform_identity();
+ transform_applied = false;
+ transform_negative_scaled = false;
+ transform_normal = transform_identity();
- delete patch_table;
- patch_table = NULL;
+ delete patch_table;
+ patch_table = NULL;
}
void Mesh::add_vertex(float3 P)
{
- verts.push_back_reserved(P);
+ verts.push_back_reserved(P);
- if(subd_faces.size()) {
- vert_patch_uv.push_back_reserved(make_float2(0.0f, 0.0f));
- }
+ if (subd_faces.size()) {
+ vert_patch_uv.push_back_reserved(make_float2(0.0f, 0.0f));
+ }
}
void Mesh::add_vertex_slow(float3 P)
{
- verts.push_back_slow(P);
+ verts.push_back_slow(P);
- if(subd_faces.size()) {
- vert_patch_uv.push_back_slow(make_float2(0.0f, 0.0f));
- }
+ if (subd_faces.size()) {
+ vert_patch_uv.push_back_slow(make_float2(0.0f, 0.0f));
+ }
}
void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
{
- triangles.push_back_reserved(v0);
- triangles.push_back_reserved(v1);
- triangles.push_back_reserved(v2);
- shader.push_back_reserved(shader_);
- smooth.push_back_reserved(smooth_);
+ triangles.push_back_reserved(v0);
+ triangles.push_back_reserved(v1);
+ triangles.push_back_reserved(v2);
+ shader.push_back_reserved(shader_);
+ smooth.push_back_reserved(smooth_);
- if(subd_faces.size()) {
- triangle_patch.push_back_reserved(-1);
- }
+ if (subd_faces.size()) {
+ triangle_patch.push_back_reserved(-1);
+ }
}
void Mesh::add_curve_key(float3 co, float radius)
{
- curve_keys.push_back_reserved(co);
- curve_radius.push_back_reserved(radius);
+ curve_keys.push_back_reserved(co);
+ curve_radius.push_back_reserved(radius);
}
void Mesh::add_curve(int first_key, int shader)
{
- curve_first_key.push_back_reserved(first_key);
- curve_shader.push_back_reserved(shader);
+ curve_first_key.push_back_reserved(first_key);
+ curve_shader.push_back_reserved(shader);
}
-void Mesh::add_subd_face(int* corners, int num_corners, int shader_, bool smooth_)
+void Mesh::add_subd_face(int *corners, int num_corners, int shader_, bool smooth_)
{
- int start_corner = subd_face_corners.size();
+ int start_corner = subd_face_corners.size();
- for(int i = 0; i < num_corners; i++) {
- subd_face_corners.push_back_reserved(corners[i]);
- }
+ for (int i = 0; i < num_corners; i++) {
+ subd_face_corners.push_back_reserved(corners[i]);
+ }
- int ptex_offset = 0;
+ int ptex_offset = 0;
- if(subd_faces.size()) {
- SubdFace& s = subd_faces[subd_faces.size()-1];
- ptex_offset = s.ptex_offset + s.num_ptex_faces();
- }
+ if (subd_faces.size()) {
+ SubdFace &s = subd_faces[subd_faces.size() - 1];
+ ptex_offset = s.ptex_offset + s.num_ptex_faces();
+ }
- SubdFace face = {start_corner, num_corners, shader_, smooth_, ptex_offset};
- subd_faces.push_back_reserved(face);
+ SubdFace face = {start_corner, num_corners, shader_, smooth_, ptex_offset};
+ subd_faces.push_back_reserved(face);
}
void Mesh::compute_bounds()
{
- BoundBox bnds = BoundBox::empty;
- size_t verts_size = verts.size();
- size_t curve_keys_size = curve_keys.size();
+ BoundBox bnds = BoundBox::empty;
+ size_t verts_size = verts.size();
+ size_t curve_keys_size = curve_keys.size();
- if(verts_size + curve_keys_size > 0) {
- for(size_t i = 0; i < verts_size; i++)
- bnds.grow(verts[i]);
+ if (verts_size + curve_keys_size > 0) {
+ for (size_t i = 0; i < verts_size; i++)
+ bnds.grow(verts[i]);
- for(size_t i = 0; i < curve_keys_size; i++)
- bnds.grow(curve_keys[i], curve_radius[i]);
+ for (size_t i = 0; i < curve_keys_size; i++)
+ bnds.grow(curve_keys[i], curve_radius[i]);
- Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(use_motion_blur && attr) {
- size_t steps_size = verts.size() * (motion_steps - 1);
- float3 *vert_steps = attr->data_float3();
+ Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (use_motion_blur && attr) {
+ size_t steps_size = verts.size() * (motion_steps - 1);
+ float3 *vert_steps = attr->data_float3();
- for(size_t i = 0; i < steps_size; i++)
- bnds.grow(vert_steps[i]);
- }
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow(vert_steps[i]);
+ }
- Attribute *curve_attr = curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(use_motion_blur && curve_attr) {
- size_t steps_size = curve_keys.size() * (motion_steps - 1);
- float3 *key_steps = curve_attr->data_float3();
+ Attribute *curve_attr = curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (use_motion_blur && curve_attr) {
+ size_t steps_size = curve_keys.size() * (motion_steps - 1);
+ float3 *key_steps = curve_attr->data_float3();
- for(size_t i = 0; i < steps_size; i++)
- bnds.grow(key_steps[i]);
- }
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow(key_steps[i]);
+ }
- if(!bnds.valid()) {
- bnds = BoundBox::empty;
+ if (!bnds.valid()) {
+ bnds = BoundBox::empty;
- /* skip nan or inf coordinates */
- for(size_t i = 0; i < verts_size; i++)
- bnds.grow_safe(verts[i]);
+ /* skip nan or inf coordinates */
+ for (size_t i = 0; i < verts_size; i++)
+ bnds.grow_safe(verts[i]);
- for(size_t i = 0; i < curve_keys_size; i++)
- bnds.grow_safe(curve_keys[i], curve_radius[i]);
+ for (size_t i = 0; i < curve_keys_size; i++)
+ bnds.grow_safe(curve_keys[i], curve_radius[i]);
- if(use_motion_blur && attr) {
- size_t steps_size = verts.size() * (motion_steps - 1);
- float3 *vert_steps = attr->data_float3();
+ if (use_motion_blur && attr) {
+ size_t steps_size = verts.size() * (motion_steps - 1);
+ float3 *vert_steps = attr->data_float3();
- for(size_t i = 0; i < steps_size; i++)
- bnds.grow_safe(vert_steps[i]);
- }
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow_safe(vert_steps[i]);
+ }
- if(use_motion_blur && curve_attr) {
- size_t steps_size = curve_keys.size() * (motion_steps - 1);
- float3 *key_steps = curve_attr->data_float3();
+ if (use_motion_blur && curve_attr) {
+ size_t steps_size = curve_keys.size() * (motion_steps - 1);
+ float3 *key_steps = curve_attr->data_float3();
- for(size_t i = 0; i < steps_size; i++)
- bnds.grow_safe(key_steps[i]);
- }
- }
- }
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow_safe(key_steps[i]);
+ }
+ }
+ }
- if(!bnds.valid()) {
- /* empty mesh */
- bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
- }
+ if (!bnds.valid()) {
+ /* empty mesh */
+ bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
+ }
- bounds = bnds;
+ bounds = bnds;
}
void Mesh::add_face_normals()
{
- /* don't compute if already there */
- if(attributes.find(ATTR_STD_FACE_NORMAL))
- return;
+ /* don't compute if already there */
+ if (attributes.find(ATTR_STD_FACE_NORMAL))
+ return;
- /* get attributes */
- Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
- float3 *fN = attr_fN->data_float3();
+ /* get attributes */
+ Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
+ float3 *fN = attr_fN->data_float3();
- /* compute face normals */
- size_t triangles_size = num_triangles();
+ /* compute face normals */
+ size_t triangles_size = num_triangles();
- if(triangles_size) {
- float3 *verts_ptr = verts.data();
+ if (triangles_size) {
+ float3 *verts_ptr = verts.data();
- for(size_t i = 0; i < triangles_size; i++) {
- fN[i] = get_triangle(i).compute_normal(verts_ptr);
- }
- }
+ for (size_t i = 0; i < triangles_size; i++) {
+ fN[i] = get_triangle(i).compute_normal(verts_ptr);
+ }
+ }
- /* expected to be in local space */
- if(transform_applied) {
- Transform ntfm = transform_inverse(transform_normal);
+ /* expected to be in local space */
+ if (transform_applied) {
+ Transform ntfm = transform_inverse(transform_normal);
- for(size_t i = 0; i < triangles_size; i++)
- fN[i] = normalize(transform_direction(&ntfm, fN[i]));
- }
+ for (size_t i = 0; i < triangles_size; i++)
+ fN[i] = normalize(transform_direction(&ntfm, fN[i]));
+ }
}
void Mesh::add_vertex_normals()
{
- bool flip = transform_negative_scaled;
- size_t verts_size = verts.size();
- size_t triangles_size = num_triangles();
-
- /* static vertex normals */
- if(!attributes.find(ATTR_STD_VERTEX_NORMAL) && triangles_size) {
- /* get attributes */
- Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
- Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
-
- float3 *fN = attr_fN->data_float3();
- float3 *vN = attr_vN->data_float3();
-
- /* compute vertex normals */
- memset(vN, 0, verts.size()*sizeof(float3));
-
- for(size_t i = 0; i < triangles_size; i++) {
- for(size_t j = 0; j < 3; j++) {
- vN[get_triangle(i).v[j]] += fN[i];
- }
- }
-
- for(size_t i = 0; i < verts_size; i++) {
- vN[i] = normalize(vN[i]);
- if(flip) {
- vN[i] = -vN[i];
- }
- }
- }
-
- /* motion vertex normals */
- Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
-
- if(has_motion_blur() && attr_mP && !attr_mN && triangles_size) {
- /* create attribute */
- attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
-
- for(int step = 0; step < motion_steps - 1; step++) {
- float3 *mP = attr_mP->data_float3() + step*verts.size();
- float3 *mN = attr_mN->data_float3() + step*verts.size();
-
- /* compute */
- memset(mN, 0, verts.size()*sizeof(float3));
-
- for(size_t i = 0; i < triangles_size; i++) {
- for(size_t j = 0; j < 3; j++) {
- float3 fN = get_triangle(i).compute_normal(mP);
- mN[get_triangle(i).v[j]] += fN;
- }
- }
-
- for(size_t i = 0; i < verts_size; i++) {
- mN[i] = normalize(mN[i]);
- if(flip) {
- mN[i] = -mN[i];
- }
- }
- }
- }
-
- /* subd vertex normals */
- if(!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && subd_faces.size()) {
- /* get attributes */
- Attribute *attr_vN = subd_attributes.add(ATTR_STD_VERTEX_NORMAL);
- float3 *vN = attr_vN->data_float3();
-
- /* compute vertex normals */
- memset(vN, 0, verts.size()*sizeof(float3));
-
- for(size_t i = 0; i < subd_faces.size(); i++) {
- SubdFace& face = subd_faces[i];
- float3 fN = face.normal(this);
-
- for(size_t j = 0; j < face.num_corners; j++) {
- size_t corner = subd_face_corners[face.start_corner+j];
- vN[corner] += fN;
- }
- }
-
- for(size_t i = 0; i < verts_size; i++) {
- vN[i] = normalize(vN[i]);
- if(flip) {
- vN[i] = -vN[i];
- }
- }
- }
+ bool flip = transform_negative_scaled;
+ size_t verts_size = verts.size();
+ size_t triangles_size = num_triangles();
+
+ /* static vertex normals */
+ if (!attributes.find(ATTR_STD_VERTEX_NORMAL) && triangles_size) {
+ /* get attributes */
+ Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
+ Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
+
+ float3 *fN = attr_fN->data_float3();
+ float3 *vN = attr_vN->data_float3();
+
+ /* compute vertex normals */
+ memset(vN, 0, verts.size() * sizeof(float3));
+
+ for (size_t i = 0; i < triangles_size; i++) {
+ for (size_t j = 0; j < 3; j++) {
+ vN[get_triangle(i).v[j]] += fN[i];
+ }
+ }
+
+ for (size_t i = 0; i < verts_size; i++) {
+ vN[i] = normalize(vN[i]);
+ if (flip) {
+ vN[i] = -vN[i];
+ }
+ }
+ }
+
+ /* motion vertex normals */
+ Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ if (has_motion_blur() && attr_mP && !attr_mN && triangles_size) {
+ /* create attribute */
+ attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ for (int step = 0; step < motion_steps - 1; step++) {
+ float3 *mP = attr_mP->data_float3() + step * verts.size();
+ float3 *mN = attr_mN->data_float3() + step * verts.size();
+
+ /* compute */
+ memset(mN, 0, verts.size() * sizeof(float3));
+
+ for (size_t i = 0; i < triangles_size; i++) {
+ for (size_t j = 0; j < 3; j++) {
+ float3 fN = get_triangle(i).compute_normal(mP);
+ mN[get_triangle(i).v[j]] += fN;
+ }
+ }
+
+ for (size_t i = 0; i < verts_size; i++) {
+ mN[i] = normalize(mN[i]);
+ if (flip) {
+ mN[i] = -mN[i];
+ }
+ }
+ }
+ }
+
+ /* subd vertex normals */
+ if (!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && subd_faces.size()) {
+ /* get attributes */
+ Attribute *attr_vN = subd_attributes.add(ATTR_STD_VERTEX_NORMAL);
+ float3 *vN = attr_vN->data_float3();
+
+ /* compute vertex normals */
+ memset(vN, 0, verts.size() * sizeof(float3));
+
+ for (size_t i = 0; i < subd_faces.size(); i++) {
+ SubdFace &face = subd_faces[i];
+ float3 fN = face.normal(this);
+
+ for (size_t j = 0; j < face.num_corners; j++) {
+ size_t corner = subd_face_corners[face.start_corner + j];
+ vN[corner] += fN;
+ }
+ }
+
+ for (size_t i = 0; i < verts_size; i++) {
+ vN[i] = normalize(vN[i]);
+ if (flip) {
+ vN[i] = -vN[i];
+ }
+ }
+ }
}
void Mesh::add_undisplaced()
{
- AttributeSet& attrs = (subdivision_type == SUBDIVISION_NONE) ? attributes : subd_attributes;
+ AttributeSet &attrs = (subdivision_type == SUBDIVISION_NONE) ? attributes : subd_attributes;
- /* don't compute if already there */
- if(attrs.find(ATTR_STD_POSITION_UNDISPLACED)) {
- return;
- }
+ /* don't compute if already there */
+ if (attrs.find(ATTR_STD_POSITION_UNDISPLACED)) {
+ return;
+ }
- /* get attribute */
- Attribute *attr = attrs.add(ATTR_STD_POSITION_UNDISPLACED);
- attr->flags |= ATTR_SUBDIVIDED;
+ /* get attribute */
+ Attribute *attr = attrs.add(ATTR_STD_POSITION_UNDISPLACED);
+ attr->flags |= ATTR_SUBDIVIDED;
- float3 *data = attr->data_float3();
+ float3 *data = attr->data_float3();
- /* copy verts */
- size_t size = attr->buffer_size(this, (subdivision_type == SUBDIVISION_NONE) ? ATTR_PRIM_TRIANGLE : ATTR_PRIM_SUBD);
+ /* copy verts */
+ size_t size = attr->buffer_size(
+ this, (subdivision_type == SUBDIVISION_NONE) ? ATTR_PRIM_TRIANGLE : ATTR_PRIM_SUBD);
- /* Center points for ngons aren't stored in Mesh::verts but are included in size since they will be
- * calculated later, we subtract them from size here so we don't have an overflow while copying.
- */
- size -= num_ngons * attr->data_sizeof();
+ /* Center points for ngons aren't stored in Mesh::verts but are included in size since they will be
+ * calculated later, we subtract them from size here so we don't have an overflow while copying.
+ */
+ size -= num_ngons * attr->data_sizeof();
- if(size) {
- memcpy(data, verts.data(), size);
- }
+ if (size) {
+ memcpy(data, verts.data(), size);
+ }
}
void Mesh::pack_shaders(Scene *scene, uint *tri_shader)
{
- uint shader_id = 0;
- uint last_shader = -1;
- bool last_smooth = false;
+ uint shader_id = 0;
+ uint last_shader = -1;
+ bool last_smooth = false;
- size_t triangles_size = num_triangles();
- int *shader_ptr = shader.data();
+ size_t triangles_size = num_triangles();
+ int *shader_ptr = shader.data();
- for(size_t i = 0; i < triangles_size; i++) {
- if(shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
- last_shader = shader_ptr[i];
- last_smooth = smooth[i];
- Shader *shader = (last_shader < used_shaders.size()) ?
- used_shaders[last_shader] : scene->default_surface;
- shader_id = scene->shader_manager->get_shader_id(shader, last_smooth);
- }
+ for (size_t i = 0; i < triangles_size; i++) {
+ if (shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
+ last_shader = shader_ptr[i];
+ last_smooth = smooth[i];
+ Shader *shader = (last_shader < used_shaders.size()) ? used_shaders[last_shader] :
+ scene->default_surface;
+ shader_id = scene->shader_manager->get_shader_id(shader, last_smooth);
+ }
- tri_shader[i] = shader_id;
- }
+ tri_shader[i] = shader_id;
+ }
}
void Mesh::pack_normals(float4 *vnormal)
{
- Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
- if(attr_vN == NULL) {
- /* Happens on objects with just hair. */
- return;
- }
+ Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
+ if (attr_vN == NULL) {
+ /* Happens on objects with just hair. */
+ return;
+ }
- bool do_transform = transform_applied;
- Transform ntfm = transform_normal;
+ bool do_transform = transform_applied;
+ Transform ntfm = transform_normal;
- float3 *vN = attr_vN->data_float3();
- size_t verts_size = verts.size();
+ float3 *vN = attr_vN->data_float3();
+ size_t verts_size = verts.size();
- for(size_t i = 0; i < verts_size; i++) {
- float3 vNi = vN[i];
+ for (size_t i = 0; i < verts_size; i++) {
+ float3 vNi = vN[i];
- if(do_transform)
- vNi = safe_normalize(transform_direction(&ntfm, vNi));
+ if (do_transform)
+ vNi = safe_normalize(transform_direction(&ntfm, vNi));
- vnormal[i] = make_float4(vNi.x, vNi.y, vNi.z, 0.0f);
- }
+ vnormal[i] = make_float4(vNi.x, vNi.y, vNi.z, 0.0f);
+ }
}
-void Mesh::pack_verts(const vector<uint>& tri_prim_index,
+void Mesh::pack_verts(const vector<uint> &tri_prim_index,
uint4 *tri_vindex,
uint *tri_patch,
float2 *tri_patch_uv,
size_t vert_offset,
size_t tri_offset)
{
- size_t verts_size = verts.size();
+ size_t verts_size = verts.size();
- if(verts_size && subd_faces.size()) {
- float2 *vert_patch_uv_ptr = vert_patch_uv.data();
+ if (verts_size && subd_faces.size()) {
+ float2 *vert_patch_uv_ptr = vert_patch_uv.data();
- for(size_t i = 0; i < verts_size; i++) {
- tri_patch_uv[i] = vert_patch_uv_ptr[i];
- }
- }
+ for (size_t i = 0; i < verts_size; i++) {
+ tri_patch_uv[i] = vert_patch_uv_ptr[i];
+ }
+ }
- size_t triangles_size = num_triangles();
+ size_t triangles_size = num_triangles();
- for(size_t i = 0; i < triangles_size; i++) {
- Triangle t = get_triangle(i);
- tri_vindex[i] = make_uint4(t.v[0] + vert_offset,
- t.v[1] + vert_offset,
- t.v[2] + vert_offset,
- tri_prim_index[i + tri_offset]);
+ for (size_t i = 0; i < triangles_size; i++) {
+ Triangle t = get_triangle(i);
+ tri_vindex[i] = make_uint4(t.v[0] + vert_offset,
+ t.v[1] + vert_offset,
+ t.v[2] + vert_offset,
+ tri_prim_index[i + tri_offset]);
- tri_patch[i] = (!subd_faces.size()) ? -1 : (triangle_patch[i]*8 + patch_offset);
- }
+ tri_patch[i] = (!subd_faces.size()) ? -1 : (triangle_patch[i] * 8 + patch_offset);
+ }
}
-void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
+void Mesh::pack_curves(Scene *scene,
+ float4 *curve_key_co,
+ float4 *curve_data,
+ size_t curvekey_offset)
{
- size_t curve_keys_size = curve_keys.size();
+ size_t curve_keys_size = curve_keys.size();
- /* pack curve keys */
- if(curve_keys_size) {
- float3 *keys_ptr = curve_keys.data();
- float *radius_ptr = curve_radius.data();
+ /* pack curve keys */
+ if (curve_keys_size) {
+ float3 *keys_ptr = curve_keys.data();
+ float *radius_ptr = curve_radius.data();
- for(size_t i = 0; i < curve_keys_size; i++)
- curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]);
- }
+ for (size_t i = 0; i < curve_keys_size; i++)
+ curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]);
+ }
- /* pack curve segments */
- size_t curve_num = num_curves();
+ /* pack curve segments */
+ size_t curve_num = num_curves();
- for(size_t i = 0; i < curve_num; i++) {
- Curve curve = get_curve(i);
- int shader_id = curve_shader[i];
- Shader *shader = (shader_id < used_shaders.size()) ?
- used_shaders[shader_id] : scene->default_surface;
- shader_id = scene->shader_manager->get_shader_id(shader, false);
+ for (size_t i = 0; i < curve_num; i++) {
+ Curve curve = get_curve(i);
+ int shader_id = curve_shader[i];
+ Shader *shader = (shader_id < used_shaders.size()) ? used_shaders[shader_id] :
+ scene->default_surface;
+ shader_id = scene->shader_manager->get_shader_id(shader, false);
- curve_data[i] = make_float4(
- __int_as_float(curve.first_key + curvekey_offset),
- __int_as_float(curve.num_keys),
- __int_as_float(shader_id),
- 0.0f);
- }
+ curve_data[i] = make_float4(__int_as_float(curve.first_key + curvekey_offset),
+ __int_as_float(curve.num_keys),
+ __int_as_float(shader_id),
+ 0.0f);
+ }
}
void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset)
{
- size_t num_faces = subd_faces.size();
- int ngons = 0;
-
- for(size_t f = 0; f < num_faces; f++) {
- SubdFace face = subd_faces[f];
-
- if(face.is_quad()) {
- int c[4];
- memcpy(c, &subd_face_corners[face.start_corner], sizeof(int)*4);
-
- *(patch_data++) = c[0] + vert_offset;
- *(patch_data++) = c[1] + vert_offset;
- *(patch_data++) = c[2] + vert_offset;
- *(patch_data++) = c[3] + vert_offset;
-
- *(patch_data++) = f+face_offset;
- *(patch_data++) = face.num_corners;
- *(patch_data++) = face.start_corner + corner_offset;
- *(patch_data++) = 0;
- }
- else {
- for(int i = 0; i < face.num_corners; i++) {
- int c[4];
- c[0] = subd_face_corners[face.start_corner + mod(i + 0, face.num_corners)];
- c[1] = subd_face_corners[face.start_corner + mod(i + 1, face.num_corners)];
- c[2] = verts.size() - num_subd_verts + ngons;
- c[3] = subd_face_corners[face.start_corner + mod(i - 1, face.num_corners)];
-
- *(patch_data++) = c[0] + vert_offset;
- *(patch_data++) = c[1] + vert_offset;
- *(patch_data++) = c[2] + vert_offset;
- *(patch_data++) = c[3] + vert_offset;
-
- *(patch_data++) = f+face_offset;
- *(patch_data++) = face.num_corners | (i << 16);
- *(patch_data++) = face.start_corner + corner_offset;
- *(patch_data++) = subd_face_corners.size() + ngons + corner_offset;
- }
-
- ngons++;
- }
- }
-}
-
-void Mesh::compute_bvh(Device *device,
- DeviceScene *dscene,
- SceneParams *params,
- Progress *progress,
- int n,
- int total)
-{
- if(progress->get_cancel())
- return;
-
- compute_bounds();
-
- if(need_build_bvh()) {
- string msg = "Updating Mesh BVH ";
- if(name == "")
- msg += string_printf("%u/%u", (uint)(n+1), (uint)total);
- else
- msg += string_printf("%s %u/%u", name.c_str(), (uint)(n+1), (uint)total);
-
- Object object;
- object.mesh = this;
-
- vector<Object*> objects;
- objects.push_back(&object);
-
- if(bvh && !need_update_rebuild) {
- progress->set_status(msg, "Refitting BVH");
- bvh->objects = objects;
- bvh->refit(*progress);
- }
- else {
- progress->set_status(msg, "Building BVH");
-
- BVHParams bparams;
- bparams.use_spatial_split = params->use_bvh_spatial_split;
- bparams.bvh_layout = BVHParams::best_bvh_layout(
- params->bvh_layout,
- device->get_bvh_layout_mask());
- bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
- params->use_bvh_unaligned_nodes;
- bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
- bparams.num_motion_curve_steps = params->num_bvh_time_steps;
- bparams.bvh_type = params->bvh_type;
- bparams.curve_flags = dscene->data.curve.curveflags;
- bparams.curve_subdivisions = dscene->data.curve.subdivisions;
-
- delete bvh;
- bvh = BVH::create(bparams, objects);
- MEM_GUARDED_CALL(progress, bvh->build, *progress);
- }
- }
-
- need_update = false;
- need_update_rebuild = false;
+ size_t num_faces = subd_faces.size();
+ int ngons = 0;
+
+ for (size_t f = 0; f < num_faces; f++) {
+ SubdFace face = subd_faces[f];
+
+ if (face.is_quad()) {
+ int c[4];
+ memcpy(c, &subd_face_corners[face.start_corner], sizeof(int) * 4);
+
+ *(patch_data++) = c[0] + vert_offset;
+ *(patch_data++) = c[1] + vert_offset;
+ *(patch_data++) = c[2] + vert_offset;
+ *(patch_data++) = c[3] + vert_offset;
+
+ *(patch_data++) = f + face_offset;
+ *(patch_data++) = face.num_corners;
+ *(patch_data++) = face.start_corner + corner_offset;
+ *(patch_data++) = 0;
+ }
+ else {
+ for (int i = 0; i < face.num_corners; i++) {
+ int c[4];
+ c[0] = subd_face_corners[face.start_corner + mod(i + 0, face.num_corners)];
+ c[1] = subd_face_corners[face.start_corner + mod(i + 1, face.num_corners)];
+ c[2] = verts.size() - num_subd_verts + ngons;
+ c[3] = subd_face_corners[face.start_corner + mod(i - 1, face.num_corners)];
+
+ *(patch_data++) = c[0] + vert_offset;
+ *(patch_data++) = c[1] + vert_offset;
+ *(patch_data++) = c[2] + vert_offset;
+ *(patch_data++) = c[3] + vert_offset;
+
+ *(patch_data++) = f + face_offset;
+ *(patch_data++) = face.num_corners | (i << 16);
+ *(patch_data++) = face.start_corner + corner_offset;
+ *(patch_data++) = subd_face_corners.size() + ngons + corner_offset;
+ }
+
+ ngons++;
+ }
+ }
+}
+
+void Mesh::compute_bvh(
+ Device *device, DeviceScene *dscene, SceneParams *params, Progress *progress, int n, int total)
+{
+ if (progress->get_cancel())
+ return;
+
+ compute_bounds();
+
+ if (need_build_bvh()) {
+ string msg = "Updating Mesh BVH ";
+ if (name == "")
+ msg += string_printf("%u/%u", (uint)(n + 1), (uint)total);
+ else
+ msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total);
+
+ Object object;
+ object.mesh = this;
+
+ vector<Object *> objects;
+ objects.push_back(&object);
+
+ if (bvh && !need_update_rebuild) {
+ progress->set_status(msg, "Refitting BVH");
+ bvh->objects = objects;
+ bvh->refit(*progress);
+ }
+ else {
+ progress->set_status(msg, "Building BVH");
+
+ BVHParams bparams;
+ bparams.use_spatial_split = params->use_bvh_spatial_split;
+ bparams.bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout,
+ device->get_bvh_layout_mask());
+ bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
+ params->use_bvh_unaligned_nodes;
+ bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
+ bparams.num_motion_curve_steps = params->num_bvh_time_steps;
+ bparams.bvh_type = params->bvh_type;
+ bparams.curve_flags = dscene->data.curve.curveflags;
+ bparams.curve_subdivisions = dscene->data.curve.subdivisions;
+
+ delete bvh;
+ bvh = BVH::create(bparams, objects);
+ MEM_GUARDED_CALL(progress, bvh->build, *progress);
+ }
+ }
+
+ need_update = false;
+ need_update_rebuild = false;
}
void Mesh::tag_update(Scene *scene, bool rebuild)
{
- need_update = true;
+ need_update = true;
- if(rebuild) {
- need_update_rebuild = true;
- scene->light_manager->need_update = true;
- }
- else {
- foreach(Shader *shader, used_shaders)
- if(shader->has_surface_emission)
- scene->light_manager->need_update = true;
- }
+ if (rebuild) {
+ need_update_rebuild = true;
+ scene->light_manager->need_update = true;
+ }
+ else {
+ foreach (Shader *shader, used_shaders)
+ if (shader->has_surface_emission)
+ scene->light_manager->need_update = true;
+ }
- scene->mesh_manager->need_update = true;
- scene->object_manager->need_update = true;
+ scene->mesh_manager->need_update = true;
+ scene->object_manager->need_update = true;
}
bool Mesh::has_motion_blur() const
{
- return (use_motion_blur &&
- (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) ||
- curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)));
+ return (use_motion_blur && (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) ||
+ curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)));
}
bool Mesh::has_true_displacement() const
{
- foreach(Shader *shader, used_shaders) {
- if(shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) {
- return true;
- }
- }
+ foreach (Shader *shader, used_shaders) {
+ if (shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
float Mesh::motion_time(int step) const
{
- return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f;
+ return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f;
}
int Mesh::motion_step(float time) const
{
- if(motion_steps > 1) {
- int attr_step = 0;
+ if (motion_steps > 1) {
+ int attr_step = 0;
- for(int step = 0; step < motion_steps; step++) {
- float step_time = motion_time(step);
- if(step_time == time) {
- return attr_step;
- }
+ for (int step = 0; step < motion_steps; step++) {
+ float step_time = motion_time(step);
+ if (step_time == time) {
+ return attr_step;
+ }
- /* Center step is stored in a separate attribute. */
- if(step != motion_steps / 2) {
- attr_step++;
- }
- }
- }
+ /* Center step is stored in a separate attribute. */
+ if (step != motion_steps / 2) {
+ attr_step++;
+ }
+ }
+ }
- return -1;
+ return -1;
}
bool Mesh::need_build_bvh() const
{
- return !transform_applied || has_surface_bssrdf;
+ return !transform_applied || has_surface_bssrdf;
}
bool Mesh::is_instanced() const
{
- /* Currently we treat subsurface objects as instanced.
- *
- * While it might be not very optimal for ray traversal, it avoids having
- * duplicated BVH in the memory, saving quite some space.
- */
- return !transform_applied || has_surface_bssrdf;
+ /* Currently we treat subsurface objects as instanced.
+ *
+ * While it might be not very optimal for ray traversal, it avoids having
+ * duplicated BVH in the memory, saving quite some space.
+ */
+ return !transform_applied || has_surface_bssrdf;
}
/* Mesh Manager */
MeshManager::MeshManager()
{
- need_update = true;
- need_flags_update = true;
+ need_update = true;
+ need_flags_update = true;
}
MeshManager::~MeshManager()
{
}
-void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<AttributeRequestSet>& mesh_attributes)
+void MeshManager::update_osl_attributes(Device *device,
+ Scene *scene,
+ vector<AttributeRequestSet> &mesh_attributes)
{
#ifdef WITH_OSL
- /* for OSL, a hash map is used to lookup the attribute by name. */
- OSLGlobals *og = (OSLGlobals*)device->osl_memory();
-
- og->object_name_map.clear();
- og->attribute_map.clear();
- og->object_names.clear();
-
- og->attribute_map.resize(scene->objects.size()*ATTR_PRIM_TYPES);
-
- for(size_t i = 0; i < scene->objects.size(); i++) {
- /* set object name to object index map */
- Object *object = scene->objects[i];
- og->object_name_map[object->name] = i;
- og->object_names.push_back(object->name);
-
- /* set object attributes */
- foreach(ParamValue& attr, object->attributes) {
- OSLGlobals::Attribute osl_attr;
-
- osl_attr.type = attr.type();
- osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
- osl_attr.value = attr;
- osl_attr.desc.offset = 0;
- osl_attr.desc.flags = 0;
-
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][attr.name()] = osl_attr;
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr;
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
- }
-
- /* find mesh attributes */
- size_t j;
-
- for(j = 0; j < scene->meshes.size(); j++)
- if(scene->meshes[j] == object->mesh)
- break;
-
- AttributeRequestSet& attributes = mesh_attributes[j];
-
- /* set object attributes */
- foreach(AttributeRequest& req, attributes.requests) {
- OSLGlobals::Attribute osl_attr;
-
- if(req.triangle_desc.element != ATTR_ELEMENT_NONE) {
- osl_attr.desc = req.triangle_desc;
-
- if(req.triangle_type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else if(req.triangle_type == TypeDesc::TypeMatrix)
- osl_attr.type = TypeDesc::TypeMatrix;
- else if(req.triangle_type == TypeFloat2)
- osl_attr.type = TypeFloat2;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if(req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][stdname] = osl_attr;
- }
- else if(req.name != ustring()) {
- /* add lookup by mesh attribute name */
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][req.name] = osl_attr;
- }
- }
-
- if(req.curve_desc.element != ATTR_ELEMENT_NONE) {
- osl_attr.desc = req.curve_desc;
-
- if(req.curve_type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else if(req.curve_type == TypeDesc::TypeMatrix)
- osl_attr.type = TypeDesc::TypeMatrix;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if(req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr;
- }
- else if(req.name != ustring()) {
- /* add lookup by mesh attribute name */
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr;
- }
- }
-
- if(req.subd_desc.element != ATTR_ELEMENT_NONE) {
- osl_attr.desc = req.subd_desc;
-
- if(req.subd_type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else if(req.subd_type == TypeDesc::TypeMatrix)
- osl_attr.type = TypeDesc::TypeMatrix;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if(req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
- }
- else if(req.name != ustring()) {
- /* add lookup by mesh attribute name */
- og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
- }
- }
- }
- }
+ /* for OSL, a hash map is used to lookup the attribute by name. */
+ OSLGlobals *og = (OSLGlobals *)device->osl_memory();
+
+ og->object_name_map.clear();
+ og->attribute_map.clear();
+ og->object_names.clear();
+
+ og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
+
+ for (size_t i = 0; i < scene->objects.size(); i++) {
+ /* set object name to object index map */
+ Object *object = scene->objects[i];
+ og->object_name_map[object->name] = i;
+ og->object_names.push_back(object->name);
+
+ /* set object attributes */
+ foreach (ParamValue &attr, object->attributes) {
+ OSLGlobals::Attribute osl_attr;
+
+ osl_attr.type = attr.type();
+ osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
+ osl_attr.value = attr;
+ osl_attr.desc.offset = 0;
+ osl_attr.desc.flags = 0;
+
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][attr.name()] = osl_attr;
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr;
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
+ }
+
+ /* find mesh attributes */
+ size_t j;
+
+ for (j = 0; j < scene->meshes.size(); j++)
+ if (scene->meshes[j] == object->mesh)
+ break;
+
+ AttributeRequestSet &attributes = mesh_attributes[j];
+
+ /* set object attributes */
+ foreach (AttributeRequest &req, attributes.requests) {
+ OSLGlobals::Attribute osl_attr;
+
+ if (req.triangle_desc.element != ATTR_ELEMENT_NONE) {
+ osl_attr.desc = req.triangle_desc;
+
+ if (req.triangle_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else if (req.triangle_type == TypeDesc::TypeMatrix)
+ osl_attr.type = TypeDesc::TypeMatrix;
+ else if (req.triangle_type == TypeFloat2)
+ osl_attr.type = TypeFloat2;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if (req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][stdname] = osl_attr;
+ }
+ else if (req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][req.name] = osl_attr;
+ }
+ }
+
+ if (req.curve_desc.element != ATTR_ELEMENT_NONE) {
+ osl_attr.desc = req.curve_desc;
+
+ if (req.curve_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else if (req.curve_type == TypeDesc::TypeMatrix)
+ osl_attr.type = TypeDesc::TypeMatrix;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if (req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr;
+ }
+ else if (req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr;
+ }
+ }
+
+ if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
+ osl_attr.desc = req.subd_desc;
+
+ if (req.subd_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else if (req.subd_type == TypeDesc::TypeMatrix)
+ osl_attr.type = TypeDesc::TypeMatrix;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if (req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
+ }
+ else if (req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
+ }
+ }
+ }
+ }
#else
- (void) device;
- (void) scene;
- (void) mesh_attributes;
+ (void)device;
+ (void)scene;
+ (void)mesh_attributes;
#endif
}
-void MeshManager::update_svm_attributes(Device *, DeviceScene *dscene, Scene *scene, vector<AttributeRequestSet>& mesh_attributes)
-{
- /* for SVM, the attributes_map table is used to lookup the offset of an
- * attribute, based on a unique shader attribute id. */
-
- /* compute array stride */
- int attr_map_size = 0;
+void MeshManager::update_svm_attributes(Device *,
+ DeviceScene *dscene,
+ Scene *scene,
+ vector<AttributeRequestSet> &mesh_attributes)
+{
+ /* for SVM, the attributes_map table is used to lookup the offset of an
+ * attribute, based on a unique shader attribute id. */
+
+ /* compute array stride */
+ int attr_map_size = 0;
+
+ for (size_t i = 0; i < scene->meshes.size(); i++) {
+ Mesh *mesh = scene->meshes[i];
+ mesh->attr_map_offset = attr_map_size;
+ attr_map_size += (mesh_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
+ }
- for(size_t i = 0; i < scene->meshes.size(); i++) {
- Mesh *mesh = scene->meshes[i];
- mesh->attr_map_offset = attr_map_size;
- attr_map_size += (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES;
- }
+ if (attr_map_size == 0)
+ return;
- if(attr_map_size == 0)
- return;
+ /* create attribute map */
+ uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
+ memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
- /* create attribute map */
- uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
- memset(attr_map, 0, dscene->attributes_map.size()*sizeof(uint));
+ for (size_t i = 0; i < scene->meshes.size(); i++) {
+ Mesh *mesh = scene->meshes[i];
+ AttributeRequestSet &attributes = mesh_attributes[i];
- for(size_t i = 0; i < scene->meshes.size(); i++) {
- Mesh *mesh = scene->meshes[i];
- AttributeRequestSet& attributes = mesh_attributes[i];
+ /* set object attributes */
+ int index = mesh->attr_map_offset;
- /* set object attributes */
- int index = mesh->attr_map_offset;
+ foreach (AttributeRequest &req, attributes.requests) {
+ uint id;
- foreach(AttributeRequest& req, attributes.requests) {
- uint id;
+ if (req.std == ATTR_STD_NONE)
+ id = scene->shader_manager->get_attribute_id(req.name);
+ else
+ id = scene->shader_manager->get_attribute_id(req.std);
- if(req.std == ATTR_STD_NONE)
- id = scene->shader_manager->get_attribute_id(req.name);
- else
- id = scene->shader_manager->get_attribute_id(req.std);
+ if (mesh->num_triangles()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.triangle_desc.element;
+ attr_map[index].z = as_uint(req.triangle_desc.offset);
- if(mesh->num_triangles()) {
- attr_map[index].x = id;
- attr_map[index].y = req.triangle_desc.element;
- attr_map[index].z = as_uint(req.triangle_desc.offset);
+ if (req.triangle_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else if (req.triangle_type == TypeDesc::TypeMatrix)
+ attr_map[index].w = NODE_ATTR_MATRIX;
+ else if (req.triangle_type == TypeFloat2)
+ attr_map[index].w = NODE_ATTR_FLOAT2;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
- if(req.triangle_type == TypeDesc::TypeFloat)
- attr_map[index].w = NODE_ATTR_FLOAT;
- else if(req.triangle_type == TypeDesc::TypeMatrix)
- attr_map[index].w = NODE_ATTR_MATRIX;
- else if(req.triangle_type == TypeFloat2)
- attr_map[index].w = NODE_ATTR_FLOAT2;
- else
- attr_map[index].w = NODE_ATTR_FLOAT3;
+ attr_map[index].w |= req.triangle_desc.flags << 8;
+ }
- attr_map[index].w |= req.triangle_desc.flags << 8;
- }
+ index++;
- index++;
+ if (mesh->num_curves()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.curve_desc.element;
+ attr_map[index].z = as_uint(req.curve_desc.offset);
- if(mesh->num_curves()) {
- attr_map[index].x = id;
- attr_map[index].y = req.curve_desc.element;
- attr_map[index].z = as_uint(req.curve_desc.offset);
+ if (req.curve_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else if (req.curve_type == TypeDesc::TypeMatrix)
+ attr_map[index].w = NODE_ATTR_MATRIX;
+ else if (req.curve_type == TypeFloat2)
+ attr_map[index].w = NODE_ATTR_FLOAT2;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
- if(req.curve_type == TypeDesc::TypeFloat)
- attr_map[index].w = NODE_ATTR_FLOAT;
- else if(req.curve_type == TypeDesc::TypeMatrix)
- attr_map[index].w = NODE_ATTR_MATRIX;
- else if(req.curve_type == TypeFloat2)
- attr_map[index].w = NODE_ATTR_FLOAT2;
- else
- attr_map[index].w = NODE_ATTR_FLOAT3;
+ attr_map[index].w |= req.curve_desc.flags << 8;
+ }
- attr_map[index].w |= req.curve_desc.flags << 8;
- }
+ index++;
- index++;
+ if (mesh->subd_faces.size()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.subd_desc.element;
+ attr_map[index].z = as_uint(req.subd_desc.offset);
- if(mesh->subd_faces.size()) {
- attr_map[index].x = id;
- attr_map[index].y = req.subd_desc.element;
- attr_map[index].z = as_uint(req.subd_desc.offset);
+ if (req.subd_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else if (req.subd_type == TypeDesc::TypeMatrix)
+ attr_map[index].w = NODE_ATTR_MATRIX;
+ else if (req.subd_type == TypeFloat2)
+ attr_map[index].w = NODE_ATTR_FLOAT2;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
- if(req.subd_type == TypeDesc::TypeFloat)
- attr_map[index].w = NODE_ATTR_FLOAT;
- else if(req.subd_type == TypeDesc::TypeMatrix)
- attr_map[index].w = NODE_ATTR_MATRIX;
- else if(req.subd_type == TypeFloat2)
- attr_map[index].w = NODE_ATTR_FLOAT2;
- else
- attr_map[index].w = NODE_ATTR_FLOAT3;
+ attr_map[index].w |= req.subd_desc.flags << 8;
+ }
- attr_map[index].w |= req.subd_desc.flags << 8;
- }
+ index++;
+ }
- index++;
- }
-
- /* terminator */
- for(int j = 0; j < ATTR_PRIM_TYPES; j++) {
- attr_map[index].x = ATTR_STD_NONE;
- attr_map[index].y = 0;
- attr_map[index].z = 0;
- attr_map[index].w = 0;
-
- index++;
- }
- }
-
- /* copy to device */
- dscene->attributes_map.copy_to_device();
+ /* terminator */
+ for (int j = 0; j < ATTR_PRIM_TYPES; j++) {
+ attr_map[index].x = ATTR_STD_NONE;
+ attr_map[index].y = 0;
+ attr_map[index].z = 0;
+ attr_map[index].w = 0;
+
+ index++;
+ }
+ }
+
+ /* copy to device */
+ dscene->attributes_map.copy_to_device();
}
static void update_attribute_element_size(Mesh *mesh,
Attribute *mattr,
AttributePrimitive prim,
size_t *attr_float_size,
- size_t *attr_float2_size,
+ size_t *attr_float2_size,
size_t *attr_float3_size,
size_t *attr_uchar4_size)
{
- if(mattr) {
- size_t size = mattr->element_size(mesh, prim);
-
- if(mattr->element == ATTR_ELEMENT_VOXEL) {
- /* pass */
- }
- else if(mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
- *attr_uchar4_size += size;
- }
- else if(mattr->type == TypeDesc::TypeFloat) {
- *attr_float_size += size;
- }
- else if(mattr->type == TypeFloat2) {
- *attr_float2_size += size;
- }
- else if(mattr->type == TypeDesc::TypeMatrix) {
- *attr_float3_size += size * 4;
- }
- else {
- *attr_float3_size += size;
- }
- }
+ if (mattr) {
+ size_t size = mattr->element_size(mesh, prim);
+
+ if (mattr->element == ATTR_ELEMENT_VOXEL) {
+ /* pass */
+ }
+ else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
+ *attr_uchar4_size += size;
+ }
+ else if (mattr->type == TypeDesc::TypeFloat) {
+ *attr_float_size += size;
+ }
+ else if (mattr->type == TypeFloat2) {
+ *attr_float2_size += size;
+ }
+ else if (mattr->type == TypeDesc::TypeMatrix) {
+ *attr_float3_size += size * 4;
+ }
+ else {
+ *attr_float3_size += size;
+ }
+ }
}
static void update_attribute_element_offset(Mesh *mesh,
- device_vector<float>& attr_float,
- size_t& attr_float_offset,
- device_vector<float2>& attr_float2,
- size_t& attr_float2_offset,
- device_vector<float4>& attr_float3,
- size_t& attr_float3_offset,
- device_vector<uchar4>& attr_uchar4,
- size_t& attr_uchar4_offset,
+ device_vector<float> &attr_float,
+ size_t &attr_float_offset,
+ device_vector<float2> &attr_float2,
+ size_t &attr_float2_offset,
+ device_vector<float4> &attr_float3,
+ size_t &attr_float3_offset,
+ device_vector<uchar4> &attr_uchar4,
+ size_t &attr_uchar4_offset,
Attribute *mattr,
AttributePrimitive prim,
- TypeDesc& type,
- AttributeDescriptor& desc)
-{
- if(mattr) {
- /* store element and type */
- desc.element = mattr->element;
- desc.flags = mattr->flags;
- type = mattr->type;
-
- /* store attribute data in arrays */
- size_t size = mattr->element_size(mesh, prim);
-
- AttributeElement& element = desc.element;
- int& offset = desc.offset;
-
- if(mattr->element == ATTR_ELEMENT_VOXEL) {
- /* store slot in offset value */
- VoxelAttribute *voxel_data = mattr->data_voxel();
- offset = voxel_data->slot;
- }
- else if(mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
- uchar4 *data = mattr->data_uchar4();
- offset = attr_uchar4_offset;
-
- assert(attr_uchar4.size() >= offset + size);
- for(size_t k = 0; k < size; k++) {
- attr_uchar4[offset+k] = data[k];
- }
- attr_uchar4_offset += size;
- }
- else if(mattr->type == TypeDesc::TypeFloat) {
- float *data = mattr->data_float();
- offset = attr_float_offset;
-
- assert(attr_float.size() >= offset + size);
- for(size_t k = 0; k < size; k++) {
- attr_float[offset+k] = data[k];
- }
- attr_float_offset += size;
- }
- else if(mattr->type == TypeFloat2) {
- float2 *data = mattr->data_float2();
- offset = attr_float2_offset;
-
- assert(attr_float2.size() >= offset + size);
- for(size_t k = 0; k < size; k++) {
- attr_float2[offset+k] = data[k];
- }
- attr_float2_offset += size;
- }
- else if(mattr->type == TypeDesc::TypeMatrix) {
- Transform *tfm = mattr->data_transform();
- offset = attr_float3_offset;
-
- assert(attr_float3.size() >= offset + size * 3);
- for(size_t k = 0; k < size*3; k++) {
- attr_float3[offset+k] = (&tfm->x)[k];
- }
- attr_float3_offset += size * 3;
- }
- else {
- float4 *data = mattr->data_float4();
- offset = attr_float3_offset;
-
- assert(attr_float3.size() >= offset + size);
- for(size_t k = 0; k < size; k++) {
- attr_float3[offset+k] = data[k];
- }
- attr_float3_offset += size;
- }
-
- /* mesh vertex/curve index is global, not per object, so we sneak
- * a correction for that in here */
- if(mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK && desc.flags & ATTR_SUBDIVIDED) {
- /* indices for subdivided attributes are retrieved
- * from patch table so no need for correction here*/
- }
- else if(element == ATTR_ELEMENT_VERTEX)
- offset -= mesh->vert_offset;
- else if(element == ATTR_ELEMENT_VERTEX_MOTION)
- offset -= mesh->vert_offset;
- else if(element == ATTR_ELEMENT_FACE) {
- if(prim == ATTR_PRIM_TRIANGLE)
- offset -= mesh->tri_offset;
- else
- offset -= mesh->face_offset;
- }
- else if(element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) {
- if(prim == ATTR_PRIM_TRIANGLE)
- offset -= 3*mesh->tri_offset;
- else
- offset -= mesh->corner_offset;
- }
- else if(element == ATTR_ELEMENT_CURVE)
- offset -= mesh->curve_offset;
- else if(element == ATTR_ELEMENT_CURVE_KEY)
- offset -= mesh->curvekey_offset;
- else if(element == ATTR_ELEMENT_CURVE_KEY_MOTION)
- offset -= mesh->curvekey_offset;
- }
- else {
- /* attribute not found */
- desc.element = ATTR_ELEMENT_NONE;
- desc.offset = 0;
- }
-}
-
-void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
-{
- progress.set_status("Updating Mesh", "Computing attributes");
-
- /* gather per mesh requested attributes. as meshes may have multiple
- * shaders assigned, this merges the requested attributes that have
- * been set per shader by the shader manager */
- vector<AttributeRequestSet> mesh_attributes(scene->meshes.size());
-
- for(size_t i = 0; i < scene->meshes.size(); i++) {
- Mesh *mesh = scene->meshes[i];
-
- scene->need_global_attributes(mesh_attributes[i]);
-
- foreach(Shader *shader, mesh->used_shaders) {
- mesh_attributes[i].add(shader->attributes);
- }
- }
-
- /* mesh attribute are stored in a single array per data type. here we fill
- * those arrays, and set the offset and element type to create attribute
- * maps next */
-
- /* Pre-allocate attributes to avoid arrays re-allocation which would
- * take 2x of overall attribute memory usage.
- */
- size_t attr_float_size = 0;
- size_t attr_float2_size = 0;
- size_t attr_float3_size = 0;
- size_t attr_uchar4_size = 0;
- for(size_t i = 0; i < scene->meshes.size(); i++) {
- Mesh *mesh = scene->meshes[i];
- AttributeRequestSet& attributes = mesh_attributes[i];
- foreach(AttributeRequest& req, attributes.requests) {
- Attribute *triangle_mattr = mesh->attributes.find(req);
- Attribute *curve_mattr = mesh->curve_attributes.find(req);
- Attribute *subd_mattr = mesh->subd_attributes.find(req);
-
- update_attribute_element_size(mesh,
- triangle_mattr,
- ATTR_PRIM_TRIANGLE,
- &attr_float_size,
- &attr_float2_size,
- &attr_float3_size,
- &attr_uchar4_size);
- update_attribute_element_size(mesh,
- curve_mattr,
- ATTR_PRIM_CURVE,
- &attr_float_size,
- &attr_float2_size,
- &attr_float3_size,
- &attr_uchar4_size);
- update_attribute_element_size(mesh,
- subd_mattr,
- ATTR_PRIM_SUBD,
- &attr_float_size,
- &attr_float2_size,
- &attr_float3_size,
- &attr_uchar4_size);
- }
- }
-
- dscene->attributes_float.alloc(attr_float_size);
- dscene->attributes_float2.alloc(attr_float2_size);
- dscene->attributes_float3.alloc(attr_float3_size);
- dscene->attributes_uchar4.alloc(attr_uchar4_size);
-
- size_t attr_float_offset = 0;
- size_t attr_float2_offset = 0;
- size_t attr_float3_offset = 0;
- size_t attr_uchar4_offset = 0;
-
- /* Fill in attributes. */
- for(size_t i = 0; i < scene->meshes.size(); i++) {
- Mesh *mesh = scene->meshes[i];
- AttributeRequestSet& attributes = mesh_attributes[i];
-
- /* todo: we now store std and name attributes from requests even if
- * they actually refer to the same mesh attributes, optimize */
- foreach(AttributeRequest& req, attributes.requests) {
- Attribute *triangle_mattr = mesh->attributes.find(req);
- Attribute *curve_mattr = mesh->curve_attributes.find(req);
- Attribute *subd_mattr = mesh->subd_attributes.find(req);
-
- update_attribute_element_offset(mesh,
- dscene->attributes_float, attr_float_offset,
- dscene->attributes_float2, attr_float2_offset,
- dscene->attributes_float3, attr_float3_offset,
- dscene->attributes_uchar4, attr_uchar4_offset,
- triangle_mattr,
- ATTR_PRIM_TRIANGLE,
- req.triangle_type,
- req.triangle_desc);
-
- update_attribute_element_offset(mesh,
- dscene->attributes_float, attr_float_offset,
- dscene->attributes_float2, attr_float2_offset,
- dscene->attributes_float3, attr_float3_offset,
- dscene->attributes_uchar4, attr_uchar4_offset,
- curve_mattr,
- ATTR_PRIM_CURVE,
- req.curve_type,
- req.curve_desc);
-
- update_attribute_element_offset(mesh,
- dscene->attributes_float, attr_float_offset,
- dscene->attributes_float2, attr_float2_offset,
- dscene->attributes_float3, attr_float3_offset,
- dscene->attributes_uchar4, attr_uchar4_offset,
- subd_mattr,
- ATTR_PRIM_SUBD,
- req.subd_type,
- req.subd_desc);
-
- if(progress.get_cancel()) return;
- }
- }
-
- /* create attribute lookup maps */
- if(scene->shader_manager->use_osl())
- update_osl_attributes(device, scene, mesh_attributes);
-
- update_svm_attributes(device, dscene, scene, mesh_attributes);
-
- if(progress.get_cancel()) return;
-
- /* copy to device */
- progress.set_status("Updating Mesh", "Copying Attributes to device");
-
- if(dscene->attributes_float.size()) {
- dscene->attributes_float.copy_to_device();
- }
- if(dscene->attributes_float2.size()) {
- dscene->attributes_float2.copy_to_device();
- }
- if(dscene->attributes_float3.size()) {
- dscene->attributes_float3.copy_to_device();
- }
- if(dscene->attributes_uchar4.size()) {
- dscene->attributes_uchar4.copy_to_device();
- }
-
- if(progress.get_cancel()) return;
-
- /* After mesh attributes and patch tables have been copied to device memory,
- * we need to update offsets in the objects. */
- scene->object_manager->device_update_mesh_offsets(device, dscene, scene);
+ TypeDesc &type,
+ AttributeDescriptor &desc)
+{
+ if (mattr) {
+ /* store element and type */
+ desc.element = mattr->element;
+ desc.flags = mattr->flags;
+ type = mattr->type;
+
+ /* store attribute data in arrays */
+ size_t size = mattr->element_size(mesh, prim);
+
+ AttributeElement &element = desc.element;
+ int &offset = desc.offset;
+
+ if (mattr->element == ATTR_ELEMENT_VOXEL) {
+ /* store slot in offset value */
+ VoxelAttribute *voxel_data = mattr->data_voxel();
+ offset = voxel_data->slot;
+ }
+ else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
+ uchar4 *data = mattr->data_uchar4();
+ offset = attr_uchar4_offset;
+
+ assert(attr_uchar4.size() >= offset + size);
+ for (size_t k = 0; k < size; k++) {
+ attr_uchar4[offset + k] = data[k];
+ }
+ attr_uchar4_offset += size;
+ }
+ else if (mattr->type == TypeDesc::TypeFloat) {
+ float *data = mattr->data_float();
+ offset = attr_float_offset;
+
+ assert(attr_float.size() >= offset + size);
+ for (size_t k = 0; k < size; k++) {
+ attr_float[offset + k] = data[k];
+ }
+ attr_float_offset += size;
+ }
+ else if (mattr->type == TypeFloat2) {
+ float2 *data = mattr->data_float2();
+ offset = attr_float2_offset;
+
+ assert(attr_float2.size() >= offset + size);
+ for (size_t k = 0; k < size; k++) {
+ attr_float2[offset + k] = data[k];
+ }
+ attr_float2_offset += size;
+ }
+ else if (mattr->type == TypeDesc::TypeMatrix) {
+ Transform *tfm = mattr->data_transform();
+ offset = attr_float3_offset;
+
+ assert(attr_float3.size() >= offset + size * 3);
+ for (size_t k = 0; k < size * 3; k++) {
+ attr_float3[offset + k] = (&tfm->x)[k];
+ }
+ attr_float3_offset += size * 3;
+ }
+ else {
+ float4 *data = mattr->data_float4();
+ offset = attr_float3_offset;
+
+ assert(attr_float3.size() >= offset + size);
+ for (size_t k = 0; k < size; k++) {
+ attr_float3[offset + k] = data[k];
+ }
+ attr_float3_offset += size;
+ }
+
+ /* mesh vertex/curve index is global, not per object, so we sneak
+ * a correction for that in here */
+ if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK &&
+ desc.flags & ATTR_SUBDIVIDED) {
+ /* indices for subdivided attributes are retrieved
+ * from patch table so no need for correction here*/
+ }
+ else if (element == ATTR_ELEMENT_VERTEX)
+ offset -= mesh->vert_offset;
+ else if (element == ATTR_ELEMENT_VERTEX_MOTION)
+ offset -= mesh->vert_offset;
+ else if (element == ATTR_ELEMENT_FACE) {
+ if (prim == ATTR_PRIM_TRIANGLE)
+ offset -= mesh->tri_offset;
+ else
+ offset -= mesh->face_offset;
+ }
+ else if (element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) {
+ if (prim == ATTR_PRIM_TRIANGLE)
+ offset -= 3 * mesh->tri_offset;
+ else
+ offset -= mesh->corner_offset;
+ }
+ else if (element == ATTR_ELEMENT_CURVE)
+ offset -= mesh->curve_offset;
+ else if (element == ATTR_ELEMENT_CURVE_KEY)
+ offset -= mesh->curvekey_offset;
+ else if (element == ATTR_ELEMENT_CURVE_KEY_MOTION)
+ offset -= mesh->curvekey_offset;
+ }
+ else {
+ /* attribute not found */
+ desc.element = ATTR_ELEMENT_NONE;
+ desc.offset = 0;
+ }
+}
+
+void MeshManager::device_update_attributes(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
+{
+ progress.set_status("Updating Mesh", "Computing attributes");
+
+ /* gather per mesh requested attributes. as meshes may have multiple
+ * shaders assigned, this merges the requested attributes that have
+ * been set per shader by the shader manager */
+ vector<AttributeRequestSet> mesh_attributes(scene->meshes.size());
+
+ for (size_t i = 0; i < scene->meshes.size(); i++) {
+ Mesh *mesh = scene->meshes[i];
+
+ scene->need_global_attributes(mesh_attributes[i]);
+
+ foreach (Shader *shader, mesh->used_shaders) {
+ mesh_attributes[i].add(shader->attributes);
+ }
+ }
+
+ /* mesh attribute are stored in a single array per data type. here we fill
+ * those arrays, and set the offset and element type to create attribute
+ * maps next */
+
+ /* Pre-allocate attributes to avoid arrays re-allocation which would
+ * take 2x of overall attribute memory usage.
+ */
+ size_t attr_float_size = 0;
+ size_t attr_float2_size = 0;
+ size_t attr_float3_size = 0;
+ size_t attr_uchar4_size = 0;
+ for (size_t i = 0; i < scene->meshes.size(); i++) {
+ Mesh *mesh = scene->meshes[i];
+ AttributeRequestSet &attributes = mesh_attributes[i];
+ foreach (AttributeRequest &req, attributes.requests) {
+ Attribute *triangle_mattr = mesh->attributes.find(req);
+ Attribute *curve_mattr = mesh->curve_attributes.find(req);
+ Attribute *subd_mattr = mesh->subd_attributes.find(req);
+
+ update_attribute_element_size(mesh,
+ triangle_mattr,
+ ATTR_PRIM_TRIANGLE,
+ &attr_float_size,
+ &attr_float2_size,
+ &attr_float3_size,
+ &attr_uchar4_size);
+ update_attribute_element_size(mesh,
+ curve_mattr,
+ ATTR_PRIM_CURVE,
+ &attr_float_size,
+ &attr_float2_size,
+ &attr_float3_size,
+ &attr_uchar4_size);
+ update_attribute_element_size(mesh,
+ subd_mattr,
+ ATTR_PRIM_SUBD,
+ &attr_float_size,
+ &attr_float2_size,
+ &attr_float3_size,
+ &attr_uchar4_size);
+ }
+ }
+
+ dscene->attributes_float.alloc(attr_float_size);
+ dscene->attributes_float2.alloc(attr_float2_size);
+ dscene->attributes_float3.alloc(attr_float3_size);
+ dscene->attributes_uchar4.alloc(attr_uchar4_size);
+
+ size_t attr_float_offset = 0;
+ size_t attr_float2_offset = 0;
+ size_t attr_float3_offset = 0;
+ size_t attr_uchar4_offset = 0;
+
+ /* Fill in attributes. */
+ for (size_t i = 0; i < scene->meshes.size(); i++) {
+ Mesh *mesh = scene->meshes[i];
+ AttributeRequestSet &attributes = mesh_attributes[i];
+
+ /* todo: we now store std and name attributes from requests even if
+ * they actually refer to the same mesh attributes, optimize */
+ foreach (AttributeRequest &req, attributes.requests) {
+ Attribute *triangle_mattr = mesh->attributes.find(req);
+ Attribute *curve_mattr = mesh->curve_attributes.find(req);
+ Attribute *subd_mattr = mesh->subd_attributes.find(req);
+
+ update_attribute_element_offset(mesh,
+ dscene->attributes_float,
+ attr_float_offset,
+ dscene->attributes_float2,
+ attr_float2_offset,
+ dscene->attributes_float3,
+ attr_float3_offset,
+ dscene->attributes_uchar4,
+ attr_uchar4_offset,
+ triangle_mattr,
+ ATTR_PRIM_TRIANGLE,
+ req.triangle_type,
+ req.triangle_desc);
+
+ update_attribute_element_offset(mesh,
+ dscene->attributes_float,
+ attr_float_offset,
+ dscene->attributes_float2,
+ attr_float2_offset,
+ dscene->attributes_float3,
+ attr_float3_offset,
+ dscene->attributes_uchar4,
+ attr_uchar4_offset,
+ curve_mattr,
+ ATTR_PRIM_CURVE,
+ req.curve_type,
+ req.curve_desc);
+
+ update_attribute_element_offset(mesh,
+ dscene->attributes_float,
+ attr_float_offset,
+ dscene->attributes_float2,
+ attr_float2_offset,
+ dscene->attributes_float3,
+ attr_float3_offset,
+ dscene->attributes_uchar4,
+ attr_uchar4_offset,
+ subd_mattr,
+ ATTR_PRIM_SUBD,
+ req.subd_type,
+ req.subd_desc);
+
+ if (progress.get_cancel())
+ return;
+ }
+ }
+
+ /* create attribute lookup maps */
+ if (scene->shader_manager->use_osl())
+ update_osl_attributes(device, scene, mesh_attributes);
+
+ update_svm_attributes(device, dscene, scene, mesh_attributes);
+
+ if (progress.get_cancel())
+ return;
+
+ /* copy to device */
+ progress.set_status("Updating Mesh", "Copying Attributes to device");
+
+ if (dscene->attributes_float.size()) {
+ dscene->attributes_float.copy_to_device();
+ }
+ if (dscene->attributes_float2.size()) {
+ dscene->attributes_float2.copy_to_device();
+ }
+ if (dscene->attributes_float3.size()) {
+ dscene->attributes_float3.copy_to_device();
+ }
+ if (dscene->attributes_uchar4.size()) {
+ dscene->attributes_uchar4.copy_to_device();
+ }
+
+ if (progress.get_cancel())
+ return;
+
+ /* After mesh attributes and patch tables have been copied to device memory,
+ * we need to update offsets in the objects. */
+ scene->object_manager->device_update_mesh_offsets(device, dscene, scene);
}
void MeshManager::mesh_calc_offset(Scene *scene)
{
- size_t vert_size = 0;
- size_t tri_size = 0;
-
- size_t curve_key_size = 0;
- size_t curve_size = 0;
-
- size_t patch_size = 0;
- size_t face_size = 0;
- size_t corner_size = 0;
-
- foreach(Mesh *mesh, scene->meshes) {
- mesh->vert_offset = vert_size;
- mesh->tri_offset = tri_size;
-
- mesh->curvekey_offset = curve_key_size;
- mesh->curve_offset = curve_size;
-
- mesh->patch_offset = patch_size;
- mesh->face_offset = face_size;
- mesh->corner_offset = corner_size;
-
- vert_size += mesh->verts.size();
- tri_size += mesh->num_triangles();
-
- curve_key_size += mesh->curve_keys.size();
- curve_size += mesh->num_curves();
-
- if(mesh->subd_faces.size()) {
- Mesh::SubdFace& last = mesh->subd_faces[mesh->subd_faces.size()-1];
- patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
-
- /* patch tables are stored in same array so include them in patch_size */
- if(mesh->patch_table) {
- mesh->patch_table_offset = patch_size;
- patch_size += mesh->patch_table->total_size();
- }
- }
- face_size += mesh->subd_faces.size();
- corner_size += mesh->subd_face_corners.size();
- }
-}
-
-void MeshManager::device_update_mesh(Device *,
- DeviceScene *dscene,
- Scene *scene,
- bool for_displacement,
- Progress& progress)
-{
- /* Count. */
- size_t vert_size = 0;
- size_t tri_size = 0;
-
- size_t curve_key_size = 0;
- size_t curve_size = 0;
-
- size_t patch_size = 0;
-
- foreach(Mesh *mesh, scene->meshes) {
- vert_size += mesh->verts.size();
- tri_size += mesh->num_triangles();
-
- curve_key_size += mesh->curve_keys.size();
- curve_size += mesh->num_curves();
-
- if(mesh->subd_faces.size()) {
- Mesh::SubdFace& last = mesh->subd_faces[mesh->subd_faces.size()-1];
- patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
-
- /* patch tables are stored in same array so include them in patch_size */
- if(mesh->patch_table) {
- mesh->patch_table_offset = patch_size;
- patch_size += mesh->patch_table->total_size();
- }
- }
- }
-
- /* Create mapping from triangle to primitive triangle array. */
- vector<uint> tri_prim_index(tri_size);
- if(for_displacement) {
- /* For displacement kernels we do some trickery to make them believe
- * we've got all required data ready. However, that data is different
- * from final render kernels since we don't have BVH yet, so can't
- * really use same semantic of arrays.
- */
- foreach(Mesh *mesh, scene->meshes) {
- for(size_t i = 0; i < mesh->num_triangles(); ++i) {
- tri_prim_index[i + mesh->tri_offset] = 3 * (i + mesh->tri_offset);
- }
- }
- }
- else {
- for(size_t i = 0; i < dscene->prim_index.size(); ++i) {
- if((dscene->prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
- tri_prim_index[dscene->prim_index[i]] = dscene->prim_tri_index[i];
- }
- }
- }
-
- /* Fill in all the arrays. */
- if(tri_size != 0) {
- /* normals */
- progress.set_status("Updating Mesh", "Computing normals");
-
- uint *tri_shader = dscene->tri_shader.alloc(tri_size);
- float4 *vnormal = dscene->tri_vnormal.alloc(vert_size);
- uint4 *tri_vindex = dscene->tri_vindex.alloc(tri_size);
- uint *tri_patch = dscene->tri_patch.alloc(tri_size);
- float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
-
- foreach(Mesh *mesh, scene->meshes) {
- mesh->pack_shaders(scene,
- &tri_shader[mesh->tri_offset]);
- mesh->pack_normals(&vnormal[mesh->vert_offset]);
- mesh->pack_verts(tri_prim_index,
- &tri_vindex[mesh->tri_offset],
- &tri_patch[mesh->tri_offset],
- &tri_patch_uv[mesh->vert_offset],
- mesh->vert_offset,
- mesh->tri_offset);
- if(progress.get_cancel()) return;
- }
-
- /* vertex coordinates */
- progress.set_status("Updating Mesh", "Copying Mesh to device");
-
- dscene->tri_shader.copy_to_device();
- dscene->tri_vnormal.copy_to_device();
- dscene->tri_vindex.copy_to_device();
- dscene->tri_patch.copy_to_device();
- dscene->tri_patch_uv.copy_to_device();
- }
-
- if(curve_size != 0) {
- progress.set_status("Updating Mesh", "Copying Strands to device");
-
- float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
- float4 *curves = dscene->curves.alloc(curve_size);
-
- foreach(Mesh *mesh, scene->meshes) {
- mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset);
- if(progress.get_cancel()) return;
- }
-
- dscene->curve_keys.copy_to_device();
- dscene->curves.copy_to_device();
- }
-
- if(patch_size != 0) {
- progress.set_status("Updating Mesh", "Copying Patches to device");
-
- uint *patch_data = dscene->patches.alloc(patch_size);
-
- foreach(Mesh *mesh, scene->meshes) {
- mesh->pack_patches(&patch_data[mesh->patch_offset], mesh->vert_offset, mesh->face_offset, mesh->corner_offset);
-
- if(mesh->patch_table) {
- mesh->patch_table->copy_adjusting_offsets(&patch_data[mesh->patch_table_offset], mesh->patch_table_offset);
- }
-
- if(progress.get_cancel()) return;
- }
-
- dscene->patches.copy_to_device();
- }
-
- if(for_displacement) {
- float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3);
- foreach(Mesh *mesh, scene->meshes) {
- for(size_t i = 0; i < mesh->num_triangles(); ++i) {
- Mesh::Triangle t = mesh->get_triangle(i);
- size_t offset = 3 * (i + mesh->tri_offset);
- prim_tri_verts[offset + 0] = float3_to_float4(mesh->verts[t.v[0]]);
- prim_tri_verts[offset + 1] = float3_to_float4(mesh->verts[t.v[1]]);
- prim_tri_verts[offset + 2] = float3_to_float4(mesh->verts[t.v[2]]);
- }
- }
- dscene->prim_tri_verts.copy_to_device();
- }
-}
-
-void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
-{
- /* bvh build */
- progress.set_status("Updating Scene BVH", "Building");
-
- BVHParams bparams;
- bparams.top_level = true;
- bparams.bvh_layout = BVHParams::best_bvh_layout(
- scene->params.bvh_layout,
- device->get_bvh_layout_mask());
- bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
- bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
- scene->params.use_bvh_unaligned_nodes;
- bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps;
- bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps;
- bparams.bvh_type = scene->params.bvh_type;
- bparams.curve_flags = dscene->data.curve.curveflags;
- bparams.curve_subdivisions = dscene->data.curve.subdivisions;
-
- VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout)
- << " layout.";
+ size_t vert_size = 0;
+ size_t tri_size = 0;
+
+ size_t curve_key_size = 0;
+ size_t curve_size = 0;
+
+ size_t patch_size = 0;
+ size_t face_size = 0;
+ size_t corner_size = 0;
+
+ foreach (Mesh *mesh, scene->meshes) {
+ mesh->vert_offset = vert_size;
+ mesh->tri_offset = tri_size;
+
+ mesh->curvekey_offset = curve_key_size;
+ mesh->curve_offset = curve_size;
+
+ mesh->patch_offset = patch_size;
+ mesh->face_offset = face_size;
+ mesh->corner_offset = corner_size;
+
+ vert_size += mesh->verts.size();
+ tri_size += mesh->num_triangles();
+
+ curve_key_size += mesh->curve_keys.size();
+ curve_size += mesh->num_curves();
+
+ if (mesh->subd_faces.size()) {
+ Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1];
+ patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
+
+ /* patch tables are stored in same array so include them in patch_size */
+ if (mesh->patch_table) {
+ mesh->patch_table_offset = patch_size;
+ patch_size += mesh->patch_table->total_size();
+ }
+ }
+ face_size += mesh->subd_faces.size();
+ corner_size += mesh->subd_face_corners.size();
+ }
+}
+
+void MeshManager::device_update_mesh(
+ Device *, DeviceScene *dscene, Scene *scene, bool for_displacement, Progress &progress)
+{
+ /* Count. */
+ size_t vert_size = 0;
+ size_t tri_size = 0;
+
+ size_t curve_key_size = 0;
+ size_t curve_size = 0;
+
+ size_t patch_size = 0;
+
+ foreach (Mesh *mesh, scene->meshes) {
+ vert_size += mesh->verts.size();
+ tri_size += mesh->num_triangles();
+
+ curve_key_size += mesh->curve_keys.size();
+ curve_size += mesh->num_curves();
+
+ if (mesh->subd_faces.size()) {
+ Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1];
+ patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
+
+ /* patch tables are stored in same array so include them in patch_size */
+ if (mesh->patch_table) {
+ mesh->patch_table_offset = patch_size;
+ patch_size += mesh->patch_table->total_size();
+ }
+ }
+ }
+
+ /* Create mapping from triangle to primitive triangle array. */
+ vector<uint> tri_prim_index(tri_size);
+ if (for_displacement) {
+ /* For displacement kernels we do some trickery to make them believe
+ * we've got all required data ready. However, that data is different
+ * from final render kernels since we don't have BVH yet, so can't
+ * really use same semantic of arrays.
+ */
+ foreach (Mesh *mesh, scene->meshes) {
+ for (size_t i = 0; i < mesh->num_triangles(); ++i) {
+ tri_prim_index[i + mesh->tri_offset] = 3 * (i + mesh->tri_offset);
+ }
+ }
+ }
+ else {
+ for (size_t i = 0; i < dscene->prim_index.size(); ++i) {
+ if ((dscene->prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
+ tri_prim_index[dscene->prim_index[i]] = dscene->prim_tri_index[i];
+ }
+ }
+ }
+
+ /* Fill in all the arrays. */
+ if (tri_size != 0) {
+ /* normals */
+ progress.set_status("Updating Mesh", "Computing normals");
+
+ uint *tri_shader = dscene->tri_shader.alloc(tri_size);
+ float4 *vnormal = dscene->tri_vnormal.alloc(vert_size);
+ uint4 *tri_vindex = dscene->tri_vindex.alloc(tri_size);
+ uint *tri_patch = dscene->tri_patch.alloc(tri_size);
+ float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
+
+ foreach (Mesh *mesh, scene->meshes) {
+ mesh->pack_shaders(scene, &tri_shader[mesh->tri_offset]);
+ mesh->pack_normals(&vnormal[mesh->vert_offset]);
+ mesh->pack_verts(tri_prim_index,
+ &tri_vindex[mesh->tri_offset],
+ &tri_patch[mesh->tri_offset],
+ &tri_patch_uv[mesh->vert_offset],
+ mesh->vert_offset,
+ mesh->tri_offset);
+ if (progress.get_cancel())
+ return;
+ }
+
+ /* vertex coordinates */
+ progress.set_status("Updating Mesh", "Copying Mesh to device");
+
+ dscene->tri_shader.copy_to_device();
+ dscene->tri_vnormal.copy_to_device();
+ dscene->tri_vindex.copy_to_device();
+ dscene->tri_patch.copy_to_device();
+ dscene->tri_patch_uv.copy_to_device();
+ }
+
+ if (curve_size != 0) {
+ progress.set_status("Updating Mesh", "Copying Strands to device");
+
+ float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
+ float4 *curves = dscene->curves.alloc(curve_size);
+
+ foreach (Mesh *mesh, scene->meshes) {
+ mesh->pack_curves(scene,
+ &curve_keys[mesh->curvekey_offset],
+ &curves[mesh->curve_offset],
+ mesh->curvekey_offset);
+ if (progress.get_cancel())
+ return;
+ }
+
+ dscene->curve_keys.copy_to_device();
+ dscene->curves.copy_to_device();
+ }
+
+ if (patch_size != 0) {
+ progress.set_status("Updating Mesh", "Copying Patches to device");
+
+ uint *patch_data = dscene->patches.alloc(patch_size);
+
+ foreach (Mesh *mesh, scene->meshes) {
+ mesh->pack_patches(&patch_data[mesh->patch_offset],
+ mesh->vert_offset,
+ mesh->face_offset,
+ mesh->corner_offset);
+
+ if (mesh->patch_table) {
+ mesh->patch_table->copy_adjusting_offsets(&patch_data[mesh->patch_table_offset],
+ mesh->patch_table_offset);
+ }
+
+ if (progress.get_cancel())
+ return;
+ }
+
+ dscene->patches.copy_to_device();
+ }
+
+ if (for_displacement) {
+ float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3);
+ foreach (Mesh *mesh, scene->meshes) {
+ for (size_t i = 0; i < mesh->num_triangles(); ++i) {
+ Mesh::Triangle t = mesh->get_triangle(i);
+ size_t offset = 3 * (i + mesh->tri_offset);
+ prim_tri_verts[offset + 0] = float3_to_float4(mesh->verts[t.v[0]]);
+ prim_tri_verts[offset + 1] = float3_to_float4(mesh->verts[t.v[1]]);
+ prim_tri_verts[offset + 2] = float3_to_float4(mesh->verts[t.v[2]]);
+ }
+ }
+ dscene->prim_tri_verts.copy_to_device();
+ }
+}
+
+void MeshManager::device_update_bvh(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
+{
+ /* bvh build */
+ progress.set_status("Updating Scene BVH", "Building");
+
+ BVHParams bparams;
+ bparams.top_level = true;
+ bparams.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
+ device->get_bvh_layout_mask());
+ bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
+ bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
+ scene->params.use_bvh_unaligned_nodes;
+ bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps;
+ bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps;
+ bparams.bvh_type = scene->params.bvh_type;
+ bparams.curve_flags = dscene->data.curve.curveflags;
+ bparams.curve_subdivisions = dscene->data.curve.subdivisions;
+
+ VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
#ifdef WITH_EMBREE
- if(bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
- if(dscene->data.bvh.scene) {
- BVHEmbree::destroy(dscene->data.bvh.scene);
- }
- }
+ if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
+ if (dscene->data.bvh.scene) {
+ BVHEmbree::destroy(dscene->data.bvh.scene);
+ }
+ }
#endif
- BVH *bvh = BVH::create(bparams, scene->objects);
- bvh->build(progress, &device->stats);
+ BVH *bvh = BVH::create(bparams, scene->objects);
+ bvh->build(progress, &device->stats);
- if(progress.get_cancel()) {
+ if (progress.get_cancel()) {
#ifdef WITH_EMBREE
- if(bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
- if(dscene->data.bvh.scene) {
- BVHEmbree::destroy(dscene->data.bvh.scene);
- }
- }
+ if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
+ if (dscene->data.bvh.scene) {
+ BVHEmbree::destroy(dscene->data.bvh.scene);
+ }
+ }
#endif
- delete bvh;
- return;
- }
-
- /* copy to device */
- progress.set_status("Updating Scene BVH", "Copying BVH to device");
-
- PackedBVH& pack = bvh->pack;
-
- if(pack.nodes.size()) {
- dscene->bvh_nodes.steal_data(pack.nodes);
- dscene->bvh_nodes.copy_to_device();
- }
- if(pack.leaf_nodes.size()) {
- dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes);
- dscene->bvh_leaf_nodes.copy_to_device();
- }
- if(pack.object_node.size()) {
- dscene->object_node.steal_data(pack.object_node);
- dscene->object_node.copy_to_device();
- }
- if(pack.prim_tri_index.size()) {
- dscene->prim_tri_index.steal_data(pack.prim_tri_index);
- dscene->prim_tri_index.copy_to_device();
- }
- if(pack.prim_tri_verts.size()) {
- dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
- dscene->prim_tri_verts.copy_to_device();
- }
- if(pack.prim_type.size()) {
- dscene->prim_type.steal_data(pack.prim_type);
- dscene->prim_type.copy_to_device();
- }
- if(pack.prim_visibility.size()) {
- dscene->prim_visibility.steal_data(pack.prim_visibility);
- dscene->prim_visibility.copy_to_device();
- }
- if(pack.prim_index.size()) {
- dscene->prim_index.steal_data(pack.prim_index);
- dscene->prim_index.copy_to_device();
- }
- if(pack.prim_object.size()) {
- dscene->prim_object.steal_data(pack.prim_object);
- dscene->prim_object.copy_to_device();
- }
- if(pack.prim_time.size()) {
- dscene->prim_time.steal_data(pack.prim_time);
- dscene->prim_time.copy_to_device();
- }
-
- dscene->data.bvh.root = pack.root_index;
- dscene->data.bvh.bvh_layout = bparams.bvh_layout;
- dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
-
+ delete bvh;
+ return;
+ }
+
+ /* copy to device */
+ progress.set_status("Updating Scene BVH", "Copying BVH to device");
+
+ PackedBVH &pack = bvh->pack;
+
+ if (pack.nodes.size()) {
+ dscene->bvh_nodes.steal_data(pack.nodes);
+ dscene->bvh_nodes.copy_to_device();
+ }
+ if (pack.leaf_nodes.size()) {
+ dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes);
+ dscene->bvh_leaf_nodes.copy_to_device();
+ }
+ if (pack.object_node.size()) {
+ dscene->object_node.steal_data(pack.object_node);
+ dscene->object_node.copy_to_device();
+ }
+ if (pack.prim_tri_index.size()) {
+ dscene->prim_tri_index.steal_data(pack.prim_tri_index);
+ dscene->prim_tri_index.copy_to_device();
+ }
+ if (pack.prim_tri_verts.size()) {
+ dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
+ dscene->prim_tri_verts.copy_to_device();
+ }
+ if (pack.prim_type.size()) {
+ dscene->prim_type.steal_data(pack.prim_type);
+ dscene->prim_type.copy_to_device();
+ }
+ if (pack.prim_visibility.size()) {
+ dscene->prim_visibility.steal_data(pack.prim_visibility);
+ dscene->prim_visibility.copy_to_device();
+ }
+ if (pack.prim_index.size()) {
+ dscene->prim_index.steal_data(pack.prim_index);
+ dscene->prim_index.copy_to_device();
+ }
+ if (pack.prim_object.size()) {
+ dscene->prim_object.steal_data(pack.prim_object);
+ dscene->prim_object.copy_to_device();
+ }
+ if (pack.prim_time.size()) {
+ dscene->prim_time.steal_data(pack.prim_time);
+ dscene->prim_time.copy_to_device();
+ }
+
+ dscene->data.bvh.root = pack.root_index;
+ dscene->data.bvh.bvh_layout = bparams.bvh_layout;
+ dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
#ifdef WITH_EMBREE
- if(bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
- dscene->data.bvh.scene = ((BVHEmbree*)bvh)->scene;
- }
- else {
- dscene->data.bvh.scene = NULL;
- }
+ if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
+ dscene->data.bvh.scene = ((BVHEmbree *)bvh)->scene;
+ }
+ else {
+ dscene->data.bvh.scene = NULL;
+ }
#endif
- delete bvh;
+ delete bvh;
}
-void MeshManager::device_update_preprocess(Device *device,
- Scene *scene,
- Progress& progress)
+void MeshManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
{
- if(!need_update && !need_flags_update) {
- return;
- }
+ if (!need_update && !need_flags_update) {
+ return;
+ }
- progress.set_status("Updating Meshes Flags");
+ progress.set_status("Updating Meshes Flags");
- /* Update flags. */
- bool volume_images_updated = false;
+ /* Update flags. */
+ bool volume_images_updated = false;
- foreach(Mesh *mesh, scene->meshes) {
- mesh->has_volume = false;
+ foreach (Mesh *mesh, scene->meshes) {
+ mesh->has_volume = false;
- foreach(const Shader *shader, mesh->used_shaders) {
- if(shader->has_volume) {
- mesh->has_volume = true;
- }
- if(shader->has_surface_bssrdf) {
- mesh->has_surface_bssrdf = true;
- }
- }
+ foreach (const Shader *shader, mesh->used_shaders) {
+ if (shader->has_volume) {
+ mesh->has_volume = true;
+ }
+ if (shader->has_surface_bssrdf) {
+ mesh->has_surface_bssrdf = true;
+ }
+ }
- if(need_update && mesh->has_volume) {
- /* Create volume meshes if there is voxel data. */
- bool has_voxel_attributes = false;
+ if (need_update && mesh->has_volume) {
+ /* Create volume meshes if there is voxel data. */
+ bool has_voxel_attributes = false;
- foreach(Attribute& attr, mesh->attributes.attributes) {
- if(attr.element == ATTR_ELEMENT_VOXEL) {
- has_voxel_attributes = true;
- }
- }
+ foreach (Attribute &attr, mesh->attributes.attributes) {
+ if (attr.element == ATTR_ELEMENT_VOXEL) {
+ has_voxel_attributes = true;
+ }
+ }
- if(has_voxel_attributes) {
- if(!volume_images_updated) {
- progress.set_status("Updating Meshes Volume Bounds");
- device_update_volume_images(device, scene, progress);
- volume_images_updated = true;
- }
+ if (has_voxel_attributes) {
+ if (!volume_images_updated) {
+ progress.set_status("Updating Meshes Volume Bounds");
+ device_update_volume_images(device, scene, progress);
+ volume_images_updated = true;
+ }
- create_volume_mesh(scene, mesh, progress);
- }
- }
- }
+ create_volume_mesh(scene, mesh, progress);
+ }
+ }
+ }
- need_flags_update = false;
+ need_flags_update = false;
}
void MeshManager::device_update_displacement_images(Device *device,
Scene *scene,
- Progress& progress)
-{
- progress.set_status("Updating Displacement Images");
- TaskPool pool;
- ImageManager *image_manager = scene->image_manager;
- set<int> bump_images;
- foreach(Mesh *mesh, scene->meshes) {
- if(mesh->need_update) {
- foreach(Shader *shader, mesh->used_shaders) {
- if(!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
- continue;
- }
- foreach(ShaderNode* node, shader->graph->nodes) {
- if(node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
- continue;
- }
-
- ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode*>(node);
- int slot = image_node->slot;
- if(slot != -1) {
- bump_images.insert(slot);
- }
- }
- }
- }
- }
- foreach(int slot, bump_images) {
- pool.push(function_bind(&ImageManager::device_update_slot,
- image_manager,
- device,
- scene,
- slot,
- &progress));
- }
- pool.wait_work();
-}
-
-void MeshManager::device_update_volume_images(Device *device,
- Scene *scene,
- Progress& progress)
-{
- progress.set_status("Updating Volume Images");
- TaskPool pool;
- ImageManager *image_manager = scene->image_manager;
- set<int> volume_images;
-
- foreach(Mesh *mesh, scene->meshes) {
- if(!mesh->need_update) {
- continue;
- }
-
- foreach(Attribute& attr, mesh->attributes.attributes) {
- if(attr.element != ATTR_ELEMENT_VOXEL) {
- continue;
- }
-
- VoxelAttribute *voxel = attr.data_voxel();
-
- if(voxel->slot != -1) {
- volume_images.insert(voxel->slot);
- }
- }
- }
-
- foreach(int slot, volume_images) {
- pool.push(function_bind(&ImageManager::device_update_slot,
- image_manager,
- device,
- scene,
- slot,
- &progress));
- }
- pool.wait_work();
-}
-
-void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
-{
- if(!need_update)
- return;
-
- VLOG(1) << "Total " << scene->meshes.size() << " meshes.";
-
- bool true_displacement_used = false;
- size_t total_tess_needed = 0;
-
- foreach(Mesh *mesh, scene->meshes) {
- foreach(Shader *shader, mesh->used_shaders) {
- if(shader->need_update_mesh)
- mesh->need_update = true;
- }
-
- if(mesh->need_update) {
- /* Update normals. */
- mesh->add_face_normals();
- mesh->add_vertex_normals();
-
- if(mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) {
- mesh->add_undisplaced();
- }
-
- /* Test if we need tessellation. */
- if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE &&
- mesh->num_subd_verts == 0 &&
- mesh->subd_params)
- {
- total_tess_needed++;
- }
-
- /* Test if we need displacement. */
- if(mesh->has_true_displacement()) {
- true_displacement_used = true;
- }
-
- if(progress.get_cancel()) return;
- }
- }
-
- /* Tessellate meshes that are using subdivision */
- if(total_tess_needed) {
- Camera *dicing_camera = scene->dicing_camera;
- dicing_camera->update(scene);
-
- size_t i = 0;
- foreach(Mesh *mesh, scene->meshes) {
- if(mesh->need_update &&
- mesh->subdivision_type != Mesh::SUBDIVISION_NONE &&
- mesh->num_subd_verts == 0 &&
- mesh->subd_params)
- {
- string msg = "Tessellating ";
- if(mesh->name == "")
- msg += string_printf("%u/%u", (uint)(i+1), (uint)total_tess_needed);
- else
- msg += string_printf("%s %u/%u", mesh->name.c_str(), (uint)(i+1), (uint)total_tess_needed);
-
- progress.set_status("Updating Mesh", msg);
-
- mesh->subd_params->camera = dicing_camera;
- DiagSplit dsplit(*mesh->subd_params);
- mesh->tessellate(&dsplit);
-
- i++;
-
- if(progress.get_cancel()) return;
- }
-
- }
- }
-
- /* Update images needed for true displacement. */
- bool old_need_object_flags_update = false;
- if(true_displacement_used) {
- VLOG(1) << "Updating images used for true displacement.";
- device_update_displacement_images(device, scene, progress);
- old_need_object_flags_update = scene->object_manager->need_flags_update;
- scene->object_manager->device_update_flags(device,
- dscene,
- scene,
- progress,
- false);
- }
-
- /* Device update. */
- device_free(device, dscene);
-
- mesh_calc_offset(scene);
- if(true_displacement_used) {
- device_update_mesh(device, dscene, scene, true, progress);
- }
- if(progress.get_cancel()) return;
-
- device_update_attributes(device, dscene, scene, progress);
- if(progress.get_cancel()) return;
-
- /* Update displacement. */
- bool displacement_done = false;
- size_t num_bvh = 0;
-
- foreach(Mesh *mesh, scene->meshes) {
- if(mesh->need_update) {
- if(displace(device, dscene, scene, mesh, progress)) {
- displacement_done = true;
- }
-
- if(mesh->need_build_bvh()) {
- num_bvh++;
- }
- }
-
- if(progress.get_cancel()) return;
- }
-
- /* Device re-update after displacement. */
- if(displacement_done) {
- device_free(device, dscene);
-
- device_update_attributes(device, dscene, scene, progress);
- if(progress.get_cancel()) return;
- }
-
- TaskPool pool;
-
- size_t i = 0;
- foreach(Mesh *mesh, scene->meshes) {
- if(mesh->need_update) {
- pool.push(function_bind(&Mesh::compute_bvh,
- mesh,
- device,
- dscene,
- &scene->params,
- &progress,
- i,
- num_bvh));
- if(mesh->need_build_bvh()) {
- i++;
- }
- }
- }
-
- TaskPool::Summary summary;
- pool.wait_work(&summary);
- VLOG(2) << "Objects BVH build pool statistics:\n"
- << summary.full_report();
-
- foreach(Shader *shader, scene->shaders) {
- shader->need_update_mesh = false;
- }
-
- Scene::MotionType need_motion = scene->need_motion();
- bool motion_blur = need_motion == Scene::MOTION_BLUR;
-
- /* Update objects. */
- vector<Object *> volume_objects;
- foreach(Object *object, scene->objects) {
- object->compute_bounds(motion_blur);
- }
-
- if(progress.get_cancel()) return;
-
- device_update_bvh(device, dscene, scene, progress);
- if(progress.get_cancel()) return;
-
- device_update_mesh(device, dscene, scene, false, progress);
- if(progress.get_cancel()) return;
-
- need_update = false;
-
- if(true_displacement_used) {
- /* Re-tag flags for update, so they're re-evaluated
- * for meshes with correct bounding boxes.
- *
- * This wouldn't cause wrong results, just true
- * displacement might be less optimal ot calculate.
- */
- scene->object_manager->need_flags_update = old_need_object_flags_update;
- }
+ Progress &progress)
+{
+ progress.set_status("Updating Displacement Images");
+ TaskPool pool;
+ ImageManager *image_manager = scene->image_manager;
+ set<int> bump_images;
+ foreach (Mesh *mesh, scene->meshes) {
+ if (mesh->need_update) {
+ foreach (Shader *shader, mesh->used_shaders) {
+ if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
+ continue;
+ }
+ foreach (ShaderNode *node, shader->graph->nodes) {
+ if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
+ continue;
+ }
+
+ ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode *>(node);
+ int slot = image_node->slot;
+ if (slot != -1) {
+ bump_images.insert(slot);
+ }
+ }
+ }
+ }
+ }
+ foreach (int slot, bump_images) {
+ pool.push(function_bind(
+ &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
+ }
+ pool.wait_work();
+}
+
+void MeshManager::device_update_volume_images(Device *device, Scene *scene, Progress &progress)
+{
+ progress.set_status("Updating Volume Images");
+ TaskPool pool;
+ ImageManager *image_manager = scene->image_manager;
+ set<int> volume_images;
+
+ foreach (Mesh *mesh, scene->meshes) {
+ if (!mesh->need_update) {
+ continue;
+ }
+
+ foreach (Attribute &attr, mesh->attributes.attributes) {
+ if (attr.element != ATTR_ELEMENT_VOXEL) {
+ continue;
+ }
+
+ VoxelAttribute *voxel = attr.data_voxel();
+
+ if (voxel->slot != -1) {
+ volume_images.insert(voxel->slot);
+ }
+ }
+ }
+
+ foreach (int slot, volume_images) {
+ pool.push(function_bind(
+ &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
+ }
+ pool.wait_work();
+}
+
+void MeshManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
+{
+ if (!need_update)
+ return;
+
+ VLOG(1) << "Total " << scene->meshes.size() << " meshes.";
+
+ bool true_displacement_used = false;
+ size_t total_tess_needed = 0;
+
+ foreach (Mesh *mesh, scene->meshes) {
+ foreach (Shader *shader, mesh->used_shaders) {
+ if (shader->need_update_mesh)
+ mesh->need_update = true;
+ }
+
+ if (mesh->need_update) {
+ /* Update normals. */
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+
+ if (mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) {
+ mesh->add_undisplaced();
+ }
+
+ /* Test if we need tessellation. */
+ if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 &&
+ mesh->subd_params) {
+ total_tess_needed++;
+ }
+
+ /* Test if we need displacement. */
+ if (mesh->has_true_displacement()) {
+ true_displacement_used = true;
+ }
+
+ if (progress.get_cancel())
+ return;
+ }
+ }
+
+ /* Tessellate meshes that are using subdivision */
+ if (total_tess_needed) {
+ Camera *dicing_camera = scene->dicing_camera;
+ dicing_camera->update(scene);
+
+ size_t i = 0;
+ foreach (Mesh *mesh, scene->meshes) {
+ if (mesh->need_update && mesh->subdivision_type != Mesh::SUBDIVISION_NONE &&
+ mesh->num_subd_verts == 0 && mesh->subd_params) {
+ string msg = "Tessellating ";
+ if (mesh->name == "")
+ msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed);
+ else
+ msg += string_printf(
+ "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed);
+
+ progress.set_status("Updating Mesh", msg);
+
+ mesh->subd_params->camera = dicing_camera;
+ DiagSplit dsplit(*mesh->subd_params);
+ mesh->tessellate(&dsplit);
+
+ i++;
+
+ if (progress.get_cancel())
+ return;
+ }
+ }
+ }
+
+ /* Update images needed for true displacement. */
+ bool old_need_object_flags_update = false;
+ if (true_displacement_used) {
+ VLOG(1) << "Updating images used for true displacement.";
+ device_update_displacement_images(device, scene, progress);
+ old_need_object_flags_update = scene->object_manager->need_flags_update;
+ scene->object_manager->device_update_flags(device, dscene, scene, progress, false);
+ }
+
+ /* Device update. */
+ device_free(device, dscene);
+
+ mesh_calc_offset(scene);
+ if (true_displacement_used) {
+ device_update_mesh(device, dscene, scene, true, progress);
+ }
+ if (progress.get_cancel())
+ return;
+
+ device_update_attributes(device, dscene, scene, progress);
+ if (progress.get_cancel())
+ return;
+
+ /* Update displacement. */
+ bool displacement_done = false;
+ size_t num_bvh = 0;
+
+ foreach (Mesh *mesh, scene->meshes) {
+ if (mesh->need_update) {
+ if (displace(device, dscene, scene, mesh, progress)) {
+ displacement_done = true;
+ }
+
+ if (mesh->need_build_bvh()) {
+ num_bvh++;
+ }
+ }
+
+ if (progress.get_cancel())
+ return;
+ }
+
+ /* Device re-update after displacement. */
+ if (displacement_done) {
+ device_free(device, dscene);
+
+ device_update_attributes(device, dscene, scene, progress);
+ if (progress.get_cancel())
+ return;
+ }
+
+ TaskPool pool;
+
+ size_t i = 0;
+ foreach (Mesh *mesh, scene->meshes) {
+ if (mesh->need_update) {
+ pool.push(function_bind(
+ &Mesh::compute_bvh, mesh, device, dscene, &scene->params, &progress, i, num_bvh));
+ if (mesh->need_build_bvh()) {
+ i++;
+ }
+ }
+ }
+
+ TaskPool::Summary summary;
+ pool.wait_work(&summary);
+ VLOG(2) << "Objects BVH build pool statistics:\n" << summary.full_report();
+
+ foreach (Shader *shader, scene->shaders) {
+ shader->need_update_mesh = false;
+ }
+
+ Scene::MotionType need_motion = scene->need_motion();
+ bool motion_blur = need_motion == Scene::MOTION_BLUR;
+
+ /* Update objects. */
+ vector<Object *> volume_objects;
+ foreach (Object *object, scene->objects) {
+ object->compute_bounds(motion_blur);
+ }
+
+ if (progress.get_cancel())
+ return;
+
+ device_update_bvh(device, dscene, scene, progress);
+ if (progress.get_cancel())
+ return;
+
+ device_update_mesh(device, dscene, scene, false, progress);
+ if (progress.get_cancel())
+ return;
+
+ need_update = false;
+
+ if (true_displacement_used) {
+ /* Re-tag flags for update, so they're re-evaluated
+ * for meshes with correct bounding boxes.
+ *
+ * This wouldn't cause wrong results, just true
+ * displacement might be less optimal ot calculate.
+ */
+ scene->object_manager->need_flags_update = old_need_object_flags_update;
+ }
}
void MeshManager::device_free(Device *device, DeviceScene *dscene)
{
- dscene->bvh_nodes.free();
- dscene->bvh_leaf_nodes.free();
- dscene->object_node.free();
- dscene->prim_tri_verts.free();
- dscene->prim_tri_index.free();
- dscene->prim_type.free();
- dscene->prim_visibility.free();
- dscene->prim_index.free();
- dscene->prim_object.free();
- dscene->prim_time.free();
- dscene->tri_shader.free();
- dscene->tri_vnormal.free();
- dscene->tri_vindex.free();
- dscene->tri_patch.free();
- dscene->tri_patch_uv.free();
- dscene->curves.free();
- dscene->curve_keys.free();
- dscene->patches.free();
- dscene->attributes_map.free();
- dscene->attributes_float.free();
- dscene->attributes_float2.free();
- dscene->attributes_float3.free();
- dscene->attributes_uchar4.free();
+ dscene->bvh_nodes.free();
+ dscene->bvh_leaf_nodes.free();
+ dscene->object_node.free();
+ dscene->prim_tri_verts.free();
+ dscene->prim_tri_index.free();
+ dscene->prim_type.free();
+ dscene->prim_visibility.free();
+ dscene->prim_index.free();
+ dscene->prim_object.free();
+ dscene->prim_time.free();
+ dscene->tri_shader.free();
+ dscene->tri_vnormal.free();
+ dscene->tri_vindex.free();
+ dscene->tri_patch.free();
+ dscene->tri_patch_uv.free();
+ dscene->curves.free();
+ dscene->curve_keys.free();
+ dscene->patches.free();
+ dscene->attributes_map.free();
+ dscene->attributes_float.free();
+ dscene->attributes_float2.free();
+ dscene->attributes_float3.free();
+ dscene->attributes_uchar4.free();
#ifdef WITH_OSL
- OSLGlobals *og = (OSLGlobals*)device->osl_memory();
+ OSLGlobals *og = (OSLGlobals *)device->osl_memory();
- if(og) {
- og->object_name_map.clear();
- og->attribute_map.clear();
- og->object_names.clear();
- }
+ if (og) {
+ og->object_name_map.clear();
+ og->attribute_map.clear();
+ og->object_names.clear();
+ }
#else
- (void) device;
+ (void)device;
#endif
}
void MeshManager::tag_update(Scene *scene)
{
- need_update = true;
- scene->object_manager->need_update = true;
+ need_update = true;
+ scene->object_manager->need_update = true;
}
void MeshManager::collect_statistics(const Scene *scene, RenderStats *stats)
{
- foreach(Mesh *mesh, scene->meshes) {
- stats->mesh.geometry.add_entry(
- NamedSizeEntry(string(mesh->name.c_str()),
- mesh->get_total_size_in_bytes()));
- }
+ foreach (Mesh *mesh, scene->meshes) {
+ stats->mesh.geometry.add_entry(
+ NamedSizeEntry(string(mesh->name.c_str()), mesh->get_total_size_in_bytes()));
+ }
}
bool Mesh::need_attribute(Scene *scene, AttributeStandard std)
{
- if(std == ATTR_STD_NONE)
- return false;
+ if (std == ATTR_STD_NONE)
+ return false;
- if(scene->need_global_attribute(std))
- return true;
+ if (scene->need_global_attribute(std))
+ return true;
- foreach(Shader *shader, used_shaders)
- if(shader->attributes.find(std))
- return true;
+ foreach (Shader *shader, used_shaders)
+ if (shader->attributes.find(std))
+ return true;
- return false;
+ return false;
}
bool Mesh::need_attribute(Scene * /*scene*/, ustring name)
{
- if(name == ustring())
- return false;
+ if (name == ustring())
+ return false;
- foreach(Shader *shader, used_shaders)
- if(shader->attributes.find(name))
- return true;
+ foreach (Shader *shader, used_shaders)
+ if (shader->attributes.find(name))
+ return true;
- return false;
+ return false;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 789d1cc2b54..05c67ccb3b7 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -50,344 +50,352 @@ struct PackedPatchTable;
/* Mesh */
class Mesh : public Node {
-public:
- NODE_DECLARE
-
- /* Mesh Triangle */
- struct Triangle {
- int v[3];
-
- void bounds_grow(const float3 *verts, BoundBox& bounds) const;
-
- void motion_verts(const float3 *verts,
- const float3 *vert_steps,
- size_t num_verts,
- size_t num_steps,
- float time,
- float3 r_verts[3]) const;
-
- void verts_for_step(const float3 *verts,
- const float3 *vert_steps,
- size_t num_verts,
- size_t num_steps,
- size_t step,
- float3 r_verts[3]) const;
-
- float3 compute_normal(const float3 *verts) const;
-
- bool valid(const float3 *verts) const;
- };
-
- Triangle get_triangle(size_t i) const
- {
- Triangle tri = {{triangles[i*3 + 0],
- triangles[i*3 + 1],
- triangles[i*3 + 2]}};
- return tri;
- }
-
- size_t num_triangles() const
- {
- return triangles.size() / 3;
- }
-
- /* Mesh Curve */
- struct Curve {
- int first_key;
- int num_keys;
-
- int num_segments() { return num_keys - 1; }
-
- void bounds_grow(const int k,
- const float3 *curve_keys,
- const float *curve_radius,
- BoundBox& bounds) const;
- void bounds_grow(float4 keys[4], BoundBox& bounds) const;
- void bounds_grow(const int k,
- const float3 *curve_keys,
- const float *curve_radius,
- const Transform& aligned_space,
- BoundBox& bounds) const;
-
- void motion_keys(const float3 *curve_keys,
- const float *curve_radius,
- const float3 *key_steps,
- size_t num_curve_keys,
- size_t num_steps,
- float time,
- size_t k0, size_t k1,
- float4 r_keys[2]) const;
- void cardinal_motion_keys(const float3 *curve_keys,
- const float *curve_radius,
- const float3 *key_steps,
- size_t num_curve_keys,
- size_t num_steps,
- float time,
- size_t k0, size_t k1,
- size_t k2, size_t k3,
- float4 r_keys[4]) const;
-
- void keys_for_step(const float3 *curve_keys,
- const float *curve_radius,
- const float3 *key_steps,
- size_t num_curve_keys,
- size_t num_steps,
- size_t step,
- size_t k0, size_t k1,
- float4 r_keys[2]) const;
- void cardinal_keys_for_step(const float3 *curve_keys,
- const float *curve_radius,
- const float3 *key_steps,
- size_t num_curve_keys,
- size_t num_steps,
- size_t step,
- size_t k0, size_t k1,
- size_t k2, size_t k3,
- float4 r_keys[4]) const;
- };
-
- Curve get_curve(size_t i) const
- {
- int first = curve_first_key[i];
- int next_first = (i+1 < curve_first_key.size()) ? curve_first_key[i+1] : curve_keys.size();
-
- Curve curve = {first, next_first - first};
- return curve;
- }
-
- size_t num_curves() const
- {
- return curve_first_key.size();
- }
-
- /* Mesh SubdFace */
- struct SubdFace {
- int start_corner;
- int num_corners;
- int shader;
- bool smooth;
- int ptex_offset;
-
- bool is_quad() { return num_corners == 4; }
- float3 normal(const Mesh *mesh) const;
- int num_ptex_faces() const { return num_corners == 4 ? 1 : num_corners; }
- };
-
- struct SubdEdgeCrease {
- int v[2];
- float crease;
- };
-
- enum SubdivisionType {
- SUBDIVISION_NONE,
- SUBDIVISION_LINEAR,
- SUBDIVISION_CATMULL_CLARK,
- };
-
- SubdivisionType subdivision_type;
-
- /* Mesh Data */
- enum GeometryFlags {
- GEOMETRY_NONE = 0,
- GEOMETRY_TRIANGLES = (1 << 0),
- GEOMETRY_CURVES = (1 << 1),
- };
- int geometry_flags; /* used to distinguish meshes with no verts
- and meshed for which geometry is not created */
-
- array<int> triangles;
- array<float3> verts;
- array<int> shader;
- array<bool> smooth;
-
- /* used for storing patch info for subd triangles, only allocated if there are patches */
- array<int> triangle_patch; /* must be < 0 for non subd triangles */
- array<float2> vert_patch_uv;
-
- float volume_isovalue;
- bool has_volume; /* Set in the device_update_flags(). */
- bool has_surface_bssrdf; /* Set in the device_update_flags(). */
-
- array<float3> curve_keys;
- array<float> curve_radius;
- array<int> curve_first_key;
- array<int> curve_shader;
-
- array<SubdFace> subd_faces;
- array<int> subd_face_corners;
- int num_ngons;
-
- array<SubdEdgeCrease> subd_creases;
-
- SubdParams *subd_params;
-
- vector<Shader*> used_shaders;
- AttributeSet attributes;
- AttributeSet curve_attributes;
- AttributeSet subd_attributes;
-
- BoundBox bounds;
- bool transform_applied;
- bool transform_negative_scaled;
- Transform transform_normal;
-
- PackedPatchTable *patch_table;
-
- uint motion_steps;
- bool use_motion_blur;
-
- /* Update Flags */
- bool need_update;
- bool need_update_rebuild;
-
- /* BVH */
- BVH *bvh;
- size_t tri_offset;
- size_t vert_offset;
-
- size_t curve_offset;
- size_t curvekey_offset;
-
- size_t patch_offset;
- size_t patch_table_offset;
- size_t face_offset;
- size_t corner_offset;
-
- size_t attr_map_offset;
-
- size_t num_subd_verts;
-
- /* Functions */
- Mesh();
- ~Mesh();
-
- void resize_mesh(int numverts, int numfaces);
- void reserve_mesh(int numverts, int numfaces);
- void resize_curves(int numcurves, int numkeys);
- void reserve_curves(int numcurves, int numkeys);
- void resize_subd_faces(int numfaces, int num_ngons, int numcorners);
- void reserve_subd_faces(int numfaces, int num_ngons, int numcorners);
- void clear(bool preserve_voxel_data = false);
- void add_vertex(float3 P);
- void add_vertex_slow(float3 P);
- void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
- void add_curve_key(float3 loc, float radius);
- void add_curve(int first_key, int shader);
- void add_subd_face(int* corners, int num_corners, int shader_, bool smooth_);
-
- void compute_bounds();
- void add_face_normals();
- void add_vertex_normals();
- void add_undisplaced();
-
- void pack_shaders(Scene *scene, uint *shader);
- void pack_normals(float4 *vnormal);
- void pack_verts(const vector<uint>& tri_prim_index,
- uint4 *tri_vindex,
- uint *tri_patch,
- float2 *tri_patch_uv,
- size_t vert_offset,
- size_t tri_offset);
- void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
- void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
-
- void compute_bvh(Device *device,
- DeviceScene *dscene,
- SceneParams *params,
- Progress *progress,
- int n,
- int total);
-
- bool need_attribute(Scene *scene, AttributeStandard std);
- bool need_attribute(Scene *scene, ustring name);
-
- void tag_update(Scene *scene, bool rebuild);
-
- bool has_motion_blur() const;
- bool has_true_displacement() const;
-
- /* Convert between normalized -1..1 motion time and index
- * in the VERTEX_MOTION attribute. */
- float motion_time(int step) const;
- int motion_step(float time) const;
-
- /* Check whether the mesh should have own BVH built separately. Briefly,
- * own BVH is needed for mesh, if:
- *
- * - It is instanced multiple times, so each instance object should share the
- * same BVH tree.
- * - Special ray intersection is needed, for example to limit subsurface rays
- * to only the mesh itself.
- */
- bool need_build_bvh() const;
-
- /* Check if the mesh should be treated as instanced. */
- bool is_instanced() const;
-
- void tessellate(DiagSplit *split);
+ public:
+ NODE_DECLARE
+
+ /* Mesh Triangle */
+ struct Triangle {
+ int v[3];
+
+ void bounds_grow(const float3 *verts, BoundBox &bounds) const;
+
+ void motion_verts(const float3 *verts,
+ const float3 *vert_steps,
+ size_t num_verts,
+ size_t num_steps,
+ float time,
+ float3 r_verts[3]) const;
+
+ void verts_for_step(const float3 *verts,
+ const float3 *vert_steps,
+ size_t num_verts,
+ size_t num_steps,
+ size_t step,
+ float3 r_verts[3]) const;
+
+ float3 compute_normal(const float3 *verts) const;
+
+ bool valid(const float3 *verts) const;
+ };
+
+ Triangle get_triangle(size_t i) const
+ {
+ Triangle tri = {{triangles[i * 3 + 0], triangles[i * 3 + 1], triangles[i * 3 + 2]}};
+ return tri;
+ }
+
+ size_t num_triangles() const
+ {
+ return triangles.size() / 3;
+ }
+
+ /* Mesh Curve */
+ struct Curve {
+ int first_key;
+ int num_keys;
+
+ int num_segments()
+ {
+ return num_keys - 1;
+ }
+
+ void bounds_grow(const int k,
+ const float3 *curve_keys,
+ const float *curve_radius,
+ BoundBox &bounds) const;
+ void bounds_grow(float4 keys[4], BoundBox &bounds) const;
+ void bounds_grow(const int k,
+ const float3 *curve_keys,
+ const float *curve_radius,
+ const Transform &aligned_space,
+ BoundBox &bounds) const;
+
+ void motion_keys(const float3 *curve_keys,
+ const float *curve_radius,
+ const float3 *key_steps,
+ size_t num_curve_keys,
+ size_t num_steps,
+ float time,
+ size_t k0,
+ size_t k1,
+ float4 r_keys[2]) const;
+ void cardinal_motion_keys(const float3 *curve_keys,
+ const float *curve_radius,
+ const float3 *key_steps,
+ size_t num_curve_keys,
+ size_t num_steps,
+ float time,
+ size_t k0,
+ size_t k1,
+ size_t k2,
+ size_t k3,
+ float4 r_keys[4]) const;
+
+ void keys_for_step(const float3 *curve_keys,
+ const float *curve_radius,
+ const float3 *key_steps,
+ size_t num_curve_keys,
+ size_t num_steps,
+ size_t step,
+ size_t k0,
+ size_t k1,
+ float4 r_keys[2]) const;
+ void cardinal_keys_for_step(const float3 *curve_keys,
+ const float *curve_radius,
+ const float3 *key_steps,
+ size_t num_curve_keys,
+ size_t num_steps,
+ size_t step,
+ size_t k0,
+ size_t k1,
+ size_t k2,
+ size_t k3,
+ float4 r_keys[4]) const;
+ };
+
+ Curve get_curve(size_t i) const
+ {
+ int first = curve_first_key[i];
+ int next_first = (i + 1 < curve_first_key.size()) ? curve_first_key[i + 1] : curve_keys.size();
+
+ Curve curve = {first, next_first - first};
+ return curve;
+ }
+
+ size_t num_curves() const
+ {
+ return curve_first_key.size();
+ }
+
+ /* Mesh SubdFace */
+ struct SubdFace {
+ int start_corner;
+ int num_corners;
+ int shader;
+ bool smooth;
+ int ptex_offset;
+
+ bool is_quad()
+ {
+ return num_corners == 4;
+ }
+ float3 normal(const Mesh *mesh) const;
+ int num_ptex_faces() const
+ {
+ return num_corners == 4 ? 1 : num_corners;
+ }
+ };
+
+ struct SubdEdgeCrease {
+ int v[2];
+ float crease;
+ };
+
+ enum SubdivisionType {
+ SUBDIVISION_NONE,
+ SUBDIVISION_LINEAR,
+ SUBDIVISION_CATMULL_CLARK,
+ };
+
+ SubdivisionType subdivision_type;
+
+ /* Mesh Data */
+ enum GeometryFlags {
+ GEOMETRY_NONE = 0,
+ GEOMETRY_TRIANGLES = (1 << 0),
+ GEOMETRY_CURVES = (1 << 1),
+ };
+ int geometry_flags; /* used to distinguish meshes with no verts
+ and meshed for which geometry is not created */
+
+ array<int> triangles;
+ array<float3> verts;
+ array<int> shader;
+ array<bool> smooth;
+
+ /* used for storing patch info for subd triangles, only allocated if there are patches */
+ array<int> triangle_patch; /* must be < 0 for non subd triangles */
+ array<float2> vert_patch_uv;
+
+ float volume_isovalue;
+ bool has_volume; /* Set in the device_update_flags(). */
+ bool has_surface_bssrdf; /* Set in the device_update_flags(). */
+
+ array<float3> curve_keys;
+ array<float> curve_radius;
+ array<int> curve_first_key;
+ array<int> curve_shader;
+
+ array<SubdFace> subd_faces;
+ array<int> subd_face_corners;
+ int num_ngons;
+
+ array<SubdEdgeCrease> subd_creases;
+
+ SubdParams *subd_params;
+
+ vector<Shader *> used_shaders;
+ AttributeSet attributes;
+ AttributeSet curve_attributes;
+ AttributeSet subd_attributes;
+
+ BoundBox bounds;
+ bool transform_applied;
+ bool transform_negative_scaled;
+ Transform transform_normal;
+
+ PackedPatchTable *patch_table;
+
+ uint motion_steps;
+ bool use_motion_blur;
+
+ /* Update Flags */
+ bool need_update;
+ bool need_update_rebuild;
+
+ /* BVH */
+ BVH *bvh;
+ size_t tri_offset;
+ size_t vert_offset;
+
+ size_t curve_offset;
+ size_t curvekey_offset;
+
+ size_t patch_offset;
+ size_t patch_table_offset;
+ size_t face_offset;
+ size_t corner_offset;
+
+ size_t attr_map_offset;
+
+ size_t num_subd_verts;
+
+ /* Functions */
+ Mesh();
+ ~Mesh();
+
+ void resize_mesh(int numverts, int numfaces);
+ void reserve_mesh(int numverts, int numfaces);
+ void resize_curves(int numcurves, int numkeys);
+ void reserve_curves(int numcurves, int numkeys);
+ void resize_subd_faces(int numfaces, int num_ngons, int numcorners);
+ void reserve_subd_faces(int numfaces, int num_ngons, int numcorners);
+ void clear(bool preserve_voxel_data = false);
+ void add_vertex(float3 P);
+ void add_vertex_slow(float3 P);
+ void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
+ void add_curve_key(float3 loc, float radius);
+ void add_curve(int first_key, int shader);
+ void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_);
+
+ void compute_bounds();
+ void add_face_normals();
+ void add_vertex_normals();
+ void add_undisplaced();
+
+ void pack_shaders(Scene *scene, uint *shader);
+ void pack_normals(float4 *vnormal);
+ void pack_verts(const vector<uint> &tri_prim_index,
+ uint4 *tri_vindex,
+ uint *tri_patch,
+ float2 *tri_patch_uv,
+ size_t vert_offset,
+ size_t tri_offset);
+ void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
+ void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
+
+ void compute_bvh(Device *device,
+ DeviceScene *dscene,
+ SceneParams *params,
+ Progress *progress,
+ int n,
+ int total);
+
+ bool need_attribute(Scene *scene, AttributeStandard std);
+ bool need_attribute(Scene *scene, ustring name);
+
+ void tag_update(Scene *scene, bool rebuild);
+
+ bool has_motion_blur() const;
+ bool has_true_displacement() const;
+
+ /* Convert between normalized -1..1 motion time and index
+ * in the VERTEX_MOTION attribute. */
+ float motion_time(int step) const;
+ int motion_step(float time) const;
+
+ /* Check whether the mesh should have own BVH built separately. Briefly,
+ * own BVH is needed for mesh, if:
+ *
+ * - It is instanced multiple times, so each instance object should share the
+ * same BVH tree.
+ * - Special ray intersection is needed, for example to limit subsurface rays
+ * to only the mesh itself.
+ */
+ bool need_build_bvh() const;
+
+ /* Check if the mesh should be treated as instanced. */
+ bool is_instanced() const;
+
+ void tessellate(DiagSplit *split);
};
/* Mesh Manager */
class MeshManager {
-public:
- bool need_update;
- bool need_flags_update;
+ public:
+ bool need_update;
+ bool need_flags_update;
- MeshManager();
- ~MeshManager();
+ MeshManager();
+ ~MeshManager();
- bool displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress& progress);
+ bool displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress);
- /* attributes */
- void update_osl_attributes(Device *device, Scene *scene, vector<AttributeRequestSet>& mesh_attributes);
- void update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector<AttributeRequestSet>& mesh_attributes);
+ /* attributes */
+ void update_osl_attributes(Device *device,
+ Scene *scene,
+ vector<AttributeRequestSet> &mesh_attributes);
+ void update_svm_attributes(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ vector<AttributeRequestSet> &mesh_attributes);
- void device_update_preprocess(Device *device, Scene *scene, Progress& progress);
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_update_preprocess(Device *device, Scene *scene, Progress &progress);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_free(Device *device, DeviceScene *dscene);
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene);
- void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress);
+ void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress);
- void collect_statistics(const Scene *scene, RenderStats *stats);
+ void collect_statistics(const Scene *scene, RenderStats *stats);
-protected:
- /* Calculate verts/triangles/curves offsets in global arrays. */
- void mesh_calc_offset(Scene *scene);
+ protected:
+ /* Calculate verts/triangles/curves offsets in global arrays. */
+ void mesh_calc_offset(Scene *scene);
- void device_update_object(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress& progress);
+ void device_update_object(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
- void device_update_mesh(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- bool for_displacement,
- Progress& progress);
+ void device_update_mesh(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ bool for_displacement,
+ Progress &progress);
- void device_update_attributes(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress& progress);
+ void device_update_attributes(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress);
- void device_update_bvh(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress& progress);
+ void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
- void device_update_displacement_images(Device *device,
- Scene *scene,
- Progress& progress);
+ void device_update_displacement_images(Device *device, Scene *scene, Progress &progress);
- void device_update_volume_images(Device *device,
- Scene *scene,
- Progress& progress);
+ void device_update_volume_images(Device *device, Scene *scene, Progress &progress);
};
CCL_NAMESPACE_END
-#endif /* __MESH_H__ */
+#endif /* __MESH_H__ */
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index 53b9bfa3451..5ae9348d83e 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -26,296 +26,301 @@
CCL_NAMESPACE_BEGIN
-static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
+static float3 compute_face_normal(const Mesh::Triangle &t, float3 *verts)
{
- float3 v0 = verts[t.v[0]];
- float3 v1 = verts[t.v[1]];
- float3 v2 = verts[t.v[2]];
+ float3 v0 = verts[t.v[0]];
+ float3 v1 = verts[t.v[1]];
+ float3 v2 = verts[t.v[2]];
- float3 norm = cross(v1 - v0, v2 - v0);
- float normlen = len(norm);
+ float3 norm = cross(v1 - v0, v2 - v0);
+ float normlen = len(norm);
- if(normlen == 0.0f)
- return make_float3(1.0f, 0.0f, 0.0f);
+ if (normlen == 0.0f)
+ return make_float3(1.0f, 0.0f, 0.0f);
- return norm / normlen;
+ return norm / normlen;
}
-bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress& progress)
+bool MeshManager::displace(
+ Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress)
{
- /* verify if we have a displacement shader */
- if(!mesh->has_true_displacement()) {
- return false;
- }
-
- string msg = string_printf("Computing Displacement %s", mesh->name.c_str());
- progress.set_status("Updating Mesh", msg);
-
- /* find object index. todo: is arbitrary */
- size_t object_index = OBJECT_NONE;
-
- for(size_t i = 0; i < scene->objects.size(); i++) {
- if(scene->objects[i]->mesh == mesh) {
- object_index = i;
- break;
- }
- }
-
- /* setup input for device task */
- const size_t num_verts = mesh->verts.size();
- vector<bool> done(num_verts, false);
- device_vector<uint4> d_input(device, "displace_input", MEM_READ_ONLY);
- uint4 *d_input_data = d_input.alloc(num_verts);
- size_t d_input_size = 0;
-
- size_t num_triangles = mesh->num_triangles();
- for(size_t i = 0; i < num_triangles; i++) {
- Mesh::Triangle t = mesh->get_triangle(i);
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] : scene->default_surface;
-
- if(!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
- continue;
- }
-
- for(int j = 0; j < 3; j++) {
- if(done[t.v[j]])
- continue;
-
- done[t.v[j]] = true;
-
- /* set up object, primitive and barycentric coordinates */
- int object = object_index;
- int prim = mesh->tri_offset + i;
- float u, v;
-
- switch(j) {
- case 0:
- u = 1.0f;
- v = 0.0f;
- break;
- case 1:
- u = 0.0f;
- v = 1.0f;
- break;
- default:
- u = 0.0f;
- v = 0.0f;
- break;
- }
-
- /* back */
- uint4 in = make_uint4(object, prim, __float_as_int(u), __float_as_int(v));
- d_input_data[d_input_size++] = in;
- }
- }
-
- if(d_input_size == 0)
- return false;
-
- /* run device task */
- device_vector<float4> d_output(device, "displace_output", MEM_READ_WRITE);
- d_output.alloc(d_input_size);
- d_output.zero_to_device();
- d_input.copy_to_device();
-
- /* needs to be up to data for attribute access */
- device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
-
- DeviceTask task(DeviceTask::SHADER);
- task.shader_input = d_input.device_pointer;
- task.shader_output = d_output.device_pointer;
- task.shader_eval_type = SHADER_EVAL_DISPLACE;
- task.shader_x = 0;
- task.shader_w = d_output.size();
- task.num_samples = 1;
- task.get_cancel = function_bind(&Progress::get_cancel, &progress);
-
- device->task_add(task);
- device->task_wait();
-
- if(progress.get_cancel()) {
- d_input.free();
- d_output.free();
- return false;
- }
-
- d_output.copy_from_device(0, 1, d_output.size());
- d_input.free();
-
- /* read result */
- done.clear();
- done.resize(num_verts, false);
- int k = 0;
-
- float4 *offset = d_output.data();
-
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- for(size_t i = 0; i < num_triangles; i++) {
- Mesh::Triangle t = mesh->get_triangle(i);
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] : scene->default_surface;
-
- if(!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
- continue;
- }
-
- for(int j = 0; j < 3; j++) {
- if(!done[t.v[j]]) {
- done[t.v[j]] = true;
- float3 off = float4_to_float3(offset[k++]);
- /* Avoid illegal vertex coordinates. */
- off = ensure_finite3(off);
- mesh->verts[t.v[j]] += off;
- if(attr_mP != NULL) {
- for(int step = 0; step < mesh->motion_steps - 1; step++) {
- float3 *mP = attr_mP->data_float3() + step*num_verts;
- mP[t.v[j]] += off;
- }
- }
- }
- }
- }
-
- d_output.free();
-
- /* for displacement method both, we only need to recompute the face
- * normals, as bump mapping in the shader will already alter the
- * vertex normal, so we start from the non-displaced vertex normals
- * to avoid applying the perturbation twice. */
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
- mesh->add_face_normals();
-
- bool need_recompute_vertex_normals = false;
-
- foreach(Shader *shader, mesh->used_shaders) {
- if(shader->has_displacement && shader->displacement_method == DISPLACE_TRUE) {
- need_recompute_vertex_normals = true;
- break;
- }
- }
-
- if(need_recompute_vertex_normals) {
- bool flip = mesh->transform_negative_scaled;
- vector<bool> tri_has_true_disp(num_triangles, false);
-
- for(size_t i = 0; i < num_triangles; i++) {
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] : scene->default_surface;
-
- tri_has_true_disp[i] = shader->has_displacement && shader->displacement_method == DISPLACE_TRUE;
- }
-
- /* static vertex normals */
-
- /* get attributes */
- Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
- Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
-
- float3 *fN = attr_fN->data_float3();
- float3 *vN = attr_vN->data_float3();
-
- /* compute vertex normals */
-
- /* zero vertex normals on triangles with true displacement */
- for(size_t i = 0; i < num_triangles; i++) {
- if(tri_has_true_disp[i]) {
- for(size_t j = 0; j < 3; j++) {
- vN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
- }
- }
- }
-
- /* add face normals to vertex normals */
- for(size_t i = 0; i < num_triangles; i++) {
- if(tri_has_true_disp[i]) {
- for(size_t j = 0; j < 3; j++) {
- vN[mesh->get_triangle(i).v[j]] += fN[i];
- }
- }
- }
-
- /* normalize vertex normals */
- done.clear();
- done.resize(num_verts, false);
-
- for(size_t i = 0; i < num_triangles; i++) {
- if(tri_has_true_disp[i]) {
- for(size_t j = 0; j < 3; j++) {
- int vert = mesh->get_triangle(i).v[j];
-
- if(done[vert]) {
- continue;
- }
-
- vN[vert] = normalize(vN[vert]);
- if(flip)
- vN[vert] = -vN[vert];
-
- done[vert] = true;
- }
- }
- }
-
- /* motion vertex normals */
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
-
- if(mesh->has_motion_blur() && attr_mP && attr_mN) {
- for(int step = 0; step < mesh->motion_steps - 1; step++) {
- float3 *mP = attr_mP->data_float3() + step*mesh->verts.size();
- float3 *mN = attr_mN->data_float3() + step*mesh->verts.size();
-
- /* compute */
-
- /* zero vertex normals on triangles with true displacement */
- for(size_t i = 0; i < num_triangles; i++) {
- if(tri_has_true_disp[i]) {
- for(size_t j = 0; j < 3; j++) {
- mN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
- }
- }
- }
-
- /* add face normals to vertex normals */
- for(size_t i = 0; i < num_triangles; i++) {
- if(tri_has_true_disp[i]) {
- for(size_t j = 0; j < 3; j++) {
- float3 fN = compute_face_normal(mesh->get_triangle(i), mP);
- mN[mesh->get_triangle(i).v[j]] += fN;
- }
- }
- }
-
- /* normalize vertex normals */
- done.clear();
- done.resize(num_verts, false);
-
- for(size_t i = 0; i < num_triangles; i++) {
- if(tri_has_true_disp[i]) {
- for(size_t j = 0; j < 3; j++) {
- int vert = mesh->get_triangle(i).v[j];
-
- if(done[vert]) {
- continue;
- }
-
- mN[vert] = normalize(mN[vert]);
- if(flip)
- mN[vert] = -mN[vert];
-
- done[vert] = true;
- }
- }
- }
- }
- }
- }
-
- return true;
+ /* verify if we have a displacement shader */
+ if (!mesh->has_true_displacement()) {
+ return false;
+ }
+
+ string msg = string_printf("Computing Displacement %s", mesh->name.c_str());
+ progress.set_status("Updating Mesh", msg);
+
+ /* find object index. todo: is arbitrary */
+ size_t object_index = OBJECT_NONE;
+
+ for (size_t i = 0; i < scene->objects.size(); i++) {
+ if (scene->objects[i]->mesh == mesh) {
+ object_index = i;
+ break;
+ }
+ }
+
+ /* setup input for device task */
+ const size_t num_verts = mesh->verts.size();
+ vector<bool> done(num_verts, false);
+ device_vector<uint4> d_input(device, "displace_input", MEM_READ_ONLY);
+ uint4 *d_input_data = d_input.alloc(num_verts);
+ size_t d_input_size = 0;
+
+ size_t num_triangles = mesh->num_triangles();
+ for (size_t i = 0; i < num_triangles; i++) {
+ Mesh::Triangle t = mesh->get_triangle(i);
+ int shader_index = mesh->shader[i];
+ Shader *shader = (shader_index < mesh->used_shaders.size()) ?
+ mesh->used_shaders[shader_index] :
+ scene->default_surface;
+
+ if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
+ continue;
+ }
+
+ for (int j = 0; j < 3; j++) {
+ if (done[t.v[j]])
+ continue;
+
+ done[t.v[j]] = true;
+
+ /* set up object, primitive and barycentric coordinates */
+ int object = object_index;
+ int prim = mesh->tri_offset + i;
+ float u, v;
+
+ switch (j) {
+ case 0:
+ u = 1.0f;
+ v = 0.0f;
+ break;
+ case 1:
+ u = 0.0f;
+ v = 1.0f;
+ break;
+ default:
+ u = 0.0f;
+ v = 0.0f;
+ break;
+ }
+
+ /* back */
+ uint4 in = make_uint4(object, prim, __float_as_int(u), __float_as_int(v));
+ d_input_data[d_input_size++] = in;
+ }
+ }
+
+ if (d_input_size == 0)
+ return false;
+
+ /* run device task */
+ device_vector<float4> d_output(device, "displace_output", MEM_READ_WRITE);
+ d_output.alloc(d_input_size);
+ d_output.zero_to_device();
+ d_input.copy_to_device();
+
+ /* needs to be up to data for attribute access */
+ device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
+
+ DeviceTask task(DeviceTask::SHADER);
+ task.shader_input = d_input.device_pointer;
+ task.shader_output = d_output.device_pointer;
+ task.shader_eval_type = SHADER_EVAL_DISPLACE;
+ task.shader_x = 0;
+ task.shader_w = d_output.size();
+ task.num_samples = 1;
+ task.get_cancel = function_bind(&Progress::get_cancel, &progress);
+
+ device->task_add(task);
+ device->task_wait();
+
+ if (progress.get_cancel()) {
+ d_input.free();
+ d_output.free();
+ return false;
+ }
+
+ d_output.copy_from_device(0, 1, d_output.size());
+ d_input.free();
+
+ /* read result */
+ done.clear();
+ done.resize(num_verts, false);
+ int k = 0;
+
+ float4 *offset = d_output.data();
+
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ for (size_t i = 0; i < num_triangles; i++) {
+ Mesh::Triangle t = mesh->get_triangle(i);
+ int shader_index = mesh->shader[i];
+ Shader *shader = (shader_index < mesh->used_shaders.size()) ?
+ mesh->used_shaders[shader_index] :
+ scene->default_surface;
+
+ if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
+ continue;
+ }
+
+ for (int j = 0; j < 3; j++) {
+ if (!done[t.v[j]]) {
+ done[t.v[j]] = true;
+ float3 off = float4_to_float3(offset[k++]);
+ /* Avoid illegal vertex coordinates. */
+ off = ensure_finite3(off);
+ mesh->verts[t.v[j]] += off;
+ if (attr_mP != NULL) {
+ for (int step = 0; step < mesh->motion_steps - 1; step++) {
+ float3 *mP = attr_mP->data_float3() + step * num_verts;
+ mP[t.v[j]] += off;
+ }
+ }
+ }
+ }
+ }
+
+ d_output.free();
+
+ /* for displacement method both, we only need to recompute the face
+ * normals, as bump mapping in the shader will already alter the
+ * vertex normal, so we start from the non-displaced vertex normals
+ * to avoid applying the perturbation twice. */
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+
+ bool need_recompute_vertex_normals = false;
+
+ foreach (Shader *shader, mesh->used_shaders) {
+ if (shader->has_displacement && shader->displacement_method == DISPLACE_TRUE) {
+ need_recompute_vertex_normals = true;
+ break;
+ }
+ }
+
+ if (need_recompute_vertex_normals) {
+ bool flip = mesh->transform_negative_scaled;
+ vector<bool> tri_has_true_disp(num_triangles, false);
+
+ for (size_t i = 0; i < num_triangles; i++) {
+ int shader_index = mesh->shader[i];
+ Shader *shader = (shader_index < mesh->used_shaders.size()) ?
+ mesh->used_shaders[shader_index] :
+ scene->default_surface;
+
+ tri_has_true_disp[i] = shader->has_displacement &&
+ shader->displacement_method == DISPLACE_TRUE;
+ }
+
+ /* static vertex normals */
+
+ /* get attributes */
+ Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
+ Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+
+ float3 *fN = attr_fN->data_float3();
+ float3 *vN = attr_vN->data_float3();
+
+ /* compute vertex normals */
+
+ /* zero vertex normals on triangles with true displacement */
+ for (size_t i = 0; i < num_triangles; i++) {
+ if (tri_has_true_disp[i]) {
+ for (size_t j = 0; j < 3; j++) {
+ vN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ }
+ }
+
+ /* add face normals to vertex normals */
+ for (size_t i = 0; i < num_triangles; i++) {
+ if (tri_has_true_disp[i]) {
+ for (size_t j = 0; j < 3; j++) {
+ vN[mesh->get_triangle(i).v[j]] += fN[i];
+ }
+ }
+ }
+
+ /* normalize vertex normals */
+ done.clear();
+ done.resize(num_verts, false);
+
+ for (size_t i = 0; i < num_triangles; i++) {
+ if (tri_has_true_disp[i]) {
+ for (size_t j = 0; j < 3; j++) {
+ int vert = mesh->get_triangle(i).v[j];
+
+ if (done[vert]) {
+ continue;
+ }
+
+ vN[vert] = normalize(vN[vert]);
+ if (flip)
+ vN[vert] = -vN[vert];
+
+ done[vert] = true;
+ }
+ }
+ }
+
+ /* motion vertex normals */
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ if (mesh->has_motion_blur() && attr_mP && attr_mN) {
+ for (int step = 0; step < mesh->motion_steps - 1; step++) {
+ float3 *mP = attr_mP->data_float3() + step * mesh->verts.size();
+ float3 *mN = attr_mN->data_float3() + step * mesh->verts.size();
+
+ /* compute */
+
+ /* zero vertex normals on triangles with true displacement */
+ for (size_t i = 0; i < num_triangles; i++) {
+ if (tri_has_true_disp[i]) {
+ for (size_t j = 0; j < 3; j++) {
+ mN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ }
+ }
+
+ /* add face normals to vertex normals */
+ for (size_t i = 0; i < num_triangles; i++) {
+ if (tri_has_true_disp[i]) {
+ for (size_t j = 0; j < 3; j++) {
+ float3 fN = compute_face_normal(mesh->get_triangle(i), mP);
+ mN[mesh->get_triangle(i).v[j]] += fN;
+ }
+ }
+ }
+
+ /* normalize vertex normals */
+ done.clear();
+ done.resize(num_verts, false);
+
+ for (size_t i = 0; i < num_triangles; i++) {
+ if (tri_has_true_disp[i]) {
+ for (size_t j = 0; j < 3; j++) {
+ int vert = mesh->get_triangle(i).v[j];
+
+ if (done[vert]) {
+ continue;
+ }
+
+ mN[vert] = normalize(mN[vert]);
+ if (flip)
+ mN[vert] = -mN[vert];
+
+ done[vert] = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp
index 95cc6f1fca1..46c8240fb71 100644
--- a/intern/cycles/render/mesh_subdivision.cpp
+++ b/intern/cycles/render/mesh_subdivision.cpp
@@ -31,87 +31,92 @@ CCL_NAMESPACE_BEGIN
CCL_NAMESPACE_END
-#include <opensubdiv/far/topologyRefinerFactory.h>
-#include <opensubdiv/far/primvarRefiner.h>
-#include <opensubdiv/far/patchTableFactory.h>
-#include <opensubdiv/far/patchMap.h>
+# include <opensubdiv/far/topologyRefinerFactory.h>
+# include <opensubdiv/far/primvarRefiner.h>
+# include <opensubdiv/far/patchTableFactory.h>
+# include <opensubdiv/far/patchMap.h>
/* specializations of TopologyRefinerFactory for ccl::Mesh */
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far {
- template<>
- bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner& refiner, ccl::Mesh const& mesh)
- {
- setNumBaseVertices(refiner, mesh.verts.size());
- setNumBaseFaces(refiner, mesh.subd_faces.size());
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner,
+ ccl::Mesh const &mesh)
+{
+ setNumBaseVertices(refiner, mesh.verts.size());
+ setNumBaseFaces(refiner, mesh.subd_faces.size());
- const ccl::Mesh::SubdFace* face = mesh.subd_faces.data();
+ const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
- for(int i = 0; i < mesh.subd_faces.size(); i++, face++) {
- setNumBaseFaceVertices(refiner, i, face->num_corners);
- }
+ for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
+ setNumBaseFaceVertices(refiner, i, face->num_corners);
+ }
- return true;
- }
+ return true;
+}
- template<>
- bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner& refiner, ccl::Mesh const& mesh)
- {
- const ccl::Mesh::SubdFace* face = mesh.subd_faces.data();
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner,
+ ccl::Mesh const &mesh)
+{
+ const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
- for(int i = 0; i < mesh.subd_faces.size(); i++, face++) {
- IndexArray face_verts = getBaseFaceVertices(refiner, i);
+ for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
+ IndexArray face_verts = getBaseFaceVertices(refiner, i);
- int* corner = &mesh.subd_face_corners[face->start_corner];
+ int *corner = &mesh.subd_face_corners[face->start_corner];
- for(int j = 0; j < face->num_corners; j++, corner++) {
- face_verts[j] = *corner;
- }
- }
+ for (int j = 0; j < face->num_corners; j++, corner++) {
+ face_verts[j] = *corner;
+ }
+ }
- return true;
- }
+ return true;
+}
- template<>
- bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner& refiner, ccl::Mesh const& mesh)
- {
- const ccl::Mesh::SubdEdgeCrease* crease = mesh.subd_creases.data();
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
+ ccl::Mesh const &mesh)
+{
+ const ccl::Mesh::SubdEdgeCrease *crease = mesh.subd_creases.data();
- for(int i = 0; i < mesh.subd_creases.size(); i++, crease++) {
- Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]);
+ for (int i = 0; i < mesh.subd_creases.size(); i++, crease++) {
+ Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]);
- if(edge != INDEX_INVALID) {
- setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f);
- }
- }
+ if (edge != INDEX_INVALID) {
+ setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f);
+ }
+ }
- for(int i = 0; i < mesh.verts.size(); i++) {
- ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
+ for (int i = 0; i < mesh.verts.size(); i++) {
+ ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
- if(vert_edges.size() == 2) {
- float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
- sharpness = ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1]));
+ if (vert_edges.size() == 2) {
+ float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
+ sharpness = ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1]));
- setBaseVertexSharpness(refiner, i, sharpness);
- }
- }
+ setBaseVertexSharpness(refiner, i, sharpness);
+ }
+ }
- return true;
- }
+ return true;
+}
- template<>
- bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner& /*refiner*/, ccl::Mesh const& /*mesh*/)
- {
- return true;
- }
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner & /*refiner*/,
+ ccl::Mesh const & /*mesh*/)
+{
+ return true;
+}
- template<>
- void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError /*err_code*/,
- char const * /*msg*/, ccl::Mesh const& /*mesh*/)
- {
- }
+template<>
+void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError /*err_code*/,
+ char const * /*msg*/,
+ ccl::Mesh const & /*mesh*/)
+{
+}
} /* namespace Far */
} /* namespace OPENSUBDIV_VERSION */
} /* namespace OpenSubdiv */
@@ -122,226 +127,242 @@ using namespace OpenSubdiv;
/* struct that implements OpenSubdiv's vertex interface */
-template<typename T>
-struct OsdValue {
- T value;
+template<typename T> struct OsdValue {
+ T value;
- OsdValue() {}
+ OsdValue()
+ {
+ }
- void Clear(void* = 0) {
- memset(&value, 0, sizeof(T));
- }
+ void Clear(void * = 0)
+ {
+ memset(&value, 0, sizeof(T));
+ }
- void AddWithWeight(OsdValue<T> const& src, float weight) {
- value += src.value * weight;
- }
+ void AddWithWeight(OsdValue<T> const &src, float weight)
+ {
+ value += src.value * weight;
+ }
};
-template<>
-void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4> const& src, float weight)
+template<> void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4> const &src, float weight)
{
- for(int i = 0; i < 4; i++) {
- value[i] += (uchar)(src.value[i] * weight);
- }
+ for (int i = 0; i < 4; i++) {
+ value[i] += (uchar)(src.value[i] * weight);
+ }
}
/* class for holding OpenSubdiv data used during tessellation */
class OsdData {
- Mesh* mesh;
- vector<OsdValue<float3> > verts;
- Far::TopologyRefiner* refiner;
- Far::PatchTable* patch_table;
- Far::PatchMap* patch_map;
-
-public:
- OsdData() : mesh(NULL), refiner(NULL), patch_table(NULL), patch_map(NULL) {}
-
- ~OsdData()
- {
- delete refiner;
- delete patch_table;
- delete patch_map;
- }
-
- void build_from_mesh(Mesh* mesh_)
- {
- mesh = mesh_;
-
- /* type and options */
- Sdc::SchemeType type = Sdc::SCHEME_CATMARK;
-
- Sdc::Options options;
- options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
-
- /* create refiner */
- refiner = Far::TopologyRefinerFactory<Mesh>::Create(*mesh,
- Far::TopologyRefinerFactory<Mesh>::Options(type, options));
-
- /* adaptive refinement */
- int max_isolation = calculate_max_isolation();
- refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
-
- /* create patch table */
- Far::PatchTableFactory::Options patch_options;
- patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
-
- patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
-
- /* interpolate verts */
- int num_refiner_verts = refiner->GetNumVerticesTotal();
- int num_local_points = patch_table->GetNumLocalPoints();
-
- verts.resize(num_refiner_verts + num_local_points);
- for(int i = 0; i < mesh->verts.size(); i++) {
- verts[i].value = mesh->verts[i];
- }
-
- OsdValue<float3>* src = verts.data();
- for(int i = 0; i < refiner->GetMaxLevel(); i++) {
- OsdValue<float3>* dest = src + refiner->GetLevel(i).GetNumVertices();
- Far::PrimvarRefiner(*refiner).Interpolate(i+1, src, dest);
- src = dest;
- }
-
- if(num_local_points) {
- patch_table->ComputeLocalPointValues(&verts[0], &verts[num_refiner_verts]);
- }
-
- /* create patch map */
- patch_map = new Far::PatchMap(*patch_table);
- }
-
- void subdivide_attribute(Attribute& attr)
- {
- Far::PrimvarRefiner primvar_refiner(*refiner);
-
- if(attr.element == ATTR_ELEMENT_VERTEX) {
- int num_refiner_verts = refiner->GetNumVerticesTotal();
- int num_local_points = patch_table->GetNumLocalPoints();
-
- attr.resize(num_refiner_verts + num_local_points);
- attr.flags |= ATTR_FINAL_SIZE;
-
- char* src = attr.buffer.data();
-
- for(int i = 0; i < refiner->GetMaxLevel(); i++) {
- char* dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof();
-
- if(attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
- primvar_refiner.Interpolate(i+1, (OsdValue<float>*)src, (OsdValue<float>*&)dest);
- }
- else if(attr.same_storage(attr.type, TypeFloat2)) {
- primvar_refiner.Interpolate(i+1, (OsdValue<float2>*)src, (OsdValue<float2>*&)dest);
- }
- else {
- primvar_refiner.Interpolate(i+1, (OsdValue<float4>*)src, (OsdValue<float4>*&)dest);
- }
-
- src = dest;
- }
-
- if(num_local_points) {
- if(attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
- patch_table->ComputeLocalPointValues((OsdValue<float>*)&attr.buffer[0],
- (OsdValue<float>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
- }
- else if(attr.same_storage(attr.type, TypeFloat2)) {
- patch_table->ComputeLocalPointValues((OsdValue<float2>*)&attr.buffer[0],
- (OsdValue<float2>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
- }
- else {
- patch_table->ComputeLocalPointValues((OsdValue<float4>*)&attr.buffer[0],
- (OsdValue<float4>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
- }
- }
- }
- else if(attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
- // TODO(mai): fvar interpolation
- }
- }
-
- int calculate_max_isolation()
- {
- /* loop over all edges to find longest in screen space */
- const Far::TopologyLevel& level = refiner->GetLevel(0);
- Transform objecttoworld = mesh->subd_params->objecttoworld;
- Camera* cam = mesh->subd_params->camera;
-
- float longest_edge = 0.0f;
-
- for(size_t i = 0; i < level.GetNumEdges(); i++) {
- Far::ConstIndexArray verts = level.GetEdgeVertices(i);
-
- float3 a = mesh->verts[verts[0]];
- float3 b = mesh->verts[verts[1]];
-
- float edge_len;
-
- if(cam) {
- a = transform_point(&objecttoworld, a);
- b = transform_point(&objecttoworld, b);
-
- edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f);
- }
- else {
- edge_len = len(a - b);
- }
-
- longest_edge = max(longest_edge, edge_len);
- }
-
- /* calculate isolation level */
- int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f);
-
- return min(isolation, 10);
- }
-
- friend struct OsdPatch;
- friend class Mesh;
+ Mesh *mesh;
+ vector<OsdValue<float3>> verts;
+ Far::TopologyRefiner *refiner;
+ Far::PatchTable *patch_table;
+ Far::PatchMap *patch_map;
+
+ public:
+ OsdData() : mesh(NULL), refiner(NULL), patch_table(NULL), patch_map(NULL)
+ {
+ }
+
+ ~OsdData()
+ {
+ delete refiner;
+ delete patch_table;
+ delete patch_map;
+ }
+
+ void build_from_mesh(Mesh *mesh_)
+ {
+ mesh = mesh_;
+
+ /* type and options */
+ Sdc::SchemeType type = Sdc::SCHEME_CATMARK;
+
+ Sdc::Options options;
+ options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
+
+ /* create refiner */
+ refiner = Far::TopologyRefinerFactory<Mesh>::Create(
+ *mesh, Far::TopologyRefinerFactory<Mesh>::Options(type, options));
+
+ /* adaptive refinement */
+ int max_isolation = calculate_max_isolation();
+ refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
+
+ /* create patch table */
+ Far::PatchTableFactory::Options patch_options;
+ patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
+
+ patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
+
+ /* interpolate verts */
+ int num_refiner_verts = refiner->GetNumVerticesTotal();
+ int num_local_points = patch_table->GetNumLocalPoints();
+
+ verts.resize(num_refiner_verts + num_local_points);
+ for (int i = 0; i < mesh->verts.size(); i++) {
+ verts[i].value = mesh->verts[i];
+ }
+
+ OsdValue<float3> *src = verts.data();
+ for (int i = 0; i < refiner->GetMaxLevel(); i++) {
+ OsdValue<float3> *dest = src + refiner->GetLevel(i).GetNumVertices();
+ Far::PrimvarRefiner(*refiner).Interpolate(i + 1, src, dest);
+ src = dest;
+ }
+
+ if (num_local_points) {
+ patch_table->ComputeLocalPointValues(&verts[0], &verts[num_refiner_verts]);
+ }
+
+ /* create patch map */
+ patch_map = new Far::PatchMap(*patch_table);
+ }
+
+ void subdivide_attribute(Attribute &attr)
+ {
+ Far::PrimvarRefiner primvar_refiner(*refiner);
+
+ if (attr.element == ATTR_ELEMENT_VERTEX) {
+ int num_refiner_verts = refiner->GetNumVerticesTotal();
+ int num_local_points = patch_table->GetNumLocalPoints();
+
+ attr.resize(num_refiner_verts + num_local_points);
+ attr.flags |= ATTR_FINAL_SIZE;
+
+ char *src = attr.buffer.data();
+
+ for (int i = 0; i < refiner->GetMaxLevel(); i++) {
+ char *dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof();
+
+ if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
+ primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)src, (OsdValue<float> *&)dest);
+ }
+ else if (attr.same_storage(attr.type, TypeFloat2)) {
+ primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)src, (OsdValue<float2> *&)dest);
+ }
+ else {
+ primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)src, (OsdValue<float4> *&)dest);
+ }
+
+ src = dest;
+ }
+
+ if (num_local_points) {
+ if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
+ patch_table->ComputeLocalPointValues(
+ (OsdValue<float> *)&attr.buffer[0],
+ (OsdValue<float> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+ }
+ else if (attr.same_storage(attr.type, TypeFloat2)) {
+ patch_table->ComputeLocalPointValues(
+ (OsdValue<float2> *)&attr.buffer[0],
+ (OsdValue<float2> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+ }
+ else {
+ patch_table->ComputeLocalPointValues(
+ (OsdValue<float4> *)&attr.buffer[0],
+ (OsdValue<float4> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+ }
+ }
+ }
+ else if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
+ // TODO(mai): fvar interpolation
+ }
+ }
+
+ int calculate_max_isolation()
+ {
+ /* loop over all edges to find longest in screen space */
+ const Far::TopologyLevel &level = refiner->GetLevel(0);
+ Transform objecttoworld = mesh->subd_params->objecttoworld;
+ Camera *cam = mesh->subd_params->camera;
+
+ float longest_edge = 0.0f;
+
+ for (size_t i = 0; i < level.GetNumEdges(); i++) {
+ Far::ConstIndexArray verts = level.GetEdgeVertices(i);
+
+ float3 a = mesh->verts[verts[0]];
+ float3 b = mesh->verts[verts[1]];
+
+ float edge_len;
+
+ if (cam) {
+ a = transform_point(&objecttoworld, a);
+ b = transform_point(&objecttoworld, b);
+
+ edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f);
+ }
+ else {
+ edge_len = len(a - b);
+ }
+
+ longest_edge = max(longest_edge, edge_len);
+ }
+
+ /* calculate isolation level */
+ int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f);
+
+ return min(isolation, 10);
+ }
+
+ friend struct OsdPatch;
+ friend class Mesh;
};
/* ccl::Patch implementation that uses OpenSubdiv for eval */
struct OsdPatch : Patch {
- OsdData* osd_data;
-
- OsdPatch(OsdData* data) : osd_data(data) {}
-
- void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
- {
- const Far::PatchTable::PatchHandle* handle = osd_data->patch_map->FindPatch(patch_index, u, v);
- assert(handle);
-
- float p_weights[20], du_weights[20], dv_weights[20];
- osd_data->patch_table->EvaluateBasis(*handle, u, v, p_weights, du_weights, dv_weights);
-
- Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
-
- float3 du, dv;
- if(P) *P = make_float3(0.0f, 0.0f, 0.0f);
- du = make_float3(0.0f, 0.0f, 0.0f);
- dv = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < cv.size(); i++) {
- float3 p = osd_data->verts[cv[i]].value;
-
- if(P) *P += p * p_weights[i];
- du += p * du_weights[i];
- dv += p * dv_weights[i];
- }
-
- if(dPdu) *dPdu = du;
- if(dPdv) *dPdv = dv;
- if(N) {
- *N = cross(du, dv);
-
- float t = len(*N);
- *N = (t != 0.0f) ? *N/t : make_float3(0.0f, 0.0f, 1.0f);
- }
- }
-
- BoundBox bound() { return BoundBox::empty; }
+ OsdData *osd_data;
+
+ OsdPatch(OsdData *data) : osd_data(data)
+ {
+ }
+
+ void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
+ {
+ const Far::PatchTable::PatchHandle *handle = osd_data->patch_map->FindPatch(patch_index, u, v);
+ assert(handle);
+
+ float p_weights[20], du_weights[20], dv_weights[20];
+ osd_data->patch_table->EvaluateBasis(*handle, u, v, p_weights, du_weights, dv_weights);
+
+ Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
+
+ float3 du, dv;
+ if (P)
+ *P = make_float3(0.0f, 0.0f, 0.0f);
+ du = make_float3(0.0f, 0.0f, 0.0f);
+ dv = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < cv.size(); i++) {
+ float3 p = osd_data->verts[cv[i]].value;
+
+ if (P)
+ *P += p * p_weights[i];
+ du += p * du_weights[i];
+ dv += p * dv_weights[i];
+ }
+
+ if (dPdu)
+ *dPdu = du;
+ if (dPdv)
+ *dPdv = dv;
+ if (N) {
+ *N = cross(du, dv);
+
+ float t = len(*N);
+ *N = (t != 0.0f) ? *N / t : make_float3(0.0f, 0.0f, 1.0f);
+ }
+ }
+
+ BoundBox bound()
+ {
+ return BoundBox::empty;
+ }
};
#endif
@@ -349,273 +370,280 @@ struct OsdPatch : Patch {
void Mesh::tessellate(DiagSplit *split)
{
#ifdef WITH_OPENSUBDIV
- OsdData osd_data;
- bool need_packed_patch_table = false;
-
- if(subdivision_type == SUBDIVISION_CATMULL_CLARK) {
- if(subd_faces.size()) {
- osd_data.build_from_mesh(this);
- }
- }
- else
+ OsdData osd_data;
+ bool need_packed_patch_table = false;
+
+ if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
+ if (subd_faces.size()) {
+ osd_data.build_from_mesh(this);
+ }
+ }
+ else
#endif
- {
- /* force linear subdivision if OpenSubdiv is unavailable to avoid
- * falling into catmull-clark code paths by accident
- */
- subdivision_type = SUBDIVISION_LINEAR;
+ {
+ /* force linear subdivision if OpenSubdiv is unavailable to avoid
+ * falling into catmull-clark code paths by accident
+ */
+ subdivision_type = SUBDIVISION_LINEAR;
- /* force disable attribute subdivision for same reason as above */
- foreach(Attribute& attr, subd_attributes.attributes) {
- attr.flags &= ~ATTR_SUBDIVIDED;
- }
- }
+ /* force disable attribute subdivision for same reason as above */
+ foreach (Attribute &attr, subd_attributes.attributes) {
+ attr.flags &= ~ATTR_SUBDIVIDED;
+ }
+ }
- int num_faces = subd_faces.size();
+ int num_faces = subd_faces.size();
- Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL);
- float3* vN = attr_vN->data_float3();
+ Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL);
+ float3 *vN = attr_vN->data_float3();
- for(int f = 0; f < num_faces; f++) {
- SubdFace& face = subd_faces[f];
+ for (int f = 0; f < num_faces; f++) {
+ SubdFace &face = subd_faces[f];
- if(face.is_quad()) {
- /* quad */
- QuadDice::SubPatch subpatch;
+ if (face.is_quad()) {
+ /* quad */
+ QuadDice::SubPatch subpatch;
- LinearQuadPatch quad_patch;
+ LinearQuadPatch quad_patch;
#ifdef WITH_OPENSUBDIV
- OsdPatch osd_patch(&osd_data);
+ OsdPatch osd_patch(&osd_data);
- if(subdivision_type == SUBDIVISION_CATMULL_CLARK) {
- osd_patch.patch_index = face.ptex_offset;
+ if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
+ osd_patch.patch_index = face.ptex_offset;
- subpatch.patch = &osd_patch;
- }
- else
+ subpatch.patch = &osd_patch;
+ }
+ else
#endif
- {
- float3 *hull = quad_patch.hull;
- float3 *normals = quad_patch.normals;
-
- quad_patch.patch_index = face.ptex_offset;
-
- for(int i = 0; i < 4; i++) {
- hull[i] = verts[subd_face_corners[face.start_corner+i]];
- }
-
- if(face.smooth) {
- for(int i = 0; i < 4; i++) {
- normals[i] = vN[subd_face_corners[face.start_corner+i]];
- }
- }
- else {
- float3 N = face.normal(this);
- for(int i = 0; i < 4; i++) {
- normals[i] = N;
- }
- }
-
- swap(hull[2], hull[3]);
- swap(normals[2], normals[3]);
-
- subpatch.patch = &quad_patch;
- }
-
- subpatch.patch->shader = face.shader;
-
- /* Quad faces need to be split at least once to line up with split ngons, we do this
- * here in this manner because if we do it later edge factors may end up slightly off.
- */
- subpatch.P00 = make_float2(0.0f, 0.0f);
- subpatch.P10 = make_float2(0.5f, 0.0f);
- subpatch.P01 = make_float2(0.0f, 0.5f);
- subpatch.P11 = make_float2(0.5f, 0.5f);
- split->split_quad(subpatch.patch, &subpatch);
-
- subpatch.P00 = make_float2(0.5f, 0.0f);
- subpatch.P10 = make_float2(1.0f, 0.0f);
- subpatch.P01 = make_float2(0.5f, 0.5f);
- subpatch.P11 = make_float2(1.0f, 0.5f);
- split->split_quad(subpatch.patch, &subpatch);
-
- subpatch.P00 = make_float2(0.0f, 0.5f);
- subpatch.P10 = make_float2(0.5f, 0.5f);
- subpatch.P01 = make_float2(0.0f, 1.0f);
- subpatch.P11 = make_float2(0.5f, 1.0f);
- split->split_quad(subpatch.patch, &subpatch);
-
- subpatch.P00 = make_float2(0.5f, 0.5f);
- subpatch.P10 = make_float2(1.0f, 0.5f);
- subpatch.P01 = make_float2(0.5f, 1.0f);
- subpatch.P11 = make_float2(1.0f, 1.0f);
- split->split_quad(subpatch.patch, &subpatch);
- }
- else {
- /* ngon */
+ {
+ float3 *hull = quad_patch.hull;
+ float3 *normals = quad_patch.normals;
+
+ quad_patch.patch_index = face.ptex_offset;
+
+ for (int i = 0; i < 4; i++) {
+ hull[i] = verts[subd_face_corners[face.start_corner + i]];
+ }
+
+ if (face.smooth) {
+ for (int i = 0; i < 4; i++) {
+ normals[i] = vN[subd_face_corners[face.start_corner + i]];
+ }
+ }
+ else {
+ float3 N = face.normal(this);
+ for (int i = 0; i < 4; i++) {
+ normals[i] = N;
+ }
+ }
+
+ swap(hull[2], hull[3]);
+ swap(normals[2], normals[3]);
+
+ subpatch.patch = &quad_patch;
+ }
+
+ subpatch.patch->shader = face.shader;
+
+ /* Quad faces need to be split at least once to line up with split ngons, we do this
+ * here in this manner because if we do it later edge factors may end up slightly off.
+ */
+ subpatch.P00 = make_float2(0.0f, 0.0f);
+ subpatch.P10 = make_float2(0.5f, 0.0f);
+ subpatch.P01 = make_float2(0.0f, 0.5f);
+ subpatch.P11 = make_float2(0.5f, 0.5f);
+ split->split_quad(subpatch.patch, &subpatch);
+
+ subpatch.P00 = make_float2(0.5f, 0.0f);
+ subpatch.P10 = make_float2(1.0f, 0.0f);
+ subpatch.P01 = make_float2(0.5f, 0.5f);
+ subpatch.P11 = make_float2(1.0f, 0.5f);
+ split->split_quad(subpatch.patch, &subpatch);
+
+ subpatch.P00 = make_float2(0.0f, 0.5f);
+ subpatch.P10 = make_float2(0.5f, 0.5f);
+ subpatch.P01 = make_float2(0.0f, 1.0f);
+ subpatch.P11 = make_float2(0.5f, 1.0f);
+ split->split_quad(subpatch.patch, &subpatch);
+
+ subpatch.P00 = make_float2(0.5f, 0.5f);
+ subpatch.P10 = make_float2(1.0f, 0.5f);
+ subpatch.P01 = make_float2(0.5f, 1.0f);
+ subpatch.P11 = make_float2(1.0f, 1.0f);
+ split->split_quad(subpatch.patch, &subpatch);
+ }
+ else {
+ /* ngon */
#ifdef WITH_OPENSUBDIV
- if(subdivision_type == SUBDIVISION_CATMULL_CLARK) {
- OsdPatch patch(&osd_data);
+ if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
+ OsdPatch patch(&osd_data);
- patch.shader = face.shader;
+ patch.shader = face.shader;
- for(int corner = 0; corner < face.num_corners; corner++) {
- patch.patch_index = face.ptex_offset + corner;
+ for (int corner = 0; corner < face.num_corners; corner++) {
+ patch.patch_index = face.ptex_offset + corner;
- split->split_quad(&patch);
- }
- }
- else
+ split->split_quad(&patch);
+ }
+ }
+ else
#endif
- {
- float3 center_vert = make_float3(0.0f, 0.0f, 0.0f);
- float3 center_normal = make_float3(0.0f, 0.0f, 0.0f);
-
- float inv_num_corners = 1.0f/float(face.num_corners);
- for(int corner = 0; corner < face.num_corners; corner++) {
- center_vert += verts[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
- center_normal += vN[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
- }
-
- for(int corner = 0; corner < face.num_corners; corner++) {
- LinearQuadPatch patch;
- float3 *hull = patch.hull;
- float3 *normals = patch.normals;
-
- patch.patch_index = face.ptex_offset + corner;
-
- patch.shader = face.shader;
-
- hull[0] = verts[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
- hull[1] = verts[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
- hull[2] = verts[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
- hull[3] = center_vert;
-
- hull[1] = (hull[1] + hull[0]) * 0.5;
- hull[2] = (hull[2] + hull[0]) * 0.5;
-
- if(face.smooth) {
- normals[0] = vN[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
- normals[1] = vN[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
- normals[2] = vN[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
- normals[3] = center_normal;
-
- normals[1] = (normals[1] + normals[0]) * 0.5;
- normals[2] = (normals[2] + normals[0]) * 0.5;
- }
- else {
- float3 N = face.normal(this);
- for(int i = 0; i < 4; i++) {
- normals[i] = N;
- }
- }
-
- split->split_quad(&patch);
- }
- }
- }
- }
-
- /* interpolate center points for attributes */
- foreach(Attribute& attr, subd_attributes.attributes) {
+ {
+ float3 center_vert = make_float3(0.0f, 0.0f, 0.0f);
+ float3 center_normal = make_float3(0.0f, 0.0f, 0.0f);
+
+ float inv_num_corners = 1.0f / float(face.num_corners);
+ for (int corner = 0; corner < face.num_corners; corner++) {
+ center_vert += verts[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
+ center_normal += vN[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
+ }
+
+ for (int corner = 0; corner < face.num_corners; corner++) {
+ LinearQuadPatch patch;
+ float3 *hull = patch.hull;
+ float3 *normals = patch.normals;
+
+ patch.patch_index = face.ptex_offset + corner;
+
+ patch.shader = face.shader;
+
+ hull[0] =
+ verts[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
+ hull[1] =
+ verts[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
+ hull[2] =
+ verts[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
+ hull[3] = center_vert;
+
+ hull[1] = (hull[1] + hull[0]) * 0.5;
+ hull[2] = (hull[2] + hull[0]) * 0.5;
+
+ if (face.smooth) {
+ normals[0] =
+ vN[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
+ normals[1] =
+ vN[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
+ normals[2] =
+ vN[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
+ normals[3] = center_normal;
+
+ normals[1] = (normals[1] + normals[0]) * 0.5;
+ normals[2] = (normals[2] + normals[0]) * 0.5;
+ }
+ else {
+ float3 N = face.normal(this);
+ for (int i = 0; i < 4; i++) {
+ normals[i] = N;
+ }
+ }
+
+ split->split_quad(&patch);
+ }
+ }
+ }
+ }
+
+ /* interpolate center points for attributes */
+ foreach (Attribute &attr, subd_attributes.attributes) {
#ifdef WITH_OPENSUBDIV
- if(subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) {
- if(attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
- /* keep subdivision for corner attributes disabled for now */
- attr.flags &= ~ATTR_SUBDIVIDED;
- }
- else if(subd_faces.size()) {
- osd_data.subdivide_attribute(attr);
-
- need_packed_patch_table = true;
- continue;
- }
- }
+ if (subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) {
+ if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
+ /* keep subdivision for corner attributes disabled for now */
+ attr.flags &= ~ATTR_SUBDIVIDED;
+ }
+ else if (subd_faces.size()) {
+ osd_data.subdivide_attribute(attr);
+
+ need_packed_patch_table = true;
+ continue;
+ }
+ }
#endif
- char* data = attr.data();
- size_t stride = attr.data_sizeof();
- int ngons = 0;
-
- switch(attr.element) {
- case ATTR_ELEMENT_VERTEX: {
- for(int f = 0; f < num_faces; f++) {
- SubdFace& face = subd_faces[f];
-
- if(!face.is_quad()) {
- char* center = data + (verts.size() - num_subd_verts + ngons) * stride;
- attr.zero_data(center);
-
- float inv_num_corners = 1.0f / float(face.num_corners);
-
- for(int corner = 0; corner < face.num_corners; corner++) {
- attr.add_with_weight(center,
- data + subd_face_corners[face.start_corner + corner] * stride,
- inv_num_corners);
- }
-
- ngons++;
- }
- }
- } break;
- case ATTR_ELEMENT_VERTEX_MOTION: {
- // TODO(mai): implement
- } break;
- case ATTR_ELEMENT_CORNER: {
- for(int f = 0; f < num_faces; f++) {
- SubdFace& face = subd_faces[f];
-
- if(!face.is_quad()) {
- char* center = data + (subd_face_corners.size() + ngons) * stride;
- attr.zero_data(center);
-
- float inv_num_corners = 1.0f / float(face.num_corners);
-
- for(int corner = 0; corner < face.num_corners; corner++) {
- attr.add_with_weight(center,
- data + (face.start_corner + corner) * stride,
- inv_num_corners);
- }
-
- ngons++;
- }
- }
- } break;
- case ATTR_ELEMENT_CORNER_BYTE: {
- for(int f = 0; f < num_faces; f++) {
- SubdFace& face = subd_faces[f];
-
- if(!face.is_quad()) {
- uchar* center = (uchar*)data + (subd_face_corners.size() + ngons) * stride;
-
- float inv_num_corners = 1.0f / float(face.num_corners);
- float4 val = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-
- for(int corner = 0; corner < face.num_corners; corner++) {
- for(int i = 0; i < 4; i++) {
- val[i] += float(*(data + (face.start_corner + corner) * stride + i)) * inv_num_corners;
- }
- }
-
- for(int i = 0; i < 4; i++) {
- center[i] = uchar(min(max(val[i], 0.0f), 255.0f));
- }
-
- ngons++;
- }
- }
- } break;
- default: break;
- }
- }
+ char *data = attr.data();
+ size_t stride = attr.data_sizeof();
+ int ngons = 0;
+
+ switch (attr.element) {
+ case ATTR_ELEMENT_VERTEX: {
+ for (int f = 0; f < num_faces; f++) {
+ SubdFace &face = subd_faces[f];
+
+ if (!face.is_quad()) {
+ char *center = data + (verts.size() - num_subd_verts + ngons) * stride;
+ attr.zero_data(center);
+
+ float inv_num_corners = 1.0f / float(face.num_corners);
+
+ for (int corner = 0; corner < face.num_corners; corner++) {
+ attr.add_with_weight(center,
+ data + subd_face_corners[face.start_corner + corner] * stride,
+ inv_num_corners);
+ }
+
+ ngons++;
+ }
+ }
+ } break;
+ case ATTR_ELEMENT_VERTEX_MOTION: {
+ // TODO(mai): implement
+ } break;
+ case ATTR_ELEMENT_CORNER: {
+ for (int f = 0; f < num_faces; f++) {
+ SubdFace &face = subd_faces[f];
+
+ if (!face.is_quad()) {
+ char *center = data + (subd_face_corners.size() + ngons) * stride;
+ attr.zero_data(center);
+
+ float inv_num_corners = 1.0f / float(face.num_corners);
+
+ for (int corner = 0; corner < face.num_corners; corner++) {
+ attr.add_with_weight(
+ center, data + (face.start_corner + corner) * stride, inv_num_corners);
+ }
+
+ ngons++;
+ }
+ }
+ } break;
+ case ATTR_ELEMENT_CORNER_BYTE: {
+ for (int f = 0; f < num_faces; f++) {
+ SubdFace &face = subd_faces[f];
+
+ if (!face.is_quad()) {
+ uchar *center = (uchar *)data + (subd_face_corners.size() + ngons) * stride;
+
+ float inv_num_corners = 1.0f / float(face.num_corners);
+ float4 val = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ for (int corner = 0; corner < face.num_corners; corner++) {
+ for (int i = 0; i < 4; i++) {
+ val[i] += float(*(data + (face.start_corner + corner) * stride + i)) *
+ inv_num_corners;
+ }
+ }
+
+ for (int i = 0; i < 4; i++) {
+ center[i] = uchar(min(max(val[i], 0.0f), 255.0f));
+ }
+
+ ngons++;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+ }
#ifdef WITH_OPENSUBDIV
- /* pack patch tables */
- if(need_packed_patch_table) {
- delete patch_table;
- patch_table = new PackedPatchTable;
- patch_table->pack(osd_data.patch_table);
- }
+ /* pack patch tables */
+ if (need_packed_patch_table) {
+ delete patch_table;
+ patch_table = new PackedPatchTable;
+ patch_table->pack(osd_data.patch_table);
+ }
#endif
}
diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp
index 3ee4124ba0f..a1d61fd4db7 100644
--- a/intern/cycles/render/mesh_volume.cpp
+++ b/intern/cycles/render/mesh_volume.cpp
@@ -27,98 +27,106 @@ CCL_NAMESPACE_BEGIN
static size_t compute_voxel_index(const int3 &resolution, size_t x, size_t y, size_t z)
{
- if(x == -1 || x >= resolution.x) {
- return -1;
- }
+ if (x == -1 || x >= resolution.x) {
+ return -1;
+ }
- if(y == -1 || y >= resolution.y) {
- return -1;
- }
+ if (y == -1 || y >= resolution.y) {
+ return -1;
+ }
- if(z == -1 || z >= resolution.z) {
- return -1;
- }
+ if (z == -1 || z >= resolution.z) {
+ return -1;
+ }
- return x + y*resolution.x + z*resolution.x*resolution.y;
+ return x + y * resolution.x + z * resolution.x * resolution.y;
}
struct QuadData {
- int v0, v1, v2, v3;
+ int v0, v1, v2, v3;
- float3 normal;
+ float3 normal;
};
enum {
- QUAD_X_MIN = 0,
- QUAD_X_MAX = 1,
- QUAD_Y_MIN = 2,
- QUAD_Y_MAX = 3,
- QUAD_Z_MIN = 4,
- QUAD_Z_MAX = 5,
+ QUAD_X_MIN = 0,
+ QUAD_X_MAX = 1,
+ QUAD_Y_MIN = 2,
+ QUAD_Y_MAX = 3,
+ QUAD_Z_MIN = 4,
+ QUAD_Z_MAX = 5,
};
const int quads_indices[6][4] = {
- /* QUAD_X_MIN */
- { 4, 0, 3, 7 },
- /* QUAD_X_MAX */
- { 1, 5, 6, 2 },
- /* QUAD_Y_MIN */
- { 4, 5, 1, 0 },
- /* QUAD_Y_MAX */
- { 3, 2, 6, 7 },
- /* QUAD_Z_MIN */
- { 0, 1, 2, 3 },
- /* QUAD_Z_MAX */
- { 5, 4, 7, 6 },
+ /* QUAD_X_MIN */
+ {4, 0, 3, 7},
+ /* QUAD_X_MAX */
+ {1, 5, 6, 2},
+ /* QUAD_Y_MIN */
+ {4, 5, 1, 0},
+ /* QUAD_Y_MAX */
+ {3, 2, 6, 7},
+ /* QUAD_Z_MIN */
+ {0, 1, 2, 3},
+ /* QUAD_Z_MAX */
+ {5, 4, 7, 6},
};
const float3 quads_normals[6] = {
- /* QUAD_X_MIN */
- make_float3(-1.0f, 0.0f, 0.0f),
- /* QUAD_X_MAX */
- make_float3(1.0f, 0.0f, 0.0f),
- /* QUAD_Y_MIN */
- make_float3(0.0f, -1.0f, 0.0f),
- /* QUAD_Y_MAX */
- make_float3(0.0f, 1.0f, 0.0f),
- /* QUAD_Z_MIN */
- make_float3(0.0f, 0.0f, -1.0f),
- /* QUAD_Z_MAX */
- make_float3(0.0f, 0.0f, 1.0f),
+ /* QUAD_X_MIN */
+ make_float3(-1.0f, 0.0f, 0.0f),
+ /* QUAD_X_MAX */
+ make_float3(1.0f, 0.0f, 0.0f),
+ /* QUAD_Y_MIN */
+ make_float3(0.0f, -1.0f, 0.0f),
+ /* QUAD_Y_MAX */
+ make_float3(0.0f, 1.0f, 0.0f),
+ /* QUAD_Z_MIN */
+ make_float3(0.0f, 0.0f, -1.0f),
+ /* QUAD_Z_MAX */
+ make_float3(0.0f, 0.0f, 1.0f),
};
-static int add_vertex(int3 v, vector<int3> &vertices, int3 res, unordered_map<size_t, int> &used_verts)
+static int add_vertex(int3 v,
+ vector<int3> &vertices,
+ int3 res,
+ unordered_map<size_t, int> &used_verts)
{
- size_t vert_key = v.x + v.y * (res.x+1) + v.z * (res.x+1)*(res.y+1);
- unordered_map<size_t, int>::iterator it = used_verts.find(vert_key);
+ size_t vert_key = v.x + v.y * (res.x + 1) + v.z * (res.x + 1) * (res.y + 1);
+ unordered_map<size_t, int>::iterator it = used_verts.find(vert_key);
- if(it != used_verts.end()) {
- return it->second;
- }
+ if (it != used_verts.end()) {
+ return it->second;
+ }
- int vertex_offset = vertices.size();
- used_verts[vert_key] = vertex_offset;
- vertices.push_back(v);
- return vertex_offset;
+ int vertex_offset = vertices.size();
+ used_verts[vert_key] = vertex_offset;
+ vertices.push_back(v);
+ return vertex_offset;
}
-static void create_quad(int3 corners[8], vector<int3> &vertices, vector<QuadData> &quads, int3 res, unordered_map<size_t, int> &used_verts, int face_index)
+static void create_quad(int3 corners[8],
+ vector<int3> &vertices,
+ vector<QuadData> &quads,
+ int3 res,
+ unordered_map<size_t, int> &used_verts,
+ int face_index)
{
- QuadData quad;
- quad.v0 = add_vertex(corners[quads_indices[face_index][0]], vertices, res, used_verts);
- quad.v1 = add_vertex(corners[quads_indices[face_index][1]], vertices, res, used_verts);
- quad.v2 = add_vertex(corners[quads_indices[face_index][2]], vertices, res, used_verts);
- quad.v3 = add_vertex(corners[quads_indices[face_index][3]], vertices, res, used_verts);
- quad.normal = quads_normals[face_index];
-
- quads.push_back(quad);
+ QuadData quad;
+ quad.v0 = add_vertex(corners[quads_indices[face_index][0]], vertices, res, used_verts);
+ quad.v1 = add_vertex(corners[quads_indices[face_index][1]], vertices, res, used_verts);
+ quad.v2 = add_vertex(corners[quads_indices[face_index][2]], vertices, res, used_verts);
+ quad.v3 = add_vertex(corners[quads_indices[face_index][3]], vertices, res, used_verts);
+ quad.normal = quads_normals[face_index];
+
+ quads.push_back(quad);
}
struct VolumeParams {
- int3 resolution;
- float3 cell_size;
- float3 start_point;
- int pad_size;
+ int3 resolution;
+ float3 cell_size;
+ float3 start_point;
+ int pad_size;
};
static const int CUBE_SIZE = 8;
@@ -135,373 +143,365 @@ static const int CUBE_SIZE = 8;
* volume to generate a tight mesh around the volume.
*/
class VolumeMeshBuilder {
- /* Auxilliary volume that is used to check if a node already added. */
- vector<char> grid;
+ /* Auxilliary volume that is used to check if a node already added. */
+ vector<char> grid;
- /* The resolution of the auxilliary volume, set to be equal to 1/CUBE_SIZE
- * of the original volume on each axis. */
- int3 res;
+ /* The resolution of the auxilliary volume, set to be equal to 1/CUBE_SIZE
+ * of the original volume on each axis. */
+ int3 res;
- size_t number_of_nodes;
+ size_t number_of_nodes;
- /* Offset due to padding in the original grid. Padding will transform the
- * coordinates of the original grid from 0...res to -padding...res+padding,
- * so some coordinates are negative, and we need to properly account for
- * them. */
- int3 pad_offset;
+ /* Offset due to padding in the original grid. Padding will transform the
+ * coordinates of the original grid from 0...res to -padding...res+padding,
+ * so some coordinates are negative, and we need to properly account for
+ * them. */
+ int3 pad_offset;
- VolumeParams *params;
+ VolumeParams *params;
-public:
- VolumeMeshBuilder(VolumeParams *volume_params);
+ public:
+ VolumeMeshBuilder(VolumeParams *volume_params);
- void add_node(int x, int y, int z);
+ void add_node(int x, int y, int z);
- void add_node_with_padding(int x, int y, int z);
+ void add_node_with_padding(int x, int y, int z);
- void create_mesh(vector<float3> &vertices,
- vector<int> &indices,
- vector<float3> &face_normals);
+ void create_mesh(vector<float3> &vertices, vector<int> &indices, vector<float3> &face_normals);
-private:
- void generate_vertices_and_quads(vector<int3> &vertices_is,
- vector<QuadData> &quads);
+ private:
+ void generate_vertices_and_quads(vector<int3> &vertices_is, vector<QuadData> &quads);
- void convert_object_space(const vector<int3> &vertices,
- vector<float3> &out_vertices);
+ void convert_object_space(const vector<int3> &vertices, vector<float3> &out_vertices);
- void convert_quads_to_tris(const vector<QuadData> &quads,
- vector<int> &tris,
- vector<float3> &face_normals);
+ void convert_quads_to_tris(const vector<QuadData> &quads,
+ vector<int> &tris,
+ vector<float3> &face_normals);
};
VolumeMeshBuilder::VolumeMeshBuilder(VolumeParams *volume_params)
{
- params = volume_params;
- number_of_nodes = 0;
+ params = volume_params;
+ number_of_nodes = 0;
- const size_t x = divide_up(params->resolution.x, CUBE_SIZE);
- const size_t y = divide_up(params->resolution.y, CUBE_SIZE);
- const size_t z = divide_up(params->resolution.z, CUBE_SIZE);
+ const size_t x = divide_up(params->resolution.x, CUBE_SIZE);
+ const size_t y = divide_up(params->resolution.y, CUBE_SIZE);
+ const size_t z = divide_up(params->resolution.z, CUBE_SIZE);
- /* Adding 2*pad_size since we pad in both positive and negative directions
- * along the axis. */
- const size_t px = divide_up(params->resolution.x + 2*params->pad_size, CUBE_SIZE);
- const size_t py = divide_up(params->resolution.y + 2*params->pad_size, CUBE_SIZE);
- const size_t pz = divide_up(params->resolution.z + 2*params->pad_size, CUBE_SIZE);
+ /* Adding 2*pad_size since we pad in both positive and negative directions
+ * along the axis. */
+ const size_t px = divide_up(params->resolution.x + 2 * params->pad_size, CUBE_SIZE);
+ const size_t py = divide_up(params->resolution.y + 2 * params->pad_size, CUBE_SIZE);
+ const size_t pz = divide_up(params->resolution.z + 2 * params->pad_size, CUBE_SIZE);
- res = make_int3(px, py, pz);
- pad_offset = make_int3(px - x, py - y, pz - z);
+ res = make_int3(px, py, pz);
+ pad_offset = make_int3(px - x, py - y, pz - z);
- grid.resize(px*py*pz, 0);
+ grid.resize(px * py * pz, 0);
}
void VolumeMeshBuilder::add_node(int x, int y, int z)
{
- /* Map coordinates to index space. */
- const int index_x = (x/CUBE_SIZE) + pad_offset.x;
- const int index_y = (y/CUBE_SIZE) + pad_offset.y;
- const int index_z = (z/CUBE_SIZE) + pad_offset.z;
+ /* Map coordinates to index space. */
+ const int index_x = (x / CUBE_SIZE) + pad_offset.x;
+ const int index_y = (y / CUBE_SIZE) + pad_offset.y;
+ const int index_z = (z / CUBE_SIZE) + pad_offset.z;
- assert((index_x >= 0) && (index_y >= 0) && (index_z >= 0));
+ assert((index_x >= 0) && (index_y >= 0) && (index_z >= 0));
- const size_t index = compute_voxel_index(res, index_x, index_y, index_z);
+ const size_t index = compute_voxel_index(res, index_x, index_y, index_z);
- /* We already have a node here. */
- if(grid[index] == 1) {
- return;
- }
+ /* We already have a node here. */
+ if (grid[index] == 1) {
+ return;
+ }
- ++number_of_nodes;
+ ++number_of_nodes;
- grid[index] = 1;
+ grid[index] = 1;
}
void VolumeMeshBuilder::add_node_with_padding(int x, int y, int z)
{
- for(int px = x - params->pad_size; px < x + params->pad_size; ++px) {
- for(int py = y - params->pad_size; py < y + params->pad_size; ++py) {
- for(int pz = z - params->pad_size; pz < z + params->pad_size; ++pz) {
- add_node(px, py, pz);
- }
- }
- }
+ for (int px = x - params->pad_size; px < x + params->pad_size; ++px) {
+ for (int py = y - params->pad_size; py < y + params->pad_size; ++py) {
+ for (int pz = z - params->pad_size; pz < z + params->pad_size; ++pz) {
+ add_node(px, py, pz);
+ }
+ }
+ }
}
void VolumeMeshBuilder::create_mesh(vector<float3> &vertices,
vector<int> &indices,
vector<float3> &face_normals)
{
- /* We create vertices in index space (is), and only convert them to object
- * space when done. */
- vector<int3> vertices_is;
- vector<QuadData> quads;
+ /* We create vertices in index space (is), and only convert them to object
+ * space when done. */
+ vector<int3> vertices_is;
+ vector<QuadData> quads;
- generate_vertices_and_quads(vertices_is, quads);
+ generate_vertices_and_quads(vertices_is, quads);
- convert_object_space(vertices_is, vertices);
+ convert_object_space(vertices_is, vertices);
- convert_quads_to_tris(quads, indices, face_normals);
+ convert_quads_to_tris(quads, indices, face_normals);
}
-void VolumeMeshBuilder::generate_vertices_and_quads(
- vector<ccl::int3> &vertices_is,
- vector<QuadData> &quads)
+void VolumeMeshBuilder::generate_vertices_and_quads(vector<ccl::int3> &vertices_is,
+ vector<QuadData> &quads)
{
- unordered_map<size_t, int> used_verts;
-
- for(int z = 0; z < res.z; ++z) {
- for(int y = 0; y < res.y; ++y) {
- for(int x = 0; x < res.x; ++x) {
- size_t voxel_index = compute_voxel_index(res, x, y, z);
- if(grid[voxel_index] == 0) {
- continue;
- }
-
- /* Compute min and max coords of the node in index space. */
- int3 min = make_int3((x - pad_offset.x)*CUBE_SIZE,
- (y - pad_offset.y)*CUBE_SIZE,
- (z - pad_offset.z)*CUBE_SIZE);
-
- /* Maximum is just CUBE_SIZE voxels away from minimum on each axis. */
- int3 max = make_int3(min.x + CUBE_SIZE, min.y + CUBE_SIZE, min.z + CUBE_SIZE);
-
- int3 corners[8] = {
- make_int3(min[0], min[1], min[2]),
- make_int3(max[0], min[1], min[2]),
- make_int3(max[0], max[1], min[2]),
- make_int3(min[0], max[1], min[2]),
- make_int3(min[0], min[1], max[2]),
- make_int3(max[0], min[1], max[2]),
- make_int3(max[0], max[1], max[2]),
- make_int3(min[0], max[1], max[2]),
- };
-
- /* Only create a quad if on the border between an active and
- * an inactive node.
- */
-
- voxel_index = compute_voxel_index(res, x - 1, y, z);
- if(voxel_index == -1 || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MIN);
- }
-
- voxel_index = compute_voxel_index(res, x + 1, y, z);
- if(voxel_index == -1 || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MAX);
- }
-
- voxel_index = compute_voxel_index(res, x, y - 1, z);
- if(voxel_index == -1 || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MIN);
- }
-
- voxel_index = compute_voxel_index(res, x, y + 1, z);
- if(voxel_index == -1 || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MAX);
- }
-
- voxel_index = compute_voxel_index(res, x, y, z - 1);
- if(voxel_index == -1 || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MIN);
- }
-
- voxel_index = compute_voxel_index(res, x, y, z + 1);
- if(voxel_index == -1 || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MAX);
- }
- }
- }
- }
+ unordered_map<size_t, int> used_verts;
+
+ for (int z = 0; z < res.z; ++z) {
+ for (int y = 0; y < res.y; ++y) {
+ for (int x = 0; x < res.x; ++x) {
+ size_t voxel_index = compute_voxel_index(res, x, y, z);
+ if (grid[voxel_index] == 0) {
+ continue;
+ }
+
+ /* Compute min and max coords of the node in index space. */
+ int3 min = make_int3((x - pad_offset.x) * CUBE_SIZE,
+ (y - pad_offset.y) * CUBE_SIZE,
+ (z - pad_offset.z) * CUBE_SIZE);
+
+ /* Maximum is just CUBE_SIZE voxels away from minimum on each axis. */
+ int3 max = make_int3(min.x + CUBE_SIZE, min.y + CUBE_SIZE, min.z + CUBE_SIZE);
+
+ int3 corners[8] = {
+ make_int3(min[0], min[1], min[2]),
+ make_int3(max[0], min[1], min[2]),
+ make_int3(max[0], max[1], min[2]),
+ make_int3(min[0], max[1], min[2]),
+ make_int3(min[0], min[1], max[2]),
+ make_int3(max[0], min[1], max[2]),
+ make_int3(max[0], max[1], max[2]),
+ make_int3(min[0], max[1], max[2]),
+ };
+
+ /* Only create a quad if on the border between an active and
+ * an inactive node.
+ */
+
+ voxel_index = compute_voxel_index(res, x - 1, y, z);
+ if (voxel_index == -1 || grid[voxel_index] == 0) {
+ create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MIN);
+ }
+
+ voxel_index = compute_voxel_index(res, x + 1, y, z);
+ if (voxel_index == -1 || grid[voxel_index] == 0) {
+ create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MAX);
+ }
+
+ voxel_index = compute_voxel_index(res, x, y - 1, z);
+ if (voxel_index == -1 || grid[voxel_index] == 0) {
+ create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MIN);
+ }
+
+ voxel_index = compute_voxel_index(res, x, y + 1, z);
+ if (voxel_index == -1 || grid[voxel_index] == 0) {
+ create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MAX);
+ }
+
+ voxel_index = compute_voxel_index(res, x, y, z - 1);
+ if (voxel_index == -1 || grid[voxel_index] == 0) {
+ create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MIN);
+ }
+
+ voxel_index = compute_voxel_index(res, x, y, z + 1);
+ if (voxel_index == -1 || grid[voxel_index] == 0) {
+ create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MAX);
+ }
+ }
+ }
+ }
}
void VolumeMeshBuilder::convert_object_space(const vector<int3> &vertices,
- vector<float3> &out_vertices)
+ vector<float3> &out_vertices)
{
- out_vertices.reserve(vertices.size());
+ out_vertices.reserve(vertices.size());
- for(size_t i = 0; i < vertices.size(); ++i) {
- float3 vertex = make_float3(vertices[i].x, vertices[i].y, vertices[i].z);
- vertex *= params->cell_size;
- vertex += params->start_point;
+ for (size_t i = 0; i < vertices.size(); ++i) {
+ float3 vertex = make_float3(vertices[i].x, vertices[i].y, vertices[i].z);
+ vertex *= params->cell_size;
+ vertex += params->start_point;
- out_vertices.push_back(vertex);
- }
+ out_vertices.push_back(vertex);
+ }
}
void VolumeMeshBuilder::convert_quads_to_tris(const vector<QuadData> &quads,
vector<int> &tris,
vector<float3> &face_normals)
{
- int index_offset = 0;
- tris.resize(quads.size()*6);
- face_normals.reserve(quads.size()*2);
+ int index_offset = 0;
+ tris.resize(quads.size() * 6);
+ face_normals.reserve(quads.size() * 2);
- for(size_t i = 0; i < quads.size(); ++i) {
- tris[index_offset++] = quads[i].v0;
- tris[index_offset++] = quads[i].v2;
- tris[index_offset++] = quads[i].v1;
+ for (size_t i = 0; i < quads.size(); ++i) {
+ tris[index_offset++] = quads[i].v0;
+ tris[index_offset++] = quads[i].v2;
+ tris[index_offset++] = quads[i].v1;
- face_normals.push_back(quads[i].normal);
+ face_normals.push_back(quads[i].normal);
- tris[index_offset++] = quads[i].v0;
- tris[index_offset++] = quads[i].v3;
- tris[index_offset++] = quads[i].v2;
+ tris[index_offset++] = quads[i].v0;
+ tris[index_offset++] = quads[i].v3;
+ tris[index_offset++] = quads[i].v2;
- face_normals.push_back(quads[i].normal);
- }
+ face_normals.push_back(quads[i].normal);
+ }
}
/* ************************************************************************** */
struct VoxelAttributeGrid {
- float *data;
- int channels;
+ float *data;
+ int channels;
};
-void MeshManager::create_volume_mesh(Scene *scene,
- Mesh *mesh,
- Progress& progress)
+void MeshManager::create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress)
{
- string msg = string_printf("Computing Volume Mesh %s", mesh->name.c_str());
- progress.set_status("Updating Mesh", msg);
-
- vector<VoxelAttributeGrid> voxel_grids;
-
- /* Compute volume parameters. */
- VolumeParams volume_params;
- volume_params.resolution = make_int3(0, 0, 0);
-
- foreach(Attribute& attr, mesh->attributes.attributes) {
- if(attr.element != ATTR_ELEMENT_VOXEL) {
- continue;
- }
-
- VoxelAttribute *voxel = attr.data_voxel();
- device_memory *image_memory = scene->image_manager->image_memory(voxel->slot);
- int3 resolution = make_int3(image_memory->data_width,
- image_memory->data_height,
- image_memory->data_depth);
-
- if(volume_params.resolution == make_int3(0, 0, 0)) {
- volume_params.resolution = resolution;
- }
- else if(volume_params.resolution != resolution) {
- VLOG(1) << "Can't create volume mesh, all voxel grid resolutions must be equal\n";
- return;
- }
-
- VoxelAttributeGrid voxel_grid;
- voxel_grid.data = static_cast<float*>(image_memory->host_pointer);
- voxel_grid.channels = image_memory->data_elements;
- voxel_grids.push_back(voxel_grid);
- }
-
- if(voxel_grids.empty()) {
- return;
- }
-
- /* Compute padding. */
- Shader *volume_shader = NULL;
- int pad_size = 0;
-
- foreach(Shader *shader, mesh->used_shaders) {
- if(!shader->has_volume) {
- continue;
- }
-
- volume_shader = shader;
-
- if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) {
- pad_size = max(1, pad_size);
- }
- else if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) {
- pad_size = max(2, pad_size);
- }
-
- break;
- }
-
- if(!volume_shader) {
- return;
- }
-
- /* Compute start point and cell size from transform. */
- Attribute *attr = mesh->attributes.find(ATTR_STD_GENERATED_TRANSFORM);
- const int3 resolution = volume_params.resolution;
- float3 start_point = make_float3(0.0f, 0.0f, 0.0f);
- float3 cell_size = make_float3(1.0f/resolution.x,
- 1.0f/resolution.y,
- 1.0f/resolution.z);
-
- if(attr) {
- const Transform *tfm = attr->data_transform();
- const Transform itfm = transform_inverse(*tfm);
- start_point = transform_point(&itfm, start_point);
- cell_size = transform_direction(&itfm, cell_size);
- }
-
- volume_params.start_point = start_point;
- volume_params.cell_size = cell_size;
- volume_params.pad_size = pad_size;
-
- /* Build bounding mesh around non-empty volume cells. */
- VolumeMeshBuilder builder(&volume_params);
- const float isovalue = mesh->volume_isovalue;
-
- for(int z = 0; z < resolution.z; ++z) {
- for(int y = 0; y < resolution.y; ++y) {
- for(int x = 0; x < resolution.x; ++x) {
- size_t voxel_index = compute_voxel_index(resolution, x, y, z);
-
- for(size_t i = 0; i < voxel_grids.size(); ++i) {
- const VoxelAttributeGrid &voxel_grid = voxel_grids[i];
- const int channels = voxel_grid.channels;
-
- for(int c = 0; c < channels; c++) {
- if(voxel_grid.data[voxel_index * channels + c] >= isovalue) {
- builder.add_node_with_padding(x, y, z);
- break;
- }
- }
- }
- }
- }
- }
-
- /* Create mesh. */
- vector<float3> vertices;
- vector<int> indices;
- vector<float3> face_normals;
- builder.create_mesh(vertices, indices, face_normals);
-
- mesh->clear(true);
- mesh->reserve_mesh(vertices.size(), indices.size()/3);
- mesh->used_shaders.push_back(volume_shader);
-
- for(size_t i = 0; i < vertices.size(); ++i) {
- mesh->add_vertex(vertices[i]);
- }
-
- for(size_t i = 0; i < indices.size(); i += 3) {
- mesh->add_triangle(indices[i], indices[i + 1], indices[i + 2], 0, false);
- }
-
- Attribute *attr_fN = mesh->attributes.add(ATTR_STD_FACE_NORMAL);
- float3 *fN = attr_fN->data_float3();
-
- for(size_t i = 0; i < face_normals.size(); ++i) {
- fN[i] = face_normals[i];
- }
-
- /* Print stats. */
- VLOG(1) << "Memory usage volume mesh: "
- << ((vertices.size() + face_normals.size())*sizeof(float3) + indices.size()*sizeof(int))/(1024.0*1024.0)
- << "Mb.";
-
- VLOG(1) << "Memory usage volume grid: "
- << (resolution.x*resolution.y*resolution.z*sizeof(float))/(1024.0*1024.0)
- << "Mb.";
+ string msg = string_printf("Computing Volume Mesh %s", mesh->name.c_str());
+ progress.set_status("Updating Mesh", msg);
+
+ vector<VoxelAttributeGrid> voxel_grids;
+
+ /* Compute volume parameters. */
+ VolumeParams volume_params;
+ volume_params.resolution = make_int3(0, 0, 0);
+
+ foreach (Attribute &attr, mesh->attributes.attributes) {
+ if (attr.element != ATTR_ELEMENT_VOXEL) {
+ continue;
+ }
+
+ VoxelAttribute *voxel = attr.data_voxel();
+ device_memory *image_memory = scene->image_manager->image_memory(voxel->slot);
+ int3 resolution = make_int3(
+ image_memory->data_width, image_memory->data_height, image_memory->data_depth);
+
+ if (volume_params.resolution == make_int3(0, 0, 0)) {
+ volume_params.resolution = resolution;
+ }
+ else if (volume_params.resolution != resolution) {
+ VLOG(1) << "Can't create volume mesh, all voxel grid resolutions must be equal\n";
+ return;
+ }
+
+ VoxelAttributeGrid voxel_grid;
+ voxel_grid.data = static_cast<float *>(image_memory->host_pointer);
+ voxel_grid.channels = image_memory->data_elements;
+ voxel_grids.push_back(voxel_grid);
+ }
+
+ if (voxel_grids.empty()) {
+ return;
+ }
+
+ /* Compute padding. */
+ Shader *volume_shader = NULL;
+ int pad_size = 0;
+
+ foreach (Shader *shader, mesh->used_shaders) {
+ if (!shader->has_volume) {
+ continue;
+ }
+
+ volume_shader = shader;
+
+ if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) {
+ pad_size = max(1, pad_size);
+ }
+ else if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) {
+ pad_size = max(2, pad_size);
+ }
+
+ break;
+ }
+
+ if (!volume_shader) {
+ return;
+ }
+
+ /* Compute start point and cell size from transform. */
+ Attribute *attr = mesh->attributes.find(ATTR_STD_GENERATED_TRANSFORM);
+ const int3 resolution = volume_params.resolution;
+ float3 start_point = make_float3(0.0f, 0.0f, 0.0f);
+ float3 cell_size = make_float3(1.0f / resolution.x, 1.0f / resolution.y, 1.0f / resolution.z);
+
+ if (attr) {
+ const Transform *tfm = attr->data_transform();
+ const Transform itfm = transform_inverse(*tfm);
+ start_point = transform_point(&itfm, start_point);
+ cell_size = transform_direction(&itfm, cell_size);
+ }
+
+ volume_params.start_point = start_point;
+ volume_params.cell_size = cell_size;
+ volume_params.pad_size = pad_size;
+
+ /* Build bounding mesh around non-empty volume cells. */
+ VolumeMeshBuilder builder(&volume_params);
+ const float isovalue = mesh->volume_isovalue;
+
+ for (int z = 0; z < resolution.z; ++z) {
+ for (int y = 0; y < resolution.y; ++y) {
+ for (int x = 0; x < resolution.x; ++x) {
+ size_t voxel_index = compute_voxel_index(resolution, x, y, z);
+
+ for (size_t i = 0; i < voxel_grids.size(); ++i) {
+ const VoxelAttributeGrid &voxel_grid = voxel_grids[i];
+ const int channels = voxel_grid.channels;
+
+ for (int c = 0; c < channels; c++) {
+ if (voxel_grid.data[voxel_index * channels + c] >= isovalue) {
+ builder.add_node_with_padding(x, y, z);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Create mesh. */
+ vector<float3> vertices;
+ vector<int> indices;
+ vector<float3> face_normals;
+ builder.create_mesh(vertices, indices, face_normals);
+
+ mesh->clear(true);
+ mesh->reserve_mesh(vertices.size(), indices.size() / 3);
+ mesh->used_shaders.push_back(volume_shader);
+
+ for (size_t i = 0; i < vertices.size(); ++i) {
+ mesh->add_vertex(vertices[i]);
+ }
+
+ for (size_t i = 0; i < indices.size(); i += 3) {
+ mesh->add_triangle(indices[i], indices[i + 1], indices[i + 2], 0, false);
+ }
+
+ Attribute *attr_fN = mesh->attributes.add(ATTR_STD_FACE_NORMAL);
+ float3 *fN = attr_fN->data_float3();
+
+ for (size_t i = 0; i < face_normals.size(); ++i) {
+ fN[i] = face_normals[i];
+ }
+
+ /* Print stats. */
+ VLOG(1) << "Memory usage volume mesh: "
+ << ((vertices.size() + face_normals.size()) * sizeof(float3) +
+ indices.size() * sizeof(int)) /
+ (1024.0 * 1024.0)
+ << "Mb.";
+
+ VLOG(1) << "Memory usage volume grid: "
+ << (resolution.x * resolution.y * resolution.z * sizeof(float)) / (1024.0 * 1024.0)
+ << "Mb.";
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index cc9dd8f2679..f3572ee1585 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -37,36 +37,36 @@ CCL_NAMESPACE_BEGIN
/* Texture Mapping */
#define TEXTURE_MAPPING_DEFINE(TextureNode) \
- SOCKET_POINT(tex_mapping.translation, "Translation", make_float3(0.0f, 0.0f, 0.0f)); \
- SOCKET_VECTOR(tex_mapping.rotation, "Rotation", make_float3(0.0f, 0.0f, 0.0f)); \
- SOCKET_VECTOR(tex_mapping.scale, "Scale", make_float3(1.0f, 1.0f, 1.0f)); \
- \
- SOCKET_VECTOR(tex_mapping.min, "Min", make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX)); \
- SOCKET_VECTOR(tex_mapping.max, "Max", make_float3(FLT_MAX, FLT_MAX, FLT_MAX)); \
- SOCKET_BOOLEAN(tex_mapping.use_minmax, "Use Min Max", false); \
- \
- static NodeEnum mapping_axis_enum; \
- mapping_axis_enum.insert("none", TextureMapping::NONE); \
- mapping_axis_enum.insert("x", TextureMapping::X); \
- mapping_axis_enum.insert("y", TextureMapping::Y); \
- mapping_axis_enum.insert("z", TextureMapping::Z); \
- SOCKET_ENUM(tex_mapping.x_mapping, "x_mapping", mapping_axis_enum, TextureMapping::X); \
- SOCKET_ENUM(tex_mapping.y_mapping, "y_mapping", mapping_axis_enum, TextureMapping::Y); \
- SOCKET_ENUM(tex_mapping.z_mapping, "z_mapping", mapping_axis_enum, TextureMapping::Z); \
- \
- static NodeEnum mapping_type_enum; \
- mapping_type_enum.insert("point", TextureMapping::POINT); \
- mapping_type_enum.insert("texture", TextureMapping::TEXTURE); \
- mapping_type_enum.insert("vector", TextureMapping::VECTOR); \
- mapping_type_enum.insert("normal", TextureMapping::NORMAL); \
- SOCKET_ENUM(tex_mapping.type, "Type", mapping_type_enum, TextureMapping::TEXTURE); \
- \
- static NodeEnum mapping_projection_enum; \
- mapping_projection_enum.insert("flat", TextureMapping::FLAT); \
- mapping_projection_enum.insert("cube", TextureMapping::CUBE); \
- mapping_projection_enum.insert("tube", TextureMapping::TUBE); \
- mapping_projection_enum.insert("sphere", TextureMapping::SPHERE); \
- SOCKET_ENUM(tex_mapping.projection, "Projection", mapping_projection_enum, TextureMapping::FLAT);
+ SOCKET_POINT(tex_mapping.translation, "Translation", make_float3(0.0f, 0.0f, 0.0f)); \
+ SOCKET_VECTOR(tex_mapping.rotation, "Rotation", make_float3(0.0f, 0.0f, 0.0f)); \
+ SOCKET_VECTOR(tex_mapping.scale, "Scale", make_float3(1.0f, 1.0f, 1.0f)); \
+\
+ SOCKET_VECTOR(tex_mapping.min, "Min", make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX)); \
+ SOCKET_VECTOR(tex_mapping.max, "Max", make_float3(FLT_MAX, FLT_MAX, FLT_MAX)); \
+ SOCKET_BOOLEAN(tex_mapping.use_minmax, "Use Min Max", false); \
+\
+ static NodeEnum mapping_axis_enum; \
+ mapping_axis_enum.insert("none", TextureMapping::NONE); \
+ mapping_axis_enum.insert("x", TextureMapping::X); \
+ mapping_axis_enum.insert("y", TextureMapping::Y); \
+ mapping_axis_enum.insert("z", TextureMapping::Z); \
+ SOCKET_ENUM(tex_mapping.x_mapping, "x_mapping", mapping_axis_enum, TextureMapping::X); \
+ SOCKET_ENUM(tex_mapping.y_mapping, "y_mapping", mapping_axis_enum, TextureMapping::Y); \
+ SOCKET_ENUM(tex_mapping.z_mapping, "z_mapping", mapping_axis_enum, TextureMapping::Z); \
+\
+ static NodeEnum mapping_type_enum; \
+ mapping_type_enum.insert("point", TextureMapping::POINT); \
+ mapping_type_enum.insert("texture", TextureMapping::TEXTURE); \
+ mapping_type_enum.insert("vector", TextureMapping::VECTOR); \
+ mapping_type_enum.insert("normal", TextureMapping::NORMAL); \
+ SOCKET_ENUM(tex_mapping.type, "Type", mapping_type_enum, TextureMapping::TEXTURE); \
+\
+ static NodeEnum mapping_projection_enum; \
+ mapping_projection_enum.insert("flat", TextureMapping::FLAT); \
+ mapping_projection_enum.insert("cube", TextureMapping::CUBE); \
+ mapping_projection_enum.insert("tube", TextureMapping::TUBE); \
+ mapping_projection_enum.insert("sphere", TextureMapping::SPHERE); \
+ SOCKET_ENUM(tex_mapping.projection, "Projection", mapping_projection_enum, TextureMapping::FLAT);
TextureMapping::TextureMapping()
{
@@ -74,6146 +74,6096 @@ TextureMapping::TextureMapping()
Transform TextureMapping::compute_transform()
{
- Transform mmat = transform_scale(make_float3(0.0f, 0.0f, 0.0f));
-
- if(x_mapping != NONE)
- mmat[0][x_mapping-1] = 1.0f;
- if(y_mapping != NONE)
- mmat[1][y_mapping-1] = 1.0f;
- if(z_mapping != NONE)
- mmat[2][z_mapping-1] = 1.0f;
-
- float3 scale_clamped = scale;
-
- if(type == TEXTURE || type == NORMAL) {
- /* keep matrix invertible */
- if(fabsf(scale.x) < 1e-5f)
- scale_clamped.x = signf(scale.x)*1e-5f;
- if(fabsf(scale.y) < 1e-5f)
- scale_clamped.y = signf(scale.y)*1e-5f;
- if(fabsf(scale.z) < 1e-5f)
- scale_clamped.z = signf(scale.z)*1e-5f;
- }
-
- Transform smat = transform_scale(scale_clamped);
- Transform rmat = transform_euler(rotation);
- Transform tmat = transform_translate(translation);
-
- Transform mat;
-
- switch(type) {
- case TEXTURE:
- /* inverse transform on texture coordinate gives
- * forward transform on texture */
- mat = tmat*rmat*smat;
- mat = transform_inverse(mat);
- break;
- case POINT:
- /* full transform */
- mat = tmat*rmat*smat;
- break;
- case VECTOR:
- /* no translation for vectors */
- mat = rmat*smat;
- break;
- case NORMAL:
- /* no translation for normals, and inverse transpose */
- mat = rmat*smat;
- mat = transform_transposed_inverse(mat);
- break;
- }
-
- /* projection last */
- mat = mat*mmat;
-
- return mat;
+ Transform mmat = transform_scale(make_float3(0.0f, 0.0f, 0.0f));
+
+ if (x_mapping != NONE)
+ mmat[0][x_mapping - 1] = 1.0f;
+ if (y_mapping != NONE)
+ mmat[1][y_mapping - 1] = 1.0f;
+ if (z_mapping != NONE)
+ mmat[2][z_mapping - 1] = 1.0f;
+
+ float3 scale_clamped = scale;
+
+ if (type == TEXTURE || type == NORMAL) {
+ /* keep matrix invertible */
+ if (fabsf(scale.x) < 1e-5f)
+ scale_clamped.x = signf(scale.x) * 1e-5f;
+ if (fabsf(scale.y) < 1e-5f)
+ scale_clamped.y = signf(scale.y) * 1e-5f;
+ if (fabsf(scale.z) < 1e-5f)
+ scale_clamped.z = signf(scale.z) * 1e-5f;
+ }
+
+ Transform smat = transform_scale(scale_clamped);
+ Transform rmat = transform_euler(rotation);
+ Transform tmat = transform_translate(translation);
+
+ Transform mat;
+
+ switch (type) {
+ case TEXTURE:
+ /* inverse transform on texture coordinate gives
+ * forward transform on texture */
+ mat = tmat * rmat * smat;
+ mat = transform_inverse(mat);
+ break;
+ case POINT:
+ /* full transform */
+ mat = tmat * rmat * smat;
+ break;
+ case VECTOR:
+ /* no translation for vectors */
+ mat = rmat * smat;
+ break;
+ case NORMAL:
+ /* no translation for normals, and inverse transpose */
+ mat = rmat * smat;
+ mat = transform_transposed_inverse(mat);
+ break;
+ }
+
+ /* projection last */
+ mat = mat * mmat;
+
+ return mat;
}
bool TextureMapping::skip()
{
- if(translation != make_float3(0.0f, 0.0f, 0.0f))
- return false;
- if(rotation != make_float3(0.0f, 0.0f, 0.0f))
- return false;
- if(scale != make_float3(1.0f, 1.0f, 1.0f))
- return false;
+ if (translation != make_float3(0.0f, 0.0f, 0.0f))
+ return false;
+ if (rotation != make_float3(0.0f, 0.0f, 0.0f))
+ return false;
+ if (scale != make_float3(1.0f, 1.0f, 1.0f))
+ return false;
- if(x_mapping != X || y_mapping != Y || z_mapping != Z)
- return false;
- if(use_minmax)
- return false;
+ if (x_mapping != X || y_mapping != Y || z_mapping != Z)
+ return false;
+ if (use_minmax)
+ return false;
- return true;
+ return true;
}
-void TextureMapping::compile(SVMCompiler& compiler, int offset_in, int offset_out)
+void TextureMapping::compile(SVMCompiler &compiler, int offset_in, int offset_out)
{
- compiler.add_node(NODE_MAPPING, offset_in, offset_out);
+ compiler.add_node(NODE_MAPPING, offset_in, offset_out);
- Transform tfm = compute_transform();
- compiler.add_node(tfm.x);
- compiler.add_node(tfm.y);
- compiler.add_node(tfm.z);
+ Transform tfm = compute_transform();
+ compiler.add_node(tfm.x);
+ compiler.add_node(tfm.y);
+ compiler.add_node(tfm.z);
- if(use_minmax) {
- compiler.add_node(NODE_MIN_MAX, offset_out, offset_out);
- compiler.add_node(float3_to_float4(min));
- compiler.add_node(float3_to_float4(max));
- }
+ if (use_minmax) {
+ compiler.add_node(NODE_MIN_MAX, offset_out, offset_out);
+ compiler.add_node(float3_to_float4(min));
+ compiler.add_node(float3_to_float4(max));
+ }
- if(type == NORMAL) {
- compiler.add_node(NODE_VECTOR_MATH, NODE_VECTOR_MATH_NORMALIZE, offset_out, offset_out);
- compiler.add_node(NODE_VECTOR_MATH, SVM_STACK_INVALID, offset_out);
- }
+ if (type == NORMAL) {
+ compiler.add_node(NODE_VECTOR_MATH, NODE_VECTOR_MATH_NORMALIZE, offset_out, offset_out);
+ compiler.add_node(NODE_VECTOR_MATH, SVM_STACK_INVALID, offset_out);
+ }
}
/* Convenience function for texture nodes, allocating stack space to output
* a modified vector and returning its offset */
-int TextureMapping::compile_begin(SVMCompiler& compiler, ShaderInput *vector_in)
+int TextureMapping::compile_begin(SVMCompiler &compiler, ShaderInput *vector_in)
{
- if(!skip()) {
- int offset_in = compiler.stack_assign(vector_in);
- int offset_out = compiler.stack_find_offset(SocketType::VECTOR);
+ if (!skip()) {
+ int offset_in = compiler.stack_assign(vector_in);
+ int offset_out = compiler.stack_find_offset(SocketType::VECTOR);
- compile(compiler, offset_in, offset_out);
+ compile(compiler, offset_in, offset_out);
- return offset_out;
- }
+ return offset_out;
+ }
- return compiler.stack_assign(vector_in);
+ return compiler.stack_assign(vector_in);
}
-void TextureMapping::compile_end(SVMCompiler& compiler, ShaderInput *vector_in, int vector_offset)
+void TextureMapping::compile_end(SVMCompiler &compiler, ShaderInput *vector_in, int vector_offset)
{
- if(!skip()) {
- compiler.stack_clear_offset(vector_in->type(), vector_offset);
- }
+ if (!skip()) {
+ compiler.stack_clear_offset(vector_in->type(), vector_offset);
+ }
}
void TextureMapping::compile(OSLCompiler &compiler)
{
- if(!skip()) {
- compiler.parameter("mapping", compute_transform());
- compiler.parameter("use_mapping", 1);
- }
+ if (!skip()) {
+ compiler.parameter("mapping", compute_transform());
+ compiler.parameter("use_mapping", 1);
+ }
}
/* Image Texture */
NODE_DEFINE(ImageTextureNode)
{
- NodeType* type = NodeType::add("image_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("image_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(ImageTextureNode);
+ TEXTURE_MAPPING_DEFINE(ImageTextureNode);
- SOCKET_STRING(filename, "Filename", ustring());
+ SOCKET_STRING(filename, "Filename", ustring());
- static NodeEnum color_space_enum;
- color_space_enum.insert("none", NODE_COLOR_SPACE_NONE);
- color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR);
- SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR);
+ static NodeEnum color_space_enum;
+ color_space_enum.insert("none", NODE_COLOR_SPACE_NONE);
+ color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR);
+ SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR);
- SOCKET_BOOLEAN(use_alpha, "Use Alpha", true);
+ SOCKET_BOOLEAN(use_alpha, "Use Alpha", true);
- static NodeEnum interpolation_enum;
- interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
- interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
- interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
- interpolation_enum.insert("smart", INTERPOLATION_SMART);
- SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
+ static NodeEnum interpolation_enum;
+ interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
+ interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
+ interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
+ interpolation_enum.insert("smart", INTERPOLATION_SMART);
+ SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
- static NodeEnum extension_enum;
- extension_enum.insert("periodic", EXTENSION_REPEAT);
- extension_enum.insert("clamp", EXTENSION_EXTEND);
- extension_enum.insert("black", EXTENSION_CLIP);
- SOCKET_ENUM(extension, "Extension", extension_enum, EXTENSION_REPEAT);
+ static NodeEnum extension_enum;
+ extension_enum.insert("periodic", EXTENSION_REPEAT);
+ extension_enum.insert("clamp", EXTENSION_EXTEND);
+ extension_enum.insert("black", EXTENSION_CLIP);
+ SOCKET_ENUM(extension, "Extension", extension_enum, EXTENSION_REPEAT);
- static NodeEnum projection_enum;
- projection_enum.insert("flat", NODE_IMAGE_PROJ_FLAT);
- projection_enum.insert("box", NODE_IMAGE_PROJ_BOX);
- projection_enum.insert("sphere", NODE_IMAGE_PROJ_SPHERE);
- projection_enum.insert("tube", NODE_IMAGE_PROJ_TUBE);
- SOCKET_ENUM(projection, "Projection", projection_enum, NODE_IMAGE_PROJ_FLAT);
+ static NodeEnum projection_enum;
+ projection_enum.insert("flat", NODE_IMAGE_PROJ_FLAT);
+ projection_enum.insert("box", NODE_IMAGE_PROJ_BOX);
+ projection_enum.insert("sphere", NODE_IMAGE_PROJ_SPHERE);
+ projection_enum.insert("tube", NODE_IMAGE_PROJ_TUBE);
+ SOCKET_ENUM(projection, "Projection", projection_enum, NODE_IMAGE_PROJ_FLAT);
- SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f);
+ SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV);
+ SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(alpha, "Alpha");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(alpha, "Alpha");
- return type;
+ return type;
}
-ImageTextureNode::ImageTextureNode()
-: ImageSlotTextureNode(node_type)
+ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type)
{
- image_manager = NULL;
- slot = -1;
- is_float = -1;
- is_linear = false;
- builtin_data = NULL;
- animated = false;
+ image_manager = NULL;
+ slot = -1;
+ is_float = -1;
+ is_linear = false;
+ builtin_data = NULL;
+ animated = false;
}
ImageTextureNode::~ImageTextureNode()
{
- if(image_manager) {
- image_manager->remove_image(filename.string(),
- builtin_data,
- interpolation,
- extension,
- use_alpha);
- }
+ if (image_manager) {
+ image_manager->remove_image(
+ filename.string(), builtin_data, interpolation, extension, use_alpha);
+ }
}
ShaderNode *ImageTextureNode::clone() const
{
- ImageTextureNode *node = new ImageTextureNode(*this);
- node->image_manager = NULL;
- node->slot = -1;
- node->is_float = -1;
- node->is_linear = false;
- return node;
+ ImageTextureNode *node = new ImageTextureNode(*this);
+ node->image_manager = NULL;
+ node->slot = -1;
+ node->is_float = -1;
+ node->is_linear = false;
+ return node;
}
void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
#ifdef WITH_PTEX
- /* todo: avoid loading other texture coordinates when using ptex,
- * and hide texture coordinate socket in the UI */
- if(shader->has_surface && string_endswith(filename, ".ptx")) {
- /* ptex */
- attributes->add(ATTR_STD_PTEX_FACE_ID);
- attributes->add(ATTR_STD_PTEX_UV);
- }
+ /* todo: avoid loading other texture coordinates when using ptex,
+ * and hide texture coordinate socket in the UI */
+ if (shader->has_surface && string_endswith(filename, ".ptx")) {
+ /* ptex */
+ attributes->add(ATTR_STD_PTEX_FACE_ID);
+ attributes->add(ATTR_STD_PTEX_UV);
+ }
#endif
- ShaderNode::attributes(shader, attributes);
-}
-
-void ImageTextureNode::compile(SVMCompiler& compiler)
-{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *alpha_out = output("Alpha");
-
- image_manager = compiler.image_manager;
- if(is_float == -1) {
- ImageMetaData metadata;
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- extension,
- use_alpha,
- metadata);
- is_float = metadata.is_float;
- is_linear = metadata.is_linear;
- }
-
- if(slot != -1) {
- int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1;
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
-
- if(projection != NODE_IMAGE_PROJ_BOX) {
- compiler.add_node(NODE_TEX_IMAGE,
- slot,
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(alpha_out),
- srgb),
- projection);
- }
- else {
- compiler.add_node(NODE_TEX_IMAGE_BOX,
- slot,
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(alpha_out),
- srgb),
- __float_as_int(projection_blend));
- }
-
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
- }
- else {
- /* image not found */
- if(!color_out->links.empty()) {
- compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
- compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
- TEX_IMAGE_MISSING_G,
- TEX_IMAGE_MISSING_B));
- }
- if(!alpha_out->links.empty())
- compiler.add_node(NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
- }
-}
-
-void ImageTextureNode::compile(OSLCompiler& compiler)
-{
- ShaderOutput *alpha_out = output("Alpha");
-
- tex_mapping.compile(compiler);
-
- image_manager = compiler.image_manager;
- if(is_float == -1) {
- ImageMetaData metadata;
- if(builtin_data == NULL) {
- image_manager->get_image_metadata(filename.string(), NULL, metadata);
- }
- else {
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- extension,
- use_alpha,
- metadata);
- }
- is_float = metadata.is_float;
- is_linear = metadata.is_linear;
- }
-
- if(slot == -1) {
- compiler.parameter(this, "filename");
- }
- else {
- /* TODO(sergey): It's not so simple to pass custom attribute
- * to the texture() function in order to make builtin images
- * support more clear. So we use special file name which is
- * "@i<slot_number>" and check whether file name matches this
- * mask in the OSLRenderServices::texture().
- */
- compiler.parameter("filename", string_printf("@i%d", slot).c_str());
- }
- if(is_linear || color_space != NODE_COLOR_SPACE_COLOR)
- compiler.parameter("color_space", "linear");
- else
- compiler.parameter("color_space", "sRGB");
- compiler.parameter(this, "projection");
- compiler.parameter(this, "projection_blend");
- compiler.parameter("is_float", is_float);
- compiler.parameter("use_alpha", !alpha_out->links.empty());
- compiler.parameter(this, "interpolation");
- compiler.parameter(this, "extension");
-
- compiler.add(this, "node_image_texture");
+ ShaderNode::attributes(shader, attributes);
+}
+
+void ImageTextureNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *alpha_out = output("Alpha");
+
+ image_manager = compiler.image_manager;
+ if (is_float == -1) {
+ ImageMetaData metadata;
+ slot = image_manager->add_image(filename.string(),
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ extension,
+ use_alpha,
+ metadata);
+ is_float = metadata.is_float;
+ is_linear = metadata.is_linear;
+ }
+
+ if (slot != -1) {
+ int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR) ? 0 : 1;
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+
+ if (projection != NODE_IMAGE_PROJ_BOX) {
+ compiler.add_node(NODE_TEX_IMAGE,
+ slot,
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(alpha_out),
+ srgb),
+ projection);
+ }
+ else {
+ compiler.add_node(NODE_TEX_IMAGE_BOX,
+ slot,
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(alpha_out),
+ srgb),
+ __float_as_int(projection_blend));
+ }
+
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ }
+ else {
+ /* image not found */
+ if (!color_out->links.empty()) {
+ compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_VALUE_V,
+ make_float3(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B));
+ }
+ if (!alpha_out->links.empty())
+ compiler.add_node(
+ NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
+ }
+}
+
+void ImageTextureNode::compile(OSLCompiler &compiler)
+{
+ ShaderOutput *alpha_out = output("Alpha");
+
+ tex_mapping.compile(compiler);
+
+ image_manager = compiler.image_manager;
+ if (is_float == -1) {
+ ImageMetaData metadata;
+ if (builtin_data == NULL) {
+ image_manager->get_image_metadata(filename.string(), NULL, metadata);
+ }
+ else {
+ slot = image_manager->add_image(filename.string(),
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ extension,
+ use_alpha,
+ metadata);
+ }
+ is_float = metadata.is_float;
+ is_linear = metadata.is_linear;
+ }
+
+ if (slot == -1) {
+ compiler.parameter(this, "filename");
+ }
+ else {
+ /* TODO(sergey): It's not so simple to pass custom attribute
+ * to the texture() function in order to make builtin images
+ * support more clear. So we use special file name which is
+ * "@i<slot_number>" and check whether file name matches this
+ * mask in the OSLRenderServices::texture().
+ */
+ compiler.parameter("filename", string_printf("@i%d", slot).c_str());
+ }
+ if (is_linear || color_space != NODE_COLOR_SPACE_COLOR)
+ compiler.parameter("color_space", "linear");
+ else
+ compiler.parameter("color_space", "sRGB");
+ compiler.parameter(this, "projection");
+ compiler.parameter(this, "projection_blend");
+ compiler.parameter("is_float", is_float);
+ compiler.parameter("use_alpha", !alpha_out->links.empty());
+ compiler.parameter(this, "interpolation");
+ compiler.parameter(this, "extension");
+
+ compiler.add(this, "node_image_texture");
}
/* Environment Texture */
NODE_DEFINE(EnvironmentTextureNode)
{
- NodeType* type = NodeType::add("environment_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("environment_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(EnvironmentTextureNode);
+ TEXTURE_MAPPING_DEFINE(EnvironmentTextureNode);
- SOCKET_STRING(filename, "Filename", ustring());
+ SOCKET_STRING(filename, "Filename", ustring());
- static NodeEnum color_space_enum;
- color_space_enum.insert("none", NODE_COLOR_SPACE_NONE);
- color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR);
- SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR);
+ static NodeEnum color_space_enum;
+ color_space_enum.insert("none", NODE_COLOR_SPACE_NONE);
+ color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR);
+ SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR);
- SOCKET_BOOLEAN(use_alpha, "Use Alpha", true);
+ SOCKET_BOOLEAN(use_alpha, "Use Alpha", true);
- static NodeEnum interpolation_enum;
- interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
- interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
- interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
- interpolation_enum.insert("smart", INTERPOLATION_SMART);
- SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
+ static NodeEnum interpolation_enum;
+ interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
+ interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
+ interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
+ interpolation_enum.insert("smart", INTERPOLATION_SMART);
+ SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
- static NodeEnum projection_enum;
- projection_enum.insert("equirectangular", NODE_ENVIRONMENT_EQUIRECTANGULAR);
- projection_enum.insert("mirror_ball", NODE_ENVIRONMENT_MIRROR_BALL);
- SOCKET_ENUM(projection, "Projection", projection_enum, NODE_ENVIRONMENT_EQUIRECTANGULAR);
+ static NodeEnum projection_enum;
+ projection_enum.insert("equirectangular", NODE_ENVIRONMENT_EQUIRECTANGULAR);
+ projection_enum.insert("mirror_ball", NODE_ENVIRONMENT_MIRROR_BALL);
+ SOCKET_ENUM(projection, "Projection", projection_enum, NODE_ENVIRONMENT_EQUIRECTANGULAR);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION);
+ SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(alpha, "Alpha");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(alpha, "Alpha");
- return type;
+ return type;
}
-EnvironmentTextureNode::EnvironmentTextureNode()
-: ImageSlotTextureNode(node_type)
+EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_type)
{
- image_manager = NULL;
- slot = -1;
- is_float = -1;
- is_linear = false;
- builtin_data = NULL;
- animated = false;
+ image_manager = NULL;
+ slot = -1;
+ is_float = -1;
+ is_linear = false;
+ builtin_data = NULL;
+ animated = false;
}
EnvironmentTextureNode::~EnvironmentTextureNode()
{
- if(image_manager) {
- image_manager->remove_image(filename.string(),
- builtin_data,
- interpolation,
- EXTENSION_REPEAT,
- use_alpha);
- }
+ if (image_manager) {
+ image_manager->remove_image(
+ filename.string(), builtin_data, interpolation, EXTENSION_REPEAT, use_alpha);
+ }
}
ShaderNode *EnvironmentTextureNode::clone() const
{
- EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
- node->image_manager = NULL;
- node->slot = -1;
- node->is_float = -1;
- node->is_linear = false;
- return node;
+ EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
+ node->image_manager = NULL;
+ node->slot = -1;
+ node->is_float = -1;
+ node->is_linear = false;
+ return node;
}
void EnvironmentTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
#ifdef WITH_PTEX
- if(shader->has_surface && string_endswith(filename, ".ptx")) {
- /* ptex */
- attributes->add(ATTR_STD_PTEX_FACE_ID);
- attributes->add(ATTR_STD_PTEX_UV);
- }
+ if (shader->has_surface && string_endswith(filename, ".ptx")) {
+ /* ptex */
+ attributes->add(ATTR_STD_PTEX_FACE_ID);
+ attributes->add(ATTR_STD_PTEX_UV);
+ }
#endif
- ShaderNode::attributes(shader, attributes);
-}
-
-void EnvironmentTextureNode::compile(SVMCompiler& compiler)
-{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *alpha_out = output("Alpha");
-
- image_manager = compiler.image_manager;
- if(slot == -1) {
- ImageMetaData metadata;
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- EXTENSION_REPEAT,
- use_alpha,
- metadata);
- is_float = metadata.is_float;
- is_linear = metadata.is_linear;
- }
-
- if(slot != -1) {
- int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1;
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
-
- compiler.add_node(NODE_TEX_ENVIRONMENT,
- slot,
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(alpha_out),
- srgb),
- projection);
-
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
- }
- else {
- /* image not found */
- if(!color_out->links.empty()) {
- compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
- compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
- TEX_IMAGE_MISSING_G,
- TEX_IMAGE_MISSING_B));
- }
- if(!alpha_out->links.empty())
- compiler.add_node(NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
- }
-}
-
-void EnvironmentTextureNode::compile(OSLCompiler& compiler)
-{
- ShaderOutput *alpha_out = output("Alpha");
-
- tex_mapping.compile(compiler);
-
- /* See comments in ImageTextureNode::compile about support
- * of builtin images.
- */
- image_manager = compiler.image_manager;
- if(is_float == -1) {
- ImageMetaData metadata;
- if(builtin_data == NULL) {
- image_manager->get_image_metadata(filename.string(), NULL, metadata);
- }
- else {
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- EXTENSION_REPEAT,
- use_alpha,
- metadata);
- }
- is_float = metadata.is_float;
- is_linear = metadata.is_linear;
- }
-
- if(slot == -1) {
- compiler.parameter(this, "filename");
- }
- else {
- compiler.parameter("filename", string_printf("@i%d", slot).c_str());
- }
- compiler.parameter(this, "projection");
- if(is_linear || color_space != NODE_COLOR_SPACE_COLOR)
- compiler.parameter("color_space", "linear");
- else
- compiler.parameter("color_space", "sRGB");
-
- compiler.parameter(this, "interpolation");
- compiler.parameter("is_float", is_float);
- compiler.parameter("use_alpha", !alpha_out->links.empty());
- compiler.add(this, "node_environment_texture");
+ ShaderNode::attributes(shader, attributes);
+}
+
+void EnvironmentTextureNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *alpha_out = output("Alpha");
+
+ image_manager = compiler.image_manager;
+ if (slot == -1) {
+ ImageMetaData metadata;
+ slot = image_manager->add_image(filename.string(),
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ EXTENSION_REPEAT,
+ use_alpha,
+ metadata);
+ is_float = metadata.is_float;
+ is_linear = metadata.is_linear;
+ }
+
+ if (slot != -1) {
+ int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR) ? 0 : 1;
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+
+ compiler.add_node(NODE_TEX_ENVIRONMENT,
+ slot,
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(alpha_out),
+ srgb),
+ projection);
+
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ }
+ else {
+ /* image not found */
+ if (!color_out->links.empty()) {
+ compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_VALUE_V,
+ make_float3(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B));
+ }
+ if (!alpha_out->links.empty())
+ compiler.add_node(
+ NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
+ }
+}
+
+void EnvironmentTextureNode::compile(OSLCompiler &compiler)
+{
+ ShaderOutput *alpha_out = output("Alpha");
+
+ tex_mapping.compile(compiler);
+
+ /* See comments in ImageTextureNode::compile about support
+ * of builtin images.
+ */
+ image_manager = compiler.image_manager;
+ if (is_float == -1) {
+ ImageMetaData metadata;
+ if (builtin_data == NULL) {
+ image_manager->get_image_metadata(filename.string(), NULL, metadata);
+ }
+ else {
+ slot = image_manager->add_image(filename.string(),
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ EXTENSION_REPEAT,
+ use_alpha,
+ metadata);
+ }
+ is_float = metadata.is_float;
+ is_linear = metadata.is_linear;
+ }
+
+ if (slot == -1) {
+ compiler.parameter(this, "filename");
+ }
+ else {
+ compiler.parameter("filename", string_printf("@i%d", slot).c_str());
+ }
+ compiler.parameter(this, "projection");
+ if (is_linear || color_space != NODE_COLOR_SPACE_COLOR)
+ compiler.parameter("color_space", "linear");
+ else
+ compiler.parameter("color_space", "sRGB");
+
+ compiler.parameter(this, "interpolation");
+ compiler.parameter("is_float", is_float);
+ compiler.parameter("use_alpha", !alpha_out->links.empty());
+ compiler.add(this, "node_environment_texture");
}
/* Sky Texture */
static float2 sky_spherical_coordinates(float3 dir)
{
- return make_float2(acosf(dir.z), atan2f(dir.x, dir.y));
+ return make_float2(acosf(dir.z), atan2f(dir.x, dir.y));
}
typedef struct SunSky {
- /* sun direction in spherical and cartesian */
- float theta, phi;
+ /* sun direction in spherical and cartesian */
+ float theta, phi;
- /* Parameter */
- float radiance_x, radiance_y, radiance_z;
- float config_x[9], config_y[9], config_z[9];
+ /* Parameter */
+ float radiance_x, radiance_y, radiance_z;
+ float config_x[9], config_y[9], config_z[9];
} SunSky;
/* Preetham model */
static float sky_perez_function(float lam[6], float theta, float gamma)
{
- return (1.0f + lam[0]*expf(lam[1]/cosf(theta))) * (1.0f + lam[2]*expf(lam[3]*gamma) + lam[4]*cosf(gamma)*cosf(gamma));
+ return (1.0f + lam[0] * expf(lam[1] / cosf(theta))) *
+ (1.0f + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma));
}
static void sky_texture_precompute_old(SunSky *sunsky, float3 dir, float turbidity)
{
- /*
- * We re-use the SunSky struct of the new model, to avoid extra variables
- * zenith_Y/x/y is now radiance_x/y/z
- * perez_Y/x/y is now config_x/y/z
- */
-
- float2 spherical = sky_spherical_coordinates(dir);
- float theta = spherical.x;
- float phi = spherical.y;
-
- sunsky->theta = theta;
- sunsky->phi = phi;
-
- float theta2 = theta*theta;
- float theta3 = theta2*theta;
- float T = turbidity;
- float T2 = T * T;
-
- float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI_F - 2.0f * theta);
- sunsky->radiance_x = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
- sunsky->radiance_x *= 0.06f;
-
- sunsky->radiance_y =
- (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
- (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) * T +
- (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
-
- sunsky->radiance_z =
- (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
- (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta + 0.00516f) * T +
- (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta + 0.26688f);
-
- sunsky->config_x[0] = (0.1787f * T - 1.4630f);
- sunsky->config_x[1] = (-0.3554f * T + 0.4275f);
- sunsky->config_x[2] = (-0.0227f * T + 5.3251f);
- sunsky->config_x[3] = (0.1206f * T - 2.5771f);
- sunsky->config_x[4] = (-0.0670f * T + 0.3703f);
-
- sunsky->config_y[0] = (-0.0193f * T - 0.2592f);
- sunsky->config_y[1] = (-0.0665f * T + 0.0008f);
- sunsky->config_y[2] = (-0.0004f * T + 0.2125f);
- sunsky->config_y[3] = (-0.0641f * T - 0.8989f);
- sunsky->config_y[4] = (-0.0033f * T + 0.0452f);
-
- sunsky->config_z[0] = (-0.0167f * T - 0.2608f);
- sunsky->config_z[1] = (-0.0950f * T + 0.0092f);
- sunsky->config_z[2] = (-0.0079f * T + 0.2102f);
- sunsky->config_z[3] = (-0.0441f * T - 1.6537f);
- sunsky->config_z[4] = (-0.0109f * T + 0.0529f);
-
- /* unused for old sky model */
- for(int i = 5; i < 9; i++) {
- sunsky->config_x[i] = 0.0f;
- sunsky->config_y[i] = 0.0f;
- sunsky->config_z[i] = 0.0f;
- }
-
- sunsky->radiance_x /= sky_perez_function(sunsky->config_x, 0, theta);
- sunsky->radiance_y /= sky_perez_function(sunsky->config_y, 0, theta);
- sunsky->radiance_z /= sky_perez_function(sunsky->config_z, 0, theta);
+ /*
+ * We re-use the SunSky struct of the new model, to avoid extra variables
+ * zenith_Y/x/y is now radiance_x/y/z
+ * perez_Y/x/y is now config_x/y/z
+ */
+
+ float2 spherical = sky_spherical_coordinates(dir);
+ float theta = spherical.x;
+ float phi = spherical.y;
+
+ sunsky->theta = theta;
+ sunsky->phi = phi;
+
+ float theta2 = theta * theta;
+ float theta3 = theta2 * theta;
+ float T = turbidity;
+ float T2 = T * T;
+
+ float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI_F - 2.0f * theta);
+ sunsky->radiance_x = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
+ sunsky->radiance_x *= 0.06f;
+
+ sunsky->radiance_y = (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
+ (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) * T +
+ (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
+
+ sunsky->radiance_z = (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
+ (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta + 0.00516f) * T +
+ (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta + 0.26688f);
+
+ sunsky->config_x[0] = (0.1787f * T - 1.4630f);
+ sunsky->config_x[1] = (-0.3554f * T + 0.4275f);
+ sunsky->config_x[2] = (-0.0227f * T + 5.3251f);
+ sunsky->config_x[3] = (0.1206f * T - 2.5771f);
+ sunsky->config_x[4] = (-0.0670f * T + 0.3703f);
+
+ sunsky->config_y[0] = (-0.0193f * T - 0.2592f);
+ sunsky->config_y[1] = (-0.0665f * T + 0.0008f);
+ sunsky->config_y[2] = (-0.0004f * T + 0.2125f);
+ sunsky->config_y[3] = (-0.0641f * T - 0.8989f);
+ sunsky->config_y[4] = (-0.0033f * T + 0.0452f);
+
+ sunsky->config_z[0] = (-0.0167f * T - 0.2608f);
+ sunsky->config_z[1] = (-0.0950f * T + 0.0092f);
+ sunsky->config_z[2] = (-0.0079f * T + 0.2102f);
+ sunsky->config_z[3] = (-0.0441f * T - 1.6537f);
+ sunsky->config_z[4] = (-0.0109f * T + 0.0529f);
+
+ /* unused for old sky model */
+ for (int i = 5; i < 9; i++) {
+ sunsky->config_x[i] = 0.0f;
+ sunsky->config_y[i] = 0.0f;
+ sunsky->config_z[i] = 0.0f;
+ }
+
+ sunsky->radiance_x /= sky_perez_function(sunsky->config_x, 0, theta);
+ sunsky->radiance_y /= sky_perez_function(sunsky->config_y, 0, theta);
+ sunsky->radiance_z /= sky_perez_function(sunsky->config_z, 0, theta);
}
/* Hosek / Wilkie */
-static void sky_texture_precompute_new(SunSky *sunsky, float3 dir, float turbidity, float ground_albedo)
+static void sky_texture_precompute_new(SunSky *sunsky,
+ float3 dir,
+ float turbidity,
+ float ground_albedo)
{
- /* Calculate Sun Direction and save coordinates */
- float2 spherical = sky_spherical_coordinates(dir);
- float theta = spherical.x;
- float phi = spherical.y;
+ /* Calculate Sun Direction and save coordinates */
+ float2 spherical = sky_spherical_coordinates(dir);
+ float theta = spherical.x;
+ float phi = spherical.y;
- /* Clamp Turbidity */
- turbidity = clamp(turbidity, 0.0f, 10.0f);
+ /* Clamp Turbidity */
+ turbidity = clamp(turbidity, 0.0f, 10.0f);
- /* Clamp to Horizon */
- theta = clamp(theta, 0.0f, M_PI_2_F);
+ /* Clamp to Horizon */
+ theta = clamp(theta, 0.0f, M_PI_2_F);
- sunsky->theta = theta;
- sunsky->phi = phi;
+ sunsky->theta = theta;
+ sunsky->phi = phi;
- float solarElevation = M_PI_2_F - theta;
+ float solarElevation = M_PI_2_F - theta;
- /* Initialize Sky Model */
- ArHosekSkyModelState *sky_state;
- sky_state = arhosek_xyz_skymodelstate_alloc_init((double)turbidity, (double)ground_albedo, (double)solarElevation);
+ /* Initialize Sky Model */
+ ArHosekSkyModelState *sky_state;
+ sky_state = arhosek_xyz_skymodelstate_alloc_init(
+ (double)turbidity, (double)ground_albedo, (double)solarElevation);
- /* Copy values from sky_state to SunSky */
- for(int i = 0; i < 9; ++i) {
- sunsky->config_x[i] = (float)sky_state->configs[0][i];
- sunsky->config_y[i] = (float)sky_state->configs[1][i];
- sunsky->config_z[i] = (float)sky_state->configs[2][i];
- }
- sunsky->radiance_x = (float)sky_state->radiances[0];
- sunsky->radiance_y = (float)sky_state->radiances[1];
- sunsky->radiance_z = (float)sky_state->radiances[2];
+ /* Copy values from sky_state to SunSky */
+ for (int i = 0; i < 9; ++i) {
+ sunsky->config_x[i] = (float)sky_state->configs[0][i];
+ sunsky->config_y[i] = (float)sky_state->configs[1][i];
+ sunsky->config_z[i] = (float)sky_state->configs[2][i];
+ }
+ sunsky->radiance_x = (float)sky_state->radiances[0];
+ sunsky->radiance_y = (float)sky_state->radiances[1];
+ sunsky->radiance_z = (float)sky_state->radiances[2];
- /* Free sky_state */
- arhosekskymodelstate_free(sky_state);
+ /* Free sky_state */
+ arhosekskymodelstate_free(sky_state);
}
NODE_DEFINE(SkyTextureNode)
{
- NodeType* type = NodeType::add("sky_texture", create, NodeType::SHADER);
-
- TEXTURE_MAPPING_DEFINE(SkyTextureNode);
-
- static NodeEnum type_enum;
- type_enum.insert("preetham", NODE_SKY_OLD);
- type_enum.insert("hosek_wilkie", NODE_SKY_NEW);
- SOCKET_ENUM(type, "Type", type_enum, NODE_SKY_NEW);
-
- SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f));
- SOCKET_FLOAT(turbidity, "Turbidity", 2.2f);
- SOCKET_FLOAT(ground_albedo, "Ground Albedo", 0.3f);
-
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
-
- SOCKET_OUT_COLOR(color, "Color");
-
- return type;
-}
-
-SkyTextureNode::SkyTextureNode()
-: TextureNode(node_type)
-{
-}
-
-void SkyTextureNode::compile(SVMCompiler& compiler)
-{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *color_out = output("Color");
-
- SunSky sunsky;
- if(type == NODE_SKY_OLD)
- sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
- else if(type == NODE_SKY_NEW)
- sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
- else
- assert(false);
-
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
-
- compiler.stack_assign(color_out);
- compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), type);
- compiler.add_node(__float_as_uint(sunsky.phi), __float_as_uint(sunsky.theta), __float_as_uint(sunsky.radiance_x), __float_as_uint(sunsky.radiance_y));
- compiler.add_node(__float_as_uint(sunsky.radiance_z), __float_as_uint(sunsky.config_x[0]), __float_as_uint(sunsky.config_x[1]), __float_as_uint(sunsky.config_x[2]));
- compiler.add_node(__float_as_uint(sunsky.config_x[3]), __float_as_uint(sunsky.config_x[4]), __float_as_uint(sunsky.config_x[5]), __float_as_uint(sunsky.config_x[6]));
- compiler.add_node(__float_as_uint(sunsky.config_x[7]), __float_as_uint(sunsky.config_x[8]), __float_as_uint(sunsky.config_y[0]), __float_as_uint(sunsky.config_y[1]));
- compiler.add_node(__float_as_uint(sunsky.config_y[2]), __float_as_uint(sunsky.config_y[3]), __float_as_uint(sunsky.config_y[4]), __float_as_uint(sunsky.config_y[5]));
- compiler.add_node(__float_as_uint(sunsky.config_y[6]), __float_as_uint(sunsky.config_y[7]), __float_as_uint(sunsky.config_y[8]), __float_as_uint(sunsky.config_z[0]));
- compiler.add_node(__float_as_uint(sunsky.config_z[1]), __float_as_uint(sunsky.config_z[2]), __float_as_uint(sunsky.config_z[3]), __float_as_uint(sunsky.config_z[4]));
- compiler.add_node(__float_as_uint(sunsky.config_z[5]), __float_as_uint(sunsky.config_z[6]), __float_as_uint(sunsky.config_z[7]), __float_as_uint(sunsky.config_z[8]));
-
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
-}
-
-void SkyTextureNode::compile(OSLCompiler& compiler)
-{
- tex_mapping.compile(compiler);
-
- SunSky sunsky;
- if(type == NODE_SKY_OLD)
- sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
- else if(type == NODE_SKY_NEW)
- sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
- else
- assert(false);
-
- compiler.parameter(this, "type");
- compiler.parameter("theta", sunsky.theta);
- compiler.parameter("phi", sunsky.phi);
- compiler.parameter_color("radiance", make_float3(sunsky.radiance_x, sunsky.radiance_y, sunsky.radiance_z));
- compiler.parameter_array("config_x", sunsky.config_x, 9);
- compiler.parameter_array("config_y", sunsky.config_y, 9);
- compiler.parameter_array("config_z", sunsky.config_z, 9);
- compiler.add(this, "node_sky_texture");
+ NodeType *type = NodeType::add("sky_texture", create, NodeType::SHADER);
+
+ TEXTURE_MAPPING_DEFINE(SkyTextureNode);
+
+ static NodeEnum type_enum;
+ type_enum.insert("preetham", NODE_SKY_OLD);
+ type_enum.insert("hosek_wilkie", NODE_SKY_NEW);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_SKY_NEW);
+
+ SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f));
+ SOCKET_FLOAT(turbidity, "Turbidity", 2.2f);
+ SOCKET_FLOAT(ground_albedo, "Ground Albedo", 0.3f);
+
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+
+ SOCKET_OUT_COLOR(color, "Color");
+
+ return type;
+}
+
+SkyTextureNode::SkyTextureNode() : TextureNode(node_type)
+{
+}
+
+void SkyTextureNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *color_out = output("Color");
+
+ SunSky sunsky;
+ if (type == NODE_SKY_OLD)
+ sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
+ else if (type == NODE_SKY_NEW)
+ sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
+ else
+ assert(false);
+
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+
+ compiler.stack_assign(color_out);
+ compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), type);
+ compiler.add_node(__float_as_uint(sunsky.phi),
+ __float_as_uint(sunsky.theta),
+ __float_as_uint(sunsky.radiance_x),
+ __float_as_uint(sunsky.radiance_y));
+ compiler.add_node(__float_as_uint(sunsky.radiance_z),
+ __float_as_uint(sunsky.config_x[0]),
+ __float_as_uint(sunsky.config_x[1]),
+ __float_as_uint(sunsky.config_x[2]));
+ compiler.add_node(__float_as_uint(sunsky.config_x[3]),
+ __float_as_uint(sunsky.config_x[4]),
+ __float_as_uint(sunsky.config_x[5]),
+ __float_as_uint(sunsky.config_x[6]));
+ compiler.add_node(__float_as_uint(sunsky.config_x[7]),
+ __float_as_uint(sunsky.config_x[8]),
+ __float_as_uint(sunsky.config_y[0]),
+ __float_as_uint(sunsky.config_y[1]));
+ compiler.add_node(__float_as_uint(sunsky.config_y[2]),
+ __float_as_uint(sunsky.config_y[3]),
+ __float_as_uint(sunsky.config_y[4]),
+ __float_as_uint(sunsky.config_y[5]));
+ compiler.add_node(__float_as_uint(sunsky.config_y[6]),
+ __float_as_uint(sunsky.config_y[7]),
+ __float_as_uint(sunsky.config_y[8]),
+ __float_as_uint(sunsky.config_z[0]));
+ compiler.add_node(__float_as_uint(sunsky.config_z[1]),
+ __float_as_uint(sunsky.config_z[2]),
+ __float_as_uint(sunsky.config_z[3]),
+ __float_as_uint(sunsky.config_z[4]));
+ compiler.add_node(__float_as_uint(sunsky.config_z[5]),
+ __float_as_uint(sunsky.config_z[6]),
+ __float_as_uint(sunsky.config_z[7]),
+ __float_as_uint(sunsky.config_z[8]));
+
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
+}
+
+void SkyTextureNode::compile(OSLCompiler &compiler)
+{
+ tex_mapping.compile(compiler);
+
+ SunSky sunsky;
+ if (type == NODE_SKY_OLD)
+ sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
+ else if (type == NODE_SKY_NEW)
+ sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
+ else
+ assert(false);
+
+ compiler.parameter(this, "type");
+ compiler.parameter("theta", sunsky.theta);
+ compiler.parameter("phi", sunsky.phi);
+ compiler.parameter_color("radiance",
+ make_float3(sunsky.radiance_x, sunsky.radiance_y, sunsky.radiance_z));
+ compiler.parameter_array("config_x", sunsky.config_x, 9);
+ compiler.parameter_array("config_y", sunsky.config_y, 9);
+ compiler.parameter_array("config_z", sunsky.config_z, 9);
+ compiler.add(this, "node_sky_texture");
}
/* Gradient Texture */
NODE_DEFINE(GradientTextureNode)
{
- NodeType* type = NodeType::add("gradient_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("gradient_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(GradientTextureNode);
+ TEXTURE_MAPPING_DEFINE(GradientTextureNode);
- static NodeEnum type_enum;
- type_enum.insert("linear", NODE_BLEND_LINEAR);
- type_enum.insert("quadratic", NODE_BLEND_QUADRATIC);
- type_enum.insert("easing", NODE_BLEND_EASING);
- type_enum.insert("diagonal", NODE_BLEND_DIAGONAL);
- type_enum.insert("radial", NODE_BLEND_RADIAL);
- type_enum.insert("quadratic_sphere", NODE_BLEND_QUADRATIC_SPHERE);
- type_enum.insert("spherical", NODE_BLEND_SPHERICAL);
- SOCKET_ENUM(type, "Type", type_enum, NODE_BLEND_LINEAR);
+ static NodeEnum type_enum;
+ type_enum.insert("linear", NODE_BLEND_LINEAR);
+ type_enum.insert("quadratic", NODE_BLEND_QUADRATIC);
+ type_enum.insert("easing", NODE_BLEND_EASING);
+ type_enum.insert("diagonal", NODE_BLEND_DIAGONAL);
+ type_enum.insert("radial", NODE_BLEND_RADIAL);
+ type_enum.insert("quadratic_sphere", NODE_BLEND_QUADRATIC_SPHERE);
+ type_enum.insert("spherical", NODE_BLEND_SPHERICAL);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_BLEND_LINEAR);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-GradientTextureNode::GradientTextureNode()
-: TextureNode(node_type)
+GradientTextureNode::GradientTextureNode() : TextureNode(node_type)
{
}
-void GradientTextureNode::compile(SVMCompiler& compiler)
+void GradientTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *fac_out = output("Fac");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *fac_out = output("Fac");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_GRADIENT,
- compiler.encode_uchar4(
- type,
- vector_offset,
- compiler.stack_assign_if_linked(fac_out),
- compiler.stack_assign_if_linked(color_out)));
+ compiler.add_node(NODE_TEX_GRADIENT,
+ compiler.encode_uchar4(type,
+ vector_offset,
+ compiler.stack_assign_if_linked(fac_out),
+ compiler.stack_assign_if_linked(color_out)));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void GradientTextureNode::compile(OSLCompiler& compiler)
+void GradientTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.parameter(this, "type");
- compiler.add(this, "node_gradient_texture");
+ compiler.parameter(this, "type");
+ compiler.add(this, "node_gradient_texture");
}
/* Noise Texture */
NODE_DEFINE(NoiseTextureNode)
{
- NodeType* type = NodeType::add("noise_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("noise_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(NoiseTextureNode);
+ TEXTURE_MAPPING_DEFINE(NoiseTextureNode);
- SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
- SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
- SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+ SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
+ SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-NoiseTextureNode::NoiseTextureNode()
-: TextureNode(node_type)
+NoiseTextureNode::NoiseTextureNode() : TextureNode(node_type)
{
}
-void NoiseTextureNode::compile(SVMCompiler& compiler)
+void NoiseTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *distortion_in = input("Distortion");
- ShaderInput *detail_in = input("Detail");
- ShaderInput *scale_in = input("Scale");
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *fac_out = output("Fac");
+ ShaderInput *distortion_in = input("Distortion");
+ ShaderInput *detail_in = input("Detail");
+ ShaderInput *scale_in = input("Scale");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *fac_out = output("Fac");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_NOISE,
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign_if_linked(scale_in),
- compiler.stack_assign_if_linked(detail_in),
- compiler.stack_assign_if_linked(distortion_in)),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(fac_out)));
- compiler.add_node(
- __float_as_int(scale),
- __float_as_int(detail),
- __float_as_int(distortion));
+ compiler.add_node(NODE_TEX_NOISE,
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign_if_linked(scale_in),
+ compiler.stack_assign_if_linked(detail_in),
+ compiler.stack_assign_if_linked(distortion_in)),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(fac_out)));
+ compiler.add_node(__float_as_int(scale), __float_as_int(detail), __float_as_int(distortion));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void NoiseTextureNode::compile(OSLCompiler& compiler)
+void NoiseTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.add(this, "node_noise_texture");
+ compiler.add(this, "node_noise_texture");
}
/* Voronoi Texture */
NODE_DEFINE(VoronoiTextureNode)
{
- NodeType* type = NodeType::add("voronoi_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("voronoi_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(VoronoiTextureNode);
+ TEXTURE_MAPPING_DEFINE(VoronoiTextureNode);
- static NodeEnum coloring_enum;
- coloring_enum.insert("intensity", NODE_VORONOI_INTENSITY);
- coloring_enum.insert("cells", NODE_VORONOI_CELLS);
- SOCKET_ENUM(coloring, "Coloring", coloring_enum, NODE_VORONOI_INTENSITY);
+ static NodeEnum coloring_enum;
+ coloring_enum.insert("intensity", NODE_VORONOI_INTENSITY);
+ coloring_enum.insert("cells", NODE_VORONOI_CELLS);
+ SOCKET_ENUM(coloring, "Coloring", coloring_enum, NODE_VORONOI_INTENSITY);
- static NodeEnum metric;
- metric.insert("distance", NODE_VORONOI_DISTANCE);
- metric.insert("manhattan", NODE_VORONOI_MANHATTAN);
- metric.insert("chebychev", NODE_VORONOI_CHEBYCHEV);
- metric.insert("minkowski", NODE_VORONOI_MINKOWSKI);
- SOCKET_ENUM(metric, "Distance Metric", metric, NODE_VORONOI_INTENSITY);
+ static NodeEnum metric;
+ metric.insert("distance", NODE_VORONOI_DISTANCE);
+ metric.insert("manhattan", NODE_VORONOI_MANHATTAN);
+ metric.insert("chebychev", NODE_VORONOI_CHEBYCHEV);
+ metric.insert("minkowski", NODE_VORONOI_MINKOWSKI);
+ SOCKET_ENUM(metric, "Distance Metric", metric, NODE_VORONOI_INTENSITY);
- static NodeEnum feature_enum;
- feature_enum.insert("F1", NODE_VORONOI_F1);
- feature_enum.insert("F2", NODE_VORONOI_F2);
- feature_enum.insert("F3", NODE_VORONOI_F3);
- feature_enum.insert("F4", NODE_VORONOI_F4);
- feature_enum.insert("F2F1", NODE_VORONOI_F2F1);
- SOCKET_ENUM(feature, "Feature", feature_enum, NODE_VORONOI_INTENSITY);
+ static NodeEnum feature_enum;
+ feature_enum.insert("F1", NODE_VORONOI_F1);
+ feature_enum.insert("F2", NODE_VORONOI_F2);
+ feature_enum.insert("F3", NODE_VORONOI_F3);
+ feature_enum.insert("F4", NODE_VORONOI_F4);
+ feature_enum.insert("F2F1", NODE_VORONOI_F2F1);
+ SOCKET_ENUM(feature, "Feature", feature_enum, NODE_VORONOI_INTENSITY);
- SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
- SOCKET_IN_FLOAT(exponent, "Exponent", 0.5f);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+ SOCKET_IN_FLOAT(exponent, "Exponent", 0.5f);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-VoronoiTextureNode::VoronoiTextureNode()
-: TextureNode(node_type)
+VoronoiTextureNode::VoronoiTextureNode() : TextureNode(node_type)
{
}
-void VoronoiTextureNode::compile(SVMCompiler& compiler)
+void VoronoiTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *scale_in = input("Scale");
- ShaderInput *vector_in = input("Vector");
- ShaderInput *exponent_in = input("Exponent");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *fac_out = output("Fac");
+ ShaderInput *scale_in = input("Scale");
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *exponent_in = input("Exponent");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *fac_out = output("Fac");
- if(vector_in->link) compiler.stack_assign(vector_in);
- if(scale_in->link) compiler.stack_assign(scale_in);
- if(exponent_in->link) compiler.stack_assign(exponent_in);
+ if (vector_in->link)
+ compiler.stack_assign(vector_in);
+ if (scale_in->link)
+ compiler.stack_assign(scale_in);
+ if (exponent_in->link)
+ compiler.stack_assign(exponent_in);
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_VORONOI,
- compiler.encode_uchar4(
- vector_offset,
- coloring,
- metric,
- feature
- ),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(scale_in),
- compiler.stack_assign_if_linked(exponent_in),
- compiler.stack_assign(fac_out),
- compiler.stack_assign(color_out)
- ));
- compiler.add_node(
- __float_as_int(scale),
- __float_as_int(exponent));
+ compiler.add_node(NODE_TEX_VORONOI,
+ compiler.encode_uchar4(vector_offset, coloring, metric, feature),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(scale_in),
+ compiler.stack_assign_if_linked(exponent_in),
+ compiler.stack_assign(fac_out),
+ compiler.stack_assign(color_out)));
+ compiler.add_node(__float_as_int(scale), __float_as_int(exponent));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void VoronoiTextureNode::compile(OSLCompiler& compiler)
+void VoronoiTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.parameter(this, "coloring");
- compiler.parameter(this, "metric");
- compiler.parameter(this, "feature");
- compiler.add(this, "node_voronoi_texture");
+ compiler.parameter(this, "coloring");
+ compiler.parameter(this, "metric");
+ compiler.parameter(this, "feature");
+ compiler.add(this, "node_voronoi_texture");
}
/* IES Light */
NODE_DEFINE(IESLightNode)
{
- NodeType* type = NodeType::add("ies_light", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("ies_light", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(IESLightNode);
+ TEXTURE_MAPPING_DEFINE(IESLightNode);
- SOCKET_STRING(ies, "IES", ustring());
- SOCKET_STRING(filename, "File Name", ustring());
+ SOCKET_STRING(ies, "IES", ustring());
+ SOCKET_STRING(filename, "File Name", ustring());
- SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_NORMAL);
+ SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_NORMAL);
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-IESLightNode::IESLightNode()
-: TextureNode(node_type)
+IESLightNode::IESLightNode() : TextureNode(node_type)
{
- light_manager = NULL;
- slot = -1;
+ light_manager = NULL;
+ slot = -1;
}
ShaderNode *IESLightNode::clone() const
{
- IESLightNode *node = new IESLightNode(*this);
+ IESLightNode *node = new IESLightNode(*this);
- node->light_manager = NULL;
- node->slot = -1;
+ node->light_manager = NULL;
+ node->slot = -1;
- return node;
+ return node;
}
IESLightNode::~IESLightNode()
{
- if(light_manager) {
- light_manager->remove_ies(slot);
- }
+ if (light_manager) {
+ light_manager->remove_ies(slot);
+ }
}
void IESLightNode::get_slot()
{
- assert(light_manager);
+ assert(light_manager);
- if(slot == -1) {
- if(ies.empty()) {
- slot = light_manager->add_ies_from_file(filename);
- }
- else {
- slot = light_manager->add_ies(ies);
- }
- }
+ if (slot == -1) {
+ if (ies.empty()) {
+ slot = light_manager->add_ies_from_file(filename);
+ }
+ else {
+ slot = light_manager->add_ies(ies);
+ }
+ }
}
-void IESLightNode::compile(SVMCompiler& compiler)
+void IESLightNode::compile(SVMCompiler &compiler)
{
- light_manager = compiler.light_manager;
- get_slot();
+ light_manager = compiler.light_manager;
+ get_slot();
- ShaderInput *strength_in = input("Strength");
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *fac_out = output("Fac");
+ ShaderInput *strength_in = input("Strength");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *fac_out = output("Fac");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_IES,
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(strength_in),
- vector_offset,
- compiler.stack_assign(fac_out),
- 0),
- slot,
- __float_as_int(strength));
+ compiler.add_node(NODE_IES,
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(strength_in),
+ vector_offset,
+ compiler.stack_assign(fac_out),
+ 0),
+ slot,
+ __float_as_int(strength));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void IESLightNode::compile(OSLCompiler& compiler)
+void IESLightNode::compile(OSLCompiler &compiler)
{
- light_manager = compiler.light_manager;
- get_slot();
+ light_manager = compiler.light_manager;
+ get_slot();
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.parameter("slot", slot);
- compiler.add(this, "node_ies_light");
+ compiler.parameter("slot", slot);
+ compiler.add(this, "node_ies_light");
}
/* Musgrave Texture */
NODE_DEFINE(MusgraveTextureNode)
{
- NodeType* type = NodeType::add("musgrave_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("musgrave_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(MusgraveTextureNode);
+ TEXTURE_MAPPING_DEFINE(MusgraveTextureNode);
- static NodeEnum type_enum;
- type_enum.insert("multifractal", NODE_MUSGRAVE_MULTIFRACTAL);
- type_enum.insert("fBM", NODE_MUSGRAVE_FBM);
- type_enum.insert("hybrid_multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL);
- type_enum.insert("ridged_multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL);
- type_enum.insert("hetero_terrain", NODE_MUSGRAVE_HETERO_TERRAIN);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MUSGRAVE_FBM);
+ static NodeEnum type_enum;
+ type_enum.insert("multifractal", NODE_MUSGRAVE_MULTIFRACTAL);
+ type_enum.insert("fBM", NODE_MUSGRAVE_FBM);
+ type_enum.insert("hybrid_multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL);
+ type_enum.insert("ridged_multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL);
+ type_enum.insert("hetero_terrain", NODE_MUSGRAVE_HETERO_TERRAIN);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_MUSGRAVE_FBM);
- SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
- SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
- SOCKET_IN_FLOAT(dimension, "Dimension", 2.0f);
- SOCKET_IN_FLOAT(lacunarity, "Lacunarity", 1.0f);
- SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
- SOCKET_IN_FLOAT(gain, "Gain", 1.0f);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+ SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
+ SOCKET_IN_FLOAT(dimension, "Dimension", 2.0f);
+ SOCKET_IN_FLOAT(lacunarity, "Lacunarity", 1.0f);
+ SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
+ SOCKET_IN_FLOAT(gain, "Gain", 1.0f);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-MusgraveTextureNode::MusgraveTextureNode()
-: TextureNode(node_type)
+MusgraveTextureNode::MusgraveTextureNode() : TextureNode(node_type)
{
}
-void MusgraveTextureNode::compile(SVMCompiler& compiler)
+void MusgraveTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderInput *scale_in = input("Scale");
- ShaderInput *dimension_in = input("Dimension");
- ShaderInput *lacunarity_in = input("Lacunarity");
- ShaderInput *detail_in = input("Detail");
- ShaderInput *offset_in = input("Offset");
- ShaderInput *gain_in = input("Gain");
- ShaderOutput *fac_out = output("Fac");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *scale_in = input("Scale");
+ ShaderInput *dimension_in = input("Dimension");
+ ShaderInput *lacunarity_in = input("Lacunarity");
+ ShaderInput *detail_in = input("Detail");
+ ShaderInput *offset_in = input("Offset");
+ ShaderInput *gain_in = input("Gain");
+ ShaderOutput *fac_out = output("Fac");
+ ShaderOutput *color_out = output("Color");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_MUSGRAVE,
- compiler.encode_uchar4(
- type,
- vector_offset,
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(fac_out)),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(dimension_in),
- compiler.stack_assign_if_linked(lacunarity_in),
- compiler.stack_assign_if_linked(detail_in),
- compiler.stack_assign_if_linked(offset_in)),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(gain_in),
- compiler.stack_assign_if_linked(scale_in)));
- compiler.add_node(__float_as_int(dimension),
- __float_as_int(lacunarity),
- __float_as_int(detail),
- __float_as_int(offset));
- compiler.add_node(__float_as_int(gain),
- __float_as_int(scale));
+ compiler.add_node(NODE_TEX_MUSGRAVE,
+ compiler.encode_uchar4(type,
+ vector_offset,
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(fac_out)),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(dimension_in),
+ compiler.stack_assign_if_linked(lacunarity_in),
+ compiler.stack_assign_if_linked(detail_in),
+ compiler.stack_assign_if_linked(offset_in)),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(gain_in),
+ compiler.stack_assign_if_linked(scale_in)));
+ compiler.add_node(__float_as_int(dimension),
+ __float_as_int(lacunarity),
+ __float_as_int(detail),
+ __float_as_int(offset));
+ compiler.add_node(__float_as_int(gain), __float_as_int(scale));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void MusgraveTextureNode::compile(OSLCompiler& compiler)
+void MusgraveTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.parameter(this, "type");
- compiler.add(this, "node_musgrave_texture");
+ compiler.parameter(this, "type");
+ compiler.add(this, "node_musgrave_texture");
}
/* Wave Texture */
NODE_DEFINE(WaveTextureNode)
{
- NodeType* type = NodeType::add("wave_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("wave_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(WaveTextureNode);
+ TEXTURE_MAPPING_DEFINE(WaveTextureNode);
- static NodeEnum type_enum;
- type_enum.insert("bands", NODE_WAVE_BANDS);
- type_enum.insert("rings", NODE_WAVE_RINGS);
- SOCKET_ENUM(type, "Type", type_enum, NODE_WAVE_BANDS);
+ static NodeEnum type_enum;
+ type_enum.insert("bands", NODE_WAVE_BANDS);
+ type_enum.insert("rings", NODE_WAVE_RINGS);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_WAVE_BANDS);
- static NodeEnum profile_enum;
- profile_enum.insert("sine", NODE_WAVE_PROFILE_SIN);
- profile_enum.insert("saw", NODE_WAVE_PROFILE_SAW);
- SOCKET_ENUM(profile, "Profile", profile_enum, NODE_WAVE_PROFILE_SIN);
+ static NodeEnum profile_enum;
+ profile_enum.insert("sine", NODE_WAVE_PROFILE_SIN);
+ profile_enum.insert("saw", NODE_WAVE_PROFILE_SAW);
+ SOCKET_ENUM(profile, "Profile", profile_enum, NODE_WAVE_PROFILE_SIN);
- SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
- SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
- SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
- SOCKET_IN_FLOAT(detail_scale, "Detail Scale", 0.0f);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+ SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
+ SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
+ SOCKET_IN_FLOAT(detail_scale, "Detail Scale", 0.0f);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-WaveTextureNode::WaveTextureNode()
-: TextureNode(node_type)
+WaveTextureNode::WaveTextureNode() : TextureNode(node_type)
{
}
-void WaveTextureNode::compile(SVMCompiler& compiler)
+void WaveTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *scale_in = input("Scale");
- ShaderInput *distortion_in = input("Distortion");
- ShaderInput *dscale_in = input("Detail Scale");
- ShaderInput *detail_in = input("Detail");
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *fac_out = output("Fac");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *scale_in = input("Scale");
+ ShaderInput *distortion_in = input("Distortion");
+ ShaderInput *dscale_in = input("Detail Scale");
+ ShaderInput *detail_in = input("Detail");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *fac_out = output("Fac");
+ ShaderOutput *color_out = output("Color");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_WAVE,
- compiler.encode_uchar4(
- type,
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(fac_out),
- compiler.stack_assign_if_linked(dscale_in)),
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign_if_linked(scale_in),
- compiler.stack_assign_if_linked(detail_in),
- compiler.stack_assign_if_linked(distortion_in)),
- profile);
+ compiler.add_node(NODE_TEX_WAVE,
+ compiler.encode_uchar4(type,
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(fac_out),
+ compiler.stack_assign_if_linked(dscale_in)),
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign_if_linked(scale_in),
+ compiler.stack_assign_if_linked(detail_in),
+ compiler.stack_assign_if_linked(distortion_in)),
+ profile);
- compiler.add_node(
- __float_as_int(scale),
- __float_as_int(detail),
- __float_as_int(distortion),
- __float_as_int(detail_scale));
+ compiler.add_node(__float_as_int(scale),
+ __float_as_int(detail),
+ __float_as_int(distortion),
+ __float_as_int(detail_scale));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void WaveTextureNode::compile(OSLCompiler& compiler)
+void WaveTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.parameter(this, "type");
- compiler.parameter(this, "profile");
+ compiler.parameter(this, "type");
+ compiler.parameter(this, "profile");
- compiler.add(this, "node_wave_texture");
+ compiler.add(this, "node_wave_texture");
}
/* Magic Texture */
NODE_DEFINE(MagicTextureNode)
{
- NodeType* type = NodeType::add("magic_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("magic_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(MagicTextureNode);
+ TEXTURE_MAPPING_DEFINE(MagicTextureNode);
- SOCKET_INT(depth, "Depth", 2);
+ SOCKET_INT(depth, "Depth", 2);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
- SOCKET_IN_FLOAT(distortion, "Distortion", 1.0f);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
+ SOCKET_IN_FLOAT(distortion, "Distortion", 1.0f);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-MagicTextureNode::MagicTextureNode()
-: TextureNode(node_type)
+MagicTextureNode::MagicTextureNode() : TextureNode(node_type)
{
}
-void MagicTextureNode::compile(SVMCompiler& compiler)
+void MagicTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderInput *scale_in = input("Scale");
- ShaderInput *distortion_in = input("Distortion");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *fac_out = output("Fac");
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *scale_in = input("Scale");
+ ShaderInput *distortion_in = input("Distortion");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *fac_out = output("Fac");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_MAGIC,
- compiler.encode_uchar4(
- depth,
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(fac_out)),
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign_if_linked(scale_in),
- compiler.stack_assign_if_linked(distortion_in)));
- compiler.add_node(
- __float_as_int(scale),
- __float_as_int(distortion));
+ compiler.add_node(NODE_TEX_MAGIC,
+ compiler.encode_uchar4(depth,
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(fac_out)),
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign_if_linked(scale_in),
+ compiler.stack_assign_if_linked(distortion_in)));
+ compiler.add_node(__float_as_int(scale), __float_as_int(distortion));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void MagicTextureNode::compile(OSLCompiler& compiler)
+void MagicTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.parameter(this, "depth");
- compiler.add(this, "node_magic_texture");
+ compiler.parameter(this, "depth");
+ compiler.add(this, "node_magic_texture");
}
/* Checker Texture */
NODE_DEFINE(CheckerTextureNode)
{
- NodeType* type = NodeType::add("checker_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("checker_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(CheckerTextureNode);
+ TEXTURE_MAPPING_DEFINE(CheckerTextureNode);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_IN_COLOR(color1, "Color1", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_COLOR(color2, "Color2", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_COLOR(color1, "Color1", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_COLOR(color2, "Color2", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-CheckerTextureNode::CheckerTextureNode()
-: TextureNode(node_type)
+CheckerTextureNode::CheckerTextureNode() : TextureNode(node_type)
{
}
-void CheckerTextureNode::compile(SVMCompiler& compiler)
+void CheckerTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderInput *color1_in = input("Color1");
- ShaderInput *color2_in = input("Color2");
- ShaderInput *scale_in = input("Scale");
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *color1_in = input("Color1");
+ ShaderInput *color2_in = input("Color2");
+ ShaderInput *scale_in = input("Scale");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *fac_out = output("Fac");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *fac_out = output("Fac");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_CHECKER,
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign(color1_in),
- compiler.stack_assign(color2_in),
- compiler.stack_assign_if_linked(scale_in)),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(fac_out)),
- __float_as_int(scale));
+ compiler.add_node(NODE_TEX_CHECKER,
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign(color1_in),
+ compiler.stack_assign(color2_in),
+ compiler.stack_assign_if_linked(scale_in)),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(fac_out)),
+ __float_as_int(scale));
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void CheckerTextureNode::compile(OSLCompiler& compiler)
+void CheckerTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.add(this, "node_checker_texture");
+ compiler.add(this, "node_checker_texture");
}
/* Brick Texture */
NODE_DEFINE(BrickTextureNode)
{
- NodeType* type = NodeType::add("brick_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("brick_texture", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(BrickTextureNode);
+ TEXTURE_MAPPING_DEFINE(BrickTextureNode);
- SOCKET_FLOAT(offset, "Offset", 0.5f);
- SOCKET_INT(offset_frequency, "Offset Frequency", 2);
- SOCKET_FLOAT(squash, "Squash", 1.0f);
- SOCKET_INT(squash_frequency, "Squash Frequency", 2);
+ SOCKET_FLOAT(offset, "Offset", 0.5f);
+ SOCKET_INT(offset_frequency, "Offset Frequency", 2);
+ SOCKET_FLOAT(squash, "Squash", 1.0f);
+ SOCKET_INT(squash_frequency, "Squash Frequency", 2);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+ SOCKET_IN_POINT(
+ vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
- SOCKET_IN_COLOR(color1, "Color1", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_COLOR(color2, "Color2", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_COLOR(mortar, "Mortar", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
- SOCKET_IN_FLOAT(mortar_size, "Mortar Size", 0.02f);
- SOCKET_IN_FLOAT(mortar_smooth, "Mortar Smooth", 0.0f);
- SOCKET_IN_FLOAT(bias, "Bias", 0.0f);
- SOCKET_IN_FLOAT(brick_width, "Brick Width", 0.5f);
- SOCKET_IN_FLOAT(row_height, "Row Height", 0.25f);
+ SOCKET_IN_COLOR(color1, "Color1", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_COLOR(color2, "Color2", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_COLOR(mortar, "Mortar", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
+ SOCKET_IN_FLOAT(mortar_size, "Mortar Size", 0.02f);
+ SOCKET_IN_FLOAT(mortar_smooth, "Mortar Smooth", 0.0f);
+ SOCKET_IN_FLOAT(bias, "Bias", 0.0f);
+ SOCKET_IN_FLOAT(brick_width, "Brick Width", 0.5f);
+ SOCKET_IN_FLOAT(row_height, "Row Height", 0.25f);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-BrickTextureNode::BrickTextureNode()
-: TextureNode(node_type)
+BrickTextureNode::BrickTextureNode() : TextureNode(node_type)
{
}
-void BrickTextureNode::compile(SVMCompiler& compiler)
+void BrickTextureNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderInput *color1_in = input("Color1");
- ShaderInput *color2_in = input("Color2");
- ShaderInput *mortar_in = input("Mortar");
- ShaderInput *scale_in = input("Scale");
- ShaderInput *mortar_size_in = input("Mortar Size");
- ShaderInput *mortar_smooth_in = input("Mortar Smooth");
- ShaderInput *bias_in = input("Bias");
- ShaderInput *brick_width_in = input("Brick Width");
- ShaderInput *row_height_in = input("Row Height");
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *color1_in = input("Color1");
+ ShaderInput *color2_in = input("Color2");
+ ShaderInput *mortar_in = input("Mortar");
+ ShaderInput *scale_in = input("Scale");
+ ShaderInput *mortar_size_in = input("Mortar Size");
+ ShaderInput *mortar_smooth_in = input("Mortar Smooth");
+ ShaderInput *bias_in = input("Bias");
+ ShaderInput *brick_width_in = input("Brick Width");
+ ShaderInput *row_height_in = input("Row Height");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *fac_out = output("Fac");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *fac_out = output("Fac");
- int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+ int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
- compiler.add_node(NODE_TEX_BRICK,
- compiler.encode_uchar4(
- vector_offset,
- compiler.stack_assign(color1_in),
- compiler.stack_assign(color2_in),
- compiler.stack_assign(mortar_in)),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(scale_in),
- compiler.stack_assign_if_linked(mortar_size_in),
- compiler.stack_assign_if_linked(bias_in),
- compiler.stack_assign_if_linked(brick_width_in)),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(row_height_in),
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(fac_out),
- compiler.stack_assign_if_linked(mortar_smooth_in)));
+ compiler.add_node(NODE_TEX_BRICK,
+ compiler.encode_uchar4(vector_offset,
+ compiler.stack_assign(color1_in),
+ compiler.stack_assign(color2_in),
+ compiler.stack_assign(mortar_in)),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(scale_in),
+ compiler.stack_assign_if_linked(mortar_size_in),
+ compiler.stack_assign_if_linked(bias_in),
+ compiler.stack_assign_if_linked(brick_width_in)),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(row_height_in),
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(fac_out),
+ compiler.stack_assign_if_linked(mortar_smooth_in)));
- compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency),
- __float_as_int(scale),
- __float_as_int(mortar_size),
- __float_as_int(bias));
+ compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency),
+ __float_as_int(scale),
+ __float_as_int(mortar_size),
+ __float_as_int(bias));
- compiler.add_node(__float_as_int(brick_width),
- __float_as_int(row_height),
- __float_as_int(offset),
- __float_as_int(squash));
+ compiler.add_node(__float_as_int(brick_width),
+ __float_as_int(row_height),
+ __float_as_int(offset),
+ __float_as_int(squash));
- compiler.add_node(__float_as_int(mortar_smooth),
- SVM_STACK_INVALID,
- SVM_STACK_INVALID,
- SVM_STACK_INVALID);
+ compiler.add_node(
+ __float_as_int(mortar_smooth), SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID);
- tex_mapping.compile_end(compiler, vector_in, vector_offset);
+ tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
-void BrickTextureNode::compile(OSLCompiler& compiler)
+void BrickTextureNode::compile(OSLCompiler &compiler)
{
- tex_mapping.compile(compiler);
+ tex_mapping.compile(compiler);
- compiler.parameter(this, "offset");
- compiler.parameter(this, "offset_frequency");
- compiler.parameter(this, "squash");
- compiler.parameter(this, "squash_frequency");
- compiler.add(this, "node_brick_texture");
+ compiler.parameter(this, "offset");
+ compiler.parameter(this, "offset_frequency");
+ compiler.parameter(this, "squash");
+ compiler.parameter(this, "squash_frequency");
+ compiler.add(this, "node_brick_texture");
}
/* Point Density Texture */
NODE_DEFINE(PointDensityTextureNode)
{
- NodeType* type = NodeType::add("point_density_texture", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("point_density_texture", create, NodeType::SHADER);
- SOCKET_STRING(filename, "Filename", ustring());
+ SOCKET_STRING(filename, "Filename", ustring());
- static NodeEnum space_enum;
- space_enum.insert("object", NODE_TEX_VOXEL_SPACE_OBJECT);
- space_enum.insert("world", NODE_TEX_VOXEL_SPACE_WORLD);
- SOCKET_ENUM(space, "Space", space_enum, NODE_TEX_VOXEL_SPACE_OBJECT);
+ static NodeEnum space_enum;
+ space_enum.insert("object", NODE_TEX_VOXEL_SPACE_OBJECT);
+ space_enum.insert("world", NODE_TEX_VOXEL_SPACE_WORLD);
+ SOCKET_ENUM(space, "Space", space_enum, NODE_TEX_VOXEL_SPACE_OBJECT);
- static NodeEnum interpolation_enum;
- interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
- interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
- interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
- interpolation_enum.insert("smart", INTERPOLATION_SMART);
- SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
+ static NodeEnum interpolation_enum;
+ interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
+ interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
+ interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
+ interpolation_enum.insert("smart", INTERPOLATION_SMART);
+ SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
- SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
+ SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION);
+ SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION);
- SOCKET_OUT_FLOAT(density, "Density");
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(density, "Density");
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-PointDensityTextureNode::PointDensityTextureNode()
-: ShaderNode(node_type)
+PointDensityTextureNode::PointDensityTextureNode() : ShaderNode(node_type)
{
- image_manager = NULL;
- slot = -1;
- builtin_data = NULL;
+ image_manager = NULL;
+ slot = -1;
+ builtin_data = NULL;
}
PointDensityTextureNode::~PointDensityTextureNode()
{
- if(image_manager) {
- image_manager->remove_image(filename.string(),
- builtin_data,
- interpolation,
- EXTENSION_CLIP,
- true);
- }
+ if (image_manager) {
+ image_manager->remove_image(
+ filename.string(), builtin_data, interpolation, EXTENSION_CLIP, true);
+ }
}
ShaderNode *PointDensityTextureNode::clone() const
{
- PointDensityTextureNode *node = new PointDensityTextureNode(*this);
- node->image_manager = NULL;
- node->slot = -1;
- return node;
+ PointDensityTextureNode *node = new PointDensityTextureNode(*this);
+ node->image_manager = NULL;
+ node->slot = -1;
+ return node;
}
-void PointDensityTextureNode::attributes(Shader *shader,
- AttributeRequestSet *attributes)
+void PointDensityTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_volume)
- attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ if (shader->has_volume)
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
- ShaderNode::attributes(shader, attributes);
+ ShaderNode::attributes(shader, attributes);
}
void PointDensityTextureNode::add_image()
{
- if(slot == -1) {
- ImageMetaData metadata;
- slot = image_manager->add_image(filename.string(), builtin_data,
- false, 0,
- interpolation,
- EXTENSION_CLIP,
- true,
- metadata);
- }
-}
-
-void PointDensityTextureNode::compile(SVMCompiler& compiler)
-{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *density_out = output("Density");
- ShaderOutput *color_out = output("Color");
-
- const bool use_density = !density_out->links.empty();
- const bool use_color = !color_out->links.empty();
-
- image_manager = compiler.image_manager;
-
- if(use_density || use_color) {
- add_image();
-
- if(slot != -1) {
- compiler.stack_assign(vector_in);
- compiler.add_node(NODE_TEX_VOXEL,
- slot,
- compiler.encode_uchar4(compiler.stack_assign(vector_in),
- compiler.stack_assign_if_linked(density_out),
- compiler.stack_assign_if_linked(color_out),
- space));
- if(space == NODE_TEX_VOXEL_SPACE_WORLD) {
- compiler.add_node(tfm.x);
- compiler.add_node(tfm.y);
- compiler.add_node(tfm.z);
- }
- }
- else {
- if(use_density) {
- compiler.add_node(NODE_VALUE_F,
- __float_as_int(0.0f),
- compiler.stack_assign(density_out));
- }
- if(use_color) {
- compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
- compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
- TEX_IMAGE_MISSING_G,
- TEX_IMAGE_MISSING_B));
- }
- }
- }
-}
-
-void PointDensityTextureNode::compile(OSLCompiler& compiler)
-{
- ShaderOutput *density_out = output("Density");
- ShaderOutput *color_out = output("Color");
-
- const bool use_density = !density_out->links.empty();
- const bool use_color = !color_out->links.empty();
-
- image_manager = compiler.image_manager;
-
- if(use_density || use_color) {
- add_image();
-
- if(slot != -1) {
- compiler.parameter("filename", string_printf("@i%d", slot).c_str());
- }
- if(space == NODE_TEX_VOXEL_SPACE_WORLD) {
- compiler.parameter("mapping", tfm);
- compiler.parameter("use_mapping", 1);
- }
- compiler.parameter(this, "interpolation");
- compiler.add(this, "node_voxel_texture");
- }
+ if (slot == -1) {
+ ImageMetaData metadata;
+ slot = image_manager->add_image(
+ filename.string(), builtin_data, false, 0, interpolation, EXTENSION_CLIP, true, metadata);
+ }
+}
+
+void PointDensityTextureNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *density_out = output("Density");
+ ShaderOutput *color_out = output("Color");
+
+ const bool use_density = !density_out->links.empty();
+ const bool use_color = !color_out->links.empty();
+
+ image_manager = compiler.image_manager;
+
+ if (use_density || use_color) {
+ add_image();
+
+ if (slot != -1) {
+ compiler.stack_assign(vector_in);
+ compiler.add_node(NODE_TEX_VOXEL,
+ slot,
+ compiler.encode_uchar4(compiler.stack_assign(vector_in),
+ compiler.stack_assign_if_linked(density_out),
+ compiler.stack_assign_if_linked(color_out),
+ space));
+ if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
+ compiler.add_node(tfm.x);
+ compiler.add_node(tfm.y);
+ compiler.add_node(tfm.z);
+ }
+ }
+ else {
+ if (use_density) {
+ compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(density_out));
+ }
+ if (use_color) {
+ compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_VALUE_V,
+ make_float3(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B));
+ }
+ }
+ }
+}
+
+void PointDensityTextureNode::compile(OSLCompiler &compiler)
+{
+ ShaderOutput *density_out = output("Density");
+ ShaderOutput *color_out = output("Color");
+
+ const bool use_density = !density_out->links.empty();
+ const bool use_color = !color_out->links.empty();
+
+ image_manager = compiler.image_manager;
+
+ if (use_density || use_color) {
+ add_image();
+
+ if (slot != -1) {
+ compiler.parameter("filename", string_printf("@i%d", slot).c_str());
+ }
+ if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
+ compiler.parameter("mapping", tfm);
+ compiler.parameter("use_mapping", 1);
+ }
+ compiler.parameter(this, "interpolation");
+ compiler.add(this, "node_voxel_texture");
+ }
}
/* Normal */
NODE_DEFINE(NormalNode)
{
- NodeType* type = NodeType::add("normal", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("normal", create, NodeType::SHADER);
- SOCKET_VECTOR(direction, "direction", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_VECTOR(direction, "direction", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_NORMAL(normal, "Normal");
- SOCKET_OUT_FLOAT(dot, "Dot");
+ SOCKET_OUT_NORMAL(normal, "Normal");
+ SOCKET_OUT_FLOAT(dot, "Dot");
- return type;
+ return type;
}
-NormalNode::NormalNode()
-: ShaderNode(node_type)
+NormalNode::NormalNode() : ShaderNode(node_type)
{
}
-void NormalNode::compile(SVMCompiler& compiler)
+void NormalNode::compile(SVMCompiler &compiler)
{
- ShaderInput *normal_in = input("Normal");
- ShaderOutput *normal_out = output("Normal");
- ShaderOutput *dot_out = output("Dot");
+ ShaderInput *normal_in = input("Normal");
+ ShaderOutput *normal_out = output("Normal");
+ ShaderOutput *dot_out = output("Dot");
- compiler.add_node(NODE_NORMAL,
- compiler.stack_assign(normal_in),
- compiler.stack_assign(normal_out),
- compiler.stack_assign(dot_out));
- compiler.add_node(
- __float_as_int(direction.x),
- __float_as_int(direction.y),
- __float_as_int(direction.z));
+ compiler.add_node(NODE_NORMAL,
+ compiler.stack_assign(normal_in),
+ compiler.stack_assign(normal_out),
+ compiler.stack_assign(dot_out));
+ compiler.add_node(
+ __float_as_int(direction.x), __float_as_int(direction.y), __float_as_int(direction.z));
}
-void NormalNode::compile(OSLCompiler& compiler)
+void NormalNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "direction");
- compiler.add(this, "node_normal");
+ compiler.parameter(this, "direction");
+ compiler.add(this, "node_normal");
}
/* Mapping */
NODE_DEFINE(MappingNode)
{
- NodeType* type = NodeType::add("mapping", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("mapping", create, NodeType::SHADER);
- TEXTURE_MAPPING_DEFINE(MappingNode);
+ TEXTURE_MAPPING_DEFINE(MappingNode);
- SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_POINT(vector, "Vector");
+ SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_OUT_POINT(vector, "Vector");
- return type;
+ return type;
}
-MappingNode::MappingNode()
-: ShaderNode(node_type)
+MappingNode::MappingNode() : ShaderNode(node_type)
{
}
-void MappingNode::compile(SVMCompiler& compiler)
+void MappingNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *vector_out = output("Vector");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *vector_out = output("Vector");
- tex_mapping.compile(compiler, compiler.stack_assign(vector_in), compiler.stack_assign(vector_out));
+ tex_mapping.compile(
+ compiler, compiler.stack_assign(vector_in), compiler.stack_assign(vector_out));
}
-void MappingNode::compile(OSLCompiler& compiler)
+void MappingNode::compile(OSLCompiler &compiler)
{
- compiler.parameter("Matrix", tex_mapping.compute_transform());
- compiler.parameter_point("mapping_min", tex_mapping.min);
- compiler.parameter_point("mapping_max", tex_mapping.max);
- compiler.parameter("use_minmax", tex_mapping.use_minmax);
+ compiler.parameter("Matrix", tex_mapping.compute_transform());
+ compiler.parameter_point("mapping_min", tex_mapping.min);
+ compiler.parameter_point("mapping_max", tex_mapping.max);
+ compiler.parameter("use_minmax", tex_mapping.use_minmax);
- compiler.add(this, "node_mapping");
+ compiler.add(this, "node_mapping");
}
/* RGBToBW */
NODE_DEFINE(RGBToBWNode)
{
- NodeType* type = NodeType::add("rgb_to_bw", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("rgb_to_bw", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_FLOAT(val, "Val");
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_OUT_FLOAT(val, "Val");
- return type;
+ return type;
}
-RGBToBWNode::RGBToBWNode()
-: ShaderNode(node_type)
+RGBToBWNode::RGBToBWNode() : ShaderNode(node_type)
{
}
-void RGBToBWNode::constant_fold(const ConstantFolder& folder)
+void RGBToBWNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- float val = folder.scene->shader_manager->linear_rgb_to_gray(color);
- folder.make_constant(val);
- }
+ if (folder.all_inputs_constant()) {
+ float val = folder.scene->shader_manager->linear_rgb_to_gray(color);
+ folder.make_constant(val);
+ }
}
-void RGBToBWNode::compile(SVMCompiler& compiler)
+void RGBToBWNode::compile(SVMCompiler &compiler)
{
- compiler.add_node(NODE_CONVERT,
- NODE_CONVERT_CF,
- compiler.stack_assign(inputs[0]),
- compiler.stack_assign(outputs[0]));
+ compiler.add_node(NODE_CONVERT,
+ NODE_CONVERT_CF,
+ compiler.stack_assign(inputs[0]),
+ compiler.stack_assign(outputs[0]));
}
-void RGBToBWNode::compile(OSLCompiler& compiler)
+void RGBToBWNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_rgb_to_bw");
+ compiler.add(this, "node_rgb_to_bw");
}
/* Convert */
-const NodeType* ConvertNode::node_types[ConvertNode::MAX_TYPE][ConvertNode::MAX_TYPE];
+const NodeType *ConvertNode::node_types[ConvertNode::MAX_TYPE][ConvertNode::MAX_TYPE];
bool ConvertNode::initialized = ConvertNode::register_types();
-Node* ConvertNode::create(const NodeType *type)
+Node *ConvertNode::create(const NodeType *type)
{
- return new ConvertNode(type->inputs[0].type, type->outputs[0].type);
+ return new ConvertNode(type->inputs[0].type, type->outputs[0].type);
}
bool ConvertNode::register_types()
{
- const int num_types = 8;
- SocketType::Type types[num_types] = {SocketType::FLOAT,
- SocketType::INT,
- SocketType::COLOR,
- SocketType::VECTOR,
- SocketType::POINT,
- SocketType::NORMAL,
- SocketType::STRING,
- SocketType::CLOSURE};
-
- for(size_t i = 0; i < num_types; i++) {
- SocketType::Type from = types[i];
- ustring from_name(SocketType::type_name(from));
- ustring from_value_name("value_" + from_name.string());
-
- for(size_t j = 0; j < num_types; j++) {
- SocketType::Type to = types[j];
- ustring to_name(SocketType::type_name(to));
- ustring to_value_name("value_" + to_name.string());
-
- string node_name = "convert_" + from_name.string() + "_to_" + to_name.string();
- NodeType* type = NodeType::add(node_name.c_str(), create, NodeType::SHADER);
-
- type->register_input(from_value_name, from_value_name, from,
- SOCKET_OFFSETOF(ConvertNode, value_float), SocketType::zero_default_value(),
- NULL, NULL, SocketType::LINKABLE);
- type->register_output(to_value_name, to_value_name, to);
-
- assert(from < MAX_TYPE);
- assert(to < MAX_TYPE);
-
- node_types[from][to] = type;
- }
- }
-
- return true;
+ const int num_types = 8;
+ SocketType::Type types[num_types] = {SocketType::FLOAT,
+ SocketType::INT,
+ SocketType::COLOR,
+ SocketType::VECTOR,
+ SocketType::POINT,
+ SocketType::NORMAL,
+ SocketType::STRING,
+ SocketType::CLOSURE};
+
+ for (size_t i = 0; i < num_types; i++) {
+ SocketType::Type from = types[i];
+ ustring from_name(SocketType::type_name(from));
+ ustring from_value_name("value_" + from_name.string());
+
+ for (size_t j = 0; j < num_types; j++) {
+ SocketType::Type to = types[j];
+ ustring to_name(SocketType::type_name(to));
+ ustring to_value_name("value_" + to_name.string());
+
+ string node_name = "convert_" + from_name.string() + "_to_" + to_name.string();
+ NodeType *type = NodeType::add(node_name.c_str(), create, NodeType::SHADER);
+
+ type->register_input(from_value_name,
+ from_value_name,
+ from,
+ SOCKET_OFFSETOF(ConvertNode, value_float),
+ SocketType::zero_default_value(),
+ NULL,
+ NULL,
+ SocketType::LINKABLE);
+ type->register_output(to_value_name, to_value_name, to);
+
+ assert(from < MAX_TYPE);
+ assert(to < MAX_TYPE);
+
+ node_types[from][to] = type;
+ }
+ }
+
+ return true;
}
ConvertNode::ConvertNode(SocketType::Type from_, SocketType::Type to_, bool autoconvert)
-: ShaderNode(node_types[from_][to_])
-{
- from = from_;
- to = to_;
-
- if(from == to)
- special_type = SHADER_SPECIAL_TYPE_PROXY;
- else if(autoconvert)
- special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
-}
-
-void ConvertNode::constant_fold(const ConstantFolder& folder)
-{
- /* proxy nodes should have been removed at this point */
- assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
-
- /* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */
-
- if(folder.all_inputs_constant()) {
- if(from == SocketType::FLOAT) {
- if(SocketType::is_float3(to)) {
- folder.make_constant(make_float3(value_float, value_float, value_float));
- }
- }
- else if(SocketType::is_float3(from)) {
- if(to == SocketType::FLOAT) {
- if(from == SocketType::COLOR) {
- /* color to float */
- float val = folder.scene->shader_manager->linear_rgb_to_gray(value_color);
- folder.make_constant(val);
- }
- else {
- /* vector/point/normal to float */
- folder.make_constant(average(value_vector));
- }
- }
- else if(SocketType::is_float3(to)) {
- folder.make_constant(value_color);
- }
- }
- }
- else {
- ShaderInput *in = inputs[0];
- ShaderNode *prev = in->link->parent;
-
- /* no-op conversion of A to B to A */
- if(prev->type == node_types[to][from]) {
- ShaderInput *prev_in = prev->inputs[0];
-
- if(SocketType::is_float3(from) && (to == SocketType::FLOAT || SocketType::is_float3(to)) && prev_in->link) {
- folder.bypass(prev_in->link);
- }
- }
- }
-}
-
-void ConvertNode::compile(SVMCompiler& compiler)
-{
- /* proxy nodes should have been removed at this point */
- assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
-
- ShaderInput *in = inputs[0];
- ShaderOutput *out = outputs[0];
-
- if(from == SocketType::FLOAT) {
- if(to == SocketType::INT)
- /* float to int */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out));
- else
- /* float to float3 */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out));
- }
- else if(from == SocketType::INT) {
- if(to == SocketType::FLOAT)
- /* int to float */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out));
- else
- /* int to vector/point/normal */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out));
- }
- else if(to == SocketType::FLOAT) {
- if(from == SocketType::COLOR)
- /* color to float */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out));
- else
- /* vector/point/normal to float */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out));
- }
- else if(to == SocketType::INT) {
- if(from == SocketType::COLOR)
- /* color to int */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out));
- else
- /* vector/point/normal to int */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out));
- }
- else {
- /* float3 to float3 */
- if(in->link) {
- /* no op in SVM */
- compiler.stack_link(in, out);
- }
- else {
- /* set 0,0,0 value */
- compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out));
- compiler.add_node(NODE_VALUE_V, value_color);
- }
- }
-}
-
-void ConvertNode::compile(OSLCompiler& compiler)
-{
- /* proxy nodes should have been removed at this point */
- assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
-
- if(from == SocketType::FLOAT)
- compiler.add(this, "node_convert_from_float");
- else if(from == SocketType::INT)
- compiler.add(this, "node_convert_from_int");
- else if(from == SocketType::COLOR)
- compiler.add(this, "node_convert_from_color");
- else if(from == SocketType::VECTOR)
- compiler.add(this, "node_convert_from_vector");
- else if(from == SocketType::POINT)
- compiler.add(this, "node_convert_from_point");
- else if(from == SocketType::NORMAL)
- compiler.add(this, "node_convert_from_normal");
- else
- assert(0);
+ : ShaderNode(node_types[from_][to_])
+{
+ from = from_;
+ to = to_;
+
+ if (from == to)
+ special_type = SHADER_SPECIAL_TYPE_PROXY;
+ else if (autoconvert)
+ special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
+}
+
+void ConvertNode::constant_fold(const ConstantFolder &folder)
+{
+ /* proxy nodes should have been removed at this point */
+ assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
+
+ /* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */
+
+ if (folder.all_inputs_constant()) {
+ if (from == SocketType::FLOAT) {
+ if (SocketType::is_float3(to)) {
+ folder.make_constant(make_float3(value_float, value_float, value_float));
+ }
+ }
+ else if (SocketType::is_float3(from)) {
+ if (to == SocketType::FLOAT) {
+ if (from == SocketType::COLOR) {
+ /* color to float */
+ float val = folder.scene->shader_manager->linear_rgb_to_gray(value_color);
+ folder.make_constant(val);
+ }
+ else {
+ /* vector/point/normal to float */
+ folder.make_constant(average(value_vector));
+ }
+ }
+ else if (SocketType::is_float3(to)) {
+ folder.make_constant(value_color);
+ }
+ }
+ }
+ else {
+ ShaderInput *in = inputs[0];
+ ShaderNode *prev = in->link->parent;
+
+ /* no-op conversion of A to B to A */
+ if (prev->type == node_types[to][from]) {
+ ShaderInput *prev_in = prev->inputs[0];
+
+ if (SocketType::is_float3(from) && (to == SocketType::FLOAT || SocketType::is_float3(to)) &&
+ prev_in->link) {
+ folder.bypass(prev_in->link);
+ }
+ }
+ }
+}
+
+void ConvertNode::compile(SVMCompiler &compiler)
+{
+ /* proxy nodes should have been removed at this point */
+ assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
+
+ ShaderInput *in = inputs[0];
+ ShaderOutput *out = outputs[0];
+
+ if (from == SocketType::FLOAT) {
+ if (to == SocketType::INT)
+ /* float to int */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out));
+ else
+ /* float to float3 */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out));
+ }
+ else if (from == SocketType::INT) {
+ if (to == SocketType::FLOAT)
+ /* int to float */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out));
+ else
+ /* int to vector/point/normal */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out));
+ }
+ else if (to == SocketType::FLOAT) {
+ if (from == SocketType::COLOR)
+ /* color to float */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out));
+ else
+ /* vector/point/normal to float */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out));
+ }
+ else if (to == SocketType::INT) {
+ if (from == SocketType::COLOR)
+ /* color to int */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out));
+ else
+ /* vector/point/normal to int */
+ compiler.add_node(
+ NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out));
+ }
+ else {
+ /* float3 to float3 */
+ if (in->link) {
+ /* no op in SVM */
+ compiler.stack_link(in, out);
+ }
+ else {
+ /* set 0,0,0 value */
+ compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out));
+ compiler.add_node(NODE_VALUE_V, value_color);
+ }
+ }
+}
+
+void ConvertNode::compile(OSLCompiler &compiler)
+{
+ /* proxy nodes should have been removed at this point */
+ assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
+
+ if (from == SocketType::FLOAT)
+ compiler.add(this, "node_convert_from_float");
+ else if (from == SocketType::INT)
+ compiler.add(this, "node_convert_from_int");
+ else if (from == SocketType::COLOR)
+ compiler.add(this, "node_convert_from_color");
+ else if (from == SocketType::VECTOR)
+ compiler.add(this, "node_convert_from_vector");
+ else if (from == SocketType::POINT)
+ compiler.add(this, "node_convert_from_point");
+ else if (from == SocketType::NORMAL)
+ compiler.add(this, "node_convert_from_normal");
+ else
+ assert(0);
}
/* Base type for all closure-type nodes */
-BsdfBaseNode::BsdfBaseNode(const NodeType *node_type)
- : ShaderNode(node_type)
+BsdfBaseNode::BsdfBaseNode(const NodeType *node_type) : ShaderNode(node_type)
{
- special_type = SHADER_SPECIAL_TYPE_CLOSURE;
+ special_type = SHADER_SPECIAL_TYPE_CLOSURE;
}
bool BsdfBaseNode::has_bump()
{
- /* detect if anything is plugged into the normal input besides the default */
- ShaderInput *normal_in = input("Normal");
- return (normal_in && normal_in->link &&
- normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY);
+ /* detect if anything is plugged into the normal input besides the default */
+ ShaderInput *normal_in = input("Normal");
+ return (normal_in && normal_in->link &&
+ normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY);
}
/* BSDF Closure */
-BsdfNode::BsdfNode(const NodeType *node_type)
-: BsdfBaseNode(node_type)
+BsdfNode::BsdfNode(const NodeType *node_type) : BsdfBaseNode(node_type)
{
}
-void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3, ShaderInput *param4)
+void BsdfNode::compile(SVMCompiler &compiler,
+ ShaderInput *param1,
+ ShaderInput *param2,
+ ShaderInput *param3,
+ ShaderInput *param4)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *normal_in = input("Normal");
- ShaderInput *tangent_in = input("Tangent");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *normal_in = input("Normal");
+ ShaderInput *tangent_in = input("Tangent");
- if(color_in->link)
- compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
- else
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
+ if (color_in->link)
+ compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
+ else
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
- int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID;
- int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) : SVM_STACK_INVALID;
- int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID;
- int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID;
+ int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID;
+ int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) :
+ SVM_STACK_INVALID;
+ int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID;
+ int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID;
- compiler.add_node(NODE_CLOSURE_BSDF,
- compiler.encode_uchar4(closure,
- (param1)? compiler.stack_assign(param1): SVM_STACK_INVALID,
- (param2)? compiler.stack_assign(param2): SVM_STACK_INVALID,
- compiler.closure_mix_weight_offset()),
- __float_as_int((param1)? get_float(param1->socket_type): 0.0f),
- __float_as_int((param2)? get_float(param2->socket_type): 0.0f));
+ compiler.add_node(
+ NODE_CLOSURE_BSDF,
+ compiler.encode_uchar4(closure,
+ (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID,
+ (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID,
+ compiler.closure_mix_weight_offset()),
+ __float_as_int((param1) ? get_float(param1->socket_type) : 0.0f),
+ __float_as_int((param2) ? get_float(param2->socket_type) : 0.0f));
- compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset);
+ compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset);
}
-void BsdfNode::compile(SVMCompiler& compiler)
+void BsdfNode::compile(SVMCompiler &compiler)
{
- compile(compiler, NULL, NULL);
+ compile(compiler, NULL, NULL);
}
-void BsdfNode::compile(OSLCompiler& /*compiler*/)
+void BsdfNode::compile(OSLCompiler & /*compiler*/)
{
- assert(0);
+ assert(0);
}
/* Anisotropic BSDF Closure */
NODE_DEFINE(AnisotropicBsdfNode)
{
- NodeType* type = NodeType::add("anisotropic_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("anisotropic_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- static NodeEnum distribution_enum;
- distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID);
- distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
- distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID);
- distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID);
- SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
+ static NodeEnum distribution_enum;
+ distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID);
+ distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
+ distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID);
+ distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID);
+ SOCKET_ENUM(
+ distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
- SOCKET_IN_VECTOR(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
+ SOCKET_IN_VECTOR(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
- SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
- SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.5f);
- SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
+ SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
+ SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.5f);
+ SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-AnisotropicBsdfNode::AnisotropicBsdfNode()
-: BsdfNode(node_type)
+AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
+ closure = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
}
void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- ShaderInput *tangent_in = input("Tangent");
+ if (shader->has_surface) {
+ ShaderInput *tangent_in = input("Tangent");
- if(!tangent_in->link)
- attributes->add(ATTR_STD_GENERATED);
- }
+ if (!tangent_in->link)
+ attributes->add(ATTR_STD_GENERATED);
+ }
- ShaderNode::attributes(shader, attributes);
+ ShaderNode::attributes(shader, attributes);
}
-void AnisotropicBsdfNode::compile(SVMCompiler& compiler)
+void AnisotropicBsdfNode::compile(SVMCompiler &compiler)
{
- closure = distribution;
+ closure = distribution;
- if(closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID)
- BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
- else
- BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
+ if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID)
+ BsdfNode::compile(
+ compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
+ else
+ BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
}
-void AnisotropicBsdfNode::compile(OSLCompiler& compiler)
+void AnisotropicBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "distribution");
- compiler.add(this, "node_anisotropic_bsdf");
+ compiler.parameter(this, "distribution");
+ compiler.add(this, "node_anisotropic_bsdf");
}
/* Glossy BSDF Closure */
NODE_DEFINE(GlossyBsdfNode)
{
- NodeType* type = NodeType::add("glossy_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("glossy_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- static NodeEnum distribution_enum;
- distribution_enum.insert("sharp", CLOSURE_BSDF_REFLECTION_ID);
- distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
- distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
- distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
- distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
- SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
- SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
+ static NodeEnum distribution_enum;
+ distribution_enum.insert("sharp", CLOSURE_BSDF_REFLECTION_ID);
+ distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
+ distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
+ distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
+ distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
+ SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
+ SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-GlossyBsdfNode::GlossyBsdfNode()
-: BsdfNode(node_type)
+GlossyBsdfNode::GlossyBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_MICROFACET_GGX_ID;
- distribution_orig = NBUILTIN_CLOSURES;
+ closure = CLOSURE_BSDF_MICROFACET_GGX_ID;
+ distribution_orig = NBUILTIN_CLOSURES;
}
void GlossyBsdfNode::simplify_settings(Scene *scene)
{
- if(distribution_orig == NBUILTIN_CLOSURES) {
- roughness_orig = roughness;
- distribution_orig = distribution;
- }
- else {
- /* By default we use original values, so we don't worry about restoring
- * defaults later one and can only do override when needed.
- */
- roughness = roughness_orig;
- distribution = distribution_orig;
- }
- Integrator *integrator = scene->integrator;
- ShaderInput *roughness_input = input("Roughness");
- if(integrator->filter_glossy == 0.0f) {
- /* Fallback to Sharp closure for Roughness close to 0.
- * Note: Keep the epsilon in sync with kernel!
- */
- if(!roughness_input->link && roughness <= 1e-4f) {
- VLOG(1) << "Using sharp glossy BSDF.";
- distribution = CLOSURE_BSDF_REFLECTION_ID;
- }
- }
- else {
- /* If filter glossy is used we replace Sharp glossy with GGX so we can
- * benefit from closure blur to remove unwanted noise.
- */
- if(roughness_input->link == NULL &&
- distribution == CLOSURE_BSDF_REFLECTION_ID)
- {
- VLOG(1) << "Using GGX glossy with filter glossy.";
- distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
- roughness = 0.0f;
- }
- }
- closure = distribution;
+ if (distribution_orig == NBUILTIN_CLOSURES) {
+ roughness_orig = roughness;
+ distribution_orig = distribution;
+ }
+ else {
+ /* By default we use original values, so we don't worry about restoring
+ * defaults later one and can only do override when needed.
+ */
+ roughness = roughness_orig;
+ distribution = distribution_orig;
+ }
+ Integrator *integrator = scene->integrator;
+ ShaderInput *roughness_input = input("Roughness");
+ if (integrator->filter_glossy == 0.0f) {
+ /* Fallback to Sharp closure for Roughness close to 0.
+ * Note: Keep the epsilon in sync with kernel!
+ */
+ if (!roughness_input->link && roughness <= 1e-4f) {
+ VLOG(1) << "Using sharp glossy BSDF.";
+ distribution = CLOSURE_BSDF_REFLECTION_ID;
+ }
+ }
+ else {
+ /* If filter glossy is used we replace Sharp glossy with GGX so we can
+ * benefit from closure blur to remove unwanted noise.
+ */
+ if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFLECTION_ID) {
+ VLOG(1) << "Using GGX glossy with filter glossy.";
+ distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
+ roughness = 0.0f;
+ }
+ }
+ closure = distribution;
}
bool GlossyBsdfNode::has_integrator_dependency()
{
- ShaderInput *roughness_input = input("Roughness");
- return !roughness_input->link &&
- (distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f);
+ ShaderInput *roughness_input = input("Roughness");
+ return !roughness_input->link &&
+ (distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f);
}
-void GlossyBsdfNode::compile(SVMCompiler& compiler)
+void GlossyBsdfNode::compile(SVMCompiler &compiler)
{
- closure = distribution;
+ closure = distribution;
- if(closure == CLOSURE_BSDF_REFLECTION_ID)
- BsdfNode::compile(compiler, NULL, NULL);
- else if(closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
- BsdfNode::compile(compiler, input("Roughness"), NULL, input("Color"));
- else
- BsdfNode::compile(compiler, input("Roughness"), NULL);
+ if (closure == CLOSURE_BSDF_REFLECTION_ID)
+ BsdfNode::compile(compiler, NULL, NULL);
+ else if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
+ BsdfNode::compile(compiler, input("Roughness"), NULL, input("Color"));
+ else
+ BsdfNode::compile(compiler, input("Roughness"), NULL);
}
-void GlossyBsdfNode::compile(OSLCompiler& compiler)
+void GlossyBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "distribution");
- compiler.add(this, "node_glossy_bsdf");
+ compiler.parameter(this, "distribution");
+ compiler.add(this, "node_glossy_bsdf");
}
/* Glass BSDF Closure */
NODE_DEFINE(GlassBsdfNode)
{
- NodeType* type = NodeType::add("glass_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("glass_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- static NodeEnum distribution_enum;
- distribution_enum.insert("sharp", CLOSURE_BSDF_SHARP_GLASS_ID);
- distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
- distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
- distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
- SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
- SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
- SOCKET_IN_FLOAT(IOR, "IOR", 0.3f);
+ static NodeEnum distribution_enum;
+ distribution_enum.insert("sharp", CLOSURE_BSDF_SHARP_GLASS_ID);
+ distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
+ distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
+ distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
+ SOCKET_ENUM(
+ distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
+ SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
+ SOCKET_IN_FLOAT(IOR, "IOR", 0.3f);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-GlassBsdfNode::GlassBsdfNode()
-: BsdfNode(node_type)
+GlassBsdfNode::GlassBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_SHARP_GLASS_ID;
- distribution_orig = NBUILTIN_CLOSURES;
+ closure = CLOSURE_BSDF_SHARP_GLASS_ID;
+ distribution_orig = NBUILTIN_CLOSURES;
}
void GlassBsdfNode::simplify_settings(Scene *scene)
{
- if(distribution_orig == NBUILTIN_CLOSURES) {
- roughness_orig = roughness;
- distribution_orig = distribution;
- }
- else {
- /* By default we use original values, so we don't worry about restoring
- * defaults later one and can only do override when needed.
- */
- roughness = roughness_orig;
- distribution = distribution_orig;
- }
- Integrator *integrator = scene->integrator;
- ShaderInput *roughness_input = input("Roughness");
- if(integrator->filter_glossy == 0.0f) {
- /* Fallback to Sharp closure for Roughness close to 0.
- * Note: Keep the epsilon in sync with kernel!
- */
- if(!roughness_input->link && roughness <= 1e-4f) {
- VLOG(1) << "Using sharp glass BSDF.";
- distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
- }
- }
- else {
- /* If filter glossy is used we replace Sharp glossy with GGX so we can
- * benefit from closure blur to remove unwanted noise.
- */
- if(roughness_input->link == NULL &&
- distribution == CLOSURE_BSDF_SHARP_GLASS_ID)
- {
- VLOG(1) << "Using GGX glass with filter glossy.";
- distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
- roughness = 0.0f;
- }
- }
- closure = distribution;
+ if (distribution_orig == NBUILTIN_CLOSURES) {
+ roughness_orig = roughness;
+ distribution_orig = distribution;
+ }
+ else {
+ /* By default we use original values, so we don't worry about restoring
+ * defaults later one and can only do override when needed.
+ */
+ roughness = roughness_orig;
+ distribution = distribution_orig;
+ }
+ Integrator *integrator = scene->integrator;
+ ShaderInput *roughness_input = input("Roughness");
+ if (integrator->filter_glossy == 0.0f) {
+ /* Fallback to Sharp closure for Roughness close to 0.
+ * Note: Keep the epsilon in sync with kernel!
+ */
+ if (!roughness_input->link && roughness <= 1e-4f) {
+ VLOG(1) << "Using sharp glass BSDF.";
+ distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
+ }
+ }
+ else {
+ /* If filter glossy is used we replace Sharp glossy with GGX so we can
+ * benefit from closure blur to remove unwanted noise.
+ */
+ if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_SHARP_GLASS_ID) {
+ VLOG(1) << "Using GGX glass with filter glossy.";
+ distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
+ roughness = 0.0f;
+ }
+ }
+ closure = distribution;
}
bool GlassBsdfNode::has_integrator_dependency()
{
- ShaderInput *roughness_input = input("Roughness");
- return !roughness_input->link &&
- (distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f);
+ ShaderInput *roughness_input = input("Roughness");
+ return !roughness_input->link &&
+ (distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f);
}
-void GlassBsdfNode::compile(SVMCompiler& compiler)
+void GlassBsdfNode::compile(SVMCompiler &compiler)
{
- closure = distribution;
+ closure = distribution;
- if(closure == CLOSURE_BSDF_SHARP_GLASS_ID)
- BsdfNode::compile(compiler, NULL, input("IOR"));
- else if(closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
- BsdfNode::compile(compiler, input("Roughness"), input("IOR"), input("Color"));
- else
- BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
+ if (closure == CLOSURE_BSDF_SHARP_GLASS_ID)
+ BsdfNode::compile(compiler, NULL, input("IOR"));
+ else if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
+ BsdfNode::compile(compiler, input("Roughness"), input("IOR"), input("Color"));
+ else
+ BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
}
-void GlassBsdfNode::compile(OSLCompiler& compiler)
+void GlassBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "distribution");
- compiler.add(this, "node_glass_bsdf");
+ compiler.parameter(this, "distribution");
+ compiler.add(this, "node_glass_bsdf");
}
/* Refraction BSDF Closure */
NODE_DEFINE(RefractionBsdfNode)
{
- NodeType* type = NodeType::add("refraction_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("refraction_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- static NodeEnum distribution_enum;
- distribution_enum.insert("sharp", CLOSURE_BSDF_REFRACTION_ID);
- distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
- distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
- SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
+ static NodeEnum distribution_enum;
+ distribution_enum.insert("sharp", CLOSURE_BSDF_REFRACTION_ID);
+ distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
+ distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
+ SOCKET_ENUM(
+ distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
- SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
- SOCKET_IN_FLOAT(IOR, "IOR", 0.3f);
+ SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
+ SOCKET_IN_FLOAT(IOR, "IOR", 0.3f);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-RefractionBsdfNode::RefractionBsdfNode()
-: BsdfNode(node_type)
+RefractionBsdfNode::RefractionBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_REFRACTION_ID;
- distribution_orig = NBUILTIN_CLOSURES;
+ closure = CLOSURE_BSDF_REFRACTION_ID;
+ distribution_orig = NBUILTIN_CLOSURES;
}
void RefractionBsdfNode::simplify_settings(Scene *scene)
{
- if(distribution_orig == NBUILTIN_CLOSURES) {
- roughness_orig = roughness;
- distribution_orig = distribution;
- }
- else {
- /* By default we use original values, so we don't worry about restoring
- * defaults later one and can only do override when needed.
- */
- roughness = roughness_orig;
- distribution = distribution_orig;
- }
- Integrator *integrator = scene->integrator;
- ShaderInput *roughness_input = input("Roughness");
- if(integrator->filter_glossy == 0.0f) {
- /* Fallback to Sharp closure for Roughness close to 0.
- * Note: Keep the epsilon in sync with kernel!
- */
- if(!roughness_input->link && roughness <= 1e-4f) {
- VLOG(1) << "Using sharp refraction BSDF.";
- distribution = CLOSURE_BSDF_REFRACTION_ID;
- }
- }
- else {
- /* If filter glossy is used we replace Sharp glossy with GGX so we can
- * benefit from closure blur to remove unwanted noise.
- */
- if(roughness_input->link == NULL &&
- distribution == CLOSURE_BSDF_REFRACTION_ID)
- {
- VLOG(1) << "Using GGX refraction with filter glossy.";
- distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- roughness = 0.0f;
- }
- }
- closure = distribution;
+ if (distribution_orig == NBUILTIN_CLOSURES) {
+ roughness_orig = roughness;
+ distribution_orig = distribution;
+ }
+ else {
+ /* By default we use original values, so we don't worry about restoring
+ * defaults later one and can only do override when needed.
+ */
+ roughness = roughness_orig;
+ distribution = distribution_orig;
+ }
+ Integrator *integrator = scene->integrator;
+ ShaderInput *roughness_input = input("Roughness");
+ if (integrator->filter_glossy == 0.0f) {
+ /* Fallback to Sharp closure for Roughness close to 0.
+ * Note: Keep the epsilon in sync with kernel!
+ */
+ if (!roughness_input->link && roughness <= 1e-4f) {
+ VLOG(1) << "Using sharp refraction BSDF.";
+ distribution = CLOSURE_BSDF_REFRACTION_ID;
+ }
+ }
+ else {
+ /* If filter glossy is used we replace Sharp glossy with GGX so we can
+ * benefit from closure blur to remove unwanted noise.
+ */
+ if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFRACTION_ID) {
+ VLOG(1) << "Using GGX refraction with filter glossy.";
+ distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ roughness = 0.0f;
+ }
+ }
+ closure = distribution;
}
bool RefractionBsdfNode::has_integrator_dependency()
{
- ShaderInput *roughness_input = input("Roughness");
- return !roughness_input->link &&
- (distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f);
+ ShaderInput *roughness_input = input("Roughness");
+ return !roughness_input->link &&
+ (distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f);
}
-void RefractionBsdfNode::compile(SVMCompiler& compiler)
+void RefractionBsdfNode::compile(SVMCompiler &compiler)
{
- closure = distribution;
+ closure = distribution;
- if(closure == CLOSURE_BSDF_REFRACTION_ID)
- BsdfNode::compile(compiler, NULL, input("IOR"));
- else
- BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
+ if (closure == CLOSURE_BSDF_REFRACTION_ID)
+ BsdfNode::compile(compiler, NULL, input("IOR"));
+ else
+ BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
}
-void RefractionBsdfNode::compile(OSLCompiler& compiler)
+void RefractionBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "distribution");
- compiler.add(this, "node_refraction_bsdf");
+ compiler.parameter(this, "distribution");
+ compiler.add(this, "node_refraction_bsdf");
}
/* Toon BSDF Closure */
NODE_DEFINE(ToonBsdfNode)
{
- NodeType* type = NodeType::add("toon_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("toon_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- static NodeEnum component_enum;
- component_enum.insert("diffuse", CLOSURE_BSDF_DIFFUSE_TOON_ID);
- component_enum.insert("glossy", CLOSURE_BSDF_GLOSSY_TOON_ID);
- SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_DIFFUSE_TOON_ID);
- SOCKET_IN_FLOAT(size, "Size", 0.5f);
- SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
+ static NodeEnum component_enum;
+ component_enum.insert("diffuse", CLOSURE_BSDF_DIFFUSE_TOON_ID);
+ component_enum.insert("glossy", CLOSURE_BSDF_GLOSSY_TOON_ID);
+ SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_DIFFUSE_TOON_ID);
+ SOCKET_IN_FLOAT(size, "Size", 0.5f);
+ SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-ToonBsdfNode::ToonBsdfNode()
-: BsdfNode(node_type)
+ToonBsdfNode::ToonBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_DIFFUSE_TOON_ID;
+ closure = CLOSURE_BSDF_DIFFUSE_TOON_ID;
}
-void ToonBsdfNode::compile(SVMCompiler& compiler)
+void ToonBsdfNode::compile(SVMCompiler &compiler)
{
- closure = component;
+ closure = component;
- BsdfNode::compile(compiler, input("Size"), input("Smooth"));
+ BsdfNode::compile(compiler, input("Size"), input("Smooth"));
}
-void ToonBsdfNode::compile(OSLCompiler& compiler)
+void ToonBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "component");
- compiler.add(this, "node_toon_bsdf");
+ compiler.parameter(this, "component");
+ compiler.add(this, "node_toon_bsdf");
}
/* Velvet BSDF Closure */
NODE_DEFINE(VelvetBsdfNode)
{
- NodeType* type = NodeType::add("velvet_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("velvet_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_IN_FLOAT(sigma, "Sigma", 1.0f);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_FLOAT(sigma, "Sigma", 1.0f);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-VelvetBsdfNode::VelvetBsdfNode()
-: BsdfNode(node_type)
+VelvetBsdfNode::VelvetBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
+ closure = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
}
-void VelvetBsdfNode::compile(SVMCompiler& compiler)
+void VelvetBsdfNode::compile(SVMCompiler &compiler)
{
- BsdfNode::compile(compiler, input("Sigma"), NULL);
+ BsdfNode::compile(compiler, input("Sigma"), NULL);
}
-void VelvetBsdfNode::compile(OSLCompiler& compiler)
+void VelvetBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_velvet_bsdf");
+ compiler.add(this, "node_velvet_bsdf");
}
/* Diffuse BSDF Closure */
NODE_DEFINE(DiffuseBsdfNode)
{
- NodeType* type = NodeType::add("diffuse_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("diffuse_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-DiffuseBsdfNode::DiffuseBsdfNode()
-: BsdfNode(node_type)
+DiffuseBsdfNode::DiffuseBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_DIFFUSE_ID;
+ closure = CLOSURE_BSDF_DIFFUSE_ID;
}
-void DiffuseBsdfNode::compile(SVMCompiler& compiler)
+void DiffuseBsdfNode::compile(SVMCompiler &compiler)
{
- BsdfNode::compile(compiler, input("Roughness"), NULL);
+ BsdfNode::compile(compiler, input("Roughness"), NULL);
}
-void DiffuseBsdfNode::compile(OSLCompiler& compiler)
+void DiffuseBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_diffuse_bsdf");
+ compiler.add(this, "node_diffuse_bsdf");
}
/* Disney principled BSDF Closure */
NODE_DEFINE(PrincipledBsdfNode)
{
- NodeType* type = NodeType::add("principled_bsdf", create, NodeType::SHADER);
-
- static NodeEnum distribution_enum;
- distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
- distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
- SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
-
- static NodeEnum subsurface_method_enum;
- subsurface_method_enum.insert("burley", CLOSURE_BSSRDF_PRINCIPLED_ID);
- subsurface_method_enum.insert("random_walk", CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
- SOCKET_ENUM(subsurface_method, "Subsurface Method", subsurface_method_enum, CLOSURE_BSSRDF_PRINCIPLED_ID);
-
- SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_COLOR(subsurface_color, "Subsurface Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
- SOCKET_IN_FLOAT(subsurface, "Subsurface", 0.0f);
- SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f));
- SOCKET_IN_FLOAT(specular, "Specular", 0.0f);
- SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
- SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f);
- SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f);
- SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f);
- SOCKET_IN_FLOAT(sheen_tint, "Sheen Tint", 0.0f);
- SOCKET_IN_FLOAT(clearcoat, "Clearcoat", 0.0f);
- SOCKET_IN_FLOAT(clearcoat_roughness, "Clearcoat Roughness", 0.03f);
- SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
- SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f);
- SOCKET_IN_FLOAT(transmission_roughness, "Transmission Roughness", 0.0f);
- SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_NORMAL(clearcoat_normal, "Clearcoat Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_NORMAL(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
-
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
-
- return type;
-}
-
-PrincipledBsdfNode::PrincipledBsdfNode()
- : BsdfBaseNode(node_type)
-{
- closure = CLOSURE_BSDF_PRINCIPLED_ID;
- distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
- distribution_orig = NBUILTIN_CLOSURES;
+ NodeType *type = NodeType::add("principled_bsdf", create, NodeType::SHADER);
+
+ static NodeEnum distribution_enum;
+ distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
+ distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
+ SOCKET_ENUM(
+ distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
+
+ static NodeEnum subsurface_method_enum;
+ subsurface_method_enum.insert("burley", CLOSURE_BSSRDF_PRINCIPLED_ID);
+ subsurface_method_enum.insert("random_walk", CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
+ SOCKET_ENUM(subsurface_method,
+ "Subsurface Method",
+ subsurface_method_enum,
+ CLOSURE_BSSRDF_PRINCIPLED_ID);
+
+ SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_COLOR(subsurface_color, "Subsurface Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
+ SOCKET_IN_FLOAT(subsurface, "Subsurface", 0.0f);
+ SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f));
+ SOCKET_IN_FLOAT(specular, "Specular", 0.0f);
+ SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
+ SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f);
+ SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f);
+ SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f);
+ SOCKET_IN_FLOAT(sheen_tint, "Sheen Tint", 0.0f);
+ SOCKET_IN_FLOAT(clearcoat, "Clearcoat", 0.0f);
+ SOCKET_IN_FLOAT(clearcoat_roughness, "Clearcoat Roughness", 0.03f);
+ SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
+ SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f);
+ SOCKET_IN_FLOAT(transmission_roughness, "Transmission Roughness", 0.0f);
+ SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_NORMAL(clearcoat_normal,
+ "Clearcoat Normal",
+ make_float3(0.0f, 0.0f, 0.0f),
+ SocketType::LINK_NORMAL);
+ SOCKET_IN_NORMAL(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+
+ return type;
+}
+
+PrincipledBsdfNode::PrincipledBsdfNode() : BsdfBaseNode(node_type)
+{
+ closure = CLOSURE_BSDF_PRINCIPLED_ID;
+ distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ distribution_orig = NBUILTIN_CLOSURES;
}
bool PrincipledBsdfNode::has_surface_bssrdf()
{
- ShaderInput *subsurface_in = input("Subsurface");
- return (subsurface_in->link != NULL || subsurface > CLOSURE_WEIGHT_CUTOFF);
+ ShaderInput *subsurface_in = input("Subsurface");
+ return (subsurface_in->link != NULL || subsurface > CLOSURE_WEIGHT_CUTOFF);
}
void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- ShaderInput *tangent_in = input("Tangent");
-
- if(!tangent_in->link)
- attributes->add(ATTR_STD_GENERATED);
- }
-
- ShaderNode::attributes(shader, attributes);
-}
-
-void PrincipledBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, ShaderInput *p_subsurface, ShaderInput *p_subsurface_radius,
- ShaderInput *p_specular, ShaderInput *p_roughness, ShaderInput *p_specular_tint, ShaderInput *p_anisotropic,
- ShaderInput *p_sheen, ShaderInput *p_sheen_tint, ShaderInput *p_clearcoat, ShaderInput *p_clearcoat_roughness,
- ShaderInput *p_ior, ShaderInput *p_transmission, ShaderInput *p_anisotropic_rotation, ShaderInput *p_transmission_roughness)
-{
- ShaderInput *base_color_in = input("Base Color");
- ShaderInput *subsurface_color_in = input("Subsurface Color");
- ShaderInput *normal_in = input("Normal");
- ShaderInput *clearcoat_normal_in = input("Clearcoat Normal");
- ShaderInput *tangent_in = input("Tangent");
-
- float3 weight = make_float3(1.0f, 1.0f, 1.0f);
-
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, weight);
-
- int normal_offset = compiler.stack_assign_if_linked(normal_in);
- int clearcoat_normal_offset = compiler.stack_assign_if_linked(clearcoat_normal_in);
- int tangent_offset = compiler.stack_assign_if_linked(tangent_in);
- int specular_offset = compiler.stack_assign(p_specular);
- int roughness_offset = compiler.stack_assign(p_roughness);
- int specular_tint_offset = compiler.stack_assign(p_specular_tint);
- int anisotropic_offset = compiler.stack_assign(p_anisotropic);
- int sheen_offset = compiler.stack_assign(p_sheen);
- int sheen_tint_offset = compiler.stack_assign(p_sheen_tint);
- int clearcoat_offset = compiler.stack_assign(p_clearcoat);
- int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness);
- int ior_offset = compiler.stack_assign(p_ior);
- int transmission_offset = compiler.stack_assign(p_transmission);
- int transmission_roughness_offset = compiler.stack_assign(p_transmission_roughness);
- int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation);
- int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius);
-
- compiler.add_node(NODE_CLOSURE_BSDF,
- compiler.encode_uchar4(closure,
- compiler.stack_assign(p_metallic),
- compiler.stack_assign(p_subsurface),
- compiler.closure_mix_weight_offset()),
- __float_as_int((p_metallic) ? get_float(p_metallic->socket_type) : 0.0f),
- __float_as_int((p_subsurface) ? get_float(p_subsurface->socket_type) : 0.0f));
-
- compiler.add_node(normal_offset, tangent_offset,
- compiler.encode_uchar4(specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
- compiler.encode_uchar4(sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset));
-
- compiler.add_node(compiler.encode_uchar4(ior_offset, transmission_offset, anisotropic_rotation_offset, transmission_roughness_offset),
- distribution, subsurface_method, SVM_STACK_INVALID);
-
- float3 bc_default = get_float3(base_color_in->socket_type);
-
- compiler.add_node(((base_color_in->link) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID),
- __float_as_int(bc_default.x), __float_as_int(bc_default.y), __float_as_int(bc_default.z));
-
- compiler.add_node(clearcoat_normal_offset, subsurface_radius_offset, SVM_STACK_INVALID, SVM_STACK_INVALID);
-
- float3 ss_default = get_float3(subsurface_color_in->socket_type);
-
- compiler.add_node(((subsurface_color_in->link) ? compiler.stack_assign(subsurface_color_in) : SVM_STACK_INVALID),
- __float_as_int(ss_default.x), __float_as_int(ss_default.y), __float_as_int(ss_default.z));
+ if (shader->has_surface) {
+ ShaderInput *tangent_in = input("Tangent");
+
+ if (!tangent_in->link)
+ attributes->add(ATTR_STD_GENERATED);
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void PrincipledBsdfNode::compile(SVMCompiler &compiler,
+ ShaderInput *p_metallic,
+ ShaderInput *p_subsurface,
+ ShaderInput *p_subsurface_radius,
+ ShaderInput *p_specular,
+ ShaderInput *p_roughness,
+ ShaderInput *p_specular_tint,
+ ShaderInput *p_anisotropic,
+ ShaderInput *p_sheen,
+ ShaderInput *p_sheen_tint,
+ ShaderInput *p_clearcoat,
+ ShaderInput *p_clearcoat_roughness,
+ ShaderInput *p_ior,
+ ShaderInput *p_transmission,
+ ShaderInput *p_anisotropic_rotation,
+ ShaderInput *p_transmission_roughness)
+{
+ ShaderInput *base_color_in = input("Base Color");
+ ShaderInput *subsurface_color_in = input("Subsurface Color");
+ ShaderInput *normal_in = input("Normal");
+ ShaderInput *clearcoat_normal_in = input("Clearcoat Normal");
+ ShaderInput *tangent_in = input("Tangent");
+
+ float3 weight = make_float3(1.0f, 1.0f, 1.0f);
+
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, weight);
+
+ int normal_offset = compiler.stack_assign_if_linked(normal_in);
+ int clearcoat_normal_offset = compiler.stack_assign_if_linked(clearcoat_normal_in);
+ int tangent_offset = compiler.stack_assign_if_linked(tangent_in);
+ int specular_offset = compiler.stack_assign(p_specular);
+ int roughness_offset = compiler.stack_assign(p_roughness);
+ int specular_tint_offset = compiler.stack_assign(p_specular_tint);
+ int anisotropic_offset = compiler.stack_assign(p_anisotropic);
+ int sheen_offset = compiler.stack_assign(p_sheen);
+ int sheen_tint_offset = compiler.stack_assign(p_sheen_tint);
+ int clearcoat_offset = compiler.stack_assign(p_clearcoat);
+ int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness);
+ int ior_offset = compiler.stack_assign(p_ior);
+ int transmission_offset = compiler.stack_assign(p_transmission);
+ int transmission_roughness_offset = compiler.stack_assign(p_transmission_roughness);
+ int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation);
+ int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius);
+
+ compiler.add_node(NODE_CLOSURE_BSDF,
+ compiler.encode_uchar4(closure,
+ compiler.stack_assign(p_metallic),
+ compiler.stack_assign(p_subsurface),
+ compiler.closure_mix_weight_offset()),
+ __float_as_int((p_metallic) ? get_float(p_metallic->socket_type) : 0.0f),
+ __float_as_int((p_subsurface) ? get_float(p_subsurface->socket_type) : 0.0f));
+
+ compiler.add_node(
+ normal_offset,
+ tangent_offset,
+ compiler.encode_uchar4(
+ specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
+ compiler.encode_uchar4(
+ sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset));
+
+ compiler.add_node(compiler.encode_uchar4(ior_offset,
+ transmission_offset,
+ anisotropic_rotation_offset,
+ transmission_roughness_offset),
+ distribution,
+ subsurface_method,
+ SVM_STACK_INVALID);
+
+ float3 bc_default = get_float3(base_color_in->socket_type);
+
+ compiler.add_node(
+ ((base_color_in->link) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID),
+ __float_as_int(bc_default.x),
+ __float_as_int(bc_default.y),
+ __float_as_int(bc_default.z));
+
+ compiler.add_node(
+ clearcoat_normal_offset, subsurface_radius_offset, SVM_STACK_INVALID, SVM_STACK_INVALID);
+
+ float3 ss_default = get_float3(subsurface_color_in->socket_type);
+
+ compiler.add_node(((subsurface_color_in->link) ? compiler.stack_assign(subsurface_color_in) :
+ SVM_STACK_INVALID),
+ __float_as_int(ss_default.x),
+ __float_as_int(ss_default.y),
+ __float_as_int(ss_default.z));
}
bool PrincipledBsdfNode::has_integrator_dependency()
{
- ShaderInput *roughness_input = input("Roughness");
- return !roughness_input->link && roughness <= 1e-4f;
+ ShaderInput *roughness_input = input("Roughness");
+ return !roughness_input->link && roughness <= 1e-4f;
}
-void PrincipledBsdfNode::compile(SVMCompiler& compiler)
+void PrincipledBsdfNode::compile(SVMCompiler &compiler)
{
- compile(compiler, input("Metallic"), input("Subsurface"), input("Subsurface Radius"), input("Specular"),
- input("Roughness"), input("Specular Tint"), input("Anisotropic"), input("Sheen"), input("Sheen Tint"),
- input("Clearcoat"), input("Clearcoat Roughness"), input("IOR"), input("Transmission"),
- input("Anisotropic Rotation"), input("Transmission Roughness"));
+ compile(compiler,
+ input("Metallic"),
+ input("Subsurface"),
+ input("Subsurface Radius"),
+ input("Specular"),
+ input("Roughness"),
+ input("Specular Tint"),
+ input("Anisotropic"),
+ input("Sheen"),
+ input("Sheen Tint"),
+ input("Clearcoat"),
+ input("Clearcoat Roughness"),
+ input("IOR"),
+ input("Transmission"),
+ input("Anisotropic Rotation"),
+ input("Transmission Roughness"));
}
-void PrincipledBsdfNode::compile(OSLCompiler& compiler)
+void PrincipledBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "distribution");
- compiler.parameter(this, "subsurface_method");
- compiler.add(this, "node_principled_bsdf");
+ compiler.parameter(this, "distribution");
+ compiler.parameter(this, "subsurface_method");
+ compiler.add(this, "node_principled_bsdf");
}
bool PrincipledBsdfNode::has_bssrdf_bump()
{
- return has_surface_bssrdf() && has_bump();
+ return has_surface_bssrdf() && has_bump();
}
/* Translucent BSDF Closure */
NODE_DEFINE(TranslucentBsdfNode)
{
- NodeType* type = NodeType::add("translucent_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("translucent_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-TranslucentBsdfNode::TranslucentBsdfNode()
-: BsdfNode(node_type)
+TranslucentBsdfNode::TranslucentBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_TRANSLUCENT_ID;
+ closure = CLOSURE_BSDF_TRANSLUCENT_ID;
}
-void TranslucentBsdfNode::compile(SVMCompiler& compiler)
+void TranslucentBsdfNode::compile(SVMCompiler &compiler)
{
- BsdfNode::compile(compiler, NULL, NULL);
+ BsdfNode::compile(compiler, NULL, NULL);
}
-void TranslucentBsdfNode::compile(OSLCompiler& compiler)
+void TranslucentBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_translucent_bsdf");
+ compiler.add(this, "node_translucent_bsdf");
}
/* Transparent BSDF Closure */
NODE_DEFINE(TransparentBsdfNode)
{
- NodeType* type = NodeType::add("transparent_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("transparent_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-TransparentBsdfNode::TransparentBsdfNode()
-: BsdfNode(node_type)
+TransparentBsdfNode::TransparentBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_TRANSPARENT_ID;
+ closure = CLOSURE_BSDF_TRANSPARENT_ID;
}
-void TransparentBsdfNode::compile(SVMCompiler& compiler)
+void TransparentBsdfNode::compile(SVMCompiler &compiler)
{
- BsdfNode::compile(compiler, NULL, NULL);
+ BsdfNode::compile(compiler, NULL, NULL);
}
-void TransparentBsdfNode::compile(OSLCompiler& compiler)
+void TransparentBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_transparent_bsdf");
+ compiler.add(this, "node_transparent_bsdf");
}
/* Subsurface Scattering Closure */
NODE_DEFINE(SubsurfaceScatteringNode)
{
- NodeType* type = NodeType::add("subsurface_scattering", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("subsurface_scattering", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- static NodeEnum falloff_enum;
- falloff_enum.insert("cubic", CLOSURE_BSSRDF_CUBIC_ID);
- falloff_enum.insert("gaussian", CLOSURE_BSSRDF_GAUSSIAN_ID);
- falloff_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID);
- falloff_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID);
- SOCKET_ENUM(falloff, "Falloff", falloff_enum, CLOSURE_BSSRDF_BURLEY_ID);
- SOCKET_IN_FLOAT(scale, "Scale", 0.01f);
- SOCKET_IN_VECTOR(radius, "Radius", make_float3(0.1f, 0.1f, 0.1f));
- SOCKET_IN_FLOAT(sharpness, "Sharpness", 0.0f);
- SOCKET_IN_FLOAT(texture_blur, "Texture Blur", 1.0f);
+ static NodeEnum falloff_enum;
+ falloff_enum.insert("cubic", CLOSURE_BSSRDF_CUBIC_ID);
+ falloff_enum.insert("gaussian", CLOSURE_BSSRDF_GAUSSIAN_ID);
+ falloff_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID);
+ falloff_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID);
+ SOCKET_ENUM(falloff, "Falloff", falloff_enum, CLOSURE_BSSRDF_BURLEY_ID);
+ SOCKET_IN_FLOAT(scale, "Scale", 0.01f);
+ SOCKET_IN_VECTOR(radius, "Radius", make_float3(0.1f, 0.1f, 0.1f));
+ SOCKET_IN_FLOAT(sharpness, "Sharpness", 0.0f);
+ SOCKET_IN_FLOAT(texture_blur, "Texture Blur", 1.0f);
- SOCKET_OUT_CLOSURE(BSSRDF, "BSSRDF");
+ SOCKET_OUT_CLOSURE(BSSRDF, "BSSRDF");
- return type;
+ return type;
}
-SubsurfaceScatteringNode::SubsurfaceScatteringNode()
-: BsdfNode(node_type)
+SubsurfaceScatteringNode::SubsurfaceScatteringNode() : BsdfNode(node_type)
{
- closure = falloff;
+ closure = falloff;
}
-void SubsurfaceScatteringNode::compile(SVMCompiler& compiler)
+void SubsurfaceScatteringNode::compile(SVMCompiler &compiler)
{
- closure = falloff;
- BsdfNode::compile(compiler, input("Scale"), input("Texture Blur"), input("Radius"), input("Sharpness"));
+ closure = falloff;
+ BsdfNode::compile(
+ compiler, input("Scale"), input("Texture Blur"), input("Radius"), input("Sharpness"));
}
-void SubsurfaceScatteringNode::compile(OSLCompiler& compiler)
+void SubsurfaceScatteringNode::compile(OSLCompiler &compiler)
{
- closure = falloff;
- compiler.parameter(this, "falloff");
- compiler.add(this, "node_subsurface_scattering");
+ closure = falloff;
+ compiler.parameter(this, "falloff");
+ compiler.add(this, "node_subsurface_scattering");
}
bool SubsurfaceScatteringNode::has_bssrdf_bump()
{
- /* detect if anything is plugged into the normal input besides the default */
- ShaderInput *normal_in = input("Normal");
- return (normal_in->link && normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY);
+ /* detect if anything is plugged into the normal input besides the default */
+ ShaderInput *normal_in = input("Normal");
+ return (normal_in->link &&
+ normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY);
}
/* Emissive Closure */
NODE_DEFINE(EmissionNode)
{
- NodeType* type = NodeType::add("emission", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("emission", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(strength, "Strength", 10.0f);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_FLOAT(strength, "Strength", 10.0f);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(emission, "Emission");
+ SOCKET_OUT_CLOSURE(emission, "Emission");
- return type;
+ return type;
}
-EmissionNode::EmissionNode()
-: ShaderNode(node_type)
+EmissionNode::EmissionNode() : ShaderNode(node_type)
{
}
-void EmissionNode::compile(SVMCompiler& compiler)
+void EmissionNode::compile(SVMCompiler &compiler)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *strength_in = input("Strength");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *strength_in = input("Strength");
- if(color_in->link || strength_in->link) {
- compiler.add_node(NODE_EMISSION_WEIGHT,
- compiler.stack_assign(color_in),
- compiler.stack_assign(strength_in));
- }
- else
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
+ if (color_in->link || strength_in->link) {
+ compiler.add_node(
+ NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
+ }
+ else
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
- compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
+ compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
}
-void EmissionNode::compile(OSLCompiler& compiler)
+void EmissionNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_emission");
+ compiler.add(this, "node_emission");
}
-void EmissionNode::constant_fold(const ConstantFolder& folder)
+void EmissionNode::constant_fold(const ConstantFolder &folder)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *strength_in = input("Strength");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *strength_in = input("Strength");
- if((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
- (!strength_in->link && strength == 0.0f))
- {
- folder.discard();
- }
+ if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
+ (!strength_in->link && strength == 0.0f)) {
+ folder.discard();
+ }
}
/* Background Closure */
NODE_DEFINE(BackgroundNode)
{
- NodeType* type = NodeType::add("background_shader", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("background_shader", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(background, "Background");
+ SOCKET_OUT_CLOSURE(background, "Background");
- return type;
+ return type;
}
-BackgroundNode::BackgroundNode()
-: ShaderNode(node_type)
+BackgroundNode::BackgroundNode() : ShaderNode(node_type)
{
}
-void BackgroundNode::compile(SVMCompiler& compiler)
+void BackgroundNode::compile(SVMCompiler &compiler)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *strength_in = input("Strength");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *strength_in = input("Strength");
- if(color_in->link || strength_in->link) {
- compiler.add_node(NODE_EMISSION_WEIGHT,
- compiler.stack_assign(color_in),
- compiler.stack_assign(strength_in));
- }
- else
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color*strength);
+ if (color_in->link || strength_in->link) {
+ compiler.add_node(
+ NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
+ }
+ else
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
- compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset());
+ compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset());
}
-void BackgroundNode::compile(OSLCompiler& compiler)
+void BackgroundNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_background");
+ compiler.add(this, "node_background");
}
-void BackgroundNode::constant_fold(const ConstantFolder& folder)
+void BackgroundNode::constant_fold(const ConstantFolder &folder)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *strength_in = input("Strength");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *strength_in = input("Strength");
- if((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
- (!strength_in->link && strength == 0.0f))
- {
- folder.discard();
- }
+ if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
+ (!strength_in->link && strength == 0.0f)) {
+ folder.discard();
+ }
}
/* Holdout Closure */
NODE_DEFINE(HoldoutNode)
{
- NodeType* type = NodeType::add("holdout", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("holdout", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(holdout, "Holdout");
+ SOCKET_OUT_CLOSURE(holdout, "Holdout");
- return type;
+ return type;
}
-HoldoutNode::HoldoutNode()
-: ShaderNode(node_type)
+HoldoutNode::HoldoutNode() : ShaderNode(node_type)
{
}
-void HoldoutNode::compile(SVMCompiler& compiler)
+void HoldoutNode::compile(SVMCompiler &compiler)
{
- float3 value = make_float3(1.0f, 1.0f, 1.0f);
+ float3 value = make_float3(1.0f, 1.0f, 1.0f);
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value);
- compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value);
+ compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
}
-void HoldoutNode::compile(OSLCompiler& compiler)
+void HoldoutNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_holdout");
+ compiler.add(this, "node_holdout");
}
/* Ambient Occlusion */
NODE_DEFINE(AmbientOcclusionNode)
{
- NodeType* type = NodeType::add("ambient_occlusion", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("ambient_occlusion", create, NodeType::SHADER);
- SOCKET_INT(samples, "Samples", 16);
+ SOCKET_INT(samples, "Samples", 16);
- SOCKET_IN_COLOR(color, "Color", make_float3(1.0f, 1.0f, 1.0f));
- SOCKET_IN_FLOAT(distance, "Distance", 1.0f);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(1.0f, 1.0f, 1.0f));
+ SOCKET_IN_FLOAT(distance, "Distance", 1.0f);
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_BOOLEAN(inside, "Inside", false);
- SOCKET_BOOLEAN(only_local, "Only Local", false);
+ SOCKET_BOOLEAN(inside, "Inside", false);
+ SOCKET_BOOLEAN(only_local, "Only Local", false);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(ao, "AO");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(ao, "AO");
- return type;
+ return type;
}
-AmbientOcclusionNode::AmbientOcclusionNode()
-: ShaderNode(node_type)
+AmbientOcclusionNode::AmbientOcclusionNode() : ShaderNode(node_type)
{
}
-void AmbientOcclusionNode::compile(SVMCompiler& compiler)
+void AmbientOcclusionNode::compile(SVMCompiler &compiler)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *distance_in = input("Distance");
- ShaderInput *normal_in = input("Normal");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *ao_out = output("AO");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *distance_in = input("Distance");
+ ShaderInput *normal_in = input("Normal");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *ao_out = output("AO");
- int flags = (inside? NODE_AO_INSIDE : 0) | (only_local? NODE_AO_ONLY_LOCAL : 0);
+ int flags = (inside ? NODE_AO_INSIDE : 0) | (only_local ? NODE_AO_ONLY_LOCAL : 0);
- if(!distance_in->link && distance == 0.0f) {
- flags |= NODE_AO_GLOBAL_RADIUS;
- }
+ if (!distance_in->link && distance == 0.0f) {
+ flags |= NODE_AO_GLOBAL_RADIUS;
+ }
- compiler.add_node(NODE_AMBIENT_OCCLUSION,
- compiler.encode_uchar4(flags,
- compiler.stack_assign_if_linked(distance_in),
- compiler.stack_assign_if_linked(normal_in),
- compiler.stack_assign(ao_out)),
- compiler.encode_uchar4(compiler.stack_assign(color_in),
- compiler.stack_assign(color_out),
- samples),
- __float_as_uint(distance));
+ compiler.add_node(NODE_AMBIENT_OCCLUSION,
+ compiler.encode_uchar4(flags,
+ compiler.stack_assign_if_linked(distance_in),
+ compiler.stack_assign_if_linked(normal_in),
+ compiler.stack_assign(ao_out)),
+ compiler.encode_uchar4(compiler.stack_assign(color_in),
+ compiler.stack_assign(color_out),
+ samples),
+ __float_as_uint(distance));
}
-void AmbientOcclusionNode::compile(OSLCompiler& compiler)
+void AmbientOcclusionNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "samples");
- compiler.parameter(this, "inside");
- compiler.parameter(this, "only_local");
- compiler.add(this, "node_ambient_occlusion");
+ compiler.parameter(this, "samples");
+ compiler.parameter(this, "inside");
+ compiler.parameter(this, "only_local");
+ compiler.add(this, "node_ambient_occlusion");
}
/* Volume Closure */
-VolumeNode::VolumeNode(const NodeType *node_type)
-: ShaderNode(node_type)
+VolumeNode::VolumeNode(const NodeType *node_type) : ShaderNode(node_type)
{
- closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
+ closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
}
-void VolumeNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2)
+void VolumeNode::compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2)
{
- ShaderInput *color_in = input("Color");
+ ShaderInput *color_in = input("Color");
- if(color_in->link)
- compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
- else
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
+ if (color_in->link)
+ compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
+ else
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
- compiler.add_node(NODE_CLOSURE_VOLUME,
- compiler.encode_uchar4(closure,
- (param1)? compiler.stack_assign(param1): SVM_STACK_INVALID,
- (param2)? compiler.stack_assign(param2): SVM_STACK_INVALID,
- compiler.closure_mix_weight_offset()),
- __float_as_int((param1)? get_float(param1->socket_type): 0.0f),
- __float_as_int((param2)? get_float(param2->socket_type): 0.0f));
+ compiler.add_node(
+ NODE_CLOSURE_VOLUME,
+ compiler.encode_uchar4(closure,
+ (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID,
+ (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID,
+ compiler.closure_mix_weight_offset()),
+ __float_as_int((param1) ? get_float(param1->socket_type) : 0.0f),
+ __float_as_int((param2) ? get_float(param2->socket_type) : 0.0f));
}
-void VolumeNode::compile(SVMCompiler& compiler)
+void VolumeNode::compile(SVMCompiler &compiler)
{
- compile(compiler, NULL, NULL);
+ compile(compiler, NULL, NULL);
}
-void VolumeNode::compile(OSLCompiler& /*compiler*/)
+void VolumeNode::compile(OSLCompiler & /*compiler*/)
{
- assert(0);
+ assert(0);
}
/* Absorption Volume Closure */
NODE_DEFINE(AbsorptionVolumeNode)
{
- NodeType* type = NodeType::add("absorption_volume", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("absorption_volume", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(density, "Density", 1.0f);
- SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_FLOAT(density, "Density", 1.0f);
+ SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(volume, "Volume");
+ SOCKET_OUT_CLOSURE(volume, "Volume");
- return type;
+ return type;
}
-AbsorptionVolumeNode::AbsorptionVolumeNode()
-: VolumeNode(node_type)
+AbsorptionVolumeNode::AbsorptionVolumeNode() : VolumeNode(node_type)
{
- closure = CLOSURE_VOLUME_ABSORPTION_ID;
+ closure = CLOSURE_VOLUME_ABSORPTION_ID;
}
-void AbsorptionVolumeNode::compile(SVMCompiler& compiler)
+void AbsorptionVolumeNode::compile(SVMCompiler &compiler)
{
- VolumeNode::compile(compiler, input("Density"), NULL);
+ VolumeNode::compile(compiler, input("Density"), NULL);
}
-void AbsorptionVolumeNode::compile(OSLCompiler& compiler)
+void AbsorptionVolumeNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_absorption_volume");
+ compiler.add(this, "node_absorption_volume");
}
/* Scatter Volume Closure */
NODE_DEFINE(ScatterVolumeNode)
{
- NodeType* type = NodeType::add("scatter_volume", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("scatter_volume", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(density, "Density", 1.0f);
- SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
- SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_FLOAT(density, "Density", 1.0f);
+ SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
+ SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(volume, "Volume");
+ SOCKET_OUT_CLOSURE(volume, "Volume");
- return type;
+ return type;
}
-ScatterVolumeNode::ScatterVolumeNode()
-: VolumeNode(node_type)
+ScatterVolumeNode::ScatterVolumeNode() : VolumeNode(node_type)
{
- closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
+ closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
}
-void ScatterVolumeNode::compile(SVMCompiler& compiler)
+void ScatterVolumeNode::compile(SVMCompiler &compiler)
{
- VolumeNode::compile(compiler, input("Density"), input("Anisotropy"));
+ VolumeNode::compile(compiler, input("Density"), input("Anisotropy"));
}
-void ScatterVolumeNode::compile(OSLCompiler& compiler)
+void ScatterVolumeNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_scatter_volume");
+ compiler.add(this, "node_scatter_volume");
}
/* Principled Volume Closure */
NODE_DEFINE(PrincipledVolumeNode)
{
- NodeType* type = NodeType::add("principled_volume", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("principled_volume", create, NodeType::SHADER);
- SOCKET_IN_STRING(density_attribute, "Density Attribute", ustring());
- SOCKET_IN_STRING(color_attribute, "Color Attribute", ustring());
- SOCKET_IN_STRING(temperature_attribute, "Temperature Attribute", ustring());
+ SOCKET_IN_STRING(density_attribute, "Density Attribute", ustring());
+ SOCKET_IN_STRING(color_attribute, "Color Attribute", ustring());
+ SOCKET_IN_STRING(temperature_attribute, "Temperature Attribute", ustring());
- SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 0.5f));
- SOCKET_IN_FLOAT(density, "Density", 1.0f);
- SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
- SOCKET_IN_COLOR(absorption_color, "Absorption Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 0.0f);
- SOCKET_IN_COLOR(emission_color, "Emission Color", make_float3(1.0f, 1.0f, 1.0f));
- SOCKET_IN_FLOAT(blackbody_intensity, "Blackbody Intensity", 0.0f);
- SOCKET_IN_COLOR(blackbody_tint, "Blackbody Tint", make_float3(1.0f, 1.0f, 1.0f));
- SOCKET_IN_FLOAT(temperature, "Temperature", 1500.0f);
- SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 0.5f));
+ SOCKET_IN_FLOAT(density, "Density", 1.0f);
+ SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
+ SOCKET_IN_COLOR(absorption_color, "Absorption Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 0.0f);
+ SOCKET_IN_COLOR(emission_color, "Emission Color", make_float3(1.0f, 1.0f, 1.0f));
+ SOCKET_IN_FLOAT(blackbody_intensity, "Blackbody Intensity", 0.0f);
+ SOCKET_IN_COLOR(blackbody_tint, "Blackbody Tint", make_float3(1.0f, 1.0f, 1.0f));
+ SOCKET_IN_FLOAT(temperature, "Temperature", 1500.0f);
+ SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(volume, "Volume");
+ SOCKET_OUT_CLOSURE(volume, "Volume");
- return type;
+ return type;
}
-PrincipledVolumeNode::PrincipledVolumeNode()
-: VolumeNode(node_type)
+PrincipledVolumeNode::PrincipledVolumeNode() : VolumeNode(node_type)
{
- closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
+ closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
}
void PrincipledVolumeNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_volume) {
- ShaderInput *density_in = input("Density");
- ShaderInput *blackbody_in = input("Blackbody Intensity");
-
- if(density_in->link || density > 0.0f) {
- attributes->add_standard(density_attribute);
- attributes->add_standard(color_attribute);
- }
-
- if(blackbody_in->link || blackbody_intensity > 0.0f) {
- attributes->add_standard(temperature_attribute);
- }
-
- attributes->add(ATTR_STD_GENERATED_TRANSFORM);
- }
-
- ShaderNode::attributes(shader, attributes);
-}
-
-void PrincipledVolumeNode::compile(SVMCompiler& compiler)
-{
- ShaderInput *color_in = input("Color");
- ShaderInput *density_in = input("Density");
- ShaderInput *anisotropy_in = input("Anisotropy");
- ShaderInput *absorption_color_in = input("Absorption Color");
- ShaderInput *emission_in = input("Emission Strength");
- ShaderInput *emission_color_in = input("Emission Color");
- ShaderInput *blackbody_in = input("Blackbody Intensity");
- ShaderInput *blackbody_tint_in = input("Blackbody Tint");
- ShaderInput *temperature_in = input("Temperature");
-
- if(color_in->link)
- compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
- else
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
-
- compiler.add_node(NODE_PRINCIPLED_VOLUME,
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(density_in),
- compiler.stack_assign_if_linked(anisotropy_in),
- compiler.stack_assign(absorption_color_in),
- compiler.closure_mix_weight_offset()),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(emission_in),
- compiler.stack_assign(emission_color_in),
- compiler.stack_assign_if_linked(blackbody_in),
- compiler.stack_assign(temperature_in)),
- compiler.stack_assign(blackbody_tint_in));
-
- int attr_density = compiler.attribute_standard(density_attribute);
- int attr_color = compiler.attribute_standard(color_attribute);
- int attr_temperature = compiler.attribute_standard(temperature_attribute);
-
- compiler.add_node(
- __float_as_int(density),
- __float_as_int(anisotropy),
- __float_as_int(emission_strength),
- __float_as_int(blackbody_intensity));
-
- compiler.add_node(
- attr_density,
- attr_color,
- attr_temperature);
-}
-
-void PrincipledVolumeNode::compile(OSLCompiler& compiler)
-{
- if(Attribute::name_standard(density_attribute.c_str())) {
- density_attribute = ustring("geom:" + density_attribute.string());
- }
- if(Attribute::name_standard(color_attribute.c_str())) {
- color_attribute = ustring("geom:" + color_attribute.string());
- }
- if(Attribute::name_standard(temperature_attribute.c_str())) {
- temperature_attribute = ustring("geom:" + temperature_attribute.string());
- }
-
- compiler.add(this, "node_principled_volume");
+ if (shader->has_volume) {
+ ShaderInput *density_in = input("Density");
+ ShaderInput *blackbody_in = input("Blackbody Intensity");
+
+ if (density_in->link || density > 0.0f) {
+ attributes->add_standard(density_attribute);
+ attributes->add_standard(color_attribute);
+ }
+
+ if (blackbody_in->link || blackbody_intensity > 0.0f) {
+ attributes->add_standard(temperature_attribute);
+ }
+
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void PrincipledVolumeNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *color_in = input("Color");
+ ShaderInput *density_in = input("Density");
+ ShaderInput *anisotropy_in = input("Anisotropy");
+ ShaderInput *absorption_color_in = input("Absorption Color");
+ ShaderInput *emission_in = input("Emission Strength");
+ ShaderInput *emission_color_in = input("Emission Color");
+ ShaderInput *blackbody_in = input("Blackbody Intensity");
+ ShaderInput *blackbody_tint_in = input("Blackbody Tint");
+ ShaderInput *temperature_in = input("Temperature");
+
+ if (color_in->link)
+ compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
+ else
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
+
+ compiler.add_node(NODE_PRINCIPLED_VOLUME,
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(density_in),
+ compiler.stack_assign_if_linked(anisotropy_in),
+ compiler.stack_assign(absorption_color_in),
+ compiler.closure_mix_weight_offset()),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(emission_in),
+ compiler.stack_assign(emission_color_in),
+ compiler.stack_assign_if_linked(blackbody_in),
+ compiler.stack_assign(temperature_in)),
+ compiler.stack_assign(blackbody_tint_in));
+
+ int attr_density = compiler.attribute_standard(density_attribute);
+ int attr_color = compiler.attribute_standard(color_attribute);
+ int attr_temperature = compiler.attribute_standard(temperature_attribute);
+
+ compiler.add_node(__float_as_int(density),
+ __float_as_int(anisotropy),
+ __float_as_int(emission_strength),
+ __float_as_int(blackbody_intensity));
+
+ compiler.add_node(attr_density, attr_color, attr_temperature);
+}
+
+void PrincipledVolumeNode::compile(OSLCompiler &compiler)
+{
+ if (Attribute::name_standard(density_attribute.c_str())) {
+ density_attribute = ustring("geom:" + density_attribute.string());
+ }
+ if (Attribute::name_standard(color_attribute.c_str())) {
+ color_attribute = ustring("geom:" + color_attribute.string());
+ }
+ if (Attribute::name_standard(temperature_attribute.c_str())) {
+ temperature_attribute = ustring("geom:" + temperature_attribute.string());
+ }
+
+ compiler.add(this, "node_principled_volume");
}
/* Principled Hair BSDF Closure */
NODE_DEFINE(PrincipledHairBsdfNode)
{
- NodeType* type = NodeType::add("principled_hair_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("principled_hair_bsdf", create, NodeType::SHADER);
- /* Color parametrization specified as enum. */
- static NodeEnum parametrization_enum;
- parametrization_enum.insert("Direct coloring", NODE_PRINCIPLED_HAIR_REFLECTANCE);
- parametrization_enum.insert("Melanin concentration", NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
- parametrization_enum.insert("Absorption coefficient", NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION);
- SOCKET_ENUM(parametrization, "Parametrization", parametrization_enum, NODE_PRINCIPLED_HAIR_REFLECTANCE);
+ /* Color parametrization specified as enum. */
+ static NodeEnum parametrization_enum;
+ parametrization_enum.insert("Direct coloring", NODE_PRINCIPLED_HAIR_REFLECTANCE);
+ parametrization_enum.insert("Melanin concentration", NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
+ parametrization_enum.insert("Absorption coefficient", NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION);
+ SOCKET_ENUM(
+ parametrization, "Parametrization", parametrization_enum, NODE_PRINCIPLED_HAIR_REFLECTANCE);
- /* Initialize sockets to their default values. */
- SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f));
- SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f);
- SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f);
- SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f));
- SOCKET_IN_VECTOR(absorption_coefficient, "Absorption Coefficient", make_float3(0.245531f, 0.52f, 1.365f), SocketType::VECTOR);
+ /* Initialize sockets to their default values. */
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f));
+ SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f);
+ SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f);
+ SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f));
+ SOCKET_IN_VECTOR(absorption_coefficient,
+ "Absorption Coefficient",
+ make_float3(0.245531f, 0.52f, 1.365f),
+ SocketType::VECTOR);
- SOCKET_IN_FLOAT(offset, "Offset", 2.f*M_PI_F/180.f);
- SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f);
- SOCKET_IN_FLOAT(radial_roughness, "Radial Roughness", 0.3f);
- SOCKET_IN_FLOAT(coat, "Coat", 0.0f);
- SOCKET_IN_FLOAT(ior, "IOR", 1.55f);
+ SOCKET_IN_FLOAT(offset, "Offset", 2.f * M_PI_F / 180.f);
+ SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f);
+ SOCKET_IN_FLOAT(radial_roughness, "Radial Roughness", 0.3f);
+ SOCKET_IN_FLOAT(coat, "Coat", 0.0f);
+ SOCKET_IN_FLOAT(ior, "IOR", 1.55f);
- SOCKET_IN_FLOAT(random_roughness, "Random Roughness", 0.0f);
- SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f);
- SOCKET_IN_FLOAT(random, "Random", 0.0f);
+ SOCKET_IN_FLOAT(random_roughness, "Random Roughness", 0.0f);
+ SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f);
+ SOCKET_IN_FLOAT(random, "Random", 0.0f);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-PrincipledHairBsdfNode::PrincipledHairBsdfNode()
-: BsdfBaseNode(node_type)
+PrincipledHairBsdfNode::PrincipledHairBsdfNode() : BsdfBaseNode(node_type)
{
- closure = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
+ closure = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
}
/* Enable retrieving Hair Info -> Random if Random isn't linked. */
void PrincipledHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(!input("Random")->link) {
- attributes->add(ATTR_STD_CURVE_RANDOM);
- }
- ShaderNode::attributes(shader, attributes);
+ if (!input("Random")->link) {
+ attributes->add(ATTR_STD_CURVE_RANDOM);
+ }
+ ShaderNode::attributes(shader, attributes);
}
/* Prepares the input data for the SVM shader. */
-void PrincipledHairBsdfNode::compile(SVMCompiler& compiler)
-{
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, make_float3(1.0f, 1.0f, 1.0f));
-
- ShaderInput *roughness_in = input("Roughness");
- ShaderInput *radial_roughness_in = input("Radial Roughness");
- ShaderInput *random_roughness_in = input("Random Roughness");
- ShaderInput *offset_in = input("Offset");
- ShaderInput *coat_in = input("Coat");
- ShaderInput *ior_in = input("IOR");
- ShaderInput *melanin_in = input("Melanin");
- ShaderInput *melanin_redness_in = input("Melanin Redness");
- ShaderInput *random_color_in = input("Random Color");
-
- int color_ofs = compiler.stack_assign(input("Color"));
- int tint_ofs = compiler.stack_assign(input("Tint"));
- int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient"));
-
- ShaderInput *random_in = input("Random");
- int attr_random = random_in->link ? SVM_STACK_INVALID : compiler.attribute(ATTR_STD_CURVE_RANDOM);
-
- /* Encode all parameters into data nodes. */
- compiler.add_node(NODE_CLOSURE_BSDF,
- /* Socket IDs can be packed 4 at a time into a single data packet */
- compiler.encode_uchar4(closure,
- compiler.stack_assign_if_linked(roughness_in),
- compiler.stack_assign_if_linked(radial_roughness_in),
- compiler.closure_mix_weight_offset()),
- /* The rest are stored as unsigned integers */
- __float_as_uint(roughness),
- __float_as_uint(radial_roughness));
-
- compiler.add_node(compiler.stack_assign_if_linked(input("Normal")),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(offset_in),
- compiler.stack_assign_if_linked(ior_in),
- color_ofs,
- parametrization),
- __float_as_uint(offset),
- __float_as_uint(ior));
-
- compiler.add_node(
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(coat_in),
- compiler.stack_assign_if_linked(melanin_in),
- compiler.stack_assign_if_linked(melanin_redness_in),
- absorption_coefficient_ofs),
- __float_as_uint(coat),
- __float_as_uint(melanin),
- __float_as_uint(melanin_redness));
-
- compiler.add_node(
- compiler.encode_uchar4(
- tint_ofs,
- compiler.stack_assign_if_linked(random_in),
- compiler.stack_assign_if_linked(random_color_in),
- compiler.stack_assign_if_linked(random_roughness_in)),
- __float_as_uint(random),
- __float_as_uint(random_color),
- __float_as_uint(random_roughness));
-
- compiler.add_node(
- compiler.encode_uchar4(
- SVM_STACK_INVALID,
- SVM_STACK_INVALID,
- SVM_STACK_INVALID,
- SVM_STACK_INVALID),
- attr_random,
- SVM_STACK_INVALID,
- SVM_STACK_INVALID);
+void PrincipledHairBsdfNode::compile(SVMCompiler &compiler)
+{
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, make_float3(1.0f, 1.0f, 1.0f));
+
+ ShaderInput *roughness_in = input("Roughness");
+ ShaderInput *radial_roughness_in = input("Radial Roughness");
+ ShaderInput *random_roughness_in = input("Random Roughness");
+ ShaderInput *offset_in = input("Offset");
+ ShaderInput *coat_in = input("Coat");
+ ShaderInput *ior_in = input("IOR");
+ ShaderInput *melanin_in = input("Melanin");
+ ShaderInput *melanin_redness_in = input("Melanin Redness");
+ ShaderInput *random_color_in = input("Random Color");
+
+ int color_ofs = compiler.stack_assign(input("Color"));
+ int tint_ofs = compiler.stack_assign(input("Tint"));
+ int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient"));
+
+ ShaderInput *random_in = input("Random");
+ int attr_random = random_in->link ? SVM_STACK_INVALID :
+ compiler.attribute(ATTR_STD_CURVE_RANDOM);
+
+ /* Encode all parameters into data nodes. */
+ compiler.add_node(NODE_CLOSURE_BSDF,
+ /* Socket IDs can be packed 4 at a time into a single data packet */
+ compiler.encode_uchar4(closure,
+ compiler.stack_assign_if_linked(roughness_in),
+ compiler.stack_assign_if_linked(radial_roughness_in),
+ compiler.closure_mix_weight_offset()),
+ /* The rest are stored as unsigned integers */
+ __float_as_uint(roughness),
+ __float_as_uint(radial_roughness));
+
+ compiler.add_node(compiler.stack_assign_if_linked(input("Normal")),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(offset_in),
+ compiler.stack_assign_if_linked(ior_in),
+ color_ofs,
+ parametrization),
+ __float_as_uint(offset),
+ __float_as_uint(ior));
+
+ compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(coat_in),
+ compiler.stack_assign_if_linked(melanin_in),
+ compiler.stack_assign_if_linked(melanin_redness_in),
+ absorption_coefficient_ofs),
+ __float_as_uint(coat),
+ __float_as_uint(melanin),
+ __float_as_uint(melanin_redness));
+
+ compiler.add_node(compiler.encode_uchar4(tint_ofs,
+ compiler.stack_assign_if_linked(random_in),
+ compiler.stack_assign_if_linked(random_color_in),
+ compiler.stack_assign_if_linked(random_roughness_in)),
+ __float_as_uint(random),
+ __float_as_uint(random_color),
+ __float_as_uint(random_roughness));
+
+ compiler.add_node(
+ compiler.encode_uchar4(
+ SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID),
+ attr_random,
+ SVM_STACK_INVALID,
+ SVM_STACK_INVALID);
}
/* Prepares the input data for the OSL shader. */
-void PrincipledHairBsdfNode::compile(OSLCompiler& compiler)
+void PrincipledHairBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "parametrization");
- compiler.add(this, "node_principled_hair_bsdf");
+ compiler.parameter(this, "parametrization");
+ compiler.add(this, "node_principled_hair_bsdf");
}
/* Hair BSDF Closure */
NODE_DEFINE(HairBsdfNode)
{
- NodeType* type = NodeType::add("hair_bsdf", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("hair_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
- static NodeEnum component_enum;
- component_enum.insert("reflection", CLOSURE_BSDF_HAIR_REFLECTION_ID);
- component_enum.insert("transmission", CLOSURE_BSDF_HAIR_TRANSMISSION_ID);
- SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_HAIR_REFLECTION_ID);
- SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
- SOCKET_IN_FLOAT(roughness_u, "RoughnessU", 0.2f);
- SOCKET_IN_FLOAT(roughness_v, "RoughnessV", 0.2f);
- SOCKET_IN_VECTOR(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f));
+ static NodeEnum component_enum;
+ component_enum.insert("reflection", CLOSURE_BSDF_HAIR_REFLECTION_ID);
+ component_enum.insert("transmission", CLOSURE_BSDF_HAIR_TRANSMISSION_ID);
+ SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_HAIR_REFLECTION_ID);
+ SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
+ SOCKET_IN_FLOAT(roughness_u, "RoughnessU", 0.2f);
+ SOCKET_IN_FLOAT(roughness_v, "RoughnessV", 0.2f);
+ SOCKET_IN_VECTOR(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_CLOSURE(BSDF, "BSDF");
+ SOCKET_OUT_CLOSURE(BSDF, "BSDF");
- return type;
+ return type;
}
-HairBsdfNode::HairBsdfNode()
-: BsdfNode(node_type)
+HairBsdfNode::HairBsdfNode() : BsdfNode(node_type)
{
- closure = CLOSURE_BSDF_HAIR_REFLECTION_ID;
+ closure = CLOSURE_BSDF_HAIR_REFLECTION_ID;
}
-void HairBsdfNode::compile(SVMCompiler& compiler)
+void HairBsdfNode::compile(SVMCompiler &compiler)
{
- closure = component;
+ closure = component;
- BsdfNode::compile(compiler, input("RoughnessU"), input("RoughnessV"), input("Offset"));
+ BsdfNode::compile(compiler, input("RoughnessU"), input("RoughnessV"), input("Offset"));
}
-void HairBsdfNode::compile(OSLCompiler& compiler)
+void HairBsdfNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "component");
- compiler.add(this, "node_hair_bsdf");
+ compiler.parameter(this, "component");
+ compiler.add(this, "node_hair_bsdf");
}
/* Geometry */
NODE_DEFINE(GeometryNode)
{
- NodeType* type = NodeType::add("geometry", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("geometry", create, NodeType::SHADER);
- SOCKET_IN_NORMAL(normal_osl, "NormalIn", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
+ SOCKET_IN_NORMAL(normal_osl,
+ "NormalIn",
+ make_float3(0.0f, 0.0f, 0.0f),
+ SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
- SOCKET_OUT_POINT(position, "Position");
- SOCKET_OUT_NORMAL(normal, "Normal");
- SOCKET_OUT_NORMAL(tangent, "Tangent");
- SOCKET_OUT_NORMAL(true_normal, "True Normal");
- SOCKET_OUT_VECTOR(incoming, "Incoming");
- SOCKET_OUT_POINT(parametric, "Parametric");
- SOCKET_OUT_FLOAT(backfacing, "Backfacing");
- SOCKET_OUT_FLOAT(pointiness, "Pointiness");
+ SOCKET_OUT_POINT(position, "Position");
+ SOCKET_OUT_NORMAL(normal, "Normal");
+ SOCKET_OUT_NORMAL(tangent, "Tangent");
+ SOCKET_OUT_NORMAL(true_normal, "True Normal");
+ SOCKET_OUT_VECTOR(incoming, "Incoming");
+ SOCKET_OUT_POINT(parametric, "Parametric");
+ SOCKET_OUT_FLOAT(backfacing, "Backfacing");
+ SOCKET_OUT_FLOAT(pointiness, "Pointiness");
- return type;
+ return type;
}
-GeometryNode::GeometryNode()
-: ShaderNode(node_type)
+GeometryNode::GeometryNode() : ShaderNode(node_type)
{
- special_type = SHADER_SPECIAL_TYPE_GEOMETRY;
+ special_type = SHADER_SPECIAL_TYPE_GEOMETRY;
}
void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- if(!output("Tangent")->links.empty()) {
- attributes->add(ATTR_STD_GENERATED);
- }
- if(!output("Pointiness")->links.empty()) {
- attributes->add(ATTR_STD_POINTINESS);
- }
- }
-
- ShaderNode::attributes(shader, attributes);
-}
-
-void GeometryNode::compile(SVMCompiler& compiler)
-{
- ShaderOutput *out;
- ShaderNodeType geom_node = NODE_GEOMETRY;
- ShaderNodeType attr_node = NODE_ATTR;
-
- if(bump == SHADER_BUMP_DX) {
- geom_node = NODE_GEOMETRY_BUMP_DX;
- attr_node = NODE_ATTR_BUMP_DX;
- }
- else if(bump == SHADER_BUMP_DY) {
- geom_node = NODE_GEOMETRY_BUMP_DY;
- attr_node = NODE_ATTR_BUMP_DY;
- }
-
- out = output("Position");
- if(!out->links.empty()) {
- compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
- }
-
- out = output("Normal");
- if(!out->links.empty()) {
- compiler.add_node(geom_node, NODE_GEOM_N, compiler.stack_assign(out));
- }
-
- out = output("Tangent");
- if(!out->links.empty()) {
- compiler.add_node(geom_node, NODE_GEOM_T, compiler.stack_assign(out));
- }
-
- out = output("True Normal");
- if(!out->links.empty()) {
- compiler.add_node(geom_node, NODE_GEOM_Ng, compiler.stack_assign(out));
- }
-
- out = output("Incoming");
- if(!out->links.empty()) {
- compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
- }
-
- out = output("Parametric");
- if(!out->links.empty()) {
- compiler.add_node(geom_node, NODE_GEOM_uv, compiler.stack_assign(out));
- }
-
- out = output("Backfacing");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, compiler.stack_assign(out));
- }
-
- out = output("Pointiness");
- if(!out->links.empty()) {
- if(compiler.output_type() != SHADER_TYPE_VOLUME) {
- compiler.add_node(attr_node,
- ATTR_STD_POINTINESS,
- compiler.stack_assign(out),
- NODE_ATTR_FLOAT);
- }
- else {
- compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
- }
- }
-}
-
-void GeometryNode::compile(OSLCompiler& compiler)
-{
- if(bump == SHADER_BUMP_DX)
- compiler.parameter("bump_offset", "dx");
- else if(bump == SHADER_BUMP_DY)
- compiler.parameter("bump_offset", "dy");
- else
- compiler.parameter("bump_offset", "center");
-
- compiler.add(this, "node_geometry");
+ if (shader->has_surface) {
+ if (!output("Tangent")->links.empty()) {
+ attributes->add(ATTR_STD_GENERATED);
+ }
+ if (!output("Pointiness")->links.empty()) {
+ attributes->add(ATTR_STD_POINTINESS);
+ }
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void GeometryNode::compile(SVMCompiler &compiler)
+{
+ ShaderOutput *out;
+ ShaderNodeType geom_node = NODE_GEOMETRY;
+ ShaderNodeType attr_node = NODE_ATTR;
+
+ if (bump == SHADER_BUMP_DX) {
+ geom_node = NODE_GEOMETRY_BUMP_DX;
+ attr_node = NODE_ATTR_BUMP_DX;
+ }
+ else if (bump == SHADER_BUMP_DY) {
+ geom_node = NODE_GEOMETRY_BUMP_DY;
+ attr_node = NODE_ATTR_BUMP_DY;
+ }
+
+ out = output("Position");
+ if (!out->links.empty()) {
+ compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
+ }
+
+ out = output("Normal");
+ if (!out->links.empty()) {
+ compiler.add_node(geom_node, NODE_GEOM_N, compiler.stack_assign(out));
+ }
+
+ out = output("Tangent");
+ if (!out->links.empty()) {
+ compiler.add_node(geom_node, NODE_GEOM_T, compiler.stack_assign(out));
+ }
+
+ out = output("True Normal");
+ if (!out->links.empty()) {
+ compiler.add_node(geom_node, NODE_GEOM_Ng, compiler.stack_assign(out));
+ }
+
+ out = output("Incoming");
+ if (!out->links.empty()) {
+ compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
+ }
+
+ out = output("Parametric");
+ if (!out->links.empty()) {
+ compiler.add_node(geom_node, NODE_GEOM_uv, compiler.stack_assign(out));
+ }
+
+ out = output("Backfacing");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, compiler.stack_assign(out));
+ }
+
+ out = output("Pointiness");
+ if (!out->links.empty()) {
+ if (compiler.output_type() != SHADER_TYPE_VOLUME) {
+ compiler.add_node(
+ attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_FLOAT);
+ }
+ else {
+ compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
+ }
+ }
+}
+
+void GeometryNode::compile(OSLCompiler &compiler)
+{
+ if (bump == SHADER_BUMP_DX)
+ compiler.parameter("bump_offset", "dx");
+ else if (bump == SHADER_BUMP_DY)
+ compiler.parameter("bump_offset", "dy");
+ else
+ compiler.parameter("bump_offset", "center");
+
+ compiler.add(this, "node_geometry");
}
int GeometryNode::get_group()
{
- ShaderOutput *out;
- int result = ShaderNode::get_group();
+ ShaderOutput *out;
+ int result = ShaderNode::get_group();
- /* Backfacing uses NODE_LIGHT_PATH */
- out = output("Backfacing");
- if (!out->links.empty()) {
- result = max(result, NODE_GROUP_LEVEL_1);
- }
+ /* Backfacing uses NODE_LIGHT_PATH */
+ out = output("Backfacing");
+ if (!out->links.empty()) {
+ result = max(result, NODE_GROUP_LEVEL_1);
+ }
- return result;
+ return result;
}
/* TextureCoordinate */
NODE_DEFINE(TextureCoordinateNode)
{
- NodeType* type = NodeType::add("texture_coordinate", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("texture_coordinate", create, NodeType::SHADER);
- SOCKET_BOOLEAN(from_dupli, "From Dupli", false);
- SOCKET_BOOLEAN(use_transform, "Use Transform", false);
- SOCKET_TRANSFORM(ob_tfm, "Object Transform", transform_identity());
+ SOCKET_BOOLEAN(from_dupli, "From Dupli", false);
+ SOCKET_BOOLEAN(use_transform, "Use Transform", false);
+ SOCKET_TRANSFORM(ob_tfm, "Object Transform", transform_identity());
- SOCKET_IN_NORMAL(normal_osl, "NormalIn", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
+ SOCKET_IN_NORMAL(normal_osl,
+ "NormalIn",
+ make_float3(0.0f, 0.0f, 0.0f),
+ SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
- SOCKET_OUT_POINT(generated, "Generated");
- SOCKET_OUT_NORMAL(normal, "Normal");
- SOCKET_OUT_POINT(UV, "UV");
- SOCKET_OUT_POINT(object, "Object");
- SOCKET_OUT_POINT(camera, "Camera");
- SOCKET_OUT_POINT(window, "Window");
- SOCKET_OUT_NORMAL(reflection, "Reflection");
+ SOCKET_OUT_POINT(generated, "Generated");
+ SOCKET_OUT_NORMAL(normal, "Normal");
+ SOCKET_OUT_POINT(UV, "UV");
+ SOCKET_OUT_POINT(object, "Object");
+ SOCKET_OUT_POINT(camera, "Camera");
+ SOCKET_OUT_POINT(window, "Window");
+ SOCKET_OUT_NORMAL(reflection, "Reflection");
- return type;
+ return type;
}
-TextureCoordinateNode::TextureCoordinateNode()
-: ShaderNode(node_type)
+TextureCoordinateNode::TextureCoordinateNode() : ShaderNode(node_type)
{
}
void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- if(!from_dupli) {
- if(!output("Generated")->links.empty())
- attributes->add(ATTR_STD_GENERATED);
- if(!output("UV")->links.empty())
- attributes->add(ATTR_STD_UV);
- }
- }
-
- if(shader->has_volume) {
- if(!from_dupli) {
- if(!output("Generated")->links.empty()) {
- attributes->add(ATTR_STD_GENERATED_TRANSFORM);
- }
- }
- }
-
- ShaderNode::attributes(shader, attributes);
-}
-
-void TextureCoordinateNode::compile(SVMCompiler& compiler)
-{
- ShaderOutput *out;
- ShaderNodeType texco_node = NODE_TEX_COORD;
- ShaderNodeType attr_node = NODE_ATTR;
- ShaderNodeType geom_node = NODE_GEOMETRY;
-
- if(bump == SHADER_BUMP_DX) {
- texco_node = NODE_TEX_COORD_BUMP_DX;
- attr_node = NODE_ATTR_BUMP_DX;
- geom_node = NODE_GEOMETRY_BUMP_DX;
- }
- else if(bump == SHADER_BUMP_DY) {
- texco_node = NODE_TEX_COORD_BUMP_DY;
- attr_node = NODE_ATTR_BUMP_DY;
- geom_node = NODE_GEOMETRY_BUMP_DY;
- }
-
- out = output("Generated");
- if(!out->links.empty()) {
- if(compiler.background) {
- compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
- }
- else {
- if(from_dupli) {
- compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, compiler.stack_assign(out));
- }
- else if(compiler.output_type() == SHADER_TYPE_VOLUME) {
- compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, compiler.stack_assign(out));
- }
- else {
- int attr = compiler.attribute(ATTR_STD_GENERATED);
- compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
- }
- }
- }
-
- out = output("Normal");
- if(!out->links.empty()) {
- compiler.add_node(texco_node, NODE_TEXCO_NORMAL, compiler.stack_assign(out));
- }
-
- out = output("UV");
- if(!out->links.empty()) {
- if(from_dupli) {
- compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
- }
- else {
- int attr = compiler.attribute(ATTR_STD_UV);
- compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
- }
- }
-
- out = output("Object");
- if(!out->links.empty()) {
- compiler.add_node(texco_node, NODE_TEXCO_OBJECT, compiler.stack_assign(out), use_transform);
- if(use_transform) {
- Transform ob_itfm = transform_inverse(ob_tfm);
- compiler.add_node(ob_itfm.x);
- compiler.add_node(ob_itfm.y);
- compiler.add_node(ob_itfm.z);
- }
- }
-
- out = output("Camera");
- if(!out->links.empty()) {
- compiler.add_node(texco_node, NODE_TEXCO_CAMERA, compiler.stack_assign(out));
- }
-
- out = output("Window");
- if(!out->links.empty()) {
- compiler.add_node(texco_node, NODE_TEXCO_WINDOW, compiler.stack_assign(out));
- }
-
- out = output("Reflection");
- if(!out->links.empty()) {
- if(compiler.background) {
- compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
- }
- else {
- compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, compiler.stack_assign(out));
- }
- }
-}
-
-void TextureCoordinateNode::compile(OSLCompiler& compiler)
-{
- if(bump == SHADER_BUMP_DX)
- compiler.parameter("bump_offset", "dx");
- else if(bump == SHADER_BUMP_DY)
- compiler.parameter("bump_offset", "dy");
- else
- compiler.parameter("bump_offset", "center");
-
- if(compiler.background)
- compiler.parameter("is_background", true);
- if(compiler.output_type() == SHADER_TYPE_VOLUME)
- compiler.parameter("is_volume", true);
- compiler.parameter(this, "use_transform");
- Transform ob_itfm = transform_inverse(ob_tfm);
- compiler.parameter("object_itfm", ob_itfm);
-
- compiler.parameter(this, "from_dupli");
-
- compiler.add(this, "node_texture_coordinate");
+ if (shader->has_surface) {
+ if (!from_dupli) {
+ if (!output("Generated")->links.empty())
+ attributes->add(ATTR_STD_GENERATED);
+ if (!output("UV")->links.empty())
+ attributes->add(ATTR_STD_UV);
+ }
+ }
+
+ if (shader->has_volume) {
+ if (!from_dupli) {
+ if (!output("Generated")->links.empty()) {
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ }
+ }
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void TextureCoordinateNode::compile(SVMCompiler &compiler)
+{
+ ShaderOutput *out;
+ ShaderNodeType texco_node = NODE_TEX_COORD;
+ ShaderNodeType attr_node = NODE_ATTR;
+ ShaderNodeType geom_node = NODE_GEOMETRY;
+
+ if (bump == SHADER_BUMP_DX) {
+ texco_node = NODE_TEX_COORD_BUMP_DX;
+ attr_node = NODE_ATTR_BUMP_DX;
+ geom_node = NODE_GEOMETRY_BUMP_DX;
+ }
+ else if (bump == SHADER_BUMP_DY) {
+ texco_node = NODE_TEX_COORD_BUMP_DY;
+ attr_node = NODE_ATTR_BUMP_DY;
+ geom_node = NODE_GEOMETRY_BUMP_DY;
+ }
+
+ out = output("Generated");
+ if (!out->links.empty()) {
+ if (compiler.background) {
+ compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
+ }
+ else {
+ if (from_dupli) {
+ compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, compiler.stack_assign(out));
+ }
+ else if (compiler.output_type() == SHADER_TYPE_VOLUME) {
+ compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, compiler.stack_assign(out));
+ }
+ else {
+ int attr = compiler.attribute(ATTR_STD_GENERATED);
+ compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
+ }
+ }
+ }
+
+ out = output("Normal");
+ if (!out->links.empty()) {
+ compiler.add_node(texco_node, NODE_TEXCO_NORMAL, compiler.stack_assign(out));
+ }
+
+ out = output("UV");
+ if (!out->links.empty()) {
+ if (from_dupli) {
+ compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
+ }
+ else {
+ int attr = compiler.attribute(ATTR_STD_UV);
+ compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
+ }
+ }
+
+ out = output("Object");
+ if (!out->links.empty()) {
+ compiler.add_node(texco_node, NODE_TEXCO_OBJECT, compiler.stack_assign(out), use_transform);
+ if (use_transform) {
+ Transform ob_itfm = transform_inverse(ob_tfm);
+ compiler.add_node(ob_itfm.x);
+ compiler.add_node(ob_itfm.y);
+ compiler.add_node(ob_itfm.z);
+ }
+ }
+
+ out = output("Camera");
+ if (!out->links.empty()) {
+ compiler.add_node(texco_node, NODE_TEXCO_CAMERA, compiler.stack_assign(out));
+ }
+
+ out = output("Window");
+ if (!out->links.empty()) {
+ compiler.add_node(texco_node, NODE_TEXCO_WINDOW, compiler.stack_assign(out));
+ }
+
+ out = output("Reflection");
+ if (!out->links.empty()) {
+ if (compiler.background) {
+ compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
+ }
+ else {
+ compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, compiler.stack_assign(out));
+ }
+ }
+}
+
+void TextureCoordinateNode::compile(OSLCompiler &compiler)
+{
+ if (bump == SHADER_BUMP_DX)
+ compiler.parameter("bump_offset", "dx");
+ else if (bump == SHADER_BUMP_DY)
+ compiler.parameter("bump_offset", "dy");
+ else
+ compiler.parameter("bump_offset", "center");
+
+ if (compiler.background)
+ compiler.parameter("is_background", true);
+ if (compiler.output_type() == SHADER_TYPE_VOLUME)
+ compiler.parameter("is_volume", true);
+ compiler.parameter(this, "use_transform");
+ Transform ob_itfm = transform_inverse(ob_tfm);
+ compiler.parameter("object_itfm", ob_itfm);
+
+ compiler.parameter(this, "from_dupli");
+
+ compiler.add(this, "node_texture_coordinate");
}
/* UV Map */
NODE_DEFINE(UVMapNode)
{
- NodeType* type = NodeType::add("uvmap", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("uvmap", create, NodeType::SHADER);
- SOCKET_STRING(attribute, "attribute", ustring());
- SOCKET_IN_BOOLEAN(from_dupli, "from dupli", false);
+ SOCKET_STRING(attribute, "attribute", ustring());
+ SOCKET_IN_BOOLEAN(from_dupli, "from dupli", false);
- SOCKET_OUT_POINT(UV, "UV");
+ SOCKET_OUT_POINT(UV, "UV");
- return type;
+ return type;
}
-UVMapNode::UVMapNode()
-: ShaderNode(node_type)
+UVMapNode::UVMapNode() : ShaderNode(node_type)
{
}
void UVMapNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- if(!from_dupli) {
- if(!output("UV")->links.empty()) {
- if(attribute != "")
- attributes->add(attribute);
- else
- attributes->add(ATTR_STD_UV);
- }
- }
- }
-
- ShaderNode::attributes(shader, attributes);
-}
-
-void UVMapNode::compile(SVMCompiler& compiler)
-{
- ShaderOutput *out = output("UV");
- ShaderNodeType texco_node = NODE_TEX_COORD;
- ShaderNodeType attr_node = NODE_ATTR;
- int attr;
-
- if(bump == SHADER_BUMP_DX) {
- texco_node = NODE_TEX_COORD_BUMP_DX;
- attr_node = NODE_ATTR_BUMP_DX;
- }
- else if(bump == SHADER_BUMP_DY) {
- texco_node = NODE_TEX_COORD_BUMP_DY;
- attr_node = NODE_ATTR_BUMP_DY;
- }
-
- if(!out->links.empty()) {
- if(from_dupli) {
- compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
- }
- else {
- if(attribute != "")
- attr = compiler.attribute(attribute);
- else
- attr = compiler.attribute(ATTR_STD_UV);
-
- compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
- }
- }
-}
-
-void UVMapNode::compile(OSLCompiler& compiler)
-{
- if(bump == SHADER_BUMP_DX)
- compiler.parameter("bump_offset", "dx");
- else if(bump == SHADER_BUMP_DY)
- compiler.parameter("bump_offset", "dy");
- else
- compiler.parameter("bump_offset", "center");
-
- compiler.parameter(this, "from_dupli");
- compiler.parameter(this, "attribute");
- compiler.add(this, "node_uv_map");
+ if (shader->has_surface) {
+ if (!from_dupli) {
+ if (!output("UV")->links.empty()) {
+ if (attribute != "")
+ attributes->add(attribute);
+ else
+ attributes->add(ATTR_STD_UV);
+ }
+ }
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void UVMapNode::compile(SVMCompiler &compiler)
+{
+ ShaderOutput *out = output("UV");
+ ShaderNodeType texco_node = NODE_TEX_COORD;
+ ShaderNodeType attr_node = NODE_ATTR;
+ int attr;
+
+ if (bump == SHADER_BUMP_DX) {
+ texco_node = NODE_TEX_COORD_BUMP_DX;
+ attr_node = NODE_ATTR_BUMP_DX;
+ }
+ else if (bump == SHADER_BUMP_DY) {
+ texco_node = NODE_TEX_COORD_BUMP_DY;
+ attr_node = NODE_ATTR_BUMP_DY;
+ }
+
+ if (!out->links.empty()) {
+ if (from_dupli) {
+ compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
+ }
+ else {
+ if (attribute != "")
+ attr = compiler.attribute(attribute);
+ else
+ attr = compiler.attribute(ATTR_STD_UV);
+
+ compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
+ }
+ }
+}
+
+void UVMapNode::compile(OSLCompiler &compiler)
+{
+ if (bump == SHADER_BUMP_DX)
+ compiler.parameter("bump_offset", "dx");
+ else if (bump == SHADER_BUMP_DY)
+ compiler.parameter("bump_offset", "dy");
+ else
+ compiler.parameter("bump_offset", "center");
+
+ compiler.parameter(this, "from_dupli");
+ compiler.parameter(this, "attribute");
+ compiler.add(this, "node_uv_map");
}
/* Light Path */
NODE_DEFINE(LightPathNode)
{
- NodeType* type = NodeType::add("light_path", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("light_path", create, NodeType::SHADER);
- SOCKET_OUT_FLOAT(is_camera_ray, "Is Camera Ray");
- SOCKET_OUT_FLOAT(is_shadow_ray, "Is Shadow Ray");
- SOCKET_OUT_FLOAT(is_diffuse_ray, "Is Diffuse Ray");
- SOCKET_OUT_FLOAT(is_glossy_ray, "Is Glossy Ray");
- SOCKET_OUT_FLOAT(is_singular_ray, "Is Singular Ray");
- SOCKET_OUT_FLOAT(is_reflection_ray, "Is Reflection Ray");
- SOCKET_OUT_FLOAT(is_transmission_ray, "Is Transmission Ray");
- SOCKET_OUT_FLOAT(is_volume_scatter_ray, "Is Volume Scatter Ray");
- SOCKET_OUT_FLOAT(ray_length, "Ray Length");
- SOCKET_OUT_FLOAT(ray_depth, "Ray Depth");
- SOCKET_OUT_FLOAT(diffuse_depth, "Diffuse Depth");
- SOCKET_OUT_FLOAT(glossy_depth, "Glossy Depth");
- SOCKET_OUT_FLOAT(transparent_depth, "Transparent Depth");
- SOCKET_OUT_FLOAT(transmission_depth, "Transmission Depth");
+ SOCKET_OUT_FLOAT(is_camera_ray, "Is Camera Ray");
+ SOCKET_OUT_FLOAT(is_shadow_ray, "Is Shadow Ray");
+ SOCKET_OUT_FLOAT(is_diffuse_ray, "Is Diffuse Ray");
+ SOCKET_OUT_FLOAT(is_glossy_ray, "Is Glossy Ray");
+ SOCKET_OUT_FLOAT(is_singular_ray, "Is Singular Ray");
+ SOCKET_OUT_FLOAT(is_reflection_ray, "Is Reflection Ray");
+ SOCKET_OUT_FLOAT(is_transmission_ray, "Is Transmission Ray");
+ SOCKET_OUT_FLOAT(is_volume_scatter_ray, "Is Volume Scatter Ray");
+ SOCKET_OUT_FLOAT(ray_length, "Ray Length");
+ SOCKET_OUT_FLOAT(ray_depth, "Ray Depth");
+ SOCKET_OUT_FLOAT(diffuse_depth, "Diffuse Depth");
+ SOCKET_OUT_FLOAT(glossy_depth, "Glossy Depth");
+ SOCKET_OUT_FLOAT(transparent_depth, "Transparent Depth");
+ SOCKET_OUT_FLOAT(transmission_depth, "Transmission Depth");
- return type;
+ return type;
}
-LightPathNode::LightPathNode()
-: ShaderNode(node_type)
+LightPathNode::LightPathNode() : ShaderNode(node_type)
{
}
-void LightPathNode::compile(SVMCompiler& compiler)
+void LightPathNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *out;
-
- out = output("Is Camera Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, compiler.stack_assign(out));
- }
+ ShaderOutput *out;
- out = output("Is Shadow Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, compiler.stack_assign(out));
- }
+ out = output("Is Camera Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, compiler.stack_assign(out));
+ }
- out = output("Is Diffuse Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, compiler.stack_assign(out));
- }
+ out = output("Is Shadow Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, compiler.stack_assign(out));
+ }
- out = output("Is Glossy Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, compiler.stack_assign(out));
- }
+ out = output("Is Diffuse Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, compiler.stack_assign(out));
+ }
- out = output("Is Singular Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, compiler.stack_assign(out));
- }
+ out = output("Is Glossy Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, compiler.stack_assign(out));
+ }
- out = output("Is Reflection Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, compiler.stack_assign(out));
- }
+ out = output("Is Singular Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, compiler.stack_assign(out));
+ }
+ out = output("Is Reflection Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, compiler.stack_assign(out));
+ }
- out = output("Is Transmission Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out));
- }
+ out = output("Is Transmission Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out));
+ }
- out = output("Is Volume Scatter Ray");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out));
- }
+ out = output("Is Volume Scatter Ray");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out));
+ }
- out = output("Ray Length");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out));
- }
+ out = output("Ray Length");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out));
+ }
- out = output("Ray Depth");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out));
- }
+ out = output("Ray Depth");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out));
+ }
- out = output("Diffuse Depth");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_diffuse, compiler.stack_assign(out));
- }
+ out = output("Diffuse Depth");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_diffuse, compiler.stack_assign(out));
+ }
- out = output("Glossy Depth");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_glossy, compiler.stack_assign(out));
- }
+ out = output("Glossy Depth");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_glossy, compiler.stack_assign(out));
+ }
- out = output("Transparent Depth");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, compiler.stack_assign(out));
- }
+ out = output("Transparent Depth");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, compiler.stack_assign(out));
+ }
- out = output("Transmission Depth");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transmission, compiler.stack_assign(out));
- }
+ out = output("Transmission Depth");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transmission, compiler.stack_assign(out));
+ }
}
-void LightPathNode::compile(OSLCompiler& compiler)
+void LightPathNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_light_path");
+ compiler.add(this, "node_light_path");
}
/* Light Falloff */
NODE_DEFINE(LightFalloffNode)
{
- NodeType* type = NodeType::add("light_falloff", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("light_falloff", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(strength, "Strength", 100.0f);
- SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
+ SOCKET_IN_FLOAT(strength, "Strength", 100.0f);
+ SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
- SOCKET_OUT_FLOAT(quadratic, "Quadratic");
- SOCKET_OUT_FLOAT(linear, "Linear");
- SOCKET_OUT_FLOAT(constant, "Constant");
+ SOCKET_OUT_FLOAT(quadratic, "Quadratic");
+ SOCKET_OUT_FLOAT(linear, "Linear");
+ SOCKET_OUT_FLOAT(constant, "Constant");
- return type;
+ return type;
}
-LightFalloffNode::LightFalloffNode()
-: ShaderNode(node_type)
+LightFalloffNode::LightFalloffNode() : ShaderNode(node_type)
{
}
-void LightFalloffNode::compile(SVMCompiler& compiler)
+void LightFalloffNode::compile(SVMCompiler &compiler)
{
- ShaderInput *strength_in = input("Strength");
- ShaderInput *smooth_in = input("Smooth");
+ ShaderInput *strength_in = input("Strength");
+ ShaderInput *smooth_in = input("Smooth");
- ShaderOutput *out = output("Quadratic");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_QUADRATIC,
- compiler.encode_uchar4(
- compiler.stack_assign(strength_in),
- compiler.stack_assign(smooth_in),
- compiler.stack_assign(out)));
- }
+ ShaderOutput *out = output("Quadratic");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_FALLOFF,
+ NODE_LIGHT_FALLOFF_QUADRATIC,
+ compiler.encode_uchar4(compiler.stack_assign(strength_in),
+ compiler.stack_assign(smooth_in),
+ compiler.stack_assign(out)));
+ }
- out = output("Linear");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_LINEAR,
- compiler.encode_uchar4(
- compiler.stack_assign(strength_in),
- compiler.stack_assign(smooth_in),
- compiler.stack_assign(out)));
- }
+ out = output("Linear");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_FALLOFF,
+ NODE_LIGHT_FALLOFF_LINEAR,
+ compiler.encode_uchar4(compiler.stack_assign(strength_in),
+ compiler.stack_assign(smooth_in),
+ compiler.stack_assign(out)));
+ }
- out = output("Constant");
- if(!out->links.empty()) {
- compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_CONSTANT,
- compiler.encode_uchar4(
- compiler.stack_assign(strength_in),
- compiler.stack_assign(smooth_in),
- compiler.stack_assign(out)));
- }
+ out = output("Constant");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_LIGHT_FALLOFF,
+ NODE_LIGHT_FALLOFF_CONSTANT,
+ compiler.encode_uchar4(compiler.stack_assign(strength_in),
+ compiler.stack_assign(smooth_in),
+ compiler.stack_assign(out)));
+ }
}
-void LightFalloffNode::compile(OSLCompiler& compiler)
+void LightFalloffNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_light_falloff");
+ compiler.add(this, "node_light_falloff");
}
/* Object Info */
NODE_DEFINE(ObjectInfoNode)
{
- NodeType* type = NodeType::add("object_info", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("object_info", create, NodeType::SHADER);
- SOCKET_OUT_VECTOR(location, "Location");
- SOCKET_OUT_FLOAT(object_index, "Object Index");
- SOCKET_OUT_FLOAT(material_index, "Material Index");
- SOCKET_OUT_FLOAT(random, "Random");
+ SOCKET_OUT_VECTOR(location, "Location");
+ SOCKET_OUT_FLOAT(object_index, "Object Index");
+ SOCKET_OUT_FLOAT(material_index, "Material Index");
+ SOCKET_OUT_FLOAT(random, "Random");
- return type;
+ return type;
}
-ObjectInfoNode::ObjectInfoNode()
-: ShaderNode(node_type)
+ObjectInfoNode::ObjectInfoNode() : ShaderNode(node_type)
{
}
-void ObjectInfoNode::compile(SVMCompiler& compiler)
+void ObjectInfoNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *out = output("Location");
- if(!out->links.empty()) {
- compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out));
- }
+ ShaderOutput *out = output("Location");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out));
+ }
- out = output("Object Index");
- if(!out->links.empty()) {
- compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out));
- }
+ out = output("Object Index");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out));
+ }
- out = output("Material Index");
- if(!out->links.empty()) {
- compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, compiler.stack_assign(out));
- }
+ out = output("Material Index");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, compiler.stack_assign(out));
+ }
- out = output("Random");
- if(!out->links.empty()) {
- compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, compiler.stack_assign(out));
- }
+ out = output("Random");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, compiler.stack_assign(out));
+ }
}
-void ObjectInfoNode::compile(OSLCompiler& compiler)
+void ObjectInfoNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_object_info");
+ compiler.add(this, "node_object_info");
}
/* Particle Info */
NODE_DEFINE(ParticleInfoNode)
{
- NodeType* type = NodeType::add("particle_info", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("particle_info", create, NodeType::SHADER);
- SOCKET_OUT_FLOAT(index, "Index");
- SOCKET_OUT_FLOAT(random, "Random");
- SOCKET_OUT_FLOAT(age, "Age");
- SOCKET_OUT_FLOAT(lifetime, "Lifetime");
- SOCKET_OUT_POINT(location, "Location");
-#if 0 /* not yet supported */
- SOCKET_OUT_QUATERNION(rotation, "Rotation");
+ SOCKET_OUT_FLOAT(index, "Index");
+ SOCKET_OUT_FLOAT(random, "Random");
+ SOCKET_OUT_FLOAT(age, "Age");
+ SOCKET_OUT_FLOAT(lifetime, "Lifetime");
+ SOCKET_OUT_POINT(location, "Location");
+#if 0 /* not yet supported */
+ SOCKET_OUT_QUATERNION(rotation, "Rotation");
#endif
- SOCKET_OUT_FLOAT(size, "Size");
- SOCKET_OUT_VECTOR(velocity, "Velocity");
- SOCKET_OUT_VECTOR(angular_velocity, "Angular Velocity");
+ SOCKET_OUT_FLOAT(size, "Size");
+ SOCKET_OUT_VECTOR(velocity, "Velocity");
+ SOCKET_OUT_VECTOR(angular_velocity, "Angular Velocity");
- return type;
+ return type;
}
-ParticleInfoNode::ParticleInfoNode()
-: ShaderNode(node_type)
+ParticleInfoNode::ParticleInfoNode() : ShaderNode(node_type)
{
}
void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(!output("Index")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
- if(!output("Random")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
- if(!output("Age")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
- if(!output("Lifetime")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
- if(!output("Location")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
-#if 0 /* not yet supported */
- if(!output("Rotation")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Index")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Random")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Age")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Lifetime")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Location")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+#if 0 /* not yet supported */
+ if(!output("Rotation")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
#endif
- if(!output("Size")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
- if(!output("Velocity")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
- if(!output("Angular Velocity")->links.empty())
- attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Size")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Velocity")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if (!output("Angular Velocity")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
- ShaderNode::attributes(shader, attributes);
+ ShaderNode::attributes(shader, attributes);
}
-void ParticleInfoNode::compile(SVMCompiler& compiler)
+void ParticleInfoNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *out;
+ ShaderOutput *out;
- out = output("Index");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out));
- }
+ out = output("Index");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out));
+ }
- out = output("Random");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out));
- }
+ out = output("Random");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out));
+ }
- out = output("Age");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out));
- }
+ out = output("Age");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out));
+ }
- out = output("Lifetime");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, compiler.stack_assign(out));
- }
+ out = output("Lifetime");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, compiler.stack_assign(out));
+ }
- out = output("Location");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, compiler.stack_assign(out));
- }
+ out = output("Location");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, compiler.stack_assign(out));
+ }
- /* quaternion data is not yet supported by Cycles */
+ /* quaternion data is not yet supported by Cycles */
#if 0
- out = output("Rotation");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, compiler.stack_assign(out));
- }
+ out = output("Rotation");
+ if(!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, compiler.stack_assign(out));
+ }
#endif
- out = output("Size");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out));
- }
+ out = output("Size");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out));
+ }
- out = output("Velocity");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, compiler.stack_assign(out));
- }
+ out = output("Velocity");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, compiler.stack_assign(out));
+ }
- out = output("Angular Velocity");
- if(!out->links.empty()) {
- compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, compiler.stack_assign(out));
- }
+ out = output("Angular Velocity");
+ if (!out->links.empty()) {
+ compiler.add_node(
+ NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, compiler.stack_assign(out));
+ }
}
-void ParticleInfoNode::compile(OSLCompiler& compiler)
+void ParticleInfoNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_particle_info");
+ compiler.add(this, "node_particle_info");
}
/* Hair Info */
NODE_DEFINE(HairInfoNode)
{
- NodeType* type = NodeType::add("hair_info", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("hair_info", create, NodeType::SHADER);
- SOCKET_OUT_FLOAT(is_strand, "Is Strand");
- SOCKET_OUT_FLOAT(intercept, "Intercept");
- SOCKET_OUT_FLOAT(thickness, "Thickness");
- SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal");
+ SOCKET_OUT_FLOAT(is_strand, "Is Strand");
+ SOCKET_OUT_FLOAT(intercept, "Intercept");
+ SOCKET_OUT_FLOAT(thickness, "Thickness");
+ SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal");
#if 0 /*output for minimum hair width transparency - deactivated */
- SOCKET_OUT_FLOAT(fade, "Fade");
+ SOCKET_OUT_FLOAT(fade, "Fade");
#endif
- SOCKET_OUT_FLOAT(index, "Random");
+ SOCKET_OUT_FLOAT(index, "Random");
- return type;
+ return type;
}
-HairInfoNode::HairInfoNode()
-: ShaderNode(node_type)
+HairInfoNode::HairInfoNode() : ShaderNode(node_type)
{
}
void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- ShaderOutput *intercept_out = output("Intercept");
+ if (shader->has_surface) {
+ ShaderOutput *intercept_out = output("Intercept");
- if(!intercept_out->links.empty())
- attributes->add(ATTR_STD_CURVE_INTERCEPT);
+ if (!intercept_out->links.empty())
+ attributes->add(ATTR_STD_CURVE_INTERCEPT);
- if(!output("Random")->links.empty())
- attributes->add(ATTR_STD_CURVE_RANDOM);
- }
+ if (!output("Random")->links.empty())
+ attributes->add(ATTR_STD_CURVE_RANDOM);
+ }
- ShaderNode::attributes(shader, attributes);
+ ShaderNode::attributes(shader, attributes);
}
-void HairInfoNode::compile(SVMCompiler& compiler)
+void HairInfoNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *out;
+ ShaderOutput *out;
- out = output("Is Strand");
- if(!out->links.empty()) {
- compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, compiler.stack_assign(out));
- }
+ out = output("Is Strand");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, compiler.stack_assign(out));
+ }
- out = output("Intercept");
- if(!out->links.empty()) {
- int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
- compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
- }
+ out = output("Intercept");
+ if (!out->links.empty()) {
+ int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
+ compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
+ }
- out = output("Thickness");
- if(!out->links.empty()) {
- compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, compiler.stack_assign(out));
- }
+ out = output("Thickness");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, compiler.stack_assign(out));
+ }
- out = output("Tangent Normal");
- if(!out->links.empty()) {
- compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out));
- }
+ out = output("Tangent Normal");
+ if (!out->links.empty()) {
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out));
+ }
- /*out = output("Fade");
- if(!out->links.empty()) {
- compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out));
- }*/
+ /*out = output("Fade");
+ if(!out->links.empty()) {
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out));
+ }*/
- out = output("Random");
- if(!out->links.empty()) {
- int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);
- compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
- }
+ out = output("Random");
+ if (!out->links.empty()) {
+ int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);
+ compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
+ }
}
-void HairInfoNode::compile(OSLCompiler& compiler)
+void HairInfoNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_hair_info");
+ compiler.add(this, "node_hair_info");
}
/* Value */
NODE_DEFINE(ValueNode)
{
- NodeType* type = NodeType::add("value", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("value", create, NodeType::SHADER);
- SOCKET_FLOAT(value, "Value", 0.0f);
- SOCKET_OUT_FLOAT(value, "Value");
+ SOCKET_FLOAT(value, "Value", 0.0f);
+ SOCKET_OUT_FLOAT(value, "Value");
- return type;
+ return type;
}
-ValueNode::ValueNode()
-: ShaderNode(node_type)
+ValueNode::ValueNode() : ShaderNode(node_type)
{
}
-void ValueNode::constant_fold(const ConstantFolder& folder)
+void ValueNode::constant_fold(const ConstantFolder &folder)
{
- folder.make_constant(value);
+ folder.make_constant(value);
}
-void ValueNode::compile(SVMCompiler& compiler)
+void ValueNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *val_out = output("Value");
+ ShaderOutput *val_out = output("Value");
- compiler.add_node(NODE_VALUE_F, __float_as_int(value), compiler.stack_assign(val_out));
+ compiler.add_node(NODE_VALUE_F, __float_as_int(value), compiler.stack_assign(val_out));
}
-void ValueNode::compile(OSLCompiler& compiler)
+void ValueNode::compile(OSLCompiler &compiler)
{
- compiler.parameter("value_value", value);
- compiler.add(this, "node_value");
+ compiler.parameter("value_value", value);
+ compiler.add(this, "node_value");
}
/* Color */
NODE_DEFINE(ColorNode)
{
- NodeType* type = NodeType::add("color", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("color", create, NodeType::SHADER);
- SOCKET_COLOR(value, "Value", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_COLOR(value, "Value", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-ColorNode::ColorNode()
-: ShaderNode(node_type)
+ColorNode::ColorNode() : ShaderNode(node_type)
{
}
-void ColorNode::constant_fold(const ConstantFolder& folder)
+void ColorNode::constant_fold(const ConstantFolder &folder)
{
- folder.make_constant(value);
+ folder.make_constant(value);
}
-void ColorNode::compile(SVMCompiler& compiler)
+void ColorNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *color_out = output("Color");
+ ShaderOutput *color_out = output("Color");
- if(!color_out->links.empty()) {
- compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
- compiler.add_node(NODE_VALUE_V, value);
- }
+ if (!color_out->links.empty()) {
+ compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
+ compiler.add_node(NODE_VALUE_V, value);
+ }
}
-void ColorNode::compile(OSLCompiler& compiler)
+void ColorNode::compile(OSLCompiler &compiler)
{
- compiler.parameter_color("color_value", value);
+ compiler.parameter_color("color_value", value);
- compiler.add(this, "node_value");
+ compiler.add(this, "node_value");
}
/* Add Closure */
NODE_DEFINE(AddClosureNode)
{
- NodeType* type = NodeType::add("add_closure", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("add_closure", create, NodeType::SHADER);
- SOCKET_IN_CLOSURE(closure1, "Closure1");
- SOCKET_IN_CLOSURE(closure2, "Closure2");
- SOCKET_OUT_CLOSURE(closure, "Closure");
+ SOCKET_IN_CLOSURE(closure1, "Closure1");
+ SOCKET_IN_CLOSURE(closure2, "Closure2");
+ SOCKET_OUT_CLOSURE(closure, "Closure");
- return type;
+ return type;
}
-AddClosureNode::AddClosureNode()
-: ShaderNode(node_type)
+AddClosureNode::AddClosureNode() : ShaderNode(node_type)
{
- special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
+ special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
}
-void AddClosureNode::compile(SVMCompiler& /*compiler*/)
+void AddClosureNode::compile(SVMCompiler & /*compiler*/)
{
- /* handled in the SVM compiler */
+ /* handled in the SVM compiler */
}
-void AddClosureNode::compile(OSLCompiler& compiler)
+void AddClosureNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_add_closure");
+ compiler.add(this, "node_add_closure");
}
-void AddClosureNode::constant_fold(const ConstantFolder& folder)
+void AddClosureNode::constant_fold(const ConstantFolder &folder)
{
- ShaderInput *closure1_in = input("Closure1");
- ShaderInput *closure2_in = input("Closure2");
+ ShaderInput *closure1_in = input("Closure1");
+ ShaderInput *closure2_in = input("Closure2");
- /* remove useless add closures nodes */
- if(!closure1_in->link) {
- folder.bypass_or_discard(closure2_in);
- }
- else if(!closure2_in->link) {
- folder.bypass_or_discard(closure1_in);
- }
+ /* remove useless add closures nodes */
+ if (!closure1_in->link) {
+ folder.bypass_or_discard(closure2_in);
+ }
+ else if (!closure2_in->link) {
+ folder.bypass_or_discard(closure1_in);
+ }
}
/* Mix Closure */
NODE_DEFINE(MixClosureNode)
{
- NodeType* type = NodeType::add("mix_closure", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("mix_closure", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
- SOCKET_IN_CLOSURE(closure1, "Closure1");
- SOCKET_IN_CLOSURE(closure2, "Closure2");
+ SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
+ SOCKET_IN_CLOSURE(closure1, "Closure1");
+ SOCKET_IN_CLOSURE(closure2, "Closure2");
- SOCKET_OUT_CLOSURE(closure, "Closure");
+ SOCKET_OUT_CLOSURE(closure, "Closure");
- return type;
+ return type;
}
-MixClosureNode::MixClosureNode()
-: ShaderNode(node_type)
+MixClosureNode::MixClosureNode() : ShaderNode(node_type)
{
- special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
+ special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
}
-void MixClosureNode::compile(SVMCompiler& /*compiler*/)
+void MixClosureNode::compile(SVMCompiler & /*compiler*/)
{
- /* handled in the SVM compiler */
+ /* handled in the SVM compiler */
}
-void MixClosureNode::compile(OSLCompiler& compiler)
+void MixClosureNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_mix_closure");
+ compiler.add(this, "node_mix_closure");
}
-void MixClosureNode::constant_fold(const ConstantFolder& folder)
+void MixClosureNode::constant_fold(const ConstantFolder &folder)
{
- ShaderInput *fac_in = input("Fac");
- ShaderInput *closure1_in = input("Closure1");
- ShaderInput *closure2_in = input("Closure2");
+ ShaderInput *fac_in = input("Fac");
+ ShaderInput *closure1_in = input("Closure1");
+ ShaderInput *closure2_in = input("Closure2");
- /* remove useless mix closures nodes */
- if(closure1_in->link == closure2_in->link) {
- folder.bypass_or_discard(closure1_in);
- }
- /* remove unused mix closure input when factor is 0.0 or 1.0
- * check for closure links and make sure factor link is disconnected */
- else if(!fac_in->link) {
- /* factor 0.0 */
- if(fac <= 0.0f) {
- folder.bypass_or_discard(closure1_in);
- }
- /* factor 1.0 */
- else if(fac >= 1.0f) {
- folder.bypass_or_discard(closure2_in);
- }
- }
+ /* remove useless mix closures nodes */
+ if (closure1_in->link == closure2_in->link) {
+ folder.bypass_or_discard(closure1_in);
+ }
+ /* remove unused mix closure input when factor is 0.0 or 1.0
+ * check for closure links and make sure factor link is disconnected */
+ else if (!fac_in->link) {
+ /* factor 0.0 */
+ if (fac <= 0.0f) {
+ folder.bypass_or_discard(closure1_in);
+ }
+ /* factor 1.0 */
+ else if (fac >= 1.0f) {
+ folder.bypass_or_discard(closure2_in);
+ }
+ }
}
/* Mix Closure */
NODE_DEFINE(MixClosureWeightNode)
{
- NodeType* type = NodeType::add("mix_closure_weight", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("mix_closure_weight", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(weight, "Weight", 1.0f);
- SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
+ SOCKET_IN_FLOAT(weight, "Weight", 1.0f);
+ SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
- SOCKET_OUT_FLOAT(weight1, "Weight1");
- SOCKET_OUT_FLOAT(weight2, "Weight2");
+ SOCKET_OUT_FLOAT(weight1, "Weight1");
+ SOCKET_OUT_FLOAT(weight2, "Weight2");
- return type;
+ return type;
}
-MixClosureWeightNode::MixClosureWeightNode()
-: ShaderNode(node_type)
+MixClosureWeightNode::MixClosureWeightNode() : ShaderNode(node_type)
{
}
-void MixClosureWeightNode::compile(SVMCompiler& compiler)
+void MixClosureWeightNode::compile(SVMCompiler &compiler)
{
- ShaderInput *weight_in = input("Weight");
- ShaderInput *fac_in = input("Fac");
- ShaderOutput *weight1_out = output("Weight1");
- ShaderOutput *weight2_out = output("Weight2");
+ ShaderInput *weight_in = input("Weight");
+ ShaderInput *fac_in = input("Fac");
+ ShaderOutput *weight1_out = output("Weight1");
+ ShaderOutput *weight2_out = output("Weight2");
- compiler.add_node(NODE_MIX_CLOSURE,
- compiler.encode_uchar4(
- compiler.stack_assign(fac_in),
- compiler.stack_assign(weight_in),
- compiler.stack_assign(weight1_out),
- compiler.stack_assign(weight2_out)));
+ compiler.add_node(NODE_MIX_CLOSURE,
+ compiler.encode_uchar4(compiler.stack_assign(fac_in),
+ compiler.stack_assign(weight_in),
+ compiler.stack_assign(weight1_out),
+ compiler.stack_assign(weight2_out)));
}
-void MixClosureWeightNode::compile(OSLCompiler& /*compiler*/)
+void MixClosureWeightNode::compile(OSLCompiler & /*compiler*/)
{
- assert(0);
+ assert(0);
}
/* Invert */
NODE_DEFINE(InvertNode)
{
- NodeType* type = NodeType::add("invert", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("invert", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-InvertNode::InvertNode()
-: ShaderNode(node_type)
+InvertNode::InvertNode() : ShaderNode(node_type)
{
}
-void InvertNode::constant_fold(const ConstantFolder& folder)
+void InvertNode::constant_fold(const ConstantFolder &folder)
{
- ShaderInput *fac_in = input("Fac");
- ShaderInput *color_in = input("Color");
+ ShaderInput *fac_in = input("Fac");
+ ShaderInput *color_in = input("Color");
- if(!fac_in->link) {
- /* evaluate fully constant node */
- if(!color_in->link) {
- folder.make_constant(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac));
- }
- /* remove no-op node */
- else if(fac == 0.0f) {
- folder.bypass(color_in->link);
- }
- }
+ if (!fac_in->link) {
+ /* evaluate fully constant node */
+ if (!color_in->link) {
+ folder.make_constant(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac));
+ }
+ /* remove no-op node */
+ else if (fac == 0.0f) {
+ folder.bypass(color_in->link);
+ }
+ }
}
-void InvertNode::compile(SVMCompiler& compiler)
+void InvertNode::compile(SVMCompiler &compiler)
{
- ShaderInput *fac_in = input("Fac");
- ShaderInput *color_in = input("Color");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *fac_in = input("Fac");
+ ShaderInput *color_in = input("Color");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_INVERT,
- compiler.stack_assign(fac_in),
- compiler.stack_assign(color_in),
- compiler.stack_assign(color_out));
+ compiler.add_node(NODE_INVERT,
+ compiler.stack_assign(fac_in),
+ compiler.stack_assign(color_in),
+ compiler.stack_assign(color_out));
}
-void InvertNode::compile(OSLCompiler& compiler)
+void InvertNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_invert");
+ compiler.add(this, "node_invert");
}
/* Mix */
NODE_DEFINE(MixNode)
{
- NodeType* type = NodeType::add("mix", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("mix", create, NodeType::SHADER);
- static NodeEnum type_enum;
- type_enum.insert("mix", NODE_MIX_BLEND);
- type_enum.insert("add", NODE_MIX_ADD);
- type_enum.insert("multiply", NODE_MIX_MUL);
- type_enum.insert("screen", NODE_MIX_SCREEN);
- type_enum.insert("overlay", NODE_MIX_OVERLAY);
- type_enum.insert("subtract", NODE_MIX_SUB);
- type_enum.insert("divide", NODE_MIX_DIV);
- type_enum.insert("difference", NODE_MIX_DIFF);
- type_enum.insert("darken", NODE_MIX_DARK);
- type_enum.insert("lighten", NODE_MIX_LIGHT);
- type_enum.insert("dodge", NODE_MIX_DODGE);
- type_enum.insert("burn", NODE_MIX_BURN);
- type_enum.insert("hue", NODE_MIX_HUE);
- type_enum.insert("saturation", NODE_MIX_SAT);
- type_enum.insert("value", NODE_MIX_VAL);
- type_enum.insert("color", NODE_MIX_COLOR);
- type_enum.insert("soft_light", NODE_MIX_SOFT);
- type_enum.insert("linear_light", NODE_MIX_LINEAR);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MIX_BLEND);
+ static NodeEnum type_enum;
+ type_enum.insert("mix", NODE_MIX_BLEND);
+ type_enum.insert("add", NODE_MIX_ADD);
+ type_enum.insert("multiply", NODE_MIX_MUL);
+ type_enum.insert("screen", NODE_MIX_SCREEN);
+ type_enum.insert("overlay", NODE_MIX_OVERLAY);
+ type_enum.insert("subtract", NODE_MIX_SUB);
+ type_enum.insert("divide", NODE_MIX_DIV);
+ type_enum.insert("difference", NODE_MIX_DIFF);
+ type_enum.insert("darken", NODE_MIX_DARK);
+ type_enum.insert("lighten", NODE_MIX_LIGHT);
+ type_enum.insert("dodge", NODE_MIX_DODGE);
+ type_enum.insert("burn", NODE_MIX_BURN);
+ type_enum.insert("hue", NODE_MIX_HUE);
+ type_enum.insert("saturation", NODE_MIX_SAT);
+ type_enum.insert("value", NODE_MIX_VAL);
+ type_enum.insert("color", NODE_MIX_COLOR);
+ type_enum.insert("soft_light", NODE_MIX_SOFT);
+ type_enum.insert("linear_light", NODE_MIX_LINEAR);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_MIX_BLEND);
- SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
+ SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
- SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
- SOCKET_IN_COLOR(color1, "Color1", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_COLOR(color2, "Color2", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
+ SOCKET_IN_COLOR(color1, "Color1", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_COLOR(color2, "Color2", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-MixNode::MixNode()
-: ShaderNode(node_type)
+MixNode::MixNode() : ShaderNode(node_type)
{
}
-void MixNode::compile(SVMCompiler& compiler)
+void MixNode::compile(SVMCompiler &compiler)
{
- ShaderInput *fac_in = input("Fac");
- ShaderInput *color1_in = input("Color1");
- ShaderInput *color2_in = input("Color2");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *fac_in = input("Fac");
+ ShaderInput *color1_in = input("Color1");
+ ShaderInput *color2_in = input("Color2");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_MIX,
- compiler.stack_assign(fac_in),
- compiler.stack_assign(color1_in),
- compiler.stack_assign(color2_in));
- compiler.add_node(NODE_MIX, type, compiler.stack_assign(color_out));
+ compiler.add_node(NODE_MIX,
+ compiler.stack_assign(fac_in),
+ compiler.stack_assign(color1_in),
+ compiler.stack_assign(color2_in));
+ compiler.add_node(NODE_MIX, type, compiler.stack_assign(color_out));
- if(use_clamp) {
- compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out));
- compiler.add_node(NODE_MIX, NODE_MIX_CLAMP, compiler.stack_assign(color_out));
- }
+ if (use_clamp) {
+ compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out));
+ compiler.add_node(NODE_MIX, NODE_MIX_CLAMP, compiler.stack_assign(color_out));
+ }
}
-void MixNode::compile(OSLCompiler& compiler)
+void MixNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "type");
- compiler.parameter(this, "use_clamp");
- compiler.add(this, "node_mix");
+ compiler.parameter(this, "type");
+ compiler.parameter(this, "use_clamp");
+ compiler.add(this, "node_mix");
}
-void MixNode::constant_fold(const ConstantFolder& folder)
+void MixNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant_clamp(svm_mix(type, fac, color1, color2), use_clamp);
- }
- else {
- folder.fold_mix(type, use_clamp);
- }
+ if (folder.all_inputs_constant()) {
+ folder.make_constant_clamp(svm_mix(type, fac, color1, color2), use_clamp);
+ }
+ else {
+ folder.fold_mix(type, use_clamp);
+ }
}
/* Combine RGB */
NODE_DEFINE(CombineRGBNode)
{
- NodeType* type = NodeType::add("combine_rgb", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("combine_rgb", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(r, "R", 0.0f);
- SOCKET_IN_FLOAT(g, "G", 0.0f);
- SOCKET_IN_FLOAT(b, "B", 0.0f);
+ SOCKET_IN_FLOAT(r, "R", 0.0f);
+ SOCKET_IN_FLOAT(g, "G", 0.0f);
+ SOCKET_IN_FLOAT(b, "B", 0.0f);
- SOCKET_OUT_COLOR(image, "Image");
+ SOCKET_OUT_COLOR(image, "Image");
- return type;
+ return type;
}
-CombineRGBNode::CombineRGBNode()
-: ShaderNode(node_type)
+CombineRGBNode::CombineRGBNode() : ShaderNode(node_type)
{
}
-void CombineRGBNode::constant_fold(const ConstantFolder& folder)
+void CombineRGBNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant(make_float3(r, g, b));
- }
+ if (folder.all_inputs_constant()) {
+ folder.make_constant(make_float3(r, g, b));
+ }
}
-void CombineRGBNode::compile(SVMCompiler& compiler)
+void CombineRGBNode::compile(SVMCompiler &compiler)
{
- ShaderInput *red_in = input("R");
- ShaderInput *green_in = input("G");
- ShaderInput *blue_in = input("B");
- ShaderOutput *color_out = output("Image");
+ ShaderInput *red_in = input("R");
+ ShaderInput *green_in = input("G");
+ ShaderInput *blue_in = input("B");
+ ShaderOutput *color_out = output("Image");
- compiler.add_node(NODE_COMBINE_VECTOR,
- compiler.stack_assign(red_in), 0,
- compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_COMBINE_VECTOR, compiler.stack_assign(red_in), 0, compiler.stack_assign(color_out));
- compiler.add_node(NODE_COMBINE_VECTOR,
- compiler.stack_assign(green_in), 1,
- compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_COMBINE_VECTOR, compiler.stack_assign(green_in), 1, compiler.stack_assign(color_out));
- compiler.add_node(NODE_COMBINE_VECTOR,
- compiler.stack_assign(blue_in), 2,
- compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_COMBINE_VECTOR, compiler.stack_assign(blue_in), 2, compiler.stack_assign(color_out));
}
-void CombineRGBNode::compile(OSLCompiler& compiler)
+void CombineRGBNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_combine_rgb");
+ compiler.add(this, "node_combine_rgb");
}
/* Combine XYZ */
NODE_DEFINE(CombineXYZNode)
{
- NodeType* type = NodeType::add("combine_xyz", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("combine_xyz", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(x, "X", 0.0f);
- SOCKET_IN_FLOAT(y, "Y", 0.0f);
- SOCKET_IN_FLOAT(z, "Z", 0.0f);
+ SOCKET_IN_FLOAT(x, "X", 0.0f);
+ SOCKET_IN_FLOAT(y, "Y", 0.0f);
+ SOCKET_IN_FLOAT(z, "Z", 0.0f);
- SOCKET_OUT_VECTOR(vector, "Vector");
+ SOCKET_OUT_VECTOR(vector, "Vector");
- return type;
+ return type;
}
-CombineXYZNode::CombineXYZNode()
-: ShaderNode(node_type)
+CombineXYZNode::CombineXYZNode() : ShaderNode(node_type)
{
}
-void CombineXYZNode::constant_fold(const ConstantFolder& folder)
+void CombineXYZNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant(make_float3(x, y, z));
- }
+ if (folder.all_inputs_constant()) {
+ folder.make_constant(make_float3(x, y, z));
+ }
}
-void CombineXYZNode::compile(SVMCompiler& compiler)
+void CombineXYZNode::compile(SVMCompiler &compiler)
{
- ShaderInput *x_in = input("X");
- ShaderInput *y_in = input("Y");
- ShaderInput *z_in = input("Z");
- ShaderOutput *vector_out = output("Vector");
+ ShaderInput *x_in = input("X");
+ ShaderInput *y_in = input("Y");
+ ShaderInput *z_in = input("Z");
+ ShaderOutput *vector_out = output("Vector");
- compiler.add_node(NODE_COMBINE_VECTOR,
- compiler.stack_assign(x_in), 0,
- compiler.stack_assign(vector_out));
+ compiler.add_node(
+ NODE_COMBINE_VECTOR, compiler.stack_assign(x_in), 0, compiler.stack_assign(vector_out));
- compiler.add_node(NODE_COMBINE_VECTOR,
- compiler.stack_assign(y_in), 1,
- compiler.stack_assign(vector_out));
+ compiler.add_node(
+ NODE_COMBINE_VECTOR, compiler.stack_assign(y_in), 1, compiler.stack_assign(vector_out));
- compiler.add_node(NODE_COMBINE_VECTOR,
- compiler.stack_assign(z_in), 2,
- compiler.stack_assign(vector_out));
+ compiler.add_node(
+ NODE_COMBINE_VECTOR, compiler.stack_assign(z_in), 2, compiler.stack_assign(vector_out));
}
-void CombineXYZNode::compile(OSLCompiler& compiler)
+void CombineXYZNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_combine_xyz");
+ compiler.add(this, "node_combine_xyz");
}
/* Combine HSV */
NODE_DEFINE(CombineHSVNode)
{
- NodeType* type = NodeType::add("combine_hsv", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("combine_hsv", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(h, "H", 0.0f);
- SOCKET_IN_FLOAT(s, "S", 0.0f);
- SOCKET_IN_FLOAT(v, "V", 0.0f);
+ SOCKET_IN_FLOAT(h, "H", 0.0f);
+ SOCKET_IN_FLOAT(s, "S", 0.0f);
+ SOCKET_IN_FLOAT(v, "V", 0.0f);
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-CombineHSVNode::CombineHSVNode()
-: ShaderNode(node_type)
+CombineHSVNode::CombineHSVNode() : ShaderNode(node_type)
{
}
-void CombineHSVNode::constant_fold(const ConstantFolder& folder)
+void CombineHSVNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant(hsv_to_rgb(make_float3(h, s, v)));
- }
+ if (folder.all_inputs_constant()) {
+ folder.make_constant(hsv_to_rgb(make_float3(h, s, v)));
+ }
}
-void CombineHSVNode::compile(SVMCompiler& compiler)
+void CombineHSVNode::compile(SVMCompiler &compiler)
{
- ShaderInput *hue_in = input("H");
- ShaderInput *saturation_in = input("S");
- ShaderInput *value_in = input("V");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *hue_in = input("H");
+ ShaderInput *saturation_in = input("S");
+ ShaderInput *value_in = input("V");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_COMBINE_HSV,
- compiler.stack_assign(hue_in),
- compiler.stack_assign(saturation_in),
- compiler.stack_assign(value_in));
- compiler.add_node(NODE_COMBINE_HSV,
- compiler.stack_assign(color_out));
+ compiler.add_node(NODE_COMBINE_HSV,
+ compiler.stack_assign(hue_in),
+ compiler.stack_assign(saturation_in),
+ compiler.stack_assign(value_in));
+ compiler.add_node(NODE_COMBINE_HSV, compiler.stack_assign(color_out));
}
-void CombineHSVNode::compile(OSLCompiler& compiler)
+void CombineHSVNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_combine_hsv");
+ compiler.add(this, "node_combine_hsv");
}
/* Gamma */
NODE_DEFINE(GammaNode)
{
- NodeType* type = NodeType::add("gamma", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("gamma", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_FLOAT(gamma, "Gamma", 1.0f);
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(gamma, "Gamma", 1.0f);
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-GammaNode::GammaNode()
-: ShaderNode(node_type)
+GammaNode::GammaNode() : ShaderNode(node_type)
{
}
-void GammaNode::constant_fold(const ConstantFolder& folder)
+void GammaNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant(svm_math_gamma_color(color, gamma));
- }
- else {
- ShaderInput *color_in = input("Color");
- ShaderInput *gamma_in = input("Gamma");
+ if (folder.all_inputs_constant()) {
+ folder.make_constant(svm_math_gamma_color(color, gamma));
+ }
+ else {
+ ShaderInput *color_in = input("Color");
+ ShaderInput *gamma_in = input("Gamma");
- /* 1 ^ X == X ^ 0 == 1 */
- if(folder.is_one(color_in) || folder.is_zero(gamma_in)) {
- folder.make_one();
- }
- /* X ^ 1 == X */
- else if(folder.is_one(gamma_in)) {
- folder.try_bypass_or_make_constant(color_in, false);
- }
- }
+ /* 1 ^ X == X ^ 0 == 1 */
+ if (folder.is_one(color_in) || folder.is_zero(gamma_in)) {
+ folder.make_one();
+ }
+ /* X ^ 1 == X */
+ else if (folder.is_one(gamma_in)) {
+ folder.try_bypass_or_make_constant(color_in, false);
+ }
+ }
}
-void GammaNode::compile(SVMCompiler& compiler)
+void GammaNode::compile(SVMCompiler &compiler)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *gamma_in = input("Gamma");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *gamma_in = input("Gamma");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_GAMMA,
- compiler.stack_assign(gamma_in),
- compiler.stack_assign(color_in),
- compiler.stack_assign(color_out));
+ compiler.add_node(NODE_GAMMA,
+ compiler.stack_assign(gamma_in),
+ compiler.stack_assign(color_in),
+ compiler.stack_assign(color_out));
}
-void GammaNode::compile(OSLCompiler& compiler)
+void GammaNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_gamma");
+ compiler.add(this, "node_gamma");
}
/* Bright Contrast */
NODE_DEFINE(BrightContrastNode)
{
- NodeType* type = NodeType::add("brightness_contrast", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("brightness_contrast", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_FLOAT(bright, "Bright", 0.0f);
- SOCKET_IN_FLOAT(contrast, "Contrast", 0.0f);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(bright, "Bright", 0.0f);
+ SOCKET_IN_FLOAT(contrast, "Contrast", 0.0f);
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-BrightContrastNode::BrightContrastNode()
-: ShaderNode(node_type)
+BrightContrastNode::BrightContrastNode() : ShaderNode(node_type)
{
}
-void BrightContrastNode::constant_fold(const ConstantFolder& folder)
+void BrightContrastNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant(svm_brightness_contrast(color, bright, contrast));
- }
+ if (folder.all_inputs_constant()) {
+ folder.make_constant(svm_brightness_contrast(color, bright, contrast));
+ }
}
-void BrightContrastNode::compile(SVMCompiler& compiler)
+void BrightContrastNode::compile(SVMCompiler &compiler)
{
- ShaderInput *color_in = input("Color");
- ShaderInput *bright_in = input("Bright");
- ShaderInput *contrast_in = input("Contrast");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *color_in = input("Color");
+ ShaderInput *bright_in = input("Bright");
+ ShaderInput *contrast_in = input("Contrast");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_BRIGHTCONTRAST,
- compiler.stack_assign(color_in),
- compiler.stack_assign(color_out),
- compiler.encode_uchar4(
- compiler.stack_assign(bright_in),
- compiler.stack_assign(contrast_in)));
+ compiler.add_node(NODE_BRIGHTCONTRAST,
+ compiler.stack_assign(color_in),
+ compiler.stack_assign(color_out),
+ compiler.encode_uchar4(compiler.stack_assign(bright_in),
+ compiler.stack_assign(contrast_in)));
}
-void BrightContrastNode::compile(OSLCompiler& compiler)
+void BrightContrastNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_brightness");
+ compiler.add(this, "node_brightness");
}
/* Separate RGB */
NODE_DEFINE(SeparateRGBNode)
{
- NodeType* type = NodeType::add("separate_rgb", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("separate_rgb", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Image", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_COLOR(color, "Image", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_FLOAT(r, "R");
- SOCKET_OUT_FLOAT(g, "G");
- SOCKET_OUT_FLOAT(b, "B");
+ SOCKET_OUT_FLOAT(r, "R");
+ SOCKET_OUT_FLOAT(g, "G");
+ SOCKET_OUT_FLOAT(b, "B");
- return type;
+ return type;
}
-SeparateRGBNode::SeparateRGBNode()
-: ShaderNode(node_type)
+SeparateRGBNode::SeparateRGBNode() : ShaderNode(node_type)
{
}
-void SeparateRGBNode::constant_fold(const ConstantFolder& folder)
+void SeparateRGBNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- for(int channel = 0; channel < 3; channel++) {
- if(outputs[channel] == folder.output) {
- folder.make_constant(color[channel]);
- return;
- }
- }
- }
+ if (folder.all_inputs_constant()) {
+ for (int channel = 0; channel < 3; channel++) {
+ if (outputs[channel] == folder.output) {
+ folder.make_constant(color[channel]);
+ return;
+ }
+ }
+ }
}
-void SeparateRGBNode::compile(SVMCompiler& compiler)
+void SeparateRGBNode::compile(SVMCompiler &compiler)
{
- ShaderInput *color_in = input("Image");
- ShaderOutput *red_out = output("R");
- ShaderOutput *green_out = output("G");
- ShaderOutput *blue_out = output("B");
+ ShaderInput *color_in = input("Image");
+ ShaderOutput *red_out = output("R");
+ ShaderOutput *green_out = output("G");
+ ShaderOutput *blue_out = output("B");
- compiler.add_node(NODE_SEPARATE_VECTOR,
- compiler.stack_assign(color_in), 0,
- compiler.stack_assign(red_out));
+ compiler.add_node(
+ NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 0, compiler.stack_assign(red_out));
- compiler.add_node(NODE_SEPARATE_VECTOR,
- compiler.stack_assign(color_in), 1,
- compiler.stack_assign(green_out));
+ compiler.add_node(
+ NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 1, compiler.stack_assign(green_out));
- compiler.add_node(NODE_SEPARATE_VECTOR,
- compiler.stack_assign(color_in), 2,
- compiler.stack_assign(blue_out));
+ compiler.add_node(
+ NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 2, compiler.stack_assign(blue_out));
}
-void SeparateRGBNode::compile(OSLCompiler& compiler)
+void SeparateRGBNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_separate_rgb");
+ compiler.add(this, "node_separate_rgb");
}
/* Separate XYZ */
NODE_DEFINE(SeparateXYZNode)
{
- NodeType* type = NodeType::add("separate_xyz", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("separate_xyz", create, NodeType::SHADER);
- SOCKET_IN_COLOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_COLOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_FLOAT(x, "X");
- SOCKET_OUT_FLOAT(y, "Y");
- SOCKET_OUT_FLOAT(z, "Z");
+ SOCKET_OUT_FLOAT(x, "X");
+ SOCKET_OUT_FLOAT(y, "Y");
+ SOCKET_OUT_FLOAT(z, "Z");
- return type;
+ return type;
}
-SeparateXYZNode::SeparateXYZNode()
-: ShaderNode(node_type)
+SeparateXYZNode::SeparateXYZNode() : ShaderNode(node_type)
{
}
-void SeparateXYZNode::constant_fold(const ConstantFolder& folder)
+void SeparateXYZNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- for(int channel = 0; channel < 3; channel++) {
- if(outputs[channel] == folder.output) {
- folder.make_constant(vector[channel]);
- return;
- }
- }
- }
+ if (folder.all_inputs_constant()) {
+ for (int channel = 0; channel < 3; channel++) {
+ if (outputs[channel] == folder.output) {
+ folder.make_constant(vector[channel]);
+ return;
+ }
+ }
+ }
}
-void SeparateXYZNode::compile(SVMCompiler& compiler)
+void SeparateXYZNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *x_out = output("X");
- ShaderOutput *y_out = output("Y");
- ShaderOutput *z_out = output("Z");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *x_out = output("X");
+ ShaderOutput *y_out = output("Y");
+ ShaderOutput *z_out = output("Z");
- compiler.add_node(NODE_SEPARATE_VECTOR,
- compiler.stack_assign(vector_in), 0,
- compiler.stack_assign(x_out));
+ compiler.add_node(
+ NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 0, compiler.stack_assign(x_out));
- compiler.add_node(NODE_SEPARATE_VECTOR,
- compiler.stack_assign(vector_in), 1,
- compiler.stack_assign(y_out));
+ compiler.add_node(
+ NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 1, compiler.stack_assign(y_out));
- compiler.add_node(NODE_SEPARATE_VECTOR,
- compiler.stack_assign(vector_in), 2,
- compiler.stack_assign(z_out));
+ compiler.add_node(
+ NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 2, compiler.stack_assign(z_out));
}
-void SeparateXYZNode::compile(OSLCompiler& compiler)
+void SeparateXYZNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_separate_xyz");
+ compiler.add(this, "node_separate_xyz");
}
/* Separate HSV */
NODE_DEFINE(SeparateHSVNode)
{
- NodeType* type = NodeType::add("separate_hsv", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("separate_hsv", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_FLOAT(h, "H");
- SOCKET_OUT_FLOAT(s, "S");
- SOCKET_OUT_FLOAT(v, "V");
+ SOCKET_OUT_FLOAT(h, "H");
+ SOCKET_OUT_FLOAT(s, "S");
+ SOCKET_OUT_FLOAT(v, "V");
- return type;
+ return type;
}
-SeparateHSVNode::SeparateHSVNode()
-: ShaderNode(node_type)
+SeparateHSVNode::SeparateHSVNode() : ShaderNode(node_type)
{
}
-void SeparateHSVNode::constant_fold(const ConstantFolder& folder)
+void SeparateHSVNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- float3 hsv = rgb_to_hsv(color);
+ if (folder.all_inputs_constant()) {
+ float3 hsv = rgb_to_hsv(color);
- for(int channel = 0; channel < 3; channel++) {
- if(outputs[channel] == folder.output) {
- folder.make_constant(hsv[channel]);
- return;
- }
- }
- }
+ for (int channel = 0; channel < 3; channel++) {
+ if (outputs[channel] == folder.output) {
+ folder.make_constant(hsv[channel]);
+ return;
+ }
+ }
+ }
}
-void SeparateHSVNode::compile(SVMCompiler& compiler)
+void SeparateHSVNode::compile(SVMCompiler &compiler)
{
- ShaderInput *color_in = input("Color");
- ShaderOutput *hue_out = output("H");
- ShaderOutput *saturation_out = output("S");
- ShaderOutput *value_out = output("V");
+ ShaderInput *color_in = input("Color");
+ ShaderOutput *hue_out = output("H");
+ ShaderOutput *saturation_out = output("S");
+ ShaderOutput *value_out = output("V");
- compiler.add_node(NODE_SEPARATE_HSV,
- compiler.stack_assign(color_in),
- compiler.stack_assign(hue_out),
- compiler.stack_assign(saturation_out));
- compiler.add_node(NODE_SEPARATE_HSV,
- compiler.stack_assign(value_out));
+ compiler.add_node(NODE_SEPARATE_HSV,
+ compiler.stack_assign(color_in),
+ compiler.stack_assign(hue_out),
+ compiler.stack_assign(saturation_out));
+ compiler.add_node(NODE_SEPARATE_HSV, compiler.stack_assign(value_out));
}
-void SeparateHSVNode::compile(OSLCompiler& compiler)
+void SeparateHSVNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_separate_hsv");
+ compiler.add(this, "node_separate_hsv");
}
/* Hue Saturation Value */
NODE_DEFINE(HSVNode)
{
- NodeType* type = NodeType::add("hsv", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("hsv", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(hue, "Hue", 0.5f);
- SOCKET_IN_FLOAT(saturation, "Saturation", 1.0f);
- SOCKET_IN_FLOAT(value, "Value", 1.0f);
- SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(hue, "Hue", 0.5f);
+ SOCKET_IN_FLOAT(saturation, "Saturation", 1.0f);
+ SOCKET_IN_FLOAT(value, "Value", 1.0f);
+ SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-HSVNode::HSVNode()
-: ShaderNode(node_type)
+HSVNode::HSVNode() : ShaderNode(node_type)
{
}
-void HSVNode::compile(SVMCompiler& compiler)
+void HSVNode::compile(SVMCompiler &compiler)
{
- ShaderInput *hue_in = input("Hue");
- ShaderInput *saturation_in = input("Saturation");
- ShaderInput *value_in = input("Value");
- ShaderInput *fac_in = input("Fac");
- ShaderInput *color_in = input("Color");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *hue_in = input("Hue");
+ ShaderInput *saturation_in = input("Saturation");
+ ShaderInput *value_in = input("Value");
+ ShaderInput *fac_in = input("Fac");
+ ShaderInput *color_in = input("Color");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_HSV,
- compiler.encode_uchar4(
- compiler.stack_assign(color_in),
- compiler.stack_assign(fac_in),
- compiler.stack_assign(color_out)),
- compiler.encode_uchar4(
- compiler.stack_assign(hue_in),
- compiler.stack_assign(saturation_in),
- compiler.stack_assign(value_in)));
+ compiler.add_node(NODE_HSV,
+ compiler.encode_uchar4(compiler.stack_assign(color_in),
+ compiler.stack_assign(fac_in),
+ compiler.stack_assign(color_out)),
+ compiler.encode_uchar4(compiler.stack_assign(hue_in),
+ compiler.stack_assign(saturation_in),
+ compiler.stack_assign(value_in)));
}
-void HSVNode::compile(OSLCompiler& compiler)
+void HSVNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_hsv");
+ compiler.add(this, "node_hsv");
}
/* Attribute */
NODE_DEFINE(AttributeNode)
{
- NodeType* type = NodeType::add("attribute", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("attribute", create, NodeType::SHADER);
- SOCKET_STRING(attribute, "Attribute", ustring());
+ SOCKET_STRING(attribute, "Attribute", ustring());
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_VECTOR(vector, "Vector");
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_VECTOR(vector, "Vector");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-AttributeNode::AttributeNode()
-: ShaderNode(node_type)
+AttributeNode::AttributeNode() : ShaderNode(node_type)
{
}
void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- ShaderOutput *color_out = output("Color");
- ShaderOutput *vector_out = output("Vector");
- ShaderOutput *fac_out = output("Fac");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *vector_out = output("Vector");
+ ShaderOutput *fac_out = output("Fac");
- if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) {
- attributes->add_standard(attribute);
- }
+ if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) {
+ attributes->add_standard(attribute);
+ }
- if(shader->has_volume) {
- attributes->add(ATTR_STD_GENERATED_TRANSFORM);
- }
+ if (shader->has_volume) {
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ }
- ShaderNode::attributes(shader, attributes);
+ ShaderNode::attributes(shader, attributes);
}
-void AttributeNode::compile(SVMCompiler& compiler)
+void AttributeNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *color_out = output("Color");
- ShaderOutput *vector_out = output("Vector");
- ShaderOutput *fac_out = output("Fac");
- ShaderNodeType attr_node = NODE_ATTR;
- int attr = compiler.attribute_standard(attribute);
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *vector_out = output("Vector");
+ ShaderOutput *fac_out = output("Fac");
+ ShaderNodeType attr_node = NODE_ATTR;
+ int attr = compiler.attribute_standard(attribute);
- if(bump == SHADER_BUMP_DX)
- attr_node = NODE_ATTR_BUMP_DX;
- else if(bump == SHADER_BUMP_DY)
- attr_node = NODE_ATTR_BUMP_DY;
+ if (bump == SHADER_BUMP_DX)
+ attr_node = NODE_ATTR_BUMP_DX;
+ else if (bump == SHADER_BUMP_DY)
+ attr_node = NODE_ATTR_BUMP_DY;
- if(!color_out->links.empty() || !vector_out->links.empty()) {
- if(!color_out->links.empty()) {
- compiler.add_node(attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_FLOAT3);
- }
- if(!vector_out->links.empty()) {
- compiler.add_node(attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_FLOAT3);
- }
- }
+ if (!color_out->links.empty() || !vector_out->links.empty()) {
+ if (!color_out->links.empty()) {
+ compiler.add_node(attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_FLOAT3);
+ }
+ if (!vector_out->links.empty()) {
+ compiler.add_node(attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_FLOAT3);
+ }
+ }
- if(!fac_out->links.empty()) {
- compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_FLOAT);
- }
+ if (!fac_out->links.empty()) {
+ compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_FLOAT);
+ }
}
-void AttributeNode::compile(OSLCompiler& compiler)
+void AttributeNode::compile(OSLCompiler &compiler)
{
- if(bump == SHADER_BUMP_DX)
- compiler.parameter("bump_offset", "dx");
- else if(bump == SHADER_BUMP_DY)
- compiler.parameter("bump_offset", "dy");
- else
- compiler.parameter("bump_offset", "center");
+ if (bump == SHADER_BUMP_DX)
+ compiler.parameter("bump_offset", "dx");
+ else if (bump == SHADER_BUMP_DY)
+ compiler.parameter("bump_offset", "dy");
+ else
+ compiler.parameter("bump_offset", "center");
- if(Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE)
- compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
- else
- compiler.parameter("name", attribute.c_str());
+ if (Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE)
+ compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
+ else
+ compiler.parameter("name", attribute.c_str());
- compiler.add(this, "node_attribute");
+ compiler.add(this, "node_attribute");
}
/* Camera */
NODE_DEFINE(CameraNode)
{
- NodeType* type = NodeType::add("camera_info", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("camera_info", create, NodeType::SHADER);
- SOCKET_OUT_VECTOR(view_vector, "View Vector");
- SOCKET_OUT_FLOAT(view_z_depth, "View Z Depth");
- SOCKET_OUT_FLOAT(view_distance, "View Distance");
+ SOCKET_OUT_VECTOR(view_vector, "View Vector");
+ SOCKET_OUT_FLOAT(view_z_depth, "View Z Depth");
+ SOCKET_OUT_FLOAT(view_distance, "View Distance");
- return type;
+ return type;
}
-CameraNode::CameraNode()
-: ShaderNode(node_type)
+CameraNode::CameraNode() : ShaderNode(node_type)
{
}
-void CameraNode::compile(SVMCompiler& compiler)
+void CameraNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *vector_out = output("View Vector");
- ShaderOutput *z_depth_out = output("View Z Depth");
- ShaderOutput *distance_out = output("View Distance");
+ ShaderOutput *vector_out = output("View Vector");
+ ShaderOutput *z_depth_out = output("View Z Depth");
+ ShaderOutput *distance_out = output("View Distance");
- compiler.add_node(NODE_CAMERA,
- compiler.stack_assign(vector_out),
- compiler.stack_assign(z_depth_out),
- compiler.stack_assign(distance_out));
+ compiler.add_node(NODE_CAMERA,
+ compiler.stack_assign(vector_out),
+ compiler.stack_assign(z_depth_out),
+ compiler.stack_assign(distance_out));
}
-void CameraNode::compile(OSLCompiler& compiler)
+void CameraNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_camera");
+ compiler.add(this, "node_camera");
}
/* Fresnel */
NODE_DEFINE(FresnelNode)
{
- NodeType* type = NodeType::add("fresnel", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("fresnel", create, NodeType::SHADER);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
- SOCKET_IN_FLOAT(IOR, "IOR", 1.45f);
+ SOCKET_IN_NORMAL(normal,
+ "Normal",
+ make_float3(0.0f, 0.0f, 0.0f),
+ SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
+ SOCKET_IN_FLOAT(IOR, "IOR", 1.45f);
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-FresnelNode::FresnelNode()
-: ShaderNode(node_type)
+FresnelNode::FresnelNode() : ShaderNode(node_type)
{
}
-void FresnelNode::compile(SVMCompiler& compiler)
+void FresnelNode::compile(SVMCompiler &compiler)
{
- ShaderInput *normal_in = input("Normal");
- ShaderInput *IOR_in = input("IOR");
- ShaderOutput *fac_out = output("Fac");
+ ShaderInput *normal_in = input("Normal");
+ ShaderInput *IOR_in = input("IOR");
+ ShaderOutput *fac_out = output("Fac");
- compiler.add_node(NODE_FRESNEL,
- compiler.stack_assign(IOR_in),
- __float_as_int(IOR),
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(normal_in),
- compiler.stack_assign(fac_out)));
+ compiler.add_node(NODE_FRESNEL,
+ compiler.stack_assign(IOR_in),
+ __float_as_int(IOR),
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(normal_in),
+ compiler.stack_assign(fac_out)));
}
-void FresnelNode::compile(OSLCompiler& compiler)
+void FresnelNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_fresnel");
+ compiler.add(this, "node_fresnel");
}
/* Layer Weight */
NODE_DEFINE(LayerWeightNode)
{
- NodeType* type = NodeType::add("layer_weight", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("layer_weight", create, NodeType::SHADER);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
- SOCKET_IN_FLOAT(blend, "Blend", 0.5f);
+ SOCKET_IN_NORMAL(normal,
+ "Normal",
+ make_float3(0.0f, 0.0f, 0.0f),
+ SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
+ SOCKET_IN_FLOAT(blend, "Blend", 0.5f);
- SOCKET_OUT_FLOAT(fresnel, "Fresnel");
- SOCKET_OUT_FLOAT(facing, "Facing");
+ SOCKET_OUT_FLOAT(fresnel, "Fresnel");
+ SOCKET_OUT_FLOAT(facing, "Facing");
- return type;
+ return type;
}
-LayerWeightNode::LayerWeightNode()
-: ShaderNode(node_type)
+LayerWeightNode::LayerWeightNode() : ShaderNode(node_type)
{
}
-void LayerWeightNode::compile(SVMCompiler& compiler)
+void LayerWeightNode::compile(SVMCompiler &compiler)
{
- ShaderInput *normal_in = input("Normal");
- ShaderInput *blend_in = input("Blend");
- ShaderOutput *fresnel_out = output("Fresnel");
- ShaderOutput *facing_out = output("Facing");
+ ShaderInput *normal_in = input("Normal");
+ ShaderInput *blend_in = input("Blend");
+ ShaderOutput *fresnel_out = output("Fresnel");
+ ShaderOutput *facing_out = output("Facing");
- if(!fresnel_out->links.empty()) {
- compiler.add_node(NODE_LAYER_WEIGHT,
- compiler.stack_assign_if_linked(blend_in),
- __float_as_int(blend),
- compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL,
- compiler.stack_assign_if_linked(normal_in),
- compiler.stack_assign(fresnel_out)));
- }
+ if (!fresnel_out->links.empty()) {
+ compiler.add_node(NODE_LAYER_WEIGHT,
+ compiler.stack_assign_if_linked(blend_in),
+ __float_as_int(blend),
+ compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL,
+ compiler.stack_assign_if_linked(normal_in),
+ compiler.stack_assign(fresnel_out)));
+ }
- if(!facing_out->links.empty()) {
- compiler.add_node(NODE_LAYER_WEIGHT,
- compiler.stack_assign_if_linked(blend_in),
- __float_as_int(blend),
- compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING,
- compiler.stack_assign_if_linked(normal_in),
- compiler.stack_assign(facing_out)));
- }
+ if (!facing_out->links.empty()) {
+ compiler.add_node(NODE_LAYER_WEIGHT,
+ compiler.stack_assign_if_linked(blend_in),
+ __float_as_int(blend),
+ compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING,
+ compiler.stack_assign_if_linked(normal_in),
+ compiler.stack_assign(facing_out)));
+ }
}
-void LayerWeightNode::compile(OSLCompiler& compiler)
+void LayerWeightNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_layer_weight");
+ compiler.add(this, "node_layer_weight");
}
/* Wireframe */
NODE_DEFINE(WireframeNode)
{
- NodeType* type = NodeType::add("wireframe", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("wireframe", create, NodeType::SHADER);
- SOCKET_BOOLEAN(use_pixel_size, "Use Pixel Size", false);
- SOCKET_IN_FLOAT(size, "Size", 0.01f);
- SOCKET_OUT_FLOAT(fac, "Fac");
+ SOCKET_BOOLEAN(use_pixel_size, "Use Pixel Size", false);
+ SOCKET_IN_FLOAT(size, "Size", 0.01f);
+ SOCKET_OUT_FLOAT(fac, "Fac");
- return type;
+ return type;
}
-WireframeNode::WireframeNode()
-: ShaderNode(node_type)
+WireframeNode::WireframeNode() : ShaderNode(node_type)
{
}
-void WireframeNode::compile(SVMCompiler& compiler)
+void WireframeNode::compile(SVMCompiler &compiler)
{
- ShaderInput *size_in = input("Size");
- ShaderOutput *fac_out = output("Fac");
- NodeBumpOffset bump_offset = NODE_BUMP_OFFSET_CENTER;
- if(bump == SHADER_BUMP_DX) {
- bump_offset = NODE_BUMP_OFFSET_DX;
- }
- else if(bump == SHADER_BUMP_DY) {
- bump_offset = NODE_BUMP_OFFSET_DY;
- }
- compiler.add_node(NODE_WIREFRAME,
- compiler.stack_assign(size_in),
- compiler.stack_assign(fac_out),
- compiler.encode_uchar4(use_pixel_size,
- bump_offset,
- 0, 0));
+ ShaderInput *size_in = input("Size");
+ ShaderOutput *fac_out = output("Fac");
+ NodeBumpOffset bump_offset = NODE_BUMP_OFFSET_CENTER;
+ if (bump == SHADER_BUMP_DX) {
+ bump_offset = NODE_BUMP_OFFSET_DX;
+ }
+ else if (bump == SHADER_BUMP_DY) {
+ bump_offset = NODE_BUMP_OFFSET_DY;
+ }
+ compiler.add_node(NODE_WIREFRAME,
+ compiler.stack_assign(size_in),
+ compiler.stack_assign(fac_out),
+ compiler.encode_uchar4(use_pixel_size, bump_offset, 0, 0));
}
-void WireframeNode::compile(OSLCompiler& compiler)
+void WireframeNode::compile(OSLCompiler &compiler)
{
- if(bump == SHADER_BUMP_DX) {
- compiler.parameter("bump_offset", "dx");
- }
- else if(bump == SHADER_BUMP_DY) {
- compiler.parameter("bump_offset", "dy");
- }
- else {
- compiler.parameter("bump_offset", "center");
- }
- compiler.parameter(this, "use_pixel_size");
- compiler.add(this, "node_wireframe");
+ if (bump == SHADER_BUMP_DX) {
+ compiler.parameter("bump_offset", "dx");
+ }
+ else if (bump == SHADER_BUMP_DY) {
+ compiler.parameter("bump_offset", "dy");
+ }
+ else {
+ compiler.parameter("bump_offset", "center");
+ }
+ compiler.parameter(this, "use_pixel_size");
+ compiler.add(this, "node_wireframe");
}
/* Wavelength */
NODE_DEFINE(WavelengthNode)
{
- NodeType* type = NodeType::add("wavelength", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("wavelength", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(wavelength, "Wavelength", 500.0f);
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_IN_FLOAT(wavelength, "Wavelength", 500.0f);
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-WavelengthNode::WavelengthNode()
-: ShaderNode(node_type)
+WavelengthNode::WavelengthNode() : ShaderNode(node_type)
{
}
-void WavelengthNode::compile(SVMCompiler& compiler)
+void WavelengthNode::compile(SVMCompiler &compiler)
{
- ShaderInput *wavelength_in = input("Wavelength");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *wavelength_in = input("Wavelength");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_WAVELENGTH,
- compiler.stack_assign(wavelength_in),
- compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_WAVELENGTH, compiler.stack_assign(wavelength_in), compiler.stack_assign(color_out));
}
-void WavelengthNode::compile(OSLCompiler& compiler)
+void WavelengthNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_wavelength");
+ compiler.add(this, "node_wavelength");
}
/* Blackbody */
NODE_DEFINE(BlackbodyNode)
{
- NodeType* type = NodeType::add("blackbody", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("blackbody", create, NodeType::SHADER);
- SOCKET_IN_FLOAT(temperature, "Temperature", 1200.0f);
- SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_IN_FLOAT(temperature, "Temperature", 1200.0f);
+ SOCKET_OUT_COLOR(color, "Color");
- return type;
+ return type;
}
-BlackbodyNode::BlackbodyNode()
-: ShaderNode(node_type)
+BlackbodyNode::BlackbodyNode() : ShaderNode(node_type)
{
}
-void BlackbodyNode::constant_fold(const ConstantFolder& folder)
+void BlackbodyNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant(svm_math_blackbody_color(temperature));
- }
+ if (folder.all_inputs_constant()) {
+ folder.make_constant(svm_math_blackbody_color(temperature));
+ }
}
-void BlackbodyNode::compile(SVMCompiler& compiler)
+void BlackbodyNode::compile(SVMCompiler &compiler)
{
- ShaderInput *temperature_in = input("Temperature");
- ShaderOutput *color_out = output("Color");
+ ShaderInput *temperature_in = input("Temperature");
+ ShaderOutput *color_out = output("Color");
- compiler.add_node(NODE_BLACKBODY,
- compiler.stack_assign(temperature_in),
- compiler.stack_assign(color_out));
+ compiler.add_node(
+ NODE_BLACKBODY, compiler.stack_assign(temperature_in), compiler.stack_assign(color_out));
}
-void BlackbodyNode::compile(OSLCompiler& compiler)
+void BlackbodyNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_blackbody");
+ compiler.add(this, "node_blackbody");
}
/* Output */
NODE_DEFINE(OutputNode)
{
- NodeType* type = NodeType::add("output", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("output", create, NodeType::SHADER);
- SOCKET_IN_CLOSURE(surface, "Surface");
- SOCKET_IN_CLOSURE(volume, "Volume");
- SOCKET_IN_VECTOR(displacement, "Displacement", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_CLOSURE(surface, "Surface");
+ SOCKET_IN_CLOSURE(volume, "Volume");
+ SOCKET_IN_VECTOR(displacement, "Displacement", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f));
- return type;
+ return type;
}
-OutputNode::OutputNode()
-: ShaderNode(node_type)
+OutputNode::OutputNode() : ShaderNode(node_type)
{
- special_type = SHADER_SPECIAL_TYPE_OUTPUT;
+ special_type = SHADER_SPECIAL_TYPE_OUTPUT;
}
-void OutputNode::compile(SVMCompiler& compiler)
+void OutputNode::compile(SVMCompiler &compiler)
{
- if(compiler.output_type() == SHADER_TYPE_DISPLACEMENT) {
- ShaderInput *displacement_in = input("Displacement");
+ if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT) {
+ ShaderInput *displacement_in = input("Displacement");
- if(displacement_in->link) {
- compiler.add_node(NODE_SET_DISPLACEMENT, compiler.stack_assign(displacement_in));
- }
- }
+ if (displacement_in->link) {
+ compiler.add_node(NODE_SET_DISPLACEMENT, compiler.stack_assign(displacement_in));
+ }
+ }
}
-void OutputNode::compile(OSLCompiler& compiler)
+void OutputNode::compile(OSLCompiler &compiler)
{
- if(compiler.output_type() == SHADER_TYPE_SURFACE)
- compiler.add(this, "node_output_surface");
- else if(compiler.output_type() == SHADER_TYPE_VOLUME)
- compiler.add(this, "node_output_volume");
- else if(compiler.output_type() == SHADER_TYPE_DISPLACEMENT)
- compiler.add(this, "node_output_displacement");
+ if (compiler.output_type() == SHADER_TYPE_SURFACE)
+ compiler.add(this, "node_output_surface");
+ else if (compiler.output_type() == SHADER_TYPE_VOLUME)
+ compiler.add(this, "node_output_volume");
+ else if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT)
+ compiler.add(this, "node_output_displacement");
}
/* Math */
NODE_DEFINE(MathNode)
{
- NodeType* type = NodeType::add("math", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("math", create, NodeType::SHADER);
- static NodeEnum type_enum;
- type_enum.insert("add", NODE_MATH_ADD);
- type_enum.insert("subtract", NODE_MATH_SUBTRACT);
- type_enum.insert("multiply", NODE_MATH_MULTIPLY);
- type_enum.insert("divide", NODE_MATH_DIVIDE);
- type_enum.insert("sine", NODE_MATH_SINE);
- type_enum.insert("cosine", NODE_MATH_COSINE);
- type_enum.insert("tangent", NODE_MATH_TANGENT);
- type_enum.insert("arcsine", NODE_MATH_ARCSINE);
- type_enum.insert("arccosine", NODE_MATH_ARCCOSINE);
- type_enum.insert("arctangent", NODE_MATH_ARCTANGENT);
- type_enum.insert("power", NODE_MATH_POWER);
- type_enum.insert("logarithm", NODE_MATH_LOGARITHM);
- type_enum.insert("minimum", NODE_MATH_MINIMUM);
- type_enum.insert("maximum", NODE_MATH_MAXIMUM);
- type_enum.insert("round", NODE_MATH_ROUND);
- type_enum.insert("less_than", NODE_MATH_LESS_THAN);
- type_enum.insert("greater_than", NODE_MATH_GREATER_THAN);
- type_enum.insert("modulo", NODE_MATH_MODULO);
- type_enum.insert("absolute", NODE_MATH_ABSOLUTE);
- type_enum.insert("arctan2", NODE_MATH_ARCTAN2);
- type_enum.insert("floor", NODE_MATH_FLOOR);
- type_enum.insert("ceil", NODE_MATH_CEIL);
- type_enum.insert("fract", NODE_MATH_FRACT);
- type_enum.insert("sqrt", NODE_MATH_SQRT);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD);
+ static NodeEnum type_enum;
+ type_enum.insert("add", NODE_MATH_ADD);
+ type_enum.insert("subtract", NODE_MATH_SUBTRACT);
+ type_enum.insert("multiply", NODE_MATH_MULTIPLY);
+ type_enum.insert("divide", NODE_MATH_DIVIDE);
+ type_enum.insert("sine", NODE_MATH_SINE);
+ type_enum.insert("cosine", NODE_MATH_COSINE);
+ type_enum.insert("tangent", NODE_MATH_TANGENT);
+ type_enum.insert("arcsine", NODE_MATH_ARCSINE);
+ type_enum.insert("arccosine", NODE_MATH_ARCCOSINE);
+ type_enum.insert("arctangent", NODE_MATH_ARCTANGENT);
+ type_enum.insert("power", NODE_MATH_POWER);
+ type_enum.insert("logarithm", NODE_MATH_LOGARITHM);
+ type_enum.insert("minimum", NODE_MATH_MINIMUM);
+ type_enum.insert("maximum", NODE_MATH_MAXIMUM);
+ type_enum.insert("round", NODE_MATH_ROUND);
+ type_enum.insert("less_than", NODE_MATH_LESS_THAN);
+ type_enum.insert("greater_than", NODE_MATH_GREATER_THAN);
+ type_enum.insert("modulo", NODE_MATH_MODULO);
+ type_enum.insert("absolute", NODE_MATH_ABSOLUTE);
+ type_enum.insert("arctan2", NODE_MATH_ARCTAN2);
+ type_enum.insert("floor", NODE_MATH_FLOOR);
+ type_enum.insert("ceil", NODE_MATH_CEIL);
+ type_enum.insert("fract", NODE_MATH_FRACT);
+ type_enum.insert("sqrt", NODE_MATH_SQRT);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD);
- SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
+ SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
- SOCKET_IN_FLOAT(value1, "Value1", 0.0f);
- SOCKET_IN_FLOAT(value2, "Value2", 0.0f);
+ SOCKET_IN_FLOAT(value1, "Value1", 0.0f);
+ SOCKET_IN_FLOAT(value2, "Value2", 0.0f);
- SOCKET_OUT_FLOAT(value, "Value");
+ SOCKET_OUT_FLOAT(value, "Value");
- return type;
+ return type;
}
-MathNode::MathNode()
-: ShaderNode(node_type)
+MathNode::MathNode() : ShaderNode(node_type)
{
}
-void MathNode::constant_fold(const ConstantFolder& folder)
+void MathNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- folder.make_constant_clamp(svm_math(type, value1, value2), use_clamp);
- }
- else {
- folder.fold_math(type, use_clamp);
- }
+ if (folder.all_inputs_constant()) {
+ folder.make_constant_clamp(svm_math(type, value1, value2), use_clamp);
+ }
+ else {
+ folder.fold_math(type, use_clamp);
+ }
}
-void MathNode::compile(SVMCompiler& compiler)
+void MathNode::compile(SVMCompiler &compiler)
{
- ShaderInput *value1_in = input("Value1");
- ShaderInput *value2_in = input("Value2");
- ShaderOutput *value_out = output("Value");
+ ShaderInput *value1_in = input("Value1");
+ ShaderInput *value2_in = input("Value2");
+ ShaderOutput *value_out = output("Value");
- compiler.add_node(NODE_MATH, type, compiler.stack_assign(value1_in), compiler.stack_assign(value2_in));
- compiler.add_node(NODE_MATH, compiler.stack_assign(value_out));
+ compiler.add_node(
+ NODE_MATH, type, compiler.stack_assign(value1_in), compiler.stack_assign(value2_in));
+ compiler.add_node(NODE_MATH, compiler.stack_assign(value_out));
- if(use_clamp) {
- compiler.add_node(NODE_MATH, NODE_MATH_CLAMP, compiler.stack_assign(value_out));
- compiler.add_node(NODE_MATH, compiler.stack_assign(value_out));
- }
+ if (use_clamp) {
+ compiler.add_node(NODE_MATH, NODE_MATH_CLAMP, compiler.stack_assign(value_out));
+ compiler.add_node(NODE_MATH, compiler.stack_assign(value_out));
+ }
}
-void MathNode::compile(OSLCompiler& compiler)
+void MathNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "type");
- compiler.parameter(this, "use_clamp");
- compiler.add(this, "node_math");
+ compiler.parameter(this, "type");
+ compiler.parameter(this, "use_clamp");
+ compiler.add(this, "node_math");
}
/* VectorMath */
NODE_DEFINE(VectorMathNode)
{
- NodeType* type = NodeType::add("vector_math", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("vector_math", create, NodeType::SHADER);
- static NodeEnum type_enum;
- type_enum.insert("add", NODE_VECTOR_MATH_ADD);
- type_enum.insert("subtract", NODE_VECTOR_MATH_SUBTRACT);
- type_enum.insert("average", NODE_VECTOR_MATH_AVERAGE);
- type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT);
- type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT);
- type_enum.insert("normalize", NODE_VECTOR_MATH_NORMALIZE);
- SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_MATH_ADD);
+ static NodeEnum type_enum;
+ type_enum.insert("add", NODE_VECTOR_MATH_ADD);
+ type_enum.insert("subtract", NODE_VECTOR_MATH_SUBTRACT);
+ type_enum.insert("average", NODE_VECTOR_MATH_AVERAGE);
+ type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT);
+ type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT);
+ type_enum.insert("normalize", NODE_VECTOR_MATH_NORMALIZE);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_MATH_ADD);
- SOCKET_IN_VECTOR(vector1, "Vector1", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_VECTOR(vector2, "Vector2", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_VECTOR(vector1, "Vector1", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_VECTOR(vector2, "Vector2", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_FLOAT(value, "Value");
- SOCKET_OUT_VECTOR(vector, "Vector");
+ SOCKET_OUT_FLOAT(value, "Value");
+ SOCKET_OUT_VECTOR(vector, "Vector");
- return type;
+ return type;
}
-VectorMathNode::VectorMathNode()
-: ShaderNode(node_type)
+VectorMathNode::VectorMathNode() : ShaderNode(node_type)
{
}
-void VectorMathNode::constant_fold(const ConstantFolder& folder)
+void VectorMathNode::constant_fold(const ConstantFolder &folder)
{
- float value;
- float3 vector;
+ float value;
+ float3 vector;
- if(folder.all_inputs_constant()) {
- svm_vector_math(&value,
- &vector,
- type,
- vector1,
- vector2);
+ if (folder.all_inputs_constant()) {
+ svm_vector_math(&value, &vector, type, vector1, vector2);
- if(folder.output == output("Value")) {
- folder.make_constant(value);
- }
- else if(folder.output == output("Vector")) {
- folder.make_constant(vector);
- }
- }
- else {
- folder.fold_vector_math(type);
- }
+ if (folder.output == output("Value")) {
+ folder.make_constant(value);
+ }
+ else if (folder.output == output("Vector")) {
+ folder.make_constant(vector);
+ }
+ }
+ else {
+ folder.fold_vector_math(type);
+ }
}
-void VectorMathNode::compile(SVMCompiler& compiler)
+void VectorMathNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector1_in = input("Vector1");
- ShaderInput *vector2_in = input("Vector2");
- ShaderOutput *value_out = output("Value");
- ShaderOutput *vector_out = output("Vector");
+ ShaderInput *vector1_in = input("Vector1");
+ ShaderInput *vector2_in = input("Vector2");
+ ShaderOutput *value_out = output("Value");
+ ShaderOutput *vector_out = output("Vector");
- compiler.add_node(NODE_VECTOR_MATH,
- type,
- compiler.stack_assign(vector1_in),
- compiler.stack_assign(vector2_in));
- compiler.add_node(NODE_VECTOR_MATH,
- compiler.stack_assign(value_out),
- compiler.stack_assign(vector_out));
+ compiler.add_node(NODE_VECTOR_MATH,
+ type,
+ compiler.stack_assign(vector1_in),
+ compiler.stack_assign(vector2_in));
+ compiler.add_node(
+ NODE_VECTOR_MATH, compiler.stack_assign(value_out), compiler.stack_assign(vector_out));
}
-void VectorMathNode::compile(OSLCompiler& compiler)
+void VectorMathNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "type");
- compiler.add(this, "node_vector_math");
+ compiler.parameter(this, "type");
+ compiler.add(this, "node_vector_math");
}
/* VectorTransform */
NODE_DEFINE(VectorTransformNode)
{
- NodeType* type = NodeType::add("vector_transform", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("vector_transform", create, NodeType::SHADER);
- static NodeEnum type_enum;
- type_enum.insert("vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
- type_enum.insert("point", NODE_VECTOR_TRANSFORM_TYPE_POINT);
- type_enum.insert("normal", NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
- SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
+ static NodeEnum type_enum;
+ type_enum.insert("vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
+ type_enum.insert("point", NODE_VECTOR_TRANSFORM_TYPE_POINT);
+ type_enum.insert("normal", NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
- static NodeEnum space_enum;
- space_enum.insert("world", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD);
- space_enum.insert("object", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT);
- space_enum.insert("camera", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA);
- SOCKET_ENUM(convert_from, "Convert From", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD);
- SOCKET_ENUM(convert_to, "Convert To", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT);
+ static NodeEnum space_enum;
+ space_enum.insert("world", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD);
+ space_enum.insert("object", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT);
+ space_enum.insert("camera", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA);
+ SOCKET_ENUM(convert_from, "Convert From", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD);
+ SOCKET_ENUM(convert_to, "Convert To", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT);
- SOCKET_IN_VECTOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_VECTOR(vector, "Vector");
+ SOCKET_IN_VECTOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_OUT_VECTOR(vector, "Vector");
- return type;
+ return type;
}
-VectorTransformNode::VectorTransformNode()
-: ShaderNode(node_type)
+VectorTransformNode::VectorTransformNode() : ShaderNode(node_type)
{
}
-void VectorTransformNode::compile(SVMCompiler& compiler)
+void VectorTransformNode::compile(SVMCompiler &compiler)
{
- ShaderInput *vector_in = input("Vector");
- ShaderOutput *vector_out = output("Vector");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *vector_out = output("Vector");
- compiler.add_node(NODE_VECTOR_TRANSFORM,
- compiler.encode_uchar4(type, convert_from, convert_to),
- compiler.encode_uchar4(compiler.stack_assign(vector_in),
- compiler.stack_assign(vector_out)));
+ compiler.add_node(
+ NODE_VECTOR_TRANSFORM,
+ compiler.encode_uchar4(type, convert_from, convert_to),
+ compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign(vector_out)));
}
-void VectorTransformNode::compile(OSLCompiler& compiler)
+void VectorTransformNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "type");
- compiler.parameter(this, "convert_from");
- compiler.parameter(this, "convert_to");
- compiler.add(this, "node_vector_transform");
+ compiler.parameter(this, "type");
+ compiler.parameter(this, "convert_from");
+ compiler.parameter(this, "convert_to");
+ compiler.add(this, "node_vector_transform");
}
/* BumpNode */
NODE_DEFINE(BumpNode)
{
- NodeType* type = NodeType::add("bump", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("bump", create, NodeType::SHADER);
- SOCKET_BOOLEAN(invert, "Invert", false);
- SOCKET_BOOLEAN(use_object_space, "UseObjectSpace", false);
+ SOCKET_BOOLEAN(invert, "Invert", false);
+ SOCKET_BOOLEAN(use_object_space, "UseObjectSpace", false);
- /* this input is used by the user, but after graph transform it is no longer
- * used and moved to sampler center/x/y instead */
- SOCKET_IN_FLOAT(height, "Height", 1.0f);
+ /* this input is used by the user, but after graph transform it is no longer
+ * used and moved to sampler center/x/y instead */
+ SOCKET_IN_FLOAT(height, "Height", 1.0f);
- SOCKET_IN_FLOAT(sample_center, "SampleCenter", 0.0f);
- SOCKET_IN_FLOAT(sample_x, "SampleX", 0.0f);
- SOCKET_IN_FLOAT(sample_y, "SampleY", 0.0f);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
- SOCKET_IN_FLOAT(distance, "Distance", 0.1f);
+ SOCKET_IN_FLOAT(sample_center, "SampleCenter", 0.0f);
+ SOCKET_IN_FLOAT(sample_x, "SampleX", 0.0f);
+ SOCKET_IN_FLOAT(sample_y, "SampleY", 0.0f);
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
+ SOCKET_IN_FLOAT(distance, "Distance", 0.1f);
- SOCKET_OUT_NORMAL(normal, "Normal");
+ SOCKET_OUT_NORMAL(normal, "Normal");
- return type;
+ return type;
}
-BumpNode::BumpNode()
-: ShaderNode(node_type)
+BumpNode::BumpNode() : ShaderNode(node_type)
{
- special_type = SHADER_SPECIAL_TYPE_BUMP;
+ special_type = SHADER_SPECIAL_TYPE_BUMP;
}
-void BumpNode::compile(SVMCompiler& compiler)
+void BumpNode::compile(SVMCompiler &compiler)
{
- ShaderInput *center_in = input("SampleCenter");
- ShaderInput *dx_in = input("SampleX");
- ShaderInput *dy_in = input("SampleY");
- ShaderInput *normal_in = input("Normal");
- ShaderInput *strength_in = input("Strength");
- ShaderInput *distance_in = input("Distance");
- ShaderOutput *normal_out = output("Normal");
+ ShaderInput *center_in = input("SampleCenter");
+ ShaderInput *dx_in = input("SampleX");
+ ShaderInput *dy_in = input("SampleY");
+ ShaderInput *normal_in = input("Normal");
+ ShaderInput *strength_in = input("Strength");
+ ShaderInput *distance_in = input("Distance");
+ ShaderOutput *normal_out = output("Normal");
- /* pack all parameters in the node */
- compiler.add_node(NODE_SET_BUMP,
- compiler.encode_uchar4(
- compiler.stack_assign_if_linked(normal_in),
- compiler.stack_assign(distance_in),
- invert,
- use_object_space),
- compiler.encode_uchar4(
- compiler.stack_assign(center_in),
- compiler.stack_assign(dx_in),
- compiler.stack_assign(dy_in),
- compiler.stack_assign(strength_in)),
- compiler.stack_assign(normal_out));
+ /* pack all parameters in the node */
+ compiler.add_node(NODE_SET_BUMP,
+ compiler.encode_uchar4(compiler.stack_assign_if_linked(normal_in),
+ compiler.stack_assign(distance_in),
+ invert,
+ use_object_space),
+ compiler.encode_uchar4(compiler.stack_assign(center_in),
+ compiler.stack_assign(dx_in),
+ compiler.stack_assign(dy_in),
+ compiler.stack_assign(strength_in)),
+ compiler.stack_assign(normal_out));
}
-void BumpNode::compile(OSLCompiler& compiler)
+void BumpNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "invert");
- compiler.parameter(this, "use_object_space");
- compiler.add(this, "node_bump");
+ compiler.parameter(this, "invert");
+ compiler.parameter(this, "use_object_space");
+ compiler.add(this, "node_bump");
}
-void BumpNode::constant_fold(const ConstantFolder& folder)
+void BumpNode::constant_fold(const ConstantFolder &folder)
{
- ShaderInput *height_in = input("Height");
- ShaderInput *normal_in = input("Normal");
+ ShaderInput *height_in = input("Height");
+ ShaderInput *normal_in = input("Normal");
- if(height_in->link == NULL) {
- if(normal_in->link == NULL) {
- GeometryNode *geom = new GeometryNode();
- folder.graph->add(geom);
- folder.bypass(geom->output("Normal"));
- }
- else {
- folder.bypass(normal_in->link);
- }
- }
+ if (height_in->link == NULL) {
+ if (normal_in->link == NULL) {
+ GeometryNode *geom = new GeometryNode();
+ folder.graph->add(geom);
+ folder.bypass(geom->output("Normal"));
+ }
+ else {
+ folder.bypass(normal_in->link);
+ }
+ }
- /* TODO(sergey): Ignore bump with zero strength. */
+ /* TODO(sergey): Ignore bump with zero strength. */
}
-
/* Curve node */
-CurvesNode::CurvesNode(const NodeType *node_type)
-: ShaderNode(node_type)
+CurvesNode::CurvesNode(const NodeType *node_type) : ShaderNode(node_type)
{
}
-void CurvesNode::constant_fold(const ConstantFolder& folder, ShaderInput *value_in)
+void CurvesNode::constant_fold(const ConstantFolder &folder, ShaderInput *value_in)
{
- ShaderInput *fac_in = input("Fac");
+ ShaderInput *fac_in = input("Fac");
- /* evaluate fully constant node */
- if(folder.all_inputs_constant()) {
- if(curves.size() == 0) {
- return;
- }
+ /* evaluate fully constant node */
+ if (folder.all_inputs_constant()) {
+ if (curves.size() == 0) {
+ return;
+ }
- float3 pos = (value - make_float3(min_x, min_x, min_x)) / (max_x - min_x);
- float3 result;
+ float3 pos = (value - make_float3(min_x, min_x, min_x)) / (max_x - min_x);
+ float3 result;
- result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, true, curves.size()).x;
- result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, true, curves.size()).y;
- result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, true, curves.size()).z;
+ result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, true, curves.size()).x;
+ result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, true, curves.size()).y;
+ result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, true, curves.size()).z;
- folder.make_constant(interp(value, result, fac));
- }
- /* remove no-op node */
- else if(!fac_in->link && fac == 0.0f) {
- /* link is not null because otherwise all inputs are constant */
- folder.bypass(value_in->link);
- }
+ folder.make_constant(interp(value, result, fac));
+ }
+ /* remove no-op node */
+ else if (!fac_in->link && fac == 0.0f) {
+ /* link is not null because otherwise all inputs are constant */
+ folder.bypass(value_in->link);
+ }
}
-void CurvesNode::compile(SVMCompiler& compiler, int type, ShaderInput *value_in, ShaderOutput *value_out)
+void CurvesNode::compile(SVMCompiler &compiler,
+ int type,
+ ShaderInput *value_in,
+ ShaderOutput *value_out)
{
- if(curves.size() == 0)
- return;
+ if (curves.size() == 0)
+ return;
- ShaderInput *fac_in = input("Fac");
+ ShaderInput *fac_in = input("Fac");
- compiler.add_node(type,
- compiler.encode_uchar4(compiler.stack_assign(fac_in),
- compiler.stack_assign(value_in),
- compiler.stack_assign(value_out)),
- __float_as_int(min_x),
- __float_as_int(max_x));
+ compiler.add_node(type,
+ compiler.encode_uchar4(compiler.stack_assign(fac_in),
+ compiler.stack_assign(value_in),
+ compiler.stack_assign(value_out)),
+ __float_as_int(min_x),
+ __float_as_int(max_x));
- compiler.add_node(curves.size());
- for(int i = 0; i < curves.size(); i++)
- compiler.add_node(float3_to_float4(curves[i]));
+ compiler.add_node(curves.size());
+ for (int i = 0; i < curves.size(); i++)
+ compiler.add_node(float3_to_float4(curves[i]));
}
-void CurvesNode::compile(OSLCompiler& compiler, const char* name)
+void CurvesNode::compile(OSLCompiler &compiler, const char *name)
{
- if(curves.size() == 0)
- return;
+ if (curves.size() == 0)
+ return;
- compiler.parameter_color_array("ramp", curves);
- compiler.parameter(this, "min_x");
- compiler.parameter(this, "max_x");
- compiler.add(this, name);
+ compiler.parameter_color_array("ramp", curves);
+ compiler.parameter(this, "min_x");
+ compiler.parameter(this, "max_x");
+ compiler.add(this, name);
}
-void CurvesNode::compile(SVMCompiler& /*compiler*/)
+void CurvesNode::compile(SVMCompiler & /*compiler*/)
{
- assert(0);
+ assert(0);
}
-void CurvesNode::compile(OSLCompiler& /*compiler*/)
+void CurvesNode::compile(OSLCompiler & /*compiler*/)
{
- assert(0);
+ assert(0);
}
/* RGBCurvesNode */
NODE_DEFINE(RGBCurvesNode)
{
- NodeType* type = NodeType::add("rgb_curves", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("rgb_curves", create, NodeType::SHADER);
- SOCKET_COLOR_ARRAY(curves, "Curves", array<float3>());
- SOCKET_FLOAT(min_x, "Min X", 0.0f);
- SOCKET_FLOAT(max_x, "Max X", 1.0f);
+ SOCKET_COLOR_ARRAY(curves, "Curves", array<float3>());
+ SOCKET_FLOAT(min_x, "Min X", 0.0f);
+ SOCKET_FLOAT(max_x, "Max X", 1.0f);
- SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
- SOCKET_IN_COLOR(value, "Color", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
+ SOCKET_IN_COLOR(value, "Color", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_COLOR(value, "Color");
+ SOCKET_OUT_COLOR(value, "Color");
- return type;
+ return type;
}
-RGBCurvesNode::RGBCurvesNode()
-: CurvesNode(node_type)
+RGBCurvesNode::RGBCurvesNode() : CurvesNode(node_type)
{
}
-void RGBCurvesNode::constant_fold(const ConstantFolder& folder)
+void RGBCurvesNode::constant_fold(const ConstantFolder &folder)
{
- CurvesNode::constant_fold(folder, input("Color"));
+ CurvesNode::constant_fold(folder, input("Color"));
}
-void RGBCurvesNode::compile(SVMCompiler& compiler)
+void RGBCurvesNode::compile(SVMCompiler &compiler)
{
- CurvesNode::compile(compiler, NODE_RGB_CURVES, input("Color"), output("Color"));
+ CurvesNode::compile(compiler, NODE_RGB_CURVES, input("Color"), output("Color"));
}
-void RGBCurvesNode::compile(OSLCompiler& compiler)
+void RGBCurvesNode::compile(OSLCompiler &compiler)
{
- CurvesNode::compile(compiler, "node_rgb_curves");
+ CurvesNode::compile(compiler, "node_rgb_curves");
}
/* VectorCurvesNode */
NODE_DEFINE(VectorCurvesNode)
{
- NodeType* type = NodeType::add("vector_curves", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("vector_curves", create, NodeType::SHADER);
- SOCKET_VECTOR_ARRAY(curves, "Curves", array<float3>());
- SOCKET_FLOAT(min_x, "Min X", 0.0f);
- SOCKET_FLOAT(max_x, "Max X", 1.0f);
+ SOCKET_VECTOR_ARRAY(curves, "Curves", array<float3>());
+ SOCKET_FLOAT(min_x, "Min X", 0.0f);
+ SOCKET_FLOAT(max_x, "Max X", 1.0f);
- SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
- SOCKET_IN_VECTOR(value, "Vector", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
+ SOCKET_IN_VECTOR(value, "Vector", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_VECTOR(value, "Vector");
+ SOCKET_OUT_VECTOR(value, "Vector");
- return type;
+ return type;
}
-VectorCurvesNode::VectorCurvesNode()
-: CurvesNode(node_type)
+VectorCurvesNode::VectorCurvesNode() : CurvesNode(node_type)
{
}
-void VectorCurvesNode::constant_fold(const ConstantFolder& folder)
+void VectorCurvesNode::constant_fold(const ConstantFolder &folder)
{
- CurvesNode::constant_fold(folder, input("Vector"));
+ CurvesNode::constant_fold(folder, input("Vector"));
}
-void VectorCurvesNode::compile(SVMCompiler& compiler)
+void VectorCurvesNode::compile(SVMCompiler &compiler)
{
- CurvesNode::compile(compiler, NODE_VECTOR_CURVES, input("Vector"), output("Vector"));
+ CurvesNode::compile(compiler, NODE_VECTOR_CURVES, input("Vector"), output("Vector"));
}
-void VectorCurvesNode::compile(OSLCompiler& compiler)
+void VectorCurvesNode::compile(OSLCompiler &compiler)
{
- CurvesNode::compile(compiler, "node_vector_curves");
+ CurvesNode::compile(compiler, "node_vector_curves");
}
/* RGBRampNode */
NODE_DEFINE(RGBRampNode)
{
- NodeType* type = NodeType::add("rgb_ramp", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("rgb_ramp", create, NodeType::SHADER);
- SOCKET_COLOR_ARRAY(ramp, "Ramp", array<float3>());
- SOCKET_FLOAT_ARRAY(ramp_alpha, "Ramp Alpha", array<float>());
- SOCKET_BOOLEAN(interpolate, "Interpolate", true);
+ SOCKET_COLOR_ARRAY(ramp, "Ramp", array<float3>());
+ SOCKET_FLOAT_ARRAY(ramp_alpha, "Ramp Alpha", array<float>());
+ SOCKET_BOOLEAN(interpolate, "Interpolate", true);
- SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
+ SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
- SOCKET_OUT_COLOR(color, "Color");
- SOCKET_OUT_FLOAT(alpha, "Alpha");
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(alpha, "Alpha");
- return type;
+ return type;
}
-RGBRampNode::RGBRampNode()
-: ShaderNode(node_type)
+RGBRampNode::RGBRampNode() : ShaderNode(node_type)
{
}
-void RGBRampNode::constant_fold(const ConstantFolder& folder)
+void RGBRampNode::constant_fold(const ConstantFolder &folder)
{
- if(ramp.size() == 0 || ramp.size() != ramp_alpha.size())
- return;
+ if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
+ return;
- if(folder.all_inputs_constant()) {
- float f = clamp(fac, 0.0f, 1.0f) * (ramp.size() - 1);
+ if (folder.all_inputs_constant()) {
+ float f = clamp(fac, 0.0f, 1.0f) * (ramp.size() - 1);
- /* clamp int as well in case of NaN */
- int i = clamp((int)f, 0, ramp.size()-1);
- float t = f - (float)i;
+ /* clamp int as well in case of NaN */
+ int i = clamp((int)f, 0, ramp.size() - 1);
+ float t = f - (float)i;
- bool use_lerp = interpolate && t > 0.0f;
+ bool use_lerp = interpolate && t > 0.0f;
- if(folder.output == output("Color")) {
- float3 color = rgb_ramp_lookup(ramp.data(), fac, use_lerp, false, ramp.size());
- folder.make_constant(color);
- }
- else if(folder.output == output("Alpha")) {
- float alpha = float_ramp_lookup(ramp_alpha.data(), fac, use_lerp, false, ramp_alpha.size());
- folder.make_constant(alpha);
- }
- }
+ if (folder.output == output("Color")) {
+ float3 color = rgb_ramp_lookup(ramp.data(), fac, use_lerp, false, ramp.size());
+ folder.make_constant(color);
+ }
+ else if (folder.output == output("Alpha")) {
+ float alpha = float_ramp_lookup(ramp_alpha.data(), fac, use_lerp, false, ramp_alpha.size());
+ folder.make_constant(alpha);
+ }
+ }
}
-void RGBRampNode::compile(SVMCompiler& compiler)
+void RGBRampNode::compile(SVMCompiler &compiler)
{
- if(ramp.size() == 0 || ramp.size() != ramp_alpha.size())
- return;
+ if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
+ return;
- ShaderInput *fac_in = input("Fac");
- ShaderOutput *color_out = output("Color");
- ShaderOutput *alpha_out = output("Alpha");
+ ShaderInput *fac_in = input("Fac");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *alpha_out = output("Alpha");
- compiler.add_node(NODE_RGB_RAMP,
- compiler.encode_uchar4(
- compiler.stack_assign(fac_in),
- compiler.stack_assign_if_linked(color_out),
- compiler.stack_assign_if_linked(alpha_out)),
- interpolate);
+ compiler.add_node(NODE_RGB_RAMP,
+ compiler.encode_uchar4(compiler.stack_assign(fac_in),
+ compiler.stack_assign_if_linked(color_out),
+ compiler.stack_assign_if_linked(alpha_out)),
+ interpolate);
- compiler.add_node(ramp.size());
- for(int i = 0; i < ramp.size(); i++)
- compiler.add_node(make_float4(ramp[i].x, ramp[i].y, ramp[i].z, ramp_alpha[i]));
+ compiler.add_node(ramp.size());
+ for (int i = 0; i < ramp.size(); i++)
+ compiler.add_node(make_float4(ramp[i].x, ramp[i].y, ramp[i].z, ramp_alpha[i]));
}
-void RGBRampNode::compile(OSLCompiler& compiler)
+void RGBRampNode::compile(OSLCompiler &compiler)
{
- if(ramp.size() == 0 || ramp.size() != ramp_alpha.size())
- return;
+ if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
+ return;
- compiler.parameter_color_array("ramp_color", ramp);
- compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size());
- compiler.parameter(this, "interpolate");
+ compiler.parameter_color_array("ramp_color", ramp);
+ compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size());
+ compiler.parameter(this, "interpolate");
- compiler.add(this, "node_rgb_ramp");
+ compiler.add(this, "node_rgb_ramp");
}
/* Set Normal Node */
NODE_DEFINE(SetNormalNode)
{
- NodeType* type = NodeType::add("set_normal", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("set_normal", create, NodeType::SHADER);
- SOCKET_IN_VECTOR(direction, "Direction", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_OUT_NORMAL(normal, "Normal");
+ SOCKET_IN_VECTOR(direction, "Direction", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_OUT_NORMAL(normal, "Normal");
- return type;
+ return type;
}
-SetNormalNode::SetNormalNode()
-: ShaderNode(node_type)
+SetNormalNode::SetNormalNode() : ShaderNode(node_type)
{
}
-void SetNormalNode::compile(SVMCompiler& compiler)
+void SetNormalNode::compile(SVMCompiler &compiler)
{
- ShaderInput *direction_in = input("Direction");
- ShaderOutput *normal_out = output("Normal");
+ ShaderInput *direction_in = input("Direction");
+ ShaderOutput *normal_out = output("Normal");
- compiler.add_node(NODE_CLOSURE_SET_NORMAL,
- compiler.stack_assign(direction_in),
- compiler.stack_assign(normal_out));
+ compiler.add_node(NODE_CLOSURE_SET_NORMAL,
+ compiler.stack_assign(direction_in),
+ compiler.stack_assign(normal_out));
}
-void SetNormalNode::compile(OSLCompiler& compiler)
+void SetNormalNode::compile(OSLCompiler &compiler)
{
- compiler.add(this, "node_set_normal");
+ compiler.add(this, "node_set_normal");
}
/* OSLNode */
-OSLNode::OSLNode()
-: ShaderNode(new NodeType(NodeType::SHADER))
+OSLNode::OSLNode() : ShaderNode(new NodeType(NodeType::SHADER))
{
- special_type = SHADER_SPECIAL_TYPE_SCRIPT;
+ special_type = SHADER_SPECIAL_TYPE_SCRIPT;
}
OSLNode::~OSLNode()
{
- delete type;
+ delete type;
}
ShaderNode *OSLNode::clone() const
{
- return OSLNode::create(this->inputs.size(), this);
+ return OSLNode::create(this->inputs.size(), this);
}
-OSLNode* OSLNode::create(size_t num_inputs, const OSLNode *from)
+OSLNode *OSLNode::create(size_t num_inputs, const OSLNode *from)
{
- /* allocate space for the node itself and parameters, aligned to 16 bytes
- * assuming that's the most parameter types need */
- size_t node_size = align_up(sizeof(OSLNode), 16);
- size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
+ /* allocate space for the node itself and parameters, aligned to 16 bytes
+ * assuming that's the most parameter types need */
+ size_t node_size = align_up(sizeof(OSLNode), 16);
+ size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
- char *node_memory = (char*) operator new(node_size + inputs_size);
- memset(node_memory, 0, node_size + inputs_size);
+ char *node_memory = (char *)operator new(node_size + inputs_size);
+ memset(node_memory, 0, node_size + inputs_size);
- if(!from) {
- return new(node_memory) OSLNode();
- }
- else {
- /* copy input default values and node type for cloning */
- memcpy(node_memory + node_size, (char*)from + node_size, inputs_size);
+ if (!from) {
+ return new (node_memory) OSLNode();
+ }
+ else {
+ /* copy input default values and node type for cloning */
+ memcpy(node_memory + node_size, (char *)from + node_size, inputs_size);
- OSLNode *node = new(node_memory) OSLNode(*from);
- node->type = new NodeType(*(from->type));
- return node;
- }
+ OSLNode *node = new (node_memory) OSLNode(*from);
+ node->type = new NodeType(*(from->type));
+ return node;
+ }
}
-char* OSLNode::input_default_value()
+char *OSLNode::input_default_value()
{
- /* pointer to default value storage, which is the same as our actual value */
- size_t num_inputs = type->inputs.size();
- size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
- return (char*)this + align_up(sizeof(OSLNode), 16) + inputs_size;
+ /* pointer to default value storage, which is the same as our actual value */
+ size_t num_inputs = type->inputs.size();
+ size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
+ return (char *)this + align_up(sizeof(OSLNode), 16) + inputs_size;
}
void OSLNode::add_input(ustring name, SocketType::Type socket_type)
{
- char *memory = input_default_value();
- size_t offset = memory - (char*)this;
- const_cast<NodeType*>(type)->register_input(name, name, socket_type, offset, memory, NULL, NULL, SocketType::LINKABLE);
+ char *memory = input_default_value();
+ size_t offset = memory - (char *)this;
+ const_cast<NodeType *>(type)->register_input(
+ name, name, socket_type, offset, memory, NULL, NULL, SocketType::LINKABLE);
}
void OSLNode::add_output(ustring name, SocketType::Type socket_type)
{
- const_cast<NodeType*>(type)->register_output(name, name, socket_type);
+ const_cast<NodeType *>(type)->register_output(name, name, socket_type);
}
-void OSLNode::compile(SVMCompiler&)
+void OSLNode::compile(SVMCompiler &)
{
- /* doesn't work for SVM, obviously ... */
+ /* doesn't work for SVM, obviously ... */
}
-void OSLNode::compile(OSLCompiler& compiler)
+void OSLNode::compile(OSLCompiler &compiler)
{
- if(!filepath.empty())
- compiler.add(this, filepath.c_str(), true);
- else
- compiler.add(this, bytecode_hash.c_str(), false);
+ if (!filepath.empty())
+ compiler.add(this, filepath.c_str(), true);
+ else
+ compiler.add(this, bytecode_hash.c_str(), false);
}
/* Normal Map */
NODE_DEFINE(NormalMapNode)
{
- NodeType* type = NodeType::add("normal_map", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("normal_map", create, NodeType::SHADER);
- static NodeEnum space_enum;
- space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
- space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
- space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
- space_enum.insert("blender_object", NODE_NORMAL_MAP_BLENDER_OBJECT);
- space_enum.insert("blender_world", NODE_NORMAL_MAP_BLENDER_WORLD);
- SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
+ static NodeEnum space_enum;
+ space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
+ space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
+ space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
+ space_enum.insert("blender_object", NODE_NORMAL_MAP_BLENDER_OBJECT);
+ space_enum.insert("blender_world", NODE_NORMAL_MAP_BLENDER_WORLD);
+ SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
- SOCKET_STRING(attribute, "Attribute", ustring());
+ SOCKET_STRING(attribute, "Attribute", ustring());
- SOCKET_IN_NORMAL(normal_osl, "NormalIn", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
- SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 1.0f));
+ SOCKET_IN_NORMAL(normal_osl,
+ "NormalIn",
+ make_float3(0.0f, 0.0f, 0.0f),
+ SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
+ SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 1.0f));
- SOCKET_OUT_NORMAL(normal, "Normal");
+ SOCKET_OUT_NORMAL(normal, "Normal");
- return type;
+ return type;
}
-NormalMapNode::NormalMapNode()
-: ShaderNode(node_type)
+NormalMapNode::NormalMapNode() : ShaderNode(node_type)
{
}
void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
- if(attribute.empty()) {
- attributes->add(ATTR_STD_UV_TANGENT);
- attributes->add(ATTR_STD_UV_TANGENT_SIGN);
- }
- else {
- attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
- attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
- }
-
- attributes->add(ATTR_STD_VERTEX_NORMAL);
- }
-
- ShaderNode::attributes(shader, attributes);
-}
-
-void NormalMapNode::compile(SVMCompiler& compiler)
-{
- ShaderInput *color_in = input("Color");
- ShaderInput *strength_in = input("Strength");
- ShaderOutput *normal_out = output("Normal");
- int attr = 0, attr_sign = 0;
-
- if(space == NODE_NORMAL_MAP_TANGENT) {
- if(attribute.empty()) {
- attr = compiler.attribute(ATTR_STD_UV_TANGENT);
- attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
- }
- else {
- attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
- attr_sign = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
- }
- }
-
- compiler.add_node(NODE_NORMAL_MAP,
- compiler.encode_uchar4(
- compiler.stack_assign(color_in),
- compiler.stack_assign(strength_in),
- compiler.stack_assign(normal_out),
- space),
- attr, attr_sign);
-}
-
-void NormalMapNode::compile(OSLCompiler& compiler)
-{
- if(space == NODE_NORMAL_MAP_TANGENT) {
- if(attribute.empty()) {
- compiler.parameter("attr_name", ustring("geom:tangent"));
- compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
- }
- else {
- compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
- compiler.parameter("attr_sign_name", ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
- }
- }
-
- compiler.parameter(this, "space");
- compiler.add(this, "node_normal_map");
+ if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
+ if (attribute.empty()) {
+ attributes->add(ATTR_STD_UV_TANGENT);
+ attributes->add(ATTR_STD_UV_TANGENT_SIGN);
+ }
+ else {
+ attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
+ }
+
+ attributes->add(ATTR_STD_VERTEX_NORMAL);
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void NormalMapNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *color_in = input("Color");
+ ShaderInput *strength_in = input("Strength");
+ ShaderOutput *normal_out = output("Normal");
+ int attr = 0, attr_sign = 0;
+
+ if (space == NODE_NORMAL_MAP_TANGENT) {
+ if (attribute.empty()) {
+ attr = compiler.attribute(ATTR_STD_UV_TANGENT);
+ attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
+ }
+ else {
+ attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ attr_sign = compiler.attribute(
+ ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
+ }
+ }
+
+ compiler.add_node(NODE_NORMAL_MAP,
+ compiler.encode_uchar4(compiler.stack_assign(color_in),
+ compiler.stack_assign(strength_in),
+ compiler.stack_assign(normal_out),
+ space),
+ attr,
+ attr_sign);
+}
+
+void NormalMapNode::compile(OSLCompiler &compiler)
+{
+ if (space == NODE_NORMAL_MAP_TANGENT) {
+ if (attribute.empty()) {
+ compiler.parameter("attr_name", ustring("geom:tangent"));
+ compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
+ }
+ else {
+ compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ compiler.parameter("attr_sign_name",
+ ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
+ }
+ }
+
+ compiler.parameter(this, "space");
+ compiler.add(this, "node_normal_map");
}
/* Tangent */
NODE_DEFINE(TangentNode)
{
- NodeType* type = NodeType::add("tangent", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("tangent", create, NodeType::SHADER);
- static NodeEnum direction_type_enum;
- direction_type_enum.insert("radial", NODE_TANGENT_RADIAL);
- direction_type_enum.insert("uv_map", NODE_TANGENT_UVMAP);
- SOCKET_ENUM(direction_type, "Direction Type", direction_type_enum, NODE_TANGENT_RADIAL);
+ static NodeEnum direction_type_enum;
+ direction_type_enum.insert("radial", NODE_TANGENT_RADIAL);
+ direction_type_enum.insert("uv_map", NODE_TANGENT_UVMAP);
+ SOCKET_ENUM(direction_type, "Direction Type", direction_type_enum, NODE_TANGENT_RADIAL);
- static NodeEnum axis_enum;
- axis_enum.insert("x", NODE_TANGENT_AXIS_X);
- axis_enum.insert("y", NODE_TANGENT_AXIS_Y);
- axis_enum.insert("z", NODE_TANGENT_AXIS_Z);
- SOCKET_ENUM(axis, "Axis", axis_enum, NODE_TANGENT_AXIS_X);
+ static NodeEnum axis_enum;
+ axis_enum.insert("x", NODE_TANGENT_AXIS_X);
+ axis_enum.insert("y", NODE_TANGENT_AXIS_Y);
+ axis_enum.insert("z", NODE_TANGENT_AXIS_Z);
+ SOCKET_ENUM(axis, "Axis", axis_enum, NODE_TANGENT_AXIS_X);
- SOCKET_STRING(attribute, "Attribute", ustring());
+ SOCKET_STRING(attribute, "Attribute", ustring());
- SOCKET_IN_NORMAL(normal_osl, "NormalIn", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
- SOCKET_OUT_NORMAL(tangent, "Tangent");
+ SOCKET_IN_NORMAL(normal_osl,
+ "NormalIn",
+ make_float3(0.0f, 0.0f, 0.0f),
+ SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
+ SOCKET_OUT_NORMAL(tangent, "Tangent");
- return type;
+ return type;
}
-TangentNode::TangentNode()
-: ShaderNode(node_type)
+TangentNode::TangentNode() : ShaderNode(node_type)
{
}
void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- if(direction_type == NODE_TANGENT_UVMAP) {
- if(attribute.empty())
- attributes->add(ATTR_STD_UV_TANGENT);
- else
- attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
- }
- else
- attributes->add(ATTR_STD_GENERATED);
- }
+ if (shader->has_surface) {
+ if (direction_type == NODE_TANGENT_UVMAP) {
+ if (attribute.empty())
+ attributes->add(ATTR_STD_UV_TANGENT);
+ else
+ attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ }
+ else
+ attributes->add(ATTR_STD_GENERATED);
+ }
- ShaderNode::attributes(shader, attributes);
+ ShaderNode::attributes(shader, attributes);
}
-void TangentNode::compile(SVMCompiler& compiler)
+void TangentNode::compile(SVMCompiler &compiler)
{
- ShaderOutput *tangent_out = output("Tangent");
- int attr;
+ ShaderOutput *tangent_out = output("Tangent");
+ int attr;
- if(direction_type == NODE_TANGENT_UVMAP) {
- if(attribute.empty())
- attr = compiler.attribute(ATTR_STD_UV_TANGENT);
- else
- attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
- }
- else
- attr = compiler.attribute(ATTR_STD_GENERATED);
+ if (direction_type == NODE_TANGENT_UVMAP) {
+ if (attribute.empty())
+ attr = compiler.attribute(ATTR_STD_UV_TANGENT);
+ else
+ attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ }
+ else
+ attr = compiler.attribute(ATTR_STD_GENERATED);
- compiler.add_node(NODE_TANGENT,
- compiler.encode_uchar4(
- compiler.stack_assign(tangent_out),
- direction_type,
- axis), attr);
+ compiler.add_node(
+ NODE_TANGENT,
+ compiler.encode_uchar4(compiler.stack_assign(tangent_out), direction_type, axis),
+ attr);
}
-void TangentNode::compile(OSLCompiler& compiler)
+void TangentNode::compile(OSLCompiler &compiler)
{
- if(direction_type == NODE_TANGENT_UVMAP) {
- if(attribute.empty())
- compiler.parameter("attr_name", ustring("geom:tangent"));
- else
- compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
- }
+ if (direction_type == NODE_TANGENT_UVMAP) {
+ if (attribute.empty())
+ compiler.parameter("attr_name", ustring("geom:tangent"));
+ else
+ compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ }
- compiler.parameter(this, "direction_type");
- compiler.parameter(this, "axis");
- compiler.add(this, "node_tangent");
+ compiler.parameter(this, "direction_type");
+ compiler.parameter(this, "axis");
+ compiler.add(this, "node_tangent");
}
/* Bevel */
NODE_DEFINE(BevelNode)
{
- NodeType* type = NodeType::add("bevel", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("bevel", create, NodeType::SHADER);
- SOCKET_INT(samples, "Samples", 4);
+ SOCKET_INT(samples, "Samples", 4);
- SOCKET_IN_FLOAT(radius, "Radius", 0.05f);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(radius, "Radius", 0.05f);
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_OUT_NORMAL(bevel, "Normal");
+ SOCKET_OUT_NORMAL(bevel, "Normal");
- return type;
+ return type;
}
-BevelNode::BevelNode()
-: ShaderNode(node_type)
+BevelNode::BevelNode() : ShaderNode(node_type)
{
}
-void BevelNode::compile(SVMCompiler& compiler)
+void BevelNode::compile(SVMCompiler &compiler)
{
- ShaderInput *radius_in = input("Radius");
- ShaderInput *normal_in = input("Normal");
- ShaderOutput *normal_out = output("Normal");
+ ShaderInput *radius_in = input("Radius");
+ ShaderInput *normal_in = input("Normal");
+ ShaderOutput *normal_out = output("Normal");
- compiler.add_node(NODE_BEVEL,
- compiler.encode_uchar4(samples,
- compiler.stack_assign(radius_in),
- compiler.stack_assign_if_linked(normal_in),
- compiler.stack_assign(normal_out)));
+ compiler.add_node(NODE_BEVEL,
+ compiler.encode_uchar4(samples,
+ compiler.stack_assign(radius_in),
+ compiler.stack_assign_if_linked(normal_in),
+ compiler.stack_assign(normal_out)));
}
-void BevelNode::compile(OSLCompiler& compiler)
+void BevelNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "samples");
- compiler.add(this, "node_bevel");
+ compiler.parameter(this, "samples");
+ compiler.add(this, "node_bevel");
}
/* Displacement */
NODE_DEFINE(DisplacementNode)
{
- NodeType* type = NodeType::add("displacement", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("displacement", create, NodeType::SHADER);
- static NodeEnum space_enum;
- space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
- space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
+ static NodeEnum space_enum;
+ space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
+ space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
- SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_OBJECT);
+ SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_OBJECT);
- SOCKET_IN_FLOAT(height, "Height", 0.0f);
- SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.5f);
- SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
- SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
+ SOCKET_IN_FLOAT(height, "Height", 0.0f);
+ SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.5f);
+ SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_OUT_VECTOR(displacement, "Displacement");
+ SOCKET_OUT_VECTOR(displacement, "Displacement");
- return type;
+ return type;
}
-DisplacementNode::DisplacementNode()
-: ShaderNode(node_type)
+DisplacementNode::DisplacementNode() : ShaderNode(node_type)
{
}
-void DisplacementNode::constant_fold(const ConstantFolder& folder)
+void DisplacementNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- if((height - midlevel == 0.0f) || (scale == 0.0f)) {
- folder.make_zero();
- }
- }
+ if (folder.all_inputs_constant()) {
+ if ((height - midlevel == 0.0f) || (scale == 0.0f)) {
+ folder.make_zero();
+ }
+ }
}
-void DisplacementNode::compile(SVMCompiler& compiler)
+void DisplacementNode::compile(SVMCompiler &compiler)
{
- ShaderInput *height_in = input("Height");
- ShaderInput *midlevel_in = input("Midlevel");
- ShaderInput *scale_in = input("Scale");
- ShaderInput *normal_in = input("Normal");
- ShaderOutput *displacement_out = output("Displacement");
+ ShaderInput *height_in = input("Height");
+ ShaderInput *midlevel_in = input("Midlevel");
+ ShaderInput *scale_in = input("Scale");
+ ShaderInput *normal_in = input("Normal");
+ ShaderOutput *displacement_out = output("Displacement");
- compiler.add_node(NODE_DISPLACEMENT,
- compiler.encode_uchar4(compiler.stack_assign(height_in),
- compiler.stack_assign(midlevel_in),
- compiler.stack_assign(scale_in),
- compiler.stack_assign_if_linked(normal_in)),
- compiler.stack_assign(displacement_out),
- space);
+ compiler.add_node(NODE_DISPLACEMENT,
+ compiler.encode_uchar4(compiler.stack_assign(height_in),
+ compiler.stack_assign(midlevel_in),
+ compiler.stack_assign(scale_in),
+ compiler.stack_assign_if_linked(normal_in)),
+ compiler.stack_assign(displacement_out),
+ space);
}
-void DisplacementNode::compile(OSLCompiler& compiler)
+void DisplacementNode::compile(OSLCompiler &compiler)
{
- compiler.parameter(this, "space");
- compiler.add(this, "node_displacement");
+ compiler.parameter(this, "space");
+ compiler.add(this, "node_displacement");
}
/* Vector Displacement */
NODE_DEFINE(VectorDisplacementNode)
{
- NodeType* type = NodeType::add("vector_displacement", create, NodeType::SHADER);
+ NodeType *type = NodeType::add("vector_displacement", create, NodeType::SHADER);
- static NodeEnum space_enum;
- space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
- space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
- space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
+ static NodeEnum space_enum;
+ space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
+ space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
+ space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
- SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
- SOCKET_STRING(attribute, "Attribute", ustring());
+ SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
+ SOCKET_STRING(attribute, "Attribute", ustring());
- SOCKET_IN_COLOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.0f);
- SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+ SOCKET_IN_COLOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.0f);
+ SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
- SOCKET_OUT_VECTOR(displacement, "Displacement");
+ SOCKET_OUT_VECTOR(displacement, "Displacement");
- return type;
+ return type;
}
-VectorDisplacementNode::VectorDisplacementNode()
-: ShaderNode(node_type)
+VectorDisplacementNode::VectorDisplacementNode() : ShaderNode(node_type)
{
}
-void VectorDisplacementNode::constant_fold(const ConstantFolder& folder)
+void VectorDisplacementNode::constant_fold(const ConstantFolder &folder)
{
- if(folder.all_inputs_constant()) {
- if((vector == make_float3(0.0f, 0.0f, 0.0f) && midlevel == 0.0f) ||
- (scale == 0.0f)) {
- folder.make_zero();
- }
- }
+ if (folder.all_inputs_constant()) {
+ if ((vector == make_float3(0.0f, 0.0f, 0.0f) && midlevel == 0.0f) || (scale == 0.0f)) {
+ folder.make_zero();
+ }
+ }
}
void VectorDisplacementNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
- if(attribute.empty()) {
- attributes->add(ATTR_STD_UV_TANGENT);
- attributes->add(ATTR_STD_UV_TANGENT_SIGN);
- }
- else {
- attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
- attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
- }
-
- attributes->add(ATTR_STD_VERTEX_NORMAL);
- }
-
- ShaderNode::attributes(shader, attributes);
-}
-
-void VectorDisplacementNode::compile(SVMCompiler& compiler)
-{
- ShaderInput *vector_in = input("Vector");
- ShaderInput *midlevel_in = input("Midlevel");
- ShaderInput *scale_in = input("Scale");
- ShaderOutput *displacement_out = output("Displacement");
- int attr = 0, attr_sign = 0;
-
- if(space == NODE_NORMAL_MAP_TANGENT) {
- if(attribute.empty()) {
- attr = compiler.attribute(ATTR_STD_UV_TANGENT);
- attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
- }
- else {
- attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
- attr_sign = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
- }
- }
-
- compiler.add_node(NODE_VECTOR_DISPLACEMENT,
- compiler.encode_uchar4(compiler.stack_assign(vector_in),
- compiler.stack_assign(midlevel_in),
- compiler.stack_assign(scale_in),
- compiler.stack_assign(displacement_out)),
- attr, attr_sign);
-
- compiler.add_node(space);
-}
-
-void VectorDisplacementNode::compile(OSLCompiler& compiler)
-{
- if(space == NODE_NORMAL_MAP_TANGENT) {
- if(attribute.empty()) {
- compiler.parameter("attr_name", ustring("geom:tangent"));
- compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
- }
- else {
- compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
- compiler.parameter("attr_sign_name", ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
- }
- }
-
- compiler.parameter(this, "space");
- compiler.add(this, "node_vector_displacement");
+ if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
+ if (attribute.empty()) {
+ attributes->add(ATTR_STD_UV_TANGENT);
+ attributes->add(ATTR_STD_UV_TANGENT_SIGN);
+ }
+ else {
+ attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
+ }
+
+ attributes->add(ATTR_STD_VERTEX_NORMAL);
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void VectorDisplacementNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *midlevel_in = input("Midlevel");
+ ShaderInput *scale_in = input("Scale");
+ ShaderOutput *displacement_out = output("Displacement");
+ int attr = 0, attr_sign = 0;
+
+ if (space == NODE_NORMAL_MAP_TANGENT) {
+ if (attribute.empty()) {
+ attr = compiler.attribute(ATTR_STD_UV_TANGENT);
+ attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
+ }
+ else {
+ attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ attr_sign = compiler.attribute(
+ ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
+ }
+ }
+
+ compiler.add_node(NODE_VECTOR_DISPLACEMENT,
+ compiler.encode_uchar4(compiler.stack_assign(vector_in),
+ compiler.stack_assign(midlevel_in),
+ compiler.stack_assign(scale_in),
+ compiler.stack_assign(displacement_out)),
+ attr,
+ attr_sign);
+
+ compiler.add_node(space);
+}
+
+void VectorDisplacementNode::compile(OSLCompiler &compiler)
+{
+ if (space == NODE_NORMAL_MAP_TANGENT) {
+ if (attribute.empty()) {
+ compiler.parameter("attr_name", ustring("geom:tangent"));
+ compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
+ }
+ else {
+ compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ compiler.parameter("attr_sign_name",
+ ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
+ }
+ }
+
+ compiler.parameter(this, "space");
+ compiler.add(this, "node_vector_displacement");
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 5571c525e9a..7796711115e 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -33,1137 +33,1459 @@ class Shader;
/* Texture Mapping */
class TextureMapping {
-public:
- TextureMapping();
- Transform compute_transform();
- bool skip();
- void compile(SVMCompiler& compiler, int offset_in, int offset_out);
- int compile(SVMCompiler& compiler, ShaderInput *vector_in);
- void compile(OSLCompiler &compiler);
+ public:
+ TextureMapping();
+ Transform compute_transform();
+ bool skip();
+ void compile(SVMCompiler &compiler, int offset_in, int offset_out);
+ int compile(SVMCompiler &compiler, ShaderInput *vector_in);
+ void compile(OSLCompiler &compiler);
- int compile_begin(SVMCompiler& compiler, ShaderInput *vector_in);
- void compile_end(SVMCompiler& compiler, ShaderInput *vector_in, int vector_offset);
+ int compile_begin(SVMCompiler &compiler, ShaderInput *vector_in);
+ void compile_end(SVMCompiler &compiler, ShaderInput *vector_in, int vector_offset);
- float3 translation;
- float3 rotation;
- float3 scale;
+ float3 translation;
+ float3 rotation;
+ float3 scale;
- float3 min, max;
- bool use_minmax;
+ float3 min, max;
+ bool use_minmax;
- enum Type { POINT = 0, TEXTURE = 1, VECTOR = 2, NORMAL = 3 };
- Type type;
+ enum Type { POINT = 0, TEXTURE = 1, VECTOR = 2, NORMAL = 3 };
+ Type type;
- enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 };
- Mapping x_mapping, y_mapping, z_mapping;
+ enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 };
+ Mapping x_mapping, y_mapping, z_mapping;
- enum Projection { FLAT, CUBE, TUBE, SPHERE };
- Projection projection;
+ enum Projection { FLAT, CUBE, TUBE, SPHERE };
+ Projection projection;
};
/* Nodes */
class TextureNode : public ShaderNode {
-public:
- explicit TextureNode(const NodeType *node_type) : ShaderNode(node_type) {}
- TextureMapping tex_mapping;
+ public:
+ explicit TextureNode(const NodeType *node_type) : ShaderNode(node_type)
+ {
+ }
+ TextureMapping tex_mapping;
};
/* Any node which uses image manager's slot should be a subclass of this one. */
class ImageSlotTextureNode : public TextureNode {
-public:
- explicit ImageSlotTextureNode(const NodeType *node_type) : TextureNode(node_type) {
- special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
- }
- int slot;
+ public:
+ explicit ImageSlotTextureNode(const NodeType *node_type) : TextureNode(node_type)
+ {
+ special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
+ }
+ int slot;
};
class ImageTextureNode : public ImageSlotTextureNode {
-public:
- SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
- ~ImageTextureNode();
- ShaderNode *clone() const;
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
-
- ImageManager *image_manager;
- int is_float;
- bool is_linear;
- bool use_alpha;
- ustring filename;
- void *builtin_data;
- NodeImageColorSpace color_space;
- NodeImageProjection projection;
- InterpolationType interpolation;
- ExtensionType extension;
- float projection_blend;
- bool animated;
- float3 vector;
-
- virtual bool equals(const ShaderNode& other)
- {
- const ImageTextureNode& image_node = (const ImageTextureNode&)other;
- return ImageSlotTextureNode::equals(other) &&
- builtin_data == image_node.builtin_data &&
- animated == image_node.animated;
- }
+ public:
+ SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
+ ~ImageTextureNode();
+ ShaderNode *clone() const;
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+
+ ImageManager *image_manager;
+ int is_float;
+ bool is_linear;
+ bool use_alpha;
+ ustring filename;
+ void *builtin_data;
+ NodeImageColorSpace color_space;
+ NodeImageProjection projection;
+ InterpolationType interpolation;
+ ExtensionType extension;
+ float projection_blend;
+ bool animated;
+ float3 vector;
+
+ virtual bool equals(const ShaderNode &other)
+ {
+ const ImageTextureNode &image_node = (const ImageTextureNode &)other;
+ return ImageSlotTextureNode::equals(other) && builtin_data == image_node.builtin_data &&
+ animated == image_node.animated;
+ }
};
class EnvironmentTextureNode : public ImageSlotTextureNode {
-public:
- SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
- ~EnvironmentTextureNode();
- ShaderNode *clone() const;
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
-
- ImageManager *image_manager;
- int is_float;
- bool is_linear;
- bool use_alpha;
- ustring filename;
- void *builtin_data;
- NodeImageColorSpace color_space;
- NodeEnvironmentProjection projection;
- InterpolationType interpolation;
- bool animated;
- float3 vector;
-
- virtual bool equals(const ShaderNode& other)
- {
- const EnvironmentTextureNode& env_node = (const EnvironmentTextureNode&)other;
- return ImageSlotTextureNode::equals(other) &&
- builtin_data == env_node.builtin_data &&
- animated == env_node.animated;
- }
+ public:
+ SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
+ ~EnvironmentTextureNode();
+ ShaderNode *clone() const;
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
+
+ ImageManager *image_manager;
+ int is_float;
+ bool is_linear;
+ bool use_alpha;
+ ustring filename;
+ void *builtin_data;
+ NodeImageColorSpace color_space;
+ NodeEnvironmentProjection projection;
+ InterpolationType interpolation;
+ bool animated;
+ float3 vector;
+
+ virtual bool equals(const ShaderNode &other)
+ {
+ const EnvironmentTextureNode &env_node = (const EnvironmentTextureNode &)other;
+ return ImageSlotTextureNode::equals(other) && builtin_data == env_node.builtin_data &&
+ animated == env_node.animated;
+ }
};
class SkyTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(SkyTextureNode)
+ public:
+ SHADER_NODE_CLASS(SkyTextureNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- NodeSkyType type;
- float3 sun_direction;
- float turbidity;
- float ground_albedo;
- float3 vector;
+ NodeSkyType type;
+ float3 sun_direction;
+ float turbidity;
+ float ground_albedo;
+ float3 vector;
};
class OutputNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(OutputNode)
+ public:
+ SHADER_NODE_CLASS(OutputNode)
- void *surface;
- void *volume;
- float3 displacement;
- float3 normal;
+ void *surface;
+ void *volume;
+ float3 displacement;
+ float3 normal;
- /* Don't allow output node de-duplication. */
- virtual bool equals(const ShaderNode& /*other*/) { return false; }
+ /* Don't allow output node de-duplication. */
+ virtual bool equals(const ShaderNode & /*other*/)
+ {
+ return false;
+ }
};
class GradientTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(GradientTextureNode)
+ public:
+ SHADER_NODE_CLASS(GradientTextureNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- NodeGradientType type;
- float3 vector;
+ NodeGradientType type;
+ float3 vector;
};
class NoiseTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(NoiseTextureNode)
+ public:
+ SHADER_NODE_CLASS(NoiseTextureNode)
- float scale, detail, distortion;
- float3 vector;
+ float scale, detail, distortion;
+ float3 vector;
};
class VoronoiTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(VoronoiTextureNode)
+ public:
+ SHADER_NODE_CLASS(VoronoiTextureNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- NodeVoronoiColoring coloring;
- NodeVoronoiDistanceMetric metric;
- NodeVoronoiFeature feature;
- float scale, exponent;
- float3 vector;
+ NodeVoronoiColoring coloring;
+ NodeVoronoiDistanceMetric metric;
+ NodeVoronoiFeature feature;
+ float scale, exponent;
+ float3 vector;
};
class MusgraveTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(MusgraveTextureNode)
+ public:
+ SHADER_NODE_CLASS(MusgraveTextureNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- NodeMusgraveType type;
- float scale, detail, dimension, lacunarity, offset, gain;
- float3 vector;
+ NodeMusgraveType type;
+ float scale, detail, dimension, lacunarity, offset, gain;
+ float3 vector;
};
class WaveTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(WaveTextureNode)
+ public:
+ SHADER_NODE_CLASS(WaveTextureNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- NodeWaveType type;
- NodeWaveProfile profile;
+ NodeWaveType type;
+ NodeWaveProfile profile;
- float scale, distortion, detail, detail_scale;
- float3 vector;
+ float scale, distortion, detail, detail_scale;
+ float3 vector;
};
class MagicTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(MagicTextureNode)
+ public:
+ SHADER_NODE_CLASS(MagicTextureNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- int depth;
- float3 vector;
- float scale, distortion;
+ int depth;
+ float3 vector;
+ float scale, distortion;
};
class CheckerTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(CheckerTextureNode)
+ public:
+ SHADER_NODE_CLASS(CheckerTextureNode)
- float3 vector, color1, color2;
- float scale;
+ float3 vector, color1, color2;
+ float scale;
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
};
class BrickTextureNode : public TextureNode {
-public:
- SHADER_NODE_CLASS(BrickTextureNode)
+ public:
+ SHADER_NODE_CLASS(BrickTextureNode)
- float offset, squash;
- int offset_frequency, squash_frequency;
+ float offset, squash;
+ int offset_frequency, squash_frequency;
- float3 color1, color2, mortar;
- float scale, mortar_size, mortar_smooth, bias, brick_width, row_height;
- float3 vector;
+ float3 color1, color2, mortar;
+ float scale, mortar_size, mortar_smooth, bias, brick_width, row_height;
+ float3 vector;
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
};
class PointDensityTextureNode : public ShaderNode {
-public:
- SHADER_NODE_NO_CLONE_CLASS(PointDensityTextureNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
-
- ~PointDensityTextureNode();
- ShaderNode *clone() const;
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
-
- bool has_spatial_varying() { return true; }
- bool has_object_dependency() { return true; }
-
- void add_image();
-
- ustring filename;
- NodeTexVoxelSpace space;
- InterpolationType interpolation;
- Transform tfm;
- float3 vector;
-
- ImageManager *image_manager;
- int slot;
- void *builtin_data;
-
- virtual bool equals(const ShaderNode& other) {
- const PointDensityTextureNode& point_dendity_node = (const PointDensityTextureNode&)other;
- return ShaderNode::equals(other) &&
- builtin_data == point_dendity_node.builtin_data;
- }
+ public:
+ SHADER_NODE_NO_CLONE_CLASS(PointDensityTextureNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
+
+ ~PointDensityTextureNode();
+ ShaderNode *clone() const;
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ bool has_object_dependency()
+ {
+ return true;
+ }
+
+ void add_image();
+
+ ustring filename;
+ NodeTexVoxelSpace space;
+ InterpolationType interpolation;
+ Transform tfm;
+ float3 vector;
+
+ ImageManager *image_manager;
+ int slot;
+ void *builtin_data;
+
+ virtual bool equals(const ShaderNode &other)
+ {
+ const PointDensityTextureNode &point_dendity_node = (const PointDensityTextureNode &)other;
+ return ShaderNode::equals(other) && builtin_data == point_dendity_node.builtin_data;
+ }
};
class IESLightNode : public TextureNode {
-public:
- SHADER_NODE_NO_CLONE_CLASS(IESLightNode)
+ public:
+ SHADER_NODE_NO_CLONE_CLASS(IESLightNode)
- ~IESLightNode();
- ShaderNode *clone() const;
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ ~IESLightNode();
+ ShaderNode *clone() const;
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- ustring filename;
- ustring ies;
+ ustring filename;
+ ustring ies;
- float strength;
- float3 vector;
+ float strength;
+ float3 vector;
-private:
- LightManager *light_manager;
- int slot;
+ private:
+ LightManager *light_manager;
+ int slot;
- void get_slot();
+ void get_slot();
};
class MappingNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(MappingNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ public:
+ SHADER_NODE_CLASS(MappingNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- float3 vector;
- TextureMapping tex_mapping;
+ float3 vector;
+ TextureMapping tex_mapping;
};
class RGBToBWNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(RGBToBWNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(RGBToBWNode)
+ void constant_fold(const ConstantFolder &folder);
- float3 color;
+ float3 color;
};
class ConvertNode : public ShaderNode {
-public:
- ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false);
- SHADER_NODE_BASE_CLASS(ConvertNode)
+ public:
+ ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false);
+ SHADER_NODE_BASE_CLASS(ConvertNode)
- void constant_fold(const ConstantFolder& folder);
+ void constant_fold(const ConstantFolder &folder);
- SocketType::Type from, to;
+ SocketType::Type from, to;
- union {
- float value_float;
- int value_int;
- float3 value_color;
- float3 value_vector;
- float3 value_point;
- float3 value_normal;
- };
- ustring value_string;
+ union {
+ float value_float;
+ int value_int;
+ float3 value_color;
+ float3 value_vector;
+ float3 value_point;
+ float3 value_normal;
+ };
+ ustring value_string;
-private:
- static const int MAX_TYPE = 12;
- static bool register_types();
- static Node* create(const NodeType *type);
- static const NodeType *node_types[MAX_TYPE][MAX_TYPE];
- static bool initialized;
+ private:
+ static const int MAX_TYPE = 12;
+ static bool register_types();
+ static Node *create(const NodeType *type);
+ static const NodeType *node_types[MAX_TYPE][MAX_TYPE];
+ static bool initialized;
};
class BsdfBaseNode : public ShaderNode {
-public:
- BsdfBaseNode(const NodeType *node_type);
+ public:
+ BsdfBaseNode(const NodeType *node_type);
- bool has_spatial_varying() { return true; }
- virtual ClosureType get_closure_type() { return closure; }
- virtual bool has_bump();
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual ClosureType get_closure_type()
+ {
+ return closure;
+ }
+ virtual bool has_bump();
- virtual bool equals(const ShaderNode& /*other*/)
- {
- /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */
- return false;
- }
+ virtual bool equals(const ShaderNode & /*other*/)
+ {
+ /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */
+ return false;
+ }
- ClosureType closure;
+ ClosureType closure;
};
class BsdfNode : public BsdfBaseNode {
-public:
- explicit BsdfNode(const NodeType *node_type);
- SHADER_NODE_BASE_CLASS(BsdfNode)
+ public:
+ explicit BsdfNode(const NodeType *node_type);
+ SHADER_NODE_BASE_CLASS(BsdfNode)
- void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL);
+ void compile(SVMCompiler &compiler,
+ ShaderInput *param1,
+ ShaderInput *param2,
+ ShaderInput *param3 = NULL,
+ ShaderInput *param4 = NULL);
- float3 color;
- float3 normal;
- float surface_mix_weight;
+ float3 color;
+ float3 normal;
+ float surface_mix_weight;
};
class AnisotropicBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(AnisotropicBsdfNode)
+ public:
+ SHADER_NODE_CLASS(AnisotropicBsdfNode)
- float3 tangent;
- float roughness, anisotropy, rotation;
- ClosureType distribution;
+ float3 tangent;
+ float roughness, anisotropy, rotation;
+ ClosureType distribution;
- ClosureType get_closure_type() { return distribution; }
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
+ ClosureType get_closure_type()
+ {
+ return distribution;
+ }
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
};
class DiffuseBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(DiffuseBsdfNode)
+ public:
+ SHADER_NODE_CLASS(DiffuseBsdfNode)
- float roughness;
+ float roughness;
};
/* Disney principled BRDF */
class PrincipledBsdfNode : public BsdfBaseNode {
-public:
- SHADER_NODE_CLASS(PrincipledBsdfNode)
-
- bool has_surface_bssrdf();
- bool has_bssrdf_bump();
- void compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface, ShaderInput *subsurface_radius,
- ShaderInput *specular, ShaderInput *roughness, ShaderInput *specular_tint, ShaderInput *anisotropic,
- ShaderInput *sheen, ShaderInput *sheen_tint, ShaderInput *clearcoat, ShaderInput *clearcoat_roughness,
- ShaderInput *ior, ShaderInput *transmission, ShaderInput *anisotropic_rotation, ShaderInput *transmission_roughness);
-
- float3 base_color;
- float3 subsurface_color, subsurface_radius;
- float metallic, subsurface, specular, roughness, specular_tint, anisotropic,
- sheen, sheen_tint, clearcoat, clearcoat_roughness, ior, transmission,
- anisotropic_rotation, transmission_roughness;
- float3 normal, clearcoat_normal, tangent;
- float surface_mix_weight;
- ClosureType distribution, distribution_orig;
- ClosureType subsurface_method;
-
- bool has_integrator_dependency();
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
+ public:
+ SHADER_NODE_CLASS(PrincipledBsdfNode)
+
+ bool has_surface_bssrdf();
+ bool has_bssrdf_bump();
+ void compile(SVMCompiler &compiler,
+ ShaderInput *metallic,
+ ShaderInput *subsurface,
+ ShaderInput *subsurface_radius,
+ ShaderInput *specular,
+ ShaderInput *roughness,
+ ShaderInput *specular_tint,
+ ShaderInput *anisotropic,
+ ShaderInput *sheen,
+ ShaderInput *sheen_tint,
+ ShaderInput *clearcoat,
+ ShaderInput *clearcoat_roughness,
+ ShaderInput *ior,
+ ShaderInput *transmission,
+ ShaderInput *anisotropic_rotation,
+ ShaderInput *transmission_roughness);
+
+ float3 base_color;
+ float3 subsurface_color, subsurface_radius;
+ float metallic, subsurface, specular, roughness, specular_tint, anisotropic, sheen, sheen_tint,
+ clearcoat, clearcoat_roughness, ior, transmission, anisotropic_rotation,
+ transmission_roughness;
+ float3 normal, clearcoat_normal, tangent;
+ float surface_mix_weight;
+ ClosureType distribution, distribution_orig;
+ ClosureType subsurface_method;
+
+ bool has_integrator_dependency();
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
};
class TranslucentBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(TranslucentBsdfNode)
+ public:
+ SHADER_NODE_CLASS(TranslucentBsdfNode)
};
class TransparentBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(TransparentBsdfNode)
+ public:
+ SHADER_NODE_CLASS(TransparentBsdfNode)
- bool has_surface_transparent() { return true; }
+ bool has_surface_transparent()
+ {
+ return true;
+ }
};
class VelvetBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(VelvetBsdfNode)
+ public:
+ SHADER_NODE_CLASS(VelvetBsdfNode)
- float sigma;
+ float sigma;
};
class GlossyBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(GlossyBsdfNode)
+ public:
+ SHADER_NODE_CLASS(GlossyBsdfNode)
- void simplify_settings(Scene *scene);
- bool has_integrator_dependency();
- ClosureType get_closure_type() { return distribution; }
+ void simplify_settings(Scene *scene);
+ bool has_integrator_dependency();
+ ClosureType get_closure_type()
+ {
+ return distribution;
+ }
- float roughness, roughness_orig;
- ClosureType distribution, distribution_orig;
+ float roughness, roughness_orig;
+ ClosureType distribution, distribution_orig;
};
class GlassBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(GlassBsdfNode)
+ public:
+ SHADER_NODE_CLASS(GlassBsdfNode)
- void simplify_settings(Scene *scene);
- bool has_integrator_dependency();
- ClosureType get_closure_type() { return distribution; }
+ void simplify_settings(Scene *scene);
+ bool has_integrator_dependency();
+ ClosureType get_closure_type()
+ {
+ return distribution;
+ }
- float roughness, roughness_orig, IOR;
- ClosureType distribution, distribution_orig;
+ float roughness, roughness_orig, IOR;
+ ClosureType distribution, distribution_orig;
};
class RefractionBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(RefractionBsdfNode)
+ public:
+ SHADER_NODE_CLASS(RefractionBsdfNode)
- void simplify_settings(Scene *scene);
- bool has_integrator_dependency();
- ClosureType get_closure_type() { return distribution; }
+ void simplify_settings(Scene *scene);
+ bool has_integrator_dependency();
+ ClosureType get_closure_type()
+ {
+ return distribution;
+ }
- float roughness, roughness_orig, IOR;
- ClosureType distribution, distribution_orig;
+ float roughness, roughness_orig, IOR;
+ ClosureType distribution, distribution_orig;
};
class ToonBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(ToonBsdfNode)
+ public:
+ SHADER_NODE_CLASS(ToonBsdfNode)
- float smooth, size;
- ClosureType component;
+ float smooth, size;
+ ClosureType component;
};
class SubsurfaceScatteringNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(SubsurfaceScatteringNode)
- bool has_surface_bssrdf() { return true; }
- bool has_bssrdf_bump();
- ClosureType get_closure_type() { return falloff; }
-
- float scale;
- float3 radius;
- float sharpness;
- float texture_blur;
- ClosureType falloff;
+ public:
+ SHADER_NODE_CLASS(SubsurfaceScatteringNode)
+ bool has_surface_bssrdf()
+ {
+ return true;
+ }
+ bool has_bssrdf_bump();
+ ClosureType get_closure_type()
+ {
+ return falloff;
+ }
+
+ float scale;
+ float3 radius;
+ float sharpness;
+ float texture_blur;
+ ClosureType falloff;
};
class EmissionNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(EmissionNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(EmissionNode)
+ void constant_fold(const ConstantFolder &folder);
- bool has_surface_emission() { return true; }
- bool has_volume_support() { return true; }
+ bool has_surface_emission()
+ {
+ return true;
+ }
+ bool has_volume_support()
+ {
+ return true;
+ }
- float3 color;
- float strength;
- float surface_mix_weight;
+ float3 color;
+ float strength;
+ float surface_mix_weight;
};
class BackgroundNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(BackgroundNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(BackgroundNode)
+ void constant_fold(const ConstantFolder &folder);
- float3 color;
- float strength;
- float surface_mix_weight;
+ float3 color;
+ float strength;
+ float surface_mix_weight;
};
class HoldoutNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(HoldoutNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
- virtual ClosureType get_closure_type() { return CLOSURE_HOLDOUT_ID; }
+ public:
+ SHADER_NODE_CLASS(HoldoutNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
+ virtual ClosureType get_closure_type()
+ {
+ return CLOSURE_HOLDOUT_ID;
+ }
- float surface_mix_weight;
- float volume_mix_weight;
+ float surface_mix_weight;
+ float volume_mix_weight;
};
class AmbientOcclusionNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(AmbientOcclusionNode)
-
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
- virtual bool has_raytrace() { return true; }
-
- float3 color;
- float distance;
- float3 normal;
- int samples;
-
- bool only_local;
- bool inside;
+ public:
+ SHADER_NODE_CLASS(AmbientOcclusionNode)
+
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
+ virtual bool has_raytrace()
+ {
+ return true;
+ }
+
+ float3 color;
+ float distance;
+ float3 normal;
+ int samples;
+
+ bool only_local;
+ bool inside;
};
class VolumeNode : public ShaderNode {
-public:
- VolumeNode(const NodeType *node_type);
- SHADER_NODE_BASE_CLASS(VolumeNode)
-
- void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2);
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
- virtual int get_feature() {
- return ShaderNode::get_feature() | NODE_FEATURE_VOLUME;
- }
- virtual ClosureType get_closure_type() { return closure; }
- virtual bool has_volume_support() { return true; }
-
- float3 color;
- float density;
- float volume_mix_weight;
- ClosureType closure;
-
- virtual bool equals(const ShaderNode& /*other*/)
- {
- /* TODO(sergey): With some care Volume nodes can be de-duplicated. */
- return false;
- }
+ public:
+ VolumeNode(const NodeType *node_type);
+ SHADER_NODE_BASE_CLASS(VolumeNode)
+
+ void compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
+ virtual int get_feature()
+ {
+ return ShaderNode::get_feature() | NODE_FEATURE_VOLUME;
+ }
+ virtual ClosureType get_closure_type()
+ {
+ return closure;
+ }
+ virtual bool has_volume_support()
+ {
+ return true;
+ }
+
+ float3 color;
+ float density;
+ float volume_mix_weight;
+ ClosureType closure;
+
+ virtual bool equals(const ShaderNode & /*other*/)
+ {
+ /* TODO(sergey): With some care Volume nodes can be de-duplicated. */
+ return false;
+ }
};
class AbsorptionVolumeNode : public VolumeNode {
-public:
- SHADER_NODE_CLASS(AbsorptionVolumeNode)
+ public:
+ SHADER_NODE_CLASS(AbsorptionVolumeNode)
};
class ScatterVolumeNode : public VolumeNode {
-public:
- SHADER_NODE_CLASS(ScatterVolumeNode)
+ public:
+ SHADER_NODE_CLASS(ScatterVolumeNode)
- float anisotropy;
+ float anisotropy;
};
class PrincipledVolumeNode : public VolumeNode {
-public:
- SHADER_NODE_CLASS(PrincipledVolumeNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
-
- ustring density_attribute;
- ustring color_attribute;
- ustring temperature_attribute;
-
- float anisotropy;
- float3 absorption_color;
- float emission_strength;
- float3 emission_color;
- float blackbody_intensity;
- float3 blackbody_tint;
- float temperature;
+ public:
+ SHADER_NODE_CLASS(PrincipledVolumeNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+
+ ustring density_attribute;
+ ustring color_attribute;
+ ustring temperature_attribute;
+
+ float anisotropy;
+ float3 absorption_color;
+ float emission_strength;
+ float3 emission_color;
+ float blackbody_intensity;
+ float3 blackbody_tint;
+ float temperature;
};
/* Interface between the I/O sockets and the SVM/OSL backend. */
class PrincipledHairBsdfNode : public BsdfBaseNode {
-public:
- SHADER_NODE_CLASS(PrincipledHairBsdfNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
-
- /* Longitudinal roughness. */
- float roughness;
- /* Azimuthal roughness. */
- float radial_roughness;
- /* Randomization factor for roughnesses. */
- float random_roughness;
- /* Longitudinal roughness factor for only the diffuse bounce (shiny undercoat). */
- float coat;
- /* Index of reflection. */
- float ior;
- /* Cuticle tilt angle. */
- float offset;
- /* Direct coloring's color. */
- float3 color;
- /* Melanin concentration. */
- float melanin;
- /* Melanin redness ratio. */
- float melanin_redness;
- /* Dye color. */
- float3 tint;
- /* Randomization factor for melanin quantities. */
- float random_color;
- /* Absorption coefficient (unfiltered). */
- float3 absorption_coefficient;
-
- float3 normal;
- float surface_mix_weight;
- /* If linked, here will be the given random number. */
- float random;
- /* Selected coloring parametrization. */
- NodePrincipledHairParametrization parametrization;
+ public:
+ SHADER_NODE_CLASS(PrincipledHairBsdfNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+
+ /* Longitudinal roughness. */
+ float roughness;
+ /* Azimuthal roughness. */
+ float radial_roughness;
+ /* Randomization factor for roughnesses. */
+ float random_roughness;
+ /* Longitudinal roughness factor for only the diffuse bounce (shiny undercoat). */
+ float coat;
+ /* Index of reflection. */
+ float ior;
+ /* Cuticle tilt angle. */
+ float offset;
+ /* Direct coloring's color. */
+ float3 color;
+ /* Melanin concentration. */
+ float melanin;
+ /* Melanin redness ratio. */
+ float melanin_redness;
+ /* Dye color. */
+ float3 tint;
+ /* Randomization factor for melanin quantities. */
+ float random_color;
+ /* Absorption coefficient (unfiltered). */
+ float3 absorption_coefficient;
+
+ float3 normal;
+ float surface_mix_weight;
+ /* If linked, here will be the given random number. */
+ float random;
+ /* Selected coloring parametrization. */
+ NodePrincipledHairParametrization parametrization;
};
class HairBsdfNode : public BsdfNode {
-public:
- SHADER_NODE_CLASS(HairBsdfNode)
- ClosureType get_closure_type() { return component; }
+ public:
+ SHADER_NODE_CLASS(HairBsdfNode)
+ ClosureType get_closure_type()
+ {
+ return component;
+ }
- ClosureType component;
- float offset;
- float roughness_u;
- float roughness_v;
- float3 tangent;
+ ClosureType component;
+ float offset;
+ float roughness_u;
+ float roughness_v;
+ float3 tangent;
};
class GeometryNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(GeometryNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- bool has_spatial_varying() { return true; }
- int get_group();
-
- float3 normal_osl;
+ public:
+ SHADER_NODE_CLASS(GeometryNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ int get_group();
+
+ float3 normal_osl;
};
class TextureCoordinateNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(TextureCoordinateNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- bool has_spatial_varying() { return true; }
- bool has_object_dependency() { return use_transform; }
-
- float3 normal_osl;
- bool from_dupli;
- bool use_transform;
- Transform ob_tfm;
+ public:
+ SHADER_NODE_CLASS(TextureCoordinateNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ bool has_object_dependency()
+ {
+ return use_transform;
+ }
+
+ float3 normal_osl;
+ bool from_dupli;
+ bool use_transform;
+ Transform ob_tfm;
};
class UVMapNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(UVMapNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
-
- ustring attribute;
- bool from_dupli;
+ public:
+ SHADER_NODE_CLASS(UVMapNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
+
+ ustring attribute;
+ bool from_dupli;
};
class LightPathNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(LightPathNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(LightPathNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
};
class LightFalloffNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(LightFalloffNode)
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ public:
+ SHADER_NODE_CLASS(LightFalloffNode)
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- float strength;
- float smooth;
+ float strength;
+ float smooth;
};
class ObjectInfoNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(ObjectInfoNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(ObjectInfoNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
};
class ParticleInfoNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(ParticleInfoNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(ParticleInfoNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
};
class HairInfoNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(HairInfoNode)
-
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
- virtual int get_feature() {
- return ShaderNode::get_feature() | NODE_FEATURE_HAIR;
- }
+ public:
+ SHADER_NODE_CLASS(HairInfoNode)
+
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
+ virtual int get_feature()
+ {
+ return ShaderNode::get_feature() | NODE_FEATURE_HAIR;
+ }
};
class ValueNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(ValueNode)
+ public:
+ SHADER_NODE_CLASS(ValueNode)
- void constant_fold(const ConstantFolder& folder);
+ void constant_fold(const ConstantFolder &folder);
- float value;
+ float value;
};
class ColorNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(ColorNode)
+ public:
+ SHADER_NODE_CLASS(ColorNode)
- void constant_fold(const ConstantFolder& folder);
+ void constant_fold(const ConstantFolder &folder);
- float3 value;
+ float3 value;
};
class AddClosureNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(AddClosureNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(AddClosureNode)
+ void constant_fold(const ConstantFolder &folder);
};
class MixClosureNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(MixClosureNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(MixClosureNode)
+ void constant_fold(const ConstantFolder &folder);
- float fac;
+ float fac;
};
class MixClosureWeightNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(MixClosureWeightNode)
+ public:
+ SHADER_NODE_CLASS(MixClosureWeightNode)
- float weight;
- float fac;
+ float weight;
+ float fac;
};
class InvertNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(InvertNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(InvertNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float fac;
- float3 color;
+ float fac;
+ float3 color;
};
class MixNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(MixNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(MixNode)
+ void constant_fold(const ConstantFolder &folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- NodeMix type;
- bool use_clamp;
- float3 color1;
- float3 color2;
- float fac;
+ NodeMix type;
+ bool use_clamp;
+ float3 color1;
+ float3 color2;
+ float fac;
};
class CombineRGBNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(CombineRGBNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(CombineRGBNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float r, g, b;
+ float r, g, b;
};
class CombineHSVNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(CombineHSVNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(CombineHSVNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float h, s, v;
+ float h, s, v;
};
class CombineXYZNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(CombineXYZNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(CombineXYZNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float x, y, z;
+ float x, y, z;
};
class GammaNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(GammaNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(GammaNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
- float3 color;
- float gamma;
+ float3 color;
+ float gamma;
};
class BrightContrastNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(BrightContrastNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(BrightContrastNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
- float3 color;
- float bright;
- float contrast;
+ float3 color;
+ float bright;
+ float contrast;
};
class SeparateRGBNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(SeparateRGBNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(SeparateRGBNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float3 color;
+ float3 color;
};
class SeparateHSVNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(SeparateHSVNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(SeparateHSVNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float3 color;
+ float3 color;
};
class SeparateXYZNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(SeparateXYZNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(SeparateXYZNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float3 vector;
+ float3 vector;
};
class HSVNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(HSVNode)
+ public:
+ SHADER_NODE_CLASS(HSVNode)
- float hue;
- float saturation;
- float value;
- float fac;
- float3 color;
+ float hue;
+ float saturation;
+ float value;
+ float fac;
+ float3 color;
};
class AttributeNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(AttributeNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- bool has_spatial_varying() { return true; }
+ public:
+ SHADER_NODE_CLASS(AttributeNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ bool has_spatial_varying()
+ {
+ return true;
+ }
- ustring attribute;
+ ustring attribute;
};
class CameraNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(CameraNode)
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ public:
+ SHADER_NODE_CLASS(CameraNode)
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
};
class FresnelNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(FresnelNode)
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(FresnelNode)
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
- float3 normal;
- float IOR;
+ float3 normal;
+ float IOR;
};
class LayerWeightNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(LayerWeightNode)
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(LayerWeightNode)
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
- float3 normal;
- float blend;
+ float3 normal;
+ float blend;
};
class WireframeNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(WireframeNode)
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(WireframeNode)
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float size;
- bool use_pixel_size;
+ float size;
+ bool use_pixel_size;
};
class WavelengthNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(WavelengthNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(WavelengthNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float wavelength;
+ float wavelength;
};
class BlackbodyNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(BlackbodyNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ public:
+ SHADER_NODE_CLASS(BlackbodyNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- float temperature;
+ float temperature;
};
class MathNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(MathNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(MathNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
+ void constant_fold(const ConstantFolder &folder);
- float value1;
- float value2;
- NodeMath type;
- bool use_clamp;
+ float value1;
+ float value2;
+ NodeMath type;
+ bool use_clamp;
};
class NormalNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(NormalNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+ public:
+ SHADER_NODE_CLASS(NormalNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_2;
+ }
- float3 direction;
- float3 normal;
+ float3 direction;
+ float3 normal;
};
class VectorMathNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(VectorMathNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(VectorMathNode)
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
+ void constant_fold(const ConstantFolder &folder);
- float3 vector1;
- float3 vector2;
- NodeVectorMath type;
+ float3 vector1;
+ float3 vector2;
+ NodeVectorMath type;
};
class VectorTransformNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(VectorTransformNode)
+ public:
+ SHADER_NODE_CLASS(VectorTransformNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- NodeVectorTransformType type;
- NodeVectorTransformConvertSpace convert_from;
- NodeVectorTransformConvertSpace convert_to;
- float3 vector;
+ NodeVectorTransformType type;
+ NodeVectorTransformConvertSpace convert_from;
+ NodeVectorTransformConvertSpace convert_to;
+ float3 vector;
};
class BumpNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(BumpNode)
- void constant_fold(const ConstantFolder& folder);
- bool has_spatial_varying() { return true; }
- virtual int get_feature() {
- return NODE_FEATURE_BUMP;
- }
-
- bool invert;
- bool use_object_space;
- float height;
- float sample_center;
- float sample_x;
- float sample_y;
- float3 normal;
- float strength;
- float distance;
+ public:
+ SHADER_NODE_CLASS(BumpNode)
+ void constant_fold(const ConstantFolder &folder);
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_feature()
+ {
+ return NODE_FEATURE_BUMP;
+ }
+
+ bool invert;
+ bool use_object_space;
+ float height;
+ float sample_center;
+ float sample_x;
+ float sample_y;
+ float3 normal;
+ float strength;
+ float distance;
};
class CurvesNode : public ShaderNode {
-public:
- explicit CurvesNode(const NodeType *node_type);
- SHADER_NODE_BASE_CLASS(CurvesNode)
+ public:
+ explicit CurvesNode(const NodeType *node_type);
+ SHADER_NODE_BASE_CLASS(CurvesNode)
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
- array<float3> curves;
- float min_x, max_x, fac;
- float3 value;
+ array<float3> curves;
+ float min_x, max_x, fac;
+ float3 value;
-protected:
- using ShaderNode::constant_fold;
- void constant_fold(const ConstantFolder& folder, ShaderInput *value_in);
- void compile(SVMCompiler& compiler, int type, ShaderInput *value_in, ShaderOutput *value_out);
- void compile(OSLCompiler& compiler, const char *name);
+ protected:
+ using ShaderNode::constant_fold;
+ void constant_fold(const ConstantFolder &folder, ShaderInput *value_in);
+ void compile(SVMCompiler &compiler, int type, ShaderInput *value_in, ShaderOutput *value_out);
+ void compile(OSLCompiler &compiler, const char *name);
};
class RGBCurvesNode : public CurvesNode {
-public:
- SHADER_NODE_CLASS(RGBCurvesNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(RGBCurvesNode)
+ void constant_fold(const ConstantFolder &folder);
};
class VectorCurvesNode : public CurvesNode {
-public:
- SHADER_NODE_CLASS(VectorCurvesNode)
- void constant_fold(const ConstantFolder& folder);
+ public:
+ SHADER_NODE_CLASS(VectorCurvesNode)
+ void constant_fold(const ConstantFolder &folder);
};
class RGBRampNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(RGBRampNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
+ public:
+ SHADER_NODE_CLASS(RGBRampNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_1;
+ }
- array<float3> ramp;
- array<float> ramp_alpha;
- float fac;
- bool interpolate;
+ array<float3> ramp;
+ array<float> ramp_alpha;
+ float fac;
+ bool interpolate;
};
class SetNormalNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(SetNormalNode)
- float3 direction;
+ public:
+ SHADER_NODE_CLASS(SetNormalNode)
+ float3 direction;
};
class OSLNode : public ShaderNode {
-public:
- static OSLNode *create(size_t num_inputs, const OSLNode *from = NULL);
- ~OSLNode();
+ public:
+ static OSLNode *create(size_t num_inputs, const OSLNode *from = NULL);
+ ~OSLNode();
- ShaderNode *clone() const;
+ ShaderNode *clone() const;
- char* input_default_value();
- void add_input(ustring name, SocketType::Type type);
- void add_output(ustring name, SocketType::Type type);
+ char *input_default_value();
+ void add_input(ustring name, SocketType::Type type);
+ void add_output(ustring name, SocketType::Type type);
- SHADER_NODE_NO_CLONE_CLASS(OSLNode)
+ SHADER_NODE_NO_CLONE_CLASS(OSLNode)
- /* ideally we could beter detect this, but we can't query this now */
- bool has_spatial_varying() { return true; }
- bool has_volume_support() { return true; }
+ /* ideally we could beter detect this, but we can't query this now */
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ bool has_volume_support()
+ {
+ return true;
+ }
- virtual bool equals(const ShaderNode& /*other*/) { return false; }
+ virtual bool equals(const ShaderNode & /*other*/)
+ {
+ return false;
+ }
- string filepath;
- string bytecode_hash;
+ string filepath;
+ string bytecode_hash;
};
class NormalMapNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(NormalMapNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
-
- NodeNormalMapSpace space;
- ustring attribute;
- float strength;
- float3 color;
- float3 normal_osl;
+ public:
+ SHADER_NODE_CLASS(NormalMapNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
+
+ NodeNormalMapSpace space;
+ ustring attribute;
+ float strength;
+ float3 color;
+ float3 normal_osl;
};
class TangentNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(TangentNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
-
- NodeTangentDirectionType direction_type;
- NodeTangentAxis axis;
- ustring attribute;
- float3 normal_osl;
+ public:
+ SHADER_NODE_CLASS(TangentNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
+
+ NodeTangentDirectionType direction_type;
+ NodeTangentAxis axis;
+ ustring attribute;
+ float3 normal_osl;
};
class BevelNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(BevelNode)
- bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_3; }
- virtual bool has_raytrace() { return true; }
-
- float radius;
- float3 normal;
- int samples;
+ public:
+ SHADER_NODE_CLASS(BevelNode)
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
+ virtual bool has_raytrace()
+ {
+ return true;
+ }
+
+ float radius;
+ float3 normal;
+ int samples;
};
class DisplacementNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(DisplacementNode)
- void constant_fold(const ConstantFolder& folder);
- virtual int get_feature() {
- return NODE_FEATURE_BUMP;
- }
+ public:
+ SHADER_NODE_CLASS(DisplacementNode)
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_feature()
+ {
+ return NODE_FEATURE_BUMP;
+ }
- NodeNormalMapSpace space;
- float height;
- float midlevel;
- float scale;
- float3 normal;
+ NodeNormalMapSpace space;
+ float height;
+ float midlevel;
+ float scale;
+ float3 normal;
};
class VectorDisplacementNode : public ShaderNode {
-public:
- SHADER_NODE_CLASS(VectorDisplacementNode)
- void attributes(Shader *shader, AttributeRequestSet *attributes);
- bool has_attribute_dependency() { return true; }
- void constant_fold(const ConstantFolder& folder);
- virtual int get_feature() {
- return NODE_FEATURE_BUMP;
- }
-
- NodeNormalMapSpace space;
- ustring attribute;
- float3 vector;
- float midlevel;
- float scale;
+ public:
+ SHADER_NODE_CLASS(VectorDisplacementNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_attribute_dependency()
+ {
+ return true;
+ }
+ void constant_fold(const ConstantFolder &folder);
+ virtual int get_feature()
+ {
+ return NODE_FEATURE_BUMP;
+ }
+
+ NodeNormalMapSpace space;
+ ustring attribute;
+ float3 vector;
+ float midlevel;
+ float scale;
};
CCL_NAMESPACE_END
-#endif /* __NODES_H__ */
+#endif /* __NODES_H__ */
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index b34d16c438b..6c6f8810412 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -38,77 +38,76 @@ CCL_NAMESPACE_BEGIN
/* Global state of object transform update. */
struct UpdateObjectTransformState {
- /* Global state used by device_update_object_transform().
- * Common for both threaded and non-threaded update.
- */
+ /* Global state used by device_update_object_transform().
+ * Common for both threaded and non-threaded update.
+ */
- /* Type of the motion required by the scene settings. */
- Scene::MotionType need_motion;
+ /* Type of the motion required by the scene settings. */
+ Scene::MotionType need_motion;
- /* Mapping from particle system to a index in packed particle array.
- * Only used for read.
- */
- map<ParticleSystem*, int> particle_offset;
+ /* Mapping from particle system to a index in packed particle array.
+ * Only used for read.
+ */
+ map<ParticleSystem *, int> particle_offset;
- /* Mesh area.
- * Used to avoid calculation of mesh area multiple times. Used for both
- * read and write. Acquire surface_area_lock to keep it all thread safe.
- */
- map<Mesh*, float> surface_area_map;
+ /* Mesh area.
+ * Used to avoid calculation of mesh area multiple times. Used for both
+ * read and write. Acquire surface_area_lock to keep it all thread safe.
+ */
+ map<Mesh *, float> surface_area_map;
- /* Motion offsets for each object. */
- array<uint> motion_offset;
+ /* Motion offsets for each object. */
+ array<uint> motion_offset;
- /* Packed object arrays. Those will be filled in. */
- uint *object_flag;
- KernelObject *objects;
- Transform *object_motion_pass;
- DecomposedTransform *object_motion;
+ /* Packed object arrays. Those will be filled in. */
+ uint *object_flag;
+ KernelObject *objects;
+ Transform *object_motion_pass;
+ DecomposedTransform *object_motion;
- /* Flags which will be synchronized to Integrator. */
- bool have_motion;
- bool have_curves;
+ /* Flags which will be synchronized to Integrator. */
+ bool have_motion;
+ bool have_curves;
- /* ** Scheduling queue. ** */
+ /* ** Scheduling queue. ** */
- Scene *scene;
+ Scene *scene;
- /* Some locks to keep everything thread-safe. */
- thread_spin_lock queue_lock;
- thread_spin_lock surface_area_lock;
+ /* Some locks to keep everything thread-safe. */
+ thread_spin_lock queue_lock;
+ thread_spin_lock surface_area_lock;
- /* First unused object index in the queue. */
- int queue_start_object;
+ /* First unused object index in the queue. */
+ int queue_start_object;
};
/* Object */
NODE_DEFINE(Object)
{
- NodeType* type = NodeType::add("object", create);
-
- SOCKET_NODE(mesh, "Mesh", &Mesh::node_type);
- SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
- SOCKET_UINT(visibility, "Visibility", ~0);
- SOCKET_UINT(random_id, "Random ID", 0);
- SOCKET_INT(pass_id, "Pass ID", 0);
- SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
- SOCKET_BOOLEAN(hide_on_missing_motion, "Hide on Missing Motion", false);
- SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f));
- SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f));
- SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
-
- SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false);
-
- return type;
+ NodeType *type = NodeType::add("object", create);
+
+ SOCKET_NODE(mesh, "Mesh", &Mesh::node_type);
+ SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
+ SOCKET_UINT(visibility, "Visibility", ~0);
+ SOCKET_UINT(random_id, "Random ID", 0);
+ SOCKET_INT(pass_id, "Pass ID", 0);
+ SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
+ SOCKET_BOOLEAN(hide_on_missing_motion, "Hide on Missing Motion", false);
+ SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f));
+ SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f));
+ SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
+
+ SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false);
+
+ return type;
}
-Object::Object()
-: Node(node_type)
+Object::Object() : Node(node_type)
{
- particle_system = NULL;
- particle_index = 0;
- bounds = BoundBox::empty;
+ particle_system = NULL;
+ particle_index = 0;
+ bounds = BoundBox::empty;
}
Object::~Object()
@@ -117,768 +116,762 @@ Object::~Object()
void Object::update_motion()
{
- if(!use_motion()) {
- return;
- }
-
- bool have_motion = false;
-
- for(size_t i = 0; i < motion.size(); i++) {
- if(motion[i] == transform_empty()) {
- if(hide_on_missing_motion) {
- /* Hide objects that have no valid previous or next
- * transform, for example particle that stop existing. It
- * would be better to handle this in the kernel and make
- * objects invisible outside certain motion steps. */
- tfm = transform_empty();
- motion.clear();
- return;
- }
- else {
- /* Otherwise just copy center motion. */
- motion[i] = tfm;
- }
- }
-
- /* Test if any of the transforms are actually different. */
- have_motion = have_motion || motion[i] != tfm;
- }
-
- /* Clear motion array if there is no actual motion. */
- if(!have_motion) {
- motion.clear();
- }
+ if (!use_motion()) {
+ return;
+ }
+
+ bool have_motion = false;
+
+ for (size_t i = 0; i < motion.size(); i++) {
+ if (motion[i] == transform_empty()) {
+ if (hide_on_missing_motion) {
+ /* Hide objects that have no valid previous or next
+ * transform, for example particle that stop existing. It
+ * would be better to handle this in the kernel and make
+ * objects invisible outside certain motion steps. */
+ tfm = transform_empty();
+ motion.clear();
+ return;
+ }
+ else {
+ /* Otherwise just copy center motion. */
+ motion[i] = tfm;
+ }
+ }
+
+ /* Test if any of the transforms are actually different. */
+ have_motion = have_motion || motion[i] != tfm;
+ }
+
+ /* Clear motion array if there is no actual motion. */
+ if (!have_motion) {
+ motion.clear();
+ }
}
void Object::compute_bounds(bool motion_blur)
{
- BoundBox mbounds = mesh->bounds;
-
- if(motion_blur && use_motion()) {
- array<DecomposedTransform> decomp(motion.size());
- transform_motion_decompose(decomp.data(), motion.data(), motion.size());
-
- bounds = BoundBox::empty;
-
- /* todo: this is really terrible. according to pbrt there is a better
- * way to find this iteratively, but did not find implementation yet
- * or try to implement myself */
- for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
- Transform ttfm;
-
- transform_motion_array_interpolate(&ttfm, decomp.data(), motion.size(), t);
- bounds.grow(mbounds.transformed(&ttfm));
- }
- }
- else {
- /* No motion blur case. */
- if(mesh->transform_applied) {
- bounds = mbounds;
- }
- else {
- bounds = mbounds.transformed(&tfm);
- }
- }
+ BoundBox mbounds = mesh->bounds;
+
+ if (motion_blur && use_motion()) {
+ array<DecomposedTransform> decomp(motion.size());
+ transform_motion_decompose(decomp.data(), motion.data(), motion.size());
+
+ bounds = BoundBox::empty;
+
+ /* todo: this is really terrible. according to pbrt there is a better
+ * way to find this iteratively, but did not find implementation yet
+ * or try to implement myself */
+ for (float t = 0.0f; t < 1.0f; t += (1.0f / 128.0f)) {
+ Transform ttfm;
+
+ transform_motion_array_interpolate(&ttfm, decomp.data(), motion.size(), t);
+ bounds.grow(mbounds.transformed(&ttfm));
+ }
+ }
+ else {
+ /* No motion blur case. */
+ if (mesh->transform_applied) {
+ bounds = mbounds;
+ }
+ else {
+ bounds = mbounds.transformed(&tfm);
+ }
+ }
}
void Object::apply_transform(bool apply_to_motion)
{
- if(!mesh || tfm == transform_identity())
- return;
-
- /* triangles */
- if(mesh->verts.size()) {
- /* store matrix to transform later. when accessing these as attributes we
- * do not want the transform to be applied for consistency between static
- * and dynamic BVH, so we do it on packing. */
- mesh->transform_normal = transform_transposed_inverse(tfm);
-
- /* apply to mesh vertices */
- for(size_t i = 0; i < mesh->verts.size(); i++)
- mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
-
- if(apply_to_motion) {
- Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr) {
- size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
- float3 *vert_steps = attr->data_float3();
-
- for(size_t i = 0; i < steps_size; i++)
- vert_steps[i] = transform_point(&tfm, vert_steps[i]);
- }
-
- Attribute *attr_N = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
-
- if(attr_N) {
- Transform ntfm = mesh->transform_normal;
- size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
- float3 *normal_steps = attr_N->data_float3();
-
- for(size_t i = 0; i < steps_size; i++)
- normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
- }
- }
- }
-
- /* curves */
- if(mesh->curve_keys.size()) {
- /* compute uniform scale */
- float3 c0 = transform_get_column(&tfm, 0);
- float3 c1 = transform_get_column(&tfm, 1);
- float3 c2 = transform_get_column(&tfm, 2);
- float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f/3.0f);
-
- /* apply transform to curve keys */
- for(size_t i = 0; i < mesh->curve_keys.size(); i++) {
- float3 co = transform_point(&tfm, mesh->curve_keys[i]);
- float radius = mesh->curve_radius[i] * scalar;
-
- /* scale for curve radius is only correct for uniform scale */
- mesh->curve_keys[i] = co;
- mesh->curve_radius[i] = radius;
- }
-
- if(apply_to_motion) {
- Attribute *curve_attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(curve_attr) {
- /* apply transform to motion curve keys */
- size_t steps_size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
- float4 *key_steps = curve_attr->data_float4();
-
- for(size_t i = 0; i < steps_size; i++) {
- float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
- float radius = key_steps[i].w * scalar;
-
- /* scale for curve radius is only correct for uniform scale */
- key_steps[i] = float3_to_float4(co);
- key_steps[i].w = radius;
- }
- }
- }
- }
-
- /* we keep normals pointing in same direction on negative scale, notify
- * mesh about this in it (re)calculates normals */
- if(transform_negative_scale(tfm))
- mesh->transform_negative_scaled = true;
-
- if(bounds.valid()) {
- mesh->compute_bounds();
- compute_bounds(false);
- }
-
- /* tfm is not reset to identity, all code that uses it needs to check the
- * transform_applied boolean */
+ if (!mesh || tfm == transform_identity())
+ return;
+
+ /* triangles */
+ if (mesh->verts.size()) {
+ /* store matrix to transform later. when accessing these as attributes we
+ * do not want the transform to be applied for consistency between static
+ * and dynamic BVH, so we do it on packing. */
+ mesh->transform_normal = transform_transposed_inverse(tfm);
+
+ /* apply to mesh vertices */
+ for (size_t i = 0; i < mesh->verts.size(); i++)
+ mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
+
+ if (apply_to_motion) {
+ Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr) {
+ size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps_size; i++)
+ vert_steps[i] = transform_point(&tfm, vert_steps[i]);
+ }
+
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ if (attr_N) {
+ Transform ntfm = mesh->transform_normal;
+ size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
+ float3 *normal_steps = attr_N->data_float3();
+
+ for (size_t i = 0; i < steps_size; i++)
+ normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
+ }
+ }
+ }
+
+ /* curves */
+ if (mesh->curve_keys.size()) {
+ /* compute uniform scale */
+ float3 c0 = transform_get_column(&tfm, 0);
+ float3 c1 = transform_get_column(&tfm, 1);
+ float3 c2 = transform_get_column(&tfm, 2);
+ float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f / 3.0f);
+
+ /* apply transform to curve keys */
+ for (size_t i = 0; i < mesh->curve_keys.size(); i++) {
+ float3 co = transform_point(&tfm, mesh->curve_keys[i]);
+ float radius = mesh->curve_radius[i] * scalar;
+
+ /* scale for curve radius is only correct for uniform scale */
+ mesh->curve_keys[i] = co;
+ mesh->curve_radius[i] = radius;
+ }
+
+ if (apply_to_motion) {
+ Attribute *curve_attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (curve_attr) {
+ /* apply transform to motion curve keys */
+ size_t steps_size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
+ float4 *key_steps = curve_attr->data_float4();
+
+ for (size_t i = 0; i < steps_size; i++) {
+ float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
+ float radius = key_steps[i].w * scalar;
+
+ /* scale for curve radius is only correct for uniform scale */
+ key_steps[i] = float3_to_float4(co);
+ key_steps[i].w = radius;
+ }
+ }
+ }
+ }
+
+ /* we keep normals pointing in same direction on negative scale, notify
+ * mesh about this in it (re)calculates normals */
+ if (transform_negative_scale(tfm))
+ mesh->transform_negative_scaled = true;
+
+ if (bounds.valid()) {
+ mesh->compute_bounds();
+ compute_bounds(false);
+ }
+
+ /* tfm is not reset to identity, all code that uses it needs to check the
+ * transform_applied boolean */
}
void Object::tag_update(Scene *scene)
{
- if(mesh) {
- if(mesh->transform_applied)
- mesh->need_update = true;
-
- foreach(Shader *shader, mesh->used_shaders) {
- if(shader->use_mis && shader->has_surface_emission)
- scene->light_manager->need_update = true;
- }
- }
-
- scene->camera->need_flags_update = true;
- scene->curve_system_manager->need_update = true;
- scene->mesh_manager->need_update = true;
- scene->object_manager->need_update = true;
+ if (mesh) {
+ if (mesh->transform_applied)
+ mesh->need_update = true;
+
+ foreach (Shader *shader, mesh->used_shaders) {
+ if (shader->use_mis && shader->has_surface_emission)
+ scene->light_manager->need_update = true;
+ }
+ }
+
+ scene->camera->need_flags_update = true;
+ scene->curve_system_manager->need_update = true;
+ scene->mesh_manager->need_update = true;
+ scene->object_manager->need_update = true;
}
bool Object::use_motion() const
{
- return (motion.size() > 1);
+ return (motion.size() > 1);
}
float Object::motion_time(int step) const
{
- return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
+ return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
}
int Object::motion_step(float time) const
{
- if(use_motion()) {
- for(size_t step = 0; step < motion.size(); step++) {
- if(time == motion_time(step)) {
- return step;
- }
- }
- }
-
- return -1;
+ if (use_motion()) {
+ for (size_t step = 0; step < motion.size(); step++) {
+ if (time == motion_time(step)) {
+ return step;
+ }
+ }
+ }
+
+ return -1;
}
bool Object::is_traceable() const
{
- /* Mesh itself can be empty,can skip all such objects. */
- if(!bounds.valid() || bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) {
- return false;
- }
- /* TODO(sergey): Check for mesh vertices/curves. visibility flags. */
- return true;
+ /* Mesh itself can be empty,can skip all such objects. */
+ if (!bounds.valid() || bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) {
+ return false;
+ }
+ /* TODO(sergey): Check for mesh vertices/curves. visibility flags. */
+ return true;
}
-uint Object::visibility_for_tracing() const {
- uint trace_visibility = visibility;
- if(is_shadow_catcher) {
- trace_visibility &= ~PATH_RAY_SHADOW_NON_CATCHER;
- }
- else {
- trace_visibility &= ~PATH_RAY_SHADOW_CATCHER;
- }
- return trace_visibility;
+uint Object::visibility_for_tracing() const
+{
+ uint trace_visibility = visibility;
+ if (is_shadow_catcher) {
+ trace_visibility &= ~PATH_RAY_SHADOW_NON_CATCHER;
+ }
+ else {
+ trace_visibility &= ~PATH_RAY_SHADOW_CATCHER;
+ }
+ return trace_visibility;
}
int Object::get_device_index() const
{
- return index;
+ return index;
}
/* Object Manager */
ObjectManager::ObjectManager()
{
- need_update = true;
- need_flags_update = true;
+ need_update = true;
+ need_flags_update = true;
}
ObjectManager::~ObjectManager()
{
}
-void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state,
- Object *ob)
+void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
{
- KernelObject& kobject = state->objects[ob->index];
- Transform *object_motion_pass = state->object_motion_pass;
-
- Mesh *mesh = ob->mesh;
- uint flag = 0;
-
- /* Compute transformations. */
- Transform tfm = ob->tfm;
- Transform itfm = transform_inverse(tfm);
-
- /* Compute surface area. for uniform scale we can do avoid the many
- * transform calls and share computation for instances.
- *
- * TODO(brecht): Correct for displacement, and move to a better place.
- */
- float uniform_scale;
- float surface_area = 0.0f;
- float pass_id = ob->pass_id;
- float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF);
- int particle_index = (ob->particle_system)
- ? ob->particle_index + state->particle_offset[ob->particle_system]
- : 0;
-
- if(transform_uniform_scale(tfm, uniform_scale)) {
- map<Mesh*, float>::iterator it;
-
- /* NOTE: This isn't fully optimal and could in theory lead to multiple
- * threads calculating area of the same mesh in parallel. However, this
- * also prevents suspending all the threads when some mesh's area is
- * not yet known.
- */
- state->surface_area_lock.lock();
- it = state->surface_area_map.find(mesh);
- state->surface_area_lock.unlock();
-
- if(it == state->surface_area_map.end()) {
- size_t num_triangles = mesh->num_triangles();
- for(size_t j = 0; j < num_triangles; j++) {
- Mesh::Triangle t = mesh->get_triangle(j);
- float3 p1 = mesh->verts[t.v[0]];
- float3 p2 = mesh->verts[t.v[1]];
- float3 p3 = mesh->verts[t.v[2]];
-
- surface_area += triangle_area(p1, p2, p3);
- }
-
- state->surface_area_lock.lock();
- state->surface_area_map[mesh] = surface_area;
- state->surface_area_lock.unlock();
- }
- else {
- surface_area = it->second;
- }
-
- surface_area *= uniform_scale;
- }
- else {
- size_t num_triangles = mesh->num_triangles();
- for(size_t j = 0; j < num_triangles; j++) {
- Mesh::Triangle t = mesh->get_triangle(j);
- float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]);
- float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]);
- float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]);
-
- surface_area += triangle_area(p1, p2, p3);
- }
- }
-
- kobject.tfm = tfm;
- kobject.itfm = itfm;
- kobject.surface_area = surface_area;
- kobject.pass_id = pass_id;
- kobject.random_number = random_number;
- kobject.particle_index = particle_index;
- kobject.motion_offset = 0;
-
- if(mesh->use_motion_blur) {
- state->have_motion = true;
- }
- if(mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
- flag |= SD_OBJECT_HAS_VERTEX_MOTION;
- }
-
- if(state->need_motion == Scene::MOTION_PASS) {
- /* Clear motion array if there is no actual motion. */
- ob->update_motion();
-
- /* Compute motion transforms. */
- Transform tfm_pre, tfm_post;
- if(ob->use_motion()) {
- tfm_pre = ob->motion[0];
- tfm_post = ob->motion[ob->motion.size() - 1];
- }
- else {
- tfm_pre = tfm;
- tfm_post = tfm;
- }
-
- /* Motion transformations, is world/object space depending if mesh
- * comes with deformed position in object space, or if we transform
- * the shading point in world space. */
- if(!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
- tfm_pre = tfm_pre * itfm;
- tfm_post = tfm_post * itfm;
- }
-
- int motion_pass_offset = ob->index*OBJECT_MOTION_PASS_SIZE;
- object_motion_pass[motion_pass_offset + 0] = tfm_pre;
- object_motion_pass[motion_pass_offset + 1] = tfm_post;
- }
- else if(state->need_motion == Scene::MOTION_BLUR) {
- if(ob->use_motion()) {
- kobject.motion_offset = state->motion_offset[ob->index];
-
- /* Decompose transforms for interpolation. */
- DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
- transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
- flag |= SD_OBJECT_MOTION;
- state->have_motion = true;
- }
- }
-
- /* Dupli object coords and motion info. */
- kobject.dupli_generated[0] = ob->dupli_generated[0];
- kobject.dupli_generated[1] = ob->dupli_generated[1];
- kobject.dupli_generated[2] = ob->dupli_generated[2];
- kobject.numkeys = mesh->curve_keys.size();
- kobject.dupli_uv[0] = ob->dupli_uv[0];
- kobject.dupli_uv[1] = ob->dupli_uv[1];
- int totalsteps = mesh->motion_steps;
- kobject.numsteps = (totalsteps - 1)/2;
- kobject.numverts = mesh->verts.size();
- kobject.patch_map_offset = 0;
- kobject.attribute_map_offset = 0;
- uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
- uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
- kobject.cryptomatte_object = util_hash_to_float(hash_name);
- kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
-
- /* Object flag. */
- if(ob->use_holdout) {
- flag |= SD_OBJECT_HOLDOUT_MASK;
- }
- state->object_flag[ob->index] = flag;
-
- /* Have curves. */
- if(mesh->num_curves()) {
- state->have_curves = true;
- }
+ KernelObject &kobject = state->objects[ob->index];
+ Transform *object_motion_pass = state->object_motion_pass;
+
+ Mesh *mesh = ob->mesh;
+ uint flag = 0;
+
+ /* Compute transformations. */
+ Transform tfm = ob->tfm;
+ Transform itfm = transform_inverse(tfm);
+
+ /* Compute surface area. for uniform scale we can do avoid the many
+ * transform calls and share computation for instances.
+ *
+ * TODO(brecht): Correct for displacement, and move to a better place.
+ */
+ float uniform_scale;
+ float surface_area = 0.0f;
+ float pass_id = ob->pass_id;
+ float random_number = (float)ob->random_id * (1.0f / (float)0xFFFFFFFF);
+ int particle_index = (ob->particle_system) ?
+ ob->particle_index + state->particle_offset[ob->particle_system] :
+ 0;
+
+ if (transform_uniform_scale(tfm, uniform_scale)) {
+ map<Mesh *, float>::iterator it;
+
+ /* NOTE: This isn't fully optimal and could in theory lead to multiple
+ * threads calculating area of the same mesh in parallel. However, this
+ * also prevents suspending all the threads when some mesh's area is
+ * not yet known.
+ */
+ state->surface_area_lock.lock();
+ it = state->surface_area_map.find(mesh);
+ state->surface_area_lock.unlock();
+
+ if (it == state->surface_area_map.end()) {
+ size_t num_triangles = mesh->num_triangles();
+ for (size_t j = 0; j < num_triangles; j++) {
+ Mesh::Triangle t = mesh->get_triangle(j);
+ float3 p1 = mesh->verts[t.v[0]];
+ float3 p2 = mesh->verts[t.v[1]];
+ float3 p3 = mesh->verts[t.v[2]];
+
+ surface_area += triangle_area(p1, p2, p3);
+ }
+
+ state->surface_area_lock.lock();
+ state->surface_area_map[mesh] = surface_area;
+ state->surface_area_lock.unlock();
+ }
+ else {
+ surface_area = it->second;
+ }
+
+ surface_area *= uniform_scale;
+ }
+ else {
+ size_t num_triangles = mesh->num_triangles();
+ for (size_t j = 0; j < num_triangles; j++) {
+ Mesh::Triangle t = mesh->get_triangle(j);
+ float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]);
+ float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]);
+ float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]);
+
+ surface_area += triangle_area(p1, p2, p3);
+ }
+ }
+
+ kobject.tfm = tfm;
+ kobject.itfm = itfm;
+ kobject.surface_area = surface_area;
+ kobject.pass_id = pass_id;
+ kobject.random_number = random_number;
+ kobject.particle_index = particle_index;
+ kobject.motion_offset = 0;
+
+ if (mesh->use_motion_blur) {
+ state->have_motion = true;
+ }
+ if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
+ flag |= SD_OBJECT_HAS_VERTEX_MOTION;
+ }
+
+ if (state->need_motion == Scene::MOTION_PASS) {
+ /* Clear motion array if there is no actual motion. */
+ ob->update_motion();
+
+ /* Compute motion transforms. */
+ Transform tfm_pre, tfm_post;
+ if (ob->use_motion()) {
+ tfm_pre = ob->motion[0];
+ tfm_post = ob->motion[ob->motion.size() - 1];
+ }
+ else {
+ tfm_pre = tfm;
+ tfm_post = tfm;
+ }
+
+ /* Motion transformations, is world/object space depending if mesh
+ * comes with deformed position in object space, or if we transform
+ * the shading point in world space. */
+ if (!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
+ tfm_pre = tfm_pre * itfm;
+ tfm_post = tfm_post * itfm;
+ }
+
+ int motion_pass_offset = ob->index * OBJECT_MOTION_PASS_SIZE;
+ object_motion_pass[motion_pass_offset + 0] = tfm_pre;
+ object_motion_pass[motion_pass_offset + 1] = tfm_post;
+ }
+ else if (state->need_motion == Scene::MOTION_BLUR) {
+ if (ob->use_motion()) {
+ kobject.motion_offset = state->motion_offset[ob->index];
+
+ /* Decompose transforms for interpolation. */
+ DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
+ transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
+ flag |= SD_OBJECT_MOTION;
+ state->have_motion = true;
+ }
+ }
+
+ /* Dupli object coords and motion info. */
+ kobject.dupli_generated[0] = ob->dupli_generated[0];
+ kobject.dupli_generated[1] = ob->dupli_generated[1];
+ kobject.dupli_generated[2] = ob->dupli_generated[2];
+ kobject.numkeys = mesh->curve_keys.size();
+ kobject.dupli_uv[0] = ob->dupli_uv[0];
+ kobject.dupli_uv[1] = ob->dupli_uv[1];
+ int totalsteps = mesh->motion_steps;
+ kobject.numsteps = (totalsteps - 1) / 2;
+ kobject.numverts = mesh->verts.size();
+ kobject.patch_map_offset = 0;
+ kobject.attribute_map_offset = 0;
+ uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
+ uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
+ kobject.cryptomatte_object = util_hash_to_float(hash_name);
+ kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
+
+ /* Object flag. */
+ if (ob->use_holdout) {
+ flag |= SD_OBJECT_HOLDOUT_MASK;
+ }
+ state->object_flag[ob->index] = flag;
+
+ /* Have curves. */
+ if (mesh->num_curves()) {
+ state->have_curves = true;
+ }
}
-bool ObjectManager::device_update_object_transform_pop_work(
- UpdateObjectTransformState *state,
- int *start_index,
- int *num_objects)
+bool ObjectManager::device_update_object_transform_pop_work(UpdateObjectTransformState *state,
+ int *start_index,
+ int *num_objects)
{
- /* Tweakable parameter, number of objects per chunk.
- * Too small value will cause some extra overhead due to spin lock,
- * too big value might not use all threads nicely.
- */
- static const int OBJECTS_PER_TASK = 32;
- bool have_work = false;
- state->queue_lock.lock();
- int num_scene_objects = state->scene->objects.size();
- if(state->queue_start_object < num_scene_objects) {
- int count = min(OBJECTS_PER_TASK,
- num_scene_objects - state->queue_start_object);
- *start_index = state->queue_start_object;
- *num_objects = count;
- state->queue_start_object += count;
- have_work = true;
- }
- state->queue_lock.unlock();
- return have_work;
+ /* Tweakable parameter, number of objects per chunk.
+ * Too small value will cause some extra overhead due to spin lock,
+ * too big value might not use all threads nicely.
+ */
+ static const int OBJECTS_PER_TASK = 32;
+ bool have_work = false;
+ state->queue_lock.lock();
+ int num_scene_objects = state->scene->objects.size();
+ if (state->queue_start_object < num_scene_objects) {
+ int count = min(OBJECTS_PER_TASK, num_scene_objects - state->queue_start_object);
+ *start_index = state->queue_start_object;
+ *num_objects = count;
+ state->queue_start_object += count;
+ have_work = true;
+ }
+ state->queue_lock.unlock();
+ return have_work;
}
-void ObjectManager::device_update_object_transform_task(
- UpdateObjectTransformState *state)
+void ObjectManager::device_update_object_transform_task(UpdateObjectTransformState *state)
{
- int start_index, num_objects;
- while(device_update_object_transform_pop_work(state,
- &start_index,
- &num_objects))
- {
- for(int i = 0; i < num_objects; ++i) {
- const int object_index = start_index + i;
- Object *ob = state->scene->objects[object_index];
- device_update_object_transform(state, ob);
- }
- }
+ int start_index, num_objects;
+ while (device_update_object_transform_pop_work(state, &start_index, &num_objects)) {
+ for (int i = 0; i < num_objects; ++i) {
+ const int object_index = start_index + i;
+ Object *ob = state->scene->objects[object_index];
+ device_update_object_transform(state, ob);
+ }
+ }
}
-void ObjectManager::device_update_transforms(DeviceScene *dscene,
- Scene *scene,
- Progress& progress)
+void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
{
- UpdateObjectTransformState state;
- state.need_motion = scene->need_motion();
- state.have_motion = false;
- state.have_curves = false;
- state.scene = scene;
- state.queue_start_object = 0;
-
- state.objects = dscene->objects.alloc(scene->objects.size());
- state.object_flag = dscene->object_flag.alloc(scene->objects.size());
- state.object_motion = NULL;
- state.object_motion_pass = NULL;
-
- if(state.need_motion == Scene::MOTION_PASS) {
- state.object_motion_pass = dscene->object_motion_pass.alloc(OBJECT_MOTION_PASS_SIZE*scene->objects.size());
- }
- else if(state.need_motion == Scene::MOTION_BLUR) {
- /* Set object offsets into global object motion array. */
- uint *motion_offsets = state.motion_offset.resize(scene->objects.size());
- uint motion_offset = 0;
-
- foreach(Object *ob, scene->objects) {
- *motion_offsets = motion_offset;
- motion_offsets++;
-
- /* Clear motion array if there is no actual motion. */
- ob->update_motion();
- motion_offset += ob->motion.size();
- }
-
- state.object_motion = dscene->object_motion.alloc(motion_offset);
- }
-
- /* Particle system device offsets
- * 0 is dummy particle, index starts at 1.
- */
- int numparticles = 1;
- foreach(ParticleSystem *psys, scene->particle_systems) {
- state.particle_offset[psys] = numparticles;
- numparticles += psys->particles.size();
- }
-
- /* NOTE: If it's just a handful of objects we deal with them in a single
- * thread to avoid threading overhead. However, this threshold is might
- * need some tweaks to make mid-complex scenes optimal.
- */
- if(scene->objects.size() < 64) {
- foreach(Object *ob, scene->objects) {
- device_update_object_transform(&state, ob);
- if(progress.get_cancel()) {
- return;
- }
- }
- }
- else {
- const int num_threads = TaskScheduler::num_threads();
- TaskPool pool;
- for(int i = 0; i < num_threads; ++i) {
- pool.push(function_bind(
- &ObjectManager::device_update_object_transform_task,
- this,
- &state));
- }
- pool.wait_work();
- if(progress.get_cancel()) {
- return;
- }
- }
-
- dscene->objects.copy_to_device();
- if(state.need_motion == Scene::MOTION_PASS) {
- dscene->object_motion_pass.copy_to_device();
- }
- else if(state.need_motion == Scene::MOTION_BLUR) {
- dscene->object_motion.copy_to_device();
- }
-
- dscene->data.bvh.have_motion = state.have_motion;
- dscene->data.bvh.have_curves = state.have_curves;
- dscene->data.bvh.have_instancing = true;
+ UpdateObjectTransformState state;
+ state.need_motion = scene->need_motion();
+ state.have_motion = false;
+ state.have_curves = false;
+ state.scene = scene;
+ state.queue_start_object = 0;
+
+ state.objects = dscene->objects.alloc(scene->objects.size());
+ state.object_flag = dscene->object_flag.alloc(scene->objects.size());
+ state.object_motion = NULL;
+ state.object_motion_pass = NULL;
+
+ if (state.need_motion == Scene::MOTION_PASS) {
+ state.object_motion_pass = dscene->object_motion_pass.alloc(OBJECT_MOTION_PASS_SIZE *
+ scene->objects.size());
+ }
+ else if (state.need_motion == Scene::MOTION_BLUR) {
+ /* Set object offsets into global object motion array. */
+ uint *motion_offsets = state.motion_offset.resize(scene->objects.size());
+ uint motion_offset = 0;
+
+ foreach (Object *ob, scene->objects) {
+ *motion_offsets = motion_offset;
+ motion_offsets++;
+
+ /* Clear motion array if there is no actual motion. */
+ ob->update_motion();
+ motion_offset += ob->motion.size();
+ }
+
+ state.object_motion = dscene->object_motion.alloc(motion_offset);
+ }
+
+ /* Particle system device offsets
+ * 0 is dummy particle, index starts at 1.
+ */
+ int numparticles = 1;
+ foreach (ParticleSystem *psys, scene->particle_systems) {
+ state.particle_offset[psys] = numparticles;
+ numparticles += psys->particles.size();
+ }
+
+ /* NOTE: If it's just a handful of objects we deal with them in a single
+ * thread to avoid threading overhead. However, this threshold is might
+ * need some tweaks to make mid-complex scenes optimal.
+ */
+ if (scene->objects.size() < 64) {
+ foreach (Object *ob, scene->objects) {
+ device_update_object_transform(&state, ob);
+ if (progress.get_cancel()) {
+ return;
+ }
+ }
+ }
+ else {
+ const int num_threads = TaskScheduler::num_threads();
+ TaskPool pool;
+ for (int i = 0; i < num_threads; ++i) {
+ pool.push(function_bind(&ObjectManager::device_update_object_transform_task, this, &state));
+ }
+ pool.wait_work();
+ if (progress.get_cancel()) {
+ return;
+ }
+ }
+
+ dscene->objects.copy_to_device();
+ if (state.need_motion == Scene::MOTION_PASS) {
+ dscene->object_motion_pass.copy_to_device();
+ }
+ else if (state.need_motion == Scene::MOTION_BLUR) {
+ dscene->object_motion.copy_to_device();
+ }
+
+ dscene->data.bvh.have_motion = state.have_motion;
+ dscene->data.bvh.have_curves = state.have_curves;
+ dscene->data.bvh.have_instancing = true;
}
-void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+void ObjectManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- VLOG(1) << "Total " << scene->objects.size() << " objects.";
+ VLOG(1) << "Total " << scene->objects.size() << " objects.";
- device_free(device, dscene);
+ device_free(device, dscene);
- if(scene->objects.size() == 0)
- return;
+ if (scene->objects.size() == 0)
+ return;
- /* Assign object IDs. */
- int index = 0;
- foreach(Object *object, scene->objects) {
- object->index = index++;
- }
+ /* Assign object IDs. */
+ int index = 0;
+ foreach (Object *object, scene->objects) {
+ object->index = index++;
+ }
- /* set object transform matrices, before applying static transforms */
- progress.set_status("Updating Objects", "Copying Transformations to device");
- device_update_transforms(dscene, scene, progress);
+ /* set object transform matrices, before applying static transforms */
+ progress.set_status("Updating Objects", "Copying Transformations to device");
+ device_update_transforms(dscene, scene, progress);
- if(progress.get_cancel()) return;
+ if (progress.get_cancel())
+ return;
- /* prepare for static BVH building */
- /* todo: do before to support getting object level coords? */
- if(scene->params.bvh_type == SceneParams::BVH_STATIC) {
- progress.set_status("Updating Objects", "Applying Static Transformations");
- apply_static_transforms(dscene, scene, progress);
- }
+ /* prepare for static BVH building */
+ /* todo: do before to support getting object level coords? */
+ if (scene->params.bvh_type == SceneParams::BVH_STATIC) {
+ progress.set_status("Updating Objects", "Applying Static Transformations");
+ apply_static_transforms(dscene, scene, progress);
+ }
}
-void ObjectManager::device_update_flags(Device *,
- DeviceScene *dscene,
- Scene *scene,
- Progress& /*progress*/,
- bool bounds_valid)
+void ObjectManager::device_update_flags(
+ Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
{
- if(!need_update && !need_flags_update)
- return;
-
- need_update = false;
- need_flags_update = false;
-
- if(scene->objects.size() == 0)
- return;
-
- /* Object info flag. */
- uint *object_flag = dscene->object_flag.data();
-
- /* Object volume intersection. */
- vector<Object *> volume_objects;
- bool has_volume_objects = false;
- foreach(Object *object, scene->objects) {
- if(object->mesh->has_volume) {
- if(bounds_valid) {
- volume_objects.push_back(object);
- }
- has_volume_objects = true;
- }
- }
-
- foreach(Object *object, scene->objects) {
- if(object->mesh->has_volume) {
- object_flag[object->index] |= SD_OBJECT_HAS_VOLUME;
- object_flag[object->index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
-
- foreach(Attribute& attr, object->mesh->attributes.attributes) {
- if(attr.element == ATTR_ELEMENT_VOXEL) {
- object_flag[object->index] |= SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
- }
- }
- }
- else {
- object_flag[object->index] &= ~(SD_OBJECT_HAS_VOLUME|SD_OBJECT_HAS_VOLUME_ATTRIBUTES);
- }
- if(object->is_shadow_catcher) {
- object_flag[object->index] |= SD_OBJECT_SHADOW_CATCHER;
- }
- else {
- object_flag[object->index] &= ~SD_OBJECT_SHADOW_CATCHER;
- }
-
- if(bounds_valid) {
- foreach(Object *volume_object, volume_objects) {
- if(object == volume_object) {
- continue;
- }
- if(object->bounds.intersects(volume_object->bounds)) {
- object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
- break;
- }
- }
- }
- else if(has_volume_objects) {
- /* Not really valid, but can't make more reliable in the case
- * of bounds not being up to date.
- */
- object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
- }
- }
-
- /* Copy object flag. */
- dscene->object_flag.copy_to_device();
+ if (!need_update && !need_flags_update)
+ return;
+
+ need_update = false;
+ need_flags_update = false;
+
+ if (scene->objects.size() == 0)
+ return;
+
+ /* Object info flag. */
+ uint *object_flag = dscene->object_flag.data();
+
+ /* Object volume intersection. */
+ vector<Object *> volume_objects;
+ bool has_volume_objects = false;
+ foreach (Object *object, scene->objects) {
+ if (object->mesh->has_volume) {
+ if (bounds_valid) {
+ volume_objects.push_back(object);
+ }
+ has_volume_objects = true;
+ }
+ }
+
+ foreach (Object *object, scene->objects) {
+ if (object->mesh->has_volume) {
+ object_flag[object->index] |= SD_OBJECT_HAS_VOLUME;
+ object_flag[object->index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
+
+ foreach (Attribute &attr, object->mesh->attributes.attributes) {
+ if (attr.element == ATTR_ELEMENT_VOXEL) {
+ object_flag[object->index] |= SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
+ }
+ }
+ }
+ else {
+ object_flag[object->index] &= ~(SD_OBJECT_HAS_VOLUME | SD_OBJECT_HAS_VOLUME_ATTRIBUTES);
+ }
+ if (object->is_shadow_catcher) {
+ object_flag[object->index] |= SD_OBJECT_SHADOW_CATCHER;
+ }
+ else {
+ object_flag[object->index] &= ~SD_OBJECT_SHADOW_CATCHER;
+ }
+
+ if (bounds_valid) {
+ foreach (Object *volume_object, volume_objects) {
+ if (object == volume_object) {
+ continue;
+ }
+ if (object->bounds.intersects(volume_object->bounds)) {
+ object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
+ break;
+ }
+ }
+ }
+ else if (has_volume_objects) {
+ /* Not really valid, but can't make more reliable in the case
+ * of bounds not being up to date.
+ */
+ object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
+ }
+ }
+
+ /* Copy object flag. */
+ dscene->object_flag.copy_to_device();
}
void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene)
{
- if(dscene->objects.size() == 0) {
- return;
- }
+ if (dscene->objects.size() == 0) {
+ return;
+ }
- KernelObject *kobjects = dscene->objects.data();
+ KernelObject *kobjects = dscene->objects.data();
- bool update = false;
+ bool update = false;
- foreach(Object *object, scene->objects) {
- Mesh* mesh = object->mesh;
+ foreach (Object *object, scene->objects) {
+ Mesh *mesh = object->mesh;
- if(mesh->patch_table) {
- uint patch_map_offset = 2*(mesh->patch_table_offset + mesh->patch_table->total_size() -
- mesh->patch_table->num_nodes * PATCH_NODE_SIZE) - mesh->patch_offset;
+ if (mesh->patch_table) {
+ uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() -
+ mesh->patch_table->num_nodes * PATCH_NODE_SIZE) -
+ mesh->patch_offset;
- if(kobjects[object->index].patch_map_offset != patch_map_offset) {
- kobjects[object->index].patch_map_offset = patch_map_offset;
- update = true;
- }
- }
+ if (kobjects[object->index].patch_map_offset != patch_map_offset) {
+ kobjects[object->index].patch_map_offset = patch_map_offset;
+ update = true;
+ }
+ }
- if(kobjects[object->index].attribute_map_offset != mesh->attr_map_offset) {
- kobjects[object->index].attribute_map_offset = mesh->attr_map_offset;
- update = true;
- }
- }
+ if (kobjects[object->index].attribute_map_offset != mesh->attr_map_offset) {
+ kobjects[object->index].attribute_map_offset = mesh->attr_map_offset;
+ update = true;
+ }
+ }
- if(update) {
- dscene->objects.copy_to_device();
- }
+ if (update) {
+ dscene->objects.copy_to_device();
+ }
}
void ObjectManager::device_free(Device *, DeviceScene *dscene)
{
- dscene->objects.free();
- dscene->object_motion_pass.free();
- dscene->object_motion.free();
- dscene->object_flag.free();
+ dscene->objects.free();
+ dscene->object_motion_pass.free();
+ dscene->object_motion.free();
+ dscene->object_flag.free();
}
-void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress& progress)
+void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
{
- /* todo: normals and displacement should be done before applying transform! */
- /* todo: create objects/meshes in right order! */
-
- /* counter mesh users */
- map<Mesh*, int> mesh_users;
- Scene::MotionType need_motion = scene->need_motion();
- bool motion_blur = need_motion == Scene::MOTION_BLUR;
- bool apply_to_motion = need_motion != Scene::MOTION_PASS;
- int i = 0;
- bool have_instancing = false;
-
- foreach(Object *object, scene->objects) {
- map<Mesh*, int>::iterator it = mesh_users.find(object->mesh);
-
- if(it == mesh_users.end())
- mesh_users[object->mesh] = 1;
- else
- it->second++;
- }
-
- if(progress.get_cancel()) return;
-
- uint *object_flag = dscene->object_flag.data();
-
- /* apply transforms for objects with single user meshes */
- foreach(Object *object, scene->objects) {
- /* Annoying feedback loop here: we can't use is_instanced() because
- * it'll use uninitialized transform_applied flag.
- *
- * Could be solved by moving reference counter to Mesh.
- */
- if((mesh_users[object->mesh] == 1 && !object->mesh->has_surface_bssrdf) &&
- !object->mesh->has_true_displacement() && object->mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
- {
- if(!(motion_blur && object->use_motion())) {
- if(!object->mesh->transform_applied) {
- object->apply_transform(apply_to_motion);
- object->mesh->transform_applied = true;
-
- if(progress.get_cancel()) return;
- }
-
- object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
- if(object->mesh->transform_negative_scaled)
- object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
- }
- else
- have_instancing = true;
- }
- else
- have_instancing = true;
-
- i++;
- }
-
- dscene->data.bvh.have_instancing = have_instancing;
+ /* todo: normals and displacement should be done before applying transform! */
+ /* todo: create objects/meshes in right order! */
+
+ /* counter mesh users */
+ map<Mesh *, int> mesh_users;
+ Scene::MotionType need_motion = scene->need_motion();
+ bool motion_blur = need_motion == Scene::MOTION_BLUR;
+ bool apply_to_motion = need_motion != Scene::MOTION_PASS;
+ int i = 0;
+ bool have_instancing = false;
+
+ foreach (Object *object, scene->objects) {
+ map<Mesh *, int>::iterator it = mesh_users.find(object->mesh);
+
+ if (it == mesh_users.end())
+ mesh_users[object->mesh] = 1;
+ else
+ it->second++;
+ }
+
+ if (progress.get_cancel())
+ return;
+
+ uint *object_flag = dscene->object_flag.data();
+
+ /* apply transforms for objects with single user meshes */
+ foreach (Object *object, scene->objects) {
+ /* Annoying feedback loop here: we can't use is_instanced() because
+ * it'll use uninitialized transform_applied flag.
+ *
+ * Could be solved by moving reference counter to Mesh.
+ */
+ if ((mesh_users[object->mesh] == 1 && !object->mesh->has_surface_bssrdf) &&
+ !object->mesh->has_true_displacement() &&
+ object->mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
+ if (!(motion_blur && object->use_motion())) {
+ if (!object->mesh->transform_applied) {
+ object->apply_transform(apply_to_motion);
+ object->mesh->transform_applied = true;
+
+ if (progress.get_cancel())
+ return;
+ }
+
+ object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
+ if (object->mesh->transform_negative_scaled)
+ object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
+ }
+ else
+ have_instancing = true;
+ }
+ else
+ have_instancing = true;
+
+ i++;
+ }
+
+ dscene->data.bvh.have_instancing = have_instancing;
}
void ObjectManager::tag_update(Scene *scene)
{
- need_update = true;
- scene->curve_system_manager->need_update = true;
- scene->mesh_manager->need_update = true;
- scene->light_manager->need_update = true;
+ need_update = true;
+ scene->curve_system_manager->need_update = true;
+ scene->mesh_manager->need_update = true;
+ scene->light_manager->need_update = true;
}
string ObjectManager::get_cryptomatte_objects(Scene *scene)
{
- string manifest = "{";
-
- unordered_set<ustring, ustringHash> objects;
- foreach(Object *object, scene->objects) {
- if(objects.count(object->name)) {
- continue;
- }
- objects.insert(object->name);
- uint32_t hash_name = util_murmur_hash3(object->name.c_str(), object->name.length(), 0);
- manifest += string_printf("\"%s\":\"%08x\",", object->name.c_str(), hash_name);
- }
- manifest[manifest.size()-1] = '}';
- return manifest;
+ string manifest = "{";
+
+ unordered_set<ustring, ustringHash> objects;
+ foreach (Object *object, scene->objects) {
+ if (objects.count(object->name)) {
+ continue;
+ }
+ objects.insert(object->name);
+ uint32_t hash_name = util_murmur_hash3(object->name.c_str(), object->name.length(), 0);
+ manifest += string_printf("\"%s\":\"%08x\",", object->name.c_str(), hash_name);
+ }
+ manifest[manifest.size() - 1] = '}';
+ return manifest;
}
string ObjectManager::get_cryptomatte_assets(Scene *scene)
{
- string manifest = "{";
- unordered_set<ustring, ustringHash> assets;
- foreach(Object *ob, scene->objects) {
- if(assets.count(ob->asset_name)) {
- continue;
- }
- assets.insert(ob->asset_name);
- uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
- manifest += string_printf("\"%s\":\"%08x\",", ob->asset_name.c_str(), hash_asset);
- }
- manifest[manifest.size()-1] = '}';
- return manifest;
+ string manifest = "{";
+ unordered_set<ustring, ustringHash> assets;
+ foreach (Object *ob, scene->objects) {
+ if (assets.count(ob->asset_name)) {
+ continue;
+ }
+ assets.insert(ob->asset_name);
+ uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
+ manifest += string_printf("\"%s\":\"%08x\",", ob->asset_name.c_str(), hash_asset);
+ }
+ manifest[manifest.size() - 1] = '}';
+ return manifest;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 134f0bc3577..2fd43900da1 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -43,105 +43,101 @@ class ObjectManager;
/* Object */
class Object : public Node {
-public:
- NODE_DECLARE
-
- Mesh *mesh;
- Transform tfm;
- BoundBox bounds;
- uint random_id;
- int pass_id;
- ustring asset_name;
- vector<ParamValue> attributes;
- uint visibility;
- array<Transform> motion;
- bool hide_on_missing_motion;
- bool use_holdout;
- bool is_shadow_catcher;
-
- float3 dupli_generated;
- float2 dupli_uv;
-
- ParticleSystem *particle_system;
- int particle_index;
-
- Object();
- ~Object();
-
- void tag_update(Scene *scene);
-
- void compute_bounds(bool motion_blur);
- void apply_transform(bool apply_to_motion);
-
- /* Convert between normalized -1..1 motion time and index
- * in the motion array. */
- bool use_motion() const;
- float motion_time(int step) const;
- int motion_step(float time) const;
- void update_motion();
-
- /* Check whether object is traceable and it worth adding it to
- * kernel scene.
- */
- bool is_traceable() const;
-
- /* Combine object's visibility with all possible internal run-time
- * determined flags which denotes trace-time visibility.
- */
- uint visibility_for_tracing() const;
-
- /* Returns the index that is used in the kernel for this object. */
- int get_device_index() const;
-
-protected:
- /* Specifies the position of the object in scene->objects and
- * in the device vectors. Gets set in device_update. */
- int index;
-
- friend class ObjectManager;
+ public:
+ NODE_DECLARE
+
+ Mesh *mesh;
+ Transform tfm;
+ BoundBox bounds;
+ uint random_id;
+ int pass_id;
+ ustring asset_name;
+ vector<ParamValue> attributes;
+ uint visibility;
+ array<Transform> motion;
+ bool hide_on_missing_motion;
+ bool use_holdout;
+ bool is_shadow_catcher;
+
+ float3 dupli_generated;
+ float2 dupli_uv;
+
+ ParticleSystem *particle_system;
+ int particle_index;
+
+ Object();
+ ~Object();
+
+ void tag_update(Scene *scene);
+
+ void compute_bounds(bool motion_blur);
+ void apply_transform(bool apply_to_motion);
+
+ /* Convert between normalized -1..1 motion time and index
+ * in the motion array. */
+ bool use_motion() const;
+ float motion_time(int step) const;
+ int motion_step(float time) const;
+ void update_motion();
+
+ /* Check whether object is traceable and it worth adding it to
+ * kernel scene.
+ */
+ bool is_traceable() const;
+
+ /* Combine object's visibility with all possible internal run-time
+ * determined flags which denotes trace-time visibility.
+ */
+ uint visibility_for_tracing() const;
+
+ /* Returns the index that is used in the kernel for this object. */
+ int get_device_index() const;
+
+ protected:
+ /* Specifies the position of the object in scene->objects and
+ * in the device vectors. Gets set in device_update. */
+ int index;
+
+ friend class ObjectManager;
};
/* Object Manager */
class ObjectManager {
-public:
- bool need_update;
- bool need_flags_update;
-
- ObjectManager();
- ~ObjectManager();
-
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_update_transforms(DeviceScene *dscene,
- Scene *scene,
- Progress& progress);
-
- void device_update_flags(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress& progress,
- bool bounds_valid = true);
- void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene);
-
- void device_free(Device *device, DeviceScene *dscene);
-
- void tag_update(Scene *scene);
-
- void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress& progress);
-
- string get_cryptomatte_objects(Scene *scene);
- string get_cryptomatte_assets(Scene *scene);
-
-protected:
- void device_update_object_transform(UpdateObjectTransformState *state,
- Object *ob);
- void device_update_object_transform_task(UpdateObjectTransformState *state);
- bool device_update_object_transform_pop_work(
- UpdateObjectTransformState *state,
- int *start_index,
- int *num_objects);
+ public:
+ bool need_update;
+ bool need_flags_update;
+
+ ObjectManager();
+ ~ObjectManager();
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_update_transforms(DeviceScene *dscene, Scene *scene, Progress &progress);
+
+ void device_update_flags(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress,
+ bool bounds_valid = true);
+ void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene);
+
+ void device_free(Device *device, DeviceScene *dscene);
+
+ void tag_update(Scene *scene);
+
+ void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress);
+
+ string get_cryptomatte_objects(Scene *scene);
+ string get_cryptomatte_assets(Scene *scene);
+
+ protected:
+ void device_update_object_transform(UpdateObjectTransformState *state, Object *ob);
+ void device_update_object_transform_task(UpdateObjectTransformState *state);
+ bool device_update_object_transform_pop_work(UpdateObjectTransformState *state,
+ int *start_index,
+ int *num_objects);
};
CCL_NAMESPACE_END
-#endif /* __OBJECT_H__ */
+#endif /* __OBJECT_H__ */
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index c603dc69a16..b66a46938be 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -25,16 +25,16 @@
#ifdef WITH_OSL
-#include "kernel/osl/osl_globals.h"
-#include "kernel/osl/osl_services.h"
-#include "kernel/osl/osl_shader.h"
+# include "kernel/osl/osl_globals.h"
+# include "kernel/osl/osl_services.h"
+# include "kernel/osl/osl_shader.h"
-#include "util/util_foreach.h"
-#include "util/util_logging.h"
-#include "util/util_md5.h"
-#include "util/util_path.h"
-#include "util/util_progress.h"
-#include "util/util_projection.h"
+# include "util/util_foreach.h"
+# include "util/util_logging.h"
+# include "util/util_md5.h"
+# include "util/util_path.h"
+# include "util/util_progress.h"
+# include "util/util_projection.h"
#endif
@@ -58,1151 +58,1140 @@ thread_mutex OSLShaderManager::ss_mutex;
OSLShaderManager::OSLShaderManager()
{
- texture_system_init();
- shading_system_init();
+ texture_system_init();
+ shading_system_init();
}
OSLShaderManager::~OSLShaderManager()
{
- shading_system_free();
- texture_system_free();
+ shading_system_free();
+ texture_system_free();
}
void OSLShaderManager::free_memory()
{
-#ifdef OSL_HAS_BLENDER_CLEANUP_FIX
- /* There is a problem with llvm+osl: The order global destructors across
- * different compilation units run cannot be guaranteed, on windows this means
- * that the llvm destructors run before the osl destructors, causing a crash
- * when the process exits. the OSL in svn has a special cleanup hack to
- * sidestep this behavior */
- OSL::pvt::LLVM_Util::Cleanup();
-#endif
+# ifdef OSL_HAS_BLENDER_CLEANUP_FIX
+ /* There is a problem with llvm+osl: The order global destructors across
+ * different compilation units run cannot be guaranteed, on windows this means
+ * that the llvm destructors run before the osl destructors, causing a crash
+ * when the process exits. the OSL in svn has a special cleanup hack to
+ * sidestep this behavior */
+ OSL::pvt::LLVM_Util::Cleanup();
+# endif
}
void OSLShaderManager::reset(Scene * /*scene*/)
{
- shading_system_free();
- shading_system_init();
+ shading_system_free();
+ shading_system_init();
}
-void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+void OSLShaderManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
+ VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
- device_free(device, dscene, scene);
+ device_free(device, dscene, scene);
- /* determine which shaders are in use */
- device_update_shaders_used(scene);
+ /* determine which shaders are in use */
+ device_update_shaders_used(scene);
- /* create shaders */
- OSLGlobals *og = (OSLGlobals*)device->osl_memory();
+ /* create shaders */
+ OSLGlobals *og = (OSLGlobals *)device->osl_memory();
- foreach(Shader *shader, scene->shaders) {
- assert(shader->graph);
+ foreach (Shader *shader, scene->shaders) {
+ assert(shader->graph);
- if(progress.get_cancel()) return;
+ if (progress.get_cancel())
+ return;
- /* we can only compile one shader at the time as the OSL ShadingSytem
- * has a single state, but we put the lock here so different renders can
- * compile shaders alternating */
- thread_scoped_lock lock(ss_mutex);
+ /* we can only compile one shader at the time as the OSL ShadingSytem
+ * has a single state, but we put the lock here so different renders can
+ * compile shaders alternating */
+ thread_scoped_lock lock(ss_mutex);
- OSLCompiler compiler((void*)this, (void*)ss,
- scene->image_manager,
- scene->light_manager);
- compiler.background = (shader == scene->default_background);
- compiler.compile(scene, og, shader);
+ OSLCompiler compiler((void *)this, (void *)ss, scene->image_manager, scene->light_manager);
+ compiler.background = (shader == scene->default_background);
+ compiler.compile(scene, og, shader);
- if(shader->use_mis && shader->has_surface_emission)
- scene->light_manager->need_update = true;
- }
+ if (shader->use_mis && shader->has_surface_emission)
+ scene->light_manager->need_update = true;
+ }
- /* setup shader engine */
- og->ss = ss;
- og->ts = ts;
- og->services = services;
+ /* setup shader engine */
+ og->ss = ss;
+ og->ts = ts;
+ og->services = services;
- int background_id = scene->shader_manager->get_shader_id(scene->default_background);
- og->background_state = og->surface_state[background_id & SHADER_MASK];
- og->use = true;
+ int background_id = scene->shader_manager->get_shader_id(scene->default_background);
+ og->background_state = og->surface_state[background_id & SHADER_MASK];
+ og->use = true;
- foreach(Shader *shader, scene->shaders)
- shader->need_update = false;
+ foreach (Shader *shader, scene->shaders)
+ shader->need_update = false;
- need_update = false;
+ need_update = false;
- /* set texture system */
- scene->image_manager->set_osl_texture_system((void*)ts);
+ /* set texture system */
+ scene->image_manager->set_osl_texture_system((void *)ts);
- device_update_common(device, dscene, scene, progress);
+ device_update_common(device, dscene, scene, progress);
- {
- /* Perform greedyjit optimization.
- *
- * This might waste time on optimizing gorups which are never actually
- * used, but this prevents OSL from allocating data on TLS at render
- * time.
- *
- * This is much better for us because this way we aren't required to
- * stop task scheduler threads to make sure all TLS is clean and don't
- * have issues with TLS data free accessing freed memory if task scheduler
- * is being freed after the Session is freed.
- */
- thread_scoped_lock lock(ss_shared_mutex);
- ss->optimize_all_groups();
- }
+ {
+ /* Perform greedyjit optimization.
+ *
+ * This might waste time on optimizing gorups which are never actually
+ * used, but this prevents OSL from allocating data on TLS at render
+ * time.
+ *
+ * This is much better for us because this way we aren't required to
+ * stop task scheduler threads to make sure all TLS is clean and don't
+ * have issues with TLS data free accessing freed memory if task scheduler
+ * is being freed after the Session is freed.
+ */
+ thread_scoped_lock lock(ss_shared_mutex);
+ ss->optimize_all_groups();
+ }
}
void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
{
- OSLGlobals *og = (OSLGlobals*)device->osl_memory();
+ OSLGlobals *og = (OSLGlobals *)device->osl_memory();
- device_free_common(device, dscene, scene);
+ device_free_common(device, dscene, scene);
- /* clear shader engine */
- og->use = false;
- og->ss = NULL;
- og->ts = NULL;
+ /* clear shader engine */
+ og->use = false;
+ og->ss = NULL;
+ og->ts = NULL;
- og->surface_state.clear();
- og->volume_state.clear();
- og->displacement_state.clear();
- og->bump_state.clear();
- og->background_state.reset();
+ og->surface_state.clear();
+ og->volume_state.clear();
+ og->displacement_state.clear();
+ og->bump_state.clear();
+ og->background_state.reset();
}
void OSLShaderManager::texture_system_init()
{
- /* create texture system, shared between different renders to reduce memory usage */
- thread_scoped_lock lock(ts_shared_mutex);
+ /* create texture system, shared between different renders to reduce memory usage */
+ thread_scoped_lock lock(ts_shared_mutex);
- if(ts_shared_users == 0) {
- ts_shared = TextureSystem::create(true);
+ if (ts_shared_users == 0) {
+ ts_shared = TextureSystem::create(true);
- ts_shared->attribute("automip", 1);
- ts_shared->attribute("autotile", 64);
- ts_shared->attribute("gray_to_rgb", 1);
+ ts_shared->attribute("automip", 1);
+ ts_shared->attribute("autotile", 64);
+ ts_shared->attribute("gray_to_rgb", 1);
- /* effectively unlimited for now, until we support proper mipmap lookups */
- ts_shared->attribute("max_memory_MB", 16384);
- }
+ /* effectively unlimited for now, until we support proper mipmap lookups */
+ ts_shared->attribute("max_memory_MB", 16384);
+ }
- ts = ts_shared;
- ts_shared_users++;
+ ts = ts_shared;
+ ts_shared_users++;
}
void OSLShaderManager::texture_system_free()
{
- /* shared texture system decrease users and destroy if no longer used */
- thread_scoped_lock lock(ts_shared_mutex);
- ts_shared_users--;
+ /* shared texture system decrease users and destroy if no longer used */
+ thread_scoped_lock lock(ts_shared_mutex);
+ ts_shared_users--;
- if(ts_shared_users == 0) {
- ts_shared->invalidate_all(true);
- OSL::TextureSystem::destroy(ts_shared);
- ts_shared = NULL;
- }
+ if (ts_shared_users == 0) {
+ ts_shared->invalidate_all(true);
+ OSL::TextureSystem::destroy(ts_shared);
+ ts_shared = NULL;
+ }
- ts = NULL;
+ ts = NULL;
}
void OSLShaderManager::shading_system_init()
{
- /* create shading system, shared between different renders to reduce memory usage */
- thread_scoped_lock lock(ss_shared_mutex);
-
- if(ss_shared_users == 0) {
- services_shared = new OSLRenderServices();
-
- string shader_path = path_get("shader");
-#ifdef _WIN32
- /* Annoying thing, Cycles stores paths in UTF-8 codepage, so it can
- * operate with file paths with any character. This requires to use wide
- * char functions, but OSL uses old fashioned ANSI functions which means:
- *
- * - We have to convert our paths to ANSI before passing to OSL
- * - OSL can't be used when there's a multi-byte character in the path
- * to the shaders folder.
- */
- shader_path = string_to_ansi(shader_path);
-#endif
-
- ss_shared = new OSL::ShadingSystem(services_shared, ts_shared, &errhandler);
- ss_shared->attribute("lockgeom", 1);
- ss_shared->attribute("commonspace", "world");
- ss_shared->attribute("searchpath:shader", shader_path);
- ss_shared->attribute("greedyjit", 1);
-
- VLOG(1) << "Using shader search path: " << shader_path;
-
- /* our own ray types */
- static const char *raytypes[] = {
- "camera", /* PATH_RAY_CAMERA */
- "reflection", /* PATH_RAY_REFLECT */
- "refraction", /* PATH_RAY_TRANSMIT */
- "diffuse", /* PATH_RAY_DIFFUSE */
- "glossy", /* PATH_RAY_GLOSSY */
- "singular", /* PATH_RAY_SINGULAR */
- "transparent", /* PATH_RAY_TRANSPARENT */
-
- "shadow", /* PATH_RAY_SHADOW_OPAQUE_NON_CATCHER */
- "shadow", /* PATH_RAY_SHADOW_OPAQUE_CATCHER */
- "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER */
- "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_CATCHER */
-
- "__unused__",
- "volume_scatter", /* PATH_RAY_VOLUME_SCATTER */
- "__unused__",
-
- "__unused__",
- "diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- };
-
- const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]);
- ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
-
- OSLShader::register_closures((OSLShadingSystem*)ss_shared);
-
- loaded_shaders.clear();
- }
-
- ss = ss_shared;
- services = services_shared;
- ss_shared_users++;
+ /* create shading system, shared between different renders to reduce memory usage */
+ thread_scoped_lock lock(ss_shared_mutex);
+
+ if (ss_shared_users == 0) {
+ services_shared = new OSLRenderServices();
+
+ string shader_path = path_get("shader");
+# ifdef _WIN32
+ /* Annoying thing, Cycles stores paths in UTF-8 codepage, so it can
+ * operate with file paths with any character. This requires to use wide
+ * char functions, but OSL uses old fashioned ANSI functions which means:
+ *
+ * - We have to convert our paths to ANSI before passing to OSL
+ * - OSL can't be used when there's a multi-byte character in the path
+ * to the shaders folder.
+ */
+ shader_path = string_to_ansi(shader_path);
+# endif
+
+ ss_shared = new OSL::ShadingSystem(services_shared, ts_shared, &errhandler);
+ ss_shared->attribute("lockgeom", 1);
+ ss_shared->attribute("commonspace", "world");
+ ss_shared->attribute("searchpath:shader", shader_path);
+ ss_shared->attribute("greedyjit", 1);
+
+ VLOG(1) << "Using shader search path: " << shader_path;
+
+ /* our own ray types */
+ static const char *raytypes[] = {
+ "camera", /* PATH_RAY_CAMERA */
+ "reflection", /* PATH_RAY_REFLECT */
+ "refraction", /* PATH_RAY_TRANSMIT */
+ "diffuse", /* PATH_RAY_DIFFUSE */
+ "glossy", /* PATH_RAY_GLOSSY */
+ "singular", /* PATH_RAY_SINGULAR */
+ "transparent", /* PATH_RAY_TRANSPARENT */
+
+ "shadow", /* PATH_RAY_SHADOW_OPAQUE_NON_CATCHER */
+ "shadow", /* PATH_RAY_SHADOW_OPAQUE_CATCHER */
+ "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER */
+ "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_CATCHER */
+
+ "__unused__", "volume_scatter", /* PATH_RAY_VOLUME_SCATTER */
+ "__unused__",
+
+ "__unused__", "diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */
+ "__unused__", "__unused__", "__unused__", "__unused__",
+ "__unused__", "__unused__", "__unused__",
+ };
+
+ const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]);
+ ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
+
+ OSLShader::register_closures((OSLShadingSystem *)ss_shared);
+
+ loaded_shaders.clear();
+ }
+
+ ss = ss_shared;
+ services = services_shared;
+ ss_shared_users++;
}
void OSLShaderManager::shading_system_free()
{
- /* shared shading system decrease users and destroy if no longer used */
- thread_scoped_lock lock(ss_shared_mutex);
- ss_shared_users--;
+ /* shared shading system decrease users and destroy if no longer used */
+ thread_scoped_lock lock(ss_shared_mutex);
+ ss_shared_users--;
- if(ss_shared_users == 0) {
- delete ss_shared;
- ss_shared = NULL;
+ if (ss_shared_users == 0) {
+ delete ss_shared;
+ ss_shared = NULL;
- delete services_shared;
- services_shared = NULL;
- }
+ delete services_shared;
+ services_shared = NULL;
+ }
- ss = NULL;
- services = NULL;
+ ss = NULL;
+ services = NULL;
}
-bool OSLShaderManager::osl_compile(const string& inputfile, const string& outputfile)
+bool OSLShaderManager::osl_compile(const string &inputfile, const string &outputfile)
{
- vector<string> options;
- string stdosl_path;
- string shader_path = path_get("shader");
+ vector<string> options;
+ string stdosl_path;
+ string shader_path = path_get("shader");
- /* specify output file name */
- options.push_back("-o");
- options.push_back(outputfile);
+ /* specify output file name */
+ options.push_back("-o");
+ options.push_back(outputfile);
- /* specify standard include path */
- string include_path_arg = string("-I") + shader_path;
- options.push_back(include_path_arg);
+ /* specify standard include path */
+ string include_path_arg = string("-I") + shader_path;
+ options.push_back(include_path_arg);
- stdosl_path = path_get("shader/stdosl.h");
+ stdosl_path = path_get("shader/stdosl.h");
- /* compile */
- OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
- bool ok = compiler->compile(string_view(inputfile), options, string_view(stdosl_path));
- delete compiler;
+ /* compile */
+ OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
+ bool ok = compiler->compile(string_view(inputfile), options, string_view(stdosl_path));
+ delete compiler;
- return ok;
+ return ok;
}
-bool OSLShaderManager::osl_query(OSL::OSLQuery& query, const string& filepath)
+bool OSLShaderManager::osl_query(OSL::OSLQuery &query, const string &filepath)
{
- string searchpath = path_user_get("shaders");
- return query.open(filepath, searchpath);
+ string searchpath = path_user_get("shaders");
+ return query.open(filepath, searchpath);
}
-static string shader_filepath_hash(const string& filepath, uint64_t modified_time)
+static string shader_filepath_hash(const string &filepath, uint64_t modified_time)
{
- /* compute a hash from filepath and modified time to detect changes */
- MD5Hash md5;
- md5.append((const uint8_t*)filepath.c_str(), filepath.size());
- md5.append((const uint8_t*)&modified_time, sizeof(modified_time));
+ /* compute a hash from filepath and modified time to detect changes */
+ MD5Hash md5;
+ md5.append((const uint8_t *)filepath.c_str(), filepath.size());
+ md5.append((const uint8_t *)&modified_time, sizeof(modified_time));
- return md5.get_hex();
+ return md5.get_hex();
}
-const char *OSLShaderManager::shader_test_loaded(const string& hash)
+const char *OSLShaderManager::shader_test_loaded(const string &hash)
{
- map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
- return (it == loaded_shaders.end())? NULL: it->first.c_str();
+ map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
+ return (it == loaded_shaders.end()) ? NULL : it->first.c_str();
}
-OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string& hash)
+OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string &hash)
{
- map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
- return (it == loaded_shaders.end())? NULL: &it->second;
+ map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
+ return (it == loaded_shaders.end()) ? NULL : &it->second;
}
const char *OSLShaderManager::shader_load_filepath(string filepath)
{
- size_t len = filepath.size();
- string extension = filepath.substr(len - 4);
- uint64_t modified_time = path_modified_time(filepath);
-
- if(extension == ".osl") {
- /* .OSL File */
- string osopath = filepath.substr(0, len - 4) + ".oso";
- uint64_t oso_modified_time = path_modified_time(osopath);
-
- /* test if we have loaded the corresponding .OSO already */
- if(oso_modified_time != 0) {
- const char *hash = shader_test_loaded(shader_filepath_hash(osopath, oso_modified_time));
-
- if(hash)
- return hash;
- }
-
- /* autocompile .OSL to .OSO if needed */
- if(oso_modified_time == 0 || (oso_modified_time < modified_time)) {
- OSLShaderManager::osl_compile(filepath, osopath);
- modified_time = path_modified_time(osopath);
- }
- else
- modified_time = oso_modified_time;
-
- filepath = osopath;
- }
- else {
- if(extension == ".oso") {
- /* .OSO File, nothing to do */
- }
- else if(path_dirname(filepath) == "") {
- /* .OSO File in search path */
- filepath = path_join(path_user_get("shaders"), filepath + ".oso");
- }
- else {
- /* unknown file */
- return NULL;
- }
-
- /* test if we have loaded this .OSO already */
- const char *hash = shader_test_loaded(shader_filepath_hash(filepath, modified_time));
-
- if(hash)
- return hash;
- }
-
- /* read oso bytecode from file */
- string bytecode_hash = shader_filepath_hash(filepath, modified_time);
- string bytecode;
-
- if(!path_read_text(filepath, bytecode)) {
- fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str());
- OSLShaderInfo info;
- loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */
- return NULL;
- }
-
- return shader_load_bytecode(bytecode_hash, bytecode);
+ size_t len = filepath.size();
+ string extension = filepath.substr(len - 4);
+ uint64_t modified_time = path_modified_time(filepath);
+
+ if (extension == ".osl") {
+ /* .OSL File */
+ string osopath = filepath.substr(0, len - 4) + ".oso";
+ uint64_t oso_modified_time = path_modified_time(osopath);
+
+ /* test if we have loaded the corresponding .OSO already */
+ if (oso_modified_time != 0) {
+ const char *hash = shader_test_loaded(shader_filepath_hash(osopath, oso_modified_time));
+
+ if (hash)
+ return hash;
+ }
+
+ /* autocompile .OSL to .OSO if needed */
+ if (oso_modified_time == 0 || (oso_modified_time < modified_time)) {
+ OSLShaderManager::osl_compile(filepath, osopath);
+ modified_time = path_modified_time(osopath);
+ }
+ else
+ modified_time = oso_modified_time;
+
+ filepath = osopath;
+ }
+ else {
+ if (extension == ".oso") {
+ /* .OSO File, nothing to do */
+ }
+ else if (path_dirname(filepath) == "") {
+ /* .OSO File in search path */
+ filepath = path_join(path_user_get("shaders"), filepath + ".oso");
+ }
+ else {
+ /* unknown file */
+ return NULL;
+ }
+
+ /* test if we have loaded this .OSO already */
+ const char *hash = shader_test_loaded(shader_filepath_hash(filepath, modified_time));
+
+ if (hash)
+ return hash;
+ }
+
+ /* read oso bytecode from file */
+ string bytecode_hash = shader_filepath_hash(filepath, modified_time);
+ string bytecode;
+
+ if (!path_read_text(filepath, bytecode)) {
+ fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str());
+ OSLShaderInfo info;
+ loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */
+ return NULL;
+ }
+
+ return shader_load_bytecode(bytecode_hash, bytecode);
}
-const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode)
+const char *OSLShaderManager::shader_load_bytecode(const string &hash, const string &bytecode)
{
- ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str());
+ ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str());
- OSLShaderInfo info;
+ OSLShaderInfo info;
- if(!info.query.open_bytecode(bytecode)) {
- fprintf(stderr, "OSL query error: %s\n", info.query.geterror().c_str());
- }
+ if (!info.query.open_bytecode(bytecode)) {
+ fprintf(stderr, "OSL query error: %s\n", info.query.geterror().c_str());
+ }
- /* this is a bit weak, but works */
- info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos);
- info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos);
- info.has_surface_bssrdf = (bytecode.find("\"bssrdf\"") != string::npos);
+ /* this is a bit weak, but works */
+ info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos);
+ info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos);
+ info.has_surface_bssrdf = (bytecode.find("\"bssrdf\"") != string::npos);
- loaded_shaders[hash] = info;
+ loaded_shaders[hash] = info;
- return loaded_shaders.find(hash)->first.c_str();
+ return loaded_shaders.find(hash)->first.c_str();
}
-OSLNode *OSLShaderManager::osl_node(const std::string& filepath,
- const std::string& bytecode_hash,
- const std::string& bytecode)
+OSLNode *OSLShaderManager::osl_node(const std::string &filepath,
+ const std::string &bytecode_hash,
+ const std::string &bytecode)
{
- /* create query */
- const char *hash;
-
- if(!filepath.empty()) {
- hash = shader_load_filepath(filepath);
- }
- else {
- hash = shader_test_loaded(bytecode_hash);
- if(!hash)
- hash = shader_load_bytecode(bytecode_hash, bytecode);
- }
-
- if(!hash) {
- return NULL;
- }
-
- OSLShaderInfo *info = shader_loaded_info(hash);
-
- /* count number of inputs */
- size_t num_inputs = 0;
-
- for(int i = 0; i < info->query.nparams(); i++) {
- const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
-
- /* skip unsupported types */
- if(param->varlenarray || param->isstruct || param->type.arraylen > 1)
- continue;
-
- if(!param->isoutput)
- num_inputs++;
- }
-
- /* create node */
- OSLNode *node = OSLNode::create(num_inputs);
-
- /* add new sockets from parameters */
- set<void*> used_sockets;
-
- for(int i = 0; i < info->query.nparams(); i++) {
- const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
-
- /* skip unsupported types */
- if(param->varlenarray || param->isstruct || param->type.arraylen > 1)
- continue;
-
- SocketType::Type socket_type;
-
- if(param->isclosure) {
- socket_type = SocketType::CLOSURE;
- }
- else if(param->type.vecsemantics != TypeDesc::NOSEMANTICS) {
- if(param->type.vecsemantics == TypeDesc::COLOR)
- socket_type = SocketType::COLOR;
- else if(param->type.vecsemantics == TypeDesc::POINT)
- socket_type = SocketType::POINT;
- else if(param->type.vecsemantics == TypeDesc::VECTOR)
- socket_type = SocketType::VECTOR;
- else if(param->type.vecsemantics == TypeDesc::NORMAL)
- socket_type = SocketType::NORMAL;
- else
- continue;
-
- if(!param->isoutput && param->validdefault) {
- float3 *default_value = (float3*)node->input_default_value();
- default_value->x = param->fdefault[0];
- default_value->y = param->fdefault[1];
- default_value->z = param->fdefault[2];
- }
- }
- else if(param->type.aggregate == TypeDesc::SCALAR) {
- if(param->type.basetype == TypeDesc::INT) {
- socket_type = SocketType::INT;
-
- if(!param->isoutput && param->validdefault) {
- *(int*)node->input_default_value() = param->idefault[0];
- }
- }
- else if(param->type.basetype == TypeDesc::FLOAT) {
- socket_type = SocketType::FLOAT;
-
- if(!param->isoutput && param->validdefault) {
- *(float*)node->input_default_value() = param->fdefault[0];
- }
- }
- else if(param->type.basetype == TypeDesc::STRING) {
- socket_type = SocketType::STRING;
-
- if(!param->isoutput && param->validdefault) {
- *(ustring*)node->input_default_value() = param->sdefault[0];
- }
- }
- else
- continue;
- }
- else
- continue;
-
- if(param->isoutput) {
- node->add_output(param->name, socket_type);
- }
- else {
- node->add_input(param->name, socket_type);
- }
- }
-
- /* set bytcode hash or filepath */
- if(!bytecode_hash.empty()) {
- node->bytecode_hash = bytecode_hash;
- }
- else {
- node->filepath = filepath;
- }
-
- /* Generate inputs and outputs */
- node->create_inputs_outputs(node->type);
-
- return node;
+ /* create query */
+ const char *hash;
+
+ if (!filepath.empty()) {
+ hash = shader_load_filepath(filepath);
+ }
+ else {
+ hash = shader_test_loaded(bytecode_hash);
+ if (!hash)
+ hash = shader_load_bytecode(bytecode_hash, bytecode);
+ }
+
+ if (!hash) {
+ return NULL;
+ }
+
+ OSLShaderInfo *info = shader_loaded_info(hash);
+
+ /* count number of inputs */
+ size_t num_inputs = 0;
+
+ for (int i = 0; i < info->query.nparams(); i++) {
+ const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
+
+ /* skip unsupported types */
+ if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
+ continue;
+
+ if (!param->isoutput)
+ num_inputs++;
+ }
+
+ /* create node */
+ OSLNode *node = OSLNode::create(num_inputs);
+
+ /* add new sockets from parameters */
+ set<void *> used_sockets;
+
+ for (int i = 0; i < info->query.nparams(); i++) {
+ const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
+
+ /* skip unsupported types */
+ if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
+ continue;
+
+ SocketType::Type socket_type;
+
+ if (param->isclosure) {
+ socket_type = SocketType::CLOSURE;
+ }
+ else if (param->type.vecsemantics != TypeDesc::NOSEMANTICS) {
+ if (param->type.vecsemantics == TypeDesc::COLOR)
+ socket_type = SocketType::COLOR;
+ else if (param->type.vecsemantics == TypeDesc::POINT)
+ socket_type = SocketType::POINT;
+ else if (param->type.vecsemantics == TypeDesc::VECTOR)
+ socket_type = SocketType::VECTOR;
+ else if (param->type.vecsemantics == TypeDesc::NORMAL)
+ socket_type = SocketType::NORMAL;
+ else
+ continue;
+
+ if (!param->isoutput && param->validdefault) {
+ float3 *default_value = (float3 *)node->input_default_value();
+ default_value->x = param->fdefault[0];
+ default_value->y = param->fdefault[1];
+ default_value->z = param->fdefault[2];
+ }
+ }
+ else if (param->type.aggregate == TypeDesc::SCALAR) {
+ if (param->type.basetype == TypeDesc::INT) {
+ socket_type = SocketType::INT;
+
+ if (!param->isoutput && param->validdefault) {
+ *(int *)node->input_default_value() = param->idefault[0];
+ }
+ }
+ else if (param->type.basetype == TypeDesc::FLOAT) {
+ socket_type = SocketType::FLOAT;
+
+ if (!param->isoutput && param->validdefault) {
+ *(float *)node->input_default_value() = param->fdefault[0];
+ }
+ }
+ else if (param->type.basetype == TypeDesc::STRING) {
+ socket_type = SocketType::STRING;
+
+ if (!param->isoutput && param->validdefault) {
+ *(ustring *)node->input_default_value() = param->sdefault[0];
+ }
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+
+ if (param->isoutput) {
+ node->add_output(param->name, socket_type);
+ }
+ else {
+ node->add_input(param->name, socket_type);
+ }
+ }
+
+ /* set bytcode hash or filepath */
+ if (!bytecode_hash.empty()) {
+ node->bytecode_hash = bytecode_hash;
+ }
+ else {
+ node->filepath = filepath;
+ }
+
+ /* Generate inputs and outputs */
+ node->create_inputs_outputs(node->type);
+
+ return node;
}
/* Graph Compiler */
-OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_,
+OSLCompiler::OSLCompiler(void *manager_,
+ void *shadingsys_,
ImageManager *image_manager_,
LightManager *light_manager_)
{
- manager = manager_;
- shadingsys = shadingsys_;
- image_manager = image_manager_;
- light_manager = light_manager_;
- current_type = SHADER_TYPE_SURFACE;
- current_shader = NULL;
- background = false;
+ manager = manager_;
+ shadingsys = shadingsys_;
+ image_manager = image_manager_;
+ light_manager = light_manager_;
+ current_type = SHADER_TYPE_SURFACE;
+ current_shader = NULL;
+ background = false;
}
string OSLCompiler::id(ShaderNode *node)
{
- /* assign layer unique name based on pointer address + bump mode */
- stringstream stream;
- stream << "node_" << node->type->name << "_" << node;
+ /* assign layer unique name based on pointer address + bump mode */
+ stringstream stream;
+ stream << "node_" << node->type->name << "_" << node;
- return stream.str();
+ return stream.str();
}
string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input)
{
- string sname(input->name().string());
- size_t i;
-
- /* strip whitespace */
- while((i = sname.find(" ")) != string::npos)
- sname.replace(i, 1, "");
-
- /* if output exists with the same name, add "In" suffix */
- foreach(ShaderOutput *output, node->outputs) {
- if(input->name() == output->name()) {
- sname += "In";
- break;
- }
- }
-
- return sname;
+ string sname(input->name().string());
+ size_t i;
+
+ /* strip whitespace */
+ while ((i = sname.find(" ")) != string::npos)
+ sname.replace(i, 1, "");
+
+ /* if output exists with the same name, add "In" suffix */
+ foreach (ShaderOutput *output, node->outputs) {
+ if (input->name() == output->name()) {
+ sname += "In";
+ break;
+ }
+ }
+
+ return sname;
}
string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output)
{
- string sname(output->name().string());
- size_t i;
-
- /* strip whitespace */
- while((i = sname.find(" ")) != string::npos)
- sname.replace(i, 1, "");
-
- /* if input exists with the same name, add "Out" suffix */
- foreach(ShaderInput *input, node->inputs) {
- if(input->name() == output->name()) {
- sname += "Out";
- break;
- }
- }
-
- return sname;
+ string sname(output->name().string());
+ size_t i;
+
+ /* strip whitespace */
+ while ((i = sname.find(" ")) != string::npos)
+ sname.replace(i, 1, "");
+
+ /* if input exists with the same name, add "Out" suffix */
+ foreach (ShaderInput *input, node->inputs) {
+ if (input->name() == output->name()) {
+ sname += "Out";
+ break;
+ }
+ }
+
+ return sname;
}
bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
{
- /* exception for output node, only one input is actually used
- * depending on the current shader type */
-
- if(input->flags() & SocketType::SVM_INTERNAL)
- return true;
-
- if(node->special_type == SHADER_SPECIAL_TYPE_OUTPUT) {
- if(input->name() == "Surface" && current_type != SHADER_TYPE_SURFACE)
- return true;
- if(input->name() == "Volume" && current_type != SHADER_TYPE_VOLUME)
- return true;
- if(input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT)
- return true;
- if(input->name() == "Normal" && current_type != SHADER_TYPE_BUMP)
- return true;
- }
- else if(node->special_type == SHADER_SPECIAL_TYPE_BUMP) {
- if(input->name() == "Height")
- return true;
- }
- else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->special_type == SHADER_SPECIAL_TYPE_BUMP)
- return true;
-
- return false;
+ /* exception for output node, only one input is actually used
+ * depending on the current shader type */
+
+ if (input->flags() & SocketType::SVM_INTERNAL)
+ return true;
+
+ if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT) {
+ if (input->name() == "Surface" && current_type != SHADER_TYPE_SURFACE)
+ return true;
+ if (input->name() == "Volume" && current_type != SHADER_TYPE_VOLUME)
+ return true;
+ if (input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT)
+ return true;
+ if (input->name() == "Normal" && current_type != SHADER_TYPE_BUMP)
+ return true;
+ }
+ else if (node->special_type == SHADER_SPECIAL_TYPE_BUMP) {
+ if (input->name() == "Height")
+ return true;
+ }
+ else if (current_type == SHADER_TYPE_DISPLACEMENT && input->link &&
+ input->link->parent->special_type == SHADER_SPECIAL_TYPE_BUMP)
+ return true;
+
+ return false;
}
void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
-
- /* load filepath */
- if(isfilepath) {
- name = ((OSLShaderManager*)manager)->shader_load_filepath(name);
-
- if(name == NULL)
- return;
- }
-
- /* pass in fixed parameter values */
- foreach(ShaderInput *input, node->inputs) {
- if(!input->link) {
- /* checks to untangle graphs */
- if(node_skip_input(node, input))
- continue;
- /* already has default value assigned */
- else if(input->flags() & SocketType::DEFAULT_LINK_MASK)
- continue;
-
- string param_name = compatible_name(node, input);
- const SocketType& socket = input->socket_type;
- switch(input->type()) {
- case SocketType::COLOR:
- parameter_color(param_name.c_str(), node->get_float3(socket));
- break;
- case SocketType::POINT:
- parameter_point(param_name.c_str(), node->get_float3(socket));
- break;
- case SocketType::VECTOR:
- parameter_vector(param_name.c_str(), node->get_float3(socket));
- break;
- case SocketType::NORMAL:
- parameter_normal(param_name.c_str(), node->get_float3(socket));
- break;
- case SocketType::FLOAT:
- parameter(param_name.c_str(), node->get_float(socket));
- break;
- case SocketType::INT:
- parameter(param_name.c_str(), node->get_int(socket));
- break;
- case SocketType::STRING:
- parameter(param_name.c_str(), node->get_string(socket));
- break;
- case SocketType::CLOSURE:
- case SocketType::UNDEFINED:
- default:
- break;
- }
- }
- }
-
- /* create shader of the appropriate type. OSL only distinguishes between "surface"
- * and "displacement" atm */
- if(current_type == SHADER_TYPE_SURFACE)
- ss->Shader("surface", name, id(node).c_str());
- else if(current_type == SHADER_TYPE_VOLUME)
- ss->Shader("surface", name, id(node).c_str());
- else if(current_type == SHADER_TYPE_DISPLACEMENT)
- ss->Shader("displacement", name, id(node).c_str());
- else if(current_type == SHADER_TYPE_BUMP)
- ss->Shader("displacement", name, id(node).c_str());
- else
- assert(0);
-
- /* link inputs to other nodes */
- foreach(ShaderInput *input, node->inputs) {
- if(input->link) {
- if(node_skip_input(node, input))
- continue;
-
- /* connect shaders */
- string id_from = id(input->link->parent);
- string id_to = id(node);
- string param_from = compatible_name(input->link->parent, input->link);
- string param_to = compatible_name(node, input);
-
- ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str());
- }
- }
-
- /* test if we shader contains specific closures */
- OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name);
-
- if(current_type == SHADER_TYPE_SURFACE) {
- if(info) {
- if(info->has_surface_emission)
- current_shader->has_surface_emission = true;
- if(info->has_surface_transparent)
- current_shader->has_surface_transparent = true;
- if(info->has_surface_bssrdf) {
- current_shader->has_surface_bssrdf = true;
- current_shader->has_bssrdf_bump = true; /* can't detect yet */
- }
- current_shader->has_bump = true; /* can't detect yet */
- }
-
- if(node->has_spatial_varying()) {
- current_shader->has_surface_spatial_varying = true;
- }
- }
- else if(current_type == SHADER_TYPE_VOLUME) {
- if(node->has_spatial_varying())
- current_shader->has_volume_spatial_varying = true;
- }
-
- if(node->has_object_dependency()) {
- current_shader->has_object_dependency = true;
- }
-
- if(node->has_attribute_dependency()) {
- current_shader->has_attribute_dependency = true;
- }
-
- if(node->has_integrator_dependency()) {
- current_shader->has_integrator_dependency = true;
- }
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+
+ /* load filepath */
+ if (isfilepath) {
+ name = ((OSLShaderManager *)manager)->shader_load_filepath(name);
+
+ if (name == NULL)
+ return;
+ }
+
+ /* pass in fixed parameter values */
+ foreach (ShaderInput *input, node->inputs) {
+ if (!input->link) {
+ /* checks to untangle graphs */
+ if (node_skip_input(node, input))
+ continue;
+ /* already has default value assigned */
+ else if (input->flags() & SocketType::DEFAULT_LINK_MASK)
+ continue;
+
+ string param_name = compatible_name(node, input);
+ const SocketType &socket = input->socket_type;
+ switch (input->type()) {
+ case SocketType::COLOR:
+ parameter_color(param_name.c_str(), node->get_float3(socket));
+ break;
+ case SocketType::POINT:
+ parameter_point(param_name.c_str(), node->get_float3(socket));
+ break;
+ case SocketType::VECTOR:
+ parameter_vector(param_name.c_str(), node->get_float3(socket));
+ break;
+ case SocketType::NORMAL:
+ parameter_normal(param_name.c_str(), node->get_float3(socket));
+ break;
+ case SocketType::FLOAT:
+ parameter(param_name.c_str(), node->get_float(socket));
+ break;
+ case SocketType::INT:
+ parameter(param_name.c_str(), node->get_int(socket));
+ break;
+ case SocketType::STRING:
+ parameter(param_name.c_str(), node->get_string(socket));
+ break;
+ case SocketType::CLOSURE:
+ case SocketType::UNDEFINED:
+ default:
+ break;
+ }
+ }
+ }
+
+ /* create shader of the appropriate type. OSL only distinguishes between "surface"
+ * and "displacement" atm */
+ if (current_type == SHADER_TYPE_SURFACE)
+ ss->Shader("surface", name, id(node).c_str());
+ else if (current_type == SHADER_TYPE_VOLUME)
+ ss->Shader("surface", name, id(node).c_str());
+ else if (current_type == SHADER_TYPE_DISPLACEMENT)
+ ss->Shader("displacement", name, id(node).c_str());
+ else if (current_type == SHADER_TYPE_BUMP)
+ ss->Shader("displacement", name, id(node).c_str());
+ else
+ assert(0);
+
+ /* link inputs to other nodes */
+ foreach (ShaderInput *input, node->inputs) {
+ if (input->link) {
+ if (node_skip_input(node, input))
+ continue;
+
+ /* connect shaders */
+ string id_from = id(input->link->parent);
+ string id_to = id(node);
+ string param_from = compatible_name(input->link->parent, input->link);
+ string param_to = compatible_name(node, input);
+
+ ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str());
+ }
+ }
+
+ /* test if we shader contains specific closures */
+ OSLShaderInfo *info = ((OSLShaderManager *)manager)->shader_loaded_info(name);
+
+ if (current_type == SHADER_TYPE_SURFACE) {
+ if (info) {
+ if (info->has_surface_emission)
+ current_shader->has_surface_emission = true;
+ if (info->has_surface_transparent)
+ current_shader->has_surface_transparent = true;
+ if (info->has_surface_bssrdf) {
+ current_shader->has_surface_bssrdf = true;
+ current_shader->has_bssrdf_bump = true; /* can't detect yet */
+ }
+ current_shader->has_bump = true; /* can't detect yet */
+ }
+
+ if (node->has_spatial_varying()) {
+ current_shader->has_surface_spatial_varying = true;
+ }
+ }
+ else if (current_type == SHADER_TYPE_VOLUME) {
+ if (node->has_spatial_varying())
+ current_shader->has_volume_spatial_varying = true;
+ }
+
+ if (node->has_object_dependency()) {
+ current_shader->has_object_dependency = true;
+ }
+
+ if (node->has_attribute_dependency()) {
+ current_shader->has_attribute_dependency = true;
+ }
+
+ if (node->has_integrator_dependency()) {
+ current_shader->has_integrator_dependency = true;
+ }
}
static TypeDesc array_typedesc(TypeDesc typedesc, int arraylength)
{
- return TypeDesc((TypeDesc::BASETYPE)typedesc.basetype,
- (TypeDesc::AGGREGATE)typedesc.aggregate,
- (TypeDesc::VECSEMANTICS)typedesc.vecsemantics,
- arraylength);
+ return TypeDesc((TypeDesc::BASETYPE)typedesc.basetype,
+ (TypeDesc::AGGREGATE)typedesc.aggregate,
+ (TypeDesc::VECSEMANTICS)typedesc.vecsemantics,
+ arraylength);
}
-void OSLCompiler::parameter(ShaderNode* node, const char *name)
+void OSLCompiler::parameter(ShaderNode *node, const char *name)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ustring uname = ustring(name);
- const SocketType& socket = *(node->type->find_input(uname));
-
- switch(socket.type)
- {
- case SocketType::BOOLEAN:
- {
- int value = node->get_bool(socket);
- ss->Parameter(name, TypeDesc::TypeInt, &value);
- break;
- }
- case SocketType::FLOAT:
- {
- float value = node->get_float(socket);
- ss->Parameter(uname, TypeDesc::TypeFloat, &value);
- break;
- }
- case SocketType::INT:
- {
- int value = node->get_int(socket);
- ss->Parameter(uname, TypeDesc::TypeInt, &value);
- break;
- }
- case SocketType::COLOR:
- {
- float3 value = node->get_float3(socket);
- ss->Parameter(uname, TypeDesc::TypeColor, &value);
- break;
- }
- case SocketType::VECTOR:
- {
- float3 value = node->get_float3(socket);
- ss->Parameter(uname, TypeDesc::TypeVector, &value);
- break;
- }
- case SocketType::POINT:
- {
- float3 value = node->get_float3(socket);
- ss->Parameter(uname, TypeDesc::TypePoint, &value);
- break;
- }
- case SocketType::NORMAL:
- {
- float3 value = node->get_float3(socket);
- ss->Parameter(uname, TypeDesc::TypeNormal, &value);
- break;
- }
- case SocketType::POINT2:
- {
- float2 value = node->get_float2(socket);
- ss->Parameter(uname, TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), &value);
- break;
- }
- case SocketType::STRING:
- {
- ustring value = node->get_string(socket);
- ss->Parameter(uname, TypeDesc::TypeString, &value);
- break;
- }
- case SocketType::ENUM:
- {
- ustring value = node->get_string(socket);
- ss->Parameter(uname, TypeDesc::TypeString, &value);
- break;
- }
- case SocketType::TRANSFORM:
- {
- Transform value = node->get_transform(socket);
- ProjectionTransform projection(value);
- projection = projection_transpose(projection);
- ss->Parameter(uname, TypeDesc::TypeMatrix, &projection);
- break;
- }
- case SocketType::BOOLEAN_ARRAY:
- {
- // OSL does not support booleans, so convert to int
- const array<bool>& value = node->get_bool_array(socket);
- array<int> intvalue(value.size());
- for(size_t i = 0; i < value.size(); i++)
- intvalue[i] = value[i];
- ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), intvalue.data());
- break;
- }
- case SocketType::FLOAT_ARRAY:
- {
- const array<float>& value = node->get_float_array(socket);
- ss->Parameter(uname, array_typedesc(TypeDesc::TypeFloat, value.size()), value.data());
- break;
- }
- case SocketType::INT_ARRAY:
- {
- const array<int>& value = node->get_int_array(socket);
- ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), value.data());
- break;
- }
- case SocketType::COLOR_ARRAY:
- case SocketType::VECTOR_ARRAY:
- case SocketType::POINT_ARRAY:
- case SocketType::NORMAL_ARRAY:
- {
- TypeDesc typedesc;
-
- switch(socket.type)
- {
- case SocketType::COLOR_ARRAY: typedesc = TypeDesc::TypeColor; break;
- case SocketType::VECTOR_ARRAY: typedesc = TypeDesc::TypeVector; break;
- case SocketType::POINT_ARRAY: typedesc = TypeDesc::TypePoint; break;
- case SocketType::NORMAL_ARRAY: typedesc = TypeDesc::TypeNormal; break;
- default: assert(0); break;
- }
-
- // convert to tightly packed array since float3 has padding
- const array<float3>& value = node->get_float3_array(socket);
- array<float> fvalue(value.size() * 3);
- for(size_t i = 0, j = 0; i < value.size(); i++) {
- fvalue[j++] = value[i].x;
- fvalue[j++] = value[i].y;
- fvalue[j++] = value[i].z;
- }
-
- ss->Parameter(uname, array_typedesc(typedesc, value.size()), fvalue.data());
- break;
- }
- case SocketType::POINT2_ARRAY:
- {
- const array<float2>& value = node->get_float2_array(socket);
- ss->Parameter(uname, array_typedesc(TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), value.size()), value.data());
- break;
- }
- case SocketType::STRING_ARRAY:
- {
- const array<ustring>& value = node->get_string_array(socket);
- ss->Parameter(uname, array_typedesc(TypeDesc::TypeString, value.size()), value.data());
- break;
- }
- case SocketType::TRANSFORM_ARRAY:
- {
- const array<Transform>& value = node->get_transform_array(socket);
- array<ProjectionTransform> fvalue(value.size());
- for(size_t i = 0; i < value.size(); i++) {
- fvalue[i] = projection_transpose(ProjectionTransform(value[i]));
- }
- ss->Parameter(uname, array_typedesc(TypeDesc::TypeMatrix, fvalue.size()), fvalue.data());
- break;
- }
- case SocketType::CLOSURE:
- case SocketType::NODE:
- case SocketType::NODE_ARRAY:
- case SocketType::UNDEFINED:
- case SocketType::UINT:
- {
- assert(0);
- break;
- }
- }
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ustring uname = ustring(name);
+ const SocketType &socket = *(node->type->find_input(uname));
+
+ switch (socket.type) {
+ case SocketType::BOOLEAN: {
+ int value = node->get_bool(socket);
+ ss->Parameter(name, TypeDesc::TypeInt, &value);
+ break;
+ }
+ case SocketType::FLOAT: {
+ float value = node->get_float(socket);
+ ss->Parameter(uname, TypeDesc::TypeFloat, &value);
+ break;
+ }
+ case SocketType::INT: {
+ int value = node->get_int(socket);
+ ss->Parameter(uname, TypeDesc::TypeInt, &value);
+ break;
+ }
+ case SocketType::COLOR: {
+ float3 value = node->get_float3(socket);
+ ss->Parameter(uname, TypeDesc::TypeColor, &value);
+ break;
+ }
+ case SocketType::VECTOR: {
+ float3 value = node->get_float3(socket);
+ ss->Parameter(uname, TypeDesc::TypeVector, &value);
+ break;
+ }
+ case SocketType::POINT: {
+ float3 value = node->get_float3(socket);
+ ss->Parameter(uname, TypeDesc::TypePoint, &value);
+ break;
+ }
+ case SocketType::NORMAL: {
+ float3 value = node->get_float3(socket);
+ ss->Parameter(uname, TypeDesc::TypeNormal, &value);
+ break;
+ }
+ case SocketType::POINT2: {
+ float2 value = node->get_float2(socket);
+ ss->Parameter(uname, TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), &value);
+ break;
+ }
+ case SocketType::STRING: {
+ ustring value = node->get_string(socket);
+ ss->Parameter(uname, TypeDesc::TypeString, &value);
+ break;
+ }
+ case SocketType::ENUM: {
+ ustring value = node->get_string(socket);
+ ss->Parameter(uname, TypeDesc::TypeString, &value);
+ break;
+ }
+ case SocketType::TRANSFORM: {
+ Transform value = node->get_transform(socket);
+ ProjectionTransform projection(value);
+ projection = projection_transpose(projection);
+ ss->Parameter(uname, TypeDesc::TypeMatrix, &projection);
+ break;
+ }
+ case SocketType::BOOLEAN_ARRAY: {
+ // OSL does not support booleans, so convert to int
+ const array<bool> &value = node->get_bool_array(socket);
+ array<int> intvalue(value.size());
+ for (size_t i = 0; i < value.size(); i++)
+ intvalue[i] = value[i];
+ ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), intvalue.data());
+ break;
+ }
+ case SocketType::FLOAT_ARRAY: {
+ const array<float> &value = node->get_float_array(socket);
+ ss->Parameter(uname, array_typedesc(TypeDesc::TypeFloat, value.size()), value.data());
+ break;
+ }
+ case SocketType::INT_ARRAY: {
+ const array<int> &value = node->get_int_array(socket);
+ ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), value.data());
+ break;
+ }
+ case SocketType::COLOR_ARRAY:
+ case SocketType::VECTOR_ARRAY:
+ case SocketType::POINT_ARRAY:
+ case SocketType::NORMAL_ARRAY: {
+ TypeDesc typedesc;
+
+ switch (socket.type) {
+ case SocketType::COLOR_ARRAY:
+ typedesc = TypeDesc::TypeColor;
+ break;
+ case SocketType::VECTOR_ARRAY:
+ typedesc = TypeDesc::TypeVector;
+ break;
+ case SocketType::POINT_ARRAY:
+ typedesc = TypeDesc::TypePoint;
+ break;
+ case SocketType::NORMAL_ARRAY:
+ typedesc = TypeDesc::TypeNormal;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ // convert to tightly packed array since float3 has padding
+ const array<float3> &value = node->get_float3_array(socket);
+ array<float> fvalue(value.size() * 3);
+ for (size_t i = 0, j = 0; i < value.size(); i++) {
+ fvalue[j++] = value[i].x;
+ fvalue[j++] = value[i].y;
+ fvalue[j++] = value[i].z;
+ }
+
+ ss->Parameter(uname, array_typedesc(typedesc, value.size()), fvalue.data());
+ break;
+ }
+ case SocketType::POINT2_ARRAY: {
+ const array<float2> &value = node->get_float2_array(socket);
+ ss->Parameter(
+ uname,
+ array_typedesc(TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), value.size()),
+ value.data());
+ break;
+ }
+ case SocketType::STRING_ARRAY: {
+ const array<ustring> &value = node->get_string_array(socket);
+ ss->Parameter(uname, array_typedesc(TypeDesc::TypeString, value.size()), value.data());
+ break;
+ }
+ case SocketType::TRANSFORM_ARRAY: {
+ const array<Transform> &value = node->get_transform_array(socket);
+ array<ProjectionTransform> fvalue(value.size());
+ for (size_t i = 0; i < value.size(); i++) {
+ fvalue[i] = projection_transpose(ProjectionTransform(value[i]));
+ }
+ ss->Parameter(uname, array_typedesc(TypeDesc::TypeMatrix, fvalue.size()), fvalue.data());
+ break;
+ }
+ case SocketType::CLOSURE:
+ case SocketType::NODE:
+ case SocketType::NODE_ARRAY:
+ case SocketType::UNDEFINED:
+ case SocketType::UINT: {
+ assert(0);
+ break;
+ }
+ }
}
void OSLCompiler::parameter(const char *name, float f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ss->Parameter(name, TypeDesc::TypeFloat, &f);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ss->Parameter(name, TypeDesc::TypeFloat, &f);
}
void OSLCompiler::parameter_color(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ss->Parameter(name, TypeDesc::TypeColor, &f);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ss->Parameter(name, TypeDesc::TypeColor, &f);
}
void OSLCompiler::parameter_point(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ss->Parameter(name, TypeDesc::TypePoint, &f);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ss->Parameter(name, TypeDesc::TypePoint, &f);
}
void OSLCompiler::parameter_normal(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ss->Parameter(name, TypeDesc::TypeNormal, &f);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ss->Parameter(name, TypeDesc::TypeNormal, &f);
}
void OSLCompiler::parameter_vector(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ss->Parameter(name, TypeDesc::TypeVector, &f);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ss->Parameter(name, TypeDesc::TypeVector, &f);
}
void OSLCompiler::parameter(const char *name, int f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ss->Parameter(name, TypeDesc::TypeInt, &f);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ss->Parameter(name, TypeDesc::TypeInt, &f);
}
void OSLCompiler::parameter(const char *name, const char *s)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ss->Parameter(name, TypeDesc::TypeString, &s);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ss->Parameter(name, TypeDesc::TypeString, &s);
}
void OSLCompiler::parameter(const char *name, ustring s)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- const char *str = s.c_str();
- ss->Parameter(name, TypeDesc::TypeString, &str);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ const char *str = s.c_str();
+ ss->Parameter(name, TypeDesc::TypeString, &str);
}
-void OSLCompiler::parameter(const char *name, const Transform& tfm)
+void OSLCompiler::parameter(const char *name, const Transform &tfm)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ProjectionTransform projection(tfm);
- projection = projection_transpose(projection);
- ss->Parameter(name, TypeDesc::TypeMatrix, (float*)&projection);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ ProjectionTransform projection(tfm);
+ projection = projection_transpose(projection);
+ ss->Parameter(name, TypeDesc::TypeMatrix, (float *)&projection);
}
void OSLCompiler::parameter_array(const char *name, const float f[], int arraylen)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- TypeDesc type = TypeDesc::TypeFloat;
- type.arraylen = arraylen;
- ss->Parameter(name, type, f);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ TypeDesc type = TypeDesc::TypeFloat;
+ type.arraylen = arraylen;
+ ss->Parameter(name, type, f);
}
-void OSLCompiler::parameter_color_array(const char *name, const array<float3>& f)
+void OSLCompiler::parameter_color_array(const char *name, const array<float3> &f)
{
- /* NB: cycles float3 type is actually 4 floats! need to use an explicit array */
- array<float[3]> table(f.size());
-
- for(int i = 0; i < f.size(); ++i) {
- table[i][0] = f[i].x;
- table[i][1] = f[i].y;
- table[i][2] = f[i].z;
- }
-
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- TypeDesc type = TypeDesc::TypeColor;
- type.arraylen = table.size();
- ss->Parameter(name, type, table.data());
+ /* NB: cycles float3 type is actually 4 floats! need to use an explicit array */
+ array<float[3]> table(f.size());
+
+ for (int i = 0; i < f.size(); ++i) {
+ table[i][0] = f[i].x;
+ table[i][1] = f[i].y;
+ table[i][2] = f[i].z;
+ }
+
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+ TypeDesc type = TypeDesc::TypeColor;
+ type.arraylen = table.size();
+ ss->Parameter(name, type, table.data());
}
void OSLCompiler::parameter_attribute(const char *name, ustring s)
{
- if(Attribute::name_standard(s.c_str()))
- parameter(name, (string("geom:") + s.c_str()).c_str());
- else
- parameter(name, s.c_str());
+ if (Attribute::name_standard(s.c_str()))
+ parameter(name, (string("geom:") + s.c_str()).c_str());
+ else
+ parameter(name, s.c_str());
}
-void OSLCompiler::find_dependencies(ShaderNodeSet& dependencies, ShaderInput *input)
+void OSLCompiler::find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input)
{
- ShaderNode *node = (input->link)? input->link->parent: NULL;
+ ShaderNode *node = (input->link) ? input->link->parent : NULL;
- if(node != NULL && dependencies.find(node) == dependencies.end()) {
- foreach(ShaderInput *in, node->inputs)
- if(!node_skip_input(node, in))
- find_dependencies(dependencies, in);
+ if (node != NULL && dependencies.find(node) == dependencies.end()) {
+ foreach (ShaderInput *in, node->inputs)
+ if (!node_skip_input(node, in))
+ find_dependencies(dependencies, in);
- dependencies.insert(node);
- }
+ dependencies.insert(node);
+ }
}
-void OSLCompiler::generate_nodes(const ShaderNodeSet& nodes)
+void OSLCompiler::generate_nodes(const ShaderNodeSet &nodes)
{
- ShaderNodeSet done;
- bool nodes_done;
-
- do {
- nodes_done = true;
-
- foreach(ShaderNode *node, nodes) {
- if(done.find(node) == done.end()) {
- bool inputs_done = true;
-
- foreach(ShaderInput *input, node->inputs)
- if(!node_skip_input(node, input))
- if(input->link && done.find(input->link->parent) == done.end())
- inputs_done = false;
-
- if(inputs_done) {
- node->compile(*this);
- done.insert(node);
-
- if(current_type == SHADER_TYPE_SURFACE) {
- if(node->has_surface_emission())
- current_shader->has_surface_emission = true;
- if(node->has_surface_transparent())
- current_shader->has_surface_transparent = true;
- if(node->has_spatial_varying())
- current_shader->has_surface_spatial_varying = true;
- if(node->has_surface_bssrdf()) {
- current_shader->has_surface_bssrdf = true;
- if(node->has_bssrdf_bump())
- current_shader->has_bssrdf_bump = true;
- }
- if(node->has_bump()) {
- current_shader->has_bump = true;
- }
- }
- else if(current_type == SHADER_TYPE_VOLUME) {
- if(node->has_spatial_varying())
- current_shader->has_volume_spatial_varying = true;
- }
- }
- else
- nodes_done = false;
- }
- }
- } while(!nodes_done);
+ ShaderNodeSet done;
+ bool nodes_done;
+
+ do {
+ nodes_done = true;
+
+ foreach (ShaderNode *node, nodes) {
+ if (done.find(node) == done.end()) {
+ bool inputs_done = true;
+
+ foreach (ShaderInput *input, node->inputs)
+ if (!node_skip_input(node, input))
+ if (input->link && done.find(input->link->parent) == done.end())
+ inputs_done = false;
+
+ if (inputs_done) {
+ node->compile(*this);
+ done.insert(node);
+
+ if (current_type == SHADER_TYPE_SURFACE) {
+ if (node->has_surface_emission())
+ current_shader->has_surface_emission = true;
+ if (node->has_surface_transparent())
+ current_shader->has_surface_transparent = true;
+ if (node->has_spatial_varying())
+ current_shader->has_surface_spatial_varying = true;
+ if (node->has_surface_bssrdf()) {
+ current_shader->has_surface_bssrdf = true;
+ if (node->has_bssrdf_bump())
+ current_shader->has_bssrdf_bump = true;
+ }
+ if (node->has_bump()) {
+ current_shader->has_bump = true;
+ }
+ }
+ else if (current_type == SHADER_TYPE_VOLUME) {
+ if (node->has_spatial_varying())
+ current_shader->has_volume_spatial_varying = true;
+ }
+ }
+ else
+ nodes_done = false;
+ }
+ }
+ } while (!nodes_done);
}
OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
-
- current_type = type;
-
- OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->name.c_str());
-
- ShaderNode *output = graph->output();
- ShaderNodeSet dependencies;
-
- if(type == SHADER_TYPE_SURFACE) {
- /* generate surface shader */
- find_dependencies(dependencies, output->input("Surface"));
- generate_nodes(dependencies);
- output->compile(*this);
- }
- else if(type == SHADER_TYPE_BUMP) {
- /* generate bump shader */
- find_dependencies(dependencies, output->input("Normal"));
- generate_nodes(dependencies);
- output->compile(*this);
- }
- else if(type == SHADER_TYPE_VOLUME) {
- /* generate volume shader */
- find_dependencies(dependencies, output->input("Volume"));
- generate_nodes(dependencies);
- output->compile(*this);
- }
- else if(type == SHADER_TYPE_DISPLACEMENT) {
- /* generate displacement shader */
- find_dependencies(dependencies, output->input("Displacement"));
- generate_nodes(dependencies);
- output->compile(*this);
- }
- else
- assert(0);
-
- ss->ShaderGroupEnd();
-
- return group;
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
+
+ current_type = type;
+
+ OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->name.c_str());
+
+ ShaderNode *output = graph->output();
+ ShaderNodeSet dependencies;
+
+ if (type == SHADER_TYPE_SURFACE) {
+ /* generate surface shader */
+ find_dependencies(dependencies, output->input("Surface"));
+ generate_nodes(dependencies);
+ output->compile(*this);
+ }
+ else if (type == SHADER_TYPE_BUMP) {
+ /* generate bump shader */
+ find_dependencies(dependencies, output->input("Normal"));
+ generate_nodes(dependencies);
+ output->compile(*this);
+ }
+ else if (type == SHADER_TYPE_VOLUME) {
+ /* generate volume shader */
+ find_dependencies(dependencies, output->input("Volume"));
+ generate_nodes(dependencies);
+ output->compile(*this);
+ }
+ else if (type == SHADER_TYPE_DISPLACEMENT) {
+ /* generate displacement shader */
+ find_dependencies(dependencies, output->input("Displacement"));
+ generate_nodes(dependencies);
+ output->compile(*this);
+ }
+ else
+ assert(0);
+
+ ss->ShaderGroupEnd();
+
+ return group;
}
void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader)
{
- if(shader->need_update) {
- ShaderGraph *graph = shader->graph;
- ShaderNode *output = (graph)? graph->output(): NULL;
-
- bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
- output->input("Surface")->link && output->input("Displacement")->link;
-
- /* finalize */
- shader->graph->finalize(scene,
- has_bump,
- shader->has_integrator_dependency,
- shader->displacement_method == DISPLACE_BOTH);
-
- current_shader = shader;
-
- shader->has_surface = false;
- shader->has_surface_emission = false;
- shader->has_surface_transparent = false;
- shader->has_surface_bssrdf = false;
- shader->has_bump = has_bump;
- shader->has_bssrdf_bump = has_bump;
- shader->has_volume = false;
- shader->has_displacement = false;
- shader->has_surface_spatial_varying = false;
- shader->has_volume_spatial_varying = false;
- shader->has_object_dependency = false;
- shader->has_attribute_dependency = false;
- shader->has_integrator_dependency = false;
-
- /* generate surface shader */
- if(shader->used && graph && output->input("Surface")->link) {
- shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
-
- if(has_bump)
- shader->osl_surface_bump_ref = compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
- else
- shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
-
- shader->has_surface = true;
- }
- else {
- shader->osl_surface_ref = OSL::ShaderGroupRef();
- shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
- }
-
- /* generate volume shader */
- if(shader->used && graph && output->input("Volume")->link) {
- shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
- shader->has_volume = true;
- }
- else
- shader->osl_volume_ref = OSL::ShaderGroupRef();
-
- /* generate displacement shader */
- if(shader->used && graph && output->input("Displacement")->link) {
- shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
- shader->has_displacement = true;
- }
- else
- shader->osl_displacement_ref = OSL::ShaderGroupRef();
- }
-
- /* push state to array for lookup */
- og->surface_state.push_back(shader->osl_surface_ref);
- og->volume_state.push_back(shader->osl_volume_ref);
- og->displacement_state.push_back(shader->osl_displacement_ref);
- og->bump_state.push_back(shader->osl_surface_bump_ref);
+ if (shader->need_update) {
+ ShaderGraph *graph = shader->graph;
+ ShaderNode *output = (graph) ? graph->output() : NULL;
+
+ bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
+ output->input("Surface")->link && output->input("Displacement")->link;
+
+ /* finalize */
+ shader->graph->finalize(scene,
+ has_bump,
+ shader->has_integrator_dependency,
+ shader->displacement_method == DISPLACE_BOTH);
+
+ current_shader = shader;
+
+ shader->has_surface = false;
+ shader->has_surface_emission = false;
+ shader->has_surface_transparent = false;
+ shader->has_surface_bssrdf = false;
+ shader->has_bump = has_bump;
+ shader->has_bssrdf_bump = has_bump;
+ shader->has_volume = false;
+ shader->has_displacement = false;
+ shader->has_surface_spatial_varying = false;
+ shader->has_volume_spatial_varying = false;
+ shader->has_object_dependency = false;
+ shader->has_attribute_dependency = false;
+ shader->has_integrator_dependency = false;
+
+ /* generate surface shader */
+ if (shader->used && graph && output->input("Surface")->link) {
+ shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
+
+ if (has_bump)
+ shader->osl_surface_bump_ref = compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
+ else
+ shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
+
+ shader->has_surface = true;
+ }
+ else {
+ shader->osl_surface_ref = OSL::ShaderGroupRef();
+ shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
+ }
+
+ /* generate volume shader */
+ if (shader->used && graph && output->input("Volume")->link) {
+ shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
+ shader->has_volume = true;
+ }
+ else
+ shader->osl_volume_ref = OSL::ShaderGroupRef();
+
+ /* generate displacement shader */
+ if (shader->used && graph && output->input("Displacement")->link) {
+ shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
+ shader->has_displacement = true;
+ }
+ else
+ shader->osl_displacement_ref = OSL::ShaderGroupRef();
+ }
+
+ /* push state to array for lookup */
+ og->surface_state.push_back(shader->osl_surface_ref);
+ og->volume_state.push_back(shader->osl_volume_ref);
+ og->displacement_state.push_back(shader->osl_displacement_ref);
+ og->bump_state.push_back(shader->osl_surface_bump_ref);
}
#else
@@ -1247,7 +1236,7 @@ void OSLCompiler::parameter(const char * /*name*/, ustring /*s*/)
{
}
-void OSLCompiler::parameter(const char * /*name*/, const Transform& /*tfm*/)
+void OSLCompiler::parameter(const char * /*name*/, const Transform & /*tfm*/)
{
}
@@ -1255,10 +1244,10 @@ void OSLCompiler::parameter_array(const char * /*name*/, const float /*f*/[], in
{
}
-void OSLCompiler::parameter_color_array(const char * /*name*/, const array<float3>& /*f*/)
+void OSLCompiler::parameter_color_array(const char * /*name*/, const array<float3> & /*f*/)
{
}
-#endif /* WITH_OSL */
+#endif /* WITH_OSL */
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index 93cc3139608..aec518a6c2b 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -27,10 +27,10 @@
#include "render/shader.h"
#ifdef WITH_OSL
-#include <OSL/llvm_util.h>
-#include <OSL/oslcomp.h>
-#include <OSL/oslexec.h>
-#include <OSL/oslquery.h>
+# include <OSL/llvm_util.h>
+# include <OSL/oslcomp.h>
+# include <OSL/oslexec.h>
+# include <OSL/oslquery.h>
#endif
CCL_NAMESPACE_BEGIN
@@ -52,70 +52,73 @@ class ShaderOutput;
* to auto detect closures in the shader for MIS and transparent shadows */
struct OSLShaderInfo {
- OSLShaderInfo()
- : has_surface_emission(false), has_surface_transparent(false),
- has_surface_bssrdf(false)
- {}
-
- OSL::OSLQuery query;
- bool has_surface_emission;
- bool has_surface_transparent;
- bool has_surface_bssrdf;
+ OSLShaderInfo()
+ : has_surface_emission(false), has_surface_transparent(false), has_surface_bssrdf(false)
+ {
+ }
+
+ OSL::OSLQuery query;
+ bool has_surface_emission;
+ bool has_surface_transparent;
+ bool has_surface_bssrdf;
};
/* Shader Manage */
class OSLShaderManager : public ShaderManager {
-public:
- OSLShaderManager();
- ~OSLShaderManager();
-
- static void free_memory();
-
- void reset(Scene *scene);
-
- bool use_osl() { return true; }
-
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_free(Device *device, DeviceScene *dscene, Scene *scene);
-
- /* osl compile and query */
- static bool osl_compile(const string& inputfile, const string& outputfile);
- static bool osl_query(OSL::OSLQuery& query, const string& filepath);
-
- /* shader file loading, all functions return pointer to hash string if found */
- const char *shader_test_loaded(const string& hash);
- const char *shader_load_bytecode(const string& hash, const string& bytecode);
- const char *shader_load_filepath(string filepath);
- OSLShaderInfo *shader_loaded_info(const string& hash);
-
- /* create OSL node using OSLQuery */
- OSLNode *osl_node(const std::string& filepath,
- const std::string& bytecode_hash = "",
- const std::string& bytecode = "");
-
-protected:
- void texture_system_init();
- void texture_system_free();
-
- void shading_system_init();
- void shading_system_free();
-
- OSL::ShadingSystem *ss;
- OSL::TextureSystem *ts;
- OSLRenderServices *services;
- OSL::ErrorHandler errhandler;
- map<string, OSLShaderInfo> loaded_shaders;
-
- static OSL::TextureSystem *ts_shared;
- static thread_mutex ts_shared_mutex;
- static int ts_shared_users;
-
- static OSL::ShadingSystem *ss_shared;
- static OSLRenderServices *services_shared;
- static thread_mutex ss_shared_mutex;
- static thread_mutex ss_mutex;
- static int ss_shared_users;
+ public:
+ OSLShaderManager();
+ ~OSLShaderManager();
+
+ static void free_memory();
+
+ void reset(Scene *scene);
+
+ bool use_osl()
+ {
+ return true;
+ }
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_free(Device *device, DeviceScene *dscene, Scene *scene);
+
+ /* osl compile and query */
+ static bool osl_compile(const string &inputfile, const string &outputfile);
+ static bool osl_query(OSL::OSLQuery &query, const string &filepath);
+
+ /* shader file loading, all functions return pointer to hash string if found */
+ const char *shader_test_loaded(const string &hash);
+ const char *shader_load_bytecode(const string &hash, const string &bytecode);
+ const char *shader_load_filepath(string filepath);
+ OSLShaderInfo *shader_loaded_info(const string &hash);
+
+ /* create OSL node using OSLQuery */
+ OSLNode *osl_node(const std::string &filepath,
+ const std::string &bytecode_hash = "",
+ const std::string &bytecode = "");
+
+ protected:
+ void texture_system_init();
+ void texture_system_free();
+
+ void shading_system_init();
+ void shading_system_free();
+
+ OSL::ShadingSystem *ss;
+ OSL::TextureSystem *ts;
+ OSLRenderServices *services;
+ OSL::ErrorHandler errhandler;
+ map<string, OSLShaderInfo> loaded_shaders;
+
+ static OSL::TextureSystem *ts_shared;
+ static thread_mutex ts_shared_mutex;
+ static int ts_shared_users;
+
+ static OSL::ShadingSystem *ss_shared;
+ static OSLRenderServices *services_shared;
+ static thread_mutex ss_shared_mutex;
+ static thread_mutex ss_mutex;
+ static int ss_shared_users;
};
#endif
@@ -123,55 +126,59 @@ protected:
/* Graph Compiler */
class OSLCompiler {
-public:
- OSLCompiler(void *manager, void *shadingsys,
- ImageManager *image_manager,
- LightManager *light_manager);
- void compile(Scene *scene, OSLGlobals *og, Shader *shader);
-
- void add(ShaderNode *node, const char *name, bool isfilepath = false);
-
- void parameter(ShaderNode *node, const char *name);
-
- void parameter(const char *name, float f);
- void parameter_color(const char *name, float3 f);
- void parameter_vector(const char *name, float3 f);
- void parameter_normal(const char *name, float3 f);
- void parameter_point(const char *name, float3 f);
- void parameter(const char *name, int f);
- void parameter(const char *name, const char *s);
- void parameter(const char *name, ustring str);
- void parameter(const char *name, const Transform& tfm);
-
- void parameter_array(const char *name, const float f[], int arraylen);
- void parameter_color_array(const char *name, const array<float3>& f);
-
- void parameter_attribute(const char *name, ustring s);
-
- ShaderType output_type() { return current_type; }
-
- bool background;
- ImageManager *image_manager;
- LightManager *light_manager;
-
-private:
+ public:
+ OSLCompiler(void *manager,
+ void *shadingsys,
+ ImageManager *image_manager,
+ LightManager *light_manager);
+ void compile(Scene *scene, OSLGlobals *og, Shader *shader);
+
+ void add(ShaderNode *node, const char *name, bool isfilepath = false);
+
+ void parameter(ShaderNode *node, const char *name);
+
+ void parameter(const char *name, float f);
+ void parameter_color(const char *name, float3 f);
+ void parameter_vector(const char *name, float3 f);
+ void parameter_normal(const char *name, float3 f);
+ void parameter_point(const char *name, float3 f);
+ void parameter(const char *name, int f);
+ void parameter(const char *name, const char *s);
+ void parameter(const char *name, ustring str);
+ void parameter(const char *name, const Transform &tfm);
+
+ void parameter_array(const char *name, const float f[], int arraylen);
+ void parameter_color_array(const char *name, const array<float3> &f);
+
+ void parameter_attribute(const char *name, ustring s);
+
+ ShaderType output_type()
+ {
+ return current_type;
+ }
+
+ bool background;
+ ImageManager *image_manager;
+ LightManager *light_manager;
+
+ private:
#ifdef WITH_OSL
- string id(ShaderNode *node);
- OSL::ShaderGroupRef compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
- bool node_skip_input(ShaderNode *node, ShaderInput *input);
- string compatible_name(ShaderNode *node, ShaderInput *input);
- string compatible_name(ShaderNode *node, ShaderOutput *output);
-
- void find_dependencies(ShaderNodeSet& dependencies, ShaderInput *input);
- void generate_nodes(const ShaderNodeSet& nodes);
+ string id(ShaderNode *node);
+ OSL::ShaderGroupRef compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
+ bool node_skip_input(ShaderNode *node, ShaderInput *input);
+ string compatible_name(ShaderNode *node, ShaderInput *input);
+ string compatible_name(ShaderNode *node, ShaderOutput *output);
+
+ void find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input);
+ void generate_nodes(const ShaderNodeSet &nodes);
#endif
- void *shadingsys;
- void *manager;
- ShaderType current_type;
- Shader *current_shader;
+ void *shadingsys;
+ void *manager;
+ ShaderType current_type;
+ Shader *current_shader;
};
CCL_NAMESPACE_END
-#endif /* __OSL_H__ */
+#endif /* __OSL_H__ */
diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp
index 0583556c8a9..8335404b197 100644
--- a/intern/cycles/render/particles.cpp
+++ b/intern/cycles/render/particles.cpp
@@ -39,86 +39,93 @@ ParticleSystem::~ParticleSystem()
void ParticleSystem::tag_update(Scene *scene)
{
- scene->particle_system_manager->need_update = true;
+ scene->particle_system_manager->need_update = true;
}
/* Particle System Manager */
ParticleSystemManager::ParticleSystemManager()
{
- need_update = true;
+ need_update = true;
}
ParticleSystemManager::~ParticleSystemManager()
{
}
-void ParticleSystemManager::device_update_particles(Device *, DeviceScene *dscene, Scene *scene, Progress& progress)
+void ParticleSystemManager::device_update_particles(Device *,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
{
- /* count particles.
- * adds one dummy particle at the beginning to avoid invalid lookups,
- * in case a shader uses particle info without actual particle data. */
- int num_particles = 1;
- for(size_t j = 0; j < scene->particle_systems.size(); j++)
- num_particles += scene->particle_systems[j]->particles.size();
-
- KernelParticle *kparticles = dscene->particles.alloc(num_particles);
-
- /* dummy particle */
- memset(kparticles, 0, sizeof(KernelParticle));
-
- int i = 1;
- for(size_t j = 0; j < scene->particle_systems.size(); j++) {
- ParticleSystem *psys = scene->particle_systems[j];
-
- for(size_t k = 0; k < psys->particles.size(); k++) {
- /* pack in texture */
- Particle& pa = psys->particles[k];
-
- kparticles[i].index = pa.index;
- kparticles[i].age = pa.age;
- kparticles[i].lifetime = pa.lifetime;
- kparticles[i].size = pa.size;
- kparticles[i].rotation = pa.rotation;
- kparticles[i].location = float3_to_float4(pa.location);
- kparticles[i].velocity = float3_to_float4(pa.velocity);
- kparticles[i].angular_velocity = float3_to_float4(pa.angular_velocity);
-
- i++;
-
- if(progress.get_cancel()) return;
- }
- }
-
- dscene->particles.copy_to_device();
+ /* count particles.
+ * adds one dummy particle at the beginning to avoid invalid lookups,
+ * in case a shader uses particle info without actual particle data. */
+ int num_particles = 1;
+ for (size_t j = 0; j < scene->particle_systems.size(); j++)
+ num_particles += scene->particle_systems[j]->particles.size();
+
+ KernelParticle *kparticles = dscene->particles.alloc(num_particles);
+
+ /* dummy particle */
+ memset(kparticles, 0, sizeof(KernelParticle));
+
+ int i = 1;
+ for (size_t j = 0; j < scene->particle_systems.size(); j++) {
+ ParticleSystem *psys = scene->particle_systems[j];
+
+ for (size_t k = 0; k < psys->particles.size(); k++) {
+ /* pack in texture */
+ Particle &pa = psys->particles[k];
+
+ kparticles[i].index = pa.index;
+ kparticles[i].age = pa.age;
+ kparticles[i].lifetime = pa.lifetime;
+ kparticles[i].size = pa.size;
+ kparticles[i].rotation = pa.rotation;
+ kparticles[i].location = float3_to_float4(pa.location);
+ kparticles[i].velocity = float3_to_float4(pa.velocity);
+ kparticles[i].angular_velocity = float3_to_float4(pa.angular_velocity);
+
+ i++;
+
+ if (progress.get_cancel())
+ return;
+ }
+ }
+
+ dscene->particles.copy_to_device();
}
-void ParticleSystemManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+void ParticleSystemManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- VLOG(1) << "Total " << scene->particle_systems.size()
- << " particle systems.";
+ VLOG(1) << "Total " << scene->particle_systems.size() << " particle systems.";
- device_free(device, dscene);
+ device_free(device, dscene);
- progress.set_status("Updating Particle Systems", "Copying Particles to device");
- device_update_particles(device, dscene, scene, progress);
+ progress.set_status("Updating Particle Systems", "Copying Particles to device");
+ device_update_particles(device, dscene, scene, progress);
- if(progress.get_cancel()) return;
+ if (progress.get_cancel())
+ return;
- need_update = false;
+ need_update = false;
}
void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
{
- dscene->particles.free();
+ dscene->particles.free();
}
void ParticleSystemManager::tag_update(Scene * /*scene*/)
{
- need_update = true;
+ need_update = true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/particles.h b/intern/cycles/render/particles.h
index 27821907af0..65663c31c37 100644
--- a/intern/cycles/render/particles.h
+++ b/intern/cycles/render/particles.h
@@ -30,42 +30,45 @@ class Scene;
/* Particle System */
struct Particle {
- int index;
- float age;
- float lifetime;
- float3 location;
- float4 rotation;
- float size;
- float3 velocity;
- float3 angular_velocity;
+ int index;
+ float age;
+ float lifetime;
+ float3 location;
+ float4 rotation;
+ float size;
+ float3 velocity;
+ float3 angular_velocity;
};
class ParticleSystem {
-public:
- ParticleSystem();
- ~ParticleSystem();
+ public:
+ ParticleSystem();
+ ~ParticleSystem();
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene);
- array<Particle> particles;
+ array<Particle> particles;
};
/* ParticleSystem Manager */
class ParticleSystemManager {
-public:
- bool need_update;
+ public:
+ bool need_update;
- ParticleSystemManager();
- ~ParticleSystemManager();
+ ParticleSystemManager();
+ ~ParticleSystemManager();
- void device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_update_particles(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_free(Device *device, DeviceScene *dscene);
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene);
};
CCL_NAMESPACE_END
-#endif /* __PARTICLES_H__ */
+#endif /* __PARTICLES_H__ */
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 1f551f206ef..1e75fa0f99b 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -41,352 +41,359 @@
CCL_NAMESPACE_BEGIN
DeviceScene::DeviceScene(Device *device)
-: bvh_nodes(device, "__bvh_nodes", MEM_TEXTURE),
- bvh_leaf_nodes(device, "__bvh_leaf_nodes", MEM_TEXTURE),
- object_node(device, "__object_node", MEM_TEXTURE),
- prim_tri_index(device, "__prim_tri_index", MEM_TEXTURE),
- prim_tri_verts(device, "__prim_tri_verts", MEM_TEXTURE),
- prim_type(device, "__prim_type", MEM_TEXTURE),
- prim_visibility(device, "__prim_visibility", MEM_TEXTURE),
- prim_index(device, "__prim_index", MEM_TEXTURE),
- prim_object(device, "__prim_object", MEM_TEXTURE),
- prim_time(device, "__prim_time", MEM_TEXTURE),
- tri_shader(device, "__tri_shader", MEM_TEXTURE),
- tri_vnormal(device, "__tri_vnormal", MEM_TEXTURE),
- tri_vindex(device, "__tri_vindex", MEM_TEXTURE),
- tri_patch(device, "__tri_patch", MEM_TEXTURE),
- tri_patch_uv(device, "__tri_patch_uv", MEM_TEXTURE),
- curves(device, "__curves", MEM_TEXTURE),
- curve_keys(device, "__curve_keys", MEM_TEXTURE),
- patches(device, "__patches", MEM_TEXTURE),
- objects(device, "__objects", MEM_TEXTURE),
- object_motion_pass(device, "__object_motion_pass", MEM_TEXTURE),
- object_motion(device, "__object_motion", MEM_TEXTURE),
- object_flag(device, "__object_flag", MEM_TEXTURE),
- camera_motion(device, "__camera_motion", MEM_TEXTURE),
- attributes_map(device, "__attributes_map", MEM_TEXTURE),
- attributes_float(device, "__attributes_float", MEM_TEXTURE),
- attributes_float2(device, "__attributes_float2", MEM_TEXTURE),
- attributes_float3(device, "__attributes_float3", MEM_TEXTURE),
- attributes_uchar4(device, "__attributes_uchar4", MEM_TEXTURE),
- light_distribution(device, "__light_distribution", MEM_TEXTURE),
- lights(device, "__lights", MEM_TEXTURE),
- light_background_marginal_cdf(device, "__light_background_marginal_cdf", MEM_TEXTURE),
- light_background_conditional_cdf(device, "__light_background_conditional_cdf", MEM_TEXTURE),
- particles(device, "__particles", MEM_TEXTURE),
- svm_nodes(device, "__svm_nodes", MEM_TEXTURE),
- shaders(device, "__shaders", MEM_TEXTURE),
- lookup_table(device, "__lookup_table", MEM_TEXTURE),
- sobol_directions(device, "__sobol_directions", MEM_TEXTURE),
- ies_lights(device, "__ies", MEM_TEXTURE)
+ : bvh_nodes(device, "__bvh_nodes", MEM_TEXTURE),
+ bvh_leaf_nodes(device, "__bvh_leaf_nodes", MEM_TEXTURE),
+ object_node(device, "__object_node", MEM_TEXTURE),
+ prim_tri_index(device, "__prim_tri_index", MEM_TEXTURE),
+ prim_tri_verts(device, "__prim_tri_verts", MEM_TEXTURE),
+ prim_type(device, "__prim_type", MEM_TEXTURE),
+ prim_visibility(device, "__prim_visibility", MEM_TEXTURE),
+ prim_index(device, "__prim_index", MEM_TEXTURE),
+ prim_object(device, "__prim_object", MEM_TEXTURE),
+ prim_time(device, "__prim_time", MEM_TEXTURE),
+ tri_shader(device, "__tri_shader", MEM_TEXTURE),
+ tri_vnormal(device, "__tri_vnormal", MEM_TEXTURE),
+ tri_vindex(device, "__tri_vindex", MEM_TEXTURE),
+ tri_patch(device, "__tri_patch", MEM_TEXTURE),
+ tri_patch_uv(device, "__tri_patch_uv", MEM_TEXTURE),
+ curves(device, "__curves", MEM_TEXTURE),
+ curve_keys(device, "__curve_keys", MEM_TEXTURE),
+ patches(device, "__patches", MEM_TEXTURE),
+ objects(device, "__objects", MEM_TEXTURE),
+ object_motion_pass(device, "__object_motion_pass", MEM_TEXTURE),
+ object_motion(device, "__object_motion", MEM_TEXTURE),
+ object_flag(device, "__object_flag", MEM_TEXTURE),
+ camera_motion(device, "__camera_motion", MEM_TEXTURE),
+ attributes_map(device, "__attributes_map", MEM_TEXTURE),
+ attributes_float(device, "__attributes_float", MEM_TEXTURE),
+ attributes_float2(device, "__attributes_float2", MEM_TEXTURE),
+ attributes_float3(device, "__attributes_float3", MEM_TEXTURE),
+ attributes_uchar4(device, "__attributes_uchar4", MEM_TEXTURE),
+ light_distribution(device, "__light_distribution", MEM_TEXTURE),
+ lights(device, "__lights", MEM_TEXTURE),
+ light_background_marginal_cdf(device, "__light_background_marginal_cdf", MEM_TEXTURE),
+ light_background_conditional_cdf(device, "__light_background_conditional_cdf", MEM_TEXTURE),
+ particles(device, "__particles", MEM_TEXTURE),
+ svm_nodes(device, "__svm_nodes", MEM_TEXTURE),
+ shaders(device, "__shaders", MEM_TEXTURE),
+ lookup_table(device, "__lookup_table", MEM_TEXTURE),
+ sobol_directions(device, "__sobol_directions", MEM_TEXTURE),
+ ies_lights(device, "__ies", MEM_TEXTURE)
{
- memset((void*)&data, 0, sizeof(data));
+ memset((void *)&data, 0, sizeof(data));
}
-Scene::Scene(const SceneParams& params_, Device *device)
- : name("Scene"),
- device(device),
- dscene(device),
- params(params_)
+Scene::Scene(const SceneParams &params_, Device *device)
+ : name("Scene"), device(device), dscene(device), params(params_)
{
- memset((void *)&dscene.data, 0, sizeof(dscene.data));
-
- camera = new Camera();
- dicing_camera = new Camera();
- lookup_tables = new LookupTables();
- film = new Film();
- background = new Background();
- light_manager = new LightManager();
- mesh_manager = new MeshManager();
- object_manager = new ObjectManager();
- integrator = new Integrator();
- image_manager = new ImageManager(device->info);
- particle_system_manager = new ParticleSystemManager();
- curve_system_manager = new CurveSystemManager();
- bake_manager = new BakeManager();
-
- /* OSL only works on the CPU */
- if(device->info.has_osl)
- shader_manager = ShaderManager::create(this, params.shadingsystem);
- else
- shader_manager = ShaderManager::create(this, SHADINGSYSTEM_SVM);
+ memset((void *)&dscene.data, 0, sizeof(dscene.data));
+
+ camera = new Camera();
+ dicing_camera = new Camera();
+ lookup_tables = new LookupTables();
+ film = new Film();
+ background = new Background();
+ light_manager = new LightManager();
+ mesh_manager = new MeshManager();
+ object_manager = new ObjectManager();
+ integrator = new Integrator();
+ image_manager = new ImageManager(device->info);
+ particle_system_manager = new ParticleSystemManager();
+ curve_system_manager = new CurveSystemManager();
+ bake_manager = new BakeManager();
+
+ /* OSL only works on the CPU */
+ if (device->info.has_osl)
+ shader_manager = ShaderManager::create(this, params.shadingsystem);
+ else
+ shader_manager = ShaderManager::create(this, SHADINGSYSTEM_SVM);
}
Scene::~Scene()
{
- free_memory(true);
+ free_memory(true);
}
void Scene::free_memory(bool final)
{
- foreach(Shader *s, shaders)
- delete s;
- foreach(Mesh *m, meshes)
- delete m;
- foreach(Object *o, objects)
- delete o;
- foreach(Light *l, lights)
- delete l;
- foreach(ParticleSystem *p, particle_systems)
- delete p;
-
- shaders.clear();
- meshes.clear();
- objects.clear();
- lights.clear();
- particle_systems.clear();
-
- if(device) {
- camera->device_free(device, &dscene, this);
- film->device_free(device, &dscene, this);
- background->device_free(device, &dscene);
- integrator->device_free(device, &dscene);
-
- object_manager->device_free(device, &dscene);
- mesh_manager->device_free(device, &dscene);
- shader_manager->device_free(device, &dscene, this);
- light_manager->device_free(device, &dscene);
-
- particle_system_manager->device_free(device, &dscene);
- curve_system_manager->device_free(device, &dscene);
-
- bake_manager->device_free(device, &dscene);
-
- if(!params.persistent_data || final)
- image_manager->device_free(device);
- else
- image_manager->device_free_builtin(device);
-
- lookup_tables->device_free(device, &dscene);
- }
-
- if(final) {
- delete lookup_tables;
- delete camera;
- delete dicing_camera;
- delete film;
- delete background;
- delete integrator;
- delete object_manager;
- delete mesh_manager;
- delete shader_manager;
- delete light_manager;
- delete particle_system_manager;
- delete curve_system_manager;
- delete image_manager;
- delete bake_manager;
- }
+ foreach (Shader *s, shaders)
+ delete s;
+ foreach (Mesh *m, meshes)
+ delete m;
+ foreach (Object *o, objects)
+ delete o;
+ foreach (Light *l, lights)
+ delete l;
+ foreach (ParticleSystem *p, particle_systems)
+ delete p;
+
+ shaders.clear();
+ meshes.clear();
+ objects.clear();
+ lights.clear();
+ particle_systems.clear();
+
+ if (device) {
+ camera->device_free(device, &dscene, this);
+ film->device_free(device, &dscene, this);
+ background->device_free(device, &dscene);
+ integrator->device_free(device, &dscene);
+
+ object_manager->device_free(device, &dscene);
+ mesh_manager->device_free(device, &dscene);
+ shader_manager->device_free(device, &dscene, this);
+ light_manager->device_free(device, &dscene);
+
+ particle_system_manager->device_free(device, &dscene);
+ curve_system_manager->device_free(device, &dscene);
+
+ bake_manager->device_free(device, &dscene);
+
+ if (!params.persistent_data || final)
+ image_manager->device_free(device);
+ else
+ image_manager->device_free_builtin(device);
+
+ lookup_tables->device_free(device, &dscene);
+ }
+
+ if (final) {
+ delete lookup_tables;
+ delete camera;
+ delete dicing_camera;
+ delete film;
+ delete background;
+ delete integrator;
+ delete object_manager;
+ delete mesh_manager;
+ delete shader_manager;
+ delete light_manager;
+ delete particle_system_manager;
+ delete curve_system_manager;
+ delete image_manager;
+ delete bake_manager;
+ }
}
-void Scene::device_update(Device *device_, Progress& progress)
+void Scene::device_update(Device *device_, Progress &progress)
{
- if(!device)
- device = device_;
+ if (!device)
+ device = device_;
- bool print_stats = need_data_update();
+ bool print_stats = need_data_update();
- /* The order of updates is important, because there's dependencies between
- * the different managers, using data computed by previous managers.
- *
- * - Image manager uploads images used by shaders.
- * - Camera may be used for adaptive subdivision.
- * - Displacement shader must have all shader data available.
- * - Light manager needs lookup tables and final mesh data to compute emission CDF.
- * - Film needs light manager to run for use_light_visibility
- * - Lookup tables are done a second time to handle film tables
- */
+ /* The order of updates is important, because there's dependencies between
+ * the different managers, using data computed by previous managers.
+ *
+ * - Image manager uploads images used by shaders.
+ * - Camera may be used for adaptive subdivision.
+ * - Displacement shader must have all shader data available.
+ * - Light manager needs lookup tables and final mesh data to compute emission CDF.
+ * - Film needs light manager to run for use_light_visibility
+ * - Lookup tables are done a second time to handle film tables
+ */
- progress.set_status("Updating Shaders");
- shader_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Shaders");
+ shader_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Background");
- background->device_update(device, &dscene, this);
+ progress.set_status("Updating Background");
+ background->device_update(device, &dscene, this);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Camera");
- camera->device_update(device, &dscene, this);
+ progress.set_status("Updating Camera");
+ camera->device_update(device, &dscene, this);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- mesh_manager->device_update_preprocess(device, this, progress);
+ mesh_manager->device_update_preprocess(device, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Objects");
- object_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Objects");
+ object_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Hair Systems");
- curve_system_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Hair Systems");
+ curve_system_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Particle Systems");
- particle_system_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Particle Systems");
+ particle_system_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Meshes");
- mesh_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Meshes");
+ mesh_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Objects Flags");
- object_manager->device_update_flags(device, &dscene, this, progress);
+ progress.set_status("Updating Objects Flags");
+ object_manager->device_update_flags(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Images");
- image_manager->device_update(device, this, progress);
+ progress.set_status("Updating Images");
+ image_manager->device_update(device, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Camera Volume");
- camera->device_update_volume(device, &dscene, this);
+ progress.set_status("Updating Camera Volume");
+ camera->device_update_volume(device, &dscene, this);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Lookup Tables");
- lookup_tables->device_update(device, &dscene);
+ progress.set_status("Updating Lookup Tables");
+ lookup_tables->device_update(device, &dscene);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Lights");
- light_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Lights");
+ light_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Integrator");
- integrator->device_update(device, &dscene, this);
+ progress.set_status("Updating Integrator");
+ integrator->device_update(device, &dscene, this);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Film");
- film->device_update(device, &dscene, this);
+ progress.set_status("Updating Film");
+ film->device_update(device, &dscene, this);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Lookup Tables");
- lookup_tables->device_update(device, &dscene);
+ progress.set_status("Updating Lookup Tables");
+ lookup_tables->device_update(device, &dscene);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- progress.set_status("Updating Baking");
- bake_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Baking");
+ bake_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel() || device->have_error()) return;
+ if (progress.get_cancel() || device->have_error())
+ return;
- if(device->have_error() == false) {
- progress.set_status("Updating Device", "Writing constant memory");
- device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
- }
+ if (device->have_error() == false) {
+ progress.set_status("Updating Device", "Writing constant memory");
+ device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
+ }
- if(print_stats) {
- size_t mem_used = util_guarded_get_mem_used();
- size_t mem_peak = util_guarded_get_mem_peak();
+ if (print_stats) {
+ size_t mem_used = util_guarded_get_mem_used();
+ size_t mem_peak = util_guarded_get_mem_peak();
- VLOG(1) << "System memory statistics after full device sync:\n"
- << " Usage: " << string_human_readable_number(mem_used)
- << " (" << string_human_readable_size(mem_used) << ")\n"
- << " Peak: " << string_human_readable_number(mem_peak)
- << " (" << string_human_readable_size(mem_peak) << ")";
- }
+ VLOG(1) << "System memory statistics after full device sync:\n"
+ << " Usage: " << string_human_readable_number(mem_used) << " ("
+ << string_human_readable_size(mem_used) << ")\n"
+ << " Peak: " << string_human_readable_number(mem_peak) << " ("
+ << string_human_readable_size(mem_peak) << ")";
+ }
}
Scene::MotionType Scene::need_motion()
{
- if(integrator->motion_blur)
- return MOTION_BLUR;
- else if(Pass::contains(film->passes, PASS_MOTION))
- return MOTION_PASS;
- else
- return MOTION_NONE;
+ if (integrator->motion_blur)
+ return MOTION_BLUR;
+ else if (Pass::contains(film->passes, PASS_MOTION))
+ return MOTION_PASS;
+ else
+ return MOTION_NONE;
}
float Scene::motion_shutter_time()
{
- if(need_motion() == Scene::MOTION_PASS)
- return 2.0f;
- else
- return camera->shuttertime;
+ if (need_motion() == Scene::MOTION_PASS)
+ return 2.0f;
+ else
+ return camera->shuttertime;
}
bool Scene::need_global_attribute(AttributeStandard std)
{
- if(std == ATTR_STD_UV)
- return Pass::contains(film->passes, PASS_UV);
- else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
- return need_motion() != MOTION_NONE;
- else if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
- return need_motion() == MOTION_BLUR;
-
- return false;
+ if (std == ATTR_STD_UV)
+ return Pass::contains(film->passes, PASS_UV);
+ else if (std == ATTR_STD_MOTION_VERTEX_POSITION)
+ return need_motion() != MOTION_NONE;
+ else if (std == ATTR_STD_MOTION_VERTEX_NORMAL)
+ return need_motion() == MOTION_BLUR;
+
+ return false;
}
-void Scene::need_global_attributes(AttributeRequestSet& attributes)
+void Scene::need_global_attributes(AttributeRequestSet &attributes)
{
- for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
- if(need_global_attribute((AttributeStandard)std))
- attributes.add((AttributeStandard)std);
+ for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
+ if (need_global_attribute((AttributeStandard)std))
+ attributes.add((AttributeStandard)std);
}
bool Scene::need_update()
{
- return (need_reset() || film->need_update);
+ return (need_reset() || film->need_update);
}
bool Scene::need_data_update()
{
- return (background->need_update
- || image_manager->need_update
- || object_manager->need_update
- || mesh_manager->need_update
- || light_manager->need_update
- || lookup_tables->need_update
- || integrator->need_update
- || shader_manager->need_update
- || particle_system_manager->need_update
- || curve_system_manager->need_update
- || bake_manager->need_update
- || film->need_update);
+ return (background->need_update || image_manager->need_update || object_manager->need_update ||
+ mesh_manager->need_update || light_manager->need_update || lookup_tables->need_update ||
+ integrator->need_update || shader_manager->need_update ||
+ particle_system_manager->need_update || curve_system_manager->need_update ||
+ bake_manager->need_update || film->need_update);
}
bool Scene::need_reset()
{
- return need_data_update() || camera->need_update;
+ return need_data_update() || camera->need_update;
}
void Scene::reset()
{
- shader_manager->reset(this);
- shader_manager->add_default(this);
-
- /* ensure all objects are updated */
- camera->tag_update();
- dicing_camera->tag_update();
- film->tag_update(this);
- background->tag_update(this);
- integrator->tag_update(this);
- object_manager->tag_update(this);
- mesh_manager->tag_update(this);
- light_manager->tag_update(this);
- particle_system_manager->tag_update(this);
- curve_system_manager->tag_update(this);
+ shader_manager->reset(this);
+ shader_manager->add_default(this);
+
+ /* ensure all objects are updated */
+ camera->tag_update();
+ dicing_camera->tag_update();
+ film->tag_update(this);
+ background->tag_update(this);
+ integrator->tag_update(this);
+ object_manager->tag_update(this);
+ mesh_manager->tag_update(this);
+ light_manager->tag_update(this);
+ particle_system_manager->tag_update(this);
+ curve_system_manager->tag_update(this);
}
void Scene::device_free()
{
- free_memory(false);
+ free_memory(false);
}
void Scene::collect_statistics(RenderStats *stats)
{
- mesh_manager->collect_statistics(this, stats);
- image_manager->collect_statistics(stats);
+ mesh_manager->collect_statistics(this, stats);
+ image_manager->collect_statistics(stats);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index e43800fe5c4..45997bccf5d 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -61,215 +61,215 @@ class RenderStats;
/* Scene Device Data */
class DeviceScene {
-public:
- /* BVH */
- device_vector<int4> bvh_nodes;
- device_vector<int4> bvh_leaf_nodes;
- device_vector<int> object_node;
- device_vector<uint> prim_tri_index;
- device_vector<float4> prim_tri_verts;
- device_vector<int> prim_type;
- device_vector<uint> prim_visibility;
- device_vector<int> prim_index;
- device_vector<int> prim_object;
- device_vector<float2> prim_time;
-
- /* mesh */
- device_vector<uint> tri_shader;
- device_vector<float4> tri_vnormal;
- device_vector<uint4> tri_vindex;
- device_vector<uint> tri_patch;
- device_vector<float2> tri_patch_uv;
-
- device_vector<float4> curves;
- device_vector<float4> curve_keys;
-
- device_vector<uint> patches;
-
- /* objects */
- device_vector<KernelObject> objects;
- device_vector<Transform> object_motion_pass;
- device_vector<DecomposedTransform> object_motion;
- device_vector<uint> object_flag;
-
- /* cameras */
- device_vector<DecomposedTransform> camera_motion;
-
- /* attributes */
- device_vector<uint4> attributes_map;
- device_vector<float> attributes_float;
- device_vector<float2> attributes_float2;
- device_vector<float4> attributes_float3;
- device_vector<uchar4> attributes_uchar4;
-
- /* lights */
- device_vector<KernelLightDistribution> light_distribution;
- device_vector<KernelLight> lights;
- device_vector<float2> light_background_marginal_cdf;
- device_vector<float2> light_background_conditional_cdf;
-
- /* particles */
- device_vector<KernelParticle> particles;
-
- /* shaders */
- device_vector<int4> svm_nodes;
- device_vector<KernelShader> shaders;
-
- /* lookup tables */
- device_vector<float> lookup_table;
-
- /* integrator */
- device_vector<uint> sobol_directions;
-
- /* ies lights */
- device_vector<float> ies_lights;
-
- KernelData data;
-
- DeviceScene(Device *device);
+ public:
+ /* BVH */
+ device_vector<int4> bvh_nodes;
+ device_vector<int4> bvh_leaf_nodes;
+ device_vector<int> object_node;
+ device_vector<uint> prim_tri_index;
+ device_vector<float4> prim_tri_verts;
+ device_vector<int> prim_type;
+ device_vector<uint> prim_visibility;
+ device_vector<int> prim_index;
+ device_vector<int> prim_object;
+ device_vector<float2> prim_time;
+
+ /* mesh */
+ device_vector<uint> tri_shader;
+ device_vector<float4> tri_vnormal;
+ device_vector<uint4> tri_vindex;
+ device_vector<uint> tri_patch;
+ device_vector<float2> tri_patch_uv;
+
+ device_vector<float4> curves;
+ device_vector<float4> curve_keys;
+
+ device_vector<uint> patches;
+
+ /* objects */
+ device_vector<KernelObject> objects;
+ device_vector<Transform> object_motion_pass;
+ device_vector<DecomposedTransform> object_motion;
+ device_vector<uint> object_flag;
+
+ /* cameras */
+ device_vector<DecomposedTransform> camera_motion;
+
+ /* attributes */
+ device_vector<uint4> attributes_map;
+ device_vector<float> attributes_float;
+ device_vector<float2> attributes_float2;
+ device_vector<float4> attributes_float3;
+ device_vector<uchar4> attributes_uchar4;
+
+ /* lights */
+ device_vector<KernelLightDistribution> light_distribution;
+ device_vector<KernelLight> lights;
+ device_vector<float2> light_background_marginal_cdf;
+ device_vector<float2> light_background_conditional_cdf;
+
+ /* particles */
+ device_vector<KernelParticle> particles;
+
+ /* shaders */
+ device_vector<int4> svm_nodes;
+ device_vector<KernelShader> shaders;
+
+ /* lookup tables */
+ device_vector<float> lookup_table;
+
+ /* integrator */
+ device_vector<uint> sobol_directions;
+
+ /* ies lights */
+ device_vector<float> ies_lights;
+
+ KernelData data;
+
+ DeviceScene(Device *device);
};
/* Scene Parameters */
class SceneParams {
-public:
- /* Type of BVH, in terms whether it is supported dynamic updates of meshes
- * or whether modifying geometry requires full BVH rebuild.
- */
- enum BVHType {
- /* BVH supports dynamic updates of geometry.
- *
- * Faster for updating BVH tree when doing modifications in viewport,
- * but slower for rendering.
- */
- BVH_DYNAMIC = 0,
- /* BVH tree is calculated for specific scene, updates in geometry
- * requires full tree rebuild.
- *
- * Slower to update BVH tree when modifying objects in viewport, also
- * slower to build final BVH tree but gives best possible render speed.
- */
- BVH_STATIC = 1,
-
- BVH_NUM_TYPES,
- };
-
- ShadingSystem shadingsystem;
-
- /* Requested BVH layout.
- *
- * If it's not supported by the device, the widest one from supported ones
- * will be used, but BVH wider than this one will never be used.
- */
- BVHLayout bvh_layout;
-
- BVHType bvh_type;
- bool use_bvh_spatial_split;
- bool use_bvh_unaligned_nodes;
- int num_bvh_time_steps;
- bool persistent_data;
- int texture_limit;
-
- SceneParams()
- {
- shadingsystem = SHADINGSYSTEM_SVM;
- bvh_layout = BVH_LAYOUT_BVH2;
- bvh_type = BVH_DYNAMIC;
- use_bvh_spatial_split = false;
- use_bvh_unaligned_nodes = true;
- num_bvh_time_steps = 0;
- persistent_data = false;
- texture_limit = 0;
- }
-
- bool modified(const SceneParams& params)
- { return !(shadingsystem == params.shadingsystem
- && bvh_layout == params.bvh_layout
- && bvh_type == params.bvh_type
- && use_bvh_spatial_split == params.use_bvh_spatial_split
- && use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes
- && num_bvh_time_steps == params.num_bvh_time_steps
- && persistent_data == params.persistent_data
- && texture_limit == params.texture_limit); }
+ public:
+ /* Type of BVH, in terms whether it is supported dynamic updates of meshes
+ * or whether modifying geometry requires full BVH rebuild.
+ */
+ enum BVHType {
+ /* BVH supports dynamic updates of geometry.
+ *
+ * Faster for updating BVH tree when doing modifications in viewport,
+ * but slower for rendering.
+ */
+ BVH_DYNAMIC = 0,
+ /* BVH tree is calculated for specific scene, updates in geometry
+ * requires full tree rebuild.
+ *
+ * Slower to update BVH tree when modifying objects in viewport, also
+ * slower to build final BVH tree but gives best possible render speed.
+ */
+ BVH_STATIC = 1,
+
+ BVH_NUM_TYPES,
+ };
+
+ ShadingSystem shadingsystem;
+
+ /* Requested BVH layout.
+ *
+ * If it's not supported by the device, the widest one from supported ones
+ * will be used, but BVH wider than this one will never be used.
+ */
+ BVHLayout bvh_layout;
+
+ BVHType bvh_type;
+ bool use_bvh_spatial_split;
+ bool use_bvh_unaligned_nodes;
+ int num_bvh_time_steps;
+ bool persistent_data;
+ int texture_limit;
+
+ SceneParams()
+ {
+ shadingsystem = SHADINGSYSTEM_SVM;
+ bvh_layout = BVH_LAYOUT_BVH2;
+ bvh_type = BVH_DYNAMIC;
+ use_bvh_spatial_split = false;
+ use_bvh_unaligned_nodes = true;
+ num_bvh_time_steps = 0;
+ persistent_data = false;
+ texture_limit = 0;
+ }
+
+ bool modified(const SceneParams &params)
+ {
+ return !(shadingsystem == params.shadingsystem && bvh_layout == params.bvh_layout &&
+ bvh_type == params.bvh_type &&
+ use_bvh_spatial_split == params.use_bvh_spatial_split &&
+ use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes &&
+ num_bvh_time_steps == params.num_bvh_time_steps &&
+ persistent_data == params.persistent_data && texture_limit == params.texture_limit);
+ }
};
/* Scene */
class Scene {
-public:
- /* Optional name. Is used for logging and reporting. */
- string name;
-
- /* data */
- Camera *camera;
- Camera *dicing_camera;
- LookupTables *lookup_tables;
- Film *film;
- Background *background;
- Integrator *integrator;
-
- /* data lists */
- vector<Object*> objects;
- vector<Mesh*> meshes;
- vector<Shader*> shaders;
- vector<Light*> lights;
- vector<ParticleSystem*> particle_systems;
-
- /* data managers */
- ImageManager *image_manager;
- LightManager *light_manager;
- ShaderManager *shader_manager;
- MeshManager *mesh_manager;
- ObjectManager *object_manager;
- ParticleSystemManager *particle_system_manager;
- CurveSystemManager *curve_system_manager;
- BakeManager *bake_manager;
-
- /* default shaders */
- Shader *default_surface;
- Shader *default_light;
- Shader *default_background;
- Shader *default_empty;
-
- /* device */
- Device *device;
- DeviceScene dscene;
-
- /* parameters */
- SceneParams params;
-
- /* mutex must be locked manually by callers */
- thread_mutex mutex;
-
- Scene(const SceneParams& params, Device *device);
- ~Scene();
-
- void device_update(Device *device, Progress& progress);
-
- bool need_global_attribute(AttributeStandard std);
- void need_global_attributes(AttributeRequestSet& attributes);
-
- enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR };
- MotionType need_motion();
- float motion_shutter_time();
-
- bool need_update();
- bool need_reset();
-
- void reset();
- void device_free();
-
- void collect_statistics(RenderStats *stats);
-
-protected:
- /* Check if some heavy data worth logging was updated.
- * Mainly used to suppress extra annoying logging.
- */
- bool need_data_update();
-
- void free_memory(bool final);
+ public:
+ /* Optional name. Is used for logging and reporting. */
+ string name;
+
+ /* data */
+ Camera *camera;
+ Camera *dicing_camera;
+ LookupTables *lookup_tables;
+ Film *film;
+ Background *background;
+ Integrator *integrator;
+
+ /* data lists */
+ vector<Object *> objects;
+ vector<Mesh *> meshes;
+ vector<Shader *> shaders;
+ vector<Light *> lights;
+ vector<ParticleSystem *> particle_systems;
+
+ /* data managers */
+ ImageManager *image_manager;
+ LightManager *light_manager;
+ ShaderManager *shader_manager;
+ MeshManager *mesh_manager;
+ ObjectManager *object_manager;
+ ParticleSystemManager *particle_system_manager;
+ CurveSystemManager *curve_system_manager;
+ BakeManager *bake_manager;
+
+ /* default shaders */
+ Shader *default_surface;
+ Shader *default_light;
+ Shader *default_background;
+ Shader *default_empty;
+
+ /* device */
+ Device *device;
+ DeviceScene dscene;
+
+ /* parameters */
+ SceneParams params;
+
+ /* mutex must be locked manually by callers */
+ thread_mutex mutex;
+
+ Scene(const SceneParams &params, Device *device);
+ ~Scene();
+
+ void device_update(Device *device, Progress &progress);
+
+ bool need_global_attribute(AttributeStandard std);
+ void need_global_attributes(AttributeRequestSet &attributes);
+
+ enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR };
+ MotionType need_motion();
+ float motion_shutter_time();
+
+ bool need_update();
+ bool need_reset();
+
+ void reset();
+ void device_free();
+
+ void collect_statistics(RenderStats *stats);
+
+ protected:
+ /* Check if some heavy data worth logging was updated.
+ * Mainly used to suppress extra annoying logging.
+ */
+ bool need_data_update();
+
+ void free_memory(bool final);
};
CCL_NAMESPACE_END
-#endif /* __SCENE_H__ */
+#endif /* __SCENE_H__ */
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index e88d960d9d2..29eb779a7d6 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -43,1121 +43,1122 @@ CCL_NAMESPACE_BEGIN
* progressive refine and viewport rendering does requires tiles to
* always be allocated for the same device
*/
-Session::Session(const SessionParams& params_)
-: params(params_),
- tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
- params.background == false || params.progressive_refine, params.background, params.tile_order,
- max(params.device.multi_devices.size(), 1), params.pixel_size),
- stats(),
- profiler()
+Session::Session(const SessionParams &params_)
+ : params(params_),
+ tile_manager(params.progressive,
+ params.samples,
+ params.tile_size,
+ params.start_resolution,
+ params.background == false || params.progressive_refine,
+ params.background,
+ params.tile_order,
+ max(params.device.multi_devices.size(), 1),
+ params.pixel_size),
+ stats(),
+ profiler()
{
- device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
+ device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
- TaskScheduler::init(params.threads);
+ TaskScheduler::init(params.threads);
- device = Device::create(params.device, stats, profiler, params.background);
+ device = Device::create(params.device, stats, profiler, params.background);
- if(params.background && !params.write_render_cb) {
- buffers = NULL;
- display = NULL;
- }
- else {
- buffers = new RenderBuffers(device);
- display = new DisplayBuffer(device, params.display_buffer_linear);
- }
+ if (params.background && !params.write_render_cb) {
+ buffers = NULL;
+ display = NULL;
+ }
+ else {
+ buffers = new RenderBuffers(device);
+ display = new DisplayBuffer(device, params.display_buffer_linear);
+ }
- session_thread = NULL;
- scene = NULL;
+ session_thread = NULL;
+ scene = NULL;
- reset_time = 0.0;
- last_update_time = 0.0;
+ reset_time = 0.0;
+ last_update_time = 0.0;
- delayed_reset.do_reset = false;
- delayed_reset.samples = 0;
+ delayed_reset.do_reset = false;
+ delayed_reset.samples = 0;
- display_outdated = false;
- gpu_draw_ready = false;
- gpu_need_tonemap = false;
- pause = false;
- kernels_loaded = false;
+ display_outdated = false;
+ gpu_draw_ready = false;
+ gpu_need_tonemap = false;
+ pause = false;
+ kernels_loaded = false;
- /* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
- max_closure_global = 1;
+ /* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
+ max_closure_global = 1;
}
Session::~Session()
{
- if(session_thread) {
- /* wait for session thread to end */
- progress.set_cancel("Exiting");
+ if (session_thread) {
+ /* wait for session thread to end */
+ progress.set_cancel("Exiting");
- gpu_need_tonemap = false;
- gpu_need_tonemap_cond.notify_all();
+ gpu_need_tonemap = false;
+ gpu_need_tonemap_cond.notify_all();
- {
- thread_scoped_lock pause_lock(pause_mutex);
- pause = false;
- }
- pause_cond.notify_all();
+ {
+ thread_scoped_lock pause_lock(pause_mutex);
+ pause = false;
+ }
+ pause_cond.notify_all();
- wait();
- }
+ wait();
+ }
- if(params.write_render_cb) {
- /* tonemap and write out image if requested */
- delete display;
+ if (params.write_render_cb) {
+ /* tonemap and write out image if requested */
+ delete display;
- display = new DisplayBuffer(device, false);
- display->reset(buffers->params);
- tonemap(params.samples);
+ display = new DisplayBuffer(device, false);
+ display->reset(buffers->params);
+ tonemap(params.samples);
- int w = display->draw_width;
- int h = display->draw_height;
- uchar4 *pixels = display->rgba_byte.copy_from_device(0, w, h);
- params.write_render_cb((uchar*)pixels, w, h, 4);
- }
+ int w = display->draw_width;
+ int h = display->draw_height;
+ uchar4 *pixels = display->rgba_byte.copy_from_device(0, w, h);
+ params.write_render_cb((uchar *)pixels, w, h, 4);
+ }
- /* clean up */
- tile_manager.device_free();
+ /* clean up */
+ tile_manager.device_free();
- delete buffers;
- delete display;
- delete scene;
- delete device;
+ delete buffers;
+ delete display;
+ delete scene;
+ delete device;
- TaskScheduler::exit();
+ TaskScheduler::exit();
}
void Session::start()
{
- if (!session_thread) {
- session_thread = new thread(function_bind(&Session::run, this));
- }
+ if (!session_thread) {
+ session_thread = new thread(function_bind(&Session::run, this));
+ }
}
bool Session::ready_to_reset()
{
- double dt = time_dt() - reset_time;
+ double dt = time_dt() - reset_time;
- if(!display_outdated)
- return (dt > params.reset_timeout);
- else
- return (dt > params.cancel_timeout);
+ if (!display_outdated)
+ return (dt > params.reset_timeout);
+ else
+ return (dt > params.cancel_timeout);
}
/* GPU Session */
-void Session::reset_gpu(BufferParams& buffer_params, int samples)
+void Session::reset_gpu(BufferParams &buffer_params, int samples)
{
- thread_scoped_lock pause_lock(pause_mutex);
+ thread_scoped_lock pause_lock(pause_mutex);
- /* block for buffer access and reset immediately. we can't do this
- * in the thread, because we need to allocate an OpenGL buffer, and
- * that only works in the main thread */
- thread_scoped_lock display_lock(display_mutex);
- thread_scoped_lock buffers_lock(buffers_mutex);
+ /* block for buffer access and reset immediately. we can't do this
+ * in the thread, because we need to allocate an OpenGL buffer, and
+ * that only works in the main thread */
+ thread_scoped_lock display_lock(display_mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex);
- display_outdated = true;
- reset_time = time_dt();
+ display_outdated = true;
+ reset_time = time_dt();
- reset_(buffer_params, samples);
+ reset_(buffer_params, samples);
- gpu_need_tonemap = false;
- gpu_need_tonemap_cond.notify_all();
+ gpu_need_tonemap = false;
+ gpu_need_tonemap_cond.notify_all();
- pause_cond.notify_all();
+ pause_cond.notify_all();
}
-bool Session::draw_gpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
+bool Session::draw_gpu(BufferParams &buffer_params, DeviceDrawParams &draw_params)
{
- /* block for buffer access */
- thread_scoped_lock display_lock(display_mutex);
-
- /* first check we already rendered something */
- if(gpu_draw_ready) {
- /* then verify the buffers have the expected size, so we don't
- * draw previous results in a resized window */
- if(!buffer_params.modified(display->params)) {
- /* for CUDA we need to do tonemapping still, since we can
- * only access GL buffers from the main thread */
- if(gpu_need_tonemap) {
- thread_scoped_lock buffers_lock(buffers_mutex);
- tonemap(tile_manager.state.sample);
- gpu_need_tonemap = false;
- gpu_need_tonemap_cond.notify_all();
- }
-
- display->draw(device, draw_params);
-
- if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
- return false;
-
- return true;
- }
- }
-
- return false;
+ /* block for buffer access */
+ thread_scoped_lock display_lock(display_mutex);
+
+ /* first check we already rendered something */
+ if (gpu_draw_ready) {
+ /* then verify the buffers have the expected size, so we don't
+ * draw previous results in a resized window */
+ if (!buffer_params.modified(display->params)) {
+ /* for CUDA we need to do tonemapping still, since we can
+ * only access GL buffers from the main thread */
+ if (gpu_need_tonemap) {
+ thread_scoped_lock buffers_lock(buffers_mutex);
+ tonemap(tile_manager.state.sample);
+ gpu_need_tonemap = false;
+ gpu_need_tonemap_cond.notify_all();
+ }
+
+ display->draw(device, draw_params);
+
+ if (display_outdated && (time_dt() - reset_time) > params.text_timeout)
+ return false;
+
+ return true;
+ }
+ }
+
+ return false;
}
void Session::run_gpu()
{
- bool tiles_written = false;
-
- reset_time = time_dt();
- last_update_time = time_dt();
-
- progress.set_render_start_time();
-
- while(!progress.get_cancel()) {
- /* advance to next tile */
- bool no_tiles = !tile_manager.next();
-
- DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN;
- if (no_tiles) {
- kernel_state = device->get_active_kernel_switch_state();
- }
-
- if(params.background) {
- /* if no work left and in background mode, we can stop immediately */
- if(no_tiles) {
- progress.set_status("Finished");
- break;
- }
- }
-
- /* Don't go in pause mode when image was rendered with preview kernels
- * When feature kernels become available the session will be resetted. */
- else if (no_tiles && kernel_state == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
- time_sleep(0.1);
- }
- else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
- reset_gpu(tile_manager.params, params.samples);
- }
-
- else {
- /* if in interactive mode, and we are either paused or done for now,
- * wait for pause condition notify to wake up again */
- thread_scoped_lock pause_lock(pause_mutex);
-
- if(!pause && !tile_manager.done()) {
- /* reset could have happened after no_tiles was set, before this lock.
- * in this case we shall not wait for pause condition
- */
- }
- else if(pause || no_tiles) {
- update_status_time(pause, no_tiles);
-
- while(1) {
- scoped_timer pause_timer;
- pause_cond.wait(pause_lock);
- if(pause) {
- progress.add_skip_time(pause_timer, params.background);
- }
-
- update_status_time(pause, no_tiles);
- progress.set_update();
-
- if(!pause)
- break;
- }
- }
-
- if(progress.get_cancel())
- break;
- }
-
- if(!no_tiles) {
- /* update scene */
- scoped_timer update_timer;
- if(update_scene()) {
- profiler.reset(scene->shaders.size(), scene->objects.size());
- }
- progress.add_skip_time(update_timer, params.background);
-
- if(!device->error_message().empty())
- progress.set_error(device->error_message());
-
- if(progress.get_cancel())
- break;
- }
-
- if(!no_tiles) {
- /* buffers mutex is locked entirely while rendering each
- * sample, and released/reacquired on each iteration to allow
- * reset and draw in between */
- thread_scoped_lock buffers_lock(buffers_mutex);
-
- /* update status and timing */
- update_status_time();
-
- /* render */
- render();
-
- device->task_wait();
-
- if(!device->error_message().empty())
- progress.set_cancel(device->error_message());
-
- /* update status and timing */
- update_status_time();
-
- gpu_need_tonemap = true;
- gpu_draw_ready = true;
- progress.set_update();
-
- /* wait for tonemap */
- if(!params.background) {
- while(gpu_need_tonemap) {
- if(progress.get_cancel())
- break;
-
- gpu_need_tonemap_cond.wait(buffers_lock);
- }
- }
-
- if(!device->error_message().empty())
- progress.set_error(device->error_message());
-
- tiles_written = update_progressive_refine(progress.get_cancel());
-
- if(progress.get_cancel())
- break;
- }
- }
-
- if(!tiles_written)
- update_progressive_refine(true);
+ bool tiles_written = false;
+
+ reset_time = time_dt();
+ last_update_time = time_dt();
+
+ progress.set_render_start_time();
+
+ while (!progress.get_cancel()) {
+ /* advance to next tile */
+ bool no_tiles = !tile_manager.next();
+
+ DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN;
+ if (no_tiles) {
+ kernel_state = device->get_active_kernel_switch_state();
+ }
+
+ if (params.background) {
+ /* if no work left and in background mode, we can stop immediately */
+ if (no_tiles) {
+ progress.set_status("Finished");
+ break;
+ }
+ }
+
+ /* Don't go in pause mode when image was rendered with preview kernels
+ * When feature kernels become available the session will be resetted. */
+ else if (no_tiles && kernel_state == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
+ time_sleep(0.1);
+ }
+ else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
+ reset_gpu(tile_manager.params, params.samples);
+ }
+
+ else {
+ /* if in interactive mode, and we are either paused or done for now,
+ * wait for pause condition notify to wake up again */
+ thread_scoped_lock pause_lock(pause_mutex);
+
+ if (!pause && !tile_manager.done()) {
+ /* reset could have happened after no_tiles was set, before this lock.
+ * in this case we shall not wait for pause condition
+ */
+ }
+ else if (pause || no_tiles) {
+ update_status_time(pause, no_tiles);
+
+ while (1) {
+ scoped_timer pause_timer;
+ pause_cond.wait(pause_lock);
+ if (pause) {
+ progress.add_skip_time(pause_timer, params.background);
+ }
+
+ update_status_time(pause, no_tiles);
+ progress.set_update();
+
+ if (!pause)
+ break;
+ }
+ }
+
+ if (progress.get_cancel())
+ break;
+ }
+
+ if (!no_tiles) {
+ /* update scene */
+ scoped_timer update_timer;
+ if (update_scene()) {
+ profiler.reset(scene->shaders.size(), scene->objects.size());
+ }
+ progress.add_skip_time(update_timer, params.background);
+
+ if (!device->error_message().empty())
+ progress.set_error(device->error_message());
+
+ if (progress.get_cancel())
+ break;
+ }
+
+ if (!no_tiles) {
+ /* buffers mutex is locked entirely while rendering each
+ * sample, and released/reacquired on each iteration to allow
+ * reset and draw in between */
+ thread_scoped_lock buffers_lock(buffers_mutex);
+
+ /* update status and timing */
+ update_status_time();
+
+ /* render */
+ render();
+
+ device->task_wait();
+
+ if (!device->error_message().empty())
+ progress.set_cancel(device->error_message());
+
+ /* update status and timing */
+ update_status_time();
+
+ gpu_need_tonemap = true;
+ gpu_draw_ready = true;
+ progress.set_update();
+
+ /* wait for tonemap */
+ if (!params.background) {
+ while (gpu_need_tonemap) {
+ if (progress.get_cancel())
+ break;
+
+ gpu_need_tonemap_cond.wait(buffers_lock);
+ }
+ }
+
+ if (!device->error_message().empty())
+ progress.set_error(device->error_message());
+
+ tiles_written = update_progressive_refine(progress.get_cancel());
+
+ if (progress.get_cancel())
+ break;
+ }
+ }
+
+ if (!tiles_written)
+ update_progressive_refine(true);
}
/* CPU Session */
-void Session::reset_cpu(BufferParams& buffer_params, int samples)
+void Session::reset_cpu(BufferParams &buffer_params, int samples)
{
- thread_scoped_lock reset_lock(delayed_reset.mutex);
- thread_scoped_lock pause_lock(pause_mutex);
+ thread_scoped_lock reset_lock(delayed_reset.mutex);
+ thread_scoped_lock pause_lock(pause_mutex);
- display_outdated = true;
- reset_time = time_dt();
+ display_outdated = true;
+ reset_time = time_dt();
- delayed_reset.params = buffer_params;
- delayed_reset.samples = samples;
- delayed_reset.do_reset = true;
- device->task_cancel();
+ delayed_reset.params = buffer_params;
+ delayed_reset.samples = samples;
+ delayed_reset.do_reset = true;
+ device->task_cancel();
- pause_cond.notify_all();
+ pause_cond.notify_all();
}
-bool Session::draw_cpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
+bool Session::draw_cpu(BufferParams &buffer_params, DeviceDrawParams &draw_params)
{
- thread_scoped_lock display_lock(display_mutex);
+ thread_scoped_lock display_lock(display_mutex);
- /* first check we already rendered something */
- if(display->draw_ready()) {
- /* then verify the buffers have the expected size, so we don't
- * draw previous results in a resized window */
- if(!buffer_params.modified(display->params)) {
- display->draw(device, draw_params);
+ /* first check we already rendered something */
+ if (display->draw_ready()) {
+ /* then verify the buffers have the expected size, so we don't
+ * draw previous results in a resized window */
+ if (!buffer_params.modified(display->params)) {
+ display->draw(device, draw_params);
- if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
- return false;
+ if (display_outdated && (time_dt() - reset_time) > params.text_timeout)
+ return false;
- return true;
- }
- }
+ return true;
+ }
+ }
- return false;
+ return false;
}
-bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
+bool Session::acquire_tile(Device *tile_device, RenderTile &rtile)
{
- if(progress.get_cancel()) {
- if(params.progressive_refine == false) {
- /* for progressive refine current sample should be finished for all tiles */
- return false;
- }
- }
-
- thread_scoped_lock tile_lock(tile_mutex);
-
- /* get next tile from manager */
- Tile *tile;
- int device_num = device->device_number(tile_device);
-
- if(!tile_manager.next_tile(tile, device_num))
- return false;
-
- /* fill render tile */
- rtile.x = tile_manager.state.buffer.full_x + tile->x;
- rtile.y = tile_manager.state.buffer.full_y + tile->y;
- rtile.w = tile->w;
- rtile.h = tile->h;
- rtile.start_sample = tile_manager.state.sample;
- rtile.num_samples = tile_manager.state.num_samples;
- rtile.resolution = tile_manager.state.resolution_divider;
- rtile.tile_index = tile->index;
- rtile.task = (tile->state == Tile::DENOISE)? RenderTile::DENOISE: RenderTile::PATH_TRACE;
-
- tile_lock.unlock();
-
- /* in case of a permanent buffer, return it, otherwise we will allocate
- * a new temporary buffer */
- if(buffers) {
- tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
-
- rtile.buffer = buffers->buffer.device_pointer;
- rtile.buffers = buffers;
-
- device->map_tile(tile_device, rtile);
-
- return true;
- }
-
- if(tile->buffers == NULL) {
- /* fill buffer parameters */
- BufferParams buffer_params = tile_manager.params;
- buffer_params.full_x = rtile.x;
- buffer_params.full_y = rtile.y;
- buffer_params.width = rtile.w;
- buffer_params.height = rtile.h;
-
- /* allocate buffers */
- tile->buffers = new RenderBuffers(tile_device);
- tile->buffers->reset(buffer_params);
- }
-
- tile->buffers->params.get_offset_stride(rtile.offset, rtile.stride);
-
- rtile.buffer = tile->buffers->buffer.device_pointer;
- rtile.buffers = tile->buffers;
- rtile.sample = tile_manager.state.sample;
-
- /* this will tag tile as IN PROGRESS in blender-side render pipeline,
- * which is needed to highlight currently rendering tile before first
- * sample was processed for it
- */
- update_tile_sample(rtile);
-
- return true;
+ if (progress.get_cancel()) {
+ if (params.progressive_refine == false) {
+ /* for progressive refine current sample should be finished for all tiles */
+ return false;
+ }
+ }
+
+ thread_scoped_lock tile_lock(tile_mutex);
+
+ /* get next tile from manager */
+ Tile *tile;
+ int device_num = device->device_number(tile_device);
+
+ if (!tile_manager.next_tile(tile, device_num))
+ return false;
+
+ /* fill render tile */
+ rtile.x = tile_manager.state.buffer.full_x + tile->x;
+ rtile.y = tile_manager.state.buffer.full_y + tile->y;
+ rtile.w = tile->w;
+ rtile.h = tile->h;
+ rtile.start_sample = tile_manager.state.sample;
+ rtile.num_samples = tile_manager.state.num_samples;
+ rtile.resolution = tile_manager.state.resolution_divider;
+ rtile.tile_index = tile->index;
+ rtile.task = (tile->state == Tile::DENOISE) ? RenderTile::DENOISE : RenderTile::PATH_TRACE;
+
+ tile_lock.unlock();
+
+ /* in case of a permanent buffer, return it, otherwise we will allocate
+ * a new temporary buffer */
+ if (buffers) {
+ tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
+
+ rtile.buffer = buffers->buffer.device_pointer;
+ rtile.buffers = buffers;
+
+ device->map_tile(tile_device, rtile);
+
+ return true;
+ }
+
+ if (tile->buffers == NULL) {
+ /* fill buffer parameters */
+ BufferParams buffer_params = tile_manager.params;
+ buffer_params.full_x = rtile.x;
+ buffer_params.full_y = rtile.y;
+ buffer_params.width = rtile.w;
+ buffer_params.height = rtile.h;
+
+ /* allocate buffers */
+ tile->buffers = new RenderBuffers(tile_device);
+ tile->buffers->reset(buffer_params);
+ }
+
+ tile->buffers->params.get_offset_stride(rtile.offset, rtile.stride);
+
+ rtile.buffer = tile->buffers->buffer.device_pointer;
+ rtile.buffers = tile->buffers;
+ rtile.sample = tile_manager.state.sample;
+
+ /* this will tag tile as IN PROGRESS in blender-side render pipeline,
+ * which is needed to highlight currently rendering tile before first
+ * sample was processed for it
+ */
+ update_tile_sample(rtile);
+
+ return true;
}
-void Session::update_tile_sample(RenderTile& rtile)
+void Session::update_tile_sample(RenderTile &rtile)
{
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex);
- if(update_render_tile_cb) {
- if(params.progressive_refine == false) {
- /* todo: optimize this by making it thread safe and removing lock */
+ if (update_render_tile_cb) {
+ if (params.progressive_refine == false) {
+ /* todo: optimize this by making it thread safe and removing lock */
- update_render_tile_cb(rtile, true);
- }
- }
+ update_render_tile_cb(rtile, true);
+ }
+ }
- update_status_time();
+ update_status_time();
}
-void Session::release_tile(RenderTile& rtile)
+void Session::release_tile(RenderTile &rtile)
{
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex);
- progress.add_finished_tile(rtile.task == RenderTile::DENOISE);
+ progress.add_finished_tile(rtile.task == RenderTile::DENOISE);
- bool delete_tile;
+ bool delete_tile;
- if(tile_manager.finish_tile(rtile.tile_index, delete_tile)) {
- if(write_render_tile_cb && params.progressive_refine == false) {
- write_render_tile_cb(rtile);
- }
+ if (tile_manager.finish_tile(rtile.tile_index, delete_tile)) {
+ if (write_render_tile_cb && params.progressive_refine == false) {
+ write_render_tile_cb(rtile);
+ }
- if(delete_tile) {
- delete rtile.buffers;
- tile_manager.state.tiles[rtile.tile_index].buffers = NULL;
- }
- }
- else {
- if(update_render_tile_cb && params.progressive_refine == false) {
- update_render_tile_cb(rtile, false);
- }
- }
+ if (delete_tile) {
+ delete rtile.buffers;
+ tile_manager.state.tiles[rtile.tile_index].buffers = NULL;
+ }
+ }
+ else {
+ if (update_render_tile_cb && params.progressive_refine == false) {
+ update_render_tile_cb(rtile, false);
+ }
+ }
- update_status_time();
+ update_status_time();
}
void Session::map_neighbor_tiles(RenderTile *tiles, Device *tile_device)
{
- thread_scoped_lock tile_lock(tile_mutex);
-
- int center_idx = tiles[4].tile_index;
- assert(tile_manager.state.tiles[center_idx].state == Tile::DENOISE);
- BufferParams buffer_params = tile_manager.params;
- int4 image_region = make_int4(buffer_params.full_x, buffer_params.full_y,
- buffer_params.full_x + buffer_params.width, buffer_params.full_y + buffer_params.height);
-
- for(int dy = -1, i = 0; dy <= 1; dy++) {
- for(int dx = -1; dx <= 1; dx++, i++) {
- int px = tiles[4].x + dx*params.tile_size.x;
- int py = tiles[4].y + dy*params.tile_size.y;
- if(px >= image_region.x && py >= image_region.y &&
- px < image_region.z && py < image_region.w) {
- int tile_index = center_idx + dy*tile_manager.state.tile_stride + dx;
- Tile *tile = &tile_manager.state.tiles[tile_index];
- assert(tile->buffers);
-
- tiles[i].buffer = tile->buffers->buffer.device_pointer;
- tiles[i].x = tile_manager.state.buffer.full_x + tile->x;
- tiles[i].y = tile_manager.state.buffer.full_y + tile->y;
- tiles[i].w = tile->w;
- tiles[i].h = tile->h;
- tiles[i].buffers = tile->buffers;
-
- tile->buffers->params.get_offset_stride(tiles[i].offset, tiles[i].stride);
- }
- else {
- tiles[i].buffer = (device_ptr)NULL;
- tiles[i].buffers = NULL;
- tiles[i].x = clamp(px, image_region.x, image_region.z);
- tiles[i].y = clamp(py, image_region.y, image_region.w);
- tiles[i].w = tiles[i].h = 0;
- }
- }
- }
-
- assert(tiles[4].buffers);
- device->map_neighbor_tiles(tile_device, tiles);
-
- /* The denoised result is written back to the original tile. */
- tiles[9] = tiles[4];
+ thread_scoped_lock tile_lock(tile_mutex);
+
+ int center_idx = tiles[4].tile_index;
+ assert(tile_manager.state.tiles[center_idx].state == Tile::DENOISE);
+ BufferParams buffer_params = tile_manager.params;
+ int4 image_region = make_int4(buffer_params.full_x,
+ buffer_params.full_y,
+ buffer_params.full_x + buffer_params.width,
+ buffer_params.full_y + buffer_params.height);
+
+ for (int dy = -1, i = 0; dy <= 1; dy++) {
+ for (int dx = -1; dx <= 1; dx++, i++) {
+ int px = tiles[4].x + dx * params.tile_size.x;
+ int py = tiles[4].y + dy * params.tile_size.y;
+ if (px >= image_region.x && py >= image_region.y && px < image_region.z &&
+ py < image_region.w) {
+ int tile_index = center_idx + dy * tile_manager.state.tile_stride + dx;
+ Tile *tile = &tile_manager.state.tiles[tile_index];
+ assert(tile->buffers);
+
+ tiles[i].buffer = tile->buffers->buffer.device_pointer;
+ tiles[i].x = tile_manager.state.buffer.full_x + tile->x;
+ tiles[i].y = tile_manager.state.buffer.full_y + tile->y;
+ tiles[i].w = tile->w;
+ tiles[i].h = tile->h;
+ tiles[i].buffers = tile->buffers;
+
+ tile->buffers->params.get_offset_stride(tiles[i].offset, tiles[i].stride);
+ }
+ else {
+ tiles[i].buffer = (device_ptr)NULL;
+ tiles[i].buffers = NULL;
+ tiles[i].x = clamp(px, image_region.x, image_region.z);
+ tiles[i].y = clamp(py, image_region.y, image_region.w);
+ tiles[i].w = tiles[i].h = 0;
+ }
+ }
+ }
+
+ assert(tiles[4].buffers);
+ device->map_neighbor_tiles(tile_device, tiles);
+
+ /* The denoised result is written back to the original tile. */
+ tiles[9] = tiles[4];
}
void Session::unmap_neighbor_tiles(RenderTile *tiles, Device *tile_device)
{
- thread_scoped_lock tile_lock(tile_mutex);
- device->unmap_neighbor_tiles(tile_device, tiles);
+ thread_scoped_lock tile_lock(tile_mutex);
+ device->unmap_neighbor_tiles(tile_device, tiles);
}
void Session::run_cpu()
{
- bool tiles_written = false;
-
- last_update_time = time_dt();
-
- {
- /* reset once to start */
- thread_scoped_lock reset_lock(delayed_reset.mutex);
- thread_scoped_lock buffers_lock(buffers_mutex);
- thread_scoped_lock display_lock(display_mutex);
-
- reset_(delayed_reset.params, delayed_reset.samples);
- delayed_reset.do_reset = false;
- }
-
- while(!progress.get_cancel()) {
- /* advance to next tile */
- bool no_tiles = !tile_manager.next();
- bool need_tonemap = false;
-
- DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN;
- if (no_tiles) {
- kernel_state = device->get_active_kernel_switch_state();
- }
-
- if(params.background) {
- /* if no work left and in background mode, we can stop immediately */
- if(no_tiles) {
- progress.set_status("Finished");
- break;
- }
- }
-
- /* Don't go in pause mode when preview kernels are used
- * When feature kernels become available the session will be resetted. */
- else if (no_tiles && kernel_state == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
- time_sleep(0.1);
- }
- else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
- reset_cpu(tile_manager.params, params.samples);
- }
-
- else {
- /* if in interactive mode, and we are either paused or done for now,
- * wait for pause condition notify to wake up again */
- thread_scoped_lock pause_lock(pause_mutex);
-
- if(!pause && delayed_reset.do_reset) {
- /* reset once to start */
- thread_scoped_lock reset_lock(delayed_reset.mutex);
- thread_scoped_lock buffers_lock(buffers_mutex);
- thread_scoped_lock display_lock(display_mutex);
-
- reset_(delayed_reset.params, delayed_reset.samples);
- delayed_reset.do_reset = false;
- }
- else if(pause || no_tiles) {
- update_status_time(pause, no_tiles);
-
- while(1) {
- scoped_timer pause_timer;
- pause_cond.wait(pause_lock);
- if(pause) {
- progress.add_skip_time(pause_timer, params.background);
- }
-
- update_status_time(pause, no_tiles);
- progress.set_update();
-
- if(!pause)
- break;
- }
- }
-
- if(progress.get_cancel())
- break;
- }
-
- if(!no_tiles) {
- /* buffers mutex is locked entirely while rendering each
- * sample, and released/reacquired on each iteration to allow
- * reset and draw in between */
- thread_scoped_lock buffers_lock(buffers_mutex);
-
- /* update scene */
- scoped_timer update_timer;
- if(update_scene()) {
- profiler.reset(scene->shaders.size(), scene->objects.size());
- }
- progress.add_skip_time(update_timer, params.background);
-
- if(!device->error_message().empty())
- progress.set_error(device->error_message());
-
- if(progress.get_cancel())
- break;
-
- /* update status and timing */
- update_status_time();
-
- /* render */
- render();
-
- /* update status and timing */
- update_status_time();
-
- if(!params.background)
- need_tonemap = true;
-
- if(!device->error_message().empty())
- progress.set_error(device->error_message());
- }
-
- device->task_wait();
-
- {
- thread_scoped_lock reset_lock(delayed_reset.mutex);
- thread_scoped_lock buffers_lock(buffers_mutex);
- thread_scoped_lock display_lock(display_mutex);
-
- if(delayed_reset.do_reset) {
- /* reset rendering if request from main thread */
- delayed_reset.do_reset = false;
- reset_(delayed_reset.params, delayed_reset.samples);
- }
- else if(need_tonemap) {
- /* tonemap only if we do not reset, we don't we don't
- * want to show the result of an incomplete sample */
- tonemap(tile_manager.state.sample);
- }
-
- if(!device->error_message().empty())
- progress.set_error(device->error_message());
-
- tiles_written = update_progressive_refine(progress.get_cancel());
- }
-
- progress.set_update();
- }
-
- if(!tiles_written)
- update_progressive_refine(true);
+ bool tiles_written = false;
+
+ last_update_time = time_dt();
+
+ {
+ /* reset once to start */
+ thread_scoped_lock reset_lock(delayed_reset.mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock display_lock(display_mutex);
+
+ reset_(delayed_reset.params, delayed_reset.samples);
+ delayed_reset.do_reset = false;
+ }
+
+ while (!progress.get_cancel()) {
+ /* advance to next tile */
+ bool no_tiles = !tile_manager.next();
+ bool need_tonemap = false;
+
+ DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN;
+ if (no_tiles) {
+ kernel_state = device->get_active_kernel_switch_state();
+ }
+
+ if (params.background) {
+ /* if no work left and in background mode, we can stop immediately */
+ if (no_tiles) {
+ progress.set_status("Finished");
+ break;
+ }
+ }
+
+ /* Don't go in pause mode when preview kernels are used
+ * When feature kernels become available the session will be resetted. */
+ else if (no_tiles && kernel_state == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
+ time_sleep(0.1);
+ }
+ else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
+ reset_cpu(tile_manager.params, params.samples);
+ }
+
+ else {
+ /* if in interactive mode, and we are either paused or done for now,
+ * wait for pause condition notify to wake up again */
+ thread_scoped_lock pause_lock(pause_mutex);
+
+ if (!pause && delayed_reset.do_reset) {
+ /* reset once to start */
+ thread_scoped_lock reset_lock(delayed_reset.mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock display_lock(display_mutex);
+
+ reset_(delayed_reset.params, delayed_reset.samples);
+ delayed_reset.do_reset = false;
+ }
+ else if (pause || no_tiles) {
+ update_status_time(pause, no_tiles);
+
+ while (1) {
+ scoped_timer pause_timer;
+ pause_cond.wait(pause_lock);
+ if (pause) {
+ progress.add_skip_time(pause_timer, params.background);
+ }
+
+ update_status_time(pause, no_tiles);
+ progress.set_update();
+
+ if (!pause)
+ break;
+ }
+ }
+
+ if (progress.get_cancel())
+ break;
+ }
+
+ if (!no_tiles) {
+ /* buffers mutex is locked entirely while rendering each
+ * sample, and released/reacquired on each iteration to allow
+ * reset and draw in between */
+ thread_scoped_lock buffers_lock(buffers_mutex);
+
+ /* update scene */
+ scoped_timer update_timer;
+ if (update_scene()) {
+ profiler.reset(scene->shaders.size(), scene->objects.size());
+ }
+ progress.add_skip_time(update_timer, params.background);
+
+ if (!device->error_message().empty())
+ progress.set_error(device->error_message());
+
+ if (progress.get_cancel())
+ break;
+
+ /* update status and timing */
+ update_status_time();
+
+ /* render */
+ render();
+
+ /* update status and timing */
+ update_status_time();
+
+ if (!params.background)
+ need_tonemap = true;
+
+ if (!device->error_message().empty())
+ progress.set_error(device->error_message());
+ }
+
+ device->task_wait();
+
+ {
+ thread_scoped_lock reset_lock(delayed_reset.mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock display_lock(display_mutex);
+
+ if (delayed_reset.do_reset) {
+ /* reset rendering if request from main thread */
+ delayed_reset.do_reset = false;
+ reset_(delayed_reset.params, delayed_reset.samples);
+ }
+ else if (need_tonemap) {
+ /* tonemap only if we do not reset, we don't we don't
+ * want to show the result of an incomplete sample */
+ tonemap(tile_manager.state.sample);
+ }
+
+ if (!device->error_message().empty())
+ progress.set_error(device->error_message());
+
+ tiles_written = update_progressive_refine(progress.get_cancel());
+ }
+
+ progress.set_update();
+ }
+
+ if (!tiles_written)
+ update_progressive_refine(true);
}
DeviceRequestedFeatures Session::get_requested_device_features()
{
- /* TODO(sergey): Consider moving this to the Scene level. */
- DeviceRequestedFeatures requested_features;
- requested_features.experimental = params.experimental;
-
- scene->shader_manager->get_requested_features(
- scene,
- &requested_features);
-
- /* This features are not being tweaked as often as shaders,
- * so could be done selective magic for the viewport as well.
- */
- bool use_motion = scene->need_motion() == Scene::MotionType::MOTION_BLUR;
- requested_features.use_hair = false;
- requested_features.use_object_motion = false;
- requested_features.use_camera_motion = use_motion && scene->camera->use_motion();
- foreach(Object *object, scene->objects) {
- Mesh *mesh = object->mesh;
- if(mesh->num_curves()) {
- requested_features.use_hair = true;
- }
- if (use_motion) {
- requested_features.use_object_motion |= object->use_motion() | mesh->use_motion_blur;
- requested_features.use_camera_motion |= mesh->use_motion_blur;
- }
+ /* TODO(sergey): Consider moving this to the Scene level. */
+ DeviceRequestedFeatures requested_features;
+ requested_features.experimental = params.experimental;
+
+ scene->shader_manager->get_requested_features(scene, &requested_features);
+
+ /* This features are not being tweaked as often as shaders,
+ * so could be done selective magic for the viewport as well.
+ */
+ bool use_motion = scene->need_motion() == Scene::MotionType::MOTION_BLUR;
+ requested_features.use_hair = false;
+ requested_features.use_object_motion = false;
+ requested_features.use_camera_motion = use_motion && scene->camera->use_motion();
+ foreach (Object *object, scene->objects) {
+ Mesh *mesh = object->mesh;
+ if (mesh->num_curves()) {
+ requested_features.use_hair = true;
+ }
+ if (use_motion) {
+ requested_features.use_object_motion |= object->use_motion() | mesh->use_motion_blur;
+ requested_features.use_camera_motion |= mesh->use_motion_blur;
+ }
#ifdef WITH_OPENSUBDIV
- if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
- requested_features.use_patch_evaluation = true;
- }
+ if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
+ requested_features.use_patch_evaluation = true;
+ }
#endif
- if(object->is_shadow_catcher) {
- requested_features.use_shadow_tricks = true;
- }
- requested_features.use_true_displacement |= mesh->has_true_displacement();
- }
-
- requested_features.use_background_light = scene->light_manager->has_background_light(scene);
-
- BakeManager *bake_manager = scene->bake_manager;
- requested_features.use_baking = bake_manager->get_baking();
- requested_features.use_integrator_branched = (scene->integrator->method == Integrator::BRANCHED_PATH);
- if(params.run_denoising) {
- requested_features.use_denoising = true;
- requested_features.use_shadow_tricks = true;
- }
-
- return requested_features;
+ if (object->is_shadow_catcher) {
+ requested_features.use_shadow_tricks = true;
+ }
+ requested_features.use_true_displacement |= mesh->has_true_displacement();
+ }
+
+ requested_features.use_background_light = scene->light_manager->has_background_light(scene);
+
+ BakeManager *bake_manager = scene->bake_manager;
+ requested_features.use_baking = bake_manager->get_baking();
+ requested_features.use_integrator_branched = (scene->integrator->method ==
+ Integrator::BRANCHED_PATH);
+ if (params.run_denoising) {
+ requested_features.use_denoising = true;
+ requested_features.use_shadow_tricks = true;
+ }
+
+ return requested_features;
}
bool Session::load_kernels(bool lock_scene)
{
- thread_scoped_lock scene_lock;
- if(lock_scene) {
- scene_lock = thread_scoped_lock(scene->mutex);
- }
-
- DeviceRequestedFeatures requested_features = get_requested_device_features();
-
- if(!kernels_loaded || loaded_kernel_features.modified(requested_features)) {
- progress.set_status("Loading render kernels (may take a few minutes the first time)");
-
- scoped_timer timer;
-
- VLOG(2) << "Requested features:\n" << requested_features;
- if(!device->load_kernels(requested_features)) {
- string message = device->error_message();
- if(message.empty())
- message = "Failed loading render kernel, see console for errors";
-
- progress.set_error(message);
- progress.set_status("Error", message);
- progress.set_update();
- return false;
- }
-
- progress.add_skip_time(timer, false);
- VLOG(1) << "Total time spent loading kernels: " << time_dt() - timer.get_start();
-
- kernels_loaded = true;
- loaded_kernel_features = requested_features;
- return true;
- }
- return false;
+ thread_scoped_lock scene_lock;
+ if (lock_scene) {
+ scene_lock = thread_scoped_lock(scene->mutex);
+ }
+
+ DeviceRequestedFeatures requested_features = get_requested_device_features();
+
+ if (!kernels_loaded || loaded_kernel_features.modified(requested_features)) {
+ progress.set_status("Loading render kernels (may take a few minutes the first time)");
+
+ scoped_timer timer;
+
+ VLOG(2) << "Requested features:\n" << requested_features;
+ if (!device->load_kernels(requested_features)) {
+ string message = device->error_message();
+ if (message.empty())
+ message = "Failed loading render kernel, see console for errors";
+
+ progress.set_error(message);
+ progress.set_status("Error", message);
+ progress.set_update();
+ return false;
+ }
+
+ progress.add_skip_time(timer, false);
+ VLOG(1) << "Total time spent loading kernels: " << time_dt() - timer.get_start();
+
+ kernels_loaded = true;
+ loaded_kernel_features = requested_features;
+ return true;
+ }
+ return false;
}
void Session::run()
{
- if(params.use_profiling && (params.device.type == DEVICE_CPU)) {
- profiler.start();
- }
-
- /* session thread loop */
- progress.set_status("Waiting for render to start");
-
- /* run */
- if(!progress.get_cancel()) {
- /* reset number of rendered samples */
- progress.reset_sample();
-
- if(device_use_gl)
- run_gpu();
- else
- run_cpu();
- }
-
- profiler.stop();
-
- /* progress update */
- if(progress.get_cancel())
- progress.set_status("Cancel", progress.get_cancel_message());
- else
- progress.set_update();
+ if (params.use_profiling && (params.device.type == DEVICE_CPU)) {
+ profiler.start();
+ }
+
+ /* session thread loop */
+ progress.set_status("Waiting for render to start");
+
+ /* run */
+ if (!progress.get_cancel()) {
+ /* reset number of rendered samples */
+ progress.reset_sample();
+
+ if (device_use_gl)
+ run_gpu();
+ else
+ run_cpu();
+ }
+
+ profiler.stop();
+
+ /* progress update */
+ if (progress.get_cancel())
+ progress.set_status("Cancel", progress.get_cancel_message());
+ else
+ progress.set_update();
}
-bool Session::draw(BufferParams& buffer_params, DeviceDrawParams &draw_params)
+bool Session::draw(BufferParams &buffer_params, DeviceDrawParams &draw_params)
{
- if(device_use_gl)
- return draw_gpu(buffer_params, draw_params);
- else
- return draw_cpu(buffer_params, draw_params);
+ if (device_use_gl)
+ return draw_gpu(buffer_params, draw_params);
+ else
+ return draw_cpu(buffer_params, draw_params);
}
-void Session::reset_(BufferParams& buffer_params, int samples)
+void Session::reset_(BufferParams &buffer_params, int samples)
{
- if(buffers && buffer_params.modified(tile_manager.params)) {
- gpu_draw_ready = false;
- buffers->reset(buffer_params);
- if(display) {
- display->reset(buffer_params);
- }
- }
-
- tile_manager.reset(buffer_params, samples);
- progress.reset_sample();
-
- bool show_progress = params.background || tile_manager.get_num_effective_samples() != INT_MAX;
- progress.set_total_pixel_samples(show_progress? tile_manager.state.total_pixel_samples : 0);
-
- if(!params.background)
- progress.set_start_time();
- progress.set_render_start_time();
+ if (buffers && buffer_params.modified(tile_manager.params)) {
+ gpu_draw_ready = false;
+ buffers->reset(buffer_params);
+ if (display) {
+ display->reset(buffer_params);
+ }
+ }
+
+ tile_manager.reset(buffer_params, samples);
+ progress.reset_sample();
+
+ bool show_progress = params.background || tile_manager.get_num_effective_samples() != INT_MAX;
+ progress.set_total_pixel_samples(show_progress ? tile_manager.state.total_pixel_samples : 0);
+
+ if (!params.background)
+ progress.set_start_time();
+ progress.set_render_start_time();
}
-void Session::reset(BufferParams& buffer_params, int samples)
+void Session::reset(BufferParams &buffer_params, int samples)
{
- if(device_use_gl)
- reset_gpu(buffer_params, samples);
- else
- reset_cpu(buffer_params, samples);
+ if (device_use_gl)
+ reset_gpu(buffer_params, samples);
+ else
+ reset_cpu(buffer_params, samples);
}
void Session::set_samples(int samples)
{
- if(samples != params.samples) {
- params.samples = samples;
- tile_manager.set_samples(samples);
-
- {
- thread_scoped_lock pause_lock(pause_mutex);
- }
- pause_cond.notify_all();
- }
+ if (samples != params.samples) {
+ params.samples = samples;
+ tile_manager.set_samples(samples);
+
+ {
+ thread_scoped_lock pause_lock(pause_mutex);
+ }
+ pause_cond.notify_all();
+ }
}
void Session::set_pause(bool pause_)
{
- bool notify = false;
+ bool notify = false;
- {
- thread_scoped_lock pause_lock(pause_mutex);
+ {
+ thread_scoped_lock pause_lock(pause_mutex);
- if(pause != pause_) {
- pause = pause_;
- notify = true;
- }
- }
+ if (pause != pause_) {
+ pause = pause_;
+ notify = true;
+ }
+ }
- if(notify)
- pause_cond.notify_all();
+ if (notify)
+ pause_cond.notify_all();
}
void Session::wait()
{
- if (session_thread) {
- session_thread->join();
- delete session_thread;
- }
+ if (session_thread) {
+ session_thread->join();
+ delete session_thread;
+ }
- session_thread = NULL;
+ session_thread = NULL;
}
bool Session::update_scene()
{
- thread_scoped_lock scene_lock(scene->mutex);
-
- /* update camera if dimensions changed for progressive render. the camera
- * knows nothing about progressive or cropped rendering, it just gets the
- * image dimensions passed in */
- Camera *cam = scene->camera;
- int width = tile_manager.state.buffer.full_width;
- int height = tile_manager.state.buffer.full_height;
- int resolution = tile_manager.state.resolution_divider;
-
- if(width != cam->width || height != cam->height) {
- cam->width = width;
- cam->height = height;
- cam->resolution = resolution;
- cam->tag_update();
- }
-
- /* number of samples is needed by multi jittered
- * sampling pattern and by baking */
- Integrator *integrator = scene->integrator;
- BakeManager *bake_manager = scene->bake_manager;
-
- if(integrator->sampling_pattern == SAMPLING_PATTERN_CMJ ||
- bake_manager->get_baking())
- {
- int aa_samples = tile_manager.num_samples;
-
- if(aa_samples != integrator->aa_samples) {
- integrator->aa_samples = aa_samples;
- integrator->tag_update(scene);
- }
- }
-
- /* update scene */
- if(scene->need_update()) {
- bool new_kernels_needed = load_kernels(false);
-
- /* Update max_closures. */
- KernelIntegrator *kintegrator = &scene->dscene.data.integrator;
- if(params.background) {
- kintegrator->max_closures = get_max_closure_count();
- }
- else {
- /* Currently viewport render is faster with higher max_closures, needs investigating. */
- kintegrator->max_closures = MAX_CLOSURE;
- }
-
- progress.set_status("Updating Scene");
- MEM_GUARDED_CALL(&progress, scene->device_update, device, progress);
-
- DeviceKernelStatus kernel_switch_status = device->get_active_kernel_switch_state();
- bool kernel_switch_needed = kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE ||
- kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
- if (kernel_switch_status == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
- progress.set_kernel_status("Compiling render kernels");
- }
- if (new_kernels_needed || kernel_switch_needed) {
- progress.set_kernel_status("Compiling render kernels");
- device->wait_for_availability(loaded_kernel_features);
- progress.set_kernel_status("");
- }
-
- if (kernel_switch_needed) {
- reset(tile_manager.params, params.samples);
- }
- return true;
- }
- return false;
+ thread_scoped_lock scene_lock(scene->mutex);
+
+ /* update camera if dimensions changed for progressive render. the camera
+ * knows nothing about progressive or cropped rendering, it just gets the
+ * image dimensions passed in */
+ Camera *cam = scene->camera;
+ int width = tile_manager.state.buffer.full_width;
+ int height = tile_manager.state.buffer.full_height;
+ int resolution = tile_manager.state.resolution_divider;
+
+ if (width != cam->width || height != cam->height) {
+ cam->width = width;
+ cam->height = height;
+ cam->resolution = resolution;
+ cam->tag_update();
+ }
+
+ /* number of samples is needed by multi jittered
+ * sampling pattern and by baking */
+ Integrator *integrator = scene->integrator;
+ BakeManager *bake_manager = scene->bake_manager;
+
+ if (integrator->sampling_pattern == SAMPLING_PATTERN_CMJ || bake_manager->get_baking()) {
+ int aa_samples = tile_manager.num_samples;
+
+ if (aa_samples != integrator->aa_samples) {
+ integrator->aa_samples = aa_samples;
+ integrator->tag_update(scene);
+ }
+ }
+
+ /* update scene */
+ if (scene->need_update()) {
+ bool new_kernels_needed = load_kernels(false);
+
+ /* Update max_closures. */
+ KernelIntegrator *kintegrator = &scene->dscene.data.integrator;
+ if (params.background) {
+ kintegrator->max_closures = get_max_closure_count();
+ }
+ else {
+ /* Currently viewport render is faster with higher max_closures, needs investigating. */
+ kintegrator->max_closures = MAX_CLOSURE;
+ }
+
+ progress.set_status("Updating Scene");
+ MEM_GUARDED_CALL(&progress, scene->device_update, device, progress);
+
+ DeviceKernelStatus kernel_switch_status = device->get_active_kernel_switch_state();
+ bool kernel_switch_needed = kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE ||
+ kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
+ if (kernel_switch_status == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
+ progress.set_kernel_status("Compiling render kernels");
+ }
+ if (new_kernels_needed || kernel_switch_needed) {
+ progress.set_kernel_status("Compiling render kernels");
+ device->wait_for_availability(loaded_kernel_features);
+ progress.set_kernel_status("");
+ }
+
+ if (kernel_switch_needed) {
+ reset(tile_manager.params, params.samples);
+ }
+ return true;
+ }
+ return false;
}
void Session::update_status_time(bool show_pause, bool show_done)
{
- int progressive_sample = tile_manager.state.sample;
- int num_samples = tile_manager.get_num_effective_samples();
-
- int tile = progress.get_rendered_tiles();
- int num_tiles = tile_manager.state.num_tiles;
-
- /* update status */
- string status, substatus;
-
- if(!params.progressive) {
- const bool is_cpu = params.device.type == DEVICE_CPU;
- const bool rendering_finished = (tile == num_tiles);
- const bool is_last_tile = (tile + 1) == num_tiles;
-
- substatus = string_printf("Rendered %d/%d Tiles", tile, num_tiles);
-
- if(!rendering_finished && (device->show_samples() || (is_cpu && is_last_tile))) {
- /* Some devices automatically support showing the sample number:
- * - CUDADevice
- * - OpenCLDevice when using the megakernel (the split kernel renders multiple
- * samples at the same time, so the current sample isn't really defined)
- * - CPUDevice when using one thread
- * For these devices, the current sample is always shown.
- *
- * The other option is when the last tile is currently being rendered by the CPU.
- */
- substatus += string_printf(", Sample %d/%d", progress.get_current_sample(), num_samples);
- }
- if(params.full_denoising) {
- substatus += string_printf(", Denoised %d tiles", progress.get_denoised_tiles());
- }
- else if(params.run_denoising) {
- substatus += string_printf(", Prefiltered %d tiles", progress.get_denoised_tiles());
- }
- }
- else if(tile_manager.num_samples == INT_MAX)
- substatus = string_printf("Path Tracing Sample %d", progressive_sample+1);
- else
- substatus = string_printf("Path Tracing Sample %d/%d",
- progressive_sample+1,
- num_samples);
-
- if(show_pause) {
- status = "Rendering Paused";
- }
- else if(show_done) {
- status = "Rendering Done";
- progress.set_end_time(); /* Save end time so that further calls to get_time are accurate. */
- }
- else {
- status = substatus;
- substatus.clear();
- }
-
- progress.set_status(status, substatus);
+ int progressive_sample = tile_manager.state.sample;
+ int num_samples = tile_manager.get_num_effective_samples();
+
+ int tile = progress.get_rendered_tiles();
+ int num_tiles = tile_manager.state.num_tiles;
+
+ /* update status */
+ string status, substatus;
+
+ if (!params.progressive) {
+ const bool is_cpu = params.device.type == DEVICE_CPU;
+ const bool rendering_finished = (tile == num_tiles);
+ const bool is_last_tile = (tile + 1) == num_tiles;
+
+ substatus = string_printf("Rendered %d/%d Tiles", tile, num_tiles);
+
+ if (!rendering_finished && (device->show_samples() || (is_cpu && is_last_tile))) {
+ /* Some devices automatically support showing the sample number:
+ * - CUDADevice
+ * - OpenCLDevice when using the megakernel (the split kernel renders multiple
+ * samples at the same time, so the current sample isn't really defined)
+ * - CPUDevice when using one thread
+ * For these devices, the current sample is always shown.
+ *
+ * The other option is when the last tile is currently being rendered by the CPU.
+ */
+ substatus += string_printf(", Sample %d/%d", progress.get_current_sample(), num_samples);
+ }
+ if (params.full_denoising) {
+ substatus += string_printf(", Denoised %d tiles", progress.get_denoised_tiles());
+ }
+ else if (params.run_denoising) {
+ substatus += string_printf(", Prefiltered %d tiles", progress.get_denoised_tiles());
+ }
+ }
+ else if (tile_manager.num_samples == INT_MAX)
+ substatus = string_printf("Path Tracing Sample %d", progressive_sample + 1);
+ else
+ substatus = string_printf("Path Tracing Sample %d/%d", progressive_sample + 1, num_samples);
+
+ if (show_pause) {
+ status = "Rendering Paused";
+ }
+ else if (show_done) {
+ status = "Rendering Done";
+ progress.set_end_time(); /* Save end time so that further calls to get_time are accurate. */
+ }
+ else {
+ status = substatus;
+ substatus.clear();
+ }
+
+ progress.set_status(status, substatus);
}
void Session::render()
{
- /* Clear buffers. */
- if(buffers && tile_manager.state.sample == tile_manager.range_start_sample) {
- buffers->zero();
- }
-
- /* Add path trace task. */
- DeviceTask task(DeviceTask::RENDER);
-
- task.acquire_tile = function_bind(&Session::acquire_tile, this, _1, _2);
- task.release_tile = function_bind(&Session::release_tile, this, _1);
- task.map_neighbor_tiles = function_bind(&Session::map_neighbor_tiles, this, _1, _2);
- task.unmap_neighbor_tiles = function_bind(&Session::unmap_neighbor_tiles, this, _1, _2);
- task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);
- task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1);
- task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2);
- task.need_finish_queue = params.progressive_refine;
- task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH;
- task.requested_tile_size = params.tile_size;
- task.passes_size = tile_manager.params.get_passes_size();
-
- if(params.run_denoising) {
- task.denoising = params.denoising;
-
- assert(!scene->film->need_update);
- task.pass_stride = scene->film->pass_stride;
- task.target_pass_stride = task.pass_stride;
- task.pass_denoising_data = scene->film->denoising_data_offset;
- task.pass_denoising_clean = scene->film->denoising_clean_offset;
-
- task.denoising_from_render = true;
- task.denoising_do_filter = params.full_denoising;
- task.denoising_write_passes = params.write_denoising_passes;
- }
-
- device->task_add(task);
+ /* Clear buffers. */
+ if (buffers && tile_manager.state.sample == tile_manager.range_start_sample) {
+ buffers->zero();
+ }
+
+ /* Add path trace task. */
+ DeviceTask task(DeviceTask::RENDER);
+
+ task.acquire_tile = function_bind(&Session::acquire_tile, this, _1, _2);
+ task.release_tile = function_bind(&Session::release_tile, this, _1);
+ task.map_neighbor_tiles = function_bind(&Session::map_neighbor_tiles, this, _1, _2);
+ task.unmap_neighbor_tiles = function_bind(&Session::unmap_neighbor_tiles, this, _1, _2);
+ task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);
+ task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1);
+ task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2);
+ task.need_finish_queue = params.progressive_refine;
+ task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH;
+ task.requested_tile_size = params.tile_size;
+ task.passes_size = tile_manager.params.get_passes_size();
+
+ if (params.run_denoising) {
+ task.denoising = params.denoising;
+
+ assert(!scene->film->need_update);
+ task.pass_stride = scene->film->pass_stride;
+ task.target_pass_stride = task.pass_stride;
+ task.pass_denoising_data = scene->film->denoising_data_offset;
+ task.pass_denoising_clean = scene->film->denoising_clean_offset;
+
+ task.denoising_from_render = true;
+ task.denoising_do_filter = params.full_denoising;
+ task.denoising_write_passes = params.write_denoising_passes;
+ }
+
+ device->task_add(task);
}
void Session::tonemap(int sample)
{
- /* add tonemap task */
- DeviceTask task(DeviceTask::FILM_CONVERT);
-
- task.x = tile_manager.state.buffer.full_x;
- task.y = tile_manager.state.buffer.full_y;
- task.w = tile_manager.state.buffer.width;
- task.h = tile_manager.state.buffer.height;
- task.rgba_byte = display->rgba_byte.device_pointer;
- task.rgba_half = display->rgba_half.device_pointer;
- task.buffer = buffers->buffer.device_pointer;
- task.sample = sample;
- tile_manager.state.buffer.get_offset_stride(task.offset, task.stride);
-
- if(task.w > 0 && task.h > 0) {
- device->task_add(task);
- device->task_wait();
-
- /* set display to new size */
- display->draw_set(task.w, task.h);
- }
-
- display_outdated = false;
+ /* add tonemap task */
+ DeviceTask task(DeviceTask::FILM_CONVERT);
+
+ task.x = tile_manager.state.buffer.full_x;
+ task.y = tile_manager.state.buffer.full_y;
+ task.w = tile_manager.state.buffer.width;
+ task.h = tile_manager.state.buffer.height;
+ task.rgba_byte = display->rgba_byte.device_pointer;
+ task.rgba_half = display->rgba_half.device_pointer;
+ task.buffer = buffers->buffer.device_pointer;
+ task.sample = sample;
+ tile_manager.state.buffer.get_offset_stride(task.offset, task.stride);
+
+ if (task.w > 0 && task.h > 0) {
+ device->task_add(task);
+ device->task_wait();
+
+ /* set display to new size */
+ display->draw_set(task.w, task.h);
+ }
+
+ display_outdated = false;
}
bool Session::update_progressive_refine(bool cancel)
{
- int sample = tile_manager.state.sample + 1;
- bool write = sample == tile_manager.num_samples || cancel;
-
- double current_time = time_dt();
-
- if(current_time - last_update_time < params.progressive_update_timeout) {
- /* if last sample was processed, we need to write buffers anyway */
- if(!write && sample != 1)
- return false;
- }
-
- if(params.progressive_refine) {
- foreach(Tile& tile, tile_manager.state.tiles) {
- if(!tile.buffers) {
- continue;
- }
-
- RenderTile rtile;
- rtile.x = tile_manager.state.buffer.full_x + tile.x;
- rtile.y = tile_manager.state.buffer.full_y + tile.y;
- rtile.w = tile.w;
- rtile.h = tile.h;
- rtile.sample = sample;
- rtile.buffers = tile.buffers;
-
- if(write) {
- if(write_render_tile_cb)
- write_render_tile_cb(rtile);
- }
- else {
- if(update_render_tile_cb)
- update_render_tile_cb(rtile, true);
- }
- }
- }
-
- last_update_time = current_time;
-
- return write;
+ int sample = tile_manager.state.sample + 1;
+ bool write = sample == tile_manager.num_samples || cancel;
+
+ double current_time = time_dt();
+
+ if (current_time - last_update_time < params.progressive_update_timeout) {
+ /* if last sample was processed, we need to write buffers anyway */
+ if (!write && sample != 1)
+ return false;
+ }
+
+ if (params.progressive_refine) {
+ foreach (Tile &tile, tile_manager.state.tiles) {
+ if (!tile.buffers) {
+ continue;
+ }
+
+ RenderTile rtile;
+ rtile.x = tile_manager.state.buffer.full_x + tile.x;
+ rtile.y = tile_manager.state.buffer.full_y + tile.y;
+ rtile.w = tile.w;
+ rtile.h = tile.h;
+ rtile.sample = sample;
+ rtile.buffers = tile.buffers;
+
+ if (write) {
+ if (write_render_tile_cb)
+ write_render_tile_cb(rtile);
+ }
+ else {
+ if (update_render_tile_cb)
+ update_render_tile_cb(rtile, true);
+ }
+ }
+ }
+
+ last_update_time = current_time;
+
+ return write;
}
void Session::device_free()
{
- scene->device_free();
+ scene->device_free();
- tile_manager.device_free();
+ tile_manager.device_free();
- /* used from background render only, so no need to
- * re-create render/display buffers here
- */
+ /* used from background render only, so no need to
+ * re-create render/display buffers here
+ */
}
void Session::collect_statistics(RenderStats *render_stats)
{
- scene->collect_statistics(render_stats);
- if(params.use_profiling && (params.device.type == DEVICE_CPU)) {
- render_stats->collect_profiling(scene, profiler);
- }
+ scene->collect_statistics(render_stats);
+ if (params.use_profiling && (params.device.type == DEVICE_CPU)) {
+ render_stats->collect_profiling(scene, profiler);
+ }
}
int Session::get_max_closure_count()
{
- if (scene->shader_manager->use_osl()) {
- /* OSL always needs the maximum as we can't predict the
- * number of closures a shader might generate. */
- return MAX_CLOSURE;
- }
-
- int max_closures = 0;
- for(int i = 0; i < scene->shaders.size(); i++) {
- int num_closures = scene->shaders[i]->graph->get_num_closures();
- max_closures = max(max_closures, num_closures);
- }
- max_closure_global = max(max_closure_global, max_closures);
-
- if (max_closure_global > MAX_CLOSURE) {
- /* This is usually harmless as more complex shader tend to get many
- * closures discarded due to mixing or low weights. We need to limit
- * to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
- * avoids excessive memory usage for split kernels. */
- VLOG(2) << "Maximum number of closures exceeded: "
- << max_closure_global
- << " > "
- << MAX_CLOSURE;
-
- max_closure_global = MAX_CLOSURE;
- }
-
- return max_closure_global;
+ if (scene->shader_manager->use_osl()) {
+ /* OSL always needs the maximum as we can't predict the
+ * number of closures a shader might generate. */
+ return MAX_CLOSURE;
+ }
+
+ int max_closures = 0;
+ for (int i = 0; i < scene->shaders.size(); i++) {
+ int num_closures = scene->shaders[i]->graph->get_num_closures();
+ max_closures = max(max_closures, num_closures);
+ }
+ max_closure_global = max(max_closure_global, max_closures);
+
+ if (max_closure_global > MAX_CLOSURE) {
+ /* This is usually harmless as more complex shader tend to get many
+ * closures discarded due to mixing or low weights. We need to limit
+ * to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
+ * avoids excessive memory usage for split kernels. */
+ VLOG(2) << "Maximum number of closures exceeded: " << max_closure_global << " > "
+ << MAX_CLOSURE;
+
+ max_closure_global = MAX_CLOSURE;
+ }
+
+ return max_closure_global;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 404b7b7a945..60d8f7a8b14 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -42,91 +42,83 @@ class Scene;
/* Session Parameters */
class SessionParams {
-public:
- DeviceInfo device;
- bool background;
- bool progressive_refine;
-
- bool progressive;
- bool experimental;
- int samples;
- int2 tile_size;
- TileOrder tile_order;
- int start_resolution;
- int pixel_size;
- int threads;
-
- bool use_profiling;
-
- bool display_buffer_linear;
-
- bool run_denoising;
- bool write_denoising_passes;
- bool full_denoising;
- DenoiseParams denoising;
-
- double cancel_timeout;
- double reset_timeout;
- double text_timeout;
- double progressive_update_timeout;
-
- ShadingSystem shadingsystem;
-
- function<bool(const uchar *pixels,
- int width,
- int height,
- int channels)> write_render_cb;
-
- SessionParams()
- {
- background = false;
- progressive_refine = false;
-
- progressive = false;
- experimental = false;
- samples = 1024;
- tile_size = make_int2(64, 64);
- start_resolution = INT_MAX;
- pixel_size = 1;
- threads = 0;
-
- use_profiling = false;
-
- run_denoising = false;
- write_denoising_passes = false;
- full_denoising = false;
-
- display_buffer_linear = false;
-
- cancel_timeout = 0.1;
- reset_timeout = 0.1;
- text_timeout = 1.0;
- progressive_update_timeout = 1.0;
-
- shadingsystem = SHADINGSYSTEM_SVM;
- tile_order = TILE_CENTER;
- }
-
- bool modified(const SessionParams& params)
- { return !(device == params.device
- && background == params.background
- && progressive_refine == params.progressive_refine
- /* && samples == params.samples */
- && progressive == params.progressive
- && experimental == params.experimental
- && tile_size == params.tile_size
- && start_resolution == params.start_resolution
- && pixel_size == params.pixel_size
- && threads == params.threads
- && use_profiling == params.use_profiling
- && display_buffer_linear == params.display_buffer_linear
- && cancel_timeout == params.cancel_timeout
- && reset_timeout == params.reset_timeout
- && text_timeout == params.text_timeout
- && progressive_update_timeout == params.progressive_update_timeout
- && tile_order == params.tile_order
- && shadingsystem == params.shadingsystem); }
-
+ public:
+ DeviceInfo device;
+ bool background;
+ bool progressive_refine;
+
+ bool progressive;
+ bool experimental;
+ int samples;
+ int2 tile_size;
+ TileOrder tile_order;
+ int start_resolution;
+ int pixel_size;
+ int threads;
+
+ bool use_profiling;
+
+ bool display_buffer_linear;
+
+ bool run_denoising;
+ bool write_denoising_passes;
+ bool full_denoising;
+ DenoiseParams denoising;
+
+ double cancel_timeout;
+ double reset_timeout;
+ double text_timeout;
+ double progressive_update_timeout;
+
+ ShadingSystem shadingsystem;
+
+ function<bool(const uchar *pixels, int width, int height, int channels)> write_render_cb;
+
+ SessionParams()
+ {
+ background = false;
+ progressive_refine = false;
+
+ progressive = false;
+ experimental = false;
+ samples = 1024;
+ tile_size = make_int2(64, 64);
+ start_resolution = INT_MAX;
+ pixel_size = 1;
+ threads = 0;
+
+ use_profiling = false;
+
+ run_denoising = false;
+ write_denoising_passes = false;
+ full_denoising = false;
+
+ display_buffer_linear = false;
+
+ cancel_timeout = 0.1;
+ reset_timeout = 0.1;
+ text_timeout = 1.0;
+ progressive_update_timeout = 1.0;
+
+ shadingsystem = SHADINGSYSTEM_SVM;
+ tile_order = TILE_CENTER;
+ }
+
+ bool modified(const SessionParams &params)
+ {
+ return !(device == params.device && background == params.background &&
+ progressive_refine == params.progressive_refine
+ /* && samples == params.samples */
+ && progressive == params.progressive && experimental == params.experimental &&
+ tile_size == params.tile_size && start_resolution == params.start_resolution &&
+ pixel_size == params.pixel_size && threads == params.threads &&
+ use_profiling == params.use_profiling &&
+ display_buffer_linear == params.display_buffer_linear &&
+ cancel_timeout == params.cancel_timeout && reset_timeout == params.reset_timeout &&
+ text_timeout == params.text_timeout &&
+ progressive_update_timeout == params.progressive_update_timeout &&
+ tile_order == params.tile_order && shadingsystem == params.shadingsystem);
+ }
};
/* Session
@@ -135,111 +127,111 @@ public:
* control loop and dispatching tasks. */
class Session {
-public:
- Device *device;
- Scene *scene;
- RenderBuffers *buffers;
- DisplayBuffer *display;
- Progress progress;
- SessionParams params;
- TileManager tile_manager;
- Stats stats;
- Profiler profiler;
+ public:
+ Device *device;
+ Scene *scene;
+ RenderBuffers *buffers;
+ DisplayBuffer *display;
+ Progress progress;
+ SessionParams params;
+ TileManager tile_manager;
+ Stats stats;
+ Profiler profiler;
- function<void(RenderTile&)> write_render_tile_cb;
- function<void(RenderTile&, bool)> update_render_tile_cb;
+ function<void(RenderTile &)> write_render_tile_cb;
+ function<void(RenderTile &, bool)> update_render_tile_cb;
- explicit Session(const SessionParams& params);
- ~Session();
+ explicit Session(const SessionParams &params);
+ ~Session();
- void start();
- bool draw(BufferParams& params, DeviceDrawParams& draw_params);
- void wait();
+ void start();
+ bool draw(BufferParams &params, DeviceDrawParams &draw_params);
+ void wait();
- bool ready_to_reset();
- void reset(BufferParams& params, int samples);
- void set_samples(int samples);
- void set_pause(bool pause);
+ bool ready_to_reset();
+ void reset(BufferParams &params, int samples);
+ void set_samples(int samples);
+ void set_pause(bool pause);
- bool update_scene();
- bool load_kernels(bool lock_scene=true);
+ bool update_scene();
+ bool load_kernels(bool lock_scene = true);
- void device_free();
+ void device_free();
- /* Returns the rendering progress or 0 if no progress can be determined
- * (for example, when rendering with unlimited samples). */
- float get_progress();
+ /* Returns the rendering progress or 0 if no progress can be determined
+ * (for example, when rendering with unlimited samples). */
+ float get_progress();
- void collect_statistics(RenderStats *stats);
+ void collect_statistics(RenderStats *stats);
-protected:
- struct DelayedReset {
- thread_mutex mutex;
- bool do_reset;
- BufferParams params;
- int samples;
- } delayed_reset;
+ protected:
+ struct DelayedReset {
+ thread_mutex mutex;
+ bool do_reset;
+ BufferParams params;
+ int samples;
+ } delayed_reset;
- void run();
+ void run();
- void update_status_time(bool show_pause = false, bool show_done = false);
+ void update_status_time(bool show_pause = false, bool show_done = false);
- void tonemap(int sample);
- void render();
- void reset_(BufferParams& params, int samples);
+ void tonemap(int sample);
+ void render();
+ void reset_(BufferParams &params, int samples);
- void run_cpu();
- bool draw_cpu(BufferParams& params, DeviceDrawParams& draw_params);
- void reset_cpu(BufferParams& params, int samples);
+ void run_cpu();
+ bool draw_cpu(BufferParams &params, DeviceDrawParams &draw_params);
+ void reset_cpu(BufferParams &params, int samples);
- void run_gpu();
- bool draw_gpu(BufferParams& params, DeviceDrawParams& draw_params);
- void reset_gpu(BufferParams& params, int samples);
+ void run_gpu();
+ bool draw_gpu(BufferParams &params, DeviceDrawParams &draw_params);
+ void reset_gpu(BufferParams &params, int samples);
- bool acquire_tile(Device *tile_device, RenderTile& tile);
- void update_tile_sample(RenderTile& tile);
- void release_tile(RenderTile& tile);
+ bool acquire_tile(Device *tile_device, RenderTile &tile);
+ void update_tile_sample(RenderTile &tile);
+ void release_tile(RenderTile &tile);
- void map_neighbor_tiles(RenderTile *tiles, Device *tile_device);
- void unmap_neighbor_tiles(RenderTile *tiles, Device *tile_device);
+ void map_neighbor_tiles(RenderTile *tiles, Device *tile_device);
+ void unmap_neighbor_tiles(RenderTile *tiles, Device *tile_device);
- bool device_use_gl;
+ bool device_use_gl;
- thread *session_thread;
+ thread *session_thread;
- volatile bool display_outdated;
+ volatile bool display_outdated;
- volatile bool gpu_draw_ready;
- volatile bool gpu_need_tonemap;
- thread_condition_variable gpu_need_tonemap_cond;
+ volatile bool gpu_draw_ready;
+ volatile bool gpu_need_tonemap;
+ thread_condition_variable gpu_need_tonemap_cond;
- bool pause;
- thread_condition_variable pause_cond;
- thread_mutex pause_mutex;
- thread_mutex tile_mutex;
- thread_mutex buffers_mutex;
- thread_mutex display_mutex;
+ bool pause;
+ thread_condition_variable pause_cond;
+ thread_mutex pause_mutex;
+ thread_mutex tile_mutex;
+ thread_mutex buffers_mutex;
+ thread_mutex display_mutex;
- bool kernels_loaded;
- DeviceRequestedFeatures loaded_kernel_features;
+ bool kernels_loaded;
+ DeviceRequestedFeatures loaded_kernel_features;
- double reset_time;
+ double reset_time;
- /* progressive refine */
- double last_update_time;
- bool update_progressive_refine(bool cancel);
+ /* progressive refine */
+ double last_update_time;
+ bool update_progressive_refine(bool cancel);
- DeviceRequestedFeatures get_requested_device_features();
+ DeviceRequestedFeatures get_requested_device_features();
- /* ** Split kernel routines ** */
+ /* ** Split kernel routines ** */
- /* Maximumnumber of closure during session lifetime. */
- int max_closure_global;
+ /* Maximumnumber of closure during session lifetime. */
+ int max_closure_global;
- /* Get maximum number of closures to be used in kernel. */
- int get_max_closure_count();
+ /* Get maximum number of closures to be used in kernel. */
+ int get_max_closure_count();
};
CCL_NAMESPACE_END
-#endif /* __SESSION_H__ */
+#endif /* __SESSION_H__ */
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 3c94f2dfb59..ac3303cbfeb 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -48,16 +48,15 @@ bool ShaderManager::beckmann_table_ready = false;
/* 2D slope distribution (alpha = 1.0) */
static float beckmann_table_P22(const float slope_x, const float slope_y)
{
- return expf(-(slope_x*slope_x + slope_y*slope_y));
+ return expf(-(slope_x * slope_x + slope_y * slope_y));
}
/* maximal slope amplitude (range that contains 99.99% of the distribution) */
static float beckmann_table_slope_max()
{
- return 6.0;
+ return 6.0;
}
-
/* MSVC 2015 needs this ugly hack to prevent a codegen bug on x86
* see T50176 for details
*/
@@ -74,327 +73,331 @@ static float beckmann_table_slope_max()
*/
static void beckmann_table_rows(float *table, int row_from, int row_to)
{
- /* allocate temporary data */
- const int DATA_TMP_SIZE = 512;
- vector<double> slope_x(DATA_TMP_SIZE);
- vector<double> CDF_P22_omega_i(DATA_TMP_SIZE);
-
- /* loop over incident directions */
- for(int index_theta = row_from; index_theta < row_to; index_theta++) {
- /* incident vector */
- const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f);
- const float sin_theta = safe_sqrtf(1.0f - cos_theta*cos_theta);
-
- /* for a given incident vector
- * integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
- slope_x[0] = (double)-beckmann_table_slope_max();
- CDF_P22_omega_i[0] = 0;
-
- for(MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) {
- /* slope_x */
- slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() + 2.0f * beckmann_table_slope_max() * index_slope_x/(DATA_TMP_SIZE - 1.0f));
-
- /* dot product with incident vector */
- float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x]*sin_theta + cos_theta);
- /* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
- float P22_omega_i = 0.0f;
-
- for(int j = 0; j < 100; ++j) {
- float slope_y = -beckmann_table_slope_max() + 2.0f * beckmann_table_slope_max() * j * (1.0f/99.0f);
- P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y);
- }
-
- /* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
- CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i;
- }
-
- /* renormalize CDF_P22_omega_i */
- for(int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x)
- CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1];
-
- /* loop over random number U1 */
- int index_slope_x = 0;
-
- for(int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) {
- const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1);
-
- /* inverse CDF_P22_omega_i, solve Eq.(11) */
- while(CDF_P22_omega_i[index_slope_x] <= U)
- ++index_slope_x;
-
- const double interp =
- (CDF_P22_omega_i[index_slope_x] - U) /
- (CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]);
-
- /* store value */
- table[index_U + index_theta*BECKMANN_TABLE_SIZE] = (float)(
- interp * slope_x[index_slope_x - 1] +
- (1.0 - interp) * slope_x[index_slope_x]);
- }
- }
+ /* allocate temporary data */
+ const int DATA_TMP_SIZE = 512;
+ vector<double> slope_x(DATA_TMP_SIZE);
+ vector<double> CDF_P22_omega_i(DATA_TMP_SIZE);
+
+ /* loop over incident directions */
+ for (int index_theta = row_from; index_theta < row_to; index_theta++) {
+ /* incident vector */
+ const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f);
+ const float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
+
+ /* for a given incident vector
+ * integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
+ slope_x[0] = (double)-beckmann_table_slope_max();
+ CDF_P22_omega_i[0] = 0;
+
+ for (MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) {
+ /* slope_x */
+ slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() +
+ 2.0f * beckmann_table_slope_max() * index_slope_x /
+ (DATA_TMP_SIZE - 1.0f));
+
+ /* dot product with incident vector */
+ float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x] * sin_theta + cos_theta);
+ /* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
+ float P22_omega_i = 0.0f;
+
+ for (int j = 0; j < 100; ++j) {
+ float slope_y = -beckmann_table_slope_max() +
+ 2.0f * beckmann_table_slope_max() * j * (1.0f / 99.0f);
+ P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y);
+ }
+
+ /* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
+ CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i;
+ }
+
+ /* renormalize CDF_P22_omega_i */
+ for (int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x)
+ CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1];
+
+ /* loop over random number U1 */
+ int index_slope_x = 0;
+
+ for (int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) {
+ const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1);
+
+ /* inverse CDF_P22_omega_i, solve Eq.(11) */
+ while (CDF_P22_omega_i[index_slope_x] <= U)
+ ++index_slope_x;
+
+ const double interp = (CDF_P22_omega_i[index_slope_x] - U) /
+ (CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]);
+
+ /* store value */
+ table[index_U + index_theta * BECKMANN_TABLE_SIZE] =
+ (float)(interp * slope_x[index_slope_x - 1] + (1.0 - interp) * slope_x[index_slope_x]);
+ }
+ }
}
#undef MSVC_VOLATILE
-static void beckmann_table_build(vector<float>& table)
+static void beckmann_table_build(vector<float> &table)
{
- table.resize(BECKMANN_TABLE_SIZE*BECKMANN_TABLE_SIZE);
+ table.resize(BECKMANN_TABLE_SIZE * BECKMANN_TABLE_SIZE);
- /* multithreaded build */
- TaskPool pool;
+ /* multithreaded build */
+ TaskPool pool;
- for(int i = 0; i < BECKMANN_TABLE_SIZE; i+=8)
- pool.push(function_bind(&beckmann_table_rows, &table[0], i, i+8));
+ for (int i = 0; i < BECKMANN_TABLE_SIZE; i += 8)
+ pool.push(function_bind(&beckmann_table_rows, &table[0], i, i + 8));
- pool.wait_work();
+ pool.wait_work();
}
/* Shader */
NODE_DEFINE(Shader)
{
- NodeType* type = NodeType::add("shader", create);
-
- SOCKET_BOOLEAN(use_mis, "Use MIS", true);
- SOCKET_BOOLEAN(use_transparent_shadow, "Use Transparent Shadow", true);
- SOCKET_BOOLEAN(heterogeneous_volume, "Heterogeneous Volume", true);
-
- static NodeEnum volume_sampling_method_enum;
- volume_sampling_method_enum.insert("distance", VOLUME_SAMPLING_DISTANCE);
- volume_sampling_method_enum.insert("equiangular", VOLUME_SAMPLING_EQUIANGULAR);
- volume_sampling_method_enum.insert("multiple_importance", VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
- SOCKET_ENUM(volume_sampling_method, "Volume Sampling Method", volume_sampling_method_enum, VOLUME_SAMPLING_DISTANCE);
-
- static NodeEnum volume_interpolation_method_enum;
- volume_interpolation_method_enum.insert("linear", VOLUME_INTERPOLATION_LINEAR);
- volume_interpolation_method_enum.insert("cubic", VOLUME_INTERPOLATION_CUBIC);
- SOCKET_ENUM(volume_interpolation_method, "Volume Interpolation Method", volume_interpolation_method_enum, VOLUME_INTERPOLATION_LINEAR);
-
- static NodeEnum displacement_method_enum;
- displacement_method_enum.insert("bump", DISPLACE_BUMP);
- displacement_method_enum.insert("true", DISPLACE_TRUE);
- displacement_method_enum.insert("both", DISPLACE_BOTH);
- SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP);
-
- return type;
+ NodeType *type = NodeType::add("shader", create);
+
+ SOCKET_BOOLEAN(use_mis, "Use MIS", true);
+ SOCKET_BOOLEAN(use_transparent_shadow, "Use Transparent Shadow", true);
+ SOCKET_BOOLEAN(heterogeneous_volume, "Heterogeneous Volume", true);
+
+ static NodeEnum volume_sampling_method_enum;
+ volume_sampling_method_enum.insert("distance", VOLUME_SAMPLING_DISTANCE);
+ volume_sampling_method_enum.insert("equiangular", VOLUME_SAMPLING_EQUIANGULAR);
+ volume_sampling_method_enum.insert("multiple_importance", VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
+ SOCKET_ENUM(volume_sampling_method,
+ "Volume Sampling Method",
+ volume_sampling_method_enum,
+ VOLUME_SAMPLING_DISTANCE);
+
+ static NodeEnum volume_interpolation_method_enum;
+ volume_interpolation_method_enum.insert("linear", VOLUME_INTERPOLATION_LINEAR);
+ volume_interpolation_method_enum.insert("cubic", VOLUME_INTERPOLATION_CUBIC);
+ SOCKET_ENUM(volume_interpolation_method,
+ "Volume Interpolation Method",
+ volume_interpolation_method_enum,
+ VOLUME_INTERPOLATION_LINEAR);
+
+ static NodeEnum displacement_method_enum;
+ displacement_method_enum.insert("bump", DISPLACE_BUMP);
+ displacement_method_enum.insert("true", DISPLACE_TRUE);
+ displacement_method_enum.insert("both", DISPLACE_BOTH);
+ SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP);
+
+ return type;
}
-Shader::Shader()
-: Node(node_type)
+Shader::Shader() : Node(node_type)
{
- pass_id = 0;
-
- graph = NULL;
-
- has_surface = false;
- has_surface_transparent = false;
- has_surface_emission = false;
- has_surface_bssrdf = false;
- has_volume = false;
- has_displacement = false;
- has_bump = false;
- has_bssrdf_bump = false;
- has_surface_spatial_varying = false;
- has_volume_spatial_varying = false;
- has_object_dependency = false;
- has_attribute_dependency = false;
- has_integrator_dependency = false;
- has_volume_connected = false;
-
- displacement_method = DISPLACE_BUMP;
-
- id = -1;
- used = false;
-
- need_update = true;
- need_update_mesh = true;
- need_sync_object = false;
+ pass_id = 0;
+
+ graph = NULL;
+
+ has_surface = false;
+ has_surface_transparent = false;
+ has_surface_emission = false;
+ has_surface_bssrdf = false;
+ has_volume = false;
+ has_displacement = false;
+ has_bump = false;
+ has_bssrdf_bump = false;
+ has_surface_spatial_varying = false;
+ has_volume_spatial_varying = false;
+ has_object_dependency = false;
+ has_attribute_dependency = false;
+ has_integrator_dependency = false;
+ has_volume_connected = false;
+
+ displacement_method = DISPLACE_BUMP;
+
+ id = -1;
+ used = false;
+
+ need_update = true;
+ need_update_mesh = true;
+ need_sync_object = false;
}
Shader::~Shader()
{
- delete graph;
+ delete graph;
}
bool Shader::is_constant_emission(float3 *emission)
{
- ShaderInput *surf = graph->output()->input("Surface");
+ ShaderInput *surf = graph->output()->input("Surface");
- if(surf->link == NULL) {
- return false;
- }
+ if (surf->link == NULL) {
+ return false;
+ }
- if(surf->link->parent->type == EmissionNode::node_type) {
- EmissionNode *node = (EmissionNode*) surf->link->parent;
+ if (surf->link->parent->type == EmissionNode::node_type) {
+ EmissionNode *node = (EmissionNode *)surf->link->parent;
- assert(node->input("Color"));
- assert(node->input("Strength"));
+ assert(node->input("Color"));
+ assert(node->input("Strength"));
- if(node->input("Color")->link || node->input("Strength")->link) {
- return false;
- }
+ if (node->input("Color")->link || node->input("Strength")->link) {
+ return false;
+ }
- *emission = node->color*node->strength;
- }
- else if(surf->link->parent->type == BackgroundNode::node_type) {
- BackgroundNode *node = (BackgroundNode*) surf->link->parent;
+ *emission = node->color * node->strength;
+ }
+ else if (surf->link->parent->type == BackgroundNode::node_type) {
+ BackgroundNode *node = (BackgroundNode *)surf->link->parent;
- assert(node->input("Color"));
- assert(node->input("Strength"));
+ assert(node->input("Color"));
+ assert(node->input("Strength"));
- if(node->input("Color")->link || node->input("Strength")->link) {
- return false;
- }
+ if (node->input("Color")->link || node->input("Strength")->link) {
+ return false;
+ }
- *emission = node->color*node->strength;
- }
- else {
- return false;
- }
+ *emission = node->color * node->strength;
+ }
+ else {
+ return false;
+ }
- return true;
+ return true;
}
void Shader::set_graph(ShaderGraph *graph_)
{
- /* do this here already so that we can detect if mesh or object attributes
- * are needed, since the node attribute callbacks check if their sockets
- * are connected but proxy nodes should not count */
- if(graph_) {
- graph_->remove_proxy_nodes();
-
- if(displacement_method != DISPLACE_BUMP) {
- graph_->compute_displacement_hash();
- }
- }
-
- /* update geometry if displacement changed */
- if(displacement_method != DISPLACE_BUMP) {
- const char *old_hash = (graph)? graph->displacement_hash.c_str() : "";
- const char *new_hash = (graph_)? graph_->displacement_hash.c_str() : "";
-
- if(strcmp(old_hash, new_hash) != 0) {
- need_update_mesh = true;
- }
- }
-
- /* assign graph */
- delete graph;
- graph = graph_;
-
- /* Store info here before graph optimization to make sure that
- * nodes that get optimized away still count. */
- has_volume_connected = (graph->output()->input("Volume")->link != NULL);
+ /* do this here already so that we can detect if mesh or object attributes
+ * are needed, since the node attribute callbacks check if their sockets
+ * are connected but proxy nodes should not count */
+ if (graph_) {
+ graph_->remove_proxy_nodes();
+
+ if (displacement_method != DISPLACE_BUMP) {
+ graph_->compute_displacement_hash();
+ }
+ }
+
+ /* update geometry if displacement changed */
+ if (displacement_method != DISPLACE_BUMP) {
+ const char *old_hash = (graph) ? graph->displacement_hash.c_str() : "";
+ const char *new_hash = (graph_) ? graph_->displacement_hash.c_str() : "";
+
+ if (strcmp(old_hash, new_hash) != 0) {
+ need_update_mesh = true;
+ }
+ }
+
+ /* assign graph */
+ delete graph;
+ graph = graph_;
+
+ /* Store info here before graph optimization to make sure that
+ * nodes that get optimized away still count. */
+ has_volume_connected = (graph->output()->input("Volume")->link != NULL);
}
void Shader::tag_update(Scene *scene)
{
- /* update tag */
- need_update = true;
- scene->shader_manager->need_update = true;
-
- /* if the shader previously was emissive, update light distribution,
- * if the new shader is emissive, a light manager update tag will be
- * done in the shader manager device update. */
- if(use_mis && has_surface_emission)
- scene->light_manager->need_update = true;
-
- /* Special handle of background MIS light for now: for some reason it
- * has use_mis set to false. We are quite close to release now, so
- * better to be safe.
- */
- if(this == scene->default_background &&
- scene->light_manager->has_background_light(scene))
- {
- scene->light_manager->need_update = true;
- }
-
- /* quick detection of which kind of shaders we have to avoid loading
- * e.g. surface attributes when there is only a volume shader. this could
- * be more fine grained but it's better than nothing */
- OutputNode *output = graph->output();
- bool prev_has_volume = has_volume;
- has_surface = has_surface || output->input("Surface")->link;
- has_volume = has_volume || output->input("Volume")->link;
- has_displacement = has_displacement || output->input("Displacement")->link;
-
- /* get requested attributes. this could be optimized by pruning unused
- * nodes here already, but that's the job of the shader manager currently,
- * and may not be so great for interactive rendering where you temporarily
- * disconnect a node */
-
- AttributeRequestSet prev_attributes = attributes;
-
- attributes.clear();
- foreach(ShaderNode *node, graph->nodes)
- node->attributes(this, &attributes);
-
- if(has_displacement && displacement_method == DISPLACE_BOTH) {
- attributes.add(ATTR_STD_POSITION_UNDISPLACED);
- }
-
- /* compare if the attributes changed, mesh manager will check
- * need_update_mesh, update the relevant meshes and clear it. */
- if(attributes.modified(prev_attributes)) {
- need_update_mesh = true;
- scene->mesh_manager->need_update = true;
- }
-
- if(has_volume != prev_has_volume) {
- scene->mesh_manager->need_flags_update = true;
- scene->object_manager->need_flags_update = true;
- }
+ /* update tag */
+ need_update = true;
+ scene->shader_manager->need_update = true;
+
+ /* if the shader previously was emissive, update light distribution,
+ * if the new shader is emissive, a light manager update tag will be
+ * done in the shader manager device update. */
+ if (use_mis && has_surface_emission)
+ scene->light_manager->need_update = true;
+
+ /* Special handle of background MIS light for now: for some reason it
+ * has use_mis set to false. We are quite close to release now, so
+ * better to be safe.
+ */
+ if (this == scene->default_background && scene->light_manager->has_background_light(scene)) {
+ scene->light_manager->need_update = true;
+ }
+
+ /* quick detection of which kind of shaders we have to avoid loading
+ * e.g. surface attributes when there is only a volume shader. this could
+ * be more fine grained but it's better than nothing */
+ OutputNode *output = graph->output();
+ bool prev_has_volume = has_volume;
+ has_surface = has_surface || output->input("Surface")->link;
+ has_volume = has_volume || output->input("Volume")->link;
+ has_displacement = has_displacement || output->input("Displacement")->link;
+
+ /* get requested attributes. this could be optimized by pruning unused
+ * nodes here already, but that's the job of the shader manager currently,
+ * and may not be so great for interactive rendering where you temporarily
+ * disconnect a node */
+
+ AttributeRequestSet prev_attributes = attributes;
+
+ attributes.clear();
+ foreach (ShaderNode *node, graph->nodes)
+ node->attributes(this, &attributes);
+
+ if (has_displacement && displacement_method == DISPLACE_BOTH) {
+ attributes.add(ATTR_STD_POSITION_UNDISPLACED);
+ }
+
+ /* compare if the attributes changed, mesh manager will check
+ * need_update_mesh, update the relevant meshes and clear it. */
+ if (attributes.modified(prev_attributes)) {
+ need_update_mesh = true;
+ scene->mesh_manager->need_update = true;
+ }
+
+ if (has_volume != prev_has_volume) {
+ scene->mesh_manager->need_flags_update = true;
+ scene->object_manager->need_flags_update = true;
+ }
}
void Shader::tag_used(Scene *scene)
{
- /* if an unused shader suddenly gets used somewhere, it needs to be
- * recompiled because it was skipped for compilation before */
- if(!used) {
- need_update = true;
- scene->shader_manager->need_update = true;
- }
+ /* if an unused shader suddenly gets used somewhere, it needs to be
+ * recompiled because it was skipped for compilation before */
+ if (!used) {
+ need_update = true;
+ scene->shader_manager->need_update = true;
+ }
}
/* Shader Manager */
ShaderManager::ShaderManager()
{
- need_update = true;
- beckmann_table_offset = TABLE_OFFSET_INVALID;
+ need_update = true;
+ beckmann_table_offset = TABLE_OFFSET_INVALID;
- xyz_to_r = make_float3( 3.2404542f, -1.5371385f, -0.4985314f);
- xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
- xyz_to_b = make_float3( 0.0556434f, -0.2040259f, 1.0572252f);
- rgb_to_y = make_float3( 0.2126729f, 0.7151522f, 0.0721750f);
+ xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
+ xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
+ xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
+ rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
#ifdef WITH_OCIO
- OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
- if(config) {
- if(config->hasRole("XYZ") && config->hasRole("scene_linear")) {
- OCIO::ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
- OCIO::ConstProcessorRcPtr to_xyz_processor = config->getProcessor("scene_linear", "XYZ");
- if(to_rgb_processor && to_xyz_processor) {
- float r[] = {1.0f, 0.0f, 0.0f};
- float g[] = {0.0f, 1.0f, 0.0f};
- float b[] = {0.0f, 0.0f, 1.0f};
- to_xyz_processor->applyRGB(r);
- to_xyz_processor->applyRGB(g);
- to_xyz_processor->applyRGB(b);
- rgb_to_y = make_float3(r[1], g[1], b[1]);
-
- float x[] = {1.0f, 0.0f, 0.0f};
- float y[] = {0.0f, 1.0f, 0.0f};
- float z[] = {0.0f, 0.0f, 1.0f};
- to_rgb_processor->applyRGB(x);
- to_rgb_processor->applyRGB(y);
- to_rgb_processor->applyRGB(z);
- xyz_to_r = make_float3(x[0], y[0], z[0]);
- xyz_to_g = make_float3(x[1], y[1], z[1]);
- xyz_to_b = make_float3(x[2], y[2], z[2]);
- }
- }
- }
+ OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
+ if (config) {
+ if (config->hasRole("XYZ") && config->hasRole("scene_linear")) {
+ OCIO::ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
+ OCIO::ConstProcessorRcPtr to_xyz_processor = config->getProcessor("scene_linear", "XYZ");
+ if (to_rgb_processor && to_xyz_processor) {
+ float r[] = {1.0f, 0.0f, 0.0f};
+ float g[] = {0.0f, 1.0f, 0.0f};
+ float b[] = {0.0f, 0.0f, 1.0f};
+ to_xyz_processor->applyRGB(r);
+ to_xyz_processor->applyRGB(g);
+ to_xyz_processor->applyRGB(b);
+ rgb_to_y = make_float3(r[1], g[1], b[1]);
+
+ float x[] = {1.0f, 0.0f, 0.0f};
+ float y[] = {0.0f, 1.0f, 0.0f};
+ float z[] = {0.0f, 0.0f, 1.0f};
+ to_rgb_processor->applyRGB(x);
+ to_rgb_processor->applyRGB(y);
+ to_rgb_processor->applyRGB(z);
+ xyz_to_r = make_float3(x[0], y[0], z[0]);
+ xyz_to_g = make_float3(x[1], y[1], z[1]);
+ xyz_to_b = make_float3(x[2], y[2], z[2]);
+ }
+ }
+ }
#endif
}
@@ -404,337 +407,337 @@ ShaderManager::~ShaderManager()
ShaderManager *ShaderManager::create(Scene *scene, int shadingsystem)
{
- ShaderManager *manager;
+ ShaderManager *manager;
- (void) shadingsystem; /* Ignored when built without OSL. */
+ (void)shadingsystem; /* Ignored when built without OSL. */
#ifdef WITH_OSL
- if(shadingsystem == SHADINGSYSTEM_OSL) {
- manager = new OSLShaderManager();
- }
- else
+ if (shadingsystem == SHADINGSYSTEM_OSL) {
+ manager = new OSLShaderManager();
+ }
+ else
#endif
- {
- manager = new SVMShaderManager();
- }
+ {
+ manager = new SVMShaderManager();
+ }
- add_default(scene);
+ add_default(scene);
- return manager;
+ return manager;
}
uint ShaderManager::get_attribute_id(ustring name)
{
- thread_scoped_spin_lock lock(attribute_lock_);
+ thread_scoped_spin_lock lock(attribute_lock_);
- /* get a unique id for each name, for SVM attribute lookup */
- AttributeIDMap::iterator it = unique_attribute_id.find(name);
+ /* get a unique id for each name, for SVM attribute lookup */
+ AttributeIDMap::iterator it = unique_attribute_id.find(name);
- if(it != unique_attribute_id.end())
- return it->second;
+ if (it != unique_attribute_id.end())
+ return it->second;
- uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
- unique_attribute_id[name] = id;
- return id;
+ uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
+ unique_attribute_id[name] = id;
+ return id;
}
uint ShaderManager::get_attribute_id(AttributeStandard std)
{
- return (uint)std;
+ return (uint)std;
}
int ShaderManager::get_shader_id(Shader *shader, bool smooth)
{
- /* get a shader id to pass to the kernel */
- int id = shader->id;
+ /* get a shader id to pass to the kernel */
+ int id = shader->id;
- /* smooth flag */
- if(smooth)
- id |= SHADER_SMOOTH_NORMAL;
+ /* smooth flag */
+ if (smooth)
+ id |= SHADER_SMOOTH_NORMAL;
- /* default flags */
- id |= SHADER_CAST_SHADOW|SHADER_AREA_LIGHT;
+ /* default flags */
+ id |= SHADER_CAST_SHADOW | SHADER_AREA_LIGHT;
- return id;
+ return id;
}
void ShaderManager::device_update_shaders_used(Scene *scene)
{
- /* figure out which shaders are in use, so SVM/OSL can skip compiling them
- * for speed and avoid loading image textures into memory */
- uint id = 0;
- foreach(Shader *shader, scene->shaders) {
- shader->used = false;
- shader->id = id++;
- }
-
- scene->default_surface->used = true;
- scene->default_light->used = true;
- scene->default_background->used = true;
- scene->default_empty->used = true;
-
- if(scene->background->shader)
- scene->background->shader->used = true;
-
- foreach(Mesh *mesh, scene->meshes)
- foreach(Shader *shader, mesh->used_shaders)
- shader->used = true;
-
- foreach(Light *light, scene->lights)
- if(light->shader)
- light->shader->used = true;
+ /* figure out which shaders are in use, so SVM/OSL can skip compiling them
+ * for speed and avoid loading image textures into memory */
+ uint id = 0;
+ foreach (Shader *shader, scene->shaders) {
+ shader->used = false;
+ shader->id = id++;
+ }
+
+ scene->default_surface->used = true;
+ scene->default_light->used = true;
+ scene->default_background->used = true;
+ scene->default_empty->used = true;
+
+ if (scene->background->shader)
+ scene->background->shader->used = true;
+
+ foreach (Mesh *mesh, scene->meshes)
+ foreach (Shader *shader, mesh->used_shaders)
+ shader->used = true;
+
+ foreach (Light *light, scene->lights)
+ if (light->shader)
+ light->shader->used = true;
}
void ShaderManager::device_update_common(Device *device,
DeviceScene *dscene,
Scene *scene,
- Progress& /*progress*/)
+ Progress & /*progress*/)
{
- dscene->shaders.free();
-
- if(scene->shaders.size() == 0)
- return;
-
- KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
- bool has_volumes = false;
- bool has_transparent_shadow = false;
-
- foreach(Shader *shader, scene->shaders) {
- uint flag = 0;
-
- if(shader->use_mis)
- flag |= SD_USE_MIS;
- if(shader->has_surface_transparent && shader->use_transparent_shadow)
- flag |= SD_HAS_TRANSPARENT_SHADOW;
- if(shader->has_volume) {
- flag |= SD_HAS_VOLUME;
- has_volumes = true;
-
- /* todo: this could check more fine grained, to skip useless volumes
- * enclosed inside an opaque bsdf.
- */
- flag |= SD_HAS_TRANSPARENT_SHADOW;
- }
- /* in this case we can assume transparent surface */
- if(shader->has_volume_connected && !shader->has_surface)
- flag |= SD_HAS_ONLY_VOLUME;
- if(shader->heterogeneous_volume && shader->has_volume_spatial_varying)
- flag |= SD_HETEROGENEOUS_VOLUME;
- if(shader->has_attribute_dependency)
- flag |= SD_NEED_ATTRIBUTES;
- if(shader->has_bssrdf_bump)
- flag |= SD_HAS_BSSRDF_BUMP;
- if(device->info.has_volume_decoupled) {
- if(shader->volume_sampling_method == VOLUME_SAMPLING_EQUIANGULAR)
- flag |= SD_VOLUME_EQUIANGULAR;
- if(shader->volume_sampling_method == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
- flag |= SD_VOLUME_MIS;
- }
- if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC)
- flag |= SD_VOLUME_CUBIC;
- if(shader->has_bump)
- flag |= SD_HAS_BUMP;
- if(shader->displacement_method != DISPLACE_BUMP)
- flag |= SD_HAS_DISPLACEMENT;
-
- /* constant emission check */
- float3 constant_emission = make_float3(0.0f, 0.0f, 0.0f);
- if(shader->is_constant_emission(&constant_emission))
- flag |= SD_HAS_CONSTANT_EMISSION;
-
- uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
-
- /* regular shader */
- kshader->flags = flag;
- kshader->pass_id = shader->pass_id;
- kshader->constant_emission[0] = constant_emission.x;
- kshader->constant_emission[1] = constant_emission.y;
- kshader->constant_emission[2] = constant_emission.z;
- kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id);
- kshader++;
-
- has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
- }
-
- dscene->shaders.copy_to_device();
-
- /* lookup tables */
- KernelTables *ktables = &dscene->data.tables;
-
- /* beckmann lookup table */
- if(beckmann_table_offset == TABLE_OFFSET_INVALID) {
- if(!beckmann_table_ready) {
- thread_scoped_lock lock(lookup_table_mutex);
- if(!beckmann_table_ready) {
- beckmann_table_build(beckmann_table);
- beckmann_table_ready = true;
- }
- }
- beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
- }
- ktables->beckmann_offset = (int)beckmann_table_offset;
-
- /* integrator */
- KernelIntegrator *kintegrator = &dscene->data.integrator;
- kintegrator->use_volumes = has_volumes;
- /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
- kintegrator->transparent_shadows = has_transparent_shadow;
-
- /* film */
- KernelFilm *kfilm = &dscene->data.film;
- /* color space, needs to be here because e.g. displacement shaders could depend on it */
- kfilm->xyz_to_r = float3_to_float4(xyz_to_r);
- kfilm->xyz_to_g = float3_to_float4(xyz_to_g);
- kfilm->xyz_to_b = float3_to_float4(xyz_to_b);
- kfilm->rgb_to_y = float3_to_float4(rgb_to_y);
+ dscene->shaders.free();
+
+ if (scene->shaders.size() == 0)
+ return;
+
+ KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
+ bool has_volumes = false;
+ bool has_transparent_shadow = false;
+
+ foreach (Shader *shader, scene->shaders) {
+ uint flag = 0;
+
+ if (shader->use_mis)
+ flag |= SD_USE_MIS;
+ if (shader->has_surface_transparent && shader->use_transparent_shadow)
+ flag |= SD_HAS_TRANSPARENT_SHADOW;
+ if (shader->has_volume) {
+ flag |= SD_HAS_VOLUME;
+ has_volumes = true;
+
+ /* todo: this could check more fine grained, to skip useless volumes
+ * enclosed inside an opaque bsdf.
+ */
+ flag |= SD_HAS_TRANSPARENT_SHADOW;
+ }
+ /* in this case we can assume transparent surface */
+ if (shader->has_volume_connected && !shader->has_surface)
+ flag |= SD_HAS_ONLY_VOLUME;
+ if (shader->heterogeneous_volume && shader->has_volume_spatial_varying)
+ flag |= SD_HETEROGENEOUS_VOLUME;
+ if (shader->has_attribute_dependency)
+ flag |= SD_NEED_ATTRIBUTES;
+ if (shader->has_bssrdf_bump)
+ flag |= SD_HAS_BSSRDF_BUMP;
+ if (device->info.has_volume_decoupled) {
+ if (shader->volume_sampling_method == VOLUME_SAMPLING_EQUIANGULAR)
+ flag |= SD_VOLUME_EQUIANGULAR;
+ if (shader->volume_sampling_method == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
+ flag |= SD_VOLUME_MIS;
+ }
+ if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC)
+ flag |= SD_VOLUME_CUBIC;
+ if (shader->has_bump)
+ flag |= SD_HAS_BUMP;
+ if (shader->displacement_method != DISPLACE_BUMP)
+ flag |= SD_HAS_DISPLACEMENT;
+
+ /* constant emission check */
+ float3 constant_emission = make_float3(0.0f, 0.0f, 0.0f);
+ if (shader->is_constant_emission(&constant_emission))
+ flag |= SD_HAS_CONSTANT_EMISSION;
+
+ uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
+
+ /* regular shader */
+ kshader->flags = flag;
+ kshader->pass_id = shader->pass_id;
+ kshader->constant_emission[0] = constant_emission.x;
+ kshader->constant_emission[1] = constant_emission.y;
+ kshader->constant_emission[2] = constant_emission.z;
+ kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id);
+ kshader++;
+
+ has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
+ }
+
+ dscene->shaders.copy_to_device();
+
+ /* lookup tables */
+ KernelTables *ktables = &dscene->data.tables;
+
+ /* beckmann lookup table */
+ if (beckmann_table_offset == TABLE_OFFSET_INVALID) {
+ if (!beckmann_table_ready) {
+ thread_scoped_lock lock(lookup_table_mutex);
+ if (!beckmann_table_ready) {
+ beckmann_table_build(beckmann_table);
+ beckmann_table_ready = true;
+ }
+ }
+ beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
+ }
+ ktables->beckmann_offset = (int)beckmann_table_offset;
+
+ /* integrator */
+ KernelIntegrator *kintegrator = &dscene->data.integrator;
+ kintegrator->use_volumes = has_volumes;
+ /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
+ kintegrator->transparent_shadows = has_transparent_shadow;
+
+ /* film */
+ KernelFilm *kfilm = &dscene->data.film;
+ /* color space, needs to be here because e.g. displacement shaders could depend on it */
+ kfilm->xyz_to_r = float3_to_float4(xyz_to_r);
+ kfilm->xyz_to_g = float3_to_float4(xyz_to_g);
+ kfilm->xyz_to_b = float3_to_float4(xyz_to_b);
+ kfilm->rgb_to_y = float3_to_float4(rgb_to_y);
}
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
{
- scene->lookup_tables->remove_table(&beckmann_table_offset);
+ scene->lookup_tables->remove_table(&beckmann_table_offset);
- dscene->shaders.free();
+ dscene->shaders.free();
}
void ShaderManager::add_default(Scene *scene)
{
- /* default surface */
- {
- ShaderGraph *graph = new ShaderGraph();
-
- DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
- diffuse->color = make_float3(0.8f, 0.8f, 0.8f);
- graph->add(diffuse);
-
- graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
-
- Shader *shader = new Shader();
- shader->name = "default_surface";
- shader->graph = graph;
- scene->shaders.push_back(shader);
- scene->default_surface = shader;
- }
-
- /* default light */
- {
- ShaderGraph *graph = new ShaderGraph();
-
- EmissionNode *emission = new EmissionNode();
- emission->color = make_float3(0.8f, 0.8f, 0.8f);
- emission->strength = 0.0f;
- graph->add(emission);
-
- graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
-
- Shader *shader = new Shader();
- shader->name = "default_light";
- shader->graph = graph;
- scene->shaders.push_back(shader);
- scene->default_light = shader;
- }
-
- /* default background */
- {
- ShaderGraph *graph = new ShaderGraph();
-
- Shader *shader = new Shader();
- shader->name = "default_background";
- shader->graph = graph;
- scene->shaders.push_back(shader);
- scene->default_background = shader;
- }
-
- /* default empty */
- {
- ShaderGraph *graph = new ShaderGraph();
-
- Shader *shader = new Shader();
- shader->name = "default_empty";
- shader->graph = graph;
- scene->shaders.push_back(shader);
- scene->default_empty = shader;
- }
+ /* default surface */
+ {
+ ShaderGraph *graph = new ShaderGraph();
+
+ DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
+ diffuse->color = make_float3(0.8f, 0.8f, 0.8f);
+ graph->add(diffuse);
+
+ graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
+
+ Shader *shader = new Shader();
+ shader->name = "default_surface";
+ shader->graph = graph;
+ scene->shaders.push_back(shader);
+ scene->default_surface = shader;
+ }
+
+ /* default light */
+ {
+ ShaderGraph *graph = new ShaderGraph();
+
+ EmissionNode *emission = new EmissionNode();
+ emission->color = make_float3(0.8f, 0.8f, 0.8f);
+ emission->strength = 0.0f;
+ graph->add(emission);
+
+ graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
+
+ Shader *shader = new Shader();
+ shader->name = "default_light";
+ shader->graph = graph;
+ scene->shaders.push_back(shader);
+ scene->default_light = shader;
+ }
+
+ /* default background */
+ {
+ ShaderGraph *graph = new ShaderGraph();
+
+ Shader *shader = new Shader();
+ shader->name = "default_background";
+ shader->graph = graph;
+ scene->shaders.push_back(shader);
+ scene->default_background = shader;
+ }
+
+ /* default empty */
+ {
+ ShaderGraph *graph = new ShaderGraph();
+
+ Shader *shader = new Shader();
+ shader->name = "default_empty";
+ shader->graph = graph;
+ scene->shaders.push_back(shader);
+ scene->default_empty = shader;
+ }
}
void ShaderManager::get_requested_graph_features(ShaderGraph *graph,
DeviceRequestedFeatures *requested_features)
{
- foreach(ShaderNode *node, graph->nodes) {
- requested_features->max_nodes_group = max(requested_features->max_nodes_group,
- node->get_group());
- requested_features->nodes_features |= node->get_feature();
- if(node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
- BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode*>(node);
- if(CLOSURE_IS_VOLUME(bsdf_node->closure)) {
- requested_features->nodes_features |= NODE_FEATURE_VOLUME;
- }
- else if(CLOSURE_IS_PRINCIPLED(bsdf_node->closure)) {
- requested_features->use_principled = true;
- }
- }
- if(node->has_surface_bssrdf()) {
- requested_features->use_subsurface = true;
- }
- if(node->has_surface_transparent()) {
- requested_features->use_transparent = true;
- }
- if(node->has_raytrace()) {
- requested_features->use_shader_raytrace = true;
- }
- }
+ foreach (ShaderNode *node, graph->nodes) {
+ requested_features->max_nodes_group = max(requested_features->max_nodes_group,
+ node->get_group());
+ requested_features->nodes_features |= node->get_feature();
+ if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
+ BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node);
+ if (CLOSURE_IS_VOLUME(bsdf_node->closure)) {
+ requested_features->nodes_features |= NODE_FEATURE_VOLUME;
+ }
+ else if (CLOSURE_IS_PRINCIPLED(bsdf_node->closure)) {
+ requested_features->use_principled = true;
+ }
+ }
+ if (node->has_surface_bssrdf()) {
+ requested_features->use_subsurface = true;
+ }
+ if (node->has_surface_transparent()) {
+ requested_features->use_transparent = true;
+ }
+ if (node->has_raytrace()) {
+ requested_features->use_shader_raytrace = true;
+ }
+ }
}
void ShaderManager::get_requested_features(Scene *scene,
DeviceRequestedFeatures *requested_features)
{
- requested_features->max_nodes_group = NODE_GROUP_LEVEL_0;
- requested_features->nodes_features = 0;
- for(int i = 0; i < scene->shaders.size(); i++) {
- Shader *shader = scene->shaders[i];
- /* Gather requested features from all the nodes from the graph nodes. */
- get_requested_graph_features(shader->graph, requested_features);
- ShaderNode *output_node = shader->graph->output();
- if(output_node->input("Displacement")->link != NULL) {
- requested_features->nodes_features |= NODE_FEATURE_BUMP;
- if(shader->displacement_method == DISPLACE_BOTH) {
- requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE;
- }
- }
- /* On top of volume nodes, also check if we need volume sampling because
- * e.g. an Emission node would slip through the NODE_FEATURE_VOLUME check */
- if(shader->has_volume)
- requested_features->use_volume |= true;
- }
+ requested_features->max_nodes_group = NODE_GROUP_LEVEL_0;
+ requested_features->nodes_features = 0;
+ for (int i = 0; i < scene->shaders.size(); i++) {
+ Shader *shader = scene->shaders[i];
+ /* Gather requested features from all the nodes from the graph nodes. */
+ get_requested_graph_features(shader->graph, requested_features);
+ ShaderNode *output_node = shader->graph->output();
+ if (output_node->input("Displacement")->link != NULL) {
+ requested_features->nodes_features |= NODE_FEATURE_BUMP;
+ if (shader->displacement_method == DISPLACE_BOTH) {
+ requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE;
+ }
+ }
+ /* On top of volume nodes, also check if we need volume sampling because
+ * e.g. an Emission node would slip through the NODE_FEATURE_VOLUME check */
+ if (shader->has_volume)
+ requested_features->use_volume |= true;
+ }
}
void ShaderManager::free_memory()
{
- beckmann_table.free_memory();
+ beckmann_table.free_memory();
#ifdef WITH_OSL
- OSLShaderManager::free_memory();
+ OSLShaderManager::free_memory();
#endif
}
float ShaderManager::linear_rgb_to_gray(float3 c)
{
- return dot(c, rgb_to_y);
+ return dot(c, rgb_to_y);
}
string ShaderManager::get_cryptomatte_materials(Scene *scene)
{
- string manifest = "{";
- unordered_set<ustring, ustringHash> materials;
- foreach(Shader *shader, scene->shaders) {
- if(materials.count(shader->name)) {
- continue;
- }
- materials.insert(shader->name);
- uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
- manifest += string_printf("\"%s\":\"%08x\",", shader->name.c_str(), cryptomatte_id);
- }
- manifest[manifest.size()-1] = '}';
- return manifest;
+ string manifest = "{";
+ unordered_set<ustring, ustringHash> materials;
+ foreach (Shader *shader, scene->shaders) {
+ if (materials.count(shader->name)) {
+ continue;
+ }
+ materials.insert(shader->name);
+ uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
+ manifest += string_printf("\"%s\":\"%08x\",", shader->name.c_str(), cryptomatte_id);
+ }
+ manifest[manifest.size() - 1] = '}';
+ return manifest;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 05772b9a9cd..600b0cc59d4 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -45,33 +45,30 @@ class Scene;
class ShaderGraph;
struct float3;
-enum ShadingSystem {
- SHADINGSYSTEM_OSL,
- SHADINGSYSTEM_SVM
-};
+enum ShadingSystem { SHADINGSYSTEM_OSL, SHADINGSYSTEM_SVM };
/* Keep those in sync with the python-defined enum. */
enum VolumeSampling {
- VOLUME_SAMPLING_DISTANCE = 0,
- VOLUME_SAMPLING_EQUIANGULAR = 1,
- VOLUME_SAMPLING_MULTIPLE_IMPORTANCE = 2,
+ VOLUME_SAMPLING_DISTANCE = 0,
+ VOLUME_SAMPLING_EQUIANGULAR = 1,
+ VOLUME_SAMPLING_MULTIPLE_IMPORTANCE = 2,
- VOLUME_NUM_SAMPLING,
+ VOLUME_NUM_SAMPLING,
};
enum VolumeInterpolation {
- VOLUME_INTERPOLATION_LINEAR = 0,
- VOLUME_INTERPOLATION_CUBIC = 1,
+ VOLUME_INTERPOLATION_LINEAR = 0,
+ VOLUME_INTERPOLATION_CUBIC = 1,
- VOLUME_NUM_INTERPOLATION,
+ VOLUME_NUM_INTERPOLATION,
};
enum DisplacementMethod {
- DISPLACE_BUMP = 0,
- DISPLACE_TRUE = 1,
- DISPLACE_BOTH = 2,
+ DISPLACE_BUMP = 0,
+ DISPLACE_TRUE = 1,
+ DISPLACE_BOTH = 2,
- DISPLACE_NUM_METHODS,
+ DISPLACE_NUM_METHODS,
};
/* Shader describing the appearance of a Mesh, Light or Background.
@@ -81,78 +78,78 @@ enum DisplacementMethod {
* separately. */
class Shader : public Node {
-public:
- NODE_DECLARE
-
- int pass_id;
-
- /* shader graph */
- ShaderGraph *graph;
-
- /* sampling */
- bool use_mis;
- bool use_transparent_shadow;
- bool heterogeneous_volume;
- VolumeSampling volume_sampling_method;
- int volume_interpolation_method;
-
- /* synchronization */
- bool need_update;
- bool need_update_mesh;
- bool need_sync_object;
-
- /* If the shader has only volume components, the surface is assumed to
- * be transparent.
- * However, graph optimization might remove the volume subgraph, but
- * since the user connected something to the volume output the surface
- * should still be transparent.
- * Therefore, has_volume_connected stores whether some volume subtree
- * was connected before optimization. */
- bool has_volume_connected;
-
- /* information about shader after compiling */
- bool has_surface;
- bool has_surface_emission;
- bool has_surface_transparent;
- bool has_volume;
- bool has_displacement;
- bool has_surface_bssrdf;
- bool has_bump;
- bool has_bssrdf_bump;
- bool has_surface_spatial_varying;
- bool has_volume_spatial_varying;
- bool has_object_dependency;
- bool has_attribute_dependency;
- bool has_integrator_dependency;
-
- /* displacement */
- DisplacementMethod displacement_method;
-
- /* requested mesh attributes */
- AttributeRequestSet attributes;
-
- /* determined before compiling */
- uint id;
- bool used;
+ public:
+ NODE_DECLARE
+
+ int pass_id;
+
+ /* shader graph */
+ ShaderGraph *graph;
+
+ /* sampling */
+ bool use_mis;
+ bool use_transparent_shadow;
+ bool heterogeneous_volume;
+ VolumeSampling volume_sampling_method;
+ int volume_interpolation_method;
+
+ /* synchronization */
+ bool need_update;
+ bool need_update_mesh;
+ bool need_sync_object;
+
+ /* If the shader has only volume components, the surface is assumed to
+ * be transparent.
+ * However, graph optimization might remove the volume subgraph, but
+ * since the user connected something to the volume output the surface
+ * should still be transparent.
+ * Therefore, has_volume_connected stores whether some volume subtree
+ * was connected before optimization. */
+ bool has_volume_connected;
+
+ /* information about shader after compiling */
+ bool has_surface;
+ bool has_surface_emission;
+ bool has_surface_transparent;
+ bool has_volume;
+ bool has_displacement;
+ bool has_surface_bssrdf;
+ bool has_bump;
+ bool has_bssrdf_bump;
+ bool has_surface_spatial_varying;
+ bool has_volume_spatial_varying;
+ bool has_object_dependency;
+ bool has_attribute_dependency;
+ bool has_integrator_dependency;
+
+ /* displacement */
+ DisplacementMethod displacement_method;
+
+ /* requested mesh attributes */
+ AttributeRequestSet attributes;
+
+ /* determined before compiling */
+ uint id;
+ bool used;
#ifdef WITH_OSL
- /* osl shading state references */
- OSL::ShaderGroupRef osl_surface_ref;
- OSL::ShaderGroupRef osl_surface_bump_ref;
- OSL::ShaderGroupRef osl_volume_ref;
- OSL::ShaderGroupRef osl_displacement_ref;
+ /* osl shading state references */
+ OSL::ShaderGroupRef osl_surface_ref;
+ OSL::ShaderGroupRef osl_surface_bump_ref;
+ OSL::ShaderGroupRef osl_volume_ref;
+ OSL::ShaderGroupRef osl_displacement_ref;
#endif
- Shader();
- ~Shader();
+ Shader();
+ ~Shader();
- /* Checks whether the shader consists of just a emission node with fixed inputs that's connected directly to the output.
- * If yes, it sets the content of emission to the constant value (color * strength), which is then used for speeding up light evaluation. */
- bool is_constant_emission(float3* emission);
+ /* Checks whether the shader consists of just a emission node with fixed inputs that's connected directly to the output.
+ * If yes, it sets the content of emission to the constant value (color * strength), which is then used for speeding up light evaluation. */
+ bool is_constant_emission(float3 *emission);
- void set_graph(ShaderGraph *graph);
- void tag_update(Scene *scene);
- void tag_used(Scene *scene);
+ void set_graph(ShaderGraph *graph);
+ void tag_update(Scene *scene);
+ void tag_used(Scene *scene);
};
/* Shader Manager virtual base class
@@ -161,68 +158,73 @@ public:
* shader compiling and device updating. */
class ShaderManager {
-public:
- bool need_update;
+ public:
+ bool need_update;
- static ShaderManager *create(Scene *scene, int shadingsystem);
- virtual ~ShaderManager();
+ static ShaderManager *create(Scene *scene, int shadingsystem);
+ virtual ~ShaderManager();
- virtual void reset(Scene *scene) = 0;
+ virtual void reset(Scene *scene) = 0;
- virtual bool use_osl() { return false; }
+ virtual bool use_osl()
+ {
+ return false;
+ }
- /* device update */
- virtual void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) = 0;
- virtual void device_free(Device *device, DeviceScene *dscene, Scene *scene) = 0;
+ /* device update */
+ virtual void device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress) = 0;
+ virtual void device_free(Device *device, DeviceScene *dscene, Scene *scene) = 0;
- void device_update_shaders_used(Scene *scene);
- void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_free_common(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_update_shaders_used(Scene *scene);
+ void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_free_common(Device *device, DeviceScene *dscene, Scene *scene);
- /* get globally unique id for a type of attribute */
- uint get_attribute_id(ustring name);
- uint get_attribute_id(AttributeStandard std);
+ /* get globally unique id for a type of attribute */
+ uint get_attribute_id(ustring name);
+ uint get_attribute_id(AttributeStandard std);
- /* get shader id for mesh faces */
- int get_shader_id(Shader *shader, bool smooth = false);
+ /* get shader id for mesh faces */
+ int get_shader_id(Shader *shader, bool smooth = false);
- /* add default shaders to scene, to use as default for things that don't
- * have any shader assigned explicitly */
- static void add_default(Scene *scene);
+ /* add default shaders to scene, to use as default for things that don't
+ * have any shader assigned explicitly */
+ static void add_default(Scene *scene);
- /* Selective nodes compilation. */
- void get_requested_features(Scene *scene,
- DeviceRequestedFeatures *requested_features);
+ /* Selective nodes compilation. */
+ void get_requested_features(Scene *scene, DeviceRequestedFeatures *requested_features);
- static void free_memory();
+ static void free_memory();
- float linear_rgb_to_gray(float3 c);
+ float linear_rgb_to_gray(float3 c);
- string get_cryptomatte_materials(Scene *scene);
+ string get_cryptomatte_materials(Scene *scene);
-protected:
- ShaderManager();
+ protected:
+ ShaderManager();
- typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
- AttributeIDMap unique_attribute_id;
+ typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
+ AttributeIDMap unique_attribute_id;
- static thread_mutex lookup_table_mutex;
- static vector<float> beckmann_table;
- static bool beckmann_table_ready;
+ static thread_mutex lookup_table_mutex;
+ static vector<float> beckmann_table;
+ static bool beckmann_table_ready;
- size_t beckmann_table_offset;
+ size_t beckmann_table_offset;
- void get_requested_graph_features(ShaderGraph *graph,
- DeviceRequestedFeatures *requested_features);
+ void get_requested_graph_features(ShaderGraph *graph,
+ DeviceRequestedFeatures *requested_features);
- thread_spin_lock attribute_lock_;
+ thread_spin_lock attribute_lock_;
- float3 xyz_to_r;
- float3 xyz_to_g;
- float3 xyz_to_b;
- float3 rgb_to_y;
+ float3 xyz_to_r;
+ float3 xyz_to_g;
+ float3 xyz_to_b;
+ float3 rgb_to_y;
};
CCL_NAMESPACE_END
-#endif /* __SHADER_H__ */
+#endif /* __SHADER_H__ */
diff --git a/intern/cycles/render/sobol.h b/intern/cycles/render/sobol.h
index ce7a28587f2..d38857d2b35 100644
--- a/intern/cycles/render/sobol.h
+++ b/intern/cycles/render/sobol.h
@@ -28,4 +28,4 @@ void sobol_generate_direction_vectors(uint vectors[][SOBOL_BITS], int dimensions
CCL_NAMESPACE_END
-#endif /* __SOBOL_H__ */
+#endif /* __SOBOL_H__ */
diff --git a/intern/cycles/render/stats.cpp b/intern/cycles/render/stats.cpp
index 4245745944d..0937b95a891 100644
--- a/intern/cycles/render/stats.cpp
+++ b/intern/cycles/render/stats.cpp
@@ -28,284 +28,293 @@ static int kIndentNumSpaces = 2;
namespace {
-bool namedSizeEntryComparator(const NamedSizeEntry& a, const NamedSizeEntry& b)
+bool namedSizeEntryComparator(const NamedSizeEntry &a, const NamedSizeEntry &b)
{
- /* We sort in descending order. */
- return a.size > b.size;
+ /* We sort in descending order. */
+ return a.size > b.size;
}
-bool namedTimeSampleEntryComparator(const NamedNestedSampleStats& a, const NamedNestedSampleStats& b)
+bool namedTimeSampleEntryComparator(const NamedNestedSampleStats &a,
+ const NamedNestedSampleStats &b)
{
- return a.sum_samples > b.sum_samples;
+ return a.sum_samples > b.sum_samples;
}
-bool namedSampleCountPairComparator(const NamedSampleCountPair& a, const NamedSampleCountPair& b)
+bool namedSampleCountPairComparator(const NamedSampleCountPair &a, const NamedSampleCountPair &b)
{
- return a.samples > b.samples;
+ return a.samples > b.samples;
}
} // namespace
-NamedSizeEntry::NamedSizeEntry()
- : name(""),
- size(0) {
+NamedSizeEntry::NamedSizeEntry() : name(""), size(0)
+{
}
-NamedSizeEntry::NamedSizeEntry(const string& name, size_t size)
- : name(name),
- size(size) {
+NamedSizeEntry::NamedSizeEntry(const string &name, size_t size) : name(name), size(size)
+{
}
/* Named size statistics. */
-NamedSizeStats::NamedSizeStats()
- : total_size(0) {
+NamedSizeStats::NamedSizeStats() : total_size(0)
+{
}
-void NamedSizeStats::add_entry(const NamedSizeEntry& entry) {
- total_size += entry.size;
- entries.push_back(entry);
+void NamedSizeStats::add_entry(const NamedSizeEntry &entry)
+{
+ total_size += entry.size;
+ entries.push_back(entry);
}
string NamedSizeStats::full_report(int indent_level)
{
- const string indent(indent_level * kIndentNumSpaces, ' ');
- const string double_indent = indent + indent;
- string result = "";
- result += string_printf("%sTotal memory: %s (%s)\n",
- indent.c_str(),
- string_human_readable_size(total_size).c_str(),
- string_human_readable_number(total_size).c_str());
- sort(entries.begin(), entries.end(), namedSizeEntryComparator);
- foreach(const NamedSizeEntry& entry, entries) {
- result += string_printf(
- "%s%-32s %s (%s)\n",
- double_indent.c_str(),
- entry.name.c_str(),
- string_human_readable_size(entry.size).c_str(),
- string_human_readable_number(entry.size).c_str());
- }
- return result;
+ const string indent(indent_level * kIndentNumSpaces, ' ');
+ const string double_indent = indent + indent;
+ string result = "";
+ result += string_printf("%sTotal memory: %s (%s)\n",
+ indent.c_str(),
+ string_human_readable_size(total_size).c_str(),
+ string_human_readable_number(total_size).c_str());
+ sort(entries.begin(), entries.end(), namedSizeEntryComparator);
+ foreach (const NamedSizeEntry &entry, entries) {
+ result += string_printf("%s%-32s %s (%s)\n",
+ double_indent.c_str(),
+ entry.name.c_str(),
+ string_human_readable_size(entry.size).c_str(),
+ string_human_readable_number(entry.size).c_str());
+ }
+ return result;
}
/* Named time sample statistics. */
-NamedNestedSampleStats::NamedNestedSampleStats()
- : name(""), self_samples(0), sum_samples(0)
-{}
+NamedNestedSampleStats::NamedNestedSampleStats() : name(""), self_samples(0), sum_samples(0)
+{
+}
-NamedNestedSampleStats::NamedNestedSampleStats(const string& name, uint64_t samples)
- : name(name), self_samples(samples), sum_samples(samples)
-{}
+NamedNestedSampleStats::NamedNestedSampleStats(const string &name, uint64_t samples)
+ : name(name), self_samples(samples), sum_samples(samples)
+{
+}
-NamedNestedSampleStats& NamedNestedSampleStats::add_entry(const string& name_, uint64_t samples_)
+NamedNestedSampleStats &NamedNestedSampleStats::add_entry(const string &name_, uint64_t samples_)
{
- entries.push_back(NamedNestedSampleStats(name_, samples_));
- return entries[entries.size()-1];
+ entries.push_back(NamedNestedSampleStats(name_, samples_));
+ return entries[entries.size() - 1];
}
void NamedNestedSampleStats::update_sum()
{
- sum_samples = self_samples;
- foreach(NamedNestedSampleStats& entry, entries) {
- entry.update_sum();
- sum_samples += entry.sum_samples;
- }
+ sum_samples = self_samples;
+ foreach (NamedNestedSampleStats &entry, entries) {
+ entry.update_sum();
+ sum_samples += entry.sum_samples;
+ }
}
string NamedNestedSampleStats::full_report(int indent_level, uint64_t total_samples)
{
- update_sum();
-
- if(total_samples == 0) {
- total_samples = sum_samples;
- }
-
- const string indent(indent_level * kIndentNumSpaces, ' ');
-
- const double sum_percent = 100*((double) sum_samples) / total_samples;
- const double sum_seconds = sum_samples * 0.001;
- const double self_percent = 100*((double) self_samples) / total_samples;
- const double self_seconds = self_samples * 0.001;
- string info = string_printf("%-32s: Total %3.2f%% (%.2fs), Self %3.2f%% (%.2fs)\n",
- name.c_str(),
- sum_percent,
- sum_seconds,
- self_percent,
- self_seconds);
- string result = indent + info;
-
- sort(entries.begin(), entries.end(), namedTimeSampleEntryComparator);
- foreach(NamedNestedSampleStats& entry, entries) {
- result += entry.full_report(indent_level + 1, total_samples);
- }
- return result;
+ update_sum();
+
+ if (total_samples == 0) {
+ total_samples = sum_samples;
+ }
+
+ const string indent(indent_level * kIndentNumSpaces, ' ');
+
+ const double sum_percent = 100 * ((double)sum_samples) / total_samples;
+ const double sum_seconds = sum_samples * 0.001;
+ const double self_percent = 100 * ((double)self_samples) / total_samples;
+ const double self_seconds = self_samples * 0.001;
+ string info = string_printf("%-32s: Total %3.2f%% (%.2fs), Self %3.2f%% (%.2fs)\n",
+ name.c_str(),
+ sum_percent,
+ sum_seconds,
+ self_percent,
+ self_seconds);
+ string result = indent + info;
+
+ sort(entries.begin(), entries.end(), namedTimeSampleEntryComparator);
+ foreach (NamedNestedSampleStats &entry, entries) {
+ result += entry.full_report(indent_level + 1, total_samples);
+ }
+ return result;
}
/* Named sample count pairs. */
-NamedSampleCountPair::NamedSampleCountPair(const ustring& name, uint64_t samples, uint64_t hits)
- : name(name), samples(samples), hits(hits)
-{}
+NamedSampleCountPair::NamedSampleCountPair(const ustring &name, uint64_t samples, uint64_t hits)
+ : name(name), samples(samples), hits(hits)
+{
+}
NamedSampleCountStats::NamedSampleCountStats()
-{}
+{
+}
-void NamedSampleCountStats::add(const ustring& name, uint64_t samples, uint64_t hits)
+void NamedSampleCountStats::add(const ustring &name, uint64_t samples, uint64_t hits)
{
- entry_map::iterator entry = entries.find(name);
- if(entry != entries.end()) {
- entry->second.samples += samples;
- entry->second.hits += hits;
- return;
- }
- entries.emplace(name, NamedSampleCountPair(name, samples, hits));
+ entry_map::iterator entry = entries.find(name);
+ if (entry != entries.end()) {
+ entry->second.samples += samples;
+ entry->second.hits += hits;
+ return;
+ }
+ entries.emplace(name, NamedSampleCountPair(name, samples, hits));
}
string NamedSampleCountStats::full_report(int indent_level)
{
- const string indent(indent_level * kIndentNumSpaces, ' ');
+ const string indent(indent_level * kIndentNumSpaces, ' ');
- vector<NamedSampleCountPair> sorted_entries;
- sorted_entries.reserve(entries.size());
+ vector<NamedSampleCountPair> sorted_entries;
+ sorted_entries.reserve(entries.size());
- uint64_t total_hits = 0, total_samples = 0;
- foreach(entry_map::const_reference entry, entries) {
- const NamedSampleCountPair &pair = entry.second;
+ uint64_t total_hits = 0, total_samples = 0;
+ foreach (entry_map::const_reference entry, entries) {
+ const NamedSampleCountPair &pair = entry.second;
- total_hits += pair.hits;
- total_samples += pair.samples;
+ total_hits += pair.hits;
+ total_samples += pair.samples;
- sorted_entries.push_back(pair);
- }
- const double avg_samples_per_hit = ((double) total_samples) / total_hits;
+ sorted_entries.push_back(pair);
+ }
+ const double avg_samples_per_hit = ((double)total_samples) / total_hits;
- sort(sorted_entries.begin(), sorted_entries.end(), namedSampleCountPairComparator);
+ sort(sorted_entries.begin(), sorted_entries.end(), namedSampleCountPairComparator);
- string result = "";
- foreach(const NamedSampleCountPair& entry, sorted_entries) {
- const double seconds = entry.samples * 0.001;
- const double relative = ((double) entry.samples) / (entry.hits * avg_samples_per_hit);
+ string result = "";
+ foreach (const NamedSampleCountPair &entry, sorted_entries) {
+ const double seconds = entry.samples * 0.001;
+ const double relative = ((double)entry.samples) / (entry.hits * avg_samples_per_hit);
- result += indent + string_printf("%-32s: %.2fs (Relative cost: %.2f)\n",
- entry.name.c_str(),
- seconds,
- relative);
- }
- return result;
+ result += indent +
+ string_printf(
+ "%-32s: %.2fs (Relative cost: %.2f)\n", entry.name.c_str(), seconds, relative);
+ }
+ return result;
}
/* Mesh statistics. */
-MeshStats::MeshStats() {
+MeshStats::MeshStats()
+{
}
string MeshStats::full_report(int indent_level)
{
- const string indent(indent_level * kIndentNumSpaces, ' ');
- string result = "";
- result += indent + "Geometry:\n" + geometry.full_report(indent_level + 1);
- return result;
+ const string indent(indent_level * kIndentNumSpaces, ' ');
+ string result = "";
+ result += indent + "Geometry:\n" + geometry.full_report(indent_level + 1);
+ return result;
}
/* Image statistics. */
-ImageStats::ImageStats() {
+ImageStats::ImageStats()
+{
}
string ImageStats::full_report(int indent_level)
{
- const string indent(indent_level * kIndentNumSpaces, ' ');
- string result = "";
- result += indent + "Textures:\n" + textures.full_report(indent_level + 1);
- return result;
+ const string indent(indent_level * kIndentNumSpaces, ' ');
+ string result = "";
+ result += indent + "Textures:\n" + textures.full_report(indent_level + 1);
+ return result;
}
/* Overall statistics. */
-RenderStats::RenderStats() {
- has_profiling = false;
+RenderStats::RenderStats()
+{
+ has_profiling = false;
}
-void RenderStats::collect_profiling(Scene *scene, Profiler& prof)
+void RenderStats::collect_profiling(Scene *scene, Profiler &prof)
{
- has_profiling = true;
-
- kernel = NamedNestedSampleStats("Total render time", prof.get_event(PROFILING_UNKNOWN));
-
- kernel.add_entry("Ray setup", prof.get_event(PROFILING_RAY_SETUP));
- kernel.add_entry("Result writing", prof.get_event(PROFILING_WRITE_RESULT));
-
- NamedNestedSampleStats &integrator = kernel.add_entry("Path integration", prof.get_event(PROFILING_PATH_INTEGRATE));
- integrator.add_entry("Scene intersection", prof.get_event(PROFILING_SCENE_INTERSECT));
- integrator.add_entry("Indirect emission", prof.get_event(PROFILING_INDIRECT_EMISSION));
- integrator.add_entry("Volumes", prof.get_event(PROFILING_VOLUME));
-
- NamedNestedSampleStats &shading = integrator.add_entry("Shading", 0);
- shading.add_entry("Shader Setup", prof.get_event(PROFILING_SHADER_SETUP));
- shading.add_entry("Shader Eval", prof.get_event(PROFILING_SHADER_EVAL));
- shading.add_entry("Shader Apply", prof.get_event(PROFILING_SHADER_APPLY));
- shading.add_entry("Ambient Occlusion", prof.get_event(PROFILING_AO));
- shading.add_entry("Subsurface", prof.get_event(PROFILING_SUBSURFACE));
-
- integrator.add_entry("Connect Light", prof.get_event(PROFILING_CONNECT_LIGHT));
- integrator.add_entry("Surface Bounce", prof.get_event(PROFILING_SURFACE_BOUNCE));
-
- NamedNestedSampleStats &intersection = kernel.add_entry("Intersection", 0);
- intersection.add_entry("Full Intersection", prof.get_event(PROFILING_INTERSECT));
- intersection.add_entry("Local Intersection", prof.get_event(PROFILING_INTERSECT_LOCAL));
- intersection.add_entry("Shadow All Intersection", prof.get_event(PROFILING_INTERSECT_SHADOW_ALL));
- intersection.add_entry("Volume Intersection", prof.get_event(PROFILING_INTERSECT_VOLUME));
- intersection.add_entry("Volume All Intersection", prof.get_event(PROFILING_INTERSECT_VOLUME_ALL));
-
- NamedNestedSampleStats &closure = kernel.add_entry("Closures", 0);
- closure.add_entry("Surface Closure Evaluation", prof.get_event(PROFILING_CLOSURE_EVAL));
- closure.add_entry("Surface Closure Sampling", prof.get_event(PROFILING_CLOSURE_SAMPLE));
- closure.add_entry("Volume Closure Evaluation", prof.get_event(PROFILING_CLOSURE_VOLUME_EVAL));
- closure.add_entry("Volume Closure Sampling", prof.get_event(PROFILING_CLOSURE_VOLUME_SAMPLE));
-
- NamedNestedSampleStats &denoising = kernel.add_entry("Denoising", prof.get_event(PROFILING_DENOISING));
- denoising.add_entry("Construct Transform", prof.get_event(PROFILING_DENOISING_CONSTRUCT_TRANSFORM));
- denoising.add_entry("Reconstruct", prof.get_event(PROFILING_DENOISING_RECONSTRUCT));
-
- NamedNestedSampleStats &prefilter = denoising.add_entry("Prefiltering", 0);
- prefilter.add_entry("Divide Shadow", prof.get_event(PROFILING_DENOISING_DIVIDE_SHADOW));
- prefilter.add_entry("Non-Local means", prof.get_event(PROFILING_DENOISING_NON_LOCAL_MEANS));
- prefilter.add_entry("Get Feature", prof.get_event(PROFILING_DENOISING_GET_FEATURE));
- prefilter.add_entry("Detect Outliers", prof.get_event(PROFILING_DENOISING_DETECT_OUTLIERS));
- prefilter.add_entry("Combine Halves", prof.get_event(PROFILING_DENOISING_COMBINE_HALVES));
-
- shaders.entries.clear();
- foreach(Shader *shader, scene->shaders) {
- uint64_t samples, hits;
- if(prof.get_shader(shader->id, samples, hits)) {
- shaders.add(shader->name, samples, hits);
- }
- }
-
- objects.entries.clear();
- foreach(Object *object, scene->objects) {
- uint64_t samples, hits;
- if(prof.get_object(object->get_device_index(), samples, hits)) {
- objects.add(object->name, samples, hits);
- }
- }
+ has_profiling = true;
+
+ kernel = NamedNestedSampleStats("Total render time", prof.get_event(PROFILING_UNKNOWN));
+
+ kernel.add_entry("Ray setup", prof.get_event(PROFILING_RAY_SETUP));
+ kernel.add_entry("Result writing", prof.get_event(PROFILING_WRITE_RESULT));
+
+ NamedNestedSampleStats &integrator = kernel.add_entry("Path integration",
+ prof.get_event(PROFILING_PATH_INTEGRATE));
+ integrator.add_entry("Scene intersection", prof.get_event(PROFILING_SCENE_INTERSECT));
+ integrator.add_entry("Indirect emission", prof.get_event(PROFILING_INDIRECT_EMISSION));
+ integrator.add_entry("Volumes", prof.get_event(PROFILING_VOLUME));
+
+ NamedNestedSampleStats &shading = integrator.add_entry("Shading", 0);
+ shading.add_entry("Shader Setup", prof.get_event(PROFILING_SHADER_SETUP));
+ shading.add_entry("Shader Eval", prof.get_event(PROFILING_SHADER_EVAL));
+ shading.add_entry("Shader Apply", prof.get_event(PROFILING_SHADER_APPLY));
+ shading.add_entry("Ambient Occlusion", prof.get_event(PROFILING_AO));
+ shading.add_entry("Subsurface", prof.get_event(PROFILING_SUBSURFACE));
+
+ integrator.add_entry("Connect Light", prof.get_event(PROFILING_CONNECT_LIGHT));
+ integrator.add_entry("Surface Bounce", prof.get_event(PROFILING_SURFACE_BOUNCE));
+
+ NamedNestedSampleStats &intersection = kernel.add_entry("Intersection", 0);
+ intersection.add_entry("Full Intersection", prof.get_event(PROFILING_INTERSECT));
+ intersection.add_entry("Local Intersection", prof.get_event(PROFILING_INTERSECT_LOCAL));
+ intersection.add_entry("Shadow All Intersection",
+ prof.get_event(PROFILING_INTERSECT_SHADOW_ALL));
+ intersection.add_entry("Volume Intersection", prof.get_event(PROFILING_INTERSECT_VOLUME));
+ intersection.add_entry("Volume All Intersection",
+ prof.get_event(PROFILING_INTERSECT_VOLUME_ALL));
+
+ NamedNestedSampleStats &closure = kernel.add_entry("Closures", 0);
+ closure.add_entry("Surface Closure Evaluation", prof.get_event(PROFILING_CLOSURE_EVAL));
+ closure.add_entry("Surface Closure Sampling", prof.get_event(PROFILING_CLOSURE_SAMPLE));
+ closure.add_entry("Volume Closure Evaluation", prof.get_event(PROFILING_CLOSURE_VOLUME_EVAL));
+ closure.add_entry("Volume Closure Sampling", prof.get_event(PROFILING_CLOSURE_VOLUME_SAMPLE));
+
+ NamedNestedSampleStats &denoising = kernel.add_entry("Denoising",
+ prof.get_event(PROFILING_DENOISING));
+ denoising.add_entry("Construct Transform",
+ prof.get_event(PROFILING_DENOISING_CONSTRUCT_TRANSFORM));
+ denoising.add_entry("Reconstruct", prof.get_event(PROFILING_DENOISING_RECONSTRUCT));
+
+ NamedNestedSampleStats &prefilter = denoising.add_entry("Prefiltering", 0);
+ prefilter.add_entry("Divide Shadow", prof.get_event(PROFILING_DENOISING_DIVIDE_SHADOW));
+ prefilter.add_entry("Non-Local means", prof.get_event(PROFILING_DENOISING_NON_LOCAL_MEANS));
+ prefilter.add_entry("Get Feature", prof.get_event(PROFILING_DENOISING_GET_FEATURE));
+ prefilter.add_entry("Detect Outliers", prof.get_event(PROFILING_DENOISING_DETECT_OUTLIERS));
+ prefilter.add_entry("Combine Halves", prof.get_event(PROFILING_DENOISING_COMBINE_HALVES));
+
+ shaders.entries.clear();
+ foreach (Shader *shader, scene->shaders) {
+ uint64_t samples, hits;
+ if (prof.get_shader(shader->id, samples, hits)) {
+ shaders.add(shader->name, samples, hits);
+ }
+ }
+
+ objects.entries.clear();
+ foreach (Object *object, scene->objects) {
+ uint64_t samples, hits;
+ if (prof.get_object(object->get_device_index(), samples, hits)) {
+ objects.add(object->name, samples, hits);
+ }
+ }
}
string RenderStats::full_report()
{
- string result = "";
- result += "Mesh statistics:\n" + mesh.full_report(1);
- result += "Image statistics:\n" + image.full_report(1);
- if(has_profiling) {
- result += "Kernel statistics:\n" + kernel.full_report(1);
- result += "Shader statistics:\n" + shaders.full_report(1);
- result += "Object statistics:\n" + objects.full_report(1);
- }
- else {
- result += "Profiling information not available (only works with CPU rendering)";
- }
- return result;
+ string result = "";
+ result += "Mesh statistics:\n" + mesh.full_report(1);
+ result += "Image statistics:\n" + image.full_report(1);
+ if (has_profiling) {
+ result += "Kernel statistics:\n" + kernel.full_report(1);
+ result += "Shader statistics:\n" + shaders.full_report(1);
+ result += "Object statistics:\n" + objects.full_report(1);
+ }
+ else {
+ result += "Profiling information not available (only works with CPU rendering)";
+ }
+ return result;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/stats.h b/intern/cycles/render/stats.h
index 33fe1f4b185..f1bf1903483 100644
--- a/intern/cycles/render/stats.h
+++ b/intern/cycles/render/stats.h
@@ -33,12 +33,12 @@ CCL_NAMESPACE_BEGIN
* avoiding duplicating code for things like sorting.
*/
class NamedSizeEntry {
-public:
- NamedSizeEntry();
- NamedSizeEntry(const string& name, size_t size);
+ public:
+ NamedSizeEntry();
+ NamedSizeEntry(const string &name, size_t size);
- string name;
- size_t size;
+ string name;
+ size_t size;
};
/* Container of named size entries. Used, for example, to store per-mesh memory
@@ -46,115 +46,115 @@ public:
* container.
*/
class NamedSizeStats {
-public:
- NamedSizeStats();
+ public:
+ NamedSizeStats();
- /* Add entry to the statistics. */
- void add_entry(const NamedSizeEntry& entry);
+ /* Add entry to the statistics. */
+ void add_entry(const NamedSizeEntry &entry);
- /* Generate full human-readable report. */
- string full_report(int indent_level = 0);
+ /* Generate full human-readable report. */
+ string full_report(int indent_level = 0);
- /* Total size of all entries. */
- size_t total_size;
+ /* Total size of all entries. */
+ size_t total_size;
- /* NOTE: Is fine to read directly, but for adding use add_entry(), which
- * makes sure all accumulating values are properly updated.
- */
- vector<NamedSizeEntry> entries;
+ /* NOTE: Is fine to read directly, but for adding use add_entry(), which
+ * makes sure all accumulating values are properly updated.
+ */
+ vector<NamedSizeEntry> entries;
};
class NamedNestedSampleStats {
-public:
- NamedNestedSampleStats();
- NamedNestedSampleStats(const string& name, uint64_t samples);
+ public:
+ NamedNestedSampleStats();
+ NamedNestedSampleStats(const string &name, uint64_t samples);
- NamedNestedSampleStats& add_entry(const string& name, uint64_t samples);
+ NamedNestedSampleStats &add_entry(const string &name, uint64_t samples);
- /* Updates sum_samples recursively. */
- void update_sum();
+ /* Updates sum_samples recursively. */
+ void update_sum();
- string full_report(int indent_level = 0, uint64_t total_samples = 0);
+ string full_report(int indent_level = 0, uint64_t total_samples = 0);
- string name;
+ string name;
- /* self_samples contains only the samples that this specific event got,
- * while sum_samples also includes the samples of all sub-entries. */
- uint64_t self_samples, sum_samples;
+ /* self_samples contains only the samples that this specific event got,
+ * while sum_samples also includes the samples of all sub-entries. */
+ uint64_t self_samples, sum_samples;
- vector<NamedNestedSampleStats> entries;
+ vector<NamedNestedSampleStats> entries;
};
/* Named entry containing both a time-sample count for objects of a type and a
* total count of processed items.
* This allows to estimate the time spent per item. */
class NamedSampleCountPair {
-public:
- NamedSampleCountPair(const ustring& name, uint64_t samples, uint64_t hits);
+ public:
+ NamedSampleCountPair(const ustring &name, uint64_t samples, uint64_t hits);
- ustring name;
- uint64_t samples;
- uint64_t hits;
+ ustring name;
+ uint64_t samples;
+ uint64_t hits;
};
/* Contains statistics about pairs of samples and counts as described above. */
class NamedSampleCountStats {
-public:
- NamedSampleCountStats();
+ public:
+ NamedSampleCountStats();
- string full_report(int indent_level = 0);
- void add(const ustring& name, uint64_t samples, uint64_t hits);
+ string full_report(int indent_level = 0);
+ void add(const ustring &name, uint64_t samples, uint64_t hits);
- typedef unordered_map<ustring, NamedSampleCountPair, ustringHash> entry_map;
- entry_map entries;
+ typedef unordered_map<ustring, NamedSampleCountPair, ustringHash> entry_map;
+ entry_map entries;
};
/* Statistics about mesh in the render database. */
class MeshStats {
-public:
- MeshStats();
+ public:
+ MeshStats();
- /* Generate full human-readable report. */
- string full_report(int indent_level = 0);
+ /* Generate full human-readable report. */
+ string full_report(int indent_level = 0);
- /* Input geometry statistics, this is what is coming as an input to render
- * from. say, Blender. This does not include runtime or engine specific
- * memory like BVH.
- */
- NamedSizeStats geometry;
+ /* Input geometry statistics, this is what is coming as an input to render
+ * from. say, Blender. This does not include runtime or engine specific
+ * memory like BVH.
+ */
+ NamedSizeStats geometry;
};
/* Statistics about images held in memory. */
class ImageStats {
-public:
- ImageStats();
+ public:
+ ImageStats();
- /* Generate full human-readable report. */
- string full_report(int indent_level = 0);
+ /* Generate full human-readable report. */
+ string full_report(int indent_level = 0);
- NamedSizeStats textures;
+ NamedSizeStats textures;
};
/* Render process statistics. */
class RenderStats {
-public:
- RenderStats();
+ public:
+ RenderStats();
- /* Return full report as string. */
- string full_report();
+ /* Return full report as string. */
+ string full_report();
- /* Collect kernel sampling information from Stats. */
- void collect_profiling(Scene *scene, Profiler& prof);
+ /* Collect kernel sampling information from Stats. */
+ void collect_profiling(Scene *scene, Profiler &prof);
- bool has_profiling;
+ bool has_profiling;
- MeshStats mesh;
- ImageStats image;
- NamedNestedSampleStats kernel;
- NamedSampleCountStats shaders;
- NamedSampleCountStats objects;
+ MeshStats mesh;
+ ImageStats image;
+ NamedNestedSampleStats kernel;
+ NamedSampleCountStats shaders;
+ NamedSampleCountStats objects;
};
CCL_NAMESPACE_END
-#endif /* __RENDER_STATS_H__ */
+#endif /* __RENDER_STATS_H__ */
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 360b2b461cf..d8e3e24f39e 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -49,107 +49,106 @@ void SVMShaderManager::device_update_shader(Scene *scene,
Progress *progress,
array<int4> *global_svm_nodes)
{
- if(progress->get_cancel()) {
- return;
- }
- assert(shader->graph);
+ if (progress->get_cancel()) {
+ return;
+ }
+ assert(shader->graph);
- array<int4> svm_nodes;
- svm_nodes.push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
+ array<int4> svm_nodes;
+ svm_nodes.push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
- SVMCompiler::Summary summary;
- SVMCompiler compiler(scene->shader_manager, scene->image_manager, scene->light_manager);
- compiler.background = (shader == scene->default_background);
- compiler.compile(scene, shader, svm_nodes, 0, &summary);
+ SVMCompiler::Summary summary;
+ SVMCompiler compiler(scene->shader_manager, scene->image_manager, scene->light_manager);
+ compiler.background = (shader == scene->default_background);
+ compiler.compile(scene, shader, svm_nodes, 0, &summary);
- VLOG(2) << "Compilation summary:\n"
- << "Shader name: " << shader->name << "\n"
- << summary.full_report();
+ VLOG(2) << "Compilation summary:\n"
+ << "Shader name: " << shader->name << "\n"
+ << summary.full_report();
- nodes_lock_.lock();
- if(shader->use_mis && shader->has_surface_emission) {
- scene->light_manager->need_update = true;
- }
+ nodes_lock_.lock();
+ if (shader->use_mis && shader->has_surface_emission) {
+ scene->light_manager->need_update = true;
+ }
- /* The copy needs to be done inside the lock, if another thread resizes the array
- * while memcpy is running, it'll be copying into possibly invalid/freed ram.
- */
- size_t global_nodes_size = global_svm_nodes->size();
- global_svm_nodes->resize(global_nodes_size + svm_nodes.size());
+ /* The copy needs to be done inside the lock, if another thread resizes the array
+ * while memcpy is running, it'll be copying into possibly invalid/freed ram.
+ */
+ size_t global_nodes_size = global_svm_nodes->size();
+ global_svm_nodes->resize(global_nodes_size + svm_nodes.size());
- /* Offset local SVM nodes to a global address space. */
- int4& jump_node = (*global_svm_nodes)[shader->id];
- jump_node.y = svm_nodes[0].y + global_nodes_size - 1;
- jump_node.z = svm_nodes[0].z + global_nodes_size - 1;
- jump_node.w = svm_nodes[0].w + global_nodes_size - 1;
- /* Copy new nodes to global storage. */
- memcpy(&(*global_svm_nodes)[global_nodes_size],
- &svm_nodes[1],
- sizeof(int4) * (svm_nodes.size() - 1));
- nodes_lock_.unlock();
+ /* Offset local SVM nodes to a global address space. */
+ int4 &jump_node = (*global_svm_nodes)[shader->id];
+ jump_node.y = svm_nodes[0].y + global_nodes_size - 1;
+ jump_node.z = svm_nodes[0].z + global_nodes_size - 1;
+ jump_node.w = svm_nodes[0].w + global_nodes_size - 1;
+ /* Copy new nodes to global storage. */
+ memcpy(&(*global_svm_nodes)[global_nodes_size],
+ &svm_nodes[1],
+ sizeof(int4) * (svm_nodes.size() - 1));
+ nodes_lock_.unlock();
}
-void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+void SVMShaderManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress &progress)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
+ VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
- double start_time = time_dt();
+ double start_time = time_dt();
- /* test if we need to update */
- device_free(device, dscene, scene);
+ /* test if we need to update */
+ device_free(device, dscene, scene);
- /* determine which shaders are in use */
- device_update_shaders_used(scene);
+ /* determine which shaders are in use */
+ device_update_shaders_used(scene);
- /* svm_nodes */
- array<int4> svm_nodes;
- size_t i;
+ /* svm_nodes */
+ array<int4> svm_nodes;
+ size_t i;
- for(i = 0; i < scene->shaders.size(); i++) {
- svm_nodes.push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
- }
+ for (i = 0; i < scene->shaders.size(); i++) {
+ svm_nodes.push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
+ }
- TaskPool task_pool;
- foreach(Shader *shader, scene->shaders) {
- task_pool.push(function_bind(&SVMShaderManager::device_update_shader,
- this,
- scene,
- shader,
- &progress,
- &svm_nodes),
- false);
- }
- task_pool.wait_work();
+ TaskPool task_pool;
+ foreach (Shader *shader, scene->shaders) {
+ task_pool.push(
+ function_bind(
+ &SVMShaderManager::device_update_shader, this, scene, shader, &progress, &svm_nodes),
+ false);
+ }
+ task_pool.wait_work();
- if(progress.get_cancel()) {
- return;
- }
+ if (progress.get_cancel()) {
+ return;
+ }
- dscene->svm_nodes.steal_data(svm_nodes);
- dscene->svm_nodes.copy_to_device();
+ dscene->svm_nodes.steal_data(svm_nodes);
+ dscene->svm_nodes.copy_to_device();
- for(i = 0; i < scene->shaders.size(); i++) {
- Shader *shader = scene->shaders[i];
- shader->need_update = false;
- }
+ for (i = 0; i < scene->shaders.size(); i++) {
+ Shader *shader = scene->shaders[i];
+ shader->need_update = false;
+ }
- device_update_common(device, dscene, scene, progress);
+ device_update_common(device, dscene, scene, progress);
- need_update = false;
+ need_update = false;
- VLOG(1) << "Shader manager updated "
- << scene->shaders.size() << " shaders in "
- << time_dt() - start_time << " seconds.";
+ VLOG(1) << "Shader manager updated " << scene->shaders.size() << " shaders in "
+ << time_dt() - start_time << " seconds.";
}
void SVMShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
{
- device_free_common(device, dscene, scene);
+ device_free_common(device, dscene, scene);
- dscene->svm_nodes.free();
+ dscene->svm_nodes.free();
}
/* Graph Compiler */
@@ -158,772 +157,751 @@ SVMCompiler::SVMCompiler(ShaderManager *shader_manager_,
ImageManager *image_manager_,
LightManager *light_manager_)
{
- shader_manager = shader_manager_;
- image_manager = image_manager_;
- light_manager = light_manager_;
- max_stack_use = 0;
- current_type = SHADER_TYPE_SURFACE;
- current_shader = NULL;
- current_graph = NULL;
- background = false;
- mix_weight_offset = SVM_STACK_INVALID;
- compile_failed = false;
+ shader_manager = shader_manager_;
+ image_manager = image_manager_;
+ light_manager = light_manager_;
+ max_stack_use = 0;
+ current_type = SHADER_TYPE_SURFACE;
+ current_shader = NULL;
+ current_graph = NULL;
+ background = false;
+ mix_weight_offset = SVM_STACK_INVALID;
+ compile_failed = false;
}
int SVMCompiler::stack_size(SocketType::Type type)
{
- int size = 0;
-
- switch(type) {
- case SocketType::FLOAT:
- case SocketType::INT:
- size = 1;
- break;
- case SocketType::COLOR:
- case SocketType::VECTOR:
- case SocketType::NORMAL:
- case SocketType::POINT:
- size = 3;
- break;
- case SocketType::CLOSURE:
- size = 0;
- break;
- default:
- assert(0);
- break;
- }
-
- return size;
+ int size = 0;
+
+ switch (type) {
+ case SocketType::FLOAT:
+ case SocketType::INT:
+ size = 1;
+ break;
+ case SocketType::COLOR:
+ case SocketType::VECTOR:
+ case SocketType::NORMAL:
+ case SocketType::POINT:
+ size = 3;
+ break;
+ case SocketType::CLOSURE:
+ size = 0;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ return size;
}
int SVMCompiler::stack_find_offset(int size)
{
- int offset = -1;
+ int offset = -1;
- /* find free space in stack & mark as used */
- for(int i = 0, num_unused = 0; i < SVM_STACK_SIZE; i++) {
- if(active_stack.users[i]) num_unused = 0;
- else num_unused++;
+ /* find free space in stack & mark as used */
+ for (int i = 0, num_unused = 0; i < SVM_STACK_SIZE; i++) {
+ if (active_stack.users[i])
+ num_unused = 0;
+ else
+ num_unused++;
- if(num_unused == size) {
- offset = i+1 - size;
- max_stack_use = max(i+1, max_stack_use);
+ if (num_unused == size) {
+ offset = i + 1 - size;
+ max_stack_use = max(i + 1, max_stack_use);
- while(i >= offset)
- active_stack.users[i--] = 1;
+ while (i >= offset)
+ active_stack.users[i--] = 1;
- return offset;
- }
- }
+ return offset;
+ }
+ }
- if(!compile_failed) {
- compile_failed = true;
- fprintf(stderr, "Cycles: out of SVM stack space, shader \"%s\" too big.\n", current_shader->name.c_str());
- }
+ if (!compile_failed) {
+ compile_failed = true;
+ fprintf(stderr,
+ "Cycles: out of SVM stack space, shader \"%s\" too big.\n",
+ current_shader->name.c_str());
+ }
- return 0;
+ return 0;
}
int SVMCompiler::stack_find_offset(SocketType::Type type)
{
- return stack_find_offset(stack_size(type));
+ return stack_find_offset(stack_size(type));
}
void SVMCompiler::stack_clear_offset(SocketType::Type type, int offset)
{
- int size = stack_size(type);
+ int size = stack_size(type);
- for(int i = 0; i < size; i++)
- active_stack.users[offset + i]--;
+ for (int i = 0; i < size; i++)
+ active_stack.users[offset + i]--;
}
int SVMCompiler::stack_assign(ShaderInput *input)
{
- /* stack offset assign? */
- if(input->stack_offset == SVM_STACK_INVALID) {
- if(input->link) {
- /* linked to output -> use output offset */
- assert(input->link->stack_offset != SVM_STACK_INVALID);
- input->stack_offset = input->link->stack_offset;
- }
- else {
- Node *node = input->parent;
-
- /* not linked to output -> add nodes to load default value */
- input->stack_offset = stack_find_offset(input->type());
-
- if(input->type() == SocketType::FLOAT) {
- add_node(NODE_VALUE_F, __float_as_int(node->get_float(input->socket_type)), input->stack_offset);
- }
- else if(input->type() == SocketType::INT) {
- add_node(NODE_VALUE_F, node->get_int(input->socket_type), input->stack_offset);
- }
- else if(input->type() == SocketType::VECTOR ||
- input->type() == SocketType::NORMAL ||
- input->type() == SocketType::POINT ||
- input->type() == SocketType::COLOR)
- {
-
- add_node(NODE_VALUE_V, input->stack_offset);
- add_node(NODE_VALUE_V, node->get_float3(input->socket_type));
- }
- else /* should not get called for closure */
- assert(0);
- }
- }
-
- return input->stack_offset;
+ /* stack offset assign? */
+ if (input->stack_offset == SVM_STACK_INVALID) {
+ if (input->link) {
+ /* linked to output -> use output offset */
+ assert(input->link->stack_offset != SVM_STACK_INVALID);
+ input->stack_offset = input->link->stack_offset;
+ }
+ else {
+ Node *node = input->parent;
+
+ /* not linked to output -> add nodes to load default value */
+ input->stack_offset = stack_find_offset(input->type());
+
+ if (input->type() == SocketType::FLOAT) {
+ add_node(NODE_VALUE_F,
+ __float_as_int(node->get_float(input->socket_type)),
+ input->stack_offset);
+ }
+ else if (input->type() == SocketType::INT) {
+ add_node(NODE_VALUE_F, node->get_int(input->socket_type), input->stack_offset);
+ }
+ else if (input->type() == SocketType::VECTOR || input->type() == SocketType::NORMAL ||
+ input->type() == SocketType::POINT || input->type() == SocketType::COLOR) {
+
+ add_node(NODE_VALUE_V, input->stack_offset);
+ add_node(NODE_VALUE_V, node->get_float3(input->socket_type));
+ }
+ else /* should not get called for closure */
+ assert(0);
+ }
+ }
+
+ return input->stack_offset;
}
int SVMCompiler::stack_assign(ShaderOutput *output)
{
- /* if no stack offset assigned yet, find one */
- if(output->stack_offset == SVM_STACK_INVALID)
- output->stack_offset = stack_find_offset(output->type());
+ /* if no stack offset assigned yet, find one */
+ if (output->stack_offset == SVM_STACK_INVALID)
+ output->stack_offset = stack_find_offset(output->type());
- return output->stack_offset;
+ return output->stack_offset;
}
int SVMCompiler::stack_assign_if_linked(ShaderInput *input)
{
- if(input->link)
- return stack_assign(input);
+ if (input->link)
+ return stack_assign(input);
- return SVM_STACK_INVALID;
+ return SVM_STACK_INVALID;
}
int SVMCompiler::stack_assign_if_linked(ShaderOutput *output)
{
- if(!output->links.empty())
- return stack_assign(output);
+ if (!output->links.empty())
+ return stack_assign(output);
- return SVM_STACK_INVALID;
+ return SVM_STACK_INVALID;
}
void SVMCompiler::stack_link(ShaderInput *input, ShaderOutput *output)
{
- if(output->stack_offset == SVM_STACK_INVALID) {
- assert(input->link);
- assert(stack_size(output->type()) == stack_size(input->link->type()));
+ if (output->stack_offset == SVM_STACK_INVALID) {
+ assert(input->link);
+ assert(stack_size(output->type()) == stack_size(input->link->type()));
- output->stack_offset = input->link->stack_offset;
+ output->stack_offset = input->link->stack_offset;
- int size = stack_size(output->type());
+ int size = stack_size(output->type());
- for(int i = 0; i < size; i++)
- active_stack.users[output->stack_offset + i]++;
- }
+ for (int i = 0; i < size; i++)
+ active_stack.users[output->stack_offset + i]++;
+ }
}
-void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet& done)
+void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet &done)
{
- /* optimization we should add:
- * find and lower user counts for outputs for which all inputs are done.
- * this is done before the node is compiled, under the assumption that the
- * node will first load all inputs from the stack and then writes its
- * outputs. this used to work, but was disabled because it gave trouble
- * with inputs getting stack positions assigned */
+ /* optimization we should add:
+ * find and lower user counts for outputs for which all inputs are done.
+ * this is done before the node is compiled, under the assumption that the
+ * node will first load all inputs from the stack and then writes its
+ * outputs. this used to work, but was disabled because it gave trouble
+ * with inputs getting stack positions assigned */
- foreach(ShaderInput *input, node->inputs) {
- ShaderOutput *output = input->link;
+ foreach (ShaderInput *input, node->inputs) {
+ ShaderOutput *output = input->link;
- if(output && output->stack_offset != SVM_STACK_INVALID) {
- bool all_done = true;
+ if (output && output->stack_offset != SVM_STACK_INVALID) {
+ bool all_done = true;
- /* optimization we should add: verify if in->parent is actually used */
- foreach(ShaderInput *in, output->links)
- if(in->parent != node && done.find(in->parent) == done.end())
- all_done = false;
+ /* optimization we should add: verify if in->parent is actually used */
+ foreach (ShaderInput *in, output->links)
+ if (in->parent != node && done.find(in->parent) == done.end())
+ all_done = false;
- if(all_done) {
- stack_clear_offset(output->type(), output->stack_offset);
- output->stack_offset = SVM_STACK_INVALID;
+ if (all_done) {
+ stack_clear_offset(output->type(), output->stack_offset);
+ output->stack_offset = SVM_STACK_INVALID;
- foreach(ShaderInput *in, output->links)
- in->stack_offset = SVM_STACK_INVALID;
- }
- }
- }
+ foreach (ShaderInput *in, output->links)
+ in->stack_offset = SVM_STACK_INVALID;
+ }
+ }
+ }
}
void SVMCompiler::stack_clear_temporary(ShaderNode *node)
{
- foreach(ShaderInput *input, node->inputs) {
- if(!input->link && input->stack_offset != SVM_STACK_INVALID) {
- stack_clear_offset(input->type(), input->stack_offset);
- input->stack_offset = SVM_STACK_INVALID;
- }
- }
+ foreach (ShaderInput *input, node->inputs) {
+ if (!input->link && input->stack_offset != SVM_STACK_INVALID) {
+ stack_clear_offset(input->type(), input->stack_offset);
+ input->stack_offset = SVM_STACK_INVALID;
+ }
+ }
}
uint SVMCompiler::encode_uchar4(uint x, uint y, uint z, uint w)
{
- assert(x <= 255);
- assert(y <= 255);
- assert(z <= 255);
- assert(w <= 255);
+ assert(x <= 255);
+ assert(y <= 255);
+ assert(z <= 255);
+ assert(w <= 255);
- return (x) | (y << 8) | (z << 16) | (w << 24);
+ return (x) | (y << 8) | (z << 16) | (w << 24);
}
void SVMCompiler::add_node(int a, int b, int c, int d)
{
- current_svm_nodes.push_back_slow(make_int4(a, b, c, d));
+ current_svm_nodes.push_back_slow(make_int4(a, b, c, d));
}
void SVMCompiler::add_node(ShaderNodeType type, int a, int b, int c)
{
- current_svm_nodes.push_back_slow(make_int4(type, a, b, c));
+ current_svm_nodes.push_back_slow(make_int4(type, a, b, c));
}
-void SVMCompiler::add_node(ShaderNodeType type, const float3& f)
+void SVMCompiler::add_node(ShaderNodeType type, const float3 &f)
{
- current_svm_nodes.push_back_slow(make_int4(type,
- __float_as_int(f.x),
- __float_as_int(f.y),
- __float_as_int(f.z)));
+ current_svm_nodes.push_back_slow(
+ make_int4(type, __float_as_int(f.x), __float_as_int(f.y), __float_as_int(f.z)));
}
-void SVMCompiler::add_node(const float4& f)
+void SVMCompiler::add_node(const float4 &f)
{
- current_svm_nodes.push_back_slow(make_int4(
- __float_as_int(f.x),
- __float_as_int(f.y),
- __float_as_int(f.z),
- __float_as_int(f.w)));
+ current_svm_nodes.push_back_slow(make_int4(
+ __float_as_int(f.x), __float_as_int(f.y), __float_as_int(f.z), __float_as_int(f.w)));
}
uint SVMCompiler::attribute(ustring name)
{
- return shader_manager->get_attribute_id(name);
+ return shader_manager->get_attribute_id(name);
}
uint SVMCompiler::attribute(AttributeStandard std)
{
- return shader_manager->get_attribute_id(std);
+ return shader_manager->get_attribute_id(std);
}
uint SVMCompiler::attribute_standard(ustring name)
{
- AttributeStandard std = Attribute::name_standard(name.c_str());
- return (std)? attribute(std): attribute(name);
+ AttributeStandard std = Attribute::name_standard(name.c_str());
+ return (std) ? attribute(std) : attribute(name);
}
-void SVMCompiler::find_dependencies(ShaderNodeSet& dependencies,
- const ShaderNodeSet& done,
+void SVMCompiler::find_dependencies(ShaderNodeSet &dependencies,
+ const ShaderNodeSet &done,
ShaderInput *input,
ShaderNode *skip_node)
{
- ShaderNode *node = (input->link)? input->link->parent: NULL;
- if(node != NULL &&
- done.find(node) == done.end() &&
- node != skip_node &&
- dependencies.find(node) == dependencies.end())
- {
- foreach(ShaderInput *in, node->inputs) {
- find_dependencies(dependencies, done, in, skip_node);
- }
- dependencies.insert(node);
- }
-}
-
-void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet& done)
-{
- node->compile(*this);
- stack_clear_users(node, done);
- stack_clear_temporary(node);
-
- if(current_type == SHADER_TYPE_SURFACE) {
- if(node->has_spatial_varying())
- current_shader->has_surface_spatial_varying = true;
- }
- else if(current_type == SHADER_TYPE_VOLUME) {
- if(node->has_spatial_varying())
- current_shader->has_volume_spatial_varying = true;
- }
-
- if(node->has_object_dependency()) {
- current_shader->has_object_dependency = true;
- }
-
- if(node->has_attribute_dependency()) {
- current_shader->has_attribute_dependency = true;
- }
-
- if(node->has_integrator_dependency()) {
- current_shader->has_integrator_dependency = true;
- }
-}
-
-void SVMCompiler::generate_svm_nodes(const ShaderNodeSet& nodes,
- CompilerState *state)
-{
- ShaderNodeSet& done = state->nodes_done;
- vector<bool>& done_flag = state->nodes_done_flag;
-
- bool nodes_done;
- do {
- nodes_done = true;
-
- foreach(ShaderNode *node, nodes) {
- if(!done_flag[node->id]) {
- bool inputs_done = true;
-
- foreach(ShaderInput *input, node->inputs) {
- if(input->link && !done_flag[input->link->parent->id]) {
- inputs_done = false;
- }
- }
- if(inputs_done) {
- generate_node(node, done);
- done.insert(node);
- done_flag[node->id] = true;
- }
- else {
- nodes_done = false;
- }
- }
- }
- } while(!nodes_done);
-}
-
-void SVMCompiler::generate_closure_node(ShaderNode *node,
- CompilerState *state)
-{
- /* execute dependencies for closure */
- foreach(ShaderInput *in, node->inputs) {
- if(in->link != NULL) {
- ShaderNodeSet dependencies;
- find_dependencies(dependencies, state->nodes_done, in);
- generate_svm_nodes(dependencies, state);
- }
- }
-
- /* closure mix weight */
- const char *weight_name = (current_type == SHADER_TYPE_VOLUME)? "VolumeMixWeight": "SurfaceMixWeight";
- ShaderInput *weight_in = node->input(weight_name);
-
- if(weight_in && (weight_in->link || node->get_float(weight_in->socket_type) != 1.0f))
- mix_weight_offset = stack_assign(weight_in);
- else
- mix_weight_offset = SVM_STACK_INVALID;
-
- /* compile closure itself */
- generate_node(node, state->nodes_done);
-
- mix_weight_offset = SVM_STACK_INVALID;
-
- if(current_type == SHADER_TYPE_SURFACE) {
- if(node->has_surface_emission())
- current_shader->has_surface_emission = true;
- if(node->has_surface_transparent())
- current_shader->has_surface_transparent = true;
- if(node->has_surface_bssrdf()) {
- current_shader->has_surface_bssrdf = true;
- if(node->has_bssrdf_bump())
- current_shader->has_bssrdf_bump = true;
- }
- if(node->has_bump()) {
- current_shader->has_bump = true;
- }
- }
+ ShaderNode *node = (input->link) ? input->link->parent : NULL;
+ if (node != NULL && done.find(node) == done.end() && node != skip_node &&
+ dependencies.find(node) == dependencies.end()) {
+ foreach (ShaderInput *in, node->inputs) {
+ find_dependencies(dependencies, done, in, skip_node);
+ }
+ dependencies.insert(node);
+ }
+}
+
+void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet &done)
+{
+ node->compile(*this);
+ stack_clear_users(node, done);
+ stack_clear_temporary(node);
+
+ if (current_type == SHADER_TYPE_SURFACE) {
+ if (node->has_spatial_varying())
+ current_shader->has_surface_spatial_varying = true;
+ }
+ else if (current_type == SHADER_TYPE_VOLUME) {
+ if (node->has_spatial_varying())
+ current_shader->has_volume_spatial_varying = true;
+ }
+
+ if (node->has_object_dependency()) {
+ current_shader->has_object_dependency = true;
+ }
+
+ if (node->has_attribute_dependency()) {
+ current_shader->has_attribute_dependency = true;
+ }
+
+ if (node->has_integrator_dependency()) {
+ current_shader->has_integrator_dependency = true;
+ }
+}
+
+void SVMCompiler::generate_svm_nodes(const ShaderNodeSet &nodes, CompilerState *state)
+{
+ ShaderNodeSet &done = state->nodes_done;
+ vector<bool> &done_flag = state->nodes_done_flag;
+
+ bool nodes_done;
+ do {
+ nodes_done = true;
+
+ foreach (ShaderNode *node, nodes) {
+ if (!done_flag[node->id]) {
+ bool inputs_done = true;
+
+ foreach (ShaderInput *input, node->inputs) {
+ if (input->link && !done_flag[input->link->parent->id]) {
+ inputs_done = false;
+ }
+ }
+ if (inputs_done) {
+ generate_node(node, done);
+ done.insert(node);
+ done_flag[node->id] = true;
+ }
+ else {
+ nodes_done = false;
+ }
+ }
+ }
+ } while (!nodes_done);
+}
+
+void SVMCompiler::generate_closure_node(ShaderNode *node, CompilerState *state)
+{
+ /* execute dependencies for closure */
+ foreach (ShaderInput *in, node->inputs) {
+ if (in->link != NULL) {
+ ShaderNodeSet dependencies;
+ find_dependencies(dependencies, state->nodes_done, in);
+ generate_svm_nodes(dependencies, state);
+ }
+ }
+
+ /* closure mix weight */
+ const char *weight_name = (current_type == SHADER_TYPE_VOLUME) ? "VolumeMixWeight" :
+ "SurfaceMixWeight";
+ ShaderInput *weight_in = node->input(weight_name);
+
+ if (weight_in && (weight_in->link || node->get_float(weight_in->socket_type) != 1.0f))
+ mix_weight_offset = stack_assign(weight_in);
+ else
+ mix_weight_offset = SVM_STACK_INVALID;
+
+ /* compile closure itself */
+ generate_node(node, state->nodes_done);
+
+ mix_weight_offset = SVM_STACK_INVALID;
+
+ if (current_type == SHADER_TYPE_SURFACE) {
+ if (node->has_surface_emission())
+ current_shader->has_surface_emission = true;
+ if (node->has_surface_transparent())
+ current_shader->has_surface_transparent = true;
+ if (node->has_surface_bssrdf()) {
+ current_shader->has_surface_bssrdf = true;
+ if (node->has_bssrdf_bump())
+ current_shader->has_bssrdf_bump = true;
+ }
+ if (node->has_bump()) {
+ current_shader->has_bump = true;
+ }
+ }
}
void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node,
ShaderNode *node,
CompilerState *state,
- const ShaderNodeSet& shared)
-{
- if(shared.find(node) != shared.end()) {
- generate_multi_closure(root_node, node, state);
- }
- else {
- foreach(ShaderInput *in, node->inputs) {
- if(in->type() == SocketType::CLOSURE && in->link)
- generated_shared_closure_nodes(root_node,
- in->link->parent,
- state,
- shared);
- }
- }
+ const ShaderNodeSet &shared)
+{
+ if (shared.find(node) != shared.end()) {
+ generate_multi_closure(root_node, node, state);
+ }
+ else {
+ foreach (ShaderInput *in, node->inputs) {
+ if (in->type() == SocketType::CLOSURE && in->link)
+ generated_shared_closure_nodes(root_node, in->link->parent, state, shared);
+ }
+ }
}
void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
ShaderNode *node,
CompilerState *state)
{
- /* only generate once */
- if(state->closure_done.find(node) != state->closure_done.end())
- return;
-
- state->closure_done.insert(node);
-
- if(node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
- /* weighting is already taken care of in ShaderGraph::transform_multi_closure */
- ShaderInput *cl1in = node->input("Closure1");
- ShaderInput *cl2in = node->input("Closure2");
- ShaderInput *facin = node->input("Fac");
-
- /* skip empty mix/add closure nodes */
- if(!cl1in->link && !cl2in->link)
- return;
-
- if(facin && facin->link) {
- /* mix closure: generate instructions to compute mix weight */
- ShaderNodeSet dependencies;
- find_dependencies(dependencies, state->nodes_done, facin);
- generate_svm_nodes(dependencies, state);
-
- /* execute shared dependencies. this is needed to allow skipping
- * of zero weight closures and their dependencies later, so we
- * ensure that they only skip dependencies that are unique to them */
- ShaderNodeSet cl1deps, cl2deps, shareddeps;
-
- find_dependencies(cl1deps, state->nodes_done, cl1in);
- find_dependencies(cl2deps, state->nodes_done, cl2in);
-
- ShaderNodeIDComparator node_id_comp;
- set_intersection(cl1deps.begin(), cl1deps.end(),
- cl2deps.begin(), cl2deps.end(),
- std::inserter(shareddeps, shareddeps.begin()),
- node_id_comp);
-
- /* it's possible some nodes are not shared between this mix node
- * inputs, but still needed to be always executed, this mainly
- * happens when a node of current subbranch is used by a parent
- * node or so */
- if(root_node != node) {
- foreach(ShaderInput *in, root_node->inputs) {
- ShaderNodeSet rootdeps;
- find_dependencies(rootdeps, state->nodes_done, in, node);
- set_intersection(rootdeps.begin(), rootdeps.end(),
- cl1deps.begin(), cl1deps.end(),
- std::inserter(shareddeps, shareddeps.begin()),
- node_id_comp);
- set_intersection(rootdeps.begin(), rootdeps.end(),
- cl2deps.begin(), cl2deps.end(),
- std::inserter(shareddeps, shareddeps.begin()),
- node_id_comp);
- }
- }
-
- if(!shareddeps.empty()) {
- if(cl1in->link) {
- generated_shared_closure_nodes(root_node,
- cl1in->link->parent,
- state,
- shareddeps);
- }
- if(cl2in->link) {
- generated_shared_closure_nodes(root_node,
- cl2in->link->parent,
- state,
- shareddeps);
- }
-
- generate_svm_nodes(shareddeps, state);
- }
-
- /* generate instructions for input closure 1 */
- if(cl1in->link) {
- /* Add instruction to skip closure and its dependencies if mix
- * weight is zero.
- */
- current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ONE,
- 0,
- stack_assign(facin),
- 0));
- int node_jump_skip_index = current_svm_nodes.size() - 1;
-
- generate_multi_closure(root_node, cl1in->link->parent, state);
-
- /* Fill in jump instruction location to be after closure. */
- current_svm_nodes[node_jump_skip_index].y =
- current_svm_nodes.size() - node_jump_skip_index - 1;
- }
-
- /* generate instructions for input closure 2 */
- if(cl2in->link) {
- /* Add instruction to skip closure and its dependencies if mix
- * weight is zero.
- */
- current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ZERO,
- 0,
- stack_assign(facin),
- 0));
- int node_jump_skip_index = current_svm_nodes.size() - 1;
-
- generate_multi_closure(root_node, cl2in->link->parent, state);
-
- /* Fill in jump instruction location to be after closure. */
- current_svm_nodes[node_jump_skip_index].y =
- current_svm_nodes.size() - node_jump_skip_index - 1;
- }
-
- /* unassign */
- facin->stack_offset = SVM_STACK_INVALID;
- }
- else {
- /* execute closures and their dependencies, no runtime checks
- * to skip closures here because was already optimized due to
- * fixed weight or add closure that always needs both */
- if(cl1in->link)
- generate_multi_closure(root_node, cl1in->link->parent, state);
- if(cl2in->link)
- generate_multi_closure(root_node, cl2in->link->parent, state);
- }
- }
- else {
- generate_closure_node(node, state);
- }
-
- state->nodes_done.insert(node);
- state->nodes_done_flag[node->id] = true;
+ /* only generate once */
+ if (state->closure_done.find(node) != state->closure_done.end())
+ return;
+
+ state->closure_done.insert(node);
+
+ if (node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
+ /* weighting is already taken care of in ShaderGraph::transform_multi_closure */
+ ShaderInput *cl1in = node->input("Closure1");
+ ShaderInput *cl2in = node->input("Closure2");
+ ShaderInput *facin = node->input("Fac");
+
+ /* skip empty mix/add closure nodes */
+ if (!cl1in->link && !cl2in->link)
+ return;
+
+ if (facin && facin->link) {
+ /* mix closure: generate instructions to compute mix weight */
+ ShaderNodeSet dependencies;
+ find_dependencies(dependencies, state->nodes_done, facin);
+ generate_svm_nodes(dependencies, state);
+
+ /* execute shared dependencies. this is needed to allow skipping
+ * of zero weight closures and their dependencies later, so we
+ * ensure that they only skip dependencies that are unique to them */
+ ShaderNodeSet cl1deps, cl2deps, shareddeps;
+
+ find_dependencies(cl1deps, state->nodes_done, cl1in);
+ find_dependencies(cl2deps, state->nodes_done, cl2in);
+
+ ShaderNodeIDComparator node_id_comp;
+ set_intersection(cl1deps.begin(),
+ cl1deps.end(),
+ cl2deps.begin(),
+ cl2deps.end(),
+ std::inserter(shareddeps, shareddeps.begin()),
+ node_id_comp);
+
+ /* it's possible some nodes are not shared between this mix node
+ * inputs, but still needed to be always executed, this mainly
+ * happens when a node of current subbranch is used by a parent
+ * node or so */
+ if (root_node != node) {
+ foreach (ShaderInput *in, root_node->inputs) {
+ ShaderNodeSet rootdeps;
+ find_dependencies(rootdeps, state->nodes_done, in, node);
+ set_intersection(rootdeps.begin(),
+ rootdeps.end(),
+ cl1deps.begin(),
+ cl1deps.end(),
+ std::inserter(shareddeps, shareddeps.begin()),
+ node_id_comp);
+ set_intersection(rootdeps.begin(),
+ rootdeps.end(),
+ cl2deps.begin(),
+ cl2deps.end(),
+ std::inserter(shareddeps, shareddeps.begin()),
+ node_id_comp);
+ }
+ }
+
+ if (!shareddeps.empty()) {
+ if (cl1in->link) {
+ generated_shared_closure_nodes(root_node, cl1in->link->parent, state, shareddeps);
+ }
+ if (cl2in->link) {
+ generated_shared_closure_nodes(root_node, cl2in->link->parent, state, shareddeps);
+ }
+
+ generate_svm_nodes(shareddeps, state);
+ }
+
+ /* generate instructions for input closure 1 */
+ if (cl1in->link) {
+ /* Add instruction to skip closure and its dependencies if mix
+ * weight is zero.
+ */
+ current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ONE, 0, stack_assign(facin), 0));
+ int node_jump_skip_index = current_svm_nodes.size() - 1;
+
+ generate_multi_closure(root_node, cl1in->link->parent, state);
+
+ /* Fill in jump instruction location to be after closure. */
+ current_svm_nodes[node_jump_skip_index].y = current_svm_nodes.size() -
+ node_jump_skip_index - 1;
+ }
+
+ /* generate instructions for input closure 2 */
+ if (cl2in->link) {
+ /* Add instruction to skip closure and its dependencies if mix
+ * weight is zero.
+ */
+ current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ZERO, 0, stack_assign(facin), 0));
+ int node_jump_skip_index = current_svm_nodes.size() - 1;
+
+ generate_multi_closure(root_node, cl2in->link->parent, state);
+
+ /* Fill in jump instruction location to be after closure. */
+ current_svm_nodes[node_jump_skip_index].y = current_svm_nodes.size() -
+ node_jump_skip_index - 1;
+ }
+
+ /* unassign */
+ facin->stack_offset = SVM_STACK_INVALID;
+ }
+ else {
+ /* execute closures and their dependencies, no runtime checks
+ * to skip closures here because was already optimized due to
+ * fixed weight or add closure that always needs both */
+ if (cl1in->link)
+ generate_multi_closure(root_node, cl1in->link->parent, state);
+ if (cl2in->link)
+ generate_multi_closure(root_node, cl2in->link->parent, state);
+ }
+ }
+ else {
+ generate_closure_node(node, state);
+ }
+
+ state->nodes_done.insert(node);
+ state->nodes_done_flag[node->id] = true;
}
-
void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
{
- /* Converting a shader graph into svm_nodes that can be executed
- * sequentially on the virtual machine is fairly simple. We can keep
- * looping over nodes and each time all the inputs of a node are
- * ready, we add svm_nodes for it that read the inputs from the
- * stack and write outputs back to the stack.
- *
- * With the SVM, we always sample only a single closure. We can think
- * of all closures nodes as a binary tree with mix closures as inner
- * nodes and other closures as leafs. The SVM will traverse that tree,
- * each time deciding to go left or right depending on the mix weights,
- * until a closure is found.
- *
- * We only execute nodes that are needed for the mix weights and chosen
- * closure.
- */
-
- current_type = type;
- current_graph = graph;
-
- /* get input in output node */
- ShaderNode *node = graph->output();
- ShaderInput *clin = NULL;
-
- switch(type) {
- case SHADER_TYPE_SURFACE:
- clin = node->input("Surface");
- break;
- case SHADER_TYPE_VOLUME:
- clin = node->input("Volume");
- break;
- case SHADER_TYPE_DISPLACEMENT:
- clin = node->input("Displacement");
- break;
- case SHADER_TYPE_BUMP:
- clin = node->input("Normal");
- break;
- default:
- assert(0);
- break;
- }
-
- /* clear all compiler state */
- memset((void *)&active_stack, 0, sizeof(active_stack));
- current_svm_nodes.clear();
-
- foreach(ShaderNode *node_iter, graph->nodes) {
- foreach(ShaderInput *input, node_iter->inputs)
- input->stack_offset = SVM_STACK_INVALID;
- foreach(ShaderOutput *output, node_iter->outputs)
- output->stack_offset = SVM_STACK_INVALID;
- }
-
- /* for the bump shader we need add a node to store the shader state */
- bool need_bump_state = (type == SHADER_TYPE_BUMP) && (shader->displacement_method == DISPLACE_BOTH);
- int bump_state_offset = SVM_STACK_INVALID;
- if(need_bump_state) {
- bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE);
- add_node(NODE_ENTER_BUMP_EVAL, bump_state_offset);
- }
-
- if(shader->used) {
- if(clin->link) {
- bool generate = false;
-
- switch(type) {
- case SHADER_TYPE_SURFACE: /* generate surface shader */
- generate = true;
- shader->has_surface = true;
- break;
- case SHADER_TYPE_VOLUME: /* generate volume shader */
- generate = true;
- shader->has_volume = true;
- break;
- case SHADER_TYPE_DISPLACEMENT: /* generate displacement shader */
- generate = true;
- shader->has_displacement = true;
- break;
- case SHADER_TYPE_BUMP: /* generate bump shader */
- generate = true;
- break;
- default:
- break;
- }
-
- if(generate) {
- CompilerState state(graph);
- generate_multi_closure(clin->link->parent,
- clin->link->parent,
- &state);
- }
- }
-
- /* compile output node */
- node->compile(*this);
- }
-
- /* add node to restore state after bump shader has finished */
- if(need_bump_state) {
- add_node(NODE_LEAVE_BUMP_EVAL, bump_state_offset);
- }
-
- /* if compile failed, generate empty shader */
- if(compile_failed) {
- current_svm_nodes.clear();
- compile_failed = false;
- }
-
- /* for bump shaders we fall thru to the surface shader, but if this is any other kind of shader it ends here */
- if(type != SHADER_TYPE_BUMP) {
- add_node(NODE_END, 0, 0, 0);
- }
-}
-
-void SVMCompiler::compile(Scene *scene,
- Shader *shader,
- array<int4>& svm_nodes,
- int index,
- Summary *summary)
-{
- /* copy graph for shader with bump mapping */
- ShaderNode *output = shader->graph->output();
- int start_num_svm_nodes = svm_nodes.size();
-
- const double time_start = time_dt();
-
- bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
- output->input("Surface")->link && output->input("Displacement")->link;
-
- /* finalize */
- {
- scoped_timer timer((summary != NULL)? &summary->time_finalize: NULL);
- shader->graph->finalize(scene,
- has_bump,
- shader->has_integrator_dependency,
- shader->displacement_method == DISPLACE_BOTH);
- }
-
- current_shader = shader;
-
- shader->has_surface = false;
- shader->has_surface_emission = false;
- shader->has_surface_transparent = false;
- shader->has_surface_bssrdf = false;
- shader->has_bump = has_bump;
- shader->has_bssrdf_bump = has_bump;
- shader->has_volume = false;
- shader->has_displacement = false;
- shader->has_surface_spatial_varying = false;
- shader->has_volume_spatial_varying = false;
- shader->has_object_dependency = false;
- shader->has_attribute_dependency = false;
- shader->has_integrator_dependency = false;
-
- /* generate bump shader */
- if(has_bump) {
- scoped_timer timer((summary != NULL)? &summary->time_generate_bump: NULL);
- compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
- svm_nodes[index].y = svm_nodes.size();
- svm_nodes.append(current_svm_nodes);
- }
-
- /* generate surface shader */
- {
- scoped_timer timer((summary != NULL)? &summary->time_generate_surface: NULL);
- compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
- /* only set jump offset if there's no bump shader, as the bump shader will fall thru to this one if it exists */
- if(!has_bump) {
- svm_nodes[index].y = svm_nodes.size();
- }
- svm_nodes.append(current_svm_nodes);
- }
-
- /* generate volume shader */
- {
- scoped_timer timer((summary != NULL)? &summary->time_generate_volume: NULL);
- compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
- svm_nodes[index].z = svm_nodes.size();
- svm_nodes.append(current_svm_nodes);
- }
-
- /* generate displacement shader */
- {
- scoped_timer timer((summary != NULL)? &summary->time_generate_displacement: NULL);
- compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
- svm_nodes[index].w = svm_nodes.size();
- svm_nodes.append(current_svm_nodes);
- }
-
- /* Fill in summary information. */
- if(summary != NULL) {
- summary->time_total = time_dt() - time_start;
- summary->peak_stack_usage = max_stack_use;
- summary->num_svm_nodes = svm_nodes.size() - start_num_svm_nodes;
- }
+ /* Converting a shader graph into svm_nodes that can be executed
+ * sequentially on the virtual machine is fairly simple. We can keep
+ * looping over nodes and each time all the inputs of a node are
+ * ready, we add svm_nodes for it that read the inputs from the
+ * stack and write outputs back to the stack.
+ *
+ * With the SVM, we always sample only a single closure. We can think
+ * of all closures nodes as a binary tree with mix closures as inner
+ * nodes and other closures as leafs. The SVM will traverse that tree,
+ * each time deciding to go left or right depending on the mix weights,
+ * until a closure is found.
+ *
+ * We only execute nodes that are needed for the mix weights and chosen
+ * closure.
+ */
+
+ current_type = type;
+ current_graph = graph;
+
+ /* get input in output node */
+ ShaderNode *node = graph->output();
+ ShaderInput *clin = NULL;
+
+ switch (type) {
+ case SHADER_TYPE_SURFACE:
+ clin = node->input("Surface");
+ break;
+ case SHADER_TYPE_VOLUME:
+ clin = node->input("Volume");
+ break;
+ case SHADER_TYPE_DISPLACEMENT:
+ clin = node->input("Displacement");
+ break;
+ case SHADER_TYPE_BUMP:
+ clin = node->input("Normal");
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ /* clear all compiler state */
+ memset((void *)&active_stack, 0, sizeof(active_stack));
+ current_svm_nodes.clear();
+
+ foreach (ShaderNode *node_iter, graph->nodes) {
+ foreach (ShaderInput *input, node_iter->inputs)
+ input->stack_offset = SVM_STACK_INVALID;
+ foreach (ShaderOutput *output, node_iter->outputs)
+ output->stack_offset = SVM_STACK_INVALID;
+ }
+
+ /* for the bump shader we need add a node to store the shader state */
+ bool need_bump_state = (type == SHADER_TYPE_BUMP) &&
+ (shader->displacement_method == DISPLACE_BOTH);
+ int bump_state_offset = SVM_STACK_INVALID;
+ if (need_bump_state) {
+ bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE);
+ add_node(NODE_ENTER_BUMP_EVAL, bump_state_offset);
+ }
+
+ if (shader->used) {
+ if (clin->link) {
+ bool generate = false;
+
+ switch (type) {
+ case SHADER_TYPE_SURFACE: /* generate surface shader */
+ generate = true;
+ shader->has_surface = true;
+ break;
+ case SHADER_TYPE_VOLUME: /* generate volume shader */
+ generate = true;
+ shader->has_volume = true;
+ break;
+ case SHADER_TYPE_DISPLACEMENT: /* generate displacement shader */
+ generate = true;
+ shader->has_displacement = true;
+ break;
+ case SHADER_TYPE_BUMP: /* generate bump shader */
+ generate = true;
+ break;
+ default:
+ break;
+ }
+
+ if (generate) {
+ CompilerState state(graph);
+ generate_multi_closure(clin->link->parent, clin->link->parent, &state);
+ }
+ }
+
+ /* compile output node */
+ node->compile(*this);
+ }
+
+ /* add node to restore state after bump shader has finished */
+ if (need_bump_state) {
+ add_node(NODE_LEAVE_BUMP_EVAL, bump_state_offset);
+ }
+
+ /* if compile failed, generate empty shader */
+ if (compile_failed) {
+ current_svm_nodes.clear();
+ compile_failed = false;
+ }
+
+ /* for bump shaders we fall thru to the surface shader, but if this is any other kind of shader it ends here */
+ if (type != SHADER_TYPE_BUMP) {
+ add_node(NODE_END, 0, 0, 0);
+ }
+}
+
+void SVMCompiler::compile(
+ Scene *scene, Shader *shader, array<int4> &svm_nodes, int index, Summary *summary)
+{
+ /* copy graph for shader with bump mapping */
+ ShaderNode *output = shader->graph->output();
+ int start_num_svm_nodes = svm_nodes.size();
+
+ const double time_start = time_dt();
+
+ bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
+ output->input("Surface")->link && output->input("Displacement")->link;
+
+ /* finalize */
+ {
+ scoped_timer timer((summary != NULL) ? &summary->time_finalize : NULL);
+ shader->graph->finalize(scene,
+ has_bump,
+ shader->has_integrator_dependency,
+ shader->displacement_method == DISPLACE_BOTH);
+ }
+
+ current_shader = shader;
+
+ shader->has_surface = false;
+ shader->has_surface_emission = false;
+ shader->has_surface_transparent = false;
+ shader->has_surface_bssrdf = false;
+ shader->has_bump = has_bump;
+ shader->has_bssrdf_bump = has_bump;
+ shader->has_volume = false;
+ shader->has_displacement = false;
+ shader->has_surface_spatial_varying = false;
+ shader->has_volume_spatial_varying = false;
+ shader->has_object_dependency = false;
+ shader->has_attribute_dependency = false;
+ shader->has_integrator_dependency = false;
+
+ /* generate bump shader */
+ if (has_bump) {
+ scoped_timer timer((summary != NULL) ? &summary->time_generate_bump : NULL);
+ compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
+ svm_nodes[index].y = svm_nodes.size();
+ svm_nodes.append(current_svm_nodes);
+ }
+
+ /* generate surface shader */
+ {
+ scoped_timer timer((summary != NULL) ? &summary->time_generate_surface : NULL);
+ compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
+ /* only set jump offset if there's no bump shader, as the bump shader will fall thru to this one if it exists */
+ if (!has_bump) {
+ svm_nodes[index].y = svm_nodes.size();
+ }
+ svm_nodes.append(current_svm_nodes);
+ }
+
+ /* generate volume shader */
+ {
+ scoped_timer timer((summary != NULL) ? &summary->time_generate_volume : NULL);
+ compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
+ svm_nodes[index].z = svm_nodes.size();
+ svm_nodes.append(current_svm_nodes);
+ }
+
+ /* generate displacement shader */
+ {
+ scoped_timer timer((summary != NULL) ? &summary->time_generate_displacement : NULL);
+ compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
+ svm_nodes[index].w = svm_nodes.size();
+ svm_nodes.append(current_svm_nodes);
+ }
+
+ /* Fill in summary information. */
+ if (summary != NULL) {
+ summary->time_total = time_dt() - time_start;
+ summary->peak_stack_usage = max_stack_use;
+ summary->num_svm_nodes = svm_nodes.size() - start_num_svm_nodes;
+ }
}
/* Compiler summary implementation. */
SVMCompiler::Summary::Summary()
- : num_svm_nodes(0),
- peak_stack_usage(0),
- time_finalize(0.0),
- time_generate_surface(0.0),
- time_generate_bump(0.0),
- time_generate_volume(0.0),
- time_generate_displacement(0.0),
- time_total(0.0)
+ : num_svm_nodes(0),
+ peak_stack_usage(0),
+ time_finalize(0.0),
+ time_generate_surface(0.0),
+ time_generate_bump(0.0),
+ time_generate_volume(0.0),
+ time_generate_displacement(0.0),
+ time_total(0.0)
{
}
string SVMCompiler::Summary::full_report() const
{
- string report = "";
- report += string_printf("Number of SVM nodes: %d\n", num_svm_nodes);
- report += string_printf("Peak stack usage: %d\n", peak_stack_usage);
+ string report = "";
+ report += string_printf("Number of SVM nodes: %d\n", num_svm_nodes);
+ report += string_printf("Peak stack usage: %d\n", peak_stack_usage);
- report += string_printf("Time (in seconds):\n");
- report += string_printf("Finalize: %f\n", time_finalize);
- report += string_printf(" Surface: %f\n", time_generate_surface);
- report += string_printf(" Bump: %f\n", time_generate_bump);
- report += string_printf(" Volume: %f\n", time_generate_volume);
- report += string_printf(" Displacement: %f\n", time_generate_displacement);
- report += string_printf("Generate: %f\n", time_generate_surface +
- time_generate_bump +
- time_generate_volume +
- time_generate_displacement);
- report += string_printf("Total: %f\n", time_total);
+ report += string_printf("Time (in seconds):\n");
+ report += string_printf("Finalize: %f\n", time_finalize);
+ report += string_printf(" Surface: %f\n", time_generate_surface);
+ report += string_printf(" Bump: %f\n", time_generate_bump);
+ report += string_printf(" Volume: %f\n", time_generate_volume);
+ report += string_printf(" Displacement: %f\n", time_generate_displacement);
+ report += string_printf("Generate: %f\n",
+ time_generate_surface + time_generate_bump + time_generate_volume +
+ time_generate_displacement);
+ report += string_printf("Total: %f\n", time_total);
- return report;
+ return report;
}
/* Global state of the compiler. */
SVMCompiler::CompilerState::CompilerState(ShaderGraph *graph)
{
- int max_id = 0;
- foreach(ShaderNode *node, graph->nodes) {
- max_id = max(node->id, max_id);
- }
- nodes_done_flag.resize(max_id + 1, false);
+ int max_id = 0;
+ foreach (ShaderNode *node, graph->nodes) {
+ max_id = max(node->id, max_id);
+ }
+ nodes_done_flag.resize(max_id + 1, false);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index ddf35602fa6..d6964fb158b 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -40,186 +40,196 @@ class ShaderOutput;
/* Shader Manager */
class SVMShaderManager : public ShaderManager {
-public:
- SVMShaderManager();
- ~SVMShaderManager();
+ public:
+ SVMShaderManager();
+ ~SVMShaderManager();
- void reset(Scene *scene);
+ void reset(Scene *scene);
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_free(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
+ void device_free(Device *device, DeviceScene *dscene, Scene *scene);
-protected:
- /* Lock used to synchronize threaded nodes compilation. */
- thread_spin_lock nodes_lock_;
+ protected:
+ /* Lock used to synchronize threaded nodes compilation. */
+ thread_spin_lock nodes_lock_;
- void device_update_shader(Scene *scene,
- Shader *shader,
- Progress *progress,
- array<int4> *global_svm_nodes);
+ void device_update_shader(Scene *scene,
+ Shader *shader,
+ Progress *progress,
+ array<int4> *global_svm_nodes);
};
/* Graph Compiler */
class SVMCompiler {
-public:
- struct Summary {
- Summary();
-
- /* Number of SVM nodes shader was compiled into. */
- int num_svm_nodes;
-
- /* Peak stack usage during shader evaluation. */
- int peak_stack_usage;
-
- /* Time spent on surface graph finalization. */
- double time_finalize;
-
- /* Time spent on generating SVM nodes for surface shader. */
- double time_generate_surface;
-
- /* Time spent on generating SVM nodes for bump shader. */
- double time_generate_bump;
-
- /* Time spent on generating SVM nodes for volume shader. */
- double time_generate_volume;
-
- /* Time spent on generating SVM nodes for displacement shader. */
- double time_generate_displacement;
-
- /* Total time spent on all routines. */
- double time_total;
-
- /* A full multiline description of the state of the compiler after
- * compilation.
- */
- string full_report() const;
- };
-
- SVMCompiler(ShaderManager *shader_manager,
- ImageManager *image_manager,
- LightManager *light_manager);
- void compile(Scene *scene,
- Shader *shader,
- array<int4>& svm_nodes,
- int index,
- Summary *summary = NULL);
-
- int stack_assign(ShaderOutput *output);
- int stack_assign(ShaderInput *input);
- int stack_assign_if_linked(ShaderInput *input);
- int stack_assign_if_linked(ShaderOutput *output);
- int stack_find_offset(int size);
- int stack_find_offset(SocketType::Type type);
- void stack_clear_offset(SocketType::Type type, int offset);
- void stack_link(ShaderInput *input, ShaderOutput *output);
-
- void add_node(ShaderNodeType type, int a = 0, int b = 0, int c = 0);
- void add_node(int a = 0, int b = 0, int c = 0, int d = 0);
- void add_node(ShaderNodeType type, const float3& f);
- void add_node(const float4& f);
- uint attribute(ustring name);
- uint attribute(AttributeStandard std);
- uint attribute_standard(ustring name);
- uint encode_uchar4(uint x, uint y = 0, uint z = 0, uint w = 0);
- uint closure_mix_weight_offset() { return mix_weight_offset; }
-
- ShaderType output_type() { return current_type; }
-
- ImageManager *image_manager;
- ShaderManager *shader_manager;
- LightManager *light_manager;
- bool background;
-
-protected:
- /* stack */
- struct Stack {
- Stack() { memset(users, 0, sizeof(users)); }
- Stack(const Stack& other) { memcpy(users, other.users, sizeof(users)); }
- Stack& operator=(const Stack& other) { memcpy(users, other.users, sizeof(users)); return *this; }
-
- bool empty()
- {
- for(int i = 0; i < SVM_STACK_SIZE; i++)
- if(users[i])
- return false;
-
- return true;
- }
-
- void print()
- {
- printf("stack <");
-
- for(int i = 0; i < SVM_STACK_SIZE; i++)
- printf((users[i])? "*": " ");
-
- printf(">\n");
- }
-
- int users[SVM_STACK_SIZE];
- };
-
- /* Global state of the compiler accessible from the compilation routines. */
- struct CompilerState {
- explicit CompilerState(ShaderGraph *graph);
-
- /* ** Global state, used by various compilation steps. ** */
-
- /* Set of nodes which were already compiled. */
- ShaderNodeSet nodes_done;
-
- /* Set of closures which were already compiled. */
- ShaderNodeSet closure_done;
-
- /* ** SVM nodes generation state ** */
-
- /* Flag whether the node with corresponding ID was already compiled or
- * not. Array element with index i corresponds to a node with such if.
- *
- * TODO(sergey): This is actually a copy of nodes_done just in another
- * notation. We can de-duplicate this storage actually after switching
- * all areas to use this flags array.
- */
- vector<bool> nodes_done_flag;
- };
-
- void stack_clear_temporary(ShaderNode *node);
- int stack_size(SocketType::Type type);
- void stack_clear_users(ShaderNode *node, ShaderNodeSet& done);
-
- /* single closure */
- void find_dependencies(ShaderNodeSet& dependencies,
- const ShaderNodeSet& done,
- ShaderInput *input,
- ShaderNode *skip_node = NULL);
- void generate_node(ShaderNode *node, ShaderNodeSet& done);
- void generate_closure_node(ShaderNode *node, CompilerState *state);
- void generated_shared_closure_nodes(ShaderNode *root_node,
- ShaderNode *node,
- CompilerState *state,
- const ShaderNodeSet& shared);
- void generate_svm_nodes(const ShaderNodeSet& nodes,
- CompilerState *state);
-
- /* multi closure */
- void generate_multi_closure(ShaderNode *root_node,
- ShaderNode *node,
- CompilerState *state);
-
- /* compile */
- void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
-
- array<int4> current_svm_nodes;
- ShaderType current_type;
- Shader *current_shader;
- ShaderGraph *current_graph;
- Stack active_stack;
- int max_stack_use;
- uint mix_weight_offset;
- bool compile_failed;
+ public:
+ struct Summary {
+ Summary();
+
+ /* Number of SVM nodes shader was compiled into. */
+ int num_svm_nodes;
+
+ /* Peak stack usage during shader evaluation. */
+ int peak_stack_usage;
+
+ /* Time spent on surface graph finalization. */
+ double time_finalize;
+
+ /* Time spent on generating SVM nodes for surface shader. */
+ double time_generate_surface;
+
+ /* Time spent on generating SVM nodes for bump shader. */
+ double time_generate_bump;
+
+ /* Time spent on generating SVM nodes for volume shader. */
+ double time_generate_volume;
+
+ /* Time spent on generating SVM nodes for displacement shader. */
+ double time_generate_displacement;
+
+ /* Total time spent on all routines. */
+ double time_total;
+
+ /* A full multiline description of the state of the compiler after
+ * compilation.
+ */
+ string full_report() const;
+ };
+
+ SVMCompiler(ShaderManager *shader_manager,
+ ImageManager *image_manager,
+ LightManager *light_manager);
+ void compile(
+ Scene *scene, Shader *shader, array<int4> &svm_nodes, int index, Summary *summary = NULL);
+
+ int stack_assign(ShaderOutput *output);
+ int stack_assign(ShaderInput *input);
+ int stack_assign_if_linked(ShaderInput *input);
+ int stack_assign_if_linked(ShaderOutput *output);
+ int stack_find_offset(int size);
+ int stack_find_offset(SocketType::Type type);
+ void stack_clear_offset(SocketType::Type type, int offset);
+ void stack_link(ShaderInput *input, ShaderOutput *output);
+
+ void add_node(ShaderNodeType type, int a = 0, int b = 0, int c = 0);
+ void add_node(int a = 0, int b = 0, int c = 0, int d = 0);
+ void add_node(ShaderNodeType type, const float3 &f);
+ void add_node(const float4 &f);
+ uint attribute(ustring name);
+ uint attribute(AttributeStandard std);
+ uint attribute_standard(ustring name);
+ uint encode_uchar4(uint x, uint y = 0, uint z = 0, uint w = 0);
+ uint closure_mix_weight_offset()
+ {
+ return mix_weight_offset;
+ }
+
+ ShaderType output_type()
+ {
+ return current_type;
+ }
+
+ ImageManager *image_manager;
+ ShaderManager *shader_manager;
+ LightManager *light_manager;
+ bool background;
+
+ protected:
+ /* stack */
+ struct Stack {
+ Stack()
+ {
+ memset(users, 0, sizeof(users));
+ }
+ Stack(const Stack &other)
+ {
+ memcpy(users, other.users, sizeof(users));
+ }
+ Stack &operator=(const Stack &other)
+ {
+ memcpy(users, other.users, sizeof(users));
+ return *this;
+ }
+
+ bool empty()
+ {
+ for (int i = 0; i < SVM_STACK_SIZE; i++)
+ if (users[i])
+ return false;
+
+ return true;
+ }
+
+ void print()
+ {
+ printf("stack <");
+
+ for (int i = 0; i < SVM_STACK_SIZE; i++)
+ printf((users[i]) ? "*" : " ");
+
+ printf(">\n");
+ }
+
+ int users[SVM_STACK_SIZE];
+ };
+
+ /* Global state of the compiler accessible from the compilation routines. */
+ struct CompilerState {
+ explicit CompilerState(ShaderGraph *graph);
+
+ /* ** Global state, used by various compilation steps. ** */
+
+ /* Set of nodes which were already compiled. */
+ ShaderNodeSet nodes_done;
+
+ /* Set of closures which were already compiled. */
+ ShaderNodeSet closure_done;
+
+ /* ** SVM nodes generation state ** */
+
+ /* Flag whether the node with corresponding ID was already compiled or
+ * not. Array element with index i corresponds to a node with such if.
+ *
+ * TODO(sergey): This is actually a copy of nodes_done just in another
+ * notation. We can de-duplicate this storage actually after switching
+ * all areas to use this flags array.
+ */
+ vector<bool> nodes_done_flag;
+ };
+
+ void stack_clear_temporary(ShaderNode *node);
+ int stack_size(SocketType::Type type);
+ void stack_clear_users(ShaderNode *node, ShaderNodeSet &done);
+
+ /* single closure */
+ void find_dependencies(ShaderNodeSet &dependencies,
+ const ShaderNodeSet &done,
+ ShaderInput *input,
+ ShaderNode *skip_node = NULL);
+ void generate_node(ShaderNode *node, ShaderNodeSet &done);
+ void generate_closure_node(ShaderNode *node, CompilerState *state);
+ void generated_shared_closure_nodes(ShaderNode *root_node,
+ ShaderNode *node,
+ CompilerState *state,
+ const ShaderNodeSet &shared);
+ void generate_svm_nodes(const ShaderNodeSet &nodes, CompilerState *state);
+
+ /* multi closure */
+ void generate_multi_closure(ShaderNode *root_node, ShaderNode *node, CompilerState *state);
+
+ /* compile */
+ void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
+
+ array<int4> current_svm_nodes;
+ ShaderType current_type;
+ Shader *current_shader;
+ ShaderGraph *current_graph;
+ Stack active_stack;
+ int max_stack_use;
+ uint mix_weight_offset;
+ bool compile_failed;
};
CCL_NAMESPACE_END
-#endif /* __SVM_H__ */
+#endif /* __SVM_H__ */
diff --git a/intern/cycles/render/tables.cpp b/intern/cycles/render/tables.cpp
index ddbb138f059..d88925939e3 100644
--- a/intern/cycles/render/tables.cpp
+++ b/intern/cycles/render/tables.cpp
@@ -26,92 +26,92 @@ CCL_NAMESPACE_BEGIN
LookupTables::LookupTables()
{
- need_update = true;
+ need_update = true;
}
LookupTables::~LookupTables()
{
- assert(lookup_tables.size() == 0);
+ assert(lookup_tables.size() == 0);
}
void LookupTables::device_update(Device *, DeviceScene *dscene)
{
- if(!need_update)
- return;
+ if (!need_update)
+ return;
- VLOG(1) << "Total " << lookup_tables.size() << " lookup tables.";
+ VLOG(1) << "Total " << lookup_tables.size() << " lookup tables.";
- if(lookup_tables.size() > 0)
- dscene->lookup_table.copy_to_device();
+ if (lookup_tables.size() > 0)
+ dscene->lookup_table.copy_to_device();
- need_update = false;
+ need_update = false;
}
void LookupTables::device_free(Device *, DeviceScene *dscene)
{
- dscene->lookup_table.free();
+ dscene->lookup_table.free();
}
static size_t round_up_to_multiple(size_t size, size_t chunk)
{
- return ((size + chunk - 1)/chunk) * chunk;
+ return ((size + chunk - 1) / chunk) * chunk;
}
-size_t LookupTables::add_table(DeviceScene *dscene, vector<float>& data)
+size_t LookupTables::add_table(DeviceScene *dscene, vector<float> &data)
{
- assert(data.size() > 0);
+ assert(data.size() > 0);
- need_update = true;
+ need_update = true;
- Table new_table;
- new_table.offset = 0;
- new_table.size = round_up_to_multiple(data.size(), TABLE_CHUNK_SIZE);
+ Table new_table;
+ new_table.offset = 0;
+ new_table.size = round_up_to_multiple(data.size(), TABLE_CHUNK_SIZE);
- /* find space to put lookup table */
- list<Table>::iterator table;
+ /* find space to put lookup table */
+ list<Table>::iterator table;
- for(table = lookup_tables.begin(); table != lookup_tables.end(); table++) {
- if(new_table.offset + new_table.size <= table->offset) {
- lookup_tables.insert(table, new_table);
- break;
- }
- else
- new_table.offset = table->offset + table->size;
- }
+ for (table = lookup_tables.begin(); table != lookup_tables.end(); table++) {
+ if (new_table.offset + new_table.size <= table->offset) {
+ lookup_tables.insert(table, new_table);
+ break;
+ }
+ else
+ new_table.offset = table->offset + table->size;
+ }
- if(table == lookup_tables.end()) {
- /* add at the end */
- lookup_tables.push_back(new_table);
- dscene->lookup_table.resize(new_table.offset + new_table.size);
- }
+ if (table == lookup_tables.end()) {
+ /* add at the end */
+ lookup_tables.push_back(new_table);
+ dscene->lookup_table.resize(new_table.offset + new_table.size);
+ }
- /* copy table data and return offset */
- float *dtable = dscene->lookup_table.data();
- memcpy(dtable + new_table.offset, &data[0], sizeof(float) * data.size());
+ /* copy table data and return offset */
+ float *dtable = dscene->lookup_table.data();
+ memcpy(dtable + new_table.offset, &data[0], sizeof(float) * data.size());
- return new_table.offset;
+ return new_table.offset;
}
void LookupTables::remove_table(size_t *offset)
{
- if(*offset == TABLE_OFFSET_INVALID) {
- /* The table isn't even allocated, so just return here. */
- return;
- }
+ if (*offset == TABLE_OFFSET_INVALID) {
+ /* The table isn't even allocated, so just return here. */
+ return;
+ }
- need_update = true;
+ need_update = true;
- list<Table>::iterator table;
+ list<Table>::iterator table;
- for(table = lookup_tables.begin(); table != lookup_tables.end(); table++) {
- if(table->offset == *offset) {
- lookup_tables.erase(table);
- *offset = TABLE_OFFSET_INVALID;
- return;
- }
- }
+ for (table = lookup_tables.begin(); table != lookup_tables.end(); table++) {
+ if (table->offset == *offset) {
+ lookup_tables.erase(table);
+ *offset = TABLE_OFFSET_INVALID;
+ return;
+ }
+ }
- assert(table != lookup_tables.end());
+ assert(table != lookup_tables.end());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/tables.h b/intern/cycles/render/tables.h
index 709333cb1b6..12b59bb0aeb 100644
--- a/intern/cycles/render/tables.h
+++ b/intern/cycles/render/tables.h
@@ -29,25 +29,25 @@ enum { TABLE_CHUNK_SIZE = 256 };
enum { TABLE_OFFSET_INVALID = -1 };
class LookupTables {
-public:
- struct Table {
- size_t offset;
- size_t size;
- };
+ public:
+ struct Table {
+ size_t offset;
+ size_t size;
+ };
- bool need_update;
- list<Table> lookup_tables;
+ bool need_update;
+ list<Table> lookup_tables;
- LookupTables();
- ~LookupTables();
+ LookupTables();
+ ~LookupTables();
- void device_update(Device *device, DeviceScene *dscene);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_update(Device *device, DeviceScene *dscene);
+ void device_free(Device *device, DeviceScene *dscene);
- size_t add_table(DeviceScene *dscene, vector<float>& data);
- void remove_table(size_t *offset);
+ size_t add_table(DeviceScene *dscene, vector<float> &data);
+ void remove_table(size_t *offset);
};
CCL_NAMESPACE_END
-#endif /* __TABLES_H__ */
+#endif /* __TABLES_H__ */
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index dc863b067b0..3148b5ef664 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -25,89 +25,93 @@ CCL_NAMESPACE_BEGIN
namespace {
class TileComparator {
-public:
- TileComparator(TileOrder order_, int2 center_, Tile *tiles_)
- : order(order_),
- center(center_),
- tiles(tiles_)
- {}
-
- bool operator()(int a, int b)
- {
- switch(order) {
- case TILE_CENTER:
- {
- float2 dist_a = make_float2(center.x - (tiles[a].x + tiles[a].w/2),
- center.y - (tiles[a].y + tiles[a].h/2));
- float2 dist_b = make_float2(center.x - (tiles[b].x + tiles[b].w/2),
- center.y - (tiles[b].y + tiles[b].h/2));
- return dot(dist_a, dist_a) < dot(dist_b, dist_b);
- }
- case TILE_LEFT_TO_RIGHT:
- return (tiles[a].x == tiles[b].x)? (tiles[a].y < tiles[b].y): (tiles[a].x < tiles[b].x);
- case TILE_RIGHT_TO_LEFT:
- return (tiles[a].x == tiles[b].x)? (tiles[a].y < tiles[b].y): (tiles[a].x > tiles[b].x);
- case TILE_TOP_TO_BOTTOM:
- return (tiles[a].y == tiles[b].y)? (tiles[a].x < tiles[b].x): (tiles[a].y > tiles[b].y);
- case TILE_BOTTOM_TO_TOP:
- default:
- return (tiles[a].y == tiles[b].y)? (tiles[a].x < tiles[b].x): (tiles[a].y < tiles[b].y);
- }
- }
-
-protected:
- TileOrder order;
- int2 center;
- Tile *tiles;
+ public:
+ TileComparator(TileOrder order_, int2 center_, Tile *tiles_)
+ : order(order_), center(center_), tiles(tiles_)
+ {
+ }
+
+ bool operator()(int a, int b)
+ {
+ switch (order) {
+ case TILE_CENTER: {
+ float2 dist_a = make_float2(center.x - (tiles[a].x + tiles[a].w / 2),
+ center.y - (tiles[a].y + tiles[a].h / 2));
+ float2 dist_b = make_float2(center.x - (tiles[b].x + tiles[b].w / 2),
+ center.y - (tiles[b].y + tiles[b].h / 2));
+ return dot(dist_a, dist_a) < dot(dist_b, dist_b);
+ }
+ case TILE_LEFT_TO_RIGHT:
+ return (tiles[a].x == tiles[b].x) ? (tiles[a].y < tiles[b].y) : (tiles[a].x < tiles[b].x);
+ case TILE_RIGHT_TO_LEFT:
+ return (tiles[a].x == tiles[b].x) ? (tiles[a].y < tiles[b].y) : (tiles[a].x > tiles[b].x);
+ case TILE_TOP_TO_BOTTOM:
+ return (tiles[a].y == tiles[b].y) ? (tiles[a].x < tiles[b].x) : (tiles[a].y > tiles[b].y);
+ case TILE_BOTTOM_TO_TOP:
+ default:
+ return (tiles[a].y == tiles[b].y) ? (tiles[a].x < tiles[b].x) : (tiles[a].y < tiles[b].y);
+ }
+ }
+
+ protected:
+ TileOrder order;
+ int2 center;
+ Tile *tiles;
};
inline int2 hilbert_index_to_pos(int n, int d)
{
- int2 r, xy = make_int2(0, 0);
- for(int s = 1; s < n; s *= 2) {
- r.x = (d >> 1) & 1;
- r.y = (d ^ r.x) & 1;
- if(!r.y) {
- if(r.x) {
- xy = make_int2(s-1, s-1) - xy;
- }
- swap(xy.x, xy.y);
- }
- xy += r*make_int2(s, s);
- d >>= 2;
- }
- return xy;
+ int2 r, xy = make_int2(0, 0);
+ for (int s = 1; s < n; s *= 2) {
+ r.x = (d >> 1) & 1;
+ r.y = (d ^ r.x) & 1;
+ if (!r.y) {
+ if (r.x) {
+ xy = make_int2(s - 1, s - 1) - xy;
+ }
+ swap(xy.x, xy.y);
+ }
+ xy += r * make_int2(s, s);
+ d >>= 2;
+ }
+ return xy;
}
enum SpiralDirection {
- DIRECTION_UP,
- DIRECTION_LEFT,
- DIRECTION_DOWN,
- DIRECTION_RIGHT,
+ DIRECTION_UP,
+ DIRECTION_LEFT,
+ DIRECTION_DOWN,
+ DIRECTION_RIGHT,
};
-} /* namespace */
-
-TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_,
- bool preserve_tile_device_, bool background_, TileOrder tile_order_,
- int num_devices_, int pixel_size_)
+} /* namespace */
+
+TileManager::TileManager(bool progressive_,
+ int num_samples_,
+ int2 tile_size_,
+ int start_resolution_,
+ bool preserve_tile_device_,
+ bool background_,
+ TileOrder tile_order_,
+ int num_devices_,
+ int pixel_size_)
{
- progressive = progressive_;
- tile_size = tile_size_;
- tile_order = tile_order_;
- start_resolution = start_resolution_;
- pixel_size = pixel_size_;
- num_samples = num_samples_;
- num_devices = num_devices_;
- preserve_tile_device = preserve_tile_device_;
- background = background_;
- schedule_denoising = false;
-
- range_start_sample = 0;
- range_num_samples = -1;
-
- BufferParams buffer_params;
- reset(buffer_params, 0);
+ progressive = progressive_;
+ tile_size = tile_size_;
+ tile_order = tile_order_;
+ start_resolution = start_resolution_;
+ pixel_size = pixel_size_;
+ num_samples = num_samples_;
+ num_devices = num_devices_;
+ preserve_tile_device = preserve_tile_device_;
+ background = background_;
+ schedule_denoising = false;
+
+ range_start_sample = 0;
+ range_num_samples = -1;
+
+ BufferParams buffer_params;
+ reset(buffer_params, 0);
}
TileManager::~TileManager()
@@ -116,422 +120,422 @@ TileManager::~TileManager()
void TileManager::device_free()
{
- if(schedule_denoising || progressive) {
- for(int i = 0; i < state.tiles.size(); i++) {
- delete state.tiles[i].buffers;
- state.tiles[i].buffers = NULL;
- }
- }
-
- state.tiles.clear();
+ if (schedule_denoising || progressive) {
+ for (int i = 0; i < state.tiles.size(); i++) {
+ delete state.tiles[i].buffers;
+ state.tiles[i].buffers = NULL;
+ }
+ }
+
+ state.tiles.clear();
}
static int get_divider(int w, int h, int start_resolution)
{
- int divider = 1;
- if(start_resolution != INT_MAX) {
- while(w*h > start_resolution*start_resolution) {
- w = max(1, w/2);
- h = max(1, h/2);
-
- divider <<= 1;
- }
- }
- return divider;
+ int divider = 1;
+ if (start_resolution != INT_MAX) {
+ while (w * h > start_resolution * start_resolution) {
+ w = max(1, w / 2);
+ h = max(1, h / 2);
+
+ divider <<= 1;
+ }
+ }
+ return divider;
}
-void TileManager::reset(BufferParams& params_, int num_samples_)
+void TileManager::reset(BufferParams &params_, int num_samples_)
{
- params = params_;
-
- set_samples(num_samples_);
-
- state.buffer = BufferParams();
- state.sample = range_start_sample - 1;
- state.num_tiles = 0;
- state.num_samples = 0;
- state.resolution_divider = get_divider(params.width, params.height, start_resolution);
- state.render_tiles.clear();
- state.denoising_tiles.clear();
- device_free();
+ params = params_;
+
+ set_samples(num_samples_);
+
+ state.buffer = BufferParams();
+ state.sample = range_start_sample - 1;
+ state.num_tiles = 0;
+ state.num_samples = 0;
+ state.resolution_divider = get_divider(params.width, params.height, start_resolution);
+ state.render_tiles.clear();
+ state.denoising_tiles.clear();
+ device_free();
}
void TileManager::set_samples(int num_samples_)
{
- num_samples = num_samples_;
-
- /* No real progress indication is possible when using unlimited samples. */
- if(num_samples == INT_MAX) {
- state.total_pixel_samples = 0;
- }
- else {
- uint64_t pixel_samples = 0;
- /* While rendering in the viewport, the initial preview resolution is increased to the native resolution
- * before the actual rendering begins. Therefore, additional pixel samples will be rendered. */
- int divider = max(get_divider(params.width, params.height, start_resolution) / 2, pixel_size);
- while(divider > pixel_size) {
- int image_w = max(1, params.width/divider);
- int image_h = max(1, params.height/divider);
- pixel_samples += image_w * image_h;
- divider >>= 1;
- }
-
- int image_w = max(1, params.width/divider);
- int image_h = max(1, params.height/divider);
- state.total_pixel_samples = pixel_samples + (uint64_t)get_num_effective_samples() * image_w*image_h;
- if(schedule_denoising) {
- state.total_pixel_samples += params.width*params.height;
- }
- }
+ num_samples = num_samples_;
+
+ /* No real progress indication is possible when using unlimited samples. */
+ if (num_samples == INT_MAX) {
+ state.total_pixel_samples = 0;
+ }
+ else {
+ uint64_t pixel_samples = 0;
+ /* While rendering in the viewport, the initial preview resolution is increased to the native resolution
+ * before the actual rendering begins. Therefore, additional pixel samples will be rendered. */
+ int divider = max(get_divider(params.width, params.height, start_resolution) / 2, pixel_size);
+ while (divider > pixel_size) {
+ int image_w = max(1, params.width / divider);
+ int image_h = max(1, params.height / divider);
+ pixel_samples += image_w * image_h;
+ divider >>= 1;
+ }
+
+ int image_w = max(1, params.width / divider);
+ int image_h = max(1, params.height / divider);
+ state.total_pixel_samples = pixel_samples +
+ (uint64_t)get_num_effective_samples() * image_w * image_h;
+ if (schedule_denoising) {
+ state.total_pixel_samples += params.width * params.height;
+ }
+ }
}
/* If sliced is false, splits image into tiles and assigns equal amount of tiles to every render device.
* If sliced is true, slice image into as much pieces as how many devices are rendering this image. */
int TileManager::gen_tiles(bool sliced)
{
- int resolution = state.resolution_divider;
- int image_w = max(1, params.width/resolution);
- int image_h = max(1, params.height/resolution);
- int2 center = make_int2(image_w/2, image_h/2);
-
- int num_logical_devices = preserve_tile_device? num_devices: 1;
- int num = min(image_h, num_logical_devices);
- int slice_num = sliced? num: 1;
- int tile_w = (tile_size.x >= image_w) ? 1 : divide_up(image_w, tile_size.x);
-
- device_free();
- state.render_tiles.clear();
- state.denoising_tiles.clear();
- state.render_tiles.resize(num);
- state.denoising_tiles.resize(num);
- state.tile_stride = tile_w;
- vector<list<int> >::iterator tile_list;
- tile_list = state.render_tiles.begin();
-
- if(tile_order == TILE_HILBERT_SPIRAL) {
- assert(!sliced);
-
- int tile_h = (tile_size.y >= image_h) ? 1 : divide_up(image_h, tile_size.y);
- state.tiles.resize(tile_w*tile_h);
-
- /* Size of blocks in tiles, must be a power of 2 */
- const int hilbert_size = (max(tile_size.x, tile_size.y) <= 12)? 8: 4;
-
- int tiles_per_device = divide_up(tile_w * tile_h, num);
- int cur_device = 0, cur_tiles = 0;
-
- int2 block_size = tile_size * make_int2(hilbert_size, hilbert_size);
- /* Number of blocks to fill the image */
- int blocks_x = (block_size.x >= image_w)? 1: divide_up(image_w, block_size.x);
- int blocks_y = (block_size.y >= image_h)? 1: divide_up(image_h, block_size.y);
- int n = max(blocks_x, blocks_y) | 0x1; /* Side length of the spiral (must be odd) */
- /* Offset of spiral (to keep it centered) */
- int2 offset = make_int2((image_w - n*block_size.x)/2, (image_h - n*block_size.y)/2);
- offset = (offset / tile_size) * tile_size; /* Round to tile border. */
-
- int2 block = make_int2(0, 0); /* Current block */
- SpiralDirection prev_dir = DIRECTION_UP, dir = DIRECTION_UP;
- for(int i = 0;;) {
- /* Generate the tiles in the current block. */
- for(int hilbert_index = 0; hilbert_index < hilbert_size*hilbert_size; hilbert_index++) {
- int2 tile, hilbert_pos = hilbert_index_to_pos(hilbert_size, hilbert_index);
- /* Rotate block according to spiral direction. */
- if(prev_dir == DIRECTION_UP && dir == DIRECTION_UP) {
- tile = make_int2(hilbert_pos.y, hilbert_pos.x);
- }
- else if(dir == DIRECTION_LEFT || prev_dir == DIRECTION_LEFT) {
- tile = hilbert_pos;
- }
- else if(dir == DIRECTION_DOWN) {
- tile = make_int2(hilbert_size-1-hilbert_pos.y, hilbert_size-1-hilbert_pos.x);
- }
- else {
- tile = make_int2(hilbert_size-1-hilbert_pos.x, hilbert_size-1-hilbert_pos.y);
- }
-
- int2 pos = block*block_size + tile*tile_size + offset;
- /* Only add tiles which are in the image (tiles outside of the image can be generated since the spiral is always square). */
- if(pos.x >= 0 && pos.y >= 0 && pos.x < image_w && pos.y < image_h) {
- int w = min(tile_size.x, image_w - pos.x);
- int h = min(tile_size.y, image_h - pos.y);
- int2 ipos = pos / tile_size;
- int idx = ipos.y*tile_w + ipos.x;
- state.tiles[idx] = Tile(idx, pos.x, pos.y, w, h, cur_device, Tile::RENDER);
- tile_list->push_front(idx);
- cur_tiles++;
-
- if(cur_tiles == tiles_per_device) {
- tile_list++;
- cur_tiles = 0;
- cur_device++;
- }
- }
- }
-
- /* Stop as soon as the spiral has reached the center block. */
- if(block.x == (n-1)/2 && block.y == (n-1)/2)
- break;
-
- /* Advance to next block. */
- prev_dir = dir;
- switch(dir) {
- case DIRECTION_UP:
- block.y++;
- if(block.y == (n-i-1)) {
- dir = DIRECTION_LEFT;
- }
- break;
- case DIRECTION_LEFT:
- block.x++;
- if(block.x == (n-i-1)) {
- dir = DIRECTION_DOWN;
- }
- break;
- case DIRECTION_DOWN:
- block.y--;
- if(block.y == i) {
- dir = DIRECTION_RIGHT;
- }
- break;
- case DIRECTION_RIGHT:
- block.x--;
- if(block.x == i+1) {
- dir = DIRECTION_UP;
- i++;
- }
- break;
- }
- }
- return tile_w*tile_h;
- }
-
- int idx = 0;
- for(int slice = 0; slice < slice_num; slice++) {
- int slice_y = (image_h/slice_num)*slice;
- int slice_h = (slice == slice_num-1)? image_h - slice*(image_h/slice_num): image_h/slice_num;
-
- int tile_h = (tile_size.y >= slice_h)? 1: divide_up(slice_h, tile_size.y);
-
- int tiles_per_device = divide_up(tile_w * tile_h, num);
- int cur_device = 0, cur_tiles = 0;
-
- for(int tile_y = 0; tile_y < tile_h; tile_y++) {
- for(int tile_x = 0; tile_x < tile_w; tile_x++, idx++) {
- int x = tile_x * tile_size.x;
- int y = tile_y * tile_size.y;
- int w = (tile_x == tile_w-1)? image_w - x: tile_size.x;
- int h = (tile_y == tile_h-1)? slice_h - y: tile_size.y;
-
- state.tiles.push_back(Tile(idx, x, y + slice_y, w, h, sliced? slice: cur_device, Tile::RENDER));
- tile_list->push_back(idx);
-
- if(!sliced) {
- cur_tiles++;
-
- if(cur_tiles == tiles_per_device) {
- /* Tiles are already generated in Bottom-to-Top order, so no sort is necessary in that case. */
- if(tile_order != TILE_BOTTOM_TO_TOP) {
- tile_list->sort(TileComparator(tile_order, center, &state.tiles[0]));
- }
- tile_list++;
- cur_tiles = 0;
- cur_device++;
- }
- }
- }
- }
- if(sliced) {
- tile_list++;
- }
- }
-
- return idx;
+ int resolution = state.resolution_divider;
+ int image_w = max(1, params.width / resolution);
+ int image_h = max(1, params.height / resolution);
+ int2 center = make_int2(image_w / 2, image_h / 2);
+
+ int num_logical_devices = preserve_tile_device ? num_devices : 1;
+ int num = min(image_h, num_logical_devices);
+ int slice_num = sliced ? num : 1;
+ int tile_w = (tile_size.x >= image_w) ? 1 : divide_up(image_w, tile_size.x);
+
+ device_free();
+ state.render_tiles.clear();
+ state.denoising_tiles.clear();
+ state.render_tiles.resize(num);
+ state.denoising_tiles.resize(num);
+ state.tile_stride = tile_w;
+ vector<list<int>>::iterator tile_list;
+ tile_list = state.render_tiles.begin();
+
+ if (tile_order == TILE_HILBERT_SPIRAL) {
+ assert(!sliced);
+
+ int tile_h = (tile_size.y >= image_h) ? 1 : divide_up(image_h, tile_size.y);
+ state.tiles.resize(tile_w * tile_h);
+
+ /* Size of blocks in tiles, must be a power of 2 */
+ const int hilbert_size = (max(tile_size.x, tile_size.y) <= 12) ? 8 : 4;
+
+ int tiles_per_device = divide_up(tile_w * tile_h, num);
+ int cur_device = 0, cur_tiles = 0;
+
+ int2 block_size = tile_size * make_int2(hilbert_size, hilbert_size);
+ /* Number of blocks to fill the image */
+ int blocks_x = (block_size.x >= image_w) ? 1 : divide_up(image_w, block_size.x);
+ int blocks_y = (block_size.y >= image_h) ? 1 : divide_up(image_h, block_size.y);
+ int n = max(blocks_x, blocks_y) | 0x1; /* Side length of the spiral (must be odd) */
+ /* Offset of spiral (to keep it centered) */
+ int2 offset = make_int2((image_w - n * block_size.x) / 2, (image_h - n * block_size.y) / 2);
+ offset = (offset / tile_size) * tile_size; /* Round to tile border. */
+
+ int2 block = make_int2(0, 0); /* Current block */
+ SpiralDirection prev_dir = DIRECTION_UP, dir = DIRECTION_UP;
+ for (int i = 0;;) {
+ /* Generate the tiles in the current block. */
+ for (int hilbert_index = 0; hilbert_index < hilbert_size * hilbert_size; hilbert_index++) {
+ int2 tile, hilbert_pos = hilbert_index_to_pos(hilbert_size, hilbert_index);
+ /* Rotate block according to spiral direction. */
+ if (prev_dir == DIRECTION_UP && dir == DIRECTION_UP) {
+ tile = make_int2(hilbert_pos.y, hilbert_pos.x);
+ }
+ else if (dir == DIRECTION_LEFT || prev_dir == DIRECTION_LEFT) {
+ tile = hilbert_pos;
+ }
+ else if (dir == DIRECTION_DOWN) {
+ tile = make_int2(hilbert_size - 1 - hilbert_pos.y, hilbert_size - 1 - hilbert_pos.x);
+ }
+ else {
+ tile = make_int2(hilbert_size - 1 - hilbert_pos.x, hilbert_size - 1 - hilbert_pos.y);
+ }
+
+ int2 pos = block * block_size + tile * tile_size + offset;
+ /* Only add tiles which are in the image (tiles outside of the image can be generated since the spiral is always square). */
+ if (pos.x >= 0 && pos.y >= 0 && pos.x < image_w && pos.y < image_h) {
+ int w = min(tile_size.x, image_w - pos.x);
+ int h = min(tile_size.y, image_h - pos.y);
+ int2 ipos = pos / tile_size;
+ int idx = ipos.y * tile_w + ipos.x;
+ state.tiles[idx] = Tile(idx, pos.x, pos.y, w, h, cur_device, Tile::RENDER);
+ tile_list->push_front(idx);
+ cur_tiles++;
+
+ if (cur_tiles == tiles_per_device) {
+ tile_list++;
+ cur_tiles = 0;
+ cur_device++;
+ }
+ }
+ }
+
+ /* Stop as soon as the spiral has reached the center block. */
+ if (block.x == (n - 1) / 2 && block.y == (n - 1) / 2)
+ break;
+
+ /* Advance to next block. */
+ prev_dir = dir;
+ switch (dir) {
+ case DIRECTION_UP:
+ block.y++;
+ if (block.y == (n - i - 1)) {
+ dir = DIRECTION_LEFT;
+ }
+ break;
+ case DIRECTION_LEFT:
+ block.x++;
+ if (block.x == (n - i - 1)) {
+ dir = DIRECTION_DOWN;
+ }
+ break;
+ case DIRECTION_DOWN:
+ block.y--;
+ if (block.y == i) {
+ dir = DIRECTION_RIGHT;
+ }
+ break;
+ case DIRECTION_RIGHT:
+ block.x--;
+ if (block.x == i + 1) {
+ dir = DIRECTION_UP;
+ i++;
+ }
+ break;
+ }
+ }
+ return tile_w * tile_h;
+ }
+
+ int idx = 0;
+ for (int slice = 0; slice < slice_num; slice++) {
+ int slice_y = (image_h / slice_num) * slice;
+ int slice_h = (slice == slice_num - 1) ? image_h - slice * (image_h / slice_num) :
+ image_h / slice_num;
+
+ int tile_h = (tile_size.y >= slice_h) ? 1 : divide_up(slice_h, tile_size.y);
+
+ int tiles_per_device = divide_up(tile_w * tile_h, num);
+ int cur_device = 0, cur_tiles = 0;
+
+ for (int tile_y = 0; tile_y < tile_h; tile_y++) {
+ for (int tile_x = 0; tile_x < tile_w; tile_x++, idx++) {
+ int x = tile_x * tile_size.x;
+ int y = tile_y * tile_size.y;
+ int w = (tile_x == tile_w - 1) ? image_w - x : tile_size.x;
+ int h = (tile_y == tile_h - 1) ? slice_h - y : tile_size.y;
+
+ state.tiles.push_back(
+ Tile(idx, x, y + slice_y, w, h, sliced ? slice : cur_device, Tile::RENDER));
+ tile_list->push_back(idx);
+
+ if (!sliced) {
+ cur_tiles++;
+
+ if (cur_tiles == tiles_per_device) {
+ /* Tiles are already generated in Bottom-to-Top order, so no sort is necessary in that case. */
+ if (tile_order != TILE_BOTTOM_TO_TOP) {
+ tile_list->sort(TileComparator(tile_order, center, &state.tiles[0]));
+ }
+ tile_list++;
+ cur_tiles = 0;
+ cur_device++;
+ }
+ }
+ }
+ }
+ if (sliced) {
+ tile_list++;
+ }
+ }
+
+ return idx;
}
void TileManager::gen_render_tiles()
{
- /* Regenerate just the render tiles for progressive render. */
- foreach(Tile& tile, state.tiles) {
- state.render_tiles[tile.device].push_back(tile.index);
- }
+ /* Regenerate just the render tiles for progressive render. */
+ foreach (Tile &tile, state.tiles) {
+ state.render_tiles[tile.device].push_back(tile.index);
+ }
}
void TileManager::set_tiles()
{
- int resolution = state.resolution_divider;
- int image_w = max(1, params.width/resolution);
- int image_h = max(1, params.height/resolution);
+ int resolution = state.resolution_divider;
+ int image_w = max(1, params.width / resolution);
+ int image_h = max(1, params.height / resolution);
- state.num_tiles = gen_tiles(!background);
+ state.num_tiles = gen_tiles(!background);
- state.buffer.width = image_w;
- state.buffer.height = image_h;
+ state.buffer.width = image_w;
+ state.buffer.height = image_h;
- state.buffer.full_x = params.full_x/resolution;
- state.buffer.full_y = params.full_y/resolution;
- state.buffer.full_width = max(1, params.full_width/resolution);
- state.buffer.full_height = max(1, params.full_height/resolution);
+ state.buffer.full_x = params.full_x / resolution;
+ state.buffer.full_y = params.full_y / resolution;
+ state.buffer.full_width = max(1, params.full_width / resolution);
+ state.buffer.full_height = max(1, params.full_height / resolution);
}
int TileManager::get_neighbor_index(int index, int neighbor)
{
- static const int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1, 0}, dy[] = {-1, -1, -1, 0, 0, 1, 1, 1, 0};
+ static const int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1, 0}, dy[] = {-1, -1, -1, 0, 0, 1, 1, 1, 0};
- int resolution = state.resolution_divider;
- int image_w = max(1, params.width/resolution);
- int image_h = max(1, params.height/resolution);
- int tile_w = (tile_size.x >= image_w)? 1: divide_up(image_w, tile_size.x);
- int tile_h = (tile_size.y >= image_h)? 1: divide_up(image_h, tile_size.y);
+ int resolution = state.resolution_divider;
+ int image_w = max(1, params.width / resolution);
+ int image_h = max(1, params.height / resolution);
+ int tile_w = (tile_size.x >= image_w) ? 1 : divide_up(image_w, tile_size.x);
+ int tile_h = (tile_size.y >= image_h) ? 1 : divide_up(image_h, tile_size.y);
- int nx = state.tiles[index].x/tile_size.x + dx[neighbor], ny = state.tiles[index].y/tile_size.y + dy[neighbor];
- if(nx < 0 || ny < 0 || nx >= tile_w || ny >= tile_h)
- return -1;
+ int nx = state.tiles[index].x / tile_size.x + dx[neighbor],
+ ny = state.tiles[index].y / tile_size.y + dy[neighbor];
+ if (nx < 0 || ny < 0 || nx >= tile_w || ny >= tile_h)
+ return -1;
- return ny*state.tile_stride + nx;
+ return ny * state.tile_stride + nx;
}
/* Checks whether all neighbors of a tile (as well as the tile itself) are at least at state min_state. */
bool TileManager::check_neighbor_state(int index, Tile::State min_state)
{
- if(index < 0 || state.tiles[index].state < min_state) {
- return false;
- }
- for(int neighbor = 0; neighbor < 9; neighbor++) {
- int nindex = get_neighbor_index(index, neighbor);
- /* Out-of-bounds tiles don't matter. */
- if(nindex >= 0 && state.tiles[nindex].state < min_state) {
- return false;
- }
- }
-
- return true;
+ if (index < 0 || state.tiles[index].state < min_state) {
+ return false;
+ }
+ for (int neighbor = 0; neighbor < 9; neighbor++) {
+ int nindex = get_neighbor_index(index, neighbor);
+ /* Out-of-bounds tiles don't matter. */
+ if (nindex >= 0 && state.tiles[nindex].state < min_state) {
+ return false;
+ }
+ }
+
+ return true;
}
/* Returns whether the tile should be written (and freed if no denoising is used) instead of updating. */
bool TileManager::finish_tile(int index, bool &delete_tile)
{
- delete_tile = false;
-
- if(progressive) {
- return true;
- }
-
- switch(state.tiles[index].state) {
- case Tile::RENDER:
- {
- if(!schedule_denoising) {
- state.tiles[index].state = Tile::DONE;
- delete_tile = true;
- return true;
- }
- state.tiles[index].state = Tile::RENDERED;
- /* For each neighbor and the tile itself, check whether all of its neighbors have been rendered. If yes, it can be denoised. */
- for(int neighbor = 0; neighbor < 9; neighbor++) {
- int nindex = get_neighbor_index(index, neighbor);
- if(check_neighbor_state(nindex, Tile::RENDERED)) {
- state.tiles[nindex].state = Tile::DENOISE;
- state.denoising_tiles[state.tiles[nindex].device].push_back(nindex);
- }
- }
- return false;
- }
- case Tile::DENOISE:
- {
- state.tiles[index].state = Tile::DENOISED;
- /* For each neighbor and the tile itself, check whether all of its neighbors have been denoised. If yes, it can be freed. */
- for(int neighbor = 0; neighbor < 9; neighbor++) {
- int nindex = get_neighbor_index(index, neighbor);
- if(check_neighbor_state(nindex, Tile::DENOISED)) {
- state.tiles[nindex].state = Tile::DONE;
- /* It can happen that the tile just finished denoising and already can be freed here.
- * However, in that case it still has to be written before deleting, so we can't delete it yet. */
- if(neighbor == 8) {
- delete_tile = true;
- }
- else {
- delete state.tiles[nindex].buffers;
- state.tiles[nindex].buffers = NULL;
- }
- }
- }
- return true;
- }
- default:
- assert(false);
- return true;
- }
+ delete_tile = false;
+
+ if (progressive) {
+ return true;
+ }
+
+ switch (state.tiles[index].state) {
+ case Tile::RENDER: {
+ if (!schedule_denoising) {
+ state.tiles[index].state = Tile::DONE;
+ delete_tile = true;
+ return true;
+ }
+ state.tiles[index].state = Tile::RENDERED;
+ /* For each neighbor and the tile itself, check whether all of its neighbors have been rendered. If yes, it can be denoised. */
+ for (int neighbor = 0; neighbor < 9; neighbor++) {
+ int nindex = get_neighbor_index(index, neighbor);
+ if (check_neighbor_state(nindex, Tile::RENDERED)) {
+ state.tiles[nindex].state = Tile::DENOISE;
+ state.denoising_tiles[state.tiles[nindex].device].push_back(nindex);
+ }
+ }
+ return false;
+ }
+ case Tile::DENOISE: {
+ state.tiles[index].state = Tile::DENOISED;
+ /* For each neighbor and the tile itself, check whether all of its neighbors have been denoised. If yes, it can be freed. */
+ for (int neighbor = 0; neighbor < 9; neighbor++) {
+ int nindex = get_neighbor_index(index, neighbor);
+ if (check_neighbor_state(nindex, Tile::DENOISED)) {
+ state.tiles[nindex].state = Tile::DONE;
+ /* It can happen that the tile just finished denoising and already can be freed here.
+ * However, in that case it still has to be written before deleting, so we can't delete it yet. */
+ if (neighbor == 8) {
+ delete_tile = true;
+ }
+ else {
+ delete state.tiles[nindex].buffers;
+ state.tiles[nindex].buffers = NULL;
+ }
+ }
+ }
+ return true;
+ }
+ default:
+ assert(false);
+ return true;
+ }
}
-bool TileManager::next_tile(Tile* &tile, int device)
+bool TileManager::next_tile(Tile *&tile, int device)
{
- int logical_device = preserve_tile_device? device: 0;
+ int logical_device = preserve_tile_device ? device : 0;
- if(logical_device >= state.render_tiles.size())
- return false;
+ if (logical_device >= state.render_tiles.size())
+ return false;
- if(!state.denoising_tiles[logical_device].empty()) {
- int idx = state.denoising_tiles[logical_device].front();
- state.denoising_tiles[logical_device].pop_front();
- tile = &state.tiles[idx];
- return true;
- }
+ if (!state.denoising_tiles[logical_device].empty()) {
+ int idx = state.denoising_tiles[logical_device].front();
+ state.denoising_tiles[logical_device].pop_front();
+ tile = &state.tiles[idx];
+ return true;
+ }
- if(state.render_tiles[logical_device].empty())
- return false;
+ if (state.render_tiles[logical_device].empty())
+ return false;
- int idx = state.render_tiles[logical_device].front();
- state.render_tiles[logical_device].pop_front();
- tile = &state.tiles[idx];
- return true;
+ int idx = state.render_tiles[logical_device].front();
+ state.render_tiles[logical_device].pop_front();
+ tile = &state.tiles[idx];
+ return true;
}
bool TileManager::done()
{
- int end_sample = (range_num_samples == -1)
- ? num_samples
- : range_start_sample + range_num_samples;
- return (state.resolution_divider == pixel_size) &&
- (state.sample+state.num_samples >= end_sample);
+ int end_sample = (range_num_samples == -1) ? num_samples :
+ range_start_sample + range_num_samples;
+ return (state.resolution_divider == pixel_size) &&
+ (state.sample + state.num_samples >= end_sample);
}
bool TileManager::next()
{
- if(done())
- return false;
-
- if(progressive && state.resolution_divider > pixel_size) {
- state.sample = 0;
- state.resolution_divider = max(state.resolution_divider/2, pixel_size);
- state.num_samples = 1;
- set_tiles();
- }
- else {
- state.sample++;
-
- if(progressive)
- state.num_samples = 1;
- else if(range_num_samples == -1)
- state.num_samples = num_samples;
- else
- state.num_samples = range_num_samples;
-
- state.resolution_divider = pixel_size;
-
- if(state.sample == range_start_sample) {
- set_tiles();
- }
- else {
- gen_render_tiles();
- }
- }
-
- return true;
+ if (done())
+ return false;
+
+ if (progressive && state.resolution_divider > pixel_size) {
+ state.sample = 0;
+ state.resolution_divider = max(state.resolution_divider / 2, pixel_size);
+ state.num_samples = 1;
+ set_tiles();
+ }
+ else {
+ state.sample++;
+
+ if (progressive)
+ state.num_samples = 1;
+ else if (range_num_samples == -1)
+ state.num_samples = num_samples;
+ else
+ state.num_samples = range_num_samples;
+
+ state.resolution_divider = pixel_size;
+
+ if (state.sample == range_start_sample) {
+ set_tiles();
+ }
+ else {
+ gen_render_tiles();
+ }
+ }
+
+ return true;
}
int TileManager::get_num_effective_samples()
{
- return (range_num_samples == -1) ? num_samples
- : range_num_samples;
+ return (range_num_samples == -1) ? num_samples : range_num_samples;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 2835c793073..017c1af0ead 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -27,131 +27,144 @@ CCL_NAMESPACE_BEGIN
/* Tile */
class Tile {
-public:
- int index;
- int x, y, w, h;
- int device;
- /* RENDER: The tile has to be rendered.
- * RENDERED: The tile has been rendered, but can't be denoised yet (waiting for neighbors).
- * DENOISE: The tile can be denoised now.
- * DENOISED: The tile has been denoised, but can't be freed yet (waiting for neighbors).
- * DONE: The tile is finished and has been freed. */
- typedef enum { RENDER = 0, RENDERED, DENOISE, DENOISED, DONE } State;
- State state;
- RenderBuffers *buffers;
-
- Tile()
- {}
-
- Tile(int index_, int x_, int y_, int w_, int h_, int device_, State state_ = RENDER)
- : index(index_), x(x_), y(y_), w(w_), h(h_), device(device_), state(state_), buffers(NULL) {}
+ public:
+ int index;
+ int x, y, w, h;
+ int device;
+ /* RENDER: The tile has to be rendered.
+ * RENDERED: The tile has been rendered, but can't be denoised yet (waiting for neighbors).
+ * DENOISE: The tile can be denoised now.
+ * DENOISED: The tile has been denoised, but can't be freed yet (waiting for neighbors).
+ * DONE: The tile is finished and has been freed. */
+ typedef enum { RENDER = 0, RENDERED, DENOISE, DENOISED, DONE } State;
+ State state;
+ RenderBuffers *buffers;
+
+ Tile()
+ {
+ }
+
+ Tile(int index_, int x_, int y_, int w_, int h_, int device_, State state_ = RENDER)
+ : index(index_), x(x_), y(y_), w(w_), h(h_), device(device_), state(state_), buffers(NULL)
+ {
+ }
};
/* Tile order */
/* Note: this should match enum_tile_order in properties.py */
enum TileOrder {
- TILE_CENTER = 0,
- TILE_RIGHT_TO_LEFT = 1,
- TILE_LEFT_TO_RIGHT = 2,
- TILE_TOP_TO_BOTTOM = 3,
- TILE_BOTTOM_TO_TOP = 4,
- TILE_HILBERT_SPIRAL = 5,
+ TILE_CENTER = 0,
+ TILE_RIGHT_TO_LEFT = 1,
+ TILE_LEFT_TO_RIGHT = 2,
+ TILE_TOP_TO_BOTTOM = 3,
+ TILE_BOTTOM_TO_TOP = 4,
+ TILE_HILBERT_SPIRAL = 5,
};
/* Tile Manager */
class TileManager {
-public:
- BufferParams params;
-
- struct State {
- vector<Tile> tiles;
- int tile_stride;
- BufferParams buffer;
- int sample;
- int num_samples;
- int resolution_divider;
- int num_tiles;
-
- /* Total samples over all pixels: Generally num_samples*num_pixels,
- * but can be higher due to the initial resolution division for previews. */
- uint64_t total_pixel_samples;
-
- /* These lists contain the indices of the tiles to be rendered/denoised and are used
- * when acquiring a new tile for the device.
- * Each list in each vector is for one logical device. */
- vector<list<int> > render_tiles;
- vector<list<int> > denoising_tiles;
- } state;
-
- int num_samples;
-
- TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution,
- bool preserve_tile_device, bool background, TileOrder tile_order, int num_devices = 1, int pixel_size = 1);
- ~TileManager();
-
- void device_free();
- void reset(BufferParams& params, int num_samples);
- void set_samples(int num_samples);
- bool next();
- bool next_tile(Tile* &tile, int device = 0);
- bool finish_tile(int index, bool& delete_tile);
- bool done();
-
- void set_tile_order(TileOrder tile_order_) { tile_order = tile_order_; }
-
- /* ** Sample range rendering. ** */
-
- /* Start sample in the range. */
- int range_start_sample;
-
- /* Number to samples in the rendering range. */
- int range_num_samples;
-
- /* Get number of actual samples to render. */
- int get_num_effective_samples();
-
- /* Schedule tiles for denoising after they've been rendered. */
- bool schedule_denoising;
-protected:
-
- void set_tiles();
-
- bool progressive;
- int2 tile_size;
- TileOrder tile_order;
- int start_resolution;
- int pixel_size;
- int num_devices;
-
- /* in some cases it is important that the same tile will be returned for the same
- * device it was originally generated for (i.e. viewport rendering when buffer is
- * allocating once for tile and then always used by it)
- *
- * in other cases any tile could be handled by any device (i.e. final rendering
- * without progressive refine)
- */
- bool preserve_tile_device;
-
- /* for background render tiles should exactly match render parts generated from
- * blender side, which means image first gets split into tiles and then tiles are
- * assigning to render devices
- *
- * however viewport rendering expects tiles to be allocated in a special way,
- * meaning image is being sliced horizontally first and every device handles
- * it's own slice
- */
- bool background;
-
- /* Generate tile list, return number of tiles. */
- int gen_tiles(bool sliced);
- void gen_render_tiles();
-
- int get_neighbor_index(int index, int neighbor);
- bool check_neighbor_state(int index, Tile::State state);
+ public:
+ BufferParams params;
+
+ struct State {
+ vector<Tile> tiles;
+ int tile_stride;
+ BufferParams buffer;
+ int sample;
+ int num_samples;
+ int resolution_divider;
+ int num_tiles;
+
+ /* Total samples over all pixels: Generally num_samples*num_pixels,
+ * but can be higher due to the initial resolution division for previews. */
+ uint64_t total_pixel_samples;
+
+ /* These lists contain the indices of the tiles to be rendered/denoised and are used
+ * when acquiring a new tile for the device.
+ * Each list in each vector is for one logical device. */
+ vector<list<int>> render_tiles;
+ vector<list<int>> denoising_tiles;
+ } state;
+
+ int num_samples;
+
+ TileManager(bool progressive,
+ int num_samples,
+ int2 tile_size,
+ int start_resolution,
+ bool preserve_tile_device,
+ bool background,
+ TileOrder tile_order,
+ int num_devices = 1,
+ int pixel_size = 1);
+ ~TileManager();
+
+ void device_free();
+ void reset(BufferParams &params, int num_samples);
+ void set_samples(int num_samples);
+ bool next();
+ bool next_tile(Tile *&tile, int device = 0);
+ bool finish_tile(int index, bool &delete_tile);
+ bool done();
+
+ void set_tile_order(TileOrder tile_order_)
+ {
+ tile_order = tile_order_;
+ }
+
+ /* ** Sample range rendering. ** */
+
+ /* Start sample in the range. */
+ int range_start_sample;
+
+ /* Number to samples in the rendering range. */
+ int range_num_samples;
+
+ /* Get number of actual samples to render. */
+ int get_num_effective_samples();
+
+ /* Schedule tiles for denoising after they've been rendered. */
+ bool schedule_denoising;
+
+ protected:
+ void set_tiles();
+
+ bool progressive;
+ int2 tile_size;
+ TileOrder tile_order;
+ int start_resolution;
+ int pixel_size;
+ int num_devices;
+
+ /* in some cases it is important that the same tile will be returned for the same
+ * device it was originally generated for (i.e. viewport rendering when buffer is
+ * allocating once for tile and then always used by it)
+ *
+ * in other cases any tile could be handled by any device (i.e. final rendering
+ * without progressive refine)
+ */
+ bool preserve_tile_device;
+
+ /* for background render tiles should exactly match render parts generated from
+ * blender side, which means image first gets split into tiles and then tiles are
+ * assigning to render devices
+ *
+ * however viewport rendering expects tiles to be allocated in a special way,
+ * meaning image is being sliced horizontally first and every device handles
+ * it's own slice
+ */
+ bool background;
+
+ /* Generate tile list, return number of tiles. */
+ int gen_tiles(bool sliced);
+ void gen_render_tiles();
+
+ int get_neighbor_index(int index, int neighbor);
+ bool check_neighbor_state(int index, Tile::State state);
};
CCL_NAMESPACE_END
-#endif /* __TILE_H__ */
+#endif /* __TILE_H__ */
diff --git a/intern/cycles/subd/CMakeLists.txt b/intern/cycles/subd/CMakeLists.txt
index 9669bdede7e..f5ceaa0436d 100644
--- a/intern/cycles/subd/CMakeLists.txt
+++ b/intern/cycles/subd/CMakeLists.txt
@@ -1,6 +1,6 @@
set(INC
- ..
+ ..
)
set(INC_SYS
@@ -8,17 +8,17 @@ set(INC_SYS
)
set(SRC
- subd_dice.cpp
- subd_patch.cpp
- subd_split.cpp
- subd_patch_table.cpp
+ subd_dice.cpp
+ subd_patch.cpp
+ subd_split.cpp
+ subd_patch_table.cpp
)
set(SRC_HEADERS
- subd_dice.h
- subd_patch.h
- subd_patch_table.h
- subd_split.h
+ subd_dice.h
+ subd_patch.h
+ subd_patch_table.h
+ subd_split.h
)
set(LIB
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index c5ac54cfcc8..6b062ecfea2 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -24,327 +24,335 @@ CCL_NAMESPACE_BEGIN
/* EdgeDice Base */
-EdgeDice::EdgeDice(const SubdParams& params_)
-: params(params_)
+EdgeDice::EdgeDice(const SubdParams &params_) : params(params_)
{
- mesh_P = NULL;
- mesh_N = NULL;
- vert_offset = 0;
+ mesh_P = NULL;
+ mesh_N = NULL;
+ vert_offset = 0;
- params.mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
+ params.mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
- if(params.ptex) {
- params.mesh->attributes.add(ATTR_STD_PTEX_UV);
- params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
- }
+ if (params.ptex) {
+ params.mesh->attributes.add(ATTR_STD_PTEX_UV);
+ params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
+ }
}
void EdgeDice::reserve(int num_verts)
{
- Mesh *mesh = params.mesh;
+ Mesh *mesh = params.mesh;
- vert_offset = mesh->verts.size();
- tri_offset = mesh->num_triangles();
+ vert_offset = mesh->verts.size();
+ tri_offset = mesh->num_triangles();
- /* todo: optimize so we can reserve in advance, this is like push_back_slow() */
- if(vert_offset + num_verts > mesh->verts.capacity()) {
- mesh->reserve_mesh(size_t((vert_offset + num_verts) * 1.2), mesh->num_triangles());
- }
+ /* todo: optimize so we can reserve in advance, this is like push_back_slow() */
+ if (vert_offset + num_verts > mesh->verts.capacity()) {
+ mesh->reserve_mesh(size_t((vert_offset + num_verts) * 1.2), mesh->num_triangles());
+ }
- mesh->resize_mesh(vert_offset + num_verts, tri_offset);
+ mesh->resize_mesh(vert_offset + num_verts, tri_offset);
- Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
+ Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
- mesh_P = mesh->verts.data();
- mesh_N = attr_vN->data_float3();
+ mesh_P = mesh->verts.data();
+ mesh_N = attr_vN->data_float3();
}
int EdgeDice::add_vert(Patch *patch, float2 uv)
{
- float3 P, N;
+ float3 P, N;
- patch->eval(&P, NULL, NULL, &N, uv.x, uv.y);
+ patch->eval(&P, NULL, NULL, &N, uv.x, uv.y);
- assert(vert_offset < params.mesh->verts.size());
+ assert(vert_offset < params.mesh->verts.size());
- mesh_P[vert_offset] = P;
- mesh_N[vert_offset] = N;
- params.mesh->vert_patch_uv[vert_offset] = make_float2(uv.x, uv.y);
+ mesh_P[vert_offset] = P;
+ mesh_N[vert_offset] = N;
+ params.mesh->vert_patch_uv[vert_offset] = make_float2(uv.x, uv.y);
- if(params.ptex) {
- Attribute *attr_ptex_uv = params.mesh->attributes.add(ATTR_STD_PTEX_UV);
- params.mesh->attributes.resize();
+ if (params.ptex) {
+ Attribute *attr_ptex_uv = params.mesh->attributes.add(ATTR_STD_PTEX_UV);
+ params.mesh->attributes.resize();
- float3 *ptex_uv = attr_ptex_uv->data_float3();
- ptex_uv[vert_offset] = make_float3(uv.x, uv.y, 0.0f);
- }
+ float3 *ptex_uv = attr_ptex_uv->data_float3();
+ ptex_uv[vert_offset] = make_float3(uv.x, uv.y, 0.0f);
+ }
- params.mesh->num_subd_verts++;
+ params.mesh->num_subd_verts++;
- return vert_offset++;
+ return vert_offset++;
}
void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2)
{
- Mesh *mesh = params.mesh;
+ Mesh *mesh = params.mesh;
- /* todo: optimize so we can reserve in advance, this is like push_back_slow() */
- if(mesh->triangles.size() == mesh->triangles.capacity())
- mesh->reserve_mesh(mesh->verts.size(), size_t(max(mesh->num_triangles() + 1, 1) * 1.2));
+ /* todo: optimize so we can reserve in advance, this is like push_back_slow() */
+ if (mesh->triangles.size() == mesh->triangles.capacity())
+ mesh->reserve_mesh(mesh->verts.size(), size_t(max(mesh->num_triangles() + 1, 1) * 1.2));
- mesh->add_triangle(v0, v1, v2, patch->shader, true);
- params.mesh->triangle_patch[params.mesh->num_triangles()-1] = patch->patch_index;
+ mesh->add_triangle(v0, v1, v2, patch->shader, true);
+ params.mesh->triangle_patch[params.mesh->num_triangles() - 1] = patch->patch_index;
- if(params.ptex) {
- Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
- params.mesh->attributes.resize();
+ if (params.ptex) {
+ Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
+ params.mesh->attributes.resize();
- float *ptex_face_id = attr_ptex_face_id->data_float();
- ptex_face_id[tri_offset] = (float)patch->ptex_face_id();
- }
+ float *ptex_face_id = attr_ptex_face_id->data_float();
+ ptex_face_id[tri_offset] = (float)patch->ptex_face_id();
+ }
- tri_offset++;
+ tri_offset++;
}
-void EdgeDice::stitch_triangles(Patch *patch, vector<int>& outer, vector<int>& inner)
+void EdgeDice::stitch_triangles(Patch *patch, vector<int> &outer, vector<int> &inner)
{
- if(inner.size() == 0 || outer.size() == 0)
- return; // XXX avoid crashes for Mu or Mv == 1, missing polygons
-
- /* stitch together two arrays of verts with triangles. at each step,
- * we compare using the next verts on both sides, to find the split
- * direction with the smallest diagonal, and use that in order to keep
- * the triangle shape reasonable. */
- for(size_t i = 0, j = 0; i+1 < inner.size() || j+1 < outer.size();) {
- int v0, v1, v2;
-
- v0 = inner[i];
- v1 = outer[j];
-
- if(j+1 == outer.size()) {
- v2 = inner[++i];
- }
- else if(i+1 == inner.size()) {
- v2 = outer[++j];
- }
- else {
- /* length of diagonals */
- float len1 = len_squared(mesh_P[inner[i]] - mesh_P[outer[j+1]]);
- float len2 = len_squared(mesh_P[outer[j]] - mesh_P[inner[i+1]]);
-
- /* use smallest diagonal */
- if(len1 < len2)
- v2 = outer[++j];
- else
- v2 = inner[++i];
- }
-
- add_triangle(patch, v0, v1, v2);
- }
+ if (inner.size() == 0 || outer.size() == 0)
+ return; // XXX avoid crashes for Mu or Mv == 1, missing polygons
+
+ /* stitch together two arrays of verts with triangles. at each step,
+ * we compare using the next verts on both sides, to find the split
+ * direction with the smallest diagonal, and use that in order to keep
+ * the triangle shape reasonable. */
+ for (size_t i = 0, j = 0; i + 1 < inner.size() || j + 1 < outer.size();) {
+ int v0, v1, v2;
+
+ v0 = inner[i];
+ v1 = outer[j];
+
+ if (j + 1 == outer.size()) {
+ v2 = inner[++i];
+ }
+ else if (i + 1 == inner.size()) {
+ v2 = outer[++j];
+ }
+ else {
+ /* length of diagonals */
+ float len1 = len_squared(mesh_P[inner[i]] - mesh_P[outer[j + 1]]);
+ float len2 = len_squared(mesh_P[outer[j]] - mesh_P[inner[i + 1]]);
+
+ /* use smallest diagonal */
+ if (len1 < len2)
+ v2 = outer[++j];
+ else
+ v2 = inner[++i];
+ }
+
+ add_triangle(patch, v0, v1, v2);
+ }
}
/* QuadDice */
-QuadDice::QuadDice(const SubdParams& params_)
-: EdgeDice(params_)
+QuadDice::QuadDice(const SubdParams &params_) : EdgeDice(params_)
{
}
-void QuadDice::reserve(EdgeFactors& ef, int Mu, int Mv)
+void QuadDice::reserve(EdgeFactors &ef, int Mu, int Mv)
{
- /* XXX need to make this also work for edge factor 0 and 1 */
- int num_verts = (ef.tu0 + ef.tu1 + ef.tv0 + ef.tv1) + (Mu - 1)*(Mv - 1);
- EdgeDice::reserve(num_verts);
+ /* XXX need to make this also work for edge factor 0 and 1 */
+ int num_verts = (ef.tu0 + ef.tu1 + ef.tv0 + ef.tv1) + (Mu - 1) * (Mv - 1);
+ EdgeDice::reserve(num_verts);
}
-float2 QuadDice::map_uv(SubPatch& sub, float u, float v)
+float2 QuadDice::map_uv(SubPatch &sub, float u, float v)
{
- /* map UV from subpatch to patch parametric coordinates */
- float2 d0 = interp(sub.P00, sub.P01, v);
- float2 d1 = interp(sub.P10, sub.P11, v);
- return interp(d0, d1, u);
+ /* map UV from subpatch to patch parametric coordinates */
+ float2 d0 = interp(sub.P00, sub.P01, v);
+ float2 d1 = interp(sub.P10, sub.P11, v);
+ return interp(d0, d1, u);
}
-float3 QuadDice::eval_projected(SubPatch& sub, float u, float v)
+float3 QuadDice::eval_projected(SubPatch &sub, float u, float v)
{
- float2 uv = map_uv(sub, u, v);
- float3 P;
+ float2 uv = map_uv(sub, u, v);
+ float3 P;
- sub.patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
- if(params.camera)
- P = transform_perspective(&params.camera->worldtoraster, P);
+ sub.patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
+ if (params.camera)
+ P = transform_perspective(&params.camera->worldtoraster, P);
- return P;
+ return P;
}
-int QuadDice::add_vert(SubPatch& sub, float u, float v)
+int QuadDice::add_vert(SubPatch &sub, float u, float v)
{
- return EdgeDice::add_vert(sub.patch, map_uv(sub, u, v));
+ return EdgeDice::add_vert(sub.patch, map_uv(sub, u, v));
}
-void QuadDice::add_side_u(SubPatch& sub,
- vector<int>& outer, vector<int>& inner,
- int Mu, int Mv, int tu, int side, int offset)
+void QuadDice::add_side_u(SubPatch &sub,
+ vector<int> &outer,
+ vector<int> &inner,
+ int Mu,
+ int Mv,
+ int tu,
+ int side,
+ int offset)
{
- outer.clear();
- inner.clear();
+ outer.clear();
+ inner.clear();
- /* set verts on the edge of the patch */
- outer.push_back(offset + ((side)? 2: 0));
+ /* set verts on the edge of the patch */
+ outer.push_back(offset + ((side) ? 2 : 0));
- for(int i = 1; i < tu; i++) {
- float u = i/(float)tu;
- float v = (side)? 1.0f: 0.0f;
+ for (int i = 1; i < tu; i++) {
+ float u = i / (float)tu;
+ float v = (side) ? 1.0f : 0.0f;
- outer.push_back(add_vert(sub, u, v));
- }
+ outer.push_back(add_vert(sub, u, v));
+ }
- outer.push_back(offset + ((side)? 3: 1));
+ outer.push_back(offset + ((side) ? 3 : 1));
- /* set verts on the edge of the inner grid */
- for(int i = 0; i < Mu-1; i++) {
- int j = (side)? Mv-1-1: 0;
- inner.push_back(offset + 4 + i + j*(Mu-1));
- }
+ /* set verts on the edge of the inner grid */
+ for (int i = 0; i < Mu - 1; i++) {
+ int j = (side) ? Mv - 1 - 1 : 0;
+ inner.push_back(offset + 4 + i + j * (Mu - 1));
+ }
}
-void QuadDice::add_side_v(SubPatch& sub,
- vector<int>& outer, vector<int>& inner,
- int Mu, int Mv, int tv, int side, int offset)
+void QuadDice::add_side_v(SubPatch &sub,
+ vector<int> &outer,
+ vector<int> &inner,
+ int Mu,
+ int Mv,
+ int tv,
+ int side,
+ int offset)
{
- outer.clear();
- inner.clear();
+ outer.clear();
+ inner.clear();
- /* set verts on the edge of the patch */
- outer.push_back(offset + ((side)? 1: 0));
+ /* set verts on the edge of the patch */
+ outer.push_back(offset + ((side) ? 1 : 0));
- for(int j = 1; j < tv; j++) {
- float u = (side)? 1.0f: 0.0f;
- float v = j/(float)tv;
+ for (int j = 1; j < tv; j++) {
+ float u = (side) ? 1.0f : 0.0f;
+ float v = j / (float)tv;
- outer.push_back(add_vert(sub, u, v));
- }
+ outer.push_back(add_vert(sub, u, v));
+ }
- outer.push_back(offset + ((side)? 3: 2));
+ outer.push_back(offset + ((side) ? 3 : 2));
- /* set verts on the edge of the inner grid */
- for(int j = 0; j < Mv-1; j++) {
- int i = (side)? Mu-1-1: 0;
- inner.push_back(offset + 4 + i + j*(Mu-1));
- }
+ /* set verts on the edge of the inner grid */
+ for (int j = 0; j < Mv - 1; j++) {
+ int i = (side) ? Mu - 1 - 1 : 0;
+ inner.push_back(offset + 4 + i + j * (Mu - 1));
+ }
}
-float QuadDice::quad_area(const float3& a, const float3& b, const float3& c, const float3& d)
+float QuadDice::quad_area(const float3 &a, const float3 &b, const float3 &c, const float3 &d)
{
- return triangle_area(a, b, d) + triangle_area(a, d, c);
+ return triangle_area(a, b, d) + triangle_area(a, d, c);
}
-float QuadDice::scale_factor(SubPatch& sub, EdgeFactors& ef, int Mu, int Mv)
+float QuadDice::scale_factor(SubPatch &sub, EdgeFactors &ef, int Mu, int Mv)
{
- /* estimate area as 4x largest of 4 quads */
- float3 P[3][3];
-
- for(int i = 0; i < 3; i++)
- for(int j = 0; j < 3; j++)
- P[i][j] = eval_projected(sub, i*0.5f, j*0.5f);
-
- float A1 = quad_area(P[0][0], P[1][0], P[0][1], P[1][1]);
- float A2 = quad_area(P[1][0], P[2][0], P[1][1], P[2][1]);
- float A3 = quad_area(P[0][1], P[1][1], P[0][2], P[1][2]);
- float A4 = quad_area(P[1][1], P[2][1], P[1][2], P[2][2]);
- float Apatch = max(A1, max(A2, max(A3, A4)))*4.0f;
-
- /* solve for scaling factor */
- float Atri = params.dicing_rate*params.dicing_rate*0.5f;
- float Ntris = Apatch/Atri;
-
- // XXX does the -sqrt solution matter
- // XXX max(D, 0.0) is highly suspicious, need to test cases
- // where D goes negative
- float N = 0.5f*(Ntris - (ef.tu0 + ef.tu1 + ef.tv0 + ef.tv1));
- float D = 4.0f*N*Mu*Mv + (Mu + Mv)*(Mu + Mv);
- float S = (Mu + Mv + sqrtf(max(D, 0.0f)))/(2*Mu*Mv);
-
- return S;
+ /* estimate area as 4x largest of 4 quads */
+ float3 P[3][3];
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ P[i][j] = eval_projected(sub, i * 0.5f, j * 0.5f);
+
+ float A1 = quad_area(P[0][0], P[1][0], P[0][1], P[1][1]);
+ float A2 = quad_area(P[1][0], P[2][0], P[1][1], P[2][1]);
+ float A3 = quad_area(P[0][1], P[1][1], P[0][2], P[1][2]);
+ float A4 = quad_area(P[1][1], P[2][1], P[1][2], P[2][2]);
+ float Apatch = max(A1, max(A2, max(A3, A4))) * 4.0f;
+
+ /* solve for scaling factor */
+ float Atri = params.dicing_rate * params.dicing_rate * 0.5f;
+ float Ntris = Apatch / Atri;
+
+ // XXX does the -sqrt solution matter
+ // XXX max(D, 0.0) is highly suspicious, need to test cases
+ // where D goes negative
+ float N = 0.5f * (Ntris - (ef.tu0 + ef.tu1 + ef.tv0 + ef.tv1));
+ float D = 4.0f * N * Mu * Mv + (Mu + Mv) * (Mu + Mv);
+ float S = (Mu + Mv + sqrtf(max(D, 0.0f))) / (2 * Mu * Mv);
+
+ return S;
}
-void QuadDice::add_corners(SubPatch& sub)
+void QuadDice::add_corners(SubPatch &sub)
{
- /* add verts for patch corners */
- add_vert(sub, 0.0f, 0.0f);
- add_vert(sub, 1.0f, 0.0f);
- add_vert(sub, 0.0f, 1.0f);
- add_vert(sub, 1.0f, 1.0f);
+ /* add verts for patch corners */
+ add_vert(sub, 0.0f, 0.0f);
+ add_vert(sub, 1.0f, 0.0f);
+ add_vert(sub, 0.0f, 1.0f);
+ add_vert(sub, 1.0f, 1.0f);
}
-void QuadDice::add_grid(SubPatch& sub, int Mu, int Mv, int offset)
+void QuadDice::add_grid(SubPatch &sub, int Mu, int Mv, int offset)
{
- /* create inner grid */
- float du = 1.0f/(float)Mu;
- float dv = 1.0f/(float)Mv;
-
- for(int j = 1; j < Mv; j++) {
- for(int i = 1; i < Mu; i++) {
- float u = i*du;
- float v = j*dv;
-
- add_vert(sub, u, v);
-
- if(i < Mu-1 && j < Mv-1) {
- int i1 = offset + 4 + (i-1) + (j-1)*(Mu-1);
- int i2 = offset + 4 + i + (j-1)*(Mu-1);
- int i3 = offset + 4 + i + j*(Mu-1);
- int i4 = offset + 4 + (i-1) + j*(Mu-1);
-
- add_triangle(sub.patch, i1, i2, i3);
- add_triangle(sub.patch, i1, i3, i4);
- }
- }
- }
+ /* create inner grid */
+ float du = 1.0f / (float)Mu;
+ float dv = 1.0f / (float)Mv;
+
+ for (int j = 1; j < Mv; j++) {
+ for (int i = 1; i < Mu; i++) {
+ float u = i * du;
+ float v = j * dv;
+
+ add_vert(sub, u, v);
+
+ if (i < Mu - 1 && j < Mv - 1) {
+ int i1 = offset + 4 + (i - 1) + (j - 1) * (Mu - 1);
+ int i2 = offset + 4 + i + (j - 1) * (Mu - 1);
+ int i3 = offset + 4 + i + j * (Mu - 1);
+ int i4 = offset + 4 + (i - 1) + j * (Mu - 1);
+
+ add_triangle(sub.patch, i1, i2, i3);
+ add_triangle(sub.patch, i1, i3, i4);
+ }
+ }
+ }
}
-void QuadDice::dice(SubPatch& sub, EdgeFactors& ef)
+void QuadDice::dice(SubPatch &sub, EdgeFactors &ef)
{
- /* compute inner grid size with scale factor */
- int Mu = max(ef.tu0, ef.tu1);
- int Mv = max(ef.tv0, ef.tv1);
+ /* compute inner grid size with scale factor */
+ int Mu = max(ef.tu0, ef.tu1);
+ int Mv = max(ef.tv0, ef.tv1);
#if 0 /* Doesnt work very well, especially at grazing angles. */
- float S = scale_factor(sub, ef, Mu, Mv);
+ float S = scale_factor(sub, ef, Mu, Mv);
#else
- float S = 1.0f;
+ float S = 1.0f;
#endif
- Mu = max((int)ceil(S*Mu), 2); // XXX handle 0 & 1?
- Mv = max((int)ceil(S*Mv), 2); // XXX handle 0 & 1?
+ Mu = max((int)ceil(S * Mu), 2); // XXX handle 0 & 1?
+ Mv = max((int)ceil(S * Mv), 2); // XXX handle 0 & 1?
- /* reserve space for new verts */
- int offset = params.mesh->verts.size();
- reserve(ef, Mu, Mv);
+ /* reserve space for new verts */
+ int offset = params.mesh->verts.size();
+ reserve(ef, Mu, Mv);
- /* corners and inner grid */
- add_corners(sub);
- add_grid(sub, Mu, Mv, offset);
+ /* corners and inner grid */
+ add_corners(sub);
+ add_grid(sub, Mu, Mv, offset);
- /* bottom side */
- vector<int> outer, inner;
+ /* bottom side */
+ vector<int> outer, inner;
- add_side_u(sub, outer, inner, Mu, Mv, ef.tu0, 0, offset);
- stitch_triangles(sub.patch, outer, inner);
+ add_side_u(sub, outer, inner, Mu, Mv, ef.tu0, 0, offset);
+ stitch_triangles(sub.patch, outer, inner);
- /* top side */
- add_side_u(sub, outer, inner, Mu, Mv, ef.tu1, 1, offset);
- stitch_triangles(sub.patch, inner, outer);
+ /* top side */
+ add_side_u(sub, outer, inner, Mu, Mv, ef.tu1, 1, offset);
+ stitch_triangles(sub.patch, inner, outer);
- /* left side */
- add_side_v(sub, outer, inner, Mu, Mv, ef.tv0, 0, offset);
- stitch_triangles(sub.patch, inner, outer);
+ /* left side */
+ add_side_v(sub, outer, inner, Mu, Mv, ef.tv0, 0, offset);
+ stitch_triangles(sub.patch, inner, outer);
- /* right side */
- add_side_v(sub, outer, inner, Mu, Mv, ef.tv1, 1, offset);
- stitch_triangles(sub.patch, outer, inner);
+ /* right side */
+ add_side_v(sub, outer, inner, Mu, Mv, ef.tv1, 1, offset);
+ stitch_triangles(sub.patch, outer, inner);
- assert(vert_offset == params.mesh->verts.size());
+ assert(vert_offset == params.mesh->verts.size());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h
index 2bef8d4cf8d..eee54e01861 100644
--- a/intern/cycles/subd/subd_dice.h
+++ b/intern/cycles/subd/subd_dice.h
@@ -32,48 +32,47 @@ class Mesh;
class Patch;
struct SubdParams {
- Mesh *mesh;
- bool ptex;
-
- int test_steps;
- int split_threshold;
- float dicing_rate;
- int max_level;
- Camera *camera;
- Transform objecttoworld;
-
- SubdParams(Mesh *mesh_, bool ptex_ = false)
- {
- mesh = mesh_;
- ptex = ptex_;
-
- test_steps = 3;
- split_threshold = 1;
- dicing_rate = 1.0f;
- max_level = 12;
- camera = NULL;
- }
-
+ Mesh *mesh;
+ bool ptex;
+
+ int test_steps;
+ int split_threshold;
+ float dicing_rate;
+ int max_level;
+ Camera *camera;
+ Transform objecttoworld;
+
+ SubdParams(Mesh *mesh_, bool ptex_ = false)
+ {
+ mesh = mesh_;
+ ptex = ptex_;
+
+ test_steps = 3;
+ split_threshold = 1;
+ dicing_rate = 1.0f;
+ max_level = 12;
+ camera = NULL;
+ }
};
/* EdgeDice Base */
class EdgeDice {
-public:
- SubdParams params;
- float3 *mesh_P;
- float3 *mesh_N;
- size_t vert_offset;
- size_t tri_offset;
+ public:
+ SubdParams params;
+ float3 *mesh_P;
+ float3 *mesh_N;
+ size_t vert_offset;
+ size_t tri_offset;
- explicit EdgeDice(const SubdParams& params);
+ explicit EdgeDice(const SubdParams &params);
- void reserve(int num_verts);
+ void reserve(int num_verts);
- int add_vert(Patch *patch, float2 uv);
- void add_triangle(Patch *patch, int v0, int v1, int v2);
+ int add_vert(Patch *patch, float2 uv);
+ void add_triangle(Patch *patch, int v0, int v1, int v2);
- void stitch_triangles(Patch *patch, vector<int>& outer, vector<int>& inner);
+ void stitch_triangles(Patch *patch, vector<int> &outer, vector<int> &inner);
};
/* Quad EdgeDice
@@ -90,48 +89,58 @@ public:
*/
class QuadDice : public EdgeDice {
-public:
- struct SubPatch {
- Patch *patch;
-
- float2 P00;
- float2 P10;
- float2 P01;
- float2 P11;
- };
-
- struct EdgeFactors {
- int tu0;
- int tu1;
- int tv0;
- int tv1;
- };
-
- explicit QuadDice(const SubdParams& params);
-
- void reserve(EdgeFactors& ef, int Mu, int Mv);
- float3 eval_projected(SubPatch& sub, float u, float v);
-
- float2 map_uv(SubPatch& sub, float u, float v);
- int add_vert(SubPatch& sub, float u, float v);
-
- void add_corners(SubPatch& sub);
- void add_grid(SubPatch& sub, int Mu, int Mv, int offset);
-
- void add_side_u(SubPatch& sub,
- vector<int>& outer, vector<int>& inner,
- int Mu, int Mv, int tu, int side, int offset);
-
- void add_side_v(SubPatch& sub,
- vector<int>& outer, vector<int>& inner,
- int Mu, int Mv, int tv, int side, int offset);
-
- float quad_area(const float3& a, const float3& b, const float3& c, const float3& d);
- float scale_factor(SubPatch& sub, EdgeFactors& ef, int Mu, int Mv);
-
- void dice(SubPatch& sub, EdgeFactors& ef);
+ public:
+ struct SubPatch {
+ Patch *patch;
+
+ float2 P00;
+ float2 P10;
+ float2 P01;
+ float2 P11;
+ };
+
+ struct EdgeFactors {
+ int tu0;
+ int tu1;
+ int tv0;
+ int tv1;
+ };
+
+ explicit QuadDice(const SubdParams &params);
+
+ void reserve(EdgeFactors &ef, int Mu, int Mv);
+ float3 eval_projected(SubPatch &sub, float u, float v);
+
+ float2 map_uv(SubPatch &sub, float u, float v);
+ int add_vert(SubPatch &sub, float u, float v);
+
+ void add_corners(SubPatch &sub);
+ void add_grid(SubPatch &sub, int Mu, int Mv, int offset);
+
+ void add_side_u(SubPatch &sub,
+ vector<int> &outer,
+ vector<int> &inner,
+ int Mu,
+ int Mv,
+ int tu,
+ int side,
+ int offset);
+
+ void add_side_v(SubPatch &sub,
+ vector<int> &outer,
+ vector<int> &inner,
+ int Mu,
+ int Mv,
+ int tv,
+ int side,
+ int offset);
+
+ float quad_area(const float3 &a, const float3 &b, const float3 &c, const float3 &d);
+ float scale_factor(SubPatch &sub, EdgeFactors &ef, int Mu, int Mv);
+
+ void dice(SubPatch &sub, EdgeFactors &ef);
};
CCL_NAMESPACE_END
-#endif /* __SUBD_DICE_H__ */
+#endif /* __SUBD_DICE_H__ */
diff --git a/intern/cycles/subd/subd_patch.cpp b/intern/cycles/subd/subd_patch.cpp
index f8f5aa25d19..a975b7b6342 100644
--- a/intern/cycles/subd/subd_patch.cpp
+++ b/intern/cycles/subd/subd_patch.cpp
@@ -29,89 +29,93 @@ CCL_NAMESPACE_BEGIN
static void decasteljau_cubic(float3 *P, float3 *dt, float t, const float3 cp[4])
{
- float3 d0 = cp[0] + t*(cp[1] - cp[0]);
- float3 d1 = cp[1] + t*(cp[2] - cp[1]);
- float3 d2 = cp[2] + t*(cp[3] - cp[2]);
+ float3 d0 = cp[0] + t * (cp[1] - cp[0]);
+ float3 d1 = cp[1] + t * (cp[2] - cp[1]);
+ float3 d2 = cp[2] + t * (cp[3] - cp[2]);
- d0 += t*(d1 - d0);
- d1 += t*(d2 - d1);
+ d0 += t * (d1 - d0);
+ d1 += t * (d2 - d1);
- *P = d0 + t*(d1 - d0);
- if(dt) *dt = d1 - d0;
+ *P = d0 + t * (d1 - d0);
+ if (dt)
+ *dt = d1 - d0;
}
-static void decasteljau_bicubic(float3 *P, float3 *du, float3 *dv, const float3 cp[16], float u, float v)
+static void decasteljau_bicubic(
+ float3 *P, float3 *du, float3 *dv, const float3 cp[16], float u, float v)
{
- float3 ucp[4], utn[4];
-
- /* interpolate over u */
- decasteljau_cubic(ucp+0, utn+0, u, cp);
- decasteljau_cubic(ucp+1, utn+1, u, cp+4);
- decasteljau_cubic(ucp+2, utn+2, u, cp+8);
- decasteljau_cubic(ucp+3, utn+3, u, cp+12);
-
- /* interpolate over v */
- decasteljau_cubic(P, dv, v, ucp);
- if(du) decasteljau_cubic(du, NULL, v, utn);
+ float3 ucp[4], utn[4];
+
+ /* interpolate over u */
+ decasteljau_cubic(ucp + 0, utn + 0, u, cp);
+ decasteljau_cubic(ucp + 1, utn + 1, u, cp + 4);
+ decasteljau_cubic(ucp + 2, utn + 2, u, cp + 8);
+ decasteljau_cubic(ucp + 3, utn + 3, u, cp + 12);
+
+ /* interpolate over v */
+ decasteljau_cubic(P, dv, v, ucp);
+ if (du)
+ decasteljau_cubic(du, NULL, v, utn);
}
/* Linear Quad Patch */
void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
{
- float3 d0 = interp(hull[0], hull[1], u);
- float3 d1 = interp(hull[2], hull[3], u);
+ float3 d0 = interp(hull[0], hull[1], u);
+ float3 d1 = interp(hull[2], hull[3], u);
- *P = interp(d0, d1, v);
+ *P = interp(d0, d1, v);
- if(dPdu && dPdv) {
- *dPdu = interp(hull[1] - hull[0], hull[3] - hull[2], v);
- *dPdv = interp(hull[2] - hull[0], hull[3] - hull[1], u);
- }
+ if (dPdu && dPdv) {
+ *dPdu = interp(hull[1] - hull[0], hull[3] - hull[2], v);
+ *dPdv = interp(hull[2] - hull[0], hull[3] - hull[1], u);
+ }
- if(N) {
- *N = normalize(interp(interp(normals[0], normals[1], u), interp(normals[2], normals[3], u), v));
- }
+ if (N) {
+ *N = normalize(
+ interp(interp(normals[0], normals[1], u), interp(normals[2], normals[3], u), v));
+ }
}
BoundBox LinearQuadPatch::bound()
{
- BoundBox bbox = BoundBox::empty;
+ BoundBox bbox = BoundBox::empty;
- for(int i = 0; i < 4; i++)
- bbox.grow(hull[i]);
+ for (int i = 0; i < 4; i++)
+ bbox.grow(hull[i]);
- return bbox;
+ return bbox;
}
/* Bicubic Patch */
void BicubicPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
{
- if(N) {
- float3 dPdu_, dPdv_;
- decasteljau_bicubic(P, &dPdu_, &dPdv_, hull, u, v);
-
- if(dPdu && dPdv) {
- *dPdu = dPdu_;
- *dPdv = dPdv_;
- }
-
- *N = normalize(cross(dPdu_, dPdv_));
- }
- else {
- decasteljau_bicubic(P, dPdu, dPdv, hull, u, v);
- }
+ if (N) {
+ float3 dPdu_, dPdv_;
+ decasteljau_bicubic(P, &dPdu_, &dPdv_, hull, u, v);
+
+ if (dPdu && dPdv) {
+ *dPdu = dPdu_;
+ *dPdv = dPdv_;
+ }
+
+ *N = normalize(cross(dPdu_, dPdv_));
+ }
+ else {
+ decasteljau_bicubic(P, dPdu, dPdv, hull, u, v);
+ }
}
BoundBox BicubicPatch::bound()
{
- BoundBox bbox = BoundBox::empty;
+ BoundBox bbox = BoundBox::empty;
- for(int i = 0; i < 16; i++)
- bbox.grow(hull[i]);
+ for (int i = 0; i < 16; i++)
+ bbox.grow(hull[i]);
- return bbox;
+ return bbox;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/subd/subd_patch.h b/intern/cycles/subd/subd_patch.h
index 84100139f2c..5209d4d0b07 100644
--- a/intern/cycles/subd/subd_patch.h
+++ b/intern/cycles/subd/subd_patch.h
@@ -23,37 +23,42 @@
CCL_NAMESPACE_BEGIN
class Patch {
-public:
- virtual ~Patch() {}
- virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v) = 0;
- virtual BoundBox bound() = 0;
- virtual int ptex_face_id() { return -1; }
-
- int patch_index;
- int shader;
+ public:
+ virtual ~Patch()
+ {
+ }
+ virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v) = 0;
+ virtual BoundBox bound() = 0;
+ virtual int ptex_face_id()
+ {
+ return -1;
+ }
+
+ int patch_index;
+ int shader;
};
/* Linear Quad Patch */
class LinearQuadPatch : public Patch {
-public:
- float3 hull[4];
- float3 normals[4];
+ public:
+ float3 hull[4];
+ float3 normals[4];
- void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
- BoundBox bound();
+ void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
+ BoundBox bound();
};
/* Bicubic Patch */
class BicubicPatch : public Patch {
-public:
- float3 hull[16];
+ public:
+ float3 hull[16];
- void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
- BoundBox bound();
+ void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
+ BoundBox bound();
};
CCL_NAMESPACE_END
-#endif /* __SUBD_PATCH_H__ */
+#endif /* __SUBD_PATCH_H__ */
diff --git a/intern/cycles/subd/subd_patch_table.cpp b/intern/cycles/subd/subd_patch_table.cpp
index f9671ee144d..4e873375725 100644
--- a/intern/cycles/subd/subd_patch_table.cpp
+++ b/intern/cycles/subd/subd_patch_table.cpp
@@ -30,7 +30,7 @@
#include "util/util_math.h"
#ifdef WITH_OPENSUBDIV
-#include <opensubdiv/far/patchTable.h>
+# include <opensubdiv/far/patchTable.h>
#endif
CCL_NAMESPACE_BEGIN
@@ -42,144 +42,146 @@ using namespace OpenSubdiv;
/* functions for building patch maps */
struct PatchMapQuadNode {
- /* sets all the children to point to the patch of index */
- void set_child(int index)
- {
- for(int i = 0; i < 4; i++) {
- children[i] = index | PATCH_MAP_NODE_IS_SET | PATCH_MAP_NODE_IS_LEAF;
- }
- }
-
- /* sets the child in quadrant to point to the node or patch of the given index */
- void set_child(unsigned char quadrant, int index, bool is_leaf=true)
- {
- assert(quadrant < 4);
- children[quadrant] = index | PATCH_MAP_NODE_IS_SET | (is_leaf ? PATCH_MAP_NODE_IS_LEAF : 0);
- }
-
- uint children[4];
+ /* sets all the children to point to the patch of index */
+ void set_child(int index)
+ {
+ for (int i = 0; i < 4; i++) {
+ children[i] = index | PATCH_MAP_NODE_IS_SET | PATCH_MAP_NODE_IS_LEAF;
+ }
+ }
+
+ /* sets the child in quadrant to point to the node or patch of the given index */
+ void set_child(unsigned char quadrant, int index, bool is_leaf = true)
+ {
+ assert(quadrant < 4);
+ children[quadrant] = index | PATCH_MAP_NODE_IS_SET | (is_leaf ? PATCH_MAP_NODE_IS_LEAF : 0);
+ }
+
+ uint children[4];
};
-template<class T>
-static int resolve_quadrant(T& median, T& u, T& v)
+template<class T> static int resolve_quadrant(T &median, T &u, T &v)
{
- int quadrant = -1;
-
- if(u < median) {
- if(v < median) {
- quadrant = 0;
- }
- else {
- quadrant = 1;
- v -= median;
- }
- }
- else {
- if(v < median) {
- quadrant = 3;
- }
- else {
- quadrant = 2;
- v -= median;
- }
- u -= median;
- }
-
- return quadrant;
+ int quadrant = -1;
+
+ if (u < median) {
+ if (v < median) {
+ quadrant = 0;
+ }
+ else {
+ quadrant = 1;
+ v -= median;
+ }
+ }
+ else {
+ if (v < median) {
+ quadrant = 3;
+ }
+ else {
+ quadrant = 2;
+ v -= median;
+ }
+ u -= median;
+ }
+
+ return quadrant;
}
-static void build_patch_map(PackedPatchTable& table, OpenSubdiv::Far::PatchTable* patch_table, int offset)
+static void build_patch_map(PackedPatchTable &table,
+ OpenSubdiv::Far::PatchTable *patch_table,
+ int offset)
{
- int num_faces = 0;
-
- for(int array = 0; array < table.num_arrays; array++) {
- Far::ConstPatchParamArray params = patch_table->GetPatchParams(array);
-
- for(int j = 0; j < patch_table->GetNumPatches(array); j++) {
- num_faces = max(num_faces, (int)params[j].GetFaceId());
- }
- }
- num_faces++;
-
- vector<PatchMapQuadNode> quadtree;
- quadtree.reserve(num_faces + table.num_patches);
- quadtree.resize(num_faces);
-
- /* adjust offsets to make indices relative to the table */
- int handle_index = -(table.num_patches * PATCH_HANDLE_SIZE);
- offset += table.total_size();
-
- /* populate the quadtree from the FarPatchArrays sub-patches */
- for(int array = 0; array < table.num_arrays; array++) {
- Far::ConstPatchParamArray params = patch_table->GetPatchParams(array);
-
- for(int i = 0; i < patch_table->GetNumPatches(array); i++, handle_index += PATCH_HANDLE_SIZE) {
- const Far::PatchParam& param = params[i];
- unsigned short depth = param.GetDepth();
-
- PatchMapQuadNode* node = &quadtree[params[i].GetFaceId()];
-
- if(depth == (param.NonQuadRoot() ? 1 : 0)) {
- /* special case : regular BSpline face w/ no sub-patches */
- node->set_child(handle_index + offset);
- continue;
- }
-
- int u = param.GetU();
- int v = param.GetV();
- int pdepth = param.NonQuadRoot() ? depth-2 : depth-1;
- int half = 1 << pdepth;
-
- for(int j = 0; j < depth; j++) {
- int delta = half >> 1;
-
- int quadrant = resolve_quadrant(half, u, v);
- assert(quadrant >= 0);
-
- half = delta;
-
- if(j == pdepth) {
- /* we have reached the depth of the sub-patch : add a leaf */
- assert(!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET));
- node->set_child(quadrant, handle_index + offset, true);
- break;
- }
- else {
- /* travel down the child node of the corresponding quadrant */
- if(!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET)) {
- /* create a new branch in the quadrant */
- quadtree.push_back(PatchMapQuadNode());
-
- int idx = (int)quadtree.size() - 1;
- node->set_child(quadrant, idx*4 + offset, false);
-
- node = &quadtree[idx];
- }
- else {
- /* travel down an existing branch */
- uint idx = node->children[quadrant] & PATCH_MAP_NODE_INDEX_MASK;
- node = &(quadtree[(idx - offset)/4]);
- }
- }
- }
- }
- }
-
- /* copy into table */
- assert(table.table.size() == table.total_size());
- uint map_offset = table.total_size();
-
- table.num_nodes = quadtree.size() * 4;
- table.table.resize(table.total_size());
-
- uint* data = &table.table[map_offset];
-
- for(int i = 0; i < quadtree.size(); i++) {
- for(int j = 0; j < 4; j++) {
- assert(quadtree[i].children[j] & PATCH_MAP_NODE_IS_SET);
- *(data++) = quadtree[i].children[j];
- }
- }
+ int num_faces = 0;
+
+ for (int array = 0; array < table.num_arrays; array++) {
+ Far::ConstPatchParamArray params = patch_table->GetPatchParams(array);
+
+ for (int j = 0; j < patch_table->GetNumPatches(array); j++) {
+ num_faces = max(num_faces, (int)params[j].GetFaceId());
+ }
+ }
+ num_faces++;
+
+ vector<PatchMapQuadNode> quadtree;
+ quadtree.reserve(num_faces + table.num_patches);
+ quadtree.resize(num_faces);
+
+ /* adjust offsets to make indices relative to the table */
+ int handle_index = -(table.num_patches * PATCH_HANDLE_SIZE);
+ offset += table.total_size();
+
+ /* populate the quadtree from the FarPatchArrays sub-patches */
+ for (int array = 0; array < table.num_arrays; array++) {
+ Far::ConstPatchParamArray params = patch_table->GetPatchParams(array);
+
+ for (int i = 0; i < patch_table->GetNumPatches(array);
+ i++, handle_index += PATCH_HANDLE_SIZE) {
+ const Far::PatchParam &param = params[i];
+ unsigned short depth = param.GetDepth();
+
+ PatchMapQuadNode *node = &quadtree[params[i].GetFaceId()];
+
+ if (depth == (param.NonQuadRoot() ? 1 : 0)) {
+ /* special case : regular BSpline face w/ no sub-patches */
+ node->set_child(handle_index + offset);
+ continue;
+ }
+
+ int u = param.GetU();
+ int v = param.GetV();
+ int pdepth = param.NonQuadRoot() ? depth - 2 : depth - 1;
+ int half = 1 << pdepth;
+
+ for (int j = 0; j < depth; j++) {
+ int delta = half >> 1;
+
+ int quadrant = resolve_quadrant(half, u, v);
+ assert(quadrant >= 0);
+
+ half = delta;
+
+ if (j == pdepth) {
+ /* we have reached the depth of the sub-patch : add a leaf */
+ assert(!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET));
+ node->set_child(quadrant, handle_index + offset, true);
+ break;
+ }
+ else {
+ /* travel down the child node of the corresponding quadrant */
+ if (!(node->children[quadrant] & PATCH_MAP_NODE_IS_SET)) {
+ /* create a new branch in the quadrant */
+ quadtree.push_back(PatchMapQuadNode());
+
+ int idx = (int)quadtree.size() - 1;
+ node->set_child(quadrant, idx * 4 + offset, false);
+
+ node = &quadtree[idx];
+ }
+ else {
+ /* travel down an existing branch */
+ uint idx = node->children[quadrant] & PATCH_MAP_NODE_INDEX_MASK;
+ node = &(quadtree[(idx - offset) / 4]);
+ }
+ }
+ }
+ }
+ }
+
+ /* copy into table */
+ assert(table.table.size() == table.total_size());
+ uint map_offset = table.total_size();
+
+ table.num_nodes = quadtree.size() * 4;
+ table.table.resize(table.total_size());
+
+ uint *data = &table.table[map_offset];
+
+ for (int i = 0; i < quadtree.size(); i++) {
+ for (int j = 0; j < 4; j++) {
+ assert(quadtree[i].children[j] & PATCH_MAP_NODE_IS_SET);
+ *(data++) = quadtree[i].children[j];
+ }
+ }
}
#endif
@@ -188,108 +190,106 @@ static void build_patch_map(PackedPatchTable& table, OpenSubdiv::Far::PatchTable
size_t PackedPatchTable::total_size()
{
- return num_arrays * PATCH_ARRAY_SIZE +
- num_indices +
- num_patches * (PATCH_PARAM_SIZE + PATCH_HANDLE_SIZE) +
- num_nodes * PATCH_NODE_SIZE;
+ return num_arrays * PATCH_ARRAY_SIZE + num_indices +
+ num_patches * (PATCH_PARAM_SIZE + PATCH_HANDLE_SIZE) + num_nodes * PATCH_NODE_SIZE;
}
-void PackedPatchTable::pack(Far::PatchTable* patch_table, int offset)
+void PackedPatchTable::pack(Far::PatchTable *patch_table, int offset)
{
- num_arrays = 0;
- num_patches = 0;
- num_indices = 0;
- num_nodes = 0;
+ num_arrays = 0;
+ num_patches = 0;
+ num_indices = 0;
+ num_nodes = 0;
#ifdef WITH_OPENSUBDIV
- num_arrays = patch_table->GetNumPatchArrays();
+ num_arrays = patch_table->GetNumPatchArrays();
- for(int i = 0; i < num_arrays; i++) {
- int patches = patch_table->GetNumPatches(i);
- int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();
+ for (int i = 0; i < num_arrays; i++) {
+ int patches = patch_table->GetNumPatches(i);
+ int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();
- num_patches += patches;
- num_indices += patches * num_control;
- }
+ num_patches += patches;
+ num_indices += patches * num_control;
+ }
- table.resize(total_size());
- uint* data = table.data();
+ table.resize(total_size());
+ uint *data = table.data();
- uint* array = data;
- uint* index = array + num_arrays * PATCH_ARRAY_SIZE;
- uint* param = index + num_indices;
- uint* handle = param + num_patches * PATCH_PARAM_SIZE;
+ uint *array = data;
+ uint *index = array + num_arrays * PATCH_ARRAY_SIZE;
+ uint *param = index + num_indices;
+ uint *handle = param + num_patches * PATCH_PARAM_SIZE;
- uint current_param = 0;
+ uint current_param = 0;
- for(int i = 0; i < num_arrays; i++) {
- *(array++) = patch_table->GetPatchArrayDescriptor(i).GetType();
- *(array++) = patch_table->GetNumPatches(i);
- *(array++) = (index - data) + offset;
- *(array++) = (param - data) + offset;
+ for (int i = 0; i < num_arrays; i++) {
+ *(array++) = patch_table->GetPatchArrayDescriptor(i).GetType();
+ *(array++) = patch_table->GetNumPatches(i);
+ *(array++) = (index - data) + offset;
+ *(array++) = (param - data) + offset;
- Far::ConstIndexArray indices = patch_table->GetPatchArrayVertices(i);
+ Far::ConstIndexArray indices = patch_table->GetPatchArrayVertices(i);
- for(int j = 0; j < indices.size(); j++) {
- *(index++) = indices[j];
- }
+ for (int j = 0; j < indices.size(); j++) {
+ *(index++) = indices[j];
+ }
- const Far::PatchParamTable& param_table = patch_table->GetPatchParamTable();
+ const Far::PatchParamTable &param_table = patch_table->GetPatchParamTable();
- int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();
- int patches = patch_table->GetNumPatches(i);
+ int num_control = patch_table->GetPatchArrayDescriptor(i).GetNumControlVertices();
+ int patches = patch_table->GetNumPatches(i);
- for(int j = 0; j < patches; j++, current_param++) {
- *(param++) = param_table[current_param].field0;
- *(param++) = param_table[current_param].field1;
+ for (int j = 0; j < patches; j++, current_param++) {
+ *(param++) = param_table[current_param].field0;
+ *(param++) = param_table[current_param].field1;
- *(handle++) = (array - data) - PATCH_ARRAY_SIZE + offset;
- *(handle++) = (param - data) - PATCH_PARAM_SIZE + offset;
- *(handle++) = j * num_control;
- }
- }
+ *(handle++) = (array - data) - PATCH_ARRAY_SIZE + offset;
+ *(handle++) = (param - data) - PATCH_PARAM_SIZE + offset;
+ *(handle++) = j * num_control;
+ }
+ }
- build_patch_map(*this, patch_table, offset);
+ build_patch_map(*this, patch_table, offset);
#else
- (void) patch_table;
- (void) offset;
+ (void)patch_table;
+ (void)offset;
#endif
}
-void PackedPatchTable::copy_adjusting_offsets(uint* dest, int doffset)
+void PackedPatchTable::copy_adjusting_offsets(uint *dest, int doffset)
{
- uint* src = table.data();
-
- /* arrays */
- for(int i = 0; i < num_arrays; i++) {
- *(dest++) = *(src++);
- *(dest++) = *(src++);
- *(dest++) = *(src++) + doffset;
- *(dest++) = *(src++) + doffset;
- }
-
- /* indices */
- for(int i = 0; i < num_indices; i++) {
- *(dest++) = *(src++);
- }
-
- /* params */
- for(int i = 0; i < num_patches; i++) {
- *(dest++) = *(src++);
- *(dest++) = *(src++);
- }
-
- /* handles */
- for(int i = 0; i < num_patches; i++) {
- *(dest++) = *(src++) + doffset;
- *(dest++) = *(src++) + doffset;
- *(dest++) = *(src++);
- }
-
- /* nodes */
- for(int i = 0; i < num_nodes; i++) {
- *(dest++) = *(src++) + doffset;
- }
+ uint *src = table.data();
+
+ /* arrays */
+ for (int i = 0; i < num_arrays; i++) {
+ *(dest++) = *(src++);
+ *(dest++) = *(src++);
+ *(dest++) = *(src++) + doffset;
+ *(dest++) = *(src++) + doffset;
+ }
+
+ /* indices */
+ for (int i = 0; i < num_indices; i++) {
+ *(dest++) = *(src++);
+ }
+
+ /* params */
+ for (int i = 0; i < num_patches; i++) {
+ *(dest++) = *(src++);
+ *(dest++) = *(src++);
+ }
+
+ /* handles */
+ for (int i = 0; i < num_patches; i++) {
+ *(dest++) = *(src++) + doffset;
+ *(dest++) = *(src++) + doffset;
+ *(dest++) = *(src++);
+ }
+
+ /* nodes */
+ for (int i = 0; i < num_nodes; i++) {
+ *(dest++) = *(src++) + doffset;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/subd/subd_patch_table.h b/intern/cycles/subd/subd_patch_table.h
index 1765578c42e..118d410f8f0 100644
--- a/intern/cycles/subd/subd_patch_table.h
+++ b/intern/cycles/subd/subd_patch_table.h
@@ -21,11 +21,11 @@
#include "util/util_types.h"
#ifdef WITH_OPENSUBDIV
-#ifdef _MSC_VER
-# include "iso646.h"
-#endif
+# ifdef _MSC_VER
+# include "iso646.h"
+# endif
-#include <opensubdiv/far/patchTable.h>
+# include <opensubdiv/far/patchTable.h>
#endif
CCL_NAMESPACE_BEGIN
@@ -34,7 +34,9 @@ CCL_NAMESPACE_BEGIN
using namespace OpenSubdiv;
#else
/* forward declare for when OpenSubdiv is unavailable */
-namespace Far { struct PatchTable; }
+namespace Far {
+struct PatchTable;
+}
#endif
#define PATCH_ARRAY_SIZE 4
@@ -43,20 +45,20 @@ namespace Far { struct PatchTable; }
#define PATCH_NODE_SIZE 1
struct PackedPatchTable {
- array<uint> table;
+ array<uint> table;
- size_t num_arrays;
- size_t num_indices;
- size_t num_patches;
- size_t num_nodes;
+ size_t num_arrays;
+ size_t num_indices;
+ size_t num_patches;
+ size_t num_nodes;
- /* calculated size from num_* members */
- size_t total_size();
+ /* calculated size from num_* members */
+ size_t total_size();
- void pack(Far::PatchTable* patch_table, int offset = 0);
- void copy_adjusting_offsets(uint* dest, int doffset);
+ void pack(Far::PatchTable *patch_table, int offset = 0);
+ void copy_adjusting_offsets(uint *dest, int doffset);
};
CCL_NAMESPACE_END
-#endif /* __SUBD_PATCH_TABLE_H__ */
+#endif /* __SUBD_PATCH_TABLE_H__ */
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index 76261243359..803363bc240 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -28,233 +28,230 @@ CCL_NAMESPACE_BEGIN
/* DiagSplit */
-DiagSplit::DiagSplit(const SubdParams& params_)
-: params(params_)
+DiagSplit::DiagSplit(const SubdParams &params_) : params(params_)
{
}
-void DiagSplit::dispatch(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef)
+void DiagSplit::dispatch(QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef)
{
- subpatches_quad.push_back(sub);
- edgefactors_quad.push_back(ef);
+ subpatches_quad.push_back(sub);
+ edgefactors_quad.push_back(ef);
}
float3 DiagSplit::to_world(Patch *patch, float2 uv)
{
- float3 P;
+ float3 P;
- patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
- if(params.camera)
- P = transform_point(&params.objecttoworld, P);
+ patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
+ if (params.camera)
+ P = transform_point(&params.objecttoworld, P);
- return P;
+ return P;
}
int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend)
{
- float3 Plast = make_float3(0.0f, 0.0f, 0.0f);
- float Lsum = 0.0f;
- float Lmax = 0.0f;
+ float3 Plast = make_float3(0.0f, 0.0f, 0.0f);
+ float Lsum = 0.0f;
+ float Lmax = 0.0f;
- for(int i = 0; i < params.test_steps; i++) {
- float t = i/(float)(params.test_steps-1);
+ for (int i = 0; i < params.test_steps; i++) {
+ float t = i / (float)(params.test_steps - 1);
- float3 P = to_world(patch, Pstart + t*(Pend - Pstart));
+ float3 P = to_world(patch, Pstart + t * (Pend - Pstart));
- if(i > 0) {
- float L;
+ if (i > 0) {
+ float L;
- if(!params.camera) {
- L = len(P - Plast);
- }
- else {
- Camera* cam = params.camera;
+ if (!params.camera) {
+ L = len(P - Plast);
+ }
+ else {
+ Camera *cam = params.camera;
- float pixel_width = cam->world_to_raster_size((P + Plast) * 0.5f);
- L = len(P - Plast) / pixel_width;
- }
+ float pixel_width = cam->world_to_raster_size((P + Plast) * 0.5f);
+ L = len(P - Plast) / pixel_width;
+ }
- Lsum += L;
- Lmax = max(L, Lmax);
- }
+ Lsum += L;
+ Lmax = max(L, Lmax);
+ }
- Plast = P;
- }
+ Plast = P;
+ }
- int tmin = (int)ceil(Lsum/params.dicing_rate);
- int tmax = (int)ceil((params.test_steps-1)*Lmax/params.dicing_rate); // XXX paper says N instead of N-1, seems wrong?
+ int tmin = (int)ceil(Lsum / params.dicing_rate);
+ int tmax = (int)ceil((params.test_steps - 1) * Lmax /
+ params.dicing_rate); // XXX paper says N instead of N-1, seems wrong?
- if(tmax - tmin > params.split_threshold)
- return DSPLIT_NON_UNIFORM;
+ if (tmax - tmin > params.split_threshold)
+ return DSPLIT_NON_UNIFORM;
- return tmax;
+ return tmax;
}
-void DiagSplit::partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t)
+void DiagSplit::partition_edge(
+ Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t)
{
- if(t == DSPLIT_NON_UNIFORM) {
- *P = (Pstart + Pend)*0.5f;
- *t0 = T(patch, Pstart, *P);
- *t1 = T(patch, *P, Pend);
- }
- else {
- int I = (int)floor((float)t*0.5f);
- *P = interp(Pstart, Pend, (t == 0)? 0: I/(float)t); /* XXX is t faces or verts */
- *t0 = I;
- *t1 = t - I;
- }
+ if (t == DSPLIT_NON_UNIFORM) {
+ *P = (Pstart + Pend) * 0.5f;
+ *t0 = T(patch, Pstart, *P);
+ *t1 = T(patch, *P, Pend);
+ }
+ else {
+ int I = (int)floor((float)t * 0.5f);
+ *P = interp(Pstart, Pend, (t == 0) ? 0 : I / (float)t); /* XXX is t faces or verts */
+ *t0 = I;
+ *t1 = t - I;
+ }
}
-static void limit_edge_factors(const QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int max_t)
+static void limit_edge_factors(const QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef, int max_t)
{
- float2 P00 = sub.P00;
- float2 P01 = sub.P01;
- float2 P10 = sub.P10;
- float2 P11 = sub.P11;
-
- int tu0 = int(max_t * len(P10 - P00));
- int tu1 = int(max_t * len(P11 - P01));
- int tv0 = int(max_t * len(P01 - P00));
- int tv1 = int(max_t * len(P11 - P10));
-
- ef.tu0 = tu0 <= 1 ? 1 : min(ef.tu0, tu0);
- ef.tu1 = tu1 <= 1 ? 1 : min(ef.tu1, tu1);
- ef.tv0 = tv0 <= 1 ? 1 : min(ef.tv0, tv0);
- ef.tv1 = tv1 <= 1 ? 1 : min(ef.tv1, tv1);
+ float2 P00 = sub.P00;
+ float2 P01 = sub.P01;
+ float2 P10 = sub.P10;
+ float2 P11 = sub.P11;
+
+ int tu0 = int(max_t * len(P10 - P00));
+ int tu1 = int(max_t * len(P11 - P01));
+ int tv0 = int(max_t * len(P01 - P00));
+ int tv1 = int(max_t * len(P11 - P10));
+
+ ef.tu0 = tu0 <= 1 ? 1 : min(ef.tu0, tu0);
+ ef.tu1 = tu1 <= 1 ? 1 : min(ef.tu1, tu1);
+ ef.tv0 = tv0 <= 1 ? 1 : min(ef.tv0, tv0);
+ ef.tv1 = tv1 <= 1 ? 1 : min(ef.tv1, tv1);
}
-void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth)
+void DiagSplit::split(QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef, int depth)
{
- if(depth > 32) {
- /* We should never get here, but just in case end recursion safely. */
- ef.tu0 = 1;
- ef.tu1 = 1;
- ef.tv0 = 1;
- ef.tv1 = 1;
+ if (depth > 32) {
+ /* We should never get here, but just in case end recursion safely. */
+ ef.tu0 = 1;
+ ef.tu1 = 1;
+ ef.tv0 = 1;
+ ef.tv1 = 1;
- dispatch(sub, ef);
- return;
- }
+ dispatch(sub, ef);
+ return;
+ }
- bool split_u = (ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM);
- bool split_v = (ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM);
+ bool split_u = (ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM);
+ bool split_v = (ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM);
- /* Split subpatches such that the ratio of T for opposite edges doesn't
+ /* Split subpatches such that the ratio of T for opposite edges doesn't
* exceed 1.5, this reduces over tessellation for some patches
- */
- bool tmp_split_v = split_v;
- if(!split_u && min(ef.tu0, ef.tu1) > 8 && min(ef.tu0, ef.tu1)*1.5f < max(ef.tu0, ef.tu1))
- split_v = true;
- if(!tmp_split_v && min(ef.tu0, ef.tu1) > 8 && min(ef.tv0, ef.tv1)*1.5f < max(ef.tv0, ef.tv1))
- split_u = true;
-
- /* alternate axis */
- if(split_u && split_v) {
- split_u = depth % 2;
- }
-
- if(split_u) {
- /* partition edges */
- QuadDice::EdgeFactors ef0, ef1;
- float2 Pu0, Pu1;
-
- partition_edge(sub.patch,
- &Pu0, &ef0.tu0, &ef1.tu0, sub.P00, sub.P10, ef.tu0);
- partition_edge(sub.patch,
- &Pu1, &ef0.tu1, &ef1.tu1, sub.P01, sub.P11, ef.tu1);
-
- /* split */
- int tsplit = T(sub.patch, Pu0, Pu1);
- ef0.tv0 = ef.tv0;
- ef0.tv1 = tsplit;
-
- ef1.tv0 = tsplit;
- ef1.tv1 = ef.tv1;
-
- /* create subpatches */
- QuadDice::SubPatch sub0 = {sub.patch, sub.P00, Pu0, sub.P01, Pu1};
- QuadDice::SubPatch sub1 = {sub.patch, Pu0, sub.P10, Pu1, sub.P11};
-
- limit_edge_factors(sub0, ef0, 1 << params.max_level);
- limit_edge_factors(sub1, ef1, 1 << params.max_level);
-
- split(sub0, ef0, depth+1);
- split(sub1, ef1, depth+1);
- }
- else if(split_v) {
- /* partition edges */
- QuadDice::EdgeFactors ef0, ef1;
- float2 Pv0, Pv1;
-
- partition_edge(sub.patch,
- &Pv0, &ef0.tv0, &ef1.tv0, sub.P00, sub.P01, ef.tv0);
- partition_edge(sub.patch,
- &Pv1, &ef0.tv1, &ef1.tv1, sub.P10, sub.P11, ef.tv1);
-
- /* split */
- int tsplit = T(sub.patch, Pv0, Pv1);
- ef0.tu0 = ef.tu0;
- ef0.tu1 = tsplit;
-
- ef1.tu0 = tsplit;
- ef1.tu1 = ef.tu1;
-
- /* create subpatches */
- QuadDice::SubPatch sub0 = {sub.patch, sub.P00, sub.P10, Pv0, Pv1};
- QuadDice::SubPatch sub1 = {sub.patch, Pv0, Pv1, sub.P01, sub.P11};
-
- limit_edge_factors(sub0, ef0, 1 << params.max_level);
- limit_edge_factors(sub1, ef1, 1 << params.max_level);
-
- split(sub0, ef0, depth+1);
- split(sub1, ef1, depth+1);
- }
- else {
- dispatch(sub, ef);
- }
+ */
+ bool tmp_split_v = split_v;
+ if (!split_u && min(ef.tu0, ef.tu1) > 8 && min(ef.tu0, ef.tu1) * 1.5f < max(ef.tu0, ef.tu1))
+ split_v = true;
+ if (!tmp_split_v && min(ef.tu0, ef.tu1) > 8 && min(ef.tv0, ef.tv1) * 1.5f < max(ef.tv0, ef.tv1))
+ split_u = true;
+
+ /* alternate axis */
+ if (split_u && split_v) {
+ split_u = depth % 2;
+ }
+
+ if (split_u) {
+ /* partition edges */
+ QuadDice::EdgeFactors ef0, ef1;
+ float2 Pu0, Pu1;
+
+ partition_edge(sub.patch, &Pu0, &ef0.tu0, &ef1.tu0, sub.P00, sub.P10, ef.tu0);
+ partition_edge(sub.patch, &Pu1, &ef0.tu1, &ef1.tu1, sub.P01, sub.P11, ef.tu1);
+
+ /* split */
+ int tsplit = T(sub.patch, Pu0, Pu1);
+ ef0.tv0 = ef.tv0;
+ ef0.tv1 = tsplit;
+
+ ef1.tv0 = tsplit;
+ ef1.tv1 = ef.tv1;
+
+ /* create subpatches */
+ QuadDice::SubPatch sub0 = {sub.patch, sub.P00, Pu0, sub.P01, Pu1};
+ QuadDice::SubPatch sub1 = {sub.patch, Pu0, sub.P10, Pu1, sub.P11};
+
+ limit_edge_factors(sub0, ef0, 1 << params.max_level);
+ limit_edge_factors(sub1, ef1, 1 << params.max_level);
+
+ split(sub0, ef0, depth + 1);
+ split(sub1, ef1, depth + 1);
+ }
+ else if (split_v) {
+ /* partition edges */
+ QuadDice::EdgeFactors ef0, ef1;
+ float2 Pv0, Pv1;
+
+ partition_edge(sub.patch, &Pv0, &ef0.tv0, &ef1.tv0, sub.P00, sub.P01, ef.tv0);
+ partition_edge(sub.patch, &Pv1, &ef0.tv1, &ef1.tv1, sub.P10, sub.P11, ef.tv1);
+
+ /* split */
+ int tsplit = T(sub.patch, Pv0, Pv1);
+ ef0.tu0 = ef.tu0;
+ ef0.tu1 = tsplit;
+
+ ef1.tu0 = tsplit;
+ ef1.tu1 = ef.tu1;
+
+ /* create subpatches */
+ QuadDice::SubPatch sub0 = {sub.patch, sub.P00, sub.P10, Pv0, Pv1};
+ QuadDice::SubPatch sub1 = {sub.patch, Pv0, Pv1, sub.P01, sub.P11};
+
+ limit_edge_factors(sub0, ef0, 1 << params.max_level);
+ limit_edge_factors(sub1, ef1, 1 << params.max_level);
+
+ split(sub0, ef0, depth + 1);
+ split(sub1, ef1, depth + 1);
+ }
+ else {
+ dispatch(sub, ef);
+ }
}
void DiagSplit::split_quad(Patch *patch, QuadDice::SubPatch *subpatch)
{
- QuadDice::SubPatch sub_split;
- QuadDice::EdgeFactors ef_split;
+ QuadDice::SubPatch sub_split;
+ QuadDice::EdgeFactors ef_split;
- if(subpatch) {
- sub_split = *subpatch;
- }
- else {
- sub_split.patch = patch;
- sub_split.P00 = make_float2(0.0f, 0.0f);
- sub_split.P10 = make_float2(1.0f, 0.0f);
- sub_split.P01 = make_float2(0.0f, 1.0f);
- sub_split.P11 = make_float2(1.0f, 1.0f);
- }
+ if (subpatch) {
+ sub_split = *subpatch;
+ }
+ else {
+ sub_split.patch = patch;
+ sub_split.P00 = make_float2(0.0f, 0.0f);
+ sub_split.P10 = make_float2(1.0f, 0.0f);
+ sub_split.P01 = make_float2(0.0f, 1.0f);
+ sub_split.P11 = make_float2(1.0f, 1.0f);
+ }
- ef_split.tu0 = T(patch, sub_split.P00, sub_split.P10);
- ef_split.tu1 = T(patch, sub_split.P01, sub_split.P11);
- ef_split.tv0 = T(patch, sub_split.P00, sub_split.P01);
- ef_split.tv1 = T(patch, sub_split.P10, sub_split.P11);
+ ef_split.tu0 = T(patch, sub_split.P00, sub_split.P10);
+ ef_split.tu1 = T(patch, sub_split.P01, sub_split.P11);
+ ef_split.tv0 = T(patch, sub_split.P00, sub_split.P01);
+ ef_split.tv1 = T(patch, sub_split.P10, sub_split.P11);
- limit_edge_factors(sub_split, ef_split, 1 << params.max_level);
+ limit_edge_factors(sub_split, ef_split, 1 << params.max_level);
- split(sub_split, ef_split);
+ split(sub_split, ef_split);
- QuadDice dice(params);
+ QuadDice dice(params);
- for(size_t i = 0; i < subpatches_quad.size(); i++) {
- QuadDice::SubPatch& sub = subpatches_quad[i];
- QuadDice::EdgeFactors& ef = edgefactors_quad[i];
+ for (size_t i = 0; i < subpatches_quad.size(); i++) {
+ QuadDice::SubPatch &sub = subpatches_quad[i];
+ QuadDice::EdgeFactors &ef = edgefactors_quad[i];
- ef.tu0 = max(ef.tu0, 1);
- ef.tu1 = max(ef.tu1, 1);
- ef.tv0 = max(ef.tv0, 1);
- ef.tv1 = max(ef.tv1, 1);
+ ef.tu0 = max(ef.tu0, 1);
+ ef.tu1 = max(ef.tu1, 1);
+ ef.tv0 = max(ef.tv0, 1);
+ ef.tv1 = max(ef.tv1, 1);
- dice.dice(sub, ef);
- }
+ dice.dice(sub, ef);
+ }
- subpatches_quad.clear();
- edgefactors_quad.clear();
+ subpatches_quad.clear();
+ edgefactors_quad.clear();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/subd/subd_split.h b/intern/cycles/subd/subd_split.h
index 3368c93944b..6e68d8ee598 100644
--- a/intern/cycles/subd/subd_split.h
+++ b/intern/cycles/subd/subd_split.h
@@ -35,25 +35,25 @@ class Patch;
#define DSPLIT_NON_UNIFORM -1
class DiagSplit {
-public:
- vector<QuadDice::SubPatch> subpatches_quad;
- vector<QuadDice::EdgeFactors> edgefactors_quad;
+ public:
+ vector<QuadDice::SubPatch> subpatches_quad;
+ vector<QuadDice::EdgeFactors> edgefactors_quad;
- SubdParams params;
+ SubdParams params;
- explicit DiagSplit(const SubdParams& params);
+ explicit DiagSplit(const SubdParams &params);
- float3 to_world(Patch *patch, float2 uv);
- int T(Patch *patch, float2 Pstart, float2 Pend);
- void partition_edge(Patch *patch, float2 *P, int *t0, int *t1,
- float2 Pstart, float2 Pend, int t);
+ float3 to_world(Patch *patch, float2 uv);
+ int T(Patch *patch, float2 Pstart, float2 Pend);
+ void partition_edge(
+ Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t);
- void dispatch(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef);
- void split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth=0);
+ void dispatch(QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef);
+ void split(QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef, int depth = 0);
- void split_quad(Patch *patch, QuadDice::SubPatch *subpatch=NULL);
+ void split_quad(Patch *patch, QuadDice::SubPatch *subpatch = NULL);
};
CCL_NAMESPACE_END
-#endif /* __SUBD_SPLIT_H__ */
+#endif /* __SUBD_SPLIT_H__ */
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index 73fe590f8ae..98fcc8cd15e 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -1,87 +1,87 @@
if(WITH_GTESTS)
- Include(GTestTesting)
+ Include(GTestTesting)
- # Otherwise we get warnings here that we cant fix in external projects
- remove_strict_flags()
+ # Otherwise we get warnings here that we cant fix in external projects
+ remove_strict_flags()
endif()
macro(CYCLES_TEST SRC EXTRA_LIBS)
- if(WITH_GTESTS)
- BLENDER_SRC_GTEST("cycles_${SRC}" "${SRC}_test.cpp" "${EXTRA_LIBS}")
- endif()
+ if(WITH_GTESTS)
+ BLENDER_SRC_GTEST("cycles_${SRC}" "${SRC}_test.cpp" "${EXTRA_LIBS}")
+ endif()
endmacro()
set(INC
- .
- ..
- ../device
- ../graph
- ../kernel
- ../render
- ../util
+ .
+ ..
+ ../device
+ ../graph
+ ../kernel
+ ../render
+ ../util
)
set(ALL_CYCLES_LIBRARIES
- cycles_device
- cycles_kernel
- cycles_render
- cycles_bvh
- cycles_graph
- cycles_subd
- cycles_util
- extern_clew
- ${BLENDER_GL_LIBRARIES}
- ${BLENDER_GLEW_LIBRARIES}
- ${CYCLES_APP_GLEW_LIBRARY}
- ${OPENIMAGEIO_LIBRARIES}
+ cycles_device
+ cycles_kernel
+ cycles_render
+ cycles_bvh
+ cycles_graph
+ cycles_subd
+ cycles_util
+ extern_clew
+ ${BLENDER_GL_LIBRARIES}
+ ${BLENDER_GLEW_LIBRARIES}
+ ${CYCLES_APP_GLEW_LIBRARY}
+ ${OPENIMAGEIO_LIBRARIES}
)
if(WITH_CYCLES_OSL)
- list(APPEND ALL_CYCLES_LIBRARIES
- cycles_kernel_osl
- ${OSL_LIBRARIES}
- ${LLVM_LIBRARIES}
- )
+ list(APPEND ALL_CYCLES_LIBRARIES
+ cycles_kernel_osl
+ ${OSL_LIBRARIES}
+ ${LLVM_LIBRARIES}
+ )
endif()
if(WITH_OPENCOLORIO)
- list(APPEND ALL_CYCLES_LIBRARIES
- ${OPENCOLORIO_LIBRARIES}
- )
+ list(APPEND ALL_CYCLES_LIBRARIES
+ ${OPENCOLORIO_LIBRARIES}
+ )
endif()
if(WITH_IMAGE_OPENJPEG)
- list(APPEND ALL_CYCLES_LIBRARIES ${OPENJPEG_LIBRARIES})
+ list(APPEND ALL_CYCLES_LIBRARIES ${OPENJPEG_LIBRARIES})
endif()
if(WITH_OPENSUBDIV)
- add_definitions(-DWITH_OPENSUBDIV)
- include_directories(
- SYSTEM
- ${OPENSUBDIV_INCLUDE_DIR}
- )
- list(APPEND ALL_CYCLES_LIBRARIES
- ${OPENSUBDIV_LIBRARIES}
- )
+ add_definitions(-DWITH_OPENSUBDIV)
+ include_directories(
+ SYSTEM
+ ${OPENSUBDIV_INCLUDE_DIR}
+ )
+ list(APPEND ALL_CYCLES_LIBRARIES
+ ${OPENSUBDIV_LIBRARIES}
+ )
endif()
if(WITH_CYCLES_EMBREE)
- list(APPEND ALL_CYCLES_LIBRARIES
- ${EMBREE_LIBRARIES}
- )
+ list(APPEND ALL_CYCLES_LIBRARIES
+ ${EMBREE_LIBRARIES}
+ )
endif()
if(WITH_CUDA_DYNLOAD)
- list(APPEND ALL_CYCLES_LIBRARIES extern_cuew)
+ list(APPEND ALL_CYCLES_LIBRARIES extern_cuew)
else()
- list(APPEND ALL_CYCLES_LIBRARIES ${CUDA_CUDA_LIBRARY})
+ list(APPEND ALL_CYCLES_LIBRARIES ${CUDA_CUDA_LIBRARY})
endif()
if(NOT CYCLES_STANDALONE_REPOSITORY)
- list(APPEND ALL_CYCLES_LIBRARIES bf_intern_glew_mx bf_intern_guardedalloc ${GLEW_LIBRARY})
+ list(APPEND ALL_CYCLES_LIBRARIES bf_intern_glew_mx bf_intern_guardedalloc ${GLEW_LIBRARY})
endif()
list(APPEND ALL_CYCLES_LIBRARIES
- ${BOOST_LIBRARIES}
- ${PNG_LIBRARIES}
- ${JPEG_LIBRARIES}
- ${ZLIB_LIBRARIES}
- ${TIFF_LIBRARY}
- ${OPENIMAGEIO_LIBRARIES}
- ${OPENEXR_LIBRARIES}
+ ${BOOST_LIBRARIES}
+ ${PNG_LIBRARIES}
+ ${JPEG_LIBRARIES}
+ ${ZLIB_LIBRARIES}
+ ${TIFF_LIBRARY}
+ ${OPENIMAGEIO_LIBRARIES}
+ ${OPENEXR_LIBRARIES}
)
include_directories(${INC})
diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp
index 5f60411758d..7fb92bfb862 100644
--- a/intern/cycles/test/render_graph_finalize_test.cpp
+++ b/intern/cycles/test/render_graph_finalize_test.cpp
@@ -25,214 +25,199 @@
#include "util/util_string.h"
#include "util/util_vector.h"
+using testing::_;
using testing::AnyNumber;
using testing::HasSubstr;
using testing::ScopedMockLog;
-using testing::_;
CCL_NAMESPACE_BEGIN
namespace {
-template<typename T>
-class ShaderNodeBuilder {
-public:
- ShaderNodeBuilder(const string& name)
- : name_(name)
- {
- node_ = new T();
- node_->name = name;
- }
-
- const string& name() const {
- return name_;
- }
-
- ShaderNode *node() const {
- return node_;
- }
-
- template<typename V>
- ShaderNodeBuilder& set(const string& input_name, V value)
- {
- ShaderInput *input_socket = node_->input(input_name.c_str());
- EXPECT_NE((void*)NULL, input_socket);
- input_socket->set(value);
- return *this;
- }
-
- template<typename T2, typename V>
- ShaderNodeBuilder& set(V T2::*pfield, V value)
- {
- static_cast<T*>(node_)->*pfield = value;
- return *this;
- }
-
-protected:
- string name_;
- ShaderNode *node_;
+template<typename T> class ShaderNodeBuilder {
+ public:
+ ShaderNodeBuilder(const string &name) : name_(name)
+ {
+ node_ = new T();
+ node_->name = name;
+ }
+
+ const string &name() const
+ {
+ return name_;
+ }
+
+ ShaderNode *node() const
+ {
+ return node_;
+ }
+
+ template<typename V> ShaderNodeBuilder &set(const string &input_name, V value)
+ {
+ ShaderInput *input_socket = node_->input(input_name.c_str());
+ EXPECT_NE((void *)NULL, input_socket);
+ input_socket->set(value);
+ return *this;
+ }
+
+ template<typename T2, typename V> ShaderNodeBuilder &set(V T2::*pfield, V value)
+ {
+ static_cast<T *>(node_)->*pfield = value;
+ return *this;
+ }
+
+ protected:
+ string name_;
+ ShaderNode *node_;
};
class ShaderGraphBuilder {
-public:
- ShaderGraphBuilder(ShaderGraph *graph)
- : graph_(graph)
- {
- node_map_["Output"] = graph->output();
- }
-
- ShaderNode *find_node(const string& name)
- {
- map<string, ShaderNode *>::iterator it = node_map_.find(name);
- if(it == node_map_.end()) {
- return NULL;
- }
- return it->second;
- }
-
- template<typename T>
- ShaderGraphBuilder& add_node(const T& node)
- {
- EXPECT_EQ(find_node(node.name()), (void*)NULL);
- graph_->add(node.node());
- node_map_[node.name()] = node.node();
- return *this;
- }
-
- ShaderGraphBuilder& add_connection(const string& from,
- const string& to)
- {
- vector<string> tokens_from, tokens_to;
- string_split(tokens_from, from, "::");
- string_split(tokens_to, to, "::");
- EXPECT_EQ(tokens_from.size(), 2);
- EXPECT_EQ(tokens_to.size(), 2);
- ShaderNode *node_from = find_node(tokens_from[0]),
- *node_to = find_node(tokens_to[0]);
- EXPECT_NE((void*)NULL, node_from);
- EXPECT_NE((void*)NULL, node_to);
- EXPECT_NE(node_from, node_to);
- ShaderOutput *socket_from = node_from->output(tokens_from[1].c_str());
- ShaderInput *socket_to = node_to->input(tokens_to[1].c_str());
- EXPECT_NE((void*)NULL, socket_from);
- EXPECT_NE((void*)NULL, socket_to);
- graph_->connect(socket_from, socket_to);
- return *this;
- }
-
- /* Common input/output boilerplate. */
- ShaderGraphBuilder& add_attribute(const string &name)
- {
- return (*this)
- .add_node(ShaderNodeBuilder<AttributeNode>(name)
- .set(&AttributeNode::attribute, ustring(name)));
- }
-
- ShaderGraphBuilder& output_closure(const string& from)
- {
- return (*this).add_connection(from, "Output::Surface");
- }
-
- ShaderGraphBuilder& output_color(const string& from)
- {
- return (*this)
- .add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
- .add_connection(from, "EmissionNode::Color")
- .output_closure("EmissionNode::Emission");
- }
-
- ShaderGraphBuilder& output_value(const string& from)
- {
- return (*this)
- .add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
- .add_connection(from, "EmissionNode::Strength")
- .output_closure("EmissionNode::Emission");
- }
-
-protected:
- ShaderGraph *graph_;
- map<string, ShaderNode *> node_map_;
+ public:
+ ShaderGraphBuilder(ShaderGraph *graph) : graph_(graph)
+ {
+ node_map_["Output"] = graph->output();
+ }
+
+ ShaderNode *find_node(const string &name)
+ {
+ map<string, ShaderNode *>::iterator it = node_map_.find(name);
+ if (it == node_map_.end()) {
+ return NULL;
+ }
+ return it->second;
+ }
+
+ template<typename T> ShaderGraphBuilder &add_node(const T &node)
+ {
+ EXPECT_EQ(find_node(node.name()), (void *)NULL);
+ graph_->add(node.node());
+ node_map_[node.name()] = node.node();
+ return *this;
+ }
+
+ ShaderGraphBuilder &add_connection(const string &from, const string &to)
+ {
+ vector<string> tokens_from, tokens_to;
+ string_split(tokens_from, from, "::");
+ string_split(tokens_to, to, "::");
+ EXPECT_EQ(tokens_from.size(), 2);
+ EXPECT_EQ(tokens_to.size(), 2);
+ ShaderNode *node_from = find_node(tokens_from[0]), *node_to = find_node(tokens_to[0]);
+ EXPECT_NE((void *)NULL, node_from);
+ EXPECT_NE((void *)NULL, node_to);
+ EXPECT_NE(node_from, node_to);
+ ShaderOutput *socket_from = node_from->output(tokens_from[1].c_str());
+ ShaderInput *socket_to = node_to->input(tokens_to[1].c_str());
+ EXPECT_NE((void *)NULL, socket_from);
+ EXPECT_NE((void *)NULL, socket_to);
+ graph_->connect(socket_from, socket_to);
+ return *this;
+ }
+
+ /* Common input/output boilerplate. */
+ ShaderGraphBuilder &add_attribute(const string &name)
+ {
+ return (*this).add_node(
+ ShaderNodeBuilder<AttributeNode>(name).set(&AttributeNode::attribute, ustring(name)));
+ }
+
+ ShaderGraphBuilder &output_closure(const string &from)
+ {
+ return (*this).add_connection(from, "Output::Surface");
+ }
+
+ ShaderGraphBuilder &output_color(const string &from)
+ {
+ return (*this)
+ .add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
+ .add_connection(from, "EmissionNode::Color")
+ .output_closure("EmissionNode::Emission");
+ }
+
+ ShaderGraphBuilder &output_value(const string &from)
+ {
+ return (*this)
+ .add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
+ .add_connection(from, "EmissionNode::Strength")
+ .output_closure("EmissionNode::Emission");
+ }
+
+ protected:
+ ShaderGraph *graph_;
+ map<string, ShaderNode *> node_map_;
};
} // namespace
-class RenderGraph : public testing::Test
-{
-protected:
- ScopedMockLog log;
- Stats stats;
- Profiler profiler;
- DeviceInfo device_info;
- Device *device_cpu;
- SceneParams scene_params;
- Scene *scene;
- ShaderGraph graph;
- ShaderGraphBuilder builder;
-
- RenderGraph()
- : testing::Test(),
- builder(&graph)
- {
- }
-
- virtual void SetUp()
- {
- util_logging_start();
- util_logging_verbosity_set(1);
-
- device_cpu = Device::create(device_info, stats, profiler, true);
- scene = new Scene(scene_params, device_cpu);
- }
-
- virtual void TearDown()
- {
- delete scene;
- delete device_cpu;
- }
+class RenderGraph : public testing::Test {
+ protected:
+ ScopedMockLog log;
+ Stats stats;
+ Profiler profiler;
+ DeviceInfo device_info;
+ Device *device_cpu;
+ SceneParams scene_params;
+ Scene *scene;
+ ShaderGraph graph;
+ ShaderGraphBuilder builder;
+
+ RenderGraph() : testing::Test(), builder(&graph)
+ {
+ }
+
+ virtual void SetUp()
+ {
+ util_logging_start();
+ util_logging_verbosity_set(1);
+
+ device_cpu = Device::create(device_info, stats, profiler, true);
+ scene = new Scene(scene_params, device_cpu);
+ }
+
+ virtual void TearDown()
+ {
+ delete scene;
+ delete device_cpu;
+ }
};
-#define EXPECT_ANY_MESSAGE(log) \
- EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber()); \
+#define EXPECT_ANY_MESSAGE(log) EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
#define CORRECT_INFO_MESSAGE(log, message) \
- EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message)));
+ EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message)));
#define INVALID_INFO_MESSAGE(log, message) \
- EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message))).Times(0);
+ EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message))).Times(0);
/*
* Test deduplication of nodes that have inputs, some of them folded.
*/
TEST_F(RenderGraph, deduplicate_deep)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Value1::Value to constant (0.8).");
- CORRECT_INFO_MESSAGE(log, "Folding Value2::Value to constant (0.8).");
- CORRECT_INFO_MESSAGE(log, "Deduplicated 2 nodes.");
-
- builder
- .add_node(ShaderNodeBuilder<GeometryNode>("Geometry1"))
- .add_node(ShaderNodeBuilder<GeometryNode>("Geometry2"))
- .add_node(ShaderNodeBuilder<ValueNode>("Value1")
- .set(&ValueNode::value, 0.8f))
- .add_node(ShaderNodeBuilder<ValueNode>("Value2")
- .set(&ValueNode::value, 0.8f))
- .add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise1"))
- .add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise2"))
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_BLEND)
- .set("Fac", 0.5f))
- .add_connection("Geometry1::Parametric", "Noise1::Vector")
- .add_connection("Value1::Value", "Noise1::Scale")
- .add_connection("Noise1::Color", "Mix::Color1")
- .add_connection("Geometry2::Parametric", "Noise2::Vector")
- .add_connection("Value2::Value", "Noise2::Scale")
- .add_connection("Noise2::Color", "Mix::Color2")
- .output_color("Mix::Color");
-
- graph.finalize(scene);
-
- EXPECT_EQ(graph.nodes.size(), 5);
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Value1::Value to constant (0.8).");
+ CORRECT_INFO_MESSAGE(log, "Folding Value2::Value to constant (0.8).");
+ CORRECT_INFO_MESSAGE(log, "Deduplicated 2 nodes.");
+
+ builder.add_node(ShaderNodeBuilder<GeometryNode>("Geometry1"))
+ .add_node(ShaderNodeBuilder<GeometryNode>("Geometry2"))
+ .add_node(ShaderNodeBuilder<ValueNode>("Value1").set(&ValueNode::value, 0.8f))
+ .add_node(ShaderNodeBuilder<ValueNode>("Value2").set(&ValueNode::value, 0.8f))
+ .add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise1"))
+ .add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise2"))
+ .add_node(
+ ShaderNodeBuilder<MixNode>("Mix").set(&MixNode::type, NODE_MIX_BLEND).set("Fac", 0.5f))
+ .add_connection("Geometry1::Parametric", "Noise1::Vector")
+ .add_connection("Value1::Value", "Noise1::Scale")
+ .add_connection("Noise1::Color", "Mix::Color1")
+ .add_connection("Geometry2::Parametric", "Noise2::Vector")
+ .add_connection("Value2::Value", "Noise2::Scale")
+ .add_connection("Noise2::Color", "Mix::Color2")
+ .output_color("Mix::Color");
+
+ graph.finalize(scene);
+
+ EXPECT_EQ(graph.nodes.size(), 5);
}
/*
@@ -240,16 +225,17 @@ TEST_F(RenderGraph, deduplicate_deep)
*/
TEST_F(RenderGraph, constant_fold_rgb_to_bw)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding RGBToBWNodeNode::Val to constant (0.8).");
- CORRECT_INFO_MESSAGE(log, "Folding convert_float_to_color::value_color to constant (0.8, 0.8, 0.8).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding RGBToBWNodeNode::Val to constant (0.8).");
+ CORRECT_INFO_MESSAGE(log,
+ "Folding convert_float_to_color::value_color to constant (0.8, 0.8, 0.8).");
- builder
- .add_node(ShaderNodeBuilder<RGBToBWNode>("RGBToBWNodeNode")
- .set("Color", make_float3(0.8f, 0.8f, 0.8f)))
- .output_color("RGBToBWNodeNode::Val");
+ builder
+ .add_node(ShaderNodeBuilder<RGBToBWNode>("RGBToBWNodeNode")
+ .set("Color", make_float3(0.8f, 0.8f, 0.8f)))
+ .output_color("RGBToBWNodeNode::Val");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -258,28 +244,26 @@ TEST_F(RenderGraph, constant_fold_rgb_to_bw)
*/
TEST_F(RenderGraph, constant_fold_emission1)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
- builder
- .add_node(ShaderNodeBuilder<EmissionNode>("Emission")
- .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
- .output_closure("Emission::Emission");
+ builder
+ .add_node(
+ ShaderNodeBuilder<EmissionNode>("Emission").set("Color", make_float3(0.0f, 0.0f, 0.0f)))
+ .output_closure("Emission::Emission");
- graph.finalize(scene);
+ graph.finalize(scene);
}
TEST_F(RenderGraph, constant_fold_emission2)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
- builder
- .add_node(ShaderNodeBuilder<EmissionNode>("Emission")
- .set("Strength", 0.0f))
- .output_closure("Emission::Emission");
+ builder.add_node(ShaderNodeBuilder<EmissionNode>("Emission").set("Strength", 0.0f))
+ .output_closure("Emission::Emission");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -288,28 +272,26 @@ TEST_F(RenderGraph, constant_fold_emission2)
*/
TEST_F(RenderGraph, constant_fold_background1)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
- builder
- .add_node(ShaderNodeBuilder<BackgroundNode>("Background")
- .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
- .output_closure("Background::Background");
+ builder
+ .add_node(ShaderNodeBuilder<BackgroundNode>("Background")
+ .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
+ .output_closure("Background::Background");
- graph.finalize(scene);
+ graph.finalize(scene);
}
TEST_F(RenderGraph, constant_fold_background2)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
- builder
- .add_node(ShaderNodeBuilder<BackgroundNode>("Background")
- .set("Strength", 0.0f))
- .output_closure("Background::Background");
+ builder.add_node(ShaderNodeBuilder<BackgroundNode>("Background").set("Strength", 0.0f))
+ .output_closure("Background::Background");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -318,23 +300,22 @@ TEST_F(RenderGraph, constant_fold_background2)
*/
TEST_F(RenderGraph, constant_fold_shader_add)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding AddClosure1::Closure to socket Diffuse::BSDF.");
- CORRECT_INFO_MESSAGE(log, "Folding AddClosure2::Closure to socket Diffuse::BSDF.");
- INVALID_INFO_MESSAGE(log, "Folding AddClosure3");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding AddClosure1::Closure to socket Diffuse::BSDF.");
+ CORRECT_INFO_MESSAGE(log, "Folding AddClosure2::Closure to socket Diffuse::BSDF.");
+ INVALID_INFO_MESSAGE(log, "Folding AddClosure3");
- builder
- .add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
- .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure1"))
- .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure2"))
- .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure3"))
- .add_connection("Diffuse::BSDF", "AddClosure1::Closure1")
- .add_connection("Diffuse::BSDF", "AddClosure2::Closure2")
- .add_connection("AddClosure1::Closure", "AddClosure3::Closure1")
- .add_connection("AddClosure2::Closure", "AddClosure3::Closure2")
- .output_closure("AddClosure3::Closure");
+ builder.add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
+ .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure1"))
+ .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure2"))
+ .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure3"))
+ .add_connection("Diffuse::BSDF", "AddClosure1::Closure1")
+ .add_connection("Diffuse::BSDF", "AddClosure2::Closure2")
+ .add_connection("AddClosure1::Closure", "AddClosure3::Closure1")
+ .add_connection("AddClosure2::Closure", "AddClosure3::Closure2")
+ .output_closure("AddClosure3::Closure");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -344,30 +325,27 @@ TEST_F(RenderGraph, constant_fold_shader_add)
*/
TEST_F(RenderGraph, constant_fold_shader_mix)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding MixClosure1::Closure to socket Diffuse::BSDF.");
- CORRECT_INFO_MESSAGE(log, "Folding MixClosure2::Closure to socket Diffuse::BSDF.");
- CORRECT_INFO_MESSAGE(log, "Folding MixClosure3::Closure to socket Diffuse::BSDF.");
-
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
- /* choose left */
- .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure1")
- .set("Fac", 0.0f))
- .add_connection("Diffuse::BSDF", "MixClosure1::Closure1")
- /* choose right */
- .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure2")
- .set("Fac", 1.0f))
- .add_connection("Diffuse::BSDF", "MixClosure2::Closure2")
- /* both inputs folded the same */
- .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure3"))
- .add_connection("Attribute::Fac", "MixClosure3::Fac")
- .add_connection("MixClosure1::Closure", "MixClosure3::Closure1")
- .add_connection("MixClosure2::Closure", "MixClosure3::Closure2")
- .output_closure("MixClosure3::Closure");
-
- graph.finalize(scene);
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding MixClosure1::Closure to socket Diffuse::BSDF.");
+ CORRECT_INFO_MESSAGE(log, "Folding MixClosure2::Closure to socket Diffuse::BSDF.");
+ CORRECT_INFO_MESSAGE(log, "Folding MixClosure3::Closure to socket Diffuse::BSDF.");
+
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
+ /* choose left */
+ .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure1").set("Fac", 0.0f))
+ .add_connection("Diffuse::BSDF", "MixClosure1::Closure1")
+ /* choose right */
+ .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure2").set("Fac", 1.0f))
+ .add_connection("Diffuse::BSDF", "MixClosure2::Closure2")
+ /* both inputs folded the same */
+ .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure3"))
+ .add_connection("Attribute::Fac", "MixClosure3::Fac")
+ .add_connection("MixClosure1::Closure", "MixClosure3::Closure1")
+ .add_connection("MixClosure2::Closure", "MixClosure3::Closure2")
+ .output_closure("MixClosure3::Closure");
+
+ graph.finalize(scene);
}
/*
@@ -376,16 +354,16 @@ TEST_F(RenderGraph, constant_fold_shader_mix)
*/
TEST_F(RenderGraph, constant_fold_invert)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to constant (0.68, 0.5, 0.32).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to constant (0.68, 0.5, 0.32).");
- builder
- .add_node(ShaderNodeBuilder<InvertNode>("Invert")
- .set("Fac", 0.8f)
- .set("Color", make_float3(0.2f, 0.5f, 0.8f)))
- .output_color("Invert::Color");
+ builder
+ .add_node(ShaderNodeBuilder<InvertNode>("Invert")
+ .set("Fac", 0.8f)
+ .set("Color", make_float3(0.2f, 0.5f, 0.8f)))
+ .output_color("Invert::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -394,17 +372,15 @@ TEST_F(RenderGraph, constant_fold_invert)
*/
TEST_F(RenderGraph, constant_fold_invert_fac_0)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to socket Attribute::Color.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to socket Attribute::Color.");
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<InvertNode>("Invert")
- .set("Fac", 0.0f))
- .add_connection("Attribute::Color", "Invert::Color")
- .output_color("Invert::Color");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<InvertNode>("Invert").set("Fac", 0.0f))
+ .add_connection("Attribute::Color", "Invert::Color")
+ .output_color("Invert::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -413,16 +389,16 @@ TEST_F(RenderGraph, constant_fold_invert_fac_0)
*/
TEST_F(RenderGraph, constant_fold_invert_fac_0_const)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to constant (0.2, 0.5, 0.8).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to constant (0.2, 0.5, 0.8).");
- builder
- .add_node(ShaderNodeBuilder<InvertNode>("Invert")
- .set("Fac", 0.0f)
- .set("Color", make_float3(0.2f, 0.5f, 0.8f)))
- .output_color("Invert::Color");
+ builder
+ .add_node(ShaderNodeBuilder<InvertNode>("Invert")
+ .set("Fac", 0.0f)
+ .set("Color", make_float3(0.2f, 0.5f, 0.8f)))
+ .output_color("Invert::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -431,19 +407,19 @@ TEST_F(RenderGraph, constant_fold_invert_fac_0_const)
*/
TEST_F(RenderGraph, constant_fold_mix_add)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding MixAdd::Color to constant (0.62, 1.14, 1.42).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding MixAdd::Color to constant (0.62, 1.14, 1.42).");
- builder
- .add_node(ShaderNodeBuilder<MixNode>("MixAdd")
- .set(&MixNode::type, NODE_MIX_ADD)
- .set(&MixNode::use_clamp, false)
- .set("Fac", 0.8f)
- .set("Color1", make_float3(0.3, 0.5, 0.7))
- .set("Color2", make_float3(0.4, 0.8, 0.9)))
- .output_color("MixAdd::Color");
+ builder
+ .add_node(ShaderNodeBuilder<MixNode>("MixAdd")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, false)
+ .set("Fac", 0.8f)
+ .set("Color1", make_float3(0.3, 0.5, 0.7))
+ .set("Color2", make_float3(0.4, 0.8, 0.9)))
+ .output_color("MixAdd::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -452,19 +428,19 @@ TEST_F(RenderGraph, constant_fold_mix_add)
*/
TEST_F(RenderGraph, constant_fold_mix_add_clamp)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding MixAdd::Color to constant (0.62, 1, 1).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding MixAdd::Color to constant (0.62, 1, 1).");
- builder
- .add_node(ShaderNodeBuilder<MixNode>("MixAdd")
- .set(&MixNode::type, NODE_MIX_ADD)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 0.8f)
- .set("Color1", make_float3(0.3, 0.5, 0.7))
- .set("Color2", make_float3(0.4, 0.8, 0.9)))
- .output_color("MixAdd::Color");
+ builder
+ .add_node(ShaderNodeBuilder<MixNode>("MixAdd")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 0.8f)
+ .set("Color1", make_float3(0.3, 0.5, 0.7))
+ .set("Color2", make_float3(0.4, 0.8, 0.9)))
+ .output_color("MixAdd::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -473,21 +449,20 @@ TEST_F(RenderGraph, constant_fold_mix_add_clamp)
*/
TEST_F(RenderGraph, constant_fold_part_mix_dodge_no_fac_0)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding ");
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding ");
- builder
- .add_attribute("Attribute1")
- .add_attribute("Attribute2")
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_DODGE)
- .set(&MixNode::use_clamp, false)
- .set("Fac", 0.0f))
- .add_connection("Attribute1::Color", "Mix::Color1")
- .add_connection("Attribute2::Color", "Mix::Color2")
- .output_color("Mix::Color");
+ builder.add_attribute("Attribute1")
+ .add_attribute("Attribute2")
+ .add_node(ShaderNodeBuilder<MixNode>("Mix")
+ .set(&MixNode::type, NODE_MIX_DODGE)
+ .set(&MixNode::use_clamp, false)
+ .set("Fac", 0.0f))
+ .add_connection("Attribute1::Color", "Mix::Color1")
+ .add_connection("Attribute2::Color", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -496,21 +471,20 @@ TEST_F(RenderGraph, constant_fold_part_mix_dodge_no_fac_0)
*/
TEST_F(RenderGraph, constant_fold_part_mix_light_no_fac_0)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding ");
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding ");
- builder
- .add_attribute("Attribute1")
- .add_attribute("Attribute2")
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_LIGHT)
- .set(&MixNode::use_clamp, false)
- .set("Fac", 0.0f))
- .add_connection("Attribute1::Color", "Mix::Color1")
- .add_connection("Attribute2::Color", "Mix::Color2")
- .output_color("Mix::Color");
+ builder.add_attribute("Attribute1")
+ .add_attribute("Attribute2")
+ .add_node(ShaderNodeBuilder<MixNode>("Mix")
+ .set(&MixNode::type, NODE_MIX_LIGHT)
+ .set(&MixNode::use_clamp, false)
+ .set("Fac", 0.0f))
+ .add_connection("Attribute1::Color", "Mix::Color1")
+ .add_connection("Attribute2::Color", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -519,21 +493,20 @@ TEST_F(RenderGraph, constant_fold_part_mix_light_no_fac_0)
*/
TEST_F(RenderGraph, constant_fold_part_mix_burn_no_fac_0)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding ");
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding ");
- builder
- .add_attribute("Attribute1")
- .add_attribute("Attribute2")
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_BURN)
- .set(&MixNode::use_clamp, false)
- .set("Fac", 0.0f))
- .add_connection("Attribute1::Color", "Mix::Color1")
- .add_connection("Attribute2::Color", "Mix::Color2")
- .output_color("Mix::Color");
+ builder.add_attribute("Attribute1")
+ .add_attribute("Attribute2")
+ .add_node(ShaderNodeBuilder<MixNode>("Mix")
+ .set(&MixNode::type, NODE_MIX_BURN)
+ .set(&MixNode::use_clamp, false)
+ .set("Fac", 0.0f))
+ .add_connection("Attribute1::Color", "Mix::Color1")
+ .add_connection("Attribute2::Color", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -542,21 +515,20 @@ TEST_F(RenderGraph, constant_fold_part_mix_burn_no_fac_0)
*/
TEST_F(RenderGraph, constant_fold_part_mix_blend_clamped_no_fac_0)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding ");
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding ");
- builder
- .add_attribute("Attribute1")
- .add_attribute("Attribute2")
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_BLEND)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 0.0f))
- .add_connection("Attribute1::Color", "Mix::Color1")
- .add_connection("Attribute2::Color", "Mix::Color2")
- .output_color("Mix::Color");
+ builder.add_attribute("Attribute1")
+ .add_attribute("Attribute2")
+ .add_node(ShaderNodeBuilder<MixNode>("Mix")
+ .set(&MixNode::type, NODE_MIX_BLEND)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 0.0f))
+ .add_connection("Attribute1::Color", "Mix::Color1")
+ .add_connection("Attribute2::Color", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -566,38 +538,37 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend_clamped_no_fac_0)
*/
TEST_F(RenderGraph, constant_fold_part_mix_blend)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding MixBlend1::Color to socket Attribute1::Color.");
- CORRECT_INFO_MESSAGE(log, "Folding MixBlend2::Color to socket Attribute1::Color.");
- CORRECT_INFO_MESSAGE(log, "Folding MixBlend3::Color to socket Attribute1::Color.");
-
- builder
- .add_attribute("Attribute1")
- .add_attribute("Attribute2")
- /* choose left */
- .add_node(ShaderNodeBuilder<MixNode>("MixBlend1")
- .set(&MixNode::type, NODE_MIX_BLEND)
- .set(&MixNode::use_clamp, false)
- .set("Fac", 0.0f))
- .add_connection("Attribute1::Color", "MixBlend1::Color1")
- .add_connection("Attribute2::Color", "MixBlend1::Color2")
- /* choose right */
- .add_node(ShaderNodeBuilder<MixNode>("MixBlend2")
- .set(&MixNode::type, NODE_MIX_BLEND)
- .set(&MixNode::use_clamp, false)
- .set("Fac", 1.0f))
- .add_connection("Attribute1::Color", "MixBlend2::Color2")
- .add_connection("Attribute2::Color", "MixBlend2::Color1")
- /* both inputs folded to Attribute1 */
- .add_node(ShaderNodeBuilder<MixNode>("MixBlend3")
- .set(&MixNode::type, NODE_MIX_BLEND)
- .set(&MixNode::use_clamp, false))
- .add_connection("Attribute1::Fac", "MixBlend3::Fac")
- .add_connection("MixBlend1::Color", "MixBlend3::Color1")
- .add_connection("MixBlend2::Color", "MixBlend3::Color2")
- .output_color("MixBlend3::Color");
-
- graph.finalize(scene);
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding MixBlend1::Color to socket Attribute1::Color.");
+ CORRECT_INFO_MESSAGE(log, "Folding MixBlend2::Color to socket Attribute1::Color.");
+ CORRECT_INFO_MESSAGE(log, "Folding MixBlend3::Color to socket Attribute1::Color.");
+
+ builder.add_attribute("Attribute1")
+ .add_attribute("Attribute2")
+ /* choose left */
+ .add_node(ShaderNodeBuilder<MixNode>("MixBlend1")
+ .set(&MixNode::type, NODE_MIX_BLEND)
+ .set(&MixNode::use_clamp, false)
+ .set("Fac", 0.0f))
+ .add_connection("Attribute1::Color", "MixBlend1::Color1")
+ .add_connection("Attribute2::Color", "MixBlend1::Color2")
+ /* choose right */
+ .add_node(ShaderNodeBuilder<MixNode>("MixBlend2")
+ .set(&MixNode::type, NODE_MIX_BLEND)
+ .set(&MixNode::use_clamp, false)
+ .set("Fac", 1.0f))
+ .add_connection("Attribute1::Color", "MixBlend2::Color2")
+ .add_connection("Attribute2::Color", "MixBlend2::Color1")
+ /* both inputs folded to Attribute1 */
+ .add_node(ShaderNodeBuilder<MixNode>("MixBlend3")
+ .set(&MixNode::type, NODE_MIX_BLEND)
+ .set(&MixNode::use_clamp, false))
+ .add_connection("Attribute1::Fac", "MixBlend3::Fac")
+ .add_connection("MixBlend1::Color", "MixBlend3::Color1")
+ .add_connection("MixBlend2::Color", "MixBlend3::Color2")
+ .output_color("MixBlend3::Color");
+
+ graph.finalize(scene);
}
/*
@@ -606,20 +577,19 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend)
*/
TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_bad)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding Mix::");
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding Mix::");
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_SUB)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 0.5f))
- .add_connection("Attribute::Color", "Mix::Color1")
- .add_connection("Attribute::Color", "Mix::Color2")
- .output_color("Mix::Color");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<MixNode>("Mix")
+ .set(&MixNode::type, NODE_MIX_SUB)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 0.5f))
+ .add_connection("Attribute::Color", "Mix::Color1")
+ .add_connection("Attribute::Color", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -628,76 +598,77 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_bad)
*/
TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_1)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Mix::Color to constant (0, 0, 0).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Mix::Color to constant (0, 0, 0).");
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_SUB)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 1.0f))
- .add_connection("Attribute::Color", "Mix::Color1")
- .add_connection("Attribute::Color", "Mix::Color2")
- .output_color("Mix::Color");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<MixNode>("Mix")
+ .set(&MixNode::type, NODE_MIX_SUB)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_connection("Attribute::Color", "Mix::Color1")
+ .add_connection("Attribute::Color", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
* Graph for testing partial folds of MixRGB with one constant argument.
* Includes 4 tests: constant on each side with fac either unknown or 1.
*/
-static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, NodeMix type, float3 constval)
-{
- builder
- .add_attribute("Attribute")
- /* constant on the left */
- .add_node(ShaderNodeBuilder<MixNode>("Mix_Cx_Fx")
- .set(&MixNode::type, type)
- .set(&MixNode::use_clamp, false)
- .set("Color1", constval))
- .add_node(ShaderNodeBuilder<MixNode>("Mix_Cx_F1")
- .set(&MixNode::type, type)
- .set(&MixNode::use_clamp, false)
- .set("Color1", constval)
- .set("Fac", 1.0f))
- .add_connection("Attribute::Fac", "Mix_Cx_Fx::Fac")
- .add_connection("Attribute::Color", "Mix_Cx_Fx::Color2")
- .add_connection("Attribute::Color", "Mix_Cx_F1::Color2")
- /* constant on the right */
- .add_node(ShaderNodeBuilder<MixNode>("Mix_xC_Fx")
- .set(&MixNode::type, type)
- .set(&MixNode::use_clamp, false)
- .set("Color2", constval))
- .add_node(ShaderNodeBuilder<MixNode>("Mix_xC_F1")
- .set(&MixNode::type, type)
- .set(&MixNode::use_clamp, false)
- .set("Color2", constval)
- .set("Fac", 1.0f))
- .add_connection("Attribute::Fac", "Mix_xC_Fx::Fac")
- .add_connection("Attribute::Color", "Mix_xC_Fx::Color1")
- .add_connection("Attribute::Color", "Mix_xC_F1::Color1")
- /* results of actual tests simply added up to connect to output */
- .add_node(ShaderNodeBuilder<MixNode>("Out12")
- .set(&MixNode::type, NODE_MIX_ADD)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 1.0f))
- .add_node(ShaderNodeBuilder<MixNode>("Out34")
- .set(&MixNode::type, NODE_MIX_ADD)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 1.0f))
- .add_node(ShaderNodeBuilder<MixNode>("Out1234")
- .set(&MixNode::type, NODE_MIX_ADD)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 1.0f))
- .add_connection("Mix_Cx_Fx::Color", "Out12::Color1")
- .add_connection("Mix_Cx_F1::Color", "Out12::Color2")
- .add_connection("Mix_xC_Fx::Color", "Out34::Color1")
- .add_connection("Mix_xC_F1::Color", "Out34::Color2")
- .add_connection("Out12::Color", "Out1234::Color1")
- .add_connection("Out34::Color", "Out1234::Color2")
- .output_color("Out1234::Color");
+static void build_mix_partial_test_graph(ShaderGraphBuilder &builder,
+ NodeMix type,
+ float3 constval)
+{
+ builder
+ .add_attribute("Attribute")
+ /* constant on the left */
+ .add_node(ShaderNodeBuilder<MixNode>("Mix_Cx_Fx")
+ .set(&MixNode::type, type)
+ .set(&MixNode::use_clamp, false)
+ .set("Color1", constval))
+ .add_node(ShaderNodeBuilder<MixNode>("Mix_Cx_F1")
+ .set(&MixNode::type, type)
+ .set(&MixNode::use_clamp, false)
+ .set("Color1", constval)
+ .set("Fac", 1.0f))
+ .add_connection("Attribute::Fac", "Mix_Cx_Fx::Fac")
+ .add_connection("Attribute::Color", "Mix_Cx_Fx::Color2")
+ .add_connection("Attribute::Color", "Mix_Cx_F1::Color2")
+ /* constant on the right */
+ .add_node(ShaderNodeBuilder<MixNode>("Mix_xC_Fx")
+ .set(&MixNode::type, type)
+ .set(&MixNode::use_clamp, false)
+ .set("Color2", constval))
+ .add_node(ShaderNodeBuilder<MixNode>("Mix_xC_F1")
+ .set(&MixNode::type, type)
+ .set(&MixNode::use_clamp, false)
+ .set("Color2", constval)
+ .set("Fac", 1.0f))
+ .add_connection("Attribute::Fac", "Mix_xC_Fx::Fac")
+ .add_connection("Attribute::Color", "Mix_xC_Fx::Color1")
+ .add_connection("Attribute::Color", "Mix_xC_F1::Color1")
+ /* results of actual tests simply added up to connect to output */
+ .add_node(ShaderNodeBuilder<MixNode>("Out12")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_node(ShaderNodeBuilder<MixNode>("Out34")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_node(ShaderNodeBuilder<MixNode>("Out1234")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_connection("Mix_Cx_Fx::Color", "Out12::Color1")
+ .add_connection("Mix_Cx_F1::Color", "Out12::Color2")
+ .add_connection("Mix_xC_Fx::Color", "Out34::Color1")
+ .add_connection("Mix_xC_F1::Color", "Out34::Color2")
+ .add_connection("Out12::Color", "Out1234::Color1")
+ .add_connection("Out34::Color", "Out1234::Color2")
+ .output_color("Out1234::Color");
}
/*
@@ -705,17 +676,17 @@ static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, NodeMix ty
*/
TEST_F(RenderGraph, constant_fold_part_mix_add_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* 0 + X (fac 1) == X */
- INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to socket Attribute::Color.");
- /* X + 0 (fac ?) == X */
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
- INVALID_INFO_MESSAGE(log, "Folding Out");
+ EXPECT_ANY_MESSAGE(log);
+ /* 0 + X (fac 1) == X */
+ INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to socket Attribute::Color.");
+ /* X + 0 (fac ?) == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
+ INVALID_INFO_MESSAGE(log, "Folding Out");
- build_mix_partial_test_graph(builder, NODE_MIX_ADD, make_float3(0, 0, 0));
- graph.finalize(scene);
+ build_mix_partial_test_graph(builder, NODE_MIX_ADD, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -723,16 +694,16 @@ TEST_F(RenderGraph, constant_fold_part_mix_add_0)
*/
TEST_F(RenderGraph, constant_fold_part_mix_sub_0)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
- INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color");
- /* X - 0 (fac ?) == X */
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
- INVALID_INFO_MESSAGE(log, "Folding Out");
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
+ INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color");
+ /* X - 0 (fac ?) == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
+ INVALID_INFO_MESSAGE(log, "Folding Out");
- build_mix_partial_test_graph(builder, NODE_MIX_SUB, make_float3(0, 0, 0));
- graph.finalize(scene);
+ build_mix_partial_test_graph(builder, NODE_MIX_SUB, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -740,17 +711,17 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_0)
*/
TEST_F(RenderGraph, constant_fold_part_mix_mul_1)
{
- EXPECT_ANY_MESSAGE(log);
- /* 1 * X (fac 1) == X */
- INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to socket Attribute::Color.");
- /* X * 1 (fac ?) == X */
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
- INVALID_INFO_MESSAGE(log, "Folding Out");
+ EXPECT_ANY_MESSAGE(log);
+ /* 1 * X (fac 1) == X */
+ INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to socket Attribute::Color.");
+ /* X * 1 (fac ?) == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
+ INVALID_INFO_MESSAGE(log, "Folding Out");
- build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(1, 1, 1));
- graph.finalize(scene);
+ build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(1, 1, 1));
+ graph.finalize(scene);
}
/*
@@ -758,16 +729,16 @@ TEST_F(RenderGraph, constant_fold_part_mix_mul_1)
*/
TEST_F(RenderGraph, constant_fold_part_mix_div_1)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
- INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color");
- /* X / 1 (fac ?) == X */
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
- INVALID_INFO_MESSAGE(log, "Folding Out");
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
+ INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color");
+ /* X / 1 (fac ?) == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
+ INVALID_INFO_MESSAGE(log, "Folding Out");
- build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(1, 1, 1));
- graph.finalize(scene);
+ build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(1, 1, 1));
+ graph.finalize(scene);
}
/*
@@ -775,19 +746,19 @@ TEST_F(RenderGraph, constant_fold_part_mix_div_1)
*/
TEST_F(RenderGraph, constant_fold_part_mix_mul_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* 0 * ? (fac ?) == 0 */
- CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to constant (0, 0, 0).");
- /* ? * 0 (fac 1) == 0 */
- INVALID_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to constant (0, 0, 0).");
+ EXPECT_ANY_MESSAGE(log);
+ /* 0 * ? (fac ?) == 0 */
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to constant (0, 0, 0).");
+ /* ? * 0 (fac 1) == 0 */
+ INVALID_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding Out12::Color to constant (0, 0, 0).");
- INVALID_INFO_MESSAGE(log, "Folding Out1234");
+ CORRECT_INFO_MESSAGE(log, "Folding Out12::Color to constant (0, 0, 0).");
+ INVALID_INFO_MESSAGE(log, "Folding Out1234");
- build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(0, 0, 0));
- graph.finalize(scene);
+ build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -795,18 +766,18 @@ TEST_F(RenderGraph, constant_fold_part_mix_mul_0)
*/
TEST_F(RenderGraph, constant_fold_part_mix_div_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* 0 / ? (fac ?) == 0 */
- CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to constant (0, 0, 0).");
- INVALID_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color");
- INVALID_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color");
+ EXPECT_ANY_MESSAGE(log);
+ /* 0 / ? (fac ?) == 0 */
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to constant (0, 0, 0).");
+ INVALID_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color");
+ INVALID_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color");
- CORRECT_INFO_MESSAGE(log, "Folding Out12::Color to constant (0, 0, 0).");
- INVALID_INFO_MESSAGE(log, "Folding Out1234");
+ CORRECT_INFO_MESSAGE(log, "Folding Out12::Color to constant (0, 0, 0).");
+ INVALID_INFO_MESSAGE(log, "Folding Out1234");
- build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(0, 0, 0));
- graph.finalize(scene);
+ build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -814,22 +785,22 @@ TEST_F(RenderGraph, constant_fold_part_mix_div_0)
*/
TEST_F(RenderGraph, constant_fold_separate_combine_rgb)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::R to constant (0.3).");
- CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::G to constant (0.5).");
- CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::B to constant (0.7).");
- CORRECT_INFO_MESSAGE(log, "Folding CombineRGB::Image to constant (0.3, 0.5, 0.7).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::R to constant (0.3).");
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::G to constant (0.5).");
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::B to constant (0.7).");
+ CORRECT_INFO_MESSAGE(log, "Folding CombineRGB::Image to constant (0.3, 0.5, 0.7).");
- builder
- .add_node(ShaderNodeBuilder<SeparateRGBNode>("SeparateRGB")
- .set("Image", make_float3(0.3f, 0.5f, 0.7f)))
- .add_node(ShaderNodeBuilder<CombineRGBNode>("CombineRGB"))
- .add_connection("SeparateRGB::R", "CombineRGB::R")
- .add_connection("SeparateRGB::G", "CombineRGB::G")
- .add_connection("SeparateRGB::B", "CombineRGB::B")
- .output_color("CombineRGB::Image");
+ builder
+ .add_node(ShaderNodeBuilder<SeparateRGBNode>("SeparateRGB")
+ .set("Image", make_float3(0.3f, 0.5f, 0.7f)))
+ .add_node(ShaderNodeBuilder<CombineRGBNode>("CombineRGB"))
+ .add_connection("SeparateRGB::R", "CombineRGB::R")
+ .add_connection("SeparateRGB::G", "CombineRGB::G")
+ .add_connection("SeparateRGB::B", "CombineRGB::B")
+ .output_color("CombineRGB::Image");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -837,23 +808,24 @@ TEST_F(RenderGraph, constant_fold_separate_combine_rgb)
*/
TEST_F(RenderGraph, constant_fold_separate_combine_xyz)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::X to constant (0.3).");
- CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::Y to constant (0.5).");
- CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::Z to constant (0.7).");
- CORRECT_INFO_MESSAGE(log, "Folding CombineXYZ::Vector to constant (0.3, 0.5, 0.7).");
- CORRECT_INFO_MESSAGE(log, "Folding convert_vector_to_color::value_color to constant (0.3, 0.5, 0.7).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::X to constant (0.3).");
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::Y to constant (0.5).");
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::Z to constant (0.7).");
+ CORRECT_INFO_MESSAGE(log, "Folding CombineXYZ::Vector to constant (0.3, 0.5, 0.7).");
+ CORRECT_INFO_MESSAGE(
+ log, "Folding convert_vector_to_color::value_color to constant (0.3, 0.5, 0.7).");
- builder
- .add_node(ShaderNodeBuilder<SeparateXYZNode>("SeparateXYZ")
- .set("Vector", make_float3(0.3f, 0.5f, 0.7f)))
- .add_node(ShaderNodeBuilder<CombineXYZNode>("CombineXYZ"))
- .add_connection("SeparateXYZ::X", "CombineXYZ::X")
- .add_connection("SeparateXYZ::Y", "CombineXYZ::Y")
- .add_connection("SeparateXYZ::Z", "CombineXYZ::Z")
- .output_color("CombineXYZ::Vector");
+ builder
+ .add_node(ShaderNodeBuilder<SeparateXYZNode>("SeparateXYZ")
+ .set("Vector", make_float3(0.3f, 0.5f, 0.7f)))
+ .add_node(ShaderNodeBuilder<CombineXYZNode>("CombineXYZ"))
+ .add_connection("SeparateXYZ::X", "CombineXYZ::X")
+ .add_connection("SeparateXYZ::Y", "CombineXYZ::Y")
+ .add_connection("SeparateXYZ::Z", "CombineXYZ::Z")
+ .output_color("CombineXYZ::Vector");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -861,22 +833,22 @@ TEST_F(RenderGraph, constant_fold_separate_combine_xyz)
*/
TEST_F(RenderGraph, constant_fold_separate_combine_hsv)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::H to constant (0.583333).");
- CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::S to constant (0.571429).");
- CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::V to constant (0.7).");
- CORRECT_INFO_MESSAGE(log, "Folding CombineHSV::Color to constant (0.3, 0.5, 0.7).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::H to constant (0.583333).");
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::S to constant (0.571429).");
+ CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::V to constant (0.7).");
+ CORRECT_INFO_MESSAGE(log, "Folding CombineHSV::Color to constant (0.3, 0.5, 0.7).");
- builder
- .add_node(ShaderNodeBuilder<SeparateHSVNode>("SeparateHSV")
- .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
- .add_node(ShaderNodeBuilder<CombineHSVNode>("CombineHSV"))
- .add_connection("SeparateHSV::H", "CombineHSV::H")
- .add_connection("SeparateHSV::S", "CombineHSV::S")
- .add_connection("SeparateHSV::V", "CombineHSV::V")
- .output_color("CombineHSV::Color");
+ builder
+ .add_node(ShaderNodeBuilder<SeparateHSVNode>("SeparateHSV")
+ .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
+ .add_node(ShaderNodeBuilder<CombineHSVNode>("CombineHSV"))
+ .add_connection("SeparateHSV::H", "CombineHSV::H")
+ .add_connection("SeparateHSV::S", "CombineHSV::S")
+ .add_connection("SeparateHSV::V", "CombineHSV::V")
+ .output_color("CombineHSV::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -884,16 +856,16 @@ TEST_F(RenderGraph, constant_fold_separate_combine_hsv)
*/
TEST_F(RenderGraph, constant_fold_gamma)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Gamma::Color to constant (0.164317, 0.353553, 0.585662).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Gamma::Color to constant (0.164317, 0.353553, 0.585662).");
- builder
- .add_node(ShaderNodeBuilder<GammaNode>("Gamma")
- .set("Color", make_float3(0.3f, 0.5f, 0.7f))
- .set("Gamma", 1.5f))
- .output_color("Gamma::Color");
+ builder
+ .add_node(ShaderNodeBuilder<GammaNode>("Gamma")
+ .set("Color", make_float3(0.3f, 0.5f, 0.7f))
+ .set("Gamma", 1.5f))
+ .output_color("Gamma::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -901,30 +873,29 @@ TEST_F(RenderGraph, constant_fold_gamma)
*/
TEST_F(RenderGraph, constant_fold_gamma_part_0)
{
- EXPECT_ANY_MESSAGE(log);
- INVALID_INFO_MESSAGE(log, "Folding Gamma_Cx::");
- CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to constant (1, 1, 1).");
-
- builder
- .add_attribute("Attribute")
- /* constant on the left */
- .add_node(ShaderNodeBuilder<GammaNode>("Gamma_Cx")
- .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
- .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
- /* constant on the right */
- .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC")
- .set("Gamma", 0.0f))
- .add_connection("Attribute::Color", "Gamma_xC::Color")
- /* output sum */
- .add_node(ShaderNodeBuilder<MixNode>("Out")
- .set(&MixNode::type, NODE_MIX_ADD)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 1.0f))
- .add_connection("Gamma_Cx::Color", "Out::Color1")
- .add_connection("Gamma_xC::Color", "Out::Color2")
- .output_color("Out::Color");
-
- graph.finalize(scene);
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding Gamma_Cx::");
+ CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to constant (1, 1, 1).");
+
+ builder
+ .add_attribute("Attribute")
+ /* constant on the left */
+ .add_node(
+ ShaderNodeBuilder<GammaNode>("Gamma_Cx").set("Color", make_float3(0.0f, 0.0f, 0.0f)))
+ .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
+ /* constant on the right */
+ .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC").set("Gamma", 0.0f))
+ .add_connection("Attribute::Color", "Gamma_xC::Color")
+ /* output sum */
+ .add_node(ShaderNodeBuilder<MixNode>("Out")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_connection("Gamma_Cx::Color", "Out::Color1")
+ .add_connection("Gamma_xC::Color", "Out::Color2")
+ .output_color("Out::Color");
+
+ graph.finalize(scene);
}
/*
@@ -932,30 +903,29 @@ TEST_F(RenderGraph, constant_fold_gamma_part_0)
*/
TEST_F(RenderGraph, constant_fold_gamma_part_1)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Gamma_Cx::Color to constant (1, 1, 1).");
- CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to socket Attribute::Color.");
-
- builder
- .add_attribute("Attribute")
- /* constant on the left */
- .add_node(ShaderNodeBuilder<GammaNode>("Gamma_Cx")
- .set("Color", make_float3(1.0f, 1.0f, 1.0f)))
- .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
- /* constant on the right */
- .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC")
- .set("Gamma", 1.0f))
- .add_connection("Attribute::Color", "Gamma_xC::Color")
- /* output sum */
- .add_node(ShaderNodeBuilder<MixNode>("Out")
- .set(&MixNode::type, NODE_MIX_ADD)
- .set(&MixNode::use_clamp, true)
- .set("Fac", 1.0f))
- .add_connection("Gamma_Cx::Color", "Out::Color1")
- .add_connection("Gamma_xC::Color", "Out::Color2")
- .output_color("Out::Color");
-
- graph.finalize(scene);
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Gamma_Cx::Color to constant (1, 1, 1).");
+ CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to socket Attribute::Color.");
+
+ builder
+ .add_attribute("Attribute")
+ /* constant on the left */
+ .add_node(
+ ShaderNodeBuilder<GammaNode>("Gamma_Cx").set("Color", make_float3(1.0f, 1.0f, 1.0f)))
+ .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
+ /* constant on the right */
+ .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC").set("Gamma", 1.0f))
+ .add_connection("Attribute::Color", "Gamma_xC::Color")
+ /* output sum */
+ .add_node(ShaderNodeBuilder<MixNode>("Out")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_connection("Gamma_Cx::Color", "Out::Color1")
+ .add_connection("Gamma_xC::Color", "Out::Color2")
+ .output_color("Out::Color");
+
+ graph.finalize(scene);
}
/*
@@ -963,17 +933,17 @@ TEST_F(RenderGraph, constant_fold_gamma_part_1)
*/
TEST_F(RenderGraph, constant_fold_bright_contrast)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding BrightContrast::Color to constant (0.16, 0.6, 1.04).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding BrightContrast::Color to constant (0.16, 0.6, 1.04).");
- builder
- .add_node(ShaderNodeBuilder<BrightContrastNode>("BrightContrast")
- .set("Color", make_float3(0.3f, 0.5f, 0.7f))
- .set("Bright", 0.1f)
- .set("Contrast", 1.2f))
- .output_color("BrightContrast::Color");
+ builder
+ .add_node(ShaderNodeBuilder<BrightContrastNode>("BrightContrast")
+ .set("Color", make_float3(0.3f, 0.5f, 0.7f))
+ .set("Bright", 0.1f)
+ .set("Contrast", 1.2f))
+ .output_color("BrightContrast::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -981,15 +951,13 @@ TEST_F(RenderGraph, constant_fold_bright_contrast)
*/
TEST_F(RenderGraph, constant_fold_blackbody)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Blackbody::Color to constant (3.94163, 0.226523, 0).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Blackbody::Color to constant (3.94163, 0.226523, 0).");
- builder
- .add_node(ShaderNodeBuilder<BlackbodyNode>("Blackbody")
- .set("Temperature", 1200.0f))
- .output_color("Blackbody::Color");
+ builder.add_node(ShaderNodeBuilder<BlackbodyNode>("Blackbody").set("Temperature", 1200.0f))
+ .output_color("Blackbody::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -997,18 +965,18 @@ TEST_F(RenderGraph, constant_fold_blackbody)
*/
TEST_F(RenderGraph, constant_fold_math)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (1.6).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (1.6).");
- builder
- .add_node(ShaderNodeBuilder<MathNode>("Math")
- .set(&MathNode::type, NODE_MATH_ADD)
- .set(&MathNode::use_clamp, false)
- .set("Value1", 0.7f)
- .set("Value2", 0.9f))
- .output_value("Math::Value");
+ builder
+ .add_node(ShaderNodeBuilder<MathNode>("Math")
+ .set(&MathNode::type, NODE_MATH_ADD)
+ .set(&MathNode::use_clamp, false)
+ .set("Value1", 0.7f)
+ .set("Value2", 0.9f))
+ .output_value("Math::Value");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1016,47 +984,49 @@ TEST_F(RenderGraph, constant_fold_math)
*/
TEST_F(RenderGraph, constant_fold_math_clamp)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (1).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (1).");
- builder
- .add_node(ShaderNodeBuilder<MathNode>("Math")
- .set(&MathNode::type, NODE_MATH_ADD)
- .set(&MathNode::use_clamp, true)
- .set("Value1", 0.7f)
- .set("Value2", 0.9f))
- .output_value("Math::Value");
+ builder
+ .add_node(ShaderNodeBuilder<MathNode>("Math")
+ .set(&MathNode::type, NODE_MATH_ADD)
+ .set(&MathNode::use_clamp, true)
+ .set("Value1", 0.7f)
+ .set("Value2", 0.9f))
+ .output_value("Math::Value");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
* Graph for testing partial folds of Math with one constant argument.
* Includes 2 tests: constant on each side.
*/
-static void build_math_partial_test_graph(ShaderGraphBuilder &builder, NodeMath type, float constval)
-{
- builder
- .add_attribute("Attribute")
- /* constant on the left */
- .add_node(ShaderNodeBuilder<MathNode>("Math_Cx")
- .set(&MathNode::type, type)
- .set(&MathNode::use_clamp, false)
- .set("Value1", constval))
- .add_connection("Attribute::Fac", "Math_Cx::Value2")
- /* constant on the right */
- .add_node(ShaderNodeBuilder<MathNode>("Math_xC")
- .set(&MathNode::type, type)
- .set(&MathNode::use_clamp, false)
- .set("Value2", constval))
- .add_connection("Attribute::Fac", "Math_xC::Value1")
- /* output sum */
- .add_node(ShaderNodeBuilder<MathNode>("Out")
- .set(&MathNode::type, NODE_MATH_ADD)
- .set(&MathNode::use_clamp, true))
- .add_connection("Math_Cx::Value", "Out::Value1")
- .add_connection("Math_xC::Value", "Out::Value2")
- .output_value("Out::Value");
+static void build_math_partial_test_graph(ShaderGraphBuilder &builder,
+ NodeMath type,
+ float constval)
+{
+ builder
+ .add_attribute("Attribute")
+ /* constant on the left */
+ .add_node(ShaderNodeBuilder<MathNode>("Math_Cx")
+ .set(&MathNode::type, type)
+ .set(&MathNode::use_clamp, false)
+ .set("Value1", constval))
+ .add_connection("Attribute::Fac", "Math_Cx::Value2")
+ /* constant on the right */
+ .add_node(ShaderNodeBuilder<MathNode>("Math_xC")
+ .set(&MathNode::type, type)
+ .set(&MathNode::use_clamp, false)
+ .set("Value2", constval))
+ .add_connection("Attribute::Fac", "Math_xC::Value1")
+ /* output sum */
+ .add_node(ShaderNodeBuilder<MathNode>("Out")
+ .set(&MathNode::type, NODE_MATH_ADD)
+ .set(&MathNode::use_clamp, true))
+ .add_connection("Math_Cx::Value", "Out::Value1")
+ .add_connection("Math_xC::Value", "Out::Value2")
+ .output_value("Out::Value");
}
/*
@@ -1064,14 +1034,14 @@ static void build_math_partial_test_graph(ShaderGraphBuilder &builder, NodeMath
*/
TEST_F(RenderGraph, constant_fold_part_math_add_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X + 0 == 0 + X == X */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to socket Attribute::Fac.");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* X + 0 == 0 + X == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to socket Attribute::Fac.");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_math_partial_test_graph(builder, NODE_MATH_ADD, 0.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_ADD, 0.0f);
+ graph.finalize(scene);
}
/*
@@ -1079,14 +1049,14 @@ TEST_F(RenderGraph, constant_fold_part_math_add_0)
*/
TEST_F(RenderGraph, constant_fold_part_math_sub_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X - 0 == X */
- INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* X - 0 == X */
+ INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_math_partial_test_graph(builder, NODE_MATH_SUBTRACT, 0.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_SUBTRACT, 0.0f);
+ graph.finalize(scene);
}
/*
@@ -1094,14 +1064,14 @@ TEST_F(RenderGraph, constant_fold_part_math_sub_0)
*/
TEST_F(RenderGraph, constant_fold_part_math_mul_1)
{
- EXPECT_ANY_MESSAGE(log);
- /* X * 1 == 1 * X == X */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to socket Attribute::Fac.");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* X * 1 == 1 * X == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to socket Attribute::Fac.");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 1.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 1.0f);
+ graph.finalize(scene);
}
/*
@@ -1109,14 +1079,14 @@ TEST_F(RenderGraph, constant_fold_part_math_mul_1)
*/
TEST_F(RenderGraph, constant_fold_part_math_div_1)
{
- EXPECT_ANY_MESSAGE(log);
- /* X / 1 == X */
- INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* X / 1 == X */
+ INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 1.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 1.0f);
+ graph.finalize(scene);
}
/*
@@ -1124,15 +1094,15 @@ TEST_F(RenderGraph, constant_fold_part_math_div_1)
*/
TEST_F(RenderGraph, constant_fold_part_math_mul_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X * 0 == 0 * X == 0 */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (0).");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to constant (0).");
- CORRECT_INFO_MESSAGE(log, "Folding Out::Value to constant (0)");
- CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
+ EXPECT_ANY_MESSAGE(log);
+ /* X * 0 == 0 * X == 0 */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to constant (0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Out::Value to constant (0)");
+ CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
- build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 0.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 0.0f);
+ graph.finalize(scene);
}
/*
@@ -1140,14 +1110,14 @@ TEST_F(RenderGraph, constant_fold_part_math_mul_0)
*/
TEST_F(RenderGraph, constant_fold_part_math_div_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* 0 / X == 0 */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (0).");
- INVALID_INFO_MESSAGE(log, "Folding Math_xC::");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* 0 / X == 0 */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (0).");
+ INVALID_INFO_MESSAGE(log, "Folding Math_xC::");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 0.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 0.0f);
+ graph.finalize(scene);
}
/*
@@ -1155,14 +1125,14 @@ TEST_F(RenderGraph, constant_fold_part_math_div_0)
*/
TEST_F(RenderGraph, constant_fold_part_math_pow_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X ^ 0 == 1 */
- INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to constant (1).");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* X ^ 0 == 1 */
+ INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to constant (1).");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_math_partial_test_graph(builder, NODE_MATH_POWER, 0.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_POWER, 0.0f);
+ graph.finalize(scene);
}
/*
@@ -1170,14 +1140,14 @@ TEST_F(RenderGraph, constant_fold_part_math_pow_0)
*/
TEST_F(RenderGraph, constant_fold_part_math_pow_1)
{
- EXPECT_ANY_MESSAGE(log);
- /* 1 ^ X == 1; X ^ 1 == X */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (1)");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* 1 ^ X == 1; X ^ 1 == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (1)");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_math_partial_test_graph(builder, NODE_MATH_POWER, 1.0f);
- graph.finalize(scene);
+ build_math_partial_test_graph(builder, NODE_MATH_POWER, 1.0f);
+ graph.finalize(scene);
}
/*
@@ -1185,51 +1155,52 @@ TEST_F(RenderGraph, constant_fold_part_math_pow_1)
*/
TEST_F(RenderGraph, constant_fold_vector_math)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Value to constant (1).");
- CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Vector to constant (3, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding convert_vector_to_float::value_float to constant (1).");
- CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (2).");
- CORRECT_INFO_MESSAGE(log, "Folding convert_float_to_color::value_color to constant (2, 2, 2).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Value to constant (1).");
+ CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Vector to constant (3, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Folding convert_vector_to_float::value_float to constant (1).");
+ CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (2).");
+ CORRECT_INFO_MESSAGE(log, "Folding convert_float_to_color::value_color to constant (2, 2, 2).");
- builder
- .add_node(ShaderNodeBuilder<VectorMathNode>("VectorMath")
- .set(&VectorMathNode::type, NODE_VECTOR_MATH_SUBTRACT)
- .set("Vector1", make_float3(1.3f, 0.5f, 0.7f))
- .set("Vector2", make_float3(-1.7f, 0.5f, 0.7f)))
- .add_node(ShaderNodeBuilder<MathNode>("Math")
- .set(&MathNode::type, NODE_MATH_ADD))
- .add_connection("VectorMath::Vector", "Math::Value1")
- .add_connection("VectorMath::Value", "Math::Value2")
- .output_color("Math::Value");
+ builder
+ .add_node(ShaderNodeBuilder<VectorMathNode>("VectorMath")
+ .set(&VectorMathNode::type, NODE_VECTOR_MATH_SUBTRACT)
+ .set("Vector1", make_float3(1.3f, 0.5f, 0.7f))
+ .set("Vector2", make_float3(-1.7f, 0.5f, 0.7f)))
+ .add_node(ShaderNodeBuilder<MathNode>("Math").set(&MathNode::type, NODE_MATH_ADD))
+ .add_connection("VectorMath::Vector", "Math::Value1")
+ .add_connection("VectorMath::Value", "Math::Value2")
+ .output_color("Math::Value");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
* Graph for testing partial folds of Vector Math with one constant argument.
* Includes 2 tests: constant on each side.
*/
-static void build_vecmath_partial_test_graph(ShaderGraphBuilder &builder, NodeVectorMath type, float3 constval)
-{
- builder
- .add_attribute("Attribute")
- /* constant on the left */
- .add_node(ShaderNodeBuilder<VectorMathNode>("Math_Cx")
- .set(&VectorMathNode::type, type)
- .set("Vector1", constval))
- .add_connection("Attribute::Vector", "Math_Cx::Vector2")
- /* constant on the right */
- .add_node(ShaderNodeBuilder<VectorMathNode>("Math_xC")
- .set(&VectorMathNode::type, type)
- .set("Vector2", constval))
- .add_connection("Attribute::Vector", "Math_xC::Vector1")
- /* output sum */
- .add_node(ShaderNodeBuilder<VectorMathNode>("Out")
- .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD))
- .add_connection("Math_Cx::Vector", "Out::Vector1")
- .add_connection("Math_xC::Vector", "Out::Vector2")
- .output_color("Out::Vector");
+static void build_vecmath_partial_test_graph(ShaderGraphBuilder &builder,
+ NodeVectorMath type,
+ float3 constval)
+{
+ builder
+ .add_attribute("Attribute")
+ /* constant on the left */
+ .add_node(ShaderNodeBuilder<VectorMathNode>("Math_Cx")
+ .set(&VectorMathNode::type, type)
+ .set("Vector1", constval))
+ .add_connection("Attribute::Vector", "Math_Cx::Vector2")
+ /* constant on the right */
+ .add_node(ShaderNodeBuilder<VectorMathNode>("Math_xC")
+ .set(&VectorMathNode::type, type)
+ .set("Vector2", constval))
+ .add_connection("Attribute::Vector", "Math_xC::Vector1")
+ /* output sum */
+ .add_node(ShaderNodeBuilder<VectorMathNode>("Out").set(&VectorMathNode::type,
+ NODE_VECTOR_MATH_ADD))
+ .add_connection("Math_Cx::Vector", "Out::Vector1")
+ .add_connection("Math_xC::Vector", "Out::Vector2")
+ .output_color("Out::Vector");
}
/*
@@ -1237,14 +1208,14 @@ static void build_vecmath_partial_test_graph(ShaderGraphBuilder &builder, NodeVe
*/
TEST_F(RenderGraph, constant_fold_part_vecmath_add_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X + 0 == 0 + X == X */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to socket Attribute::Vector.");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to socket Attribute::Vector.");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* X + 0 == 0 + X == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to socket Attribute::Vector.");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to socket Attribute::Vector.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_ADD, make_float3(0,0,0));
- graph.finalize(scene);
+ build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_ADD, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -1252,14 +1223,14 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_add_0)
*/
TEST_F(RenderGraph, constant_fold_part_vecmath_sub_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X - 0 == X */
- INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to socket Attribute::Vector.");
- INVALID_INFO_MESSAGE(log, "Folding Out::");
+ EXPECT_ANY_MESSAGE(log);
+ /* X - 0 == X */
+ INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to socket Attribute::Vector.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
- build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_SUBTRACT, make_float3(0,0,0));
- graph.finalize(scene);
+ build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_SUBTRACT, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -1267,15 +1238,15 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_sub_0)
*/
TEST_F(RenderGraph, constant_fold_part_vecmath_dot_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X * 0 == 0 * X == X */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding Out::Vector to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
+ EXPECT_ANY_MESSAGE(log);
+ /* X * 0 == 0 * X == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Out::Vector to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
- build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_DOT_PRODUCT, make_float3(0,0,0));
- graph.finalize(scene);
+ build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_DOT_PRODUCT, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -1283,15 +1254,15 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_dot_0)
*/
TEST_F(RenderGraph, constant_fold_part_vecmath_cross_0)
{
- EXPECT_ANY_MESSAGE(log);
- /* X * 0 == 0 * X == X */
- CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Folding Out::Vector to constant (0, 0, 0).");
- CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
+ EXPECT_ANY_MESSAGE(log);
+ /* X * 0 == 0 * X == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Folding Out::Vector to constant (0, 0, 0).");
+ CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
- build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_CROSS_PRODUCT, make_float3(0,0,0));
- graph.finalize(scene);
+ build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_CROSS_PRODUCT, make_float3(0, 0, 0));
+ graph.finalize(scene);
}
/*
@@ -1299,16 +1270,15 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_cross_0)
*/
TEST_F(RenderGraph, constant_fold_bump)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Bump::Normal to socket Geometry1::Normal.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Bump::Normal to socket Geometry1::Normal.");
- builder
- .add_node(ShaderNodeBuilder<GeometryNode>("Geometry1"))
- .add_node(ShaderNodeBuilder<BumpNode>("Bump"))
- .add_connection("Geometry1::Normal", "Bump::Normal")
- .output_color("Bump::Normal");
+ builder.add_node(ShaderNodeBuilder<GeometryNode>("Geometry1"))
+ .add_node(ShaderNodeBuilder<BumpNode>("Bump"))
+ .add_connection("Geometry1::Normal", "Bump::Normal")
+ .output_color("Bump::Normal");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1316,24 +1286,21 @@ TEST_F(RenderGraph, constant_fold_bump)
*/
TEST_F(RenderGraph, constant_fold_bump_no_input)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Bump::Normal to socket geometry::Normal.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Bump::Normal to socket geometry::Normal.");
- builder
- .add_node(ShaderNodeBuilder<BumpNode>("Bump"))
- .output_color("Bump::Normal");
+ builder.add_node(ShaderNodeBuilder<BumpNode>("Bump")).output_color("Bump::Normal");
- graph.finalize(scene);
+ graph.finalize(scene);
}
-template<class T>
-void init_test_curve(array<T> &buffer, T start, T end, int steps)
+template<class T> void init_test_curve(array<T> &buffer, T start, T end, int steps)
{
- buffer.resize(steps);
+ buffer.resize(steps);
- for(int i = 0; i < steps; i++) {
- buffer[i] = lerp(start, end, float(i)/(steps-1));
- }
+ for (int i = 0; i < steps; i++) {
+ buffer[i] = lerp(start, end, float(i) / (steps - 1));
+ }
}
/*
@@ -1342,22 +1309,22 @@ void init_test_curve(array<T> &buffer, T start, T end, int steps)
*/
TEST_F(RenderGraph, constant_fold_rgb_curves)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to constant (0.275, 0.5, 0.475).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to constant (0.275, 0.5, 0.475).");
- array<float3> curve;
- init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
+ array<float3> curve;
+ init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
- builder
- .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
- .set(&CurvesNode::curves, curve)
- .set(&CurvesNode::min_x, 0.1f)
- .set(&CurvesNode::max_x, 0.9f)
- .set("Fac", 0.5f)
- .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
- .output_color("Curves::Color");
+ builder
+ .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
+ .set(&CurvesNode::curves, curve)
+ .set(&CurvesNode::min_x, 0.1f)
+ .set(&CurvesNode::max_x, 0.9f)
+ .set("Fac", 0.5f)
+ .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
+ .output_color("Curves::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1366,48 +1333,46 @@ TEST_F(RenderGraph, constant_fold_rgb_curves)
*/
TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to socket Attribute::Color.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to socket Attribute::Color.");
- array<float3> curve;
- init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
+ array<float3> curve;
+ init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
- .set(&CurvesNode::curves, curve)
- .set(&CurvesNode::min_x, 0.1f)
- .set(&CurvesNode::max_x, 0.9f)
- .set("Fac", 0.0f))
- .add_connection("Attribute::Color", "Curves::Color")
- .output_color("Curves::Color");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
+ .set(&CurvesNode::curves, curve)
+ .set(&CurvesNode::min_x, 0.1f)
+ .set(&CurvesNode::max_x, 0.9f)
+ .set("Fac", 0.0f))
+ .add_connection("Attribute::Color", "Curves::Color")
+ .output_color("Curves::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
-
/*
* Tests:
* - Folding of RGB Curves with zero Fac and all constant inputs.
*/
TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0_const)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to constant (0.3, 0.5, 0.7).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to constant (0.3, 0.5, 0.7).");
- array<float3> curve;
- init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
+ array<float3> curve;
+ init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
- builder
- .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
- .set(&CurvesNode::curves, curve)
- .set(&CurvesNode::min_x, 0.1f)
- .set(&CurvesNode::max_x, 0.9f)
- .set("Fac", 0.0f)
- .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
- .output_color("Curves::Color");
+ builder
+ .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
+ .set(&CurvesNode::curves, curve)
+ .set(&CurvesNode::min_x, 0.1f)
+ .set(&CurvesNode::max_x, 0.9f)
+ .set("Fac", 0.0f)
+ .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
+ .output_color("Curves::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1416,22 +1381,22 @@ TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0_const)
*/
TEST_F(RenderGraph, constant_fold_vector_curves)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Curves::Vector to constant (0.275, 0.5, 0.475).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Curves::Vector to constant (0.275, 0.5, 0.475).");
- array<float3> curve;
- init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
+ array<float3> curve;
+ init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
- builder
- .add_node(ShaderNodeBuilder<VectorCurvesNode>("Curves")
- .set(&CurvesNode::curves, curve)
- .set(&CurvesNode::min_x, 0.1f)
- .set(&CurvesNode::max_x, 0.9f)
- .set("Fac", 0.5f)
- .set("Vector", make_float3(0.3f, 0.5f, 0.7f)))
- .output_color("Curves::Vector");
+ builder
+ .add_node(ShaderNodeBuilder<VectorCurvesNode>("Curves")
+ .set(&CurvesNode::curves, curve)
+ .set(&CurvesNode::min_x, 0.1f)
+ .set(&CurvesNode::max_x, 0.9f)
+ .set("Fac", 0.5f)
+ .set("Vector", make_float3(0.3f, 0.5f, 0.7f)))
+ .output_color("Curves::Vector");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1440,23 +1405,22 @@ TEST_F(RenderGraph, constant_fold_vector_curves)
*/
TEST_F(RenderGraph, constant_fold_vector_curves_fac_0)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Curves::Vector to socket Attribute::Vector.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Curves::Vector to socket Attribute::Vector.");
- array<float3> curve;
- init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
+ array<float3> curve;
+ init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<VectorCurvesNode>("Curves")
- .set(&CurvesNode::curves, curve)
- .set(&CurvesNode::min_x, 0.1f)
- .set(&CurvesNode::max_x, 0.9f)
- .set("Fac", 0.0f))
- .add_connection("Attribute::Vector", "Curves::Vector")
- .output_color("Curves::Vector");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<VectorCurvesNode>("Curves")
+ .set(&CurvesNode::curves, curve)
+ .set(&CurvesNode::min_x, 0.1f)
+ .set(&CurvesNode::max_x, 0.9f)
+ .set("Fac", 0.0f))
+ .add_connection("Attribute::Vector", "Curves::Vector")
+ .output_color("Curves::Vector");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1465,28 +1429,27 @@ TEST_F(RenderGraph, constant_fold_vector_curves_fac_0)
*/
TEST_F(RenderGraph, constant_fold_rgb_ramp)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Ramp::Color to constant (0.14, 0.39, 0.64).");
- CORRECT_INFO_MESSAGE(log, "Folding Ramp::Alpha to constant (0.89).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Ramp::Color to constant (0.14, 0.39, 0.64).");
+ CORRECT_INFO_MESSAGE(log, "Folding Ramp::Alpha to constant (0.89).");
- array<float3> curve;
- array<float> alpha;
- init_test_curve(curve, make_float3(0.0f, 0.25f, 0.5f), make_float3(0.25f, 0.5f, 0.75f), 9);
- init_test_curve(alpha, 0.75f, 1.0f, 9);
+ array<float3> curve;
+ array<float> alpha;
+ init_test_curve(curve, make_float3(0.0f, 0.25f, 0.5f), make_float3(0.25f, 0.5f, 0.75f), 9);
+ init_test_curve(alpha, 0.75f, 1.0f, 9);
- builder
- .add_node(ShaderNodeBuilder<RGBRampNode>("Ramp")
- .set(&RGBRampNode::ramp, curve)
- .set(&RGBRampNode::ramp_alpha, alpha)
- .set(&RGBRampNode::interpolate, true)
- .set("Fac", 0.56f))
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_ADD))
- .add_connection("Ramp::Color", "Mix::Color1")
- .add_connection("Ramp::Alpha", "Mix::Color2")
- .output_color("Mix::Color");
+ builder
+ .add_node(ShaderNodeBuilder<RGBRampNode>("Ramp")
+ .set(&RGBRampNode::ramp, curve)
+ .set(&RGBRampNode::ramp_alpha, alpha)
+ .set(&RGBRampNode::interpolate, true)
+ .set("Fac", 0.56f))
+ .add_node(ShaderNodeBuilder<MixNode>("Mix").set(&MixNode::type, NODE_MIX_ADD))
+ .add_connection("Ramp::Color", "Mix::Color1")
+ .add_connection("Ramp::Alpha", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1495,28 +1458,27 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp)
*/
TEST_F(RenderGraph, constant_fold_rgb_ramp_flat)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Ramp::Color to constant (0.125, 0.375, 0.625).");
- CORRECT_INFO_MESSAGE(log, "Folding Ramp::Alpha to constant (0.875).");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Ramp::Color to constant (0.125, 0.375, 0.625).");
+ CORRECT_INFO_MESSAGE(log, "Folding Ramp::Alpha to constant (0.875).");
- array<float3> curve;
- array<float> alpha;
- init_test_curve(curve, make_float3(0.0f, 0.25f, 0.5f), make_float3(0.25f, 0.5f, 0.75f), 9);
- init_test_curve(alpha, 0.75f, 1.0f, 9);
+ array<float3> curve;
+ array<float> alpha;
+ init_test_curve(curve, make_float3(0.0f, 0.25f, 0.5f), make_float3(0.25f, 0.5f, 0.75f), 9);
+ init_test_curve(alpha, 0.75f, 1.0f, 9);
- builder
- .add_node(ShaderNodeBuilder<RGBRampNode>("Ramp")
- .set(&RGBRampNode::ramp, curve)
- .set(&RGBRampNode::ramp_alpha, alpha)
- .set(&RGBRampNode::interpolate, false)
- .set("Fac", 0.56f))
- .add_node(ShaderNodeBuilder<MixNode>("Mix")
- .set(&MixNode::type, NODE_MIX_ADD))
- .add_connection("Ramp::Color", "Mix::Color1")
- .add_connection("Ramp::Alpha", "Mix::Color2")
- .output_color("Mix::Color");
+ builder
+ .add_node(ShaderNodeBuilder<RGBRampNode>("Ramp")
+ .set(&RGBRampNode::ramp, curve)
+ .set(&RGBRampNode::ramp_alpha, alpha)
+ .set(&RGBRampNode::interpolate, false)
+ .set("Fac", 0.56f))
+ .add_node(ShaderNodeBuilder<MixNode>("Mix").set(&MixNode::type, NODE_MIX_ADD))
+ .add_connection("Ramp::Color", "Mix::Color1")
+ .add_connection("Ramp::Alpha", "Mix::Color2")
+ .output_color("Mix::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1525,18 +1487,18 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp_flat)
*/
TEST_F(RenderGraph, constant_fold_convert_float_color_float)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to socket convert_float_to_color::value_color.");
- CORRECT_INFO_MESSAGE(log, "Folding convert_color_to_float::value_float to socket Attribute::Fac.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log,
+ "Folding Invert::Color to socket convert_float_to_color::value_color.");
+ CORRECT_INFO_MESSAGE(log,
+ "Folding convert_color_to_float::value_float to socket Attribute::Fac.");
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<InvertNode>("Invert")
- .set("Fac", 0.0f))
- .add_connection("Attribute::Fac", "Invert::Color")
- .output_value("Invert::Color");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<InvertNode>("Invert").set("Fac", 0.0f))
+ .add_connection("Attribute::Fac", "Invert::Color")
+ .output_value("Invert::Color");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1545,19 +1507,20 @@ TEST_F(RenderGraph, constant_fold_convert_float_color_float)
*/
TEST_F(RenderGraph, constant_fold_convert_color_vector_color)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding VecAdd::Vector to socket convert_color_to_vector::value_vector.");
- CORRECT_INFO_MESSAGE(log, "Folding convert_vector_to_color::value_color to socket Attribute::Color.");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log,
+ "Folding VecAdd::Vector to socket convert_color_to_vector::value_vector.");
+ CORRECT_INFO_MESSAGE(log,
+ "Folding convert_vector_to_color::value_color to socket Attribute::Color.");
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<VectorMathNode>("VecAdd")
- .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD)
- .set("Vector2", make_float3(0,0,0)))
- .add_connection("Attribute::Color", "VecAdd::Vector1")
- .output_color("VecAdd::Vector");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<VectorMathNode>("VecAdd")
+ .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD)
+ .set("Vector2", make_float3(0, 0, 0)))
+ .add_connection("Attribute::Color", "VecAdd::Vector1")
+ .output_color("VecAdd::Vector");
- graph.finalize(scene);
+ graph.finalize(scene);
}
/*
@@ -1566,19 +1529,19 @@ TEST_F(RenderGraph, constant_fold_convert_color_vector_color)
*/
TEST_F(RenderGraph, constant_fold_convert_color_float_color)
{
- EXPECT_ANY_MESSAGE(log);
- CORRECT_INFO_MESSAGE(log, "Folding MathAdd::Value to socket convert_color_to_float::value_float.");
- INVALID_INFO_MESSAGE(log, "Folding convert_float_to_color::");
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log,
+ "Folding MathAdd::Value to socket convert_color_to_float::value_float.");
+ INVALID_INFO_MESSAGE(log, "Folding convert_float_to_color::");
- builder
- .add_attribute("Attribute")
- .add_node(ShaderNodeBuilder<MathNode>("MathAdd")
- .set(&MathNode::type, NODE_MATH_ADD)
- .set("Value2", 0.0f))
- .add_connection("Attribute::Color", "MathAdd::Value1")
- .output_color("MathAdd::Value");
+ builder.add_attribute("Attribute")
+ .add_node(ShaderNodeBuilder<MathNode>("MathAdd")
+ .set(&MathNode::type, NODE_MATH_ADD)
+ .set("Value2", 0.0f))
+ .add_connection("Attribute::Color", "MathAdd::Value1")
+ .output_color("MathAdd::Value");
- graph.finalize(scene);
+ graph.finalize(scene);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/test/util_aligned_malloc_test.cpp b/intern/cycles/test/util_aligned_malloc_test.cpp
index 9fb3aad0c3f..8829c422a0f 100644
--- a/intern/cycles/test/util_aligned_malloc_test.cpp
+++ b/intern/cycles/test/util_aligned_malloc_test.cpp
@@ -24,19 +24,19 @@ CCL_NAMESPACE_BEGIN
TEST(util_aligned_malloc, aligned_malloc_16)
{
- int *mem = (int*)util_aligned_malloc(sizeof(int), 16);
- CHECK_ALIGNMENT(mem, 16);
- util_aligned_free(mem);
+ int *mem = (int *)util_aligned_malloc(sizeof(int), 16);
+ CHECK_ALIGNMENT(mem, 16);
+ util_aligned_free(mem);
}
/* On Apple we currently only support 16 bytes alignment. */
#ifndef __APPLE__
TEST(util_aligned_malloc, aligned_malloc_32)
{
- int *mem = (int*)util_aligned_malloc(sizeof(int), 32);
- CHECK_ALIGNMENT(mem, 32);
- util_aligned_free(mem);
+ int *mem = (int *)util_aligned_malloc(sizeof(int), 32);
+ CHECK_ALIGNMENT(mem, 32);
+ util_aligned_free(mem);
}
-#endif /* __APPLE__ */
+#endif /* __APPLE__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/test/util_path_test.cpp b/intern/cycles/test/util_path_test.cpp
index 1df568493d8..76d48dc241d 100644
--- a/intern/cycles/test/util_path_test.cpp
+++ b/intern/cycles/test/util_path_test.cpp
@@ -25,377 +25,377 @@ CCL_NAMESPACE_BEGIN
#ifndef _WIN32
TEST(util_path_filename, simple_unix)
{
- string str = path_filename("/tmp/foo.txt");
- EXPECT_EQ(str, "foo.txt");
+ string str = path_filename("/tmp/foo.txt");
+ EXPECT_EQ(str, "foo.txt");
}
TEST(util_path_filename, root_unix)
{
- string str = path_filename("/");
- EXPECT_EQ(str, "/");
+ string str = path_filename("/");
+ EXPECT_EQ(str, "/");
}
TEST(util_path_filename, last_slash_unix)
{
- string str = path_filename("/tmp/foo.txt/");
- EXPECT_EQ(str, ".");
+ string str = path_filename("/tmp/foo.txt/");
+ EXPECT_EQ(str, ".");
}
TEST(util_path_filename, alternate_slash_unix)
{
- string str = path_filename("/tmp\\foo.txt");
- EXPECT_EQ(str, "tmp\\foo.txt");
+ string str = path_filename("/tmp\\foo.txt");
+ EXPECT_EQ(str, "tmp\\foo.txt");
}
-#endif /* !_WIN32 */
+#endif /* !_WIN32 */
TEST(util_path_filename, file_only)
{
- string str = path_filename("foo.txt");
- EXPECT_EQ(str, "foo.txt");
+ string str = path_filename("foo.txt");
+ EXPECT_EQ(str, "foo.txt");
}
TEST(util_path_filename, empty)
{
- string str = path_filename("");
- EXPECT_EQ(str, "");
+ string str = path_filename("");
+ EXPECT_EQ(str, "");
}
#ifdef _WIN32
TEST(util_path_filename, simple_windows)
{
- string str = path_filename("C:\\tmp\\foo.txt");
- EXPECT_EQ(str, "foo.txt");
+ string str = path_filename("C:\\tmp\\foo.txt");
+ EXPECT_EQ(str, "foo.txt");
}
TEST(util_path_filename, root_windows)
{
- string str = path_filename("C:\\");
- EXPECT_EQ(str, "\\");
+ string str = path_filename("C:\\");
+ EXPECT_EQ(str, "\\");
}
TEST(util_path_filename, last_slash_windows)
{
- string str = path_filename("C:\\tmp\\foo.txt\\");
- EXPECT_EQ(str, ".");
+ string str = path_filename("C:\\tmp\\foo.txt\\");
+ EXPECT_EQ(str, ".");
}
TEST(util_path_filename, alternate_slash_windows)
{
- string str = path_filename("C:\\tmp/foo.txt");
- EXPECT_EQ(str, "foo.txt");
+ string str = path_filename("C:\\tmp/foo.txt");
+ EXPECT_EQ(str, "foo.txt");
}
-#endif /* _WIN32 */
+#endif /* _WIN32 */
/* ******** Tests for path_dirname() ******** */
#ifndef _WIN32
TEST(util_path_dirname, simple_unix)
{
- string str = path_dirname("/tmp/foo.txt");
- EXPECT_EQ(str, "/tmp");
+ string str = path_dirname("/tmp/foo.txt");
+ EXPECT_EQ(str, "/tmp");
}
TEST(util_path_dirname, root_unix)
{
- string str = path_dirname("/");
- EXPECT_EQ(str, "");
+ string str = path_dirname("/");
+ EXPECT_EQ(str, "");
}
TEST(util_path_dirname, last_slash_unix)
{
- string str = path_dirname("/tmp/foo.txt/");
- EXPECT_EQ(str, "/tmp/foo.txt");
+ string str = path_dirname("/tmp/foo.txt/");
+ EXPECT_EQ(str, "/tmp/foo.txt");
}
TEST(util_path_dirname, alternate_slash_unix)
{
- string str = path_dirname("/tmp\\foo.txt");
- EXPECT_EQ(str, "/");
+ string str = path_dirname("/tmp\\foo.txt");
+ EXPECT_EQ(str, "/");
}
-#endif /* !_WIN32 */
+#endif /* !_WIN32 */
TEST(util_path_dirname, file_only)
{
- string str = path_dirname("foo.txt");
- EXPECT_EQ(str, "");
+ string str = path_dirname("foo.txt");
+ EXPECT_EQ(str, "");
}
TEST(util_path_dirname, empty)
{
- string str = path_dirname("");
- EXPECT_EQ(str, "");
+ string str = path_dirname("");
+ EXPECT_EQ(str, "");
}
#ifdef _WIN32
TEST(util_path_dirname, simple_windows)
{
- string str = path_dirname("C:\\tmp\\foo.txt");
- EXPECT_EQ(str, "C:\\tmp");
+ string str = path_dirname("C:\\tmp\\foo.txt");
+ EXPECT_EQ(str, "C:\\tmp");
}
TEST(util_path_dirname, root_windows)
{
- string str = path_dirname("C:\\");
- EXPECT_EQ(str, "C:");
+ string str = path_dirname("C:\\");
+ EXPECT_EQ(str, "C:");
}
TEST(util_path_dirname, last_slash_windows)
{
- string str = path_dirname("C:\\tmp\\foo.txt\\");
- EXPECT_EQ(str, "C:\\tmp\\foo.txt");
+ string str = path_dirname("C:\\tmp\\foo.txt\\");
+ EXPECT_EQ(str, "C:\\tmp\\foo.txt");
}
TEST(util_path_dirname, alternate_slash_windows)
{
- string str = path_dirname("C:\\tmp/foo.txt");
- EXPECT_EQ(str, "C:\\tmp");
+ string str = path_dirname("C:\\tmp/foo.txt");
+ EXPECT_EQ(str, "C:\\tmp");
}
-#endif /* _WIN32 */
+#endif /* _WIN32 */
/* ******** Tests for path_join() ******** */
TEST(util_path_join, empty_both)
{
- string str = path_join("", "");
- EXPECT_EQ(str, "");
+ string str = path_join("", "");
+ EXPECT_EQ(str, "");
}
TEST(util_path_join, empty_directory)
{
- string str = path_join("", "foo.txt");
- EXPECT_EQ(str, "foo.txt");
+ string str = path_join("", "foo.txt");
+ EXPECT_EQ(str, "foo.txt");
}
TEST(util_path_join, empty_filename)
{
- string str = path_join("foo", "");
- EXPECT_EQ(str, "foo");
+ string str = path_join("foo", "");
+ EXPECT_EQ(str, "foo");
}
#ifndef _WIN32
TEST(util_path_join, simple_unix)
{
- string str = path_join("foo", "bar");
- EXPECT_EQ(str, "foo/bar");
+ string str = path_join("foo", "bar");
+ EXPECT_EQ(str, "foo/bar");
}
TEST(util_path_join, directory_slash_unix)
{
- string str = path_join("foo/", "bar");
- EXPECT_EQ(str, "foo/bar");
+ string str = path_join("foo/", "bar");
+ EXPECT_EQ(str, "foo/bar");
}
TEST(util_path_join, filename_slash_unix)
{
- string str = path_join("foo", "/bar");
- EXPECT_EQ(str, "foo/bar");
+ string str = path_join("foo", "/bar");
+ EXPECT_EQ(str, "foo/bar");
}
TEST(util_path_join, both_slash_unix)
{
- string str = path_join("foo/", "/bar");
- EXPECT_EQ(str, "foo//bar");
+ string str = path_join("foo/", "/bar");
+ EXPECT_EQ(str, "foo//bar");
}
TEST(util_path_join, directory_alternate_slash_unix)
{
- string str = path_join("foo\\", "bar");
- EXPECT_EQ(str, "foo\\/bar");
+ string str = path_join("foo\\", "bar");
+ EXPECT_EQ(str, "foo\\/bar");
}
TEST(util_path_join, filename_alternate_slash_unix)
{
- string str = path_join("foo", "\\bar");
- EXPECT_EQ(str, "foo/\\bar");
+ string str = path_join("foo", "\\bar");
+ EXPECT_EQ(str, "foo/\\bar");
}
TEST(util_path_join, both_alternate_slash_unix)
{
- string str = path_join("foo", "\\bar");
- EXPECT_EQ(str, "foo/\\bar");
+ string str = path_join("foo", "\\bar");
+ EXPECT_EQ(str, "foo/\\bar");
}
TEST(util_path_join, empty_dir_filename_slash_unix)
{
- string str = path_join("", "/foo.txt");
- EXPECT_EQ(str, "/foo.txt");
+ string str = path_join("", "/foo.txt");
+ EXPECT_EQ(str, "/foo.txt");
}
TEST(util_path_join, empty_dir_filename_alternate_slash_unix)
{
- string str = path_join("", "\\foo.txt");
- EXPECT_EQ(str, "\\foo.txt");
+ string str = path_join("", "\\foo.txt");
+ EXPECT_EQ(str, "\\foo.txt");
}
TEST(util_path_join, empty_filename_dir_slash_unix)
{
- string str = path_join("foo/", "");
- EXPECT_EQ(str, "foo/");
+ string str = path_join("foo/", "");
+ EXPECT_EQ(str, "foo/");
}
TEST(util_path_join, empty_filename_dir_alternate_slash_unix)
{
- string str = path_join("foo\\", "");
- EXPECT_EQ(str, "foo\\");
+ string str = path_join("foo\\", "");
+ EXPECT_EQ(str, "foo\\");
}
#else /* !_WIN32 */
TEST(util_path_join, simple_windows)
{
- string str = path_join("foo", "bar");
- EXPECT_EQ(str, "foo\\bar");
+ string str = path_join("foo", "bar");
+ EXPECT_EQ(str, "foo\\bar");
}
TEST(util_path_join, directory_slash_windows)
{
- string str = path_join("foo\\", "bar");
- EXPECT_EQ(str, "foo\\bar");
+ string str = path_join("foo\\", "bar");
+ EXPECT_EQ(str, "foo\\bar");
}
TEST(util_path_join, filename_slash_windows)
{
- string str = path_join("foo", "\\bar");
- EXPECT_EQ(str, "foo\\bar");
+ string str = path_join("foo", "\\bar");
+ EXPECT_EQ(str, "foo\\bar");
}
TEST(util_path_join, both_slash_windows)
{
- string str = path_join("foo\\", "\\bar");
- EXPECT_EQ(str, "foo\\\\bar");
+ string str = path_join("foo\\", "\\bar");
+ EXPECT_EQ(str, "foo\\\\bar");
}
TEST(util_path_join, directory_alternate_slash_windows)
{
- string str = path_join("foo/", "bar");
- EXPECT_EQ(str, "foo/bar");
+ string str = path_join("foo/", "bar");
+ EXPECT_EQ(str, "foo/bar");
}
TEST(util_path_join, filename_alternate_slash_windows)
{
- string str = path_join("foo", "/bar");
- EXPECT_EQ(str, "foo/bar");
+ string str = path_join("foo", "/bar");
+ EXPECT_EQ(str, "foo/bar");
}
TEST(util_path_join, both_alternate_slash_windows)
{
- string str = path_join("foo/", "/bar");
- EXPECT_EQ(str, "foo//bar");
+ string str = path_join("foo/", "/bar");
+ EXPECT_EQ(str, "foo//bar");
}
TEST(util_path_join, empty_dir_filename_slash_windows)
{
- string str = path_join("", "\\foo.txt");
- EXPECT_EQ(str, "\\foo.txt");
+ string str = path_join("", "\\foo.txt");
+ EXPECT_EQ(str, "\\foo.txt");
}
TEST(util_path_join, empty_dir_filename_alternate_slash_windows)
{
- string str = path_join("", "/foo.txt");
- EXPECT_EQ(str, "/foo.txt");
+ string str = path_join("", "/foo.txt");
+ EXPECT_EQ(str, "/foo.txt");
}
TEST(util_path_join, empty_filename_dir_slash_windows)
{
- string str = path_join("foo\\", "");
- EXPECT_EQ(str, "foo\\");
+ string str = path_join("foo\\", "");
+ EXPECT_EQ(str, "foo\\");
}
TEST(util_path_join, empty_filename_dir_alternate_slash_windows)
{
- string str = path_join("foo/", "");
- EXPECT_EQ(str, "foo/");
+ string str = path_join("foo/", "");
+ EXPECT_EQ(str, "foo/");
}
-#endif /* !_WIN32 */
+#endif /* !_WIN32 */
/* ******** Tests for path_escape() ******** */
TEST(util_path_escape, no_escape_chars)
{
- string str = path_escape("/tmp/foo/bar");
- EXPECT_EQ(str, "/tmp/foo/bar");
+ string str = path_escape("/tmp/foo/bar");
+ EXPECT_EQ(str, "/tmp/foo/bar");
}
TEST(util_path_escape, simple)
{
- string str = path_escape("/tmp/foo bar");
- EXPECT_EQ(str, "/tmp/foo\\ bar");
+ string str = path_escape("/tmp/foo bar");
+ EXPECT_EQ(str, "/tmp/foo\\ bar");
}
TEST(util_path_escape, simple_end)
{
- string str = path_escape("/tmp/foo/bar ");
- EXPECT_EQ(str, "/tmp/foo/bar\\ ");
+ string str = path_escape("/tmp/foo/bar ");
+ EXPECT_EQ(str, "/tmp/foo/bar\\ ");
}
TEST(util_path_escape, multiple)
{
- string str = path_escape("/tmp/foo bar");
- EXPECT_EQ(str, "/tmp/foo\\ \\ bar");
+ string str = path_escape("/tmp/foo bar");
+ EXPECT_EQ(str, "/tmp/foo\\ \\ bar");
}
TEST(util_path_escape, simple_multiple_end)
{
- string str = path_escape("/tmp/foo/bar ");
- EXPECT_EQ(str, "/tmp/foo/bar\\ \\ ");
+ string str = path_escape("/tmp/foo/bar ");
+ EXPECT_EQ(str, "/tmp/foo/bar\\ \\ ");
}
/* ******** Tests for path_is_relative() ******** */
TEST(util_path_is_relative, filename)
{
- bool is_relative = path_is_relative("foo.txt");
- EXPECT_TRUE(is_relative);
+ bool is_relative = path_is_relative("foo.txt");
+ EXPECT_TRUE(is_relative);
}
#ifndef _WIN32
TEST(util_path_is_relative, absolute_unix)
{
- bool is_relative = path_is_relative("/tmp/foo.txt");
- EXPECT_FALSE(is_relative);
+ bool is_relative = path_is_relative("/tmp/foo.txt");
+ EXPECT_FALSE(is_relative);
}
TEST(util_path_is_relative, relative_dir_unix)
{
- bool is_relative = path_is_relative("tmp/foo.txt");
- EXPECT_TRUE(is_relative);
+ bool is_relative = path_is_relative("tmp/foo.txt");
+ EXPECT_TRUE(is_relative);
}
TEST(util_path_is_relative, absolute_windir_on_unix)
{
- bool is_relative = path_is_relative("C:\\tmp\\foo.txt");
- EXPECT_TRUE(is_relative);
+ bool is_relative = path_is_relative("C:\\tmp\\foo.txt");
+ EXPECT_TRUE(is_relative);
}
TEST(util_path_is_relative, relative_windir_on_unix)
{
- bool is_relative = path_is_relative("tmp\\foo.txt");
- EXPECT_TRUE(is_relative);
+ bool is_relative = path_is_relative("tmp\\foo.txt");
+ EXPECT_TRUE(is_relative);
}
-#endif /* !_WIN32 */
+#endif /* !_WIN32 */
#ifdef _WIN32
TEST(util_path_is_relative, absolute_windows)
{
- bool is_relative = path_is_relative("C:\\tmp\\foo.txt");
- EXPECT_FALSE(is_relative);
+ bool is_relative = path_is_relative("C:\\tmp\\foo.txt");
+ EXPECT_FALSE(is_relative);
}
TEST(util_path_is_relative, relative_dir_windows)
{
- bool is_relative = path_is_relative("tmp\\foo.txt");
- EXPECT_TRUE(is_relative);
+ bool is_relative = path_is_relative("tmp\\foo.txt");
+ EXPECT_TRUE(is_relative);
}
TEST(util_path_is_relative, absolute_unixdir_on_windows)
{
- bool is_relative = path_is_relative("/tmp/foo.txt");
- EXPECT_TRUE(is_relative);
+ bool is_relative = path_is_relative("/tmp/foo.txt");
+ EXPECT_TRUE(is_relative);
}
TEST(util_path_is_relative, relative_unixdir_on_windows)
{
- bool is_relative = path_is_relative("tmp/foo.txt");
- EXPECT_TRUE(is_relative);
+ bool is_relative = path_is_relative("tmp/foo.txt");
+ EXPECT_TRUE(is_relative);
}
-#endif /* _WIN32 */
+#endif /* _WIN32 */
CCL_NAMESPACE_END
diff --git a/intern/cycles/test/util_string_test.cpp b/intern/cycles/test/util_string_test.cpp
index 6c059ba5d12..97f8daa65de 100644
--- a/intern/cycles/test/util_string_test.cpp
+++ b/intern/cycles/test/util_string_test.cpp
@@ -24,262 +24,261 @@ CCL_NAMESPACE_BEGIN
TEST(util_string_printf, no_format)
{
- string str = string_printf("foo bar");
- EXPECT_EQ("foo bar", str);
+ string str = string_printf("foo bar");
+ EXPECT_EQ("foo bar", str);
}
TEST(util_string_printf, int_number)
{
- string str = string_printf("foo %d bar", 314);
- EXPECT_EQ("foo 314 bar", str);
+ string str = string_printf("foo %d bar", 314);
+ EXPECT_EQ("foo 314 bar", str);
}
TEST(util_string_printf, float_number_default_precision)
{
- string str = string_printf("foo %f bar", 3.1415);
- EXPECT_EQ("foo 3.141500 bar", str);
+ string str = string_printf("foo %f bar", 3.1415);
+ EXPECT_EQ("foo 3.141500 bar", str);
}
TEST(util_string_printf, float_number_custom_precision)
{
- string str = string_printf("foo %.1f bar", 3.1415);
- EXPECT_EQ("foo 3.1 bar", str);
+ string str = string_printf("foo %.1f bar", 3.1415);
+ EXPECT_EQ("foo 3.1 bar", str);
}
/* ******** Tests for string_printf() ******** */
TEST(util_string_iequals, empty_a)
{
- bool equals = string_iequals("", "foo");
- EXPECT_FALSE(equals);
+ bool equals = string_iequals("", "foo");
+ EXPECT_FALSE(equals);
}
TEST(util_string_iequals, empty_b)
{
- bool equals = string_iequals("foo", "");
- EXPECT_FALSE(equals);
+ bool equals = string_iequals("foo", "");
+ EXPECT_FALSE(equals);
}
TEST(util_string_iequals, same_register)
{
- bool equals = string_iequals("foo", "foo");
- EXPECT_TRUE(equals);
+ bool equals = string_iequals("foo", "foo");
+ EXPECT_TRUE(equals);
}
TEST(util_string_iequals, different_register)
{
- bool equals = string_iequals("XFoo", "XfoO");
- EXPECT_TRUE(equals);
+ bool equals = string_iequals("XFoo", "XfoO");
+ EXPECT_TRUE(equals);
}
/* ******** Tests for string_split() ******** */
TEST(util_string_split, empty)
{
- vector<string> tokens;
- string_split(tokens, "");
- EXPECT_EQ(tokens.size(), 0);
+ vector<string> tokens;
+ string_split(tokens, "");
+ EXPECT_EQ(tokens.size(), 0);
}
TEST(util_string_split, only_spaces)
{
- vector<string> tokens;
- string_split(tokens, " \t\t \t");
- EXPECT_EQ(tokens.size(), 0);
+ vector<string> tokens;
+ string_split(tokens, " \t\t \t");
+ EXPECT_EQ(tokens.size(), 0);
}
TEST(util_string_split, single)
{
- vector<string> tokens;
- string_split(tokens, "foo");
- EXPECT_EQ(tokens.size(), 1);
- EXPECT_EQ(tokens[0], "foo");
+ vector<string> tokens;
+ string_split(tokens, "foo");
+ EXPECT_EQ(tokens.size(), 1);
+ EXPECT_EQ(tokens[0], "foo");
}
TEST(util_string_split, simple)
{
- vector<string> tokens;
- string_split(tokens, "foo a bar b");
- EXPECT_EQ(tokens.size(), 4);
- EXPECT_EQ(tokens[0], "foo");
- EXPECT_EQ(tokens[1], "a");
- EXPECT_EQ(tokens[2], "bar");
- EXPECT_EQ(tokens[3], "b");
+ vector<string> tokens;
+ string_split(tokens, "foo a bar b");
+ EXPECT_EQ(tokens.size(), 4);
+ EXPECT_EQ(tokens[0], "foo");
+ EXPECT_EQ(tokens[1], "a");
+ EXPECT_EQ(tokens[2], "bar");
+ EXPECT_EQ(tokens[3], "b");
}
TEST(util_string_split, multiple_spaces)
{
- vector<string> tokens;
- string_split(tokens, " \t foo \ta bar b\t ");
- EXPECT_EQ(tokens.size(), 4);
- EXPECT_EQ(tokens[0], "foo");
- EXPECT_EQ(tokens[1], "a");
- EXPECT_EQ(tokens[2], "bar");
- EXPECT_EQ(tokens[3], "b");
+ vector<string> tokens;
+ string_split(tokens, " \t foo \ta bar b\t ");
+ EXPECT_EQ(tokens.size(), 4);
+ EXPECT_EQ(tokens[0], "foo");
+ EXPECT_EQ(tokens[1], "a");
+ EXPECT_EQ(tokens[2], "bar");
+ EXPECT_EQ(tokens[3], "b");
}
/* ******** Tests for string_replace() ******** */
TEST(util_string_replace, empty_haystack_and_other)
{
- string str = "";
- string_replace(str, "x", "");
- EXPECT_EQ(str, "");
+ string str = "";
+ string_replace(str, "x", "");
+ EXPECT_EQ(str, "");
}
TEST(util_string_replace, empty_haystack)
{
- string str = "";
- string_replace(str, "x", "y");
- EXPECT_EQ(str, "");
+ string str = "";
+ string_replace(str, "x", "y");
+ EXPECT_EQ(str, "");
}
TEST(util_string_replace, empty_other)
{
- string str = "x";
- string_replace(str, "x", "");
- EXPECT_EQ(str, "");
+ string str = "x";
+ string_replace(str, "x", "");
+ EXPECT_EQ(str, "");
}
TEST(util_string_replace, long_haystack_empty_other)
{
- string str = "a x b xxc";
- string_replace(str, "x", "");
- EXPECT_EQ(str, "a b c");
+ string str = "a x b xxc";
+ string_replace(str, "x", "");
+ EXPECT_EQ(str, "a b c");
}
TEST(util_string_replace, long_haystack)
{
- string str = "a x b xxc";
- string_replace(str, "x", "FOO");
- EXPECT_EQ(str, "a FOO b FOOFOOc");
+ string str = "a x b xxc";
+ string_replace(str, "x", "FOO");
+ EXPECT_EQ(str, "a FOO b FOOFOOc");
}
/* ******** Tests for string_endswith() ******** */
TEST(util_string_endswith, empty_both)
{
- bool endswith = string_endswith("", "");
- EXPECT_TRUE(endswith);
+ bool endswith = string_endswith("", "");
+ EXPECT_TRUE(endswith);
}
TEST(util_string_endswith, empty_string)
{
- bool endswith = string_endswith("", "foo");
- EXPECT_FALSE(endswith);
+ bool endswith = string_endswith("", "foo");
+ EXPECT_FALSE(endswith);
}
TEST(util_string_endswith, empty_end)
{
- bool endswith = string_endswith("foo", "");
- EXPECT_TRUE(endswith);
+ bool endswith = string_endswith("foo", "");
+ EXPECT_TRUE(endswith);
}
TEST(util_string_endswith, simple_true)
{
- bool endswith = string_endswith("foo bar", "bar");
- EXPECT_TRUE(endswith);
+ bool endswith = string_endswith("foo bar", "bar");
+ EXPECT_TRUE(endswith);
}
TEST(util_string_endswith, simple_false)
{
- bool endswith = string_endswith("foo bar", "foo");
- EXPECT_FALSE(endswith);
+ bool endswith = string_endswith("foo bar", "foo");
+ EXPECT_FALSE(endswith);
}
/* ******** Tests for string_strip() ******** */
TEST(util_string_strip, empty)
{
- string str = string_strip("");
- EXPECT_EQ(str, "");
+ string str = string_strip("");
+ EXPECT_EQ(str, "");
}
TEST(util_string_strip, only_spaces)
{
- string str = string_strip(" ");
- EXPECT_EQ(str, "");
+ string str = string_strip(" ");
+ EXPECT_EQ(str, "");
}
TEST(util_string_strip, no_spaces)
{
- string str = string_strip("foo bar");
- EXPECT_EQ(str, "foo bar");
+ string str = string_strip("foo bar");
+ EXPECT_EQ(str, "foo bar");
}
TEST(util_string_strip, with_spaces)
{
- string str = string_strip(" foo bar ");
- EXPECT_EQ(str, "foo bar");
+ string str = string_strip(" foo bar ");
+ EXPECT_EQ(str, "foo bar");
}
/* ******** Tests for string_remove_trademark() ******** */
TEST(util_string_remove_trademark, empty)
{
- string str = string_remove_trademark("");
- EXPECT_EQ(str, "");
+ string str = string_remove_trademark("");
+ EXPECT_EQ(str, "");
}
TEST(util_string_remove_trademark, no_trademark)
{
- string str = string_remove_trademark("foo bar");
- EXPECT_EQ(str, "foo bar");
+ string str = string_remove_trademark("foo bar");
+ EXPECT_EQ(str, "foo bar");
}
TEST(util_string_remove_trademark, only_tm)
{
- string str = string_remove_trademark("foo bar(TM) zzz");
- EXPECT_EQ(str, "foo bar zzz");
+ string str = string_remove_trademark("foo bar(TM) zzz");
+ EXPECT_EQ(str, "foo bar zzz");
}
TEST(util_string_remove_trademark, only_r)
{
- string str = string_remove_trademark("foo bar(R) zzz");
- EXPECT_EQ(str, "foo bar zzz");
+ string str = string_remove_trademark("foo bar(R) zzz");
+ EXPECT_EQ(str, "foo bar zzz");
}
TEST(util_string_remove_trademark, both)
{
- string str = string_remove_trademark("foo bar(TM)(R) zzz");
- EXPECT_EQ(str, "foo bar zzz");
+ string str = string_remove_trademark("foo bar(TM)(R) zzz");
+ EXPECT_EQ(str, "foo bar zzz");
}
TEST(util_string_remove_trademark, both_space)
{
- string str = string_remove_trademark("foo bar(TM) (R) zzz");
- EXPECT_EQ(str, "foo bar zzz");
+ string str = string_remove_trademark("foo bar(TM) (R) zzz");
+ EXPECT_EQ(str, "foo bar zzz");
}
TEST(util_string_remove_trademark, both_space_around)
{
- string str = string_remove_trademark("foo bar (TM) (R) zzz");
- EXPECT_EQ(str, "foo bar zzz");
+ string str = string_remove_trademark("foo bar (TM) (R) zzz");
+ EXPECT_EQ(str, "foo bar zzz");
}
TEST(util_string_remove_trademark, trademark_space_suffix)
{
- string str = string_remove_trademark("foo bar (TM)");
- EXPECT_EQ(str, "foo bar");
+ string str = string_remove_trademark("foo bar (TM)");
+ EXPECT_EQ(str, "foo bar");
}
TEST(util_string_remove_trademark, trademark_space_middle)
{
- string str = string_remove_trademark("foo bar (TM) baz");
- EXPECT_EQ(str, "foo bar baz");
+ string str = string_remove_trademark("foo bar (TM) baz");
+ EXPECT_EQ(str, "foo bar baz");
}
-
TEST(util_string_remove_trademark, r_space_suffix)
{
- string str = string_remove_trademark("foo bar (R)");
- EXPECT_EQ(str, "foo bar");
+ string str = string_remove_trademark("foo bar (R)");
+ EXPECT_EQ(str, "foo bar");
}
TEST(util_string_remove_trademark, r_space_middle)
{
- string str = string_remove_trademark("foo bar (R) baz");
- EXPECT_EQ(str, "foo bar baz");
+ string str = string_remove_trademark("foo bar (R) baz");
+ EXPECT_EQ(str, "foo bar baz");
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/test/util_task_test.cpp b/intern/cycles/test/util_task_test.cpp
index 2268206b214..a8b4dfc3a37 100644
--- a/intern/cycles/test/util_task_test.cpp
+++ b/intern/cycles/test/util_task_test.cpp
@@ -22,35 +22,38 @@ CCL_NAMESPACE_BEGIN
namespace {
-void task_run() {
+void task_run()
+{
}
} // namespace
-TEST(util_task, basic) {
- TaskScheduler::init(0);
- TaskPool pool;
- for(int i = 0; i < 100; ++i) {
- pool.push(function_bind(task_run));
- }
- TaskPool::Summary summary;
- pool.wait_work(&summary);
- TaskScheduler::exit();
- EXPECT_EQ(summary.num_tasks_handled, 100);
+TEST(util_task, basic)
+{
+ TaskScheduler::init(0);
+ TaskPool pool;
+ for (int i = 0; i < 100; ++i) {
+ pool.push(function_bind(task_run));
+ }
+ TaskPool::Summary summary;
+ pool.wait_work(&summary);
+ TaskScheduler::exit();
+ EXPECT_EQ(summary.num_tasks_handled, 100);
}
-TEST(util_task, multiple_times) {
- for(int N = 0; N < 1000; ++N) {
- TaskScheduler::init(0);
- TaskPool pool;
- for(int i = 0; i < 100; ++i) {
- pool.push(function_bind(task_run));
- }
- TaskPool::Summary summary;
- pool.wait_work(&summary);
- TaskScheduler::exit();
- EXPECT_EQ(summary.num_tasks_handled, 100);
- }
+TEST(util_task, multiple_times)
+{
+ for (int N = 0; N < 1000; ++N) {
+ TaskScheduler::init(0);
+ TaskPool pool;
+ for (int i = 0; i < 100; ++i) {
+ pool.push(function_bind(task_run));
+ }
+ TaskPool::Summary summary;
+ pool.wait_work(&summary);
+ TaskScheduler::exit();
+ EXPECT_EQ(summary.num_tasks_handled, 100);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/test/util_time_test.cpp b/intern/cycles/test/util_time_test.cpp
index 74f9f3b2134..ab5ead2c7b1 100644
--- a/intern/cycles/test/util_time_test.cpp
+++ b/intern/cycles/test/util_time_test.cpp
@@ -20,45 +20,50 @@
CCL_NAMESPACE_BEGIN
-TEST(time_human_readable_to_seconds, Empty) {
- EXPECT_EQ(time_human_readable_to_seconds(""), 0.0);
- EXPECT_EQ(time_human_readable_from_seconds(0.0), "00:00.00");
+TEST(time_human_readable_to_seconds, Empty)
+{
+ EXPECT_EQ(time_human_readable_to_seconds(""), 0.0);
+ EXPECT_EQ(time_human_readable_from_seconds(0.0), "00:00.00");
}
-TEST(time_human_readable_to_seconds, Fraction) {
- EXPECT_NEAR(time_human_readable_to_seconds(".1"), 0.1, 1e-8f);
- EXPECT_NEAR(time_human_readable_to_seconds(".10"), 0.1, 1e-8f);
- EXPECT_EQ(time_human_readable_from_seconds(0.1), "00:00.10");
+TEST(time_human_readable_to_seconds, Fraction)
+{
+ EXPECT_NEAR(time_human_readable_to_seconds(".1"), 0.1, 1e-8f);
+ EXPECT_NEAR(time_human_readable_to_seconds(".10"), 0.1, 1e-8f);
+ EXPECT_EQ(time_human_readable_from_seconds(0.1), "00:00.10");
}
-TEST(time_human_readable_to_seconds, Seconds) {
- EXPECT_NEAR(time_human_readable_to_seconds("2.1"), 2.1, 1e-8f);
- EXPECT_NEAR(time_human_readable_to_seconds("02.10"), 2.1, 1e-8f);
- EXPECT_EQ(time_human_readable_from_seconds(2.1), "00:02.10");
+TEST(time_human_readable_to_seconds, Seconds)
+{
+ EXPECT_NEAR(time_human_readable_to_seconds("2.1"), 2.1, 1e-8f);
+ EXPECT_NEAR(time_human_readable_to_seconds("02.10"), 2.1, 1e-8f);
+ EXPECT_EQ(time_human_readable_from_seconds(2.1), "00:02.10");
- EXPECT_NEAR(time_human_readable_to_seconds("12.1"), 12.1, 1e-8f);
- EXPECT_NEAR(time_human_readable_to_seconds("12.10"), 12.1, 1e-8f);
- EXPECT_EQ(time_human_readable_from_seconds(12.1), "00:12.10");
+ EXPECT_NEAR(time_human_readable_to_seconds("12.1"), 12.1, 1e-8f);
+ EXPECT_NEAR(time_human_readable_to_seconds("12.10"), 12.1, 1e-8f);
+ EXPECT_EQ(time_human_readable_from_seconds(12.1), "00:12.10");
}
-TEST(time_human_readable_to_seconds, MinutesSeconds) {
- EXPECT_NEAR(time_human_readable_to_seconds("3:2.1"), 182.1, 1e-8f);
- EXPECT_NEAR(time_human_readable_to_seconds("03:02.10"), 182.1, 1e-8f);
- EXPECT_EQ(time_human_readable_from_seconds(182.1), "03:02.10");
+TEST(time_human_readable_to_seconds, MinutesSeconds)
+{
+ EXPECT_NEAR(time_human_readable_to_seconds("3:2.1"), 182.1, 1e-8f);
+ EXPECT_NEAR(time_human_readable_to_seconds("03:02.10"), 182.1, 1e-8f);
+ EXPECT_EQ(time_human_readable_from_seconds(182.1), "03:02.10");
- EXPECT_NEAR(time_human_readable_to_seconds("34:12.1"), 2052.1, 1e-8f);
- EXPECT_NEAR(time_human_readable_to_seconds("34:12.10"), 2052.1, 1e-8f);
- EXPECT_EQ(time_human_readable_from_seconds(2052.1), "34:12.10");
+ EXPECT_NEAR(time_human_readable_to_seconds("34:12.1"), 2052.1, 1e-8f);
+ EXPECT_NEAR(time_human_readable_to_seconds("34:12.10"), 2052.1, 1e-8f);
+ EXPECT_EQ(time_human_readable_from_seconds(2052.1), "34:12.10");
}
-TEST(time_human_readable_to_seconds, HoursMinutesSeconds) {
- EXPECT_NEAR(time_human_readable_to_seconds("4:3:2.1"), 14582.1, 1e-8f);
- EXPECT_NEAR(time_human_readable_to_seconds("04:03:02.10"), 14582.1, 1e-8f);
- EXPECT_EQ(time_human_readable_from_seconds(14582.1), "04:03:02.10");
+TEST(time_human_readable_to_seconds, HoursMinutesSeconds)
+{
+ EXPECT_NEAR(time_human_readable_to_seconds("4:3:2.1"), 14582.1, 1e-8f);
+ EXPECT_NEAR(time_human_readable_to_seconds("04:03:02.10"), 14582.1, 1e-8f);
+ EXPECT_EQ(time_human_readable_from_seconds(14582.1), "04:03:02.10");
- EXPECT_NEAR(time_human_readable_to_seconds("56:34:12.1"), 203652.1, 1e-8f);
- EXPECT_NEAR(time_human_readable_to_seconds("56:34:12.10"), 203652.1, 1e-8f);
- EXPECT_EQ(time_human_readable_from_seconds(203652.1), "56:34:12.10");
+ EXPECT_NEAR(time_human_readable_to_seconds("56:34:12.1"), 203652.1, 1e-8f);
+ EXPECT_NEAR(time_human_readable_to_seconds("56:34:12.10"), 203652.1, 1e-8f);
+ EXPECT_EQ(time_human_readable_from_seconds(203652.1), "56:34:12.10");
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index b8b38a531ea..1c7a6549253 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -1,30 +1,30 @@
set(INC
- ..
- ../../glew-mx
+ ..
+ ../../glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_DIR}
+ ${GLEW_INCLUDE_DIR}
)
set(SRC
- util_aligned_malloc.cpp
- util_debug.cpp
- util_ies.cpp
- util_logging.cpp
- util_math_cdf.cpp
- util_md5.cpp
- util_murmurhash.cpp
- util_path.cpp
- util_profiling.cpp
- util_string.cpp
- util_simd.cpp
- util_system.cpp
- util_task.cpp
- util_thread.cpp
- util_time.cpp
- util_transform.cpp
+ util_aligned_malloc.cpp
+ util_debug.cpp
+ util_ies.cpp
+ util_logging.cpp
+ util_math_cdf.cpp
+ util_md5.cpp
+ util_murmurhash.cpp
+ util_path.cpp
+ util_profiling.cpp
+ util_string.cpp
+ util_simd.cpp
+ util_system.cpp
+ util_task.cpp
+ util_thread.cpp
+ util_time.cpp
+ util_transform.cpp
)
set(LIB
@@ -32,117 +32,117 @@ set(LIB
)
if(WITH_CYCLES_STANDALONE)
- if (WITH_CYCLES_STANDALONE_GUI)
- list(APPEND SRC
- util_view.cpp
- )
- endif()
+ if (WITH_CYCLES_STANDALONE_GUI)
+ list(APPEND SRC
+ util_view.cpp
+ )
+ endif()
endif()
if(CYCLES_STANDALONE_REPOSITORY)
- list(APPEND INC_SYS ../../third_party/numaapi/include)
+ list(APPEND INC_SYS ../../third_party/numaapi/include)
else()
- list(APPEND INC_SYS ../../numaapi/include)
+ list(APPEND INC_SYS ../../numaapi/include)
endif()
set(SRC_HEADERS
- util_algorithm.h
- util_aligned_malloc.h
- util_args.h
- util_array.h
- util_atomic.h
- util_boundbox.h
- util_debug.h
- util_defines.h
- util_guarded_allocator.cpp
- util_foreach.h
- util_function.h
- util_guarded_allocator.h
- util_half.h
- util_hash.h
- util_ies.h
- util_image.h
- util_image_impl.h
- util_list.h
- util_logging.h
- util_map.h
- util_math.h
- util_math_cdf.h
- util_math_fast.h
- util_math_intersect.h
- util_math_float2.h
- util_math_float3.h
- util_math_float4.h
- util_math_int2.h
- util_math_int3.h
- util_math_int4.h
- util_math_matrix.h
- util_md5.h
- util_murmurhash.h
- util_opengl.h
- util_optimization.h
- util_param.h
- util_path.h
- util_profiling.h
- util_progress.h
- util_projection.h
- util_queue.h
- util_rect.h
- util_set.h
- util_simd.h
- util_sky_model.cpp
- util_sky_model.h
- util_sky_model_data.h
- util_avxf.h
- util_avxb.h
- util_sseb.h
- util_ssef.h
- util_ssei.h
- util_stack_allocator.h
- util_static_assert.h
- util_stats.h
- util_string.h
- util_system.h
- util_task.h
- util_texture.h
- util_thread.h
- util_time.h
- util_transform.h
- util_types.h
- util_types_float2.h
- util_types_float2_impl.h
- util_types_float3.h
- util_types_float3_impl.h
- util_types_float4.h
- util_types_float4_impl.h
- util_types_float8.h
- util_types_float8_impl.h
- util_types_int2.h
- util_types_int2_impl.h
- util_types_int3.h
- util_types_int3_impl.h
- util_types_int4.h
- util_types_int4_impl.h
- util_types_uchar2.h
- util_types_uchar2_impl.h
- util_types_uchar3.h
- util_types_uchar3_impl.h
- util_types_uchar4.h
- util_types_uchar4_impl.h
- util_types_uint2.h
- util_types_uint2_impl.h
- util_types_uint3.h
- util_types_uint3_impl.h
- util_types_uint4.h
- util_types_uint4_impl.h
- util_types_ushort4.h
- util_types_vector3.h
- util_types_vector3_impl.h
- util_vector.h
- util_version.h
- util_view.h
- util_windows.h
- util_xml.h
+ util_algorithm.h
+ util_aligned_malloc.h
+ util_args.h
+ util_array.h
+ util_atomic.h
+ util_boundbox.h
+ util_debug.h
+ util_defines.h
+ util_guarded_allocator.cpp
+ util_foreach.h
+ util_function.h
+ util_guarded_allocator.h
+ util_half.h
+ util_hash.h
+ util_ies.h
+ util_image.h
+ util_image_impl.h
+ util_list.h
+ util_logging.h
+ util_map.h
+ util_math.h
+ util_math_cdf.h
+ util_math_fast.h
+ util_math_intersect.h
+ util_math_float2.h
+ util_math_float3.h
+ util_math_float4.h
+ util_math_int2.h
+ util_math_int3.h
+ util_math_int4.h
+ util_math_matrix.h
+ util_md5.h
+ util_murmurhash.h
+ util_opengl.h
+ util_optimization.h
+ util_param.h
+ util_path.h
+ util_profiling.h
+ util_progress.h
+ util_projection.h
+ util_queue.h
+ util_rect.h
+ util_set.h
+ util_simd.h
+ util_sky_model.cpp
+ util_sky_model.h
+ util_sky_model_data.h
+ util_avxf.h
+ util_avxb.h
+ util_sseb.h
+ util_ssef.h
+ util_ssei.h
+ util_stack_allocator.h
+ util_static_assert.h
+ util_stats.h
+ util_string.h
+ util_system.h
+ util_task.h
+ util_texture.h
+ util_thread.h
+ util_time.h
+ util_transform.h
+ util_types.h
+ util_types_float2.h
+ util_types_float2_impl.h
+ util_types_float3.h
+ util_types_float3_impl.h
+ util_types_float4.h
+ util_types_float4_impl.h
+ util_types_float8.h
+ util_types_float8_impl.h
+ util_types_int2.h
+ util_types_int2_impl.h
+ util_types_int3.h
+ util_types_int3_impl.h
+ util_types_int4.h
+ util_types_int4_impl.h
+ util_types_uchar2.h
+ util_types_uchar2_impl.h
+ util_types_uchar3.h
+ util_types_uchar3_impl.h
+ util_types_uchar4.h
+ util_types_uchar4_impl.h
+ util_types_uint2.h
+ util_types_uint2_impl.h
+ util_types_uint3.h
+ util_types_uint3_impl.h
+ util_types_uint4.h
+ util_types_uint4_impl.h
+ util_types_ushort4.h
+ util_types_vector3.h
+ util_types_vector3_impl.h
+ util_vector.h
+ util_version.h
+ util_view.h
+ util_windows.h
+ util_xml.h
)
include_directories(${INC})
diff --git a/intern/cycles/util/util_algorithm.h b/intern/cycles/util/util_algorithm.h
index f9e6476cc52..62093039625 100644
--- a/intern/cycles/util/util_algorithm.h
+++ b/intern/cycles/util/util_algorithm.h
@@ -21,12 +21,12 @@
CCL_NAMESPACE_BEGIN
-using std::sort;
-using std::swap;
using std::max;
using std::min;
using std::remove;
+using std::sort;
+using std::swap;
CCL_NAMESPACE_END
-#endif /* __UTIL_ALGORITHM_H__ */
+#endif /* __UTIL_ALGORITHM_H__ */
diff --git a/intern/cycles/util/util_aligned_malloc.cpp b/intern/cycles/util/util_aligned_malloc.cpp
index cc7252dcc58..104e6c5e3f4 100644
--- a/intern/cycles/util/util_aligned_malloc.cpp
+++ b/intern/cycles/util/util_aligned_malloc.cpp
@@ -29,7 +29,7 @@
# undef __MSVCRT_VERSION__
# endif
# define __MSVCRT_VERSION__ 0x0700
-# endif /* FREE_WINDOWS */
+# endif /* FREE_WINDOWS */
# include <malloc.h>
#else
/* Apple's malloc is 16-byte aligned, and does not have malloc.h, so include
@@ -43,39 +43,39 @@ CCL_NAMESPACE_BEGIN
void *util_aligned_malloc(size_t size, int alignment)
{
#ifdef WITH_BLENDER_GUARDEDALLOC
- return MEM_mallocN_aligned(size, alignment, "Cycles Aligned Alloc");
+ return MEM_mallocN_aligned(size, alignment, "Cycles Aligned Alloc");
#elif defined(_WIN32)
- return _aligned_malloc(size, alignment);
+ return _aligned_malloc(size, alignment);
#elif defined(__APPLE__)
- /* On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
- * they work natively with SSE types with no further work.
- */
- assert(alignment == 16);
- return malloc(size);
+ /* On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
+ * they work natively with SSE types with no further work.
+ */
+ assert(alignment == 16);
+ return malloc(size);
#elif defined(__FreeBSD__) || defined(__NetBSD__)
- void *result;
- if(posix_memalign(&result, alignment, size)) {
- /* Non-zero means allocation error
- * either no allocation or bad alignment value.
- */
- return NULL;
- }
- return result;
-#else /* This is for Linux. */
- return memalign(alignment, size);
+ void *result;
+ if (posix_memalign(&result, alignment, size)) {
+ /* Non-zero means allocation error
+ * either no allocation or bad alignment value.
+ */
+ return NULL;
+ }
+ return result;
+#else /* This is for Linux. */
+ return memalign(alignment, size);
#endif
}
void util_aligned_free(void *ptr)
{
#if defined(WITH_BLENDER_GUARDEDALLOC)
- if(ptr != NULL) {
- MEM_freeN(ptr);
- }
+ if (ptr != NULL) {
+ MEM_freeN(ptr);
+ }
#elif defined(_WIN32)
- _aligned_free(ptr);
+ _aligned_free(ptr);
#else
- free(ptr);
+ free(ptr);
#endif
}
diff --git a/intern/cycles/util/util_aligned_malloc.h b/intern/cycles/util/util_aligned_malloc.h
index 66d77c83454..0f006e95f6a 100644
--- a/intern/cycles/util/util_aligned_malloc.h
+++ b/intern/cycles/util/util_aligned_malloc.h
@@ -32,4 +32,4 @@ void util_aligned_free(void *ptr);
CCL_NAMESPACE_END
-#endif /* __UTIL_ALIGNED_MALLOC_H__ */
+#endif /* __UTIL_ALIGNED_MALLOC_H__ */
diff --git a/intern/cycles/util/util_args.h b/intern/cycles/util/util_args.h
index 9fe54b14d77..be6f2c2b9f1 100644
--- a/intern/cycles/util/util_args.h
+++ b/intern/cycles/util/util_args.h
@@ -28,4 +28,4 @@ OIIO_NAMESPACE_USING
CCL_NAMESPACE_END
-#endif /* __UTIL_ARGS_H__ */
+#endif /* __UTIL_ARGS_H__ */
diff --git a/intern/cycles/util/util_array.h b/intern/cycles/util/util_array.h
index 5f18d434c31..1d7e39344f6 100644
--- a/intern/cycles/util/util_array.h
+++ b/intern/cycles/util/util_array.h
@@ -34,256 +34,250 @@ CCL_NAMESPACE_BEGIN
* - if this is used, we are not tempted to use inefficient operations
* - aligned allocation for CPU native data types */
-template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES>
-class array
-{
-public:
- array()
- : data_(NULL),
- datasize_(0),
- capacity_(0)
- {}
-
- explicit array(size_t newsize)
- {
- if(newsize == 0) {
- data_ = NULL;
- datasize_ = 0;
- capacity_ = 0;
- }
- else {
- data_ = mem_allocate(newsize);
- datasize_ = newsize;
- capacity_ = datasize_;
- }
- }
-
- array(const array& from)
- {
- if(from.datasize_ == 0) {
- data_ = NULL;
- datasize_ = 0;
- capacity_ = 0;
- }
- else {
- data_ = mem_allocate(from.datasize_);
- memcpy(data_, from.data_, from.datasize_*sizeof(T));
- datasize_ = from.datasize_;
- capacity_ = datasize_;
- }
- }
-
- array& operator=(const array& from)
- {
- if(this != &from) {
- resize(from.size());
- memcpy((void*)data_, from.data_, datasize_*sizeof(T));
- }
-
- return *this;
- }
-
- array& operator=(const vector<T>& from)
- {
- resize(from.size());
-
- if(from.size() > 0) {
- memcpy(data_, &from[0], datasize_*sizeof(T));
- }
-
- return *this;
- }
-
- ~array()
- {
- mem_free(data_, capacity_);
- }
-
- bool operator==(const array<T>& other) const
- {
- if(datasize_ != other.datasize_) {
- return false;
- }
-
- return memcmp(data_, other.data_, datasize_*sizeof(T)) == 0;
- }
-
- bool operator!=(const array<T>& other) const
- {
- return !(*this == other);
- }
-
- void steal_data(array& from)
- {
- if(this != &from) {
- clear();
-
- data_ = from.data_;
- datasize_ = from.datasize_;
- capacity_ = from.capacity_;
-
- from.data_ = NULL;
- from.datasize_ = 0;
- from.capacity_ = 0;
- }
- }
-
- T *steal_pointer()
- {
- T *ptr = data_;
- data_ = NULL;
- clear();
- return ptr;
- }
-
- T* resize(size_t newsize)
- {
- if(newsize == 0) {
- clear();
- }
- else if(newsize != datasize_) {
- if(newsize > capacity_) {
- T *newdata = mem_allocate(newsize);
- if(newdata == NULL) {
- /* Allocation failed, likely out of memory. */
- clear();
- return NULL;
- }
- else if(data_ != NULL) {
- memcpy((void *)newdata,
- data_,
- ((datasize_ < newsize)? datasize_: newsize)*sizeof(T));
- mem_free(data_, capacity_);
- }
- data_ = newdata;
- capacity_ = newsize;
- }
- datasize_ = newsize;
- }
- return data_;
- }
-
- T* resize(size_t newsize, const T& value)
- {
- size_t oldsize = size();
- resize(newsize);
-
- for(size_t i = oldsize; i < size(); i++) {
- data_[i] = value;
- }
-
- return data_;
- }
-
- void clear()
- {
- if(data_ != NULL) {
- mem_free(data_, capacity_);
- data_ = NULL;
- }
- datasize_ = 0;
- capacity_ = 0;
- }
-
- size_t empty() const
- {
- return datasize_ == 0;
- }
-
- size_t size() const
- {
- return datasize_;
- }
-
- T* data()
- {
- return data_;
- }
-
- const T* data() const
- {
- return data_;
- }
-
- T& operator[](size_t i) const
- {
- assert(i < datasize_);
- return data_[i];
- }
-
- void reserve(size_t newcapacity)
- {
- if(newcapacity > capacity_) {
- T *newdata = mem_allocate(newcapacity);
- if(data_ != NULL) {
- memcpy(newdata, data_, ((datasize_ < newcapacity)? datasize_: newcapacity)*sizeof(T));
- mem_free(data_, capacity_);
- }
- data_ = newdata;
- capacity_ = newcapacity;
- }
- }
-
- size_t capacity() const
- {
- return capacity_;
- }
-
- // do not use this method unless you are sure the code is not performance critical
- void push_back_slow(const T& t)
- {
- if(capacity_ == datasize_)
- {
- reserve(datasize_ == 0 ? 1 : (size_t)((datasize_ + 1) * 1.2));
- }
-
- data_[datasize_++] = t;
- }
-
- void push_back_reserved(const T& t)
- {
- assert(datasize_ < capacity_);
- push_back_slow(t);
- }
-
- void append(const array<T>& from)
- {
- if(from.size()) {
- size_t old_size = size();
- resize(old_size + from.size());
- memcpy(data_ + old_size, from.data(), sizeof(T) * from.size());
- }
- }
-
-protected:
- inline T* mem_allocate(size_t N)
- {
- if(N == 0) {
- return NULL;
- }
- T *mem = (T*)util_aligned_malloc(sizeof(T)*N, alignment);
- if(mem != NULL) {
- util_guarded_mem_alloc(sizeof(T)*N);
- }
- else {
- throw std::bad_alloc();
- }
- return mem;
- }
-
- inline void mem_free(T *mem, size_t N)
- {
- if(mem != NULL) {
- util_guarded_mem_free(sizeof(T)*N);
- util_aligned_free(mem);
- }
- }
-
- T *data_;
- size_t datasize_;
- size_t capacity_;
+template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class array {
+ public:
+ array() : data_(NULL), datasize_(0), capacity_(0)
+ {
+ }
+
+ explicit array(size_t newsize)
+ {
+ if (newsize == 0) {
+ data_ = NULL;
+ datasize_ = 0;
+ capacity_ = 0;
+ }
+ else {
+ data_ = mem_allocate(newsize);
+ datasize_ = newsize;
+ capacity_ = datasize_;
+ }
+ }
+
+ array(const array &from)
+ {
+ if (from.datasize_ == 0) {
+ data_ = NULL;
+ datasize_ = 0;
+ capacity_ = 0;
+ }
+ else {
+ data_ = mem_allocate(from.datasize_);
+ memcpy(data_, from.data_, from.datasize_ * sizeof(T));
+ datasize_ = from.datasize_;
+ capacity_ = datasize_;
+ }
+ }
+
+ array &operator=(const array &from)
+ {
+ if (this != &from) {
+ resize(from.size());
+ memcpy((void *)data_, from.data_, datasize_ * sizeof(T));
+ }
+
+ return *this;
+ }
+
+ array &operator=(const vector<T> &from)
+ {
+ resize(from.size());
+
+ if (from.size() > 0) {
+ memcpy(data_, &from[0], datasize_ * sizeof(T));
+ }
+
+ return *this;
+ }
+
+ ~array()
+ {
+ mem_free(data_, capacity_);
+ }
+
+ bool operator==(const array<T> &other) const
+ {
+ if (datasize_ != other.datasize_) {
+ return false;
+ }
+
+ return memcmp(data_, other.data_, datasize_ * sizeof(T)) == 0;
+ }
+
+ bool operator!=(const array<T> &other) const
+ {
+ return !(*this == other);
+ }
+
+ void steal_data(array &from)
+ {
+ if (this != &from) {
+ clear();
+
+ data_ = from.data_;
+ datasize_ = from.datasize_;
+ capacity_ = from.capacity_;
+
+ from.data_ = NULL;
+ from.datasize_ = 0;
+ from.capacity_ = 0;
+ }
+ }
+
+ T *steal_pointer()
+ {
+ T *ptr = data_;
+ data_ = NULL;
+ clear();
+ return ptr;
+ }
+
+ T *resize(size_t newsize)
+ {
+ if (newsize == 0) {
+ clear();
+ }
+ else if (newsize != datasize_) {
+ if (newsize > capacity_) {
+ T *newdata = mem_allocate(newsize);
+ if (newdata == NULL) {
+ /* Allocation failed, likely out of memory. */
+ clear();
+ return NULL;
+ }
+ else if (data_ != NULL) {
+ memcpy(
+ (void *)newdata, data_, ((datasize_ < newsize) ? datasize_ : newsize) * sizeof(T));
+ mem_free(data_, capacity_);
+ }
+ data_ = newdata;
+ capacity_ = newsize;
+ }
+ datasize_ = newsize;
+ }
+ return data_;
+ }
+
+ T *resize(size_t newsize, const T &value)
+ {
+ size_t oldsize = size();
+ resize(newsize);
+
+ for (size_t i = oldsize; i < size(); i++) {
+ data_[i] = value;
+ }
+
+ return data_;
+ }
+
+ void clear()
+ {
+ if (data_ != NULL) {
+ mem_free(data_, capacity_);
+ data_ = NULL;
+ }
+ datasize_ = 0;
+ capacity_ = 0;
+ }
+
+ size_t empty() const
+ {
+ return datasize_ == 0;
+ }
+
+ size_t size() const
+ {
+ return datasize_;
+ }
+
+ T *data()
+ {
+ return data_;
+ }
+
+ const T *data() const
+ {
+ return data_;
+ }
+
+ T &operator[](size_t i) const
+ {
+ assert(i < datasize_);
+ return data_[i];
+ }
+
+ void reserve(size_t newcapacity)
+ {
+ if (newcapacity > capacity_) {
+ T *newdata = mem_allocate(newcapacity);
+ if (data_ != NULL) {
+ memcpy(newdata, data_, ((datasize_ < newcapacity) ? datasize_ : newcapacity) * sizeof(T));
+ mem_free(data_, capacity_);
+ }
+ data_ = newdata;
+ capacity_ = newcapacity;
+ }
+ }
+
+ size_t capacity() const
+ {
+ return capacity_;
+ }
+
+ // do not use this method unless you are sure the code is not performance critical
+ void push_back_slow(const T &t)
+ {
+ if (capacity_ == datasize_) {
+ reserve(datasize_ == 0 ? 1 : (size_t)((datasize_ + 1) * 1.2));
+ }
+
+ data_[datasize_++] = t;
+ }
+
+ void push_back_reserved(const T &t)
+ {
+ assert(datasize_ < capacity_);
+ push_back_slow(t);
+ }
+
+ void append(const array<T> &from)
+ {
+ if (from.size()) {
+ size_t old_size = size();
+ resize(old_size + from.size());
+ memcpy(data_ + old_size, from.data(), sizeof(T) * from.size());
+ }
+ }
+
+ protected:
+ inline T *mem_allocate(size_t N)
+ {
+ if (N == 0) {
+ return NULL;
+ }
+ T *mem = (T *)util_aligned_malloc(sizeof(T) * N, alignment);
+ if (mem != NULL) {
+ util_guarded_mem_alloc(sizeof(T) * N);
+ }
+ else {
+ throw std::bad_alloc();
+ }
+ return mem;
+ }
+
+ inline void mem_free(T *mem, size_t N)
+ {
+ if (mem != NULL) {
+ util_guarded_mem_free(sizeof(T) * N);
+ util_aligned_free(mem);
+ }
+ }
+
+ T *data_;
+ size_t datasize_;
+ size_t capacity_;
};
CCL_NAMESPACE_END
-#endif /* __UTIL_ARRAY_H__ */
+#endif /* __UTIL_ARRAY_H__ */
diff --git a/intern/cycles/util/util_atomic.h b/intern/cycles/util/util_atomic.h
index 477b667a6fe..a8ea1dc925e 100644
--- a/intern/cycles/util/util_atomic.h
+++ b/intern/cycles/util/util_atomic.h
@@ -20,94 +20,97 @@
#ifndef __KERNEL_GPU__
/* Using atomic ops header from Blender. */
-#include "atomic_ops.h"
+# include "atomic_ops.h"
-#define atomic_add_and_fetch_float(p, x) atomic_add_and_fetch_fl((p), (x))
-#define atomic_compare_and_swap_float(p, old_val, new_val) atomic_cas_float((p), (old_val), (new_val))
+# define atomic_add_and_fetch_float(p, x) atomic_add_and_fetch_fl((p), (x))
+# define atomic_compare_and_swap_float(p, old_val, new_val) \
+ atomic_cas_float((p), (old_val), (new_val))
-#define atomic_fetch_and_inc_uint32(p) atomic_fetch_and_add_uint32((p), 1)
-#define atomic_fetch_and_dec_uint32(p) atomic_fetch_and_add_uint32((p), -1)
+# define atomic_fetch_and_inc_uint32(p) atomic_fetch_and_add_uint32((p), 1)
+# define atomic_fetch_and_dec_uint32(p) atomic_fetch_and_add_uint32((p), -1)
-#define CCL_LOCAL_MEM_FENCE 0
-#define ccl_barrier(flags) ((void) 0)
+# define CCL_LOCAL_MEM_FENCE 0
+# define ccl_barrier(flags) ((void)0)
-#else /* __KERNEL_GPU__ */
+#else /* __KERNEL_GPU__ */
-#ifdef __KERNEL_OPENCL__
+# ifdef __KERNEL_OPENCL__
/* Float atomics implementation credits:
* http://suhorukov.blogspot.in/2011/12/opencl-11-atomic-operations-on-floating.html
*/
ccl_device_inline float atomic_add_and_fetch_float(volatile ccl_global float *source,
- const float operand)
+ const float operand)
{
- union {
- unsigned int int_value;
- float float_value;
- } new_value;
- union {
- unsigned int int_value;
- float float_value;
- } prev_value;
- do {
- prev_value.float_value = *source;
- new_value.float_value = prev_value.float_value + operand;
- } while(atomic_cmpxchg((volatile ccl_global unsigned int *)source,
- prev_value.int_value,
- new_value.int_value) != prev_value.int_value);
- return new_value.float_value;
+ union {
+ unsigned int int_value;
+ float float_value;
+ } new_value;
+ union {
+ unsigned int int_value;
+ float float_value;
+ } prev_value;
+ do {
+ prev_value.float_value = *source;
+ new_value.float_value = prev_value.float_value + operand;
+ } while (atomic_cmpxchg((volatile ccl_global unsigned int *)source,
+ prev_value.int_value,
+ new_value.int_value) != prev_value.int_value);
+ return new_value.float_value;
}
ccl_device_inline float atomic_compare_and_swap_float(volatile ccl_global float *dest,
- const float old_val, const float new_val)
+ const float old_val,
+ const float new_val)
{
- union {
- unsigned int int_value;
- float float_value;
- } new_value, prev_value, result;
- prev_value.float_value = old_val;
- new_value.float_value = new_val;
- result.int_value = atomic_cmpxchg((volatile ccl_global unsigned int *)dest,
- prev_value.int_value, new_value.int_value);
- return result.float_value;
+ union {
+ unsigned int int_value;
+ float float_value;
+ } new_value, prev_value, result;
+ prev_value.float_value = old_val;
+ new_value.float_value = new_val;
+ result.int_value = atomic_cmpxchg(
+ (volatile ccl_global unsigned int *)dest, prev_value.int_value, new_value.int_value);
+ return result.float_value;
}
-#define atomic_fetch_and_add_uint32(p, x) atomic_add((p), (x))
-#define atomic_fetch_and_inc_uint32(p) atomic_inc((p))
-#define atomic_fetch_and_dec_uint32(p) atomic_dec((p))
+# define atomic_fetch_and_add_uint32(p, x) atomic_add((p), (x))
+# define atomic_fetch_and_inc_uint32(p) atomic_inc((p))
+# define atomic_fetch_and_dec_uint32(p) atomic_dec((p))
-#define CCL_LOCAL_MEM_FENCE CLK_LOCAL_MEM_FENCE
-#define ccl_barrier(flags) barrier(flags)
+# define CCL_LOCAL_MEM_FENCE CLK_LOCAL_MEM_FENCE
+# define ccl_barrier(flags) barrier(flags)
-#endif /* __KERNEL_OPENCL__ */
+# endif /* __KERNEL_OPENCL__ */
-#ifdef __KERNEL_CUDA__
+# ifdef __KERNEL_CUDA__
-#define atomic_add_and_fetch_float(p, x) (atomicAdd((float*)(p), (float)(x)) + (float)(x))
+# define atomic_add_and_fetch_float(p, x) (atomicAdd((float *)(p), (float)(x)) + (float)(x))
-#define atomic_fetch_and_add_uint32(p, x) atomicAdd((unsigned int*)(p), (unsigned int)(x))
-#define atomic_fetch_and_sub_uint32(p, x) atomicSub((unsigned int*)(p), (unsigned int)(x))
-#define atomic_fetch_and_inc_uint32(p) atomic_fetch_and_add_uint32((p), 1)
-#define atomic_fetch_and_dec_uint32(p) atomic_fetch_and_sub_uint32((p), 1)
+# define atomic_fetch_and_add_uint32(p, x) atomicAdd((unsigned int *)(p), (unsigned int)(x))
+# define atomic_fetch_and_sub_uint32(p, x) atomicSub((unsigned int *)(p), (unsigned int)(x))
+# define atomic_fetch_and_inc_uint32(p) atomic_fetch_and_add_uint32((p), 1)
+# define atomic_fetch_and_dec_uint32(p) atomic_fetch_and_sub_uint32((p), 1)
ccl_device_inline float atomic_compare_and_swap_float(volatile float *dest,
- const float old_val, const float new_val)
+ const float old_val,
+ const float new_val)
{
- union {
- unsigned int int_value;
- float float_value;
- } new_value, prev_value, result;
- prev_value.float_value = old_val;
- new_value.float_value = new_val;
- result.int_value = atomicCAS((unsigned int *)dest, prev_value.int_value,new_value.int_value);
- return result.float_value;
+ union {
+ unsigned int int_value;
+ float float_value;
+ } new_value, prev_value, result;
+ prev_value.float_value = old_val;
+ new_value.float_value = new_val;
+ result.int_value = atomicCAS((unsigned int *)dest, prev_value.int_value, new_value.int_value);
+ return result.float_value;
}
-#define CCL_LOCAL_MEM_FENCE
-#define ccl_barrier(flags) __syncthreads()
+# define CCL_LOCAL_MEM_FENCE
+# define ccl_barrier(flags) __syncthreads()
-#endif /* __KERNEL_CUDA__ */
+# endif /* __KERNEL_CUDA__ */
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
-#endif /* __UTIL_ATOMIC_H__ */
+#endif /* __UTIL_ATOMIC_H__ */
diff --git a/intern/cycles/util/util_avxb.h b/intern/cycles/util/util_avxb.h
index 25ef39d39ae..54dd8068eca 100644
--- a/intern/cycles/util/util_avxb.h
+++ b/intern/cycles/util/util_avxb.h
@@ -16,125 +16,214 @@
*/
#ifndef __UTIL_AVXB_H__
-#define __UTIL_AVXB_H__
+# define __UTIL_AVXB_H__
CCL_NAMESPACE_BEGIN
struct avxf;
/*! 4-wide SSE bool type. */
-struct avxb
-{
- typedef avxb Mask; // mask type
- typedef avxf Float; // float type
-
- enum { size = 8 }; // number of SIMD elements
- union { __m256 m256; int32_t v[8]; }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline avxb ( ) {}
- __forceinline avxb ( const avxb& other ) { m256 = other.m256; }
- __forceinline avxb& operator=( const avxb& other ) { m256 = other.m256; return *this; }
-
- __forceinline avxb( const __m256 input ) : m256(input) {}
- __forceinline operator const __m256&( void ) const { return m256; }
- __forceinline operator const __m256i( void ) const { return _mm256_castps_si256(m256); }
- __forceinline operator const __m256d( void ) const { return _mm256_castps_pd(m256); }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constants
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline avxb( FalseTy ) : m256(_mm256_setzero_ps()) {}
- __forceinline avxb( TrueTy ) : m256(_mm256_castsi256_ps(_mm256_set1_epi32(-1))) {}
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline bool operator []( const size_t i ) const { assert(i < 8); return (_mm256_movemask_ps(m256) >> i) & 1; }
- __forceinline int32_t& operator []( const size_t i ) { assert(i < 8); return v[i]; }
+struct avxb {
+ typedef avxb Mask; // mask type
+ typedef avxf Float; // float type
+
+ enum { size = 8 }; // number of SIMD elements
+ union {
+ __m256 m256;
+ int32_t v[8];
+ }; // data
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Constructors, Assignment & Cast Operators
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline avxb()
+ {
+ }
+ __forceinline avxb(const avxb &other)
+ {
+ m256 = other.m256;
+ }
+ __forceinline avxb &operator=(const avxb &other)
+ {
+ m256 = other.m256;
+ return *this;
+ }
+
+ __forceinline avxb(const __m256 input) : m256(input)
+ {
+ }
+ __forceinline operator const __m256 &(void)const
+ {
+ return m256;
+ }
+ __forceinline operator const __m256i(void) const
+ {
+ return _mm256_castps_si256(m256);
+ }
+ __forceinline operator const __m256d(void) const
+ {
+ return _mm256_castps_pd(m256);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Constants
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline avxb(FalseTy) : m256(_mm256_setzero_ps())
+ {
+ }
+ __forceinline avxb(TrueTy) : m256(_mm256_castsi256_ps(_mm256_set1_epi32(-1)))
+ {
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Array Access
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline bool operator[](const size_t i) const
+ {
+ assert(i < 8);
+ return (_mm256_movemask_ps(m256) >> i) & 1;
+ }
+ __forceinline int32_t &operator[](const size_t i)
+ {
+ assert(i < 8);
+ return v[i];
+ }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxb operator !( const avxb& a ) { return _mm256_xor_ps(a, avxb(True)); }
+__forceinline const avxb operator!(const avxb &a)
+{
+ return _mm256_xor_ps(a, avxb(True));
+}
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxb operator &( const avxb& a, const avxb& b ) { return _mm256_and_ps(a, b); }
-__forceinline const avxb operator |( const avxb& a, const avxb& b ) { return _mm256_or_ps (a, b); }
-__forceinline const avxb operator ^( const avxb& a, const avxb& b ) { return _mm256_xor_ps(a, b); }
+__forceinline const avxb operator&(const avxb &a, const avxb &b)
+{
+ return _mm256_and_ps(a, b);
+}
+__forceinline const avxb operator|(const avxb &a, const avxb &b)
+{
+ return _mm256_or_ps(a, b);
+}
+__forceinline const avxb operator^(const avxb &a, const avxb &b)
+{
+ return _mm256_xor_ps(a, b);
+}
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxb operator &=( avxb& a, const avxb& b ) { return a = a & b; }
-__forceinline const avxb operator |=( avxb& a, const avxb& b ) { return a = a | b; }
-__forceinline const avxb operator ^=( avxb& a, const avxb& b ) { return a = a ^ b; }
+__forceinline const avxb operator&=(avxb &a, const avxb &b)
+{
+ return a = a & b;
+}
+__forceinline const avxb operator|=(avxb &a, const avxb &b)
+{
+ return a = a | b;
+}
+__forceinline const avxb operator^=(avxb &a, const avxb &b)
+{
+ return a = a ^ b;
+}
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxb operator !=( const avxb& a, const avxb& b ) { return _mm256_xor_ps(a, b); }
-__forceinline const avxb operator ==( const avxb& a, const avxb& b )
-{
-#ifdef __KERNEL_AVX2__
- return _mm256_castsi256_ps(_mm256_cmpeq_epi32(a, b));
-#else
- __m128i a_lo = _mm_castps_si128(_mm256_extractf128_ps(a, 0));
- __m128i a_hi = _mm_castps_si128(_mm256_extractf128_ps(a, 1));
- __m128i b_lo = _mm_castps_si128(_mm256_extractf128_ps(b, 0));
- __m128i b_hi = _mm_castps_si128(_mm256_extractf128_ps(b, 1));
- __m128i c_lo = _mm_cmpeq_epi32(a_lo, b_lo);
- __m128i c_hi = _mm_cmpeq_epi32(a_hi, b_hi);
- __m256i result = _mm256_insertf128_si256(_mm256_castsi128_si256(c_lo), c_hi, 1);
- return _mm256_castsi256_ps(result);
-#endif
+__forceinline const avxb operator!=(const avxb &a, const avxb &b)
+{
+ return _mm256_xor_ps(a, b);
+}
+__forceinline const avxb operator==(const avxb &a, const avxb &b)
+{
+# ifdef __KERNEL_AVX2__
+ return _mm256_castsi256_ps(_mm256_cmpeq_epi32(a, b));
+# else
+ __m128i a_lo = _mm_castps_si128(_mm256_extractf128_ps(a, 0));
+ __m128i a_hi = _mm_castps_si128(_mm256_extractf128_ps(a, 1));
+ __m128i b_lo = _mm_castps_si128(_mm256_extractf128_ps(b, 0));
+ __m128i b_hi = _mm_castps_si128(_mm256_extractf128_ps(b, 1));
+ __m128i c_lo = _mm_cmpeq_epi32(a_lo, b_lo);
+ __m128i c_hi = _mm_cmpeq_epi32(a_hi, b_hi);
+ __m256i result = _mm256_insertf128_si256(_mm256_castsi128_si256(c_lo), c_hi, 1);
+ return _mm256_castsi256_ps(result);
+# endif
}
-__forceinline const avxb select( const avxb& m, const avxb& t, const avxb& f ) {
-#if defined(__KERNEL_SSE41__)
- return _mm256_blendv_ps(f, t, m);
-#else
- return _mm256_or_ps(_mm256_and_ps(m, t), _mm256_andnot_ps(m, f));
-#endif
+__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
+{
+# if defined(__KERNEL_SSE41__)
+ return _mm256_blendv_ps(f, t, m);
+# else
+ return _mm256_or_ps(_mm256_and_ps(m, t), _mm256_andnot_ps(m, f));
+# endif
}
////////////////////////////////////////////////////////////////////////////////
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxb unpacklo( const avxb& a, const avxb& b ) { return _mm256_unpacklo_ps(a, b); }
-__forceinline const avxb unpackhi( const avxb& a, const avxb& b ) { return _mm256_unpackhi_ps(a, b); }
+__forceinline const avxb unpacklo(const avxb &a, const avxb &b)
+{
+ return _mm256_unpacklo_ps(a, b);
+}
+__forceinline const avxb unpackhi(const avxb &a, const avxb &b)
+{
+ return _mm256_unpackhi_ps(a, b);
+}
////////////////////////////////////////////////////////////////////////////////
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
-#if defined(__KERNEL_SSE41__)
-__forceinline size_t popcnt( const avxb& a ) { return __popcnt(_mm256_movemask_ps(a)); }
-#else
-__forceinline size_t popcnt( const avxb& a ) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3])+bool(a[4])+
- bool(a[5])+bool(a[6])+bool(a[7]); }
-#endif
+# if defined(__KERNEL_SSE41__)
+__forceinline size_t popcnt(const avxb &a)
+{
+ return __popcnt(_mm256_movemask_ps(a));
+}
+# else
+__forceinline size_t popcnt(const avxb &a)
+{
+ return bool(a[0]) + bool(a[1]) + bool(a[2]) + bool(a[3]) + bool(a[4]) + bool(a[5]) + bool(a[6]) +
+ bool(a[7]);
+}
+# endif
-__forceinline bool reduce_and( const avxb& a ) { return _mm256_movemask_ps(a) == 0xf; }
-__forceinline bool reduce_or ( const avxb& a ) { return _mm256_movemask_ps(a) != 0x0; }
-__forceinline bool all ( const avxb& b ) { return _mm256_movemask_ps(b) == 0xf; }
-__forceinline bool any ( const avxb& b ) { return _mm256_movemask_ps(b) != 0x0; }
-__forceinline bool none ( const avxb& b ) { return _mm256_movemask_ps(b) == 0x0; }
+__forceinline bool reduce_and(const avxb &a)
+{
+ return _mm256_movemask_ps(a) == 0xf;
+}
+__forceinline bool reduce_or(const avxb &a)
+{
+ return _mm256_movemask_ps(a) != 0x0;
+}
+__forceinline bool all(const avxb &b)
+{
+ return _mm256_movemask_ps(b) == 0xf;
+}
+__forceinline bool any(const avxb &b)
+{
+ return _mm256_movemask_ps(b) != 0x0;
+}
+__forceinline bool none(const avxb &b)
+{
+ return _mm256_movemask_ps(b) == 0x0;
+}
-__forceinline size_t movemask( const avxb& a ) { return _mm256_movemask_ps(a); }
+__forceinline size_t movemask(const avxb &a)
+{
+ return _mm256_movemask_ps(a);
+}
////////////////////////////////////////////////////////////////////////////////
/// Debug Functions
@@ -142,8 +231,7 @@ __forceinline size_t movemask( const avxb& a ) { return _mm256_movemask_ps(a); }
ccl_device_inline void print_avxb(const char *label, const avxb &a)
{
- printf("%s: %d %d %d %d %d %d %d %d\n",
- label, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
+ printf("%s: %d %d %d %d %d %d %d %d\n", label, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
}
#endif
diff --git a/intern/cycles/util/util_avxf.h b/intern/cycles/util/util_avxf.h
index f00c722f25b..156607e65fb 100644
--- a/intern/cycles/util/util_avxf.h
+++ b/intern/cycles/util/util_avxf.h
@@ -15,217 +15,330 @@
*/
#ifndef __UTIL_AVXF_H__
-#define __UTIL_AVXF_H__
+# define __UTIL_AVXF_H__
CCL_NAMESPACE_BEGIN
struct avxb;
-struct avxf
-{
- typedef avxf Float;
-
- enum { size = 8 }; /* Number of SIMD elements. */
-
- union {
- __m256 m256;
- float f[8];
- int i[8];
- };
-
- __forceinline avxf () {}
- __forceinline avxf (const avxf& other) { m256 = other.m256; }
- __forceinline avxf& operator=(const avxf& other) { m256 = other.m256; return *this; }
-
- __forceinline avxf(const __m256 a) : m256(a) {}
- __forceinline avxf(const __m256i a) : m256(_mm256_castsi256_ps (a)) {}
-
- __forceinline operator const __m256&() const { return m256; }
- __forceinline operator __m256&() { return m256; }
-
- __forceinline avxf (float a) : m256(_mm256_set1_ps(a)) {}
-
- __forceinline avxf(float high32x4, float low32x4) :
- m256(_mm256_set_ps(high32x4, high32x4, high32x4, high32x4, low32x4, low32x4, low32x4, low32x4)) {}
-
- __forceinline avxf(float a3, float a2, float a1, float a0) :
- m256(_mm256_set_ps(a3, a2, a1, a0, a3, a2, a1, a0)) {}
-
- __forceinline avxf(float a7, float a6, float a5, float a4, float a3, float a2, float a1, float a0) :
- m256(_mm256_set_ps(a7, a6, a5, a4, a3, a2, a1, a0)) {}
-
- __forceinline avxf(float3 a) :
- m256(_mm256_set_ps(a.w, a.z, a.y, a.x, a.w, a.z, a.y, a.x)) {}
-
-
- __forceinline avxf(int a3, int a2, int a1, int a0)
- {
- const __m256i foo = _mm256_set_epi32(a3, a2, a1, a0, a3, a2, a1, a0);
- m256 = _mm256_castsi256_ps(foo);
- }
-
-
- __forceinline avxf(int a7, int a6, int a5, int a4, int a3, int a2, int a1, int a0)
- {
- const __m256i foo = _mm256_set_epi32(a7, a6, a5, a4, a3, a2, a1, a0);
- m256 = _mm256_castsi256_ps(foo);
- }
-
- __forceinline avxf(__m128 a, __m128 b)
- {
- const __m256 foo = _mm256_castps128_ps256(a);
- m256 = _mm256_insertf128_ps(foo, b, 1);
- }
-
- __forceinline const float& operator [](const size_t i) const { assert(i < 8); return f[i]; }
- __forceinline float& operator [](const size_t i) { assert(i < 8); return f[i]; }
+struct avxf {
+ typedef avxf Float;
+
+ enum { size = 8 }; /* Number of SIMD elements. */
+
+ union {
+ __m256 m256;
+ float f[8];
+ int i[8];
+ };
+
+ __forceinline avxf()
+ {
+ }
+ __forceinline avxf(const avxf &other)
+ {
+ m256 = other.m256;
+ }
+ __forceinline avxf &operator=(const avxf &other)
+ {
+ m256 = other.m256;
+ return *this;
+ }
+
+ __forceinline avxf(const __m256 a) : m256(a)
+ {
+ }
+ __forceinline avxf(const __m256i a) : m256(_mm256_castsi256_ps(a))
+ {
+ }
+
+ __forceinline operator const __m256 &() const
+ {
+ return m256;
+ }
+ __forceinline operator __m256 &()
+ {
+ return m256;
+ }
+
+ __forceinline avxf(float a) : m256(_mm256_set1_ps(a))
+ {
+ }
+
+ __forceinline avxf(float high32x4, float low32x4)
+ : m256(_mm256_set_ps(
+ high32x4, high32x4, high32x4, high32x4, low32x4, low32x4, low32x4, low32x4))
+ {
+ }
+
+ __forceinline avxf(float a3, float a2, float a1, float a0)
+ : m256(_mm256_set_ps(a3, a2, a1, a0, a3, a2, a1, a0))
+ {
+ }
+
+ __forceinline avxf(
+ float a7, float a6, float a5, float a4, float a3, float a2, float a1, float a0)
+ : m256(_mm256_set_ps(a7, a6, a5, a4, a3, a2, a1, a0))
+ {
+ }
+
+ __forceinline avxf(float3 a) : m256(_mm256_set_ps(a.w, a.z, a.y, a.x, a.w, a.z, a.y, a.x))
+ {
+ }
+
+ __forceinline avxf(int a3, int a2, int a1, int a0)
+ {
+ const __m256i foo = _mm256_set_epi32(a3, a2, a1, a0, a3, a2, a1, a0);
+ m256 = _mm256_castsi256_ps(foo);
+ }
+
+ __forceinline avxf(int a7, int a6, int a5, int a4, int a3, int a2, int a1, int a0)
+ {
+ const __m256i foo = _mm256_set_epi32(a7, a6, a5, a4, a3, a2, a1, a0);
+ m256 = _mm256_castsi256_ps(foo);
+ }
+
+ __forceinline avxf(__m128 a, __m128 b)
+ {
+ const __m256 foo = _mm256_castps128_ps256(a);
+ m256 = _mm256_insertf128_ps(foo, b, 1);
+ }
+
+ __forceinline const float &operator[](const size_t i) const
+ {
+ assert(i < 8);
+ return f[i];
+ }
+ __forceinline float &operator[](const size_t i)
+ {
+ assert(i < 8);
+ return f[i];
+ }
};
-__forceinline avxf cross(const avxf& a, const avxf& b)
+__forceinline avxf cross(const avxf &a, const avxf &b)
{
- avxf r(0.0, a[4]*b[5] - a[5]*b[4], a[6]*b[4] - a[4]*b[6], a[5]*b[6] - a[6]*b[5],
- 0.0, a[0]*b[1] - a[1]*b[0], a[2]*b[0] - a[0]*b[2], a[1]*b[2] - a[2]*b[1]);
- return r;
+ avxf r(0.0,
+ a[4] * b[5] - a[5] * b[4],
+ a[6] * b[4] - a[4] * b[6],
+ a[5] * b[6] - a[6] * b[5],
+ 0.0,
+ a[0] * b[1] - a[1] * b[0],
+ a[2] * b[0] - a[0] * b[2],
+ a[1] * b[2] - a[2] * b[1]);
+ return r;
}
-__forceinline void dot3(const avxf& a, const avxf& b, float &den, float &den2)
+__forceinline void dot3(const avxf &a, const avxf &b, float &den, float &den2)
{
- const avxf t = _mm256_mul_ps(a.m256, b.m256);
- den = ((float*)&t)[0] + ((float*)&t)[1] + ((float*)&t)[2];
- den2 = ((float*)&t)[4] + ((float*)&t)[5] + ((float*)&t)[6];
+ const avxf t = _mm256_mul_ps(a.m256, b.m256);
+ den = ((float *)&t)[0] + ((float *)&t)[1] + ((float *)&t)[2];
+ den2 = ((float *)&t)[4] + ((float *)&t)[5] + ((float *)&t)[6];
}
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxf mm256_sqrt(const avxf& a) { return _mm256_sqrt_ps(a.m256); }
+__forceinline const avxf mm256_sqrt(const avxf &a)
+{
+ return _mm256_sqrt_ps(a.m256);
+}
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxf operator +(const avxf& a, const avxf& b) { return _mm256_add_ps(a.m256, b.m256); }
-__forceinline const avxf operator +(const avxf& a, const float& b) { return a + avxf(b); }
-__forceinline const avxf operator +(const float& a, const avxf& b) { return avxf(a) + b; }
+__forceinline const avxf operator+(const avxf &a, const avxf &b)
+{
+ return _mm256_add_ps(a.m256, b.m256);
+}
+__forceinline const avxf operator+(const avxf &a, const float &b)
+{
+ return a + avxf(b);
+}
+__forceinline const avxf operator+(const float &a, const avxf &b)
+{
+ return avxf(a) + b;
+}
-__forceinline const avxf operator -(const avxf& a, const avxf& b) { return _mm256_sub_ps(a.m256, b.m256); }
-__forceinline const avxf operator -(const avxf& a, const float& b) { return a - avxf(b); }
-__forceinline const avxf operator -(const float& a, const avxf& b) { return avxf(a) - b; }
+__forceinline const avxf operator-(const avxf &a, const avxf &b)
+{
+ return _mm256_sub_ps(a.m256, b.m256);
+}
+__forceinline const avxf operator-(const avxf &a, const float &b)
+{
+ return a - avxf(b);
+}
+__forceinline const avxf operator-(const float &a, const avxf &b)
+{
+ return avxf(a) - b;
+}
-__forceinline const avxf operator *(const avxf& a, const avxf& b) { return _mm256_mul_ps(a.m256, b.m256); }
-__forceinline const avxf operator *(const avxf& a, const float& b) { return a * avxf(b); }
-__forceinline const avxf operator *(const float& a, const avxf& b) { return avxf(a) * b; }
+__forceinline const avxf operator*(const avxf &a, const avxf &b)
+{
+ return _mm256_mul_ps(a.m256, b.m256);
+}
+__forceinline const avxf operator*(const avxf &a, const float &b)
+{
+ return a * avxf(b);
+}
+__forceinline const avxf operator*(const float &a, const avxf &b)
+{
+ return avxf(a) * b;
+}
-__forceinline const avxf operator /(const avxf& a, const avxf& b) { return _mm256_div_ps(a.m256,b.m256); }
-__forceinline const avxf operator /(const avxf& a, const float& b) { return a/avxf(b); }
-__forceinline const avxf operator /(const float& a, const avxf& b) { return avxf(a)/b; }
+__forceinline const avxf operator/(const avxf &a, const avxf &b)
+{
+ return _mm256_div_ps(a.m256, b.m256);
+}
+__forceinline const avxf operator/(const avxf &a, const float &b)
+{
+ return a / avxf(b);
+}
+__forceinline const avxf operator/(const float &a, const avxf &b)
+{
+ return avxf(a) / b;
+}
-__forceinline const avxf operator|(const avxf& a, const avxf& b) { return _mm256_or_ps(a.m256,b.m256); }
+__forceinline const avxf operator|(const avxf &a, const avxf &b)
+{
+ return _mm256_or_ps(a.m256, b.m256);
+}
-__forceinline const avxf operator^(const avxf& a, const avxf& b) { return _mm256_xor_ps(a.m256,b.m256); }
+__forceinline const avxf operator^(const avxf &a, const avxf &b)
+{
+ return _mm256_xor_ps(a.m256, b.m256);
+}
-__forceinline const avxf operator&(const avxf& a, const avxf& b) { return _mm256_and_ps(a.m256,b.m256); }
+__forceinline const avxf operator&(const avxf &a, const avxf &b)
+{
+ return _mm256_and_ps(a.m256, b.m256);
+}
-__forceinline const avxf max(const avxf& a, const avxf& b) { return _mm256_max_ps(a.m256, b.m256); }
-__forceinline const avxf min(const avxf& a, const avxf& b) { return _mm256_min_ps(a.m256, b.m256); }
+__forceinline const avxf max(const avxf &a, const avxf &b)
+{
+ return _mm256_max_ps(a.m256, b.m256);
+}
+__forceinline const avxf min(const avxf &a, const avxf &b)
+{
+ return _mm256_min_ps(a.m256, b.m256);
+}
////////////////////////////////////////////////////////////////////////////////
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxf shuffle(const avxf& a, const __m256i &shuf) {
- return _mm256_permutevar_ps(a, shuf);
+__forceinline const avxf shuffle(const avxf &a, const __m256i &shuf)
+{
+ return _mm256_permutevar_ps(a, shuf);
}
-template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7> __forceinline const avxf shuffle(const avxf& a) {
- return _mm256_permutevar_ps(a, _mm256_set_epi32( i7,i6,i5,i4 ,i3,i2,i1,i0));
+template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7>
+__forceinline const avxf shuffle(const avxf &a)
+{
+ return _mm256_permutevar_ps(a, _mm256_set_epi32(i7, i6, i5, i4, i3, i2, i1, i0));
}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const avxf shuffle(const avxf& a, const avxf& b) {
- return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const avxf shuffle(const avxf &a, const avxf &b)
+{
+ return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const avxf shuffle(const avxf& a) {
- return shuffle<i0,i1,i2,i3>(a,a);
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const avxf shuffle(const avxf &a)
+{
+ return shuffle<i0, i1, i2, i3>(a, a);
}
-template<size_t i0> __forceinline const avxf shuffle(const avxf& a, const avxf& b) {
- return shuffle<i0,i0,i0,i0>(a, b);
+template<size_t i0> __forceinline const avxf shuffle(const avxf &a, const avxf &b)
+{
+ return shuffle<i0, i0, i0, i0>(a, b);
}
-template<size_t i0> __forceinline const avxf shuffle(const avxf& a) {
- return shuffle<i0>(a,a);
+template<size_t i0> __forceinline const avxf shuffle(const avxf &a)
+{
+ return shuffle<i0>(a, a);
}
-template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7> __forceinline const avxf permute(const avxf& a) {
-#ifdef __KERNEL_AVX2__
- return _mm256_permutevar8x32_ps(a,_mm256_set_epi32( i7,i6,i5,i4 ,i3,i2,i1,i0));
-#else
- float temp[8];
- _mm256_storeu_ps((float*)&temp, a);
- return avxf(temp[i7], temp[i6], temp[i5], temp[i4], temp[i3], temp[i2], temp[i1], temp[i0]);
-#endif
+template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7>
+__forceinline const avxf permute(const avxf &a)
+{
+# ifdef __KERNEL_AVX2__
+ return _mm256_permutevar8x32_ps(a, _mm256_set_epi32(i7, i6, i5, i4, i3, i2, i1, i0));
+# else
+ float temp[8];
+ _mm256_storeu_ps((float *)&temp, a);
+ return avxf(temp[i7], temp[i6], temp[i5], temp[i4], temp[i3], temp[i2], temp[i1], temp[i0]);
+# endif
}
-template<int S0, int S1, int S2, int S3,int S4,int S5,int S6, int S7>
+template<int S0, int S1, int S2, int S3, int S4, int S5, int S6, int S7>
ccl_device_inline const avxf set_sign_bit(const avxf &a)
{
- return a ^ avxf(S7 << 31, S6 << 31, S5 << 31, S4 << 31, S3 << 31,S2 << 31,S1 << 31,S0 << 31);
+ return a ^ avxf(S7 << 31, S6 << 31, S5 << 31, S4 << 31, S3 << 31, S2 << 31, S1 << 31, S0 << 31);
}
-template<size_t S0, size_t S1, size_t S2, size_t S3,size_t S4,size_t S5,size_t S6, size_t S7>
+template<size_t S0, size_t S1, size_t S2, size_t S3, size_t S4, size_t S5, size_t S6, size_t S7>
ccl_device_inline const avxf blend(const avxf &a, const avxf &b)
{
- return _mm256_blend_ps(a,b,S7 << 0 | S6 << 1 | S5 << 2 | S4 << 3 | S3 << 4 | S2 << 5 | S1 << 6 | S0 << 7);
+ return _mm256_blend_ps(
+ a, b, S7 << 0 | S6 << 1 | S5 << 2 | S4 << 3 | S3 << 4 | S2 << 5 | S1 << 6 | S0 << 7);
}
-template<size_t S0, size_t S1, size_t S2, size_t S3 >
+template<size_t S0, size_t S1, size_t S2, size_t S3>
ccl_device_inline const avxf blend(const avxf &a, const avxf &b)
{
- return blend<S0,S1,S2,S3,S0,S1,S2,S3>(a,b);
+ return blend<S0, S1, S2, S3, S0, S1, S2, S3>(a, b);
}
//#if defined(__KERNEL_SSE41__)
-__forceinline avxf maxi(const avxf& a, const avxf& b) {
- const avxf ci = _mm256_max_ps(a, b);
- return ci;
+__forceinline avxf maxi(const avxf &a, const avxf &b)
+{
+ const avxf ci = _mm256_max_ps(a, b);
+ return ci;
}
-__forceinline avxf mini(const avxf& a, const avxf& b) {
- const avxf ci = _mm256_min_ps(a, b);
- return ci;
+__forceinline avxf mini(const avxf &a, const avxf &b)
+{
+ const avxf ci = _mm256_min_ps(a, b);
+ return ci;
}
//#endif
////////////////////////////////////////////////////////////////////////////////
/// Ternary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxf madd (const avxf& a, const avxf& b, const avxf& c) {
-#ifdef __KERNEL_AVX2__
- return _mm256_fmadd_ps(a,b,c);
-#else
- return c+(a*b);
-#endif
+__forceinline const avxf madd(const avxf &a, const avxf &b, const avxf &c)
+{
+# ifdef __KERNEL_AVX2__
+ return _mm256_fmadd_ps(a, b, c);
+# else
+ return c + (a * b);
+# endif
}
-__forceinline const avxf nmadd(const avxf& a, const avxf& b, const avxf& c) {
-#ifdef __KERNEL_AVX2__
- return _mm256_fnmadd_ps(a, b, c);
-#else
- return c-(a*b);
-#endif
+__forceinline const avxf nmadd(const avxf &a, const avxf &b, const avxf &c)
+{
+# ifdef __KERNEL_AVX2__
+ return _mm256_fnmadd_ps(a, b, c);
+# else
+ return c - (a * b);
+# endif
}
-__forceinline const avxf msub(const avxf& a, const avxf& b, const avxf& c) {
-#ifdef __KERNEL_AVX2__
- return _mm256_fmsub_ps(a, b, c);
-#else
- return (a*b) - c;
-#endif
+__forceinline const avxf msub(const avxf &a, const avxf &b, const avxf &c)
+{
+# ifdef __KERNEL_AVX2__
+ return _mm256_fmsub_ps(a, b, c);
+# else
+ return (a * b) - c;
+# endif
}
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxb operator <=(const avxf& a, const avxf& b) {
- return _mm256_cmp_ps(a.m256, b.m256, _CMP_LE_OS);
+__forceinline const avxb operator<=(const avxf &a, const avxf &b)
+{
+ return _mm256_cmp_ps(a.m256, b.m256, _CMP_LE_OS);
}
#endif
@@ -236,6 +349,6 @@ __forceinline const avxb operator <=(const avxf& a, const avxf& b) {
#endif
#define _mm256_loadu2_m128(/* float const* */ hiaddr, /* float const* */ loaddr) \
- _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr))
+ _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr))
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h
index fe89e398840..b5c3f1a8954 100644
--- a/intern/cycles/util/util_boundbox.h
+++ b/intern/cycles/util/util_boundbox.h
@@ -29,257 +29,254 @@ CCL_NAMESPACE_BEGIN
/* 3D BoundBox */
-class BoundBox
-{
-public:
- float3 min, max;
-
- __forceinline BoundBox()
- {
- }
-
- __forceinline BoundBox(const float3& pt)
- : min(pt), max(pt)
- {
- }
-
- __forceinline BoundBox(const float3& min_, const float3& max_)
- : min(min_), max(max_)
- {
- }
-
- enum empty_t { empty = 0};
-
- __forceinline BoundBox(empty_t)
- : min(make_float3(FLT_MAX, FLT_MAX, FLT_MAX)), max(make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX))
- {
- }
-
- __forceinline void grow(const float3& pt)
- {
- /* the order of arguments to min is such that if pt is nan, it will not
- * influence the resulting bounding box */
- min = ccl::min(pt, min);
- max = ccl::max(pt, max);
- }
-
- __forceinline void grow(const float3& pt, float border)
- {
- float3 shift = make_float3(border, border, border);
- min = ccl::min(pt - shift, min);
- max = ccl::max(pt + shift, max);
- }
-
- __forceinline void grow(const BoundBox& bbox)
- {
- grow(bbox.min);
- grow(bbox.max);
- }
-
- __forceinline void grow_safe(const float3& pt)
- {
- /* the order of arguments to min is such that if pt is nan, it will not
- * influence the resulting bounding box */
- if(isfinite(pt.x) && isfinite(pt.y) && isfinite(pt.z)) {
- min = ccl::min(pt, min);
- max = ccl::max(pt, max);
- }
- }
-
- __forceinline void grow_safe(const float3& pt, float border)
- {
- if(isfinite(pt.x) && isfinite(pt.y) && isfinite(pt.z) && isfinite(border)) {
- float3 shift = make_float3(border, border, border);
- min = ccl::min(pt - shift, min);
- max = ccl::max(pt + shift, max);
- }
- }
-
- __forceinline void grow_safe(const BoundBox& bbox)
- {
- grow_safe(bbox.min);
- grow_safe(bbox.max);
- }
-
- __forceinline void intersect(const BoundBox& bbox)
- {
- min = ccl::max(min, bbox.min);
- max = ccl::min(max, bbox.max);
- }
-
- /* todo: avoid using this */
- __forceinline float safe_area() const
- {
- if(!((min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z)))
- return 0.0f;
-
- return area();
- }
-
- __forceinline float area() const
- {
- return half_area()*2.0f;
- }
-
- __forceinline float half_area() const
- {
- float3 d = max - min;
- return (d.x*d.z + d.y*d.z + d.x*d.y);
- }
-
- __forceinline float3 center() const
- {
- return 0.5f*(min + max);
- }
-
- __forceinline float3 center2() const
- {
- return min + max;
- }
-
- __forceinline float3 size() const
- {
- return max - min;
- }
-
- __forceinline bool valid() const
- {
- return (min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z) &&
- (isfinite(min.x) && isfinite(min.y) && isfinite(min.z)) &&
- (isfinite(max.x) && isfinite(max.y) && isfinite(max.z));
- }
-
- BoundBox transformed(const Transform *tfm) const
- {
- BoundBox result = BoundBox::empty;
-
- for(int i = 0; i < 8; i++) {
- float3 p;
-
- p.x = (i & 1)? min.x: max.x;
- p.y = (i & 2)? min.y: max.y;
- p.z = (i & 4)? min.z: max.z;
-
- result.grow(transform_point(tfm, p));
- }
-
- return result;
- }
-
- __forceinline bool intersects(const BoundBox& other)
- {
- float3 center_diff = center() - other.center(),
- total_size = (size() + other.size()) * 0.5f;
- return fabsf(center_diff.x) <= total_size.x &&
- fabsf(center_diff.y) <= total_size.y &&
- fabsf(center_diff.z) <= total_size.z;
- }
+class BoundBox {
+ public:
+ float3 min, max;
+
+ __forceinline BoundBox()
+ {
+ }
+
+ __forceinline BoundBox(const float3 &pt) : min(pt), max(pt)
+ {
+ }
+
+ __forceinline BoundBox(const float3 &min_, const float3 &max_) : min(min_), max(max_)
+ {
+ }
+
+ enum empty_t { empty = 0 };
+
+ __forceinline BoundBox(empty_t)
+ : min(make_float3(FLT_MAX, FLT_MAX, FLT_MAX)), max(make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX))
+ {
+ }
+
+ __forceinline void grow(const float3 &pt)
+ {
+ /* the order of arguments to min is such that if pt is nan, it will not
+ * influence the resulting bounding box */
+ min = ccl::min(pt, min);
+ max = ccl::max(pt, max);
+ }
+
+ __forceinline void grow(const float3 &pt, float border)
+ {
+ float3 shift = make_float3(border, border, border);
+ min = ccl::min(pt - shift, min);
+ max = ccl::max(pt + shift, max);
+ }
+
+ __forceinline void grow(const BoundBox &bbox)
+ {
+ grow(bbox.min);
+ grow(bbox.max);
+ }
+
+ __forceinline void grow_safe(const float3 &pt)
+ {
+ /* the order of arguments to min is such that if pt is nan, it will not
+ * influence the resulting bounding box */
+ if (isfinite(pt.x) && isfinite(pt.y) && isfinite(pt.z)) {
+ min = ccl::min(pt, min);
+ max = ccl::max(pt, max);
+ }
+ }
+
+ __forceinline void grow_safe(const float3 &pt, float border)
+ {
+ if (isfinite(pt.x) && isfinite(pt.y) && isfinite(pt.z) && isfinite(border)) {
+ float3 shift = make_float3(border, border, border);
+ min = ccl::min(pt - shift, min);
+ max = ccl::max(pt + shift, max);
+ }
+ }
+
+ __forceinline void grow_safe(const BoundBox &bbox)
+ {
+ grow_safe(bbox.min);
+ grow_safe(bbox.max);
+ }
+
+ __forceinline void intersect(const BoundBox &bbox)
+ {
+ min = ccl::max(min, bbox.min);
+ max = ccl::min(max, bbox.max);
+ }
+
+ /* todo: avoid using this */
+ __forceinline float safe_area() const
+ {
+ if (!((min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z)))
+ return 0.0f;
+
+ return area();
+ }
+
+ __forceinline float area() const
+ {
+ return half_area() * 2.0f;
+ }
+
+ __forceinline float half_area() const
+ {
+ float3 d = max - min;
+ return (d.x * d.z + d.y * d.z + d.x * d.y);
+ }
+
+ __forceinline float3 center() const
+ {
+ return 0.5f * (min + max);
+ }
+
+ __forceinline float3 center2() const
+ {
+ return min + max;
+ }
+
+ __forceinline float3 size() const
+ {
+ return max - min;
+ }
+
+ __forceinline bool valid() const
+ {
+ return (min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z) &&
+ (isfinite(min.x) && isfinite(min.y) && isfinite(min.z)) &&
+ (isfinite(max.x) && isfinite(max.y) && isfinite(max.z));
+ }
+
+ BoundBox transformed(const Transform *tfm) const
+ {
+ BoundBox result = BoundBox::empty;
+
+ for (int i = 0; i < 8; i++) {
+ float3 p;
+
+ p.x = (i & 1) ? min.x : max.x;
+ p.y = (i & 2) ? min.y : max.y;
+ p.z = (i & 4) ? min.z : max.z;
+
+ result.grow(transform_point(tfm, p));
+ }
+
+ return result;
+ }
+
+ __forceinline bool intersects(const BoundBox &other)
+ {
+ float3 center_diff = center() - other.center(), total_size = (size() + other.size()) * 0.5f;
+ return fabsf(center_diff.x) <= total_size.x && fabsf(center_diff.y) <= total_size.y &&
+ fabsf(center_diff.z) <= total_size.z;
+ }
};
-__forceinline BoundBox merge(const BoundBox& bbox, const float3& pt)
+__forceinline BoundBox merge(const BoundBox &bbox, const float3 &pt)
{
- return BoundBox(min(bbox.min, pt), max(bbox.max, pt));
+ return BoundBox(min(bbox.min, pt), max(bbox.max, pt));
}
-__forceinline BoundBox merge(const BoundBox& a, const BoundBox& b)
+__forceinline BoundBox merge(const BoundBox &a, const BoundBox &b)
{
- return BoundBox(min(a.min, b.min), max(a.max, b.max));
+ return BoundBox(min(a.min, b.min), max(a.max, b.max));
}
-__forceinline BoundBox merge(const BoundBox& a, const BoundBox& b, const BoundBox& c, const BoundBox& d)
+__forceinline BoundBox merge(const BoundBox &a,
+ const BoundBox &b,
+ const BoundBox &c,
+ const BoundBox &d)
{
- return merge(merge(a, b), merge(c, d));
+ return merge(merge(a, b), merge(c, d));
}
-__forceinline BoundBox intersect(const BoundBox& a, const BoundBox& b)
+__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
{
- return BoundBox(max(a.min, b.min), min(a.max, b.max));
+ return BoundBox(max(a.min, b.min), min(a.max, b.max));
}
-__forceinline BoundBox intersect(const BoundBox& a, const BoundBox& b, const BoundBox& c)
+__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b, const BoundBox &c)
{
- return intersect(a, intersect(b, c));
+ return intersect(a, intersect(b, c));
}
/* 2D BoundBox */
class BoundBox2D {
-public:
- float left;
- float right;
- float bottom;
- float top;
-
- BoundBox2D()
- : left(0.0f), right(1.0f), bottom(0.0f), top(1.0f)
- {
- }
-
- bool operator==(const BoundBox2D& other) const
- {
- return (left == other.left && right == other.right &&
- bottom == other.bottom && top == other.top);
- }
-
- float width()
- {
- return right - left;
- }
-
- float height()
- {
- return top - bottom;
- }
-
- BoundBox2D operator*(float f) const
- {
- BoundBox2D result;
-
- result.left = left*f;
- result.right = right*f;
- result.bottom = bottom*f;
- result.top = top*f;
-
- return result;
- }
-
- BoundBox2D subset(const BoundBox2D& other) const
- {
- BoundBox2D subset;
-
- subset.left = left + other.left*(right - left);
- subset.right = left + other.right*(right - left);
- subset.bottom = bottom + other.bottom*(top - bottom);
- subset.top = bottom + other.top*(top - bottom);
-
- return subset;
- }
-
- BoundBox2D make_relative_to(const BoundBox2D& other) const
- {
- BoundBox2D result;
-
- result.left = ((left - other.left) / (other.right - other.left));
- result.right = ((right - other.left) / (other.right - other.left));
- result.bottom = ((bottom - other.bottom) / (other.top - other.bottom));
- result.top = ((top - other.bottom) / (other.top - other.bottom));
-
- return result;
- }
-
- BoundBox2D clamp(float mn = 0.0f, float mx = 1.0f)
- {
- BoundBox2D result;
-
- result.left = ccl::clamp(left, mn, mx);
- result.right = ccl::clamp(right, mn, mx);
- result.bottom = ccl::clamp(bottom, mn, mx);
- result.top = ccl::clamp(top, mn, mx);
-
- return result;
- }
+ public:
+ float left;
+ float right;
+ float bottom;
+ float top;
+
+ BoundBox2D() : left(0.0f), right(1.0f), bottom(0.0f), top(1.0f)
+ {
+ }
+
+ bool operator==(const BoundBox2D &other) const
+ {
+ return (left == other.left && right == other.right && bottom == other.bottom &&
+ top == other.top);
+ }
+
+ float width()
+ {
+ return right - left;
+ }
+
+ float height()
+ {
+ return top - bottom;
+ }
+
+ BoundBox2D operator*(float f) const
+ {
+ BoundBox2D result;
+
+ result.left = left * f;
+ result.right = right * f;
+ result.bottom = bottom * f;
+ result.top = top * f;
+
+ return result;
+ }
+
+ BoundBox2D subset(const BoundBox2D &other) const
+ {
+ BoundBox2D subset;
+
+ subset.left = left + other.left * (right - left);
+ subset.right = left + other.right * (right - left);
+ subset.bottom = bottom + other.bottom * (top - bottom);
+ subset.top = bottom + other.top * (top - bottom);
+
+ return subset;
+ }
+
+ BoundBox2D make_relative_to(const BoundBox2D &other) const
+ {
+ BoundBox2D result;
+
+ result.left = ((left - other.left) / (other.right - other.left));
+ result.right = ((right - other.left) / (other.right - other.left));
+ result.bottom = ((bottom - other.bottom) / (other.top - other.bottom));
+ result.top = ((top - other.bottom) / (other.top - other.bottom));
+
+ return result;
+ }
+
+ BoundBox2D clamp(float mn = 0.0f, float mx = 1.0f)
+ {
+ BoundBox2D result;
+
+ result.left = ccl::clamp(left, mn, mx);
+ result.right = ccl::clamp(right, mn, mx);
+ result.bottom = ccl::clamp(bottom, mn, mx);
+ result.top = ccl::clamp(top, mn, mx);
+
+ return result;
+ }
};
CCL_NAMESPACE_END
-#endif /* __UTIL_BOUNDBOX_H__ */
+#endif /* __UTIL_BOUNDBOX_H__ */
diff --git a/intern/cycles/util/util_color.h b/intern/cycles/util/util_color.h
index e6efc7d73fc..ca4c393f66e 100644
--- a/intern/cycles/util/util_color.h
+++ b/intern/cycles/util/util_color.h
@@ -21,133 +21,147 @@
#include "util/util_types.h"
#ifdef __KERNEL_SSE2__
-#include "util/util_simd.h"
+# include "util/util_simd.h"
#endif
CCL_NAMESPACE_BEGIN
ccl_device uchar float_to_byte(float val)
{
- return ((val <= 0.0f) ? 0 : ((val > (1.0f - 0.5f / 255.0f)) ? 255 : (uchar)((255.0f * val) + 0.5f)));
+ return ((val <= 0.0f) ? 0 :
+ ((val > (1.0f - 0.5f / 255.0f)) ? 255 : (uchar)((255.0f * val) + 0.5f)));
}
ccl_device uchar4 color_float_to_byte(float3 c)
{
- uchar r, g, b;
+ uchar r, g, b;
- r = float_to_byte(c.x);
- g = float_to_byte(c.y);
- b = float_to_byte(c.z);
+ r = float_to_byte(c.x);
+ g = float_to_byte(c.y);
+ b = float_to_byte(c.z);
- return make_uchar4(r, g, b, 0);
+ return make_uchar4(r, g, b, 0);
}
ccl_device_inline float3 color_byte_to_float(uchar4 c)
{
- return make_float3(c.x*(1.0f/255.0f), c.y*(1.0f/255.0f), c.z*(1.0f/255.0f));
+ return make_float3(c.x * (1.0f / 255.0f), c.y * (1.0f / 255.0f), c.z * (1.0f / 255.0f));
}
ccl_device float color_srgb_to_linear(float c)
{
- if(c < 0.04045f)
- return (c < 0.0f)? 0.0f: c * (1.0f/12.92f);
- else
- return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
+ if (c < 0.04045f)
+ return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
+ else
+ return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
}
ccl_device float color_linear_to_srgb(float c)
{
- if(c < 0.0031308f)
- return (c < 0.0f)? 0.0f: c * 12.92f;
- else
- return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
+ if (c < 0.0031308f)
+ return (c < 0.0f) ? 0.0f : c * 12.92f;
+ else
+ return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
}
ccl_device float3 rgb_to_hsv(float3 rgb)
{
- float cmax, cmin, h, s, v, cdelta;
- float3 c;
-
- cmax = fmaxf(rgb.x, fmaxf(rgb.y, rgb.z));
- cmin = min(rgb.x, min(rgb.y, rgb.z));
- cdelta = cmax - cmin;
-
- v = cmax;
-
- if(cmax != 0.0f) {
- s = cdelta/cmax;
- }
- else {
- s = 0.0f;
- h = 0.0f;
- }
-
- if(s != 0.0f) {
- float3 cmax3 = make_float3(cmax, cmax, cmax);
- c = (cmax3 - rgb)/cdelta;
-
- if (rgb.x == cmax) h = c.z - c.y;
- else if(rgb.y == cmax) h = 2.0f + c.x - c.z;
- else h = 4.0f + c.y - c.x;
-
- h /= 6.0f;
-
- if(h < 0.0f)
- h += 1.0f;
- }
- else {
- h = 0.0f;
- }
-
- return make_float3(h, s, v);
+ float cmax, cmin, h, s, v, cdelta;
+ float3 c;
+
+ cmax = fmaxf(rgb.x, fmaxf(rgb.y, rgb.z));
+ cmin = min(rgb.x, min(rgb.y, rgb.z));
+ cdelta = cmax - cmin;
+
+ v = cmax;
+
+ if (cmax != 0.0f) {
+ s = cdelta / cmax;
+ }
+ else {
+ s = 0.0f;
+ h = 0.0f;
+ }
+
+ if (s != 0.0f) {
+ float3 cmax3 = make_float3(cmax, cmax, cmax);
+ c = (cmax3 - rgb) / cdelta;
+
+ if (rgb.x == cmax)
+ h = c.z - c.y;
+ else if (rgb.y == cmax)
+ h = 2.0f + c.x - c.z;
+ else
+ h = 4.0f + c.y - c.x;
+
+ h /= 6.0f;
+
+ if (h < 0.0f)
+ h += 1.0f;
+ }
+ else {
+ h = 0.0f;
+ }
+
+ return make_float3(h, s, v);
}
ccl_device float3 hsv_to_rgb(float3 hsv)
{
- float i, f, p, q, t, h, s, v;
- float3 rgb;
-
- h = hsv.x;
- s = hsv.y;
- v = hsv.z;
-
- if(s != 0.0f) {
- if(h == 1.0f)
- h = 0.0f;
-
- h *= 6.0f;
- i = floorf(h);
- f = h - i;
- rgb = make_float3(f, f, f);
- p = v*(1.0f-s);
- q = v*(1.0f-(s*f));
- t = v*(1.0f-(s*(1.0f-f)));
-
- if (i == 0.0f) rgb = make_float3(v, t, p);
- else if(i == 1.0f) rgb = make_float3(q, v, p);
- else if(i == 2.0f) rgb = make_float3(p, v, t);
- else if(i == 3.0f) rgb = make_float3(p, q, v);
- else if(i == 4.0f) rgb = make_float3(t, p, v);
- else rgb = make_float3(v, p, q);
- }
- else {
- rgb = make_float3(v, v, v);
- }
-
- return rgb;
+ float i, f, p, q, t, h, s, v;
+ float3 rgb;
+
+ h = hsv.x;
+ s = hsv.y;
+ v = hsv.z;
+
+ if (s != 0.0f) {
+ if (h == 1.0f)
+ h = 0.0f;
+
+ h *= 6.0f;
+ i = floorf(h);
+ f = h - i;
+ rgb = make_float3(f, f, f);
+ p = v * (1.0f - s);
+ q = v * (1.0f - (s * f));
+ t = v * (1.0f - (s * (1.0f - f)));
+
+ if (i == 0.0f)
+ rgb = make_float3(v, t, p);
+ else if (i == 1.0f)
+ rgb = make_float3(q, v, p);
+ else if (i == 2.0f)
+ rgb = make_float3(p, v, t);
+ else if (i == 3.0f)
+ rgb = make_float3(p, q, v);
+ else if (i == 4.0f)
+ rgb = make_float3(t, p, v);
+ else
+ rgb = make_float3(v, p, q);
+ }
+ else {
+ rgb = make_float3(v, v, v);
+ }
+
+ return rgb;
}
ccl_device float3 xyY_to_xyz(float x, float y, float Y)
{
- float X, Z;
+ float X, Z;
- if(y != 0.0f) X = (x / y) * Y;
- else X = 0.0f;
+ if (y != 0.0f)
+ X = (x / y) * Y;
+ else
+ X = 0.0f;
- if(y != 0.0f && Y != 0.0f) Z = (1.0f - x - y) / y * Y;
- else Z = 0.0f;
+ if (y != 0.0f && Y != 0.0f)
+ Z = (1.0f - x - y) / y * Y;
+ else
+ Z = 0.0f;
- return make_float3(X, Y, Z);
+ return make_float3(X, Y, Z);
}
#ifdef __KERNEL_SSE2__
@@ -158,86 +172,84 @@ ccl_device float3 xyY_to_xyz(float x, float y, float Y)
* exp = exponent, encoded as uint32_t
* e2coeff = 2^(127/exponent - 127) * bias_coeff^(1/exponent), encoded as uint32_t
*/
-template<unsigned exp, unsigned e2coeff>
-ccl_device_inline ssef fastpow(const ssef &arg)
+template<unsigned exp, unsigned e2coeff> ccl_device_inline ssef fastpow(const ssef &arg)
{
- ssef ret;
- ret = arg * cast(ssei(e2coeff));
- ret = ssef(cast(ret));
- ret = ret * cast(ssei(exp));
- ret = cast(ssei(ret));
- return ret;
+ ssef ret;
+ ret = arg * cast(ssei(e2coeff));
+ ret = ssef(cast(ret));
+ ret = ret * cast(ssei(exp));
+ ret = cast(ssei(ret));
+ return ret;
}
/* Improve x ^ 1.0f/5.0f solution with Newton-Raphson method */
ccl_device_inline ssef improve_5throot_solution(const ssef &old_result, const ssef &x)
{
- ssef approx2 = old_result * old_result;
- ssef approx4 = approx2 * approx2;
- ssef t = x / approx4;
- ssef summ = madd(ssef(4.0f), old_result, t);
- return summ * ssef(1.0f/5.0f);
+ ssef approx2 = old_result * old_result;
+ ssef approx4 = approx2 * approx2;
+ ssef t = x / approx4;
+ ssef summ = madd(ssef(4.0f), old_result, t);
+ return summ * ssef(1.0f / 5.0f);
}
/* Calculate powf(x, 2.4). Working domain: 1e-10 < x < 1e+10 */
ccl_device_inline ssef fastpow24(const ssef &arg)
{
- /* max, avg and |avg| errors were calculated in gcc without FMA instructions
- * The final precision should be better than powf in glibc */
-
- /* Calculate x^4/5, coefficient 0.994 was constructed manually to minimize avg error */
- /* 0x3F4CCCCD = 4/5 */
- /* 0x4F55A7FB = 2^(127/(4/5) - 127) * 0.994^(1/(4/5)) */
- ssef x = fastpow<0x3F4CCCCD, 0x4F55A7FB>(arg); // error max = 0.17 avg = 0.0018 |avg| = 0.05
- ssef arg2 = arg * arg;
- ssef arg4 = arg2 * arg2;
- x = improve_5throot_solution(x, arg4); /* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */
- x = improve_5throot_solution(x, arg4); /* error max = 0.00021 avg = 1.6e-05 |avg| = 1.6e-05 */
- x = improve_5throot_solution(x, arg4); /* error max = 6.1e-07 avg = 5.2e-08 |avg| = 1.1e-07 */
- return x * (x * x);
+ /* max, avg and |avg| errors were calculated in gcc without FMA instructions
+ * The final precision should be better than powf in glibc */
+
+ /* Calculate x^4/5, coefficient 0.994 was constructed manually to minimize avg error */
+ /* 0x3F4CCCCD = 4/5 */
+ /* 0x4F55A7FB = 2^(127/(4/5) - 127) * 0.994^(1/(4/5)) */
+ ssef x = fastpow<0x3F4CCCCD, 0x4F55A7FB>(arg); // error max = 0.17 avg = 0.0018 |avg| = 0.05
+ ssef arg2 = arg * arg;
+ ssef arg4 = arg2 * arg2;
+ x = improve_5throot_solution(x,
+ arg4); /* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */
+ x = improve_5throot_solution(x,
+ arg4); /* error max = 0.00021 avg = 1.6e-05 |avg| = 1.6e-05 */
+ x = improve_5throot_solution(x,
+ arg4); /* error max = 6.1e-07 avg = 5.2e-08 |avg| = 1.1e-07 */
+ return x * (x * x);
}
ccl_device ssef color_srgb_to_linear(const ssef &c)
{
- sseb cmp = c < ssef(0.04045f);
- ssef lt = max(c * ssef(1.0f/12.92f), ssef(0.0f));
- ssef gtebase = (c + ssef(0.055f)) * ssef(1.0f/1.055f); /* fma */
- ssef gte = fastpow24(gtebase);
- return select(cmp, lt, gte);
+ sseb cmp = c < ssef(0.04045f);
+ ssef lt = max(c * ssef(1.0f / 12.92f), ssef(0.0f));
+ ssef gtebase = (c + ssef(0.055f)) * ssef(1.0f / 1.055f); /* fma */
+ ssef gte = fastpow24(gtebase);
+ return select(cmp, lt, gte);
}
-#endif /* __KERNEL_SSE2__ */
+#endif /* __KERNEL_SSE2__ */
ccl_device float3 color_srgb_to_linear_v3(float3 c)
{
- return make_float3(color_srgb_to_linear(c.x),
- color_srgb_to_linear(c.y),
- color_srgb_to_linear(c.z));
+ return make_float3(
+ color_srgb_to_linear(c.x), color_srgb_to_linear(c.y), color_srgb_to_linear(c.z));
}
ccl_device float3 color_linear_to_srgb_v3(float3 c)
{
- return make_float3(color_linear_to_srgb(c.x),
- color_linear_to_srgb(c.y),
- color_linear_to_srgb(c.z));
+ return make_float3(
+ color_linear_to_srgb(c.x), color_linear_to_srgb(c.y), color_linear_to_srgb(c.z));
}
ccl_device float4 color_srgb_to_linear_v4(float4 c)
{
#ifdef __KERNEL_SSE2__
- ssef r_ssef;
- float4 &r = (float4 &)r_ssef;
- r = c;
- r_ssef = color_srgb_to_linear(r_ssef);
- r.w = c.w;
- return r;
+ ssef r_ssef;
+ float4 &r = (float4 &)r_ssef;
+ r = c;
+ r_ssef = color_srgb_to_linear(r_ssef);
+ r.w = c.w;
+ return r;
#else
- return make_float4(color_srgb_to_linear(c.x),
- color_srgb_to_linear(c.y),
- color_srgb_to_linear(c.z),
- c.w);
+ return make_float4(
+ color_srgb_to_linear(c.x), color_srgb_to_linear(c.y), color_srgb_to_linear(c.z), c.w);
#endif
}
CCL_NAMESPACE_END
-#endif /* __UTIL_COLOR_H__ */
+#endif /* __UTIL_COLOR_H__ */
diff --git a/intern/cycles/util/util_debug.cpp b/intern/cycles/util/util_debug.cpp
index b4cc69411ed..aabfea7fc49 100644
--- a/intern/cycles/util/util_debug.cpp
+++ b/intern/cycles/util/util_debug.cpp
@@ -26,159 +26,153 @@
CCL_NAMESPACE_BEGIN
DebugFlags::CPU::CPU()
- : avx2(true),
- avx(true),
- sse41(true),
- sse3(true),
- sse2(true),
- bvh_layout(BVH_LAYOUT_DEFAULT),
- split_kernel(false)
+ : avx2(true),
+ avx(true),
+ sse41(true),
+ sse3(true),
+ sse2(true),
+ bvh_layout(BVH_LAYOUT_DEFAULT),
+ split_kernel(false)
{
- reset();
+ reset();
}
void DebugFlags::CPU::reset()
{
#define STRINGIFY(x) #x
#define CHECK_CPU_FLAGS(flag, env) \
- do { \
- flag = (getenv(env) == NULL); \
- if(!flag) { \
- VLOG(1) << "Disabling " << STRINGIFY(flag) << " instruction set."; \
- } \
- } while(0)
-
- CHECK_CPU_FLAGS(avx2, "CYCLES_CPU_NO_AVX2");
- CHECK_CPU_FLAGS(avx, "CYCLES_CPU_NO_AVX");
- CHECK_CPU_FLAGS(sse41, "CYCLES_CPU_NO_SSE41");
- CHECK_CPU_FLAGS(sse3, "CYCLES_CPU_NO_SSE3");
- CHECK_CPU_FLAGS(sse2, "CYCLES_CPU_NO_SSE2");
+ do { \
+ flag = (getenv(env) == NULL); \
+ if (!flag) { \
+ VLOG(1) << "Disabling " << STRINGIFY(flag) << " instruction set."; \
+ } \
+ } while (0)
+
+ CHECK_CPU_FLAGS(avx2, "CYCLES_CPU_NO_AVX2");
+ CHECK_CPU_FLAGS(avx, "CYCLES_CPU_NO_AVX");
+ CHECK_CPU_FLAGS(sse41, "CYCLES_CPU_NO_SSE41");
+ CHECK_CPU_FLAGS(sse3, "CYCLES_CPU_NO_SSE3");
+ CHECK_CPU_FLAGS(sse2, "CYCLES_CPU_NO_SSE2");
#undef STRINGIFY
#undef CHECK_CPU_FLAGS
- if(getenv("CYCLES_BVH2") != NULL) {
- bvh_layout = BVH_LAYOUT_BVH2;
- }
- else if(getenv("CYCLES_BVH4") != NULL) {
- bvh_layout = BVH_LAYOUT_BVH4;
- }
- else if(getenv("CYCLES_BVH8") != NULL) {
- bvh_layout = BVH_LAYOUT_BVH8;
- }
- else {
- bvh_layout = BVH_LAYOUT_DEFAULT;
- }
-
- split_kernel = false;
+ if (getenv("CYCLES_BVH2") != NULL) {
+ bvh_layout = BVH_LAYOUT_BVH2;
+ }
+ else if (getenv("CYCLES_BVH4") != NULL) {
+ bvh_layout = BVH_LAYOUT_BVH4;
+ }
+ else if (getenv("CYCLES_BVH8") != NULL) {
+ bvh_layout = BVH_LAYOUT_BVH8;
+ }
+ else {
+ bvh_layout = BVH_LAYOUT_DEFAULT;
+ }
+
+ split_kernel = false;
}
-DebugFlags::CUDA::CUDA()
- : adaptive_compile(false),
- split_kernel(false)
+DebugFlags::CUDA::CUDA() : adaptive_compile(false), split_kernel(false)
{
- reset();
+ reset();
}
void DebugFlags::CUDA::reset()
{
- if(getenv("CYCLES_CUDA_ADAPTIVE_COMPILE") != NULL)
- adaptive_compile = true;
+ if (getenv("CYCLES_CUDA_ADAPTIVE_COMPILE") != NULL)
+ adaptive_compile = true;
- split_kernel = false;
+ split_kernel = false;
}
-DebugFlags::OpenCL::OpenCL()
- : device_type(DebugFlags::OpenCL::DEVICE_ALL),
- debug(false)
+DebugFlags::OpenCL::OpenCL() : device_type(DebugFlags::OpenCL::DEVICE_ALL), debug(false)
{
- reset();
+ reset();
}
void DebugFlags::OpenCL::reset()
{
- /* Initialize device type from environment variables. */
- device_type = DebugFlags::OpenCL::DEVICE_ALL;
- char *device = getenv("CYCLES_OPENCL_TEST");
- if(device) {
- if(strcmp(device, "NONE") == 0) {
- device_type = DebugFlags::OpenCL::DEVICE_NONE;
- }
- else if(strcmp(device, "ALL") == 0) {
- device_type = DebugFlags::OpenCL::DEVICE_ALL;
- }
- else if(strcmp(device, "DEFAULT") == 0) {
- device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
- }
- else if(strcmp(device, "CPU") == 0) {
- device_type = DebugFlags::OpenCL::DEVICE_CPU;
- }
- else if(strcmp(device, "GPU") == 0) {
- device_type = DebugFlags::OpenCL::DEVICE_GPU;
- }
- else if(strcmp(device, "ACCELERATOR") == 0) {
- device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
- }
- }
- /* Initialize other flags from environment variables. */
- debug = (getenv("CYCLES_OPENCL_DEBUG") != NULL);
+ /* Initialize device type from environment variables. */
+ device_type = DebugFlags::OpenCL::DEVICE_ALL;
+ char *device = getenv("CYCLES_OPENCL_TEST");
+ if (device) {
+ if (strcmp(device, "NONE") == 0) {
+ device_type = DebugFlags::OpenCL::DEVICE_NONE;
+ }
+ else if (strcmp(device, "ALL") == 0) {
+ device_type = DebugFlags::OpenCL::DEVICE_ALL;
+ }
+ else if (strcmp(device, "DEFAULT") == 0) {
+ device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
+ }
+ else if (strcmp(device, "CPU") == 0) {
+ device_type = DebugFlags::OpenCL::DEVICE_CPU;
+ }
+ else if (strcmp(device, "GPU") == 0) {
+ device_type = DebugFlags::OpenCL::DEVICE_GPU;
+ }
+ else if (strcmp(device, "ACCELERATOR") == 0) {
+ device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
+ }
+ }
+ /* Initialize other flags from environment variables. */
+ debug = (getenv("CYCLES_OPENCL_DEBUG") != NULL);
}
-DebugFlags::DebugFlags()
-: viewport_static_bvh(false)
+DebugFlags::DebugFlags() : viewport_static_bvh(false)
{
- /* Nothing for now. */
+ /* Nothing for now. */
}
void DebugFlags::reset()
{
- viewport_static_bvh = false;
- cpu.reset();
- cuda.reset();
- opencl.reset();
+ viewport_static_bvh = false;
+ cpu.reset();
+ cuda.reset();
+ opencl.reset();
}
-std::ostream& operator <<(std::ostream &os,
- DebugFlagsConstRef debug_flags)
+std::ostream &operator<<(std::ostream &os, DebugFlagsConstRef debug_flags)
{
- os << "CPU flags:\n"
- << " AVX2 : " << string_from_bool(debug_flags.cpu.avx2) << "\n"
- << " AVX : " << string_from_bool(debug_flags.cpu.avx) << "\n"
- << " SSE4.1 : " << string_from_bool(debug_flags.cpu.sse41) << "\n"
- << " SSE3 : " << string_from_bool(debug_flags.cpu.sse3) << "\n"
- << " SSE2 : " << string_from_bool(debug_flags.cpu.sse2) << "\n"
- << " BVH layout : " << bvh_layout_name(debug_flags.cpu.bvh_layout) << "\n"
- << " Split : " << string_from_bool(debug_flags.cpu.split_kernel) << "\n";
-
- os << "CUDA flags:\n"
- << " Adaptive Compile: " << string_from_bool(debug_flags.cuda.adaptive_compile) << "\n";
-
- const char *opencl_device_type;
- switch(debug_flags.opencl.device_type) {
- case DebugFlags::OpenCL::DEVICE_NONE:
- opencl_device_type = "NONE";
- break;
- case DebugFlags::OpenCL::DEVICE_ALL:
- opencl_device_type = "ALL";
- break;
- case DebugFlags::OpenCL::DEVICE_DEFAULT:
- opencl_device_type = "DEFAULT";
- break;
- case DebugFlags::OpenCL::DEVICE_CPU:
- opencl_device_type = "CPU";
- break;
- case DebugFlags::OpenCL::DEVICE_GPU:
- opencl_device_type = "GPU";
- break;
- case DebugFlags::OpenCL::DEVICE_ACCELERATOR:
- opencl_device_type = "ACCELERATOR";
- break;
- }
- os << "OpenCL flags:\n"
- << " Device type : " << opencl_device_type << "\n"
- << " Debug : " << string_from_bool(debug_flags.opencl.debug) << "\n"
- << " Memory limit : " << string_human_readable_size(debug_flags.opencl.mem_limit) << "\n";
- return os;
+ os << "CPU flags:\n"
+ << " AVX2 : " << string_from_bool(debug_flags.cpu.avx2) << "\n"
+ << " AVX : " << string_from_bool(debug_flags.cpu.avx) << "\n"
+ << " SSE4.1 : " << string_from_bool(debug_flags.cpu.sse41) << "\n"
+ << " SSE3 : " << string_from_bool(debug_flags.cpu.sse3) << "\n"
+ << " SSE2 : " << string_from_bool(debug_flags.cpu.sse2) << "\n"
+ << " BVH layout : " << bvh_layout_name(debug_flags.cpu.bvh_layout) << "\n"
+ << " Split : " << string_from_bool(debug_flags.cpu.split_kernel) << "\n";
+
+ os << "CUDA flags:\n"
+ << " Adaptive Compile: " << string_from_bool(debug_flags.cuda.adaptive_compile) << "\n";
+
+ const char *opencl_device_type;
+ switch (debug_flags.opencl.device_type) {
+ case DebugFlags::OpenCL::DEVICE_NONE:
+ opencl_device_type = "NONE";
+ break;
+ case DebugFlags::OpenCL::DEVICE_ALL:
+ opencl_device_type = "ALL";
+ break;
+ case DebugFlags::OpenCL::DEVICE_DEFAULT:
+ opencl_device_type = "DEFAULT";
+ break;
+ case DebugFlags::OpenCL::DEVICE_CPU:
+ opencl_device_type = "CPU";
+ break;
+ case DebugFlags::OpenCL::DEVICE_GPU:
+ opencl_device_type = "GPU";
+ break;
+ case DebugFlags::OpenCL::DEVICE_ACCELERATOR:
+ opencl_device_type = "ACCELERATOR";
+ break;
+ }
+ os << "OpenCL flags:\n"
+ << " Device type : " << opencl_device_type << "\n"
+ << " Debug : " << string_from_bool(debug_flags.opencl.debug) << "\n"
+ << " Memory limit : " << string_human_readable_size(debug_flags.opencl.mem_limit) << "\n";
+ return os;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_debug.h b/intern/cycles/util/util_debug.h
index e8c272cdb80..d668ddc6d6c 100644
--- a/intern/cycles/util/util_debug.h
+++ b/intern/cycles/util/util_debug.h
@@ -29,151 +29,166 @@ CCL_NAMESPACE_BEGIN
* the interface.
*/
class DebugFlags {
-public:
- /* Use static BVH in viewport, to match final render exactly. */
- bool viewport_static_bvh;
-
- /* Descriptor of CPU feature-set to be used. */
- struct CPU {
- CPU();
-
- /* Reset flags to their defaults. */
- void reset();
-
- /* Flags describing which instructions sets are allowed for use. */
- bool avx2;
- bool avx;
- bool sse41;
- bool sse3;
- bool sse2;
-
- /* Check functions to see whether instructions up to the given one
- * are allowed for use.
- */
- bool has_avx2() { return has_avx() && avx2; }
- bool has_avx() { return has_sse41() && avx; }
- bool has_sse41() { return has_sse3() && sse41; }
- bool has_sse3() { return has_sse2() && sse3; }
- bool has_sse2() { return sse2; }
-
- /* Requested BVH size.
- *
- * Rendering will use widest possible BVH which is below or equal
- * this one.
- */
- BVHLayout bvh_layout;
-
- /* Whether split kernel is used */
- bool split_kernel;
- };
-
- /* Descriptor of CUDA feature-set to be used. */
- struct CUDA {
- CUDA();
-
- /* Reset flags to their defaults. */
- void reset();
-
- /* Whether adaptive feature based runtime compile is enabled or not.
- * Requires the CUDA Toolkit and only works on Linux atm. */
- bool adaptive_compile;
-
- /* Whether split kernel is used */
- bool split_kernel;
- };
-
- /* Descriptor of OpenCL feature-set to be used. */
- struct OpenCL {
- OpenCL();
-
- /* Reset flags to their defaults. */
- void reset();
-
- /* Available device types.
- * Only gives a hint which devices to let user to choose from, does not
- * try to use any sort of optimal device or so.
- */
- enum DeviceType {
- /* None of OpenCL devices will be used. */
- DEVICE_NONE,
- /* All OpenCL devices will be used. */
- DEVICE_ALL,
- /* Default system OpenCL device will be used. */
- DEVICE_DEFAULT,
- /* Host processor will be used. */
- DEVICE_CPU,
- /* GPU devices will be used. */
- DEVICE_GPU,
- /* Dedicated OpenCL accelerator device will be used. */
- DEVICE_ACCELERATOR,
- };
-
- /* Available kernel types. */
- enum KernelType {
- /* Do automated guess which kernel to use, based on the officially
- * supported GPUs and such.
- */
- KERNEL_DEFAULT,
- /* Force mega kernel to be used. */
- KERNEL_MEGA,
- /* Force split kernel to be used. */
- KERNEL_SPLIT,
- };
-
- /* Requested device type. */
- DeviceType device_type;
-
- /* Use debug version of the kernel. */
- bool debug;
-
- /* TODO(mai): Currently this is only for OpenCL, but we should have it implemented for all devices. */
- /* Artificial memory limit in bytes (0 if disabled). */
- size_t mem_limit;
- };
-
- /* Get instance of debug flags registry. */
- static DebugFlags& get()
- {
- static DebugFlags instance;
- return instance;
- }
-
- /* Reset flags to their defaults. */
- void reset();
-
- /* Requested CPU flags. */
- CPU cpu;
-
- /* Requested CUDA flags. */
- CUDA cuda;
-
- /* Requested OpenCL flags. */
- OpenCL opencl;
-
-private:
- DebugFlags();
+ public:
+ /* Use static BVH in viewport, to match final render exactly. */
+ bool viewport_static_bvh;
+
+ /* Descriptor of CPU feature-set to be used. */
+ struct CPU {
+ CPU();
+
+ /* Reset flags to their defaults. */
+ void reset();
+
+ /* Flags describing which instructions sets are allowed for use. */
+ bool avx2;
+ bool avx;
+ bool sse41;
+ bool sse3;
+ bool sse2;
+
+ /* Check functions to see whether instructions up to the given one
+ * are allowed for use.
+ */
+ bool has_avx2()
+ {
+ return has_avx() && avx2;
+ }
+ bool has_avx()
+ {
+ return has_sse41() && avx;
+ }
+ bool has_sse41()
+ {
+ return has_sse3() && sse41;
+ }
+ bool has_sse3()
+ {
+ return has_sse2() && sse3;
+ }
+ bool has_sse2()
+ {
+ return sse2;
+ }
+
+ /* Requested BVH size.
+ *
+ * Rendering will use widest possible BVH which is below or equal
+ * this one.
+ */
+ BVHLayout bvh_layout;
+
+ /* Whether split kernel is used */
+ bool split_kernel;
+ };
+
+ /* Descriptor of CUDA feature-set to be used. */
+ struct CUDA {
+ CUDA();
+
+ /* Reset flags to their defaults. */
+ void reset();
+
+ /* Whether adaptive feature based runtime compile is enabled or not.
+ * Requires the CUDA Toolkit and only works on Linux atm. */
+ bool adaptive_compile;
+
+ /* Whether split kernel is used */
+ bool split_kernel;
+ };
+
+ /* Descriptor of OpenCL feature-set to be used. */
+ struct OpenCL {
+ OpenCL();
+
+ /* Reset flags to their defaults. */
+ void reset();
+
+ /* Available device types.
+ * Only gives a hint which devices to let user to choose from, does not
+ * try to use any sort of optimal device or so.
+ */
+ enum DeviceType {
+ /* None of OpenCL devices will be used. */
+ DEVICE_NONE,
+ /* All OpenCL devices will be used. */
+ DEVICE_ALL,
+ /* Default system OpenCL device will be used. */
+ DEVICE_DEFAULT,
+ /* Host processor will be used. */
+ DEVICE_CPU,
+ /* GPU devices will be used. */
+ DEVICE_GPU,
+ /* Dedicated OpenCL accelerator device will be used. */
+ DEVICE_ACCELERATOR,
+ };
+
+ /* Available kernel types. */
+ enum KernelType {
+ /* Do automated guess which kernel to use, based on the officially
+ * supported GPUs and such.
+ */
+ KERNEL_DEFAULT,
+ /* Force mega kernel to be used. */
+ KERNEL_MEGA,
+ /* Force split kernel to be used. */
+ KERNEL_SPLIT,
+ };
+
+ /* Requested device type. */
+ DeviceType device_type;
+
+ /* Use debug version of the kernel. */
+ bool debug;
+
+ /* TODO(mai): Currently this is only for OpenCL, but we should have it implemented for all devices. */
+ /* Artificial memory limit in bytes (0 if disabled). */
+ size_t mem_limit;
+ };
+
+ /* Get instance of debug flags registry. */
+ static DebugFlags &get()
+ {
+ static DebugFlags instance;
+ return instance;
+ }
+
+ /* Reset flags to their defaults. */
+ void reset();
+
+ /* Requested CPU flags. */
+ CPU cpu;
+
+ /* Requested CUDA flags. */
+ CUDA cuda;
+
+ /* Requested OpenCL flags. */
+ OpenCL opencl;
+
+ private:
+ DebugFlags();
#if (__cplusplus > 199711L)
-public:
- explicit DebugFlags(DebugFlags const& /*other*/) = delete;
- void operator=(DebugFlags const& /*other*/) = delete;
+ public:
+ explicit DebugFlags(DebugFlags const & /*other*/) = delete;
+ void operator=(DebugFlags const & /*other*/) = delete;
#else
-private:
- explicit DebugFlags(DebugFlags const& /*other*/);
- void operator=(DebugFlags const& /*other*/);
+ private:
+ explicit DebugFlags(DebugFlags const & /*other*/);
+ void operator=(DebugFlags const & /*other*/);
#endif
};
-typedef DebugFlags& DebugFlagsRef;
-typedef const DebugFlags& DebugFlagsConstRef;
+typedef DebugFlags &DebugFlagsRef;
+typedef const DebugFlags &DebugFlagsConstRef;
-inline DebugFlags& DebugFlags() {
+inline DebugFlags &DebugFlags()
+{
return DebugFlags::get();
}
-std::ostream& operator <<(std::ostream &os,
- DebugFlagsConstRef debug_flags);
+std::ostream &operator<<(std::ostream &os, DebugFlagsConstRef debug_flags);
CCL_NAMESPACE_END
-#endif /* __UTIL_DEBUG_H__ */
+#endif /* __UTIL_DEBUG_H__ */
diff --git a/intern/cycles/util/util_defines.h b/intern/cycles/util/util_defines.h
index 2cb42d9bd56..7f3bead0a18 100644
--- a/intern/cycles/util/util_defines.h
+++ b/intern/cycles/util/util_defines.h
@@ -16,118 +16,125 @@
*/
#ifndef __UTIL_DEFINES_H__
-#define __UTIL_DEFINES_H__
+# define __UTIL_DEFINES_H__
/* Bitness */
-#if defined(__ppc64__) || defined(__PPC64__) || defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
-# define __KERNEL_64_BIT__
-#endif
+# if defined(__ppc64__) || defined(__PPC64__) || defined(__x86_64__) || defined(__ia64__) || \
+ defined(_M_X64)
+# define __KERNEL_64_BIT__
+# endif
/* Qualifiers for kernel code shared by CPU and GPU */
-#ifndef __KERNEL_GPU__
-# define ccl_device static inline
-# define ccl_device_noinline static
-# define ccl_global
-# define ccl_static_constant static const
-# define ccl_constant const
-# define ccl_local
-# define ccl_local_param
-# define ccl_private
-# define ccl_restrict __restrict
-# define ccl_ref &
-# define __KERNEL_WITH_SSE_ALIGN__
-
-# if defined(_WIN32) && !defined(FREE_WINDOWS)
-# define ccl_device_inline static __forceinline
-# define ccl_device_forceinline static __forceinline
-# define ccl_align(...) __declspec(align(__VA_ARGS__))
-# ifdef __KERNEL_64_BIT__
-# define ccl_try_align(...) __declspec(align(__VA_ARGS__))
-# else /* __KERNEL_64_BIT__ */
-# undef __KERNEL_WITH_SSE_ALIGN__
+# ifndef __KERNEL_GPU__
+# define ccl_device static inline
+# define ccl_device_noinline static
+# define ccl_global
+# define ccl_static_constant static const
+# define ccl_constant const
+# define ccl_local
+# define ccl_local_param
+# define ccl_private
+# define ccl_restrict __restrict
+# define ccl_ref &
+# define __KERNEL_WITH_SSE_ALIGN__
+
+# if defined(_WIN32) && !defined(FREE_WINDOWS)
+# define ccl_device_inline static __forceinline
+# define ccl_device_forceinline static __forceinline
+# define ccl_align(...) __declspec(align(__VA_ARGS__))
+# ifdef __KERNEL_64_BIT__
+# define ccl_try_align(...) __declspec(align(__VA_ARGS__))
+# else /* __KERNEL_64_BIT__ */
+# undef __KERNEL_WITH_SSE_ALIGN__
/* No support for function arguments (error C2719). */
-# define ccl_try_align(...)
-# endif /* __KERNEL_64_BIT__ */
-# define ccl_may_alias
-# define ccl_always_inline __forceinline
-# define ccl_never_inline __declspec(noinline)
-# define ccl_maybe_unused
-# else /* _WIN32 && !FREE_WINDOWS */
-# define ccl_device_inline static inline __attribute__((always_inline))
-# define ccl_device_forceinline static inline __attribute__((always_inline))
-# define ccl_align(...) __attribute__((aligned(__VA_ARGS__)))
-# ifndef FREE_WINDOWS64
-# define __forceinline inline __attribute__((always_inline))
-# endif
-# define ccl_try_align(...) __attribute__((aligned(__VA_ARGS__)))
-# define ccl_may_alias __attribute__((__may_alias__))
-# define ccl_always_inline __attribute__((always_inline))
-# define ccl_never_inline __attribute__((noinline))
-# define ccl_maybe_unused __attribute__((used))
-# endif /* _WIN32 && !FREE_WINDOWS */
+# define ccl_try_align(...)
+# endif /* __KERNEL_64_BIT__ */
+# define ccl_may_alias
+# define ccl_always_inline __forceinline
+# define ccl_never_inline __declspec(noinline)
+# define ccl_maybe_unused
+# else /* _WIN32 && !FREE_WINDOWS */
+# define ccl_device_inline static inline __attribute__((always_inline))
+# define ccl_device_forceinline static inline __attribute__((always_inline))
+# define ccl_align(...) __attribute__((aligned(__VA_ARGS__)))
+# ifndef FREE_WINDOWS64
+# define __forceinline inline __attribute__((always_inline))
+# endif
+# define ccl_try_align(...) __attribute__((aligned(__VA_ARGS__)))
+# define ccl_may_alias __attribute__((__may_alias__))
+# define ccl_always_inline __attribute__((always_inline))
+# define ccl_never_inline __attribute__((noinline))
+# define ccl_maybe_unused __attribute__((used))
+# endif /* _WIN32 && !FREE_WINDOWS */
/* Use to suppress '-Wimplicit-fallthrough' (in place of 'break'). */
-# ifndef ATTR_FALLTHROUGH
-# if defined(__GNUC__) && (__GNUC__ >= 7) /* gcc7.0+ only */
-# define ATTR_FALLTHROUGH __attribute__((fallthrough))
-# else
-# define ATTR_FALLTHROUGH ((void) 0)
+# ifndef ATTR_FALLTHROUGH
+# if defined(__GNUC__) && (__GNUC__ >= 7) /* gcc7.0+ only */
+# define ATTR_FALLTHROUGH __attribute__((fallthrough))
+# else
+# define ATTR_FALLTHROUGH ((void)0)
+# endif
# endif
-# endif
-#endif /* __KERNEL_GPU__ */
+# endif /* __KERNEL_GPU__ */
/* macros */
/* hints for branch prediction, only use in code that runs a _lot_ */
-#if defined(__GNUC__) && defined(__KERNEL_CPU__)
-# define LIKELY(x) __builtin_expect(!!(x), 1)
-# define UNLIKELY(x) __builtin_expect(!!(x), 0)
-#else
-# define LIKELY(x) (x)
-# define UNLIKELY(x) (x)
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
-# if defined(__cplusplus)
-/* Some magic to be sure we don't have reference in the type. */
-template<typename T> static inline T decltype_helper(T x) { return x; }
-# define TYPEOF(x) decltype(decltype_helper(x))
+# if defined(__GNUC__) && defined(__KERNEL_CPU__)
+# define LIKELY(x) __builtin_expect(!!(x), 1)
+# define UNLIKELY(x) __builtin_expect(!!(x), 0)
# else
-# define TYPEOF(x) typeof(x)
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
+# endif
+
+# if defined(__GNUC__) || defined(__clang__)
+# if defined(__cplusplus)
+/* Some magic to be sure we don't have reference in the type. */
+template<typename T> static inline T decltype_helper(T x)
+{
+ return x;
+}
+# define TYPEOF(x) decltype(decltype_helper(x))
+# else
+# define TYPEOF(x) typeof(x)
+# endif
# endif
-#endif
/* Causes warning:
* incompatible types when assigning to type 'Foo' from type 'Bar'
* ... the compiler optimizes away the temp var */
-#ifdef __GNUC__
-#define CHECK_TYPE(var, type) { \
- TYPEOF(var) *__tmp; \
- __tmp = (type *)NULL; \
- (void) __tmp; \
-} (void) 0
-
-#define CHECK_TYPE_PAIR(var_a, var_b) { \
- TYPEOF(var_a) *__tmp; \
- __tmp = (typeof(var_b) *)NULL; \
- (void) __tmp; \
-} (void) 0
-#else
-# define CHECK_TYPE(var, type)
-# define CHECK_TYPE_PAIR(var_a, var_b)
-#endif
+# ifdef __GNUC__
+# define CHECK_TYPE(var, type) \
+ { \
+ TYPEOF(var) * __tmp; \
+ __tmp = (type *)NULL; \
+ (void)__tmp; \
+ } \
+ (void)0
+
+# define CHECK_TYPE_PAIR(var_a, var_b) \
+ { \
+ TYPEOF(var_a) * __tmp; \
+ __tmp = (typeof(var_b) *)NULL; \
+ (void)__tmp; \
+ } \
+ (void)0
+# else
+# define CHECK_TYPE(var, type)
+# define CHECK_TYPE_PAIR(var_a, var_b)
+# endif
/* can be used in simple macros */
-#define CHECK_TYPE_INLINE(val, type) \
- ((void)(((type)0) != (val)))
+# define CHECK_TYPE_INLINE(val, type) ((void)(((type)0) != (val)))
-#ifndef __KERNEL_GPU__
-# include <cassert>
-# define util_assert(statement) assert(statement)
-#else
-# define util_assert(statement)
-#endif
+# ifndef __KERNEL_GPU__
+# include <cassert>
+# define util_assert(statement) assert(statement)
+# else
+# define util_assert(statement)
+# endif
-#endif /* __UTIL_DEFINES_H__ */
+#endif /* __UTIL_DEFINES_H__ */
diff --git a/intern/cycles/util/util_foreach.h b/intern/cycles/util/util_foreach.h
index fd106d58b43..d907974be91 100644
--- a/intern/cycles/util/util_foreach.h
+++ b/intern/cycles/util/util_foreach.h
@@ -19,6 +19,6 @@
/* Nice foreach() loops for STL data structures. */
-#define foreach(x, y) for(x : y)
+#define foreach(x, y) for (x : y)
-#endif /* __UTIL_FOREACH_H__ */
+#endif /* __UTIL_FOREACH_H__ */
diff --git a/intern/cycles/util/util_function.h b/intern/cycles/util/util_function.h
index 72c7ce43073..f3cc00329ad 100644
--- a/intern/cycles/util/util_function.h
+++ b/intern/cycles/util/util_function.h
@@ -36,4 +36,4 @@ using std::placeholders::_9;
CCL_NAMESPACE_END
-#endif /* __UTIL_FUNCTION_H__ */
+#endif /* __UTIL_FUNCTION_H__ */
diff --git a/intern/cycles/util/util_guarded_allocator.cpp b/intern/cycles/util/util_guarded_allocator.cpp
index ae1d217c54f..1cb466a1ffa 100644
--- a/intern/cycles/util/util_guarded_allocator.cpp
+++ b/intern/cycles/util/util_guarded_allocator.cpp
@@ -25,25 +25,24 @@ static Stats global_stats(Stats::static_init);
void util_guarded_mem_alloc(size_t n)
{
- global_stats.mem_alloc(n);
+ global_stats.mem_alloc(n);
}
void util_guarded_mem_free(size_t n)
{
- global_stats.mem_free(n);
+ global_stats.mem_free(n);
}
/* Public API. */
size_t util_guarded_get_mem_used()
{
- return global_stats.mem_used;
+ return global_stats.mem_used;
}
size_t util_guarded_get_mem_peak()
{
- return global_stats.mem_peak;
+ return global_stats.mem_peak;
}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_guarded_allocator.h b/intern/cycles/util/util_guarded_allocator.h
index 99edf77e2c7..2d09326d2ca 100644
--- a/intern/cycles/util/util_guarded_allocator.h
+++ b/intern/cycles/util/util_guarded_allocator.h
@@ -31,117 +31,127 @@ void util_guarded_mem_alloc(size_t n);
void util_guarded_mem_free(size_t n);
/* Guarded allocator for the use with STL. */
-template <typename T>
-class GuardedAllocator {
-public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T *pointer;
- typedef const T *const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
-
- GuardedAllocator() {}
- GuardedAllocator(const GuardedAllocator&) {}
-
- T *allocate(size_t n, const void *hint = 0)
- {
- (void) hint;
- size_t size = n * sizeof(T);
- util_guarded_mem_alloc(size);
- if(n == 0) {
- return NULL;
- }
- T *mem;
+template<typename T> class GuardedAllocator {
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T *pointer;
+ typedef const T *const_pointer;
+ typedef T &reference;
+ typedef const T &const_reference;
+ typedef T value_type;
+
+ GuardedAllocator()
+ {
+ }
+ GuardedAllocator(const GuardedAllocator &)
+ {
+ }
+
+ T *allocate(size_t n, const void *hint = 0)
+ {
+ (void)hint;
+ size_t size = n * sizeof(T);
+ util_guarded_mem_alloc(size);
+ if (n == 0) {
+ return NULL;
+ }
+ T *mem;
#ifdef WITH_BLENDER_GUARDEDALLOC
- /* C++ standard requires allocation functions to allocate memory suitably
- * aligned for any standard type. This is 16 bytes for 64 bit platform as
- * far as i concerned. We might over-align on 32bit here, but that should
- * be all safe actually.
- */
- mem = (T*)MEM_mallocN_aligned(size, 16, "Cycles Alloc");
+ /* C++ standard requires allocation functions to allocate memory suitably
+ * aligned for any standard type. This is 16 bytes for 64 bit platform as
+ * far as i concerned. We might over-align on 32bit here, but that should
+ * be all safe actually.
+ */
+ mem = (T *)MEM_mallocN_aligned(size, 16, "Cycles Alloc");
#else
- mem = (T*)malloc(size);
+ mem = (T *)malloc(size);
#endif
- if(mem == NULL) {
- throw std::bad_alloc();
- }
- return mem;
- }
-
- void deallocate(T *p, size_t n)
- {
- util_guarded_mem_free(n * sizeof(T));
- if(p != NULL) {
+ if (mem == NULL) {
+ throw std::bad_alloc();
+ }
+ return mem;
+ }
+
+ void deallocate(T *p, size_t n)
+ {
+ util_guarded_mem_free(n * sizeof(T));
+ if (p != NULL) {
#ifdef WITH_BLENDER_GUARDEDALLOC
- MEM_freeN(p);
+ MEM_freeN(p);
#else
- free(p);
+ free(p);
#endif
- }
- }
-
- T *address(T& x) const
- {
- return &x;
- }
-
- const T *address(const T& x) const
- {
- return &x;
- }
-
- GuardedAllocator<T>& operator=(const GuardedAllocator&)
- {
- return *this;
- }
-
- size_t max_size() const
- {
- return size_t(-1);
- }
-
- template <class U>
- struct rebind {
- typedef GuardedAllocator<U> other;
- };
-
- template <class U>
- GuardedAllocator(const GuardedAllocator<U>&) {}
-
- template <class U>
- GuardedAllocator& operator=(const GuardedAllocator<U>&) { return *this; }
-
- inline bool operator==(GuardedAllocator const& /*other*/) const { return true; }
- inline bool operator!=(GuardedAllocator const& other) const { return !operator==(other); }
+ }
+ }
+
+ T *address(T &x) const
+ {
+ return &x;
+ }
+
+ const T *address(const T &x) const
+ {
+ return &x;
+ }
+
+ GuardedAllocator<T> &operator=(const GuardedAllocator &)
+ {
+ return *this;
+ }
+
+ size_t max_size() const
+ {
+ return size_t(-1);
+ }
+
+ template<class U> struct rebind {
+ typedef GuardedAllocator<U> other;
+ };
+
+ template<class U> GuardedAllocator(const GuardedAllocator<U> &)
+ {
+ }
+
+ template<class U> GuardedAllocator &operator=(const GuardedAllocator<U> &)
+ {
+ return *this;
+ }
+
+ inline bool operator==(GuardedAllocator const & /*other*/) const
+ {
+ return true;
+ }
+ inline bool operator!=(GuardedAllocator const &other) const
+ {
+ return !operator==(other);
+ }
#ifdef _MSC_VER
- /* Welcome to the black magic here.
- *
- * The issue is that MSVC C++ allocates container proxy on any
- * vector initialization, including static vectors which don't
- * have any data yet. This leads to several issues:
- *
- * - Static objects initialization fiasco (global_stats from
- * util_stats.h might not be initialized yet).
- * - If main() function changes allocator type (for example,
- * this might happen with `blender --debug-memory`) nobody
- * will know how to convert already allocated memory to a new
- * guarded allocator.
- *
- * Here we work this around by making it so container proxy does
- * not use guarded allocation. A bit fragile, unfortunately.
- */
- template<>
- struct rebind<std::_Container_proxy> {
- typedef std::allocator<std::_Container_proxy> other;
- };
-
- operator std::allocator<std::_Container_proxy>() const
- {
- return std::allocator<std::_Container_proxy>();
- }
+ /* Welcome to the black magic here.
+ *
+ * The issue is that MSVC C++ allocates container proxy on any
+ * vector initialization, including static vectors which don't
+ * have any data yet. This leads to several issues:
+ *
+ * - Static objects initialization fiasco (global_stats from
+ * util_stats.h might not be initialized yet).
+ * - If main() function changes allocator type (for example,
+ * this might happen with `blender --debug-memory`) nobody
+ * will know how to convert already allocated memory to a new
+ * guarded allocator.
+ *
+ * Here we work this around by making it so container proxy does
+ * not use guarded allocation. A bit fragile, unfortunately.
+ */
+ template<> struct rebind<std::_Container_proxy> {
+ typedef std::allocator<std::_Container_proxy> other;
+ };
+
+ operator std::allocator<std::_Container_proxy>() const
+ {
+ return std::allocator<std::_Container_proxy>();
+ }
#endif
};
@@ -158,17 +168,17 @@ size_t util_guarded_get_mem_peak();
* when running out of memory.
*/
#define MEM_GUARDED_CALL(progress, func, ...) \
- do { \
- try { \
- (func)(__VA_ARGS__); \
- } \
- catch (std::bad_alloc&) { \
- fprintf(stderr, "Error: run out of memory!\n"); \
- fflush(stderr); \
- (progress)->set_error("Out of memory"); \
- } \
- } while(false)
+ do { \
+ try { \
+ (func)(__VA_ARGS__); \
+ } \
+ catch (std::bad_alloc &) { \
+ fprintf(stderr, "Error: run out of memory!\n"); \
+ fflush(stderr); \
+ (progress)->set_error("Out of memory"); \
+ } \
+ } while (false)
CCL_NAMESPACE_END
-#endif /* __UTIL_GUARDED_ALLOCATOR_H__ */
+#endif /* __UTIL_GUARDED_ALLOCATOR_H__ */
diff --git a/intern/cycles/util/util_half.h b/intern/cycles/util/util_half.h
index 3868509c21b..9c40f5310c2 100644
--- a/intern/cycles/util/util_half.h
+++ b/intern/cycles/util/util_half.h
@@ -21,7 +21,7 @@
#include "util/util_math.h"
#ifdef __KERNEL_SSE2__
-#include "util/util_simd.h"
+# include "util/util_simd.h"
#endif
CCL_NAMESPACE_BEGIN
@@ -30,122 +30,139 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_OPENCL__
-#define float4_store_half(h, f, scale) vstore_half4(f * (scale), 0, h);
+# define float4_store_half(h, f, scale) vstore_half4(f *(scale), 0, h);
#else
/* CUDA has its own half data type, no need to define then */
-#ifndef __KERNEL_CUDA__
+# ifndef __KERNEL_CUDA__
/* Implementing this as a class rather than a typedef so that the compiler can tell it apart from unsigned shorts. */
class half {
-public:
- half() : v(0) {}
- half(const unsigned short& i) : v(i) {}
- operator unsigned short() { return v; }
- half& operator =(const unsigned short& i) { v = i; return *this; }
-private:
- unsigned short v;
+ public:
+ half() : v(0)
+ {
+ }
+ half(const unsigned short &i) : v(i)
+ {
+ }
+ operator unsigned short()
+ {
+ return v;
+ }
+ half &operator=(const unsigned short &i)
+ {
+ v = i;
+ return *this;
+ }
+
+ private:
+ unsigned short v;
};
-#endif
+# endif
-struct half4 { half x, y, z, w; };
+struct half4 {
+ half x, y, z, w;
+};
-#ifdef __KERNEL_CUDA__
+# ifdef __KERNEL_CUDA__
ccl_device_inline void float4_store_half(half *h, float4 f, float scale)
{
- h[0] = __float2half(f.x * scale);
- h[1] = __float2half(f.y * scale);
- h[2] = __float2half(f.z * scale);
- h[3] = __float2half(f.w * scale);
+ h[0] = __float2half(f.x * scale);
+ h[1] = __float2half(f.y * scale);
+ h[2] = __float2half(f.z * scale);
+ h[3] = __float2half(f.w * scale);
}
-#else
+# else
ccl_device_inline void float4_store_half(half *h, float4 f, float scale)
{
-#ifndef __KERNEL_SSE2__
- for(int i = 0; i < 4; i++) {
- /* optimized float to half for pixels:
- * assumes no negative, no nan, no inf, and sets denormal to 0 */
- union { uint i; float f; } in;
- float fscale = f[i] * scale;
- in.f = (fscale > 0.0f)? ((fscale < 65504.0f)? fscale: 65504.0f): 0.0f;
- int x = in.i;
-
- int absolute = x & 0x7FFFFFFF;
- int Z = absolute + 0xC8000000;
- int result = (absolute < 0x38800000)? 0: Z;
- int rshift = (result >> 13);
-
- h[i] = (rshift & 0x7FFF);
- }
-#else
- /* same as above with SSE */
- ssef fscale = load4f(f) * scale;
- ssef x = min(max(fscale, 0.0f), 65504.0f);
-
-#ifdef __KERNEL_AVX2__
- ssei rpack = _mm_cvtps_ph(x, 0);
-#else
- ssei absolute = cast(x) & 0x7FFFFFFF;
- ssei Z = absolute + 0xC8000000;
- ssei result = andnot(absolute < 0x38800000, Z);
- ssei rshift = (result >> 13) & 0x7FFF;
- ssei rpack = _mm_packs_epi32(rshift, rshift);
-#endif
-
- _mm_storel_pi((__m64*)h, _mm_castsi128_ps(rpack));
-#endif
+# ifndef __KERNEL_SSE2__
+ for (int i = 0; i < 4; i++) {
+ /* optimized float to half for pixels:
+ * assumes no negative, no nan, no inf, and sets denormal to 0 */
+ union {
+ uint i;
+ float f;
+ } in;
+ float fscale = f[i] * scale;
+ in.f = (fscale > 0.0f) ? ((fscale < 65504.0f) ? fscale : 65504.0f) : 0.0f;
+ int x = in.i;
+
+ int absolute = x & 0x7FFFFFFF;
+ int Z = absolute + 0xC8000000;
+ int result = (absolute < 0x38800000) ? 0 : Z;
+ int rshift = (result >> 13);
+
+ h[i] = (rshift & 0x7FFF);
+ }
+# else
+ /* same as above with SSE */
+ ssef fscale = load4f(f) * scale;
+ ssef x = min(max(fscale, 0.0f), 65504.0f);
+
+# ifdef __KERNEL_AVX2__
+ ssei rpack = _mm_cvtps_ph(x, 0);
+# else
+ ssei absolute = cast(x) & 0x7FFFFFFF;
+ ssei Z = absolute + 0xC8000000;
+ ssei result = andnot(absolute < 0x38800000, Z);
+ ssei rshift = (result >> 13) & 0x7FFF;
+ ssei rpack = _mm_packs_epi32(rshift, rshift);
+# endif
+
+ _mm_storel_pi((__m64 *)h, _mm_castsi128_ps(rpack));
+# endif
}
ccl_device_inline float half_to_float(half h)
{
- float f;
+ float f;
- *((int*) &f) = ((h & 0x8000) << 16) | (((h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13);
+ *((int *)&f) = ((h & 0x8000) << 16) | (((h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13);
- return f;
+ return f;
}
ccl_device_inline float4 half4_to_float4(half4 h)
{
- float4 f;
+ float4 f;
- f.x = half_to_float(h.x);
- f.y = half_to_float(h.y);
- f.z = half_to_float(h.z);
- f.w = half_to_float(h.w);
+ f.x = half_to_float(h.x);
+ f.y = half_to_float(h.y);
+ f.z = half_to_float(h.z);
+ f.w = half_to_float(h.w);
- return f;
+ return f;
}
ccl_device_inline half float_to_half(float f)
{
- const uint u = __float_as_uint(f);
- /* Sign bit, shifted to it's position. */
- uint sign_bit = u & 0x80000000;
- sign_bit >>= 16;
- /* Exponent. */
- uint exponent_bits = u & 0x7f800000;
- /* Non-sign bits. */
- uint value_bits = u & 0x7fffffff;
- value_bits >>= 13; /* Align mantissa on MSB. */
- value_bits -= 0x1c000; /* Adjust bias. */
- /* Flush-to-zero. */
- value_bits = (exponent_bits < 0x38800000) ? 0 : value_bits;
- /* Clamp-to-max. */
- value_bits = (exponent_bits > 0x47000000) ? 0x7bff : value_bits;
- /* Denormals-as-zero. */
- value_bits = (exponent_bits == 0 ? 0 : value_bits);
- /* Re-insert sign bit and return. */
- return (value_bits | sign_bit);
+ const uint u = __float_as_uint(f);
+ /* Sign bit, shifted to it's position. */
+ uint sign_bit = u & 0x80000000;
+ sign_bit >>= 16;
+ /* Exponent. */
+ uint exponent_bits = u & 0x7f800000;
+ /* Non-sign bits. */
+ uint value_bits = u & 0x7fffffff;
+ value_bits >>= 13; /* Align mantissa on MSB. */
+ value_bits -= 0x1c000; /* Adjust bias. */
+ /* Flush-to-zero. */
+ value_bits = (exponent_bits < 0x38800000) ? 0 : value_bits;
+ /* Clamp-to-max. */
+ value_bits = (exponent_bits > 0x47000000) ? 0x7bff : value_bits;
+ /* Denormals-as-zero. */
+ value_bits = (exponent_bits == 0 ? 0 : value_bits);
+ /* Re-insert sign bit and return. */
+ return (value_bits | sign_bit);
}
-#endif
+# endif
#endif
CCL_NAMESPACE_END
-#endif /* __UTIL_HALF_H__ */
+#endif /* __UTIL_HALF_H__ */
diff --git a/intern/cycles/util/util_hash.h b/intern/cycles/util/util_hash.h
index f343252eaca..785482967db 100644
--- a/intern/cycles/util/util_hash.h
+++ b/intern/cycles/util/util_hash.h
@@ -23,49 +23,56 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline uint hash_int_2d(uint kx, uint ky)
{
-#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
-
- uint a, b, c;
-
- a = b = c = 0xdeadbeef + (2 << 2) + 13;
- a += kx;
- b += ky;
-
- c ^= b; c -= rot(b,14);
- a ^= c; a -= rot(c,11);
- b ^= a; b -= rot(a,25);
- c ^= b; c -= rot(b,16);
- a ^= c; a -= rot(c,4);
- b ^= a; b -= rot(a,14);
- c ^= b; c -= rot(b,24);
-
- return c;
+#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+
+ uint a, b, c;
+
+ a = b = c = 0xdeadbeef + (2 << 2) + 13;
+ a += kx;
+ b += ky;
+
+ c ^= b;
+ c -= rot(b, 14);
+ a ^= c;
+ a -= rot(c, 11);
+ b ^= a;
+ b -= rot(a, 25);
+ c ^= b;
+ c -= rot(b, 16);
+ a ^= c;
+ a -= rot(c, 4);
+ b ^= a;
+ b -= rot(a, 14);
+ c ^= b;
+ c -= rot(b, 24);
+
+ return c;
#undef rot
}
ccl_device_inline uint hash_int(uint k)
{
- return hash_int_2d(k, 0);
+ return hash_int_2d(k, 0);
}
#ifndef __KERNEL_GPU__
static inline uint hash_string(const char *str)
{
- uint i = 0, c;
+ uint i = 0, c;
- while((c = *str++))
- i = i * 37 + c;
+ while ((c = *str++))
+ i = i * 37 + c;
- return i;
+ return i;
}
#endif
ccl_device_inline float hash_int_01(uint k)
{
- return (float)hash_int(k) * (1.0f/(float)0xFFFFFFFF);
+ return (float)hash_int(k) * (1.0f / (float)0xFFFFFFFF);
}
CCL_NAMESPACE_END
-#endif /* __UTIL_HASH_H__ */
+#endif /* __UTIL_HASH_H__ */
diff --git a/intern/cycles/util/util_ies.cpp b/intern/cycles/util/util_ies.cpp
index 277045d9bc4..ff5c709b406 100644
--- a/intern/cycles/util/util_ies.cpp
+++ b/intern/cycles/util/util_ies.cpp
@@ -30,374 +30,376 @@ template class GuardedAllocator<char>;
bool IESFile::load(ustring ies)
{
- clear();
- if(!parse(ies) || !process()) {
- clear();
- return false;
- }
- return true;
+ clear();
+ if (!parse(ies) || !process()) {
+ clear();
+ return false;
+ }
+ return true;
}
void IESFile::clear()
{
- intensity.clear();
- v_angles.clear();
- h_angles.clear();
+ intensity.clear();
+ v_angles.clear();
+ h_angles.clear();
}
int IESFile::packed_size()
{
- if(v_angles.size() && h_angles.size() > 0) {
- return 2 + h_angles.size() + v_angles.size() + h_angles.size()*v_angles.size();
- }
- return 0;
+ if (v_angles.size() && h_angles.size() > 0) {
+ return 2 + h_angles.size() + v_angles.size() + h_angles.size() * v_angles.size();
+ }
+ return 0;
}
void IESFile::pack(float *data)
{
- if(v_angles.size() && h_angles.size()) {
- *(data++) = __int_as_float(h_angles.size());
- *(data++) = __int_as_float(v_angles.size());
-
- memcpy(data, &h_angles[0], h_angles.size()*sizeof(float));
- data += h_angles.size();
- memcpy(data, &v_angles[0], v_angles.size()*sizeof(float));
- data += v_angles.size();
-
- for(int h = 0; h < intensity.size(); h++) {
- memcpy(data, &intensity[h][0], v_angles.size()*sizeof(float));
- data += v_angles.size();
- }
- }
+ if (v_angles.size() && h_angles.size()) {
+ *(data++) = __int_as_float(h_angles.size());
+ *(data++) = __int_as_float(v_angles.size());
+
+ memcpy(data, &h_angles[0], h_angles.size() * sizeof(float));
+ data += h_angles.size();
+ memcpy(data, &v_angles[0], v_angles.size() * sizeof(float));
+ data += v_angles.size();
+
+ for (int h = 0; h < intensity.size(); h++) {
+ memcpy(data, &intensity[h][0], v_angles.size() * sizeof(float));
+ data += v_angles.size();
+ }
+ }
}
class IESTextParser {
-public:
- vector<char> text;
- char *data;
-
- IESTextParser(ustring str)
- : text(str.begin(), str.end())
- {
- std::replace(text.begin(), text.end(), ',', ' ');
- data = strstr(&text[0], "\nTILT=");
- }
-
- bool eof() {
- return (data == NULL) || (data[0] == '\0');
- }
-
- double get_double() {
- if(eof()) {
- return 0.0;
- }
- char *old_data = data;
- double val = strtod(data, &data);
- if(data == old_data) {
- data = NULL;
- return 0.0;
- }
- return val;
- }
-
- long get_long() {
- if(eof()) {
- return 0;
- }
- char *old_data = data;
- long val = strtol(data, &data, 10);
- if(data == old_data) {
- data = NULL;
- return 0;
- }
- return val;
- }
+ public:
+ vector<char> text;
+ char *data;
+
+ IESTextParser(ustring str) : text(str.begin(), str.end())
+ {
+ std::replace(text.begin(), text.end(), ',', ' ');
+ data = strstr(&text[0], "\nTILT=");
+ }
+
+ bool eof()
+ {
+ return (data == NULL) || (data[0] == '\0');
+ }
+
+ double get_double()
+ {
+ if (eof()) {
+ return 0.0;
+ }
+ char *old_data = data;
+ double val = strtod(data, &data);
+ if (data == old_data) {
+ data = NULL;
+ return 0.0;
+ }
+ return val;
+ }
+
+ long get_long()
+ {
+ if (eof()) {
+ return 0;
+ }
+ char *old_data = data;
+ long val = strtol(data, &data, 10);
+ if (data == old_data) {
+ data = NULL;
+ return 0;
+ }
+ return val;
+ }
};
bool IESFile::parse(ustring ies)
{
- if(ies.empty()) {
- return false;
- }
-
- IESTextParser parser(ies);
- if(parser.eof()) {
- return false;
- }
-
- /* Handle the tilt data block. */
- if(strncmp(parser.data, "\nTILT=INCLUDE", 13) == 0) {
- parser.data += 13;
- parser.get_double(); /* Lamp to Luminaire geometry */
- int num_tilt = parser.get_long(); /* Amount of tilt angles and factors */
- /* Skip over angles and factors. */
- for(int i = 0; i < 2*num_tilt; i++) {
- parser.get_double();
- }
- }
- else {
- /* Skip to next line. */
- parser.data = strstr(parser.data+1, "\n");
- }
-
- if(parser.eof()) {
- return false;
- }
- parser.data++;
-
- parser.get_long(); /* Number of lamps */
- parser.get_double(); /* Lumens per lamp */
- double factor = parser.get_double(); /* Candela multiplier */
- int v_angles_num = parser.get_long(); /* Number of vertical angles */
- int h_angles_num = parser.get_long(); /* Number of horizontal angles */
- type = (IESType) parser.get_long(); /* Photometric type */
-
- /* TODO(lukas): Test whether the current type B processing can also deal with type A files.
- * In theory the only difference should be orientation which we ignore anyways, but with IES you never know...
- */
- if(type != TYPE_B && type != TYPE_C) {
- return false;
- }
-
- parser.get_long(); /* Unit of the geometry data */
- parser.get_double(); /* Width */
- parser.get_double(); /* Length */
- parser.get_double(); /* Height */
- factor *= parser.get_double(); /* Ballast factor */
- factor *= parser.get_double(); /* Ballast-Lamp Photometric factor */
- parser.get_double(); /* Input Watts */
-
- /* Intensity values in IES files are specified in candela (lumen/sr), a photometric quantity.
- * Cycles expects radiometric quantities, though, which requires a conversion.
- * However, the Luminous efficacy (ratio of lumens per Watt) depends on the spectral distribution
- * of the light source since lumens take human perception into account.
- * Since this spectral distribution is not known from the IES file, a typical one must be assumed.
- * The D65 standard illuminant has a Luminous efficacy of 177.83, which is used here to convert to Watt/sr.
- * A more advanced approach would be to add a Blackbody Temperature input to the node and numerically
- * integrate the Luminous efficacy from the resulting spectral distribution.
- * Also, the Watt/sr value must be multiplied by 4*pi to get the Watt value that Cycles expects
- * for lamp strength. Therefore, the conversion here uses 4*pi/177.83 as a Candela to Watt factor.
- */
- factor *= 0.0706650768394;
-
- v_angles.reserve(v_angles_num);
- for(int i = 0; i < v_angles_num; i++) {
- v_angles.push_back((float) parser.get_double());
- }
-
- h_angles.reserve(h_angles_num);
- for(int i = 0; i < h_angles_num; i++) {
- h_angles.push_back((float) parser.get_double());
- }
-
- intensity.resize(h_angles_num);
- for(int i = 0; i < h_angles_num; i++) {
- intensity[i].reserve(v_angles_num);
- for(int j = 0; j < v_angles_num; j++) {
- intensity[i].push_back((float) (factor * parser.get_double()));
- }
- }
-
- return !parser.eof();
+ if (ies.empty()) {
+ return false;
+ }
+
+ IESTextParser parser(ies);
+ if (parser.eof()) {
+ return false;
+ }
+
+ /* Handle the tilt data block. */
+ if (strncmp(parser.data, "\nTILT=INCLUDE", 13) == 0) {
+ parser.data += 13;
+ parser.get_double(); /* Lamp to Luminaire geometry */
+ int num_tilt = parser.get_long(); /* Amount of tilt angles and factors */
+ /* Skip over angles and factors. */
+ for (int i = 0; i < 2 * num_tilt; i++) {
+ parser.get_double();
+ }
+ }
+ else {
+ /* Skip to next line. */
+ parser.data = strstr(parser.data + 1, "\n");
+ }
+
+ if (parser.eof()) {
+ return false;
+ }
+ parser.data++;
+
+ parser.get_long(); /* Number of lamps */
+ parser.get_double(); /* Lumens per lamp */
+ double factor = parser.get_double(); /* Candela multiplier */
+ int v_angles_num = parser.get_long(); /* Number of vertical angles */
+ int h_angles_num = parser.get_long(); /* Number of horizontal angles */
+ type = (IESType)parser.get_long(); /* Photometric type */
+
+ /* TODO(lukas): Test whether the current type B processing can also deal with type A files.
+ * In theory the only difference should be orientation which we ignore anyways, but with IES you never know...
+ */
+ if (type != TYPE_B && type != TYPE_C) {
+ return false;
+ }
+
+ parser.get_long(); /* Unit of the geometry data */
+ parser.get_double(); /* Width */
+ parser.get_double(); /* Length */
+ parser.get_double(); /* Height */
+ factor *= parser.get_double(); /* Ballast factor */
+ factor *= parser.get_double(); /* Ballast-Lamp Photometric factor */
+ parser.get_double(); /* Input Watts */
+
+ /* Intensity values in IES files are specified in candela (lumen/sr), a photometric quantity.
+ * Cycles expects radiometric quantities, though, which requires a conversion.
+ * However, the Luminous efficacy (ratio of lumens per Watt) depends on the spectral distribution
+ * of the light source since lumens take human perception into account.
+ * Since this spectral distribution is not known from the IES file, a typical one must be assumed.
+ * The D65 standard illuminant has a Luminous efficacy of 177.83, which is used here to convert to Watt/sr.
+ * A more advanced approach would be to add a Blackbody Temperature input to the node and numerically
+ * integrate the Luminous efficacy from the resulting spectral distribution.
+ * Also, the Watt/sr value must be multiplied by 4*pi to get the Watt value that Cycles expects
+ * for lamp strength. Therefore, the conversion here uses 4*pi/177.83 as a Candela to Watt factor.
+ */
+ factor *= 0.0706650768394;
+
+ v_angles.reserve(v_angles_num);
+ for (int i = 0; i < v_angles_num; i++) {
+ v_angles.push_back((float)parser.get_double());
+ }
+
+ h_angles.reserve(h_angles_num);
+ for (int i = 0; i < h_angles_num; i++) {
+ h_angles.push_back((float)parser.get_double());
+ }
+
+ intensity.resize(h_angles_num);
+ for (int i = 0; i < h_angles_num; i++) {
+ intensity[i].reserve(v_angles_num);
+ for (int j = 0; j < v_angles_num; j++) {
+ intensity[i].push_back((float)(factor * parser.get_double()));
+ }
+ }
+
+ return !parser.eof();
}
bool IESFile::process_type_b()
{
- vector<vector<float> > newintensity;
- newintensity.resize(v_angles.size());
- for(int i = 0; i < v_angles.size(); i++) {
- newintensity[i].reserve(h_angles.size());
- for(int j = 0; j < h_angles.size(); j++) {
- newintensity[i].push_back(intensity[j][i]);
- }
- }
- intensity.swap(newintensity);
- h_angles.swap(v_angles);
-
- float h_first = h_angles[0], h_last = h_angles[h_angles.size()-1];
- if(h_last != 90.0f) {
- return false;
- }
-
- if(h_first == 0.0f) {
- /* The range in the file corresponds to 90°-180°, we need to mirror that to get the
- * full 180° range. */
- vector<float> new_h_angles;
- vector<vector<float> > new_intensity;
- int hnum = h_angles.size();
- new_h_angles.reserve(2*hnum-1);
- new_intensity.reserve(2*hnum-1);
- for(int i = hnum-1; i > 0; i--) {
- new_h_angles.push_back(90.0f - h_angles[i]);
- new_intensity.push_back(intensity[i]);
- }
- for(int i = 0; i < hnum; i++) {
- new_h_angles.push_back(90.0f + h_angles[i]);
- new_intensity.push_back(intensity[i]);
- }
- h_angles.swap(new_h_angles);
- intensity.swap(new_intensity);
- }
- else if(h_first == -90.0f) {
- /* We have full 180° coverage, so just shift to match the angle range convention. */
- for(int i = 0; i < h_angles.size(); i++) {
- h_angles[i] += 90.0f;
- }
- }
- /* To get correct results with the cubic interpolation in the kernel, the horizontal range
- * has to cover all 360°. Therefore, we copy the 0° entry to 360° to ensure full coverage
- * and seamless interpolation. */
- h_angles.push_back(360.0f);
- intensity.push_back(intensity[0]);
-
- float v_first = v_angles[0], v_last = v_angles[v_angles.size()-1];
- if(v_last != 90.0f) {
- return false;
- }
-
- if(v_first == 0.0f) {
- /* The range in the file corresponds to 90°-180°, we need to mirror that to get the
- * full 180° range. */
- vector<float> new_v_angles;
- int hnum = h_angles.size();
- int vnum = v_angles.size();
- new_v_angles.reserve(2*vnum-1);
- for(int i = vnum-1; i > 0; i--) {
- new_v_angles.push_back(90.0f - v_angles[i]);
- }
- for(int i = 0; i < vnum; i++) {
- new_v_angles.push_back(90.0f + v_angles[i]);
- }
- for(int i = 0; i < hnum; i++) {
- vector<float> new_intensity;
- new_intensity.reserve(2*vnum-1);
- for(int j = vnum-2; j >= 0; j--) {
- new_intensity.push_back(intensity[i][j]);
- }
- new_intensity.insert(new_intensity.end(), intensity[i].begin(), intensity[i].end());
- intensity[i].swap(new_intensity);
- }
- v_angles.swap(new_v_angles);
- }
- else if(v_first == -90.0f) {
- /* We have full 180° coverage, so just shift to match the angle range convention. */
- for(int i = 0; i < v_angles.size(); i++) {
- v_angles[i] += 90.0f;
- }
- }
-
- return true;
+ vector<vector<float>> newintensity;
+ newintensity.resize(v_angles.size());
+ for (int i = 0; i < v_angles.size(); i++) {
+ newintensity[i].reserve(h_angles.size());
+ for (int j = 0; j < h_angles.size(); j++) {
+ newintensity[i].push_back(intensity[j][i]);
+ }
+ }
+ intensity.swap(newintensity);
+ h_angles.swap(v_angles);
+
+ float h_first = h_angles[0], h_last = h_angles[h_angles.size() - 1];
+ if (h_last != 90.0f) {
+ return false;
+ }
+
+ if (h_first == 0.0f) {
+ /* The range in the file corresponds to 90°-180°, we need to mirror that to get the
+ * full 180° range. */
+ vector<float> new_h_angles;
+ vector<vector<float>> new_intensity;
+ int hnum = h_angles.size();
+ new_h_angles.reserve(2 * hnum - 1);
+ new_intensity.reserve(2 * hnum - 1);
+ for (int i = hnum - 1; i > 0; i--) {
+ new_h_angles.push_back(90.0f - h_angles[i]);
+ new_intensity.push_back(intensity[i]);
+ }
+ for (int i = 0; i < hnum; i++) {
+ new_h_angles.push_back(90.0f + h_angles[i]);
+ new_intensity.push_back(intensity[i]);
+ }
+ h_angles.swap(new_h_angles);
+ intensity.swap(new_intensity);
+ }
+ else if (h_first == -90.0f) {
+ /* We have full 180° coverage, so just shift to match the angle range convention. */
+ for (int i = 0; i < h_angles.size(); i++) {
+ h_angles[i] += 90.0f;
+ }
+ }
+ /* To get correct results with the cubic interpolation in the kernel, the horizontal range
+ * has to cover all 360°. Therefore, we copy the 0° entry to 360° to ensure full coverage
+ * and seamless interpolation. */
+ h_angles.push_back(360.0f);
+ intensity.push_back(intensity[0]);
+
+ float v_first = v_angles[0], v_last = v_angles[v_angles.size() - 1];
+ if (v_last != 90.0f) {
+ return false;
+ }
+
+ if (v_first == 0.0f) {
+ /* The range in the file corresponds to 90°-180°, we need to mirror that to get the
+ * full 180° range. */
+ vector<float> new_v_angles;
+ int hnum = h_angles.size();
+ int vnum = v_angles.size();
+ new_v_angles.reserve(2 * vnum - 1);
+ for (int i = vnum - 1; i > 0; i--) {
+ new_v_angles.push_back(90.0f - v_angles[i]);
+ }
+ for (int i = 0; i < vnum; i++) {
+ new_v_angles.push_back(90.0f + v_angles[i]);
+ }
+ for (int i = 0; i < hnum; i++) {
+ vector<float> new_intensity;
+ new_intensity.reserve(2 * vnum - 1);
+ for (int j = vnum - 2; j >= 0; j--) {
+ new_intensity.push_back(intensity[i][j]);
+ }
+ new_intensity.insert(new_intensity.end(), intensity[i].begin(), intensity[i].end());
+ intensity[i].swap(new_intensity);
+ }
+ v_angles.swap(new_v_angles);
+ }
+ else if (v_first == -90.0f) {
+ /* We have full 180° coverage, so just shift to match the angle range convention. */
+ for (int i = 0; i < v_angles.size(); i++) {
+ v_angles[i] += 90.0f;
+ }
+ }
+
+ return true;
}
bool IESFile::process_type_c()
{
- if(h_angles[0] == 90.0f) {
- /* Some files are stored from 90° to 270°, so we just rotate them to the regular 0°-180° range here. */
- for(int i = 0; i < h_angles.size(); i++) {
- h_angles[i] -= 90.0f;
- }
- }
-
- if(h_angles[0] != 0.0f) {
- return false;
- }
-
- if(h_angles.size() == 1) {
- h_angles.push_back(360.0f);
- intensity.push_back(intensity[0]);
- }
-
- if(h_angles[h_angles.size()-1] == 90.0f) {
- /* Only one quadrant is defined, so we need to mirror twice (from one to two, then to four).
- * Since the two->four mirroring step might also be required if we get an input of two quadrants,
- * we only do the first mirror here and later do the second mirror in either case. */
- int hnum = h_angles.size();
- for(int i = hnum-2; i >= 0; i--) {
- h_angles.push_back(180.0f - h_angles[i]);
- intensity.push_back(intensity[i]);
- }
- }
-
- if(h_angles[h_angles.size()-1] == 180.0f) {
- /* Mirror half to the full range. */
- int hnum = h_angles.size();
- for(int i = hnum-2; i >= 0; i--) {
- h_angles.push_back(360.0f - h_angles[i]);
- intensity.push_back(intensity[i]);
- }
- }
-
- /* Some files skip the 360° entry (contrary to standard) because it's supposed to be identical to the 0° entry.
- * If the file has a discernible order in its spacing, just fix this. */
- if(h_angles[h_angles.size()-1] != 360.0f) {
- int hnum = h_angles.size();
- float last_step = h_angles[hnum-1]-h_angles[hnum-2];
- float first_step = h_angles[1]-h_angles[0];
- float difference = 360.0f - h_angles[hnum-1];
- if(last_step == difference || first_step == difference) {
- h_angles.push_back(360.0f);
- intensity.push_back(intensity[0]);
- }
- else {
- return false;
- }
- }
-
- float v_first = v_angles[0], v_last = v_angles[v_angles.size()-1];
- if(v_first == 90.0f) {
- if(v_last == 180.0f) {
- /* Flip to ensure that vertical angles always start at 0°. */
- for(int i = 0; i < v_angles.size(); i++) {
- v_angles[i] = 180.0f - v_angles[i];
- }
- }
- else {
- return false;
- }
- }
- else if(v_first != 0.0f) {
- return false;
- }
-
- return true;
+ if (h_angles[0] == 90.0f) {
+ /* Some files are stored from 90° to 270°, so we just rotate them to the regular 0°-180° range here. */
+ for (int i = 0; i < h_angles.size(); i++) {
+ h_angles[i] -= 90.0f;
+ }
+ }
+
+ if (h_angles[0] != 0.0f) {
+ return false;
+ }
+
+ if (h_angles.size() == 1) {
+ h_angles.push_back(360.0f);
+ intensity.push_back(intensity[0]);
+ }
+
+ if (h_angles[h_angles.size() - 1] == 90.0f) {
+ /* Only one quadrant is defined, so we need to mirror twice (from one to two, then to four).
+ * Since the two->four mirroring step might also be required if we get an input of two quadrants,
+ * we only do the first mirror here and later do the second mirror in either case. */
+ int hnum = h_angles.size();
+ for (int i = hnum - 2; i >= 0; i--) {
+ h_angles.push_back(180.0f - h_angles[i]);
+ intensity.push_back(intensity[i]);
+ }
+ }
+
+ if (h_angles[h_angles.size() - 1] == 180.0f) {
+ /* Mirror half to the full range. */
+ int hnum = h_angles.size();
+ for (int i = hnum - 2; i >= 0; i--) {
+ h_angles.push_back(360.0f - h_angles[i]);
+ intensity.push_back(intensity[i]);
+ }
+ }
+
+ /* Some files skip the 360° entry (contrary to standard) because it's supposed to be identical to the 0° entry.
+ * If the file has a discernible order in its spacing, just fix this. */
+ if (h_angles[h_angles.size() - 1] != 360.0f) {
+ int hnum = h_angles.size();
+ float last_step = h_angles[hnum - 1] - h_angles[hnum - 2];
+ float first_step = h_angles[1] - h_angles[0];
+ float difference = 360.0f - h_angles[hnum - 1];
+ if (last_step == difference || first_step == difference) {
+ h_angles.push_back(360.0f);
+ intensity.push_back(intensity[0]);
+ }
+ else {
+ return false;
+ }
+ }
+
+ float v_first = v_angles[0], v_last = v_angles[v_angles.size() - 1];
+ if (v_first == 90.0f) {
+ if (v_last == 180.0f) {
+ /* Flip to ensure that vertical angles always start at 0°. */
+ for (int i = 0; i < v_angles.size(); i++) {
+ v_angles[i] = 180.0f - v_angles[i];
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ else if (v_first != 0.0f) {
+ return false;
+ }
+
+ return true;
}
bool IESFile::process()
{
- if(h_angles.size() == 0 || v_angles.size() == 0) {
- return false;
- }
-
- if(type == TYPE_B) {
- if(!process_type_b()) {
- return false;
- }
- }
- else {
- assert(type == TYPE_C);
- if(!process_type_c()) {
- return false;
- }
- }
-
- assert(v_angles[0] == 0.0f);
- assert(h_angles[0] == 0.0f);
- assert(h_angles[h_angles.size()-1] == 360.0f);
-
- /* Convert from deg to rad. */
- for(int i = 0; i < v_angles.size(); i++) {
- v_angles[i] *= M_PI_F / 180.f;
- }
- for(int i = 0; i < h_angles.size(); i++) {
- h_angles[i] *= M_PI_F / 180.f;
- }
-
- return true;
+ if (h_angles.size() == 0 || v_angles.size() == 0) {
+ return false;
+ }
+
+ if (type == TYPE_B) {
+ if (!process_type_b()) {
+ return false;
+ }
+ }
+ else {
+ assert(type == TYPE_C);
+ if (!process_type_c()) {
+ return false;
+ }
+ }
+
+ assert(v_angles[0] == 0.0f);
+ assert(h_angles[0] == 0.0f);
+ assert(h_angles[h_angles.size() - 1] == 360.0f);
+
+ /* Convert from deg to rad. */
+ for (int i = 0; i < v_angles.size(); i++) {
+ v_angles[i] *= M_PI_F / 180.f;
+ }
+ for (int i = 0; i < h_angles.size(); i++) {
+ h_angles[i] *= M_PI_F / 180.f;
+ }
+
+ return true;
}
IESFile::~IESFile()
{
- clear();
+ clear();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_ies.h b/intern/cycles/util/util_ies.h
index 096b1fdf803..ab1b9ea57cf 100644
--- a/intern/cycles/util/util_ies.h
+++ b/intern/cycles/util/util_ies.h
@@ -23,39 +23,37 @@
CCL_NAMESPACE_BEGIN
class IESFile {
-public:
- IESFile() {}
- ~IESFile();
-
- int packed_size();
- void pack(float *data);
-
- bool load(ustring ies);
- void clear();
-
-protected:
- bool parse(ustring ies);
- bool process();
- bool process_type_b();
- bool process_type_c();
-
- /* The brightness distribution is stored in spherical coordinates.
- * The horizontal angles correspond to theta in the regular notation
- * and always span the full range from 0° to 360°.
- * The vertical angles correspond to phi and always start at 0°. */
- vector<float> v_angles, h_angles;
- /* The actual values are stored here, with every entry storing the values
- * of one horizontal segment. */
- vector<vector<float> > intensity;
-
- /* Types of angle representation in IES files. Currently, only B and C are supported. */
- enum IESType {
- TYPE_A = 3,
- TYPE_B = 2,
- TYPE_C = 1
- } type;
+ public:
+ IESFile()
+ {
+ }
+ ~IESFile();
+
+ int packed_size();
+ void pack(float *data);
+
+ bool load(ustring ies);
+ void clear();
+
+ protected:
+ bool parse(ustring ies);
+ bool process();
+ bool process_type_b();
+ bool process_type_c();
+
+ /* The brightness distribution is stored in spherical coordinates.
+ * The horizontal angles correspond to theta in the regular notation
+ * and always span the full range from 0° to 360°.
+ * The vertical angles correspond to phi and always start at 0°. */
+ vector<float> v_angles, h_angles;
+ /* The actual values are stored here, with every entry storing the values
+ * of one horizontal segment. */
+ vector<vector<float>> intensity;
+
+ /* Types of angle representation in IES files. Currently, only B and C are supported. */
+ enum IESType { TYPE_A = 3, TYPE_B = 2, TYPE_C = 1 } type;
};
CCL_NAMESPACE_END
-#endif /* __UTIL_IES_H__ */
+#endif /* __UTIL_IES_H__ */
diff --git a/intern/cycles/util/util_image.h b/intern/cycles/util/util_image.h
index da5f56271c8..8962c09d098 100644
--- a/intern/cycles/util/util_image.h
+++ b/intern/cycles/util/util_image.h
@@ -15,20 +15,20 @@
*/
#ifndef __UTIL_IMAGE_H__
-#define __UTIL_IMAGE_H__
+# define __UTIL_IMAGE_H__
/* OpenImageIO is used for all image file reading and writing. */
-#include <OpenImageIO/imageio.h>
+# include <OpenImageIO/imageio.h>
-#include "util/util_vector.h"
+# include "util/util_vector.h"
CCL_NAMESPACE_BEGIN
OIIO_NAMESPACE_USING
template<typename T>
-void util_image_resize_pixels(const vector<T>& input_pixels,
+void util_image_resize_pixels(const vector<T> &input_pixels,
const size_t input_width,
const size_t input_height,
const size_t input_depth,
@@ -39,69 +39,59 @@ void util_image_resize_pixels(const vector<T>& input_pixels,
size_t *output_depth);
/* Cast input pixel from unknown storage to float. */
-template<typename T>
-inline float util_image_cast_to_float(T value);
+template<typename T> inline float util_image_cast_to_float(T value);
-template<>
-inline float util_image_cast_to_float(float value)
+template<> inline float util_image_cast_to_float(float value)
{
- return value;
+ return value;
}
-template<>
-inline float util_image_cast_to_float(uchar value)
+template<> inline float util_image_cast_to_float(uchar value)
{
- return (float)value / 255.0f;
+ return (float)value / 255.0f;
}
-template<>
-inline float util_image_cast_to_float(uint16_t value)
+template<> inline float util_image_cast_to_float(uint16_t value)
{
- return (float)value / 65535.0f;
+ return (float)value / 65535.0f;
}
-template<>
-inline float util_image_cast_to_float(half value)
+template<> inline float util_image_cast_to_float(half value)
{
- return half_to_float(value);
+ return half_to_float(value);
}
/* Cast float value to output pixel type. */
-template<typename T>
-inline T util_image_cast_from_float(float value);
+template<typename T> inline T util_image_cast_from_float(float value);
-template<>
-inline float util_image_cast_from_float(float value)
+template<> inline float util_image_cast_from_float(float value)
{
- return value;
+ return value;
}
-template<>
-inline uchar util_image_cast_from_float(float value)
+template<> inline uchar util_image_cast_from_float(float value)
{
- if(value < 0.0f) {
- return 0;
- }
- else if(value > (1.0f - 0.5f / 255.0f)) {
- return 255;
- }
- return (uchar)((255.0f * value) + 0.5f);
+ if (value < 0.0f) {
+ return 0;
+ }
+ else if (value > (1.0f - 0.5f / 255.0f)) {
+ return 255;
+ }
+ return (uchar)((255.0f * value) + 0.5f);
}
-template<>
-inline uint16_t util_image_cast_from_float(float value)
+template<> inline uint16_t util_image_cast_from_float(float value)
{
- if(value < 0.0f) {
- return 0;
- }
- else if(value > (1.0f - 0.5f / 65535.0f)) {
- return 65535;
- }
- return (uint16_t)((65535.0f * value) + 0.5f);
+ if (value < 0.0f) {
+ return 0;
+ }
+ else if (value > (1.0f - 0.5f / 65535.0f)) {
+ return 65535;
+ }
+ return (uint16_t)((65535.0f * value) + 0.5f);
}
-template<>
-inline half util_image_cast_from_float(float value)
+template<> inline half util_image_cast_from_float(float value)
{
- return float_to_half(value);
+ return float_to_half(value);
}
CCL_NAMESPACE_END
-#endif /* __UTIL_IMAGE_H__ */
+#endif /* __UTIL_IMAGE_H__ */
#include "util/util_image_impl.h"
diff --git a/intern/cycles/util/util_image_impl.h b/intern/cycles/util/util_image_impl.h
index 5bc1c727595..3eb30d070ea 100644
--- a/intern/cycles/util/util_image_impl.h
+++ b/intern/cycles/util/util_image_impl.h
@@ -26,20 +26,21 @@ CCL_NAMESPACE_BEGIN
namespace {
template<typename T>
-const T *util_image_read(const vector<T>& pixels,
+const T *util_image_read(const vector<T> &pixels,
const size_t width,
const size_t height,
const size_t /*depth*/,
const size_t components,
- const size_t x, const size_t y, const size_t z) {
- const size_t index = ((size_t)z * (width * height) +
- (size_t)y * width +
- (size_t)x) * components;
- return &pixels[index];
+ const size_t x,
+ const size_t y,
+ const size_t z)
+{
+ const size_t index = ((size_t)z * (width * height) + (size_t)y * width + (size_t)x) * components;
+ return &pixels[index];
}
template<typename T>
-void util_image_downscale_sample(const vector<T>& pixels,
+void util_image_downscale_sample(const vector<T> &pixels,
const size_t width,
const size_t height,
const size_t depth,
@@ -50,48 +51,41 @@ void util_image_downscale_sample(const vector<T>& pixels,
const float z,
T *result)
{
- assert(components <= 4);
- const size_t ix = (size_t)x,
- iy = (size_t)y,
- iz = (size_t)z;
- /* TODO(sergey): Support something smarter than box filer. */
- float accum[4] = {0};
- size_t count = 0;
- for(size_t dz = 0; dz < kernel_size; ++dz) {
- for(size_t dy = 0; dy < kernel_size; ++dy) {
- for(size_t dx = 0; dx < kernel_size; ++dx) {
- const size_t nx = ix + dx,
- ny = iy + dy,
- nz = iz + dz;
- if(nx >= width || ny >= height || nz >= depth) {
- continue;
- }
- const T *pixel = util_image_read(pixels,
- width, height, depth,
- components,
- nx, ny, nz);
- for(size_t k = 0; k < components; ++k) {
- accum[k] += util_image_cast_to_float(pixel[k]);
- }
- ++count;
- }
- }
- }
- if(count != 0) {
- const float inv_count = 1.0f / (float)count;
- for(size_t k = 0; k < components; ++k) {
- result[k] = util_image_cast_from_float<T>(accum[k] * inv_count);
- }
- }
- else {
- for(size_t k = 0; k < components; ++k) {
- result[k] = T(0.0f);
- }
- }
+ assert(components <= 4);
+ const size_t ix = (size_t)x, iy = (size_t)y, iz = (size_t)z;
+ /* TODO(sergey): Support something smarter than box filer. */
+ float accum[4] = {0};
+ size_t count = 0;
+ for (size_t dz = 0; dz < kernel_size; ++dz) {
+ for (size_t dy = 0; dy < kernel_size; ++dy) {
+ for (size_t dx = 0; dx < kernel_size; ++dx) {
+ const size_t nx = ix + dx, ny = iy + dy, nz = iz + dz;
+ if (nx >= width || ny >= height || nz >= depth) {
+ continue;
+ }
+ const T *pixel = util_image_read(pixels, width, height, depth, components, nx, ny, nz);
+ for (size_t k = 0; k < components; ++k) {
+ accum[k] += util_image_cast_to_float(pixel[k]);
+ }
+ ++count;
+ }
+ }
+ }
+ if (count != 0) {
+ const float inv_count = 1.0f / (float)count;
+ for (size_t k = 0; k < components; ++k) {
+ result[k] = util_image_cast_from_float<T>(accum[k] * inv_count);
+ }
+ }
+ else {
+ for (size_t k = 0; k < components; ++k) {
+ result[k] = T(0.0f);
+ }
+ }
}
template<typename T>
-void util_image_downscale_pixels(const vector<T>& input_pixels,
+void util_image_downscale_pixels(const vector<T> &input_pixels,
const size_t input_width,
const size_t input_height,
const size_t input_depth,
@@ -102,31 +96,33 @@ void util_image_downscale_pixels(const vector<T>& input_pixels,
const size_t output_depth,
vector<T> *output_pixels)
{
- const size_t kernel_size = (size_t)(inv_scale_factor + 0.5f);
- for(size_t z = 0; z < output_depth; ++z) {
- for(size_t y = 0; y < output_height; ++y) {
- for(size_t x = 0; x < output_width; ++x) {
- const float input_x = (float)x * inv_scale_factor,
- input_y = (float)y * inv_scale_factor,
- input_z = (float)z * inv_scale_factor;
- const size_t output_index =
- (z * output_width * output_height +
- y * output_width + x) * components;
- util_image_downscale_sample(input_pixels,
- input_width, input_height, input_depth,
- components,
- kernel_size,
- input_x, input_y, input_z,
- &output_pixels->at(output_index));
- }
- }
- }
+ const size_t kernel_size = (size_t)(inv_scale_factor + 0.5f);
+ for (size_t z = 0; z < output_depth; ++z) {
+ for (size_t y = 0; y < output_height; ++y) {
+ for (size_t x = 0; x < output_width; ++x) {
+ const float input_x = (float)x * inv_scale_factor, input_y = (float)y * inv_scale_factor,
+ input_z = (float)z * inv_scale_factor;
+ const size_t output_index = (z * output_width * output_height + y * output_width + x) *
+ components;
+ util_image_downscale_sample(input_pixels,
+ input_width,
+ input_height,
+ input_depth,
+ components,
+ kernel_size,
+ input_x,
+ input_y,
+ input_z,
+ &output_pixels->at(output_index));
+ }
+ }
+ }
}
-} /* namespace */
+} /* namespace */
template<typename T>
-void util_image_resize_pixels(const vector<T>& input_pixels,
+void util_image_resize_pixels(const vector<T> &input_pixels,
const size_t input_width,
const size_t input_height,
const size_t input_depth,
@@ -137,39 +133,43 @@ void util_image_resize_pixels(const vector<T>& input_pixels,
size_t *output_height,
size_t *output_depth)
{
- /* Early output for case when no scaling is applied. */
- if(scale_factor == 1.0f) {
- *output_width = input_width;
- *output_height = input_height;
- *output_depth = input_depth;
- *output_pixels = input_pixels;
- return;
- }
- /* First of all, we calculate output image dimensions.
- * We clamp them to be 1 pixel at least so we do not generate degenerate
- * image.
- */
- *output_width = max((size_t)((float)input_width * scale_factor), (size_t)1);
- *output_height = max((size_t)((float)input_height * scale_factor), (size_t)1);
- *output_depth = max((size_t)((float)input_depth * scale_factor), (size_t)1);
- /* Prepare pixel storage for the result. */
- const size_t num_output_pixels = ((*output_width) *
- (*output_height) *
- (*output_depth)) * components;
- output_pixels->resize(num_output_pixels);
- if(scale_factor < 1.0f) {
- const float inv_scale_factor = 1.0f / scale_factor;
- util_image_downscale_pixels(input_pixels,
- input_width, input_height, input_depth,
- components,
- inv_scale_factor,
- *output_width, *output_height, *output_depth,
- output_pixels);
- } else {
- /* TODO(sergey): Needs implementation. */
- }
+ /* Early output for case when no scaling is applied. */
+ if (scale_factor == 1.0f) {
+ *output_width = input_width;
+ *output_height = input_height;
+ *output_depth = input_depth;
+ *output_pixels = input_pixels;
+ return;
+ }
+ /* First of all, we calculate output image dimensions.
+ * We clamp them to be 1 pixel at least so we do not generate degenerate
+ * image.
+ */
+ *output_width = max((size_t)((float)input_width * scale_factor), (size_t)1);
+ *output_height = max((size_t)((float)input_height * scale_factor), (size_t)1);
+ *output_depth = max((size_t)((float)input_depth * scale_factor), (size_t)1);
+ /* Prepare pixel storage for the result. */
+ const size_t num_output_pixels = ((*output_width) * (*output_height) * (*output_depth)) *
+ components;
+ output_pixels->resize(num_output_pixels);
+ if (scale_factor < 1.0f) {
+ const float inv_scale_factor = 1.0f / scale_factor;
+ util_image_downscale_pixels(input_pixels,
+ input_width,
+ input_height,
+ input_depth,
+ components,
+ inv_scale_factor,
+ *output_width,
+ *output_height,
+ *output_depth,
+ output_pixels);
+ }
+ else {
+ /* TODO(sergey): Needs implementation. */
+ }
}
CCL_NAMESPACE_END
-#endif /* __UTIL_IMAGE_IMPL_H__ */
+#endif /* __UTIL_IMAGE_IMPL_H__ */
diff --git a/intern/cycles/util/util_list.h b/intern/cycles/util/util_list.h
index fcf8e4f5c74..f555b001186 100644
--- a/intern/cycles/util/util_list.h
+++ b/intern/cycles/util/util_list.h
@@ -25,4 +25,4 @@ using std::list;
CCL_NAMESPACE_END
-#endif /* __UTIL_LIST_H__ */
+#endif /* __UTIL_LIST_H__ */
diff --git a/intern/cycles/util/util_logging.cpp b/intern/cycles/util/util_logging.cpp
index b0922db32fb..4a5e7e6a9ea 100644
--- a/intern/cycles/util/util_logging.cpp
+++ b/intern/cycles/util/util_logging.cpp
@@ -28,63 +28,55 @@ CCL_NAMESPACE_BEGIN
void util_logging_init(const char *argv0)
{
#ifdef WITH_CYCLES_LOGGING
- using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
+ using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
- /* Make it so ERROR messages are always print into console. */
- char severity_fatal[32];
- snprintf(severity_fatal, sizeof(severity_fatal), "%d",
- google::GLOG_ERROR);
+ /* Make it so ERROR messages are always print into console. */
+ char severity_fatal[32];
+ snprintf(severity_fatal, sizeof(severity_fatal), "%d", google::GLOG_ERROR);
- google::InitGoogleLogging(argv0);
- SetCommandLineOption("logtostderr", "1");
- SetCommandLineOption("v", "0");
- SetCommandLineOption("stderrthreshold", severity_fatal);
- SetCommandLineOption("minloglevel", severity_fatal);
+ google::InitGoogleLogging(argv0);
+ SetCommandLineOption("logtostderr", "1");
+ SetCommandLineOption("v", "0");
+ SetCommandLineOption("stderrthreshold", severity_fatal);
+ SetCommandLineOption("minloglevel", severity_fatal);
#else
- (void) argv0;
+ (void)argv0;
#endif
}
void util_logging_start()
{
#ifdef WITH_CYCLES_LOGGING
- using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
- SetCommandLineOption("logtostderr", "1");
- SetCommandLineOption("v", "2");
- SetCommandLineOption("stderrthreshold", "1");
- SetCommandLineOption("minloglevel", "0");
+ using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
+ SetCommandLineOption("logtostderr", "1");
+ SetCommandLineOption("v", "2");
+ SetCommandLineOption("stderrthreshold", "1");
+ SetCommandLineOption("minloglevel", "0");
#endif
}
void util_logging_verbosity_set(int verbosity)
{
#ifdef WITH_CYCLES_LOGGING
- using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
- char val[10];
- snprintf(val, sizeof(val), "%d", verbosity);
- SetCommandLineOption("v", val);
+ using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
+ char val[10];
+ snprintf(val, sizeof(val), "%d", verbosity);
+ SetCommandLineOption("v", val);
#else
- (void) verbosity;
+ (void)verbosity;
#endif
}
-std::ostream& operator <<(std::ostream &os,
- const int2 &value)
+std::ostream &operator<<(std::ostream &os, const int2 &value)
{
- os << "(" << value.x
- << ", " << value.y
- << ")";
- return os;
+ os << "(" << value.x << ", " << value.y << ")";
+ return os;
}
-std::ostream& operator <<(std::ostream &os,
- const float3 &value)
+std::ostream &operator<<(std::ostream &os, const float3 &value)
{
- os << "(" << value.x
- << ", " << value.y
- << ", " << value.z
- << ")";
- return os;
+ os << "(" << value.x << ", " << value.y << ", " << value.z << ")";
+ return os;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_logging.h b/intern/cycles/util/util_logging.h
index f66d7c92dcc..1a5e6666b32 100644
--- a/intern/cycles/util/util_logging.h
+++ b/intern/cycles/util/util_logging.h
@@ -28,25 +28,31 @@ CCL_NAMESPACE_BEGIN
#if !defined(WITH_CYCLES_LOGGING) || defined(__KERNEL_GPU__)
class StubStream {
-public:
- template<class T>
- StubStream& operator<<(const T&) {
- return *this;
- }
+ public:
+ template<class T> StubStream &operator<<(const T &)
+ {
+ return *this;
+ }
};
class LogMessageVoidify {
-public:
- LogMessageVoidify() { }
- void operator&(StubStream&) { }
+ public:
+ LogMessageVoidify()
+ {
+ }
+ void operator&(StubStream &)
+ {
+ }
};
-# define LOG_SUPPRESS() (true) ? ((void) 0) : LogMessageVoidify() & StubStream()
+# define LOG_SUPPRESS() (true) ? ((void)0) : LogMessageVoidify() & StubStream()
# define LOG(severity) LOG_SUPPRESS()
# define VLOG(severity) LOG_SUPPRESS()
#endif
-#define VLOG_ONCE(level, flag) if(!flag) flag = true, VLOG(level)
+#define VLOG_ONCE(level, flag) \
+ if (!flag) \
+ flag = true, VLOG(level)
struct int2;
struct float3;
@@ -55,11 +61,9 @@ void util_logging_init(const char *argv0);
void util_logging_start();
void util_logging_verbosity_set(int verbosity);
-std::ostream& operator <<(std::ostream &os,
- const int2 &value);
-std::ostream& operator <<(std::ostream &os,
- const float3 &value);
+std::ostream &operator<<(std::ostream &os, const int2 &value);
+std::ostream &operator<<(std::ostream &os, const float3 &value);
CCL_NAMESPACE_END
-#endif /* __UTIL_LOGGING_H__ */
+#endif /* __UTIL_LOGGING_H__ */
diff --git a/intern/cycles/util/util_map.h b/intern/cycles/util/util_map.h
index 1952d33ada8..3c9288417cf 100644
--- a/intern/cycles/util/util_map.h
+++ b/intern/cycles/util/util_map.h
@@ -28,4 +28,4 @@ using std::unordered_map;
CCL_NAMESPACE_END
-#endif /* __UTIL_MAP_H__ */
+#endif /* __UTIL_MAP_H__ */
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 6167119f873..2c7f826db93 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -26,12 +26,11 @@
# include <cmath>
#endif
-
#ifndef __KERNEL_OPENCL__
# include <float.h>
# include <math.h>
# include <stdio.h>
-#endif /* __KERNEL_OPENCL__ */
+#endif /* __KERNEL_OPENCL__ */
#include "util/util_types.h"
@@ -41,22 +40,22 @@ CCL_NAMESPACE_BEGIN
/* Division */
#ifndef M_PI_F
-# define M_PI_F (3.1415926535897932f) /* pi */
+# define M_PI_F (3.1415926535897932f) /* pi */
#endif
#ifndef M_PI_2_F
-# define M_PI_2_F (1.5707963267948966f) /* pi/2 */
+# define M_PI_2_F (1.5707963267948966f) /* pi/2 */
#endif
#ifndef M_PI_4_F
-# define M_PI_4_F (0.7853981633974830f) /* pi/4 */
+# define M_PI_4_F (0.7853981633974830f) /* pi/4 */
#endif
#ifndef M_1_PI_F
-# define M_1_PI_F (0.3183098861837067f) /* 1/pi */
+# define M_1_PI_F (0.3183098861837067f) /* 1/pi */
#endif
#ifndef M_2_PI_F
-# define M_2_PI_F (0.6366197723675813f) /* 2/pi */
+# define M_2_PI_F (0.6366197723675813f) /* 2/pi */
#endif
#ifndef M_1_2PI_F
-# define M_1_2PI_F (0.1591549430918953f) /* 1/(2*pi) */
+# define M_1_2PI_F (0.1591549430918953f) /* 1/(2*pi) */
#endif
#ifndef M_SQRT_PI_8_F
# define M_SQRT_PI_8_F (0.6266570686577501f) /* sqrt(pi/8) */
@@ -67,21 +66,21 @@ CCL_NAMESPACE_BEGIN
/* Multiplication */
#ifndef M_2PI_F
-# define M_2PI_F (6.2831853071795864f) /* 2*pi */
+# define M_2PI_F (6.2831853071795864f) /* 2*pi */
#endif
#ifndef M_4PI_F
-# define M_4PI_F (12.566370614359172f) /* 4*pi */
+# define M_4PI_F (12.566370614359172f) /* 4*pi */
#endif
/* Float sqrt variations */
#ifndef M_SQRT2_F
-# define M_SQRT2_F (1.4142135623730950f) /* sqrt(2) */
+# define M_SQRT2_F (1.4142135623730950f) /* sqrt(2) */
#endif
#ifndef M_LN2_F
-# define M_LN2_F (0.6931471805599453f) /* ln(2) */
+# define M_LN2_F (0.6931471805599453f) /* ln(2) */
#endif
#ifndef M_LN10_F
-# define M_LN10_F (2.3025850929940457f) /* ln(10) */
+# define M_LN10_F (2.3025850929940457f) /* ln(10) */
#endif
/* Scalar */
@@ -90,15 +89,15 @@ CCL_NAMESPACE_BEGIN
# ifndef __KERNEL_OPENCL__
ccl_device_inline float fmaxf(float a, float b)
{
- return (a > b)? a: b;
+ return (a > b) ? a : b;
}
ccl_device_inline float fminf(float a, float b)
{
- return (a < b)? a: b;
+ return (a < b) ? a : b;
}
-# endif /* !__KERNEL_OPENCL__ */
-#endif /* _WIN32 */
+# endif /* !__KERNEL_OPENCL__ */
+#endif /* _WIN32 */
#ifndef __KERNEL_GPU__
using std::isfinite;
@@ -107,37 +106,37 @@ using std::sqrt;
ccl_device_inline int abs(int x)
{
- return (x > 0)? x: -x;
+ return (x > 0) ? x : -x;
}
ccl_device_inline int max(int a, int b)
{
- return (a > b)? a: b;
+ return (a > b) ? a : b;
}
ccl_device_inline int min(int a, int b)
{
- return (a < b)? a: b;
+ return (a < b) ? a : b;
}
ccl_device_inline float max(float a, float b)
{
- return (a > b)? a: b;
+ return (a > b) ? a : b;
}
ccl_device_inline float min(float a, float b)
{
- return (a < b)? a: b;
+ return (a < b) ? a : b;
}
ccl_device_inline double max(double a, double b)
{
- return (a > b)? a: b;
+ return (a > b) ? a : b;
}
ccl_device_inline double min(double a, double b)
{
- return (a < b)? a: b;
+ return (a < b) ? a : b;
}
/* These 2 guys are templated for usage with registers data.
@@ -146,27 +145,25 @@ ccl_device_inline double min(double a, double b)
* But for other devices we'll need to be careful about this.
*/
-template<typename T>
-ccl_device_inline T min4(const T& a, const T& b, const T& c, const T& d)
+template<typename T> ccl_device_inline T min4(const T &a, const T &b, const T &c, const T &d)
{
- return min(min(a,b),min(c,d));
+ return min(min(a, b), min(c, d));
}
-template<typename T>
-ccl_device_inline T max4(const T& a, const T& b, const T& c, const T& d)
+template<typename T> ccl_device_inline T max4(const T &a, const T &b, const T &c, const T &d)
{
- return max(max(a,b),max(c,d));
+ return max(max(a, b), max(c, d));
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
ccl_device_inline float min4(float a, float b, float c, float d)
{
- return min(min(a, b), min(c, d));
+ return min(min(a, b), min(c, d));
}
ccl_device_inline float max4(float a, float b, float c, float d)
{
- return max(max(a, b), max(c, d));
+ return max(max(a, b), max(c, d));
}
#ifndef __KERNEL_OPENCL__
@@ -174,189 +171,210 @@ ccl_device_inline float max4(float a, float b, float c, float d)
ccl_device_inline int as_int(uint i)
{
- union { uint ui; int i; } u;
- u.ui = i;
- return u.i;
+ union {
+ uint ui;
+ int i;
+ } u;
+ u.ui = i;
+ return u.i;
}
ccl_device_inline uint as_uint(int i)
{
- union { uint ui; int i; } u;
- u.i = i;
- return u.ui;
+ union {
+ uint ui;
+ int i;
+ } u;
+ u.i = i;
+ return u.ui;
}
ccl_device_inline uint as_uint(float f)
{
- union { uint i; float f; } u;
- u.f = f;
- return u.i;
+ union {
+ uint i;
+ float f;
+ } u;
+ u.f = f;
+ return u.i;
}
ccl_device_inline int __float_as_int(float f)
{
- union { int i; float f; } u;
- u.f = f;
- return u.i;
+ union {
+ int i;
+ float f;
+ } u;
+ u.f = f;
+ return u.i;
}
ccl_device_inline float __int_as_float(int i)
{
- union { int i; float f; } u;
- u.i = i;
- return u.f;
+ union {
+ int i;
+ float f;
+ } u;
+ u.i = i;
+ return u.f;
}
ccl_device_inline uint __float_as_uint(float f)
{
- union { uint i; float f; } u;
- u.f = f;
- return u.i;
+ union {
+ uint i;
+ float f;
+ } u;
+ u.f = f;
+ return u.i;
}
ccl_device_inline float __uint_as_float(uint i)
{
- union { uint i; float f; } u;
- u.i = i;
- return u.f;
+ union {
+ uint i;
+ float f;
+ } u;
+ u.i = i;
+ return u.f;
}
ccl_device_inline int4 __float4_as_int4(float4 f)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_castps_si128(f.m128));
- #else
- return make_int4(__float_as_int(f.x),
- __float_as_int(f.y),
- __float_as_int(f.z),
- __float_as_int(f.w));
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_castps_si128(f.m128));
+# else
+ return make_int4(
+ __float_as_int(f.x), __float_as_int(f.y), __float_as_int(f.z), __float_as_int(f.w));
+# endif
}
ccl_device_inline float4 __int4_as_float4(int4 i)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_castsi128_ps(i.m128));
-#else
- return make_float4(__int_as_float(i.x),
- __int_as_float(i.y),
- __int_as_float(i.z),
- __int_as_float(i.w));
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_castsi128_ps(i.m128));
+# else
+ return make_float4(
+ __int_as_float(i.x), __int_as_float(i.y), __int_as_float(i.z), __int_as_float(i.w));
+# endif
}
-#endif /* __KERNEL_OPENCL__ */
+#endif /* __KERNEL_OPENCL__ */
/* Versions of functions which are safe for fast math. */
ccl_device_inline bool isnan_safe(float f)
{
- unsigned int x = __float_as_uint(f);
- return (x << 1) > 0xff000000u;
+ unsigned int x = __float_as_uint(f);
+ return (x << 1) > 0xff000000u;
}
ccl_device_inline bool isfinite_safe(float f)
{
- /* By IEEE 754 rule, 2*Inf equals Inf */
- unsigned int x = __float_as_uint(f);
- return (f == f) && (x == 0 || x == (1u << 31) || (f != 2.0f*f)) && !((x << 1) > 0xff000000u);
+ /* By IEEE 754 rule, 2*Inf equals Inf */
+ unsigned int x = __float_as_uint(f);
+ return (f == f) && (x == 0 || x == (1u << 31) || (f != 2.0f * f)) && !((x << 1) > 0xff000000u);
}
ccl_device_inline float ensure_finite(float v)
{
- return isfinite_safe(v)? v : 0.0f;
+ return isfinite_safe(v) ? v : 0.0f;
}
#ifndef __KERNEL_OPENCL__
ccl_device_inline int clamp(int a, int mn, int mx)
{
- return min(max(a, mn), mx);
+ return min(max(a, mn), mx);
}
ccl_device_inline float clamp(float a, float mn, float mx)
{
- return min(max(a, mn), mx);
+ return min(max(a, mn), mx);
}
ccl_device_inline float mix(float a, float b, float t)
{
- return a + t*(b - a);
+ return a + t * (b - a);
}
-#endif /* __KERNEL_OPENCL__ */
+#endif /* __KERNEL_OPENCL__ */
#ifndef __KERNEL_CUDA__
ccl_device_inline float saturate(float a)
{
- return clamp(a, 0.0f, 1.0f);
+ return clamp(a, 0.0f, 1.0f);
}
-#endif /* __KERNEL_CUDA__ */
+#endif /* __KERNEL_CUDA__ */
ccl_device_inline int float_to_int(float f)
{
- return (int)f;
+ return (int)f;
}
ccl_device_inline int floor_to_int(float f)
{
- return float_to_int(floorf(f));
+ return float_to_int(floorf(f));
}
ccl_device_inline int quick_floor_to_int(float x)
{
- return float_to_int(x) - ((x < 0) ? 1 : 0);
+ return float_to_int(x) - ((x < 0) ? 1 : 0);
}
ccl_device_inline int ceil_to_int(float f)
{
- return float_to_int(ceilf(f));
+ return float_to_int(ceilf(f));
}
ccl_device_inline float signf(float f)
{
- return (f < 0.0f)? -1.0f: 1.0f;
+ return (f < 0.0f) ? -1.0f : 1.0f;
}
ccl_device_inline float nonzerof(float f, float eps)
{
- if(fabsf(f) < eps)
- return signf(f)*eps;
- else
- return f;
+ if (fabsf(f) < eps)
+ return signf(f) * eps;
+ else
+ return f;
}
ccl_device_inline float smoothstepf(float f)
{
- float ff = f*f;
- return (3.0f*ff - 2.0f*ff*f);
+ float ff = f * f;
+ return (3.0f * ff - 2.0f * ff * f);
}
ccl_device_inline int mod(int x, int m)
{
- return (x % m + m) % m;
+ return (x % m + m) % m;
}
ccl_device_inline float3 float2_to_float3(const float2 a)
{
- return make_float3(a.x, a.y, 0.0f);
+ return make_float3(a.x, a.y, 0.0f);
}
ccl_device_inline float3 float4_to_float3(const float4 a)
{
- return make_float3(a.x, a.y, a.z);
+ return make_float3(a.x, a.y, a.z);
}
ccl_device_inline float4 float3_to_float4(const float3 a)
{
- return make_float4(a.x, a.y, a.z, 1.0f);
+ return make_float4(a.x, a.y, a.z, 1.0f);
}
ccl_device_inline float inverse_lerp(float a, float b, float x)
{
- return (x - a) / (b - a);
+ return (x - a) / (b - a);
}
/* Cubic interpolation between b and c, a and d are the previous and next point. */
ccl_device_inline float cubic_interp(float a, float b, float c, float d, float x)
{
- return 0.5f*(((d + 3.0f*(b-c) - a)*x + (2.0f*a - 5.0f*b + 4.0f*c - d))*x + (c - a))*x + b;
+ return 0.5f *
+ (((d + 3.0f * (b - c) - a) * x + (2.0f * a - 5.0f * b + 4.0f * c - d)) * x +
+ (c - a)) *
+ x +
+ b;
}
CCL_NAMESPACE_END
@@ -376,26 +394,22 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_OPENCL__
/* Interpolation */
-template<class A, class B> A lerp(const A& a, const A& b, const B& t)
+template<class A, class B> A lerp(const A &a, const A &b, const B &t)
{
- return (A)(a * ((B)1 - t) + b * t);
+ return (A)(a * ((B)1 - t) + b * t);
}
-#endif /* __KERNEL_OPENCL__ */
+#endif /* __KERNEL_OPENCL__ */
/* Triangle */
#ifndef __KERNEL_OPENCL__
-ccl_device_inline float triangle_area(const float3& v1,
- const float3& v2,
- const float3& v3)
+ccl_device_inline float triangle_area(const float3 &v1, const float3 &v2, const float3 &v3)
#else
-ccl_device_inline float triangle_area(const float3 v1,
- const float3 v2,
- const float3 v3)
+ccl_device_inline float triangle_area(const float3 v1, const float3 v2, const float3 v3)
#endif
{
- return len(cross(v3 - v2, v1 - v2))*0.5f;
+ return len(cross(v3 - v2, v1 - v2)) * 0.5f;
}
/* Orthonormal vectors */
@@ -403,240 +417,240 @@ ccl_device_inline float triangle_area(const float3 v1,
ccl_device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b)
{
#if 0
- if(fabsf(N.y) >= 0.999f) {
- *a = make_float3(1, 0, 0);
- *b = make_float3(0, 0, 1);
- return;
- }
- if(fabsf(N.z) >= 0.999f) {
- *a = make_float3(1, 0, 0);
- *b = make_float3(0, 1, 0);
- return;
- }
+ if(fabsf(N.y) >= 0.999f) {
+ *a = make_float3(1, 0, 0);
+ *b = make_float3(0, 0, 1);
+ return;
+ }
+ if(fabsf(N.z) >= 0.999f) {
+ *a = make_float3(1, 0, 0);
+ *b = make_float3(0, 1, 0);
+ return;
+ }
#endif
- if(N.x != N.y || N.x != N.z)
- *a = make_float3(N.z-N.y, N.x-N.z, N.y-N.x); //(1,1,1)x N
- else
- *a = make_float3(N.z-N.y, N.x+N.z, -N.y-N.x); //(-1,1,1)x N
+ if (N.x != N.y || N.x != N.z)
+ *a = make_float3(N.z - N.y, N.x - N.z, N.y - N.x); //(1,1,1)x N
+ else
+ *a = make_float3(N.z - N.y, N.x + N.z, -N.y - N.x); //(-1,1,1)x N
- *a = normalize(*a);
- *b = cross(N, *a);
+ *a = normalize(*a);
+ *b = cross(N, *a);
}
/* Color division */
ccl_device_inline float3 safe_invert_color(float3 a)
{
- float x, y, z;
+ float x, y, z;
- x = (a.x != 0.0f)? 1.0f/a.x: 0.0f;
- y = (a.y != 0.0f)? 1.0f/a.y: 0.0f;
- z = (a.z != 0.0f)? 1.0f/a.z: 0.0f;
+ x = (a.x != 0.0f) ? 1.0f / a.x : 0.0f;
+ y = (a.y != 0.0f) ? 1.0f / a.y : 0.0f;
+ z = (a.z != 0.0f) ? 1.0f / a.z : 0.0f;
- return make_float3(x, y, z);
+ return make_float3(x, y, z);
}
ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
{
- float x, y, z;
+ float x, y, z;
- x = (b.x != 0.0f)? a.x/b.x: 0.0f;
- y = (b.y != 0.0f)? a.y/b.y: 0.0f;
- z = (b.z != 0.0f)? a.z/b.z: 0.0f;
+ x = (b.x != 0.0f) ? a.x / b.x : 0.0f;
+ y = (b.y != 0.0f) ? a.y / b.y : 0.0f;
+ z = (b.z != 0.0f) ? a.z / b.z : 0.0f;
- return make_float3(x, y, z);
+ return make_float3(x, y, z);
}
ccl_device_inline float3 safe_divide_even_color(float3 a, float3 b)
{
- float x, y, z;
-
- x = (b.x != 0.0f)? a.x/b.x: 0.0f;
- y = (b.y != 0.0f)? a.y/b.y: 0.0f;
- z = (b.z != 0.0f)? a.z/b.z: 0.0f;
-
- /* try to get gray even if b is zero */
- if(b.x == 0.0f) {
- if(b.y == 0.0f) {
- x = z;
- y = z;
- }
- else if(b.z == 0.0f) {
- x = y;
- z = y;
- }
- else
- x = 0.5f*(y + z);
- }
- else if(b.y == 0.0f) {
- if(b.z == 0.0f) {
- y = x;
- z = x;
- }
- else
- y = 0.5f*(x + z);
- }
- else if(b.z == 0.0f) {
- z = 0.5f*(x + y);
- }
-
- return make_float3(x, y, z);
+ float x, y, z;
+
+ x = (b.x != 0.0f) ? a.x / b.x : 0.0f;
+ y = (b.y != 0.0f) ? a.y / b.y : 0.0f;
+ z = (b.z != 0.0f) ? a.z / b.z : 0.0f;
+
+ /* try to get gray even if b is zero */
+ if (b.x == 0.0f) {
+ if (b.y == 0.0f) {
+ x = z;
+ y = z;
+ }
+ else if (b.z == 0.0f) {
+ x = y;
+ z = y;
+ }
+ else
+ x = 0.5f * (y + z);
+ }
+ else if (b.y == 0.0f) {
+ if (b.z == 0.0f) {
+ y = x;
+ z = x;
+ }
+ else
+ y = 0.5f * (x + z);
+ }
+ else if (b.z == 0.0f) {
+ z = 0.5f * (x + y);
+ }
+
+ return make_float3(x, y, z);
}
/* Rotation of point around axis and angle */
ccl_device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
{
- float costheta = cosf(angle);
- float sintheta = sinf(angle);
- float3 r;
+ float costheta = cosf(angle);
+ float sintheta = sinf(angle);
+ float3 r;
- r.x = ((costheta + (1 - costheta) * axis.x * axis.x) * p.x) +
- (((1 - costheta) * axis.x * axis.y - axis.z * sintheta) * p.y) +
- (((1 - costheta) * axis.x * axis.z + axis.y * sintheta) * p.z);
+ r.x = ((costheta + (1 - costheta) * axis.x * axis.x) * p.x) +
+ (((1 - costheta) * axis.x * axis.y - axis.z * sintheta) * p.y) +
+ (((1 - costheta) * axis.x * axis.z + axis.y * sintheta) * p.z);
- r.y = (((1 - costheta) * axis.x * axis.y + axis.z * sintheta) * p.x) +
- ((costheta + (1 - costheta) * axis.y * axis.y) * p.y) +
- (((1 - costheta) * axis.y * axis.z - axis.x * sintheta) * p.z);
+ r.y = (((1 - costheta) * axis.x * axis.y + axis.z * sintheta) * p.x) +
+ ((costheta + (1 - costheta) * axis.y * axis.y) * p.y) +
+ (((1 - costheta) * axis.y * axis.z - axis.x * sintheta) * p.z);
- r.z = (((1 - costheta) * axis.x * axis.z - axis.y * sintheta) * p.x) +
- (((1 - costheta) * axis.y * axis.z + axis.x * sintheta) * p.y) +
- ((costheta + (1 - costheta) * axis.z * axis.z) * p.z);
+ r.z = (((1 - costheta) * axis.x * axis.z - axis.y * sintheta) * p.x) +
+ (((1 - costheta) * axis.y * axis.z + axis.x * sintheta) * p.y) +
+ ((costheta + (1 - costheta) * axis.z * axis.z) * p.z);
- return r;
+ return r;
}
/* NaN-safe math ops */
ccl_device_inline float safe_sqrtf(float f)
{
- return sqrtf(max(f, 0.0f));
+ return sqrtf(max(f, 0.0f));
}
ccl_device float safe_asinf(float a)
{
- return asinf(clamp(a, -1.0f, 1.0f));
+ return asinf(clamp(a, -1.0f, 1.0f));
}
ccl_device float safe_acosf(float a)
{
- return acosf(clamp(a, -1.0f, 1.0f));
+ return acosf(clamp(a, -1.0f, 1.0f));
}
ccl_device float compatible_powf(float x, float y)
{
#ifdef __KERNEL_GPU__
- if(y == 0.0f) /* x^0 -> 1, including 0^0 */
- return 1.0f;
-
- /* GPU pow doesn't accept negative x, do manual checks here */
- if(x < 0.0f) {
- if(fmodf(-y, 2.0f) == 0.0f)
- return powf(-x, y);
- else
- return -powf(-x, y);
- }
- else if(x == 0.0f)
- return 0.0f;
+ if (y == 0.0f) /* x^0 -> 1, including 0^0 */
+ return 1.0f;
+
+ /* GPU pow doesn't accept negative x, do manual checks here */
+ if (x < 0.0f) {
+ if (fmodf(-y, 2.0f) == 0.0f)
+ return powf(-x, y);
+ else
+ return -powf(-x, y);
+ }
+ else if (x == 0.0f)
+ return 0.0f;
#endif
- return powf(x, y);
+ return powf(x, y);
}
ccl_device float safe_powf(float a, float b)
{
- if(UNLIKELY(a < 0.0f && b != float_to_int(b)))
- return 0.0f;
+ if (UNLIKELY(a < 0.0f && b != float_to_int(b)))
+ return 0.0f;
- return compatible_powf(a, b);
+ return compatible_powf(a, b);
}
ccl_device float safe_divide(float a, float b)
{
- return (b != 0.0f)? a/b: 0.0f;
+ return (b != 0.0f) ? a / b : 0.0f;
}
ccl_device float safe_logf(float a, float b)
{
- if(UNLIKELY(a <= 0.0f || b <= 0.0f))
- return 0.0f;
+ if (UNLIKELY(a <= 0.0f || b <= 0.0f))
+ return 0.0f;
- return safe_divide(logf(a),logf(b));
+ return safe_divide(logf(a), logf(b));
}
ccl_device float safe_modulo(float a, float b)
{
- return (b != 0.0f)? fmodf(a, b): 0.0f;
+ return (b != 0.0f) ? fmodf(a, b) : 0.0f;
}
ccl_device_inline float sqr(float a)
{
- return a * a;
+ return a * a;
}
ccl_device_inline float pow20(float a)
{
- return sqr(sqr(sqr(sqr(a))*a));
+ return sqr(sqr(sqr(sqr(a)) * a));
}
ccl_device_inline float pow22(float a)
{
- return sqr(a*sqr(sqr(sqr(a))*a));
+ return sqr(a * sqr(sqr(sqr(a)) * a));
}
ccl_device_inline float beta(float x, float y)
{
#ifndef __KERNEL_OPENCL__
- return expf(lgammaf(x) + lgammaf(y) - lgammaf(x+y));
+ return expf(lgammaf(x) + lgammaf(y) - lgammaf(x + y));
#else
- return expf(lgamma(x) + lgamma(y) - lgamma(x+y));
+ return expf(lgamma(x) + lgamma(y) - lgamma(x + y));
#endif
}
ccl_device_inline float xor_signmask(float x, int y)
{
- return __int_as_float(__float_as_int(x) ^ y);
+ return __int_as_float(__float_as_int(x) ^ y);
}
ccl_device float bits_to_01(uint bits)
{
- return bits * (1.0f/(float)0xFFFFFFFF);
+ return bits * (1.0f / (float)0xFFFFFFFF);
}
/* projections */
ccl_device_inline float2 map_to_tube(const float3 co)
{
- float len, u, v;
- len = sqrtf(co.x * co.x + co.y * co.y);
- if(len > 0.0f) {
- u = (1.0f - (atan2f(co.x / len, co.y / len) / M_PI_F)) * 0.5f;
- v = (co.z + 1.0f) * 0.5f;
- }
- else {
- u = v = 0.0f;
- }
- return make_float2(u, v);
+ float len, u, v;
+ len = sqrtf(co.x * co.x + co.y * co.y);
+ if (len > 0.0f) {
+ u = (1.0f - (atan2f(co.x / len, co.y / len) / M_PI_F)) * 0.5f;
+ v = (co.z + 1.0f) * 0.5f;
+ }
+ else {
+ u = v = 0.0f;
+ }
+ return make_float2(u, v);
}
ccl_device_inline float2 map_to_sphere(const float3 co)
{
- float l = len(co);
- float u, v;
- if(l > 0.0f) {
- if(UNLIKELY(co.x == 0.0f && co.y == 0.0f)) {
- u = 0.0f; /* othwise domain error */
- }
- else {
- u = (1.0f - atan2f(co.x, co.y) / M_PI_F) / 2.0f;
- }
- v = 1.0f - safe_acosf(co.z / l) / M_PI_F;
- }
- else {
- u = v = 0.0f;
- }
- return make_float2(u, v);
+ float l = len(co);
+ float u, v;
+ if (l > 0.0f) {
+ if (UNLIKELY(co.x == 0.0f && co.y == 0.0f)) {
+ u = 0.0f; /* othwise domain error */
+ }
+ else {
+ u = (1.0f - atan2f(co.x, co.y) / M_PI_F) / 2.0f;
+ }
+ v = 1.0f - safe_acosf(co.z / l) / M_PI_F;
+ }
+ else {
+ u = v = 0.0f;
+ }
+ return make_float2(u, v);
}
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_H__ */
+#endif /* __UTIL_MATH_H__ */
diff --git a/intern/cycles/util/util_math_cdf.cpp b/intern/cycles/util/util_math_cdf.cpp
index c14d4793ea1..a58bab188ef 100644
--- a/intern/cycles/util/util_math_cdf.cpp
+++ b/intern/cycles/util/util_math_cdf.cpp
@@ -27,41 +27,44 @@ void util_cdf_invert(const int resolution,
const float to,
const vector<float> &cdf,
const bool make_symmetric,
- vector<float> &inv_cdf) {
- const float inv_resolution = 1.0f / (float)resolution;
- const float range = to - from;
- inv_cdf.resize(resolution);
- if(make_symmetric) {
- const int half_size = (resolution - 1) / 2;
- for(int i = 0; i <= half_size; i++) {
- float x = i / (float)half_size;
- int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
- float t;
- if(index < cdf.size() - 1) {
- t = (x - cdf[index])/(cdf[index+1] - cdf[index]);
- } else {
- t = 0.0f;
- index = cdf.size() - 1;
- }
- float y = ((index + t) / (resolution - 1)) * (2.0f * range);
- inv_cdf[half_size+i] = 0.5f*(1.0f + y);
- inv_cdf[half_size-i] = 0.5f*(1.0f - y);
- }
- }
- else {
- for(int i = 0; i < resolution; i++) {
- float x = from + range * (float)i * inv_resolution;
- int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
- float t;
- if(index < cdf.size() - 1) {
- t = (x - cdf[index])/(cdf[index+1] - cdf[index]);
- } else {
- t = 0.0f;
- index = resolution;
- }
- inv_cdf[i] = (index + t) * inv_resolution;
- }
- }
+ vector<float> &inv_cdf)
+{
+ const float inv_resolution = 1.0f / (float)resolution;
+ const float range = to - from;
+ inv_cdf.resize(resolution);
+ if (make_symmetric) {
+ const int half_size = (resolution - 1) / 2;
+ for (int i = 0; i <= half_size; i++) {
+ float x = i / (float)half_size;
+ int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
+ float t;
+ if (index < cdf.size() - 1) {
+ t = (x - cdf[index]) / (cdf[index + 1] - cdf[index]);
+ }
+ else {
+ t = 0.0f;
+ index = cdf.size() - 1;
+ }
+ float y = ((index + t) / (resolution - 1)) * (2.0f * range);
+ inv_cdf[half_size + i] = 0.5f * (1.0f + y);
+ inv_cdf[half_size - i] = 0.5f * (1.0f - y);
+ }
+ }
+ else {
+ for (int i = 0; i < resolution; i++) {
+ float x = from + range * (float)i * inv_resolution;
+ int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
+ float t;
+ if (index < cdf.size() - 1) {
+ t = (x - cdf[index]) / (cdf[index + 1] - cdf[index]);
+ }
+ else {
+ t = 0.0f;
+ index = resolution;
+ }
+ inv_cdf[i] = (index + t) * inv_resolution;
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_math_cdf.h b/intern/cycles/util/util_math_cdf.h
index 983855e3e9b..43995204263 100644
--- a/intern/cycles/util/util_math_cdf.h
+++ b/intern/cycles/util/util_math_cdf.h
@@ -24,27 +24,24 @@
CCL_NAMESPACE_BEGIN
/* Evaluate CDF of a given functor with given range and resolution. */
-template <typename Functor>
-void util_cdf_evaluate(const int resolution,
- const float from,
- const float to,
- Functor functor,
- vector<float> &cdf)
+template<typename Functor>
+void util_cdf_evaluate(
+ const int resolution, const float from, const float to, Functor functor, vector<float> &cdf)
{
- const int cdf_count = resolution + 1;
- const float range = to - from;
- cdf.resize(cdf_count);
- cdf[0] = 0.0f;
- /* Actual CDF evaluation. */
- for(int i = 0; i < resolution; ++i) {
- float x = from + range * (float)i / (resolution - 1);
- float y = functor(x);
- cdf[i + 1] = cdf[i] + fabsf(y);
- }
- /* Normalize the CDF. */
- for(int i = 0; i <= resolution; i++) {
- cdf[i] /= cdf[resolution];
- }
+ const int cdf_count = resolution + 1;
+ const float range = to - from;
+ cdf.resize(cdf_count);
+ cdf[0] = 0.0f;
+ /* Actual CDF evaluation. */
+ for (int i = 0; i < resolution; ++i) {
+ float x = from + range * (float)i / (resolution - 1);
+ float y = functor(x);
+ cdf[i + 1] = cdf[i] + fabsf(y);
+ }
+ /* Normalize the CDF. */
+ for (int i = 0; i <= resolution; i++) {
+ cdf[i] /= cdf[resolution];
+ }
}
/* Invert pre-calculated CDF function. */
@@ -56,7 +53,7 @@ void util_cdf_invert(const int resolution,
vector<float> &inv_cdf);
/* Evaluate inverted CDF of a given functor with given range and resolution. */
-template <typename Functor>
+template<typename Functor>
void util_cdf_inverted(const int resolution,
const float from,
const float to,
@@ -64,15 +61,15 @@ void util_cdf_inverted(const int resolution,
const bool make_symmetric,
vector<float> &inv_cdf)
{
- vector<float> cdf;
- /* There is no much smartness going around lower resolution for the CDF table,
- * this just to match the old code from pixel filter so it all stays exactly
- * the same and no regression tests are failed.
- */
- util_cdf_evaluate(resolution - 1, from, to, functor, cdf);
- util_cdf_invert(resolution, from, to, cdf, make_symmetric, inv_cdf);
+ vector<float> cdf;
+ /* There is no much smartness going around lower resolution for the CDF table,
+ * this just to match the old code from pixel filter so it all stays exactly
+ * the same and no regression tests are failed.
+ */
+ util_cdf_evaluate(resolution - 1, from, to, functor, cdf);
+ util_cdf_invert(resolution, from, to, cdf, make_symmetric, inv_cdf);
}
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_H_CDF__ */
+#endif /* __UTIL_MATH_H_CDF__ */
diff --git a/intern/cycles/util/util_math_fast.h b/intern/cycles/util/util_math_fast.h
index fe4e02197a4..872271666aa 100644
--- a/intern/cycles/util/util_math_fast.h
+++ b/intern/cycles/util/util_math_fast.h
@@ -49,18 +49,18 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline float madd(const float a, const float b, const float c)
{
- /* NOTE: In the future we may want to explicitly ask for a fused
- * multiply-add in a specialized version for float.
- *
- * NOTE: GCC/ICC will turn this (for float) into a FMA unless
- * explicitly asked not to, clang seems to leave the code alone.
- */
- return a * b + c;
+ /* NOTE: In the future we may want to explicitly ask for a fused
+ * multiply-add in a specialized version for float.
+ *
+ * NOTE: GCC/ICC will turn this (for float) into a FMA unless
+ * explicitly asked not to, clang seems to leave the code alone.
+ */
+ return a * b + c;
}
ccl_device_inline float4 madd4(const float4 a, const float4 b, const float4 c)
{
- return a * b + c;
+ return a * b + c;
}
/*
@@ -82,116 +82,117 @@ ccl_device_inline float4 madd4(const float4 a, const float4 b, const float4 c)
/* Round to nearest integer, returning as an int. */
ccl_device_inline int fast_rint(float x)
{
- /* used by sin/cos/tan range reduction. */
+ /* used by sin/cos/tan range reduction. */
#ifdef __KERNEL_SSE4__
- /* Single roundps instruction on SSE4.1+ (for gcc/clang at least). */
- return float_to_int(rintf(x));
+ /* Single roundps instruction on SSE4.1+ (for gcc/clang at least). */
+ return float_to_int(rintf(x));
#else
- /* emulate rounding by adding/substracting 0.5. */
- return float_to_int(x + copysignf(0.5f, x));
+ /* emulate rounding by adding/substracting 0.5. */
+ return float_to_int(x + copysignf(0.5f, x));
#endif
}
ccl_device float fast_sinf(float x)
{
- /* Very accurate argument reduction from SLEEF,
- * starts failing around x=262000
- *
- * Results on: [-2pi,2pi].
- *
- * Examined 2173837240 values of sin: 0.00662760244 avg ulp diff, 2 max ulp,
- * 1.19209e-07 max error
- */
- int q = fast_rint(x * M_1_PI_F);
- float qf = q;
- x = madd(qf, -0.78515625f*4, x);
- x = madd(qf, -0.00024187564849853515625f*4, x);
- x = madd(qf, -3.7747668102383613586e-08f*4, x);
- x = madd(qf, -1.2816720341285448015e-12f*4, x);
- x = M_PI_2_F - (M_PI_2_F - x); /* Crush denormals */
- float s = x * x;
- if((q & 1) != 0) x = -x;
- /* This polynomial approximation has very low error on [-pi/2,+pi/2]
- * 1.19209e-07 max error in total over [-2pi,+2pi]. */
- float u = 2.6083159809786593541503e-06f;
- u = madd(u, s, -0.0001981069071916863322258f);
- u = madd(u, s, +0.00833307858556509017944336f);
- u = madd(u, s, -0.166666597127914428710938f);
- u = madd(s, u * x, x);
- /* For large x, the argument reduction can fail and the polynomial can be
- * evaluated with arguments outside the valid internal. Just clamp the bad
- * values away (setting to 0.0f means no branches need to be generated). */
- if(fabsf(u) > 1.0f) {
- u = 0.0f;
- }
- return u;
+ /* Very accurate argument reduction from SLEEF,
+ * starts failing around x=262000
+ *
+ * Results on: [-2pi,2pi].
+ *
+ * Examined 2173837240 values of sin: 0.00662760244 avg ulp diff, 2 max ulp,
+ * 1.19209e-07 max error
+ */
+ int q = fast_rint(x * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f * 4, x);
+ x = madd(qf, -0.00024187564849853515625f * 4, x);
+ x = madd(qf, -3.7747668102383613586e-08f * 4, x);
+ x = madd(qf, -1.2816720341285448015e-12f * 4, x);
+ x = M_PI_2_F - (M_PI_2_F - x); /* Crush denormals */
+ float s = x * x;
+ if ((q & 1) != 0)
+ x = -x;
+ /* This polynomial approximation has very low error on [-pi/2,+pi/2]
+ * 1.19209e-07 max error in total over [-2pi,+2pi]. */
+ float u = 2.6083159809786593541503e-06f;
+ u = madd(u, s, -0.0001981069071916863322258f);
+ u = madd(u, s, +0.00833307858556509017944336f);
+ u = madd(u, s, -0.166666597127914428710938f);
+ u = madd(s, u * x, x);
+ /* For large x, the argument reduction can fail and the polynomial can be
+ * evaluated with arguments outside the valid internal. Just clamp the bad
+ * values away (setting to 0.0f means no branches need to be generated). */
+ if (fabsf(u) > 1.0f) {
+ u = 0.0f;
+ }
+ return u;
}
ccl_device float fast_cosf(float x)
{
- /* Same argument reduction as fast_sinf(). */
- int q = fast_rint(x * M_1_PI_F);
- float qf = q;
- x = madd(qf, -0.78515625f*4, x);
- x = madd(qf, -0.00024187564849853515625f*4, x);
- x = madd(qf, -3.7747668102383613586e-08f*4, x);
- x = madd(qf, -1.2816720341285448015e-12f*4, x);
- x = M_PI_2_F - (M_PI_2_F - x); /* Crush denormals. */
- float s = x * x;
- /* Polynomial from SLEEF's sincosf, max error is
- * 4.33127e-07 over [-2pi,2pi] (98% of values are "exact"). */
- float u = -2.71811842367242206819355e-07f;
- u = madd(u, s, +2.47990446951007470488548e-05f);
- u = madd(u, s, -0.00138888787478208541870117f);
- u = madd(u, s, +0.0416666641831398010253906f);
- u = madd(u, s, -0.5f);
- u = madd(u, s, +1.0f);
- if((q & 1) != 0) {
- u = -u;
- }
- if(fabsf(u) > 1.0f) {
- u = 0.0f;
- }
- return u;
+ /* Same argument reduction as fast_sinf(). */
+ int q = fast_rint(x * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f * 4, x);
+ x = madd(qf, -0.00024187564849853515625f * 4, x);
+ x = madd(qf, -3.7747668102383613586e-08f * 4, x);
+ x = madd(qf, -1.2816720341285448015e-12f * 4, x);
+ x = M_PI_2_F - (M_PI_2_F - x); /* Crush denormals. */
+ float s = x * x;
+ /* Polynomial from SLEEF's sincosf, max error is
+ * 4.33127e-07 over [-2pi,2pi] (98% of values are "exact"). */
+ float u = -2.71811842367242206819355e-07f;
+ u = madd(u, s, +2.47990446951007470488548e-05f);
+ u = madd(u, s, -0.00138888787478208541870117f);
+ u = madd(u, s, +0.0416666641831398010253906f);
+ u = madd(u, s, -0.5f);
+ u = madd(u, s, +1.0f);
+ if ((q & 1) != 0) {
+ u = -u;
+ }
+ if (fabsf(u) > 1.0f) {
+ u = 0.0f;
+ }
+ return u;
}
-ccl_device void fast_sincosf(float x, float* sine, float* cosine)
+ccl_device void fast_sincosf(float x, float *sine, float *cosine)
{
- /* Same argument reduction as fast_sin. */
- int q = fast_rint(x * M_1_PI_F);
- float qf = q;
- x = madd(qf, -0.78515625f*4, x);
- x = madd(qf, -0.00024187564849853515625f*4, x);
- x = madd(qf, -3.7747668102383613586e-08f*4, x);
- x = madd(qf, -1.2816720341285448015e-12f*4, x);
- x = M_PI_2_F - (M_PI_2_F - x); // crush denormals
- float s = x * x;
- /* NOTE: same exact polynomials as fast_sinf() and fast_cosf() above. */
- if((q & 1) != 0) {
- x = -x;
- }
- float su = 2.6083159809786593541503e-06f;
- su = madd(su, s, -0.0001981069071916863322258f);
- su = madd(su, s, +0.00833307858556509017944336f);
- su = madd(su, s, -0.166666597127914428710938f);
- su = madd(s, su * x, x);
- float cu = -2.71811842367242206819355e-07f;
- cu = madd(cu, s, +2.47990446951007470488548e-05f);
- cu = madd(cu, s, -0.00138888787478208541870117f);
- cu = madd(cu, s, +0.0416666641831398010253906f);
- cu = madd(cu, s, -0.5f);
- cu = madd(cu, s, +1.0f);
- if((q & 1) != 0) {
- cu = -cu;
- }
- if(fabsf(su) > 1.0f) {
- su = 0.0f;
- }
- if(fabsf(cu) > 1.0f) {
- cu = 0.0f;
- }
- *sine = su;
- *cosine = cu;
+ /* Same argument reduction as fast_sin. */
+ int q = fast_rint(x * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f * 4, x);
+ x = madd(qf, -0.00024187564849853515625f * 4, x);
+ x = madd(qf, -3.7747668102383613586e-08f * 4, x);
+ x = madd(qf, -1.2816720341285448015e-12f * 4, x);
+ x = M_PI_2_F - (M_PI_2_F - x); // crush denormals
+ float s = x * x;
+ /* NOTE: same exact polynomials as fast_sinf() and fast_cosf() above. */
+ if ((q & 1) != 0) {
+ x = -x;
+ }
+ float su = 2.6083159809786593541503e-06f;
+ su = madd(su, s, -0.0001981069071916863322258f);
+ su = madd(su, s, +0.00833307858556509017944336f);
+ su = madd(su, s, -0.166666597127914428710938f);
+ su = madd(s, su * x, x);
+ float cu = -2.71811842367242206819355e-07f;
+ cu = madd(cu, s, +2.47990446951007470488548e-05f);
+ cu = madd(cu, s, -0.00138888787478208541870117f);
+ cu = madd(cu, s, +0.0416666641831398010253906f);
+ cu = madd(cu, s, -0.5f);
+ cu = madd(cu, s, +1.0f);
+ if ((q & 1) != 0) {
+ cu = -cu;
+ }
+ if (fabsf(su) > 1.0f) {
+ su = 0.0f;
+ }
+ if (fabsf(cu) > 1.0f) {
+ cu = 0.0f;
+ }
+ *sine = su;
+ *cosine = cu;
}
/* NOTE: this approximation is only valid on [-8192.0,+8192.0], it starts
@@ -200,33 +201,33 @@ ccl_device void fast_sincosf(float x, float* sine, float* cosine)
*/
ccl_device float fast_tanf(float x)
{
- /* Derived from SLEEF implementation.
- *
- * Note that we cannot apply the "denormal crush" trick everywhere because
- * we sometimes need to take the reciprocal of the polynomial
- */
- int q = fast_rint(x * 2.0f * M_1_PI_F);
- float qf = q;
- x = madd(qf, -0.78515625f*2, x);
- x = madd(qf, -0.00024187564849853515625f*2, x);
- x = madd(qf, -3.7747668102383613586e-08f*2, x);
- x = madd(qf, -1.2816720341285448015e-12f*2, x);
- if((q & 1) == 0) {
- /* Crush denormals (only if we aren't inverting the result later). */
- x = M_PI_4_F - (M_PI_4_F - x);
- }
- float s = x * x;
- float u = 0.00927245803177356719970703f;
- u = madd(u, s, 0.00331984995864331722259521f);
- u = madd(u, s, 0.0242998078465461730957031f);
- u = madd(u, s, 0.0534495301544666290283203f);
- u = madd(u, s, 0.133383005857467651367188f);
- u = madd(u, s, 0.333331853151321411132812f);
- u = madd(s, u * x, x);
- if((q & 1) != 0) {
- u = -1.0f / u;
- }
- return u;
+ /* Derived from SLEEF implementation.
+ *
+ * Note that we cannot apply the "denormal crush" trick everywhere because
+ * we sometimes need to take the reciprocal of the polynomial
+ */
+ int q = fast_rint(x * 2.0f * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f * 2, x);
+ x = madd(qf, -0.00024187564849853515625f * 2, x);
+ x = madd(qf, -3.7747668102383613586e-08f * 2, x);
+ x = madd(qf, -1.2816720341285448015e-12f * 2, x);
+ if ((q & 1) == 0) {
+ /* Crush denormals (only if we aren't inverting the result later). */
+ x = M_PI_4_F - (M_PI_4_F - x);
+ }
+ float s = x * x;
+ float u = 0.00927245803177356719970703f;
+ u = madd(u, s, 0.00331984995864331722259521f);
+ u = madd(u, s, 0.0242998078465461730957031f);
+ u = madd(u, s, 0.0534495301544666290283203f);
+ u = madd(u, s, 0.133383005857467651367188f);
+ u = madd(u, s, 0.333331853151321411132812f);
+ u = madd(s, u * x, x);
+ if ((q & 1) != 0) {
+ u = -1.0f / u;
+ }
+ return u;
}
/* Fast, approximate sin(x*M_PI) with maximum absolute error of 0.000918954611.
@@ -235,122 +236,119 @@ ccl_device float fast_tanf(float x)
*/
ccl_device float fast_sinpif(float x)
{
- /* Fast trick to strip the integral part off, so our domain is [-1, 1]. */
- const float z = x - ((x + 25165824.0f) - 25165824.0f);
- const float y = z - z * fabsf(z);
- const float Q = 3.10396624f;
- const float P = 3.584135056f; /* P = 16-4*Q */
- return y * (Q + P * fabsf(y));
-
- /* The original article used used inferior constants for Q and P and
- * so had max error 1.091e-3.
- *
- * The optimal value for Q was determined by exhaustive search, minimizing
- * the absolute numerical error relative to float(std::sin(double(phi*M_PI)))
- * over the interval [0,2] (which is where most of the invocations happen).
- *
- * The basic idea of this approximation starts with the coarse approximation:
- * sin(pi*x) ~= f(x) = 4 * (x - x * abs(x))
- *
- * This approximation always _over_ estimates the target. On the other hand,
- * the curve:
- * sin(pi*x) ~= f(x) * abs(f(x)) / 4
- *
- * always lies _under_ the target. Thus we can simply numerically search for
- * the optimal constant to LERP these curves into a more precise
- * approximation.
- *
- * After folding the constants together and simplifying the resulting math,
- * we end up with the compact implementation above.
- *
- * NOTE: this function actually computes sin(x * pi) which avoids one or two
- * mults in many cases and guarantees exact values at integer periods.
- */
+ /* Fast trick to strip the integral part off, so our domain is [-1, 1]. */
+ const float z = x - ((x + 25165824.0f) - 25165824.0f);
+ const float y = z - z * fabsf(z);
+ const float Q = 3.10396624f;
+ const float P = 3.584135056f; /* P = 16-4*Q */
+ return y * (Q + P * fabsf(y));
+
+ /* The original article used used inferior constants for Q and P and
+ * so had max error 1.091e-3.
+ *
+ * The optimal value for Q was determined by exhaustive search, minimizing
+ * the absolute numerical error relative to float(std::sin(double(phi*M_PI)))
+ * over the interval [0,2] (which is where most of the invocations happen).
+ *
+ * The basic idea of this approximation starts with the coarse approximation:
+ * sin(pi*x) ~= f(x) = 4 * (x - x * abs(x))
+ *
+ * This approximation always _over_ estimates the target. On the other hand,
+ * the curve:
+ * sin(pi*x) ~= f(x) * abs(f(x)) / 4
+ *
+ * always lies _under_ the target. Thus we can simply numerically search for
+ * the optimal constant to LERP these curves into a more precise
+ * approximation.
+ *
+ * After folding the constants together and simplifying the resulting math,
+ * we end up with the compact implementation above.
+ *
+ * NOTE: this function actually computes sin(x * pi) which avoids one or two
+ * mults in many cases and guarantees exact values at integer periods.
+ */
}
/* Fast approximate cos(x*M_PI) with ~0.1% absolute error. */
ccl_device_inline float fast_cospif(float x)
{
- return fast_sinpif(x+0.5f);
+ return fast_sinpif(x + 0.5f);
}
ccl_device float fast_acosf(float x)
{
- const float f = fabsf(x);
- /* clamp and crush denormals. */
- const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f;
- /* Based on http://www.pouet.net/topic.php?which=9132&page=2
- * 85% accurate (ulp 0)
- * Examined 2130706434 values of acos: 15.2000597 avg ulp diff, 4492 max ulp, 4.51803e-05 max error // without "denormal crush"
- * Examined 2130706434 values of acos: 15.2007108 avg ulp diff, 4492 max ulp, 4.51803e-05 max error // with "denormal crush"
- */
- const float a = sqrtf(1.0f - m) *
- (1.5707963267f + m * (-0.213300989f + m *
- (0.077980478f + m * -0.02164095f)));
- return x < 0 ? M_PI_F - a : a;
+ const float f = fabsf(x);
+ /* clamp and crush denormals. */
+ const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f;
+ /* Based on http://www.pouet.net/topic.php?which=9132&page=2
+ * 85% accurate (ulp 0)
+ * Examined 2130706434 values of acos: 15.2000597 avg ulp diff, 4492 max ulp, 4.51803e-05 max error // without "denormal crush"
+ * Examined 2130706434 values of acos: 15.2007108 avg ulp diff, 4492 max ulp, 4.51803e-05 max error // with "denormal crush"
+ */
+ const float a = sqrtf(1.0f - m) *
+ (1.5707963267f + m * (-0.213300989f + m * (0.077980478f + m * -0.02164095f)));
+ return x < 0 ? M_PI_F - a : a;
}
ccl_device float fast_asinf(float x)
{
- /* Based on acosf approximation above.
- * Max error is 4.51133e-05 (ulps are higher because we are consistently off
- * by a little amount).
- */
- const float f = fabsf(x);
- /* Clamp and crush denormals. */
- const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f;
- const float a = M_PI_2_F - sqrtf(1.0f - m) *
- (1.5707963267f + m * (-0.213300989f + m *
- (0.077980478f + m * -0.02164095f)));
- return copysignf(a, x);
+ /* Based on acosf approximation above.
+ * Max error is 4.51133e-05 (ulps are higher because we are consistently off
+ * by a little amount).
+ */
+ const float f = fabsf(x);
+ /* Clamp and crush denormals. */
+ const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f;
+ const float a = M_PI_2_F -
+ sqrtf(1.0f - m) * (1.5707963267f +
+ m * (-0.213300989f + m * (0.077980478f + m * -0.02164095f)));
+ return copysignf(a, x);
}
ccl_device float fast_atanf(float x)
{
- const float a = fabsf(x);
- const float k = a > 1.0f ? 1 / a : a;
- const float s = 1.0f - (1.0f - k); /* Crush denormals. */
- const float t = s * s;
- /* http://mathforum.org/library/drmath/view/62672.html
- * Examined 4278190080 values of atan: 2.36864877 avg ulp diff, 302 max ulp, 6.55651e-06 max error // (with denormals)
- * Examined 4278190080 values of atan: 171160502 avg ulp diff, 855638016 max ulp, 6.55651e-06 max error // (crush denormals)
- */
- float r = s * madd(0.43157974f, t, 1.0f) /
- madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f);
- if(a > 1.0f) {
- r = M_PI_2_F - r;
- }
- return copysignf(r, x);
+ const float a = fabsf(x);
+ const float k = a > 1.0f ? 1 / a : a;
+ const float s = 1.0f - (1.0f - k); /* Crush denormals. */
+ const float t = s * s;
+ /* http://mathforum.org/library/drmath/view/62672.html
+ * Examined 4278190080 values of atan: 2.36864877 avg ulp diff, 302 max ulp, 6.55651e-06 max error // (with denormals)
+ * Examined 4278190080 values of atan: 171160502 avg ulp diff, 855638016 max ulp, 6.55651e-06 max error // (crush denormals)
+ */
+ float r = s * madd(0.43157974f, t, 1.0f) / madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f);
+ if (a > 1.0f) {
+ r = M_PI_2_F - r;
+ }
+ return copysignf(r, x);
}
ccl_device float fast_atan2f(float y, float x)
{
- /* Based on atan approximation above.
- *
- * The special cases around 0 and infinity were tested explicitly.
- *
- * The only case not handled correctly is x=NaN,y=0 which returns 0 instead
- * of nan.
- */
- const float a = fabsf(x);
- const float b = fabsf(y);
-
- const float k = (b == 0) ? 0.0f : ((a == b) ? 1.0f : (b > a ? a / b : b / a));
- const float s = 1.0f - (1.0f - k); /* Crush denormals */
- const float t = s * s;
-
- float r = s * madd(0.43157974f, t, 1.0f) /
- madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f);
-
- if(b > a) {
- /* Account for arg reduction. */
- r = M_PI_2_F - r;
- }
- /* Test sign bit of x. */
- if(__float_as_uint(x) & 0x80000000u) {
- r = M_PI_F - r;
- }
- return copysignf(r, y);
+ /* Based on atan approximation above.
+ *
+ * The special cases around 0 and infinity were tested explicitly.
+ *
+ * The only case not handled correctly is x=NaN,y=0 which returns 0 instead
+ * of nan.
+ */
+ const float a = fabsf(x);
+ const float b = fabsf(y);
+
+ const float k = (b == 0) ? 0.0f : ((a == b) ? 1.0f : (b > a ? a / b : b / a));
+ const float s = 1.0f - (1.0f - k); /* Crush denormals */
+ const float t = s * s;
+
+ float r = s * madd(0.43157974f, t, 1.0f) / madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f);
+
+ if (b > a) {
+ /* Account for arg reduction. */
+ r = M_PI_2_F - r;
+ }
+ /* Test sign bit of x. */
+ if (__float_as_uint(x) & 0x80000000u) {
+ r = M_PI_F - r;
+ }
+ return copysignf(r, y);
}
/* Based on:
@@ -359,204 +357,207 @@ ccl_device float fast_atan2f(float y, float x)
*/
ccl_device float fast_log2f(float x)
{
- /* NOTE: clamp to avoid special cases and make result "safe" from large
- * negative values/nans. */
- x = clamp(x, FLT_MIN, FLT_MAX);
- unsigned bits = __float_as_uint(x);
- int exponent = (int)(bits >> 23) - 127;
- float f = __uint_as_float((bits & 0x007FFFFF) | 0x3f800000) - 1.0f;
- /* Examined 2130706432 values of log2 on [1.17549435e-38,3.40282347e+38]:
- * 0.0797524457 avg ulp diff, 3713596 max ulp, 7.62939e-06 max error.
- * ulp histogram:
- * 0 = 97.46%
- * 1 = 2.29%
- * 2 = 0.11%
- */
- float f2 = f * f;
- float f4 = f2 * f2;
- float hi = madd(f, -0.00931049621349f, 0.05206469089414f);
- float lo = madd(f, 0.47868480909345f, -0.72116591947498f);
- hi = madd(f, hi, -0.13753123777116f);
- hi = madd(f, hi, 0.24187369696082f);
- hi = madd(f, hi, -0.34730547155299f);
- lo = madd(f, lo, 1.442689881667200f);
- return ((f4 * hi) + (f * lo)) + exponent;
+ /* NOTE: clamp to avoid special cases and make result "safe" from large
+ * negative values/nans. */
+ x = clamp(x, FLT_MIN, FLT_MAX);
+ unsigned bits = __float_as_uint(x);
+ int exponent = (int)(bits >> 23) - 127;
+ float f = __uint_as_float((bits & 0x007FFFFF) | 0x3f800000) - 1.0f;
+ /* Examined 2130706432 values of log2 on [1.17549435e-38,3.40282347e+38]:
+ * 0.0797524457 avg ulp diff, 3713596 max ulp, 7.62939e-06 max error.
+ * ulp histogram:
+ * 0 = 97.46%
+ * 1 = 2.29%
+ * 2 = 0.11%
+ */
+ float f2 = f * f;
+ float f4 = f2 * f2;
+ float hi = madd(f, -0.00931049621349f, 0.05206469089414f);
+ float lo = madd(f, 0.47868480909345f, -0.72116591947498f);
+ hi = madd(f, hi, -0.13753123777116f);
+ hi = madd(f, hi, 0.24187369696082f);
+ hi = madd(f, hi, -0.34730547155299f);
+ lo = madd(f, lo, 1.442689881667200f);
+ return ((f4 * hi) + (f * lo)) + exponent;
}
ccl_device_inline float fast_logf(float x)
{
- /* Examined 2130706432 values of logf on [1.17549435e-38,3.40282347e+38]:
- * 0.313865375 avg ulp diff, 5148137 max ulp, 7.62939e-06 max error.
- */
- return fast_log2f(x) * M_LN2_F;
+ /* Examined 2130706432 values of logf on [1.17549435e-38,3.40282347e+38]:
+ * 0.313865375 avg ulp diff, 5148137 max ulp, 7.62939e-06 max error.
+ */
+ return fast_log2f(x) * M_LN2_F;
}
ccl_device_inline float fast_log10(float x)
{
- /* Examined 2130706432 values of log10f on [1.17549435e-38,3.40282347e+38]:
- * 0.631237033 avg ulp diff, 4471615 max ulp, 3.8147e-06 max error.
- */
- return fast_log2f(x) * M_LN2_F / M_LN10_F;
+ /* Examined 2130706432 values of log10f on [1.17549435e-38,3.40282347e+38]:
+ * 0.631237033 avg ulp diff, 4471615 max ulp, 3.8147e-06 max error.
+ */
+ return fast_log2f(x) * M_LN2_F / M_LN10_F;
}
ccl_device float fast_logb(float x)
{
- /* Don't bother with denormals. */
- x = fabsf(x);
- x = clamp(x, FLT_MIN, FLT_MAX);
- unsigned bits = __float_as_uint(x);
- return (int)(bits >> 23) - 127;
+ /* Don't bother with denormals. */
+ x = fabsf(x);
+ x = clamp(x, FLT_MIN, FLT_MAX);
+ unsigned bits = __float_as_uint(x);
+ return (int)(bits >> 23) - 127;
}
ccl_device float fast_exp2f(float x)
{
- /* Clamp to safe range for final addition. */
- x = clamp(x, -126.0f, 126.0f);
- /* Range reduction. */
- int m = (int)x; x -= m;
- x = 1.0f - (1.0f - x); /* Crush denormals (does not affect max ulps!). */
- /* 5th degree polynomial generated with sollya
- * Examined 2247622658 values of exp2 on [-126,126]: 2.75764912 avg ulp diff,
- * 232 max ulp.
- *
- * ulp histogram:
- * 0 = 87.81%
- * 1 = 4.18%
- */
- float r = 1.33336498402e-3f;
- r = madd(x, r, 9.810352697968e-3f);
- r = madd(x, r, 5.551834031939e-2f);
- r = madd(x, r, 0.2401793301105f);
- r = madd(x, r, 0.693144857883f);
- r = madd(x, r, 1.0f);
- /* Multiply by 2 ^ m by adding in the exponent. */
- /* NOTE: left-shift of negative number is undefined behavior. */
- return __uint_as_float(__float_as_uint(r) + ((unsigned)m << 23));
+ /* Clamp to safe range for final addition. */
+ x = clamp(x, -126.0f, 126.0f);
+ /* Range reduction. */
+ int m = (int)x;
+ x -= m;
+ x = 1.0f - (1.0f - x); /* Crush denormals (does not affect max ulps!). */
+ /* 5th degree polynomial generated with sollya
+ * Examined 2247622658 values of exp2 on [-126,126]: 2.75764912 avg ulp diff,
+ * 232 max ulp.
+ *
+ * ulp histogram:
+ * 0 = 87.81%
+ * 1 = 4.18%
+ */
+ float r = 1.33336498402e-3f;
+ r = madd(x, r, 9.810352697968e-3f);
+ r = madd(x, r, 5.551834031939e-2f);
+ r = madd(x, r, 0.2401793301105f);
+ r = madd(x, r, 0.693144857883f);
+ r = madd(x, r, 1.0f);
+ /* Multiply by 2 ^ m by adding in the exponent. */
+ /* NOTE: left-shift of negative number is undefined behavior. */
+ return __uint_as_float(__float_as_uint(r) + ((unsigned)m << 23));
}
ccl_device_inline float fast_expf(float x)
{
- /* Examined 2237485550 values of exp on [-87.3300018,87.3300018]:
- * 2.6666452 avg ulp diff, 230 max ulp.
- */
- return fast_exp2f(x / M_LN2_F);
+ /* Examined 2237485550 values of exp on [-87.3300018,87.3300018]:
+ * 2.6666452 avg ulp diff, 230 max ulp.
+ */
+ return fast_exp2f(x / M_LN2_F);
}
#ifndef __KERNEL_GPU__
ccl_device float4 fast_exp2f4(float4 x)
{
- const float4 one = make_float4(1.0f);
- const float4 limit = make_float4(126.0f);
- x = clamp(x, -limit, limit);
- int4 m = make_int4(x);
- x = one - (one - (x - make_float4(m)));
- float4 r = make_float4(1.33336498402e-3f);
- r = madd4(x, r, make_float4(9.810352697968e-3f));
- r = madd4(x, r, make_float4(5.551834031939e-2f));
- r = madd4(x, r, make_float4(0.2401793301105f));
- r = madd4(x, r, make_float4(0.693144857883f));
- r = madd4(x, r, make_float4(1.0f));
- return __int4_as_float4(__float4_as_int4(r) + (m << 23));
+ const float4 one = make_float4(1.0f);
+ const float4 limit = make_float4(126.0f);
+ x = clamp(x, -limit, limit);
+ int4 m = make_int4(x);
+ x = one - (one - (x - make_float4(m)));
+ float4 r = make_float4(1.33336498402e-3f);
+ r = madd4(x, r, make_float4(9.810352697968e-3f));
+ r = madd4(x, r, make_float4(5.551834031939e-2f));
+ r = madd4(x, r, make_float4(0.2401793301105f));
+ r = madd4(x, r, make_float4(0.693144857883f));
+ r = madd4(x, r, make_float4(1.0f));
+ return __int4_as_float4(__float4_as_int4(r) + (m << 23));
}
ccl_device_inline float4 fast_expf4(float4 x)
{
- return fast_exp2f4(x / M_LN2_F);
+ return fast_exp2f4(x / M_LN2_F);
}
#endif
ccl_device_inline float fast_exp10(float x)
{
- /* Examined 2217701018 values of exp10 on [-37.9290009,37.9290009]:
- * 2.71732409 avg ulp diff, 232 max ulp.
- */
- return fast_exp2f(x * M_LN10_F / M_LN2_F);
+ /* Examined 2217701018 values of exp10 on [-37.9290009,37.9290009]:
+ * 2.71732409 avg ulp diff, 232 max ulp.
+ */
+ return fast_exp2f(x * M_LN10_F / M_LN2_F);
}
ccl_device_inline float fast_expm1f(float x)
{
- if(fabsf(x) < 1e-5f) {
- x = 1.0f - (1.0f - x); /* Crush denormals. */
- return madd(0.5f, x * x, x);
- }
- else {
- return fast_expf(x) - 1.0f;
- }
+ if (fabsf(x) < 1e-5f) {
+ x = 1.0f - (1.0f - x); /* Crush denormals. */
+ return madd(0.5f, x * x, x);
+ }
+ else {
+ return fast_expf(x) - 1.0f;
+ }
}
ccl_device float fast_sinhf(float x)
{
- float a = fabsf(x);
- if(a > 1.0f) {
- /* Examined 53389559 values of sinh on [1,87.3300018]:
- * 33.6886442 avg ulp diff, 178 max ulp. */
- float e = fast_expf(a);
- return copysignf(0.5f * e - 0.5f / e, x);
- }
- else {
- a = 1.0f - (1.0f - a); /* Crush denorms. */
- float a2 = a * a;
- /* Degree 7 polynomial generated with sollya. */
- /* Examined 2130706434 values of sinh on [-1,1]: 1.19209e-07 max error. */
- float r = 2.03945513931e-4f;
- r = madd(r, a2, 8.32990277558e-3f);
- r = madd(r, a2, 0.1666673421859f);
- r = madd(r * a, a2, a);
- return copysignf(r, x);
- }
+ float a = fabsf(x);
+ if (a > 1.0f) {
+ /* Examined 53389559 values of sinh on [1,87.3300018]:
+ * 33.6886442 avg ulp diff, 178 max ulp. */
+ float e = fast_expf(a);
+ return copysignf(0.5f * e - 0.5f / e, x);
+ }
+ else {
+ a = 1.0f - (1.0f - a); /* Crush denorms. */
+ float a2 = a * a;
+ /* Degree 7 polynomial generated with sollya. */
+ /* Examined 2130706434 values of sinh on [-1,1]: 1.19209e-07 max error. */
+ float r = 2.03945513931e-4f;
+ r = madd(r, a2, 8.32990277558e-3f);
+ r = madd(r, a2, 0.1666673421859f);
+ r = madd(r * a, a2, a);
+ return copysignf(r, x);
+ }
}
ccl_device_inline float fast_coshf(float x)
{
- /* Examined 2237485550 values of cosh on [-87.3300018,87.3300018]:
- * 1.78256726 avg ulp diff, 178 max ulp.
- */
- float e = fast_expf(fabsf(x));
- return 0.5f * e + 0.5f / e;
+ /* Examined 2237485550 values of cosh on [-87.3300018,87.3300018]:
+ * 1.78256726 avg ulp diff, 178 max ulp.
+ */
+ float e = fast_expf(fabsf(x));
+ return 0.5f * e + 0.5f / e;
}
ccl_device_inline float fast_tanhf(float x)
{
- /* Examined 4278190080 values of tanh on [-3.40282347e+38,3.40282347e+38]:
- * 3.12924e-06 max error.
- */
- /* NOTE: ulp error is high because of sub-optimal handling around the origin. */
- float e = fast_expf(2.0f * fabsf(x));
- return copysignf(1.0f - 2.0f / (1.0f + e), x);
+ /* Examined 4278190080 values of tanh on [-3.40282347e+38,3.40282347e+38]:
+ * 3.12924e-06 max error.
+ */
+ /* NOTE: ulp error is high because of sub-optimal handling around the origin. */
+ float e = fast_expf(2.0f * fabsf(x));
+ return copysignf(1.0f - 2.0f / (1.0f + e), x);
}
ccl_device float fast_safe_powf(float x, float y)
{
- if(y == 0) return 1.0f; /* x^1=1 */
- if(x == 0) return 0.0f; /* 0^y=0 */
- float sign = 1.0f;
- if(x < 0.0f) {
- /* if x is negative, only deal with integer powers
- * powf returns NaN for non-integers, we will return 0 instead.
- */
- int ybits = __float_as_int(y) & 0x7fffffff;
- if(ybits >= 0x4b800000) {
- // always even int, keep positive
- }
- else if(ybits >= 0x3f800000) {
- /* Bigger than 1, check. */
- int k = (ybits >> 23) - 127; /* Get exponent. */
- int j = ybits >> (23 - k); /* Shift out possible fractional bits. */
- if((j << (23 - k)) == ybits) { /* rebuild number and check for a match. */
- /* +1 for even, -1 for odd. */
- sign = __int_as_float(0x3f800000 | (j << 31));
- }
- else {
- /* Not an integer. */
- return 0.0f;
- }
- }
- else {
- /* Not an integer. */
- return 0.0f;
- }
- }
- return sign * fast_exp2f(y * fast_log2f(fabsf(x)));
+ if (y == 0)
+ return 1.0f; /* x^1=1 */
+ if (x == 0)
+ return 0.0f; /* 0^y=0 */
+ float sign = 1.0f;
+ if (x < 0.0f) {
+ /* if x is negative, only deal with integer powers
+ * powf returns NaN for non-integers, we will return 0 instead.
+ */
+ int ybits = __float_as_int(y) & 0x7fffffff;
+ if (ybits >= 0x4b800000) {
+ // always even int, keep positive
+ }
+ else if (ybits >= 0x3f800000) {
+ /* Bigger than 1, check. */
+ int k = (ybits >> 23) - 127; /* Get exponent. */
+ int j = ybits >> (23 - k); /* Shift out possible fractional bits. */
+ if ((j << (23 - k)) == ybits) { /* rebuild number and check for a match. */
+ /* +1 for even, -1 for odd. */
+ sign = __int_as_float(0x3f800000 | (j << 31));
+ }
+ else {
+ /* Not an integer. */
+ return 0.0f;
+ }
+ }
+ else {
+ /* Not an integer. */
+ return 0.0f;
+ }
+ }
+ return sign * fast_exp2f(y * fast_log2f(fabsf(x)));
}
/* TODO(sergey): Check speed with our erf functions implementation from
@@ -565,74 +566,75 @@ ccl_device float fast_safe_powf(float x, float y)
ccl_device_inline float fast_erff(float x)
{
- /* Examined 1082130433 values of erff on [0,4]: 1.93715e-06 max error. */
- /* Abramowitz and Stegun, 7.1.28. */
- const float a1 = 0.0705230784f;
- const float a2 = 0.0422820123f;
- const float a3 = 0.0092705272f;
- const float a4 = 0.0001520143f;
- const float a5 = 0.0002765672f;
- const float a6 = 0.0000430638f;
- const float a = fabsf(x);
- if(a >= 12.3f) {
- return copysignf(1.0f, x);
- }
- const float b = 1.0f - (1.0f - a); /* Crush denormals. */
- const float r = madd(madd(madd(madd(madd(madd(a6, b, a5), b, a4), b, a3), b, a2), b, a1), b, 1.0f);
- const float s = r * r; /* ^2 */
- const float t = s * s; /* ^4 */
- const float u = t * t; /* ^8 */
- const float v = u * u; /* ^16 */
- return copysignf(1.0f - 1.0f / v, x);
+ /* Examined 1082130433 values of erff on [0,4]: 1.93715e-06 max error. */
+ /* Abramowitz and Stegun, 7.1.28. */
+ const float a1 = 0.0705230784f;
+ const float a2 = 0.0422820123f;
+ const float a3 = 0.0092705272f;
+ const float a4 = 0.0001520143f;
+ const float a5 = 0.0002765672f;
+ const float a6 = 0.0000430638f;
+ const float a = fabsf(x);
+ if (a >= 12.3f) {
+ return copysignf(1.0f, x);
+ }
+ const float b = 1.0f - (1.0f - a); /* Crush denormals. */
+ const float r = madd(
+ madd(madd(madd(madd(madd(a6, b, a5), b, a4), b, a3), b, a2), b, a1), b, 1.0f);
+ const float s = r * r; /* ^2 */
+ const float t = s * s; /* ^4 */
+ const float u = t * t; /* ^8 */
+ const float v = u * u; /* ^16 */
+ return copysignf(1.0f - 1.0f / v, x);
}
ccl_device_inline float fast_erfcf(float x)
{
- /* Examined 2164260866 values of erfcf on [-4,4]: 1.90735e-06 max error.
- *
- * ulp histogram:
- *
- * 0 = 80.30%
- */
- return 1.0f - fast_erff(x);
+ /* Examined 2164260866 values of erfcf on [-4,4]: 1.90735e-06 max error.
+ *
+ * ulp histogram:
+ *
+ * 0 = 80.30%
+ */
+ return 1.0f - fast_erff(x);
}
ccl_device_inline float fast_ierff(float x)
{
- /* From: Approximating the erfinv function by Mike Giles. */
- /* To avoid trouble at the limit, clamp input to 1-eps. */
- float a = fabsf(x);
- if(a > 0.99999994f) {
- a = 0.99999994f;
- }
- float w = -fast_logf((1.0f - a) * (1.0f + a)), p;
- if(w < 5.0f) {
- w = w - 2.5f;
- p = 2.81022636e-08f;
- p = madd(p, w, 3.43273939e-07f);
- p = madd(p, w, -3.5233877e-06f);
- p = madd(p, w, -4.39150654e-06f);
- p = madd(p, w, 0.00021858087f);
- p = madd(p, w, -0.00125372503f);
- p = madd(p, w, -0.00417768164f);
- p = madd(p, w, 0.246640727f);
- p = madd(p, w, 1.50140941f);
- }
- else {
- w = sqrtf(w) - 3.0f;
- p = -0.000200214257f;
- p = madd(p, w, 0.000100950558f);
- p = madd(p, w, 0.00134934322f);
- p = madd(p, w, -0.00367342844f);
- p = madd(p, w, 0.00573950773f);
- p = madd(p, w, -0.0076224613f);
- p = madd(p, w, 0.00943887047f);
- p = madd(p, w, 1.00167406f);
- p = madd(p, w, 2.83297682f);
- }
- return p * x;
+ /* From: Approximating the erfinv function by Mike Giles. */
+ /* To avoid trouble at the limit, clamp input to 1-eps. */
+ float a = fabsf(x);
+ if (a > 0.99999994f) {
+ a = 0.99999994f;
+ }
+ float w = -fast_logf((1.0f - a) * (1.0f + a)), p;
+ if (w < 5.0f) {
+ w = w - 2.5f;
+ p = 2.81022636e-08f;
+ p = madd(p, w, 3.43273939e-07f);
+ p = madd(p, w, -3.5233877e-06f);
+ p = madd(p, w, -4.39150654e-06f);
+ p = madd(p, w, 0.00021858087f);
+ p = madd(p, w, -0.00125372503f);
+ p = madd(p, w, -0.00417768164f);
+ p = madd(p, w, 0.246640727f);
+ p = madd(p, w, 1.50140941f);
+ }
+ else {
+ w = sqrtf(w) - 3.0f;
+ p = -0.000200214257f;
+ p = madd(p, w, 0.000100950558f);
+ p = madd(p, w, 0.00134934322f);
+ p = madd(p, w, -0.00367342844f);
+ p = madd(p, w, 0.00573950773f);
+ p = madd(p, w, -0.0076224613f);
+ p = madd(p, w, 0.00943887047f);
+ p = madd(p, w, 1.00167406f);
+ p = madd(p, w, 2.83297682f);
+ }
+ return p * x;
}
CCL_NAMESPACE_END
-#endif /* __UTIL_FAST_MATH__ */
+#endif /* __UTIL_FAST_MATH__ */
diff --git a/intern/cycles/util/util_math_float2.h b/intern/cycles/util/util_math_float2.h
index 6fe8e3b4115..9feaf042d19 100644
--- a/intern/cycles/util/util_math_float2.h
+++ b/intern/cycles/util/util_math_float2.h
@@ -28,206 +28,206 @@ CCL_NAMESPACE_BEGIN
*/
#ifndef __KERNEL_OPENCL__
-ccl_device_inline float2 operator-(const float2& a);
-ccl_device_inline float2 operator*(const float2& a, const float2& b);
-ccl_device_inline float2 operator*(const float2& a, float f);
-ccl_device_inline float2 operator*(float f, const float2& a);
-ccl_device_inline float2 operator/(float f, const float2& a);
-ccl_device_inline float2 operator/(const float2& a, float f);
-ccl_device_inline float2 operator/(const float2& a, const float2& b);
-ccl_device_inline float2 operator+(const float2& a, const float2& b);
-ccl_device_inline float2 operator-(const float2& a, const float2& b);
-ccl_device_inline float2 operator+=(float2& a, const float2& b);
-ccl_device_inline float2 operator*=(float2& a, const float2& b);
-ccl_device_inline float2 operator*=(float2& a, float f);
-ccl_device_inline float2 operator/=(float2& a, const float2& b);
-ccl_device_inline float2 operator/=(float2& a, float f);
-
-ccl_device_inline bool operator==(const float2& a, const float2& b);
-ccl_device_inline bool operator!=(const float2& a, const float2& b);
-
-ccl_device_inline bool is_zero(const float2& a);
-ccl_device_inline float average(const float2& a);
-ccl_device_inline float dot(const float2& a, const float2& b);
-ccl_device_inline float cross(const float2& a, const float2& b);
-ccl_device_inline float len(const float2& a);
-ccl_device_inline float2 normalize(const float2& a);
-ccl_device_inline float2 normalize_len(const float2& a, float *t);
-ccl_device_inline float2 safe_normalize(const float2& a);
-ccl_device_inline float2 min(const float2& a, const float2& b);
-ccl_device_inline float2 max(const float2& a, const float2& b);
-ccl_device_inline float2 clamp(const float2& a, const float2& mn, const float2& mx);
-ccl_device_inline float2 fabs(const float2& a);
-ccl_device_inline float2 as_float2(const float4& a);
-ccl_device_inline float2 interp(const float2& a, const float2& b, float t);
-#endif /* !__KERNEL_OPENCL__ */
+ccl_device_inline float2 operator-(const float2 &a);
+ccl_device_inline float2 operator*(const float2 &a, const float2 &b);
+ccl_device_inline float2 operator*(const float2 &a, float f);
+ccl_device_inline float2 operator*(float f, const float2 &a);
+ccl_device_inline float2 operator/(float f, const float2 &a);
+ccl_device_inline float2 operator/(const float2 &a, float f);
+ccl_device_inline float2 operator/(const float2 &a, const float2 &b);
+ccl_device_inline float2 operator+(const float2 &a, const float2 &b);
+ccl_device_inline float2 operator-(const float2 &a, const float2 &b);
+ccl_device_inline float2 operator+=(float2 &a, const float2 &b);
+ccl_device_inline float2 operator*=(float2 &a, const float2 &b);
+ccl_device_inline float2 operator*=(float2 &a, float f);
+ccl_device_inline float2 operator/=(float2 &a, const float2 &b);
+ccl_device_inline float2 operator/=(float2 &a, float f);
+
+ccl_device_inline bool operator==(const float2 &a, const float2 &b);
+ccl_device_inline bool operator!=(const float2 &a, const float2 &b);
+
+ccl_device_inline bool is_zero(const float2 &a);
+ccl_device_inline float average(const float2 &a);
+ccl_device_inline float dot(const float2 &a, const float2 &b);
+ccl_device_inline float cross(const float2 &a, const float2 &b);
+ccl_device_inline float len(const float2 &a);
+ccl_device_inline float2 normalize(const float2 &a);
+ccl_device_inline float2 normalize_len(const float2 &a, float *t);
+ccl_device_inline float2 safe_normalize(const float2 &a);
+ccl_device_inline float2 min(const float2 &a, const float2 &b);
+ccl_device_inline float2 max(const float2 &a, const float2 &b);
+ccl_device_inline float2 clamp(const float2 &a, const float2 &mn, const float2 &mx);
+ccl_device_inline float2 fabs(const float2 &a);
+ccl_device_inline float2 as_float2(const float4 &a);
+ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t);
+#endif /* !__KERNEL_OPENCL__ */
/*******************************************************************************
* Definition.
*/
#ifndef __KERNEL_OPENCL__
-ccl_device_inline float2 operator-(const float2& a)
+ccl_device_inline float2 operator-(const float2 &a)
{
- return make_float2(-a.x, -a.y);
+ return make_float2(-a.x, -a.y);
}
-ccl_device_inline float2 operator*(const float2& a, const float2& b)
+ccl_device_inline float2 operator*(const float2 &a, const float2 &b)
{
- return make_float2(a.x*b.x, a.y*b.y);
+ return make_float2(a.x * b.x, a.y * b.y);
}
-ccl_device_inline float2 operator*(const float2& a, float f)
+ccl_device_inline float2 operator*(const float2 &a, float f)
{
- return make_float2(a.x*f, a.y*f);
+ return make_float2(a.x * f, a.y * f);
}
-ccl_device_inline float2 operator*(float f, const float2& a)
+ccl_device_inline float2 operator*(float f, const float2 &a)
{
- return make_float2(a.x*f, a.y*f);
+ return make_float2(a.x * f, a.y * f);
}
-ccl_device_inline float2 operator/(float f, const float2& a)
+ccl_device_inline float2 operator/(float f, const float2 &a)
{
- return make_float2(f/a.x, f/a.y);
+ return make_float2(f / a.x, f / a.y);
}
-ccl_device_inline float2 operator/(const float2& a, float f)
+ccl_device_inline float2 operator/(const float2 &a, float f)
{
- float invf = 1.0f/f;
- return make_float2(a.x*invf, a.y*invf);
+ float invf = 1.0f / f;
+ return make_float2(a.x * invf, a.y * invf);
}
-ccl_device_inline float2 operator/(const float2& a, const float2& b)
+ccl_device_inline float2 operator/(const float2 &a, const float2 &b)
{
- return make_float2(a.x/b.x, a.y/b.y);
+ return make_float2(a.x / b.x, a.y / b.y);
}
-ccl_device_inline float2 operator+(const float2& a, const float2& b)
+ccl_device_inline float2 operator+(const float2 &a, const float2 &b)
{
- return make_float2(a.x+b.x, a.y+b.y);
+ return make_float2(a.x + b.x, a.y + b.y);
}
-ccl_device_inline float2 operator-(const float2& a, const float2& b)
+ccl_device_inline float2 operator-(const float2 &a, const float2 &b)
{
- return make_float2(a.x-b.x, a.y-b.y);
+ return make_float2(a.x - b.x, a.y - b.y);
}
-ccl_device_inline float2 operator+=(float2& a, const float2& b)
+ccl_device_inline float2 operator+=(float2 &a, const float2 &b)
{
- return a = a + b;
+ return a = a + b;
}
-ccl_device_inline float2 operator*=(float2& a, const float2& b)
+ccl_device_inline float2 operator*=(float2 &a, const float2 &b)
{
- return a = a * b;
+ return a = a * b;
}
-ccl_device_inline float2 operator*=(float2& a, float f)
+ccl_device_inline float2 operator*=(float2 &a, float f)
{
- return a = a * f;
+ return a = a * f;
}
-ccl_device_inline float2 operator/=(float2& a, const float2& b)
+ccl_device_inline float2 operator/=(float2 &a, const float2 &b)
{
- return a = a / b;
+ return a = a / b;
}
-ccl_device_inline float2 operator/=(float2& a, float f)
+ccl_device_inline float2 operator/=(float2 &a, float f)
{
- float invf = 1.0f/f;
- return a = a * invf;
+ float invf = 1.0f / f;
+ return a = a * invf;
}
-ccl_device_inline bool operator==(const float2& a, const float2& b)
+ccl_device_inline bool operator==(const float2 &a, const float2 &b)
{
- return (a.x == b.x && a.y == b.y);
+ return (a.x == b.x && a.y == b.y);
}
-ccl_device_inline bool operator!=(const float2& a, const float2& b)
+ccl_device_inline bool operator!=(const float2 &a, const float2 &b)
{
- return !(a == b);
+ return !(a == b);
}
-ccl_device_inline bool is_zero(const float2& a)
+ccl_device_inline bool is_zero(const float2 &a)
{
- return (a.x == 0.0f && a.y == 0.0f);
+ return (a.x == 0.0f && a.y == 0.0f);
}
-ccl_device_inline float average(const float2& a)
+ccl_device_inline float average(const float2 &a)
{
- return (a.x + a.y)*(1.0f/2.0f);
+ return (a.x + a.y) * (1.0f / 2.0f);
}
-ccl_device_inline float dot(const float2& a, const float2& b)
+ccl_device_inline float dot(const float2 &a, const float2 &b)
{
- return a.x*b.x + a.y*b.y;
+ return a.x * b.x + a.y * b.y;
}
-ccl_device_inline float cross(const float2& a, const float2& b)
+ccl_device_inline float cross(const float2 &a, const float2 &b)
{
- return (a.x*b.y - a.y*b.x);
+ return (a.x * b.y - a.y * b.x);
}
-ccl_device_inline float len(const float2& a)
+ccl_device_inline float len(const float2 &a)
{
- return sqrtf(dot(a, a));
+ return sqrtf(dot(a, a));
}
-ccl_device_inline float2 normalize(const float2& a)
+ccl_device_inline float2 normalize(const float2 &a)
{
- return a/len(a);
+ return a / len(a);
}
-ccl_device_inline float2 normalize_len(const float2& a, float *t)
+ccl_device_inline float2 normalize_len(const float2 &a, float *t)
{
- *t = len(a);
- return a/(*t);
+ *t = len(a);
+ return a / (*t);
}
-ccl_device_inline float2 safe_normalize(const float2& a)
+ccl_device_inline float2 safe_normalize(const float2 &a)
{
- float t = len(a);
- return (t != 0.0f)? a/t: a;
+ float t = len(a);
+ return (t != 0.0f) ? a / t : a;
}
-ccl_device_inline float2 min(const float2& a, const float2& b)
+ccl_device_inline float2 min(const float2 &a, const float2 &b)
{
- return make_float2(min(a.x, b.x), min(a.y, b.y));
+ return make_float2(min(a.x, b.x), min(a.y, b.y));
}
-ccl_device_inline float2 max(const float2& a, const float2& b)
+ccl_device_inline float2 max(const float2 &a, const float2 &b)
{
- return make_float2(max(a.x, b.x), max(a.y, b.y));
+ return make_float2(max(a.x, b.x), max(a.y, b.y));
}
-ccl_device_inline float2 clamp(const float2& a, const float2& mn, const float2& mx)
+ccl_device_inline float2 clamp(const float2 &a, const float2 &mn, const float2 &mx)
{
- return min(max(a, mn), mx);
+ return min(max(a, mn), mx);
}
-ccl_device_inline float2 fabs(const float2& a)
+ccl_device_inline float2 fabs(const float2 &a)
{
- return make_float2(fabsf(a.x), fabsf(a.y));
+ return make_float2(fabsf(a.x), fabsf(a.y));
}
-ccl_device_inline float2 as_float2(const float4& a)
+ccl_device_inline float2 as_float2(const float4 &a)
{
- return make_float2(a.x, a.y);
+ return make_float2(a.x, a.y);
}
-ccl_device_inline float2 interp(const float2& a, const float2& b, float t)
+ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
{
- return a + t*(b - a);
+ return a + t * (b - a);
}
-ccl_device_inline float2 mix(const float2& a, const float2& b, float t)
+ccl_device_inline float2 mix(const float2 &a, const float2 &b, float t)
{
- return a + t*(b - a);
+ return a + t * (b - a);
}
-#endif /* !__KERNEL_OPENCL__ */
+#endif /* !__KERNEL_OPENCL__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_FLOAT2_H__ */
+#endif /* __UTIL_MATH_FLOAT2_H__ */
diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h
index a54a3f3087c..85e9b8114ff 100644
--- a/intern/cycles/util/util_math_float3.h
+++ b/intern/cycles/util/util_math_float3.h
@@ -28,37 +28,37 @@ CCL_NAMESPACE_BEGIN
*/
#ifndef __KERNEL_OPENCL__
-ccl_device_inline float3 operator-(const float3& a);
-ccl_device_inline float3 operator*(const float3& a, const float3& b);
-ccl_device_inline float3 operator*(const float3& a, const float f);
-ccl_device_inline float3 operator*(const float f, const float3& a);
-ccl_device_inline float3 operator/(const float f, const float3& a);
-ccl_device_inline float3 operator/(const float3& a, const float f);
-ccl_device_inline float3 operator/(const float3& a, const float3& b);
-ccl_device_inline float3 operator+(const float3& a, const float3& b);
-ccl_device_inline float3 operator-(const float3& a, const float3& b);
-ccl_device_inline float3 operator+=(float3& a, const float3& b);
-ccl_device_inline float3 operator-=(float3& a, const float3& b);
-ccl_device_inline float3 operator*=(float3& a, const float3& b);
-ccl_device_inline float3 operator*=(float3& a, float f);
-ccl_device_inline float3 operator/=(float3& a, const float3& b);
-ccl_device_inline float3 operator/=(float3& a, float f);
-
-ccl_device_inline bool operator==(const float3& a, const float3& b);
-ccl_device_inline bool operator!=(const float3& a, const float3& b);
-
-ccl_device_inline float dot(const float3& a, const float3& b);
-ccl_device_inline float dot_xy(const float3& a, const float3& b);
-ccl_device_inline float3 cross(const float3& a, const float3& b);
-ccl_device_inline float3 normalize(const float3& a);
-ccl_device_inline float3 min(const float3& a, const float3& b);
-ccl_device_inline float3 max(const float3& a, const float3& b);
-ccl_device_inline float3 clamp(const float3& a, const float3& mn, const float3& mx);
-ccl_device_inline float3 fabs(const float3& a);
-ccl_device_inline float3 mix(const float3& a, const float3& b, float t);
-ccl_device_inline float3 rcp(const float3& a);
-ccl_device_inline float3 sqrt(const float3& a);
-#endif /* !__KERNEL_OPENCL__ */
+ccl_device_inline float3 operator-(const float3 &a);
+ccl_device_inline float3 operator*(const float3 &a, const float3 &b);
+ccl_device_inline float3 operator*(const float3 &a, const float f);
+ccl_device_inline float3 operator*(const float f, const float3 &a);
+ccl_device_inline float3 operator/(const float f, const float3 &a);
+ccl_device_inline float3 operator/(const float3 &a, const float f);
+ccl_device_inline float3 operator/(const float3 &a, const float3 &b);
+ccl_device_inline float3 operator+(const float3 &a, const float3 &b);
+ccl_device_inline float3 operator-(const float3 &a, const float3 &b);
+ccl_device_inline float3 operator+=(float3 &a, const float3 &b);
+ccl_device_inline float3 operator-=(float3 &a, const float3 &b);
+ccl_device_inline float3 operator*=(float3 &a, const float3 &b);
+ccl_device_inline float3 operator*=(float3 &a, float f);
+ccl_device_inline float3 operator/=(float3 &a, const float3 &b);
+ccl_device_inline float3 operator/=(float3 &a, float f);
+
+ccl_device_inline bool operator==(const float3 &a, const float3 &b);
+ccl_device_inline bool operator!=(const float3 &a, const float3 &b);
+
+ccl_device_inline float dot(const float3 &a, const float3 &b);
+ccl_device_inline float dot_xy(const float3 &a, const float3 &b);
+ccl_device_inline float3 cross(const float3 &a, const float3 &b);
+ccl_device_inline float3 normalize(const float3 &a);
+ccl_device_inline float3 min(const float3 &a, const float3 &b);
+ccl_device_inline float3 max(const float3 &a, const float3 &b);
+ccl_device_inline float3 clamp(const float3 &a, const float3 &mn, const float3 &mx);
+ccl_device_inline float3 fabs(const float3 &a);
+ccl_device_inline float3 mix(const float3 &a, const float3 &b, float t);
+ccl_device_inline float3 rcp(const float3 &a);
+ccl_device_inline float3 sqrt(const float3 &a);
+#endif /* !__KERNEL_OPENCL__ */
ccl_device_inline float min3(float3 a);
ccl_device_inline float max3(float3 a);
@@ -81,342 +81,345 @@ ccl_device_inline bool isequal_float3(const float3 a, const float3 b);
*/
#ifndef __KERNEL_OPENCL__
-ccl_device_inline float3 operator-(const float3& a)
+ccl_device_inline float3 operator-(const float3 &a)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_xor_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))));
-#else
- return make_float3(-a.x, -a.y, -a.z);
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_xor_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))));
+# else
+ return make_float3(-a.x, -a.y, -a.z);
+# endif
}
-ccl_device_inline float3 operator*(const float3& a, const float3& b)
+ccl_device_inline float3 operator*(const float3 &a, const float3 &b)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_mul_ps(a.m128,b.m128));
-#else
- return make_float3(a.x*b.x, a.y*b.y, a.z*b.z);
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_mul_ps(a.m128, b.m128));
+# else
+ return make_float3(a.x * b.x, a.y * b.y, a.z * b.z);
+# endif
}
-ccl_device_inline float3 operator*(const float3& a, const float f)
+ccl_device_inline float3 operator*(const float3 &a, const float f)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_mul_ps(a.m128,_mm_set1_ps(f)));
-#else
- return make_float3(a.x*f, a.y*f, a.z*f);
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_mul_ps(a.m128, _mm_set1_ps(f)));
+# else
+ return make_float3(a.x * f, a.y * f, a.z * f);
+# endif
}
-ccl_device_inline float3 operator*(const float f, const float3& a)
+ccl_device_inline float3 operator*(const float f, const float3 &a)
{
-#if defined(__KERNEL_SSE__)
- return float3(_mm_mul_ps(_mm_set1_ps(f), a.m128));
-#else
- return make_float3(a.x*f, a.y*f, a.z*f);
-#endif
+# if defined(__KERNEL_SSE__)
+ return float3(_mm_mul_ps(_mm_set1_ps(f), a.m128));
+# else
+ return make_float3(a.x * f, a.y * f, a.z * f);
+# endif
}
-ccl_device_inline float3 operator/(const float f, const float3& a)
+ccl_device_inline float3 operator/(const float f, const float3 &a)
{
-#if defined(__KERNEL_SSE__)
- return float3(_mm_div_ps(_mm_set1_ps(f), a.m128));
-#else
- return make_float3(f / a.x, f / a.y, f / a.z);
-#endif
+# if defined(__KERNEL_SSE__)
+ return float3(_mm_div_ps(_mm_set1_ps(f), a.m128));
+# else
+ return make_float3(f / a.x, f / a.y, f / a.z);
+# endif
}
-ccl_device_inline float3 operator/(const float3& a, const float f)
+ccl_device_inline float3 operator/(const float3 &a, const float f)
{
- float invf = 1.0f/f;
- return a * invf;
+ float invf = 1.0f / f;
+ return a * invf;
}
-ccl_device_inline float3 operator/(const float3& a, const float3& b)
+ccl_device_inline float3 operator/(const float3 &a, const float3 &b)
{
-#if defined(__KERNEL_SSE__)
- return float3(_mm_div_ps(a.m128, b.m128));
-#else
- return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
-#endif
+# if defined(__KERNEL_SSE__)
+ return float3(_mm_div_ps(a.m128, b.m128));
+# else
+ return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
+# endif
}
-ccl_device_inline float3 operator+(const float3& a, const float3& b)
+ccl_device_inline float3 operator+(const float3 &a, const float3 &b)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_add_ps(a.m128, b.m128));
-#else
- return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_add_ps(a.m128, b.m128));
+# else
+ return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
+# endif
}
-ccl_device_inline float3 operator-(const float3& a, const float3& b)
+ccl_device_inline float3 operator-(const float3 &a, const float3 &b)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_sub_ps(a.m128, b.m128));
-#else
- return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_sub_ps(a.m128, b.m128));
+# else
+ return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
+# endif
}
-ccl_device_inline float3 operator+=(float3& a, const float3& b)
+ccl_device_inline float3 operator+=(float3 &a, const float3 &b)
{
- return a = a + b;
+ return a = a + b;
}
-ccl_device_inline float3 operator-=(float3& a, const float3& b)
+ccl_device_inline float3 operator-=(float3 &a, const float3 &b)
{
- return a = a - b;
+ return a = a - b;
}
-ccl_device_inline float3 operator*=(float3& a, const float3& b)
+ccl_device_inline float3 operator*=(float3 &a, const float3 &b)
{
- return a = a * b;
+ return a = a * b;
}
-ccl_device_inline float3 operator*=(float3& a, float f)
+ccl_device_inline float3 operator*=(float3 &a, float f)
{
- return a = a * f;
+ return a = a * f;
}
-ccl_device_inline float3 operator/=(float3& a, const float3& b)
+ccl_device_inline float3 operator/=(float3 &a, const float3 &b)
{
- return a = a / b;
+ return a = a / b;
}
-ccl_device_inline float3 operator/=(float3& a, float f)
+ccl_device_inline float3 operator/=(float3 &a, float f)
{
- float invf = 1.0f/f;
- return a = a * invf;
+ float invf = 1.0f / f;
+ return a = a * invf;
}
-ccl_device_inline bool operator==(const float3& a, const float3& b)
+ccl_device_inline bool operator==(const float3 &a, const float3 &b)
{
-#ifdef __KERNEL_SSE__
- return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 7) == 7;
-#else
- return (a.x == b.x && a.y == b.y && a.z == b.z);
-#endif
+# ifdef __KERNEL_SSE__
+ return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 7) == 7;
+# else
+ return (a.x == b.x && a.y == b.y && a.z == b.z);
+# endif
}
-ccl_device_inline bool operator!=(const float3& a, const float3& b)
+ccl_device_inline bool operator!=(const float3 &a, const float3 &b)
{
- return !(a == b);
+ return !(a == b);
}
-ccl_device_inline float dot(const float3& a, const float3& b)
+ccl_device_inline float dot(const float3 &a, const float3 &b)
{
-#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7F));
-#else
- return a.x*b.x + a.y*b.y + a.z*b.z;
-#endif
+# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+ return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7F));
+# else
+ return a.x * b.x + a.y * b.y + a.z * b.z;
+# endif
}
-ccl_device_inline float dot_xy(const float3& a, const float3& b)
+ccl_device_inline float dot_xy(const float3 &a, const float3 &b)
{
-#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- return _mm_cvtss_f32(_mm_hadd_ps(_mm_mul_ps(a,b),b));
-#else
- return a.x*b.x + a.y*b.y;
-#endif
+# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+ return _mm_cvtss_f32(_mm_hadd_ps(_mm_mul_ps(a, b), b));
+# else
+ return a.x * b.x + a.y * b.y;
+# endif
}
-ccl_device_inline float3 cross(const float3& a, const float3& b)
+ccl_device_inline float3 cross(const float3 &a, const float3 &b)
{
- float3 r = make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
- return r;
+ float3 r = make_float3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
+ return r;
}
-ccl_device_inline float3 normalize(const float3& a)
+ccl_device_inline float3 normalize(const float3 &a)
{
-#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- __m128 norm = _mm_sqrt_ps(_mm_dp_ps(a.m128, a.m128, 0x7F));
- return float3(_mm_div_ps(a.m128, norm));
-#else
- return a/len(a);
-#endif
+# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+ __m128 norm = _mm_sqrt_ps(_mm_dp_ps(a.m128, a.m128, 0x7F));
+ return float3(_mm_div_ps(a.m128, norm));
+# else
+ return a / len(a);
+# endif
}
-ccl_device_inline float3 min(const float3& a, const float3& b)
+ccl_device_inline float3 min(const float3 &a, const float3 &b)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_min_ps(a.m128, b.m128));
-#else
- return make_float3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_min_ps(a.m128, b.m128));
+# else
+ return make_float3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
+# endif
}
-ccl_device_inline float3 max(const float3& a, const float3& b)
+ccl_device_inline float3 max(const float3 &a, const float3 &b)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_max_ps(a.m128, b.m128));
-#else
- return make_float3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_max_ps(a.m128, b.m128));
+# else
+ return make_float3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
+# endif
}
-ccl_device_inline float3 clamp(const float3& a, const float3& mn, const float3& mx)
+ccl_device_inline float3 clamp(const float3 &a, const float3 &mn, const float3 &mx)
{
- return min(max(a, mn), mx);
+ return min(max(a, mn), mx);
}
-ccl_device_inline float3 fabs(const float3& a)
+ccl_device_inline float3 fabs(const float3 &a)
{
-#ifdef __KERNEL_SSE__
- __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
- return float3(_mm_and_ps(a.m128, mask));
-#else
- return make_float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
-#endif
+# ifdef __KERNEL_SSE__
+ __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
+ return float3(_mm_and_ps(a.m128, mask));
+# else
+ return make_float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
+# endif
}
-ccl_device_inline float3 sqrt(const float3& a)
+ccl_device_inline float3 sqrt(const float3 &a)
{
-#ifdef __KERNEL_SSE__
- return float3(_mm_sqrt_ps(a));
-#else
- return make_float3(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z));
-#endif
+# ifdef __KERNEL_SSE__
+ return float3(_mm_sqrt_ps(a));
+# else
+ return make_float3(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z));
+# endif
}
-ccl_device_inline float3 mix(const float3& a, const float3& b, float t)
+ccl_device_inline float3 mix(const float3 &a, const float3 &b, float t)
{
- return a + t*(b - a);
+ return a + t * (b - a);
}
-ccl_device_inline float3 rcp(const float3& a)
+ccl_device_inline float3 rcp(const float3 &a)
{
-#ifdef __KERNEL_SSE__
- /* Don't use _mm_rcp_ps due to poor precision. */
- return float3(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
-#else
- return make_float3(1.0f/a.x, 1.0f/a.y, 1.0f/a.z);
-#endif
+# ifdef __KERNEL_SSE__
+ /* Don't use _mm_rcp_ps due to poor precision. */
+ return float3(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
+# else
+ return make_float3(1.0f / a.x, 1.0f / a.y, 1.0f / a.z);
+# endif
}
-#endif /* !__KERNEL_OPENCL__ */
+#endif /* !__KERNEL_OPENCL__ */
ccl_device_inline float min3(float3 a)
{
- return min(min(a.x, a.y), a.z);
+ return min(min(a.x, a.y), a.z);
}
ccl_device_inline float max3(float3 a)
{
- return max(max(a.x, a.y), a.z);
+ return max(max(a.x, a.y), a.z);
}
ccl_device_inline float len(const float3 a)
{
#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(a.m128, a.m128, 0x7F)));
+ return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(a.m128, a.m128, 0x7F)));
#else
- return sqrtf(dot(a, a));
+ return sqrtf(dot(a, a));
#endif
}
ccl_device_inline float len_squared(const float3 a)
{
- return dot(a, a);
+ return dot(a, a);
}
ccl_device_inline float3 saturate3(float3 a)
{
- return make_float3(saturate(a.x), saturate(a.y), saturate(a.z));
+ return make_float3(saturate(a.x), saturate(a.y), saturate(a.z));
}
ccl_device_inline float3 normalize_len(const float3 a, float *t)
{
- *t = len(a);
- float x = 1.0f / *t;
- return a*x;
+ *t = len(a);
+ float x = 1.0f / *t;
+ return a * x;
}
ccl_device_inline float3 safe_normalize(const float3 a)
{
- float t = len(a);
- return (t != 0.0f)? a * (1.0f/t) : a;
+ float t = len(a);
+ return (t != 0.0f) ? a * (1.0f / t) : a;
}
ccl_device_inline float3 safe_normalize_len(const float3 a, float *t)
{
- *t = len(a);
- return (*t != 0.0f)? a/(*t): a;
+ *t = len(a);
+ return (*t != 0.0f) ? a / (*t) : a;
}
ccl_device_inline float3 interp(float3 a, float3 b, float t)
{
- return a + t*(b - a);
+ return a + t * (b - a);
}
ccl_device_inline bool is_zero(const float3 a)
{
#ifdef __KERNEL_SSE__
- return a == make_float3(0.0f);
+ return a == make_float3(0.0f);
#else
- return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f);
+ return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f);
#endif
}
ccl_device_inline float reduce_add(const float3 a)
{
- return (a.x + a.y + a.z);
+ return (a.x + a.y + a.z);
}
ccl_device_inline float average(const float3 a)
{
- return reduce_add(a)*(1.0f/3.0f);
+ return reduce_add(a) * (1.0f / 3.0f);
}
ccl_device_inline bool isequal_float3(const float3 a, const float3 b)
{
#ifdef __KERNEL_OPENCL__
- return all(a == b);
+ return all(a == b);
#else
- return a == b;
+ return a == b;
#endif
}
ccl_device_inline float3 pow3(float3 v, float e)
{
- return make_float3(powf(v.x, e), powf(v.y, e), powf(v.z, e));
+ return make_float3(powf(v.x, e), powf(v.y, e), powf(v.z, e));
}
ccl_device_inline float3 exp3(float3 v)
{
- return make_float3(expf(v.x), expf(v.y), expf(v.z));
+ return make_float3(expf(v.x), expf(v.y), expf(v.z));
}
ccl_device_inline float3 log3(float3 v)
{
- return make_float3(logf(v.x), logf(v.y), logf(v.z));
+ return make_float3(logf(v.x), logf(v.y), logf(v.z));
}
ccl_device_inline int3 quick_floor_to_int3(const float3 a)
{
#ifdef __KERNEL_SSE__
- int3 b = int3(_mm_cvttps_epi32(a.m128));
- int3 isneg = int3(_mm_castps_si128(_mm_cmplt_ps(a.m128, _mm_set_ps1(0.0f))));
- /* Unsaturated add 0xffffffff is the same as subtract -1. */
- return b + isneg;
+ int3 b = int3(_mm_cvttps_epi32(a.m128));
+ int3 isneg = int3(_mm_castps_si128(_mm_cmplt_ps(a.m128, _mm_set_ps1(0.0f))));
+ /* Unsaturated add 0xffffffff is the same as subtract -1. */
+ return b + isneg;
#else
- return make_int3(quick_floor_to_int(a.x), quick_floor_to_int(a.y), quick_floor_to_int(a.z));
+ return make_int3(quick_floor_to_int(a.x), quick_floor_to_int(a.y), quick_floor_to_int(a.z));
#endif
}
ccl_device_inline bool isfinite3_safe(float3 v)
{
- return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z);
+ return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z);
}
ccl_device_inline float3 ensure_finite3(float3 v)
{
- if(!isfinite_safe(v.x)) v.x = 0.0f;
- if(!isfinite_safe(v.y)) v.y = 0.0f;
- if(!isfinite_safe(v.z)) v.z = 0.0f;
- return v;
+ if (!isfinite_safe(v.x))
+ v.x = 0.0f;
+ if (!isfinite_safe(v.y))
+ v.y = 0.0f;
+ if (!isfinite_safe(v.z))
+ v.z = 0.0f;
+ return v;
}
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_FLOAT3_H__ */
+#endif /* __UTIL_MATH_FLOAT3_H__ */
diff --git a/intern/cycles/util/util_math_float4.h b/intern/cycles/util/util_math_float4.h
index 479ccf202ba..1fb886572e3 100644
--- a/intern/cycles/util/util_math_float4.h
+++ b/intern/cycles/util/util_math_float4.h
@@ -28,433 +28,408 @@ CCL_NAMESPACE_BEGIN
*/
#ifndef __KERNEL_OPENCL__
-ccl_device_inline float4 operator-(const float4& a);
-ccl_device_inline float4 operator*(const float4& a, const float4& b);
-ccl_device_inline float4 operator*(const float4& a, float f);
-ccl_device_inline float4 operator*(float f, const float4& a);
-ccl_device_inline float4 operator/(const float4& a, float f);
-ccl_device_inline float4 operator/(const float4& a, const float4& b);
-ccl_device_inline float4 operator+(const float4& a, const float4& b);
-ccl_device_inline float4 operator-(const float4& a, const float4& b);
-ccl_device_inline float4 operator+=(float4& a, const float4& b);
-ccl_device_inline float4 operator*=(float4& a, const float4& b);
-ccl_device_inline float4 operator*=(float4& a, float f);
-ccl_device_inline float4 operator/=(float4& a, float f);
-
-ccl_device_inline int4 operator<(const float4& a, const float4& b);
-ccl_device_inline int4 operator>=(const float4& a, const float4& b);
-ccl_device_inline int4 operator<=(const float4& a, const float4& b);
-ccl_device_inline bool operator==(const float4& a, const float4& b);
-
-ccl_device_inline float dot(const float4& a, const float4& b);
-ccl_device_inline float len_squared(const float4& a);
-ccl_device_inline float4 rcp(const float4& a);
-ccl_device_inline float4 sqrt(const float4& a);
-ccl_device_inline float4 sqr(const float4& a);
-ccl_device_inline float4 cross(const float4& a, const float4& b);
-ccl_device_inline bool is_zero(const float4& a);
-ccl_device_inline float average(const float4& a);
-ccl_device_inline float len(const float4& a);
-ccl_device_inline float4 normalize(const float4& a);
-ccl_device_inline float4 safe_normalize(const float4& a);
-ccl_device_inline float4 min(const float4& a, const float4& b);
-ccl_device_inline float4 max(const float4& a, const float4& b);
-ccl_device_inline float4 clamp(const float4& a, const float4& mn, const float4& mx);
-ccl_device_inline float4 fabs(const float4& a);
-#endif /* !__KERNEL_OPENCL__*/
+ccl_device_inline float4 operator-(const float4 &a);
+ccl_device_inline float4 operator*(const float4 &a, const float4 &b);
+ccl_device_inline float4 operator*(const float4 &a, float f);
+ccl_device_inline float4 operator*(float f, const float4 &a);
+ccl_device_inline float4 operator/(const float4 &a, float f);
+ccl_device_inline float4 operator/(const float4 &a, const float4 &b);
+ccl_device_inline float4 operator+(const float4 &a, const float4 &b);
+ccl_device_inline float4 operator-(const float4 &a, const float4 &b);
+ccl_device_inline float4 operator+=(float4 &a, const float4 &b);
+ccl_device_inline float4 operator*=(float4 &a, const float4 &b);
+ccl_device_inline float4 operator*=(float4 &a, float f);
+ccl_device_inline float4 operator/=(float4 &a, float f);
+
+ccl_device_inline int4 operator<(const float4 &a, const float4 &b);
+ccl_device_inline int4 operator>=(const float4 &a, const float4 &b);
+ccl_device_inline int4 operator<=(const float4 &a, const float4 &b);
+ccl_device_inline bool operator==(const float4 &a, const float4 &b);
+
+ccl_device_inline float dot(const float4 &a, const float4 &b);
+ccl_device_inline float len_squared(const float4 &a);
+ccl_device_inline float4 rcp(const float4 &a);
+ccl_device_inline float4 sqrt(const float4 &a);
+ccl_device_inline float4 sqr(const float4 &a);
+ccl_device_inline float4 cross(const float4 &a, const float4 &b);
+ccl_device_inline bool is_zero(const float4 &a);
+ccl_device_inline float average(const float4 &a);
+ccl_device_inline float len(const float4 &a);
+ccl_device_inline float4 normalize(const float4 &a);
+ccl_device_inline float4 safe_normalize(const float4 &a);
+ccl_device_inline float4 min(const float4 &a, const float4 &b);
+ccl_device_inline float4 max(const float4 &a, const float4 &b);
+ccl_device_inline float4 clamp(const float4 &a, const float4 &mn, const float4 &mx);
+ccl_device_inline float4 fabs(const float4 &a);
+#endif /* !__KERNEL_OPENCL__*/
#ifdef __KERNEL_SSE__
template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4& b);
+__forceinline const float4 shuffle(const float4 &b);
template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4& a, const float4& b);
+__forceinline const float4 shuffle(const float4 &a, const float4 &b);
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& b);
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &b);
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& a, const float4& b);
-template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4& a, const float4& b);
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &a, const float4 &b);
+template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4 &a, const float4 &b);
# ifdef __KERNEL_SSE3__
-template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4& b);
-template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4& b);
+template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4 &b);
+template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4 &b);
# endif
-#endif /* __KERNEL_SSE__ */
+#endif /* __KERNEL_SSE__ */
#ifndef __KERNEL_GPU__
-ccl_device_inline float4 select(const int4& mask,
- const float4& a,
- const float4& b);
-ccl_device_inline float4 reduce_min(const float4& a);
-ccl_device_inline float4 reduce_max(const float4& a);
-ccl_device_inline float4 reduce_add(const float4& a);
-#endif /* !__KERNEL_GPU__ */
+ccl_device_inline float4 select(const int4 &mask, const float4 &a, const float4 &b);
+ccl_device_inline float4 reduce_min(const float4 &a);
+ccl_device_inline float4 reduce_max(const float4 &a);
+ccl_device_inline float4 reduce_add(const float4 &a);
+#endif /* !__KERNEL_GPU__ */
/*******************************************************************************
* Definition.
*/
#ifndef __KERNEL_OPENCL__
-ccl_device_inline float4 operator-(const float4& a)
+ccl_device_inline float4 operator-(const float4 &a)
{
-#ifdef __KERNEL_SSE__
- __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
- return float4(_mm_xor_ps(a.m128, mask));
-#else
- return make_float4(-a.x, -a.y, -a.z, -a.w);
-#endif
+# ifdef __KERNEL_SSE__
+ __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
+ return float4(_mm_xor_ps(a.m128, mask));
+# else
+ return make_float4(-a.x, -a.y, -a.z, -a.w);
+# endif
}
-ccl_device_inline float4 operator*(const float4& a, const float4& b)
+ccl_device_inline float4 operator*(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_mul_ps(a.m128, b.m128));
-#else
- return make_float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_mul_ps(a.m128, b.m128));
+# else
+ return make_float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
+# endif
}
-ccl_device_inline float4 operator*(const float4& a, float f)
+ccl_device_inline float4 operator*(const float4 &a, float f)
{
-#if defined(__KERNEL_SSE__)
- return a * make_float4(f);
-#else
- return make_float4(a.x*f, a.y*f, a.z*f, a.w*f);
-#endif
+# if defined(__KERNEL_SSE__)
+ return a * make_float4(f);
+# else
+ return make_float4(a.x * f, a.y * f, a.z * f, a.w * f);
+# endif
}
-ccl_device_inline float4 operator*(float f, const float4& a)
+ccl_device_inline float4 operator*(float f, const float4 &a)
{
- return a * f;
+ return a * f;
}
-ccl_device_inline float4 operator/(const float4& a, float f)
+ccl_device_inline float4 operator/(const float4 &a, float f)
{
- return a * (1.0f/f);
+ return a * (1.0f / f);
}
-ccl_device_inline float4 operator/(const float4& a, const float4& b)
+ccl_device_inline float4 operator/(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_div_ps(a.m128, b.m128));
-#else
- return make_float4(a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w);
-#endif
-
+# ifdef __KERNEL_SSE__
+ return float4(_mm_div_ps(a.m128, b.m128));
+# else
+ return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
+# endif
}
-ccl_device_inline float4 operator+(const float4& a, const float4& b)
+ccl_device_inline float4 operator+(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_add_ps(a.m128, b.m128));
-#else
- return make_float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_add_ps(a.m128, b.m128));
+# else
+ return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+# endif
}
-ccl_device_inline float4 operator-(const float4& a, const float4& b)
+ccl_device_inline float4 operator-(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_sub_ps(a.m128, b.m128));
-#else
- return make_float4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_sub_ps(a.m128, b.m128));
+# else
+ return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+# endif
}
-ccl_device_inline float4 operator+=(float4& a, const float4& b)
+ccl_device_inline float4 operator+=(float4 &a, const float4 &b)
{
- return a = a + b;
+ return a = a + b;
}
-ccl_device_inline float4 operator*=(float4& a, const float4& b)
+ccl_device_inline float4 operator*=(float4 &a, const float4 &b)
{
- return a = a * b;
+ return a = a * b;
}
-ccl_device_inline float4 operator*=(float4& a, float f)
+ccl_device_inline float4 operator*=(float4 &a, float f)
{
- return a = a * f;
+ return a = a * f;
}
-ccl_device_inline float4 operator/=(float4& a, float f)
+ccl_device_inline float4 operator/=(float4 &a, float f)
{
- return a = a / f;
+ return a = a / f;
}
-ccl_device_inline int4 operator<(const float4& a, const float4& b)
+ccl_device_inline int4 operator<(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_castps_si128(_mm_cmplt_ps(a.m128, b.m128)));
-#else
- return make_int4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_castps_si128(_mm_cmplt_ps(a.m128, b.m128)));
+# else
+ return make_int4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w);
+# endif
}
-ccl_device_inline int4 operator>=(const float4& a, const float4& b)
+ccl_device_inline int4 operator>=(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_castps_si128(_mm_cmpge_ps(a.m128, b.m128)));
-#else
- return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_castps_si128(_mm_cmpge_ps(a.m128, b.m128)));
+# else
+ return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
+# endif
}
-ccl_device_inline int4 operator<=(const float4& a, const float4& b)
+ccl_device_inline int4 operator<=(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_castps_si128(_mm_cmple_ps(a.m128, b.m128)));
-#else
- return make_int4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_castps_si128(_mm_cmple_ps(a.m128, b.m128)));
+# else
+ return make_int4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w);
+# endif
}
-ccl_device_inline bool operator==(const float4& a, const float4& b)
+ccl_device_inline bool operator==(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 15) == 15;
-#else
- return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 15) == 15;
+# else
+ return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
+# endif
}
-ccl_device_inline float dot(const float4& a, const float4& b)
+ccl_device_inline float dot(const float4 &a, const float4 &b)
{
-#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- return _mm_cvtss_f32(_mm_dp_ps(a, b, 0xFF));
-#else
- return (a.x*b.x + a.y*b.y) + (a.z*b.z + a.w*b.w);
-#endif
+# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+ return _mm_cvtss_f32(_mm_dp_ps(a, b, 0xFF));
+# else
+ return (a.x * b.x + a.y * b.y) + (a.z * b.z + a.w * b.w);
+# endif
}
-ccl_device_inline float len_squared(const float4& a)
+ccl_device_inline float len_squared(const float4 &a)
{
- return dot(a, a);
+ return dot(a, a);
}
-ccl_device_inline float4 rcp(const float4& a)
+ccl_device_inline float4 rcp(const float4 &a)
{
-#ifdef __KERNEL_SSE__
- /* Don't use _mm_rcp_ps due to poor precision. */
- return float4(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
-#else
- return make_float4(1.0f/a.x, 1.0f/a.y, 1.0f/a.z, 1.0f/a.w);
-#endif
+# ifdef __KERNEL_SSE__
+ /* Don't use _mm_rcp_ps due to poor precision. */
+ return float4(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
+# else
+ return make_float4(1.0f / a.x, 1.0f / a.y, 1.0f / a.z, 1.0f / a.w);
+# endif
}
-ccl_device_inline float4 sqrt(const float4& a)
+ccl_device_inline float4 sqrt(const float4 &a)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_sqrt_ps(a.m128));
-#else
- return make_float4(sqrtf(a.x),
- sqrtf(a.y),
- sqrtf(a.z),
- sqrtf(a.w));
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_sqrt_ps(a.m128));
+# else
+ return make_float4(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w));
+# endif
}
-ccl_device_inline float4 sqr(const float4& a)
+ccl_device_inline float4 sqr(const float4 &a)
{
- return a * a;
+ return a * a;
}
-ccl_device_inline float4 cross(const float4& a, const float4& b)
+ccl_device_inline float4 cross(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return (shuffle<1,2,0,0>(a)*shuffle<2,0,1,0>(b)) -
- (shuffle<2,0,1,0>(a)*shuffle<1,2,0,0>(b));
-#else
- return make_float4(a.y*b.z - a.z*b.y,
- a.z*b.x - a.x*b.z,
- a.x*b.y - a.y*b.x,
- 0.0f);
-#endif
+# ifdef __KERNEL_SSE__
+ return (shuffle<1, 2, 0, 0>(a) * shuffle<2, 0, 1, 0>(b)) -
+ (shuffle<2, 0, 1, 0>(a) * shuffle<1, 2, 0, 0>(b));
+# else
+ return make_float4(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x, 0.0f);
+# endif
}
-ccl_device_inline bool is_zero(const float4& a)
+ccl_device_inline bool is_zero(const float4 &a)
{
-#ifdef __KERNEL_SSE__
- return a == make_float4(0.0f);
-#else
- return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
-#endif
+# ifdef __KERNEL_SSE__
+ return a == make_float4(0.0f);
+# else
+ return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
+# endif
}
-ccl_device_inline float4 reduce_add(const float4& a)
+ccl_device_inline float4 reduce_add(const float4 &a)
{
-#ifdef __KERNEL_SSE__
-# ifdef __KERNEL_SSE3__
- float4 h(_mm_hadd_ps(a.m128, a.m128));
- return float4( _mm_hadd_ps(h.m128, h.m128));
+# ifdef __KERNEL_SSE__
+# ifdef __KERNEL_SSE3__
+ float4 h(_mm_hadd_ps(a.m128, a.m128));
+ return float4(_mm_hadd_ps(h.m128, h.m128));
+# else
+ float4 h(shuffle<1, 0, 3, 2>(a) + a);
+ return shuffle<2, 3, 0, 1>(h) + h;
+# endif
# else
- float4 h(shuffle<1,0,3,2>(a) + a);
- return shuffle<2,3,0,1>(h) + h;
+ float sum = (a.x + a.y) + (a.z + a.w);
+ return make_float4(sum, sum, sum, sum);
# endif
-#else
- float sum = (a.x + a.y) + (a.z + a.w);
- return make_float4(sum, sum, sum, sum);
-#endif
}
-ccl_device_inline float average(const float4& a)
+ccl_device_inline float average(const float4 &a)
{
- return reduce_add(a).x * 0.25f;
+ return reduce_add(a).x * 0.25f;
}
-ccl_device_inline float len(const float4& a)
+ccl_device_inline float len(const float4 &a)
{
- return sqrtf(dot(a, a));
+ return sqrtf(dot(a, a));
}
-ccl_device_inline float4 normalize(const float4& a)
+ccl_device_inline float4 normalize(const float4 &a)
{
- return a/len(a);
+ return a / len(a);
}
-ccl_device_inline float4 safe_normalize(const float4& a)
+ccl_device_inline float4 safe_normalize(const float4 &a)
{
- float t = len(a);
- return (t != 0.0f)? a/t: a;
+ float t = len(a);
+ return (t != 0.0f) ? a / t : a;
}
-ccl_device_inline float4 min(const float4& a, const float4& b)
+ccl_device_inline float4 min(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_min_ps(a.m128, b.m128));
-#else
- return make_float4(min(a.x, b.x),
- min(a.y, b.y),
- min(a.z, b.z),
- min(a.w, b.w));
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_min_ps(a.m128, b.m128));
+# else
+ return make_float4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
+# endif
}
-ccl_device_inline float4 max(const float4& a, const float4& b)
+ccl_device_inline float4 max(const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_max_ps(a.m128, b.m128));
-#else
- return make_float4(max(a.x, b.x),
- max(a.y, b.y),
- max(a.z, b.z),
- max(a.w, b.w));
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_max_ps(a.m128, b.m128));
+# else
+ return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
+# endif
}
-ccl_device_inline float4 clamp(const float4& a, const float4& mn, const float4& mx)
+ccl_device_inline float4 clamp(const float4 &a, const float4 &mn, const float4 &mx)
{
- return min(max(a, mn), mx);
+ return min(max(a, mn), mx);
}
-ccl_device_inline float4 fabs(const float4& a)
+ccl_device_inline float4 fabs(const float4 &a)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))));
-#else
- return make_float4(fabsf(a.x),
- fabsf(a.y),
- fabsf(a.z),
- fabsf(a.w));
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))));
+# else
+ return make_float4(fabsf(a.x), fabsf(a.y), fabsf(a.z), fabsf(a.w));
+# endif
}
-#endif /* !__KERNEL_OPENCL__*/
+#endif /* !__KERNEL_OPENCL__*/
#ifdef __KERNEL_SSE__
template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4& b)
+__forceinline const float4 shuffle(const float4 &b)
{
- return float4(_mm_castsi128_ps(
- _mm_shuffle_epi32(_mm_castps_si128(b),
- _MM_SHUFFLE(index_3, index_2, index_1, index_0))));
+ return float4(_mm_castsi128_ps(
+ _mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(index_3, index_2, index_1, index_0))));
}
template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4& a, const float4& b)
+__forceinline const float4 shuffle(const float4 &a, const float4 &b)
{
- return float4(_mm_shuffle_ps(a.m128, b.m128,
- _MM_SHUFFLE(index_3, index_2, index_1, index_0)));
+ return float4(_mm_shuffle_ps(a.m128, b.m128, _MM_SHUFFLE(index_3, index_2, index_1, index_0)));
}
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& b)
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &b)
{
- return float4(_mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(b))));
+ return float4(_mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(b))));
}
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& a, const float4& b)
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &a, const float4 &b)
{
- return float4(_mm_movelh_ps(a.m128, b.m128));
+ return float4(_mm_movelh_ps(a.m128, b.m128));
}
-template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4& a, const float4& b)
+template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4 &a, const float4 &b)
{
- return float4(_mm_movehl_ps(b.m128, a.m128));
+ return float4(_mm_movehl_ps(b.m128, a.m128));
}
# ifdef __KERNEL_SSE3__
-template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4& b)
+template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4 &b)
{
- return float4(_mm_moveldup_ps(b));
+ return float4(_mm_moveldup_ps(b));
}
-template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4& b)
+template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4 &b)
{
- return float4(_mm_movehdup_ps(b));
+ return float4(_mm_movehdup_ps(b));
}
-# endif /* __KERNEL_SSE3__ */
-#endif /* __KERNEL_SSE__ */
+# endif /* __KERNEL_SSE3__ */
+#endif /* __KERNEL_SSE__ */
#ifndef __KERNEL_GPU__
-ccl_device_inline float4 select(const int4& mask,
- const float4& a,
- const float4& b)
+ccl_device_inline float4 select(const int4 &mask, const float4 &a, const float4 &b)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_blendv_ps(b.m128, a.m128, _mm_castsi128_ps(mask.m128)));
-#else
- return make_float4((mask.x)? a.x: b.x,
- (mask.y)? a.y: b.y,
- (mask.z)? a.z: b.z,
- (mask.w)? a.w: b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_blendv_ps(b.m128, a.m128, _mm_castsi128_ps(mask.m128)));
+# else
+ return make_float4(
+ (mask.x) ? a.x : b.x, (mask.y) ? a.y : b.y, (mask.z) ? a.z : b.z, (mask.w) ? a.w : b.w);
+# endif
}
-ccl_device_inline float4 mask(const int4& mask,
- const float4& a)
+ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
{
- /* Replace elements of x with zero where mask isn't set. */
- return select(mask, a, make_float4(0.0f));
+ /* Replace elements of x with zero where mask isn't set. */
+ return select(mask, a, make_float4(0.0f));
}
-ccl_device_inline float4 reduce_min(const float4& a)
+ccl_device_inline float4 reduce_min(const float4 &a)
{
-#ifdef __KERNEL_SSE__
- float4 h = min(shuffle<1,0,3,2>(a), a);
- return min(shuffle<2,3,0,1>(h), h);
-#else
- return make_float4(min(min(a.x, a.y), min(a.z, a.w)));
-#endif
+# ifdef __KERNEL_SSE__
+ float4 h = min(shuffle<1, 0, 3, 2>(a), a);
+ return min(shuffle<2, 3, 0, 1>(h), h);
+# else
+ return make_float4(min(min(a.x, a.y), min(a.z, a.w)));
+# endif
}
-ccl_device_inline float4 reduce_max(const float4& a)
+ccl_device_inline float4 reduce_max(const float4 &a)
{
-#ifdef __KERNEL_SSE__
- float4 h = max(shuffle<1,0,3,2>(a), a);
- return max(shuffle<2,3,0,1>(h), h);
-#else
- return make_float4(max(max(a.x, a.y), max(a.z, a.w)));
-#endif
+# ifdef __KERNEL_SSE__
+ float4 h = max(shuffle<1, 0, 3, 2>(a), a);
+ return max(shuffle<2, 3, 0, 1>(h), h);
+# else
+ return make_float4(max(max(a.x, a.y), max(a.z, a.w)));
+# endif
}
ccl_device_inline float4 load_float4(const float *v)
{
-#ifdef __KERNEL_SSE__
- return float4(_mm_loadu_ps(v));
-#else
- return make_float4(v[0], v[1], v[2], v[3]);
-#endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_loadu_ps(v));
+# else
+ return make_float4(v[0], v[1], v[2], v[3]);
+# endif
}
-#endif /* !__KERNEL_GPU__ */
+#endif /* !__KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_FLOAT4_H__ */
+#endif /* __UTIL_MATH_FLOAT4_H__ */
diff --git a/intern/cycles/util/util_math_int2.h b/intern/cycles/util/util_math_int2.h
index dd401d9a091..0295cd51f7e 100644
--- a/intern/cycles/util/util_math_int2.h
+++ b/intern/cycles/util/util_math_int2.h
@@ -34,7 +34,7 @@ ccl_device_inline int2 operator+=(int2 &a, const int2 &b);
ccl_device_inline int2 operator-(const int2 &a, const int2 &b);
ccl_device_inline int2 operator*(const int2 &a, const int2 &b);
ccl_device_inline int2 operator/(const int2 &a, const int2 &b);
-#endif /* !__KERNEL_OPENCL__ */
+#endif /* !__KERNEL_OPENCL__ */
/*******************************************************************************
* Definition.
@@ -43,35 +43,35 @@ ccl_device_inline int2 operator/(const int2 &a, const int2 &b);
#ifndef __KERNEL_OPENCL__
ccl_device_inline bool operator==(const int2 a, const int2 b)
{
- return (a.x == b.x && a.y == b.y);
+ return (a.x == b.x && a.y == b.y);
}
ccl_device_inline int2 operator+(const int2 &a, const int2 &b)
{
- return make_int2(a.x + b.x, a.y + b.y);
+ return make_int2(a.x + b.x, a.y + b.y);
}
ccl_device_inline int2 operator+=(int2 &a, const int2 &b)
{
- return a = a + b;
+ return a = a + b;
}
ccl_device_inline int2 operator-(const int2 &a, const int2 &b)
{
- return make_int2(a.x - b.x, a.y - b.y);
+ return make_int2(a.x - b.x, a.y - b.y);
}
ccl_device_inline int2 operator*(const int2 &a, const int2 &b)
{
- return make_int2(a.x * b.x, a.y * b.y);
+ return make_int2(a.x * b.x, a.y * b.y);
}
ccl_device_inline int2 operator/(const int2 &a, const int2 &b)
{
- return make_int2(a.x / b.x, a.y / b.y);
+ return make_int2(a.x / b.x, a.y / b.y);
}
-#endif /* !__KERNEL_OPENCL__ */
+#endif /* !__KERNEL_OPENCL__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_INT2_H__ */
+#endif /* __UTIL_MATH_INT2_H__ */
diff --git a/intern/cycles/util/util_math_int3.h b/intern/cycles/util/util_math_int3.h
index 2f4752f90f1..d92ed895dc2 100644
--- a/intern/cycles/util/util_math_int3.h
+++ b/intern/cycles/util/util_math_int3.h
@@ -30,9 +30,9 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_OPENCL__
ccl_device_inline int3 min(int3 a, int3 b);
ccl_device_inline int3 max(int3 a, int3 b);
-ccl_device_inline int3 clamp(const int3& a, int mn, int mx);
-ccl_device_inline int3 clamp(const int3& a, int3& mn, int mx);
-#endif /* !__KERNEL_OPENCL__ */
+ccl_device_inline int3 clamp(const int3 &a, int mn, int mx);
+ccl_device_inline int3 clamp(const int3 &a, int3 &mn, int mx);
+#endif /* !__KERNEL_OPENCL__ */
/*******************************************************************************
* Definition.
@@ -41,76 +41,74 @@ ccl_device_inline int3 clamp(const int3& a, int3& mn, int mx);
#ifndef __KERNEL_OPENCL__
ccl_device_inline int3 min(int3 a, int3 b)
{
-#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
- return int3(_mm_min_epi32(a.m128, b.m128));
-#else
- return make_int3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
-#endif
+# if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
+ return int3(_mm_min_epi32(a.m128, b.m128));
+# else
+ return make_int3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
+# endif
}
ccl_device_inline int3 max(int3 a, int3 b)
{
-#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
- return int3(_mm_max_epi32(a.m128, b.m128));
-#else
- return make_int3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
-#endif
+# if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
+ return int3(_mm_max_epi32(a.m128, b.m128));
+# else
+ return make_int3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
+# endif
}
-ccl_device_inline int3 clamp(const int3& a, int mn, int mx)
+ccl_device_inline int3 clamp(const int3 &a, int mn, int mx)
{
-#ifdef __KERNEL_SSE__
- return min(max(a, make_int3(mn)), make_int3(mx));
-#else
- return make_int3(clamp(a.x, mn, mx), clamp(a.y, mn, mx), clamp(a.z, mn, mx));
-#endif
+# ifdef __KERNEL_SSE__
+ return min(max(a, make_int3(mn)), make_int3(mx));
+# else
+ return make_int3(clamp(a.x, mn, mx), clamp(a.y, mn, mx), clamp(a.z, mn, mx));
+# endif
}
-ccl_device_inline int3 clamp(const int3& a, int3& mn, int mx)
+ccl_device_inline int3 clamp(const int3 &a, int3 &mn, int mx)
{
-#ifdef __KERNEL_SSE__
- return min(max(a, mn), make_int3(mx));
-#else
- return make_int3(clamp(a.x, mn.x, mx),
- clamp(a.y, mn.y, mx),
- clamp(a.z, mn.z, mx));
-#endif
+# ifdef __KERNEL_SSE__
+ return min(max(a, mn), make_int3(mx));
+# else
+ return make_int3(clamp(a.x, mn.x, mx), clamp(a.y, mn.y, mx), clamp(a.z, mn.z, mx));
+# endif
}
ccl_device_inline bool operator==(const int3 &a, const int3 &b)
{
- return a.x == b.x && a.y == b.y && a.z == b.z;
+ return a.x == b.x && a.y == b.y && a.z == b.z;
}
ccl_device_inline bool operator!=(const int3 &a, const int3 &b)
{
- return !(a == b);
+ return !(a == b);
}
ccl_device_inline bool operator<(const int3 &a, const int3 &b)
{
- return a.x < b.x && a.y < b.y && a.z < b.z;
+ return a.x < b.x && a.y < b.y && a.z < b.z;
}
ccl_device_inline int3 operator+(const int3 &a, const int3 &b)
{
-#ifdef __KERNEL_SSE__
- return int3(_mm_add_epi32(a.m128, b.m128));
-#else
- return make_int3(a.x + b.x, a.y + b.y, a.z + b.z);
-#endif
+# ifdef __KERNEL_SSE__
+ return int3(_mm_add_epi32(a.m128, b.m128));
+# else
+ return make_int3(a.x + b.x, a.y + b.y, a.z + b.z);
+# endif
}
ccl_device_inline int3 operator-(const int3 &a, const int3 &b)
{
-#ifdef __KERNEL_SSE__
- return int3(_mm_sub_epi32(a.m128, b.m128));
-#else
- return make_int3(a.x - b.x, a.y - b.y, a.z - b.z);
-#endif
+# ifdef __KERNEL_SSE__
+ return int3(_mm_sub_epi32(a.m128, b.m128));
+# else
+ return make_int3(a.x - b.x, a.y - b.y, a.z - b.z);
+# endif
}
-#endif /* !__KERNEL_OPENCL__ */
+#endif /* !__KERNEL_OPENCL__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_INT3_H__ */
+#endif /* __UTIL_MATH_INT3_H__ */
diff --git a/intern/cycles/util/util_math_int4.h b/intern/cycles/util/util_math_int4.h
index 763c42318d5..186cc58489b 100644
--- a/intern/cycles/util/util_math_int4.h
+++ b/intern/cycles/util/util_math_int4.h
@@ -28,132 +28,129 @@ CCL_NAMESPACE_BEGIN
*/
#ifndef __KERNEL_GPU__
-ccl_device_inline int4 operator+(const int4& a, const int4& b);
-ccl_device_inline int4 operator+=(int4& a, const int4& b);
-ccl_device_inline int4 operator>>(const int4& a, int i);
-ccl_device_inline int4 operator<<(const int4& a, int i);
-ccl_device_inline int4 operator<(const int4& a, const int4& b);
-ccl_device_inline int4 operator>=(const int4& a, const int4& b);
-ccl_device_inline int4 operator&(const int4& a, const int4& b);
+ccl_device_inline int4 operator+(const int4 &a, const int4 &b);
+ccl_device_inline int4 operator+=(int4 &a, const int4 &b);
+ccl_device_inline int4 operator>>(const int4 &a, int i);
+ccl_device_inline int4 operator<<(const int4 &a, int i);
+ccl_device_inline int4 operator<(const int4 &a, const int4 &b);
+ccl_device_inline int4 operator>=(const int4 &a, const int4 &b);
+ccl_device_inline int4 operator&(const int4 &a, const int4 &b);
ccl_device_inline int4 min(int4 a, int4 b);
ccl_device_inline int4 max(int4 a, int4 b);
-ccl_device_inline int4 clamp(const int4& a, const int4& mn, const int4& mx);
-ccl_device_inline int4 select(const int4& mask, const int4& a, const int4& b);
-#endif /* __KERNEL_GPU__ */
+ccl_device_inline int4 clamp(const int4 &a, const int4 &mn, const int4 &mx);
+ccl_device_inline int4 select(const int4 &mask, const int4 &a, const int4 &b);
+#endif /* __KERNEL_GPU__ */
/*******************************************************************************
* Definition.
*/
#ifndef __KERNEL_GPU__
-ccl_device_inline int4 operator+(const int4& a, const int4& b)
+ccl_device_inline int4 operator+(const int4 &a, const int4 &b)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_add_epi32(a.m128, b.m128));
-#else
- return make_int4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_add_epi32(a.m128, b.m128));
+# else
+ return make_int4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+# endif
}
-ccl_device_inline int4 operator+=(int4& a, const int4& b)
+ccl_device_inline int4 operator+=(int4 &a, const int4 &b)
{
- return a = a + b;
+ return a = a + b;
}
-ccl_device_inline int4 operator>>(const int4& a, int i)
+ccl_device_inline int4 operator>>(const int4 &a, int i)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_srai_epi32(a.m128, i));
-#else
- return make_int4(a.x >> i, a.y >> i, a.z >> i, a.w >> i);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_srai_epi32(a.m128, i));
+# else
+ return make_int4(a.x >> i, a.y >> i, a.z >> i, a.w >> i);
+# endif
}
-ccl_device_inline int4 operator<<(const int4& a, int i)
+ccl_device_inline int4 operator<<(const int4 &a, int i)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_slli_epi32(a.m128, i));
-#else
- return make_int4(a.x << i, a.y << i, a.z << i, a.w << i);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_slli_epi32(a.m128, i));
+# else
+ return make_int4(a.x << i, a.y << i, a.z << i, a.w << i);
+# endif
}
-ccl_device_inline int4 operator<(const int4& a, const int4& b)
+ccl_device_inline int4 operator<(const int4 &a, const int4 &b)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_cmplt_epi32(a.m128, b.m128));
-#else
- return make_int4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_cmplt_epi32(a.m128, b.m128));
+# else
+ return make_int4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w);
+# endif
}
-ccl_device_inline int4 operator>=(const int4& a, const int4& b)
+ccl_device_inline int4 operator>=(const int4 &a, const int4 &b)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_xor_si128(_mm_set1_epi32(0xffffffff), _mm_cmplt_epi32(a.m128, b.m128)));
-#else
- return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_xor_si128(_mm_set1_epi32(0xffffffff), _mm_cmplt_epi32(a.m128, b.m128)));
+# else
+ return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
+# endif
}
-ccl_device_inline int4 operator&(const int4& a, const int4& b)
+ccl_device_inline int4 operator&(const int4 &a, const int4 &b)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_and_si128(a.m128, b.m128));
-#else
- return make_int4(a.x & b.x, a.y & b.y, a.z & b.z, a.w & b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_and_si128(a.m128, b.m128));
+# else
+ return make_int4(a.x & b.x, a.y & b.y, a.z & b.z, a.w & b.w);
+# endif
}
ccl_device_inline int4 min(int4 a, int4 b)
{
-#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
- return int4(_mm_min_epi32(a.m128, b.m128));
-#else
- return make_int4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
-#endif
+# if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
+ return int4(_mm_min_epi32(a.m128, b.m128));
+# else
+ return make_int4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
+# endif
}
ccl_device_inline int4 max(int4 a, int4 b)
{
-#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
- return int4(_mm_max_epi32(a.m128, b.m128));
-#else
- return make_int4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
-#endif
+# if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
+ return int4(_mm_max_epi32(a.m128, b.m128));
+# else
+ return make_int4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
+# endif
}
-ccl_device_inline int4 clamp(const int4& a, const int4& mn, const int4& mx)
+ccl_device_inline int4 clamp(const int4 &a, const int4 &mn, const int4 &mx)
{
- return min(max(a, mn), mx);
+ return min(max(a, mn), mx);
}
-ccl_device_inline int4 select(const int4& mask, const int4& a, const int4& b)
+ccl_device_inline int4 select(const int4 &mask, const int4 &a, const int4 &b)
{
-#ifdef __KERNEL_SSE__
- const __m128 m = _mm_cvtepi32_ps(mask);
- /* TODO(sergey): avoid cvt. */
- return int4(_mm_castps_si128(
- _mm_or_ps(_mm_and_ps(m, _mm_castsi128_ps(a)),
- _mm_andnot_ps(m, _mm_castsi128_ps(b)))));
-#else
- return make_int4((mask.x)? a.x: b.x,
- (mask.y)? a.y: b.y,
- (mask.z)? a.z: b.z,
- (mask.w)? a.w: b.w);
-#endif
+# ifdef __KERNEL_SSE__
+ const __m128 m = _mm_cvtepi32_ps(mask);
+ /* TODO(sergey): avoid cvt. */
+ return int4(_mm_castps_si128(
+ _mm_or_ps(_mm_and_ps(m, _mm_castsi128_ps(a)), _mm_andnot_ps(m, _mm_castsi128_ps(b)))));
+# else
+ return make_int4(
+ (mask.x) ? a.x : b.x, (mask.y) ? a.y : b.y, (mask.z) ? a.z : b.z, (mask.w) ? a.w : b.w);
+# endif
}
ccl_device_inline int4 load_int4(const int *v)
{
-#ifdef __KERNEL_SSE__
- return int4(_mm_loadu_si128((__m128i*)v));
-#else
- return make_int4(v[0], v[1], v[2], v[3]);
-#endif
+# ifdef __KERNEL_SSE__
+ return int4(_mm_loadu_si128((__m128i *)v));
+# else
+ return make_int4(v[0], v[1], v[2], v[3]);
+# endif
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_INT4_H__ */
+#endif /* __UTIL_MATH_INT4_H__ */
diff --git a/intern/cycles/util/util_math_intersect.h b/intern/cycles/util/util_math_intersect.h
index aa75783d378..95ac231c611 100644
--- a/intern/cycles/util/util_math_intersect.h
+++ b/intern/cycles/util/util_math_intersect.h
@@ -21,167 +21,175 @@ CCL_NAMESPACE_BEGIN
/* Ray Intersection */
-ccl_device bool ray_sphere_intersect(
- float3 ray_P, float3 ray_D, float ray_t,
- float3 sphere_P, float sphere_radius,
- float3 *isect_P, float *isect_t)
+ccl_device bool ray_sphere_intersect(float3 ray_P,
+ float3 ray_D,
+ float ray_t,
+ float3 sphere_P,
+ float sphere_radius,
+ float3 *isect_P,
+ float *isect_t)
{
- const float3 d = sphere_P - ray_P;
- const float radiussq = sphere_radius*sphere_radius;
- const float tsq = dot(d, d);
-
- if(tsq > radiussq) {
- /* Ray origin outside sphere. */
- const float tp = dot(d, ray_D);
- if(tp < 0.0f) {
- /* Ray points away from sphere. */
- return false;
- }
- const float dsq = tsq - tp*tp; /* pythagoras */
- if(dsq > radiussq) {
- /* Closest point on ray outside sphere. */
- return false;
- }
- const float t = tp - sqrtf(radiussq - dsq); /* pythagoras */
- if(t < ray_t) {
- *isect_t = t;
- *isect_P = ray_P + ray_D*t;
- return true;
- }
- }
- return false;
+ const float3 d = sphere_P - ray_P;
+ const float radiussq = sphere_radius * sphere_radius;
+ const float tsq = dot(d, d);
+
+ if (tsq > radiussq) {
+ /* Ray origin outside sphere. */
+ const float tp = dot(d, ray_D);
+ if (tp < 0.0f) {
+ /* Ray points away from sphere. */
+ return false;
+ }
+ const float dsq = tsq - tp * tp; /* pythagoras */
+ if (dsq > radiussq) {
+ /* Closest point on ray outside sphere. */
+ return false;
+ }
+ const float t = tp - sqrtf(radiussq - dsq); /* pythagoras */
+ if (t < ray_t) {
+ *isect_t = t;
+ *isect_P = ray_P + ray_D * t;
+ return true;
+ }
+ }
+ return false;
}
-ccl_device bool ray_aligned_disk_intersect(
- float3 ray_P, float3 ray_D, float ray_t,
- float3 disk_P, float disk_radius,
- float3 *isect_P, float *isect_t)
+ccl_device bool ray_aligned_disk_intersect(float3 ray_P,
+ float3 ray_D,
+ float ray_t,
+ float3 disk_P,
+ float disk_radius,
+ float3 *isect_P,
+ float *isect_t)
{
- /* Aligned disk normal. */
- float disk_t;
- const float3 disk_N = normalize_len(ray_P - disk_P, &disk_t);
- const float div = dot(ray_D, disk_N);
- if(UNLIKELY(div == 0.0f)) {
- return false;
- }
- /* Compute t to intersection point. */
- const float t = -disk_t/div;
- if(t < 0.0f || t > ray_t) {
- return false;
- }
- /* Test if within radius. */
- float3 P = ray_P + ray_D*t;
- if(len_squared(P - disk_P) > disk_radius*disk_radius) {
- return false;
- }
- *isect_P = P;
- *isect_t = t;
- return true;
+ /* Aligned disk normal. */
+ float disk_t;
+ const float3 disk_N = normalize_len(ray_P - disk_P, &disk_t);
+ const float div = dot(ray_D, disk_N);
+ if (UNLIKELY(div == 0.0f)) {
+ return false;
+ }
+ /* Compute t to intersection point. */
+ const float t = -disk_t / div;
+ if (t < 0.0f || t > ray_t) {
+ return false;
+ }
+ /* Test if within radius. */
+ float3 P = ray_P + ray_D * t;
+ if (len_squared(P - disk_P) > disk_radius * disk_radius) {
+ return false;
+ }
+ *isect_P = P;
+ *isect_t = t;
+ return true;
}
-ccl_device_forceinline bool ray_triangle_intersect(
- float3 ray_P, float3 ray_dir, float ray_t,
+ccl_device_forceinline bool ray_triangle_intersect(float3 ray_P,
+ float3 ray_dir,
+ float ray_t,
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- const ssef *ssef_verts,
+ const ssef *ssef_verts,
#else
- const float3 tri_a, const float3 tri_b, const float3 tri_c,
+ const float3 tri_a,
+ const float3 tri_b,
+ const float3 tri_c,
#endif
- float *isect_u, float *isect_v, float *isect_t)
+ float *isect_u,
+ float *isect_v,
+ float *isect_t)
{
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
- typedef ssef float3;
- const float3 tri_a(ssef_verts[0]);
- const float3 tri_b(ssef_verts[1]);
- const float3 tri_c(ssef_verts[2]);
- const float3 P(ray_P);
- const float3 dir(ray_dir);
+ typedef ssef float3;
+ const float3 tri_a(ssef_verts[0]);
+ const float3 tri_b(ssef_verts[1]);
+ const float3 tri_c(ssef_verts[2]);
+ const float3 P(ray_P);
+ const float3 dir(ray_dir);
#else
# define dot3(a, b) dot(a, b)
- const float3 P = ray_P;
- const float3 dir = ray_dir;
+ const float3 P = ray_P;
+ const float3 dir = ray_dir;
#endif
- /* Calculate vertices relative to ray origin. */
- const float3 v0 = tri_c - P;
- const float3 v1 = tri_a - P;
- const float3 v2 = tri_b - P;
-
- /* Calculate triangle edges. */
- const float3 e0 = v2 - v0;
- const float3 e1 = v0 - v1;
- const float3 e2 = v1 - v2;
-
- /* Perform edge tests. */
-#if defined(__KERNEL_SSE2__) && defined (__KERNEL_SSE__)
- const float3 crossU = cross(v2 + v0, e0);
- const float3 crossV = cross(v0 + v1, e1);
- const float3 crossW = cross(v1 + v2, e2);
-
- ssef crossX(crossU);
- ssef crossY(crossV);
- ssef crossZ(crossW);
- ssef zero = _mm_setzero_ps();
- _MM_TRANSPOSE4_PS(crossX, crossY, crossZ, zero);
-
- const ssef dirX(ray_dir.x);
- const ssef dirY(ray_dir.y);
- const ssef dirZ(ray_dir.z);
-
- ssef UVWW = madd(crossX, dirX, madd(crossY, dirY, crossZ * dirZ));
+ /* Calculate vertices relative to ray origin. */
+ const float3 v0 = tri_c - P;
+ const float3 v1 = tri_a - P;
+ const float3 v2 = tri_b - P;
+
+ /* Calculate triangle edges. */
+ const float3 e0 = v2 - v0;
+ const float3 e1 = v0 - v1;
+ const float3 e2 = v1 - v2;
+
+ /* Perform edge tests. */
+#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
+ const float3 crossU = cross(v2 + v0, e0);
+ const float3 crossV = cross(v0 + v1, e1);
+ const float3 crossW = cross(v1 + v2, e2);
+
+ ssef crossX(crossU);
+ ssef crossY(crossV);
+ ssef crossZ(crossW);
+ ssef zero = _mm_setzero_ps();
+ _MM_TRANSPOSE4_PS(crossX, crossY, crossZ, zero);
+
+ const ssef dirX(ray_dir.x);
+ const ssef dirY(ray_dir.y);
+ const ssef dirZ(ray_dir.z);
+
+ ssef UVWW = madd(crossX, dirX, madd(crossY, dirY, crossZ * dirZ));
#else /* __KERNEL_SSE2__ */
- const float U = dot(cross(v2 + v0, e0), ray_dir);
- const float V = dot(cross(v0 + v1, e1), ray_dir);
- const float W = dot(cross(v1 + v2, e2), ray_dir);
-#endif /* __KERNEL_SSE2__ */
-
-#if defined(__KERNEL_SSE2__) && defined (__KERNEL_SSE__)
- int uvw_sign = movemask(UVWW) & 0x7;
- if(uvw_sign != 0) {
- if(uvw_sign != 0x7) {
- return false;
- }
- }
+ const float U = dot(cross(v2 + v0, e0), ray_dir);
+ const float V = dot(cross(v0 + v1, e1), ray_dir);
+ const float W = dot(cross(v1 + v2, e2), ray_dir);
+#endif /* __KERNEL_SSE2__ */
+
+#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
+ int uvw_sign = movemask(UVWW) & 0x7;
+ if (uvw_sign != 0) {
+ if (uvw_sign != 0x7) {
+ return false;
+ }
+ }
#else
- const float minUVW = min(U, min(V, W));
- const float maxUVW = max(U, max(V, W));
+ const float minUVW = min(U, min(V, W));
+ const float maxUVW = max(U, max(V, W));
- if(minUVW < 0.0f && maxUVW > 0.0f) {
- return false;
- }
+ if (minUVW < 0.0f && maxUVW > 0.0f) {
+ return false;
+ }
#endif
-
- /* Calculate geometry normal and denominator. */
- const float3 Ng1 = cross(e1, e0);
- //const Vec3vfM Ng1 = stable_triangle_normal(e2,e1,e0);
- const float3 Ng = Ng1 + Ng1;
- const float den = dot3(Ng, dir);
- /* Avoid division by 0. */
- if(UNLIKELY(den == 0.0f)) {
- return false;
- }
-
- /* Perform depth test. */
- const float T = dot3(v0, Ng);
- const int sign_den = (__float_as_int(den) & 0x80000000);
- const float sign_T = xor_signmask(T, sign_den);
- if((sign_T < 0.0f) ||
- (sign_T > ray_t * xor_signmask(den, sign_den)))
- {
- return false;
- }
-
- const float inv_den = 1.0f / den;
-#if defined(__KERNEL_SSE2__) && defined (__KERNEL_SSE__)
- UVWW *= inv_den;
- _mm_store_ss(isect_u, UVWW);
- _mm_store_ss(isect_v, shuffle<1,1,3,3>(UVWW));
+ /* Calculate geometry normal and denominator. */
+ const float3 Ng1 = cross(e1, e0);
+ //const Vec3vfM Ng1 = stable_triangle_normal(e2,e1,e0);
+ const float3 Ng = Ng1 + Ng1;
+ const float den = dot3(Ng, dir);
+ /* Avoid division by 0. */
+ if (UNLIKELY(den == 0.0f)) {
+ return false;
+ }
+
+ /* Perform depth test. */
+ const float T = dot3(v0, Ng);
+ const int sign_den = (__float_as_int(den) & 0x80000000);
+ const float sign_T = xor_signmask(T, sign_den);
+ if ((sign_T < 0.0f) || (sign_T > ray_t * xor_signmask(den, sign_den))) {
+ return false;
+ }
+
+ const float inv_den = 1.0f / den;
+#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
+ UVWW *= inv_den;
+ _mm_store_ss(isect_u, UVWW);
+ _mm_store_ss(isect_v, shuffle<1, 1, 3, 3>(UVWW));
#else
- *isect_u = U * inv_den;
- *isect_v = V * inv_den;
+ *isect_u = U * inv_den;
+ *isect_v = V * inv_den;
#endif
- *isect_t = T * inv_den;
- return true;
+ *isect_t = T * inv_den;
+ return true;
#undef dot3
}
@@ -191,40 +199,51 @@ ccl_device_forceinline bool ray_triangle_intersect(
* If ellipse is true, hits outside the ellipse that's enclosed by the
* quad are rejected.
*/
-ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D,
- float ray_mint, float ray_maxt,
+ccl_device bool ray_quad_intersect(float3 ray_P,
+ float3 ray_D,
+ float ray_mint,
+ float ray_maxt,
float3 quad_P,
- float3 quad_u, float3 quad_v, float3 quad_n,
- float3 *isect_P, float *isect_t,
- float *isect_u, float *isect_v, bool ellipse)
+ float3 quad_u,
+ float3 quad_v,
+ float3 quad_n,
+ float3 *isect_P,
+ float *isect_t,
+ float *isect_u,
+ float *isect_v,
+ bool ellipse)
{
- /* Perform intersection test. */
- float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n);
- if(t < ray_mint || t > ray_maxt) {
- return false;
- }
- const float3 hit = ray_P + t*ray_D;
- const float3 inplane = hit - quad_P;
- const float u = dot(inplane, quad_u) / dot(quad_u, quad_u);
- if(u < -0.5f || u > 0.5f) {
- return false;
- }
- const float v = dot(inplane, quad_v) / dot(quad_v, quad_v);
- if(v < -0.5f || v > 0.5f) {
- return false;
- }
- if(ellipse && (u*u + v*v > 0.25f)) {
- return false;
- }
- /* Store the result. */
- /* TODO(sergey): Check whether we can avoid some checks here. */
- if(isect_P != NULL) *isect_P = hit;
- if(isect_t != NULL) *isect_t = t;
- if(isect_u != NULL) *isect_u = u + 0.5f;
- if(isect_v != NULL) *isect_v = v + 0.5f;
- return true;
+ /* Perform intersection test. */
+ float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n);
+ if (t < ray_mint || t > ray_maxt) {
+ return false;
+ }
+ const float3 hit = ray_P + t * ray_D;
+ const float3 inplane = hit - quad_P;
+ const float u = dot(inplane, quad_u) / dot(quad_u, quad_u);
+ if (u < -0.5f || u > 0.5f) {
+ return false;
+ }
+ const float v = dot(inplane, quad_v) / dot(quad_v, quad_v);
+ if (v < -0.5f || v > 0.5f) {
+ return false;
+ }
+ if (ellipse && (u * u + v * v > 0.25f)) {
+ return false;
+ }
+ /* Store the result. */
+ /* TODO(sergey): Check whether we can avoid some checks here. */
+ if (isect_P != NULL)
+ *isect_P = hit;
+ if (isect_t != NULL)
+ *isect_t = t;
+ if (isect_u != NULL)
+ *isect_u = u + 0.5f;
+ if (isect_v != NULL)
+ *isect_v = v + 0.5f;
+ return true;
}
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_INTERSECT_H__ */
+#endif /* __UTIL_MATH_INTERSECT_H__ */
diff --git a/intern/cycles/util/util_math_matrix.h b/intern/cycles/util/util_math_matrix.h
index 9ffcb9659b2..fe80fab6ebd 100644
--- a/intern/cycles/util/util_math_matrix.h
+++ b/intern/cycles/util/util_math_matrix.h
@@ -19,17 +19,17 @@
CCL_NAMESPACE_BEGIN
-#define MAT(A, size, row, col) A[(row)*(size)+(col)]
+#define MAT(A, size, row, col) A[(row) * (size) + (col)]
/* Variants that use a constant stride on GPUS. */
#ifdef __KERNEL_GPU__
-# define MATS(A, n, r, c, s) A[((r)*(n)+(c))*(s)]
+# define MATS(A, n, r, c, s) A[((r) * (n) + (c)) * (s)]
/* Element access when only the lower-triangular elements are stored. */
-# define MATHS(A, r, c, s) A[((r)*((r)+1)/2+(c))*(s)]
-# define VECS(V, i, s) V[(i)*(s)]
+# define MATHS(A, r, c, s) A[((r) * ((r) + 1) / 2 + (c)) * (s)]
+# define VECS(V, i, s) V[(i) * (s)]
#else
# define MATS(A, n, r, c, s) MAT(A, n, r, c)
-# define MATHS(A, r, c, s) A[(r)*((r)+1)/2+(c)]
+# define MATHS(A, r, c, s) A[(r) * ((r) + 1) / 2 + (c)]
# define VECS(V, i, s) V[i]
#endif
@@ -37,111 +37,115 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline void math_vector_zero(float *v, int n)
{
- for(int i = 0; i < n; i++) {
- v[i] = 0.0f;
- }
+ for (int i = 0; i < n; i++) {
+ v[i] = 0.0f;
+ }
}
ccl_device_inline void math_matrix_zero(float *A, int n)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) = 0.0f;
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ MAT(A, n, row, col) = 0.0f;
+ }
+ }
}
/* Elementary vector operations. */
ccl_device_inline void math_vector_add(float *a, const float *ccl_restrict b, int n)
{
- for(int i = 0; i < n; i++) {
- a[i] += b[i];
- }
+ for (int i = 0; i < n; i++) {
+ a[i] += b[i];
+ }
}
ccl_device_inline void math_vector_mul(float *a, const float *ccl_restrict b, int n)
{
- for(int i = 0; i < n; i++) {
- a[i] *= b[i];
- }
+ for (int i = 0; i < n; i++) {
+ a[i] *= b[i];
+ }
}
-ccl_device_inline void math_vector_mul_strided(ccl_global float *a, const float *ccl_restrict b, int astride, int n)
+ccl_device_inline void math_vector_mul_strided(ccl_global float *a,
+ const float *ccl_restrict b,
+ int astride,
+ int n)
{
- for(int i = 0; i < n; i++) {
- a[i*astride] *= b[i];
- }
+ for (int i = 0; i < n; i++) {
+ a[i * astride] *= b[i];
+ }
}
ccl_device_inline void math_vector_scale(float *a, float b, int n)
{
- for(int i = 0; i < n; i++) {
- a[i] *= b;
- }
+ for (int i = 0; i < n; i++) {
+ a[i] *= b;
+ }
}
ccl_device_inline void math_vector_max(float *a, const float *ccl_restrict b, int n)
{
- for(int i = 0; i < n; i++) {
- a[i] = max(a[i], b[i]);
- }
+ for (int i = 0; i < n; i++) {
+ a[i] = max(a[i], b[i]);
+ }
}
ccl_device_inline void math_vec3_add(float3 *v, int n, float *x, float3 w)
{
- for(int i = 0; i < n; i++) {
- v[i] += w*x[i];
- }
+ for (int i = 0; i < n; i++) {
+ v[i] += w * x[i];
+ }
}
-ccl_device_inline void math_vec3_add_strided(ccl_global float3 *v, int n, float *x, float3 w, int stride)
+ccl_device_inline void math_vec3_add_strided(
+ ccl_global float3 *v, int n, float *x, float3 w, int stride)
{
- for(int i = 0; i < n; i++) {
- ccl_global float *elem = (ccl_global float*) (v + i*stride);
- atomic_add_and_fetch_float(elem+0, w.x*x[i]);
- atomic_add_and_fetch_float(elem+1, w.y*x[i]);
- atomic_add_and_fetch_float(elem+2, w.z*x[i]);
- }
+ for (int i = 0; i < n; i++) {
+ ccl_global float *elem = (ccl_global float *)(v + i * stride);
+ atomic_add_and_fetch_float(elem + 0, w.x * x[i]);
+ atomic_add_and_fetch_float(elem + 1, w.y * x[i]);
+ atomic_add_and_fetch_float(elem + 2, w.z * x[i]);
+ }
}
/* Elementary matrix operations.
* Note: TriMatrix refers to a square matrix that is symmetric, and therefore its upper-triangular part isn't stored. */
-ccl_device_inline void math_trimatrix_add_diagonal(ccl_global float *A, int n, float val, int stride)
+ccl_device_inline void math_trimatrix_add_diagonal(ccl_global float *A,
+ int n,
+ float val,
+ int stride)
{
- for(int row = 0; row < n; row++) {
- MATHS(A, row, row, stride) += val;
- }
+ for (int row = 0; row < n; row++) {
+ MATHS(A, row, row, stride) += val;
+ }
}
/* Add Gramian matrix of v to A.
* The Gramian matrix of v is vt*v, so element (i,j) is v[i]*v[j]. */
ccl_device_inline void math_matrix_add_gramian(float *A,
- int n,
- const float *ccl_restrict v,
- float weight)
+ int n,
+ const float *ccl_restrict v,
+ float weight)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) += v[row]*v[col]*weight;
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ MAT(A, n, row, col) += v[row] * v[col] * weight;
+ }
+ }
}
/* Add Gramian matrix of v to A.
* The Gramian matrix of v is vt*v, so element (i,j) is v[i]*v[j]. */
-ccl_device_inline void math_trimatrix_add_gramian_strided(ccl_global float *A,
- int n,
- const float *ccl_restrict v,
- float weight,
- int stride)
+ccl_device_inline void math_trimatrix_add_gramian_strided(
+ ccl_global float *A, int n, const float *ccl_restrict v, float weight, int stride)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- atomic_add_and_fetch_float(&MATHS(A, row, col, stride), v[row]*v[col]*weight);
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ atomic_add_and_fetch_float(&MATHS(A, row, col, stride), v[row] * v[col] * weight);
+ }
+ }
}
ccl_device_inline void math_trimatrix_add_gramian(ccl_global float *A,
@@ -149,23 +153,23 @@ ccl_device_inline void math_trimatrix_add_gramian(ccl_global float *A,
const float *ccl_restrict v,
float weight)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- MATHS(A, row, col, 1) += v[row]*v[col]*weight;
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ MATHS(A, row, col, 1) += v[row] * v[col] * weight;
+ }
+ }
}
/* Transpose matrix A inplace. */
ccl_device_inline void math_matrix_transpose(ccl_global float *A, int n, int stride)
{
- for(int i = 0; i < n; i++) {
- for(int j = 0; j < i; j++) {
- float temp = MATS(A, n, i, j, stride);
- MATS(A, n, i, j, stride) = MATS(A, n, j, i, stride);
- MATS(A, n, j, i, stride) = temp;
- }
- }
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < i; j++) {
+ float temp = MATS(A, n, i, j, stride);
+ MATS(A, n, i, j, stride) = MATS(A, n, j, i, stride);
+ MATS(A, n, j, i, stride) = temp;
+ }
+ }
}
/* Solvers for matrix problems */
@@ -175,21 +179,21 @@ ccl_device_inline void math_matrix_transpose(ccl_global float *A, int n, int str
* Also, only the lower triangular part of A is ever accessed. */
ccl_device void math_trimatrix_cholesky(ccl_global float *A, int n, int stride)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- float sum_col = MATHS(A, row, col, stride);
- for(int k = 0; k < col; k++) {
- sum_col -= MATHS(A, row, k, stride) * MATHS(A, col, k, stride);
- }
- if(row == col) {
- sum_col = sqrtf(max(sum_col, 0.0f));
- }
- else {
- sum_col /= MATHS(A, col, col, stride);
- }
- MATHS(A, row, col, stride) = sum_col;
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ float sum_col = MATHS(A, row, col, stride);
+ for (int k = 0; k < col; k++) {
+ sum_col -= MATHS(A, row, k, stride) * MATHS(A, col, k, stride);
+ }
+ if (row == col) {
+ sum_col = sqrtf(max(sum_col, 0.0f));
+ }
+ else {
+ sum_col /= MATHS(A, col, col, stride);
+ }
+ MATHS(A, row, col, stride) = sum_col;
+ }
+ }
}
/* Solve A*S=y for S given A and y, where A is symmetrical positive-semidefinite and both inputs are destroyed in the process.
@@ -201,29 +205,32 @@ ccl_device void math_trimatrix_cholesky(ccl_global float *A, int n, int stride)
*
* This is useful for solving the normal equation S=inv(Xt*W*X)*Xt*W*y, since Xt*W*X is
* symmetrical positive-semidefinite by construction, so we can just use this function with A=Xt*W*X and y=Xt*W*y. */
-ccl_device_inline void math_trimatrix_vec3_solve(ccl_global float *A, ccl_global float3 *y, int n, int stride)
+ccl_device_inline void math_trimatrix_vec3_solve(ccl_global float *A,
+ ccl_global float3 *y,
+ int n,
+ int stride)
{
- /* Since the first entry of the design row is always 1, the upper-left element of XtWX is a good
- * heuristic for the amount of pixels considered (with weighting), therefore the amount of correction
- * is scaled based on it. */
- math_trimatrix_add_diagonal(A, n, 3e-7f*A[0], stride); /* Improve the numerical stability. */
- math_trimatrix_cholesky(A, n, stride); /* Replace A with L so that L*Lt = A. */
-
- /* Use forward substitution to solve L*b = y, replacing y by b. */
- for(int row = 0; row < n; row++) {
- float3 sum = VECS(y, row, stride);
- for(int col = 0; col < row; col++)
- sum -= MATHS(A, row, col, stride) * VECS(y, col, stride);
- VECS(y, row, stride) = sum / MATHS(A, row, row, stride);
- }
-
- /* Use backward substitution to solve Lt*S = b, replacing b by S. */
- for(int row = n-1; row >= 0; row--) {
- float3 sum = VECS(y, row, stride);
- for(int col = row+1; col < n; col++)
- sum -= MATHS(A, col, row, stride) * VECS(y, col, stride);
- VECS(y, row, stride) = sum / MATHS(A, row, row, stride);
- }
+ /* Since the first entry of the design row is always 1, the upper-left element of XtWX is a good
+ * heuristic for the amount of pixels considered (with weighting), therefore the amount of correction
+ * is scaled based on it. */
+ math_trimatrix_add_diagonal(A, n, 3e-7f * A[0], stride); /* Improve the numerical stability. */
+ math_trimatrix_cholesky(A, n, stride); /* Replace A with L so that L*Lt = A. */
+
+ /* Use forward substitution to solve L*b = y, replacing y by b. */
+ for (int row = 0; row < n; row++) {
+ float3 sum = VECS(y, row, stride);
+ for (int col = 0; col < row; col++)
+ sum -= MATHS(A, row, col, stride) * VECS(y, col, stride);
+ VECS(y, row, stride) = sum / MATHS(A, row, row, stride);
+ }
+
+ /* Use backward substitution to solve Lt*S = b, replacing b by S. */
+ for (int row = n - 1; row >= 0; row--) {
+ float3 sum = VECS(y, row, stride);
+ for (int col = row + 1; col < n; col++)
+ sum -= MATHS(A, col, row, stride) * VECS(y, col, stride);
+ VECS(y, row, stride) = sum / MATHS(A, row, row, stride);
+ }
}
/* Perform the Jacobi Eigenvalue Methon on matrix A.
@@ -234,181 +241,193 @@ ccl_device_inline void math_trimatrix_vec3_solve(ccl_global float *A, ccl_global
* and V will contain the eigenvectors of the original A in its rows (!),
* so that A = V^T*D*V. Therefore, the diagonal elements of D are the (sorted) eigenvalues of A.
*/
-ccl_device void math_matrix_jacobi_eigendecomposition(float *A, ccl_global float *V, int n, int v_stride)
+ccl_device void math_matrix_jacobi_eigendecomposition(float *A,
+ ccl_global float *V,
+ int n,
+ int v_stride)
{
- const float singular_epsilon = 1e-9f;
-
- for(int row = 0; row < n; row++) {
- for(int col = 0; col < n; col++) {
- MATS(V, n, row, col, v_stride) = (col == row) ? 1.0f : 0.0f;
- }
- }
-
- for(int sweep = 0; sweep < 8; sweep++) {
- float off_diagonal = 0.0f;
- for(int row = 1; row < n; row++) {
- for(int col = 0; col < row; col++) {
- off_diagonal += fabsf(MAT(A, n, row, col));
- }
- }
- if(off_diagonal < 1e-7f) {
- /* The matrix has nearly reached diagonal form.
- * Since the eigenvalues are only used to determine truncation, their exact values aren't required - a relative error of a few ULPs won't matter at all. */
- break;
- }
-
- /* Set the threshold for the small element rotation skip in the first sweep:
- * Skip all elements that are less than a tenth of the average off-diagonal element. */
- float threshold = 0.2f*off_diagonal / (n*n);
-
- for(int row = 1; row < n; row++) {
- for(int col = 0; col < row; col++) {
- /* Perform a Jacobi rotation on this element that reduces it to zero. */
- float element = MAT(A, n, row, col);
- float abs_element = fabsf(element);
-
- /* If we're in a later sweep and the element already is very small, just set it to zero and skip the rotation. */
- if(sweep > 3 && abs_element <= singular_epsilon*fabsf(MAT(A, n, row, row)) && abs_element <= singular_epsilon*fabsf(MAT(A, n, col, col))) {
- MAT(A, n, row, col) = 0.0f;
- continue;
- }
-
- if(element == 0.0f) {
- continue;
- }
-
- /* If we're in one of the first sweeps and the element is smaller than the threshold, skip it. */
- if(sweep < 3 && (abs_element < threshold)) {
- continue;
- }
-
- /* Determine rotation: The rotation is characterized by its angle phi - or, in the actual implementation, sin(phi) and cos(phi).
- * To find those, we first compute their ratio - that might be unstable if the angle approaches 90°, so there's a fallback for that case.
- * Then, we compute sin(phi) and cos(phi) themselves. */
- float singular_diff = MAT(A, n, row, row) - MAT(A, n, col, col);
- float ratio;
- if(abs_element > singular_epsilon*fabsf(singular_diff)) {
- float cot_2phi = 0.5f*singular_diff / element;
- ratio = 1.0f / (fabsf(cot_2phi) + sqrtf(1.0f + cot_2phi*cot_2phi));
- if(cot_2phi < 0.0f) ratio = -ratio; /* Copy sign. */
- }
- else {
- ratio = element / singular_diff;
- }
-
- float c = 1.0f / sqrtf(1.0f + ratio*ratio);
- float s = ratio*c;
- /* To improve numerical stability by avoiding cancellation, the update equations are reformulized to use sin(phi) and tan(phi/2) instead. */
- float tan_phi_2 = s / (1.0f + c);
-
- /* Update the singular values in the diagonal. */
- float singular_delta = ratio*element;
- MAT(A, n, row, row) += singular_delta;
- MAT(A, n, col, col) -= singular_delta;
-
- /* Set the element itself to zero. */
- MAT(A, n, row, col) = 0.0f;
-
- /* Perform the actual rotations on the matrices. */
-#define ROT(M, r1, c1, r2, c2, stride) \
- { \
- float M1 = MATS(M, n, r1, c1, stride); \
- float M2 = MATS(M, n, r2, c2, stride); \
- MATS(M, n, r1, c1, stride) -= s*(M2 + tan_phi_2*M1); \
- MATS(M, n, r2, c2, stride) += s*(M1 - tan_phi_2*M2); \
- }
-
- /* Split into three parts to ensure correct accesses since we only store the lower-triangular part of A. */
- for(int i = 0 ; i < col; i++) ROT(A, col, i, row, i, 1);
- for(int i = col+1; i < row; i++) ROT(A, i, col, row, i, 1);
- for(int i = row+1; i < n ; i++) ROT(A, i, col, i, row, 1);
-
- for(int i = 0 ; i < n ; i++) ROT(V, col, i, row, i, v_stride);
+ const float singular_epsilon = 1e-9f;
+
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col < n; col++) {
+ MATS(V, n, row, col, v_stride) = (col == row) ? 1.0f : 0.0f;
+ }
+ }
+
+ for (int sweep = 0; sweep < 8; sweep++) {
+ float off_diagonal = 0.0f;
+ for (int row = 1; row < n; row++) {
+ for (int col = 0; col < row; col++) {
+ off_diagonal += fabsf(MAT(A, n, row, col));
+ }
+ }
+ if (off_diagonal < 1e-7f) {
+ /* The matrix has nearly reached diagonal form.
+ * Since the eigenvalues are only used to determine truncation, their exact values aren't required - a relative error of a few ULPs won't matter at all. */
+ break;
+ }
+
+ /* Set the threshold for the small element rotation skip in the first sweep:
+ * Skip all elements that are less than a tenth of the average off-diagonal element. */
+ float threshold = 0.2f * off_diagonal / (n * n);
+
+ for (int row = 1; row < n; row++) {
+ for (int col = 0; col < row; col++) {
+ /* Perform a Jacobi rotation on this element that reduces it to zero. */
+ float element = MAT(A, n, row, col);
+ float abs_element = fabsf(element);
+
+ /* If we're in a later sweep and the element already is very small, just set it to zero and skip the rotation. */
+ if (sweep > 3 && abs_element <= singular_epsilon * fabsf(MAT(A, n, row, row)) &&
+ abs_element <= singular_epsilon * fabsf(MAT(A, n, col, col))) {
+ MAT(A, n, row, col) = 0.0f;
+ continue;
+ }
+
+ if (element == 0.0f) {
+ continue;
+ }
+
+ /* If we're in one of the first sweeps and the element is smaller than the threshold, skip it. */
+ if (sweep < 3 && (abs_element < threshold)) {
+ continue;
+ }
+
+ /* Determine rotation: The rotation is characterized by its angle phi - or, in the actual implementation, sin(phi) and cos(phi).
+ * To find those, we first compute their ratio - that might be unstable if the angle approaches 90°, so there's a fallback for that case.
+ * Then, we compute sin(phi) and cos(phi) themselves. */
+ float singular_diff = MAT(A, n, row, row) - MAT(A, n, col, col);
+ float ratio;
+ if (abs_element > singular_epsilon * fabsf(singular_diff)) {
+ float cot_2phi = 0.5f * singular_diff / element;
+ ratio = 1.0f / (fabsf(cot_2phi) + sqrtf(1.0f + cot_2phi * cot_2phi));
+ if (cot_2phi < 0.0f)
+ ratio = -ratio; /* Copy sign. */
+ }
+ else {
+ ratio = element / singular_diff;
+ }
+
+ float c = 1.0f / sqrtf(1.0f + ratio * ratio);
+ float s = ratio * c;
+ /* To improve numerical stability by avoiding cancellation, the update equations are reformulized to use sin(phi) and tan(phi/2) instead. */
+ float tan_phi_2 = s / (1.0f + c);
+
+ /* Update the singular values in the diagonal. */
+ float singular_delta = ratio * element;
+ MAT(A, n, row, row) += singular_delta;
+ MAT(A, n, col, col) -= singular_delta;
+
+ /* Set the element itself to zero. */
+ MAT(A, n, row, col) = 0.0f;
+
+ /* Perform the actual rotations on the matrices. */
+#define ROT(M, r1, c1, r2, c2, stride) \
+ { \
+ float M1 = MATS(M, n, r1, c1, stride); \
+ float M2 = MATS(M, n, r2, c2, stride); \
+ MATS(M, n, r1, c1, stride) -= s * (M2 + tan_phi_2 * M1); \
+ MATS(M, n, r2, c2, stride) += s * (M1 - tan_phi_2 * M2); \
+ }
+
+ /* Split into three parts to ensure correct accesses since we only store the lower-triangular part of A. */
+ for (int i = 0; i < col; i++)
+ ROT(A, col, i, row, i, 1);
+ for (int i = col + 1; i < row; i++)
+ ROT(A, i, col, row, i, 1);
+ for (int i = row + 1; i < n; i++)
+ ROT(A, i, col, i, row, 1);
+
+ for (int i = 0; i < n; i++)
+ ROT(V, col, i, row, i, v_stride);
#undef ROT
- }
- }
- }
-
- /* Sort eigenvalues and the associated eigenvectors. */
- for(int i = 0; i < n - 1; i++) {
- float v = MAT(A, n, i, i);
- int k = i;
- for(int j = i; j < n; j++) {
- if(MAT(A, n, j, j) >= v) {
- v = MAT(A, n, j, j);
- k = j;
- }
- }
- if(k != i) {
- /* Swap eigenvalues. */
- MAT(A, n, k, k) = MAT(A, n, i, i);
- MAT(A, n, i, i) = v;
- /* Swap eigenvectors. */
- for(int j = 0; j < n; j++) {
- float v = MATS(V, n, i, j, v_stride);
- MATS(V, n, i, j, v_stride) = MATS(V, n, k, j, v_stride);
- MATS(V, n, k, j, v_stride) = v;
- }
- }
- }
+ }
+ }
+ }
+
+ /* Sort eigenvalues and the associated eigenvectors. */
+ for (int i = 0; i < n - 1; i++) {
+ float v = MAT(A, n, i, i);
+ int k = i;
+ for (int j = i; j < n; j++) {
+ if (MAT(A, n, j, j) >= v) {
+ v = MAT(A, n, j, j);
+ k = j;
+ }
+ }
+ if (k != i) {
+ /* Swap eigenvalues. */
+ MAT(A, n, k, k) = MAT(A, n, i, i);
+ MAT(A, n, i, i) = v;
+ /* Swap eigenvectors. */
+ for (int j = 0; j < n; j++) {
+ float v = MATS(V, n, i, j, v_stride);
+ MATS(V, n, i, j, v_stride) = MATS(V, n, k, j, v_stride);
+ MATS(V, n, k, j, v_stride) = v;
+ }
+ }
+ }
}
#ifdef __KERNEL_SSE3__
ccl_device_inline void math_vector_zero_sse(float4 *A, int n)
{
- for(int i = 0; i < n; i++) {
- A[i] = make_float4(0.0f);
- }
+ for (int i = 0; i < n; i++) {
+ A[i] = make_float4(0.0f);
+ }
}
ccl_device_inline void math_matrix_zero_sse(float4 *A, int n)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) = make_float4(0.0f);
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ MAT(A, n, row, col) = make_float4(0.0f);
+ }
+ }
}
/* Add Gramian matrix of v to A.
* The Gramian matrix of v is v^T*v, so element (i,j) is v[i]*v[j]. */
-ccl_device_inline void math_matrix_add_gramian_sse(float4 *A, int n, const float4 *ccl_restrict v, float4 weight)
+ccl_device_inline void math_matrix_add_gramian_sse(float4 *A,
+ int n,
+ const float4 *ccl_restrict v,
+ float4 weight)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) = MAT(A, n, row, col) + v[row] * v[col] * weight;
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ MAT(A, n, row, col) = MAT(A, n, row, col) + v[row] * v[col] * weight;
+ }
+ }
}
ccl_device_inline void math_vector_add_sse(float4 *V, int n, const float4 *ccl_restrict a)
{
- for(int i = 0; i < n; i++) {
- V[i] += a[i];
- }
+ for (int i = 0; i < n; i++) {
+ V[i] += a[i];
+ }
}
ccl_device_inline void math_vector_mul_sse(float4 *V, int n, const float4 *ccl_restrict a)
{
- for(int i = 0; i < n; i++) {
- V[i] *= a[i];
- }
+ for (int i = 0; i < n; i++) {
+ V[i] *= a[i];
+ }
}
ccl_device_inline void math_vector_max_sse(float4 *a, const float4 *ccl_restrict b, int n)
{
- for(int i = 0; i < n; i++) {
- a[i] = max(a[i], b[i]);
- }
+ for (int i = 0; i < n; i++) {
+ a[i] = max(a[i], b[i]);
+ }
}
ccl_device_inline void math_matrix_hsum(float *A, int n, const float4 *ccl_restrict B)
{
- for(int row = 0; row < n; row++) {
- for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) = reduce_add(MAT(B, n, row, col))[0];
- }
- }
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col <= row; col++) {
+ MAT(A, n, row, col) = reduce_add(MAT(B, n, row, col))[0];
+ }
+ }
}
#endif
@@ -416,4 +435,4 @@ ccl_device_inline void math_matrix_hsum(float *A, int n, const float4 *ccl_restr
CCL_NAMESPACE_END
-#endif /* __UTIL_MATH_MATRIX_H__ */
+#endif /* __UTIL_MATH_MATRIX_H__ */
diff --git a/intern/cycles/util/util_md5.cpp b/intern/cycles/util/util_md5.cpp
index 7cdd28a4793..c11f495f785 100644
--- a/intern/cycles/util/util_md5.cpp
+++ b/intern/cycles/util/util_md5.cpp
@@ -10,11 +10,11 @@
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
+ * misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* L. Peter Deutsch
@@ -34,239 +34,237 @@ CCL_NAMESPACE_BEGIN
#define T_MASK ((uint32_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3 0x242070db
+#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6 0x4787c62a
+#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9 0x698098d8
+#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13 0x6b901122
+#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16 0x49b40821
+#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19 0x265e5a51
+#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22 0x02441453
+#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25 0x21e1cde6
+#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28 0x455a14ed
+#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31 0x676f02d9
+#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35 0x6d9d6122
+#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38 0x4bdecfa9
+#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41 0x289b7ec6
+#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44 0x04881d05
+#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47 0x1fa27cf8
+#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50 0x432aff97
+#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53 0x655b59c3
+#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57 0x6fa87e4f
+#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60 0x4e0811a1
+#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63 0x2ad7d2bb
+#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
void MD5Hash::process(const uint8_t *data /*[64]*/)
{
- uint32_t
- a = abcd[0], b = abcd[1],
- c = abcd[2], d = abcd[3];
- uint32_t t;
- /* Define storage for little-endian or both types of CPUs. */
- uint32_t xbuf[16];
- const uint32_t *X;
-
- {
- /*
- * Determine dynamically whether this is a big-endian or
- * little-endian machine, since we can use a more efficient
- * algorithm on the latter.
- */
- static const int w = 1;
-
- if(*((const uint8_t *)&w)) /* dynamic little-endian */
- {
- /*
- * On little-endian machines, we can process properly aligned
- * data without copying it.
- */
- if(!((data - (const uint8_t *)0) & 3)) {
- /* data are properly aligned */
- X = (const uint32_t *)data;
- }
- else {
- /* not aligned */
- memcpy(xbuf, data, 64);
- X = xbuf;
- }
- }
- else { /* dynamic big-endian */
- /*
- * On big-endian machines, we must arrange the bytes in the
- * right order.
- */
- const uint8_t *xp = data;
- int i;
-
- X = xbuf; /* (dynamic only) */
- for(i = 0; i < 16; ++i, xp += 4)
- xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
- }
- }
+ uint32_t a = abcd[0], b = abcd[1], c = abcd[2], d = abcd[3];
+ uint32_t t;
+ /* Define storage for little-endian or both types of CPUs. */
+ uint32_t xbuf[16];
+ const uint32_t *X;
+
+ {
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const uint8_t *)&w)) /* dynamic little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const uint8_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const uint32_t *)data;
+ }
+ else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+ else { /* dynamic big-endian */
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const uint8_t *xp = data;
+ int i;
+
+ X = xbuf; /* (dynamic only) */
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+ }
+ }
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
- /* Round 1. */
- /* Let [abcd k s i] denote the operation
- * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + F(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 7, T1);
- SET(d, a, b, c, 1, 12, T2);
- SET(c, d, a, b, 2, 17, T3);
- SET(b, c, d, a, 3, 22, T4);
- SET(a, b, c, d, 4, 7, T5);
- SET(d, a, b, c, 5, 12, T6);
- SET(c, d, a, b, 6, 17, T7);
- SET(b, c, d, a, 7, 22, T8);
- SET(a, b, c, d, 8, 7, T9);
- SET(d, a, b, c, 9, 12, T10);
- SET(c, d, a, b, 10, 17, T11);
- SET(b, c, d, a, 11, 22, T12);
- SET(a, b, c, d, 12, 7, T13);
- SET(d, a, b, c, 13, 12, T14);
- SET(c, d, a, b, 14, 17, T15);
- SET(b, c, d, a, 15, 22, T16);
+#define SET(a, b, c, d, k, s, Ti) \
+ t = a + F(b, c, d) + X[k] + Ti; \
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
#undef SET
- /* Round 2. */
- /* Let [abcd k s i] denote the operation
- * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + G(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 1, 5, T17);
- SET(d, a, b, c, 6, 9, T18);
- SET(c, d, a, b, 11, 14, T19);
- SET(b, c, d, a, 0, 20, T20);
- SET(a, b, c, d, 5, 5, T21);
- SET(d, a, b, c, 10, 9, T22);
- SET(c, d, a, b, 15, 14, T23);
- SET(b, c, d, a, 4, 20, T24);
- SET(a, b, c, d, 9, 5, T25);
- SET(d, a, b, c, 14, 9, T26);
- SET(c, d, a, b, 3, 14, T27);
- SET(b, c, d, a, 8, 20, T28);
- SET(a, b, c, d, 13, 5, T29);
- SET(d, a, b, c, 2, 9, T30);
- SET(c, d, a, b, 7, 14, T31);
- SET(b, c, d, a, 12, 20, T32);
+#define SET(a, b, c, d, k, s, Ti) \
+ t = a + G(b, c, d) + X[k] + Ti; \
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
#undef SET
- /* Round 3. */
- /* Let [abcd k s t] denote the operation
- * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + H(b,c,d) + X[k] + Ti;\
+#define SET(a, b, c, d, k, s, Ti) \
+ t = a + H(b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 5, 4, T33);
- SET(d, a, b, c, 8, 11, T34);
- SET(c, d, a, b, 11, 16, T35);
- SET(b, c, d, a, 14, 23, T36);
- SET(a, b, c, d, 1, 4, T37);
- SET(d, a, b, c, 4, 11, T38);
- SET(c, d, a, b, 7, 16, T39);
- SET(b, c, d, a, 10, 23, T40);
- SET(a, b, c, d, 13, 4, T41);
- SET(d, a, b, c, 0, 11, T42);
- SET(c, d, a, b, 3, 16, T43);
- SET(b, c, d, a, 6, 23, T44);
- SET(a, b, c, d, 9, 4, T45);
- SET(d, a, b, c, 12, 11, T46);
- SET(c, d, a, b, 15, 16, T47);
- SET(b, c, d, a, 2, 23, T48);
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
#undef SET
- /* Round 4. */
- /* Let [abcd k s t] denote the operation
- * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + I(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 6, T49);
- SET(d, a, b, c, 7, 10, T50);
- SET(c, d, a, b, 14, 15, T51);
- SET(b, c, d, a, 5, 21, T52);
- SET(a, b, c, d, 12, 6, T53);
- SET(d, a, b, c, 3, 10, T54);
- SET(c, d, a, b, 10, 15, T55);
- SET(b, c, d, a, 1, 21, T56);
- SET(a, b, c, d, 8, 6, T57);
- SET(d, a, b, c, 15, 10, T58);
- SET(c, d, a, b, 6, 15, T59);
- SET(b, c, d, a, 13, 21, T60);
- SET(a, b, c, d, 4, 6, T61);
- SET(d, a, b, c, 11, 10, T62);
- SET(c, d, a, b, 2, 15, T63);
- SET(b, c, d, a, 9, 21, T64);
+#define SET(a, b, c, d, k, s, Ti) \
+ t = a + I(b, c, d) + X[k] + Ti; \
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
#undef SET
- /* Then perform the following additions. (That is increment each
- * of the four registers by the value it had before this block
- * was started.) */
- abcd[0] += a;
- abcd[1] += b;
- abcd[2] += c;
- abcd[3] += d;
+ /* Then perform the following additions. (That is increment each
+ * of the four registers by the value it had before this block
+ * was started.) */
+ abcd[0] += a;
+ abcd[1] += b;
+ abcd[2] += c;
+ abcd[3] += d;
}
MD5Hash::MD5Hash()
{
- count[0] = count[1] = 0;
- abcd[0] = 0x67452301;
- abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
- abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
- abcd[3] = 0x10325476;
+ count[0] = count[1] = 0;
+ abcd[0] = 0x67452301;
+ abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ abcd[3] = 0x10325476;
}
MD5Hash::~MD5Hash()
@@ -275,116 +273,115 @@ MD5Hash::~MD5Hash()
void MD5Hash::append(const uint8_t *data, int nbytes)
{
- const uint8_t *p = data;
- int left = nbytes;
- int offset = (count[0] >> 3) & 63;
- uint32_t nbits = (uint32_t)(nbytes << 3);
-
- if(nbytes <= 0)
- return;
-
- /* Update the message length. */
- count[1] += nbytes >> 29;
- count[0] += nbits;
- if(count[0] < nbits)
- count[1]++;
-
- /* Process an initial partial block. */
- if(offset) {
- int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
- memcpy(buf + offset, p, copy);
- if(offset + copy < 64)
- return;
- p += copy;
- left -= copy;
- process(buf);
- }
-
- /* Process full blocks. */
- for(; left >= 64; p += 64, left -= 64)
- process(p);
-
- /* Process a final partial block. */
- if(left)
- memcpy(buf, p, left);
+ const uint8_t *p = data;
+ int left = nbytes;
+ int offset = (count[0] >> 3) & 63;
+ uint32_t nbits = (uint32_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ count[1] += nbytes >> 29;
+ count[0] += nbits;
+ if (count[0] < nbits)
+ count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ process(buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ process(p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(buf, p, left);
}
-void MD5Hash::append(const string& str)
+void MD5Hash::append(const string &str)
{
- if(str.size()) {
- append((const uint8_t*)str.c_str(), str.size());
- }
+ if (str.size()) {
+ append((const uint8_t *)str.c_str(), str.size());
+ }
}
-bool MD5Hash::append_file(const string& filepath)
+bool MD5Hash::append_file(const string &filepath)
{
- FILE *f = path_fopen(filepath, "rb");
+ FILE *f = path_fopen(filepath, "rb");
- if(!f) {
- fprintf(stderr, "MD5: failed to open file %s\n", filepath.c_str());
- return false;
- }
+ if (!f) {
+ fprintf(stderr, "MD5: failed to open file %s\n", filepath.c_str());
+ return false;
+ }
- const size_t buffer_size = 1024;
- uint8_t buffer[buffer_size];
- size_t n;
+ const size_t buffer_size = 1024;
+ uint8_t buffer[buffer_size];
+ size_t n;
- do {
- n = fread(buffer, 1, buffer_size, f);
- append(buffer, n);
- } while(n == buffer_size);
+ do {
+ n = fread(buffer, 1, buffer_size, f);
+ append(buffer, n);
+ } while (n == buffer_size);
- bool success = (ferror(f) == 0);
+ bool success = (ferror(f) == 0);
- fclose(f);
+ fclose(f);
- return success;
+ return success;
}
void MD5Hash::finish(uint8_t digest[16])
{
- static const uint8_t pad[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- uint8_t data[8];
- int i;
-
- /* Save the length before padding. */
- for(i = 0; i < 8; ++i)
- data[i] = (uint8_t)(count[i >> 2] >> ((i & 3) << 3));
-
- /* Pad to 56 bytes mod 64. */
- append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
- /* Append the length. */
- append(data, 8);
-
- for(i = 0; i < 16; ++i)
- digest[i] = (uint8_t)(abcd[i >> 2] >> ((i & 3) << 3));
+ static const uint8_t pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ uint8_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (uint8_t)(count[i >> 2] >> ((i & 3) << 3));
+
+ /* Pad to 56 bytes mod 64. */
+ append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ append(data, 8);
+
+ for (i = 0; i < 16; ++i)
+ digest[i] = (uint8_t)(abcd[i >> 2] >> ((i & 3) << 3));
}
string MD5Hash::get_hex()
{
- uint8_t digest[16];
- char buf[16*2+1];
+ uint8_t digest[16];
+ char buf[16 * 2 + 1];
- finish(digest);
+ finish(digest);
- for(int i = 0; i < 16; i++)
- sprintf(buf + i*2, "%02X", (unsigned int)digest[i]);
- buf[sizeof(buf)-1] = '\0';
+ for (int i = 0; i < 16; i++)
+ sprintf(buf + i * 2, "%02X", (unsigned int)digest[i]);
+ buf[sizeof(buf) - 1] = '\0';
- return string(buf);
+ return string(buf);
}
-string util_md5_string(const string& str)
+string util_md5_string(const string &str)
{
- MD5Hash md5;
- md5.append((uint8_t*)str.c_str(), str.size());
- return md5.get_hex();
+ MD5Hash md5;
+ md5.append((uint8_t *)str.c_str(), str.size());
+ return md5.get_hex();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_md5.h b/intern/cycles/util/util_md5.h
index f8c0115d8ce..4622945f9d2 100644
--- a/intern/cycles/util/util_md5.h
+++ b/intern/cycles/util/util_md5.h
@@ -36,26 +36,26 @@
CCL_NAMESPACE_BEGIN
class MD5Hash {
-public:
- MD5Hash();
- ~MD5Hash();
-
- void append(const uint8_t *data, int size);
- void append(const string& str);
- bool append_file(const string& filepath);
- string get_hex();
-
-protected:
- void process(const uint8_t *data);
- void finish(uint8_t digest[16]);
-
- uint32_t count[2]; /* message length in bits, lsw first */
- uint32_t abcd[4]; /* digest buffer */
- uint8_t buf[64]; /* accumulate block */
+ public:
+ MD5Hash();
+ ~MD5Hash();
+
+ void append(const uint8_t *data, int size);
+ void append(const string &str);
+ bool append_file(const string &filepath);
+ string get_hex();
+
+ protected:
+ void process(const uint8_t *data);
+ void finish(uint8_t digest[16]);
+
+ uint32_t count[2]; /* message length in bits, lsw first */
+ uint32_t abcd[4]; /* digest buffer */
+ uint8_t buf[64]; /* accumulate block */
};
-string util_md5_string(const string& str);
+string util_md5_string(const string &str);
CCL_NAMESPACE_END
-#endif /* __UTIL_MD5_H__ */
+#endif /* __UTIL_MD5_H__ */
diff --git a/intern/cycles/util/util_murmurhash.cpp b/intern/cycles/util/util_murmurhash.cpp
index 68df8fa1a84..5d728769fe9 100644
--- a/intern/cycles/util/util_murmurhash.cpp
+++ b/intern/cycles/util/util_murmurhash.cpp
@@ -27,15 +27,15 @@
#include "util/util_murmurhash.h"
#if defined(_MSC_VER)
-# define ROTL32(x,y) _rotl(x,y)
-# define ROTL64(x,y) _rotl64(x,y)
+# define ROTL32(x, y) _rotl(x, y)
+# define ROTL64(x, y) _rotl64(x, y)
# define BIG_CONSTANT(x) (x)
#else
ccl_device_inline uint32_t rotl32(uint32_t x, int8_t r)
{
- return (x << r) | (x >> (32 - r));
+ return (x << r) | (x >> (32 - r));
}
-# define ROTL32(x,y) rotl32(x,y)
+# define ROTL32(x, y) rotl32(x, y)
# define BIG_CONSTANT(x) (x##LLU)
#endif
@@ -45,82 +45,82 @@ CCL_NAMESPACE_BEGIN
* handle aligned reads, do the conversion here. */
ccl_device_inline uint32_t mm_hash_getblock32(const uint32_t *p, int i)
{
- return p[i];
+ return p[i];
}
/* Finalization mix - force all bits of a hash block to avalanche */
-ccl_device_inline uint32_t mm_hash_fmix32 ( uint32_t h )
+ccl_device_inline uint32_t mm_hash_fmix32(uint32_t h)
{
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- h ^= h >> 16;
- return h;
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+ return h;
}
uint32_t util_murmur_hash3(const void *key, int len, uint32_t seed)
{
- const uint8_t * data = (const uint8_t*)key;
- const int nblocks = len / 4;
-
- uint32_t h1 = seed;
-
- const uint32_t c1 = 0xcc9e2d51;
- const uint32_t c2 = 0x1b873593;
-
- const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
-
- for(int i = -nblocks; i; i++) {
- uint32_t k1 = mm_hash_getblock32(blocks,i);
-
- k1 *= c1;
- k1 = ROTL32(k1,15);
- k1 *= c2;
-
- h1 ^= k1;
- h1 = ROTL32(h1,13);
- h1 = h1 * 5 + 0xe6546b64;
- }
-
- const uint8_t *tail = (const uint8_t*)(data + nblocks*4);
-
- uint32_t k1 = 0;
-
- switch(len & 3) {
- case 3:
- k1 ^= tail[2] << 16;
- ATTR_FALLTHROUGH;
- case 2:
- k1 ^= tail[1] << 8;
- ATTR_FALLTHROUGH;
- case 1:
- k1 ^= tail[0];
- k1 *= c1;
- k1 = ROTL32(k1,15);
- k1 *= c2;
- h1 ^= k1;
- }
-
- h1 ^= len;
- h1 = mm_hash_fmix32(h1);
- return h1;
+ const uint8_t *data = (const uint8_t *)key;
+ const int nblocks = len / 4;
+
+ uint32_t h1 = seed;
+
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+
+ const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
+
+ for (int i = -nblocks; i; i++) {
+ uint32_t k1 = mm_hash_getblock32(blocks, i);
+
+ k1 *= c1;
+ k1 = ROTL32(k1, 15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = ROTL32(h1, 13);
+ h1 = h1 * 5 + 0xe6546b64;
+ }
+
+ const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
+
+ uint32_t k1 = 0;
+
+ switch (len & 3) {
+ case 3:
+ k1 ^= tail[2] << 16;
+ ATTR_FALLTHROUGH;
+ case 2:
+ k1 ^= tail[1] << 8;
+ ATTR_FALLTHROUGH;
+ case 1:
+ k1 ^= tail[0];
+ k1 *= c1;
+ k1 = ROTL32(k1, 15);
+ k1 *= c2;
+ h1 ^= k1;
+ }
+
+ h1 ^= len;
+ h1 = mm_hash_fmix32(h1);
+ return h1;
}
/* This is taken from the cryptomatte specification 1.0 */
float util_hash_to_float(uint32_t hash)
{
- uint32_t mantissa = hash & (( 1 << 23) - 1);
- uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
- exponent = max(exponent, (uint32_t) 1);
- exponent = min(exponent, (uint32_t) 254);
- exponent = exponent << 23;
- uint32_t sign = (hash >> 31);
- sign = sign << 31;
- uint32_t float_bits = sign | exponent | mantissa;
- float f;
- memcpy(&f, &float_bits, sizeof(uint32_t));
- return f;
+ uint32_t mantissa = hash & ((1 << 23) - 1);
+ uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
+ exponent = max(exponent, (uint32_t)1);
+ exponent = min(exponent, (uint32_t)254);
+ exponent = exponent << 23;
+ uint32_t sign = (hash >> 31);
+ sign = sign << 31;
+ uint32_t float_bits = sign | exponent | mantissa;
+ float f;
+ memcpy(&f, &float_bits, sizeof(uint32_t));
+ return f;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_murmurhash.h b/intern/cycles/util/util_murmurhash.h
index 3e7897d3ae6..2ec87efd87a 100644
--- a/intern/cycles/util/util_murmurhash.h
+++ b/intern/cycles/util/util_murmurhash.h
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
#ifndef __UTIL_MURMURHASH_H__
#define __UTIL_MURMURHASH_H__
@@ -27,4 +26,4 @@ float util_hash_to_float(uint32_t hash);
CCL_NAMESPACE_END
-#endif /* __UTIL_MURMURHASH_H__ */
+#endif /* __UTIL_MURMURHASH_H__ */
diff --git a/intern/cycles/util/util_opengl.h b/intern/cycles/util/util_opengl.h
index 04f0fbaf288..7a8d5eec1f9 100644
--- a/intern/cycles/util/util_opengl.h
+++ b/intern/cycles/util/util_opengl.h
@@ -22,4 +22,4 @@
#include <GL/glew.h>
-#endif /* __UTIL_OPENGL_H__ */
+#endif /* __UTIL_OPENGL_H__ */
diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h
index 5267bd9a97a..46dd883282a 100644
--- a/intern/cycles/util/util_optimization.h
+++ b/intern/cycles/util/util_optimization.h
@@ -23,49 +23,49 @@
*
* Compile a regular, SSE2 and SSE3 kernel. */
-#if defined(i386) || defined(_M_IX86)
+# if defined(i386) || defined(_M_IX86)
/* We require minimum SSE2 support on x86, so auto enable. */
-# define __KERNEL_SSE2__
+# define __KERNEL_SSE2__
-# ifdef WITH_KERNEL_SSE2
-# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
-# endif
+# ifdef WITH_KERNEL_SSE2
+# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
+# endif
-# ifdef WITH_KERNEL_SSE3
-# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
-# endif
+# ifdef WITH_KERNEL_SSE3
+# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
+# endif
-#endif /* defined(i386) || defined(_M_IX86) */
+# endif /* defined(i386) || defined(_M_IX86) */
/* x86-64
*
* Compile a regular (includes SSE2), SSE3, SSE 4.1, AVX and AVX2 kernel. */
-#if defined(__x86_64__) || defined(_M_X64)
+# if defined(__x86_64__) || defined(_M_X64)
/* SSE2 is always available on x86-64 CPUs, so auto enable */
-# define __KERNEL_SSE2__
+# define __KERNEL_SSE2__
/* no SSE2 kernel on x86-64, part of regular kernel */
-# ifdef WITH_KERNEL_SSE3
-# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
-# endif
+# ifdef WITH_KERNEL_SSE3
+# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
+# endif
-# ifdef WITH_KERNEL_SSE41
-# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
-# endif
+# ifdef WITH_KERNEL_SSE41
+# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
+# endif
-# ifdef WITH_KERNEL_AVX
-# define WITH_CYCLES_OPTIMIZED_KERNEL_AVX
-# endif
+# ifdef WITH_KERNEL_AVX
+# define WITH_CYCLES_OPTIMIZED_KERNEL_AVX
+# endif
-# ifdef WITH_KERNEL_AVX2
-# define WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
-# endif
+# ifdef WITH_KERNEL_AVX2
+# define WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
+# endif
-#endif /* defined(__x86_64__) || defined(_M_X64) */
+# endif /* defined(__x86_64__) || defined(_M_X64) */
#endif
-#endif /* __UTIL_OPTIMIZATION_H__ */
+#endif /* __UTIL_OPTIMIZATION_H__ */
diff --git a/intern/cycles/util/util_param.h b/intern/cycles/util/util_param.h
index 03815486429..cfbe416aba1 100644
--- a/intern/cycles/util/util_param.h
+++ b/intern/cycles/util/util_param.h
@@ -32,4 +32,4 @@ static constexpr TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2);
CCL_NAMESPACE_END
-#endif /* __UTIL_PARAM_H__ */
+#endif /* __UTIL_PARAM_H__ */
diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp
index 93080a6c80c..77293c45f6b 100644
--- a/intern/cycles/util/util_path.cpp
+++ b/intern/cycles/util/util_path.cpp
@@ -58,7 +58,7 @@ typedef struct _stati64 path_stat_t;
typedef struct _stat path_stat_t;
# endif
# ifndef S_ISDIR
-# define S_ISDIR(x) (((x) & _S_IFDIR) == _S_IFDIR)
+# define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
# endif
#else
typedef struct stat path_stat_t;
@@ -72,918 +72,870 @@ namespace {
#ifdef _WIN32
class directory_iterator {
-public:
- class path_info {
- public:
- path_info(const string& path,
- const WIN32_FIND_DATAW& find_data)
- : path_(path),
- find_data_(find_data)
- {
- }
-
- string path() {
- return path_join(path_, string_from_wstring(find_data_.cFileName));
- }
- protected:
- const string& path_;
- const WIN32_FIND_DATAW& find_data_;
- };
-
- directory_iterator()
- : path_info_("", find_data_),
- h_find_(INVALID_HANDLE_VALUE)
- {
- }
-
- explicit directory_iterator(const string& path)
- : path_(path),
- path_info_(path, find_data_)
- {
- string wildcard = path;
- if(wildcard[wildcard.size() - 1] != DIR_SEP) {
- wildcard += DIR_SEP;
- }
- wildcard += "*";
- h_find_ = FindFirstFileW(string_to_wstring(wildcard).c_str(),
- &find_data_);
- if(h_find_ != INVALID_HANDLE_VALUE) {
- skip_dots();
- }
- }
-
- ~directory_iterator()
- {
- if(h_find_ != INVALID_HANDLE_VALUE) {
- FindClose(h_find_);
- }
- }
-
- directory_iterator& operator++()
- {
- step();
- return *this;
- }
-
- path_info* operator-> ()
- {
- return &path_info_;
- }
-
- bool operator!=(const directory_iterator& other)
- {
- return h_find_ != other.h_find_;
- }
-
-protected:
- bool step()
- {
- if(do_step()) {
- return skip_dots();
- }
- return false;
- }
-
- bool do_step()
- {
- if(h_find_ != INVALID_HANDLE_VALUE) {
- bool result = FindNextFileW(h_find_, &find_data_) == TRUE;
- if(!result) {
- FindClose(h_find_);
- h_find_ = INVALID_HANDLE_VALUE;
- }
- return result;
- }
- return false;
- }
-
- bool skip_dots()
- {
- while(wcscmp(find_data_.cFileName, L".") == 0 ||
- wcscmp(find_data_.cFileName, L"..") == 0)
- {
- if(!do_step()) {
- return false;
- }
- }
- return true;
- }
-
- string path_;
- path_info path_info_;
- WIN32_FIND_DATAW find_data_;
- HANDLE h_find_;
+ public:
+ class path_info {
+ public:
+ path_info(const string &path, const WIN32_FIND_DATAW &find_data)
+ : path_(path), find_data_(find_data)
+ {
+ }
+
+ string path()
+ {
+ return path_join(path_, string_from_wstring(find_data_.cFileName));
+ }
+
+ protected:
+ const string &path_;
+ const WIN32_FIND_DATAW &find_data_;
+ };
+
+ directory_iterator() : path_info_("", find_data_), h_find_(INVALID_HANDLE_VALUE)
+ {
+ }
+
+ explicit directory_iterator(const string &path) : path_(path), path_info_(path, find_data_)
+ {
+ string wildcard = path;
+ if (wildcard[wildcard.size() - 1] != DIR_SEP) {
+ wildcard += DIR_SEP;
+ }
+ wildcard += "*";
+ h_find_ = FindFirstFileW(string_to_wstring(wildcard).c_str(), &find_data_);
+ if (h_find_ != INVALID_HANDLE_VALUE) {
+ skip_dots();
+ }
+ }
+
+ ~directory_iterator()
+ {
+ if (h_find_ != INVALID_HANDLE_VALUE) {
+ FindClose(h_find_);
+ }
+ }
+
+ directory_iterator &operator++()
+ {
+ step();
+ return *this;
+ }
+
+ path_info *operator->()
+ {
+ return &path_info_;
+ }
+
+ bool operator!=(const directory_iterator &other)
+ {
+ return h_find_ != other.h_find_;
+ }
+
+ protected:
+ bool step()
+ {
+ if (do_step()) {
+ return skip_dots();
+ }
+ return false;
+ }
+
+ bool do_step()
+ {
+ if (h_find_ != INVALID_HANDLE_VALUE) {
+ bool result = FindNextFileW(h_find_, &find_data_) == TRUE;
+ if (!result) {
+ FindClose(h_find_);
+ h_find_ = INVALID_HANDLE_VALUE;
+ }
+ return result;
+ }
+ return false;
+ }
+
+ bool skip_dots()
+ {
+ while (wcscmp(find_data_.cFileName, L".") == 0 || wcscmp(find_data_.cFileName, L"..") == 0) {
+ if (!do_step()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ string path_;
+ path_info path_info_;
+ WIN32_FIND_DATAW find_data_;
+ HANDLE h_find_;
};
-#else /* _WIN32 */
+#else /* _WIN32 */
class directory_iterator {
-public:
- class path_info {
- public:
- explicit path_info(const string& path)
- : path_(path),
- entry_(NULL)
- {
- }
-
- string path() {
- return path_join(path_, entry_->d_name);
- }
-
- void current_entry_set(const struct dirent *entry)
- {
- entry_ = entry;
- }
- protected:
- const string& path_;
- const struct dirent *entry_;
- };
-
- directory_iterator()
- : path_info_(""),
- name_list_(NULL),
- num_entries_(-1),
- cur_entry_(-1)
- {
- }
-
- explicit directory_iterator(const string& path)
- : path_(path),
- path_info_(path_),
- cur_entry_(0)
- {
- num_entries_ = scandir(path.c_str(),
- &name_list_,
- NULL,
- alphasort);
- if(num_entries_ < 0) {
- perror("scandir");
- }
- else {
- skip_dots();
- }
- }
-
- ~directory_iterator()
- {
- destroy_name_list();
- }
-
- directory_iterator& operator++()
- {
- step();
- return *this;
- }
-
- path_info* operator-> ()
- {
- path_info_.current_entry_set(name_list_[cur_entry_]);
- return &path_info_;
- }
-
- bool operator!=(const directory_iterator& other)
- {
- return name_list_ != other.name_list_;
- }
-
-protected:
- bool step()
- {
- if(do_step()) {
- return skip_dots();
- }
- return false;
- }
-
- bool do_step()
- {
- ++cur_entry_;
- if(cur_entry_ >= num_entries_) {
- destroy_name_list();
- return false;
- }
- return true;
- }
-
- /* Skip . and .. folders. */
- bool skip_dots()
- {
- while(strcmp(name_list_[cur_entry_]->d_name, ".") == 0 ||
- strcmp(name_list_[cur_entry_]->d_name, "..") == 0)
- {
- if(!step()) {
- return false;
- }
- }
- return true;
- }
-
- void destroy_name_list()
- {
- if(name_list_ == NULL) {
- return;
- }
- for(int i = 0; i < num_entries_; ++i) {
- free(name_list_[i]);
- }
- free(name_list_);
- name_list_ = NULL;
- }
-
- string path_;
- path_info path_info_;
- struct dirent **name_list_;
- int num_entries_, cur_entry_;
+ public:
+ class path_info {
+ public:
+ explicit path_info(const string &path) : path_(path), entry_(NULL)
+ {
+ }
+
+ string path()
+ {
+ return path_join(path_, entry_->d_name);
+ }
+
+ void current_entry_set(const struct dirent *entry)
+ {
+ entry_ = entry;
+ }
+
+ protected:
+ const string &path_;
+ const struct dirent *entry_;
+ };
+
+ directory_iterator() : path_info_(""), name_list_(NULL), num_entries_(-1), cur_entry_(-1)
+ {
+ }
+
+ explicit directory_iterator(const string &path) : path_(path), path_info_(path_), cur_entry_(0)
+ {
+ num_entries_ = scandir(path.c_str(), &name_list_, NULL, alphasort);
+ if (num_entries_ < 0) {
+ perror("scandir");
+ }
+ else {
+ skip_dots();
+ }
+ }
+
+ ~directory_iterator()
+ {
+ destroy_name_list();
+ }
+
+ directory_iterator &operator++()
+ {
+ step();
+ return *this;
+ }
+
+ path_info *operator->()
+ {
+ path_info_.current_entry_set(name_list_[cur_entry_]);
+ return &path_info_;
+ }
+
+ bool operator!=(const directory_iterator &other)
+ {
+ return name_list_ != other.name_list_;
+ }
+
+ protected:
+ bool step()
+ {
+ if (do_step()) {
+ return skip_dots();
+ }
+ return false;
+ }
+
+ bool do_step()
+ {
+ ++cur_entry_;
+ if (cur_entry_ >= num_entries_) {
+ destroy_name_list();
+ return false;
+ }
+ return true;
+ }
+
+ /* Skip . and .. folders. */
+ bool skip_dots()
+ {
+ while (strcmp(name_list_[cur_entry_]->d_name, ".") == 0 ||
+ strcmp(name_list_[cur_entry_]->d_name, "..") == 0) {
+ if (!step()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void destroy_name_list()
+ {
+ if (name_list_ == NULL) {
+ return;
+ }
+ for (int i = 0; i < num_entries_; ++i) {
+ free(name_list_[i]);
+ }
+ free(name_list_);
+ name_list_ = NULL;
+ }
+
+ string path_;
+ path_info path_info_;
+ struct dirent **name_list_;
+ int num_entries_, cur_entry_;
};
-#endif /* _WIN32 */
+#endif /* _WIN32 */
-size_t find_last_slash(const string& path)
+size_t find_last_slash(const string &path)
{
- for(size_t i = 0; i < path.size(); ++i) {
- size_t index = path.size() - 1 - i;
+ for (size_t i = 0; i < path.size(); ++i) {
+ size_t index = path.size() - 1 - i;
#ifdef _WIN32
- if(path[index] == DIR_SEP || path[index] == DIR_SEP_ALT)
+ if (path[index] == DIR_SEP || path[index] == DIR_SEP_ALT)
#else
- if(path[index] == DIR_SEP)
+ if (path[index] == DIR_SEP)
#endif
- {
- return index;
- }
- }
- return string::npos;
-}
-
-} /* namespace */
-
-static char *path_specials(const string& sub)
-{
- static bool env_init = false;
- static char *env_shader_path;
- static char *env_source_path;
- if(!env_init) {
- env_shader_path = getenv("CYCLES_SHADER_PATH");
- /* NOTE: It is KERNEL in env variable for compatibility reasons. */
- env_source_path = getenv("CYCLES_KERNEL_PATH");
- env_init = true;
- }
- if(env_shader_path != NULL && sub == "shader") {
- return env_shader_path;
- }
- else if(env_shader_path != NULL && sub == "source") {
- return env_source_path;
- }
- return NULL;
+ {
+ return index;
+ }
+ }
+ return string::npos;
+}
+
+} /* namespace */
+
+static char *path_specials(const string &sub)
+{
+ static bool env_init = false;
+ static char *env_shader_path;
+ static char *env_source_path;
+ if (!env_init) {
+ env_shader_path = getenv("CYCLES_SHADER_PATH");
+ /* NOTE: It is KERNEL in env variable for compatibility reasons. */
+ env_source_path = getenv("CYCLES_KERNEL_PATH");
+ env_init = true;
+ }
+ if (env_shader_path != NULL && sub == "shader") {
+ return env_shader_path;
+ }
+ else if (env_shader_path != NULL && sub == "source") {
+ return env_source_path;
+ }
+ return NULL;
}
#if defined(__linux__) || defined(__APPLE__)
static string path_xdg_cache_get()
{
- const char *home = getenv("XDG_CACHE_HOME");
- if(home) {
- return string(home);
- }
- else {
- home = getenv("HOME");
- if(home == NULL) {
- home = getpwuid(getuid())->pw_dir;
- }
- return path_join(string(home), ".cache");
- }
+ const char *home = getenv("XDG_CACHE_HOME");
+ if (home) {
+ return string(home);
+ }
+ else {
+ home = getenv("HOME");
+ if (home == NULL) {
+ home = getpwuid(getuid())->pw_dir;
+ }
+ return path_join(string(home), ".cache");
+ }
}
#endif
-void path_init(const string& path, const string& user_path)
+void path_init(const string &path, const string &user_path)
{
- cached_path = path;
- cached_user_path = user_path;
+ cached_path = path;
+ cached_user_path = user_path;
#ifdef _MSC_VER
- // workaround for https://svn.boost.org/trac/boost/ticket/6320
- // indirectly init boost codec here since it's not thread safe, and can
- // cause crashes when it happens in multithreaded image load
- OIIO::Filesystem::exists(path);
+ // workaround for https://svn.boost.org/trac/boost/ticket/6320
+ // indirectly init boost codec here since it's not thread safe, and can
+ // cause crashes when it happens in multithreaded image load
+ OIIO::Filesystem::exists(path);
#endif
}
-string path_get(const string& sub)
+string path_get(const string &sub)
{
- char *special = path_specials(sub);
- if(special != NULL)
- return special;
+ char *special = path_specials(sub);
+ if (special != NULL)
+ return special;
- if(cached_path == "")
- cached_path = path_dirname(Sysutil::this_program_path());
+ if (cached_path == "")
+ cached_path = path_dirname(Sysutil::this_program_path());
- return path_join(cached_path, sub);
+ return path_join(cached_path, sub);
}
-string path_user_get(const string& sub)
+string path_user_get(const string &sub)
{
- if(cached_user_path == "")
- cached_user_path = path_dirname(Sysutil::this_program_path());
+ if (cached_user_path == "")
+ cached_user_path = path_dirname(Sysutil::this_program_path());
- return path_join(cached_user_path, sub);
+ return path_join(cached_user_path, sub);
}
-string path_cache_get(const string& sub)
+string path_cache_get(const string &sub)
{
#if defined(__linux__) || defined(__APPLE__)
- if(cached_xdg_cache_path == "") {
- cached_xdg_cache_path = path_xdg_cache_get();
- }
- string result = path_join(cached_xdg_cache_path, "cycles");
- return path_join(result, sub);
+ if (cached_xdg_cache_path == "") {
+ cached_xdg_cache_path = path_xdg_cache_get();
+ }
+ string result = path_join(cached_xdg_cache_path, "cycles");
+ return path_join(result, sub);
#else
- /* TODO(sergey): What that should be on Windows? */
- return path_user_get(path_join("cache", sub));
+ /* TODO(sergey): What that should be on Windows? */
+ return path_user_get(path_join("cache", sub));
#endif
}
#if defined(__linux__) || defined(__APPLE__)
-string path_xdg_home_get(const string& sub = "");
+string path_xdg_home_get(const string &sub = "");
#endif
-string path_filename(const string& path)
+string path_filename(const string &path)
{
- size_t index = find_last_slash(path);
- if(index != string::npos) {
- /* Corner cases to match boost behavior. */
+ size_t index = find_last_slash(path);
+ if (index != string::npos) {
+ /* Corner cases to match boost behavior. */
#ifndef _WIN32
- if(index == 0 && path.size() == 1) {
- return path;
- }
+ if (index == 0 && path.size() == 1) {
+ return path;
+ }
#endif
- if(index == path.size() - 1) {
+ if (index == path.size() - 1) {
#ifdef _WIN32
- if(index == 2) {
- return string(1, DIR_SEP);
- }
+ if (index == 2) {
+ return string(1, DIR_SEP);
+ }
#endif
- return ".";
- }
- return path.substr(index + 1, path.size() - index - 1);
- }
- return path;
+ return ".";
+ }
+ return path.substr(index + 1, path.size() - index - 1);
+ }
+ return path;
}
-string path_dirname(const string& path)
+string path_dirname(const string &path)
{
- size_t index = find_last_slash(path);
- if(index != string::npos) {
+ size_t index = find_last_slash(path);
+ if (index != string::npos) {
#ifndef _WIN32
- if(index == 0 && path.size() > 1) {
- return string(1, DIR_SEP);
- }
+ if (index == 0 && path.size() > 1) {
+ return string(1, DIR_SEP);
+ }
#endif
- return path.substr(0, index);
- }
- return "";
+ return path.substr(0, index);
+ }
+ return "";
}
-string path_join(const string& dir, const string& file)
+string path_join(const string &dir, const string &file)
{
- if(dir.size() == 0) {
- return file;
- }
- if(file.size() == 0) {
- return dir;
- }
- string result = dir;
+ if (dir.size() == 0) {
+ return file;
+ }
+ if (file.size() == 0) {
+ return dir;
+ }
+ string result = dir;
#ifndef _WIN32
- if(result[result.size() - 1] != DIR_SEP &&
- file[0] != DIR_SEP)
+ if (result[result.size() - 1] != DIR_SEP && file[0] != DIR_SEP)
#else
- if(result[result.size() - 1] != DIR_SEP &&
- result[result.size() - 1] != DIR_SEP_ALT &&
- file[0] != DIR_SEP &&
- file[0] != DIR_SEP_ALT)
+ if (result[result.size() - 1] != DIR_SEP && result[result.size() - 1] != DIR_SEP_ALT &&
+ file[0] != DIR_SEP && file[0] != DIR_SEP_ALT)
#endif
- {
- result += DIR_SEP;
- }
- result += file;
- return result;
+ {
+ result += DIR_SEP;
+ }
+ result += file;
+ return result;
}
-string path_escape(const string& path)
+string path_escape(const string &path)
{
- string result = path;
- string_replace(result, " ", "\\ ");
- return result;
+ string result = path;
+ string_replace(result, " ", "\\ ");
+ return result;
}
-bool path_is_relative(const string& path)
+bool path_is_relative(const string &path)
{
#ifdef _WIN32
# ifdef HAVE_SHLWAPI_H
- return PathIsRelative(path.c_str());
+ return PathIsRelative(path.c_str());
# else /* HAVE_SHLWAPI_H */
- if(path.size() >= 3) {
- return !(((path[0] >= 'a' && path[0] <= 'z') ||
- (path[0] >= 'A' && path[0] <= 'Z')) &&
- path[1] == ':' && path[2] == DIR_SEP);
- }
- return true;
-# endif /* HAVE_SHLWAPI_H */
-#else /* _WIN32 */
- if(path.size() == 0) {
- return 1;
- }
- return path[0] != DIR_SEP;
-#endif /* _WIN32 */
+ if (path.size() >= 3) {
+ return !(((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z')) &&
+ path[1] == ':' && path[2] == DIR_SEP);
+ }
+ return true;
+# endif /* HAVE_SHLWAPI_H */
+#else /* _WIN32 */
+ if (path.size() == 0) {
+ return 1;
+ }
+ return path[0] != DIR_SEP;
+#endif /* _WIN32 */
}
#ifdef _WIN32
/* Add a slash if the UNC path points to a share. */
-static string path_unc_add_slash_to_share(const string& path)
+static string path_unc_add_slash_to_share(const string &path)
{
- size_t slash_after_server = path.find(DIR_SEP, 2);
- if(slash_after_server != string::npos) {
- size_t slash_after_share = path.find(DIR_SEP,
- slash_after_server + 1);
- if(slash_after_share == string::npos) {
- return path + DIR_SEP;
- }
- }
- return path;
+ size_t slash_after_server = path.find(DIR_SEP, 2);
+ if (slash_after_server != string::npos) {
+ size_t slash_after_share = path.find(DIR_SEP, slash_after_server + 1);
+ if (slash_after_share == string::npos) {
+ return path + DIR_SEP;
+ }
+ }
+ return path;
}
/* Convert:
* \\?\UNC\server\share\folder\... to \\server\share\folder\...
* \\?\C:\ to C:\ and \\?\C:\folder\... to C:\folder\...
*/
-static string path_unc_to_short(const string& path)
-{
- size_t len = path.size();
- if((len > 3) &&
- (path[0] == DIR_SEP) &&
- (path[1] == DIR_SEP) &&
- (path[2] == '?') &&
- ((path[3] == DIR_SEP) || (path[3] == DIR_SEP_ALT)))
- {
- if((len > 5) && (path[5] == ':')) {
- return path.substr(4, len - 4);
- }
- else if((len > 7) &&
- (path.substr(4, 3) == "UNC") &&
- ((path[7] == DIR_SEP) || (path[7] == DIR_SEP_ALT)))
- {
- return "\\\\" + path.substr(8, len - 8);
- }
- }
- return path;
-}
-
-static string path_cleanup_unc(const string& path)
-{
- string result = path_unc_to_short(path);
- if(path.size() > 2) {
- /* It's possible path is now a non-UNC. */
- if(result[0] == DIR_SEP && result[1] == DIR_SEP) {
- return path_unc_add_slash_to_share(result);
- }
- }
- return result;
+static string path_unc_to_short(const string &path)
+{
+ size_t len = path.size();
+ if ((len > 3) && (path[0] == DIR_SEP) && (path[1] == DIR_SEP) && (path[2] == '?') &&
+ ((path[3] == DIR_SEP) || (path[3] == DIR_SEP_ALT))) {
+ if ((len > 5) && (path[5] == ':')) {
+ return path.substr(4, len - 4);
+ }
+ else if ((len > 7) && (path.substr(4, 3) == "UNC") &&
+ ((path[7] == DIR_SEP) || (path[7] == DIR_SEP_ALT))) {
+ return "\\\\" + path.substr(8, len - 8);
+ }
+ }
+ return path;
+}
+
+static string path_cleanup_unc(const string &path)
+{
+ string result = path_unc_to_short(path);
+ if (path.size() > 2) {
+ /* It's possible path is now a non-UNC. */
+ if (result[0] == DIR_SEP && result[1] == DIR_SEP) {
+ return path_unc_add_slash_to_share(result);
+ }
+ }
+ return result;
}
/* Make path compatible for stat() functions. */
-static string path_make_compatible(const string& path)
-{
- string result = path;
- /* In Windows stat() doesn't recognize dir ending on a slash. */
- if(result.size() > 3 && result[result.size() - 1] == DIR_SEP) {
- result.resize(result.size() - 1);
- }
- /* Clean up UNC path. */
- if((path.size() >= 3) && (path[0] == DIR_SEP) && (path[1] == DIR_SEP)) {
- result = path_cleanup_unc(result);
- }
- /* Make sure volume-only path ends up wit ha directory separator. */
- if(result.size() == 2 && result[1] == ':') {
- result += DIR_SEP;
- }
- return result;
-}
-
-static int path_wstat(const wstring& path_wc, path_stat_t *st)
-{
-#if defined(_MSC_VER) || defined(__MINGW64__)
- return _wstat64(path_wc.c_str(), st);
-#elif defined(__MINGW32__)
- return _wstati64(path_wc.c_str(), st);
-#else
- return _wstat(path_wc.c_str(), st);
-#endif
+static string path_make_compatible(const string &path)
+{
+ string result = path;
+ /* In Windows stat() doesn't recognize dir ending on a slash. */
+ if (result.size() > 3 && result[result.size() - 1] == DIR_SEP) {
+ result.resize(result.size() - 1);
+ }
+ /* Clean up UNC path. */
+ if ((path.size() >= 3) && (path[0] == DIR_SEP) && (path[1] == DIR_SEP)) {
+ result = path_cleanup_unc(result);
+ }
+ /* Make sure volume-only path ends up wit ha directory separator. */
+ if (result.size() == 2 && result[1] == ':') {
+ result += DIR_SEP;
+ }
+ return result;
+}
+
+static int path_wstat(const wstring &path_wc, path_stat_t *st)
+{
+# if defined(_MSC_VER) || defined(__MINGW64__)
+ return _wstat64(path_wc.c_str(), st);
+# elif defined(__MINGW32__)
+ return _wstati64(path_wc.c_str(), st);
+# else
+ return _wstat(path_wc.c_str(), st);
+# endif
}
-static int path_stat(const string& path, path_stat_t *st)
+static int path_stat(const string &path, path_stat_t *st)
{
- wstring path_wc = string_to_wstring(path);
- return path_wstat(path_wc, st);
+ wstring path_wc = string_to_wstring(path);
+ return path_wstat(path_wc, st);
}
#else /* _WIN32 */
-static int path_stat(const string& path, path_stat_t *st)
+static int path_stat(const string &path, path_stat_t *st)
{
- return stat(path.c_str(), st);
+ return stat(path.c_str(), st);
}
-#endif /* _WIN32 */
+#endif /* _WIN32 */
-size_t path_file_size(const string& path)
+size_t path_file_size(const string &path)
{
- path_stat_t st;
- if(path_stat(path, &st) != 0) {
- return -1;
- }
- return st.st_size;
+ path_stat_t st;
+ if (path_stat(path, &st) != 0) {
+ return -1;
+ }
+ return st.st_size;
}
-bool path_exists(const string& path)
+bool path_exists(const string &path)
{
#ifdef _WIN32
- string fixed_path = path_make_compatible(path);
- wstring path_wc = string_to_wstring(fixed_path);
- path_stat_t st;
- if(path_wstat(path_wc, &st) != 0) {
- return false;
- }
- return st.st_mode != 0;
+ string fixed_path = path_make_compatible(path);
+ wstring path_wc = string_to_wstring(fixed_path);
+ path_stat_t st;
+ if (path_wstat(path_wc, &st) != 0) {
+ return false;
+ }
+ return st.st_mode != 0;
#else /* _WIN32 */
- struct stat st;
- if(stat(path.c_str(), &st) != 0) {
- return 0;
- }
- return st.st_mode != 0;
-#endif /* _WIN32 */
+ struct stat st;
+ if (stat(path.c_str(), &st) != 0) {
+ return 0;
+ }
+ return st.st_mode != 0;
+#endif /* _WIN32 */
}
-bool path_is_directory(const string& path)
+bool path_is_directory(const string &path)
{
- path_stat_t st;
- if(path_stat(path, &st) != 0) {
- return false;
- }
- return S_ISDIR(st.st_mode);
+ path_stat_t st;
+ if (path_stat(path, &st) != 0) {
+ return false;
+ }
+ return S_ISDIR(st.st_mode);
}
-static void path_files_md5_hash_recursive(MD5Hash& hash, const string& dir)
+static void path_files_md5_hash_recursive(MD5Hash &hash, const string &dir)
{
- if(path_exists(dir)) {
- directory_iterator it(dir), it_end;
+ if (path_exists(dir)) {
+ directory_iterator it(dir), it_end;
- for(; it != it_end; ++it) {
- if(path_is_directory(it->path())) {
- path_files_md5_hash_recursive(hash, it->path());
- }
- else {
- string filepath = it->path();
+ for (; it != it_end; ++it) {
+ if (path_is_directory(it->path())) {
+ path_files_md5_hash_recursive(hash, it->path());
+ }
+ else {
+ string filepath = it->path();
- hash.append((const uint8_t*)filepath.c_str(), filepath.size());
- hash.append_file(filepath);
- }
- }
- }
+ hash.append((const uint8_t *)filepath.c_str(), filepath.size());
+ hash.append_file(filepath);
+ }
+ }
+ }
}
-string path_files_md5_hash(const string& dir)
+string path_files_md5_hash(const string &dir)
{
- /* computes md5 hash of all files in the directory */
- MD5Hash hash;
+ /* computes md5 hash of all files in the directory */
+ MD5Hash hash;
- path_files_md5_hash_recursive(hash, dir);
+ path_files_md5_hash_recursive(hash, dir);
- return hash.get_hex();
+ return hash.get_hex();
}
-static bool create_directories_recursivey(const string& path)
+static bool create_directories_recursivey(const string &path)
{
- if(path_is_directory(path)) {
- /* Directory already exists, nothing to do. */
- return true;
- }
- if(path_exists(path)) {
- /* File exists and it's not a directory. */
- return false;
- }
+ if (path_is_directory(path)) {
+ /* Directory already exists, nothing to do. */
+ return true;
+ }
+ if (path_exists(path)) {
+ /* File exists and it's not a directory. */
+ return false;
+ }
- string parent = path_dirname(path);
- if(parent.size() > 0 && parent != path) {
- if(!create_directories_recursivey(parent)) {
- return false;
- }
- }
+ string parent = path_dirname(path);
+ if (parent.size() > 0 && parent != path) {
+ if (!create_directories_recursivey(parent)) {
+ return false;
+ }
+ }
#ifdef _WIN32
- wstring path_wc = string_to_wstring(path);
- return _wmkdir(path_wc.c_str()) == 0;
+ wstring path_wc = string_to_wstring(path);
+ return _wmkdir(path_wc.c_str()) == 0;
#else
- return mkdir(path.c_str(), 0777) == 0;
+ return mkdir(path.c_str(), 0777) == 0;
#endif
}
-void path_create_directories(const string& filepath)
+void path_create_directories(const string &filepath)
{
- string path = path_dirname(filepath);
- create_directories_recursivey(path);
+ string path = path_dirname(filepath);
+ create_directories_recursivey(path);
}
-bool path_write_binary(const string& path, const vector<uint8_t>& binary)
+bool path_write_binary(const string &path, const vector<uint8_t> &binary)
{
- path_create_directories(path);
+ path_create_directories(path);
- /* write binary file from memory */
- FILE *f = path_fopen(path, "wb");
+ /* write binary file from memory */
+ FILE *f = path_fopen(path, "wb");
- if(!f)
- return false;
+ if (!f)
+ return false;
- if(binary.size() > 0)
- fwrite(&binary[0], sizeof(uint8_t), binary.size(), f);
+ if (binary.size() > 0)
+ fwrite(&binary[0], sizeof(uint8_t), binary.size(), f);
- fclose(f);
+ fclose(f);
- return true;
+ return true;
}
-bool path_write_text(const string& path, string& text)
+bool path_write_text(const string &path, string &text)
{
- vector<uint8_t> binary(text.length(), 0);
- std::copy(text.begin(), text.end(), binary.begin());
+ vector<uint8_t> binary(text.length(), 0);
+ std::copy(text.begin(), text.end(), binary.begin());
- return path_write_binary(path, binary);
+ return path_write_binary(path, binary);
}
-bool path_read_binary(const string& path, vector<uint8_t>& binary)
+bool path_read_binary(const string &path, vector<uint8_t> &binary)
{
- /* read binary file into memory */
- FILE *f = path_fopen(path, "rb");
+ /* read binary file into memory */
+ FILE *f = path_fopen(path, "rb");
- if(!f) {
- binary.resize(0);
- return false;
- }
+ if (!f) {
+ binary.resize(0);
+ return false;
+ }
- binary.resize(path_file_size(path));
+ binary.resize(path_file_size(path));
- if(binary.size() == 0) {
- fclose(f);
- return false;
- }
+ if (binary.size() == 0) {
+ fclose(f);
+ return false;
+ }
- if(fread(&binary[0], sizeof(uint8_t), binary.size(), f) != binary.size()) {
- fclose(f);
- return false;
- }
+ if (fread(&binary[0], sizeof(uint8_t), binary.size(), f) != binary.size()) {
+ fclose(f);
+ return false;
+ }
- fclose(f);
+ fclose(f);
- return true;
+ return true;
}
-bool path_read_text(const string& path, string& text)
+bool path_read_text(const string &path, string &text)
{
- vector<uint8_t> binary;
+ vector<uint8_t> binary;
- if(!path_exists(path) || !path_read_binary(path, binary))
- return false;
+ if (!path_exists(path) || !path_read_binary(path, binary))
+ return false;
- const char *str = (const char*)&binary[0];
- size_t size = binary.size();
- text = string(str, size);
+ const char *str = (const char *)&binary[0];
+ size_t size = binary.size();
+ text = string(str, size);
- return true;
+ return true;
}
-uint64_t path_modified_time(const string& path)
+uint64_t path_modified_time(const string &path)
{
- path_stat_t st;
- if(path_stat(path, &st) != 0) {
- return 0;
- }
- return st.st_mtime;
+ path_stat_t st;
+ if (path_stat(path, &st) != 0) {
+ return 0;
+ }
+ return st.st_mtime;
}
-bool path_remove(const string& path)
+bool path_remove(const string &path)
{
- return remove(path.c_str()) == 0;
+ return remove(path.c_str()) == 0;
}
struct SourceReplaceState {
- typedef map<string, string> ProcessedMapping;
- /* Base director for all relative include headers. */
- string base;
- /* Result of processed files. */
- ProcessedMapping processed_files;
- /* Set of files which are considered "precompiled" and which are replaced
- * with and empty string on a subsequent occurrence in include statement.
- */
- set<string> precompiled_headers;
+ typedef map<string, string> ProcessedMapping;
+ /* Base director for all relative include headers. */
+ string base;
+ /* Result of processed files. */
+ ProcessedMapping processed_files;
+ /* Set of files which are considered "precompiled" and which are replaced
+ * with and empty string on a subsequent occurrence in include statement.
+ */
+ set<string> precompiled_headers;
};
-static string path_source_replace_includes_recursive(
- const string& source,
- const string& source_filepath,
- SourceReplaceState *state);
-
-static string line_directive(const SourceReplaceState& state,
- const string& path,
- const int line)
-{
- string unescaped_path = path;
- /* First we make path relative. */
- if(string_startswith(unescaped_path, state.base.c_str())) {
- const string base_file = path_filename(state.base);
- const size_t base_len = state.base.length();
- unescaped_path = base_file +
- unescaped_path.substr(base_len,
- unescaped_path.length() - base_len);
- }
- /* Second, we replace all unsafe characters. */
- const size_t length = unescaped_path.length();
- string escaped_path = "";
- for(size_t i = 0; i < length; ++i) {
- const char ch = unescaped_path[i];
- if(strchr("\"\'\?\\", ch) != NULL) {
- escaped_path += "\\";
- }
- escaped_path += ch;
- }
- /* TODO(sergey): Check whether using std::to_string combined with several
- * concatenation operations is any faster.
- */
- return string_printf("#line %d \"%s\"", line, escaped_path.c_str());
-}
-
-static string path_source_handle_preprocessor(
- const string& preprocessor_line,
- const string& source_filepath,
- const size_t line_number,
- SourceReplaceState *state)
-{
- string result = preprocessor_line;
- string token = string_strip(
- preprocessor_line.substr(1, preprocessor_line.size() - 1));
- if(string_startswith(token, "include")) {
- token = string_strip(token.substr(7, token.size() - 7));
- if(token[0] == '"') {
- const size_t n_start = 1;
- const size_t n_end = token.find("\"", n_start);
- const string filename = token.substr(n_start, n_end - n_start);
- const bool is_precompiled = string_endswith(token, "// PRECOMPILED");
- string filepath = path_join(state->base, filename);
- if(!path_exists(filepath)) {
- filepath = path_join(path_dirname(source_filepath),
- filename);
- }
- if(is_precompiled) {
- state->precompiled_headers.insert(filepath);
- }
- string text;
- if(path_read_text(filepath, text)) {
- text = path_source_replace_includes_recursive(
- text, filepath, state);
- /* Use line directives for better error messages. */
- result = line_directive(*state, filepath, 1) + "\n"
- + text + "\n"
- + line_directive(*state, source_filepath, line_number + 1);
- }
- }
- }
- return result;
+static string path_source_replace_includes_recursive(const string &source,
+ const string &source_filepath,
+ SourceReplaceState *state);
+
+static string line_directive(const SourceReplaceState &state, const string &path, const int line)
+{
+ string unescaped_path = path;
+ /* First we make path relative. */
+ if (string_startswith(unescaped_path, state.base.c_str())) {
+ const string base_file = path_filename(state.base);
+ const size_t base_len = state.base.length();
+ unescaped_path = base_file +
+ unescaped_path.substr(base_len, unescaped_path.length() - base_len);
+ }
+ /* Second, we replace all unsafe characters. */
+ const size_t length = unescaped_path.length();
+ string escaped_path = "";
+ for (size_t i = 0; i < length; ++i) {
+ const char ch = unescaped_path[i];
+ if (strchr("\"\'\?\\", ch) != NULL) {
+ escaped_path += "\\";
+ }
+ escaped_path += ch;
+ }
+ /* TODO(sergey): Check whether using std::to_string combined with several
+ * concatenation operations is any faster.
+ */
+ return string_printf("#line %d \"%s\"", line, escaped_path.c_str());
+}
+
+static string path_source_handle_preprocessor(const string &preprocessor_line,
+ const string &source_filepath,
+ const size_t line_number,
+ SourceReplaceState *state)
+{
+ string result = preprocessor_line;
+ string token = string_strip(preprocessor_line.substr(1, preprocessor_line.size() - 1));
+ if (string_startswith(token, "include")) {
+ token = string_strip(token.substr(7, token.size() - 7));
+ if (token[0] == '"') {
+ const size_t n_start = 1;
+ const size_t n_end = token.find("\"", n_start);
+ const string filename = token.substr(n_start, n_end - n_start);
+ const bool is_precompiled = string_endswith(token, "// PRECOMPILED");
+ string filepath = path_join(state->base, filename);
+ if (!path_exists(filepath)) {
+ filepath = path_join(path_dirname(source_filepath), filename);
+ }
+ if (is_precompiled) {
+ state->precompiled_headers.insert(filepath);
+ }
+ string text;
+ if (path_read_text(filepath, text)) {
+ text = path_source_replace_includes_recursive(text, filepath, state);
+ /* Use line directives for better error messages. */
+ result = line_directive(*state, filepath, 1) + "\n" + text + "\n" +
+ line_directive(*state, source_filepath, line_number + 1);
+ }
+ }
+ }
+ return result;
}
/* Our own little c preprocessor that replaces #includes with the file
* contents, to work around issue of OpenCL drivers not supporting
* include paths with spaces in them.
*/
-static string path_source_replace_includes_recursive(
- const string& source,
- const string& source_filepath,
- SourceReplaceState *state)
-{
- /* Try to re-use processed file without spending time on replacing all
- * include directives again.
- */
- SourceReplaceState::ProcessedMapping::iterator replaced_file =
- state->processed_files.find(source_filepath);
- if(replaced_file != state->processed_files.end()) {
- if(state->precompiled_headers.find(source_filepath) !=
- state->precompiled_headers.end()) {
- return "";
- }
- return replaced_file->second;
- }
- /* Perform full file processing. */
- string result = "";
- const size_t source_length = source.length();
- size_t index = 0;
- /* Information about where we are in the source. */
- size_t line_number = 0, column_number = 1;
- /* Currently gathered non-preprocessor token.
- * Store as start/length rather than token itself to avoid overhead of
- * memory re-allocations on each character concatenation.
- */
- size_t token_start = 0, token_length = 0;
- /* Denotes whether we're inside of preprocessor line, together with
- * preprocessor line itself.
- *
- * TODO(sergey): Investigate whether using token start/end position
- * gives measurable speedup.
- */
- bool inside_preprocessor = false;
- string preprocessor_line = "";
- /* Actual loop over the whole source. */
- while(index < source_length) {
- const char ch = source[index];
- if(ch == '\n') {
- if(inside_preprocessor) {
- result += path_source_handle_preprocessor(preprocessor_line,
- source_filepath,
- line_number,
- state);
- /* Start gathering net part of the token. */
- token_start = index;
- token_length = 0;
- }
- inside_preprocessor = false;
- preprocessor_line = "";
- column_number = 0;
- ++line_number;
- }
- else if(ch == '#' && column_number == 1 && !inside_preprocessor) {
- /* Append all possible non-preprocessor token to the result. */
- if(token_length != 0) {
- result.append(source, token_start, token_length);
- token_start = index;
- token_length = 0;
- }
- inside_preprocessor = true;
- }
- if(inside_preprocessor) {
- preprocessor_line += ch;
- }
- else {
- ++token_length;
- }
- ++index;
- ++column_number;
- }
- /* Append possible tokens which happened before special events handled
- * above.
- */
- if(token_length != 0) {
- result.append(source, token_start, token_length);
- }
- if(inside_preprocessor) {
- result += path_source_handle_preprocessor(preprocessor_line,
- source_filepath,
- line_number,
- state);
- }
- /* Store result for further reuse. */
- state->processed_files[source_filepath] = result;
- return result;
-}
-
-string path_source_replace_includes(const string& source,
- const string& path,
- const string& source_filename)
-{
- SourceReplaceState state;
- state.base = path;
- return path_source_replace_includes_recursive(
- source,
- path_join(path, source_filename),
- &state);
-}
-
-FILE *path_fopen(const string& path, const string& mode)
+static string path_source_replace_includes_recursive(const string &source,
+ const string &source_filepath,
+ SourceReplaceState *state)
+{
+ /* Try to re-use processed file without spending time on replacing all
+ * include directives again.
+ */
+ SourceReplaceState::ProcessedMapping::iterator replaced_file = state->processed_files.find(
+ source_filepath);
+ if (replaced_file != state->processed_files.end()) {
+ if (state->precompiled_headers.find(source_filepath) != state->precompiled_headers.end()) {
+ return "";
+ }
+ return replaced_file->second;
+ }
+ /* Perform full file processing. */
+ string result = "";
+ const size_t source_length = source.length();
+ size_t index = 0;
+ /* Information about where we are in the source. */
+ size_t line_number = 0, column_number = 1;
+ /* Currently gathered non-preprocessor token.
+ * Store as start/length rather than token itself to avoid overhead of
+ * memory re-allocations on each character concatenation.
+ */
+ size_t token_start = 0, token_length = 0;
+ /* Denotes whether we're inside of preprocessor line, together with
+ * preprocessor line itself.
+ *
+ * TODO(sergey): Investigate whether using token start/end position
+ * gives measurable speedup.
+ */
+ bool inside_preprocessor = false;
+ string preprocessor_line = "";
+ /* Actual loop over the whole source. */
+ while (index < source_length) {
+ const char ch = source[index];
+ if (ch == '\n') {
+ if (inside_preprocessor) {
+ result += path_source_handle_preprocessor(
+ preprocessor_line, source_filepath, line_number, state);
+ /* Start gathering net part of the token. */
+ token_start = index;
+ token_length = 0;
+ }
+ inside_preprocessor = false;
+ preprocessor_line = "";
+ column_number = 0;
+ ++line_number;
+ }
+ else if (ch == '#' && column_number == 1 && !inside_preprocessor) {
+ /* Append all possible non-preprocessor token to the result. */
+ if (token_length != 0) {
+ result.append(source, token_start, token_length);
+ token_start = index;
+ token_length = 0;
+ }
+ inside_preprocessor = true;
+ }
+ if (inside_preprocessor) {
+ preprocessor_line += ch;
+ }
+ else {
+ ++token_length;
+ }
+ ++index;
+ ++column_number;
+ }
+ /* Append possible tokens which happened before special events handled
+ * above.
+ */
+ if (token_length != 0) {
+ result.append(source, token_start, token_length);
+ }
+ if (inside_preprocessor) {
+ result += path_source_handle_preprocessor(
+ preprocessor_line, source_filepath, line_number, state);
+ }
+ /* Store result for further reuse. */
+ state->processed_files[source_filepath] = result;
+ return result;
+}
+
+string path_source_replace_includes(const string &source,
+ const string &path,
+ const string &source_filename)
+{
+ SourceReplaceState state;
+ state.base = path;
+ return path_source_replace_includes_recursive(source, path_join(path, source_filename), &state);
+}
+
+FILE *path_fopen(const string &path, const string &mode)
{
#ifdef _WIN32
- wstring path_wc = string_to_wstring(path);
- wstring mode_wc = string_to_wstring(mode);
- return _wfopen(path_wc.c_str(), mode_wc.c_str());
+ wstring path_wc = string_to_wstring(path);
+ wstring mode_wc = string_to_wstring(mode);
+ return _wfopen(path_wc.c_str(), mode_wc.c_str());
#else
- return fopen(path.c_str(), mode.c_str());
+ return fopen(path.c_str(), mode.c_str());
#endif
}
-void path_cache_clear_except(const string& name, const set<string>& except)
+void path_cache_clear_except(const string &name, const set<string> &except)
{
- string dir = path_user_get("cache");
-
- if(path_exists(dir)) {
- directory_iterator it(dir), it_end;
+ string dir = path_user_get("cache");
- for(; it != it_end; ++it) {
- string filename = path_filename(it->path());
+ if (path_exists(dir)) {
+ directory_iterator it(dir), it_end;
- if(string_startswith(filename, name.c_str()))
- if(except.find(filename) == except.end())
- path_remove(it->path());
- }
- }
+ for (; it != it_end; ++it) {
+ string filename = path_filename(it->path());
+ if (string_startswith(filename, name.c_str()))
+ if (except.find(filename) == except.end())
+ path_remove(it->path());
+ }
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_path.h b/intern/cycles/util/util_path.h
index 738dba94647..7a83c2135a4 100644
--- a/intern/cycles/util/util_path.h
+++ b/intern/cycles/util/util_path.h
@@ -32,46 +32,46 @@
CCL_NAMESPACE_BEGIN
/* program paths */
-void path_init(const string& path = "", const string& user_path = "");
-string path_get(const string& sub = "");
-string path_user_get(const string& sub = "");
-string path_cache_get(const string& sub = "");
+void path_init(const string &path = "", const string &user_path = "");
+string path_get(const string &sub = "");
+string path_user_get(const string &sub = "");
+string path_cache_get(const string &sub = "");
/* path string manipulation */
-string path_filename(const string& path);
-string path_dirname(const string& path);
-string path_join(const string& dir, const string& file);
-string path_escape(const string& path);
-bool path_is_relative(const string& path);
+string path_filename(const string &path);
+string path_dirname(const string &path);
+string path_join(const string &dir, const string &file);
+string path_escape(const string &path);
+bool path_is_relative(const string &path);
/* file info */
-size_t path_file_size(const string& path);
-bool path_exists(const string& path);
-bool path_is_directory(const string& path);
-string path_files_md5_hash(const string& dir);
-uint64_t path_modified_time(const string& path);
+size_t path_file_size(const string &path);
+bool path_exists(const string &path);
+bool path_is_directory(const string &path);
+string path_files_md5_hash(const string &dir);
+uint64_t path_modified_time(const string &path);
/* directory utility */
-void path_create_directories(const string& path);
+void path_create_directories(const string &path);
/* file read/write utilities */
-FILE *path_fopen(const string& path, const string& mode);
+FILE *path_fopen(const string &path, const string &mode);
-bool path_write_binary(const string& path, const vector<uint8_t>& binary);
-bool path_write_text(const string& path, string& text);
-bool path_read_binary(const string& path, vector<uint8_t>& binary);
-bool path_read_text(const string& path, string& text);
+bool path_write_binary(const string &path, const vector<uint8_t> &binary);
+bool path_write_text(const string &path, string &text);
+bool path_read_binary(const string &path, vector<uint8_t> &binary);
+bool path_read_text(const string &path, string &text);
/* File manipulation. */
-bool path_remove(const string& path);
+bool path_remove(const string &path);
/* source code utility */
-string path_source_replace_includes(const string& source,
- const string& path,
- const string& source_filename="");
+string path_source_replace_includes(const string &source,
+ const string &path,
+ const string &source_filename = "");
/* cache utility */
-void path_cache_clear_except(const string& name, const set<string>& except);
+void path_cache_clear_except(const string &name, const set<string> &except);
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_profiling.cpp b/intern/cycles/util/util_profiling.cpp
index 30aaef69310..e3edf219435 100644
--- a/intern/cycles/util/util_profiling.cpp
+++ b/intern/cycles/util/util_profiling.cpp
@@ -20,159 +20,159 @@
CCL_NAMESPACE_BEGIN
-Profiler::Profiler()
- : do_stop_worker(true), worker(NULL)
+Profiler::Profiler() : do_stop_worker(true), worker(NULL)
{
}
Profiler::~Profiler()
{
- assert(worker == NULL);
+ assert(worker == NULL);
}
void Profiler::run()
{
- uint64_t updates = 0;
- auto start_time = std::chrono::system_clock::now();
- while(!do_stop_worker) {
- thread_scoped_lock lock(mutex);
- foreach(ProfilingState *state, states) {
- uint32_t cur_event = state->event;
- int32_t cur_shader = state->shader;
- int32_t cur_object = state->object;
-
- /* The state reads/writes should be atomic, but just to be sure
- * check the values for validity anyways. */
- if(cur_event < PROFILING_NUM_EVENTS) {
- event_samples[cur_event]++;
- }
-
- if(cur_shader >= 0 && cur_shader < shader_samples.size()) {
- /* Only consider the active shader during events whose runtime significantly depends on it. */
- if(((cur_event >= PROFILING_SHADER_EVAL ) && (cur_event <= PROFILING_SUBSURFACE)) ||
- ((cur_event >= PROFILING_CLOSURE_EVAL) && (cur_event <= PROFILING_CLOSURE_VOLUME_SAMPLE))) {
- shader_samples[cur_shader]++;
- }
- }
-
- if(cur_object >= 0 && cur_object < object_samples.size()) {
- object_samples[cur_object]++;
- }
- }
- lock.unlock();
-
- /* Relative waits always overshoot a bit, so just waiting 1ms every
- * time would cause the sampling to drift over time.
- * By keeping track of the absolute time, the wait times correct themselves -
- * if one wait overshoots a lot, the next one will be shorter to compensate. */
- updates++;
- std::this_thread::sleep_until(start_time + updates*std::chrono::milliseconds(1));
- }
+ uint64_t updates = 0;
+ auto start_time = std::chrono::system_clock::now();
+ while (!do_stop_worker) {
+ thread_scoped_lock lock(mutex);
+ foreach (ProfilingState *state, states) {
+ uint32_t cur_event = state->event;
+ int32_t cur_shader = state->shader;
+ int32_t cur_object = state->object;
+
+ /* The state reads/writes should be atomic, but just to be sure
+ * check the values for validity anyways. */
+ if (cur_event < PROFILING_NUM_EVENTS) {
+ event_samples[cur_event]++;
+ }
+
+ if (cur_shader >= 0 && cur_shader < shader_samples.size()) {
+ /* Only consider the active shader during events whose runtime significantly depends on it. */
+ if (((cur_event >= PROFILING_SHADER_EVAL) && (cur_event <= PROFILING_SUBSURFACE)) ||
+ ((cur_event >= PROFILING_CLOSURE_EVAL) &&
+ (cur_event <= PROFILING_CLOSURE_VOLUME_SAMPLE))) {
+ shader_samples[cur_shader]++;
+ }
+ }
+
+ if (cur_object >= 0 && cur_object < object_samples.size()) {
+ object_samples[cur_object]++;
+ }
+ }
+ lock.unlock();
+
+ /* Relative waits always overshoot a bit, so just waiting 1ms every
+ * time would cause the sampling to drift over time.
+ * By keeping track of the absolute time, the wait times correct themselves -
+ * if one wait overshoots a lot, the next one will be shorter to compensate. */
+ updates++;
+ std::this_thread::sleep_until(start_time + updates * std::chrono::milliseconds(1));
+ }
}
void Profiler::reset(int num_shaders, int num_objects)
{
- bool running = (worker != NULL);
- if(running) {
- stop();
- }
-
- /* Resize and clear the accumulation vectors. */
- shader_hits.assign(num_shaders, 0);
- object_hits.assign(num_objects, 0);
-
- event_samples.assign(PROFILING_NUM_EVENTS, 0);
- shader_samples.assign(num_shaders, 0);
- object_samples.assign(num_objects, 0);
-
- if(running) {
- start();
- }
+ bool running = (worker != NULL);
+ if (running) {
+ stop();
+ }
+
+ /* Resize and clear the accumulation vectors. */
+ shader_hits.assign(num_shaders, 0);
+ object_hits.assign(num_objects, 0);
+
+ event_samples.assign(PROFILING_NUM_EVENTS, 0);
+ shader_samples.assign(num_shaders, 0);
+ object_samples.assign(num_objects, 0);
+
+ if (running) {
+ start();
+ }
}
void Profiler::start()
{
- assert(worker == NULL);
- do_stop_worker = false;
- worker = new thread(function_bind(&Profiler::run, this));
+ assert(worker == NULL);
+ do_stop_worker = false;
+ worker = new thread(function_bind(&Profiler::run, this));
}
void Profiler::stop()
{
- if(worker != NULL) {
- do_stop_worker = true;
+ if (worker != NULL) {
+ do_stop_worker = true;
- worker->join();
- delete worker;
- worker = NULL;
- }
+ worker->join();
+ delete worker;
+ worker = NULL;
+ }
}
void Profiler::add_state(ProfilingState *state)
{
- thread_scoped_lock lock(mutex);
+ thread_scoped_lock lock(mutex);
- /* Add the ProfilingState from the list of sampled states. */
- assert(std::find(states.begin(), states.end(), state) == states.end());
- states.push_back(state);
+ /* Add the ProfilingState from the list of sampled states. */
+ assert(std::find(states.begin(), states.end(), state) == states.end());
+ states.push_back(state);
- /* Resize thread-local hit counters. */
- state->shader_hits.assign(shader_hits.size(), 0);
- state->object_hits.assign(object_hits.size(), 0);
+ /* Resize thread-local hit counters. */
+ state->shader_hits.assign(shader_hits.size(), 0);
+ state->object_hits.assign(object_hits.size(), 0);
- /* Initialize the state. */
- state->event = PROFILING_UNKNOWN;
- state->shader = -1;
- state->object = -1;
- state->active = true;
+ /* Initialize the state. */
+ state->event = PROFILING_UNKNOWN;
+ state->shader = -1;
+ state->object = -1;
+ state->active = true;
}
void Profiler::remove_state(ProfilingState *state)
{
- thread_scoped_lock lock(mutex);
-
- /* Remove the ProfilingState from the list of sampled states. */
- states.erase(std::remove(states.begin(), states.end(), state), states.end());
- state->active = false;
-
- /* Merge thread-local hit counters. */
- assert(shader_hits.size() == state->shader_hits.size());
- for(int i = 0; i < shader_hits.size(); i++) {
- shader_hits[i] += state->shader_hits[i];
- }
-
- assert(object_hits.size() == state->object_hits.size());
- for(int i = 0; i < object_hits.size(); i++) {
- object_hits[i] += state->object_hits[i];
- }
+ thread_scoped_lock lock(mutex);
+
+ /* Remove the ProfilingState from the list of sampled states. */
+ states.erase(std::remove(states.begin(), states.end(), state), states.end());
+ state->active = false;
+
+ /* Merge thread-local hit counters. */
+ assert(shader_hits.size() == state->shader_hits.size());
+ for (int i = 0; i < shader_hits.size(); i++) {
+ shader_hits[i] += state->shader_hits[i];
+ }
+
+ assert(object_hits.size() == state->object_hits.size());
+ for (int i = 0; i < object_hits.size(); i++) {
+ object_hits[i] += state->object_hits[i];
+ }
}
uint64_t Profiler::get_event(ProfilingEvent event)
{
- assert(worker == NULL);
- return event_samples[event];
+ assert(worker == NULL);
+ return event_samples[event];
}
bool Profiler::get_shader(int shader, uint64_t &samples, uint64_t &hits)
{
- assert(worker == NULL);
- if(shader_samples[shader] == 0) {
- return false;
- }
- samples = shader_samples[shader];
- hits = shader_hits[shader];
- return true;
+ assert(worker == NULL);
+ if (shader_samples[shader] == 0) {
+ return false;
+ }
+ samples = shader_samples[shader];
+ hits = shader_hits[shader];
+ return true;
}
bool Profiler::get_object(int object, uint64_t &samples, uint64_t &hits)
{
- assert(worker == NULL);
- if(object_samples[object] == 0) {
- return false;
- }
- samples = object_samples[object];
- hits = object_hits[object];
- return true;
+ assert(worker == NULL);
+ if (object_samples[object] == 0) {
+ return false;
+ }
+ samples = object_samples[object];
+ hits = object_hits[object];
+ return true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_profiling.h b/intern/cycles/util/util_profiling.h
index 77cdbb0b325..f5f500239f2 100644
--- a/intern/cycles/util/util_profiling.h
+++ b/intern/cycles/util/util_profiling.h
@@ -27,42 +27,42 @@
CCL_NAMESPACE_BEGIN
enum ProfilingEvent : uint32_t {
- PROFILING_UNKNOWN,
- PROFILING_RAY_SETUP,
- PROFILING_PATH_INTEGRATE,
- PROFILING_SCENE_INTERSECT,
- PROFILING_INDIRECT_EMISSION,
- PROFILING_VOLUME,
- PROFILING_SHADER_SETUP,
- PROFILING_SHADER_EVAL,
- PROFILING_SHADER_APPLY,
- PROFILING_AO,
- PROFILING_SUBSURFACE,
- PROFILING_CONNECT_LIGHT,
- PROFILING_SURFACE_BOUNCE,
- PROFILING_WRITE_RESULT,
-
- PROFILING_INTERSECT,
- PROFILING_INTERSECT_LOCAL,
- PROFILING_INTERSECT_SHADOW_ALL,
- PROFILING_INTERSECT_VOLUME,
- PROFILING_INTERSECT_VOLUME_ALL,
-
- PROFILING_CLOSURE_EVAL,
- PROFILING_CLOSURE_SAMPLE,
- PROFILING_CLOSURE_VOLUME_EVAL,
- PROFILING_CLOSURE_VOLUME_SAMPLE,
-
- PROFILING_DENOISING,
- PROFILING_DENOISING_CONSTRUCT_TRANSFORM,
- PROFILING_DENOISING_RECONSTRUCT,
- PROFILING_DENOISING_DIVIDE_SHADOW,
- PROFILING_DENOISING_NON_LOCAL_MEANS,
- PROFILING_DENOISING_COMBINE_HALVES,
- PROFILING_DENOISING_GET_FEATURE,
- PROFILING_DENOISING_DETECT_OUTLIERS,
-
- PROFILING_NUM_EVENTS,
+ PROFILING_UNKNOWN,
+ PROFILING_RAY_SETUP,
+ PROFILING_PATH_INTEGRATE,
+ PROFILING_SCENE_INTERSECT,
+ PROFILING_INDIRECT_EMISSION,
+ PROFILING_VOLUME,
+ PROFILING_SHADER_SETUP,
+ PROFILING_SHADER_EVAL,
+ PROFILING_SHADER_APPLY,
+ PROFILING_AO,
+ PROFILING_SUBSURFACE,
+ PROFILING_CONNECT_LIGHT,
+ PROFILING_SURFACE_BOUNCE,
+ PROFILING_WRITE_RESULT,
+
+ PROFILING_INTERSECT,
+ PROFILING_INTERSECT_LOCAL,
+ PROFILING_INTERSECT_SHADOW_ALL,
+ PROFILING_INTERSECT_VOLUME,
+ PROFILING_INTERSECT_VOLUME_ALL,
+
+ PROFILING_CLOSURE_EVAL,
+ PROFILING_CLOSURE_SAMPLE,
+ PROFILING_CLOSURE_VOLUME_EVAL,
+ PROFILING_CLOSURE_VOLUME_SAMPLE,
+
+ PROFILING_DENOISING,
+ PROFILING_DENOISING_CONSTRUCT_TRANSFORM,
+ PROFILING_DENOISING_RECONSTRUCT,
+ PROFILING_DENOISING_DIVIDE_SHADOW,
+ PROFILING_DENOISING_NON_LOCAL_MEANS,
+ PROFILING_DENOISING_COMBINE_HALVES,
+ PROFILING_DENOISING_GET_FEATURE,
+ PROFILING_DENOISING_DETECT_OUTLIERS,
+
+ PROFILING_NUM_EVENTS,
};
/* Contains the current execution state of a worker thread.
@@ -79,97 +79,97 @@ enum ProfilingEvent : uint32_t {
* case of reading an intermediate state could at worst result
* in a single incorrect sample. */
struct ProfilingState {
- volatile uint32_t event = PROFILING_UNKNOWN;
- volatile int32_t shader = -1;
- volatile int32_t object = -1;
- volatile bool active = false;
+ volatile uint32_t event = PROFILING_UNKNOWN;
+ volatile int32_t shader = -1;
+ volatile int32_t object = -1;
+ volatile bool active = false;
- vector<uint64_t> shader_hits;
- vector<uint64_t> object_hits;
+ vector<uint64_t> shader_hits;
+ vector<uint64_t> object_hits;
};
class Profiler {
-public:
- Profiler();
- ~Profiler();
+ public:
+ Profiler();
+ ~Profiler();
- void reset(int num_shaders, int num_objects);
+ void reset(int num_shaders, int num_objects);
- void start();
- void stop();
+ void start();
+ void stop();
- void add_state(ProfilingState *state);
- void remove_state(ProfilingState *state);
+ void add_state(ProfilingState *state);
+ void remove_state(ProfilingState *state);
- uint64_t get_event(ProfilingEvent event);
- bool get_shader(int shader, uint64_t &samples, uint64_t &hits);
- bool get_object(int object, uint64_t &samples, uint64_t &hits);
+ uint64_t get_event(ProfilingEvent event);
+ bool get_shader(int shader, uint64_t &samples, uint64_t &hits);
+ bool get_object(int object, uint64_t &samples, uint64_t &hits);
-protected:
- void run();
+ protected:
+ void run();
- /* Tracks how often the worker was in each ProfilingEvent while sampling,
- * so multiplying the values by the sample frequency (currently 1ms)
- * gives the approximate time spent in each state. */
- vector<uint64_t> event_samples;
- vector<uint64_t> shader_samples;
- vector<uint64_t> object_samples;
+ /* Tracks how often the worker was in each ProfilingEvent while sampling,
+ * so multiplying the values by the sample frequency (currently 1ms)
+ * gives the approximate time spent in each state. */
+ vector<uint64_t> event_samples;
+ vector<uint64_t> shader_samples;
+ vector<uint64_t> object_samples;
- /* Tracks the total amounts every object/shader was hit.
- * Used to evaluate relative cost, written by the render thread.
- * Indexed by the shader and object IDs that the kernel also uses
- * to index __object_flag and __shaders. */
- vector<uint64_t> shader_hits;
- vector<uint64_t> object_hits;
+ /* Tracks the total amounts every object/shader was hit.
+ * Used to evaluate relative cost, written by the render thread.
+ * Indexed by the shader and object IDs that the kernel also uses
+ * to index __object_flag and __shaders. */
+ vector<uint64_t> shader_hits;
+ vector<uint64_t> object_hits;
- volatile bool do_stop_worker;
- thread *worker;
+ volatile bool do_stop_worker;
+ thread *worker;
- thread_mutex mutex;
- vector<ProfilingState*> states;
+ thread_mutex mutex;
+ vector<ProfilingState *> states;
};
class ProfilingHelper {
-public:
- ProfilingHelper(ProfilingState *state, ProfilingEvent event)
- : state(state)
- {
- previous_event = state->event;
- state->event = event;
- }
-
- inline void set_event(ProfilingEvent event)
- {
- state->event = event;
- }
-
- inline void set_shader(int shader)
- {
- state->shader = shader;
- if(state->active) {
- assert(shader < state->shader_hits.size());
- state->shader_hits[shader]++;
- }
- }
-
- inline void set_object(int object)
- {
- state->object = object;
- if(state->active) {
- assert(object < state->object_hits.size());
- state->object_hits[object]++;
- }
- }
-
- ~ProfilingHelper()
- {
- state->event = previous_event;
- }
-private:
- ProfilingState *state;
- uint32_t previous_event;
+ public:
+ ProfilingHelper(ProfilingState *state, ProfilingEvent event) : state(state)
+ {
+ previous_event = state->event;
+ state->event = event;
+ }
+
+ inline void set_event(ProfilingEvent event)
+ {
+ state->event = event;
+ }
+
+ inline void set_shader(int shader)
+ {
+ state->shader = shader;
+ if (state->active) {
+ assert(shader < state->shader_hits.size());
+ state->shader_hits[shader]++;
+ }
+ }
+
+ inline void set_object(int object)
+ {
+ state->object = object;
+ if (state->active) {
+ assert(object < state->object_hits.size());
+ state->object_hits[object]++;
+ }
+ }
+
+ ~ProfilingHelper()
+ {
+ state->event = previous_event;
+ }
+
+ private:
+ ProfilingState *state;
+ uint32_t previous_event;
};
CCL_NAMESPACE_END
-#endif /* __UTIL_PROFILING_H__ */
+#endif /* __UTIL_PROFILING_H__ */
diff --git a/intern/cycles/util/util_progress.h b/intern/cycles/util/util_progress.h
index 06900d14cdc..f05e5b918f3 100644
--- a/intern/cycles/util/util_progress.h
+++ b/intern/cycles/util/util_progress.h
@@ -31,361 +31,359 @@
CCL_NAMESPACE_BEGIN
class Progress {
-public:
- Progress()
- {
- pixel_samples = 0;
- total_pixel_samples = 0;
- current_tile_sample = 0;
- rendered_tiles = 0;
- denoised_tiles = 0;
- start_time = time_dt();
- render_start_time = time_dt();
- end_time = 0.0;
- status = "Initializing";
- substatus = "";
- sync_status = "";
- sync_substatus = "";
- kernel_status = "";
- update_cb = function_null;
- cancel = false;
- cancel_message = "";
- error = false;
- error_message = "";
- cancel_cb = function_null;
- }
-
- Progress(Progress& progress)
- {
- *this = progress;
- }
-
- Progress& operator=(Progress& progress)
- {
- thread_scoped_lock lock(progress.progress_mutex);
-
- progress.get_status(status, substatus);
-
- pixel_samples = progress.pixel_samples;
- total_pixel_samples = progress.total_pixel_samples;
- current_tile_sample = progress.get_current_sample();
-
- return *this;
- }
-
- void reset()
- {
- pixel_samples = 0;
- total_pixel_samples = 0;
- current_tile_sample = 0;
- rendered_tiles = 0;
- denoised_tiles = 0;
- start_time = time_dt();
- render_start_time = time_dt();
- end_time = 0.0;
- status = "Initializing";
- substatus = "";
- sync_status = "";
- sync_substatus = "";
- kernel_status = "";
- cancel = false;
- cancel_message = "";
- error = false;
- error_message = "";
- }
-
- /* cancel */
- void set_cancel(const string& cancel_message_)
- {
- thread_scoped_lock lock(progress_mutex);
- cancel_message = cancel_message_;
- cancel = true;
- }
-
- bool get_cancel()
- {
- if(!cancel && cancel_cb)
- cancel_cb();
-
- return cancel;
- }
-
- string get_cancel_message()
- {
- thread_scoped_lock lock(progress_mutex);
- return cancel_message;
- }
-
- void set_cancel_callback(function<void()> function)
- {
- cancel_cb = function;
- }
-
- /* error */
- void set_error(const string& error_message_)
- {
- thread_scoped_lock lock(progress_mutex);
- error_message = error_message_;
- error = true;
- /* If error happens we also stop rendering. */
- cancel_message = error_message_;
- cancel = true;
- }
-
- bool get_error()
- {
- return error;
- }
-
- string get_error_message()
- {
- thread_scoped_lock lock(progress_mutex);
- return error_message;
- }
-
- /* tile and timing information */
-
- void set_start_time()
- {
- thread_scoped_lock lock(progress_mutex);
-
- start_time = time_dt();
- end_time = 0.0;
- }
-
- void set_render_start_time()
- {
- thread_scoped_lock lock(progress_mutex);
-
- render_start_time = time_dt();
- }
-
- void add_skip_time(const scoped_timer &start_timer, bool only_render)
- {
- double skip_time = time_dt() - start_timer.get_start();
-
- render_start_time += skip_time;
- if(!only_render) {
- start_time += skip_time;
- }
- }
-
- void get_time(double& total_time_, double& render_time_)
- {
- thread_scoped_lock lock(progress_mutex);
-
- double time = (end_time > 0) ? end_time : time_dt();
-
- total_time_ = time - start_time;
- render_time_ = time - render_start_time;
- }
-
- void set_end_time()
- {
- end_time = time_dt();
- }
-
- void reset_sample()
- {
- thread_scoped_lock lock(progress_mutex);
-
- pixel_samples = 0;
- current_tile_sample = 0;
- rendered_tiles = 0;
- denoised_tiles = 0;
- }
-
- void set_total_pixel_samples(uint64_t total_pixel_samples_)
- {
- thread_scoped_lock lock(progress_mutex);
-
- total_pixel_samples = total_pixel_samples_;
- }
-
- float get_progress()
- {
- if(total_pixel_samples > 0) {
- return ((float) pixel_samples) / total_pixel_samples;
- }
- return 0.0f;
- }
-
- void add_samples(uint64_t pixel_samples_, int tile_sample)
- {
- thread_scoped_lock lock(progress_mutex);
-
- pixel_samples += pixel_samples_;
- current_tile_sample = tile_sample;
- }
-
- void add_samples_update(uint64_t pixel_samples_, int tile_sample)
- {
- add_samples(pixel_samples_, tile_sample);
- set_update();
- }
-
- void add_finished_tile(bool denoised)
- {
- thread_scoped_lock lock(progress_mutex);
-
- if(denoised) {
- denoised_tiles++;
- }
- else {
- rendered_tiles++;
- }
- }
-
- int get_current_sample()
- {
- thread_scoped_lock lock(progress_mutex);
- /* Note that the value here always belongs to the last tile that updated,
- * so it's only useful if there is only one active tile. */
- return current_tile_sample;
- }
-
- int get_rendered_tiles()
- {
- thread_scoped_lock lock(progress_mutex);
- return rendered_tiles;
- }
-
- int get_denoised_tiles()
- {
- thread_scoped_lock lock(progress_mutex);
- return denoised_tiles;
- }
-
- /* status messages */
-
- void set_status(const string& status_, const string& substatus_ = "")
- {
- {
- thread_scoped_lock lock(progress_mutex);
- status = status_;
- substatus = substatus_;
- }
-
- set_update();
- }
-
- void set_substatus(const string& substatus_)
- {
- {
- thread_scoped_lock lock(progress_mutex);
- substatus = substatus_;
- }
-
- set_update();
- }
-
- void set_sync_status(const string& status_, const string& substatus_ = "")
- {
- {
- thread_scoped_lock lock(progress_mutex);
- sync_status = status_;
- sync_substatus = substatus_;
- }
-
- set_update();
-
- }
-
- void set_sync_substatus(const string& substatus_)
- {
- {
- thread_scoped_lock lock(progress_mutex);
- sync_substatus = substatus_;
- }
-
- set_update();
- }
-
- void get_status(string& status_, string& substatus_)
- {
- thread_scoped_lock lock(progress_mutex);
-
- if(sync_status != "") {
- status_ = sync_status;
- substatus_ = sync_substatus;
- }
- else {
- status_ = status;
- substatus_ = substatus;
- }
- }
-
-
- /* kernel status */
-
- void set_kernel_status(const string &kernel_status_)
- {
- {
- thread_scoped_lock lock(progress_mutex);
- kernel_status = kernel_status_;
- }
-
- set_update();
- }
-
- void get_kernel_status(string &kernel_status_)
- {
- thread_scoped_lock lock(progress_mutex);
- kernel_status_ = kernel_status;
- }
-
- /* callback */
-
- void set_update()
- {
- if(update_cb) {
- thread_scoped_lock lock(update_mutex);
- update_cb();
- }
- }
-
- void set_update_callback(function<void()> function)
- {
- update_cb = function;
- }
-
-protected:
- thread_mutex progress_mutex;
- thread_mutex update_mutex;
- function<void()> update_cb;
- function<void()> cancel_cb;
-
- /* pixel_samples counts how many samples have been rendered over all pixel, not just per pixel.
- * This makes the progress estimate more accurate when tiles with different sizes are used.
- *
- * total_pixel_samples is the total amount of pixel samples that will be rendered. */
- uint64_t pixel_samples, total_pixel_samples;
- /* Stores the current sample count of the last tile that called the update function.
- * It's used to display the sample count if only one tile is active. */
- int current_tile_sample;
- /* Stores the number of tiles that's already finished.
- * Used to determine whether all but the last tile are finished rendering, in which case the current_tile_sample is displayed. */
- int rendered_tiles, denoised_tiles;
-
- double start_time, render_start_time;
- /* End time written when render is done, so it doesn't keep increasing on redraws. */
- double end_time;
-
- string status;
- string substatus;
-
- string sync_status;
- string sync_substatus;
-
- string kernel_status;
-
- volatile bool cancel;
- string cancel_message;
-
- volatile bool error;
- string error_message;
+ public:
+ Progress()
+ {
+ pixel_samples = 0;
+ total_pixel_samples = 0;
+ current_tile_sample = 0;
+ rendered_tiles = 0;
+ denoised_tiles = 0;
+ start_time = time_dt();
+ render_start_time = time_dt();
+ end_time = 0.0;
+ status = "Initializing";
+ substatus = "";
+ sync_status = "";
+ sync_substatus = "";
+ kernel_status = "";
+ update_cb = function_null;
+ cancel = false;
+ cancel_message = "";
+ error = false;
+ error_message = "";
+ cancel_cb = function_null;
+ }
+
+ Progress(Progress &progress)
+ {
+ *this = progress;
+ }
+
+ Progress &operator=(Progress &progress)
+ {
+ thread_scoped_lock lock(progress.progress_mutex);
+
+ progress.get_status(status, substatus);
+
+ pixel_samples = progress.pixel_samples;
+ total_pixel_samples = progress.total_pixel_samples;
+ current_tile_sample = progress.get_current_sample();
+
+ return *this;
+ }
+
+ void reset()
+ {
+ pixel_samples = 0;
+ total_pixel_samples = 0;
+ current_tile_sample = 0;
+ rendered_tiles = 0;
+ denoised_tiles = 0;
+ start_time = time_dt();
+ render_start_time = time_dt();
+ end_time = 0.0;
+ status = "Initializing";
+ substatus = "";
+ sync_status = "";
+ sync_substatus = "";
+ kernel_status = "";
+ cancel = false;
+ cancel_message = "";
+ error = false;
+ error_message = "";
+ }
+
+ /* cancel */
+ void set_cancel(const string &cancel_message_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+ cancel_message = cancel_message_;
+ cancel = true;
+ }
+
+ bool get_cancel()
+ {
+ if (!cancel && cancel_cb)
+ cancel_cb();
+
+ return cancel;
+ }
+
+ string get_cancel_message()
+ {
+ thread_scoped_lock lock(progress_mutex);
+ return cancel_message;
+ }
+
+ void set_cancel_callback(function<void()> function)
+ {
+ cancel_cb = function;
+ }
+
+ /* error */
+ void set_error(const string &error_message_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+ error_message = error_message_;
+ error = true;
+ /* If error happens we also stop rendering. */
+ cancel_message = error_message_;
+ cancel = true;
+ }
+
+ bool get_error()
+ {
+ return error;
+ }
+
+ string get_error_message()
+ {
+ thread_scoped_lock lock(progress_mutex);
+ return error_message;
+ }
+
+ /* tile and timing information */
+
+ void set_start_time()
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ start_time = time_dt();
+ end_time = 0.0;
+ }
+
+ void set_render_start_time()
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ render_start_time = time_dt();
+ }
+
+ void add_skip_time(const scoped_timer &start_timer, bool only_render)
+ {
+ double skip_time = time_dt() - start_timer.get_start();
+
+ render_start_time += skip_time;
+ if (!only_render) {
+ start_time += skip_time;
+ }
+ }
+
+ void get_time(double &total_time_, double &render_time_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ double time = (end_time > 0) ? end_time : time_dt();
+
+ total_time_ = time - start_time;
+ render_time_ = time - render_start_time;
+ }
+
+ void set_end_time()
+ {
+ end_time = time_dt();
+ }
+
+ void reset_sample()
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ pixel_samples = 0;
+ current_tile_sample = 0;
+ rendered_tiles = 0;
+ denoised_tiles = 0;
+ }
+
+ void set_total_pixel_samples(uint64_t total_pixel_samples_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ total_pixel_samples = total_pixel_samples_;
+ }
+
+ float get_progress()
+ {
+ if (total_pixel_samples > 0) {
+ return ((float)pixel_samples) / total_pixel_samples;
+ }
+ return 0.0f;
+ }
+
+ void add_samples(uint64_t pixel_samples_, int tile_sample)
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ pixel_samples += pixel_samples_;
+ current_tile_sample = tile_sample;
+ }
+
+ void add_samples_update(uint64_t pixel_samples_, int tile_sample)
+ {
+ add_samples(pixel_samples_, tile_sample);
+ set_update();
+ }
+
+ void add_finished_tile(bool denoised)
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ if (denoised) {
+ denoised_tiles++;
+ }
+ else {
+ rendered_tiles++;
+ }
+ }
+
+ int get_current_sample()
+ {
+ thread_scoped_lock lock(progress_mutex);
+ /* Note that the value here always belongs to the last tile that updated,
+ * so it's only useful if there is only one active tile. */
+ return current_tile_sample;
+ }
+
+ int get_rendered_tiles()
+ {
+ thread_scoped_lock lock(progress_mutex);
+ return rendered_tiles;
+ }
+
+ int get_denoised_tiles()
+ {
+ thread_scoped_lock lock(progress_mutex);
+ return denoised_tiles;
+ }
+
+ /* status messages */
+
+ void set_status(const string &status_, const string &substatus_ = "")
+ {
+ {
+ thread_scoped_lock lock(progress_mutex);
+ status = status_;
+ substatus = substatus_;
+ }
+
+ set_update();
+ }
+
+ void set_substatus(const string &substatus_)
+ {
+ {
+ thread_scoped_lock lock(progress_mutex);
+ substatus = substatus_;
+ }
+
+ set_update();
+ }
+
+ void set_sync_status(const string &status_, const string &substatus_ = "")
+ {
+ {
+ thread_scoped_lock lock(progress_mutex);
+ sync_status = status_;
+ sync_substatus = substatus_;
+ }
+
+ set_update();
+ }
+
+ void set_sync_substatus(const string &substatus_)
+ {
+ {
+ thread_scoped_lock lock(progress_mutex);
+ sync_substatus = substatus_;
+ }
+
+ set_update();
+ }
+
+ void get_status(string &status_, string &substatus_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ if (sync_status != "") {
+ status_ = sync_status;
+ substatus_ = sync_substatus;
+ }
+ else {
+ status_ = status;
+ substatus_ = substatus;
+ }
+ }
+
+ /* kernel status */
+
+ void set_kernel_status(const string &kernel_status_)
+ {
+ {
+ thread_scoped_lock lock(progress_mutex);
+ kernel_status = kernel_status_;
+ }
+
+ set_update();
+ }
+
+ void get_kernel_status(string &kernel_status_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+ kernel_status_ = kernel_status;
+ }
+
+ /* callback */
+
+ void set_update()
+ {
+ if (update_cb) {
+ thread_scoped_lock lock(update_mutex);
+ update_cb();
+ }
+ }
+
+ void set_update_callback(function<void()> function)
+ {
+ update_cb = function;
+ }
+
+ protected:
+ thread_mutex progress_mutex;
+ thread_mutex update_mutex;
+ function<void()> update_cb;
+ function<void()> cancel_cb;
+
+ /* pixel_samples counts how many samples have been rendered over all pixel, not just per pixel.
+ * This makes the progress estimate more accurate when tiles with different sizes are used.
+ *
+ * total_pixel_samples is the total amount of pixel samples that will be rendered. */
+ uint64_t pixel_samples, total_pixel_samples;
+ /* Stores the current sample count of the last tile that called the update function.
+ * It's used to display the sample count if only one tile is active. */
+ int current_tile_sample;
+ /* Stores the number of tiles that's already finished.
+ * Used to determine whether all but the last tile are finished rendering, in which case the current_tile_sample is displayed. */
+ int rendered_tiles, denoised_tiles;
+
+ double start_time, render_start_time;
+ /* End time written when render is done, so it doesn't keep increasing on redraws. */
+ double end_time;
+
+ string status;
+ string substatus;
+
+ string sync_status;
+ string sync_substatus;
+
+ string kernel_status;
+
+ volatile bool cancel;
+ string cancel_message;
+
+ volatile bool error;
+ string error_message;
};
CCL_NAMESPACE_END
-#endif /* __UTIL_PROGRESS_H__ */
+#endif /* __UTIL_PROGRESS_H__ */
diff --git a/intern/cycles/util/util_projection.h b/intern/cycles/util/util_projection.h
index d1af013ae3a..416af18b53e 100644
--- a/intern/cycles/util/util_projection.h
+++ b/intern/cycles/util/util_projection.h
@@ -24,153 +24,193 @@ CCL_NAMESPACE_BEGIN
/* 4x4 projection matrix, perspective or orthographic. */
typedef struct ProjectionTransform {
- float4 x, y, z, w; /* rows */
+ float4 x, y, z, w; /* rows */
#ifndef __KERNEL_GPU__
- ProjectionTransform()
- {
- }
-
- explicit ProjectionTransform(const Transform& tfm)
- : x(tfm.x),
- y(tfm.y),
- z(tfm.z),
- w(make_float4(0.0f, 0.0f, 0.0f, 1.0f))
- {
- }
+ ProjectionTransform()
+ {
+ }
+
+ explicit ProjectionTransform(const Transform &tfm)
+ : x(tfm.x), y(tfm.y), z(tfm.z), w(make_float4(0.0f, 0.0f, 0.0f, 1.0f))
+ {
+ }
#endif
} ProjectionTransform;
typedef struct PerspectiveMotionTransform {
- ProjectionTransform pre;
- ProjectionTransform post;
+ ProjectionTransform pre;
+ ProjectionTransform post;
} PerspectiveMotionTransform;
/* Functions */
ccl_device_inline float3 transform_perspective(const ProjectionTransform *t, const float3 a)
{
- float4 b = make_float4(a.x, a.y, a.z, 1.0f);
- float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
- float w = dot(t->w, b);
+ float4 b = make_float4(a.x, a.y, a.z, 1.0f);
+ float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
+ float w = dot(t->w, b);
- return (w != 0.0f)? c/w: make_float3(0.0f, 0.0f, 0.0f);
+ return (w != 0.0f) ? c / w : make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device_inline float3 transform_perspective_direction(const ProjectionTransform *t, const float3 a)
+ccl_device_inline float3 transform_perspective_direction(const ProjectionTransform *t,
+ const float3 a)
{
- float3 c = make_float3(
- a.x*t->x.x + a.y*t->x.y + a.z*t->x.z,
- a.x*t->y.x + a.y*t->y.y + a.z*t->y.z,
- a.x*t->z.x + a.y*t->z.y + a.z*t->z.z);
+ float3 c = make_float3(a.x * t->x.x + a.y * t->x.y + a.z * t->x.z,
+ a.x * t->y.x + a.y * t->y.y + a.z * t->y.z,
+ a.x * t->z.x + a.y * t->z.y + a.z * t->z.z);
- return c;
+ return c;
}
#ifndef __KERNEL_GPU__
-ccl_device_inline Transform projection_to_transform(const ProjectionTransform& a)
+ccl_device_inline Transform projection_to_transform(const ProjectionTransform &a)
{
- Transform tfm = {a.x, a.y, a.z};
- return tfm;
+ Transform tfm = {a.x, a.y, a.z};
+ return tfm;
}
-ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform& a)
+ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform &a)
{
- ProjectionTransform t;
-
- t.x.x = a.x.x; t.x.y = a.y.x; t.x.z = a.z.x; t.x.w = a.w.x;
- t.y.x = a.x.y; t.y.y = a.y.y; t.y.z = a.z.y; t.y.w = a.w.y;
- t.z.x = a.x.z; t.z.y = a.y.z; t.z.z = a.z.z; t.z.w = a.w.z;
- t.w.x = a.x.w; t.w.y = a.y.w; t.w.z = a.z.w; t.w.w = a.w.w;
-
- return t;
+ ProjectionTransform t;
+
+ t.x.x = a.x.x;
+ t.x.y = a.y.x;
+ t.x.z = a.z.x;
+ t.x.w = a.w.x;
+ t.y.x = a.x.y;
+ t.y.y = a.y.y;
+ t.y.z = a.z.y;
+ t.y.w = a.w.y;
+ t.z.x = a.x.z;
+ t.z.y = a.y.z;
+ t.z.z = a.z.z;
+ t.z.w = a.w.z;
+ t.w.x = a.x.w;
+ t.w.y = a.y.w;
+ t.w.z = a.z.w;
+ t.w.w = a.w.w;
+
+ return t;
}
-ProjectionTransform projection_inverse(const ProjectionTransform& a);
-
-ccl_device_inline ProjectionTransform make_projection(
- float a, float b, float c, float d,
- float e, float f, float g, float h,
- float i, float j, float k, float l,
- float m, float n, float o, float p)
+ProjectionTransform projection_inverse(const ProjectionTransform &a);
+
+ccl_device_inline ProjectionTransform make_projection(float a,
+ float b,
+ float c,
+ float d,
+ float e,
+ float f,
+ float g,
+ float h,
+ float i,
+ float j,
+ float k,
+ float l,
+ float m,
+ float n,
+ float o,
+ float p)
{
- ProjectionTransform t;
-
- t.x.x = a; t.x.y = b; t.x.z = c; t.x.w = d;
- t.y.x = e; t.y.y = f; t.y.z = g; t.y.w = h;
- t.z.x = i; t.z.y = j; t.z.z = k; t.z.w = l;
- t.w.x = m; t.w.y = n; t.w.z = o; t.w.w = p;
-
- return t;
+ ProjectionTransform t;
+
+ t.x.x = a;
+ t.x.y = b;
+ t.x.z = c;
+ t.x.w = d;
+ t.y.x = e;
+ t.y.y = f;
+ t.y.z = g;
+ t.y.w = h;
+ t.z.x = i;
+ t.z.y = j;
+ t.z.z = k;
+ t.z.w = l;
+ t.w.x = m;
+ t.w.y = n;
+ t.w.z = o;
+ t.w.w = p;
+
+ return t;
}
ccl_device_inline ProjectionTransform projection_identity()
{
- return make_projection(
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
+ return make_projection(1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f);
}
-ccl_device_inline ProjectionTransform operator*(const ProjectionTransform& a, const ProjectionTransform& b)
+ccl_device_inline ProjectionTransform operator*(const ProjectionTransform &a,
+ const ProjectionTransform &b)
{
- ProjectionTransform c = projection_transpose(b);
- ProjectionTransform t;
+ ProjectionTransform c = projection_transpose(b);
+ ProjectionTransform t;
- t.x = make_float4(dot(a.x, c.x), dot(a.x, c.y), dot(a.x, c.z), dot(a.x, c.w));
- t.y = make_float4(dot(a.y, c.x), dot(a.y, c.y), dot(a.y, c.z), dot(a.y, c.w));
- t.z = make_float4(dot(a.z, c.x), dot(a.z, c.y), dot(a.z, c.z), dot(a.z, c.w));
- t.w = make_float4(dot(a.w, c.x), dot(a.w, c.y), dot(a.w, c.z), dot(a.w, c.w));
+ t.x = make_float4(dot(a.x, c.x), dot(a.x, c.y), dot(a.x, c.z), dot(a.x, c.w));
+ t.y = make_float4(dot(a.y, c.x), dot(a.y, c.y), dot(a.y, c.z), dot(a.y, c.w));
+ t.z = make_float4(dot(a.z, c.x), dot(a.z, c.y), dot(a.z, c.z), dot(a.z, c.w));
+ t.w = make_float4(dot(a.w, c.x), dot(a.w, c.y), dot(a.w, c.z), dot(a.w, c.w));
- return t;
+ return t;
}
-ccl_device_inline ProjectionTransform operator*(const ProjectionTransform& a, const Transform& b)
+ccl_device_inline ProjectionTransform operator*(const ProjectionTransform &a, const Transform &b)
{
- return a * ProjectionTransform(b);
+ return a * ProjectionTransform(b);
}
-ccl_device_inline ProjectionTransform operator*(const Transform& a, const ProjectionTransform& b)
+ccl_device_inline ProjectionTransform operator*(const Transform &a, const ProjectionTransform &b)
{
- return ProjectionTransform(a) * b;
+ return ProjectionTransform(a) * b;
}
-ccl_device_inline void print_projection(const char *label, const ProjectionTransform& t)
+ccl_device_inline void print_projection(const char *label, const ProjectionTransform &t)
{
- print_float4(label, t.x);
- print_float4(label, t.y);
- print_float4(label, t.z);
- print_float4(label, t.w);
- printf("\n");
+ print_float4(label, t.x);
+ print_float4(label, t.y);
+ print_float4(label, t.z);
+ print_float4(label, t.w);
+ printf("\n");
}
ccl_device_inline ProjectionTransform projection_perspective(float fov, float n, float f)
{
- ProjectionTransform persp = make_projection(
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, f / (f - n), -f*n / (f - n),
- 0, 0, 1, 0);
+ ProjectionTransform persp = make_projection(
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, f / (f - n), -f * n / (f - n), 0, 0, 1, 0);
- float inv_angle = 1.0f/tanf(0.5f*fov);
+ float inv_angle = 1.0f / tanf(0.5f * fov);
- Transform scale = transform_scale(inv_angle, inv_angle, 1);
+ Transform scale = transform_scale(inv_angle, inv_angle, 1);
- return scale * persp;
+ return scale * persp;
}
ccl_device_inline ProjectionTransform projection_orthographic(float znear, float zfar)
{
- Transform t =
- transform_scale(1.0f, 1.0f, 1.0f / (zfar-znear)) *
- transform_translate(0.0f, 0.0f, -znear);
+ Transform t = transform_scale(1.0f, 1.0f, 1.0f / (zfar - znear)) *
+ transform_translate(0.0f, 0.0f, -znear);
- return ProjectionTransform(t);
+ return ProjectionTransform(t);
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_PROJECTION_H__ */
+#endif /* __UTIL_PROJECTION_H__ */
diff --git a/intern/cycles/util/util_queue.h b/intern/cycles/util/util_queue.h
index 0a2b7718f57..622f4fe3e47 100644
--- a/intern/cycles/util/util_queue.h
+++ b/intern/cycles/util/util_queue.h
@@ -25,4 +25,4 @@ using std::queue;
CCL_NAMESPACE_END
-#endif /* __UTIL_LIST_H__ */
+#endif /* __UTIL_LIST_H__ */
diff --git a/intern/cycles/util/util_rect.h b/intern/cycles/util/util_rect.h
index 389669acf2e..36f02a01f7b 100644
--- a/intern/cycles/util/util_rect.h
+++ b/intern/cycles/util/util_rect.h
@@ -26,47 +26,47 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline int4 rect_from_shape(int x0, int y0, int w, int h)
{
- return make_int4(x0, y0, x0 + w, y0 + h);
+ return make_int4(x0, y0, x0 + w, y0 + h);
}
ccl_device_inline int4 rect_expand(int4 rect, int d)
{
- return make_int4(rect.x - d, rect.y - d, rect.z + d, rect.w + d);
+ return make_int4(rect.x - d, rect.y - d, rect.z + d, rect.w + d);
}
/* Returns the intersection of two rects. */
ccl_device_inline int4 rect_clip(int4 a, int4 b)
{
- return make_int4(max(a.x, b.x), max(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
+ return make_int4(max(a.x, b.x), max(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
}
ccl_device_inline bool rect_is_valid(int4 rect)
{
- return (rect.z > rect.x) && (rect.w > rect.y);
+ return (rect.z > rect.x) && (rect.w > rect.y);
}
/* Returns the local row-major index of the pixel inside the rect. */
ccl_device_inline int coord_to_local_index(int4 rect, int x, int y)
{
- int w = rect.z - rect.x;
- return (y - rect.y) * w + (x - rect.x);
+ int w = rect.z - rect.x;
+ return (y - rect.y) * w + (x - rect.x);
}
/* Finds the coordinates of a pixel given by its row-major index in the rect,
* and returns whether the pixel is inside it. */
ccl_device_inline bool local_index_to_coord(int4 rect, int idx, int *x, int *y)
{
- int w = rect.z - rect.x;
- *x = (idx % w) + rect.x;
- *y = (idx / w) + rect.y;
- return (*y < rect.w);
+ int w = rect.z - rect.x;
+ *x = (idx % w) + rect.x;
+ *y = (idx / w) + rect.y;
+ return (*y < rect.w);
}
ccl_device_inline int rect_size(int4 rect)
{
- return (rect.z - rect.x) * (rect.w - rect.y);
+ return (rect.z - rect.x) * (rect.w - rect.y);
}
CCL_NAMESPACE_END
-#endif /* __UTIL_RECT_H__ */
+#endif /* __UTIL_RECT_H__ */
diff --git a/intern/cycles/util/util_set.h b/intern/cycles/util/util_set.h
index a9c56bb4919..298e1f7729a 100644
--- a/intern/cycles/util/util_set.h
+++ b/intern/cycles/util/util_set.h
@@ -31,4 +31,4 @@ using std::unordered_set;
CCL_NAMESPACE_END
-#endif /* __UTIL_SET_H__ */
+#endif /* __UTIL_SET_H__ */
diff --git a/intern/cycles/util/util_simd.cpp b/intern/cycles/util/util_simd.cpp
index f90439c188b..861dcf1fe36 100644
--- a/intern/cycles/util/util_simd.cpp
+++ b/intern/cycles/util/util_simd.cpp
@@ -15,33 +15,29 @@
* limitations under the License.
*/
-#if (defined(WITH_KERNEL_SSE2)) || \
- (defined(WITH_KERNEL_NATIVE) && defined(__SSE2__))
+#if (defined(WITH_KERNEL_SSE2)) || (defined(WITH_KERNEL_NATIVE) && defined(__SSE2__))
-#define __KERNEL_SSE2__
-#include "util/util_simd.h"
+# define __KERNEL_SSE2__
+# include "util/util_simd.h"
CCL_NAMESPACE_BEGIN
-const __m128 _mm_lookupmask_ps[16] = {
- _mm_castsi128_ps(_mm_set_epi32( 0, 0, 0, 0)),
- _mm_castsi128_ps(_mm_set_epi32( 0, 0, 0,-1)),
- _mm_castsi128_ps(_mm_set_epi32( 0, 0,-1, 0)),
- _mm_castsi128_ps(_mm_set_epi32( 0, 0,-1,-1)),
- _mm_castsi128_ps(_mm_set_epi32( 0,-1, 0, 0)),
- _mm_castsi128_ps(_mm_set_epi32( 0,-1, 0,-1)),
- _mm_castsi128_ps(_mm_set_epi32( 0,-1,-1, 0)),
- _mm_castsi128_ps(_mm_set_epi32( 0,-1,-1,-1)),
- _mm_castsi128_ps(_mm_set_epi32(-1, 0, 0, 0)),
- _mm_castsi128_ps(_mm_set_epi32(-1, 0, 0,-1)),
- _mm_castsi128_ps(_mm_set_epi32(-1, 0,-1, 0)),
- _mm_castsi128_ps(_mm_set_epi32(-1, 0,-1,-1)),
- _mm_castsi128_ps(_mm_set_epi32(-1,-1, 0, 0)),
- _mm_castsi128_ps(_mm_set_epi32(-1,-1, 0,-1)),
- _mm_castsi128_ps(_mm_set_epi32(-1,-1,-1, 0)),
- _mm_castsi128_ps(_mm_set_epi32(-1,-1,-1,-1))
-};
-
+const __m128 _mm_lookupmask_ps[16] = {_mm_castsi128_ps(_mm_set_epi32(0, 0, 0, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(0, 0, 0, -1)),
+ _mm_castsi128_ps(_mm_set_epi32(0, 0, -1, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(0, 0, -1, -1)),
+ _mm_castsi128_ps(_mm_set_epi32(0, -1, 0, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(0, -1, 0, -1)),
+ _mm_castsi128_ps(_mm_set_epi32(0, -1, -1, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(0, -1, -1, -1)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, 0, 0, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, 0, 0, -1)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, 0, -1, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, 0, -1, -1)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, -1, 0, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, -1, 0, -1)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, -1, -1, 0)),
+ _mm_castsi128_ps(_mm_set_epi32(-1, -1, -1, -1))};
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_simd.h b/intern/cycles/util/util_simd.h
index c92fc1ae391..8fcaadc5f53 100644
--- a/intern/cycles/util/util_simd.h
+++ b/intern/cycles/util/util_simd.h
@@ -20,439 +20,550 @@
#ifndef __KERNEL_GPU__
-#include <limits>
+# include <limits>
-#include "util/util_defines.h"
+# include "util/util_defines.h"
/* SSE Intrinsics includes
*
* We assume __KERNEL_SSEX__ flags to have been defined at this point */
/* SSE intrinsics headers */
-#ifndef FREE_WINDOWS64
+# ifndef FREE_WINDOWS64
-#ifdef _MSC_VER
-# include <intrin.h>
-#elif (defined(__x86_64__) || defined(__i386__))
-# include <x86intrin.h>
-#endif
+# ifdef _MSC_VER
+# include <intrin.h>
+# elif (defined(__x86_64__) || defined(__i386__))
+# include <x86intrin.h>
+# endif
-#else
+# else
/* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
* Since we can't avoid including <windows.h>, better only include that */
-#include "util/util_windows.h"
+# include "util/util_windows.h"
-#endif
+# endif
-#if defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)
- #define SIMD_SET_FLUSH_TO_ZERO \
- _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); \
- _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
-#else
- #define SIMD_SET_FLUSH_TO_ZERO
-#endif
+# if defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)
+# define SIMD_SET_FLUSH_TO_ZERO \
+ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); \
+ _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
+# else
+# define SIMD_SET_FLUSH_TO_ZERO
+# endif
CCL_NAMESPACE_BEGIN
-#ifdef __KERNEL_SSE2__
+# ifdef __KERNEL_SSE2__
extern const __m128 _mm_lookupmask_ps[16];
/* Special Types */
static struct TrueTy {
-__forceinline operator bool( ) const { return true; }
+ __forceinline operator bool() const
+ {
+ return true;
+ }
} True ccl_maybe_unused;
static struct FalseTy {
-__forceinline operator bool( ) const { return false; }
+ __forceinline operator bool() const
+ {
+ return false;
+ }
} False ccl_maybe_unused;
-static struct NegInfTy
-{
-__forceinline operator float ( ) const { return -std::numeric_limits<float>::infinity(); }
-__forceinline operator int ( ) const { return std::numeric_limits<int>::min(); }
+static struct NegInfTy {
+ __forceinline operator float() const
+ {
+ return -std::numeric_limits<float>::infinity();
+ }
+ __forceinline operator int() const
+ {
+ return std::numeric_limits<int>::min();
+ }
} neg_inf ccl_maybe_unused;
-static struct PosInfTy
-{
-__forceinline operator float ( ) const { return std::numeric_limits<float>::infinity(); }
-__forceinline operator int ( ) const { return std::numeric_limits<int>::max(); }
+static struct PosInfTy {
+ __forceinline operator float() const
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ __forceinline operator int() const
+ {
+ return std::numeric_limits<int>::max();
+ }
} inf ccl_maybe_unused, pos_inf ccl_maybe_unused;
/* Intrinsics Functions */
-#if defined(__BMI__) && defined(__GNUC__)
-# ifndef _tzcnt_u32
-# define _tzcnt_u32 __tzcnt_u32
-# endif
-# ifndef _tzcnt_u64
-# define _tzcnt_u64 __tzcnt_u64
-# endif
-#endif
+# if defined(__BMI__) && defined(__GNUC__)
+# ifndef _tzcnt_u32
+# define _tzcnt_u32 __tzcnt_u32
+# endif
+# ifndef _tzcnt_u64
+# define _tzcnt_u64 __tzcnt_u64
+# endif
+# endif
-#if defined(__LZCNT__)
-#define _lzcnt_u32 __lzcnt32
-#define _lzcnt_u64 __lzcnt64
-#endif
+# if defined(__LZCNT__)
+# define _lzcnt_u32 __lzcnt32
+# define _lzcnt_u64 __lzcnt64
+# endif
-#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__clang__)
+# if defined(_WIN32) && !defined(__MINGW32__) && !defined(__clang__)
-__forceinline int __popcnt(int in) {
+__forceinline int __popcnt(int in)
+{
return _mm_popcnt_u32(in);
}
-#if !defined(_MSC_VER)
-__forceinline unsigned int __popcnt(unsigned int in) {
+# if !defined(_MSC_VER)
+__forceinline unsigned int __popcnt(unsigned int in)
+{
return _mm_popcnt_u32(in);
}
-#endif
+# endif
-#if defined(__KERNEL_64_BIT__)
-__forceinline long long __popcnt(long long in) {
+# if defined(__KERNEL_64_BIT__)
+__forceinline long long __popcnt(long long in)
+{
return _mm_popcnt_u64(in);
}
-__forceinline size_t __popcnt(size_t in) {
+__forceinline size_t __popcnt(size_t in)
+{
return _mm_popcnt_u64(in);
}
-#endif
+# endif
-__forceinline int __bsf(int v) {
-#if defined(__KERNEL_AVX2__)
+__forceinline int __bsf(int v)
+{
+# if defined(__KERNEL_AVX2__)
return _tzcnt_u32(v);
-#else
- unsigned long r = 0; _BitScanForward(&r,v); return r;
-#endif
+# else
+ unsigned long r = 0;
+ _BitScanForward(&r, v);
+ return r;
+# endif
}
-__forceinline unsigned int __bsf(unsigned int v) {
-#if defined(__KERNEL_AVX2__)
+__forceinline unsigned int __bsf(unsigned int v)
+{
+# if defined(__KERNEL_AVX2__)
return _tzcnt_u32(v);
-#else
- unsigned long r = 0; _BitScanForward(&r,v); return r;
-#endif
+# else
+ unsigned long r = 0;
+ _BitScanForward(&r, v);
+ return r;
+# endif
}
-__forceinline int __bsr(int v) {
- unsigned long r = 0; _BitScanReverse(&r,v); return r;
+__forceinline int __bsr(int v)
+{
+ unsigned long r = 0;
+ _BitScanReverse(&r, v);
+ return r;
}
-__forceinline int __btc(int v, int i) {
- long r = v; _bittestandcomplement(&r,i); return r;
+__forceinline int __btc(int v, int i)
+{
+ long r = v;
+ _bittestandcomplement(&r, i);
+ return r;
}
-__forceinline int __bts(int v, int i) {
- long r = v; _bittestandset(&r,i); return r;
+__forceinline int __bts(int v, int i)
+{
+ long r = v;
+ _bittestandset(&r, i);
+ return r;
}
-__forceinline int __btr(int v, int i) {
- long r = v; _bittestandreset(&r,i); return r;
+__forceinline int __btr(int v, int i)
+{
+ long r = v;
+ _bittestandreset(&r, i);
+ return r;
}
-__forceinline int bitscan(int v) {
-#if defined(__KERNEL_AVX2__)
+__forceinline int bitscan(int v)
+{
+# if defined(__KERNEL_AVX2__)
return _tzcnt_u32(v);
-#else
+# else
return __bsf(v);
-#endif
+# endif
}
__forceinline int clz(const int x)
{
-#if defined(__KERNEL_AVX2__)
+# if defined(__KERNEL_AVX2__)
return _lzcnt_u32(x);
-#else
- if(UNLIKELY(x == 0)) return 32;
+# else
+ if (UNLIKELY(x == 0))
+ return 32;
return 31 - __bsr(x);
-#endif
+# endif
}
-__forceinline int __bscf(int& v)
+__forceinline int __bscf(int &v)
{
int i = __bsf(v);
- v &= v-1;
+ v &= v - 1;
return i;
}
-__forceinline unsigned int __bscf(unsigned int& v)
+__forceinline unsigned int __bscf(unsigned int &v)
{
unsigned int i = __bsf(v);
- v &= v-1;
+ v &= v - 1;
return i;
}
-#if defined(__KERNEL_64_BIT__)
+# if defined(__KERNEL_64_BIT__)
-__forceinline size_t __bsf(size_t v) {
-#if defined(__KERNEL_AVX2__)
+__forceinline size_t __bsf(size_t v)
+{
+# if defined(__KERNEL_AVX2__)
return _tzcnt_u64(v);
-#else
- unsigned long r = 0; _BitScanForward64(&r,v); return r;
-#endif
+# else
+ unsigned long r = 0;
+ _BitScanForward64(&r, v);
+ return r;
+# endif
}
-__forceinline size_t __bsr(size_t v) {
- unsigned long r = 0; _BitScanReverse64(&r,v); return r;
+__forceinline size_t __bsr(size_t v)
+{
+ unsigned long r = 0;
+ _BitScanReverse64(&r, v);
+ return r;
}
-__forceinline size_t __btc(size_t v, size_t i) {
- size_t r = v; _bittestandcomplement64((__int64*)&r,i); return r;
+__forceinline size_t __btc(size_t v, size_t i)
+{
+ size_t r = v;
+ _bittestandcomplement64((__int64 *)&r, i);
+ return r;
}
-__forceinline size_t __bts(size_t v, size_t i) {
- __int64 r = v; _bittestandset64(&r,i); return r;
+__forceinline size_t __bts(size_t v, size_t i)
+{
+ __int64 r = v;
+ _bittestandset64(&r, i);
+ return r;
}
-__forceinline size_t __btr(size_t v, size_t i) {
- __int64 r = v; _bittestandreset64(&r,i); return r;
+__forceinline size_t __btr(size_t v, size_t i)
+{
+ __int64 r = v;
+ _bittestandreset64(&r, i);
+ return r;
}
-__forceinline size_t bitscan(size_t v) {
-#if defined(__KERNEL_AVX2__)
-#if defined(__KERNEL_64_BIT__)
+__forceinline size_t bitscan(size_t v)
+{
+# if defined(__KERNEL_AVX2__)
+# if defined(__KERNEL_64_BIT__)
return _tzcnt_u64(v);
-#else
+# else
return _tzcnt_u32(v);
-#endif
-#else
+# endif
+# else
return __bsf(v);
-#endif
+# endif
}
-__forceinline size_t __bscf(size_t& v)
+__forceinline size_t __bscf(size_t &v)
{
size_t i = __bsf(v);
- v &= v-1;
+ v &= v - 1;
return i;
}
-#endif /* __KERNEL_64_BIT__ */
+# endif /* __KERNEL_64_BIT__ */
-#else /* _WIN32 */
+# else /* _WIN32 */
-__forceinline unsigned int __popcnt(unsigned int in) {
- int r = 0; asm ("popcnt %1,%0" : "=r"(r) : "r"(in)); return r;
+__forceinline unsigned int __popcnt(unsigned int in)
+{
+ int r = 0;
+ asm("popcnt %1,%0" : "=r"(r) : "r"(in));
+ return r;
}
-__forceinline int __bsf(int v) {
- int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r;
+__forceinline int __bsf(int v)
+{
+ int r = 0;
+ asm("bsf %1,%0" : "=r"(r) : "r"(v));
+ return r;
}
-__forceinline int __bsr(int v) {
- int r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r;
+__forceinline int __bsr(int v)
+{
+ int r = 0;
+ asm("bsr %1,%0" : "=r"(r) : "r"(v));
+ return r;
}
-__forceinline int __btc(int v, int i) {
- int r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r;
+__forceinline int __btc(int v, int i)
+{
+ int r = 0;
+ asm("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags");
+ return r;
}
-__forceinline int __bts(int v, int i) {
- int r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
+__forceinline int __bts(int v, int i)
+{
+ int r = 0;
+ asm("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags");
+ return r;
}
-__forceinline int __btr(int v, int i) {
- int r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
+__forceinline int __btr(int v, int i)
+{
+ int r = 0;
+ asm("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags");
+ return r;
}
-#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
-__forceinline size_t __bsf(size_t v) {
- size_t r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r;
+# if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && \
+ !(defined(__ILP32__) && defined(__x86_64__))
+__forceinline size_t __bsf(size_t v)
+{
+ size_t r = 0;
+ asm("bsf %1,%0" : "=r"(r) : "r"(v));
+ return r;
}
-#endif
+# endif
-__forceinline unsigned int __bsf(unsigned int v) {
- unsigned int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r;
+__forceinline unsigned int __bsf(unsigned int v)
+{
+ unsigned int r = 0;
+ asm("bsf %1,%0" : "=r"(r) : "r"(v));
+ return r;
}
-__forceinline size_t __bsr(size_t v) {
- size_t r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r;
+__forceinline size_t __bsr(size_t v)
+{
+ size_t r = 0;
+ asm("bsr %1,%0" : "=r"(r) : "r"(v));
+ return r;
}
-__forceinline size_t __btc(size_t v, size_t i) {
- size_t r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r;
+__forceinline size_t __btc(size_t v, size_t i)
+{
+ size_t r = 0;
+ asm("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags");
+ return r;
}
-__forceinline size_t __bts(size_t v, size_t i) {
- size_t r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
+__forceinline size_t __bts(size_t v, size_t i)
+{
+ size_t r = 0;
+ asm("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags");
+ return r;
}
-__forceinline size_t __btr(size_t v, size_t i) {
- size_t r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
+__forceinline size_t __btr(size_t v, size_t i)
+{
+ size_t r = 0;
+ asm("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags");
+ return r;
}
-__forceinline int bitscan(int v) {
-#if defined(__KERNEL_AVX2__)
+__forceinline int bitscan(int v)
+{
+# if defined(__KERNEL_AVX2__)
return _tzcnt_u32(v);
-#else
+# else
return __bsf(v);
-#endif
+# endif
}
-__forceinline unsigned int bitscan(unsigned int v) {
-#if defined(__KERNEL_AVX2__)
+__forceinline unsigned int bitscan(unsigned int v)
+{
+# if defined(__KERNEL_AVX2__)
return _tzcnt_u32(v);
-#else
+# else
return __bsf(v);
-#endif
+# endif
}
-#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
-__forceinline size_t bitscan(size_t v) {
-#if defined(__KERNEL_AVX2__)
-#if defined(__KERNEL_64_BIT__)
+# if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && \
+ !(defined(__ILP32__) && defined(__x86_64__))
+__forceinline size_t bitscan(size_t v)
+{
+# if defined(__KERNEL_AVX2__)
+# if defined(__KERNEL_64_BIT__)
return _tzcnt_u64(v);
-#else
+# else
return _tzcnt_u32(v);
-#endif
-#else
+# endif
+# else
return __bsf(v);
-#endif
+# endif
}
-#endif
+# endif
__forceinline int clz(const int x)
{
-#if defined(__KERNEL_AVX2__)
+# if defined(__KERNEL_AVX2__)
return _lzcnt_u32(x);
-#else
- if(UNLIKELY(x == 0)) return 32;
+# else
+ if (UNLIKELY(x == 0))
+ return 32;
return 31 - __bsr(x);
-#endif
+# endif
}
-__forceinline int __bscf(int& v)
+__forceinline int __bscf(int &v)
{
int i = bitscan(v);
-#if defined(__KERNEL_AVX2__)
- v &= v-1;
-#else
- v = __btc(v,i);
-#endif
+# if defined(__KERNEL_AVX2__)
+ v &= v - 1;
+# else
+ v = __btc(v, i);
+# endif
return i;
}
-__forceinline unsigned int __bscf(unsigned int& v)
+__forceinline unsigned int __bscf(unsigned int &v)
{
unsigned int i = bitscan(v);
- v &= v-1;
+ v &= v - 1;
return i;
}
-#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
-__forceinline size_t __bscf(size_t& v)
+# if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && \
+ !(defined(__ILP32__) && defined(__x86_64__))
+__forceinline size_t __bscf(size_t &v)
{
size_t i = bitscan(v);
-#if defined(__KERNEL_AVX2__)
- v &= v-1;
-#else
- v = __btc(v,i);
-#endif
+# if defined(__KERNEL_AVX2__)
+ v &= v - 1;
+# else
+ v = __btc(v, i);
+# endif
return i;
}
-#endif
+# endif
-#endif /* _WIN32 */
+# endif /* _WIN32 */
/* Test __KERNEL_SSE41__ for MSVC which does not define __SSE4_1__, and test
* __SSE4_1__ to avoid OpenImageIO conflicts with our emulation macros on other
* platforms when compiling code outside the kernel. */
-#if !(defined(__KERNEL_SSE41__) || defined(__SSE4_1__) || defined(__SSE4_2__))
+# if !(defined(__KERNEL_SSE41__) || defined(__SSE4_1__) || defined(__SSE4_2__))
/* Emulation of SSE4 functions with SSE2 */
-#define _MM_FROUND_TO_NEAREST_INT 0x00
-#define _MM_FROUND_TO_NEG_INF 0x01
-#define _MM_FROUND_TO_POS_INF 0x02
-#define _MM_FROUND_TO_ZERO 0x03
-#define _MM_FROUND_CUR_DIRECTION 0x04
+# define _MM_FROUND_TO_NEAREST_INT 0x00
+# define _MM_FROUND_TO_NEG_INF 0x01
+# define _MM_FROUND_TO_POS_INF 0x02
+# define _MM_FROUND_TO_ZERO 0x03
+# define _MM_FROUND_CUR_DIRECTION 0x04
-#undef _mm_blendv_ps
-#define _mm_blendv_ps _mm_blendv_ps_emu
-__forceinline __m128 _mm_blendv_ps_emu( __m128 value, __m128 input, __m128 mask)
+# undef _mm_blendv_ps
+# define _mm_blendv_ps _mm_blendv_ps_emu
+__forceinline __m128 _mm_blendv_ps_emu(__m128 value, __m128 input, __m128 mask)
{
- __m128i isignmask = _mm_set1_epi32(0x80000000);
- __m128 signmask = _mm_castsi128_ps(isignmask);
- __m128i iandsign = _mm_castps_si128(_mm_and_ps(mask, signmask));
- __m128i icmpmask = _mm_cmpeq_epi32(iandsign, isignmask);
- __m128 cmpmask = _mm_castsi128_ps(icmpmask);
- return _mm_or_ps(_mm_and_ps(cmpmask, input), _mm_andnot_ps(cmpmask, value));
+ __m128i isignmask = _mm_set1_epi32(0x80000000);
+ __m128 signmask = _mm_castsi128_ps(isignmask);
+ __m128i iandsign = _mm_castps_si128(_mm_and_ps(mask, signmask));
+ __m128i icmpmask = _mm_cmpeq_epi32(iandsign, isignmask);
+ __m128 cmpmask = _mm_castsi128_ps(icmpmask);
+ return _mm_or_ps(_mm_and_ps(cmpmask, input), _mm_andnot_ps(cmpmask, value));
}
-#undef _mm_blend_ps
-#define _mm_blend_ps _mm_blend_ps_emu
-__forceinline __m128 _mm_blend_ps_emu( __m128 value, __m128 input, const int mask)
+# undef _mm_blend_ps
+# define _mm_blend_ps _mm_blend_ps_emu
+__forceinline __m128 _mm_blend_ps_emu(__m128 value, __m128 input, const int mask)
{
- assert(mask < 0x10); return _mm_blendv_ps(value, input, _mm_lookupmask_ps[mask]);
+ assert(mask < 0x10);
+ return _mm_blendv_ps(value, input, _mm_lookupmask_ps[mask]);
}
-#undef _mm_blendv_epi8
-#define _mm_blendv_epi8 _mm_blendv_epi8_emu
-__forceinline __m128i _mm_blendv_epi8_emu( __m128i value, __m128i input, __m128i mask)
+# undef _mm_blendv_epi8
+# define _mm_blendv_epi8 _mm_blendv_epi8_emu
+__forceinline __m128i _mm_blendv_epi8_emu(__m128i value, __m128i input, __m128i mask)
{
- return _mm_or_si128(_mm_and_si128(mask, input), _mm_andnot_si128(mask, value));
+ return _mm_or_si128(_mm_and_si128(mask, input), _mm_andnot_si128(mask, value));
}
-#undef _mm_min_epi32
-#define _mm_min_epi32 _mm_min_epi32_emu
-__forceinline __m128i _mm_min_epi32_emu( __m128i value, __m128i input)
+# undef _mm_min_epi32
+# define _mm_min_epi32 _mm_min_epi32_emu
+__forceinline __m128i _mm_min_epi32_emu(__m128i value, __m128i input)
{
- return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(value, input));
+ return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(value, input));
}
-#undef _mm_max_epi32
-#define _mm_max_epi32 _mm_max_epi32_emu
-__forceinline __m128i _mm_max_epi32_emu( __m128i value, __m128i input)
+# undef _mm_max_epi32
+# define _mm_max_epi32 _mm_max_epi32_emu
+__forceinline __m128i _mm_max_epi32_emu(__m128i value, __m128i input)
{
- return _mm_blendv_epi8(value, input, _mm_cmplt_epi32(value, input));
+ return _mm_blendv_epi8(value, input, _mm_cmplt_epi32(value, input));
}
-#undef _mm_extract_epi32
-#define _mm_extract_epi32 _mm_extract_epi32_emu
-__forceinline int _mm_extract_epi32_emu( __m128i input, const int index)
+# undef _mm_extract_epi32
+# define _mm_extract_epi32 _mm_extract_epi32_emu
+__forceinline int _mm_extract_epi32_emu(__m128i input, const int index)
{
- switch(index) {
- case 0: return _mm_cvtsi128_si32(input);
- case 1: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(1, 1, 1, 1)));
- case 2: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(2, 2, 2, 2)));
- case 3: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(3, 3, 3, 3)));
- default: assert(false); return 0;
+ switch (index) {
+ case 0:
+ return _mm_cvtsi128_si32(input);
+ case 1:
+ return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(1, 1, 1, 1)));
+ case 2:
+ return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(2, 2, 2, 2)));
+ case 3:
+ return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(3, 3, 3, 3)));
+ default:
+ assert(false);
+ return 0;
}
}
-#undef _mm_insert_epi32
-#define _mm_insert_epi32 _mm_insert_epi32_emu
-__forceinline __m128i _mm_insert_epi32_emu( __m128i value, int input, const int index)
+# undef _mm_insert_epi32
+# define _mm_insert_epi32 _mm_insert_epi32_emu
+__forceinline __m128i _mm_insert_epi32_emu(__m128i value, int input, const int index)
{
- assert(index >= 0 && index < 4); ((int*)&value)[index] = input; return value;
+ assert(index >= 0 && index < 4);
+ ((int *)&value)[index] = input;
+ return value;
}
-#undef _mm_insert_ps
-#define _mm_insert_ps _mm_insert_ps_emu
-__forceinline __m128 _mm_insert_ps_emu( __m128 value, __m128 input, const int index)
+# undef _mm_insert_ps
+# define _mm_insert_ps _mm_insert_ps_emu
+__forceinline __m128 _mm_insert_ps_emu(__m128 value, __m128 input, const int index)
{
- assert(index < 0x100);
- ((float*)&value)[(index >> 4)&0x3] = ((float*)&input)[index >> 6];
- return _mm_andnot_ps(_mm_lookupmask_ps[index&0xf], value);
+ assert(index < 0x100);
+ ((float *)&value)[(index >> 4) & 0x3] = ((float *)&input)[index >> 6];
+ return _mm_andnot_ps(_mm_lookupmask_ps[index & 0xf], value);
}
-#undef _mm_round_ps
-#define _mm_round_ps _mm_round_ps_emu
-__forceinline __m128 _mm_round_ps_emu( __m128 value, const int flags)
+# undef _mm_round_ps
+# define _mm_round_ps _mm_round_ps_emu
+__forceinline __m128 _mm_round_ps_emu(__m128 value, const int flags)
{
- switch(flags)
- {
- case _MM_FROUND_TO_NEAREST_INT: return _mm_cvtepi32_ps(_mm_cvtps_epi32(value));
- case _MM_FROUND_TO_NEG_INF : return _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_add_ps(value, _mm_set1_ps(-0.5f))));
- case _MM_FROUND_TO_POS_INF : return _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_add_ps(value, _mm_set1_ps( 0.5f))));
- case _MM_FROUND_TO_ZERO : return _mm_cvtepi32_ps(_mm_cvttps_epi32(value));
+ switch (flags) {
+ case _MM_FROUND_TO_NEAREST_INT:
+ return _mm_cvtepi32_ps(_mm_cvtps_epi32(value));
+ case _MM_FROUND_TO_NEG_INF:
+ return _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_add_ps(value, _mm_set1_ps(-0.5f))));
+ case _MM_FROUND_TO_POS_INF:
+ return _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_add_ps(value, _mm_set1_ps(0.5f))));
+ case _MM_FROUND_TO_ZERO:
+ return _mm_cvtepi32_ps(_mm_cvttps_epi32(value));
}
return value;
}
-#endif /* !(defined(__KERNEL_SSE41__) || defined(__SSE4_1__) || defined(__SSE4_2__)) */
+# endif /* !(defined(__KERNEL_SSE41__) || defined(__SSE4_1__) || defined(__SSE4_2__)) */
-#else /* __KERNEL_SSE2__ */
+# else /* __KERNEL_SSE2__ */
/* This section is for utility functions which operates on non-register data
* which might be used from a non-vectorized code.
@@ -460,38 +571,34 @@ __forceinline __m128 _mm_round_ps_emu( __m128 value, const int flags)
ccl_device_inline int bitscan(int value)
{
- assert(value != 0);
- int bit = 0;
- while((value & (1 << bit)) == 0) {
- ++bit;
- }
- return bit;
+ assert(value != 0);
+ int bit = 0;
+ while ((value & (1 << bit)) == 0) {
+ ++bit;
+ }
+ return bit;
}
ccl_device_inline int __bsr(int value)
{
- assert(value != 0);
- int bit = 0;
- while(value >>= 1) {
- ++bit;
- }
- return bit;
+ assert(value != 0);
+ int bit = 0;
+ while (value >>= 1) {
+ ++bit;
+ }
+ return bit;
}
-#endif /* __KERNEL_SSE2__ */
+# endif /* __KERNEL_SSE2__ */
/* quiet unused define warnings */
-#if defined(__KERNEL_SSE2__) || \
- defined(__KERNEL_SSE3__) || \
- defined(__KERNEL_SSSE3__) || \
- defined(__KERNEL_SSE41__) || \
- defined(__KERNEL_AVX__) || \
- defined(__KERNEL_AVX2__)
- /* do nothing */
-#endif
+# if defined(__KERNEL_SSE2__) || defined(__KERNEL_SSE3__) || defined(__KERNEL_SSSE3__) || \
+ defined(__KERNEL_SSE41__) || defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
+/* do nothing */
+# endif
CCL_NAMESPACE_END
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
-#endif /* __UTIL_SIMD_TYPES_H__ */
+#endif /* __UTIL_SIMD_TYPES_H__ */
diff --git a/intern/cycles/util/util_sky_model.cpp b/intern/cycles/util/util_sky_model.cpp
index 526bce4ff88..4a6a9f32607 100644
--- a/intern/cycles/util/util_sky_model.cpp
+++ b/intern/cycles/util/util_sky_model.cpp
@@ -111,23 +111,23 @@ CCL_NAMESPACE_BEGIN
// replicated to make this a stand-alone module.
#ifndef MATH_PI
-#define MATH_PI 3.141592653589793
+# define MATH_PI 3.141592653589793
#endif
#ifndef MATH_DEG_TO_RAD
-#define MATH_DEG_TO_RAD ( MATH_PI / 180.0 )
+# define MATH_DEG_TO_RAD (MATH_PI / 180.0)
#endif
#ifndef DEGREES
-#define DEGREES * MATH_DEG_TO_RAD
+# define DEGREES *MATH_DEG_TO_RAD
#endif
#ifndef TERRESTRIAL_SOLAR_RADIUS
-#define TERRESTRIAL_SOLAR_RADIUS ( ( 0.51 DEGREES ) / 2.0 )
+# define TERRESTRIAL_SOLAR_RADIUS ((0.51 DEGREES) / 2.0)
#endif
#ifndef ALLOC
-#define ALLOC(_struct) ((_struct *)malloc(sizeof(_struct)))
+# define ALLOC(_struct) ((_struct *)malloc(sizeof(_struct)))
#endif
// internal definitions
@@ -137,233 +137,213 @@ typedef const double *ArHosekSkyModel_Radiance_Dataset;
// internal functions
-static void ArHosekSkyModel_CookConfiguration(
- ArHosekSkyModel_Dataset dataset,
- ArHosekSkyModelConfiguration config,
- double turbidity,
- double albedo,
- double solar_elevation)
+static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
+ ArHosekSkyModelConfiguration config,
+ double turbidity,
+ double albedo,
+ double solar_elevation)
{
- const double * elev_matrix;
-
- int int_turbidity = (int)turbidity;
- double turbidity_rem = turbidity - (double)int_turbidity;
-
- solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
-
- // alb 0 low turb
-
- elev_matrix = dataset + ( 9 * 6 * (int_turbidity-1));
-
- for(unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] =
- (1.0-albedo) * (1.0 - turbidity_rem)
- * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
- pow(solar_elevation, 5.0) * elev_matrix[i+45]);
- }
-
- // alb 1 low turb
- elev_matrix = dataset + (9*6*10 + 9*6*(int_turbidity-1));
- for(unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] +=
- (albedo) * (1.0 - turbidity_rem)
- * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
- pow(solar_elevation, 5.0) * elev_matrix[i+45]);
- }
-
- if(int_turbidity == 10)
- return;
-
- // alb 0 high turb
- elev_matrix = dataset + (9*6*(int_turbidity));
- for(unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] +=
- (1.0-albedo) * (turbidity_rem)
- * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
- pow(solar_elevation, 5.0) * elev_matrix[i+45]);
- }
-
- // alb 1 high turb
- elev_matrix = dataset + (9*6*10 + 9*6*(int_turbidity));
- for(unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] +=
- (albedo) * (turbidity_rem)
- * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
- pow(solar_elevation, 5.0) * elev_matrix[i+45]);
- }
+ const double *elev_matrix;
+
+ int int_turbidity = (int)turbidity;
+ double turbidity_rem = turbidity - (double)int_turbidity;
+
+ solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
+
+ // alb 0 low turb
+
+ elev_matrix = dataset + (9 * 6 * (int_turbidity - 1));
+
+ for (unsigned int i = 0; i < 9; ++i) {
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ config[i] =
+ (1.0 - albedo) * (1.0 - turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
+ pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
+ }
+
+ // alb 1 low turb
+ elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity - 1));
+ for (unsigned int i = 0; i < 9; ++i) {
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ config[i] +=
+ (albedo) * (1.0 - turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
+ pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
+ }
+
+ if (int_turbidity == 10)
+ return;
+
+ // alb 0 high turb
+ elev_matrix = dataset + (9 * 6 * (int_turbidity));
+ for (unsigned int i = 0; i < 9; ++i) {
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ config[i] +=
+ (1.0 - albedo) * (turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
+ pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
+ }
+
+ // alb 1 high turb
+ elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity));
+ for (unsigned int i = 0; i < 9; ++i) {
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ config[i] +=
+ (albedo) * (turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
+ pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
+ }
}
-static double ArHosekSkyModel_CookRadianceConfiguration(
- ArHosekSkyModel_Radiance_Dataset dataset,
- double turbidity,
- double albedo,
- double solar_elevation)
+static double ArHosekSkyModel_CookRadianceConfiguration(ArHosekSkyModel_Radiance_Dataset dataset,
+ double turbidity,
+ double albedo,
+ double solar_elevation)
{
- const double* elev_matrix;
-
- int int_turbidity = (int)turbidity;
- double turbidity_rem = turbidity - (double)int_turbidity;
- double res;
- solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
-
- // alb 0 low turb
- elev_matrix = dataset + (6*(int_turbidity-1));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res = (1.0-albedo) * (1.0 - turbidity_rem) *
- ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
- 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
-
- // alb 1 low turb
- elev_matrix = dataset + (6*10 + 6*(int_turbidity-1));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res += (albedo) * (1.0 - turbidity_rem) *
- ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
- 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
- if(int_turbidity == 10)
- return res;
-
- // alb 0 high turb
- elev_matrix = dataset + (6*(int_turbidity));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res += (1.0-albedo) * (turbidity_rem) *
- ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
- 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
-
- // alb 1 high turb
- elev_matrix = dataset + (6*10 + 6*(int_turbidity));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res += (albedo) * (turbidity_rem) *
- ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
- 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
- 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
- return res;
+ const double *elev_matrix;
+
+ int int_turbidity = (int)turbidity;
+ double turbidity_rem = turbidity - (double)int_turbidity;
+ double res;
+ solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
+
+ // alb 0 low turb
+ elev_matrix = dataset + (6 * (int_turbidity - 1));
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ res = (1.0 - albedo) * (1.0 - turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
+ pow(solar_elevation, 5.0) * elev_matrix[5]);
+
+ // alb 1 low turb
+ elev_matrix = dataset + (6 * 10 + 6 * (int_turbidity - 1));
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ res += (albedo) * (1.0 - turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
+ pow(solar_elevation, 5.0) * elev_matrix[5]);
+ if (int_turbidity == 10)
+ return res;
+
+ // alb 0 high turb
+ elev_matrix = dataset + (6 * (int_turbidity));
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ res += (1.0 - albedo) * (turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
+ pow(solar_elevation, 5.0) * elev_matrix[5]);
+
+ // alb 1 high turb
+ elev_matrix = dataset + (6 * 10 + 6 * (int_turbidity));
+ //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
+ res += (albedo) * (turbidity_rem) *
+ (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
+ 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
+ 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
+ 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
+ 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
+ pow(solar_elevation, 5.0) * elev_matrix[5]);
+ return res;
}
-static double ArHosekSkyModel_GetRadianceInternal(
- ArHosekSkyModelConfiguration configuration,
- double theta,
- double gamma)
+static double ArHosekSkyModel_GetRadianceInternal(ArHosekSkyModelConfiguration configuration,
+ double theta,
+ double gamma)
{
- const double expM = exp(configuration[4] * gamma);
- const double rayM = cos(gamma)*cos(gamma);
- const double mieM = (1.0 + cos(gamma)*cos(gamma)) / pow((1.0 + configuration[8]*configuration[8] - 2.0*configuration[8]*cos(gamma)), 1.5);
- const double zenith = sqrt(cos(theta));
-
- return (1.0 + configuration[0] * exp(configuration[1] / (cos(theta) + 0.01))) *
- (configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith);
+ const double expM = exp(configuration[4] * gamma);
+ const double rayM = cos(gamma) * cos(gamma);
+ const double mieM =
+ (1.0 + cos(gamma) * cos(gamma)) /
+ pow((1.0 + configuration[8] * configuration[8] - 2.0 * configuration[8] * cos(gamma)), 1.5);
+ const double zenith = sqrt(cos(theta));
+
+ return (1.0 + configuration[0] * exp(configuration[1] / (cos(theta) + 0.01))) *
+ (configuration[2] + configuration[3] * expM + configuration[5] * rayM +
+ configuration[6] * mieM + configuration[7] * zenith);
}
-void arhosekskymodelstate_free(ArHosekSkyModelState * state)
+void arhosekskymodelstate_free(ArHosekSkyModelState *state)
{
- free(state);
+ free(state);
}
-double arhosekskymodel_radiance(ArHosekSkyModelState *state,
+double arhosekskymodel_radiance(ArHosekSkyModelState *state,
double theta,
double gamma,
double wavelength)
{
- int low_wl = (int)((wavelength - 320.0) / 40.0);
-
- if(low_wl < 0 || low_wl >= 11)
- return 0.0;
-
- double interp = fmod((wavelength - 320.0 ) / 40.0, 1.0);
-
- double val_low =
- ArHosekSkyModel_GetRadianceInternal(
- state->configs[low_wl],
- theta,
- gamma)
- * state->radiances[low_wl]
- * state->emission_correction_factor_sky[low_wl];
-
- if(interp < 1e-6)
- return val_low;
-
- double result = ( 1.0 - interp ) * val_low;
-
- if(low_wl+1 < 11) {
- result +=
- interp
- * ArHosekSkyModel_GetRadianceInternal(
- state->configs[low_wl+1],
- theta,
- gamma)
- * state->radiances[low_wl+1]
- * state->emission_correction_factor_sky[low_wl+1];
- }
-
- return result;
-}
+ int low_wl = (int)((wavelength - 320.0) / 40.0);
+
+ if (low_wl < 0 || low_wl >= 11)
+ return 0.0;
+
+ double interp = fmod((wavelength - 320.0) / 40.0, 1.0);
+
+ double val_low = ArHosekSkyModel_GetRadianceInternal(state->configs[low_wl], theta, gamma) *
+ state->radiances[low_wl] * state->emission_correction_factor_sky[low_wl];
+
+ if (interp < 1e-6)
+ return val_low;
+
+ double result = (1.0 - interp) * val_low;
+ if (low_wl + 1 < 11) {
+ result += interp *
+ ArHosekSkyModel_GetRadianceInternal(state->configs[low_wl + 1], theta, gamma) *
+ state->radiances[low_wl + 1] * state->emission_correction_factor_sky[low_wl + 1];
+ }
+
+ return result;
+}
// xyz and rgb versions
-ArHosekSkyModelState * arhosek_xyz_skymodelstate_alloc_init(
- const double turbidity,
- const double albedo,
- const double elevation)
+ArHosekSkyModelState *arhosek_xyz_skymodelstate_alloc_init(const double turbidity,
+ const double albedo,
+ const double elevation)
{
- ArHosekSkyModelState * state = ALLOC(ArHosekSkyModelState);
-
- state->solar_radius = TERRESTRIAL_SOLAR_RADIUS;
- state->turbidity = turbidity;
- state->albedo = albedo;
- state->elevation = elevation;
-
- for(unsigned int channel = 0; channel < 3; ++channel) {
- ArHosekSkyModel_CookConfiguration(
- datasetsXYZ[channel],
- state->configs[channel],
- turbidity,
- albedo,
- elevation);
-
- state->radiances[channel] =
- ArHosekSkyModel_CookRadianceConfiguration(
- datasetsXYZRad[channel],
- turbidity,
- albedo,
- elevation);
- }
-
- return state;
+ ArHosekSkyModelState *state = ALLOC(ArHosekSkyModelState);
+
+ state->solar_radius = TERRESTRIAL_SOLAR_RADIUS;
+ state->turbidity = turbidity;
+ state->albedo = albedo;
+ state->elevation = elevation;
+
+ for (unsigned int channel = 0; channel < 3; ++channel) {
+ ArHosekSkyModel_CookConfiguration(
+ datasetsXYZ[channel], state->configs[channel], turbidity, albedo, elevation);
+
+ state->radiances[channel] = ArHosekSkyModel_CookRadianceConfiguration(
+ datasetsXYZRad[channel], turbidity, albedo, elevation);
+ }
+
+ return state;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_sky_model.h b/intern/cycles/util/util_sky_model.h
index 2e593f58c39..84340614b2c 100644
--- a/intern/cycles/util/util_sky_model.h
+++ b/intern/cycles/util/util_sky_model.h
@@ -28,7 +28,6 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
/* ============================================================================
This file is part of a sample implementation of the analytical skylight and
@@ -92,7 +91,6 @@ an updated version of this code has been published!
============================================================================ */
-
/*
This code is taken from ART, a rendering research system written in a
@@ -303,11 +301,10 @@ HINT #1: if you want to model the sky of an earth-like planet that orbits
CCL_NAMESPACE_BEGIN
#ifndef _SKY_MODEL_H_
-#define _SKY_MODEL_H_
+# define _SKY_MODEL_H_
typedef double ArHosekSkyModelConfiguration[9];
-
// Spectral version of the model
/* ----------------------------------------------------------------------------
@@ -336,18 +333,16 @@ typedef double ArHosekSkyModelConfiguration[9];
---------------------------------------------------------------------------- */
-typedef struct ArHosekSkyModelState
-{
- ArHosekSkyModelConfiguration configs[11];
- double radiances[11];
- double turbidity;
- double solar_radius;
- double emission_correction_factor_sky[11];
- double emission_correction_factor_sun[11];
- double albedo;
- double elevation;
-}
-ArHosekSkyModelState;
+typedef struct ArHosekSkyModelState {
+ ArHosekSkyModelConfiguration configs[11];
+ double radiances[11];
+ double turbidity;
+ double solar_radius;
+ double emission_correction_factor_sky[11];
+ double emission_correction_factor_sun[11];
+ double albedo;
+ double elevation;
+} ArHosekSkyModelState;
/* ----------------------------------------------------------------------------
@@ -358,11 +353,9 @@ ArHosekSkyModelState;
---------------------------------------------------------------------------- */
-ArHosekSkyModelState *arhosekskymodelstate_alloc_init(
- const double solar_elevation,
- const double atmospheric_turbidity,
- const double ground_albedo);
-
+ArHosekSkyModelState *arhosekskymodelstate_alloc_init(const double solar_elevation,
+ const double atmospheric_turbidity,
+ const double ground_albedo);
/* ----------------------------------------------------------------------------
@@ -393,14 +386,14 @@ ArHosekSkyModelState *arhosekskymodelstate_alloc_init(
---------------------------------------------------------------------------- */
-ArHosekSkyModelState* arhosekskymodelstate_alienworld_alloc_init(
- const double solar_elevation,
- const double solar_intensity,
- const double solar_surface_temperature_kelvin,
- const double atmospheric_turbidity,
- const double ground_albedo);
+ArHosekSkyModelState *arhosekskymodelstate_alienworld_alloc_init(
+ const double solar_elevation,
+ const double solar_intensity,
+ const double solar_surface_temperature_kelvin,
+ const double atmospheric_turbidity,
+ const double ground_albedo);
-void arhosekskymodelstate_free(ArHosekSkyModelState *state);
+void arhosekskymodelstate_free(ArHosekSkyModelState *state);
double arhosekskymodel_radiance(ArHosekSkyModelState *state,
double theta,
@@ -409,20 +402,15 @@ double arhosekskymodel_radiance(ArHosekSkyModelState *state,
// CIE XYZ and RGB versions
+ArHosekSkyModelState *arhosek_xyz_skymodelstate_alloc_init(const double turbidity,
+ const double albedo,
+ const double elevation);
-ArHosekSkyModelState * arhosek_xyz_skymodelstate_alloc_init(
- const double turbidity,
- const double albedo,
- const double elevation);
+ArHosekSkyModelState *arhosek_rgb_skymodelstate_alloc_init(const double turbidity,
+ const double albedo,
+ const double elevation);
-
-ArHosekSkyModelState * arhosek_rgb_skymodelstate_alloc_init(
- const double turbidity,
- const double albedo,
- const double elevation);
-
-
-double arhosek_tristim_skymodel_radiance(ArHosekSkyModelState* state,
+double arhosek_tristim_skymodel_radiance(ArHosekSkyModelState *state,
double theta,
double gamma,
int channel);
@@ -431,12 +419,11 @@ double arhosek_tristim_skymodel_radiance(ArHosekSkyModelState* state,
// Please read the above description before using this - there are several
// caveats!
-double arhosekskymodel_solar_radiance(ArHosekSkyModelState* state,
+double arhosekskymodel_solar_radiance(ArHosekSkyModelState *state,
double theta,
double gamma,
double wavelength);
-
#endif // _SKY_MODEL_H_
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_sky_model_data.h b/intern/cycles/util/util_sky_model_data.h
index e6f3f761532..a2a3935eb84 100644
--- a/intern/cycles/util/util_sky_model_data.h
+++ b/intern/cycles/util/util_sky_model_data.h
@@ -28,7 +28,6 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
/* ============================================================================
This file is part of a sample implementation of the analytical skylight and
@@ -104,3760 +103,3745 @@ the model.
// Uses Sep 9 pattern / Aug 23 mean dataset
static const double datasetXYZ1[] = {
- // albedo 0, turbidity 1
- -1.117001e+000,
- -1.867262e-001,
- -1.113505e+001,
- 1.259865e+001,
- -3.937339e-002,
- 1.167571e+000,
- 7.100686e-003,
- 3.592678e+000,
- 6.083296e-001,
- -1.152006e+000,
- -1.926669e-001,
- 6.152049e+000,
- -4.770802e+000,
- -8.704701e-002,
- 7.483626e-001,
- 3.372718e-002,
- 4.464592e+000,
- 4.036546e-001,
- -1.072371e+000,
- -2.696632e-001,
- 2.816168e-001,
- 1.820571e+000,
- -3.742666e-001,
- 2.080607e+000,
- -7.675295e-002,
- -2.835366e+000,
- 1.129329e+000,
- -1.109935e+000,
- -1.532764e-001,
- 1.198787e+000,
- -9.015183e-001,
- 5.173015e-003,
- 5.749178e-001,
- 1.075633e-001,
- 4.387949e+000,
- 2.650413e-001,
- -1.052297e+000,
- -2.229452e-001,
- 1.952347e+000,
- 5.727205e-001,
- -4.885070e+000,
- 1.984016e+000,
- -1.106197e-001,
- -4.898361e-001,
- 8.907873e-001,
- -1.070108e+000,
- -1.600465e-001,
- 1.593886e+000,
- -4.479251e-005,
- -3.306541e+000,
- 9.390193e-001,
- 9.513168e-002,
- 2.343583e+000,
- 5.335404e-001,
- // albedo 0, turbidity 2
- -1.113253e+000,
- -1.699600e-001,
- -1.038822e+001,
- 1.137513e+001,
- -4.040911e-002,
- 1.037455e+000,
- 4.991792e-002,
- 4.801919e+000,
- 6.302710e-001,
- -1.135747e+000,
- -1.678594e-001,
- 4.970755e+000,
- -4.430230e+000,
- -6.657408e-002,
- 3.636161e-001,
- 1.558009e-001,
- 6.013370e+000,
- 3.959601e-001,
- -1.095892e+000,
- -2.732595e-001,
- 7.666496e-001,
- 1.350731e+000,
- -4.401401e-001,
- 2.470135e+000,
- -1.707929e-001,
- -3.260793e+000,
- 1.170337e+000,
- -1.073668e+000,
- -2.603929e-002,
- -1.944589e-001,
- 4.575207e-001,
- 6.878164e-001,
- -1.390770e-001,
- 3.690299e-001,
- 7.885781e+000,
- 1.877694e-001,
- -1.070091e+000,
- -2.798957e-001,
- 2.338478e+000,
- -2.647221e+000,
- -7.387808e+000,
- 2.329210e+000,
- -1.644639e-001,
- -2.003710e+000,
- 9.874527e-001,
- -1.067120e+000,
- -1.418866e-001,
- 1.254090e+000,
- 6.053048e+000,
- -2.918892e+000,
- 5.322812e-001,
- 1.613053e-001,
- 3.018161e+000,
- 5.274090e-001,
- // albedo 0, turbidity 3
- -1.129483e+000,
- -1.890619e-001,
- -9.065101e+000,
- 9.659923e+000,
- -3.607819e-002,
- 8.314359e-001,
- 8.181661e-002,
- 4.768868e+000,
- 6.339777e-001,
- -1.146420e+000,
- -1.883579e-001,
- 3.309173e+000,
- -3.127882e+000,
- -6.938176e-002,
- 3.987113e-001,
- 1.400581e-001,
- 6.283042e+000,
- 5.267076e-001,
- -1.128348e+000,
- -2.641305e-001,
- 1.223176e+000,
- 5.514952e-002,
- -3.490649e-001,
- 1.997784e+000,
- -4.123709e-002,
- -2.251251e+000,
- 9.483466e-001,
- -1.025820e+000,
- 1.404690e-002,
- -1.187406e+000,
- 2.729900e+000,
- 5.877588e-001,
- -2.761140e-001,
- 4.602633e-001,
- 8.305125e+000,
- 3.945001e-001,
- -1.083957e+000,
- -2.606679e-001,
- 2.207108e+000,
- -7.202803e+000,
- -5.968103e+000,
- 2.129455e+000,
- -7.789512e-002,
- -1.137688e+000,
- 8.871769e-001,
- -1.062465e+000,
- -1.512189e-001,
- 1.042881e+000,
- 1.427839e+001,
- -4.242214e+000,
- 4.038100e-001,
- 1.997780e-001,
- 2.814449e+000,
- 5.803196e-001,
- // albedo 0, turbidity 4
- -1.175099e+000,
- -2.410789e-001,
- -1.108587e+001,
- 1.133404e+001,
- -1.819300e-002,
- 6.772942e-001,
- 9.605043e-002,
- 4.231166e+000,
- 6.239972e-001,
- -1.224207e+000,
- -2.883527e-001,
- 3.002206e+000,
- -2.649612e+000,
- -4.795418e-002,
- 4.984398e-001,
- 3.251434e-002,
- 4.851611e+000,
- 6.551019e-001,
- -1.136955e+000,
- -2.423048e-001,
- 1.058823e+000,
- -2.489236e-001,
- -2.462179e-001,
- 1.933140e+000,
- 9.106828e-002,
- -1.905869e-001,
- 8.171065e-001,
- -1.014535e+000,
- -8.262500e-003,
- -1.448017e+000,
- 2.295788e+000,
- 3.510334e-001,
- -1.477418e+000,
- 5.432449e-001,
- 5.762796e+000,
- 4.908751e-001,
- -1.070666e+000,
- -2.379780e-001,
- 1.844589e+000,
- -5.442448e+000,
- -4.012768e+000,
- 2.945275e+000,
- 9.854725e-003,
- 8.455959e-002,
- 8.145030e-001,
- -1.071525e+000,
- -1.777132e-001,
- 8.076590e-001,
- 9.925865e+000,
- -3.324623e+000,
- -6.367437e-001,
- 2.844581e-001,
- 2.248384e+000,
- 6.544022e-001,
- // albedo 0, turbidity 5
- -1.218818e+000,
- -2.952382e-001,
- -1.345975e+001,
- 1.347153e+001,
- -6.814585e-003,
- 5.079068e-001,
- 1.197230e-001,
- 3.776949e+000,
- 5.836961e-001,
- -1.409868e+000,
- -5.114330e-001,
- 2.776539e+000,
- -2.039001e+000,
- -2.673769e-002,
- 4.145288e-001,
- 7.829342e-004,
- 2.275883e+000,
- 6.629691e-001,
- -1.069151e+000,
- -9.434247e-002,
- 7.293972e-001,
- -1.222473e+000,
- -1.533461e-001,
- 2.160357e+000,
- 4.626837e-002,
- 3.852415e+000,
- 8.593570e-001,
- -1.021306e+000,
- -1.149551e-001,
- -1.108414e+000,
- 4.178343e+000,
- 4.013665e-001,
- -2.222814e+000,
- 6.929462e-001,
- 1.392652e+000,
- 4.401662e-001,
- -1.074251e+000,
- -2.224002e-001,
- 1.372356e+000,
- -8.858704e+000,
- -3.922660e+000,
- 3.020018e+000,
- -1.458724e-002,
- 1.511186e+000,
- 8.288064e-001,
- -1.062048e+000,
- -1.526582e-001,
- 4.921067e-001,
- 1.485522e+001,
- -3.229936e+000,
- -8.426604e-001,
- 3.916243e-001,
- 2.678994e+000,
- 6.689264e-001,
- // albedo 0, turbidity 6
- -1.257023e+000,
- -3.364700e-001,
- -1.527795e+001,
- 1.504223e+001,
- 2.717715e-003,
- 3.029910e-001,
- 1.636851e-001,
- 3.561663e+000,
- 5.283161e-001,
- -1.635124e+000,
- -7.329993e-001,
- 3.523939e+000,
- -2.566337e+000,
- -1.902543e-002,
- 5.505483e-001,
- -6.242176e-002,
- 1.065992e+000,
- 6.654236e-001,
- -9.295823e-001,
- 4.845834e-002,
- -2.992990e-001,
- -2.001327e-001,
- -8.019339e-002,
- 1.807806e+000,
- 9.020277e-002,
- 5.095372e+000,
- 8.639936e-001,
- -1.093740e+000,
- -2.148608e-001,
- -5.216240e-001,
- 2.119777e+000,
- 9.506454e-002,
- -1.831439e+000,
- 6.961204e-001,
- 1.102084e-001,
- 4.384319e-001,
- -1.044181e+000,
- -1.849257e-001,
- 9.071246e-001,
- -4.648901e+000,
- -2.279385e+000,
- 2.356502e+000,
- -4.169147e-002,
- 1.932557e+000,
- 8.296550e-001,
- -1.061451e+000,
- -1.458745e-001,
- 2.952267e-001,
- 8.967214e+000,
- -3.726228e+000,
- -5.022316e-001,
- 5.684877e-001,
- 3.102347e+000,
- 6.658443e-001,
- // albedo 0, turbidity 7
- -1.332391e+000,
- -4.127769e-001,
- -9.328643e+000,
- 9.046194e+000,
- 3.457775e-003,
- 3.377425e-001,
- 1.530909e-001,
- 3.301209e+000,
- 4.997917e-001,
- -1.932002e+000,
- -9.947777e-001,
- -2.042329e+000,
- 3.586940e+000,
- -5.642182e-002,
- 8.130478e-001,
- -8.195988e-002,
- 1.118294e-001,
- 5.617231e-001,
- -8.707374e-001,
- 1.286999e-001,
- 1.820054e+000,
- -4.674706e+000,
- 3.317471e-003,
- 5.919018e-001,
- 1.975278e-001,
- 6.686519e+000,
- 9.631727e-001,
- -1.070378e+000,
- -3.030579e-001,
- -9.041938e-001,
- 6.200201e+000,
- 1.232207e-001,
- -3.650628e-001,
- 5.029403e-001,
- -2.903162e+000,
- 3.811408e-001,
- -1.063035e+000,
- -1.637545e-001,
- 5.853072e-001,
- -7.889906e+000,
- -1.200641e+000,
- 1.035018e+000,
- 1.192093e-001,
- 3.267054e+000,
- 8.416151e-001,
- -1.053655e+000,
- -1.562286e-001,
- 2.423683e-001,
- 1.128575e+001,
- -4.363262e+000,
- -7.314160e-002,
- 5.642088e-001,
- 2.514023e+000,
- 6.670457e-001,
- // albedo 0, turbidity 8
- -1.366112e+000,
- -4.718287e-001,
- -7.876222e+000,
- 7.746900e+000,
- -9.182309e-003,
- 4.716076e-001,
- 8.320252e-002,
- 3.165603e+000,
- 5.392334e-001,
- -2.468204e+000,
- -1.336340e+000,
- -5.386723e+000,
- 7.072672e+000,
- -8.329266e-002,
- 8.636876e-001,
- -1.978177e-002,
- -1.326218e-001,
- 2.979222e-001,
- -9.653522e-001,
- -2.373416e-002,
- 1.810250e+000,
- -6.467262e+000,
- 1.410706e-001,
- -4.753717e-001,
- 3.003095e-001,
- 6.551163e+000,
- 1.151083e+000,
- -8.943186e-001,
- -2.487152e-001,
- -2.308960e-001,
- 8.512648e+000,
- 1.298402e-001,
- 1.034705e+000,
- 2.303509e-001,
- -3.924095e+000,
- 2.982717e-001,
- -1.146999e+000,
- -2.318784e-001,
- 8.992419e-002,
- -9.933614e+000,
- -8.860920e-001,
- -3.071656e-002,
- 2.852012e-001,
- 3.046199e+000,
- 8.599001e-001,
- -1.032399e+000,
- -1.645145e-001,
- 2.683599e-001,
- 1.327701e+001,
- -4.407670e+000,
- 7.709869e-002,
- 4.951727e-001,
- 1.957277e+000,
- 6.630943e-001,
- // albedo 0, turbidity 9
- -1.469070e+000,
- -6.135092e-001,
- -6.506263e+000,
- 6.661315e+000,
- -3.835383e-002,
- 7.150413e-001,
- 7.784318e-003,
- 2.820577e+000,
- 6.756784e-001,
- -2.501583e+000,
- -1.247404e+000,
- -1.523462e+001,
- 1.633191e+001,
- -1.204803e-002,
- 5.896471e-001,
- -2.002023e-002,
- 1.144647e+000,
- 6.177874e-002,
- -2.438672e+000,
- -1.127291e+000,
- 5.731172e+000,
- -1.021350e+001,
- 6.165610e-002,
- -7.752641e-001,
- 4.708254e-001,
- 4.176847e+000,
- 1.200881e+000,
- -1.513427e-001,
- 9.792731e-002,
- -1.612349e+000,
- 9.814289e+000,
- 5.188921e-002,
- 1.716403e+000,
- -7.039255e-002,
- -2.815115e+000,
- 3.291874e-001,
- -1.318511e+000,
- -3.650554e-001,
- 4.221268e-001,
- -9.294529e+000,
- -4.397520e-002,
- -8.100625e-001,
- 3.742719e-001,
- 1.834166e+000,
- 8.223450e-001,
- -1.016009e+000,
- -1.820264e-001,
- 1.278426e-001,
- 1.182696e+001,
- -4.801528e+000,
- 4.947899e-001,
- 4.660378e-001,
- 1.601254e+000,
- 6.702359e-001,
- // albedo 0, turbidity 10
- -1.841310e+000,
- -9.781779e-001,
- -4.610903e+000,
- 4.824662e+000,
- -5.100806e-002,
- 6.463776e-001,
- -6.377724e-006,
- 2.216875e+000,
- 8.618530e-001,
- -2.376373e+000,
- -1.108657e+000,
- -1.489799e+001,
- 1.546458e+001,
- 4.091025e-002,
- 9.761780e-002,
- -1.048958e-002,
- 2.165834e+000,
- -1.609171e-001,
- -4.710318e+000,
- -2.261963e+000,
- 6.947327e+000,
- -1.034828e+001,
- -1.325542e-001,
- 7.508674e-001,
- 2.247553e-001,
- 2.873142e+000,
- 1.297100e+000,
- 2.163750e-001,
- -1.944345e-001,
- -2.437860e+000,
- 1.011314e+001,
- 4.450500e-001,
- 3.111492e-001,
- 2.751323e-001,
- -1.627906e+000,
- 2.531213e-001,
- -1.258794e+000,
- -3.524641e-001,
- 8.425444e-001,
- -1.085313e+001,
- -1.154381e+000,
- -4.638014e-001,
- -2.781115e-003,
- 4.344498e-001,
- 8.507091e-001,
- -1.018938e+000,
- -1.804153e-001,
- -6.354054e-002,
- 1.573150e+001,
- -4.386999e+000,
- 6.211115e-001,
- 5.294648e-001,
- 1.580749e+000,
- 6.586655e-001,
- // albedo 1, turbidity 1
- -1.116416e+000,
- -1.917524e-001,
- -1.068233e+001,
- 1.222221e+001,
- -3.668978e-002,
- 1.054022e+000,
- 1.592132e-002,
- 3.180583e+000,
- 5.627370e-001,
- -1.132341e+000,
- -1.671286e-001,
- 5.976499e+000,
- -4.227366e+000,
- -9.542489e-002,
- 8.664938e-001,
- 8.351793e-003,
- 4.876068e+000,
- 4.492779e-001,
- -1.087635e+000,
- -3.173679e-001,
- 4.314407e-001,
- 1.100555e+000,
- -4.410057e-001,
- 1.677253e+000,
- -3.005925e-002,
- -4.201249e+000,
- 1.070902e+000,
- -1.083031e+000,
- -8.847705e-002,
- 1.291773e+000,
- 4.546776e-001,
- 3.091894e-001,
- 7.261760e-001,
- 4.203659e-002,
- 5.990615e+000,
- 3.704756e-001,
- -1.057899e+000,
- -2.246706e-001,
- 2.329563e+000,
- -1.219656e+000,
- -5.335260e+000,
- 8.545378e-001,
- -3.906209e-002,
- -9.025499e-001,
- 7.797348e-001,
- -1.073305e+000,
- -1.522553e-001,
- 1.767063e+000,
- 1.904280e+000,
- -3.101673e+000,
- 3.995856e-001,
- 2.905192e-002,
- 2.563977e+000,
- 5.753067e-001,
- // albedo 1, turbidity 2
- -1.113674e+000,
- -1.759694e-001,
- -9.754125e+000,
- 1.087391e+001,
- -3.841093e-002,
- 9.524272e-001,
- 5.680219e-002,
- 4.227034e+000,
- 6.029571e-001,
- -1.126496e+000,
- -1.680281e-001,
- 5.332352e+000,
- -4.575579e+000,
- -6.761755e-002,
- 3.295335e-001,
- 1.194896e-001,
- 5.570901e+000,
- 4.536185e-001,
- -1.103074e+000,
- -2.681801e-001,
- 6.571479e-002,
- 2.396522e+000,
- -4.551280e-001,
- 2.466331e+000,
- -1.232022e-001,
- -3.023201e+000,
- 1.086379e+000,
- -1.053299e+000,
- -2.697173e-002,
- 8.379121e-001,
- -9.681458e-001,
- 5.890692e-001,
- -4.872027e-001,
- 2.936929e-001,
- 7.510139e+000,
- 3.079122e-001,
- -1.079553e+000,
- -2.710448e-001,
- 2.462379e+000,
- -3.713554e-001,
- -8.534512e+000,
- 1.828242e+000,
- -1.686398e-001,
- -1.961340e+000,
- 8.941077e-001,
- -1.069741e+000,
- -1.396394e-001,
- 1.657868e+000,
- 3.236313e+000,
- -2.706344e+000,
- -2.948122e-001,
- 1.314816e-001,
- 2.868457e+000,
- 5.413403e-001,
- // albedo 1, turbidity 3
- -1.131649e+000,
- -1.954455e-001,
- -7.751595e+000,
- 8.685861e+000,
- -4.910871e-002,
- 8.992952e-001,
- 4.710143e-002,
- 4.254818e+000,
- 6.821116e-001,
- -1.156689e+000,
- -1.884324e-001,
- 3.163519e+000,
- -3.091522e+000,
- -6.613927e-002,
- -2.575883e-002,
- 1.640065e-001,
- 6.073643e+000,
- 4.453468e-001,
- -1.079224e+000,
- -2.621389e-001,
- 9.446437e-001,
- 1.448479e+000,
- -3.969384e-001,
- 2.626638e+000,
- -8.101186e-002,
- -3.016355e+000,
- 1.076295e+000,
- -1.080832e+000,
- 1.033057e-002,
- -3.500156e-001,
- -3.281419e-002,
- 5.655512e-001,
- -1.156742e+000,
- 4.534710e-001,
- 8.774122e+000,
- 2.772869e-001,
- -1.051202e+000,
- -2.679975e-001,
- 2.719109e+000,
- -2.190316e+000,
- -6.878798e+000,
- 2.250481e+000,
- -2.030252e-001,
- -2.026527e+000,
- 9.701096e-001,
- -1.089849e+000,
- -1.598589e-001,
- 1.564748e+000,
- 6.869187e+000,
- -3.053670e+000,
- -6.110435e-001,
- 1.644472e-001,
- 2.370452e+000,
- 5.511770e-001,
- // albedo 1, turbidity 4
- -1.171419e+000,
- -2.429746e-001,
- -8.991334e+000,
- 9.571216e+000,
- -2.772861e-002,
- 6.688262e-001,
- 7.683478e-002,
- 3.785611e+000,
- 6.347635e-001,
- -1.228554e+000,
- -2.917562e-001,
- 2.753986e+000,
- -2.491780e+000,
- -4.663434e-002,
- 3.118303e-001,
- 7.546506e-002,
- 4.463096e+000,
- 5.955071e-001,
- -1.093124e+000,
- -2.447767e-001,
- 9.097406e-001,
- 5.448296e-001,
- -2.957824e-001,
- 2.024167e+000,
- -5.152333e-004,
- -1.069081e+000,
- 9.369565e-001,
- -1.056994e+000,
- 1.569507e-002,
- -8.217491e-001,
- 1.870818e+000,
- 7.061930e-001,
- -1.483928e+000,
- 5.978206e-001,
- 6.864902e+000,
- 3.673332e-001,
- -1.054871e+000,
- -2.758129e-001,
- 2.712807e+000,
- -5.950110e+000,
- -6.554039e+000,
- 2.447523e+000,
- -1.895171e-001,
- -1.454292e+000,
- 9.131738e-001,
- -1.100218e+000,
- -1.746241e-001,
- 1.438505e+000,
- 1.115481e+001,
- -3.266076e+000,
- -8.837357e-001,
- 1.970100e-001,
- 1.991595e+000,
- 5.907821e-001,
- // albedo 1, turbidity 5
- -1.207267e+000,
- -2.913610e-001,
- -1.103767e+001,
- 1.140724e+001,
- -1.416800e-002,
- 5.564047e-001,
- 8.476262e-002,
- 3.371255e+000,
- 6.221335e-001,
- -1.429698e+000,
- -5.374218e-001,
- 2.837524e+000,
- -2.221936e+000,
- -2.422337e-002,
- 9.313758e-002,
- 7.190250e-002,
- 1.869022e+000,
- 5.609035e-001,
- -1.002274e+000,
- -6.972810e-002,
- 4.031308e-001,
- -3.932997e-001,
- -1.521923e-001,
- 2.390646e+000,
- -6.893990e-002,
- 2.999661e+000,
- 1.017843e+000,
- -1.081168e+000,
- -1.178666e-001,
- -4.968080e-001,
- 3.919299e+000,
- 6.046866e-001,
- -2.440615e+000,
- 7.891538e-001,
- 2.140835e+000,
- 2.740470e-001,
- -1.050727e+000,
- -2.307688e-001,
- 2.276396e+000,
- -9.454407e+000,
- -5.505176e+000,
- 2.992620e+000,
- -2.450942e-001,
- 6.078372e-001,
- 9.606765e-001,
- -1.103752e+000,
- -1.810202e-001,
- 1.375044e+000,
- 1.589095e+001,
- -3.438954e+000,
- -1.265669e+000,
- 2.475172e-001,
- 1.680768e+000,
- 5.978056e-001,
- // albedo 1, turbidity 6
- -1.244324e+000,
- -3.378542e-001,
- -1.111001e+001,
- 1.137784e+001,
- -7.896794e-003,
- 4.808023e-001,
- 9.249904e-002,
- 3.025816e+000,
- 5.880239e-001,
- -1.593165e+000,
- -7.027621e-001,
- 2.220896e+000,
- -1.437709e+000,
- -1.534738e-002,
- 6.286958e-002,
- 6.644555e-002,
- 1.091727e+000,
- 5.470080e-001,
- -9.136506e-001,
- 1.344874e-002,
- 7.772636e-001,
- -1.209396e+000,
- -1.408978e-001,
- 2.433718e+000,
- -1.041938e-001,
- 3.791244e+000,
- 1.037916e+000,
- -1.134968e+000,
- -1.803315e-001,
- -9.267335e-001,
- 4.576670e+000,
- 6.851928e-001,
- -2.805000e+000,
- 8.687208e-001,
- 1.161483e+000,
- 2.571688e-001,
- -1.017037e+000,
- -2.053943e-001,
- 2.361640e+000,
- -9.887818e+000,
- -5.122889e+000,
- 3.287088e+000,
- -2.594102e-001,
- 8.578927e-001,
- 9.592340e-001,
- -1.118723e+000,
- -1.934942e-001,
- 1.226023e+000,
- 1.674140e+001,
- -3.277335e+000,
- -1.629809e+000,
- 2.765232e-001,
- 1.637713e+000,
- 6.113963e-001,
- // albedo 1, turbidity 7
- -1.314779e+000,
- -4.119915e-001,
- -1.241150e+001,
- 1.241578e+001,
- 2.344284e-003,
- 2.980837e-001,
- 1.414613e-001,
- 2.781731e+000,
- 4.998556e-001,
- -1.926199e+000,
- -1.020038e+000,
- 2.569200e+000,
- -1.081159e+000,
- -2.266833e-002,
- 3.588668e-001,
- 8.750078e-003,
- -2.452171e-001,
- 4.796758e-001,
- -7.780002e-001,
- 1.850647e-001,
- 4.445456e-002,
- -2.409297e+000,
- -7.816346e-002,
- 1.546790e+000,
- -2.807227e-002,
- 5.998176e+000,
- 1.132396e+000,
- -1.179326e+000,
- -3.578330e-001,
- -2.392933e-001,
- 6.467883e+000,
- 5.904596e-001,
- -1.869975e+000,
- 8.045839e-001,
- -2.498121e+000,
- 1.610633e-001,
- -1.009956e+000,
- -1.311896e-001,
- 1.726577e+000,
- -1.219356e+001,
- -3.466239e+000,
- 2.343602e+000,
- -2.252205e-001,
- 2.573681e+000,
- 1.027109e+000,
- -1.112460e+000,
- -2.063093e-001,
- 1.233051e+000,
- 2.058946e+001,
- -4.578074e+000,
- -1.145643e+000,
- 3.160192e-001,
- 1.420159e+000,
- 5.860212e-001,
- // albedo 1, turbidity 8
- -1.371689e+000,
- -4.914196e-001,
- -1.076610e+001,
- 1.107405e+001,
- -1.485077e-002,
- 5.936218e-001,
- 3.685482e-002,
- 2.599968e+000,
- 6.002204e-001,
- -2.436997e+000,
- -1.377939e+000,
- 2.130141e-002,
- 1.079593e+000,
- -1.796232e-002,
- -3.933248e-002,
- 1.610711e-001,
- -6.901181e-001,
- 1.206416e-001,
- -8.743368e-001,
- 7.331370e-002,
- 8.734259e-001,
- -3.743126e+000,
- -3.151167e-002,
- 1.297596e+000,
- -7.634926e-002,
- 6.532873e+000,
- 1.435737e+000,
- -9.810197e-001,
- -3.521634e-001,
- -2.855205e-001,
- 7.134674e+000,
- 6.839748e-001,
- -1.394841e+000,
- 6.952036e-001,
- -4.633104e+000,
- -2.173401e-002,
- -1.122958e+000,
- -1.691536e-001,
- 1.382360e+000,
- -1.102913e+001,
- -2.608171e+000,
- 1.865111e+000,
- -1.345154e-001,
- 3.112342e+000,
- 1.094134e+000,
- -1.075586e+000,
- -2.077415e-001,
- 1.171477e+000,
- 1.793270e+001,
- -4.656858e+000,
- -1.036839e+000,
- 3.338295e-001,
- 1.042793e+000,
- 5.739374e-001,
- // albedo 1, turbidity 9
- -1.465871e+000,
- -6.364486e-001,
- -8.833718e+000,
- 9.343650e+000,
- -3.223600e-002,
- 7.552848e-001,
- -3.121341e-006,
- 2.249164e+000,
- 8.094662e-001,
- -2.448924e+000,
- -1.270878e+000,
- -4.823703e+000,
- 5.853058e+000,
- -2.149127e-002,
- 3.581132e-002,
- -1.230276e-003,
- 4.892553e-001,
- -1.597657e-001,
- -2.419809e+000,
- -1.071337e+000,
- 1.575648e+000,
- -4.983580e+000,
- 9.545185e-003,
- 5.032615e-001,
- 4.186266e-001,
- 4.634147e+000,
- 1.433517e+000,
- -1.383278e-001,
- -2.797095e-002,
- -1.943067e-001,
- 6.679623e+000,
- 4.118280e-001,
- -2.744289e-001,
- -2.118722e-002,
- -4.337025e+000,
- 1.505072e-001,
- -1.341872e+000,
- -2.518572e-001,
- 1.027009e+000,
- -6.527103e+000,
- -1.081271e+000,
- 1.015465e+000,
- 2.845789e-001,
- 2.470371e+000,
- 9.278120e-001,
- -1.040640e+000,
- -2.367454e-001,
- 1.100744e+000,
- 8.827253e+000,
- -4.560794e+000,
- -7.287017e-001,
- 2.842503e-001,
- 6.336593e-001,
- 6.327335e-001,
- // albedo 1, turbidity 10
- -1.877993e+000,
- -1.025135e+000,
- -4.311037e+000,
- 4.715016e+000,
- -4.711631e-002,
- 6.335844e-001,
- -7.665398e-006,
- 1.788017e+000,
- 9.001409e-001,
- -2.281540e+000,
- -1.137668e+000,
- -1.036869e+001,
- 1.136254e+001,
- 1.961739e-002,
- -9.836174e-002,
- -6.734567e-003,
- 1.320918e+000,
- -2.400807e-001,
- -4.904054e+000,
- -2.315781e+000,
- 5.735999e+000,
- -8.626257e+000,
- -1.255643e-001,
- 1.545446e+000,
- 1.396860e-001,
- 2.972897e+000,
- 1.429934e+000,
- 4.077067e-001,
- -1.833688e-001,
- -2.450939e+000,
- 9.119433e+000,
- 4.505361e-001,
- -1.340828e+000,
- 3.973690e-001,
- -1.785370e+000,
- 9.628711e-002,
- -1.296052e+000,
- -3.250526e-001,
- 1.813294e+000,
- -1.031485e+001,
- -1.388690e+000,
- 1.239733e+000,
- -8.989196e-002,
- -3.389637e-001,
- 9.639560e-001,
- -1.062181e+000,
- -2.423444e-001,
- 7.577592e-001,
- 1.566938e+001,
- -4.462264e+000,
- -5.742810e-001,
- 3.262259e-001,
- 9.461672e-001,
- 6.232887e-001,
+ // albedo 0, turbidity 1
+ -1.117001e+000,
+ -1.867262e-001,
+ -1.113505e+001,
+ 1.259865e+001,
+ -3.937339e-002,
+ 1.167571e+000,
+ 7.100686e-003,
+ 3.592678e+000,
+ 6.083296e-001,
+ -1.152006e+000,
+ -1.926669e-001,
+ 6.152049e+000,
+ -4.770802e+000,
+ -8.704701e-002,
+ 7.483626e-001,
+ 3.372718e-002,
+ 4.464592e+000,
+ 4.036546e-001,
+ -1.072371e+000,
+ -2.696632e-001,
+ 2.816168e-001,
+ 1.820571e+000,
+ -3.742666e-001,
+ 2.080607e+000,
+ -7.675295e-002,
+ -2.835366e+000,
+ 1.129329e+000,
+ -1.109935e+000,
+ -1.532764e-001,
+ 1.198787e+000,
+ -9.015183e-001,
+ 5.173015e-003,
+ 5.749178e-001,
+ 1.075633e-001,
+ 4.387949e+000,
+ 2.650413e-001,
+ -1.052297e+000,
+ -2.229452e-001,
+ 1.952347e+000,
+ 5.727205e-001,
+ -4.885070e+000,
+ 1.984016e+000,
+ -1.106197e-001,
+ -4.898361e-001,
+ 8.907873e-001,
+ -1.070108e+000,
+ -1.600465e-001,
+ 1.593886e+000,
+ -4.479251e-005,
+ -3.306541e+000,
+ 9.390193e-001,
+ 9.513168e-002,
+ 2.343583e+000,
+ 5.335404e-001,
+ // albedo 0, turbidity 2
+ -1.113253e+000,
+ -1.699600e-001,
+ -1.038822e+001,
+ 1.137513e+001,
+ -4.040911e-002,
+ 1.037455e+000,
+ 4.991792e-002,
+ 4.801919e+000,
+ 6.302710e-001,
+ -1.135747e+000,
+ -1.678594e-001,
+ 4.970755e+000,
+ -4.430230e+000,
+ -6.657408e-002,
+ 3.636161e-001,
+ 1.558009e-001,
+ 6.013370e+000,
+ 3.959601e-001,
+ -1.095892e+000,
+ -2.732595e-001,
+ 7.666496e-001,
+ 1.350731e+000,
+ -4.401401e-001,
+ 2.470135e+000,
+ -1.707929e-001,
+ -3.260793e+000,
+ 1.170337e+000,
+ -1.073668e+000,
+ -2.603929e-002,
+ -1.944589e-001,
+ 4.575207e-001,
+ 6.878164e-001,
+ -1.390770e-001,
+ 3.690299e-001,
+ 7.885781e+000,
+ 1.877694e-001,
+ -1.070091e+000,
+ -2.798957e-001,
+ 2.338478e+000,
+ -2.647221e+000,
+ -7.387808e+000,
+ 2.329210e+000,
+ -1.644639e-001,
+ -2.003710e+000,
+ 9.874527e-001,
+ -1.067120e+000,
+ -1.418866e-001,
+ 1.254090e+000,
+ 6.053048e+000,
+ -2.918892e+000,
+ 5.322812e-001,
+ 1.613053e-001,
+ 3.018161e+000,
+ 5.274090e-001,
+ // albedo 0, turbidity 3
+ -1.129483e+000,
+ -1.890619e-001,
+ -9.065101e+000,
+ 9.659923e+000,
+ -3.607819e-002,
+ 8.314359e-001,
+ 8.181661e-002,
+ 4.768868e+000,
+ 6.339777e-001,
+ -1.146420e+000,
+ -1.883579e-001,
+ 3.309173e+000,
+ -3.127882e+000,
+ -6.938176e-002,
+ 3.987113e-001,
+ 1.400581e-001,
+ 6.283042e+000,
+ 5.267076e-001,
+ -1.128348e+000,
+ -2.641305e-001,
+ 1.223176e+000,
+ 5.514952e-002,
+ -3.490649e-001,
+ 1.997784e+000,
+ -4.123709e-002,
+ -2.251251e+000,
+ 9.483466e-001,
+ -1.025820e+000,
+ 1.404690e-002,
+ -1.187406e+000,
+ 2.729900e+000,
+ 5.877588e-001,
+ -2.761140e-001,
+ 4.602633e-001,
+ 8.305125e+000,
+ 3.945001e-001,
+ -1.083957e+000,
+ -2.606679e-001,
+ 2.207108e+000,
+ -7.202803e+000,
+ -5.968103e+000,
+ 2.129455e+000,
+ -7.789512e-002,
+ -1.137688e+000,
+ 8.871769e-001,
+ -1.062465e+000,
+ -1.512189e-001,
+ 1.042881e+000,
+ 1.427839e+001,
+ -4.242214e+000,
+ 4.038100e-001,
+ 1.997780e-001,
+ 2.814449e+000,
+ 5.803196e-001,
+ // albedo 0, turbidity 4
+ -1.175099e+000,
+ -2.410789e-001,
+ -1.108587e+001,
+ 1.133404e+001,
+ -1.819300e-002,
+ 6.772942e-001,
+ 9.605043e-002,
+ 4.231166e+000,
+ 6.239972e-001,
+ -1.224207e+000,
+ -2.883527e-001,
+ 3.002206e+000,
+ -2.649612e+000,
+ -4.795418e-002,
+ 4.984398e-001,
+ 3.251434e-002,
+ 4.851611e+000,
+ 6.551019e-001,
+ -1.136955e+000,
+ -2.423048e-001,
+ 1.058823e+000,
+ -2.489236e-001,
+ -2.462179e-001,
+ 1.933140e+000,
+ 9.106828e-002,
+ -1.905869e-001,
+ 8.171065e-001,
+ -1.014535e+000,
+ -8.262500e-003,
+ -1.448017e+000,
+ 2.295788e+000,
+ 3.510334e-001,
+ -1.477418e+000,
+ 5.432449e-001,
+ 5.762796e+000,
+ 4.908751e-001,
+ -1.070666e+000,
+ -2.379780e-001,
+ 1.844589e+000,
+ -5.442448e+000,
+ -4.012768e+000,
+ 2.945275e+000,
+ 9.854725e-003,
+ 8.455959e-002,
+ 8.145030e-001,
+ -1.071525e+000,
+ -1.777132e-001,
+ 8.076590e-001,
+ 9.925865e+000,
+ -3.324623e+000,
+ -6.367437e-001,
+ 2.844581e-001,
+ 2.248384e+000,
+ 6.544022e-001,
+ // albedo 0, turbidity 5
+ -1.218818e+000,
+ -2.952382e-001,
+ -1.345975e+001,
+ 1.347153e+001,
+ -6.814585e-003,
+ 5.079068e-001,
+ 1.197230e-001,
+ 3.776949e+000,
+ 5.836961e-001,
+ -1.409868e+000,
+ -5.114330e-001,
+ 2.776539e+000,
+ -2.039001e+000,
+ -2.673769e-002,
+ 4.145288e-001,
+ 7.829342e-004,
+ 2.275883e+000,
+ 6.629691e-001,
+ -1.069151e+000,
+ -9.434247e-002,
+ 7.293972e-001,
+ -1.222473e+000,
+ -1.533461e-001,
+ 2.160357e+000,
+ 4.626837e-002,
+ 3.852415e+000,
+ 8.593570e-001,
+ -1.021306e+000,
+ -1.149551e-001,
+ -1.108414e+000,
+ 4.178343e+000,
+ 4.013665e-001,
+ -2.222814e+000,
+ 6.929462e-001,
+ 1.392652e+000,
+ 4.401662e-001,
+ -1.074251e+000,
+ -2.224002e-001,
+ 1.372356e+000,
+ -8.858704e+000,
+ -3.922660e+000,
+ 3.020018e+000,
+ -1.458724e-002,
+ 1.511186e+000,
+ 8.288064e-001,
+ -1.062048e+000,
+ -1.526582e-001,
+ 4.921067e-001,
+ 1.485522e+001,
+ -3.229936e+000,
+ -8.426604e-001,
+ 3.916243e-001,
+ 2.678994e+000,
+ 6.689264e-001,
+ // albedo 0, turbidity 6
+ -1.257023e+000,
+ -3.364700e-001,
+ -1.527795e+001,
+ 1.504223e+001,
+ 2.717715e-003,
+ 3.029910e-001,
+ 1.636851e-001,
+ 3.561663e+000,
+ 5.283161e-001,
+ -1.635124e+000,
+ -7.329993e-001,
+ 3.523939e+000,
+ -2.566337e+000,
+ -1.902543e-002,
+ 5.505483e-001,
+ -6.242176e-002,
+ 1.065992e+000,
+ 6.654236e-001,
+ -9.295823e-001,
+ 4.845834e-002,
+ -2.992990e-001,
+ -2.001327e-001,
+ -8.019339e-002,
+ 1.807806e+000,
+ 9.020277e-002,
+ 5.095372e+000,
+ 8.639936e-001,
+ -1.093740e+000,
+ -2.148608e-001,
+ -5.216240e-001,
+ 2.119777e+000,
+ 9.506454e-002,
+ -1.831439e+000,
+ 6.961204e-001,
+ 1.102084e-001,
+ 4.384319e-001,
+ -1.044181e+000,
+ -1.849257e-001,
+ 9.071246e-001,
+ -4.648901e+000,
+ -2.279385e+000,
+ 2.356502e+000,
+ -4.169147e-002,
+ 1.932557e+000,
+ 8.296550e-001,
+ -1.061451e+000,
+ -1.458745e-001,
+ 2.952267e-001,
+ 8.967214e+000,
+ -3.726228e+000,
+ -5.022316e-001,
+ 5.684877e-001,
+ 3.102347e+000,
+ 6.658443e-001,
+ // albedo 0, turbidity 7
+ -1.332391e+000,
+ -4.127769e-001,
+ -9.328643e+000,
+ 9.046194e+000,
+ 3.457775e-003,
+ 3.377425e-001,
+ 1.530909e-001,
+ 3.301209e+000,
+ 4.997917e-001,
+ -1.932002e+000,
+ -9.947777e-001,
+ -2.042329e+000,
+ 3.586940e+000,
+ -5.642182e-002,
+ 8.130478e-001,
+ -8.195988e-002,
+ 1.118294e-001,
+ 5.617231e-001,
+ -8.707374e-001,
+ 1.286999e-001,
+ 1.820054e+000,
+ -4.674706e+000,
+ 3.317471e-003,
+ 5.919018e-001,
+ 1.975278e-001,
+ 6.686519e+000,
+ 9.631727e-001,
+ -1.070378e+000,
+ -3.030579e-001,
+ -9.041938e-001,
+ 6.200201e+000,
+ 1.232207e-001,
+ -3.650628e-001,
+ 5.029403e-001,
+ -2.903162e+000,
+ 3.811408e-001,
+ -1.063035e+000,
+ -1.637545e-001,
+ 5.853072e-001,
+ -7.889906e+000,
+ -1.200641e+000,
+ 1.035018e+000,
+ 1.192093e-001,
+ 3.267054e+000,
+ 8.416151e-001,
+ -1.053655e+000,
+ -1.562286e-001,
+ 2.423683e-001,
+ 1.128575e+001,
+ -4.363262e+000,
+ -7.314160e-002,
+ 5.642088e-001,
+ 2.514023e+000,
+ 6.670457e-001,
+ // albedo 0, turbidity 8
+ -1.366112e+000,
+ -4.718287e-001,
+ -7.876222e+000,
+ 7.746900e+000,
+ -9.182309e-003,
+ 4.716076e-001,
+ 8.320252e-002,
+ 3.165603e+000,
+ 5.392334e-001,
+ -2.468204e+000,
+ -1.336340e+000,
+ -5.386723e+000,
+ 7.072672e+000,
+ -8.329266e-002,
+ 8.636876e-001,
+ -1.978177e-002,
+ -1.326218e-001,
+ 2.979222e-001,
+ -9.653522e-001,
+ -2.373416e-002,
+ 1.810250e+000,
+ -6.467262e+000,
+ 1.410706e-001,
+ -4.753717e-001,
+ 3.003095e-001,
+ 6.551163e+000,
+ 1.151083e+000,
+ -8.943186e-001,
+ -2.487152e-001,
+ -2.308960e-001,
+ 8.512648e+000,
+ 1.298402e-001,
+ 1.034705e+000,
+ 2.303509e-001,
+ -3.924095e+000,
+ 2.982717e-001,
+ -1.146999e+000,
+ -2.318784e-001,
+ 8.992419e-002,
+ -9.933614e+000,
+ -8.860920e-001,
+ -3.071656e-002,
+ 2.852012e-001,
+ 3.046199e+000,
+ 8.599001e-001,
+ -1.032399e+000,
+ -1.645145e-001,
+ 2.683599e-001,
+ 1.327701e+001,
+ -4.407670e+000,
+ 7.709869e-002,
+ 4.951727e-001,
+ 1.957277e+000,
+ 6.630943e-001,
+ // albedo 0, turbidity 9
+ -1.469070e+000,
+ -6.135092e-001,
+ -6.506263e+000,
+ 6.661315e+000,
+ -3.835383e-002,
+ 7.150413e-001,
+ 7.784318e-003,
+ 2.820577e+000,
+ 6.756784e-001,
+ -2.501583e+000,
+ -1.247404e+000,
+ -1.523462e+001,
+ 1.633191e+001,
+ -1.204803e-002,
+ 5.896471e-001,
+ -2.002023e-002,
+ 1.144647e+000,
+ 6.177874e-002,
+ -2.438672e+000,
+ -1.127291e+000,
+ 5.731172e+000,
+ -1.021350e+001,
+ 6.165610e-002,
+ -7.752641e-001,
+ 4.708254e-001,
+ 4.176847e+000,
+ 1.200881e+000,
+ -1.513427e-001,
+ 9.792731e-002,
+ -1.612349e+000,
+ 9.814289e+000,
+ 5.188921e-002,
+ 1.716403e+000,
+ -7.039255e-002,
+ -2.815115e+000,
+ 3.291874e-001,
+ -1.318511e+000,
+ -3.650554e-001,
+ 4.221268e-001,
+ -9.294529e+000,
+ -4.397520e-002,
+ -8.100625e-001,
+ 3.742719e-001,
+ 1.834166e+000,
+ 8.223450e-001,
+ -1.016009e+000,
+ -1.820264e-001,
+ 1.278426e-001,
+ 1.182696e+001,
+ -4.801528e+000,
+ 4.947899e-001,
+ 4.660378e-001,
+ 1.601254e+000,
+ 6.702359e-001,
+ // albedo 0, turbidity 10
+ -1.841310e+000,
+ -9.781779e-001,
+ -4.610903e+000,
+ 4.824662e+000,
+ -5.100806e-002,
+ 6.463776e-001,
+ -6.377724e-006,
+ 2.216875e+000,
+ 8.618530e-001,
+ -2.376373e+000,
+ -1.108657e+000,
+ -1.489799e+001,
+ 1.546458e+001,
+ 4.091025e-002,
+ 9.761780e-002,
+ -1.048958e-002,
+ 2.165834e+000,
+ -1.609171e-001,
+ -4.710318e+000,
+ -2.261963e+000,
+ 6.947327e+000,
+ -1.034828e+001,
+ -1.325542e-001,
+ 7.508674e-001,
+ 2.247553e-001,
+ 2.873142e+000,
+ 1.297100e+000,
+ 2.163750e-001,
+ -1.944345e-001,
+ -2.437860e+000,
+ 1.011314e+001,
+ 4.450500e-001,
+ 3.111492e-001,
+ 2.751323e-001,
+ -1.627906e+000,
+ 2.531213e-001,
+ -1.258794e+000,
+ -3.524641e-001,
+ 8.425444e-001,
+ -1.085313e+001,
+ -1.154381e+000,
+ -4.638014e-001,
+ -2.781115e-003,
+ 4.344498e-001,
+ 8.507091e-001,
+ -1.018938e+000,
+ -1.804153e-001,
+ -6.354054e-002,
+ 1.573150e+001,
+ -4.386999e+000,
+ 6.211115e-001,
+ 5.294648e-001,
+ 1.580749e+000,
+ 6.586655e-001,
+ // albedo 1, turbidity 1
+ -1.116416e+000,
+ -1.917524e-001,
+ -1.068233e+001,
+ 1.222221e+001,
+ -3.668978e-002,
+ 1.054022e+000,
+ 1.592132e-002,
+ 3.180583e+000,
+ 5.627370e-001,
+ -1.132341e+000,
+ -1.671286e-001,
+ 5.976499e+000,
+ -4.227366e+000,
+ -9.542489e-002,
+ 8.664938e-001,
+ 8.351793e-003,
+ 4.876068e+000,
+ 4.492779e-001,
+ -1.087635e+000,
+ -3.173679e-001,
+ 4.314407e-001,
+ 1.100555e+000,
+ -4.410057e-001,
+ 1.677253e+000,
+ -3.005925e-002,
+ -4.201249e+000,
+ 1.070902e+000,
+ -1.083031e+000,
+ -8.847705e-002,
+ 1.291773e+000,
+ 4.546776e-001,
+ 3.091894e-001,
+ 7.261760e-001,
+ 4.203659e-002,
+ 5.990615e+000,
+ 3.704756e-001,
+ -1.057899e+000,
+ -2.246706e-001,
+ 2.329563e+000,
+ -1.219656e+000,
+ -5.335260e+000,
+ 8.545378e-001,
+ -3.906209e-002,
+ -9.025499e-001,
+ 7.797348e-001,
+ -1.073305e+000,
+ -1.522553e-001,
+ 1.767063e+000,
+ 1.904280e+000,
+ -3.101673e+000,
+ 3.995856e-001,
+ 2.905192e-002,
+ 2.563977e+000,
+ 5.753067e-001,
+ // albedo 1, turbidity 2
+ -1.113674e+000,
+ -1.759694e-001,
+ -9.754125e+000,
+ 1.087391e+001,
+ -3.841093e-002,
+ 9.524272e-001,
+ 5.680219e-002,
+ 4.227034e+000,
+ 6.029571e-001,
+ -1.126496e+000,
+ -1.680281e-001,
+ 5.332352e+000,
+ -4.575579e+000,
+ -6.761755e-002,
+ 3.295335e-001,
+ 1.194896e-001,
+ 5.570901e+000,
+ 4.536185e-001,
+ -1.103074e+000,
+ -2.681801e-001,
+ 6.571479e-002,
+ 2.396522e+000,
+ -4.551280e-001,
+ 2.466331e+000,
+ -1.232022e-001,
+ -3.023201e+000,
+ 1.086379e+000,
+ -1.053299e+000,
+ -2.697173e-002,
+ 8.379121e-001,
+ -9.681458e-001,
+ 5.890692e-001,
+ -4.872027e-001,
+ 2.936929e-001,
+ 7.510139e+000,
+ 3.079122e-001,
+ -1.079553e+000,
+ -2.710448e-001,
+ 2.462379e+000,
+ -3.713554e-001,
+ -8.534512e+000,
+ 1.828242e+000,
+ -1.686398e-001,
+ -1.961340e+000,
+ 8.941077e-001,
+ -1.069741e+000,
+ -1.396394e-001,
+ 1.657868e+000,
+ 3.236313e+000,
+ -2.706344e+000,
+ -2.948122e-001,
+ 1.314816e-001,
+ 2.868457e+000,
+ 5.413403e-001,
+ // albedo 1, turbidity 3
+ -1.131649e+000,
+ -1.954455e-001,
+ -7.751595e+000,
+ 8.685861e+000,
+ -4.910871e-002,
+ 8.992952e-001,
+ 4.710143e-002,
+ 4.254818e+000,
+ 6.821116e-001,
+ -1.156689e+000,
+ -1.884324e-001,
+ 3.163519e+000,
+ -3.091522e+000,
+ -6.613927e-002,
+ -2.575883e-002,
+ 1.640065e-001,
+ 6.073643e+000,
+ 4.453468e-001,
+ -1.079224e+000,
+ -2.621389e-001,
+ 9.446437e-001,
+ 1.448479e+000,
+ -3.969384e-001,
+ 2.626638e+000,
+ -8.101186e-002,
+ -3.016355e+000,
+ 1.076295e+000,
+ -1.080832e+000,
+ 1.033057e-002,
+ -3.500156e-001,
+ -3.281419e-002,
+ 5.655512e-001,
+ -1.156742e+000,
+ 4.534710e-001,
+ 8.774122e+000,
+ 2.772869e-001,
+ -1.051202e+000,
+ -2.679975e-001,
+ 2.719109e+000,
+ -2.190316e+000,
+ -6.878798e+000,
+ 2.250481e+000,
+ -2.030252e-001,
+ -2.026527e+000,
+ 9.701096e-001,
+ -1.089849e+000,
+ -1.598589e-001,
+ 1.564748e+000,
+ 6.869187e+000,
+ -3.053670e+000,
+ -6.110435e-001,
+ 1.644472e-001,
+ 2.370452e+000,
+ 5.511770e-001,
+ // albedo 1, turbidity 4
+ -1.171419e+000,
+ -2.429746e-001,
+ -8.991334e+000,
+ 9.571216e+000,
+ -2.772861e-002,
+ 6.688262e-001,
+ 7.683478e-002,
+ 3.785611e+000,
+ 6.347635e-001,
+ -1.228554e+000,
+ -2.917562e-001,
+ 2.753986e+000,
+ -2.491780e+000,
+ -4.663434e-002,
+ 3.118303e-001,
+ 7.546506e-002,
+ 4.463096e+000,
+ 5.955071e-001,
+ -1.093124e+000,
+ -2.447767e-001,
+ 9.097406e-001,
+ 5.448296e-001,
+ -2.957824e-001,
+ 2.024167e+000,
+ -5.152333e-004,
+ -1.069081e+000,
+ 9.369565e-001,
+ -1.056994e+000,
+ 1.569507e-002,
+ -8.217491e-001,
+ 1.870818e+000,
+ 7.061930e-001,
+ -1.483928e+000,
+ 5.978206e-001,
+ 6.864902e+000,
+ 3.673332e-001,
+ -1.054871e+000,
+ -2.758129e-001,
+ 2.712807e+000,
+ -5.950110e+000,
+ -6.554039e+000,
+ 2.447523e+000,
+ -1.895171e-001,
+ -1.454292e+000,
+ 9.131738e-001,
+ -1.100218e+000,
+ -1.746241e-001,
+ 1.438505e+000,
+ 1.115481e+001,
+ -3.266076e+000,
+ -8.837357e-001,
+ 1.970100e-001,
+ 1.991595e+000,
+ 5.907821e-001,
+ // albedo 1, turbidity 5
+ -1.207267e+000,
+ -2.913610e-001,
+ -1.103767e+001,
+ 1.140724e+001,
+ -1.416800e-002,
+ 5.564047e-001,
+ 8.476262e-002,
+ 3.371255e+000,
+ 6.221335e-001,
+ -1.429698e+000,
+ -5.374218e-001,
+ 2.837524e+000,
+ -2.221936e+000,
+ -2.422337e-002,
+ 9.313758e-002,
+ 7.190250e-002,
+ 1.869022e+000,
+ 5.609035e-001,
+ -1.002274e+000,
+ -6.972810e-002,
+ 4.031308e-001,
+ -3.932997e-001,
+ -1.521923e-001,
+ 2.390646e+000,
+ -6.893990e-002,
+ 2.999661e+000,
+ 1.017843e+000,
+ -1.081168e+000,
+ -1.178666e-001,
+ -4.968080e-001,
+ 3.919299e+000,
+ 6.046866e-001,
+ -2.440615e+000,
+ 7.891538e-001,
+ 2.140835e+000,
+ 2.740470e-001,
+ -1.050727e+000,
+ -2.307688e-001,
+ 2.276396e+000,
+ -9.454407e+000,
+ -5.505176e+000,
+ 2.992620e+000,
+ -2.450942e-001,
+ 6.078372e-001,
+ 9.606765e-001,
+ -1.103752e+000,
+ -1.810202e-001,
+ 1.375044e+000,
+ 1.589095e+001,
+ -3.438954e+000,
+ -1.265669e+000,
+ 2.475172e-001,
+ 1.680768e+000,
+ 5.978056e-001,
+ // albedo 1, turbidity 6
+ -1.244324e+000,
+ -3.378542e-001,
+ -1.111001e+001,
+ 1.137784e+001,
+ -7.896794e-003,
+ 4.808023e-001,
+ 9.249904e-002,
+ 3.025816e+000,
+ 5.880239e-001,
+ -1.593165e+000,
+ -7.027621e-001,
+ 2.220896e+000,
+ -1.437709e+000,
+ -1.534738e-002,
+ 6.286958e-002,
+ 6.644555e-002,
+ 1.091727e+000,
+ 5.470080e-001,
+ -9.136506e-001,
+ 1.344874e-002,
+ 7.772636e-001,
+ -1.209396e+000,
+ -1.408978e-001,
+ 2.433718e+000,
+ -1.041938e-001,
+ 3.791244e+000,
+ 1.037916e+000,
+ -1.134968e+000,
+ -1.803315e-001,
+ -9.267335e-001,
+ 4.576670e+000,
+ 6.851928e-001,
+ -2.805000e+000,
+ 8.687208e-001,
+ 1.161483e+000,
+ 2.571688e-001,
+ -1.017037e+000,
+ -2.053943e-001,
+ 2.361640e+000,
+ -9.887818e+000,
+ -5.122889e+000,
+ 3.287088e+000,
+ -2.594102e-001,
+ 8.578927e-001,
+ 9.592340e-001,
+ -1.118723e+000,
+ -1.934942e-001,
+ 1.226023e+000,
+ 1.674140e+001,
+ -3.277335e+000,
+ -1.629809e+000,
+ 2.765232e-001,
+ 1.637713e+000,
+ 6.113963e-001,
+ // albedo 1, turbidity 7
+ -1.314779e+000,
+ -4.119915e-001,
+ -1.241150e+001,
+ 1.241578e+001,
+ 2.344284e-003,
+ 2.980837e-001,
+ 1.414613e-001,
+ 2.781731e+000,
+ 4.998556e-001,
+ -1.926199e+000,
+ -1.020038e+000,
+ 2.569200e+000,
+ -1.081159e+000,
+ -2.266833e-002,
+ 3.588668e-001,
+ 8.750078e-003,
+ -2.452171e-001,
+ 4.796758e-001,
+ -7.780002e-001,
+ 1.850647e-001,
+ 4.445456e-002,
+ -2.409297e+000,
+ -7.816346e-002,
+ 1.546790e+000,
+ -2.807227e-002,
+ 5.998176e+000,
+ 1.132396e+000,
+ -1.179326e+000,
+ -3.578330e-001,
+ -2.392933e-001,
+ 6.467883e+000,
+ 5.904596e-001,
+ -1.869975e+000,
+ 8.045839e-001,
+ -2.498121e+000,
+ 1.610633e-001,
+ -1.009956e+000,
+ -1.311896e-001,
+ 1.726577e+000,
+ -1.219356e+001,
+ -3.466239e+000,
+ 2.343602e+000,
+ -2.252205e-001,
+ 2.573681e+000,
+ 1.027109e+000,
+ -1.112460e+000,
+ -2.063093e-001,
+ 1.233051e+000,
+ 2.058946e+001,
+ -4.578074e+000,
+ -1.145643e+000,
+ 3.160192e-001,
+ 1.420159e+000,
+ 5.860212e-001,
+ // albedo 1, turbidity 8
+ -1.371689e+000,
+ -4.914196e-001,
+ -1.076610e+001,
+ 1.107405e+001,
+ -1.485077e-002,
+ 5.936218e-001,
+ 3.685482e-002,
+ 2.599968e+000,
+ 6.002204e-001,
+ -2.436997e+000,
+ -1.377939e+000,
+ 2.130141e-002,
+ 1.079593e+000,
+ -1.796232e-002,
+ -3.933248e-002,
+ 1.610711e-001,
+ -6.901181e-001,
+ 1.206416e-001,
+ -8.743368e-001,
+ 7.331370e-002,
+ 8.734259e-001,
+ -3.743126e+000,
+ -3.151167e-002,
+ 1.297596e+000,
+ -7.634926e-002,
+ 6.532873e+000,
+ 1.435737e+000,
+ -9.810197e-001,
+ -3.521634e-001,
+ -2.855205e-001,
+ 7.134674e+000,
+ 6.839748e-001,
+ -1.394841e+000,
+ 6.952036e-001,
+ -4.633104e+000,
+ -2.173401e-002,
+ -1.122958e+000,
+ -1.691536e-001,
+ 1.382360e+000,
+ -1.102913e+001,
+ -2.608171e+000,
+ 1.865111e+000,
+ -1.345154e-001,
+ 3.112342e+000,
+ 1.094134e+000,
+ -1.075586e+000,
+ -2.077415e-001,
+ 1.171477e+000,
+ 1.793270e+001,
+ -4.656858e+000,
+ -1.036839e+000,
+ 3.338295e-001,
+ 1.042793e+000,
+ 5.739374e-001,
+ // albedo 1, turbidity 9
+ -1.465871e+000,
+ -6.364486e-001,
+ -8.833718e+000,
+ 9.343650e+000,
+ -3.223600e-002,
+ 7.552848e-001,
+ -3.121341e-006,
+ 2.249164e+000,
+ 8.094662e-001,
+ -2.448924e+000,
+ -1.270878e+000,
+ -4.823703e+000,
+ 5.853058e+000,
+ -2.149127e-002,
+ 3.581132e-002,
+ -1.230276e-003,
+ 4.892553e-001,
+ -1.597657e-001,
+ -2.419809e+000,
+ -1.071337e+000,
+ 1.575648e+000,
+ -4.983580e+000,
+ 9.545185e-003,
+ 5.032615e-001,
+ 4.186266e-001,
+ 4.634147e+000,
+ 1.433517e+000,
+ -1.383278e-001,
+ -2.797095e-002,
+ -1.943067e-001,
+ 6.679623e+000,
+ 4.118280e-001,
+ -2.744289e-001,
+ -2.118722e-002,
+ -4.337025e+000,
+ 1.505072e-001,
+ -1.341872e+000,
+ -2.518572e-001,
+ 1.027009e+000,
+ -6.527103e+000,
+ -1.081271e+000,
+ 1.015465e+000,
+ 2.845789e-001,
+ 2.470371e+000,
+ 9.278120e-001,
+ -1.040640e+000,
+ -2.367454e-001,
+ 1.100744e+000,
+ 8.827253e+000,
+ -4.560794e+000,
+ -7.287017e-001,
+ 2.842503e-001,
+ 6.336593e-001,
+ 6.327335e-001,
+ // albedo 1, turbidity 10
+ -1.877993e+000,
+ -1.025135e+000,
+ -4.311037e+000,
+ 4.715016e+000,
+ -4.711631e-002,
+ 6.335844e-001,
+ -7.665398e-006,
+ 1.788017e+000,
+ 9.001409e-001,
+ -2.281540e+000,
+ -1.137668e+000,
+ -1.036869e+001,
+ 1.136254e+001,
+ 1.961739e-002,
+ -9.836174e-002,
+ -6.734567e-003,
+ 1.320918e+000,
+ -2.400807e-001,
+ -4.904054e+000,
+ -2.315781e+000,
+ 5.735999e+000,
+ -8.626257e+000,
+ -1.255643e-001,
+ 1.545446e+000,
+ 1.396860e-001,
+ 2.972897e+000,
+ 1.429934e+000,
+ 4.077067e-001,
+ -1.833688e-001,
+ -2.450939e+000,
+ 9.119433e+000,
+ 4.505361e-001,
+ -1.340828e+000,
+ 3.973690e-001,
+ -1.785370e+000,
+ 9.628711e-002,
+ -1.296052e+000,
+ -3.250526e-001,
+ 1.813294e+000,
+ -1.031485e+001,
+ -1.388690e+000,
+ 1.239733e+000,
+ -8.989196e-002,
+ -3.389637e-001,
+ 9.639560e-001,
+ -1.062181e+000,
+ -2.423444e-001,
+ 7.577592e-001,
+ 1.566938e+001,
+ -4.462264e+000,
+ -5.742810e-001,
+ 3.262259e-001,
+ 9.461672e-001,
+ 6.232887e-001,
};
-static const double datasetXYZRad1[] =
-{
- // albedo 0, turbidity 1
- 1.560219e+000,
- 1.417388e+000,
- 1.206927e+000,
- 1.091949e+001,
- 5.931416e+000,
- 7.304788e+000,
- // albedo 0, turbidity 2
- 1.533049e+000,
- 1.560532e+000,
- 3.685059e-001,
- 1.355040e+001,
- 5.543711e+000,
- 7.792189e+000,
- // albedo 0, turbidity 3
- 1.471043e+000,
- 1.746088e+000,
- -9.299697e-001,
- 1.720362e+001,
- 5.473384e+000,
- 8.336416e+000,
- // albedo 0, turbidity 4
- 1.355991e+000,
- 2.109348e+000,
- -3.295855e+000,
- 2.264843e+001,
- 5.454607e+000,
- 9.304656e+000,
- // albedo 0, turbidity 5
- 1.244963e+000,
- 2.547533e+000,
- -5.841485e+000,
- 2.756879e+001,
- 5.576104e+000,
- 1.043287e+001,
- // albedo 0, turbidity 6
- 1.175532e+000,
- 2.784634e+000,
- -7.212225e+000,
- 2.975347e+001,
- 6.472980e+000,
- 1.092331e+001,
- // albedo 0, turbidity 7
- 1.082973e+000,
- 3.118094e+000,
- -8.934293e+000,
- 3.186879e+001,
- 8.473885e+000,
- 1.174019e+001,
- // albedo 0, turbidity 8
- 9.692500e-001,
- 3.349574e+000,
- -1.003810e+001,
- 3.147654e+001,
- 1.338931e+001,
- 1.272547e+001,
- // albedo 0, turbidity 9
- 8.547044e-001,
- 3.151538e+000,
- -9.095567e+000,
- 2.554995e+001,
- 2.273219e+001,
- 1.410398e+001,
- // albedo 0, turbidity 10
- 7.580340e-001,
- 2.311153e+000,
- -5.170814e+000,
- 1.229669e+001,
- 3.686529e+001,
- 1.598882e+001,
- // albedo 1, turbidity 1
- 1.664273e+000,
- 1.574468e+000,
- 1.422078e+000,
- 9.768247e+000,
- 1.447338e+001,
- 1.644988e+001,
- // albedo 1, turbidity 2
- 1.638295e+000,
- 1.719586e+000,
- 5.786675e-001,
- 1.239846e+001,
- 1.415419e+001,
- 1.728605e+001,
- // albedo 1, turbidity 3
- 1.572623e+000,
- 1.921559e+000,
- -7.714802e-001,
- 1.609246e+001,
- 1.420954e+001,
- 1.825908e+001,
- // albedo 1, turbidity 4
- 1.468395e+000,
- 2.211970e+000,
- -2.845869e+000,
- 2.075027e+001,
- 1.524822e+001,
- 1.937622e+001,
- // albedo 1, turbidity 5
- 1.355047e+000,
- 2.556469e+000,
- -4.960920e+000,
- 2.460237e+001,
- 1.648360e+001,
- 2.065648e+001,
- // albedo 1, turbidity 6
- 1.291642e+000,
- 2.742036e+000,
- -6.061967e+000,
- 2.602002e+001,
- 1.819144e+001,
- 2.116712e+001,
- // albedo 1, turbidity 7
- 1.194565e+000,
- 2.972120e+000,
- -7.295779e+000,
- 2.691805e+001,
- 2.124880e+001,
- 2.201819e+001,
- // albedo 1, turbidity 8
- 1.083631e+000,
- 3.047021e+000,
- -7.766096e+000,
- 2.496261e+001,
- 2.744264e+001,
- 2.291875e+001,
- // albedo 1, turbidity 9
- 9.707994e-001,
- 2.736459e+000,
- -6.308284e+000,
- 1.760860e+001,
- 3.776291e+001,
- 2.392150e+001,
- // albedo 1, turbidity 10
- 8.574294e-001,
- 1.865155e+000,
- -2.364707e+000,
- 4.337793e+000,
- 5.092831e+001,
- 2.523432e+001,
+static const double datasetXYZRad1[] = {
+ // albedo 0, turbidity 1
+ 1.560219e+000,
+ 1.417388e+000,
+ 1.206927e+000,
+ 1.091949e+001,
+ 5.931416e+000,
+ 7.304788e+000,
+ // albedo 0, turbidity 2
+ 1.533049e+000,
+ 1.560532e+000,
+ 3.685059e-001,
+ 1.355040e+001,
+ 5.543711e+000,
+ 7.792189e+000,
+ // albedo 0, turbidity 3
+ 1.471043e+000,
+ 1.746088e+000,
+ -9.299697e-001,
+ 1.720362e+001,
+ 5.473384e+000,
+ 8.336416e+000,
+ // albedo 0, turbidity 4
+ 1.355991e+000,
+ 2.109348e+000,
+ -3.295855e+000,
+ 2.264843e+001,
+ 5.454607e+000,
+ 9.304656e+000,
+ // albedo 0, turbidity 5
+ 1.244963e+000,
+ 2.547533e+000,
+ -5.841485e+000,
+ 2.756879e+001,
+ 5.576104e+000,
+ 1.043287e+001,
+ // albedo 0, turbidity 6
+ 1.175532e+000,
+ 2.784634e+000,
+ -7.212225e+000,
+ 2.975347e+001,
+ 6.472980e+000,
+ 1.092331e+001,
+ // albedo 0, turbidity 7
+ 1.082973e+000,
+ 3.118094e+000,
+ -8.934293e+000,
+ 3.186879e+001,
+ 8.473885e+000,
+ 1.174019e+001,
+ // albedo 0, turbidity 8
+ 9.692500e-001,
+ 3.349574e+000,
+ -1.003810e+001,
+ 3.147654e+001,
+ 1.338931e+001,
+ 1.272547e+001,
+ // albedo 0, turbidity 9
+ 8.547044e-001,
+ 3.151538e+000,
+ -9.095567e+000,
+ 2.554995e+001,
+ 2.273219e+001,
+ 1.410398e+001,
+ // albedo 0, turbidity 10
+ 7.580340e-001,
+ 2.311153e+000,
+ -5.170814e+000,
+ 1.229669e+001,
+ 3.686529e+001,
+ 1.598882e+001,
+ // albedo 1, turbidity 1
+ 1.664273e+000,
+ 1.574468e+000,
+ 1.422078e+000,
+ 9.768247e+000,
+ 1.447338e+001,
+ 1.644988e+001,
+ // albedo 1, turbidity 2
+ 1.638295e+000,
+ 1.719586e+000,
+ 5.786675e-001,
+ 1.239846e+001,
+ 1.415419e+001,
+ 1.728605e+001,
+ // albedo 1, turbidity 3
+ 1.572623e+000,
+ 1.921559e+000,
+ -7.714802e-001,
+ 1.609246e+001,
+ 1.420954e+001,
+ 1.825908e+001,
+ // albedo 1, turbidity 4
+ 1.468395e+000,
+ 2.211970e+000,
+ -2.845869e+000,
+ 2.075027e+001,
+ 1.524822e+001,
+ 1.937622e+001,
+ // albedo 1, turbidity 5
+ 1.355047e+000,
+ 2.556469e+000,
+ -4.960920e+000,
+ 2.460237e+001,
+ 1.648360e+001,
+ 2.065648e+001,
+ // albedo 1, turbidity 6
+ 1.291642e+000,
+ 2.742036e+000,
+ -6.061967e+000,
+ 2.602002e+001,
+ 1.819144e+001,
+ 2.116712e+001,
+ // albedo 1, turbidity 7
+ 1.194565e+000,
+ 2.972120e+000,
+ -7.295779e+000,
+ 2.691805e+001,
+ 2.124880e+001,
+ 2.201819e+001,
+ // albedo 1, turbidity 8
+ 1.083631e+000,
+ 3.047021e+000,
+ -7.766096e+000,
+ 2.496261e+001,
+ 2.744264e+001,
+ 2.291875e+001,
+ // albedo 1, turbidity 9
+ 9.707994e-001,
+ 2.736459e+000,
+ -6.308284e+000,
+ 1.760860e+001,
+ 3.776291e+001,
+ 2.392150e+001,
+ // albedo 1, turbidity 10
+ 8.574294e-001,
+ 1.865155e+000,
+ -2.364707e+000,
+ 4.337793e+000,
+ 5.092831e+001,
+ 2.523432e+001,
};
-static const double datasetXYZ2[] =
-{
- // albedo 0, turbidity 1
- -1.127942e+000,
- -1.905548e-001,
- -1.252356e+001,
- 1.375799e+001,
- -3.624732e-002,
- 1.055453e+000,
- 1.385036e-002,
- 4.176970e+000,
- 5.928345e-001,
- -1.155260e+000,
- -1.778135e-001,
- 6.216056e+000,
- -5.254116e+000,
- -8.787445e-002,
- 8.434621e-001,
- 4.025734e-002,
- 6.195322e+000,
- 3.111856e-001,
- -1.125624e+000,
- -3.217593e-001,
- 5.043919e-001,
- 1.686284e+000,
- -3.536071e-001,
- 1.476321e+000,
- -7.899019e-002,
- -4.522531e+000,
- 1.271691e+000,
- -1.081801e+000,
- -1.033234e-001,
- 9.995550e-001,
- 7.482946e-003,
- -6.776018e-002,
- 1.463141e+000,
- 9.492021e-002,
- 5.612723e+000,
- 1.298846e-001,
- -1.075320e+000,
- -2.402711e-001,
- 2.141284e+000,
- -1.203359e+000,
- -4.945188e+000,
- 1.437221e+000,
- -8.096750e-002,
- -1.028378e+000,
- 1.004164e+000,
- -1.073337e+000,
- -1.516517e-001,
- 1.639379e+000,
- 2.304669e+000,
- -3.214244e+000,
- 1.286245e+000,
- 5.613957e-002,
- 2.480902e+000,
- 4.999363e-001,
- // albedo 0, turbidity 2
- -1.128399e+000,
- -1.857793e-001,
- -1.089863e+001,
- 1.172984e+001,
- -3.768099e-002,
- 9.439285e-001,
- 4.869335e-002,
- 4.845114e+000,
- 6.119211e-001,
- -1.114002e+000,
- -1.399280e-001,
- 4.963800e+000,
- -4.685500e+000,
- -7.780879e-002,
- 4.049736e-001,
- 1.586297e-001,
- 7.770264e+000,
- 3.449006e-001,
- -1.185472e+000,
- -3.403543e-001,
- 6.588322e-001,
- 1.133713e+000,
- -4.118674e-001,
- 2.061191e+000,
- -1.882768e-001,
- -4.372586e+000,
- 1.223530e+000,
- -1.002272e+000,
- 2.000703e-002,
- 7.073269e-002,
- 1.485075e+000,
- 5.005589e-001,
- 4.301494e-001,
- 3.626541e-001,
- 7.921098e+000,
- 1.574766e-001,
- -1.121006e+000,
- -3.007777e-001,
- 2.242051e+000,
- -4.571561e+000,
- -7.761071e+000,
- 2.053404e+000,
- -1.524018e-001,
- -1.886162e+000,
- 1.018208e+000,
- -1.058864e+000,
- -1.358673e-001,
- 1.389667e+000,
- 8.633409e+000,
- -3.437249e+000,
- 7.295429e-001,
- 1.514700e-001,
- 2.842513e+000,
- 5.014325e-001,
- // albedo 0, turbidity 3
- -1.144464e+000,
- -2.043799e-001,
- -1.020188e+001,
- 1.071247e+001,
- -3.256693e-002,
- 7.860205e-001,
- 6.872719e-002,
- 4.824771e+000,
- 6.259836e-001,
- -1.170104e+000,
- -2.118626e-001,
- 4.391405e+000,
- -4.198900e+000,
- -7.111559e-002,
- 3.890442e-001,
- 1.024831e-001,
- 6.282535e+000,
- 5.365688e-001,
- -1.129171e+000,
- -2.552880e-001,
- 2.238298e-001,
- 7.314295e-001,
- -3.562730e-001,
- 1.881931e+000,
- -3.078716e-002,
- -1.039120e+000,
- 9.096301e-001,
- -1.042294e+000,
- 4.450203e-003,
- -5.116033e-001,
- 2.627589e+000,
- 6.098996e-001,
- -1.264638e-001,
- 4.325281e-001,
- 7.080503e+000,
- 4.583646e-001,
- -1.082293e+000,
- -2.723056e-001,
- 2.065076e+000,
- -8.143133e+000,
- -7.892212e+000,
- 2.142231e+000,
- -7.106240e-002,
- -1.122398e+000,
- 8.338505e-001,
- -1.071715e+000,
- -1.426568e-001,
- 1.095351e+000,
- 1.729783e+001,
- -3.851931e+000,
- 4.360514e-001,
- 2.114440e-001,
- 2.970832e+000,
- 5.944389e-001,
- // albedo 0, turbidity 4
- -1.195909e+000,
- -2.590449e-001,
- -1.191037e+001,
- 1.207947e+001,
- -1.589842e-002,
- 6.297846e-001,
- 9.054772e-002,
- 4.285959e+000,
- 5.933752e-001,
- -1.245763e+000,
- -3.316637e-001,
- 4.293660e+000,
- -3.694011e+000,
- -4.699947e-002,
- 4.843684e-001,
- 2.130425e-002,
- 4.097549e+000,
- 6.530809e-001,
- -1.148742e+000,
- -1.902509e-001,
- -2.393233e-001,
- -2.441254e-001,
- -2.610918e-001,
- 1.846988e+000,
- 3.532866e-002,
- 2.660106e+000,
- 8.358294e-001,
- -1.016080e+000,
- -7.444960e-002,
- -5.053436e-001,
- 4.388855e+000,
- 6.054987e-001,
- -1.208300e+000,
- 5.817215e-001,
- 2.543570e+000,
- 4.726568e-001,
- -1.072027e+000,
- -2.101440e-001,
- 1.518378e+000,
- -1.060119e+001,
- -6.016546e+000,
- 2.649475e+000,
- -5.166992e-002,
- 1.571269e+000,
- 8.344622e-001,
- -1.072365e+000,
- -1.511201e-001,
- 7.478010e-001,
- 1.900732e+001,
- -3.950387e+000,
- -3.473907e-001,
- 3.797211e-001,
- 2.782949e+000,
- 6.296808e-001,
- // albedo 0, turbidity 5
- -1.239423e+000,
- -3.136289e-001,
- -1.351100e+001,
- 1.349468e+001,
- -7.070423e-003,
- 5.012315e-001,
- 1.106008e-001,
- 3.803619e+000,
- 5.577948e-001,
- -1.452524e+000,
- -5.676944e-001,
- 2.993153e+000,
- -2.277288e+000,
- -2.168954e-002,
- 3.056720e-001,
- 1.152338e-002,
- 1.852697e+000,
- 6.427228e-001,
- -1.061421e+000,
- -4.590521e-002,
- 6.057022e-001,
- -1.096835e+000,
- -1.504952e-001,
- 2.344921e+000,
- -5.491832e-002,
- 5.268322e+000,
- 9.082253e-001,
- -1.042373e+000,
- -1.769498e-001,
- -1.075388e+000,
- 3.831712e+000,
- 3.154140e-001,
- -2.416458e+000,
- 7.909032e-001,
- -1.492892e-002,
- 3.854049e-001,
- -1.064159e+000,
- -1.892684e-001,
- 1.438685e+000,
- -8.166362e+000,
- -3.616364e+000,
- 3.275206e+000,
- -1.203825e-001,
- 2.039491e+000,
- 8.688057e-001,
- -1.070120e+000,
- -1.569508e-001,
- 4.124760e-001,
- 1.399683e+001,
- -3.547085e+000,
- -1.046326e+000,
- 4.973825e-001,
- 2.791231e+000,
- 6.503286e-001,
- // albedo 0, turbidity 6
- -1.283579e+000,
- -3.609518e-001,
- -1.335397e+001,
- 1.315248e+001,
- -4.431938e-004,
- 3.769526e-001,
- 1.429824e-001,
- 3.573613e+000,
- 4.998696e-001,
- -1.657952e+000,
- -7.627948e-001,
- 1.958222e+000,
- -7.949816e-001,
- -2.882837e-002,
- 5.356149e-001,
- -5.191946e-002,
- 8.869955e-001,
- 6.263320e-001,
- -9.527600e-001,
- 6.494189e-002,
- 5.361303e-001,
- -2.129590e+000,
- -9.258630e-002,
- 1.604776e+000,
- 5.067770e-002,
- 6.376055e+000,
- 9.138052e-001,
- -1.080827e+000,
- -2.523120e-001,
- -7.154262e-001,
- 4.120085e+000,
- 1.878228e-001,
- -1.492158e+000,
- 6.881655e-001,
- -1.446611e+000,
- 4.040631e-001,
- -1.054075e+000,
- -1.665498e-001,
- 9.191052e-001,
- -6.636943e+000,
- -1.894826e+000,
- 2.107810e+000,
- -3.680499e-002,
- 2.655452e+000,
- 8.413840e-001,
- -1.061127e+000,
- -1.448849e-001,
- 2.667493e-001,
- 1.034103e+001,
- -4.285769e+000,
- -3.874504e-001,
- 5.998752e-001,
- 3.132426e+000,
- 6.652753e-001,
- // albedo 0, turbidity 7
- -1.347345e+000,
- -4.287832e-001,
- -9.305553e+000,
- 9.133813e+000,
- -3.173527e-003,
- 3.977564e-001,
- 1.151420e-001,
- 3.320564e+000,
- 4.998134e-001,
- -1.927296e+000,
- -9.901372e-001,
- -2.593499e+000,
- 4.087421e+000,
- -5.833993e-002,
- 8.158929e-001,
- -4.681279e-002,
- 2.423716e-001,
- 4.938052e-001,
- -9.470092e-001,
- 7.325237e-002,
- 2.064735e+000,
- -5.167540e+000,
- -1.313751e-002,
- 4.832169e-001,
- 1.126295e-001,
- 6.970522e+000,
- 1.035022e+000,
- -1.022557e+000,
- -2.762616e-001,
- -9.375748e-001,
- 6.696739e+000,
- 2.200765e-001,
- -1.133253e-001,
- 5.492505e-001,
- -3.109391e+000,
- 3.321914e-001,
- -1.087444e+000,
- -1.836263e-001,
- 6.225024e-001,
- -8.576765e+000,
- -1.107637e+000,
- 7.859427e-001,
- 9.910909e-002,
- 3.112938e+000,
- 8.596261e-001,
- -1.051544e+000,
- -1.546262e-001,
- 2.371731e-001,
- 1.200502e+001,
- -4.527291e+000,
- 7.268862e-002,
- 5.571478e-001,
- 2.532873e+000,
- 6.662000e-001,
- // albedo 0, turbidity 8
- -1.375576e+000,
- -4.840019e-001,
- -8.121290e+000,
- 8.058140e+000,
- -1.445661e-002,
- 5.123314e-001,
- 5.813321e-002,
- 3.203219e+000,
- 5.442318e-001,
- -2.325221e+000,
- -1.241463e+000,
- -7.063430e+000,
- 8.741369e+000,
- -7.829950e-002,
- 8.844273e-001,
- -3.471106e-002,
- 1.740583e-001,
- 2.814079e-001,
- -1.228700e+000,
- -2.013412e-001,
- 2.949042e+000,
- -7.371945e+000,
- 1.071753e-001,
- -2.491970e-001,
- 2.265223e-001,
- 6.391504e+000,
- 1.172389e+000,
- -7.601786e-001,
- -1.680631e-001,
- -7.584444e-001,
- 8.541356e+000,
- 8.222291e-002,
- 6.729633e-001,
- 3.206615e-001,
- -3.700940e+000,
- 2.710054e-001,
- -1.191166e+000,
- -2.672347e-001,
- 2.927498e-001,
- -9.713613e+000,
- -4.783721e-001,
- 2.352803e-001,
- 2.161949e-001,
- 2.691481e+000,
- 8.745447e-001,
- -1.030135e+000,
- -1.653301e-001,
- 2.263443e-001,
- 1.296157e+001,
- -4.650644e+000,
- 7.055709e-003,
- 5.091975e-001,
- 2.000370e+000,
- 6.603839e-001,
- // albedo 0, turbidity 9
- -1.508018e+000,
- -6.460933e-001,
- -6.402745e+000,
- 6.545995e+000,
- -3.750320e-002,
- 6.921803e-001,
- 3.309819e-003,
- 2.797527e+000,
- 6.978446e-001,
- -2.333308e+000,
- -1.167837e+000,
- -1.746787e+001,
- 1.868630e+001,
- -8.948229e-003,
- 5.621946e-001,
- -3.402626e-002,
- 1.217943e+000,
- 1.149865e-002,
- -2.665953e+000,
- -1.226307e+000,
- 7.169725e+000,
- -1.159434e+001,
- 3.583420e-002,
- -3.074378e-001,
- 3.412248e-001,
- 4.422122e+000,
- 1.283791e+000,
- -9.705116e-002,
- 8.312991e-002,
- -2.160462e+000,
- 1.028235e+001,
- 3.543357e-002,
- 1.032049e+000,
- 1.058310e-001,
- -2.972898e+000,
- 2.418628e-001,
- -1.329617e+000,
- -3.699557e-001,
- 5.560117e-001,
- -9.730113e+000,
- 9.938865e-002,
- -3.071488e-001,
- 2.510691e-001,
- 1.777111e+000,
- 8.705142e-001,
- -1.019387e+000,
- -1.893247e-001,
- 1.194079e-001,
- 1.239436e+001,
- -4.799224e+000,
- 2.940213e-001,
- 4.841268e-001,
- 1.529724e+000,
- 6.582615e-001,
- // albedo 0, turbidity 10
- -1.896737e+000,
- -1.005442e+000,
- -6.411032e+000,
- 6.548220e+000,
- -3.227596e-002,
- 5.717262e-001,
- -8.115192e-006,
- 2.296704e+000,
- 9.000749e-001,
- -2.411116e+000,
- -1.225587e+000,
- -1.753629e+001,
- 1.829393e+001,
- 1.247555e-002,
- 2.364616e-001,
- -5.114637e-003,
- 1.603778e+000,
- -2.224156e-001,
- -4.707121e+000,
- -2.074977e+000,
- 7.942300e+000,
- -1.132407e+001,
- -5.415654e-002,
- 5.446811e-001,
- 1.032493e-001,
- 4.010235e+000,
- 1.369802e+000,
- 1.010482e-001,
- -4.013305e-001,
- -2.674579e+000,
- 9.779409e+000,
- 1.782506e-001,
- 7.053045e-001,
- 4.200002e-001,
- -2.400671e+000,
- 1.953165e-001,
- -1.243526e+000,
- -3.391255e-001,
- 8.848882e-001,
- -9.789025e+000,
- -3.997324e-001,
- -9.546227e-001,
- -1.044017e-001,
- 6.010593e-001,
- 8.714462e-001,
- -1.014633e+000,
- -1.730009e-001,
- -7.738934e-002,
- 1.390903e+001,
- -4.847307e+000,
- 1.076059e+000,
- 5.685743e-001,
- 1.572992e+000,
- 6.561432e-001,
- // albedo 1, turbidity 1
- -1.122998e+000,
- -1.881183e-001,
- -1.030709e+001,
- 1.158932e+001,
- -4.079495e-002,
- 9.603774e-001,
- 3.079436e-002,
- 4.009235e+000,
- 5.060745e-001,
- -1.134790e+000,
- -1.539688e-001,
- 5.478405e+000,
- -4.217270e+000,
- -1.043858e-001,
- 7.165008e-001,
- 1.524765e-002,
- 6.473623e+000,
- 4.207882e-001,
- -1.134957e+000,
- -3.513318e-001,
- 7.393837e-001,
- 1.354415e+000,
- -4.764078e-001,
- 1.690441e+000,
- -5.492640e-002,
- -5.563523e+000,
- 1.145743e+000,
- -1.058344e+000,
- -5.758503e-002,
- 1.168230e+000,
- 3.269824e-001,
- 1.795193e-001,
- 7.849011e-001,
- 7.441853e-002,
- 6.904804e+000,
- 2.818790e-001,
- -1.075194e+000,
- -2.355813e-001,
- 2.463685e+000,
- -1.536505e+000,
- -7.505771e+000,
- 9.619712e-001,
- -6.465851e-002,
- -1.355492e+000,
- 8.489847e-001,
- -1.079030e+000,
- -1.465328e-001,
- 1.773838e+000,
- 2.310131e+000,
- -3.136065e+000,
- 3.507952e-001,
- 4.435014e-002,
- 2.819225e+000,
- 5.689008e-001,
- // albedo 1, turbidity 2
- -1.125833e+000,
- -1.870849e-001,
- -9.555833e+000,
- 1.059713e+001,
- -4.225402e-002,
- 9.164663e-001,
- 4.338796e-002,
- 4.400980e+000,
- 6.056119e-001,
- -1.127440e+000,
- -1.551891e-001,
- 4.755621e+000,
- -4.408806e+000,
- -7.851763e-002,
- 2.268284e-001,
- 1.460070e-001,
- 7.048003e+000,
- 3.525997e-001,
- -1.143788e+000,
- -3.170178e-001,
- 5.480669e-001,
- 2.041830e+000,
- -4.532139e-001,
- 2.302233e+000,
- -1.887419e-001,
- -4.489221e+000,
- 1.250967e+000,
- -1.032849e+000,
- 7.376031e-003,
- 5.666073e-001,
- -2.312203e-001,
- 4.862894e-001,
- -1.748294e-001,
- 3.572870e-001,
- 8.380522e+000,
- 1.302333e-001,
- -1.093728e+000,
- -2.786977e-001,
- 2.641272e+000,
- -1.507494e+000,
- -8.731243e+000,
- 1.684055e+000,
- -2.023377e-001,
- -2.176398e+000,
- 1.013249e+000,
- -1.076578e+000,
- -1.456205e-001,
- 1.693935e+000,
- 2.945003e+000,
- -2.822673e+000,
- -2.520033e-001,
- 1.517034e-001,
- 2.649109e+000,
- 5.179094e-001,
- // albedo 1, turbidity 3
- -1.146417e+000,
- -2.119353e-001,
- -7.187525e+000,
- 8.058599e+000,
- -5.256438e-002,
- 8.375733e-001,
- 3.887093e-002,
- 4.222111e+000,
- 6.695347e-001,
- -1.173674e+000,
- -2.067025e-001,
- 2.899359e+000,
- -2.804918e+000,
- -8.473899e-002,
- 3.944225e-003,
- 1.340641e-001,
- 6.160887e+000,
- 4.527141e-001,
- -1.090098e+000,
- -2.599633e-001,
- 9.180856e-001,
- 1.092710e+000,
- -4.215019e-001,
- 2.427660e+000,
- -9.277667e-002,
- -2.123523e+000,
- 1.058159e+000,
- -1.084460e+000,
- 8.056181e-003,
- -2.453510e-001,
- 6.619567e-001,
- 4.668118e-001,
- -9.526719e-001,
- 4.648454e-001,
- 8.001572e+000,
- 3.054194e-001,
- -1.053728e+000,
- -2.765784e-001,
- 2.792388e+000,
- -3.489517e+000,
- -8.150535e+000,
- 2.195757e+000,
- -2.017234e-001,
- -2.128017e+000,
- 9.326589e-001,
- -1.099348e+000,
- -1.593939e-001,
- 1.568292e+000,
- 7.247853e+000,
- -2.933000e+000,
- -5.890481e-001,
- 1.724440e-001,
- 2.433484e+000,
- 5.736558e-001,
- // albedo 1, turbidity 4
- -1.185983e+000,
- -2.581184e-001,
- -7.761056e+000,
- 8.317053e+000,
- -3.351773e-002,
- 6.676667e-001,
- 5.941733e-002,
- 3.820727e+000,
- 6.324032e-001,
- -1.268591e+000,
- -3.398067e-001,
- 2.348503e+000,
- -2.023779e+000,
- -5.368458e-002,
- 1.083282e-001,
- 8.402858e-002,
- 3.910254e+000,
- 5.577481e-001,
- -1.071353e+000,
- -1.992459e-001,
- 7.878387e-001,
- 1.974702e-001,
- -3.033058e-001,
- 2.335298e+000,
- -8.205259e-002,
- 7.954454e-001,
- 9.972312e-001,
- -1.089513e+000,
- -3.104364e-002,
- -5.995746e-001,
- 2.330281e+000,
- 6.581939e-001,
- -1.821467e+000,
- 6.679973e-001,
- 5.090195e+000,
- 3.125161e-001,
- -1.040214e+000,
- -2.570934e-001,
- 2.660489e+000,
- -6.506045e+000,
- -7.053586e+000,
- 2.763153e+000,
- -2.433632e-001,
- -7.648176e-001,
- 9.452937e-001,
- -1.116052e+000,
- -1.831993e-001,
- 1.457694e+000,
- 1.163608e+001,
- -3.216426e+000,
- -1.045594e+000,
- 2.285002e-001,
- 1.817407e+000,
- 5.810396e-001,
- // albedo 1, turbidity 5
- -1.230134e+000,
- -3.136264e-001,
- -8.909301e+000,
- 9.145006e+000,
- -1.055387e-002,
- 4.467317e-001,
- 1.016826e-001,
- 3.342964e+000,
- 5.633840e-001,
- -1.442907e+000,
- -5.593147e-001,
- 2.156447e+000,
- -1.241657e+000,
- -3.512130e-002,
- 3.050274e-001,
- 1.797175e-002,
- 1.742358e+000,
- 5.977153e-001,
- -1.027627e+000,
- -6.481539e-002,
- 4.351975e-001,
- -1.051677e+000,
- -2.030672e-001,
- 1.942684e+000,
- -3.615993e-002,
- 4.050266e+000,
- 9.801624e-001,
- -1.082110e+000,
- -1.578209e-001,
- -3.397511e-001,
- 4.163851e+000,
- 6.650368e-001,
- -1.841730e+000,
- 7.062544e-001,
- 6.789881e-001,
- 3.172623e-001,
- -1.047447e+000,
- -1.977560e-001,
- 2.183364e+000,
- -8.805249e+000,
- -5.483962e+000,
- 2.551309e+000,
- -1.779640e-001,
- 1.519501e+000,
- 9.212536e-001,
- -1.111853e+000,
- -1.935736e-001,
- 1.394408e+000,
- 1.392405e+001,
- -3.465430e+000,
- -1.068432e+000,
- 2.388671e-001,
- 1.455336e+000,
- 6.233425e-001,
- // albedo 1, turbidity 6
- -1.262238e+000,
- -3.546341e-001,
- -1.008703e+001,
- 1.020084e+001,
- -1.852187e-003,
- 3.537580e-001,
- 1.239199e-001,
- 3.056093e+000,
- 5.132052e-001,
- -1.613810e+000,
- -7.355585e-001,
- 2.760123e+000,
- -1.685253e+000,
- -2.517552e-002,
- 2.914258e-001,
- 4.743448e-003,
- 8.689596e-001,
- 5.674192e-001,
- -9.462336e-001,
- 2.950767e-002,
- -2.613816e-001,
- -7.398653e-001,
- -1.315558e-001,
- 1.901042e+000,
- -6.447844e-002,
- 4.969341e+000,
- 1.027342e+000,
- -1.111481e+000,
- -2.194054e-001,
- -9.004538e-002,
- 3.983442e+000,
- 4.871278e-001,
- -1.965315e+000,
- 7.956121e-001,
- -2.363225e-001,
- 2.718037e-001,
- -1.036397e+000,
- -1.827106e-001,
- 1.964747e+000,
- -8.870759e+000,
- -4.208011e+000,
- 2.461215e+000,
- -2.158905e-001,
- 1.561676e+000,
- 9.436866e-001,
- -1.113769e+000,
- -1.947819e-001,
- 1.300720e+000,
- 1.516476e+001,
- -4.088732e+000,
- -1.069384e+000,
- 2.836434e-001,
- 1.671451e+000,
- 6.229612e-001,
- // albedo 1, turbidity 7
- -1.328069e+000,
- -4.244047e-001,
- -8.417040e+000,
- 8.552244e+000,
- -6.813504e-003,
- 4.127422e-001,
- 9.619897e-002,
- 2.854227e+000,
- 5.059880e-001,
- -1.927552e+000,
- -1.025290e+000,
- 9.529576e-001,
- 4.255950e-001,
- -3.738779e-002,
- 2.584586e-001,
- 4.911004e-002,
- -2.640913e-001,
- 4.138626e-001,
- -8.488094e-001,
- 1.435988e-001,
- 6.356807e-001,
- -2.895732e+000,
- -8.473961e-002,
- 1.701305e+000,
- -1.323908e-001,
- 6.499338e+000,
- 1.210928e+000,
- -1.128313e+000,
- -3.397048e-001,
- -4.043140e-001,
- 6.265097e+000,
- 5.482395e-001,
- -2.057614e+000,
- 8.884087e-001,
- -2.943879e+000,
- 9.760301e-002,
- -1.039764e+000,
- -1.494772e-001,
- 1.781915e+000,
- -1.153012e+001,
- -3.379232e+000,
- 2.517231e+000,
- -2.764393e-001,
- 2.588849e+000,
- 1.052120e+000,
- -1.108447e+000,
- -2.012251e-001,
- 1.198640e+000,
- 1.925331e+001,
- -4.423892e+000,
- -1.257122e+000,
- 3.395690e-001,
- 1.481220e+000,
- 5.880175e-001,
- // albedo 1, turbidity 8
- -1.374185e+000,
- -4.967434e-001,
- -7.401318e+000,
- 7.724021e+000,
- -2.345723e-002,
- 5.979653e-001,
- 2.436346e-002,
- 2.658970e+000,
- 6.014891e-001,
- -2.310933e+000,
- -1.290290e+000,
- -1.301909e+000,
- 2.557806e+000,
- -3.744449e-002,
- 8.982861e-002,
- 1.090613e-001,
- -4.398363e-001,
- 1.184329e-001,
- -1.124730e+000,
- -9.921830e-002,
- 1.366902e+000,
- -4.172489e+000,
- -5.078016e-002,
- 1.393597e+000,
- -9.323843e-002,
- 6.452721e+000,
- 1.435913e+000,
- -8.468477e-001,
- -2.744819e-001,
- -4.347200e-001,
- 6.713362e+000,
- 6.127133e-001,
- -1.685634e+000,
- 7.360941e-001,
- -4.535502e+000,
- -2.920866e-002,
- -1.165242e+000,
- -2.008697e-001,
- 1.438778e+000,
- -1.008936e+001,
- -2.214771e+000,
- 2.102909e+000,
- -1.763085e-001,
- 2.859075e+000,
- 1.093470e+000,
- -1.074614e+000,
- -2.066374e-001,
- 1.131891e+000,
- 1.630063e+001,
- -4.801441e+000,
- -1.112590e+000,
- 3.595785e-001,
- 1.122227e+000,
- 5.794610e-001,
- // albedo 1, turbidity 9
- -1.521515e+000,
- -6.835604e-001,
- -5.571044e+000,
- 6.028774e+000,
- -4.253715e-002,
- 6.875746e-001,
- -5.279456e-006,
- 2.180150e+000,
- 8.487705e-001,
- -2.240415e+000,
- -1.171166e+000,
- -7.182771e+000,
- 8.417068e+000,
- -1.932866e-002,
- 1.101887e-001,
- -1.098862e-002,
- 6.242195e-001,
- -2.393875e-001,
- -2.712354e+000,
- -1.198830e+000,
- 3.180200e+000,
- -6.768130e+000,
- -2.563386e-003,
- 7.984607e-001,
- 2.764376e-001,
- 4.695358e+000,
- 1.557045e+000,
- -3.655172e-002,
- -2.142321e-002,
- -9.138120e-001,
- 7.932786e+000,
- 3.516542e-001,
- -7.994343e-001,
- 1.786761e-001,
- -4.208399e+000,
- 1.820576e-002,
- -1.368610e+000,
- -2.656212e-001,
- 1.249397e+000,
- -8.317818e+000,
- -8.962772e-001,
- 1.423249e+000,
- 1.478381e-001,
- 2.191660e+000,
- 1.007748e+000,
- -1.041753e+000,
- -2.453366e-001,
- 1.061102e+000,
- 1.130172e+001,
- -4.739312e+000,
- -9.223334e-001,
- 2.982776e-001,
- 6.162931e-001,
- 6.080302e-001,
- // albedo 1, turbidity 10
- -1.989159e+000,
- -1.095160e+000,
- -2.915550e+000,
- 3.275339e+000,
- -5.735765e-002,
- 5.742174e-001,
- -7.683288e-006,
- 1.763400e+000,
- 9.001342e-001,
- -2.070020e+000,
- -1.086338e+000,
- -1.095898e+001,
- 1.206960e+001,
- 3.780123e-002,
- -1.774699e-002,
- -5.881348e-004,
- 1.333819e+000,
- -2.605423e-001,
- -5.249653e+000,
- -2.383040e+000,
- 6.160406e+000,
- -9.097138e+000,
- -1.955319e-001,
- 1.651785e+000,
- 6.016463e-004,
- 3.021824e+000,
- 1.493574e+000,
- 4.685432e-001,
- -2.358662e-001,
- -2.666433e+000,
- 9.685763e+000,
- 5.804928e-001,
- -1.521875e+000,
- 5.668989e-001,
- -1.548136e+000,
- 1.688642e-002,
- -1.296891e+000,
- -3.449031e-001,
- 1.928548e+000,
- -1.167560e+001,
- -1.627615e+000,
- 1.355603e+000,
- -1.929074e-001,
- -6.568952e-001,
- 1.009774e+000,
- -1.067288e+000,
- -2.410392e-001,
- 7.147961e-001,
- 1.783840e+001,
- -4.374399e+000,
- -6.588777e-001,
- 3.329831e-001,
- 1.012066e+000,
- 6.118645e-001,
+static const double datasetXYZ2[] = {
+ // albedo 0, turbidity 1
+ -1.127942e+000,
+ -1.905548e-001,
+ -1.252356e+001,
+ 1.375799e+001,
+ -3.624732e-002,
+ 1.055453e+000,
+ 1.385036e-002,
+ 4.176970e+000,
+ 5.928345e-001,
+ -1.155260e+000,
+ -1.778135e-001,
+ 6.216056e+000,
+ -5.254116e+000,
+ -8.787445e-002,
+ 8.434621e-001,
+ 4.025734e-002,
+ 6.195322e+000,
+ 3.111856e-001,
+ -1.125624e+000,
+ -3.217593e-001,
+ 5.043919e-001,
+ 1.686284e+000,
+ -3.536071e-001,
+ 1.476321e+000,
+ -7.899019e-002,
+ -4.522531e+000,
+ 1.271691e+000,
+ -1.081801e+000,
+ -1.033234e-001,
+ 9.995550e-001,
+ 7.482946e-003,
+ -6.776018e-002,
+ 1.463141e+000,
+ 9.492021e-002,
+ 5.612723e+000,
+ 1.298846e-001,
+ -1.075320e+000,
+ -2.402711e-001,
+ 2.141284e+000,
+ -1.203359e+000,
+ -4.945188e+000,
+ 1.437221e+000,
+ -8.096750e-002,
+ -1.028378e+000,
+ 1.004164e+000,
+ -1.073337e+000,
+ -1.516517e-001,
+ 1.639379e+000,
+ 2.304669e+000,
+ -3.214244e+000,
+ 1.286245e+000,
+ 5.613957e-002,
+ 2.480902e+000,
+ 4.999363e-001,
+ // albedo 0, turbidity 2
+ -1.128399e+000,
+ -1.857793e-001,
+ -1.089863e+001,
+ 1.172984e+001,
+ -3.768099e-002,
+ 9.439285e-001,
+ 4.869335e-002,
+ 4.845114e+000,
+ 6.119211e-001,
+ -1.114002e+000,
+ -1.399280e-001,
+ 4.963800e+000,
+ -4.685500e+000,
+ -7.780879e-002,
+ 4.049736e-001,
+ 1.586297e-001,
+ 7.770264e+000,
+ 3.449006e-001,
+ -1.185472e+000,
+ -3.403543e-001,
+ 6.588322e-001,
+ 1.133713e+000,
+ -4.118674e-001,
+ 2.061191e+000,
+ -1.882768e-001,
+ -4.372586e+000,
+ 1.223530e+000,
+ -1.002272e+000,
+ 2.000703e-002,
+ 7.073269e-002,
+ 1.485075e+000,
+ 5.005589e-001,
+ 4.301494e-001,
+ 3.626541e-001,
+ 7.921098e+000,
+ 1.574766e-001,
+ -1.121006e+000,
+ -3.007777e-001,
+ 2.242051e+000,
+ -4.571561e+000,
+ -7.761071e+000,
+ 2.053404e+000,
+ -1.524018e-001,
+ -1.886162e+000,
+ 1.018208e+000,
+ -1.058864e+000,
+ -1.358673e-001,
+ 1.389667e+000,
+ 8.633409e+000,
+ -3.437249e+000,
+ 7.295429e-001,
+ 1.514700e-001,
+ 2.842513e+000,
+ 5.014325e-001,
+ // albedo 0, turbidity 3
+ -1.144464e+000,
+ -2.043799e-001,
+ -1.020188e+001,
+ 1.071247e+001,
+ -3.256693e-002,
+ 7.860205e-001,
+ 6.872719e-002,
+ 4.824771e+000,
+ 6.259836e-001,
+ -1.170104e+000,
+ -2.118626e-001,
+ 4.391405e+000,
+ -4.198900e+000,
+ -7.111559e-002,
+ 3.890442e-001,
+ 1.024831e-001,
+ 6.282535e+000,
+ 5.365688e-001,
+ -1.129171e+000,
+ -2.552880e-001,
+ 2.238298e-001,
+ 7.314295e-001,
+ -3.562730e-001,
+ 1.881931e+000,
+ -3.078716e-002,
+ -1.039120e+000,
+ 9.096301e-001,
+ -1.042294e+000,
+ 4.450203e-003,
+ -5.116033e-001,
+ 2.627589e+000,
+ 6.098996e-001,
+ -1.264638e-001,
+ 4.325281e-001,
+ 7.080503e+000,
+ 4.583646e-001,
+ -1.082293e+000,
+ -2.723056e-001,
+ 2.065076e+000,
+ -8.143133e+000,
+ -7.892212e+000,
+ 2.142231e+000,
+ -7.106240e-002,
+ -1.122398e+000,
+ 8.338505e-001,
+ -1.071715e+000,
+ -1.426568e-001,
+ 1.095351e+000,
+ 1.729783e+001,
+ -3.851931e+000,
+ 4.360514e-001,
+ 2.114440e-001,
+ 2.970832e+000,
+ 5.944389e-001,
+ // albedo 0, turbidity 4
+ -1.195909e+000,
+ -2.590449e-001,
+ -1.191037e+001,
+ 1.207947e+001,
+ -1.589842e-002,
+ 6.297846e-001,
+ 9.054772e-002,
+ 4.285959e+000,
+ 5.933752e-001,
+ -1.245763e+000,
+ -3.316637e-001,
+ 4.293660e+000,
+ -3.694011e+000,
+ -4.699947e-002,
+ 4.843684e-001,
+ 2.130425e-002,
+ 4.097549e+000,
+ 6.530809e-001,
+ -1.148742e+000,
+ -1.902509e-001,
+ -2.393233e-001,
+ -2.441254e-001,
+ -2.610918e-001,
+ 1.846988e+000,
+ 3.532866e-002,
+ 2.660106e+000,
+ 8.358294e-001,
+ -1.016080e+000,
+ -7.444960e-002,
+ -5.053436e-001,
+ 4.388855e+000,
+ 6.054987e-001,
+ -1.208300e+000,
+ 5.817215e-001,
+ 2.543570e+000,
+ 4.726568e-001,
+ -1.072027e+000,
+ -2.101440e-001,
+ 1.518378e+000,
+ -1.060119e+001,
+ -6.016546e+000,
+ 2.649475e+000,
+ -5.166992e-002,
+ 1.571269e+000,
+ 8.344622e-001,
+ -1.072365e+000,
+ -1.511201e-001,
+ 7.478010e-001,
+ 1.900732e+001,
+ -3.950387e+000,
+ -3.473907e-001,
+ 3.797211e-001,
+ 2.782949e+000,
+ 6.296808e-001,
+ // albedo 0, turbidity 5
+ -1.239423e+000,
+ -3.136289e-001,
+ -1.351100e+001,
+ 1.349468e+001,
+ -7.070423e-003,
+ 5.012315e-001,
+ 1.106008e-001,
+ 3.803619e+000,
+ 5.577948e-001,
+ -1.452524e+000,
+ -5.676944e-001,
+ 2.993153e+000,
+ -2.277288e+000,
+ -2.168954e-002,
+ 3.056720e-001,
+ 1.152338e-002,
+ 1.852697e+000,
+ 6.427228e-001,
+ -1.061421e+000,
+ -4.590521e-002,
+ 6.057022e-001,
+ -1.096835e+000,
+ -1.504952e-001,
+ 2.344921e+000,
+ -5.491832e-002,
+ 5.268322e+000,
+ 9.082253e-001,
+ -1.042373e+000,
+ -1.769498e-001,
+ -1.075388e+000,
+ 3.831712e+000,
+ 3.154140e-001,
+ -2.416458e+000,
+ 7.909032e-001,
+ -1.492892e-002,
+ 3.854049e-001,
+ -1.064159e+000,
+ -1.892684e-001,
+ 1.438685e+000,
+ -8.166362e+000,
+ -3.616364e+000,
+ 3.275206e+000,
+ -1.203825e-001,
+ 2.039491e+000,
+ 8.688057e-001,
+ -1.070120e+000,
+ -1.569508e-001,
+ 4.124760e-001,
+ 1.399683e+001,
+ -3.547085e+000,
+ -1.046326e+000,
+ 4.973825e-001,
+ 2.791231e+000,
+ 6.503286e-001,
+ // albedo 0, turbidity 6
+ -1.283579e+000,
+ -3.609518e-001,
+ -1.335397e+001,
+ 1.315248e+001,
+ -4.431938e-004,
+ 3.769526e-001,
+ 1.429824e-001,
+ 3.573613e+000,
+ 4.998696e-001,
+ -1.657952e+000,
+ -7.627948e-001,
+ 1.958222e+000,
+ -7.949816e-001,
+ -2.882837e-002,
+ 5.356149e-001,
+ -5.191946e-002,
+ 8.869955e-001,
+ 6.263320e-001,
+ -9.527600e-001,
+ 6.494189e-002,
+ 5.361303e-001,
+ -2.129590e+000,
+ -9.258630e-002,
+ 1.604776e+000,
+ 5.067770e-002,
+ 6.376055e+000,
+ 9.138052e-001,
+ -1.080827e+000,
+ -2.523120e-001,
+ -7.154262e-001,
+ 4.120085e+000,
+ 1.878228e-001,
+ -1.492158e+000,
+ 6.881655e-001,
+ -1.446611e+000,
+ 4.040631e-001,
+ -1.054075e+000,
+ -1.665498e-001,
+ 9.191052e-001,
+ -6.636943e+000,
+ -1.894826e+000,
+ 2.107810e+000,
+ -3.680499e-002,
+ 2.655452e+000,
+ 8.413840e-001,
+ -1.061127e+000,
+ -1.448849e-001,
+ 2.667493e-001,
+ 1.034103e+001,
+ -4.285769e+000,
+ -3.874504e-001,
+ 5.998752e-001,
+ 3.132426e+000,
+ 6.652753e-001,
+ // albedo 0, turbidity 7
+ -1.347345e+000,
+ -4.287832e-001,
+ -9.305553e+000,
+ 9.133813e+000,
+ -3.173527e-003,
+ 3.977564e-001,
+ 1.151420e-001,
+ 3.320564e+000,
+ 4.998134e-001,
+ -1.927296e+000,
+ -9.901372e-001,
+ -2.593499e+000,
+ 4.087421e+000,
+ -5.833993e-002,
+ 8.158929e-001,
+ -4.681279e-002,
+ 2.423716e-001,
+ 4.938052e-001,
+ -9.470092e-001,
+ 7.325237e-002,
+ 2.064735e+000,
+ -5.167540e+000,
+ -1.313751e-002,
+ 4.832169e-001,
+ 1.126295e-001,
+ 6.970522e+000,
+ 1.035022e+000,
+ -1.022557e+000,
+ -2.762616e-001,
+ -9.375748e-001,
+ 6.696739e+000,
+ 2.200765e-001,
+ -1.133253e-001,
+ 5.492505e-001,
+ -3.109391e+000,
+ 3.321914e-001,
+ -1.087444e+000,
+ -1.836263e-001,
+ 6.225024e-001,
+ -8.576765e+000,
+ -1.107637e+000,
+ 7.859427e-001,
+ 9.910909e-002,
+ 3.112938e+000,
+ 8.596261e-001,
+ -1.051544e+000,
+ -1.546262e-001,
+ 2.371731e-001,
+ 1.200502e+001,
+ -4.527291e+000,
+ 7.268862e-002,
+ 5.571478e-001,
+ 2.532873e+000,
+ 6.662000e-001,
+ // albedo 0, turbidity 8
+ -1.375576e+000,
+ -4.840019e-001,
+ -8.121290e+000,
+ 8.058140e+000,
+ -1.445661e-002,
+ 5.123314e-001,
+ 5.813321e-002,
+ 3.203219e+000,
+ 5.442318e-001,
+ -2.325221e+000,
+ -1.241463e+000,
+ -7.063430e+000,
+ 8.741369e+000,
+ -7.829950e-002,
+ 8.844273e-001,
+ -3.471106e-002,
+ 1.740583e-001,
+ 2.814079e-001,
+ -1.228700e+000,
+ -2.013412e-001,
+ 2.949042e+000,
+ -7.371945e+000,
+ 1.071753e-001,
+ -2.491970e-001,
+ 2.265223e-001,
+ 6.391504e+000,
+ 1.172389e+000,
+ -7.601786e-001,
+ -1.680631e-001,
+ -7.584444e-001,
+ 8.541356e+000,
+ 8.222291e-002,
+ 6.729633e-001,
+ 3.206615e-001,
+ -3.700940e+000,
+ 2.710054e-001,
+ -1.191166e+000,
+ -2.672347e-001,
+ 2.927498e-001,
+ -9.713613e+000,
+ -4.783721e-001,
+ 2.352803e-001,
+ 2.161949e-001,
+ 2.691481e+000,
+ 8.745447e-001,
+ -1.030135e+000,
+ -1.653301e-001,
+ 2.263443e-001,
+ 1.296157e+001,
+ -4.650644e+000,
+ 7.055709e-003,
+ 5.091975e-001,
+ 2.000370e+000,
+ 6.603839e-001,
+ // albedo 0, turbidity 9
+ -1.508018e+000,
+ -6.460933e-001,
+ -6.402745e+000,
+ 6.545995e+000,
+ -3.750320e-002,
+ 6.921803e-001,
+ 3.309819e-003,
+ 2.797527e+000,
+ 6.978446e-001,
+ -2.333308e+000,
+ -1.167837e+000,
+ -1.746787e+001,
+ 1.868630e+001,
+ -8.948229e-003,
+ 5.621946e-001,
+ -3.402626e-002,
+ 1.217943e+000,
+ 1.149865e-002,
+ -2.665953e+000,
+ -1.226307e+000,
+ 7.169725e+000,
+ -1.159434e+001,
+ 3.583420e-002,
+ -3.074378e-001,
+ 3.412248e-001,
+ 4.422122e+000,
+ 1.283791e+000,
+ -9.705116e-002,
+ 8.312991e-002,
+ -2.160462e+000,
+ 1.028235e+001,
+ 3.543357e-002,
+ 1.032049e+000,
+ 1.058310e-001,
+ -2.972898e+000,
+ 2.418628e-001,
+ -1.329617e+000,
+ -3.699557e-001,
+ 5.560117e-001,
+ -9.730113e+000,
+ 9.938865e-002,
+ -3.071488e-001,
+ 2.510691e-001,
+ 1.777111e+000,
+ 8.705142e-001,
+ -1.019387e+000,
+ -1.893247e-001,
+ 1.194079e-001,
+ 1.239436e+001,
+ -4.799224e+000,
+ 2.940213e-001,
+ 4.841268e-001,
+ 1.529724e+000,
+ 6.582615e-001,
+ // albedo 0, turbidity 10
+ -1.896737e+000,
+ -1.005442e+000,
+ -6.411032e+000,
+ 6.548220e+000,
+ -3.227596e-002,
+ 5.717262e-001,
+ -8.115192e-006,
+ 2.296704e+000,
+ 9.000749e-001,
+ -2.411116e+000,
+ -1.225587e+000,
+ -1.753629e+001,
+ 1.829393e+001,
+ 1.247555e-002,
+ 2.364616e-001,
+ -5.114637e-003,
+ 1.603778e+000,
+ -2.224156e-001,
+ -4.707121e+000,
+ -2.074977e+000,
+ 7.942300e+000,
+ -1.132407e+001,
+ -5.415654e-002,
+ 5.446811e-001,
+ 1.032493e-001,
+ 4.010235e+000,
+ 1.369802e+000,
+ 1.010482e-001,
+ -4.013305e-001,
+ -2.674579e+000,
+ 9.779409e+000,
+ 1.782506e-001,
+ 7.053045e-001,
+ 4.200002e-001,
+ -2.400671e+000,
+ 1.953165e-001,
+ -1.243526e+000,
+ -3.391255e-001,
+ 8.848882e-001,
+ -9.789025e+000,
+ -3.997324e-001,
+ -9.546227e-001,
+ -1.044017e-001,
+ 6.010593e-001,
+ 8.714462e-001,
+ -1.014633e+000,
+ -1.730009e-001,
+ -7.738934e-002,
+ 1.390903e+001,
+ -4.847307e+000,
+ 1.076059e+000,
+ 5.685743e-001,
+ 1.572992e+000,
+ 6.561432e-001,
+ // albedo 1, turbidity 1
+ -1.122998e+000,
+ -1.881183e-001,
+ -1.030709e+001,
+ 1.158932e+001,
+ -4.079495e-002,
+ 9.603774e-001,
+ 3.079436e-002,
+ 4.009235e+000,
+ 5.060745e-001,
+ -1.134790e+000,
+ -1.539688e-001,
+ 5.478405e+000,
+ -4.217270e+000,
+ -1.043858e-001,
+ 7.165008e-001,
+ 1.524765e-002,
+ 6.473623e+000,
+ 4.207882e-001,
+ -1.134957e+000,
+ -3.513318e-001,
+ 7.393837e-001,
+ 1.354415e+000,
+ -4.764078e-001,
+ 1.690441e+000,
+ -5.492640e-002,
+ -5.563523e+000,
+ 1.145743e+000,
+ -1.058344e+000,
+ -5.758503e-002,
+ 1.168230e+000,
+ 3.269824e-001,
+ 1.795193e-001,
+ 7.849011e-001,
+ 7.441853e-002,
+ 6.904804e+000,
+ 2.818790e-001,
+ -1.075194e+000,
+ -2.355813e-001,
+ 2.463685e+000,
+ -1.536505e+000,
+ -7.505771e+000,
+ 9.619712e-001,
+ -6.465851e-002,
+ -1.355492e+000,
+ 8.489847e-001,
+ -1.079030e+000,
+ -1.465328e-001,
+ 1.773838e+000,
+ 2.310131e+000,
+ -3.136065e+000,
+ 3.507952e-001,
+ 4.435014e-002,
+ 2.819225e+000,
+ 5.689008e-001,
+ // albedo 1, turbidity 2
+ -1.125833e+000,
+ -1.870849e-001,
+ -9.555833e+000,
+ 1.059713e+001,
+ -4.225402e-002,
+ 9.164663e-001,
+ 4.338796e-002,
+ 4.400980e+000,
+ 6.056119e-001,
+ -1.127440e+000,
+ -1.551891e-001,
+ 4.755621e+000,
+ -4.408806e+000,
+ -7.851763e-002,
+ 2.268284e-001,
+ 1.460070e-001,
+ 7.048003e+000,
+ 3.525997e-001,
+ -1.143788e+000,
+ -3.170178e-001,
+ 5.480669e-001,
+ 2.041830e+000,
+ -4.532139e-001,
+ 2.302233e+000,
+ -1.887419e-001,
+ -4.489221e+000,
+ 1.250967e+000,
+ -1.032849e+000,
+ 7.376031e-003,
+ 5.666073e-001,
+ -2.312203e-001,
+ 4.862894e-001,
+ -1.748294e-001,
+ 3.572870e-001,
+ 8.380522e+000,
+ 1.302333e-001,
+ -1.093728e+000,
+ -2.786977e-001,
+ 2.641272e+000,
+ -1.507494e+000,
+ -8.731243e+000,
+ 1.684055e+000,
+ -2.023377e-001,
+ -2.176398e+000,
+ 1.013249e+000,
+ -1.076578e+000,
+ -1.456205e-001,
+ 1.693935e+000,
+ 2.945003e+000,
+ -2.822673e+000,
+ -2.520033e-001,
+ 1.517034e-001,
+ 2.649109e+000,
+ 5.179094e-001,
+ // albedo 1, turbidity 3
+ -1.146417e+000,
+ -2.119353e-001,
+ -7.187525e+000,
+ 8.058599e+000,
+ -5.256438e-002,
+ 8.375733e-001,
+ 3.887093e-002,
+ 4.222111e+000,
+ 6.695347e-001,
+ -1.173674e+000,
+ -2.067025e-001,
+ 2.899359e+000,
+ -2.804918e+000,
+ -8.473899e-002,
+ 3.944225e-003,
+ 1.340641e-001,
+ 6.160887e+000,
+ 4.527141e-001,
+ -1.090098e+000,
+ -2.599633e-001,
+ 9.180856e-001,
+ 1.092710e+000,
+ -4.215019e-001,
+ 2.427660e+000,
+ -9.277667e-002,
+ -2.123523e+000,
+ 1.058159e+000,
+ -1.084460e+000,
+ 8.056181e-003,
+ -2.453510e-001,
+ 6.619567e-001,
+ 4.668118e-001,
+ -9.526719e-001,
+ 4.648454e-001,
+ 8.001572e+000,
+ 3.054194e-001,
+ -1.053728e+000,
+ -2.765784e-001,
+ 2.792388e+000,
+ -3.489517e+000,
+ -8.150535e+000,
+ 2.195757e+000,
+ -2.017234e-001,
+ -2.128017e+000,
+ 9.326589e-001,
+ -1.099348e+000,
+ -1.593939e-001,
+ 1.568292e+000,
+ 7.247853e+000,
+ -2.933000e+000,
+ -5.890481e-001,
+ 1.724440e-001,
+ 2.433484e+000,
+ 5.736558e-001,
+ // albedo 1, turbidity 4
+ -1.185983e+000,
+ -2.581184e-001,
+ -7.761056e+000,
+ 8.317053e+000,
+ -3.351773e-002,
+ 6.676667e-001,
+ 5.941733e-002,
+ 3.820727e+000,
+ 6.324032e-001,
+ -1.268591e+000,
+ -3.398067e-001,
+ 2.348503e+000,
+ -2.023779e+000,
+ -5.368458e-002,
+ 1.083282e-001,
+ 8.402858e-002,
+ 3.910254e+000,
+ 5.577481e-001,
+ -1.071353e+000,
+ -1.992459e-001,
+ 7.878387e-001,
+ 1.974702e-001,
+ -3.033058e-001,
+ 2.335298e+000,
+ -8.205259e-002,
+ 7.954454e-001,
+ 9.972312e-001,
+ -1.089513e+000,
+ -3.104364e-002,
+ -5.995746e-001,
+ 2.330281e+000,
+ 6.581939e-001,
+ -1.821467e+000,
+ 6.679973e-001,
+ 5.090195e+000,
+ 3.125161e-001,
+ -1.040214e+000,
+ -2.570934e-001,
+ 2.660489e+000,
+ -6.506045e+000,
+ -7.053586e+000,
+ 2.763153e+000,
+ -2.433632e-001,
+ -7.648176e-001,
+ 9.452937e-001,
+ -1.116052e+000,
+ -1.831993e-001,
+ 1.457694e+000,
+ 1.163608e+001,
+ -3.216426e+000,
+ -1.045594e+000,
+ 2.285002e-001,
+ 1.817407e+000,
+ 5.810396e-001,
+ // albedo 1, turbidity 5
+ -1.230134e+000,
+ -3.136264e-001,
+ -8.909301e+000,
+ 9.145006e+000,
+ -1.055387e-002,
+ 4.467317e-001,
+ 1.016826e-001,
+ 3.342964e+000,
+ 5.633840e-001,
+ -1.442907e+000,
+ -5.593147e-001,
+ 2.156447e+000,
+ -1.241657e+000,
+ -3.512130e-002,
+ 3.050274e-001,
+ 1.797175e-002,
+ 1.742358e+000,
+ 5.977153e-001,
+ -1.027627e+000,
+ -6.481539e-002,
+ 4.351975e-001,
+ -1.051677e+000,
+ -2.030672e-001,
+ 1.942684e+000,
+ -3.615993e-002,
+ 4.050266e+000,
+ 9.801624e-001,
+ -1.082110e+000,
+ -1.578209e-001,
+ -3.397511e-001,
+ 4.163851e+000,
+ 6.650368e-001,
+ -1.841730e+000,
+ 7.062544e-001,
+ 6.789881e-001,
+ 3.172623e-001,
+ -1.047447e+000,
+ -1.977560e-001,
+ 2.183364e+000,
+ -8.805249e+000,
+ -5.483962e+000,
+ 2.551309e+000,
+ -1.779640e-001,
+ 1.519501e+000,
+ 9.212536e-001,
+ -1.111853e+000,
+ -1.935736e-001,
+ 1.394408e+000,
+ 1.392405e+001,
+ -3.465430e+000,
+ -1.068432e+000,
+ 2.388671e-001,
+ 1.455336e+000,
+ 6.233425e-001,
+ // albedo 1, turbidity 6
+ -1.262238e+000,
+ -3.546341e-001,
+ -1.008703e+001,
+ 1.020084e+001,
+ -1.852187e-003,
+ 3.537580e-001,
+ 1.239199e-001,
+ 3.056093e+000,
+ 5.132052e-001,
+ -1.613810e+000,
+ -7.355585e-001,
+ 2.760123e+000,
+ -1.685253e+000,
+ -2.517552e-002,
+ 2.914258e-001,
+ 4.743448e-003,
+ 8.689596e-001,
+ 5.674192e-001,
+ -9.462336e-001,
+ 2.950767e-002,
+ -2.613816e-001,
+ -7.398653e-001,
+ -1.315558e-001,
+ 1.901042e+000,
+ -6.447844e-002,
+ 4.969341e+000,
+ 1.027342e+000,
+ -1.111481e+000,
+ -2.194054e-001,
+ -9.004538e-002,
+ 3.983442e+000,
+ 4.871278e-001,
+ -1.965315e+000,
+ 7.956121e-001,
+ -2.363225e-001,
+ 2.718037e-001,
+ -1.036397e+000,
+ -1.827106e-001,
+ 1.964747e+000,
+ -8.870759e+000,
+ -4.208011e+000,
+ 2.461215e+000,
+ -2.158905e-001,
+ 1.561676e+000,
+ 9.436866e-001,
+ -1.113769e+000,
+ -1.947819e-001,
+ 1.300720e+000,
+ 1.516476e+001,
+ -4.088732e+000,
+ -1.069384e+000,
+ 2.836434e-001,
+ 1.671451e+000,
+ 6.229612e-001,
+ // albedo 1, turbidity 7
+ -1.328069e+000,
+ -4.244047e-001,
+ -8.417040e+000,
+ 8.552244e+000,
+ -6.813504e-003,
+ 4.127422e-001,
+ 9.619897e-002,
+ 2.854227e+000,
+ 5.059880e-001,
+ -1.927552e+000,
+ -1.025290e+000,
+ 9.529576e-001,
+ 4.255950e-001,
+ -3.738779e-002,
+ 2.584586e-001,
+ 4.911004e-002,
+ -2.640913e-001,
+ 4.138626e-001,
+ -8.488094e-001,
+ 1.435988e-001,
+ 6.356807e-001,
+ -2.895732e+000,
+ -8.473961e-002,
+ 1.701305e+000,
+ -1.323908e-001,
+ 6.499338e+000,
+ 1.210928e+000,
+ -1.128313e+000,
+ -3.397048e-001,
+ -4.043140e-001,
+ 6.265097e+000,
+ 5.482395e-001,
+ -2.057614e+000,
+ 8.884087e-001,
+ -2.943879e+000,
+ 9.760301e-002,
+ -1.039764e+000,
+ -1.494772e-001,
+ 1.781915e+000,
+ -1.153012e+001,
+ -3.379232e+000,
+ 2.517231e+000,
+ -2.764393e-001,
+ 2.588849e+000,
+ 1.052120e+000,
+ -1.108447e+000,
+ -2.012251e-001,
+ 1.198640e+000,
+ 1.925331e+001,
+ -4.423892e+000,
+ -1.257122e+000,
+ 3.395690e-001,
+ 1.481220e+000,
+ 5.880175e-001,
+ // albedo 1, turbidity 8
+ -1.374185e+000,
+ -4.967434e-001,
+ -7.401318e+000,
+ 7.724021e+000,
+ -2.345723e-002,
+ 5.979653e-001,
+ 2.436346e-002,
+ 2.658970e+000,
+ 6.014891e-001,
+ -2.310933e+000,
+ -1.290290e+000,
+ -1.301909e+000,
+ 2.557806e+000,
+ -3.744449e-002,
+ 8.982861e-002,
+ 1.090613e-001,
+ -4.398363e-001,
+ 1.184329e-001,
+ -1.124730e+000,
+ -9.921830e-002,
+ 1.366902e+000,
+ -4.172489e+000,
+ -5.078016e-002,
+ 1.393597e+000,
+ -9.323843e-002,
+ 6.452721e+000,
+ 1.435913e+000,
+ -8.468477e-001,
+ -2.744819e-001,
+ -4.347200e-001,
+ 6.713362e+000,
+ 6.127133e-001,
+ -1.685634e+000,
+ 7.360941e-001,
+ -4.535502e+000,
+ -2.920866e-002,
+ -1.165242e+000,
+ -2.008697e-001,
+ 1.438778e+000,
+ -1.008936e+001,
+ -2.214771e+000,
+ 2.102909e+000,
+ -1.763085e-001,
+ 2.859075e+000,
+ 1.093470e+000,
+ -1.074614e+000,
+ -2.066374e-001,
+ 1.131891e+000,
+ 1.630063e+001,
+ -4.801441e+000,
+ -1.112590e+000,
+ 3.595785e-001,
+ 1.122227e+000,
+ 5.794610e-001,
+ // albedo 1, turbidity 9
+ -1.521515e+000,
+ -6.835604e-001,
+ -5.571044e+000,
+ 6.028774e+000,
+ -4.253715e-002,
+ 6.875746e-001,
+ -5.279456e-006,
+ 2.180150e+000,
+ 8.487705e-001,
+ -2.240415e+000,
+ -1.171166e+000,
+ -7.182771e+000,
+ 8.417068e+000,
+ -1.932866e-002,
+ 1.101887e-001,
+ -1.098862e-002,
+ 6.242195e-001,
+ -2.393875e-001,
+ -2.712354e+000,
+ -1.198830e+000,
+ 3.180200e+000,
+ -6.768130e+000,
+ -2.563386e-003,
+ 7.984607e-001,
+ 2.764376e-001,
+ 4.695358e+000,
+ 1.557045e+000,
+ -3.655172e-002,
+ -2.142321e-002,
+ -9.138120e-001,
+ 7.932786e+000,
+ 3.516542e-001,
+ -7.994343e-001,
+ 1.786761e-001,
+ -4.208399e+000,
+ 1.820576e-002,
+ -1.368610e+000,
+ -2.656212e-001,
+ 1.249397e+000,
+ -8.317818e+000,
+ -8.962772e-001,
+ 1.423249e+000,
+ 1.478381e-001,
+ 2.191660e+000,
+ 1.007748e+000,
+ -1.041753e+000,
+ -2.453366e-001,
+ 1.061102e+000,
+ 1.130172e+001,
+ -4.739312e+000,
+ -9.223334e-001,
+ 2.982776e-001,
+ 6.162931e-001,
+ 6.080302e-001,
+ // albedo 1, turbidity 10
+ -1.989159e+000,
+ -1.095160e+000,
+ -2.915550e+000,
+ 3.275339e+000,
+ -5.735765e-002,
+ 5.742174e-001,
+ -7.683288e-006,
+ 1.763400e+000,
+ 9.001342e-001,
+ -2.070020e+000,
+ -1.086338e+000,
+ -1.095898e+001,
+ 1.206960e+001,
+ 3.780123e-002,
+ -1.774699e-002,
+ -5.881348e-004,
+ 1.333819e+000,
+ -2.605423e-001,
+ -5.249653e+000,
+ -2.383040e+000,
+ 6.160406e+000,
+ -9.097138e+000,
+ -1.955319e-001,
+ 1.651785e+000,
+ 6.016463e-004,
+ 3.021824e+000,
+ 1.493574e+000,
+ 4.685432e-001,
+ -2.358662e-001,
+ -2.666433e+000,
+ 9.685763e+000,
+ 5.804928e-001,
+ -1.521875e+000,
+ 5.668989e-001,
+ -1.548136e+000,
+ 1.688642e-002,
+ -1.296891e+000,
+ -3.449031e-001,
+ 1.928548e+000,
+ -1.167560e+001,
+ -1.627615e+000,
+ 1.355603e+000,
+ -1.929074e-001,
+ -6.568952e-001,
+ 1.009774e+000,
+ -1.067288e+000,
+ -2.410392e-001,
+ 7.147961e-001,
+ 1.783840e+001,
+ -4.374399e+000,
+ -6.588777e-001,
+ 3.329831e-001,
+ 1.012066e+000,
+ 6.118645e-001,
};
-static const double datasetXYZRad2[] =
-{
- // albedo 0, turbidity 1
- 1.632341e+000,
- 1.395230e+000,
- 1.375634e+000,
- 1.238193e+001,
- 5.921102e+000,
- 7.766508e+000,
- // albedo 0, turbidity 2
- 1.597115e+000,
- 1.554617e+000,
- 3.932382e-001,
- 1.505284e+001,
- 5.725234e+000,
- 8.158155e+000,
- // albedo 0, turbidity 3
- 1.522034e+000,
- 1.844545e+000,
- -1.322862e+000,
- 1.918382e+001,
- 5.440769e+000,
- 8.837119e+000,
- // albedo 0, turbidity 4
- 1.403048e+000,
- 2.290852e+000,
- -4.013792e+000,
- 2.485100e+001,
- 5.521888e+000,
- 9.845547e+000,
- // albedo 0, turbidity 5
- 1.286364e+000,
- 2.774498e+000,
- -6.648221e+000,
- 2.964151e+001,
- 5.923777e+000,
- 1.097075e+001,
- // albedo 0, turbidity 6
- 1.213544e+000,
- 3.040195e+000,
- -8.092676e+000,
- 3.186082e+001,
- 6.789782e+000,
- 1.158899e+001,
- // albedo 0, turbidity 7
- 1.122622e+000,
- 3.347465e+000,
- -9.649016e+000,
- 3.343824e+001,
- 9.347715e+000,
- 1.231374e+001,
- // albedo 0, turbidity 8
- 1.007356e+000,
- 3.543858e+000,
- -1.053520e+001,
- 3.239842e+001,
- 1.483962e+001,
- 1.331718e+001,
- // albedo 0, turbidity 9
- 8.956642e-001,
- 3.278700e+000,
- -9.254933e+000,
- 2.557923e+001,
- 2.489677e+001,
- 1.476166e+001,
- // albedo 0, turbidity 10
- 7.985143e-001,
- 2.340404e+000,
- -4.928274e+000,
- 1.141787e+001,
- 3.961501e+001,
- 1.682448e+001,
- // albedo 1, turbidity 1
- 1.745162e+000,
- 1.639467e+000,
- 1.342721e+000,
- 1.166033e+001,
- 1.490124e+001,
- 1.774031e+001,
- // albedo 1, turbidity 2
- 1.708439e+000,
- 1.819144e+000,
- 2.834399e-001,
- 1.448066e+001,
- 1.459214e+001,
- 1.858679e+001,
- // albedo 1, turbidity 3
- 1.631720e+000,
- 2.094799e+000,
- -1.378825e+000,
- 1.843198e+001,
- 1.463173e+001,
- 1.962881e+001,
- // albedo 1, turbidity 4
- 1.516536e+000,
- 2.438729e+000,
- -3.624121e+000,
- 2.298621e+001,
- 1.599782e+001,
- 2.070027e+001,
- // albedo 1, turbidity 5
- 1.405863e+000,
- 2.785191e+000,
- -5.705236e+000,
- 2.645121e+001,
- 1.768330e+001,
- 2.191903e+001,
- // albedo 1, turbidity 6
- 1.344052e+000,
- 2.951807e+000,
- -6.683851e+000,
- 2.744271e+001,
- 1.985706e+001,
- 2.229452e+001,
- // albedo 1, turbidity 7
- 1.245827e+000,
- 3.182923e+000,
- -7.822960e+000,
- 2.791395e+001,
- 2.327254e+001,
- 2.315910e+001,
- // albedo 1, turbidity 8
- 1.132305e+000,
- 3.202593e+000,
- -8.008429e+000,
- 2.521093e+001,
- 3.000014e+001,
- 2.405306e+001,
- // albedo 1, turbidity 9
- 1.020330e+000,
- 2.820556e+000,
- -6.238704e+000,
- 1.709276e+001,
- 4.077916e+001,
- 2.509949e+001,
- // albedo 1, turbidity 10
- 9.031570e-001,
- 1.863917e+000,
- -1.955738e+000,
- 3.032665e+000,
- 5.434290e+001,
- 2.641780e+001,
+static const double datasetXYZRad2[] = {
+ // albedo 0, turbidity 1
+ 1.632341e+000,
+ 1.395230e+000,
+ 1.375634e+000,
+ 1.238193e+001,
+ 5.921102e+000,
+ 7.766508e+000,
+ // albedo 0, turbidity 2
+ 1.597115e+000,
+ 1.554617e+000,
+ 3.932382e-001,
+ 1.505284e+001,
+ 5.725234e+000,
+ 8.158155e+000,
+ // albedo 0, turbidity 3
+ 1.522034e+000,
+ 1.844545e+000,
+ -1.322862e+000,
+ 1.918382e+001,
+ 5.440769e+000,
+ 8.837119e+000,
+ // albedo 0, turbidity 4
+ 1.403048e+000,
+ 2.290852e+000,
+ -4.013792e+000,
+ 2.485100e+001,
+ 5.521888e+000,
+ 9.845547e+000,
+ // albedo 0, turbidity 5
+ 1.286364e+000,
+ 2.774498e+000,
+ -6.648221e+000,
+ 2.964151e+001,
+ 5.923777e+000,
+ 1.097075e+001,
+ // albedo 0, turbidity 6
+ 1.213544e+000,
+ 3.040195e+000,
+ -8.092676e+000,
+ 3.186082e+001,
+ 6.789782e+000,
+ 1.158899e+001,
+ // albedo 0, turbidity 7
+ 1.122622e+000,
+ 3.347465e+000,
+ -9.649016e+000,
+ 3.343824e+001,
+ 9.347715e+000,
+ 1.231374e+001,
+ // albedo 0, turbidity 8
+ 1.007356e+000,
+ 3.543858e+000,
+ -1.053520e+001,
+ 3.239842e+001,
+ 1.483962e+001,
+ 1.331718e+001,
+ // albedo 0, turbidity 9
+ 8.956642e-001,
+ 3.278700e+000,
+ -9.254933e+000,
+ 2.557923e+001,
+ 2.489677e+001,
+ 1.476166e+001,
+ // albedo 0, turbidity 10
+ 7.985143e-001,
+ 2.340404e+000,
+ -4.928274e+000,
+ 1.141787e+001,
+ 3.961501e+001,
+ 1.682448e+001,
+ // albedo 1, turbidity 1
+ 1.745162e+000,
+ 1.639467e+000,
+ 1.342721e+000,
+ 1.166033e+001,
+ 1.490124e+001,
+ 1.774031e+001,
+ // albedo 1, turbidity 2
+ 1.708439e+000,
+ 1.819144e+000,
+ 2.834399e-001,
+ 1.448066e+001,
+ 1.459214e+001,
+ 1.858679e+001,
+ // albedo 1, turbidity 3
+ 1.631720e+000,
+ 2.094799e+000,
+ -1.378825e+000,
+ 1.843198e+001,
+ 1.463173e+001,
+ 1.962881e+001,
+ // albedo 1, turbidity 4
+ 1.516536e+000,
+ 2.438729e+000,
+ -3.624121e+000,
+ 2.298621e+001,
+ 1.599782e+001,
+ 2.070027e+001,
+ // albedo 1, turbidity 5
+ 1.405863e+000,
+ 2.785191e+000,
+ -5.705236e+000,
+ 2.645121e+001,
+ 1.768330e+001,
+ 2.191903e+001,
+ // albedo 1, turbidity 6
+ 1.344052e+000,
+ 2.951807e+000,
+ -6.683851e+000,
+ 2.744271e+001,
+ 1.985706e+001,
+ 2.229452e+001,
+ // albedo 1, turbidity 7
+ 1.245827e+000,
+ 3.182923e+000,
+ -7.822960e+000,
+ 2.791395e+001,
+ 2.327254e+001,
+ 2.315910e+001,
+ // albedo 1, turbidity 8
+ 1.132305e+000,
+ 3.202593e+000,
+ -8.008429e+000,
+ 2.521093e+001,
+ 3.000014e+001,
+ 2.405306e+001,
+ // albedo 1, turbidity 9
+ 1.020330e+000,
+ 2.820556e+000,
+ -6.238704e+000,
+ 1.709276e+001,
+ 4.077916e+001,
+ 2.509949e+001,
+ // albedo 1, turbidity 10
+ 9.031570e-001,
+ 1.863917e+000,
+ -1.955738e+000,
+ 3.032665e+000,
+ 5.434290e+001,
+ 2.641780e+001,
};
-static const double datasetXYZ3[] =
-{
- // albedo 0, turbidity 1
- -1.310023e+000,
- -4.407658e-001,
- -3.640340e+001,
- 3.683292e+001,
- -8.124762e-003,
- 5.297961e-001,
- 1.188633e-002,
- 3.138320e+000,
- 5.134778e-001,
- -1.424100e+000,
- -5.501606e-001,
- -1.753510e+001,
- 1.822769e+001,
- -1.539272e-002,
- 6.366826e-001,
- 2.661996e-003,
- 2.659915e+000,
- 4.071138e-001,
- -1.103436e+000,
- -1.884105e-001,
- 6.425322e+000,
- -6.910579e+000,
- -2.019861e-002,
- 3.553271e-001,
- -1.589061e-002,
- 5.345985e+000,
- 8.790218e-001,
- -1.186200e+000,
- -4.307514e-001,
- -3.957947e+000,
- 5.979352e+000,
- -5.348869e-002,
- 1.736117e+000,
- 3.491346e-002,
- -2.692261e+000,
- 5.610506e-001,
- -1.006038e+000,
- -1.305995e-001,
- 4.473513e+000,
- -3.806719e+000,
- 1.419407e-001,
- -2.148238e-002,
- -5.081185e-002,
- 3.735362e+000,
- 5.358280e-001,
- -1.078507e+000,
- -1.633754e-001,
- -3.812368e+000,
- 4.381700e+000,
- 2.988122e-002,
- 1.754224e+000,
- 1.472376e-001,
- 3.722798e+000,
- 4.999157e-001,
- // albedo 0, turbidity 2
- -1.333582e+000,
- -4.649908e-001,
- -3.359528e+001,
- 3.404375e+001,
- -9.384242e-003,
- 5.587511e-001,
- 5.726310e-003,
- 3.073145e+000,
- 5.425529e-001,
- -1.562624e+000,
- -7.107068e-001,
- -1.478170e+001,
- 1.559839e+001,
- -1.462375e-002,
- 5.050133e-001,
- 2.516017e-002,
- 1.604696e+000,
- 2.902403e-001,
- -8.930158e-001,
- 4.068077e-002,
- 1.373481e+000,
- -2.342752e+000,
- -2.098058e-002,
- 6.248686e-001,
- -5.258363e-002,
- 7.058214e+000,
- 1.150373e+000,
- -1.262823e+000,
- -4.818353e-001,
- 8.892610e-004,
- 1.923120e+000,
- -4.979718e-002,
- 1.040693e+000,
- 1.558103e-001,
- -2.852480e+000,
- 2.420691e-001,
- -9.968383e-001,
- -1.200648e-001,
- 1.324342e+000,
- -9.430889e-001,
- 1.931098e-001,
- 4.436916e-001,
- -7.320456e-002,
- 4.215931e+000,
- 7.898019e-001,
- -1.078185e+000,
- -1.718192e-001,
- -1.720191e+000,
- 2.358918e+000,
- 2.765637e-002,
- 1.260245e+000,
- 2.021941e-001,
- 3.395483e+000,
- 5.173628e-001,
- // albedo 0, turbidity 3
- -1.353023e+000,
- -4.813523e-001,
- -3.104920e+001,
- 3.140156e+001,
- -9.510741e-003,
- 5.542030e-001,
- 8.135471e-003,
- 3.136646e+000,
- 5.215989e-001,
- -1.624704e+000,
- -7.990201e-001,
- -2.167125e+001,
- 2.246341e+001,
- -1.163533e-002,
- 5.415746e-001,
- 2.618378e-002,
- 1.139214e+000,
- 3.444357e-001,
- -7.983610e-001,
- 1.417476e-001,
- 9.914841e+000,
- -1.081503e+001,
- -1.218845e-002,
- 3.411392e-001,
- -6.137698e-002,
- 7.445848e+000,
- 1.180080e+000,
- -1.266679e+000,
- -4.288977e-001,
- -5.818701e+000,
- 6.986437e+000,
- -8.180711e-002,
- 1.397403e+000,
- 2.016916e-001,
- -1.275731e+000,
- 2.592773e-001,
- -1.009707e+000,
- -1.537754e-001,
- 3.496378e+000,
- -3.013726e+000,
- 2.421150e-001,
- -2.831925e-001,
- 3.003395e-002,
- 3.702862e+000,
- 7.746320e-001,
- -1.075646e+000,
- -1.768747e-001,
- -1.347762e+000,
- 1.989004e+000,
- 1.375836e-002,
- 1.764810e+000,
- 1.330018e-001,
- 3.230864e+000,
- 6.626210e-001,
- // albedo 0, turbidity 4
- -1.375269e+000,
- -5.103569e-001,
- -3.442661e+001,
- 3.478703e+001,
- -8.460009e-003,
- 5.408643e-001,
- 4.813323e-003,
- 3.016078e+000,
- 5.062069e-001,
- -1.821679e+000,
- -9.766461e-001,
- -1.926488e+001,
- 1.997912e+001,
- -9.822567e-003,
- 3.649556e-001,
- 4.316092e-002,
- 8.930190e-001,
- 4.166527e-001,
- -6.633542e-001,
- 1.997841e-001,
- 2.395592e+000,
- -3.117175e+000,
- -1.080884e-002,
- 8.983814e-001,
- -1.375825e-001,
- 6.673463e+000,
- 1.115663e+000,
- -1.303240e+000,
- -3.612712e-001,
- 8.292959e-002,
- 3.381364e-001,
- -6.078648e-002,
- 3.229247e-001,
- 3.680987e-001,
- 7.046755e-001,
- 3.144924e-001,
- -9.952598e-001,
- -2.039076e-001,
- 4.026851e-001,
- 2.686684e-001,
- 1.640712e-001,
- 5.186341e-001,
- -1.205520e-002,
- 2.659613e+000,
- 8.030394e-001,
- -1.098579e+000,
- -2.151992e-001,
- 6.558198e-001,
- -7.436900e-004,
- -1.421817e-003,
- 1.073701e+000,
- 1.886875e-001,
- 2.536857e+000,
- 6.673923e-001,
- // albedo 0, turbidity 5
- -1.457986e+000,
- -5.906842e-001,
- -3.812464e+001,
- 3.838539e+001,
- -6.024357e-003,
- 4.741484e-001,
- 1.209223e-002,
- 2.818432e+000,
- 5.012433e-001,
- -1.835728e+000,
- -1.003405e+000,
- -6.848129e+000,
- 7.601943e+000,
- -1.277375e-002,
- 4.785598e-001,
- 3.366853e-002,
- 1.097701e+000,
- 4.636635e-001,
- -8.491348e-001,
- 9.466365e-003,
- -2.685226e+000,
- 2.004060e+000,
- -1.168708e-002,
- 6.752316e-001,
- -1.543371e-001,
- 5.674759e+000,
- 1.039534e+000,
- -1.083379e+000,
- -1.506790e-001,
- 7.328236e-001,
- -5.095568e-001,
- -8.609153e-002,
- 4.448820e-001,
- 4.174662e-001,
- 1.481556e+000,
- 3.942551e-001,
- -1.117089e+000,
- -3.337605e-001,
- 2.502281e-001,
- 4.036323e-001,
- 2.673899e-001,
- 2.829817e-001,
- 2.242450e-002,
- 2.043207e+000,
- 7.706902e-001,
- -1.071648e+000,
- -2.126200e-001,
- 6.069466e-001,
- -1.456290e-003,
- -5.515960e-001,
- 1.046755e+000,
- 1.985021e-001,
- 2.290245e+000,
- 6.876058e-001,
- // albedo 0, turbidity 6
- -1.483903e+000,
- -6.309647e-001,
- -4.380213e+001,
- 4.410537e+001,
- -5.712161e-003,
- 5.195992e-001,
- 2.028428e-003,
- 2.687114e+000,
- 5.098321e-001,
- -2.053976e+000,
- -1.141473e+000,
- 5.109183e-001,
- 8.060391e-002,
- -1.033983e-002,
- 4.066532e-001,
- 4.869627e-002,
- 1.161722e+000,
- 4.039525e-001,
- -6.348185e-001,
- 7.651292e-002,
- -1.031327e+001,
- 1.007598e+001,
- -2.083688e-002,
- 7.359516e-001,
- -2.029459e-001,
- 5.013257e+000,
- 1.077649e+000,
- -1.228630e+000,
- -1.650496e-001,
- 4.077157e-002,
- -7.189167e-001,
- -5.092220e-002,
- 2.959814e-001,
- 5.111496e-001,
- 2.540433e+000,
- 3.615330e-001,
- -1.041883e+000,
- -3.278413e-001,
- -6.691911e-002,
- 1.307364e+000,
- 2.166663e-001,
- 3.000595e-001,
- -3.157136e-003,
- 1.389208e+000,
- 7.999026e-001,
- -1.103556e+000,
- -2.443602e-001,
- 4.705347e-001,
- -9.296482e-004,
- -5.309920e-001,
- 9.654511e-001,
- 2.142587e-001,
- 2.244723e+000,
- 6.839976e-001,
- // albedo 0, turbidity 7
- -1.555684e+000,
- -6.962113e-001,
- -4.647983e+001,
- 4.674270e+001,
- -5.034895e-003,
- 4.755090e-001,
- -9.502561e-007,
- 2.626569e+000,
- 5.056194e-001,
- -1.998288e+000,
- -1.124720e+000,
- -1.629586e+000,
- 2.187993e+000,
- -8.284384e-003,
- 3.845258e-001,
- 5.726240e-002,
- 1.185644e+000,
- 4.255812e-001,
- -1.032570e+000,
- -2.513850e-001,
- -3.721112e+000,
- 3.506967e+000,
- -2.186561e-002,
- 9.436049e-001,
- -2.451412e-001,
- 4.725724e+000,
- 1.039256e+000,
- -8.597532e-001,
- 9.073332e-002,
- -2.553741e+000,
- 1.993237e+000,
- -4.390891e-002,
- -2.046928e-001,
- 5.515623e-001,
- 1.909127e+000,
- 3.948212e-001,
- -1.210482e+000,
- -4.477622e-001,
- -2.267805e-001,
- 1.219488e+000,
- 1.336186e-001,
- 6.866897e-001,
- 2.808997e-002,
- 1.600403e+000,
- 7.816409e-001,
- -1.078168e+000,
- -2.699261e-001,
- 2.537282e-001,
- 3.820684e-001,
- -4.425103e-001,
- 5.298235e-001,
- 2.185217e-001,
- 1.728679e+000,
- 6.882743e-001,
- // albedo 0, turbidity 8
- -1.697968e+000,
- -8.391488e-001,
- -5.790105e+001,
- 5.814120e+001,
- -3.404760e-003,
- 4.265140e-001,
- -1.796301e-006,
- 2.368442e+000,
- 5.324429e-001,
- -2.141552e+000,
- -1.172230e+000,
- 1.677872e+001,
- -1.641470e+001,
- -5.732425e-003,
- 2.002199e-001,
- 6.841834e-002,
- 1.485338e+000,
- 3.215763e-001,
- -1.442946e+000,
- -7.264245e-001,
- -9.503706e+000,
- 9.650462e+000,
- -2.120995e-002,
- 1.419263e+000,
- -2.893098e-001,
- 3.860731e+000,
- 1.120857e+000,
- -5.696752e-001,
- 3.411279e-001,
- -2.931035e-001,
- -6.512552e-001,
- -1.068437e-001,
- -1.085661e+000,
- 6.107549e-001,
- 1.459503e+000,
- 3.210336e-001,
- -1.313839e+000,
- -5.921371e-001,
- -2.332222e-001,
- 1.648196e+000,
- 2.492787e-001,
- 1.381033e+000,
- -1.993392e-002,
- 9.812560e-001,
- 8.316329e-001,
- -1.087464e+000,
- -3.195534e-001,
- 2.902095e-001,
- 3.383709e-001,
- -8.798482e-001,
- 1.494668e-002,
- 2.529703e-001,
- 1.452644e+000,
- 6.693870e-001,
- // albedo 0, turbidity 9
- -2.068582e+000,
- -1.118605e+000,
- -5.081598e+001,
- 5.097486e+001,
- -3.280669e-003,
- 4.067371e-001,
- -2.544951e-006,
- 2.179497e+000,
- 5.778017e-001,
- -1.744693e+000,
- -8.537207e-001,
- 2.234361e+001,
- -2.208318e+001,
- -5.932616e-003,
- 1.035049e-001,
- 5.742772e-002,
- 1.977880e+000,
- 2.124846e-001,
- -3.287515e+000,
- -2.140268e+000,
- -1.249566e+001,
- 1.240091e+001,
- -2.409349e-002,
- 1.397821e+000,
- -2.371627e-001,
- 2.771192e+000,
- 1.170496e+000,
- 5.502311e-001,
- 1.046630e+000,
- 2.193517e+000,
- -2.220400e+000,
- -1.064394e-001,
- -1.017926e+000,
- 4.795457e-001,
- 1.030644e+000,
- 3.177516e-001,
- -1.719734e+000,
- -9.536198e-001,
- -6.586821e-001,
- 1.386361e+000,
- -2.513065e-002,
- 1.187011e+000,
- 6.542539e-002,
- 5.296055e-001,
- 8.082660e-001,
- -1.005700e+000,
- -3.028096e-001,
- 4.470957e-002,
- 1.007760e+000,
- -8.119016e-001,
- 3.153338e-002,
- 2.311321e-001,
- 1.182208e+000,
- 6.824758e-001,
- // albedo 0, turbidity 10
- -2.728867e+000,
- -1.580388e+000,
- -3.079627e+001,
- 3.092586e+001,
- -4.197673e-003,
- 3.154759e-001,
- -3.897675e-006,
- 1.920567e+000,
- 6.664791e-001,
- -1.322495e+000,
- -7.249275e-001,
- 1.477660e+001,
- -1.468154e+001,
- -9.044857e-003,
- 5.624314e-002,
- 6.498392e-002,
- 2.047389e+000,
- 6.367540e-002,
- -6.102376e+000,
- -3.473018e+000,
- -9.926071e+000,
- 9.637797e+000,
- -1.097909e-002,
- 1.103498e+000,
- -2.424521e-001,
- 2.520748e+000,
- 1.240260e+000,
- 1.351796e+000,
- 1.018588e+000,
- 2.009081e+000,
- -1.333394e+000,
- -1.979125e-001,
- -3.318292e-001,
- 4.476624e-001,
- 9.095235e-001,
- 2.955611e-001,
- -1.774467e+000,
- -1.079880e+000,
- -8.084680e-002,
- 2.577697e-001,
- -1.149295e-001,
- 4.975303e-001,
- 2.931611e-003,
- -3.803171e-001,
- 8.002794e-001,
- -9.898401e-001,
- -2.542513e-001,
- -7.530911e-002,
- 1.870355e+000,
- -1.521918e+000,
- 2.405164e-001,
- 2.964615e-001,
- 1.334800e+000,
- 6.789053e-001,
- // albedo 1, turbidity 1
- -1.279730e+000,
- -4.290674e-001,
- -4.277972e+001,
- 4.343305e+001,
- -6.541826e-003,
- 4.945086e-001,
- 1.425338e-002,
- 2.685244e+000,
- 5.011313e-001,
- -1.449506e+000,
- -5.766374e-001,
- -1.688496e+001,
- 1.781118e+001,
- -1.121649e-002,
- 3.545020e-001,
- 2.287338e-002,
- 1.904281e+000,
- 4.936998e-001,
- -1.021980e+000,
- -1.897574e-001,
- 2.482462e+000,
- -2.941725e+000,
- -1.570448e-002,
- 7.532578e-001,
- -4.256800e-002,
- 5.239660e+000,
- 4.983116e-001,
- -1.162608e+000,
- -3.428049e-001,
- 3.974358e+000,
- -1.527935e+000,
- -3.919201e-002,
- 8.758593e-001,
- 7.291363e-002,
- -3.455257e+000,
- 8.007426e-001,
- -9.929985e-001,
- -8.712006e-002,
- -7.397313e-001,
- 1.348372e+000,
- 9.511685e-002,
- 3.233584e-001,
- -7.549148e-002,
- 5.806452e+000,
- 4.990042e-001,
- -1.084996e+000,
- -1.739767e-001,
- 1.580475e-001,
- 9.088180e-001,
- 6.871433e-002,
- 5.933079e-001,
- 1.188921e-001,
- 3.074079e+000,
- 4.999327e-001,
- // albedo 1, turbidity 2
- -1.317009e+000,
- -4.661946e-001,
- -4.255347e+001,
- 4.312782e+001,
- -5.727235e-003,
- 4.285447e-001,
- 2.189854e-002,
- 2.608310e+000,
- 5.190700e-001,
- -1.469236e+000,
- -6.282139e-001,
- -1.241404e+001,
- 1.348765e+001,
- -1.204770e-002,
- 5.070285e-001,
- -7.280216e-004,
- 1.491533e+000,
- 3.635064e-001,
- -9.713808e-001,
- -8.138038e-002,
- 3.709854e-001,
- -1.041174e+000,
- -1.814075e-002,
- 5.060860e-001,
- -2.053756e-002,
- 6.161431e+000,
- 1.093736e+000,
- -1.159057e+000,
- -3.698074e-001,
- 2.711209e+000,
- -6.006479e-001,
- -4.896926e-002,
- 9.273957e-001,
- 1.137712e-001,
- -3.496828e+000,
- 2.867109e-001,
- -1.011601e+000,
- -8.201890e-002,
- 2.105725e-001,
- 4.597520e-001,
- 1.478925e-001,
- 2.138940e-001,
- -5.660670e-002,
- 6.057755e+000,
- 7.859121e-001,
- -1.078020e+000,
- -1.811580e-001,
- 1.646622e-001,
- 8.348426e-001,
- 1.149064e-001,
- 4.985738e-001,
- 1.376605e-001,
- 2.746607e+000,
- 4.999626e-001,
- // albedo 1, turbidity 3
- -1.325672e+000,
- -4.769313e-001,
- -4.111215e+001,
- 4.168293e+001,
- -6.274997e-003,
- 4.649469e-001,
- 1.119411e-002,
- 2.631267e+000,
- 5.234546e-001,
- -1.619391e+000,
- -8.000253e-001,
- -1.534098e+001,
- 1.632706e+001,
- -1.012023e-002,
- 4.242255e-001,
- 2.931597e-002,
- 8.925807e-001,
- 3.314765e-001,
- -7.356979e-001,
- 1.368406e-001,
- 2.972579e+000,
- -3.535359e+000,
- -1.318948e-002,
- 4.607620e-001,
- -7.182778e-002,
- 6.254100e+000,
- 1.236299e+000,
- -1.316217e+000,
- -4.194427e-001,
- 3.489902e-002,
- 1.289849e+000,
- -4.755960e-002,
- 1.138222e+000,
- 1.975992e-001,
- -8.991542e-001,
- 2.290572e-001,
- -9.502188e-001,
- -1.172703e-001,
- 1.405202e+000,
- -3.061919e-001,
- 1.058772e-001,
- -3.760592e-001,
- -1.983179e-002,
- 3.562353e+000,
- 7.895959e-001,
- -1.100117e+000,
- -1.900567e-001,
- 4.925030e-001,
- 5.250225e-001,
- 1.576804e-001,
- 1.042701e+000,
- 7.330743e-002,
- 2.796064e+000,
- 6.749783e-001,
- // albedo 1, turbidity 4
- -1.354183e+000,
- -5.130625e-001,
- -4.219268e+001,
- 4.271772e+001,
- -5.365373e-003,
- 4.136743e-001,
- 1.235172e-002,
- 2.520122e+000,
- 5.187269e-001,
- -1.741434e+000,
- -9.589761e-001,
- -8.230339e+000,
- 9.296799e+000,
- -9.600162e-003,
- 4.994969e-001,
- 2.955452e-002,
- 3.667099e-001,
- 3.526999e-001,
- -6.917347e-001,
- 2.154887e-001,
- -8.760264e-001,
- 2.334121e-001,
- -1.909621e-002,
- 4.748033e-001,
- -1.138514e-001,
- 6.515360e+000,
- 1.225097e+000,
- -1.293189e+000,
- -4.218700e-001,
- 1.620952e+000,
- -7.858597e-001,
- -3.769410e-002,
- 6.636786e-001,
- 3.364945e-001,
- -5.341017e-001,
- 2.128347e-001,
- -9.735521e-001,
- -1.325495e-001,
- 1.007517e+000,
- 2.598258e-001,
- 6.762169e-002,
- 1.421018e-003,
- -6.915987e-002,
- 3.185897e+000,
- 8.641956e-001,
- -1.094800e+000,
- -1.962062e-001,
- 5.755591e-001,
- 2.906259e-001,
- 2.625748e-001,
- 7.644049e-001,
- 1.347492e-001,
- 2.677126e+000,
- 6.465460e-001,
- // albedo 1, turbidity 5
- -1.393063e+000,
- -5.578338e-001,
- -4.185249e+001,
- 4.233504e+001,
- -5.435640e-003,
- 4.743765e-001,
- 7.422477e-003,
- 2.442801e+000,
- 5.211707e-001,
- -1.939487e+000,
- -1.128509e+000,
- -8.974257e+000,
- 9.978383e+000,
- -7.965597e-003,
- 2.948830e-001,
- 4.436763e-002,
- 2.839868e-001,
- 3.440424e-001,
- -6.011562e-001,
- 2.354877e-001,
- -3.079820e+000,
- 2.585094e+000,
- -2.002701e-002,
- 7.793909e-001,
- -1.598414e-001,
- 5.834678e+000,
- 1.202856e+000,
- -1.315676e+000,
- -3.903446e-001,
- 1.701900e+000,
- -1.304609e+000,
- -1.045121e-002,
- 2.747707e-001,
- 4.143967e-001,
- 3.197102e-001,
- 2.637580e-001,
- -9.618628e-001,
- -1.625841e-001,
- 1.187138e+000,
- 1.497802e-001,
- -5.590954e-006,
- 3.178475e-002,
- -4.153145e-002,
- 2.496096e+000,
- 8.195082e-001,
- -1.111554e+000,
- -2.365546e-001,
- 7.831875e-001,
- 2.018684e-001,
- 2.074369e-001,
- 7.395978e-001,
- 1.225730e-001,
- 1.876478e+000,
- 6.821167e-001,
- // albedo 1, turbidity 6
- -1.427879e+000,
- -5.994879e-001,
- -3.531016e+001,
- 3.581581e+001,
- -6.431497e-003,
- 4.554192e-001,
- 7.348731e-004,
- 2.334619e+000,
- 5.233377e-001,
- -1.998177e+000,
- -1.206633e+000,
- -2.146510e+001,
- 2.242237e+001,
- -5.857596e-003,
- 2.755663e-001,
- 6.384795e-002,
- 1.358244e-001,
- 3.328437e-001,
- -6.440630e-001,
- 2.058571e-001,
- 2.155499e+000,
- -2.587968e+000,
- -1.840023e-002,
- 8.826555e-001,
- -2.222452e-001,
- 5.847073e+000,
- 1.228387e+000,
- -1.229071e+000,
- -3.360441e-001,
- -3.429599e-001,
- 6.179469e-001,
- 2.029610e-003,
- 8.899319e-002,
- 5.041624e-001,
- 1.882964e-001,
- 2.252040e-001,
- -1.022905e+000,
- -2.101621e-001,
- 1.915689e+000,
- -6.498794e-001,
- -3.463651e-002,
- 8.954605e-002,
- -6.797854e-002,
- 2.417705e+000,
- 8.568618e-001,
- -1.082538e+000,
- -2.007723e-001,
- 4.731009e-001,
- 4.077267e-001,
- 1.324289e-001,
- 6.514880e-001,
- 1.702912e-001,
- 2.309383e+000,
- 6.600895e-001,
- // albedo 1, turbidity 7
- -1.472139e+000,
- -6.499815e-001,
- -3.428465e+001,
- 3.469659e+001,
- -5.747023e-003,
- 4.174167e-001,
- 1.688597e-003,
- 2.323046e+000,
- 5.395191e-001,
- -2.161176e+000,
- -1.353089e+000,
- -2.226827e+001,
- 2.329138e+001,
- -5.583808e-003,
- 2.364793e-001,
- 6.096656e-002,
- 1.944666e-003,
- 2.861624e-001,
- -6.593044e-001,
- 1.393558e-001,
- 4.698373e+000,
- -5.193883e+000,
- -1.998390e-002,
- 1.095635e+000,
- -2.391254e-001,
- 5.598103e+000,
- 1.236193e+000,
- -1.195717e+000,
- -2.972715e-001,
- 4.648953e-002,
- 3.024588e-001,
- 5.003313e-003,
- -3.754741e-001,
- 5.247265e-001,
- -1.381312e-001,
- 2.493896e-001,
- -1.020139e+000,
- -2.253524e-001,
- 3.548437e-001,
- 7.030485e-001,
- -2.107076e-002,
- 4.581395e-001,
- -3.243757e-002,
- 2.453259e+000,
- 8.323623e-001,
- -1.098770e+000,
- -2.435780e-001,
- 8.761614e-001,
- 1.941613e-001,
- -1.990692e-001,
- 3.761139e-001,
- 1.657412e-001,
- 1.590503e+000,
- 6.741417e-001,
- // albedo 1, turbidity 8
- -1.648007e+000,
- -8.205121e-001,
- -4.435106e+001,
- 4.479801e+001,
- -4.181353e-003,
- 3.854830e-001,
- -1.842385e-006,
- 2.000281e+000,
- 5.518363e-001,
- -2.140986e+000,
- -1.282239e+000,
- -3.979213e+000,
- 4.672459e+000,
- -5.008582e-003,
- 2.421920e-001,
- 6.253602e-002,
- 6.612713e-001,
- 2.555851e-001,
- -1.300502e+000,
- -5.137898e-001,
- 5.179821e-001,
- -4.032341e-001,
- -2.066785e-002,
- 1.087929e+000,
- -2.615309e-001,
- 4.225887e+000,
- 1.229237e+000,
- -6.963340e-001,
- 9.241060e-002,
- 6.936356e-002,
- -3.588571e-001,
- -5.461843e-002,
- -5.616643e-001,
- 5.484166e-001,
- -4.776267e-002,
- 2.414935e-001,
- -1.233179e+000,
- -4.325498e-001,
- 6.479813e-001,
- 8.368356e-001,
- 2.458875e-001,
- 6.464752e-001,
- -2.897097e-002,
- 1.561773e+000,
- 8.518598e-001,
- -1.051023e+000,
- -2.533690e-001,
- 1.004294e+000,
- 3.028083e-001,
- -1.520108e+000,
- 1.607013e-001,
- 1.619975e-001,
- 1.131094e+000,
- 6.706655e-001,
- // albedo 1, turbidity 9
- -1.948249e+000,
- -1.097383e+000,
- -4.453697e+001,
- 4.494902e+001,
- -3.579939e-003,
- 3.491605e-001,
- -2.500253e-006,
- 1.740442e+000,
- 6.188022e-001,
- -2.154253e+000,
- -1.209559e+000,
- 4.144894e+000,
- -3.562411e+000,
- -5.638843e-003,
- 1.067169e-001,
- 7.594858e-002,
- 1.005280e+000,
- 1.072543e-001,
- -2.513259e+000,
- -1.507208e+000,
- -1.602979e+000,
- 1.404154e+000,
- -5.560750e-003,
- 1.240490e+000,
- -2.852117e-001,
- 3.485252e+000,
- 1.349321e+000,
- -7.832214e-002,
- 3.655626e-001,
- 3.856288e-001,
- 6.867894e-001,
- -1.609523e-001,
- -6.704306e-001,
- 5.357301e-001,
- -6.457935e-001,
- 1.479503e-001,
- -1.354784e+000,
- -5.454375e-001,
- 8.797469e-001,
- -1.466514e+000,
- 7.134420e-001,
- 5.934903e-001,
- -2.911178e-002,
- 8.643737e-001,
- 9.030724e-001,
- -1.048324e+000,
- -2.738736e-001,
- 8.783074e-001,
- 3.246188e+000,
- -4.435369e+000,
- 1.251791e-001,
- 1.783486e-001,
- 1.064657e+000,
- 6.522878e-001,
- // albedo 1, turbidity 10
- -2.770408e+000,
- -1.618911e+000,
- -2.504031e+001,
- 2.531674e+001,
- -4.239279e-003,
- 3.241013e-001,
- -3.764484e-006,
- 1.586843e+000,
- 7.035906e-001,
- -1.913500e+000,
- -1.144014e+000,
- -1.080587e+001,
- 1.153677e+001,
- -1.003197e-002,
- 1.577515e-001,
- 5.217789e-002,
- 1.225278e+000,
- 5.172771e-003,
- -5.293208e+000,
- -2.876463e+000,
- 2.087053e+000,
- -3.201552e+000,
- 3.892964e-003,
- 5.323930e-001,
- -2.034512e-001,
- 2.617760e+000,
- 1.273597e+000,
- 9.060340e-001,
- 3.773409e-001,
- -6.399945e-001,
- 3.213979e+000,
- -9.112172e-002,
- 6.494055e-001,
- 3.953280e-001,
- 5.047796e-001,
- 2.998695e-001,
- -1.482179e+000,
- -6.778310e-001,
- 1.161775e+000,
- -3.004872e+000,
- 4.774797e-001,
- -4.969248e-001,
- -3.512074e-003,
- -1.307190e+000,
- 7.927378e-001,
- -9.863181e-001,
- -1.803364e-001,
- 5.810824e-001,
- 4.580570e+000,
- -3.863454e+000,
- 5.328174e-001,
- 2.272821e-001,
- 1.771114e+000,
- 6.791814e-001,
+static const double datasetXYZ3[] = {
+ // albedo 0, turbidity 1
+ -1.310023e+000,
+ -4.407658e-001,
+ -3.640340e+001,
+ 3.683292e+001,
+ -8.124762e-003,
+ 5.297961e-001,
+ 1.188633e-002,
+ 3.138320e+000,
+ 5.134778e-001,
+ -1.424100e+000,
+ -5.501606e-001,
+ -1.753510e+001,
+ 1.822769e+001,
+ -1.539272e-002,
+ 6.366826e-001,
+ 2.661996e-003,
+ 2.659915e+000,
+ 4.071138e-001,
+ -1.103436e+000,
+ -1.884105e-001,
+ 6.425322e+000,
+ -6.910579e+000,
+ -2.019861e-002,
+ 3.553271e-001,
+ -1.589061e-002,
+ 5.345985e+000,
+ 8.790218e-001,
+ -1.186200e+000,
+ -4.307514e-001,
+ -3.957947e+000,
+ 5.979352e+000,
+ -5.348869e-002,
+ 1.736117e+000,
+ 3.491346e-002,
+ -2.692261e+000,
+ 5.610506e-001,
+ -1.006038e+000,
+ -1.305995e-001,
+ 4.473513e+000,
+ -3.806719e+000,
+ 1.419407e-001,
+ -2.148238e-002,
+ -5.081185e-002,
+ 3.735362e+000,
+ 5.358280e-001,
+ -1.078507e+000,
+ -1.633754e-001,
+ -3.812368e+000,
+ 4.381700e+000,
+ 2.988122e-002,
+ 1.754224e+000,
+ 1.472376e-001,
+ 3.722798e+000,
+ 4.999157e-001,
+ // albedo 0, turbidity 2
+ -1.333582e+000,
+ -4.649908e-001,
+ -3.359528e+001,
+ 3.404375e+001,
+ -9.384242e-003,
+ 5.587511e-001,
+ 5.726310e-003,
+ 3.073145e+000,
+ 5.425529e-001,
+ -1.562624e+000,
+ -7.107068e-001,
+ -1.478170e+001,
+ 1.559839e+001,
+ -1.462375e-002,
+ 5.050133e-001,
+ 2.516017e-002,
+ 1.604696e+000,
+ 2.902403e-001,
+ -8.930158e-001,
+ 4.068077e-002,
+ 1.373481e+000,
+ -2.342752e+000,
+ -2.098058e-002,
+ 6.248686e-001,
+ -5.258363e-002,
+ 7.058214e+000,
+ 1.150373e+000,
+ -1.262823e+000,
+ -4.818353e-001,
+ 8.892610e-004,
+ 1.923120e+000,
+ -4.979718e-002,
+ 1.040693e+000,
+ 1.558103e-001,
+ -2.852480e+000,
+ 2.420691e-001,
+ -9.968383e-001,
+ -1.200648e-001,
+ 1.324342e+000,
+ -9.430889e-001,
+ 1.931098e-001,
+ 4.436916e-001,
+ -7.320456e-002,
+ 4.215931e+000,
+ 7.898019e-001,
+ -1.078185e+000,
+ -1.718192e-001,
+ -1.720191e+000,
+ 2.358918e+000,
+ 2.765637e-002,
+ 1.260245e+000,
+ 2.021941e-001,
+ 3.395483e+000,
+ 5.173628e-001,
+ // albedo 0, turbidity 3
+ -1.353023e+000,
+ -4.813523e-001,
+ -3.104920e+001,
+ 3.140156e+001,
+ -9.510741e-003,
+ 5.542030e-001,
+ 8.135471e-003,
+ 3.136646e+000,
+ 5.215989e-001,
+ -1.624704e+000,
+ -7.990201e-001,
+ -2.167125e+001,
+ 2.246341e+001,
+ -1.163533e-002,
+ 5.415746e-001,
+ 2.618378e-002,
+ 1.139214e+000,
+ 3.444357e-001,
+ -7.983610e-001,
+ 1.417476e-001,
+ 9.914841e+000,
+ -1.081503e+001,
+ -1.218845e-002,
+ 3.411392e-001,
+ -6.137698e-002,
+ 7.445848e+000,
+ 1.180080e+000,
+ -1.266679e+000,
+ -4.288977e-001,
+ -5.818701e+000,
+ 6.986437e+000,
+ -8.180711e-002,
+ 1.397403e+000,
+ 2.016916e-001,
+ -1.275731e+000,
+ 2.592773e-001,
+ -1.009707e+000,
+ -1.537754e-001,
+ 3.496378e+000,
+ -3.013726e+000,
+ 2.421150e-001,
+ -2.831925e-001,
+ 3.003395e-002,
+ 3.702862e+000,
+ 7.746320e-001,
+ -1.075646e+000,
+ -1.768747e-001,
+ -1.347762e+000,
+ 1.989004e+000,
+ 1.375836e-002,
+ 1.764810e+000,
+ 1.330018e-001,
+ 3.230864e+000,
+ 6.626210e-001,
+ // albedo 0, turbidity 4
+ -1.375269e+000,
+ -5.103569e-001,
+ -3.442661e+001,
+ 3.478703e+001,
+ -8.460009e-003,
+ 5.408643e-001,
+ 4.813323e-003,
+ 3.016078e+000,
+ 5.062069e-001,
+ -1.821679e+000,
+ -9.766461e-001,
+ -1.926488e+001,
+ 1.997912e+001,
+ -9.822567e-003,
+ 3.649556e-001,
+ 4.316092e-002,
+ 8.930190e-001,
+ 4.166527e-001,
+ -6.633542e-001,
+ 1.997841e-001,
+ 2.395592e+000,
+ -3.117175e+000,
+ -1.080884e-002,
+ 8.983814e-001,
+ -1.375825e-001,
+ 6.673463e+000,
+ 1.115663e+000,
+ -1.303240e+000,
+ -3.612712e-001,
+ 8.292959e-002,
+ 3.381364e-001,
+ -6.078648e-002,
+ 3.229247e-001,
+ 3.680987e-001,
+ 7.046755e-001,
+ 3.144924e-001,
+ -9.952598e-001,
+ -2.039076e-001,
+ 4.026851e-001,
+ 2.686684e-001,
+ 1.640712e-001,
+ 5.186341e-001,
+ -1.205520e-002,
+ 2.659613e+000,
+ 8.030394e-001,
+ -1.098579e+000,
+ -2.151992e-001,
+ 6.558198e-001,
+ -7.436900e-004,
+ -1.421817e-003,
+ 1.073701e+000,
+ 1.886875e-001,
+ 2.536857e+000,
+ 6.673923e-001,
+ // albedo 0, turbidity 5
+ -1.457986e+000,
+ -5.906842e-001,
+ -3.812464e+001,
+ 3.838539e+001,
+ -6.024357e-003,
+ 4.741484e-001,
+ 1.209223e-002,
+ 2.818432e+000,
+ 5.012433e-001,
+ -1.835728e+000,
+ -1.003405e+000,
+ -6.848129e+000,
+ 7.601943e+000,
+ -1.277375e-002,
+ 4.785598e-001,
+ 3.366853e-002,
+ 1.097701e+000,
+ 4.636635e-001,
+ -8.491348e-001,
+ 9.466365e-003,
+ -2.685226e+000,
+ 2.004060e+000,
+ -1.168708e-002,
+ 6.752316e-001,
+ -1.543371e-001,
+ 5.674759e+000,
+ 1.039534e+000,
+ -1.083379e+000,
+ -1.506790e-001,
+ 7.328236e-001,
+ -5.095568e-001,
+ -8.609153e-002,
+ 4.448820e-001,
+ 4.174662e-001,
+ 1.481556e+000,
+ 3.942551e-001,
+ -1.117089e+000,
+ -3.337605e-001,
+ 2.502281e-001,
+ 4.036323e-001,
+ 2.673899e-001,
+ 2.829817e-001,
+ 2.242450e-002,
+ 2.043207e+000,
+ 7.706902e-001,
+ -1.071648e+000,
+ -2.126200e-001,
+ 6.069466e-001,
+ -1.456290e-003,
+ -5.515960e-001,
+ 1.046755e+000,
+ 1.985021e-001,
+ 2.290245e+000,
+ 6.876058e-001,
+ // albedo 0, turbidity 6
+ -1.483903e+000,
+ -6.309647e-001,
+ -4.380213e+001,
+ 4.410537e+001,
+ -5.712161e-003,
+ 5.195992e-001,
+ 2.028428e-003,
+ 2.687114e+000,
+ 5.098321e-001,
+ -2.053976e+000,
+ -1.141473e+000,
+ 5.109183e-001,
+ 8.060391e-002,
+ -1.033983e-002,
+ 4.066532e-001,
+ 4.869627e-002,
+ 1.161722e+000,
+ 4.039525e-001,
+ -6.348185e-001,
+ 7.651292e-002,
+ -1.031327e+001,
+ 1.007598e+001,
+ -2.083688e-002,
+ 7.359516e-001,
+ -2.029459e-001,
+ 5.013257e+000,
+ 1.077649e+000,
+ -1.228630e+000,
+ -1.650496e-001,
+ 4.077157e-002,
+ -7.189167e-001,
+ -5.092220e-002,
+ 2.959814e-001,
+ 5.111496e-001,
+ 2.540433e+000,
+ 3.615330e-001,
+ -1.041883e+000,
+ -3.278413e-001,
+ -6.691911e-002,
+ 1.307364e+000,
+ 2.166663e-001,
+ 3.000595e-001,
+ -3.157136e-003,
+ 1.389208e+000,
+ 7.999026e-001,
+ -1.103556e+000,
+ -2.443602e-001,
+ 4.705347e-001,
+ -9.296482e-004,
+ -5.309920e-001,
+ 9.654511e-001,
+ 2.142587e-001,
+ 2.244723e+000,
+ 6.839976e-001,
+ // albedo 0, turbidity 7
+ -1.555684e+000,
+ -6.962113e-001,
+ -4.647983e+001,
+ 4.674270e+001,
+ -5.034895e-003,
+ 4.755090e-001,
+ -9.502561e-007,
+ 2.626569e+000,
+ 5.056194e-001,
+ -1.998288e+000,
+ -1.124720e+000,
+ -1.629586e+000,
+ 2.187993e+000,
+ -8.284384e-003,
+ 3.845258e-001,
+ 5.726240e-002,
+ 1.185644e+000,
+ 4.255812e-001,
+ -1.032570e+000,
+ -2.513850e-001,
+ -3.721112e+000,
+ 3.506967e+000,
+ -2.186561e-002,
+ 9.436049e-001,
+ -2.451412e-001,
+ 4.725724e+000,
+ 1.039256e+000,
+ -8.597532e-001,
+ 9.073332e-002,
+ -2.553741e+000,
+ 1.993237e+000,
+ -4.390891e-002,
+ -2.046928e-001,
+ 5.515623e-001,
+ 1.909127e+000,
+ 3.948212e-001,
+ -1.210482e+000,
+ -4.477622e-001,
+ -2.267805e-001,
+ 1.219488e+000,
+ 1.336186e-001,
+ 6.866897e-001,
+ 2.808997e-002,
+ 1.600403e+000,
+ 7.816409e-001,
+ -1.078168e+000,
+ -2.699261e-001,
+ 2.537282e-001,
+ 3.820684e-001,
+ -4.425103e-001,
+ 5.298235e-001,
+ 2.185217e-001,
+ 1.728679e+000,
+ 6.882743e-001,
+ // albedo 0, turbidity 8
+ -1.697968e+000,
+ -8.391488e-001,
+ -5.790105e+001,
+ 5.814120e+001,
+ -3.404760e-003,
+ 4.265140e-001,
+ -1.796301e-006,
+ 2.368442e+000,
+ 5.324429e-001,
+ -2.141552e+000,
+ -1.172230e+000,
+ 1.677872e+001,
+ -1.641470e+001,
+ -5.732425e-003,
+ 2.002199e-001,
+ 6.841834e-002,
+ 1.485338e+000,
+ 3.215763e-001,
+ -1.442946e+000,
+ -7.264245e-001,
+ -9.503706e+000,
+ 9.650462e+000,
+ -2.120995e-002,
+ 1.419263e+000,
+ -2.893098e-001,
+ 3.860731e+000,
+ 1.120857e+000,
+ -5.696752e-001,
+ 3.411279e-001,
+ -2.931035e-001,
+ -6.512552e-001,
+ -1.068437e-001,
+ -1.085661e+000,
+ 6.107549e-001,
+ 1.459503e+000,
+ 3.210336e-001,
+ -1.313839e+000,
+ -5.921371e-001,
+ -2.332222e-001,
+ 1.648196e+000,
+ 2.492787e-001,
+ 1.381033e+000,
+ -1.993392e-002,
+ 9.812560e-001,
+ 8.316329e-001,
+ -1.087464e+000,
+ -3.195534e-001,
+ 2.902095e-001,
+ 3.383709e-001,
+ -8.798482e-001,
+ 1.494668e-002,
+ 2.529703e-001,
+ 1.452644e+000,
+ 6.693870e-001,
+ // albedo 0, turbidity 9
+ -2.068582e+000,
+ -1.118605e+000,
+ -5.081598e+001,
+ 5.097486e+001,
+ -3.280669e-003,
+ 4.067371e-001,
+ -2.544951e-006,
+ 2.179497e+000,
+ 5.778017e-001,
+ -1.744693e+000,
+ -8.537207e-001,
+ 2.234361e+001,
+ -2.208318e+001,
+ -5.932616e-003,
+ 1.035049e-001,
+ 5.742772e-002,
+ 1.977880e+000,
+ 2.124846e-001,
+ -3.287515e+000,
+ -2.140268e+000,
+ -1.249566e+001,
+ 1.240091e+001,
+ -2.409349e-002,
+ 1.397821e+000,
+ -2.371627e-001,
+ 2.771192e+000,
+ 1.170496e+000,
+ 5.502311e-001,
+ 1.046630e+000,
+ 2.193517e+000,
+ -2.220400e+000,
+ -1.064394e-001,
+ -1.017926e+000,
+ 4.795457e-001,
+ 1.030644e+000,
+ 3.177516e-001,
+ -1.719734e+000,
+ -9.536198e-001,
+ -6.586821e-001,
+ 1.386361e+000,
+ -2.513065e-002,
+ 1.187011e+000,
+ 6.542539e-002,
+ 5.296055e-001,
+ 8.082660e-001,
+ -1.005700e+000,
+ -3.028096e-001,
+ 4.470957e-002,
+ 1.007760e+000,
+ -8.119016e-001,
+ 3.153338e-002,
+ 2.311321e-001,
+ 1.182208e+000,
+ 6.824758e-001,
+ // albedo 0, turbidity 10
+ -2.728867e+000,
+ -1.580388e+000,
+ -3.079627e+001,
+ 3.092586e+001,
+ -4.197673e-003,
+ 3.154759e-001,
+ -3.897675e-006,
+ 1.920567e+000,
+ 6.664791e-001,
+ -1.322495e+000,
+ -7.249275e-001,
+ 1.477660e+001,
+ -1.468154e+001,
+ -9.044857e-003,
+ 5.624314e-002,
+ 6.498392e-002,
+ 2.047389e+000,
+ 6.367540e-002,
+ -6.102376e+000,
+ -3.473018e+000,
+ -9.926071e+000,
+ 9.637797e+000,
+ -1.097909e-002,
+ 1.103498e+000,
+ -2.424521e-001,
+ 2.520748e+000,
+ 1.240260e+000,
+ 1.351796e+000,
+ 1.018588e+000,
+ 2.009081e+000,
+ -1.333394e+000,
+ -1.979125e-001,
+ -3.318292e-001,
+ 4.476624e-001,
+ 9.095235e-001,
+ 2.955611e-001,
+ -1.774467e+000,
+ -1.079880e+000,
+ -8.084680e-002,
+ 2.577697e-001,
+ -1.149295e-001,
+ 4.975303e-001,
+ 2.931611e-003,
+ -3.803171e-001,
+ 8.002794e-001,
+ -9.898401e-001,
+ -2.542513e-001,
+ -7.530911e-002,
+ 1.870355e+000,
+ -1.521918e+000,
+ 2.405164e-001,
+ 2.964615e-001,
+ 1.334800e+000,
+ 6.789053e-001,
+ // albedo 1, turbidity 1
+ -1.279730e+000,
+ -4.290674e-001,
+ -4.277972e+001,
+ 4.343305e+001,
+ -6.541826e-003,
+ 4.945086e-001,
+ 1.425338e-002,
+ 2.685244e+000,
+ 5.011313e-001,
+ -1.449506e+000,
+ -5.766374e-001,
+ -1.688496e+001,
+ 1.781118e+001,
+ -1.121649e-002,
+ 3.545020e-001,
+ 2.287338e-002,
+ 1.904281e+000,
+ 4.936998e-001,
+ -1.021980e+000,
+ -1.897574e-001,
+ 2.482462e+000,
+ -2.941725e+000,
+ -1.570448e-002,
+ 7.532578e-001,
+ -4.256800e-002,
+ 5.239660e+000,
+ 4.983116e-001,
+ -1.162608e+000,
+ -3.428049e-001,
+ 3.974358e+000,
+ -1.527935e+000,
+ -3.919201e-002,
+ 8.758593e-001,
+ 7.291363e-002,
+ -3.455257e+000,
+ 8.007426e-001,
+ -9.929985e-001,
+ -8.712006e-002,
+ -7.397313e-001,
+ 1.348372e+000,
+ 9.511685e-002,
+ 3.233584e-001,
+ -7.549148e-002,
+ 5.806452e+000,
+ 4.990042e-001,
+ -1.084996e+000,
+ -1.739767e-001,
+ 1.580475e-001,
+ 9.088180e-001,
+ 6.871433e-002,
+ 5.933079e-001,
+ 1.188921e-001,
+ 3.074079e+000,
+ 4.999327e-001,
+ // albedo 1, turbidity 2
+ -1.317009e+000,
+ -4.661946e-001,
+ -4.255347e+001,
+ 4.312782e+001,
+ -5.727235e-003,
+ 4.285447e-001,
+ 2.189854e-002,
+ 2.608310e+000,
+ 5.190700e-001,
+ -1.469236e+000,
+ -6.282139e-001,
+ -1.241404e+001,
+ 1.348765e+001,
+ -1.204770e-002,
+ 5.070285e-001,
+ -7.280216e-004,
+ 1.491533e+000,
+ 3.635064e-001,
+ -9.713808e-001,
+ -8.138038e-002,
+ 3.709854e-001,
+ -1.041174e+000,
+ -1.814075e-002,
+ 5.060860e-001,
+ -2.053756e-002,
+ 6.161431e+000,
+ 1.093736e+000,
+ -1.159057e+000,
+ -3.698074e-001,
+ 2.711209e+000,
+ -6.006479e-001,
+ -4.896926e-002,
+ 9.273957e-001,
+ 1.137712e-001,
+ -3.496828e+000,
+ 2.867109e-001,
+ -1.011601e+000,
+ -8.201890e-002,
+ 2.105725e-001,
+ 4.597520e-001,
+ 1.478925e-001,
+ 2.138940e-001,
+ -5.660670e-002,
+ 6.057755e+000,
+ 7.859121e-001,
+ -1.078020e+000,
+ -1.811580e-001,
+ 1.646622e-001,
+ 8.348426e-001,
+ 1.149064e-001,
+ 4.985738e-001,
+ 1.376605e-001,
+ 2.746607e+000,
+ 4.999626e-001,
+ // albedo 1, turbidity 3
+ -1.325672e+000,
+ -4.769313e-001,
+ -4.111215e+001,
+ 4.168293e+001,
+ -6.274997e-003,
+ 4.649469e-001,
+ 1.119411e-002,
+ 2.631267e+000,
+ 5.234546e-001,
+ -1.619391e+000,
+ -8.000253e-001,
+ -1.534098e+001,
+ 1.632706e+001,
+ -1.012023e-002,
+ 4.242255e-001,
+ 2.931597e-002,
+ 8.925807e-001,
+ 3.314765e-001,
+ -7.356979e-001,
+ 1.368406e-001,
+ 2.972579e+000,
+ -3.535359e+000,
+ -1.318948e-002,
+ 4.607620e-001,
+ -7.182778e-002,
+ 6.254100e+000,
+ 1.236299e+000,
+ -1.316217e+000,
+ -4.194427e-001,
+ 3.489902e-002,
+ 1.289849e+000,
+ -4.755960e-002,
+ 1.138222e+000,
+ 1.975992e-001,
+ -8.991542e-001,
+ 2.290572e-001,
+ -9.502188e-001,
+ -1.172703e-001,
+ 1.405202e+000,
+ -3.061919e-001,
+ 1.058772e-001,
+ -3.760592e-001,
+ -1.983179e-002,
+ 3.562353e+000,
+ 7.895959e-001,
+ -1.100117e+000,
+ -1.900567e-001,
+ 4.925030e-001,
+ 5.250225e-001,
+ 1.576804e-001,
+ 1.042701e+000,
+ 7.330743e-002,
+ 2.796064e+000,
+ 6.749783e-001,
+ // albedo 1, turbidity 4
+ -1.354183e+000,
+ -5.130625e-001,
+ -4.219268e+001,
+ 4.271772e+001,
+ -5.365373e-003,
+ 4.136743e-001,
+ 1.235172e-002,
+ 2.520122e+000,
+ 5.187269e-001,
+ -1.741434e+000,
+ -9.589761e-001,
+ -8.230339e+000,
+ 9.296799e+000,
+ -9.600162e-003,
+ 4.994969e-001,
+ 2.955452e-002,
+ 3.667099e-001,
+ 3.526999e-001,
+ -6.917347e-001,
+ 2.154887e-001,
+ -8.760264e-001,
+ 2.334121e-001,
+ -1.909621e-002,
+ 4.748033e-001,
+ -1.138514e-001,
+ 6.515360e+000,
+ 1.225097e+000,
+ -1.293189e+000,
+ -4.218700e-001,
+ 1.620952e+000,
+ -7.858597e-001,
+ -3.769410e-002,
+ 6.636786e-001,
+ 3.364945e-001,
+ -5.341017e-001,
+ 2.128347e-001,
+ -9.735521e-001,
+ -1.325495e-001,
+ 1.007517e+000,
+ 2.598258e-001,
+ 6.762169e-002,
+ 1.421018e-003,
+ -6.915987e-002,
+ 3.185897e+000,
+ 8.641956e-001,
+ -1.094800e+000,
+ -1.962062e-001,
+ 5.755591e-001,
+ 2.906259e-001,
+ 2.625748e-001,
+ 7.644049e-001,
+ 1.347492e-001,
+ 2.677126e+000,
+ 6.465460e-001,
+ // albedo 1, turbidity 5
+ -1.393063e+000,
+ -5.578338e-001,
+ -4.185249e+001,
+ 4.233504e+001,
+ -5.435640e-003,
+ 4.743765e-001,
+ 7.422477e-003,
+ 2.442801e+000,
+ 5.211707e-001,
+ -1.939487e+000,
+ -1.128509e+000,
+ -8.974257e+000,
+ 9.978383e+000,
+ -7.965597e-003,
+ 2.948830e-001,
+ 4.436763e-002,
+ 2.839868e-001,
+ 3.440424e-001,
+ -6.011562e-001,
+ 2.354877e-001,
+ -3.079820e+000,
+ 2.585094e+000,
+ -2.002701e-002,
+ 7.793909e-001,
+ -1.598414e-001,
+ 5.834678e+000,
+ 1.202856e+000,
+ -1.315676e+000,
+ -3.903446e-001,
+ 1.701900e+000,
+ -1.304609e+000,
+ -1.045121e-002,
+ 2.747707e-001,
+ 4.143967e-001,
+ 3.197102e-001,
+ 2.637580e-001,
+ -9.618628e-001,
+ -1.625841e-001,
+ 1.187138e+000,
+ 1.497802e-001,
+ -5.590954e-006,
+ 3.178475e-002,
+ -4.153145e-002,
+ 2.496096e+000,
+ 8.195082e-001,
+ -1.111554e+000,
+ -2.365546e-001,
+ 7.831875e-001,
+ 2.018684e-001,
+ 2.074369e-001,
+ 7.395978e-001,
+ 1.225730e-001,
+ 1.876478e+000,
+ 6.821167e-001,
+ // albedo 1, turbidity 6
+ -1.427879e+000,
+ -5.994879e-001,
+ -3.531016e+001,
+ 3.581581e+001,
+ -6.431497e-003,
+ 4.554192e-001,
+ 7.348731e-004,
+ 2.334619e+000,
+ 5.233377e-001,
+ -1.998177e+000,
+ -1.206633e+000,
+ -2.146510e+001,
+ 2.242237e+001,
+ -5.857596e-003,
+ 2.755663e-001,
+ 6.384795e-002,
+ 1.358244e-001,
+ 3.328437e-001,
+ -6.440630e-001,
+ 2.058571e-001,
+ 2.155499e+000,
+ -2.587968e+000,
+ -1.840023e-002,
+ 8.826555e-001,
+ -2.222452e-001,
+ 5.847073e+000,
+ 1.228387e+000,
+ -1.229071e+000,
+ -3.360441e-001,
+ -3.429599e-001,
+ 6.179469e-001,
+ 2.029610e-003,
+ 8.899319e-002,
+ 5.041624e-001,
+ 1.882964e-001,
+ 2.252040e-001,
+ -1.022905e+000,
+ -2.101621e-001,
+ 1.915689e+000,
+ -6.498794e-001,
+ -3.463651e-002,
+ 8.954605e-002,
+ -6.797854e-002,
+ 2.417705e+000,
+ 8.568618e-001,
+ -1.082538e+000,
+ -2.007723e-001,
+ 4.731009e-001,
+ 4.077267e-001,
+ 1.324289e-001,
+ 6.514880e-001,
+ 1.702912e-001,
+ 2.309383e+000,
+ 6.600895e-001,
+ // albedo 1, turbidity 7
+ -1.472139e+000,
+ -6.499815e-001,
+ -3.428465e+001,
+ 3.469659e+001,
+ -5.747023e-003,
+ 4.174167e-001,
+ 1.688597e-003,
+ 2.323046e+000,
+ 5.395191e-001,
+ -2.161176e+000,
+ -1.353089e+000,
+ -2.226827e+001,
+ 2.329138e+001,
+ -5.583808e-003,
+ 2.364793e-001,
+ 6.096656e-002,
+ 1.944666e-003,
+ 2.861624e-001,
+ -6.593044e-001,
+ 1.393558e-001,
+ 4.698373e+000,
+ -5.193883e+000,
+ -1.998390e-002,
+ 1.095635e+000,
+ -2.391254e-001,
+ 5.598103e+000,
+ 1.236193e+000,
+ -1.195717e+000,
+ -2.972715e-001,
+ 4.648953e-002,
+ 3.024588e-001,
+ 5.003313e-003,
+ -3.754741e-001,
+ 5.247265e-001,
+ -1.381312e-001,
+ 2.493896e-001,
+ -1.020139e+000,
+ -2.253524e-001,
+ 3.548437e-001,
+ 7.030485e-001,
+ -2.107076e-002,
+ 4.581395e-001,
+ -3.243757e-002,
+ 2.453259e+000,
+ 8.323623e-001,
+ -1.098770e+000,
+ -2.435780e-001,
+ 8.761614e-001,
+ 1.941613e-001,
+ -1.990692e-001,
+ 3.761139e-001,
+ 1.657412e-001,
+ 1.590503e+000,
+ 6.741417e-001,
+ // albedo 1, turbidity 8
+ -1.648007e+000,
+ -8.205121e-001,
+ -4.435106e+001,
+ 4.479801e+001,
+ -4.181353e-003,
+ 3.854830e-001,
+ -1.842385e-006,
+ 2.000281e+000,
+ 5.518363e-001,
+ -2.140986e+000,
+ -1.282239e+000,
+ -3.979213e+000,
+ 4.672459e+000,
+ -5.008582e-003,
+ 2.421920e-001,
+ 6.253602e-002,
+ 6.612713e-001,
+ 2.555851e-001,
+ -1.300502e+000,
+ -5.137898e-001,
+ 5.179821e-001,
+ -4.032341e-001,
+ -2.066785e-002,
+ 1.087929e+000,
+ -2.615309e-001,
+ 4.225887e+000,
+ 1.229237e+000,
+ -6.963340e-001,
+ 9.241060e-002,
+ 6.936356e-002,
+ -3.588571e-001,
+ -5.461843e-002,
+ -5.616643e-001,
+ 5.484166e-001,
+ -4.776267e-002,
+ 2.414935e-001,
+ -1.233179e+000,
+ -4.325498e-001,
+ 6.479813e-001,
+ 8.368356e-001,
+ 2.458875e-001,
+ 6.464752e-001,
+ -2.897097e-002,
+ 1.561773e+000,
+ 8.518598e-001,
+ -1.051023e+000,
+ -2.533690e-001,
+ 1.004294e+000,
+ 3.028083e-001,
+ -1.520108e+000,
+ 1.607013e-001,
+ 1.619975e-001,
+ 1.131094e+000,
+ 6.706655e-001,
+ // albedo 1, turbidity 9
+ -1.948249e+000,
+ -1.097383e+000,
+ -4.453697e+001,
+ 4.494902e+001,
+ -3.579939e-003,
+ 3.491605e-001,
+ -2.500253e-006,
+ 1.740442e+000,
+ 6.188022e-001,
+ -2.154253e+000,
+ -1.209559e+000,
+ 4.144894e+000,
+ -3.562411e+000,
+ -5.638843e-003,
+ 1.067169e-001,
+ 7.594858e-002,
+ 1.005280e+000,
+ 1.072543e-001,
+ -2.513259e+000,
+ -1.507208e+000,
+ -1.602979e+000,
+ 1.404154e+000,
+ -5.560750e-003,
+ 1.240490e+000,
+ -2.852117e-001,
+ 3.485252e+000,
+ 1.349321e+000,
+ -7.832214e-002,
+ 3.655626e-001,
+ 3.856288e-001,
+ 6.867894e-001,
+ -1.609523e-001,
+ -6.704306e-001,
+ 5.357301e-001,
+ -6.457935e-001,
+ 1.479503e-001,
+ -1.354784e+000,
+ -5.454375e-001,
+ 8.797469e-001,
+ -1.466514e+000,
+ 7.134420e-001,
+ 5.934903e-001,
+ -2.911178e-002,
+ 8.643737e-001,
+ 9.030724e-001,
+ -1.048324e+000,
+ -2.738736e-001,
+ 8.783074e-001,
+ 3.246188e+000,
+ -4.435369e+000,
+ 1.251791e-001,
+ 1.783486e-001,
+ 1.064657e+000,
+ 6.522878e-001,
+ // albedo 1, turbidity 10
+ -2.770408e+000,
+ -1.618911e+000,
+ -2.504031e+001,
+ 2.531674e+001,
+ -4.239279e-003,
+ 3.241013e-001,
+ -3.764484e-006,
+ 1.586843e+000,
+ 7.035906e-001,
+ -1.913500e+000,
+ -1.144014e+000,
+ -1.080587e+001,
+ 1.153677e+001,
+ -1.003197e-002,
+ 1.577515e-001,
+ 5.217789e-002,
+ 1.225278e+000,
+ 5.172771e-003,
+ -5.293208e+000,
+ -2.876463e+000,
+ 2.087053e+000,
+ -3.201552e+000,
+ 3.892964e-003,
+ 5.323930e-001,
+ -2.034512e-001,
+ 2.617760e+000,
+ 1.273597e+000,
+ 9.060340e-001,
+ 3.773409e-001,
+ -6.399945e-001,
+ 3.213979e+000,
+ -9.112172e-002,
+ 6.494055e-001,
+ 3.953280e-001,
+ 5.047796e-001,
+ 2.998695e-001,
+ -1.482179e+000,
+ -6.778310e-001,
+ 1.161775e+000,
+ -3.004872e+000,
+ 4.774797e-001,
+ -4.969248e-001,
+ -3.512074e-003,
+ -1.307190e+000,
+ 7.927378e-001,
+ -9.863181e-001,
+ -1.803364e-001,
+ 5.810824e-001,
+ 4.580570e+000,
+ -3.863454e+000,
+ 5.328174e-001,
+ 2.272821e-001,
+ 1.771114e+000,
+ 6.791814e-001,
};
-static const double datasetXYZRad3[] =
-{
- // albedo 0, turbidity 1
- 1.168084e+000,
- 2.156455e+000,
- -3.980314e+000,
- 1.989302e+001,
- 1.328335e+001,
- 1.435621e+001,
- // albedo 0, turbidity 2
- 1.135488e+000,
- 2.294701e+000,
- -4.585886e+000,
- 2.090208e+001,
- 1.347840e+001,
- 1.467658e+001,
- // albedo 0, turbidity 3
- 1.107408e+000,
- 2.382765e+000,
- -5.112357e+000,
- 2.147823e+001,
- 1.493128e+001,
- 1.460882e+001,
- // albedo 0, turbidity 4
- 1.054193e+000,
- 2.592891e+000,
- -6.115000e+000,
- 2.268967e+001,
- 1.635672e+001,
- 1.518999e+001,
- // albedo 0, turbidity 5
- 1.006946e+000,
- 2.705420e+000,
- -6.698930e+000,
- 2.291830e+001,
- 1.834324e+001,
- 1.570651e+001,
- // albedo 0, turbidity 6
- 9.794044e-001,
- 2.742440e+000,
- -6.805283e+000,
- 2.225271e+001,
- 2.050797e+001,
- 1.563130e+001,
- // albedo 0, turbidity 7
- 9.413577e-001,
- 2.722009e+000,
- -6.760707e+000,
- 2.098242e+001,
- 2.342588e+001,
- 1.605011e+001,
- // albedo 0, turbidity 8
- 8.917923e-001,
- 2.592780e+000,
- -6.152635e+000,
- 1.774141e+001,
- 2.858324e+001,
- 1.657910e+001,
- // albedo 0, turbidity 9
- 8.288391e-001,
- 2.153434e+000,
- -4.118327e+000,
- 1.078118e+001,
- 3.681710e+001,
- 1.738139e+001,
- // albedo 0, turbidity 10
- 7.623528e-001,
- 1.418187e+000,
- -8.845235e-001,
- 7.590129e-001,
- 4.629859e+001,
- 1.921657e+001,
- // albedo 1, turbidity 1
- 1.352858e+000,
- 2.048862e+000,
- -2.053393e+000,
- 1.405874e+001,
- 3.045344e+001,
- 3.044430e+001,
- // albedo 1, turbidity 2
- 1.330497e+000,
- 2.126497e+000,
- -2.466296e+000,
- 1.467559e+001,
- 3.090738e+001,
- 3.069707e+001,
- // albedo 1, turbidity 3
- 1.286344e+000,
- 2.200436e+000,
- -2.877228e+000,
- 1.492701e+001,
- 3.236288e+001,
- 3.077223e+001,
- // albedo 1, turbidity 4
- 1.234428e+000,
- 2.289628e+000,
- -3.404699e+000,
- 1.499436e+001,
- 3.468390e+001,
- 3.084842e+001,
- // albedo 1, turbidity 5
- 1.178660e+000,
- 2.306071e+000,
- -3.549159e+000,
- 1.411006e+001,
- 3.754188e+001,
- 3.079730e+001,
- // albedo 1, turbidity 6
- 1.151366e+000,
- 2.333005e+000,
- -3.728627e+000,
- 1.363374e+001,
- 3.905894e+001,
- 3.092599e+001,
- // albedo 1, turbidity 7
- 1.101593e+000,
- 2.299422e+000,
- -3.565787e+000,
- 1.196745e+001,
- 4.188472e+001,
- 3.102755e+001,
- // albedo 1, turbidity 8
- 1.038322e+000,
- 2.083539e+000,
- -2.649585e+000,
- 8.037389e+000,
- 4.700869e+001,
- 3.065948e+001,
- // albedo 1, turbidity 9
- 9.596146e-001,
- 1.671470e+000,
- -8.751538e-001,
- 1.679772e+000,
- 5.345784e+001,
- 3.054520e+001,
- // albedo 1, turbidity 10
- 8.640731e-001,
- 9.858301e-001,
- 1.854956e+000,
- -6.798097e+000,
- 5.936468e+001,
- 3.110255e+001,
+static const double datasetXYZRad3[] = {
+ // albedo 0, turbidity 1
+ 1.168084e+000,
+ 2.156455e+000,
+ -3.980314e+000,
+ 1.989302e+001,
+ 1.328335e+001,
+ 1.435621e+001,
+ // albedo 0, turbidity 2
+ 1.135488e+000,
+ 2.294701e+000,
+ -4.585886e+000,
+ 2.090208e+001,
+ 1.347840e+001,
+ 1.467658e+001,
+ // albedo 0, turbidity 3
+ 1.107408e+000,
+ 2.382765e+000,
+ -5.112357e+000,
+ 2.147823e+001,
+ 1.493128e+001,
+ 1.460882e+001,
+ // albedo 0, turbidity 4
+ 1.054193e+000,
+ 2.592891e+000,
+ -6.115000e+000,
+ 2.268967e+001,
+ 1.635672e+001,
+ 1.518999e+001,
+ // albedo 0, turbidity 5
+ 1.006946e+000,
+ 2.705420e+000,
+ -6.698930e+000,
+ 2.291830e+001,
+ 1.834324e+001,
+ 1.570651e+001,
+ // albedo 0, turbidity 6
+ 9.794044e-001,
+ 2.742440e+000,
+ -6.805283e+000,
+ 2.225271e+001,
+ 2.050797e+001,
+ 1.563130e+001,
+ // albedo 0, turbidity 7
+ 9.413577e-001,
+ 2.722009e+000,
+ -6.760707e+000,
+ 2.098242e+001,
+ 2.342588e+001,
+ 1.605011e+001,
+ // albedo 0, turbidity 8
+ 8.917923e-001,
+ 2.592780e+000,
+ -6.152635e+000,
+ 1.774141e+001,
+ 2.858324e+001,
+ 1.657910e+001,
+ // albedo 0, turbidity 9
+ 8.288391e-001,
+ 2.153434e+000,
+ -4.118327e+000,
+ 1.078118e+001,
+ 3.681710e+001,
+ 1.738139e+001,
+ // albedo 0, turbidity 10
+ 7.623528e-001,
+ 1.418187e+000,
+ -8.845235e-001,
+ 7.590129e-001,
+ 4.629859e+001,
+ 1.921657e+001,
+ // albedo 1, turbidity 1
+ 1.352858e+000,
+ 2.048862e+000,
+ -2.053393e+000,
+ 1.405874e+001,
+ 3.045344e+001,
+ 3.044430e+001,
+ // albedo 1, turbidity 2
+ 1.330497e+000,
+ 2.126497e+000,
+ -2.466296e+000,
+ 1.467559e+001,
+ 3.090738e+001,
+ 3.069707e+001,
+ // albedo 1, turbidity 3
+ 1.286344e+000,
+ 2.200436e+000,
+ -2.877228e+000,
+ 1.492701e+001,
+ 3.236288e+001,
+ 3.077223e+001,
+ // albedo 1, turbidity 4
+ 1.234428e+000,
+ 2.289628e+000,
+ -3.404699e+000,
+ 1.499436e+001,
+ 3.468390e+001,
+ 3.084842e+001,
+ // albedo 1, turbidity 5
+ 1.178660e+000,
+ 2.306071e+000,
+ -3.549159e+000,
+ 1.411006e+001,
+ 3.754188e+001,
+ 3.079730e+001,
+ // albedo 1, turbidity 6
+ 1.151366e+000,
+ 2.333005e+000,
+ -3.728627e+000,
+ 1.363374e+001,
+ 3.905894e+001,
+ 3.092599e+001,
+ // albedo 1, turbidity 7
+ 1.101593e+000,
+ 2.299422e+000,
+ -3.565787e+000,
+ 1.196745e+001,
+ 4.188472e+001,
+ 3.102755e+001,
+ // albedo 1, turbidity 8
+ 1.038322e+000,
+ 2.083539e+000,
+ -2.649585e+000,
+ 8.037389e+000,
+ 4.700869e+001,
+ 3.065948e+001,
+ // albedo 1, turbidity 9
+ 9.596146e-001,
+ 1.671470e+000,
+ -8.751538e-001,
+ 1.679772e+000,
+ 5.345784e+001,
+ 3.054520e+001,
+ // albedo 1, turbidity 10
+ 8.640731e-001,
+ 9.858301e-001,
+ 1.854956e+000,
+ -6.798097e+000,
+ 5.936468e+001,
+ 3.110255e+001,
};
+static const double *datasetsXYZ[] = {datasetXYZ1, datasetXYZ2, datasetXYZ3};
-
-static const double* datasetsXYZ[] = {
- datasetXYZ1,
- datasetXYZ2,
- datasetXYZ3
-};
-
-static const double* datasetsXYZRad[] = {
- datasetXYZRad1,
- datasetXYZRad2,
- datasetXYZRad3
-};
+static const double *datasetsXYZRad[] = {datasetXYZRad1, datasetXYZRad2, datasetXYZRad3};
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_sseb.h b/intern/cycles/util/util_sseb.h
index f6810505126..56f8f676ba1 100644
--- a/intern/cycles/util/util_sseb.h
+++ b/intern/cycles/util/util_sseb.h
@@ -26,150 +26,274 @@ struct ssei;
struct ssef;
/*! 4-wide SSE bool type. */
-struct sseb
-{
- typedef sseb Mask; // mask type
- typedef ssei Int; // int type
- typedef ssef Float; // float type
-
- enum { size = 4 }; // number of SIMD elements
- union { __m128 m128; int32_t v[4]; }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline sseb ( ) {}
- __forceinline sseb ( const sseb& other ) { m128 = other.m128; }
- __forceinline sseb& operator=( const sseb& other ) { m128 = other.m128; return *this; }
-
- __forceinline sseb( const __m128 input ) : m128(input) {}
- __forceinline operator const __m128&( void ) const { return m128; }
- __forceinline operator const __m128i( void ) const { return _mm_castps_si128(m128); }
- __forceinline operator const __m128d( void ) const { return _mm_castps_pd(m128); }
-
- __forceinline sseb ( bool a )
- : m128(_mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)]) {}
- __forceinline sseb ( bool a, bool b)
- : m128(_mm_lookupmask_ps[(size_t(b) << 3) | (size_t(a) << 2) | (size_t(b) << 1) | size_t(a)]) {}
- __forceinline sseb ( bool a, bool b, bool c, bool d)
- : m128(_mm_lookupmask_ps[(size_t(d) << 3) | (size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {}
- __forceinline sseb(int mask) {
- assert(mask >= 0 && mask < 16);
- m128 = _mm_lookupmask_ps[mask];
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constants
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline sseb( FalseTy ) : m128(_mm_setzero_ps()) {}
- __forceinline sseb( TrueTy ) : m128(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))) {}
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline bool operator []( const size_t i ) const { assert(i < 4); return (_mm_movemask_ps(m128) >> i) & 1; }
- __forceinline int32_t& operator []( const size_t i ) { assert(i < 4); return v[i]; }
+struct sseb {
+ typedef sseb Mask; // mask type
+ typedef ssei Int; // int type
+ typedef ssef Float; // float type
+
+ enum { size = 4 }; // number of SIMD elements
+ union {
+ __m128 m128;
+ int32_t v[4];
+ }; // data
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Constructors, Assignment & Cast Operators
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline sseb()
+ {
+ }
+ __forceinline sseb(const sseb &other)
+ {
+ m128 = other.m128;
+ }
+ __forceinline sseb &operator=(const sseb &other)
+ {
+ m128 = other.m128;
+ return *this;
+ }
+
+ __forceinline sseb(const __m128 input) : m128(input)
+ {
+ }
+ __forceinline operator const __m128 &(void)const
+ {
+ return m128;
+ }
+ __forceinline operator const __m128i(void) const
+ {
+ return _mm_castps_si128(m128);
+ }
+ __forceinline operator const __m128d(void) const
+ {
+ return _mm_castps_pd(m128);
+ }
+
+ __forceinline sseb(bool a)
+ : m128(_mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)])
+ {
+ }
+ __forceinline sseb(bool a, bool b)
+ : m128(_mm_lookupmask_ps[(size_t(b) << 3) | (size_t(a) << 2) | (size_t(b) << 1) | size_t(a)])
+ {
+ }
+ __forceinline sseb(bool a, bool b, bool c, bool d)
+ : m128(_mm_lookupmask_ps[(size_t(d) << 3) | (size_t(c) << 2) | (size_t(b) << 1) | size_t(a)])
+ {
+ }
+ __forceinline sseb(int mask)
+ {
+ assert(mask >= 0 && mask < 16);
+ m128 = _mm_lookupmask_ps[mask];
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Constants
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline sseb(FalseTy) : m128(_mm_setzero_ps())
+ {
+ }
+ __forceinline sseb(TrueTy)
+ : m128(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())))
+ {
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Array Access
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline bool operator[](const size_t i) const
+ {
+ assert(i < 4);
+ return (_mm_movemask_ps(m128) >> i) & 1;
+ }
+ __forceinline int32_t &operator[](const size_t i)
+ {
+ assert(i < 4);
+ return v[i];
+ }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const sseb operator !( const sseb& a ) { return _mm_xor_ps(a, sseb(True)); }
+__forceinline const sseb operator!(const sseb &a)
+{
+ return _mm_xor_ps(a, sseb(True));
+}
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const sseb operator &( const sseb& a, const sseb& b ) { return _mm_and_ps(a, b); }
-__forceinline const sseb operator |( const sseb& a, const sseb& b ) { return _mm_or_ps (a, b); }
-__forceinline const sseb operator ^( const sseb& a, const sseb& b ) { return _mm_xor_ps(a, b); }
+__forceinline const sseb operator&(const sseb &a, const sseb &b)
+{
+ return _mm_and_ps(a, b);
+}
+__forceinline const sseb operator|(const sseb &a, const sseb &b)
+{
+ return _mm_or_ps(a, b);
+}
+__forceinline const sseb operator^(const sseb &a, const sseb &b)
+{
+ return _mm_xor_ps(a, b);
+}
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const sseb operator &=( sseb& a, const sseb& b ) { return a = a & b; }
-__forceinline const sseb operator |=( sseb& a, const sseb& b ) { return a = a | b; }
-__forceinline const sseb operator ^=( sseb& a, const sseb& b ) { return a = a ^ b; }
+__forceinline const sseb operator&=(sseb &a, const sseb &b)
+{
+ return a = a & b;
+}
+__forceinline const sseb operator|=(sseb &a, const sseb &b)
+{
+ return a = a | b;
+}
+__forceinline const sseb operator^=(sseb &a, const sseb &b)
+{
+ return a = a ^ b;
+}
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
-__forceinline const sseb operator !=( const sseb& a, const sseb& b ) { return _mm_xor_ps(a, b); }
-__forceinline const sseb operator ==( const sseb& a, const sseb& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
+__forceinline const sseb operator!=(const sseb &a, const sseb &b)
+{
+ return _mm_xor_ps(a, b);
+}
+__forceinline const sseb operator==(const sseb &a, const sseb &b)
+{
+ return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b));
+}
-__forceinline const sseb select( const sseb& m, const sseb& t, const sseb& f ) {
-#if defined(__KERNEL_SSE41__)
- return _mm_blendv_ps(f, t, m);
-#else
- return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
-#endif
+__forceinline const sseb select(const sseb &m, const sseb &t, const sseb &f)
+{
+# if defined(__KERNEL_SSE41__)
+ return _mm_blendv_ps(f, t, m);
+# else
+ return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
+# endif
}
////////////////////////////////////////////////////////////////////////////////
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
-__forceinline const sseb unpacklo( const sseb& a, const sseb& b ) { return _mm_unpacklo_ps(a, b); }
-__forceinline const sseb unpackhi( const sseb& a, const sseb& b ) { return _mm_unpackhi_ps(a, b); }
+__forceinline const sseb unpacklo(const sseb &a, const sseb &b)
+{
+ return _mm_unpacklo_ps(a, b);
+}
+__forceinline const sseb unpackhi(const sseb &a, const sseb &b)
+{
+ return _mm_unpackhi_ps(a, b);
+}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const sseb shuffle( const sseb& a ) {
- return _mm_castsi128_ps(_mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0)));
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const sseb shuffle(const sseb &a)
+{
+ return _mm_castsi128_ps(_mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0)));
}
-template<> __forceinline const sseb shuffle<0, 1, 0, 1>( const sseb& a ) {
- return _mm_movelh_ps(a, a);
+template<> __forceinline const sseb shuffle<0, 1, 0, 1>(const sseb &a)
+{
+ return _mm_movelh_ps(a, a);
}
-template<> __forceinline const sseb shuffle<2, 3, 2, 3>( const sseb& a ) {
- return _mm_movehl_ps(a, a);
+template<> __forceinline const sseb shuffle<2, 3, 2, 3>(const sseb &a)
+{
+ return _mm_movehl_ps(a, a);
}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const sseb shuffle( const sseb& a, const sseb& b ) {
- return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const sseb shuffle(const sseb &a, const sseb &b)
+{
+ return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
-template<> __forceinline const sseb shuffle<0, 1, 0, 1>( const sseb& a, const sseb& b ) {
- return _mm_movelh_ps(a, b);
+template<> __forceinline const sseb shuffle<0, 1, 0, 1>(const sseb &a, const sseb &b)
+{
+ return _mm_movelh_ps(a, b);
}
-template<> __forceinline const sseb shuffle<2, 3, 2, 3>( const sseb& a, const sseb& b ) {
- return _mm_movehl_ps(b, a);
+template<> __forceinline const sseb shuffle<2, 3, 2, 3>(const sseb &a, const sseb &b)
+{
+ return _mm_movehl_ps(b, a);
}
-#if defined(__KERNEL_SSE3__)
-template<> __forceinline const sseb shuffle<0, 0, 2, 2>( const sseb& a ) { return _mm_moveldup_ps(a); }
-template<> __forceinline const sseb shuffle<1, 1, 3, 3>( const sseb& a ) { return _mm_movehdup_ps(a); }
-#endif
+# if defined(__KERNEL_SSE3__)
+template<> __forceinline const sseb shuffle<0, 0, 2, 2>(const sseb &a)
+{
+ return _mm_moveldup_ps(a);
+}
+template<> __forceinline const sseb shuffle<1, 1, 3, 3>(const sseb &a)
+{
+ return _mm_movehdup_ps(a);
+}
+# endif
-#if defined(__KERNEL_SSE41__)
-template<size_t dst, size_t src, size_t clr> __forceinline const sseb insert( const sseb& a, const sseb& b ) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
-template<size_t dst, size_t src> __forceinline const sseb insert( const sseb& a, const sseb& b ) { return insert<dst, src, 0>(a, b); }
-template<size_t dst> __forceinline const sseb insert( const sseb& a, const bool b ) { return insert<dst,0>(a, sseb(b)); }
-#endif
+# if defined(__KERNEL_SSE41__)
+template<size_t dst, size_t src, size_t clr>
+__forceinline const sseb insert(const sseb &a, const sseb &b)
+{
+ return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr);
+}
+template<size_t dst, size_t src> __forceinline const sseb insert(const sseb &a, const sseb &b)
+{
+ return insert<dst, src, 0>(a, b);
+}
+template<size_t dst> __forceinline const sseb insert(const sseb &a, const bool b)
+{
+ return insert<dst, 0>(a, sseb(b));
+}
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
-#if defined(__KERNEL_SSE41__)
-__forceinline size_t popcnt( const sseb& a ) { return __popcnt(_mm_movemask_ps(a)); }
-#else
-__forceinline size_t popcnt( const sseb& a ) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); }
-#endif
+# if defined(__KERNEL_SSE41__)
+__forceinline size_t popcnt(const sseb &a)
+{
+ return __popcnt(_mm_movemask_ps(a));
+}
+# else
+__forceinline size_t popcnt(const sseb &a)
+{
+ return bool(a[0]) + bool(a[1]) + bool(a[2]) + bool(a[3]);
+}
+# endif
-__forceinline bool reduce_and( const sseb& a ) { return _mm_movemask_ps(a) == 0xf; }
-__forceinline bool reduce_or ( const sseb& a ) { return _mm_movemask_ps(a) != 0x0; }
-__forceinline bool all ( const sseb& b ) { return _mm_movemask_ps(b) == 0xf; }
-__forceinline bool any ( const sseb& b ) { return _mm_movemask_ps(b) != 0x0; }
-__forceinline bool none ( const sseb& b ) { return _mm_movemask_ps(b) == 0x0; }
+__forceinline bool reduce_and(const sseb &a)
+{
+ return _mm_movemask_ps(a) == 0xf;
+}
+__forceinline bool reduce_or(const sseb &a)
+{
+ return _mm_movemask_ps(a) != 0x0;
+}
+__forceinline bool all(const sseb &b)
+{
+ return _mm_movemask_ps(b) == 0xf;
+}
+__forceinline bool any(const sseb &b)
+{
+ return _mm_movemask_ps(b) != 0x0;
+}
+__forceinline bool none(const sseb &b)
+{
+ return _mm_movemask_ps(b) == 0x0;
+}
-__forceinline size_t movemask( const sseb& a ) { return _mm_movemask_ps(a); }
+__forceinline size_t movemask(const sseb &a)
+{
+ return _mm_movemask_ps(a);
+}
////////////////////////////////////////////////////////////////////////////////
/// Debug Functions
@@ -177,8 +301,7 @@ __forceinline size_t movemask( const sseb& a ) { return _mm_movemask_ps(a); }
ccl_device_inline void print_sseb(const char *label, const sseb &a)
{
- printf("%s: %d %d %d %d\n",
- label, a[0], a[1], a[2], a[3]);
+ printf("%s: %d %d %d %d\n", label, a[0], a[1], a[2], a[3]);
}
#endif
diff --git a/intern/cycles/util/util_ssef.h b/intern/cycles/util/util_ssef.h
index 66670c9a779..e6610dbb197 100644
--- a/intern/cycles/util/util_ssef.h
+++ b/intern/cycles/util/util_ssef.h
@@ -26,587 +26,971 @@ struct sseb;
struct ssef;
/*! 4-wide SSE float type. */
-struct ssef
-{
- typedef sseb Mask; // mask type
- typedef ssei Int; // int type
- typedef ssef Float; // float type
-
- enum { size = 4 }; // number of SIMD elements
- union { __m128 m128; float f[4]; int i[4]; }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline ssef () {}
- __forceinline ssef (const ssef& other) { m128 = other.m128; }
- __forceinline ssef& operator=(const ssef& other) { m128 = other.m128; return *this; }
-
- __forceinline ssef(const __m128 a) : m128(a) {}
- __forceinline operator const __m128&() const { return m128; }
- __forceinline operator __m128&() { return m128; }
-
- __forceinline ssef (float a) : m128(_mm_set1_ps(a)) {}
- __forceinline ssef (float a, float b, float c, float d) : m128(_mm_setr_ps(a, b, c, d)) {}
-
- __forceinline explicit ssef(const __m128i a) : m128(_mm_cvtepi32_ps(a)) {}
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Loads and Stores
- ////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__KERNEL_AVX__)
- static __forceinline ssef broadcast(const void* const a) { return _mm_broadcast_ss((float*)a); }
-#else
- static __forceinline ssef broadcast(const void* const a) { return _mm_set1_ps(*(float*)a); }
-#endif
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline const float& operator [](const size_t i) const { assert(i < 4); return f[i]; }
- __forceinline float& operator [](const size_t i) { assert(i < 4); return f[i]; }
+struct ssef {
+ typedef sseb Mask; // mask type
+ typedef ssei Int; // int type
+ typedef ssef Float; // float type
+
+ enum { size = 4 }; // number of SIMD elements
+ union {
+ __m128 m128;
+ float f[4];
+ int i[4];
+ }; // data
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Constructors, Assignment & Cast Operators
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline ssef()
+ {
+ }
+ __forceinline ssef(const ssef &other)
+ {
+ m128 = other.m128;
+ }
+ __forceinline ssef &operator=(const ssef &other)
+ {
+ m128 = other.m128;
+ return *this;
+ }
+
+ __forceinline ssef(const __m128 a) : m128(a)
+ {
+ }
+ __forceinline operator const __m128 &() const
+ {
+ return m128;
+ }
+ __forceinline operator __m128 &()
+ {
+ return m128;
+ }
+
+ __forceinline ssef(float a) : m128(_mm_set1_ps(a))
+ {
+ }
+ __forceinline ssef(float a, float b, float c, float d) : m128(_mm_setr_ps(a, b, c, d))
+ {
+ }
+
+ __forceinline explicit ssef(const __m128i a) : m128(_mm_cvtepi32_ps(a))
+ {
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Loads and Stores
+ ////////////////////////////////////////////////////////////////////////////////
+
+# if defined(__KERNEL_AVX__)
+ static __forceinline ssef broadcast(const void *const a)
+ {
+ return _mm_broadcast_ss((float *)a);
+ }
+# else
+ static __forceinline ssef broadcast(const void *const a)
+ {
+ return _mm_set1_ps(*(float *)a);
+ }
+# endif
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Array Access
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline const float &operator[](const size_t i) const
+ {
+ assert(i < 4);
+ return f[i];
+ }
+ __forceinline float &operator[](const size_t i)
+ {
+ assert(i < 4);
+ return f[i];
+ }
};
-
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const ssef cast (const __m128i& a) { return _mm_castsi128_ps(a); }
-__forceinline const ssef operator +(const ssef& a) { return a; }
-__forceinline const ssef operator -(const ssef& a) { return _mm_xor_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
-__forceinline const ssef abs (const ssef& a) { return _mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); }
-#if defined(__KERNEL_SSE41__)
-__forceinline const ssef sign (const ssef& a) { return _mm_blendv_ps(ssef(1.0f), -ssef(1.0f), _mm_cmplt_ps(a,ssef(0.0f))); }
-#endif
-__forceinline const ssef signmsk (const ssef& a) { return _mm_and_ps(a.m128,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
+__forceinline const ssef cast(const __m128i &a)
+{
+ return _mm_castsi128_ps(a);
+}
+__forceinline const ssef operator+(const ssef &a)
+{
+ return a;
+}
+__forceinline const ssef operator-(const ssef &a)
+{
+ return _mm_xor_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000)));
+}
+__forceinline const ssef abs(const ssef &a)
+{
+ return _mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)));
+}
+# if defined(__KERNEL_SSE41__)
+__forceinline const ssef sign(const ssef &a)
+{
+ return _mm_blendv_ps(ssef(1.0f), -ssef(1.0f), _mm_cmplt_ps(a, ssef(0.0f)));
+}
+# endif
+__forceinline const ssef signmsk(const ssef &a)
+{
+ return _mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000)));
+}
-__forceinline const ssef rcp (const ssef& a) {
- const ssef r = _mm_rcp_ps(a.m128);
- return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a));
+__forceinline const ssef rcp(const ssef &a)
+{
+ const ssef r = _mm_rcp_ps(a.m128);
+ return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a));
+}
+__forceinline const ssef sqr(const ssef &a)
+{
+ return _mm_mul_ps(a, a);
}
-__forceinline const ssef sqr (const ssef& a) { return _mm_mul_ps(a,a); }
-__forceinline const ssef mm_sqrt(const ssef& a) { return _mm_sqrt_ps(a.m128); }
-__forceinline const ssef rsqrt(const ssef& a) {
- const ssef r = _mm_rsqrt_ps(a.m128);
- return _mm_add_ps(_mm_mul_ps(_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f), r),
- _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set_ps(-0.5f, -0.5f, -0.5f, -0.5f)), r), _mm_mul_ps(r, r)));
+__forceinline const ssef mm_sqrt(const ssef &a)
+{
+ return _mm_sqrt_ps(a.m128);
+}
+__forceinline const ssef rsqrt(const ssef &a)
+{
+ const ssef r = _mm_rsqrt_ps(a.m128);
+ return _mm_add_ps(
+ _mm_mul_ps(_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f), r),
+ _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set_ps(-0.5f, -0.5f, -0.5f, -0.5f)), r),
+ _mm_mul_ps(r, r)));
}
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const ssef operator +(const ssef& a, const ssef& b) { return _mm_add_ps(a.m128, b.m128); }
-__forceinline const ssef operator +(const ssef& a, const float& b) { return a + ssef(b); }
-__forceinline const ssef operator +(const float& a, const ssef& b) { return ssef(a) + b; }
+__forceinline const ssef operator+(const ssef &a, const ssef &b)
+{
+ return _mm_add_ps(a.m128, b.m128);
+}
+__forceinline const ssef operator+(const ssef &a, const float &b)
+{
+ return a + ssef(b);
+}
+__forceinline const ssef operator+(const float &a, const ssef &b)
+{
+ return ssef(a) + b;
+}
-__forceinline const ssef operator -(const ssef& a, const ssef& b) { return _mm_sub_ps(a.m128, b.m128); }
-__forceinline const ssef operator -(const ssef& a, const float& b) { return a - ssef(b); }
-__forceinline const ssef operator -(const float& a, const ssef& b) { return ssef(a) - b; }
+__forceinline const ssef operator-(const ssef &a, const ssef &b)
+{
+ return _mm_sub_ps(a.m128, b.m128);
+}
+__forceinline const ssef operator-(const ssef &a, const float &b)
+{
+ return a - ssef(b);
+}
+__forceinline const ssef operator-(const float &a, const ssef &b)
+{
+ return ssef(a) - b;
+}
-__forceinline const ssef operator *(const ssef& a, const ssef& b) { return _mm_mul_ps(a.m128, b.m128); }
-__forceinline const ssef operator *(const ssef& a, const float& b) { return a * ssef(b); }
-__forceinline const ssef operator *(const float& a, const ssef& b) { return ssef(a) * b; }
+__forceinline const ssef operator*(const ssef &a, const ssef &b)
+{
+ return _mm_mul_ps(a.m128, b.m128);
+}
+__forceinline const ssef operator*(const ssef &a, const float &b)
+{
+ return a * ssef(b);
+}
+__forceinline const ssef operator*(const float &a, const ssef &b)
+{
+ return ssef(a) * b;
+}
-__forceinline const ssef operator /(const ssef& a, const ssef& b) { return _mm_div_ps(a.m128,b.m128); }
-__forceinline const ssef operator /(const ssef& a, const float& b) { return a/ssef(b); }
-__forceinline const ssef operator /(const float& a, const ssef& b) { return ssef(a)/b; }
+__forceinline const ssef operator/(const ssef &a, const ssef &b)
+{
+ return _mm_div_ps(a.m128, b.m128);
+}
+__forceinline const ssef operator/(const ssef &a, const float &b)
+{
+ return a / ssef(b);
+}
+__forceinline const ssef operator/(const float &a, const ssef &b)
+{
+ return ssef(a) / b;
+}
-__forceinline const ssef operator^(const ssef& a, const ssef& b) { return _mm_xor_ps(a.m128,b.m128); }
-__forceinline const ssef operator^(const ssef& a, const ssei& b) { return _mm_xor_ps(a.m128,_mm_castsi128_ps(b.m128)); }
+__forceinline const ssef operator^(const ssef &a, const ssef &b)
+{
+ return _mm_xor_ps(a.m128, b.m128);
+}
+__forceinline const ssef operator^(const ssef &a, const ssei &b)
+{
+ return _mm_xor_ps(a.m128, _mm_castsi128_ps(b.m128));
+}
-__forceinline const ssef operator&(const ssef& a, const ssef& b) { return _mm_and_ps(a.m128,b.m128); }
-__forceinline const ssef operator&(const ssef& a, const ssei& b) { return _mm_and_ps(a.m128,_mm_castsi128_ps(b.m128)); }
+__forceinline const ssef operator&(const ssef &a, const ssef &b)
+{
+ return _mm_and_ps(a.m128, b.m128);
+}
+__forceinline const ssef operator&(const ssef &a, const ssei &b)
+{
+ return _mm_and_ps(a.m128, _mm_castsi128_ps(b.m128));
+}
-__forceinline const ssef operator|(const ssef& a, const ssef& b) { return _mm_or_ps(a.m128,b.m128); }
-__forceinline const ssef operator|(const ssef& a, const ssei& b) { return _mm_or_ps(a.m128,_mm_castsi128_ps(b.m128)); }
+__forceinline const ssef operator|(const ssef &a, const ssef &b)
+{
+ return _mm_or_ps(a.m128, b.m128);
+}
+__forceinline const ssef operator|(const ssef &a, const ssei &b)
+{
+ return _mm_or_ps(a.m128, _mm_castsi128_ps(b.m128));
+}
-__forceinline const ssef andnot(const ssef& a, const ssef& b) { return _mm_andnot_ps(a.m128,b.m128); }
+__forceinline const ssef andnot(const ssef &a, const ssef &b)
+{
+ return _mm_andnot_ps(a.m128, b.m128);
+}
-__forceinline const ssef min(const ssef& a, const ssef& b) { return _mm_min_ps(a.m128,b.m128); }
-__forceinline const ssef min(const ssef& a, const float& b) { return _mm_min_ps(a.m128,ssef(b)); }
-__forceinline const ssef min(const float& a, const ssef& b) { return _mm_min_ps(ssef(a),b.m128); }
+__forceinline const ssef min(const ssef &a, const ssef &b)
+{
+ return _mm_min_ps(a.m128, b.m128);
+}
+__forceinline const ssef min(const ssef &a, const float &b)
+{
+ return _mm_min_ps(a.m128, ssef(b));
+}
+__forceinline const ssef min(const float &a, const ssef &b)
+{
+ return _mm_min_ps(ssef(a), b.m128);
+}
-__forceinline const ssef max(const ssef& a, const ssef& b) { return _mm_max_ps(a.m128,b.m128); }
-__forceinline const ssef max(const ssef& a, const float& b) { return _mm_max_ps(a.m128,ssef(b)); }
-__forceinline const ssef max(const float& a, const ssef& b) { return _mm_max_ps(ssef(a),b.m128); }
+__forceinline const ssef max(const ssef &a, const ssef &b)
+{
+ return _mm_max_ps(a.m128, b.m128);
+}
+__forceinline const ssef max(const ssef &a, const float &b)
+{
+ return _mm_max_ps(a.m128, ssef(b));
+}
+__forceinline const ssef max(const float &a, const ssef &b)
+{
+ return _mm_max_ps(ssef(a), b.m128);
+}
-#if defined(__KERNEL_SSE41__)
-__forceinline ssef mini(const ssef& a, const ssef& b) {
- const ssei ai = _mm_castps_si128(a);
- const ssei bi = _mm_castps_si128(b);
- const ssei ci = _mm_min_epi32(ai,bi);
- return _mm_castsi128_ps(ci);
+# if defined(__KERNEL_SSE41__)
+__forceinline ssef mini(const ssef &a, const ssef &b)
+{
+ const ssei ai = _mm_castps_si128(a);
+ const ssei bi = _mm_castps_si128(b);
+ const ssei ci = _mm_min_epi32(ai, bi);
+ return _mm_castsi128_ps(ci);
}
-#endif
+# endif
-#if defined(__KERNEL_SSE41__)
-__forceinline ssef maxi(const ssef& a, const ssef& b) {
- const ssei ai = _mm_castps_si128(a);
- const ssei bi = _mm_castps_si128(b);
- const ssei ci = _mm_max_epi32(ai,bi);
- return _mm_castsi128_ps(ci);
+# if defined(__KERNEL_SSE41__)
+__forceinline ssef maxi(const ssef &a, const ssef &b)
+{
+ const ssei ai = _mm_castps_si128(a);
+ const ssei bi = _mm_castps_si128(b);
+ const ssei ci = _mm_max_epi32(ai, bi);
+ return _mm_castsi128_ps(ci);
}
-#endif
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Ternary Operators
////////////////////////////////////////////////////////////////////////////////
-#if defined(__KERNEL_AVX2__)
-__forceinline const ssef madd (const ssef& a, const ssef& b, const ssef& c) { return _mm_fmadd_ps(a,b,c); }
-__forceinline const ssef msub (const ssef& a, const ssef& b, const ssef& c) { return _mm_fmsub_ps(a,b,c); }
-__forceinline const ssef nmadd(const ssef& a, const ssef& b, const ssef& c) { return _mm_fnmadd_ps(a,b,c); }
-__forceinline const ssef nmsub(const ssef& a, const ssef& b, const ssef& c) { return _mm_fnmsub_ps(a,b,c); }
-#else
-__forceinline const ssef madd (const ssef& a, const ssef& b, const ssef& c) { return a*b+c; }
-__forceinline const ssef msub (const ssef& a, const ssef& b, const ssef& c) { return a*b-c; }
-__forceinline const ssef nmadd(const ssef& a, const ssef& b, const ssef& c) { return c-a*b;}
-__forceinline const ssef nmsub(const ssef& a, const ssef& b, const ssef& c) { return -a*b-c; }
-#endif
+# if defined(__KERNEL_AVX2__)
+__forceinline const ssef madd(const ssef &a, const ssef &b, const ssef &c)
+{
+ return _mm_fmadd_ps(a, b, c);
+}
+__forceinline const ssef msub(const ssef &a, const ssef &b, const ssef &c)
+{
+ return _mm_fmsub_ps(a, b, c);
+}
+__forceinline const ssef nmadd(const ssef &a, const ssef &b, const ssef &c)
+{
+ return _mm_fnmadd_ps(a, b, c);
+}
+__forceinline const ssef nmsub(const ssef &a, const ssef &b, const ssef &c)
+{
+ return _mm_fnmsub_ps(a, b, c);
+}
+# else
+__forceinline const ssef madd(const ssef &a, const ssef &b, const ssef &c)
+{
+ return a * b + c;
+}
+__forceinline const ssef msub(const ssef &a, const ssef &b, const ssef &c)
+{
+ return a * b - c;
+}
+__forceinline const ssef nmadd(const ssef &a, const ssef &b, const ssef &c)
+{
+ return c - a * b;
+}
+__forceinline const ssef nmsub(const ssef &a, const ssef &b, const ssef &c)
+{
+ return -a * b - c;
+}
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline ssef& operator +=(ssef& a, const ssef& b) { return a = a + b; }
-__forceinline ssef& operator +=(ssef& a, const float& b) { return a = a + b; }
+__forceinline ssef &operator+=(ssef &a, const ssef &b)
+{
+ return a = a + b;
+}
+__forceinline ssef &operator+=(ssef &a, const float &b)
+{
+ return a = a + b;
+}
-__forceinline ssef& operator -=(ssef& a, const ssef& b) { return a = a - b; }
-__forceinline ssef& operator -=(ssef& a, const float& b) { return a = a - b; }
+__forceinline ssef &operator-=(ssef &a, const ssef &b)
+{
+ return a = a - b;
+}
+__forceinline ssef &operator-=(ssef &a, const float &b)
+{
+ return a = a - b;
+}
-__forceinline ssef& operator *=(ssef& a, const ssef& b) { return a = a * b; }
-__forceinline ssef& operator *=(ssef& a, const float& b) { return a = a * b; }
+__forceinline ssef &operator*=(ssef &a, const ssef &b)
+{
+ return a = a * b;
+}
+__forceinline ssef &operator*=(ssef &a, const float &b)
+{
+ return a = a * b;
+}
-__forceinline ssef& operator /=(ssef& a, const ssef& b) { return a = a / b; }
-__forceinline ssef& operator /=(ssef& a, const float& b) { return a = a / b; }
+__forceinline ssef &operator/=(ssef &a, const ssef &b)
+{
+ return a = a / b;
+}
+__forceinline ssef &operator/=(ssef &a, const float &b)
+{
+ return a = a / b;
+}
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
-__forceinline const sseb operator ==(const ssef& a, const ssef& b) { return _mm_cmpeq_ps(a.m128, b.m128); }
-__forceinline const sseb operator ==(const ssef& a, const float& b) { return a == ssef(b); }
-__forceinline const sseb operator ==(const float& a, const ssef& b) { return ssef(a) == b; }
+__forceinline const sseb operator==(const ssef &a, const ssef &b)
+{
+ return _mm_cmpeq_ps(a.m128, b.m128);
+}
+__forceinline const sseb operator==(const ssef &a, const float &b)
+{
+ return a == ssef(b);
+}
+__forceinline const sseb operator==(const float &a, const ssef &b)
+{
+ return ssef(a) == b;
+}
-__forceinline const sseb operator !=(const ssef& a, const ssef& b) { return _mm_cmpneq_ps(a.m128, b.m128); }
-__forceinline const sseb operator !=(const ssef& a, const float& b) { return a != ssef(b); }
-__forceinline const sseb operator !=(const float& a, const ssef& b) { return ssef(a) != b; }
+__forceinline const sseb operator!=(const ssef &a, const ssef &b)
+{
+ return _mm_cmpneq_ps(a.m128, b.m128);
+}
+__forceinline const sseb operator!=(const ssef &a, const float &b)
+{
+ return a != ssef(b);
+}
+__forceinline const sseb operator!=(const float &a, const ssef &b)
+{
+ return ssef(a) != b;
+}
-__forceinline const sseb operator <(const ssef& a, const ssef& b) { return _mm_cmplt_ps(a.m128, b.m128); }
-__forceinline const sseb operator <(const ssef& a, const float& b) { return a < ssef(b); }
-__forceinline const sseb operator <(const float& a, const ssef& b) { return ssef(a) < b; }
+__forceinline const sseb operator<(const ssef &a, const ssef &b)
+{
+ return _mm_cmplt_ps(a.m128, b.m128);
+}
+__forceinline const sseb operator<(const ssef &a, const float &b)
+{
+ return a < ssef(b);
+}
+__forceinline const sseb operator<(const float &a, const ssef &b)
+{
+ return ssef(a) < b;
+}
-__forceinline const sseb operator >=(const ssef& a, const ssef& b) { return _mm_cmpnlt_ps(a.m128, b.m128); }
-__forceinline const sseb operator >=(const ssef& a, const float& b) { return a >= ssef(b); }
-__forceinline const sseb operator >=(const float& a, const ssef& b) { return ssef(a) >= b; }
+__forceinline const sseb operator>=(const ssef &a, const ssef &b)
+{
+ return _mm_cmpnlt_ps(a.m128, b.m128);
+}
+__forceinline const sseb operator>=(const ssef &a, const float &b)
+{
+ return a >= ssef(b);
+}
+__forceinline const sseb operator>=(const float &a, const ssef &b)
+{
+ return ssef(a) >= b;
+}
-__forceinline const sseb operator >(const ssef& a, const ssef& b) { return _mm_cmpnle_ps(a.m128, b.m128); }
-__forceinline const sseb operator >(const ssef& a, const float& b) { return a > ssef(b); }
-__forceinline const sseb operator >(const float& a, const ssef& b) { return ssef(a) > b; }
+__forceinline const sseb operator>(const ssef &a, const ssef &b)
+{
+ return _mm_cmpnle_ps(a.m128, b.m128);
+}
+__forceinline const sseb operator>(const ssef &a, const float &b)
+{
+ return a > ssef(b);
+}
+__forceinline const sseb operator>(const float &a, const ssef &b)
+{
+ return ssef(a) > b;
+}
-__forceinline const sseb operator <=(const ssef& a, const ssef& b) { return _mm_cmple_ps(a.m128, b.m128); }
-__forceinline const sseb operator <=(const ssef& a, const float& b) { return a <= ssef(b); }
-__forceinline const sseb operator <=(const float& a, const ssef& b) { return ssef(a) <= b; }
+__forceinline const sseb operator<=(const ssef &a, const ssef &b)
+{
+ return _mm_cmple_ps(a.m128, b.m128);
+}
+__forceinline const sseb operator<=(const ssef &a, const float &b)
+{
+ return a <= ssef(b);
+}
+__forceinline const sseb operator<=(const float &a, const ssef &b)
+{
+ return ssef(a) <= b;
+}
-__forceinline const ssef select(const sseb& m, const ssef& t, const ssef& f) {
-#ifdef __KERNEL_SSE41__
- return _mm_blendv_ps(f, t, m);
-#else
- return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
-#endif
+__forceinline const ssef select(const sseb &m, const ssef &t, const ssef &f)
+{
+# ifdef __KERNEL_SSE41__
+ return _mm_blendv_ps(f, t, m);
+# else
+ return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
+# endif
}
-__forceinline const ssef select(const ssef& m, const ssef& t, const ssef& f) {
-#ifdef __KERNEL_SSE41__
- return _mm_blendv_ps(f, t, m);
-#else
- return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
-#endif
+__forceinline const ssef select(const ssef &m, const ssef &t, const ssef &f)
+{
+# ifdef __KERNEL_SSE41__
+ return _mm_blendv_ps(f, t, m);
+# else
+ return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
+# endif
}
-__forceinline const ssef select(const int mask, const ssef& t, const ssef& f) {
-#if defined(__KERNEL_SSE41__) && ((!defined(__clang__) && !defined(_MSC_VER)) || defined(__INTEL_COMPILER))
- return _mm_blend_ps(f, t, mask);
-#else
- return select(sseb(mask),t,f);
-#endif
+__forceinline const ssef select(const int mask, const ssef &t, const ssef &f)
+{
+# if defined(__KERNEL_SSE41__) && \
+ ((!defined(__clang__) && !defined(_MSC_VER)) || defined(__INTEL_COMPILER))
+ return _mm_blend_ps(f, t, mask);
+# else
+ return select(sseb(mask), t, f);
+# endif
}
////////////////////////////////////////////////////////////////////////////////
/// Rounding Functions
////////////////////////////////////////////////////////////////////////////////
-#if defined(__KERNEL_SSE41__)
-__forceinline const ssef round_even(const ssef& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); }
-__forceinline const ssef round_down(const ssef& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
-__forceinline const ssef round_up (const ssef& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
-__forceinline const ssef round_zero(const ssef& a) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); }
-__forceinline const ssef floor (const ssef& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
-__forceinline const ssef ceil (const ssef& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
-#endif
+# if defined(__KERNEL_SSE41__)
+__forceinline const ssef round_even(const ssef &a)
+{
+ return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT);
+}
+__forceinline const ssef round_down(const ssef &a)
+{
+ return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF);
+}
+__forceinline const ssef round_up(const ssef &a)
+{
+ return _mm_round_ps(a, _MM_FROUND_TO_POS_INF);
+}
+__forceinline const ssef round_zero(const ssef &a)
+{
+ return _mm_round_ps(a, _MM_FROUND_TO_ZERO);
+}
+__forceinline const ssef floor(const ssef &a)
+{
+ return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF);
+}
+__forceinline const ssef ceil(const ssef &a)
+{
+ return _mm_round_ps(a, _MM_FROUND_TO_POS_INF);
+}
+# endif
-__forceinline ssei truncatei(const ssef& a) {
- return _mm_cvttps_epi32(a.m128);
+__forceinline ssei truncatei(const ssef &a)
+{
+ return _mm_cvttps_epi32(a.m128);
}
-__forceinline ssei floori(const ssef& a) {
-#if defined(__KERNEL_SSE41__)
- return ssei(floor(a));
-#else
- return ssei(a-ssef(0.5f));
-#endif
+__forceinline ssei floori(const ssef &a)
+{
+# if defined(__KERNEL_SSE41__)
+ return ssei(floor(a));
+# else
+ return ssei(a - ssef(0.5f));
+# endif
}
////////////////////////////////////////////////////////////////////////////////
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
-__forceinline ssef unpacklo(const ssef& a, const ssef& b) { return _mm_unpacklo_ps(a.m128, b.m128); }
-__forceinline ssef unpackhi(const ssef& a, const ssef& b) { return _mm_unpackhi_ps(a.m128, b.m128); }
+__forceinline ssef unpacklo(const ssef &a, const ssef &b)
+{
+ return _mm_unpacklo_ps(a.m128, b.m128);
+}
+__forceinline ssef unpackhi(const ssef &a, const ssef &b)
+{
+ return _mm_unpackhi_ps(a.m128, b.m128);
+}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssef shuffle(const ssef& b) {
- return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const ssef shuffle(const ssef &b)
+{
+ return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
}
-template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef& a) {
- return _mm_movelh_ps(a, a);
+template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef &a)
+{
+ return _mm_movelh_ps(a, a);
}
-template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef& a) {
- return _mm_movehl_ps(a, a);
+template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef &a)
+{
+ return _mm_movehl_ps(a, a);
}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssef shuffle(const ssef& a, const ssef& b) {
- return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const ssef shuffle(const ssef &a, const ssef &b)
+{
+ return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
-template<size_t i0> __forceinline const ssef shuffle(const ssef& a, const ssef& b) {
- return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i0, i0, i0, i0));
+template<size_t i0> __forceinline const ssef shuffle(const ssef &a, const ssef &b)
+{
+ return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i0, i0, i0, i0));
}
-template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef& a, const ssef& b) {
- return _mm_movelh_ps(a, b);
+template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef &a, const ssef &b)
+{
+ return _mm_movelh_ps(a, b);
}
-template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef& a, const ssef& b) {
- return _mm_movehl_ps(b, a);
+template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef &a, const ssef &b)
+{
+ return _mm_movehl_ps(b, a);
}
-#if defined(__KERNEL_SSSE3__)
-__forceinline const ssef shuffle8(const ssef& a, const ssei& shuf) {
- return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
+# if defined(__KERNEL_SSSE3__)
+__forceinline const ssef shuffle8(const ssef &a, const ssei &shuf)
+{
+ return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
}
-#endif
+# endif
-#if defined(__KERNEL_SSE3__)
-template<> __forceinline const ssef shuffle<0, 0, 2, 2>(const ssef& b) { return _mm_moveldup_ps(b); }
-template<> __forceinline const ssef shuffle<1, 1, 3, 3>(const ssef& b) { return _mm_movehdup_ps(b); }
-#endif
+# if defined(__KERNEL_SSE3__)
+template<> __forceinline const ssef shuffle<0, 0, 2, 2>(const ssef &b)
+{
+ return _mm_moveldup_ps(b);
+}
+template<> __forceinline const ssef shuffle<1, 1, 3, 3>(const ssef &b)
+{
+ return _mm_movehdup_ps(b);
+}
+# endif
-template<size_t i0> __forceinline const ssef shuffle(const ssef& b) {
- return shuffle<i0,i0,i0,i0>(b);
+template<size_t i0> __forceinline const ssef shuffle(const ssef &b)
+{
+ return shuffle<i0, i0, i0, i0>(b);
}
-#if defined(__KERNEL_AVX__)
-__forceinline const ssef shuffle(const ssef& a, const ssei& shuf) {
- return _mm_permutevar_ps(a, shuf);
+# if defined(__KERNEL_AVX__)
+__forceinline const ssef shuffle(const ssef &a, const ssei &shuf)
+{
+ return _mm_permutevar_ps(a, shuf);
}
-#endif
+# endif
-template<size_t i> __forceinline float extract (const ssef& a) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); }
-template<> __forceinline float extract<0>(const ssef& a) { return _mm_cvtss_f32(a); }
+template<size_t i> __forceinline float extract(const ssef &a)
+{
+ return _mm_cvtss_f32(shuffle<i, i, i, i>(a));
+}
+template<> __forceinline float extract<0>(const ssef &a)
+{
+ return _mm_cvtss_f32(a);
+}
-#if defined(__KERNEL_SSE41__)
-template<size_t dst, size_t src, size_t clr> __forceinline const ssef insert(const ssef& a, const ssef& b) { return _mm_insert_ps(a, b,(dst << 4) |(src << 6) | clr); }
-template<size_t dst, size_t src> __forceinline const ssef insert(const ssef& a, const ssef& b) { return insert<dst, src, 0>(a, b); }
-template<size_t dst> __forceinline const ssef insert(const ssef& a, const float b) { return insert<dst, 0>(a, _mm_set_ss(b)); }
-#else
-template<size_t dst> __forceinline const ssef insert(const ssef& a, const float b) { ssef c = a; c[dst] = b; return c; }
-#endif
+# if defined(__KERNEL_SSE41__)
+template<size_t dst, size_t src, size_t clr>
+__forceinline const ssef insert(const ssef &a, const ssef &b)
+{
+ return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr);
+}
+template<size_t dst, size_t src> __forceinline const ssef insert(const ssef &a, const ssef &b)
+{
+ return insert<dst, src, 0>(a, b);
+}
+template<size_t dst> __forceinline const ssef insert(const ssef &a, const float b)
+{
+ return insert<dst, 0>(a, _mm_set_ss(b));
+}
+# else
+template<size_t dst> __forceinline const ssef insert(const ssef &a, const float b)
+{
+ ssef c = a;
+ c[dst] = b;
+ return c;
+}
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Transpose
////////////////////////////////////////////////////////////////////////////////
-__forceinline void transpose(const ssef& r0, const ssef& r1, const ssef& r2, const ssef& r3, ssef& c0, ssef& c1, ssef& c2, ssef& c3)
+__forceinline void transpose(const ssef &r0,
+ const ssef &r1,
+ const ssef &r2,
+ const ssef &r3,
+ ssef &c0,
+ ssef &c1,
+ ssef &c2,
+ ssef &c3)
{
- ssef l02 = unpacklo(r0,r2);
- ssef h02 = unpackhi(r0,r2);
- ssef l13 = unpacklo(r1,r3);
- ssef h13 = unpackhi(r1,r3);
- c0 = unpacklo(l02,l13);
- c1 = unpackhi(l02,l13);
- c2 = unpacklo(h02,h13);
- c3 = unpackhi(h02,h13);
-}
-
-__forceinline void transpose(const ssef& r0, const ssef& r1, const ssef& r2, const ssef& r3, ssef& c0, ssef& c1, ssef& c2)
+ ssef l02 = unpacklo(r0, r2);
+ ssef h02 = unpackhi(r0, r2);
+ ssef l13 = unpacklo(r1, r3);
+ ssef h13 = unpackhi(r1, r3);
+ c0 = unpacklo(l02, l13);
+ c1 = unpackhi(l02, l13);
+ c2 = unpacklo(h02, h13);
+ c3 = unpackhi(h02, h13);
+}
+
+__forceinline void transpose(
+ const ssef &r0, const ssef &r1, const ssef &r2, const ssef &r3, ssef &c0, ssef &c1, ssef &c2)
{
- ssef l02 = unpacklo(r0,r2);
- ssef h02 = unpackhi(r0,r2);
- ssef l13 = unpacklo(r1,r3);
- ssef h13 = unpackhi(r1,r3);
- c0 = unpacklo(l02,l13);
- c1 = unpackhi(l02,l13);
- c2 = unpacklo(h02,h13);
+ ssef l02 = unpacklo(r0, r2);
+ ssef h02 = unpackhi(r0, r2);
+ ssef l13 = unpacklo(r1, r3);
+ ssef h13 = unpackhi(r1, r3);
+ c0 = unpacklo(l02, l13);
+ c1 = unpackhi(l02, l13);
+ c2 = unpacklo(h02, h13);
}
////////////////////////////////////////////////////////////////////////////////
/// Reductions
////////////////////////////////////////////////////////////////////////////////
-__forceinline const ssef vreduce_min(const ssef& v) { ssef h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
-__forceinline const ssef vreduce_max(const ssef& v) { ssef h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
-__forceinline const ssef vreduce_add(const ssef& v) { ssef h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
+__forceinline const ssef vreduce_min(const ssef &v)
+{
+ ssef h = min(shuffle<1, 0, 3, 2>(v), v);
+ return min(shuffle<2, 3, 0, 1>(h), h);
+}
+__forceinline const ssef vreduce_max(const ssef &v)
+{
+ ssef h = max(shuffle<1, 0, 3, 2>(v), v);
+ return max(shuffle<2, 3, 0, 1>(h), h);
+}
+__forceinline const ssef vreduce_add(const ssef &v)
+{
+ ssef h = shuffle<1, 0, 3, 2>(v) + v;
+ return shuffle<2, 3, 0, 1>(h) + h;
+}
-__forceinline float reduce_min(const ssef& v) { return _mm_cvtss_f32(vreduce_min(v)); }
-__forceinline float reduce_max(const ssef& v) { return _mm_cvtss_f32(vreduce_max(v)); }
-__forceinline float reduce_add(const ssef& v) { return _mm_cvtss_f32(vreduce_add(v)); }
+__forceinline float reduce_min(const ssef &v)
+{
+ return _mm_cvtss_f32(vreduce_min(v));
+}
+__forceinline float reduce_max(const ssef &v)
+{
+ return _mm_cvtss_f32(vreduce_max(v));
+}
+__forceinline float reduce_add(const ssef &v)
+{
+ return _mm_cvtss_f32(vreduce_add(v));
+}
-__forceinline size_t select_min(const ssef& v) { return __bsf(movemask(v == vreduce_min(v))); }
-__forceinline size_t select_max(const ssef& v) { return __bsf(movemask(v == vreduce_max(v))); }
+__forceinline size_t select_min(const ssef &v)
+{
+ return __bsf(movemask(v == vreduce_min(v)));
+}
+__forceinline size_t select_max(const ssef &v)
+{
+ return __bsf(movemask(v == vreduce_max(v)));
+}
-__forceinline size_t select_min(const sseb& valid, const ssef& v) { const ssef a = select(valid,v,ssef(pos_inf)); return __bsf(movemask(valid &(a == vreduce_min(a)))); }
-__forceinline size_t select_max(const sseb& valid, const ssef& v) { const ssef a = select(valid,v,ssef(neg_inf)); return __bsf(movemask(valid &(a == vreduce_max(a)))); }
+__forceinline size_t select_min(const sseb &valid, const ssef &v)
+{
+ const ssef a = select(valid, v, ssef(pos_inf));
+ return __bsf(movemask(valid & (a == vreduce_min(a))));
+}
+__forceinline size_t select_max(const sseb &valid, const ssef &v)
+{
+ const ssef a = select(valid, v, ssef(neg_inf));
+ return __bsf(movemask(valid & (a == vreduce_max(a))));
+}
-__forceinline size_t movemask( const ssef& a ) { return _mm_movemask_ps(a); }
+__forceinline size_t movemask(const ssef &a)
+{
+ return _mm_movemask_ps(a);
+}
////////////////////////////////////////////////////////////////////////////////
/// Memory load and store operations
////////////////////////////////////////////////////////////////////////////////
-__forceinline ssef load4f(const float4& a) {
-#ifdef __KERNEL_WITH_SSE_ALIGN__
- return _mm_load_ps(&a.x);
-#else
- return _mm_loadu_ps(&a.x);
-#endif
+__forceinline ssef load4f(const float4 &a)
+{
+# ifdef __KERNEL_WITH_SSE_ALIGN__
+ return _mm_load_ps(&a.x);
+# else
+ return _mm_loadu_ps(&a.x);
+# endif
}
-__forceinline ssef load4f(const float3& a) {
-#ifdef __KERNEL_WITH_SSE_ALIGN__
- return _mm_load_ps(&a.x);
-#else
- return _mm_loadu_ps(&a.x);
-#endif
+__forceinline ssef load4f(const float3 &a)
+{
+# ifdef __KERNEL_WITH_SSE_ALIGN__
+ return _mm_load_ps(&a.x);
+# else
+ return _mm_loadu_ps(&a.x);
+# endif
}
-__forceinline ssef load4f(const void* const a) {
- return _mm_load_ps((float*)a);
+__forceinline ssef load4f(const void *const a)
+{
+ return _mm_load_ps((float *)a);
}
-__forceinline ssef load1f_first(const float a) {
- return _mm_set_ss(a);
+__forceinline ssef load1f_first(const float a)
+{
+ return _mm_set_ss(a);
}
-__forceinline void store4f(void* ptr, const ssef& v) {
- _mm_store_ps((float*)ptr,v);
+__forceinline void store4f(void *ptr, const ssef &v)
+{
+ _mm_store_ps((float *)ptr, v);
}
-__forceinline ssef loadu4f(const void* const a) {
- return _mm_loadu_ps((float*)a);
+__forceinline ssef loadu4f(const void *const a)
+{
+ return _mm_loadu_ps((float *)a);
}
-__forceinline void storeu4f(void* ptr, const ssef& v) {
- _mm_storeu_ps((float*)ptr,v);
+__forceinline void storeu4f(void *ptr, const ssef &v)
+{
+ _mm_storeu_ps((float *)ptr, v);
}
-__forceinline void store4f(const sseb& mask, void* ptr, const ssef& f) {
-#if defined(__KERNEL_AVX__)
- _mm_maskstore_ps((float*)ptr,(__m128i)mask,f);
-#else
- *(ssef*)ptr = select(mask,f,*(ssef*)ptr);
-#endif
+__forceinline void store4f(const sseb &mask, void *ptr, const ssef &f)
+{
+# if defined(__KERNEL_AVX__)
+ _mm_maskstore_ps((float *)ptr, (__m128i)mask, f);
+# else
+ *(ssef *)ptr = select(mask, f, *(ssef *)ptr);
+# endif
}
-__forceinline ssef load4f_nt(void* ptr) {
-#if defined(__KERNEL_SSE41__)
- return _mm_castsi128_ps(_mm_stream_load_si128((__m128i*)ptr));
-#else
- return _mm_load_ps((float*)ptr);
-#endif
+__forceinline ssef load4f_nt(void *ptr)
+{
+# if defined(__KERNEL_SSE41__)
+ return _mm_castsi128_ps(_mm_stream_load_si128((__m128i *)ptr));
+# else
+ return _mm_load_ps((float *)ptr);
+# endif
}
-__forceinline void store4f_nt(void* ptr, const ssef& v) {
-#if defined(__KERNEL_SSE41__)
- _mm_stream_ps((float*)ptr,v);
-#else
- _mm_store_ps((float*)ptr,v);
-#endif
+__forceinline void store4f_nt(void *ptr, const ssef &v)
+{
+# if defined(__KERNEL_SSE41__)
+ _mm_stream_ps((float *)ptr, v);
+# else
+ _mm_store_ps((float *)ptr, v);
+# endif
}
////////////////////////////////////////////////////////////////////////////////
/// Euclidian Space Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline float dot(const ssef& a, const ssef& b) {
- return reduce_add(a*b);
+__forceinline float dot(const ssef &a, const ssef &b)
+{
+ return reduce_add(a * b);
}
/* calculate shuffled cross product, useful when order of components does not matter */
-__forceinline ssef cross_zxy(const ssef& a, const ssef& b)
+__forceinline ssef cross_zxy(const ssef &a, const ssef &b)
{
- const ssef a0 = a;
- const ssef b0 = shuffle<1,2,0,3>(b);
- const ssef a1 = shuffle<1,2,0,3>(a);
- const ssef b1 = b;
- return msub(a0,b0,a1*b1);
+ const ssef a0 = a;
+ const ssef b0 = shuffle<1, 2, 0, 3>(b);
+ const ssef a1 = shuffle<1, 2, 0, 3>(a);
+ const ssef b1 = b;
+ return msub(a0, b0, a1 * b1);
}
-__forceinline ssef cross(const ssef& a, const ssef& b)
+__forceinline ssef cross(const ssef &a, const ssef &b)
{
- return shuffle<1,2,0,3>(cross_zxy(a, b));
+ return shuffle<1, 2, 0, 3>(cross_zxy(a, b));
}
-ccl_device_inline const ssef dot3_splat(const ssef& a, const ssef& b)
+ccl_device_inline const ssef dot3_splat(const ssef &a, const ssef &b)
{
-#ifdef __KERNEL_SSE41__
- return _mm_dp_ps(a.m128, b.m128, 0x7f);
-#else
- ssef t = a * b;
- return ssef(((float*)&t)[0] + ((float*)&t)[1] + ((float*)&t)[2]);
-#endif
+# ifdef __KERNEL_SSE41__
+ return _mm_dp_ps(a.m128, b.m128, 0x7f);
+# else
+ ssef t = a * b;
+ return ssef(((float *)&t)[0] + ((float *)&t)[1] + ((float *)&t)[2]);
+# endif
}
/* squared length taking only specified axes into account */
-template<size_t X, size_t Y, size_t Z, size_t W>
-ccl_device_inline float len_squared(const ssef& a)
-{
-#ifndef __KERNEL_SSE41__
- float4& t = (float4 &)a;
- return (X ? t.x * t.x : 0.0f) + (Y ? t.y * t.y : 0.0f) + (Z ? t.z * t.z : 0.0f) + (W ? t.w * t.w : 0.0f);
-#else
- return extract<0>(ssef(_mm_dp_ps(a.m128, a.m128, (X << 4) | (Y << 5) | (Z << 6) | (W << 7) | 0xf)));
-#endif
+template<size_t X, size_t Y, size_t Z, size_t W> ccl_device_inline float len_squared(const ssef &a)
+{
+# ifndef __KERNEL_SSE41__
+ float4 &t = (float4 &)a;
+ return (X ? t.x * t.x : 0.0f) + (Y ? t.y * t.y : 0.0f) + (Z ? t.z * t.z : 0.0f) +
+ (W ? t.w * t.w : 0.0f);
+# else
+ return extract<0>(
+ ssef(_mm_dp_ps(a.m128, a.m128, (X << 4) | (Y << 5) | (Z << 6) | (W << 7) | 0xf)));
+# endif
}
-ccl_device_inline float dot3(const ssef& a, const ssef& b)
+ccl_device_inline float dot3(const ssef &a, const ssef &b)
{
-#ifdef __KERNEL_SSE41__
- return extract<0>(ssef(_mm_dp_ps(a.m128, b.m128, 0x7f)));
-#else
- ssef t = a * b;
- return ((float*)&t)[0] + ((float*)&t)[1] + ((float*)&t)[2];
-#endif
+# ifdef __KERNEL_SSE41__
+ return extract<0>(ssef(_mm_dp_ps(a.m128, b.m128, 0x7f)));
+# else
+ ssef t = a * b;
+ return ((float *)&t)[0] + ((float *)&t)[1] + ((float *)&t)[2];
+# endif
}
-ccl_device_inline const ssef len3_squared_splat(const ssef& a)
+ccl_device_inline const ssef len3_squared_splat(const ssef &a)
{
- return dot3_splat(a, a);
+ return dot3_splat(a, a);
}
-ccl_device_inline float len3_squared(const ssef& a)
+ccl_device_inline float len3_squared(const ssef &a)
{
- return dot3(a, a);
+ return dot3(a, a);
}
-ccl_device_inline float len3(const ssef& a)
+ccl_device_inline float len3(const ssef &a)
{
- return extract<0>(mm_sqrt(dot3_splat(a, a)));
+ return extract<0>(mm_sqrt(dot3_splat(a, a)));
}
/* SSE shuffle utility functions */
-#ifdef __KERNEL_SSSE3__
+# ifdef __KERNEL_SSSE3__
/* faster version for SSSE3 */
typedef ssei shuffle_swap_t;
ccl_device_inline shuffle_swap_t shuffle_swap_identity()
{
- return _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+ return _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
}
ccl_device_inline shuffle_swap_t shuffle_swap_swap()
{
- return _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+ return _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
}
-ccl_device_inline const ssef shuffle_swap(const ssef& a, const shuffle_swap_t& shuf)
+ccl_device_inline const ssef shuffle_swap(const ssef &a, const shuffle_swap_t &shuf)
{
- return cast(_mm_shuffle_epi8(cast(a), shuf));
+ return cast(_mm_shuffle_epi8(cast(a), shuf));
}
-#else
+# else
/* somewhat slower version for SSE2 */
typedef int shuffle_swap_t;
ccl_device_inline shuffle_swap_t shuffle_swap_identity()
{
- return 0;
+ return 0;
}
ccl_device_inline shuffle_swap_t shuffle_swap_swap()
{
- return 1;
+ return 1;
}
-ccl_device_inline const ssef shuffle_swap(const ssef& a, shuffle_swap_t shuf)
+ccl_device_inline const ssef shuffle_swap(const ssef &a, shuffle_swap_t shuf)
{
- /* shuffle value must be a constant, so we need to branch */
- if(shuf)
- return ssef(_mm_shuffle_ps(a.m128, a.m128, _MM_SHUFFLE(1, 0, 3, 2)));
- else
- return ssef(_mm_shuffle_ps(a.m128, a.m128, _MM_SHUFFLE(3, 2, 1, 0)));
+ /* shuffle value must be a constant, so we need to branch */
+ if (shuf)
+ return ssef(_mm_shuffle_ps(a.m128, a.m128, _MM_SHUFFLE(1, 0, 3, 2)));
+ else
+ return ssef(_mm_shuffle_ps(a.m128, a.m128, _MM_SHUFFLE(3, 2, 1, 0)));
}
-#endif
+# endif
-#ifdef __KERNEL_SSE41__
+# ifdef __KERNEL_SSE41__
-ccl_device_inline void gen_idirsplat_swap(const ssef &pn, const shuffle_swap_t &shuf_identity, const shuffle_swap_t &shuf_swap,
- const float3& idir, ssef idirsplat[3], shuffle_swap_t shufflexyz[3])
+ccl_device_inline void gen_idirsplat_swap(const ssef &pn,
+ const shuffle_swap_t &shuf_identity,
+ const shuffle_swap_t &shuf_swap,
+ const float3 &idir,
+ ssef idirsplat[3],
+ shuffle_swap_t shufflexyz[3])
{
- const __m128 idirsplat_raw[] = { _mm_set_ps1(idir.x), _mm_set_ps1(idir.y), _mm_set_ps1(idir.z) };
- idirsplat[0] = _mm_xor_ps(idirsplat_raw[0], pn);
- idirsplat[1] = _mm_xor_ps(idirsplat_raw[1], pn);
- idirsplat[2] = _mm_xor_ps(idirsplat_raw[2], pn);
-
- const ssef signmask = cast(ssei(0x80000000));
- const ssef shuf_identity_f = cast(shuf_identity);
- const ssef shuf_swap_f = cast(shuf_swap);
-
- shufflexyz[0] = _mm_castps_si128(_mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[0], signmask)));
- shufflexyz[1] = _mm_castps_si128(_mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[1], signmask)));
- shufflexyz[2] = _mm_castps_si128(_mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[2], signmask)));
-}
-
-#else
-
-ccl_device_inline void gen_idirsplat_swap(const ssef &pn, const shuffle_swap_t &shuf_identity, const shuffle_swap_t &shuf_swap,
- const float3& idir, ssef idirsplat[3], shuffle_swap_t shufflexyz[3])
+ const __m128 idirsplat_raw[] = {_mm_set_ps1(idir.x), _mm_set_ps1(idir.y), _mm_set_ps1(idir.z)};
+ idirsplat[0] = _mm_xor_ps(idirsplat_raw[0], pn);
+ idirsplat[1] = _mm_xor_ps(idirsplat_raw[1], pn);
+ idirsplat[2] = _mm_xor_ps(idirsplat_raw[2], pn);
+
+ const ssef signmask = cast(ssei(0x80000000));
+ const ssef shuf_identity_f = cast(shuf_identity);
+ const ssef shuf_swap_f = cast(shuf_swap);
+
+ shufflexyz[0] = _mm_castps_si128(
+ _mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[0], signmask)));
+ shufflexyz[1] = _mm_castps_si128(
+ _mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[1], signmask)));
+ shufflexyz[2] = _mm_castps_si128(
+ _mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[2], signmask)));
+}
+
+# else
+
+ccl_device_inline void gen_idirsplat_swap(const ssef &pn,
+ const shuffle_swap_t &shuf_identity,
+ const shuffle_swap_t &shuf_swap,
+ const float3 &idir,
+ ssef idirsplat[3],
+ shuffle_swap_t shufflexyz[3])
{
- idirsplat[0] = ssef(idir.x) ^ pn;
- idirsplat[1] = ssef(idir.y) ^ pn;
- idirsplat[2] = ssef(idir.z) ^ pn;
+ idirsplat[0] = ssef(idir.x) ^ pn;
+ idirsplat[1] = ssef(idir.y) ^ pn;
+ idirsplat[2] = ssef(idir.z) ^ pn;
- shufflexyz[0] = (idir.x >= 0)? shuf_identity: shuf_swap;
- shufflexyz[1] = (idir.y >= 0)? shuf_identity: shuf_swap;
- shufflexyz[2] = (idir.z >= 0)? shuf_identity: shuf_swap;
+ shufflexyz[0] = (idir.x >= 0) ? shuf_identity : shuf_swap;
+ shufflexyz[1] = (idir.y >= 0) ? shuf_identity : shuf_swap;
+ shufflexyz[2] = (idir.z >= 0) ? shuf_identity : shuf_swap;
}
-#endif
+# endif
ccl_device_inline const ssef uint32_to_float(const ssei &in)
{
- ssei a = _mm_srli_epi32(in, 16);
- ssei b = _mm_and_si128(in, _mm_set1_epi32(0x0000ffff));
- ssei c = _mm_or_si128(a, _mm_set1_epi32(0x53000000));
- ssef d = _mm_cvtepi32_ps(b);
- ssef e = _mm_sub_ps(_mm_castsi128_ps(c), _mm_castsi128_ps(_mm_set1_epi32(0x53000000)));
- return _mm_add_ps(e, d);
+ ssei a = _mm_srli_epi32(in, 16);
+ ssei b = _mm_and_si128(in, _mm_set1_epi32(0x0000ffff));
+ ssei c = _mm_or_si128(a, _mm_set1_epi32(0x53000000));
+ ssef d = _mm_cvtepi32_ps(b);
+ ssef e = _mm_sub_ps(_mm_castsi128_ps(c), _mm_castsi128_ps(_mm_set1_epi32(0x53000000)));
+ return _mm_add_ps(e, d);
}
template<size_t S1, size_t S2, size_t S3, size_t S4>
ccl_device_inline const ssef set_sign_bit(const ssef &a)
{
- return cast(cast(a) ^ ssei(S1 << 31, S2 << 31, S3 << 31, S4 << 31));
+ return cast(cast(a) ^ ssei(S1 << 31, S2 << 31, S3 << 31, S4 << 31));
}
////////////////////////////////////////////////////////////////////////////////
@@ -615,12 +999,8 @@ ccl_device_inline const ssef set_sign_bit(const ssef &a)
ccl_device_inline void print_ssef(const char *label, const ssef &a)
{
- printf("%s: %.8f %.8f %.8f %.8f\n",
- label,
- (double)a[0],
- (double)a[1],
- (double)a[2],
- (double)a[3]);
+ printf(
+ "%s: %.8f %.8f %.8f %.8f\n", label, (double)a[0], (double)a[1], (double)a[2], (double)a[3]);
}
#endif
diff --git a/intern/cycles/util/util_ssei.h b/intern/cycles/util/util_ssei.h
index ba0389cd114..86429260a0e 100644
--- a/intern/cycles/util/util_ssei.h
+++ b/intern/cycles/util/util_ssei.h
@@ -26,263 +26,576 @@ struct sseb;
struct ssef;
/*! 4-wide SSE integer type. */
-struct ssei
-{
- typedef sseb Mask; // mask type
- typedef ssei Int; // int type
- typedef ssef Float; // float type
-
- enum { size = 4 }; // number of SIMD elements
- union { __m128i m128; int32_t i[4]; }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline ssei ( ) {}
- __forceinline ssei ( const ssei& a ) { m128 = a.m128; }
- __forceinline ssei& operator=( const ssei& a ) { m128 = a.m128; return *this; }
-
- __forceinline ssei( const __m128i a ) : m128(a) {}
- __forceinline operator const __m128i&( void ) const { return m128; }
- __forceinline operator __m128i&( void ) { return m128; }
-
- __forceinline ssei ( const int a ) : m128(_mm_set1_epi32(a)) {}
- __forceinline ssei ( int a, int b, int c, int d ) : m128(_mm_setr_epi32(a, b, c, d)) {}
-
- __forceinline explicit ssei( const __m128 a ) : m128(_mm_cvtps_epi32(a)) {}
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline const int32_t& operator []( const size_t index ) const { assert(index < 4); return i[index]; }
- __forceinline int32_t& operator []( const size_t index ) { assert(index < 4); return i[index]; }
+struct ssei {
+ typedef sseb Mask; // mask type
+ typedef ssei Int; // int type
+ typedef ssef Float; // float type
+
+ enum { size = 4 }; // number of SIMD elements
+ union {
+ __m128i m128;
+ int32_t i[4];
+ }; // data
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Constructors, Assignment & Cast Operators
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline ssei()
+ {
+ }
+ __forceinline ssei(const ssei &a)
+ {
+ m128 = a.m128;
+ }
+ __forceinline ssei &operator=(const ssei &a)
+ {
+ m128 = a.m128;
+ return *this;
+ }
+
+ __forceinline ssei(const __m128i a) : m128(a)
+ {
+ }
+ __forceinline operator const __m128i &(void)const
+ {
+ return m128;
+ }
+ __forceinline operator __m128i &(void)
+ {
+ return m128;
+ }
+
+ __forceinline ssei(const int a) : m128(_mm_set1_epi32(a))
+ {
+ }
+ __forceinline ssei(int a, int b, int c, int d) : m128(_mm_setr_epi32(a, b, c, d))
+ {
+ }
+
+ __forceinline explicit ssei(const __m128 a) : m128(_mm_cvtps_epi32(a))
+ {
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// Array Access
+ ////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline const int32_t &operator[](const size_t index) const
+ {
+ assert(index < 4);
+ return i[index];
+ }
+ __forceinline int32_t &operator[](const size_t index)
+ {
+ assert(index < 4);
+ return i[index];
+ }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const ssei cast ( const __m128& a ) { return _mm_castps_si128(a); }
-__forceinline const ssei operator +( const ssei& a ) { return a; }
-__forceinline const ssei operator -( const ssei& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); }
-#if defined(__KERNEL_SSSE3__)
-__forceinline const ssei abs ( const ssei& a ) { return _mm_abs_epi32(a.m128); }
-#endif
+__forceinline const ssei cast(const __m128 &a)
+{
+ return _mm_castps_si128(a);
+}
+__forceinline const ssei operator+(const ssei &a)
+{
+ return a;
+}
+__forceinline const ssei operator-(const ssei &a)
+{
+ return _mm_sub_epi32(_mm_setzero_si128(), a.m128);
+}
+# if defined(__KERNEL_SSSE3__)
+__forceinline const ssei abs(const ssei &a)
+{
+ return _mm_abs_epi32(a.m128);
+}
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline const ssei operator +( const ssei& a, const ssei& b ) { return _mm_add_epi32(a.m128, b.m128); }
-__forceinline const ssei operator +( const ssei& a, const int32_t& b ) { return a + ssei(b); }
-__forceinline const ssei operator +( const int32_t& a, const ssei& b ) { return ssei(a) + b; }
+__forceinline const ssei operator+(const ssei &a, const ssei &b)
+{
+ return _mm_add_epi32(a.m128, b.m128);
+}
+__forceinline const ssei operator+(const ssei &a, const int32_t &b)
+{
+ return a + ssei(b);
+}
+__forceinline const ssei operator+(const int32_t &a, const ssei &b)
+{
+ return ssei(a) + b;
+}
-__forceinline const ssei operator -( const ssei& a, const ssei& b ) { return _mm_sub_epi32(a.m128, b.m128); }
-__forceinline const ssei operator -( const ssei& a, const int32_t& b ) { return a - ssei(b); }
-__forceinline const ssei operator -( const int32_t& a, const ssei& b ) { return ssei(a) - b; }
+__forceinline const ssei operator-(const ssei &a, const ssei &b)
+{
+ return _mm_sub_epi32(a.m128, b.m128);
+}
+__forceinline const ssei operator-(const ssei &a, const int32_t &b)
+{
+ return a - ssei(b);
+}
+__forceinline const ssei operator-(const int32_t &a, const ssei &b)
+{
+ return ssei(a) - b;
+}
-#if defined(__KERNEL_SSE41__)
-__forceinline const ssei operator *( const ssei& a, const ssei& b ) { return _mm_mullo_epi32(a.m128, b.m128); }
-__forceinline const ssei operator *( const ssei& a, const int32_t& b ) { return a * ssei(b); }
-__forceinline const ssei operator *( const int32_t& a, const ssei& b ) { return ssei(a) * b; }
-#endif
+# if defined(__KERNEL_SSE41__)
+__forceinline const ssei operator*(const ssei &a, const ssei &b)
+{
+ return _mm_mullo_epi32(a.m128, b.m128);
+}
+__forceinline const ssei operator*(const ssei &a, const int32_t &b)
+{
+ return a * ssei(b);
+}
+__forceinline const ssei operator*(const int32_t &a, const ssei &b)
+{
+ return ssei(a) * b;
+}
+# endif
-__forceinline const ssei operator &( const ssei& a, const ssei& b ) { return _mm_and_si128(a.m128, b.m128); }
-__forceinline const ssei operator &( const ssei& a, const int32_t& b ) { return a & ssei(b); }
-__forceinline const ssei operator &( const int32_t& a, const ssei& b ) { return ssei(a) & b; }
+__forceinline const ssei operator&(const ssei &a, const ssei &b)
+{
+ return _mm_and_si128(a.m128, b.m128);
+}
+__forceinline const ssei operator&(const ssei &a, const int32_t &b)
+{
+ return a & ssei(b);
+}
+__forceinline const ssei operator&(const int32_t &a, const ssei &b)
+{
+ return ssei(a) & b;
+}
-__forceinline const ssei operator |( const ssei& a, const ssei& b ) { return _mm_or_si128(a.m128, b.m128); }
-__forceinline const ssei operator |( const ssei& a, const int32_t& b ) { return a | ssei(b); }
-__forceinline const ssei operator |( const int32_t& a, const ssei& b ) { return ssei(a) | b; }
+__forceinline const ssei operator|(const ssei &a, const ssei &b)
+{
+ return _mm_or_si128(a.m128, b.m128);
+}
+__forceinline const ssei operator|(const ssei &a, const int32_t &b)
+{
+ return a | ssei(b);
+}
+__forceinline const ssei operator|(const int32_t &a, const ssei &b)
+{
+ return ssei(a) | b;
+}
-__forceinline const ssei operator ^( const ssei& a, const ssei& b ) { return _mm_xor_si128(a.m128, b.m128); }
-__forceinline const ssei operator ^( const ssei& a, const int32_t& b ) { return a ^ ssei(b); }
-__forceinline const ssei operator ^( const int32_t& a, const ssei& b ) { return ssei(a) ^ b; }
+__forceinline const ssei operator^(const ssei &a, const ssei &b)
+{
+ return _mm_xor_si128(a.m128, b.m128);
+}
+__forceinline const ssei operator^(const ssei &a, const int32_t &b)
+{
+ return a ^ ssei(b);
+}
+__forceinline const ssei operator^(const int32_t &a, const ssei &b)
+{
+ return ssei(a) ^ b;
+}
-__forceinline const ssei operator <<( const ssei& a, const int32_t& n ) { return _mm_slli_epi32(a.m128, n); }
-__forceinline const ssei operator >>( const ssei& a, const int32_t& n ) { return _mm_srai_epi32(a.m128, n); }
+__forceinline const ssei operator<<(const ssei &a, const int32_t &n)
+{
+ return _mm_slli_epi32(a.m128, n);
+}
+__forceinline const ssei operator>>(const ssei &a, const int32_t &n)
+{
+ return _mm_srai_epi32(a.m128, n);
+}
-__forceinline const ssei andnot(const ssei& a, const ssei& b) { return _mm_andnot_si128(a.m128,b.m128); }
-__forceinline const ssei andnot(const sseb& a, const ssei& b) { return _mm_andnot_si128(cast(a.m128),b.m128); }
-__forceinline const ssei andnot(const ssei& a, const sseb& b) { return _mm_andnot_si128(a.m128,cast(b.m128)); }
+__forceinline const ssei andnot(const ssei &a, const ssei &b)
+{
+ return _mm_andnot_si128(a.m128, b.m128);
+}
+__forceinline const ssei andnot(const sseb &a, const ssei &b)
+{
+ return _mm_andnot_si128(cast(a.m128), b.m128);
+}
+__forceinline const ssei andnot(const ssei &a, const sseb &b)
+{
+ return _mm_andnot_si128(a.m128, cast(b.m128));
+}
-__forceinline const ssei sra ( const ssei& a, const int32_t& b ) { return _mm_srai_epi32(a.m128, b); }
-__forceinline const ssei srl ( const ssei& a, const int32_t& b ) { return _mm_srli_epi32(a.m128, b); }
+__forceinline const ssei sra(const ssei &a, const int32_t &b)
+{
+ return _mm_srai_epi32(a.m128, b);
+}
+__forceinline const ssei srl(const ssei &a, const int32_t &b)
+{
+ return _mm_srli_epi32(a.m128, b);
+}
-#if defined(__KERNEL_SSE41__)
-__forceinline const ssei min( const ssei& a, const ssei& b ) { return _mm_min_epi32(a.m128, b.m128); }
-__forceinline const ssei min( const ssei& a, const int32_t& b ) { return min(a,ssei(b)); }
-__forceinline const ssei min( const int32_t& a, const ssei& b ) { return min(ssei(a),b); }
+# if defined(__KERNEL_SSE41__)
+__forceinline const ssei min(const ssei &a, const ssei &b)
+{
+ return _mm_min_epi32(a.m128, b.m128);
+}
+__forceinline const ssei min(const ssei &a, const int32_t &b)
+{
+ return min(a, ssei(b));
+}
+__forceinline const ssei min(const int32_t &a, const ssei &b)
+{
+ return min(ssei(a), b);
+}
-__forceinline const ssei max( const ssei& a, const ssei& b ) { return _mm_max_epi32(a.m128, b.m128); }
-__forceinline const ssei max( const ssei& a, const int32_t& b ) { return max(a,ssei(b)); }
-__forceinline const ssei max( const int32_t& a, const ssei& b ) { return max(ssei(a),b); }
-#endif
+__forceinline const ssei max(const ssei &a, const ssei &b)
+{
+ return _mm_max_epi32(a.m128, b.m128);
+}
+__forceinline const ssei max(const ssei &a, const int32_t &b)
+{
+ return max(a, ssei(b));
+}
+__forceinline const ssei max(const int32_t &a, const ssei &b)
+{
+ return max(ssei(a), b);
+}
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
-__forceinline ssei& operator +=( ssei& a, const ssei& b ) { return a = a + b; }
-__forceinline ssei& operator +=( ssei& a, const int32_t& b ) { return a = a + b; }
+__forceinline ssei &operator+=(ssei &a, const ssei &b)
+{
+ return a = a + b;
+}
+__forceinline ssei &operator+=(ssei &a, const int32_t &b)
+{
+ return a = a + b;
+}
-__forceinline ssei& operator -=( ssei& a, const ssei& b ) { return a = a - b; }
-__forceinline ssei& operator -=( ssei& a, const int32_t& b ) { return a = a - b; }
+__forceinline ssei &operator-=(ssei &a, const ssei &b)
+{
+ return a = a - b;
+}
+__forceinline ssei &operator-=(ssei &a, const int32_t &b)
+{
+ return a = a - b;
+}
-#if defined(__KERNEL_SSE41__)
-__forceinline ssei& operator *=( ssei& a, const ssei& b ) { return a = a * b; }
-__forceinline ssei& operator *=( ssei& a, const int32_t& b ) { return a = a * b; }
-#endif
+# if defined(__KERNEL_SSE41__)
+__forceinline ssei &operator*=(ssei &a, const ssei &b)
+{
+ return a = a * b;
+}
+__forceinline ssei &operator*=(ssei &a, const int32_t &b)
+{
+ return a = a * b;
+}
+# endif
-__forceinline ssei& operator &=( ssei& a, const ssei& b ) { return a = a & b; }
-__forceinline ssei& operator &=( ssei& a, const int32_t& b ) { return a = a & b; }
+__forceinline ssei &operator&=(ssei &a, const ssei &b)
+{
+ return a = a & b;
+}
+__forceinline ssei &operator&=(ssei &a, const int32_t &b)
+{
+ return a = a & b;
+}
-__forceinline ssei& operator |=( ssei& a, const ssei& b ) { return a = a | b; }
-__forceinline ssei& operator |=( ssei& a, const int32_t& b ) { return a = a | b; }
+__forceinline ssei &operator|=(ssei &a, const ssei &b)
+{
+ return a = a | b;
+}
+__forceinline ssei &operator|=(ssei &a, const int32_t &b)
+{
+ return a = a | b;
+}
-__forceinline ssei& operator <<=( ssei& a, const int32_t& b ) { return a = a << b; }
-__forceinline ssei& operator >>=( ssei& a, const int32_t& b ) { return a = a >> b; }
+__forceinline ssei &operator<<=(ssei &a, const int32_t &b)
+{
+ return a = a << b;
+}
+__forceinline ssei &operator>>=(ssei &a, const int32_t &b)
+{
+ return a = a >> b;
+}
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
-__forceinline const sseb operator ==( const ssei& a, const ssei& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32 (a.m128, b.m128)); }
-__forceinline const sseb operator ==( const ssei& a, const int32_t& b ) { return a == ssei(b); }
-__forceinline const sseb operator ==( const int32_t& a, const ssei& b ) { return ssei(a) == b; }
+__forceinline const sseb operator==(const ssei &a, const ssei &b)
+{
+ return _mm_castsi128_ps(_mm_cmpeq_epi32(a.m128, b.m128));
+}
+__forceinline const sseb operator==(const ssei &a, const int32_t &b)
+{
+ return a == ssei(b);
+}
+__forceinline const sseb operator==(const int32_t &a, const ssei &b)
+{
+ return ssei(a) == b;
+}
-__forceinline const sseb operator !=( const ssei& a, const ssei& b ) { return !(a == b); }
-__forceinline const sseb operator !=( const ssei& a, const int32_t& b ) { return a != ssei(b); }
-__forceinline const sseb operator !=( const int32_t& a, const ssei& b ) { return ssei(a) != b; }
+__forceinline const sseb operator!=(const ssei &a, const ssei &b)
+{
+ return !(a == b);
+}
+__forceinline const sseb operator!=(const ssei &a, const int32_t &b)
+{
+ return a != ssei(b);
+}
+__forceinline const sseb operator!=(const int32_t &a, const ssei &b)
+{
+ return ssei(a) != b;
+}
-__forceinline const sseb operator < ( const ssei& a, const ssei& b ) { return _mm_castsi128_ps(_mm_cmplt_epi32 (a.m128, b.m128)); }
-__forceinline const sseb operator < ( const ssei& a, const int32_t& b ) { return a < ssei(b); }
-__forceinline const sseb operator < ( const int32_t& a, const ssei& b ) { return ssei(a) < b; }
+__forceinline const sseb operator<(const ssei &a, const ssei &b)
+{
+ return _mm_castsi128_ps(_mm_cmplt_epi32(a.m128, b.m128));
+}
+__forceinline const sseb operator<(const ssei &a, const int32_t &b)
+{
+ return a < ssei(b);
+}
+__forceinline const sseb operator<(const int32_t &a, const ssei &b)
+{
+ return ssei(a) < b;
+}
-__forceinline const sseb operator >=( const ssei& a, const ssei& b ) { return !(a < b); }
-__forceinline const sseb operator >=( const ssei& a, const int32_t& b ) { return a >= ssei(b); }
-__forceinline const sseb operator >=( const int32_t& a, const ssei& b ) { return ssei(a) >= b; }
+__forceinline const sseb operator>=(const ssei &a, const ssei &b)
+{
+ return !(a < b);
+}
+__forceinline const sseb operator>=(const ssei &a, const int32_t &b)
+{
+ return a >= ssei(b);
+}
+__forceinline const sseb operator>=(const int32_t &a, const ssei &b)
+{
+ return ssei(a) >= b;
+}
-__forceinline const sseb operator > ( const ssei& a, const ssei& b ) { return _mm_castsi128_ps(_mm_cmpgt_epi32 (a.m128, b.m128)); }
-__forceinline const sseb operator > ( const ssei& a, const int32_t& b ) { return a > ssei(b); }
-__forceinline const sseb operator > ( const int32_t& a, const ssei& b ) { return ssei(a) > b; }
+__forceinline const sseb operator>(const ssei &a, const ssei &b)
+{
+ return _mm_castsi128_ps(_mm_cmpgt_epi32(a.m128, b.m128));
+}
+__forceinline const sseb operator>(const ssei &a, const int32_t &b)
+{
+ return a > ssei(b);
+}
+__forceinline const sseb operator>(const int32_t &a, const ssei &b)
+{
+ return ssei(a) > b;
+}
-__forceinline const sseb operator <=( const ssei& a, const ssei& b ) { return !(a > b); }
-__forceinline const sseb operator <=( const ssei& a, const int32_t& b ) { return a <= ssei(b); }
-__forceinline const sseb operator <=( const int32_t& a, const ssei& b ) { return ssei(a) <= b; }
+__forceinline const sseb operator<=(const ssei &a, const ssei &b)
+{
+ return !(a > b);
+}
+__forceinline const sseb operator<=(const ssei &a, const int32_t &b)
+{
+ return a <= ssei(b);
+}
+__forceinline const sseb operator<=(const int32_t &a, const ssei &b)
+{
+ return ssei(a) <= b;
+}
-__forceinline const ssei select( const sseb& m, const ssei& t, const ssei& f ) {
-#ifdef __KERNEL_SSE41__
- return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m));
-#else
- return _mm_or_si128(_mm_and_si128(m, t), _mm_andnot_si128(m, f));
-#endif
+__forceinline const ssei select(const sseb &m, const ssei &t, const ssei &f)
+{
+# ifdef __KERNEL_SSE41__
+ return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m));
+# else
+ return _mm_or_si128(_mm_and_si128(m, t), _mm_andnot_si128(m, f));
+# endif
}
-__forceinline const ssei select( const int mask, const ssei& t, const ssei& f ) {
-#if defined(__KERNEL_SSE41__) && ((!defined(__clang__) && !defined(_MSC_VER)) || defined(__INTEL_COMPILER))
- return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask));
-#else
- return select(sseb(mask),t,f);
-#endif
+__forceinline const ssei select(const int mask, const ssei &t, const ssei &f)
+{
+# if defined(__KERNEL_SSE41__) && \
+ ((!defined(__clang__) && !defined(_MSC_VER)) || defined(__INTEL_COMPILER))
+ return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask));
+# else
+ return select(sseb(mask), t, f);
+# endif
}
////////////////////////////////////////////////////////////////////////////////
// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
-__forceinline ssei unpacklo( const ssei& a, const ssei& b ) { return _mm_unpacklo_epi32(a, b); }
-__forceinline ssei unpackhi( const ssei& a, const ssei& b ) { return _mm_unpackhi_epi32(a, b); }
+__forceinline ssei unpacklo(const ssei &a, const ssei &b)
+{
+ return _mm_unpacklo_epi32(a, b);
+}
+__forceinline ssei unpackhi(const ssei &a, const ssei &b)
+{
+ return _mm_unpackhi_epi32(a, b);
+}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssei shuffle( const ssei& a ) {
- return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const ssei shuffle(const ssei &a)
+{
+ return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
}
-template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssei shuffle( const ssei& a, const ssei& b ) {
- return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const ssei shuffle(const ssei &a, const ssei &b)
+{
+ return _mm_castps_si128(
+ _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
}
-template<size_t i0> __forceinline const ssei shuffle( const ssei& b ) {
- return shuffle<i0,i0,i0,i0>(b);
+template<size_t i0> __forceinline const ssei shuffle(const ssei &b)
+{
+ return shuffle<i0, i0, i0, i0>(b);
}
-#if defined(__KERNEL_SSE41__)
-template<size_t src> __forceinline int extract( const ssei& b ) { return _mm_extract_epi32(b, src); }
-template<size_t dst> __forceinline const ssei insert( const ssei& a, const int32_t b ) { return _mm_insert_epi32(a, b, dst); }
-#else
-template<size_t src> __forceinline int extract( const ssei& b ) { return b[src]; }
-template<size_t dst> __forceinline const ssei insert( const ssei& a, const int32_t b ) { ssei c = a; c[dst] = b; return c; }
-#endif
+# if defined(__KERNEL_SSE41__)
+template<size_t src> __forceinline int extract(const ssei &b)
+{
+ return _mm_extract_epi32(b, src);
+}
+template<size_t dst> __forceinline const ssei insert(const ssei &a, const int32_t b)
+{
+ return _mm_insert_epi32(a, b, dst);
+}
+# else
+template<size_t src> __forceinline int extract(const ssei &b)
+{
+ return b[src];
+}
+template<size_t dst> __forceinline const ssei insert(const ssei &a, const int32_t b)
+{
+ ssei c = a;
+ c[dst] = b;
+ return c;
+}
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Reductions
////////////////////////////////////////////////////////////////////////////////
-#if defined(__KERNEL_SSE41__)
-__forceinline const ssei vreduce_min(const ssei& v) { ssei h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
-__forceinline const ssei vreduce_max(const ssei& v) { ssei h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
-__forceinline const ssei vreduce_add(const ssei& v) { ssei h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
+# if defined(__KERNEL_SSE41__)
+__forceinline const ssei vreduce_min(const ssei &v)
+{
+ ssei h = min(shuffle<1, 0, 3, 2>(v), v);
+ return min(shuffle<2, 3, 0, 1>(h), h);
+}
+__forceinline const ssei vreduce_max(const ssei &v)
+{
+ ssei h = max(shuffle<1, 0, 3, 2>(v), v);
+ return max(shuffle<2, 3, 0, 1>(h), h);
+}
+__forceinline const ssei vreduce_add(const ssei &v)
+{
+ ssei h = shuffle<1, 0, 3, 2>(v) + v;
+ return shuffle<2, 3, 0, 1>(h) + h;
+}
-__forceinline int reduce_min(const ssei& v) { return extract<0>(vreduce_min(v)); }
-__forceinline int reduce_max(const ssei& v) { return extract<0>(vreduce_max(v)); }
-__forceinline int reduce_add(const ssei& v) { return extract<0>(vreduce_add(v)); }
+__forceinline int reduce_min(const ssei &v)
+{
+ return extract<0>(vreduce_min(v));
+}
+__forceinline int reduce_max(const ssei &v)
+{
+ return extract<0>(vreduce_max(v));
+}
+__forceinline int reduce_add(const ssei &v)
+{
+ return extract<0>(vreduce_add(v));
+}
-__forceinline size_t select_min(const ssei& v) { return __bsf(movemask(v == vreduce_min(v))); }
-__forceinline size_t select_max(const ssei& v) { return __bsf(movemask(v == vreduce_max(v))); }
+__forceinline size_t select_min(const ssei &v)
+{
+ return __bsf(movemask(v == vreduce_min(v)));
+}
+__forceinline size_t select_max(const ssei &v)
+{
+ return __bsf(movemask(v == vreduce_max(v)));
+}
-__forceinline size_t select_min(const sseb& valid, const ssei& v) { const ssei a = select(valid,v,ssei((int)pos_inf)); return __bsf(movemask(valid & (a == vreduce_min(a)))); }
-__forceinline size_t select_max(const sseb& valid, const ssei& v) { const ssei a = select(valid,v,ssei((int)neg_inf)); return __bsf(movemask(valid & (a == vreduce_max(a)))); }
+__forceinline size_t select_min(const sseb &valid, const ssei &v)
+{
+ const ssei a = select(valid, v, ssei((int)pos_inf));
+ return __bsf(movemask(valid & (a == vreduce_min(a))));
+}
+__forceinline size_t select_max(const sseb &valid, const ssei &v)
+{
+ const ssei a = select(valid, v, ssei((int)neg_inf));
+ return __bsf(movemask(valid & (a == vreduce_max(a))));
+}
-#else
+# else
-__forceinline int ssei_min(int a, int b) { return (a < b)? a: b; }
-__forceinline int ssei_max(int a, int b) { return (a > b)? a: b; }
-__forceinline int reduce_min(const ssei& v) { return ssei_min(ssei_min(v[0],v[1]),ssei_min(v[2],v[3])); }
-__forceinline int reduce_max(const ssei& v) { return ssei_max(ssei_max(v[0],v[1]),ssei_max(v[2],v[3])); }
-__forceinline int reduce_add(const ssei& v) { return v[0]+v[1]+v[2]+v[3]; }
+__forceinline int ssei_min(int a, int b)
+{
+ return (a < b) ? a : b;
+}
+__forceinline int ssei_max(int a, int b)
+{
+ return (a > b) ? a : b;
+}
+__forceinline int reduce_min(const ssei &v)
+{
+ return ssei_min(ssei_min(v[0], v[1]), ssei_min(v[2], v[3]));
+}
+__forceinline int reduce_max(const ssei &v)
+{
+ return ssei_max(ssei_max(v[0], v[1]), ssei_max(v[2], v[3]));
+}
+__forceinline int reduce_add(const ssei &v)
+{
+ return v[0] + v[1] + v[2] + v[3];
+}
-#endif
+# endif
////////////////////////////////////////////////////////////////////////////////
/// Memory load and store operations
////////////////////////////////////////////////////////////////////////////////
-__forceinline ssei load4i( const void* const a ) {
- return _mm_load_si128((__m128i*)a);
+__forceinline ssei load4i(const void *const a)
+{
+ return _mm_load_si128((__m128i *)a);
}
-__forceinline void store4i(void* ptr, const ssei& v) {
- _mm_store_si128((__m128i*)ptr,v);
+__forceinline void store4i(void *ptr, const ssei &v)
+{
+ _mm_store_si128((__m128i *)ptr, v);
}
-__forceinline void storeu4i(void* ptr, const ssei& v) {
- _mm_storeu_si128((__m128i*)ptr,v);
+__forceinline void storeu4i(void *ptr, const ssei &v)
+{
+ _mm_storeu_si128((__m128i *)ptr, v);
}
-__forceinline void store4i( const sseb& mask, void* ptr, const ssei& i ) {
-#if defined (__KERNEL_AVX__)
- _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i));
-#else
- *(ssei*)ptr = select(mask,i,*(ssei*)ptr);
-#endif
+__forceinline void store4i(const sseb &mask, void *ptr, const ssei &i)
+{
+# if defined(__KERNEL_AVX__)
+ _mm_maskstore_ps((float *)ptr, (__m128i)mask, _mm_castsi128_ps(i));
+# else
+ *(ssei *)ptr = select(mask, i, *(ssei *)ptr);
+# endif
}
-__forceinline ssei load4i_nt (void* ptr) {
-#if defined(__KERNEL_SSE41__)
- return _mm_stream_load_si128((__m128i*)ptr);
-#else
- return _mm_load_si128((__m128i*)ptr);
-#endif
+__forceinline ssei load4i_nt(void *ptr)
+{
+# if defined(__KERNEL_SSE41__)
+ return _mm_stream_load_si128((__m128i *)ptr);
+# else
+ return _mm_load_si128((__m128i *)ptr);
+# endif
}
-__forceinline void store4i_nt(void* ptr, const ssei& v) {
-#if defined(__KERNEL_SSE41__)
- _mm_stream_ps((float*)ptr,_mm_castsi128_ps(v));
-#else
- _mm_store_si128((__m128i*)ptr,v);
-#endif
+__forceinline void store4i_nt(void *ptr, const ssei &v)
+{
+# if defined(__KERNEL_SSE41__)
+ _mm_stream_ps((float *)ptr, _mm_castsi128_ps(v));
+# else
+ _mm_store_si128((__m128i *)ptr, v);
+# endif
}
////////////////////////////////////////////////////////////////////////////////
@@ -291,8 +604,7 @@ __forceinline void store4i_nt(void* ptr, const ssei& v) {
ccl_device_inline void print_ssei(const char *label, const ssei &a)
{
- printf("%s: %df %df %df %d\n",
- label, a[0], a[1], a[2], a[3]);
+ printf("%s: %df %df %df %d\n", label, a[0], a[1], a[2], a[3]);
}
#endif
diff --git a/intern/cycles/util/util_stack_allocator.h b/intern/cycles/util/util_stack_allocator.h
index 4e978e18bee..36db655e5eb 100644
--- a/intern/cycles/util/util_stack_allocator.h
+++ b/intern/cycles/util/util_stack_allocator.h
@@ -23,145 +23,143 @@
CCL_NAMESPACE_BEGIN
/* Stack allocator for the use with STL. */
-template <int SIZE, typename T>
-class ccl_try_align(16) StackAllocator {
-public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T *pointer;
- typedef const T *const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
-
- /* Allocator construction/destruction. */
-
- StackAllocator()
- : pointer_(0),
- use_stack_(true) {}
-
- StackAllocator(const StackAllocator&)
- : pointer_(0),
- use_stack_(true) {}
-
- template <class U>
- StackAllocator(const StackAllocator<SIZE, U>&)
- : pointer_(0),
- use_stack_(false) {}
-
- /* Memory allocation/deallocation. */
-
- T *allocate(size_t n, const void *hint = 0)
- {
- (void) hint;
- if(n == 0) {
- return NULL;
- }
- if(pointer_ + n >= SIZE || use_stack_ == false) {
- size_t size = n * sizeof(T);
- util_guarded_mem_alloc(size);
- T *mem;
+template<int SIZE, typename T> class ccl_try_align(16) StackAllocator
+{
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T *pointer;
+ typedef const T *const_pointer;
+ typedef T &reference;
+ typedef const T &const_reference;
+ typedef T value_type;
+
+ /* Allocator construction/destruction. */
+
+ StackAllocator() : pointer_(0), use_stack_(true)
+ {
+ }
+
+ StackAllocator(const StackAllocator &) : pointer_(0), use_stack_(true)
+ {
+ }
+
+ template<class U>
+ StackAllocator(const StackAllocator<SIZE, U> &) : pointer_(0), use_stack_(false)
+ {
+ }
+
+ /* Memory allocation/deallocation. */
+
+ T *allocate(size_t n, const void *hint = 0)
+ {
+ (void)hint;
+ if (n == 0) {
+ return NULL;
+ }
+ if (pointer_ + n >= SIZE || use_stack_ == false) {
+ size_t size = n * sizeof(T);
+ util_guarded_mem_alloc(size);
+ T *mem;
#ifdef WITH_BLENDER_GUARDEDALLOC
- mem = (T*)MEM_mallocN_aligned(size, 16, "Cycles Alloc");
+ mem = (T *)MEM_mallocN_aligned(size, 16, "Cycles Alloc");
#else
- mem = (T*)malloc(size);
+ mem = (T *)malloc(size);
#endif
- if(mem == NULL) {
- throw std::bad_alloc();
- }
- return mem;
- }
- T *mem = &data_[pointer_];
- pointer_ += n;
- return mem;
- }
-
- void deallocate(T *p, size_t n)
- {
- if(p == NULL) {
- return;
- }
- if(p < data_ || p >= data_ + SIZE) {
- util_guarded_mem_free(n * sizeof(T));
+ if (mem == NULL) {
+ throw std::bad_alloc();
+ }
+ return mem;
+ }
+ T *mem = &data_[pointer_];
+ pointer_ += n;
+ return mem;
+ }
+
+ void deallocate(T * p, size_t n)
+ {
+ if (p == NULL) {
+ return;
+ }
+ if (p < data_ || p >= data_ + SIZE) {
+ util_guarded_mem_free(n * sizeof(T));
#ifdef WITH_BLENDER_GUARDEDALLOC
- MEM_freeN(p);
+ MEM_freeN(p);
#else
- free(p);
+ free(p);
#endif
- return;
- }
- /* We don't support memory free for the stack allocator. */
- }
-
- /* Address of an reference. */
-
- T *address(T& x) const
- {
- return &x;
- }
-
- const T *address(const T& x) const
- {
- return &x;
- }
-
- /* Object construction/destruction. */
-
- void construct(T *p, const T& val)
- {
- if(p != NULL) {
- new ((T *)p) T(val);
- }
- }
-
- void destroy(T *p)
- {
- p->~T();
- }
-
- /* Maximum allocation size. */
-
- size_t max_size() const
- {
- return size_t(-1);
- }
-
- /* Rebind to other ype of allocator. */
-
- template <class U>
- struct rebind {
- typedef StackAllocator<SIZE, U> other;
- };
-
- /* Operators */
-
- template <class U>
- inline StackAllocator& operator=(const StackAllocator<SIZE, U>&)
- {
- return *this;
- }
-
- StackAllocator<SIZE, T>& operator=(const StackAllocator&)
- {
- return *this;
- }
-
- inline bool operator==(StackAllocator const& /*other*/) const
- {
- return true;
- }
-
- inline bool operator!=(StackAllocator const& other) const
- {
- return !operator==(other);
- }
-
-private:
- int pointer_;
- bool use_stack_;
- T data_[SIZE];
+ return;
+ }
+ /* We don't support memory free for the stack allocator. */
+ }
+
+ /* Address of an reference. */
+
+ T *address(T & x) const
+ {
+ return &x;
+ }
+
+ const T *address(const T &x) const
+ {
+ return &x;
+ }
+
+ /* Object construction/destruction. */
+
+ void construct(T * p, const T &val)
+ {
+ if (p != NULL) {
+ new ((T *)p) T(val);
+ }
+ }
+
+ void destroy(T * p)
+ {
+ p->~T();
+ }
+
+ /* Maximum allocation size. */
+
+ size_t max_size() const
+ {
+ return size_t(-1);
+ }
+
+ /* Rebind to other ype of allocator. */
+
+ template<class U> struct rebind {
+ typedef StackAllocator<SIZE, U> other;
+ };
+
+ /* Operators */
+
+ template<class U> inline StackAllocator &operator=(const StackAllocator<SIZE, U> &)
+ {
+ return *this;
+ }
+
+ StackAllocator<SIZE, T> &operator=(const StackAllocator &)
+ {
+ return *this;
+ }
+
+ inline bool operator==(StackAllocator const & /*other*/) const
+ {
+ return true;
+ }
+
+ inline bool operator!=(StackAllocator const &other) const
+ {
+ return !operator==(other);
+ }
+
+ private:
+ int pointer_;
+ bool use_stack_;
+ T data_[SIZE];
};
CCL_NAMESPACE_END
-#endif /* __UTIL_STACK_ALLOCATOR_H__ */
+#endif /* __UTIL_STACK_ALLOCATOR_H__ */
diff --git a/intern/cycles/util/util_static_assert.h b/intern/cycles/util/util_static_assert.h
index b1c6c374693..b4b972a4036 100644
--- a/intern/cycles/util/util_static_assert.h
+++ b/intern/cycles/util/util_static_assert.h
@@ -15,18 +15,18 @@
*/
#ifndef __UTIL_STATIC_ASSERT_H__
-#define __UTIL_STATIC_ASSERT_H__
+# define __UTIL_STATIC_ASSERT_H__
CCL_NAMESPACE_BEGIN
/* TODO(sergey): In theory CUDA might work with own static assert
* implementation since it's just pure C++.
*/
-#ifdef __KERNEL_GPU__
-# ifndef static_assert
-# define static_assert(statement, message)
-# endif
-#endif /* __KERNEL_GPU__ */
+# ifdef __KERNEL_GPU__
+# ifndef static_assert
+# define static_assert(statement, message)
+# endif
+# endif /* __KERNEL_GPU__ */
/* TODO(sergey): For until C++11 is a bare minimum for us,
* we do a bit of a trickery to show meaningful message so
@@ -43,8 +43,8 @@ CCL_NAMESPACE_BEGIN
* name to the error message,
*/
# define static_assert_align(st, align) \
- static_assert((sizeof(st) % (align) == 0), "Structure must be strictly aligned") // NOLINT
+ static_assert((sizeof(st) % (align) == 0), "Structure must be strictly aligned") // NOLINT
CCL_NAMESPACE_END
-#endif /* __UTIL_STATIC_ASSERT_H__ */
+#endif /* __UTIL_STATIC_ASSERT_H__ */
diff --git a/intern/cycles/util/util_stats.h b/intern/cycles/util/util_stats.h
index f1f2df94e33..15cf836de3c 100644
--- a/intern/cycles/util/util_stats.h
+++ b/intern/cycles/util/util_stats.h
@@ -23,26 +23,32 @@
CCL_NAMESPACE_BEGIN
class Stats {
-public:
- enum static_init_t { static_init = 0 };
-
- Stats() : mem_used(0), mem_peak(0) {}
- explicit Stats(static_init_t) {}
-
- void mem_alloc(size_t size) {
- atomic_add_and_fetch_z(&mem_used, size);
- atomic_fetch_and_update_max_z(&mem_peak, mem_used);
- }
-
- void mem_free(size_t size) {
- assert(mem_used >= size);
- atomic_sub_and_fetch_z(&mem_used, size);
- }
-
- size_t mem_used;
- size_t mem_peak;
+ public:
+ enum static_init_t { static_init = 0 };
+
+ Stats() : mem_used(0), mem_peak(0)
+ {
+ }
+ explicit Stats(static_init_t)
+ {
+ }
+
+ void mem_alloc(size_t size)
+ {
+ atomic_add_and_fetch_z(&mem_used, size);
+ atomic_fetch_and_update_max_z(&mem_peak, mem_used);
+ }
+
+ void mem_free(size_t size)
+ {
+ assert(mem_used >= size);
+ atomic_sub_and_fetch_z(&mem_used, size);
+ }
+
+ size_t mem_used;
+ size_t mem_peak;
};
CCL_NAMESPACE_END
-#endif /* __UTIL_STATS_H__ */
+#endif /* __UTIL_STATS_H__ */
diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp
index 47119e90a45..afcca7e0411 100644
--- a/intern/cycles/util/util_string.cpp
+++ b/intern/cycles/util/util_string.cpp
@@ -25,276 +25,232 @@
# ifndef vsnprintf
# define vsnprintf _vsnprintf
# endif
-#endif /* _WIN32 */
+#endif /* _WIN32 */
CCL_NAMESPACE_BEGIN
string string_printf(const char *format, ...)
{
- vector<char> str(128, 0);
-
- while(1) {
- va_list args;
- int result;
-
- va_start(args, format);
- result = vsnprintf(&str[0], str.size(), format, args);
- va_end(args);
-
- if(result == -1) {
- /* not enough space or formatting error */
- if(str.size() > 65536) {
- assert(0);
- return string("");
- }
-
- str.resize(str.size()*2, 0);
- continue;
- }
- else if(result >= (int)str.size()) {
- /* not enough space */
- str.resize(result + 1, 0);
- continue;
- }
-
- return string(&str[0]);
- }
+ vector<char> str(128, 0);
+
+ while (1) {
+ va_list args;
+ int result;
+
+ va_start(args, format);
+ result = vsnprintf(&str[0], str.size(), format, args);
+ va_end(args);
+
+ if (result == -1) {
+ /* not enough space or formatting error */
+ if (str.size() > 65536) {
+ assert(0);
+ return string("");
+ }
+
+ str.resize(str.size() * 2, 0);
+ continue;
+ }
+ else if (result >= (int)str.size()) {
+ /* not enough space */
+ str.resize(result + 1, 0);
+ continue;
+ }
+
+ return string(&str[0]);
+ }
}
-bool string_iequals(const string& a, const string& b)
+bool string_iequals(const string &a, const string &b)
{
- if(a.size() == b.size()) {
- for(size_t i = 0; i < a.size(); i++)
- if(toupper(a[i]) != toupper(b[i]))
- return false;
+ if (a.size() == b.size()) {
+ for (size_t i = 0; i < a.size(); i++)
+ if (toupper(a[i]) != toupper(b[i]))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-void string_split(vector<string>& tokens,
- const string& str,
- const string& separators,
+void string_split(vector<string> &tokens,
+ const string &str,
+ const string &separators,
bool skip_empty_tokens)
{
- size_t token_start = 0, token_length = 0;
- for(size_t i = 0; i < str.size(); ++i) {
- const char ch = str[i];
- if(separators.find(ch) == string::npos) {
- /* Current character is not a separator,
- * append it to token by increasing token length.
- */
- ++token_length;
- }
- else {
- /* Current character is a separator,
- * append current token to the list.
- */
- if(!skip_empty_tokens || token_length > 0) {
- string token = str.substr(token_start, token_length);
- tokens.push_back(token);
- }
- token_start = i + 1;
- token_length = 0;
- }
- }
- /* Append token from the tail of the string if exists. */
- if(token_length) {
- string token = str.substr(token_start, token_length);
- tokens.push_back(token);
- }
+ size_t token_start = 0, token_length = 0;
+ for (size_t i = 0; i < str.size(); ++i) {
+ const char ch = str[i];
+ if (separators.find(ch) == string::npos) {
+ /* Current character is not a separator,
+ * append it to token by increasing token length.
+ */
+ ++token_length;
+ }
+ else {
+ /* Current character is a separator,
+ * append current token to the list.
+ */
+ if (!skip_empty_tokens || token_length > 0) {
+ string token = str.substr(token_start, token_length);
+ tokens.push_back(token);
+ }
+ token_start = i + 1;
+ token_length = 0;
+ }
+ }
+ /* Append token from the tail of the string if exists. */
+ if (token_length) {
+ string token = str.substr(token_start, token_length);
+ tokens.push_back(token);
+ }
}
-bool string_startswith(const string& s, const char *start)
+bool string_startswith(const string &s, const char *start)
{
- size_t len = strlen(start);
+ size_t len = strlen(start);
- if(len > s.size())
- return 0;
- else
- return strncmp(s.c_str(), start, len) == 0;
+ if (len > s.size())
+ return 0;
+ else
+ return strncmp(s.c_str(), start, len) == 0;
}
-bool string_endswith(const string& s, const char *end)
+bool string_endswith(const string &s, const char *end)
{
- size_t len = strlen(end);
+ size_t len = strlen(end);
- if(len > s.size())
- return 0;
- else
- return strncmp(s.c_str() + s.size() - len, end, len) == 0;
+ if (len > s.size())
+ return 0;
+ else
+ return strncmp(s.c_str() + s.size() - len, end, len) == 0;
}
-string string_strip(const string& s)
+string string_strip(const string &s)
{
- string result = s;
- result.erase(0, result.find_first_not_of(' '));
- result.erase(result.find_last_not_of(' ') + 1);
- return result;
-
+ string result = s;
+ result.erase(0, result.find_first_not_of(' '));
+ result.erase(result.find_last_not_of(' ') + 1);
+ return result;
}
-void string_replace(string& haystack, const string& needle, const string& other)
+void string_replace(string &haystack, const string &needle, const string &other)
{
- size_t i = 0, index;
- while((index = haystack.find(needle, i)) != string::npos) {
- haystack.replace(index, needle.size(), other);
- i = index + other.size();
- }
+ size_t i = 0, index;
+ while ((index = haystack.find(needle, i)) != string::npos) {
+ haystack.replace(index, needle.size(), other);
+ i = index + other.size();
+ }
}
string string_remove_trademark(const string &s)
{
- string result = s;
+ string result = s;
- /* Special case, so we don;t leave sequential spaces behind. */
- /* TODO(sergey): Consider using regex perhaps? */
- string_replace(result, " (TM)", "");
- string_replace(result, " (R)", "");
+ /* Special case, so we don;t leave sequential spaces behind. */
+ /* TODO(sergey): Consider using regex perhaps? */
+ string_replace(result, " (TM)", "");
+ string_replace(result, " (R)", "");
- string_replace(result, "(TM)", "");
- string_replace(result, "(R)", "");
+ string_replace(result, "(TM)", "");
+ string_replace(result, "(R)", "");
- return string_strip(result);
+ return string_strip(result);
}
string string_from_bool(bool var)
{
- if(var)
- return "True";
- else
- return "False";
+ if (var)
+ return "True";
+ else
+ return "False";
}
string to_string(const char *str)
{
- return string(str);
+ return string(str);
}
/* Wide char strings helpers for Windows. */
#ifdef _WIN32
-wstring string_to_wstring(const string& str)
+wstring string_to_wstring(const string &str)
{
- const int length_wc = MultiByteToWideChar(CP_UTF8,
- 0,
- str.c_str(),
- str.length(),
- NULL,
- 0);
- wstring str_wc(length_wc, 0);
- MultiByteToWideChar(CP_UTF8,
- 0,
- str.c_str(),
- str.length(),
- &str_wc[0],
- length_wc);
- return str_wc;
+ const int length_wc = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
+ wstring str_wc(length_wc, 0);
+ MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &str_wc[0], length_wc);
+ return str_wc;
}
-string string_from_wstring(const wstring& str)
+string string_from_wstring(const wstring &str)
{
- int length_mb = WideCharToMultiByte(CP_UTF8,
- 0,
- str.c_str(),
- str.size(),
- NULL,
- 0,
- NULL, NULL);
- string str_mb(length_mb, 0);
- WideCharToMultiByte(CP_UTF8,
- 0,
- str.c_str(),
- str.size(),
- &str_mb[0],
- length_mb,
- NULL, NULL);
- return str_mb;
+ int length_mb = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.size(), NULL, 0, NULL, NULL);
+ string str_mb(length_mb, 0);
+ WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.size(), &str_mb[0], length_mb, NULL, NULL);
+ return str_mb;
}
-string string_to_ansi(const string& str)
+string string_to_ansi(const string &str)
{
- const int length_wc = MultiByteToWideChar(CP_UTF8,
- 0,
- str.c_str(),
- str.length(),
- NULL,
- 0);
- wstring str_wc(length_wc, 0);
- MultiByteToWideChar(CP_UTF8,
- 0,
- str.c_str(),
- str.length(),
- &str_wc[0],
- length_wc);
-
- int length_mb = WideCharToMultiByte(CP_ACP,
- 0,
- str_wc.c_str(),
- str_wc.size(),
- NULL,
- 0,
- NULL, NULL);
-
- string str_mb(length_mb, 0);
- WideCharToMultiByte(CP_ACP,
- 0,
- str_wc.c_str(),
- str_wc.size(),
- &str_mb[0],
- length_mb,
- NULL, NULL);
-
- return str_mb;
+ const int length_wc = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
+ wstring str_wc(length_wc, 0);
+ MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &str_wc[0], length_wc);
+
+ int length_mb = WideCharToMultiByte(
+ CP_ACP, 0, str_wc.c_str(), str_wc.size(), NULL, 0, NULL, NULL);
+
+ string str_mb(length_mb, 0);
+ WideCharToMultiByte(CP_ACP, 0, str_wc.c_str(), str_wc.size(), &str_mb[0], length_mb, NULL, NULL);
+
+ return str_mb;
}
-#endif /* _WIN32 */
+#endif /* _WIN32 */
string string_human_readable_size(size_t size)
{
- static const char suffixes[] = "BKMGTPEZY";
+ static const char suffixes[] = "BKMGTPEZY";
- const char* suffix = suffixes;
- size_t r = 0;
+ const char *suffix = suffixes;
+ size_t r = 0;
- while(size >= 1024) {
- r = size % 1024;
- size /= 1024;
- suffix++;
- }
+ while (size >= 1024) {
+ r = size % 1024;
+ size /= 1024;
+ suffix++;
+ }
- if(*suffix != 'B')
- return string_printf("%.2f%c", double(size*1024+r)/1024.0, *suffix);
- else
- return string_printf("%zu", size);
+ if (*suffix != 'B')
+ return string_printf("%.2f%c", double(size * 1024 + r) / 1024.0, *suffix);
+ else
+ return string_printf("%zu", size);
}
string string_human_readable_number(size_t num)
{
- if(num == 0) {
- return "0";
- }
+ if (num == 0) {
+ return "0";
+ }
- /* Add thousands separators. */
- char buf[32];
+ /* Add thousands separators. */
+ char buf[32];
- char* p = buf+31;
- *p = '\0';
+ char *p = buf + 31;
+ *p = '\0';
- int i = -1;
- while(num) {
- if(++i && i % 3 == 0)
- *(--p) = ',';
+ int i = -1;
+ while (num) {
+ if (++i && i % 3 == 0)
+ *(--p) = ',';
- *(--p) = '0' + (num % 10);
+ *(--p) = '0' + (num % 10);
- num /= 10;
- }
+ num /= 10;
+ }
- return p;
+ return p;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h
index 02584fe5113..f71145741c9 100644
--- a/intern/cycles/util/util_string.h
+++ b/intern/cycles/util/util_string.h
@@ -25,30 +25,30 @@
CCL_NAMESPACE_BEGIN
+using std::istringstream;
+using std::ostringstream;
using std::string;
using std::stringstream;
-using std::ostringstream;
-using std::istringstream;
using std::to_string;
#ifdef __GNUC__
-#define PRINTF_ATTRIBUTE __attribute__((format(printf, 1, 2)))
+# define PRINTF_ATTRIBUTE __attribute__((format(printf, 1, 2)))
#else
-#define PRINTF_ATTRIBUTE
+# define PRINTF_ATTRIBUTE
#endif
string string_printf(const char *format, ...) PRINTF_ATTRIBUTE;
-bool string_iequals(const string& a, const string& b);
-void string_split(vector<string>& tokens,
- const string& str,
- const string& separators = "\t ",
+bool string_iequals(const string &a, const string &b);
+void string_split(vector<string> &tokens,
+ const string &str,
+ const string &separators = "\t ",
bool skip_empty_tokens = true);
-void string_replace(string& haystack, const string& needle, const string& other);
-bool string_startswith(const string& s, const char *start);
-bool string_endswith(const string& s, const char *end);
-string string_strip(const string& s);
-string string_remove_trademark(const string& s);
+void string_replace(string &haystack, const string &needle, const string &other);
+bool string_startswith(const string &s, const char *start);
+bool string_endswith(const string &s, const char *end);
+string string_strip(const string &s);
+string string_remove_trademark(const string &s);
string string_from_bool(const bool var);
string to_string(const char *str);
@@ -61,9 +61,9 @@ string to_string(const char *str);
*/
#ifdef _WIN32
using std::wstring;
-wstring string_to_wstring(const string& path);
-string string_from_wstring(const wstring& path);
-string string_to_ansi(const string& str);
+wstring string_to_wstring(const string &path);
+string string_from_wstring(const wstring &path);
+string string_to_ansi(const string &str);
#endif
/* Make a string from a size in bytes in human readable form */
@@ -73,4 +73,4 @@ string string_human_readable_number(size_t num);
CCL_NAMESPACE_END
-#endif /* __UTIL_STRING_H__ */
+#endif /* __UTIL_STRING_H__ */
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index 2a5c4a8f012..0cd991c6231 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -26,7 +26,7 @@
OIIO_NAMESPACE_USING
#ifdef _WIN32
-# if(!defined(FREE_WINDOWS))
+# if (!defined(FREE_WINDOWS))
# include <intrin.h>
# endif
# include "util_windows.h"
@@ -43,333 +43,332 @@ CCL_NAMESPACE_BEGIN
bool system_cpu_ensure_initialized()
{
- static bool is_initialized = false;
- static bool result = false;
- if(is_initialized) {
- return result;
- }
- is_initialized = true;
- const NUMAAPI_Result numa_result = numaAPI_Initialize();
- result = (numa_result == NUMAAPI_SUCCESS);
- return result;
+ static bool is_initialized = false;
+ static bool result = false;
+ if (is_initialized) {
+ return result;
+ }
+ is_initialized = true;
+ const NUMAAPI_Result numa_result = numaAPI_Initialize();
+ result = (numa_result == NUMAAPI_SUCCESS);
+ return result;
}
/* Fallback solution, which doesn't use NUMA/CPU groups. */
static int system_cpu_thread_count_fallback()
{
#ifdef _WIN32
- SYSTEM_INFO info;
- GetSystemInfo(&info);
- return info.dwNumberOfProcessors;
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ return info.dwNumberOfProcessors;
#elif defined(__APPLE__)
- int count;
- size_t len = sizeof(count);
- int mib[2] = { CTL_HW, HW_NCPU };
- sysctl(mib, 2, &count, &len, NULL, 0);
- return count;
+ int count;
+ size_t len = sizeof(count);
+ int mib[2] = {CTL_HW, HW_NCPU};
+ sysctl(mib, 2, &count, &len, NULL, 0);
+ return count;
#else
- return sysconf(_SC_NPROCESSORS_ONLN);
+ return sysconf(_SC_NPROCESSORS_ONLN);
#endif
}
int system_cpu_thread_count()
{
- const int num_nodes = system_cpu_num_numa_nodes();
- int num_threads = 0;
- for(int node = 0; node < num_nodes; ++node) {
- if(!system_cpu_is_numa_node_available(node)) {
- continue;
- }
- num_threads += system_cpu_num_numa_node_processors(node);
- }
- return num_threads;
+ const int num_nodes = system_cpu_num_numa_nodes();
+ int num_threads = 0;
+ for (int node = 0; node < num_nodes; ++node) {
+ if (!system_cpu_is_numa_node_available(node)) {
+ continue;
+ }
+ num_threads += system_cpu_num_numa_node_processors(node);
+ }
+ return num_threads;
}
int system_cpu_num_numa_nodes()
{
- if(!system_cpu_ensure_initialized()) {
- /* Fallback to a single node with all the threads. */
- return 1;
- }
- return numaAPI_GetNumNodes();
+ if (!system_cpu_ensure_initialized()) {
+ /* Fallback to a single node with all the threads. */
+ return 1;
+ }
+ return numaAPI_GetNumNodes();
}
bool system_cpu_is_numa_node_available(int node)
{
- if(!system_cpu_ensure_initialized()) {
- return true;
- }
- return numaAPI_IsNodeAvailable(node);
+ if (!system_cpu_ensure_initialized()) {
+ return true;
+ }
+ return numaAPI_IsNodeAvailable(node);
}
int system_cpu_num_numa_node_processors(int node)
{
- if(!system_cpu_ensure_initialized()) {
- return system_cpu_thread_count_fallback();
- }
- return numaAPI_GetNumNodeProcessors(node);
+ if (!system_cpu_ensure_initialized()) {
+ return system_cpu_thread_count_fallback();
+ }
+ return numaAPI_GetNumNodeProcessors(node);
}
bool system_cpu_run_thread_on_node(int node)
{
- if(!system_cpu_ensure_initialized()) {
- return true;
- }
- return numaAPI_RunThreadOnNode(node);
+ if (!system_cpu_ensure_initialized()) {
+ return true;
+ }
+ return numaAPI_RunThreadOnNode(node);
}
int system_console_width()
{
- int columns = 0;
+ int columns = 0;
#ifdef _WIN32
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
- columns = csbi.dwSize.X;
- }
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
+ columns = csbi.dwSize.X;
+ }
#else
- struct winsize w;
- if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
- columns = w.ws_col;
- }
+ struct winsize w;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
+ columns = w.ws_col;
+ }
#endif
- return (columns > 0) ? columns : 80;
+ return (columns > 0) ? columns : 80;
}
int system_cpu_num_active_group_processors()
{
- if(!system_cpu_ensure_initialized()) {
- return system_cpu_thread_count_fallback();
- }
- return numaAPI_GetNumCurrentNodesProcessors();
+ if (!system_cpu_ensure_initialized()) {
+ return system_cpu_thread_count_fallback();
+ }
+ return numaAPI_GetNumCurrentNodesProcessors();
}
#if !defined(_WIN32) || defined(FREE_WINDOWS)
static void __cpuid(int data[4], int selector)
{
-#if defined(__x86_64__)
- asm("cpuid" : "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
-#elif defined(__i386__)
- asm("pushl %%ebx \n\t"
- "cpuid \n\t"
- "movl %%ebx, %1 \n\t"
- "popl %%ebx \n\t"
- : "=a" (data[0]), "=r" (data[1]), "=c" (data[2]), "=d" (data[3])
- : "a"(selector)
- : "ebx");
-#else
- data[0] = data[1] = data[2] = data[3] = 0;
-#endif
+# if defined(__x86_64__)
+ asm("cpuid" : "=a"(data[0]), "=b"(data[1]), "=c"(data[2]), "=d"(data[3]) : "a"(selector));
+# elif defined(__i386__)
+ asm("pushl %%ebx \n\t"
+ "cpuid \n\t"
+ "movl %%ebx, %1 \n\t"
+ "popl %%ebx \n\t"
+ : "=a"(data[0]), "=r"(data[1]), "=c"(data[2]), "=d"(data[3])
+ : "a"(selector)
+ : "ebx");
+# else
+ data[0] = data[1] = data[2] = data[3] = 0;
+# endif
}
#endif
string system_cpu_brand_string()
{
- char buf[48] = {0};
- int result[4] = {0};
+ char buf[48] = {0};
+ int result[4] = {0};
- __cpuid(result, 0x80000000);
+ __cpuid(result, 0x80000000);
- if(result[0] >= (int)0x80000004) {
- __cpuid((int*)(buf+0), 0x80000002);
- __cpuid((int*)(buf+16), 0x80000003);
- __cpuid((int*)(buf+32), 0x80000004);
+ if (result[0] >= (int)0x80000004) {
+ __cpuid((int *)(buf + 0), 0x80000002);
+ __cpuid((int *)(buf + 16), 0x80000003);
+ __cpuid((int *)(buf + 32), 0x80000004);
- string brand = buf;
+ string brand = buf;
- /* make it a bit more presentable */
- brand = string_remove_trademark(brand);
+ /* make it a bit more presentable */
+ brand = string_remove_trademark(brand);
- return brand;
- }
+ return brand;
+ }
- return "Unknown CPU";
+ return "Unknown CPU";
}
int system_cpu_bits()
{
- return (sizeof(void*)*8);
+ return (sizeof(void *) * 8);
}
#if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(_M_IX86)
struct CPUCapabilities {
- bool x64;
- bool mmx;
- bool sse;
- bool sse2;
- bool sse3;
- bool ssse3;
- bool sse41;
- bool sse42;
- bool sse4a;
- bool avx;
- bool f16c;
- bool avx2;
- bool xop;
- bool fma3;
- bool fma4;
- bool bmi1;
- bool bmi2;
+ bool x64;
+ bool mmx;
+ bool sse;
+ bool sse2;
+ bool sse3;
+ bool ssse3;
+ bool sse41;
+ bool sse42;
+ bool sse4a;
+ bool avx;
+ bool f16c;
+ bool avx2;
+ bool xop;
+ bool fma3;
+ bool fma4;
+ bool bmi1;
+ bool bmi2;
};
-static CPUCapabilities& system_cpu_capabilities()
+static CPUCapabilities &system_cpu_capabilities()
{
- static CPUCapabilities caps;
- static bool caps_init = false;
-
- if(!caps_init) {
- int result[4], num;
-
- memset(&caps, 0, sizeof(caps));
-
- __cpuid(result, 0);
- num = result[0];
-
- if(num >= 1) {
- __cpuid(result, 0x00000001);
- caps.mmx = (result[3] & ((int)1 << 23)) != 0;
- caps.sse = (result[3] & ((int)1 << 25)) != 0;
- caps.sse2 = (result[3] & ((int)1 << 26)) != 0;
- caps.sse3 = (result[2] & ((int)1 << 0)) != 0;
-
- caps.ssse3 = (result[2] & ((int)1 << 9)) != 0;
- caps.sse41 = (result[2] & ((int)1 << 19)) != 0;
- caps.sse42 = (result[2] & ((int)1 << 20)) != 0;
-
- caps.fma3 = (result[2] & ((int)1 << 12)) != 0;
- caps.avx = false;
- bool os_uses_xsave_xrestore = (result[2] & ((int)1 << 27)) != 0;
- bool cpu_avx_support = (result[2] & ((int)1 << 28)) != 0;
-
- if( os_uses_xsave_xrestore && cpu_avx_support) {
- // Check if the OS will save the YMM registers
- uint32_t xcr_feature_mask;
-#if defined(__GNUC__)
- int edx; /* not used */
- /* actual opcode for xgetbv */
- __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (xcr_feature_mask) , "=d" (edx) : "c" (0) );
-#elif defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
- xcr_feature_mask = (uint32_t)_xgetbv(_XCR_XFEATURE_ENABLED_MASK); /* min VS2010 SP1 compiler is required */
-#else
- xcr_feature_mask = 0;
-#endif
- caps.avx = (xcr_feature_mask & 0x6) == 0x6;
- }
+ static CPUCapabilities caps;
+ static bool caps_init = false;
+
+ if (!caps_init) {
+ int result[4], num;
+
+ memset(&caps, 0, sizeof(caps));
+
+ __cpuid(result, 0);
+ num = result[0];
+
+ if (num >= 1) {
+ __cpuid(result, 0x00000001);
+ caps.mmx = (result[3] & ((int)1 << 23)) != 0;
+ caps.sse = (result[3] & ((int)1 << 25)) != 0;
+ caps.sse2 = (result[3] & ((int)1 << 26)) != 0;
+ caps.sse3 = (result[2] & ((int)1 << 0)) != 0;
+
+ caps.ssse3 = (result[2] & ((int)1 << 9)) != 0;
+ caps.sse41 = (result[2] & ((int)1 << 19)) != 0;
+ caps.sse42 = (result[2] & ((int)1 << 20)) != 0;
+
+ caps.fma3 = (result[2] & ((int)1 << 12)) != 0;
+ caps.avx = false;
+ bool os_uses_xsave_xrestore = (result[2] & ((int)1 << 27)) != 0;
+ bool cpu_avx_support = (result[2] & ((int)1 << 28)) != 0;
+
+ if (os_uses_xsave_xrestore && cpu_avx_support) {
+ // Check if the OS will save the YMM registers
+ uint32_t xcr_feature_mask;
+# if defined(__GNUC__)
+ int edx; /* not used */
+ /* actual opcode for xgetbv */
+ __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(xcr_feature_mask), "=d"(edx) : "c"(0));
+# elif defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
+ xcr_feature_mask = (uint32_t)_xgetbv(
+ _XCR_XFEATURE_ENABLED_MASK); /* min VS2010 SP1 compiler is required */
+# else
+ xcr_feature_mask = 0;
+# endif
+ caps.avx = (xcr_feature_mask & 0x6) == 0x6;
+ }
- caps.f16c = (result[2] & ((int)1 << 29)) != 0;
+ caps.f16c = (result[2] & ((int)1 << 29)) != 0;
- __cpuid(result, 0x00000007);
- caps.bmi1 = (result[1] & ((int)1 << 3)) != 0;
- caps.bmi2 = (result[1] & ((int)1 << 8)) != 0;
- caps.avx2 = (result[1] & ((int)1 << 5)) != 0;
- }
+ __cpuid(result, 0x00000007);
+ caps.bmi1 = (result[1] & ((int)1 << 3)) != 0;
+ caps.bmi2 = (result[1] & ((int)1 << 8)) != 0;
+ caps.avx2 = (result[1] & ((int)1 << 5)) != 0;
+ }
- caps_init = true;
- }
+ caps_init = true;
+ }
- return caps;
+ return caps;
}
bool system_cpu_support_sse2()
{
- CPUCapabilities& caps = system_cpu_capabilities();
- return caps.sse && caps.sse2;
+ CPUCapabilities &caps = system_cpu_capabilities();
+ return caps.sse && caps.sse2;
}
bool system_cpu_support_sse3()
{
- CPUCapabilities& caps = system_cpu_capabilities();
- return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3;
+ CPUCapabilities &caps = system_cpu_capabilities();
+ return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3;
}
bool system_cpu_support_sse41()
{
- CPUCapabilities& caps = system_cpu_capabilities();
- return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41;
+ CPUCapabilities &caps = system_cpu_capabilities();
+ return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41;
}
bool system_cpu_support_avx()
{
- CPUCapabilities& caps = system_cpu_capabilities();
- return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 &&
- caps.sse41 && caps.avx;
+ CPUCapabilities &caps = system_cpu_capabilities();
+ return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41 && caps.avx;
}
bool system_cpu_support_avx2()
{
- CPUCapabilities& caps = system_cpu_capabilities();
- return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41 &&
- caps.avx && caps.f16c && caps.avx2 && caps.fma3 && caps.bmi1 &&
- caps.bmi2;
+ CPUCapabilities &caps = system_cpu_capabilities();
+ return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41 && caps.avx && caps.f16c &&
+ caps.avx2 && caps.fma3 && caps.bmi1 && caps.bmi2;
}
#else
bool system_cpu_support_sse2()
{
- return false;
+ return false;
}
bool system_cpu_support_sse3()
{
- return false;
+ return false;
}
bool system_cpu_support_sse41()
{
- return false;
+ return false;
}
bool system_cpu_support_avx()
{
- return false;
+ return false;
}
bool system_cpu_support_avx2()
{
- return false;
+ return false;
}
#endif
-bool system_call_self(const vector<string>& args)
+bool system_call_self(const vector<string> &args)
{
- /* Escape program and arguments in case they contain spaces. */
- string cmd = "\"" + Sysutil::this_program_path() + "\"";
+ /* Escape program and arguments in case they contain spaces. */
+ string cmd = "\"" + Sysutil::this_program_path() + "\"";
- for(int i = 0; i < args.size(); i++) {
- cmd += " \"" + args[i] + "\"";
- }
+ for (int i = 0; i < args.size(); i++) {
+ cmd += " \"" + args[i] + "\"";
+ }
#ifdef _WIN32
- /* Use cmd /S to avoid issues with spaces in arguments. */
- cmd = "cmd /S /C \"" + cmd + " > nul \"";
+ /* Use cmd /S to avoid issues with spaces in arguments. */
+ cmd = "cmd /S /C \"" + cmd + " > nul \"";
#else
- /* Quiet output. */
- cmd += " > /dev/null";
+ /* Quiet output. */
+ cmd += " > /dev/null";
#endif
- return (system(cmd.c_str()) == 0);
+ return (system(cmd.c_str()) == 0);
}
size_t system_physical_ram()
{
#ifdef _WIN32
- MEMORYSTATUSEX ram;
- ram.dwLength = sizeof (ram);
- GlobalMemoryStatusEx(&ram);
- return ram.ullTotalPhys * 1024;
+ MEMORYSTATUSEX ram;
+ ram.dwLength = sizeof(ram);
+ GlobalMemoryStatusEx(&ram);
+ return ram.ullTotalPhys * 1024;
#elif defined(__APPLE__)
- uint64_t ram = 0;
- size_t len = sizeof(ram);
- if(sysctlbyname("hw.memsize", &ram, &len, NULL, 0) == 0) {
- return ram;
- }
- return 0;
+ uint64_t ram = 0;
+ size_t len = sizeof(ram);
+ if (sysctlbyname("hw.memsize", &ram, &len, NULL, 0) == 0) {
+ return ram;
+ }
+ return 0;
#else
- size_t ps = sysconf(_SC_PAGESIZE);
- size_t pn = sysconf(_SC_PHYS_PAGES);
- return ps * pn;
+ size_t ps = sysconf(_SC_PAGESIZE);
+ size_t pn = sysconf(_SC_PHYS_PAGES);
+ return ps * pn;
#endif
}
diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h
index 2590b31a59d..c4db8b74339 100644
--- a/intern/cycles/util/util_system.h
+++ b/intern/cycles/util/util_system.h
@@ -63,8 +63,8 @@ bool system_cpu_support_avx2();
size_t system_physical_ram();
/* Start a new process of the current application with the given arguments. */
-bool system_call_self(const vector<string>& args);
+bool system_call_self(const vector<string> &args);
CCL_NAMESPACE_END
-#endif /* __UTIL_SYSTEM_H__ */
+#endif /* __UTIL_SYSTEM_H__ */
diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp
index ce166af206a..4b11ce73ea9 100644
--- a/intern/cycles/util/util_task.cpp
+++ b/intern/cycles/util/util_task.cpp
@@ -23,10 +23,14 @@
//#define THREADING_DEBUG_ENABLED
#ifdef THREADING_DEBUG_ENABLED
-#include <stdio.h>
-#define THREADING_DEBUG(...) do { printf(__VA_ARGS__); fflush(stdout); } while(0)
+# include <stdio.h>
+# define THREADING_DEBUG(...) \
+ do { \
+ printf(__VA_ARGS__); \
+ fflush(stdout); \
+ } while (0)
#else
-#define THREADING_DEBUG(...)
+# define THREADING_DEBUG(...)
#endif
CCL_NAMESPACE_BEGIN
@@ -35,156 +39,156 @@ CCL_NAMESPACE_BEGIN
TaskPool::TaskPool()
{
- num_tasks_handled = 0;
- num = 0;
- do_cancel = false;
+ num_tasks_handled = 0;
+ num = 0;
+ do_cancel = false;
}
TaskPool::~TaskPool()
{
- stop();
+ stop();
}
void TaskPool::push(Task *task, bool front)
{
- TaskScheduler::Entry entry;
+ TaskScheduler::Entry entry;
- entry.task = task;
- entry.pool = this;
+ entry.task = task;
+ entry.pool = this;
- TaskScheduler::push(entry, front);
+ TaskScheduler::push(entry, front);
}
-void TaskPool::push(const TaskRunFunction& run, bool front)
+void TaskPool::push(const TaskRunFunction &run, bool front)
{
- push(new Task(run), front);
+ push(new Task(run), front);
}
void TaskPool::wait_work(Summary *stats)
{
- thread_scoped_lock num_lock(num_mutex);
+ thread_scoped_lock num_lock(num_mutex);
- while(num != 0) {
- num_lock.unlock();
+ while (num != 0) {
+ num_lock.unlock();
- thread_scoped_lock queue_lock(TaskScheduler::queue_mutex);
+ thread_scoped_lock queue_lock(TaskScheduler::queue_mutex);
- /* find task from this pool. if we get a task from another pool,
- * we can get into deadlock */
- TaskScheduler::Entry work_entry;
- bool found_entry = false;
- list<TaskScheduler::Entry>::iterator it;
+ /* find task from this pool. if we get a task from another pool,
+ * we can get into deadlock */
+ TaskScheduler::Entry work_entry;
+ bool found_entry = false;
+ list<TaskScheduler::Entry>::iterator it;
- for(it = TaskScheduler::queue.begin(); it != TaskScheduler::queue.end(); it++) {
- TaskScheduler::Entry& entry = *it;
+ for (it = TaskScheduler::queue.begin(); it != TaskScheduler::queue.end(); it++) {
+ TaskScheduler::Entry &entry = *it;
- if(entry.pool == this) {
- work_entry = entry;
- found_entry = true;
- TaskScheduler::queue.erase(it);
- break;
- }
- }
+ if (entry.pool == this) {
+ work_entry = entry;
+ found_entry = true;
+ TaskScheduler::queue.erase(it);
+ break;
+ }
+ }
- queue_lock.unlock();
+ queue_lock.unlock();
- /* if found task, do it, otherwise wait until other tasks are done */
- if(found_entry) {
- /* run task */
- work_entry.task->run(0);
+ /* if found task, do it, otherwise wait until other tasks are done */
+ if (found_entry) {
+ /* run task */
+ work_entry.task->run(0);
- /* delete task */
- delete work_entry.task;
+ /* delete task */
+ delete work_entry.task;
- /* notify pool task was done */
- num_decrease(1);
- }
+ /* notify pool task was done */
+ num_decrease(1);
+ }
- num_lock.lock();
- if(num == 0)
- break;
+ num_lock.lock();
+ if (num == 0)
+ break;
- if(!found_entry) {
- THREADING_DEBUG("num==%d, Waiting for condition in TaskPool::wait_work !found_entry\n", num);
- num_cond.wait(num_lock);
- THREADING_DEBUG("num==%d, condition wait done in TaskPool::wait_work !found_entry\n", num);
- }
- }
+ if (!found_entry) {
+ THREADING_DEBUG("num==%d, Waiting for condition in TaskPool::wait_work !found_entry\n", num);
+ num_cond.wait(num_lock);
+ THREADING_DEBUG("num==%d, condition wait done in TaskPool::wait_work !found_entry\n", num);
+ }
+ }
- if(stats != NULL) {
- stats->time_total = time_dt() - start_time;
- stats->num_tasks_handled = num_tasks_handled;
- }
+ if (stats != NULL) {
+ stats->time_total = time_dt() - start_time;
+ stats->num_tasks_handled = num_tasks_handled;
+ }
}
void TaskPool::cancel()
{
- do_cancel = true;
+ do_cancel = true;
- TaskScheduler::clear(this);
+ TaskScheduler::clear(this);
- {
- thread_scoped_lock num_lock(num_mutex);
+ {
+ thread_scoped_lock num_lock(num_mutex);
- while(num) {
- THREADING_DEBUG("num==%d, Waiting for condition in TaskPool::cancel\n", num);
- num_cond.wait(num_lock);
- THREADING_DEBUG("num==%d condition wait done in TaskPool::cancel\n", num);
- }
- }
+ while (num) {
+ THREADING_DEBUG("num==%d, Waiting for condition in TaskPool::cancel\n", num);
+ num_cond.wait(num_lock);
+ THREADING_DEBUG("num==%d condition wait done in TaskPool::cancel\n", num);
+ }
+ }
- do_cancel = false;
+ do_cancel = false;
}
void TaskPool::stop()
{
- TaskScheduler::clear(this);
+ TaskScheduler::clear(this);
- assert(num == 0);
+ assert(num == 0);
}
bool TaskPool::canceled()
{
- return do_cancel;
+ return do_cancel;
}
bool TaskPool::finished()
{
- thread_scoped_lock num_lock(num_mutex);
- return num == 0;
+ thread_scoped_lock num_lock(num_mutex);
+ return num == 0;
}
void TaskPool::num_decrease(int done)
{
- num_mutex.lock();
- num -= done;
+ num_mutex.lock();
+ num -= done;
- assert(num >= 0);
- if(num == 0) {
- THREADING_DEBUG("num==%d, notifying all in TaskPool::num_decrease\n", num);
- num_cond.notify_all();
- }
+ assert(num >= 0);
+ if (num == 0) {
+ THREADING_DEBUG("num==%d, notifying all in TaskPool::num_decrease\n", num);
+ num_cond.notify_all();
+ }
- num_mutex.unlock();
+ num_mutex.unlock();
}
void TaskPool::num_increase()
{
- thread_scoped_lock num_lock(num_mutex);
- if(num_tasks_handled == 0) {
- start_time = time_dt();
- }
- num++;
- num_tasks_handled++;
- THREADING_DEBUG("num==%d, notifying all in TaskPool::num_increase\n", num);
- num_cond.notify_all();
+ thread_scoped_lock num_lock(num_mutex);
+ if (num_tasks_handled == 0) {
+ start_time = time_dt();
+ }
+ num++;
+ num_tasks_handled++;
+ THREADING_DEBUG("num==%d, notifying all in TaskPool::num_increase\n", num);
+ num_cond.notify_all();
}
/* Task Scheduler */
thread_mutex TaskScheduler::mutex;
int TaskScheduler::users = 0;
-vector<thread*> TaskScheduler::threads;
+vector<thread *> TaskScheduler::threads;
bool TaskScheduler::do_exit = false;
list<TaskScheduler::Entry> TaskScheduler::queue;
@@ -198,412 +202,401 @@ namespace {
* that node.
* If node is not available, then the corresponding number of processors is
* zero. */
-void get_per_node_num_processors(vector<int>* num_per_node_processors)
-{
- const int num_nodes = system_cpu_num_numa_nodes();
- if(num_nodes == 0) {
- LOG(ERROR) << "Zero available NUMA nodes, is not supposed to happen.";
- return;
- }
- num_per_node_processors->resize(num_nodes);
- for(int node = 0; node < num_nodes; ++node) {
- if(!system_cpu_is_numa_node_available(node)) {
- (*num_per_node_processors)[node] = 0;
- continue;
- }
- (*num_per_node_processors)[node] =
- system_cpu_num_numa_node_processors(node);
- }
+void get_per_node_num_processors(vector<int> *num_per_node_processors)
+{
+ const int num_nodes = system_cpu_num_numa_nodes();
+ if (num_nodes == 0) {
+ LOG(ERROR) << "Zero available NUMA nodes, is not supposed to happen.";
+ return;
+ }
+ num_per_node_processors->resize(num_nodes);
+ for (int node = 0; node < num_nodes; ++node) {
+ if (!system_cpu_is_numa_node_available(node)) {
+ (*num_per_node_processors)[node] = 0;
+ continue;
+ }
+ (*num_per_node_processors)[node] = system_cpu_num_numa_node_processors(node);
+ }
}
/* Calculate total number of processors on all available nodes.
* This is similar to system_cpu_thread_count(), but uses pre-calculated number
* of processors on each of the node, avoiding extra system calls and checks for
* the node availability. */
-int get_num_total_processors(const vector<int>& num_per_node_processors)
+int get_num_total_processors(const vector<int> &num_per_node_processors)
{
- int num_total_processors = 0;
- foreach(int num_node_processors, num_per_node_processors) {
- num_total_processors += num_node_processors;
- }
- return num_total_processors;
+ int num_total_processors = 0;
+ foreach (int num_node_processors, num_per_node_processors) {
+ num_total_processors += num_node_processors;
+ }
+ return num_total_processors;
}
/* Compute NUMA node for every thread to run on, for the best performance. */
vector<int> distribute_threads_on_nodes(const int num_threads)
{
- /* Start with all threads unassigned to any specific NUMA node. */
- vector<int> thread_nodes(num_threads, -1);
- const int num_active_group_processors =
- system_cpu_num_active_group_processors();
- VLOG(1) << "Detected " << num_active_group_processors << " processors "
- << "in active group.";
- if(num_active_group_processors >= num_threads) {
- /* If the current thread is set up in a way that its affinity allows to
- * use at least requested number of threads we do not explicitly set
- * affinity to the worker therads.
- * This way we allow users to manually edit affinity of the parent
- * thread, and here we follow that affinity. This way it's possible to
- * have two Cycles/Blender instances running manually set to a different
- * dies on a CPU. */
- VLOG(1) << "Not setting thread group affinity.";
- return thread_nodes;
- }
- vector<int> num_per_node_processors;
- get_per_node_num_processors(&num_per_node_processors);
- if(num_per_node_processors.size() == 0) {
- /* Error was already repported, here we can't do anything, so we simply
- * leave default affinity to all the worker threads. */
- return thread_nodes;
- }
- const int num_nodes = num_per_node_processors.size();
- int thread_index = 0;
- /* First pass: fill in all the nodes to their maximum.
- *
- * If there is less threads than the overall nodes capacity, some of the
- * nodes or parts of them will idle.
- *
- * TODO(sergey): Consider picking up fastest nodes if number of threads
- * fits on them. For example, on Threadripper2 we might consider using nodes
- * 0 and 2 if user requested 32 render threads. */
- const int num_total_node_processors =
- get_num_total_processors(num_per_node_processors);
- int current_node_index = 0;
- while(thread_index < num_total_node_processors &&
- thread_index < num_threads) {
- const int num_node_processors =
- num_per_node_processors[current_node_index];
- for(int processor_index = 0;
- processor_index < num_node_processors;
- ++processor_index)
- {
- VLOG(1) << "Scheduling thread " << thread_index << " to node "
- << current_node_index << ".";
- thread_nodes[thread_index] = current_node_index;
- ++thread_index;
- if(thread_index == num_threads) {
- /* All threads are scheduled on their nodes. */
- return thread_nodes;
- }
- }
- ++current_node_index;
- }
- /* Second pass: keep scheduling threads to each node one by one, uniformly
- * fillign them in.
- * This is where things becomes tricky to predict for the maximum
- * performance: on the one hand this avoids too much threading overhead on
- * few nodes, but for the final performance having all the overhead on one
- * node might be better idea (since other nodes will have better chance of
- * rendering faster).
- * But more tricky is that nodes might have difference capacity, so we might
- * want to do some weighted scheduling. For example, if node 0 has 16
- * processors and node 1 has 32 processors, we'd better schedule 1 extra
- * thread on node 0 and 2 extra threads on node 1. */
- current_node_index = 0;
- while(thread_index < num_threads) {
- /* Skip unavailable nodes. */
- /* TODO(sergey): Add sanity check against deadlock. */
- while(num_per_node_processors[current_node_index] == 0) {
- current_node_index = (current_node_index + 1) % num_nodes;
- }
- VLOG(1) << "Scheduling thread " << thread_index << " to node "
- << current_node_index << ".";
- ++thread_index;
- current_node_index = (current_node_index + 1) % num_nodes;
- }
-
- return thread_nodes;
+ /* Start with all threads unassigned to any specific NUMA node. */
+ vector<int> thread_nodes(num_threads, -1);
+ const int num_active_group_processors = system_cpu_num_active_group_processors();
+ VLOG(1) << "Detected " << num_active_group_processors << " processors "
+ << "in active group.";
+ if (num_active_group_processors >= num_threads) {
+ /* If the current thread is set up in a way that its affinity allows to
+ * use at least requested number of threads we do not explicitly set
+ * affinity to the worker therads.
+ * This way we allow users to manually edit affinity of the parent
+ * thread, and here we follow that affinity. This way it's possible to
+ * have two Cycles/Blender instances running manually set to a different
+ * dies on a CPU. */
+ VLOG(1) << "Not setting thread group affinity.";
+ return thread_nodes;
+ }
+ vector<int> num_per_node_processors;
+ get_per_node_num_processors(&num_per_node_processors);
+ if (num_per_node_processors.size() == 0) {
+ /* Error was already repported, here we can't do anything, so we simply
+ * leave default affinity to all the worker threads. */
+ return thread_nodes;
+ }
+ const int num_nodes = num_per_node_processors.size();
+ int thread_index = 0;
+ /* First pass: fill in all the nodes to their maximum.
+ *
+ * If there is less threads than the overall nodes capacity, some of the
+ * nodes or parts of them will idle.
+ *
+ * TODO(sergey): Consider picking up fastest nodes if number of threads
+ * fits on them. For example, on Threadripper2 we might consider using nodes
+ * 0 and 2 if user requested 32 render threads. */
+ const int num_total_node_processors = get_num_total_processors(num_per_node_processors);
+ int current_node_index = 0;
+ while (thread_index < num_total_node_processors && thread_index < num_threads) {
+ const int num_node_processors = num_per_node_processors[current_node_index];
+ for (int processor_index = 0; processor_index < num_node_processors; ++processor_index) {
+ VLOG(1) << "Scheduling thread " << thread_index << " to node " << current_node_index << ".";
+ thread_nodes[thread_index] = current_node_index;
+ ++thread_index;
+ if (thread_index == num_threads) {
+ /* All threads are scheduled on their nodes. */
+ return thread_nodes;
+ }
+ }
+ ++current_node_index;
+ }
+ /* Second pass: keep scheduling threads to each node one by one, uniformly
+ * fillign them in.
+ * This is where things becomes tricky to predict for the maximum
+ * performance: on the one hand this avoids too much threading overhead on
+ * few nodes, but for the final performance having all the overhead on one
+ * node might be better idea (since other nodes will have better chance of
+ * rendering faster).
+ * But more tricky is that nodes might have difference capacity, so we might
+ * want to do some weighted scheduling. For example, if node 0 has 16
+ * processors and node 1 has 32 processors, we'd better schedule 1 extra
+ * thread on node 0 and 2 extra threads on node 1. */
+ current_node_index = 0;
+ while (thread_index < num_threads) {
+ /* Skip unavailable nodes. */
+ /* TODO(sergey): Add sanity check against deadlock. */
+ while (num_per_node_processors[current_node_index] == 0) {
+ current_node_index = (current_node_index + 1) % num_nodes;
+ }
+ VLOG(1) << "Scheduling thread " << thread_index << " to node " << current_node_index << ".";
+ ++thread_index;
+ current_node_index = (current_node_index + 1) % num_nodes;
+ }
+
+ return thread_nodes;
}
} // namespace
void TaskScheduler::init(int num_threads)
{
- thread_scoped_lock lock(mutex);
- /* Multiple cycles instances can use this task scheduler, sharing the same
- * threads, so we keep track of the number of users. */
- ++users;
- if(users != 1) {
- return;
- }
- do_exit = false;
- const bool use_auto_threads = (num_threads == 0);
- if(use_auto_threads) {
- /* Automatic number of threads. */
- num_threads = system_cpu_thread_count();
- }
- VLOG(1) << "Creating pool of " << num_threads << " threads.";
-
- /* Compute distribution on NUMA nodes. */
- vector<int> thread_nodes = distribute_threads_on_nodes(num_threads);
-
- /* Launch threads that will be waiting for work. */
- threads.resize(num_threads);
- for(int thread_index = 0; thread_index < num_threads; ++thread_index) {
- threads[thread_index] = new thread(
- function_bind(&TaskScheduler::thread_run, thread_index + 1),
- thread_nodes[thread_index]);
- }
+ thread_scoped_lock lock(mutex);
+ /* Multiple cycles instances can use this task scheduler, sharing the same
+ * threads, so we keep track of the number of users. */
+ ++users;
+ if (users != 1) {
+ return;
+ }
+ do_exit = false;
+ const bool use_auto_threads = (num_threads == 0);
+ if (use_auto_threads) {
+ /* Automatic number of threads. */
+ num_threads = system_cpu_thread_count();
+ }
+ VLOG(1) << "Creating pool of " << num_threads << " threads.";
+
+ /* Compute distribution on NUMA nodes. */
+ vector<int> thread_nodes = distribute_threads_on_nodes(num_threads);
+
+ /* Launch threads that will be waiting for work. */
+ threads.resize(num_threads);
+ for (int thread_index = 0; thread_index < num_threads; ++thread_index) {
+ threads[thread_index] = new thread(function_bind(&TaskScheduler::thread_run, thread_index + 1),
+ thread_nodes[thread_index]);
+ }
}
void TaskScheduler::exit()
{
- thread_scoped_lock lock(mutex);
- users--;
- if(users == 0) {
- VLOG(1) << "De-initializing thread pool of task scheduler.";
- /* stop all waiting threads */
- TaskScheduler::queue_mutex.lock();
- do_exit = true;
- TaskScheduler::queue_cond.notify_all();
- TaskScheduler::queue_mutex.unlock();
-
- /* delete threads */
- foreach(thread *t, threads) {
- t->join();
- delete t;
- }
- threads.clear();
- }
+ thread_scoped_lock lock(mutex);
+ users--;
+ if (users == 0) {
+ VLOG(1) << "De-initializing thread pool of task scheduler.";
+ /* stop all waiting threads */
+ TaskScheduler::queue_mutex.lock();
+ do_exit = true;
+ TaskScheduler::queue_cond.notify_all();
+ TaskScheduler::queue_mutex.unlock();
+
+ /* delete threads */
+ foreach (thread *t, threads) {
+ t->join();
+ delete t;
+ }
+ threads.clear();
+ }
}
void TaskScheduler::free_memory()
{
- assert(users == 0);
- threads.free_memory();
+ assert(users == 0);
+ threads.free_memory();
}
-bool TaskScheduler::thread_wait_pop(Entry& entry)
+bool TaskScheduler::thread_wait_pop(Entry &entry)
{
- thread_scoped_lock queue_lock(queue_mutex);
+ thread_scoped_lock queue_lock(queue_mutex);
- while(queue.empty() && !do_exit)
- queue_cond.wait(queue_lock);
+ while (queue.empty() && !do_exit)
+ queue_cond.wait(queue_lock);
- if(queue.empty()) {
- assert(do_exit);
- return false;
- }
+ if (queue.empty()) {
+ assert(do_exit);
+ return false;
+ }
- entry = queue.front();
- queue.pop_front();
+ entry = queue.front();
+ queue.pop_front();
- return true;
+ return true;
}
void TaskScheduler::thread_run(int thread_id)
{
- Entry entry;
+ Entry entry;
- /* todo: test affinity/denormal mask */
+ /* todo: test affinity/denormal mask */
- /* keep popping off tasks */
- while(thread_wait_pop(entry)) {
- /* run task */
- entry.task->run(thread_id);
+ /* keep popping off tasks */
+ while (thread_wait_pop(entry)) {
+ /* run task */
+ entry.task->run(thread_id);
- /* delete task */
- delete entry.task;
+ /* delete task */
+ delete entry.task;
- /* notify pool task was done */
- entry.pool->num_decrease(1);
- }
+ /* notify pool task was done */
+ entry.pool->num_decrease(1);
+ }
}
-void TaskScheduler::push(Entry& entry, bool front)
+void TaskScheduler::push(Entry &entry, bool front)
{
- entry.pool->num_increase();
+ entry.pool->num_increase();
- /* add entry to queue */
- TaskScheduler::queue_mutex.lock();
- if(front)
- TaskScheduler::queue.push_front(entry);
- else
- TaskScheduler::queue.push_back(entry);
+ /* add entry to queue */
+ TaskScheduler::queue_mutex.lock();
+ if (front)
+ TaskScheduler::queue.push_front(entry);
+ else
+ TaskScheduler::queue.push_back(entry);
- TaskScheduler::queue_cond.notify_one();
- TaskScheduler::queue_mutex.unlock();
+ TaskScheduler::queue_cond.notify_one();
+ TaskScheduler::queue_mutex.unlock();
}
void TaskScheduler::clear(TaskPool *pool)
{
- thread_scoped_lock queue_lock(TaskScheduler::queue_mutex);
+ thread_scoped_lock queue_lock(TaskScheduler::queue_mutex);
- /* erase all tasks from this pool from the queue */
- list<Entry>::iterator it = queue.begin();
- int done = 0;
+ /* erase all tasks from this pool from the queue */
+ list<Entry>::iterator it = queue.begin();
+ int done = 0;
- while(it != queue.end()) {
- Entry& entry = *it;
+ while (it != queue.end()) {
+ Entry &entry = *it;
- if(entry.pool == pool) {
- done++;
- delete entry.task;
+ if (entry.pool == pool) {
+ done++;
+ delete entry.task;
- it = queue.erase(it);
- }
- else
- it++;
- }
+ it = queue.erase(it);
+ }
+ else
+ it++;
+ }
- queue_lock.unlock();
+ queue_lock.unlock();
- /* notify done */
- pool->num_decrease(done);
+ /* notify done */
+ pool->num_decrease(done);
}
/* Dedicated Task Pool */
DedicatedTaskPool::DedicatedTaskPool()
{
- do_cancel = false;
- do_exit = false;
- num = 0;
+ do_cancel = false;
+ do_exit = false;
+ num = 0;
- worker_thread = new thread(function_bind(&DedicatedTaskPool::thread_run, this));
+ worker_thread = new thread(function_bind(&DedicatedTaskPool::thread_run, this));
}
DedicatedTaskPool::~DedicatedTaskPool()
{
- stop();
- worker_thread->join();
- delete worker_thread;
+ stop();
+ worker_thread->join();
+ delete worker_thread;
}
void DedicatedTaskPool::push(Task *task, bool front)
{
- num_increase();
+ num_increase();
- /* add task to queue */
- queue_mutex.lock();
- if(front)
- queue.push_front(task);
- else
- queue.push_back(task);
+ /* add task to queue */
+ queue_mutex.lock();
+ if (front)
+ queue.push_front(task);
+ else
+ queue.push_back(task);
- queue_cond.notify_one();
- queue_mutex.unlock();
+ queue_cond.notify_one();
+ queue_mutex.unlock();
}
-void DedicatedTaskPool::push(const TaskRunFunction& run, bool front)
+void DedicatedTaskPool::push(const TaskRunFunction &run, bool front)
{
- push(new Task(run), front);
+ push(new Task(run), front);
}
void DedicatedTaskPool::wait()
{
- thread_scoped_lock num_lock(num_mutex);
+ thread_scoped_lock num_lock(num_mutex);
- while(num)
- num_cond.wait(num_lock);
+ while (num)
+ num_cond.wait(num_lock);
}
void DedicatedTaskPool::cancel()
{
- do_cancel = true;
+ do_cancel = true;
- clear();
- wait();
+ clear();
+ wait();
- do_cancel = false;
+ do_cancel = false;
}
void DedicatedTaskPool::stop()
{
- clear();
+ clear();
- do_exit = true;
- queue_cond.notify_all();
+ do_exit = true;
+ queue_cond.notify_all();
- wait();
+ wait();
- assert(num == 0);
+ assert(num == 0);
}
bool DedicatedTaskPool::canceled()
{
- return do_cancel;
+ return do_cancel;
}
void DedicatedTaskPool::num_decrease(int done)
{
- thread_scoped_lock num_lock(num_mutex);
- num -= done;
+ thread_scoped_lock num_lock(num_mutex);
+ num -= done;
- assert(num >= 0);
- if(num == 0)
- num_cond.notify_all();
+ assert(num >= 0);
+ if (num == 0)
+ num_cond.notify_all();
}
void DedicatedTaskPool::num_increase()
{
- thread_scoped_lock num_lock(num_mutex);
- num++;
- num_cond.notify_all();
+ thread_scoped_lock num_lock(num_mutex);
+ num++;
+ num_cond.notify_all();
}
-bool DedicatedTaskPool::thread_wait_pop(Task*& task)
+bool DedicatedTaskPool::thread_wait_pop(Task *&task)
{
- thread_scoped_lock queue_lock(queue_mutex);
+ thread_scoped_lock queue_lock(queue_mutex);
- while(queue.empty() && !do_exit)
- queue_cond.wait(queue_lock);
+ while (queue.empty() && !do_exit)
+ queue_cond.wait(queue_lock);
- if(queue.empty()) {
- assert(do_exit);
- return false;
- }
+ if (queue.empty()) {
+ assert(do_exit);
+ return false;
+ }
- task = queue.front();
- queue.pop_front();
+ task = queue.front();
+ queue.pop_front();
- return true;
+ return true;
}
void DedicatedTaskPool::thread_run()
{
- Task *task;
+ Task *task;
- /* keep popping off tasks */
- while(thread_wait_pop(task)) {
- /* run task */
- task->run(0);
+ /* keep popping off tasks */
+ while (thread_wait_pop(task)) {
+ /* run task */
+ task->run(0);
- /* delete task */
- delete task;
+ /* delete task */
+ delete task;
- /* notify task was done */
- num_decrease(1);
- }
+ /* notify task was done */
+ num_decrease(1);
+ }
}
void DedicatedTaskPool::clear()
{
- thread_scoped_lock queue_lock(queue_mutex);
+ thread_scoped_lock queue_lock(queue_mutex);
- /* erase all tasks from the queue */
- list<Task*>::iterator it = queue.begin();
- int done = 0;
+ /* erase all tasks from the queue */
+ list<Task *>::iterator it = queue.begin();
+ int done = 0;
- while(it != queue.end()) {
- done++;
- delete *it;
+ while (it != queue.end()) {
+ done++;
+ delete *it;
- it = queue.erase(it);
- }
+ it = queue.erase(it);
+ }
- queue_lock.unlock();
+ queue_lock.unlock();
- /* notify done */
- num_decrease(done);
+ /* notify done */
+ num_decrease(done);
}
string TaskPool::Summary::full_report() const
{
- string report = "";
- report += string_printf("Total time: %f\n", time_total);
- report += string_printf("Tasks handled: %d\n", num_tasks_handled);
- return report;
+ string report = "";
+ report += string_printf("Total time: %f\n", time_total);
+ report += string_printf("Tasks handled: %d\n", num_tasks_handled);
+ return report;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h
index a7e19d1ab75..fd30a33d8ef 100644
--- a/intern/cycles/util/util_task.h
+++ b/intern/cycles/util/util_task.h
@@ -48,15 +48,18 @@ typedef function<void(int thread_id)> TaskRunFunction;
*
* Base class for tasks to be executed in threads. */
-class Task
-{
-public:
- Task() {};
- explicit Task(const TaskRunFunction& run_) : run(run_) {}
-
- virtual ~Task() {}
-
- TaskRunFunction run;
+class Task {
+ public:
+ Task(){};
+ explicit Task(const TaskRunFunction &run_) : run(run_)
+ {
+ }
+
+ virtual ~Task()
+ {
+ }
+
+ TaskRunFunction run;
};
/* Task Pool
@@ -68,54 +71,53 @@ public:
* The run callback that actually executes the task may be created like this:
* function_bind(&MyClass::task_execute, this, _1, _2) */
-class TaskPool
-{
-public:
- struct Summary {
- /* Time spent to handle all tasks. */
- double time_total;
+class TaskPool {
+ public:
+ struct Summary {
+ /* Time spent to handle all tasks. */
+ double time_total;
- /* Number of all tasks handled by this pool. */
- int num_tasks_handled;
+ /* Number of all tasks handled by this pool. */
+ int num_tasks_handled;
- /* A full multiline description of the state of the pool after
- * all work is done.
- */
- string full_report() const;
- };
+ /* A full multiline description of the state of the pool after
+ * all work is done.
+ */
+ string full_report() const;
+ };
- TaskPool();
- ~TaskPool();
+ TaskPool();
+ ~TaskPool();
- void push(Task *task, bool front = false);
- void push(const TaskRunFunction& run, bool front = false);
+ void push(Task *task, bool front = false);
+ void push(const TaskRunFunction &run, bool front = false);
- void wait_work(Summary *stats = NULL); /* work and wait until all tasks are done */
- void cancel(); /* cancel all tasks, keep worker threads running */
- void stop(); /* stop all worker threads */
- bool finished(); /* check if all work has been completed */
+ void wait_work(Summary *stats = NULL); /* work and wait until all tasks are done */
+ void cancel(); /* cancel all tasks, keep worker threads running */
+ void stop(); /* stop all worker threads */
+ bool finished(); /* check if all work has been completed */
- bool canceled(); /* for worker threads, test if canceled */
+ bool canceled(); /* for worker threads, test if canceled */
-protected:
- friend class TaskScheduler;
+ protected:
+ friend class TaskScheduler;
- void num_decrease(int done);
- void num_increase();
+ void num_decrease(int done);
+ void num_increase();
- thread_mutex num_mutex;
- thread_condition_variable num_cond;
+ thread_mutex num_mutex;
+ thread_condition_variable num_cond;
- int num;
- bool do_cancel;
+ int num;
+ bool do_cancel;
- /* ** Statistics ** */
+ /* ** Statistics ** */
- /* Time time stamp of first task pushed. */
- double start_time;
+ /* Time time stamp of first task pushed. */
+ double start_time;
- /* Number of all tasks handled by this pool. */
- int num_tasks_handled;
+ /* Number of all tasks handled by this pool. */
+ int num_tasks_handled;
};
/* Task Scheduler
@@ -123,41 +125,46 @@ protected:
* Central scheduler that holds running threads ready to execute tasks. A singe
* queue holds the task from all pools. */
-class TaskScheduler
-{
-public:
- static void init(int num_threads = 0);
- static void exit();
- static void free_memory();
-
- /* number of threads that can work on task */
- static int num_threads() { return threads.size(); }
-
- /* test if any session is using the scheduler */
- static bool active() { return users != 0; }
-
-protected:
- friend class TaskPool;
-
- struct Entry {
- Task *task;
- TaskPool *pool;
- };
-
- static thread_mutex mutex;
- static int users;
- static vector<thread*> threads;
- static bool do_exit;
-
- static list<Entry> queue;
- static thread_mutex queue_mutex;
- static thread_condition_variable queue_cond;
-
- static void thread_run(int thread_id);
- static bool thread_wait_pop(Entry& entry);
-
- static void push(Entry& entry, bool front);
- static void clear(TaskPool *pool);
+class TaskScheduler {
+ public:
+ static void init(int num_threads = 0);
+ static void exit();
+ static void free_memory();
+
+ /* number of threads that can work on task */
+ static int num_threads()
+ {
+ return threads.size();
+ }
+
+ /* test if any session is using the scheduler */
+ static bool active()
+ {
+ return users != 0;
+ }
+
+ protected:
+ friend class TaskPool;
+
+ struct Entry {
+ Task *task;
+ TaskPool *pool;
+ };
+
+ static thread_mutex mutex;
+ static int users;
+ static vector<thread *> threads;
+ static bool do_exit;
+
+ static list<Entry> queue;
+ static thread_mutex queue_mutex;
+ static thread_condition_variable queue_cond;
+
+ static void thread_run(int thread_id);
+ static bool thread_wait_pop(Entry &entry);
+
+ static void push(Entry &entry, bool front);
+ static void clear(TaskPool *pool);
};
/* Dedicated Task Pool
@@ -167,42 +174,41 @@ protected:
* The run callback that actually executes the task may be created like this:
* function_bind(&MyClass::task_execute, this, _1, _2) */
-class DedicatedTaskPool
-{
-public:
- DedicatedTaskPool();
- ~DedicatedTaskPool();
+class DedicatedTaskPool {
+ public:
+ DedicatedTaskPool();
+ ~DedicatedTaskPool();
- void push(Task *task, bool front = false);
- void push(const TaskRunFunction& run, bool front = false);
+ void push(Task *task, bool front = false);
+ void push(const TaskRunFunction &run, bool front = false);
- void wait(); /* wait until all tasks are done */
- void cancel(); /* cancel all tasks, keep worker thread running */
- void stop(); /* stop worker thread */
+ void wait(); /* wait until all tasks are done */
+ void cancel(); /* cancel all tasks, keep worker thread running */
+ void stop(); /* stop worker thread */
- bool canceled(); /* for worker thread, test if canceled */
+ bool canceled(); /* for worker thread, test if canceled */
-protected:
- void num_decrease(int done);
- void num_increase();
+ protected:
+ void num_decrease(int done);
+ void num_increase();
- void thread_run();
- bool thread_wait_pop(Task*& entry);
+ void thread_run();
+ bool thread_wait_pop(Task *&entry);
- void clear();
+ void clear();
- thread_mutex num_mutex;
- thread_condition_variable num_cond;
+ thread_mutex num_mutex;
+ thread_condition_variable num_cond;
- list<Task*> queue;
- thread_mutex queue_mutex;
- thread_condition_variable queue_cond;
+ list<Task *> queue;
+ thread_mutex queue_mutex;
+ thread_condition_variable queue_cond;
- int num;
- bool do_cancel;
- bool do_exit;
+ int num;
+ bool do_cancel;
+ bool do_exit;
- thread *worker_thread;
+ thread *worker_thread;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_texture.h b/intern/cycles/util/util_texture.h
index 233cfe33305..5ce16e0095a 100644
--- a/intern/cycles/util/util_texture.h
+++ b/intern/cycles/util/util_texture.h
@@ -34,29 +34,29 @@ CCL_NAMESPACE_BEGIN
/* Interpolation types for textures
* cuda also use texture space to store other objects */
typedef enum InterpolationType {
- INTERPOLATION_NONE = -1,
- INTERPOLATION_LINEAR = 0,
- INTERPOLATION_CLOSEST = 1,
- INTERPOLATION_CUBIC = 2,
- INTERPOLATION_SMART = 3,
+ INTERPOLATION_NONE = -1,
+ INTERPOLATION_LINEAR = 0,
+ INTERPOLATION_CLOSEST = 1,
+ INTERPOLATION_CUBIC = 2,
+ INTERPOLATION_SMART = 3,
- INTERPOLATION_NUM_TYPES,
+ INTERPOLATION_NUM_TYPES,
} InterpolationType;
/* Texture types
* Since we store the type in the lower bits of a flat index,
* the shift and bit mask constant below need to be kept in sync. */
typedef enum ImageDataType {
- IMAGE_DATA_TYPE_FLOAT4 = 0,
- IMAGE_DATA_TYPE_BYTE4 = 1,
- IMAGE_DATA_TYPE_HALF4 = 2,
- IMAGE_DATA_TYPE_FLOAT = 3,
- IMAGE_DATA_TYPE_BYTE = 4,
- IMAGE_DATA_TYPE_HALF = 5,
- IMAGE_DATA_TYPE_USHORT4 = 6,
- IMAGE_DATA_TYPE_USHORT = 7,
+ IMAGE_DATA_TYPE_FLOAT4 = 0,
+ IMAGE_DATA_TYPE_BYTE4 = 1,
+ IMAGE_DATA_TYPE_HALF4 = 2,
+ IMAGE_DATA_TYPE_FLOAT = 3,
+ IMAGE_DATA_TYPE_BYTE = 4,
+ IMAGE_DATA_TYPE_HALF = 5,
+ IMAGE_DATA_TYPE_USHORT4 = 6,
+ IMAGE_DATA_TYPE_USHORT = 7,
- IMAGE_DATA_NUM_TYPES
+ IMAGE_DATA_NUM_TYPES
} ImageDataType;
#define IMAGE_DATA_TYPE_SHIFT 3
@@ -66,27 +66,27 @@ typedef enum ImageDataType {
*
* Defines how the image is extrapolated past its original bounds. */
typedef enum ExtensionType {
- /* Cause the image to repeat horizontally and vertically. */
- EXTENSION_REPEAT = 0,
- /* Extend by repeating edge pixels of the image. */
- EXTENSION_EXTEND = 1,
- /* Clip to image size and set exterior pixels as transparent. */
- EXTENSION_CLIP = 2,
+ /* Cause the image to repeat horizontally and vertically. */
+ EXTENSION_REPEAT = 0,
+ /* Extend by repeating edge pixels of the image. */
+ EXTENSION_EXTEND = 1,
+ /* Clip to image size and set exterior pixels as transparent. */
+ EXTENSION_CLIP = 2,
- EXTENSION_NUM_TYPES,
+ EXTENSION_NUM_TYPES,
} ExtensionType;
typedef struct TextureInfo {
- /* Pointer, offset or texture depending on device. */
- uint64_t data;
- /* Buffer number for OpenCL. */
- uint cl_buffer;
- /* Interpolation and extension type. */
- uint interpolation, extension;
- /* Dimensions. */
- uint width, height, depth;
+ /* Pointer, offset or texture depending on device. */
+ uint64_t data;
+ /* Buffer number for OpenCL. */
+ uint cl_buffer;
+ /* Interpolation and extension type. */
+ uint interpolation, extension;
+ /* Dimensions. */
+ uint width, height, depth;
} TextureInfo;
CCL_NAMESPACE_END
-#endif /* __UTIL_TEXTURE_H__ */
+#endif /* __UTIL_TEXTURE_H__ */
diff --git a/intern/cycles/util/util_thread.cpp b/intern/cycles/util/util_thread.cpp
index f3c6077f6b7..cccde5ae7d5 100644
--- a/intern/cycles/util/util_thread.cpp
+++ b/intern/cycles/util/util_thread.cpp
@@ -21,54 +21,51 @@
CCL_NAMESPACE_BEGIN
-thread::thread(function<void()> run_cb, int node)
- : run_cb_(run_cb),
- joined_(false),
- node_(node)
+thread::thread(function<void()> run_cb, int node) : run_cb_(run_cb), joined_(false), node_(node)
{
#ifdef __APPLE__
- /* Set the stack size to 2MB to match Linux. The default 512KB on macOS is
- * too small for Embree, and consistent stack size also makes things more
- * predictable in general. */
- pthread_attr_t attribute;
- pthread_attr_init(&attribute);
- pthread_attr_setstacksize(&attribute, 1024*1024*2);
- pthread_create(&pthread_id, &attribute, run, (void*)this);
+ /* Set the stack size to 2MB to match Linux. The default 512KB on macOS is
+ * too small for Embree, and consistent stack size also makes things more
+ * predictable in general. */
+ pthread_attr_t attribute;
+ pthread_attr_init(&attribute);
+ pthread_attr_setstacksize(&attribute, 1024 * 1024 * 2);
+ pthread_create(&pthread_id, &attribute, run, (void *)this);
#else
- std_thread = std::thread(&thread::run, this);
+ std_thread = std::thread(&thread::run, this);
#endif
}
thread::~thread()
{
- if(!joined_) {
- join();
- }
+ if (!joined_) {
+ join();
+ }
}
void *thread::run(void *arg)
{
- thread *self = (thread*)(arg);
- if (self->node_ != -1) {
- system_cpu_run_thread_on_node(self->node_);
- }
- self->run_cb_();
- return NULL;
+ thread *self = (thread *)(arg);
+ if (self->node_ != -1) {
+ system_cpu_run_thread_on_node(self->node_);
+ }
+ self->run_cb_();
+ return NULL;
}
bool thread::join()
{
- joined_ = true;
+ joined_ = true;
#ifdef __APPLE__
- return pthread_join(pthread_id, NULL) == 0;
+ return pthread_join(pthread_id, NULL) == 0;
#else
- try {
- std_thread.join();
- return true;
- }
- catch (const std::system_error&) {
- return false;
- }
+ try {
+ std_thread.join();
+ return true;
+ }
+ catch (const std::system_error &) {
+ return false;
+ }
#endif
}
diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h
index 793d44130b6..18ec5b32144 100644
--- a/intern/cycles/util/util_thread.h
+++ b/intern/cycles/util/util_thread.h
@@ -45,103 +45,115 @@ typedef std::condition_variable thread_condition_variable;
* custom stack size on macOS. */
class thread {
-public:
- /* NOTE: Node index of -1 means that affinity will be inherited from the
- * parent thread and no override on top of that will happen. */
- thread(function<void()> run_cb, int node = -1);
- ~thread();
+ public:
+ /* NOTE: Node index of -1 means that affinity will be inherited from the
+ * parent thread and no override on top of that will happen. */
+ thread(function<void()> run_cb, int node = -1);
+ ~thread();
- static void *run(void *arg);
- bool join();
+ static void *run(void *arg);
+ bool join();
-protected:
- function<void()> run_cb_;
+ protected:
+ function<void()> run_cb_;
#ifdef __APPLE__
- pthread_t pthread_id;
+ pthread_t pthread_id;
#else
- std::thread std_thread;
+ std::thread std_thread;
#endif
- bool joined_;
- int node_;
+ bool joined_;
+ int node_;
};
/* Own wrapper around pthread's spin lock to make it's use easier. */
class thread_spin_lock {
-public:
+ public:
#ifdef __APPLE__
- inline thread_spin_lock() {
- spin_ = OS_SPINLOCK_INIT;
- }
-
- inline void lock() {
- OSSpinLockLock(&spin_);
- }
-
- inline void unlock() {
- OSSpinLockUnlock(&spin_);
- }
+ inline thread_spin_lock()
+ {
+ spin_ = OS_SPINLOCK_INIT;
+ }
+
+ inline void lock()
+ {
+ OSSpinLockLock(&spin_);
+ }
+
+ inline void unlock()
+ {
+ OSSpinLockUnlock(&spin_);
+ }
#elif defined(_WIN32)
- inline thread_spin_lock() {
- const DWORD SPIN_COUNT = 50000;
- InitializeCriticalSectionAndSpinCount(&cs_, SPIN_COUNT);
- }
-
- inline ~thread_spin_lock() {
- DeleteCriticalSection(&cs_);
- }
-
- inline void lock() {
- EnterCriticalSection(&cs_);
- }
-
- inline void unlock() {
- LeaveCriticalSection(&cs_);
- }
+ inline thread_spin_lock()
+ {
+ const DWORD SPIN_COUNT = 50000;
+ InitializeCriticalSectionAndSpinCount(&cs_, SPIN_COUNT);
+ }
+
+ inline ~thread_spin_lock()
+ {
+ DeleteCriticalSection(&cs_);
+ }
+
+ inline void lock()
+ {
+ EnterCriticalSection(&cs_);
+ }
+
+ inline void unlock()
+ {
+ LeaveCriticalSection(&cs_);
+ }
#else
- inline thread_spin_lock() {
- pthread_spin_init(&spin_, 0);
- }
-
- inline ~thread_spin_lock() {
- pthread_spin_destroy(&spin_);
- }
-
- inline void lock() {
- pthread_spin_lock(&spin_);
- }
-
- inline void unlock() {
- pthread_spin_unlock(&spin_);
- }
+ inline thread_spin_lock()
+ {
+ pthread_spin_init(&spin_, 0);
+ }
+
+ inline ~thread_spin_lock()
+ {
+ pthread_spin_destroy(&spin_);
+ }
+
+ inline void lock()
+ {
+ pthread_spin_lock(&spin_);
+ }
+
+ inline void unlock()
+ {
+ pthread_spin_unlock(&spin_);
+ }
#endif
-protected:
+ protected:
#ifdef __APPLE__
- OSSpinLock spin_;
+ OSSpinLock spin_;
#elif defined(_WIN32)
- CRITICAL_SECTION cs_;
+ CRITICAL_SECTION cs_;
#else
- pthread_spinlock_t spin_;
+ pthread_spinlock_t spin_;
#endif
};
class thread_scoped_spin_lock {
-public:
- explicit thread_scoped_spin_lock(thread_spin_lock& lock)
- : lock_(lock) {
- lock_.lock();
- }
+ public:
+ explicit thread_scoped_spin_lock(thread_spin_lock &lock) : lock_(lock)
+ {
+ lock_.lock();
+ }
- ~thread_scoped_spin_lock() {
- lock_.unlock();
- }
+ ~thread_scoped_spin_lock()
+ {
+ lock_.unlock();
+ }
- /* TODO(sergey): Implement manual control over lock/unlock. */
+ /* TODO(sergey): Implement manual control over lock/unlock. */
-protected:
- thread_spin_lock& lock_;
+ protected:
+ thread_spin_lock &lock_;
};
CCL_NAMESPACE_END
-#endif /* __UTIL_THREAD_H__ */
+#endif /* __UTIL_THREAD_H__ */
diff --git a/intern/cycles/util/util_time.cpp b/intern/cycles/util/util_time.cpp
index 9983fdd1df3..1641395d07e 100644
--- a/intern/cycles/util/util_time.cpp
+++ b/intern/cycles/util/util_time.cpp
@@ -32,44 +32,44 @@ CCL_NAMESPACE_BEGIN
#ifdef _WIN32
double time_dt()
{
- __int64 frequency, counter;
+ __int64 frequency, counter;
- QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
- QueryPerformanceCounter((LARGE_INTEGER*)&counter);
+ QueryPerformanceFrequency((LARGE_INTEGER *)&frequency);
+ QueryPerformanceCounter((LARGE_INTEGER *)&counter);
- return (double)counter/(double)frequency;
+ return (double)counter / (double)frequency;
}
void time_sleep(double t)
{
- Sleep((int)(t*1000));
+ Sleep((int)(t * 1000));
}
#else
double time_dt()
{
- struct timeval now;
- gettimeofday(&now, NULL);
+ struct timeval now;
+ gettimeofday(&now, NULL);
- return now.tv_sec + now.tv_usec*1e-6;
+ return now.tv_sec + now.tv_usec * 1e-6;
}
/* sleep t seconds */
void time_sleep(double t)
{
- /* get whole seconds */
- int s = (int)t;
+ /* get whole seconds */
+ int s = (int)t;
- if(s >= 1) {
- sleep(s);
+ if (s >= 1) {
+ sleep(s);
- /* adjust parameter to remove whole seconds */
- t -= s;
- }
+ /* adjust parameter to remove whole seconds */
+ t -= s;
+ }
- /* get microseconds */
- int us = (int)(t * 1e6);
- if(us > 0)
- usleep(us);
+ /* get microseconds */
+ int us = (int)(t * 1e6);
+ if (us > 0)
+ usleep(us);
}
#endif
@@ -77,63 +77,63 @@ void time_sleep(double t)
string time_human_readable_from_seconds(const double seconds)
{
- const int h = (((int)seconds) / (60 * 60));
- const int m = (((int)seconds) / 60) % 60;
- const int s = (((int)seconds) % 60);
- const int r = (((int)(seconds * 100)) % 100);
-
- if(h > 0) {
- return string_printf("%.2d:%.2d:%.2d.%.2d", h, m, s, r);
- }
- else {
- return string_printf("%.2d:%.2d.%.2d", m, s, r);
- }
+ const int h = (((int)seconds) / (60 * 60));
+ const int m = (((int)seconds) / 60) % 60;
+ const int s = (((int)seconds) % 60);
+ const int r = (((int)(seconds * 100)) % 100);
+
+ if (h > 0) {
+ return string_printf("%.2d:%.2d:%.2d.%.2d", h, m, s, r);
+ }
+ else {
+ return string_printf("%.2d:%.2d.%.2d", m, s, r);
+ }
}
-double time_human_readable_to_seconds(const string& time_string)
+double time_human_readable_to_seconds(const string &time_string)
{
- /* Those are multiplies of a corresponding token surrounded by : in the
- * time string, which denotes how to convert value to seconds.
- * Effectively: seconds, minutes, hours, days in seconds. */
- const int multipliers[] = {1, 60, 60*60, 24*60*60};
- const int num_multiplies = sizeof(multipliers) / sizeof(*multipliers);
- if(time_string.empty()) {
- return 0.0;
- }
- double result = 0.0;
- /* Split fractions of a second from the encoded time. */
- vector<string> fraction_tokens;
- string_split(fraction_tokens, time_string, ".", false);
- const int num_fraction_tokens = fraction_tokens.size();
- if(num_fraction_tokens == 0) {
- /* Time string is malformed. */
- return 0.0;
- }
- else if(fraction_tokens.size() == 1) {
- /* There is no fraction of a second specified, the rest of the code
- * handles this normally. */
- }
- else if(fraction_tokens.size() == 2) {
- result = atof(fraction_tokens[1].c_str());
- result *= pow(0.1, fraction_tokens[1].length());
- }
- else {
- /* This is not a valid string, the result can not be reliable. */
- return 0.0;
- }
- /* Split hours, minutes and seconds.
- * Hours part is optional. */
- vector<string> tokens;
- string_split(tokens, fraction_tokens[0], ":", false);
- const int num_tokens = tokens.size();
- if(num_tokens > num_multiplies) {
- /* Can not reliably represent the value. */
- return 0.0;
- }
- for(int i = 0; i < num_tokens; ++i) {
- result += atoi(tokens[num_tokens - i - 1].c_str()) * multipliers[i];
- }
- return result;
+ /* Those are multiplies of a corresponding token surrounded by : in the
+ * time string, which denotes how to convert value to seconds.
+ * Effectively: seconds, minutes, hours, days in seconds. */
+ const int multipliers[] = {1, 60, 60 * 60, 24 * 60 * 60};
+ const int num_multiplies = sizeof(multipliers) / sizeof(*multipliers);
+ if (time_string.empty()) {
+ return 0.0;
+ }
+ double result = 0.0;
+ /* Split fractions of a second from the encoded time. */
+ vector<string> fraction_tokens;
+ string_split(fraction_tokens, time_string, ".", false);
+ const int num_fraction_tokens = fraction_tokens.size();
+ if (num_fraction_tokens == 0) {
+ /* Time string is malformed. */
+ return 0.0;
+ }
+ else if (fraction_tokens.size() == 1) {
+ /* There is no fraction of a second specified, the rest of the code
+ * handles this normally. */
+ }
+ else if (fraction_tokens.size() == 2) {
+ result = atof(fraction_tokens[1].c_str());
+ result *= pow(0.1, fraction_tokens[1].length());
+ }
+ else {
+ /* This is not a valid string, the result can not be reliable. */
+ return 0.0;
+ }
+ /* Split hours, minutes and seconds.
+ * Hours part is optional. */
+ vector<string> tokens;
+ string_split(tokens, fraction_tokens[0], ":", false);
+ const int num_tokens = tokens.size();
+ if (num_tokens > num_multiplies) {
+ /* Can not reliably represent the value. */
+ return 0.0;
+ }
+ for (int i = 0; i < num_tokens; ++i) {
+ result += atoi(tokens[num_tokens - i - 1].c_str()) * multipliers[i];
+ }
+ return result;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_time.h b/intern/cycles/util/util_time.h
index ed4dd5154d7..bc9a7414312 100644
--- a/intern/cycles/util/util_time.h
+++ b/intern/cycles/util/util_time.h
@@ -32,38 +32,38 @@ void time_sleep(double t);
/* Scoped timer. */
class scoped_timer {
-public:
- explicit scoped_timer(double *value = NULL) : value_(value)
- {
- time_start_ = time_dt();
- }
-
- ~scoped_timer()
- {
- if(value_ != NULL) {
- *value_ = get_time();
- }
- }
-
- double get_start() const
- {
- return time_start_;
- }
-
- double get_time() const
- {
- return time_dt() - time_start_;
- }
-
-protected:
- double *value_;
- double time_start_;
+ public:
+ explicit scoped_timer(double *value = NULL) : value_(value)
+ {
+ time_start_ = time_dt();
+ }
+
+ ~scoped_timer()
+ {
+ if (value_ != NULL) {
+ *value_ = get_time();
+ }
+ }
+
+ double get_start() const
+ {
+ return time_start_;
+ }
+
+ double get_time() const
+ {
+ return time_dt() - time_start_;
+ }
+
+ protected:
+ double *value_;
+ double time_start_;
};
/* Make human readable string from time, compatible with Blender metadata. */
string time_human_readable_from_seconds(const double seconds);
-double time_human_readable_to_seconds(const string& str);
+double time_human_readable_to_seconds(const string &str);
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index c72e729a2e5..6a9bfbea4ca 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -58,232 +58,230 @@ CCL_NAMESPACE_BEGIN
static bool transform_matrix4_gj_inverse(float R[][4], float M[][4])
{
- /* forward elimination */
- for(int i = 0; i < 4; i++) {
- int pivot = i;
- float pivotsize = M[i][i];
-
- if(pivotsize < 0)
- pivotsize = -pivotsize;
-
- for(int j = i + 1; j < 4; j++) {
- float tmp = M[j][i];
-
- if(tmp < 0)
- tmp = -tmp;
-
- if(tmp > pivotsize) {
- pivot = j;
- pivotsize = tmp;
- }
- }
-
- if(UNLIKELY(pivotsize == 0.0f))
- return false;
-
- if(pivot != i) {
- for(int j = 0; j < 4; j++) {
- float tmp;
-
- tmp = M[i][j];
- M[i][j] = M[pivot][j];
- M[pivot][j] = tmp;
-
- tmp = R[i][j];
- R[i][j] = R[pivot][j];
- R[pivot][j] = tmp;
- }
- }
-
- for(int j = i + 1; j < 4; j++) {
- float f = M[j][i] / M[i][i];
-
- for(int k = 0; k < 4; k++) {
- M[j][k] -= f*M[i][k];
- R[j][k] -= f*R[i][k];
- }
- }
- }
-
- /* backward substitution */
- for(int i = 3; i >= 0; --i) {
- float f;
-
- if(UNLIKELY((f = M[i][i]) == 0.0f))
- return false;
-
- for(int j = 0; j < 4; j++) {
- M[i][j] /= f;
- R[i][j] /= f;
- }
-
- for(int j = 0; j < i; j++) {
- f = M[j][i];
-
- for(int k = 0; k < 4; k++) {
- M[j][k] -= f*M[i][k];
- R[j][k] -= f*R[i][k];
- }
- }
- }
-
- return true;
+ /* forward elimination */
+ for (int i = 0; i < 4; i++) {
+ int pivot = i;
+ float pivotsize = M[i][i];
+
+ if (pivotsize < 0)
+ pivotsize = -pivotsize;
+
+ for (int j = i + 1; j < 4; j++) {
+ float tmp = M[j][i];
+
+ if (tmp < 0)
+ tmp = -tmp;
+
+ if (tmp > pivotsize) {
+ pivot = j;
+ pivotsize = tmp;
+ }
+ }
+
+ if (UNLIKELY(pivotsize == 0.0f))
+ return false;
+
+ if (pivot != i) {
+ for (int j = 0; j < 4; j++) {
+ float tmp;
+
+ tmp = M[i][j];
+ M[i][j] = M[pivot][j];
+ M[pivot][j] = tmp;
+
+ tmp = R[i][j];
+ R[i][j] = R[pivot][j];
+ R[pivot][j] = tmp;
+ }
+ }
+
+ for (int j = i + 1; j < 4; j++) {
+ float f = M[j][i] / M[i][i];
+
+ for (int k = 0; k < 4; k++) {
+ M[j][k] -= f * M[i][k];
+ R[j][k] -= f * R[i][k];
+ }
+ }
+ }
+
+ /* backward substitution */
+ for (int i = 3; i >= 0; --i) {
+ float f;
+
+ if (UNLIKELY((f = M[i][i]) == 0.0f))
+ return false;
+
+ for (int j = 0; j < 4; j++) {
+ M[i][j] /= f;
+ R[i][j] /= f;
+ }
+
+ for (int j = 0; j < i; j++) {
+ f = M[j][i];
+
+ for (int k = 0; k < 4; k++) {
+ M[j][k] -= f * M[i][k];
+ R[j][k] -= f * R[i][k];
+ }
+ }
+ }
+
+ return true;
}
-ProjectionTransform projection_inverse(const ProjectionTransform& tfm)
+ProjectionTransform projection_inverse(const ProjectionTransform &tfm)
{
- ProjectionTransform tfmR = projection_identity();
- float M[4][4], R[4][4];
+ ProjectionTransform tfmR = projection_identity();
+ float M[4][4], R[4][4];
- memcpy(R, &tfmR, sizeof(R));
- memcpy(M, &tfm, sizeof(M));
+ memcpy(R, &tfmR, sizeof(R));
+ memcpy(M, &tfm, sizeof(M));
- if(UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
- /* matrix is degenerate (e.g. 0 scale on some axis), ideally we should
- * never be in this situation, but try to invert it anyway with tweak */
- M[0][0] += 1e-8f;
- M[1][1] += 1e-8f;
- M[2][2] += 1e-8f;
+ if (UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
+ /* matrix is degenerate (e.g. 0 scale on some axis), ideally we should
+ * never be in this situation, but try to invert it anyway with tweak */
+ M[0][0] += 1e-8f;
+ M[1][1] += 1e-8f;
+ M[2][2] += 1e-8f;
- if(UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
- return projection_identity();
- }
- }
+ if (UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
+ return projection_identity();
+ }
+ }
- memcpy(&tfmR, R, sizeof(R));
+ memcpy(&tfmR, R, sizeof(R));
- return tfmR;
+ return tfmR;
}
-Transform transform_inverse(const Transform& tfm)
+Transform transform_inverse(const Transform &tfm)
{
- ProjectionTransform projection(tfm);
- return projection_to_transform(projection_inverse(projection));
+ ProjectionTransform projection(tfm);
+ return projection_to_transform(projection_inverse(projection));
}
-Transform transform_transposed_inverse(const Transform& tfm)
+Transform transform_transposed_inverse(const Transform &tfm)
{
- ProjectionTransform projection(tfm);
- ProjectionTransform iprojection = projection_inverse(projection);
- return projection_to_transform(projection_transpose(iprojection));
+ ProjectionTransform projection(tfm);
+ ProjectionTransform iprojection = projection_inverse(projection);
+ return projection_to_transform(projection_transpose(iprojection));
}
/* Motion Transform */
-float4 transform_to_quat(const Transform& tfm)
+float4 transform_to_quat(const Transform &tfm)
{
- double trace = (double)(tfm[0][0] + tfm[1][1] + tfm[2][2]);
- float4 qt;
+ double trace = (double)(tfm[0][0] + tfm[1][1] + tfm[2][2]);
+ float4 qt;
- if(trace > 0.0) {
- double s = sqrt(trace + 1.0);
+ if (trace > 0.0) {
+ double s = sqrt(trace + 1.0);
- qt.w = (float)(s/2.0);
- s = 0.5/s;
+ qt.w = (float)(s / 2.0);
+ s = 0.5 / s;
- qt.x = (float)((double)(tfm[2][1] - tfm[1][2]) * s);
- qt.y = (float)((double)(tfm[0][2] - tfm[2][0]) * s);
- qt.z = (float)((double)(tfm[1][0] - tfm[0][1]) * s);
- }
- else {
- int i = 0;
+ qt.x = (float)((double)(tfm[2][1] - tfm[1][2]) * s);
+ qt.y = (float)((double)(tfm[0][2] - tfm[2][0]) * s);
+ qt.z = (float)((double)(tfm[1][0] - tfm[0][1]) * s);
+ }
+ else {
+ int i = 0;
- if(tfm[1][1] > tfm[i][i])
- i = 1;
- if(tfm[2][2] > tfm[i][i])
- i = 2;
+ if (tfm[1][1] > tfm[i][i])
+ i = 1;
+ if (tfm[2][2] > tfm[i][i])
+ i = 2;
- int j = (i + 1)%3;
- int k = (j + 1)%3;
+ int j = (i + 1) % 3;
+ int k = (j + 1) % 3;
- double s = sqrt((double)(tfm[i][i] - (tfm[j][j] + tfm[k][k])) + 1.0);
+ double s = sqrt((double)(tfm[i][i] - (tfm[j][j] + tfm[k][k])) + 1.0);
- double q[3];
- q[i] = s * 0.5;
- if(s != 0.0)
- s = 0.5/s;
+ double q[3];
+ q[i] = s * 0.5;
+ if (s != 0.0)
+ s = 0.5 / s;
- double w = (double)(tfm[k][j] - tfm[j][k]) * s;
- q[j] = (double)(tfm[j][i] + tfm[i][j]) * s;
- q[k] = (double)(tfm[k][i] + tfm[i][k]) * s;
+ double w = (double)(tfm[k][j] - tfm[j][k]) * s;
+ q[j] = (double)(tfm[j][i] + tfm[i][j]) * s;
+ q[k] = (double)(tfm[k][i] + tfm[i][k]) * s;
- qt.x = (float)q[0];
- qt.y = (float)q[1];
- qt.z = (float)q[2];
- qt.w = (float)w;
- }
+ qt.x = (float)q[0];
+ qt.y = (float)q[1];
+ qt.z = (float)q[2];
+ qt.w = (float)w;
+ }
- return qt;
+ return qt;
}
static void transform_decompose(DecomposedTransform *decomp, const Transform *tfm)
{
- /* extract translation */
- decomp->y = make_float4(tfm->x.w, tfm->y.w, tfm->z.w, 0.0f);
-
- /* extract rotation */
- Transform M = *tfm;
- M.x.w = 0.0f; M.y.w = 0.0f; M.z.w = 0.0f;
-
- Transform R = M;
- float norm;
- int iteration = 0;
-
- do {
- Transform Rnext;
- Transform Rit = transform_transposed_inverse(R);
-
- for(int i = 0; i < 3; i++)
- for(int j = 0; j < 4; j++)
- Rnext[i][j] = 0.5f * (R[i][j] + Rit[i][j]);
-
- norm = 0.0f;
- for(int i = 0; i < 3; i++) {
- norm = max(norm,
- fabsf(R[i][0] - Rnext[i][0]) +
- fabsf(R[i][1] - Rnext[i][1]) +
- fabsf(R[i][2] - Rnext[i][2]));
- }
-
- R = Rnext;
- iteration++;
- } while(iteration < 100 && norm > 1e-4f);
-
- if(transform_negative_scale(R))
- R = R * transform_scale(-1.0f, -1.0f, -1.0f);
-
- decomp->x = transform_to_quat(R);
-
- /* extract scale and pack it */
- Transform scale = transform_inverse(R) * M;
- decomp->y.w = scale.x.x;
- decomp->z = make_float4(scale.x.y, scale.x.z, scale.y.x, scale.y.y);
- decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
+ /* extract translation */
+ decomp->y = make_float4(tfm->x.w, tfm->y.w, tfm->z.w, 0.0f);
+
+ /* extract rotation */
+ Transform M = *tfm;
+ M.x.w = 0.0f;
+ M.y.w = 0.0f;
+ M.z.w = 0.0f;
+
+ Transform R = M;
+ float norm;
+ int iteration = 0;
+
+ do {
+ Transform Rnext;
+ Transform Rit = transform_transposed_inverse(R);
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 4; j++)
+ Rnext[i][j] = 0.5f * (R[i][j] + Rit[i][j]);
+
+ norm = 0.0f;
+ for (int i = 0; i < 3; i++) {
+ norm = max(norm,
+ fabsf(R[i][0] - Rnext[i][0]) + fabsf(R[i][1] - Rnext[i][1]) +
+ fabsf(R[i][2] - Rnext[i][2]));
+ }
+
+ R = Rnext;
+ iteration++;
+ } while (iteration < 100 && norm > 1e-4f);
+
+ if (transform_negative_scale(R))
+ R = R * transform_scale(-1.0f, -1.0f, -1.0f);
+
+ decomp->x = transform_to_quat(R);
+
+ /* extract scale and pack it */
+ Transform scale = transform_inverse(R) * M;
+ decomp->y.w = scale.x.x;
+ decomp->z = make_float4(scale.x.y, scale.x.z, scale.y.x, scale.y.y);
+ decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
}
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size)
{
- for(size_t i = 0; i < size; i++) {
- transform_decompose(decomp + i, motion + i);
-
- if(i > 0) {
- /* Ensure rotation around shortest angle, negated quaternions are the same
- * but this means we don't have to do the check in quat_interpolate */
- if(dot(decomp[i-1].x, decomp[i].x) < 0.0f)
- decomp[i-1].x = -decomp[i-1].x;
- }
- }
+ for (size_t i = 0; i < size; i++) {
+ transform_decompose(decomp + i, motion + i);
+
+ if (i > 0) {
+ /* Ensure rotation around shortest angle, negated quaternions are the same
+ * but this means we don't have to do the check in quat_interpolate */
+ if (dot(decomp[i - 1].x, decomp[i].x) < 0.0f)
+ decomp[i - 1].x = -decomp[i - 1].x;
+ }
+ }
}
-Transform transform_from_viewplane(BoundBox2D& viewplane)
+Transform transform_from_viewplane(BoundBox2D &viewplane)
{
- return
- transform_scale(1.0f / (viewplane.right - viewplane.left),
- 1.0f / (viewplane.top - viewplane.bottom),
- 1.0f) *
- transform_translate(-viewplane.left,
- -viewplane.bottom,
- 0.0f);
+ return transform_scale(1.0f / (viewplane.right - viewplane.left),
+ 1.0f / (viewplane.top - viewplane.bottom),
+ 1.0f) *
+ transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index e4cadd3e81a..13ca27c2fed 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -18,7 +18,7 @@
#define __UTIL_TRANSFORM_H__
#ifndef __KERNEL_GPU__
-#include <string.h>
+# include <string.h>
#endif
#include "util/util_math.h"
@@ -29,11 +29,17 @@ CCL_NAMESPACE_BEGIN
/* Affine transformation, stored as 4x3 matrix. */
typedef struct Transform {
- float4 x, y, z;
+ float4 x, y, z;
#ifndef __KERNEL_GPU__
- float4 operator[](int i) const { return *(&x + i); }
- float4& operator[](int i) { return *(&x + i); }
+ float4 operator[](int i) const
+ {
+ return *(&x + i);
+ }
+ float4 &operator[](int i)
+ {
+ return *(&x + i);
+ }
#endif
} Transform;
@@ -42,267 +48,268 @@ typedef struct Transform {
* rotation (4), then translation (3), then 3x3 scale matrix (9). */
typedef struct DecomposedTransform {
- float4 x, y, z, w;
+ float4 x, y, z, w;
} DecomposedTransform;
/* Functions */
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)
{
- /* TODO(sergey): Disabled for now, causes crashes in certain cases. */
+ /* TODO(sergey): Disabled for now, causes crashes in certain cases. */
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
- ssef x, y, z, w, aa;
- aa = a.m128;
+ ssef x, y, z, w, aa;
+ aa = a.m128;
- x = _mm_loadu_ps(&t->x.x);
- y = _mm_loadu_ps(&t->y.x);
- z = _mm_loadu_ps(&t->z.x);
- w = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
+ x = _mm_loadu_ps(&t->x.x);
+ y = _mm_loadu_ps(&t->y.x);
+ z = _mm_loadu_ps(&t->z.x);
+ w = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
- _MM_TRANSPOSE4_PS(x, y, z, w);
+ _MM_TRANSPOSE4_PS(x, y, z, w);
- ssef tmp = shuffle<0>(aa) * x;
- tmp = madd(shuffle<1>(aa), y, tmp);
- tmp = madd(shuffle<2>(aa), z, tmp);
- tmp += w;
+ ssef tmp = shuffle<0>(aa) * x;
+ tmp = madd(shuffle<1>(aa), y, tmp);
+ tmp = madd(shuffle<2>(aa), z, tmp);
+ tmp += w;
- return float3(tmp.m128);
+ return float3(tmp.m128);
#else
- float3 c = make_float3(
- a.x*t->x.x + a.y*t->x.y + a.z*t->x.z + t->x.w,
- a.x*t->y.x + a.y*t->y.y + a.z*t->y.z + t->y.w,
- a.x*t->z.x + a.y*t->z.y + a.z*t->z.z + t->z.w);
+ float3 c = make_float3(a.x * t->x.x + a.y * t->x.y + a.z * t->x.z + t->x.w,
+ a.x * t->y.x + a.y * t->y.y + a.z * t->y.z + t->y.w,
+ a.x * t->z.x + a.y * t->z.y + a.z * t->z.z + t->z.w);
- return c;
+ return c;
#endif
}
ccl_device_inline float3 transform_direction(const Transform *t, const float3 a)
{
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
- ssef x, y, z, w, aa;
- aa = a.m128;
- x = _mm_loadu_ps(&t->x.x);
- y = _mm_loadu_ps(&t->y.x);
- z = _mm_loadu_ps(&t->z.x);
- w = _mm_setzero_ps();
+ ssef x, y, z, w, aa;
+ aa = a.m128;
+ x = _mm_loadu_ps(&t->x.x);
+ y = _mm_loadu_ps(&t->y.x);
+ z = _mm_loadu_ps(&t->z.x);
+ w = _mm_setzero_ps();
- _MM_TRANSPOSE4_PS(x, y, z, w);
+ _MM_TRANSPOSE4_PS(x, y, z, w);
- ssef tmp = shuffle<0>(aa) * x;
- tmp = madd(shuffle<1>(aa), y, tmp);
- tmp = madd(shuffle<2>(aa), z, tmp);
+ ssef tmp = shuffle<0>(aa) * x;
+ tmp = madd(shuffle<1>(aa), y, tmp);
+ tmp = madd(shuffle<2>(aa), z, tmp);
- return float3(tmp.m128);
+ return float3(tmp.m128);
#else
- float3 c = make_float3(
- a.x*t->x.x + a.y*t->x.y + a.z*t->x.z,
- a.x*t->y.x + a.y*t->y.y + a.z*t->y.z,
- a.x*t->z.x + a.y*t->z.y + a.z*t->z.z);
+ float3 c = make_float3(a.x * t->x.x + a.y * t->x.y + a.z * t->x.z,
+ a.x * t->y.x + a.y * t->y.y + a.z * t->y.z,
+ a.x * t->z.x + a.y * t->z.y + a.z * t->z.z);
- return c;
+ return c;
#endif
}
ccl_device_inline float3 transform_direction_transposed(const Transform *t, const float3 a)
{
- float3 x = make_float3(t->x.x, t->y.x, t->z.x);
- float3 y = make_float3(t->x.y, t->y.y, t->z.y);
- float3 z = make_float3(t->x.z, t->y.z, t->z.z);
+ float3 x = make_float3(t->x.x, t->y.x, t->z.x);
+ float3 y = make_float3(t->x.y, t->y.y, t->z.y);
+ float3 z = make_float3(t->x.z, t->y.z, t->z.z);
- return make_float3(dot(x, a), dot(y, a), dot(z, a));
+ return make_float3(dot(x, a), dot(y, a), dot(z, a));
}
-ccl_device_inline Transform make_transform(float a, float b, float c, float d,
- float e, float f, float g, float h,
- float i, float j, float k, float l)
+ccl_device_inline Transform make_transform(float a,
+ float b,
+ float c,
+ float d,
+ float e,
+ float f,
+ float g,
+ float h,
+ float i,
+ float j,
+ float k,
+ float l)
{
- Transform t;
-
- t.x.x = a; t.x.y = b; t.x.z = c; t.x.w = d;
- t.y.x = e; t.y.y = f; t.y.z = g; t.y.w = h;
- t.z.x = i; t.z.y = j; t.z.z = k; t.z.w = l;
-
- return t;
+ Transform t;
+
+ t.x.x = a;
+ t.x.y = b;
+ t.x.z = c;
+ t.x.w = d;
+ t.y.x = e;
+ t.y.y = f;
+ t.y.z = g;
+ t.y.w = h;
+ t.z.x = i;
+ t.z.y = j;
+ t.z.z = k;
+ t.z.w = l;
+
+ return t;
}
/* Constructs a coordinate frame from a normalized normal. */
ccl_device_inline Transform make_transform_frame(float3 N)
{
- const float3 dx0 = cross(make_float3(1.0f, 0.0f, 0.0f), N);
- const float3 dx1 = cross(make_float3(0.0f, 1.0f, 0.0f), N);
- const float3 dx = normalize((dot(dx0,dx0) > dot(dx1,dx1))? dx0: dx1);
- const float3 dy = normalize(cross(N, dx));
- return make_transform(dx.x, dx.y, dx.z, 0.0f,
- dy.x, dy.y, dy.z, 0.0f,
- N.x , N.y, N.z, 0.0f);
+ const float3 dx0 = cross(make_float3(1.0f, 0.0f, 0.0f), N);
+ const float3 dx1 = cross(make_float3(0.0f, 1.0f, 0.0f), N);
+ const float3 dx = normalize((dot(dx0, dx0) > dot(dx1, dx1)) ? dx0 : dx1);
+ const float3 dy = normalize(cross(N, dx));
+ return make_transform(dx.x, dx.y, dx.z, 0.0f, dy.x, dy.y, dy.z, 0.0f, N.x, N.y, N.z, 0.0f);
}
#ifndef __KERNEL_GPU__
ccl_device_inline Transform operator*(const Transform a, const Transform b)
{
- float4 c_x = make_float4(b.x.x, b.y.x, b.z.x, 0.0f);
- float4 c_y = make_float4(b.x.y, b.y.y, b.z.y, 0.0f);
- float4 c_z = make_float4(b.x.z, b.y.z, b.z.z, 0.0f);
- float4 c_w = make_float4(b.x.w, b.y.w, b.z.w, 1.0f);
+ float4 c_x = make_float4(b.x.x, b.y.x, b.z.x, 0.0f);
+ float4 c_y = make_float4(b.x.y, b.y.y, b.z.y, 0.0f);
+ float4 c_z = make_float4(b.x.z, b.y.z, b.z.z, 0.0f);
+ float4 c_w = make_float4(b.x.w, b.y.w, b.z.w, 1.0f);
- Transform t;
- t.x = make_float4(dot(a.x, c_x), dot(a.x, c_y), dot(a.x, c_z), dot(a.x, c_w));
- t.y = make_float4(dot(a.y, c_x), dot(a.y, c_y), dot(a.y, c_z), dot(a.y, c_w));
- t.z = make_float4(dot(a.z, c_x), dot(a.z, c_y), dot(a.z, c_z), dot(a.z, c_w));
+ Transform t;
+ t.x = make_float4(dot(a.x, c_x), dot(a.x, c_y), dot(a.x, c_z), dot(a.x, c_w));
+ t.y = make_float4(dot(a.y, c_x), dot(a.y, c_y), dot(a.y, c_z), dot(a.y, c_w));
+ t.z = make_float4(dot(a.z, c_x), dot(a.z, c_y), dot(a.z, c_z), dot(a.z, c_w));
- return t;
+ return t;
}
-ccl_device_inline void print_transform(const char *label, const Transform& t)
+ccl_device_inline void print_transform(const char *label, const Transform &t)
{
- print_float4(label, t.x);
- print_float4(label, t.y);
- print_float4(label, t.z);
- printf("\n");
+ print_float4(label, t.x);
+ print_float4(label, t.y);
+ print_float4(label, t.z);
+ printf("\n");
}
ccl_device_inline Transform transform_translate(float3 t)
{
- return make_transform(
- 1, 0, 0, t.x,
- 0, 1, 0, t.y,
- 0, 0, 1, t.z);
+ return make_transform(1, 0, 0, t.x, 0, 1, 0, t.y, 0, 0, 1, t.z);
}
ccl_device_inline Transform transform_translate(float x, float y, float z)
{
- return transform_translate(make_float3(x, y, z));
+ return transform_translate(make_float3(x, y, z));
}
ccl_device_inline Transform transform_scale(float3 s)
{
- return make_transform(
- s.x, 0, 0, 0,
- 0, s.y, 0, 0,
- 0, 0, s.z, 0);
+ return make_transform(s.x, 0, 0, 0, 0, s.y, 0, 0, 0, 0, s.z, 0);
}
ccl_device_inline Transform transform_scale(float x, float y, float z)
{
- return transform_scale(make_float3(x, y, z));
+ return transform_scale(make_float3(x, y, z));
}
ccl_device_inline Transform transform_rotate(float angle, float3 axis)
{
- float s = sinf(angle);
- float c = cosf(angle);
- float t = 1.0f - c;
-
- axis = normalize(axis);
-
- return make_transform(
- axis.x*axis.x*t + c,
- axis.x*axis.y*t - s*axis.z,
- axis.x*axis.z*t + s*axis.y,
- 0.0f,
-
- axis.y*axis.x*t + s*axis.z,
- axis.y*axis.y*t + c,
- axis.y*axis.z*t - s*axis.x,
- 0.0f,
-
- axis.z*axis.x*t - s*axis.y,
- axis.z*axis.y*t + s*axis.x,
- axis.z*axis.z*t + c,
- 0.0f);
+ float s = sinf(angle);
+ float c = cosf(angle);
+ float t = 1.0f - c;
+
+ axis = normalize(axis);
+
+ return make_transform(axis.x * axis.x * t + c,
+ axis.x * axis.y * t - s * axis.z,
+ axis.x * axis.z * t + s * axis.y,
+ 0.0f,
+
+ axis.y * axis.x * t + s * axis.z,
+ axis.y * axis.y * t + c,
+ axis.y * axis.z * t - s * axis.x,
+ 0.0f,
+
+ axis.z * axis.x * t - s * axis.y,
+ axis.z * axis.y * t + s * axis.x,
+ axis.z * axis.z * t + c,
+ 0.0f);
}
/* Euler is assumed to be in XYZ order. */
ccl_device_inline Transform transform_euler(float3 euler)
{
- return
- transform_rotate(euler.z, make_float3(0.0f, 0.0f, 1.0f)) *
- transform_rotate(euler.y, make_float3(0.0f, 1.0f, 0.0f)) *
- transform_rotate(euler.x, make_float3(1.0f, 0.0f, 0.0f));
+ return transform_rotate(euler.z, make_float3(0.0f, 0.0f, 1.0f)) *
+ transform_rotate(euler.y, make_float3(0.0f, 1.0f, 0.0f)) *
+ transform_rotate(euler.x, make_float3(1.0f, 0.0f, 0.0f));
}
ccl_device_inline Transform transform_identity()
{
- return transform_scale(1.0f, 1.0f, 1.0f);
+ return transform_scale(1.0f, 1.0f, 1.0f);
}
-ccl_device_inline bool operator==(const Transform& A, const Transform& B)
+ccl_device_inline bool operator==(const Transform &A, const Transform &B)
{
- return memcmp(&A, &B, sizeof(Transform)) == 0;
+ return memcmp(&A, &B, sizeof(Transform)) == 0;
}
-ccl_device_inline bool operator!=(const Transform& A, const Transform& B)
+ccl_device_inline bool operator!=(const Transform &A, const Transform &B)
{
- return !(A == B);
+ return !(A == B);
}
ccl_device_inline float3 transform_get_column(const Transform *t, int column)
{
- return make_float3(t->x[column], t->y[column], t->z[column]);
+ return make_float3(t->x[column], t->y[column], t->z[column]);
}
ccl_device_inline void transform_set_column(Transform *t, int column, float3 value)
{
- t->x[column] = value.x;
- t->y[column] = value.y;
- t->z[column] = value.z;
+ t->x[column] = value.x;
+ t->y[column] = value.y;
+ t->z[column] = value.z;
}
-Transform transform_inverse(const Transform& a);
-Transform transform_transposed_inverse(const Transform& a);
+Transform transform_inverse(const Transform &a);
+Transform transform_transposed_inverse(const Transform &a);
-ccl_device_inline bool transform_uniform_scale(const Transform& tfm, float& scale)
+ccl_device_inline bool transform_uniform_scale(const Transform &tfm, float &scale)
{
- /* the epsilon here is quite arbitrary, but this function is only used for
- * surface area and bump, where we expect it to not be so sensitive */
- float eps = 1e-6f;
-
- float sx = len_squared(float4_to_float3(tfm.x));
- float sy = len_squared(float4_to_float3(tfm.y));
- float sz = len_squared(float4_to_float3(tfm.z));
- float stx = len_squared(transform_get_column(&tfm, 0));
- float sty = len_squared(transform_get_column(&tfm, 1));
- float stz = len_squared(transform_get_column(&tfm, 2));
-
- if(fabsf(sx - sy) < eps && fabsf(sx - sz) < eps &&
- fabsf(sx - stx) < eps && fabsf(sx - sty) < eps &&
- fabsf(sx - stz) < eps)
- {
- scale = sx;
- return true;
- }
-
- return false;
+ /* the epsilon here is quite arbitrary, but this function is only used for
+ * surface area and bump, where we expect it to not be so sensitive */
+ float eps = 1e-6f;
+
+ float sx = len_squared(float4_to_float3(tfm.x));
+ float sy = len_squared(float4_to_float3(tfm.y));
+ float sz = len_squared(float4_to_float3(tfm.z));
+ float stx = len_squared(transform_get_column(&tfm, 0));
+ float sty = len_squared(transform_get_column(&tfm, 1));
+ float stz = len_squared(transform_get_column(&tfm, 2));
+
+ if (fabsf(sx - sy) < eps && fabsf(sx - sz) < eps && fabsf(sx - stx) < eps &&
+ fabsf(sx - sty) < eps && fabsf(sx - stz) < eps) {
+ scale = sx;
+ return true;
+ }
+
+ return false;
}
-ccl_device_inline bool transform_negative_scale(const Transform& tfm)
+ccl_device_inline bool transform_negative_scale(const Transform &tfm)
{
- float3 c0 = transform_get_column(&tfm, 0);
- float3 c1 = transform_get_column(&tfm, 1);
- float3 c2 = transform_get_column(&tfm, 2);
+ float3 c0 = transform_get_column(&tfm, 0);
+ float3 c1 = transform_get_column(&tfm, 1);
+ float3 c2 = transform_get_column(&tfm, 2);
- return (dot(cross(c0, c1), c2) < 0.0f);
+ return (dot(cross(c0, c1), c2) < 0.0f);
}
-ccl_device_inline Transform transform_clear_scale(const Transform& tfm)
+ccl_device_inline Transform transform_clear_scale(const Transform &tfm)
{
- Transform ntfm = tfm;
+ Transform ntfm = tfm;
- transform_set_column(&ntfm, 0, normalize(transform_get_column(&ntfm, 0)));
- transform_set_column(&ntfm, 1, normalize(transform_get_column(&ntfm, 1)));
- transform_set_column(&ntfm, 2, normalize(transform_get_column(&ntfm, 2)));
+ transform_set_column(&ntfm, 0, normalize(transform_get_column(&ntfm, 0)));
+ transform_set_column(&ntfm, 1, normalize(transform_get_column(&ntfm, 1)));
+ transform_set_column(&ntfm, 2, normalize(transform_get_column(&ntfm, 2)));
- return ntfm;
+ return ntfm;
}
ccl_device_inline Transform transform_empty()
{
- return make_transform(
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0);
+ return make_transform(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
#endif
@@ -311,90 +318,101 @@ ccl_device_inline Transform transform_empty()
ccl_device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
{
- /* use simpe nlerp instead of slerp. it's faster and almost the same */
- return normalize((1.0f - t)*q1 + t*q2);
+ /* use simpe nlerp instead of slerp. it's faster and almost the same */
+ return normalize((1.0f - t) * q1 + t * q2);
#if 0
- /* note: this does not ensure rotation around shortest angle, q1 and q2
- * are assumed to be matched already in transform_motion_decompose */
- float costheta = dot(q1, q2);
-
- /* possible optimization: it might be possible to precompute theta/qperp */
-
- if(costheta > 0.9995f) {
- /* linear interpolation in degenerate case */
- return normalize((1.0f - t)*q1 + t*q2);
- }
- else {
- /* slerp */
- float theta = acosf(clamp(costheta, -1.0f, 1.0f));
- float4 qperp = normalize(q2 - q1 * costheta);
- float thetap = theta * t;
- return q1 * cosf(thetap) + qperp * sinf(thetap);
- }
+ /* note: this does not ensure rotation around shortest angle, q1 and q2
+ * are assumed to be matched already in transform_motion_decompose */
+ float costheta = dot(q1, q2);
+
+ /* possible optimization: it might be possible to precompute theta/qperp */
+
+ if(costheta > 0.9995f) {
+ /* linear interpolation in degenerate case */
+ return normalize((1.0f - t)*q1 + t*q2);
+ }
+ else {
+ /* slerp */
+ float theta = acosf(clamp(costheta, -1.0f, 1.0f));
+ float4 qperp = normalize(q2 - q1 * costheta);
+ float thetap = theta * t;
+ return q1 * cosf(thetap) + qperp * sinf(thetap);
+ }
#endif
}
ccl_device_inline Transform transform_quick_inverse(Transform M)
{
- /* possible optimization: can we avoid doing this altogether and construct
- * the inverse matrix directly from negated translation, transposed rotation,
- * scale can be inverted but what about shearing? */
- Transform R;
- float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
- if(det == 0.0f) {
- M.x.x += 1e-8f;
- M.y.y += 1e-8f;
- M.z.z += 1e-8f;
- det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
- }
- det = (det != 0.0f)? 1.0f/det: 0.0f;
-
- float3 Rx = det*make_float3(M.z.z*M.y.y - M.z.y*M.y.z, M.z.y*M.x.z - M.z.z*M.x.y, M.y.z*M.x.y - M.y.y*M.x.z);
- float3 Ry = det*make_float3(M.z.x*M.y.z - M.z.z*M.y.x, M.z.z*M.x.x - M.z.x*M.x.z, M.y.x*M.x.z - M.y.z*M.x.x);
- float3 Rz = det*make_float3(M.z.y*M.y.x - M.z.x*M.y.y, M.z.x*M.x.y - M.z.y*M.x.x, M.y.y*M.x.x - M.y.x*M.x.y);
- float3 T = -make_float3(M.x.w, M.y.w, M.z.w);
-
- R.x = make_float4(Rx.x, Rx.y, Rx.z, dot(Rx, T));
- R.y = make_float4(Ry.x, Ry.y, Ry.z, dot(Ry, T));
- R.z = make_float4(Rz.x, Rz.y, Rz.z, dot(Rz, T));
-
- return R;
+ /* possible optimization: can we avoid doing this altogether and construct
+ * the inverse matrix directly from negated translation, transposed rotation,
+ * scale can be inverted but what about shearing? */
+ Transform R;
+ float det = M.x.x * (M.z.z * M.y.y - M.z.y * M.y.z) - M.y.x * (M.z.z * M.x.y - M.z.y * M.x.z) +
+ M.z.x * (M.y.z * M.x.y - M.y.y * M.x.z);
+ if (det == 0.0f) {
+ M.x.x += 1e-8f;
+ M.y.y += 1e-8f;
+ M.z.z += 1e-8f;
+ det = M.x.x * (M.z.z * M.y.y - M.z.y * M.y.z) - M.y.x * (M.z.z * M.x.y - M.z.y * M.x.z) +
+ M.z.x * (M.y.z * M.x.y - M.y.y * M.x.z);
+ }
+ det = (det != 0.0f) ? 1.0f / det : 0.0f;
+
+ float3 Rx = det * make_float3(M.z.z * M.y.y - M.z.y * M.y.z,
+ M.z.y * M.x.z - M.z.z * M.x.y,
+ M.y.z * M.x.y - M.y.y * M.x.z);
+ float3 Ry = det * make_float3(M.z.x * M.y.z - M.z.z * M.y.x,
+ M.z.z * M.x.x - M.z.x * M.x.z,
+ M.y.x * M.x.z - M.y.z * M.x.x);
+ float3 Rz = det * make_float3(M.z.y * M.y.x - M.z.x * M.y.y,
+ M.z.x * M.x.y - M.z.y * M.x.x,
+ M.y.y * M.x.x - M.y.x * M.x.y);
+ float3 T = -make_float3(M.x.w, M.y.w, M.z.w);
+
+ R.x = make_float4(Rx.x, Rx.y, Rx.z, dot(Rx, T));
+ R.y = make_float4(Ry.x, Ry.y, Ry.z, dot(Ry, T));
+ R.z = make_float4(Rz.x, Rz.y, Rz.z, dot(Rz, T));
+
+ return R;
}
ccl_device_inline void transform_compose(Transform *tfm, const DecomposedTransform *decomp)
{
- /* rotation */
- float q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
-
- q0 = M_SQRT2_F * decomp->x.w;
- q1 = M_SQRT2_F * decomp->x.x;
- q2 = M_SQRT2_F * decomp->x.y;
- q3 = M_SQRT2_F * decomp->x.z;
-
- qda = q0*q1;
- qdb = q0*q2;
- qdc = q0*q3;
- qaa = q1*q1;
- qab = q1*q2;
- qac = q1*q3;
- qbb = q2*q2;
- qbc = q2*q3;
- qcc = q3*q3;
-
- float3 rotation_x = make_float3(1.0f-qbb-qcc, -qdc+qab, qdb+qac);
- float3 rotation_y = make_float3(qdc+qab, 1.0f-qaa-qcc, -qda+qbc);
- float3 rotation_z = make_float3(-qdb+qac, qda+qbc, 1.0f-qaa-qbb);
-
- /* scale */
- float3 scale_x = make_float3(decomp->y.w, decomp->z.z, decomp->w.y);
- float3 scale_y = make_float3(decomp->z.x, decomp->z.w, decomp->w.z);
- float3 scale_z = make_float3(decomp->z.y, decomp->w.x, decomp->w.w);
-
- /* compose with translation */
- tfm->x = make_float4(dot(rotation_x, scale_x), dot(rotation_x, scale_y), dot(rotation_x, scale_z), decomp->y.x);
- tfm->y = make_float4(dot(rotation_y, scale_x), dot(rotation_y, scale_y), dot(rotation_y, scale_z), decomp->y.y);
- tfm->z = make_float4(dot(rotation_z, scale_x), dot(rotation_z, scale_y), dot(rotation_z, scale_z), decomp->y.z);
+ /* rotation */
+ float q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
+
+ q0 = M_SQRT2_F * decomp->x.w;
+ q1 = M_SQRT2_F * decomp->x.x;
+ q2 = M_SQRT2_F * decomp->x.y;
+ q3 = M_SQRT2_F * decomp->x.z;
+
+ qda = q0 * q1;
+ qdb = q0 * q2;
+ qdc = q0 * q3;
+ qaa = q1 * q1;
+ qab = q1 * q2;
+ qac = q1 * q3;
+ qbb = q2 * q2;
+ qbc = q2 * q3;
+ qcc = q3 * q3;
+
+ float3 rotation_x = make_float3(1.0f - qbb - qcc, -qdc + qab, qdb + qac);
+ float3 rotation_y = make_float3(qdc + qab, 1.0f - qaa - qcc, -qda + qbc);
+ float3 rotation_z = make_float3(-qdb + qac, qda + qbc, 1.0f - qaa - qbb);
+
+ /* scale */
+ float3 scale_x = make_float3(decomp->y.w, decomp->z.z, decomp->w.y);
+ float3 scale_y = make_float3(decomp->z.x, decomp->z.w, decomp->w.z);
+ float3 scale_z = make_float3(decomp->z.y, decomp->w.x, decomp->w.w);
+
+ /* compose with translation */
+ tfm->x = make_float4(
+ dot(rotation_x, scale_x), dot(rotation_x, scale_y), dot(rotation_x, scale_z), decomp->y.x);
+ tfm->y = make_float4(
+ dot(rotation_y, scale_x), dot(rotation_y, scale_y), dot(rotation_y, scale_z), decomp->y.y);
+ tfm->z = make_float4(
+ dot(rotation_z, scale_x), dot(rotation_z, scale_y), dot(rotation_z, scale_z), decomp->y.z);
}
/* Interpolate from array of decomposed transforms. */
@@ -403,62 +421,60 @@ ccl_device void transform_motion_array_interpolate(Transform *tfm,
uint numsteps,
float time)
{
- /* Figure out which steps we need to interpolate. */
- int maxstep = numsteps-1;
- int step = min((int)(time*maxstep), maxstep-1);
- float t = time*maxstep - step;
-
- const ccl_global DecomposedTransform *a = motion + step;
- const ccl_global DecomposedTransform *b = motion + step + 1;
-
- /* Interpolate rotation, translation and scale. */
- DecomposedTransform decomp;
- decomp.x = quat_interpolate(a->x, b->x, t);
- decomp.y = (1.0f - t)*a->y + t*b->y;
- decomp.z = (1.0f - t)*a->z + t*b->z;
- decomp.w = (1.0f - t)*a->w + t*b->w;
-
- /* Compose rotation, translation, scale into matrix. */
- transform_compose(tfm, &decomp);
+ /* Figure out which steps we need to interpolate. */
+ int maxstep = numsteps - 1;
+ int step = min((int)(time * maxstep), maxstep - 1);
+ float t = time * maxstep - step;
+
+ const ccl_global DecomposedTransform *a = motion + step;
+ const ccl_global DecomposedTransform *b = motion + step + 1;
+
+ /* Interpolate rotation, translation and scale. */
+ DecomposedTransform decomp;
+ decomp.x = quat_interpolate(a->x, b->x, t);
+ decomp.y = (1.0f - t) * a->y + t * b->y;
+ decomp.z = (1.0f - t) * a->z + t * b->z;
+ decomp.w = (1.0f - t) * a->w + t * b->w;
+
+ /* Compose rotation, translation, scale into matrix. */
+ transform_compose(tfm, &decomp);
}
#ifndef __KERNEL_GPU__
-#ifdef WITH_EMBREE
-ccl_device void transform_motion_array_interpolate_straight(Transform *tfm,
- const ccl_global DecomposedTransform *motion,
- uint numsteps,
- float time)
+# ifdef WITH_EMBREE
+ccl_device void transform_motion_array_interpolate_straight(
+ Transform *tfm, const ccl_global DecomposedTransform *motion, uint numsteps, float time)
{
- /* Figure out which steps we need to interpolate. */
- int maxstep = numsteps - 1;
- int step = min((int)(time*maxstep), maxstep - 1);
- float t = time * maxstep - step;
-
- const ccl_global DecomposedTransform *a = motion + step;
- const ccl_global DecomposedTransform *b = motion + step + 1;
- Transform step1, step2;
-
- transform_compose(&step1, a);
- transform_compose(&step2, b);
-
- /* matrix lerp */
- tfm->x = (1.0f - t) * step1.x + t * step2.x;
- tfm->y = (1.0f - t) * step1.y + t * step2.y;
- tfm->z = (1.0f - t) * step1.z + t * step2.z;
+ /* Figure out which steps we need to interpolate. */
+ int maxstep = numsteps - 1;
+ int step = min((int)(time * maxstep), maxstep - 1);
+ float t = time * maxstep - step;
+
+ const ccl_global DecomposedTransform *a = motion + step;
+ const ccl_global DecomposedTransform *b = motion + step + 1;
+ Transform step1, step2;
+
+ transform_compose(&step1, a);
+ transform_compose(&step2, b);
+
+ /* matrix lerp */
+ tfm->x = (1.0f - t) * step1.x + t * step2.x;
+ tfm->y = (1.0f - t) * step1.y + t * step2.y;
+ tfm->z = (1.0f - t) * step1.z + t * step2.z;
}
-#endif
+# endif
class BoundBox2D;
-ccl_device_inline bool operator==(const DecomposedTransform& A, const DecomposedTransform& B)
+ccl_device_inline bool operator==(const DecomposedTransform &A, const DecomposedTransform &B)
{
- return memcmp(&A, &B, sizeof(DecomposedTransform)) == 0;
+ return memcmp(&A, &B, sizeof(DecomposedTransform)) == 0;
}
-float4 transform_to_quat(const Transform& tfm);
+float4 transform_to_quat(const Transform &tfm);
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size);
-Transform transform_from_viewplane(BoundBox2D& viewplane);
+Transform transform_from_viewplane(BoundBox2D &viewplane);
#endif
@@ -469,14 +485,14 @@ Transform transform_from_viewplane(BoundBox2D& viewplane);
#ifdef __KERNEL_OPENCL__
-#define OPENCL_TRANSFORM_ADDRSPACE_GLUE(a, b) a ## b
-#define OPENCL_TRANSFORM_ADDRSPACE_DECLARE(function) \
-ccl_device_inline float3 OPENCL_TRANSFORM_ADDRSPACE_GLUE(function, _addrspace)( \
- ccl_addr_space const Transform *t, const float3 a) \
-{ \
- Transform private_tfm = *t; \
- return function(&private_tfm, a); \
-}
+# define OPENCL_TRANSFORM_ADDRSPACE_GLUE(a, b) a##b
+# define OPENCL_TRANSFORM_ADDRSPACE_DECLARE(function) \
+ ccl_device_inline float3 OPENCL_TRANSFORM_ADDRSPACE_GLUE(function, _addrspace)( \
+ ccl_addr_space const Transform *t, const float3 a) \
+ { \
+ Transform private_tfm = *t; \
+ return function(&private_tfm, a); \
+ }
OPENCL_TRANSFORM_ADDRSPACE_DECLARE(transform_point)
OPENCL_TRANSFORM_ADDRSPACE_DECLARE(transform_direction)
@@ -495,4 +511,4 @@ OPENCL_TRANSFORM_ADDRSPACE_DECLARE(transform_direction_transposed)
CCL_NAMESPACE_END
-#endif /* __UTIL_TRANSFORM_H__ */
+#endif /* __UTIL_TRANSFORM_H__ */
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 535048d8f8c..48e9983ac8f 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -74,31 +74,31 @@ typedef int64_t ssize_t;
# else
typedef int32_t ssize_t;
# endif
-# endif /* _WIN32 */
+# endif /* _WIN32 */
/* Generic Memory Pointer */
typedef uint64_t device_ptr;
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
ccl_device_inline size_t align_up(size_t offset, size_t alignment)
{
- return (offset + alignment - 1) & ~(alignment - 1);
+ return (offset + alignment - 1) & ~(alignment - 1);
}
ccl_device_inline size_t divide_up(size_t x, size_t y)
{
- return (x + y - 1) / y;
+ return (x + y - 1) / y;
}
ccl_device_inline size_t round_up(size_t x, size_t multiple)
{
- return ((x + multiple - 1) / multiple) * multiple;
+ return ((x + multiple - 1) / multiple) * multiple;
}
ccl_device_inline size_t round_down(size_t x, size_t multiple)
{
- return (x / multiple) * multiple;
+ return (x / multiple) * multiple;
}
CCL_NAMESPACE_END
@@ -150,10 +150,10 @@ CCL_NAMESPACE_END
# include "util/util_sseb.h"
# include "util/util_ssei.h"
# include "util/util_ssef.h"
-#if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
-# include "util/util_avxb.h"
-# include "util/util_avxf.h"
-#endif
+# if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
+# include "util/util_avxb.h"
+# include "util/util_avxf.h"
+# endif
#endif
-#endif /* __UTIL_TYPES_H__ */
+#endif /* __UTIL_TYPES_H__ */
diff --git a/intern/cycles/util/util_types_float2.h b/intern/cycles/util/util_types_float2.h
index ec7a1f717a1..3760bf579b6 100644
--- a/intern/cycles/util/util_types_float2.h
+++ b/intern/cycles/util/util_types_float2.h
@@ -25,16 +25,16 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct float2 {
- float x, y;
+ float x, y;
- __forceinline float operator[](int i) const;
- __forceinline float& operator[](int i);
+ __forceinline float operator[](int i) const;
+ __forceinline float &operator[](int i);
};
ccl_device_inline float2 make_float2(float x, float y);
-ccl_device_inline void print_float2(const char *label, const float2& a);
-#endif /* __KERNEL_GPU__ */
+ccl_device_inline void print_float2(const char *label, const float2 &a);
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT2_H__ */
+#endif /* __UTIL_TYPES_FLOAT2_H__ */
diff --git a/intern/cycles/util/util_types_float2_impl.h b/intern/cycles/util/util_types_float2_impl.h
index 782dda195eb..7810d2a8781 100644
--- a/intern/cycles/util/util_types_float2_impl.h
+++ b/intern/cycles/util/util_types_float2_impl.h
@@ -30,30 +30,30 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
__forceinline float float2::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 2);
+ return *(&x + i);
}
-__forceinline float& float2::operator[](int i)
+__forceinline float &float2::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 2);
+ return *(&x + i);
}
ccl_device_inline float2 make_float2(float x, float y)
{
- float2 a = {x, y};
- return a;
+ float2 a = {x, y};
+ return a;
}
-ccl_device_inline void print_float2(const char *label, const float2& a)
+ccl_device_inline void print_float2(const char *label, const float2 &a)
{
- printf("%s: %.8f %.8f\n", label, (double)a.x, (double)a.y);
+ printf("%s: %.8f %.8f\n", label, (double)a.x, (double)a.y);
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT2_IMPL_H__ */
+#endif /* __UTIL_TYPES_FLOAT2_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_float3.h b/intern/cycles/util/util_types_float3.h
index ed2300e7996..694a600bf5c 100644
--- a/intern/cycles/util/util_types_float3.h
+++ b/intern/cycles/util/util_types_float3.h
@@ -24,34 +24,37 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-struct ccl_try_align(16) float3 {
-#ifdef __KERNEL_SSE__
- union {
- __m128 m128;
- struct { float x, y, z, w; };
- };
-
- __forceinline float3();
- __forceinline float3(const float3& a);
- __forceinline explicit float3(const __m128& a);
-
- __forceinline operator const __m128&() const;
- __forceinline operator __m128&();
-
- __forceinline float3& operator =(const float3& a);
-#else /* __KERNEL_SSE__ */
- float x, y, z, w;
-#endif /* __KERNEL_SSE__ */
-
- __forceinline float operator[](int i) const;
- __forceinline float& operator[](int i);
+struct ccl_try_align(16) float3
+{
+# ifdef __KERNEL_SSE__
+ union {
+ __m128 m128;
+ struct {
+ float x, y, z, w;
+ };
+ };
+
+ __forceinline float3();
+ __forceinline float3(const float3 &a);
+ __forceinline explicit float3(const __m128 &a);
+
+ __forceinline operator const __m128 &() const;
+ __forceinline operator __m128 &();
+
+ __forceinline float3 &operator=(const float3 &a);
+# else /* __KERNEL_SSE__ */
+ float x, y, z, w;
+# endif /* __KERNEL_SSE__ */
+
+ __forceinline float operator[](int i) const;
+ __forceinline float &operator[](int i);
};
ccl_device_inline float3 make_float3(float f);
ccl_device_inline float3 make_float3(float x, float y, float z);
-ccl_device_inline void print_float3(const char *label, const float3& a);
-#endif /* __KERNEL_GPU__ */
+ccl_device_inline void print_float3(const char *label, const float3 &a);
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT3_H__ */
+#endif /* __UTIL_TYPES_FLOAT3_H__ */
diff --git a/intern/cycles/util/util_types_float3_impl.h b/intern/cycles/util/util_types_float3_impl.h
index 2e840a5c399..ab25fb4c975 100644
--- a/intern/cycles/util/util_types_float3_impl.h
+++ b/intern/cycles/util/util_types_float3_impl.h
@@ -28,78 +28,76 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-#ifdef __KERNEL_SSE__
+# ifdef __KERNEL_SSE__
__forceinline float3::float3()
{
}
-__forceinline float3::float3(const float3& a)
- : m128(a.m128)
+__forceinline float3::float3(const float3 &a) : m128(a.m128)
{
}
-__forceinline float3::float3(const __m128& a)
- : m128(a)
+__forceinline float3::float3(const __m128 &a) : m128(a)
{
}
-__forceinline float3::operator const __m128&() const
+__forceinline float3::operator const __m128 &() const
{
- return m128;
+ return m128;
}
-__forceinline float3::operator __m128&()
+__forceinline float3::operator __m128 &()
{
- return m128;
+ return m128;
}
-__forceinline float3& float3::operator =(const float3& a)
+__forceinline float3 &float3::operator=(const float3 &a)
{
- m128 = a.m128;
- return *this;
+ m128 = a.m128;
+ return *this;
}
-#endif /* __KERNEL_SSE__ */
+# endif /* __KERNEL_SSE__ */
__forceinline float float3::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 3);
+ return *(&x + i);
}
-__forceinline float& float3::operator[](int i)
+__forceinline float &float3::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 3);
+ return *(&x + i);
}
ccl_device_inline float3 make_float3(float f)
{
-#ifdef __KERNEL_SSE__
- float3 a(_mm_set1_ps(f));
-#else
- float3 a = {f, f, f, f};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ float3 a(_mm_set1_ps(f));
+# else
+ float3 a = {f, f, f, f};
+# endif
+ return a;
}
ccl_device_inline float3 make_float3(float x, float y, float z)
{
-#ifdef __KERNEL_SSE__
- float3 a(_mm_set_ps(0.0f, z, y, x));
-#else
- float3 a = {x, y, z, 0.0f};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ float3 a(_mm_set_ps(0.0f, z, y, x));
+# else
+ float3 a = {x, y, z, 0.0f};
+# endif
+ return a;
}
-ccl_device_inline void print_float3(const char *label, const float3& a)
+ccl_device_inline void print_float3(const char *label, const float3 &a)
{
- printf("%s: %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z);
+ printf("%s: %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z);
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT3_IMPL_H__ */
+#endif /* __UTIL_TYPES_FLOAT3_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_float4.h b/intern/cycles/util/util_types_float4.h
index 5c10d483c2e..c29e6e15bc3 100644
--- a/intern/cycles/util/util_types_float4.h
+++ b/intern/cycles/util/util_types_float4.h
@@ -26,35 +26,38 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct int4;
-struct ccl_try_align(16) float4 {
-#ifdef __KERNEL_SSE__
- union {
- __m128 m128;
- struct { float x, y, z, w; };
- };
-
- __forceinline float4();
- __forceinline explicit float4(const __m128& a);
-
- __forceinline operator const __m128&() const;
- __forceinline operator __m128&();
-
- __forceinline float4& operator =(const float4& a);
-
-#else /* __KERNEL_SSE__ */
- float x, y, z, w;
-#endif /* __KERNEL_SSE__ */
-
- __forceinline float operator[](int i) const;
- __forceinline float& operator[](int i);
+struct ccl_try_align(16) float4
+{
+# ifdef __KERNEL_SSE__
+ union {
+ __m128 m128;
+ struct {
+ float x, y, z, w;
+ };
+ };
+
+ __forceinline float4();
+ __forceinline explicit float4(const __m128 &a);
+
+ __forceinline operator const __m128 &() const;
+ __forceinline operator __m128 &();
+
+ __forceinline float4 &operator=(const float4 &a);
+
+# else /* __KERNEL_SSE__ */
+ float x, y, z, w;
+# endif /* __KERNEL_SSE__ */
+
+ __forceinline float operator[](int i) const;
+ __forceinline float &operator[](int i);
};
ccl_device_inline float4 make_float4(float f);
ccl_device_inline float4 make_float4(float x, float y, float z, float w);
-ccl_device_inline float4 make_float4(const int4& i);
-ccl_device_inline void print_float4(const char *label, const float4& a);
-#endif /* __KERNEL_GPU__ */
+ccl_device_inline float4 make_float4(const int4 &i);
+ccl_device_inline void print_float4(const char *label, const float4 &a);
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT4_H__ */
+#endif /* __UTIL_TYPES_FLOAT4_H__ */
diff --git a/intern/cycles/util/util_types_float4_impl.h b/intern/cycles/util/util_types_float4_impl.h
index a83148031f1..05a1feee5b2 100644
--- a/intern/cycles/util/util_types_float4_impl.h
+++ b/intern/cycles/util/util_types_float4_impl.h
@@ -28,85 +28,82 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-#ifdef __KERNEL_SSE__
+# ifdef __KERNEL_SSE__
__forceinline float4::float4()
{
}
-__forceinline float4::float4(const __m128& a)
- : m128(a)
+__forceinline float4::float4(const __m128 &a) : m128(a)
{
}
-__forceinline float4::operator const __m128&() const
+__forceinline float4::operator const __m128 &() const
{
- return m128;
+ return m128;
}
-__forceinline float4::operator __m128&()
+__forceinline float4::operator __m128 &()
{
- return m128;
+ return m128;
}
-__forceinline float4& float4::operator =(const float4& a)
+__forceinline float4 &float4::operator=(const float4 &a)
{
- m128 = a.m128;
- return *this;
+ m128 = a.m128;
+ return *this;
}
-#endif /* __KERNEL_SSE__ */
+# endif /* __KERNEL_SSE__ */
__forceinline float float4::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 4);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 4);
+ return *(&x + i);
}
-__forceinline float& float4::operator[](int i)
+__forceinline float &float4::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 4);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 4);
+ return *(&x + i);
}
ccl_device_inline float4 make_float4(float f)
{
-#ifdef __KERNEL_SSE__
- float4 a(_mm_set1_ps(f));
-#else
- float4 a = {f, f, f, f};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ float4 a(_mm_set1_ps(f));
+# else
+ float4 a = {f, f, f, f};
+# endif
+ return a;
}
ccl_device_inline float4 make_float4(float x, float y, float z, float w)
{
-#ifdef __KERNEL_SSE__
- float4 a(_mm_set_ps(w, z, y, x));
-#else
- float4 a = {x, y, z, w};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ float4 a(_mm_set_ps(w, z, y, x));
+# else
+ float4 a = {x, y, z, w};
+# endif
+ return a;
}
-ccl_device_inline float4 make_float4(const int4& i)
+ccl_device_inline float4 make_float4(const int4 &i)
{
-#ifdef __KERNEL_SSE__
- float4 a(_mm_cvtepi32_ps(i.m128));
-#else
- float4 a = {(float)i.x, (float)i.y, (float)i.z, (float)i.w};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ float4 a(_mm_cvtepi32_ps(i.m128));
+# else
+ float4 a = {(float)i.x, (float)i.y, (float)i.z, (float)i.w};
+# endif
+ return a;
}
-ccl_device_inline void print_float4(const char *label, const float4& a)
+ccl_device_inline void print_float4(const char *label, const float4 &a)
{
- printf("%s: %.8f %.8f %.8f %.8f\n",
- label,
- (double)a.x, (double)a.y, (double)a.z, (double)a.w);
+ printf("%s: %.8f %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z, (double)a.w);
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT4_IMPL_H__ */
+#endif /* __UTIL_TYPES_FLOAT4_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_float8.h b/intern/cycles/util/util_types_float8.h
index 08720b8ff48..7289e3298c3 100644
--- a/intern/cycles/util/util_types_float8.h
+++ b/intern/cycles/util/util_types_float8.h
@@ -37,35 +37,38 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-struct ccl_try_align(32) float8 {
-#ifdef __KERNEL_AVX2__
- union {
- __m256 m256;
- struct { float a, b, c, d, e, f, g, h; };
- };
+struct ccl_try_align(32) float8
+{
+# ifdef __KERNEL_AVX2__
+ union {
+ __m256 m256;
+ struct {
+ float a, b, c, d, e, f, g, h;
+ };
+ };
- __forceinline float8();
- __forceinline float8(const float8& a);
- __forceinline explicit float8(const __m256& a);
+ __forceinline float8();
+ __forceinline float8(const float8 &a);
+ __forceinline explicit float8(const __m256 &a);
- __forceinline operator const __m256&() const;
- __forceinline operator __m256&();
+ __forceinline operator const __m256 &() const;
+ __forceinline operator __m256 &();
- __forceinline float8& operator =(const float8& a);
+ __forceinline float8 &operator=(const float8 &a);
-#else /* __KERNEL_AVX2__ */
- float a, b, c, d, e, f, g, h;
-#endif /* __KERNEL_AVX2__ */
+# else /* __KERNEL_AVX2__ */
+ float a, b, c, d, e, f, g, h;
+# endif /* __KERNEL_AVX2__ */
- __forceinline float operator[](int i) const;
- __forceinline float& operator[](int i);
+ __forceinline float operator[](int i) const;
+ __forceinline float &operator[](int i);
};
ccl_device_inline float8 make_float8(float f);
-ccl_device_inline float8 make_float8(float a, float b, float c, float d,
- float e, float f, float g, float h);
-#endif /* __KERNEL_GPU__ */
+ccl_device_inline float8
+make_float8(float a, float b, float c, float d, float e, float f, float g, float h);
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT8_H__ */
+#endif /* __UTIL_TYPES_FLOAT8_H__ */
diff --git a/intern/cycles/util/util_types_float8_impl.h b/intern/cycles/util/util_types_float8_impl.h
index 84fe233c334..8ce3d81b1bb 100644
--- a/intern/cycles/util/util_types_float8_impl.h
+++ b/intern/cycles/util/util_types_float8_impl.h
@@ -40,75 +40,73 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-#ifdef __KERNEL_AVX2__
+# ifdef __KERNEL_AVX2__
__forceinline float8::float8()
{
}
-__forceinline float8::float8(const float8& f)
- : m256(f.m256)
+__forceinline float8::float8(const float8 &f) : m256(f.m256)
{
}
-__forceinline float8::float8(const __m256& f)
- : m256(f)
+__forceinline float8::float8(const __m256 &f) : m256(f)
{
}
-__forceinline float8::operator const __m256&() const
+__forceinline float8::operator const __m256 &() const
{
- return m256;
+ return m256;
}
-__forceinline float8::operator __m256&()
+__forceinline float8::operator __m256 &()
{
- return m256;
+ return m256;
}
-__forceinline float8& float8::operator =(const float8& f)
+__forceinline float8 &float8::operator=(const float8 &f)
{
- m256 = f.m256;
- return *this;
+ m256 = f.m256;
+ return *this;
}
-#endif /* __KERNEL_AVX2__ */
+# endif /* __KERNEL_AVX2__ */
__forceinline float float8::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 8);
- return *(&a + i);
+ util_assert(i >= 0);
+ util_assert(i < 8);
+ return *(&a + i);
}
-__forceinline float& float8::operator[](int i)
+__forceinline float &float8::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 8);
- return *(&a + i);
+ util_assert(i >= 0);
+ util_assert(i < 8);
+ return *(&a + i);
}
ccl_device_inline float8 make_float8(float f)
{
-#ifdef __KERNEL_AVX2__
- float8 r(_mm256_set1_ps(f));
-#else
- float8 r = {f, f, f, f, f, f, f, f};
-#endif
- return r;
+# ifdef __KERNEL_AVX2__
+ float8 r(_mm256_set1_ps(f));
+# else
+ float8 r = {f, f, f, f, f, f, f, f};
+# endif
+ return r;
}
-ccl_device_inline float8 make_float8(float a, float b, float c, float d,
- float e, float f, float g, float h)
+ccl_device_inline float8
+make_float8(float a, float b, float c, float d, float e, float f, float g, float h)
{
-#ifdef __KERNEL_AVX2__
- float8 r(_mm256_set_ps(a, b, c, d, e, f, g, h));
-#else
- float8 r = {a, b, c, d, e, f, g, h};
-#endif
- return r;
+# ifdef __KERNEL_AVX2__
+ float8 r(_mm256_set_ps(a, b, c, d, e, f, g, h));
+# else
+ float8 r = {a, b, c, d, e, f, g, h};
+# endif
+ return r;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_FLOAT8_IMPL_H__ */
+#endif /* __UTIL_TYPES_FLOAT8_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_int2.h b/intern/cycles/util/util_types_int2.h
index 82e860f89eb..8811e5ec7c2 100644
--- a/intern/cycles/util/util_types_int2.h
+++ b/intern/cycles/util/util_types_int2.h
@@ -25,15 +25,15 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct int2 {
- int x, y;
+ int x, y;
- __forceinline int operator[](int i) const;
- __forceinline int& operator[](int i);
+ __forceinline int operator[](int i) const;
+ __forceinline int &operator[](int i);
};
ccl_device_inline int2 make_int2(int x, int y);
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_INT2_H__ */
+#endif /* __UTIL_TYPES_INT2_H__ */
diff --git a/intern/cycles/util/util_types_int2_impl.h b/intern/cycles/util/util_types_int2_impl.h
index c7d3942e723..ce95d4f14e5 100644
--- a/intern/cycles/util/util_types_int2_impl.h
+++ b/intern/cycles/util/util_types_int2_impl.h
@@ -26,25 +26,25 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
int int2::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 2);
+ return *(&x + i);
}
-int& int2::operator[](int i)
+int &int2::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 2);
+ return *(&x + i);
}
ccl_device_inline int2 make_int2(int x, int y)
{
- int2 a = {x, y};
- return a;
+ int2 a = {x, y};
+ return a;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_INT2_IMPL_H__ */
+#endif /* __UTIL_TYPES_INT2_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_int3.h b/intern/cycles/util/util_types_int3.h
index f68074b982b..09edc09dff3 100644
--- a/intern/cycles/util/util_types_int3.h
+++ b/intern/cycles/util/util_types_int3.h
@@ -24,34 +24,37 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-struct ccl_try_align(16) int3 {
-#ifdef __KERNEL_SSE__
- union {
- __m128i m128;
- struct { int x, y, z, w; };
- };
-
- __forceinline int3();
- __forceinline int3(const int3& a);
- __forceinline explicit int3(const __m128i& a);
-
- __forceinline operator const __m128i&() const;
- __forceinline operator __m128i&();
-
- __forceinline int3& operator =(const int3& a);
-#else /* __KERNEL_SSE__ */
- int x, y, z, w;
-#endif /* __KERNEL_SSE__ */
-
- __forceinline int operator[](int i) const;
- __forceinline int& operator[](int i);
+struct ccl_try_align(16) int3
+{
+# ifdef __KERNEL_SSE__
+ union {
+ __m128i m128;
+ struct {
+ int x, y, z, w;
+ };
+ };
+
+ __forceinline int3();
+ __forceinline int3(const int3 &a);
+ __forceinline explicit int3(const __m128i &a);
+
+ __forceinline operator const __m128i &() const;
+ __forceinline operator __m128i &();
+
+ __forceinline int3 &operator=(const int3 &a);
+# else /* __KERNEL_SSE__ */
+ int x, y, z, w;
+# endif /* __KERNEL_SSE__ */
+
+ __forceinline int operator[](int i) const;
+ __forceinline int &operator[](int i);
};
ccl_device_inline int3 make_int3(int i);
ccl_device_inline int3 make_int3(int x, int y, int z);
-ccl_device_inline void print_int3(const char *label, const int3& a);
-#endif /* __KERNEL_GPU__ */
+ccl_device_inline void print_int3(const char *label, const int3 &a);
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_INT3_H__ */
+#endif /* __UTIL_TYPES_INT3_H__ */
diff --git a/intern/cycles/util/util_types_int3_impl.h b/intern/cycles/util/util_types_int3_impl.h
index 1b195ca753f..080c892640b 100644
--- a/intern/cycles/util/util_types_int3_impl.h
+++ b/intern/cycles/util/util_types_int3_impl.h
@@ -28,79 +28,77 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-#ifdef __KERNEL_SSE__
+# ifdef __KERNEL_SSE__
__forceinline int3::int3()
{
}
-__forceinline int3::int3(const __m128i& a)
- : m128(a)
+__forceinline int3::int3(const __m128i &a) : m128(a)
{
}
-__forceinline int3::int3(const int3& a)
- : m128(a.m128)
+__forceinline int3::int3(const int3 &a) : m128(a.m128)
{
}
-__forceinline int3::operator const __m128i&() const
+__forceinline int3::operator const __m128i &() const
{
- return m128;
+ return m128;
}
-__forceinline int3::operator __m128i&()
+__forceinline int3::operator __m128i &()
{
- return m128;
+ return m128;
}
-__forceinline int3& int3::operator =(const int3& a)
+__forceinline int3 &int3::operator=(const int3 &a)
{
- m128 = a.m128;
- return *this;
+ m128 = a.m128;
+ return *this;
}
-#endif /* __KERNEL_SSE__ */
+# endif /* __KERNEL_SSE__ */
__forceinline int int3::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 3);
+ return *(&x + i);
}
-__forceinline int& int3::operator[](int i)
+__forceinline int &int3::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 3);
+ return *(&x + i);
}
ccl_device_inline int3 make_int3(int i)
{
-#ifdef __KERNEL_SSE__
- int3 a(_mm_set1_epi32(i));
-#else
- int3 a = {i, i, i, i};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ int3 a(_mm_set1_epi32(i));
+# else
+ int3 a = {i, i, i, i};
+# endif
+ return a;
}
ccl_device_inline int3 make_int3(int x, int y, int z)
{
-#ifdef __KERNEL_SSE__
- int3 a(_mm_set_epi32(0, z, y, x));
-#else
- int3 a = {x, y, z, 0};
-#endif
+# ifdef __KERNEL_SSE__
+ int3 a(_mm_set_epi32(0, z, y, x));
+# else
+ int3 a = {x, y, z, 0};
+# endif
- return a;
+ return a;
}
-ccl_device_inline void print_int3(const char *label, const int3& a)
+ccl_device_inline void print_int3(const char *label, const int3 &a)
{
- printf("%s: %d %d %d\n", label, a.x, a.y, a.z);
+ printf("%s: %d %d %d\n", label, a.x, a.y, a.z);
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_INT3_IMPL_H__ */
+#endif /* __UTIL_TYPES_INT3_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_int4.h b/intern/cycles/util/util_types_int4.h
index 52e6fed8c14..5c7917cf5d6 100644
--- a/intern/cycles/util/util_types_int4.h
+++ b/intern/cycles/util/util_types_int4.h
@@ -28,36 +28,39 @@ CCL_NAMESPACE_BEGIN
struct float3;
struct float4;
-struct ccl_try_align(16) int4 {
-#ifdef __KERNEL_SSE__
- union {
- __m128i m128;
- struct { int x, y, z, w; };
- };
-
- __forceinline int4();
- __forceinline int4(const int4& a);
- __forceinline explicit int4(const __m128i& a);
-
- __forceinline operator const __m128i&() const;
- __forceinline operator __m128i&();
-
- __forceinline int4& operator=(const int4& a);
-#else /* __KERNEL_SSE__ */
- int x, y, z, w;
-#endif /* __KERNEL_SSE__ */
-
- __forceinline int operator[](int i) const;
- __forceinline int& operator[](int i);
+struct ccl_try_align(16) int4
+{
+# ifdef __KERNEL_SSE__
+ union {
+ __m128i m128;
+ struct {
+ int x, y, z, w;
+ };
+ };
+
+ __forceinline int4();
+ __forceinline int4(const int4 &a);
+ __forceinline explicit int4(const __m128i &a);
+
+ __forceinline operator const __m128i &() const;
+ __forceinline operator __m128i &();
+
+ __forceinline int4 &operator=(const int4 &a);
+# else /* __KERNEL_SSE__ */
+ int x, y, z, w;
+# endif /* __KERNEL_SSE__ */
+
+ __forceinline int operator[](int i) const;
+ __forceinline int &operator[](int i);
};
ccl_device_inline int4 make_int4(int i);
ccl_device_inline int4 make_int4(int x, int y, int z, int w);
-ccl_device_inline int4 make_int4(const float3& f);
-ccl_device_inline int4 make_int4(const float4& f);
-ccl_device_inline void print_int4(const char *label, const int4& a);
-#endif /* __KERNEL_GPU__ */
+ccl_device_inline int4 make_int4(const float3 &f);
+ccl_device_inline int4 make_int4(const float4 &f);
+ccl_device_inline void print_int4(const char *label, const int4 &a);
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_INT4_H__ */
+#endif /* __UTIL_TYPES_INT4_H__ */
diff --git a/intern/cycles/util/util_types_int4_impl.h b/intern/cycles/util/util_types_int4_impl.h
index c058f86c400..c6f6ff23a17 100644
--- a/intern/cycles/util/util_types_int4_impl.h
+++ b/intern/cycles/util/util_types_int4_impl.h
@@ -28,98 +28,96 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-#ifdef __KERNEL_SSE__
+# ifdef __KERNEL_SSE__
__forceinline int4::int4()
{
}
-__forceinline int4::int4(const int4& a)
- : m128(a.m128)
+__forceinline int4::int4(const int4 &a) : m128(a.m128)
{
}
-__forceinline int4::int4(const __m128i& a)
- : m128(a)
+__forceinline int4::int4(const __m128i &a) : m128(a)
{
}
-__forceinline int4::operator const __m128i&() const
+__forceinline int4::operator const __m128i &() const
{
- return m128;
+ return m128;
}
-__forceinline int4::operator __m128i&()
+__forceinline int4::operator __m128i &()
{
- return m128;
+ return m128;
}
-__forceinline int4& int4::operator=(const int4& a)
+__forceinline int4 &int4::operator=(const int4 &a)
{
- m128 = a.m128;
- return *this;
+ m128 = a.m128;
+ return *this;
}
-#endif /* __KERNEL_SSE__ */
+# endif /* __KERNEL_SSE__ */
__forceinline int int4::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 4);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 4);
+ return *(&x + i);
}
-__forceinline int& int4::operator[](int i)
+__forceinline int &int4::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 4);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 4);
+ return *(&x + i);
}
ccl_device_inline int4 make_int4(int i)
{
-#ifdef __KERNEL_SSE__
- int4 a(_mm_set1_epi32(i));
-#else
- int4 a = {i, i, i, i};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ int4 a(_mm_set1_epi32(i));
+# else
+ int4 a = {i, i, i, i};
+# endif
+ return a;
}
ccl_device_inline int4 make_int4(int x, int y, int z, int w)
{
-#ifdef __KERNEL_SSE__
- int4 a(_mm_set_epi32(w, z, y, x));
-#else
- int4 a = {x, y, z, w};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ int4 a(_mm_set_epi32(w, z, y, x));
+# else
+ int4 a = {x, y, z, w};
+# endif
+ return a;
}
-ccl_device_inline int4 make_int4(const float3& f)
+ccl_device_inline int4 make_int4(const float3 &f)
{
-#ifdef __KERNEL_SSE__
- int4 a(_mm_cvtps_epi32(f.m128));
-#else
- int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ int4 a(_mm_cvtps_epi32(f.m128));
+# else
+ int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w};
+# endif
+ return a;
}
-ccl_device_inline int4 make_int4(const float4& f)
+ccl_device_inline int4 make_int4(const float4 &f)
{
-#ifdef __KERNEL_SSE__
- int4 a(_mm_cvtps_epi32(f.m128));
-#else
- int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w};
-#endif
- return a;
+# ifdef __KERNEL_SSE__
+ int4 a(_mm_cvtps_epi32(f.m128));
+# else
+ int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w};
+# endif
+ return a;
}
-ccl_device_inline void print_int4(const char *label, const int4& a)
+ccl_device_inline void print_int4(const char *label, const int4 &a)
{
- printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w);
+ printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w);
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_INT4_IMPL_H__ */
+#endif /* __UTIL_TYPES_INT4_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_uchar2.h b/intern/cycles/util/util_types_uchar2.h
index f618a2234ca..8cc486e3e48 100644
--- a/intern/cycles/util/util_types_uchar2.h
+++ b/intern/cycles/util/util_types_uchar2.h
@@ -25,15 +25,15 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct uchar2 {
- uchar x, y;
+ uchar x, y;
- __forceinline uchar operator[](int i) const;
- __forceinline uchar& operator[](int i);
+ __forceinline uchar operator[](int i) const;
+ __forceinline uchar &operator[](int i);
};
ccl_device_inline uchar2 make_uchar2(uchar x, uchar y);
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UCHAR2_H__ */
+#endif /* __UTIL_TYPES_UCHAR2_H__ */
diff --git a/intern/cycles/util/util_types_uchar2_impl.h b/intern/cycles/util/util_types_uchar2_impl.h
index d5f196d0ce0..16968c32dd9 100644
--- a/intern/cycles/util/util_types_uchar2_impl.h
+++ b/intern/cycles/util/util_types_uchar2_impl.h
@@ -26,25 +26,25 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
uchar uchar2::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 2);
+ return *(&x + i);
}
-uchar& uchar2::operator[](int i)
+uchar &uchar2::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 2);
+ return *(&x + i);
}
ccl_device_inline uchar2 make_uchar2(uchar x, uchar y)
{
- uchar2 a = {x, y};
- return a;
+ uchar2 a = {x, y};
+ return a;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UCHAR2_IMPL_H__ */
+#endif /* __UTIL_TYPES_UCHAR2_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_uchar3.h b/intern/cycles/util/util_types_uchar3.h
index 1e3644e6fd6..5838c437c70 100644
--- a/intern/cycles/util/util_types_uchar3.h
+++ b/intern/cycles/util/util_types_uchar3.h
@@ -25,15 +25,15 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct uchar3 {
- uchar x, y, z;
+ uchar x, y, z;
- __forceinline uchar operator[](int i) const;
- __forceinline uchar& operator[](int i);
+ __forceinline uchar operator[](int i) const;
+ __forceinline uchar &operator[](int i);
};
ccl_device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z);
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UCHAR3_H__ */
+#endif /* __UTIL_TYPES_UCHAR3_H__ */
diff --git a/intern/cycles/util/util_types_uchar3_impl.h b/intern/cycles/util/util_types_uchar3_impl.h
index 611021efb7f..aa31b725731 100644
--- a/intern/cycles/util/util_types_uchar3_impl.h
+++ b/intern/cycles/util/util_types_uchar3_impl.h
@@ -26,25 +26,25 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
uchar uchar3::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 3);
+ return *(&x + i);
}
-uchar& uchar3::operator[](int i)
+uchar &uchar3::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 3);
+ return *(&x + i);
}
ccl_device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z)
{
- uchar3 a = {x, y, z};
- return a;
+ uchar3 a = {x, y, z};
+ return a;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UCHAR3_IMPL_H__ */
+#endif /* __UTIL_TYPES_UCHAR3_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_uchar4.h b/intern/cycles/util/util_types_uchar4.h
index 3802cebbfb9..22b6a1ac705 100644
--- a/intern/cycles/util/util_types_uchar4.h
+++ b/intern/cycles/util/util_types_uchar4.h
@@ -25,15 +25,15 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct uchar4 {
- uchar x, y, z, w;
+ uchar x, y, z, w;
- __forceinline uchar operator[](int i) const;
- __forceinline uchar& operator[](int i);
+ __forceinline uchar operator[](int i) const;
+ __forceinline uchar &operator[](int i);
};
ccl_device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w);
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UCHAR4_H__ */
+#endif /* __UTIL_TYPES_UCHAR4_H__ */
diff --git a/intern/cycles/util/util_types_uchar4_impl.h b/intern/cycles/util/util_types_uchar4_impl.h
index 03039f60c54..79879f176a6 100644
--- a/intern/cycles/util/util_types_uchar4_impl.h
+++ b/intern/cycles/util/util_types_uchar4_impl.h
@@ -26,25 +26,25 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
uchar uchar4::operator[](int i) const
{
- util_assert(i >= 0);
- util_assert(i < 4);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 4);
+ return *(&x + i);
}
-uchar& uchar4::operator[](int i)
+uchar &uchar4::operator[](int i)
{
- util_assert(i >= 0);
- util_assert(i < 4);
- return *(&x + i);
+ util_assert(i >= 0);
+ util_assert(i < 4);
+ return *(&x + i);
}
ccl_device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w)
{
- uchar4 a = {x, y, z, w};
- return a;
+ uchar4 a = {x, y, z, w};
+ return a;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UCHAR4_IMPL_H__ */
+#endif /* __UTIL_TYPES_UCHAR4_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_uint2.h b/intern/cycles/util/util_types_uint2.h
index c4a31899614..abcb8ee5346 100644
--- a/intern/cycles/util/util_types_uint2.h
+++ b/intern/cycles/util/util_types_uint2.h
@@ -25,15 +25,15 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct uint2 {
- uint x, y;
+ uint x, y;
- __forceinline uint operator[](uint i) const;
- __forceinline uint& operator[](uint i);
+ __forceinline uint operator[](uint i) const;
+ __forceinline uint &operator[](uint i);
};
ccl_device_inline uint2 make_uint2(uint x, uint y);
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UINT2_H__ */
+#endif /* __UTIL_TYPES_UINT2_H__ */
diff --git a/intern/cycles/util/util_types_uint2_impl.h b/intern/cycles/util/util_types_uint2_impl.h
index b50ffa2667f..db62bd99b89 100644
--- a/intern/cycles/util/util_types_uint2_impl.h
+++ b/intern/cycles/util/util_types_uint2_impl.h
@@ -26,23 +26,23 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
__forceinline uint uint2::operator[](uint i) const
{
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i < 2);
+ return *(&x + i);
}
-__forceinline uint& uint2::operator[](uint i)
+__forceinline uint &uint2::operator[](uint i)
{
- util_assert(i < 2);
- return *(&x + i);
+ util_assert(i < 2);
+ return *(&x + i);
}
ccl_device_inline uint2 make_uint2(uint x, uint y)
{
- uint2 a = {x, y};
- return a;
+ uint2 a = {x, y};
+ return a;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UINT2_IMPL_H__ */
+#endif /* __UTIL_TYPES_UINT2_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_uint3.h b/intern/cycles/util/util_types_uint3.h
index aeeecd2df06..436d870b621 100644
--- a/intern/cycles/util/util_types_uint3.h
+++ b/intern/cycles/util/util_types_uint3.h
@@ -25,15 +25,15 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct uint3 {
- uint x, y, z;
+ uint x, y, z;
- __forceinline uint operator[](uint i) const;
- __forceinline uint& operator[](uint i);
+ __forceinline uint operator[](uint i) const;
+ __forceinline uint &operator[](uint i);
};
ccl_device_inline uint3 make_uint3(uint x, uint y, uint z);
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UINT3_H__ */
+#endif /* __UTIL_TYPES_UINT3_H__ */
diff --git a/intern/cycles/util/util_types_uint3_impl.h b/intern/cycles/util/util_types_uint3_impl.h
index 26005d5baff..d188fa06e2a 100644
--- a/intern/cycles/util/util_types_uint3_impl.h
+++ b/intern/cycles/util/util_types_uint3_impl.h
@@ -26,23 +26,23 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
__forceinline uint uint3::operator[](uint i) const
{
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i < 3);
+ return *(&x + i);
}
-__forceinline uint& uint3::operator[](uint i)
+__forceinline uint &uint3::operator[](uint i)
{
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i < 3);
+ return *(&x + i);
}
ccl_device_inline uint3 make_uint3(uint x, uint y, uint z)
{
- uint3 a = {x, y, z};
- return a;
+ uint3 a = {x, y, z};
+ return a;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UINT3_IMPL_H__ */
+#endif /* __UTIL_TYPES_UINT3_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_uint4.h b/intern/cycles/util/util_types_uint4.h
index 2d3a7bb85e4..57f2859fedf 100644
--- a/intern/cycles/util/util_types_uint4.h
+++ b/intern/cycles/util/util_types_uint4.h
@@ -25,15 +25,15 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct uint4 {
- uint x, y, z, w;
+ uint x, y, z, w;
- __forceinline uint operator[](uint i) const;
- __forceinline uint& operator[](uint i);
+ __forceinline uint operator[](uint i) const;
+ __forceinline uint &operator[](uint i);
};
ccl_device_inline uint4 make_uint4(uint x, uint y, uint z, uint w);
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UINT4_H__ */
+#endif /* __UTIL_TYPES_UINT4_H__ */
diff --git a/intern/cycles/util/util_types_uint4_impl.h b/intern/cycles/util/util_types_uint4_impl.h
index 6d48131a446..bac8d23030d 100644
--- a/intern/cycles/util/util_types_uint4_impl.h
+++ b/intern/cycles/util/util_types_uint4_impl.h
@@ -26,23 +26,23 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
__forceinline uint uint4::operator[](uint i) const
{
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i < 3);
+ return *(&x + i);
}
-__forceinline uint& uint4::operator[](uint i)
+__forceinline uint &uint4::operator[](uint i)
{
- util_assert(i < 3);
- return *(&x + i);
+ util_assert(i < 3);
+ return *(&x + i);
}
ccl_device_inline uint4 make_uint4(uint x, uint y, uint z, uint w)
{
- uint4 a = {x, y, z, w};
- return a;
+ uint4 a = {x, y, z, w};
+ return a;
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_UINT4_IMPL_H__ */
+#endif /* __UTIL_TYPES_UINT4_IMPL_H__ */
diff --git a/intern/cycles/util/util_types_ushort4.h b/intern/cycles/util/util_types_ushort4.h
index fc234b8abe8..476ceec622c 100644
--- a/intern/cycles/util/util_types_ushort4.h
+++ b/intern/cycles/util/util_types_ushort4.h
@@ -26,11 +26,11 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
struct ushort4 {
- uint16_t x, y, z, w;
+ uint16_t x, y, z, w;
};
#endif
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_USHORT4_H__ */
+#endif /* __UTIL_TYPES_USHORT4_H__ */
diff --git a/intern/cycles/util/util_types_vector3.h b/intern/cycles/util/util_types_vector3.h
index 12acf9dc959..728c7ca62a1 100644
--- a/intern/cycles/util/util_types_vector3.h
+++ b/intern/cycles/util/util_types_vector3.h
@@ -24,18 +24,16 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-template<typename T>
-class vector3
-{
-public:
- T x, y, z;
+template<typename T> class vector3 {
+ public:
+ T x, y, z;
- __forceinline vector3();
- __forceinline vector3(const T& a);
- __forceinline vector3(const T& x, const T& y, const T& z);
+ __forceinline vector3();
+ __forceinline vector3(const T &a);
+ __forceinline vector3(const T &x, const T &y, const T &z);
};
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_VECTOR3_H__ */
+#endif /* __UTIL_TYPES_VECTOR3_H__ */
diff --git a/intern/cycles/util/util_types_vector3_impl.h b/intern/cycles/util/util_types_vector3_impl.h
index 2f6b8368540..33ba53e20b2 100644
--- a/intern/cycles/util/util_types_vector3_impl.h
+++ b/intern/cycles/util/util_types_vector3_impl.h
@@ -24,24 +24,20 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_GPU__
-template<typename T>
-ccl_always_inline vector3<T>::vector3()
+template<typename T> ccl_always_inline vector3<T>::vector3()
{
}
-template<typename T>
-ccl_always_inline vector3<T>::vector3(const T& a)
- : x(a), y(a), z(a)
+template<typename T> ccl_always_inline vector3<T>::vector3(const T &a) : x(a), y(a), z(a)
{
}
template<typename T>
-ccl_always_inline vector3<T>::vector3(const T& x, const T& y, const T& z)
- : x(x), y(y), z(z)
+ccl_always_inline vector3<T>::vector3(const T &x, const T &y, const T &z) : x(x), y(y), z(z)
{
}
-#endif /* __KERNEL_GPU__ */
+#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
-#endif /* __UTIL_TYPES_VECTOR3_IMPL_H__ */
+#endif /* __UTIL_TYPES_VECTOR3_IMPL_H__ */
diff --git a/intern/cycles/util/util_unique_ptr.h b/intern/cycles/util/util_unique_ptr.h
index 1ceae73172e..3aaaf083eff 100644
--- a/intern/cycles/util/util_unique_ptr.h
+++ b/intern/cycles/util/util_unique_ptr.h
@@ -25,4 +25,4 @@ using std::unique_ptr;
CCL_NAMESPACE_END
-#endif /* __UTIL_UNIQUE_PTR_H__ */
+#endif /* __UTIL_UNIQUE_PTR_H__ */
diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h
index 18fa231d6e7..437478d64d3 100644
--- a/intern/cycles/util/util_vector.h
+++ b/intern/cycles/util/util_vector.h
@@ -32,30 +32,28 @@ CCL_NAMESPACE_BEGIN
* - Use own allocator which keeps track of used/peak memory.
* - Have method to ensure capacity is re-set to 0.
*/
-template<typename value_type,
- typename allocator_type = GuardedAllocator<value_type> >
-class vector : public std::vector<value_type, allocator_type>
-{
-public:
- typedef std::vector<value_type, allocator_type> BaseClass;
-
- /* Inherit all constructors from base class. */
- using BaseClass::vector;
-
- /* Try as hard as possible to use zero memory. */
- void free_memory()
- {
- BaseClass::resize(0);
- BaseClass::shrink_to_fit();
- }
-
- /* Some external API might demand working with std::vector. */
- operator std::vector<value_type>()
- {
- return std::vector<value_type>(this->begin(), this->end());
- }
+template<typename value_type, typename allocator_type = GuardedAllocator<value_type>>
+class vector : public std::vector<value_type, allocator_type> {
+ public:
+ typedef std::vector<value_type, allocator_type> BaseClass;
+
+ /* Inherit all constructors from base class. */
+ using BaseClass::vector;
+
+ /* Try as hard as possible to use zero memory. */
+ void free_memory()
+ {
+ BaseClass::resize(0);
+ BaseClass::shrink_to_fit();
+ }
+
+ /* Some external API might demand working with std::vector. */
+ operator std::vector<value_type>()
+ {
+ return std::vector<value_type>(this->begin(), this->end());
+ }
};
CCL_NAMESPACE_END
-#endif /* __UTIL_VECTOR_H__ */
+#endif /* __UTIL_VECTOR_H__ */
diff --git a/intern/cycles/util/util_version.h b/intern/cycles/util/util_version.h
index 980c5a269e6..38829d3a29c 100644
--- a/intern/cycles/util/util_version.h
+++ b/intern/cycles/util/util_version.h
@@ -21,17 +21,15 @@
CCL_NAMESPACE_BEGIN
-#define CYCLES_VERSION_MAJOR 1
-#define CYCLES_VERSION_MINOR 9
-#define CYCLES_VERSION_PATCH 0
+#define CYCLES_VERSION_MAJOR 1
+#define CYCLES_VERSION_MINOR 9
+#define CYCLES_VERSION_PATCH 0
-#define CYCLES_MAKE_VERSION_STRING2(a,b,c) #a "." #b "." #c
-#define CYCLES_MAKE_VERSION_STRING(a,b,c) CYCLES_MAKE_VERSION_STRING2(a,b,c)
+#define CYCLES_MAKE_VERSION_STRING2(a, b, c) #a "." #b "." #c
+#define CYCLES_MAKE_VERSION_STRING(a, b, c) CYCLES_MAKE_VERSION_STRING2(a, b, c)
#define CYCLES_VERSION_STRING \
- CYCLES_MAKE_VERSION_STRING(CYCLES_VERSION_MAJOR, \
- CYCLES_VERSION_MINOR, \
- CYCLES_VERSION_PATCH)
+ CYCLES_MAKE_VERSION_STRING(CYCLES_VERSION_MAJOR, CYCLES_VERSION_MINOR, CYCLES_VERSION_PATCH)
CCL_NAMESPACE_END
-#endif /* __UTIL_VERSION_H__ */
+#endif /* __UTIL_VERSION_H__ */
diff --git a/intern/cycles/util/util_view.cpp b/intern/cycles/util/util_view.cpp
index c0ddc2a88bf..f23174fd6dc 100644
--- a/intern/cycles/util/util_view.cpp
+++ b/intern/cycles/util/util_view.cpp
@@ -24,9 +24,9 @@
#include "util/util_view.h"
#ifdef __APPLE__
-#include <GLUT/glut.h>
+# include <GLUT/glut.h>
#else
-#include <GL/glut.h>
+# include <GL/glut.h>
#endif
CCL_NAMESPACE_BEGIN
@@ -34,241 +34,249 @@ CCL_NAMESPACE_BEGIN
/* structs */
struct View {
- ViewInitFunc initf;
- ViewExitFunc exitf;
- ViewResizeFunc resize;
- ViewDisplayFunc display;
- ViewKeyboardFunc keyboard;
- ViewMotionFunc motion;
+ ViewInitFunc initf;
+ ViewExitFunc exitf;
+ ViewResizeFunc resize;
+ ViewDisplayFunc display;
+ ViewKeyboardFunc keyboard;
+ ViewMotionFunc motion;
- bool first_display;
- bool redraw;
+ bool first_display;
+ bool redraw;
- int mouseX, mouseY;
- int mouseBut0, mouseBut2;
+ int mouseX, mouseY;
+ int mouseBut0, mouseBut2;
- int width, height;
+ int width, height;
} V;
/* public */
static void view_display_text(int x, int y, const char *text)
{
- const char *c;
+ const char *c;
- glRasterPos3f(x, y, 0);
+ glRasterPos3f(x, y, 0);
- for(c = text; *c != '\0'; c++)
- glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
+ for (c = text; *c != '\0'; c++)
+ glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
}
void view_display_info(const char *info)
{
- const int height = 20;
+ const int height = 20;
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(0.1f, 0.1f, 0.1f, 0.8f);
- glRectf(0.0f, V.height - height, V.width, V.height);
- glDisable(GL_BLEND);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(0.1f, 0.1f, 0.1f, 0.8f);
+ glRectf(0.0f, V.height - height, V.width, V.height);
+ glDisable(GL_BLEND);
- glColor3f(0.5f, 0.5f, 0.5f);
+ glColor3f(0.5f, 0.5f, 0.5f);
- view_display_text(10, 7 + V.height - height, info);
+ view_display_text(10, 7 + V.height - height, info);
- glColor3f(1.0f, 1.0f, 1.0f);
+ glColor3f(1.0f, 1.0f, 1.0f);
}
void view_display_help()
{
- const int w = (int)((float)V.width / 1.15f);
- const int h = (int)((float)V.height / 1.15f);
+ const int w = (int)((float)V.width / 1.15f);
+ const int h = (int)((float)V.height / 1.15f);
- const int x1 = (V.width - w) / 2;
- const int x2 = x1 + w;
+ const int x1 = (V.width - w) / 2;
+ const int x2 = x1 + w;
- const int y1 = (V.height - h) / 2;
- const int y2 = y1 + h;
+ const int y1 = (V.height - h) / 2;
+ const int y2 = y1 + h;
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(0.5f, 0.5f, 0.5f, 0.8f);
- glRectf(x1, y1, x2, y2);
- glDisable(GL_BLEND);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(0.5f, 0.5f, 0.5f, 0.8f);
+ glRectf(x1, y1, x2, y2);
+ glDisable(GL_BLEND);
- glColor3f(0.8f, 0.8f, 0.8f);
+ glColor3f(0.8f, 0.8f, 0.8f);
- string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING;
+ string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING;
- view_display_text(x1+20, y2-20, info.c_str());
- view_display_text(x1+20, y2-40, "(C) 2011-2016 Blender Foundation");
- view_display_text(x1+20, y2-80, "Controls:");
- view_display_text(x1+20, y2-100, "h: Info/Help");
- view_display_text(x1+20, y2-120, "r: Reset");
- view_display_text(x1+20, y2-140, "p: Pause");
- view_display_text(x1+20, y2-160, "esc: Cancel");
- view_display_text(x1+20, y2-180, "q: Quit program");
+ view_display_text(x1 + 20, y2 - 20, info.c_str());
+ view_display_text(x1 + 20, y2 - 40, "(C) 2011-2016 Blender Foundation");
+ view_display_text(x1 + 20, y2 - 80, "Controls:");
+ view_display_text(x1 + 20, y2 - 100, "h: Info/Help");
+ view_display_text(x1 + 20, y2 - 120, "r: Reset");
+ view_display_text(x1 + 20, y2 - 140, "p: Pause");
+ view_display_text(x1 + 20, y2 - 160, "esc: Cancel");
+ view_display_text(x1 + 20, y2 - 180, "q: Quit program");
- view_display_text(x1+20, y2-210, "i: Interactive mode");
- view_display_text(x1+20, y2-230, "Left mouse: Move camera");
- view_display_text(x1+20, y2-250, "Right mouse: Rotate camera");
- view_display_text(x1+20, y2-270, "W/A/S/D: Move camera");
- view_display_text(x1+20, y2-290, "0/1/2/3: Set max bounces");
+ view_display_text(x1 + 20, y2 - 210, "i: Interactive mode");
+ view_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera");
+ view_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera");
+ view_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera");
+ view_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces");
- glColor3f(1.0f, 1.0f, 1.0f);
+ glColor3f(1.0f, 1.0f, 1.0f);
}
static void view_display()
{
- if(V.first_display) {
- if(V.initf) V.initf();
- if(V.exitf) atexit(V.exitf);
+ if (V.first_display) {
+ if (V.initf)
+ V.initf();
+ if (V.exitf)
+ atexit(V.exitf);
- V.first_display = false;
- }
+ V.first_display = false;
+ }
- glClearColor(0.05f, 0.05f, 0.05f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glClearColor(0.05f, 0.05f, 0.05f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0, V.width, 0, V.height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0, V.width, 0, V.height);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
- glRasterPos3f(0, 0, 0);
+ glRasterPos3f(0, 0, 0);
- if(V.display)
- V.display();
+ if (V.display)
+ V.display();
- glutSwapBuffers();
+ glutSwapBuffers();
}
static void view_reshape(int width, int height)
{
- if(width <= 0 || height <= 0)
- return;
+ if (width <= 0 || height <= 0)
+ return;
- V.width = width;
- V.height = height;
+ V.width = width;
+ V.height = height;
- glViewport(0, 0, width, height);
+ glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
- if(V.resize)
- V.resize(width, height);
+ if (V.resize)
+ V.resize(width, height);
}
static void view_keyboard(unsigned char key, int x, int y)
{
- if(V.keyboard)
- V.keyboard(key);
-
- if(key == 'm')
- printf("mouse %d %d\n", x, y);
- if(key == 'q') {
- if(V.exitf) V.exitf();
- exit(0);
- }
+ if (V.keyboard)
+ V.keyboard(key);
+
+ if (key == 'm')
+ printf("mouse %d %d\n", x, y);
+ if (key == 'q') {
+ if (V.exitf)
+ V.exitf();
+ exit(0);
+ }
}
static void view_mouse(int button, int state, int x, int y)
{
- if(button == 0) {
- if(state == GLUT_DOWN) {
- V.mouseX = x;
- V.mouseY = y;
- V.mouseBut0 = 1;
- }
- else if(state == GLUT_UP) {
- V.mouseBut0 = 0;
- }
- }
- else if(button == 2) {
- if(state == GLUT_DOWN) {
- V.mouseX = x;
- V.mouseY = y;
- V.mouseBut2 = 1;
- }
- else if(state == GLUT_UP) {
- V.mouseBut2 = 0;
- }
- }
+ if (button == 0) {
+ if (state == GLUT_DOWN) {
+ V.mouseX = x;
+ V.mouseY = y;
+ V.mouseBut0 = 1;
+ }
+ else if (state == GLUT_UP) {
+ V.mouseBut0 = 0;
+ }
+ }
+ else if (button == 2) {
+ if (state == GLUT_DOWN) {
+ V.mouseX = x;
+ V.mouseY = y;
+ V.mouseBut2 = 1;
+ }
+ else if (state == GLUT_UP) {
+ V.mouseBut2 = 0;
+ }
+ }
}
static void view_motion(int x, int y)
{
- const int but = V.mouseBut0? 0:2;
- const int distX = x - V.mouseX;
- const int distY = y - V.mouseY;
+ const int but = V.mouseBut0 ? 0 : 2;
+ const int distX = x - V.mouseX;
+ const int distY = y - V.mouseY;
- if(V.motion)
- V.motion(distX, distY, but);
+ if (V.motion)
+ V.motion(distX, distY, but);
- V.mouseX = x;
- V.mouseY = y;
+ V.mouseX = x;
+ V.mouseY = y;
}
static void view_idle()
{
- if(V.redraw) {
- V.redraw = false;
- glutPostRedisplay();
- }
+ if (V.redraw) {
+ V.redraw = false;
+ glutPostRedisplay();
+ }
- time_sleep(0.1);
+ time_sleep(0.1);
}
-void view_main_loop(const char *title, int width, int height,
- ViewInitFunc initf, ViewExitFunc exitf,
- ViewResizeFunc resize, ViewDisplayFunc display,
- ViewKeyboardFunc keyboard, ViewMotionFunc motion)
+void view_main_loop(const char *title,
+ int width,
+ int height,
+ ViewInitFunc initf,
+ ViewExitFunc exitf,
+ ViewResizeFunc resize,
+ ViewDisplayFunc display,
+ ViewKeyboardFunc keyboard,
+ ViewMotionFunc motion)
{
- const char *name = "app";
- char *argv = (char*)name;
- int argc = 1;
-
- memset(&V, 0, sizeof(V));
- V.width = width;
- V.height = height;
- V.first_display = true;
- V.redraw = false;
- V.initf = initf;
- V.exitf = exitf;
- V.resize = resize;
- V.display = display;
- V.keyboard = keyboard;
- V.motion = motion;
-
- glutInit(&argc, &argv);
- glutInitWindowSize(width, height);
- glutInitWindowPosition(0, 0);
- glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
- glutCreateWindow(title);
-
- glewInit();
-
- view_reshape(width, height);
-
- glutDisplayFunc(view_display);
- glutIdleFunc(view_idle);
- glutReshapeFunc(view_reshape);
- glutKeyboardFunc(view_keyboard);
- glutMouseFunc(view_mouse);
- glutMotionFunc(view_motion);
-
- glutMainLoop();
+ const char *name = "app";
+ char *argv = (char *)name;
+ int argc = 1;
+
+ memset(&V, 0, sizeof(V));
+ V.width = width;
+ V.height = height;
+ V.first_display = true;
+ V.redraw = false;
+ V.initf = initf;
+ V.exitf = exitf;
+ V.resize = resize;
+ V.display = display;
+ V.keyboard = keyboard;
+ V.motion = motion;
+
+ glutInit(&argc, &argv);
+ glutInitWindowSize(width, height);
+ glutInitWindowPosition(0, 0);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ glutCreateWindow(title);
+
+ glewInit();
+
+ view_reshape(width, height);
+
+ glutDisplayFunc(view_display);
+ glutIdleFunc(view_idle);
+ glutReshapeFunc(view_reshape);
+ glutKeyboardFunc(view_keyboard);
+ glutMouseFunc(view_mouse);
+ glutMotionFunc(view_motion);
+
+ glutMainLoop();
}
void view_redraw()
{
- V.redraw = true;
+ V.redraw = true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_view.h b/intern/cycles/util/util_view.h
index ae50b098b39..ad5c53ee5d5 100644
--- a/intern/cycles/util/util_view.h
+++ b/intern/cycles/util/util_view.h
@@ -29,10 +29,15 @@ typedef void (*ViewDisplayFunc)();
typedef void (*ViewKeyboardFunc)(unsigned char key);
typedef void (*ViewMotionFunc)(int x, int y, int button);
-void view_main_loop(const char *title, int width, int height,
- ViewInitFunc initf, ViewExitFunc exitf,
- ViewResizeFunc resize, ViewDisplayFunc display,
- ViewKeyboardFunc keyboard, ViewMotionFunc motion);
+void view_main_loop(const char *title,
+ int width,
+ int height,
+ ViewInitFunc initf,
+ ViewExitFunc exitf,
+ ViewResizeFunc resize,
+ ViewDisplayFunc display,
+ ViewKeyboardFunc keyboard,
+ ViewMotionFunc motion);
void view_display_info(const char *info);
void view_display_help();
@@ -40,4 +45,4 @@ void view_redraw();
CCL_NAMESPACE_END
-#endif /*__UTIL_VIEW_H__*/
+#endif /*__UTIL_VIEW_H__*/
diff --git a/intern/cycles/util/util_windows.h b/intern/cycles/util/util_windows.h
index bd1bc85adff..0d85c5437f6 100644
--- a/intern/cycles/util/util_windows.h
+++ b/intern/cycles/util/util_windows.h
@@ -19,18 +19,18 @@
#ifdef _WIN32
-#ifndef NOGDI
-# define NOGDI
-#endif
-#ifndef NOMINMAX
-# define NOMINMAX
-#endif
-#ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
+# ifndef NOGDI
+# define NOGDI
+# endif
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
-#include <windows.h>
+# include <windows.h>
-#endif /* _WIN32 */
+#endif /* _WIN32 */
-#endif /* __UTIL_WINDOWS_H__ */
+#endif /* __UTIL_WINDOWS_H__ */
diff --git a/intern/cycles/util/util_xml.h b/intern/cycles/util/util_xml.h
index c8a3a495f30..6f06f17937b 100644
--- a/intern/cycles/util/util_xml.h
+++ b/intern/cycles/util/util_xml.h
@@ -38,4 +38,4 @@ using PUGIXML_NAMESPACE::xml_parse_result;
CCL_NAMESPACE_END
-#endif /* __UTIL_XML_H__ */
+#endif /* __UTIL_XML_H__ */
diff --git a/intern/dualcon/CMakeLists.txt b/intern/dualcon/CMakeLists.txt
index a5c1137bc65..9a0be94fc75 100644
--- a/intern/dualcon/CMakeLists.txt
+++ b/intern/dualcon/CMakeLists.txt
@@ -17,32 +17,32 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- intern
+ .
+ intern
)
set(INC_SYS
- ${EIGEN3_INCLUDE_DIRS}
+ ${EIGEN3_INCLUDE_DIRS}
)
set(SRC
- intern/manifold_table.cpp
- intern/marching_cubes_table.cpp
- intern/octree.cpp
- intern/Projections.cpp
+ intern/manifold_table.cpp
+ intern/marching_cubes_table.cpp
+ intern/octree.cpp
+ intern/Projections.cpp
- intern/cubes.h
- intern/GeoCommon.h
- intern/manifold_table.h
- intern/marching_cubes_table.h
- intern/MemoryAllocator.h
- intern/ModelReader.h
- intern/octree.h
- intern/Projections.h
- intern/Queue.h
+ intern/cubes.h
+ intern/GeoCommon.h
+ intern/manifold_table.h
+ intern/marching_cubes_table.h
+ intern/MemoryAllocator.h
+ intern/ModelReader.h
+ intern/octree.h
+ intern/Projections.h
+ intern/Queue.h
- intern/dualcon_c_api.cpp
- dualcon.h
+ intern/dualcon_c_api.cpp
+ dualcon.h
)
set(LIB
diff --git a/intern/dualcon/dualcon.h b/intern/dualcon/dualcon.h
index 4e84e60154d..e9bff72a1ce 100644
--- a/intern/dualcon/dualcon.h
+++ b/intern/dualcon/dualcon.h
@@ -29,22 +29,22 @@ typedef float (*DualConCo)[3];
typedef unsigned int (*DualConTri)[3];
-typedef unsigned int (*DualConLoop);
+typedef unsigned int(*DualConLoop);
typedef struct DualConInput {
- DualConLoop mloop;
+ DualConLoop mloop;
- DualConCo co;
- int co_stride;
- int totco;
+ DualConCo co;
+ int co_stride;
+ int totco;
- DualConTri looptri;
- int tri_stride;
- int tottri;
+ DualConTri looptri;
+ int tri_stride;
+ int tottri;
- int loop_stride;
+ int loop_stride;
- float min[3], max[3];
+ float min[3], max[3];
} DualConInput;
/* callback for allocating memory for output */
@@ -55,16 +55,16 @@ typedef void (*DualConAddVert)(void *output, const float co[3]);
typedef void (*DualConAddQuad)(void *output, const int vert_indices[4]);
typedef enum {
- DUALCON_FLOOD_FILL = 1,
+ DUALCON_FLOOD_FILL = 1,
} DualConFlags;
typedef enum {
- /* blocky */
- DUALCON_CENTROID,
- /* smooth */
- DUALCON_MASS_POINT,
- /* keeps sharp edges */
- DUALCON_SHARP_FEATURES,
+ /* blocky */
+ DUALCON_CENTROID,
+ /* smooth */
+ DUALCON_MASS_POINT,
+ /* keeps sharp edges */
+ DUALCON_SHARP_FEATURES,
} DualConMode;
/* Usage:
diff --git a/intern/dualcon/intern/GeoCommon.h b/intern/dualcon/intern/GeoCommon.h
index 3c21b4c36e8..421e2c5e65e 100644
--- a/intern/dualcon/intern/GeoCommon.h
+++ b/intern/dualcon/intern/GeoCommon.h
@@ -28,31 +28,29 @@
* @author Tao Ju
*/
-
// 3d point with integer coordinates
typedef struct {
- int x, y, z;
+ int x, y, z;
} Point3i;
typedef struct {
- Point3i begin;
- Point3i end;
+ Point3i begin;
+ Point3i end;
} BoundingBox;
// triangle that points to three vertices
typedef struct {
- float vt[3][3];
+ float vt[3][3];
} Triangle;
// 3d point with float coordinates
typedef struct {
- float x, y, z;
+ float x, y, z;
} Point3f;
typedef struct {
- Point3f begin;
- Point3f end;
+ Point3f begin;
+ Point3f end;
} BoundingBoxf;
-
-#endif /* __GEOCOMMON_H__ */
+#endif /* __GEOCOMMON_H__ */
diff --git a/intern/dualcon/intern/MemoryAllocator.h b/intern/dualcon/intern/MemoryAllocator.h
index 035348483fc..933b9dea197 100644
--- a/intern/dualcon/intern/MemoryAllocator.h
+++ b/intern/dualcon/intern/MemoryAllocator.h
@@ -29,29 +29,27 @@
* @author Tao Ju
*/
-
-
/**
* Base class of memory allocators
*/
-class VirtualMemoryAllocator
-{
-public:
-virtual ~VirtualMemoryAllocator() {}
+class VirtualMemoryAllocator {
+ public:
+ virtual ~VirtualMemoryAllocator()
+ {
+ }
-virtual void *allocate( ) = 0;
-virtual void deallocate(void *obj) = 0;
-virtual void destroy( ) = 0;
-virtual void printInfo( ) = 0;
+ virtual void *allocate() = 0;
+ virtual void deallocate(void *obj) = 0;
+ virtual void destroy() = 0;
+ virtual void printInfo() = 0;
-virtual int getAllocated( ) = 0;
-virtual int getAll( ) = 0;
-virtual int getBytes( ) = 0;
+ virtual int getAllocated() = 0;
+ virtual int getAll() = 0;
+ virtual int getBytes() = 0;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:VirtualMemoryAllocator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:VirtualMemoryAllocator")
#endif
-
};
/**
@@ -59,167 +57,160 @@ virtual int getBytes( ) = 0;
*
* Note: there are 4 bytes overhead for each allocated yet unused object.
*/
-template < int N >
-class MemoryAllocator : public VirtualMemoryAllocator
-{
-private:
+template<int N> class MemoryAllocator : public VirtualMemoryAllocator {
+ private:
+ /// Constants
+ int HEAP_UNIT, HEAP_MASK;
-/// Constants
-int HEAP_UNIT, HEAP_MASK;
+ /// Data array
+ UCHAR **data;
-/// Data array
-UCHAR **data;
+ /// Allocation stack
+ UCHAR ***stack;
-/// Allocation stack
-UCHAR ***stack;
+ /// Number of data blocks
+ int datablocknum;
-/// Number of data blocks
-int datablocknum;
+ /// Number of stack blocks
+ int stackblocknum;
-/// Number of stack blocks
-int stackblocknum;
+ /// Size of stack
+ int stacksize;
-/// Size of stack
-int stacksize;
+ /// Number of available objects on stack
+ int available;
-/// Number of available objects on stack
-int available;
-
-/**
+ /**
* Allocate a memory block
*/
-void allocateDataBlock( )
-{
- // Allocate a data block
- datablocknum += 1;
- data = ( UCHAR ** )realloc(data, sizeof (UCHAR *) * datablocknum);
- data[datablocknum - 1] = ( UCHAR * )malloc(HEAP_UNIT * N);
-
- // Update allocation stack
- for (int i = 0; i < HEAP_UNIT; i++)
- {
- stack[0][i] = (data[datablocknum - 1] + i * N);
- }
- available = HEAP_UNIT;
-}
-
-/**
+ void allocateDataBlock()
+ {
+ // Allocate a data block
+ datablocknum += 1;
+ data = (UCHAR **)realloc(data, sizeof(UCHAR *) * datablocknum);
+ data[datablocknum - 1] = (UCHAR *)malloc(HEAP_UNIT * N);
+
+ // Update allocation stack
+ for (int i = 0; i < HEAP_UNIT; i++) {
+ stack[0][i] = (data[datablocknum - 1] + i * N);
+ }
+ available = HEAP_UNIT;
+ }
+
+ /**
* Allocate a stack block, to store more deallocated objects
*/
-void allocateStackBlock( )
-{
- // Allocate a stack block
- stackblocknum += 1;
- stacksize += HEAP_UNIT;
- stack = ( UCHAR *** )realloc(stack, sizeof (UCHAR * *) * stackblocknum);
- stack[stackblocknum - 1] = ( UCHAR ** )malloc(HEAP_UNIT * sizeof (UCHAR *) );
-}
-
-
-public:
-/**
+ void allocateStackBlock()
+ {
+ // Allocate a stack block
+ stackblocknum += 1;
+ stacksize += HEAP_UNIT;
+ stack = (UCHAR ***)realloc(stack, sizeof(UCHAR **) * stackblocknum);
+ stack[stackblocknum - 1] = (UCHAR **)malloc(HEAP_UNIT * sizeof(UCHAR *));
+ }
+
+ public:
+ /**
* Constructor
*/
-MemoryAllocator( )
-{
- HEAP_UNIT = 1 << HEAP_BASE;
- HEAP_MASK = (1 << HEAP_BASE) - 1;
-
- data = ( UCHAR ** )malloc(sizeof(UCHAR *) );
- data[0] = ( UCHAR * )malloc(HEAP_UNIT * N);
- datablocknum = 1;
-
- stack = ( UCHAR *** )malloc(sizeof (UCHAR * *) );
- stack[0] = ( UCHAR ** )malloc(HEAP_UNIT * sizeof (UCHAR *) );
- stackblocknum = 1;
- stacksize = HEAP_UNIT;
- available = HEAP_UNIT;
-
- for (int i = 0; i < HEAP_UNIT; i++)
- {
- stack[0][i] = (data[0] + i * N);
- }
-}
-
-/**
+ MemoryAllocator()
+ {
+ HEAP_UNIT = 1 << HEAP_BASE;
+ HEAP_MASK = (1 << HEAP_BASE) - 1;
+
+ data = (UCHAR **)malloc(sizeof(UCHAR *));
+ data[0] = (UCHAR *)malloc(HEAP_UNIT * N);
+ datablocknum = 1;
+
+ stack = (UCHAR ***)malloc(sizeof(UCHAR **));
+ stack[0] = (UCHAR **)malloc(HEAP_UNIT * sizeof(UCHAR *));
+ stackblocknum = 1;
+ stacksize = HEAP_UNIT;
+ available = HEAP_UNIT;
+
+ for (int i = 0; i < HEAP_UNIT; i++) {
+ stack[0][i] = (data[0] + i * N);
+ }
+ }
+
+ /**
* Destructor
*/
-void destroy( )
-{
- int i;
- for (i = 0; i < datablocknum; i++)
- {
- free(data[i]);
- }
- for (i = 0; i < stackblocknum; i++)
- {
- free(stack[i]);
- }
- free(data);
- free(stack);
-}
-
-/**
+ void destroy()
+ {
+ int i;
+ for (i = 0; i < datablocknum; i++) {
+ free(data[i]);
+ }
+ for (i = 0; i < stackblocknum; i++) {
+ free(stack[i]);
+ }
+ free(data);
+ free(stack);
+ }
+
+ /**
* Allocation method
*/
-void *allocate( )
-{
- if (available == 0)
- {
- allocateDataBlock( );
- }
-
- // printf("Allocating %d\n", header[ allocated ]) ;
- available--;
- return (void *)stack[available >> HEAP_BASE][available & HEAP_MASK];
-}
-
-/**
+ void *allocate()
+ {
+ if (available == 0) {
+ allocateDataBlock();
+ }
+
+ // printf("Allocating %d\n", header[ allocated ]) ;
+ available--;
+ return (void *)stack[available >> HEAP_BASE][available & HEAP_MASK];
+ }
+
+ /**
* De-allocation method
*/
-void deallocate(void *obj)
-{
- if (available == stacksize)
- {
- allocateStackBlock( );
- }
-
- // printf("De-allocating %d\n", ( obj - data ) / N ) ;
- stack[available >> HEAP_BASE][available & HEAP_MASK] = (UCHAR *)obj;
- available++;
- // printf("%d %d\n", allocated, header[ allocated ]) ;
-}
-
-/**
+ void deallocate(void *obj)
+ {
+ if (available == stacksize) {
+ allocateStackBlock();
+ }
+
+ // printf("De-allocating %d\n", ( obj - data ) / N ) ;
+ stack[available >> HEAP_BASE][available & HEAP_MASK] = (UCHAR *)obj;
+ available++;
+ // printf("%d %d\n", allocated, header[ allocated ]) ;
+ }
+
+ /**
* Print information
*/
-void printInfo( )
-{
- printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n", getBytes(), getAllocated(), getAll(), stacksize);
-}
-
-/**
+ void printInfo()
+ {
+ printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n",
+ getBytes(),
+ getAllocated(),
+ getAll(),
+ stacksize);
+ }
+
+ /**
* Query methods
*/
-int getAllocated( )
-{
- return HEAP_UNIT * datablocknum - available;
-};
+ int getAllocated()
+ {
+ return HEAP_UNIT * datablocknum - available;
+ };
-int getAll( )
-{
- return HEAP_UNIT * datablocknum;
-};
+ int getAll()
+ {
+ return HEAP_UNIT * datablocknum;
+ };
-int getBytes( )
-{
- return N;
-};
+ int getBytes()
+ {
+ return N;
+ };
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:MemoryAllocator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:MemoryAllocator")
#endif
-
};
-#endif /* __MEMORYALLOCATOR_H__ */
+#endif /* __MEMORYALLOCATOR_H__ */
diff --git a/intern/dualcon/intern/ModelReader.h b/intern/dualcon/intern/ModelReader.h
index ae735b2f1d0..0f056724a62 100644
--- a/intern/dualcon/intern/ModelReader.h
+++ b/intern/dualcon/intern/ModelReader.h
@@ -24,40 +24,37 @@
*
* @author Tao Ju
*/
-class ModelReader
-{
-public:
-/// Constructor
-ModelReader(){
-};
+class ModelReader {
+ public:
+ /// Constructor
+ ModelReader(){};
-/// Get next triangle
-virtual Triangle *getNextTriangle( ) = 0;
-virtual int getNextTriangle(int t[3]) = 0;
+ /// Get next triangle
+ virtual Triangle *getNextTriangle() = 0;
+ virtual int getNextTriangle(int t[3]) = 0;
-/// Get bounding box
-virtual float getBoundingBox(float origin[3]) = 0;
+ /// Get bounding box
+ virtual float getBoundingBox(float origin[3]) = 0;
-/// Get number of triangles
-virtual int getNumTriangles( ) = 0;
+ /// Get number of triangles
+ virtual int getNumTriangles() = 0;
-/// Get storage size
-virtual int getMemory( ) = 0;
+ /// Get storage size
+ virtual int getMemory() = 0;
-/// Reset file reading location
-virtual void reset( ) = 0;
+ /// Reset file reading location
+ virtual void reset() = 0;
-/// For explicit vertex models
-virtual int getNumVertices( ) = 0;
+ /// For explicit vertex models
+ virtual int getNumVertices() = 0;
-virtual void getNextVertex(float v[3]) = 0;
+ virtual void getNextVertex(float v[3]) = 0;
-virtual void printInfo( ) = 0;
+ virtual void printInfo() = 0;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:ModelReader")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:ModelReader")
#endif
-
};
-#endif /* __MODELREADER_H__ */
+#endif /* __MODELREADER_H__ */
diff --git a/intern/dualcon/intern/Projections.cpp b/intern/dualcon/intern/Projections.cpp
index 9fc9f5beb14..b065ba95330 100644
--- a/intern/dualcon/intern/Projections.cpp
+++ b/intern/dualcon/intern/Projections.cpp
@@ -22,52 +22,45 @@
#include "Projections.h"
const int vertmap[8][3] = {
- {0, 0, 0},
- {0, 0, 1},
- {0, 1, 0},
- {0, 1, 1},
- {1, 0, 0},
- {1, 0, 1},
- {1, 1, 0},
- {1, 1, 1},
+ {0, 0, 0},
+ {0, 0, 1},
+ {0, 1, 0},
+ {0, 1, 1},
+ {1, 0, 0},
+ {1, 0, 1},
+ {1, 1, 0},
+ {1, 1, 1},
};
const int centmap[3][3][3][2] = {
- {{{0, 0}, {0, 1}, {1, 1}},
- {{0, 2}, {0, 3}, {1, 3}},
- {{2, 2}, {2, 3}, {3, 3}}},
+ {{{0, 0}, {0, 1}, {1, 1}}, {{0, 2}, {0, 3}, {1, 3}}, {{2, 2}, {2, 3}, {3, 3}}},
- {{{0, 4}, {0, 5}, {1, 5}},
- {{0, 6}, {0, 7}, {1, 7}},
- {{2, 6}, {2, 7}, {3, 7}}},
+ {{{0, 4}, {0, 5}, {1, 5}}, {{0, 6}, {0, 7}, {1, 7}}, {{2, 6}, {2, 7}, {3, 7}}},
- {{{4, 4}, {4, 5}, {5, 5}},
- {{4, 6}, {4, 7}, {5, 7}},
- {{6, 6}, {6, 7}, {7, 7}}}
-};
+ {{{4, 4}, {4, 5}, {5, 5}}, {{4, 6}, {4, 7}, {5, 7}}, {{6, 6}, {6, 7}, {7, 7}}}};
const int edgemap[12][2] = {
- {0, 4},
- {1, 5},
- {2, 6},
- {3, 7},
- {0, 2},
- {1, 3},
- {4, 6},
- {5, 7},
- {0, 1},
- {2, 3},
- {4, 5},
- {6, 7},
+ {0, 4},
+ {1, 5},
+ {2, 6},
+ {3, 7},
+ {0, 2},
+ {1, 3},
+ {4, 6},
+ {5, 7},
+ {0, 1},
+ {2, 3},
+ {4, 5},
+ {6, 7},
};
const int facemap[6][4] = {
- {0, 1, 2, 3},
- {4, 5, 6, 7},
- {0, 1, 4, 5},
- {2, 3, 6, 7},
- {0, 2, 4, 6},
- {1, 3, 5, 7},
+ {0, 1, 2, 3},
+ {4, 5, 6, 7},
+ {0, 1, 4, 5},
+ {2, 3, 6, 7},
+ {0, 2, 4, 6},
+ {1, 3, 5, 7},
};
/**
@@ -75,16 +68,16 @@ const int facemap[6][4] = {
*/
static void crossProduct(int64_t res[3], const int64_t a[3], const int64_t b[3])
{
- res[0] = a[1] * b[2] - a[2] * b[1];
- res[1] = a[2] * b[0] - a[0] * b[2];
- res[2] = a[0] * b[1] - a[1] * b[0];
+ res[0] = a[1] * b[2] - a[2] * b[1];
+ res[1] = a[2] * b[0] - a[0] * b[2];
+ res[2] = a[0] * b[1] - a[1] * b[0];
}
static void crossProduct(double res[3], const double a[3], const double b[3])
{
- res[0] = a[1] * b[2] - a[2] * b[1];
- res[1] = a[2] * b[0] - a[0] * b[2];
- res[2] = a[0] * b[1] - a[1] * b[0];
+ res[0] = a[1] * b[2] - a[2] * b[1];
+ res[1] = a[2] * b[0] - a[0] * b[2];
+ res[2] = a[0] * b[1] - a[1] * b[0];
}
/**
@@ -92,18 +85,18 @@ static void crossProduct(double res[3], const double a[3], const double b[3])
*/
static int64_t dotProduct(const int64_t a[3], const int64_t b[3])
{
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
static void normalize(double a[3])
{
- double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
- if (mag > 0) {
- mag = sqrt(mag);
- a[0] /= mag;
- a[1] /= mag;
- a[2] /= mag;
- }
+ double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
+ if (mag > 0) {
+ mag = sqrt(mag);
+ a[0] /= mag;
+ a[1] /= mag;
+ a[2] /= mag;
+ }
}
/* Create projection axes for cube+triangle intersection testing.
@@ -118,114 +111,115 @@ static void normalize(double a[3])
*/
static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[3][3])
{
- /* Cube face normals */
- axes[0][0] = 1;
- axes[0][1] = 0;
- axes[0][2] = 0;
- axes[1][0] = 0;
- axes[1][1] = 1;
- axes[1][2] = 0;
- axes[2][0] = 0;
- axes[2][1] = 0;
- axes[2][2] = 1;
-
- /* Get triangle edge vectors */
- int64_t tri_edges[3][3];
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++)
- tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
- }
-
- /* Triangle normal */
- crossProduct(axes[3], tri_edges[0], tri_edges[1]);
-
- // Face edges and triangle edges
- int ct = 4;
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- crossProduct(axes[ct], axes[j], tri_edges[i]);
- ct++;
- }
- }
+ /* Cube face normals */
+ axes[0][0] = 1;
+ axes[0][1] = 0;
+ axes[0][2] = 0;
+ axes[1][0] = 0;
+ axes[1][1] = 1;
+ axes[1][2] = 0;
+ axes[2][0] = 0;
+ axes[2][1] = 0;
+ axes[2][2] = 1;
+
+ /* Get triangle edge vectors */
+ int64_t tri_edges[3][3];
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++)
+ tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
+ }
+
+ /* Triangle normal */
+ crossProduct(axes[3], tri_edges[0], tri_edges[1]);
+
+ // Face edges and triangle edges
+ int ct = 4;
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ crossProduct(axes[ct], axes[j], tri_edges[i]);
+ ct++;
+ }
+ }
}
/**
* Construction from a cube (axes aligned) and triangle
*/
-CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3], int64_t tri[3][3], int64_t /*error*/, int triind)
+CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3],
+ int64_t tri[3][3],
+ int64_t /*error*/,
+ int triind)
{
- int i;
- inherit = new TriangleProjection;
- inherit->index = triind;
-
- int64_t axes[NUM_AXES][3];
- create_projection_axes(axes, tri);
-
- /* Normalize face normal and store */
- double dedge1[] = {(double)tri[1][0] - (double)tri[0][0],
- (double)tri[1][1] - (double)tri[0][1],
- (double)tri[1][2] - (double)tri[0][2]};
- double dedge2[] = {(double)tri[2][0] - (double)tri[1][0],
- (double)tri[2][1] - (double)tri[1][1],
- (double)tri[2][2] - (double)tri[1][2]};
- crossProduct(inherit->norm, dedge1, dedge2);
- normalize(inherit->norm);
-
- int64_t cubeedge[3][3];
- for (i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- cubeedge[i][j] = 0;
- }
- cubeedge[i][i] = cube[1][i] - cube[0][i];
- }
-
- /* Project the cube on to each axis */
- for (int axis = 0; axis < NUM_AXES; axis++) {
- CubeProjection &cube_proj = cubeProj[axis];
-
- /* Origin */
- cube_proj.origin = dotProduct(axes[axis], cube[0]);
-
- /* 3 direction vectors */
- for (i = 0; i < 3; i++)
- cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
-
- /* Offsets of 2 ends of cube projection */
- int64_t max = 0;
- int64_t min = 0;
- for (i = 1; i < 8; i++) {
- int64_t proj = (vertmap[i][0] * cube_proj.edges[0] +
- vertmap[i][1] * cube_proj.edges[1] +
- vertmap[i][2] * cube_proj.edges[2]);
- if (proj > max) {
- max = proj;
- }
- if (proj < min) {
- min = proj;
- }
- }
- cube_proj.min = min;
- cube_proj.max = max;
-
- }
-
- /* Project the triangle on to each axis */
- for (int axis = 0; axis < NUM_AXES; axis++) {
- const int64_t vts[3] = {dotProduct(axes[axis], tri[0]),
- dotProduct(axes[axis], tri[1]),
- dotProduct(axes[axis], tri[2])};
-
- // Triangle
- inherit->tri_proj[axis][0] = vts[0];
- inherit->tri_proj[axis][1] = vts[0];
- for (i = 1; i < 3; i++) {
- if (vts[i] < inherit->tri_proj[axis][0])
- inherit->tri_proj[axis][0] = vts[i];
-
- if (vts[i] > inherit->tri_proj[axis][1])
- inherit->tri_proj[axis][1] = vts[i];
- }
- }
+ int i;
+ inherit = new TriangleProjection;
+ inherit->index = triind;
+
+ int64_t axes[NUM_AXES][3];
+ create_projection_axes(axes, tri);
+
+ /* Normalize face normal and store */
+ double dedge1[] = {(double)tri[1][0] - (double)tri[0][0],
+ (double)tri[1][1] - (double)tri[0][1],
+ (double)tri[1][2] - (double)tri[0][2]};
+ double dedge2[] = {(double)tri[2][0] - (double)tri[1][0],
+ (double)tri[2][1] - (double)tri[1][1],
+ (double)tri[2][2] - (double)tri[1][2]};
+ crossProduct(inherit->norm, dedge1, dedge2);
+ normalize(inherit->norm);
+
+ int64_t cubeedge[3][3];
+ for (i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ cubeedge[i][j] = 0;
+ }
+ cubeedge[i][i] = cube[1][i] - cube[0][i];
+ }
+
+ /* Project the cube on to each axis */
+ for (int axis = 0; axis < NUM_AXES; axis++) {
+ CubeProjection &cube_proj = cubeProj[axis];
+
+ /* Origin */
+ cube_proj.origin = dotProduct(axes[axis], cube[0]);
+
+ /* 3 direction vectors */
+ for (i = 0; i < 3; i++)
+ cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
+
+ /* Offsets of 2 ends of cube projection */
+ int64_t max = 0;
+ int64_t min = 0;
+ for (i = 1; i < 8; i++) {
+ int64_t proj = (vertmap[i][0] * cube_proj.edges[0] + vertmap[i][1] * cube_proj.edges[1] +
+ vertmap[i][2] * cube_proj.edges[2]);
+ if (proj > max) {
+ max = proj;
+ }
+ if (proj < min) {
+ min = proj;
+ }
+ }
+ cube_proj.min = min;
+ cube_proj.max = max;
+ }
+
+ /* Project the triangle on to each axis */
+ for (int axis = 0; axis < NUM_AXES; axis++) {
+ const int64_t vts[3] = {dotProduct(axes[axis], tri[0]),
+ dotProduct(axes[axis], tri[1]),
+ dotProduct(axes[axis], tri[2])};
+
+ // Triangle
+ inherit->tri_proj[axis][0] = vts[0];
+ inherit->tri_proj[axis][1] = vts[0];
+ for (i = 1; i < 3; i++) {
+ if (vts[i] < inherit->tri_proj[axis][0])
+ inherit->tri_proj[axis][0] = vts[i];
+
+ if (vts[i] > inherit->tri_proj[axis][1])
+ inherit->tri_proj[axis][1] = vts[i];
+ }
+ }
}
/**
@@ -234,67 +228,64 @@ CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3], int64_t tri[3][3], int6
*/
CubeTriangleIsect::CubeTriangleIsect(CubeTriangleIsect *parent)
{
- // Copy inheritable projections
- this->inherit = parent->inherit;
+ // Copy inheritable projections
+ this->inherit = parent->inherit;
- // Shrink cube projections
- for (int i = 0; i < NUM_AXES; i++) {
- cubeProj[i].origin = parent->cubeProj[i].origin;
+ // Shrink cube projections
+ for (int i = 0; i < NUM_AXES; i++) {
+ cubeProj[i].origin = parent->cubeProj[i].origin;
- for (int j = 0; j < 3; j++)
- cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
+ for (int j = 0; j < 3; j++)
+ cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
- cubeProj[i].min = parent->cubeProj[i].min >> 1;
- cubeProj[i].max = parent->cubeProj[i].max >> 1;
- }
+ cubeProj[i].min = parent->cubeProj[i].min >> 1;
+ cubeProj[i].max = parent->cubeProj[i].max >> 1;
+ }
}
-unsigned char CubeTriangleIsect::getBoxMask( )
+unsigned char CubeTriangleIsect::getBoxMask()
{
- int i, j, k;
- int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
- unsigned char boxmask = 0;
- int64_t child_len = cubeProj[0].edges[0] >> 1;
-
- for (i = 0; i < 3; i++) {
- int64_t mid = cubeProj[i].origin + child_len;
-
- // Check bounding box
- if (mid >= inherit->tri_proj[i][0]) {
- bmask[i][0] = 1;
- }
- if (mid < inherit->tri_proj[i][1]) {
- bmask[i][1] = 1;
- }
-
- }
-
- // Fill in masks
- int ct = 0;
- for (i = 0; i < 2; i++) {
- for (j = 0; j < 2; j++) {
- for (k = 0; k < 2; k++) {
- boxmask |= ( (bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
- ct++;
- }
- }
- }
-
- // Return bounding box masks
- return boxmask;
+ int i, j, k;
+ int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
+ unsigned char boxmask = 0;
+ int64_t child_len = cubeProj[0].edges[0] >> 1;
+
+ for (i = 0; i < 3; i++) {
+ int64_t mid = cubeProj[i].origin + child_len;
+
+ // Check bounding box
+ if (mid >= inherit->tri_proj[i][0]) {
+ bmask[i][0] = 1;
+ }
+ if (mid < inherit->tri_proj[i][1]) {
+ bmask[i][1] = 1;
+ }
+ }
+
+ // Fill in masks
+ int ct = 0;
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ for (k = 0; k < 2; k++) {
+ boxmask |= ((bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
+ ct++;
+ }
+ }
+ }
+
+ // Return bounding box masks
+ return boxmask;
}
-
/**
* Shifting a cube to a new origin
*/
void CubeTriangleIsect::shift(int off[3])
{
- for (int i = 0; i < NUM_AXES; i++) {
- cubeProj[i].origin += (off[0] * cubeProj[i].edges[0] +
- off[1] * cubeProj[i].edges[1] +
- off[2] * cubeProj[i].edges[2]);
- }
+ for (int i = 0; i < NUM_AXES; i++) {
+ cubeProj[i].origin += (off[0] * cubeProj[i].edges[0] + off[1] * cubeProj[i].edges[1] +
+ off[2] * cubeProj[i].edges[2]);
+ }
}
/**
@@ -302,75 +293,70 @@ void CubeTriangleIsect::shift(int off[3])
*/
int CubeTriangleIsect::isIntersecting() const
{
- for (int i = 0; i < NUM_AXES; i++) {
- /*
- int64_t proj0 = cubeProj[i][0] +
- vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
- vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
- vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
- int64_t proj1 = cubeProj[i][0] +
- vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
- vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
- vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
- */
-
- int64_t proj0 = cubeProj[i].origin + cubeProj[i].min;
- int64_t proj1 = cubeProj[i].origin + cubeProj[i].max;
-
- if (proj0 > inherit->tri_proj[i][1] ||
- proj1 < inherit->tri_proj[i][0]) {
- return 0;
- }
- }
-
- return 1;
+ for (int i = 0; i < NUM_AXES; i++) {
+ /*
+ int64_t proj0 = cubeProj[i][0] +
+ vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
+ vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
+ vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
+ int64_t proj1 = cubeProj[i][0] +
+ vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
+ vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
+ vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
+ */
+
+ int64_t proj0 = cubeProj[i].origin + cubeProj[i].min;
+ int64_t proj1 = cubeProj[i].origin + cubeProj[i].max;
+
+ if (proj0 > inherit->tri_proj[i][1] || proj1 < inherit->tri_proj[i][0]) {
+ return 0;
+ }
+ }
+
+ return 1;
}
int CubeTriangleIsect::isIntersectingPrimary(int edgeInd) const
{
- for (int i = 0; i < NUM_AXES; i++) {
-
- int64_t proj0 = cubeProj[i].origin;
- int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
-
- if (proj0 < proj1) {
- if (proj0 > inherit->tri_proj[i][1] ||
- proj1 < inherit->tri_proj[i][0]) {
- return 0;
- }
- }
- else {
- if (proj1 > inherit->tri_proj[i][1] ||
- proj0 < inherit->tri_proj[i][0]) {
- return 0;
- }
- }
-
- }
-
- // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ;
- return 1;
+ for (int i = 0; i < NUM_AXES; i++) {
+
+ int64_t proj0 = cubeProj[i].origin;
+ int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
+
+ if (proj0 < proj1) {
+ if (proj0 > inherit->tri_proj[i][1] || proj1 < inherit->tri_proj[i][0]) {
+ return 0;
+ }
+ }
+ else {
+ if (proj1 > inherit->tri_proj[i][1] || proj0 < inherit->tri_proj[i][0]) {
+ return 0;
+ }
+ }
+ }
+
+ // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ;
+ return 1;
}
float CubeTriangleIsect::getIntersectionPrimary(int edgeInd) const
{
- int i = 3;
-
+ int i = 3;
- int64_t proj0 = cubeProj[i].origin;
- int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
- int64_t proj2 = inherit->tri_proj[i][1];
- int64_t d = proj1 - proj0;
- double alpha;
+ int64_t proj0 = cubeProj[i].origin;
+ int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
+ int64_t proj2 = inherit->tri_proj[i][1];
+ int64_t d = proj1 - proj0;
+ double alpha;
- if (d == 0)
- alpha = 0.5;
- else {
- alpha = (double)((proj2 - proj0)) / (double)d;
+ if (d == 0)
+ alpha = 0.5;
+ else {
+ alpha = (double)((proj2 - proj0)) / (double)d;
- if (alpha < 0 || alpha > 1)
- alpha = 0.5;
- }
+ if (alpha < 0 || alpha > 1)
+ alpha = 0.5;
+ }
- return (float)alpha;
+ return (float)alpha;
}
diff --git a/intern/dualcon/intern/Projections.h b/intern/dualcon/intern/Projections.h
index e77c234b058..fc650158a0b 100644
--- a/intern/dualcon/intern/Projections.h
+++ b/intern/dualcon/intern/Projections.h
@@ -24,11 +24,11 @@
#define GRID_DIMENSION 20
#if defined(_WIN32) && !(_MSC_VER >= 1900)
-#define isnan(n) _isnan(n)
-#define LONG __int64
-#define int64_t __int64
+# define isnan(n) _isnan(n)
+# define LONG __int64
+# define int64_t __int64
#else
-#include <stdint.h>
+# include <stdint.h>
#endif
/**
@@ -59,71 +59,70 @@ extern const int facemap[6][4];
* Structure for the projections inheritable from parent
*/
struct TriangleProjection {
- /// Projections of triangle (min and max)
- int64_t tri_proj[NUM_AXES][2];
+ /// Projections of triangle (min and max)
+ int64_t tri_proj[NUM_AXES][2];
- /// Normal of the triangle
- double norm[3];
+ /// Normal of the triangle
+ double norm[3];
- /// Index of polygon
- int index;
+ /// Index of polygon
+ int index;
};
/* This is a projection for the cube against a single projection
axis, see CubeTriangleIsect.cubeProj */
struct CubeProjection {
- int64_t origin;
- int64_t edges[3];
- int64_t min, max;
+ int64_t origin;
+ int64_t edges[3];
+ int64_t min, max;
};
-
/**
* Class for projections of cube / triangle vertices on the separating axes
*/
-class CubeTriangleIsect
-{
-public:
- /// Inheritable portion
- TriangleProjection *inherit;
-
- /// Projections of the cube vertices
- CubeProjection cubeProj[NUM_AXES];
-
-public:
- CubeTriangleIsect() {}
-
- /**
- * Construction from a cube (axes aligned) and triangle
- */
- CubeTriangleIsect(int64_t cube[2][3], int64_t trig[3][3], int64_t error, int triind);
-
- /**
- * Construction from a parent CubeTriangleIsect object and the index of
- * the children
- */
- CubeTriangleIsect(CubeTriangleIsect *parent);
-
- unsigned char getBoxMask( );
-
- /**
- * Shifting a cube to a new origin
- */
- void shift(int off[3]);
-
- /**
- * Method to test intersection of the triangle and the cube
- */
- int isIntersecting() const;
-
- int isIntersectingPrimary(int edgeInd) const;
-
- float getIntersectionPrimary(int edgeInd) const;
+class CubeTriangleIsect {
+ public:
+ /// Inheritable portion
+ TriangleProjection *inherit;
+
+ /// Projections of the cube vertices
+ CubeProjection cubeProj[NUM_AXES];
+
+ public:
+ CubeTriangleIsect()
+ {
+ }
+
+ /**
+ * Construction from a cube (axes aligned) and triangle
+ */
+ CubeTriangleIsect(int64_t cube[2][3], int64_t trig[3][3], int64_t error, int triind);
+
+ /**
+ * Construction from a parent CubeTriangleIsect object and the index of
+ * the children
+ */
+ CubeTriangleIsect(CubeTriangleIsect *parent);
+
+ unsigned char getBoxMask();
+
+ /**
+ * Shifting a cube to a new origin
+ */
+ void shift(int off[3]);
+
+ /**
+ * Method to test intersection of the triangle and the cube
+ */
+ int isIntersecting() const;
+
+ int isIntersectingPrimary(int edgeInd) const;
+
+ float getIntersectionPrimary(int edgeInd) const;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:CubeTriangleIsect")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:CubeTriangleIsect")
#endif
-
};
-#endif /* __PROJECTIONS_H__ */
+#endif /* __PROJECTIONS_H__ */
diff --git a/intern/dualcon/intern/Queue.h b/intern/dualcon/intern/Queue.h
index 1a257aa9a85..2620ab6cb32 100644
--- a/intern/dualcon/intern/Queue.h
+++ b/intern/dualcon/intern/Queue.h
@@ -18,85 +18,78 @@
#define __QUEUE_H__
struct gridQueueEle {
- int x, y, z;
- UCHAR dir;
- gridQueueEle *next;
+ int x, y, z;
+ UCHAR dir;
+ gridQueueEle *next;
};
-class GridQueue
-{
-gridQueueEle *head;
-gridQueueEle *tail;
-int numEles;
-
-public:
-
-GridQueue( )
-{
- head = NULL;
- tail = NULL;
- numEles = 0;
-}
-
-gridQueueEle *getHead( )
-{
- return head;
-}
-
-int getNumElements( )
-{
- return numEles;
-}
-
-
-void pushQueue(int st[3], int dir)
-{
- gridQueueEle *ele = new gridQueueEle;
- ele->x = st[0];
- ele->y = st[1];
- ele->z = st[2];
- ele->dir = (UCHAR) dir;
- ele->next = NULL;
- if (head == NULL)
- {
- head = ele;
- }
- else {
- tail->next = ele;
- }
- tail = ele;
- numEles++;
-}
-
-int popQueue(int st[3], int& dir)
-{
- if (head == NULL)
- {
- return 0;
- }
-
- st[0] = head->x;
- st[1] = head->y;
- st[2] = head->z;
- dir = (int) (head->dir);
-
- gridQueueEle *temp = head;
- head = head->next;
- delete temp;
-
- if (head == NULL)
- {
- tail = NULL;
- }
- numEles--;
-
- return 1;
-}
+class GridQueue {
+ gridQueueEle *head;
+ gridQueueEle *tail;
+ int numEles;
+
+ public:
+ GridQueue()
+ {
+ head = NULL;
+ tail = NULL;
+ numEles = 0;
+ }
+
+ gridQueueEle *getHead()
+ {
+ return head;
+ }
+
+ int getNumElements()
+ {
+ return numEles;
+ }
+
+ void pushQueue(int st[3], int dir)
+ {
+ gridQueueEle *ele = new gridQueueEle;
+ ele->x = st[0];
+ ele->y = st[1];
+ ele->z = st[2];
+ ele->dir = (UCHAR)dir;
+ ele->next = NULL;
+ if (head == NULL) {
+ head = ele;
+ }
+ else {
+ tail->next = ele;
+ }
+ tail = ele;
+ numEles++;
+ }
+
+ int popQueue(int st[3], int &dir)
+ {
+ if (head == NULL) {
+ return 0;
+ }
+
+ st[0] = head->x;
+ st[1] = head->y;
+ st[2] = head->z;
+ dir = (int)(head->dir);
+
+ gridQueueEle *temp = head;
+ head = head->next;
+ delete temp;
+
+ if (head == NULL) {
+ tail = NULL;
+ }
+ numEles--;
+
+ return 1;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:GridQueue")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:GridQueue")
#endif
-
};
-#endif /* __QUEUE_H__ */
+#endif /* __QUEUE_H__ */
diff --git a/intern/dualcon/intern/cubes.h b/intern/dualcon/intern/cubes.h
index 1a8413524d4..3561ce008c2 100644
--- a/intern/dualcon/intern/cubes.h
+++ b/intern/dualcon/intern/cubes.h
@@ -20,26 +20,24 @@
#include "marching_cubes_table.h"
/* simple wrapper for auto-generated marching cubes data */
-class Cubes
-{
-public:
-/// Get number of triangles
-int getNumTriangle(int mask)
-{
- return marching_cubes_numtri[mask];
-}
+class Cubes {
+ public:
+ /// Get number of triangles
+ int getNumTriangle(int mask)
+ {
+ return marching_cubes_numtri[mask];
+ }
-/// Get a triangle
-void getTriangle(int mask, int index, int indices[3])
-{
- for (int i = 0; i < 3; i++)
- indices[i] = marching_cubes_tris[mask][index][i];
-}
+ /// Get a triangle
+ void getTriangle(int mask, int index, int indices[3])
+ {
+ for (int i = 0; i < 3; i++)
+ indices[i] = marching_cubes_tris[mask][index][i];
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Cubes")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Cubes")
#endif
-
};
-#endif /* __CUBES_H__ */
+#endif /* __CUBES_H__ */
diff --git a/intern/dualcon/intern/dualcon_c_api.cpp b/intern/dualcon/intern/dualcon_c_api.cpp
index 01aa8a608db..459bb711e13 100644
--- a/intern/dualcon/intern/dualcon_c_api.cpp
+++ b/intern/dualcon/intern/dualcon_c_api.cpp
@@ -23,141 +23,139 @@
#include <float.h>
#if defined(_WIN32)
-#define isnan(n) _isnan(n)
+# define isnan(n) _isnan(n)
#endif
static void veccopy(float dst[3], const float src[3])
{
- dst[0] = src[0];
- dst[1] = src[1];
- dst[2] = src[2];
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
}
#define GET_TRI(_mesh, _n) \
- (*(DualConTri)(((char *)(_mesh)->looptri) + ((_n) * (_mesh)->tri_stride)))
+ (*(DualConTri)(((char *)(_mesh)->looptri) + ((_n) * (_mesh)->tri_stride)))
-#define GET_CO(_mesh, _n) \
- (*(DualConCo)(((char *)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
+#define GET_CO(_mesh, _n) (*(DualConCo)(((char *)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
#define GET_LOOP(_mesh, _n) \
- (*(DualConLoop)(((char *)(_mesh)->mloop) + ((_n) * (_mesh)->loop_stride)))
-
-class DualConInputReader : public ModelReader
-{
-private:
-const DualConInput *input_mesh;
-int tottri, curtri;
-float min[3], max[3], maxsize;
-float scale;
-public:
-DualConInputReader(const DualConInput *mesh, float _scale)
- : input_mesh(mesh), scale(_scale)
-{
- reset();
-}
-
-void reset()
-{
- curtri = 0;
- maxsize = 0;
- tottri = input_mesh->tottri;
-
- veccopy(min, input_mesh->min);
- veccopy(max, input_mesh->max);
-
- /* initialize maxsize */
- for (int i = 0; i < 3; i++) {
- float d = max[i] - min[i];
- if (d > maxsize)
- maxsize = d;
- }
-
- /* redo the bounds */
- for (int i = 0; i < 3; i++)
- {
- min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
- max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
- }
-
- for (int i = 0; i < 3; i++)
- min[i] -= maxsize * (1 / scale - 1) / 2;
- maxsize *= 1 / scale;
-}
-
-Triangle *getNextTriangle()
-{
- if (curtri == input_mesh->tottri)
- return NULL;
-
- Triangle *t = new Triangle();
-
- unsigned int *tr = GET_TRI(input_mesh, curtri);
- veccopy(t->vt[0], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[0])));
- veccopy(t->vt[1], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[1])));
- veccopy(t->vt[2], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[2])));
-
- curtri++;
-
- /* remove triangle if it contains invalid coords */
- for (int i = 0; i < 3; i++) {
- const float *co = t->vt[i];
- if (isnan(co[0]) || isnan(co[1]) || isnan(co[2])) {
- delete t;
- return getNextTriangle();
- }
- }
-
- return t;
-}
-
-int getNextTriangle(int t[3])
-{
- if (curtri == input_mesh->tottri)
- return 0;
-
- unsigned int *tr = GET_TRI(input_mesh, curtri);
- t[0] = tr[0];
- t[1] = tr[1];
- t[2] = tr[2];
-
- curtri++;
-
- return 1;
-}
-
-int getNumTriangles()
-{
- return tottri;
-}
-
-int getNumVertices()
-{
- return input_mesh->totco;
-}
-
-float getBoundingBox(float origin[3])
-{
- veccopy(origin, min);
- return maxsize;
-}
-
-/* output */
-void getNextVertex(float /*v*/[3])
-{
- /* not used */
-}
-
-/* stubs */
-void printInfo() {
-}
-int getMemory() {
- return sizeof(DualConInputReader);
-}
+ (*(DualConLoop)(((char *)(_mesh)->mloop) + ((_n) * (_mesh)->loop_stride)))
+
+class DualConInputReader : public ModelReader {
+ private:
+ const DualConInput *input_mesh;
+ int tottri, curtri;
+ float min[3], max[3], maxsize;
+ float scale;
+
+ public:
+ DualConInputReader(const DualConInput *mesh, float _scale) : input_mesh(mesh), scale(_scale)
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ curtri = 0;
+ maxsize = 0;
+ tottri = input_mesh->tottri;
+
+ veccopy(min, input_mesh->min);
+ veccopy(max, input_mesh->max);
+
+ /* initialize maxsize */
+ for (int i = 0; i < 3; i++) {
+ float d = max[i] - min[i];
+ if (d > maxsize)
+ maxsize = d;
+ }
+
+ /* redo the bounds */
+ for (int i = 0; i < 3; i++) {
+ min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
+ max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
+ }
+
+ for (int i = 0; i < 3; i++)
+ min[i] -= maxsize * (1 / scale - 1) / 2;
+ maxsize *= 1 / scale;
+ }
+
+ Triangle *getNextTriangle()
+ {
+ if (curtri == input_mesh->tottri)
+ return NULL;
+
+ Triangle *t = new Triangle();
+
+ unsigned int *tr = GET_TRI(input_mesh, curtri);
+ veccopy(t->vt[0], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[0])));
+ veccopy(t->vt[1], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[1])));
+ veccopy(t->vt[2], GET_CO(input_mesh, GET_LOOP(input_mesh, tr[2])));
+
+ curtri++;
+
+ /* remove triangle if it contains invalid coords */
+ for (int i = 0; i < 3; i++) {
+ const float *co = t->vt[i];
+ if (isnan(co[0]) || isnan(co[1]) || isnan(co[2])) {
+ delete t;
+ return getNextTriangle();
+ }
+ }
+
+ return t;
+ }
+
+ int getNextTriangle(int t[3])
+ {
+ if (curtri == input_mesh->tottri)
+ return 0;
+
+ unsigned int *tr = GET_TRI(input_mesh, curtri);
+ t[0] = tr[0];
+ t[1] = tr[1];
+ t[2] = tr[2];
+
+ curtri++;
+
+ return 1;
+ }
+
+ int getNumTriangles()
+ {
+ return tottri;
+ }
+
+ int getNumVertices()
+ {
+ return input_mesh->totco;
+ }
+
+ float getBoundingBox(float origin[3])
+ {
+ veccopy(origin, min);
+ return maxsize;
+ }
+
+ /* output */
+ void getNextVertex(float /*v*/[3])
+ {
+ /* not used */
+ }
+
+ /* stubs */
+ void printInfo()
+ {
+ }
+ int getMemory()
+ {
+ return sizeof(DualConInputReader);
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:DualConInputReader")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:DualConInputReader")
#endif
-
};
void *dualcon(const DualConInput *input_mesh,
@@ -173,9 +171,8 @@ void *dualcon(const DualConInput *input_mesh,
float scale,
int depth)
{
- DualConInputReader r(input_mesh, scale);
- Octree o(&r, alloc_output, add_vert, add_quad,
- flags, mode, depth, threshold, hermite_num);
- o.scanConvert();
- return o.getOutputMesh();
+ DualConInputReader r(input_mesh, scale);
+ Octree o(&r, alloc_output, add_vert, add_quad, flags, mode, depth, threshold, hermite_num);
+ o.scanConvert();
+ return o.getOutputMesh();
}
diff --git a/intern/dualcon/intern/manifold_table.cpp b/intern/dualcon/intern/manifold_table.cpp
index baa6b82a91f..d08e1fd27c0 100644
--- a/intern/dualcon/intern/manifold_table.cpp
+++ b/intern/dualcon/intern/manifold_table.cpp
@@ -16,261 +16,3331 @@
#include "manifold_table.h"
-const ManifoldIndices manifold_table[256] = {
- {0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
- {3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
- {3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {2, {{0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 2}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
- {2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
- {3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
- {2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
- {2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}}},
- {2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {1, 1}}},
- {2, {{0, 0}, {1, 2}, {1, 1}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
- {2, {{2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
- {3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {1, 1}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {1, 1}}},
- {2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {1, 1}}},
- {2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {1, 1}, {2, 2}}},
- {3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}}},
- {4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 1}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}}},
- {2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 2}, {0, 0}, {2, 2}, {1, 1}}},
- {2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}}},
- {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
- {2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}, {2, 2}, {1, 1}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
- {2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}},
- {2, {{1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
- {2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
- {2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
- {2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
- {2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
- {3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}, {0, 0}, {3, 3}}},
- {2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
- {2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}},
- {3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
- {3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}}},
- {4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}, {1, 1}, {4, 4}}},
- {2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}},
- {2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}}},
- {2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
- {2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}}},
- {2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}}},
- {2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
- {2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {2, 2}}},
- {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}}},
- {2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 2}, {2, 2}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {2, {{2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 2}, {2, 2}, {0, 0}, {1, 1}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}},
- {2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
- {2, {{2, 2}, {1, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
- {2, {{2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
- {2, {{1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {1, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {2, 1}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}}},
- {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}},
- {2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {1, 2}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
- {0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}
-};
+const ManifoldIndices manifold_table[256] = {{0,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {3,
+ {{1, 1},
+ {2, 2},
+ {3, 3},
+ {0, 0},
+ {3, 3},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {3, 3},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {3,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {3, 3},
+ {1, 1},
+ {3, 3},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {3, 3},
+ {2, 2},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 2},
+ {2, 2},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1}}},
+ {3,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {3, 3},
+ {1, 1},
+ {3, 3},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {3, 3},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {1, 2},
+ {1, 1},
+ {2, 2},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 2}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {3,
+ {{1, 1},
+ {2, 2},
+ {3, 3},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {3, 3},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {3, 3}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {1, 1}}},
+ {2,
+ {{2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 2},
+ {1, 1},
+ {2, 2}}},
+ {3,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {0, 0},
+ {3, 3},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {3, 3},
+ {1, 1},
+ {2, 2}}},
+ {4,
+ {{1, 1},
+ {2, 2},
+ {3, 3},
+ {4, 4},
+ {1, 1},
+ {4, 4},
+ {3, 3},
+ {2, 2},
+ {1, 1},
+ {4, 4},
+ {2, 2},
+ {3, 3}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1}}},
+ {2,
+ {{1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 1}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2}}},
+ {3,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {3, 3},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {3, 3}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1}}},
+ {3,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {3, 3},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {3, 3},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {3, 3}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {3,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {3, 3},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {3, 3},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {3, 3}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {2, 2}}},
+ {4,
+ {{1, 1},
+ {2, 2},
+ {3, 3},
+ {4, 4},
+ {3, 3},
+ {2, 2},
+ {1, 1},
+ {4, 4},
+ {2, 2},
+ {3, 3},
+ {1, 1},
+ {4, 4}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {1, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {1, 2},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {1, 2},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {2, 2}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {2, 2}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 2},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {2,
+ {{2, 2},
+ {1, 1},
+ {1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {1, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 2},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 2}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1}}},
+ {2,
+ {{2, 2},
+ {1, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 1}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2}}},
+ {2,
+ {{2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 2},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {1, 2},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 2},
+ {2, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {1, 2},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {2, 2},
+ {1, 2},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {2, 2},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{2, 2},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {1, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {2, 2},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {2, 2},
+ {1, 1},
+ {1, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {2, 2},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {1, 2},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {2,
+ {{1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 2},
+ {2, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {2, 2},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{1, 2},
+ {0, 0},
+ {0, 0},
+ {2, 1},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {2,
+ {{0, 0},
+ {1, 2},
+ {2, 1},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {2, 2},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {1,
+ {{1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0}}},
+ {0,
+ {{0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}}}};
diff --git a/intern/dualcon/intern/manifold_table.h b/intern/dualcon/intern/manifold_table.h
index 2d60041312a..4f15afefa75 100644
--- a/intern/dualcon/intern/manifold_table.h
+++ b/intern/dualcon/intern/manifold_table.h
@@ -18,10 +18,10 @@
#define __MANIFOLD_TABLE_H__
typedef struct {
- int comps;
- int pairs[12][2];
+ int comps;
+ int pairs[12][2];
} ManifoldIndices;
extern const ManifoldIndices manifold_table[256];
-#endif /* __MANIFOLD_TABLE_H__ */
+#endif /* __MANIFOLD_TABLE_H__ */
diff --git a/intern/dualcon/intern/marching_cubes_table.cpp b/intern/dualcon/intern/marching_cubes_table.cpp
index 85b6813f483..5270be25033 100644
--- a/intern/dualcon/intern/marching_cubes_table.cpp
+++ b/intern/dualcon/intern/marching_cubes_table.cpp
@@ -18,531 +18,2574 @@
/* number of triangles in each configuration */
const int marching_cubes_numtri[TOTCONF] = {
- 0, 1, 1, 2, 1, 2, 4, 3, 1, 4, 2, 3, 2, 3, 3, 2, 1, 2, 4, 3, 4, 3, 5, 4,
- 6, 5, 5, 4, 5, 4, 4, 3, 1, 4, 2, 3, 6, 5, 5, 4, 4, 5, 3, 4, 5, 4, 4, 3,
- 2, 3, 3, 2, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 1, 4, 6, 5, 2, 3, 5, 4,
- 4, 5, 5, 4, 3, 4, 4, 3, 2, 3, 5, 4, 3, 2, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
- 4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2,
- 4, 3, 3, 2, 3, 2, 2, 1, 1, 6, 4, 5, 4, 5, 5, 4, 2, 5, 3, 4, 3, 4, 4, 3,
- 4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 2, 5, 3, 4, 5, 4, 4, 3,
- 3, 4, 2, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
- 2, 5, 5, 4, 3, 4, 4, 3, 3, 4, 4, 3, 2, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2,
- 4, 3, 3, 2, 3, 2, 2, 1, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
- 2, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0
-};
+ 0, 1, 1, 2, 1, 2, 4, 3, 1, 4, 2, 3, 2, 3, 3, 2, 1, 2, 4, 3, 4, 3, 5, 4, 6, 5, 5, 4, 5,
+ 4, 4, 3, 1, 4, 2, 3, 6, 5, 5, 4, 4, 5, 3, 4, 5, 4, 4, 3, 2, 3, 3, 2, 5, 4, 4, 3, 5, 4,
+ 4, 3, 4, 3, 3, 2, 1, 4, 6, 5, 2, 3, 5, 4, 4, 5, 5, 4, 3, 4, 4, 3, 2, 3, 5, 4, 3, 2, 4,
+ 3, 5, 4, 4, 3, 4, 3, 3, 2, 4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 3, 4, 4, 3,
+ 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 1, 6, 4, 5, 4, 5, 5, 4, 2, 5, 3, 4, 3, 4, 4, 3, 4,
+ 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 2, 5, 3, 4, 5, 4, 4, 3, 3, 4, 2, 3, 4, 3,
+ 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 2, 5, 5, 4, 3, 4, 4, 3, 3, 4, 4,
+ 3, 2, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 3, 4, 4, 3, 4, 3, 3, 2,
+ 4, 3, 3, 2, 3, 2, 2, 1, 2, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
/* table of triangles in each configuration */
-const int marching_cubes_tris[TOTCONF][MAX_TRIS][3] = {
- {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 8}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 1, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 1}, {4, 1, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 9, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 8, 9}, {0, 9, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 5, 9}, {1, 9, 2}, {1, 2, 4}, {1, 4, 8}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 1, 5}, {0, 5, 9}, {0, 9, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 3, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 8, 5}, {0, 5, 3}, {0, 3, 9}, {0, 9, 4}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 1, 3}, {8, 3, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 1}, {4, 1, 3}, {4, 3, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 5, 3}, {4, 3, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 8, 5}, {0, 5, 3}, {0, 3, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 1}, {4, 1, 3}, {4, 3, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 1, 3}, {0, 3, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 6, 10}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 4, 6}, {8, 6, 10}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 10, 1}, {6, 1, 5}, {6, 5, 8}, {6, 8, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 6, 10}, {4, 10, 1}, {4, 1, 5}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 0, 4}, {10, 4, 9}, {10, 9, 2}, {10, 2, 6}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 10, 8}, {6, 8, 9}, {6, 9, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {6, 10, 1}, {6, 1, 5}, {6, 5, 9}, {6, 9, 2},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 10, 1}, {6, 1, 5}, {6, 5, 9}, {6, 9, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 0, 5}, {0, 6, 9}, {9, 5, 0}, {6, 10, 3}, {5, 3, 10},
- {3, 9, 6}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 5}, {10, 5, 3}, {9, 4, 6}, {6, 10, 3}, {6, 3, 9},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 3}, {9, 8, 0}, {9, 0, 6}, {6, 10, 3}, {6, 3, 9},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 6, 10}, {4, 10, 1}, {4, 1, 3}, {4, 3, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 4, 5}, {3, 2, 6}, {3, 6, 10}, {10, 0, 5}, {10, 5, 3},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 10, 8}, {6, 8, 5}, {6, 5, 3}, {6, 3, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {6, 10, 1}, {6, 1, 3}, {6, 3, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 10, 1}, {6, 1, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 7, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 10}, {4, 10, 7}, {4, 7, 1}, {4, 1, 8}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 10, 7}, {8, 7, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 10}, {4, 10, 7}, {4, 7, 5}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 2, 4}, {10, 4, 1}, {7, 2, 10}, {1, 9, 7}, {1, 4, 9},
- {9, 2, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 8, 9}, {2, 0, 10}, {2, 10, 7}, {7, 1, 9}, {7, 9, 2},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 10}, {7, 5, 9}, {7, 9, 2}, {2, 4, 10}, {2, 10, 7},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 7}, {0, 7, 5}, {0, 5, 9}, {0, 9, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 7, 3}, {10, 3, 9}, {10, 9, 5}, {10, 5, 1}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {4, 0, 10}, {4, 10, 7}, {4, 7, 3}, {4, 3, 9},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 10, 7}, {8, 7, 3}, {8, 3, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 10}, {4, 10, 7}, {4, 7, 3}, {4, 3, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 5, 1}, {4, 1, 10}, {7, 3, 2}, {2, 4, 10}, {2, 10, 7},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {0, 10, 7}, {0, 7, 3}, {0, 3, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 10}, {4, 10, 7}, {4, 7, 3}, {4, 3, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 7}, {0, 7, 3}, {0, 3, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 6, 7}, {0, 7, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 4, 6}, {8, 6, 7}, {8, 7, 1}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 0, 6}, {8, 6, 7}, {8, 7, 5}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 6, 7}, {4, 7, 5}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 0, 4}, {1, 4, 9}, {2, 6, 7}, {7, 1, 9}, {7, 9, 2},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 7, 1}, {6, 1, 8}, {6, 8, 9}, {6, 9, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {6, 7, 5}, {6, 5, 9}, {6, 9, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 7, 5}, {6, 5, 9}, {6, 9, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 1, 0}, {6, 7, 3}, {6, 3, 9}, {9, 5, 0}, {9, 0, 6},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {4, 6, 7}, {4, 7, 3}, {4, 3, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 0, 6}, {8, 6, 7}, {8, 7, 3}, {8, 3, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 6, 7}, {4, 7, 3}, {4, 3, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 4, 5}, {0, 5, 1}, {6, 7, 3}, {6, 3, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {6, 7, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {6, 7, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 7, 3}, {6, 3, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 2, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 4, 2}, {8, 2, 11}, {8, 11, 6}, {8, 6, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 1, 6}, {6, 1, 11}, {11, 1, 5}, {2, 11, 5}, {2, 5, 8},
- {6, 2, 8}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 1}, {5, 4, 2}, {5, 2, 11}, {11, 6, 1}, {11, 1, 5},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 4, 9}, {6, 9, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 8}, {6, 8, 9}, {6, 9, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 4, 8}, {6, 8, 1}, {5, 9, 11}, {11, 6, 1}, {11, 1, 5},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 1}, {6, 1, 5}, {6, 5, 9}, {6, 9, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 2, 9}, {6, 9, 5}, {6, 5, 3}, {6, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 2, 9}, {6, 0, 8}, {6, 8, 5}, {6, 5, 3}, {6, 3, 11},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{2, 9, 8}, {1, 3, 11}, {1, 11, 6}, {6, 2, 8}, {6, 8, 1},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 2, 9}, {6, 0, 1}, {6, 1, 3}, {6, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 4, 5}, {6, 5, 3}, {6, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 8}, {6, 8, 5}, {6, 5, 3}, {6, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 4, 8}, {6, 8, 1}, {6, 1, 3}, {6, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 1}, {6, 1, 3}, {6, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 0, 2}, {10, 2, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 4}, {10, 4, 2}, {10, 2, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 0, 2}, {11, 10, 1}, {11, 1, 5}, {5, 8, 2}, {5, 2, 11},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 5}, {10, 5, 4}, {10, 4, 2}, {10, 2, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 0, 4}, {10, 4, 9}, {10, 9, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 9}, {10, 9, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {10, 1, 5}, {10, 5, 9}, {10, 9, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 5}, {10, 5, 9}, {10, 9, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 2, 9}, {0, 9, 5}, {3, 11, 10}, {10, 0, 5}, {10, 5, 3},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 2, 9}, {10, 8, 5}, {10, 5, 3}, {10, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 0, 2}, {8, 2, 9}, {10, 1, 3}, {10, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 2, 9}, {10, 1, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 0, 4}, {10, 4, 5}, {10, 5, 3}, {10, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 5}, {10, 5, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {10, 1, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 3}, {10, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 10, 6}, {1, 6, 2}, {1, 2, 11}, {1, 11, 7}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {7, 1, 8}, {7, 8, 4}, {7, 4, 2}, {7, 2, 11},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 10, 6}, {8, 6, 2}, {11, 7, 5}, {5, 8, 2}, {5, 2, 11},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {7, 5, 4}, {7, 4, 2}, {7, 2, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 6, 4}, {9, 11, 7}, {9, 7, 1}, {1, 10, 4}, {1, 4, 9},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {7, 1, 8}, {7, 8, 9}, {7, 9, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 10}, {4, 10, 6}, {7, 5, 9}, {7, 9, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {7, 5, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 1, 10}, {5, 10, 6}, {5, 6, 2}, {5, 2, 9}, {7, 3, 11},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {8, 5, 1}, {4, 2, 9}, {7, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 10, 6}, {8, 6, 2}, {8, 2, 9}, {7, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {4, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 6, 4}, {10, 4, 5}, {10, 5, 1}, {7, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {8, 5, 1}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 10}, {4, 10, 6}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 1, 0}, {7, 0, 2}, {7, 2, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 1, 8}, {7, 8, 4}, {7, 4, 2}, {7, 2, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 5, 8}, {7, 8, 0}, {7, 0, 2}, {7, 2, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 5, 4}, {7, 4, 2}, {7, 2, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 1, 0}, {7, 0, 4}, {7, 4, 9}, {7, 9, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 1, 8}, {7, 8, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {7, 5, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 5, 9}, {7, 9, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 1, 0}, {5, 0, 2}, {5, 2, 9}, {7, 3, 11}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {4, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 0, 2}, {8, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 2, 9}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 4, 5}, {0, 5, 1}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 3, 11}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 11, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 11, 0}, {7, 0, 8}, {0, 11, 4}, {8, 3, 7}, {11, 3, 4},
- {3, 8, 4}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 1, 7}, {8, 7, 11}, {8, 11, 3}, {8, 3, 5}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 1, 7}, {0, 7, 11}, {3, 5, 4}, {4, 0, 11}, {4, 11, 3},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 9, 3}, {4, 3, 7}, {4, 7, 11}, {4, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 9, 3}, {8, 3, 7}, {11, 2, 0}, {0, 8, 7}, {0, 7, 11},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 9, 3}, {4, 8, 1}, {4, 1, 7}, {4, 7, 11}, {4, 11, 2},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 9, 3}, {0, 1, 7}, {0, 7, 11}, {0, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 7, 11}, {5, 11, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 7}, {11, 9, 4}, {11, 4, 0}, {0, 8, 7}, {0, 7, 11},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 1, 7}, {8, 7, 11}, {8, 11, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 1}, {4, 1, 7}, {4, 7, 11}, {4, 11, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 5, 7}, {4, 7, 11}, {4, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 8, 5}, {0, 5, 7}, {0, 7, 11}, {0, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 1}, {4, 1, 7}, {4, 7, 11}, {4, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 1, 7}, {0, 7, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 6, 11}, {0, 11, 3}, {0, 3, 7}, {0, 7, 10}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 10, 8}, {4, 6, 11}, {4, 11, 3}, {3, 7, 8}, {3, 8, 4},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {5, 8, 0}, {5, 0, 6}, {5, 6, 11}, {5, 11, 3},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {5, 4, 6}, {5, 6, 11}, {5, 11, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 10, 0}, {7, 0, 4}, {7, 4, 9}, {7, 9, 3}, {6, 11, 2},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 10, 8}, {7, 8, 9}, {7, 9, 3}, {6, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {10, 1, 7}, {5, 9, 3}, {6, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {5, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 7, 10}, {5, 10, 0}, {6, 11, 9}, {9, 5, 0}, {9, 0, 6},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 5}, {10, 5, 7}, {4, 6, 11}, {4, 11, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {8, 0, 6}, {8, 6, 11}, {8, 11, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {4, 6, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 0, 4}, {10, 4, 5}, {10, 5, 7}, {6, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 5}, {10, 5, 7}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {10, 1, 7}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 10, 11}, {1, 11, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 11}, {3, 1, 8}, {3, 8, 4}, {4, 0, 11}, {4, 11, 3},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 8, 10}, {5, 10, 11}, {5, 11, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 4, 0}, {5, 0, 10}, {5, 10, 11}, {5, 11, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{9, 3, 1}, {10, 11, 2}, {10, 2, 4}, {4, 9, 1}, {4, 1, 10},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 8, 9}, {1, 9, 3}, {0, 10, 11}, {0, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 9, 3}, {4, 8, 10}, {4, 10, 11}, {4, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 9, 3}, {0, 10, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 1, 10}, {5, 10, 11}, {5, 11, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {4, 0, 10}, {4, 10, 11}, {4, 11, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 10, 11}, {8, 11, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 0, 10}, {4, 10, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 5, 1}, {4, 1, 10}, {4, 10, 11}, {4, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {0, 10, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 10}, {4, 10, 11}, {4, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 11}, {0, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 0, 6}, {1, 6, 11}, {1, 11, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 8, 4}, {1, 4, 6}, {1, 6, 11}, {1, 11, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 8, 0}, {5, 0, 6}, {5, 6, 11}, {5, 11, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 4, 6}, {5, 6, 11}, {5, 11, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 0, 4}, {1, 4, 9}, {1, 9, 3}, {6, 11, 2}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 8, 9}, {1, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {5, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 9, 3}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 1, 0}, {5, 0, 6}, {5, 6, 11}, {5, 11, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {4, 6, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 0, 6}, {8, 6, 11}, {8, 11, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 6, 11}, {4, 11, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 4, 5}, {0, 5, 1}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 11, 2}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 6, 2}, {7, 2, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 6, 0}, {7, 0, 8}, {4, 2, 3}, {3, 7, 8}, {3, 8, 4},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 7, 6}, {2, 3, 5}, {2, 5, 8}, {8, 1, 6}, {8, 6, 2},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 1}, {6, 1, 7}, {5, 4, 2}, {5, 2, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 6, 4}, {7, 4, 9}, {7, 9, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 6, 0}, {7, 0, 8}, {7, 8, 9}, {7, 9, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 4, 8}, {6, 8, 1}, {6, 1, 7}, {5, 9, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 1}, {6, 1, 7}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 7, 6}, {5, 6, 2}, {5, 2, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 8}, {6, 8, 5}, {6, 5, 7}, {4, 2, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 1, 7}, {8, 7, 6}, {8, 6, 2}, {8, 2, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 1}, {6, 1, 7}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 4, 5}, {6, 5, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 8}, {6, 8, 5}, {6, 5, 7}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 4, 8}, {6, 8, 1}, {6, 1, 7}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{6, 0, 1}, {6, 1, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 10, 0}, {7, 0, 2}, {7, 2, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 10, 8}, {7, 8, 4}, {7, 4, 2}, {7, 2, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {5, 8, 0}, {5, 0, 2}, {5, 2, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {5, 4, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 10, 0}, {7, 0, 4}, {7, 4, 9}, {7, 9, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{7, 10, 8}, {7, 8, 9}, {7, 9, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {10, 1, 7}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 7, 10}, {5, 10, 0}, {5, 0, 2}, {5, 2, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 5}, {10, 5, 7}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {8, 0, 2}, {8, 2, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 0, 4}, {10, 4, 5}, {10, 5, 7}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 8, 5}, {10, 5, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {10, 1, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 1, 7}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 10, 6}, {1, 6, 2}, {1, 2, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {1, 8, 4}, {1, 4, 2}, {1, 2, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 8, 10}, {5, 10, 6}, {5, 6, 2}, {5, 2, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {5, 4, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 10, 6}, {1, 6, 4}, {1, 4, 9}, {1, 9, 3}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {1, 8, 9}, {1, 9, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 10}, {4, 10, 6}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 1, 10}, {5, 10, 6}, {5, 6, 2}, {5, 2, 9}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {8, 5, 1}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 10, 6}, {8, 6, 2}, {8, 2, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{10, 6, 4}, {10, 4, 5}, {10, 5, 1}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {8, 5, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 10}, {4, 10, 6}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 10, 6}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 0, 2}, {1, 2, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 8, 4}, {1, 4, 2}, {1, 2, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 8, 0}, {5, 0, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 4, 2}, {5, 2, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 0, 4}, {1, 4, 9}, {1, 9, 3}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{1, 8, 9}, {1, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 9, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{5, 1, 0}, {5, 0, 2}, {5, 2, 9}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 0, 2}, {8, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 2, 9}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 4, 5}, {0, 5, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{8, 5, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{4, 8, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
- {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
- {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}
-};
+const int marching_cubes_tris[TOTCONF][MAX_TRIS][3] = {{{0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 8},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 1, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 1},
+ {4, 1, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 8, 9},
+ {0, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 5, 9},
+ {1, 9, 2},
+ {1, 2, 4},
+ {1, 4, 8},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 1, 5},
+ {0, 5, 9},
+ {0, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 8, 5},
+ {0, 5, 3},
+ {0, 3, 9},
+ {0, 9, 4},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 1, 3},
+ {8, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 1},
+ {4, 1, 3},
+ {4, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 5, 3},
+ {4, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 8, 5},
+ {0, 5, 3},
+ {0, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 1},
+ {4, 1, 3},
+ {4, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 1, 3},
+ {0, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 6, 10},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 4, 6},
+ {8, 6, 10},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 10, 1},
+ {6, 1, 5},
+ {6, 5, 8},
+ {6, 8, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 6, 10},
+ {4, 10, 1},
+ {4, 1, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 0, 4},
+ {10, 4, 9},
+ {10, 9, 2},
+ {10, 2, 6},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 10, 8},
+ {6, 8, 9},
+ {6, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {6, 10, 1},
+ {6, 1, 5},
+ {6, 5, 9},
+ {6, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 10, 1},
+ {6, 1, 5},
+ {6, 5, 9},
+ {6, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 0, 5},
+ {0, 6, 9},
+ {9, 5, 0},
+ {6, 10, 3},
+ {5, 3, 10},
+ {3, 9, 6},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 5},
+ {10, 5, 3},
+ {9, 4, 6},
+ {6, 10, 3},
+ {6, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 3},
+ {9, 8, 0},
+ {9, 0, 6},
+ {6, 10, 3},
+ {6, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 6, 10},
+ {4, 10, 1},
+ {4, 1, 3},
+ {4, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 4, 5},
+ {3, 2, 6},
+ {3, 6, 10},
+ {10, 0, 5},
+ {10, 5, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 10, 8},
+ {6, 8, 5},
+ {6, 5, 3},
+ {6, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {6, 10, 1},
+ {6, 1, 3},
+ {6, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 10, 1},
+ {6, 1, 3},
+ {6, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 7, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 10},
+ {4, 10, 7},
+ {4, 7, 1},
+ {4, 1, 8},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 10, 7},
+ {8, 7, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 10},
+ {4, 10, 7},
+ {4, 7, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 2, 4},
+ {10, 4, 1},
+ {7, 2, 10},
+ {1, 9, 7},
+ {1, 4, 9},
+ {9, 2, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 8, 9},
+ {2, 0, 10},
+ {2, 10, 7},
+ {7, 1, 9},
+ {7, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 10},
+ {7, 5, 9},
+ {7, 9, 2},
+ {2, 4, 10},
+ {2, 10, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 7},
+ {0, 7, 5},
+ {0, 5, 9},
+ {0, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 7, 3},
+ {10, 3, 9},
+ {10, 9, 5},
+ {10, 5, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {4, 0, 10},
+ {4, 10, 7},
+ {4, 7, 3},
+ {4, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 10, 7},
+ {8, 7, 3},
+ {8, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 10},
+ {4, 10, 7},
+ {4, 7, 3},
+ {4, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 5, 1},
+ {4, 1, 10},
+ {7, 3, 2},
+ {2, 4, 10},
+ {2, 10, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {0, 10, 7},
+ {0, 7, 3},
+ {0, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 10},
+ {4, 10, 7},
+ {4, 7, 3},
+ {4, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 7},
+ {0, 7, 3},
+ {0, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 6, 7},
+ {0, 7, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 4, 6},
+ {8, 6, 7},
+ {8, 7, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 0, 6},
+ {8, 6, 7},
+ {8, 7, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 6, 7},
+ {4, 7, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 0, 4},
+ {1, 4, 9},
+ {2, 6, 7},
+ {7, 1, 9},
+ {7, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 7, 1},
+ {6, 1, 8},
+ {6, 8, 9},
+ {6, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {6, 7, 5},
+ {6, 5, 9},
+ {6, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 7, 5},
+ {6, 5, 9},
+ {6, 9, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 1, 0},
+ {6, 7, 3},
+ {6, 3, 9},
+ {9, 5, 0},
+ {9, 0, 6},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {4, 6, 7},
+ {4, 7, 3},
+ {4, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 0, 6},
+ {8, 6, 7},
+ {8, 7, 3},
+ {8, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 6, 7},
+ {4, 7, 3},
+ {4, 3, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 4, 5},
+ {0, 5, 1},
+ {6, 7, 3},
+ {6, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {6, 7, 3},
+ {6, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {6, 7, 3},
+ {6, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 7, 3},
+ {6, 3, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 4, 2},
+ {8, 2, 11},
+ {8, 11, 6},
+ {8, 6, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 1, 6},
+ {6, 1, 11},
+ {11, 1, 5},
+ {2, 11, 5},
+ {2, 5, 8},
+ {6, 2, 8},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 1},
+ {5, 4, 2},
+ {5, 2, 11},
+ {11, 6, 1},
+ {11, 1, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 4, 9},
+ {6, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 8},
+ {6, 8, 9},
+ {6, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 4, 8},
+ {6, 8, 1},
+ {5, 9, 11},
+ {11, 6, 1},
+ {11, 1, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 1},
+ {6, 1, 5},
+ {6, 5, 9},
+ {6, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 2, 9},
+ {6, 9, 5},
+ {6, 5, 3},
+ {6, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 2, 9},
+ {6, 0, 8},
+ {6, 8, 5},
+ {6, 5, 3},
+ {6, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{2, 9, 8},
+ {1, 3, 11},
+ {1, 11, 6},
+ {6, 2, 8},
+ {6, 8, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 2, 9},
+ {6, 0, 1},
+ {6, 1, 3},
+ {6, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 4, 5},
+ {6, 5, 3},
+ {6, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 8},
+ {6, 8, 5},
+ {6, 5, 3},
+ {6, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 4, 8},
+ {6, 8, 1},
+ {6, 1, 3},
+ {6, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 1},
+ {6, 1, 3},
+ {6, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 0, 2},
+ {10, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 4},
+ {10, 4, 2},
+ {10, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 0, 2},
+ {11, 10, 1},
+ {11, 1, 5},
+ {5, 8, 2},
+ {5, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 5},
+ {10, 5, 4},
+ {10, 4, 2},
+ {10, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 0, 4},
+ {10, 4, 9},
+ {10, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 9},
+ {10, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {10, 1, 5},
+ {10, 5, 9},
+ {10, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 5},
+ {10, 5, 9},
+ {10, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 2, 9},
+ {0, 9, 5},
+ {3, 11, 10},
+ {10, 0, 5},
+ {10, 5, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 2, 9},
+ {10, 8, 5},
+ {10, 5, 3},
+ {10, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 0, 2},
+ {8, 2, 9},
+ {10, 1, 3},
+ {10, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 2, 9},
+ {10, 1, 3},
+ {10, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 0, 4},
+ {10, 4, 5},
+ {10, 5, 3},
+ {10, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 5},
+ {10, 5, 3},
+ {10, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {10, 1, 3},
+ {10, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 3},
+ {10, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 10, 6},
+ {1, 6, 2},
+ {1, 2, 11},
+ {1, 11, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {7, 1, 8},
+ {7, 8, 4},
+ {7, 4, 2},
+ {7, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 10, 6},
+ {8, 6, 2},
+ {11, 7, 5},
+ {5, 8, 2},
+ {5, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {7, 5, 4},
+ {7, 4, 2},
+ {7, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 6, 4},
+ {9, 11, 7},
+ {9, 7, 1},
+ {1, 10, 4},
+ {1, 4, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {7, 1, 8},
+ {7, 8, 9},
+ {7, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 10},
+ {4, 10, 6},
+ {7, 5, 9},
+ {7, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {7, 5, 9},
+ {7, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 1, 10},
+ {5, 10, 6},
+ {5, 6, 2},
+ {5, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {8, 5, 1},
+ {4, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 10, 6},
+ {8, 6, 2},
+ {8, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {4, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 6, 4},
+ {10, 4, 5},
+ {10, 5, 1},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {8, 5, 1},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 10},
+ {4, 10, 6},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 1, 0},
+ {7, 0, 2},
+ {7, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 1, 8},
+ {7, 8, 4},
+ {7, 4, 2},
+ {7, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 5, 8},
+ {7, 8, 0},
+ {7, 0, 2},
+ {7, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 5, 4},
+ {7, 4, 2},
+ {7, 2, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 1, 0},
+ {7, 0, 4},
+ {7, 4, 9},
+ {7, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 1, 8},
+ {7, 8, 9},
+ {7, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {7, 5, 9},
+ {7, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 5, 9},
+ {7, 9, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 1, 0},
+ {5, 0, 2},
+ {5, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {4, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 0, 2},
+ {8, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 2, 9},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 4, 5},
+ {0, 5, 1},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 3, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 11, 0},
+ {7, 0, 8},
+ {0, 11, 4},
+ {8, 3, 7},
+ {11, 3, 4},
+ {3, 8, 4},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 1, 7},
+ {8, 7, 11},
+ {8, 11, 3},
+ {8, 3, 5},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 1, 7},
+ {0, 7, 11},
+ {3, 5, 4},
+ {4, 0, 11},
+ {4, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 9, 3},
+ {4, 3, 7},
+ {4, 7, 11},
+ {4, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 9, 3},
+ {8, 3, 7},
+ {11, 2, 0},
+ {0, 8, 7},
+ {0, 7, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 9, 3},
+ {4, 8, 1},
+ {4, 1, 7},
+ {4, 7, 11},
+ {4, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 9, 3},
+ {0, 1, 7},
+ {0, 7, 11},
+ {0, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 7, 11},
+ {5, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 7},
+ {11, 9, 4},
+ {11, 4, 0},
+ {0, 8, 7},
+ {0, 7, 11},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 1, 7},
+ {8, 7, 11},
+ {8, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 1},
+ {4, 1, 7},
+ {4, 7, 11},
+ {4, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 5, 7},
+ {4, 7, 11},
+ {4, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 8, 5},
+ {0, 5, 7},
+ {0, 7, 11},
+ {0, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 1},
+ {4, 1, 7},
+ {4, 7, 11},
+ {4, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 1, 7},
+ {0, 7, 11},
+ {0, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 6, 11},
+ {0, 11, 3},
+ {0, 3, 7},
+ {0, 7, 10},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 10, 8},
+ {4, 6, 11},
+ {4, 11, 3},
+ {3, 7, 8},
+ {3, 8, 4},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {5, 8, 0},
+ {5, 0, 6},
+ {5, 6, 11},
+ {5, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {5, 4, 6},
+ {5, 6, 11},
+ {5, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 10, 0},
+ {7, 0, 4},
+ {7, 4, 9},
+ {7, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 10, 8},
+ {7, 8, 9},
+ {7, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {10, 1, 7},
+ {5, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {5, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 7, 10},
+ {5, 10, 0},
+ {6, 11, 9},
+ {9, 5, 0},
+ {9, 0, 6},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 5},
+ {10, 5, 7},
+ {4, 6, 11},
+ {4, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {8, 0, 6},
+ {8, 6, 11},
+ {8, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {4, 6, 11},
+ {4, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 0, 4},
+ {10, 4, 5},
+ {10, 5, 7},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 5},
+ {10, 5, 7},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {10, 1, 7},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 10, 11},
+ {1, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 11},
+ {3, 1, 8},
+ {3, 8, 4},
+ {4, 0, 11},
+ {4, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 8, 10},
+ {5, 10, 11},
+ {5, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 4, 0},
+ {5, 0, 10},
+ {5, 10, 11},
+ {5, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{9, 3, 1},
+ {10, 11, 2},
+ {10, 2, 4},
+ {4, 9, 1},
+ {4, 1, 10},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 8, 9},
+ {1, 9, 3},
+ {0, 10, 11},
+ {0, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 9, 3},
+ {4, 8, 10},
+ {4, 10, 11},
+ {4, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 9, 3},
+ {0, 10, 11},
+ {0, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 1, 10},
+ {5, 10, 11},
+ {5, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {4, 0, 10},
+ {4, 10, 11},
+ {4, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 10, 11},
+ {8, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 0, 10},
+ {4, 10, 11},
+ {4, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 5, 1},
+ {4, 1, 10},
+ {4, 10, 11},
+ {4, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {0, 10, 11},
+ {0, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 10},
+ {4, 10, 11},
+ {4, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 11},
+ {0, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 0, 6},
+ {1, 6, 11},
+ {1, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 8, 4},
+ {1, 4, 6},
+ {1, 6, 11},
+ {1, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 8, 0},
+ {5, 0, 6},
+ {5, 6, 11},
+ {5, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 4, 6},
+ {5, 6, 11},
+ {5, 11, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 0, 4},
+ {1, 4, 9},
+ {1, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 8, 9},
+ {1, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {5, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 9, 3},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 1, 0},
+ {5, 0, 6},
+ {5, 6, 11},
+ {5, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {4, 6, 11},
+ {4, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 0, 6},
+ {8, 6, 11},
+ {8, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 6, 11},
+ {4, 11, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 4, 5},
+ {0, 5, 1},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 11, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 6, 2},
+ {7, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 6, 0},
+ {7, 0, 8},
+ {4, 2, 3},
+ {3, 7, 8},
+ {3, 8, 4},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 7, 6},
+ {2, 3, 5},
+ {2, 5, 8},
+ {8, 1, 6},
+ {8, 6, 2},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 1},
+ {6, 1, 7},
+ {5, 4, 2},
+ {5, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 6, 4},
+ {7, 4, 9},
+ {7, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 6, 0},
+ {7, 0, 8},
+ {7, 8, 9},
+ {7, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 4, 8},
+ {6, 8, 1},
+ {6, 1, 7},
+ {5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 1},
+ {6, 1, 7},
+ {5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 7, 6},
+ {5, 6, 2},
+ {5, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 8},
+ {6, 8, 5},
+ {6, 5, 7},
+ {4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 1, 7},
+ {8, 7, 6},
+ {8, 6, 2},
+ {8, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 1},
+ {6, 1, 7},
+ {4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 4, 5},
+ {6, 5, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 8},
+ {6, 8, 5},
+ {6, 5, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 4, 8},
+ {6, 8, 1},
+ {6, 1, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{6, 0, 1},
+ {6, 1, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 10, 0},
+ {7, 0, 2},
+ {7, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 10, 8},
+ {7, 8, 4},
+ {7, 4, 2},
+ {7, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {5, 8, 0},
+ {5, 0, 2},
+ {5, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {5, 4, 2},
+ {5, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 10, 0},
+ {7, 0, 4},
+ {7, 4, 9},
+ {7, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{7, 10, 8},
+ {7, 8, 9},
+ {7, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {10, 1, 7},
+ {5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 7, 10},
+ {5, 10, 0},
+ {5, 0, 2},
+ {5, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 5},
+ {10, 5, 7},
+ {4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {8, 0, 2},
+ {8, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 0, 4},
+ {10, 4, 5},
+ {10, 5, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 8, 5},
+ {10, 5, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {10, 1, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 1, 7},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 10, 6},
+ {1, 6, 2},
+ {1, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {1, 8, 4},
+ {1, 4, 2},
+ {1, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 8, 10},
+ {5, 10, 6},
+ {5, 6, 2},
+ {5, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {5, 4, 2},
+ {5, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 10, 6},
+ {1, 6, 4},
+ {1, 4, 9},
+ {1, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {1, 8, 9},
+ {1, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 10},
+ {4, 10, 6},
+ {5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 1, 10},
+ {5, 10, 6},
+ {5, 6, 2},
+ {5, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {8, 5, 1},
+ {4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 10, 6},
+ {8, 6, 2},
+ {8, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{10, 6, 4},
+ {10, 4, 5},
+ {10, 5, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {8, 5, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 10},
+ {4, 10, 6},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 10, 6},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 0, 2},
+ {1, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 8, 4},
+ {1, 4, 2},
+ {1, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 8, 0},
+ {5, 0, 2},
+ {5, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 4, 2},
+ {5, 2, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 0, 4},
+ {1, 4, 9},
+ {1, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{1, 8, 9},
+ {1, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 9, 3},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{5, 1, 0},
+ {5, 0, 2},
+ {5, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 0, 2},
+ {8, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 2, 9},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 4, 5},
+ {0, 5, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{8, 5, 1},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{4, 8, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}},
+ {{0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}}};
diff --git a/intern/dualcon/intern/octree.cpp b/intern/dualcon/intern/octree.cpp
index 878cd2971de..46783176fc1 100644
--- a/intern/dualcon/intern/octree.cpp
+++ b/intern/dualcon/intern/octree.cpp
@@ -34,2063 +34,2085 @@
#if DC_DEBUG
/* enable debug printfs */
-#define dc_printf printf
+# define dc_printf printf
#else
/* disable debug printfs */
-#define dc_printf(...) do {} while (0)
+# define dc_printf(...) \
+ do { \
+ } while (0)
#endif
Octree::Octree(ModelReader *mr,
DualConAllocOutput alloc_output_func,
DualConAddVert add_vert_func,
DualConAddQuad add_quad_func,
- DualConFlags flags, DualConMode dualcon_mode, int depth,
- float threshold, float sharpness)
- : use_flood_fill(flags & DUALCON_FLOOD_FILL),
- /* note on `use_manifold':
-
- After playing around with this option, the only case I could
- find where this option gives different results is on
- relatively thin corners. Sometimes along these corners two
- vertices from separate sides will be placed in the same
- position, so hole gets filled with a 5-sided face, where two
- of those vertices are in the same 3D location. If
- `use_manifold' is disabled, then the modifier doesn't
- generate two separate vertices so the results end up as all
- quads.
-
- Since the results are just as good with all quads, there
- doesn't seem any reason to allow this to be toggled in
- Blender. -nicholasbishop
- */
- use_manifold(false),
- hermite_num(sharpness),
- mode(dualcon_mode),
- alloc_output(alloc_output_func),
- add_vert(add_vert_func),
- add_quad(add_quad_func)
+ DualConFlags flags,
+ DualConMode dualcon_mode,
+ int depth,
+ float threshold,
+ float sharpness)
+ : use_flood_fill(flags & DUALCON_FLOOD_FILL),
+ /* note on `use_manifold':
+
+ After playing around with this option, the only case I could
+ find where this option gives different results is on
+ relatively thin corners. Sometimes along these corners two
+ vertices from separate sides will be placed in the same
+ position, so hole gets filled with a 5-sided face, where two
+ of those vertices are in the same 3D location. If
+ `use_manifold' is disabled, then the modifier doesn't
+ generate two separate vertices so the results end up as all
+ quads.
+
+ Since the results are just as good with all quads, there
+ doesn't seem any reason to allow this to be toggled in
+ Blender. -nicholasbishop
+ */
+ use_manifold(false),
+ hermite_num(sharpness),
+ mode(dualcon_mode),
+ alloc_output(alloc_output_func),
+ add_vert(add_vert_func),
+ add_quad(add_quad_func)
{
- thresh = threshold;
- reader = mr;
- dimen = 1 << GRID_DIMENSION;
- range = reader->getBoundingBox(origin);
- nodeCount = nodeSpace = 0;
- maxDepth = depth;
- mindimen = (dimen >> maxDepth);
- minshift = (GRID_DIMENSION - maxDepth);
- buildTable();
-
- maxTrianglePerCell = 0;
-
- // Initialize memory
+ thresh = threshold;
+ reader = mr;
+ dimen = 1 << GRID_DIMENSION;
+ range = reader->getBoundingBox(origin);
+ nodeCount = nodeSpace = 0;
+ maxDepth = depth;
+ mindimen = (dimen >> maxDepth);
+ minshift = (GRID_DIMENSION - maxDepth);
+ buildTable();
+
+ maxTrianglePerCell = 0;
+
+ // Initialize memory
#ifdef IN_VERBOSE_MODE
- dc_printf("Range: %f origin: %f, %f,%f \n", range, origin[0], origin[1], origin[2]);
- dc_printf("Initialize memory...\n");
+ dc_printf("Range: %f origin: %f, %f,%f \n", range, origin[0], origin[1], origin[2]);
+ dc_printf("Initialize memory...\n");
#endif
- initMemory();
- root = (Node *)createInternal(0);
+ initMemory();
+ root = (Node *)createInternal(0);
- // Read MC table
+ // Read MC table
#ifdef IN_VERBOSE_MODE
- dc_printf("Reading contour table...\n");
+ dc_printf("Reading contour table...\n");
#endif
- cubes = new Cubes();
-
+ cubes = new Cubes();
}
Octree::~Octree()
{
- delete cubes;
- freeMemory();
+ delete cubes;
+ freeMemory();
}
void Octree::scanConvert()
{
- // Scan triangles
+ // Scan triangles
#if DC_DEBUG
- clock_t start, finish;
- start = clock();
+ clock_t start, finish;
+ start = clock();
#endif
- addAllTriangles();
- resetMinimalEdges();
- preparePrimalEdgesMask(&root->internal);
+ addAllTriangles();
+ resetMinimalEdges();
+ preparePrimalEdgesMask(&root->internal);
#if DC_DEBUG
- finish = clock();
- dc_printf("Time taken: %f seconds \n",
- (double)(finish - start) / CLOCKS_PER_SEC);
+ finish = clock();
+ dc_printf("Time taken: %f seconds \n",
+ (double)(finish - start) / CLOCKS_PER_SEC);
#endif
- // Generate signs
- // Find holes
+ // Generate signs
+ // Find holes
#if DC_DEBUG
- dc_printf("Patching...\n");
- start = clock();
+ dc_printf("Patching...\n");
+ start = clock();
#endif
- trace();
+ trace();
#if DC_DEBUG
- finish = clock();
- dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
-#ifdef IN_VERBOSE_MODE
- dc_printf("Holes: %d Average Length: %f Max Length: %d \n", numRings, (float)totRingLengths / (float) numRings, maxRingLength);
-#endif
+ finish = clock();
+ dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
+# ifdef IN_VERBOSE_MODE
+ dc_printf("Holes: %d Average Length: %f Max Length: %d \n",
+ numRings,
+ (float)totRingLengths / (float)numRings,
+ maxRingLength);
+# endif
#endif
- // Check again
- int tnumRings = numRings;
- trace();
+ // Check again
+ int tnumRings = numRings;
+ trace();
#ifdef IN_VERBOSE_MODE
- dc_printf("Holes after patching: %d \n", numRings);
+ dc_printf("Holes after patching: %d \n", numRings);
#endif
- numRings = tnumRings;
+ numRings = tnumRings;
#if DC_DEBUG
- dc_printf("Building signs...\n");
- start = clock();
+ dc_printf("Building signs...\n");
+ start = clock();
#endif
- buildSigns();
+ buildSigns();
#if DC_DEBUG
- finish = clock();
- dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
+ finish = clock();
+ dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
#endif
- if (use_flood_fill) {
- /*
- start = clock();
- floodFill();
- // Check again
- tnumRings = numRings;
- trace();
- dc_printf("Holes after filling: %d \n", numRings);
- numRings = tnumRings;
- buildSigns();
- finish = clock();
- dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
- */
+ if (use_flood_fill) {
+ /*
+ start = clock();
+ floodFill();
+ // Check again
+ tnumRings = numRings;
+ trace();
+ dc_printf("Holes after filling: %d \n", numRings);
+ numRings = tnumRings;
+ buildSigns();
+ finish = clock();
+ dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
+ */
#if DC_DEBUG
- start = clock();
- dc_printf("Removing components...\n");
+ start = clock();
+ dc_printf("Removing components...\n");
#endif
- floodFill();
- buildSigns();
- // dc_printf("Checking...\n");
- // floodFill();
+ floodFill();
+ buildSigns();
+ // dc_printf("Checking...\n");
+ // floodFill();
#if DC_DEBUG
- finish = clock();
- dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
+ finish = clock();
+ dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
#endif
- }
+ }
- // Output
+ // Output
#if DC_DEBUG
- start = clock();
+ start = clock();
#endif
- writeOut();
+ writeOut();
#if DC_DEBUG
- finish = clock();
+ finish = clock();
#endif
- // dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
+ // dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC);
- // Print info
+ // Print info
#ifdef IN_VERBOSE_MODE
- printMemUsage();
+ printMemUsage();
#endif
}
void Octree::initMemory()
{
- leafalloc[0] = new MemoryAllocator<sizeof(LeafNode)>();
- leafalloc[1] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) *EDGE_FLOATS>();
- leafalloc[2] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) *EDGE_FLOATS * 2>();
- leafalloc[3] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) *EDGE_FLOATS * 3>();
-
- alloc[0] = new MemoryAllocator<sizeof(InternalNode)>();
- alloc[1] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *)>();
- alloc[2] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 2>();
- alloc[3] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 3>();
- alloc[4] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 4>();
- alloc[5] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 5>();
- alloc[6] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 6>();
- alloc[7] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 7>();
- alloc[8] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 8>();
+ leafalloc[0] = new MemoryAllocator<sizeof(LeafNode)>();
+ leafalloc[1] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS>();
+ leafalloc[2] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS * 2>();
+ leafalloc[3] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS * 3>();
+
+ alloc[0] = new MemoryAllocator<sizeof(InternalNode)>();
+ alloc[1] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *)>();
+ alloc[2] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 2>();
+ alloc[3] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 3>();
+ alloc[4] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 4>();
+ alloc[5] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 5>();
+ alloc[6] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 6>();
+ alloc[7] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 7>();
+ alloc[8] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node *) * 8>();
}
void Octree::freeMemory()
{
- for (int i = 0; i < 9; i++) {
- alloc[i]->destroy();
- delete alloc[i];
- }
-
- for (int i = 0; i < 4; i++) {
- leafalloc[i]->destroy();
- delete leafalloc[i];
- }
+ for (int i = 0; i < 9; i++) {
+ alloc[i]->destroy();
+ delete alloc[i];
+ }
+
+ for (int i = 0; i < 4; i++) {
+ leafalloc[i]->destroy();
+ delete leafalloc[i];
+ }
}
void Octree::printMemUsage()
{
- int totalbytes = 0;
- dc_printf("********* Internal nodes: \n");
- for (int i = 0; i < 9; i++) {
- alloc[i]->printInfo();
-
- totalbytes += alloc[i]->getAll() * alloc[i]->getBytes();
- }
- dc_printf("********* Leaf nodes: \n");
- int totalLeafs = 0;
- for (int i = 0; i < 4; i++) {
- leafalloc[i]->printInfo();
-
- totalbytes += leafalloc[i]->getAll() * leafalloc[i]->getBytes();
- totalLeafs += leafalloc[i]->getAllocated();
- }
-
- dc_printf("Total allocated bytes on disk: %d \n", totalbytes);
- dc_printf("Total leaf nodes: %d\n", totalLeafs);
+ int totalbytes = 0;
+ dc_printf("********* Internal nodes: \n");
+ for (int i = 0; i < 9; i++) {
+ alloc[i]->printInfo();
+
+ totalbytes += alloc[i]->getAll() * alloc[i]->getBytes();
+ }
+ dc_printf("********* Leaf nodes: \n");
+ int totalLeafs = 0;
+ for (int i = 0; i < 4; i++) {
+ leafalloc[i]->printInfo();
+
+ totalbytes += leafalloc[i]->getAll() * leafalloc[i]->getBytes();
+ totalLeafs += leafalloc[i]->getAllocated();
+ }
+
+ dc_printf("Total allocated bytes on disk: %d \n", totalbytes);
+ dc_printf("Total leaf nodes: %d\n", totalLeafs);
}
void Octree::resetMinimalEdges()
{
- cellProcParity(root, 0, maxDepth);
+ cellProcParity(root, 0, maxDepth);
}
void Octree::addAllTriangles()
{
- Triangle *trian;
- int count = 0;
+ Triangle *trian;
+ int count = 0;
#if DC_DEBUG
- int total = reader->getNumTriangles();
- int unitcount = 1000;
- dc_printf("\nScan converting to depth %d...\n", maxDepth);
+ int total = reader->getNumTriangles();
+ int unitcount = 1000;
+ dc_printf("\nScan converting to depth %d...\n", maxDepth);
#endif
- srand(0);
+ srand(0);
- while ((trian = reader->getNextTriangle()) != NULL) {
- // Drop triangles
- {
- addTriangle(trian, count);
- }
- delete trian;
+ while ((trian = reader->getNextTriangle()) != NULL) {
+ // Drop triangles
+ {
+ addTriangle(trian, count);
+ }
+ delete trian;
- count++;
+ count++;
#if DC_DEBUG
- if (count % unitcount == 0) {
- putchar(13);
-
- switch ((count / unitcount) % 4) {
- case 0: dc_printf("-");
- break;
- case 1: dc_printf("/");
- break;
- case 2: dc_printf("|");
- break;
- case 3: dc_printf("\\");
- break;
- }
-
- float percent = (float) count / total;
-
- /*
- int totbars = 50;
- int bars =(int)(percent * totbars);
- for(int i = 0; i < bars; i ++) {
- putchar(219);
- }
- for(i = bars; i < totbars; i ++) {
- putchar(176);
- }
- */
-
- dc_printf(" %d triangles: ", count);
- dc_printf(" %f%% complete.", 100 * percent);
- }
+ if (count % unitcount == 0) {
+ putchar(13);
+
+ switch ((count / unitcount) % 4) {
+ case 0:
+ dc_printf("-");
+ break;
+ case 1:
+ dc_printf("/");
+ break;
+ case 2:
+ dc_printf("|");
+ break;
+ case 3:
+ dc_printf("\\");
+ break;
+ }
+
+ float percent = (float)count / total;
+
+ /*
+ int totbars = 50;
+ int bars =(int)(percent * totbars);
+ for(int i = 0; i < bars; i ++) {
+ putchar(219);
+ }
+ for(i = bars; i < totbars; i ++) {
+ putchar(176);
+ }
+ */
+
+ dc_printf(" %d triangles: ", count);
+ dc_printf(" %f%% complete.", 100 * percent);
+ }
#endif
-
- }
- putchar(13);
+ }
+ putchar(13);
}
/* Prepare a triangle for insertion into the octree; call the other
addTriangle() to (recursively) build the octree */
void Octree::addTriangle(Triangle *trian, int triind)
{
- int i, j;
-
- /* Project the triangle's coordinates into the grid */
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++)
- trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
- }
-
- /* Generate projections */
- int64_t cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
- int64_t trig[3][3];
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++)
- trig[i][j] = (int64_t)(trian->vt[i][j]);
- }
-
- /* Add triangle to the octree */
- int64_t errorvec = (int64_t)(0);
- CubeTriangleIsect *proj = new CubeTriangleIsect(cube, trig, errorvec, triind);
- root = (Node *)addTriangle(&root->internal, proj, maxDepth);
-
- delete proj->inherit;
- delete proj;
+ int i, j;
+
+ /* Project the triangle's coordinates into the grid */
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++)
+ trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
+ }
+
+ /* Generate projections */
+ int64_t cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
+ int64_t trig[3][3];
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++)
+ trig[i][j] = (int64_t)(trian->vt[i][j]);
+ }
+
+ /* Add triangle to the octree */
+ int64_t errorvec = (int64_t)(0);
+ CubeTriangleIsect *proj = new CubeTriangleIsect(cube, trig, errorvec, triind);
+ root = (Node *)addTriangle(&root->internal, proj, maxDepth);
+
+ delete proj->inherit;
+ delete proj;
}
#if 0
static void print_depth(int height, int maxDepth)
{
- for (int i = 0; i < maxDepth - height; i++)
- printf(" ");
+ for (int i = 0; i < maxDepth - height; i++)
+ printf(" ");
}
#endif
InternalNode *Octree::addTriangle(InternalNode *node, CubeTriangleIsect *p, int height)
{
- int i;
- const int vertdiff[8][3] = {
- {0, 0, 0},
- {0, 0, 1},
- {0, 1, -1},
- {0, 0, 1},
- {1, -1, -1},
- {0, 0, 1},
- {0, 1, -1},
- {0, 0, 1}};
- unsigned char boxmask = p->getBoxMask();
- CubeTriangleIsect *subp = new CubeTriangleIsect(p);
-
- int count = 0;
- int tempdiff[3] = {0, 0, 0};
-
- /* Check triangle against each of the input node's children */
- for (i = 0; i < 8; i++) {
- tempdiff[0] += vertdiff[i][0];
- tempdiff[1] += vertdiff[i][1];
- tempdiff[2] += vertdiff[i][2];
-
- /* Quick pruning using bounding box */
- if (boxmask & (1 << i)) {
- subp->shift(tempdiff);
- tempdiff[0] = tempdiff[1] = tempdiff[2] = 0;
-
- /* Pruning using intersection test */
- if (subp->isIntersecting()) {
- if (!node->has_child(i)) {
- if (height == 1)
- node = addLeafChild(node, i, count, createLeaf(0));
- else
- node = addInternalChild(node, i, count, createInternal(0));
- }
- Node *chd = node->get_child(count);
-
- if (node->is_child_leaf(i))
- node->set_child(count, (Node *)updateCell(&chd->leaf, subp));
- else
- node->set_child(count, (Node *)addTriangle(&chd->internal, subp, height - 1));
- }
- }
-
- if (node->has_child(i))
- count++;
- }
-
- delete subp;
-
- return node;
+ int i;
+ const int vertdiff[8][3] = {
+ {0, 0, 0}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}, {1, -1, -1}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}};
+ unsigned char boxmask = p->getBoxMask();
+ CubeTriangleIsect *subp = new CubeTriangleIsect(p);
+
+ int count = 0;
+ int tempdiff[3] = {0, 0, 0};
+
+ /* Check triangle against each of the input node's children */
+ for (i = 0; i < 8; i++) {
+ tempdiff[0] += vertdiff[i][0];
+ tempdiff[1] += vertdiff[i][1];
+ tempdiff[2] += vertdiff[i][2];
+
+ /* Quick pruning using bounding box */
+ if (boxmask & (1 << i)) {
+ subp->shift(tempdiff);
+ tempdiff[0] = tempdiff[1] = tempdiff[2] = 0;
+
+ /* Pruning using intersection test */
+ if (subp->isIntersecting()) {
+ if (!node->has_child(i)) {
+ if (height == 1)
+ node = addLeafChild(node, i, count, createLeaf(0));
+ else
+ node = addInternalChild(node, i, count, createInternal(0));
+ }
+ Node *chd = node->get_child(count);
+
+ if (node->is_child_leaf(i))
+ node->set_child(count, (Node *)updateCell(&chd->leaf, subp));
+ else
+ node->set_child(count, (Node *)addTriangle(&chd->internal, subp, height - 1));
+ }
+ }
+
+ if (node->has_child(i))
+ count++;
+ }
+
+ delete subp;
+
+ return node;
}
LeafNode *Octree::updateCell(LeafNode *node, CubeTriangleIsect *p)
{
- int i;
-
- // Edge connectivity
- int mask[3] = {0, 4, 8 };
- int oldc = 0, newc = 0;
- float offs[3];
- float a[3], b[3], c[3];
-
- for (i = 0; i < 3; i++) {
- if (!getEdgeParity(node, mask[i])) {
- if (p->isIntersectingPrimary(i)) {
- // actualQuads ++;
- setEdge(node, mask[i]);
- offs[newc] = p->getIntersectionPrimary(i);
- a[newc] = (float) p->inherit->norm[0];
- b[newc] = (float) p->inherit->norm[1];
- c[newc] = (float) p->inherit->norm[2];
- newc++;
- }
- }
- else {
- offs[newc] = getEdgeOffsetNormal(node, oldc, a[newc], b[newc], c[newc]);
-
- oldc++;
- newc++;
- }
- }
-
- if (newc > oldc) {
- // New offsets added, update this node
- node = updateEdgeOffsetsNormals(node, oldc, newc, offs, a, b, c);
- }
-
- return node;
+ int i;
+
+ // Edge connectivity
+ int mask[3] = {0, 4, 8};
+ int oldc = 0, newc = 0;
+ float offs[3];
+ float a[3], b[3], c[3];
+
+ for (i = 0; i < 3; i++) {
+ if (!getEdgeParity(node, mask[i])) {
+ if (p->isIntersectingPrimary(i)) {
+ // actualQuads ++;
+ setEdge(node, mask[i]);
+ offs[newc] = p->getIntersectionPrimary(i);
+ a[newc] = (float)p->inherit->norm[0];
+ b[newc] = (float)p->inherit->norm[1];
+ c[newc] = (float)p->inherit->norm[2];
+ newc++;
+ }
+ }
+ else {
+ offs[newc] = getEdgeOffsetNormal(node, oldc, a[newc], b[newc], c[newc]);
+
+ oldc++;
+ newc++;
+ }
+ }
+
+ if (newc > oldc) {
+ // New offsets added, update this node
+ node = updateEdgeOffsetsNormals(node, oldc, newc, offs, a, b, c);
+ }
+
+ return node;
}
void Octree::preparePrimalEdgesMask(InternalNode *node)
{
- int count = 0;
- for (int i = 0; i < 8; i++) {
- if (node->has_child(i)) {
- if (node->is_child_leaf(i))
- createPrimalEdgesMask(&node->get_child(count)->leaf);
- else
- preparePrimalEdgesMask(&node->get_child(count)->internal);
-
- count++;
- }
- }
+ int count = 0;
+ for (int i = 0; i < 8; i++) {
+ if (node->has_child(i)) {
+ if (node->is_child_leaf(i))
+ createPrimalEdgesMask(&node->get_child(count)->leaf);
+ else
+ preparePrimalEdgesMask(&node->get_child(count)->internal);
+
+ count++;
+ }
+ }
}
void Octree::trace()
{
- int st[3] = {0, 0, 0, };
- numRings = 0;
- totRingLengths = 0;
- maxRingLength = 0;
-
- PathList *chdpath = NULL;
- root = trace(root, st, dimen, maxDepth, chdpath);
-
- if (chdpath != NULL) {
- dc_printf("there are incomplete rings.\n");
- printPaths(chdpath);
- };
+ int st[3] = {
+ 0,
+ 0,
+ 0,
+ };
+ numRings = 0;
+ totRingLengths = 0;
+ maxRingLength = 0;
+
+ PathList *chdpath = NULL;
+ root = trace(root, st, dimen, maxDepth, chdpath);
+
+ if (chdpath != NULL) {
+ dc_printf("there are incomplete rings.\n");
+ printPaths(chdpath);
+ };
}
-Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *& paths)
+Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *&paths)
{
- len >>= 1;
- PathList *chdpaths[8];
- Node *chd[8];
- int nst[8][3];
- int i, j;
-
- // Get children paths
- int chdleaf[8];
- newnode->internal.fill_children(chd, chdleaf);
-
- // int count = 0;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 3; j++) {
- nst[i][j] = st[j] + len * vertmap[i][j];
- }
-
- if (chd[i] == NULL || newnode->internal.is_child_leaf(i)) {
- chdpaths[i] = NULL;
- }
- else {
- trace(chd[i], nst[i], len, depth - 1, chdpaths[i]);
- }
- }
-
- // Get connectors on the faces
- PathList *conn[12];
- Node *nf[2];
- int lf[2];
- int df[2] = {depth - 1, depth - 1};
- int *nstf[2];
-
- newnode->internal.fill_children(chd, chdleaf);
-
- for (i = 0; i < 12; i++) {
- int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
-
- for (int j = 0; j < 2; j++) {
- lf[j] = chdleaf[c[j]];
- nf[j] = chd[c[j]];
- nstf[j] = nst[c[j]];
- }
-
- conn[i] = NULL;
-
- findPaths((Node **)nf, lf, df, nstf, depth - 1, cellProcFaceMask[i][2], conn[i]);
-
- //if(conn[i]) {
- // printPath(conn[i]);
- //}
- }
-
- // Connect paths
- PathList *rings = NULL;
- combinePaths(chdpaths[0], chdpaths[1], conn[8], rings);
- combinePaths(chdpaths[2], chdpaths[3], conn[9], rings);
- combinePaths(chdpaths[4], chdpaths[5], conn[10], rings);
- combinePaths(chdpaths[6], chdpaths[7], conn[11], rings);
-
- combinePaths(chdpaths[0], chdpaths[2], conn[4], rings);
- combinePaths(chdpaths[4], chdpaths[6], conn[5], rings);
- combinePaths(chdpaths[0], NULL, conn[6], rings);
- combinePaths(chdpaths[4], NULL, conn[7], rings);
-
- combinePaths(chdpaths[0], chdpaths[4], conn[0], rings);
- combinePaths(chdpaths[0], NULL, conn[1], rings);
- combinePaths(chdpaths[0], NULL, conn[2], rings);
- combinePaths(chdpaths[0], NULL, conn[3], rings);
-
- // By now, only chdpaths[0] and rings have contents
-
- // Process rings
- if (rings) {
- // printPath(rings);
-
- /* Let's count first */
- PathList *trings = rings;
- while (trings) {
- numRings++;
- totRingLengths += trings->length;
- if (trings->length > maxRingLength) {
- maxRingLength = trings->length;
- }
- trings = trings->next;
- }
-
- // printPath(rings);
- newnode = patch(newnode, st, (len << 1), rings);
- }
-
- // Return incomplete paths
- paths = chdpaths[0];
- return newnode;
+ len >>= 1;
+ PathList *chdpaths[8];
+ Node *chd[8];
+ int nst[8][3];
+ int i, j;
+
+ // Get children paths
+ int chdleaf[8];
+ newnode->internal.fill_children(chd, chdleaf);
+
+ // int count = 0;
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 3; j++) {
+ nst[i][j] = st[j] + len * vertmap[i][j];
+ }
+
+ if (chd[i] == NULL || newnode->internal.is_child_leaf(i)) {
+ chdpaths[i] = NULL;
+ }
+ else {
+ trace(chd[i], nst[i], len, depth - 1, chdpaths[i]);
+ }
+ }
+
+ // Get connectors on the faces
+ PathList *conn[12];
+ Node *nf[2];
+ int lf[2];
+ int df[2] = {depth - 1, depth - 1};
+ int *nstf[2];
+
+ newnode->internal.fill_children(chd, chdleaf);
+
+ for (i = 0; i < 12; i++) {
+ int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
+
+ for (int j = 0; j < 2; j++) {
+ lf[j] = chdleaf[c[j]];
+ nf[j] = chd[c[j]];
+ nstf[j] = nst[c[j]];
+ }
+
+ conn[i] = NULL;
+
+ findPaths((Node **)nf, lf, df, nstf, depth - 1, cellProcFaceMask[i][2], conn[i]);
+
+ //if(conn[i]) {
+ // printPath(conn[i]);
+ //}
+ }
+
+ // Connect paths
+ PathList *rings = NULL;
+ combinePaths(chdpaths[0], chdpaths[1], conn[8], rings);
+ combinePaths(chdpaths[2], chdpaths[3], conn[9], rings);
+ combinePaths(chdpaths[4], chdpaths[5], conn[10], rings);
+ combinePaths(chdpaths[6], chdpaths[7], conn[11], rings);
+
+ combinePaths(chdpaths[0], chdpaths[2], conn[4], rings);
+ combinePaths(chdpaths[4], chdpaths[6], conn[5], rings);
+ combinePaths(chdpaths[0], NULL, conn[6], rings);
+ combinePaths(chdpaths[4], NULL, conn[7], rings);
+
+ combinePaths(chdpaths[0], chdpaths[4], conn[0], rings);
+ combinePaths(chdpaths[0], NULL, conn[1], rings);
+ combinePaths(chdpaths[0], NULL, conn[2], rings);
+ combinePaths(chdpaths[0], NULL, conn[3], rings);
+
+ // By now, only chdpaths[0] and rings have contents
+
+ // Process rings
+ if (rings) {
+ // printPath(rings);
+
+ /* Let's count first */
+ PathList *trings = rings;
+ while (trings) {
+ numRings++;
+ totRingLengths += trings->length;
+ if (trings->length > maxRingLength) {
+ maxRingLength = trings->length;
+ }
+ trings = trings->next;
+ }
+
+ // printPath(rings);
+ newnode = patch(newnode, st, (len << 1), rings);
+ }
+
+ // Return incomplete paths
+ paths = chdpaths[0];
+ return newnode;
}
-void Octree::findPaths(Node *node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList *& paths)
+void Octree::findPaths(
+ Node *node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList *&paths)
{
- if (!(node[0] && node[1])) {
- return;
- }
-
- if (!(leaf[0] && leaf[1])) {
- // Not at the bottom, recur
-
- // Fill children nodes
- int i, j;
- Node *chd[2][8];
- int chdleaf[2][8];
- int nst[2][8][3];
-
- for (j = 0; j < 2; j++) {
- if (!leaf[j]) {
- node[j]->internal.fill_children(chd[j], chdleaf[j]);
-
- int len = (dimen >> (maxDepth - depth[j] + 1));
- for (i = 0; i < 8; i++) {
- for (int k = 0; k < 3; k++) {
- nst[j][i][k] = st[j][k] + len * vertmap[i][k];
- }
- }
-
- }
- }
-
- // 4 face calls
- Node *nf[2];
- int df[2];
- int lf[2];
- int *nstf[2];
- for (i = 0; i < 4; i++) {
- int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
- for (int j = 0; j < 2; j++) {
- if (leaf[j]) {
- lf[j] = leaf[j];
- nf[j] = node[j];
- df[j] = depth[j];
- nstf[j] = st[j];
- }
- else {
- lf[j] = chdleaf[j][c[j]];
- nf[j] = chd[j][c[j]];
- df[j] = depth[j] - 1;
- nstf[j] = nst[j][c[j]];
- }
- }
- findPaths(nf, lf, df, nstf, maxdep - 1, faceProcFaceMask[dir][i][2], paths);
- }
-
- }
- else {
- // At the bottom, check this face
- int ind = (depth[0] == maxdep ? 0 : 1);
- int fcind = 2 * dir + (1 - ind);
- if (getFaceParity((LeafNode *)node[ind], fcind)) {
- // Add into path
- PathElement *ele1 = new PathElement;
- PathElement *ele2 = new PathElement;
-
- ele1->pos[0] = st[0][0];
- ele1->pos[1] = st[0][1];
- ele1->pos[2] = st[0][2];
-
- ele2->pos[0] = st[1][0];
- ele2->pos[1] = st[1][1];
- ele2->pos[2] = st[1][2];
-
- ele1->next = ele2;
- ele2->next = NULL;
-
- PathList *lst = new PathList;
- lst->head = ele1;
- lst->tail = ele2;
- lst->length = 2;
- lst->next = paths;
- paths = lst;
-
- // int l =(dimen >> maxDepth);
- }
- }
-
+ if (!(node[0] && node[1])) {
+ return;
+ }
+
+ if (!(leaf[0] && leaf[1])) {
+ // Not at the bottom, recur
+
+ // Fill children nodes
+ int i, j;
+ Node *chd[2][8];
+ int chdleaf[2][8];
+ int nst[2][8][3];
+
+ for (j = 0; j < 2; j++) {
+ if (!leaf[j]) {
+ node[j]->internal.fill_children(chd[j], chdleaf[j]);
+
+ int len = (dimen >> (maxDepth - depth[j] + 1));
+ for (i = 0; i < 8; i++) {
+ for (int k = 0; k < 3; k++) {
+ nst[j][i][k] = st[j][k] + len * vertmap[i][k];
+ }
+ }
+ }
+ }
+
+ // 4 face calls
+ Node *nf[2];
+ int df[2];
+ int lf[2];
+ int *nstf[2];
+ for (i = 0; i < 4; i++) {
+ int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
+ for (int j = 0; j < 2; j++) {
+ if (leaf[j]) {
+ lf[j] = leaf[j];
+ nf[j] = node[j];
+ df[j] = depth[j];
+ nstf[j] = st[j];
+ }
+ else {
+ lf[j] = chdleaf[j][c[j]];
+ nf[j] = chd[j][c[j]];
+ df[j] = depth[j] - 1;
+ nstf[j] = nst[j][c[j]];
+ }
+ }
+ findPaths(nf, lf, df, nstf, maxdep - 1, faceProcFaceMask[dir][i][2], paths);
+ }
+ }
+ else {
+ // At the bottom, check this face
+ int ind = (depth[0] == maxdep ? 0 : 1);
+ int fcind = 2 * dir + (1 - ind);
+ if (getFaceParity((LeafNode *)node[ind], fcind)) {
+ // Add into path
+ PathElement *ele1 = new PathElement;
+ PathElement *ele2 = new PathElement;
+
+ ele1->pos[0] = st[0][0];
+ ele1->pos[1] = st[0][1];
+ ele1->pos[2] = st[0][2];
+
+ ele2->pos[0] = st[1][0];
+ ele2->pos[1] = st[1][1];
+ ele2->pos[2] = st[1][2];
+
+ ele1->next = ele2;
+ ele2->next = NULL;
+
+ PathList *lst = new PathList;
+ lst->head = ele1;
+ lst->tail = ele2;
+ lst->length = 2;
+ lst->next = paths;
+ paths = lst;
+
+ // int l =(dimen >> maxDepth);
+ }
+ }
}
-void Octree::combinePaths(PathList *& list1, PathList *list2, PathList *paths, PathList *& rings)
+void Octree::combinePaths(PathList *&list1, PathList *list2, PathList *paths, PathList *&rings)
{
- // Make new list of paths
- PathList *nlist = NULL;
-
- // Search for each connectors in paths
- PathList *tpaths = paths;
- PathList *tlist, *pre;
- while (tpaths) {
- PathList *singlist = tpaths;
- PathList *templist;
- tpaths = tpaths->next;
- singlist->next = NULL;
-
- // Look for hookup in list1
- tlist = list1;
- pre = NULL;
- while (tlist) {
- if ((templist = combineSinglePath(list1, pre, tlist, singlist, NULL, singlist)) != NULL) {
- singlist = templist;
- continue;
- }
- pre = tlist;
- tlist = tlist->next;
- }
-
- // Look for hookup in list2
- tlist = list2;
- pre = NULL;
- while (tlist) {
- if ((templist = combineSinglePath(list2, pre, tlist, singlist, NULL, singlist)) != NULL) {
- singlist = templist;
- continue;
- }
- pre = tlist;
- tlist = tlist->next;
- }
-
- // Look for hookup in nlist
- tlist = nlist;
- pre = NULL;
- while (tlist) {
- if ((templist = combineSinglePath(nlist, pre, tlist, singlist, NULL, singlist)) != NULL) {
- singlist = templist;
- continue;
- }
- pre = tlist;
- tlist = tlist->next;
- }
-
- // Add to nlist or rings
- if (isEqual(singlist->head, singlist->tail)) {
- PathElement *temp = singlist->head;
- singlist->head = temp->next;
- delete temp;
- singlist->length--;
- singlist->tail->next = singlist->head;
-
- singlist->next = rings;
- rings = singlist;
- }
- else {
- singlist->next = nlist;
- nlist = singlist;
- }
-
- }
-
- // Append list2 and nlist to the end of list1
- tlist = list1;
- if (tlist != NULL) {
- while (tlist->next != NULL) {
- tlist = tlist->next;
- }
- tlist->next = list2;
- }
- else {
- tlist = list2;
- list1 = list2;
- }
-
- if (tlist != NULL) {
- while (tlist->next != NULL) {
- tlist = tlist->next;
- }
- tlist->next = nlist;
- }
- else {
- tlist = nlist;
- list1 = nlist;
- }
-
+ // Make new list of paths
+ PathList *nlist = NULL;
+
+ // Search for each connectors in paths
+ PathList *tpaths = paths;
+ PathList *tlist, *pre;
+ while (tpaths) {
+ PathList *singlist = tpaths;
+ PathList *templist;
+ tpaths = tpaths->next;
+ singlist->next = NULL;
+
+ // Look for hookup in list1
+ tlist = list1;
+ pre = NULL;
+ while (tlist) {
+ if ((templist = combineSinglePath(list1, pre, tlist, singlist, NULL, singlist)) != NULL) {
+ singlist = templist;
+ continue;
+ }
+ pre = tlist;
+ tlist = tlist->next;
+ }
+
+ // Look for hookup in list2
+ tlist = list2;
+ pre = NULL;
+ while (tlist) {
+ if ((templist = combineSinglePath(list2, pre, tlist, singlist, NULL, singlist)) != NULL) {
+ singlist = templist;
+ continue;
+ }
+ pre = tlist;
+ tlist = tlist->next;
+ }
+
+ // Look for hookup in nlist
+ tlist = nlist;
+ pre = NULL;
+ while (tlist) {
+ if ((templist = combineSinglePath(nlist, pre, tlist, singlist, NULL, singlist)) != NULL) {
+ singlist = templist;
+ continue;
+ }
+ pre = tlist;
+ tlist = tlist->next;
+ }
+
+ // Add to nlist or rings
+ if (isEqual(singlist->head, singlist->tail)) {
+ PathElement *temp = singlist->head;
+ singlist->head = temp->next;
+ delete temp;
+ singlist->length--;
+ singlist->tail->next = singlist->head;
+
+ singlist->next = rings;
+ rings = singlist;
+ }
+ else {
+ singlist->next = nlist;
+ nlist = singlist;
+ }
+ }
+
+ // Append list2 and nlist to the end of list1
+ tlist = list1;
+ if (tlist != NULL) {
+ while (tlist->next != NULL) {
+ tlist = tlist->next;
+ }
+ tlist->next = list2;
+ }
+ else {
+ tlist = list2;
+ list1 = list2;
+ }
+
+ if (tlist != NULL) {
+ while (tlist->next != NULL) {
+ tlist = tlist->next;
+ }
+ tlist->next = nlist;
+ }
+ else {
+ tlist = nlist;
+ list1 = nlist;
+ }
}
-PathList *Octree::combineSinglePath(PathList *& head1, PathList *pre1, PathList *& list1, PathList *& head2, PathList *pre2, PathList *& list2)
+PathList *Octree::combineSinglePath(PathList *&head1,
+ PathList *pre1,
+ PathList *&list1,
+ PathList *&head2,
+ PathList *pre2,
+ PathList *&list2)
{
- if (isEqual(list1->head, list2->head) || isEqual(list1->tail, list2->tail)) {
- // Reverse the list
- if (list1->length < list2->length) {
- // Reverse list1
- PathElement *prev = list1->head;
- PathElement *next = prev->next;
- prev->next = NULL;
- while (next != NULL) {
- PathElement *tnext = next->next;
- next->next = prev;
-
- prev = next;
- next = tnext;
- }
-
- list1->tail = list1->head;
- list1->head = prev;
- }
- else {
- // Reverse list2
- PathElement *prev = list2->head;
- PathElement *next = prev->next;
- prev->next = NULL;
- while (next != NULL) {
- PathElement *tnext = next->next;
- next->next = prev;
-
- prev = next;
- next = tnext;
- }
-
- list2->tail = list2->head;
- list2->head = prev;
- }
- }
-
- if (isEqual(list1->head, list2->tail)) {
-
- // Easy case
- PathElement *temp = list1->head->next;
- delete list1->head;
- list2->tail->next = temp;
-
- PathList *nlist = new PathList;
- nlist->length = list1->length + list2->length - 1;
- nlist->head = list2->head;
- nlist->tail = list1->tail;
- nlist->next = NULL;
-
- deletePath(head1, pre1, list1);
- deletePath(head2, pre2, list2);
-
- return nlist;
- }
- else if (isEqual(list1->tail, list2->head)) {
- // Easy case
- PathElement *temp = list2->head->next;
- delete list2->head;
- list1->tail->next = temp;
-
- PathList *nlist = new PathList;
- nlist->length = list1->length + list2->length - 1;
- nlist->head = list1->head;
- nlist->tail = list2->tail;
- nlist->next = NULL;
-
- deletePath(head1, pre1, list1);
- deletePath(head2, pre2, list2);
-
- return nlist;
- }
-
- return NULL;
+ if (isEqual(list1->head, list2->head) || isEqual(list1->tail, list2->tail)) {
+ // Reverse the list
+ if (list1->length < list2->length) {
+ // Reverse list1
+ PathElement *prev = list1->head;
+ PathElement *next = prev->next;
+ prev->next = NULL;
+ while (next != NULL) {
+ PathElement *tnext = next->next;
+ next->next = prev;
+
+ prev = next;
+ next = tnext;
+ }
+
+ list1->tail = list1->head;
+ list1->head = prev;
+ }
+ else {
+ // Reverse list2
+ PathElement *prev = list2->head;
+ PathElement *next = prev->next;
+ prev->next = NULL;
+ while (next != NULL) {
+ PathElement *tnext = next->next;
+ next->next = prev;
+
+ prev = next;
+ next = tnext;
+ }
+
+ list2->tail = list2->head;
+ list2->head = prev;
+ }
+ }
+
+ if (isEqual(list1->head, list2->tail)) {
+
+ // Easy case
+ PathElement *temp = list1->head->next;
+ delete list1->head;
+ list2->tail->next = temp;
+
+ PathList *nlist = new PathList;
+ nlist->length = list1->length + list2->length - 1;
+ nlist->head = list2->head;
+ nlist->tail = list1->tail;
+ nlist->next = NULL;
+
+ deletePath(head1, pre1, list1);
+ deletePath(head2, pre2, list2);
+
+ return nlist;
+ }
+ else if (isEqual(list1->tail, list2->head)) {
+ // Easy case
+ PathElement *temp = list2->head->next;
+ delete list2->head;
+ list1->tail->next = temp;
+
+ PathList *nlist = new PathList;
+ nlist->length = list1->length + list2->length - 1;
+ nlist->head = list1->head;
+ nlist->tail = list2->tail;
+ nlist->next = NULL;
+
+ deletePath(head1, pre1, list1);
+ deletePath(head2, pre2, list2);
+
+ return nlist;
+ }
+
+ return NULL;
}
-void Octree::deletePath(PathList *& head, PathList *pre, PathList *& curr)
+void Octree::deletePath(PathList *&head, PathList *pre, PathList *&curr)
{
- PathList *temp = curr;
- curr = temp->next;
- delete temp;
-
- if (pre == NULL) {
- head = curr;
- }
- else {
- pre->next = curr;
- }
+ PathList *temp = curr;
+ curr = temp->next;
+ delete temp;
+
+ if (pre == NULL) {
+ head = curr;
+ }
+ else {
+ pre->next = curr;
+ }
}
void Octree::printElement(PathElement *ele)
{
- if (ele != NULL) {
- dc_printf("(%d %d %d)", ele->pos[0], ele->pos[1], ele->pos[2]);
- }
+ if (ele != NULL) {
+ dc_printf("(%d %d %d)", ele->pos[0], ele->pos[1], ele->pos[2]);
+ }
}
void Octree::printPath(PathList *path)
{
- PathElement *n = path->head;
- int same = 0;
+ PathElement *n = path->head;
+ int same = 0;
#if DC_DEBUG
- int len = (dimen >> maxDepth);
+ int len = (dimen >> maxDepth);
#endif
- while (n && (same == 0 || n != path->head)) {
- same++;
- dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
- n = n->next;
- }
-
- if (n == path->head) {
- dc_printf(" Ring!\n");
- }
- else {
- dc_printf(" %p end!\n", n);
- }
+ while (n && (same == 0 || n != path->head)) {
+ same++;
+ dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
+ n = n->next;
+ }
+
+ if (n == path->head) {
+ dc_printf(" Ring!\n");
+ }
+ else {
+ dc_printf(" %p end!\n", n);
+ }
}
void Octree::printPath(PathElement *path)
{
- PathElement *n = path;
- int same = 0;
+ PathElement *n = path;
+ int same = 0;
#if DC_DEBUG
- int len = (dimen >> maxDepth);
+ int len = (dimen >> maxDepth);
#endif
- while (n && (same == 0 || n != path)) {
- same++;
- dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
- n = n->next;
- }
-
- if (n == path) {
- dc_printf(" Ring!\n");
- }
- else {
- dc_printf(" %p end!\n", n);
- }
-
+ while (n && (same == 0 || n != path)) {
+ same++;
+ dc_printf("(%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len);
+ n = n->next;
+ }
+
+ if (n == path) {
+ dc_printf(" Ring!\n");
+ }
+ else {
+ dc_printf(" %p end!\n", n);
+ }
}
-
void Octree::printPaths(PathList *path)
{
- PathList *iter = path;
- int i = 0;
- while (iter != NULL) {
- dc_printf("Path %d:\n", i);
- printPath(iter);
- iter = iter->next;
- i++;
- }
+ PathList *iter = path;
+ int i = 0;
+ while (iter != NULL) {
+ dc_printf("Path %d:\n", i);
+ printPath(iter);
+ iter = iter->next;
+ i++;
+ }
}
Node *Octree::patch(Node *newnode, int st[3], int len, PathList *rings)
{
#ifdef IN_DEBUG_MODE
- dc_printf("Call to PATCH with rings: \n");
- printPaths(rings);
+ dc_printf("Call to PATCH with rings: \n");
+ printPaths(rings);
#endif
- /* Do nothing but couting
- PathList* tlist = rings;
- PathList* ttlist;
- PathElement* telem, * ttelem;
- while(tlist!= NULL) {
- // printPath(tlist);
- numRings ++;
- totRingLengths += tlist->length;
- if(tlist->length > maxRingLength) {
- maxRingLength = tlist->length;
- }
- ttlist = tlist;
- tlist = tlist->next;
- }
- return node;
- */
-
-
- /* Pass onto separate calls in each direction */
- if (len == mindimen) {
- dc_printf("Error! should have no list by now.\n");
- exit(0);
- }
-
- // YZ plane
- PathList *xlists[2];
- newnode = patchSplit(newnode, st, len, rings, 0, xlists[0], xlists[1]);
-
- // XZ plane
- PathList *ylists[4];
- newnode = patchSplit(newnode, st, len, xlists[0], 1, ylists[0], ylists[1]);
- newnode = patchSplit(newnode, st, len, xlists[1], 1, ylists[2], ylists[3]);
-
- // XY plane
- PathList *zlists[8];
- newnode = patchSplit(newnode, st, len, ylists[0], 2, zlists[0], zlists[1]);
- newnode = patchSplit(newnode, st, len, ylists[1], 2, zlists[2], zlists[3]);
- newnode = patchSplit(newnode, st, len, ylists[2], 2, zlists[4], zlists[5]);
- newnode = patchSplit(newnode, st, len, ylists[3], 2, zlists[6], zlists[7]);
-
- // Recur
- len >>= 1;
- int count = 0;
- for (int i = 0; i < 8; i++) {
- if (zlists[i] != NULL) {
- int nori[3] = {
- st[0] + len * vertmap[i][0],
- st[1] + len * vertmap[i][1],
- st[2] + len * vertmap[i][2]
- };
- patch(newnode->internal.get_child(count), nori, len, zlists[i]);
- }
-
- if (newnode->internal.has_child(i)) {
- count++;
- }
- }
+ /* Do nothing but couting
+ PathList* tlist = rings;
+ PathList* ttlist;
+ PathElement* telem, * ttelem;
+ while(tlist!= NULL) {
+ // printPath(tlist);
+ numRings ++;
+ totRingLengths += tlist->length;
+ if(tlist->length > maxRingLength) {
+ maxRingLength = tlist->length;
+ }
+ ttlist = tlist;
+ tlist = tlist->next;
+ }
+ return node;
+ */
+
+ /* Pass onto separate calls in each direction */
+ if (len == mindimen) {
+ dc_printf("Error! should have no list by now.\n");
+ exit(0);
+ }
+
+ // YZ plane
+ PathList *xlists[2];
+ newnode = patchSplit(newnode, st, len, rings, 0, xlists[0], xlists[1]);
+
+ // XZ plane
+ PathList *ylists[4];
+ newnode = patchSplit(newnode, st, len, xlists[0], 1, ylists[0], ylists[1]);
+ newnode = patchSplit(newnode, st, len, xlists[1], 1, ylists[2], ylists[3]);
+
+ // XY plane
+ PathList *zlists[8];
+ newnode = patchSplit(newnode, st, len, ylists[0], 2, zlists[0], zlists[1]);
+ newnode = patchSplit(newnode, st, len, ylists[1], 2, zlists[2], zlists[3]);
+ newnode = patchSplit(newnode, st, len, ylists[2], 2, zlists[4], zlists[5]);
+ newnode = patchSplit(newnode, st, len, ylists[3], 2, zlists[6], zlists[7]);
+
+ // Recur
+ len >>= 1;
+ int count = 0;
+ for (int i = 0; i < 8; i++) {
+ if (zlists[i] != NULL) {
+ int nori[3] = {
+ st[0] + len * vertmap[i][0], st[1] + len * vertmap[i][1], st[2] + len * vertmap[i][2]};
+ patch(newnode->internal.get_child(count), nori, len, zlists[i]);
+ }
+
+ if (newnode->internal.has_child(i)) {
+ count++;
+ }
+ }
#ifdef IN_DEBUG_MODE
- dc_printf("Return from PATCH\n");
+ dc_printf("Return from PATCH\n");
#endif
- return newnode;
-
+ return newnode;
}
-
-Node *Octree::patchSplit(Node *newnode, int st[3], int len, PathList *rings,
- int dir, PathList *& nrings1, PathList *& nrings2)
+Node *Octree::patchSplit(Node *newnode,
+ int st[3],
+ int len,
+ PathList *rings,
+ int dir,
+ PathList *&nrings1,
+ PathList *&nrings2)
{
#ifdef IN_DEBUG_MODE
- dc_printf("Call to PATCHSPLIT with direction %d and rings: \n", dir);
- printPaths(rings);
+ dc_printf("Call to PATCHSPLIT with direction %d and rings: \n", dir);
+ printPaths(rings);
#endif
- nrings1 = NULL;
- nrings2 = NULL;
- PathList *tmp;
- while (rings != NULL) {
- // Process this ring
- newnode = patchSplitSingle(newnode, st, len, rings->head, dir, nrings1, nrings2);
+ nrings1 = NULL;
+ nrings2 = NULL;
+ PathList *tmp;
+ while (rings != NULL) {
+ // Process this ring
+ newnode = patchSplitSingle(newnode, st, len, rings->head, dir, nrings1, nrings2);
- // Delete this ring from the group
- tmp = rings;
- rings = rings->next;
- delete tmp;
- }
+ // Delete this ring from the group
+ tmp = rings;
+ rings = rings->next;
+ delete tmp;
+ }
#ifdef IN_DEBUG_MODE
- dc_printf("Return from PATCHSPLIT with \n");
- dc_printf("Rings gourp 1:\n");
- printPaths(nrings1);
- dc_printf("Rings group 2:\n");
- printPaths(nrings2);
+ dc_printf("Return from PATCHSPLIT with \n");
+ dc_printf("Rings gourp 1:\n");
+ printPaths(nrings1);
+ dc_printf("Rings group 2:\n");
+ printPaths(nrings2);
#endif
- return newnode;
+ return newnode;
}
-Node *Octree::patchSplitSingle(Node *newnode, int st[3], int len, PathElement *head, int dir, PathList *& nrings1, PathList *& nrings2)
+Node *Octree::patchSplitSingle(Node *newnode,
+ int st[3],
+ int len,
+ PathElement *head,
+ int dir,
+ PathList *&nrings1,
+ PathList *&nrings2)
{
#ifdef IN_DEBUG_MODE
- dc_printf("Call to PATCHSPLITSINGLE with direction %d and path: \n", dir);
- printPath(head);
+ dc_printf("Call to PATCHSPLITSINGLE with direction %d and path: \n", dir);
+ printPath(head);
#endif
- if (head == NULL) {
+ if (head == NULL) {
#ifdef IN_DEBUG_MODE
- dc_printf("Return from PATCHSPLITSINGLE with head==NULL.\n");
+ dc_printf("Return from PATCHSPLITSINGLE with head==NULL.\n");
#endif
- return newnode;
- }
- else {
- // printPath(head);
- }
-
- // Walk along the ring to find pair of intersections
- PathElement *pre1 = NULL;
- PathElement *pre2 = NULL;
- int side = findPair(head, st[dir] + len / 2, dir, pre1, pre2);
-
- /*
- if(pre1 == pre2) {
- int edgelen =(dimen >> maxDepth);
- dc_printf("Location: %d %d %d Direction: %d Reso: %d\n", st[0]/edgelen, st[1]/edgelen, st[2]/edgelen, dir, len/edgelen);
- printPath(head);
- exit(0);
- }
- */
-
- if (side) {
- // Entirely on one side
- PathList *nring = new PathList();
- nring->head = head;
-
- if (side == -1) {
- nring->next = nrings1;
- nrings1 = nring;
- }
- else {
- nring->next = nrings2;
- nrings2 = nring;
- }
- }
- else {
- // Break into two parts
- PathElement *nxt1 = pre1->next;
- PathElement *nxt2 = pre2->next;
- pre1->next = nxt2;
- pre2->next = nxt1;
-
- newnode = connectFace(newnode, st, len, dir, pre1, pre2);
-
- if (isEqual(pre1, pre1->next)) {
- if (pre1 == pre1->next) {
- delete pre1;
- pre1 = NULL;
- }
- else {
- PathElement *temp = pre1->next;
- pre1->next = temp->next;
- delete temp;
- }
- }
- if (isEqual(pre2, pre2->next)) {
- if (pre2 == pre2->next) {
- delete pre2;
- pre2 = NULL;
- }
- else {
- PathElement *temp = pre2->next;
- pre2->next = temp->next;
- delete temp;
- }
- }
-
- compressRing(pre1);
- compressRing(pre2);
-
- // Recur
- newnode = patchSplitSingle(newnode, st, len, pre1, dir, nrings1, nrings2);
- newnode = patchSplitSingle(newnode, st, len, pre2, dir, nrings1, nrings2);
-
- }
+ return newnode;
+ }
+ else {
+ // printPath(head);
+ }
+
+ // Walk along the ring to find pair of intersections
+ PathElement *pre1 = NULL;
+ PathElement *pre2 = NULL;
+ int side = findPair(head, st[dir] + len / 2, dir, pre1, pre2);
+
+ /*
+ if(pre1 == pre2) {
+ int edgelen =(dimen >> maxDepth);
+ dc_printf("Location: %d %d %d Direction: %d Reso: %d\n", st[0]/edgelen, st[1]/edgelen, st[2]/edgelen, dir, len/edgelen);
+ printPath(head);
+ exit(0);
+ }
+ */
+
+ if (side) {
+ // Entirely on one side
+ PathList *nring = new PathList();
+ nring->head = head;
+
+ if (side == -1) {
+ nring->next = nrings1;
+ nrings1 = nring;
+ }
+ else {
+ nring->next = nrings2;
+ nrings2 = nring;
+ }
+ }
+ else {
+ // Break into two parts
+ PathElement *nxt1 = pre1->next;
+ PathElement *nxt2 = pre2->next;
+ pre1->next = nxt2;
+ pre2->next = nxt1;
+
+ newnode = connectFace(newnode, st, len, dir, pre1, pre2);
+
+ if (isEqual(pre1, pre1->next)) {
+ if (pre1 == pre1->next) {
+ delete pre1;
+ pre1 = NULL;
+ }
+ else {
+ PathElement *temp = pre1->next;
+ pre1->next = temp->next;
+ delete temp;
+ }
+ }
+ if (isEqual(pre2, pre2->next)) {
+ if (pre2 == pre2->next) {
+ delete pre2;
+ pre2 = NULL;
+ }
+ else {
+ PathElement *temp = pre2->next;
+ pre2->next = temp->next;
+ delete temp;
+ }
+ }
+
+ compressRing(pre1);
+ compressRing(pre2);
+
+ // Recur
+ newnode = patchSplitSingle(newnode, st, len, pre1, dir, nrings1, nrings2);
+ newnode = patchSplitSingle(newnode, st, len, pre2, dir, nrings1, nrings2);
+ }
#ifdef IN_DEBUG_MODE
- dc_printf("Return from PATCHSPLITSINGLE with \n");
- dc_printf("Rings gourp 1:\n");
- printPaths(nrings1);
- dc_printf("Rings group 2:\n");
- printPaths(nrings2);
+ dc_printf("Return from PATCHSPLITSINGLE with \n");
+ dc_printf("Rings gourp 1:\n");
+ printPaths(nrings1);
+ dc_printf("Rings group 2:\n");
+ printPaths(nrings2);
#endif
- return newnode;
+ return newnode;
}
-Node *Octree::connectFace(Node *newnode, int st[3], int len, int dir,
- PathElement *f1, PathElement *f2)
+Node *Octree::connectFace(
+ Node *newnode, int st[3], int len, int dir, PathElement *f1, PathElement *f2)
{
#ifdef IN_DEBUG_MODE
- dc_printf("Call to CONNECTFACE with direction %d and length %d path: \n", dir, len);
- dc_printf("Path(low side): \n");
- printPath(f1);
-// checkPath(f1);
- dc_printf("Path(high side): \n");
- printPath(f2);
-// checkPath(f2);
+ dc_printf("Call to CONNECTFACE with direction %d and length %d path: \n", dir, len);
+ dc_printf("Path(low side): \n");
+ printPath(f1);
+ // checkPath(f1);
+ dc_printf("Path(high side): \n");
+ printPath(f2);
+// checkPath(f2);
#endif
- // Setup 2D
- int pos = st[dir] + len / 2;
- int xdir = (dir + 1) % 3;
- int ydir = (dir + 2) % 3;
-
- // Use existing intersections on f1 and f2
- int x1, y1, x2, y2;
- float p1, q1, p2, q2;
-
- getFacePoint(f2->next, dir, x1, y1, p1, q1);
- getFacePoint(f2, dir, x2, y2, p2, q2);
-
- float dx = x2 + p2 - x1 - p1;
- float dy = y2 + q2 - y1 - q1;
-
- // Do adapted Bresenham line drawing
- float rx = p1, ry = q1;
- int incx = 1, incy = 1;
- int lx = x1, ly = y1;
- int hx = x2, hy = y2;
- int choice;
- if (x2 < x1) {
- incx = -1;
- rx = 1 - rx;
- lx = x2;
- hx = x1;
- }
- if (y2 < y1) {
- incy = -1;
- ry = 1 - ry;
- ly = y2;
- hy = y1;
- }
-
- float sx = dx * incx;
- float sy = dy * incy;
-
- int ori[3];
- ori[dir] = pos / mindimen;
- ori[xdir] = x1;
- ori[ydir] = y1;
- int walkdir;
- int inc;
- float alpha;
-
- PathElement *curEleN = f1;
- PathElement *curEleP = f2->next;
- Node *nodeN = NULL, *nodeP = NULL;
- LeafNode *curN = locateLeaf(&newnode->internal, len, f1->pos);
- LeafNode *curP = locateLeaf(&newnode->internal, len, f2->next->pos);
- if (curN == NULL || curP == NULL) {
- exit(0);
- }
- int stN[3], stP[3];
- int lenN, lenP;
-
- /* Unused code, leaving for posterity
-
- float stpt[3], edpt[3];
- stpt[dir] = edpt[dir] =(float) pos;
- stpt[xdir] =(x1 + p1) * mindimen;
- stpt[ydir] =(y1 + q1) * mindimen;
- edpt[xdir] =(x2 + p2) * mindimen;
- edpt[ydir] =(y2 + q2) * mindimen;
- */
- while (ori[xdir] != x2 || ori[ydir] != y2) {
- int next;
- if (sy * (1 - rx) > sx * (1 - ry)) {
- choice = 1;
- next = ori[ydir] + incy;
- if (next < ly || next > hy) {
- choice = 4;
- next = ori[xdir] + incx;
- }
- }
- else {
- choice = 2;
- next = ori[xdir] + incx;
- if (next < lx || next > hx) {
- choice = 3;
- next = ori[ydir] + incy;
- }
- }
-
- if (choice & 1) {
- ori[ydir] = next;
- if (choice == 1) {
- rx += (sy == 0 ? 0 : (1 - ry) * sx / sy);
- ry = 0;
- }
-
- walkdir = 2;
- inc = incy;
- alpha = x2 < x1 ? 1 - rx : rx;
- }
- else {
- ori[xdir] = next;
- if (choice == 2) {
- ry += (sx == 0 ? 0 : (1 - rx) * sy / sx);
- rx = 0;
- }
-
- walkdir = 1;
- inc = incx;
- alpha = y2 < y1 ? 1 - ry : ry;
- }
-
-
-
- // Get the exact location of the marcher
- int nori[3] = {ori[0] * mindimen, ori[1] * mindimen, ori[2] * mindimen};
- float spt[3] = {(float) nori[0], (float) nori[1], (float) nori[2]};
- spt[(dir + (3 - walkdir)) % 3] += alpha * mindimen;
- if (inc < 0) {
- spt[(dir + walkdir) % 3] += mindimen;
- }
-
- // dc_printf("new x,y: %d %d\n", ori[xdir] / edgelen, ori[ydir] / edgelen);
- // dc_printf("nori: %d %d %d alpha: %f walkdir: %d\n", nori[0], nori[1], nori[2], alpha, walkdir);
- // dc_printf("%f %f %f\n", spt[0], spt[1], spt[2]);
-
- // Locate the current cells on both sides
- newnode = locateCell(&newnode->internal, st, len, nori, dir, 1, nodeN, stN, lenN);
- newnode = locateCell(&newnode->internal, st, len, nori, dir, 0, nodeP, stP, lenP);
-
- updateParent(&newnode->internal, len, st);
-
- int flag = 0;
- // Add the cells to the rings and fill in the patch
- PathElement *newEleN;
- if (curEleN->pos[0] != stN[0] || curEleN->pos[1] != stN[1] || curEleN->pos[2] != stN[2]) {
- if (curEleN->next->pos[0] != stN[0] || curEleN->next->pos[1] != stN[1] || curEleN->next->pos[2] != stN[2]) {
- newEleN = new PathElement;
- newEleN->next = curEleN->next;
- newEleN->pos[0] = stN[0];
- newEleN->pos[1] = stN[1];
- newEleN->pos[2] = stN[2];
-
- curEleN->next = newEleN;
- }
- else {
- newEleN = curEleN->next;
- }
- curN = patchAdjacent(&newnode->internal, len, curEleN->pos, curN,
- newEleN->pos, (LeafNode *)nodeN, walkdir,
- inc, dir, 1, alpha);
-
- curEleN = newEleN;
- flag++;
- }
-
- PathElement *newEleP;
- if (curEleP->pos[0] != stP[0] || curEleP->pos[1] != stP[1] || curEleP->pos[2] != stP[2]) {
- if (f2->pos[0] != stP[0] || f2->pos[1] != stP[1] || f2->pos[2] != stP[2]) {
- newEleP = new PathElement;
- newEleP->next = curEleP;
- newEleP->pos[0] = stP[0];
- newEleP->pos[1] = stP[1];
- newEleP->pos[2] = stP[2];
-
- f2->next = newEleP;
- }
- else {
- newEleP = f2;
- }
- curP = patchAdjacent(&newnode->internal, len, curEleP->pos, curP,
- newEleP->pos, (LeafNode *)nodeP, walkdir,
- inc, dir, 0, alpha);
-
-
-
- curEleP = newEleP;
- flag++;
- }
-
-
- /*
- if(flag == 0) {
- dc_printf("error: non-synchronized patching! at \n");
- }
- */
- }
+ // Setup 2D
+ int pos = st[dir] + len / 2;
+ int xdir = (dir + 1) % 3;
+ int ydir = (dir + 2) % 3;
+
+ // Use existing intersections on f1 and f2
+ int x1, y1, x2, y2;
+ float p1, q1, p2, q2;
+
+ getFacePoint(f2->next, dir, x1, y1, p1, q1);
+ getFacePoint(f2, dir, x2, y2, p2, q2);
+
+ float dx = x2 + p2 - x1 - p1;
+ float dy = y2 + q2 - y1 - q1;
+
+ // Do adapted Bresenham line drawing
+ float rx = p1, ry = q1;
+ int incx = 1, incy = 1;
+ int lx = x1, ly = y1;
+ int hx = x2, hy = y2;
+ int choice;
+ if (x2 < x1) {
+ incx = -1;
+ rx = 1 - rx;
+ lx = x2;
+ hx = x1;
+ }
+ if (y2 < y1) {
+ incy = -1;
+ ry = 1 - ry;
+ ly = y2;
+ hy = y1;
+ }
+
+ float sx = dx * incx;
+ float sy = dy * incy;
+
+ int ori[3];
+ ori[dir] = pos / mindimen;
+ ori[xdir] = x1;
+ ori[ydir] = y1;
+ int walkdir;
+ int inc;
+ float alpha;
+
+ PathElement *curEleN = f1;
+ PathElement *curEleP = f2->next;
+ Node *nodeN = NULL, *nodeP = NULL;
+ LeafNode *curN = locateLeaf(&newnode->internal, len, f1->pos);
+ LeafNode *curP = locateLeaf(&newnode->internal, len, f2->next->pos);
+ if (curN == NULL || curP == NULL) {
+ exit(0);
+ }
+ int stN[3], stP[3];
+ int lenN, lenP;
+
+ /* Unused code, leaving for posterity
+
+ float stpt[3], edpt[3];
+ stpt[dir] = edpt[dir] =(float) pos;
+ stpt[xdir] =(x1 + p1) * mindimen;
+ stpt[ydir] =(y1 + q1) * mindimen;
+ edpt[xdir] =(x2 + p2) * mindimen;
+ edpt[ydir] =(y2 + q2) * mindimen;
+ */
+ while (ori[xdir] != x2 || ori[ydir] != y2) {
+ int next;
+ if (sy * (1 - rx) > sx * (1 - ry)) {
+ choice = 1;
+ next = ori[ydir] + incy;
+ if (next < ly || next > hy) {
+ choice = 4;
+ next = ori[xdir] + incx;
+ }
+ }
+ else {
+ choice = 2;
+ next = ori[xdir] + incx;
+ if (next < lx || next > hx) {
+ choice = 3;
+ next = ori[ydir] + incy;
+ }
+ }
+
+ if (choice & 1) {
+ ori[ydir] = next;
+ if (choice == 1) {
+ rx += (sy == 0 ? 0 : (1 - ry) * sx / sy);
+ ry = 0;
+ }
+
+ walkdir = 2;
+ inc = incy;
+ alpha = x2 < x1 ? 1 - rx : rx;
+ }
+ else {
+ ori[xdir] = next;
+ if (choice == 2) {
+ ry += (sx == 0 ? 0 : (1 - rx) * sy / sx);
+ rx = 0;
+ }
+
+ walkdir = 1;
+ inc = incx;
+ alpha = y2 < y1 ? 1 - ry : ry;
+ }
+
+ // Get the exact location of the marcher
+ int nori[3] = {ori[0] * mindimen, ori[1] * mindimen, ori[2] * mindimen};
+ float spt[3] = {(float)nori[0], (float)nori[1], (float)nori[2]};
+ spt[(dir + (3 - walkdir)) % 3] += alpha * mindimen;
+ if (inc < 0) {
+ spt[(dir + walkdir) % 3] += mindimen;
+ }
+
+ // dc_printf("new x,y: %d %d\n", ori[xdir] / edgelen, ori[ydir] / edgelen);
+ // dc_printf("nori: %d %d %d alpha: %f walkdir: %d\n", nori[0], nori[1], nori[2], alpha, walkdir);
+ // dc_printf("%f %f %f\n", spt[0], spt[1], spt[2]);
+
+ // Locate the current cells on both sides
+ newnode = locateCell(&newnode->internal, st, len, nori, dir, 1, nodeN, stN, lenN);
+ newnode = locateCell(&newnode->internal, st, len, nori, dir, 0, nodeP, stP, lenP);
+
+ updateParent(&newnode->internal, len, st);
+
+ int flag = 0;
+ // Add the cells to the rings and fill in the patch
+ PathElement *newEleN;
+ if (curEleN->pos[0] != stN[0] || curEleN->pos[1] != stN[1] || curEleN->pos[2] != stN[2]) {
+ if (curEleN->next->pos[0] != stN[0] || curEleN->next->pos[1] != stN[1] ||
+ curEleN->next->pos[2] != stN[2]) {
+ newEleN = new PathElement;
+ newEleN->next = curEleN->next;
+ newEleN->pos[0] = stN[0];
+ newEleN->pos[1] = stN[1];
+ newEleN->pos[2] = stN[2];
+
+ curEleN->next = newEleN;
+ }
+ else {
+ newEleN = curEleN->next;
+ }
+ curN = patchAdjacent(&newnode->internal,
+ len,
+ curEleN->pos,
+ curN,
+ newEleN->pos,
+ (LeafNode *)nodeN,
+ walkdir,
+ inc,
+ dir,
+ 1,
+ alpha);
+
+ curEleN = newEleN;
+ flag++;
+ }
+
+ PathElement *newEleP;
+ if (curEleP->pos[0] != stP[0] || curEleP->pos[1] != stP[1] || curEleP->pos[2] != stP[2]) {
+ if (f2->pos[0] != stP[0] || f2->pos[1] != stP[1] || f2->pos[2] != stP[2]) {
+ newEleP = new PathElement;
+ newEleP->next = curEleP;
+ newEleP->pos[0] = stP[0];
+ newEleP->pos[1] = stP[1];
+ newEleP->pos[2] = stP[2];
+
+ f2->next = newEleP;
+ }
+ else {
+ newEleP = f2;
+ }
+ curP = patchAdjacent(&newnode->internal,
+ len,
+ curEleP->pos,
+ curP,
+ newEleP->pos,
+ (LeafNode *)nodeP,
+ walkdir,
+ inc,
+ dir,
+ 0,
+ alpha);
+
+ curEleP = newEleP;
+ flag++;
+ }
+
+ /*
+ if(flag == 0) {
+ dc_printf("error: non-synchronized patching! at \n");
+ }
+ */
+ }
#ifdef IN_DEBUG_MODE
- dc_printf("Return from CONNECTFACE with \n");
- dc_printf("Path(low side):\n");
- printPath(f1);
- checkPath(f1);
- dc_printf("Path(high side):\n");
- printPath(f2);
- checkPath(f2);
+ dc_printf("Return from CONNECTFACE with \n");
+ dc_printf("Path(low side):\n");
+ printPath(f1);
+ checkPath(f1);
+ dc_printf("Path(high side):\n");
+ printPath(f2);
+ checkPath(f2);
#endif
-
- return newnode;
+ return newnode;
}
-LeafNode *Octree::patchAdjacent(InternalNode *node, int len, int st1[3],
- LeafNode *leaf1, int st2[3], LeafNode *leaf2,
- int walkdir, int inc, int dir, int side,
+LeafNode *Octree::patchAdjacent(InternalNode *node,
+ int len,
+ int st1[3],
+ LeafNode *leaf1,
+ int st2[3],
+ LeafNode *leaf2,
+ int walkdir,
+ int inc,
+ int dir,
+ int side,
float alpha)
{
#ifdef IN_DEBUG_MODE
- dc_printf("Before patching.\n");
- printInfo(st1);
- printInfo(st2);
- dc_printf("-----------------%d %d %d; %d %d %d\n", st1[0], st2[1], st1[2], st2[0], st2[1], st2[2]);
+ dc_printf("Before patching.\n");
+ printInfo(st1);
+ printInfo(st2);
+ dc_printf(
+ "-----------------%d %d %d; %d %d %d\n", st1[0], st2[1], st1[2], st2[0], st2[1], st2[2]);
#endif
- // Get edge index on each leaf
- int edgedir = (dir + (3 - walkdir)) % 3;
- int incdir = (dir + walkdir) % 3;
- int ind1 = (edgedir == 1 ? (dir + 3 - edgedir) % 3 - 1 : 2 - (dir + 3 - edgedir) % 3);
- int ind2 = (edgedir == 1 ? (incdir + 3 - edgedir) % 3 - 1 : 2 - (incdir + 3 - edgedir) % 3);
+ // Get edge index on each leaf
+ int edgedir = (dir + (3 - walkdir)) % 3;
+ int incdir = (dir + walkdir) % 3;
+ int ind1 = (edgedir == 1 ? (dir + 3 - edgedir) % 3 - 1 : 2 - (dir + 3 - edgedir) % 3);
+ int ind2 = (edgedir == 1 ? (incdir + 3 - edgedir) % 3 - 1 : 2 - (incdir + 3 - edgedir) % 3);
- int eind1 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 1 : 0) << ind2));
- int eind2 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 0 : 1) << ind2));
+ int eind1 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 1 : 0) << ind2));
+ int eind2 = ((edgedir << 2) | (side << ind1) | ((inc > 0 ? 0 : 1) << ind2));
#ifdef IN_DEBUG_MODE
- dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
- /*
- if(alpha < 0 || alpha > 1) {
- dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
- printInfo(st1);
- printInfo(st2);
- }
- */
+ dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
+ /*
+ if(alpha < 0 || alpha > 1) {
+ dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha);
+ printInfo(st1);
+ printInfo(st2);
+ }
+ */
#endif
- // Flip edge parity
- LeafNode *nleaf1 = flipEdge(leaf1, eind1, alpha);
- LeafNode *nleaf2 = flipEdge(leaf2, eind2, alpha);
-
- // Update parent link
- updateParent(node, len, st1, nleaf1);
- updateParent(node, len, st2, nleaf2);
- // updateParent(nleaf1, mindimen, st1);
- // updateParent(nleaf2, mindimen, st2);
-
- /*
- float m[3];
- dc_printf("Adding new point: %f %f %f\n", spt[0], spt[1], spt[2]);
- getMinimizer(leaf1, m);
- dc_printf("Cell %d now has minimizer %f %f %f\n", leaf1, m[0], m[1], m[2]);
- getMinimizer(leaf2, m);
- dc_printf("Cell %d now has minimizer %f %f %f\n", leaf2, m[0], m[1], m[2]);
- */
+ // Flip edge parity
+ LeafNode *nleaf1 = flipEdge(leaf1, eind1, alpha);
+ LeafNode *nleaf2 = flipEdge(leaf2, eind2, alpha);
+
+ // Update parent link
+ updateParent(node, len, st1, nleaf1);
+ updateParent(node, len, st2, nleaf2);
+ // updateParent(nleaf1, mindimen, st1);
+ // updateParent(nleaf2, mindimen, st2);
+
+ /*
+ float m[3];
+ dc_printf("Adding new point: %f %f %f\n", spt[0], spt[1], spt[2]);
+ getMinimizer(leaf1, m);
+ dc_printf("Cell %d now has minimizer %f %f %f\n", leaf1, m[0], m[1], m[2]);
+ getMinimizer(leaf2, m);
+ dc_printf("Cell %d now has minimizer %f %f %f\n", leaf2, m[0], m[1], m[2]);
+ */
#ifdef IN_DEBUG_MODE
- dc_printf("After patching.\n");
- printInfo(st1);
- printInfo(st2);
+ dc_printf("After patching.\n");
+ printInfo(st1);
+ printInfo(st2);
#endif
- return nleaf2;
+ return nleaf2;
}
-Node *Octree::locateCell(InternalNode *node, int st[3], int len, int ori[3], int dir, int side, Node *& rleaf, int rst[3], int& rlen)
+Node *Octree::locateCell(InternalNode *node,
+ int st[3],
+ int len,
+ int ori[3],
+ int dir,
+ int side,
+ Node *&rleaf,
+ int rst[3],
+ int &rlen)
{
#ifdef IN_DEBUG_MODE
- // dc_printf("Call to LOCATECELL with node ");
- // printNode(node);
+ // dc_printf("Call to LOCATECELL with node ");
+ // printNode(node);
#endif
- int i;
- len >>= 1;
- int ind = 0;
- for (i = 0; i < 3; i++) {
- ind <<= 1;
- if (i == dir && side == 1) {
- ind |= (ori[i] <= (st[i] + len) ? 0 : 1);
- }
- else {
- ind |= (ori[i] < (st[i] + len) ? 0 : 1);
- }
- }
+ int i;
+ len >>= 1;
+ int ind = 0;
+ for (i = 0; i < 3; i++) {
+ ind <<= 1;
+ if (i == dir && side == 1) {
+ ind |= (ori[i] <= (st[i] + len) ? 0 : 1);
+ }
+ else {
+ ind |= (ori[i] < (st[i] + len) ? 0 : 1);
+ }
+ }
#ifdef IN_DEBUG_MODE
- // dc_printf("In LOCATECELL index of ori(%d %d %d) with dir %d side %d in st(%d %d %d, %d) is: %d\n",
- // ori[0], ori[1], ori[2], dir, side, st[0], st[1], st[2], len, ind);
+ // dc_printf("In LOCATECELL index of ori(%d %d %d) with dir %d side %d in st(%d %d %d, %d) is: %d\n",
+ // ori[0], ori[1], ori[2], dir, side, st[0], st[1], st[2], len, ind);
#endif
- rst[0] = st[0] + vertmap[ind][0] * len;
- rst[1] = st[1] + vertmap[ind][1] * len;
- rst[2] = st[2] + vertmap[ind][2] * len;
-
- if (node->has_child(ind)) {
- int count = node->get_child_count(ind);
- Node *chd = node->get_child(count);
- if (node->is_child_leaf(ind)) {
- rleaf = chd;
- rlen = len;
- }
- else {
- // Recur
- node->set_child(count, locateCell(&chd->internal, rst, len, ori, dir, side, rleaf, rst, rlen));
- }
- }
- else {
- // Create a new child here
- if (len == mindimen) {
- LeafNode *chd = createLeaf(0);
- node = addChild(node, ind, (Node *)chd, 1);
- rleaf = (Node *)chd;
- rlen = len;
- }
- else {
- // Subdivide the empty cube
- InternalNode *chd = createInternal(0);
- node = addChild(node, ind,
- locateCell(chd, rst, len, ori, dir, side, rleaf, rst, rlen), 0);
- }
- }
+ rst[0] = st[0] + vertmap[ind][0] * len;
+ rst[1] = st[1] + vertmap[ind][1] * len;
+ rst[2] = st[2] + vertmap[ind][2] * len;
+
+ if (node->has_child(ind)) {
+ int count = node->get_child_count(ind);
+ Node *chd = node->get_child(count);
+ if (node->is_child_leaf(ind)) {
+ rleaf = chd;
+ rlen = len;
+ }
+ else {
+ // Recur
+ node->set_child(count,
+ locateCell(&chd->internal, rst, len, ori, dir, side, rleaf, rst, rlen));
+ }
+ }
+ else {
+ // Create a new child here
+ if (len == mindimen) {
+ LeafNode *chd = createLeaf(0);
+ node = addChild(node, ind, (Node *)chd, 1);
+ rleaf = (Node *)chd;
+ rlen = len;
+ }
+ else {
+ // Subdivide the empty cube
+ InternalNode *chd = createInternal(0);
+ node = addChild(node, ind, locateCell(chd, rst, len, ori, dir, side, rleaf, rst, rlen), 0);
+ }
+ }
#ifdef IN_DEBUG_MODE
- // dc_printf("Return from LOCATECELL with node ");
- // printNode(newnode);
+ // dc_printf("Return from LOCATECELL with node ");
+ // printNode(newnode);
#endif
- return (Node *)node;
+ return (Node *)node;
}
void Octree::checkElement(PathElement * /*ele*/)
{
- /*
- if(ele != NULL && locateLeafCheck(ele->pos) != ele->node) {
- dc_printf("Screwed! at pos: %d %d %d\n", ele->pos[0]>>minshift, ele->pos[1]>>minshift, ele->pos[2]>>minshift);
- exit(0);
- }
- */
+ /*
+ if(ele != NULL && locateLeafCheck(ele->pos) != ele->node) {
+ dc_printf("Screwed! at pos: %d %d %d\n", ele->pos[0]>>minshift, ele->pos[1]>>minshift, ele->pos[2]>>minshift);
+ exit(0);
+ }
+ */
}
void Octree::checkPath(PathElement *path)
{
- PathElement *n = path;
- int same = 0;
- while (n && (same == 0 || n != path)) {
- same++;
- checkElement(n);
- n = n->next;
- }
-
+ PathElement *n = path;
+ int same = 0;
+ while (n && (same == 0 || n != path)) {
+ same++;
+ checkElement(n);
+ n = n->next;
+ }
}
void Octree::testFacePoint(PathElement *e1, PathElement *e2)
{
- int i;
- PathElement *e = NULL;
- for (i = 0; i < 3; i++) {
- if (e1->pos[i] != e2->pos[i]) {
- if (e1->pos[i] < e2->pos[i]) {
- e = e2;
- }
- else {
- e = e1;
- }
- break;
- }
- }
-
- int x, y;
- float p, q;
- dc_printf("Test.");
- getFacePoint(e, i, x, y, p, q);
+ int i;
+ PathElement *e = NULL;
+ for (i = 0; i < 3; i++) {
+ if (e1->pos[i] != e2->pos[i]) {
+ if (e1->pos[i] < e2->pos[i]) {
+ e = e2;
+ }
+ else {
+ e = e1;
+ }
+ break;
+ }
+ }
+
+ int x, y;
+ float p, q;
+ dc_printf("Test.");
+ getFacePoint(e, i, x, y, p, q);
}
-void Octree::getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q)
+void Octree::getFacePoint(PathElement *leaf, int dir, int &x, int &y, float &p, float &q)
{
- // Find average intersections
- float avg[3] = {0, 0, 0};
- float off[3];
- int num = 0, num2 = 0;
-
- LeafNode *leafnode = locateLeaf(leaf->pos);
- for (int i = 0; i < 4; i++) {
- int edgeind = faceMap[dir * 2][i];
- int nst[3];
- for (int j = 0; j < 3; j++) {
- nst[j] = leaf->pos[j] + mindimen * vertmap[edgemap[edgeind][0]][j];
- }
-
- if (getEdgeIntersectionByIndex(nst, edgeind / 4, off, 1)) {
- avg[0] += off[0];
- avg[1] += off[1];
- avg[2] += off[2];
- num++;
- }
- if (getEdgeParity(leafnode, edgeind)) {
- num2++;
- }
- }
- if (num == 0) {
- dc_printf("Wrong! dir: %d pos: %d %d %d num: %d\n", dir, leaf->pos[0] >> minshift, leaf->pos[1] >> minshift, leaf->pos[2] >> minshift, num2);
- avg[0] = (float) leaf->pos[0];
- avg[1] = (float) leaf->pos[1];
- avg[2] = (float) leaf->pos[2];
- }
- else {
-
- avg[0] /= num;
- avg[1] /= num;
- avg[2] /= num;
-
- //avg[0] =(float) leaf->pos[0];
- //avg[1] =(float) leaf->pos[1];
- //avg[2] =(float) leaf->pos[2];
- }
-
- int xdir = (dir + 1) % 3;
- int ydir = (dir + 2) % 3;
-
- float xf = avg[xdir];
- float yf = avg[ydir];
+ // Find average intersections
+ float avg[3] = {0, 0, 0};
+ float off[3];
+ int num = 0, num2 = 0;
+
+ LeafNode *leafnode = locateLeaf(leaf->pos);
+ for (int i = 0; i < 4; i++) {
+ int edgeind = faceMap[dir * 2][i];
+ int nst[3];
+ for (int j = 0; j < 3; j++) {
+ nst[j] = leaf->pos[j] + mindimen * vertmap[edgemap[edgeind][0]][j];
+ }
+
+ if (getEdgeIntersectionByIndex(nst, edgeind / 4, off, 1)) {
+ avg[0] += off[0];
+ avg[1] += off[1];
+ avg[2] += off[2];
+ num++;
+ }
+ if (getEdgeParity(leafnode, edgeind)) {
+ num2++;
+ }
+ }
+ if (num == 0) {
+ dc_printf("Wrong! dir: %d pos: %d %d %d num: %d\n",
+ dir,
+ leaf->pos[0] >> minshift,
+ leaf->pos[1] >> minshift,
+ leaf->pos[2] >> minshift,
+ num2);
+ avg[0] = (float)leaf->pos[0];
+ avg[1] = (float)leaf->pos[1];
+ avg[2] = (float)leaf->pos[2];
+ }
+ else {
+
+ avg[0] /= num;
+ avg[1] /= num;
+ avg[2] /= num;
+
+ //avg[0] =(float) leaf->pos[0];
+ //avg[1] =(float) leaf->pos[1];
+ //avg[2] =(float) leaf->pos[2];
+ }
+
+ int xdir = (dir + 1) % 3;
+ int ydir = (dir + 2) % 3;
+
+ float xf = avg[xdir];
+ float yf = avg[ydir];
#ifdef IN_DEBUG_MODE
- // Is it outside?
- // PathElement* leaf = leaf1->len < leaf2->len ? leaf1 : leaf2;
- /*
- float* m =(leaf == leaf1 ? m1 : m2);
- if(xf < leaf->pos[xdir] ||
- yf < leaf->pos[ydir] ||
- xf > leaf->pos[xdir] + leaf->len ||
- yf > leaf->pos[ydir] + leaf->len) {
- dc_printf("Outside cube(%d %d %d), %d : %d %d %f %f\n", leaf->pos[0], leaf->pos[1], leaf->pos[2], leaf->len,
- pos, dir, xf, yf);
-
- // For now, snap to cell
- xf = m[xdir];
- yf = m[ydir];
- }
- */
-
- /*
- if(alpha < 0 || alpha > 1 ||
- xf < leaf->pos[xdir] || xf > leaf->pos[xdir] + leaf->len ||
- yf < leaf->pos[ydir] || yf > leaf->pos[ydir] + leaf->len) {
- dc_printf("Alpha: %f Address: %d and %d\n", alpha, leaf1->node, leaf2->node);
- dc_printf("GETFACEPOINT result:(%d %d %d) %d min:(%f %f %f);(%d %d %d) %d min:(%f %f %f).\n",
- leaf1->pos[0], leaf1->pos[1], leaf1->pos[2], leaf1->len, m1[0], m1[1], m1[2],
- leaf2->pos[0], leaf2->pos[1], leaf2->pos[2], leaf2->len, m2[0], m2[1], m2[2]);
- dc_printf("Face point at dir %d pos %d: %f %f\n", dir, pos, xf, yf);
- }
- */
+ // Is it outside?
+ // PathElement* leaf = leaf1->len < leaf2->len ? leaf1 : leaf2;
+ /*
+ float* m =(leaf == leaf1 ? m1 : m2);
+ if(xf < leaf->pos[xdir] ||
+ yf < leaf->pos[ydir] ||
+ xf > leaf->pos[xdir] + leaf->len ||
+ yf > leaf->pos[ydir] + leaf->len) {
+ dc_printf("Outside cube(%d %d %d), %d : %d %d %f %f\n", leaf->pos[0], leaf->pos[1], leaf->pos[2], leaf->len,
+ pos, dir, xf, yf);
+
+ // For now, snap to cell
+ xf = m[xdir];
+ yf = m[ydir];
+ }
+ */
+
+ /*
+ if(alpha < 0 || alpha > 1 ||
+ xf < leaf->pos[xdir] || xf > leaf->pos[xdir] + leaf->len ||
+ yf < leaf->pos[ydir] || yf > leaf->pos[ydir] + leaf->len) {
+ dc_printf("Alpha: %f Address: %d and %d\n", alpha, leaf1->node, leaf2->node);
+ dc_printf("GETFACEPOINT result:(%d %d %d) %d min:(%f %f %f);(%d %d %d) %d min:(%f %f %f).\n",
+ leaf1->pos[0], leaf1->pos[1], leaf1->pos[2], leaf1->len, m1[0], m1[1], m1[2],
+ leaf2->pos[0], leaf2->pos[1], leaf2->pos[2], leaf2->len, m2[0], m2[1], m2[2]);
+ dc_printf("Face point at dir %d pos %d: %f %f\n", dir, pos, xf, yf);
+ }
+ */
#endif
+ // Get the integer and float part
+ x = ((leaf->pos[xdir]) >> minshift);
+ y = ((leaf->pos[ydir]) >> minshift);
- // Get the integer and float part
- x = ((leaf->pos[xdir]) >> minshift);
- y = ((leaf->pos[ydir]) >> minshift);
-
- p = (xf - leaf->pos[xdir]) / mindimen;
- q = (yf - leaf->pos[ydir]) / mindimen;
-
+ p = (xf - leaf->pos[xdir]) / mindimen;
+ q = (yf - leaf->pos[ydir]) / mindimen;
#ifdef IN_DEBUG_MODE
- dc_printf("Face point at dir %d : %f %f\n", dir, xf, yf);
+ dc_printf("Face point at dir %d : %f %f\n", dir, xf, yf);
#endif
}
-int Octree::findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2)
+int Octree::findPair(PathElement *head, int pos, int dir, PathElement *&pre1, PathElement *&pre2)
{
- int side = getSide(head, pos, dir);
- PathElement *cur = head;
- PathElement *anchor;
- PathElement *ppre1, *ppre2;
-
- // Start from this face, find a pair
- anchor = cur;
- ppre1 = cur;
- cur = cur->next;
- while (cur != anchor && (getSide(cur, pos, dir) == side)) {
- ppre1 = cur;
- cur = cur->next;
- }
- if (cur == anchor) {
- // No pair found
- return side;
- }
-
- side = getSide(cur, pos, dir);
- ppre2 = cur;
- cur = cur->next;
- while (getSide(cur, pos, dir) == side) {
- ppre2 = cur;
- cur = cur->next;
- }
-
-
- // Switch pre1 and pre2 if we start from the higher side
- if (side == -1) {
- cur = ppre1;
- ppre1 = ppre2;
- ppre2 = cur;
- }
-
- pre1 = ppre1;
- pre2 = ppre2;
-
- return 0;
+ int side = getSide(head, pos, dir);
+ PathElement *cur = head;
+ PathElement *anchor;
+ PathElement *ppre1, *ppre2;
+
+ // Start from this face, find a pair
+ anchor = cur;
+ ppre1 = cur;
+ cur = cur->next;
+ while (cur != anchor && (getSide(cur, pos, dir) == side)) {
+ ppre1 = cur;
+ cur = cur->next;
+ }
+ if (cur == anchor) {
+ // No pair found
+ return side;
+ }
+
+ side = getSide(cur, pos, dir);
+ ppre2 = cur;
+ cur = cur->next;
+ while (getSide(cur, pos, dir) == side) {
+ ppre2 = cur;
+ cur = cur->next;
+ }
+
+ // Switch pre1 and pre2 if we start from the higher side
+ if (side == -1) {
+ cur = ppre1;
+ ppre1 = ppre2;
+ ppre2 = cur;
+ }
+
+ pre1 = ppre1;
+ pre2 = ppre2;
+
+ return 0;
}
int Octree::getSide(PathElement *e, int pos, int dir)
{
- return (e->pos[dir] < pos ? -1 : 1);
+ return (e->pos[dir] < pos ? -1 : 1);
}
int Octree::isEqual(PathElement *e1, PathElement *e2)
{
- return (e1->pos[0] == e2->pos[0] && e1->pos[1] == e2->pos[1] && e1->pos[2] == e2->pos[2]);
+ return (e1->pos[0] == e2->pos[0] && e1->pos[1] == e2->pos[1] && e1->pos[2] == e2->pos[2]);
}
-void Octree::compressRing(PathElement *& ring)
+void Octree::compressRing(PathElement *&ring)
{
- if (ring == NULL) {
- return;
- }
+ if (ring == NULL) {
+ return;
+ }
#ifdef IN_DEBUG_MODE
- dc_printf("Call to COMPRESSRING with path: \n");
- printPath(ring);
+ dc_printf("Call to COMPRESSRING with path: \n");
+ printPath(ring);
#endif
- PathElement *cur = ring->next->next;
- PathElement *pre = ring->next;
- PathElement *prepre = ring;
- PathElement *anchor = prepre;
-
- do {
- while (isEqual(cur, prepre)) {
- // Delete
- if (cur == prepre) {
- // The ring has shrinked to a point
- delete pre;
- delete cur;
- anchor = NULL;
- break;
- }
- else {
- prepre->next = cur->next;
- delete pre;
- delete cur;
- pre = prepre->next;
- cur = pre->next;
- anchor = prepre;
- }
- }
-
- if (anchor == NULL) {
- break;
- }
-
- prepre = pre;
- pre = cur;
- cur = cur->next;
- } while (prepre != anchor);
-
- ring = anchor;
+ PathElement *cur = ring->next->next;
+ PathElement *pre = ring->next;
+ PathElement *prepre = ring;
+ PathElement *anchor = prepre;
+
+ do {
+ while (isEqual(cur, prepre)) {
+ // Delete
+ if (cur == prepre) {
+ // The ring has shrinked to a point
+ delete pre;
+ delete cur;
+ anchor = NULL;
+ break;
+ }
+ else {
+ prepre->next = cur->next;
+ delete pre;
+ delete cur;
+ pre = prepre->next;
+ cur = pre->next;
+ anchor = prepre;
+ }
+ }
+
+ if (anchor == NULL) {
+ break;
+ }
+
+ prepre = pre;
+ pre = cur;
+ cur = cur->next;
+ } while (prepre != anchor);
+
+ ring = anchor;
#ifdef IN_DEBUG_MODE
- dc_printf("Return from COMPRESSRING with path: \n");
- printPath(ring);
+ dc_printf("Return from COMPRESSRING with path: \n");
+ printPath(ring);
#endif
}
void Octree::buildSigns()
{
- // First build a lookup table
- // dc_printf("Building up look up table...\n");
- int size = 1 << 12;
- unsigned char table[1 << 12];
- for (int i = 0; i < size; i++) {
- table[i] = 0;
- }
- for (int i = 0; i < 256; i++) {
- int ind = 0;
- for (int j = 11; j >= 0; j--) {
- ind <<= 1;
- if (((i >> edgemap[j][0]) & 1) ^ ((i >> edgemap[j][1]) & 1)) {
- ind |= 1;
- }
- }
-
- table[ind] = i;
- }
-
- // Next, traverse the grid
- int sg = 1;
- int cube[8];
- buildSigns(table, root, 0, sg, cube);
+ // First build a lookup table
+ // dc_printf("Building up look up table...\n");
+ int size = 1 << 12;
+ unsigned char table[1 << 12];
+ for (int i = 0; i < size; i++) {
+ table[i] = 0;
+ }
+ for (int i = 0; i < 256; i++) {
+ int ind = 0;
+ for (int j = 11; j >= 0; j--) {
+ ind <<= 1;
+ if (((i >> edgemap[j][0]) & 1) ^ ((i >> edgemap[j][1]) & 1)) {
+ ind |= 1;
+ }
+ }
+
+ table[ind] = i;
+ }
+
+ // Next, traverse the grid
+ int sg = 1;
+ int cube[8];
+ buildSigns(table, root, 0, sg, cube);
}
void Octree::buildSigns(unsigned char table[], Node *node, int isLeaf, int sg, int rvalue[8])
{
- if (node == NULL) {
- for (int i = 0; i < 8; i++) {
- rvalue[i] = sg;
- }
- return;
- }
-
- if (isLeaf == 0) {
- // Internal node
- Node *chd[8];
- int leaf[8];
- node->internal.fill_children(chd, leaf);
-
- // Get the signs at the corners of the first cube
- rvalue[0] = sg;
- int oris[8];
- buildSigns(table, chd[0], leaf[0], sg, oris);
-
- // Get the rest
- int cube[8];
- for (int i = 1; i < 8; i++) {
- buildSigns(table, chd[i], leaf[i], oris[i], cube);
- rvalue[i] = cube[i];
- }
-
- }
- else {
- // Leaf node
- generateSigns(&node->leaf, table, sg);
-
- for (int i = 0; i < 8; i++) {
- rvalue[i] = getSign(&node->leaf, i);
- }
- }
+ if (node == NULL) {
+ for (int i = 0; i < 8; i++) {
+ rvalue[i] = sg;
+ }
+ return;
+ }
+
+ if (isLeaf == 0) {
+ // Internal node
+ Node *chd[8];
+ int leaf[8];
+ node->internal.fill_children(chd, leaf);
+
+ // Get the signs at the corners of the first cube
+ rvalue[0] = sg;
+ int oris[8];
+ buildSigns(table, chd[0], leaf[0], sg, oris);
+
+ // Get the rest
+ int cube[8];
+ for (int i = 1; i < 8; i++) {
+ buildSigns(table, chd[i], leaf[i], oris[i], cube);
+ rvalue[i] = cube[i];
+ }
+ }
+ else {
+ // Leaf node
+ generateSigns(&node->leaf, table, sg);
+
+ for (int i = 0; i < 8; i++) {
+ rvalue[i] = getSign(&node->leaf, i);
+ }
+ }
}
void Octree::floodFill()
{
- // int threshold =(int)((dimen/mindimen) *(dimen/mindimen) * 0.5f);
- int st[3] = {0, 0, 0};
-
- // First, check for largest component
- // size stored in -threshold
- clearProcessBits(root, maxDepth);
- int threshold = floodFill(root, st, dimen, maxDepth, 0);
-
- // Next remove
- dc_printf("Largest component: %d\n", threshold);
- threshold *= thresh;
- dc_printf("Removing all components smaller than %d\n", threshold);
-
- int st2[3] = {0, 0, 0};
- clearProcessBits(root, maxDepth);
- floodFill(root, st2, dimen, maxDepth, threshold);
-
+ // int threshold =(int)((dimen/mindimen) *(dimen/mindimen) * 0.5f);
+ int st[3] = {0, 0, 0};
+
+ // First, check for largest component
+ // size stored in -threshold
+ clearProcessBits(root, maxDepth);
+ int threshold = floodFill(root, st, dimen, maxDepth, 0);
+
+ // Next remove
+ dc_printf("Largest component: %d\n", threshold);
+ threshold *= thresh;
+ dc_printf("Removing all components smaller than %d\n", threshold);
+
+ int st2[3] = {0, 0, 0};
+ clearProcessBits(root, maxDepth);
+ floodFill(root, st2, dimen, maxDepth, threshold);
}
void Octree::clearProcessBits(Node *node, int height)
{
- int i;
-
- if (height == 0) {
- // Leaf cell,
- for (i = 0; i < 12; i++) {
- setOutProcess(&node->leaf, i);
- }
- }
- else {
- // Internal cell, recur
- int count = 0;
- for (i = 0; i < 8; i++) {
- if (node->internal.has_child(i)) {
- clearProcessBits(node->internal.get_child(count), height - 1);
- count++;
- }
- }
- }
+ int i;
+
+ if (height == 0) {
+ // Leaf cell,
+ for (i = 0; i < 12; i++) {
+ setOutProcess(&node->leaf, i);
+ }
+ }
+ else {
+ // Internal cell, recur
+ int count = 0;
+ for (i = 0; i < 8; i++) {
+ if (node->internal.has_child(i)) {
+ clearProcessBits(node->internal.get_child(count), height - 1);
+ count++;
+ }
+ }
+ }
}
int Octree::floodFill(LeafNode *leaf, int st[3], int len, int /*height*/, int threshold)
{
- int i, j;
- int maxtotal = 0;
-
- // Leaf cell,
- int par, inp;
-
- // Test if the leaf has intersection edges
- for (i = 0; i < 12; i++) {
- par = getEdgeParity(leaf, i);
- inp = isInProcess(leaf, i);
-
- if (par == 1 && inp == 0) {
- // Intersection edge, hasn't been processed
- // Let's start filling
- GridQueue *queue = new GridQueue();
- int total = 1;
-
- // Set to in process
- int mst[3];
- mst[0] = st[0] + vertmap[edgemap[i][0]][0] * len;
- mst[1] = st[1] + vertmap[edgemap[i][0]][1] * len;
- mst[2] = st[2] + vertmap[edgemap[i][0]][2] * len;
- int mdir = i / 4;
- setInProcessAll(mst, mdir);
-
- // Put this edge into queue
- queue->pushQueue(mst, mdir);
-
- // Queue processing
- int nst[3], dir;
- while (queue->popQueue(nst, dir) == 1) {
- // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
- // locations
- int stMask[3][3] = {
- {0, 0 - len, 0 - len},
- {0 - len, 0, 0 - len},
- {0 - len, 0 - len, 0}
- };
- int cst[2][3];
- for (j = 0; j < 3; j++) {
- cst[0][j] = nst[j];
- cst[1][j] = nst[j] + stMask[dir][j];
- }
-
- // cells
- LeafNode *cs[2];
- for (j = 0; j < 2; j++) {
- cs[j] = locateLeaf(cst[j]);
- }
-
- // Middle sign
- int s = getSign(cs[0], 0);
-
- // Masks
- int fcCells[4] = {1, 0, 1, 0};
- int fcEdges[3][4][3] = {
- {{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
- {{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
- {{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}
- };
-
- // Search for neighboring connected intersection edges
- for (int find = 0; find < 4; find++) {
- int cind = fcCells[find];
- int eind, edge;
- if (s == 0) {
- // Original order
- for (eind = 0; eind < 3; eind++) {
- edge = fcEdges[dir][find][eind];
- if (getEdgeParity(cs[cind], edge) == 1) {
- break;
- }
- }
- }
- else {
- // Inverse order
- for (eind = 2; eind >= 0; eind--) {
- edge = fcEdges[dir][find][eind];
- if (getEdgeParity(cs[cind], edge) == 1) {
- break;
- }
- }
- }
-
- if (eind == 3 || eind == -1) {
- dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
- }
- else {
- int est[3];
- est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
- est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
- est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
- int edir = edge / 4;
-
- if (isInProcess(cs[cind], edge) == 0) {
- setInProcessAll(est, edir);
- queue->pushQueue(est, edir);
- // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
- total++;
- }
- }
- }
- }
-
- dc_printf("Size of component: %d ", total);
-
- if (threshold == 0) {
- // Measuring stage
- if (total > maxtotal) {
- maxtotal = total;
- }
- dc_printf(".\n");
- delete queue;
- continue;
- }
-
- if (total >= threshold) {
- dc_printf("Maintained.\n");
- delete queue;
- continue;
- }
- dc_printf("Less then %d, removing...\n", threshold);
-
- // We have to remove this noise
-
- // Flip parity
- // setOutProcessAll(mst, mdir);
- flipParityAll(mst, mdir);
-
- // Put this edge into queue
- queue->pushQueue(mst, mdir);
-
- // Queue processing
- while (queue->popQueue(nst, dir) == 1) {
- // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
- // locations
- int stMask[3][3] = {
- {0, 0 - len, 0 - len},
- {0 - len, 0, 0 - len},
- {0 - len, 0 - len, 0}
- };
- int cst[2][3];
- for (j = 0; j < 3; j++) {
- cst[0][j] = nst[j];
- cst[1][j] = nst[j] + stMask[dir][j];
- }
-
- // cells
- LeafNode *cs[2];
- for (j = 0; j < 2; j++)
- cs[j] = locateLeaf(cst[j]);
-
- // Middle sign
- int s = getSign(cs[0], 0);
-
- // Masks
- int fcCells[4] = {1, 0, 1, 0};
- int fcEdges[3][4][3] = {
- {{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
- {{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
- {{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}
- };
-
- // Search for neighboring connected intersection edges
- for (int find = 0; find < 4; find++) {
- int cind = fcCells[find];
- int eind, edge;
- if (s == 0) {
- // Original order
- for (eind = 0; eind < 3; eind++) {
- edge = fcEdges[dir][find][eind];
- if (isInProcess(cs[cind], edge) == 1) {
- break;
- }
- }
- }
- else {
- // Inverse order
- for (eind = 2; eind >= 0; eind--) {
- edge = fcEdges[dir][find][eind];
- if (isInProcess(cs[cind], edge) == 1) {
- break;
- }
- }
- }
-
- if (eind == 3 || eind == -1) {
- dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
- }
- else {
- int est[3];
- est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
- est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
- est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
- int edir = edge / 4;
-
- if (getEdgeParity(cs[cind], edge) == 1) {
- flipParityAll(est, edir);
- queue->pushQueue(est, edir);
- // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
- total++;
- }
- }
- }
- }
-
- delete queue;
- }
- }
-
- return maxtotal;
+ int i, j;
+ int maxtotal = 0;
+
+ // Leaf cell,
+ int par, inp;
+
+ // Test if the leaf has intersection edges
+ for (i = 0; i < 12; i++) {
+ par = getEdgeParity(leaf, i);
+ inp = isInProcess(leaf, i);
+
+ if (par == 1 && inp == 0) {
+ // Intersection edge, hasn't been processed
+ // Let's start filling
+ GridQueue *queue = new GridQueue();
+ int total = 1;
+
+ // Set to in process
+ int mst[3];
+ mst[0] = st[0] + vertmap[edgemap[i][0]][0] * len;
+ mst[1] = st[1] + vertmap[edgemap[i][0]][1] * len;
+ mst[2] = st[2] + vertmap[edgemap[i][0]][2] * len;
+ int mdir = i / 4;
+ setInProcessAll(mst, mdir);
+
+ // Put this edge into queue
+ queue->pushQueue(mst, mdir);
+
+ // Queue processing
+ int nst[3], dir;
+ while (queue->popQueue(nst, dir) == 1) {
+ // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
+ // locations
+ int stMask[3][3] = {{0, 0 - len, 0 - len}, {0 - len, 0, 0 - len}, {0 - len, 0 - len, 0}};
+ int cst[2][3];
+ for (j = 0; j < 3; j++) {
+ cst[0][j] = nst[j];
+ cst[1][j] = nst[j] + stMask[dir][j];
+ }
+
+ // cells
+ LeafNode *cs[2];
+ for (j = 0; j < 2; j++) {
+ cs[j] = locateLeaf(cst[j]);
+ }
+
+ // Middle sign
+ int s = getSign(cs[0], 0);
+
+ // Masks
+ int fcCells[4] = {1, 0, 1, 0};
+ int fcEdges[3][4][3] = {{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
+ {{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
+ {{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}};
+
+ // Search for neighboring connected intersection edges
+ for (int find = 0; find < 4; find++) {
+ int cind = fcCells[find];
+ int eind, edge;
+ if (s == 0) {
+ // Original order
+ for (eind = 0; eind < 3; eind++) {
+ edge = fcEdges[dir][find][eind];
+ if (getEdgeParity(cs[cind], edge) == 1) {
+ break;
+ }
+ }
+ }
+ else {
+ // Inverse order
+ for (eind = 2; eind >= 0; eind--) {
+ edge = fcEdges[dir][find][eind];
+ if (getEdgeParity(cs[cind], edge) == 1) {
+ break;
+ }
+ }
+ }
+
+ if (eind == 3 || eind == -1) {
+ dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
+ }
+ else {
+ int est[3];
+ est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
+ est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
+ est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
+ int edir = edge / 4;
+
+ if (isInProcess(cs[cind], edge) == 0) {
+ setInProcessAll(est, edir);
+ queue->pushQueue(est, edir);
+ // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
+ total++;
+ }
+ }
+ }
+ }
+
+ dc_printf("Size of component: %d ", total);
+
+ if (threshold == 0) {
+ // Measuring stage
+ if (total > maxtotal) {
+ maxtotal = total;
+ }
+ dc_printf(".\n");
+ delete queue;
+ continue;
+ }
+
+ if (total >= threshold) {
+ dc_printf("Maintained.\n");
+ delete queue;
+ continue;
+ }
+ dc_printf("Less then %d, removing...\n", threshold);
+
+ // We have to remove this noise
+
+ // Flip parity
+ // setOutProcessAll(mst, mdir);
+ flipParityAll(mst, mdir);
+
+ // Put this edge into queue
+ queue->pushQueue(mst, mdir);
+
+ // Queue processing
+ while (queue->popQueue(nst, dir) == 1) {
+ // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir);
+ // locations
+ int stMask[3][3] = {{0, 0 - len, 0 - len}, {0 - len, 0, 0 - len}, {0 - len, 0 - len, 0}};
+ int cst[2][3];
+ for (j = 0; j < 3; j++) {
+ cst[0][j] = nst[j];
+ cst[1][j] = nst[j] + stMask[dir][j];
+ }
+
+ // cells
+ LeafNode *cs[2];
+ for (j = 0; j < 2; j++)
+ cs[j] = locateLeaf(cst[j]);
+
+ // Middle sign
+ int s = getSign(cs[0], 0);
+
+ // Masks
+ int fcCells[4] = {1, 0, 1, 0};
+ int fcEdges[3][4][3] = {{{9, 2, 11}, {8, 1, 10}, {5, 1, 7}, {4, 2, 6}},
+ {{10, 6, 11}, {8, 5, 9}, {1, 5, 3}, {0, 6, 2}},
+ {{6, 10, 7}, {4, 9, 5}, {2, 9, 3}, {0, 10, 1}}};
+
+ // Search for neighboring connected intersection edges
+ for (int find = 0; find < 4; find++) {
+ int cind = fcCells[find];
+ int eind, edge;
+ if (s == 0) {
+ // Original order
+ for (eind = 0; eind < 3; eind++) {
+ edge = fcEdges[dir][find][eind];
+ if (isInProcess(cs[cind], edge) == 1) {
+ break;
+ }
+ }
+ }
+ else {
+ // Inverse order
+ for (eind = 2; eind >= 0; eind--) {
+ edge = fcEdges[dir][find][eind];
+ if (isInProcess(cs[cind], edge) == 1) {
+ break;
+ }
+ }
+ }
+
+ if (eind == 3 || eind == -1) {
+ dc_printf("Wrong! this is not a consistent sign. %d\n", eind);
+ }
+ else {
+ int est[3];
+ est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len;
+ est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len;
+ est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len;
+ int edir = edge / 4;
+
+ if (getEdgeParity(cs[cind], edge) == 1) {
+ flipParityAll(est, edir);
+ queue->pushQueue(est, edir);
+ // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir);
+ total++;
+ }
+ }
+ }
+ }
+
+ delete queue;
+ }
+ }
+
+ return maxtotal;
}
int Octree::floodFill(Node *node, int st[3], int len, int height, int threshold)
{
- int i;
- int maxtotal = 0;
-
- if (height == 0) {
- maxtotal = floodFill(&node->leaf, st, len, height, threshold);
- }
- else {
- // Internal cell, recur
- int count = 0;
- len >>= 1;
- for (i = 0; i < 8; i++) {
- if (node->internal.has_child(i)) {
- int nst[3];
- nst[0] = st[0] + vertmap[i][0] * len;
- nst[1] = st[1] + vertmap[i][1] * len;
- nst[2] = st[2] + vertmap[i][2] * len;
-
- int d = floodFill(node->internal.get_child(count), nst, len, height - 1, threshold);
- if (d > maxtotal) {
- maxtotal = d;
- }
- count++;
- }
- }
- }
-
-
- return maxtotal;
-
+ int i;
+ int maxtotal = 0;
+
+ if (height == 0) {
+ maxtotal = floodFill(&node->leaf, st, len, height, threshold);
+ }
+ else {
+ // Internal cell, recur
+ int count = 0;
+ len >>= 1;
+ for (i = 0; i < 8; i++) {
+ if (node->internal.has_child(i)) {
+ int nst[3];
+ nst[0] = st[0] + vertmap[i][0] * len;
+ nst[1] = st[1] + vertmap[i][1] * len;
+ nst[2] = st[2] + vertmap[i][2] * len;
+
+ int d = floodFill(node->internal.get_child(count), nst, len, height - 1, threshold);
+ if (d > maxtotal) {
+ maxtotal = d;
+ }
+ count++;
+ }
+ }
+ }
+
+ return maxtotal;
}
void Octree::writeOut()
{
- int numQuads = 0;
- int numVertices = 0;
- int numEdges = 0;
+ int numQuads = 0;
+ int numVertices = 0;
+ int numEdges = 0;
- countIntersection(root, maxDepth, numQuads, numVertices, numEdges);
+ countIntersection(root, maxDepth, numQuads, numVertices, numEdges);
- dc_printf("Vertices counted: %d Polys counted: %d \n", numVertices, numQuads);
- output_mesh = alloc_output(numVertices, numQuads);
- int offset = 0;
- int st[3] = {0, 0, 0};
+ dc_printf("Vertices counted: %d Polys counted: %d \n", numVertices, numQuads);
+ output_mesh = alloc_output(numVertices, numQuads);
+ int offset = 0;
+ int st[3] = {0, 0, 0};
- // First, output vertices
- offset = 0;
- actualVerts = 0;
- actualQuads = 0;
+ // First, output vertices
+ offset = 0;
+ actualVerts = 0;
+ actualQuads = 0;
- generateMinimizer(root, st, dimen, maxDepth, offset);
- cellProcContour(root, 0, maxDepth);
- dc_printf("Vertices written: %d Quads written: %d \n", offset, actualQuads);
+ generateMinimizer(root, st, dimen, maxDepth, offset);
+ cellProcContour(root, 0, maxDepth);
+ dc_printf("Vertices written: %d Quads written: %d \n", offset, actualQuads);
}
-void Octree::countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface)
+void Octree::countIntersection(Node *node, int height, int &nedge, int &ncell, int &nface)
{
- if (height > 0) {
- int total = node->internal.get_num_children();
- for (int i = 0; i < total; i++) {
- countIntersection(node->internal.get_child(i), height - 1, nedge, ncell, nface);
- }
- }
- else {
- nedge += getNumEdges2(&node->leaf);
-
- int smask = getSignMask(&node->leaf);
-
- if (use_manifold) {
- int comps = manifold_table[smask].comps;
- ncell += comps;
- }
- else {
- if (smask > 0 && smask < 255) {
- ncell++;
- }
- }
-
- for (int i = 0; i < 3; i++) {
- if (getFaceEdgeNum(&node->leaf, i * 2)) {
- nface++;
- }
- }
- }
+ if (height > 0) {
+ int total = node->internal.get_num_children();
+ for (int i = 0; i < total; i++) {
+ countIntersection(node->internal.get_child(i), height - 1, nedge, ncell, nface);
+ }
+ }
+ else {
+ nedge += getNumEdges2(&node->leaf);
+
+ int smask = getSignMask(&node->leaf);
+
+ if (use_manifold) {
+ int comps = manifold_table[smask].comps;
+ ncell += comps;
+ }
+ else {
+ if (smask > 0 && smask < 255) {
+ ncell++;
+ }
+ }
+
+ for (int i = 0; i < 3; i++) {
+ if (getFaceEdgeNum(&node->leaf, i * 2)) {
+ nface++;
+ }
+ }
+ }
}
/* from http://eigen.tuxfamily.org/bz/show_bug.cgi?id=257 */
@@ -2099,751 +2121,713 @@ void pseudoInverse(const _Matrix_Type_ &a,
_Matrix_Type_ &result,
double epsilon = std::numeric_limits<typename _Matrix_Type_::Scalar>::epsilon())
{
- Eigen::JacobiSVD< _Matrix_Type_ > svd = a.jacobiSvd(Eigen::ComputeFullU |
- Eigen::ComputeFullV);
-
- typename _Matrix_Type_::Scalar tolerance = epsilon * std::max(a.cols(),
- a.rows()) *
- svd.singularValues().array().abs().maxCoeff();
-
- result = svd.matrixV() *
- _Matrix_Type_((svd.singularValues().array().abs() >
- tolerance).select(svd.singularValues().
- array().inverse(), 0)).asDiagonal() *
- svd.matrixU().adjoint();
+ Eigen::JacobiSVD<_Matrix_Type_> svd = a.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
+
+ typename _Matrix_Type_::Scalar tolerance = epsilon * std::max(a.cols(), a.rows()) *
+ svd.singularValues().array().abs().maxCoeff();
+
+ result = svd.matrixV() *
+ _Matrix_Type_((svd.singularValues().array().abs() > tolerance)
+ .select(svd.singularValues().array().inverse(), 0))
+ .asDiagonal() *
+ svd.matrixU().adjoint();
}
-static void solve_least_squares(const float halfA[], const float b[],
- const float midpoint[], float rvalue[])
+static void solve_least_squares(const float halfA[],
+ const float b[],
+ const float midpoint[],
+ float rvalue[])
{
- /* calculate pseudo-inverse */
- Eigen::MatrixXf A(3, 3), pinv(3, 3);
- A << halfA[0], halfA[1], halfA[2],
- halfA[1], halfA[3], halfA[4],
- halfA[2], halfA[4], halfA[5];
- pseudoInverse(A, pinv);
-
- Eigen::Vector3f b2(b), mp(midpoint), result;
- b2 = b2 + A * -mp;
- result = pinv * b2 + mp;
-
- for (int i = 0; i < 3; i++)
- rvalue[i] = result(i);
+ /* calculate pseudo-inverse */
+ Eigen::MatrixXf A(3, 3), pinv(3, 3);
+ A << halfA[0], halfA[1], halfA[2], halfA[1], halfA[3], halfA[4], halfA[2], halfA[4], halfA[5];
+ pseudoInverse(A, pinv);
+
+ Eigen::Vector3f b2(b), mp(midpoint), result;
+ b2 = b2 + A * -mp;
+ result = pinv * b2 + mp;
+
+ for (int i = 0; i < 3; i++)
+ rvalue[i] = result(i);
}
static void mass_point(float mp[3], const float pts[12][3], const int parity[12])
{
- int ec = 0;
-
- for (int i = 0; i < 12; i++) {
- if (parity[i]) {
- const float *p = pts[i];
-
- mp[0] += p[0];
- mp[1] += p[1];
- mp[2] += p[2];
-
- ec++;
- }
- }
-
- if (ec == 0) {
- return;
- }
- mp[0] /= ec;
- mp[1] /= ec;
- mp[2] /= ec;
+ int ec = 0;
+
+ for (int i = 0; i < 12; i++) {
+ if (parity[i]) {
+ const float *p = pts[i];
+
+ mp[0] += p[0];
+ mp[1] += p[1];
+ mp[2] += p[2];
+
+ ec++;
+ }
+ }
+
+ if (ec == 0) {
+ return;
+ }
+ mp[0] /= ec;
+ mp[1] /= ec;
+ mp[2] /= ec;
}
-static void minimize(float rvalue[3], float mp[3], const float pts[12][3],
- const float norms[12][3], const int parity[12])
+static void minimize(float rvalue[3],
+ float mp[3],
+ const float pts[12][3],
+ const float norms[12][3],
+ const int parity[12])
{
- float ata[6] = {0, 0, 0, 0, 0, 0};
- float atb[3] = {0, 0, 0};
- int ec = 0;
-
- for (int i = 0; i < 12; i++) {
- // if(getEdgeParity(leaf, i))
- if (parity[i]) {
- const float *norm = norms[i];
- const float *p = pts[i];
-
- // QEF
- ata[0] += (float)(norm[0] * norm[0]);
- ata[1] += (float)(norm[0] * norm[1]);
- ata[2] += (float)(norm[0] * norm[2]);
- ata[3] += (float)(norm[1] * norm[1]);
- ata[4] += (float)(norm[1] * norm[2]);
- ata[5] += (float)(norm[2] * norm[2]);
-
- const float pn = p[0] * norm[0] + p[1] * norm[1] + p[2] * norm[2];
-
- atb[0] += (float)(norm[0] * pn);
- atb[1] += (float)(norm[1] * pn);
- atb[2] += (float)(norm[2] * pn);
-
- // Minimizer
- mp[0] += p[0];
- mp[1] += p[1];
- mp[2] += p[2];
-
- ec++;
- }
- }
-
- if (ec == 0) {
- return;
- }
- mp[0] /= ec;
- mp[1] /= ec;
- mp[2] /= ec;
-
- // Solve least squares
- solve_least_squares(ata, atb, mp, rvalue);
+ float ata[6] = {0, 0, 0, 0, 0, 0};
+ float atb[3] = {0, 0, 0};
+ int ec = 0;
+
+ for (int i = 0; i < 12; i++) {
+ // if(getEdgeParity(leaf, i))
+ if (parity[i]) {
+ const float *norm = norms[i];
+ const float *p = pts[i];
+
+ // QEF
+ ata[0] += (float)(norm[0] * norm[0]);
+ ata[1] += (float)(norm[0] * norm[1]);
+ ata[2] += (float)(norm[0] * norm[2]);
+ ata[3] += (float)(norm[1] * norm[1]);
+ ata[4] += (float)(norm[1] * norm[2]);
+ ata[5] += (float)(norm[2] * norm[2]);
+
+ const float pn = p[0] * norm[0] + p[1] * norm[1] + p[2] * norm[2];
+
+ atb[0] += (float)(norm[0] * pn);
+ atb[1] += (float)(norm[1] * pn);
+ atb[2] += (float)(norm[2] * pn);
+
+ // Minimizer
+ mp[0] += p[0];
+ mp[1] += p[1];
+ mp[2] += p[2];
+
+ ec++;
+ }
+ }
+
+ if (ec == 0) {
+ return;
+ }
+ mp[0] /= ec;
+ mp[1] /= ec;
+ mp[2] /= ec;
+
+ // Solve least squares
+ solve_least_squares(ata, atb, mp, rvalue);
}
-void Octree::computeMinimizer(const LeafNode *leaf, int st[3], int len,
- float rvalue[3]) const
+void Octree::computeMinimizer(const LeafNode *leaf, int st[3], int len, float rvalue[3]) const
{
- // First, gather all edge intersections
- float pts[12][3], norms[12][3];
- int parity[12];
- fillEdgeIntersections(leaf, st, len, pts, norms, parity);
-
- switch (mode) {
- case DUALCON_CENTROID:
- rvalue[0] = (float) st[0] + len / 2;
- rvalue[1] = (float) st[1] + len / 2;
- rvalue[2] = (float) st[2] + len / 2;
- break;
-
- case DUALCON_MASS_POINT:
- rvalue[0] = rvalue[1] = rvalue[2] = 0;
- mass_point(rvalue, pts, parity);
- break;
-
- default: {
- // Sharp features */
-
- // construct QEF and minimizer
- float mp[3] = {0, 0, 0};
- minimize(rvalue, mp, pts, norms, parity);
-
- /* Restraining the location of the minimizer */
- float nh1 = hermite_num * len;
- float nh2 = (1 + hermite_num) * len;
-
- if (rvalue[0] < st[0] - nh1 ||
- rvalue[1] < st[1] - nh1 ||
- rvalue[2] < st[2] - nh1 ||
-
- rvalue[0] > st[0] + nh2 ||
- rvalue[1] > st[1] + nh2 ||
- rvalue[2] > st[2] + nh2)
- {
- // Use mass point instead
- rvalue[0] = mp[0];
- rvalue[1] = mp[1];
- rvalue[2] = mp[2];
- }
- break;
- }
- }
+ // First, gather all edge intersections
+ float pts[12][3], norms[12][3];
+ int parity[12];
+ fillEdgeIntersections(leaf, st, len, pts, norms, parity);
+
+ switch (mode) {
+ case DUALCON_CENTROID:
+ rvalue[0] = (float)st[0] + len / 2;
+ rvalue[1] = (float)st[1] + len / 2;
+ rvalue[2] = (float)st[2] + len / 2;
+ break;
+
+ case DUALCON_MASS_POINT:
+ rvalue[0] = rvalue[1] = rvalue[2] = 0;
+ mass_point(rvalue, pts, parity);
+ break;
+
+ default: {
+ // Sharp features */
+
+ // construct QEF and minimizer
+ float mp[3] = {0, 0, 0};
+ minimize(rvalue, mp, pts, norms, parity);
+
+ /* Restraining the location of the minimizer */
+ float nh1 = hermite_num * len;
+ float nh2 = (1 + hermite_num) * len;
+
+ if (rvalue[0] < st[0] - nh1 || rvalue[1] < st[1] - nh1 || rvalue[2] < st[2] - nh1 ||
+
+ rvalue[0] > st[0] + nh2 || rvalue[1] > st[1] + nh2 || rvalue[2] > st[2] + nh2) {
+ // Use mass point instead
+ rvalue[0] = mp[0];
+ rvalue[1] = mp[1];
+ rvalue[2] = mp[2];
+ }
+ break;
+ }
+ }
}
-void Octree::generateMinimizer(Node *node, int st[3], int len, int height, int& offset)
+void Octree::generateMinimizer(Node *node, int st[3], int len, int height, int &offset)
{
- int i, j;
-
- if (height == 0) {
- // Leaf cell, generate
-
- // First, find minimizer
- float rvalue[3];
- rvalue[0] = (float) st[0] + len / 2;
- rvalue[1] = (float) st[1] + len / 2;
- rvalue[2] = (float) st[2] + len / 2;
- computeMinimizer(&node->leaf, st, len, rvalue);
-
- // Update
- //float fnst[3];
- for (j = 0; j < 3; j++) {
- rvalue[j] = rvalue[j] * range / dimen + origin[j];
- //fnst[j] = st[j] * range / dimen + origin[j];
- }
-
- int mult = 0, smask = getSignMask(&node->leaf);
-
- if (use_manifold) {
- mult = manifold_table[smask].comps;
- }
- else {
- if (smask > 0 && smask < 255) {
- mult = 1;
- }
- }
-
- for (j = 0; j < mult; j++) {
- add_vert(output_mesh, rvalue);
- }
-
- // Store the index
- setMinimizerIndex(&node->leaf, offset);
-
- offset += mult;
- }
- else {
- // Internal cell, recur
- int count = 0;
- len >>= 1;
- for (i = 0; i < 8; i++) {
- if (node->internal.has_child(i)) {
- int nst[3];
- nst[0] = st[0] + vertmap[i][0] * len;
- nst[1] = st[1] + vertmap[i][1] * len;
- nst[2] = st[2] + vertmap[i][2] * len;
-
- generateMinimizer(node->internal.get_child(count),
- nst, len, height - 1, offset);
- count++;
- }
- }
- }
+ int i, j;
+
+ if (height == 0) {
+ // Leaf cell, generate
+
+ // First, find minimizer
+ float rvalue[3];
+ rvalue[0] = (float)st[0] + len / 2;
+ rvalue[1] = (float)st[1] + len / 2;
+ rvalue[2] = (float)st[2] + len / 2;
+ computeMinimizer(&node->leaf, st, len, rvalue);
+
+ // Update
+ //float fnst[3];
+ for (j = 0; j < 3; j++) {
+ rvalue[j] = rvalue[j] * range / dimen + origin[j];
+ //fnst[j] = st[j] * range / dimen + origin[j];
+ }
+
+ int mult = 0, smask = getSignMask(&node->leaf);
+
+ if (use_manifold) {
+ mult = manifold_table[smask].comps;
+ }
+ else {
+ if (smask > 0 && smask < 255) {
+ mult = 1;
+ }
+ }
+
+ for (j = 0; j < mult; j++) {
+ add_vert(output_mesh, rvalue);
+ }
+
+ // Store the index
+ setMinimizerIndex(&node->leaf, offset);
+
+ offset += mult;
+ }
+ else {
+ // Internal cell, recur
+ int count = 0;
+ len >>= 1;
+ for (i = 0; i < 8; i++) {
+ if (node->internal.has_child(i)) {
+ int nst[3];
+ nst[0] = st[0] + vertmap[i][0] * len;
+ nst[1] = st[1] + vertmap[i][1] * len;
+ nst[2] = st[2] + vertmap[i][2] * len;
+
+ generateMinimizer(node->internal.get_child(count), nst, len, height - 1, offset);
+ count++;
+ }
+ }
+ }
}
void Octree::processEdgeWrite(Node *node[4], int /*depth*/[4], int /*maxdep*/, int dir)
{
- //int color = 0;
-
- int i = 3;
- {
- if (getEdgeParity((LeafNode *)(node[i]), processEdgeMask[dir][i])) {
- int flip = 0;
- int edgeind = processEdgeMask[dir][i];
- if (getSign((LeafNode *)node[i], edgemap[edgeind][1]) > 0) {
- flip = 1;
- }
-
- int num = 0;
- {
- int ind[8];
- if (use_manifold) {
- int vind[2];
- int seq[4] = {0, 1, 3, 2};
- for (int k = 0; k < 4; k++) {
- getMinimizerIndices((LeafNode *)(node[seq[k]]), processEdgeMask[dir][seq[k]], vind);
- ind[num] = vind[0];
- num++;
-
- if (vind[1] != -1) {
- ind[num] = vind[1];
- num++;
- if (flip == 0) {
- ind[num - 1] = vind[0];
- ind[num - 2] = vind[1];
- }
- }
- }
-
- /* we don't use the manifold option, but if it is
- ever enabled again note that it can output
- non-quads */
- }
- else {
- if (flip) {
- ind[0] = getMinimizerIndex((LeafNode *)(node[2]));
- ind[1] = getMinimizerIndex((LeafNode *)(node[3]));
- ind[2] = getMinimizerIndex((LeafNode *)(node[1]));
- ind[3] = getMinimizerIndex((LeafNode *)(node[0]));
- }
- else {
- ind[0] = getMinimizerIndex((LeafNode *)(node[0]));
- ind[1] = getMinimizerIndex((LeafNode *)(node[1]));
- ind[2] = getMinimizerIndex((LeafNode *)(node[3]));
- ind[3] = getMinimizerIndex((LeafNode *)(node[2]));
- }
-
- add_quad(output_mesh, ind);
- }
- }
- return;
- }
- else {
- return;
- }
- }
+ //int color = 0;
+
+ int i = 3;
+ {
+ if (getEdgeParity((LeafNode *)(node[i]), processEdgeMask[dir][i])) {
+ int flip = 0;
+ int edgeind = processEdgeMask[dir][i];
+ if (getSign((LeafNode *)node[i], edgemap[edgeind][1]) > 0) {
+ flip = 1;
+ }
+
+ int num = 0;
+ {
+ int ind[8];
+ if (use_manifold) {
+ int vind[2];
+ int seq[4] = {0, 1, 3, 2};
+ for (int k = 0; k < 4; k++) {
+ getMinimizerIndices((LeafNode *)(node[seq[k]]), processEdgeMask[dir][seq[k]], vind);
+ ind[num] = vind[0];
+ num++;
+
+ if (vind[1] != -1) {
+ ind[num] = vind[1];
+ num++;
+ if (flip == 0) {
+ ind[num - 1] = vind[0];
+ ind[num - 2] = vind[1];
+ }
+ }
+ }
+
+ /* we don't use the manifold option, but if it is
+ ever enabled again note that it can output
+ non-quads */
+ }
+ else {
+ if (flip) {
+ ind[0] = getMinimizerIndex((LeafNode *)(node[2]));
+ ind[1] = getMinimizerIndex((LeafNode *)(node[3]));
+ ind[2] = getMinimizerIndex((LeafNode *)(node[1]));
+ ind[3] = getMinimizerIndex((LeafNode *)(node[0]));
+ }
+ else {
+ ind[0] = getMinimizerIndex((LeafNode *)(node[0]));
+ ind[1] = getMinimizerIndex((LeafNode *)(node[1]));
+ ind[2] = getMinimizerIndex((LeafNode *)(node[3]));
+ ind[3] = getMinimizerIndex((LeafNode *)(node[2]));
+ }
+
+ add_quad(output_mesh, ind);
+ }
+ }
+ return;
+ }
+ else {
+ return;
+ }
+ }
}
-
void Octree::edgeProcContour(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir)
{
- if (!(node[0] && node[1] && node[2] && node[3])) {
- return;
- }
- if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
- processEdgeWrite(node, depth, maxdep, dir);
- }
- else {
- int i, j;
- Node *chd[4][8];
- for (j = 0; j < 4; j++) {
- for (i = 0; i < 8; i++) {
- chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
- node[j]->internal.get_child(
- node[j]->internal.get_child_count(i)) : NULL;
- }
- }
-
- // 2 edge calls
- Node *ne[4];
- int le[4];
- int de[4];
- for (i = 0; i < 2; i++) {
- int c[4] = {edgeProcEdgeMask[dir][i][0],
- edgeProcEdgeMask[dir][i][1],
- edgeProcEdgeMask[dir][i][2],
- edgeProcEdgeMask[dir][i][3]};
-
- for (int j = 0; j < 4; j++) {
- if (leaf[j]) {
- le[j] = leaf[j];
- ne[j] = node[j];
- de[j] = depth[j];
- }
- else {
- le[j] = node[j]->internal.is_child_leaf(c[j]);
- ne[j] = chd[j][c[j]];
- de[j] = depth[j] - 1;
- }
- }
-
- edgeProcContour(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
- }
-
- }
+ if (!(node[0] && node[1] && node[2] && node[3])) {
+ return;
+ }
+ if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
+ processEdgeWrite(node, depth, maxdep, dir);
+ }
+ else {
+ int i, j;
+ Node *chd[4][8];
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 8; i++) {
+ chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
+ node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
+ NULL;
+ }
+ }
+
+ // 2 edge calls
+ Node *ne[4];
+ int le[4];
+ int de[4];
+ for (i = 0; i < 2; i++) {
+ int c[4] = {edgeProcEdgeMask[dir][i][0],
+ edgeProcEdgeMask[dir][i][1],
+ edgeProcEdgeMask[dir][i][2],
+ edgeProcEdgeMask[dir][i][3]};
+
+ for (int j = 0; j < 4; j++) {
+ if (leaf[j]) {
+ le[j] = leaf[j];
+ ne[j] = node[j];
+ de[j] = depth[j];
+ }
+ else {
+ le[j] = node[j]->internal.is_child_leaf(c[j]);
+ ne[j] = chd[j][c[j]];
+ de[j] = depth[j] - 1;
+ }
+ }
+
+ edgeProcContour(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
+ }
+ }
}
void Octree::faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir)
{
- if (!(node[0] && node[1])) {
- return;
- }
-
- if (!(leaf[0] && leaf[1])) {
- int i, j;
- // Fill children nodes
- Node *chd[2][8];
- for (j = 0; j < 2; j++) {
- for (i = 0; i < 8; i++) {
- chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
- node[j]->internal.get_child(
- node[j]->internal.get_child_count(i)) : NULL;
- }
- }
-
- // 4 face calls
- Node *nf[2];
- int df[2];
- int lf[2];
- for (i = 0; i < 4; i++) {
- int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
- for (int j = 0; j < 2; j++) {
- if (leaf[j]) {
- lf[j] = leaf[j];
- nf[j] = node[j];
- df[j] = depth[j];
- }
- else {
- lf[j] = node[j]->internal.is_child_leaf(c[j]);
- nf[j] = chd[j][c[j]];
- df[j] = depth[j] - 1;
- }
- }
- faceProcContour(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
- }
-
- // 4 edge calls
- int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
- Node *ne[4];
- int le[4];
- int de[4];
-
- for (i = 0; i < 4; i++) {
- int c[4] = {faceProcEdgeMask[dir][i][1], faceProcEdgeMask[dir][i][2],
- faceProcEdgeMask[dir][i][3], faceProcEdgeMask[dir][i][4]};
- int *order = orders[faceProcEdgeMask[dir][i][0]];
-
- for (int j = 0; j < 4; j++) {
- if (leaf[order[j]]) {
- le[j] = leaf[order[j]];
- ne[j] = node[order[j]];
- de[j] = depth[order[j]];
- }
- else {
- le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
- ne[j] = chd[order[j]][c[j]];
- de[j] = depth[order[j]] - 1;
- }
- }
-
- edgeProcContour(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
- }
- }
+ if (!(node[0] && node[1])) {
+ return;
+ }
+
+ if (!(leaf[0] && leaf[1])) {
+ int i, j;
+ // Fill children nodes
+ Node *chd[2][8];
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 8; i++) {
+ chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
+ node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
+ NULL;
+ }
+ }
+
+ // 4 face calls
+ Node *nf[2];
+ int df[2];
+ int lf[2];
+ for (i = 0; i < 4; i++) {
+ int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
+ for (int j = 0; j < 2; j++) {
+ if (leaf[j]) {
+ lf[j] = leaf[j];
+ nf[j] = node[j];
+ df[j] = depth[j];
+ }
+ else {
+ lf[j] = node[j]->internal.is_child_leaf(c[j]);
+ nf[j] = chd[j][c[j]];
+ df[j] = depth[j] - 1;
+ }
+ }
+ faceProcContour(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
+ }
+
+ // 4 edge calls
+ int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
+ Node *ne[4];
+ int le[4];
+ int de[4];
+
+ for (i = 0; i < 4; i++) {
+ int c[4] = {faceProcEdgeMask[dir][i][1],
+ faceProcEdgeMask[dir][i][2],
+ faceProcEdgeMask[dir][i][3],
+ faceProcEdgeMask[dir][i][4]};
+ int *order = orders[faceProcEdgeMask[dir][i][0]];
+
+ for (int j = 0; j < 4; j++) {
+ if (leaf[order[j]]) {
+ le[j] = leaf[order[j]];
+ ne[j] = node[order[j]];
+ de[j] = depth[order[j]];
+ }
+ else {
+ le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
+ ne[j] = chd[order[j]][c[j]];
+ de[j] = depth[order[j]] - 1;
+ }
+ }
+
+ edgeProcContour(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
+ }
+ }
}
-
void Octree::cellProcContour(Node *node, int leaf, int depth)
{
- if (node == NULL) {
- return;
- }
-
- if (!leaf) {
- int i;
-
- // Fill children nodes
- Node *chd[8];
- for (i = 0; i < 8; i++) {
- chd[i] = ((!leaf) && node->internal.has_child(i)) ?
- node->internal.get_child(node->internal.get_child_count(i)) : NULL;
- }
-
- // 8 Cell calls
- for (i = 0; i < 8; i++) {
- cellProcContour(chd[i], node->internal.is_child_leaf(i), depth - 1);
- }
-
- // 12 face calls
- Node *nf[2];
- int lf[2];
- int df[2] = {depth - 1, depth - 1};
- for (i = 0; i < 12; i++) {
- int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
-
- lf[0] = node->internal.is_child_leaf(c[0]);
- lf[1] = node->internal.is_child_leaf(c[1]);
-
- nf[0] = chd[c[0]];
- nf[1] = chd[c[1]];
-
- faceProcContour(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
- }
-
- // 6 edge calls
- Node *ne[4];
- int le[4];
- int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
- for (i = 0; i < 6; i++) {
- int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
-
- for (int j = 0; j < 4; j++) {
- le[j] = node->internal.is_child_leaf(c[j]);
- ne[j] = chd[c[j]];
- }
-
- edgeProcContour(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
- }
- }
-
+ if (node == NULL) {
+ return;
+ }
+
+ if (!leaf) {
+ int i;
+
+ // Fill children nodes
+ Node *chd[8];
+ for (i = 0; i < 8; i++) {
+ chd[i] = ((!leaf) && node->internal.has_child(i)) ?
+ node->internal.get_child(node->internal.get_child_count(i)) :
+ NULL;
+ }
+
+ // 8 Cell calls
+ for (i = 0; i < 8; i++) {
+ cellProcContour(chd[i], node->internal.is_child_leaf(i), depth - 1);
+ }
+
+ // 12 face calls
+ Node *nf[2];
+ int lf[2];
+ int df[2] = {depth - 1, depth - 1};
+ for (i = 0; i < 12; i++) {
+ int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
+
+ lf[0] = node->internal.is_child_leaf(c[0]);
+ lf[1] = node->internal.is_child_leaf(c[1]);
+
+ nf[0] = chd[c[0]];
+ nf[1] = chd[c[1]];
+
+ faceProcContour(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
+ }
+
+ // 6 edge calls
+ Node *ne[4];
+ int le[4];
+ int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
+ for (i = 0; i < 6; i++) {
+ int c[4] = {cellProcEdgeMask[i][0],
+ cellProcEdgeMask[i][1],
+ cellProcEdgeMask[i][2],
+ cellProcEdgeMask[i][3]};
+
+ for (int j = 0; j < 4; j++) {
+ le[j] = node->internal.is_child_leaf(c[j]);
+ ne[j] = chd[c[j]];
+ }
+
+ edgeProcContour(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
+ }
+ }
}
void Octree::processEdgeParity(LeafNode *node[4], int /*depth*/[4], int /*maxdep*/, int dir)
{
- int con = 0;
- for (int i = 0; i < 4; i++) {
- // Minimal cell
- // if(op == 0)
- {
- if (getEdgeParity(node[i], processEdgeMask[dir][i])) {
- con = 1;
- break;
- }
- }
- }
-
- if (con == 1) {
- for (int i = 0; i < 4; i++) {
- setEdge(node[i], processEdgeMask[dir][i]);
- }
- }
-
+ int con = 0;
+ for (int i = 0; i < 4; i++) {
+ // Minimal cell
+ // if(op == 0)
+ {
+ if (getEdgeParity(node[i], processEdgeMask[dir][i])) {
+ con = 1;
+ break;
+ }
+ }
+ }
+
+ if (con == 1) {
+ for (int i = 0; i < 4; i++) {
+ setEdge(node[i], processEdgeMask[dir][i]);
+ }
+ }
}
void Octree::edgeProcParity(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir)
{
- if (!(node[0] && node[1] && node[2] && node[3])) {
- return;
- }
- if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
- processEdgeParity((LeafNode **)node, depth, maxdep, dir);
- }
- else {
- int i, j;
- Node *chd[4][8];
- for (j = 0; j < 4; j++) {
- for (i = 0; i < 8; i++) {
- chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
- node[j]->internal.get_child( node[j]->internal.get_child_count(i)) : NULL;
- }
- }
-
- // 2 edge calls
- Node *ne[4];
- int le[4];
- int de[4];
- for (i = 0; i < 2; i++) {
- int c[4] = {edgeProcEdgeMask[dir][i][0],
- edgeProcEdgeMask[dir][i][1],
- edgeProcEdgeMask[dir][i][2],
- edgeProcEdgeMask[dir][i][3]};
-
- // int allleaf = 1;
- for (int j = 0; j < 4; j++) {
-
- if (leaf[j]) {
- le[j] = leaf[j];
- ne[j] = node[j];
- de[j] = depth[j];
- }
- else {
- le[j] = node[j]->internal.is_child_leaf(c[j]);
- ne[j] = chd[j][c[j]];
- de[j] = depth[j] - 1;
-
- }
-
- }
-
- edgeProcParity(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
- }
-
- }
+ if (!(node[0] && node[1] && node[2] && node[3])) {
+ return;
+ }
+ if (leaf[0] && leaf[1] && leaf[2] && leaf[3]) {
+ processEdgeParity((LeafNode **)node, depth, maxdep, dir);
+ }
+ else {
+ int i, j;
+ Node *chd[4][8];
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 8; i++) {
+ chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
+ node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
+ NULL;
+ }
+ }
+
+ // 2 edge calls
+ Node *ne[4];
+ int le[4];
+ int de[4];
+ for (i = 0; i < 2; i++) {
+ int c[4] = {edgeProcEdgeMask[dir][i][0],
+ edgeProcEdgeMask[dir][i][1],
+ edgeProcEdgeMask[dir][i][2],
+ edgeProcEdgeMask[dir][i][3]};
+
+ // int allleaf = 1;
+ for (int j = 0; j < 4; j++) {
+
+ if (leaf[j]) {
+ le[j] = leaf[j];
+ ne[j] = node[j];
+ de[j] = depth[j];
+ }
+ else {
+ le[j] = node[j]->internal.is_child_leaf(c[j]);
+ ne[j] = chd[j][c[j]];
+ de[j] = depth[j] - 1;
+ }
+ }
+
+ edgeProcParity(ne, le, de, maxdep - 1, edgeProcEdgeMask[dir][i][4]);
+ }
+ }
}
void Octree::faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir)
{
- if (!(node[0] && node[1])) {
- return;
- }
-
- if (!(leaf[0] && leaf[1])) {
- int i, j;
- // Fill children nodes
- Node *chd[2][8];
- for (j = 0; j < 2; j++) {
- for (i = 0; i < 8; i++) {
- chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
- node[j]->internal.get_child(
- node[j]->internal.get_child_count(i)) : NULL;
- }
- }
-
- // 4 face calls
- Node *nf[2];
- int df[2];
- int lf[2];
- for (i = 0; i < 4; i++) {
- int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
- for (int j = 0; j < 2; j++) {
- if (leaf[j]) {
- lf[j] = leaf[j];
- nf[j] = node[j];
- df[j] = depth[j];
- }
- else {
- lf[j] = node[j]->internal.is_child_leaf(c[j]);
- nf[j] = chd[j][c[j]];
- df[j] = depth[j] - 1;
- }
- }
- faceProcParity(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
- }
-
- // 4 edge calls
- int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
- Node *ne[4];
- int le[4];
- int de[4];
-
- for (i = 0; i < 4; i++) {
- int c[4] = {faceProcEdgeMask[dir][i][1], faceProcEdgeMask[dir][i][2],
- faceProcEdgeMask[dir][i][3], faceProcEdgeMask[dir][i][4]};
- int *order = orders[faceProcEdgeMask[dir][i][0]];
-
- for (int j = 0; j < 4; j++) {
- if (leaf[order[j]]) {
- le[j] = leaf[order[j]];
- ne[j] = node[order[j]];
- de[j] = depth[order[j]];
- }
- else {
- le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
- ne[j] = chd[order[j]][c[j]];
- de[j] = depth[order[j]] - 1;
- }
- }
-
- edgeProcParity(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
- }
- }
+ if (!(node[0] && node[1])) {
+ return;
+ }
+
+ if (!(leaf[0] && leaf[1])) {
+ int i, j;
+ // Fill children nodes
+ Node *chd[2][8];
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 8; i++) {
+ chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ?
+ node[j]->internal.get_child(node[j]->internal.get_child_count(i)) :
+ NULL;
+ }
+ }
+
+ // 4 face calls
+ Node *nf[2];
+ int df[2];
+ int lf[2];
+ for (i = 0; i < 4; i++) {
+ int c[2] = {faceProcFaceMask[dir][i][0], faceProcFaceMask[dir][i][1]};
+ for (int j = 0; j < 2; j++) {
+ if (leaf[j]) {
+ lf[j] = leaf[j];
+ nf[j] = node[j];
+ df[j] = depth[j];
+ }
+ else {
+ lf[j] = node[j]->internal.is_child_leaf(c[j]);
+ nf[j] = chd[j][c[j]];
+ df[j] = depth[j] - 1;
+ }
+ }
+ faceProcParity(nf, lf, df, maxdep - 1, faceProcFaceMask[dir][i][2]);
+ }
+
+ // 4 edge calls
+ int orders[2][4] = {{0, 0, 1, 1}, {0, 1, 0, 1}};
+ Node *ne[4];
+ int le[4];
+ int de[4];
+
+ for (i = 0; i < 4; i++) {
+ int c[4] = {faceProcEdgeMask[dir][i][1],
+ faceProcEdgeMask[dir][i][2],
+ faceProcEdgeMask[dir][i][3],
+ faceProcEdgeMask[dir][i][4]};
+ int *order = orders[faceProcEdgeMask[dir][i][0]];
+
+ for (int j = 0; j < 4; j++) {
+ if (leaf[order[j]]) {
+ le[j] = leaf[order[j]];
+ ne[j] = node[order[j]];
+ de[j] = depth[order[j]];
+ }
+ else {
+ le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
+ ne[j] = chd[order[j]][c[j]];
+ de[j] = depth[order[j]] - 1;
+ }
+ }
+
+ edgeProcParity(ne, le, de, maxdep - 1, faceProcEdgeMask[dir][i][5]);
+ }
+ }
}
-
void Octree::cellProcParity(Node *node, int leaf, int depth)
{
- if (node == NULL) {
- return;
- }
-
- if (!leaf) {
- int i;
-
- // Fill children nodes
- Node *chd[8];
- for (i = 0; i < 8; i++) {
- chd[i] = ((!leaf) && node->internal.has_child(i)) ?
- node->internal.get_child(node->internal.get_child_count(i)) : NULL;
- }
-
- // 8 Cell calls
- for (i = 0; i < 8; i++) {
- cellProcParity(chd[i], node->internal.is_child_leaf(i), depth - 1);
- }
-
- // 12 face calls
- Node *nf[2];
- int lf[2];
- int df[2] = {depth - 1, depth - 1};
- for (i = 0; i < 12; i++) {
- int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
-
- lf[0] = node->internal.is_child_leaf(c[0]);
- lf[1] = node->internal.is_child_leaf(c[1]);
-
- nf[0] = chd[c[0]];
- nf[1] = chd[c[1]];
-
- faceProcParity(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
- }
-
- // 6 edge calls
- Node *ne[4];
- int le[4];
- int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
- for (i = 0; i < 6; i++) {
- int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
-
- for (int j = 0; j < 4; j++) {
- le[j] = node->internal.is_child_leaf(c[j]);
- ne[j] = chd[c[j]];
- }
-
- edgeProcParity(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
- }
- }
-
+ if (node == NULL) {
+ return;
+ }
+
+ if (!leaf) {
+ int i;
+
+ // Fill children nodes
+ Node *chd[8];
+ for (i = 0; i < 8; i++) {
+ chd[i] = ((!leaf) && node->internal.has_child(i)) ?
+ node->internal.get_child(node->internal.get_child_count(i)) :
+ NULL;
+ }
+
+ // 8 Cell calls
+ for (i = 0; i < 8; i++) {
+ cellProcParity(chd[i], node->internal.is_child_leaf(i), depth - 1);
+ }
+
+ // 12 face calls
+ Node *nf[2];
+ int lf[2];
+ int df[2] = {depth - 1, depth - 1};
+ for (i = 0; i < 12; i++) {
+ int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
+
+ lf[0] = node->internal.is_child_leaf(c[0]);
+ lf[1] = node->internal.is_child_leaf(c[1]);
+
+ nf[0] = chd[c[0]];
+ nf[1] = chd[c[1]];
+
+ faceProcParity(nf, lf, df, depth - 1, cellProcFaceMask[i][2]);
+ }
+
+ // 6 edge calls
+ Node *ne[4];
+ int le[4];
+ int de[4] = {depth - 1, depth - 1, depth - 1, depth - 1};
+ for (i = 0; i < 6; i++) {
+ int c[4] = {cellProcEdgeMask[i][0],
+ cellProcEdgeMask[i][1],
+ cellProcEdgeMask[i][2],
+ cellProcEdgeMask[i][3]};
+
+ for (int j = 0; j < 4; j++) {
+ le[j] = node->internal.is_child_leaf(c[j]);
+ ne[j] = chd[c[j]];
+ }
+
+ edgeProcParity(ne, le, de, depth - 1, cellProcEdgeMask[i][4]);
+ }
+ }
}
/* definitions for global arrays */
const int edgemask[3] = {5, 3, 6};
const int faceMap[6][4] = {
- {4, 8, 5, 9},
- {6, 10, 7, 11},
- {0, 8, 1, 10},
- {2, 9, 3, 11},
- {0, 4, 2, 6},
- {1, 5, 3, 7},
+ {4, 8, 5, 9},
+ {6, 10, 7, 11},
+ {0, 8, 1, 10},
+ {2, 9, 3, 11},
+ {0, 4, 2, 6},
+ {1, 5, 3, 7},
};
const int cellProcFaceMask[12][3] = {
- {0, 4, 0},
- {1, 5, 0},
- {2, 6, 0},
- {3, 7, 0},
- {0, 2, 1},
- {4, 6, 1},
- {1, 3, 1},
- {5, 7, 1},
- {0, 1, 2},
- {2, 3, 2},
- {4, 5, 2},
- {6, 7, 2},
+ {0, 4, 0},
+ {1, 5, 0},
+ {2, 6, 0},
+ {3, 7, 0},
+ {0, 2, 1},
+ {4, 6, 1},
+ {1, 3, 1},
+ {5, 7, 1},
+ {0, 1, 2},
+ {2, 3, 2},
+ {4, 5, 2},
+ {6, 7, 2},
};
const int cellProcEdgeMask[6][5] = {
- {0, 1, 2, 3, 0},
- {4, 5, 6, 7, 0},
- {0, 4, 1, 5, 1},
- {2, 6, 3, 7, 1},
- {0, 2, 4, 6, 2},
- {1, 3, 5, 7, 2},
+ {0, 1, 2, 3, 0},
+ {4, 5, 6, 7, 0},
+ {0, 4, 1, 5, 1},
+ {2, 6, 3, 7, 1},
+ {0, 2, 4, 6, 2},
+ {1, 3, 5, 7, 2},
};
-const int faceProcFaceMask[3][4][3] = {
- {{4, 0, 0},
- {5, 1, 0},
- {6, 2, 0},
- {7, 3, 0}},
- {{2, 0, 1},
- {6, 4, 1},
- {3, 1, 1},
- {7, 5, 1}},
- {{1, 0, 2},
- {3, 2, 2},
- {5, 4, 2},
- {7, 6, 2}}
-};
+const int faceProcFaceMask[3][4][3] = {{{4, 0, 0}, {5, 1, 0}, {6, 2, 0}, {7, 3, 0}},
+ {{2, 0, 1}, {6, 4, 1}, {3, 1, 1}, {7, 5, 1}},
+ {{1, 0, 2}, {3, 2, 2}, {5, 4, 2}, {7, 6, 2}}};
const int faceProcEdgeMask[3][4][6] = {
- {{1, 4, 0, 5, 1, 1},
- {1, 6, 2, 7, 3, 1},
- {0, 4, 6, 0, 2, 2},
- {0, 5, 7, 1, 3, 2}},
- {{0, 2, 3, 0, 1, 0},
- {0, 6, 7, 4, 5, 0},
- {1, 2, 0, 6, 4, 2},
- {1, 3, 1, 7, 5, 2}},
- {{1, 1, 0, 3, 2, 0},
- {1, 5, 4, 7, 6, 0},
- {0, 1, 5, 0, 4, 1},
- {0, 3, 7, 2, 6, 1}}
-};
+ {{1, 4, 0, 5, 1, 1}, {1, 6, 2, 7, 3, 1}, {0, 4, 6, 0, 2, 2}, {0, 5, 7, 1, 3, 2}},
+ {{0, 2, 3, 0, 1, 0}, {0, 6, 7, 4, 5, 0}, {1, 2, 0, 6, 4, 2}, {1, 3, 1, 7, 5, 2}},
+ {{1, 1, 0, 3, 2, 0}, {1, 5, 4, 7, 6, 0}, {0, 1, 5, 0, 4, 1}, {0, 3, 7, 2, 6, 1}}};
const int edgeProcEdgeMask[3][2][5] = {
- {{3, 2, 1, 0, 0},
- {7, 6, 5, 4, 0}},
- {{5, 1, 4, 0, 1},
- {7, 3, 6, 2, 1}},
- {{6, 4, 2, 0, 2},
- {7, 5, 3, 1, 2}},
+ {{3, 2, 1, 0, 0}, {7, 6, 5, 4, 0}},
+ {{5, 1, 4, 0, 1}, {7, 3, 6, 2, 1}},
+ {{6, 4, 2, 0, 2}, {7, 5, 3, 1, 2}},
};
const int processEdgeMask[3][4] = {
- {3, 2, 1, 0},
- {7, 5, 6, 4},
- {11, 10, 9, 8},
+ {3, 2, 1, 0},
+ {7, 5, 6, 4},
+ {11, 10, 9, 8},
};
-const int dirCell[3][4][3] = {
- {{0, -1, -1},
- {0, -1, 0},
- {0, 0, -1},
- {0, 0, 0}},
- {{-1, 0, -1},
- {-1, 0, 0},
- {0, 0, -1},
- {0, 0, 0}},
- {{-1, -1, 0},
- {-1, 0, 0},
- {0, -1, 0},
- {0, 0, 0}}
-};
+const int dirCell[3][4][3] = {{{0, -1, -1}, {0, -1, 0}, {0, 0, -1}, {0, 0, 0}},
+ {{-1, 0, -1}, {-1, 0, 0}, {0, 0, -1}, {0, 0, 0}},
+ {{-1, -1, 0}, {-1, 0, 0}, {0, -1, 0}, {0, 0, 0}}};
const int dirEdge[3][4] = {
- {3, 2, 1, 0},
- {7, 6, 5, 4},
- {11, 10, 9, 8},
+ {3, 2, 1, 0},
+ {7, 6, 5, 4},
+ {11, 10, 9, 8},
};
int InternalNode::numChildrenTable[256];
diff --git a/intern/dualcon/intern/octree.h b/intern/dualcon/intern/octree.h
index 5075a5603b6..db945e36390 100644
--- a/intern/dualcon/intern/octree.h
+++ b/intern/dualcon/intern/octree.h
@@ -37,7 +37,6 @@
* @author Tao Ju
*/
-
/* Global defines */
// Uncomment to see debug information
// #define IN_DEBUG_MODE
@@ -53,98 +52,97 @@ union Node;
struct LeafNode;
struct InternalNode {
- /* Initialized in Octree::BuildTable */
- static int numChildrenTable[256];
- static int childrenCountTable[256][8];
- static int childrenIndexTable[256][8];
-
- /* Bit N indicates whether child N exists or not */
- unsigned char has_child_bitfield;
- /* Bit N indicates whether child N is a leaf or not */
- unsigned char child_is_leaf_bitfield;
-
- /* Can have up to eight children */
- Node *children[0];
-
- /// Test if child is leaf
- int is_child_leaf(int index) const
- {
- return (child_is_leaf_bitfield >> index) & 1;
- }
-
- /// If child index exists
- int has_child(int index) const
- {
- return (has_child_bitfield >> index) & 1;
- }
-
- /// Get the pointer to child index
- Node *get_child(int count)
- {
- return children[count];
- }
-
- const Node *get_child(int count) const
- {
- return children[count];
- }
-
- /// Get total number of children
- int get_num_children() const
- {
- return numChildrenTable[has_child_bitfield];
- }
-
- /// Get the count of children
- int get_child_count(int index) const
- {
- return childrenCountTable[has_child_bitfield][index];
- }
- int get_child_index(int count)
- {
- return childrenIndexTable[has_child_bitfield][count];
- }
- const int *get_child_counts() const
- {
- return childrenCountTable[has_child_bitfield];
- }
-
- /// Get all children
- void fill_children(Node *children[8], int leaf[8])
- {
- int count = 0;
- for (int i = 0; i < 8; i++) {
- leaf[i] = is_child_leaf(i);
- if (has_child(i)) {
- children[i] = get_child(count);
- count++;
- }
- else {
- children[i] = NULL;
- leaf[i] = 0;
- }
- }
- }
-
- /// Sets the child pointer
- void set_child(int count, Node *chd)
- {
- children[count] = chd;
- }
- void set_internal_child(int index, int count, InternalNode *chd)
- {
- set_child(count, (Node *)chd);
- has_child_bitfield |= (1 << index);
- }
- void set_leaf_child(int index, int count, LeafNode *chd)
- {
- set_child(count, (Node *)chd);
- has_child_bitfield |= (1 << index);
- child_is_leaf_bitfield |= (1 << index);
- }
+ /* Initialized in Octree::BuildTable */
+ static int numChildrenTable[256];
+ static int childrenCountTable[256][8];
+ static int childrenIndexTable[256][8];
+
+ /* Bit N indicates whether child N exists or not */
+ unsigned char has_child_bitfield;
+ /* Bit N indicates whether child N is a leaf or not */
+ unsigned char child_is_leaf_bitfield;
+
+ /* Can have up to eight children */
+ Node *children[0];
+
+ /// Test if child is leaf
+ int is_child_leaf(int index) const
+ {
+ return (child_is_leaf_bitfield >> index) & 1;
+ }
+
+ /// If child index exists
+ int has_child(int index) const
+ {
+ return (has_child_bitfield >> index) & 1;
+ }
+
+ /// Get the pointer to child index
+ Node *get_child(int count)
+ {
+ return children[count];
+ }
+
+ const Node *get_child(int count) const
+ {
+ return children[count];
+ }
+
+ /// Get total number of children
+ int get_num_children() const
+ {
+ return numChildrenTable[has_child_bitfield];
+ }
+
+ /// Get the count of children
+ int get_child_count(int index) const
+ {
+ return childrenCountTable[has_child_bitfield][index];
+ }
+ int get_child_index(int count)
+ {
+ return childrenIndexTable[has_child_bitfield][count];
+ }
+ const int *get_child_counts() const
+ {
+ return childrenCountTable[has_child_bitfield];
+ }
+
+ /// Get all children
+ void fill_children(Node *children[8], int leaf[8])
+ {
+ int count = 0;
+ for (int i = 0; i < 8; i++) {
+ leaf[i] = is_child_leaf(i);
+ if (has_child(i)) {
+ children[i] = get_child(count);
+ count++;
+ }
+ else {
+ children[i] = NULL;
+ leaf[i] = 0;
+ }
+ }
+ }
+
+ /// Sets the child pointer
+ void set_child(int count, Node *chd)
+ {
+ children[count] = chd;
+ }
+ void set_internal_child(int index, int count, InternalNode *chd)
+ {
+ set_child(count, (Node *)chd);
+ has_child_bitfield |= (1 << index);
+ }
+ void set_leaf_child(int index, int count, LeafNode *chd)
+ {
+ set_child(count, (Node *)chd);
+ has_child_bitfield |= (1 << index);
+ child_is_leaf_bitfield |= (1 << index);
+ }
};
-
/**
* Bits order
*
@@ -157,27 +155,27 @@ struct InternalNode {
* Byte 5: edge intersections(4 bytes per inter, or 12 bytes if USE_HERMIT)
*/
struct LeafNode /* TODO: remove this attribute once everything is fixed */ {
- unsigned short edge_parity : 12;
- unsigned short primary_edge_intersections : 3;
+ unsigned short edge_parity : 12;
+ unsigned short primary_edge_intersections : 3;
- /* XXX: maybe actually unused? */
- unsigned short in_process : 1;
+ /* XXX: maybe actually unused? */
+ unsigned short in_process : 1;
- /* bitfield */
- char signs;
+ /* bitfield */
+ char signs;
- int minimizer_index;
+ int minimizer_index;
- unsigned short flood_fill;
+ unsigned short flood_fill;
- float edge_intersections[0];
+ float edge_intersections[0];
};
/* Doesn't get directly allocated anywhere, just used for passing
pointers to nodes that could be internal or leaf. */
union Node {
- InternalNode internal;
- LeafNode leaf;
+ InternalNode internal;
+ LeafNode leaf;
};
/* Global variables */
@@ -197,1195 +195,1209 @@ extern const int dirEdge[3][4];
*/
struct PathElement {
- // Origin
- int pos[3];
+ // Origin
+ int pos[3];
- // link
- PathElement *next;
+ // link
+ PathElement *next;
};
struct PathList {
- // Head
- PathElement *head;
- PathElement *tail;
+ // Head
+ PathElement *head;
+ PathElement *tail;
- // Length of the list
- int length;
+ // Length of the list
+ int length;
- // Next list
- PathList *next;
+ // Next list
+ PathList *next;
};
-
/**
* Class for building and processing an octree
*/
-class Octree
-{
+class Octree {
public:
- /* Public members */
+ /* Public members */
- /// Memory allocators
- VirtualMemoryAllocator *alloc[9];
- VirtualMemoryAllocator *leafalloc[4];
+ /// Memory allocators
+ VirtualMemoryAllocator *alloc[9];
+ VirtualMemoryAllocator *leafalloc[4];
- /// Root node
- Node *root;
+ /// Root node
+ Node *root;
- /// Model reader
- ModelReader *reader;
+ /// Model reader
+ ModelReader *reader;
- /// Marching cubes table
- Cubes *cubes;
+ /// Marching cubes table
+ Cubes *cubes;
- /// Length of grid
- int dimen;
- int mindimen, minshift;
+ /// Length of grid
+ int dimen;
+ int mindimen, minshift;
- /// Maximum depth
- int maxDepth;
+ /// Maximum depth
+ int maxDepth;
- /// The lower corner of the bounding box and the size
- float origin[3];
- float range;
+ /// The lower corner of the bounding box and the size
+ float origin[3];
+ float range;
- /// Counting information
- int nodeCount;
- int nodeSpace;
- int nodeCounts[9];
+ /// Counting information
+ int nodeCount;
+ int nodeSpace;
+ int nodeCounts[9];
- int actualQuads, actualVerts;
+ int actualQuads, actualVerts;
- PathList *ringList;
+ PathList *ringList;
- int maxTrianglePerCell;
- int outType; // 0 for OFF, 1 for PLY, 2 for VOL
+ int maxTrianglePerCell;
+ int outType; // 0 for OFF, 1 for PLY, 2 for VOL
- // For flood filling
- int use_flood_fill;
- float thresh;
+ // For flood filling
+ int use_flood_fill;
+ float thresh;
- int use_manifold;
+ int use_manifold;
- float hermite_num;
+ float hermite_num;
- DualConMode mode;
+ DualConMode mode;
public:
- /**
- * Construtor
- */
- Octree(ModelReader *mr,
- DualConAllocOutput alloc_output_func,
- DualConAddVert add_vert_func,
- DualConAddQuad add_quad_func,
- DualConFlags flags, DualConMode mode, int depth,
- float threshold, float hermite_num);
-
- /**
- * Destructor
- */
- ~Octree();
-
- /**
- * Scan convert
- */
- void scanConvert();
-
- void *getOutputMesh() {
- return output_mesh;
- }
+ /**
+ * Construtor
+ */
+ Octree(ModelReader *mr,
+ DualConAllocOutput alloc_output_func,
+ DualConAddVert add_vert_func,
+ DualConAddQuad add_quad_func,
+ DualConFlags flags,
+ DualConMode mode,
+ int depth,
+ float threshold,
+ float hermite_num);
+
+ /**
+ * Destructor
+ */
+ ~Octree();
+
+ /**
+ * Scan convert
+ */
+ void scanConvert();
+
+ void *getOutputMesh()
+ {
+ return output_mesh;
+ }
private:
- /* Helper functions */
-
- /**
- * Initialize memory allocators
- */
- void initMemory();
-
- /**
- * Release memory
- */
- void freeMemory();
-
- /**
- * Print memory usage
- */
- void printMemUsage();
-
-
- /**
- * Methods to set / restore minimum edges
- */
- void resetMinimalEdges();
-
- void cellProcParity(Node *node, int leaf, int depth);
- void faceProcParity(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
- void edgeProcParity(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
-
- void processEdgeParity(LeafNode * node[4], int depths[4], int maxdep, int dir);
-
- /**
- * Add triangles to the tree
- */
- void addAllTriangles();
- void addTriangle(Triangle *trian, int triind);
- InternalNode *addTriangle(InternalNode *node, CubeTriangleIsect *p, int height);
-
- /**
- * Method to update minimizer in a cell: update edge intersections instead
- */
- LeafNode *updateCell(LeafNode *node, CubeTriangleIsect *p);
-
- /* Routines to detect and patch holes */
- int numRings;
- int totRingLengths;
- int maxRingLength;
-
- /**
- * Entry routine.
- */
- void trace();
- /**
- * Trace the given node, find patches and fill them in
- */
- Node *trace(Node *node, int *st, int len, int depth, PathList *& paths);
- /**
- * Look for path on the face and add to paths
- */
- void findPaths(Node * node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList * &paths);
- /**
- * Combine two list1 and list2 into list1 using connecting paths list3,
- * while closed paths are appended to rings
- */
- void combinePaths(PathList *& list1, PathList *list2, PathList *paths, PathList *& rings);
- /**
- * Helper function: combine current paths in list1 and list2 to a single path and append to list3
- */
- PathList *combineSinglePath(PathList *& head1, PathList *pre1, PathList *& list1, PathList *& head2, PathList *pre2, PathList *& list2);
-
- /**
- * Functions to patch rings in a node
- */
- Node *patch(Node *node, int st[3], int len, PathList * rings);
- Node *patchSplit(Node *node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2);
- Node *patchSplitSingle(Node *node, int st[3], int len, PathElement *head, int dir, PathList * &nrings1, PathList * &nrings2);
- Node *connectFace(Node *node, int st[3], int len, int dir, PathElement * f1, PathElement * f2);
- Node *locateCell(InternalNode *node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen);
- void compressRing(PathElement *& ring);
- void getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q);
- LeafNode *patchAdjacent(InternalNode *node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha);
- int findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2);
- int getSide(PathElement *e, int pos, int dir);
- int isEqual(PathElement *e1, PathElement *e2);
- void preparePrimalEdgesMask(InternalNode *node);
- void testFacePoint(PathElement *e1, PathElement *e2);
-
- /**
- * Path-related functions
- */
- void deletePath(PathList *& head, PathList *pre, PathList *& curr);
- void printPath(PathList *path);
- void printPath(PathElement *path);
- void printElement(PathElement *ele);
- void printPaths(PathList *path);
- void checkElement(PathElement *ele);
- void checkPath(PathElement *path);
-
-
- /**
- * Routines to build signs to create a partitioned volume
- *(after patching rings)
- */
- void buildSigns();
- void buildSigns(unsigned char table[], Node * node, int isLeaf, int sg, int rvalue[8]);
-
- /************************************************************************/
- /* To remove disconnected components */
- /************************************************************************/
- void floodFill();
- void clearProcessBits(Node *node, int height);
- int floodFill(LeafNode *leaf, int st[3], int len, int height, int threshold);
- int floodFill(Node *node, int st[3], int len, int height, int threshold);
-
- /**
- * Write out polygon file
- */
- void writeOut();
-
- void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface);
- void generateMinimizer(Node *node, int st[3], int len, int height, int& offset);
- void computeMinimizer(const LeafNode * leaf, int st[3], int len,
- float rvalue[3]) const;
- /**
- * Traversal functions to generate polygon model
- * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY
- */
- void cellProcContour(Node *node, int leaf, int depth);
- void faceProcContour(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
- void edgeProcContour(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
- void processEdgeWrite(Node * node[4], int depths[4], int maxdep, int dir);
-
- /* output callbacks/data */
- DualConAllocOutput alloc_output;
- DualConAddVert add_vert;
- DualConAddQuad add_quad;
- void *output_mesh;
+ /* Helper functions */
+
+ /**
+ * Initialize memory allocators
+ */
+ void initMemory();
+
+ /**
+ * Release memory
+ */
+ void freeMemory();
+
+ /**
+ * Print memory usage
+ */
+ void printMemUsage();
+
+ /**
+ * Methods to set / restore minimum edges
+ */
+ void resetMinimalEdges();
+
+ void cellProcParity(Node *node, int leaf, int depth);
+ void faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir);
+ void edgeProcParity(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir);
+
+ void processEdgeParity(LeafNode *node[4], int depths[4], int maxdep, int dir);
+
+ /**
+ * Add triangles to the tree
+ */
+ void addAllTriangles();
+ void addTriangle(Triangle *trian, int triind);
+ InternalNode *addTriangle(InternalNode *node, CubeTriangleIsect *p, int height);
+
+ /**
+ * Method to update minimizer in a cell: update edge intersections instead
+ */
+ LeafNode *updateCell(LeafNode *node, CubeTriangleIsect *p);
+
+ /* Routines to detect and patch holes */
+ int numRings;
+ int totRingLengths;
+ int maxRingLength;
+
+ /**
+ * Entry routine.
+ */
+ void trace();
+ /**
+ * Trace the given node, find patches and fill them in
+ */
+ Node *trace(Node *node, int *st, int len, int depth, PathList *&paths);
+ /**
+ * Look for path on the face and add to paths
+ */
+ void findPaths(
+ Node *node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList *&paths);
+ /**
+ * Combine two list1 and list2 into list1 using connecting paths list3,
+ * while closed paths are appended to rings
+ */
+ void combinePaths(PathList *&list1, PathList *list2, PathList *paths, PathList *&rings);
+ /**
+ * Helper function: combine current paths in list1 and list2 to a single path and append to list3
+ */
+ PathList *combineSinglePath(PathList *&head1,
+ PathList *pre1,
+ PathList *&list1,
+ PathList *&head2,
+ PathList *pre2,
+ PathList *&list2);
+
+ /**
+ * Functions to patch rings in a node
+ */
+ Node *patch(Node *node, int st[3], int len, PathList *rings);
+ Node *patchSplit(Node *node,
+ int st[3],
+ int len,
+ PathList *rings,
+ int dir,
+ PathList *&nrings1,
+ PathList *&nrings2);
+ Node *patchSplitSingle(Node *node,
+ int st[3],
+ int len,
+ PathElement *head,
+ int dir,
+ PathList *&nrings1,
+ PathList *&nrings2);
+ Node *connectFace(Node *node, int st[3], int len, int dir, PathElement *f1, PathElement *f2);
+ Node *locateCell(InternalNode *node,
+ int st[3],
+ int len,
+ int ori[3],
+ int dir,
+ int side,
+ Node *&rleaf,
+ int rst[3],
+ int &rlen);
+ void compressRing(PathElement *&ring);
+ void getFacePoint(PathElement *leaf, int dir, int &x, int &y, float &p, float &q);
+ LeafNode *patchAdjacent(InternalNode *node,
+ int len,
+ int st1[3],
+ LeafNode *leaf1,
+ int st2[3],
+ LeafNode *leaf2,
+ int walkdir,
+ int inc,
+ int dir,
+ int side,
+ float alpha);
+ int findPair(PathElement *head, int pos, int dir, PathElement *&pre1, PathElement *&pre2);
+ int getSide(PathElement *e, int pos, int dir);
+ int isEqual(PathElement *e1, PathElement *e2);
+ void preparePrimalEdgesMask(InternalNode *node);
+ void testFacePoint(PathElement *e1, PathElement *e2);
+
+ /**
+ * Path-related functions
+ */
+ void deletePath(PathList *&head, PathList *pre, PathList *&curr);
+ void printPath(PathList *path);
+ void printPath(PathElement *path);
+ void printElement(PathElement *ele);
+ void printPaths(PathList *path);
+ void checkElement(PathElement *ele);
+ void checkPath(PathElement *path);
+
+ /**
+ * Routines to build signs to create a partitioned volume
+ *(after patching rings)
+ */
+ void buildSigns();
+ void buildSigns(unsigned char table[], Node *node, int isLeaf, int sg, int rvalue[8]);
+
+ /************************************************************************/
+ /* To remove disconnected components */
+ /************************************************************************/
+ void floodFill();
+ void clearProcessBits(Node *node, int height);
+ int floodFill(LeafNode *leaf, int st[3], int len, int height, int threshold);
+ int floodFill(Node *node, int st[3], int len, int height, int threshold);
+
+ /**
+ * Write out polygon file
+ */
+ void writeOut();
+
+ void countIntersection(Node *node, int height, int &nedge, int &ncell, int &nface);
+ void generateMinimizer(Node *node, int st[3], int len, int height, int &offset);
+ void computeMinimizer(const LeafNode *leaf, int st[3], int len, float rvalue[3]) const;
+ /**
+ * Traversal functions to generate polygon model
+ * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY
+ */
+ void cellProcContour(Node *node, int leaf, int depth);
+ void faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxdep, int dir);
+ void edgeProcContour(Node *node[4], int leaf[4], int depth[4], int maxdep, int dir);
+ void processEdgeWrite(Node *node[4], int depths[4], int maxdep, int dir);
+
+ /* output callbacks/data */
+ DualConAllocOutput alloc_output;
+ DualConAddVert add_vert;
+ DualConAddQuad add_quad;
+ void *output_mesh;
private:
- /************ Operators for all nodes ************/
-
- /// Lookup table
- int numEdgeTable[8];
- int edgeCountTable[8][3];
-
- /// Build up lookup table
- void buildTable()
- {
- for (int i = 0; i < 256; i++) {
- InternalNode::numChildrenTable[i] = 0;
- int count = 0;
- for (int j = 0; j < 8; j++) {
- InternalNode::numChildrenTable[i] += ((i >> j) & 1);
- InternalNode::childrenCountTable[i][j] = count;
- InternalNode::childrenIndexTable[i][count] = j;
- count += ((i >> j) & 1);
- }
- }
-
- for (int i = 0; i < 8; i++) {
- numEdgeTable[i] = 0;
- int count = 0;
- for (int j = 0; j < 3; j++) {
- numEdgeTable[i] += ((i >> j) & 1);
- edgeCountTable[i][j] = count;
- count += ((i >> j) & 1);
- }
- }
- }
-
- int getSign(Node *node, int height, int index)
- {
- if (height == 0) {
- return getSign(&node->leaf, index);
- }
- else {
- if (node->internal.has_child(index)) {
- return getSign(node->internal.get_child(node->internal.get_child_count(index)),
- height - 1,
- index);
- }
- else {
- return getSign(node->internal.get_child(0),
- height - 1,
- 7 - node->internal.get_child_index(0));
- }
- }
- }
-
- /************ Operators for leaf nodes ************/
-
- void printInfo(int st[3])
- {
- printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >> minshift, st[2] >> minshift);
- LeafNode *leaf = (LeafNode *)locateLeafCheck(st);
- if (leaf)
- printInfo(leaf);
- else
- printf("Leaf not exists!\n");
- }
-
- void printInfo(const LeafNode *leaf)
- {
- /*
- printf("Edge mask: ");
- for(int i = 0; i < 12; i ++)
- {
- printf("%d ", getEdgeParity(leaf, i));
- }
- printf("\n");
- printf("Stored edge mask: ");
- for(i = 0; i < 3; i ++)
- {
- printf("%d ", getStoredEdgesParity(leaf, i));
- }
- printf("\n");
- */
- printf("Sign mask: ");
- for (int i = 0; i < 8; i++) {
- printf("%d ", getSign(leaf, i));
- }
- printf("\n");
-
- }
-
- /// Retrieve signs
- int getSign(const LeafNode *leaf, int index)
- {
- return ((leaf->signs >> index) & 1);
- }
-
- /// Set sign
- void setSign(LeafNode *leaf, int index)
- {
- leaf->signs |= (1 << index);
- }
-
- void setSign(LeafNode *leaf, int index, int sign)
- {
- leaf->signs &= (~(1 << index));
- leaf->signs |= ((sign & 1) << index);
- }
-
- int getSignMask(const LeafNode *leaf) const
- {
- return leaf->signs;
- }
-
- void setInProcessAll(int st[3], int dir)
- {
- int nst[3], eind;
- for (int i = 0; i < 4; i++) {
- nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
- nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
- nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
- eind = dirEdge[dir][i];
-
- LeafNode *cell = locateLeafCheck(nst);
- assert(cell);
-
- setInProcess(cell, eind);
- }
- }
-
- void flipParityAll(int st[3], int dir)
- {
- int nst[3], eind;
- for (int i = 0; i < 4; i++) {
- nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
- nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
- nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
- eind = dirEdge[dir][i];
-
- LeafNode *cell = locateLeaf(nst);
- flipEdge(cell, eind);
- }
- }
-
- void setInProcess(LeafNode *leaf, int eind)
- {
- assert(eind >= 0 && eind <= 11);
-
- leaf->flood_fill |= (1 << eind);
- }
-
- void setOutProcess(LeafNode *leaf, int eind)
- {
- assert(eind >= 0 && eind <= 11);
-
- leaf->flood_fill &= ~(1 << eind);
- }
-
- int isInProcess(LeafNode *leaf, int eind)
- {
- assert(eind >= 0 && eind <= 11);
-
- return (leaf->flood_fill >> eind) & 1;
- }
-
- /// Generate signs at the corners from the edge parity
- void generateSigns(LeafNode *leaf, unsigned char table[], int start)
- {
- leaf->signs = table[leaf->edge_parity];
-
- if ((start ^ leaf->signs) & 1) {
- leaf->signs = ~(leaf->signs);
- }
- }
-
- /// Get edge parity
- int getEdgeParity(const LeafNode *leaf, int index) const
- {
- assert(index >= 0 && index <= 11);
-
- return (leaf->edge_parity >> index) & 1;
- }
-
- /// Get edge parity on a face
- int getFaceParity(LeafNode *leaf, int index)
- {
- int a = getEdgeParity(leaf, faceMap[index][0]) +
- getEdgeParity(leaf, faceMap[index][1]) +
- getEdgeParity(leaf, faceMap[index][2]) +
- getEdgeParity(leaf, faceMap[index][3]);
- return (a & 1);
- }
- int getFaceEdgeNum(LeafNode *leaf, int index)
- {
- int a = getEdgeParity(leaf, faceMap[index][0]) +
- getEdgeParity(leaf, faceMap[index][1]) +
- getEdgeParity(leaf, faceMap[index][2]) +
- getEdgeParity(leaf, faceMap[index][3]);
- return a;
- }
-
- /// Set edge parity
- void flipEdge(LeafNode *leaf, int index)
- {
- assert(index >= 0 && index <= 11);
-
- leaf->edge_parity ^= (1 << index);
- }
-
- /// Set 1
- void setEdge(LeafNode *leaf, int index)
- {
- assert(index >= 0 && index <= 11);
-
- leaf->edge_parity |= (1 << index);
- }
-
- /// Set 0
- void resetEdge(LeafNode *leaf, int index)
- {
- assert(index >= 0 && index <= 11);
-
- leaf->edge_parity &= ~(1 << index);
- }
-
- /// Flipping with a new intersection offset
- void createPrimalEdgesMask(LeafNode *leaf)
- {
- leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
- }
-
- void setStoredEdgesParity(LeafNode *leaf, int pindex)
- {
- assert(pindex <= 2 && pindex >= 0);
-
- leaf->primary_edge_intersections |= (1 << pindex);
- }
-
- int getStoredEdgesParity(const LeafNode *leaf, int pindex) const
- {
- assert(pindex <= 2 && pindex >= 0);
-
- return (leaf->primary_edge_intersections >> pindex) & 1;
- }
-
- LeafNode *flipEdge(LeafNode *leaf, int index, float alpha)
- {
- flipEdge(leaf, index);
-
- if ((index & 3) == 0) {
- int ind = index / 4;
- if (getEdgeParity(leaf, index) && !getStoredEdgesParity(leaf, ind)) {
- // Create a new node
- int num = getNumEdges(leaf) + 1;
- setStoredEdgesParity(leaf, ind);
- int count = getEdgeCount(leaf, ind);
- LeafNode *nleaf = createLeaf(num);
- *nleaf = *leaf;
-
- setEdgeOffset(nleaf, alpha, count);
-
- if (num > 1) {
- float *pts = leaf->edge_intersections;
- float *npts = nleaf->edge_intersections;
- for (int i = 0; i < count; i++) {
- for (int j = 0; j < EDGE_FLOATS; j++) {
- npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j];
- }
- }
- for (int i = count + 1; i < num; i++) {
- for (int j = 0; j < EDGE_FLOATS; j++) {
- npts[i * EDGE_FLOATS + j] = pts[(i - 1) * EDGE_FLOATS + j];
- }
- }
- }
-
-
- removeLeaf(num - 1, (LeafNode *)leaf);
- leaf = nleaf;
- }
- }
-
- return leaf;
- }
-
- /// Update parent link
- void updateParent(InternalNode *node, int len, int st[3], LeafNode *leaf)
- {
- // First, locate the parent
- int count;
- InternalNode *parent = locateParent(node, len, st, count);
-
- // Update
- parent->set_child(count, (Node *)leaf);
- }
-
- void updateParent(InternalNode *node, int len, int st[3])
- {
- if (len == dimen) {
- root = (Node *)node;
- return;
- }
-
- // First, locate the parent
- int count;
- InternalNode *parent = locateParent(len, st, count);
-
- // UPdate
- parent->set_child(count, (Node *)node);
- }
-
- /// Find edge intersection on a given edge
- int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check) const
- {
- // First, locat the leaf
- const LeafNode *leaf;
- if (check) {
- leaf = locateLeafCheck(st);
- }
- else {
- leaf = locateLeaf(st);
- }
-
- if (leaf && getStoredEdgesParity(leaf, index)) {
- float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
- pt[0] = (float) st[0];
- pt[1] = (float) st[1];
- pt[2] = (float) st[2];
- pt[index] += off * mindimen;
-
- return 1;
- }
- else {
- return 0;
- }
- }
-
- /// Retrieve number of edges intersected
- int getPrimalEdgesMask(const LeafNode *leaf) const
- {
- return leaf->primary_edge_intersections;
- }
-
- int getPrimalEdgesMask2(LeafNode *leaf)
- {
- return (((leaf->edge_parity & 0x1) >> 0) |
- ((leaf->edge_parity & 0x10) >> 3) |
- ((leaf->edge_parity & 0x100) >> 6));
- }
-
- /// Get the count for a primary edge
- int getEdgeCount(const LeafNode *leaf, int index) const
- {
- return edgeCountTable[getPrimalEdgesMask(leaf)][index];
- }
- int getNumEdges(LeafNode *leaf)
- {
- return numEdgeTable[getPrimalEdgesMask(leaf)];
- }
-
- int getNumEdges2(LeafNode *leaf)
- {
- return numEdgeTable[getPrimalEdgesMask2(leaf)];
- }
-
- /// Set edge intersection
- void setEdgeOffset(LeafNode *leaf, float pt, int count)
- {
- float *pts = leaf->edge_intersections;
- pts[EDGE_FLOATS * count] = pt;
- pts[EDGE_FLOATS * count + 1] = 0;
- pts[EDGE_FLOATS * count + 2] = 0;
- pts[EDGE_FLOATS * count + 3] = 0;
- }
-
- /// Set multiple edge intersections
- void setEdgeOffsets(LeafNode *leaf, float pt[3], int len)
- {
- float *pts = leaf->edge_intersections;
- for (int i = 0; i < len; i++) {
- pts[i] = pt[i];
- }
- }
-
- /// Retrieve edge intersection
- float getEdgeOffset(const LeafNode *leaf, int count) const
- {
- return leaf->edge_intersections[4 * count];
- }
-
- /// Update method
- LeafNode *updateEdgeOffsets(LeafNode *leaf, int oldlen, int newlen, float offs[3])
- {
- // First, create a new leaf node
- LeafNode *nleaf = createLeaf(newlen);
- *nleaf = *leaf;
-
- // Next, fill in the offsets
- setEdgeOffsets(nleaf, offs, newlen);
-
- // Finally, delete the old leaf
- removeLeaf(oldlen, leaf);
-
- return nleaf;
- }
-
- /// Set minimizer index
- void setMinimizerIndex(LeafNode *leaf, int index)
- {
- leaf->minimizer_index = index;
- }
-
- /// Get minimizer index
- int getMinimizerIndex(LeafNode *leaf)
- {
- return leaf->minimizer_index;
- }
-
- int getMinimizerIndex(LeafNode *leaf, int eind)
- {
- int add = manifold_table[getSignMask(leaf)].pairs[eind][0] - 1;
- assert(add >= 0);
- return leaf->minimizer_index + add;
- }
-
- void getMinimizerIndices(LeafNode *leaf, int eind, int inds[2])
- {
- const int *add = manifold_table[getSignMask(leaf)].pairs[eind];
- inds[0] = leaf->minimizer_index + add[0] - 1;
- if (add[0] == add[1]) {
- inds[1] = -1;
- }
- else {
- inds[1] = leaf->minimizer_index + add[1] - 1;
- }
- }
-
-
- /// Set edge intersection
- void setEdgeOffsetNormal(LeafNode *leaf, float pt, float a, float b, float c, int count)
- {
- float *pts = leaf->edge_intersections;
- pts[4 * count] = pt;
- pts[4 * count + 1] = a;
- pts[4 * count + 2] = b;
- pts[4 * count + 3] = c;
- }
-
- float getEdgeOffsetNormal(LeafNode *leaf, int count, float& a, float& b, float& c)
- {
- float *pts = leaf->edge_intersections;
- a = pts[4 * count + 1];
- b = pts[4 * count + 2];
- c = pts[4 * count + 3];
- return pts[4 * count];
- }
-
- /// Set multiple edge intersections
- void setEdgeOffsetsNormals(LeafNode *leaf, const float pt[],
- const float a[], const float b[],
- const float c[], int len)
- {
- float *pts = leaf->edge_intersections;
- for (int i = 0; i < len; i++) {
- if (pt[i] > 1 || pt[i] < 0) {
- printf("\noffset: %f\n", pt[i]);
- }
- pts[i * 4] = pt[i];
- pts[i * 4 + 1] = a[i];
- pts[i * 4 + 2] = b[i];
- pts[i * 4 + 3] = c[i];
- }
- }
-
- /// Retrieve complete edge intersection
- void getEdgeIntersectionByIndex(const LeafNode *leaf, int index, int st[3],
- int len, float pt[3], float nm[3]) const
- {
- int count = getEdgeCount(leaf, index);
- const float *pts = leaf->edge_intersections;
-
- float off = pts[4 * count];
-
- pt[0] = (float) st[0];
- pt[1] = (float) st[1];
- pt[2] = (float) st[2];
- pt[index] += (off * len);
-
- nm[0] = pts[4 * count + 1];
- nm[1] = pts[4 * count + 2];
- nm[2] = pts[4 * count + 3];
- }
-
- float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
- {
- int count = getEdgeCount(leaf, index);
- float *pts = leaf->edge_intersections;
-
- float off = pts[4 * count];
-
- nm[0] = pts[4 * count + 1];
- nm[1] = pts[4 * count + 2];
- nm[2] = pts[4 * count + 3];
-
- return off;
- }
-
- void fillEdgeIntersections(const LeafNode *leaf, int st[3], int len,
- float pts[12][3], float norms[12][3]) const
- {
- int i;
- // int stt[3] = {0, 0, 0};
-
- // The three primal edges are easy
- int pmask[3] = {0, 4, 8};
- for (i = 0; i < 3; i++) {
- if (getEdgeParity(leaf, pmask[i])) {
- // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
- getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
- }
- }
-
- // 3 face adjacent cubes
- int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
- int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
- for (i = 0; i < 3; i++) {
- int e1 = getEdgeParity(leaf, fmask[i][0]);
- int e2 = getEdgeParity(leaf, fmask[i][1]);
- if (e1 || e2) {
- int nst[3] = {st[0], st[1], st[2]};
- nst[i] += len;
- // int nstt[3] = {0, 0, 0};
- // nstt[i] += 1;
- const LeafNode *node = locateLeaf(nst);
-
- if (e1) {
- // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
- getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
- }
- if (e2) {
- // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
- getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
- }
- }
- }
-
- // 3 edge adjacent cubes
- int emask[3] = {3, 7, 11};
- int eemask[3] = {0, 1, 2};
- for (i = 0; i < 3; i++) {
- if (getEdgeParity(leaf, emask[i])) {
- int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
- nst[i] -= len;
- // int nstt[3] = {1, 1, 1};
- // nstt[i] -= 1;
- const LeafNode *node = locateLeaf(nst);
-
- // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
- getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
- }
- }
- }
-
-
- void fillEdgeIntersections(const LeafNode *leaf, int st[3], int len,
- float pts[12][3], float norms[12][3],
- int parity[12]) const
- {
- int i;
- for (i = 0; i < 12; i++) {
- parity[i] = 0;
- }
- // int stt[3] = {0, 0, 0};
-
- // The three primal edges are easy
- int pmask[3] = {0, 4, 8};
- for (i = 0; i < 3; i++) {
- if (getStoredEdgesParity(leaf, i)) {
- // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
- getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
- parity[pmask[i]] = 1;
- }
- }
-
- // 3 face adjacent cubes
- int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
- int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
- for (i = 0; i < 3; i++) {
- {
- int nst[3] = {st[0], st[1], st[2]};
- nst[i] += len;
- // int nstt[3] = {0, 0, 0};
- // nstt[i] += 1;
- const LeafNode *node = locateLeafCheck(nst);
- if (node == NULL) {
- continue;
- }
-
- int e1 = getStoredEdgesParity(node, femask[i][0]);
- int e2 = getStoredEdgesParity(node, femask[i][1]);
-
- if (e1) {
- // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
- getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
- parity[fmask[i][0]] = 1;
- }
- if (e2) {
- // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
- getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
- parity[fmask[i][1]] = 1;
- }
- }
- }
-
- // 3 edge adjacent cubes
- int emask[3] = {3, 7, 11};
- int eemask[3] = {0, 1, 2};
- for (i = 0; i < 3; i++) {
- // if(getEdgeParity(leaf, emask[i]))
- {
- int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
- nst[i] -= len;
- // int nstt[3] = {1, 1, 1};
- // nstt[i] -= 1;
- const LeafNode *node = locateLeafCheck(nst);
- if (node == NULL) {
- continue;
- }
-
- if (getStoredEdgesParity(node, eemask[i])) {
- // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
- getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
- parity[emask[i]] = 1;
- }
- }
- }
- }
-
- void fillEdgeOffsetsNormals(LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
- {
- int i;
- for (i = 0; i < 12; i++) {
- parity[i] = 0;
- }
- // int stt[3] = {0, 0, 0};
-
- // The three primal edges are easy
- int pmask[3] = {0, 4, 8};
- for (i = 0; i < 3; i++) {
- if (getStoredEdgesParity(leaf, i)) {
- pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, i, norms[pmask[i]]);
- parity[pmask[i]] = 1;
- }
- }
-
- // 3 face adjacent cubes
- int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
- int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
- for (i = 0; i < 3; i++) {
- {
- int nst[3] = {st[0], st[1], st[2]};
- nst[i] += len;
- // int nstt[3] = {0, 0, 0};
- // nstt[i] += 1;
- LeafNode *node = locateLeafCheck(nst);
- if (node == NULL) {
- continue;
- }
-
- int e1 = getStoredEdgesParity(node, femask[i][0]);
- int e2 = getStoredEdgesParity(node, femask[i][1]);
-
- if (e1) {
- pts[fmask[i][0]] = getEdgeOffsetNormalByIndex(node, femask[i][0], norms[fmask[i][0]]);
- parity[fmask[i][0]] = 1;
- }
- if (e2) {
- pts[fmask[i][1]] = getEdgeOffsetNormalByIndex(node, femask[i][1], norms[fmask[i][1]]);
- parity[fmask[i][1]] = 1;
- }
- }
- }
-
- // 3 edge adjacent cubes
- int emask[3] = {3, 7, 11};
- int eemask[3] = {0, 1, 2};
- for (i = 0; i < 3; i++) {
- // if(getEdgeParity(leaf, emask[i]))
- {
- int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
- nst[i] -= len;
- // int nstt[3] = {1, 1, 1};
- // nstt[i] -= 1;
- LeafNode *node = locateLeafCheck(nst);
- if (node == NULL) {
- continue;
- }
-
- if (getStoredEdgesParity(node, eemask[i])) {
- pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
- parity[emask[i]] = 1;
- }
- }
- }
- }
-
-
- /// Update method
- LeafNode *updateEdgeOffsetsNormals(LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3])
- {
- // First, create a new leaf node
- LeafNode *nleaf = createLeaf(newlen);
- *nleaf = *leaf;
-
- // Next, fill in the offsets
- setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
-
- // Finally, delete the old leaf
- removeLeaf(oldlen, leaf);
-
- return nleaf;
- }
-
- /// Locate a leaf
- /// WARNING: assuming this leaf already exists!
-
- LeafNode *locateLeaf(int st[3])
- {
- Node *node = (Node *)root;
- for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
- int index = (((st[0] >> i) & 1) << 2) |
- (((st[1] >> i) & 1) << 1) |
- (((st[2] >> i) & 1));
- node = node->internal.get_child(node->internal.get_child_count(index));
- }
-
- return &node->leaf;
- }
-
- const LeafNode *locateLeaf(int st[3]) const
- {
- const Node *node = root;
- for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
- int index = (((st[0] >> i) & 1) << 2) |
- (((st[1] >> i) & 1) << 1) |
- (((st[2] >> i) & 1));
- node = node->internal.get_child(node->internal.get_child_count(index));
- }
-
- return &node->leaf;
- }
-
- LeafNode *locateLeaf(InternalNode *parent, int len, int st[3])
- {
- Node *node = (Node *)parent;
- int index;
- for (int i = len / 2; i >= mindimen; i >>= 1) {
- index = (((st[0] & i) ? 4 : 0) |
- ((st[1] & i) ? 2 : 0) |
- ((st[2] & i) ? 1 : 0));
- node = node->internal.get_child(node->internal.get_child_count(index));
- }
-
- return &node->leaf;
- }
-
- LeafNode *locateLeafCheck(int st[3])
- {
- Node *node = (Node *)root;
- for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
- int index = (((st[0] >> i) & 1) << 2) |
- (((st[1] >> i) & 1) << 1) |
- (((st[2] >> i) & 1));
- if (!node->internal.has_child(index)) {
- return NULL;
- }
- node = node->internal.get_child(node->internal.get_child_count(index));
- }
-
- return &node->leaf;
- }
-
- const LeafNode *locateLeafCheck(int st[3]) const
- {
- const Node *node = root;
- for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
- int index = (((st[0] >> i) & 1) << 2) |
- (((st[1] >> i) & 1) << 1) |
- (((st[2] >> i) & 1));
- if (!node->internal.has_child(index)) {
- return NULL;
- }
- node = node->internal.get_child(node->internal.get_child_count(index));
- }
-
- return &node->leaf;
- }
-
- InternalNode *locateParent(int len, int st[3], int& count)
- {
- InternalNode *node = (InternalNode *)root;
- InternalNode *pre = NULL;
- int index = 0;
- for (int i = dimen / 2; i >= len; i >>= 1) {
- index = (((st[0] & i) ? 4 : 0) |
- ((st[1] & i) ? 2 : 0) |
- ((st[2] & i) ? 1 : 0));
- pre = node;
- node = &node->get_child(node->get_child_count(index))->internal;
- }
-
- count = pre->get_child_count(index);
- return pre;
- }
-
- InternalNode *locateParent(InternalNode *parent, int len, int st[3], int& count)
- {
- InternalNode *node = parent;
- InternalNode *pre = NULL;
- int index = 0;
- for (int i = len / 2; i >= mindimen; i >>= 1) {
- index = (((st[0] & i) ? 4 : 0) |
- ((st[1] & i) ? 2 : 0) |
- ((st[2] & i) ? 1 : 0));
- pre = node;
- node = &node->get_child(node->get_child_count(index))->internal;
- }
-
- count = pre->get_child_count(index);
- return pre;
- }
-
- /************ Operators for internal nodes ************/
-
-
- /// Add a kid to an existing internal node
- InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf)
- {
- // Create new internal node
- int num = node->get_num_children();
- InternalNode *rnode = createInternal(num + 1);
-
- // Establish children
- int i;
- int count1 = 0, count2 = 0;
- for (i = 0; i < 8; i++) {
- if (i == index) {
- if (aLeaf) {
- rnode->set_leaf_child(i, count2, &child->leaf);
- }
- else {
- rnode->set_internal_child(i, count2, &child->internal);
- }
- count2++;
- }
- else if (node->has_child(i)) {
- if (node->is_child_leaf(i)) {
- rnode->set_leaf_child(i, count2, &node->get_child(count1)->leaf);
- }
- else {
- rnode->set_internal_child(i, count2, &node->get_child(count1)->internal);
- }
- count1++;
- count2++;
- }
- }
-
- removeInternal(num, node);
- return rnode;
- }
-
- /// Allocate a node
- InternalNode *createInternal(int length)
- {
- InternalNode *inode = (InternalNode *)alloc[length]->allocate();
- inode->has_child_bitfield = 0;
- inode->child_is_leaf_bitfield = 0;
- return inode;
- }
-
- LeafNode *createLeaf(int length)
- {
- assert(length <= 3);
-
- LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
- lnode->edge_parity = 0;
- lnode->primary_edge_intersections = 0;
- lnode->signs = 0;
-
- return lnode;
- }
-
- void removeInternal(int num, InternalNode *node)
- {
- alloc[num]->deallocate(node);
- }
-
- void removeLeaf(int num, LeafNode *leaf)
- {
- assert(num >= 0 && num <= 3);
- leafalloc[num]->deallocate(leaf);
- }
-
- /// Add a leaf (by creating a new par node with the leaf added)
- InternalNode *addLeafChild(InternalNode *par, int index, int count,
- LeafNode *leaf)
- {
- int num = par->get_num_children() + 1;
- InternalNode *npar = createInternal(num);
- *npar = *par;
-
- if (num == 1) {
- npar->set_leaf_child(index, 0, leaf);
- }
- else {
- int i;
- for (i = 0; i < count; i++) {
- npar->set_child(i, par->get_child(i));
- }
- npar->set_leaf_child(index, count, leaf);
- for (i = count + 1; i < num; i++) {
- npar->set_child(i, par->get_child(i - 1));
- }
- }
-
- removeInternal(num - 1, par);
- return npar;
- }
-
- InternalNode *addInternalChild(InternalNode *par, int index, int count,
- InternalNode *node)
- {
- int num = par->get_num_children() + 1;
- InternalNode *npar = createInternal(num);
- *npar = *par;
-
- if (num == 1) {
- npar->set_internal_child(index, 0, node);
- }
- else {
- int i;
- for (i = 0; i < count; i++) {
- npar->set_child(i, par->get_child(i));
- }
- npar->set_internal_child(index, count, node);
- for (i = count + 1; i < num; i++) {
- npar->set_child(i, par->get_child(i - 1));
- }
- }
-
- removeInternal(num - 1, par);
- return npar;
- }
+ /************ Operators for all nodes ************/
+
+ /// Lookup table
+ int numEdgeTable[8];
+ int edgeCountTable[8][3];
+
+ /// Build up lookup table
+ void buildTable()
+ {
+ for (int i = 0; i < 256; i++) {
+ InternalNode::numChildrenTable[i] = 0;
+ int count = 0;
+ for (int j = 0; j < 8; j++) {
+ InternalNode::numChildrenTable[i] += ((i >> j) & 1);
+ InternalNode::childrenCountTable[i][j] = count;
+ InternalNode::childrenIndexTable[i][count] = j;
+ count += ((i >> j) & 1);
+ }
+ }
+
+ for (int i = 0; i < 8; i++) {
+ numEdgeTable[i] = 0;
+ int count = 0;
+ for (int j = 0; j < 3; j++) {
+ numEdgeTable[i] += ((i >> j) & 1);
+ edgeCountTable[i][j] = count;
+ count += ((i >> j) & 1);
+ }
+ }
+ }
+
+ int getSign(Node *node, int height, int index)
+ {
+ if (height == 0) {
+ return getSign(&node->leaf, index);
+ }
+ else {
+ if (node->internal.has_child(index)) {
+ return getSign(
+ node->internal.get_child(node->internal.get_child_count(index)), height - 1, index);
+ }
+ else {
+ return getSign(
+ node->internal.get_child(0), height - 1, 7 - node->internal.get_child_index(0));
+ }
+ }
+ }
+
+ /************ Operators for leaf nodes ************/
+
+ void printInfo(int st[3])
+ {
+ printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >> minshift, st[2] >> minshift);
+ LeafNode *leaf = (LeafNode *)locateLeafCheck(st);
+ if (leaf)
+ printInfo(leaf);
+ else
+ printf("Leaf not exists!\n");
+ }
+
+ void printInfo(const LeafNode *leaf)
+ {
+ /*
+ printf("Edge mask: ");
+ for(int i = 0; i < 12; i ++)
+ {
+ printf("%d ", getEdgeParity(leaf, i));
+ }
+ printf("\n");
+ printf("Stored edge mask: ");
+ for(i = 0; i < 3; i ++)
+ {
+ printf("%d ", getStoredEdgesParity(leaf, i));
+ }
+ printf("\n");
+ */
+ printf("Sign mask: ");
+ for (int i = 0; i < 8; i++) {
+ printf("%d ", getSign(leaf, i));
+ }
+ printf("\n");
+ }
+
+ /// Retrieve signs
+ int getSign(const LeafNode *leaf, int index)
+ {
+ return ((leaf->signs >> index) & 1);
+ }
+
+ /// Set sign
+ void setSign(LeafNode *leaf, int index)
+ {
+ leaf->signs |= (1 << index);
+ }
+
+ void setSign(LeafNode *leaf, int index, int sign)
+ {
+ leaf->signs &= (~(1 << index));
+ leaf->signs |= ((sign & 1) << index);
+ }
+
+ int getSignMask(const LeafNode *leaf) const
+ {
+ return leaf->signs;
+ }
+
+ void setInProcessAll(int st[3], int dir)
+ {
+ int nst[3], eind;
+ for (int i = 0; i < 4; i++) {
+ nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
+ nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
+ nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
+ eind = dirEdge[dir][i];
+
+ LeafNode *cell = locateLeafCheck(nst);
+ assert(cell);
+
+ setInProcess(cell, eind);
+ }
+ }
+
+ void flipParityAll(int st[3], int dir)
+ {
+ int nst[3], eind;
+ for (int i = 0; i < 4; i++) {
+ nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
+ nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
+ nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
+ eind = dirEdge[dir][i];
+
+ LeafNode *cell = locateLeaf(nst);
+ flipEdge(cell, eind);
+ }
+ }
+
+ void setInProcess(LeafNode *leaf, int eind)
+ {
+ assert(eind >= 0 && eind <= 11);
+
+ leaf->flood_fill |= (1 << eind);
+ }
+
+ void setOutProcess(LeafNode *leaf, int eind)
+ {
+ assert(eind >= 0 && eind <= 11);
+
+ leaf->flood_fill &= ~(1 << eind);
+ }
+
+ int isInProcess(LeafNode *leaf, int eind)
+ {
+ assert(eind >= 0 && eind <= 11);
+
+ return (leaf->flood_fill >> eind) & 1;
+ }
+
+ /// Generate signs at the corners from the edge parity
+ void generateSigns(LeafNode *leaf, unsigned char table[], int start)
+ {
+ leaf->signs = table[leaf->edge_parity];
+
+ if ((start ^ leaf->signs) & 1) {
+ leaf->signs = ~(leaf->signs);
+ }
+ }
+
+ /// Get edge parity
+ int getEdgeParity(const LeafNode *leaf, int index) const
+ {
+ assert(index >= 0 && index <= 11);
+
+ return (leaf->edge_parity >> index) & 1;
+ }
+
+ /// Get edge parity on a face
+ int getFaceParity(LeafNode *leaf, int index)
+ {
+ int a = getEdgeParity(leaf, faceMap[index][0]) + getEdgeParity(leaf, faceMap[index][1]) +
+ getEdgeParity(leaf, faceMap[index][2]) + getEdgeParity(leaf, faceMap[index][3]);
+ return (a & 1);
+ }
+ int getFaceEdgeNum(LeafNode *leaf, int index)
+ {
+ int a = getEdgeParity(leaf, faceMap[index][0]) + getEdgeParity(leaf, faceMap[index][1]) +
+ getEdgeParity(leaf, faceMap[index][2]) + getEdgeParity(leaf, faceMap[index][3]);
+ return a;
+ }
+
+ /// Set edge parity
+ void flipEdge(LeafNode *leaf, int index)
+ {
+ assert(index >= 0 && index <= 11);
+
+ leaf->edge_parity ^= (1 << index);
+ }
+
+ /// Set 1
+ void setEdge(LeafNode *leaf, int index)
+ {
+ assert(index >= 0 && index <= 11);
+
+ leaf->edge_parity |= (1 << index);
+ }
+
+ /// Set 0
+ void resetEdge(LeafNode *leaf, int index)
+ {
+ assert(index >= 0 && index <= 11);
+
+ leaf->edge_parity &= ~(1 << index);
+ }
+
+ /// Flipping with a new intersection offset
+ void createPrimalEdgesMask(LeafNode *leaf)
+ {
+ leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
+ }
+
+ void setStoredEdgesParity(LeafNode *leaf, int pindex)
+ {
+ assert(pindex <= 2 && pindex >= 0);
+
+ leaf->primary_edge_intersections |= (1 << pindex);
+ }
+
+ int getStoredEdgesParity(const LeafNode *leaf, int pindex) const
+ {
+ assert(pindex <= 2 && pindex >= 0);
+
+ return (leaf->primary_edge_intersections >> pindex) & 1;
+ }
+
+ LeafNode *flipEdge(LeafNode *leaf, int index, float alpha)
+ {
+ flipEdge(leaf, index);
+
+ if ((index & 3) == 0) {
+ int ind = index / 4;
+ if (getEdgeParity(leaf, index) && !getStoredEdgesParity(leaf, ind)) {
+ // Create a new node
+ int num = getNumEdges(leaf) + 1;
+ setStoredEdgesParity(leaf, ind);
+ int count = getEdgeCount(leaf, ind);
+ LeafNode *nleaf = createLeaf(num);
+ *nleaf = *leaf;
+
+ setEdgeOffset(nleaf, alpha, count);
+
+ if (num > 1) {
+ float *pts = leaf->edge_intersections;
+ float *npts = nleaf->edge_intersections;
+ for (int i = 0; i < count; i++) {
+ for (int j = 0; j < EDGE_FLOATS; j++) {
+ npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j];
+ }
+ }
+ for (int i = count + 1; i < num; i++) {
+ for (int j = 0; j < EDGE_FLOATS; j++) {
+ npts[i * EDGE_FLOATS + j] = pts[(i - 1) * EDGE_FLOATS + j];
+ }
+ }
+ }
+
+ removeLeaf(num - 1, (LeafNode *)leaf);
+ leaf = nleaf;
+ }
+ }
+
+ return leaf;
+ }
+
+ /// Update parent link
+ void updateParent(InternalNode *node, int len, int st[3], LeafNode *leaf)
+ {
+ // First, locate the parent
+ int count;
+ InternalNode *parent = locateParent(node, len, st, count);
+
+ // Update
+ parent->set_child(count, (Node *)leaf);
+ }
+
+ void updateParent(InternalNode *node, int len, int st[3])
+ {
+ if (len == dimen) {
+ root = (Node *)node;
+ return;
+ }
+
+ // First, locate the parent
+ int count;
+ InternalNode *parent = locateParent(len, st, count);
+
+ // UPdate
+ parent->set_child(count, (Node *)node);
+ }
+
+ /// Find edge intersection on a given edge
+ int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check) const
+ {
+ // First, locat the leaf
+ const LeafNode *leaf;
+ if (check) {
+ leaf = locateLeafCheck(st);
+ }
+ else {
+ leaf = locateLeaf(st);
+ }
+
+ if (leaf && getStoredEdgesParity(leaf, index)) {
+ float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
+ pt[0] = (float)st[0];
+ pt[1] = (float)st[1];
+ pt[2] = (float)st[2];
+ pt[index] += off * mindimen;
+
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ /// Retrieve number of edges intersected
+ int getPrimalEdgesMask(const LeafNode *leaf) const
+ {
+ return leaf->primary_edge_intersections;
+ }
+
+ int getPrimalEdgesMask2(LeafNode *leaf)
+ {
+ return (((leaf->edge_parity & 0x1) >> 0) | ((leaf->edge_parity & 0x10) >> 3) |
+ ((leaf->edge_parity & 0x100) >> 6));
+ }
+
+ /// Get the count for a primary edge
+ int getEdgeCount(const LeafNode *leaf, int index) const
+ {
+ return edgeCountTable[getPrimalEdgesMask(leaf)][index];
+ }
+ int getNumEdges(LeafNode *leaf)
+ {
+ return numEdgeTable[getPrimalEdgesMask(leaf)];
+ }
+
+ int getNumEdges2(LeafNode *leaf)
+ {
+ return numEdgeTable[getPrimalEdgesMask2(leaf)];
+ }
+
+ /// Set edge intersection
+ void setEdgeOffset(LeafNode *leaf, float pt, int count)
+ {
+ float *pts = leaf->edge_intersections;
+ pts[EDGE_FLOATS * count] = pt;
+ pts[EDGE_FLOATS * count + 1] = 0;
+ pts[EDGE_FLOATS * count + 2] = 0;
+ pts[EDGE_FLOATS * count + 3] = 0;
+ }
+
+ /// Set multiple edge intersections
+ void setEdgeOffsets(LeafNode *leaf, float pt[3], int len)
+ {
+ float *pts = leaf->edge_intersections;
+ for (int i = 0; i < len; i++) {
+ pts[i] = pt[i];
+ }
+ }
+
+ /// Retrieve edge intersection
+ float getEdgeOffset(const LeafNode *leaf, int count) const
+ {
+ return leaf->edge_intersections[4 * count];
+ }
+
+ /// Update method
+ LeafNode *updateEdgeOffsets(LeafNode *leaf, int oldlen, int newlen, float offs[3])
+ {
+ // First, create a new leaf node
+ LeafNode *nleaf = createLeaf(newlen);
+ *nleaf = *leaf;
+
+ // Next, fill in the offsets
+ setEdgeOffsets(nleaf, offs, newlen);
+
+ // Finally, delete the old leaf
+ removeLeaf(oldlen, leaf);
+
+ return nleaf;
+ }
+
+ /// Set minimizer index
+ void setMinimizerIndex(LeafNode *leaf, int index)
+ {
+ leaf->minimizer_index = index;
+ }
+
+ /// Get minimizer index
+ int getMinimizerIndex(LeafNode *leaf)
+ {
+ return leaf->minimizer_index;
+ }
+
+ int getMinimizerIndex(LeafNode *leaf, int eind)
+ {
+ int add = manifold_table[getSignMask(leaf)].pairs[eind][0] - 1;
+ assert(add >= 0);
+ return leaf->minimizer_index + add;
+ }
+
+ void getMinimizerIndices(LeafNode *leaf, int eind, int inds[2])
+ {
+ const int *add = manifold_table[getSignMask(leaf)].pairs[eind];
+ inds[0] = leaf->minimizer_index + add[0] - 1;
+ if (add[0] == add[1]) {
+ inds[1] = -1;
+ }
+ else {
+ inds[1] = leaf->minimizer_index + add[1] - 1;
+ }
+ }
+
+ /// Set edge intersection
+ void setEdgeOffsetNormal(LeafNode *leaf, float pt, float a, float b, float c, int count)
+ {
+ float *pts = leaf->edge_intersections;
+ pts[4 * count] = pt;
+ pts[4 * count + 1] = a;
+ pts[4 * count + 2] = b;
+ pts[4 * count + 3] = c;
+ }
+
+ float getEdgeOffsetNormal(LeafNode *leaf, int count, float &a, float &b, float &c)
+ {
+ float *pts = leaf->edge_intersections;
+ a = pts[4 * count + 1];
+ b = pts[4 * count + 2];
+ c = pts[4 * count + 3];
+ return pts[4 * count];
+ }
+
+ /// Set multiple edge intersections
+ void setEdgeOffsetsNormals(
+ LeafNode *leaf, const float pt[], const float a[], const float b[], const float c[], int len)
+ {
+ float *pts = leaf->edge_intersections;
+ for (int i = 0; i < len; i++) {
+ if (pt[i] > 1 || pt[i] < 0) {
+ printf("\noffset: %f\n", pt[i]);
+ }
+ pts[i * 4] = pt[i];
+ pts[i * 4 + 1] = a[i];
+ pts[i * 4 + 2] = b[i];
+ pts[i * 4 + 3] = c[i];
+ }
+ }
+
+ /// Retrieve complete edge intersection
+ void getEdgeIntersectionByIndex(
+ const LeafNode *leaf, int index, int st[3], int len, float pt[3], float nm[3]) const
+ {
+ int count = getEdgeCount(leaf, index);
+ const float *pts = leaf->edge_intersections;
+
+ float off = pts[4 * count];
+
+ pt[0] = (float)st[0];
+ pt[1] = (float)st[1];
+ pt[2] = (float)st[2];
+ pt[index] += (off * len);
+
+ nm[0] = pts[4 * count + 1];
+ nm[1] = pts[4 * count + 2];
+ nm[2] = pts[4 * count + 3];
+ }
+
+ float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
+ {
+ int count = getEdgeCount(leaf, index);
+ float *pts = leaf->edge_intersections;
+
+ float off = pts[4 * count];
+
+ nm[0] = pts[4 * count + 1];
+ nm[1] = pts[4 * count + 2];
+ nm[2] = pts[4 * count + 3];
+
+ return off;
+ }
+
+ void fillEdgeIntersections(
+ const LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3]) const
+ {
+ int i;
+ // int stt[3] = {0, 0, 0};
+
+ // The three primal edges are easy
+ int pmask[3] = {0, 4, 8};
+ for (i = 0; i < 3; i++) {
+ if (getEdgeParity(leaf, pmask[i])) {
+ // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
+ getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
+ }
+ }
+
+ // 3 face adjacent cubes
+ int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
+ int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+ for (i = 0; i < 3; i++) {
+ int e1 = getEdgeParity(leaf, fmask[i][0]);
+ int e2 = getEdgeParity(leaf, fmask[i][1]);
+ if (e1 || e2) {
+ int nst[3] = {st[0], st[1], st[2]};
+ nst[i] += len;
+ // int nstt[3] = {0, 0, 0};
+ // nstt[i] += 1;
+ const LeafNode *node = locateLeaf(nst);
+
+ if (e1) {
+ // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
+ getEdgeIntersectionByIndex(
+ node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
+ }
+ if (e2) {
+ // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
+ getEdgeIntersectionByIndex(
+ node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
+ }
+ }
+ }
+
+ // 3 edge adjacent cubes
+ int emask[3] = {3, 7, 11};
+ int eemask[3] = {0, 1, 2};
+ for (i = 0; i < 3; i++) {
+ if (getEdgeParity(leaf, emask[i])) {
+ int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
+ nst[i] -= len;
+ // int nstt[3] = {1, 1, 1};
+ // nstt[i] -= 1;
+ const LeafNode *node = locateLeaf(nst);
+
+ // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
+ getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
+ }
+ }
+ }
+
+ void fillEdgeIntersections(const LeafNode *leaf,
+ int st[3],
+ int len,
+ float pts[12][3],
+ float norms[12][3],
+ int parity[12]) const
+ {
+ int i;
+ for (i = 0; i < 12; i++) {
+ parity[i] = 0;
+ }
+ // int stt[3] = {0, 0, 0};
+
+ // The three primal edges are easy
+ int pmask[3] = {0, 4, 8};
+ for (i = 0; i < 3; i++) {
+ if (getStoredEdgesParity(leaf, i)) {
+ // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
+ getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
+ parity[pmask[i]] = 1;
+ }
+ }
+
+ // 3 face adjacent cubes
+ int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
+ int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+ for (i = 0; i < 3; i++) {
+ {
+ int nst[3] = {st[0], st[1], st[2]};
+ nst[i] += len;
+ // int nstt[3] = {0, 0, 0};
+ // nstt[i] += 1;
+ const LeafNode *node = locateLeafCheck(nst);
+ if (node == NULL) {
+ continue;
+ }
+
+ int e1 = getStoredEdgesParity(node, femask[i][0]);
+ int e2 = getStoredEdgesParity(node, femask[i][1]);
+
+ if (e1) {
+ // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
+ getEdgeIntersectionByIndex(
+ node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
+ parity[fmask[i][0]] = 1;
+ }
+ if (e2) {
+ // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
+ getEdgeIntersectionByIndex(
+ node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
+ parity[fmask[i][1]] = 1;
+ }
+ }
+ }
+
+ // 3 edge adjacent cubes
+ int emask[3] = {3, 7, 11};
+ int eemask[3] = {0, 1, 2};
+ for (i = 0; i < 3; i++) {
+ // if(getEdgeParity(leaf, emask[i]))
+ {
+ int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
+ nst[i] -= len;
+ // int nstt[3] = {1, 1, 1};
+ // nstt[i] -= 1;
+ const LeafNode *node = locateLeafCheck(nst);
+ if (node == NULL) {
+ continue;
+ }
+
+ if (getStoredEdgesParity(node, eemask[i])) {
+ // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
+ getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
+ parity[emask[i]] = 1;
+ }
+ }
+ }
+ }
+
+ void fillEdgeOffsetsNormals(
+ LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
+ {
+ int i;
+ for (i = 0; i < 12; i++) {
+ parity[i] = 0;
+ }
+ // int stt[3] = {0, 0, 0};
+
+ // The three primal edges are easy
+ int pmask[3] = {0, 4, 8};
+ for (i = 0; i < 3; i++) {
+ if (getStoredEdgesParity(leaf, i)) {
+ pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, i, norms[pmask[i]]);
+ parity[pmask[i]] = 1;
+ }
+ }
+
+ // 3 face adjacent cubes
+ int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
+ int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+ for (i = 0; i < 3; i++) {
+ {
+ int nst[3] = {st[0], st[1], st[2]};
+ nst[i] += len;
+ // int nstt[3] = {0, 0, 0};
+ // nstt[i] += 1;
+ LeafNode *node = locateLeafCheck(nst);
+ if (node == NULL) {
+ continue;
+ }
+
+ int e1 = getStoredEdgesParity(node, femask[i][0]);
+ int e2 = getStoredEdgesParity(node, femask[i][1]);
+
+ if (e1) {
+ pts[fmask[i][0]] = getEdgeOffsetNormalByIndex(node, femask[i][0], norms[fmask[i][0]]);
+ parity[fmask[i][0]] = 1;
+ }
+ if (e2) {
+ pts[fmask[i][1]] = getEdgeOffsetNormalByIndex(node, femask[i][1], norms[fmask[i][1]]);
+ parity[fmask[i][1]] = 1;
+ }
+ }
+ }
+
+ // 3 edge adjacent cubes
+ int emask[3] = {3, 7, 11};
+ int eemask[3] = {0, 1, 2};
+ for (i = 0; i < 3; i++) {
+ // if(getEdgeParity(leaf, emask[i]))
+ {
+ int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
+ nst[i] -= len;
+ // int nstt[3] = {1, 1, 1};
+ // nstt[i] -= 1;
+ LeafNode *node = locateLeafCheck(nst);
+ if (node == NULL) {
+ continue;
+ }
+
+ if (getStoredEdgesParity(node, eemask[i])) {
+ pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
+ parity[emask[i]] = 1;
+ }
+ }
+ }
+ }
+
+ /// Update method
+ LeafNode *updateEdgeOffsetsNormals(
+ LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3])
+ {
+ // First, create a new leaf node
+ LeafNode *nleaf = createLeaf(newlen);
+ *nleaf = *leaf;
+
+ // Next, fill in the offsets
+ setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
+
+ // Finally, delete the old leaf
+ removeLeaf(oldlen, leaf);
+
+ return nleaf;
+ }
+
+ /// Locate a leaf
+ /// WARNING: assuming this leaf already exists!
+
+ LeafNode *locateLeaf(int st[3])
+ {
+ Node *node = (Node *)root;
+ for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
+ int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
+ node = node->internal.get_child(node->internal.get_child_count(index));
+ }
+
+ return &node->leaf;
+ }
+
+ const LeafNode *locateLeaf(int st[3]) const
+ {
+ const Node *node = root;
+ for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
+ int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
+ node = node->internal.get_child(node->internal.get_child_count(index));
+ }
+
+ return &node->leaf;
+ }
+
+ LeafNode *locateLeaf(InternalNode *parent, int len, int st[3])
+ {
+ Node *node = (Node *)parent;
+ int index;
+ for (int i = len / 2; i >= mindimen; i >>= 1) {
+ index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
+ node = node->internal.get_child(node->internal.get_child_count(index));
+ }
+
+ return &node->leaf;
+ }
+
+ LeafNode *locateLeafCheck(int st[3])
+ {
+ Node *node = (Node *)root;
+ for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
+ int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
+ if (!node->internal.has_child(index)) {
+ return NULL;
+ }
+ node = node->internal.get_child(node->internal.get_child_count(index));
+ }
+
+ return &node->leaf;
+ }
+
+ const LeafNode *locateLeafCheck(int st[3]) const
+ {
+ const Node *node = root;
+ for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
+ int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
+ if (!node->internal.has_child(index)) {
+ return NULL;
+ }
+ node = node->internal.get_child(node->internal.get_child_count(index));
+ }
+
+ return &node->leaf;
+ }
+
+ InternalNode *locateParent(int len, int st[3], int &count)
+ {
+ InternalNode *node = (InternalNode *)root;
+ InternalNode *pre = NULL;
+ int index = 0;
+ for (int i = dimen / 2; i >= len; i >>= 1) {
+ index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
+ pre = node;
+ node = &node->get_child(node->get_child_count(index))->internal;
+ }
+
+ count = pre->get_child_count(index);
+ return pre;
+ }
+
+ InternalNode *locateParent(InternalNode *parent, int len, int st[3], int &count)
+ {
+ InternalNode *node = parent;
+ InternalNode *pre = NULL;
+ int index = 0;
+ for (int i = len / 2; i >= mindimen; i >>= 1) {
+ index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
+ pre = node;
+ node = &node->get_child(node->get_child_count(index))->internal;
+ }
+
+ count = pre->get_child_count(index);
+ return pre;
+ }
+
+ /************ Operators for internal nodes ************/
+
+ /// Add a kid to an existing internal node
+ InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf)
+ {
+ // Create new internal node
+ int num = node->get_num_children();
+ InternalNode *rnode = createInternal(num + 1);
+
+ // Establish children
+ int i;
+ int count1 = 0, count2 = 0;
+ for (i = 0; i < 8; i++) {
+ if (i == index) {
+ if (aLeaf) {
+ rnode->set_leaf_child(i, count2, &child->leaf);
+ }
+ else {
+ rnode->set_internal_child(i, count2, &child->internal);
+ }
+ count2++;
+ }
+ else if (node->has_child(i)) {
+ if (node->is_child_leaf(i)) {
+ rnode->set_leaf_child(i, count2, &node->get_child(count1)->leaf);
+ }
+ else {
+ rnode->set_internal_child(i, count2, &node->get_child(count1)->internal);
+ }
+ count1++;
+ count2++;
+ }
+ }
+
+ removeInternal(num, node);
+ return rnode;
+ }
+
+ /// Allocate a node
+ InternalNode *createInternal(int length)
+ {
+ InternalNode *inode = (InternalNode *)alloc[length]->allocate();
+ inode->has_child_bitfield = 0;
+ inode->child_is_leaf_bitfield = 0;
+ return inode;
+ }
+
+ LeafNode *createLeaf(int length)
+ {
+ assert(length <= 3);
+
+ LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
+ lnode->edge_parity = 0;
+ lnode->primary_edge_intersections = 0;
+ lnode->signs = 0;
+
+ return lnode;
+ }
+
+ void removeInternal(int num, InternalNode *node)
+ {
+ alloc[num]->deallocate(node);
+ }
+
+ void removeLeaf(int num, LeafNode *leaf)
+ {
+ assert(num >= 0 && num <= 3);
+ leafalloc[num]->deallocate(leaf);
+ }
+
+ /// Add a leaf (by creating a new par node with the leaf added)
+ InternalNode *addLeafChild(InternalNode *par, int index, int count, LeafNode *leaf)
+ {
+ int num = par->get_num_children() + 1;
+ InternalNode *npar = createInternal(num);
+ *npar = *par;
+
+ if (num == 1) {
+ npar->set_leaf_child(index, 0, leaf);
+ }
+ else {
+ int i;
+ for (i = 0; i < count; i++) {
+ npar->set_child(i, par->get_child(i));
+ }
+ npar->set_leaf_child(index, count, leaf);
+ for (i = count + 1; i < num; i++) {
+ npar->set_child(i, par->get_child(i - 1));
+ }
+ }
+
+ removeInternal(num - 1, par);
+ return npar;
+ }
+
+ InternalNode *addInternalChild(InternalNode *par, int index, int count, InternalNode *node)
+ {
+ int num = par->get_num_children() + 1;
+ InternalNode *npar = createInternal(num);
+ *npar = *par;
+
+ if (num == 1) {
+ npar->set_internal_child(index, 0, node);
+ }
+ else {
+ int i;
+ for (i = 0; i < count; i++) {
+ npar->set_child(i, par->get_child(i));
+ }
+ npar->set_internal_child(index, count, node);
+ for (i = count + 1; i < num; i++) {
+ npar->set_child(i, par->get_child(i - 1));
+ }
+ }
+
+ removeInternal(num - 1, par);
+ return npar;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Octree")
+ MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Octree")
#endif
};
-#endif /* __OCTREE_H__ */
+#endif /* __OCTREE_H__ */
diff --git a/intern/eigen/CMakeLists.txt b/intern/eigen/CMakeLists.txt
index 650a1aa63c1..70088d080e1 100644
--- a/intern/eigen/CMakeLists.txt
+++ b/intern/eigen/CMakeLists.txt
@@ -19,25 +19,25 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
+ .
)
set(INC_SYS
- ${EIGEN3_INCLUDE_DIRS}
+ ${EIGEN3_INCLUDE_DIRS}
)
set(SRC
- eigen_capi.h
+ eigen_capi.h
- intern/eigenvalues.cc
- intern/linear_solver.cc
- intern/matrix.cc
- intern/svd.cc
+ intern/eigenvalues.cc
+ intern/linear_solver.cc
+ intern/matrix.cc
+ intern/svd.cc
- intern/eigenvalues.h
- intern/linear_solver.h
- intern/matrix.h
- intern/svd.h
+ intern/eigenvalues.h
+ intern/linear_solver.h
+ intern/matrix.h
+ intern/svd.h
)
set(LIB
diff --git a/intern/eigen/eigen_capi.h b/intern/eigen/eigen_capi.h
index 5660b28259f..52ec489159f 100644
--- a/intern/eigen/eigen_capi.h
+++ b/intern/eigen/eigen_capi.h
@@ -25,4 +25,4 @@
#include "intern/matrix.h"
#include "intern/svd.h"
-#endif /* __EIGEN_C_API_H__ */
+#endif /* __EIGEN_C_API_H__ */
diff --git a/intern/eigen/intern/eigenvalues.cc b/intern/eigen/intern/eigenvalues.cc
index 3625df826d5..8a48ae5f17a 100644
--- a/intern/eigen/intern/eigenvalues.cc
+++ b/intern/eigen/intern/eigenvalues.cc
@@ -32,32 +32,35 @@
using Eigen::SelfAdjointEigenSolver;
+using Eigen::Map;
using Eigen::MatrixXf;
using Eigen::VectorXf;
-using Eigen::Map;
using Eigen::Success;
-bool EIG_self_adjoint_eigen_solve(const int size, const float *matrix, float *r_eigen_values, float *r_eigen_vectors)
+bool EIG_self_adjoint_eigen_solve(const int size,
+ const float *matrix,
+ float *r_eigen_values,
+ float *r_eigen_vectors)
{
- SelfAdjointEigenSolver<MatrixXf> eigen_solver;
+ SelfAdjointEigenSolver<MatrixXf> eigen_solver;
- /* Blender and Eigen matrices are both column-major. */
- eigen_solver.compute(Map<MatrixXf>((float *)matrix, size, size));
+ /* Blender and Eigen matrices are both column-major. */
+ eigen_solver.compute(Map<MatrixXf>((float *)matrix, size, size));
- if (eigen_solver.info() != Success) {
- return false;
- }
+ if (eigen_solver.info() != Success) {
+ return false;
+ }
- if (r_eigen_values) {
- Map<VectorXf>(r_eigen_values, size) = eigen_solver.eigenvalues().transpose();
- }
+ if (r_eigen_values) {
+ Map<VectorXf>(r_eigen_values, size) = eigen_solver.eigenvalues().transpose();
+ }
- if (r_eigen_vectors) {
- Map<MatrixXf>(r_eigen_vectors, size, size) = eigen_solver.eigenvectors();
- }
+ if (r_eigen_vectors) {
+ Map<MatrixXf>(r_eigen_vectors, size, size) = eigen_solver.eigenvectors();
+ }
- return true;
+ return true;
}
-#endif /* __EIGEN3_EIGENVALUES_C_API_CC__ */
+#endif /* __EIGEN3_EIGENVALUES_C_API_CC__ */
diff --git a/intern/eigen/intern/eigenvalues.h b/intern/eigen/intern/eigenvalues.h
index 76388365af7..fabbdd87207 100644
--- a/intern/eigen/intern/eigenvalues.h
+++ b/intern/eigen/intern/eigenvalues.h
@@ -24,10 +24,13 @@
extern "C" {
#endif
-bool EIG_self_adjoint_eigen_solve(const int size, const float *matrix, float *r_eigen_values, float *r_eigen_vectors);
+bool EIG_self_adjoint_eigen_solve(const int size,
+ const float *matrix,
+ float *r_eigen_values,
+ float *r_eigen_vectors);
#ifdef __cplusplus
}
#endif
-#endif /* __EIGEN3_EIGENVALUES_C_API_H__ */
+#endif /* __EIGEN3_EIGENVALUES_C_API_H__ */
diff --git a/intern/eigen/intern/linear_solver.cc b/intern/eigen/intern/linear_solver.cc
index 0fc4d39309b..bce5937409c 100644
--- a/intern/eigen/intern/linear_solver.cc
+++ b/intern/eigen/intern/linear_solver.cc
@@ -41,326 +41,318 @@ typedef Eigen::Triplet<double> EigenTriplet;
/* Linear Solver data structure */
-struct LinearSolver
-{
- struct Coeff
- {
- Coeff()
- {
- index = 0;
- value = 0.0;
- }
-
- int index;
- double value;
- };
-
- struct Variable
- {
- Variable()
- {
- memset(value, 0, sizeof(value));
- locked = false;
- index = 0;
- }
-
- double value[4];
- bool locked;
- int index;
- std::vector<Coeff> a;
- };
-
- enum State
- {
- STATE_VARIABLES_CONSTRUCT,
- STATE_MATRIX_CONSTRUCT,
- STATE_MATRIX_SOLVED
- };
-
- LinearSolver(int num_rows_, int num_variables_, int num_rhs_, bool lsq_)
- {
- assert(num_variables_ > 0);
- assert(num_rhs_ <= 4);
-
- state = STATE_VARIABLES_CONSTRUCT;
- m = 0;
- n = 0;
- sparseLU = NULL;
- num_variables = num_variables_;
- num_rhs = num_rhs_;
- num_rows = num_rows_;
- least_squares = lsq_;
-
- variable.resize(num_variables);
- }
-
- ~LinearSolver()
- {
- delete sparseLU;
- }
-
- State state;
-
- int n;
- int m;
-
- std::vector<EigenTriplet> Mtriplets;
- EigenSparseMatrix M;
- EigenSparseMatrix MtM;
- std::vector<EigenVectorX> b;
- std::vector<EigenVectorX> x;
-
- EigenSparseLU *sparseLU;
-
- int num_variables;
- std::vector<Variable> variable;
-
- int num_rows;
- int num_rhs;
-
- bool least_squares;
+struct LinearSolver {
+ struct Coeff {
+ Coeff()
+ {
+ index = 0;
+ value = 0.0;
+ }
+
+ int index;
+ double value;
+ };
+
+ struct Variable {
+ Variable()
+ {
+ memset(value, 0, sizeof(value));
+ locked = false;
+ index = 0;
+ }
+
+ double value[4];
+ bool locked;
+ int index;
+ std::vector<Coeff> a;
+ };
+
+ enum State { STATE_VARIABLES_CONSTRUCT, STATE_MATRIX_CONSTRUCT, STATE_MATRIX_SOLVED };
+
+ LinearSolver(int num_rows_, int num_variables_, int num_rhs_, bool lsq_)
+ {
+ assert(num_variables_ > 0);
+ assert(num_rhs_ <= 4);
+
+ state = STATE_VARIABLES_CONSTRUCT;
+ m = 0;
+ n = 0;
+ sparseLU = NULL;
+ num_variables = num_variables_;
+ num_rhs = num_rhs_;
+ num_rows = num_rows_;
+ least_squares = lsq_;
+
+ variable.resize(num_variables);
+ }
+
+ ~LinearSolver()
+ {
+ delete sparseLU;
+ }
+
+ State state;
+
+ int n;
+ int m;
+
+ std::vector<EigenTriplet> Mtriplets;
+ EigenSparseMatrix M;
+ EigenSparseMatrix MtM;
+ std::vector<EigenVectorX> b;
+ std::vector<EigenVectorX> x;
+
+ EigenSparseLU *sparseLU;
+
+ int num_variables;
+ std::vector<Variable> variable;
+
+ int num_rows;
+ int num_rhs;
+
+ bool least_squares;
};
LinearSolver *EIG_linear_solver_new(int num_rows, int num_columns, int num_rhs)
{
- return new LinearSolver(num_rows, num_columns, num_rhs, false);
+ return new LinearSolver(num_rows, num_columns, num_rhs, false);
}
LinearSolver *EIG_linear_least_squares_solver_new(int num_rows, int num_columns, int num_rhs)
{
- return new LinearSolver(num_rows, num_columns, num_rhs, true);
+ return new LinearSolver(num_rows, num_columns, num_rhs, true);
}
void EIG_linear_solver_delete(LinearSolver *solver)
{
- delete solver;
+ delete solver;
}
/* Variables */
void EIG_linear_solver_variable_set(LinearSolver *solver, int rhs, int index, double value)
{
- solver->variable[index].value[rhs] = value;
+ solver->variable[index].value[rhs] = value;
}
double EIG_linear_solver_variable_get(LinearSolver *solver, int rhs, int index)
{
- return solver->variable[index].value[rhs];
+ return solver->variable[index].value[rhs];
}
void EIG_linear_solver_variable_lock(LinearSolver *solver, int index)
{
- if (!solver->variable[index].locked) {
- assert(solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT);
- solver->variable[index].locked = true;
- }
+ if (!solver->variable[index].locked) {
+ assert(solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT);
+ solver->variable[index].locked = true;
+ }
}
void EIG_linear_solver_variable_unlock(LinearSolver *solver, int index)
{
- if (solver->variable[index].locked) {
- assert(solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT);
- solver->variable[index].locked = false;
- }
+ if (solver->variable[index].locked) {
+ assert(solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT);
+ solver->variable[index].locked = false;
+ }
}
static void linear_solver_variables_to_vector(LinearSolver *solver)
{
- int num_rhs = solver->num_rhs;
-
- for (int i = 0; i < solver->num_variables; i++) {
- LinearSolver::Variable* v = &solver->variable[i];
- if (!v->locked) {
- for (int j = 0; j < num_rhs; j++)
- solver->x[j][v->index] = v->value[j];
- }
- }
+ int num_rhs = solver->num_rhs;
+
+ for (int i = 0; i < solver->num_variables; i++) {
+ LinearSolver::Variable *v = &solver->variable[i];
+ if (!v->locked) {
+ for (int j = 0; j < num_rhs; j++)
+ solver->x[j][v->index] = v->value[j];
+ }
+ }
}
static void linear_solver_vector_to_variables(LinearSolver *solver)
{
- int num_rhs = solver->num_rhs;
-
- for (int i = 0; i < solver->num_variables; i++) {
- LinearSolver::Variable* v = &solver->variable[i];
- if (!v->locked) {
- for (int j = 0; j < num_rhs; j++)
- v->value[j] = solver->x[j][v->index];
- }
- }
+ int num_rhs = solver->num_rhs;
+
+ for (int i = 0; i < solver->num_variables; i++) {
+ LinearSolver::Variable *v = &solver->variable[i];
+ if (!v->locked) {
+ for (int j = 0; j < num_rhs; j++)
+ v->value[j] = solver->x[j][v->index];
+ }
+ }
}
/* Matrix */
static void linear_solver_ensure_matrix_construct(LinearSolver *solver)
{
- /* transition to matrix construction if necessary */
- if (solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT) {
- int n = 0;
+ /* transition to matrix construction if necessary */
+ if (solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT) {
+ int n = 0;
- for (int i = 0; i < solver->num_variables; i++) {
- if (solver->variable[i].locked)
- solver->variable[i].index = ~0;
- else
- solver->variable[i].index = n++;
- }
+ for (int i = 0; i < solver->num_variables; i++) {
+ if (solver->variable[i].locked)
+ solver->variable[i].index = ~0;
+ else
+ solver->variable[i].index = n++;
+ }
- int m = (solver->num_rows == 0)? n: solver->num_rows;
+ int m = (solver->num_rows == 0) ? n : solver->num_rows;
- solver->m = m;
- solver->n = n;
+ solver->m = m;
+ solver->n = n;
- assert(solver->least_squares || m == n);
+ assert(solver->least_squares || m == n);
- /* reserve reasonable estimate */
- solver->Mtriplets.clear();
- solver->Mtriplets.reserve(std::max(m, n)*3);
+ /* reserve reasonable estimate */
+ solver->Mtriplets.clear();
+ solver->Mtriplets.reserve(std::max(m, n) * 3);
- solver->b.resize(solver->num_rhs);
- solver->x.resize(solver->num_rhs);
+ solver->b.resize(solver->num_rhs);
+ solver->x.resize(solver->num_rhs);
- for (int i = 0; i < solver->num_rhs; i++) {
- solver->b[i].setZero(m);
- solver->x[i].setZero(n);
- }
+ for (int i = 0; i < solver->num_rhs; i++) {
+ solver->b[i].setZero(m);
+ solver->x[i].setZero(n);
+ }
- linear_solver_variables_to_vector(solver);
+ linear_solver_variables_to_vector(solver);
- solver->state = LinearSolver::STATE_MATRIX_CONSTRUCT;
- }
+ solver->state = LinearSolver::STATE_MATRIX_CONSTRUCT;
+ }
}
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
{
- if (solver->state == LinearSolver::STATE_MATRIX_SOLVED)
- return;
-
- linear_solver_ensure_matrix_construct(solver);
-
- if (!solver->least_squares && solver->variable[row].locked);
- else if (solver->variable[col].locked) {
- if (!solver->least_squares)
- row = solver->variable[row].index;
-
- LinearSolver::Coeff coeff;
- coeff.index = row;
- coeff.value = value;
- solver->variable[col].a.push_back(coeff);
- }
- else {
- if (!solver->least_squares)
- row = solver->variable[row].index;
- col = solver->variable[col].index;
-
- /* direct insert into matrix is too slow, so use triplets */
- EigenTriplet triplet(row, col, value);
- solver->Mtriplets.push_back(triplet);
- }
+ if (solver->state == LinearSolver::STATE_MATRIX_SOLVED)
+ return;
+
+ linear_solver_ensure_matrix_construct(solver);
+
+ if (!solver->least_squares && solver->variable[row].locked)
+ ;
+ else if (solver->variable[col].locked) {
+ if (!solver->least_squares)
+ row = solver->variable[row].index;
+
+ LinearSolver::Coeff coeff;
+ coeff.index = row;
+ coeff.value = value;
+ solver->variable[col].a.push_back(coeff);
+ }
+ else {
+ if (!solver->least_squares)
+ row = solver->variable[row].index;
+ col = solver->variable[col].index;
+
+ /* direct insert into matrix is too slow, so use triplets */
+ EigenTriplet triplet(row, col, value);
+ solver->Mtriplets.push_back(triplet);
+ }
}
/* Right hand side */
void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int index, double value)
{
- linear_solver_ensure_matrix_construct(solver);
-
- if (solver->least_squares) {
- solver->b[rhs][index] += value;
- }
- else if (!solver->variable[index].locked) {
- index = solver->variable[index].index;
- solver->b[rhs][index] += value;
- }
+ linear_solver_ensure_matrix_construct(solver);
+
+ if (solver->least_squares) {
+ solver->b[rhs][index] += value;
+ }
+ else if (!solver->variable[index].locked) {
+ index = solver->variable[index].index;
+ solver->b[rhs][index] += value;
+ }
}
/* Solve */
bool EIG_linear_solver_solve(LinearSolver *solver)
{
- /* nothing to solve, perhaps all variables were locked */
- if (solver->m == 0 || solver->n == 0)
- return true;
-
- bool result = true;
-
- assert(solver->state != LinearSolver::STATE_VARIABLES_CONSTRUCT);
-
- if (solver->state == LinearSolver::STATE_MATRIX_CONSTRUCT) {
- /* create matrix from triplets */
- solver->M.resize(solver->m, solver->n);
- solver->M.setFromTriplets(solver->Mtriplets.begin(), solver->Mtriplets.end());
- solver->Mtriplets.clear();
-
- /* create least squares matrix */
- if (solver->least_squares)
- solver->MtM = solver->M.transpose() * solver->M;
-
- /* convert M to compressed column format */
- EigenSparseMatrix& M = (solver->least_squares)? solver->MtM: solver->M;
- M.makeCompressed();
-
- /* perform sparse LU factorization */
- EigenSparseLU *sparseLU = new EigenSparseLU();
- solver->sparseLU = sparseLU;
-
- sparseLU->compute(M);
- result = (sparseLU->info() == Eigen::Success);
-
- solver->state = LinearSolver::STATE_MATRIX_SOLVED;
- }
-
- if (result) {
- /* solve for each right hand side */
- for (int rhs = 0; rhs < solver->num_rhs; rhs++) {
- /* modify for locked variables */
- EigenVectorX& b = solver->b[rhs];
-
- for (int i = 0; i < solver->num_variables; i++) {
- LinearSolver::Variable *variable = &solver->variable[i];
-
- if (variable->locked) {
- std::vector<LinearSolver::Coeff>& a = variable->a;
-
- for (int j = 0; j < a.size(); j++)
- b[a[j].index] -= a[j].value*variable->value[rhs];
- }
- }
-
- /* solve */
- if (solver->least_squares) {
- EigenVectorX Mtb = solver->M.transpose() * b;
- solver->x[rhs] = solver->sparseLU->solve(Mtb);
- }
- else {
- EigenVectorX& b = solver->b[rhs];
- solver->x[rhs] = solver->sparseLU->solve(b);
- }
-
- if (solver->sparseLU->info() != Eigen::Success)
- result = false;
- }
-
- if (result)
- linear_solver_vector_to_variables(solver);
- }
-
- /* clear for next solve */
- for (int rhs = 0; rhs < solver->num_rhs; rhs++)
- solver->b[rhs].setZero(solver->m);
-
- return result;
+ /* nothing to solve, perhaps all variables were locked */
+ if (solver->m == 0 || solver->n == 0)
+ return true;
+
+ bool result = true;
+
+ assert(solver->state != LinearSolver::STATE_VARIABLES_CONSTRUCT);
+
+ if (solver->state == LinearSolver::STATE_MATRIX_CONSTRUCT) {
+ /* create matrix from triplets */
+ solver->M.resize(solver->m, solver->n);
+ solver->M.setFromTriplets(solver->Mtriplets.begin(), solver->Mtriplets.end());
+ solver->Mtriplets.clear();
+
+ /* create least squares matrix */
+ if (solver->least_squares)
+ solver->MtM = solver->M.transpose() * solver->M;
+
+ /* convert M to compressed column format */
+ EigenSparseMatrix &M = (solver->least_squares) ? solver->MtM : solver->M;
+ M.makeCompressed();
+
+ /* perform sparse LU factorization */
+ EigenSparseLU *sparseLU = new EigenSparseLU();
+ solver->sparseLU = sparseLU;
+
+ sparseLU->compute(M);
+ result = (sparseLU->info() == Eigen::Success);
+
+ solver->state = LinearSolver::STATE_MATRIX_SOLVED;
+ }
+
+ if (result) {
+ /* solve for each right hand side */
+ for (int rhs = 0; rhs < solver->num_rhs; rhs++) {
+ /* modify for locked variables */
+ EigenVectorX &b = solver->b[rhs];
+
+ for (int i = 0; i < solver->num_variables; i++) {
+ LinearSolver::Variable *variable = &solver->variable[i];
+
+ if (variable->locked) {
+ std::vector<LinearSolver::Coeff> &a = variable->a;
+
+ for (int j = 0; j < a.size(); j++)
+ b[a[j].index] -= a[j].value * variable->value[rhs];
+ }
+ }
+
+ /* solve */
+ if (solver->least_squares) {
+ EigenVectorX Mtb = solver->M.transpose() * b;
+ solver->x[rhs] = solver->sparseLU->solve(Mtb);
+ }
+ else {
+ EigenVectorX &b = solver->b[rhs];
+ solver->x[rhs] = solver->sparseLU->solve(b);
+ }
+
+ if (solver->sparseLU->info() != Eigen::Success)
+ result = false;
+ }
+
+ if (result)
+ linear_solver_vector_to_variables(solver);
+ }
+
+ /* clear for next solve */
+ for (int rhs = 0; rhs < solver->num_rhs; rhs++)
+ solver->b[rhs].setZero(solver->m);
+
+ return result;
}
/* Debugging */
void EIG_linear_solver_print_matrix(LinearSolver *solver)
{
- std::cout << "A:" << solver->M << std::endl;
+ std::cout << "A:" << solver->M << std::endl;
- for (int rhs = 0; rhs < solver->num_rhs; rhs++)
- std::cout << "b " << rhs << ":" << solver->b[rhs] << std::endl;
+ for (int rhs = 0; rhs < solver->num_rhs; rhs++)
+ std::cout << "b " << rhs << ":" << solver->b[rhs] << std::endl;
- if (solver->MtM.rows() && solver->MtM.cols())
- std::cout << "AtA:" << solver->MtM << std::endl;
+ if (solver->MtM.rows() && solver->MtM.cols())
+ std::cout << "AtA:" << solver->MtM << std::endl;
}
-
diff --git a/intern/eigen/intern/linear_solver.h b/intern/eigen/intern/linear_solver.h
index 8f07e24e9a6..4da1ec05cd0 100644
--- a/intern/eigen/intern/linear_solver.h
+++ b/intern/eigen/intern/linear_solver.h
@@ -34,15 +34,11 @@ extern "C" {
typedef struct LinearSolver LinearSolver;
-LinearSolver *EIG_linear_solver_new(
- int num_rows,
- int num_columns,
- int num_right_hand_sides);
+LinearSolver *EIG_linear_solver_new(int num_rows, int num_columns, int num_right_hand_sides);
-LinearSolver *EIG_linear_least_squares_solver_new(
- int num_rows,
- int num_columns,
- int num_right_hand_sides);
+LinearSolver *EIG_linear_least_squares_solver_new(int num_rows,
+ int num_columns,
+ int num_right_hand_sides);
void EIG_linear_solver_delete(LinearSolver *solver);
@@ -69,4 +65,3 @@ void EIG_linear_solver_print_matrix(LinearSolver *solver);
#ifdef __cplusplus
}
#endif
-
diff --git a/intern/eigen/intern/matrix.cc b/intern/eigen/intern/matrix.cc
index 961afe7e2a4..2024a1ba59a 100644
--- a/intern/eigen/intern/matrix.cc
+++ b/intern/eigen/intern/matrix.cc
@@ -25,7 +25,7 @@
# pragma GCC diagnostic ignored "-Wlogical-op"
#endif
-#ifdef __EIGEN3_MATRIX_C_API_CC__ /* quiet warning */
+#ifdef __EIGEN3_MATRIX_C_API_CC__ /* quiet warning */
#endif
#include <Eigen/Core>
@@ -38,15 +38,15 @@ using Eigen::Matrix4f;
bool EIG_invert_m4_m4(float inverse[4][4], const float matrix[4][4])
{
- Map<Matrix4f> M = Map<Matrix4f>((float*)matrix);
- Matrix4f R;
- bool invertible = true;
- M.computeInverseWithCheck(R, invertible, 0.0f);
- if (!invertible) {
- R = R.Zero();
- }
- memcpy(inverse, R.data(), sizeof(float)*4*4);
- return invertible;
+ Map<Matrix4f> M = Map<Matrix4f>((float *)matrix);
+ Matrix4f R;
+ bool invertible = true;
+ M.computeInverseWithCheck(R, invertible, 0.0f);
+ if (!invertible) {
+ R = R.Zero();
+ }
+ memcpy(inverse, R.data(), sizeof(float) * 4 * 4);
+ return invertible;
}
-#endif /* __EIGEN3_MATRIX_C_API_CC__ */
+#endif /* __EIGEN3_MATRIX_C_API_CC__ */
diff --git a/intern/eigen/intern/matrix.h b/intern/eigen/intern/matrix.h
index 78eb09c7578..91ef5e0713d 100644
--- a/intern/eigen/intern/matrix.h
+++ b/intern/eigen/intern/matrix.h
@@ -30,4 +30,4 @@ bool EIG_invert_m4_m4(float inverse[4][4], const float matrix[4][4]);
}
#endif
-#endif /* __EIGEN3_MATRIX_C_API_H__ */
+#endif /* __EIGEN3_MATRIX_C_API_H__ */
diff --git a/intern/eigen/intern/svd.cc b/intern/eigen/intern/svd.cc
index eeba4c6273e..945d1bdee14 100644
--- a/intern/eigen/intern/svd.cc
+++ b/intern/eigen/intern/svd.cc
@@ -25,7 +25,7 @@
# pragma GCC diagnostic ignored "-Wlogical-op"
#endif
-#ifdef __EIGEN3_SVD_C_API_CC__ /* quiet warning */
+#ifdef __EIGEN3_SVD_C_API_CC__ /* quiet warning */
#endif
#include <Eigen/Core>
@@ -41,31 +41,31 @@ using Eigen::NoQRPreconditioner;
using Eigen::ComputeThinU;
using Eigen::ComputeThinV;
+using Eigen::Map;
using Eigen::MatrixXf;
using Eigen::VectorXf;
-using Eigen::Map;
using Eigen::Matrix4f;
void EIG_svd_square_matrix(const int size, const float *matrix, float *r_U, float *r_S, float *r_V)
{
- /* Since our matrix is squared, we can use thinU/V. */
- unsigned int flags = (r_U ? ComputeThinU : 0) | (r_V ? ComputeThinV : 0);
+ /* Since our matrix is squared, we can use thinU/V. */
+ unsigned int flags = (r_U ? ComputeThinU : 0) | (r_V ? ComputeThinV : 0);
- /* Blender and Eigen matrices are both column-major. */
- JacobiSVD<MatrixXf, NoQRPreconditioner> svd(Map<MatrixXf>((float *)matrix, size, size), flags);
+ /* Blender and Eigen matrices are both column-major. */
+ JacobiSVD<MatrixXf, NoQRPreconditioner> svd(Map<MatrixXf>((float *)matrix, size, size), flags);
- if (r_U) {
- Map<MatrixXf>(r_U, size, size) = svd.matrixU();
- }
+ if (r_U) {
+ Map<MatrixXf>(r_U, size, size) = svd.matrixU();
+ }
- if (r_S) {
- Map<VectorXf>(r_S, size) = svd.singularValues();
- }
+ if (r_S) {
+ Map<VectorXf>(r_S, size) = svd.singularValues();
+ }
- if (r_V) {
- Map<MatrixXf>(r_V, size, size) = svd.matrixV();
- }
+ if (r_V) {
+ Map<MatrixXf>(r_V, size, size) = svd.matrixV();
+ }
}
-#endif /* __EIGEN3_SVD_C_API_CC__ */
+#endif /* __EIGEN3_SVD_C_API_CC__ */
diff --git a/intern/eigen/intern/svd.h b/intern/eigen/intern/svd.h
index 4659fa7a4e2..80238621920 100644
--- a/intern/eigen/intern/svd.h
+++ b/intern/eigen/intern/svd.h
@@ -24,10 +24,11 @@
extern "C" {
#endif
-void EIG_svd_square_matrix(const int size, const float *matrix, float *r_U, float *r_S, float *r_V);
+void EIG_svd_square_matrix(
+ const int size, const float *matrix, float *r_U, float *r_S, float *r_V);
#ifdef __cplusplus
}
#endif
-#endif /* __EIGEN3_SVD_C_API_H__ */
+#endif /* __EIGEN3_SVD_C_API_H__ */
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index a7e80490f1e..1eafd409668 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -23,7 +23,8 @@
#include <libavformat/avformat.h>
/* check our ffmpeg is new enough, avoids user complaints */
-#if (LIBAVFORMAT_VERSION_MAJOR < 52) || ((LIBAVFORMAT_VERSION_MAJOR == 52) && (LIBAVFORMAT_VERSION_MINOR <= 64))
+#if (LIBAVFORMAT_VERSION_MAJOR < 52) || \
+ ((LIBAVFORMAT_VERSION_MAJOR == 52) && (LIBAVFORMAT_VERSION_MINOR <= 64))
# error "FFmpeg 0.7 or newer is needed, Upgrade your FFmpeg or disable it"
#endif
/* end sanity check */
@@ -40,7 +41,8 @@
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
-#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
+#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
+ ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
# define FFMPEG_HAVE_PARSE_UTILS 1
# include <libavutil/parseutils.h>
#endif
@@ -57,53 +59,69 @@
# define AV_USING_LIBAV
#endif
-#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105))
+#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
+ ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105))
# define FFMPEG_HAVE_AVIO 1
#endif
-#if (LIBAVCODEC_VERSION_MAJOR > 53) || ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR > 1)) || ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR == 1) && (LIBAVCODEC_VERSION_MICRO >= 1)) || ((LIBAVCODEC_VERSION_MAJOR == 52) && (LIBAVCODEC_VERSION_MINOR >= 121))
+#if (LIBAVCODEC_VERSION_MAJOR > 53) || \
+ ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR > 1)) || \
+ ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR == 1) && \
+ (LIBAVCODEC_VERSION_MICRO >= 1)) || \
+ ((LIBAVCODEC_VERSION_MAJOR == 52) && (LIBAVCODEC_VERSION_MINOR >= 121))
# define FFMPEG_HAVE_DEFAULT_VAL_UNION 1
#endif
-#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
+#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
+ ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
# define FFMPEG_HAVE_AV_DUMP_FORMAT 1
#endif
-#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 45))
+#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
+ ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 45))
# define FFMPEG_HAVE_AV_GUESS_FORMAT 1
#endif
-#if (LIBAVCODEC_VERSION_MAJOR > 52) || ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 23))
+#if (LIBAVCODEC_VERSION_MAJOR > 52) || \
+ ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 23))
# define FFMPEG_HAVE_DECODE_AUDIO3 1
# define FFMPEG_HAVE_DECODE_VIDEO2 1
#endif
-#if (LIBAVCODEC_VERSION_MAJOR > 52) || ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 64))
+#if (LIBAVCODEC_VERSION_MAJOR > 52) || \
+ ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 64))
# define FFMPEG_HAVE_AVMEDIA_TYPES 1
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR > 52) || (LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 29)) && \
- ((LIBSWSCALE_VERSION_MAJOR > 0) || (LIBSWSCALE_VERSION_MAJOR >= 0) && (LIBSWSCALE_VERSION_MINOR >= 10))
+#if ((LIBAVCODEC_VERSION_MAJOR > 52) || \
+ (LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 29)) && \
+ ((LIBSWSCALE_VERSION_MAJOR > 0) || \
+ (LIBSWSCALE_VERSION_MAJOR >= 0) && (LIBSWSCALE_VERSION_MINOR >= 10))
# define FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR > 14))
+#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
+ (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR > 14))
# define FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR > 53) || (LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 60))
+#if ((LIBAVCODEC_VERSION_MAJOR > 53) || \
+ (LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 60))
# define FFMPEG_HAVE_ENCODE_AUDIO2
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR > 53) || (LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 42))
+#if ((LIBAVCODEC_VERSION_MAJOR > 53) || \
+ (LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 42))
# define FFMPEG_HAVE_DECODE_AUDIO4
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
+#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
+ (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
# define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
#endif
-#if ((LIBAVUTIL_VERSION_MAJOR > 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 21))
+#if ((LIBAVUTIL_VERSION_MAJOR > 51) || \
+ (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 21))
# define FFMPEG_FFV1_ALPHA_SUPPORTED
# define FFMPEG_SAMPLE_FMT_S16P_SUPPORTED
#else
@@ -111,9 +129,9 @@
FFMPEG_INLINE
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
{
- /* no planar formats in FFmpeg < 0.9 */
- (void) sample_fmt;
- return 0;
+ /* no planar formats in FFmpeg < 0.9 */
+ (void)sample_fmt;
+ return 0;
}
#endif
@@ -191,142 +209,150 @@ int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
FFMPEG_INLINE
int av_get_cropped_height_from_codec(AVCodecContext *pCodecCtx)
{
- int y = pCodecCtx->height;
+ int y = pCodecCtx->height;
#ifndef FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
-/* really bad hack to remove this dreadfull black bar at the bottom
+ /* really bad hack to remove this dreadfull black bar at the bottom
with Canon footage and old ffmpeg versions.
(to fix this properly in older ffmpeg versions one has to write a new
demuxer...)
-
+
see the actual fix here for reference:
http://git.libav.org/?p=libav.git;a=commit;h=30f515091c323da59c0f1b533703dedca2f4b95d
We do our best to apply this only to matching footage.
*/
- if (pCodecCtx->width == 1920 &&
- pCodecCtx->height == 1088 &&
- pCodecCtx->pix_fmt == PIX_FMT_YUVJ420P &&
- pCodecCtx->codec_id == AV_CODEC_ID_H264 ) {
- y = 1080;
- }
+ if (pCodecCtx->width == 1920 && pCodecCtx->height == 1088 &&
+ pCodecCtx->pix_fmt == PIX_FMT_YUVJ420P && pCodecCtx->codec_id == AV_CODEC_ID_H264) {
+ y = 1080;
+ }
#endif
- return y;
+ return y;
}
-#if ((LIBAVUTIL_VERSION_MAJOR < 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 22))
+#if ((LIBAVUTIL_VERSION_MAJOR < 51) || \
+ (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 22))
FFMPEG_INLINE
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{
- const AVOption *rv = NULL;
- (void) search_flags;
- av_set_string3(obj, name, val, 1, &rv);
- return rv != NULL;
+ const AVOption *rv = NULL;
+ (void)search_flags;
+ av_set_string3(obj, name, val, 1, &rv);
+ return rv != NULL;
}
FFMPEG_INLINE
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
{
- const AVOption *rv = NULL;
- (void) search_flags;
- rv = av_set_int(obj, name, val);
- return rv != NULL;
+ const AVOption *rv = NULL;
+ (void)search_flags;
+ rv = av_set_int(obj, name, val);
+ return rv != NULL;
}
FFMPEG_INLINE
int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
{
- const AVOption *rv = NULL;
- (void) search_flags;
- rv = av_set_double(obj, name, val);
- return rv != NULL;
+ const AVOption *rv = NULL;
+ (void)search_flags;
+ rv = av_set_double(obj, name, val);
+ return rv != NULL;
}
-# define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
-# define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
-# define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
-# define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
-# define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
-# define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
+# define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
+# define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
+# define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
+# define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
+# define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
+# define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
#endif
-#if ((LIBAVUTIL_VERSION_MAJOR < 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 54))
+#if ((LIBAVUTIL_VERSION_MAJOR < 51) || \
+ (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 54))
FFMPEG_INLINE
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
{
- if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
- return AV_SAMPLE_FMT_NONE;
- return sample_fmt;
+ if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
+ return AV_SAMPLE_FMT_NONE;
+ return sample_fmt;
}
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR < 53) || (LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 35))
+#if ((LIBAVCODEC_VERSION_MAJOR < 53) || \
+ (LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 35))
FFMPEG_INLINE
int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
{
- /* TODO: no options are taking into account */
- (void) options;
- return avcodec_open(avctx, codec);
+ /* TODO: no options are taking into account */
+ (void)options;
+ return avcodec_open(avctx, codec);
}
#endif
-#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR < 21))
+#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || \
+ (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR < 21))
FFMPEG_INLINE
AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
{
- /* TODO: no codec is taking into account */
- (void) c;
- return av_new_stream(s, 0);
+ /* TODO: no codec is taking into account */
+ (void)c;
+ return av_new_stream(s, 0);
}
FFMPEG_INLINE
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
{
- /* TODO: no options are taking into account */
- (void) options;
- return av_find_stream_info(ic);
+ /* TODO: no options are taking into account */
+ (void)options;
+ return av_find_stream_info(ic);
}
#endif
-#if ((LIBAVFORMAT_VERSION_MAJOR > 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && (LIBAVFORMAT_VERSION_MICRO >= 100)))
+#if ((LIBAVFORMAT_VERSION_MAJOR > 53) || \
+ ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || \
+ ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && \
+ (LIBAVFORMAT_VERSION_MICRO >= 100)))
FFMPEG_INLINE
void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
- int i;
+ int i;
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
- st->cur_dts = av_rescale(timestamp,
- st->time_base.den * (int64_t)ref_st->time_base.num,
- st->time_base.num * (int64_t)ref_st->time_base.den);
- }
+ st->cur_dts = av_rescale(timestamp,
+ st->time_base.den * (int64_t)ref_st->time_base.num,
+ st->time_base.num * (int64_t)ref_st->time_base.den);
+ }
}
FFMPEG_INLINE
void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
- my_update_cur_dts(s, ref_st, timestamp);
+ my_update_cur_dts(s, ref_st, timestamp);
}
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR < 54) || (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR < 28))
+#if ((LIBAVCODEC_VERSION_MAJOR < 54) || \
+ (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR < 28))
FFMPEG_INLINE
void avcodec_free_frame(AVFrame **frame)
{
- /* don't need to do anything with old AVFrame
- * since it does not have malloced members */
- (void)frame;
+ /* don't need to do anything with old AVFrame
+ * since it does not have malloced members */
+ (void)frame;
}
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
+#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
+ (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
# define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
#endif
-#if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR >= 13))
+#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
+ (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR >= 13))
# define FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
#endif
@@ -374,80 +400,82 @@ void avcodec_free_frame(AVFrame **frame)
#endif
#ifndef FFMPEG_HAVE_DECODE_AUDIO3
-FFMPEG_INLINE
-int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
- int *frame_size_ptr, AVPacket *avpkt)
+FFMPEG_INLINE
+int avcodec_decode_audio3(AVCodecContext *avctx,
+ int16_t *samples,
+ int *frame_size_ptr,
+ AVPacket *avpkt)
{
- return avcodec_decode_audio2(avctx, samples,
- frame_size_ptr, avpkt->data,
- avpkt->size);
+ return avcodec_decode_audio2(avctx, samples, frame_size_ptr, avpkt->data, avpkt->size);
}
#endif
#ifndef FFMPEG_HAVE_DECODE_VIDEO2
FFMPEG_INLINE
-int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
- int *got_picture_ptr,
- AVPacket *avpkt)
+int avcodec_decode_video2(AVCodecContext *avctx,
+ AVFrame *picture,
+ int *got_picture_ptr,
+ AVPacket *avpkt)
{
- return avcodec_decode_video(avctx, picture, got_picture_ptr,
- avpkt->data, avpkt->size);
+ return avcodec_decode_video(avctx, picture, got_picture_ptr, avpkt->data, avpkt->size);
}
#endif
FFMPEG_INLINE
-int64_t av_get_pts_from_frame(AVFormatContext *avctx, AVFrame * picture)
+int64_t av_get_pts_from_frame(AVFormatContext *avctx, AVFrame *picture)
{
- int64_t pts;
+ int64_t pts;
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 34, 100)
- pts = picture->pts;
+ pts = picture->pts;
#else
- pts = picture->pkt_pts;
+ pts = picture->pkt_pts;
#endif
- if (pts == AV_NOPTS_VALUE) {
- pts = picture->pkt_dts;
- }
- if (pts == AV_NOPTS_VALUE) {
- pts = 0;
- }
+ if (pts == AV_NOPTS_VALUE) {
+ pts = picture->pkt_dts;
+ }
+ if (pts == AV_NOPTS_VALUE) {
+ pts = 0;
+ }
- (void)avctx;
- return pts;
+ (void)avctx;
+ return pts;
}
/* obsolete constant formerly defined in FFMpeg libavcodec/avcodec.h */
#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
-# define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
+# define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
#endif
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 1, 0)
FFMPEG_INLINE
-int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *pkt,
- const AVFrame *frame, int *got_output)
+int avcodec_encode_video2(AVCodecContext *avctx,
+ AVPacket *pkt,
+ const AVFrame *frame,
+ int *got_output)
{
- int outsize, ret;
-
- ret = av_new_packet(pkt, avctx->width * avctx->height * 7 + 10000);
- if (ret < 0)
- return ret;
-
- outsize = avcodec_encode_video(avctx, pkt->data, pkt->size, frame);
- if (outsize <= 0) {
- *got_output = 0;
- av_free_packet(pkt);
- }
- else {
- *got_output = 1;
- av_shrink_packet(pkt, outsize);
- if (avctx->coded_frame) {
- pkt->pts = avctx->coded_frame->pts;
- if (avctx->coded_frame->key_frame)
- pkt->flags |= AV_PKT_FLAG_KEY;
- }
- }
-
- return outsize >= 0 ? 0 : outsize;
+ int outsize, ret;
+
+ ret = av_new_packet(pkt, avctx->width * avctx->height * 7 + 10000);
+ if (ret < 0)
+ return ret;
+
+ outsize = avcodec_encode_video(avctx, pkt->data, pkt->size, frame);
+ if (outsize <= 0) {
+ *got_output = 0;
+ av_free_packet(pkt);
+ }
+ else {
+ *got_output = 1;
+ av_shrink_packet(pkt, outsize);
+ if (avctx->coded_frame) {
+ pkt->pts = avctx->coded_frame->pts;
+ if (avctx->coded_frame->key_frame)
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ }
+ }
+
+ return outsize >= 0 ? 0 : outsize;
}
#endif
@@ -456,8 +484,8 @@ int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *pkt,
FFMPEG_INLINE
void avformat_close_input(AVFormatContext **ctx)
{
- av_close_input_file(*ctx);
- *ctx = NULL;
+ av_close_input_file(*ctx);
+ *ctx = NULL;
}
#endif
@@ -465,69 +493,68 @@ void avformat_close_input(AVFormatContext **ctx)
FFMPEG_INLINE
AVFrame *av_frame_alloc(void)
{
- return avcodec_alloc_frame();
+ return avcodec_alloc_frame();
}
FFMPEG_INLINE
void av_frame_free(AVFrame **frame)
{
- av_freep(frame);
+ av_freep(frame);
}
#endif
FFMPEG_INLINE
-const char* av_get_metadata_key_value(AVDictionary *metadata, const char *key)
+const char *av_get_metadata_key_value(AVDictionary *metadata, const char *key)
{
- if (metadata == NULL) {
- return NULL;
- }
- AVDictionaryEntry *tag = NULL;
- while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
- if (!strcmp(tag->key, key)) {
- return tag->value;
- }
- }
- return NULL;
+ if (metadata == NULL) {
+ return NULL;
+ }
+ AVDictionaryEntry *tag = NULL;
+ while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ if (!strcmp(tag->key, key)) {
+ return tag->value;
+ }
+ }
+ return NULL;
}
FFMPEG_INLINE
bool av_check_encoded_with_ffmpeg(AVFormatContext *ctx)
{
- const char* encoder = av_get_metadata_key_value(ctx->metadata, "ENCODER");
- if (encoder != NULL && !strncmp(encoder, "Lavf", 4)) {
- return true;
- }
- return false;
+ const char *encoder = av_get_metadata_key_value(ctx->metadata, "ENCODER");
+ if (encoder != NULL && !strncmp(encoder, "Lavf", 4)) {
+ return true;
+ }
+ return false;
}
FFMPEG_INLINE
-AVRational av_get_r_frame_rate_compat(AVFormatContext *ctx,
- const AVStream *stream)
+AVRational av_get_r_frame_rate_compat(AVFormatContext *ctx, const AVStream *stream)
{
- /* If the video is encoded with FFmpeg and we are decoding with FFmpeg
- * as well it seems to be more reliable to use r_frame_rate (tbr).
- *
- * For other cases we fall back to avg_frame_rate (fps) when possible.
- */
+ /* If the video is encoded with FFmpeg and we are decoding with FFmpeg
+ * as well it seems to be more reliable to use r_frame_rate (tbr).
+ *
+ * For other cases we fall back to avg_frame_rate (fps) when possible.
+ */
#ifdef AV_USING_FFMPEG
- if (av_check_encoded_with_ffmpeg(ctx)) {
- return stream->r_frame_rate;
- }
+ if (av_check_encoded_with_ffmpeg(ctx)) {
+ return stream->r_frame_rate;
+ }
#endif
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 23, 1)
- /* For until r_frame_rate was deprecated use it. */
- return stream->r_frame_rate;
+ /* For until r_frame_rate was deprecated use it. */
+ return stream->r_frame_rate;
#else
# ifdef AV_USING_FFMPEG
- /* Some of the videos might have average frame rate set to, while the
- * r_frame_rate will show a correct value. This happens, for example, for
- * OGG video files saved with Blender. */
- if (stream->avg_frame_rate.den == 0) {
- return stream->r_frame_rate;
- }
+ /* Some of the videos might have average frame rate set to, while the
+ * r_frame_rate will show a correct value. This happens, for example, for
+ * OGG video files saved with Blender. */
+ if (stream->avg_frame_rate.den == 0) {
+ return stream->r_frame_rate;
+ }
# endif
- return stream->avg_frame_rate;
+ return stream->avg_frame_rate;
#endif
}
@@ -559,209 +586,206 @@ AVRational av_get_r_frame_rate_compat(AVFormatContext *ctx,
/* NOTE: The code in this block are from FFmpeg 2.6.4, which is licensed by LGPL. */
-#define MAX_NEG_CROP 1024
+# define MAX_NEG_CROP 1024
-#define times4(x) x, x, x, x
-#define times256(x) times4(times4(times4(times4(times4(x)))))
+# define times4(x) x, x, x, x
+# define times256(x) times4(times4(times4(times4(times4(x)))))
static const uint8_t ff_compat_crop_tab[256 + 2 * MAX_NEG_CROP] = {
-times256(0x00),
-0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
-0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
-0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
-0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
-0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
-0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
-0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
-0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
-0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
-0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
-0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
-0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
-0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
-0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
-0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
-0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
-times256(0xFF)
-};
-
-#undef times4
-#undef times256
+ times256(0x00), 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
+ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
+ 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
+ 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+ 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
+ 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
+ 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
+ 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+ 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82,
+ 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
+ 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
+ 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
+ 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
+ 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
+ 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2,
+ 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
+ 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
+ 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, times256(0xFF)};
+
+# undef times4
+# undef times256
/* filter parameters: [-1 4 2 4 -1] // 8 */
FFMPEG_INLINE
void deinterlace_line(uint8_t *dst,
- const uint8_t *lum_m4, const uint8_t *lum_m3,
- const uint8_t *lum_m2, const uint8_t *lum_m1,
+ const uint8_t *lum_m4,
+ const uint8_t *lum_m3,
+ const uint8_t *lum_m2,
+ const uint8_t *lum_m1,
const uint8_t *lum,
int size)
{
- const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
- int sum;
-
- for(;size > 0;size--) {
- sum = -lum_m4[0];
- sum += lum_m3[0] << 2;
- sum += lum_m2[0] << 1;
- sum += lum_m1[0] << 2;
- sum += -lum[0];
- dst[0] = cm[(sum + 4) >> 3];
- lum_m4++;
- lum_m3++;
- lum_m2++;
- lum_m1++;
- lum++;
- dst++;
- }
+ const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
+ int sum;
+
+ for (; size > 0; size--) {
+ sum = -lum_m4[0];
+ sum += lum_m3[0] << 2;
+ sum += lum_m2[0] << 1;
+ sum += lum_m1[0] << 2;
+ sum += -lum[0];
+ dst[0] = cm[(sum + 4) >> 3];
+ lum_m4++;
+ lum_m3++;
+ lum_m2++;
+ lum_m1++;
+ lum++;
+ dst++;
+ }
}
FFMPEG_INLINE
-void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3,
- uint8_t *lum_m2, uint8_t *lum_m1,
- uint8_t *lum, int size)
+void deinterlace_line_inplace(
+ uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size)
{
- const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
- int sum;
-
- for(;size > 0;size--) {
- sum = -lum_m4[0];
- sum += lum_m3[0] << 2;
- sum += lum_m2[0] << 1;
- lum_m4[0]=lum_m2[0];
- sum += lum_m1[0] << 2;
- sum += -lum[0];
- lum_m2[0] = cm[(sum + 4) >> 3];
- lum_m4++;
- lum_m3++;
- lum_m2++;
- lum_m1++;
- lum++;
- }
+ const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
+ int sum;
+
+ for (; size > 0; size--) {
+ sum = -lum_m4[0];
+ sum += lum_m3[0] << 2;
+ sum += lum_m2[0] << 1;
+ lum_m4[0] = lum_m2[0];
+ sum += lum_m1[0] << 2;
+ sum += -lum[0];
+ lum_m2[0] = cm[(sum + 4) >> 3];
+ lum_m4++;
+ lum_m3++;
+ lum_m2++;
+ lum_m1++;
+ lum++;
+ }
}
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
top field is copied as is, but the bottom field is deinterlaced
against the top field. */
FFMPEG_INLINE
-void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
- const uint8_t *src1, int src_wrap,
- int width, int height)
+void deinterlace_bottom_field(
+ uint8_t *dst, int dst_wrap, const uint8_t *src1, int src_wrap, int width, int height)
{
- const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
- int y;
-
- src_m2 = src1;
- src_m1 = src1;
- src_0=&src_m1[src_wrap];
- src_p1=&src_0[src_wrap];
- src_p2=&src_p1[src_wrap];
- for(y=0;y<(height-2);y+=2) {
- memcpy(dst,src_m1,width);
- dst += dst_wrap;
- deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
- src_m2 = src_0;
- src_m1 = src_p1;
- src_0 = src_p2;
- src_p1 += 2*src_wrap;
- src_p2 += 2*src_wrap;
- dst += dst_wrap;
- }
- memcpy(dst,src_m1,width);
- dst += dst_wrap;
- /* do last line */
- deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
+ const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
+ int y;
+
+ src_m2 = src1;
+ src_m1 = src1;
+ src_0 = &src_m1[src_wrap];
+ src_p1 = &src_0[src_wrap];
+ src_p2 = &src_p1[src_wrap];
+ for (y = 0; y < (height - 2); y += 2) {
+ memcpy(dst, src_m1, width);
+ dst += dst_wrap;
+ deinterlace_line(dst, src_m2, src_m1, src_0, src_p1, src_p2, width);
+ src_m2 = src_0;
+ src_m1 = src_p1;
+ src_0 = src_p2;
+ src_p1 += 2 * src_wrap;
+ src_p2 += 2 * src_wrap;
+ dst += dst_wrap;
+ }
+ memcpy(dst, src_m1, width);
+ dst += dst_wrap;
+ /* do last line */
+ deinterlace_line(dst, src_m2, src_m1, src_0, src_0, src_0, width);
}
FFMPEG_INLINE
-int deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
- int width, int height)
+int deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, int width, int height)
{
- uint8_t *src_m1, *src_0, *src_p1, *src_p2;
- int y;
- uint8_t *buf = (uint8_t *)av_malloc(width);
- if (!buf)
- return AVERROR(ENOMEM);
-
- src_m1 = src1;
- memcpy(buf,src_m1,width);
- src_0=&src_m1[src_wrap];
- src_p1=&src_0[src_wrap];
- src_p2=&src_p1[src_wrap];
- for(y=0;y<(height-2);y+=2) {
- deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
- src_m1 = src_p1;
- src_0 = src_p2;
- src_p1 += 2*src_wrap;
- src_p2 += 2*src_wrap;
- }
- /* do last line */
- deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
- av_free(buf);
- return 0;
+ uint8_t *src_m1, *src_0, *src_p1, *src_p2;
+ int y;
+ uint8_t *buf = (uint8_t *)av_malloc(width);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ src_m1 = src1;
+ memcpy(buf, src_m1, width);
+ src_0 = &src_m1[src_wrap];
+ src_p1 = &src_0[src_wrap];
+ src_p2 = &src_p1[src_wrap];
+ for (y = 0; y < (height - 2); y += 2) {
+ deinterlace_line_inplace(buf, src_m1, src_0, src_p1, src_p2, width);
+ src_m1 = src_p1;
+ src_0 = src_p2;
+ src_p1 += 2 * src_wrap;
+ src_p2 += 2 * src_wrap;
+ }
+ /* do last line */
+ deinterlace_line_inplace(buf, src_m1, src_0, src_0, src_0, width);
+ av_free(buf);
+ return 0;
}
-#ifdef __GNUC__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+# ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+# endif
FFMPEG_INLINE
-int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
- enum AVPixelFormat pix_fmt, int width, int height)
+int avpicture_deinterlace(
+ AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int width, int height)
{
- int i, ret;
-
- if (pix_fmt != AV_PIX_FMT_YUV420P &&
- pix_fmt != AV_PIX_FMT_YUVJ420P &&
- pix_fmt != AV_PIX_FMT_YUV422P &&
- pix_fmt != AV_PIX_FMT_YUVJ422P &&
- pix_fmt != AV_PIX_FMT_YUV444P &&
- pix_fmt != AV_PIX_FMT_YUV411P &&
- pix_fmt != AV_PIX_FMT_GRAY8)
- return -1;
- if ((width & 3) != 0 || (height & 3) != 0)
- return -1;
-
- for(i=0;i<3;i++) {
- if (i == 1) {
- switch(pix_fmt) {
- case AV_PIX_FMT_YUVJ420P:
- case AV_PIX_FMT_YUV420P:
- width >>= 1;
- height >>= 1;
- break;
- case AV_PIX_FMT_YUV422P:
- case AV_PIX_FMT_YUVJ422P:
- width >>= 1;
- break;
- case AV_PIX_FMT_YUV411P:
- width >>= 2;
- break;
- default:
- break;
- }
- if (pix_fmt == AV_PIX_FMT_GRAY8) {
- break;
- }
- }
- if (src == dst) {
- ret = deinterlace_bottom_field_inplace(dst->data[i],
- dst->linesize[i],
- width, height);
- if (ret < 0)
- return ret;
- } else {
- deinterlace_bottom_field(dst->data[i],dst->linesize[i],
- src->data[i], src->linesize[i],
- width, height);
- }
- }
- return 0;
+ int i, ret;
+
+ if (pix_fmt != AV_PIX_FMT_YUV420P && pix_fmt != AV_PIX_FMT_YUVJ420P &&
+ pix_fmt != AV_PIX_FMT_YUV422P && pix_fmt != AV_PIX_FMT_YUVJ422P &&
+ pix_fmt != AV_PIX_FMT_YUV444P && pix_fmt != AV_PIX_FMT_YUV411P &&
+ pix_fmt != AV_PIX_FMT_GRAY8)
+ return -1;
+ if ((width & 3) != 0 || (height & 3) != 0)
+ return -1;
+
+ for (i = 0; i < 3; i++) {
+ if (i == 1) {
+ switch (pix_fmt) {
+ case AV_PIX_FMT_YUVJ420P:
+ case AV_PIX_FMT_YUV420P:
+ width >>= 1;
+ height >>= 1;
+ break;
+ case AV_PIX_FMT_YUV422P:
+ case AV_PIX_FMT_YUVJ422P:
+ width >>= 1;
+ break;
+ case AV_PIX_FMT_YUV411P:
+ width >>= 2;
+ break;
+ default:
+ break;
+ }
+ if (pix_fmt == AV_PIX_FMT_GRAY8) {
+ break;
+ }
+ }
+ if (src == dst) {
+ ret = deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], width, height);
+ if (ret < 0)
+ return ret;
+ }
+ else {
+ deinterlace_bottom_field(
+ dst->data[i], dst->linesize[i], src->data[i], src->linesize[i], width, height);
+ }
+ }
+ return 0;
}
-#ifdef __GNUC__
-# pragma GCC diagnostic pop
-#endif
+# ifdef __GNUC__
+# pragma GCC diagnostic pop
+# endif
#endif
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index a43906cea85..b096fecced8 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -19,329 +19,329 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../glew-mx
- ../string
- ../../source/blender/imbuf
- ../../source/blender/makesdna
+ .
+ ../glew-mx
+ ../string
+ ../../source/blender/imbuf
+ ../../source/blender/makesdna
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- intern/GHOST_Buttons.cpp
- intern/GHOST_C-api.cpp
- intern/GHOST_CallbackEventConsumer.cpp
- intern/GHOST_Context.cpp
- intern/GHOST_ContextNone.cpp
- intern/GHOST_DisplayManager.cpp
- intern/GHOST_EventManager.cpp
- intern/GHOST_ISystem.cpp
- intern/GHOST_ISystemPaths.cpp
- intern/GHOST_ModifierKeys.cpp
- intern/GHOST_Path-api.cpp
- intern/GHOST_Rect.cpp
- intern/GHOST_System.cpp
- intern/GHOST_TimerManager.cpp
- intern/GHOST_Window.cpp
- intern/GHOST_WindowManager.cpp
-
- GHOST_C-api.h
- GHOST_IContext.h
- GHOST_IEvent.h
- GHOST_IEventConsumer.h
- GHOST_ISystem.h
- GHOST_ISystemPaths.h
- GHOST_ITimerTask.h
- GHOST_IWindow.h
- GHOST_Path-api.h
- GHOST_Rect.h
- GHOST_Types.h
-
- intern/GHOST_Buttons.h
- intern/GHOST_CallbackEventConsumer.h
- intern/GHOST_Context.h
- intern/GHOST_ContextNone.h
- intern/GHOST_Debug.h
- intern/GHOST_DisplayManager.h
- intern/GHOST_Event.h
- intern/GHOST_EventButton.h
- intern/GHOST_EventCursor.h
- intern/GHOST_EventDragnDrop.h
- intern/GHOST_EventKey.h
- intern/GHOST_EventManager.h
- intern/GHOST_EventString.h
- intern/GHOST_EventTrackpad.h
- intern/GHOST_EventWheel.h
- intern/GHOST_ModifierKeys.h
- intern/GHOST_System.h
- intern/GHOST_SystemPaths.h
- intern/GHOST_TimerManager.h
- intern/GHOST_TimerTask.h
- intern/GHOST_Window.h
- intern/GHOST_WindowManager.h
+ intern/GHOST_Buttons.cpp
+ intern/GHOST_C-api.cpp
+ intern/GHOST_CallbackEventConsumer.cpp
+ intern/GHOST_Context.cpp
+ intern/GHOST_ContextNone.cpp
+ intern/GHOST_DisplayManager.cpp
+ intern/GHOST_EventManager.cpp
+ intern/GHOST_ISystem.cpp
+ intern/GHOST_ISystemPaths.cpp
+ intern/GHOST_ModifierKeys.cpp
+ intern/GHOST_Path-api.cpp
+ intern/GHOST_Rect.cpp
+ intern/GHOST_System.cpp
+ intern/GHOST_TimerManager.cpp
+ intern/GHOST_Window.cpp
+ intern/GHOST_WindowManager.cpp
+
+ GHOST_C-api.h
+ GHOST_IContext.h
+ GHOST_IEvent.h
+ GHOST_IEventConsumer.h
+ GHOST_ISystem.h
+ GHOST_ISystemPaths.h
+ GHOST_ITimerTask.h
+ GHOST_IWindow.h
+ GHOST_Path-api.h
+ GHOST_Rect.h
+ GHOST_Types.h
+
+ intern/GHOST_Buttons.h
+ intern/GHOST_CallbackEventConsumer.h
+ intern/GHOST_Context.h
+ intern/GHOST_ContextNone.h
+ intern/GHOST_Debug.h
+ intern/GHOST_DisplayManager.h
+ intern/GHOST_Event.h
+ intern/GHOST_EventButton.h
+ intern/GHOST_EventCursor.h
+ intern/GHOST_EventDragnDrop.h
+ intern/GHOST_EventKey.h
+ intern/GHOST_EventManager.h
+ intern/GHOST_EventString.h
+ intern/GHOST_EventTrackpad.h
+ intern/GHOST_EventWheel.h
+ intern/GHOST_ModifierKeys.h
+ intern/GHOST_System.h
+ intern/GHOST_SystemPaths.h
+ intern/GHOST_TimerManager.h
+ intern/GHOST_TimerTask.h
+ intern/GHOST_Window.h
+ intern/GHOST_WindowManager.h
)
set(LIB
- bf_intern_glew_mx
- bf_intern_string
- ${GLEW_LIBRARY}
+ bf_intern_glew_mx
+ bf_intern_string
+ ${GLEW_LIBRARY}
)
if(WITH_GHOST_DEBUG)
- list(APPEND SRC
- intern/GHOST_EventPrinter.cpp
+ list(APPEND SRC
+ intern/GHOST_EventPrinter.cpp
- intern/GHOST_EventPrinter.h
- )
- add_definitions(-DWITH_GHOST_DEBUG)
+ intern/GHOST_EventPrinter.h
+ )
+ add_definitions(-DWITH_GHOST_DEBUG)
endif()
if(WITH_INPUT_NDOF)
- add_definitions(-DWITH_INPUT_NDOF)
+ add_definitions(-DWITH_INPUT_NDOF)
- list(APPEND SRC
- intern/GHOST_NDOFManager.cpp
+ list(APPEND SRC
+ intern/GHOST_NDOFManager.cpp
- intern/GHOST_EventNDOF.h
- intern/GHOST_NDOFManager.h
- )
+ intern/GHOST_EventNDOF.h
+ intern/GHOST_NDOFManager.h
+ )
- list(APPEND INC_SYS
- ${NDOF_INCLUDE_DIRS}
- )
+ list(APPEND INC_SYS
+ ${NDOF_INCLUDE_DIRS}
+ )
endif()
if(WITH_HEADLESS OR WITH_GHOST_SDL)
- if(WITH_HEADLESS)
- list(APPEND SRC
- intern/GHOST_DisplayManagerNULL.h
- intern/GHOST_SystemNULL.h
- intern/GHOST_WindowNULL.h
- )
- add_definitions(-DWITH_HEADLESS)
- else()
- list(APPEND SRC
- intern/GHOST_ContextSDL.cpp
- intern/GHOST_DisplayManagerSDL.cpp
- intern/GHOST_SystemSDL.cpp
- intern/GHOST_WindowSDL.cpp
-
- intern/GHOST_ContextSDL.h
- intern/GHOST_DisplayManagerSDL.h
- intern/GHOST_SystemSDL.h
- intern/GHOST_WindowSDL.h
- )
- add_definitions(-DWITH_GHOST_SDL)
- endif()
-
- if(NOT WITH_HEADLESS)
- list(APPEND INC_SYS
- ${SDL_INCLUDE_DIR}
- )
- endif()
+ if(WITH_HEADLESS)
+ list(APPEND SRC
+ intern/GHOST_DisplayManagerNULL.h
+ intern/GHOST_SystemNULL.h
+ intern/GHOST_WindowNULL.h
+ )
+ add_definitions(-DWITH_HEADLESS)
+ else()
+ list(APPEND SRC
+ intern/GHOST_ContextSDL.cpp
+ intern/GHOST_DisplayManagerSDL.cpp
+ intern/GHOST_SystemSDL.cpp
+ intern/GHOST_WindowSDL.cpp
+
+ intern/GHOST_ContextSDL.h
+ intern/GHOST_DisplayManagerSDL.h
+ intern/GHOST_SystemSDL.h
+ intern/GHOST_WindowSDL.h
+ )
+ add_definitions(-DWITH_GHOST_SDL)
+ endif()
+
+ if(NOT WITH_HEADLESS)
+ list(APPEND INC_SYS
+ ${SDL_INCLUDE_DIR}
+ )
+ endif()
elseif(APPLE AND NOT WITH_X11)
- list(APPEND SRC
- intern/GHOST_DisplayManagerCocoa.mm
- intern/GHOST_SystemCocoa.mm
- intern/GHOST_WindowCocoa.mm
+ list(APPEND SRC
+ intern/GHOST_DisplayManagerCocoa.mm
+ intern/GHOST_SystemCocoa.mm
+ intern/GHOST_WindowCocoa.mm
- intern/GHOST_DisplayManagerCocoa.h
- intern/GHOST_SystemCocoa.h
- intern/GHOST_WindowCocoa.h
- )
+ intern/GHOST_DisplayManagerCocoa.h
+ intern/GHOST_SystemCocoa.h
+ intern/GHOST_WindowCocoa.h
+ )
- if(NOT WITH_GL_EGL)
- list(APPEND SRC
- intern/GHOST_ContextCGL.mm
+ if(NOT WITH_GL_EGL)
+ list(APPEND SRC
+ intern/GHOST_ContextCGL.mm
- intern/GHOST_ContextCGL.h
- )
- endif()
+ intern/GHOST_ContextCGL.h
+ )
+ endif()
- if(WITH_INPUT_NDOF)
- list(APPEND SRC
- intern/GHOST_NDOFManagerCocoa.mm
+ if(WITH_INPUT_NDOF)
+ list(APPEND SRC
+ intern/GHOST_NDOFManagerCocoa.mm
- intern/GHOST_NDOFManagerCocoa.h
- )
- endif()
+ intern/GHOST_NDOFManagerCocoa.h
+ )
+ endif()
elseif(WITH_X11)
- list(APPEND INC_SYS
- ${X11_X11_INCLUDE_PATH}
- )
-
- list(APPEND SRC
- intern/GHOST_DisplayManagerX11.cpp
- intern/GHOST_SystemX11.cpp
- intern/GHOST_TaskbarX11.cpp
- intern/GHOST_WindowX11.cpp
-
- intern/GHOST_DisplayManagerX11.h
- intern/GHOST_SystemX11.h
- intern/GHOST_TaskbarX11.h
- intern/GHOST_WindowX11.h
- )
-
- if(NOT WITH_GL_EGL)
- list(APPEND SRC
- intern/GHOST_ContextGLX.cpp
-
- intern/GHOST_ContextGLX.h
- )
- endif()
-
- if(WITH_GHOST_XDND)
- add_definitions(-DWITH_XDND)
-
- list(APPEND LIB
- extern_xdnd
- )
-
- list(APPEND INC
- ../../extern/xdnd
- )
-
- list(APPEND SRC
- intern/GHOST_DropTargetX11.cpp
-
- intern/GHOST_DropTargetX11.h
- )
- endif()
-
- if(X11_XF86keysym_INCLUDE_PATH)
- add_definitions(-DWITH_XF86KEYSYM)
- list(APPEND INC_SYS
- ${X11_XF86keysym_INCLUDE_PATH}
- )
- endif()
-
- if(WITH_X11_XF86VMODE)
- add_definitions(-DWITH_X11_XF86VMODE)
- list(APPEND INC_SYS
- ${X11_xf86vmode_INCLUDE_PATH}
- )
- endif()
-
- if(WITH_X11_XFIXES)
- add_definitions(-DWITH_X11_XFIXES)
- list(APPEND INC_SYS
- ${X11_Xfixes_INCLUDE_PATH}
- )
- endif()
-
- if(WITH_X11_ALPHA)
- add_definitions(-DWITH_X11_ALPHA)
- endif()
-
- if(WITH_INPUT_NDOF)
- list(APPEND SRC
- intern/GHOST_NDOFManagerUnix.cpp
-
- intern/GHOST_NDOFManagerUnix.h
- )
- endif()
-
- if(NOT WITH_INSTALL_PORTABLE)
- add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
- endif()
-
- if(WITH_X11_XINPUT)
- add_definitions(-DWITH_X11_XINPUT)
- list(APPEND INC_SYS
- ${X11_Xinput_INCLUDE_PATH}
- )
- endif()
-
- add_definitions(-DWITH_X11)
+ list(APPEND INC_SYS
+ ${X11_X11_INCLUDE_PATH}
+ )
+
+ list(APPEND SRC
+ intern/GHOST_DisplayManagerX11.cpp
+ intern/GHOST_SystemX11.cpp
+ intern/GHOST_TaskbarX11.cpp
+ intern/GHOST_WindowX11.cpp
+
+ intern/GHOST_DisplayManagerX11.h
+ intern/GHOST_SystemX11.h
+ intern/GHOST_TaskbarX11.h
+ intern/GHOST_WindowX11.h
+ )
+
+ if(NOT WITH_GL_EGL)
+ list(APPEND SRC
+ intern/GHOST_ContextGLX.cpp
+
+ intern/GHOST_ContextGLX.h
+ )
+ endif()
+
+ if(WITH_GHOST_XDND)
+ add_definitions(-DWITH_XDND)
+
+ list(APPEND LIB
+ extern_xdnd
+ )
+
+ list(APPEND INC
+ ../../extern/xdnd
+ )
+
+ list(APPEND SRC
+ intern/GHOST_DropTargetX11.cpp
+
+ intern/GHOST_DropTargetX11.h
+ )
+ endif()
+
+ if(X11_XF86keysym_INCLUDE_PATH)
+ add_definitions(-DWITH_XF86KEYSYM)
+ list(APPEND INC_SYS
+ ${X11_XF86keysym_INCLUDE_PATH}
+ )
+ endif()
+
+ if(WITH_X11_XF86VMODE)
+ add_definitions(-DWITH_X11_XF86VMODE)
+ list(APPEND INC_SYS
+ ${X11_xf86vmode_INCLUDE_PATH}
+ )
+ endif()
+
+ if(WITH_X11_XFIXES)
+ add_definitions(-DWITH_X11_XFIXES)
+ list(APPEND INC_SYS
+ ${X11_Xfixes_INCLUDE_PATH}
+ )
+ endif()
+
+ if(WITH_X11_ALPHA)
+ add_definitions(-DWITH_X11_ALPHA)
+ endif()
+
+ if(WITH_INPUT_NDOF)
+ list(APPEND SRC
+ intern/GHOST_NDOFManagerUnix.cpp
+
+ intern/GHOST_NDOFManagerUnix.h
+ )
+ endif()
+
+ if(NOT WITH_INSTALL_PORTABLE)
+ add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
+ endif()
+
+ if(WITH_X11_XINPUT)
+ add_definitions(-DWITH_X11_XINPUT)
+ list(APPEND INC_SYS
+ ${X11_Xinput_INCLUDE_PATH}
+ )
+ endif()
+
+ add_definitions(-DWITH_X11)
elseif(WIN32)
- ## Warnings as errors, this is too strict!
- #if(MSVC)
- # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
- #endif()
-
- list(APPEND INC_SYS
- ${WINTAB_INC}
- )
-
- list(APPEND SRC
- intern/GHOST_DisplayManagerWin32.cpp
- intern/GHOST_DropTargetWin32.cpp
- intern/GHOST_SystemWin32.cpp
- intern/GHOST_WindowWin32.cpp
-
- intern/GHOST_DisplayManagerWin32.h
- intern/GHOST_DropTargetWin32.h
- intern/GHOST_SystemWin32.h
- intern/GHOST_TaskbarWin32.h
- intern/GHOST_WindowWin32.h
- )
-
- if(NOT WITH_GL_EGL)
- list(APPEND SRC
- intern/GHOST_ContextWGL.cpp
-
- intern/GHOST_ContextWGL.h
- )
- endif()
-
- if(WITH_INPUT_IME)
- add_definitions(-DWITH_INPUT_IME)
-
- list(APPEND SRC
- intern/GHOST_ImeWin32.cpp
-
- intern/GHOST_ImeWin32.h
- )
- endif()
-
- if(WITH_INPUT_NDOF)
- list(APPEND SRC
- intern/GHOST_NDOFManagerWin32.cpp
-
- intern/GHOST_NDOFManagerWin32.h
- )
- endif()
+ ## Warnings as errors, this is too strict!
+ #if(MSVC)
+ # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
+ #endif()
+
+ list(APPEND INC_SYS
+ ${WINTAB_INC}
+ )
+
+ list(APPEND SRC
+ intern/GHOST_DisplayManagerWin32.cpp
+ intern/GHOST_DropTargetWin32.cpp
+ intern/GHOST_SystemWin32.cpp
+ intern/GHOST_WindowWin32.cpp
+
+ intern/GHOST_DisplayManagerWin32.h
+ intern/GHOST_DropTargetWin32.h
+ intern/GHOST_SystemWin32.h
+ intern/GHOST_TaskbarWin32.h
+ intern/GHOST_WindowWin32.h
+ )
+
+ if(NOT WITH_GL_EGL)
+ list(APPEND SRC
+ intern/GHOST_ContextWGL.cpp
+
+ intern/GHOST_ContextWGL.h
+ )
+ endif()
+
+ if(WITH_INPUT_IME)
+ add_definitions(-DWITH_INPUT_IME)
+
+ list(APPEND SRC
+ intern/GHOST_ImeWin32.cpp
+
+ intern/GHOST_ImeWin32.h
+ )
+ endif()
+
+ if(WITH_INPUT_NDOF)
+ list(APPEND SRC
+ intern/GHOST_NDOFManagerWin32.cpp
+
+ intern/GHOST_NDOFManagerWin32.h
+ )
+ endif()
endif()
if(WITH_GL_EGL AND NOT (WITH_HEADLESS OR WITH_GHOST_SDL))
- list(APPEND SRC
- intern/GHOST_ContextEGL.cpp
+ list(APPEND SRC
+ intern/GHOST_ContextEGL.cpp
- intern/GHOST_ContextEGL.h
- )
+ intern/GHOST_ContextEGL.h
+ )
endif()
if(APPLE)
- list(APPEND SRC
- intern/GHOST_SystemPathsCocoa.h
- intern/GHOST_SystemPathsCocoa.mm
- )
+ list(APPEND SRC
+ intern/GHOST_SystemPathsCocoa.h
+ intern/GHOST_SystemPathsCocoa.mm
+ )
elseif(UNIX)
- list(APPEND SRC
- intern/GHOST_SystemPathsUnix.cpp
- intern/GHOST_SystemPathsUnix.h
- )
+ list(APPEND SRC
+ intern/GHOST_SystemPathsUnix.cpp
+ intern/GHOST_SystemPathsUnix.h
+ )
- if(NOT WITH_INSTALL_PORTABLE)
- add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
- endif()
+ if(NOT WITH_INSTALL_PORTABLE)
+ add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
+ endif()
elseif(WIN32)
- list(APPEND SRC
- intern/GHOST_SystemPathsWin32.cpp
- intern/GHOST_SystemPathsWin32.h
- )
-
- list(APPEND INC
- ../utfconv
- )
+ list(APPEND SRC
+ intern/GHOST_SystemPathsWin32.cpp
+ intern/GHOST_SystemPathsWin32.h
+ )
+
+ list(APPEND INC
+ ../utfconv
+ )
endif()
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index fbc0662ca4f..8bb6a670754 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -45,7 +45,6 @@ GHOST_DECLARE_HANDLE(GHOST_RectangleHandle);
GHOST_DECLARE_HANDLE(GHOST_EventConsumerHandle);
GHOST_DECLARE_HANDLE(GHOST_ContextHandle);
-
/**
* Definition of a callback routine that receives events.
* \param event The event received.
@@ -53,7 +52,6 @@ GHOST_DECLARE_HANDLE(GHOST_ContextHandle);
*/
typedef int (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserDataPtr userdata);
-
/**
* Creates the one and only system.
* \return a handle to the system.
@@ -67,14 +65,13 @@ extern GHOST_SystemHandle GHOST_CreateSystem(void);
*/
extern GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle);
-
/**
* Creates an event consumer object
* \param eventCallback The event callback routine.
* \param userdata Pointer to user data returned to the callback routine.
*/
-extern GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
- GHOST_TUserDataPtr userdata);
+extern GHOST_EventConsumerHandle GHOST_CreateEventConsumer(
+ GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata);
/**
* Disposes an event consumer object
@@ -150,9 +147,8 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
* \return void.
*/
extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
- GHOST_TUns32 *width,
- GHOST_TUns32 *height);
-
+ GHOST_TUns32 *width,
+ GHOST_TUns32 *height);
/**
* Create a new window.
@@ -169,16 +165,15 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
* \param glSettings: Misc OpenGL options.
* \return A handle to the new window ( == NULL if creation failed).
*/
-extern GHOST_WindowHandle GHOST_CreateWindow(
- GHOST_SystemHandle systemhandle,
- const char *title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings);
+extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
+ const char *title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings);
/**
* Create a new offscreen context.
@@ -195,7 +190,7 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha
* \return Indication of success.
*/
extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
- GHOST_ContextHandle contexthandle);
+ GHOST_ContextHandle contexthandle);
/**
* Returns the window user data.
@@ -209,8 +204,7 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl
* \param windowhandle The handle to the window
* \param userdata The window user data.
*/
-extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle,
- GHOST_TUserDataPtr userdata);
+extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata);
/**
* Dispose a window.
@@ -227,8 +221,7 @@ extern GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
* \param windowhandle Handle to the window to be checked.
* \return Indication of validity.
*/
-extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle,
- GHOST_WindowHandle windowhandle);
+extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle);
/**
* Begins full screen mode.
@@ -359,9 +352,12 @@ extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle
extern GHOST_TSuccess GHOST_SetCustomCursorShapeEx(GHOST_WindowHandle windowhandle,
GHOST_TUns8 *bitmap,
GHOST_TUns8 *mask,
- int sizex, int sizey,
- int hotX, int hotY,
- int fg_color, int bg_color);
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color);
/**
* Returns the visibility state of the cursor.
@@ -376,8 +372,7 @@ extern int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle);
* \param visible The new visibility state of the cursor.
* \return Indication of success.
*/
-extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle,
- int visible);
+extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible);
/**
* Returns the current location of the cursor (location in screen coordinates)
@@ -414,7 +409,8 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
*/
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
GHOST_TGrabCursorMode mode,
- int bounds[4], const int mouse_ungrab_xy[2]);
+ int bounds[4],
+ const int mouse_ungrab_xy[2]);
/***************************************************************************************
* Access to mouse button and keyboard states.
@@ -454,7 +450,6 @@ extern GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
extern void GHOST_setNDOFDeadZone(float deadzone);
#endif
-
/***************************************************************************************
* Drag'n'drop operations
***************************************************************************************/
@@ -551,8 +546,7 @@ extern GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandl
* \param windowhandle The handle to the window
* \param title The title to display in the title bar.
*/
-extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle,
- const char *title);
+extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title);
/**
* Returns the title displayed in the title bar. The title
@@ -591,8 +585,7 @@ void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle);
* \param width The new width of the client area of the window.
* \return Indication of success.
*/
-extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle,
- GHOST_TUns32 width);
+extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width);
/**
* Resizes client rectangle height.
@@ -600,8 +593,7 @@ extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle,
* \param height The new height of the client area of the window.
* \return Indication of success.
*/
-extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle,
- GHOST_TUns32 height);
+extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height);
/**
* Resizes client rectangle.
@@ -658,7 +650,6 @@ extern GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle);
extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
GHOST_TWindowState state);
-
/**
* Sets the window "modified" status, indicating unsaved changes
* \param windowhandle The handle to the window
@@ -697,7 +688,7 @@ extern GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int
* \param intervalOut pointer to location to return swap interval (left untouched if there is an error)
* \return A boolean success indicator of if swap interval was successfully read.
*/
-extern GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int* intervalOut);
+extern GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int *intervalOut);
/**
* Gets the current swap interval for swapBuffers.
@@ -811,8 +802,7 @@ extern GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehand
* \param rectanglehandle The handle to the rectangle
* \param i The amount of offset given to each extreme (negative values shrink the rectangle).
*/
-extern void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle,
- GHOST_TInt32 i);
+extern void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i);
/**
* Does a union of the rectangle given and this rectangle.
@@ -851,8 +841,8 @@ extern GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehan
* \param anotherrectanglehandle The rectangle to test.
* \return visibility (not, partially or fully visible).
*/
-extern GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle,
- GHOST_RectangleHandle anotherrectanglehandle);
+extern GHOST_TVisibility GHOST_GetRectangleVisibility(
+ GHOST_RectangleHandle rectanglehandle, GHOST_RectangleHandle anotherrectanglehandle);
/**
* Sets rectangle members.
@@ -906,8 +896,6 @@ extern GHOST_TUns8 *GHOST_getClipboard(int selection);
*/
extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection);
-
-
/**
* Toggles console
* \param action
@@ -920,7 +908,6 @@ extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection);
*/
extern int GHOST_toggleConsole(int action);
-
/**
* Confirms quitting he program when there is just one window left open
* in the application
@@ -965,11 +952,11 @@ extern GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle);
* false: Move the IME windows to the given position without finishing it.
*/
extern void GHOST_BeginIME(GHOST_WindowHandle windowhandle,
- GHOST_TInt32 x,
- GHOST_TInt32 y,
- GHOST_TInt32 w,
- GHOST_TInt32 h,
- int complete);
+ GHOST_TInt32 x,
+ GHOST_TInt32 y,
+ GHOST_TInt32 w,
+ GHOST_TInt32 h,
+ int complete);
/**
* Disable the IME attached to the given window, i.e. prohibits any user-input
* events from being dispatched to the IME.
diff --git a/intern/ghost/GHOST_IContext.h b/intern/ghost/GHOST_IContext.h
index 3bc18b9a6c7..a341e18ca0a 100644
--- a/intern/ghost/GHOST_IContext.h
+++ b/intern/ghost/GHOST_IContext.h
@@ -28,7 +28,6 @@
#include "STR_String.h"
#include "GHOST_Types.h"
-
/**
* Interface for GHOST context.
*
@@ -36,31 +35,30 @@
* GHOST_ISystem::createOffscreenContext method.
* \see GHOST_ISystem#createOffscreenContext
*/
-class GHOST_IContext
-{
-public:
- /**
- * Destructor.
- */
- virtual ~GHOST_IContext()
- {
- }
+class GHOST_IContext {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_IContext()
+ {
+ }
- /**
- * Activates the drawing context.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess activateDrawingContext() = 0;
+ /**
+ * Activates the drawing context.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess activateDrawingContext() = 0;
- /**
- * Release the drawing context of the calling thread.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess releaseDrawingContext() = 0;
+ /**
+ * Release the drawing context of the calling thread.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess releaseDrawingContext() = 0;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext")
#endif
};
-#endif // __GHOST_IContext_H__
+#endif // __GHOST_IContext_H__
diff --git a/intern/ghost/GHOST_IEvent.h b/intern/ghost/GHOST_IEvent.h
index eadb29ef61c..fc7e563e1d8 100644
--- a/intern/ghost/GHOST_IEvent.h
+++ b/intern/ghost/GHOST_IEvent.h
@@ -40,44 +40,43 @@ class GHOST_IWindow;
* \see GHOST_IEventConsumer#processEvent
* \see GHOST_TEventType
*/
-class GHOST_IEvent
-{
-public:
- /**
- * Destructor.
- */
- virtual ~GHOST_IEvent()
- {
- }
+class GHOST_IEvent {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_IEvent()
+ {
+ }
- /**
- * Returns the event type.
- * \return The event type.
- */
- virtual GHOST_TEventType getType() = 0;
+ /**
+ * Returns the event type.
+ * \return The event type.
+ */
+ virtual GHOST_TEventType getType() = 0;
- /**
- * Returns the time this event was generated.
- * \return The event generation time.
- */
- virtual GHOST_TUns64 getTime() = 0;
+ /**
+ * Returns the time this event was generated.
+ * \return The event generation time.
+ */
+ virtual GHOST_TUns64 getTime() = 0;
- /**
- * Returns the window this event was generated on,
- * or NULL if it is a 'system' event.
- * \return The generating window.
- */
- virtual GHOST_IWindow *getWindow() = 0;
+ /**
+ * Returns the window this event was generated on,
+ * or NULL if it is a 'system' event.
+ * \return The generating window.
+ */
+ virtual GHOST_IWindow *getWindow() = 0;
- /**
- * Returns the event data.
- * \return The event data.
- */
- virtual GHOST_TEventDataPtr getData() = 0;
+ /**
+ * Returns the event data.
+ * \return The event data.
+ */
+ virtual GHOST_TEventDataPtr getData() = 0;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEvent")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEvent")
#endif
};
-#endif // __GHOST_IEVENT_H__
+#endif // __GHOST_IEVENT_H__
diff --git a/intern/ghost/GHOST_IEventConsumer.h b/intern/ghost/GHOST_IEventConsumer.h
index 1568a5e4600..d677a632a4b 100644
--- a/intern/ghost/GHOST_IEventConsumer.h
+++ b/intern/ghost/GHOST_IEventConsumer.h
@@ -35,27 +35,26 @@
* for every installed event consumer to pass events.
* \see GHOST_ISystem#addEventConsumer
*/
-class GHOST_IEventConsumer
-{
-public:
- /**
- * Destructor.
- */
- virtual ~GHOST_IEventConsumer()
- {
- }
+class GHOST_IEventConsumer {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_IEventConsumer()
+ {
+ }
- /**
- * This method is called by the system when it has events to dispatch.
- * \see GHOST_ISystem#dispatchEvents
- * \param event The event that can be handled or ignored.
- * \return Indication as to whether the event was handled.
- */
- virtual bool processEvent(GHOST_IEvent *event) = 0;
+ /**
+ * This method is called by the system when it has events to dispatch.
+ * \see GHOST_ISystem#dispatchEvents
+ * \param event The event that can be handled or ignored.
+ * \return Indication as to whether the event was handled.
+ */
+ virtual bool processEvent(GHOST_IEvent *event) = 0;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEventConsumer")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEventConsumer")
#endif
};
-#endif /* __GHOST_IEVENTCONSUMER_H__ */
+#endif /* __GHOST_IEVENTCONSUMER_H__ */
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index c640b016a5e..66e37a525c0 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -128,338 +128,343 @@ class GHOST_IEventConsumer;
* -# Menus for windows with events generated when they are accessed (this is
* work in progress).
*/
-class GHOST_ISystem
-{
-public:
- /**
- * Creates the one and only system.
- * \return An indication of success.
- */
- static GHOST_TSuccess createSystem();
-
- /**
- * Disposes the one and only system.
- * \return An indication of success.
- */
- static GHOST_TSuccess disposeSystem();
-
- /**
- * Returns a pointer to the one and only system (nil if it hasn't been created).
- * \return A pointer to the system.
- */
- static GHOST_ISystem *getSystem();
-
-protected:
- /**
- * Constructor.
- * Protected default constructor to force use of static createSystem member.
- */
- GHOST_ISystem() {
- }
-
- /**
- * Destructor.
- * Protected default constructor to force use of static dispose member.
- */
- virtual ~GHOST_ISystem() {
- }
-
-public:
- /***************************************************************************************
- * Time(r) functionality
- ***************************************************************************************/
-
- /**
- * Returns the system time.
- * Returns the number of milliseconds since the start of the system process.
- * Based on ANSI clock() routine.
- * \return The number of milliseconds.
- */
- virtual GHOST_TUns64 getMilliSeconds() const = 0;
-
- /**
- * Installs a timer.
- * Note that, on most operating systems, messages need to be processed in order
- * for the timer callbacks to be invoked.
- * \param delay The time to wait for the first call to the timerProc (in milliseconds)
- * \param interval The interval between calls to the timerProc (in milliseconds)
- * \param timerProc The callback invoked when the interval expires,
- * \param userData Placeholder for user data.
- * \return A timer task (0 if timer task installation failed).
- */
- virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
- GHOST_TUns64 interval,
- GHOST_TimerProcPtr timerProc,
- GHOST_TUserDataPtr userData = NULL) = 0;
-
- /**
- * Removes a timer.
- * \param timerTask Timer task to be removed.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask) = 0;
-
- /***************************************************************************************
- * Display/window management functionality
- ***************************************************************************************/
-
- /**
- * Returns the number of displays on this system.
- * \return The number of displays.
- */
- virtual GHOST_TUns8 getNumDisplays() const = 0;
-
- /**
- * Returns the dimensions of the main display on this system.
- * \return The dimension of the main display.
- */
- virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const = 0;
-
- /**
- * Returns the combine dimensions of all monitors.
- * \return The dimension of the workspace.
- */
- virtual void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const = 0;
-
- /**
- * Create a new window.
- * The new window is added to the list of windows managed.
- * Never explicitly delete the window, use disposeWindow() instead.
- * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
- * \param left The coordinate of the left edge of the window.
- * \param top The coordinate of the top edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state of the window when opened.
- * \param type The type of drawing context installed in this window.
- * \param glSettings: Misc OpenGL settings.
- * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
- * \param parentWindow Parent (embedder) window
- * \return The new window (or 0 if creation failed).
- */
- virtual GHOST_IWindow *createWindow(
- const STR_String& title,
- GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
- GHOST_TWindowState state, GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive = false,
- const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
-
- /**
- * Dispose a window.
- * \param window Pointer to the window to be disposed.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess disposeWindow(GHOST_IWindow *window) = 0;
-
- /**
- * Create a new offscreen context.
- * Never explicitly delete the context, use disposeContext() instead.
- * \return The new context (or 0 if creation failed).
- */
- virtual GHOST_IContext *createOffscreenContext() = 0;
-
- /**
- * Dispose of a context.
- * \param context Pointer to the context to be disposed.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess disposeContext(GHOST_IContext *context) = 0;
-
- /**
- * Returns whether a window is valid.
- * \param window Pointer to the window to be checked.
- * \return Indication of validity.
- */
- virtual bool validWindow(GHOST_IWindow *window) = 0;
-
- /**
- * Begins full screen mode.
- * \param setting The new setting of the display.
- * \param window Window displayed in full screen.
- * This window is invalid after full screen has been ended.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess beginFullScreen(
- const GHOST_DisplaySetting& setting, GHOST_IWindow **window,
- const bool stereoVisual, const bool alphaBackground = 0, const GHOST_TUns16 numOfAASamples = 0) = 0;
-
- /**
- * Updates the resolution while in fullscreen mode.
- * \param setting The new setting of the display.
- * \param window Window displayed in full screen.
- *
- * \return Indication of success.
- */
- virtual GHOST_TSuccess updateFullScreen(
- const GHOST_DisplaySetting& setting, GHOST_IWindow **window) = 0;
-
- /**
- * Ends full screen mode.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess endFullScreen(void) = 0;
-
- /**
- * Returns current full screen mode status.
- * \return The current status.
- */
- virtual bool getFullScreen(void) = 0;
-
- /**
- * Native pixel size support (MacBook 'retina').
- */
- virtual bool useNativePixel(void) = 0;
-
- /**
- * Focus window after opening, or put them in the background.
- */
- virtual void useWindowFocus(const bool use_focus) = 0;
-
- /***************************************************************************************
- * Event management functionality
- ***************************************************************************************/
-
- /**
- * Retrieves events from the system and stores them in the queue.
- * \param waitForEvent Flag to wait for an event (or return immediately).
- * \return Indication of the presence of events.
- */
- virtual bool processEvents(bool waitForEvent) = 0;
-
- /**
- * Retrieves events from the queue and send them to the event consumers.
- */
- virtual void dispatchEvents() = 0;
-
- /**
- * Adds the given event consumer to our list.
- * \param consumer The event consumer to add.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer) = 0;
-
- /**
- * Removes the given event consumer to our list.
- * \param consumer The event consumer to remove.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer) = 0;
-
- /***************************************************************************************
- * Cursor management functionality
- ***************************************************************************************/
-
- /**
- * Returns the current location of the cursor (location in screen coordinates)
- * \param x The x-coordinate of the cursor.
- * \param y The y-coordinate of the cursor.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0;
-
- /**
- * Updates the location of the cursor (location in screen coordinates).
- * Not all operating systems allow the cursor to be moved (without the input device being moved).
- * \param x The x-coordinate of the cursor.
- * \param y The y-coordinate of the cursor.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) = 0;
-
- /***************************************************************************************
- * Access to mouse button and keyboard states.
- ***************************************************************************************/
-
- /**
- * Returns the state of a modifier key (ouside the message queue).
- * \param mask The modifier key state to retrieve.
- * \param isDown The state of a modifier key (true == pressed).
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const = 0;
-
- /**
- * Returns the state of a mouse button (ouside the message queue).
- * \param mask The button state to retrieve.
- * \param isDown Button state.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const = 0;
-
- /**
- * Set which tablet API to use. Only affects Windows, other platforms have a single API.
- * \param api Enum indicating which API to use.
- */
- virtual void setTabletAPI(GHOST_TTabletAPI api) = 0;
+class GHOST_ISystem {
+ public:
+ /**
+ * Creates the one and only system.
+ * \return An indication of success.
+ */
+ static GHOST_TSuccess createSystem();
+
+ /**
+ * Disposes the one and only system.
+ * \return An indication of success.
+ */
+ static GHOST_TSuccess disposeSystem();
+
+ /**
+ * Returns a pointer to the one and only system (nil if it hasn't been created).
+ * \return A pointer to the system.
+ */
+ static GHOST_ISystem *getSystem();
+
+ protected:
+ /**
+ * Constructor.
+ * Protected default constructor to force use of static createSystem member.
+ */
+ GHOST_ISystem()
+ {
+ }
+
+ /**
+ * Destructor.
+ * Protected default constructor to force use of static dispose member.
+ */
+ virtual ~GHOST_ISystem()
+ {
+ }
+
+ public:
+ /***************************************************************************************
+ * Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * \return The number of milliseconds.
+ */
+ virtual GHOST_TUns64 getMilliSeconds() const = 0;
+
+ /**
+ * Installs a timer.
+ * Note that, on most operating systems, messages need to be processed in order
+ * for the timer callbacks to be invoked.
+ * \param delay The time to wait for the first call to the timerProc (in milliseconds)
+ * \param interval The interval between calls to the timerProc (in milliseconds)
+ * \param timerProc The callback invoked when the interval expires,
+ * \param userData Placeholder for user data.
+ * \return A timer task (0 if timer task installation failed).
+ */
+ virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
+ GHOST_TUns64 interval,
+ GHOST_TimerProcPtr timerProc,
+ GHOST_TUserDataPtr userData = NULL) = 0;
+
+ /**
+ * Removes a timer.
+ * \param timerTask Timer task to be removed.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask) = 0;
+
+ /***************************************************************************************
+ * Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the number of displays on this system.
+ * \return The number of displays.
+ */
+ virtual GHOST_TUns8 getNumDisplays() const = 0;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * \return The dimension of the main display.
+ */
+ virtual void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const = 0;
+
+ /**
+ * Returns the combine dimensions of all monitors.
+ * \return The dimension of the workspace.
+ */
+ virtual void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const = 0;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * \param left The coordinate of the left edge of the window.
+ * \param top The coordinate of the top edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state of the window when opened.
+ * \param type The type of drawing context installed in this window.
+ * \param glSettings: Misc OpenGL settings.
+ * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
+ * \param parentWindow Parent (embedder) window
+ * \return The new window (or 0 if creation failed).
+ */
+ virtual GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive = false,
+ const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
+
+ /**
+ * Dispose a window.
+ * \param window Pointer to the window to be disposed.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess disposeWindow(GHOST_IWindow *window) = 0;
+
+ /**
+ * Create a new offscreen context.
+ * Never explicitly delete the context, use disposeContext() instead.
+ * \return The new context (or 0 if creation failed).
+ */
+ virtual GHOST_IContext *createOffscreenContext() = 0;
+
+ /**
+ * Dispose of a context.
+ * \param context Pointer to the context to be disposed.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess disposeContext(GHOST_IContext *context) = 0;
+
+ /**
+ * Returns whether a window is valid.
+ * \param window Pointer to the window to be checked.
+ * \return Indication of validity.
+ */
+ virtual bool validWindow(GHOST_IWindow *window) = 0;
+
+ /**
+ * Begins full screen mode.
+ * \param setting The new setting of the display.
+ * \param window Window displayed in full screen.
+ * This window is invalid after full screen has been ended.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting,
+ GHOST_IWindow **window,
+ const bool stereoVisual,
+ const bool alphaBackground = 0,
+ const GHOST_TUns16 numOfAASamples = 0) = 0;
+
+ /**
+ * Updates the resolution while in fullscreen mode.
+ * \param setting The new setting of the display.
+ * \param window Window displayed in full screen.
+ *
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting,
+ GHOST_IWindow **window) = 0;
+
+ /**
+ * Ends full screen mode.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess endFullScreen(void) = 0;
+
+ /**
+ * Returns current full screen mode status.
+ * \return The current status.
+ */
+ virtual bool getFullScreen(void) = 0;
+
+ /**
+ * Native pixel size support (MacBook 'retina').
+ */
+ virtual bool useNativePixel(void) = 0;
+
+ /**
+ * Focus window after opening, or put them in the background.
+ */
+ virtual void useWindowFocus(const bool use_focus) = 0;
+
+ /***************************************************************************************
+ * Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Retrieves events from the system and stores them in the queue.
+ * \param waitForEvent Flag to wait for an event (or return immediately).
+ * \return Indication of the presence of events.
+ */
+ virtual bool processEvents(bool waitForEvent) = 0;
+
+ /**
+ * Retrieves events from the queue and send them to the event consumers.
+ */
+ virtual void dispatchEvents() = 0;
+
+ /**
+ * Adds the given event consumer to our list.
+ * \param consumer The event consumer to add.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer) = 0;
+
+ /**
+ * Removes the given event consumer to our list.
+ * \param consumer The event consumer to remove.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer) = 0;
+
+ /***************************************************************************************
+ * Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * \param x The x-coordinate of the cursor.
+ * \param y The y-coordinate of the cursor.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const = 0;
+
+ /**
+ * Updates the location of the cursor (location in screen coordinates).
+ * Not all operating systems allow the cursor to be moved (without the input device being moved).
+ * \param x The x-coordinate of the cursor.
+ * \param y The y-coordinate of the cursor.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) = 0;
+
+ /***************************************************************************************
+ * Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of a modifier key (ouside the message queue).
+ * \param mask The modifier key state to retrieve.
+ * \param isDown The state of a modifier key (true == pressed).
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool &isDown) const = 0;
+
+ /**
+ * Returns the state of a mouse button (ouside the message queue).
+ * \param mask The button state to retrieve.
+ * \param isDown Button state.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool &isDown) const = 0;
+
+ /**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param api Enum indicating which API to use.
+ */
+ virtual void setTabletAPI(GHOST_TTabletAPI api) = 0;
#ifdef WITH_INPUT_NDOF
- /**
- * Sets 3D mouse deadzone
- * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range
- */
- virtual void setNDOFDeadZone(float deadzone) = 0;
+ /**
+ * Sets 3D mouse deadzone
+ * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range
+ */
+ virtual void setNDOFDeadZone(float deadzone) = 0;
#endif
- /**
- * Toggles console
- * \param action
- * - 0: Hides
- * - 1: Shows
- * - 2: Toggles
- * - 3: Hides if it runs not from command line
- * - *: Does nothing
- * \return current status (1 -visible, 0 - hidden)
- */
- virtual int toggleConsole(int action) = 0;
-
- /***************************************************************************************
- * Access to clipboard.
- ***************************************************************************************/
-
- /**
- * Returns the selection buffer
- * \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer
- *
- */
- virtual GHOST_TUns8 *getClipboard(bool selection) const = 0;
-
- /**
- * Put data to the Clipboard
- */
- virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0;
-
- /**
- * Confirms quitting he program when there is just one window left open
- * in the application
- */
- virtual int confirmQuit(GHOST_IWindow *window) const = 0;
-
- /**
- * Informs if the system provides native dialogs (eg. confirm quit)
- */
- virtual bool supportsNativeDialogs(void) = 0;
-
-protected:
- /**
- * Initialize the system.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess init() = 0;
-
- /**
- * Shut the system down.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess exit() = 0;
-
- /** The one and only system */
- static GHOST_ISystem *m_system;
-
+ /**
+ * Toggles console
+ * \param action
+ * - 0: Hides
+ * - 1: Shows
+ * - 2: Toggles
+ * - 3: Hides if it runs not from command line
+ * - *: Does nothing
+ * \return current status (1 -visible, 0 - hidden)
+ */
+ virtual int toggleConsole(int action) = 0;
+
+ /***************************************************************************************
+ * Access to clipboard.
+ ***************************************************************************************/
+
+ /**
+ * Returns the selection buffer
+ * \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer
+ *
+ */
+ virtual GHOST_TUns8 *getClipboard(bool selection) const = 0;
+
+ /**
+ * Put data to the Clipboard
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0;
+
+ /**
+ * Confirms quitting he program when there is just one window left open
+ * in the application
+ */
+ virtual int confirmQuit(GHOST_IWindow *window) const = 0;
+
+ /**
+ * Informs if the system provides native dialogs (eg. confirm quit)
+ */
+ virtual bool supportsNativeDialogs(void) = 0;
+
+ protected:
+ /**
+ * Initialize the system.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess init() = 0;
+
+ /**
+ * Shut the system down.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess exit() = 0;
+
+ /** The one and only system */
+ static GHOST_ISystem *m_system;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystem")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystem")
#endif
};
-#endif // __GHOST_ISYSTEM_H__
+#endif // __GHOST_ISYSTEM_H__
diff --git a/intern/ghost/GHOST_ISystemPaths.h b/intern/ghost/GHOST_ISystemPaths.h
index 1b79613252d..297f6333a77 100644
--- a/intern/ghost/GHOST_ISystemPaths.h
+++ b/intern/ghost/GHOST_ISystemPaths.h
@@ -26,75 +26,75 @@
#include "GHOST_Types.h"
-class GHOST_ISystemPaths
-{
-public:
- /**
- * Creates the one and only system.
- * \return An indication of success.
- */
- static GHOST_TSuccess create();
-
- /**
- * Disposes the one and only system.
- * \return An indication of success.
- */
- static GHOST_TSuccess dispose();
-
- /**
- * Returns a pointer to the one and only system (nil if it hasn't been created).
- * \return A pointer to the system.
- */
- static GHOST_ISystemPaths *get();
-
-protected:
- /**
- * Constructor.
- * Protected default constructor to force use of static createSystem member.
- */
- GHOST_ISystemPaths() {
- }
-
- /**
- * Destructor.
- * Protected default constructor to force use of static dispose member.
- */
- virtual ~GHOST_ISystemPaths() {
- }
-
-public:
- /**
- * Determine the base dir in which shared resources are located. It will first try to use
- * "unpack and run" path, then look for properly installed path, including versioning.
- * \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
- */
- virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0;
-
- /**
- * Determine the base dir in which user configuration is stored, including versioning.
- * If needed, it will create the base directory.
- * \return Unsigned char string pointing to user dir (eg ~/.blender/).
- */
- virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0;
-
- /**
- * Determine the directory of the current binary
- * \return Unsigned char string pointing to the binary dir
- */
- virtual const GHOST_TUns8 *getBinaryDir() const = 0;
-
- /**
- * Add the file to the operating system most recently used files
- */
- virtual void addToSystemRecentFiles(const char *filename) const = 0;
-
-private:
- /** The one and only system paths*/
- static GHOST_ISystemPaths *m_systemPaths;
-
+class GHOST_ISystemPaths {
+ public:
+ /**
+ * Creates the one and only system.
+ * \return An indication of success.
+ */
+ static GHOST_TSuccess create();
+
+ /**
+ * Disposes the one and only system.
+ * \return An indication of success.
+ */
+ static GHOST_TSuccess dispose();
+
+ /**
+ * Returns a pointer to the one and only system (nil if it hasn't been created).
+ * \return A pointer to the system.
+ */
+ static GHOST_ISystemPaths *get();
+
+ protected:
+ /**
+ * Constructor.
+ * Protected default constructor to force use of static createSystem member.
+ */
+ GHOST_ISystemPaths()
+ {
+ }
+
+ /**
+ * Destructor.
+ * Protected default constructor to force use of static dispose member.
+ */
+ virtual ~GHOST_ISystemPaths()
+ {
+ }
+
+ public:
+ /**
+ * Determine the base dir in which shared resources are located. It will first try to use
+ * "unpack and run" path, then look for properly installed path, including versioning.
+ * \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
+ */
+ virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0;
+
+ /**
+ * Determine the base dir in which user configuration is stored, including versioning.
+ * If needed, it will create the base directory.
+ * \return Unsigned char string pointing to user dir (eg ~/.blender/).
+ */
+ virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0;
+
+ /**
+ * Determine the directory of the current binary
+ * \return Unsigned char string pointing to the binary dir
+ */
+ virtual const GHOST_TUns8 *getBinaryDir() const = 0;
+
+ /**
+ * Add the file to the operating system most recently used files
+ */
+ virtual void addToSystemRecentFiles(const char *filename) const = 0;
+
+ private:
+ /** The one and only system paths*/
+ static GHOST_ISystemPaths *m_systemPaths;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystemPaths")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystemPaths")
#endif
};
diff --git a/intern/ghost/GHOST_ITimerTask.h b/intern/ghost/GHOST_ITimerTask.h
index 283bc49a84b..46f4fdbc303 100644
--- a/intern/ghost/GHOST_ITimerTask.h
+++ b/intern/ghost/GHOST_ITimerTask.h
@@ -27,7 +27,6 @@
#include "GHOST_Types.h"
-
/**
* Interface for a timer task.
* Timer tasks are created by the system and can be installed by the system.
@@ -40,44 +39,42 @@
* \see GHOST_ISystem#installTimer
* \see GHOST_TimerProcPtr
*/
-class GHOST_ITimerTask
-{
-public:
- /**
- * Destructor.
- */
- virtual ~GHOST_ITimerTask()
- {
- }
-
- /**
- * Returns the timer callback.
- * \return The timer callback.
- */
- virtual GHOST_TimerProcPtr getTimerProc() const = 0;
+class GHOST_ITimerTask {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_ITimerTask()
+ {
+ }
- /**
- * Changes the timer callback.
- * \param timerProc The timer callback.
- */
- virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0;
+ /**
+ * Returns the timer callback.
+ * \return The timer callback.
+ */
+ virtual GHOST_TimerProcPtr getTimerProc() const = 0;
- /**
- * Returns the timer user data.
- * \return The timer user data.
- */
- virtual GHOST_TUserDataPtr getUserData() const = 0;
+ /**
+ * Changes the timer callback.
+ * \param timerProc The timer callback.
+ */
+ virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0;
- /**
- * Changes the time user data.
- * \param userData: The timer user data.
- */
- virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
+ /**
+ * Returns the timer user data.
+ * \return The timer user data.
+ */
+ virtual GHOST_TUserDataPtr getUserData() const = 0;
+ /**
+ * Changes the time user data.
+ * \param userData: The timer user data.
+ */
+ virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ITimerTask")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ITimerTask")
#endif
};
-#endif // __GHOST_ITIMERTASK_H__
+#endif // __GHOST_ITIMERTASK_H__
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 5236567b398..0b1b83c36a7 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -29,7 +29,6 @@
#include "GHOST_Rect.h"
#include "GHOST_Types.h"
-
/**
* Interface for GHOST windows.
*
@@ -44,316 +43,325 @@
* - The client rectangle coordinate system. The client rectangle of a window
* is the area that is drawable by the application (excluding title bars etc.).
*/
-class GHOST_IWindow
-{
-public:
- /**
- * Destructor.
- */
- virtual ~GHOST_IWindow()
- {
- }
-
- /**
- * Returns indication as to whether the window is valid.
- * \return The validity of the window.
- */
- virtual bool getValid() const = 0;
-
- /**
- * Returns the associated OS object/handle
- * \return The associated OS object/handle
- */
- virtual void *getOSWindow() const = 0;
-
- /**
- * Returns the type of drawing context used in this window.
- * \return The current type of drawing context.
- */
- virtual GHOST_TDrawingContextType getDrawingContextType() = 0;
-
- /**
- * Tries to install a rendering context in this window.
- * \param type The type of rendering context installed.
- * \return Indication as to whether installation has succeeded.
- */
- virtual GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type) = 0;
-
- /**
- * Sets the title displayed in the title bar.
- * \param title The title to display in the title bar.
- */
- virtual void setTitle(const STR_String& title) = 0;
-
- /**
- * Returns the title displayed in the title bar.
- * \param title The title displayed in the title bar.
- */
- virtual void getTitle(STR_String& title) const = 0;
-
- /**
- * Returns the window rectangle dimensions.
- * These are screen coordinates.
- * \param bounds The bounding rectangle of the window.
- */
- virtual void getWindowBounds(GHOST_Rect& bounds) const = 0;
-
- /**
- * Returns the client rectangle dimensions.
- * The left and top members of the rectangle are always zero.
- * \param bounds The bounding rectangle of the client area of the window.
- */
- virtual void getClientBounds(GHOST_Rect& bounds) const = 0;
-
- /**
- * Resizes client rectangle width.
- * \param width The new width of the client area of the window.
- */
- virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
-
- /**
- * Resizes client rectangle height.
- * \param height The new height of the client area of the window.
- */
- virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
-
- /**
- * Resizes client rectangle.
- * \param width The new width of the client area of the window.
- * \param height The new height of the client area of the window.
- */
- virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates
- * \param inX The x-coordinate on the screen.
- * \param inY The y-coordinate on the screen.
- * \param outX The x-coordinate in the client rectangle.
- * \param outY The y-coordinate in the client rectangle.
- */
- virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates
- * \param inX The x-coordinate in the client rectangle.
- * \param inY The y-coordinate in the client rectangle.
- * \param outX The x-coordinate on the screen.
- * \param outY The y-coordinate on the screen.
- */
- virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
-
- /**
- * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
- */
- virtual void setAcceptDragOperation(bool canAccept) = 0;
-
- /**
- * Returns acceptance of the dropped object
- * Usually called by the "object dropped" event handling function
- */
- virtual bool canAcceptDragOperation() const = 0;
-
- /**
- * Returns the state of the window (normal, minimized, maximized).
- * \return The state of the window.
- */
- virtual GHOST_TWindowState getState() const = 0;
-
- /**
- * Sets the state of the window (normal, minimized, maximized).
- * \param state The state of the window.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
-
- /**
- * Sets the window "modified" status, indicating unsaved changes
- * \param isUnsavedChanges Unsaved changes or not
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0;
-
- /**
- * Gets the window "modified" status, indicating unsaved changes
- * \return True if there are unsaved changes
- */
- virtual bool getModifiedState() = 0;
-
- /**
- * Sets the order of the window (bottom, top).
- * \param order The order of the window.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess swapBuffers() = 0;
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess setSwapInterval(int interval) = 0;
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \param intervalOut pointer to location to return swap interval (left untouched if there is an error)
- * \return A boolean success indicator of if swap interval was successfully read.
- */
- virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0;
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \return Number of AA Samples (0 if there is no multisample buffer)
- */
- virtual GHOST_TUns16 getNumOfAASamples() = 0;
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess activateDrawingContext() = 0;
-
- /**
- * Invalidates the contents of this window.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess invalidate() = 0;
-
- /**
- * Returns the window user data.
- * \return The window user data.
- */
- virtual GHOST_TUserDataPtr getUserData() const = 0;
-
- /**
- * Changes the window user data.
- * \param userData The window user data.
- */
- virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
-
- /**
- * Returns the tablet data (pressure etc).
- * \return The tablet data (pressure etc).
- */
- virtual const GHOST_TabletData *GetTabletData() = 0;
-
- /***************************************************************************************
- * Progress bar functionality
- ***************************************************************************************/
-
- /**
- * Sets the progress bar value displayed in the window/application icon
- * \param progress The progress %
- */
- virtual GHOST_TSuccess setProgressBar(float progress) = 0;
-
- /**
- * Hides the progress bar in the icon
- */
- virtual GHOST_TSuccess endProgressBar() = 0;
-
- /***************************************************************************************
- * Cursor management functionality
- ***************************************************************************************/
-
- /**
- * Returns the current cursor shape.
- * \return The current cursor shape.
- */
- virtual GHOST_TStandardCursor getCursorShape() const = 0;
-
- /**
- * Set the shape of the cursor.
- * \param cursorShape: The new cursor shape type id.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) = 0;
-
- /**
- * Set the shape of the cursor to a custom cursor.
- * \param bitmap The bitmap data for the cursor.
- * \param mask The mask data for the cursor.
- * \param hotX The X coordinate of the cursor hotspot.
- * \param hotY The Y coordinate of the cursor hotspot.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX,
- int hotY) = 0;
-
- virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex, int sizey,
- int hotX, int hotY,
- int fg_color, int bg_color) = 0;
-
- /**
- * Returns the visibility state of the cursor.
- * \return The visibility state of the cursor.
- */
- virtual bool getCursorVisibility() const = 0;
-
- /**
- * Shows or hides the cursor.
- * \param visible The new visibility state of the cursor.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setCursorVisibility(bool visible) = 0;
-
- /**
- * Grabs the cursor for a modal operation.
- * \param grab The new grab state of the cursor.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode /*mode*/,
- GHOST_Rect * /*bounds*/,
- GHOST_TInt32 /*mouse_ungrab_xy*/[2]) { return GHOST_kSuccess; }
-
- /** */
- virtual GHOST_TSuccess beginFullScreen() const = 0;
- virtual GHOST_TSuccess endFullScreen() const = 0;
-
- virtual float getNativePixelSize(void) = 0;
-
- /**
- * Returns the recommended DPI for this window.
- * \return The recommended DPI for this window.
- */
- virtual GHOST_TUns16 getDPIHint() = 0;
+class GHOST_IWindow {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_IWindow()
+ {
+ }
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * \return The validity of the window.
+ */
+ virtual bool getValid() const = 0;
+
+ /**
+ * Returns the associated OS object/handle
+ * \return The associated OS object/handle
+ */
+ virtual void *getOSWindow() const = 0;
+
+ /**
+ * Returns the type of drawing context used in this window.
+ * \return The current type of drawing context.
+ */
+ virtual GHOST_TDrawingContextType getDrawingContextType() = 0;
+
+ /**
+ * Tries to install a rendering context in this window.
+ * \param type The type of rendering context installed.
+ * \return Indication as to whether installation has succeeded.
+ */
+ virtual GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type) = 0;
+
+ /**
+ * Sets the title displayed in the title bar.
+ * \param title The title to display in the title bar.
+ */
+ virtual void setTitle(const STR_String &title) = 0;
+
+ /**
+ * Returns the title displayed in the title bar.
+ * \param title The title displayed in the title bar.
+ */
+ virtual void getTitle(STR_String &title) const = 0;
+
+ /**
+ * Returns the window rectangle dimensions.
+ * These are screen coordinates.
+ * \param bounds The bounding rectangle of the window.
+ */
+ virtual void getWindowBounds(GHOST_Rect &bounds) const = 0;
+
+ /**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * \param bounds The bounding rectangle of the client area of the window.
+ */
+ virtual void getClientBounds(GHOST_Rect &bounds) const = 0;
+
+ /**
+ * Resizes client rectangle width.
+ * \param width The new width of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
+
+ /**
+ * Resizes client rectangle height.
+ * \param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
+
+ /**
+ * Resizes client rectangle.
+ * \param width The new width of the client area of the window.
+ * \param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * \param inX The x-coordinate on the screen.
+ * \param inY The y-coordinate on the screen.
+ * \param outX The x-coordinate in the client rectangle.
+ * \param outY The y-coordinate in the client rectangle.
+ */
+ virtual void screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const = 0;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * \param inX The x-coordinate in the client rectangle.
+ * \param inY The y-coordinate in the client rectangle.
+ * \param outX The x-coordinate on the screen.
+ * \param outY The y-coordinate on the screen.
+ */
+ virtual void clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const = 0;
+
+ /**
+ * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
+ */
+ virtual void setAcceptDragOperation(bool canAccept) = 0;
+
+ /**
+ * Returns acceptance of the dropped object
+ * Usually called by the "object dropped" event handling function
+ */
+ virtual bool canAcceptDragOperation() const = 0;
+
+ /**
+ * Returns the state of the window (normal, minimized, maximized).
+ * \return The state of the window.
+ */
+ virtual GHOST_TWindowState getState() const = 0;
+
+ /**
+ * Sets the state of the window (normal, minimized, maximized).
+ * \param state The state of the window.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
+
+ /**
+ * Sets the window "modified" status, indicating unsaved changes
+ * \param isUnsavedChanges Unsaved changes or not
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0;
+
+ /**
+ * Gets the window "modified" status, indicating unsaved changes
+ * \return True if there are unsaved changes
+ */
+ virtual bool getModifiedState() = 0;
+
+ /**
+ * Sets the order of the window (bottom, top).
+ * \param order The order of the window.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess swapBuffers() = 0;
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess setSwapInterval(int interval) = 0;
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \param intervalOut pointer to location to return swap interval (left untouched if there is an error)
+ * \return A boolean success indicator of if swap interval was successfully read.
+ */
+ virtual GHOST_TSuccess getSwapInterval(int &intervalOut) = 0;
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \return Number of AA Samples (0 if there is no multisample buffer)
+ */
+ virtual GHOST_TUns16 getNumOfAASamples() = 0;
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess activateDrawingContext() = 0;
+
+ /**
+ * Invalidates the contents of this window.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess invalidate() = 0;
+
+ /**
+ * Returns the window user data.
+ * \return The window user data.
+ */
+ virtual GHOST_TUserDataPtr getUserData() const = 0;
+
+ /**
+ * Changes the window user data.
+ * \param userData The window user data.
+ */
+ virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
+
+ /**
+ * Returns the tablet data (pressure etc).
+ * \return The tablet data (pressure etc).
+ */
+ virtual const GHOST_TabletData *GetTabletData() = 0;
+
+ /***************************************************************************************
+ * Progress bar functionality
+ ***************************************************************************************/
+
+ /**
+ * Sets the progress bar value displayed in the window/application icon
+ * \param progress The progress %
+ */
+ virtual GHOST_TSuccess setProgressBar(float progress) = 0;
+
+ /**
+ * Hides the progress bar in the icon
+ */
+ virtual GHOST_TSuccess endProgressBar() = 0;
+
+ /***************************************************************************************
+ * Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current cursor shape.
+ * \return The current cursor shape.
+ */
+ virtual GHOST_TStandardCursor getCursorShape() const = 0;
+
+ /**
+ * Set the shape of the cursor.
+ * \param cursorShape: The new cursor shape type id.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) = 0;
+
+ /**
+ * Set the shape of the cursor to a custom cursor.
+ * \param bitmap The bitmap data for the cursor.
+ * \param mask The mask data for the cursor.
+ * \param hotX The X coordinate of the cursor hotspot.
+ * \param hotY The Y coordinate of the cursor hotspot.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY) = 0;
+
+ virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color) = 0;
+
+ /**
+ * Returns the visibility state of the cursor.
+ * \return The visibility state of the cursor.
+ */
+ virtual bool getCursorVisibility() const = 0;
+
+ /**
+ * Shows or hides the cursor.
+ * \param visible The new visibility state of the cursor.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorVisibility(bool visible) = 0;
+
+ /**
+ * Grabs the cursor for a modal operation.
+ * \param grab The new grab state of the cursor.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode /*mode*/,
+ GHOST_Rect * /*bounds*/,
+ GHOST_TInt32 /*mouse_ungrab_xy*/[2])
+ {
+ return GHOST_kSuccess;
+ }
+
+ /** */
+ virtual GHOST_TSuccess beginFullScreen() const = 0;
+ virtual GHOST_TSuccess endFullScreen() const = 0;
+
+ virtual float getNativePixelSize(void) = 0;
+
+ /**
+ * Returns the recommended DPI for this window.
+ * \return The recommended DPI for this window.
+ */
+ virtual GHOST_TUns16 getDPIHint() = 0;
#ifdef WITH_INPUT_IME
- /**
- * Enable IME attached to the given window, i.e. allows user-input
- * events to be dispatched to the IME.
- * \param x Requested x-coordinate of the rectangle
- * \param y Requested y-coordinate of the rectangle
- * \param w Requested width of the rectangle
- * \param h Requested height of the rectangle
- * \param complete Whether or not to complete the ongoing composition
- * true: Start a new composition
- * false: Move the IME windows to the given position without finishing it.
- */
- virtual void beginIME(
- GHOST_TInt32 x, GHOST_TInt32 y,
- GHOST_TInt32 w, GHOST_TInt32 h,
- int completed) = 0;
-
- /**
- * Disable the IME attached to the given window, i.e. prohibits any user-input
- * events from being dispatched to the IME.
- */
- virtual void endIME() = 0;
+ /**
+ * Enable IME attached to the given window, i.e. allows user-input
+ * events to be dispatched to the IME.
+ * \param x Requested x-coordinate of the rectangle
+ * \param y Requested y-coordinate of the rectangle
+ * \param w Requested width of the rectangle
+ * \param h Requested height of the rectangle
+ * \param complete Whether or not to complete the ongoing composition
+ * true: Start a new composition
+ * false: Move the IME windows to the given position without finishing it.
+ */
+ virtual void beginIME(
+ GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) = 0;
+
+ /**
+ * Disable the IME attached to the given window, i.e. prohibits any user-input
+ * events from being dispatched to the IME.
+ */
+ virtual void endIME() = 0;
#endif /* WITH_INPUT_IME */
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow")
#endif
};
-#endif // __GHOST_IWINDOW_H__
+#endif // __GHOST_IWINDOW_H__
diff --git a/intern/ghost/GHOST_Path-api.h b/intern/ghost/GHOST_Path-api.h
index 4cdfbf842fe..53abdf68bb4 100644
--- a/intern/ghost/GHOST_Path-api.h
+++ b/intern/ghost/GHOST_Path-api.h
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
#ifndef __GHOST_PATH_API_H__
#define __GHOST_PATH_API_H__
@@ -58,7 +57,6 @@ extern const GHOST_TUns8 *GHOST_getSystemDir(int version, const char *versionstr
*/
extern const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr);
-
/**
* Determine the dir in which the binary file is found.
* \return Unsigned char string pointing to binary dir (eg ~/usr/local/bin/).
diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h
index 057b7fa37df..cd4eb936066 100644
--- a/intern/ghost/GHOST_Rect.h
+++ b/intern/ghost/GHOST_Rect.h
@@ -27,7 +27,6 @@
#include "GHOST_Types.h"
-
/**
* Implements rectangle functionality.
* The four extreme coordinates are stored as left, top, right and bottom.
@@ -36,214 +35,230 @@
*/
class GHOST_Rect {
-public:
-
- /**
- * Constructs a rectangle with the given values.
- * \param l requested left coordinate of the rectangle
- * \param t requested top coordinate of the rectangle
- * \param r requested right coordinate of the rectangle
- * \param b requested bottom coordinate of the rectangle
- */
- GHOST_Rect(GHOST_TInt32 l = 0, GHOST_TInt32 t = 0, GHOST_TInt32 r = 0, GHOST_TInt32 b = 0)
- : m_l(l), m_t(t), m_r(r), m_b(b)
- {}
-
- /**
- * Copy constructor.
- * \param r rectangle to copy
- */
- GHOST_Rect(const GHOST_Rect& r)
- : m_l(r.m_l), m_t(r.m_t), m_r(r.m_r), m_b(r.m_b)
- {}
-
- /**
- * Destructor.
- */
- virtual ~GHOST_Rect() {}
-
- /**
- * Access to rectangle width.
- * \return width of the rectangle
- */
- virtual inline GHOST_TInt32 getWidth() const;
-
- /**
- * Access to rectangle height.
- * \return height of the rectangle
- */
- virtual inline GHOST_TInt32 getHeight() const;
-
- /**
- * Sets all members of the rectangle.
- * \param l requested left coordinate of the rectangle
- * \param t requested top coordinate of the rectangle
- * \param r requested right coordinate of the rectangle
- * \param b requested bottom coordinate of the rectangle
- */
- virtual inline void set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b);
-
- /**
- * Returns whether this rectangle is empty.
- * Empty rectangles are rectangles that have width==0 and/or height==0.
- * \return boolean value (true==empty rectangle)
- */
- virtual inline bool isEmpty() const;
-
- /**
- * Returns whether this rectangle is valid.
- * Valid rectangles are rectangles that have m_l <= m_r and m_t <= m_b. Thus, empty rectangles are valid.
- * \return boolean value (true==valid rectangle)
- */
- virtual inline bool isValid() const;
-
- /**
- * Grows (or shrinks the rectangle).
- * The method avoids negative insets making the rectangle invalid
- * \param i The amount of offset given to each extreme (negative values shrink the rectangle).
- */
- virtual void inset(GHOST_TInt32 i);
-
- /**
- * Does a union of the rectangle given and this rectangle.
- * The result is stored in this rectangle.
- * \param r The rectangle that is input for the union operation.
- */
- virtual inline void unionRect(const GHOST_Rect& r);
-
- /**
- * Grows the rectangle to included a point.
- * \param x The x-coordinate of the point.
- * \param y The y-coordinate of the point.
- */
- virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y);
-
- /**
- * Grows the rectangle to included a point.
- * \param x The x-coordinate of the point.
- * \param y The y-coordinate of the point.
- */
- virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs);
-
- /**
- * Returns whether the point is inside this rectangle.
- * Point on the boundary is considered inside.
- * \param x x-coordinate of point to test.
- * \param y y-coordinate of point to test.
- * \return boolean value (true if point is inside).
- */
- virtual inline bool isInside(GHOST_TInt32 x, GHOST_TInt32 y) const;
-
- /**
- * Returns whether the rectangle is inside this rectangle.
- * \param r rectangle to test.
- * \return visibility (not, partially or fully visible).
- */
- virtual GHOST_TVisibility getVisibility(GHOST_Rect& r) const;
-
- /**
- * Sets rectangle members.
- * Sets rectangle members such that it is centered at the given location.
- * \param cx requested center x-coordinate of the rectangle
- * \param cy requested center y-coordinate of the rectangle
- */
- virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy);
-
- /**
- * Sets rectangle members.
- * Sets rectangle members such that it is centered at the given location,
- * with the width requested.
- * \param cx requested center x-coordinate of the rectangle
- * \param cy requested center y-coordinate of the rectangle
- * \param w requested width of the rectangle
- * \param h requested height of the rectangle
- */
- virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h);
-
- /**
- * Clips a rectangle.
- * Updates the rectangle given such that it will fit within this one.
- * This can result in an empty rectangle.
- * \param r the rectangle to clip
- * \return whether clipping has occurred
- */
- virtual bool clip(GHOST_Rect& r) const;
-
- /** Left coordinate of the rectangle */
- GHOST_TInt32 m_l;
- /** Top coordinate of the rectangle */
- GHOST_TInt32 m_t;
- /** Right coordinate of the rectangle */
- GHOST_TInt32 m_r;
- /** Bottom coordinate of the rectangle */
- GHOST_TInt32 m_b;
+ public:
+ /**
+ * Constructs a rectangle with the given values.
+ * \param l requested left coordinate of the rectangle
+ * \param t requested top coordinate of the rectangle
+ * \param r requested right coordinate of the rectangle
+ * \param b requested bottom coordinate of the rectangle
+ */
+ GHOST_Rect(GHOST_TInt32 l = 0, GHOST_TInt32 t = 0, GHOST_TInt32 r = 0, GHOST_TInt32 b = 0)
+ : m_l(l), m_t(t), m_r(r), m_b(b)
+ {
+ }
+
+ /**
+ * Copy constructor.
+ * \param r rectangle to copy
+ */
+ GHOST_Rect(const GHOST_Rect &r) : m_l(r.m_l), m_t(r.m_t), m_r(r.m_r), m_b(r.m_b)
+ {
+ }
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_Rect()
+ {
+ }
+
+ /**
+ * Access to rectangle width.
+ * \return width of the rectangle
+ */
+ virtual inline GHOST_TInt32 getWidth() const;
+
+ /**
+ * Access to rectangle height.
+ * \return height of the rectangle
+ */
+ virtual inline GHOST_TInt32 getHeight() const;
+
+ /**
+ * Sets all members of the rectangle.
+ * \param l requested left coordinate of the rectangle
+ * \param t requested top coordinate of the rectangle
+ * \param r requested right coordinate of the rectangle
+ * \param b requested bottom coordinate of the rectangle
+ */
+ virtual inline void set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b);
+
+ /**
+ * Returns whether this rectangle is empty.
+ * Empty rectangles are rectangles that have width==0 and/or height==0.
+ * \return boolean value (true==empty rectangle)
+ */
+ virtual inline bool isEmpty() const;
+
+ /**
+ * Returns whether this rectangle is valid.
+ * Valid rectangles are rectangles that have m_l <= m_r and m_t <= m_b. Thus, empty rectangles are valid.
+ * \return boolean value (true==valid rectangle)
+ */
+ virtual inline bool isValid() const;
+
+ /**
+ * Grows (or shrinks the rectangle).
+ * The method avoids negative insets making the rectangle invalid
+ * \param i The amount of offset given to each extreme (negative values shrink the rectangle).
+ */
+ virtual void inset(GHOST_TInt32 i);
+
+ /**
+ * Does a union of the rectangle given and this rectangle.
+ * The result is stored in this rectangle.
+ * \param r The rectangle that is input for the union operation.
+ */
+ virtual inline void unionRect(const GHOST_Rect &r);
+
+ /**
+ * Grows the rectangle to included a point.
+ * \param x The x-coordinate of the point.
+ * \param y The y-coordinate of the point.
+ */
+ virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y);
+
+ /**
+ * Grows the rectangle to included a point.
+ * \param x The x-coordinate of the point.
+ * \param y The y-coordinate of the point.
+ */
+ virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs);
+
+ /**
+ * Returns whether the point is inside this rectangle.
+ * Point on the boundary is considered inside.
+ * \param x x-coordinate of point to test.
+ * \param y y-coordinate of point to test.
+ * \return boolean value (true if point is inside).
+ */
+ virtual inline bool isInside(GHOST_TInt32 x, GHOST_TInt32 y) const;
+
+ /**
+ * Returns whether the rectangle is inside this rectangle.
+ * \param r rectangle to test.
+ * \return visibility (not, partially or fully visible).
+ */
+ virtual GHOST_TVisibility getVisibility(GHOST_Rect &r) const;
+
+ /**
+ * Sets rectangle members.
+ * Sets rectangle members such that it is centered at the given location.
+ * \param cx requested center x-coordinate of the rectangle
+ * \param cy requested center y-coordinate of the rectangle
+ */
+ virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy);
+
+ /**
+ * Sets rectangle members.
+ * Sets rectangle members such that it is centered at the given location,
+ * with the width requested.
+ * \param cx requested center x-coordinate of the rectangle
+ * \param cy requested center y-coordinate of the rectangle
+ * \param w requested width of the rectangle
+ * \param h requested height of the rectangle
+ */
+ virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h);
+
+ /**
+ * Clips a rectangle.
+ * Updates the rectangle given such that it will fit within this one.
+ * This can result in an empty rectangle.
+ * \param r the rectangle to clip
+ * \return whether clipping has occurred
+ */
+ virtual bool clip(GHOST_Rect &r) const;
+
+ /** Left coordinate of the rectangle */
+ GHOST_TInt32 m_l;
+ /** Top coordinate of the rectangle */
+ GHOST_TInt32 m_t;
+ /** Right coordinate of the rectangle */
+ GHOST_TInt32 m_r;
+ /** Bottom coordinate of the rectangle */
+ GHOST_TInt32 m_b;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Rect")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Rect")
#endif
};
-
inline GHOST_TInt32 GHOST_Rect::getWidth() const
{
- return m_r - m_l;
+ return m_r - m_l;
}
inline GHOST_TInt32 GHOST_Rect::getHeight() const
{
- return m_b - m_t;
+ return m_b - m_t;
}
inline void GHOST_Rect::set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b)
{
- m_l = l; m_t = t; m_r = r; m_b = b;
+ m_l = l;
+ m_t = t;
+ m_r = r;
+ m_b = b;
}
inline bool GHOST_Rect::isEmpty() const
{
- return (getWidth() == 0) || (getHeight() == 0);
+ return (getWidth() == 0) || (getHeight() == 0);
}
inline bool GHOST_Rect::isValid() const
{
- return (m_l <= m_r) && (m_t <= m_b);
+ return (m_l <= m_r) && (m_t <= m_b);
}
-inline void GHOST_Rect::unionRect(const GHOST_Rect& r)
+inline void GHOST_Rect::unionRect(const GHOST_Rect &r)
{
- if (r.m_l < m_l) m_l = r.m_l;
- if (r.m_r > m_r) m_r = r.m_r;
- if (r.m_t < m_t) m_t = r.m_t;
- if (r.m_b > m_b) m_b = r.m_b;
+ if (r.m_l < m_l)
+ m_l = r.m_l;
+ if (r.m_r > m_r)
+ m_r = r.m_r;
+ if (r.m_t < m_t)
+ m_t = r.m_t;
+ if (r.m_b > m_b)
+ m_b = r.m_b;
}
inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y)
{
- if (x < m_l) m_l = x;
- if (x > m_r) m_r = x;
- if (y < m_t) m_t = y;
- if (y > m_b) m_b = y;
+ if (x < m_l)
+ m_l = x;
+ if (x > m_r)
+ m_r = x;
+ if (y < m_t)
+ m_t = y;
+ if (y > m_b)
+ m_b = y;
}
#include <stdio.h>
inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs)
{
- GHOST_TInt32 w = getWidth();
- GHOST_TInt32 h = getHeight();
-
- /* highly unlikely but avoid eternal loop */
- if (w - ofs * 2 <= 0 || h - ofs * 2 <= 0) {
- return;
- }
-
- while (x - ofs < m_l) x += w - (ofs * 2);
- while (y - ofs < m_t) y += h - (ofs * 2);
- while (x + ofs > m_r) x -= w - (ofs * 2);
- while (y + ofs > m_b) y -= h - (ofs * 2);
+ GHOST_TInt32 w = getWidth();
+ GHOST_TInt32 h = getHeight();
+
+ /* highly unlikely but avoid eternal loop */
+ if (w - ofs * 2 <= 0 || h - ofs * 2 <= 0) {
+ return;
+ }
+
+ while (x - ofs < m_l)
+ x += w - (ofs * 2);
+ while (y - ofs < m_t)
+ y += h - (ofs * 2);
+ while (x + ofs > m_r)
+ x -= w - (ofs * 2);
+ while (y + ofs > m_b)
+ y -= h - (ofs * 2);
}
inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const
{
- return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b);
+ return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b);
}
-#endif // __GHOST_RECT_H__
+#endif // __GHOST_RECT_H__
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 8f6fd45d753..36678bcc913 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -21,18 +21,24 @@
* \ingroup GHOST
*/
-
#ifndef __GHOST_TYPES_H__
#define __GHOST_TYPES_H__
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
#if defined(WITH_CXX_GUARDEDALLOC) && defined(__cplusplus)
-# define GHOST_DECLARE_HANDLE(name) typedef struct name##__ { int unused; MEM_CXX_CLASS_ALLOC_FUNCS(#name) } *name
+# define GHOST_DECLARE_HANDLE(name) \
+ typedef struct name##__ { \
+ int unused; \
+ MEM_CXX_CLASS_ALLOC_FUNCS(#name) \
+ } * name
#else
-# define GHOST_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+# define GHOST_DECLARE_HANDLE(name) \
+ typedef struct name##__ { \
+ int unused; \
+ } * name
#endif
typedef char GHOST_TInt8;
@@ -43,17 +49,16 @@ typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
typedef struct {
- GHOST_TUns16 numOfAASamples;
- int flags;
+ GHOST_TUns16 numOfAASamples;
+ int flags;
} GHOST_GLSettings;
typedef enum {
- GHOST_glStereoVisual = (1 << 0),
- GHOST_glDebugContext = (1 << 1),
- GHOST_glAlphaBackground = (1 << 2),
+ GHOST_glStereoVisual = (1 << 0),
+ GHOST_glDebugContext = (1 << 1),
+ GHOST_glAlphaBackground = (1 << 2),
} GHOST_GLFlags;
-
#ifdef _MSC_VER
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;
@@ -64,10 +69,7 @@ typedef unsigned long long GHOST_TUns64;
typedef void *GHOST_TUserDataPtr;
-typedef enum {
- GHOST_kFailure = 0,
- GHOST_kSuccess
-} GHOST_TSuccess;
+typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess;
/* Xtilt and Ytilt represent how much the pen is tilted away from
* vertically upright in either the X or Y direction, with X and Y the
@@ -77,469 +79,448 @@ typedef enum {
* --Matt
*/
typedef enum {
- GHOST_kTabletModeNone = 0,
- GHOST_kTabletModeStylus,
- GHOST_kTabletModeEraser
+ GHOST_kTabletModeNone = 0,
+ GHOST_kTabletModeStylus,
+ GHOST_kTabletModeEraser
} GHOST_TTabletMode;
typedef enum {
- GHOST_kTabletAutomatic = 0,
- GHOST_kTabletNative,
- GHOST_kTabletWintab,
+ GHOST_kTabletAutomatic = 0,
+ GHOST_kTabletNative,
+ GHOST_kTabletWintab,
} GHOST_TTabletAPI;
typedef struct GHOST_TabletData {
- GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */
- float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
- float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */
- float Ytilt; /* as above */
+ GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */
+ float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
+ float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */
+ float Ytilt; /* as above */
} GHOST_TabletData;
-
typedef enum {
- GHOST_kNotVisible = 0,
- GHOST_kPartiallyVisible,
- GHOST_kFullyVisible
+ GHOST_kNotVisible = 0,
+ GHOST_kPartiallyVisible,
+ GHOST_kFullyVisible
} GHOST_TVisibility;
+typedef enum { GHOST_kFireTimeNever = 0xFFFFFFFF } GHOST_TFireTimeConstant;
typedef enum {
- GHOST_kFireTimeNever = 0xFFFFFFFF
-} GHOST_TFireTimeConstant;
-
-typedef enum {
- GHOST_kModifierKeyLeftShift = 0,
- GHOST_kModifierKeyRightShift,
- GHOST_kModifierKeyLeftAlt,
- GHOST_kModifierKeyRightAlt,
- GHOST_kModifierKeyLeftControl,
- GHOST_kModifierKeyRightControl,
- GHOST_kModifierKeyOS,
- GHOST_kModifierKeyNumMasks
+ GHOST_kModifierKeyLeftShift = 0,
+ GHOST_kModifierKeyRightShift,
+ GHOST_kModifierKeyLeftAlt,
+ GHOST_kModifierKeyRightAlt,
+ GHOST_kModifierKeyLeftControl,
+ GHOST_kModifierKeyRightControl,
+ GHOST_kModifierKeyOS,
+ GHOST_kModifierKeyNumMasks
} GHOST_TModifierKeyMask;
-
typedef enum {
- GHOST_kWindowStateNormal = 0,
- GHOST_kWindowStateMaximized,
- GHOST_kWindowStateMinimized,
- GHOST_kWindowStateFullScreen,
- GHOST_kWindowStateEmbedded,
- // GHOST_kWindowStateModified,
- // GHOST_kWindowStateUnModified,
+ GHOST_kWindowStateNormal = 0,
+ GHOST_kWindowStateMaximized,
+ GHOST_kWindowStateMinimized,
+ GHOST_kWindowStateFullScreen,
+ GHOST_kWindowStateEmbedded,
+ // GHOST_kWindowStateModified,
+ // GHOST_kWindowStateUnModified,
} GHOST_TWindowState;
-
/** Constants for the answer to the blender exit request */
-typedef enum {
- GHOST_kExitCancel = 0,
- GHOST_kExitNow
-} GHOST_TExitRequestResponse;
-
-typedef enum {
- GHOST_kWindowOrderTop = 0,
- GHOST_kWindowOrderBottom
-} GHOST_TWindowOrder;
+typedef enum { GHOST_kExitCancel = 0, GHOST_kExitNow } GHOST_TExitRequestResponse;
+typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom } GHOST_TWindowOrder;
typedef enum {
- GHOST_kDrawingContextTypeNone = 0,
- GHOST_kDrawingContextTypeOpenGL
+ GHOST_kDrawingContextTypeNone = 0,
+ GHOST_kDrawingContextTypeOpenGL
} GHOST_TDrawingContextType;
-
typedef enum {
- GHOST_kButtonMaskLeft = 0,
- GHOST_kButtonMaskMiddle,
- GHOST_kButtonMaskRight,
- GHOST_kButtonMaskButton4,
- GHOST_kButtonMaskButton5,
- /* Trackballs and programmable buttons */
- GHOST_kButtonMaskButton6,
- GHOST_kButtonMaskButton7,
- GHOST_kButtonNumMasks
+ GHOST_kButtonMaskLeft = 0,
+ GHOST_kButtonMaskMiddle,
+ GHOST_kButtonMaskRight,
+ GHOST_kButtonMaskButton4,
+ GHOST_kButtonMaskButton5,
+ /* Trackballs and programmable buttons */
+ GHOST_kButtonMaskButton6,
+ GHOST_kButtonMaskButton7,
+ GHOST_kButtonNumMasks
} GHOST_TButtonMask;
-
typedef enum {
- GHOST_kEventUnknown = 0,
+ GHOST_kEventUnknown = 0,
- GHOST_kEventCursorMove, /// Mouse move event
- GHOST_kEventButtonDown, /// Mouse button event
- GHOST_kEventButtonUp, /// Mouse button event
- GHOST_kEventWheel, /// Mouse wheel event
- GHOST_kEventTrackpad, /// Trackpad event
+ GHOST_kEventCursorMove, /// Mouse move event
+ GHOST_kEventButtonDown, /// Mouse button event
+ GHOST_kEventButtonUp, /// Mouse button event
+ GHOST_kEventWheel, /// Mouse wheel event
+ GHOST_kEventTrackpad, /// Trackpad event
#ifdef WITH_INPUT_NDOF
- GHOST_kEventNDOFMotion, /// N degree of freedom device motion event
- GHOST_kEventNDOFButton, /// N degree of freedom device button event
+ GHOST_kEventNDOFMotion, /// N degree of freedom device motion event
+ GHOST_kEventNDOFButton, /// N degree of freedom device button event
#endif
- GHOST_kEventKeyDown,
- GHOST_kEventKeyUp,
-// GHOST_kEventKeyAuto,
+ GHOST_kEventKeyDown,
+ GHOST_kEventKeyUp,
+ // GHOST_kEventKeyAuto,
- GHOST_kEventQuit,
+ GHOST_kEventQuit,
- GHOST_kEventWindowClose,
- GHOST_kEventWindowActivate,
- GHOST_kEventWindowDeactivate,
- GHOST_kEventWindowUpdate,
- GHOST_kEventWindowSize,
- GHOST_kEventWindowMove,
- GHOST_kEventWindowDPIHintChanged,
+ GHOST_kEventWindowClose,
+ GHOST_kEventWindowActivate,
+ GHOST_kEventWindowDeactivate,
+ GHOST_kEventWindowUpdate,
+ GHOST_kEventWindowSize,
+ GHOST_kEventWindowMove,
+ GHOST_kEventWindowDPIHintChanged,
- GHOST_kEventDraggingEntered,
- GHOST_kEventDraggingUpdated,
- GHOST_kEventDraggingExited,
- GHOST_kEventDraggingDropDone,
+ GHOST_kEventDraggingEntered,
+ GHOST_kEventDraggingUpdated,
+ GHOST_kEventDraggingExited,
+ GHOST_kEventDraggingDropDone,
- GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup
- GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display
+ GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup
+ GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display
- GHOST_kEventTimer,
+ GHOST_kEventTimer,
- GHOST_kEventImeCompositionStart,
- GHOST_kEventImeComposition,
- GHOST_kEventImeCompositionEnd,
+ GHOST_kEventImeCompositionStart,
+ GHOST_kEventImeComposition,
+ GHOST_kEventImeCompositionEnd,
- GHOST_kNumEventTypes
+ GHOST_kNumEventTypes
} GHOST_TEventType;
-
typedef enum {
- GHOST_kStandardCursorFirstCursor = 0,
- GHOST_kStandardCursorDefault = 0,
- GHOST_kStandardCursorRightArrow,
- GHOST_kStandardCursorLeftArrow,
- GHOST_kStandardCursorInfo,
- GHOST_kStandardCursorDestroy,
- GHOST_kStandardCursorHelp,
- GHOST_kStandardCursorCycle,
- GHOST_kStandardCursorSpray,
- GHOST_kStandardCursorWait,
- GHOST_kStandardCursorText,
- GHOST_kStandardCursorCrosshair,
- GHOST_kStandardCursorUpDown,
- GHOST_kStandardCursorLeftRight,
- GHOST_kStandardCursorTopSide,
- GHOST_kStandardCursorBottomSide,
- GHOST_kStandardCursorLeftSide,
- GHOST_kStandardCursorRightSide,
- GHOST_kStandardCursorTopLeftCorner,
- GHOST_kStandardCursorTopRightCorner,
- GHOST_kStandardCursorBottomRightCorner,
- GHOST_kStandardCursorBottomLeftCorner,
- GHOST_kStandardCursorCopy,
- GHOST_kStandardCursorCustom,
- GHOST_kStandardCursorPencil,
-
- GHOST_kStandardCursorNumCursors
+ GHOST_kStandardCursorFirstCursor = 0,
+ GHOST_kStandardCursorDefault = 0,
+ GHOST_kStandardCursorRightArrow,
+ GHOST_kStandardCursorLeftArrow,
+ GHOST_kStandardCursorInfo,
+ GHOST_kStandardCursorDestroy,
+ GHOST_kStandardCursorHelp,
+ GHOST_kStandardCursorCycle,
+ GHOST_kStandardCursorSpray,
+ GHOST_kStandardCursorWait,
+ GHOST_kStandardCursorText,
+ GHOST_kStandardCursorCrosshair,
+ GHOST_kStandardCursorUpDown,
+ GHOST_kStandardCursorLeftRight,
+ GHOST_kStandardCursorTopSide,
+ GHOST_kStandardCursorBottomSide,
+ GHOST_kStandardCursorLeftSide,
+ GHOST_kStandardCursorRightSide,
+ GHOST_kStandardCursorTopLeftCorner,
+ GHOST_kStandardCursorTopRightCorner,
+ GHOST_kStandardCursorBottomRightCorner,
+ GHOST_kStandardCursorBottomLeftCorner,
+ GHOST_kStandardCursorCopy,
+ GHOST_kStandardCursorCustom,
+ GHOST_kStandardCursorPencil,
+
+ GHOST_kStandardCursorNumCursors
} GHOST_TStandardCursor;
-
typedef enum {
- GHOST_kKeyUnknown = -1,
- GHOST_kKeyBackSpace,
- GHOST_kKeyTab,
- GHOST_kKeyLinefeed,
- GHOST_kKeyClear,
- GHOST_kKeyEnter = 0x0D,
-
- GHOST_kKeyEsc = 0x1B,
- GHOST_kKeySpace = ' ',
- GHOST_kKeyQuote = 0x27,
- GHOST_kKeyComma = ',',
- GHOST_kKeyMinus = '-',
- GHOST_kKeyPlus = '+',
- GHOST_kKeyPeriod = '.',
- GHOST_kKeySlash = '/',
-
- // Number keys
- GHOST_kKey0 = '0',
- GHOST_kKey1,
- GHOST_kKey2,
- GHOST_kKey3,
- GHOST_kKey4,
- GHOST_kKey5,
- GHOST_kKey6,
- GHOST_kKey7,
- GHOST_kKey8,
- GHOST_kKey9,
-
- GHOST_kKeySemicolon = ';',
- GHOST_kKeyEqual = '=',
-
- // Character keys
- GHOST_kKeyA = 'A',
- GHOST_kKeyB,
- GHOST_kKeyC,
- GHOST_kKeyD,
- GHOST_kKeyE,
- GHOST_kKeyF,
- GHOST_kKeyG,
- GHOST_kKeyH,
- GHOST_kKeyI,
- GHOST_kKeyJ,
- GHOST_kKeyK,
- GHOST_kKeyL,
- GHOST_kKeyM,
- GHOST_kKeyN,
- GHOST_kKeyO,
- GHOST_kKeyP,
- GHOST_kKeyQ,
- GHOST_kKeyR,
- GHOST_kKeyS,
- GHOST_kKeyT,
- GHOST_kKeyU,
- GHOST_kKeyV,
- GHOST_kKeyW,
- GHOST_kKeyX,
- GHOST_kKeyY,
- GHOST_kKeyZ,
-
- GHOST_kKeyLeftBracket = '[',
- GHOST_kKeyRightBracket = ']',
- GHOST_kKeyBackslash = 0x5C,
- GHOST_kKeyAccentGrave = '`',
-
-
- GHOST_kKeyLeftShift = 0x100,
- GHOST_kKeyRightShift,
- GHOST_kKeyLeftControl,
- GHOST_kKeyRightControl,
- GHOST_kKeyLeftAlt,
- GHOST_kKeyRightAlt,
- GHOST_kKeyOS, // Command key on Apple, Windows key(s) on Windows
- GHOST_kKeyGrLess, // German PC only!
-
- GHOST_kKeyCapsLock,
- GHOST_kKeyNumLock,
- GHOST_kKeyScrollLock,
-
- GHOST_kKeyLeftArrow,
- GHOST_kKeyRightArrow,
- GHOST_kKeyUpArrow,
- GHOST_kKeyDownArrow,
-
- GHOST_kKeyPrintScreen,
- GHOST_kKeyPause,
-
- GHOST_kKeyInsert,
- GHOST_kKeyDelete,
- GHOST_kKeyHome,
- GHOST_kKeyEnd,
- GHOST_kKeyUpPage,
- GHOST_kKeyDownPage,
-
- // Numpad keys
- GHOST_kKeyNumpad0,
- GHOST_kKeyNumpad1,
- GHOST_kKeyNumpad2,
- GHOST_kKeyNumpad3,
- GHOST_kKeyNumpad4,
- GHOST_kKeyNumpad5,
- GHOST_kKeyNumpad6,
- GHOST_kKeyNumpad7,
- GHOST_kKeyNumpad8,
- GHOST_kKeyNumpad9,
- GHOST_kKeyNumpadPeriod,
- GHOST_kKeyNumpadEnter,
- GHOST_kKeyNumpadPlus,
- GHOST_kKeyNumpadMinus,
- GHOST_kKeyNumpadAsterisk,
- GHOST_kKeyNumpadSlash,
-
- // Function keys
- GHOST_kKeyF1,
- GHOST_kKeyF2,
- GHOST_kKeyF3,
- GHOST_kKeyF4,
- GHOST_kKeyF5,
- GHOST_kKeyF6,
- GHOST_kKeyF7,
- GHOST_kKeyF8,
- GHOST_kKeyF9,
- GHOST_kKeyF10,
- GHOST_kKeyF11,
- GHOST_kKeyF12,
- GHOST_kKeyF13,
- GHOST_kKeyF14,
- GHOST_kKeyF15,
- GHOST_kKeyF16,
- GHOST_kKeyF17,
- GHOST_kKeyF18,
- GHOST_kKeyF19,
- GHOST_kKeyF20,
- GHOST_kKeyF21,
- GHOST_kKeyF22,
- GHOST_kKeyF23,
- GHOST_kKeyF24,
-
- // Multimedia keypad buttons
- GHOST_kKeyMediaPlay,
- GHOST_kKeyMediaStop,
- GHOST_kKeyMediaFirst,
- GHOST_kKeyMediaLast
+ GHOST_kKeyUnknown = -1,
+ GHOST_kKeyBackSpace,
+ GHOST_kKeyTab,
+ GHOST_kKeyLinefeed,
+ GHOST_kKeyClear,
+ GHOST_kKeyEnter = 0x0D,
+
+ GHOST_kKeyEsc = 0x1B,
+ GHOST_kKeySpace = ' ',
+ GHOST_kKeyQuote = 0x27,
+ GHOST_kKeyComma = ',',
+ GHOST_kKeyMinus = '-',
+ GHOST_kKeyPlus = '+',
+ GHOST_kKeyPeriod = '.',
+ GHOST_kKeySlash = '/',
+
+ // Number keys
+ GHOST_kKey0 = '0',
+ GHOST_kKey1,
+ GHOST_kKey2,
+ GHOST_kKey3,
+ GHOST_kKey4,
+ GHOST_kKey5,
+ GHOST_kKey6,
+ GHOST_kKey7,
+ GHOST_kKey8,
+ GHOST_kKey9,
+
+ GHOST_kKeySemicolon = ';',
+ GHOST_kKeyEqual = '=',
+
+ // Character keys
+ GHOST_kKeyA = 'A',
+ GHOST_kKeyB,
+ GHOST_kKeyC,
+ GHOST_kKeyD,
+ GHOST_kKeyE,
+ GHOST_kKeyF,
+ GHOST_kKeyG,
+ GHOST_kKeyH,
+ GHOST_kKeyI,
+ GHOST_kKeyJ,
+ GHOST_kKeyK,
+ GHOST_kKeyL,
+ GHOST_kKeyM,
+ GHOST_kKeyN,
+ GHOST_kKeyO,
+ GHOST_kKeyP,
+ GHOST_kKeyQ,
+ GHOST_kKeyR,
+ GHOST_kKeyS,
+ GHOST_kKeyT,
+ GHOST_kKeyU,
+ GHOST_kKeyV,
+ GHOST_kKeyW,
+ GHOST_kKeyX,
+ GHOST_kKeyY,
+ GHOST_kKeyZ,
+
+ GHOST_kKeyLeftBracket = '[',
+ GHOST_kKeyRightBracket = ']',
+ GHOST_kKeyBackslash = 0x5C,
+ GHOST_kKeyAccentGrave = '`',
+
+ GHOST_kKeyLeftShift = 0x100,
+ GHOST_kKeyRightShift,
+ GHOST_kKeyLeftControl,
+ GHOST_kKeyRightControl,
+ GHOST_kKeyLeftAlt,
+ GHOST_kKeyRightAlt,
+ GHOST_kKeyOS, // Command key on Apple, Windows key(s) on Windows
+ GHOST_kKeyGrLess, // German PC only!
+
+ GHOST_kKeyCapsLock,
+ GHOST_kKeyNumLock,
+ GHOST_kKeyScrollLock,
+
+ GHOST_kKeyLeftArrow,
+ GHOST_kKeyRightArrow,
+ GHOST_kKeyUpArrow,
+ GHOST_kKeyDownArrow,
+
+ GHOST_kKeyPrintScreen,
+ GHOST_kKeyPause,
+
+ GHOST_kKeyInsert,
+ GHOST_kKeyDelete,
+ GHOST_kKeyHome,
+ GHOST_kKeyEnd,
+ GHOST_kKeyUpPage,
+ GHOST_kKeyDownPage,
+
+ // Numpad keys
+ GHOST_kKeyNumpad0,
+ GHOST_kKeyNumpad1,
+ GHOST_kKeyNumpad2,
+ GHOST_kKeyNumpad3,
+ GHOST_kKeyNumpad4,
+ GHOST_kKeyNumpad5,
+ GHOST_kKeyNumpad6,
+ GHOST_kKeyNumpad7,
+ GHOST_kKeyNumpad8,
+ GHOST_kKeyNumpad9,
+ GHOST_kKeyNumpadPeriod,
+ GHOST_kKeyNumpadEnter,
+ GHOST_kKeyNumpadPlus,
+ GHOST_kKeyNumpadMinus,
+ GHOST_kKeyNumpadAsterisk,
+ GHOST_kKeyNumpadSlash,
+
+ // Function keys
+ GHOST_kKeyF1,
+ GHOST_kKeyF2,
+ GHOST_kKeyF3,
+ GHOST_kKeyF4,
+ GHOST_kKeyF5,
+ GHOST_kKeyF6,
+ GHOST_kKeyF7,
+ GHOST_kKeyF8,
+ GHOST_kKeyF9,
+ GHOST_kKeyF10,
+ GHOST_kKeyF11,
+ GHOST_kKeyF12,
+ GHOST_kKeyF13,
+ GHOST_kKeyF14,
+ GHOST_kKeyF15,
+ GHOST_kKeyF16,
+ GHOST_kKeyF17,
+ GHOST_kKeyF18,
+ GHOST_kKeyF19,
+ GHOST_kKeyF20,
+ GHOST_kKeyF21,
+ GHOST_kKeyF22,
+ GHOST_kKeyF23,
+ GHOST_kKeyF24,
+
+ // Multimedia keypad buttons
+ GHOST_kKeyMediaPlay,
+ GHOST_kKeyMediaStop,
+ GHOST_kKeyMediaFirst,
+ GHOST_kKeyMediaLast
} GHOST_TKey;
typedef enum {
- GHOST_kGrabDisable = 0, /* grab not set */
- GHOST_kGrabNormal, /* no cursor adjustments */
- GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */
- GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */
+ GHOST_kGrabDisable = 0, /* grab not set */
+ GHOST_kGrabNormal, /* no cursor adjustments */
+ GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */
+ GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */
} GHOST_TGrabCursorMode;
typedef void *GHOST_TEventDataPtr;
typedef struct {
- /** The x-coordinate of the cursor position. */
- GHOST_TInt32 x;
- /** The y-coordinate of the cursor position. */
- GHOST_TInt32 y;
+ /** The x-coordinate of the cursor position. */
+ GHOST_TInt32 x;
+ /** The y-coordinate of the cursor position. */
+ GHOST_TInt32 y;
} GHOST_TEventCursorData;
typedef struct {
- /** The mask of the mouse button. */
- GHOST_TButtonMask button;
+ /** The mask of the mouse button. */
+ GHOST_TButtonMask button;
} GHOST_TEventButtonData;
typedef struct {
- /** Displacement of a mouse wheel. */
- GHOST_TInt32 z;
+ /** Displacement of a mouse wheel. */
+ GHOST_TInt32 z;
} GHOST_TEventWheelData;
typedef enum {
- GHOST_kTrackpadEventUnknown = 0,
- GHOST_kTrackpadEventScroll,
- GHOST_kTrackpadEventRotate,
- GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */
- GHOST_kTrackpadEventMagnify
+ GHOST_kTrackpadEventUnknown = 0,
+ GHOST_kTrackpadEventScroll,
+ GHOST_kTrackpadEventRotate,
+ GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */
+ GHOST_kTrackpadEventMagnify
} GHOST_TTrackpadEventSubTypes;
-
typedef struct {
- /** The event subtype */
- GHOST_TTrackpadEventSubTypes subtype;
- /** The x-location of the trackpad event */
- GHOST_TInt32 x;
- /** The y-location of the trackpad event */
- GHOST_TInt32 y;
- /** The x-delta or value of the trackpad event */
- GHOST_TInt32 deltaX;
- /** The y-delta (currently only for scroll subtype) of the trackpad event */
- GHOST_TInt32 deltaY;
+ /** The event subtype */
+ GHOST_TTrackpadEventSubTypes subtype;
+ /** The x-location of the trackpad event */
+ GHOST_TInt32 x;
+ /** The y-location of the trackpad event */
+ GHOST_TInt32 y;
+ /** The x-delta or value of the trackpad event */
+ GHOST_TInt32 deltaX;
+ /** The y-delta (currently only for scroll subtype) of the trackpad event */
+ GHOST_TInt32 deltaY;
} GHOST_TEventTrackpadData;
-
typedef enum {
- GHOST_kDragnDropTypeUnknown = 0,
- GHOST_kDragnDropTypeFilenames, /*Array of strings representing file names (full path) */
- GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string */
- GHOST_kDragnDropTypeBitmap /*Bitmap image data */
+ GHOST_kDragnDropTypeUnknown = 0,
+ GHOST_kDragnDropTypeFilenames, /*Array of strings representing file names (full path) */
+ GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string */
+ GHOST_kDragnDropTypeBitmap /*Bitmap image data */
} GHOST_TDragnDropTypes;
typedef struct {
- /** The x-coordinate of the cursor position. */
- GHOST_TInt32 x;
- /** The y-coordinate of the cursor position. */
- GHOST_TInt32 y;
- /** The dropped item type */
- GHOST_TDragnDropTypes dataType;
- /** The "dropped content" */
- GHOST_TEventDataPtr data;
+ /** The x-coordinate of the cursor position. */
+ GHOST_TInt32 x;
+ /** The y-coordinate of the cursor position. */
+ GHOST_TInt32 y;
+ /** The dropped item type */
+ GHOST_TDragnDropTypes dataType;
+ /** The "dropped content" */
+ GHOST_TEventDataPtr data;
} GHOST_TEventDragnDropData;
/** similar to wmImeData */
typedef struct {
- /** size_t */
- GHOST_TUserDataPtr result_len, composite_len;
- /** char * utf8 encoding */
- GHOST_TUserDataPtr result, composite;
- /** Cursor position in the IME composition. */
- int cursor_position;
- /** Represents the position of the beginning of the selection */
- int target_start;
- /** Represents the position of the end of the selection */
- int target_end;
- /** custom temporal data */
- GHOST_TUserDataPtr tmp;
+ /** size_t */
+ GHOST_TUserDataPtr result_len, composite_len;
+ /** char * utf8 encoding */
+ GHOST_TUserDataPtr result, composite;
+ /** Cursor position in the IME composition. */
+ int cursor_position;
+ /** Represents the position of the beginning of the selection */
+ int target_start;
+ /** Represents the position of the end of the selection */
+ int target_end;
+ /** custom temporal data */
+ GHOST_TUserDataPtr tmp;
} GHOST_TEventImeData;
typedef struct {
- int count;
- GHOST_TUns8 **strings;
+ int count;
+ GHOST_TUns8 **strings;
} GHOST_TStringArray;
typedef enum {
- GHOST_kNotStarted,
- GHOST_kStarting,
- GHOST_kInProgress,
- GHOST_kFinishing,
- GHOST_kFinished
+ GHOST_kNotStarted,
+ GHOST_kStarting,
+ GHOST_kInProgress,
+ GHOST_kFinishing,
+ GHOST_kFinished
} GHOST_TProgress;
#ifdef WITH_INPUT_NDOF
typedef struct {
- /** N-degree of freedom device data v3 [GSoC 2010] */
- // Each component normally ranges from -1 to +1, but can exceed that.
- // These use blender standard view coordinates, with positive rotations being CCW about the axis.
- float tx, ty, tz; // translation
- float rx, ry, rz; // rotation:
- // axis = (rx,ry,rz).normalized
- // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
- float dt; // time since previous NDOF Motion event
- GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers)
+ /** N-degree of freedom device data v3 [GSoC 2010] */
+ // Each component normally ranges from -1 to +1, but can exceed that.
+ // These use blender standard view coordinates, with positive rotations being CCW about the axis.
+ float tx, ty, tz; // translation
+ float rx, ry, rz; // rotation:
+ // axis = (rx,ry,rz).normalized
+ // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
+ float dt; // time since previous NDOF Motion event
+ GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers)
} GHOST_TEventNDOFMotionData;
typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;
// good for mouse or other buttons too, hmmm?
typedef struct {
- GHOST_TButtonAction action;
- short button;
+ GHOST_TButtonAction action;
+ short button;
} GHOST_TEventNDOFButtonData;
-#endif // WITH_INPUT_NDOF
+#endif // WITH_INPUT_NDOF
typedef struct {
- /** The key code. */
- GHOST_TKey key;
-
- /* ascii / utf8: both should always be set when possible,
- * - ascii may be '\0' however if the user presses a non ascii key
- * - unicode may not be set if the system has no unicode support
- *
- * These values are intended to be used as follows.
- * For text input use unicode when available, fallback to ascii.
- * For areas where unicode is not needed, number input for example, always
- * use ascii, unicode is ignored - campbell.
- */
- /** The ascii code for the key event ('\0' if none). */
- char ascii;
- /** The unicode character. if the length is 6, not NULL terminated if all 6 are set */
- char utf8_buf[6];
+ /** The key code. */
+ GHOST_TKey key;
+
+ /* ascii / utf8: both should always be set when possible,
+ * - ascii may be '\0' however if the user presses a non ascii key
+ * - unicode may not be set if the system has no unicode support
+ *
+ * These values are intended to be used as follows.
+ * For text input use unicode when available, fallback to ascii.
+ * For areas where unicode is not needed, number input for example, always
+ * use ascii, unicode is ignored - campbell.
+ */
+ /** The ascii code for the key event ('\0' if none). */
+ char ascii;
+ /** The unicode character. if the length is 6, not NULL terminated if all 6 are set */
+ char utf8_buf[6];
} GHOST_TEventKeyData;
typedef struct {
- /** Number of pixels on a line. */
- GHOST_TUns32 xPixels;
- /** Number of lines. */
- GHOST_TUns32 yPixels;
- /** Numberof bits per pixel. */
- GHOST_TUns32 bpp;
- /** Refresh rate (in Hertz). */
- GHOST_TUns32 frequency;
+ /** Number of pixels on a line. */
+ GHOST_TUns32 xPixels;
+ /** Number of lines. */
+ GHOST_TUns32 yPixels;
+ /** Numberof bits per pixel. */
+ GHOST_TUns32 bpp;
+ /** Refresh rate (in Hertz). */
+ GHOST_TUns32 frequency;
} GHOST_DisplaySetting;
-
#ifdef _WIN32
-typedef void* GHOST_TEmbedderWindowID;
-#endif // _WIN32
+typedef void *GHOST_TEmbedderWindowID;
+#endif // _WIN32
#ifndef _WIN32
// I can't use "Window" from "<X11/Xlib.h>" because it conflits with Window defined in winlay.h
typedef int GHOST_TEmbedderWindowID;
-#endif // _WIN32
+#endif // _WIN32
/**
* A timer task callback routine.
@@ -554,4 +535,4 @@ struct GHOST_TimerTaskHandle__;
typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, GHOST_TUns64 time);
#endif
-#endif // __GHOST_TYPES_H__
+#endif // __GHOST_TYPES_H__
diff --git a/intern/ghost/intern/GHOST_Buttons.cpp b/intern/ghost/intern/GHOST_Buttons.cpp
index a470c7cfbd5..36205201176 100644
--- a/intern/ghost/intern/GHOST_Buttons.cpp
+++ b/intern/ghost/intern/GHOST_Buttons.cpp
@@ -21,51 +21,51 @@
* \ingroup GHOST
*/
-
#include "GHOST_Buttons.h"
-
-
GHOST_Buttons::GHOST_Buttons()
{
- clear();
+ clear();
}
-
bool GHOST_Buttons::get(GHOST_TButtonMask mask) const
{
- switch (mask) {
- case GHOST_kButtonMaskLeft:
- return m_ButtonLeft;
- case GHOST_kButtonMaskMiddle:
- return m_ButtonMiddle;
- case GHOST_kButtonMaskRight:
- return m_ButtonRight;
- default:
- return false;
- }
+ switch (mask) {
+ case GHOST_kButtonMaskLeft:
+ return m_ButtonLeft;
+ case GHOST_kButtonMaskMiddle:
+ return m_ButtonMiddle;
+ case GHOST_kButtonMaskRight:
+ return m_ButtonRight;
+ default:
+ return false;
+ }
}
void GHOST_Buttons::set(GHOST_TButtonMask mask, bool down)
{
- switch (mask) {
- case GHOST_kButtonMaskLeft:
- m_ButtonLeft = down; break;
- case GHOST_kButtonMaskMiddle:
- m_ButtonMiddle = down; break;
- case GHOST_kButtonMaskRight:
- m_ButtonRight = down; break;
- default:
- break;
- }
+ switch (mask) {
+ case GHOST_kButtonMaskLeft:
+ m_ButtonLeft = down;
+ break;
+ case GHOST_kButtonMaskMiddle:
+ m_ButtonMiddle = down;
+ break;
+ case GHOST_kButtonMaskRight:
+ m_ButtonRight = down;
+ break;
+ default:
+ break;
+ }
}
void GHOST_Buttons::clear()
{
- m_ButtonLeft = false;
- m_ButtonMiddle = false;
- m_ButtonRight = false;
+ m_ButtonLeft = false;
+ m_ButtonMiddle = false;
+ m_ButtonRight = false;
}
-GHOST_Buttons::~GHOST_Buttons() {
+GHOST_Buttons::~GHOST_Buttons()
+{
}
diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h
index 0c6c5f89323..0b824739950 100644
--- a/intern/ghost/intern/GHOST_Buttons.h
+++ b/intern/ghost/intern/GHOST_Buttons.h
@@ -27,41 +27,40 @@
#include "GHOST_Types.h"
-
/**
* This struct stores the state of the mouse buttons.
* Buttons can be set using button masks.
*/
struct GHOST_Buttons {
- /**
- * Constructor.
- */
- GHOST_Buttons();
+ /**
+ * Constructor.
+ */
+ GHOST_Buttons();
- ~GHOST_Buttons();
+ ~GHOST_Buttons();
- /**
- * Returns the state of a single button.
- * \param mask Key button to return.
- * \return The state of the button (pressed == true).
- */
- bool get(GHOST_TButtonMask mask) const;
+ /**
+ * Returns the state of a single button.
+ * \param mask Key button to return.
+ * \return The state of the button (pressed == true).
+ */
+ bool get(GHOST_TButtonMask mask) const;
- /**
- * Updates the state of a single button.
- * \param mask Button state to update.
- * \param down The new state of the button.
- */
- void set(GHOST_TButtonMask mask, bool down);
+ /**
+ * Updates the state of a single button.
+ * \param mask Button state to update.
+ * \param down The new state of the button.
+ */
+ void set(GHOST_TButtonMask mask, bool down);
- /**
- * Sets the state of all buttons to up.
- */
- void clear();
+ /**
+ * Sets the state of all buttons to up.
+ */
+ void clear();
- GHOST_TUns8 m_ButtonLeft : 1;
- GHOST_TUns8 m_ButtonMiddle : 1;
- GHOST_TUns8 m_ButtonRight : 1;
+ GHOST_TUns8 m_ButtonLeft : 1;
+ GHOST_TUns8 m_ButtonMiddle : 1;
+ GHOST_TUns8 m_ButtonRight : 1;
};
-#endif // __GHOST_BUTTONS_H__
+#endif // __GHOST_BUTTONS_H__
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 24456b841da..8d9570a39f3 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -34,110 +34,97 @@
GHOST_SystemHandle GHOST_CreateSystem(void)
{
- GHOST_ISystem::createSystem();
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ GHOST_ISystem::createSystem();
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return (GHOST_SystemHandle)system;
+ return (GHOST_SystemHandle)system;
}
-
-
GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->disposeSystem();
+ return system->disposeSystem();
}
-
GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
GHOST_TUserDataPtr userdata)
{
- return (GHOST_EventConsumerHandle) new GHOST_CallbackEventConsumer(eventCallback, userdata);
+ return (GHOST_EventConsumerHandle) new GHOST_CallbackEventConsumer(eventCallback, userdata);
}
-
GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhandle)
{
- delete ((GHOST_CallbackEventConsumer *)consumerhandle);
- return GHOST_kSuccess;
+ delete ((GHOST_CallbackEventConsumer *)consumerhandle);
+ return GHOST_kSuccess;
}
-
GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->getMilliSeconds();
+ return system->getMilliSeconds();
}
-
-
GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle,
GHOST_TUns64 delay,
GHOST_TUns64 interval,
GHOST_TimerProcPtr timerproc,
GHOST_TUserDataPtr userdata)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return (GHOST_TimerTaskHandle) system->installTimer(delay, interval, timerproc, userdata);
+ return (GHOST_TimerTaskHandle)system->installTimer(delay, interval, timerproc, userdata);
}
-
-
GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
GHOST_TimerTaskHandle timertaskhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
- return system->removeTimer(timertask);
+ return system->removeTimer(timertask);
}
-
-
GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->getNumDisplays();
+ return system->getNumDisplays();
}
-
-
void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
GHOST_TUns32 *width,
GHOST_TUns32 *height)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- system->getMainDisplayDimensions(*width, *height);
+ system->getMainDisplayDimensions(*width, *height);
}
void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
- GHOST_TUns32 *width,
- GHOST_TUns32 *height)
+ GHOST_TUns32 *width,
+ GHOST_TUns32 *height)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- system->getAllDisplayDimensions(*width, *height);
+ system->getAllDisplayDimensions(*width, *height);
}
GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return (GHOST_ContextHandle) system->createOffscreenContext();
+ return (GHOST_ContextHandle)system->createOffscreenContext();
}
GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
- GHOST_ContextHandle contexthandle)
+ GHOST_ContextHandle contexthandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- GHOST_IContext *context = (GHOST_IContext *) contexthandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ GHOST_IContext *context = (GHOST_IContext *)contexthandle;
- return system->disposeContext(context);
+ return system->disposeContext(context);
}
GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
@@ -150,146 +137,131 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
- state, type, glSettings, false);
+ return (GHOST_WindowHandle)system->createWindow(
+ title, left, top, width, height, state, type, glSettings, false);
}
GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->getUserData();
+ return window->getUserData();
}
void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- window->setUserData(userdata);
+ window->setUserData(userdata);
}
GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
GHOST_WindowHandle windowhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return system->disposeWindow(window);
+ return system->disposeWindow(window);
}
-
-
-int GHOST_ValidWindow(GHOST_SystemHandle systemhandle,
- GHOST_WindowHandle windowhandle)
+int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return (int) system->validWindow(window);
+ return (int)system->validWindow(window);
}
-
-
GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,
GHOST_DisplaySetting *setting,
const int stereoVisual)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- GHOST_IWindow *window = NULL;
- bool bstereoVisual;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ GHOST_IWindow *window = NULL;
+ bool bstereoVisual;
- if (stereoVisual)
- bstereoVisual = true;
- else
- bstereoVisual = false;
+ if (stereoVisual)
+ bstereoVisual = true;
+ else
+ bstereoVisual = false;
- system->beginFullScreen(*setting, &window, bstereoVisual);
+ system->beginFullScreen(*setting, &window, bstereoVisual);
- return (GHOST_WindowHandle)window;
+ return (GHOST_WindowHandle)window;
}
-
-
GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->endFullScreen();
+ return system->endFullScreen();
}
-
-
int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return (int) system->getFullScreen();
+ return (int)system->getFullScreen();
}
-
-
int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return (int) system->processEvents(waitForEvent ? true : false);
+ return (int)system->processEvents(waitForEvent ? true : false);
}
-
-
void GHOST_DispatchEvents(GHOST_SystemHandle systemhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- system->dispatchEvents();
+ system->dispatchEvents();
}
-
-GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle)
+GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle,
+ GHOST_EventConsumerHandle consumerhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->addEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle);
+ return system->addEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle);
}
-GHOST_TSuccess GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle)
+GHOST_TSuccess GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle,
+ GHOST_EventConsumerHandle consumerhandle)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->removeEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle);
+ return system->removeEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle);
}
GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, float progress)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setProgressBar(progress);
+ return window->setProgressBar(progress);
}
GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->endProgressBar();
+ return window->endProgressBar();
}
-
GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->getCursorShape();
+ return window->getCursorShape();
}
-
-
GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
GHOST_TStandardCursor cursorshape)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setCursorShape(cursorshape);
+ return window->setCursorShape(cursorshape);
}
GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,
@@ -298,9 +270,9 @@ GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,
int hotX,
int hotY)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setCustomCursorShape(bitmap, mask, hotX, hotY);
+ return window->setCustomCursorShape(bitmap, mask, hotX, hotY);
}
GHOST_TSuccess GHOST_SetCustomCursorShapeEx(GHOST_WindowHandle windowhandle,
@@ -313,664 +285,571 @@ GHOST_TSuccess GHOST_SetCustomCursorShapeEx(GHOST_WindowHandle windowhandle,
int fg_color,
int bg_color)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setCustomCursorShape(bitmap, mask, sizex, sizey,
- hotX, hotY, fg_color, bg_color);
+ return window->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, fg_color, bg_color);
}
-
-
int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return (int) window->getCursorVisibility();
+ return (int)window->getCursorVisibility();
}
-
-
-GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle,
- int visible)
+GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setCursorVisibility(visible ? true : false);
+ return window->setCursorVisibility(visible ? true : false);
}
-
-
GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TInt32 *x,
GHOST_TInt32 *y)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->getCursorPosition(*x, *y);
+ return system->getCursorPosition(*x, *y);
}
-
-
GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TInt32 x,
GHOST_TInt32 y)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return system->setCursorPosition(x, y);
+ return system->setCursorPosition(x, y);
}
-
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
GHOST_TGrabCursorMode mode,
- int bounds[4], const int mouse_ungrab_xy[2])
+ int bounds[4],
+ const int mouse_ungrab_xy[2])
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- GHOST_Rect bounds_rect;
- GHOST_TInt32 mouse_xy[2];
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ GHOST_Rect bounds_rect;
+ GHOST_TInt32 mouse_xy[2];
- if (bounds) {
- bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]);
- }
- if (mouse_ungrab_xy) {
- mouse_xy[0] = mouse_ungrab_xy[0];
- mouse_xy[1] = mouse_ungrab_xy[1];
- }
+ if (bounds) {
+ bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]);
+ }
+ if (mouse_ungrab_xy) {
+ mouse_xy[0] = mouse_ungrab_xy[0];
+ mouse_xy[1] = mouse_ungrab_xy[1];
+ }
- return window->setCursorGrab(mode,
- bounds ? &bounds_rect : NULL,
- mouse_ungrab_xy ? mouse_xy : NULL);
+ return window->setCursorGrab(
+ mode, bounds ? &bounds_rect : NULL, mouse_ungrab_xy ? mouse_xy : NULL);
}
-
GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
GHOST_TModifierKeyMask mask,
int *isDown)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- GHOST_TSuccess result;
- bool isdown = false;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ GHOST_TSuccess result;
+ bool isdown = false;
- result = system->getModifierKeyState(mask, isdown);
- *isDown = (int) isdown;
+ result = system->getModifierKeyState(mask, isdown);
+ *isDown = (int)isdown;
- return result;
+ return result;
}
-
-
GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
GHOST_TButtonMask mask,
int *isDown)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- GHOST_TSuccess result;
- bool isdown = false;
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ GHOST_TSuccess result;
+ bool isdown = false;
- result = system->getButtonState(mask, isdown);
- *isDown = (int) isdown;
+ result = system->getButtonState(mask, isdown);
+ *isDown = (int)isdown;
- return result;
+ return result;
}
-
#ifdef WITH_INPUT_NDOF
void GHOST_setNDOFDeadZone(float deadzone)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- system->setNDOFDeadZone(deadzone);
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ system->setNDOFDeadZone(deadzone);
}
#endif
void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, GHOST_TInt8 canAccept)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- window->setAcceptDragOperation(canAccept);
+ window->setAcceptDragOperation(canAccept);
}
-
GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle)
{
- GHOST_IEvent *event = (GHOST_IEvent *) eventhandle;
+ GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
- return event->getType();
+ return event->getType();
}
-
-
GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle)
{
- GHOST_IEvent *event = (GHOST_IEvent *) eventhandle;
+ GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
- return event->getTime();
+ return event->getTime();
}
-
GHOST_WindowHandle GHOST_GetEventWindow(GHOST_EventHandle eventhandle)
{
- GHOST_IEvent *event = (GHOST_IEvent *) eventhandle;
+ GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
- return (GHOST_WindowHandle) event->getWindow();
+ return (GHOST_WindowHandle)event->getWindow();
}
-
GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle)
{
- GHOST_IEvent *event = (GHOST_IEvent *) eventhandle;
+ GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
- return event->getData();
+ return event->getData();
}
-
-
GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle)
{
- GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
+ GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
- return timertask->getTimerProc();
+ return timertask->getTimerProc();
}
-
-
-void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle,
- GHOST_TimerProcPtr timerproc)
+void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle, GHOST_TimerProcPtr timerproc)
{
- GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
+ GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
- timertask->setTimerProc(timerproc);
+ timertask->setTimerProc(timerproc);
}
-
-
GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle)
{
- GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
+ GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
- return timertask->getUserData();
+ return timertask->getUserData();
}
-
-
-void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,
- GHOST_TUserDataPtr userdata)
+void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, GHOST_TUserDataPtr userdata)
{
- GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
+ GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
- timertask->setUserData(userdata);
+ timertask->setUserData(userdata);
}
-
-
int GHOST_GetValid(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return (int) window->getValid();
+ return (int)window->getValid();
}
-
-
GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->getDrawingContextType();
+ return window->getDrawingContextType();
}
-
-
GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle,
GHOST_TDrawingContextType type)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setDrawingContextType(type);
+ return window->setDrawingContextType(type);
}
-
-
-void GHOST_SetTitle(GHOST_WindowHandle windowhandle,
- const char *title)
+void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- window->setTitle(title);
+ window->setTitle(title);
}
-
char *GHOST_GetTitle(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- STR_String title;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ STR_String title;
- window->getTitle(title);
+ window->getTitle(title);
- char *ctitle = (char *) malloc(title.Length() + 1);
+ char *ctitle = (char *)malloc(title.Length() + 1);
- if (ctitle == NULL) {
- return NULL;
- }
+ if (ctitle == NULL) {
+ return NULL;
+ }
- strcpy(ctitle, title.Ptr());
+ strcpy(ctitle, title.Ptr());
- return ctitle;
+ return ctitle;
}
-
-
GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- GHOST_Rect *rectangle = NULL;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ GHOST_Rect *rectangle = NULL;
- rectangle = new GHOST_Rect();
- window->getWindowBounds(*rectangle);
+ rectangle = new GHOST_Rect();
+ window->getWindowBounds(*rectangle);
- return (GHOST_RectangleHandle)rectangle;
+ return (GHOST_RectangleHandle)rectangle;
}
-
-
GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- GHOST_Rect *rectangle = NULL;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ GHOST_Rect *rectangle = NULL;
- rectangle = new GHOST_Rect();
- window->getClientBounds(*rectangle);
+ rectangle = new GHOST_Rect();
+ window->getClientBounds(*rectangle);
- return (GHOST_RectangleHandle)rectangle;
+ return (GHOST_RectangleHandle)rectangle;
}
-
-
void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle)
{
- delete (GHOST_Rect *) rectanglehandle;
+ delete (GHOST_Rect *)rectanglehandle;
}
-
-
-GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle,
- GHOST_TUns32 width)
+GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setClientWidth(width);
+ return window->setClientWidth(width);
}
-
-
-GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle,
- GHOST_TUns32 height)
+GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setClientHeight(height);
+ return window->setClientHeight(height);
}
-
-
GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle,
GHOST_TUns32 width,
GHOST_TUns32 height)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setClientSize(width, height);
+ return window->setClientSize(width, height);
}
-
-
void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle,
GHOST_TInt32 inX,
GHOST_TInt32 inY,
GHOST_TInt32 *outX,
GHOST_TInt32 *outY)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- window->screenToClient(inX, inY, *outX, *outY);
+ window->screenToClient(inX, inY, *outX, *outY);
}
-
-
void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle,
GHOST_TInt32 inX,
GHOST_TInt32 inY,
GHOST_TInt32 *outX,
GHOST_TInt32 *outY)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- window->clientToScreen(inX, inY, *outX, *outY);
+ window->clientToScreen(inX, inY, *outX, *outY);
}
-
-
GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->getState();
+ return window->getState();
}
-
-
-GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
- GHOST_TWindowState state)
+GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, GHOST_TWindowState state)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setState(state);
+ return window->setState(state);
}
-
-GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, GHOST_TUns8 isUnsavedChanges)
+GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle,
+ GHOST_TUns8 isUnsavedChanges)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setModifiedState(isUnsavedChanges);
+ return window->setModifiedState(isUnsavedChanges);
}
-
-GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle,
- GHOST_TWindowOrder order)
+GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle, GHOST_TWindowOrder order)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setOrder(order);
+ return window->setOrder(order);
}
-
-
GHOST_TSuccess GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->swapBuffers();
+ return window->swapBuffers();
}
GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int interval)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setSwapInterval(interval);
+ return window->setSwapInterval(interval);
}
-GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int* intervalOut)
+GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int *intervalOut)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->getSwapInterval(*intervalOut);
+ return window->getSwapInterval(*intervalOut);
}
-
GHOST_TUns16 GHOST_GetNumOfAASamples(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->getNumOfAASamples();
+ return window->getNumOfAASamples();
}
GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->activateDrawingContext();
+ return window->activateDrawingContext();
}
GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
{
- GHOST_IContext *context = (GHOST_IContext *) contexthandle;
+ GHOST_IContext *context = (GHOST_IContext *)contexthandle;
- return context->activateDrawingContext();
+ return context->activateDrawingContext();
}
GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle)
{
- GHOST_IContext *context = (GHOST_IContext *) contexthandle;
+ GHOST_IContext *context = (GHOST_IContext *)contexthandle;
- return context->releaseDrawingContext();
+ return context->releaseDrawingContext();
}
GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->invalidate();
+ return window->invalidate();
}
void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
{
- GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
- system->setTabletAPI(api);
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ system->setTabletAPI(api);
}
const GHOST_TabletData *GHOST_GetTabletData(GHOST_WindowHandle windowhandle)
{
- return ((GHOST_IWindow *)windowhandle)->GetTabletData();
+ return ((GHOST_IWindow *)windowhandle)->GetTabletData();
}
-
GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)
{
- return ((GHOST_Rect *)rectanglehandle)->getWidth();
+ return ((GHOST_Rect *)rectanglehandle)->getWidth();
}
-
-
GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle)
{
- return ((GHOST_Rect *)rectanglehandle)->getHeight();
+ return ((GHOST_Rect *)rectanglehandle)->getHeight();
}
-
-
void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_TInt32 *l,
GHOST_TInt32 *t,
GHOST_TInt32 *r,
GHOST_TInt32 *b)
{
- GHOST_Rect *rect = (GHOST_Rect *) rectanglehandle;
+ GHOST_Rect *rect = (GHOST_Rect *)rectanglehandle;
- *l = rect->m_l;
- *t = rect->m_t;
- *r = rect->m_r;
- *b = rect->m_b;
+ *l = rect->m_l;
+ *t = rect->m_t;
+ *r = rect->m_r;
+ *b = rect->m_b;
}
-
void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_TInt32 l,
GHOST_TInt32 t,
GHOST_TInt32 r,
GHOST_TInt32 b)
{
- ((GHOST_Rect *)rectanglehandle)->set(l, t, r, b);
+ ((GHOST_Rect *)rectanglehandle)->set(l, t, r, b);
}
-
-
GHOST_TSuccess GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehandle)
{
- GHOST_TSuccess result = GHOST_kFailure;
+ GHOST_TSuccess result = GHOST_kFailure;
- if (((GHOST_Rect *)rectanglehandle)->isEmpty())
- result = GHOST_kSuccess;
+ if (((GHOST_Rect *)rectanglehandle)->isEmpty())
+ result = GHOST_kSuccess;
- return result;
+ return result;
}
-
-
GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle)
{
- GHOST_TSuccess result = GHOST_kFailure;
+ GHOST_TSuccess result = GHOST_kFailure;
- if (((GHOST_Rect *)rectanglehandle)->isValid())
- result = GHOST_kSuccess;
+ if (((GHOST_Rect *)rectanglehandle)->isValid())
+ result = GHOST_kSuccess;
- return result;
+ return result;
}
-
-
-void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle,
- GHOST_TInt32 i)
+void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i)
{
- ((GHOST_Rect *)rectanglehandle)->inset(i);
+ ((GHOST_Rect *)rectanglehandle)->inset(i);
}
-
-
void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_RectangleHandle anotherrectanglehandle)
{
- ((GHOST_Rect *)rectanglehandle)->unionRect(*(GHOST_Rect *)anotherrectanglehandle);
+ ((GHOST_Rect *)rectanglehandle)->unionRect(*(GHOST_Rect *)anotherrectanglehandle);
}
-
-
void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_TInt32 x,
GHOST_TInt32 y)
{
- ((GHOST_Rect *)rectanglehandle)->unionPoint(x, y);
+ ((GHOST_Rect *)rectanglehandle)->unionPoint(x, y);
}
-
-
GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_TInt32 x,
GHOST_TInt32 y)
{
- GHOST_TSuccess result = GHOST_kFailure;
+ GHOST_TSuccess result = GHOST_kFailure;
- if (((GHOST_Rect *)rectanglehandle)->isInside(x, y))
- result = GHOST_kSuccess;
+ if (((GHOST_Rect *)rectanglehandle)->isInside(x, y))
+ result = GHOST_kSuccess;
- return result;
+ return result;
}
-
-
GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle,
GHOST_RectangleHandle anotherrectanglehandle)
{
- GHOST_TVisibility visible = GHOST_kNotVisible;
+ GHOST_TVisibility visible = GHOST_kNotVisible;
- visible = ((GHOST_Rect *)rectanglehandle)->getVisibility(*(GHOST_Rect *)anotherrectanglehandle);
+ visible = ((GHOST_Rect *)rectanglehandle)->getVisibility(*(GHOST_Rect *)anotherrectanglehandle);
- return visible;
+ return visible;
}
-
-
void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_TInt32 cx,
GHOST_TInt32 cy)
{
- ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy);
+ ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy);
}
-
-
void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle,
GHOST_TInt32 cx,
GHOST_TInt32 cy,
GHOST_TInt32 w,
GHOST_TInt32 h)
{
- ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy, w, h);
+ ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy, w, h);
}
-
-
GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_RectangleHandle anotherrectanglehandle)
{
- GHOST_TSuccess result = GHOST_kFailure;
+ GHOST_TSuccess result = GHOST_kFailure;
- if (((GHOST_Rect *)rectanglehandle)->clip(*(GHOST_Rect *)anotherrectanglehandle))
- result = GHOST_kSuccess;
+ if (((GHOST_Rect *)rectanglehandle)->clip(*(GHOST_Rect *)anotherrectanglehandle))
+ result = GHOST_kSuccess;
- return result;
+ return result;
}
GHOST_TUns8 *GHOST_getClipboard(int selection)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return system->getClipboard(selection);
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->getClipboard(selection);
}
void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- system->putClipboard(buffer, selection);
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ system->putClipboard(buffer, selection);
}
int GHOST_toggleConsole(int action)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return system->toggleConsole(action);
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->toggleConsole(action);
}
int GHOST_SupportsNativeDialogs(void)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return system->supportsNativeDialogs();
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->supportsNativeDialogs();
}
int GHOST_confirmQuit(GHOST_WindowHandle windowhandle)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return system->confirmQuit((GHOST_IWindow *) windowhandle);
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->confirmQuit((GHOST_IWindow *)windowhandle);
}
int GHOST_UseNativePixels(void)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return system->useNativePixel();
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->useNativePixel();
}
void GHOST_UseWindowFocus(int use_focus)
{
- GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return system->useWindowFocus(use_focus);
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->useWindowFocus(use_focus);
}
float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- if (window)
- return window->getNativePixelSize();
- return 1.0f;
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ if (window)
+ return window->getNativePixelSize();
+ return 1.0f;
}
GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->getDPIHint();
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ return window->getDPIHint();
}
#ifdef WITH_INPUT_IME
void GHOST_BeginIME(GHOST_WindowHandle windowhandle,
- GHOST_TInt32 x, GHOST_TInt32 y,
- GHOST_TInt32 w, GHOST_TInt32 h,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y,
+ GHOST_TInt32 w,
+ GHOST_TInt32 h,
int complete)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- window->beginIME(x, y, w, h, complete);
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ window->beginIME(x, y, w, h, complete);
}
void GHOST_EndIME(GHOST_WindowHandle windowhandle)
{
- GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- window->endIME();
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ window->endIME();
}
-#endif /* WITH_INPUT_IME */
+#endif /* WITH_INPUT_IME */
diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
index a73931f48e9..843c8adc6cb 100644
--- a/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
+++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
@@ -33,12 +32,11 @@
GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
GHOST_TUserDataPtr userData)
{
- m_eventCallback = eventCallback;
- m_userData = userData;
+ m_eventCallback = eventCallback;
+ m_userData = userData;
}
-
bool GHOST_CallbackEventConsumer::processEvent(GHOST_IEvent *event)
{
- return m_eventCallback((GHOST_EventHandle)event, m_userData) != 0;
+ return m_eventCallback((GHOST_EventHandle)event, m_userData) != 0;
}
diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.h b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
index 46f983f2dff..7abe0253f75 100644
--- a/intern/ghost/intern/GHOST_CallbackEventConsumer.h
+++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
@@ -32,41 +32,39 @@
* Event consumer that will forward events to a call-back routine.
* Especially useful for the C-API.
*/
-class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer
-{
-public:
- /**
- * Constructor.
- * \param eventCallback The call-back routine invoked.
- * \param userData The data passed back though the call-back routine.
- */
- GHOST_CallbackEventConsumer(
- GHOST_EventCallbackProcPtr eventCallback,
- GHOST_TUserDataPtr userData);
+class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer {
+ public:
+ /**
+ * Constructor.
+ * \param eventCallback The call-back routine invoked.
+ * \param userData The data passed back though the call-back routine.
+ */
+ GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
+ GHOST_TUserDataPtr userData);
- /**
- * Destructor.
- */
- ~GHOST_CallbackEventConsumer(void)
- {
- }
+ /**
+ * Destructor.
+ */
+ ~GHOST_CallbackEventConsumer(void)
+ {
+ }
- /**
- * This method is called by an event producer when an event is available.
- * \param event The event that can be handled or ignored.
- * \return Indication as to whether the event was handled.
- */
- bool processEvent(GHOST_IEvent *event);
+ /**
+ * This method is called by an event producer when an event is available.
+ * \param event The event that can be handled or ignored.
+ * \return Indication as to whether the event was handled.
+ */
+ bool processEvent(GHOST_IEvent *event);
-protected:
- /** The call-back routine invoked. */
- GHOST_EventCallbackProcPtr m_eventCallback;
- /** The data passed back though the call-back routine. */
- GHOST_TUserDataPtr m_userData;
+ protected:
+ /** The call-back routine invoked. */
+ GHOST_EventCallbackProcPtr m_eventCallback;
+ /** The data passed back though the call-back routine. */
+ GHOST_TUserDataPtr m_userData;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_CallbackEventConsumer")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_CallbackEventConsumer")
#endif
};
-#endif // __GHOST_CALLBACKEVENTCONSUMER_H__
+#endif // __GHOST_CALLBACKEVENTCONSUMER_H__
diff --git a/intern/ghost/intern/GHOST_Context.cpp b/intern/ghost/intern/GHOST_Context.cpp
index 0aae38eed2c..0d167209909 100644
--- a/intern/ghost/intern/GHOST_Context.cpp
+++ b/intern/ghost/intern/GHOST_Context.cpp
@@ -26,7 +26,7 @@
#include "GHOST_Context.h"
#ifdef _WIN32
-# include <GL/wglew.h> // only for symbolic constants, do not use API functions
+# include <GL/wglew.h> // only for symbolic constants, do not use API functions
# include <tchar.h>
#
# ifndef ERROR_PROFILE_DOES_NOT_MATCH_DEVICE
@@ -37,123 +37,115 @@
#include <cstdio>
#include <cstring>
-
#ifdef _WIN32
bool win32_silent_chk(bool result)
{
- if (!result) {
- SetLastError(NO_ERROR);
- }
+ if (!result) {
+ SetLastError(NO_ERROR);
+ }
- return result;
+ return result;
}
bool win32_chk(bool result, const char *file, int line, const char *text)
{
- if (!result) {
- LPTSTR formattedMsg = NULL;
-
- DWORD error = GetLastError();
-
- const char *msg;
-
- DWORD count = 0;
-
- /* Some drivers returns a HRESULT instead of a standard error message.
- * i.e: 0xC0072095 instead of 0x2095 for ERROR_INVALID_VERSION_ARB
- * So strip down the error to the valid error code range. */
- switch (error & 0x0000FFFF) {
- case ERROR_INVALID_VERSION_ARB:
- msg = "The specified OpenGL version and feature set are either invalid or not supported.\n";
- break;
-
- case ERROR_INVALID_PROFILE_ARB:
- msg = "The specified OpenGL profile and feature set are either invalid or not supported.\n";
- break;
-
- case ERROR_INVALID_PIXEL_TYPE_ARB:
- msg = "The specified pixel type is invalid.\n";
- break;
-
- case ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB:
- msg = ("The device contexts specified are not compatible. "
- "This can occur if the device contexts are managed by "
- "different drivers or possibly on different graphics adapters.\n");
- break;
-
-#ifdef WITH_GLEW_ES
- case ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV:
- msg = "The device context(s) and rendering context have non-matching affinity masks.\n";
- break;
-
- case ERROR_MISSING_AFFINITY_MASK_NV:
- msg = "The rendering context does not have an affinity mask set.\n";
- break;
-#endif
+ if (!result) {
+ LPTSTR formattedMsg = NULL;
+
+ DWORD error = GetLastError();
+
+ const char *msg;
+
+ DWORD count = 0;
+
+ /* Some drivers returns a HRESULT instead of a standard error message.
+ * i.e: 0xC0072095 instead of 0x2095 for ERROR_INVALID_VERSION_ARB
+ * So strip down the error to the valid error code range. */
+ switch (error & 0x0000FFFF) {
+ case ERROR_INVALID_VERSION_ARB:
+ msg =
+ "The specified OpenGL version and feature set are either invalid or not supported.\n";
+ break;
+
+ case ERROR_INVALID_PROFILE_ARB:
+ msg =
+ "The specified OpenGL profile and feature set are either invalid or not supported.\n";
+ break;
+
+ case ERROR_INVALID_PIXEL_TYPE_ARB:
+ msg = "The specified pixel type is invalid.\n";
+ break;
+
+ case ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB:
+ msg =
+ ("The device contexts specified are not compatible. "
+ "This can occur if the device contexts are managed by "
+ "different drivers or possibly on different graphics adapters.\n");
+ break;
+
+# ifdef WITH_GLEW_ES
+ case ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV:
+ msg = "The device context(s) and rendering context have non-matching affinity masks.\n";
+ break;
+
+ case ERROR_MISSING_AFFINITY_MASK_NV:
+ msg = "The rendering context does not have an affinity mask set.\n";
+ break;
+# endif
- case ERROR_PROFILE_DOES_NOT_MATCH_DEVICE:
- msg = ("The specified profile is intended for a device of a "
- "different type than the specified device.\n");
- break;
-
- default:
- {
- count =
- FormatMessage(
- (FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS),
- NULL,
- error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)(&formattedMsg),
- 0,
- NULL);
-
- msg = count > 0 ? formattedMsg : "<no system message>\n";
- break;
- }
- }
-
-#ifndef NDEBUG
- _ftprintf(
- stderr,
- "%s(%d):[%s] -> Win32 Error# (%lu): %s",
- file,
- line,
- text,
- (unsigned long)error,
- msg);
-#else
- _ftprintf(
- stderr,
- "Win32 Error# (%lu): %s",
- (unsigned long)error,
- msg);
-#endif
+ case ERROR_PROFILE_DOES_NOT_MATCH_DEVICE:
+ msg =
+ ("The specified profile is intended for a device of a "
+ "different type than the specified device.\n");
+ break;
+
+ default: {
+ count = FormatMessage((FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS),
+ NULL,
+ error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)(&formattedMsg),
+ 0,
+ NULL);
+
+ msg = count > 0 ? formattedMsg : "<no system message>\n";
+ break;
+ }
+ }
+
+# ifndef NDEBUG
+ _ftprintf(stderr,
+ "%s(%d):[%s] -> Win32 Error# (%lu): %s",
+ file,
+ line,
+ text,
+ (unsigned long)error,
+ msg);
+# else
+ _ftprintf(stderr, "Win32 Error# (%lu): %s", (unsigned long)error, msg);
+# endif
- SetLastError(NO_ERROR);
+ SetLastError(NO_ERROR);
- if (count != 0)
- LocalFree(formattedMsg);
- }
+ if (count != 0)
+ LocalFree(formattedMsg);
+ }
- return result;
+ return result;
}
-#endif // _WIN32
-
+#endif // _WIN32
void GHOST_Context::initContextGLEW()
{
- GLEW_CHK(glewInit());
+ GLEW_CHK(glewInit());
}
-
void GHOST_Context::initClearGL()
{
- glClearColor(0.447, 0.447, 0.447, 0.000);
- glClear(GL_COLOR_BUFFER_BIT);
- glClearColor(0.000, 0.000, 0.000, 0.000);
+ glClearColor(0.447, 0.447, 0.447, 0.000);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0.000, 0.000, 0.000, 0.000);
}
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index decafd10b75..ed7b63aa436 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -30,126 +30,128 @@
#include "glew-mx.h"
-#include <cstdlib> // for NULL
-
-
-class GHOST_Context : public GHOST_IContext
-{
-public:
- /**
- * Constructor.
- * \param stereoVisual Stereo visual for quad buffered stereo.
- * \param numOfAASamples Number of samples used for AA (zero if no AA)
- */
- GHOST_Context(bool stereoVisual, GHOST_TUns16 numOfAASamples)
- : m_stereoVisual(stereoVisual),
- m_numOfAASamples(numOfAASamples)
- {}
-
- /**
- * Destructor.
- */
- virtual ~GHOST_Context() {
- }
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess swapBuffers() = 0;
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess activateDrawingContext() = 0;
-
- /**
- * Release the drawing context of the calling thread.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess releaseDrawingContext()= 0;
-
- /**
- * Call immediately after new to initialize. If this fails then immediately delete the object.
- * \return Indication as to whether initialization has succeeded.
- */
- virtual GHOST_TSuccess initializeDrawingContext() = 0;
-
- /**
- * Updates the drawing context of this window. Needed
- * whenever the window is changed.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess updateDrawingContext() {
- return GHOST_kFailure;
- }
-
- /**
- * Checks if it is OK for a remove the native display
- * \return Indication as to whether removal has succeeded.
- */
- virtual GHOST_TSuccess releaseNativeHandles() = 0;
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess setSwapInterval(int /*interval*/) {
- return GHOST_kFailure;
- }
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \param intervalOut Variable to store the swap interval if it can be read.
- * \return Whether the swap interval can be read.
- */
- virtual GHOST_TSuccess getSwapInterval(int&) {
- return GHOST_kFailure;
- }
-
- /**
- * Stereo visual created. Only necessary for 'real' stereo support,
- * ie quad buffered stereo. This is not always possible, depends on
- * the graphics h/w
- */
- inline bool isStereoVisual() const {
- return m_stereoVisual;
- }
-
- /** Number of samples used in anti-aliasing, set to 0 if no AA */
- inline GHOST_TUns16 getNumOfAASamples() const {
- return m_numOfAASamples;
- }
-
-protected:
- void initContextGLEW();
-
- bool m_stereoVisual;
-
- GHOST_TUns16 m_numOfAASamples;
-
- static void initClearGL();
+#include <cstdlib> // for NULL
+
+class GHOST_Context : public GHOST_IContext {
+ public:
+ /**
+ * Constructor.
+ * \param stereoVisual Stereo visual for quad buffered stereo.
+ * \param numOfAASamples Number of samples used for AA (zero if no AA)
+ */
+ GHOST_Context(bool stereoVisual, GHOST_TUns16 numOfAASamples)
+ : m_stereoVisual(stereoVisual), m_numOfAASamples(numOfAASamples)
+ {
+ }
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_Context()
+ {
+ }
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess swapBuffers() = 0;
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess activateDrawingContext() = 0;
+
+ /**
+ * Release the drawing context of the calling thread.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess releaseDrawingContext() = 0;
+
+ /**
+ * Call immediately after new to initialize. If this fails then immediately delete the object.
+ * \return Indication as to whether initialization has succeeded.
+ */
+ virtual GHOST_TSuccess initializeDrawingContext() = 0;
+
+ /**
+ * Updates the drawing context of this window. Needed
+ * whenever the window is changed.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess updateDrawingContext()
+ {
+ return GHOST_kFailure;
+ }
+
+ /**
+ * Checks if it is OK for a remove the native display
+ * \return Indication as to whether removal has succeeded.
+ */
+ virtual GHOST_TSuccess releaseNativeHandles() = 0;
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess setSwapInterval(int /*interval*/)
+ {
+ return GHOST_kFailure;
+ }
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \param intervalOut Variable to store the swap interval if it can be read.
+ * \return Whether the swap interval can be read.
+ */
+ virtual GHOST_TSuccess getSwapInterval(int &)
+ {
+ return GHOST_kFailure;
+ }
+
+ /**
+ * Stereo visual created. Only necessary for 'real' stereo support,
+ * ie quad buffered stereo. This is not always possible, depends on
+ * the graphics h/w
+ */
+ inline bool isStereoVisual() const
+ {
+ return m_stereoVisual;
+ }
+
+ /** Number of samples used in anti-aliasing, set to 0 if no AA */
+ inline GHOST_TUns16 getNumOfAASamples() const
+ {
+ return m_numOfAASamples;
+ }
+
+ protected:
+ void initContextGLEW();
+
+ bool m_stereoVisual;
+
+ GHOST_TUns16 m_numOfAASamples;
+
+ static void initClearGL();
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Context")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Context")
#endif
};
-
#ifdef _WIN32
bool win32_chk(bool result, const char *file = NULL, int line = 0, const char *text = NULL);
bool win32_silent_chk(bool result);
# ifndef NDEBUG
-# define WIN32_CHK(x) win32_chk((x), __FILE__, __LINE__, #x)
+# define WIN32_CHK(x) win32_chk((x), __FILE__, __LINE__, # x)
# else
# define WIN32_CHK(x) win32_chk(x)
# endif
-#define WIN32_CHK_SILENT(x, silent) ((silent) ? win32_silent_chk(x) : WIN32_CHK(x))
-#endif /* _WIN32 */
-
+# define WIN32_CHK_SILENT(x, silent) ((silent) ? win32_silent_chk(x) : WIN32_CHK(x))
+#endif /* _WIN32 */
-#endif // __GHOST_CONTEXT_H__
+#endif // __GHOST_CONTEXT_H__
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index 13125e39f30..648af1cc9c7 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -27,107 +27,103 @@
#include "GHOST_Context.h"
#ifndef GHOST_OPENGL_CGL_CONTEXT_FLAGS
-#define GHOST_OPENGL_CGL_CONTEXT_FLAGS 0
+# define GHOST_OPENGL_CGL_CONTEXT_FLAGS 0
#endif
#ifndef GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY
-#define GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY 0
+# define GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY 0
#endif
-
@class NSWindow;
@class NSOpenGLView;
@class NSOpenGLContext;
-
-class GHOST_ContextCGL : public GHOST_Context
-{
-public:
- /**
- * Constructor.
- */
- GHOST_ContextCGL(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- NSWindow *window,
- NSOpenGLView *openGLView,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy);
-
- /**
- * Destructor.
- */
- ~GHOST_ContextCGL();
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess swapBuffers();
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess activateDrawingContext();
-
- /**
- * Release the drawing context of the calling thread.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess releaseDrawingContext();
-
- /**
- * Call immediately after new to initialize. If this fails then immediately delete the object.
- * \return Indication as to whether initialization has succeeded.
- */
- GHOST_TSuccess initializeDrawingContext();
-
- /**
- * Removes references to native handles from this context and then returns
- * \return GHOST_kSuccess if it is OK for the parent to release the handles and
- * GHOST_kFailure if releasing the handles will interfere with sharing
- */
- GHOST_TSuccess releaseNativeHandles();
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess setSwapInterval(int interval);
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \param intervalOut Variable to store the swap interval if it can be read.
- * \return Whether the swap interval can be read.
- */
- GHOST_TSuccess getSwapInterval(int&);
-
- /**
- * Updates the drawing context of this window.
- * Needed whenever the window is changed.
- * \return Indication of success.
- */
- GHOST_TSuccess updateDrawingContext();
-
-private:
- /** The openGL view */
- NSOpenGLView *m_openGLView;
-
- /** The OpenGL drawing context */
- NSOpenGLContext *m_openGLContext;
-
- bool m_coreProfile;
-
- const bool m_debug;
-
- /** The first created OpenGL context (for sharing display lists) */
- static NSOpenGLContext *s_sharedOpenGLContext;
- static int s_sharedCount;
+class GHOST_ContextCGL : public GHOST_Context {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_ContextCGL(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ NSWindow *window,
+ NSOpenGLView *openGLView,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy);
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_ContextCGL();
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess swapBuffers();
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess activateDrawingContext();
+
+ /**
+ * Release the drawing context of the calling thread.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess releaseDrawingContext();
+
+ /**
+ * Call immediately after new to initialize. If this fails then immediately delete the object.
+ * \return Indication as to whether initialization has succeeded.
+ */
+ GHOST_TSuccess initializeDrawingContext();
+
+ /**
+ * Removes references to native handles from this context and then returns
+ * \return GHOST_kSuccess if it is OK for the parent to release the handles and
+ * GHOST_kFailure if releasing the handles will interfere with sharing
+ */
+ GHOST_TSuccess releaseNativeHandles();
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess setSwapInterval(int interval);
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \param intervalOut Variable to store the swap interval if it can be read.
+ * \return Whether the swap interval can be read.
+ */
+ GHOST_TSuccess getSwapInterval(int &);
+
+ /**
+ * Updates the drawing context of this window.
+ * Needed whenever the window is changed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess updateDrawingContext();
+
+ private:
+ /** The openGL view */
+ NSOpenGLView *m_openGLView;
+
+ /** The OpenGL drawing context */
+ NSOpenGLContext *m_openGLContext;
+
+ bool m_coreProfile;
+
+ const bool m_debug;
+
+ /** The first created OpenGL context (for sharing display lists) */
+ static NSOpenGLContext *s_sharedOpenGLContext;
+ static int s_sharedCount;
};
-#endif // __GHOST_CONTEXTCGL_H__
+#endif // __GHOST_CONTEXTCGL_H__
diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm
index 913ba459e9a..9b4e1864adf 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.mm
+++ b/intern/ghost/intern/GHOST_ContextCGL.mm
@@ -30,380 +30,384 @@
//#define GHOST_MULTITHREADED_OPENGL
#ifdef GHOST_MULTITHREADED_OPENGL
-#include <OpenGL/OpenGL.h>
+# include <OpenGL/OpenGL.h>
#endif
#include <vector>
#include <cassert>
-
NSOpenGLContext *GHOST_ContextCGL::s_sharedOpenGLContext = nil;
-int GHOST_ContextCGL::s_sharedCount = 0;
-
-
-GHOST_ContextCGL::GHOST_ContextCGL(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- NSWindow *window,
- NSOpenGLView *openGLView,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy)
+int GHOST_ContextCGL::s_sharedCount = 0;
+
+GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ NSWindow *window,
+ NSOpenGLView *openGLView,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
m_openGLView(openGLView),
m_openGLContext(nil),
m_debug(contextFlags)
{
- // for now be very strict about OpenGL version requested
- switch (contextMajorVersion) {
- case 2:
- assert(contextMinorVersion == 1);
- assert(contextProfileMask == 0);
- m_coreProfile = false;
- break;
- case 3:
- // Apple didn't implement 3.0 or 3.1
- assert(contextMinorVersion == 3);
- assert(contextProfileMask == GL_CONTEXT_CORE_PROFILE_BIT);
- m_coreProfile = true;
- break;
- default:
- assert(false);
- }
+ // for now be very strict about OpenGL version requested
+ switch (contextMajorVersion) {
+ case 2:
+ assert(contextMinorVersion == 1);
+ assert(contextProfileMask == 0);
+ m_coreProfile = false;
+ break;
+ case 3:
+ // Apple didn't implement 3.0 or 3.1
+ assert(contextMinorVersion == 3);
+ assert(contextProfileMask == GL_CONTEXT_CORE_PROFILE_BIT);
+ m_coreProfile = true;
+ break;
+ default:
+ assert(false);
+ }
}
-
GHOST_ContextCGL::~GHOST_ContextCGL()
{
- if (m_openGLContext != nil) {
- if (m_openGLContext == [NSOpenGLContext currentContext]) {
- [NSOpenGLContext clearCurrentContext];
+ if (m_openGLContext != nil) {
+ if (m_openGLContext == [NSOpenGLContext currentContext]) {
+ [NSOpenGLContext clearCurrentContext];
- if(m_openGLView) {
- [m_openGLView clearGLContext];
- }
- }
+ if (m_openGLView) {
+ [m_openGLView clearGLContext];
+ }
+ }
- if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) {
- assert(s_sharedCount > 0);
+ if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) {
+ assert(s_sharedCount > 0);
- s_sharedCount--;
+ s_sharedCount--;
- if (s_sharedCount == 0)
- s_sharedOpenGLContext = nil;
+ if (s_sharedCount == 0)
+ s_sharedOpenGLContext = nil;
- [m_openGLContext release];
- }
- }
+ [m_openGLContext release];
+ }
+ }
}
-
GHOST_TSuccess GHOST_ContextCGL::swapBuffers()
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext flushBuffer];
- [pool drain];
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLContext flushBuffer];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextCGL::setSwapInterval(int interval)
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
- [pool drain];
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextCGL::getSwapInterval(int &intervalOut)
{
- if (m_openGLContext != nil) {
- GLint interval;
+ if (m_openGLContext != nil) {
+ GLint interval;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext getValues:&interval forParameter:NSOpenGLCPSwapInterval];
+ [m_openGLContext getValues:&interval forParameter:NSOpenGLCPSwapInterval];
- [pool drain];
+ [pool drain];
- intervalOut = static_cast<int>(interval);
+ intervalOut = static_cast<int>(interval);
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextCGL::activateDrawingContext()
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext makeCurrentContext];
- [pool drain];
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLContext makeCurrentContext];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
GHOST_TSuccess GHOST_ContextCGL::releaseDrawingContext()
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [NSOpenGLContext clearCurrentContext];
- [pool drain];
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [NSOpenGLContext clearCurrentContext];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext()
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext update];
- [pool drain];
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLContext update];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
-static void makeAttribList(
- std::vector<NSOpenGLPixelFormatAttribute>& attribs,
- bool coreProfile,
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool softwareGL)
+static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs,
+ bool coreProfile,
+ bool stereoVisual,
+ int numOfAASamples,
+ bool needAlpha,
+ bool needStencil,
+ bool softwareGL)
{
- attribs.clear();
+ attribs.clear();
- attribs.push_back(NSOpenGLPFAOpenGLProfile);
- attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy);
+ attribs.push_back(NSOpenGLPFAOpenGLProfile);
+ attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy);
- // Pixel Format Attributes for the windowed NSOpenGLContext
- attribs.push_back(NSOpenGLPFADoubleBuffer);
+ // Pixel Format Attributes for the windowed NSOpenGLContext
+ attribs.push_back(NSOpenGLPFADoubleBuffer);
- if (softwareGL) {
- attribs.push_back(NSOpenGLPFARendererID);
- attribs.push_back(kCGLRendererGenericFloatID);
- }
- else {
- attribs.push_back(NSOpenGLPFAAccelerated);
- attribs.push_back(NSOpenGLPFANoRecovery);
- }
+ if (softwareGL) {
+ attribs.push_back(NSOpenGLPFARendererID);
+ attribs.push_back(kCGLRendererGenericFloatID);
+ }
+ else {
+ attribs.push_back(NSOpenGLPFAAccelerated);
+ attribs.push_back(NSOpenGLPFANoRecovery);
+ }
- attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // for automatic GPU switching
+ attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // for automatic GPU switching
- attribs.push_back(NSOpenGLPFADepthSize);
- attribs.push_back((NSOpenGLPixelFormatAttribute) 32);
+ attribs.push_back(NSOpenGLPFADepthSize);
+ attribs.push_back((NSOpenGLPixelFormatAttribute)32);
- if (stereoVisual)
- attribs.push_back(NSOpenGLPFAStereo);
+ if (stereoVisual)
+ attribs.push_back(NSOpenGLPFAStereo);
- if (needAlpha) {
- attribs.push_back(NSOpenGLPFAAlphaSize);
- attribs.push_back((NSOpenGLPixelFormatAttribute) 8);
- }
+ if (needAlpha) {
+ attribs.push_back(NSOpenGLPFAAlphaSize);
+ attribs.push_back((NSOpenGLPixelFormatAttribute)8);
+ }
- if (needStencil) {
- attribs.push_back(NSOpenGLPFAStencilSize);
- attribs.push_back((NSOpenGLPixelFormatAttribute) 8);
- }
+ if (needStencil) {
+ attribs.push_back(NSOpenGLPFAStencilSize);
+ attribs.push_back((NSOpenGLPixelFormatAttribute)8);
+ }
- if (numOfAASamples > 0) {
- // Multisample anti-aliasing
- attribs.push_back(NSOpenGLPFAMultisample);
+ if (numOfAASamples > 0) {
+ // Multisample anti-aliasing
+ attribs.push_back(NSOpenGLPFAMultisample);
- attribs.push_back(NSOpenGLPFASampleBuffers);
- attribs.push_back((NSOpenGLPixelFormatAttribute) 1);
+ attribs.push_back(NSOpenGLPFASampleBuffers);
+ attribs.push_back((NSOpenGLPixelFormatAttribute)1);
- attribs.push_back(NSOpenGLPFASamples);
- attribs.push_back((NSOpenGLPixelFormatAttribute) numOfAASamples);
- }
+ attribs.push_back(NSOpenGLPFASamples);
+ attribs.push_back((NSOpenGLPixelFormatAttribute)numOfAASamples);
+ }
- attribs.push_back((NSOpenGLPixelFormatAttribute) 0);
+ attribs.push_back((NSOpenGLPixelFormatAttribute)0);
}
// TODO(merwin): make this available to all platforms
static void getVersion(int *major, int *minor)
{
-#if 1 // legacy GL
- sscanf((const char*)glGetString(GL_VERSION), "%d.%d", major, minor);
-#else // 3.0+
- glGetIntegerv(GL_MAJOR_VERSION, major);
- glGetIntegerv(GL_MINOR_VERSION, minor);
+#if 1 // legacy GL
+ sscanf((const char *)glGetString(GL_VERSION), "%d.%d", major, minor);
+#else // 3.0+
+ glGetIntegerv(GL_MAJOR_VERSION, major);
+ glGetIntegerv(GL_MINOR_VERSION, minor);
#endif
}
GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- std::vector<NSOpenGLPixelFormatAttribute> attribs;
- attribs.reserve(40);
+ std::vector<NSOpenGLPixelFormatAttribute> attribs;
+ attribs.reserve(40);
- NSOpenGLContext *prev_openGLContext = (m_openGLView) ? [m_openGLView openGLContext] : NULL;
+ NSOpenGLContext *prev_openGLContext = (m_openGLView) ? [m_openGLView openGLContext] : NULL;
#ifdef GHOST_OPENGL_ALPHA
- static const bool needAlpha = true;
+ static const bool needAlpha = true;
#else
- static const bool needAlpha = false;
+ static const bool needAlpha = false;
#endif
#ifdef GHOST_OPENGL_STENCIL
- static const bool needStencil = true;
+ static const bool needStencil = true;
#else
- static const bool needStencil = false;
+ static const bool needStencil = false;
#endif
- static bool softwareGL = getenv("BLENDER_SOFTWAREGL"); // command-line argument would be better
- GLint major = 0, minor = 0;
- NSOpenGLPixelFormat *pixelFormat;
- // TODO: keep pixel format for subsequent windows/contexts instead of recreating each time
-
- makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
-
- pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
-
- // Fall back to no multisampling if Antialiasing init failed
- if (m_numOfAASamples > 0 && pixelFormat == nil) {
- // XXX jwilkins: Does CGL only succeed when it makes an exact match on the number of samples?
- // Does this need to explicitly try for a lesser match before giving up?
- // (Now that I think about it, does WGL really require the code that it has for finding a lesser match?)
-
- attribs.clear();
- makeAttribList(attribs, m_coreProfile, m_stereoVisual, 0, needAlpha, needStencil, softwareGL);
- pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
- }
-
- if (pixelFormat == nil)
- goto error;
-
- if (m_numOfAASamples > 0) { //Set m_numOfAASamples to the actual value
- GLint actualSamples;
- [pixelFormat getValues:&actualSamples forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
-
- if (m_numOfAASamples != (GHOST_TUns16)actualSamples) {
- fprintf(stderr,
- "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
- "Substituting one that uses %d samples.\n",
- m_numOfAASamples, actualSamples);
-
- m_numOfAASamples = (GHOST_TUns16)actualSamples;
- }
- }
-
- m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext];
- [pixelFormat release];
-
- [m_openGLContext makeCurrentContext];
-
- getVersion(&major, &minor);
- if (m_debug) {
- fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
- fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
- }
-
- if (major < 2 || (major == 2 && minor < 1)) {
- // fall back to software renderer if GL < 2.1
- fprintf(stderr, "OpenGL 2.1 is not supported on your hardware, falling back to software");
- softwareGL = true;
-
- // discard hardware GL context
- [NSOpenGLContext clearCurrentContext];
- [m_openGLContext release];
-
- // create software GL context
- makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
- pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
- m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext];
- [pixelFormat release];
-
- [m_openGLContext makeCurrentContext];
-
- getVersion(&major, &minor);
- if (m_debug) {
- fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
- fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
- }
- }
+ static bool softwareGL = getenv("BLENDER_SOFTWAREGL"); // command-line argument would be better
+ GLint major = 0, minor = 0;
+ NSOpenGLPixelFormat *pixelFormat;
+ // TODO: keep pixel format for subsequent windows/contexts instead of recreating each time
+
+ makeAttribList(attribs,
+ m_coreProfile,
+ m_stereoVisual,
+ m_numOfAASamples,
+ needAlpha,
+ needStencil,
+ softwareGL);
+
+ pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
+
+ // Fall back to no multisampling if Antialiasing init failed
+ if (m_numOfAASamples > 0 && pixelFormat == nil) {
+ // XXX jwilkins: Does CGL only succeed when it makes an exact match on the number of samples?
+ // Does this need to explicitly try for a lesser match before giving up?
+ // (Now that I think about it, does WGL really require the code that it has for finding a lesser match?)
+
+ attribs.clear();
+ makeAttribList(attribs, m_coreProfile, m_stereoVisual, 0, needAlpha, needStencil, softwareGL);
+ pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
+ }
+
+ if (pixelFormat == nil)
+ goto error;
+
+ if (m_numOfAASamples > 0) { //Set m_numOfAASamples to the actual value
+ GLint actualSamples;
+ [pixelFormat getValues:&actualSamples forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
+
+ if (m_numOfAASamples != (GHOST_TUns16)actualSamples) {
+ fprintf(
+ stderr,
+ "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
+ "Substituting one that uses %d samples.\n",
+ m_numOfAASamples,
+ actualSamples);
+
+ m_numOfAASamples = (GHOST_TUns16)actualSamples;
+ }
+ }
+
+ m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
+ shareContext:s_sharedOpenGLContext];
+ [pixelFormat release];
+
+ [m_openGLContext makeCurrentContext];
+
+ getVersion(&major, &minor);
+ if (m_debug) {
+ fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
+ fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
+ }
+
+ if (major < 2 || (major == 2 && minor < 1)) {
+ // fall back to software renderer if GL < 2.1
+ fprintf(stderr, "OpenGL 2.1 is not supported on your hardware, falling back to software");
+ softwareGL = true;
+
+ // discard hardware GL context
+ [NSOpenGLContext clearCurrentContext];
+ [m_openGLContext release];
+
+ // create software GL context
+ makeAttribList(attribs,
+ m_coreProfile,
+ m_stereoVisual,
+ m_numOfAASamples,
+ needAlpha,
+ needStencil,
+ softwareGL);
+ pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
+ m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
+ shareContext:s_sharedOpenGLContext];
+ [pixelFormat release];
+
+ [m_openGLContext makeCurrentContext];
+
+ getVersion(&major, &minor);
+ if (m_debug) {
+ fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
+ fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
+ }
+ }
#ifdef GHOST_MULTITHREADED_OPENGL
- //Switch openGL to multhreaded mode
- if (CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine) == kCGLNoError)
- if (m_debug)
- fprintf(stderr, "\nSwitched OpenGL to multithreaded mode\n");
+ //Switch openGL to multhreaded mode
+ if (CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine) == kCGLNoError)
+ if (m_debug)
+ fprintf(stderr, "\nSwitched OpenGL to multithreaded mode\n");
#endif
#ifdef GHOST_WAIT_FOR_VSYNC
- {
- GLint swapInt = 1;
- /* wait for vsync, to avoid tearing artifacts */
- [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
- }
+ {
+ GLint swapInt = 1;
+ /* wait for vsync, to avoid tearing artifacts */
+ [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
+ }
#endif
- initContextGLEW();
-
- if (m_openGLView) {
- [m_openGLView setOpenGLContext:m_openGLContext];
- [m_openGLContext setView:m_openGLView];
- }
+ initContextGLEW();
- if (s_sharedCount == 0)
- s_sharedOpenGLContext = m_openGLContext;
+ if (m_openGLView) {
+ [m_openGLView setOpenGLContext:m_openGLContext];
+ [m_openGLContext setView:m_openGLView];
+ }
- s_sharedCount++;
+ if (s_sharedCount == 0)
+ s_sharedOpenGLContext = m_openGLContext;
+ s_sharedCount++;
- initClearGL();
- [m_openGLContext flushBuffer];
+ initClearGL();
+ [m_openGLContext flushBuffer];
- [pool drain];
+ [pool drain];
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
error:
- if (m_openGLView) {
- [m_openGLView setOpenGLContext:prev_openGLContext];
- }
+ if (m_openGLView) {
+ [m_openGLView setOpenGLContext:prev_openGLContext];
+ }
- [pixelFormat release];
+ [pixelFormat release];
- [pool drain];
+ [pool drain];
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()
{
- m_openGLContext = NULL;
- m_openGLView = NULL;
+ m_openGLContext = NULL;
+ m_openGLView = NULL;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_ContextEGL.cpp b/intern/ghost/intern/GHOST_ContextEGL.cpp
index 0fc99c4c343..34df5f3119d 100644
--- a/intern/ghost/intern/GHOST_ContextEGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextEGL.cpp
@@ -33,183 +33,185 @@
#include <cstdio>
#include <cstring>
-
-#define CASE_CODE_RETURN_STR(code) case code: return #code;
+#define CASE_CODE_RETURN_STR(code) \
+ case code: \
+ return #code;
static const char *get_egl_error_enum_string(EGLenum error)
{
- switch (error) {
- CASE_CODE_RETURN_STR(EGL_SUCCESS)
- CASE_CODE_RETURN_STR(EGL_NOT_INITIALIZED)
- CASE_CODE_RETURN_STR(EGL_BAD_ACCESS)
- CASE_CODE_RETURN_STR(EGL_BAD_ALLOC)
- CASE_CODE_RETURN_STR(EGL_BAD_ATTRIBUTE)
- CASE_CODE_RETURN_STR(EGL_BAD_CONTEXT)
- CASE_CODE_RETURN_STR(EGL_BAD_CONFIG)
- CASE_CODE_RETURN_STR(EGL_BAD_CURRENT_SURFACE)
- CASE_CODE_RETURN_STR(EGL_BAD_DISPLAY)
- CASE_CODE_RETURN_STR(EGL_BAD_SURFACE)
- CASE_CODE_RETURN_STR(EGL_BAD_MATCH)
- CASE_CODE_RETURN_STR(EGL_BAD_PARAMETER)
- CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_PIXMAP)
- CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_WINDOW)
- CASE_CODE_RETURN_STR(EGL_CONTEXT_LOST)
- default:
- return NULL;
- }
+ switch (error) {
+ CASE_CODE_RETURN_STR(EGL_SUCCESS)
+ CASE_CODE_RETURN_STR(EGL_NOT_INITIALIZED)
+ CASE_CODE_RETURN_STR(EGL_BAD_ACCESS)
+ CASE_CODE_RETURN_STR(EGL_BAD_ALLOC)
+ CASE_CODE_RETURN_STR(EGL_BAD_ATTRIBUTE)
+ CASE_CODE_RETURN_STR(EGL_BAD_CONTEXT)
+ CASE_CODE_RETURN_STR(EGL_BAD_CONFIG)
+ CASE_CODE_RETURN_STR(EGL_BAD_CURRENT_SURFACE)
+ CASE_CODE_RETURN_STR(EGL_BAD_DISPLAY)
+ CASE_CODE_RETURN_STR(EGL_BAD_SURFACE)
+ CASE_CODE_RETURN_STR(EGL_BAD_MATCH)
+ CASE_CODE_RETURN_STR(EGL_BAD_PARAMETER)
+ CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_PIXMAP)
+ CASE_CODE_RETURN_STR(EGL_BAD_NATIVE_WINDOW)
+ CASE_CODE_RETURN_STR(EGL_CONTEXT_LOST)
+ default:
+ return NULL;
+ }
}
static const char *get_egl_error_message_string(EGLenum error)
{
- switch (error) {
- case EGL_SUCCESS:
- return "The last function succeeded without error.";
+ switch (error) {
+ case EGL_SUCCESS:
+ return "The last function succeeded without error.";
- case EGL_NOT_INITIALIZED:
- return ("EGL is not initialized, or could not be initialized, "
- "for the specified EGL display connection.");
+ case EGL_NOT_INITIALIZED:
+ return (
+ "EGL is not initialized, or could not be initialized, "
+ "for the specified EGL display connection.");
- case EGL_BAD_ACCESS:
- return ("EGL cannot access a requested resource "
- "(for example a context is bound in another thread).");
+ case EGL_BAD_ACCESS:
+ return (
+ "EGL cannot access a requested resource "
+ "(for example a context is bound in another thread).");
- case EGL_BAD_ALLOC:
- return "EGL failed to allocate resources for the requested operation.";
+ case EGL_BAD_ALLOC:
+ return "EGL failed to allocate resources for the requested operation.";
- case EGL_BAD_ATTRIBUTE:
- return "An unrecognized attribute or attribute value was passed in the attribute list.";
+ case EGL_BAD_ATTRIBUTE:
+ return "An unrecognized attribute or attribute value was passed in the attribute list.";
- case EGL_BAD_CONTEXT:
- return "An EGLContext argument does not name a valid EGL rendering context.";
+ case EGL_BAD_CONTEXT:
+ return "An EGLContext argument does not name a valid EGL rendering context.";
- case EGL_BAD_CONFIG:
- return "An EGLConfig argument does not name a valid EGL frame buffer configuration.";
+ case EGL_BAD_CONFIG:
+ return "An EGLConfig argument does not name a valid EGL frame buffer configuration.";
- case EGL_BAD_CURRENT_SURFACE:
- return ("The current surface of the calling thread is a window, "
- "pixel buffer or pixmap that is no longer valid.");
+ case EGL_BAD_CURRENT_SURFACE:
+ return (
+ "The current surface of the calling thread is a window, "
+ "pixel buffer or pixmap that is no longer valid.");
- case EGL_BAD_DISPLAY:
- return "An EGLDisplay argument does not name a valid EGL display connection.";
+ case EGL_BAD_DISPLAY:
+ return "An EGLDisplay argument does not name a valid EGL display connection.";
- case EGL_BAD_SURFACE:
- return ("An EGLSurface argument does not name a valid surface "
- "(window, pixel buffer or pixmap) configured for GL rendering.");
+ case EGL_BAD_SURFACE:
+ return (
+ "An EGLSurface argument does not name a valid surface "
+ "(window, pixel buffer or pixmap) configured for GL rendering.");
- case EGL_BAD_MATCH:
- return ("Arguments are inconsistent "
- "(for example, a valid context requires buffers not supplied by a valid surface).");
+ case EGL_BAD_MATCH:
+ return (
+ "Arguments are inconsistent "
+ "(for example, a valid context requires buffers not supplied by a valid surface).");
- case EGL_BAD_PARAMETER:
- return "One or more argument values are invalid.";
+ case EGL_BAD_PARAMETER:
+ return "One or more argument values are invalid.";
- case EGL_BAD_NATIVE_PIXMAP:
- return "A NativePixmapType argument does not refer to a valid native pixmap.";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "A NativePixmapType argument does not refer to a valid native pixmap.";
- case EGL_BAD_NATIVE_WINDOW:
- return "A NativeWindowType argument does not refer to a valid native window.";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "A NativeWindowType argument does not refer to a valid native window.";
- case EGL_CONTEXT_LOST:
- return ("A power management event has occurred. "
- "The application must destroy all contexts and reinitialise OpenGL ES state "
- "and objects to continue rendering.");
+ case EGL_CONTEXT_LOST:
+ return (
+ "A power management event has occurred. "
+ "The application must destroy all contexts and reinitialise OpenGL ES state "
+ "and objects to continue rendering.");
- default:
- return NULL;
- }
+ default:
+ return NULL;
+ }
}
-
static bool egl_chk(bool result, const char *file = NULL, int line = 0, const char *text = NULL)
{
- if (!result) {
- EGLenum error = eglGetError();
+ if (!result) {
+ EGLenum error = eglGetError();
- const char *code = get_egl_error_enum_string(error);
- const char *msg = get_egl_error_message_string(error);
+ const char *code = get_egl_error_enum_string(error);
+ const char *msg = get_egl_error_message_string(error);
#ifndef NDEBUG
- fprintf(stderr,
- "%s(%d):[%s] -> EGL Error (0x%04X): %s: %s\n",
- file, line, text, error,
- code ? code : "<Unknown>",
- msg ? msg : "<Unknown>");
+ fprintf(stderr,
+ "%s(%d):[%s] -> EGL Error (0x%04X): %s: %s\n",
+ file,
+ line,
+ text,
+ error,
+ code ? code : "<Unknown>",
+ msg ? msg : "<Unknown>");
#else
- fprintf(stderr,
- "EGL Error (0x%04X): %s: %s\n",
- error,
- code ? code : "<Unknown>",
- msg ? msg : "<Unknown>");
+ fprintf(stderr,
+ "EGL Error (0x%04X): %s: %s\n",
+ error,
+ code ? code : "<Unknown>",
+ msg ? msg : "<Unknown>");
#endif
- }
+ }
- return result;
+ return result;
}
#ifndef NDEBUG
-#define EGL_CHK(x) egl_chk((x), __FILE__, __LINE__, #x)
+# define EGL_CHK(x) egl_chk((x), __FILE__, __LINE__, # x)
#else
-#define EGL_CHK(x) egl_chk(x)
+# define EGL_CHK(x) egl_chk(x)
#endif
-
static inline bool bindAPI(EGLenum api)
{
- if (EGLEW_VERSION_1_2) {
- return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE);
- }
+ if (EGLEW_VERSION_1_2) {
+ return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE);
+ }
- return false;
+ return false;
}
-
#ifdef WITH_GL_ANGLE
HMODULE GHOST_ContextEGL::s_d3dcompiler = NULL;
#endif
-
-EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT;
-EGLint GHOST_ContextEGL::s_gl_sharedCount = 0;
+EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT;
+EGLint GHOST_ContextEGL::s_gl_sharedCount = 0;
EGLContext GHOST_ContextEGL::s_gles_sharedContext = EGL_NO_CONTEXT;
-EGLint GHOST_ContextEGL::s_gles_sharedCount = 0;
-
-EGLContext GHOST_ContextEGL::s_vg_sharedContext = EGL_NO_CONTEXT;
-EGLint GHOST_ContextEGL::s_vg_sharedCount = 0;
+EGLint GHOST_ContextEGL::s_gles_sharedCount = 0;
+EGLContext GHOST_ContextEGL::s_vg_sharedContext = EGL_NO_CONTEXT;
+EGLint GHOST_ContextEGL::s_vg_sharedCount = 0;
#pragma warning(disable : 4715)
-template <typename T>
-T &choose_api(EGLenum api, T &a, T &b, T &c)
+template<typename T> T &choose_api(EGLenum api, T &a, T &b, T &c)
{
- switch (api) {
- case EGL_OPENGL_API:
- return a;
- case EGL_OPENGL_ES_API:
- return b;
- case EGL_OPENVG_API:
- return c;
- default:
- abort();
- }
+ switch (api) {
+ case EGL_OPENGL_API:
+ return a;
+ case EGL_OPENGL_ES_API:
+ return b;
+ case EGL_OPENVG_API:
+ return c;
+ default:
+ abort();
+ }
}
-
-GHOST_ContextEGL::GHOST_ContextEGL(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- EGLNativeWindowType nativeWindow,
- EGLNativeDisplayType nativeDisplay,
- EGLint contextProfileMask,
- EGLint contextMajorVersion,
- EGLint contextMinorVersion,
- EGLint contextFlags,
- EGLint contextResetNotificationStrategy,
- EGLenum api)
+GHOST_ContextEGL::GHOST_ContextEGL(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ EGLNativeWindowType nativeWindow,
+ EGLNativeDisplayType nativeDisplay,
+ EGLint contextProfileMask,
+ EGLint contextMajorVersion,
+ EGLint contextMinorVersion,
+ EGLint contextFlags,
+ EGLint contextResetNotificationStrategy,
+ EGLenum api)
: GHOST_Context(stereoVisual, numOfAASamples),
m_nativeDisplay(nativeDisplay),
- m_nativeWindow (nativeWindow),
+ m_nativeWindow(nativeWindow),
m_contextProfileMask(contextProfileMask),
m_contextMajorVersion(contextMajorVersion),
m_contextMinorVersion(contextMinorVersion),
@@ -220,395 +222,395 @@ GHOST_ContextEGL::GHOST_ContextEGL(
m_surface(EGL_NO_SURFACE),
m_display(EGL_NO_DISPLAY),
m_swap_interval(1),
- m_sharedContext(choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)),
- m_sharedCount (choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount))
+ m_sharedContext(
+ choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)),
+ m_sharedCount(choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount))
{
- assert(m_nativeWindow != 0);
- assert(m_nativeDisplay != NULL);
+ assert(m_nativeWindow != 0);
+ assert(m_nativeDisplay != NULL);
}
-
GHOST_ContextEGL::~GHOST_ContextEGL()
{
- if (m_display != EGL_NO_DISPLAY) {
+ if (m_display != EGL_NO_DISPLAY) {
- bindAPI(m_api);
+ bindAPI(m_api);
- if (m_context != EGL_NO_CONTEXT) {
- if (m_context == ::eglGetCurrentContext())
- EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+ if (m_context != EGL_NO_CONTEXT) {
+ if (m_context == ::eglGetCurrentContext())
+ EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
- if (m_context != m_sharedContext || m_sharedCount == 1) {
- assert(m_sharedCount > 0);
+ if (m_context != m_sharedContext || m_sharedCount == 1) {
+ assert(m_sharedCount > 0);
- m_sharedCount--;
+ m_sharedCount--;
- if (m_sharedCount == 0)
- m_sharedContext = EGL_NO_CONTEXT;
+ if (m_sharedCount == 0)
+ m_sharedContext = EGL_NO_CONTEXT;
- EGL_CHK(::eglDestroyContext(m_display, m_context));
- }
- }
+ EGL_CHK(::eglDestroyContext(m_display, m_context));
+ }
+ }
- if (m_surface != EGL_NO_SURFACE)
- EGL_CHK(::eglDestroySurface(m_display, m_surface));
+ if (m_surface != EGL_NO_SURFACE)
+ EGL_CHK(::eglDestroySurface(m_display, m_surface));
- EGL_CHK(::eglTerminate(m_display));
- }
+ EGL_CHK(::eglTerminate(m_display));
+ }
}
-
GHOST_TSuccess GHOST_ContextEGL::swapBuffers()
{
- return EGL_CHK(::eglSwapBuffers(m_display, m_surface)) ? GHOST_kSuccess : GHOST_kFailure;
+ return EGL_CHK(::eglSwapBuffers(m_display, m_surface)) ? GHOST_kSuccess : GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_ContextEGL::setSwapInterval(int interval)
{
- if (EGLEW_VERSION_1_1) {
- if (EGL_CHK(::eglSwapInterval(m_display, interval))) {
- m_swap_interval = interval;
-
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
- }
- else {
- return GHOST_kFailure;
- }
+ if (EGLEW_VERSION_1_1) {
+ if (EGL_CHK(::eglSwapInterval(m_display, interval))) {
+ m_swap_interval = interval;
+
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextEGL::getSwapInterval(int &intervalOut)
{
- // This is a bit of a kludge because there does not seem to
- // be a way to query the swap interval with EGL.
- intervalOut = m_swap_interval;
+ // This is a bit of a kludge because there does not seem to
+ // be a way to query the swap interval with EGL.
+ intervalOut = m_swap_interval;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext()
{
- if (m_display) {
- bindAPI(m_api);
-
- return EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)) ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_display) {
+ bindAPI(m_api);
+
+ return EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)) ? GHOST_kSuccess :
+ GHOST_kFailure;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
GHOST_TSuccess GHOST_ContextEGL::releaseDrawingContext()
{
- if (m_display) {
- bindAPI(m_api);
-
- return EGL_CHK(::eglMakeCurrent(m_display, None, None, NULL)) ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_display) {
+ bindAPI(m_api);
+
+ return EGL_CHK(::eglMakeCurrent(m_display, None, None, NULL)) ? GHOST_kSuccess :
+ GHOST_kFailure;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
void GHOST_ContextEGL::initContextEGLEW()
{
- if (GLEW_CHK(eglewInit(m_display)) != GLEW_OK)
- fprintf(stderr, "Warning! EGLEW failed to initialize properly.\n");
+ if (GLEW_CHK(eglewInit(m_display)) != GLEW_OK)
+ fprintf(stderr, "Warning! EGLEW failed to initialize properly.\n");
}
-
static const std::string &api_string(EGLenum api)
{
- static const std::string a("OpenGL");
- static const std::string b("OpenGL ES");
- static const std::string c("OpenVG");
+ static const std::string a("OpenGL");
+ static const std::string b("OpenGL ES");
+ static const std::string c("OpenVG");
- return choose_api(api, a, b, c);
+ return choose_api(api, a, b, c);
}
GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
{
- // objects have to be declared here due to the use of goto
- std::vector<EGLint> attrib_list;
- EGLint num_config = 0;
+ // objects have to be declared here due to the use of goto
+ std::vector<EGLint> attrib_list;
+ EGLint num_config = 0;
- if (m_stereoVisual)
- fprintf(stderr, "Warning! Stereo OpenGL ES contexts are not supported.\n");
+ if (m_stereoVisual)
+ fprintf(stderr, "Warning! Stereo OpenGL ES contexts are not supported.\n");
- m_stereoVisual = false; // It doesn't matter what the Window wants.
+ m_stereoVisual = false; // It doesn't matter what the Window wants.
#ifdef WITH_GL_ANGLE
- // d3dcompiler_XX.dll needs to be loaded before ANGLE will work
- if (s_d3dcompiler == NULL) {
- s_d3dcompiler = LoadLibrary(D3DCOMPILER);
+ // d3dcompiler_XX.dll needs to be loaded before ANGLE will work
+ if (s_d3dcompiler == NULL) {
+ s_d3dcompiler = LoadLibrary(D3DCOMPILER);
- WIN32_CHK(s_d3dcompiler != NULL);
+ WIN32_CHK(s_d3dcompiler != NULL);
- if (s_d3dcompiler == NULL) {
- fprintf(stderr, "LoadLibrary(\"" D3DCOMPILER "\") failed!\n");
- return GHOST_kFailure;
- }
- }
+ if (s_d3dcompiler == NULL) {
+ fprintf(stderr, "LoadLibrary(\"" D3DCOMPILER "\") failed!\n");
+ return GHOST_kFailure;
+ }
+ }
#endif
- EGLDisplay prev_display = eglGetCurrentDisplay();
- EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW);
- EGLSurface prev_read = eglGetCurrentSurface(EGL_READ);
- EGLContext prev_context = eglGetCurrentContext();
-
- m_display = ::eglGetDisplay(m_nativeDisplay);
+ EGLDisplay prev_display = eglGetCurrentDisplay();
+ EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW);
+ EGLSurface prev_read = eglGetCurrentSurface(EGL_READ);
+ EGLContext prev_context = eglGetCurrentContext();
- if (!EGL_CHK(m_display != EGL_NO_DISPLAY))
- return GHOST_kFailure;
+ m_display = ::eglGetDisplay(m_nativeDisplay);
- EGLint egl_major, egl_minor;
+ if (!EGL_CHK(m_display != EGL_NO_DISPLAY))
+ return GHOST_kFailure;
- if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor)))
- goto error;
+ EGLint egl_major, egl_minor;
- fprintf(stderr, "EGL Version %d.%d\n", egl_major, egl_minor);
+ if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor)))
+ goto error;
- if (!EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)))
- goto error;
+ fprintf(stderr, "EGL Version %d.%d\n", egl_major, egl_minor);
- initContextEGLEW();
+ if (!EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)))
+ goto error;
- if (!bindAPI(m_api))
- goto error;
+ initContextEGLEW();
+ if (!bindAPI(m_api))
+ goto error;
- // build attribute list
+ // build attribute list
- attrib_list.reserve(20);
+ attrib_list.reserve(20);
- if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) {
- // According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE,
- // but some implementations (ANGLE) do not seem to care.
+ if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) {
+ // According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE,
+ // but some implementations (ANGLE) do not seem to care.
- if (m_contextMajorVersion == 1) {
- attrib_list.push_back(EGL_RENDERABLE_TYPE);
- attrib_list.push_back(EGL_OPENGL_ES_BIT);
- }
- else if (m_contextMajorVersion == 2) {
- attrib_list.push_back(EGL_RENDERABLE_TYPE);
- attrib_list.push_back(EGL_OPENGL_ES2_BIT);
- }
- else if (m_contextMajorVersion == 3) {
- attrib_list.push_back(EGL_RENDERABLE_TYPE);
- attrib_list.push_back(EGL_OPENGL_ES3_BIT_KHR);
- }
- else {
- fprintf(stderr,
- "Warning! Unable to request an ES context of version %d.%d\n",
- m_contextMajorVersion, m_contextMinorVersion);
- }
+ if (m_contextMajorVersion == 1) {
+ attrib_list.push_back(EGL_RENDERABLE_TYPE);
+ attrib_list.push_back(EGL_OPENGL_ES_BIT);
+ }
+ else if (m_contextMajorVersion == 2) {
+ attrib_list.push_back(EGL_RENDERABLE_TYPE);
+ attrib_list.push_back(EGL_OPENGL_ES2_BIT);
+ }
+ else if (m_contextMajorVersion == 3) {
+ attrib_list.push_back(EGL_RENDERABLE_TYPE);
+ attrib_list.push_back(EGL_OPENGL_ES3_BIT_KHR);
+ }
+ else {
+ fprintf(stderr,
+ "Warning! Unable to request an ES context of version %d.%d\n",
+ m_contextMajorVersion,
+ m_contextMinorVersion);
+ }
- if (!((m_contextMajorVersion == 1) ||
- (m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) ||
- (m_contextMajorVersion == 3 && /*EGLEW_VERSION_1_4 &&*/ EGLEW_KHR_create_context) ||
- (m_contextMajorVersion == 3 && EGLEW_VERSION_1_5)))
- {
- fprintf(stderr,
- "Warning! May not be able to create a version %d.%d ES context with version %d.%d of EGL\n",
- m_contextMajorVersion, m_contextMinorVersion, egl_major, egl_minor);
- }
- }
+ if (!((m_contextMajorVersion == 1) || (m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) ||
+ (m_contextMajorVersion == 3 && /*EGLEW_VERSION_1_4 &&*/ EGLEW_KHR_create_context) ||
+ (m_contextMajorVersion == 3 && EGLEW_VERSION_1_5))) {
+ fprintf(stderr,
+ "Warning! May not be able to create a version %d.%d ES context with version %d.%d "
+ "of EGL\n",
+ m_contextMajorVersion,
+ m_contextMinorVersion,
+ egl_major,
+ egl_minor);
+ }
+ }
- attrib_list.push_back(EGL_RED_SIZE);
- attrib_list.push_back(8);
+ attrib_list.push_back(EGL_RED_SIZE);
+ attrib_list.push_back(8);
- attrib_list.push_back(EGL_GREEN_SIZE);
- attrib_list.push_back(8);
+ attrib_list.push_back(EGL_GREEN_SIZE);
+ attrib_list.push_back(8);
- attrib_list.push_back(EGL_BLUE_SIZE);
- attrib_list.push_back(8);
+ attrib_list.push_back(EGL_BLUE_SIZE);
+ attrib_list.push_back(8);
#ifdef GHOST_OPENGL_ALPHA
- attrib_list.push_back(EGL_ALPHA_SIZE);
- attrib_list.push_back(8);
+ attrib_list.push_back(EGL_ALPHA_SIZE);
+ attrib_list.push_back(8);
#endif
- attrib_list.push_back(EGL_DEPTH_SIZE);
- attrib_list.push_back(24);
+ attrib_list.push_back(EGL_DEPTH_SIZE);
+ attrib_list.push_back(24);
#ifdef GHOST_OPENGL_STENCIL
- attrib_list.push_back(EGL_STENCIL_SIZE);
- attrib_list.push_back(8);
+ attrib_list.push_back(EGL_STENCIL_SIZE);
+ attrib_list.push_back(8);
#endif
- if (m_numOfAASamples > 0) {
- attrib_list.push_back(EGL_SAMPLE_BUFFERS);
- attrib_list.push_back(1);
-
- attrib_list.push_back(EGL_SAMPLES);
- attrib_list.push_back(m_numOfAASamples);
- }
-
- attrib_list.push_back(EGL_NONE);
-
- EGLConfig config;
-
- if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config)))
- goto error;
-
- // A common error is to assume that ChooseConfig worked because it returned EGL_TRUE
- if (num_config != 1) // num_config should be exactly 1
- goto error;
-
- if (m_numOfAASamples > 0) {
- EGLint actualSamples;
-
- if (!EGL_CHK(::eglGetConfigAttrib(m_display, config, EGL_SAMPLE_BUFFERS, &actualSamples)))
- goto error;
-
- if (m_numOfAASamples != actualSamples) {
- fprintf(stderr,
- "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
- "Substituting one that uses %d samples.\n",
- m_numOfAASamples,
- actualSamples);
-
- m_numOfAASamples = (GHOST_TUns16)actualSamples;
- }
- }
-
- m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow, NULL);
-
- if (!EGL_CHK(m_surface != EGL_NO_SURFACE))
- goto error;
-
- attrib_list.clear();
-
- if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) {
- if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) {
- if (m_contextMajorVersion != 0) {
- attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
- attrib_list.push_back(m_contextMajorVersion);
- }
-
- if (m_contextMinorVersion != 0) {
- attrib_list.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
- attrib_list.push_back(m_contextMinorVersion);
- }
-
- if (m_contextFlags != 0) {
- attrib_list.push_back(EGL_CONTEXT_FLAGS_KHR);
- attrib_list.push_back(m_contextFlags);
- }
- }
- else {
- if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
- fprintf(stderr,
- "Warning! Cannot request specific versions of %s contexts.",
- api_string(m_api).c_str());
- }
-
- if (m_contextFlags != 0) {
- fprintf(stderr,
- "Warning! Flags cannot be set on %s contexts.",
- api_string(m_api).c_str());
- }
- }
-
- if (m_api == EGL_OPENGL_API) {
- if (m_contextProfileMask != 0) {
- attrib_list.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
- attrib_list.push_back(m_contextProfileMask);
- }
- }
- else {
- if (m_contextProfileMask != 0)
- fprintf(stderr,
- "Warning! Cannot select profile for %s contexts.",
- api_string(m_api).c_str());
- }
-
- if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) {
- if (m_contextResetNotificationStrategy != 0) {
- attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
- attrib_list.push_back(m_contextResetNotificationStrategy);
- }
- }
- else {
- if (m_contextResetNotificationStrategy != 0) {
- fprintf(stderr,
- "Warning! EGL %d.%d cannot set the reset notification strategy on %s contexts.",
- egl_major, egl_minor, api_string(m_api).c_str());
- }
- }
- }
- else {
- if (m_api == EGL_OPENGL_ES_API) {
- if (m_contextMajorVersion != 0) {
- attrib_list.push_back(EGL_CONTEXT_CLIENT_VERSION);
- attrib_list.push_back(m_contextMajorVersion);
- }
- }
- else {
- if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
- fprintf(stderr,
- "Warning! EGL %d.%d is unable to select between versions of %s.",
- egl_major, egl_minor, api_string(m_api).c_str());
- }
- }
-
- if (m_contextFlags != 0) {
- fprintf(stderr,
- "Warning! EGL %d.%d is unable to set context flags.",
- egl_major, egl_minor);
- }
- if (m_contextProfileMask != 0) {
- fprintf(stderr,
- "Warning! EGL %d.%d is unable to select between profiles.",
- egl_major, egl_minor);
- }
- if (m_contextResetNotificationStrategy != 0) {
- fprintf(stderr,
- "Warning! EGL %d.%d is unable to set the reset notification strategies.",
- egl_major, egl_minor);
- }
- }
-
- attrib_list.push_back(EGL_NONE);
-
- m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0]));
-
- if (!EGL_CHK(m_context != EGL_NO_CONTEXT))
- goto error;
-
- if (m_sharedContext == EGL_NO_CONTEXT)
- m_sharedContext = m_context;
-
- m_sharedCount++;
-
- if (!EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)))
- goto error;
-
- initContextGLEW();
-
- initClearGL();
- ::eglSwapBuffers(m_display, m_surface);
-
- return GHOST_kSuccess;
+ if (m_numOfAASamples > 0) {
+ attrib_list.push_back(EGL_SAMPLE_BUFFERS);
+ attrib_list.push_back(1);
+
+ attrib_list.push_back(EGL_SAMPLES);
+ attrib_list.push_back(m_numOfAASamples);
+ }
+
+ attrib_list.push_back(EGL_NONE);
+
+ EGLConfig config;
+
+ if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config)))
+ goto error;
+
+ // A common error is to assume that ChooseConfig worked because it returned EGL_TRUE
+ if (num_config != 1) // num_config should be exactly 1
+ goto error;
+
+ if (m_numOfAASamples > 0) {
+ EGLint actualSamples;
+
+ if (!EGL_CHK(::eglGetConfigAttrib(m_display, config, EGL_SAMPLE_BUFFERS, &actualSamples)))
+ goto error;
+
+ if (m_numOfAASamples != actualSamples) {
+ fprintf(
+ stderr,
+ "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
+ "Substituting one that uses %d samples.\n",
+ m_numOfAASamples,
+ actualSamples);
+
+ m_numOfAASamples = (GHOST_TUns16)actualSamples;
+ }
+ }
+
+ m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow, NULL);
+
+ if (!EGL_CHK(m_surface != EGL_NO_SURFACE))
+ goto error;
+
+ attrib_list.clear();
+
+ if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) {
+ if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) {
+ if (m_contextMajorVersion != 0) {
+ attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
+ attrib_list.push_back(m_contextMajorVersion);
+ }
+
+ if (m_contextMinorVersion != 0) {
+ attrib_list.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
+ attrib_list.push_back(m_contextMinorVersion);
+ }
+
+ if (m_contextFlags != 0) {
+ attrib_list.push_back(EGL_CONTEXT_FLAGS_KHR);
+ attrib_list.push_back(m_contextFlags);
+ }
+ }
+ else {
+ if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
+ fprintf(stderr,
+ "Warning! Cannot request specific versions of %s contexts.",
+ api_string(m_api).c_str());
+ }
+
+ if (m_contextFlags != 0) {
+ fprintf(stderr, "Warning! Flags cannot be set on %s contexts.", api_string(m_api).c_str());
+ }
+ }
+
+ if (m_api == EGL_OPENGL_API) {
+ if (m_contextProfileMask != 0) {
+ attrib_list.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
+ attrib_list.push_back(m_contextProfileMask);
+ }
+ }
+ else {
+ if (m_contextProfileMask != 0)
+ fprintf(
+ stderr, "Warning! Cannot select profile for %s contexts.", api_string(m_api).c_str());
+ }
+
+ if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) {
+ if (m_contextResetNotificationStrategy != 0) {
+ attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
+ attrib_list.push_back(m_contextResetNotificationStrategy);
+ }
+ }
+ else {
+ if (m_contextResetNotificationStrategy != 0) {
+ fprintf(stderr,
+ "Warning! EGL %d.%d cannot set the reset notification strategy on %s contexts.",
+ egl_major,
+ egl_minor,
+ api_string(m_api).c_str());
+ }
+ }
+ }
+ else {
+ if (m_api == EGL_OPENGL_ES_API) {
+ if (m_contextMajorVersion != 0) {
+ attrib_list.push_back(EGL_CONTEXT_CLIENT_VERSION);
+ attrib_list.push_back(m_contextMajorVersion);
+ }
+ }
+ else {
+ if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
+ fprintf(stderr,
+ "Warning! EGL %d.%d is unable to select between versions of %s.",
+ egl_major,
+ egl_minor,
+ api_string(m_api).c_str());
+ }
+ }
+
+ if (m_contextFlags != 0) {
+ fprintf(stderr, "Warning! EGL %d.%d is unable to set context flags.", egl_major, egl_minor);
+ }
+ if (m_contextProfileMask != 0) {
+ fprintf(stderr,
+ "Warning! EGL %d.%d is unable to select between profiles.",
+ egl_major,
+ egl_minor);
+ }
+ if (m_contextResetNotificationStrategy != 0) {
+ fprintf(stderr,
+ "Warning! EGL %d.%d is unable to set the reset notification strategies.",
+ egl_major,
+ egl_minor);
+ }
+ }
+
+ attrib_list.push_back(EGL_NONE);
+
+ m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0]));
+
+ if (!EGL_CHK(m_context != EGL_NO_CONTEXT))
+ goto error;
+
+ if (m_sharedContext == EGL_NO_CONTEXT)
+ m_sharedContext = m_context;
+
+ m_sharedCount++;
+
+ if (!EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)))
+ goto error;
+
+ initContextGLEW();
+
+ initClearGL();
+ ::eglSwapBuffers(m_display, m_surface);
+
+ return GHOST_kSuccess;
error:
- if (prev_display != EGL_NO_DISPLAY)
- EGL_CHK(eglMakeCurrent(prev_display, prev_draw, prev_read, prev_context));
+ if (prev_display != EGL_NO_DISPLAY)
+ EGL_CHK(eglMakeCurrent(prev_display, prev_draw, prev_read, prev_context));
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_ContextEGL::releaseNativeHandles()
{
- m_nativeWindow = 0;
- m_nativeDisplay = NULL;
+ m_nativeWindow = 0;
+ m_nativeDisplay = NULL;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_ContextEGL.h b/intern/ghost/intern/GHOST_ContextEGL.h
index cced618ac7e..0a759493e4d 100644
--- a/intern/ghost/intern/GHOST_ContextEGL.h
+++ b/intern/ghost/intern/GHOST_ContextEGL.h
@@ -29,117 +29,114 @@
#include <GL/eglew.h>
#ifndef GHOST_OPENGL_EGL_CONTEXT_FLAGS
-#define GHOST_OPENGL_EGL_CONTEXT_FLAGS 0
+# define GHOST_OPENGL_EGL_CONTEXT_FLAGS 0
#endif
#ifndef GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY
-#define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY 0
+# define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY 0
#endif
-
-class GHOST_ContextEGL : public GHOST_Context
-{
-public:
- /**
- * Constructor.
- */
- GHOST_ContextEGL(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- EGLNativeWindowType nativeWindow,
- EGLNativeDisplayType nativeDisplay,
- EGLint contextProfileMask,
- EGLint contextMajorVersion,
- EGLint contextMinorVersion,
- EGLint contextFlags,
- EGLint contextResetNotificationStrategy,
- EGLenum api);
-
- /**
- * Destructor.
- */
- ~GHOST_ContextEGL();
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess swapBuffers();
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess activateDrawingContext();
-
- /**
- * Release the drawing context of the calling thread.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess releaseDrawingContext();
-
- /**
- * Call immediately after new to initialize. If this fails then immediately delete the object.
- * \return Indication as to whether initialization has succeeded.
- */
- GHOST_TSuccess initializeDrawingContext();
-
- /**
- * Removes references to native handles from this context and then returns
- * \return GHOST_kSuccess if it is OK for the parent to release the handles and
- * GHOST_kFailure if releasing the handles will interfere with sharing
- */
- GHOST_TSuccess releaseNativeHandles();
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess setSwapInterval(int interval);
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \param intervalOut Variable to store the swap interval if it can be read.
- * \return Whether the swap interval can be read.
- */
- GHOST_TSuccess getSwapInterval(int &intervalOut);
-
-private:
- void initContextEGLEW();
-
- EGLNativeDisplayType m_nativeDisplay;
- EGLNativeWindowType m_nativeWindow;
-
- const EGLint m_contextProfileMask;
- const EGLint m_contextMajorVersion;
- const EGLint m_contextMinorVersion;
- const EGLint m_contextFlags;
- const EGLint m_contextResetNotificationStrategy;
-
- const EGLenum m_api;
-
- EGLContext m_context;
- EGLSurface m_surface;
- EGLDisplay m_display;
-
- EGLint m_swap_interval;
-
- EGLContext &m_sharedContext;
- EGLint &m_sharedCount;
-
- static EGLContext s_gl_sharedContext;
- static EGLint s_gl_sharedCount;
-
- static EGLContext s_gles_sharedContext;
- static EGLint s_gles_sharedCount;
-
- static EGLContext s_vg_sharedContext;
- static EGLint s_vg_sharedCount;
+class GHOST_ContextEGL : public GHOST_Context {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_ContextEGL(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ EGLNativeWindowType nativeWindow,
+ EGLNativeDisplayType nativeDisplay,
+ EGLint contextProfileMask,
+ EGLint contextMajorVersion,
+ EGLint contextMinorVersion,
+ EGLint contextFlags,
+ EGLint contextResetNotificationStrategy,
+ EGLenum api);
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_ContextEGL();
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess swapBuffers();
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess activateDrawingContext();
+
+ /**
+ * Release the drawing context of the calling thread.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess releaseDrawingContext();
+
+ /**
+ * Call immediately after new to initialize. If this fails then immediately delete the object.
+ * \return Indication as to whether initialization has succeeded.
+ */
+ GHOST_TSuccess initializeDrawingContext();
+
+ /**
+ * Removes references to native handles from this context and then returns
+ * \return GHOST_kSuccess if it is OK for the parent to release the handles and
+ * GHOST_kFailure if releasing the handles will interfere with sharing
+ */
+ GHOST_TSuccess releaseNativeHandles();
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess setSwapInterval(int interval);
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \param intervalOut Variable to store the swap interval if it can be read.
+ * \return Whether the swap interval can be read.
+ */
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
+
+ private:
+ void initContextEGLEW();
+
+ EGLNativeDisplayType m_nativeDisplay;
+ EGLNativeWindowType m_nativeWindow;
+
+ const EGLint m_contextProfileMask;
+ const EGLint m_contextMajorVersion;
+ const EGLint m_contextMinorVersion;
+ const EGLint m_contextFlags;
+ const EGLint m_contextResetNotificationStrategy;
+
+ const EGLenum m_api;
+
+ EGLContext m_context;
+ EGLSurface m_surface;
+ EGLDisplay m_display;
+
+ EGLint m_swap_interval;
+
+ EGLContext &m_sharedContext;
+ EGLint &m_sharedCount;
+
+ static EGLContext s_gl_sharedContext;
+ static EGLint s_gl_sharedCount;
+
+ static EGLContext s_gles_sharedContext;
+ static EGLint s_gles_sharedCount;
+
+ static EGLContext s_vg_sharedContext;
+ static EGLint s_vg_sharedCount;
#ifdef WITH_GL_ANGLE
- static HMODULE s_d3dcompiler;
+ static HMODULE s_d3dcompiler;
#endif
};
-#endif // __GHOST_CONTEXTEGL_H__
+#endif // __GHOST_CONTEXTEGL_H__
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index bbf82c188bc..6a5126d59b8 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -41,20 +41,18 @@ static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, co
#endif
GLXContext GHOST_ContextGLX::s_sharedContext = None;
-int GHOST_ContextGLX::s_sharedCount = 0;
-
-
-GHOST_ContextGLX::GHOST_ContextGLX(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- Window window,
- Display *display,
- GLXFBConfig fbconfig,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy)
+int GHOST_ContextGLX::s_sharedCount = 0;
+
+GHOST_ContextGLX::GHOST_ContextGLX(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ Window window,
+ Display *display,
+ GLXFBConfig fbconfig,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
m_display(display),
m_fbconfig(fbconfig),
@@ -66,312 +64,301 @@ GHOST_ContextGLX::GHOST_ContextGLX(
m_contextResetNotificationStrategy(contextResetNotificationStrategy),
m_context(None)
{
- assert(m_display != NULL);
+ assert(m_display != NULL);
}
-
GHOST_ContextGLX::~GHOST_ContextGLX()
{
- if (m_display != NULL) {
- if (m_context != None) {
- if (m_window != 0 && m_context == ::glXGetCurrentContext())
- ::glXMakeCurrent(m_display, None, NULL);
+ if (m_display != NULL) {
+ if (m_context != None) {
+ if (m_window != 0 && m_context == ::glXGetCurrentContext())
+ ::glXMakeCurrent(m_display, None, NULL);
- if (m_context != s_sharedContext || s_sharedCount == 1) {
- assert(s_sharedCount > 0);
+ if (m_context != s_sharedContext || s_sharedCount == 1) {
+ assert(s_sharedCount > 0);
- s_sharedCount--;
+ s_sharedCount--;
- if (s_sharedCount == 0)
- s_sharedContext = NULL;
+ if (s_sharedCount == 0)
+ s_sharedContext = NULL;
- ::glXDestroyContext(m_display, m_context);
- }
- }
- }
+ ::glXDestroyContext(m_display, m_context);
+ }
+ }
+ }
}
-
GHOST_TSuccess GHOST_ContextGLX::swapBuffers()
{
- ::glXSwapBuffers(m_display, m_window);
+ ::glXSwapBuffers(m_display, m_window);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextGLX::activateDrawingContext()
{
- if (m_display) {
- return ::glXMakeCurrent(m_display, m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_display) {
+ return ::glXMakeCurrent(m_display, m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
GHOST_TSuccess GHOST_ContextGLX::releaseDrawingContext()
{
- if (m_display) {
- return ::glXMakeCurrent(m_display, None, NULL) ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_display) {
+ return ::glXMakeCurrent(m_display, None, NULL) ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
void GHOST_ContextGLX::initContextGLXEW()
{
- initContextGLEW();
+ initContextGLEW();
}
GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
{
- GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
+ GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
- /* -------------------------------------------------------------------- */
- /* Begin Inline Glew */
+ /* -------------------------------------------------------------------- */
+ /* Begin Inline Glew */
#ifdef USE_GLXEW_INIT_WORKAROUND
- const GLubyte *extStart = (GLubyte *)"";
- const GLubyte *extEnd;
- if (glXQueryExtension(m_display, NULL, NULL)) {
- extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS);
- if ((extStart == NULL) ||
- (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB(
- (const GLubyte *)"glXChooseFBConfig")) == NULL ||
- (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB(
- (const GLubyte *)"glXCreateContextAttribsARB")) == NULL ||
- (glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glXGetProcAddressARB(
- (const GLubyte *)"glXCreatePbuffer")) == NULL)
- {
- extStart = (GLubyte *)"";
- }
- }
- extEnd = extStart + _glewStrLen(extStart);
-
-#undef GLXEW_ARB_create_context
- const bool GLXEW_ARB_create_context =
- _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd);
-#undef GLXEW_ARB_create_context_profile
- const bool GLXEW_ARB_create_context_profile =
- _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd);
-#undef GLXEW_ARB_create_context_robustness
-const bool GLXEW_ARB_create_context_robustness =
- _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd);
-#ifdef WITH_GLEW_ES
-#undef GLXEW_EXT_create_context_es_profile
- const bool GLXEW_EXT_create_context_es_profile =
- _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd);
-#undef GLXEW_EXT_create_context_es2_profile
- const bool GLXEW_EXT_create_context_es2_profile =
- _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd);
-#endif /* WITH_GLEW_ES */
-
- /* End Inline Glew */
- /* -------------------------------------------------------------------- */
+ const GLubyte *extStart = (GLubyte *)"";
+ const GLubyte *extEnd;
+ if (glXQueryExtension(m_display, NULL, NULL)) {
+ extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS);
+ if ((extStart == NULL) ||
+ (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB(
+ (const GLubyte *)"glXChooseFBConfig")) == NULL ||
+ (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB(
+ (const GLubyte *)"glXCreateContextAttribsARB")) == NULL ||
+ (glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glXGetProcAddressARB(
+ (const GLubyte *)"glXCreatePbuffer")) == NULL) {
+ extStart = (GLubyte *)"";
+ }
+ }
+ extEnd = extStart + _glewStrLen(extStart);
+
+# undef GLXEW_ARB_create_context
+ const bool GLXEW_ARB_create_context = _glewSearchExtension(
+ "GLX_ARB_create_context", extStart, extEnd);
+# undef GLXEW_ARB_create_context_profile
+ const bool GLXEW_ARB_create_context_profile = _glewSearchExtension(
+ "GLX_ARB_create_context_profile", extStart, extEnd);
+# undef GLXEW_ARB_create_context_robustness
+ const bool GLXEW_ARB_create_context_robustness = _glewSearchExtension(
+ "GLX_ARB_create_context_robustness", extStart, extEnd);
+# ifdef WITH_GLEW_ES
+# undef GLXEW_EXT_create_context_es_profile
+ const bool GLXEW_EXT_create_context_es_profile = _glewSearchExtension(
+ "GLX_EXT_create_context_es_profile", extStart, extEnd);
+# undef GLXEW_EXT_create_context_es2_profile
+ const bool GLXEW_EXT_create_context_es2_profile = _glewSearchExtension(
+ "GLX_EXT_create_context_es2_profile", extStart, extEnd);
+# endif /* WITH_GLEW_ES */
+
+ /* End Inline Glew */
+ /* -------------------------------------------------------------------- */
#else
- /* important to initialize only glxew (_not_ glew),
- * since this breaks w/ Mesa's `swrast`, see: T46431 */
- glxewInit();
-#endif /* USE_GLXEW_INIT_WORKAROUND */
-
+ /* important to initialize only glxew (_not_ glew),
+ * since this breaks w/ Mesa's `swrast`, see: T46431 */
+ glxewInit();
+#endif /* USE_GLXEW_INIT_WORKAROUND */
-
- if (GLXEW_ARB_create_context) {
- int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
- int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ if (GLXEW_ARB_create_context) {
+ int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
#ifdef WITH_GLEW_ES
- int profileBitES = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT;
+ int profileBitES = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT;
#endif
- if (!GLXEW_ARB_create_context_profile && profileBitCore)
- fprintf(stderr, "Warning! OpenGL core profile not available.\n");
+ if (!GLXEW_ARB_create_context_profile && profileBitCore)
+ fprintf(stderr, "Warning! OpenGL core profile not available.\n");
- if (!GLXEW_ARB_create_context_profile && profileBitCompat)
- fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n");
+ if (!GLXEW_ARB_create_context_profile && profileBitCompat)
+ fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n");
#ifdef WITH_GLEW_ES
- if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
- fprintf(stderr, "Warning! OpenGL ES profile not available.\n");
+ if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
+ fprintf(stderr, "Warning! OpenGL ES profile not available.\n");
- if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
- fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n");
+ if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
+ fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n");
#endif
- int profileMask = 0;
+ int profileMask = 0;
- if (GLXEW_ARB_create_context_profile && profileBitCore)
- profileMask |= profileBitCore;
+ if (GLXEW_ARB_create_context_profile && profileBitCore)
+ profileMask |= profileBitCore;
- if (GLXEW_ARB_create_context_profile && profileBitCompat)
- profileMask |= profileBitCompat;
+ if (GLXEW_ARB_create_context_profile && profileBitCompat)
+ profileMask |= profileBitCompat;
#ifdef WITH_GLEW_ES
- if (GLXEW_EXT_create_context_es_profile && profileBitES)
- profileMask |= profileBitES;
+ if (GLXEW_EXT_create_context_es_profile && profileBitES)
+ profileMask |= profileBitES;
#endif
- if (profileMask != m_contextProfileMask)
- fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits.");
-
-
- /* max 10 attributes plus terminator */
- int attribs[11];
- int i = 0;
-
- if (profileMask) {
- attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB;
- attribs[i++] = profileMask;
- }
-
- if (m_contextMajorVersion != 0) {
- attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
- attribs[i++] = m_contextMajorVersion;
- attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
- attribs[i++] = m_contextMinorVersion;
- }
-
- if (m_contextFlags != 0) {
- attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
- attribs[i++] = m_contextFlags;
- }
-
- if (m_contextResetNotificationStrategy != 0) {
- if (GLXEW_ARB_create_context_robustness) {
- attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
- attribs[i++] = m_contextResetNotificationStrategy;
- }
- else {
- fprintf(stderr, "Warning! Cannot set the reset notification strategy.");
- }
- }
- attribs[i++] = 0;
-
- /* Some drivers don't like having a true offscreen context.
- * Create a pixel buffer instead of a window to render to.
- * even if it will never be used for drawing. */
- int pbuffer_attribs[] = {
- GLX_PBUFFER_WIDTH, 1,
- GLX_PBUFFER_HEIGHT, 1,
- None
- };
-
- /* Create a GL 3.x context */
- if (m_fbconfig) {
- m_context = glXCreateContextAttribsARB(m_display, m_fbconfig, s_sharedContext, true, attribs);
-
- if (!m_window) {
- m_window = (Window)glXCreatePbuffer(m_display, m_fbconfig, pbuffer_attribs);
- }
- }
- else {
- GLXFBConfig *framebuffer_config = NULL;
- {
- int glx_attribs[64];
- int fbcount = 0;
-
- GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, false, true);
-
- framebuffer_config = glXChooseFBConfig(m_display, DefaultScreen(m_display), glx_attribs, &fbcount);
- }
-
- if (framebuffer_config) {
- m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs);
-
- if (!m_window) {
- m_window = (Window)glXCreatePbuffer(m_display, framebuffer_config[0], pbuffer_attribs);
- }
-
- XFree(framebuffer_config);
- }
- }
- }
- else {
- /* Don't create legacy context */
- fprintf(stderr, "Error! GLX_ARB_create_context not available.\n");
- }
-
- GHOST_TSuccess success;
-
- if (m_context != NULL) {
- const unsigned char *version;
-
- if (!s_sharedContext)
- s_sharedContext = m_context;
-
- s_sharedCount++;
-
- glXMakeCurrent(m_display, m_window, m_context);
-
- // Seems that this has to be called after MakeCurrent,
- // which means we cannot use glX extensions until after we create a context
- initContextGLXEW();
-
- if (m_window) {
- initClearGL();
- ::glXSwapBuffers(m_display, m_window);
- }
-
- /* re initialize to get the extensions properly */
- initContextGLXEW();
-
- version = glGetString(GL_VERSION);
-
- if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) {
- success = GHOST_kFailure;
- }
- else {
- success = GHOST_kSuccess;
- }
- }
- else {
- /* freeing well clean up the context initialized above */
- success = GHOST_kFailure;
- }
-
- GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
-
- return success;
+ if (profileMask != m_contextProfileMask)
+ fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits.");
+
+ /* max 10 attributes plus terminator */
+ int attribs[11];
+ int i = 0;
+
+ if (profileMask) {
+ attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB;
+ attribs[i++] = profileMask;
+ }
+
+ if (m_contextMajorVersion != 0) {
+ attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
+ attribs[i++] = m_contextMajorVersion;
+ attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
+ attribs[i++] = m_contextMinorVersion;
+ }
+
+ if (m_contextFlags != 0) {
+ attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
+ attribs[i++] = m_contextFlags;
+ }
+
+ if (m_contextResetNotificationStrategy != 0) {
+ if (GLXEW_ARB_create_context_robustness) {
+ attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
+ attribs[i++] = m_contextResetNotificationStrategy;
+ }
+ else {
+ fprintf(stderr, "Warning! Cannot set the reset notification strategy.");
+ }
+ }
+ attribs[i++] = 0;
+
+ /* Some drivers don't like having a true offscreen context.
+ * Create a pixel buffer instead of a window to render to.
+ * even if it will never be used for drawing. */
+ int pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None};
+
+ /* Create a GL 3.x context */
+ if (m_fbconfig) {
+ m_context = glXCreateContextAttribsARB(
+ m_display, m_fbconfig, s_sharedContext, true, attribs);
+
+ if (!m_window) {
+ m_window = (Window)glXCreatePbuffer(m_display, m_fbconfig, pbuffer_attribs);
+ }
+ }
+ else {
+ GLXFBConfig *framebuffer_config = NULL;
+ {
+ int glx_attribs[64];
+ int fbcount = 0;
+
+ GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, false, true);
+
+ framebuffer_config = glXChooseFBConfig(
+ m_display, DefaultScreen(m_display), glx_attribs, &fbcount);
+ }
+
+ if (framebuffer_config) {
+ m_context = glXCreateContextAttribsARB(
+ m_display, framebuffer_config[0], s_sharedContext, True, attribs);
+
+ if (!m_window) {
+ m_window = (Window)glXCreatePbuffer(m_display, framebuffer_config[0], pbuffer_attribs);
+ }
+
+ XFree(framebuffer_config);
+ }
+ }
+ }
+ else {
+ /* Don't create legacy context */
+ fprintf(stderr, "Error! GLX_ARB_create_context not available.\n");
+ }
+
+ GHOST_TSuccess success;
+
+ if (m_context != NULL) {
+ const unsigned char *version;
+
+ if (!s_sharedContext)
+ s_sharedContext = m_context;
+
+ s_sharedCount++;
+
+ glXMakeCurrent(m_display, m_window, m_context);
+
+ // Seems that this has to be called after MakeCurrent,
+ // which means we cannot use glX extensions until after we create a context
+ initContextGLXEW();
+
+ if (m_window) {
+ initClearGL();
+ ::glXSwapBuffers(m_display, m_window);
+ }
+
+ /* re initialize to get the extensions properly */
+ initContextGLXEW();
+
+ version = glGetString(GL_VERSION);
+
+ if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) {
+ success = GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ }
+ else {
+ /* freeing well clean up the context initialized above */
+ success = GHOST_kFailure;
+ }
+
+ GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
+
+ return success;
}
-
GHOST_TSuccess GHOST_ContextGLX::releaseNativeHandles()
{
- m_window = 0;
+ m_window = 0;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval)
{
- if (GLXEW_EXT_swap_control) {
- ::glXSwapIntervalEXT(m_display, m_window, interval);
-
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (GLXEW_EXT_swap_control) {
+ ::glXSwapIntervalEXT(m_display, m_window, interval);
+
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut)
{
- if (GLXEW_EXT_swap_control) {
- unsigned int interval = 0;
+ if (GLXEW_EXT_swap_control) {
+ unsigned int interval = 0;
- ::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval);
+ ::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval);
- intervalOut = static_cast<int>(interval);
+ intervalOut = static_cast<int>(interval);
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
/**
@@ -382,117 +369,123 @@ GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut)
*
* \note Similar to SDL's 'X11_GL_GetAttributes'
*/
-int GHOST_X11_GL_GetAttributes(
- int *attribs, int attribs_max,
- int samples, bool is_stereo_visual,
- bool need_alpha,
- bool for_fb_config)
+int GHOST_X11_GL_GetAttributes(int *attribs,
+ int attribs_max,
+ int samples,
+ bool is_stereo_visual,
+ bool need_alpha,
+ bool for_fb_config)
{
- int i = 0;
+ int i = 0;
#ifdef GHOST_OPENGL_STENCIL
- const bool need_stencil = true;
+ const bool need_stencil = true;
#else
- const bool need_stencil = false;
+ const bool need_stencil = false;
#endif
- if (is_stereo_visual) {
- attribs[i++] = GLX_STEREO;
- if (for_fb_config) {
- attribs[i++] = True;
- }
- }
+ if (is_stereo_visual) {
+ attribs[i++] = GLX_STEREO;
+ if (for_fb_config) {
+ attribs[i++] = True;
+ }
+ }
- if (for_fb_config) {
- attribs[i++] = GLX_RENDER_TYPE;
- attribs[i++] = GLX_RGBA_BIT;
- }
- else {
- attribs[i++] = GLX_RGBA;
- }
+ if (for_fb_config) {
+ attribs[i++] = GLX_RENDER_TYPE;
+ attribs[i++] = GLX_RGBA_BIT;
+ }
+ else {
+ attribs[i++] = GLX_RGBA;
+ }
- attribs[i++] = GLX_DOUBLEBUFFER;
- if (for_fb_config) {
- attribs[i++] = True;
- }
+ attribs[i++] = GLX_DOUBLEBUFFER;
+ if (for_fb_config) {
+ attribs[i++] = True;
+ }
- attribs[i++] = GLX_RED_SIZE;
- attribs[i++] = True;
+ attribs[i++] = GLX_RED_SIZE;
+ attribs[i++] = True;
- attribs[i++] = GLX_BLUE_SIZE;
- attribs[i++] = True;
+ attribs[i++] = GLX_BLUE_SIZE;
+ attribs[i++] = True;
- attribs[i++] = GLX_GREEN_SIZE;
- attribs[i++] = True;
+ attribs[i++] = GLX_GREEN_SIZE;
+ attribs[i++] = True;
- attribs[i++] = GLX_DEPTH_SIZE;
- attribs[i++] = True;
+ attribs[i++] = GLX_DEPTH_SIZE;
+ attribs[i++] = True;
- if (need_alpha) {
- attribs[i++] = GLX_ALPHA_SIZE;
- attribs[i++] = True;
- }
+ if (need_alpha) {
+ attribs[i++] = GLX_ALPHA_SIZE;
+ attribs[i++] = True;
+ }
- if (need_stencil) {
- attribs[i++] = GLX_STENCIL_SIZE;
- attribs[i++] = True;
- }
+ if (need_stencil) {
+ attribs[i++] = GLX_STENCIL_SIZE;
+ attribs[i++] = True;
+ }
- if (samples) {
- attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
- attribs[i++] = True;
+ if (samples) {
+ attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
+ attribs[i++] = True;
- attribs[i++] = GLX_SAMPLES_ARB;
- attribs[i++] = samples;
- }
+ attribs[i++] = GLX_SAMPLES_ARB;
+ attribs[i++] = samples;
+ }
- attribs[i++] = 0;
+ attribs[i++] = 0;
- GHOST_ASSERT(i <= attribs_max, "attribute size too small");
+ GHOST_ASSERT(i <= attribs_max, "attribute size too small");
- (void)attribs_max;
+ (void)attribs_max;
- return i;
+ return i;
}
-
/* excuse inlining part of glew */
#ifdef USE_GLXEW_INIT_WORKAROUND
static GLuint _glewStrLen(const GLubyte *s)
{
- GLuint i = 0;
- if (s == NULL) return 0;
- while (s[i] != '\0') i++;
- return i;
+ GLuint i = 0;
+ if (s == NULL)
+ return 0;
+ while (s[i] != '\0')
+ i++;
+ return i;
}
static GLuint _glewStrCLen(const GLubyte *s, GLubyte c)
{
- GLuint i = 0;
- if (s == NULL) return 0;
- while (s[i] != '\0' && s[i] != c) i++;
- return (s[i] == '\0' || s[i] == c) ? i : 0;
+ GLuint i = 0;
+ if (s == NULL)
+ return 0;
+ while (s[i] != '\0' && s[i] != c)
+ i++;
+ return (s[i] == '\0' || s[i] == c) ? i : 0;
}
static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n)
{
- GLuint i = 0;
- if (a == NULL || b == NULL)
- return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE;
- while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++;
- return i == n ? GL_TRUE : GL_FALSE;
+ GLuint i = 0;
+ if (a == NULL || b == NULL)
+ return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE;
+ while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i])
+ i++;
+ return i == n ? GL_TRUE : GL_FALSE;
}
static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end)
{
- const GLubyte *p;
- GLuint len = _glewStrLen((const GLubyte *)name);
- p = start;
- while (p < end) {
- GLuint n = _glewStrCLen(p, ' ');
- if (len == n && _glewStrSame((const GLubyte *)name, p, n)) return GL_TRUE;
- p += n + 1;
- }
- return GL_FALSE;
+ const GLubyte *p;
+ GLuint len = _glewStrLen((const GLubyte *)name);
+ p = start;
+ while (p < end) {
+ GLuint n = _glewStrCLen(p, ' ');
+ if (len == n && _glewStrSame((const GLubyte *)name, p, n))
+ return GL_TRUE;
+ p += n + 1;
+ }
+ return GL_FALSE;
}
-#endif /* USE_GLXEW_INIT_WORKAROUND */
+#endif /* USE_GLXEW_INIT_WORKAROUND */
diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h
index ec2baf49767..5b631ea55de 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.h
+++ b/intern/ghost/intern/GHOST_ContextGLX.h
@@ -28,109 +28,107 @@
#include <GL/glxew.h>
-
#ifndef GHOST_OPENGL_GLX_CONTEXT_FLAGS
/* leave as convenience define for the future */
-#define GHOST_OPENGL_GLX_CONTEXT_FLAGS 0
+# define GHOST_OPENGL_GLX_CONTEXT_FLAGS 0
#endif
#ifndef GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY
-#define GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY 0
+# define GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY 0
#endif
-class GHOST_ContextGLX : public GHOST_Context
-{
-public:
- /**
- * Constructor.
- */
- GHOST_ContextGLX(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- Window window,
- Display *display,
- GLXFBConfig fbconfig,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy);
-
- /**
- * Destructor.
- */
- ~GHOST_ContextGLX();
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess swapBuffers();
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess activateDrawingContext();
-
- /**
- * Release the drawing context of the calling thread.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess releaseDrawingContext();
-
- /**
- * Call immediately after new to initialize. If this fails then immediately delete the object.
- * \return Indication as to whether initialization has succeeded.
- */
- GHOST_TSuccess initializeDrawingContext();
-
- /**
- * Removes references to native handles from this context and then returns
- * \return GHOST_kSuccess if it is OK for the parent to release the handles and
- * GHOST_kFailure if releasing the handles will interfere with sharing
- */
- GHOST_TSuccess releaseNativeHandles();
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess setSwapInterval(int interval);
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \param intervalOut Variable to store the swap interval if it can be read.
- * \return Whether the swap interval can be read.
- */
- GHOST_TSuccess getSwapInterval(int &intervalOut);
-
-private:
- void initContextGLXEW();
-
- Display *m_display;
- GLXFBConfig m_fbconfig;
- Window m_window;
-
- const int m_contextProfileMask;
- const int m_contextMajorVersion;
- const int m_contextMinorVersion;
- const int m_contextFlags;
- const int m_contextResetNotificationStrategy;
-
- GLXContext m_context;
-
- /** The first created OpenGL context (for sharing display lists) */
- static GLXContext s_sharedContext;
- static int s_sharedCount;
+class GHOST_ContextGLX : public GHOST_Context {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_ContextGLX(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ Window window,
+ Display *display,
+ GLXFBConfig fbconfig,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy);
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_ContextGLX();
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess swapBuffers();
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess activateDrawingContext();
+
+ /**
+ * Release the drawing context of the calling thread.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess releaseDrawingContext();
+
+ /**
+ * Call immediately after new to initialize. If this fails then immediately delete the object.
+ * \return Indication as to whether initialization has succeeded.
+ */
+ GHOST_TSuccess initializeDrawingContext();
+
+ /**
+ * Removes references to native handles from this context and then returns
+ * \return GHOST_kSuccess if it is OK for the parent to release the handles and
+ * GHOST_kFailure if releasing the handles will interfere with sharing
+ */
+ GHOST_TSuccess releaseNativeHandles();
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess setSwapInterval(int interval);
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \param intervalOut Variable to store the swap interval if it can be read.
+ * \return Whether the swap interval can be read.
+ */
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
+
+ private:
+ void initContextGLXEW();
+
+ Display *m_display;
+ GLXFBConfig m_fbconfig;
+ Window m_window;
+
+ const int m_contextProfileMask;
+ const int m_contextMajorVersion;
+ const int m_contextMinorVersion;
+ const int m_contextFlags;
+ const int m_contextResetNotificationStrategy;
+
+ GLXContext m_context;
+
+ /** The first created OpenGL context (for sharing display lists) */
+ static GLXContext s_sharedContext;
+ static int s_sharedCount;
};
/* used to get GLX info */
-int GHOST_X11_GL_GetAttributes(
- int *attribs, int attribs_max,
- int samples, bool is_stereo_visual,
- bool need_alpha,
- bool for_fb_config);
-
-#endif // __GHOST_CONTEXTGLX_H__
+int GHOST_X11_GL_GetAttributes(int *attribs,
+ int attribs_max,
+ int samples,
+ bool is_stereo_visual,
+ bool need_alpha,
+ bool for_fb_config);
+
+#endif // __GHOST_CONTEXTGLX_H__
diff --git a/intern/ghost/intern/GHOST_ContextNone.cpp b/intern/ghost/intern/GHOST_ContextNone.cpp
index df5e91738da..a59cee0444f 100644
--- a/intern/ghost/intern/GHOST_ContextNone.cpp
+++ b/intern/ghost/intern/GHOST_ContextNone.cpp
@@ -25,53 +25,45 @@
#include "GHOST_ContextNone.h"
-
GHOST_TSuccess GHOST_ContextNone::swapBuffers()
{
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextNone::activateDrawingContext()
{
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextNone::releaseDrawingContext()
{
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextNone::updateDrawingContext()
{
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextNone::initializeDrawingContext()
{
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextNone::releaseNativeHandles()
{
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextNone::setSwapInterval(int interval)
{
- m_swapInterval = interval;
+ m_swapInterval = interval;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextNone::getSwapInterval(int &intervalOut)
{
- intervalOut = m_swapInterval;
- return GHOST_kSuccess;
+ intervalOut = m_swapInterval;
+ return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_ContextNone.h b/intern/ghost/intern/GHOST_ContextNone.h
index 65bad70d1fa..b7297d2497c 100644
--- a/intern/ghost/intern/GHOST_ContextNone.h
+++ b/intern/ghost/intern/GHOST_ContextNone.h
@@ -28,68 +28,64 @@
#include "GHOST_Context.h"
-class GHOST_ContextNone : public GHOST_Context
-{
-public:
+class GHOST_ContextNone : public GHOST_Context {
+ public:
+ GHOST_ContextNone(bool stereoVisual, GHOST_TUns16 numOfAASamples)
+ : GHOST_Context(stereoVisual, numOfAASamples), m_swapInterval(1)
+ {
+ }
- GHOST_ContextNone(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples)
- : GHOST_Context(stereoVisual, numOfAASamples),
- m_swapInterval(1)
- {}
+ /**
+ * Dummy function
+ * \return Always succeeds
+ */
+ GHOST_TSuccess swapBuffers();
- /**
- * Dummy function
- * \return Always succeeds
- */
- GHOST_TSuccess swapBuffers();
+ /**
+ * Dummy function
+ * \return Always succeeds
+ */
+ GHOST_TSuccess activateDrawingContext();
- /**
- * Dummy function
- * \return Always succeeds
- */
- GHOST_TSuccess activateDrawingContext();
+ /**
+ * Dummy function
+ * \return Always succeeds
+ */
+ GHOST_TSuccess releaseDrawingContext();
- /**
- * Dummy function
- * \return Always succeeds
- */
- GHOST_TSuccess releaseDrawingContext();
+ /**
+ * Dummy function
+ * \return Always succeeds
+ */
+ GHOST_TSuccess updateDrawingContext();
- /**
- * Dummy function
- * \return Always succeeds
- */
- GHOST_TSuccess updateDrawingContext();
+ /**
+ * Dummy function
+ * \return Always succeeds
+ */
+ GHOST_TSuccess initializeDrawingContext();
- /**
- * Dummy function
- * \return Always succeeds
- */
- GHOST_TSuccess initializeDrawingContext();
+ /**
+ * Dummy function
+ * \return Always succeeds
+ */
+ GHOST_TSuccess releaseNativeHandles();
- /**
- * Dummy function
- * \return Always succeeds
- */
- GHOST_TSuccess releaseNativeHandles();
+ /**
+ * Dummy function
+ * \return Always succeeds
+ */
+ GHOST_TSuccess setSwapInterval(int interval);
- /**
- * Dummy function
- * \return Always succeeds
- */
- GHOST_TSuccess setSwapInterval(int interval);
+ /**
+ * Dummy function
+ * \param intervalOut Gets whatever was set by setSwapInterval
+ * \return Always succeeds
+ */
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
- /**
- * Dummy function
- * \param intervalOut Gets whatever was set by setSwapInterval
- * \return Always succeeds
- */
- GHOST_TSuccess getSwapInterval(int &intervalOut);
-
-private:
- int m_swapInterval;
+ private:
+ int m_swapInterval;
};
-#endif // __GHOST_CONTEXTNONE_H__
+#endif // __GHOST_CONTEXTNONE_H__
diff --git a/intern/ghost/intern/GHOST_ContextSDL.cpp b/intern/ghost/intern/GHOST_ContextSDL.cpp
index efdf6353ab8..600cab6f6d5 100644
--- a/intern/ghost/intern/GHOST_ContextSDL.cpp
+++ b/intern/ghost/intern/GHOST_ContextSDL.cpp
@@ -31,20 +31,17 @@
#include <cstdio>
#include <cstring>
-
SDL_GLContext GHOST_ContextSDL::s_sharedContext = NULL;
-int GHOST_ContextSDL::s_sharedCount = 0;
-
-
-GHOST_ContextSDL::GHOST_ContextSDL(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- SDL_Window *window,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy)
+int GHOST_ContextSDL::s_sharedCount = 0;
+
+GHOST_ContextSDL::GHOST_ContextSDL(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ SDL_Window *window,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
m_window(window),
m_hidden_window(NULL),
@@ -55,168 +52,159 @@ GHOST_ContextSDL::GHOST_ContextSDL(
m_contextResetNotificationStrategy(contextResetNotificationStrategy),
m_context(NULL)
{
- // assert(m_window != NULL);
+ // assert(m_window != NULL);
}
-
GHOST_ContextSDL::~GHOST_ContextSDL()
{
- if (m_context != NULL) {
- if (m_window != NULL && m_context == SDL_GL_GetCurrentContext())
- SDL_GL_MakeCurrent(m_window, NULL);
+ if (m_context != NULL) {
+ if (m_window != NULL && m_context == SDL_GL_GetCurrentContext())
+ SDL_GL_MakeCurrent(m_window, NULL);
- if (m_context != s_sharedContext || s_sharedCount == 1) {
- assert(s_sharedCount > 0);
+ if (m_context != s_sharedContext || s_sharedCount == 1) {
+ assert(s_sharedCount > 0);
- s_sharedCount--;
+ s_sharedCount--;
- if (s_sharedCount == 0)
- s_sharedContext = NULL;
+ if (s_sharedCount == 0)
+ s_sharedContext = NULL;
- SDL_GL_DeleteContext(m_context);
- }
+ SDL_GL_DeleteContext(m_context);
+ }
- if (m_hidden_window != NULL)
- SDL_DestroyWindow(m_hidden_window);
- }
+ if (m_hidden_window != NULL)
+ SDL_DestroyWindow(m_hidden_window);
+ }
}
-
GHOST_TSuccess GHOST_ContextSDL::swapBuffers()
{
- SDL_GL_SwapWindow(m_window);
+ SDL_GL_SwapWindow(m_window);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextSDL::activateDrawingContext()
{
- if (m_context) {
- return SDL_GL_MakeCurrent(m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_context) {
+ return SDL_GL_MakeCurrent(m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextSDL::releaseDrawingContext()
{
- if (m_context) {
- /* Untested, may not work */
- return SDL_GL_MakeCurrent(NULL, NULL) ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_context) {
+ /* Untested, may not work */
+ return SDL_GL_MakeCurrent(NULL, NULL) ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext()
{
#ifdef GHOST_OPENGL_ALPHA
- const bool needAlpha = true;
+ const bool needAlpha = true;
#else
- const bool needAlpha = false;
+ const bool needAlpha = false;
#endif
#ifdef GHOST_OPENGL_STENCIL
- const bool needStencil = true;
+ const bool needStencil = true;
#else
- const bool needStencil = false;
+ const bool needStencil = false;
#endif
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, m_contextProfileMask);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, m_contextMajorVersion);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, m_contextMinorVersion);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, m_contextFlags);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, m_contextProfileMask);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, m_contextMajorVersion);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, m_contextMinorVersion);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, m_contextFlags);
- SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- if (needAlpha) {
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
- }
+ if (needAlpha) {
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ }
- if (needStencil) {
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
- }
+ if (needStencil) {
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
+ }
- if (m_stereoVisual) {
- SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
- }
+ if (m_stereoVisual) {
+ SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
+ }
- if (m_numOfAASamples) {
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_numOfAASamples);
- }
+ if (m_numOfAASamples) {
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_numOfAASamples);
+ }
- if (m_window == NULL) {
- m_hidden_window = SDL_CreateWindow(
- "Offscreen Context Windows",
- SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- 1, 1,
- SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN
- );
+ if (m_window == NULL) {
+ m_hidden_window = SDL_CreateWindow("Offscreen Context Windows",
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ 1,
+ 1,
+ SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS |
+ SDL_WINDOW_HIDDEN);
- m_window = m_hidden_window;
- }
+ m_window = m_hidden_window;
+ }
- m_context = SDL_GL_CreateContext(m_window);
+ m_context = SDL_GL_CreateContext(m_window);
- GHOST_TSuccess success;
+ GHOST_TSuccess success;
- if (m_context != NULL) {
- if (!s_sharedContext)
- s_sharedContext = m_context;
+ if (m_context != NULL) {
+ if (!s_sharedContext)
+ s_sharedContext = m_context;
- s_sharedCount++;
+ s_sharedCount++;
- success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ?
- GHOST_kFailure : GHOST_kSuccess;
+ success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ? GHOST_kFailure : GHOST_kSuccess;
- initContextGLEW();
+ initContextGLEW();
- initClearGL();
- SDL_GL_SwapWindow(m_window);
+ initClearGL();
+ SDL_GL_SwapWindow(m_window);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
- return success;
+ return success;
}
-
GHOST_TSuccess GHOST_ContextSDL::releaseNativeHandles()
{
- m_window = NULL;
+ m_window = NULL;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_ContextSDL::setSwapInterval(int interval)
{
- if (SDL_GL_SetSwapInterval(interval) != -1) {
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (SDL_GL_SetSwapInterval(interval) != -1) {
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextSDL::getSwapInterval(int &intervalOut)
{
- intervalOut = SDL_GL_GetSwapInterval();
- return GHOST_kSuccess;
+ intervalOut = SDL_GL_GetSwapInterval();
+ return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_ContextSDL.h b/intern/ghost/intern/GHOST_ContextSDL.h
index 6c36d1d703e..bbd8dd5ad5e 100644
--- a/intern/ghost/intern/GHOST_ContextSDL.h
+++ b/intern/ghost/intern/GHOST_ContextSDL.h
@@ -27,104 +27,100 @@
#include "GHOST_Context.h"
extern "C" {
- #include "SDL.h"
+#include "SDL.h"
}
-
#ifndef GHOST_OPENGL_SDL_CONTEXT_FLAGS
# ifdef WITH_GPU_DEBUG
# define GHOST_OPENGL_SDL_CONTEXT_FLAGS SDL_GL_CONTEXT_DEBUG_FLAG
# else
# define GHOST_OPENGL_SDL_CONTEXT_FLAGS 0
-# endif
+# endif
#endif
#ifndef GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY
-#define GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY 0
+# define GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY 0
#endif
-
-class GHOST_ContextSDL : public GHOST_Context
-{
-public:
- /**
- * Constructor.
- */
- GHOST_ContextSDL(
- bool stereoVisual,
- GHOST_TUns16 numOfAASamples,
- SDL_Window *window,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy);
-
- /**
- * Destructor.
- */
- ~GHOST_ContextSDL();
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess swapBuffers();
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess activateDrawingContext();
-
- /**
- * Release the drawing context of the calling thread.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess releaseDrawingContext();
-
- /**
- * Call immediately after new to initialize. If this fails then immediately delete the object.
- * \return Indication as to whether initialization has succeeded.
- */
- GHOST_TSuccess initializeDrawingContext();
-
- /**
- * Removes references to native handles from this context and then returns
- * \return GHOST_kSuccess if it is OK for the parent to release the handles and
- * GHOST_kFailure if releasing the handles will interfere with sharing
- */
- GHOST_TSuccess releaseNativeHandles();
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess setSwapInterval(int interval);
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \param intervalOut Variable to store the swap interval if it can be read.
- * \return Whether the swap interval can be read.
- */
- GHOST_TSuccess getSwapInterval(int &intervalOut);
-
-private:
- SDL_Window *m_window;
- SDL_Window *m_hidden_window;
-
- const int m_contextProfileMask;
- const int m_contextMajorVersion;
- const int m_contextMinorVersion;
- const int m_contextFlags;
- const int m_contextResetNotificationStrategy;
-
- SDL_GLContext m_context; /* m_sdl_glcontext */
-
- /** The first created OpenGL context (for sharing display lists) */
- static SDL_GLContext s_sharedContext;
- static int s_sharedCount;
+class GHOST_ContextSDL : public GHOST_Context {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_ContextSDL(bool stereoVisual,
+ GHOST_TUns16 numOfAASamples,
+ SDL_Window *window,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy);
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_ContextSDL();
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess swapBuffers();
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess activateDrawingContext();
+
+ /**
+ * Release the drawing context of the calling thread.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess releaseDrawingContext();
+
+ /**
+ * Call immediately after new to initialize. If this fails then immediately delete the object.
+ * \return Indication as to whether initialization has succeeded.
+ */
+ GHOST_TSuccess initializeDrawingContext();
+
+ /**
+ * Removes references to native handles from this context and then returns
+ * \return GHOST_kSuccess if it is OK for the parent to release the handles and
+ * GHOST_kFailure if releasing the handles will interfere with sharing
+ */
+ GHOST_TSuccess releaseNativeHandles();
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess setSwapInterval(int interval);
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \param intervalOut Variable to store the swap interval if it can be read.
+ * \return Whether the swap interval can be read.
+ */
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
+
+ private:
+ SDL_Window *m_window;
+ SDL_Window *m_hidden_window;
+
+ const int m_contextProfileMask;
+ const int m_contextMajorVersion;
+ const int m_contextMinorVersion;
+ const int m_contextFlags;
+ const int m_contextResetNotificationStrategy;
+
+ SDL_GLContext m_context; /* m_sdl_glcontext */
+
+ /** The first created OpenGL context (for sharing display lists) */
+ static SDL_GLContext s_sharedContext;
+ static int s_sharedCount;
};
-#endif // __GHOST_CONTEXTSDL_H__
+#endif // __GHOST_CONTEXTSDL_H__
diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp
index 7138db03abc..96d6e0c1600 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextWGL.cpp
@@ -31,28 +31,25 @@
#include <cassert>
#include <vector>
-
HGLRC GHOST_ContextWGL::s_sharedHGLRC = NULL;
-int GHOST_ContextWGL::s_sharedCount = 0;
+int GHOST_ContextWGL::s_sharedCount = 0;
/* Some third-generation Intel video-cards are constantly bring problems */
static bool is_crappy_intel_card()
{
- return strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL;
+ return strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL;
}
-
-GHOST_ContextWGL::GHOST_ContextWGL(
- bool stereoVisual,
- bool alphaBackground,
- GHOST_TUns16 numOfAASamples,
- HWND hWnd,
- HDC hDC,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy)
+GHOST_ContextWGL::GHOST_ContextWGL(bool stereoVisual,
+ bool alphaBackground,
+ GHOST_TUns16 numOfAASamples,
+ HWND hWnd,
+ HDC hDC,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
m_hWnd(hWnd),
m_hDC(hDC),
@@ -70,84 +67,78 @@ GHOST_ContextWGL::GHOST_ContextWGL(
m_dummyVersion(NULL)
#endif
{
- assert(m_hDC != NULL);
+ assert(m_hDC != NULL);
}
-
GHOST_ContextWGL::~GHOST_ContextWGL()
{
- if (m_hGLRC != NULL) {
- if (m_hGLRC == ::wglGetCurrentContext())
- WIN32_CHK(::wglMakeCurrent(NULL, NULL));
+ if (m_hGLRC != NULL) {
+ if (m_hGLRC == ::wglGetCurrentContext())
+ WIN32_CHK(::wglMakeCurrent(NULL, NULL));
- if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) {
- assert(s_sharedCount > 0);
+ if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) {
+ assert(s_sharedCount > 0);
- s_sharedCount--;
+ s_sharedCount--;
- if (s_sharedCount == 0)
- s_sharedHGLRC = NULL;
+ if (s_sharedCount == 0)
+ s_sharedHGLRC = NULL;
- WIN32_CHK(::wglDeleteContext(m_hGLRC));
- }
- }
+ WIN32_CHK(::wglDeleteContext(m_hGLRC));
+ }
+ }
#ifndef NDEBUG
- if (m_dummyRenderer) {
- free((void*)m_dummyRenderer);
- free((void*)m_dummyVendor);
- free((void*)m_dummyVersion);
- }
+ if (m_dummyRenderer) {
+ free((void *)m_dummyRenderer);
+ free((void *)m_dummyVendor);
+ free((void *)m_dummyVersion);
+ }
#endif
}
-
GHOST_TSuccess GHOST_ContextWGL::swapBuffers()
{
- return WIN32_CHK(::SwapBuffers(m_hDC)) ? GHOST_kSuccess : GHOST_kFailure;
+ return WIN32_CHK(::SwapBuffers(m_hDC)) ? GHOST_kSuccess : GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_ContextWGL::setSwapInterval(int interval)
{
- if (WGLEW_EXT_swap_control)
- return WIN32_CHK(::wglSwapIntervalEXT(interval)) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
- else
- return GHOST_kFailure;
+ if (WGLEW_EXT_swap_control)
+ return WIN32_CHK(::wglSwapIntervalEXT(interval)) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ else
+ return GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_ContextWGL::getSwapInterval(int &intervalOut)
{
- if (WGLEW_EXT_swap_control) {
- intervalOut = ::wglGetSwapIntervalEXT();
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (WGLEW_EXT_swap_control) {
+ intervalOut = ::wglGetSwapIntervalEXT();
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextWGL::activateDrawingContext()
{
- if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_ContextWGL::releaseDrawingContext()
{
- if (WIN32_CHK(::wglMakeCurrent(NULL, NULL))) {
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (WIN32_CHK(::wglMakeCurrent(NULL, NULL))) {
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
/* Ron Fosner's code for weighting pixel formats and forcing software.
@@ -155,99 +146,95 @@ GHOST_TSuccess GHOST_ContextWGL::releaseDrawingContext()
*/
static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd, PIXELFORMATDESCRIPTOR &preferredPFD)
{
- int weight = 0;
+ int weight = 0;
- /* assume desktop color depth is 32 bits per pixel */
+ /* assume desktop color depth is 32 bits per pixel */
- /* cull unusable pixel formats */
- /* if no formats can be found, can we determine why it was rejected? */
- if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) ||
- !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
- !(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */
- !(pfd.iPixelType == PFD_TYPE_RGBA) ||
- (pfd.cDepthBits < 16) ||
- (pfd.cColorBits > 32) || /* 64 bit formats disable aero */
- (pfd.dwFlags & PFD_GENERIC_FORMAT)) /* no software renderers */
- {
- return 0;
- }
+ /* cull unusable pixel formats */
+ /* if no formats can be found, can we determine why it was rejected? */
+ if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
+ !(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */
+ !(pfd.iPixelType == PFD_TYPE_RGBA) || (pfd.cDepthBits < 16) ||
+ (pfd.cColorBits > 32) || /* 64 bit formats disable aero */
+ (pfd.dwFlags & PFD_GENERIC_FORMAT)) /* no software renderers */
+ {
+ return 0;
+ }
- weight = 1; /* it's usable */
+ weight = 1; /* it's usable */
- /* the bigger the depth buffer the better */
- /* give no weight to a 16-bit depth buffer, because those are crap */
- weight += pfd.cDepthBits - 16;
+ /* the bigger the depth buffer the better */
+ /* give no weight to a 16-bit depth buffer, because those are crap */
+ weight += pfd.cDepthBits - 16;
- weight += pfd.cColorBits - 8;
+ weight += pfd.cColorBits - 8;
- if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0)
- weight++;
+ if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0)
+ weight++;
#ifdef WIN32_COMPOSITING
- if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION))
- weight++;
+ if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION))
+ weight++;
#endif
#ifdef GHOST_OPENGL_STENCIL
- if (pfd.cStencilBits >= 8)
- weight++;
+ if (pfd.cStencilBits >= 8)
+ weight++;
#endif
- return weight;
+ return weight;
}
-
/*
* A modification of Ron Fosner's replacement for ChoosePixelFormat
* returns 0 on error, else returns the pixel format number to be used
*/
static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR &preferredPFD)
{
- int iPixelFormat = 0;
- int weight = 0;
+ int iPixelFormat = 0;
+ int weight = 0;
- int iStereoPixelFormat = 0;
- int stereoWeight = 0;
+ int iStereoPixelFormat = 0;
+ int stereoWeight = 0;
- /* choose a pixel format using the useless Windows function in case we come up empty handed */
- int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD);
+ /* choose a pixel format using the useless Windows function in case we come up empty handed */
+ int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD);
- WIN32_CHK(iLastResortPixelFormat != 0);
+ WIN32_CHK(iLastResortPixelFormat != 0);
- int lastPFD = ::DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
+ int lastPFD = ::DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
- WIN32_CHK(lastPFD != 0);
+ WIN32_CHK(lastPFD != 0);
- for (int i = 1; i <= lastPFD; i++) {
- PIXELFORMATDESCRIPTOR pfd;
- int check = ::DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ for (int i = 1; i <= lastPFD; i++) {
+ PIXELFORMATDESCRIPTOR pfd;
+ int check = ::DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- WIN32_CHK(check == lastPFD);
+ WIN32_CHK(check == lastPFD);
- int w = weight_pixel_format(pfd, preferredPFD);
+ int w = weight_pixel_format(pfd, preferredPFD);
- if (w > weight) {
- weight = w;
- iPixelFormat = i;
- }
+ if (w > weight) {
+ weight = w;
+ iPixelFormat = i;
+ }
- if (w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) {
- stereoWeight = w;
- iStereoPixelFormat = i;
- }
- }
+ if (w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) {
+ stereoWeight = w;
+ iStereoPixelFormat = i;
+ }
+ }
- /* choose any available stereo format over a non-stereo format */
- if (iStereoPixelFormat != 0)
- iPixelFormat = iStereoPixelFormat;
+ /* choose any available stereo format over a non-stereo format */
+ if (iStereoPixelFormat != 0)
+ iPixelFormat = iStereoPixelFormat;
- if (iPixelFormat == 0) {
- fprintf(stderr, "Warning! Using result of ChoosePixelFormat.\n");
- iPixelFormat = iLastResortPixelFormat;
- }
+ if (iPixelFormat == 0) {
+ fprintf(stderr, "Warning! Using result of ChoosePixelFormat.\n");
+ iPixelFormat = iLastResortPixelFormat;
+ }
- return iPixelFormat;
+ return iPixelFormat;
}
-
/*
* Clone a window for the purpose of creating a temporary context to initialize WGL extensions.
* There is no generic way to clone the lpParam parameter, so the caller is responsible for cloning it themselves.
@@ -255,592 +242,569 @@ static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR &preferredP
static HWND clone_window(HWND hWnd, LPVOID lpParam)
{
- int count;
+ int count;
- SetLastError(NO_ERROR);
+ SetLastError(NO_ERROR);
- DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
- WIN32_CHK(GetLastError() == NO_ERROR);
+ DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
+ WIN32_CHK(GetLastError() == NO_ERROR);
- WCHAR lpClassName[100] = L"";
- count = GetClassNameW(hWnd, lpClassName, sizeof(lpClassName));
- WIN32_CHK(count != 0);
+ WCHAR lpClassName[100] = L"";
+ count = GetClassNameW(hWnd, lpClassName, sizeof(lpClassName));
+ WIN32_CHK(count != 0);
- WCHAR lpWindowName[100] = L"";
- count = GetWindowTextW(hWnd, lpWindowName, sizeof(lpWindowName));
- WIN32_CHK(count != 0);
+ WCHAR lpWindowName[100] = L"";
+ count = GetWindowTextW(hWnd, lpWindowName, sizeof(lpWindowName));
+ WIN32_CHK(count != 0);
- DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
- WIN32_CHK(GetLastError() == NO_ERROR);
+ DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
+ WIN32_CHK(GetLastError() == NO_ERROR);
- RECT rect;
- GetWindowRect(hWnd, &rect);
- WIN32_CHK(GetLastError() == NO_ERROR);
+ RECT rect;
+ GetWindowRect(hWnd, &rect);
+ WIN32_CHK(GetLastError() == NO_ERROR);
- HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT);
- WIN32_CHK(GetLastError() == NO_ERROR);
+ HWND hWndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_HWNDPARENT);
+ WIN32_CHK(GetLastError() == NO_ERROR);
- HMENU hMenu = GetMenu(hWnd);
- WIN32_CHK(GetLastError() == NO_ERROR);
+ HMENU hMenu = GetMenu(hWnd);
+ WIN32_CHK(GetLastError() == NO_ERROR);
- HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
- WIN32_CHK(GetLastError() == NO_ERROR);
+ HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
+ WIN32_CHK(GetLastError() == NO_ERROR);
- HWND hwndCloned = CreateWindowExW(
- dwExStyle,
- lpClassName,
- lpWindowName,
- dwStyle,
- rect.left,
- rect.top,
- rect.right - rect.left,
- rect.bottom - rect.top,
- hWndParent,
- hMenu,
- hInstance,
- lpParam);
+ HWND hwndCloned = CreateWindowExW(dwExStyle,
+ lpClassName,
+ lpWindowName,
+ dwStyle,
+ rect.left,
+ rect.top,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ hWndParent,
+ hMenu,
+ hInstance,
+ lpParam);
- WIN32_CHK(hwndCloned != NULL);
+ WIN32_CHK(hwndCloned != NULL);
- return hwndCloned;
+ return hwndCloned;
}
-
void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD)
{
- HWND dummyHWND = NULL;
+ HWND dummyHWND = NULL;
- HDC dummyHDC = NULL;
- HGLRC dummyHGLRC = NULL;
+ HDC dummyHDC = NULL;
+ HGLRC dummyHGLRC = NULL;
- HDC prevHDC;
- HGLRC prevHGLRC;
+ HDC prevHDC;
+ HGLRC prevHGLRC;
- int iPixelFormat;
+ int iPixelFormat;
- SetLastError(NO_ERROR);
+ SetLastError(NO_ERROR);
- prevHDC = ::wglGetCurrentDC();
- WIN32_CHK(GetLastError() == NO_ERROR);
+ prevHDC = ::wglGetCurrentDC();
+ WIN32_CHK(GetLastError() == NO_ERROR);
- prevHGLRC = ::wglGetCurrentContext();
- WIN32_CHK(GetLastError() == NO_ERROR);
+ prevHGLRC = ::wglGetCurrentContext();
+ WIN32_CHK(GetLastError() == NO_ERROR);
- iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD);
+ iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD);
- if (iPixelFormat == 0)
- goto finalize;
+ if (iPixelFormat == 0)
+ goto finalize;
- PIXELFORMATDESCRIPTOR chosenPFD;
- if (!WIN32_CHK(::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD)))
- goto finalize;
+ PIXELFORMATDESCRIPTOR chosenPFD;
+ if (!WIN32_CHK(
+ ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD)))
+ goto finalize;
- if (m_hWnd) {
- dummyHWND = clone_window(m_hWnd, NULL);
+ if (m_hWnd) {
+ dummyHWND = clone_window(m_hWnd, NULL);
- if (dummyHWND == NULL)
- goto finalize;
+ if (dummyHWND == NULL)
+ goto finalize;
- dummyHDC = GetDC(dummyHWND);
- }
+ dummyHDC = GetDC(dummyHWND);
+ }
- if (!WIN32_CHK(dummyHDC != NULL))
- goto finalize;
+ if (!WIN32_CHK(dummyHDC != NULL))
+ goto finalize;
- if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD)))
- goto finalize;
+ if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD)))
+ goto finalize;
- dummyHGLRC = ::wglCreateContext(dummyHDC);
+ dummyHGLRC = ::wglCreateContext(dummyHDC);
- if (!WIN32_CHK(dummyHGLRC != NULL))
- goto finalize;
+ if (!WIN32_CHK(dummyHGLRC != NULL))
+ goto finalize;
- if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC)))
- goto finalize;
+ if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC)))
+ goto finalize;
- if (GLEW_CHK(glewInit()) != GLEW_OK)
- fprintf(stderr, "Warning! Dummy GLEW/WGLEW failed to initialize properly.\n");
+ if (GLEW_CHK(glewInit()) != GLEW_OK)
+ fprintf(stderr, "Warning! Dummy GLEW/WGLEW failed to initialize properly.\n");
- // the following are not technially WGLEW, but they also require a context to work
+ // the following are not technially WGLEW, but they also require a context to work
#ifndef NDEBUG
- free((void*)m_dummyRenderer);
- free((void*)m_dummyVendor);
- free((void*)m_dummyVersion);
+ free((void *)m_dummyRenderer);
+ free((void *)m_dummyVendor);
+ free((void *)m_dummyVersion);
- m_dummyRenderer = _strdup(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
- m_dummyVendor = _strdup(reinterpret_cast<const char *>(glGetString(GL_VENDOR)));
- m_dummyVersion = _strdup(reinterpret_cast<const char *>(glGetString(GL_VERSION)));
+ m_dummyRenderer = _strdup(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
+ m_dummyVendor = _strdup(reinterpret_cast<const char *>(glGetString(GL_VENDOR)));
+ m_dummyVersion = _strdup(reinterpret_cast<const char *>(glGetString(GL_VERSION)));
#endif
finalize:
- WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC));
+ WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC));
- if (dummyHGLRC != NULL)
- WIN32_CHK(::wglDeleteContext(dummyHGLRC));
+ if (dummyHGLRC != NULL)
+ WIN32_CHK(::wglDeleteContext(dummyHGLRC));
- if (dummyHWND != NULL) {
- if (dummyHDC != NULL)
- WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC));
+ if (dummyHWND != NULL) {
+ if (dummyHDC != NULL)
+ WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC));
- WIN32_CHK(::DestroyWindow(dummyHWND));
- }
+ WIN32_CHK(::DestroyWindow(dummyHWND));
+ }
}
-
-static void makeAttribList(
- std::vector<int>& out,
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool sRGB)
+static void makeAttribList(std::vector<int> &out,
+ bool stereoVisual,
+ int numOfAASamples,
+ bool needAlpha,
+ bool needStencil,
+ bool sRGB)
{
- out.clear();
- out.reserve(30);
+ out.clear();
+ out.reserve(30);
- out.push_back(WGL_SUPPORT_OPENGL_ARB);
- out.push_back(GL_TRUE);
+ out.push_back(WGL_SUPPORT_OPENGL_ARB);
+ out.push_back(GL_TRUE);
- out.push_back(WGL_DRAW_TO_WINDOW_ARB);
- out.push_back(GL_TRUE);
+ out.push_back(WGL_DRAW_TO_WINDOW_ARB);
+ out.push_back(GL_TRUE);
- out.push_back(WGL_DOUBLE_BUFFER_ARB);
- out.push_back(GL_TRUE);
+ out.push_back(WGL_DOUBLE_BUFFER_ARB);
+ out.push_back(GL_TRUE);
- out.push_back(WGL_ACCELERATION_ARB);
- out.push_back(WGL_FULL_ACCELERATION_ARB);
+ out.push_back(WGL_ACCELERATION_ARB);
+ out.push_back(WGL_FULL_ACCELERATION_ARB);
- if (stereoVisual) {
- out.push_back(WGL_STEREO_ARB);
- out.push_back(GL_TRUE);
- }
+ if (stereoVisual) {
+ out.push_back(WGL_STEREO_ARB);
+ out.push_back(GL_TRUE);
+ }
- out.push_back(WGL_PIXEL_TYPE_ARB);
- out.push_back(WGL_TYPE_RGBA_ARB);
+ out.push_back(WGL_PIXEL_TYPE_ARB);
+ out.push_back(WGL_TYPE_RGBA_ARB);
- out.push_back(WGL_COLOR_BITS_ARB);
- out.push_back(24);
+ out.push_back(WGL_COLOR_BITS_ARB);
+ out.push_back(24);
- out.push_back(WGL_DEPTH_BITS_ARB);
- out.push_back(24);
+ out.push_back(WGL_DEPTH_BITS_ARB);
+ out.push_back(24);
- if (needAlpha) {
- out.push_back(WGL_ALPHA_BITS_ARB);
- out.push_back(8);
- }
+ if (needAlpha) {
+ out.push_back(WGL_ALPHA_BITS_ARB);
+ out.push_back(8);
+ }
- if (needStencil) {
- out.push_back(WGL_STENCIL_BITS_ARB);
- out.push_back(8);
- }
+ if (needStencil) {
+ out.push_back(WGL_STENCIL_BITS_ARB);
+ out.push_back(8);
+ }
- if (numOfAASamples > 0) {
- out.push_back(WGL_SAMPLES_ARB);
- out.push_back(numOfAASamples);
+ if (numOfAASamples > 0) {
+ out.push_back(WGL_SAMPLES_ARB);
+ out.push_back(numOfAASamples);
- out.push_back(WGL_SAMPLE_BUFFERS_ARB);
- out.push_back(GL_TRUE);
- }
+ out.push_back(WGL_SAMPLE_BUFFERS_ARB);
+ out.push_back(GL_TRUE);
+ }
- if (sRGB) {
- out.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
- out.push_back(GL_TRUE);
- }
+ if (sRGB) {
+ out.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
+ out.push_back(GL_TRUE);
+ }
- out.push_back(0);
+ out.push_back(0);
}
-
int GHOST_ContextWGL::_choose_pixel_format_arb_1(
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool sRGB)
+ bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB)
{
- std::vector<int> iAttributes;
+ std::vector<int> iAttributes;
#define _MAX_PIXEL_FORMATS 32
- int iPixelFormat = 0;
- int iPixelFormats[_MAX_PIXEL_FORMATS];
-
- int samples;
-
- // guard against some insanely high number of samples
- if (numOfAASamples > 64) {
- fprintf(stderr, "Warning! Clamping number of samples to 64.\n");
- samples = 64;
- }
- else {
- samples = numOfAASamples;
- }
-
- // request a format with as many samples as possible, but not more than requested
- while (samples >= 0) {
- makeAttribList(
- iAttributes,
- stereoVisual,
- samples,
- needAlpha,
- needStencil,
- sRGB);
-
- UINT nNumFormats;
- WIN32_CHK(wglChoosePixelFormatARB(m_hDC, &(iAttributes[0]), NULL, _MAX_PIXEL_FORMATS, iPixelFormats, &nNumFormats));
+ int iPixelFormat = 0;
+ int iPixelFormats[_MAX_PIXEL_FORMATS];
+
+ int samples;
+
+ // guard against some insanely high number of samples
+ if (numOfAASamples > 64) {
+ fprintf(stderr, "Warning! Clamping number of samples to 64.\n");
+ samples = 64;
+ }
+ else {
+ samples = numOfAASamples;
+ }
+
+ // request a format with as many samples as possible, but not more than requested
+ while (samples >= 0) {
+ makeAttribList(iAttributes, stereoVisual, samples, needAlpha, needStencil, sRGB);
+
+ UINT nNumFormats;
+ WIN32_CHK(wglChoosePixelFormatARB(
+ m_hDC, &(iAttributes[0]), NULL, _MAX_PIXEL_FORMATS, iPixelFormats, &nNumFormats));
#ifdef WIN32_COMPOSITING
- if (needAlpha && nNumFormats) {
- // scan through all pixel format to make sure one supports compositing
- PIXELFORMATDESCRIPTOR pfd;
- int i;
-
- for (i = 0; i < nNumFormats; i++) {
- if (DescribePixelFormat(m_hDC, iPixelFormats[i], sizeof(PIXELFORMATDESCRIPTOR), &pfd)) {
- if (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) {
- iPixelFormat = iPixelFormats[i];
- break;
- }
- }
- }
- if (i == nNumFormats) {
- fprintf(stderr,
- "Warning! Unable to find a pixel format with compositing capability.\n");
- iPixelFormat = iPixelFormats[0];
- }
- }
- else
+ if (needAlpha && nNumFormats) {
+ // scan through all pixel format to make sure one supports compositing
+ PIXELFORMATDESCRIPTOR pfd;
+ int i;
+
+ for (i = 0; i < nNumFormats; i++) {
+ if (DescribePixelFormat(m_hDC, iPixelFormats[i], sizeof(PIXELFORMATDESCRIPTOR), &pfd)) {
+ if (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) {
+ iPixelFormat = iPixelFormats[i];
+ break;
+ }
+ }
+ }
+ if (i == nNumFormats) {
+ fprintf(stderr, "Warning! Unable to find a pixel format with compositing capability.\n");
+ iPixelFormat = iPixelFormats[0];
+ }
+ }
+ else
#endif
- iPixelFormat = iPixelFormats[0];
- /* total number of formats that match (regardless of size of iPixelFormat array)
- * see: WGL_ARB_pixel_format extension spec */
- if (nNumFormats > 0)
- break;
-
- /* if not reset, then the state of iPixelFormat is undefined after call to wglChoosePixelFormatARB
- * see: WGL_ARB_pixel_format extension spec */
- iPixelFormat = 0;
-
- samples--;
- }
-
- // check how many samples were actually gotten
- if (iPixelFormat != 0) {
- int iQuery[] = { WGL_SAMPLES_ARB };
- int actualSamples, alphaBits;
- wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &actualSamples);
-
- if (actualSamples != numOfAASamples) {
- fprintf(stderr,
- "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
- "Substituting one that uses %d samples.\n",
- numOfAASamples, actualSamples);
- }
- if (needAlpha) {
- iQuery[0] = WGL_ALPHA_BITS_ARB;
- wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &alphaBits);
- if (alphaBits == 0) {
- fprintf(stderr,
- "Warning! Unable to find a frame buffer with alpha channel.\n");
- }
- }
- }
- return iPixelFormat;
+ iPixelFormat = iPixelFormats[0];
+ /* total number of formats that match (regardless of size of iPixelFormat array)
+ * see: WGL_ARB_pixel_format extension spec */
+ if (nNumFormats > 0)
+ break;
+
+ /* if not reset, then the state of iPixelFormat is undefined after call to wglChoosePixelFormatARB
+ * see: WGL_ARB_pixel_format extension spec */
+ iPixelFormat = 0;
+
+ samples--;
+ }
+
+ // check how many samples were actually gotten
+ if (iPixelFormat != 0) {
+ int iQuery[] = {WGL_SAMPLES_ARB};
+ int actualSamples, alphaBits;
+ wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &actualSamples);
+
+ if (actualSamples != numOfAASamples) {
+ fprintf(
+ stderr,
+ "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
+ "Substituting one that uses %d samples.\n",
+ numOfAASamples,
+ actualSamples);
+ }
+ if (needAlpha) {
+ iQuery[0] = WGL_ALPHA_BITS_ARB;
+ wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &alphaBits);
+ if (alphaBits == 0) {
+ fprintf(stderr, "Warning! Unable to find a frame buffer with alpha channel.\n");
+ }
+ }
+ }
+ return iPixelFormat;
}
-
int GHOST_ContextWGL::choose_pixel_format_arb(
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool sRGB)
+ bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB)
{
- int iPixelFormat;
+ int iPixelFormat;
- iPixelFormat = _choose_pixel_format_arb_1(
- stereoVisual,
- numOfAASamples,
- needAlpha,
- needStencil,
- sRGB);
+ iPixelFormat = _choose_pixel_format_arb_1(
+ stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB);
- if (iPixelFormat == 0 && stereoVisual) {
- fprintf(stderr, "Warning! Unable to find a stereo pixel format.\n");
+ if (iPixelFormat == 0 && stereoVisual) {
+ fprintf(stderr, "Warning! Unable to find a stereo pixel format.\n");
- iPixelFormat = _choose_pixel_format_arb_1(
- false,
- numOfAASamples,
- needAlpha,
- needStencil,
- sRGB);
+ iPixelFormat = _choose_pixel_format_arb_1(false, numOfAASamples, needAlpha, needStencil, sRGB);
- m_stereoVisual = false; // set context property to actual value
- }
+ m_stereoVisual = false; // set context property to actual value
+ }
- return iPixelFormat;
+ return iPixelFormat;
}
-
int GHOST_ContextWGL::choose_pixel_format(
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool sRGB)
+ bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB)
{
- PIXELFORMATDESCRIPTOR preferredPFD = {
- sizeof(PIXELFORMATDESCRIPTOR), /* size */
- 1, /* version */
- (DWORD) (
- PFD_SUPPORT_OPENGL |
- PFD_DRAW_TO_WINDOW |
- PFD_DOUBLEBUFFER | /* support double-buffering */
- (stereoVisual ? PFD_STEREO : 0) |/* support stereo */
- (
+ PIXELFORMATDESCRIPTOR preferredPFD = {
+ sizeof(PIXELFORMATDESCRIPTOR), /* size */
+ 1, /* version */
+ (DWORD)(
+ PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW |
+ PFD_DOUBLEBUFFER | /* support double-buffering */
+ (stereoVisual ? PFD_STEREO : 0) | /* support stereo */
+ (
#ifdef WIN32_COMPOSITING
- needAlpha ? PFD_SUPPORT_COMPOSITION : /* support composition for transparent background */
+ needAlpha ?
+ PFD_SUPPORT_COMPOSITION : /* support composition for transparent background */
#endif
- 0
- )),
- PFD_TYPE_RGBA, /* color type */
- (BYTE) (needAlpha ? 32 : 24), /* preferred color depth */
- 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
- (BYTE) (needAlpha ? 8 : 0), /* alpha buffer */
- 0, /* alpha shift (ignored) */
- 0, /* no accumulation buffer */
- 0, 0, 0, 0, /* accum bits (ignored) */
- 24, /* depth buffer */
- (BYTE) (needStencil ? 8 : 0), /* stencil buffer */
- 0, /* no auxiliary buffers */
- PFD_MAIN_PLANE, /* main layer */
- 0, /* reserved */
- 0, 0, 0 /* layer, visible, and damage masks (ignored) */
- };
-
- initContextWGLEW(preferredPFD);
-
- if (numOfAASamples > 0 && !WGLEW_ARB_multisample) {
- fprintf(stderr, "Warning! Unable to request a multisample framebuffer.\n");
- numOfAASamples = 0;
- }
-
- if (sRGB && !(WGLEW_ARB_framebuffer_sRGB || WGLEW_EXT_framebuffer_sRGB)) {
- fprintf(stderr, "Warning! Unable to request an sRGB framebuffer.\n");
- sRGB = false;
- }
-
- int iPixelFormat = 0;
-
- if (WGLEW_ARB_pixel_format)
- iPixelFormat = choose_pixel_format_arb(stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB);
-
- if (iPixelFormat == 0)
- iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD);
-
- return iPixelFormat;
+ 0)),
+ PFD_TYPE_RGBA, /* color type */
+ (BYTE)(needAlpha ? 32 : 24), /* preferred color depth */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* color bits (ignored) */
+ (BYTE)(needAlpha ? 8 : 0), /* alpha buffer */
+ 0, /* alpha shift (ignored) */
+ 0, /* no accumulation buffer */
+ 0,
+ 0,
+ 0,
+ 0, /* accum bits (ignored) */
+ 24, /* depth buffer */
+ (BYTE)(needStencil ? 8 : 0), /* stencil buffer */
+ 0, /* no auxiliary buffers */
+ PFD_MAIN_PLANE, /* main layer */
+ 0, /* reserved */
+ 0,
+ 0,
+ 0 /* layer, visible, and damage masks (ignored) */
+ };
+
+ initContextWGLEW(preferredPFD);
+
+ if (numOfAASamples > 0 && !WGLEW_ARB_multisample) {
+ fprintf(stderr, "Warning! Unable to request a multisample framebuffer.\n");
+ numOfAASamples = 0;
+ }
+
+ if (sRGB && !(WGLEW_ARB_framebuffer_sRGB || WGLEW_EXT_framebuffer_sRGB)) {
+ fprintf(stderr, "Warning! Unable to request an sRGB framebuffer.\n");
+ sRGB = false;
+ }
+
+ int iPixelFormat = 0;
+
+ if (WGLEW_ARB_pixel_format)
+ iPixelFormat = choose_pixel_format_arb(
+ stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB);
+
+ if (iPixelFormat == 0)
+ iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD);
+
+ return iPixelFormat;
}
-
#ifndef NDEBUG
static void reportContextString(const char *name, const char *dummy, const char *context)
{
- fprintf(stderr, "%s: %s\n", name, context);
+ fprintf(stderr, "%s: %s\n", name, context);
- if (dummy && strcmp(dummy, context) != 0)
- fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy);
+ if (dummy && strcmp(dummy, context) != 0)
+ fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy);
}
#endif
-
GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
{
- SetLastError(NO_ERROR);
+ SetLastError(NO_ERROR);
- HGLRC prevHGLRC = ::wglGetCurrentContext();
- WIN32_CHK(GetLastError() == NO_ERROR);
+ HGLRC prevHGLRC = ::wglGetCurrentContext();
+ WIN32_CHK(GetLastError() == NO_ERROR);
- HDC prevHDC = ::wglGetCurrentDC();
- WIN32_CHK(GetLastError() == NO_ERROR);
+ HDC prevHDC = ::wglGetCurrentDC();
+ WIN32_CHK(GetLastError() == NO_ERROR);
- if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) {
- const bool needAlpha = m_alphaBackground;
+ if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) {
+ const bool needAlpha = m_alphaBackground;
#ifdef GHOST_OPENGL_STENCIL
- const bool needStencil = true;
+ const bool needStencil = true;
#else
- const bool needStencil = false;
+ const bool needStencil = false;
#endif
#ifdef GHOST_OPENGL_SRGB
- const bool sRGB = true;
+ const bool sRGB = true;
#else
- const bool sRGB = false;
+ const bool sRGB = false;
#endif
- int iPixelFormat;
- int lastPFD;
+ int iPixelFormat;
+ int lastPFD;
- PIXELFORMATDESCRIPTOR chosenPFD;
+ PIXELFORMATDESCRIPTOR chosenPFD;
- iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB);
+ iPixelFormat = choose_pixel_format(
+ m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB);
- if (iPixelFormat == 0) {
- goto error;
- }
+ if (iPixelFormat == 0) {
+ goto error;
+ }
- lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
+ lastPFD = ::DescribePixelFormat(
+ m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
- if (!WIN32_CHK(lastPFD != 0)) {
- goto error;
- }
+ if (!WIN32_CHK(lastPFD != 0)) {
+ goto error;
+ }
- if (needAlpha && chosenPFD.cAlphaBits == 0)
- fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n");
+ if (needAlpha && chosenPFD.cAlphaBits == 0)
+ fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n");
- if (needStencil && chosenPFD.cStencilBits == 0)
- fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n");
+ if (needStencil && chosenPFD.cStencilBits == 0)
+ fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n");
- if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) {
- goto error;
- }
- }
+ if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) {
+ goto error;
+ }
+ }
- if (WGLEW_ARB_create_context) {
- int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
- int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ if (WGLEW_ARB_create_context) {
+ int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
#ifdef WITH_GLEW_ES
- int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT;
+ int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT;
#endif
- if (!WGLEW_ARB_create_context_profile && profileBitCore)
- fprintf(stderr, "Warning! OpenGL core profile not available.\n");
+ if (!WGLEW_ARB_create_context_profile && profileBitCore)
+ fprintf(stderr, "Warning! OpenGL core profile not available.\n");
- if (!WGLEW_ARB_create_context_profile && profileBitCompat)
- fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n");
+ if (!WGLEW_ARB_create_context_profile && profileBitCompat)
+ fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n");
#ifdef WITH_GLEW_ES
- if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
- fprintf(stderr, "Warning! OpenGL ES profile not available.\n");
+ if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
+ fprintf(stderr, "Warning! OpenGL ES profile not available.\n");
- if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
- fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n");
+ if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
+ fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n");
#endif
- int profileMask = 0;
+ int profileMask = 0;
- if (WGLEW_ARB_create_context_profile && profileBitCore)
- profileMask |= profileBitCore;
+ if (WGLEW_ARB_create_context_profile && profileBitCore)
+ profileMask |= profileBitCore;
- if (WGLEW_ARB_create_context_profile && profileBitCompat)
- profileMask |= profileBitCompat;
+ if (WGLEW_ARB_create_context_profile && profileBitCompat)
+ profileMask |= profileBitCompat;
#ifdef WITH_GLEW_ES
- if (WGLEW_EXT_create_context_es_profile && profileBitES)
- profileMask |= profileBitES;
+ if (WGLEW_EXT_create_context_es_profile && profileBitES)
+ profileMask |= profileBitES;
#endif
- if (profileMask != m_contextProfileMask)
- fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits.");
-
- std::vector<int> iAttributes;
-
- if (profileMask) {
- iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
- iAttributes.push_back(profileMask);
- }
-
- if (m_contextMajorVersion != 0) {
- iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
- iAttributes.push_back(m_contextMajorVersion);
- }
-
- if (m_contextMinorVersion != 0) {
- iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
- iAttributes.push_back(m_contextMinorVersion);
- }
-
- if (m_contextFlags != 0) {
- iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
- iAttributes.push_back(m_contextFlags);
- }
-
- if (m_contextResetNotificationStrategy != 0) {
- if (WGLEW_ARB_create_context_robustness) {
- iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
- iAttributes.push_back(m_contextResetNotificationStrategy);
- }
- else {
- fprintf(stderr, "Warning! Cannot set the reset notification strategy.");
- }
- }
-
- iAttributes.push_back(0);
-
- m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0]));
- }
-
- /* Silence warnings interpreted as errors by users when trying to get
- * a context with version higher than 3.3 Core. */
- const bool silent = m_contextMajorVersion > 3;
- if (!WIN32_CHK_SILENT(m_hGLRC != NULL, silent)) {
- goto error;
- }
-
- s_sharedCount++;
-
- if (s_sharedHGLRC == NULL) {
- s_sharedHGLRC = m_hGLRC;
- }
- else if (!WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) {
- goto error;
- }
-
- if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
- goto error;
- }
-
- initContextGLEW();
-
- if (is_crappy_intel_card()) {
- /* Some Intel cards with context 4.1 or 4.2
- * don't have the point sprite enabled by default.
- *
- * However GL_POINT_SPRITE was removed in 3.2 and is now permanently ON.
- * Then use brute force. */
- glEnable(GL_POINT_SPRITE);
- }
-
- initClearGL();
- ::SwapBuffers(m_hDC);
+ if (profileMask != m_contextProfileMask)
+ fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits.");
+
+ std::vector<int> iAttributes;
+
+ if (profileMask) {
+ iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
+ iAttributes.push_back(profileMask);
+ }
+
+ if (m_contextMajorVersion != 0) {
+ iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
+ iAttributes.push_back(m_contextMajorVersion);
+ }
+
+ if (m_contextMinorVersion != 0) {
+ iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
+ iAttributes.push_back(m_contextMinorVersion);
+ }
+
+ if (m_contextFlags != 0) {
+ iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
+ iAttributes.push_back(m_contextFlags);
+ }
+
+ if (m_contextResetNotificationStrategy != 0) {
+ if (WGLEW_ARB_create_context_robustness) {
+ iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
+ iAttributes.push_back(m_contextResetNotificationStrategy);
+ }
+ else {
+ fprintf(stderr, "Warning! Cannot set the reset notification strategy.");
+ }
+ }
+
+ iAttributes.push_back(0);
+
+ m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0]));
+ }
+
+ /* Silence warnings interpreted as errors by users when trying to get
+ * a context with version higher than 3.3 Core. */
+ const bool silent = m_contextMajorVersion > 3;
+ if (!WIN32_CHK_SILENT(m_hGLRC != NULL, silent)) {
+ goto error;
+ }
+
+ s_sharedCount++;
+
+ if (s_sharedHGLRC == NULL) {
+ s_sharedHGLRC = m_hGLRC;
+ }
+ else if (!WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) {
+ goto error;
+ }
+
+ if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
+ goto error;
+ }
+
+ initContextGLEW();
+
+ if (is_crappy_intel_card()) {
+ /* Some Intel cards with context 4.1 or 4.2
+ * don't have the point sprite enabled by default.
+ *
+ * However GL_POINT_SPRITE was removed in 3.2 and is now permanently ON.
+ * Then use brute force. */
+ glEnable(GL_POINT_SPRITE);
+ }
+
+ initClearGL();
+ ::SwapBuffers(m_hDC);
#ifndef NDEBUG
- const char *vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
- const char *renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
- const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
+ const char *vendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
+ const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
+ const char *version = reinterpret_cast<const char *>(glGetString(GL_VERSION));
- reportContextString("Vendor", m_dummyVendor, vendor);
- reportContextString("Renderer", m_dummyRenderer, renderer);
- reportContextString("Version", m_dummyVersion, version);
+ reportContextString("Vendor", m_dummyVendor, vendor);
+ reportContextString("Renderer", m_dummyRenderer, renderer);
+ reportContextString("Version", m_dummyVersion, version);
- fprintf(stderr, "Context Version: %d.%d\n", m_contextMajorVersion, m_contextMinorVersion);
+ fprintf(stderr, "Context Version: %d.%d\n", m_contextMajorVersion, m_contextMinorVersion);
#endif
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
error:
- ::wglMakeCurrent(prevHDC, prevHGLRC);
- return GHOST_kFailure;
-
+ ::wglMakeCurrent(prevHDC, prevHGLRC);
+ return GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_ContextWGL::releaseNativeHandles()
{
- GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess : GHOST_kFailure;
+ GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess :
+ GHOST_kFailure;
- m_hWnd = NULL;
- m_hDC = NULL;
+ m_hWnd = NULL;
+ m_hDC = NULL;
- return success;
+ return success;
}
diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h
index e96abbf5459..a3fd9de74a1 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.h
+++ b/intern/ghost/intern/GHOST_ContextWGL.h
@@ -31,122 +31,107 @@
#include <GL/wglew.h>
#ifndef GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
-#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0
+# define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0
#endif
-
-class GHOST_ContextWGL : public GHOST_Context
-{
-public:
- /**
- * Constructor.
- */
- GHOST_ContextWGL(
- bool stereoVisual,
- bool alphaBackground,
- GHOST_TUns16 numOfAASamples,
- HWND hWnd,
- HDC hDC,
- int contextProfileMask,
- int contextMajorVersion,
- int contextMinorVersion,
- int contextFlags,
- int contextResetNotificationStrategy);
-
- /**
- * Destructor.
- */
- ~GHOST_ContextWGL();
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess swapBuffers();
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess activateDrawingContext();
-
- /**
- * Release the drawing context of the calling thread.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess releaseDrawingContext();
-
- /**
- * Call immediately after new to initialize. If this fails then immediately delete the object.
- * \return Indication as to whether initialization has succeeded.
- */
- GHOST_TSuccess initializeDrawingContext();
-
- /**
- * Removes references to native handles from this context and then returns
- * \return GHOST_kSuccess if it is OK for the parent to release the handles and
- * GHOST_kFailure if releasing the handles will interfere with sharing
- */
- GHOST_TSuccess releaseNativeHandles();
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess setSwapInterval(int interval);
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \param intervalOut Variable to store the swap interval if it can be read.
- * \return Whether the swap interval can be read.
- */
- GHOST_TSuccess getSwapInterval(int &intervalOut);
-
-private:
- int choose_pixel_format(
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool sRGB);
-
- int choose_pixel_format_arb(
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool sRGB);
-
- int _choose_pixel_format_arb_1(
- bool stereoVisual,
- int numOfAASamples,
- bool needAlpha,
- bool needStencil,
- bool sRGB);
-
- void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD);
-
- HWND m_hWnd;
- HDC m_hDC;
-
- const int m_contextProfileMask;
- const int m_contextMajorVersion;
- const int m_contextMinorVersion;
- const int m_contextFlags;
- const bool m_alphaBackground;
- const int m_contextResetNotificationStrategy;
-
- HGLRC m_hGLRC;
+class GHOST_ContextWGL : public GHOST_Context {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_ContextWGL(bool stereoVisual,
+ bool alphaBackground,
+ GHOST_TUns16 numOfAASamples,
+ HWND hWnd,
+ HDC hDC,
+ int contextProfileMask,
+ int contextMajorVersion,
+ int contextMinorVersion,
+ int contextFlags,
+ int contextResetNotificationStrategy);
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_ContextWGL();
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess swapBuffers();
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess activateDrawingContext();
+
+ /**
+ * Release the drawing context of the calling thread.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess releaseDrawingContext();
+
+ /**
+ * Call immediately after new to initialize. If this fails then immediately delete the object.
+ * \return Indication as to whether initialization has succeeded.
+ */
+ GHOST_TSuccess initializeDrawingContext();
+
+ /**
+ * Removes references to native handles from this context and then returns
+ * \return GHOST_kSuccess if it is OK for the parent to release the handles and
+ * GHOST_kFailure if releasing the handles will interfere with sharing
+ */
+ GHOST_TSuccess releaseNativeHandles();
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess setSwapInterval(int interval);
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \param intervalOut Variable to store the swap interval if it can be read.
+ * \return Whether the swap interval can be read.
+ */
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
+
+ private:
+ int choose_pixel_format(
+ bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB);
+
+ int choose_pixel_format_arb(
+ bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB);
+
+ int _choose_pixel_format_arb_1(
+ bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB);
+
+ void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD);
+
+ HWND m_hWnd;
+ HDC m_hDC;
+
+ const int m_contextProfileMask;
+ const int m_contextMajorVersion;
+ const int m_contextMinorVersion;
+ const int m_contextFlags;
+ const bool m_alphaBackground;
+ const int m_contextResetNotificationStrategy;
+
+ HGLRC m_hGLRC;
#ifndef NDEBUG
- const char *m_dummyVendor;
- const char *m_dummyRenderer;
- const char *m_dummyVersion;
+ const char *m_dummyVendor;
+ const char *m_dummyRenderer;
+ const char *m_dummyVersion;
#endif
- static HGLRC s_sharedHGLRC;
- static int s_sharedCount;
+ static HGLRC s_sharedHGLRC;
+ static int s_sharedCount;
};
#endif // __GHOST_CONTEXTWGL_H__
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index 2351935f16b..0163197e14a 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -27,52 +27,61 @@
#ifdef _MSC_VER
# ifdef DEBUG
- /* Suppress stl-MSVC debug info warning. */
-# pragma warning (disable:4786)
+/* Suppress stl-MSVC debug info warning. */
+# pragma warning(disable : 4786)
# endif
#endif
#ifdef WITH_GHOST_DEBUG
-# define GHOST_DEBUG // spit ghost events to stdout
-#endif // WITH_GHOST_DEBUG
+# define GHOST_DEBUG // spit ghost events to stdout
+#endif // WITH_GHOST_DEBUG
#ifdef GHOST_DEBUG
# include <iostream>
-# include <stdio.h> //for printf()
-#endif // GHOST_DEBUG
-
+# include <stdio.h> //for printf()
+#endif // GHOST_DEBUG
#ifdef GHOST_DEBUG
-# define GHOST_PRINT(x) { std::cout << x; } (void)0
-# define GHOST_PRINTF(x, ...) { printf(x, __VA_ARGS__); } (void)0
+# define GHOST_PRINT(x) \
+ { \
+ std::cout << x; \
+ } \
+ (void)0
+# define GHOST_PRINTF(x, ...) \
+ { \
+ printf(x, __VA_ARGS__); \
+ } \
+ (void)0
#else // GHOST_DEBUG
# define GHOST_PRINT(x)
# define GHOST_PRINTF(x, ...)
-#endif // GHOST_DEBUG
+#endif // GHOST_DEBUG
#ifdef WITH_ASSERT_ABORT
-# include <stdio.h> //for fprintf()
-# include <stdlib.h> //for abort()
-# define GHOST_ASSERT(x, info) \
- { \
- if (!(x)) { \
- fprintf(stderr, "GHOST_ASSERT failed: "); \
- fprintf(stderr, info); \
- fprintf(stderr, "\n"); \
- abort(); \
- } \
- } (void)0
+# include <stdio.h> //for fprintf()
+# include <stdlib.h> //for abort()
+# define GHOST_ASSERT(x, info) \
+ { \
+ if (!(x)) { \
+ fprintf(stderr, "GHOST_ASSERT failed: "); \
+ fprintf(stderr, info); \
+ fprintf(stderr, "\n"); \
+ abort(); \
+ } \
+ } \
+ (void)0
#elif defined(GHOST_DEBUG)
-# define GHOST_ASSERT(x, info) \
- { \
- if (!(x)) { \
- GHOST_PRINT("GHOST_ASSERT failed: "); \
- GHOST_PRINT(info); \
- GHOST_PRINT("\n"); \
- } \
- } (void)0
+# define GHOST_ASSERT(x, info) \
+ { \
+ if (!(x)) { \
+ GHOST_PRINT("GHOST_ASSERT failed: "); \
+ GHOST_PRINT(info); \
+ GHOST_PRINT("\n"); \
+ } \
+ } \
+ (void)0
#else // GHOST_DEBUG
# define GHOST_ASSERT(x, info) ((void)0)
-#endif // GHOST_DEBUG
+#endif // GHOST_DEBUG
-#endif // __GHOST_DEBUG_H__
+#endif // __GHOST_DEBUG_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp
index 30dc78f063a..d8321bb1732 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManager.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
@@ -29,183 +28,156 @@
#include "GHOST_DisplayManager.h"
#include "GHOST_Debug.h"
-
-GHOST_DisplayManager::GHOST_DisplayManager(void)
- : m_settingsInitialized(false)
+GHOST_DisplayManager::GHOST_DisplayManager(void) : m_settingsInitialized(false)
{
}
-
GHOST_DisplayManager::~GHOST_DisplayManager(void)
{
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::initialize(
- void)
+GHOST_TSuccess GHOST_DisplayManager::initialize(void)
{
- GHOST_TSuccess success;
- if (!m_settingsInitialized) {
- success = initializeSettings();
- m_settingsInitialized = true;
- }
- else {
- success = GHOST_kSuccess;
- }
- return success;
+ GHOST_TSuccess success;
+ if (!m_settingsInitialized) {
+ success = initializeSettings();
+ m_settingsInitialized = true;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::getNumDisplays(
- GHOST_TUns8& /*numDisplays*/) const
+GHOST_TSuccess GHOST_DisplayManager::getNumDisplays(GHOST_TUns8 & /*numDisplays*/) const
{
- // Don't know if we have a display...
- return GHOST_kFailure;
+ // Don't know if we have a display...
+ return GHOST_kFailure;
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::getNumDisplaySettings(
- GHOST_TUns8 display,
- GHOST_TInt32& numSettings) const
+GHOST_TSuccess GHOST_DisplayManager::getNumDisplaySettings(GHOST_TUns8 display,
+ GHOST_TInt32 &numSettings) const
{
- GHOST_TSuccess success;
-
- GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false");
- GHOST_TUns8 numDisplays;
- success = getNumDisplays(numDisplays);
- if (success == GHOST_kSuccess) {
- if (display < numDisplays) {
- numSettings = m_settings[display].size();
- }
- else {
- success = GHOST_kFailure;
- }
- }
- return success;
+ GHOST_TSuccess success;
+
+ GHOST_ASSERT(m_settingsInitialized,
+ "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false");
+ GHOST_TUns8 numDisplays;
+ success = getNumDisplays(numDisplays);
+ if (success == GHOST_kSuccess) {
+ if (display < numDisplays) {
+ numSettings = m_settings[display].size();
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::getDisplaySetting(
- GHOST_TUns8 display,
- GHOST_TInt32 index,
- GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManager::getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const
{
- GHOST_TSuccess success;
-
- GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false");
- GHOST_TUns8 numDisplays;
- success = getNumDisplays(numDisplays);
- if (success == GHOST_kSuccess) {
- if (display < numDisplays && ((GHOST_TUns8)index < m_settings[display].size())) {
- setting = m_settings[display][index];
- }
- else {
- success = GHOST_kFailure;
- }
- }
- return success;
+ GHOST_TSuccess success;
+
+ GHOST_ASSERT(m_settingsInitialized,
+ "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false");
+ GHOST_TUns8 numDisplays;
+ success = getNumDisplays(numDisplays);
+ if (success == GHOST_kSuccess) {
+ if (display < numDisplays && ((GHOST_TUns8)index < m_settings[display].size())) {
+ setting = m_settings[display][index];
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::getCurrentDisplaySetting(
- GHOST_TUns8 /*display*/,
- GHOST_DisplaySetting& /*setting*/) const
+GHOST_TSuccess GHOST_DisplayManager::getCurrentDisplaySetting(
+ GHOST_TUns8 /*display*/, GHOST_DisplaySetting & /*setting*/) const
{
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::setCurrentDisplaySetting(
- GHOST_TUns8 /*display*/,
- const GHOST_DisplaySetting& /*setting*/)
+GHOST_TSuccess GHOST_DisplayManager::setCurrentDisplaySetting(
+ GHOST_TUns8 /*display*/, const GHOST_DisplaySetting & /*setting*/)
{
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::findMatch(
- GHOST_TUns8 display,
- const GHOST_DisplaySetting& setting,
- GHOST_DisplaySetting& match) const
+GHOST_TSuccess GHOST_DisplayManager::findMatch(GHOST_TUns8 display,
+ const GHOST_DisplaySetting &setting,
+ GHOST_DisplaySetting &match) const
{
- GHOST_TSuccess success = GHOST_kSuccess;
- GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::findMatch(): m_settingsInitialized=false");
-
- int criteria[4] = {
- (int)setting.xPixels,
- (int)setting.yPixels,
- (int)setting.bpp,
- (int)setting.frequency
- };
- int capabilities[4];
- double field, score;
- double best = 1e12; // A big number
- int found = 0;
-
- // Look at all the display modes
- for (int i = 0; (i < (int)m_settings[display].size()); i++) {
- // Store the capabilities of the display device
- capabilities[0] = m_settings[display][i].xPixels;
- capabilities[1] = m_settings[display][i].yPixels;
- capabilities[2] = m_settings[display][i].bpp;
- capabilities[3] = m_settings[display][i].frequency;
-
- // Match against all the fields of the display settings
- score = 0;
- for (int j = 0; j < 4; j++) {
- field = capabilities[j] - criteria[j];
- score += field * field;
- }
-
- if (score < best) {
- found = i;
- best = score;
- }
- }
-
- match = m_settings[display][found];
-
- GHOST_PRINT("GHOST_DisplayManager::findMatch(): settings of match:\n");
- GHOST_PRINT(" setting.xPixels=" << match.xPixels << "\n");
- GHOST_PRINT(" setting.yPixels=" << match.yPixels << "\n");
- GHOST_PRINT(" setting.bpp=" << match.bpp << "\n");
- GHOST_PRINT(" setting.frequency=" << match.frequency << "\n");
-
- return success;
+ GHOST_TSuccess success = GHOST_kSuccess;
+ GHOST_ASSERT(m_settingsInitialized,
+ "GHOST_DisplayManager::findMatch(): m_settingsInitialized=false");
+
+ int criteria[4] = {
+ (int)setting.xPixels, (int)setting.yPixels, (int)setting.bpp, (int)setting.frequency};
+ int capabilities[4];
+ double field, score;
+ double best = 1e12; // A big number
+ int found = 0;
+
+ // Look at all the display modes
+ for (int i = 0; (i < (int)m_settings[display].size()); i++) {
+ // Store the capabilities of the display device
+ capabilities[0] = m_settings[display][i].xPixels;
+ capabilities[1] = m_settings[display][i].yPixels;
+ capabilities[2] = m_settings[display][i].bpp;
+ capabilities[3] = m_settings[display][i].frequency;
+
+ // Match against all the fields of the display settings
+ score = 0;
+ for (int j = 0; j < 4; j++) {
+ field = capabilities[j] - criteria[j];
+ score += field * field;
+ }
+
+ if (score < best) {
+ found = i;
+ best = score;
+ }
+ }
+
+ match = m_settings[display][found];
+
+ GHOST_PRINT("GHOST_DisplayManager::findMatch(): settings of match:\n");
+ GHOST_PRINT(" setting.xPixels=" << match.xPixels << "\n");
+ GHOST_PRINT(" setting.yPixels=" << match.yPixels << "\n");
+ GHOST_PRINT(" setting.bpp=" << match.bpp << "\n");
+ GHOST_PRINT(" setting.frequency=" << match.frequency << "\n");
+
+ return success;
}
-
-GHOST_TSuccess
-GHOST_DisplayManager::initializeSettings(
- void)
+GHOST_TSuccess GHOST_DisplayManager::initializeSettings(void)
{
- GHOST_TUns8 numDisplays;
- GHOST_TSuccess success = getNumDisplays(numDisplays);
- if (success == GHOST_kSuccess) {
- for (GHOST_TUns8 display = 0; (display < numDisplays) && (success == GHOST_kSuccess); display++) {
- GHOST_DisplaySettings displaySettings;
- m_settings.push_back(displaySettings);
- GHOST_TInt32 numSettings;
- success = getNumDisplaySettings(display, numSettings);
- if (success == GHOST_kSuccess) {
- GHOST_TInt32 index;
- GHOST_DisplaySetting setting;
- for (index = 0; (index < numSettings) && (success == GHOST_kSuccess); index++) {
- success = getDisplaySetting(display, index, setting);
- m_settings[display].push_back(setting);
- }
- }
- else {
- break;
- }
- }
- }
- return success;
+ GHOST_TUns8 numDisplays;
+ GHOST_TSuccess success = getNumDisplays(numDisplays);
+ if (success == GHOST_kSuccess) {
+ for (GHOST_TUns8 display = 0; (display < numDisplays) && (success == GHOST_kSuccess);
+ display++) {
+ GHOST_DisplaySettings displaySettings;
+ m_settings.push_back(displaySettings);
+ GHOST_TInt32 numSettings;
+ success = getNumDisplaySettings(display, numSettings);
+ if (success == GHOST_kSuccess) {
+ GHOST_TInt32 index;
+ GHOST_DisplaySetting setting;
+ for (index = 0; (index < numSettings) && (success == GHOST_kSuccess); index++) {
+ success = getDisplaySetting(display, index, setting);
+ m_settings[display].push_back(setting);
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ return success;
}
diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h
index 67ab14d2cf9..58b36c0035b 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.h
+++ b/intern/ghost/intern/GHOST_DisplayManager.h
@@ -32,103 +32,100 @@
/**
* Manages system displays (platform independent implementation).
*/
-class GHOST_DisplayManager
-{
-public:
- enum { kMainDisplay = 0 };
- /**
- * Constructor.
- */
- GHOST_DisplayManager(void);
-
- /**
- * Destructor.
- */
- virtual ~GHOST_DisplayManager(void);
-
- /**
- * Initializes the list with devices and settings.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess initialize(void);
-
- /**
- * Returns the number of display devices on this system.
- * \param numDisplays The number of displays on this system.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
-
- /**
- * Returns the number of display settings for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param numSettings The number of settings of the display device with this index.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display,
- GHOST_TInt32& numSettings) const;
-
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param index The setting index to be returned.
- * \param setting The setting of the display device with this index.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display,
- GHOST_TInt32 index,
- GHOST_DisplaySetting& setting) const;
-
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The current setting of the display device with this index.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display,
- GHOST_DisplaySetting& setting) const;
-
- /**
- * Changes the current setting for this display device.
- * The setting given to this method is matched against the available display settings.
- * The best match is activated (@see findMatch()).
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The setting of the display device to be matched and activated.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display,
- const GHOST_DisplaySetting& setting);
-
-protected:
- typedef std::vector<GHOST_DisplaySetting> GHOST_DisplaySettings;
-
- /**
- * Finds the best display settings match.
- * \param display The index of the display device.
- * \param setting The setting to match.
- * \param match The optimal display setting.
- * \return Indication of success.
- */
- GHOST_TSuccess findMatch(GHOST_TUns8 display,
- const GHOST_DisplaySetting& setting,
- GHOST_DisplaySetting& match) const;
-
- /**
- * Retrieves settings for each display device and stores them.
- * \return Indication of success.
- */
- GHOST_TSuccess initializeSettings(void);
-
- /** Tells whether the list of display modes has been stored already. */
- bool m_settingsInitialized;
- /** The list with display settings for the main display. */
- std::vector<GHOST_DisplaySettings> m_settings;
-
+class GHOST_DisplayManager {
+ public:
+ enum { kMainDisplay = 0 };
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManager(void);
+
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_DisplayManager(void);
+
+ /**
+ * Initializes the list with devices and settings.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess initialize(void);
+
+ /**
+ * Returns the number of display devices on this system.
+ * \param numDisplays The number of displays on this system.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const;
+
+ /**
+ * Returns the number of display settings for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param numSettings The number of settings of the display device with this index.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display,
+ GHOST_TInt32 &numSettings) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param index The setting index to be returned.
+ * \param setting The setting of the display device with this index.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The current setting of the display device with this index.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display,
+ GHOST_DisplaySetting &setting) const;
+
+ /**
+ * Changes the current setting for this display device.
+ * The setting given to this method is matched against the available display settings.
+ * The best match is activated (@see findMatch()).
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The setting of the display device to be matched and activated.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display,
+ const GHOST_DisplaySetting &setting);
+
+ protected:
+ typedef std::vector<GHOST_DisplaySetting> GHOST_DisplaySettings;
+
+ /**
+ * Finds the best display settings match.
+ * \param display The index of the display device.
+ * \param setting The setting to match.
+ * \param match The optimal display setting.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess findMatch(GHOST_TUns8 display,
+ const GHOST_DisplaySetting &setting,
+ GHOST_DisplaySetting &match) const;
+
+ /**
+ * Retrieves settings for each display device and stores them.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess initializeSettings(void);
+
+ /** Tells whether the list of display modes has been stored already. */
+ bool m_settingsInitialized;
+ /** The list with display settings for the main display. */
+ std::vector<GHOST_DisplaySettings> m_settings;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DisplayManager")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DisplayManager")
#endif
};
-
-#endif // __GHOST_DISPLAYMANAGER_H__
+#endif // __GHOST_DISPLAYMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
index 5300cd0b50b..cfdc7be357e 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
@@ -26,8 +26,8 @@
#define __GHOST_DISPLAYMANAGERCOCOA_H__
#ifndef __APPLE__
-#error Apple only!
-#endif // __APPLE__
+# error Apple only!
+#endif // __APPLE__
#include "GHOST_DisplayManager.h"
@@ -35,61 +35,63 @@
* Manages system displays (Mac OSX/Cocoa implementation).
* \see GHOST_DisplayManager
*/
-class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager
-{
-public:
- /**
- * Constructor.
- */
- GHOST_DisplayManagerCocoa(void);
+class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManagerCocoa(void);
- /**
- * Returns the number of display devices on this system.
- * \param numDisplays The number of displays on this system.
- * \return Indication of success.
- */
- GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+ /**
+ * Returns the number of display devices on this system.
+ * \param numDisplays The number of displays on this system.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const;
- /**
- * Returns the number of display settings for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param numSetting: The number of settings of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+ /**
+ * Returns the number of display settings for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param numSetting: The number of settings of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const;
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param index The setting index to be returned.
- * \param setting The setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param index The setting index to be returned.
+ * \param setting The setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const;
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The current setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The current setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display,
+ GHOST_DisplaySetting &setting) const;
- /**
- * Changes the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The current setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+ /**
+ * Changes the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The current setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display,
+ const GHOST_DisplaySetting &setting);
-protected:
- //Do not cache values as OS X supports screen hot plug
- /** Cached number of displays. */
- //CGDisplayCount m_numDisplays;
- /** Cached display id's for each display. */
- //CGDirectDisplayID* m_displayIDs;
+ protected:
+ //Do not cache values as OS X supports screen hot plug
+ /** Cached number of displays. */
+ //CGDisplayCount m_numDisplays;
+ /** Cached display id's for each display. */
+ //CGDirectDisplayID* m_displayIDs;
};
-
-#endif // __GHOST_DISPLAYMANAGERCOCOA_H__
+#endif // __GHOST_DISPLAYMANAGERCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
index 74508e1345a..7f44a14f49c 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
- Damien Plisson 10/2009
+ Damien Plisson 10/2009
*/
#include <Cocoa/Cocoa.h>
@@ -25,130 +25,141 @@
// We do not support multiple monitors at the moment
-
GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void)
{
}
-
-GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8 &numDisplays) const
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- numDisplays = (GHOST_TUns8) [[NSScreen screens] count];
+ numDisplays = (GHOST_TUns8)[[NSScreen screens] count];
- [pool drain];
- return GHOST_kSuccess;
+ [pool drain];
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display,
+ GHOST_TInt32 &numSettings) const
{
- numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel
+ numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const
{
- NSScreen *askedDisplay;
+ NSScreen *askedDisplay;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if (display == kMainDisplay) //Screen #0 may not be the main one
- askedDisplay = [NSScreen mainScreen];
- else
- askedDisplay = [[NSScreen screens] objectAtIndex:display];
+ if (display == kMainDisplay) //Screen #0 may not be the main one
+ askedDisplay = [NSScreen mainScreen];
+ else
+ askedDisplay = [[NSScreen screens] objectAtIndex:display];
- if (askedDisplay == nil) {
- [pool drain];
- return GHOST_kFailure;
- }
+ if (askedDisplay == nil) {
+ [pool drain];
+ return GHOST_kFailure;
+ }
- NSRect frame = [askedDisplay visibleFrame];
- setting.xPixels = frame.size.width;
- setting.yPixels = frame.size.height;
+ NSRect frame = [askedDisplay visibleFrame];
+ setting.xPixels = frame.size.width;
+ setting.yPixels = frame.size.height;
- setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
+ setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
- setting.frequency = 0; //No more CRT display...
+ setting.frequency = 0; //No more CRT display...
#ifdef GHOST_DEBUG
- printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
-#endif // GHOST_DEBUG
-
- [pool drain];
- return GHOST_kSuccess;
+ printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n",
+ setting.xPixels,
+ setting.yPixels,
+ setting.bpp,
+ setting.frequency);
+#endif // GHOST_DEBUG
+
+ [pool drain];
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(
+ GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
{
- NSScreen *askedDisplay;
+ NSScreen *askedDisplay;
- GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported");
+ GHOST_ASSERT(
+ (display == kMainDisplay),
+ "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if (display == kMainDisplay) //Screen #0 may not be the main one
- askedDisplay = [NSScreen mainScreen];
- else
- askedDisplay = [[NSScreen screens] objectAtIndex:display];
+ if (display == kMainDisplay) //Screen #0 may not be the main one
+ askedDisplay = [NSScreen mainScreen];
+ else
+ askedDisplay = [[NSScreen screens] objectAtIndex:display];
- if (askedDisplay == nil) {
- [pool drain];
- return GHOST_kFailure;
- }
+ if (askedDisplay == nil) {
+ [pool drain];
+ return GHOST_kFailure;
+ }
- NSRect frame = [askedDisplay visibleFrame];
- setting.xPixels = frame.size.width;
- setting.yPixels = frame.size.height;
+ NSRect frame = [askedDisplay visibleFrame];
+ setting.xPixels = frame.size.width;
+ setting.yPixels = frame.size.height;
- setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
+ setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
- setting.frequency = 0; //No more CRT display...
+ setting.frequency = 0; //No more CRT display...
#ifdef GHOST_DEBUG
- printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
-#endif // GHOST_DEBUG
-
- [pool drain];
- return GHOST_kSuccess;
+ printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n",
+ setting.xPixels,
+ setting.yPixels,
+ setting.bpp,
+ setting.frequency);
+#endif // GHOST_DEBUG
+
+ [pool drain];
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
+GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(
+ GHOST_TUns8 display, const GHOST_DisplaySetting &setting)
{
- GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported");
+ GHOST_ASSERT(
+ (display == kMainDisplay),
+ "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported");
#ifdef GHOST_DEBUG
- printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): requested settings:\n");
- printf(" setting.xPixels=%d\n", setting.xPixels);
- printf(" setting.yPixels=%d\n", setting.yPixels);
- printf(" setting.bpp=%d\n", setting.bpp);
- printf(" setting.frequency=%d\n", setting.frequency);
-#endif // GHOST_DEBUG
-
- //Display configuration is no more available in 10.6
-
-/* CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
- m_displayIDs[display],
- (size_t)setting.bpp,
- (size_t)setting.xPixels,
- (size_t)setting.yPixels,
- (CGRefreshRate)setting.frequency,
- NULL);*/
+ printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): requested settings:\n");
+ printf(" setting.xPixels=%d\n", setting.xPixels);
+ printf(" setting.yPixels=%d\n", setting.yPixels);
+ printf(" setting.bpp=%d\n", setting.bpp);
+ printf(" setting.frequency=%d\n", setting.frequency);
+#endif // GHOST_DEBUG
+
+ //Display configuration is no more available in 10.6
+
+ /* CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
+ m_displayIDs[display],
+ (size_t)setting.bpp,
+ (size_t)setting.xPixels,
+ (size_t)setting.yPixels,
+ (CGRefreshRate)setting.frequency,
+ NULL);*/
#ifdef GHOST_DEBUG
-/* printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
- printf(" setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
- printf(" setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
- printf(" setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
- printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate)); */
-#endif // GHOST_DEBUG
+/* printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
+ printf(" setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
+ printf(" setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
+ printf(" setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
+ printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate)); */
+#endif // GHOST_DEBUG
- //CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
+ //CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
- return /*err == CGDisplayNoErr ?*/ GHOST_kSuccess /*: GHOST_kFailure*/;
+ return /*err == CGDisplayNoErr ?*/ GHOST_kSuccess /*: GHOST_kFailure*/;
}
diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h
index 13bd777c2f9..266a3e9a699 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerNULL.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h
@@ -27,18 +27,36 @@
class GHOST_SystemNULL;
-class GHOST_DisplayManagerNULL : public GHOST_DisplayManager
-{
-public:
- GHOST_DisplayManagerNULL( GHOST_SystemNULL *system ) : GHOST_DisplayManager(), m_system(system) { /* nop */ }
- GHOST_TSuccess getNumDisplays( GHOST_TUns8& numDisplays ) const { return GHOST_kFailure; }
- GHOST_TSuccess getNumDisplaySettings( GHOST_TUns8 display, GHOST_TInt32& numSettings ) const{ return GHOST_kFailure; }
- GHOST_TSuccess getDisplaySetting( GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting ) const { return GHOST_kFailure; }
- GHOST_TSuccess getCurrentDisplaySetting( GHOST_TUns8 display, GHOST_DisplaySetting& setting ) const { return getDisplaySetting(display,GHOST_TInt32(0),setting); }
- GHOST_TSuccess setCurrentDisplaySetting( GHOST_TUns8 display, const GHOST_DisplaySetting& setting ) { return GHOST_kSuccess; }
+class GHOST_DisplayManagerNULL : public GHOST_DisplayManager {
+ public:
+ GHOST_DisplayManagerNULL(GHOST_SystemNULL *system) : GHOST_DisplayManager(), m_system(system)
+ { /* nop */
+ }
+ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const
+ {
+ return GHOST_kFailure;
+ }
+ GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const
+ {
+ return GHOST_kFailure;
+ }
+ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const
+ {
+ return GHOST_kFailure;
+ }
+ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
+ {
+ return getDisplaySetting(display, GHOST_TInt32(0), setting);
+ }
+ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting &setting)
+ {
+ return GHOST_kSuccess;
+ }
-private:
- GHOST_SystemNULL * m_system;
+ private:
+ GHOST_SystemNULL *m_system;
};
#endif /* __GHOST_DISPLAYMANAGERNULL_H__ */
diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
index 2b2c1e39e95..059f04992fb 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
@@ -28,151 +28,141 @@
#include "GHOST_WindowManager.h"
GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system)
- : GHOST_DisplayManager(),
- m_system(system)
+ : GHOST_DisplayManager(), m_system(system)
{
- memset(&m_mode, 0, sizeof(m_mode));
+ memset(&m_mode, 0, sizeof(m_mode));
}
-GHOST_TSuccess
-GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) const
+GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8 &numDisplays) const
{
- numDisplays = SDL_GetNumVideoDisplays();
- return GHOST_kSuccess;
+ numDisplays = SDL_GetNumVideoDisplays();
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display,
- GHOST_TInt32& numSettings) const
+ GHOST_TInt32 &numSettings) const
{
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- numSettings = SDL_GetNumDisplayModes(display - 1);
+ numSettings = SDL_GetNumDisplayModes(display - 1);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-static void ghost_mode_from_sdl(GHOST_DisplaySetting& setting, SDL_DisplayMode *mode)
+static void ghost_mode_from_sdl(GHOST_DisplaySetting &setting, SDL_DisplayMode *mode)
{
- setting.xPixels = mode->w;
- setting.yPixels = mode->h;
- setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8;
- /* Just guess the frequency :( */
- setting.frequency = mode->refresh_rate ? mode->refresh_rate : 60;
+ setting.xPixels = mode->w;
+ setting.yPixels = mode->h;
+ setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8;
+ /* Just guess the frequency :( */
+ setting.frequency = mode->refresh_rate ? mode->refresh_rate : 60;
}
-static void ghost_mode_to_sdl(const GHOST_DisplaySetting& setting, SDL_DisplayMode *mode)
+static void ghost_mode_to_sdl(const GHOST_DisplaySetting &setting, SDL_DisplayMode *mode)
{
- mode->w = setting.xPixels;
- mode->h = setting.yPixels;
- // setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8; ???
- mode->refresh_rate = setting.frequency;
+ mode->w = setting.xPixels;
+ mode->h = setting.yPixels;
+ // setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8; ???
+ mode->refresh_rate = setting.frequency;
}
-GHOST_TSuccess
-GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display,
- GHOST_TInt32 index,
- GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const
{
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- SDL_DisplayMode mode;
- SDL_GetDisplayMode(display, index, &mode);
+ SDL_DisplayMode mode;
+ SDL_GetDisplayMode(display, index, &mode);
- ghost_mode_from_sdl(setting, &mode);
+ ghost_mode_from_sdl(setting, &mode);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display,
- GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplaySetting(
+ GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
{
- SDL_DisplayMode mode;
- SDL_GetCurrentDisplayMode(display, &mode);
+ SDL_DisplayMode mode;
+ SDL_GetCurrentDisplayMode(display, &mode);
- ghost_mode_from_sdl(setting, &mode);
+ ghost_mode_from_sdl(setting, &mode);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_DisplayManagerSDL::getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const
+GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const
{
- mode = m_mode;
- return GHOST_kSuccess;
+ mode = m_mode;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display,
- const GHOST_DisplaySetting& setting)
+GHOST_TSuccess GHOST_DisplayManagerSDL::setCurrentDisplaySetting(
+ GHOST_TUns8 display, const GHOST_DisplaySetting &setting)
{
- /*
- * Mode switching code ported from Quake 2 version 3.21 and bzflag version
- * 2.4.0:
- * ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
- * See linux/gl_glx.c:GLimp_SetMode
- * http://wiki.bzflag.org/BZFlag_Source
- * See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow
- */
- SDL_DisplayMode mode;
- const int num_modes = SDL_GetNumDisplayModes(display);
- int best_fit, best_dist, dist, x, y;
-
- best_dist = 9999999;
- best_fit = -1;
-
- if (num_modes == 0) {
- /* Any mode is OK. */
- ghost_mode_to_sdl(setting, &mode);
- }
- else {
- for (int i = 0; i < num_modes; i++) {
-
- SDL_GetDisplayMode(display, i, &mode);
-
- if (setting.xPixels > mode.w ||
- setting.yPixels > mode.h)
- {
- continue;
- }
-
- x = setting.xPixels - mode.w;
- y = setting.yPixels - mode.h;
- dist = (x * x) + (y * y);
- if (dist < best_dist) {
- best_dist = dist;
- best_fit = i;
- }
- }
-
- if (best_fit == -1)
- return GHOST_kFailure;
-
- SDL_GetDisplayMode(display, best_fit, &mode);
- }
-
- m_mode = mode;
-
- /* evil, SDL2 needs a window to adjust display modes */
- GHOST_WindowSDL *win = (GHOST_WindowSDL *)m_system->getWindowManager()->getActiveWindow();
-
- if (win) {
- SDL_Window *sdl_win = win->getSDLWindow();
-
-
- SDL_SetWindowDisplayMode(sdl_win, &mode);
- SDL_ShowWindow(sdl_win);
- SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
-
- return GHOST_kSuccess;
- }
- else {
- /* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point.
- * we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */
- printf("no windows available, cant fullscreen\n");
-
- /* do not fail, we will try again later when the window is created - wander */
- return GHOST_kSuccess;
- }
+ /*
+ * Mode switching code ported from Quake 2 version 3.21 and bzflag version
+ * 2.4.0:
+ * ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
+ * See linux/gl_glx.c:GLimp_SetMode
+ * http://wiki.bzflag.org/BZFlag_Source
+ * See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow
+ */
+ SDL_DisplayMode mode;
+ const int num_modes = SDL_GetNumDisplayModes(display);
+ int best_fit, best_dist, dist, x, y;
+
+ best_dist = 9999999;
+ best_fit = -1;
+
+ if (num_modes == 0) {
+ /* Any mode is OK. */
+ ghost_mode_to_sdl(setting, &mode);
+ }
+ else {
+ for (int i = 0; i < num_modes; i++) {
+
+ SDL_GetDisplayMode(display, i, &mode);
+
+ if (setting.xPixels > mode.w || setting.yPixels > mode.h) {
+ continue;
+ }
+
+ x = setting.xPixels - mode.w;
+ y = setting.yPixels - mode.h;
+ dist = (x * x) + (y * y);
+ if (dist < best_dist) {
+ best_dist = dist;
+ best_fit = i;
+ }
+ }
+
+ if (best_fit == -1)
+ return GHOST_kFailure;
+
+ SDL_GetDisplayMode(display, best_fit, &mode);
+ }
+
+ m_mode = mode;
+
+ /* evil, SDL2 needs a window to adjust display modes */
+ GHOST_WindowSDL *win = (GHOST_WindowSDL *)m_system->getWindowManager()->getActiveWindow();
+
+ if (win) {
+ SDL_Window *sdl_win = win->getSDLWindow();
+
+ SDL_SetWindowDisplayMode(sdl_win, &mode);
+ SDL_ShowWindow(sdl_win);
+ SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
+
+ return GHOST_kSuccess;
+ }
+ else {
+ /* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point.
+ * we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */
+ printf("no windows available, cant fullscreen\n");
+
+ /* do not fail, we will try again later when the window is created - wander */
+ return GHOST_kSuccess;
+ }
}
diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.h b/intern/ghost/intern/GHOST_DisplayManagerSDL.h
index 913eaf17bb0..f7704d57ab0 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerSDL.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.h
@@ -25,7 +25,7 @@
#include "GHOST_DisplayManager.h"
extern "C" {
- #include "SDL.h"
+#include "SDL.h"
}
#if !SDL_VERSION_ATLEAST(2, 0, 0)
@@ -34,37 +34,29 @@ extern "C" {
class GHOST_SystemSDL;
-class GHOST_DisplayManagerSDL : public GHOST_DisplayManager
-{
-public:
- GHOST_DisplayManagerSDL(GHOST_SystemSDL *system);
+class GHOST_DisplayManagerSDL : public GHOST_DisplayManager {
+ public:
+ GHOST_DisplayManagerSDL(GHOST_SystemSDL *system);
- GHOST_TSuccess
- getNumDisplays(GHOST_TUns8& numDisplays) const;
+ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const;
- GHOST_TSuccess
- getNumDisplaySettings(GHOST_TUns8 display,
- GHOST_TInt32& numSettings) const;
+ GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const;
- GHOST_TSuccess
- getDisplaySetting(GHOST_TUns8 display,
- GHOST_TInt32 index,
- GHOST_DisplaySetting& setting) const;
+ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const;
- GHOST_TSuccess
- getCurrentDisplaySetting(GHOST_TUns8 display,
- GHOST_DisplaySetting& setting) const;
+ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display,
+ GHOST_DisplaySetting &setting) const;
- GHOST_TSuccess
- getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const;
+ GHOST_TSuccess getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const;
- GHOST_TSuccess
- setCurrentDisplaySetting(GHOST_TUns8 display,
- const GHOST_DisplaySetting& setting);
+ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display,
+ const GHOST_DisplaySetting &setting);
-private:
- GHOST_SystemSDL *m_system;
- SDL_DisplayMode m_mode;
+ private:
+ GHOST_SystemSDL *m_system;
+ SDL_DisplayMode m_mode;
};
#endif /* __GHOST_DISPLAYMANAGERSDL_H__ */
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
index da47fe9a65c..3b28f055191 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
@@ -25,7 +25,7 @@
#include "GHOST_Debug.h"
#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -33,22 +33,20 @@
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>
-
GHOST_DisplayManagerWin32::GHOST_DisplayManagerWin32(void)
{
}
-
-GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8& numDisplays) const
+GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8 &numDisplays) const
{
- numDisplays = ::GetSystemMetrics(SM_CMONITORS);
- return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
+ numDisplays = ::GetSystemMetrics(SM_CMONITORS);
+ return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
}
static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd)
{
- dd->cb = sizeof(DISPLAY_DEVICE);
- return ::EnumDisplayDevices(NULL, d, dd, 0);
+ dd->cb = sizeof(DISPLAY_DEVICE);
+ return ::EnumDisplayDevices(NULL, d, dd, 0);
}
/*
@@ -58,125 +56,134 @@ static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd)
* the information that was cached the last time the function was called with iModeNum
* set to zero.
*/
-GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
+GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display,
+ GHOST_TInt32 &numSettings) const
{
- DISPLAY_DEVICE display_device;
- if (!get_dd(display, &display_device)) return GHOST_kFailure;
-
- numSettings = 0;
- DEVMODE dm;
- while (::EnumDisplaySettings(display_device.DeviceName, numSettings, &dm)) {
- numSettings++;
- }
- return GHOST_kSuccess;
+ DISPLAY_DEVICE display_device;
+ if (!get_dd(display, &display_device))
+ return GHOST_kFailure;
+
+ numSettings = 0;
+ DEVMODE dm;
+ while (::EnumDisplaySettings(display_device.DeviceName, numSettings, &dm)) {
+ numSettings++;
+ }
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const
{
- DISPLAY_DEVICE display_device;
- if (!get_dd(display, &display_device)) return GHOST_kFailure;
+ DISPLAY_DEVICE display_device;
+ if (!get_dd(display, &display_device))
+ return GHOST_kFailure;
- GHOST_TSuccess success;
- DEVMODE dm;
- if (::EnumDisplaySettings(display_device.DeviceName, index, &dm)) {
+ GHOST_TSuccess success;
+ DEVMODE dm;
+ if (::EnumDisplaySettings(display_device.DeviceName, index, &dm)) {
#ifdef GHOST_DEBUG
- printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency);
-#endif // GHOST_DEBUG
- setting.xPixels = dm.dmPelsWidth;
- setting.yPixels = dm.dmPelsHeight;
- setting.bpp = dm.dmBitsPerPel;
- /* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
- * may return with the value 0 or 1. These values represent the display hardware's
- * default refresh rate. This default rate is typically set by switches on a display
- * card or computer motherboard, or by a configuration program that does not use
- * Win32 display functions such as ChangeDisplaySettings.
- */
- /* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
- * returned 0 or 1 but this doesn't work since later on an exact match will
- * be searched. And this will never happen if we change it to 60. Now we rely
- * on the default h/w setting.
- */
- setting.frequency = dm.dmDisplayFrequency;
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n",
+ dm.dmPelsWidth,
+ dm.dmPelsHeight,
+ dm.dmBitsPerPel,
+ dm.dmDisplayFrequency);
+#endif // GHOST_DEBUG
+ setting.xPixels = dm.dmPelsWidth;
+ setting.yPixels = dm.dmPelsHeight;
+ setting.bpp = dm.dmBitsPerPel;
+ /* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
+ * may return with the value 0 or 1. These values represent the display hardware's
+ * default refresh rate. This default rate is typically set by switches on a display
+ * card or computer motherboard, or by a configuration program that does not use
+ * Win32 display functions such as ChangeDisplaySettings.
+ */
+ /* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
+ * returned 0 or 1 but this doesn't work since later on an exact match will
+ * be searched. And this will never happen if we change it to 60. Now we rely
+ * on the default h/w setting.
+ */
+ setting.frequency = dm.dmDisplayFrequency;
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
-GHOST_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting(
+ GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
{
- return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting);
+ return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting);
}
-
-GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
+GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(
+ GHOST_TUns8 display, const GHOST_DisplaySetting &setting)
{
- DISPLAY_DEVICE display_device;
- if (!get_dd(display, &display_device)) return GHOST_kFailure;
-
- GHOST_DisplaySetting match;
- findMatch(display, setting, match);
- DEVMODE dm;
- int i = 0;
- while (::EnumDisplaySettings(display_device.DeviceName, i++, &dm)) {
- if ((dm.dmBitsPerPel == match.bpp ) &&
- (dm.dmPelsWidth == match.xPixels) &&
- (dm.dmPelsHeight == match.yPixels) &&
- (dm.dmDisplayFrequency == match.frequency))
- {
- break;
- }
- }
- /*
- * dm.dmBitsPerPel = match.bpp;
- * dm.dmPelsWidth = match.xPixels;
- * dm.dmPelsHeight = match.yPixels;
- * dm.dmDisplayFrequency = match.frequency;
- * dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
- * dm.dmSize = sizeof(DEVMODE);
- * dm.dmDriverExtra = 0;
- */
+ DISPLAY_DEVICE display_device;
+ if (!get_dd(display, &display_device))
+ return GHOST_kFailure;
+
+ GHOST_DisplaySetting match;
+ findMatch(display, setting, match);
+ DEVMODE dm;
+ int i = 0;
+ while (::EnumDisplaySettings(display_device.DeviceName, i++, &dm)) {
+ if ((dm.dmBitsPerPel == match.bpp) && (dm.dmPelsWidth == match.xPixels) &&
+ (dm.dmPelsHeight == match.yPixels) && (dm.dmDisplayFrequency == match.frequency)) {
+ break;
+ }
+ }
+ /*
+ * dm.dmBitsPerPel = match.bpp;
+ * dm.dmPelsWidth = match.xPixels;
+ * dm.dmPelsHeight = match.yPixels;
+ * dm.dmDisplayFrequency = match.frequency;
+ * dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
+ * dm.dmSize = sizeof(DEVMODE);
+ * dm.dmDriverExtra = 0;
+ */
#ifdef GHOST_DEBUG
- printf("display change: Requested settings:\n");
- printf(" dmBitsPerPel=%d\n", dm.dmBitsPerPel);
- printf(" dmPelsWidth=%d\n", dm.dmPelsWidth);
- printf(" dmPelsHeight=%d\n", dm.dmPelsHeight);
- printf(" dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
-#endif // GHOST_DEBUG
-
- LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
+ printf("display change: Requested settings:\n");
+ printf(" dmBitsPerPel=%d\n", dm.dmBitsPerPel);
+ printf(" dmPelsWidth=%d\n", dm.dmPelsWidth);
+ printf(" dmPelsHeight=%d\n", dm.dmPelsHeight);
+ printf(" dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
+#endif // GHOST_DEBUG
+
+ LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
#ifdef GHOST_DEBUG
- switch (status) {
- case DISP_CHANGE_SUCCESSFUL:
- printf("display change: The settings change was successful.\n");
- break;
- case DISP_CHANGE_RESTART:
- printf("display change: The computer must be restarted in order for the graphics mode to work.\n");
- break;
- case DISP_CHANGE_BADFLAGS:
- printf("display change: An invalid set of flags was passed in.\n");
- break;
- case DISP_CHANGE_BADPARAM:
- printf("display change: An invalid parameter was passed in. "
- "This can include an invalid flag or combination of flags.\n");
- break;
- case DISP_CHANGE_FAILED:
- printf("display change: The display driver failed the specified graphics mode.\n");
- break;
- case DISP_CHANGE_BADMODE:
- printf("display change: The graphics mode is not supported.\n");
- break;
- case DISP_CHANGE_NOTUPDATED:
- printf("display change: Windows NT: Unable to write settings to the registry.\n");
- break;
- default:
- printf("display change: Return value invalid\n");
- break;
- }
-#endif // GHOST_DEBUG
- return status == DISP_CHANGE_SUCCESSFUL ? GHOST_kSuccess : GHOST_kFailure;
+ switch (status) {
+ case DISP_CHANGE_SUCCESSFUL:
+ printf("display change: The settings change was successful.\n");
+ break;
+ case DISP_CHANGE_RESTART:
+ printf(
+ "display change: The computer must be restarted in order for the graphics mode to "
+ "work.\n");
+ break;
+ case DISP_CHANGE_BADFLAGS:
+ printf("display change: An invalid set of flags was passed in.\n");
+ break;
+ case DISP_CHANGE_BADPARAM:
+ printf(
+ "display change: An invalid parameter was passed in. "
+ "This can include an invalid flag or combination of flags.\n");
+ break;
+ case DISP_CHANGE_FAILED:
+ printf("display change: The display driver failed the specified graphics mode.\n");
+ break;
+ case DISP_CHANGE_BADMODE:
+ printf("display change: The graphics mode is not supported.\n");
+ break;
+ case DISP_CHANGE_NOTUPDATED:
+ printf("display change: Windows NT: Unable to write settings to the registry.\n");
+ break;
+ default:
+ printf("display change: Return value invalid\n");
+ break;
+ }
+#endif // GHOST_DEBUG
+ return status == DISP_CHANGE_SUCCESSFUL ? GHOST_kSuccess : GHOST_kFailure;
}
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
index 857f96d7cef..c4ad90b1de7 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
@@ -26,65 +26,66 @@
#define __GHOST_DISPLAYMANAGERWIN32_H__
#ifndef WIN32
-#error WIN32 only!
-#endif // WIN32
+# error WIN32 only!
+#endif // WIN32
#include "GHOST_DisplayManager.h"
-
/**
* Manages system displays (WIN32 implementation).
*/
-class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager
-{
-public:
- /**
- * Constructor.
- */
- GHOST_DisplayManagerWin32(void);
+class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManagerWin32(void);
- /**
- * Returns the number of display devices on this system.
- * \param numDisplays The number of displays on this system.
- * \return Indication of success.
- */
- GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+ /**
+ * Returns the number of display devices on this system.
+ * \param numDisplays The number of displays on this system.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const;
- /**
- * Returns the number of display settings for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param numSetting: The number of settings of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+ /**
+ * Returns the number of display settings for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param numSetting: The number of settings of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const;
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param index The setting index to be returned.
- * \param setting The setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param index The setting index to be returned.
+ * \param setting The setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const;
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The current setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The current setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display,
+ GHOST_DisplaySetting &setting) const;
- /**
- * Changes the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The current setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+ /**
+ * Changes the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The current setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display,
+ const GHOST_DisplaySetting &setting);
-protected:
+ protected:
};
-
-#endif // __GHOST_DISPLAYMANAGERWIN32_H__
+#endif // __GHOST_DISPLAYMANAGERWIN32_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
index 1500da8028e..4626955ac7f 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -32,238 +32,209 @@
#include "GHOST_DisplayManagerX11.h"
#include "GHOST_SystemX11.h"
-
-GHOST_DisplayManagerX11::
-GHOST_DisplayManagerX11(
- GHOST_SystemX11 *system)
- : GHOST_DisplayManager(),
- m_system(system)
+GHOST_DisplayManagerX11::GHOST_DisplayManagerX11(GHOST_SystemX11 *system)
+ : GHOST_DisplayManager(), m_system(system)
{
- /* nothing to do. */
+ /* nothing to do. */
}
-GHOST_TSuccess
-GHOST_DisplayManagerX11::
-getNumDisplays(GHOST_TUns8& numDisplays) const
+GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplays(GHOST_TUns8 &numDisplays) const
{
- numDisplays = m_system->getNumDisplays();
- return GHOST_kSuccess;
+ numDisplays = m_system->getNumDisplays();
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess
-GHOST_DisplayManagerX11::
-getNumDisplaySettings(
- GHOST_TUns8 display,
- GHOST_TInt32& numSettings) const
+GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplaySettings(GHOST_TUns8 display,
+ GHOST_TInt32 &numSettings) const
{
#ifdef WITH_X11_XF86VMODE
- int majorVersion, minorVersion;
- XF86VidModeModeInfo **vidmodes;
- Display *dpy = m_system->getXDisplay();
+ int majorVersion, minorVersion;
+ XF86VidModeModeInfo **vidmodes;
+ Display *dpy = m_system->getXDisplay();
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- if (dpy == NULL)
- return GHOST_kFailure;
+ if (dpy == NULL)
+ return GHOST_kFailure;
- majorVersion = minorVersion = 0;
- if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
- fprintf(stderr, "Error: XF86VidMode extension missing!\n");
- return GHOST_kFailure;
- }
+ majorVersion = minorVersion = 0;
+ if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+ fprintf(stderr, "Error: XF86VidMode extension missing!\n");
+ return GHOST_kFailure;
+ }
- if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
- XFree(vidmodes);
- }
+ if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
+ XFree(vidmodes);
+ }
#else
- /* We only have one X11 setting at the moment. */
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- numSettings = 1;
+ /* We only have one X11 setting at the moment. */
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ numSettings = 1;
#endif
- (void) display;
- return GHOST_kSuccess;
+ (void)display;
+ return GHOST_kSuccess;
}
/* from SDL2 */
#ifdef WITH_X11_XF86VMODE
-static int
-calculate_rate(XF86VidModeModeInfo *info)
+static int calculate_rate(XF86VidModeModeInfo *info)
{
- return (info->htotal
- && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
- info->vtotal)) : 0;
+ return (info->htotal && info->vtotal) ? (1000 * info->dotclock / (info->htotal * info->vtotal)) :
+ 0;
}
#endif
-GHOST_TSuccess
-GHOST_DisplayManagerX11::
-getDisplaySetting(
- GHOST_TUns8 display,
- GHOST_TInt32 index,
- GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerX11::getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const
{
- Display *dpy = m_system->getXDisplay();
+ Display *dpy = m_system->getXDisplay();
- if (dpy == NULL)
- return GHOST_kFailure;
+ if (dpy == NULL)
+ return GHOST_kFailure;
- (void)display;
+ (void)display;
#ifdef WITH_X11_XF86VMODE
- int majorVersion, minorVersion;
-
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
-
- majorVersion = minorVersion = 0;
- if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
- XF86VidModeModeInfo **vidmodes;
- int numSettings;
-
- if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
- GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");
-
- setting.xPixels = vidmodes[index]->hdisplay;
- setting.yPixels = vidmodes[index]->vdisplay;
- setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
- setting.frequency = calculate_rate(vidmodes[index]);
- XFree(vidmodes);
-
- return GHOST_kSuccess;
- }
- }
- else {
- fprintf(stderr, "Warning: XF86VidMode extension missing!\n");
- /* fallback to non xf86vmode below */
- }
-#endif /* WITH_X11_XF86VMODE */
-
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
- (void)index;
-
- setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy));
- setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy));
- setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
- setting.frequency = 60.0f;
-
- return GHOST_kSuccess;
+ int majorVersion, minorVersion;
+
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+
+ majorVersion = minorVersion = 0;
+ if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+ XF86VidModeModeInfo **vidmodes;
+ int numSettings;
+
+ if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
+ GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");
+
+ setting.xPixels = vidmodes[index]->hdisplay;
+ setting.yPixels = vidmodes[index]->vdisplay;
+ setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
+ setting.frequency = calculate_rate(vidmodes[index]);
+ XFree(vidmodes);
+
+ return GHOST_kSuccess;
+ }
+ }
+ else {
+ fprintf(stderr, "Warning: XF86VidMode extension missing!\n");
+ /* fallback to non xf86vmode below */
+ }
+#endif /* WITH_X11_XF86VMODE */
+
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
+ (void)index;
+
+ setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy));
+ setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy));
+ setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
+ setting.frequency = 60.0f;
+
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_DisplayManagerX11::
-getCurrentDisplaySetting(
- GHOST_TUns8 display,
- GHOST_DisplaySetting& setting) const
+GHOST_TSuccess GHOST_DisplayManagerX11::getCurrentDisplaySetting(
+ GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
{
- /* According to the xf86vidmodegetallmodelines man page,
- * "The first element of the array corresponds to the current video mode."
- */
- return getDisplaySetting(display, 0, setting);
+ /* According to the xf86vidmodegetallmodelines man page,
+ * "The first element of the array corresponds to the current video mode."
+ */
+ return getDisplaySetting(display, 0, setting);
}
-
-GHOST_TSuccess
-GHOST_DisplayManagerX11::
-setCurrentDisplaySetting(
- GHOST_TUns8 /*display*/,
- const GHOST_DisplaySetting& setting)
+GHOST_TSuccess GHOST_DisplayManagerX11::setCurrentDisplaySetting(
+ GHOST_TUns8 /*display*/, const GHOST_DisplaySetting &setting)
{
#ifdef WITH_X11_XF86VMODE
- /* Mode switching code ported from SDL:
- * See: src/video/x11/SDL_x11modes.c:set_best_resolution
- */
- int majorVersion, minorVersion;
- XF86VidModeModeInfo **vidmodes;
- Display *dpy = m_system->getXDisplay();
- int scrnum, num_vidmodes;
-
- if (dpy == NULL)
- return GHOST_kFailure;
-
- scrnum = DefaultScreen(dpy);
-
- /* Get video mode list */
- majorVersion = minorVersion = 0;
- if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
- fprintf(stderr, "Error: XF86VidMode extension missing!\n");
- return GHOST_kFailure;
- }
+ /* Mode switching code ported from SDL:
+ * See: src/video/x11/SDL_x11modes.c:set_best_resolution
+ */
+ int majorVersion, minorVersion;
+ XF86VidModeModeInfo **vidmodes;
+ Display *dpy = m_system->getXDisplay();
+ int scrnum, num_vidmodes;
+
+ if (dpy == NULL)
+ return GHOST_kFailure;
+
+ scrnum = DefaultScreen(dpy);
+
+ /* Get video mode list */
+ majorVersion = minorVersion = 0;
+ if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+ fprintf(stderr, "Error: XF86VidMode extension missing!\n");
+ return GHOST_kFailure;
+ }
# ifdef DEBUG
- printf("Using XFree86-VidModeExtension Version %d.%d\n",
- majorVersion, minorVersion);
+ printf("Using XFree86-VidModeExtension Version %d.%d\n", majorVersion, minorVersion);
# endif
- if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) {
- int best_fit = -1;
-
- for (int i = 0; i < num_vidmodes; i++) {
- if (vidmodes[i]->hdisplay < setting.xPixels ||
- vidmodes[i]->vdisplay < setting.yPixels)
- {
- continue;
- }
-
- if (best_fit == -1 ||
- (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) ||
- (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay &&
- vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay))
- {
- best_fit = i;
- continue;
- }
-
- if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) &&
- (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay))
- {
- if (!setting.frequency) {
- /* Higher is better, right? */
- if (calculate_rate(vidmodes[i]) >
- calculate_rate(vidmodes[best_fit]))
- {
- best_fit = i;
- }
- }
- else {
- if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) <
- abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency))
- {
- best_fit = i;
- }
- }
- }
- }
-
- if (best_fit != -1) {
+ if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) {
+ int best_fit = -1;
+
+ for (int i = 0; i < num_vidmodes; i++) {
+ if (vidmodes[i]->hdisplay < setting.xPixels || vidmodes[i]->vdisplay < setting.yPixels) {
+ continue;
+ }
+
+ if (best_fit == -1 || (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) ||
+ (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay &&
+ vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay)) {
+ best_fit = i;
+ continue;
+ }
+
+ if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) &&
+ (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay)) {
+ if (!setting.frequency) {
+ /* Higher is better, right? */
+ if (calculate_rate(vidmodes[i]) > calculate_rate(vidmodes[best_fit])) {
+ best_fit = i;
+ }
+ }
+ else {
+ if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) <
+ abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency)) {
+ best_fit = i;
+ }
+ }
+ }
+ }
+
+ if (best_fit != -1) {
# ifdef DEBUG
- printf("Switching to video mode %dx%d %dx%d %d\n",
- vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay,
- vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal,
- calculate_rate(vidmodes[best_fit]));
+ printf("Switching to video mode %dx%d %dx%d %d\n",
+ vidmodes[best_fit]->hdisplay,
+ vidmodes[best_fit]->vdisplay,
+ vidmodes[best_fit]->htotal,
+ vidmodes[best_fit]->vtotal,
+ calculate_rate(vidmodes[best_fit]));
# endif
- /* change to the mode */
- XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
+ /* change to the mode */
+ XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
- /* Move the viewport to top left */
- XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
- }
+ /* Move the viewport to top left */
+ XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
+ }
- XFree(vidmodes);
- }
- else {
- return GHOST_kFailure;
- }
+ XFree(vidmodes);
+ }
+ else {
+ return GHOST_kFailure;
+ }
- XFlush(dpy);
- return GHOST_kSuccess;
+ XFlush(dpy);
+ return GHOST_kSuccess;
#else
- (void)setting;
+ (void)setting;
- /* Just pretend the request was successful. */
- return GHOST_kSuccess;
+ /* Just pretend the request was successful. */
+ return GHOST_kSuccess;
#endif
}
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.h b/intern/ghost/intern/GHOST_DisplayManagerX11.h
index 9b28f6cc42e..941152aa034 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.h
@@ -27,86 +27,64 @@
#include "GHOST_DisplayManager.h"
-
class GHOST_SystemX11;
/**
* Manages system displays (X11 implementation).
*/
-class GHOST_DisplayManagerX11 : public GHOST_DisplayManager
-{
-public:
- /**
- * Constructor.
- */
- GHOST_DisplayManagerX11(
- GHOST_SystemX11 *system
- );
-
- /**
- * Returns the number of display devices on this system.
- * \param numDisplays The number of displays on this system.
- * \return Indication of success.
- */
- GHOST_TSuccess
- getNumDisplays(
- GHOST_TUns8& numDisplays
- ) const;
+class GHOST_DisplayManagerX11 : public GHOST_DisplayManager {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManagerX11(GHOST_SystemX11 *system);
- /**
- * Returns the number of display settings for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param numSetting: The number of settings of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess
- getNumDisplaySettings(
- GHOST_TUns8 display,
- GHOST_TInt32& numSettings
- ) const;
+ /**
+ * Returns the number of display devices on this system.
+ * \param numDisplays The number of displays on this system.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const;
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param index The setting index to be returned.
- * \param setting The setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess
- getDisplaySetting(
- GHOST_TUns8 display,
- GHOST_TInt32 index,
- GHOST_DisplaySetting& setting
- ) const;
+ /**
+ * Returns the number of display settings for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param numSetting: The number of settings of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const;
- /**
- * Returns the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The current setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess
- getCurrentDisplaySetting(
- GHOST_TUns8 display,
- GHOST_DisplaySetting& setting
- ) const;
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param index The setting index to be returned.
+ * \param setting The setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display,
+ GHOST_TInt32 index,
+ GHOST_DisplaySetting &setting) const;
- /**
- * Changes the current setting for this display device.
- * \param display The index of the display to query with 0 <= display < getNumDisplays().
- * \param setting The current setting of the display device with this index.
- * \return Indication of success.
- */
- GHOST_TSuccess
- setCurrentDisplaySetting(
- GHOST_TUns8 display,
- const GHOST_DisplaySetting& setting
- );
+ /**
+ * Returns the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The current setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display,
+ GHOST_DisplaySetting &setting) const;
-private:
+ /**
+ * Changes the current setting for this display device.
+ * \param display The index of the display to query with 0 <= display < getNumDisplays().
+ * \param setting The current setting of the display device with this index.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display,
+ const GHOST_DisplaySetting &setting);
- GHOST_SystemX11 *m_system;
+ private:
+ GHOST_SystemX11 *m_system;
};
-
-#endif //
+#endif //
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
index 014b8ab13d0..b41a133a069 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
#include "GHOST_Debug.h"
#include "GHOST_DropTargetWin32.h"
#include <shellapi.h>
@@ -32,54 +31,48 @@
#ifdef GHOST_DEBUG
// utility
void printLastError(void);
-#endif // GHOST_DEBUG
-
+#endif // GHOST_DEBUG
-GHOST_DropTargetWin32::GHOST_DropTargetWin32(
- GHOST_WindowWin32 *window,
- GHOST_SystemWin32 *system)
- : m_window(window),
- m_system(system)
+GHOST_DropTargetWin32::GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system)
+ : m_window(window), m_system(system)
{
- m_cRef = 1;
- m_hWnd = window->getHWND();
- m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+ m_cRef = 1;
+ m_hWnd = window->getHWND();
+ m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
}
GHOST_DropTargetWin32::~GHOST_DropTargetWin32()
{
}
-
/*
* IUnknown::QueryInterface
*/
HRESULT __stdcall GHOST_DropTargetWin32::QueryInterface(REFIID riid, void **ppvObj)
{
- if (!ppvObj)
- return E_INVALIDARG;
- *ppvObj = NULL;
-
- if (riid == IID_IUnknown || riid == IID_IDropTarget) {
- AddRef();
- *ppvObj = (void *)this;
- return S_OK;
- }
- else {
- *ppvObj = NULL;
- return E_NOINTERFACE;
- }
+ if (!ppvObj)
+ return E_INVALIDARG;
+ *ppvObj = NULL;
+
+ if (riid == IID_IUnknown || riid == IID_IDropTarget) {
+ AddRef();
+ *ppvObj = (void *)this;
+ return S_OK;
+ }
+ else {
+ *ppvObj = NULL;
+ return E_NOINTERFACE;
+ }
}
-
/*
* IUnknown::AddRef
*/
ULONG __stdcall GHOST_DropTargetWin32::AddRef(void)
{
- return ::InterlockedIncrement(&m_cRef);
+ return ::InterlockedIncrement(&m_cRef);
}
/*
@@ -87,29 +80,33 @@ ULONG __stdcall GHOST_DropTargetWin32::AddRef(void)
*/
ULONG __stdcall GHOST_DropTargetWin32::Release(void)
{
- ULONG refs = ::InterlockedDecrement(&m_cRef);
-
- if (refs == 0) {
- delete this;
- return 0;
- }
- else {
- return refs;
- }
+ ULONG refs = ::InterlockedDecrement(&m_cRef);
+
+ if (refs == 0) {
+ delete this;
+ return 0;
+ }
+ else {
+ return refs;
+ }
}
/*
* Implementation of IDropTarget::DragEnter
*/
-HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
+HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject,
+ DWORD grfKeyState,
+ POINTL pt,
+ DWORD *pdwEffect)
{
- // we accept all drop by default
- m_window->setAcceptDragOperation(true);
- *pdwEffect = DROPEFFECT_NONE;
-
- m_draggedObjectType = getGhostType(pDataObject);
- m_system->pushDragDropEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, m_window, pt.x, pt.y, NULL);
- return S_OK;
+ // we accept all drop by default
+ m_window->setAcceptDragOperation(true);
+ *pdwEffect = DROPEFFECT_NONE;
+
+ m_draggedObjectType = getGhostType(pDataObject);
+ m_system->pushDragDropEvent(
+ GHOST_kEventDraggingEntered, m_draggedObjectType, m_window, pt.x, pt.y, NULL);
+ return S_OK;
}
/*
@@ -117,15 +114,16 @@ HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject, DWO
*/
HRESULT __stdcall GHOST_DropTargetWin32::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
- if (m_window->canAcceptDragOperation()) {
- *pdwEffect = allowedDropEffect(*pdwEffect);
- }
- else {
- *pdwEffect = DROPEFFECT_NONE;
- // *pdwEffect = DROPEFFECT_COPY; // XXX Uncomment to test drop. Drop will not be called if pdwEffect == DROPEFFECT_NONE.
- }
- m_system->pushDragDropEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, m_window, pt.x, pt.y, NULL);
- return S_OK;
+ if (m_window->canAcceptDragOperation()) {
+ *pdwEffect = allowedDropEffect(*pdwEffect);
+ }
+ else {
+ *pdwEffect = DROPEFFECT_NONE;
+ // *pdwEffect = DROPEFFECT_COPY; // XXX Uncomment to test drop. Drop will not be called if pdwEffect == DROPEFFECT_NONE.
+ }
+ m_system->pushDragDropEvent(
+ GHOST_kEventDraggingUpdated, m_draggedObjectType, m_window, pt.x, pt.y, NULL);
+ return S_OK;
}
/*
@@ -133,30 +131,34 @@ HRESULT __stdcall GHOST_DropTargetWin32::DragOver(DWORD grfKeyState, POINTL pt,
*/
HRESULT __stdcall GHOST_DropTargetWin32::DragLeave(void)
{
- m_system->pushDragDropEvent(GHOST_kEventDraggingExited, m_draggedObjectType, m_window, 0, 0, NULL);
- m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
- return S_OK;
+ m_system->pushDragDropEvent(
+ GHOST_kEventDraggingExited, m_draggedObjectType, m_window, 0, 0, NULL);
+ m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+ return S_OK;
}
/* Implementation of IDropTarget::Drop
* This function will not be called if pdwEffect is set to DROPEFFECT_NONE in
* the implementation of IDropTarget::DragOver
*/
-HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
+HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject,
+ DWORD grfKeyState,
+ POINTL pt,
+ DWORD *pdwEffect)
{
- void *data = getGhostData(pDataObject);
- if (m_window->canAcceptDragOperation()) {
- *pdwEffect = allowedDropEffect(*pdwEffect);
-
- }
- else {
- *pdwEffect = DROPEFFECT_NONE;
- }
- if (data)
- m_system->pushDragDropEvent(GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, pt.x, pt.y, data);
-
- m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
- return S_OK;
+ void *data = getGhostData(pDataObject);
+ if (m_window->canAcceptDragOperation()) {
+ *pdwEffect = allowedDropEffect(*pdwEffect);
+ }
+ else {
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+ if (data)
+ m_system->pushDragDropEvent(
+ GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, pt.x, pt.y, data);
+
+ m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+ return S_OK;
}
/*
@@ -165,222 +167,214 @@ HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject, DWORD gr
DWORD GHOST_DropTargetWin32::allowedDropEffect(DWORD dwAllowed)
{
- DWORD dwEffect = DROPEFFECT_NONE;
- if (dwAllowed & DROPEFFECT_COPY)
- dwEffect = DROPEFFECT_COPY;
+ DWORD dwEffect = DROPEFFECT_NONE;
+ if (dwAllowed & DROPEFFECT_COPY)
+ dwEffect = DROPEFFECT_COPY;
- return dwEffect;
+ return dwEffect;
}
GHOST_TDragnDropTypes GHOST_DropTargetWin32::getGhostType(IDataObject *pDataObject)
{
- /* Text
- * Note: Unicode text is available as CF_TEXT too, the system can do the
- * conversion, but we do the conversion ourself with WC_NO_BEST_FIT_CHARS.
- */
- FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
- return GHOST_kDragnDropTypeString;
- }
-
- // Filesnames
- fmtetc.cfFormat = CF_HDROP;
- if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
- return GHOST_kDragnDropTypeFilenames;
- }
-
- return GHOST_kDragnDropTypeUnknown;
+ /* Text
+ * Note: Unicode text is available as CF_TEXT too, the system can do the
+ * conversion, but we do the conversion ourself with WC_NO_BEST_FIT_CHARS.
+ */
+ FORMATETC fmtetc = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
+ return GHOST_kDragnDropTypeString;
+ }
+
+ // Filesnames
+ fmtetc.cfFormat = CF_HDROP;
+ if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
+ return GHOST_kDragnDropTypeFilenames;
+ }
+
+ return GHOST_kDragnDropTypeUnknown;
}
void *GHOST_DropTargetWin32::getGhostData(IDataObject *pDataObject)
{
- GHOST_TDragnDropTypes type = getGhostType(pDataObject);
- switch (type) {
- case GHOST_kDragnDropTypeFilenames:
- return getDropDataAsFilenames(pDataObject);
- break;
- case GHOST_kDragnDropTypeString:
- return getDropDataAsString(pDataObject);
- break;
- case GHOST_kDragnDropTypeBitmap:
- //return getDropDataAsBitmap(pDataObject);
- break;
- default:
+ GHOST_TDragnDropTypes type = getGhostType(pDataObject);
+ switch (type) {
+ case GHOST_kDragnDropTypeFilenames:
+ return getDropDataAsFilenames(pDataObject);
+ break;
+ case GHOST_kDragnDropTypeString:
+ return getDropDataAsString(pDataObject);
+ break;
+ case GHOST_kDragnDropTypeBitmap:
+ //return getDropDataAsBitmap(pDataObject);
+ break;
+ default:
#ifdef GHOST_DEBUG
- ::printf("\nGHOST_kDragnDropTypeUnknown");
-#endif // GHOST_DEBUG
- return NULL;
- break;
- }
- return NULL;
+ ::printf("\nGHOST_kDragnDropTypeUnknown");
+#endif // GHOST_DEBUG
+ return NULL;
+ break;
+ }
+ return NULL;
}
void *GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject *pDataObject)
{
- UINT totfiles, nvalid = 0;
- WCHAR fpath[MAX_PATH];
- char *temp_path;
- GHOST_TStringArray *strArray = NULL;
- FORMATETC fmtetc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- STGMEDIUM stgmed;
- HDROP hdrop;
-
- // Check if dataobject supplies the format we want.
- // Double checking here, first in getGhostType.
- if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
- if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) {
- hdrop = (HDROP) ::GlobalLock(stgmed.hGlobal);
-
- totfiles = ::DragQueryFileW(hdrop, -1, NULL, 0);
- if (!totfiles) {
- ::GlobalUnlock(stgmed.hGlobal);
- return NULL;
- }
-
- strArray = (GHOST_TStringArray *) ::malloc(sizeof(GHOST_TStringArray));
- strArray->count = 0;
- strArray->strings = (GHOST_TUns8 **) ::malloc(totfiles * sizeof(GHOST_TUns8 *));
-
- for (UINT nfile = 0; nfile < totfiles; nfile++) {
- if (::DragQueryFileW(hdrop, nfile, fpath, MAX_PATH) > 0) {
- if (!(temp_path = alloc_utf_8_from_16(fpath, 0)) ) {
- continue;
- }
- // Just ignore paths that could not be converted verbatim.
-
- strArray->strings[nvalid] = (GHOST_TUns8 *) temp_path;
- strArray->count = nvalid + 1;
- nvalid++;
- }
- }
- // Free up memory.
- ::GlobalUnlock(stgmed.hGlobal);
- ::ReleaseStgMedium(&stgmed);
-
- return strArray;
- }
- }
- return NULL;
+ UINT totfiles, nvalid = 0;
+ WCHAR fpath[MAX_PATH];
+ char *temp_path;
+ GHOST_TStringArray *strArray = NULL;
+ FORMATETC fmtetc = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ STGMEDIUM stgmed;
+ HDROP hdrop;
+
+ // Check if dataobject supplies the format we want.
+ // Double checking here, first in getGhostType.
+ if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
+ if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) {
+ hdrop = (HDROP)::GlobalLock(stgmed.hGlobal);
+
+ totfiles = ::DragQueryFileW(hdrop, -1, NULL, 0);
+ if (!totfiles) {
+ ::GlobalUnlock(stgmed.hGlobal);
+ return NULL;
+ }
+
+ strArray = (GHOST_TStringArray *)::malloc(sizeof(GHOST_TStringArray));
+ strArray->count = 0;
+ strArray->strings = (GHOST_TUns8 **)::malloc(totfiles * sizeof(GHOST_TUns8 *));
+
+ for (UINT nfile = 0; nfile < totfiles; nfile++) {
+ if (::DragQueryFileW(hdrop, nfile, fpath, MAX_PATH) > 0) {
+ if (!(temp_path = alloc_utf_8_from_16(fpath, 0))) {
+ continue;
+ }
+ // Just ignore paths that could not be converted verbatim.
+
+ strArray->strings[nvalid] = (GHOST_TUns8 *)temp_path;
+ strArray->count = nvalid + 1;
+ nvalid++;
+ }
+ }
+ // Free up memory.
+ ::GlobalUnlock(stgmed.hGlobal);
+ ::ReleaseStgMedium(&stgmed);
+
+ return strArray;
+ }
+ }
+ return NULL;
}
void *GHOST_DropTargetWin32::getDropDataAsString(IDataObject *pDataObject)
{
- char *tmp_string;
- FORMATETC fmtetc = { CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- STGMEDIUM stgmed;
-
- // Try unicode first.
- // Check if dataobject supplies the format we want.
- if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
- if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) {
- LPCWSTR wstr = (LPCWSTR) ::GlobalLock(stgmed.hGlobal);
- if (!(tmp_string = alloc_utf_8_from_16((wchar_t *)wstr, 0)) ) {
- ::GlobalUnlock(stgmed.hGlobal);
- return NULL;
- }
- // Free memory
- ::GlobalUnlock(stgmed.hGlobal);
- ::ReleaseStgMedium(&stgmed);
+ char *tmp_string;
+ FORMATETC fmtetc = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ STGMEDIUM stgmed;
+
+ // Try unicode first.
+ // Check if dataobject supplies the format we want.
+ if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
+ if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) {
+ LPCWSTR wstr = (LPCWSTR)::GlobalLock(stgmed.hGlobal);
+ if (!(tmp_string = alloc_utf_8_from_16((wchar_t *)wstr, 0))) {
+ ::GlobalUnlock(stgmed.hGlobal);
+ return NULL;
+ }
+ // Free memory
+ ::GlobalUnlock(stgmed.hGlobal);
+ ::ReleaseStgMedium(&stgmed);
#ifdef GHOST_DEBUG
- ::printf("\n<converted droped unicode string>\n%s\n</droped converted unicode string>\n", tmp_string);
-#endif // GHOST_DEBUG
- return tmp_string;
- }
- }
-
- fmtetc.cfFormat = CF_TEXT;
-
- if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
- if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) {
- char *str = (char *)::GlobalLock(stgmed.hGlobal);
-
- tmp_string = (char *)::malloc(::strlen(str) + 1);
- if (!tmp_string) {
- ::GlobalUnlock(stgmed.hGlobal);
- return NULL;
- }
-
- if (!::strcpy(tmp_string, str) ) {
- ::free(tmp_string);
- ::GlobalUnlock(stgmed.hGlobal);
- return NULL;
- }
- // Free memory
- ::GlobalUnlock(stgmed.hGlobal);
- ::ReleaseStgMedium(&stgmed);
-
- return tmp_string;
- }
- }
-
- return NULL;
+ ::printf("\n<converted droped unicode string>\n%s\n</droped converted unicode string>\n",
+ tmp_string);
+#endif // GHOST_DEBUG
+ return tmp_string;
+ }
+ }
+
+ fmtetc.cfFormat = CF_TEXT;
+
+ if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
+ if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) {
+ char *str = (char *)::GlobalLock(stgmed.hGlobal);
+
+ tmp_string = (char *)::malloc(::strlen(str) + 1);
+ if (!tmp_string) {
+ ::GlobalUnlock(stgmed.hGlobal);
+ return NULL;
+ }
+
+ if (!::strcpy(tmp_string, str)) {
+ ::free(tmp_string);
+ ::GlobalUnlock(stgmed.hGlobal);
+ return NULL;
+ }
+ // Free memory
+ ::GlobalUnlock(stgmed.hGlobal);
+ ::ReleaseStgMedium(&stgmed);
+
+ return tmp_string;
+ }
+ }
+
+ return NULL;
}
-int GHOST_DropTargetWin32::WideCharToANSI(LPCWSTR in, char * &out)
+int GHOST_DropTargetWin32::WideCharToANSI(LPCWSTR in, char *&out)
{
- int size;
- out = NULL; //caller should free if != NULL
-
- // Get the required size.
- size = ::WideCharToMultiByte(CP_ACP, //System Default Codepage
- 0x00000400, // WC_NO_BEST_FIT_CHARS
- in,
- -1, //-1 null terminated, makes output null terminated too.
- NULL,
- 0,
- NULL, NULL
- );
-
- if (!size) {
+ int size;
+ out = NULL; //caller should free if != NULL
+
+ // Get the required size.
+ size = ::WideCharToMultiByte(CP_ACP, //System Default Codepage
+ 0x00000400, // WC_NO_BEST_FIT_CHARS
+ in,
+ -1, //-1 null terminated, makes output null terminated too.
+ NULL,
+ 0,
+ NULL,
+ NULL);
+
+ if (!size) {
#ifdef GHOST_DEBUG
- ::printLastError();
-#endif // GHOST_DEBUG
- return 0;
- }
-
- out = (char *)::malloc(size);
- if (!out) {
- ::printf("\nmalloc failed!!!");
- return 0;
- }
-
- size = ::WideCharToMultiByte(CP_ACP,
- 0x00000400,
- in,
- -1,
- (LPSTR) out,
- size,
- NULL, NULL
- );
-
- if (!size) {
+ ::printLastError();
+#endif // GHOST_DEBUG
+ return 0;
+ }
+
+ out = (char *)::malloc(size);
+ if (!out) {
+ ::printf("\nmalloc failed!!!");
+ return 0;
+ }
+
+ size = ::WideCharToMultiByte(CP_ACP, 0x00000400, in, -1, (LPSTR)out, size, NULL, NULL);
+
+ if (!size) {
#ifdef GHOST_DEBUG
- ::printLastError();
-#endif //GHOST_DEBUG
- ::free(out);
- out = NULL;
- }
- return size;
+ ::printLastError();
+#endif //GHOST_DEBUG
+ ::free(out);
+ out = NULL;
+ }
+ return size;
}
#ifdef GHOST_DEBUG
void printLastError(void)
{
- LPTSTR s;
- DWORD err;
-
- err = GetLastError();
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- err,
- 0,
- (LPTSTR)&s,
- 0,
- NULL))
- {
- printf("\nLastError: (%d) %s\n", (int)err, s);
- LocalFree(s);
- }
+ LPTSTR s;
+ DWORD err;
+
+ err = GetLastError();
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ err,
+ 0,
+ (LPTSTR)&s,
+ 0,
+ NULL)) {
+ printf("\nLastError: (%d) %s\n", (int)err, s);
+ LocalFree(s);
+ }
}
-#endif // GHOST_DEBUG
+#endif // GHOST_DEBUG
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.h b/intern/ghost/intern/GHOST_DropTargetWin32.h
index 2d78c384818..e1985f85640 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.h
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.h
@@ -29,124 +29,125 @@
#include "GHOST_WindowWin32.h"
#include "GHOST_SystemWin32.h"
-class GHOST_DropTargetWin32 : public IDropTarget
-{
-public:
- /* IUnknownd implementation.
- * Enables clients to get pointers to other interfaces on a given object
- * through the QueryInterface method, and manage the existence of the object
- * through the AddRef and Release methods. All other COM interfaces are
- * inherited, directly or indirectly, from IUnknown. Therefore, the three
- * methods in IUnknown are the first entries in the VTable for every interface.
- */
- HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj);
- ULONG __stdcall AddRef(void);
- ULONG __stdcall Release(void);
-
- /* IDropTarget implementation
- * + The IDropTarget interface is one of the interfaces you implement to
- * provide drag-and-drop operations in your application. It contains methods
- * used in any application that can be a target for data during a
- * drag-and-drop operation. A drop-target application is responsible for:
- *
- * - Determining the effect of the drop on the target application.
- * - Incorporating any valid dropped data when the drop occurs.
- * - Communicating target feedback to the source so the source application
- * can provide appropriate visual feedback such as setting the cursor.
- * - Implementing drag scrolling.
- * - Registering and revoking its application windows as drop targets.
- *
- * The IDropTarget interface contains methods that handle all these
- * responsibilities except registering and revoking the application window
- * as a drop target, for which you must call the RegisterDragDrop and the
- * RevokeDragDrop functions.
- */
-
- HRESULT __stdcall DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
- HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
- HRESULT __stdcall DragLeave(void);
- HRESULT __stdcall Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
-
- /**
- * Constructor
- * With the modifier keys, we want to distinguish left and right keys.
- * Sometimes this is not possible (Windows ME for instance). Then, we want
- * events generated for both keys.
- * \param window The window to register as drop target.
- * \param system The associated system.
- */
- GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system);
-
- /**
- * Destructor
- * Do NOT destroy directly. Use Release() instead to make COM happy.
- */
- ~GHOST_DropTargetWin32();
-
-private:
-
- /* Internal helper functions */
-
- /**
- * Base the effect on those allowed by the dropsource.
- * \param dwAllowed Drop sources allowed drop effect.
- * \return The allowed drop effect.
- */
- DWORD allowedDropEffect(DWORD dwAllowed);
-
- /**
- * Query DataObject for the data types it supports.
- * \param pDataObject Pointer to the DataObject.
- * \return GHOST data type.
- */
- GHOST_TDragnDropTypes getGhostType(IDataObject *pDataObject);
-
- /**
- * Get data to pass in event.
- * It checks the type and calls specific functions for each type.
- * \param pDataObject Pointer to the DataObject.
- * \return Pointer to data.
- */
- void *getGhostData(IDataObject *pDataObject);
-
- /**
- * Allocate data as file array to pass in event.
- * \param pDataObject Pointer to the DataObject.
- * \return Pointer to data.
- */
- void *getDropDataAsFilenames(IDataObject *pDataObject);
-
- /**
- * Allocate data as string to pass in event.
- * \param pDataObject Pointer to the DataObject.
- * \return Pointer to data.
- */
- void *getDropDataAsString(IDataObject *pDataObject);
-
- /**
- * Convert Unicode to ANSI, replacing unconvertable chars with '?'.
- * The ANSI codepage is the system default codepage,
- * and can change from system to system.
- * \param in LPCWSTR.
- * \param out char *. Is set to NULL on failure.
- * \return 0 on failure. Else the size of the string including '\0'.
- */
- int WideCharToANSI(LPCWSTR in, char * &out);
-
- /* Private member variables */
- /* COM reference count. */
- LONG m_cRef;
- /* Handle of the associated window. */
- HWND m_hWnd;
- /* The associated GHOST_WindowWin32. */
- GHOST_WindowWin32 *m_window;
- /* The System. */
- GHOST_SystemWin32 *m_system;
- /* Data type of the dragged object */
- GHOST_TDragnDropTypes m_draggedObjectType;
+class GHOST_DropTargetWin32 : public IDropTarget {
+ public:
+ /* IUnknownd implementation.
+ * Enables clients to get pointers to other interfaces on a given object
+ * through the QueryInterface method, and manage the existence of the object
+ * through the AddRef and Release methods. All other COM interfaces are
+ * inherited, directly or indirectly, from IUnknown. Therefore, the three
+ * methods in IUnknown are the first entries in the VTable for every interface.
+ */
+ HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj);
+ ULONG __stdcall AddRef(void);
+ ULONG __stdcall Release(void);
+
+ /* IDropTarget implementation
+ * + The IDropTarget interface is one of the interfaces you implement to
+ * provide drag-and-drop operations in your application. It contains methods
+ * used in any application that can be a target for data during a
+ * drag-and-drop operation. A drop-target application is responsible for:
+ *
+ * - Determining the effect of the drop on the target application.
+ * - Incorporating any valid dropped data when the drop occurs.
+ * - Communicating target feedback to the source so the source application
+ * can provide appropriate visual feedback such as setting the cursor.
+ * - Implementing drag scrolling.
+ * - Registering and revoking its application windows as drop targets.
+ *
+ * The IDropTarget interface contains methods that handle all these
+ * responsibilities except registering and revoking the application window
+ * as a drop target, for which you must call the RegisterDragDrop and the
+ * RevokeDragDrop functions.
+ */
+
+ HRESULT __stdcall DragEnter(IDataObject *pDataObject,
+ DWORD grfKeyState,
+ POINTL pt,
+ DWORD *pdwEffect);
+ HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
+ HRESULT __stdcall DragLeave(void);
+ HRESULT __stdcall Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
+
+ /**
+ * Constructor
+ * With the modifier keys, we want to distinguish left and right keys.
+ * Sometimes this is not possible (Windows ME for instance). Then, we want
+ * events generated for both keys.
+ * \param window The window to register as drop target.
+ * \param system The associated system.
+ */
+ GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system);
+
+ /**
+ * Destructor
+ * Do NOT destroy directly. Use Release() instead to make COM happy.
+ */
+ ~GHOST_DropTargetWin32();
+
+ private:
+ /* Internal helper functions */
+
+ /**
+ * Base the effect on those allowed by the dropsource.
+ * \param dwAllowed Drop sources allowed drop effect.
+ * \return The allowed drop effect.
+ */
+ DWORD allowedDropEffect(DWORD dwAllowed);
+
+ /**
+ * Query DataObject for the data types it supports.
+ * \param pDataObject Pointer to the DataObject.
+ * \return GHOST data type.
+ */
+ GHOST_TDragnDropTypes getGhostType(IDataObject *pDataObject);
+
+ /**
+ * Get data to pass in event.
+ * It checks the type and calls specific functions for each type.
+ * \param pDataObject Pointer to the DataObject.
+ * \return Pointer to data.
+ */
+ void *getGhostData(IDataObject *pDataObject);
+
+ /**
+ * Allocate data as file array to pass in event.
+ * \param pDataObject Pointer to the DataObject.
+ * \return Pointer to data.
+ */
+ void *getDropDataAsFilenames(IDataObject *pDataObject);
+
+ /**
+ * Allocate data as string to pass in event.
+ * \param pDataObject Pointer to the DataObject.
+ * \return Pointer to data.
+ */
+ void *getDropDataAsString(IDataObject *pDataObject);
+
+ /**
+ * Convert Unicode to ANSI, replacing unconvertable chars with '?'.
+ * The ANSI codepage is the system default codepage,
+ * and can change from system to system.
+ * \param in LPCWSTR.
+ * \param out char *. Is set to NULL on failure.
+ * \return 0 on failure. Else the size of the string including '\0'.
+ */
+ int WideCharToANSI(LPCWSTR in, char *&out);
+
+ /* Private member variables */
+ /* COM reference count. */
+ LONG m_cRef;
+ /* Handle of the associated window. */
+ HWND m_hWnd;
+ /* The associated GHOST_WindowWin32. */
+ GHOST_WindowWin32 *m_window;
+ /* The System. */
+ GHOST_SystemWin32 *m_system;
+ /* Data type of the dragged object */
+ GHOST_TDragnDropTypes m_draggedObjectType;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetWin32")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetWin32")
#endif
};
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp
index e411772fc32..3d58ed9236e 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp
@@ -31,276 +31,286 @@ bool GHOST_DropTargetX11::m_xdndInitialized = false;
DndClass GHOST_DropTargetX11::m_dndClass;
Atom *GHOST_DropTargetX11::m_dndTypes = NULL;
Atom *GHOST_DropTargetX11::m_dndActions = NULL;
-const char *GHOST_DropTargetX11::m_dndMimeTypes[] = {"url/url", "text/uri-list", "text/plain", "application/octet-stream"};
+const char *GHOST_DropTargetX11::m_dndMimeTypes[] = {
+ "url/url", "text/uri-list", "text/plain", "application/octet-stream"};
int GHOST_DropTargetX11::m_refCounter = 0;
-#define dndTypeURLID 0
-#define dndTypeURIListID 1
-#define dndTypePlainTextID 2
-#define dndTypeOctetStreamID 3
+#define dndTypeURLID 0
+#define dndTypeURIListID 1
+#define dndTypePlainTextID 2
+#define dndTypeOctetStreamID 3
-#define dndTypeURL m_dndTypes[dndTypeURLID]
-#define dndTypeURIList m_dndTypes[dndTypeURIListID]
-#define dndTypePlainText m_dndTypes[dndTypePlainTextID]
-#define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID]
+#define dndTypeURL m_dndTypes[dndTypeURLID]
+#define dndTypeURIList m_dndTypes[dndTypeURIListID]
+#define dndTypePlainText m_dndTypes[dndTypePlainTextID]
+#define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID]
void GHOST_DropTargetX11::Initialize(void)
{
- Display *display = m_system->getXDisplay();
- int dndTypesCount = sizeof(m_dndMimeTypes) / sizeof(char *);
- int counter;
+ Display *display = m_system->getXDisplay();
+ int dndTypesCount = sizeof(m_dndMimeTypes) / sizeof(char *);
+ int counter;
- xdnd_init(&m_dndClass, display);
+ xdnd_init(&m_dndClass, display);
- m_dndTypes = new Atom[dndTypesCount + 1];
- XInternAtoms(display, (char **)m_dndMimeTypes, dndTypesCount, 0, m_dndTypes);
- m_dndTypes[dndTypesCount] = 0;
+ m_dndTypes = new Atom[dndTypesCount + 1];
+ XInternAtoms(display, (char **)m_dndMimeTypes, dndTypesCount, 0, m_dndTypes);
+ m_dndTypes[dndTypesCount] = 0;
- m_dndActions = new Atom[8];
- counter = 0;
+ m_dndActions = new Atom[8];
+ counter = 0;
- m_dndActions[counter++] = m_dndClass.XdndActionCopy;
- m_dndActions[counter++] = m_dndClass.XdndActionMove;
+ m_dndActions[counter++] = m_dndClass.XdndActionCopy;
+ m_dndActions[counter++] = m_dndClass.XdndActionMove;
#if 0 /* Not supported yet */
- dndActions[counter++] = dnd->XdndActionLink;
- dndActions[counter++] = dnd->XdndActionAsk;
- dndActions[counter++] = dnd->XdndActionPrivate;
- dndActions[counter++] = dnd->XdndActionList;
- dndActions[counter++] = dnd->XdndActionDescription;
+ dndActions[counter++] = dnd->XdndActionLink;
+ dndActions[counter++] = dnd->XdndActionAsk;
+ dndActions[counter++] = dnd->XdndActionPrivate;
+ dndActions[counter++] = dnd->XdndActionList;
+ dndActions[counter++] = dnd->XdndActionDescription;
#endif
- m_dndActions[counter++] = 0;
+ m_dndActions[counter++] = 0;
}
void GHOST_DropTargetX11::Uninitialize(void)
{
- xdnd_shut(&m_dndClass);
+ xdnd_shut(&m_dndClass);
- delete[] m_dndActions;
- delete[] m_dndTypes;
+ delete[] m_dndActions;
+ delete[] m_dndTypes;
}
GHOST_DropTargetX11::GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system)
- :
- m_window(window),
- m_system(system)
+ : m_window(window), m_system(system)
{
- if (!m_xdndInitialized) {
- Initialize();
- m_xdndInitialized = true;
- GHOST_PRINT("XDND initialized\n");
- }
+ if (!m_xdndInitialized) {
+ Initialize();
+ m_xdndInitialized = true;
+ GHOST_PRINT("XDND initialized\n");
+ }
- Window wnd = window->getXWindow();
+ Window wnd = window->getXWindow();
- xdnd_set_dnd_aware(&m_dndClass, wnd, 0);
- xdnd_set_type_list(&m_dndClass, wnd, m_dndTypes);
+ xdnd_set_dnd_aware(&m_dndClass, wnd, 0);
+ xdnd_set_type_list(&m_dndClass, wnd, m_dndTypes);
- m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
- m_refCounter++;
+ m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+ m_refCounter++;
}
GHOST_DropTargetX11::~GHOST_DropTargetX11()
{
- m_refCounter--;
- if (m_refCounter == 0) {
- Uninitialize();
- m_xdndInitialized = false;
- GHOST_PRINT("XDND uninitialized\n");
- }
+ m_refCounter--;
+ if (m_refCounter == 0) {
+ Uninitialize();
+ m_xdndInitialized = false;
+ GHOST_PRINT("XDND uninitialized\n");
+ }
}
/* based on a code from Saul Rennison
* http://stackoverflow.com/questions/2673207/c-c-url-decode-library */
typedef enum DecodeState_e {
- STATE_SEARCH = 0, ///< searching for an ampersand to convert
- STATE_CONVERTING ///< convert the two proceeding characters from hex
+ STATE_SEARCH = 0, ///< searching for an ampersand to convert
+ STATE_CONVERTING ///< convert the two proceeding characters from hex
} DecodeState_e;
void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn)
{
- unsigned int i;
- unsigned int len = strlen(encodedIn);
- DecodeState_e state = STATE_SEARCH;
- int j;
- unsigned int asciiCharacter;
- char tempNumBuf[3] = {0};
- bool bothDigits = true;
+ unsigned int i;
+ unsigned int len = strlen(encodedIn);
+ DecodeState_e state = STATE_SEARCH;
+ int j;
+ unsigned int asciiCharacter;
+ char tempNumBuf[3] = {0};
+ bool bothDigits = true;
- memset(decodedOut, 0, bufferSize);
+ memset(decodedOut, 0, bufferSize);
- for (i = 0; i < len; ++i) {
- switch (state) {
- case STATE_SEARCH:
- if (encodedIn[i] != '%') {
- strncat(decodedOut, &encodedIn[i], 1);
- assert(strlen(decodedOut) < bufferSize);
- break;
- }
+ for (i = 0; i < len; ++i) {
+ switch (state) {
+ case STATE_SEARCH:
+ if (encodedIn[i] != '%') {
+ strncat(decodedOut, &encodedIn[i], 1);
+ assert(strlen(decodedOut) < bufferSize);
+ break;
+ }
- /* We are now converting */
- state = STATE_CONVERTING;
- break;
+ /* We are now converting */
+ state = STATE_CONVERTING;
+ break;
- case STATE_CONVERTING:
- bothDigits = true;
+ case STATE_CONVERTING:
+ bothDigits = true;
- /* Create a buffer to hold the hex. For example, if %20, this
- * buffer would hold 20 (in ASCII) */
- memset(tempNumBuf, 0, sizeof(tempNumBuf));
+ /* Create a buffer to hold the hex. For example, if %20, this
+ * buffer would hold 20 (in ASCII) */
+ memset(tempNumBuf, 0, sizeof(tempNumBuf));
- /* Conversion complete (i.e. don't convert again next iter) */
- state = STATE_SEARCH;
+ /* Conversion complete (i.e. don't convert again next iter) */
+ state = STATE_SEARCH;
- strncpy(tempNumBuf, &encodedIn[i], 2);
+ strncpy(tempNumBuf, &encodedIn[i], 2);
- /* Ensure both characters are hexadecimal */
+ /* Ensure both characters are hexadecimal */
- for (j = 0; j < 2; ++j) {
- if (!isxdigit(tempNumBuf[j]))
- bothDigits = false;
- }
+ for (j = 0; j < 2; ++j) {
+ if (!isxdigit(tempNumBuf[j]))
+ bothDigits = false;
+ }
- if (!bothDigits)
- break;
+ if (!bothDigits)
+ break;
- /* Convert two hexadecimal characters into one character */
- sscanf(tempNumBuf, "%x", &asciiCharacter);
+ /* Convert two hexadecimal characters into one character */
+ sscanf(tempNumBuf, "%x", &asciiCharacter);
- /* Ensure we aren't going to overflow */
- assert(strlen(decodedOut) < bufferSize);
+ /* Ensure we aren't going to overflow */
+ assert(strlen(decodedOut) < bufferSize);
- /* Concatenate this character onto the output */
- strncat(decodedOut, (char *)&asciiCharacter, 1);
+ /* Concatenate this character onto the output */
+ strncat(decodedOut, (char *)&asciiCharacter, 1);
- /* Skip the next character */
- i++;
- break;
- }
- }
+ /* Skip the next character */
+ i++;
+ break;
+ }
+ }
}
char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl)
{
- if (strncmp(fileUrl, "file://", 7) == 0) {
- /* assume one character of encoded URL can be expanded to 4 chars max */
- int decodedSize = 4 * strlen(fileUrl) + 1;
- char *decodedPath = (char *)malloc(decodedSize);
+ if (strncmp(fileUrl, "file://", 7) == 0) {
+ /* assume one character of encoded URL can be expanded to 4 chars max */
+ int decodedSize = 4 * strlen(fileUrl) + 1;
+ char *decodedPath = (char *)malloc(decodedSize);
- UrlDecode(decodedPath, decodedSize, fileUrl + 7);
+ UrlDecode(decodedPath, decodedSize, fileUrl + 7);
- return decodedPath;
- }
+ return decodedPath;
+ }
- return NULL;
+ return NULL;
}
void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize)
{
- GHOST_TStringArray *strArray = NULL;
- int totPaths = 0, curLength = 0;
-
- /* count total number of file pathes in buffer */
- for (int i = 0; i <= dropBufferSize; i++) {
- if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
- if (curLength) {
- totPaths++;
- curLength = 0;
- }
- }
- else curLength++;
- }
-
- strArray = (GHOST_TStringArray *)malloc(sizeof(GHOST_TStringArray));
- strArray->count = 0;
- strArray->strings = (GHOST_TUns8 **)malloc(totPaths * sizeof(GHOST_TUns8 *));
-
- curLength = 0;
- for (int i = 0; i <= dropBufferSize; i++) {
- if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
- if (curLength) {
- char *curPath = (char *)malloc(curLength + 1);
- char *decodedPath;
-
- strncpy(curPath, (char *)dropBuffer + i - curLength, curLength);
- curPath[curLength] = 0;
-
- decodedPath = FileUrlDecode(curPath);
- if (decodedPath) {
- strArray->strings[strArray->count] = (GHOST_TUns8 *)decodedPath;
- strArray->count++;
- }
-
- free(curPath);
- curLength = 0;
- }
- }
- else curLength++;
- }
-
- return strArray;
+ GHOST_TStringArray *strArray = NULL;
+ int totPaths = 0, curLength = 0;
+
+ /* count total number of file pathes in buffer */
+ for (int i = 0; i <= dropBufferSize; i++) {
+ if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
+ if (curLength) {
+ totPaths++;
+ curLength = 0;
+ }
+ }
+ else
+ curLength++;
+ }
+
+ strArray = (GHOST_TStringArray *)malloc(sizeof(GHOST_TStringArray));
+ strArray->count = 0;
+ strArray->strings = (GHOST_TUns8 **)malloc(totPaths * sizeof(GHOST_TUns8 *));
+
+ curLength = 0;
+ for (int i = 0; i <= dropBufferSize; i++) {
+ if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
+ if (curLength) {
+ char *curPath = (char *)malloc(curLength + 1);
+ char *decodedPath;
+
+ strncpy(curPath, (char *)dropBuffer + i - curLength, curLength);
+ curPath[curLength] = 0;
+
+ decodedPath = FileUrlDecode(curPath);
+ if (decodedPath) {
+ strArray->strings[strArray->count] = (GHOST_TUns8 *)decodedPath;
+ strArray->count++;
+ }
+
+ free(curPath);
+ curLength = 0;
+ }
+ }
+ else
+ curLength++;
+ }
+
+ return strArray;
}
-void *GHOST_DropTargetX11::getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize)
+void *GHOST_DropTargetX11::getGhostData(Atom dropType,
+ unsigned char *dropBuffer,
+ int dropBufferSize)
{
- void *data = NULL;
- unsigned char *tmpBuffer = (unsigned char *)malloc(dropBufferSize + 1);
- bool needsFree = true;
-
- /* ensure NULL-terminator */
- memcpy(tmpBuffer, dropBuffer, dropBufferSize);
- tmpBuffer[dropBufferSize] = 0;
-
- if (dropType == dndTypeURIList) {
- m_draggedObjectType = GHOST_kDragnDropTypeFilenames;
- data = getURIListGhostData(tmpBuffer, dropBufferSize);
- }
- else if (dropType == dndTypeURL) {
- /* need to be tested */
- char *decodedPath = FileUrlDecode((char *)tmpBuffer);
-
- if (decodedPath) {
- m_draggedObjectType = GHOST_kDragnDropTypeString;
- data = decodedPath;
- }
- }
- else if (dropType == dndTypePlainText || dropType == dndTypeOctetStream) {
- m_draggedObjectType = GHOST_kDragnDropTypeString;
- data = tmpBuffer;
- needsFree = false;
- }
- else {
- m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
- }
-
- if (needsFree)
- free(tmpBuffer);
-
- return data;
+ void *data = NULL;
+ unsigned char *tmpBuffer = (unsigned char *)malloc(dropBufferSize + 1);
+ bool needsFree = true;
+
+ /* ensure NULL-terminator */
+ memcpy(tmpBuffer, dropBuffer, dropBufferSize);
+ tmpBuffer[dropBufferSize] = 0;
+
+ if (dropType == dndTypeURIList) {
+ m_draggedObjectType = GHOST_kDragnDropTypeFilenames;
+ data = getURIListGhostData(tmpBuffer, dropBufferSize);
+ }
+ else if (dropType == dndTypeURL) {
+ /* need to be tested */
+ char *decodedPath = FileUrlDecode((char *)tmpBuffer);
+
+ if (decodedPath) {
+ m_draggedObjectType = GHOST_kDragnDropTypeString;
+ data = decodedPath;
+ }
+ }
+ else if (dropType == dndTypePlainText || dropType == dndTypeOctetStream) {
+ m_draggedObjectType = GHOST_kDragnDropTypeString;
+ data = tmpBuffer;
+ needsFree = false;
+ }
+ else {
+ m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+ }
+
+ if (needsFree)
+ free(tmpBuffer);
+
+ return data;
}
bool GHOST_DropTargetX11::GHOST_HandleClientMessage(XEvent *event)
{
- Atom dropType;
- unsigned char *dropBuffer;
- int dropBufferSize, dropX, dropY;
+ Atom dropType;
+ unsigned char *dropBuffer;
+ int dropBufferSize, dropX, dropY;
- if (xdnd_get_drop(m_system->getXDisplay(), event, m_dndTypes, m_dndActions,
- &dropBuffer, &dropBufferSize, &dropType, &dropX, &dropY))
- {
- void *data = getGhostData(dropType, dropBuffer, dropBufferSize);
+ if (xdnd_get_drop(m_system->getXDisplay(),
+ event,
+ m_dndTypes,
+ m_dndActions,
+ &dropBuffer,
+ &dropBufferSize,
+ &dropType,
+ &dropX,
+ &dropY)) {
+ void *data = getGhostData(dropType, dropBuffer, dropBufferSize);
- if (data)
- m_system->pushDragDropEvent(GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, dropX, dropY, data);
+ if (data)
+ m_system->pushDragDropEvent(
+ GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, dropX, dropY, data);
- free(dropBuffer);
+ free(dropBuffer);
- m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+ m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.h b/intern/ghost/intern/GHOST_DropTargetX11.h
index 62657b4c0e5..1edb52de5e5 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.h
+++ b/intern/ghost/intern/GHOST_DropTargetX11.h
@@ -30,101 +30,100 @@
#include "xdnd.h"
-class GHOST_DropTargetX11
-{
-public:
- /**
- * Constructor
- *
- * \param window The window to register as drop target.
- * \param system The associated system.
- */
- GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system);
-
- /**
- * Destructor
- */
- ~GHOST_DropTargetX11();
-
- /**
- * Handler of ClientMessage X11 event
- */
- bool GHOST_HandleClientMessage(XEvent *event);
-
- /**
- * Get data to pass in event.
- * It checks the type and calls specific functions for each type.
- * \param dropType - type of dropped entity.
- * \param dropBuffer - buffer returned from source application
- * \param dropBufferSize - size of returned buffer
- * \return Pointer to data.
- */
- void *getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize);
-
-private:
- /* Internal helper functions */
-
- /**
- * Initialize XDND and all related X atoms
- */
- void Initialize(void);
-
- /**
- * Uninitialize XDND and all related X atoms
- */
- void Uninitialize(void);
-
- /**
- * Get data to be passed to event from text/uri-list mime type
- * \param dropBuffer - buffer returned from source application
- * \param dropBufferSize - size of dropped buffer
- * \return pointer to newly created GHOST data
- */
- void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize);
-
- /**
- * Decode URL (i.e. converts "file:///a%20b/test" to "file:///a b/test")
- * \param decodedOut - buffer for decoded URL
- * \param bufferSize - size of output buffer
- * \param encodedIn - input encoded buffer to be decoded
- */
- void UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn);
-
- /**
- * Fully decode file URL (i.e. converts "file:///a%20b/test" to "/a b/test")
- * \param fileUrl - file path URL to be fully decoded
- * \return decoded file path (resutl should be free-d)
- */
- char *FileUrlDecode(char *fileUrl);
-
- /* The associated GHOST_WindowWin32. */
- GHOST_WindowX11 *m_window;
- /* The System. */
- GHOST_SystemX11 *m_system;
-
- /* Data type of the dragged object */
- GHOST_TDragnDropTypes m_draggedObjectType;
-
- /* is dnd stuff initialzied */
- static bool m_xdndInitialized;
-
- /* class holding internal stiff of xdnd library */
- static DndClass m_dndClass;
-
- /* list of supported types to eb draggeg into */
- static Atom *m_dndTypes;
-
- /* list of supported dran'n'drop actions */
- static Atom *m_dndActions;
-
- /* List of supported MIME types to be dragged into */
- static const char *m_dndMimeTypes[];
-
- /* counter of references to global XDND structures */
- static int m_refCounter;
+class GHOST_DropTargetX11 {
+ public:
+ /**
+ * Constructor
+ *
+ * \param window The window to register as drop target.
+ * \param system The associated system.
+ */
+ GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system);
+
+ /**
+ * Destructor
+ */
+ ~GHOST_DropTargetX11();
+
+ /**
+ * Handler of ClientMessage X11 event
+ */
+ bool GHOST_HandleClientMessage(XEvent *event);
+
+ /**
+ * Get data to pass in event.
+ * It checks the type and calls specific functions for each type.
+ * \param dropType - type of dropped entity.
+ * \param dropBuffer - buffer returned from source application
+ * \param dropBufferSize - size of returned buffer
+ * \return Pointer to data.
+ */
+ void *getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize);
+
+ private:
+ /* Internal helper functions */
+
+ /**
+ * Initialize XDND and all related X atoms
+ */
+ void Initialize(void);
+
+ /**
+ * Uninitialize XDND and all related X atoms
+ */
+ void Uninitialize(void);
+
+ /**
+ * Get data to be passed to event from text/uri-list mime type
+ * \param dropBuffer - buffer returned from source application
+ * \param dropBufferSize - size of dropped buffer
+ * \return pointer to newly created GHOST data
+ */
+ void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize);
+
+ /**
+ * Decode URL (i.e. converts "file:///a%20b/test" to "file:///a b/test")
+ * \param decodedOut - buffer for decoded URL
+ * \param bufferSize - size of output buffer
+ * \param encodedIn - input encoded buffer to be decoded
+ */
+ void UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn);
+
+ /**
+ * Fully decode file URL (i.e. converts "file:///a%20b/test" to "/a b/test")
+ * \param fileUrl - file path URL to be fully decoded
+ * \return decoded file path (resutl should be free-d)
+ */
+ char *FileUrlDecode(char *fileUrl);
+
+ /* The associated GHOST_WindowWin32. */
+ GHOST_WindowX11 *m_window;
+ /* The System. */
+ GHOST_SystemX11 *m_system;
+
+ /* Data type of the dragged object */
+ GHOST_TDragnDropTypes m_draggedObjectType;
+
+ /* is dnd stuff initialzied */
+ static bool m_xdndInitialized;
+
+ /* class holding internal stiff of xdnd library */
+ static DndClass m_dndClass;
+
+ /* list of supported types to eb draggeg into */
+ static Atom *m_dndTypes;
+
+ /* list of supported dran'n'drop actions */
+ static Atom *m_dndActions;
+
+ /* List of supported MIME types to be dragged into */
+ static const char *m_dndMimeTypes[];
+
+ /* counter of references to global XDND structures */
+ static int m_refCounter;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetX11")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetX11")
#endif
};
diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h
index 49b2c766bb9..2c14df7f243 100644
--- a/intern/ghost/intern/GHOST_Event.h
+++ b/intern/ghost/intern/GHOST_Event.h
@@ -27,70 +27,68 @@
#include "GHOST_IEvent.h"
-
/**
* Base class for events received the operating system.
*/
-class GHOST_Event : public GHOST_IEvent
-{
-public:
- /**
- * Constructor.
- * \param msec The time this event was generated.
- * \param type The type of this event.
- * \param window The generating window (or NULL if system event).
- */
- GHOST_Event(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window)
- : m_type(type), m_time(msec), m_window(window), m_data(NULL)
- {
- }
+class GHOST_Event : public GHOST_IEvent {
+ public:
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param type The type of this event.
+ * \param window The generating window (or NULL if system event).
+ */
+ GHOST_Event(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window)
+ : m_type(type), m_time(msec), m_window(window), m_data(NULL)
+ {
+ }
- /**
- * Returns the event type.
- * \return The event type.
- */
- GHOST_TEventType getType()
- {
- return m_type;
- }
+ /**
+ * Returns the event type.
+ * \return The event type.
+ */
+ GHOST_TEventType getType()
+ {
+ return m_type;
+ }
- /**
- * Returns the time this event was generated.
- * \return The event generation time.
- */
- GHOST_TUns64 getTime()
- {
- return m_time;
- }
+ /**
+ * Returns the time this event was generated.
+ * \return The event generation time.
+ */
+ GHOST_TUns64 getTime()
+ {
+ return m_time;
+ }
- /**
- * Returns the window this event was generated on,
- * or NULL if it is a 'system' event.
- * \return The generating window.
- */
- GHOST_IWindow *getWindow()
- {
- return m_window;
- }
+ /**
+ * Returns the window this event was generated on,
+ * or NULL if it is a 'system' event.
+ * \return The generating window.
+ */
+ GHOST_IWindow *getWindow()
+ {
+ return m_window;
+ }
- /**
- * Returns the event data.
- * \return The event data.
- */
- GHOST_TEventDataPtr getData()
- {
- return m_data;
- }
+ /**
+ * Returns the event data.
+ * \return The event data.
+ */
+ GHOST_TEventDataPtr getData()
+ {
+ return m_data;
+ }
-protected:
- /** Type of this event. */
- GHOST_TEventType m_type;
- /** The time this event was generated. */
- GHOST_TUns64 m_time;
- /** Pointer to the generating window. */
- GHOST_IWindow *m_window;
- /** Pointer to the event data. */
- GHOST_TEventDataPtr m_data;
+ protected:
+ /** Type of this event. */
+ GHOST_TEventType m_type;
+ /** The time this event was generated. */
+ GHOST_TUns64 m_time;
+ /** Pointer to the generating window. */
+ GHOST_IWindow *m_window;
+ /** Pointer to the event data. */
+ GHOST_TEventDataPtr m_data;
};
-#endif // __GHOST_EVENT_H__
+#endif // __GHOST_EVENT_H__
diff --git a/intern/ghost/intern/GHOST_EventButton.h b/intern/ghost/intern/GHOST_EventButton.h
index b7bd27178ac..e33a1c961bc 100644
--- a/intern/ghost/intern/GHOST_EventButton.h
+++ b/intern/ghost/intern/GHOST_EventButton.h
@@ -30,26 +30,28 @@
/**
* Mouse button event.
*/
-class GHOST_EventButton : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param time The time this event was generated.
- * \param type The type of this event.
- * \param window: The window of this event.
- * \param button: The state of the buttons were at at the time of the event.
- */
- GHOST_EventButton(GHOST_TUns64 time, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask button)
- : GHOST_Event(time, type, window)
- {
- m_buttonEventData.button = button;
- m_data = &m_buttonEventData;
- }
+class GHOST_EventButton : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param time The time this event was generated.
+ * \param type The type of this event.
+ * \param window: The window of this event.
+ * \param button: The state of the buttons were at at the time of the event.
+ */
+ GHOST_EventButton(GHOST_TUns64 time,
+ GHOST_TEventType type,
+ GHOST_IWindow *window,
+ GHOST_TButtonMask button)
+ : GHOST_Event(time, type, window)
+ {
+ m_buttonEventData.button = button;
+ m_data = &m_buttonEventData;
+ }
-protected:
- /** The button event data. */
- GHOST_TEventButtonData m_buttonEventData;
+ protected:
+ /** The button event data. */
+ GHOST_TEventButtonData m_buttonEventData;
};
-#endif // __GHOST_EVENTBUTTON_H__
+#endif // __GHOST_EVENTBUTTON_H__
diff --git a/intern/ghost/intern/GHOST_EventCursor.h b/intern/ghost/intern/GHOST_EventCursor.h
index 431c26e2e49..7947b134f4b 100644
--- a/intern/ghost/intern/GHOST_EventCursor.h
+++ b/intern/ghost/intern/GHOST_EventCursor.h
@@ -30,28 +30,30 @@
/**
* Cursor event.
*/
-class GHOST_EventCursor : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param msec The time this event was generated.
- * \param type The type of this event.
- * \param x The x-coordinate of the location the cursor was at at the time of the event.
- * \param y The y-coordinate of the location the cursor was at at the time of the event.
- */
- GHOST_EventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TInt32 x, GHOST_TInt32 y)
- : GHOST_Event(msec, type, window)
- {
- m_cursorEventData.x = x;
- m_cursorEventData.y = y;
- m_data = &m_cursorEventData;
- }
+class GHOST_EventCursor : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param type The type of this event.
+ * \param x The x-coordinate of the location the cursor was at at the time of the event.
+ * \param y The y-coordinate of the location the cursor was at at the time of the event.
+ */
+ GHOST_EventCursor(GHOST_TUns64 msec,
+ GHOST_TEventType type,
+ GHOST_IWindow *window,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y)
+ : GHOST_Event(msec, type, window)
+ {
+ m_cursorEventData.x = x;
+ m_cursorEventData.y = y;
+ m_data = &m_cursorEventData;
+ }
-protected:
- /** The x,y-coordinates of the cursor position. */
- GHOST_TEventCursorData m_cursorEventData;
+ protected:
+ /** The x,y-coordinates of the cursor position. */
+ GHOST_TEventCursorData m_cursorEventData;
};
-
-#endif // __GHOST_EVENTCURSOR_H__
+#endif // __GHOST_EVENTCURSOR_H__
diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h
index b3572c4ade9..169b0b5d174 100644
--- a/intern/ghost/intern/GHOST_EventDragnDrop.h
+++ b/intern/ghost/intern/GHOST_EventDragnDrop.h
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
#ifndef __GHOST_EVENTDRAGNDROP_H__
#define __GHOST_EVENTDRAGNDROP_H__
@@ -59,69 +58,66 @@ extern "C" {
* <li>array of strings representing filenames (GHOST_TStringArray)
* <li>bitmap ImBuf
*/
-class GHOST_EventDragnDrop : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param time The time this event was generated.
- * \param type The type of this event.
- * \param dataType The type of the drop candidate object
- * \param window The window where the event occurred
- * \param x The x-coordinate of the location the cursor was at at the time of the event.
- * \param y The y-coordinate of the location the cursor was at at the time of the event.
- * \param data The "content" dropped in the window
- */
- GHOST_EventDragnDrop(GHOST_TUns64 time,
- GHOST_TEventType type,
- GHOST_TDragnDropTypes dataType,
- GHOST_IWindow *window,
- int x, int y, GHOST_TEventDataPtr data)
- : GHOST_Event(time, type, window)
- {
- m_dragnDropEventData.x = x;
- m_dragnDropEventData.y = y;
- m_dragnDropEventData.dataType = dataType;
- m_dragnDropEventData.data = data;
- m_data = &m_dragnDropEventData;
- }
-
- ~GHOST_EventDragnDrop()
- {
- //Free the dropped object data
- if (m_dragnDropEventData.data == NULL)
- return;
-
- switch (m_dragnDropEventData.dataType) {
- case GHOST_kDragnDropTypeBitmap:
- IMB_freeImBuf((ImBuf *)m_dragnDropEventData.data);
- break;
- case GHOST_kDragnDropTypeFilenames:
- {
- GHOST_TStringArray *strArray = (GHOST_TStringArray *)m_dragnDropEventData.data;
- int i;
+class GHOST_EventDragnDrop : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param time The time this event was generated.
+ * \param type The type of this event.
+ * \param dataType The type of the drop candidate object
+ * \param window The window where the event occurred
+ * \param x The x-coordinate of the location the cursor was at at the time of the event.
+ * \param y The y-coordinate of the location the cursor was at at the time of the event.
+ * \param data The "content" dropped in the window
+ */
+ GHOST_EventDragnDrop(GHOST_TUns64 time,
+ GHOST_TEventType type,
+ GHOST_TDragnDropTypes dataType,
+ GHOST_IWindow *window,
+ int x,
+ int y,
+ GHOST_TEventDataPtr data)
+ : GHOST_Event(time, type, window)
+ {
+ m_dragnDropEventData.x = x;
+ m_dragnDropEventData.y = y;
+ m_dragnDropEventData.dataType = dataType;
+ m_dragnDropEventData.data = data;
+ m_data = &m_dragnDropEventData;
+ }
- for (i = 0; i < strArray->count; i++)
- free(strArray->strings[i]);
+ ~GHOST_EventDragnDrop()
+ {
+ //Free the dropped object data
+ if (m_dragnDropEventData.data == NULL)
+ return;
- free(strArray->strings);
- free(strArray);
- }
- break;
- case GHOST_kDragnDropTypeString:
- free(m_dragnDropEventData.data);
- break;
+ switch (m_dragnDropEventData.dataType) {
+ case GHOST_kDragnDropTypeBitmap:
+ IMB_freeImBuf((ImBuf *)m_dragnDropEventData.data);
+ break;
+ case GHOST_kDragnDropTypeFilenames: {
+ GHOST_TStringArray *strArray = (GHOST_TStringArray *)m_dragnDropEventData.data;
+ int i;
- default:
- break;
- }
- }
+ for (i = 0; i < strArray->count; i++)
+ free(strArray->strings[i]);
+ free(strArray->strings);
+ free(strArray);
+ } break;
+ case GHOST_kDragnDropTypeString:
+ free(m_dragnDropEventData.data);
+ break;
+ default:
+ break;
+ }
+ }
-protected:
- /** The x,y-coordinates of the cursor position. */
- GHOST_TEventDragnDropData m_dragnDropEventData;
+ protected:
+ /** The x,y-coordinates of the cursor position. */
+ GHOST_TEventDragnDropData m_dragnDropEventData;
};
-#endif // __GHOST_EVENTDRAGNDROP_H__
+#endif // __GHOST_EVENTDRAGNDROP_H__
diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h
index d895c3184d0..f42dc99aaa5 100644
--- a/intern/ghost/intern/GHOST_EventKey.h
+++ b/intern/ghost/intern/GHOST_EventKey.h
@@ -30,52 +30,50 @@
/**
* Key event.
*/
-class GHOST_EventKey : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param msec The time this event was generated.
- * \param type The type of key event.
- * \param key The key code of the key.
- */
- GHOST_EventKey(GHOST_TUns64 msec,
- GHOST_TEventType type,
- GHOST_IWindow *window,
- GHOST_TKey key)
- : GHOST_Event(msec, type, window)
- {
- m_keyEventData.key = key;
- m_keyEventData.ascii = '\0';
- m_keyEventData.utf8_buf[0] = '\0';
- m_data = &m_keyEventData;
- }
+class GHOST_EventKey : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param type The type of key event.
+ * \param key The key code of the key.
+ */
+ GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TKey key)
+ : GHOST_Event(msec, type, window)
+ {
+ m_keyEventData.key = key;
+ m_keyEventData.ascii = '\0';
+ m_keyEventData.utf8_buf[0] = '\0';
+ m_data = &m_keyEventData;
+ }
- /**
- * Constructor.
- * \param msec The time this event was generated.
- * \param type The type of key event.
- * \param key The key code of the key.
- * \param ascii The ascii code for the key event.
- */
- GHOST_EventKey(GHOST_TUns64 msec,
- GHOST_TEventType type,
- GHOST_IWindow *window,
- GHOST_TKey key,
- char ascii,
- const char utf8_buf[6])
- : GHOST_Event(msec, type, window)
- {
- m_keyEventData.key = key;
- m_keyEventData.ascii = ascii;
- if (utf8_buf) memcpy(m_keyEventData.utf8_buf, utf8_buf, sizeof(m_keyEventData.utf8_buf));
- else m_keyEventData.utf8_buf[0] = '\0';
- m_data = &m_keyEventData;
- }
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param type The type of key event.
+ * \param key The key code of the key.
+ * \param ascii The ascii code for the key event.
+ */
+ GHOST_EventKey(GHOST_TUns64 msec,
+ GHOST_TEventType type,
+ GHOST_IWindow *window,
+ GHOST_TKey key,
+ char ascii,
+ const char utf8_buf[6])
+ : GHOST_Event(msec, type, window)
+ {
+ m_keyEventData.key = key;
+ m_keyEventData.ascii = ascii;
+ if (utf8_buf)
+ memcpy(m_keyEventData.utf8_buf, utf8_buf, sizeof(m_keyEventData.utf8_buf));
+ else
+ m_keyEventData.utf8_buf[0] = '\0';
+ m_data = &m_keyEventData;
+ }
-protected:
- /** The key event data. */
- GHOST_TEventKeyData m_keyEventData;
+ protected:
+ /** The key event data. */
+ GHOST_TEventKeyData m_keyEventData;
};
-#endif // __GHOST_EVENTKEY_H__
+#endif // __GHOST_EVENTKEY_H__
diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp
index 094467bb0dd..3c27e2c826a 100644
--- a/intern/ghost/intern/GHOST_EventManager.cpp
+++ b/intern/ghost/intern/GHOST_EventManager.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
@@ -29,186 +28,176 @@
#include "GHOST_EventManager.h"
#include <algorithm>
#include "GHOST_Debug.h"
-#include <stdio.h> // [mce] temp debug
+#include <stdio.h> // [mce] temp debug
GHOST_EventManager::GHOST_EventManager()
{
}
-
GHOST_EventManager::~GHOST_EventManager()
{
- disposeEvents();
-
- TConsumerVector::iterator iter = m_consumers.begin();
- while (iter != m_consumers.end()) {
- GHOST_IEventConsumer *consumer = *iter;
- delete consumer;
- iter = m_consumers.erase(iter);
- }
+ disposeEvents();
+
+ TConsumerVector::iterator iter = m_consumers.begin();
+ while (iter != m_consumers.end()) {
+ GHOST_IEventConsumer *consumer = *iter;
+ delete consumer;
+ iter = m_consumers.erase(iter);
+ }
}
-
GHOST_TUns32 GHOST_EventManager::getNumEvents()
{
- return (GHOST_TUns32) m_events.size();
+ return (GHOST_TUns32)m_events.size();
}
-
GHOST_TUns32 GHOST_EventManager::getNumEvents(GHOST_TEventType type)
{
- GHOST_TUns32 numEvents = 0;
- TEventStack::iterator p;
- for (p = m_events.begin(); p != m_events.end(); ++p) {
- if ((*p)->getType() == type) {
- numEvents++;
- }
- }
- return numEvents;
+ GHOST_TUns32 numEvents = 0;
+ TEventStack::iterator p;
+ for (p = m_events.begin(); p != m_events.end(); ++p) {
+ if ((*p)->getType() == type) {
+ numEvents++;
+ }
+ }
+ return numEvents;
}
-
GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent *event)
{
- GHOST_TSuccess success;
- GHOST_ASSERT(event, "invalid event");
- if (m_events.size() < m_events.max_size()) {
- m_events.push_front(event);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ GHOST_ASSERT(event, "invalid event");
+ if (m_events.size() < m_events.max_size()) {
+ m_events.push_front(event);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
void GHOST_EventManager::dispatchEvent(GHOST_IEvent *event)
{
- TConsumerVector::iterator iter;
+ TConsumerVector::iterator iter;
- for (iter = m_consumers.begin(); iter != m_consumers.end(); ++iter) {
- (*iter)->processEvent(event);
- }
+ for (iter = m_consumers.begin(); iter != m_consumers.end(); ++iter) {
+ (*iter)->processEvent(event);
+ }
}
-
void GHOST_EventManager::dispatchEvent()
{
- GHOST_IEvent *event = m_events.back();
- m_events.pop_back();
- m_handled_events.push_back(event);
+ GHOST_IEvent *event = m_events.back();
+ m_events.pop_back();
+ m_handled_events.push_back(event);
- dispatchEvent(event);
+ dispatchEvent(event);
}
-
void GHOST_EventManager::dispatchEvents()
{
- while (!m_events.empty()) {
- dispatchEvent();
- }
+ while (!m_events.empty()) {
+ dispatchEvent();
+ }
- disposeEvents();
+ disposeEvents();
}
-
GHOST_TSuccess GHOST_EventManager::addConsumer(GHOST_IEventConsumer *consumer)
{
- GHOST_TSuccess success;
- GHOST_ASSERT(consumer, "invalid consumer");
-
- // Check to see whether the consumer is already in our list
- TConsumerVector::const_iterator iter = std::find(m_consumers.begin(), m_consumers.end(), consumer);
-
- if (iter == m_consumers.end()) {
- // Add the consumer
- m_consumers.push_back(consumer);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ GHOST_ASSERT(consumer, "invalid consumer");
+
+ // Check to see whether the consumer is already in our list
+ TConsumerVector::const_iterator iter = std::find(
+ m_consumers.begin(), m_consumers.end(), consumer);
+
+ if (iter == m_consumers.end()) {
+ // Add the consumer
+ m_consumers.push_back(consumer);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
GHOST_TSuccess GHOST_EventManager::removeConsumer(GHOST_IEventConsumer *consumer)
{
- GHOST_TSuccess success;
- GHOST_ASSERT(consumer, "invalid consumer");
-
- // Check to see whether the consumer is in our list
- TConsumerVector::iterator iter = std::find(m_consumers.begin(), m_consumers.end(), consumer);
-
- if (iter != m_consumers.end()) {
- // Remove the consumer
- m_consumers.erase(iter);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ GHOST_ASSERT(consumer, "invalid consumer");
+
+ // Check to see whether the consumer is in our list
+ TConsumerVector::iterator iter = std::find(m_consumers.begin(), m_consumers.end(), consumer);
+
+ if (iter != m_consumers.end()) {
+ // Remove the consumer
+ m_consumers.erase(iter);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
void GHOST_EventManager::removeWindowEvents(GHOST_IWindow *window)
{
- TEventStack::iterator iter;
- iter = m_events.begin();
- while (iter != m_events.end()) {
- GHOST_IEvent *event = *iter;
- if (event->getWindow() == window) {
- GHOST_PRINT("GHOST_EventManager::removeWindowEvents(): removing event\n");
- /*
- * Found an event for this window, remove it.
- * The iterator will become invalid.
- */
- delete event;
- m_events.erase(iter);
- iter = m_events.begin();
- }
- else {
- ++iter;
- }
- }
+ TEventStack::iterator iter;
+ iter = m_events.begin();
+ while (iter != m_events.end()) {
+ GHOST_IEvent *event = *iter;
+ if (event->getWindow() == window) {
+ GHOST_PRINT("GHOST_EventManager::removeWindowEvents(): removing event\n");
+ /*
+ * Found an event for this window, remove it.
+ * The iterator will become invalid.
+ */
+ delete event;
+ m_events.erase(iter);
+ iter = m_events.begin();
+ }
+ else {
+ ++iter;
+ }
+ }
}
void GHOST_EventManager::removeTypeEvents(GHOST_TEventType type, GHOST_IWindow *window)
{
- TEventStack::iterator iter;
- iter = m_events.begin();
- while (iter != m_events.end()) {
- GHOST_IEvent *event = *iter;
- if ((event->getType() == type) && (!window || (event->getWindow() == window))) {
- GHOST_PRINT("GHOST_EventManager::removeTypeEvents(): removing event\n");
- /*
- * Found an event of this type for the window, remove it.
- * The iterator will become invalid.
- */
- delete event;
- m_events.erase(iter);
- iter = m_events.begin();
- }
- else {
- ++iter;
- }
- }
+ TEventStack::iterator iter;
+ iter = m_events.begin();
+ while (iter != m_events.end()) {
+ GHOST_IEvent *event = *iter;
+ if ((event->getType() == type) && (!window || (event->getWindow() == window))) {
+ GHOST_PRINT("GHOST_EventManager::removeTypeEvents(): removing event\n");
+ /*
+ * Found an event of this type for the window, remove it.
+ * The iterator will become invalid.
+ */
+ delete event;
+ m_events.erase(iter);
+ iter = m_events.begin();
+ }
+ else {
+ ++iter;
+ }
+ }
}
-
void GHOST_EventManager::disposeEvents()
{
- while (m_handled_events.empty() == false) {
- GHOST_ASSERT(m_handled_events[0], "invalid event");
- delete m_handled_events[0];
- m_handled_events.pop_front();
- }
-
- while (m_events.empty() == false) {
- GHOST_ASSERT(m_events[0], "invalid event");
- delete m_events[0];
- m_events.pop_front();
- }
+ while (m_handled_events.empty() == false) {
+ GHOST_ASSERT(m_handled_events[0], "invalid event");
+ delete m_handled_events[0];
+ m_handled_events.pop_front();
+ }
+
+ while (m_events.empty() == false) {
+ GHOST_ASSERT(m_events[0], "invalid event");
+ delete m_events[0];
+ m_events.pop_front();
+ }
}
diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h
index 04e71586550..ada5abda89b 100644
--- a/intern/ghost/intern/GHOST_EventManager.h
+++ b/intern/ghost/intern/GHOST_EventManager.h
@@ -30,7 +30,6 @@
#include "GHOST_IEventConsumer.h"
-
/**
* Manages an event stack and a list of event consumers.
* The stack works on a FIFO (First In First Out) basis.
@@ -39,117 +38,107 @@
* Ownership of the event is transferred from the event manager as soon as an event is popped.
* Events can be dispatched to the event consumers.
*/
-class GHOST_EventManager
-{
-public:
- /**
- * Constructor.
- */
- GHOST_EventManager();
-
- /**
- * Destructor.
- */
- ~GHOST_EventManager();
-
- /**
- * Returns the number of events currently on the stack.
- * \return The number of events on the stack.
- */
- GHOST_TUns32 getNumEvents();
-
- /**
- * Returns the number of events of a certain type currently on the stack.
- * \param type The type of events to be counted.
- * \return The number of events on the stack of this type.
- */
- GHOST_TUns32 getNumEvents(GHOST_TEventType type);
-
- /**
- * Pushes an event on the stack.
- * To dispatch it, call dispatchEvent() or dispatchEvents().
- * Do not delete the event!
- * \param event The event to push on the stack.
- */
- GHOST_TSuccess pushEvent(GHOST_IEvent *event);
-
- /**
- * Dispatches the given event directly, bypassing the event stack.
- */
- void dispatchEvent(GHOST_IEvent *event);
-
- /**
- * Dispatches the event at the back of the stack.
- * The event will be removed from the stack.
- */
- void dispatchEvent();
-
- /**
- * Dispatches all the events on the stack.
- * The event stack will be empty afterwards.
- */
- void dispatchEvents();
-
- /**
- * Adds a consumer to the list of event consumers.
- * \param consumer The consumer added to the list.
- * \return Indication as to whether addition has succeeded.
- */
- GHOST_TSuccess addConsumer(GHOST_IEventConsumer *consumer);
-
- /**
- * Removes a consumer from the list of event consumers.
- * \param consumer The consumer removed from the list.
- * \return Indication as to whether removal has succeeded.
- */
- GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer);
-
- /**
- * Removes all events for a window from the stack.
- * \param window The window to remove events for.
- */
- void
- removeWindowEvents(
- GHOST_IWindow *window
- );
-
- /**
- * Removes all events of a certain type from the stack.
- * The window parameter is optional. If non-null, the routine will remove
- * events only associated with that window.
- * \param type The type of events to be removed.
- * \param window The window to remove the events for.
- */
- void
- removeTypeEvents(
- GHOST_TEventType type,
- GHOST_IWindow *window = NULL
- );
-
-protected:
-
- /**
- * Removes all events from the stack.
- */
- void disposeEvents();
-
- /** A stack with events. */
- typedef std::deque<GHOST_IEvent *> TEventStack;
-
- /** The event stack. */
- std::deque<GHOST_IEvent *> m_events;
- std::deque<GHOST_IEvent *> m_handled_events;
-
- /** A vector with event consumers. */
- typedef std::vector<GHOST_IEventConsumer *> TConsumerVector;
-
- /** The list with event consumers. */
- TConsumerVector m_consumers;
-
+class GHOST_EventManager {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_EventManager();
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_EventManager();
+
+ /**
+ * Returns the number of events currently on the stack.
+ * \return The number of events on the stack.
+ */
+ GHOST_TUns32 getNumEvents();
+
+ /**
+ * Returns the number of events of a certain type currently on the stack.
+ * \param type The type of events to be counted.
+ * \return The number of events on the stack of this type.
+ */
+ GHOST_TUns32 getNumEvents(GHOST_TEventType type);
+
+ /**
+ * Pushes an event on the stack.
+ * To dispatch it, call dispatchEvent() or dispatchEvents().
+ * Do not delete the event!
+ * \param event The event to push on the stack.
+ */
+ GHOST_TSuccess pushEvent(GHOST_IEvent *event);
+
+ /**
+ * Dispatches the given event directly, bypassing the event stack.
+ */
+ void dispatchEvent(GHOST_IEvent *event);
+
+ /**
+ * Dispatches the event at the back of the stack.
+ * The event will be removed from the stack.
+ */
+ void dispatchEvent();
+
+ /**
+ * Dispatches all the events on the stack.
+ * The event stack will be empty afterwards.
+ */
+ void dispatchEvents();
+
+ /**
+ * Adds a consumer to the list of event consumers.
+ * \param consumer The consumer added to the list.
+ * \return Indication as to whether addition has succeeded.
+ */
+ GHOST_TSuccess addConsumer(GHOST_IEventConsumer *consumer);
+
+ /**
+ * Removes a consumer from the list of event consumers.
+ * \param consumer The consumer removed from the list.
+ * \return Indication as to whether removal has succeeded.
+ */
+ GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer);
+
+ /**
+ * Removes all events for a window from the stack.
+ * \param window The window to remove events for.
+ */
+ void removeWindowEvents(GHOST_IWindow *window);
+
+ /**
+ * Removes all events of a certain type from the stack.
+ * The window parameter is optional. If non-null, the routine will remove
+ * events only associated with that window.
+ * \param type The type of events to be removed.
+ * \param window The window to remove the events for.
+ */
+ void removeTypeEvents(GHOST_TEventType type, GHOST_IWindow *window = NULL);
+
+ protected:
+ /**
+ * Removes all events from the stack.
+ */
+ void disposeEvents();
+
+ /** A stack with events. */
+ typedef std::deque<GHOST_IEvent *> TEventStack;
+
+ /** The event stack. */
+ std::deque<GHOST_IEvent *> m_events;
+ std::deque<GHOST_IEvent *> m_handled_events;
+
+ /** A vector with event consumers. */
+ typedef std::vector<GHOST_IEventConsumer *> TConsumerVector;
+
+ /** The list with event consumers. */
+ TConsumerVector m_consumers;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_EventManager")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_EventManager")
#endif
};
-#endif // __GHOST_EVENTMANAGER_H__
+#endif // __GHOST_EVENTMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_EventNDOF.h b/intern/ghost/intern/GHOST_EventNDOF.h
index af4b4cb5f06..196d3868ccd 100644
--- a/intern/ghost/intern/GHOST_EventNDOF.h
+++ b/intern/ghost/intern/GHOST_EventNDOF.h
@@ -27,31 +27,28 @@
#include "GHOST_Event.h"
-class GHOST_EventNDOFMotion : public GHOST_Event
-{
-protected:
- GHOST_TEventNDOFMotionData m_axisData;
-
-public:
- GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow *window)
- : GHOST_Event(time, GHOST_kEventNDOFMotion, window)
- {
- m_data = &m_axisData;
- }
+class GHOST_EventNDOFMotion : public GHOST_Event {
+ protected:
+ GHOST_TEventNDOFMotionData m_axisData;
+
+ public:
+ GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow *window)
+ : GHOST_Event(time, GHOST_kEventNDOFMotion, window)
+ {
+ m_data = &m_axisData;
+ }
};
+class GHOST_EventNDOFButton : public GHOST_Event {
+ protected:
+ GHOST_TEventNDOFButtonData m_buttonData;
-class GHOST_EventNDOFButton : public GHOST_Event
-{
-protected:
- GHOST_TEventNDOFButtonData m_buttonData;
-
-public:
- GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow *window)
- : GHOST_Event(time, GHOST_kEventNDOFButton, window)
- {
- m_data = &m_buttonData;
- }
+ public:
+ GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow *window)
+ : GHOST_Event(time, GHOST_kEventNDOFButton, window)
+ {
+ m_data = &m_buttonData;
+ }
};
-#endif // __GHOST_EVENTNDOF_H__
+#endif // __GHOST_EVENTNDOF_H__
diff --git a/intern/ghost/intern/GHOST_EventPrinter.cpp b/intern/ghost/intern/GHOST_EventPrinter.cpp
index 0ed34cb9fba..3c5f613e11f 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.cpp
+++ b/intern/ghost/intern/GHOST_EventPrinter.cpp
@@ -32,301 +32,292 @@
bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
{
- bool handled = true;
+ bool handled = true;
- GHOST_ASSERT(event, "event==0");
+ GHOST_ASSERT(event, "event==0");
- if (event->getType() == GHOST_kEventWindowUpdate) return false;
+ if (event->getType() == GHOST_kEventWindowUpdate)
+ return false;
- std::cout << "\nGHOST_EventPrinter::processEvent, time: " << (GHOST_TInt32)event->getTime() << ", type: ";
- switch (event->getType()) {
- case GHOST_kEventUnknown:
- std::cout << "GHOST_kEventUnknown"; handled = false;
- break;
+ std::cout << "\nGHOST_EventPrinter::processEvent, time: " << (GHOST_TInt32)event->getTime()
+ << ", type: ";
+ switch (event->getType()) {
+ case GHOST_kEventUnknown:
+ std::cout << "GHOST_kEventUnknown";
+ handled = false;
+ break;
- case GHOST_kEventButtonUp:
- {
- GHOST_TEventButtonData *buttonData = (GHOST_TEventButtonData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventCursorButtonUp, button: " << buttonData->button;
- }
- break;
- case GHOST_kEventButtonDown:
- {
- GHOST_TEventButtonData *buttonData = (GHOST_TEventButtonData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventButtonDown, button: " << buttonData->button;
- }
- break;
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *buttonData =
+ (GHOST_TEventButtonData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventCursorButtonUp, button: " << buttonData->button;
+ } break;
+ case GHOST_kEventButtonDown: {
+ GHOST_TEventButtonData *buttonData =
+ (GHOST_TEventButtonData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventButtonDown, button: " << buttonData->button;
+ } break;
- case GHOST_kEventWheel:
- {
- GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventWheel, z: " << wheelData->z;
- }
- break;
+ case GHOST_kEventWheel: {
+ GHOST_TEventWheelData *wheelData =
+ (GHOST_TEventWheelData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventWheel, z: " << wheelData->z;
+ } break;
- case GHOST_kEventCursorMove:
- {
- GHOST_TEventCursorData *cursorData = (GHOST_TEventCursorData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventCursorMove, (x,y): (" << cursorData->x << "," << cursorData->y << ")";
- }
- break;
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cursorData =
+ (GHOST_TEventCursorData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventCursorMove, (x,y): (" << cursorData->x << "," << cursorData->y
+ << ")";
+ } break;
- case GHOST_kEventKeyUp:
- {
- GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
- char str[32] = {'\0'};
- getKeyString(keyData->key, str);
- std::cout << "GHOST_kEventKeyUp, key: " << str;
- }
- break;
- case GHOST_kEventKeyDown:
- {
- GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
- char str[32] = {'\0'};
- getKeyString(keyData->key, str);
- std::cout << "GHOST_kEventKeyDown, key: " << str;
- }
- break;
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
+ char str[32] = {'\0'};
+ getKeyString(keyData->key, str);
+ std::cout << "GHOST_kEventKeyUp, key: " << str;
+ } break;
+ case GHOST_kEventKeyDown: {
+ GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
+ char str[32] = {'\0'};
+ getKeyString(keyData->key, str);
+ std::cout << "GHOST_kEventKeyDown, key: " << str;
+ } break;
- case GHOST_kEventDraggingEntered:
- {
- GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventDraggingEntered, dragged object type : " << dragnDropData->dataType;
- std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
- }
- break;
+ case GHOST_kEventDraggingEntered: {
+ GHOST_TEventDragnDropData *dragnDropData =
+ (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventDraggingEntered, dragged object type : "
+ << dragnDropData->dataType;
+ std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
+ } break;
- case GHOST_kEventDraggingUpdated:
- {
- GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventDraggingUpdated, dragged object type : " << dragnDropData->dataType;
- std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
- }
- break;
+ case GHOST_kEventDraggingUpdated: {
+ GHOST_TEventDragnDropData *dragnDropData =
+ (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventDraggingUpdated, dragged object type : "
+ << dragnDropData->dataType;
+ std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
+ } break;
- case GHOST_kEventDraggingExited:
- {
- GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType;
- }
- break;
+ case GHOST_kEventDraggingExited: {
+ GHOST_TEventDragnDropData *dragnDropData =
+ (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType;
+ } break;
- case GHOST_kEventDraggingDropDone:
- {
- GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
- std::cout << "GHOST_kEventDraggingDropDone,";
- std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
- switch (dragnDropData->dataType) {
- case GHOST_kDragnDropTypeString:
- std::cout << " type : GHOST_kDragnDropTypeString,";
- std::cout << "\n String received = " << (char *)dragnDropData->data;
- break;
- case GHOST_kDragnDropTypeFilenames:
- {
- GHOST_TStringArray *strArray = (GHOST_TStringArray *)dragnDropData->data;
- int i;
- std::cout << " type : GHOST_kDragnDropTypeFilenames,";
- std::cout << "\n Received " << strArray->count << " filename" << (strArray->count > 1 ? "s:" : ":");
- for (i = 0; i < strArray->count; i++)
- std::cout << "\n File["<< i << "] : " << strArray->strings[i];
- }
- break;
- default:
- break;
- }
- }
- break;
+ case GHOST_kEventDraggingDropDone: {
+ GHOST_TEventDragnDropData *dragnDropData =
+ (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
+ std::cout << "GHOST_kEventDraggingDropDone,";
+ std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
+ switch (dragnDropData->dataType) {
+ case GHOST_kDragnDropTypeString:
+ std::cout << " type : GHOST_kDragnDropTypeString,";
+ std::cout << "\n String received = " << (char *)dragnDropData->data;
+ break;
+ case GHOST_kDragnDropTypeFilenames: {
+ GHOST_TStringArray *strArray = (GHOST_TStringArray *)dragnDropData->data;
+ int i;
+ std::cout << " type : GHOST_kDragnDropTypeFilenames,";
+ std::cout << "\n Received " << strArray->count << " filename"
+ << (strArray->count > 1 ? "s:" : ":");
+ for (i = 0; i < strArray->count; i++)
+ std::cout << "\n File[" << i << "] : " << strArray->strings[i];
+ } break;
+ default:
+ break;
+ }
+ } break;
- case GHOST_kEventOpenMainFile:
- {
- GHOST_TEventDataPtr eventData = ((GHOST_IEvent *)event)->getData();
+ case GHOST_kEventOpenMainFile: {
+ GHOST_TEventDataPtr eventData = ((GHOST_IEvent *)event)->getData();
- if (eventData)
- std::cout << "GHOST_kEventOpenMainFile for path : " << (char *)eventData;
- else
- std::cout << "GHOST_kEventOpenMainFile with no path specified!!";
- }
- break;
+ if (eventData)
+ std::cout << "GHOST_kEventOpenMainFile for path : " << (char *)eventData;
+ else
+ std::cout << "GHOST_kEventOpenMainFile with no path specified!!";
+ } break;
- case GHOST_kEventQuit:
- std::cout << "GHOST_kEventQuit";
- break;
- case GHOST_kEventWindowClose:
- std::cout << "GHOST_kEventWindowClose";
- break;
- case GHOST_kEventWindowActivate:
- std::cout << "GHOST_kEventWindowActivate";
- break;
- case GHOST_kEventWindowDeactivate:
- std::cout << "GHOST_kEventWindowDeactivate";
- break;
- case GHOST_kEventWindowUpdate:
- std::cout << "GHOST_kEventWindowUpdate";
- break;
- case GHOST_kEventWindowSize:
- std::cout << "GHOST_kEventWindowSize";
- break;
+ case GHOST_kEventQuit:
+ std::cout << "GHOST_kEventQuit";
+ break;
+ case GHOST_kEventWindowClose:
+ std::cout << "GHOST_kEventWindowClose";
+ break;
+ case GHOST_kEventWindowActivate:
+ std::cout << "GHOST_kEventWindowActivate";
+ break;
+ case GHOST_kEventWindowDeactivate:
+ std::cout << "GHOST_kEventWindowDeactivate";
+ break;
+ case GHOST_kEventWindowUpdate:
+ std::cout << "GHOST_kEventWindowUpdate";
+ break;
+ case GHOST_kEventWindowSize:
+ std::cout << "GHOST_kEventWindowSize";
+ break;
- default:
- std::cout << "not found"; handled = false;
- break;
- }
+ default:
+ std::cout << "not found";
+ handled = false;
+ break;
+ }
- std::cout.flush();
+ std::cout.flush();
- return handled;
+ return handled;
}
-
void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
{
- if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) {
- sprintf(str, "%c", (char)key);
- }
- else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) {
- sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0));
- }
- else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) {
- sprintf(str, "F%d", key - GHOST_kKeyF1 + 1);
- }
- else {
- const char *tstr = NULL;
- switch (key) {
- case GHOST_kKeyBackSpace:
- tstr = "BackSpace";
- break;
- case GHOST_kKeyTab:
- tstr = "Tab";
- break;
- case GHOST_kKeyLinefeed:
- tstr = "Linefeed";
- break;
- case GHOST_kKeyClear:
- tstr = "Clear";
- break;
- case GHOST_kKeyEnter:
- tstr = "Enter";
- break;
- case GHOST_kKeyEsc:
- tstr = "Esc";
- break;
- case GHOST_kKeySpace:
- tstr = "Space";
- break;
- case GHOST_kKeyQuote:
- tstr = "Quote";
- break;
- case GHOST_kKeyBackslash:
- tstr = "\\";
- break;
- case GHOST_kKeyAccentGrave:
- tstr = "`";
- break;
- case GHOST_kKeyLeftShift:
- tstr = "LeftShift";
- break;
- case GHOST_kKeyRightShift:
- tstr = "RightShift";
- break;
- case GHOST_kKeyLeftControl:
- tstr = "LeftControl";
- break;
- case GHOST_kKeyRightControl:
- tstr = "RightControl";
- break;
- case GHOST_kKeyLeftAlt:
- tstr = "LeftAlt";
- break;
- case GHOST_kKeyRightAlt:
- tstr = "RightAlt";
- break;
- case GHOST_kKeyOS:
- tstr = "OS";
- break;
- case GHOST_kKeyGrLess:
- // PC german!
- tstr = "GrLess";
- break;
- case GHOST_kKeyCapsLock:
- tstr = "CapsLock";
- break;
- case GHOST_kKeyNumLock:
- tstr = "NumLock";
- break;
- case GHOST_kKeyScrollLock:
- tstr = "ScrollLock";
- break;
- case GHOST_kKeyLeftArrow:
- tstr = "LeftArrow";
- break;
- case GHOST_kKeyRightArrow:
- tstr = "RightArrow";
- break;
- case GHOST_kKeyUpArrow:
- tstr = "UpArrow";
- break;
- case GHOST_kKeyDownArrow:
- tstr = "DownArrow";
- break;
- case GHOST_kKeyPrintScreen:
- tstr = "PrintScreen";
- break;
- case GHOST_kKeyPause:
- tstr = "Pause";
- break;
- case GHOST_kKeyInsert:
- tstr = "Insert";
- break;
- case GHOST_kKeyDelete:
- tstr = "Delete";
- break;
- case GHOST_kKeyHome:
- tstr = "Home";
- break;
- case GHOST_kKeyEnd:
- tstr = "End";
- break;
- case GHOST_kKeyUpPage:
- tstr = "UpPage";
- break;
- case GHOST_kKeyDownPage:
- tstr = "DownPage";
- break;
- case GHOST_kKeyNumpadPeriod:
- tstr = "NumpadPeriod";
- break;
- case GHOST_kKeyNumpadEnter:
- tstr = "NumpadEnter";
- break;
- case GHOST_kKeyNumpadPlus:
- tstr = "NumpadPlus";
- break;
- case GHOST_kKeyNumpadMinus:
- tstr = "NumpadMinus";
- break;
- case GHOST_kKeyNumpadAsterisk:
- tstr = "NumpadAsterisk";
- break;
- case GHOST_kKeyNumpadSlash:
- tstr = "NumpadSlash";
- break;
- case GHOST_kKeyMediaPlay:
- tstr = "MediaPlayPause";
- break;
- case GHOST_kKeyMediaStop:
- tstr = "MediaStop";
- break;
- case GHOST_kKeyMediaFirst:
- tstr = "MediaFirst";
- break;
- case GHOST_kKeyMediaLast:
- tstr = "MediaLast";
- break;
- default:
- tstr = "unknown";
- break;
- }
+ if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) {
+ sprintf(str, "%c", (char)key);
+ }
+ else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) {
+ sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0));
+ }
+ else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) {
+ sprintf(str, "F%d", key - GHOST_kKeyF1 + 1);
+ }
+ else {
+ const char *tstr = NULL;
+ switch (key) {
+ case GHOST_kKeyBackSpace:
+ tstr = "BackSpace";
+ break;
+ case GHOST_kKeyTab:
+ tstr = "Tab";
+ break;
+ case GHOST_kKeyLinefeed:
+ tstr = "Linefeed";
+ break;
+ case GHOST_kKeyClear:
+ tstr = "Clear";
+ break;
+ case GHOST_kKeyEnter:
+ tstr = "Enter";
+ break;
+ case GHOST_kKeyEsc:
+ tstr = "Esc";
+ break;
+ case GHOST_kKeySpace:
+ tstr = "Space";
+ break;
+ case GHOST_kKeyQuote:
+ tstr = "Quote";
+ break;
+ case GHOST_kKeyBackslash:
+ tstr = "\\";
+ break;
+ case GHOST_kKeyAccentGrave:
+ tstr = "`";
+ break;
+ case GHOST_kKeyLeftShift:
+ tstr = "LeftShift";
+ break;
+ case GHOST_kKeyRightShift:
+ tstr = "RightShift";
+ break;
+ case GHOST_kKeyLeftControl:
+ tstr = "LeftControl";
+ break;
+ case GHOST_kKeyRightControl:
+ tstr = "RightControl";
+ break;
+ case GHOST_kKeyLeftAlt:
+ tstr = "LeftAlt";
+ break;
+ case GHOST_kKeyRightAlt:
+ tstr = "RightAlt";
+ break;
+ case GHOST_kKeyOS:
+ tstr = "OS";
+ break;
+ case GHOST_kKeyGrLess:
+ // PC german!
+ tstr = "GrLess";
+ break;
+ case GHOST_kKeyCapsLock:
+ tstr = "CapsLock";
+ break;
+ case GHOST_kKeyNumLock:
+ tstr = "NumLock";
+ break;
+ case GHOST_kKeyScrollLock:
+ tstr = "ScrollLock";
+ break;
+ case GHOST_kKeyLeftArrow:
+ tstr = "LeftArrow";
+ break;
+ case GHOST_kKeyRightArrow:
+ tstr = "RightArrow";
+ break;
+ case GHOST_kKeyUpArrow:
+ tstr = "UpArrow";
+ break;
+ case GHOST_kKeyDownArrow:
+ tstr = "DownArrow";
+ break;
+ case GHOST_kKeyPrintScreen:
+ tstr = "PrintScreen";
+ break;
+ case GHOST_kKeyPause:
+ tstr = "Pause";
+ break;
+ case GHOST_kKeyInsert:
+ tstr = "Insert";
+ break;
+ case GHOST_kKeyDelete:
+ tstr = "Delete";
+ break;
+ case GHOST_kKeyHome:
+ tstr = "Home";
+ break;
+ case GHOST_kKeyEnd:
+ tstr = "End";
+ break;
+ case GHOST_kKeyUpPage:
+ tstr = "UpPage";
+ break;
+ case GHOST_kKeyDownPage:
+ tstr = "DownPage";
+ break;
+ case GHOST_kKeyNumpadPeriod:
+ tstr = "NumpadPeriod";
+ break;
+ case GHOST_kKeyNumpadEnter:
+ tstr = "NumpadEnter";
+ break;
+ case GHOST_kKeyNumpadPlus:
+ tstr = "NumpadPlus";
+ break;
+ case GHOST_kKeyNumpadMinus:
+ tstr = "NumpadMinus";
+ break;
+ case GHOST_kKeyNumpadAsterisk:
+ tstr = "NumpadAsterisk";
+ break;
+ case GHOST_kKeyNumpadSlash:
+ tstr = "NumpadSlash";
+ break;
+ case GHOST_kKeyMediaPlay:
+ tstr = "MediaPlayPause";
+ break;
+ case GHOST_kKeyMediaStop:
+ tstr = "MediaStop";
+ break;
+ case GHOST_kKeyMediaFirst:
+ tstr = "MediaFirst";
+ break;
+ case GHOST_kKeyMediaLast:
+ tstr = "MediaLast";
+ break;
+ default:
+ tstr = "unknown";
+ break;
+ }
- sprintf(str, "%s", tstr);
- }
+ sprintf(str, "%s", tstr);
+ }
}
diff --git a/intern/ghost/intern/GHOST_EventPrinter.h b/intern/ghost/intern/GHOST_EventPrinter.h
index 6ac3e1ee68a..fad9ec3cc69 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.h
+++ b/intern/ghost/intern/GHOST_EventPrinter.h
@@ -33,23 +33,22 @@
* An Event consumer that prints all the events to standard out.
* Really useful when debugging.
*/
-class GHOST_EventPrinter : public GHOST_IEventConsumer
-{
-public:
- /**
- * Prints all the events received to std out.
- * \param event The event that can be handled or not.
- * \return Indication as to whether the event was handled.
- */
- bool processEvent(GHOST_IEvent *event);
+class GHOST_EventPrinter : public GHOST_IEventConsumer {
+ public:
+ /**
+ * Prints all the events received to std out.
+ * \param event The event that can be handled or not.
+ * \return Indication as to whether the event was handled.
+ */
+ bool processEvent(GHOST_IEvent *event);
-protected:
- /**
- * Converts GHOST key code to a readable string.
- * \param key The GHOST key code to convert.
- * \param str The GHOST key code converted to a readable string.
- */
- void getKeyString(GHOST_TKey key, char str[32]) const;
+ protected:
+ /**
+ * Converts GHOST key code to a readable string.
+ * \param key The GHOST key code to convert.
+ * \param str The GHOST key code converted to a readable string.
+ */
+ void getKeyString(GHOST_TKey key, char str[32]) const;
};
-#endif // __GHOST_EVENTPRINTER_H__
+#endif // __GHOST_EVENTPRINTER_H__
diff --git a/intern/ghost/intern/GHOST_EventString.h b/intern/ghost/intern/GHOST_EventString.h
index 8a1d2169708..f0d3ffb9e91 100644
--- a/intern/ghost/intern/GHOST_EventString.h
+++ b/intern/ghost/intern/GHOST_EventString.h
@@ -27,30 +27,32 @@
#include "GHOST_Event.h"
-
/**
* Generic class for events with string data
*/
-class GHOST_EventString : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param msec The time this event was generated.
- * \param type The type of this event.
- * \param window The generating window (or NULL if system event).
- * \param data_ptr Pointer to the (unformatted) data associated with the event
- */
- GHOST_EventString(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TEventDataPtr data_ptr)
- : GHOST_Event(msec, type, window)
- {
- m_data = data_ptr;
- }
+class GHOST_EventString : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param type The type of this event.
+ * \param window The generating window (or NULL if system event).
+ * \param data_ptr Pointer to the (unformatted) data associated with the event
+ */
+ GHOST_EventString(GHOST_TUns64 msec,
+ GHOST_TEventType type,
+ GHOST_IWindow *window,
+ GHOST_TEventDataPtr data_ptr)
+ : GHOST_Event(msec, type, window)
+ {
+ m_data = data_ptr;
+ }
- ~GHOST_EventString()
- {
- if (m_data) free(m_data);
- }
+ ~GHOST_EventString()
+ {
+ if (m_data)
+ free(m_data);
+ }
};
-#endif // __GHOST_EVENTSTRING_H__
+#endif // __GHOST_EVENTSTRING_H__
diff --git a/intern/ghost/intern/GHOST_EventTrackpad.h b/intern/ghost/intern/GHOST_EventTrackpad.h
index cae80fa85a0..795e969b16d 100644
--- a/intern/ghost/intern/GHOST_EventTrackpad.h
+++ b/intern/ghost/intern/GHOST_EventTrackpad.h
@@ -30,36 +30,36 @@
/**
* Trackpad (scroll, magnify, rotate, ...) event.
*/
-class GHOST_EventTrackpad : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param msec The time this event was generated.
- * \param window: The window of this event.
- * \param subtype The subtype of the event.
- * \param x The x-delta of the pan event.
- * \param y The y-delta of the pan event.
- */
- GHOST_EventTrackpad(GHOST_TUns64 msec,
- GHOST_IWindow *window,
- GHOST_TTrackpadEventSubTypes subtype,
- GHOST_TInt32 x, GHOST_TInt32 y,
- GHOST_TInt32 deltaX, GHOST_TInt32 deltaY)
- : GHOST_Event(msec, GHOST_kEventTrackpad, window)
- {
- m_trackpadEventData.subtype = subtype;
- m_trackpadEventData.x = x;
- m_trackpadEventData.y = y;
- m_trackpadEventData.deltaX = deltaX;
- m_trackpadEventData.deltaY = deltaY;
- m_data = &m_trackpadEventData;
- }
+class GHOST_EventTrackpad : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param window: The window of this event.
+ * \param subtype The subtype of the event.
+ * \param x The x-delta of the pan event.
+ * \param y The y-delta of the pan event.
+ */
+ GHOST_EventTrackpad(GHOST_TUns64 msec,
+ GHOST_IWindow *window,
+ GHOST_TTrackpadEventSubTypes subtype,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y,
+ GHOST_TInt32 deltaX,
+ GHOST_TInt32 deltaY)
+ : GHOST_Event(msec, GHOST_kEventTrackpad, window)
+ {
+ m_trackpadEventData.subtype = subtype;
+ m_trackpadEventData.x = x;
+ m_trackpadEventData.y = y;
+ m_trackpadEventData.deltaX = deltaX;
+ m_trackpadEventData.deltaY = deltaY;
+ m_data = &m_trackpadEventData;
+ }
-protected:
- /** The mouse pan data */
- GHOST_TEventTrackpadData m_trackpadEventData;
+ protected:
+ /** The mouse pan data */
+ GHOST_TEventTrackpadData m_trackpadEventData;
};
-
-#endif // _GHOST_EVENT_PAN_H_
+#endif // _GHOST_EVENT_PAN_H_
diff --git a/intern/ghost/intern/GHOST_EventWheel.h b/intern/ghost/intern/GHOST_EventWheel.h
index 02b827d23d0..4d3eeb9cd83 100644
--- a/intern/ghost/intern/GHOST_EventWheel.h
+++ b/intern/ghost/intern/GHOST_EventWheel.h
@@ -32,26 +32,24 @@
* The displacement of the mouse wheel is counted in ticks.
* A positive value means the wheel is turned away from the user.
*/
-class GHOST_EventWheel : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param msec: The time this event was generated.
- * \param window: The window of this event.
- * \param z: The displacement of the mouse wheel.
- */
- GHOST_EventWheel(GHOST_TUns64 msec, GHOST_IWindow *window, GHOST_TInt32 z)
- : GHOST_Event(msec, GHOST_kEventWheel, window)
- {
- m_wheelEventData.z = z;
- m_data = &m_wheelEventData;
- }
+class GHOST_EventWheel : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param msec: The time this event was generated.
+ * \param window: The window of this event.
+ * \param z: The displacement of the mouse wheel.
+ */
+ GHOST_EventWheel(GHOST_TUns64 msec, GHOST_IWindow *window, GHOST_TInt32 z)
+ : GHOST_Event(msec, GHOST_kEventWheel, window)
+ {
+ m_wheelEventData.z = z;
+ m_data = &m_wheelEventData;
+ }
-protected:
- /** The z-displacement of the mouse wheel. */
- GHOST_TEventWheelData m_wheelEventData;
+ protected:
+ /** The z-displacement of the mouse wheel. */
+ GHOST_TEventWheelData m_wheelEventData;
};
-
-#endif // __GHOST_EVENTWHEEL_H__
+#endif // __GHOST_EVENTWHEEL_H__
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 02e71d1a849..914f6712676 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
@@ -46,52 +45,50 @@
GHOST_ISystem *GHOST_ISystem::m_system = NULL;
-
GHOST_TSuccess GHOST_ISystem::createSystem()
{
- GHOST_TSuccess success;
- if (!m_system) {
+ GHOST_TSuccess success;
+ if (!m_system) {
#ifdef WITH_X11
- m_system = new GHOST_SystemX11();
+ m_system = new GHOST_SystemX11();
#else
# ifdef WITH_HEADLESS
- m_system = new GHOST_SystemNULL();
+ m_system = new GHOST_SystemNULL();
# elif defined(WITH_GHOST_SDL)
- m_system = new GHOST_SystemSDL();
+ m_system = new GHOST_SystemSDL();
# elif defined(WIN32)
- m_system = new GHOST_SystemWin32();
+ m_system = new GHOST_SystemWin32();
# else
# ifdef __APPLE__
- m_system = new GHOST_SystemCocoa();
+ m_system = new GHOST_SystemCocoa();
# endif
# endif
#endif
- success = m_system != NULL ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- success = GHOST_kFailure;
- }
- if (success) {
- success = m_system->init();
- }
- return success;
+ success = m_system != NULL ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ if (success) {
+ success = m_system->init();
+ }
+ return success;
}
GHOST_TSuccess GHOST_ISystem::disposeSystem()
{
- GHOST_TSuccess success = GHOST_kSuccess;
- if (m_system) {
- delete m_system;
- m_system = NULL;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success = GHOST_kSuccess;
+ if (m_system) {
+ delete m_system;
+ m_system = NULL;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
GHOST_ISystem *GHOST_ISystem::getSystem()
{
- return m_system;
+ return m_system;
}
diff --git a/intern/ghost/intern/GHOST_ISystemPaths.cpp b/intern/ghost/intern/GHOST_ISystemPaths.cpp
index e9abe3d2983..f3bcd279211 100644
--- a/intern/ghost/intern/GHOST_ISystemPaths.cpp
+++ b/intern/ghost/intern/GHOST_ISystemPaths.cpp
@@ -21,12 +21,10 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
-
#include <stdio.h> /* just for NULL */
#include "GHOST_ISystemPaths.h"
@@ -35,54 +33,52 @@
# include "GHOST_SystemPathsWin32.h"
#else
# ifdef __APPLE__
-# include "GHOST_SystemPathsCocoa.h"
+# include "GHOST_SystemPathsCocoa.h"
# else
# include "GHOST_SystemPathsUnix.h"
# endif
#endif
-
GHOST_ISystemPaths *GHOST_ISystemPaths::m_systemPaths = NULL;
-
GHOST_TSuccess GHOST_ISystemPaths::create()
{
- GHOST_TSuccess success;
- if (!m_systemPaths) {
+ GHOST_TSuccess success;
+ if (!m_systemPaths) {
#ifdef WIN32
- m_systemPaths = new GHOST_SystemPathsWin32();
+ m_systemPaths = new GHOST_SystemPathsWin32();
#else
# ifdef __APPLE__
- m_systemPaths = new GHOST_SystemPathsCocoa();
+ m_systemPaths = new GHOST_SystemPathsCocoa();
# else
- m_systemPaths = new GHOST_SystemPathsUnix();
+ m_systemPaths = new GHOST_SystemPathsUnix();
# endif
#endif
- success = m_systemPaths != NULL ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ success = m_systemPaths != NULL ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
GHOST_TSuccess GHOST_ISystemPaths::dispose()
{
- GHOST_TSuccess success = GHOST_kSuccess;
- if (m_systemPaths) {
- delete m_systemPaths;
- m_systemPaths = NULL;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success = GHOST_kSuccess;
+ if (m_systemPaths) {
+ delete m_systemPaths;
+ m_systemPaths = NULL;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
GHOST_ISystemPaths *GHOST_ISystemPaths::get()
{
- if (!m_systemPaths) {
- create();
- }
- return m_systemPaths;
+ if (!m_systemPaths) {
+ create();
+ }
+ return m_systemPaths;
}
diff --git a/intern/ghost/intern/GHOST_IconX11.h b/intern/ghost/intern/GHOST_IconX11.h
index b9951078027..c5bcf4bedeb 100644
--- a/intern/ghost/intern/GHOST_IconX11.h
+++ b/intern/ghost/intern/GHOST_IconX11.h
@@ -51,550 +51,967 @@
* \note Using 'unsigned' to avoid `-Wnarrowing` warning.
*/
static const unsigned long BLENDER_ICONS_WM_X11[] = {
-16,16,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36f67b2b, 0xa2f6792b, 0x2df47728, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31f5782a, 0xebf57a2a, 0xf5f5792a, 0x5ff4792b, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1cf6762e, 0xccf5792b, 0xfff5792a, 0xa2f6792b, 0xaff8033, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x52f6792c, 0xe5f5792a, 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xf3f5792a,
-0xfff5792a, 0xfff5792a, 0xcdf5792a, 0x22f8782d, 0x0, 0x0, 0x0, 0x0, 0x3cf7772b, 0x98f5792a, 0x99f57a2a, 0x9cf5792b,
-0xf3f5792a, 0xfff5792a, 0xfdf5792a, 0xedf69253, 0xf2f9a36e, 0xf4f78a45, 0xfff5792a, 0xeef5792a, 0x3cf7772b, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x15f37924, 0xbbf5792a, 0xfff5792a, 0xf2f67e32, 0xfefde5d5, 0xffd7e3ec, 0xffa9c1d6, 0xffe3eaf1,
-0xfffbcaab, 0xfff57a2b, 0xecf5792a, 0x18f4752b, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe3f5792a, 0xfff5792a, 0xfff5792a,
-0xf8fcd0b3, 0xffb5cadc, 0xff10548c, 0xff0d528b, 0xff165990, 0xffd2dfea, 0xfff9ab7a, 0xfff5792a, 0x82f57a29, 0x0,
-0x1ff0000, 0x70f67929, 0xfaf5792a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfffef1e9, 0xff6692b6, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff8aacc7, 0xfffbcbac, 0xfff5792a, 0xbef6792a, 0xeed8024, 0xabf5792a, 0xfff5792a, 0xf5f5792a, 0x5cf47a2a,
-0xfdf5792a, 0xfff5792a, 0xfffcddca, 0xffb0c7d9, 0xff0f538c, 0xff0d528b, 0xff14578e, 0xffcfdce8, 0xfffab68c, 0xfff5792a,
-0xbef6792a, 0xaef57a2b, 0xfff5792a, 0xe2f5792a, 0x32f57a29, 0x0, 0xcef5792a, 0xfff5792a, 0xf7f7904e, 0xfffef6f0,
-0xffd1dee9, 0xffa3bdd3, 0xffdde7ef, 0xfffde4d4, 0xfef57d31, 0xfff5792a, 0x84f57a2b, 0x77f4782b, 0xa1f5782b, 0x17f47a2c,
-0x0, 0x0, 0x52f6792c, 0xfff5792a, 0xfff5792a, 0xfcf6853d, 0xfffab68b, 0xfffbc5a3, 0xfff9ab7a, 0xfff57c2e, 0xfff5792a,
-0xedf5792a, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7af5792a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xeef5792a, 0x3df7792a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37f6792a, 0xa6f47929,
-0xe3f5792a, 0xf2f6792a, 0xd6f57a2a, 0x8bf6792a, 0x17f47a2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-32,32,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x13f27928, 0x5ff4792b, 0x46f4782c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0xdaf4782a, 0xfff5792a, 0xfff5792a, 0xa9f4792a,
-0xdeb7627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd8f6782b, 0x2cf37a29, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcff802b,
-0xacf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf7f5792a, 0x63f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfdf5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa2f6792b, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29, 0xf0f5792b, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xcef5792a, 0x22f8782d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4ff5772a, 0xcbf57929,
-0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a,
-0xeef5792a, 0xeef5792a, 0xf8f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a, 0x4cf5792c, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17f47a2c, 0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0x86f57a2a, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x10ef8030, 0xe6f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0xcff802b, 0x32f57a29, 0x33f57828, 0x33f57828, 0x33f57828, 0x33f57828, 0x3ef77729, 0xcdf5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf68035, 0xfff9b284, 0xfffcd3ba, 0xfffde1cf, 0xfffcdac5, 0xfffac39f, 0xfff79557,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x13f27928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x27f27c27, 0xd3f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef9ac7a, 0xfffef8f3,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcd5bc, 0xfff6833a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xb5f5792a, 0x2ff8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x56f67a2a, 0xf2f6792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b488, 0xffffffff, 0xffffffff, 0xffe4ecf2, 0xff7ba1c0, 0xff4e80aa, 0xff5a89b0,
-0xff94b2cc, 0xfff7fafb, 0xffffffff, 0xfffde7d9, 0xfff68036, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6ff802b, 0x91f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfaf78e4b, 0xfffffcfb, 0xffffffff, 0xffc0d2e1, 0xff165990, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff326c9d,
-0xffecf1f6, 0xffffffff, 0xfffbc8a8, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd8f6782b, 0x2ff8000, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x1df67b2c, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbcaab,
-0xffffffff, 0xfff2f5f9, 0xff206094, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5b8ab0,
-0xffffffff, 0xfffffbf8, 0xfff68137, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x31f5782a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46f4782c,
-0xeaf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde9dc, 0xffffffff,
-0xffb5cadc, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff11558d, 0xfff8fafc,
-0xffffffff, 0xfff89c62, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6ff67a29, 0x0, 0x0, 0x0, 0x2ff8000, 0x7ff5782a,
-0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffeeee4,
-0xffffffff, 0xffb3c9db, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff10548c,
-0xfff8fafc, 0xffffffff, 0xfff8a169, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x87f6792a, 0x0, 0x0, 0x14f27326, 0xb8f5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf0f5792b, 0x56f67a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfffcdbc6, 0xffffffff, 0xffeef3f7, 0xff195b91, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff4f81ab, 0xffffffff, 0xffffffff, 0xfff78d4b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8df4792a, 0x0, 0x37f6792a,
-0xe1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd9f4792a, 0x28f2792d, 0x4ff8040, 0xf7f5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff9ad7d, 0xffffffff, 0xffffffff, 0xffaac2d6, 0xff11558d, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff256396, 0xffdce6ee, 0xffffffff, 0xfffde5d6, 0xfff57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6bf57a2b,
-0x2ff4772b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb7f5792a, 0x10ef8030, 0x0, 0x0, 0xcbf57929,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57c2e, 0xfffde3d2, 0xffffffff, 0xffffffff, 0xffcedce7, 0xff6390b4, 0xff356e9e,
-0xff3d75a2, 0xff7da2c1, 0xffeaf0f5, 0xffffffff, 0xfffffdfc, 0xfff7995d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0x38f67b29, 0x95f57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8cf6782a, 0x3ff5500, 0x0, 0x0, 0x0,
-0x6ff67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde4d4, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff8a773, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xd6f57a2a, 0x1ff0000, 0x79f4782a, 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0xeed8024,
-0xecf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfffab68b, 0xfffeede2, 0xffffffff, 0xffffffff,
-0xffffffff, 0xfffff9f6, 0xfffbd0b4, 0xfff78d4b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x62f5782a,
-0x0, 0x3ff5500, 0x60f47a2b, 0x76f47929, 0x1ff77b29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929, 0xfef5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68841, 0xfff79556, 0xfff78f4c, 0xfff57d30,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb5f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xd2f5792b, 0x15f37924, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69f57929,
-0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x28f2792d, 0xb6f5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe4f5792b, 0x5ef47a29, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0x77f4782b, 0xbaf5792b, 0xd5f5792a, 0xecf5792a,
-0xe1f5792a, 0xc5f57829, 0x98f5792a, 0x45f47a29, 0x4ff8040, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-48,48,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0xdeb7627, 0x1af57627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x7ff6d24, 0xa2f6792b, 0xfdf5792a, 0xfff5792a, 0xd3f5792a, 0x36f67b2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6ef6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a,
-0x6bf57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59f6782b,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa6f47929, 0xcff802b, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xd6f57a2a, 0x29f3762c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x4cf5792c, 0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x59f6782b,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2df47728, 0xdef5792b, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, 0x6ff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13f27928, 0xbcf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xccf5792b, 0x21f77c27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xecf5792a,
-0x49f57a2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31f5782a,
-0xa2f6792b, 0xcaf5792a, 0xcff5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a,
-0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a,
-0xfbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x81f5792a, 0x3ff5500,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff77928, 0xf7f5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x15f37924,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3f57929, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe3f5792a,
-0x39f67928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff5782a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfaf5792a, 0x6df67a2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12f1802b, 0x95f57a2b,
-0xd0f5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xd7f6792a, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xd0f5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff68035, 0xfff68c48, 0xfff78d4b, 0xfff68239, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0x89f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19f57a29, 0xc0f4792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68c49, 0xfffbc4a1, 0xfffde9dd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xfffef0e7, 0xfffbcbad, 0xfff79556, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0x95f57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x3ff77928, 0xe7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57f34, 0xfffbc8a8,
-0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xfffcd7bf, 0xfff6863f, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x62f5782a, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfbf5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde9dc, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xfffcfdfe, 0xffe0e9f0, 0xffd4e0eb, 0xffedf2f6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xfffef3ed, 0xfff79251, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x2bf3772a, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10ef8030, 0xb1f5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68035, 0xfffdebde, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffe6edf3, 0xff7199bb, 0xff1e5e93, 0xff0d528b, 0xff0d528b, 0xff0e538b, 0xff3b73a1, 0xffa5bfd4, 0xfffefeff, 0xffffffff,
-0xffffffff, 0xfffef5ef, 0xfff68a45, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32f57a29, 0xddf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffc6d6e4,
-0xff1f5f94, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5888af, 0xfff8fafc,
-0xffffffff, 0xffffffff, 0xfffddecb, 0xfff57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x36f67b2b,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x65f5792b, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68944, 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffe3ebf2,
-0xff1b5c92, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff6b95b8, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff89c62, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0x9bf57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaff8033, 0xa0f57929, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffabc94, 0xffffffff, 0xffffffff,
-0xffffffff, 0xff6b95b8, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0e538b, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xe8f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0xd1f57929,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfffcd9c2, 0xffffffff, 0xffffffff, 0xffffffff, 0xff206094, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff8bacc7, 0xffffffff, 0xffffffff,
-0xfffeece0, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x23f87c2c, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x53f6782b, 0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde7d9, 0xffffffff, 0xffffffff, 0xfff8fafc, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff7199bb, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0x4af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5ff6633, 0x8ef47829, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfffde5d5, 0xffffffff, 0xffffffff, 0xffffffff, 0xff195b91, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff86a9c5, 0xffffffff, 0xffffffff, 0xfffef7f2,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x1bf67b26,
-0xc4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xebf57a2a, 0x50f57929,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcd2b7, 0xffffffff, 0xffffffff, 0xffffffff,
-0xff618eb3, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xffccdae6, 0xffffffff, 0xffffffff, 0xfffde3d2, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0x5df47929, 0x0, 0x0, 0x0, 0x44f47829, 0xe9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x1ef7772b, 0x1af57627, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9af7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd8e3ec, 0xff16588f, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5a89b0, 0xffffffff,
-0xffffffff, 0xffffffff, 0xfffac09c, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4cf5792c,
-0x0, 0x1ff0000, 0x7cf57929, 0xfcf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xa9f4792a, 0xaff8033, 0x0, 0x5ff6633, 0xfbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff57f33, 0xfffef4ed, 0xffffffff, 0xffffffff, 0xffffffff, 0xffb3c9db, 0xff16588f, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4278a4, 0xfff1f5f8, 0xffffffff, 0xffffffff, 0xfffffcfa,
-0xfff68842, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x27f27c27, 0x0, 0x89f6792b,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x7bf57829, 0x1ff0000,
-0x0, 0x0, 0x0, 0xc9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b081,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd5e1eb, 0xff5787ae, 0xff11558d, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff246296, 0xff8cadc8, 0xfff8fafc, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffac09b, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeaf5792b, 0x1ff0000, 0x2af3792b, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf2f6792a, 0x4ef5792b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbcdaf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xfff0f4f8, 0xffc7d7e4, 0xffbdd0df, 0xffd7e3ec, 0xfffefeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xfffcdbc5, 0xfff57b2d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9ff5782a, 0x0,
-0x6bf57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdcf5792a, 0x2bf3772a, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x22f8782d, 0xfcf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff57b2d, 0xfffac39f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff57d31, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0x3bf6792b, 0x0, 0x53f6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xbcf6792a, 0x13f27928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2f6792b, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89f66, 0xfffde6d7, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeece1, 0xfff8a773, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbff67929, 0x0, 0x0, 0x4ff8040, 0xb9f57929,
-0xfff5792a, 0xfff5792a, 0xf4f5792a, 0x7df5782b, 0x4ff8040, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1cf6762e,
-0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57a2c,
-0xfff7985b, 0xfffabf9a, 0xfffcd8c0, 0xfffde5d6, 0xfffde7d9, 0xfffcd9c2, 0xfffbc3a0, 0xfff89c61, 0xfff57b2d, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x2ef47a2c, 0x0, 0x0,
-0x0, 0x1ff0000, 0x27f27c27, 0x3af67b2c, 0xeed8024, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x5df47929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x76f47929, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89f6792b, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xa2f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8af6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa0f57929, 0x3ff5500, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x62f5782a, 0xf6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfaf5792a, 0x75f47a29, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24f8782b, 0xb8f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xc4f5792a, 0x2ef47a2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3df7792a, 0xabf5792a, 0xf8f5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfcf5792b, 0xb4f5782b, 0x49f57a2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11f0782d, 0x54f6792b, 0x92f5792a,
-0xbcf6792a, 0xdbf5792a, 0xeaf5792b, 0xebf57a2a, 0xdcf5792a, 0xbef6792a, 0x97f57a2a, 0x5af47a2b, 0x16f3742e, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-64,64,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29, 0xb1f5792a, 0xd3f5792a, 0xbbf5792a, 0x5cf47a2a, 0x1ff0000, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77f4782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb4f5782b,
-0x12f1802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff5500, 0xf1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xdff5792a, 0x34f57b2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3f5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf8f5792a, 0x69f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x41f37a2b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xa4f6792a, 0xbff742e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2ef47a2c, 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x13f27928, 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xf3f5792a, 0x58f67a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, 0x6ff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x65f5792b, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xcbf57929, 0x20f77828, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xecf5792a, 0x48f4782b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x1bf67b26, 0xcaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfef5792a, 0x88f67a29, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12f1802b, 0x79f4782a, 0xaef57a2b, 0xccf5792b, 0xccf5792b, 0xccf5792b,
-0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b,
-0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b,
-0xccf5792b, 0xd5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xb8f5792a, 0x14f27326, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3bf6792b, 0xeef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe2f5792a, 0x38f67b29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcff802b, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0x6df67a2a, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59f6782b, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xa8f4792b, 0xcff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x43f47a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x2af3792b, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9bf57a2b, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xf1f5792a, 0x4af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x31f5782a, 0x66f5782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b,
-0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x84f57a2b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfff89b5f,
-0xfff9b284, 0xfffabc95, 0xfffbc3a0, 0xfffabb93, 0xfff9b082, 0xfff79659, 0xfff57b2d, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf5792b, 0x5af47a2b, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x2bf3772a, 0xd7f6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b60, 0xfffcd6be, 0xfffffaf7, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff9f5, 0xfffbcfb3, 0xfff79455, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf5792b, 0x4ff5772a, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x5cf47a2a, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff78d4b, 0xfffde0ce, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcd8c0, 0xfff68741, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x2df47728, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7ff6d24, 0x97f57a2a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff9ad7d, 0xfffffaf7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef7f2, 0xfff8a26b, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd4f5792a, 0x8ff8020, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20f77828,
-0xcbf57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff9b387, 0xfffffefe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff4f7fa, 0xffb7cbdc,
-0xff88aac6, 0xff749cbd, 0xff81a5c2, 0xff9fbad1, 0xffdee7ef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xfffffcfb, 0xfff8a671, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0x82f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x4bf57a29, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff8a672, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff2f5f9, 0xff7ba1c0,
-0xff195b91, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4c7fa9, 0xffcbdae6, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xfffffdfc, 0xfff7975a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xf5f5792a, 0x1bf67b26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x3ff5500, 0x80f57a2a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffef5ef, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffd6e2eb, 0xff2c689a, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff11558d, 0xff8fafc9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeede3, 0xfff68035,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8cf6782a, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17f47a2c, 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffe1e9f0, 0xff236295, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff93b2cb, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xfffab98f, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xeef5792a, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x3cf7772b, 0xe5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68137, 0xfffff9f6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xff4d7fa9, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff13568e, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef1e8,
-0xfff57c2e, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4ff5772a, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x73f47a2a, 0xfbf5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff9ac7b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffcbdae6, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff6893b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79a5f, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0xdeb7627, 0xaaf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc7a6,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff7ea3c1, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff1b5c92, 0xfffefeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b589, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd1f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2ff4772b,
-0xdbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcddca, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xff5888af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffe5edf3,
-0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfbf5792a, 0x5ff6633, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5ef47a29, 0xf5f5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffddfcc, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xff5988af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffe8eff4, 0xffffffff,
-0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff711c, 0x9df5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcdcc7, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xff759dbd, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff175990, 0xfffafcfd, 0xffffffff,
-0xffffffff, 0xffffffff, 0xfffbc8a7, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff77b29, 0xcaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe3f5792a, 0x45f47a29, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc8a7, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffbccfdf, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5888af, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b285, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0x28f2792d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929, 0xf0f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xc2f4792a, 0x15f37924, 0x24f8782b,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff8a773, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xfffefeff, 0xff3d75a2, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffc8d8e5,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79252, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0x1ff77b29, 0x0, 0x0, 0x0, 0x4ff8040, 0x8bf6792a, 0xfef5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a,
-0x6ff802b, 0x0, 0x1bf67b26, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff68239, 0xfffff9f5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd0dee9, 0xff175990, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff789fbe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeece0, 0xfff57a2c, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x4ff8040, 0x0, 0x0, 0x18f4752b, 0xc2f4792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfaf5792a, 0x6af57829, 0x0, 0x0, 0x0, 0x3ff5500, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffac09c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffbed0e0, 0xff1c5d92, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff0d528b, 0xff0d528b, 0xff6c96b8, 0xfffcfdfe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9aa79, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x0, 0x0, 0x18f4752b,
-0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xebf57a2a, 0x40f3782c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6843c, 0xfffef4ed, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffdee7ef, 0xff5b8ab0, 0xff0e538b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
-0xff2c689a, 0xffaac2d6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffde6d8, 0xfff57b2d, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0, 0x0, 0xb1f5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xd2f5792b, 0x21f77c27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x81f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b5f, 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffdde7ef, 0xff94b2cc, 0xff6792b6, 0xff5284ac, 0xff5f8cb2, 0xff7ca1c0, 0xffbed1e0,
-0xfffafcfd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef6f0, 0xfff68b46, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x56f67a2a, 0x0, 0x1ef7772b,
-0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xaef57a2b, 0xcff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28f2792d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9ad7d, 0xfffffdfc, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef8f3, 0xfff89b60, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeff5792a, 0x9ff711c, 0x0, 0x4af57929,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0x81f5792a,
-0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89d64, 0xfffef6f1, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xfffeede2, 0xfff78f4d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x92f5792a, 0x0, 0x0, 0x34f57b2c, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf4f5792a, 0x54f6792b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x45f47a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68a45, 0xfffbcfb3, 0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfffac29e,
-0xfff68238, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xf8f5792a, 0x1cf6762e, 0x0, 0x0, 0x1ff0000, 0xc5f57829, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xdef5792b, 0x2ff4772b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbaf5792b,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff79150, 0xfffbc8a7, 0xfffeefe5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-0xffffffff, 0xffffffff, 0xfffde7d9, 0xfffabf99, 0xfff68841, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x89f6792b, 0x0, 0x0, 0x0, 0x0,
-0x13f27928, 0xa2f6792b, 0xf6f5792b, 0xfff5792a, 0xe0f5792a, 0x83f5792b, 0xdeb7627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20f77828, 0xf3f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff78f4c,
-0xfff8a069, 0xfff9ac7c, 0xfffab68c, 0xfff9aa79, 0xfff89e64, 0xfff68842, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xdaf4782a, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5bf4782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf6f5792b,
-0x32f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x59f6782b, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x1ff0000, 0x90f4782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfef5792a, 0x69f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x82f57a29, 0xfef5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0x58f67a29, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52f6792c, 0xeff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xdbf5792a, 0x31f5782a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19f57a29, 0xacf57a2a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x8af6782b, 0x9ff711c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x3bf6792b, 0xbcf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfbf5792a, 0xa1f5782b, 0x23f87c2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2af3792b, 0x8bf6792a, 0xe1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
-0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0xd0f5792a,
-0x75f47a29, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x26f87928, 0x67f5792a, 0x93f5792a, 0xbaf5792b, 0xd2f5792b, 0xddf5792a, 0xebf57a2a, 0xddf5792a,
-0xcef5792a, 0xb1f5792a, 0x89f6792b, 0x5af47a2b, 0x17f47a2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 16, 16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x36f67b2b, 0xa2f6792b, 0x2df47728, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x31f5782a, 0xebf57a2a, 0xf5f5792a, 0x5ff4792b, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1cf6762e, 0xccf5792b, 0xfff5792a, 0xa2f6792b, 0xaff8033, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x52f6792c, 0xe5f5792a, 0xeef5792a, 0xeef5792a,
+ 0xeef5792a, 0xeef5792a, 0xeef5792a, 0xf3f5792a, 0xfff5792a, 0xfff5792a, 0xcdf5792a, 0x22f8782d,
+ 0x0, 0x0, 0x0, 0x0, 0x3cf7772b, 0x98f5792a, 0x99f57a2a, 0x9cf5792b,
+ 0xf3f5792a, 0xfff5792a, 0xfdf5792a, 0xedf69253, 0xf2f9a36e, 0xf4f78a45, 0xfff5792a, 0xeef5792a,
+ 0x3cf7772b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15f37924, 0xbbf5792a,
+ 0xfff5792a, 0xf2f67e32, 0xfefde5d5, 0xffd7e3ec, 0xffa9c1d6, 0xffe3eaf1, 0xfffbcaab, 0xfff57a2b,
+ 0xecf5792a, 0x18f4752b, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe3f5792a, 0xfff5792a,
+ 0xfff5792a, 0xf8fcd0b3, 0xffb5cadc, 0xff10548c, 0xff0d528b, 0xff165990, 0xffd2dfea, 0xfff9ab7a,
+ 0xfff5792a, 0x82f57a29, 0x0, 0x1ff0000, 0x70f67929, 0xfaf5792a, 0xfef5792a, 0xfff5792a,
+ 0xfff5792a, 0xfffef1e9, 0xff6692b6, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff8aacc7, 0xfffbcbac,
+ 0xfff5792a, 0xbef6792a, 0xeed8024, 0xabf5792a, 0xfff5792a, 0xf5f5792a, 0x5cf47a2a, 0xfdf5792a,
+ 0xfff5792a, 0xfffcddca, 0xffb0c7d9, 0xff0f538c, 0xff0d528b, 0xff14578e, 0xffcfdce8, 0xfffab68c,
+ 0xfff5792a, 0xbef6792a, 0xaef57a2b, 0xfff5792a, 0xe2f5792a, 0x32f57a29, 0x0, 0xcef5792a,
+ 0xfff5792a, 0xf7f7904e, 0xfffef6f0, 0xffd1dee9, 0xffa3bdd3, 0xffdde7ef, 0xfffde4d4, 0xfef57d31,
+ 0xfff5792a, 0x84f57a2b, 0x77f4782b, 0xa1f5782b, 0x17f47a2c, 0x0, 0x0, 0x52f6792c,
+ 0xfff5792a, 0xfff5792a, 0xfcf6853d, 0xfffab68b, 0xfffbc5a3, 0xfff9ab7a, 0xfff57c2e, 0xfff5792a,
+ 0xedf5792a, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x7af5792a, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a,
+ 0x3df7792a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x37f6792a, 0xa6f47929, 0xe3f5792a, 0xf2f6792a, 0xd6f57a2a, 0x8bf6792a, 0x17f47a2c,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 32, 32, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x13f27928, 0x5ff4792b, 0x46f4782c, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1ff0000, 0xdaf4782a, 0xfff5792a, 0xfff5792a, 0xa9f4792a, 0xdeb7627,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd8f6782b,
+ 0x2cf37a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xcff802b, 0xacf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xf7f5792a, 0x63f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfdf5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xa2f6792b, 0x9ff711c, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29, 0xf0f5792b,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x22f8782d, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x4ff5772a, 0xcbf57929, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a,
+ 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xeef5792a, 0xeef5792a, 0xf8f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a, 0x4cf5792c, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x17f47a2c, 0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a, 0x86f57a2a, 0x3ff5500,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x10ef8030, 0xe6f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a,
+ 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xcff802b, 0x32f57a29, 0x33f57828, 0x33f57828, 0x33f57828, 0x33f57828, 0x3ef77729,
+ 0xcdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfcf68035, 0xfff9b284, 0xfffcd3ba,
+ 0xfffde1cf, 0xfffcdac5, 0xfffac39f, 0xfff79557, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xcef5792a, 0x13f27928, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x27f27c27, 0xd3f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef9ac7a, 0xfffef8f3, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcd5bc, 0xfff6833a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xb5f5792a, 0x2ff8000, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x56f67a2a, 0xf2f6792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b488, 0xffffffff, 0xffffffff, 0xffe4ecf2, 0xff7ba1c0,
+ 0xff4e80aa, 0xff5a89b0, 0xff94b2cc, 0xfff7fafb, 0xffffffff, 0xfffde7d9, 0xfff68036, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x6ff802b, 0x91f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfaf78e4b, 0xfffffcfb, 0xffffffff, 0xffc0d2e1, 0xff165990, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff326c9d, 0xffecf1f6, 0xffffffff, 0xfffbc8a8, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xd8f6782b, 0x2ff8000, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1df67b2c, 0xc6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfffbcaab, 0xffffffff, 0xfff2f5f9, 0xff206094, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff5b8ab0, 0xffffffff, 0xfffffbf8, 0xfff68137,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x31f5782a, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x46f4782c, 0xeaf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfffde9dc, 0xffffffff, 0xffb5cadc, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff11558d, 0xfff8fafc, 0xffffffff, 0xfff89c62,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6ff67a29, 0x0, 0x0, 0x0, 0x2ff8000,
+ 0x7ff5782a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfffeeee4, 0xffffffff, 0xffb3c9db, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff10548c, 0xfff8fafc, 0xffffffff, 0xfff8a169,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x87f6792a, 0x0, 0x0, 0x14f27326, 0xb8f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf0f5792b, 0x56f67a2a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfffcdbc6, 0xffffffff, 0xffeef3f7, 0xff195b91, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4f81ab, 0xffffffff, 0xffffffff, 0xfff78d4b,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8df4792a, 0x0, 0x37f6792a, 0xe1f5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd9f4792a, 0x28f2792d, 0x4ff8040, 0xf7f5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff9ad7d, 0xffffffff, 0xffffffff, 0xffaac2d6, 0xff11558d, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff256396, 0xffdce6ee, 0xffffffff, 0xfffde5d6, 0xfff57a2b,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x6bf57a2b, 0x2ff4772b, 0xf4f5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xb7f5792a, 0x10ef8030, 0x0, 0x0, 0xcbf57929, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff57c2e, 0xfffde3d2, 0xffffffff, 0xffffffff, 0xffcedce7, 0xff6390b4,
+ 0xff356e9e, 0xff3d75a2, 0xff7da2c1, 0xffeaf0f5, 0xffffffff, 0xfffffdfc, 0xfff7995d, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x38f67b29, 0x95f57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0x8cf6782a, 0x3ff5500, 0x0, 0x0, 0x0, 0x6ff67a29, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde4d4, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff8a773, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xd6f57a2a, 0x1ff0000, 0x79f4782a, 0xfff5792a, 0xfff5792a, 0xf6f5792b,
+ 0x5ef47a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0xeed8024, 0xecf5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfffab68b, 0xfffeede2, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xfffff9f6, 0xfffbd0b4, 0xfff78d4b, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0x62f5782a, 0x0, 0x3ff5500, 0x60f47a2b, 0x76f47929, 0x1ff77b29,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929,
+ 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68841,
+ 0xfff79556, 0xfff78f4c, 0xfff57d30, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xb5f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x80f57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xd2f5792b, 0x15f37924, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x69f57929, 0xfaf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a,
+ 0xfee7722, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x28f2792d, 0xb6f5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe4f5792b, 0x5ef47a29, 0x1ff0000,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0x77f4782b, 0xbaf5792b, 0xd5f5792a,
+ 0xecf5792a, 0xe1f5792a, 0xc5f57829, 0x98f5792a, 0x45f47a29, 0x4ff8040, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 48, 48, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdeb7627, 0x1af57627,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x7ff6d24, 0xa2f6792b, 0xfdf5792a, 0xfff5792a,
+ 0xd3f5792a, 0x36f67b2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x6ef6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xf9f5792a, 0x6bf57a2b, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x59f6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa6f47929, 0xcff802b, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfef5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd6f57a2a, 0x29f3762c, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4cf5792c, 0xf1f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x59f6782b, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2df47728,
+ 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a,
+ 0x6ff802b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x13f27928, 0xbcf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xccf5792b, 0x21f77c27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xecf5792a, 0x49f57a2a, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31f5782a, 0xa2f6792b,
+ 0xcaf5792a, 0xcff5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a,
+ 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a,
+ 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xfbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfdf5792a, 0x81f5792a, 0x3ff5500, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff77928, 0xf7f5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x15f37924, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3f57929, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe3f5792a, 0x39f67928, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff5782a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x6df67a2a,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x12f1802b, 0x95f57a2b, 0xd0f5792a,
+ 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xddf5792a, 0xd7f6792a, 0xccf5792b, 0xccf5792b, 0xccf5792b,
+ 0xd0f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68035, 0xfff68c48, 0xfff78d4b, 0xfff68239, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0x89f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19f57a29,
+ 0xc0f4792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff68c49, 0xfffbc4a1, 0xfffde9dd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef0e7,
+ 0xfffbcbad, 0xfff79556, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0x95f57a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff77928, 0xe7f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57f34, 0xfffbc8a8,
+ 0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xfffcd7bf, 0xfff6863f, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0x62f5782a, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x77f4782b, 0xfbf5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffde9dc, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcfdfe, 0xffe0e9f0, 0xffd4e0eb, 0xffedf2f6, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef3ed, 0xfff79251, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x10ef8030, 0xb1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68035, 0xfffdebde, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffe6edf3, 0xff7199bb, 0xff1e5e93, 0xff0d528b, 0xff0d528b, 0xff0e538b, 0xff3b73a1,
+ 0xffa5bfd4, 0xfffefeff, 0xffffffff, 0xffffffff, 0xfffef5ef, 0xfff68a45, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbaf5792b, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x32f57a29, 0xddf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffc6d6e4, 0xff1f5f94, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff5888af, 0xfff8fafc, 0xffffffff, 0xffffffff, 0xfffddecb, 0xfff57a2b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x36f67b2b, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x65f5792b, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68944, 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffe3ebf2,
+ 0xff1b5c92, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff6b95b8, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff89c62, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9bf57a2b, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaff8033,
+ 0xa0f57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffabc94, 0xffffffff, 0xffffffff, 0xffffffff, 0xff6b95b8,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0e538b, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xe8f5792a, 0x1ff0000, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25f87c29, 0xd1f57929,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcd9c2, 0xffffffff, 0xffffffff, 0xffffffff, 0xff206094,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff8bacc7, 0xffffffff, 0xffffffff, 0xfffeece0, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x23f87c2c, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x53f6782b, 0xf1f5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde7d9, 0xffffffff, 0xffffffff, 0xfff8fafc, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff7199bb, 0xffffffff, 0xffffffff, 0xfffffaf7, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4af57929, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x5ff6633, 0x8ef47829, 0xfef5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffde5d5, 0xffffffff, 0xffffffff, 0xffffffff, 0xff195b91,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff86a9c5, 0xffffffff, 0xffffffff, 0xfffef7f2, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5ef47a29, 0x0, 0x0,
+ 0x0, 0x0, 0x1bf67b26, 0xc4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xebf57a2a, 0x50f57929, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcd2b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xff618eb3,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xffccdae6, 0xffffffff, 0xffffffff, 0xfffde3d2, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x5df47929, 0x0, 0x0,
+ 0x0, 0x44f47829, 0xe9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xcef5792a, 0x1ef7772b, 0x1af57627, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9af7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd8e3ec,
+ 0xff16588f, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff5a89b0, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffac09c, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4cf5792c, 0x0, 0x1ff0000,
+ 0x7cf57929, 0xfcf5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xa9f4792a, 0xaff8033, 0x0, 0x5ff6633, 0xfbf5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57f33, 0xfffef4ed, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffb3c9db, 0xff16588f, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff4278a4, 0xfff1f5f8, 0xffffffff, 0xffffffff, 0xfffffcfa, 0xfff68842, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x27f27c27, 0x0, 0x89f6792b,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfdf5792a,
+ 0x7bf57829, 0x1ff0000, 0x0, 0x0, 0x0, 0xc9f5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b081, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffd5e1eb, 0xff5787ae, 0xff11558d, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff246296,
+ 0xff8cadc8, 0xfff8fafc, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffac09b, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeaf5792b, 0x1ff0000, 0x2af3792b, 0xfef5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf2f6792a, 0x4ef5792b,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x80f57a2a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbcdaf, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xfff0f4f8, 0xffc7d7e4, 0xffbdd0df, 0xffd7e3ec, 0xfffefeff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcdbc5, 0xfff57b2d, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9ff5782a, 0x0, 0x6bf57a2b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdcf5792a, 0x2bf3772a, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x22f8782d, 0xfcf5792b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57b2d, 0xfffac39f, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcfb3, 0xfff57d31, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x3bf6792b, 0x0, 0x53f6782b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbcf6792a, 0x13f27928, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2f6792b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89f66,
+ 0xfffde6d7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xfffeece1, 0xfff8a773, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xbff67929, 0x0, 0x0, 0x4ff8040, 0xb9f57929,
+ 0xfff5792a, 0xfff5792a, 0xf4f5792a, 0x7df5782b, 0x4ff8040, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1cf6762e, 0xf1f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff57a2c, 0xfff7985b, 0xfffabf9a, 0xfffcd8c0, 0xfffde5d6, 0xfffde7d9, 0xfffcd9c2, 0xfffbc3a0,
+ 0xfff89c61, 0xfff57b2d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x2ef47a2c, 0x0, 0x0, 0x0, 0x1ff0000,
+ 0x27f27c27, 0x3af67b2c, 0xeed8024, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5df47929,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0x76f47929, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x89f6792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xa2f6792b, 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x8af6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xa0f57929, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x62f5782a, 0xf6f5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x75f47a29,
+ 0x1ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x24f8782b, 0xb8f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xc4f5792a, 0x2ef47a2c, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3df7792a, 0xabf5792a, 0xf8f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfcf5792b, 0xb4f5782b, 0x49f57a2a, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11f0782d,
+ 0x54f6792b, 0x92f5792a, 0xbcf6792a, 0xdbf5792a, 0xeaf5792b, 0xebf57a2a, 0xdcf5792a, 0xbef6792a,
+ 0x97f57a2a, 0x5af47a2b, 0x16f3742e, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64, 64,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4bf57a29,
+ 0xb1f5792a, 0xd3f5792a, 0xbbf5792a, 0x5cf47a2a, 0x1ff0000, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77f4782b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xb4f5782b, 0x12f1802b, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff5500, 0xf1f5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdff5792a, 0x34f57b2c, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3f5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf8f5792a, 0x69f57929,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x41f37a2b, 0xf4f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xa4f6792a, 0xbff742e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2ef47a2c,
+ 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xd7f6792a, 0x2bf3772a, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x13f27928, 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x58f67a29, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x4ff8040, 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x99f57a2a, 0x6ff802b, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x65f5792b, 0xf9f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xcbf57929, 0x20f77828, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3af67b2c, 0xe7f5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xecf5792a, 0x48f4782b,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1bf67b26, 0xcaf5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a,
+ 0x88f67a29, 0x3ff5500, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x12f1802b, 0x79f4782a, 0xaef57a2b, 0xccf5792b, 0xccf5792b,
+ 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b,
+ 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b,
+ 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xccf5792b, 0xd5f5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xb8f5792a, 0x14f27326, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x3bf6792b, 0xeef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xe2f5792a, 0x38f67b29, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0xcff802b, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf9f5792a, 0x6df67a2a, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x59f6782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xa8f4792b, 0xcff802b, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x43f47a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x2af3792b,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x9bf57a2b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf1f5792a,
+ 0x4af57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x31f5782a, 0x66f5782b, 0x77f4782b, 0x77f4782b, 0x77f4782b,
+ 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b, 0x77f4782b,
+ 0x84f57a2b, 0xf4f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff57d31, 0xfff89b5f, 0xfff9b284,
+ 0xfffabc95, 0xfffbc3a0, 0xfffabb93, 0xfff9b082, 0xfff79659, 0xfff57b2d, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfcf5792b, 0x5af47a2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2bf3772a,
+ 0xd7f6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b60, 0xfffcd6be, 0xfffffaf7, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff9f5, 0xfffbcfb3, 0xfff79455,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfcf5792b, 0x4ff5772a, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5cf47a2a, 0xf4f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff78d4b, 0xfffde0ce, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xfffcd8c0, 0xfff68741, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xf3f5792a, 0x2df47728, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x7ff6d24, 0x97f57a2a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff9ad7d, 0xfffffaf7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xfffef7f2, 0xfff8a26b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd4f5792a, 0x8ff8020, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x20f77828, 0xcbf57929, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9b387,
+ 0xfffffefe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff4f7fa, 0xffb7cbdc,
+ 0xff88aac6, 0xff749cbd, 0xff81a5c2, 0xff9fbad1, 0xffdee7ef, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xfffffcfb, 0xfff8a671, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x82f57a29, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x4bf57a29, 0xedf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff8a672, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff2f5f9, 0xff7ba1c0, 0xff195b91, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff4c7fa9, 0xffcbdae6, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffdfc, 0xfff7975a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0x1bf67b26, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x3ff5500, 0x80f57a2a, 0xfdf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6863f, 0xfffef5ef, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffd6e2eb, 0xff2c689a, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff11558d, 0xff8fafc9,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeede3, 0xfff68035, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x8cf6782a, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17f47a2c,
+ 0xbdf6792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc9aa, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffe1e9f0, 0xff236295, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff93b2cb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffab98f, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeef5792a, 0x9ff711c, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3cf7772b, 0xe5f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68137, 0xfffff9f6, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xff4d7fa9, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff13568e, 0xffd6e2eb, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef1e8, 0xfff57c2e, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x4ff5772a, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x73f47a2a, 0xfbf5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9ac7b, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffcbdae6, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff6893b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79a5f, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0xdeb7627, 0xaaf57a2a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc7a6, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xff7ea3c1, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff1b5c92, 0xfffefeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b589, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd1f57929, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x2ff4772b, 0xdbf5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcddca, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xff5888af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xffe5edf3, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfbf5792a, 0x5ff6633,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x5ef47a29, 0xf5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffddfcc, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xff5988af, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xffe8eff4, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbcbac, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x19f57a29,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff711c,
+ 0x9df5782a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffcdcc7, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xff759dbd, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff175990, 0xfffafcfd, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffbc8a7, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x2bf3772a,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ff77b29, 0xcaf5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xe3f5792a, 0x45f47a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffbc8a7, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffbccfdf, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff5888af, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9b285, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x28f2792d,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x50f57929, 0xf0f5792b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xc2f4792a, 0x15f37924, 0x24f8782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff8a773, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xfffefeff, 0xff3d75a2, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xffc8d8e5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff79252, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x1ff77b29,
+ 0x0, 0x0, 0x0, 0x4ff8040, 0x8bf6792a, 0xfef5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0x99f57a2a, 0x6ff802b, 0x0, 0x1bf67b26, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff68239, 0xfffff9f5, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffd0dee9, 0xff175990, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff789fbe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffeece0, 0xfff57a2c, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x4ff8040,
+ 0x0, 0x0, 0x18f4752b, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x6af57829,
+ 0x0, 0x0, 0x0, 0x3ff5500, 0xf7f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfffac09c, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffbed0e0, 0xff1c5d92, 0xff0d528b, 0xff0d528b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff6c96b8,
+ 0xfffcfdfe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff9aa79, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd7f6792a, 0x0,
+ 0x0, 0x18f4752b, 0xdef5792b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xebf57a2a, 0x40f3782c, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff6843c, 0xfffef4ed, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffdee7ef, 0xff5b8ab0, 0xff0e538b, 0xff0d528b,
+ 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff0d528b, 0xff2c689a, 0xffaac2d6, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffde6d8, 0xfff57b2d, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x9af57929, 0x0,
+ 0x0, 0xb1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xd2f5792b, 0x21f77c27, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x81f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff89b5f, 0xfffffdfc,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffdde7ef, 0xff94b2cc,
+ 0xff6792b6, 0xff5284ac, 0xff5f8cb2, 0xff7ca1c0, 0xffbed1e0, 0xfffafcfd, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffef6f0, 0xfff68b46, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x56f67a2a, 0x0,
+ 0x1ef7772b, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xaef57a2b, 0xcff802b, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x28f2792d, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff9ad7d,
+ 0xfffffdfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xfffef8f3, 0xfff89b60, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xeff5792a, 0x9ff711c, 0x0,
+ 0x4af57929, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfef5792a, 0x81f5792a, 0x1ff0000, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2f4792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff89d64, 0xfffef6f1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xfffeede2, 0xfff78f4d, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x92f5792a, 0x0, 0x0,
+ 0x34f57b2c, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xf4f5792a, 0x54f6792b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x45f47a29, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff68a45, 0xfffbcfb3, 0xfffffefd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffaf7,
+ 0xfffac29e, 0xfff68238, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf8f5792a, 0x1cf6762e, 0x0, 0x0,
+ 0x1ff0000, 0xc5f57829, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdef5792b,
+ 0x2ff4772b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbaf5792b, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff79150, 0xfffbc8a7, 0xfffeefe5, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffde7d9, 0xfffabf99, 0xfff68841,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0x89f6792b, 0x0, 0x0, 0x0,
+ 0x0, 0x13f27928, 0xa2f6792b, 0xf6f5792b, 0xfff5792a, 0xe0f5792a, 0x83f5792b, 0xdeb7627,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20f77828, 0xf3f5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff78f4c, 0xfff8a069,
+ 0xfff9ac7c, 0xfffab68c, 0xfff9aa79, 0xfff89e64, 0xfff68842, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdaf4782a, 0x9ff711c, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x9ff711c, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5bf4782a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xf6f5792b, 0x32f57a29, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x88f67a29, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfdf5792a, 0x59f6782b, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1ff0000, 0x90f4782b, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfef5792a, 0x69f57929, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x1ff0000, 0x82f57a29, 0xfef5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xf5f5792a,
+ 0x58f67a29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x52f6792c, 0xeff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xdbf5792a, 0x31f5782a,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x19f57a29, 0xacf57a2a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfaf5792a, 0x8af6782b, 0x9ff711c, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3bf6792b, 0xbcf6792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfbf5792a, 0xa1f5782b, 0x23f87c2c, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x2af3792b, 0x8bf6792a, 0xe1f5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a,
+ 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfff5792a, 0xfef5792a,
+ 0xd0f5792a, 0x75f47a29, 0x19f57a29, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x26f87928, 0x67f5792a, 0x93f5792a, 0xbaf5792b, 0xd2f5792b,
+ 0xddf5792a, 0xebf57a2a, 0xddf5792a, 0xcef5792a, 0xb1f5792a, 0x89f6792b, 0x5af47a2b, 0x17f47a2c,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
};
-#endif // __GHOST_ICONX11_H__
+#endif // __GHOST_ICONX11_H__
diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp
index 94abf92dae4..531dbe4b444 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.cpp
+++ b/intern/ghost/intern/GHOST_ImeWin32.cpp
@@ -19,18 +19,16 @@
* The Original Code is: some of this file.
*/
-
/** \file
* \ingroup GHOST
*/
#ifdef WITH_INPUT_IME
-#include "GHOST_C-api.h"
-#include "GHOST_ImeWin32.h"
-#include "GHOST_WindowWin32.h"
-#include "utfconv.h"
-
+# include "GHOST_C-api.h"
+# include "GHOST_ImeWin32.h"
+# include "GHOST_WindowWin32.h"
+# include "utfconv.h"
GHOST_ImeWin32::GHOST_ImeWin32()
: ime_status_(false),
@@ -43,472 +41,449 @@ GHOST_ImeWin32::GHOST_ImeWin32()
{
}
-
GHOST_ImeWin32::~GHOST_ImeWin32()
{
}
-
bool GHOST_ImeWin32::SetInputLanguage()
{
- /**
- * Retrieve the current keyboard layout from Windows and determine whether
- * or not the current input context has IMEs.
- * Also save its input language for language-specific operations required
- * while composing a text.
- */
- HKL keyboard_layout = ::GetKeyboardLayout(0);
- input_language_id_ = LOWORD(keyboard_layout);
- ime_status_ = ::ImmIsIME(keyboard_layout);
- return ime_status_;
+ /**
+ * Retrieve the current keyboard layout from Windows and determine whether
+ * or not the current input context has IMEs.
+ * Also save its input language for language-specific operations required
+ * while composing a text.
+ */
+ HKL keyboard_layout = ::GetKeyboardLayout(0);
+ input_language_id_ = LOWORD(keyboard_layout);
+ ime_status_ = ::ImmIsIME(keyboard_layout);
+ return ime_status_;
}
-
void GHOST_ImeWin32::CreateImeWindow(HWND window_handle)
{
- /**
- * When a user disables TSF (Text Service Framework) and CUAS (Cicero
- * Unaware Application Support), Chinese IMEs somehow ignore function calls
- * to ::ImmSetCandidateWindow(), i.e. they do not move their candidate
- * window to the position given as its parameters, and use the position
- * of the current system caret instead, i.e. it uses ::GetCaretPos() to
- * retrieve the position of their IME candidate window.
- * Therefore, we create a temporary system caret for Chinese IMEs and use
- * it during this input context.
- * Since some third-party Japanese IME also uses ::GetCaretPos() to determine
- * their window position, we also create a caret for Japanese IMEs.
- */
- if (PRIMARYLANGID(input_language_id_) == LANG_CHINESE ||
- PRIMARYLANGID(input_language_id_) == LANG_JAPANESE) {
- if (!system_caret_) {
- if (::CreateCaret(window_handle, NULL, 1, 1)) {
- system_caret_ = true;
- }
- }
- }
- /* Restore the positions of the IME windows. */
- UpdateImeWindow(window_handle);
+ /**
+ * When a user disables TSF (Text Service Framework) and CUAS (Cicero
+ * Unaware Application Support), Chinese IMEs somehow ignore function calls
+ * to ::ImmSetCandidateWindow(), i.e. they do not move their candidate
+ * window to the position given as its parameters, and use the position
+ * of the current system caret instead, i.e. it uses ::GetCaretPos() to
+ * retrieve the position of their IME candidate window.
+ * Therefore, we create a temporary system caret for Chinese IMEs and use
+ * it during this input context.
+ * Since some third-party Japanese IME also uses ::GetCaretPos() to determine
+ * their window position, we also create a caret for Japanese IMEs.
+ */
+ if (PRIMARYLANGID(input_language_id_) == LANG_CHINESE ||
+ PRIMARYLANGID(input_language_id_) == LANG_JAPANESE) {
+ if (!system_caret_) {
+ if (::CreateCaret(window_handle, NULL, 1, 1)) {
+ system_caret_ = true;
+ }
+ }
+ }
+ /* Restore the positions of the IME windows. */
+ UpdateImeWindow(window_handle);
}
-
-void GHOST_ImeWin32::SetImeWindowStyle(HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam, BOOL *handled)
+void GHOST_ImeWin32::SetImeWindowStyle(
+ HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam, BOOL *handled)
{
- /**
- * To prevent the IMM (Input Method Manager) from displaying the IME
- * composition window, Update the styles of the IME windows and EXPLICITLY
- * call ::DefWindowProc() here.
- * NOTE(hbono): We can NEVER let WTL call ::DefWindowProc() when we update
- * the styles of IME windows because the 'lparam' variable is a local one
- * and all its updates disappear in returning from this function, i.e. WTL
- * does not call ::DefWindowProc() with our updated 'lparam' value but call
- * the function with its original value and over-writes our window styles.
- */
- *handled = TRUE;
- lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
- ::DefWindowProc(window_handle, message, wparam, lparam);
+ /**
+ * To prevent the IMM (Input Method Manager) from displaying the IME
+ * composition window, Update the styles of the IME windows and EXPLICITLY
+ * call ::DefWindowProc() here.
+ * NOTE(hbono): We can NEVER let WTL call ::DefWindowProc() when we update
+ * the styles of IME windows because the 'lparam' variable is a local one
+ * and all its updates disappear in returning from this function, i.e. WTL
+ * does not call ::DefWindowProc() with our updated 'lparam' value but call
+ * the function with its original value and over-writes our window styles.
+ */
+ *handled = TRUE;
+ lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
+ ::DefWindowProc(window_handle, message, wparam, lparam);
}
-
void GHOST_ImeWin32::DestroyImeWindow(HWND window_handle)
{
- /* Destroy the system caret if we have created for this IME input context. */
- if (system_caret_) {
- ::DestroyCaret();
- system_caret_ = false;
- }
+ /* Destroy the system caret if we have created for this IME input context. */
+ if (system_caret_) {
+ ::DestroyCaret();
+ system_caret_ = false;
+ }
}
-
void GHOST_ImeWin32::MoveImeWindow(HWND window_handle, HIMC imm_context)
{
- int x = caret_rect_.m_l;
- int y = caret_rect_.m_t;
- const int kCaretMargin = 1;
- /**
- * As written in a comment in GHOST_ImeWin32::CreateImeWindow(),
- * Chinese IMEs ignore function calls to ::ImmSetCandidateWindow()
- * when a user disables TSF (Text Service Framework) and CUAS (Cicero
- * Unaware Application Support).
- * On the other hand, when a user enables TSF and CUAS, Chinese IMEs
- * ignore the position of the current system caret and uses the
- * parameters given to ::ImmSetCandidateWindow() with its 'dwStyle'
- * parameter CFS_CANDIDATEPOS.
- * Therefore, we do not only call ::ImmSetCandidateWindow() but also
- * set the positions of the temporary system caret if it exists.
- */
- CANDIDATEFORM candidate_position = { 0, CFS_CANDIDATEPOS, { x, y },
- { 0, 0, 0, 0 } };
- ::ImmSetCandidateWindow(imm_context, &candidate_position);
- if (system_caret_) {
- switch (PRIMARYLANGID(input_language_id_)) {
- case LANG_JAPANESE:
- ::SetCaretPos(x, y + caret_rect_.getHeight());
- break;
- default:
- ::SetCaretPos(x, y);
- break;
- }
- }
- if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) {
- /**
- * Chinese IMEs and Japanese IMEs require the upper-left corner of
- * the caret to move the position of their candidate windows.
- * On the other hand, Korean IMEs require the lower-left corner of the
- * caret to move their candidate windows.
- */
- y += kCaretMargin;
- }
- /**
- * Japanese IMEs and Korean IMEs also use the rectangle given to
- * ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE
- * to move their candidate windows when a user disables TSF and CUAS.
- * Therefore, we also set this parameter here.
- */
- CANDIDATEFORM exclude_rectangle = { 0, CFS_EXCLUDE, { x, y },
- { x, y, x + caret_rect_.getWidth(), y + caret_rect_.getHeight() } };
- ::ImmSetCandidateWindow(imm_context, &exclude_rectangle);
+ int x = caret_rect_.m_l;
+ int y = caret_rect_.m_t;
+ const int kCaretMargin = 1;
+ /**
+ * As written in a comment in GHOST_ImeWin32::CreateImeWindow(),
+ * Chinese IMEs ignore function calls to ::ImmSetCandidateWindow()
+ * when a user disables TSF (Text Service Framework) and CUAS (Cicero
+ * Unaware Application Support).
+ * On the other hand, when a user enables TSF and CUAS, Chinese IMEs
+ * ignore the position of the current system caret and uses the
+ * parameters given to ::ImmSetCandidateWindow() with its 'dwStyle'
+ * parameter CFS_CANDIDATEPOS.
+ * Therefore, we do not only call ::ImmSetCandidateWindow() but also
+ * set the positions of the temporary system caret if it exists.
+ */
+ CANDIDATEFORM candidate_position = {0, CFS_CANDIDATEPOS, {x, y}, {0, 0, 0, 0}};
+ ::ImmSetCandidateWindow(imm_context, &candidate_position);
+ if (system_caret_) {
+ switch (PRIMARYLANGID(input_language_id_)) {
+ case LANG_JAPANESE:
+ ::SetCaretPos(x, y + caret_rect_.getHeight());
+ break;
+ default:
+ ::SetCaretPos(x, y);
+ break;
+ }
+ }
+ if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) {
+ /**
+ * Chinese IMEs and Japanese IMEs require the upper-left corner of
+ * the caret to move the position of their candidate windows.
+ * On the other hand, Korean IMEs require the lower-left corner of the
+ * caret to move their candidate windows.
+ */
+ y += kCaretMargin;
+ }
+ /**
+ * Japanese IMEs and Korean IMEs also use the rectangle given to
+ * ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE
+ * to move their candidate windows when a user disables TSF and CUAS.
+ * Therefore, we also set this parameter here.
+ */
+ CANDIDATEFORM exclude_rectangle = {
+ 0, CFS_EXCLUDE, {x, y}, {x, y, x + caret_rect_.getWidth(), y + caret_rect_.getHeight()}};
+ ::ImmSetCandidateWindow(imm_context, &exclude_rectangle);
}
-
void GHOST_ImeWin32::UpdateImeWindow(HWND window_handle)
{
- /* Just move the IME window attached to the given window. */
- if (caret_rect_.m_l >= 0 && caret_rect_.m_t >= 0) {
- HIMC imm_context = ::ImmGetContext(window_handle);
- if (imm_context) {
- MoveImeWindow(window_handle, imm_context);
- ::ImmReleaseContext(window_handle, imm_context);
- }
- }
+ /* Just move the IME window attached to the given window. */
+ if (caret_rect_.m_l >= 0 && caret_rect_.m_t >= 0) {
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ MoveImeWindow(window_handle, imm_context);
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ }
}
-
void GHOST_ImeWin32::CleanupComposition(HWND window_handle)
{
- /**
- * Notify the IMM attached to the given window to complete the ongoing
- * composition, (this case happens when the given window is de-activated
- * while composing a text and re-activated), and reset the omposition status.
- */
- if (is_composing_) {
- HIMC imm_context = ::ImmGetContext(window_handle);
- if (imm_context) {
- ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
- ::ImmReleaseContext(window_handle, imm_context);
- }
- ResetComposition(window_handle);
- }
+ /**
+ * Notify the IMM attached to the given window to complete the ongoing
+ * composition, (this case happens when the given window is de-activated
+ * while composing a text and re-activated), and reset the omposition status.
+ */
+ if (is_composing_) {
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ ResetComposition(window_handle);
+ }
}
-
void GHOST_ImeWin32::CheckFirst(HWND window_handle)
{
- if (is_first) {
- this->EndIME(window_handle);
- is_first = false;
- }
+ if (is_first) {
+ this->EndIME(window_handle);
+ is_first = false;
+ }
}
-
void GHOST_ImeWin32::ResetComposition(HWND window_handle)
{
- /* Currently, just reset the composition status. */
- is_composing_ = false;
+ /* Currently, just reset the composition status. */
+ is_composing_ = false;
}
-
void GHOST_ImeWin32::CompleteComposition(HWND window_handle, HIMC imm_context)
{
- /**
- * We have to confirm there is an ongoing composition before completing it.
- * This is for preventing some IMEs from getting confused while completing an
- * ongoing composition even if they do not have any ongoing compositions.)
- */
- if (is_composing_) {
- ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
- ResetComposition(window_handle);
- }
+ /**
+ * We have to confirm there is an ongoing composition before completing it.
+ * This is for preventing some IMEs from getting confused while completing an
+ * ongoing composition even if they do not have any ongoing compositions.)
+ */
+ if (is_composing_) {
+ ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+ ResetComposition(window_handle);
+ }
}
-
void GHOST_ImeWin32::GetCaret(HIMC imm_context, LPARAM lparam, ImeComposition *composition)
{
- /**
- * This operation is optional and language-dependent because the caret
- * style is depended on the language, e.g.:
- * * Korean IMEs: the caret is a blinking block,
- * (It contains only one hangul character);
- * * Chinese IMEs: the caret is a blinking line,
- * (i.e. they do not need to retrieve the target selection);
- * * Japanese IMEs: the caret is a selection (or underlined) block,
- * (which can contain one or more Japanese characters).
- */
- int target_start = -1;
- int target_end = -1;
- switch (PRIMARYLANGID(input_language_id_)) {
- case LANG_KOREAN:
- if (lparam & CS_NOMOVECARET) {
- target_start = 0;
- target_end = 1;
- }
- break;
- case LANG_CHINESE:
- {
- int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0);
- if (clause_size) {
- static std::vector<unsigned long> clauses;
- clause_size = clause_size / sizeof(clauses[0]);
- clauses.resize(clause_size);
- ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, &clauses[0],
- sizeof(clauses[0]) *clause_size);
- if (composition->cursor_position == composition->ime_string.size()) {
- target_start = clauses[clause_size - 2];
- target_end = clauses[clause_size - 1];
- }
- else {
- for (int i = 0; i < clause_size - 1; i++) {
- if (clauses[i] == composition->cursor_position) {
- target_start = clauses[i];
- target_end = clauses[i + 1];
- break;
- }
- }
- }
- }
- else {
- if (composition->cursor_position != -1) {
- target_start = composition->cursor_position;
- target_end = composition->ime_string.size();
- }
- }
- break;
- }
- case LANG_JAPANESE:
-
- /**
- * For Japanese IMEs, the robustest way to retrieve the caret
- * is scanning the attribute of the latest composition string and
- * retrieving the begining and the end of the target clause, i.e.
- * a clause being converted.
- */
- if (lparam & GCS_COMPATTR) {
- int attribute_size = ::ImmGetCompositionStringW(imm_context,
- GCS_COMPATTR,
- NULL, 0);
- if (attribute_size > 0) {
- char *attribute_data = new char[attribute_size];
- if (attribute_data) {
- ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR,
- attribute_data, attribute_size);
- for (target_start = 0; target_start < attribute_size;
- ++target_start) {
- if (IsTargetAttribute(attribute_data[target_start]))
- break;
- }
- for (target_end = target_start; target_end < attribute_size;
- ++target_end) {
- if (!IsTargetAttribute(attribute_data[target_end]))
- break;
- }
- if (target_start == attribute_size) {
- /**
- * This composition clause does not contain any target clauses,
- * i.e. this clauses is an input clause.
- * We treat whole this clause as a target clause.
- */
- target_end = target_start;
- target_start = 0;
- }
- if (target_start != -1 && target_start < attribute_size &&
- attribute_data[target_start] == ATTR_TARGET_NOTCONVERTED)
- {
- composition->cursor_position = target_start;
- }
- }
- delete[] attribute_data;
- }
- }
- break;
- }
- composition->target_start = target_start;
- composition->target_end = target_end;
+ /**
+ * This operation is optional and language-dependent because the caret
+ * style is depended on the language, e.g.:
+ * * Korean IMEs: the caret is a blinking block,
+ * (It contains only one hangul character);
+ * * Chinese IMEs: the caret is a blinking line,
+ * (i.e. they do not need to retrieve the target selection);
+ * * Japanese IMEs: the caret is a selection (or underlined) block,
+ * (which can contain one or more Japanese characters).
+ */
+ int target_start = -1;
+ int target_end = -1;
+ switch (PRIMARYLANGID(input_language_id_)) {
+ case LANG_KOREAN:
+ if (lparam & CS_NOMOVECARET) {
+ target_start = 0;
+ target_end = 1;
+ }
+ break;
+ case LANG_CHINESE: {
+ int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0);
+ if (clause_size) {
+ static std::vector<unsigned long> clauses;
+ clause_size = clause_size / sizeof(clauses[0]);
+ clauses.resize(clause_size);
+ ImmGetCompositionStringW(
+ imm_context, GCS_COMPCLAUSE, &clauses[0], sizeof(clauses[0]) * clause_size);
+ if (composition->cursor_position == composition->ime_string.size()) {
+ target_start = clauses[clause_size - 2];
+ target_end = clauses[clause_size - 1];
+ }
+ else {
+ for (int i = 0; i < clause_size - 1; i++) {
+ if (clauses[i] == composition->cursor_position) {
+ target_start = clauses[i];
+ target_end = clauses[i + 1];
+ break;
+ }
+ }
+ }
+ }
+ else {
+ if (composition->cursor_position != -1) {
+ target_start = composition->cursor_position;
+ target_end = composition->ime_string.size();
+ }
+ }
+ break;
+ }
+ case LANG_JAPANESE:
+
+ /**
+ * For Japanese IMEs, the robustest way to retrieve the caret
+ * is scanning the attribute of the latest composition string and
+ * retrieving the begining and the end of the target clause, i.e.
+ * a clause being converted.
+ */
+ if (lparam & GCS_COMPATTR) {
+ int attribute_size = ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, NULL, 0);
+ if (attribute_size > 0) {
+ char *attribute_data = new char[attribute_size];
+ if (attribute_data) {
+ ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, attribute_data, attribute_size);
+ for (target_start = 0; target_start < attribute_size; ++target_start) {
+ if (IsTargetAttribute(attribute_data[target_start]))
+ break;
+ }
+ for (target_end = target_start; target_end < attribute_size; ++target_end) {
+ if (!IsTargetAttribute(attribute_data[target_end]))
+ break;
+ }
+ if (target_start == attribute_size) {
+ /**
+ * This composition clause does not contain any target clauses,
+ * i.e. this clauses is an input clause.
+ * We treat whole this clause as a target clause.
+ */
+ target_end = target_start;
+ target_start = 0;
+ }
+ if (target_start != -1 && target_start < attribute_size &&
+ attribute_data[target_start] == ATTR_TARGET_NOTCONVERTED) {
+ composition->cursor_position = target_start;
+ }
+ }
+ delete[] attribute_data;
+ }
+ }
+ break;
+ }
+ composition->target_start = target_start;
+ composition->target_end = target_end;
}
-
-bool GHOST_ImeWin32::GetString(HIMC imm_context, WPARAM lparam, int type, ImeComposition *composition)
+bool GHOST_ImeWin32::GetString(HIMC imm_context,
+ WPARAM lparam,
+ int type,
+ ImeComposition *composition)
{
- bool result = false;
- if (lparam & type) {
- int string_size = ::ImmGetCompositionStringW(imm_context, type, NULL, 0);
- if (string_size > 0) {
- int string_length = string_size / sizeof(wchar_t);
- wchar_t *string_data = new wchar_t[string_length + 1];
- string_data[string_length] = '\0';
- if (string_data) {
- /* Fill the given ImeComposition object. */
- ::ImmGetCompositionStringW(imm_context, type,
- string_data, string_size);
- composition->string_type = type;
- composition->ime_string = string_data;
- result = true;
- }
- delete[] string_data;
- }
- }
- return result;
+ bool result = false;
+ if (lparam & type) {
+ int string_size = ::ImmGetCompositionStringW(imm_context, type, NULL, 0);
+ if (string_size > 0) {
+ int string_length = string_size / sizeof(wchar_t);
+ wchar_t *string_data = new wchar_t[string_length + 1];
+ string_data[string_length] = '\0';
+ if (string_data) {
+ /* Fill the given ImeComposition object. */
+ ::ImmGetCompositionStringW(imm_context, type, string_data, string_size);
+ composition->string_type = type;
+ composition->ime_string = string_data;
+ result = true;
+ }
+ delete[] string_data;
+ }
+ }
+ return result;
}
-
bool GHOST_ImeWin32::GetResult(HWND window_handle, LPARAM lparam, ImeComposition *composition)
{
- bool result = false;
- HIMC imm_context = ::ImmGetContext(window_handle);
- if (imm_context) {
- /* Copy the result string to the ImeComposition object. */
- result = GetString(imm_context, lparam, GCS_RESULTSTR, composition);
- /**
- * Reset all the other parameters because a result string does not
- * have composition attributes.
- */
- composition->cursor_position = -1;
- composition->target_start = -1;
- composition->target_end = -1;
- ::ImmReleaseContext(window_handle, imm_context);
- }
- return result;
+ bool result = false;
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ /* Copy the result string to the ImeComposition object. */
+ result = GetString(imm_context, lparam, GCS_RESULTSTR, composition);
+ /**
+ * Reset all the other parameters because a result string does not
+ * have composition attributes.
+ */
+ composition->cursor_position = -1;
+ composition->target_start = -1;
+ composition->target_end = -1;
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ return result;
}
-
bool GHOST_ImeWin32::GetComposition(HWND window_handle, LPARAM lparam, ImeComposition *composition)
{
- bool result = false;
- HIMC imm_context = ::ImmGetContext(window_handle);
- if (imm_context) {
- /* Copy the composition string to the ImeComposition object. */
- result = GetString(imm_context, lparam, GCS_COMPSTR, composition);
-
- /* Retrieve the cursor position in the IME composition. */
- int cursor_position = ::ImmGetCompositionStringW(imm_context, GCS_CURSORPOS, NULL, 0);
- composition->cursor_position = cursor_position;
- composition->target_start = -1;
- composition->target_end = -1;
-
- /* Retrieve the target selection and Update the ImeComposition object. */
- GetCaret(imm_context, lparam, composition);
-
- /* Mark that there is an ongoing composition. */
- is_composing_ = true;
-
- ::ImmReleaseContext(window_handle, imm_context);
- }
- return result;
+ bool result = false;
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ /* Copy the composition string to the ImeComposition object. */
+ result = GetString(imm_context, lparam, GCS_COMPSTR, composition);
+
+ /* Retrieve the cursor position in the IME composition. */
+ int cursor_position = ::ImmGetCompositionStringW(imm_context, GCS_CURSORPOS, NULL, 0);
+ composition->cursor_position = cursor_position;
+ composition->target_start = -1;
+ composition->target_end = -1;
+
+ /* Retrieve the target selection and Update the ImeComposition object. */
+ GetCaret(imm_context, lparam, composition);
+
+ /* Mark that there is an ongoing composition. */
+ is_composing_ = true;
+
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ return result;
}
-
void GHOST_ImeWin32::EndIME(HWND window_handle)
{
- /**
- * A renderer process have moved its input focus to a password input
- * when there is an ongoing composition, e.g. a user has clicked a
- * mouse button and selected a password input while composing a text.
- * For this case, we have to complete the ongoing composition and
- * clean up the resources attached to this object BEFORE DISABLING THE IME.
- */
- if (!is_enable) return;
- is_enable = false;
- CleanupComposition(window_handle);
- ::ImmAssociateContextEx(window_handle, NULL, 0);
- eventImeData.composite_len = 0;
+ /**
+ * A renderer process have moved its input focus to a password input
+ * when there is an ongoing composition, e.g. a user has clicked a
+ * mouse button and selected a password input while composing a text.
+ * For this case, we have to complete the ongoing composition and
+ * clean up the resources attached to this object BEFORE DISABLING THE IME.
+ */
+ if (!is_enable)
+ return;
+ is_enable = false;
+ CleanupComposition(window_handle);
+ ::ImmAssociateContextEx(window_handle, NULL, 0);
+ eventImeData.composite_len = 0;
}
-
void GHOST_ImeWin32::BeginIME(HWND window_handle, const GHOST_Rect &caret_rect, bool complete)
{
- if (is_enable && complete) return;
- is_enable = true;
- /**
- * Load the default IME context.
- * NOTE(hbono)
- * IMM ignores this call if the IME context is loaded. Therefore, we do
- * not have to check whether or not the IME context is loaded.
- */
- ::ImmAssociateContextEx(window_handle, NULL, IACE_DEFAULT);
- /* Complete the ongoing composition and move the IME windows. */
- HIMC imm_context = ::ImmGetContext(window_handle);
- if (imm_context) {
- if (complete) {
- /**
- * A renderer process have moved its input focus to another edit
- * control when there is an ongoing composition, e.g. a user has
- * clicked a mouse button and selected another edit control while
- * composing a text.
- * For this case, we have to complete the ongoing composition and
- * hide the IME windows BEFORE MOVING THEM.
- */
- CompleteComposition(window_handle, imm_context);
- }
- /**
- * Save the caret position, and Update the position of the IME window.
- * This update is used for moving an IME window when a renderer process
- * resize/moves the input caret.
- */
- if (caret_rect.m_l >= 0 && caret_rect.m_t >= 0) {
- caret_rect_ = caret_rect;
- MoveImeWindow(window_handle, imm_context);
- }
- ::ImmReleaseContext(window_handle, imm_context);
- }
+ if (is_enable && complete)
+ return;
+ is_enable = true;
+ /**
+ * Load the default IME context.
+ * NOTE(hbono)
+ * IMM ignores this call if the IME context is loaded. Therefore, we do
+ * not have to check whether or not the IME context is loaded.
+ */
+ ::ImmAssociateContextEx(window_handle, NULL, IACE_DEFAULT);
+ /* Complete the ongoing composition and move the IME windows. */
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ if (complete) {
+ /**
+ * A renderer process have moved its input focus to another edit
+ * control when there is an ongoing composition, e.g. a user has
+ * clicked a mouse button and selected another edit control while
+ * composing a text.
+ * For this case, we have to complete the ongoing composition and
+ * hide the IME windows BEFORE MOVING THEM.
+ */
+ CompleteComposition(window_handle, imm_context);
+ }
+ /**
+ * Save the caret position, and Update the position of the IME window.
+ * This update is used for moving an IME window when a renderer process
+ * resize/moves the input caret.
+ */
+ if (caret_rect.m_l >= 0 && caret_rect.m_t >= 0) {
+ caret_rect_ = caret_rect;
+ MoveImeWindow(window_handle, imm_context);
+ }
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
}
-
static void convert_utf16_to_utf8_len(std::wstring s, int &len)
{
- if (len >= 0 && len <= s.size())
- len = count_utf_8_from_16(s.substr(0, len).c_str()) - 1;
- else
- len = -1;
+ if (len >= 0 && len <= s.size())
+ len = count_utf_8_from_16(s.substr(0, len).c_str()) - 1;
+ else
+ len = -1;
}
-
static size_t updateUtf8Buf(ImeComposition &info)
{
- size_t len = count_utf_8_from_16(info.ime_string.c_str());
- info.utf8_buf.resize(len);
- conv_utf_16_to_8(info.ime_string.c_str(), &info.utf8_buf[0], len);
- convert_utf16_to_utf8_len(info.ime_string, info.cursor_position);
- convert_utf16_to_utf8_len(info.ime_string, info.target_start);
- convert_utf16_to_utf8_len(info.ime_string, info.target_end);
- return len - 1;
+ size_t len = count_utf_8_from_16(info.ime_string.c_str());
+ info.utf8_buf.resize(len);
+ conv_utf_16_to_8(info.ime_string.c_str(), &info.utf8_buf[0], len);
+ convert_utf16_to_utf8_len(info.ime_string, info.cursor_position);
+ convert_utf16_to_utf8_len(info.ime_string, info.target_start);
+ convert_utf16_to_utf8_len(info.ime_string, info.target_end);
+ return len - 1;
}
-
void GHOST_ImeWin32::UpdateInfo(HWND window_handle)
{
- int res = this->GetResult(window_handle, GCS_RESULTSTR, &resultInfo);
- int comp = this->GetComposition(window_handle, GCS_COMPSTR | GCS_COMPATTR, &compInfo);
- /* convert wchar to utf8 */
- if (res) {
- eventImeData.result_len = (GHOST_TUserDataPtr)updateUtf8Buf(resultInfo);
- eventImeData.result = &resultInfo.utf8_buf[0];
- }
- else {
- eventImeData.result = 0;
- eventImeData.result_len = 0;
- }
- if (comp) {
- eventImeData.composite_len = (GHOST_TUserDataPtr)updateUtf8Buf(compInfo);
- eventImeData.composite = &compInfo.utf8_buf[0];
- eventImeData.cursor_position = compInfo.cursor_position;
- eventImeData.target_start = compInfo.target_start;
- eventImeData.target_end = compInfo.target_end;
- }
- else {
- eventImeData.composite = 0;
- eventImeData.composite_len = 0;
- eventImeData.cursor_position = -1;
- eventImeData.target_start = -1;
- eventImeData.target_end = -1;
- }
+ int res = this->GetResult(window_handle, GCS_RESULTSTR, &resultInfo);
+ int comp = this->GetComposition(window_handle, GCS_COMPSTR | GCS_COMPATTR, &compInfo);
+ /* convert wchar to utf8 */
+ if (res) {
+ eventImeData.result_len = (GHOST_TUserDataPtr)updateUtf8Buf(resultInfo);
+ eventImeData.result = &resultInfo.utf8_buf[0];
+ }
+ else {
+ eventImeData.result = 0;
+ eventImeData.result_len = 0;
+ }
+ if (comp) {
+ eventImeData.composite_len = (GHOST_TUserDataPtr)updateUtf8Buf(compInfo);
+ eventImeData.composite = &compInfo.utf8_buf[0];
+ eventImeData.cursor_position = compInfo.cursor_position;
+ eventImeData.target_start = compInfo.target_start;
+ eventImeData.target_end = compInfo.target_end;
+ }
+ else {
+ eventImeData.composite = 0;
+ eventImeData.composite_len = 0;
+ eventImeData.cursor_position = -1;
+ eventImeData.target_start = -1;
+ eventImeData.target_end = -1;
+ }
}
-#endif // WITH_INPUT_IME
+#endif // WITH_INPUT_IME
diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h
index 10f6d1cef55..61fc93a78af 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.h
+++ b/intern/ghost/intern/GHOST_ImeWin32.h
@@ -28,35 +28,30 @@
#ifdef WITH_INPUT_IME
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#include <string>
-
-#include "GHOST_Event.h"
-#include "GHOST_Rect.h"
-#include <vector>
-
-class GHOST_EventIME : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * \param msec The time this event was generated.
- * \param type The type of key event.
- * \param key The key code of the key.
- */
- GHOST_EventIME(GHOST_TUns64 msec,
- GHOST_TEventType type,
- GHOST_IWindow *window, void *customdata)
- : GHOST_Event(msec, type, window)
- {
- this->m_data = customdata;
- }
-
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+# include <string>
+
+# include "GHOST_Event.h"
+# include "GHOST_Rect.h"
+# include <vector>
+
+class GHOST_EventIME : public GHOST_Event {
+ public:
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param type The type of key event.
+ * \param key The key code of the key.
+ */
+ GHOST_EventIME(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata)
+ : GHOST_Event(msec, type, window)
+ {
+ this->m_data = customdata;
+ }
};
-
/**
* This header file defines a struct and a class used for encapsulating IMM32
* APIs, controls IMEs attached to a window, and enables the 'on-the-spot'
@@ -100,29 +95,29 @@ public:
/* This struct represents the status of an ongoing composition. */
struct ImeComposition {
- /* Represents the cursor position in the IME composition. */
- int cursor_position;
-
- /* Represents the position of the beginning of the selection */
- int target_start;
-
- /* Represents the position of the end of the selection */
- int target_end;
-
- /**
- * Represents the type of the string in the 'ime_string' parameter.
- * Its possible values and description are listed below:
- * Value Description
- * 0 The parameter is not used.
- * GCS_RESULTSTR The parameter represents a result string.
- * GCS_COMPSTR The parameter represents a composition string.
- */
- int string_type;
-
- /* Represents the string retrieved from IME (Input Method Editor) */
- std::wstring ime_string;
- std::vector<char> utf8_buf;
- std::vector<unsigned char> format;
+ /* Represents the cursor position in the IME composition. */
+ int cursor_position;
+
+ /* Represents the position of the beginning of the selection */
+ int target_start;
+
+ /* Represents the position of the end of the selection */
+ int target_end;
+
+ /**
+ * Represents the type of the string in the 'ime_string' parameter.
+ * Its possible values and description are listed below:
+ * Value Description
+ * 0 The parameter is not used.
+ * GCS_RESULTSTR The parameter represents a result string.
+ * GCS_COMPSTR The parameter represents a composition string.
+ */
+ int string_type;
+
+ /* Represents the string retrieved from IME (Input Method Editor) */
+ std::wstring ime_string;
+ std::vector<char> utf8_buf;
+ std::vector<unsigned char> format;
};
/**
@@ -142,258 +137,255 @@ struct ImeComposition {
* LANGUAGES BUT ALSO USED ON THE INPUT CONTEXTS OF ALL LANGUAGES.
*/
class GHOST_ImeWin32 {
-public:
- GHOST_ImeWin32();
- ~GHOST_ImeWin32();
-
- /* Retrieves whether or not there is an ongoing composition. */
- bool is_composing() const {return is_composing_;}
-
- /**
- * Retrieves the input language from Windows and update it.
- * Return values
- * * true
- * The given input language has IMEs.
- * * false
- * The given input language does not have IMEs.
- */
- bool SetInputLanguage();
-
- /**
- * Create the IME windows, and allocate required resources for them.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- */
- void CreateImeWindow(HWND window_handle);
-
- /**
- * Update the style of the IME windows.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- * * message [in] (UINT)
- * * wparam [in] (WPARAM)
- * * lparam [in] (LPARAM)
- * Represent the windows message of the caller.
- * These parameters are used for verifying if this function is called
- * in a handler function for WM_IME_SETCONTEXT messages because this
- * function uses ::DefWindowProc() to update the style.
- * A caller just has to pass the input parameters for the handler
- * function without modifications.
- * * handled [out] (BOOL*)
- * Returns ::DefWindowProc() is really called in this function.
- * PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE!
- * All the window styles set in this function are over-written when
- * calling ::DefWindowProc() after returning this function.
- */
- void SetImeWindowStyle(HWND window_handle, UINT message,
- WPARAM wparam, LPARAM lparam, BOOL* handled);
-
- /**
- * Destroy the IME windows and all the resources attached to them.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- */
- void DestroyImeWindow(HWND window_handle);
-
- /**
- * Update the position of the IME windows.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- */
- void UpdateImeWindow(HWND window_handle);
-
- /**
- * Clean up the all resources attached to the given GHOST_ImeWin32 object, and
- * reset its composition status.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- */
- void CleanupComposition(HWND window_handle);
-
- /**
- * Reset the composition status.
- * Cancel the ongoing composition if it exists.
- * NOTE(hbono): This method does not release the allocated resources.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- */
- void ResetComposition(HWND window_handle);
-
- /**
- * Retrieve a composition result of the ongoing composition if it exists.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- * * lparam [in] (LPARAM)
- * Specifies the updated members of the ongoing composition, and must be
- * the same parameter of a WM_IME_COMPOSITION message handler.
- * This parameter is used for checking if the ongoing composition has
- * its result string,
- * * composition [out] (ImeComposition)
- * Represents the struct contains the composition result.
- * Return values
- * * true
- * The ongoing composition has a composition result.
- * * false
- * The ongoing composition does not have composition results.
- * Remarks
- * This function is designed for being called from WM_IME_COMPOSITION
- * message handlers.
- */
- bool GetResult(HWND window_handle, LPARAM lparam,
- ImeComposition* composition);
-
- /**
- * Retrieve the current composition status of the ongoing composition.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- * * lparam [in] (LPARAM)
- * Specifies the updated members of the ongoing composition, and must be
- * the same parameter of a WM_IME_COMPOSITION message handler.
- * This parameter is used for checking if the ongoing composition has
- * its result string,
- * * composition [out] (ImeComposition)
- * Represents the struct contains the composition status.
- * Return values
- * * true
- * The status of the ongoing composition is updated.
- * * false
- * The status of the ongoing composition is not updated.
- * Remarks
- * This function is designed for being called from WM_IME_COMPOSITION
- * message handlers.
- */
- bool GetComposition(HWND window_handle, LPARAM lparam,
- ImeComposition* composition);
-
- /**
- * Enable the IME attached to the given window, i.e. allows user-input
- * events to be dispatched to the IME.
- * In Chrome, this function is used when:
- * * a renderer process moves its input focus to another edit control, or;
- * * a renrerer process moves the position of the focused edit control.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- * * caret_rect [in] (const gfx::Rect&)
- * Represent the rectangle of the input caret.
- * This rectangle is used for controlling the positions of IME windows.
- * * complete [in] (bool)
- * Represents whether or not to complete the ongoing composition.
- * + true
- * After finishing the ongoing composition and close its IME windows,
- * start another composition and display its IME windows to the given
- * position.
- * + false
- * Just move the IME windows of the ongoing composition to the given
- * position without finishing it.
- */
- void BeginIME(HWND window_handle,
- const GHOST_Rect& caret_rect,
- bool complete);
-
- /**
- * Disable the IME attached to the given window, i.e. prohibits any user-input
- * events from being dispatched to the IME.
- * In Chrome, this function is used when:
- * * a renreder process sets its input focus to a password input.
- * Parameters
- * * window_handle [in] (HWND)
- * Represents the window handle of the caller.
- */
- void EndIME(HWND window_handle);
-
- /* Updatg resultInfo and compInfo */
- void UpdateInfo(HWND window_handle);
-
- /* disable ime when start up */
- void CheckFirst(HWND window_handle);
-
- ImeComposition resultInfo, compInfo;
- GHOST_TEventImeData eventImeData;
-
-protected:
- /* Determines whether or not the given attribute represents a target (a.k.a. a selection). */
- bool IsTargetAttribute(char attribute) const {
- return (attribute == ATTR_TARGET_CONVERTED ||
- attribute == ATTR_TARGET_NOTCONVERTED);
- }
-
- /* Retrieve the target area. */
- void GetCaret(HIMC imm_context, LPARAM lparam,
- ImeComposition* composition);
-
- /* Update the position of the IME windows. */
- void MoveImeWindow(HWND window_handle, HIMC imm_context);
-
- /* Complete the ongoing composition if it exists. */
- void CompleteComposition(HWND window_handle, HIMC imm_context);
-
- /* Retrieve a string from the IMM. */
- bool GetString(HIMC imm_context, WPARAM lparam, int type,
- ImeComposition* composition);
-
-private:
- /**
- * Represents whether or not there is an ongoing composition in a browser
- * process, i.e. whether or not a browser process is composing a text.
- */
- bool is_composing_;
-
- /**
- * This value represents whether or not the current input context has IMEs.
- * The following table shows the list of IME status:
- * Value Description
- * false The current input language does not have IMEs.
- * true The current input language has IMEs.
- */
- bool ime_status_;
-
- /**
- * The current input Language ID retrieved from Windows, which consists of:
- * * Primary Language ID (bit 0 to bit 9), which shows a natunal language
- * (English, Korean, Chinese, Japanese, etc.) and;
- * * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region
- * the language is spoken (For English, United States, United Kingdom,
- * Australia, Canada, etc.)
- * The following list enumerates some examples for the Language ID:
- * * "en-US" (0x0409)
- * MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
- * * "ko-KR" (0x0412)
- * MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
- * * "zh-TW" (0x0404)
- * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
- * * "zh-CN" (0x0804)
- * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
- * * "ja-JP" (0x0411)
- * MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc.
- * (See <winnt.h> for other available values.)
- * This Language ID is used for processing language-specific operations in
- * IME functions.
- */
- LANGID input_language_id_;
-
- /**
- * Represents whether or not the current input context has created a system
- * caret to set the position of its IME candidate window.
- * * true: it creates a system caret.
- * * false: it does not create a system caret.
- */
- bool system_caret_;
-
- /* The rectangle of the input caret retrieved from a renderer process. */
- GHOST_Rect caret_rect_;
-
- /* used for disable ime when start up */
- bool is_first, is_enable;
+ public:
+ GHOST_ImeWin32();
+ ~GHOST_ImeWin32();
+
+ /* Retrieves whether or not there is an ongoing composition. */
+ bool is_composing() const
+ {
+ return is_composing_;
+ }
+
+ /**
+ * Retrieves the input language from Windows and update it.
+ * Return values
+ * * true
+ * The given input language has IMEs.
+ * * false
+ * The given input language does not have IMEs.
+ */
+ bool SetInputLanguage();
+
+ /**
+ * Create the IME windows, and allocate required resources for them.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void CreateImeWindow(HWND window_handle);
+
+ /**
+ * Update the style of the IME windows.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * message [in] (UINT)
+ * * wparam [in] (WPARAM)
+ * * lparam [in] (LPARAM)
+ * Represent the windows message of the caller.
+ * These parameters are used for verifying if this function is called
+ * in a handler function for WM_IME_SETCONTEXT messages because this
+ * function uses ::DefWindowProc() to update the style.
+ * A caller just has to pass the input parameters for the handler
+ * function without modifications.
+ * * handled [out] (BOOL*)
+ * Returns ::DefWindowProc() is really called in this function.
+ * PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE!
+ * All the window styles set in this function are over-written when
+ * calling ::DefWindowProc() after returning this function.
+ */
+ void SetImeWindowStyle(
+ HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam, BOOL *handled);
+
+ /**
+ * Destroy the IME windows and all the resources attached to them.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void DestroyImeWindow(HWND window_handle);
+
+ /**
+ * Update the position of the IME windows.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void UpdateImeWindow(HWND window_handle);
+
+ /**
+ * Clean up the all resources attached to the given GHOST_ImeWin32 object, and
+ * reset its composition status.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void CleanupComposition(HWND window_handle);
+
+ /**
+ * Reset the composition status.
+ * Cancel the ongoing composition if it exists.
+ * NOTE(hbono): This method does not release the allocated resources.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void ResetComposition(HWND window_handle);
+
+ /**
+ * Retrieve a composition result of the ongoing composition if it exists.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * lparam [in] (LPARAM)
+ * Specifies the updated members of the ongoing composition, and must be
+ * the same parameter of a WM_IME_COMPOSITION message handler.
+ * This parameter is used for checking if the ongoing composition has
+ * its result string,
+ * * composition [out] (ImeComposition)
+ * Represents the struct contains the composition result.
+ * Return values
+ * * true
+ * The ongoing composition has a composition result.
+ * * false
+ * The ongoing composition does not have composition results.
+ * Remarks
+ * This function is designed for being called from WM_IME_COMPOSITION
+ * message handlers.
+ */
+ bool GetResult(HWND window_handle, LPARAM lparam, ImeComposition *composition);
+
+ /**
+ * Retrieve the current composition status of the ongoing composition.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * lparam [in] (LPARAM)
+ * Specifies the updated members of the ongoing composition, and must be
+ * the same parameter of a WM_IME_COMPOSITION message handler.
+ * This parameter is used for checking if the ongoing composition has
+ * its result string,
+ * * composition [out] (ImeComposition)
+ * Represents the struct contains the composition status.
+ * Return values
+ * * true
+ * The status of the ongoing composition is updated.
+ * * false
+ * The status of the ongoing composition is not updated.
+ * Remarks
+ * This function is designed for being called from WM_IME_COMPOSITION
+ * message handlers.
+ */
+ bool GetComposition(HWND window_handle, LPARAM lparam, ImeComposition *composition);
+
+ /**
+ * Enable the IME attached to the given window, i.e. allows user-input
+ * events to be dispatched to the IME.
+ * In Chrome, this function is used when:
+ * * a renderer process moves its input focus to another edit control, or;
+ * * a renrerer process moves the position of the focused edit control.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * caret_rect [in] (const gfx::Rect&)
+ * Represent the rectangle of the input caret.
+ * This rectangle is used for controlling the positions of IME windows.
+ * * complete [in] (bool)
+ * Represents whether or not to complete the ongoing composition.
+ * + true
+ * After finishing the ongoing composition and close its IME windows,
+ * start another composition and display its IME windows to the given
+ * position.
+ * + false
+ * Just move the IME windows of the ongoing composition to the given
+ * position without finishing it.
+ */
+ void BeginIME(HWND window_handle, const GHOST_Rect &caret_rect, bool complete);
+
+ /**
+ * Disable the IME attached to the given window, i.e. prohibits any user-input
+ * events from being dispatched to the IME.
+ * In Chrome, this function is used when:
+ * * a renreder process sets its input focus to a password input.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void EndIME(HWND window_handle);
+
+ /* Updatg resultInfo and compInfo */
+ void UpdateInfo(HWND window_handle);
+
+ /* disable ime when start up */
+ void CheckFirst(HWND window_handle);
+
+ ImeComposition resultInfo, compInfo;
+ GHOST_TEventImeData eventImeData;
+
+ protected:
+ /* Determines whether or not the given attribute represents a target (a.k.a. a selection). */
+ bool IsTargetAttribute(char attribute) const
+ {
+ return (attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED);
+ }
+
+ /* Retrieve the target area. */
+ void GetCaret(HIMC imm_context, LPARAM lparam, ImeComposition *composition);
+
+ /* Update the position of the IME windows. */
+ void MoveImeWindow(HWND window_handle, HIMC imm_context);
+
+ /* Complete the ongoing composition if it exists. */
+ void CompleteComposition(HWND window_handle, HIMC imm_context);
+
+ /* Retrieve a string from the IMM. */
+ bool GetString(HIMC imm_context, WPARAM lparam, int type, ImeComposition *composition);
+
+ private:
+ /**
+ * Represents whether or not there is an ongoing composition in a browser
+ * process, i.e. whether or not a browser process is composing a text.
+ */
+ bool is_composing_;
+
+ /**
+ * This value represents whether or not the current input context has IMEs.
+ * The following table shows the list of IME status:
+ * Value Description
+ * false The current input language does not have IMEs.
+ * true The current input language has IMEs.
+ */
+ bool ime_status_;
+
+ /**
+ * The current input Language ID retrieved from Windows, which consists of:
+ * * Primary Language ID (bit 0 to bit 9), which shows a natunal language
+ * (English, Korean, Chinese, Japanese, etc.) and;
+ * * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region
+ * the language is spoken (For English, United States, United Kingdom,
+ * Australia, Canada, etc.)
+ * The following list enumerates some examples for the Language ID:
+ * * "en-US" (0x0409)
+ * MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
+ * * "ko-KR" (0x0412)
+ * MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
+ * * "zh-TW" (0x0404)
+ * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
+ * * "zh-CN" (0x0804)
+ * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
+ * * "ja-JP" (0x0411)
+ * MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc.
+ * (See <winnt.h> for other available values.)
+ * This Language ID is used for processing language-specific operations in
+ * IME functions.
+ */
+ LANGID input_language_id_;
+
+ /**
+ * Represents whether or not the current input context has created a system
+ * caret to set the position of its IME candidate window.
+ * * true: it creates a system caret.
+ * * false: it does not create a system caret.
+ */
+ bool system_caret_;
+
+ /* The rectangle of the input caret retrieved from a renderer process. */
+ GHOST_Rect caret_rect_;
+
+ /* used for disable ime when start up */
+ bool is_first, is_enable;
};
-#endif // WITH_INPUT_IME
-#endif // __GHOST_IME_H__
+#endif // WITH_INPUT_IME
+#endif // __GHOST_IME_H__
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.cpp b/intern/ghost/intern/GHOST_ModifierKeys.cpp
index 6dfdb5f5a3d..6b74eab17b8 100644
--- a/intern/ghost/intern/GHOST_ModifierKeys.cpp
+++ b/intern/ghost/intern/GHOST_ModifierKeys.cpp
@@ -21,107 +21,120 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
#include "GHOST_ModifierKeys.h"
-
GHOST_ModifierKeys::GHOST_ModifierKeys()
{
- clear();
+ clear();
}
-GHOST_ModifierKeys::~GHOST_ModifierKeys() {}
-
+GHOST_ModifierKeys::~GHOST_ModifierKeys()
+{
+}
GHOST_TKey GHOST_ModifierKeys::getModifierKeyCode(GHOST_TModifierKeyMask mask)
{
- GHOST_TKey key;
- switch (mask) {
- case GHOST_kModifierKeyLeftShift: key = GHOST_kKeyLeftShift; break;
- case GHOST_kModifierKeyRightShift: key = GHOST_kKeyRightShift; break;
- case GHOST_kModifierKeyLeftAlt: key = GHOST_kKeyLeftAlt; break;
- case GHOST_kModifierKeyRightAlt: key = GHOST_kKeyRightAlt; break;
- case GHOST_kModifierKeyLeftControl: key = GHOST_kKeyLeftControl; break;
- case GHOST_kModifierKeyRightControl: key = GHOST_kKeyRightControl; break;
- case GHOST_kModifierKeyOS: key = GHOST_kKeyOS; break;
- default:
- // Should not happen
- key = GHOST_kKeyUnknown;
- break;
- }
- return key;
+ GHOST_TKey key;
+ switch (mask) {
+ case GHOST_kModifierKeyLeftShift:
+ key = GHOST_kKeyLeftShift;
+ break;
+ case GHOST_kModifierKeyRightShift:
+ key = GHOST_kKeyRightShift;
+ break;
+ case GHOST_kModifierKeyLeftAlt:
+ key = GHOST_kKeyLeftAlt;
+ break;
+ case GHOST_kModifierKeyRightAlt:
+ key = GHOST_kKeyRightAlt;
+ break;
+ case GHOST_kModifierKeyLeftControl:
+ key = GHOST_kKeyLeftControl;
+ break;
+ case GHOST_kModifierKeyRightControl:
+ key = GHOST_kKeyRightControl;
+ break;
+ case GHOST_kModifierKeyOS:
+ key = GHOST_kKeyOS;
+ break;
+ default:
+ // Should not happen
+ key = GHOST_kKeyUnknown;
+ break;
+ }
+ return key;
}
-
bool GHOST_ModifierKeys::get(GHOST_TModifierKeyMask mask) const
{
- switch (mask) {
- case GHOST_kModifierKeyLeftShift:
- return m_LeftShift;
- case GHOST_kModifierKeyRightShift:
- return m_RightShift;
- case GHOST_kModifierKeyLeftAlt:
- return m_LeftAlt;
- case GHOST_kModifierKeyRightAlt:
- return m_RightAlt;
- case GHOST_kModifierKeyLeftControl:
- return m_LeftControl;
- case GHOST_kModifierKeyRightControl:
- return m_RightControl;
- case GHOST_kModifierKeyOS:
- return m_OS;
- default:
- return false;
- }
+ switch (mask) {
+ case GHOST_kModifierKeyLeftShift:
+ return m_LeftShift;
+ case GHOST_kModifierKeyRightShift:
+ return m_RightShift;
+ case GHOST_kModifierKeyLeftAlt:
+ return m_LeftAlt;
+ case GHOST_kModifierKeyRightAlt:
+ return m_RightAlt;
+ case GHOST_kModifierKeyLeftControl:
+ return m_LeftControl;
+ case GHOST_kModifierKeyRightControl:
+ return m_RightControl;
+ case GHOST_kModifierKeyOS:
+ return m_OS;
+ default:
+ return false;
+ }
}
-
void GHOST_ModifierKeys::set(GHOST_TModifierKeyMask mask, bool down)
{
- switch (mask) {
- case GHOST_kModifierKeyLeftShift:
- m_LeftShift = down; break;
- case GHOST_kModifierKeyRightShift:
- m_RightShift = down; break;
- case GHOST_kModifierKeyLeftAlt:
- m_LeftAlt = down; break;
- case GHOST_kModifierKeyRightAlt:
- m_RightAlt = down; break;
- case GHOST_kModifierKeyLeftControl:
- m_LeftControl = down; break;
- case GHOST_kModifierKeyRightControl:
- m_RightControl = down; break;
- case GHOST_kModifierKeyOS:
- m_OS = down; break;
- default:
- break;
- }
+ switch (mask) {
+ case GHOST_kModifierKeyLeftShift:
+ m_LeftShift = down;
+ break;
+ case GHOST_kModifierKeyRightShift:
+ m_RightShift = down;
+ break;
+ case GHOST_kModifierKeyLeftAlt:
+ m_LeftAlt = down;
+ break;
+ case GHOST_kModifierKeyRightAlt:
+ m_RightAlt = down;
+ break;
+ case GHOST_kModifierKeyLeftControl:
+ m_LeftControl = down;
+ break;
+ case GHOST_kModifierKeyRightControl:
+ m_RightControl = down;
+ break;
+ case GHOST_kModifierKeyOS:
+ m_OS = down;
+ break;
+ default:
+ break;
+ }
}
-
void GHOST_ModifierKeys::clear()
{
- m_LeftShift = false;
- m_RightShift = false;
- m_LeftAlt = false;
- m_RightAlt = false;
- m_LeftControl = false;
- m_RightControl = false;
- m_OS = false;
+ m_LeftShift = false;
+ m_RightShift = false;
+ m_LeftAlt = false;
+ m_RightAlt = false;
+ m_LeftControl = false;
+ m_RightControl = false;
+ m_OS = false;
}
-
-bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys& keys) const
+bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
{
- return (m_LeftShift == keys.m_LeftShift) &&
- (m_RightShift == keys.m_RightShift) &&
- (m_LeftAlt == keys.m_LeftAlt) &&
- (m_RightAlt == keys.m_RightAlt) &&
- (m_LeftControl == keys.m_LeftControl) &&
- (m_RightControl == keys.m_RightControl) &&
- (m_OS == keys.m_OS);
+ return (m_LeftShift == keys.m_LeftShift) && (m_RightShift == keys.m_RightShift) &&
+ (m_LeftAlt == keys.m_LeftAlt) && (m_RightAlt == keys.m_RightAlt) &&
+ (m_LeftControl == keys.m_LeftControl) && (m_RightControl == keys.m_RightControl) &&
+ (m_OS == keys.m_OS);
}
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h
index 092f38f4d5a..27ad4034068 100644
--- a/intern/ghost/intern/GHOST_ModifierKeys.h
+++ b/intern/ghost/intern/GHOST_ModifierKeys.h
@@ -32,61 +32,60 @@
* Discriminates between left and right modifier keys.
*/
struct GHOST_ModifierKeys {
- /**
- * Constructor.
- */
- GHOST_ModifierKeys();
+ /**
+ * Constructor.
+ */
+ GHOST_ModifierKeys();
- ~GHOST_ModifierKeys();
+ ~GHOST_ModifierKeys();
- /**
- * Returns the modifier key's key code from a modifier key mask.
- * \param mask The mask of the modifier key.
- * \return The modifier key's key code.
- */
- static GHOST_TKey getModifierKeyCode(GHOST_TModifierKeyMask mask);
+ /**
+ * Returns the modifier key's key code from a modifier key mask.
+ * \param mask The mask of the modifier key.
+ * \return The modifier key's key code.
+ */
+ static GHOST_TKey getModifierKeyCode(GHOST_TModifierKeyMask mask);
+ /**
+ * Returns the state of a single modifier key.
+ * \param mask: Key state to return.
+ * \return The state of the key (pressed == true).
+ */
+ bool get(GHOST_TModifierKeyMask mask) const;
- /**
- * Returns the state of a single modifier key.
- * \param mask: Key state to return.
- * \return The state of the key (pressed == true).
- */
- bool get(GHOST_TModifierKeyMask mask) const;
+ /**
+ * Updates the state of a single modifier key.
+ * \param mask: Key state to update.
+ * \param down: The new state of the key.
+ */
+ void set(GHOST_TModifierKeyMask mask, bool down);
- /**
- * Updates the state of a single modifier key.
- * \param mask: Key state to update.
- * \param down: The new state of the key.
- */
- void set(GHOST_TModifierKeyMask mask, bool down);
+ /**
+ * Sets the state of all modifier keys to up.
+ */
+ void clear();
- /**
- * Sets the state of all modifier keys to up.
- */
- void clear();
+ /**
+ * Determines whether to modifier key states are equal.
+ * \param keys: The modifier key state to compare to.
+ * \return Indication of equality.
+ */
+ bool equals(const GHOST_ModifierKeys &keys) const;
- /**
- * Determines whether to modifier key states are equal.
- * \param keys: The modifier key state to compare to.
- * \return Indication of equality.
- */
- bool equals(const GHOST_ModifierKeys& keys) const;
-
- /** Bitfield that stores the appropriate key state. */
- GHOST_TUns8 m_LeftShift : 1;
- /** Bitfield that stores the appropriate key state. */
- GHOST_TUns8 m_RightShift : 1;
- /** Bitfield that stores the appropriate key state. */
- GHOST_TUns8 m_LeftAlt : 1;
- /** Bitfield that stores the appropriate key state. */
- GHOST_TUns8 m_RightAlt : 1;
- /** Bitfield that stores the appropriate key state. */
- GHOST_TUns8 m_LeftControl : 1;
- /** Bitfield that stores the appropriate key state. */
- GHOST_TUns8 m_RightControl : 1;
- /** Bitfield that stores the appropriate key state. */
- GHOST_TUns8 m_OS : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_LeftShift : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_RightShift : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_LeftAlt : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_RightAlt : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_LeftControl : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_RightControl : 1;
+ /** Bitfield that stores the appropriate key state. */
+ GHOST_TUns8 m_OS : 1;
};
-#endif // __GHOST_MODIFIERKEYS_H__
+#endif // __GHOST_MODIFIERKEYS_H__
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index d8a81bb5839..b407d120a99 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -19,513 +19,492 @@
#include "GHOST_EventNDOF.h"
#include "GHOST_EventKey.h"
#include "GHOST_WindowManager.h"
-#include <string.h> // for memory functions
-#include <stdio.h> // for error/info reporting
+#include <string.h> // for memory functions
+#include <stdio.h> // for error/info reporting
#include <math.h>
#ifdef DEBUG_NDOF_MOTION
// printable version of each GHOST_TProgress value
-static const char *progress_string[] =
-{"not started", "starting", "in progress", "finishing", "finished"};
+static const char *progress_string[] = {
+ "not started", "starting", "in progress", "finishing", "finished"};
#endif
#ifdef DEBUG_NDOF_BUTTONS
static const char *ndof_button_names[] = {
- // used internally, never sent
- "NDOF_BUTTON_NONE",
- // these two are available from any 3Dconnexion device
- "NDOF_BUTTON_MENU",
- "NDOF_BUTTON_FIT",
- // standard views
- "NDOF_BUTTON_TOP",
- "NDOF_BUTTON_BOTTOM",
- "NDOF_BUTTON_LEFT",
- "NDOF_BUTTON_RIGHT",
- "NDOF_BUTTON_FRONT",
- "NDOF_BUTTON_BACK",
- // more views
- "NDOF_BUTTON_ISO1",
- "NDOF_BUTTON_ISO2",
- // 90 degree rotations
- "NDOF_BUTTON_ROLL_CW",
- "NDOF_BUTTON_ROLL_CCW",
- "NDOF_BUTTON_SPIN_CW",
- "NDOF_BUTTON_SPIN_CCW",
- "NDOF_BUTTON_TILT_CW",
- "NDOF_BUTTON_TILT_CCW",
- // device control
- "NDOF_BUTTON_ROTATE",
- "NDOF_BUTTON_PANZOOM",
- "NDOF_BUTTON_DOMINANT",
- "NDOF_BUTTON_PLUS",
- "NDOF_BUTTON_MINUS",
- // keyboard emulation
- "NDOF_BUTTON_ESC",
- "NDOF_BUTTON_ALT",
- "NDOF_BUTTON_SHIFT",
- "NDOF_BUTTON_CTRL",
- // general-purpose buttons
- "NDOF_BUTTON_1",
- "NDOF_BUTTON_2",
- "NDOF_BUTTON_3",
- "NDOF_BUTTON_4",
- "NDOF_BUTTON_5",
- "NDOF_BUTTON_6",
- "NDOF_BUTTON_7",
- "NDOF_BUTTON_8",
- "NDOF_BUTTON_9",
- "NDOF_BUTTON_10",
- // more general-purpose buttons
- "NDOF_BUTTON_A",
- "NDOF_BUTTON_B",
- "NDOF_BUTTON_C",
- // the end
- "NDOF_BUTTON_LAST"
-};
+ // used internally, never sent
+ "NDOF_BUTTON_NONE",
+ // these two are available from any 3Dconnexion device
+ "NDOF_BUTTON_MENU",
+ "NDOF_BUTTON_FIT",
+ // standard views
+ "NDOF_BUTTON_TOP",
+ "NDOF_BUTTON_BOTTOM",
+ "NDOF_BUTTON_LEFT",
+ "NDOF_BUTTON_RIGHT",
+ "NDOF_BUTTON_FRONT",
+ "NDOF_BUTTON_BACK",
+ // more views
+ "NDOF_BUTTON_ISO1",
+ "NDOF_BUTTON_ISO2",
+ // 90 degree rotations
+ "NDOF_BUTTON_ROLL_CW",
+ "NDOF_BUTTON_ROLL_CCW",
+ "NDOF_BUTTON_SPIN_CW",
+ "NDOF_BUTTON_SPIN_CCW",
+ "NDOF_BUTTON_TILT_CW",
+ "NDOF_BUTTON_TILT_CCW",
+ // device control
+ "NDOF_BUTTON_ROTATE",
+ "NDOF_BUTTON_PANZOOM",
+ "NDOF_BUTTON_DOMINANT",
+ "NDOF_BUTTON_PLUS",
+ "NDOF_BUTTON_MINUS",
+ // keyboard emulation
+ "NDOF_BUTTON_ESC",
+ "NDOF_BUTTON_ALT",
+ "NDOF_BUTTON_SHIFT",
+ "NDOF_BUTTON_CTRL",
+ // general-purpose buttons
+ "NDOF_BUTTON_1",
+ "NDOF_BUTTON_2",
+ "NDOF_BUTTON_3",
+ "NDOF_BUTTON_4",
+ "NDOF_BUTTON_5",
+ "NDOF_BUTTON_6",
+ "NDOF_BUTTON_7",
+ "NDOF_BUTTON_8",
+ "NDOF_BUTTON_9",
+ "NDOF_BUTTON_10",
+ // more general-purpose buttons
+ "NDOF_BUTTON_A",
+ "NDOF_BUTTON_B",
+ "NDOF_BUTTON_C",
+ // the end
+ "NDOF_BUTTON_LAST"};
#endif
// shared by the latest 3Dconnexion hardware
// SpacePilotPro uses all of these
// smaller devices use only some, based on button mask
static const NDOF_ButtonT Modern3Dx_HID_map[] = {
- NDOF_BUTTON_MENU,
- NDOF_BUTTON_FIT,
- NDOF_BUTTON_TOP,
- NDOF_BUTTON_LEFT,
- NDOF_BUTTON_RIGHT,
- NDOF_BUTTON_FRONT,
- NDOF_BUTTON_BOTTOM,
- NDOF_BUTTON_BACK,
- NDOF_BUTTON_ROLL_CW,
- NDOF_BUTTON_ROLL_CCW,
- NDOF_BUTTON_ISO1,
- NDOF_BUTTON_ISO2,
- NDOF_BUTTON_1,
- NDOF_BUTTON_2,
- NDOF_BUTTON_3,
- NDOF_BUTTON_4,
- NDOF_BUTTON_5,
- NDOF_BUTTON_6,
- NDOF_BUTTON_7,
- NDOF_BUTTON_8,
- NDOF_BUTTON_9,
- NDOF_BUTTON_10,
- NDOF_BUTTON_ESC,
- NDOF_BUTTON_ALT,
- NDOF_BUTTON_SHIFT,
- NDOF_BUTTON_CTRL,
- NDOF_BUTTON_ROTATE,
- NDOF_BUTTON_PANZOOM,
- NDOF_BUTTON_DOMINANT,
- NDOF_BUTTON_PLUS,
- NDOF_BUTTON_MINUS
-};
-
-static const NDOF_ButtonT SpaceExplorer_HID_map[] = {
- NDOF_BUTTON_1,
- NDOF_BUTTON_2,
- NDOF_BUTTON_TOP,
- NDOF_BUTTON_LEFT,
- NDOF_BUTTON_RIGHT,
- NDOF_BUTTON_FRONT,
- NDOF_BUTTON_ESC,
- NDOF_BUTTON_ALT,
- NDOF_BUTTON_SHIFT,
- NDOF_BUTTON_CTRL,
- NDOF_BUTTON_FIT,
- NDOF_BUTTON_MENU,
- NDOF_BUTTON_PLUS,
- NDOF_BUTTON_MINUS,
- NDOF_BUTTON_ROTATE
-};
+ NDOF_BUTTON_MENU, NDOF_BUTTON_FIT, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_BOTTOM, NDOF_BUTTON_BACK,
+ NDOF_BUTTON_ROLL_CW, NDOF_BUTTON_ROLL_CCW, NDOF_BUTTON_ISO1, NDOF_BUTTON_ISO2,
+ NDOF_BUTTON_1, NDOF_BUTTON_2, NDOF_BUTTON_3, NDOF_BUTTON_4,
+ NDOF_BUTTON_5, NDOF_BUTTON_6, NDOF_BUTTON_7, NDOF_BUTTON_8,
+ NDOF_BUTTON_9, NDOF_BUTTON_10, NDOF_BUTTON_ESC, NDOF_BUTTON_ALT,
+ NDOF_BUTTON_SHIFT, NDOF_BUTTON_CTRL, NDOF_BUTTON_ROTATE, NDOF_BUTTON_PANZOOM,
+ NDOF_BUTTON_DOMINANT, NDOF_BUTTON_PLUS, NDOF_BUTTON_MINUS};
+
+static const NDOF_ButtonT SpaceExplorer_HID_map[] = {NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_TOP,
+ NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT,
+ NDOF_BUTTON_FRONT,
+ NDOF_BUTTON_ESC,
+ NDOF_BUTTON_ALT,
+ NDOF_BUTTON_SHIFT,
+ NDOF_BUTTON_CTRL,
+ NDOF_BUTTON_FIT,
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_PLUS,
+ NDOF_BUTTON_MINUS,
+ NDOF_BUTTON_ROTATE};
// this is the older SpacePilot (sans Pro)
// thanks to polosson for info about this device
static const NDOF_ButtonT SpacePilot_HID_map[] = {
- NDOF_BUTTON_1,
- NDOF_BUTTON_2,
- NDOF_BUTTON_3,
- NDOF_BUTTON_4,
- NDOF_BUTTON_5,
- NDOF_BUTTON_6,
- NDOF_BUTTON_TOP,
- NDOF_BUTTON_LEFT,
- NDOF_BUTTON_RIGHT,
- NDOF_BUTTON_FRONT,
- NDOF_BUTTON_ESC,
- NDOF_BUTTON_ALT,
- NDOF_BUTTON_SHIFT,
- NDOF_BUTTON_CTRL,
- NDOF_BUTTON_FIT,
- NDOF_BUTTON_MENU,
- NDOF_BUTTON_PLUS,
- NDOF_BUTTON_MINUS,
- NDOF_BUTTON_DOMINANT,
- NDOF_BUTTON_ROTATE,
- NDOF_BUTTON_NONE // the CONFIG button -- what does it do?
+ NDOF_BUTTON_1, NDOF_BUTTON_2, NDOF_BUTTON_3, NDOF_BUTTON_4,
+ NDOF_BUTTON_5, NDOF_BUTTON_6, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_ESC, NDOF_BUTTON_ALT,
+ NDOF_BUTTON_SHIFT, NDOF_BUTTON_CTRL, NDOF_BUTTON_FIT, NDOF_BUTTON_MENU,
+ NDOF_BUTTON_PLUS, NDOF_BUTTON_MINUS, NDOF_BUTTON_DOMINANT, NDOF_BUTTON_ROTATE,
+ NDOF_BUTTON_NONE // the CONFIG button -- what does it do?
};
-static const NDOF_ButtonT Generic_HID_map[] = {
- NDOF_BUTTON_1,
- NDOF_BUTTON_2,
- NDOF_BUTTON_3,
- NDOF_BUTTON_4,
- NDOF_BUTTON_5,
- NDOF_BUTTON_6,
- NDOF_BUTTON_7,
- NDOF_BUTTON_8,
- NDOF_BUTTON_9,
- NDOF_BUTTON_A,
- NDOF_BUTTON_B,
- NDOF_BUTTON_C
-};
+static const NDOF_ButtonT Generic_HID_map[] = {NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_3,
+ NDOF_BUTTON_4,
+ NDOF_BUTTON_5,
+ NDOF_BUTTON_6,
+ NDOF_BUTTON_7,
+ NDOF_BUTTON_8,
+ NDOF_BUTTON_9,
+ NDOF_BUTTON_A,
+ NDOF_BUTTON_B,
+ NDOF_BUTTON_C};
static const int genericButtonCount = sizeof(Generic_HID_map) / sizeof(NDOF_ButtonT);
GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System &sys)
- : m_system(sys),
- m_deviceType(NDOF_UnknownDevice), // each platform has its own device detection code
- m_buttonCount(genericButtonCount),
- m_buttonMask(0),
- m_hidMap(Generic_HID_map),
- m_buttons(0),
- m_motionTime(0),
- m_prevMotionTime(0),
- m_motionState(GHOST_kNotStarted),
- m_motionEventPending(false),
- m_deadZone(0.0f)
+ : m_system(sys),
+ m_deviceType(NDOF_UnknownDevice), // each platform has its own device detection code
+ m_buttonCount(genericButtonCount),
+ m_buttonMask(0),
+ m_hidMap(Generic_HID_map),
+ m_buttons(0),
+ m_motionTime(0),
+ m_prevMotionTime(0),
+ m_motionState(GHOST_kNotStarted),
+ m_motionEventPending(false),
+ m_deadZone(0.0f)
{
- // to avoid the rare situation where one triple is updated and
- // the other is not, initialize them both here:
- memset(m_translation, 0, sizeof(m_translation));
- memset(m_rotation, 0, sizeof(m_rotation));
+ // to avoid the rare situation where one triple is updated and
+ // the other is not, initialize them both here:
+ memset(m_translation, 0, sizeof(m_translation));
+ memset(m_rotation, 0, sizeof(m_rotation));
}
bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short product_id)
{
- // call this function until it returns true
- // it's a good idea to stop calling it after that, as it will "forget"
- // whichever device it already found
-
- // default to safe generic behavior for "unknown" devices
- // unidentified devices will emit motion events like normal
- // rogue buttons do nothing by default, but can be customized by the user
-
- m_deviceType = NDOF_UnknownDevice;
- m_hidMap = Generic_HID_map;
- m_buttonCount = genericButtonCount;
- m_buttonMask = 0;
-
- // "mystery device" owners can help build a HID_map for their hardware
- // A few users have already contributed information about several older devices
- // that I don't have access to. Thanks!
-
- switch (vendor_id) {
- case 0x046D: // Logitech (3Dconnexion was a subsidiary)
- switch (product_id) {
- // -- current devices --
- case 0xC626: // full-size SpaceNavigator
- case 0xC628: // the "for Notebooks" one
- puts("ndof: using SpaceNavigator");
- m_deviceType = NDOF_SpaceNavigator;
- m_buttonCount = 2;
- m_hidMap = Modern3Dx_HID_map;
- break;
- case 0xC627:
- puts("ndof: using SpaceExplorer");
- m_deviceType = NDOF_SpaceExplorer;
- m_buttonCount = 15;
- m_hidMap = SpaceExplorer_HID_map;
- break;
- case 0xC629:
- puts("ndof: using SpacePilot Pro");
- m_deviceType = NDOF_SpacePilotPro;
- m_buttonCount = 31;
- m_hidMap = Modern3Dx_HID_map;
- break;
- case 0xC62B:
- puts("ndof: using SpaceMouse Pro");
- m_deviceType = NDOF_SpaceMousePro;
- m_buttonCount = 27;
- // ^^ actually has 15 buttons, but their HID codes range from 0 to 26
- m_buttonMask = 0x07C0F137;
- m_hidMap = Modern3Dx_HID_map;
- break;
-
- // -- older devices --
- case 0xC625:
- puts("ndof: using SpacePilot");
- m_deviceType = NDOF_SpacePilot;
- m_buttonCount = 21;
- m_hidMap = SpacePilot_HID_map;
- break;
- case 0xC621:
- puts("ndof: using Spaceball 5000");
- m_deviceType = NDOF_Spaceball5000;
- m_buttonCount = 12;
- break;
- case 0xC623:
- puts("ndof: using SpaceTraveler");
- m_deviceType = NDOF_SpaceTraveler;
- m_buttonCount = 8;
- break;
-
- default:
- printf("ndof: unknown Logitech product %04hx\n", product_id);
- }
- break;
- case 0x256F: // 3Dconnexion
- switch (product_id) {
- case 0xC62E: // plugged in
- case 0xC62F: // wireless
- puts("ndof: using SpaceMouse Wireless");
- m_deviceType = NDOF_SpaceMouseWireless;
- m_buttonCount = 2;
- m_hidMap = Modern3Dx_HID_map;
- break;
- case 0xC631: // plugged in
- case 0xC632: // wireless
- puts("ndof: using SpaceMouse Pro Wireless");
- m_deviceType = NDOF_SpaceMouseProWireless;
- m_buttonCount = 27;
- // ^^ actually has 15 buttons, but their HID codes range from 0 to 26
- m_buttonMask = 0x07C0F137;
- m_hidMap = Modern3Dx_HID_map;
- break;
- case 0xC633:
- puts("ndof: using SpaceMouse Enterprise");
- m_deviceType = NDOF_SpaceMouseEnterprise;
- m_buttonCount = 31;
- m_hidMap = Modern3Dx_HID_map;
- break;
-
- default:
- printf("ndof: unknown 3Dconnexion product %04hx\n", product_id);
- }
- break;
- default:
- printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id);
- }
-
- if (m_buttonMask == 0)
- m_buttonMask = (int) ~(UINT_MAX << m_buttonCount);
+ // call this function until it returns true
+ // it's a good idea to stop calling it after that, as it will "forget"
+ // whichever device it already found
+
+ // default to safe generic behavior for "unknown" devices
+ // unidentified devices will emit motion events like normal
+ // rogue buttons do nothing by default, but can be customized by the user
+
+ m_deviceType = NDOF_UnknownDevice;
+ m_hidMap = Generic_HID_map;
+ m_buttonCount = genericButtonCount;
+ m_buttonMask = 0;
+
+ // "mystery device" owners can help build a HID_map for their hardware
+ // A few users have already contributed information about several older devices
+ // that I don't have access to. Thanks!
+
+ switch (vendor_id) {
+ case 0x046D: // Logitech (3Dconnexion was a subsidiary)
+ switch (product_id) {
+ // -- current devices --
+ case 0xC626: // full-size SpaceNavigator
+ case 0xC628: // the "for Notebooks" one
+ puts("ndof: using SpaceNavigator");
+ m_deviceType = NDOF_SpaceNavigator;
+ m_buttonCount = 2;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+ case 0xC627:
+ puts("ndof: using SpaceExplorer");
+ m_deviceType = NDOF_SpaceExplorer;
+ m_buttonCount = 15;
+ m_hidMap = SpaceExplorer_HID_map;
+ break;
+ case 0xC629:
+ puts("ndof: using SpacePilot Pro");
+ m_deviceType = NDOF_SpacePilotPro;
+ m_buttonCount = 31;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+ case 0xC62B:
+ puts("ndof: using SpaceMouse Pro");
+ m_deviceType = NDOF_SpaceMousePro;
+ m_buttonCount = 27;
+ // ^^ actually has 15 buttons, but their HID codes range from 0 to 26
+ m_buttonMask = 0x07C0F137;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+
+ // -- older devices --
+ case 0xC625:
+ puts("ndof: using SpacePilot");
+ m_deviceType = NDOF_SpacePilot;
+ m_buttonCount = 21;
+ m_hidMap = SpacePilot_HID_map;
+ break;
+ case 0xC621:
+ puts("ndof: using Spaceball 5000");
+ m_deviceType = NDOF_Spaceball5000;
+ m_buttonCount = 12;
+ break;
+ case 0xC623:
+ puts("ndof: using SpaceTraveler");
+ m_deviceType = NDOF_SpaceTraveler;
+ m_buttonCount = 8;
+ break;
+
+ default:
+ printf("ndof: unknown Logitech product %04hx\n", product_id);
+ }
+ break;
+ case 0x256F: // 3Dconnexion
+ switch (product_id) {
+ case 0xC62E: // plugged in
+ case 0xC62F: // wireless
+ puts("ndof: using SpaceMouse Wireless");
+ m_deviceType = NDOF_SpaceMouseWireless;
+ m_buttonCount = 2;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+ case 0xC631: // plugged in
+ case 0xC632: // wireless
+ puts("ndof: using SpaceMouse Pro Wireless");
+ m_deviceType = NDOF_SpaceMouseProWireless;
+ m_buttonCount = 27;
+ // ^^ actually has 15 buttons, but their HID codes range from 0 to 26
+ m_buttonMask = 0x07C0F137;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+ case 0xC633:
+ puts("ndof: using SpaceMouse Enterprise");
+ m_deviceType = NDOF_SpaceMouseEnterprise;
+ m_buttonCount = 31;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+
+ default:
+ printf("ndof: unknown 3Dconnexion product %04hx\n", product_id);
+ }
+ break;
+ default:
+ printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id);
+ }
+
+ if (m_buttonMask == 0)
+ m_buttonMask = (int)~(UINT_MAX << m_buttonCount);
#ifdef DEBUG_NDOF_BUTTONS
- printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask);
+ printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask);
#endif
- return m_deviceType != NDOF_UnknownDevice;
+ return m_deviceType != NDOF_UnknownDevice;
}
void GHOST_NDOFManager::updateTranslation(const int t[3], GHOST_TUns64 time)
{
- memcpy(m_translation, t, sizeof(m_translation));
- m_motionTime = time;
- m_motionEventPending = true;
+ memcpy(m_translation, t, sizeof(m_translation));
+ m_motionTime = time;
+ m_motionEventPending = true;
}
void GHOST_NDOFManager::updateRotation(const int r[3], GHOST_TUns64 time)
{
- memcpy(m_rotation, r, sizeof(m_rotation));
- m_motionTime = time;
- m_motionEventPending = true;
+ memcpy(m_rotation, r, sizeof(m_rotation));
+ m_motionTime = time;
+ m_motionEventPending = true;
}
-void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, GHOST_TUns64 time, GHOST_IWindow *window)
+void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button,
+ bool press,
+ GHOST_TUns64 time,
+ GHOST_IWindow *window)
{
- GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST,
- "rogue button trying to escape NDOF manager");
+ GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST,
+ "rogue button trying to escape NDOF manager");
- GHOST_EventNDOFButton *event = new GHOST_EventNDOFButton(time, window);
- GHOST_TEventNDOFButtonData *data = (GHOST_TEventNDOFButtonData *) event->getData();
+ GHOST_EventNDOFButton *event = new GHOST_EventNDOFButton(time, window);
+ GHOST_TEventNDOFButtonData *data = (GHOST_TEventNDOFButtonData *)event->getData();
- data->action = press ? GHOST_kPress : GHOST_kRelease;
- data->button = button;
+ data->action = press ? GHOST_kPress : GHOST_kRelease;
+ data->button = button;
#ifdef DEBUG_NDOF_BUTTONS
- printf("%s %s\n", ndof_button_names[button], press ? "pressed" : "released");
+ printf("%s %s\n", ndof_button_names[button], press ? "pressed" : "released");
#endif
- m_system.pushEvent(event);
+ m_system.pushEvent(event);
}
-void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key, bool press, GHOST_TUns64 time, GHOST_IWindow *window)
+void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key,
+ bool press,
+ GHOST_TUns64 time,
+ GHOST_IWindow *window)
{
- GHOST_TEventType type = press ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
- GHOST_EventKey *event = new GHOST_EventKey(time, type, window, key);
+ GHOST_TEventType type = press ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
+ GHOST_EventKey *event = new GHOST_EventKey(time, type, window, key);
#ifdef DEBUG_NDOF_BUTTONS
- printf("keyboard %s\n", press ? "down" : "up");
+ printf("keyboard %s\n", press ? "down" : "up");
#endif
- m_system.pushEvent(event);
+ m_system.pushEvent(event);
}
void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64 time)
{
- GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow();
+ GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow();
#ifdef DEBUG_NDOF_BUTTONS
- printf("ndof: button %d -> ", button_number);
+ printf("ndof: button %d -> ", button_number);
#endif
- NDOF_ButtonT button = (button_number < m_buttonCount) ? m_hidMap[button_number] : NDOF_BUTTON_NONE;
+ NDOF_ButtonT button = (button_number < m_buttonCount) ? m_hidMap[button_number] :
+ NDOF_BUTTON_NONE;
- switch (button) {
- case NDOF_BUTTON_NONE:
+ switch (button) {
+ case NDOF_BUTTON_NONE:
#ifdef DEBUG_NDOF_BUTTONS
- printf("discarded\n");
+ printf("discarded\n");
#endif
- break;
- case NDOF_BUTTON_ESC: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break;
- case NDOF_BUTTON_ALT: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break;
- case NDOF_BUTTON_SHIFT: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break;
- case NDOF_BUTTON_CTRL: sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); break;
- default: sendButtonEvent(button, press, time, window);
- }
-
- int mask = 1 << button_number;
- if (press) {
- m_buttons |= mask; // set this button's bit
- }
- else {
- m_buttons &= ~mask; // clear this button's bit
- }
+ break;
+ case NDOF_BUTTON_ESC:
+ sendKeyEvent(GHOST_kKeyEsc, press, time, window);
+ break;
+ case NDOF_BUTTON_ALT:
+ sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window);
+ break;
+ case NDOF_BUTTON_SHIFT:
+ sendKeyEvent(GHOST_kKeyLeftShift, press, time, window);
+ break;
+ case NDOF_BUTTON_CTRL:
+ sendKeyEvent(GHOST_kKeyLeftControl, press, time, window);
+ break;
+ default:
+ sendButtonEvent(button, press, time, window);
+ }
+
+ int mask = 1 << button_number;
+ if (press) {
+ m_buttons |= mask; // set this button's bit
+ }
+ else {
+ m_buttons &= ~mask; // clear this button's bit
+ }
}
void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time)
{
- button_bits &= m_buttonMask; // discard any "garbage" bits
+ button_bits &= m_buttonMask; // discard any "garbage" bits
- int diff = m_buttons ^ button_bits;
+ int diff = m_buttons ^ button_bits;
- for (int button_number = 0; button_number < m_buttonCount; ++button_number) {
- int mask = 1 << button_number;
+ for (int button_number = 0; button_number < m_buttonCount; ++button_number) {
+ int mask = 1 << button_number;
- if (diff & mask) {
- bool press = button_bits & mask;
- updateButton(button_number, press, time);
- }
- }
+ if (diff & mask) {
+ bool press = button_bits & mask;
+ updateButton(button_number, press, time);
+ }
+ }
}
void GHOST_NDOFManager::setDeadZone(float dz)
{
- if (dz < 0.0f) {
- // negative values don't make sense, so clamp at zero
- dz = 0.0f;
- }
- else if (dz > 0.5f) {
- // warn the rogue user/developer, but allow it
- GHOST_PRINTF("ndof: dead zone of %.2f is rather high...\n", dz);
- }
- m_deadZone = dz;
-
- GHOST_PRINTF("ndof: dead zone set to %.2f\n", dz);
+ if (dz < 0.0f) {
+ // negative values don't make sense, so clamp at zero
+ dz = 0.0f;
+ }
+ else if (dz > 0.5f) {
+ // warn the rogue user/developer, but allow it
+ GHOST_PRINTF("ndof: dead zone of %.2f is rather high...\n", dz);
+ }
+ m_deadZone = dz;
+
+ GHOST_PRINTF("ndof: dead zone set to %.2f\n", dz);
}
static bool atHomePosition(GHOST_TEventNDOFMotionData *ndof)
{
#define HOME(foo) (ndof->foo == 0.0f)
- return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
+ return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
#undef HOME
}
static bool nearHomePosition(GHOST_TEventNDOFMotionData *ndof, float threshold)
{
- if (threshold == 0.0f) {
- return atHomePosition(ndof);
- }
- else {
+ if (threshold == 0.0f) {
+ return atHomePosition(ndof);
+ }
+ else {
#define HOME(foo) (fabsf(ndof->foo) < threshold)
- return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
+ return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
#undef HOME
- }
+ }
}
bool GHOST_NDOFManager::sendMotionEvent()
{
- if (!m_motionEventPending)
- return false;
+ if (!m_motionEventPending)
+ return false;
- m_motionEventPending = false; // any pending motion is handled right now
+ m_motionEventPending = false; // any pending motion is handled right now
- GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow();
+ GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow();
- if (window == NULL) {
- m_motionState = GHOST_kNotStarted; // avoid large 'dt' times when changing windows
- return false; // delivery will fail, so don't bother sending
- }
+ if (window == NULL) {
+ m_motionState = GHOST_kNotStarted; // avoid large 'dt' times when changing windows
+ return false; // delivery will fail, so don't bother sending
+ }
- GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(m_motionTime, window);
- GHOST_TEventNDOFMotionData *data = (GHOST_TEventNDOFMotionData *) event->getData();
+ GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(m_motionTime, window);
+ GHOST_TEventNDOFMotionData *data = (GHOST_TEventNDOFMotionData *)event->getData();
- // scale axis values here to normalize them to around +/- 1
- // they are scaled again for overall sensitivity in the WM based on user prefs
+ // scale axis values here to normalize them to around +/- 1
+ // they are scaled again for overall sensitivity in the WM based on user prefs
- const float scale = 1.0f / 350.0f; // 3Dconnexion devices send +/- 350 usually
+ const float scale = 1.0f / 350.0f; // 3Dconnexion devices send +/- 350 usually
- data->tx = scale * m_translation[0];
- data->ty = scale * m_translation[1];
- data->tz = scale * m_translation[2];
+ data->tx = scale * m_translation[0];
+ data->ty = scale * m_translation[1];
+ data->tz = scale * m_translation[2];
- data->rx = scale * m_rotation[0];
- data->ry = scale * m_rotation[1];
- data->rz = scale * m_rotation[2];
+ data->rx = scale * m_rotation[0];
+ data->ry = scale * m_rotation[1];
+ data->rz = scale * m_rotation[2];
- data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
- m_prevMotionTime = m_motionTime;
+ data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
+ m_prevMotionTime = m_motionTime;
- bool weHaveMotion = !nearHomePosition(data, m_deadZone);
+ bool weHaveMotion = !nearHomePosition(data, m_deadZone);
- // determine what kind of motion event to send (Starting, InProgress, Finishing)
- // and where that leaves this NDOF manager (NotStarted, InProgress, Finished)
- switch (m_motionState) {
- case GHOST_kNotStarted:
- case GHOST_kFinished:
- if (weHaveMotion) {
- data->progress = GHOST_kStarting;
- m_motionState = GHOST_kInProgress;
- // prev motion time will be ancient, so just make up a reasonable time delta
- data->dt = 0.0125f;
- }
- else {
- // send no event and keep current state
+ // determine what kind of motion event to send (Starting, InProgress, Finishing)
+ // and where that leaves this NDOF manager (NotStarted, InProgress, Finished)
+ switch (m_motionState) {
+ case GHOST_kNotStarted:
+ case GHOST_kFinished:
+ if (weHaveMotion) {
+ data->progress = GHOST_kStarting;
+ m_motionState = GHOST_kInProgress;
+ // prev motion time will be ancient, so just make up a reasonable time delta
+ data->dt = 0.0125f;
+ }
+ else {
+ // send no event and keep current state
#ifdef DEBUG_NDOF_MOTION
- printf("ndof motion ignored -- %s\n", progress_string[data->progress]);
+ printf("ndof motion ignored -- %s\n", progress_string[data->progress]);
#endif
- delete event;
- return false;
- }
- break;
- case GHOST_kInProgress:
- if (weHaveMotion) {
- data->progress = GHOST_kInProgress;
- // remain 'InProgress'
- }
- else {
- data->progress = GHOST_kFinishing;
- m_motionState = GHOST_kFinished;
- }
- break;
- default:
- ; // will always be one of the above
- }
+ delete event;
+ return false;
+ }
+ break;
+ case GHOST_kInProgress:
+ if (weHaveMotion) {
+ data->progress = GHOST_kInProgress;
+ // remain 'InProgress'
+ }
+ else {
+ data->progress = GHOST_kFinishing;
+ m_motionState = GHOST_kFinished;
+ }
+ break;
+ default:; // will always be one of the above
+ }
#ifdef DEBUG_NDOF_MOTION
- printf("ndof motion sent -- %s\n", progress_string[data->progress]);
-
- // show details about this motion event
- printf(" T=(%d,%d,%d) R=(%d,%d,%d) raw\n",
- m_translation[0], m_translation[1], m_translation[2],
- m_rotation[0], m_rotation[1], m_rotation[2]);
- printf(" T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
- data->tx, data->ty, data->tz,
- data->rx, data->ry, data->rz,
- data->dt);
+ printf("ndof motion sent -- %s\n", progress_string[data->progress]);
+
+ // show details about this motion event
+ printf(" T=(%d,%d,%d) R=(%d,%d,%d) raw\n",
+ m_translation[0],
+ m_translation[1],
+ m_translation[2],
+ m_rotation[0],
+ m_rotation[1],
+ m_rotation[2]);
+ printf(" T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
+ data->tx,
+ data->ty,
+ data->tz,
+ data->rx,
+ data->ry,
+ data->rz,
+ data->dt);
#endif
- m_system.pushEvent(event);
+ m_system.pushEvent(event);
- return true;
+ return true;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index 5f1069f11a0..a190607ca66 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -27,144 +27,145 @@
// #define DEBUG_NDOF_BUTTONS
typedef enum {
- NDOF_UnknownDevice,
-
- // current devices
- NDOF_SpaceNavigator,
- NDOF_SpaceExplorer,
- NDOF_SpacePilotPro,
- NDOF_SpaceMousePro,
- NDOF_SpaceMouseWireless,
- NDOF_SpaceMouseProWireless,
- NDOF_SpaceMouseEnterprise,
-
- // older devices
- NDOF_SpacePilot,
- NDOF_Spaceball5000,
- NDOF_SpaceTraveler
+ NDOF_UnknownDevice,
+
+ // current devices
+ NDOF_SpaceNavigator,
+ NDOF_SpaceExplorer,
+ NDOF_SpacePilotPro,
+ NDOF_SpaceMousePro,
+ NDOF_SpaceMouseWireless,
+ NDOF_SpaceMouseProWireless,
+ NDOF_SpaceMouseEnterprise,
+
+ // older devices
+ NDOF_SpacePilot,
+ NDOF_Spaceball5000,
+ NDOF_SpaceTraveler
} NDOF_DeviceT;
// NDOF device button event types
typedef enum {
- // used internally, never sent
- NDOF_BUTTON_NONE,
- // these two are available from any 3Dconnexion device
- NDOF_BUTTON_MENU,
- NDOF_BUTTON_FIT,
- // standard views
- NDOF_BUTTON_TOP,
- NDOF_BUTTON_BOTTOM,
- NDOF_BUTTON_LEFT,
- NDOF_BUTTON_RIGHT,
- NDOF_BUTTON_FRONT,
- NDOF_BUTTON_BACK,
- // more views
- NDOF_BUTTON_ISO1,
- NDOF_BUTTON_ISO2,
- // 90 degree rotations
- // these don't all correspond to physical buttons
- NDOF_BUTTON_ROLL_CW,
- NDOF_BUTTON_ROLL_CCW,
- NDOF_BUTTON_SPIN_CW,
- NDOF_BUTTON_SPIN_CCW,
- NDOF_BUTTON_TILT_CW,
- NDOF_BUTTON_TILT_CCW,
- // device control
- NDOF_BUTTON_ROTATE,
- NDOF_BUTTON_PANZOOM,
- NDOF_BUTTON_DOMINANT,
- NDOF_BUTTON_PLUS,
- NDOF_BUTTON_MINUS,
- // keyboard emulation
- NDOF_BUTTON_ESC,
- NDOF_BUTTON_ALT,
- NDOF_BUTTON_SHIFT,
- NDOF_BUTTON_CTRL,
- // general-purpose buttons
- // users can assign functions via keymap editor
- NDOF_BUTTON_1,
- NDOF_BUTTON_2,
- NDOF_BUTTON_3,
- NDOF_BUTTON_4,
- NDOF_BUTTON_5,
- NDOF_BUTTON_6,
- NDOF_BUTTON_7,
- NDOF_BUTTON_8,
- NDOF_BUTTON_9,
- NDOF_BUTTON_10,
- // more general-purpose buttons
- NDOF_BUTTON_A,
- NDOF_BUTTON_B,
- NDOF_BUTTON_C,
- // the end
- NDOF_BUTTON_LAST
+ // used internally, never sent
+ NDOF_BUTTON_NONE,
+ // these two are available from any 3Dconnexion device
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_FIT,
+ // standard views
+ NDOF_BUTTON_TOP,
+ NDOF_BUTTON_BOTTOM,
+ NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT,
+ NDOF_BUTTON_FRONT,
+ NDOF_BUTTON_BACK,
+ // more views
+ NDOF_BUTTON_ISO1,
+ NDOF_BUTTON_ISO2,
+ // 90 degree rotations
+ // these don't all correspond to physical buttons
+ NDOF_BUTTON_ROLL_CW,
+ NDOF_BUTTON_ROLL_CCW,
+ NDOF_BUTTON_SPIN_CW,
+ NDOF_BUTTON_SPIN_CCW,
+ NDOF_BUTTON_TILT_CW,
+ NDOF_BUTTON_TILT_CCW,
+ // device control
+ NDOF_BUTTON_ROTATE,
+ NDOF_BUTTON_PANZOOM,
+ NDOF_BUTTON_DOMINANT,
+ NDOF_BUTTON_PLUS,
+ NDOF_BUTTON_MINUS,
+ // keyboard emulation
+ NDOF_BUTTON_ESC,
+ NDOF_BUTTON_ALT,
+ NDOF_BUTTON_SHIFT,
+ NDOF_BUTTON_CTRL,
+ // general-purpose buttons
+ // users can assign functions via keymap editor
+ NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_3,
+ NDOF_BUTTON_4,
+ NDOF_BUTTON_5,
+ NDOF_BUTTON_6,
+ NDOF_BUTTON_7,
+ NDOF_BUTTON_8,
+ NDOF_BUTTON_9,
+ NDOF_BUTTON_10,
+ // more general-purpose buttons
+ NDOF_BUTTON_A,
+ NDOF_BUTTON_B,
+ NDOF_BUTTON_C,
+ // the end
+ NDOF_BUTTON_LAST
} NDOF_ButtonT;
-class GHOST_NDOFManager
-{
-public:
- GHOST_NDOFManager(GHOST_System&);
- virtual ~GHOST_NDOFManager() {}
-
- // whether multi-axis functionality is available (via the OS or driver)
- // does not imply that a device is plugged in or being used
- virtual bool available() = 0;
-
- // each platform's device detection should call this
- // use standard USB/HID identifiers
- bool setDevice(unsigned short vendor_id, unsigned short product_id);
-
- // filter out small/accidental/uncalibrated motions by
- // setting up a "dead zone" around home position
- // set to 0 to disable
- // 0.1 is a safe and reasonable value
- void setDeadZone(float);
-
- // the latest raw axis data from the device
- // NOTE: axis data should be in blender view coordinates
- // +X is to the right
- // +Y is up
- // +Z is out of the screen
- // for rotations, look from origin to each +axis
- // rotations are + when CCW, - when CW
- // each platform is responsible for getting axis data into this form
- // these values should not be scaled (just shuffled or flipped)
- void updateTranslation(const int t[3], GHOST_TUns64 time);
- void updateRotation(const int r[3], GHOST_TUns64 time);
-
- // the latest raw button data from the device
- // use HID button encoding (not NDOF_ButtonT)
- void updateButton(int button_number, bool press, GHOST_TUns64 time);
- void updateButtons(int button_bits, GHOST_TUns64 time);
- // NDOFButton events are sent immediately
-
- // processes and sends most recent raw data as an NDOFMotion event
- // returns whether an event was sent
- bool sendMotionEvent();
-
-protected:
- GHOST_System& m_system;
-
-private:
- void sendButtonEvent(NDOF_ButtonT, bool press, GHOST_TUns64 time, GHOST_IWindow *);
- void sendKeyEvent(GHOST_TKey, bool press, GHOST_TUns64 time, GHOST_IWindow *);
-
- NDOF_DeviceT m_deviceType;
- int m_buttonCount;
- int m_buttonMask;
- const NDOF_ButtonT *m_hidMap;
-
- int m_translation[3];
- int m_rotation[3];
- int m_buttons; // bit field
-
- GHOST_TUns64 m_motionTime; // in milliseconds
- GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent
-
- GHOST_TProgress m_motionState;
- bool m_motionEventPending;
- float m_deadZone; // discard motion with each component < this
+class GHOST_NDOFManager {
+ public:
+ GHOST_NDOFManager(GHOST_System &);
+ virtual ~GHOST_NDOFManager()
+ {
+ }
+
+ // whether multi-axis functionality is available (via the OS or driver)
+ // does not imply that a device is plugged in or being used
+ virtual bool available() = 0;
+
+ // each platform's device detection should call this
+ // use standard USB/HID identifiers
+ bool setDevice(unsigned short vendor_id, unsigned short product_id);
+
+ // filter out small/accidental/uncalibrated motions by
+ // setting up a "dead zone" around home position
+ // set to 0 to disable
+ // 0.1 is a safe and reasonable value
+ void setDeadZone(float);
+
+ // the latest raw axis data from the device
+ // NOTE: axis data should be in blender view coordinates
+ // +X is to the right
+ // +Y is up
+ // +Z is out of the screen
+ // for rotations, look from origin to each +axis
+ // rotations are + when CCW, - when CW
+ // each platform is responsible for getting axis data into this form
+ // these values should not be scaled (just shuffled or flipped)
+ void updateTranslation(const int t[3], GHOST_TUns64 time);
+ void updateRotation(const int r[3], GHOST_TUns64 time);
+
+ // the latest raw button data from the device
+ // use HID button encoding (not NDOF_ButtonT)
+ void updateButton(int button_number, bool press, GHOST_TUns64 time);
+ void updateButtons(int button_bits, GHOST_TUns64 time);
+ // NDOFButton events are sent immediately
+
+ // processes and sends most recent raw data as an NDOFMotion event
+ // returns whether an event was sent
+ bool sendMotionEvent();
+
+ protected:
+ GHOST_System &m_system;
+
+ private:
+ void sendButtonEvent(NDOF_ButtonT, bool press, GHOST_TUns64 time, GHOST_IWindow *);
+ void sendKeyEvent(GHOST_TKey, bool press, GHOST_TUns64 time, GHOST_IWindow *);
+
+ NDOF_DeviceT m_deviceType;
+ int m_buttonCount;
+ int m_buttonMask;
+ const NDOF_ButtonT *m_hidMap;
+
+ int m_translation[3];
+ int m_rotation[3];
+ int m_buttons; // bit field
+
+ GHOST_TUns64 m_motionTime; // in milliseconds
+ GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent
+
+ GHOST_TProgress m_motionState;
+ bool m_motionEventPending;
+ float m_deadZone; // discard motion with each component < this
};
#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
index e3c8dd8d985..bd1e6903f94 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
@@ -22,13 +22,12 @@
// Event capture is handled within the NDOF manager on Macintosh,
// so there's no need for SystemCocoa to look for them.
-class GHOST_NDOFManagerCocoa : public GHOST_NDOFManager
-{
-public:
- GHOST_NDOFManagerCocoa(GHOST_System&);
- ~GHOST_NDOFManagerCocoa();
+class GHOST_NDOFManagerCocoa : public GHOST_NDOFManager {
+ public:
+ GHOST_NDOFManagerCocoa(GHOST_System &);
+ ~GHOST_NDOFManagerCocoa();
- bool available();
+ bool available();
};
-#endif // #include guard
+#endif // #include guard
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
index 65d8b965d09..4d07a399002 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
@@ -23,18 +23,20 @@
#include <dlfcn.h>
#if DEBUG_NDOF_DRIVER
- #include <cstdio>
+# include <cstdio>
#endif
// static callback functions need to talk to these objects:
-static GHOST_SystemCocoa* ghost_system = NULL;
-static GHOST_NDOFManager* ndof_manager = NULL;
+static GHOST_SystemCocoa *ghost_system = NULL;
+static GHOST_NDOFManager *ndof_manager = NULL;
static uint16_t clientID = 0;
static bool driver_loaded = false;
-static bool has_old_driver = false; // 3Dconnexion drivers before 10 beta 4 are "old", not all buttons will work
-static bool has_new_driver = false; // drivers >= 10.2.2 are "new", and can process events on a separate thread
+static bool has_old_driver =
+ false; // 3Dconnexion drivers before 10 beta 4 are "old", not all buttons will work
+static bool has_new_driver =
+ false; // drivers >= 10.2.2 are "new", and can process events on a separate thread
// replicate just enough of the 3Dx API for our uses, not everything the driver provides
@@ -47,35 +49,41 @@ static bool has_new_driver = false; // drivers >= 10.2.2 are "new", and can proc
#define kConnexionMsgDeviceState '3dSR'
#define kConnexionCtlGetDeviceID '3did'
-#pragma pack(push,2) // just this struct
+#pragma pack(push, 2) // just this struct
struct ConnexionDeviceState {
- uint16_t version;
- uint16_t client;
- uint16_t command;
- int16_t param;
- int32_t value;
- uint64_t time;
- uint8_t report[8];
- uint16_t buttons8; // obsolete! (pre-10.x drivers)
- int16_t axis[6]; // tx, ty, tz, rx, ry, rz
- uint16_t address;
- uint32_t buttons;
+ uint16_t version;
+ uint16_t client;
+ uint16_t command;
+ int16_t param;
+ int32_t value;
+ uint64_t time;
+ uint8_t report[8];
+ uint16_t buttons8; // obsolete! (pre-10.x drivers)
+ int16_t axis[6]; // tx, ty, tz, rx, ry, rz
+ uint16_t address;
+ uint32_t buttons;
};
#pragma pack(pop)
// callback functions:
typedef void (*AddedHandler)(uint32_t);
typedef void (*RemovedHandler)(uint32_t);
-typedef void (*MessageHandler)(uint32_t, uint32_t msg_type, void* msg_arg);
+typedef void (*MessageHandler)(uint32_t, uint32_t msg_type, void *msg_arg);
// driver functions:
typedef int16_t (*SetConnexionHandlers_ptr)(MessageHandler, AddedHandler, RemovedHandler, bool);
typedef int16_t (*InstallConnexionHandlers_ptr)(MessageHandler, AddedHandler, RemovedHandler);
typedef void (*CleanupConnexionHandlers_ptr)();
-typedef uint16_t (*RegisterConnexionClient_ptr)(uint32_t signature, const char* name, uint16_t mode, uint32_t mask);
+typedef uint16_t (*RegisterConnexionClient_ptr)(uint32_t signature,
+ const char *name,
+ uint16_t mode,
+ uint32_t mask);
typedef void (*SetConnexionClientButtonMask_ptr)(uint16_t clientID, uint32_t buttonMask);
typedef void (*UnregisterConnexionClient_ptr)(uint16_t clientID);
-typedef int16_t (*ConnexionClientControl_ptr)(uint16_t clientID, uint32_t message, int32_t param, int32_t* result);
+typedef int16_t (*ConnexionClientControl_ptr)(uint16_t clientID,
+ uint32_t message,
+ int32_t param,
+ int32_t *result);
#define DECLARE_FUNC(name) name##_ptr name = NULL
@@ -87,190 +95,187 @@ DECLARE_FUNC(SetConnexionClientButtonMask);
DECLARE_FUNC(UnregisterConnexionClient);
DECLARE_FUNC(ConnexionClientControl);
-
-static void* load_func(void* module, const char* func_name)
+static void *load_func(void *module, const char *func_name)
{
- void* func = dlsym(module, func_name);
+ void *func = dlsym(module, func_name);
#if DEBUG_NDOF_DRIVER
- if (func) {
- printf("'%s' loaded :D\n", func_name);
- }
- else {
- printf("<!> %s\n", dlerror());
- }
+ if (func) {
+ printf("'%s' loaded :D\n", func_name);
+ }
+ else {
+ printf("<!> %s\n", dlerror());
+ }
#endif
- return func;
+ return func;
}
-#define LOAD_FUNC(name) name = (name##_ptr) load_func(module, #name)
+#define LOAD_FUNC(name) name = (name##_ptr)load_func(module, #name)
-static void* module; // handle to the whole driver
+static void *module; // handle to the whole driver
static bool load_driver_functions()
{
- if (driver_loaded) {
- return true;
- }
-
- module = dlopen("3DconnexionClient.framework/3DconnexionClient", RTLD_LAZY | RTLD_LOCAL);
-
- if (module) {
- LOAD_FUNC(SetConnexionHandlers);
-
- if (SetConnexionHandlers != NULL) {
- driver_loaded = true;
- has_new_driver = true;
- }
- else {
- LOAD_FUNC(InstallConnexionHandlers);
-
- driver_loaded = (InstallConnexionHandlers != NULL);
- }
-
- if (driver_loaded) {
- LOAD_FUNC(CleanupConnexionHandlers);
- LOAD_FUNC(RegisterConnexionClient);
- LOAD_FUNC(SetConnexionClientButtonMask);
- LOAD_FUNC(UnregisterConnexionClient);
- LOAD_FUNC(ConnexionClientControl);
-
- has_old_driver = (SetConnexionClientButtonMask == NULL);
- }
- }
+ if (driver_loaded) {
+ return true;
+ }
+
+ module = dlopen("3DconnexionClient.framework/3DconnexionClient", RTLD_LAZY | RTLD_LOCAL);
+
+ if (module) {
+ LOAD_FUNC(SetConnexionHandlers);
+
+ if (SetConnexionHandlers != NULL) {
+ driver_loaded = true;
+ has_new_driver = true;
+ }
+ else {
+ LOAD_FUNC(InstallConnexionHandlers);
+
+ driver_loaded = (InstallConnexionHandlers != NULL);
+ }
+
+ if (driver_loaded) {
+ LOAD_FUNC(CleanupConnexionHandlers);
+ LOAD_FUNC(RegisterConnexionClient);
+ LOAD_FUNC(SetConnexionClientButtonMask);
+ LOAD_FUNC(UnregisterConnexionClient);
+ LOAD_FUNC(ConnexionClientControl);
+
+ has_old_driver = (SetConnexionClientButtonMask == NULL);
+ }
+ }
#if DEBUG_NDOF_DRIVER
- else {
- printf("<!> %s\n", dlerror());
- }
+ else {
+ printf("<!> %s\n", dlerror());
+ }
- printf("loaded: %s\n", driver_loaded ? "YES" : "NO");
- printf("old: %s\n", has_old_driver ? "YES" : "NO");
- printf("new: %s\n", has_new_driver ? "YES" : "NO");
+ printf("loaded: %s\n", driver_loaded ? "YES" : "NO");
+ printf("old: %s\n", has_old_driver ? "YES" : "NO");
+ printf("new: %s\n", has_new_driver ? "YES" : "NO");
#endif
- return driver_loaded;
- }
+ return driver_loaded;
+}
static void unload_driver()
{
- dlclose(module);
+ dlclose(module);
}
static void DeviceAdded(uint32_t unused)
{
#if DEBUG_NDOF_DRIVER
- printf("ndof: device added\n");
+ printf("ndof: device added\n");
#endif
- // determine exactly which device is plugged in
- int32_t result;
- ConnexionClientControl(clientID, kConnexionCtlGetDeviceID, 0, &result);
- int16_t vendorID = result >> 16;
- int16_t productID = result & 0xffff;
+ // determine exactly which device is plugged in
+ int32_t result;
+ ConnexionClientControl(clientID, kConnexionCtlGetDeviceID, 0, &result);
+ int16_t vendorID = result >> 16;
+ int16_t productID = result & 0xffff;
- ndof_manager->setDevice(vendorID, productID);
+ ndof_manager->setDevice(vendorID, productID);
}
static void DeviceRemoved(uint32_t unused)
{
#if DEBUG_NDOF_DRIVER
- printf("ndof: device removed\n");
+ printf("ndof: device removed\n");
#endif
}
-static void DeviceEvent(uint32_t unused, uint32_t msg_type, void* msg_arg)
+static void DeviceEvent(uint32_t unused, uint32_t msg_type, void *msg_arg)
{
- if (msg_type == kConnexionMsgDeviceState) {
- ConnexionDeviceState* s = (ConnexionDeviceState*)msg_arg;
-
- // device state is broadcast to all clients; only react if sent to us
- if (s->client == clientID) {
- // TODO: is s->time compatible with GHOST timestamps? if so use that instead.
- GHOST_TUns64 now = ghost_system->getMilliSeconds();
-
- switch (s->command) {
- case kConnexionCmdHandleAxis:
- {
- // convert to blender view coordinates
- const int t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]};
- const int r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])};
-
- ndof_manager->updateTranslation(t, now);
- ndof_manager->updateRotation(r, now);
-
- ghost_system->notifyExternalEventProcessed();
- break;
- }
- case kConnexionCmdHandleButtons:
- {
- int button_bits = has_old_driver ? s->buttons8 : s->buttons;
+ if (msg_type == kConnexionMsgDeviceState) {
+ ConnexionDeviceState *s = (ConnexionDeviceState *)msg_arg;
+
+ // device state is broadcast to all clients; only react if sent to us
+ if (s->client == clientID) {
+ // TODO: is s->time compatible with GHOST timestamps? if so use that instead.
+ GHOST_TUns64 now = ghost_system->getMilliSeconds();
+
+ switch (s->command) {
+ case kConnexionCmdHandleAxis: {
+ // convert to blender view coordinates
+ const int t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]};
+ const int r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])};
+
+ ndof_manager->updateTranslation(t, now);
+ ndof_manager->updateRotation(r, now);
+
+ ghost_system->notifyExternalEventProcessed();
+ break;
+ }
+ case kConnexionCmdHandleButtons: {
+ int button_bits = has_old_driver ? s->buttons8 : s->buttons;
#ifdef DEBUG_NDOF_BUTTONS
- printf("button bits: 0x%08x\n", button_bits);
+ printf("button bits: 0x%08x\n", button_bits);
#endif
- ndof_manager->updateButtons(button_bits, now);
- ghost_system->notifyExternalEventProcessed();
- break;
- }
+ ndof_manager->updateButtons(button_bits, now);
+ ghost_system->notifyExternalEventProcessed();
+ break;
+ }
#if DEBUG_NDOF_DRIVER
- case kConnexionCmdAppSpecific:
- printf("ndof: app-specific command, param = %hd, value = %d\n", s->param, s->value);
- break;
+ case kConnexionCmdAppSpecific:
+ printf("ndof: app-specific command, param = %hd, value = %d\n", s->param, s->value);
+ break;
- default:
- printf("ndof: mystery device command %d\n", s->command);
+ default:
+ printf("ndof: mystery device command %d\n", s->command);
#endif
- }
- }
- }
+ }
+ }
+ }
}
-GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System& sys)
- : GHOST_NDOFManager(sys)
+GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System &sys) : GHOST_NDOFManager(sys)
{
- if (load_driver_functions()) {
- // give static functions something to talk to:
- ghost_system = dynamic_cast<GHOST_SystemCocoa*>(&sys);
- ndof_manager = this;
-
- uint16_t error;
- if (has_new_driver) {
- const bool separate_thread = false; // TODO: rework Mac event handler to allow this
- error = SetConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved, separate_thread);
- }
- else {
- error = InstallConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved);
- }
-
- if (error) {
+ if (load_driver_functions()) {
+ // give static functions something to talk to:
+ ghost_system = dynamic_cast<GHOST_SystemCocoa *>(&sys);
+ ndof_manager = this;
+
+ uint16_t error;
+ if (has_new_driver) {
+ const bool separate_thread = false; // TODO: rework Mac event handler to allow this
+ error = SetConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved, separate_thread);
+ }
+ else {
+ error = InstallConnexionHandlers(DeviceEvent, DeviceAdded, DeviceRemoved);
+ }
+
+ if (error) {
#if DEBUG_NDOF_DRIVER
- printf("ndof: error %d while setting up handlers\n", error);
+ printf("ndof: error %d while setting up handlers\n", error);
#endif
- return;
- }
+ return;
+ }
- // Pascal string *and* a four-letter constant. How old-skool.
- clientID = RegisterConnexionClient('blnd', "\007blender", kConnexionClientModeTakeOver, kConnexionMaskAll);
+ // Pascal string *and* a four-letter constant. How old-skool.
+ clientID = RegisterConnexionClient(
+ 'blnd', "\007blender", kConnexionClientModeTakeOver, kConnexionMaskAll);
- if (!has_old_driver) {
- SetConnexionClientButtonMask(clientID, kConnexionMaskAllButtons);
- }
- }
+ if (!has_old_driver) {
+ SetConnexionClientButtonMask(clientID, kConnexionMaskAllButtons);
+ }
+ }
}
GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa()
{
- if (driver_loaded) {
- UnregisterConnexionClient(clientID);
- CleanupConnexionHandlers();
- unload_driver();
-
- ghost_system = NULL;
- ndof_manager = NULL;
- }
+ if (driver_loaded) {
+ UnregisterConnexionClient(clientID);
+ CleanupConnexionHandlers();
+ unload_driver();
+
+ ghost_system = NULL;
+ ndof_manager = NULL;
+ }
}
bool GHOST_NDOFManagerCocoa::available()
{
- return driver_loaded;
+ return driver_loaded;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
index f8609e5cccb..8ed0af1fc29 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
@@ -23,49 +23,48 @@
#define SPNAV_SOCK_PATH "/var/run/spnav.sock"
-GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System& sys)
- : GHOST_NDOFManager(sys),
- m_available(false)
+GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
+ : GHOST_NDOFManager(sys), m_available(false)
{
- if (access(SPNAV_SOCK_PATH, F_OK) != 0) {
+ if (access(SPNAV_SOCK_PATH, F_OK) != 0) {
#ifdef DEBUG
- /* annoying for official builds, just adds noise and most people don't own these */
- puts("ndof: spacenavd not found");
- /* This isn't a hard error, just means the user doesn't have a 3D mouse. */
+ /* annoying for official builds, just adds noise and most people don't own these */
+ puts("ndof: spacenavd not found");
+ /* This isn't a hard error, just means the user doesn't have a 3D mouse. */
#endif
- }
- else if (spnav_open() != -1) {
- m_available = true;
+ }
+ else if (spnav_open() != -1) {
+ m_available = true;
- /* determine exactly which device (if any) is plugged in */
+ /* determine exactly which device (if any) is plugged in */
#define MAX_LINE_LENGTH 100
- /* look for USB devices with Logitech or 3Dconnexion's vendor ID */
- FILE *command_output = popen("lsusb | grep '046d:\\|256f:'", "r");
- if (command_output) {
- char line[MAX_LINE_LENGTH] = {0};
- while (fgets(line, MAX_LINE_LENGTH, command_output)) {
- unsigned short vendor_id = 0, product_id = 0;
- if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2)
- if (setDevice(vendor_id, product_id)) {
- break; /* stop looking once the first 3D mouse is found */
- }
- }
- pclose(command_output);
- }
- }
+ /* look for USB devices with Logitech or 3Dconnexion's vendor ID */
+ FILE *command_output = popen("lsusb | grep '046d:\\|256f:'", "r");
+ if (command_output) {
+ char line[MAX_LINE_LENGTH] = {0};
+ while (fgets(line, MAX_LINE_LENGTH, command_output)) {
+ unsigned short vendor_id = 0, product_id = 0;
+ if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2)
+ if (setDevice(vendor_id, product_id)) {
+ break; /* stop looking once the first 3D mouse is found */
+ }
+ }
+ pclose(command_output);
+ }
+ }
}
GHOST_NDOFManagerUnix::~GHOST_NDOFManagerUnix()
{
- if (m_available)
- spnav_close();
+ if (m_available)
+ spnav_close();
}
bool GHOST_NDOFManagerUnix::available()
{
- return m_available;
+ return m_available;
}
/*
@@ -85,53 +84,51 @@ static bool motion_test_prev = false;
bool GHOST_NDOFManagerUnix::processEvents()
{
- bool anyProcessed = false;
+ bool anyProcessed = false;
- if (m_available) {
- spnav_event e;
+ if (m_available) {
+ spnav_event e;
#ifdef USE_FINISH_GLITCH_WORKAROUND
- bool motion_test = false;
+ bool motion_test = false;
#endif
- while (spnav_poll_event(&e)) {
- switch (e.type) {
- case SPNAV_EVENT_MOTION:
- {
- /* convert to blender view coords */
- GHOST_TUns64 now = m_system.getMilliSeconds();
- const int t[3] = {(int)e.motion.x, (int)e.motion.y, (int)-e.motion.z};
- const int r[3] = {(int)-e.motion.rx, (int)-e.motion.ry, (int)e.motion.rz};
-
- updateTranslation(t, now);
- updateRotation(r, now);
+ while (spnav_poll_event(&e)) {
+ switch (e.type) {
+ case SPNAV_EVENT_MOTION: {
+ /* convert to blender view coords */
+ GHOST_TUns64 now = m_system.getMilliSeconds();
+ const int t[3] = {(int)e.motion.x, (int)e.motion.y, (int)-e.motion.z};
+ const int r[3] = {(int)-e.motion.rx, (int)-e.motion.ry, (int)e.motion.rz};
+
+ updateTranslation(t, now);
+ updateRotation(r, now);
#ifdef USE_FINISH_GLITCH_WORKAROUND
- motion_test = true;
+ motion_test = true;
#endif
- break;
- }
- case SPNAV_EVENT_BUTTON:
- GHOST_TUns64 now = m_system.getMilliSeconds();
- updateButton(e.button.bnum, e.button.press, now);
- break;
- }
- anyProcessed = true;
- }
+ break;
+ }
+ case SPNAV_EVENT_BUTTON:
+ GHOST_TUns64 now = m_system.getMilliSeconds();
+ updateButton(e.button.bnum, e.button.press, now);
+ break;
+ }
+ anyProcessed = true;
+ }
#ifdef USE_FINISH_GLITCH_WORKAROUND
- if (motion_test_prev == true && motion_test == false) {
- GHOST_TUns64 now = m_system.getMilliSeconds();
- const int v[3] = {0, 0, 0};
+ if (motion_test_prev == true && motion_test == false) {
+ GHOST_TUns64 now = m_system.getMilliSeconds();
+ const int v[3] = {0, 0, 0};
- updateTranslation(v, now);
- updateRotation(v, now);
+ updateTranslation(v, now);
+ updateRotation(v, now);
- anyProcessed = true;
- }
- motion_test_prev = motion_test;
+ anyProcessed = true;
+ }
+ motion_test_prev = motion_test;
#endif
+ }
- }
-
- return anyProcessed;
+ return anyProcessed;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.h b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
index e6b3f95124f..75bd022631a 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
@@ -22,16 +22,15 @@
/* Event capture is handled within the NDOF manager on Linux,
* so there's no need for SystemX11 to look for them. */
-class GHOST_NDOFManagerUnix : public GHOST_NDOFManager
-{
-public:
- GHOST_NDOFManagerUnix(GHOST_System&);
- ~GHOST_NDOFManagerUnix();
- bool available();
- bool processEvents();
+class GHOST_NDOFManagerUnix : public GHOST_NDOFManager {
+ public:
+ GHOST_NDOFManagerUnix(GHOST_System &);
+ ~GHOST_NDOFManagerUnix();
+ bool available();
+ bool processEvents();
-private:
- bool m_available;
+ private:
+ bool m_available;
};
-#endif /* __GHOST_NDOFMANAGERUNIX_H__ */
+#endif /* __GHOST_NDOFMANAGERUNIX_H__ */
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
index bcbae1c52bd..5bd1bdfb6a1 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
@@ -16,17 +16,15 @@
#include "GHOST_NDOFManagerWin32.h"
-
-GHOST_NDOFManagerWin32::GHOST_NDOFManagerWin32(GHOST_System& sys)
- : GHOST_NDOFManager(sys)
+GHOST_NDOFManagerWin32::GHOST_NDOFManagerWin32(GHOST_System &sys) : GHOST_NDOFManager(sys)
{
- /* pass */
+ /* pass */
}
// whether multi-axis functionality is available (via the OS or driver)
// does not imply that a device is plugged in or being used
bool GHOST_NDOFManagerWin32::available()
{
- // always available since RawInput is built into Windows
- return true;
+ // always available since RawInput is built into Windows
+ return true;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
index 3a1304ffd71..9ed5e6ab978 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerWin32.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
@@ -14,18 +14,15 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
#ifndef __GHOST_NDOFMANAGERWIN32_H__
#define __GHOST_NDOFMANAGERWIN32_H__
#include "GHOST_NDOFManager.h"
-
-class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager
-{
-public:
- GHOST_NDOFManagerWin32(GHOST_System&);
- bool available();
+class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager {
+ public:
+ GHOST_NDOFManagerWin32(GHOST_System &);
+ bool available();
};
-#endif // #include guard
+#endif // #include guard
diff --git a/intern/ghost/intern/GHOST_Path-api.cpp b/intern/ghost/intern/GHOST_Path-api.cpp
index 645613d17a6..9e4ed1e0eea 100644
--- a/intern/ghost/intern/GHOST_Path-api.cpp
+++ b/intern/ghost/intern/GHOST_Path-api.cpp
@@ -30,36 +30,36 @@
GHOST_TSuccess GHOST_CreateSystemPaths(void)
{
- return GHOST_ISystemPaths::create();
+ return GHOST_ISystemPaths::create();
}
GHOST_TSuccess GHOST_DisposeSystemPaths(void)
{
- return GHOST_ISystemPaths::dispose();
+ return GHOST_ISystemPaths::dispose();
}
const GHOST_TUns8 *GHOST_getSystemDir(int version, const char *versionstr)
{
- GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
- return systemPaths ? systemPaths->getSystemDir(version, versionstr) : NULL;
+ GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
+ return systemPaths ? systemPaths->getSystemDir(version, versionstr) : NULL;
}
const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr)
{
- GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
- return systemPaths ? systemPaths->getUserDir(version, versionstr) : NULL; /* shouldn't be NULL */
+ GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
+ return systemPaths ? systemPaths->getUserDir(version, versionstr) : NULL; /* shouldn't be NULL */
}
const GHOST_TUns8 *GHOST_getBinaryDir()
{
- GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
- return systemPaths ? systemPaths->getBinaryDir() : NULL; /* shouldn't be NULL */
+ GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
+ return systemPaths ? systemPaths->getBinaryDir() : NULL; /* shouldn't be NULL */
}
void GHOST_addToSystemRecentFiles(const char *filename)
{
- GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
- if (systemPaths) {
- systemPaths->addToSystemRecentFiles(filename);
- }
+ GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
+ if (systemPaths) {
+ systemPaths->addToSystemRecentFiles(filename);
+ }
}
diff --git a/intern/ghost/intern/GHOST_Rect.cpp b/intern/ghost/intern/GHOST_Rect.cpp
index 973c3d40ae8..c5b9bc44468 100644
--- a/intern/ghost/intern/GHOST_Rect.cpp
+++ b/intern/ghost/intern/GHOST_Rect.cpp
@@ -21,112 +21,107 @@
* \ingroup GHOST
*/
-
#include "GHOST_Rect.h"
-
-
void GHOST_Rect::inset(GHOST_TInt32 i)
{
- if (i > 0) {
- // Grow the rectangle
- m_l -= i;
- m_r += i;
- m_t -= i;
- m_b += i;
- }
- else if (i < 0) {
- // Shrink the rectangle, check for insets larger than half the size
- GHOST_TInt32 i2 = i * 2;
- if (getWidth() > i2) {
- m_l += i;
- m_r -= i;
- }
- else {
- m_l = m_l + ((m_r - m_l) / 2);
- m_r = m_l;
- }
- if (getHeight() > i2) {
- m_t += i;
- m_b -= i;
- }
- else {
- m_t = m_t + ((m_b - m_t) / 2);
- m_b = m_t;
- }
- }
+ if (i > 0) {
+ // Grow the rectangle
+ m_l -= i;
+ m_r += i;
+ m_t -= i;
+ m_b += i;
+ }
+ else if (i < 0) {
+ // Shrink the rectangle, check for insets larger than half the size
+ GHOST_TInt32 i2 = i * 2;
+ if (getWidth() > i2) {
+ m_l += i;
+ m_r -= i;
+ }
+ else {
+ m_l = m_l + ((m_r - m_l) / 2);
+ m_r = m_l;
+ }
+ if (getHeight() > i2) {
+ m_t += i;
+ m_b -= i;
+ }
+ else {
+ m_t = m_t + ((m_b - m_t) / 2);
+ m_b = m_t;
+ }
+ }
}
-
-GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect& r) const
+GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect &r) const
{
- bool lt = isInside(r.m_l, r.m_t);
- bool rt = isInside(r.m_r, r.m_t);
- bool lb = isInside(r.m_l, r.m_b);
- bool rb = isInside(r.m_r, r.m_b);
- GHOST_TVisibility v;
- if (lt && rt && lb && rb) {
- // All points inside, rectangle is inside this
- v = GHOST_kFullyVisible;
- }
- else if (!(lt || rt || lb || rb)) {
- // None of the points inside
- // Check to see whether the rectangle is larger than this one
- if ((r.m_l < m_l) && (r.m_t < m_t) && (r.m_r > m_r) && (r.m_b > m_b)) {
- v = GHOST_kPartiallyVisible;
- }
- else {
- v = GHOST_kNotVisible;
- }
- }
- else {
- // Some of the points inside, rectangle is partially inside
- v = GHOST_kPartiallyVisible;
- }
- return v;
+ bool lt = isInside(r.m_l, r.m_t);
+ bool rt = isInside(r.m_r, r.m_t);
+ bool lb = isInside(r.m_l, r.m_b);
+ bool rb = isInside(r.m_r, r.m_b);
+ GHOST_TVisibility v;
+ if (lt && rt && lb && rb) {
+ // All points inside, rectangle is inside this
+ v = GHOST_kFullyVisible;
+ }
+ else if (!(lt || rt || lb || rb)) {
+ // None of the points inside
+ // Check to see whether the rectangle is larger than this one
+ if ((r.m_l < m_l) && (r.m_t < m_t) && (r.m_r > m_r) && (r.m_b > m_b)) {
+ v = GHOST_kPartiallyVisible;
+ }
+ else {
+ v = GHOST_kNotVisible;
+ }
+ }
+ else {
+ // Some of the points inside, rectangle is partially inside
+ v = GHOST_kPartiallyVisible;
+ }
+ return v;
}
-
void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy)
{
- GHOST_TInt32 offset = cx - (m_l + (m_r - m_l) / 2);
- m_l += offset;
- m_r += offset;
- offset = cy - (m_t + (m_b - m_t) / 2);
- m_t += offset;
- m_b += offset;
+ GHOST_TInt32 offset = cx - (m_l + (m_r - m_l) / 2);
+ m_l += offset;
+ m_r += offset;
+ offset = cy - (m_t + (m_b - m_t) / 2);
+ m_t += offset;
+ m_b += offset;
}
void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h)
{
- long w_2, h_2;
+ long w_2, h_2;
- w_2 = w >> 1;
- h_2 = h >> 1;
- m_l = cx - w_2;
- m_t = cy - h_2;
- m_r = m_l + w;
- m_b = m_t + h;
+ w_2 = w >> 1;
+ h_2 = h >> 1;
+ m_l = cx - w_2;
+ m_t = cy - h_2;
+ m_r = m_l + w;
+ m_b = m_t + h;
}
-bool GHOST_Rect::clip(GHOST_Rect& r) const
+bool GHOST_Rect::clip(GHOST_Rect &r) const
{
- bool clipped = false;
- if (r.m_l < m_l) {
- r.m_l = m_l;
- clipped = true;
- }
- if (r.m_t < m_t) {
- r.m_t = m_t;
- clipped = true;
- }
- if (r.m_r > m_r) {
- r.m_r = m_r;
- clipped = true;
- }
- if (r.m_b > m_b) {
- r.m_b = m_b;
- clipped = true;
- }
- return clipped;
+ bool clipped = false;
+ if (r.m_l < m_l) {
+ r.m_l = m_l;
+ clipped = true;
+ }
+ if (r.m_t < m_t) {
+ r.m_t = m_t;
+ clipped = true;
+ }
+ if (r.m_r > m_r) {
+ r.m_r = m_r;
+ clipped = true;
+ }
+ if (r.m_b > m_b) {
+ r.m_b = m_b;
+ clipped = true;
+ }
+ return clipped;
}
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 27fb08ad014..1530dddd5f1 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -50,352 +50,354 @@ GHOST_System::GHOST_System()
{
}
-
GHOST_System::~GHOST_System()
{
- exit();
+ exit();
}
-
GHOST_TUns64 GHOST_System::getMilliSeconds() const
{
- GHOST_TUns64 millis = ::clock();
- if (CLOCKS_PER_SEC != 1000) {
- millis *= 1000;
- millis /= CLOCKS_PER_SEC;
- }
- return millis;
+ GHOST_TUns64 millis = ::clock();
+ if (CLOCKS_PER_SEC != 1000) {
+ millis *= 1000;
+ millis /= CLOCKS_PER_SEC;
+ }
+ return millis;
}
-
GHOST_ITimerTask *GHOST_System::installTimer(GHOST_TUns64 delay,
GHOST_TUns64 interval,
GHOST_TimerProcPtr timerProc,
GHOST_TUserDataPtr userData)
{
- GHOST_TUns64 millis = getMilliSeconds();
- GHOST_TimerTask *timer = new GHOST_TimerTask(millis + delay, interval, timerProc, userData);
- if (timer) {
- if (m_timerManager->addTimer(timer) == GHOST_kSuccess) {
- // Check to see whether we need to fire the timer right away
- m_timerManager->fireTimers(millis);
- }
- else {
- delete timer;
- timer = NULL;
- }
- }
- return timer;
+ GHOST_TUns64 millis = getMilliSeconds();
+ GHOST_TimerTask *timer = new GHOST_TimerTask(millis + delay, interval, timerProc, userData);
+ if (timer) {
+ if (m_timerManager->addTimer(timer) == GHOST_kSuccess) {
+ // Check to see whether we need to fire the timer right away
+ m_timerManager->fireTimers(millis);
+ }
+ else {
+ delete timer;
+ timer = NULL;
+ }
+ }
+ return timer;
}
-
GHOST_TSuccess GHOST_System::removeTimer(GHOST_ITimerTask *timerTask)
{
- GHOST_TSuccess success = GHOST_kFailure;
- if (timerTask) {
- success = m_timerManager->removeTimer((GHOST_TimerTask *)timerTask);
- }
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (timerTask) {
+ success = m_timerManager->removeTimer((GHOST_TimerTask *)timerTask);
+ }
+ return success;
}
-
GHOST_TSuccess GHOST_System::disposeWindow(GHOST_IWindow *window)
{
- GHOST_TSuccess success;
-
- /*
- * Remove all pending events for the window.
- */
- if (m_windowManager->getWindowFound(window)) {
- m_eventManager->removeWindowEvents(window);
- }
- if (window == m_windowManager->getFullScreenWindow()) {
- success = endFullScreen();
- }
- else {
- if (m_windowManager->getWindowFound(window)) {
- success = m_windowManager->removeWindow(window);
- if (success) {
- delete window;
- }
- }
- else {
- success = GHOST_kFailure;
- }
- }
- return success;
+ GHOST_TSuccess success;
+
+ /*
+ * Remove all pending events for the window.
+ */
+ if (m_windowManager->getWindowFound(window)) {
+ m_eventManager->removeWindowEvents(window);
+ }
+ if (window == m_windowManager->getFullScreenWindow()) {
+ success = endFullScreen();
+ }
+ else {
+ if (m_windowManager->getWindowFound(window)) {
+ success = m_windowManager->removeWindow(window);
+ if (success) {
+ delete window;
+ }
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
}
-
bool GHOST_System::validWindow(GHOST_IWindow *window)
{
- return m_windowManager->getWindowFound(window);
+ return m_windowManager->getWindowFound(window);
}
-
-GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window,
- const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples)
+GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting &setting,
+ GHOST_IWindow **window,
+ const bool stereoVisual,
+ const bool alphaBackground,
+ const GHOST_TUns16 numOfAASamples)
{
- GHOST_TSuccess success = GHOST_kFailure;
- GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager");
- if (m_displayManager) {
- if (!m_windowManager->getFullScreen()) {
- m_displayManager->getCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, m_preFullScreenSetting);
-
- //GHOST_PRINT("GHOST_System::beginFullScreen(): activating new display settings\n");
- success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting);
- if (success == GHOST_kSuccess) {
- //GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n");
- success = createFullScreenWindow((GHOST_Window **)window, setting, stereoVisual, alphaBackground, numOfAASamples);
- if (success == GHOST_kSuccess) {
- m_windowManager->beginFullScreen(*window, stereoVisual);
- }
- else {
- m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, m_preFullScreenSetting);
- }
- }
- }
- }
- if (success == GHOST_kFailure) {
- GHOST_PRINT("GHOST_System::beginFullScreen(): could not enter full-screen mode\n");
- }
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager");
+ if (m_displayManager) {
+ if (!m_windowManager->getFullScreen()) {
+ m_displayManager->getCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay,
+ m_preFullScreenSetting);
+
+ //GHOST_PRINT("GHOST_System::beginFullScreen(): activating new display settings\n");
+ success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay,
+ setting);
+ if (success == GHOST_kSuccess) {
+ //GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n");
+ success = createFullScreenWindow(
+ (GHOST_Window **)window, setting, stereoVisual, alphaBackground, numOfAASamples);
+ if (success == GHOST_kSuccess) {
+ m_windowManager->beginFullScreen(*window, stereoVisual);
+ }
+ else {
+ m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay,
+ m_preFullScreenSetting);
+ }
+ }
+ }
+ }
+ if (success == GHOST_kFailure) {
+ GHOST_PRINT("GHOST_System::beginFullScreen(): could not enter full-screen mode\n");
+ }
+ return success;
}
-
-GHOST_TSuccess GHOST_System::updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow ** /*window*/)
+GHOST_TSuccess GHOST_System::updateFullScreen(const GHOST_DisplaySetting &setting,
+ GHOST_IWindow ** /*window*/)
{
- GHOST_TSuccess success = GHOST_kFailure;
- GHOST_ASSERT(m_windowManager, "GHOST_System::updateFullScreen(): invalid window manager");
- if (m_displayManager) {
- if (m_windowManager->getFullScreen()) {
- success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting);
- }
- }
-
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ GHOST_ASSERT(m_windowManager, "GHOST_System::updateFullScreen(): invalid window manager");
+ if (m_displayManager) {
+ if (m_windowManager->getFullScreen()) {
+ success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay,
+ setting);
+ }
+ }
+
+ return success;
}
GHOST_TSuccess GHOST_System::endFullScreen(void)
{
- GHOST_TSuccess success = GHOST_kFailure;
- GHOST_ASSERT(m_windowManager, "GHOST_System::endFullScreen(): invalid window manager");
- if (m_windowManager->getFullScreen()) {
- //GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
- //GHOST_PRINT("GHOST_System::endFullScreen(): leaving window manager full-screen mode\n");
- success = m_windowManager->endFullScreen();
- GHOST_ASSERT(m_displayManager, "GHOST_System::endFullScreen(): invalid display manager");
- //GHOST_PRINT("GHOST_System::endFullScreen(): leaving full-screen mode\n");
- success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, m_preFullScreenSetting);
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ GHOST_ASSERT(m_windowManager, "GHOST_System::endFullScreen(): invalid window manager");
+ if (m_windowManager->getFullScreen()) {
+ //GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
+ //GHOST_PRINT("GHOST_System::endFullScreen(): leaving window manager full-screen mode\n");
+ success = m_windowManager->endFullScreen();
+ GHOST_ASSERT(m_displayManager, "GHOST_System::endFullScreen(): invalid display manager");
+ //GHOST_PRINT("GHOST_System::endFullScreen(): leaving full-screen mode\n");
+ success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay,
+ m_preFullScreenSetting);
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
bool GHOST_System::getFullScreen(void)
{
- bool fullScreen;
- if (m_windowManager) {
- fullScreen = m_windowManager->getFullScreen();
- }
- else {
- fullScreen = false;
- }
- return fullScreen;
+ bool fullScreen;
+ if (m_windowManager) {
+ fullScreen = m_windowManager->getFullScreen();
+ }
+ else {
+ fullScreen = false;
+ }
+ return fullScreen;
}
-
void GHOST_System::dispatchEvents()
{
#ifdef WITH_INPUT_NDOF
- // NDOF Motion event is sent only once per dispatch, so do it now:
- if (m_ndofManager) {
- m_ndofManager->sendMotionEvent();
- }
+ // NDOF Motion event is sent only once per dispatch, so do it now:
+ if (m_ndofManager) {
+ m_ndofManager->sendMotionEvent();
+ }
#endif
- if (m_eventManager) {
- m_eventManager->dispatchEvents();
- }
+ if (m_eventManager) {
+ m_eventManager->dispatchEvents();
+ }
- m_timerManager->fireTimers(getMilliSeconds());
+ m_timerManager->fireTimers(getMilliSeconds());
}
-
GHOST_TSuccess GHOST_System::addEventConsumer(GHOST_IEventConsumer *consumer)
{
- GHOST_TSuccess success;
- if (m_eventManager) {
- success = m_eventManager->addConsumer(consumer);
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ if (m_eventManager) {
+ success = m_eventManager->addConsumer(consumer);
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
GHOST_TSuccess GHOST_System::removeEventConsumer(GHOST_IEventConsumer *consumer)
{
- GHOST_TSuccess success;
- if (m_eventManager) {
- success = m_eventManager->removeConsumer(consumer);
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ if (m_eventManager) {
+ success = m_eventManager->removeConsumer(consumer);
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent *event)
{
- GHOST_TSuccess success;
- if (m_eventManager) {
- success = m_eventManager->pushEvent(event);
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ if (m_eventManager) {
+ success = m_eventManager->pushEvent(event);
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const
+GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool &isDown) const
{
- GHOST_ModifierKeys keys;
- // Get the state of all modifier keys
- GHOST_TSuccess success = getModifierKeys(keys);
- if (success) {
- // Isolate the state of the key requested
- isDown = keys.get(mask);
- }
- return success;
+ GHOST_ModifierKeys keys;
+ // Get the state of all modifier keys
+ GHOST_TSuccess success = getModifierKeys(keys);
+ if (success) {
+ // Isolate the state of the key requested
+ isDown = keys.get(mask);
+ }
+ return success;
}
-
-GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool& isDown) const
+GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool &isDown) const
{
- GHOST_Buttons buttons;
- // Get the state of all mouse buttons
- GHOST_TSuccess success = getButtons(buttons);
- if (success) {
- // Isolate the state of the mouse button requested
- isDown = buttons.get(mask);
- }
- return success;
+ GHOST_Buttons buttons;
+ // Get the state of all mouse buttons
+ GHOST_TSuccess success = getButtons(buttons);
+ if (success) {
+ // Isolate the state of the mouse button requested
+ isDown = buttons.get(mask);
+ }
+ return success;
}
void GHOST_System::setTabletAPI(GHOST_TTabletAPI api)
{
- m_tabletAPI = api;
+ m_tabletAPI = api;
}
GHOST_TTabletAPI GHOST_System::getTabletAPI(void)
{
- return m_tabletAPI;
+ return m_tabletAPI;
}
#ifdef WITH_INPUT_NDOF
void GHOST_System::setNDOFDeadZone(float deadzone)
{
- if (this->m_ndofManager) {
- this->m_ndofManager->setDeadZone(deadzone);
- }
+ if (this->m_ndofManager) {
+ this->m_ndofManager->setDeadZone(deadzone);
+ }
}
#endif
GHOST_TSuccess GHOST_System::init()
{
- m_timerManager = new GHOST_TimerManager();
- m_windowManager = new GHOST_WindowManager();
- m_eventManager = new GHOST_EventManager();
+ m_timerManager = new GHOST_TimerManager();
+ m_windowManager = new GHOST_WindowManager();
+ m_eventManager = new GHOST_EventManager();
#ifdef GHOST_DEBUG
- if (m_eventManager) {
- m_eventPrinter = new GHOST_EventPrinter();
- m_eventManager->addConsumer(m_eventPrinter);
- }
-#endif // GHOST_DEBUG
-
- if (m_timerManager && m_windowManager && m_eventManager) {
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (m_eventManager) {
+ m_eventPrinter = new GHOST_EventPrinter();
+ m_eventManager->addConsumer(m_eventPrinter);
+ }
+#endif // GHOST_DEBUG
+
+ if (m_timerManager && m_windowManager && m_eventManager) {
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-
GHOST_TSuccess GHOST_System::exit()
{
- if (getFullScreen()) {
- endFullScreen();
- }
+ if (getFullScreen()) {
+ endFullScreen();
+ }
- delete m_displayManager;
- m_displayManager = NULL;
+ delete m_displayManager;
+ m_displayManager = NULL;
- delete m_windowManager;
- m_windowManager = NULL;
+ delete m_windowManager;
+ m_windowManager = NULL;
- delete m_timerManager;
- m_timerManager = NULL;
+ delete m_timerManager;
+ m_timerManager = NULL;
- delete m_eventManager;
- m_eventManager = NULL;
+ delete m_eventManager;
+ m_eventManager = NULL;
#ifdef WITH_INPUT_NDOF
- delete m_ndofManager;
- m_ndofManager = NULL;
+ delete m_ndofManager;
+ m_ndofManager = NULL;
#endif
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
- const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples)
+GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
+ const GHOST_DisplaySetting &settings,
+ const bool stereoVisual,
+ const bool alphaBackground,
+ const GHOST_TUns16 numOfAASamples)
{
- GHOST_GLSettings glSettings = {0};
-
- if (stereoVisual)
- glSettings.flags |= GHOST_glStereoVisual;
- if (alphaBackground)
- glSettings.flags |= GHOST_glAlphaBackground;
- glSettings.numOfAASamples = numOfAASamples;
-
- /* note: don't use getCurrentDisplaySetting() because on X11 we may
- * be zoomed in and the desktop may be bigger then the viewport. */
- GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager");
- //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n");
- *window = (GHOST_Window *)createWindow(
- STR_String(""),
- 0, 0, settings.xPixels, settings.yPixels,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings,
- true /* exclusive */);
- return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess;
+ GHOST_GLSettings glSettings = {0};
+
+ if (stereoVisual)
+ glSettings.flags |= GHOST_glStereoVisual;
+ if (alphaBackground)
+ glSettings.flags |= GHOST_glAlphaBackground;
+ glSettings.numOfAASamples = numOfAASamples;
+
+ /* note: don't use getCurrentDisplaySetting() because on X11 we may
+ * be zoomed in and the desktop may be bigger then the viewport. */
+ GHOST_ASSERT(m_displayManager,
+ "GHOST_System::createFullScreenWindow(): invalid display manager");
+ //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n");
+ *window = (GHOST_Window *)createWindow(STR_String(""),
+ 0,
+ 0,
+ settings.xPixels,
+ settings.yPixels,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings,
+ true /* exclusive */);
+ return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess;
}
-
int GHOST_System::confirmQuit(GHOST_IWindow * /*window*/) const
{
- return 1;
+ return 1;
}
bool GHOST_System::supportsNativeDialogs(void)
{
- return 1;
+ return 1;
}
bool GHOST_System::useNativePixel(void)
{
- m_nativePixel = true;
- return 1;
+ m_nativePixel = true;
+ return 1;
}
void GHOST_System::useWindowFocus(const bool use_focus)
{
- m_windowFocus = use_focus;
+ m_windowFocus = use_focus;
}
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index b9b7fc5658a..2c7025b6036 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -32,8 +32,8 @@
#include "GHOST_ModifierKeys.h"
#include "GHOST_EventManager.h"
#ifdef GHOST_DEBUG
-#include "GHOST_EventPrinter.h"
-#endif // GHOST_DEBUG
+# include "GHOST_EventPrinter.h"
+#endif // GHOST_DEBUG
class GHOST_DisplayManager;
class GHOST_Event;
@@ -51,356 +51,357 @@ class GHOST_NDOFManager;
* are implemented.
* \see GHOST_ISystem.
*/
-class GHOST_System : public GHOST_ISystem
-{
-protected:
- /**
- * Constructor.
- * Protected default constructor to force use of static createSystem member.
- */
- GHOST_System();
-
- /**
- * Destructor.
- * Protected default constructor to force use of static dispose member.
- */
- virtual ~GHOST_System();
-
-public:
- /***************************************************************************************
- * Time(r) functionality
- ***************************************************************************************/
-
- /**
- * Returns the system time.
- * Returns the number of milliseconds since the start of the system process.
- * Based on ANSI clock() routine.
- * \return The number of milliseconds.
- */
- virtual GHOST_TUns64 getMilliSeconds() const;
-
- /**
- * Installs a timer.
- * Note that, on most operating systems, messages need to be processed in order
- * for the timer callbacks to be invoked.
- * \param delay The time to wait for the first call to the timerProc (in milliseconds)
- * \param interval The interval between calls to the timerProc
- * \param timerProc The callback invoked when the interval expires,
- * \param userData Placeholder for user data.
- * \return A timer task (0 if timer task installation failed).
- */
- GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
- GHOST_TUns64 interval,
- GHOST_TimerProcPtr timerProc,
- GHOST_TUserDataPtr userData = NULL);
-
- /**
- * Removes a timer.
- * \param timerTask Timer task to be removed.
- * \return Indication of success.
- */
- GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask);
-
- /***************************************************************************************
- * Display/window management functionality
- ***************************************************************************************/
-
- /**
- * Inherited from GHOST_ISystem but left pure virtual
- *
- * virtual GHOST_TUns8 getNumDisplays() const = 0;
- * virtual void getMainDisplayDimensions(...) const = 0;
- * virtual GHOST_IWindow* createWindow(..)
- */
-
- /**
- * Dispose a window.
- * \param window Pointer to the window to be disposed.
- * \return Indication of success.
- */
- GHOST_TSuccess disposeWindow(GHOST_IWindow *window);
-
- /**
- * Returns whether a window is valid.
- * \param window Pointer to the window to be checked.
- * \return Indication of validity.
- */
- bool validWindow(GHOST_IWindow *window);
-
- /**
- * Begins full screen mode.
- * \param setting The new setting of the display.
- * \param window Window displayed in full screen.
- * \param stereoVisual Stereo visual for quad buffered stereo.
- * This window is invalid after full screen has been ended.
- * \return Indication of success.
- */
- GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window,
- const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples = 0);
-
- /**
- * Updates the resolution while in fullscreen mode.
- * \param setting The new setting of the display.
- * \param window Window displayed in full screen.
- *
- * \return Indication of success.
- */
- GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window);
-
- /**
- * Ends full screen mode.
- * \return Indication of success.
- */
- GHOST_TSuccess endFullScreen(void);
-
- /**
- * Returns current full screen mode status.
- * \return The current status.
- */
- bool getFullScreen(void);
-
-
- /**
- * Native pixel size support (MacBook 'retina').
- * \return The pixel size in float.
- */
- bool useNativePixel(void);
- bool m_nativePixel;
-
- /**
- * Focus window after opening, or put them in the background.
- */
- void useWindowFocus(const bool use_focus);
- bool m_windowFocus;
-
- /***************************************************************************************
- * Event management functionality
- ***************************************************************************************/
-
- /**
- * Inherited from GHOST_ISystem but left pure virtual
- *
- * virtual bool processEvents(bool waitForEvent) = 0;
- */
-
-
-
- /**
- * Dispatches all the events on the stack.
- * The event stack will be empty afterwards.
- */
- void dispatchEvents();
-
- /**
- * Adds the given event consumer to our list.
- * \param consumer The event consumer to add.
- * \return Indication of success.
- */
- GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer);
-
- /**
- * Remove the given event consumer to our list.
- * \param consumer The event consumer to remove.
- * \return Indication of success.
- */
- GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer);
-
- /***************************************************************************************
- * Cursor management functionality
- ***************************************************************************************/
-
- /**
- * Inherited from GHOST_ISystem but left pure virtual
- * <pre>
- * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0;
- * GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
- * </pre>
- */
-
- /***************************************************************************************
- * Access to mouse button and keyboard states.
- ***************************************************************************************/
-
- /**
- * Returns the state of a modifier key (ouside the message queue).
- * \param mask The modifier key state to retrieve.
- * \param isDown The state of a modifier key (true == pressed).
- * \return Indication of success.
- */
- GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const;
-
- /**
- * Returns the state of a mouse button (ouside the message queue).
- * \param mask The button state to retrieve.
- * \param isDown Button state.
- * \return Indication of success.
- */
- GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const;
-
- /**
- * Set which tablet API to use. Only affects Windows, other platforms have a single API.
- * \param api Enum indicating which API to use.
- */
- void setTabletAPI(GHOST_TTabletAPI api);
- GHOST_TTabletAPI getTabletAPI(void);
+class GHOST_System : public GHOST_ISystem {
+ protected:
+ /**
+ * Constructor.
+ * Protected default constructor to force use of static createSystem member.
+ */
+ GHOST_System();
+
+ /**
+ * Destructor.
+ * Protected default constructor to force use of static dispose member.
+ */
+ virtual ~GHOST_System();
+
+ public:
+ /***************************************************************************************
+ * Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * \return The number of milliseconds.
+ */
+ virtual GHOST_TUns64 getMilliSeconds() const;
+
+ /**
+ * Installs a timer.
+ * Note that, on most operating systems, messages need to be processed in order
+ * for the timer callbacks to be invoked.
+ * \param delay The time to wait for the first call to the timerProc (in milliseconds)
+ * \param interval The interval between calls to the timerProc
+ * \param timerProc The callback invoked when the interval expires,
+ * \param userData Placeholder for user data.
+ * \return A timer task (0 if timer task installation failed).
+ */
+ GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
+ GHOST_TUns64 interval,
+ GHOST_TimerProcPtr timerProc,
+ GHOST_TUserDataPtr userData = NULL);
+
+ /**
+ * Removes a timer.
+ * \param timerTask Timer task to be removed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask);
+
+ /***************************************************************************************
+ * Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Inherited from GHOST_ISystem but left pure virtual
+ *
+ * virtual GHOST_TUns8 getNumDisplays() const = 0;
+ * virtual void getMainDisplayDimensions(...) const = 0;
+ * virtual GHOST_IWindow* createWindow(..)
+ */
+
+ /**
+ * Dispose a window.
+ * \param window Pointer to the window to be disposed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess disposeWindow(GHOST_IWindow *window);
+
+ /**
+ * Returns whether a window is valid.
+ * \param window Pointer to the window to be checked.
+ * \return Indication of validity.
+ */
+ bool validWindow(GHOST_IWindow *window);
+
+ /**
+ * Begins full screen mode.
+ * \param setting The new setting of the display.
+ * \param window Window displayed in full screen.
+ * \param stereoVisual Stereo visual for quad buffered stereo.
+ * This window is invalid after full screen has been ended.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting,
+ GHOST_IWindow **window,
+ const bool stereoVisual,
+ const bool alphaBackground,
+ const GHOST_TUns16 numOfAASamples = 0);
+
+ /**
+ * Updates the resolution while in fullscreen mode.
+ * \param setting The new setting of the display.
+ * \param window Window displayed in full screen.
+ *
+ * \return Indication of success.
+ */
+ GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window);
+
+ /**
+ * Ends full screen mode.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess endFullScreen(void);
+
+ /**
+ * Returns current full screen mode status.
+ * \return The current status.
+ */
+ bool getFullScreen(void);
+
+ /**
+ * Native pixel size support (MacBook 'retina').
+ * \return The pixel size in float.
+ */
+ bool useNativePixel(void);
+ bool m_nativePixel;
+
+ /**
+ * Focus window after opening, or put them in the background.
+ */
+ void useWindowFocus(const bool use_focus);
+ bool m_windowFocus;
+
+ /***************************************************************************************
+ * Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Inherited from GHOST_ISystem but left pure virtual
+ *
+ * virtual bool processEvents(bool waitForEvent) = 0;
+ */
+
+ /**
+ * Dispatches all the events on the stack.
+ * The event stack will be empty afterwards.
+ */
+ void dispatchEvents();
+
+ /**
+ * Adds the given event consumer to our list.
+ * \param consumer The event consumer to add.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer);
+
+ /**
+ * Remove the given event consumer to our list.
+ * \param consumer The event consumer to remove.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer);
+
+ /***************************************************************************************
+ * Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Inherited from GHOST_ISystem but left pure virtual
+ * <pre>
+ * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0;
+ * GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
+ * </pre>
+ */
+
+ /***************************************************************************************
+ * Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of a modifier key (ouside the message queue).
+ * \param mask The modifier key state to retrieve.
+ * \param isDown The state of a modifier key (true == pressed).
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool &isDown) const;
+
+ /**
+ * Returns the state of a mouse button (ouside the message queue).
+ * \param mask The button state to retrieve.
+ * \param isDown Button state.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool &isDown) const;
+
+ /**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param api Enum indicating which API to use.
+ */
+ void setTabletAPI(GHOST_TTabletAPI api);
+ GHOST_TTabletAPI getTabletAPI(void);
#ifdef WITH_INPUT_NDOF
- /***************************************************************************************
- * Access to 3D mouse.
- ***************************************************************************************/
-
- /**
- * Sets 3D mouse deadzone
- * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range
- */
- void setNDOFDeadZone(float deadzone);
+ /***************************************************************************************
+ * Access to 3D mouse.
+ ***************************************************************************************/
+
+ /**
+ * Sets 3D mouse deadzone
+ * \param deadzone: Deadzone of the 3D mouse (both for rotation and pan) relative to full range
+ */
+ void setNDOFDeadZone(float deadzone);
#endif
- /***************************************************************************************
- * Other (internal) functionality.
- ***************************************************************************************/
-
- /**
- * Pushes an event on the stack.
- * To dispatch it, call dispatchEvent() or dispatchEvents().
- * Do not delete the event!
- * \param event The event to push on the stack.
- */
- GHOST_TSuccess pushEvent(GHOST_IEvent *event);
-
- /**
- * \return The timer manager.
- */
- inline GHOST_TimerManager *getTimerManager() const;
-
- /**
- * \return A pointer to our event manager.
- */
- inline GHOST_EventManager *getEventManager() const;
-
- /**
- * \return A pointer to our window manager.
- */
- inline GHOST_WindowManager *getWindowManager() const;
+ /***************************************************************************************
+ * Other (internal) functionality.
+ ***************************************************************************************/
+
+ /**
+ * Pushes an event on the stack.
+ * To dispatch it, call dispatchEvent() or dispatchEvents().
+ * Do not delete the event!
+ * \param event The event to push on the stack.
+ */
+ GHOST_TSuccess pushEvent(GHOST_IEvent *event);
+
+ /**
+ * \return The timer manager.
+ */
+ inline GHOST_TimerManager *getTimerManager() const;
+
+ /**
+ * \return A pointer to our event manager.
+ */
+ inline GHOST_EventManager *getEventManager() const;
+
+ /**
+ * \return A pointer to our window manager.
+ */
+ inline GHOST_WindowManager *getWindowManager() const;
#ifdef WITH_INPUT_NDOF
- /**
- * \return A pointer to our n-degree of freedom manager.
- */
- inline GHOST_NDOFManager *getNDOFManager() const;
+ /**
+ * \return A pointer to our n-degree of freedom manager.
+ */
+ inline GHOST_NDOFManager *getNDOFManager() const;
#endif
- /**
- * Returns the state of all modifier keys.
- * \param keys The state of all modifier keys (true == pressed).
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const = 0;
-
- /**
- * Returns the state of the mouse buttons (ouside the message queue).
- * \param buttons The state of the buttons.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const = 0;
-
- /**
- * Returns the selection buffer
- * \param selection Only used on X11
- * \return Returns the clipboard data
- *
- */
- virtual GHOST_TUns8 *getClipboard(bool selection) const = 0;
-
- /**
- * Put data to the Clipboard
- * \param buffer The buffer to copy to the clipboard
- * \param selection The clipboard to copy too only used on X11
- */
- virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0;
-
- /**
- * Confirms quitting he program when there is just one window left open
- * in the application
- */
- virtual int confirmQuit(GHOST_IWindow *window) const;
-
- /**
- * Informs if the system provides native dialogs (eg. confirm quit)
- */
- virtual bool supportsNativeDialogs(void);
-
-
-protected:
- /**
- * Initialize the system.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess init();
-
- /**
- * Shut the system down.
- * \return Indication of success.
- */
- virtual GHOST_TSuccess exit();
-
- /**
- * Creates a fullscreen window.
- * \param window The window created.
- * \return Indication of success.
- */
- GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
- const bool stereoVisual, const bool alphaBackground = 0, const GHOST_TUns16 numOfAASamples = 0);
-
- /** The display manager (platform dependent). */
- GHOST_DisplayManager *m_displayManager;
-
- /** The timer manager. */
- GHOST_TimerManager *m_timerManager;
-
- /** The window manager. */
- GHOST_WindowManager *m_windowManager;
-
- /** The event manager. */
- GHOST_EventManager *m_eventManager;
+ /**
+ * Returns the state of all modifier keys.
+ * \param keys The state of all modifier keys (true == pressed).
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const = 0;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * \param buttons The state of the buttons.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const = 0;
+
+ /**
+ * Returns the selection buffer
+ * \param selection Only used on X11
+ * \return Returns the clipboard data
+ *
+ */
+ virtual GHOST_TUns8 *getClipboard(bool selection) const = 0;
+
+ /**
+ * Put data to the Clipboard
+ * \param buffer The buffer to copy to the clipboard
+ * \param selection The clipboard to copy too only used on X11
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0;
+
+ /**
+ * Confirms quitting he program when there is just one window left open
+ * in the application
+ */
+ virtual int confirmQuit(GHOST_IWindow *window) const;
+
+ /**
+ * Informs if the system provides native dialogs (eg. confirm quit)
+ */
+ virtual bool supportsNativeDialogs(void);
+
+ protected:
+ /**
+ * Initialize the system.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess init();
+
+ /**
+ * Shut the system down.
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess exit();
+
+ /**
+ * Creates a fullscreen window.
+ * \param window The window created.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess createFullScreenWindow(GHOST_Window **window,
+ const GHOST_DisplaySetting &settings,
+ const bool stereoVisual,
+ const bool alphaBackground = 0,
+ const GHOST_TUns16 numOfAASamples = 0);
+
+ /** The display manager (platform dependent). */
+ GHOST_DisplayManager *m_displayManager;
+
+ /** The timer manager. */
+ GHOST_TimerManager *m_timerManager;
+
+ /** The window manager. */
+ GHOST_WindowManager *m_windowManager;
+
+ /** The event manager. */
+ GHOST_EventManager *m_eventManager;
#ifdef WITH_INPUT_NDOF
- /** The N-degree of freedom device manager */
- GHOST_NDOFManager *m_ndofManager;
+ /** The N-degree of freedom device manager */
+ GHOST_NDOFManager *m_ndofManager;
#endif
- /** Prints all the events. */
+ /** Prints all the events. */
#ifdef GHOST_DEBUG
- GHOST_EventPrinter *m_eventPrinter;
-#endif // GHOST_DEBUG
+ GHOST_EventPrinter *m_eventPrinter;
+#endif // GHOST_DEBUG
- /** Settings of the display before the display went fullscreen. */
- GHOST_DisplaySetting m_preFullScreenSetting;
+ /** Settings of the display before the display went fullscreen. */
+ GHOST_DisplaySetting m_preFullScreenSetting;
- /** Which tablet API to use. */
- GHOST_TTabletAPI m_tabletAPI;
+ /** Which tablet API to use. */
+ GHOST_TTabletAPI m_tabletAPI;
};
inline GHOST_TimerManager *GHOST_System::getTimerManager() const
{
- return m_timerManager;
+ return m_timerManager;
}
inline GHOST_EventManager *GHOST_System::getEventManager() const
{
- return m_eventManager;
+ return m_eventManager;
}
inline GHOST_WindowManager *GHOST_System::getWindowManager() const
{
- return m_windowManager;
+ return m_windowManager;
}
#ifdef WITH_INPUT_NDOF
inline GHOST_NDOFManager *GHOST_System::getNDOFManager() const
{
- return m_ndofManager;
+ return m_ndofManager;
}
#endif
-#endif // __GHOST_SYSTEM_H__
+#endif // __GHOST_SYSTEM_H__
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 289b084cc71..9206ef90ee7 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -26,12 +26,11 @@
#define __GHOST_SYSTEMCOCOA_H__
#ifndef __APPLE__
-#error Apple OSX only!
-#endif // __APPLE__
+# error Apple OSX only!
+#endif // __APPLE__
//#define __CARBONSOUND__
-
#include "GHOST_System.h"
class GHOST_EventCursor;
@@ -39,278 +38,275 @@ class GHOST_EventKey;
class GHOST_EventWindow;
class GHOST_WindowCocoa;
-
class GHOST_SystemCocoa : public GHOST_System {
-public:
- /**
- * Constructor.
- */
- GHOST_SystemCocoa();
-
- /**
- * Destructor.
- */
- ~GHOST_SystemCocoa();
-
- /***************************************************************************************
- * Time(r) functionality
- ***************************************************************************************/
-
- /**
- * Returns the system time.
- * Returns the number of milliseconds since the start of the system process.
- * Based on ANSI clock() routine.
- * \return The number of milliseconds.
- */
- GHOST_TUns64 getMilliSeconds() const;
-
- /***************************************************************************************
- * Display/window management functionality
- ***************************************************************************************/
-
- /**
- * Returns the number of displays on this system.
- * \return The number of displays.
- */
- GHOST_TUns8 getNumDisplays() const;
-
- /**
- * Returns the dimensions of the main display on this system.
- * \return The dimension of the main display.
- */
- void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
-
- /** Returns the combine dimensions of all monitors.
- * \return The dimension of the workspace.
- */
- void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
-
- /**
- * Create a new window.
- * The new window is added to the list of windows managed.
- * Never explicitly delete the window, use disposeWindow() instead.
- * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
- * \param left The coordinate of the left edge of the window.
- * \param top The coordinate of the top edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state of the window when opened.
- * \param type The type of drawing context installed in this window.
- * \param glSettings: Misc OpenGL settings.
- * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
- * \param parentWindow Parent (embedder) window
- * \return The new window (or 0 if creation failed).
- */
- GHOST_IWindow *createWindow(
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive = false,
- const GHOST_TEmbedderWindowID parentWindow = 0
- );
-
- /**
- * Create a new offscreen context.
- * Never explicitly delete the context, use disposeContext() instead.
- * \return The new context (or 0 if creation failed).
- */
- GHOST_IContext *
- createOffscreenContext(
- );
-
- /**
- * Dispose of a context.
- * \param context Pointer to the context to be disposed.
- * \return Indication of success.
- */
- GHOST_TSuccess
- disposeContext(
- GHOST_IContext *context
- );
-
- /***************************************************************************************
- * Event management functionality
- ***************************************************************************************/
-
- /**
- * Gets events from the system and stores them in the queue.
- * \param waitForEvent Flag to wait for an event (or return immediately).
- * \return Indication of the presence of events.
- */
- bool processEvents(bool waitForEvent);
-
- /**
- * Handle User request to quit, from Menu bar Quit, and Cmd+Q
- * Display alert panel if changes performed since last save
- */
- GHOST_TUns8 handleQuitRequest();
-
- /**
- * Handle Cocoa openFile event
- * Display confirmation request panel if changes performed since last save
- */
- bool handleOpenDocumentRequest(void *filepathStr);
-
- /**
- * Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass
- * \param eventType The type of drag'n'drop event
- * \param draggedObjectType The type object concerned (currently array of file names, string, TIFF image)
- * \param mouseX x mouse coordinate (in cocoa base window coordinates)
- * \param mouseY y mouse coordinate
- * \param window The window on which the event occurred
- * \return Indication whether the event was handled.
- */
- GHOST_TSuccess handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType,
- GHOST_WindowCocoa *window, int mouseX, int mouseY, void *data);
-
- /***************************************************************************************
- * Cursor management functionality
- ***************************************************************************************/
-
- /**
- * Returns the current location of the cursor (location in screen coordinates)
- * \param x The x-coordinate of the cursor.
- * \param y The y-coordinate of the cursor.
- * \return Indication of success.
- */
- GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
-
- /**
- * Updates the location of the cursor (location in screen coordinates).
- * \param x The x-coordinate of the cursor.
- * \param y The y-coordinate of the cursor.
- * \return Indication of success.
- */
- GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
-
- /***************************************************************************************
- * Access to mouse button and keyboard states.
- ***************************************************************************************/
-
- /**
- * Returns the state of all modifier keys.
- * \param keys The state of all modifier keys (true == pressed).
- * \return Indication of success.
- */
- GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
-
- /**
- * Returns the state of the mouse buttons (ouside the message queue).
- * \param buttons The state of the buttons.
- * \return Indication of success.
- */
- GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
-
- /**
- * Returns Clipboard data
- * \param selection Indicate which buffer to return
- * \return Returns the selected buffer
- */
- GHOST_TUns8 *getClipboard(bool selection) const;
-
- /**
- * Puts buffer to system clipboard
- * \param buffer The buffer to be copied
- * \param selection Indicates which buffer to copy too, only used on X11
- */
- void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
-
- /**
- * Handles a window event. Called by GHOST_WindowCocoa window delegate
- * \param eventType The type of window event
- * \param window The window on which the event occurred
- * \return Indication whether the event was handled.
- */
- GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa *window);
-
- /**
- * Handles the Cocoa event telling the application has become active (again)
- * \return Indication whether the event was handled.
- */
- GHOST_TSuccess handleApplicationBecomeActiveEvent();
-
- /**
- * External objects should call this when they send an event outside processEvents.
- */
- void notifyExternalEventProcessed();
-
- /**
- * \see GHOST_ISystem
- */
- int toggleConsole(int action) {
- return 0;
- }
-
- /**
- * Handles a tablet event.
- * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
- * \param eventType The type of the event.
- * It needs to be passed separately as it can be either directly in the event type,
- * or as a subtype if combined with a mouse button event.
- * \return Indication whether the event was handled.
- */
- GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType);
- bool handleTabletEvent(void *eventPtr);
-
- /**
- * Handles a mouse event.
- * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
- * \return Indication whether the event was handled.
- */
- GHOST_TSuccess handleMouseEvent(void *eventPtr);
-
- /**
- * Handles a key event.
- * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
- * \return Indication whether the event was handled.
- */
- GHOST_TSuccess handleKeyEvent(void *eventPtr);
-
- /**
- * Informs if the system provides native dialogs (eg. confirm quit)
- */
- virtual bool supportsNativeDialogs(void);
-
-protected:
- /**
- * Initializes the system.
- * For now, it just registers the window class (WNDCLASS).
- * \return A success value.
- */
- GHOST_TSuccess init();
-
- /**
- * Performs the actual cursor position update (location in screen coordinates).
- * \param x The x-coordinate of the cursor.
- * \param y The y-coordinate of the cursor.
- * \return Indication of success.
- */
- GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
-
- /** Start time at initialization. */
- GHOST_TUns64 m_start_time;
-
- /** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */
- bool m_outsideLoopEventProcessed;
-
- /** Raised window is not yet known by the window manager, so delay application become active event handling */
- bool m_needDelayedApplicationBecomeActiveEventProcessing;
-
- /** State of the modifiers. */
- GHOST_TUns32 m_modifierMask;
-
- /** Ignores window size messages (when window is dragged). */
- bool m_ignoreWindowSizedMessages;
-
- /** Temporarily ignore momentum scroll events */
- bool m_ignoreMomentumScroll;
- /** Is the scroll wheel event generated by a multitouch trackpad or mouse? */
- bool m_multiTouchScroll;
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_SystemCocoa();
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_SystemCocoa();
+
+ /***************************************************************************************
+ * Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * \return The number of milliseconds.
+ */
+ GHOST_TUns64 getMilliSeconds() const;
+
+ /***************************************************************************************
+ * Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the number of displays on this system.
+ * \return The number of displays.
+ */
+ GHOST_TUns8 getNumDisplays() const;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * \return The dimension of the main display.
+ */
+ void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
+
+ /** Returns the combine dimensions of all monitors.
+ * \return The dimension of the workspace.
+ */
+ void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * \param left The coordinate of the left edge of the window.
+ * \param top The coordinate of the top edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state of the window when opened.
+ * \param type The type of drawing context installed in this window.
+ * \param glSettings: Misc OpenGL settings.
+ * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
+ * \param parentWindow Parent (embedder) window
+ * \return The new window (or 0 if creation failed).
+ */
+ GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive = false,
+ const GHOST_TEmbedderWindowID parentWindow = 0);
+
+ /**
+ * Create a new offscreen context.
+ * Never explicitly delete the context, use disposeContext() instead.
+ * \return The new context (or 0 if creation failed).
+ */
+ GHOST_IContext *createOffscreenContext();
+
+ /**
+ * Dispose of a context.
+ * \param context Pointer to the context to be disposed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess disposeContext(GHOST_IContext *context);
+
+ /***************************************************************************************
+ * Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Gets events from the system and stores them in the queue.
+ * \param waitForEvent Flag to wait for an event (or return immediately).
+ * \return Indication of the presence of events.
+ */
+ bool processEvents(bool waitForEvent);
+
+ /**
+ * Handle User request to quit, from Menu bar Quit, and Cmd+Q
+ * Display alert panel if changes performed since last save
+ */
+ GHOST_TUns8 handleQuitRequest();
+
+ /**
+ * Handle Cocoa openFile event
+ * Display confirmation request panel if changes performed since last save
+ */
+ bool handleOpenDocumentRequest(void *filepathStr);
+
+ /**
+ * Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass
+ * \param eventType The type of drag'n'drop event
+ * \param draggedObjectType The type object concerned (currently array of file names, string, TIFF image)
+ * \param mouseX x mouse coordinate (in cocoa base window coordinates)
+ * \param mouseY y mouse coordinate
+ * \param window The window on which the event occurred
+ * \return Indication whether the event was handled.
+ */
+ GHOST_TSuccess handleDraggingEvent(GHOST_TEventType eventType,
+ GHOST_TDragnDropTypes draggedObjectType,
+ GHOST_WindowCocoa *window,
+ int mouseX,
+ int mouseY,
+ void *data);
+
+ /***************************************************************************************
+ * Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * \param x The x-coordinate of the cursor.
+ * \param y The y-coordinate of the cursor.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+
+ /**
+ * Updates the location of the cursor (location in screen coordinates).
+ * \param x The x-coordinate of the cursor.
+ * \param y The y-coordinate of the cursor.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
+
+ /***************************************************************************************
+ * Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of all modifier keys.
+ * \param keys The state of all modifier keys (true == pressed).
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * \param buttons The state of the buttons.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
+
+ /**
+ * Returns Clipboard data
+ * \param selection Indicate which buffer to return
+ * \return Returns the selected buffer
+ */
+ GHOST_TUns8 *getClipboard(bool selection) const;
+
+ /**
+ * Puts buffer to system clipboard
+ * \param buffer The buffer to be copied
+ * \param selection Indicates which buffer to copy too, only used on X11
+ */
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+
+ /**
+ * Handles a window event. Called by GHOST_WindowCocoa window delegate
+ * \param eventType The type of window event
+ * \param window The window on which the event occurred
+ * \return Indication whether the event was handled.
+ */
+ GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa *window);
+
+ /**
+ * Handles the Cocoa event telling the application has become active (again)
+ * \return Indication whether the event was handled.
+ */
+ GHOST_TSuccess handleApplicationBecomeActiveEvent();
+
+ /**
+ * External objects should call this when they send an event outside processEvents.
+ */
+ void notifyExternalEventProcessed();
+
+ /**
+ * \see GHOST_ISystem
+ */
+ int toggleConsole(int action)
+ {
+ return 0;
+ }
+
+ /**
+ * Handles a tablet event.
+ * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * \param eventType The type of the event.
+ * It needs to be passed separately as it can be either directly in the event type,
+ * or as a subtype if combined with a mouse button event.
+ * \return Indication whether the event was handled.
+ */
+ GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType);
+ bool handleTabletEvent(void *eventPtr);
+
+ /**
+ * Handles a mouse event.
+ * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * \return Indication whether the event was handled.
+ */
+ GHOST_TSuccess handleMouseEvent(void *eventPtr);
+
+ /**
+ * Handles a key event.
+ * \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * \return Indication whether the event was handled.
+ */
+ GHOST_TSuccess handleKeyEvent(void *eventPtr);
+
+ /**
+ * Informs if the system provides native dialogs (eg. confirm quit)
+ */
+ virtual bool supportsNativeDialogs(void);
+
+ protected:
+ /**
+ * Initializes the system.
+ * For now, it just registers the window class (WNDCLASS).
+ * \return A success value.
+ */
+ GHOST_TSuccess init();
+
+ /**
+ * Performs the actual cursor position update (location in screen coordinates).
+ * \param x The x-coordinate of the cursor.
+ * \param y The y-coordinate of the cursor.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
+
+ /** Start time at initialization. */
+ GHOST_TUns64 m_start_time;
+
+ /** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */
+ bool m_outsideLoopEventProcessed;
+
+ /** Raised window is not yet known by the window manager, so delay application become active event handling */
+ bool m_needDelayedApplicationBecomeActiveEventProcessing;
+
+ /** State of the modifiers. */
+ GHOST_TUns32 m_modifierMask;
+
+ /** Ignores window size messages (when window is dragged). */
+ bool m_ignoreWindowSizedMessages;
+
+ /** Temporarily ignore momentum scroll events */
+ bool m_ignoreMomentumScroll;
+ /** Is the scroll wheel event generated by a multitouch trackpad or mouse? */
+ bool m_multiTouchScroll;
};
-#endif // __GHOST_SYSTEMCOCOA_H__
+#endif // __GHOST_SYSTEMCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 8b270c1d972..4c9c7453f43 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -39,7 +39,7 @@
#endif
#ifdef WITH_INPUT_NDOF
- #include "GHOST_NDOFManagerCocoa.h"
+# include "GHOST_NDOFManagerCocoa.h"
#endif
#include "AssertMacros.h"
@@ -57,24 +57,24 @@
static GHOST_TButtonMask convertButton(int button)
{
- switch (button) {
- case 0:
- return GHOST_kButtonMaskLeft;
- case 1:
- return GHOST_kButtonMaskRight;
- case 2:
- return GHOST_kButtonMaskMiddle;
- case 3:
- return GHOST_kButtonMaskButton4;
- case 4:
- return GHOST_kButtonMaskButton5;
- case 5:
- return GHOST_kButtonMaskButton6;
- case 6:
- return GHOST_kButtonMaskButton7;
- default:
- return GHOST_kButtonMaskLeft;
- }
+ switch (button) {
+ case 0:
+ return GHOST_kButtonMaskLeft;
+ case 1:
+ return GHOST_kButtonMaskRight;
+ case 2:
+ return GHOST_kButtonMaskMiddle;
+ case 3:
+ return GHOST_kButtonMaskButton4;
+ case 4:
+ return GHOST_kButtonMaskButton5;
+ case 5:
+ return GHOST_kButtonMaskButton6;
+ case 6:
+ return GHOST_kButtonMaskButton7;
+ default:
+ return GHOST_kButtonMaskLeft;
+ }
}
/**
@@ -86,171 +86,253 @@ static GHOST_TButtonMask convertButton(int button)
*/
static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
{
- //printf("\nrecvchar %c 0x%x",recvChar,recvChar);
- switch (rawCode) {
- /*Physical keycodes not used due to map changes in int'l keyboards
- case kVK_ANSI_A: return GHOST_kKeyA;
- case kVK_ANSI_B: return GHOST_kKeyB;
- case kVK_ANSI_C: return GHOST_kKeyC;
- case kVK_ANSI_D: return GHOST_kKeyD;
- case kVK_ANSI_E: return GHOST_kKeyE;
- case kVK_ANSI_F: return GHOST_kKeyF;
- case kVK_ANSI_G: return GHOST_kKeyG;
- case kVK_ANSI_H: return GHOST_kKeyH;
- case kVK_ANSI_I: return GHOST_kKeyI;
- case kVK_ANSI_J: return GHOST_kKeyJ;
- case kVK_ANSI_K: return GHOST_kKeyK;
- case kVK_ANSI_L: return GHOST_kKeyL;
- case kVK_ANSI_M: return GHOST_kKeyM;
- case kVK_ANSI_N: return GHOST_kKeyN;
- case kVK_ANSI_O: return GHOST_kKeyO;
- case kVK_ANSI_P: return GHOST_kKeyP;
- case kVK_ANSI_Q: return GHOST_kKeyQ;
- case kVK_ANSI_R: return GHOST_kKeyR;
- case kVK_ANSI_S: return GHOST_kKeyS;
- case kVK_ANSI_T: return GHOST_kKeyT;
- case kVK_ANSI_U: return GHOST_kKeyU;
- case kVK_ANSI_V: return GHOST_kKeyV;
- case kVK_ANSI_W: return GHOST_kKeyW;
- case kVK_ANSI_X: return GHOST_kKeyX;
- case kVK_ANSI_Y: return GHOST_kKeyY;
- case kVK_ANSI_Z: return GHOST_kKeyZ;*/
-
- /* Numbers keys mapped to handle some int'l keyboard (e.g. French)*/
- case kVK_ISO_Section: return GHOST_kKeyUnknown;
- case kVK_ANSI_1: return GHOST_kKey1;
- case kVK_ANSI_2: return GHOST_kKey2;
- case kVK_ANSI_3: return GHOST_kKey3;
- case kVK_ANSI_4: return GHOST_kKey4;
- case kVK_ANSI_5: return GHOST_kKey5;
- case kVK_ANSI_6: return GHOST_kKey6;
- case kVK_ANSI_7: return GHOST_kKey7;
- case kVK_ANSI_8: return GHOST_kKey8;
- case kVK_ANSI_9: return GHOST_kKey9;
- case kVK_ANSI_0: return GHOST_kKey0;
-
- case kVK_ANSI_Keypad0: return GHOST_kKeyNumpad0;
- case kVK_ANSI_Keypad1: return GHOST_kKeyNumpad1;
- case kVK_ANSI_Keypad2: return GHOST_kKeyNumpad2;
- case kVK_ANSI_Keypad3: return GHOST_kKeyNumpad3;
- case kVK_ANSI_Keypad4: return GHOST_kKeyNumpad4;
- case kVK_ANSI_Keypad5: return GHOST_kKeyNumpad5;
- case kVK_ANSI_Keypad6: return GHOST_kKeyNumpad6;
- case kVK_ANSI_Keypad7: return GHOST_kKeyNumpad7;
- case kVK_ANSI_Keypad8: return GHOST_kKeyNumpad8;
- case kVK_ANSI_Keypad9: return GHOST_kKeyNumpad9;
- case kVK_ANSI_KeypadDecimal: return GHOST_kKeyNumpadPeriod;
- case kVK_ANSI_KeypadEnter: return GHOST_kKeyNumpadEnter;
- case kVK_ANSI_KeypadPlus: return GHOST_kKeyNumpadPlus;
- case kVK_ANSI_KeypadMinus: return GHOST_kKeyNumpadMinus;
- case kVK_ANSI_KeypadMultiply: return GHOST_kKeyNumpadAsterisk;
- case kVK_ANSI_KeypadDivide: return GHOST_kKeyNumpadSlash;
- case kVK_ANSI_KeypadClear: return GHOST_kKeyUnknown;
-
- case kVK_F1: return GHOST_kKeyF1;
- case kVK_F2: return GHOST_kKeyF2;
- case kVK_F3: return GHOST_kKeyF3;
- case kVK_F4: return GHOST_kKeyF4;
- case kVK_F5: return GHOST_kKeyF5;
- case kVK_F6: return GHOST_kKeyF6;
- case kVK_F7: return GHOST_kKeyF7;
- case kVK_F8: return GHOST_kKeyF8;
- case kVK_F9: return GHOST_kKeyF9;
- case kVK_F10: return GHOST_kKeyF10;
- case kVK_F11: return GHOST_kKeyF11;
- case kVK_F12: return GHOST_kKeyF12;
- case kVK_F13: return GHOST_kKeyF13;
- case kVK_F14: return GHOST_kKeyF14;
- case kVK_F15: return GHOST_kKeyF15;
- case kVK_F16: return GHOST_kKeyF16;
- case kVK_F17: return GHOST_kKeyF17;
- case kVK_F18: return GHOST_kKeyF18;
- case kVK_F19: return GHOST_kKeyF19;
- case kVK_F20: return GHOST_kKeyF20;
-
- case kVK_UpArrow: return GHOST_kKeyUpArrow;
- case kVK_DownArrow: return GHOST_kKeyDownArrow;
- case kVK_LeftArrow: return GHOST_kKeyLeftArrow;
- case kVK_RightArrow: return GHOST_kKeyRightArrow;
-
- case kVK_Return: return GHOST_kKeyEnter;
- case kVK_Delete: return GHOST_kKeyBackSpace;
- case kVK_ForwardDelete: return GHOST_kKeyDelete;
- case kVK_Escape: return GHOST_kKeyEsc;
- case kVK_Tab: return GHOST_kKeyTab;
- case kVK_Space: return GHOST_kKeySpace;
-
- case kVK_Home: return GHOST_kKeyHome;
- case kVK_End: return GHOST_kKeyEnd;
- case kVK_PageUp: return GHOST_kKeyUpPage;
- case kVK_PageDown: return GHOST_kKeyDownPage;
-
- /*case kVK_ANSI_Minus: return GHOST_kKeyMinus;
- case kVK_ANSI_Equal: return GHOST_kKeyEqual;
- case kVK_ANSI_Comma: return GHOST_kKeyComma;
- case kVK_ANSI_Period: return GHOST_kKeyPeriod;
- case kVK_ANSI_Slash: return GHOST_kKeySlash;
- case kVK_ANSI_Semicolon: return GHOST_kKeySemicolon;
- case kVK_ANSI_Quote: return GHOST_kKeyQuote;
- case kVK_ANSI_Backslash: return GHOST_kKeyBackslash;
- case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket;
- case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket;
- case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave;*/
-
- case kVK_VolumeUp:
- case kVK_VolumeDown:
- case kVK_Mute:
- return GHOST_kKeyUnknown;
-
- default:
- {
- /* alphanumerical or punctuation key that is remappable in int'l keyboards */
- if ((recvChar >= 'A') && (recvChar <= 'Z')) {
- return (GHOST_TKey) (recvChar - 'A' + GHOST_kKeyA);
- }
- else if ((recvChar >= 'a') && (recvChar <= 'z')) {
- return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA);
- }
- else {
- /* Leopard and Snow Leopard 64bit compatible API*/
- CFDataRef uchrHandle; /*the keyboard layout*/
- TISInputSourceRef kbdTISHandle;
-
- kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource();
- uchrHandle = (CFDataRef)TISGetInputSourceProperty(kbdTISHandle,kTISPropertyUnicodeKeyLayoutData);
- CFRelease(kbdTISHandle);
-
- /*get actual character value of the "remappable" keys in int'l keyboards,
- if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger),
- then fallback on using the received charactersIgnoringModifiers */
- if (uchrHandle) {
- UInt32 deadKeyState=0;
- UniCharCount actualStrLength=0;
-
- UCKeyTranslate((UCKeyboardLayout*)CFDataGetBytePtr(uchrHandle), rawCode, keyAction, 0,
- LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, 1, &actualStrLength, &recvChar);
- }
-
- switch (recvChar) {
- case '-': return GHOST_kKeyMinus;
- case '+': return GHOST_kKeyPlus;
- case '=': return GHOST_kKeyEqual;
- case ',': return GHOST_kKeyComma;
- case '.': return GHOST_kKeyPeriod;
- case '/': return GHOST_kKeySlash;
- case ';': return GHOST_kKeySemicolon;
- case '\'': return GHOST_kKeyQuote;
- case '\\': return GHOST_kKeyBackslash;
- case '[': return GHOST_kKeyLeftBracket;
- case ']': return GHOST_kKeyRightBracket;
- case '`': return GHOST_kKeyAccentGrave;
- default:
- return GHOST_kKeyUnknown;
- }
- }
- }
- }
- return GHOST_kKeyUnknown;
+ //printf("\nrecvchar %c 0x%x",recvChar,recvChar);
+ switch (rawCode) {
+ /*Physical keycodes not used due to map changes in int'l keyboards
+ case kVK_ANSI_A: return GHOST_kKeyA;
+ case kVK_ANSI_B: return GHOST_kKeyB;
+ case kVK_ANSI_C: return GHOST_kKeyC;
+ case kVK_ANSI_D: return GHOST_kKeyD;
+ case kVK_ANSI_E: return GHOST_kKeyE;
+ case kVK_ANSI_F: return GHOST_kKeyF;
+ case kVK_ANSI_G: return GHOST_kKeyG;
+ case kVK_ANSI_H: return GHOST_kKeyH;
+ case kVK_ANSI_I: return GHOST_kKeyI;
+ case kVK_ANSI_J: return GHOST_kKeyJ;
+ case kVK_ANSI_K: return GHOST_kKeyK;
+ case kVK_ANSI_L: return GHOST_kKeyL;
+ case kVK_ANSI_M: return GHOST_kKeyM;
+ case kVK_ANSI_N: return GHOST_kKeyN;
+ case kVK_ANSI_O: return GHOST_kKeyO;
+ case kVK_ANSI_P: return GHOST_kKeyP;
+ case kVK_ANSI_Q: return GHOST_kKeyQ;
+ case kVK_ANSI_R: return GHOST_kKeyR;
+ case kVK_ANSI_S: return GHOST_kKeyS;
+ case kVK_ANSI_T: return GHOST_kKeyT;
+ case kVK_ANSI_U: return GHOST_kKeyU;
+ case kVK_ANSI_V: return GHOST_kKeyV;
+ case kVK_ANSI_W: return GHOST_kKeyW;
+ case kVK_ANSI_X: return GHOST_kKeyX;
+ case kVK_ANSI_Y: return GHOST_kKeyY;
+ case kVK_ANSI_Z: return GHOST_kKeyZ;*/
+
+ /* Numbers keys mapped to handle some int'l keyboard (e.g. French)*/
+ case kVK_ISO_Section:
+ return GHOST_kKeyUnknown;
+ case kVK_ANSI_1:
+ return GHOST_kKey1;
+ case kVK_ANSI_2:
+ return GHOST_kKey2;
+ case kVK_ANSI_3:
+ return GHOST_kKey3;
+ case kVK_ANSI_4:
+ return GHOST_kKey4;
+ case kVK_ANSI_5:
+ return GHOST_kKey5;
+ case kVK_ANSI_6:
+ return GHOST_kKey6;
+ case kVK_ANSI_7:
+ return GHOST_kKey7;
+ case kVK_ANSI_8:
+ return GHOST_kKey8;
+ case kVK_ANSI_9:
+ return GHOST_kKey9;
+ case kVK_ANSI_0:
+ return GHOST_kKey0;
+
+ case kVK_ANSI_Keypad0:
+ return GHOST_kKeyNumpad0;
+ case kVK_ANSI_Keypad1:
+ return GHOST_kKeyNumpad1;
+ case kVK_ANSI_Keypad2:
+ return GHOST_kKeyNumpad2;
+ case kVK_ANSI_Keypad3:
+ return GHOST_kKeyNumpad3;
+ case kVK_ANSI_Keypad4:
+ return GHOST_kKeyNumpad4;
+ case kVK_ANSI_Keypad5:
+ return GHOST_kKeyNumpad5;
+ case kVK_ANSI_Keypad6:
+ return GHOST_kKeyNumpad6;
+ case kVK_ANSI_Keypad7:
+ return GHOST_kKeyNumpad7;
+ case kVK_ANSI_Keypad8:
+ return GHOST_kKeyNumpad8;
+ case kVK_ANSI_Keypad9:
+ return GHOST_kKeyNumpad9;
+ case kVK_ANSI_KeypadDecimal:
+ return GHOST_kKeyNumpadPeriod;
+ case kVK_ANSI_KeypadEnter:
+ return GHOST_kKeyNumpadEnter;
+ case kVK_ANSI_KeypadPlus:
+ return GHOST_kKeyNumpadPlus;
+ case kVK_ANSI_KeypadMinus:
+ return GHOST_kKeyNumpadMinus;
+ case kVK_ANSI_KeypadMultiply:
+ return GHOST_kKeyNumpadAsterisk;
+ case kVK_ANSI_KeypadDivide:
+ return GHOST_kKeyNumpadSlash;
+ case kVK_ANSI_KeypadClear:
+ return GHOST_kKeyUnknown;
+
+ case kVK_F1:
+ return GHOST_kKeyF1;
+ case kVK_F2:
+ return GHOST_kKeyF2;
+ case kVK_F3:
+ return GHOST_kKeyF3;
+ case kVK_F4:
+ return GHOST_kKeyF4;
+ case kVK_F5:
+ return GHOST_kKeyF5;
+ case kVK_F6:
+ return GHOST_kKeyF6;
+ case kVK_F7:
+ return GHOST_kKeyF7;
+ case kVK_F8:
+ return GHOST_kKeyF8;
+ case kVK_F9:
+ return GHOST_kKeyF9;
+ case kVK_F10:
+ return GHOST_kKeyF10;
+ case kVK_F11:
+ return GHOST_kKeyF11;
+ case kVK_F12:
+ return GHOST_kKeyF12;
+ case kVK_F13:
+ return GHOST_kKeyF13;
+ case kVK_F14:
+ return GHOST_kKeyF14;
+ case kVK_F15:
+ return GHOST_kKeyF15;
+ case kVK_F16:
+ return GHOST_kKeyF16;
+ case kVK_F17:
+ return GHOST_kKeyF17;
+ case kVK_F18:
+ return GHOST_kKeyF18;
+ case kVK_F19:
+ return GHOST_kKeyF19;
+ case kVK_F20:
+ return GHOST_kKeyF20;
+
+ case kVK_UpArrow:
+ return GHOST_kKeyUpArrow;
+ case kVK_DownArrow:
+ return GHOST_kKeyDownArrow;
+ case kVK_LeftArrow:
+ return GHOST_kKeyLeftArrow;
+ case kVK_RightArrow:
+ return GHOST_kKeyRightArrow;
+
+ case kVK_Return:
+ return GHOST_kKeyEnter;
+ case kVK_Delete:
+ return GHOST_kKeyBackSpace;
+ case kVK_ForwardDelete:
+ return GHOST_kKeyDelete;
+ case kVK_Escape:
+ return GHOST_kKeyEsc;
+ case kVK_Tab:
+ return GHOST_kKeyTab;
+ case kVK_Space:
+ return GHOST_kKeySpace;
+
+ case kVK_Home:
+ return GHOST_kKeyHome;
+ case kVK_End:
+ return GHOST_kKeyEnd;
+ case kVK_PageUp:
+ return GHOST_kKeyUpPage;
+ case kVK_PageDown:
+ return GHOST_kKeyDownPage;
+
+ /*case kVK_ANSI_Minus: return GHOST_kKeyMinus;
+ case kVK_ANSI_Equal: return GHOST_kKeyEqual;
+ case kVK_ANSI_Comma: return GHOST_kKeyComma;
+ case kVK_ANSI_Period: return GHOST_kKeyPeriod;
+ case kVK_ANSI_Slash: return GHOST_kKeySlash;
+ case kVK_ANSI_Semicolon: return GHOST_kKeySemicolon;
+ case kVK_ANSI_Quote: return GHOST_kKeyQuote;
+ case kVK_ANSI_Backslash: return GHOST_kKeyBackslash;
+ case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket;
+ case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket;
+ case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave;*/
+
+ case kVK_VolumeUp:
+ case kVK_VolumeDown:
+ case kVK_Mute:
+ return GHOST_kKeyUnknown;
+
+ default: {
+ /* alphanumerical or punctuation key that is remappable in int'l keyboards */
+ if ((recvChar >= 'A') && (recvChar <= 'Z')) {
+ return (GHOST_TKey)(recvChar - 'A' + GHOST_kKeyA);
+ }
+ else if ((recvChar >= 'a') && (recvChar <= 'z')) {
+ return (GHOST_TKey)(recvChar - 'a' + GHOST_kKeyA);
+ }
+ else {
+ /* Leopard and Snow Leopard 64bit compatible API*/
+ CFDataRef uchrHandle; /*the keyboard layout*/
+ TISInputSourceRef kbdTISHandle;
+
+ kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource();
+ uchrHandle = (CFDataRef)TISGetInputSourceProperty(kbdTISHandle,
+ kTISPropertyUnicodeKeyLayoutData);
+ CFRelease(kbdTISHandle);
+
+ /*get actual character value of the "remappable" keys in int'l keyboards,
+ if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger),
+ then fallback on using the received charactersIgnoringModifiers */
+ if (uchrHandle) {
+ UInt32 deadKeyState = 0;
+ UniCharCount actualStrLength = 0;
+
+ UCKeyTranslate((UCKeyboardLayout *)CFDataGetBytePtr(uchrHandle),
+ rawCode,
+ keyAction,
+ 0,
+ LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysBit,
+ &deadKeyState,
+ 1,
+ &actualStrLength,
+ &recvChar);
+ }
+
+ switch (recvChar) {
+ case '-':
+ return GHOST_kKeyMinus;
+ case '+':
+ return GHOST_kKeyPlus;
+ case '=':
+ return GHOST_kKeyEqual;
+ case ',':
+ return GHOST_kKeyComma;
+ case '.':
+ return GHOST_kKeyPeriod;
+ case '/':
+ return GHOST_kKeySlash;
+ case ';':
+ return GHOST_kKeySemicolon;
+ case '\'':
+ return GHOST_kKeyQuote;
+ case '\\':
+ return GHOST_kKeyBackslash;
+ case '[':
+ return GHOST_kKeyLeftBracket;
+ case ']':
+ return GHOST_kKeyRightBracket;
+ case '`':
+ return GHOST_kKeyAccentGrave;
+ default:
+ return GHOST_kKeyUnknown;
+ }
+ }
+ }
+ }
+ return GHOST_kKeyUnknown;
}
#pragma mark Utility functions
@@ -262,14 +344,14 @@ static char g_firstFileBuf[512];
//TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true
extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
{
- if (g_hasFirstFile) {
- strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
- buf[FIRSTFILEBUFLG - 1] = '\0';
- return 1;
- }
- else {
- return 0;
- }
+ if (g_hasFirstFile) {
+ strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
+ buf[FIRSTFILEBUFLG - 1] = '\0';
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
#pragma mark Cocoa objects
@@ -278,9 +360,10 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
* CocoaAppDelegate
* ObjC object to capture applicationShouldTerminate, and send quit event
*/
-@interface CocoaAppDelegate : NSObject <NSApplicationDelegate> {
+@interface CocoaAppDelegate : NSObject <NSApplicationDelegate>
+{
- GHOST_SystemCocoa *systemCocoa;
+ GHOST_SystemCocoa *systemCocoa;
}
- (id)init;
@@ -292,57 +375,59 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
- (void)applicationWillTerminate:(NSNotification *)aNotification;
- (void)applicationWillBecomeActive:(NSNotification *)aNotification;
- (void)toggleFullScreen:(NSNotification *)notification;
-- (void)windowWillClose:(NSNotification*)notification;
+- (void)windowWillClose:(NSNotification *)notification;
@end
@implementation CocoaAppDelegate : NSObject
-- (id)init {
- self = [super init];
- if (self) {
- NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
- [center addObserver:self
- selector:@selector(windowWillClose:)
- name:NSWindowWillCloseNotification
- object:nil];
- }
- return self;
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserver:self
+ selector:@selector(windowWillClose:)
+ name:NSWindowWillCloseNotification
+ object:nil];
+ }
+ return self;
}
-- (void)dealloc {
- NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
- [center removeObserver:self name:NSWindowWillCloseNotification object:nil];
- [super dealloc];
+- (void)dealloc
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center removeObserver:self name:NSWindowWillCloseNotification object:nil];
+ [super dealloc];
}
--(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa
+- (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa
{
- systemCocoa = sysCocoa;
+ systemCocoa = sysCocoa;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
- if (systemCocoa->m_windowFocus) {
- // Raise application to front, convenient when starting from the terminal
- // and important for launching the animation player. we call this after the
- // application finishes launching, as doing it earlier can make us end up
- // with a frontmost window but an inactive application.
- [NSApp activateIgnoringOtherApps:YES];
- }
+ if (systemCocoa->m_windowFocus) {
+ // Raise application to front, convenient when starting from the terminal
+ // and important for launching the animation player. we call this after the
+ // application finishes launching, as doing it earlier can make us end up
+ // with a frontmost window but an inactive application.
+ [NSApp activateIgnoringOtherApps:YES];
+ }
}
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
- return systemCocoa->handleOpenDocumentRequest(filename);
+ return systemCocoa->handleOpenDocumentRequest(filename);
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
- //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be canceled
- //Note that Cmd+Q is already handled by keyhandler
- if (systemCocoa->handleQuitRequest() == GHOST_kExitNow)
- return NSTerminateCancel;//NSTerminateNow;
- else
- return NSTerminateCancel;
+ //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be canceled
+ //Note that Cmd+Q is already handled by keyhandler
+ if (systemCocoa->handleQuitRequest() == GHOST_kExitNow)
+ return NSTerminateCancel; //NSTerminateNow;
+ else
+ return NSTerminateCancel;
}
// To avoid canceling a log off process, we must use Cocoa termination process
@@ -350,13 +435,13 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
// So WM_exit needs to be called directly, as the event loop will never run before termination
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
- /*G.is_break = FALSE; //Let Cocoa perform the termination at the end
- WM_exit(C);*/
+ /*G.is_break = FALSE; //Let Cocoa perform the termination at the end
+ WM_exit(C);*/
}
- (void)applicationWillBecomeActive:(NSNotification *)aNotification
{
- systemCocoa->handleApplicationBecomeActiveEvent();
+ systemCocoa->handleApplicationBecomeActiveEvent();
}
- (void)toggleFullScreen:(NSNotification *)notification
@@ -377,273 +462,294 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
// key window from here if the closing one is not in the orderedWindows. This
// saves lack of key windows when closing "About", but does not interfere with
// Blender's window manager when closing Blender's windows.
-- (void)windowWillClose:(NSNotification*)notification {
- NSWindow* closing_window = (NSWindow*)[notification object];
- NSInteger index = [[NSApp orderedWindows] indexOfObject:closing_window];
- if (index != NSNotFound) {
- return;
- }
- // Find first suitable window from the current space.
- for (NSWindow* current_window in [NSApp orderedWindows]) {
- if (current_window == closing_window) {
- continue;
- }
- if ([current_window isOnActiveSpace] &&
- [current_window canBecomeKeyWindow])
- {
- [current_window makeKeyAndOrderFront:nil];
- return;
- }
- }
- // If that didn't find any windows, we try to find any suitable window of
- // the application.
- for (NSNumber* window_number in [NSWindow windowNumbersWithOptions:0]) {
- NSWindow* current_window =
- [NSApp windowWithWindowNumber:[window_number integerValue]];
- if (current_window == closing_window) {
- continue;
- }
- if ([current_window canBecomeKeyWindow]) {
- [current_window makeKeyAndOrderFront:nil];
- return;
- }
- }
+- (void)windowWillClose:(NSNotification *)notification
+{
+ NSWindow *closing_window = (NSWindow *)[notification object];
+ NSInteger index = [[NSApp orderedWindows] indexOfObject:closing_window];
+ if (index != NSNotFound) {
+ return;
+ }
+ // Find first suitable window from the current space.
+ for (NSWindow *current_window in [NSApp orderedWindows]) {
+ if (current_window == closing_window) {
+ continue;
+ }
+ if ([current_window isOnActiveSpace] && [current_window canBecomeKeyWindow]) {
+ [current_window makeKeyAndOrderFront:nil];
+ return;
+ }
+ }
+ // If that didn't find any windows, we try to find any suitable window of
+ // the application.
+ for (NSNumber *window_number in [NSWindow windowNumbersWithOptions:0]) {
+ NSWindow *current_window = [NSApp windowWithWindowNumber:[window_number integerValue]];
+ if (current_window == closing_window) {
+ continue;
+ }
+ if ([current_window canBecomeKeyWindow]) {
+ [current_window makeKeyAndOrderFront:nil];
+ return;
+ }
+ }
}
@end
-
#pragma mark initialization/finalization
GHOST_SystemCocoa::GHOST_SystemCocoa()
{
- int mib[2];
- struct timeval boottime;
- size_t len;
- char *rstring = NULL;
-
- m_modifierMask =0;
- m_outsideLoopEventProcessed = false;
- m_needDelayedApplicationBecomeActiveEventProcessing = false;
- m_displayManager = new GHOST_DisplayManagerCocoa ();
- GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
- m_displayManager->initialize();
-
- //NSEvent timeStamp is given in system uptime, state start date is boot time
- mib[0] = CTL_KERN;
- mib[1] = KERN_BOOTTIME;
- len = sizeof(struct timeval);
-
- sysctl(mib, 2, &boottime, &len, NULL, 0);
- m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
-
- //Detect multitouch trackpad
- mib[0] = CTL_HW;
- mib[1] = HW_MODEL;
- sysctl( mib, 2, NULL, &len, NULL, 0 );
- rstring = (char*)malloc( len );
- sysctl( mib, 2, rstring, &len, NULL, 0 );
-
- free( rstring );
- rstring = NULL;
-
- m_ignoreWindowSizedMessages = false;
- m_ignoreMomentumScroll = false;
- m_multiTouchScroll = false;
+ int mib[2];
+ struct timeval boottime;
+ size_t len;
+ char *rstring = NULL;
+
+ m_modifierMask = 0;
+ m_outsideLoopEventProcessed = false;
+ m_needDelayedApplicationBecomeActiveEventProcessing = false;
+ m_displayManager = new GHOST_DisplayManagerCocoa();
+ GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
+ m_displayManager->initialize();
+
+ //NSEvent timeStamp is given in system uptime, state start date is boot time
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTTIME;
+ len = sizeof(struct timeval);
+
+ sysctl(mib, 2, &boottime, &len, NULL, 0);
+ m_start_time = ((boottime.tv_sec * 1000) + (boottime.tv_usec / 1000));
+
+ //Detect multitouch trackpad
+ mib[0] = CTL_HW;
+ mib[1] = HW_MODEL;
+ sysctl(mib, 2, NULL, &len, NULL, 0);
+ rstring = (char *)malloc(len);
+ sysctl(mib, 2, rstring, &len, NULL, 0);
+
+ free(rstring);
+ rstring = NULL;
+
+ m_ignoreWindowSizedMessages = false;
+ m_ignoreMomentumScroll = false;
+ m_multiTouchScroll = false;
}
GHOST_SystemCocoa::~GHOST_SystemCocoa()
{
}
-
GHOST_TSuccess GHOST_SystemCocoa::init()
{
- GHOST_TSuccess success = GHOST_System::init();
- if (success) {
+ GHOST_TSuccess success = GHOST_System::init();
+ if (success) {
#ifdef WITH_INPUT_NDOF
- m_ndofManager = new GHOST_NDOFManagerCocoa(*this);
+ m_ndofManager = new GHOST_NDOFManagerCocoa(*this);
#endif
- //ProcessSerialNumber psn;
+ //ProcessSerialNumber psn;
- //Carbon stuff to move window & menu to foreground
- /*if (!GetCurrentProcess(&psn)) {
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- SetFrontProcess(&psn);
- }*/
+ //Carbon stuff to move window & menu to foreground
+ /*if (!GetCurrentProcess(&psn)) {
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess(&psn);
+ }*/
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [NSApplication sharedApplication]; // initializes NSApp
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [NSApplication sharedApplication]; // initializes NSApp
- if ([NSApp mainMenu] == nil) {
- NSMenu *mainMenubar = [[NSMenu alloc] init];
- NSMenuItem *menuItem;
- NSMenu *windowMenu;
- NSMenu *appMenu;
+ if ([NSApp mainMenu] == nil) {
+ NSMenu *mainMenubar = [[NSMenu alloc] init];
+ NSMenuItem *menuItem;
+ NSMenu *windowMenu;
+ NSMenu *appMenu;
- //Create the application menu
- appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];
+ //Create the application menu
+ appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];
- [appMenu addItemWithTitle:@"About Blender" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
- [appMenu addItem:[NSMenuItem separatorItem]];
+ [appMenu addItemWithTitle:@"About Blender"
+ action:@selector(orderFrontStandardAboutPanel:)
+ keyEquivalent:@""];
+ [appMenu addItem:[NSMenuItem separatorItem]];
- menuItem = [appMenu addItemWithTitle:@"Hide Blender" action:@selector(hide:) keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
+ menuItem = [appMenu addItemWithTitle:@"Hide Blender"
+ action:@selector(hide:)
+ keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
- menuItem = [appMenu addItemWithTitle:@"Hide others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
+ menuItem = [appMenu addItemWithTitle:@"Hide others"
+ action:@selector(hideOtherApplications:)
+ keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
- [appMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+ [appMenu addItemWithTitle:@"Show All"
+ action:@selector(unhideAllApplications:)
+ keyEquivalent:@""];
- menuItem = [appMenu addItemWithTitle:@"Quit Blender" action:@selector(terminate:) keyEquivalent:@"q"];
- [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
+ menuItem = [appMenu addItemWithTitle:@"Quit Blender"
+ action:@selector(terminate:)
+ keyEquivalent:@"q"];
+ [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
- menuItem = [[NSMenuItem alloc] init];
- [menuItem setSubmenu:appMenu];
+ menuItem = [[NSMenuItem alloc] init];
+ [menuItem setSubmenu:appMenu];
- [mainMenubar addItem:menuItem];
- [menuItem release];
- [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; //Needed for 10.5
- [appMenu release];
+ [mainMenubar addItem:menuItem];
+ [menuItem release];
+ [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; //Needed for 10.5
+ [appMenu release];
- //Create the window menu
- windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+ //Create the window menu
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
- menuItem = [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
- [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
+ menuItem = [windowMenu addItemWithTitle:@"Minimize"
+ action:@selector(performMiniaturize:)
+ keyEquivalent:@"m"];
+ [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
- [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
+ [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
- menuItem = [windowMenu addItemWithTitle:@"Enter Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f" ];
- [menuItem setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask];
+ menuItem = [windowMenu addItemWithTitle:@"Enter Full Screen"
+ action:@selector(toggleFullScreen:)
+ keyEquivalent:@"f"];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask];
- menuItem = [windowMenu addItemWithTitle:@"Close" action:@selector(performClose:) keyEquivalent:@"w"];
- [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
+ menuItem = [windowMenu addItemWithTitle:@"Close"
+ action:@selector(performClose:)
+ keyEquivalent:@"w"];
+ [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
- menuItem = [[NSMenuItem alloc] init];
- [menuItem setSubmenu:windowMenu];
+ menuItem = [[NSMenuItem alloc] init];
+ [menuItem setSubmenu:windowMenu];
- [mainMenubar addItem:menuItem];
- [menuItem release];
+ [mainMenubar addItem:menuItem];
+ [menuItem release];
- [NSApp setMainMenu:mainMenubar];
- [NSApp setWindowsMenu:windowMenu];
- [windowMenu release];
- }
+ [NSApp setMainMenu:mainMenubar];
+ [NSApp setWindowsMenu:windowMenu];
+ [windowMenu release];
+ }
- if ([NSApp delegate] == nil) {
- CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];
- [appDelegate setSystemCocoa:this];
- [NSApp setDelegate:appDelegate];
- }
+ if ([NSApp delegate] == nil) {
+ CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];
+ [appDelegate setSystemCocoa:this];
+ [NSApp setDelegate:appDelegate];
+ }
- [NSApp finishLaunching];
+ [NSApp finishLaunching];
- [pool drain];
- }
- return success;
+ [pool drain];
+ }
+ return success;
}
-
#pragma mark window management
GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
{
- //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime])
- struct timeval currentTime;
+ //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime])
+ struct timeval currentTime;
- gettimeofday(&currentTime, NULL);
+ gettimeofday(&currentTime, NULL);
- //Return timestamp of system uptime
+ //Return timestamp of system uptime
- return ((currentTime.tv_sec*1000)+(currentTime.tv_usec/1000)-m_start_time);
+ return ((currentTime.tv_sec * 1000) + (currentTime.tv_usec / 1000) - m_start_time);
}
-
GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const
{
- //Note that OS X supports monitor hot plug
- // We do not support multiple monitors at the moment
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ //Note that OS X supports monitor hot plug
+ // We do not support multiple monitors at the moment
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_TUns8 count = [[NSScreen screens] count];
+ GHOST_TUns8 count = [[NSScreen screens] count];
- [pool drain];
- return count;
+ [pool drain];
+ return count;
}
-
-void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- //Get visible frame, that is frame excluding dock and top menu bar
- NSRect frame = [[NSScreen mainScreen] visibleFrame];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ //Get visible frame, that is frame excluding dock and top menu bar
+ NSRect frame = [[NSScreen mainScreen] visibleFrame];
- //Returns max window contents (excluding title bar...)
- NSRect contentRect = [NSWindow contentRectForFrameRect:frame
- styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
+ //Returns max window contents (excluding title bar...)
+ NSRect contentRect = [NSWindow
+ contentRectForFrameRect:frame
+ styleMask:(NSTitledWindowMask | NSClosableWindowMask |
+ NSMiniaturizableWindowMask)];
- width = contentRect.size.width;
- height = contentRect.size.height;
+ width = contentRect.size.width;
+ height = contentRect.size.height;
- [pool drain];
+ [pool drain];
}
-void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- /* TODO! */
- getMainDisplayDimensions(width, height);
+ /* TODO! */
+ getMainDisplayDimensions(width, height);
}
-GHOST_IWindow* GHOST_SystemCocoa::createWindow(
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive,
- const GHOST_TEmbedderWindowID parentWindow
-)
+GHOST_IWindow *GHOST_SystemCocoa::createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive,
+ const GHOST_TEmbedderWindowID parentWindow)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_IWindow* window = NULL;
-
- //Get the available rect for including window contents
- NSRect frame = [[NSScreen mainScreen] visibleFrame];
- NSRect contentRect = [NSWindow contentRectForFrameRect:frame
- styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
-
- GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top;
-
- //Ensures window top left is inside this available rect
- left = left > contentRect.origin.x ? left : contentRect.origin.x;
- // Add contentRect.origin.y to respect docksize
- bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y;
-
- window = new GHOST_WindowCocoa(this, title, left, bottom, width, height, state, type, glSettings.flags & GHOST_glStereoVisual, glSettings.numOfAASamples, glSettings.flags & GHOST_glDebugContext);
-
- if (window->getValid()) {
- // Store the pointer to the window
- GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
- m_windowManager->addWindow(window);
- m_windowManager->setActiveWindow(window);
- //Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation)
- pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
- pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
- }
- else {
- GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
- delete window;
- window = NULL;
- }
-
- [pool drain];
- return window;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GHOST_IWindow *window = NULL;
+
+ //Get the available rect for including window contents
+ NSRect frame = [[NSScreen mainScreen] visibleFrame];
+ NSRect contentRect = [NSWindow
+ contentRectForFrameRect:frame
+ styleMask:(NSTitledWindowMask | NSClosableWindowMask |
+ NSMiniaturizableWindowMask)];
+
+ GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top;
+
+ //Ensures window top left is inside this available rect
+ left = left > contentRect.origin.x ? left : contentRect.origin.x;
+ // Add contentRect.origin.y to respect docksize
+ bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y;
+
+ window = new GHOST_WindowCocoa(this,
+ title,
+ left,
+ bottom,
+ width,
+ height,
+ state,
+ type,
+ glSettings.flags & GHOST_glStereoVisual,
+ glSettings.numOfAASamples,
+ glSettings.flags & GHOST_glDebugContext);
+
+ if (window->getValid()) {
+ // Store the pointer to the window
+ GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
+ m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
+ //Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation)
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
+ delete window;
+ window = NULL;
+ }
+
+ [pool drain];
+ return window;
}
/**
@@ -651,32 +757,31 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
* Never explicitly delete the context, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
-GHOST_IContext *
-GHOST_SystemCocoa::
-createOffscreenContext()
+GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext()
{
- GHOST_Context *context = new GHOST_ContextCGL(
- false,
- 0,
- NULL,
- NULL,
+ GHOST_Context *context = new GHOST_ContextCGL(false,
+ 0,
+ NULL,
+ NULL,
#if defined(WITH_GL_PROFILE_CORE)
- GL_CONTEXT_CORE_PROFILE_BIT,
- 3, 3,
+ GL_CONTEXT_CORE_PROFILE_BIT,
+ 3,
+ 3,
#else
- 0, // no profile bit
- 2, 1,
+ 0, // no profile bit
+ 2,
+ 1,
#endif
- GHOST_OPENGL_CGL_CONTEXT_FLAGS,
- GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
+ GHOST_OPENGL_CGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
- return NULL;
+ return NULL;
}
/**
@@ -684,26 +789,24 @@ createOffscreenContext()
* \param context Pointer to the context to be disposed.
* \return Indication of success.
*/
-GHOST_TSuccess
-GHOST_SystemCocoa::
-disposeContext(GHOST_IContext *context)
+GHOST_TSuccess GHOST_SystemCocoa::disposeContext(GHOST_IContext *context)
{
- delete context;
+ delete context;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
/**
* \note : returns coordinates in Cocoa screen coordinates
*/
-GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
+GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- NSPoint mouseLoc = [NSEvent mouseLocation];
+ NSPoint mouseLoc = [NSEvent mouseLocation];
- // Returns the mouse location in screen coordinates
- x = (GHOST_TInt32)mouseLoc.x;
- y = (GHOST_TInt32)mouseLoc.y;
- return GHOST_kSuccess;
+ // Returns the mouse location in screen coordinates
+ x = (GHOST_TInt32)mouseLoc.x;
+ y = (GHOST_TInt32)mouseLoc.y;
+ return GHOST_kSuccess;
}
/**
@@ -711,77 +814,79 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3
*/
GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
{
- GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
- if (!window) return GHOST_kFailure;
+ GHOST_WindowCocoa *window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow();
+ if (!window)
+ return GHOST_kFailure;
- //Cursor and mouse dissociation placed here not to interfere with continuous grab
- // (in cont. grab setMouseCursorPosition is directly called)
- CGAssociateMouseAndMouseCursorPosition(false);
- setMouseCursorPosition(x, y);
- CGAssociateMouseAndMouseCursorPosition(true);
+ //Cursor and mouse dissociation placed here not to interfere with continuous grab
+ // (in cont. grab setMouseCursorPosition is directly called)
+ CGAssociateMouseAndMouseCursorPosition(false);
+ setMouseCursorPosition(x, y);
+ CGAssociateMouseAndMouseCursorPosition(true);
- //Force mouse move event (not pushed by Cocoa)
- pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x, y));
- m_outsideLoopEventProcessed = true;
+ //Force mouse move event (not pushed by Cocoa)
+ pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x, y));
+ m_outsideLoopEventProcessed = true;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
{
- float xf=(float)x, yf=(float)y;
- GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
- if (!window) return GHOST_kFailure;
-
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSScreen *windowScreen = window->getScreen();
- NSRect screenRect = [windowScreen frame];
-
- //Set position relative to current screen
- xf -= screenRect.origin.x;
- yf -= screenRect.origin.y;
-
- //Quartz Display Services uses the old coordinates (top left origin)
- yf = screenRect.size.height -yf;
-
- CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
-
- // See https://stackoverflow.com/a/17559012. By default, hardware events
- // will be suppressed for 500ms after a synthetic mouse event. For unknown
- // reasons CGEventSourceSetLocalEventsSuppressionInterval does not work,
- // however calling CGAssociateMouseAndMouseCursorPosition also removes the
- // delay, even if this is undocumented.
- CGAssociateMouseAndMouseCursorPosition(true);
-
- [pool drain];
- return GHOST_kSuccess;
+ float xf = (float)x, yf = (float)y;
+ GHOST_WindowCocoa *window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow();
+ if (!window)
+ return GHOST_kFailure;
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSScreen *windowScreen = window->getScreen();
+ NSRect screenRect = [windowScreen frame];
+
+ //Set position relative to current screen
+ xf -= screenRect.origin.x;
+ yf -= screenRect.origin.y;
+
+ //Quartz Display Services uses the old coordinates (top left origin)
+ yf = screenRect.size.height - yf;
+
+ CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription]
+ objectForKey:@"NSScreenNumber"] unsignedIntValue],
+ CGPointMake(xf, yf));
+
+ // See https://stackoverflow.com/a/17559012. By default, hardware events
+ // will be suppressed for 500ms after a synthetic mouse event. For unknown
+ // reasons CGEventSourceSetLocalEventsSuppressionInterval does not work,
+ // however calling CGAssociateMouseAndMouseCursorPosition also removes the
+ // delay, even if this is undocumented.
+ CGAssociateMouseAndMouseCursorPosition(true);
+
+ [pool drain];
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const
+GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys &keys) const
{
- keys.set(GHOST_kModifierKeyOS, (m_modifierMask & NSCommandKeyMask) ? true : false);
- keys.set(GHOST_kModifierKeyLeftAlt, (m_modifierMask & NSAlternateKeyMask) ? true : false);
- keys.set(GHOST_kModifierKeyLeftShift, (m_modifierMask & NSShiftKeyMask) ? true : false);
- keys.set(GHOST_kModifierKeyLeftControl, (m_modifierMask & NSControlKeyMask) ? true : false);
+ keys.set(GHOST_kModifierKeyOS, (m_modifierMask & NSCommandKeyMask) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftAlt, (m_modifierMask & NSAlternateKeyMask) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftShift, (m_modifierMask & NSShiftKeyMask) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftControl, (m_modifierMask & NSControlKeyMask) ? true : false);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
+GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons &buttons) const
{
- UInt32 button_state = GetCurrentEventButtonState();
-
- buttons.clear();
- buttons.set(GHOST_kButtonMaskLeft, button_state & (1 << 0));
- buttons.set(GHOST_kButtonMaskRight, button_state & (1 << 1));
- buttons.set(GHOST_kButtonMaskMiddle, button_state & (1 << 2));
- buttons.set(GHOST_kButtonMaskButton4, button_state & (1 << 3));
- buttons.set(GHOST_kButtonMaskButton5, button_state & (1 << 4));
- return GHOST_kSuccess;
+ UInt32 button_state = GetCurrentEventButtonState();
+
+ buttons.clear();
+ buttons.set(GHOST_kButtonMaskLeft, button_state & (1 << 0));
+ buttons.set(GHOST_kButtonMaskRight, button_state & (1 << 1));
+ buttons.set(GHOST_kButtonMaskMiddle, button_state & (1 << 2));
+ buttons.set(GHOST_kButtonMaskButton4, button_state & (1 << 3));
+ buttons.set(GHOST_kButtonMaskButton5, button_state & (1 << 4));
+ return GHOST_kSuccess;
}
-
#pragma mark Event handlers
/**
@@ -789,991 +894,1074 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
*/
bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
{
- bool anyProcessed = false;
- NSEvent *event;
+ bool anyProcessed = false;
+ NSEvent *event;
- // SetMouseCoalescingEnabled(false, NULL);
- //TODO : implement timer ??
+ // SetMouseCoalescingEnabled(false, NULL);
+ //TODO : implement timer ??
#if 0
- do {
- GHOST_TimerManager* timerMgr = getTimerManager();
-
- if (waitForEvent) {
- GHOST_TUns64 next = timerMgr->nextFireTime();
- double timeOut;
-
- if (next == GHOST_kFireTimeNever) {
- timeOut = kEventDurationForever;
- }
- else {
- timeOut = (double)(next - getMilliSeconds())/1000.0;
- if (timeOut < 0.0)
- timeOut = 0.0;
- }
-
- ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
- }
-
- if (timerMgr->fireTimers(getMilliSeconds())) {
- anyProcessed = true;
- }
+ do {
+ GHOST_TimerManager* timerMgr = getTimerManager();
+
+ if (waitForEvent) {
+ GHOST_TUns64 next = timerMgr->nextFireTime();
+ double timeOut;
+
+ if (next == GHOST_kFireTimeNever) {
+ timeOut = kEventDurationForever;
+ }
+ else {
+ timeOut = (double)(next - getMilliSeconds())/1000.0;
+ if (timeOut < 0.0)
+ timeOut = 0.0;
+ }
+
+ ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed = true;
+ }
#endif
- do {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- event = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate distantPast]
- inMode:NSDefaultRunLoopMode
- dequeue:YES];
- if (event==nil) {
- [pool drain];
- break;
- }
-
- anyProcessed = true;
-
- // Send event to NSApp to ensure Mac wide events are handled,
- // this will send events to CocoaWindow which will call back
- // to handleKeyEvent, handleMouseEvent and handleTabletEvent
-
- // There is on special exception for ctrl+(shift)+tab. We do not
- // get keyDown events delivered to the view because they are
- // special hotkeys to switch between views, so override directly
-
- if ([event type] == NSKeyDown &&
- [event keyCode] == kVK_Tab &&
- ([event modifierFlags] & NSControlKeyMask)) {
- handleKeyEvent(event);
- }
- else {
- // For some reason NSApp is swallowing the key up events when modifier
- // key is pressed, even if there seems to be no apparent reason to do
- // so, as a workaround we always handle these up events.
- if ([event type] == NSKeyUp && ([event modifierFlags] & (NSCommandKeyMask | NSAlternateKeyMask)))
- handleKeyEvent(event);
-
- [NSApp sendEvent:event];
- }
-
- [pool drain];
- } while (event != nil);
+ do {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantPast]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ if (event == nil) {
+ [pool drain];
+ break;
+ }
+
+ anyProcessed = true;
+
+ // Send event to NSApp to ensure Mac wide events are handled,
+ // this will send events to CocoaWindow which will call back
+ // to handleKeyEvent, handleMouseEvent and handleTabletEvent
+
+ // There is on special exception for ctrl+(shift)+tab. We do not
+ // get keyDown events delivered to the view because they are
+ // special hotkeys to switch between views, so override directly
+
+ if ([event type] == NSKeyDown && [event keyCode] == kVK_Tab &&
+ ([event modifierFlags] & NSControlKeyMask)) {
+ handleKeyEvent(event);
+ }
+ else {
+ // For some reason NSApp is swallowing the key up events when modifier
+ // key is pressed, even if there seems to be no apparent reason to do
+ // so, as a workaround we always handle these up events.
+ if ([event type] == NSKeyUp &&
+ ([event modifierFlags] & (NSCommandKeyMask | NSAlternateKeyMask)))
+ handleKeyEvent(event);
+
+ [NSApp sendEvent:event];
+ }
+
+ [pool drain];
+ } while (event != nil);
#if 0
- } while (waitForEvent && !anyProcessed); // Needed only for timer implementation
+ } while (waitForEvent && !anyProcessed); // Needed only for timer implementation
#endif
- if (m_needDelayedApplicationBecomeActiveEventProcessing) handleApplicationBecomeActiveEvent();
+ if (m_needDelayedApplicationBecomeActiveEventProcessing)
+ handleApplicationBecomeActiveEvent();
- if (m_outsideLoopEventProcessed) {
- m_outsideLoopEventProcessed = false;
- return true;
- }
+ if (m_outsideLoopEventProcessed) {
+ m_outsideLoopEventProcessed = false;
+ return true;
+ }
- m_ignoreWindowSizedMessages = false;
+ m_ignoreWindowSizedMessages = false;
- return anyProcessed;
+ return anyProcessed;
}
//Note: called from NSApplication delegate
GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
{
- //Update the modifiers key mask, as its status may have changed when the application was not active
- //(that is when update events are sent to another application)
- unsigned int modifiers;
- GHOST_IWindow* window = m_windowManager->getActiveWindow();
-
- if (!window) {
- m_needDelayedApplicationBecomeActiveEventProcessing = true;
- return GHOST_kFailure;
- }
- else m_needDelayedApplicationBecomeActiveEventProcessing = false;
-
- modifiers = [[[NSApplication sharedApplication] currentEvent] modifierFlags];
-
- if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
- pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift));
- }
- if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
- pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl));
- }
- if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
- pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt));
- }
- if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
- pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyOS));
- }
-
- m_modifierMask = modifiers;
-
- m_outsideLoopEventProcessed = true;
- return GHOST_kSuccess;
+ //Update the modifiers key mask, as its status may have changed when the application was not active
+ //(that is when update events are sent to another application)
+ unsigned int modifiers;
+ GHOST_IWindow *window = m_windowManager->getActiveWindow();
+
+ if (!window) {
+ m_needDelayedApplicationBecomeActiveEventProcessing = true;
+ return GHOST_kFailure;
+ }
+ else
+ m_needDelayedApplicationBecomeActiveEventProcessing = false;
+
+ modifiers = [[[NSApplication sharedApplication] currentEvent] modifierFlags];
+
+ if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
+ pushEvent(
+ new GHOST_EventKey(getMilliSeconds(),
+ (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyLeftShift));
+ }
+ if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
+ pushEvent(new GHOST_EventKey(getMilliSeconds(),
+ (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyLeftControl));
+ }
+ if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
+ pushEvent(new GHOST_EventKey(getMilliSeconds(),
+ (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyLeftAlt));
+ }
+ if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
+ pushEvent(new GHOST_EventKey(getMilliSeconds(),
+ (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyOS));
+ }
+
+ m_modifierMask = modifiers;
+
+ m_outsideLoopEventProcessed = true;
+ return GHOST_kSuccess;
}
void GHOST_SystemCocoa::notifyExternalEventProcessed()
{
- m_outsideLoopEventProcessed = true;
+ m_outsideLoopEventProcessed = true;
}
//Note: called from NSWindow delegate
-GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)
+GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
+ GHOST_WindowCocoa *window)
{
- NSArray *windowsList;
- windowsList = [NSApp orderedWindows];
- if (!validWindow(window)) {
- return GHOST_kFailure;
- }
- switch (eventType) {
- case GHOST_kEventWindowClose:
- // check for index of mainwindow as it would quit blender without dialog and discard
- if ([windowsList count] > 1 && window->getCocoaWindow() != [windowsList objectAtIndex:[windowsList count] - 1]) {
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
- }
- else {
- handleQuitRequest(); // -> quit dialog
- }
- break;
- case GHOST_kEventWindowActivate:
- m_windowManager->setActiveWindow(window);
- window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );
- break;
- case GHOST_kEventWindowDeactivate:
- m_windowManager->setWindowInactive(window);
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
- break;
- case GHOST_kEventWindowUpdate:
- if (m_nativePixel) {
- window->setNativePixelSize();
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window) );
- }
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
- break;
- case GHOST_kEventWindowMove:
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window) );
- break;
- case GHOST_kEventWindowSize:
- if (!m_ignoreWindowSizedMessages) {
- //Enforce only one resize message per event loop (coalescing all the live resize messages)
- window->updateDrawingContext();
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
- //Mouse up event is trapped by the resizing event loop, so send it anyway to the window manager
- pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft));
- //m_ignoreWindowSizedMessages = true;
- }
- break;
- case GHOST_kEventNativeResolutionChange:
-
- if (m_nativePixel) {
- window->setNativePixelSize();
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window) );
- }
-
- default:
- return GHOST_kFailure;
- break;
- }
-
- m_outsideLoopEventProcessed = true;
- return GHOST_kSuccess;
+ NSArray *windowsList;
+ windowsList = [NSApp orderedWindows];
+ if (!validWindow(window)) {
+ return GHOST_kFailure;
+ }
+ switch (eventType) {
+ case GHOST_kEventWindowClose:
+ // check for index of mainwindow as it would quit blender without dialog and discard
+ if ([windowsList count] > 1 &&
+ window->getCocoaWindow() != [windowsList objectAtIndex:[windowsList count] - 1]) {
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window));
+ }
+ else {
+ handleQuitRequest(); // -> quit dialog
+ }
+ break;
+ case GHOST_kEventWindowActivate:
+ m_windowManager->setActiveWindow(window);
+ window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
+ break;
+ case GHOST_kEventWindowDeactivate:
+ m_windowManager->setWindowInactive(window);
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window));
+ break;
+ case GHOST_kEventWindowUpdate:
+ if (m_nativePixel) {
+ window->setNativePixelSize();
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window));
+ }
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window));
+ break;
+ case GHOST_kEventWindowMove:
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window));
+ break;
+ case GHOST_kEventWindowSize:
+ if (!m_ignoreWindowSizedMessages) {
+ //Enforce only one resize message per event loop (coalescing all the live resize messages)
+ window->updateDrawingContext();
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ //Mouse up event is trapped by the resizing event loop, so send it anyway to the window manager
+ pushEvent(new GHOST_EventButton(
+ getMilliSeconds(), GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft));
+ //m_ignoreWindowSizedMessages = true;
+ }
+ break;
+ case GHOST_kEventNativeResolutionChange:
+
+ if (m_nativePixel) {
+ window->setNativePixelSize();
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window));
+ }
+
+ default:
+ return GHOST_kFailure;
+ break;
+ }
+
+ m_outsideLoopEventProcessed = true;
+ return GHOST_kSuccess;
}
//Note: called from NSWindow subclass
-GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType,
- GHOST_WindowCocoa* window, int mouseX, int mouseY, void* data)
+GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType,
+ GHOST_TDragnDropTypes draggedObjectType,
+ GHOST_WindowCocoa *window,
+ int mouseX,
+ int mouseY,
+ void *data)
{
- if (!validWindow(window)) {
- return GHOST_kFailure;
- }
- switch (eventType) {
- case GHOST_kEventDraggingEntered:
- case GHOST_kEventDraggingUpdated:
- case GHOST_kEventDraggingExited:
- pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),eventType,draggedObjectType,window,mouseX,mouseY,NULL));
- break;
-
- case GHOST_kEventDraggingDropDone:
- {
- GHOST_TUns8 * temp_buff;
- GHOST_TStringArray *strArray;
- NSArray *droppedArray;
- size_t pastedTextSize;
- NSString *droppedStr;
- GHOST_TEventDataPtr eventData;
- int i;
-
- if (!data) return GHOST_kFailure;
-
- switch (draggedObjectType) {
- case GHOST_kDragnDropTypeFilenames:
- droppedArray = (NSArray*)data;
-
- strArray = (GHOST_TStringArray*)malloc(sizeof(GHOST_TStringArray));
- if (!strArray) return GHOST_kFailure;
-
- strArray->count = [droppedArray count];
- if (strArray->count == 0) {
- free(strArray);
- return GHOST_kFailure;
- }
-
- strArray->strings = (GHOST_TUns8**) malloc(strArray->count*sizeof(GHOST_TUns8*));
-
- for (i=0;i<strArray->count;i++)
- {
- droppedStr = [droppedArray objectAtIndex:i];
-
- pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
- temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1);
-
- if (!temp_buff) {
- strArray->count = i;
- break;
- }
-
- strncpy((char*)temp_buff, [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
- temp_buff[pastedTextSize] = '\0';
-
- strArray->strings[i] = temp_buff;
- }
-
- eventData = (GHOST_TEventDataPtr) strArray;
- break;
-
- case GHOST_kDragnDropTypeString:
- droppedStr = (NSString*)data;
- pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
-
- temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1);
-
- if (temp_buff == NULL) {
- return GHOST_kFailure;
- }
-
- strncpy((char*)temp_buff, [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
-
- temp_buff[pastedTextSize] = '\0';
-
- eventData = (GHOST_TEventDataPtr) temp_buff;
- break;
-
- case GHOST_kDragnDropTypeBitmap:
- {
- NSImage *droppedImg = (NSImage*)data;
- NSSize imgSize = [droppedImg size];
- ImBuf *ibuf = NULL;
- GHOST_TUns8 *rasterRGB = NULL;
- GHOST_TUns8 *rasterRGBA = NULL;
- GHOST_TUns8 *toIBuf = NULL;
- int x, y, to_i, from_i;
- NSBitmapImageRep *blBitmapFormatImageRGB,*blBitmapFormatImageRGBA,*bitmapImage=nil;
- NSEnumerator *enumerator;
- NSImageRep *representation;
-
- ibuf = IMB_allocImBuf (imgSize.width, imgSize.height, 32, IB_rect);
- if (!ibuf) {
- [droppedImg release];
- return GHOST_kFailure;
- }
-
- /*Get the bitmap of the image*/
- enumerator = [[droppedImg representations] objectEnumerator];
- while ((representation = [enumerator nextObject])) {
- if ([representation isKindOfClass:[NSBitmapImageRep class]]) {
- bitmapImage = (NSBitmapImageRep *)representation;
- break;
- }
- }
- if (bitmapImage == nil) return GHOST_kFailure;
-
- if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0)
- && ![bitmapImage isPlanar]) {
- /* Try a fast copy if the image is a meshed RGBA 32bit bitmap*/
- toIBuf = (GHOST_TUns8*)ibuf->rect;
- rasterRGB = (GHOST_TUns8*)[bitmapImage bitmapData];
- for (y = 0; y < imgSize.height; y++) {
- to_i = (imgSize.height-y-1)*imgSize.width;
- from_i = y*imgSize.width;
- memcpy(toIBuf+4*to_i, rasterRGB+4*from_i, 4*imgSize.width);
- }
- }
- else {
- /* Tell cocoa image resolution is same as current system one */
- [bitmapImage setSize:imgSize];
-
- /* Convert the image in a RGBA 32bit format */
- /* As Core Graphics does not support contextes with non premutliplied alpha,
- we need to get alpha key values in a separate batch */
-
- /* First get RGB values w/o Alpha to avoid pre-multiplication, 32bit but last byte is unused */
- blBitmapFormatImageRGB = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
- pixelsWide:imgSize.width
- pixelsHigh:imgSize.height
- bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO
- colorSpaceName:NSDeviceRGBColorSpace
- bitmapFormat:(NSBitmapFormat)0
- bytesPerRow:4*imgSize.width
- bitsPerPixel:32/*RGB format padded to 32bits*/];
-
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGB]];
- [bitmapImage draw];
- [NSGraphicsContext restoreGraphicsState];
-
- rasterRGB = (GHOST_TUns8*)[blBitmapFormatImageRGB bitmapData];
- if (rasterRGB == NULL) {
- [bitmapImage release];
- [blBitmapFormatImageRGB release];
- [droppedImg release];
- return GHOST_kFailure;
- }
-
- /* Then get Alpha values by getting the RGBA image (that is premultiplied btw) */
- blBitmapFormatImageRGBA = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
- pixelsWide:imgSize.width
- pixelsHigh:imgSize.height
- bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO
- colorSpaceName:NSDeviceRGBColorSpace
- bitmapFormat:(NSBitmapFormat)0
- bytesPerRow:4*imgSize.width
- bitsPerPixel:32/* RGBA */];
-
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGBA]];
- [bitmapImage draw];
- [NSGraphicsContext restoreGraphicsState];
-
- rasterRGBA = (GHOST_TUns8*)[blBitmapFormatImageRGBA bitmapData];
- if (rasterRGBA == NULL) {
- [bitmapImage release];
- [blBitmapFormatImageRGB release];
- [blBitmapFormatImageRGBA release];
- [droppedImg release];
- return GHOST_kFailure;
- }
-
- /*Copy the image to ibuf, flipping it vertically*/
- toIBuf = (GHOST_TUns8*)ibuf->rect;
- for (y = 0; y < imgSize.height; y++) {
- for (x = 0; x < imgSize.width; x++) {
- to_i = (imgSize.height-y-1)*imgSize.width + x;
- from_i = y*imgSize.width + x;
-
- toIBuf[4*to_i] = rasterRGB[4*from_i]; /* R */
- toIBuf[4*to_i+1] = rasterRGB[4*from_i+1]; /* G */
- toIBuf[4*to_i+2] = rasterRGB[4*from_i+2]; /* B */
- toIBuf[4*to_i+3] = rasterRGBA[4*from_i+3]; /* A */
- }
- }
-
- [blBitmapFormatImageRGB release];
- [blBitmapFormatImageRGBA release];
- [droppedImg release];
- }
-
- eventData = (GHOST_TEventDataPtr) ibuf;
-
- break;
- }
- default:
- return GHOST_kFailure;
- break;
- }
- pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),eventType,draggedObjectType,window,mouseX,mouseY,eventData));
-
- break;
- }
- default:
- return GHOST_kFailure;
- }
- m_outsideLoopEventProcessed = true;
- return GHOST_kSuccess;
+ if (!validWindow(window)) {
+ return GHOST_kFailure;
+ }
+ switch (eventType) {
+ case GHOST_kEventDraggingEntered:
+ case GHOST_kEventDraggingUpdated:
+ case GHOST_kEventDraggingExited:
+ pushEvent(new GHOST_EventDragnDrop(
+ getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, NULL));
+ break;
+
+ case GHOST_kEventDraggingDropDone: {
+ GHOST_TUns8 *temp_buff;
+ GHOST_TStringArray *strArray;
+ NSArray *droppedArray;
+ size_t pastedTextSize;
+ NSString *droppedStr;
+ GHOST_TEventDataPtr eventData;
+ int i;
+
+ if (!data)
+ return GHOST_kFailure;
+
+ switch (draggedObjectType) {
+ case GHOST_kDragnDropTypeFilenames:
+ droppedArray = (NSArray *)data;
+
+ strArray = (GHOST_TStringArray *)malloc(sizeof(GHOST_TStringArray));
+ if (!strArray)
+ return GHOST_kFailure;
+
+ strArray->count = [droppedArray count];
+ if (strArray->count == 0) {
+ free(strArray);
+ return GHOST_kFailure;
+ }
+
+ strArray->strings = (GHOST_TUns8 **)malloc(strArray->count * sizeof(GHOST_TUns8 *));
+
+ for (i = 0; i < strArray->count; i++) {
+ droppedStr = [droppedArray objectAtIndex:i];
+
+ pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+ temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1);
+
+ if (!temp_buff) {
+ strArray->count = i;
+ break;
+ }
+
+ strncpy((char *)temp_buff,
+ [droppedStr cStringUsingEncoding:NSUTF8StringEncoding],
+ pastedTextSize);
+ temp_buff[pastedTextSize] = '\0';
+
+ strArray->strings[i] = temp_buff;
+ }
+
+ eventData = (GHOST_TEventDataPtr)strArray;
+ break;
+
+ case GHOST_kDragnDropTypeString:
+ droppedStr = (NSString *)data;
+ pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1);
+
+ if (temp_buff == NULL) {
+ return GHOST_kFailure;
+ }
+
+ strncpy((char *)temp_buff,
+ [droppedStr cStringUsingEncoding:NSUTF8StringEncoding],
+ pastedTextSize);
+
+ temp_buff[pastedTextSize] = '\0';
+
+ eventData = (GHOST_TEventDataPtr)temp_buff;
+ break;
+
+ case GHOST_kDragnDropTypeBitmap: {
+ NSImage *droppedImg = (NSImage *)data;
+ NSSize imgSize = [droppedImg size];
+ ImBuf *ibuf = NULL;
+ GHOST_TUns8 *rasterRGB = NULL;
+ GHOST_TUns8 *rasterRGBA = NULL;
+ GHOST_TUns8 *toIBuf = NULL;
+ int x, y, to_i, from_i;
+ NSBitmapImageRep *blBitmapFormatImageRGB, *blBitmapFormatImageRGBA, *bitmapImage = nil;
+ NSEnumerator *enumerator;
+ NSImageRep *representation;
+
+ ibuf = IMB_allocImBuf(imgSize.width, imgSize.height, 32, IB_rect);
+ if (!ibuf) {
+ [droppedImg release];
+ return GHOST_kFailure;
+ }
+
+ /*Get the bitmap of the image*/
+ enumerator = [[droppedImg representations] objectEnumerator];
+ while ((representation = [enumerator nextObject])) {
+ if ([representation isKindOfClass:[NSBitmapImageRep class]]) {
+ bitmapImage = (NSBitmapImageRep *)representation;
+ break;
+ }
+ }
+ if (bitmapImage == nil)
+ return GHOST_kFailure;
+
+ if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0) &&
+ ![bitmapImage isPlanar]) {
+ /* Try a fast copy if the image is a meshed RGBA 32bit bitmap*/
+ toIBuf = (GHOST_TUns8 *)ibuf->rect;
+ rasterRGB = (GHOST_TUns8 *)[bitmapImage bitmapData];
+ for (y = 0; y < imgSize.height; y++) {
+ to_i = (imgSize.height - y - 1) * imgSize.width;
+ from_i = y * imgSize.width;
+ memcpy(toIBuf + 4 * to_i, rasterRGB + 4 * from_i, 4 * imgSize.width);
+ }
+ }
+ else {
+ /* Tell cocoa image resolution is same as current system one */
+ [bitmapImage setSize:imgSize];
+
+ /* Convert the image in a RGBA 32bit format */
+ /* As Core Graphics does not support contextes with non premutliplied alpha,
+ we need to get alpha key values in a separate batch */
+
+ /* First get RGB values w/o Alpha to avoid pre-multiplication, 32bit but last byte is unused */
+ blBitmapFormatImageRGB = [[NSBitmapImageRep alloc]
+ initWithBitmapDataPlanes:NULL
+ pixelsWide:imgSize.width
+ pixelsHigh:imgSize.height
+ bitsPerSample:8
+ samplesPerPixel:3
+ hasAlpha:NO
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bitmapFormat:(NSBitmapFormat)0
+ bytesPerRow:4 * imgSize.width
+ bitsPerPixel:32 /*RGB format padded to 32bits*/];
+
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext
+ setCurrentContext:[NSGraphicsContext
+ graphicsContextWithBitmapImageRep:blBitmapFormatImageRGB]];
+ [bitmapImage draw];
+ [NSGraphicsContext restoreGraphicsState];
+
+ rasterRGB = (GHOST_TUns8 *)[blBitmapFormatImageRGB bitmapData];
+ if (rasterRGB == NULL) {
+ [bitmapImage release];
+ [blBitmapFormatImageRGB release];
+ [droppedImg release];
+ return GHOST_kFailure;
+ }
+
+ /* Then get Alpha values by getting the RGBA image (that is premultiplied btw) */
+ blBitmapFormatImageRGBA = [[NSBitmapImageRep alloc]
+ initWithBitmapDataPlanes:NULL
+ pixelsWide:imgSize.width
+ pixelsHigh:imgSize.height
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bitmapFormat:(NSBitmapFormat)0
+ bytesPerRow:4 * imgSize.width
+ bitsPerPixel:32 /* RGBA */];
+
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext
+ setCurrentContext:[NSGraphicsContext
+ graphicsContextWithBitmapImageRep:blBitmapFormatImageRGBA]];
+ [bitmapImage draw];
+ [NSGraphicsContext restoreGraphicsState];
+
+ rasterRGBA = (GHOST_TUns8 *)[blBitmapFormatImageRGBA bitmapData];
+ if (rasterRGBA == NULL) {
+ [bitmapImage release];
+ [blBitmapFormatImageRGB release];
+ [blBitmapFormatImageRGBA release];
+ [droppedImg release];
+ return GHOST_kFailure;
+ }
+
+ /*Copy the image to ibuf, flipping it vertically*/
+ toIBuf = (GHOST_TUns8 *)ibuf->rect;
+ for (y = 0; y < imgSize.height; y++) {
+ for (x = 0; x < imgSize.width; x++) {
+ to_i = (imgSize.height - y - 1) * imgSize.width + x;
+ from_i = y * imgSize.width + x;
+
+ toIBuf[4 * to_i] = rasterRGB[4 * from_i]; /* R */
+ toIBuf[4 * to_i + 1] = rasterRGB[4 * from_i + 1]; /* G */
+ toIBuf[4 * to_i + 2] = rasterRGB[4 * from_i + 2]; /* B */
+ toIBuf[4 * to_i + 3] = rasterRGBA[4 * from_i + 3]; /* A */
+ }
+ }
+
+ [blBitmapFormatImageRGB release];
+ [blBitmapFormatImageRGBA release];
+ [droppedImg release];
+ }
+
+ eventData = (GHOST_TEventDataPtr)ibuf;
+
+ break;
+ }
+ default:
+ return GHOST_kFailure;
+ break;
+ }
+ pushEvent(new GHOST_EventDragnDrop(
+ getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, eventData));
+
+ break;
+ }
+ default:
+ return GHOST_kFailure;
+ }
+ m_outsideLoopEventProcessed = true;
+ return GHOST_kSuccess;
}
-
GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
{
- GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow();
-
- //Discard quit event if we are in cursor grab sequence
- if (window && window->getCursorGrabModeIsWarp())
- return GHOST_kExitCancel;
-
- //Check open windows if some changes are not saved
- if (m_windowManager->getAnyModifiedState())
- {
- int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved.\nDo you really want to quit?",
- @"Cancel", @"Quit Anyway", nil);
- if (shouldQuit == NSAlertAlternateReturn)
- {
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
- return GHOST_kExitNow;
- }
- else {
- //Give back focus to the blender window if user selected cancel quit
- NSArray *windowsList = [NSApp orderedWindows];
- if ([windowsList count]) {
- [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
- //Handle the modifiers keyes changed state issue
- //as recovering from the quit dialog is like application
- //gaining focus back.
- //Main issue fixed is Cmd modifier not being cleared
- handleApplicationBecomeActiveEvent();
- }
- }
- }
- else {
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
- m_outsideLoopEventProcessed = true;
- return GHOST_kExitNow;
- }
-
- return GHOST_kExitCancel;
+ GHOST_Window *window = (GHOST_Window *)m_windowManager->getActiveWindow();
+
+ //Discard quit event if we are in cursor grab sequence
+ if (window && window->getCursorGrabModeIsWarp())
+ return GHOST_kExitCancel;
+
+ //Check open windows if some changes are not saved
+ if (m_windowManager->getAnyModifiedState()) {
+ int shouldQuit = NSRunAlertPanel(
+ @"Exit Blender",
+ @"Some changes have not been saved.\nDo you really want to quit?",
+ @"Cancel",
+ @"Quit Anyway",
+ nil);
+ if (shouldQuit == NSAlertAlternateReturn) {
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL));
+ return GHOST_kExitNow;
+ }
+ else {
+ //Give back focus to the blender window if user selected cancel quit
+ NSArray *windowsList = [NSApp orderedWindows];
+ if ([windowsList count]) {
+ [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
+ //Handle the modifiers keyes changed state issue
+ //as recovering from the quit dialog is like application
+ //gaining focus back.
+ //Main issue fixed is Cmd modifier not being cleared
+ handleApplicationBecomeActiveEvent();
+ }
+ }
+ }
+ else {
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL));
+ m_outsideLoopEventProcessed = true;
+ return GHOST_kExitNow;
+ }
+
+ return GHOST_kExitCancel;
}
bool GHOST_SystemCocoa::handleOpenDocumentRequest(void *filepathStr)
{
- NSString *filepath = (NSString*)filepathStr;
- int confirmOpen = NSAlertAlternateReturn;
- NSArray *windowsList;
- char * temp_buff;
- size_t filenameTextSize;
- GHOST_Window* window= (GHOST_Window*)m_windowManager->getActiveWindow();
-
- if (!window) {
- return NO;
- }
-
- //Discard event if we are in cursor grab sequence, it'll lead to "stuck cursor" situation if the alert panel is raised
- if (window && window->getCursorGrabModeIsWarp())
- return GHOST_kExitCancel;
-
- //Check open windows if some changes are not saved
- if (m_windowManager->getAnyModifiedState())
- {
- confirmOpen = NSRunAlertPanel([NSString stringWithFormat:@"Opening %@",[filepath lastPathComponent]],
- @"Current document has not been saved.\nDo you really want to proceed?",
- @"Cancel", @"Open", nil);
- }
-
- //Give back focus to the blender window
- windowsList = [NSApp orderedWindows];
- if ([windowsList count]) {
- [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
- }
-
- if (confirmOpen == NSAlertAlternateReturn)
- {
- filenameTextSize = [filepath lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
-
- temp_buff = (char*) malloc(filenameTextSize+1);
-
- if (temp_buff == NULL) {
- return GHOST_kFailure;
- }
-
- strncpy(temp_buff, [filepath cStringUsingEncoding:NSUTF8StringEncoding], filenameTextSize);
-
- temp_buff[filenameTextSize] = '\0';
-
- pushEvent(new GHOST_EventString(getMilliSeconds(),GHOST_kEventOpenMainFile,window,(GHOST_TEventDataPtr) temp_buff));
-
- return YES;
- }
- else return NO;
+ NSString *filepath = (NSString *)filepathStr;
+ int confirmOpen = NSAlertAlternateReturn;
+ NSArray *windowsList;
+ char *temp_buff;
+ size_t filenameTextSize;
+ GHOST_Window *window = (GHOST_Window *)m_windowManager->getActiveWindow();
+
+ if (!window) {
+ return NO;
+ }
+
+ //Discard event if we are in cursor grab sequence, it'll lead to "stuck cursor" situation if the alert panel is raised
+ if (window && window->getCursorGrabModeIsWarp())
+ return GHOST_kExitCancel;
+
+ //Check open windows if some changes are not saved
+ if (m_windowManager->getAnyModifiedState()) {
+ confirmOpen = NSRunAlertPanel(
+ [NSString stringWithFormat:@"Opening %@", [filepath lastPathComponent]],
+ @"Current document has not been saved.\nDo you really want to proceed?",
+ @"Cancel",
+ @"Open",
+ nil);
+ }
+
+ //Give back focus to the blender window
+ windowsList = [NSApp orderedWindows];
+ if ([windowsList count]) {
+ [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
+ }
+
+ if (confirmOpen == NSAlertAlternateReturn) {
+ filenameTextSize = [filepath lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ temp_buff = (char *)malloc(filenameTextSize + 1);
+
+ if (temp_buff == NULL) {
+ return GHOST_kFailure;
+ }
+
+ strncpy(temp_buff, [filepath cStringUsingEncoding:NSUTF8StringEncoding], filenameTextSize);
+
+ temp_buff[filenameTextSize] = '\0';
+
+ pushEvent(new GHOST_EventString(
+ getMilliSeconds(), GHOST_kEventOpenMainFile, window, (GHOST_TEventDataPtr)temp_buff));
+
+ return YES;
+ }
+ else
+ return NO;
}
GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType)
{
- NSEvent *event = (NSEvent *)eventPtr;
- GHOST_IWindow* window;
-
- window = m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
- if (!window) {
- //printf("\nW failure for event 0x%x",[event type]);
- return GHOST_kFailure;
- }
-
- GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
-
- switch (eventType) {
- case NSTabletPoint:
- // workaround 2 cornercases:
- // 1. if [event isEnteringProximity] was not triggered since program-start
- // 2. device is not sending [event pointingDeviceType], due no eraser
- if (ct.Active == GHOST_kTabletModeNone)
- ct.Active = GHOST_kTabletModeStylus;
-
- ct.Pressure = [event pressure];
- ct.Xtilt = [event tilt].x;
- ct.Ytilt = [event tilt].y;
- break;
-
- case NSTabletProximity:
- ct.Pressure = 0;
- ct.Xtilt = 0;
- ct.Ytilt = 0;
- if ([event isEnteringProximity])
- {
- //pointer is entering tablet area proximity
- switch ([event pointingDeviceType]) {
- case NSPenPointingDevice:
- ct.Active = GHOST_kTabletModeStylus;
- break;
- case NSEraserPointingDevice:
- ct.Active = GHOST_kTabletModeEraser;
- break;
- case NSCursorPointingDevice:
- case NSUnknownPointingDevice:
- default:
- ct.Active = GHOST_kTabletModeNone;
- break;
- }
- }
- else {
- // pointer is leaving - return to mouse
- ct.Active = GHOST_kTabletModeNone;
- }
- break;
-
- default:
- GHOST_ASSERT(FALSE,"GHOST_SystemCocoa::handleTabletEvent : unknown event received");
- return GHOST_kFailure;
- break;
- }
- return GHOST_kSuccess;
+ NSEvent *event = (NSEvent *)eventPtr;
+ GHOST_IWindow *window;
+
+ window = m_windowManager->getWindowAssociatedWithOSWindow((void *)[event window]);
+ if (!window) {
+ //printf("\nW failure for event 0x%x",[event type]);
+ return GHOST_kFailure;
+ }
+
+ GHOST_TabletData &ct = ((GHOST_WindowCocoa *)window)->GetCocoaTabletData();
+
+ switch (eventType) {
+ case NSTabletPoint:
+ // workaround 2 cornercases:
+ // 1. if [event isEnteringProximity] was not triggered since program-start
+ // 2. device is not sending [event pointingDeviceType], due no eraser
+ if (ct.Active == GHOST_kTabletModeNone)
+ ct.Active = GHOST_kTabletModeStylus;
+
+ ct.Pressure = [event pressure];
+ ct.Xtilt = [event tilt].x;
+ ct.Ytilt = [event tilt].y;
+ break;
+
+ case NSTabletProximity:
+ ct.Pressure = 0;
+ ct.Xtilt = 0;
+ ct.Ytilt = 0;
+ if ([event isEnteringProximity]) {
+ //pointer is entering tablet area proximity
+ switch ([event pointingDeviceType]) {
+ case NSPenPointingDevice:
+ ct.Active = GHOST_kTabletModeStylus;
+ break;
+ case NSEraserPointingDevice:
+ ct.Active = GHOST_kTabletModeEraser;
+ break;
+ case NSCursorPointingDevice:
+ case NSUnknownPointingDevice:
+ default:
+ ct.Active = GHOST_kTabletModeNone;
+ break;
+ }
+ }
+ else {
+ // pointer is leaving - return to mouse
+ ct.Active = GHOST_kTabletModeNone;
+ }
+ break;
+
+ default:
+ GHOST_ASSERT(FALSE, "GHOST_SystemCocoa::handleTabletEvent : unknown event received");
+ return GHOST_kFailure;
+ break;
+ }
+ return GHOST_kSuccess;
}
bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
{
- NSEvent *event = (NSEvent *)eventPtr;
-
- switch ([event subtype]) {
- case NSTabletPointEventSubtype:
- handleTabletEvent(eventPtr, NSTabletPoint);
- return true;
- case NSTabletProximityEventSubtype:
- handleTabletEvent(eventPtr, NSTabletProximity);
- return true;
- default:
- //No tablet event included : do nothing
- return false;
- }
+ NSEvent *event = (NSEvent *)eventPtr;
+
+ switch ([event subtype]) {
+ case NSTabletPointEventSubtype:
+ handleTabletEvent(eventPtr, NSTabletPoint);
+ return true;
+ case NSTabletProximityEventSubtype:
+ handleTabletEvent(eventPtr, NSTabletProximity);
+ return true;
+ default:
+ //No tablet event included : do nothing
+ return false;
+ }
}
GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
{
- NSEvent *event = (NSEvent *)eventPtr;
- GHOST_WindowCocoa* window;
- CocoaWindow *cocoawindow;
-
- /* [event window] returns other windows if mouse-over, that's OSX input standard
- however, if mouse exits window(s), the windows become inactive, until you click.
- We then fall back to the active window from ghost */
- window = (GHOST_WindowCocoa*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
- if (!window) {
- window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
- if (!window) {
- //printf("\nW failure for event 0x%x",[event type]);
- return GHOST_kFailure;
- }
- }
-
- cocoawindow = (CocoaWindow *)window->getOSWindow();
-
- switch ([event type]) {
- case NSLeftMouseDown:
- pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft));
- handleTabletEvent(event); //Handle tablet events combined with mouse events
- break;
- case NSRightMouseDown:
- pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight));
- handleTabletEvent(event); //Handle tablet events combined with mouse events
- break;
- case NSOtherMouseDown:
- pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
- handleTabletEvent(event); //Handle tablet events combined with mouse events
- break;
-
- case NSLeftMouseUp:
- pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft));
- handleTabletEvent(event); //Handle tablet events combined with mouse events
- break;
- case NSRightMouseUp:
- pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight));
- handleTabletEvent(event); //Handle tablet events combined with mouse events
- break;
- case NSOtherMouseUp:
- pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
- handleTabletEvent(event); //Handle tablet events combined with mouse events
- break;
-
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- //Handle tablet events combined with mouse events
- handleTabletEvent(event);
-
- case NSMouseMoved:
- {
- GHOST_TGrabCursorMode grab_mode = window->getCursorGrabMode();
-
- /* TODO: CHECK IF THIS IS A TABLET EVENT */
- bool is_tablet = false;
-
- if (is_tablet && window->getCursorGrabModeIsWarp()) {
- grab_mode = GHOST_kGrabDisable;
- }
-
- switch (grab_mode) {
- case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move
- {
- GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y;
-
- window->getCursorGrabInitPos(x_warp, y_warp);
- window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp);
-
- window->getCursorGrabAccum(x_accum, y_accum);
- x_accum += [event deltaX];
- y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
- window->setCursorGrabAccum(x_accum, y_accum);
-
- window->clientToScreenIntern(x_warp+x_accum, y_warp+y_accum, x, y);
- pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
- break;
- }
- case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
- {
- NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
- GHOST_TInt32 x_mouse = mousePos.x;
- GHOST_TInt32 y_mouse = mousePos.y;
- GHOST_Rect bounds, windowBounds, correctedBounds;
-
- /* fallback to window bounds */
- if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
- window->getClientBounds(bounds);
-
- //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
- window->getClientBounds(windowBounds);
- window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_t);
- window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b);
- correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b;
- correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t;
-
- //Get accumulation from previous mouse warps
- GHOST_TInt32 x_accum, y_accum;
- window->getCursorGrabAccum(x_accum, y_accum);
-
- //Warp mouse cursor if needed
- GHOST_TInt32 warped_x_mouse = x_mouse;
- GHOST_TInt32 warped_y_mouse = y_mouse;
- correctedBounds.wrapPoint(warped_x_mouse, warped_y_mouse, 4);
-
- //Set new cursor position
- if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) {
- GHOST_TInt32 warped_x, warped_y;
- window->clientToScreenIntern(warped_x_mouse, warped_y_mouse, warped_x, warped_y);
- setMouseCursorPosition(warped_x, warped_y); /* wrap */
- window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse), y_accum + (y_mouse - warped_y_mouse));
- }
-
- //Generate event
- GHOST_TInt32 x, y;
- window->clientToScreenIntern(x_mouse + x_accum, y_mouse + y_accum, x, y);
- pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
- break;
- }
- default:
- {
- //Normal cursor operation: send mouse position in window
- NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
- GHOST_TInt32 x, y;
-
- window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
- pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
- break;
- }
- }
- }
- break;
-
- case NSScrollWheel:
- {
- NSEventPhase momentumPhase = NSEventPhaseNone;
- NSEventPhase phase = NSEventPhaseNone;
-
- if ([event respondsToSelector:@selector(momentumPhase)])
- momentumPhase = [event momentumPhase];
- if ([event respondsToSelector:@selector(phase)])
- phase = [event phase];
-
- /* when pressing a key while momentum scrolling continues after
- * lifting fingers off the trackpad, the action can unexpectedly
- * change from e.g. scrolling to zooming. this works around the
- * issue by ignoring momentum scroll after a key press */
- if (momentumPhase) {
- if (m_ignoreMomentumScroll)
- break;
- }
- else {
- m_ignoreMomentumScroll = false;
- }
-
- /* we assume phases are only set for gestures from trackpad or magic
- * mouse events. note that using tablet at the same time may not work
- * since this is a static variable */
- if (phase == NSEventPhaseBegan)
- m_multiTouchScroll = true;
- else if (phase == NSEventPhaseEnded)
- m_multiTouchScroll = false;
-
- /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */
- if (!m_multiTouchScroll && momentumPhase == NSEventPhaseNone) {
- GHOST_TInt32 delta;
-
- double deltaF = [event deltaY];
-
- if (deltaF == 0.0) deltaF = [event deltaX]; // make blender decide if it's horizontal scroll
- if (deltaF == 0.0) break; //discard trackpad delta=0 events
-
- delta = deltaF > 0.0 ? 1 : -1;
- pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta));
- }
- else {
- NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
- GHOST_TInt32 x, y;
- double dx;
- double dy;
-
- /* with 10.7 nice scrolling deltas are supported */
- dx = [event scrollingDeltaX];
- dy = [event scrollingDeltaY];
-
- /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */
- if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) {
- dx = [event deltaX];
- dy = [event deltaY];
- }
- window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
-
- pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
- }
- }
- break;
-
- case NSEventTypeMagnify:
- {
- NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
- GHOST_TInt32 x, y;
- window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
- pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventMagnify, x, y,
- [event magnification] * 125.0 + 0.1, 0));
- }
- break;
-
- case NSEventTypeRotate:
- {
- NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
- GHOST_TInt32 x, y;
- window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
- pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y,
- [event rotation] * -5.0, 0));
- }
- default:
- return GHOST_kFailure;
- break;
- }
-
- return GHOST_kSuccess;
+ NSEvent *event = (NSEvent *)eventPtr;
+ GHOST_WindowCocoa *window;
+ CocoaWindow *cocoawindow;
+
+ /* [event window] returns other windows if mouse-over, that's OSX input standard
+ however, if mouse exits window(s), the windows become inactive, until you click.
+ We then fall back to the active window from ghost */
+ window = (GHOST_WindowCocoa *)m_windowManager->getWindowAssociatedWithOSWindow(
+ (void *)[event window]);
+ if (!window) {
+ window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow();
+ if (!window) {
+ //printf("\nW failure for event 0x%x",[event type]);
+ return GHOST_kFailure;
+ }
+ }
+
+ cocoawindow = (CocoaWindow *)window->getOSWindow();
+
+ switch ([event type]) {
+ case NSLeftMouseDown:
+ pushEvent(new GHOST_EventButton(
+ [event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft));
+ handleTabletEvent(event); //Handle tablet events combined with mouse events
+ break;
+ case NSRightMouseDown:
+ pushEvent(new GHOST_EventButton(
+ [event timestamp] * 1000, GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight));
+ handleTabletEvent(event); //Handle tablet events combined with mouse events
+ break;
+ case NSOtherMouseDown:
+ pushEvent(new GHOST_EventButton([event timestamp] * 1000,
+ GHOST_kEventButtonDown,
+ window,
+ convertButton([event buttonNumber])));
+ handleTabletEvent(event); //Handle tablet events combined with mouse events
+ break;
+
+ case NSLeftMouseUp:
+ pushEvent(new GHOST_EventButton(
+ [event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft));
+ handleTabletEvent(event); //Handle tablet events combined with mouse events
+ break;
+ case NSRightMouseUp:
+ pushEvent(new GHOST_EventButton(
+ [event timestamp] * 1000, GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight));
+ handleTabletEvent(event); //Handle tablet events combined with mouse events
+ break;
+ case NSOtherMouseUp:
+ pushEvent(new GHOST_EventButton([event timestamp] * 1000,
+ GHOST_kEventButtonUp,
+ window,
+ convertButton([event buttonNumber])));
+ handleTabletEvent(event); //Handle tablet events combined with mouse events
+ break;
+
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ //Handle tablet events combined with mouse events
+ handleTabletEvent(event);
+
+ case NSMouseMoved: {
+ GHOST_TGrabCursorMode grab_mode = window->getCursorGrabMode();
+
+ /* TODO: CHECK IF THIS IS A TABLET EVENT */
+ bool is_tablet = false;
+
+ if (is_tablet && window->getCursorGrabModeIsWarp()) {
+ grab_mode = GHOST_kGrabDisable;
+ }
+
+ switch (grab_mode) {
+ case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move
+ {
+ GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y;
+
+ window->getCursorGrabInitPos(x_warp, y_warp);
+ window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp);
+
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x_accum += [event deltaX];
+ y_accum += -[event
+ deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
+ window->setCursorGrabAccum(x_accum, y_accum);
+
+ window->clientToScreenIntern(x_warp + x_accum, y_warp + y_accum, x, y);
+ pushEvent(new GHOST_EventCursor(
+ [event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
+ break;
+ }
+ case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
+ {
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
+ GHOST_TInt32 x_mouse = mousePos.x;
+ GHOST_TInt32 y_mouse = mousePos.y;
+ GHOST_Rect bounds, windowBounds, correctedBounds;
+
+ /* fallback to window bounds */
+ if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
+ window->getClientBounds(bounds);
+
+ //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
+ window->getClientBounds(windowBounds);
+ window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_t);
+ window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b);
+ correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b;
+ correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t;
+
+ //Get accumulation from previous mouse warps
+ GHOST_TInt32 x_accum, y_accum;
+ window->getCursorGrabAccum(x_accum, y_accum);
+
+ //Warp mouse cursor if needed
+ GHOST_TInt32 warped_x_mouse = x_mouse;
+ GHOST_TInt32 warped_y_mouse = y_mouse;
+ correctedBounds.wrapPoint(warped_x_mouse, warped_y_mouse, 4);
+
+ //Set new cursor position
+ if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) {
+ GHOST_TInt32 warped_x, warped_y;
+ window->clientToScreenIntern(warped_x_mouse, warped_y_mouse, warped_x, warped_y);
+ setMouseCursorPosition(warped_x, warped_y); /* wrap */
+ window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse),
+ y_accum + (y_mouse - warped_y_mouse));
+ }
+
+ //Generate event
+ GHOST_TInt32 x, y;
+ window->clientToScreenIntern(x_mouse + x_accum, y_mouse + y_accum, x, y);
+ pushEvent(new GHOST_EventCursor(
+ [event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
+ break;
+ }
+ default: {
+ //Normal cursor operation: send mouse position in window
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
+ GHOST_TInt32 x, y;
+
+ window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+ pushEvent(new GHOST_EventCursor(
+ [event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
+ break;
+ }
+ }
+ } break;
+
+ case NSScrollWheel: {
+ NSEventPhase momentumPhase = NSEventPhaseNone;
+ NSEventPhase phase = NSEventPhaseNone;
+
+ if ([event respondsToSelector:@selector(momentumPhase)])
+ momentumPhase = [event momentumPhase];
+ if ([event respondsToSelector:@selector(phase)])
+ phase = [event phase];
+
+ /* when pressing a key while momentum scrolling continues after
+ * lifting fingers off the trackpad, the action can unexpectedly
+ * change from e.g. scrolling to zooming. this works around the
+ * issue by ignoring momentum scroll after a key press */
+ if (momentumPhase) {
+ if (m_ignoreMomentumScroll)
+ break;
+ }
+ else {
+ m_ignoreMomentumScroll = false;
+ }
+
+ /* we assume phases are only set for gestures from trackpad or magic
+ * mouse events. note that using tablet at the same time may not work
+ * since this is a static variable */
+ if (phase == NSEventPhaseBegan)
+ m_multiTouchScroll = true;
+ else if (phase == NSEventPhaseEnded)
+ m_multiTouchScroll = false;
+
+ /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */
+ if (!m_multiTouchScroll && momentumPhase == NSEventPhaseNone) {
+ GHOST_TInt32 delta;
+
+ double deltaF = [event deltaY];
+
+ if (deltaF == 0.0)
+ deltaF = [event deltaX]; // make blender decide if it's horizontal scroll
+ if (deltaF == 0.0)
+ break; //discard trackpad delta=0 events
+
+ delta = deltaF > 0.0 ? 1 : -1;
+ pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta));
+ }
+ else {
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
+ GHOST_TInt32 x, y;
+ double dx;
+ double dy;
+
+ /* with 10.7 nice scrolling deltas are supported */
+ dx = [event scrollingDeltaX];
+ dy = [event scrollingDeltaY];
+
+ /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */
+ if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) {
+ dx = [event deltaX];
+ dy = [event deltaY];
+ }
+ window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+
+ pushEvent(new GHOST_EventTrackpad(
+ [event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
+ }
+ } break;
+
+ case NSEventTypeMagnify: {
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
+ GHOST_TInt32 x, y;
+ window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+ pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000,
+ window,
+ GHOST_kTrackpadEventMagnify,
+ x,
+ y,
+ [event magnification] * 125.0 + 0.1,
+ 0));
+ } break;
+
+ case NSEventTypeRotate: {
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
+ GHOST_TInt32 x, y;
+ window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+ pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000,
+ window,
+ GHOST_kTrackpadEventRotate,
+ x,
+ y,
+ [event rotation] * -5.0,
+ 0));
+ }
+ default:
+ return GHOST_kFailure;
+ break;
+ }
+
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
{
- NSEvent *event = (NSEvent *)eventPtr;
- GHOST_IWindow* window;
- unsigned int modifiers;
- NSString *characters;
- NSData *convertedCharacters;
- GHOST_TKey keyCode;
- unsigned char ascii;
- NSString* charsIgnoringModifiers;
-
- window = m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
- if (!window) {
- //printf("\nW failure for event 0x%x",[event type]);
- return GHOST_kFailure;
- }
-
- char utf8_buf[6]= {'\0'};
- ascii = 0;
-
- switch ([event type]) {
-
- case NSKeyDown:
- case NSKeyUp:
- charsIgnoringModifiers = [event charactersIgnoringModifiers];
- if ([charsIgnoringModifiers length] > 0) {
- keyCode = convertKey([event keyCode],
- [charsIgnoringModifiers characterAtIndex:0],
- [event type] == NSKeyDown?kUCKeyActionDown:kUCKeyActionUp);
- }
- else {
- keyCode = convertKey([event keyCode],0,
- [event type] == NSKeyDown?kUCKeyActionDown:kUCKeyActionUp);
- }
-
- /* handling both unicode or ascii */
- characters = [event characters];
- if ([characters length] > 0) {
- convertedCharacters = [characters dataUsingEncoding:NSUTF8StringEncoding];
-
- for (int x = 0; x < [convertedCharacters length]; x++) {
- utf8_buf[x] = ((char*)[convertedCharacters bytes])[x];
- }
- }
-
- /* arrow keys should not have utf8 */
- if ((keyCode > 266) && (keyCode < 271))
- utf8_buf[0] = '\0';
-
- /* F keys should not have utf8 */
- if ((keyCode >= GHOST_kKeyF1) && (keyCode <= GHOST_kKeyF20))
- utf8_buf[0] = '\0';
-
- /* no text with command key pressed */
- if (m_modifierMask & NSCommandKeyMask)
- utf8_buf[0] = '\0';
-
- if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
- break; //Cmd-Q is directly handled by Cocoa
-
- /* ascii is a subset of unicode */
- if (utf8_buf[0] && !utf8_buf[1]) {
- ascii = utf8_buf[0];
- }
-
- if ([event type] == NSKeyDown) {
- pushEvent(new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyDown, window, keyCode, ascii, utf8_buf));
- //printf("Key down rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf);
- }
- else {
- pushEvent(new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL));
- //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf);
- }
- m_ignoreMomentumScroll = true;
- break;
-
- case NSFlagsChanged:
- modifiers = [event modifierFlags];
-
- if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
- pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift));
- }
- if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
- pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl));
- }
- if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
- pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt));
- }
- if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
- pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyOS));
- }
-
- m_modifierMask = modifiers;
- m_ignoreMomentumScroll = true;
- break;
-
- default:
- return GHOST_kFailure;
- break;
- }
-
- return GHOST_kSuccess;
+ NSEvent *event = (NSEvent *)eventPtr;
+ GHOST_IWindow *window;
+ unsigned int modifiers;
+ NSString *characters;
+ NSData *convertedCharacters;
+ GHOST_TKey keyCode;
+ unsigned char ascii;
+ NSString *charsIgnoringModifiers;
+
+ window = m_windowManager->getWindowAssociatedWithOSWindow((void *)[event window]);
+ if (!window) {
+ //printf("\nW failure for event 0x%x",[event type]);
+ return GHOST_kFailure;
+ }
+
+ char utf8_buf[6] = {'\0'};
+ ascii = 0;
+
+ switch ([event type]) {
+
+ case NSKeyDown:
+ case NSKeyUp:
+ charsIgnoringModifiers = [event charactersIgnoringModifiers];
+ if ([charsIgnoringModifiers length] > 0) {
+ keyCode = convertKey([event keyCode],
+ [charsIgnoringModifiers characterAtIndex:0],
+ [event type] == NSKeyDown ? kUCKeyActionDown : kUCKeyActionUp);
+ }
+ else {
+ keyCode = convertKey(
+ [event keyCode], 0, [event type] == NSKeyDown ? kUCKeyActionDown : kUCKeyActionUp);
+ }
+
+ /* handling both unicode or ascii */
+ characters = [event characters];
+ if ([characters length] > 0) {
+ convertedCharacters = [characters dataUsingEncoding:NSUTF8StringEncoding];
+
+ for (int x = 0; x < [convertedCharacters length]; x++) {
+ utf8_buf[x] = ((char *)[convertedCharacters bytes])[x];
+ }
+ }
+
+ /* arrow keys should not have utf8 */
+ if ((keyCode > 266) && (keyCode < 271))
+ utf8_buf[0] = '\0';
+
+ /* F keys should not have utf8 */
+ if ((keyCode >= GHOST_kKeyF1) && (keyCode <= GHOST_kKeyF20))
+ utf8_buf[0] = '\0';
+
+ /* no text with command key pressed */
+ if (m_modifierMask & NSCommandKeyMask)
+ utf8_buf[0] = '\0';
+
+ if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
+ break; //Cmd-Q is directly handled by Cocoa
+
+ /* ascii is a subset of unicode */
+ if (utf8_buf[0] && !utf8_buf[1]) {
+ ascii = utf8_buf[0];
+ }
+
+ if ([event type] == NSKeyDown) {
+ pushEvent(new GHOST_EventKey(
+ [event timestamp] * 1000, GHOST_kEventKeyDown, window, keyCode, ascii, utf8_buf));
+ //printf("Key down rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf);
+ }
+ else {
+ pushEvent(new GHOST_EventKey(
+ [event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL));
+ //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf);
+ }
+ m_ignoreMomentumScroll = true;
+ break;
+
+ case NSFlagsChanged:
+ modifiers = [event modifierFlags];
+
+ if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
+ pushEvent(new GHOST_EventKey([event timestamp] * 1000,
+ (modifiers & NSShiftKeyMask) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyLeftShift));
+ }
+ if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
+ pushEvent(new GHOST_EventKey([event timestamp] * 1000,
+ (modifiers & NSControlKeyMask) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyLeftControl));
+ }
+ if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
+ pushEvent(new GHOST_EventKey([event timestamp] * 1000,
+ (modifiers & NSAlternateKeyMask) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyLeftAlt));
+ }
+ if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
+ pushEvent(new GHOST_EventKey([event timestamp] * 1000,
+ (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp,
+ window,
+ GHOST_kKeyOS));
+ }
+
+ m_modifierMask = modifiers;
+ m_ignoreMomentumScroll = true;
+ break;
+
+ default:
+ return GHOST_kFailure;
+ break;
+ }
+
+ return GHOST_kSuccess;
}
-
#pragma mark Clipboard get/set
-GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const
+GHOST_TUns8 *GHOST_SystemCocoa::getClipboard(bool selection) const
{
- GHOST_TUns8 * temp_buff;
- size_t pastedTextSize;
+ GHOST_TUns8 *temp_buff;
+ size_t pastedTextSize;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
+ NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
- if (pasteBoard == nil) {
- [pool drain];
- return NULL;
- }
+ if (pasteBoard == nil) {
+ [pool drain];
+ return NULL;
+ }
- NSArray *supportedTypes =
- [NSArray arrayWithObjects: NSStringPboardType, nil];
+ NSArray *supportedTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
- NSString *bestType = [[NSPasteboard generalPasteboard] availableTypeFromArray:supportedTypes];
+ NSString *bestType = [[NSPasteboard generalPasteboard] availableTypeFromArray:supportedTypes];
- if (bestType == nil) {
- [pool drain];
- return NULL;
- }
+ if (bestType == nil) {
+ [pool drain];
+ return NULL;
+ }
- NSString *textPasted = [pasteBoard stringForType:NSStringPboardType];
+ NSString *textPasted = [pasteBoard stringForType:NSStringPboardType];
- if (textPasted == nil) {
- [pool drain];
- return NULL;
- }
+ if (textPasted == nil) {
+ [pool drain];
+ return NULL;
+ }
- pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+ pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
- temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1);
+ temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1);
- if (temp_buff == NULL) {
- [pool drain];
- return NULL;
- }
+ if (temp_buff == NULL) {
+ [pool drain];
+ return NULL;
+ }
- strncpy((char*)temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
+ strncpy(
+ (char *)temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
- temp_buff[pastedTextSize] = '\0';
+ temp_buff[pastedTextSize] = '\0';
- [pool drain];
+ [pool drain];
- if (temp_buff) {
- return temp_buff;
- }
- else {
- return NULL;
- }
+ if (temp_buff) {
+ return temp_buff;
+ }
+ else {
+ return NULL;
+ }
}
void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
{
- NSString *textToCopy;
+ NSString *textToCopy;
- if (selection) return; // for copying the selection, used on X11
+ if (selection)
+ return; // for copying the selection, used on X11
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
+ NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
- if (pasteBoard == nil) {
- [pool drain];
- return;
- }
+ if (pasteBoard == nil) {
+ [pool drain];
+ return;
+ }
- NSArray *supportedTypes = [NSArray arrayWithObject:NSStringPboardType];
+ NSArray *supportedTypes = [NSArray arrayWithObject:NSStringPboardType];
- [pasteBoard declareTypes:supportedTypes owner:nil];
+ [pasteBoard declareTypes:supportedTypes owner:nil];
- textToCopy = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
+ textToCopy = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
- [pasteBoard setString:textToCopy forType:NSStringPboardType];
+ [pasteBoard setString:textToCopy forType:NSStringPboardType];
- [pool drain];
+ [pool drain];
}
-bool
-GHOST_SystemCocoa::supportsNativeDialogs(void)
+bool GHOST_SystemCocoa::supportsNativeDialogs(void)
{
- return false;
+ return false;
}
diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h
index 19e87bffd78..7f68c801a70 100644
--- a/intern/ghost/intern/GHOST_SystemNULL.h
+++ b/intern/ghost/intern/GHOST_SystemNULL.h
@@ -30,55 +30,109 @@
class GHOST_WindowNULL;
class GHOST_SystemNULL : public GHOST_System {
-public:
+ public:
+ GHOST_SystemNULL() : GHOST_System()
+ { /* nop */
+ }
+ ~GHOST_SystemNULL()
+ { /* nop */
+ }
+ bool processEvents(bool waitForEvent)
+ {
+ return false;
+ }
+ int toggleConsole(int action)
+ {
+ return 0;
+ }
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TUns8 *getClipboard(bool selection) const
+ {
+ return NULL;
+ }
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const
+ { /* nop */
+ }
+ GHOST_TUns64 getMilliSeconds() const
+ {
+ return 0;
+ }
+ GHOST_TUns8 getNumDisplays() const
+ {
+ return GHOST_TUns8(1);
+ }
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
+ {
+ return GHOST_kFailure;
+ }
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
+ {
+ return GHOST_kFailure;
+ }
+ void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
+ { /* nop */
+ }
+ void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
+ { /* nop */
+ }
+ bool supportsNativeDialogs(void)
+ {
+ return false;
+ }
+ GHOST_IContext *createOffscreenContext()
+ {
+ return NULL;
+ }
+ GHOST_TSuccess disposeContext(GHOST_IContext *context)
+ {
+ return GHOST_kFailure;
+ }
- GHOST_SystemNULL() : GHOST_System() { /* nop */ }
- ~GHOST_SystemNULL() { /* nop */ }
- bool processEvents(bool waitForEvent) { return false; }
- int toggleConsole(int action) { return 0; }
- GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const { return GHOST_kSuccess; }
- GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const { return GHOST_kSuccess; }
- GHOST_TUns8 *getClipboard(bool selection) const { return NULL; }
- void putClipboard(GHOST_TInt8 *buffer, bool selection) const { /* nop */ }
- GHOST_TUns64 getMilliSeconds() const { return 0; }
- GHOST_TUns8 getNumDisplays() const { return GHOST_TUns8(1); }
- GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const { return GHOST_kFailure; }
- GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { return GHOST_kFailure; }
- void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ }
- void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ }
- bool supportsNativeDialogs(void) { return false;}
- GHOST_IContext *createOffscreenContext() { return NULL; }
- GHOST_TSuccess disposeContext(GHOST_IContext *context) { return GHOST_kFailure; }
+ GHOST_TSuccess init()
+ {
+ GHOST_TSuccess success = GHOST_System::init();
- GHOST_TSuccess init() {
- GHOST_TSuccess success = GHOST_System::init();
+ if (success) {
+ m_displayManager = new GHOST_DisplayManagerNULL(this);
- if (success) {
- m_displayManager = new GHOST_DisplayManagerNULL(this);
+ if (m_displayManager) {
+ return GHOST_kSuccess;
+ }
+ }
- if (m_displayManager) {
- return GHOST_kSuccess;
- }
- }
+ return GHOST_kFailure;
+ }
- return GHOST_kFailure;
- }
-
- GHOST_IWindow *createWindow(
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- bool exclusive,
- const GHOST_TEmbedderWindowID parentWindow)
- {
- return new GHOST_WindowNULL(this, title, left, top, width, height, state, parentWindow, type,
- ((glSettings.flags & GHOST_glStereoVisual) != 0), 1);
- }
+ GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ bool exclusive,
+ const GHOST_TEmbedderWindowID parentWindow)
+ {
+ return new GHOST_WindowNULL(this,
+ title,
+ left,
+ top,
+ width,
+ height,
+ state,
+ parentWindow,
+ type,
+ ((glSettings.flags & GHOST_glStereoVisual) != 0),
+ 1);
+ }
};
-#endif /* __GHOST_SYSTEMNULL_H__ */
+#endif /* __GHOST_SYSTEMNULL_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemPaths.h b/intern/ghost/intern/GHOST_SystemPaths.h
index d8bcc3de99a..04180a143cb 100644
--- a/intern/ghost/intern/GHOST_SystemPaths.h
+++ b/intern/ghost/intern/GHOST_SystemPaths.h
@@ -26,47 +26,49 @@
#include "GHOST_ISystemPaths.h"
-class GHOST_SystemPaths : public GHOST_ISystemPaths
-{
-protected:
- /**
- * Constructor.
- * Protected default constructor to force use of static createSystem member.
- */
- GHOST_SystemPaths() {}
+class GHOST_SystemPaths : public GHOST_ISystemPaths {
+ protected:
+ /**
+ * Constructor.
+ * Protected default constructor to force use of static createSystem member.
+ */
+ GHOST_SystemPaths()
+ {
+ }
- /**
- * Destructor.
- * Protected default constructor to force use of static dispose member.
- */
- virtual ~GHOST_SystemPaths() {}
+ /**
+ * Destructor.
+ * Protected default constructor to force use of static dispose member.
+ */
+ virtual ~GHOST_SystemPaths()
+ {
+ }
-public:
+ public:
+ /**
+ * Determine the base dir in which shared resources are located. It will first try to use
+ * "unpack and run" path, then look for properly installed path, including versioning.
+ * \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
+ */
+ virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0;
- /**
- * Determine the base dir in which shared resources are located. It will first try to use
- * "unpack and run" path, then look for properly installed path, including versioning.
- * \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
- */
- virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0;
+ /**
+ * Determine the base dir in which user configuration is stored, including versioning.
+ * If needed, it will create the base directory.
+ * \return Unsigned char string pointing to user dir (eg ~/.blender/).
+ */
+ virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0;
- /**
- * Determine the base dir in which user configuration is stored, including versioning.
- * If needed, it will create the base directory.
- * \return Unsigned char string pointing to user dir (eg ~/.blender/).
- */
- virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0;
+ /**
+ * Determine the directory of the current binary
+ * \return Unsigned char string pointing to the binary dir
+ */
+ virtual const GHOST_TUns8 *getBinaryDir() const = 0;
- /**
- * Determine the directory of the current binary
- * \return Unsigned char string pointing to the binary dir
- */
- virtual const GHOST_TUns8 *getBinaryDir() const = 0;
-
- /**
- * Add the file to the operating system most recently used files
- */
- virtual void addToSystemRecentFiles(const char *filename) const = 0;
+ /**
+ * Add the file to the operating system most recently used files
+ */
+ virtual void addToSystemRecentFiles(const char *filename) const = 0;
};
#endif
diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.h b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
index 746f4933012..b66379649e7 100644
--- a/intern/ghost/intern/GHOST_SystemPathsCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
@@ -21,54 +21,51 @@
* \ingroup GHOST
*/
-
#ifndef __GHOST_SYSTEMPATHSCOCOA_H__
#define __GHOST_SYSTEMPATHSCOCOA_H__
#ifndef __APPLE__
-#error Apple OSX only!
-#endif // __APPLE__
-
+# error Apple OSX only!
+#endif // __APPLE__
#include "GHOST_SystemPaths.h"
-
class GHOST_SystemPathsCocoa : public GHOST_SystemPaths {
-public:
- /**
- * Constructor.
- */
- GHOST_SystemPathsCocoa();
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_SystemPathsCocoa();
- /**
- * Destructor.
- */
- ~GHOST_SystemPathsCocoa();
+ /**
+ * Destructor.
+ */
+ ~GHOST_SystemPathsCocoa();
- /**
- * Determine the base dir in which shared resources are located. It will first try to use
- * "unpack and run" path, then look for properly installed path, including versioning.
- * \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
- */
- const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
+ /**
+ * Determine the base dir in which shared resources are located. It will first try to use
+ * "unpack and run" path, then look for properly installed path, including versioning.
+ * \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
+ */
+ const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
- /**
- * Determine the base dir in which user configuration is stored, including versioning.
- * If needed, it will create the base directory.
- * \return Unsigned char string pointing to user dir (eg ~/.blender/).
- */
- const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
+ /**
+ * Determine the base dir in which user configuration is stored, including versioning.
+ * If needed, it will create the base directory.
+ * \return Unsigned char string pointing to user dir (eg ~/.blender/).
+ */
+ const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
- /**
- * Determine the directory of the current binary
- * \return Unsigned char string pointing to the binary dir
- */
- const GHOST_TUns8 *getBinaryDir() const;
+ /**
+ * Determine the directory of the current binary
+ * \return Unsigned char string pointing to the binary dir
+ */
+ const GHOST_TUns8 *getBinaryDir() const;
- /**
- * Add the file to the operating system most recently used files
- */
- void addToSystemRecentFiles(const char *filename) const;
+ /**
+ * Add the file to the operating system most recently used files
+ */
+ void addToSystemRecentFiles(const char *filename) const;
};
-#endif // __GHOST_SYSTEMPATHSCOCOA_H__
+#endif // __GHOST_SYSTEMPATHSCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm
index fd6a66f3db3..232ef048351 100644
--- a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm
@@ -23,10 +23,8 @@
#include "GHOST_SystemPathsCocoa.h"
-
#pragma mark initialization/finalization
-
GHOST_SystemPathsCocoa::GHOST_SystemPathsCocoa()
{
}
@@ -35,73 +33,82 @@ GHOST_SystemPathsCocoa::~GHOST_SystemPathsCocoa()
{
}
-
#pragma mark Base directories retrieval
-const GHOST_TUns8* GHOST_SystemPathsCocoa::getSystemDir(int, const char *versionstr) const
+const GHOST_TUns8 *GHOST_SystemPathsCocoa::getSystemDir(int, const char *versionstr) const
{
- static char tempPath[512] = "";
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSString *basePath;
- NSArray *paths;
-
- paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSLocalDomainMask, YES);
-
- if ([paths count] > 0)
- basePath = [paths objectAtIndex:0];
- else {
- [pool drain];
- return NULL;
- }
-
- snprintf(tempPath, sizeof(tempPath), "%s/Blender/%s", [basePath cStringUsingEncoding:NSASCIIStringEncoding], versionstr);
-
- [pool drain];
- return (GHOST_TUns8*)tempPath;
+ static char tempPath[512] = "";
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString *basePath;
+ NSArray *paths;
+
+ paths = NSSearchPathForDirectoriesInDomains(
+ NSApplicationSupportDirectory, NSLocalDomainMask, YES);
+
+ if ([paths count] > 0)
+ basePath = [paths objectAtIndex:0];
+ else {
+ [pool drain];
+ return NULL;
+ }
+
+ snprintf(tempPath,
+ sizeof(tempPath),
+ "%s/Blender/%s",
+ [basePath cStringUsingEncoding:NSASCIIStringEncoding],
+ versionstr);
+
+ [pool drain];
+ return (GHOST_TUns8 *)tempPath;
}
-const GHOST_TUns8* GHOST_SystemPathsCocoa::getUserDir(int, const char *versionstr) const
+const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserDir(int, const char *versionstr) const
{
- static char tempPath[512] = "";
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSString *basePath;
- NSArray *paths;
-
- paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
-
- if ([paths count] > 0)
- basePath = [paths objectAtIndex:0];
- else {
- [pool drain];
- return NULL;
- }
-
- snprintf(tempPath, sizeof(tempPath), "%s/Blender/%s", [basePath cStringUsingEncoding:NSASCIIStringEncoding], versionstr);
-
- [pool drain];
- return (GHOST_TUns8*)tempPath;
+ static char tempPath[512] = "";
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString *basePath;
+ NSArray *paths;
+
+ paths = NSSearchPathForDirectoriesInDomains(
+ NSApplicationSupportDirectory, NSUserDomainMask, YES);
+
+ if ([paths count] > 0)
+ basePath = [paths objectAtIndex:0];
+ else {
+ [pool drain];
+ return NULL;
+ }
+
+ snprintf(tempPath,
+ sizeof(tempPath),
+ "%s/Blender/%s",
+ [basePath cStringUsingEncoding:NSASCIIStringEncoding],
+ versionstr);
+
+ [pool drain];
+ return (GHOST_TUns8 *)tempPath;
}
-const GHOST_TUns8* GHOST_SystemPathsCocoa::getBinaryDir() const
+const GHOST_TUns8 *GHOST_SystemPathsCocoa::getBinaryDir() const
{
- static GHOST_TUns8 tempPath[512] = "";
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSString *basePath;
+ static GHOST_TUns8 tempPath[512] = "";
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString *basePath;
- basePath = [[NSBundle mainBundle] bundlePath];
+ basePath = [[NSBundle mainBundle] bundlePath];
- if (basePath == nil) {
- [pool drain];
- return NULL;
- }
+ if (basePath == nil) {
+ [pool drain];
+ return NULL;
+ }
- strcpy((char*)tempPath, [basePath cStringUsingEncoding:NSASCIIStringEncoding]);
+ strcpy((char *)tempPath, [basePath cStringUsingEncoding:NSASCIIStringEncoding]);
- [pool drain];
- return tempPath;
+ [pool drain];
+ return tempPath;
}
-void GHOST_SystemPathsCocoa::addToSystemRecentFiles(const char* filename) const
+void GHOST_SystemPathsCocoa::addToSystemRecentFiles(const char *filename) const
{
- /* XXXXX TODO: Implementation for X11 if possible */
+ /* XXXXX TODO: Implementation for X11 if possible */
}
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
index 94e058f3dac..94e48f98510 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
@@ -30,10 +30,10 @@
#include <sys/time.h>
#include <unistd.h>
-#include <stdio.h> /* for fprintf only */
-#include <cstdlib> /* for exit */
+#include <stdio.h> /* for fprintf only */
+#include <cstdlib> /* for exit */
-#include <pwd.h> /* for get home without use getenv() */
+#include <pwd.h> /* for get home without use getenv() */
#include <string>
using std::string;
@@ -54,67 +54,66 @@ GHOST_SystemPathsUnix::~GHOST_SystemPathsUnix()
const GHOST_TUns8 *GHOST_SystemPathsUnix::getSystemDir(int, const char *versionstr) const
{
- /* no prefix assumes a portable build which only uses bundled scripts */
- if (static_path) {
- static string system_path = string(static_path) + "/blender/" + versionstr;
- return (GHOST_TUns8 *)system_path.c_str();
- }
+ /* no prefix assumes a portable build which only uses bundled scripts */
+ if (static_path) {
+ static string system_path = string(static_path) + "/blender/" + versionstr;
+ return (GHOST_TUns8 *)system_path.c_str();
+ }
- return NULL;
+ return NULL;
}
const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserDir(int version, const char *versionstr) const
{
- static string user_path = "";
- static int last_version = 0;
-
- /* in blender 2.64, we migrate to XDG. to ensure the copy previous settings
- * operator works we give a different path depending on the requested version */
- if (version < 264) {
- if (user_path.empty() || last_version != version) {
- const char *home = getenv("HOME");
-
- last_version = version;
-
- if (home) {
- user_path = string(home) + "/.blender/" + versionstr;
- }
- else {
- return NULL;
- }
- }
- return (GHOST_TUns8 *)user_path.c_str();
- }
- else {
- if (user_path.empty() || last_version != version) {
- const char *home = getenv("XDG_CONFIG_HOME");
-
- last_version = version;
-
- if (home) {
- user_path = string(home) + "/blender/" + versionstr;
- }
- else {
- home = getenv("HOME");
-
- if (home == NULL)
- home = getpwuid(getuid())->pw_dir;
-
- user_path = string(home) + "/.config/blender/" + versionstr;
- }
- }
-
- return (const GHOST_TUns8 *)user_path.c_str();
- }
+ static string user_path = "";
+ static int last_version = 0;
+
+ /* in blender 2.64, we migrate to XDG. to ensure the copy previous settings
+ * operator works we give a different path depending on the requested version */
+ if (version < 264) {
+ if (user_path.empty() || last_version != version) {
+ const char *home = getenv("HOME");
+
+ last_version = version;
+
+ if (home) {
+ user_path = string(home) + "/.blender/" + versionstr;
+ }
+ else {
+ return NULL;
+ }
+ }
+ return (GHOST_TUns8 *)user_path.c_str();
+ }
+ else {
+ if (user_path.empty() || last_version != version) {
+ const char *home = getenv("XDG_CONFIG_HOME");
+
+ last_version = version;
+
+ if (home) {
+ user_path = string(home) + "/blender/" + versionstr;
+ }
+ else {
+ home = getenv("HOME");
+
+ if (home == NULL)
+ home = getpwuid(getuid())->pw_dir;
+
+ user_path = string(home) + "/.config/blender/" + versionstr;
+ }
+ }
+
+ return (const GHOST_TUns8 *)user_path.c_str();
+ }
}
const GHOST_TUns8 *GHOST_SystemPathsUnix::getBinaryDir() const
{
- return NULL;
+ return NULL;
}
void GHOST_SystemPathsUnix::addToSystemRecentFiles(const char * /*filename*/) const
{
- /* XXXXX TODO: Implementation for X11 if possible */
-
+ /* XXXXX TODO: Implementation for X11 if possible */
}
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.h b/intern/ghost/intern/GHOST_SystemPathsUnix.h
index 0bd5690fb1a..bcbe24b0d31 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.h
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.h
@@ -21,52 +21,49 @@
* \ingroup GHOST
*/
-
#ifndef __GHOST_SYSTEMPATHSUNIX_H__
#define __GHOST_SYSTEMPATHSUNIX_H__
#include "GHOST_SystemPaths.h"
#include "../GHOST_Types.h"
-
class GHOST_SystemPathsUnix : public GHOST_SystemPaths {
-public:
-
- /**
- * Constructor
- * this class should only be instanciated by GHOST_ISystem.
- */
- GHOST_SystemPathsUnix();
+ public:
+ /**
+ * Constructor
+ * this class should only be instanciated by GHOST_ISystem.
+ */
+ GHOST_SystemPathsUnix();
- /**
- * Destructor.
- */
- ~GHOST_SystemPathsUnix();
+ /**
+ * Destructor.
+ */
+ ~GHOST_SystemPathsUnix();
- /**
- * Determine the base dir in which shared resources are located. It will first try to use
- * "unpack and run" path, then look for properly installed path, including versioning.
- * \return Unsigned char string pointing to system dir (eg `/usr/share/blender/`).
- */
- const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
+ /**
+ * Determine the base dir in which shared resources are located. It will first try to use
+ * "unpack and run" path, then look for properly installed path, including versioning.
+ * \return Unsigned char string pointing to system dir (eg `/usr/share/blender/`).
+ */
+ const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
- /**
- * Determine the base dir in which user configuration is stored, including versioning.
- * If needed, it will create the base directory.
- * \return Unsigned char string pointing to user dir (eg `~/.config/.blender/`).
- */
- const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
+ /**
+ * Determine the base dir in which user configuration is stored, including versioning.
+ * If needed, it will create the base directory.
+ * \return Unsigned char string pointing to user dir (eg `~/.config/.blender/`).
+ */
+ const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
- /**
- * Determine the directory of the current binary
- * \return Unsigned char string pointing to the binary dir
- */
- const GHOST_TUns8 *getBinaryDir() const;
+ /**
+ * Determine the directory of the current binary
+ * \return Unsigned char string pointing to the binary dir
+ */
+ const GHOST_TUns8 *getBinaryDir() const;
- /**
- * Add the file to the operating system most recently used files
- */
- void addToSystemRecentFiles(const char *filename) const;
+ /**
+ * Add the file to the operating system most recently used files
+ */
+ void addToSystemRecentFiles(const char *filename) const;
};
-#endif /* __GHOST_SYSTEMPATHSUNIX_H__ */
+#endif /* __GHOST_SYSTEMPATHSUNIX_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
index a403ef294a2..bdc403b947e 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
@@ -21,11 +21,10 @@
* \ingroup GHOST
*/
-
#include "GHOST_SystemPathsWin32.h"
#ifndef _WIN32_IE
-#define _WIN32_IE 0x0501
+# define _WIN32_IE 0x0501
#endif
#include <shlobj.h>
#include "utfconv.h"
@@ -40,55 +39,57 @@ GHOST_SystemPathsWin32::~GHOST_SystemPathsWin32()
const GHOST_TUns8 *GHOST_SystemPathsWin32::getSystemDir(int, const char *versionstr) const
{
- static char knownpath[MAX_PATH * 3 + 128] = {0}; /* 1 utf-16 might translante into 3 utf-8. 2 utf-16 translates into 4 utf-8*/
- wchar_t knownpath_16[MAX_PATH];
+ static char knownpath[MAX_PATH * 3 + 128] = {
+ 0}; /* 1 utf-16 might translante into 3 utf-8. 2 utf-16 translates into 4 utf-8*/
+ wchar_t knownpath_16[MAX_PATH];
- HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16);
+ HRESULT hResult = SHGetFolderPathW(
+ NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16);
- if (hResult == S_OK) {
- conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3);
- strcat(knownpath, "\\Blender Foundation\\Blender\\");
- strcat(knownpath, versionstr);
- return (GHOST_TUns8*)knownpath;
- }
+ if (hResult == S_OK) {
+ conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3);
+ strcat(knownpath, "\\Blender Foundation\\Blender\\");
+ strcat(knownpath, versionstr);
+ return (GHOST_TUns8 *)knownpath;
+ }
- return NULL;
+ return NULL;
}
const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserDir(int, const char *versionstr) const
{
- static char knownpath[MAX_PATH * 3 + 128] = {0};
- wchar_t knownpath_16[MAX_PATH];
+ static char knownpath[MAX_PATH * 3 + 128] = {0};
+ wchar_t knownpath_16[MAX_PATH];
- HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16);
+ HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16);
- if (hResult == S_OK) {
- conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3);
- strcat(knownpath, "\\Blender Foundation\\Blender\\");
- strcat(knownpath, versionstr);
- return (GHOST_TUns8*)knownpath;
- }
+ if (hResult == S_OK) {
+ conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3);
+ strcat(knownpath, "\\Blender Foundation\\Blender\\");
+ strcat(knownpath, versionstr);
+ return (GHOST_TUns8 *)knownpath;
+ }
- return NULL;
+ return NULL;
}
const GHOST_TUns8 *GHOST_SystemPathsWin32::getBinaryDir() const
{
- static char fullname[MAX_PATH * 3] = {0};
- wchar_t fullname_16[MAX_PATH * 3];
+ static char fullname[MAX_PATH * 3] = {0};
+ wchar_t fullname_16[MAX_PATH * 3];
- if (GetModuleFileNameW(0, fullname_16, MAX_PATH)) {
- conv_utf_16_to_8(fullname_16, fullname, MAX_PATH * 3);
- return (GHOST_TUns8 *)fullname;
- }
+ if (GetModuleFileNameW(0, fullname_16, MAX_PATH)) {
+ conv_utf_16_to_8(fullname_16, fullname, MAX_PATH * 3);
+ return (GHOST_TUns8 *)fullname;
+ }
- return NULL;
+ return NULL;
}
void GHOST_SystemPathsWin32::addToSystemRecentFiles(const char *filename) const
{
- /* SHARD_PATH resolves to SHARD_PATHA for non-UNICODE build */
- UTF16_ENCODE(filename);
- SHAddToRecentDocs(SHARD_PATHW, filename_16);
- UTF16_UN_ENCODE(filename);
+ /* SHARD_PATH resolves to SHARD_PATHA for non-UNICODE build */
+ UTF16_ENCODE(filename);
+ SHAddToRecentDocs(SHARD_PATHW, filename_16);
+ UTF16_UN_ENCODE(filename);
}
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h
index bfb4ef33a68..49d241df633 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.h
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h
@@ -21,62 +21,60 @@
* \ingroup GHOST
*/
-
#ifndef __GHOST_SYSTEMPATHSWIN32_H__
#define __GHOST_SYSTEMPATHSWIN32_H__
#ifndef WIN32
-#error WIN32 only!
-#endif // WIN32
+# error WIN32 only!
+#endif // WIN32
#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "GHOST_SystemPaths.h"
-
/**
* WIN32 Implementation of GHOST_SystemPaths class.
* \see GHOST_SystemPaths.
*/
class GHOST_SystemPathsWin32 : public GHOST_SystemPaths {
-public:
- /**
- * Constructor.
- */
- GHOST_SystemPathsWin32();
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_SystemPathsWin32();
- /**
- * Destructor.
- */
- ~GHOST_SystemPathsWin32();
+ /**
+ * Destructor.
+ */
+ ~GHOST_SystemPathsWin32();
- /**
- * Determine the base dir in which shared resources are located. It will first try to use
- * "unpack and run" path, then look for properly installed path, including versioning.
- * \return Unsigned char string pointing to system dir (eg /usr/share/).
- */
- const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
+ /**
+ * Determine the base dir in which shared resources are located. It will first try to use
+ * "unpack and run" path, then look for properly installed path, including versioning.
+ * \return Unsigned char string pointing to system dir (eg /usr/share/).
+ */
+ const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
- /**
- * Determine the base dir in which user configuration is stored, including versioning.
- * If needed, it will create the base directory.
- * \return Unsigned char string pointing to user dir (eg ~/).
- */
- const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
+ /**
+ * Determine the base dir in which user configuration is stored, including versioning.
+ * If needed, it will create the base directory.
+ * \return Unsigned char string pointing to user dir (eg ~/).
+ */
+ const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
- /**
- * Determine the directory of the current binary
- * \return Unsigned char string pointing to the binary dir
- */
- const GHOST_TUns8 *getBinaryDir() const;
+ /**
+ * Determine the directory of the current binary
+ * \return Unsigned char string pointing to the binary dir
+ */
+ const GHOST_TUns8 *getBinaryDir() const;
- /**
- * Add the file to the operating system most recently used files
- */
- void addToSystemRecentFiles(const char *filename) const;
+ /**
+ * Add the file to the operating system most recently used files
+ */
+ void addToSystemRecentFiles(const char *filename) const;
};
-#endif // __GHOST_SYSTEMPATHSWIN32_H__
+#endif // __GHOST_SYSTEMPATHSWIN32_H__
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
index 362d78c6dbd..044695c115c 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.cpp
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -31,270 +31,268 @@
#include "GHOST_EventButton.h"
#include "GHOST_EventWheel.h"
-GHOST_SystemSDL::GHOST_SystemSDL()
- :
- GHOST_System()
+GHOST_SystemSDL::GHOST_SystemSDL() : GHOST_System()
{
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
- printf("Error initializing SDL: %s\n", SDL_GetError());
- }
-
- /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */
- /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
+ printf("Error initializing SDL: %s\n", SDL_GetError());
+ }
+
+ /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */
+ /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
}
GHOST_SystemSDL::~GHOST_SystemSDL()
{
- SDL_Quit();
+ SDL_Quit();
}
-GHOST_IWindow *
-GHOST_SystemSDL::createWindow(const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive,
- const GHOST_TEmbedderWindowID parentWindow
- )
+GHOST_IWindow *GHOST_SystemSDL::createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive,
+ const GHOST_TEmbedderWindowID parentWindow)
{
- GHOST_WindowSDL *window = NULL;
-
- window = new GHOST_WindowSDL(this, title,
- left, top, width, height,
- state, parentWindow, type,
- ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive,
- glSettings.numOfAASamples);
-
- if (window) {
- if (GHOST_kWindowStateFullScreen == state) {
- SDL_Window *sdl_win = window->getSDLWindow();
- SDL_DisplayMode mode;
-
- static_cast<GHOST_DisplayManagerSDL *> (m_displayManager)->getCurrentDisplayModeSDL(mode);
-
- SDL_SetWindowDisplayMode(sdl_win, &mode);
- SDL_ShowWindow(sdl_win);
- SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
- }
-
- if (window->getValid()) {
- m_windowManager->addWindow(window);
- pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
- }
- else {
- delete window;
- window = NULL;
- }
- }
- return window;
+ GHOST_WindowSDL *window = NULL;
+
+ window = new GHOST_WindowSDL(this,
+ title,
+ left,
+ top,
+ width,
+ height,
+ state,
+ parentWindow,
+ type,
+ ((glSettings.flags & GHOST_glStereoVisual) != 0),
+ exclusive,
+ glSettings.numOfAASamples);
+
+ if (window) {
+ if (GHOST_kWindowStateFullScreen == state) {
+ SDL_Window *sdl_win = window->getSDLWindow();
+ SDL_DisplayMode mode;
+
+ static_cast<GHOST_DisplayManagerSDL *>(m_displayManager)->getCurrentDisplayModeSDL(mode);
+
+ SDL_SetWindowDisplayMode(sdl_win, &mode);
+ SDL_ShowWindow(sdl_win);
+ SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
+ }
+
+ if (window->getValid()) {
+ m_windowManager->addWindow(window);
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ delete window;
+ window = NULL;
+ }
+ }
+ return window;
}
-GHOST_TSuccess
-GHOST_SystemSDL::init() {
- GHOST_TSuccess success = GHOST_System::init();
+GHOST_TSuccess GHOST_SystemSDL::init()
+{
+ GHOST_TSuccess success = GHOST_System::init();
- if (success) {
- m_displayManager = new GHOST_DisplayManagerSDL(this);
+ if (success) {
+ m_displayManager = new GHOST_DisplayManagerSDL(this);
- if (m_displayManager) {
- return GHOST_kSuccess;
- }
- }
+ if (m_displayManager) {
+ return GHOST_kSuccess;
+ }
+ }
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
/**
* Returns the dimensions of the main display on this system.
* \return The dimension of the main display.
*/
-void
-GHOST_SystemSDL::getAllDisplayDimensions(GHOST_TUns32& width,
- GHOST_TUns32& height) const
+void GHOST_SystemSDL::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- SDL_DisplayMode mode;
- SDL_GetDesktopDisplayMode(0, &mode); /* note, always 0 display */
- width = mode.w;
- height = mode.h;
+ SDL_DisplayMode mode;
+ SDL_GetDesktopDisplayMode(0, &mode); /* note, always 0 display */
+ width = mode.w;
+ height = mode.h;
}
-void
-GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32& width,
- GHOST_TUns32& height) const
+void GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- SDL_DisplayMode mode;
- SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */
- width = mode.w;
- height = mode.h;
+ SDL_DisplayMode mode;
+ SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */
+ width = mode.w;
+ height = mode.h;
}
-GHOST_TUns8
-GHOST_SystemSDL::getNumDisplays() const
+GHOST_TUns8 GHOST_SystemSDL::getNumDisplays() const
{
- return SDL_GetNumVideoDisplays();
+ return SDL_GetNumVideoDisplays();
}
-GHOST_IContext *
-GHOST_SystemSDL::createOffscreenContext()
+GHOST_IContext *GHOST_SystemSDL::createOffscreenContext()
{
- GHOST_Context *context = new GHOST_ContextSDL(
- 0,
- 0,
- NULL,
- 0, // profile bit
- 3, 3,
- GHOST_OPENGL_SDL_CONTEXT_FLAGS,
- GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
-
- return NULL;
+ GHOST_Context *context = new GHOST_ContextSDL(0,
+ 0,
+ NULL,
+ 0, // profile bit
+ 3,
+ 3,
+ GHOST_OPENGL_SDL_CONTEXT_FLAGS,
+ GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+
+ return NULL;
}
-GHOST_TSuccess
-GHOST_SystemSDL::disposeContext(GHOST_IContext *context)
+GHOST_TSuccess GHOST_SystemSDL::disposeContext(GHOST_IContext *context)
{
- delete context;
+ delete context;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const
+GHOST_TSuccess GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys &keys) const
{
- SDL_Keymod mod = SDL_GetModState();
+ SDL_Keymod mod = SDL_GetModState();
- keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0);
- keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0);
- keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0);
- keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
- keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
- keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
- keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0);
+ keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0);
+ keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0);
+ keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0);
+ keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
+ keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
+ keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
+ keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-#define GXMAP(k, x, y) case x: k = y; break
+#define GXMAP(k, x, y) \
+ case x: \
+ k = y; \
+ break
-static GHOST_TKey
-convertSDLKey(SDL_Scancode key)
+static GHOST_TKey convertSDLKey(SDL_Scancode key)
{
- GHOST_TKey type;
-
- if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
- type = GHOST_TKey(key - SDL_SCANCODE_A + int(GHOST_kKeyA));
- }
- else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
- type = (key == SDL_SCANCODE_0) ? GHOST_kKey0 : GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1));
- }
- else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
- type = GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
- }
- else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
- type = GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13));
- }
- else {
- switch (key) {
- /* TODO SDL_SCANCODE_NONUSBACKSLASH */
-
- GXMAP(type, SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace);
- GXMAP(type, SDL_SCANCODE_TAB, GHOST_kKeyTab);
- GXMAP(type, SDL_SCANCODE_RETURN, GHOST_kKeyEnter);
- GXMAP(type, SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc);
- GXMAP(type, SDL_SCANCODE_SPACE, GHOST_kKeySpace);
-
- GXMAP(type, SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon);
- GXMAP(type, SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod);
- GXMAP(type, SDL_SCANCODE_COMMA, GHOST_kKeyComma);
- GXMAP(type, SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote);
- GXMAP(type, SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave);
- GXMAP(type, SDL_SCANCODE_MINUS, GHOST_kKeyMinus);
- GXMAP(type, SDL_SCANCODE_EQUALS, GHOST_kKeyEqual);
-
- GXMAP(type, SDL_SCANCODE_SLASH, GHOST_kKeySlash);
- GXMAP(type, SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash);
- GXMAP(type, SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual);
- GXMAP(type, SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket);
- GXMAP(type, SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket);
- GXMAP(type, SDL_SCANCODE_PAUSE, GHOST_kKeyPause);
-
- GXMAP(type, SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift);
- GXMAP(type, SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift);
- GXMAP(type, SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl);
- GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
- GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
- GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
- GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS);
- GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS);
-
- GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
- GXMAP(type, SDL_SCANCODE_DELETE, GHOST_kKeyDelete);
- GXMAP(type, SDL_SCANCODE_HOME, GHOST_kKeyHome);
- GXMAP(type, SDL_SCANCODE_END, GHOST_kKeyEnd);
- GXMAP(type, SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage);
- GXMAP(type, SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage);
-
- GXMAP(type, SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow);
- GXMAP(type, SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow);
- GXMAP(type, SDL_SCANCODE_UP, GHOST_kKeyUpArrow);
- GXMAP(type, SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow);
-
- GXMAP(type, SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock);
- GXMAP(type, SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock);
- GXMAP(type, SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock);
- GXMAP(type, SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen);
-
- /* keypad events */
-
- /* note, sdl defines a bunch of kp defines I never saw before like
- * SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */
- GXMAP(type, SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0);
- GXMAP(type, SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1);
- GXMAP(type, SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2);
- GXMAP(type, SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3);
- GXMAP(type, SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4);
- GXMAP(type, SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5);
- GXMAP(type, SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6);
- GXMAP(type, SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7);
- GXMAP(type, SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8);
- GXMAP(type, SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9);
- GXMAP(type, SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod);
-
- GXMAP(type, SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter);
- GXMAP(type, SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus);
- GXMAP(type, SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus);
- GXMAP(type, SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk);
- GXMAP(type, SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash);
-
- /* Media keys in some keyboards and laptops with XFree86/Xorg */
- GXMAP(type, SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay);
- GXMAP(type, SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop);
- GXMAP(type, SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst);
- // GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
- GXMAP(type, SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
-
- default:
- printf("Unknown\n");
- type = GHOST_kKeyUnknown;
- break;
- }
- }
-
- return type;
+ GHOST_TKey type;
+
+ if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
+ type = GHOST_TKey(key - SDL_SCANCODE_A + int(GHOST_kKeyA));
+ }
+ else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
+ type = (key == SDL_SCANCODE_0) ? GHOST_kKey0 :
+ GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1));
+ }
+ else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
+ type = GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
+ }
+ else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
+ type = GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13));
+ }
+ else {
+ switch (key) {
+ /* TODO SDL_SCANCODE_NONUSBACKSLASH */
+
+ GXMAP(type, SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace);
+ GXMAP(type, SDL_SCANCODE_TAB, GHOST_kKeyTab);
+ GXMAP(type, SDL_SCANCODE_RETURN, GHOST_kKeyEnter);
+ GXMAP(type, SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc);
+ GXMAP(type, SDL_SCANCODE_SPACE, GHOST_kKeySpace);
+
+ GXMAP(type, SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon);
+ GXMAP(type, SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod);
+ GXMAP(type, SDL_SCANCODE_COMMA, GHOST_kKeyComma);
+ GXMAP(type, SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote);
+ GXMAP(type, SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave);
+ GXMAP(type, SDL_SCANCODE_MINUS, GHOST_kKeyMinus);
+ GXMAP(type, SDL_SCANCODE_EQUALS, GHOST_kKeyEqual);
+
+ GXMAP(type, SDL_SCANCODE_SLASH, GHOST_kKeySlash);
+ GXMAP(type, SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash);
+ GXMAP(type, SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual);
+ GXMAP(type, SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket);
+ GXMAP(type, SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket);
+ GXMAP(type, SDL_SCANCODE_PAUSE, GHOST_kKeyPause);
+
+ GXMAP(type, SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift);
+ GXMAP(type, SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift);
+ GXMAP(type, SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl);
+ GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
+ GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
+ GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
+ GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS);
+ GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS);
+
+ GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
+ GXMAP(type, SDL_SCANCODE_DELETE, GHOST_kKeyDelete);
+ GXMAP(type, SDL_SCANCODE_HOME, GHOST_kKeyHome);
+ GXMAP(type, SDL_SCANCODE_END, GHOST_kKeyEnd);
+ GXMAP(type, SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage);
+ GXMAP(type, SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage);
+
+ GXMAP(type, SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow);
+ GXMAP(type, SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow);
+ GXMAP(type, SDL_SCANCODE_UP, GHOST_kKeyUpArrow);
+ GXMAP(type, SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow);
+
+ GXMAP(type, SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock);
+ GXMAP(type, SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock);
+ GXMAP(type, SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock);
+ GXMAP(type, SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen);
+
+ /* keypad events */
+
+ /* note, sdl defines a bunch of kp defines I never saw before like
+ * SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */
+ GXMAP(type, SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0);
+ GXMAP(type, SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1);
+ GXMAP(type, SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2);
+ GXMAP(type, SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3);
+ GXMAP(type, SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4);
+ GXMAP(type, SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5);
+ GXMAP(type, SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6);
+ GXMAP(type, SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7);
+ GXMAP(type, SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8);
+ GXMAP(type, SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9);
+ GXMAP(type, SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod);
+
+ GXMAP(type, SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter);
+ GXMAP(type, SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus);
+ GXMAP(type, SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus);
+ GXMAP(type, SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk);
+ GXMAP(type, SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash);
+
+ /* Media keys in some keyboards and laptops with XFree86/Xorg */
+ GXMAP(type, SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay);
+ GXMAP(type, SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop);
+ GXMAP(type, SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst);
+ // GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
+ GXMAP(type, SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
+
+ default:
+ printf("Unknown\n");
+ type = GHOST_kKeyUnknown;
+ break;
+ }
+ }
+
+ return type;
}
#undef GXMAP
@@ -304,390 +302,447 @@ convertSDLKey(SDL_Scancode key)
*/
static SDL_Window *SDL_GetWindowFromID_fallback(Uint32 id)
{
- SDL_Window *sdl_win = SDL_GetWindowFromID(id);
- if (sdl_win == NULL) {
- sdl_win = SDL_GL_GetCurrentWindow();
- }
- return sdl_win;
+ SDL_Window *sdl_win = SDL_GetWindowFromID(id);
+ if (sdl_win == NULL) {
+ sdl_win = SDL_GL_GetCurrentWindow();
+ }
+ return sdl_win;
}
-void
-GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
+void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
{
- GHOST_Event *g_event = NULL;
-
- switch (sdl_event->type) {
- case SDL_WINDOWEVENT:
- {
- SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
- GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
- //assert(window != NULL); // can be NULL on close window.
-
- switch (sdl_sub_evt.event) {
- case SDL_WINDOWEVENT_EXPOSED:
- g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
- break;
- case SDL_WINDOWEVENT_RESIZED:
- g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
- break;
- case SDL_WINDOWEVENT_MOVED:
- g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window);
- break;
- case SDL_WINDOWEVENT_FOCUS_GAINED:
- g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window);
- break;
- case SDL_WINDOWEVENT_FOCUS_LOST:
- g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window);
- break;
- case SDL_WINDOWEVENT_CLOSE:
- g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
- break;
- }
-
- break;
- }
- case SDL_QUIT:
- g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL);
- break;
-
- case SDL_MOUSEMOTION:
- {
- SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion;
- SDL_Window *sdl_win = SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID);
- GHOST_WindowSDL *window = findGhostWindow(sdl_win);
- assert(window != NULL);
-
- int x_win, y_win;
- SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
-
- GHOST_TInt32 x_root = sdl_sub_evt.x + x_win;
- GHOST_TInt32 y_root = sdl_sub_evt.y + y_win;
+ GHOST_Event *g_event = NULL;
+
+ switch (sdl_event->type) {
+ case SDL_WINDOWEVENT: {
+ SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
+ GHOST_WindowSDL *window = findGhostWindow(
+ SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
+ //assert(window != NULL); // can be NULL on close window.
+
+ switch (sdl_sub_evt.event) {
+ case SDL_WINDOWEVENT_EXPOSED:
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
+ break;
+ case SDL_WINDOWEVENT_RESIZED:
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
+ break;
+ case SDL_WINDOWEVENT_MOVED:
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window);
+ break;
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window);
+ break;
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window);
+ break;
+ case SDL_WINDOWEVENT_CLOSE:
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
+ break;
+ }
+
+ break;
+ }
+ case SDL_QUIT:
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL);
+ break;
+
+ case SDL_MOUSEMOTION: {
+ SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion;
+ SDL_Window *sdl_win = SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID);
+ GHOST_WindowSDL *window = findGhostWindow(sdl_win);
+ assert(window != NULL);
+
+ int x_win, y_win;
+ SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
+
+ GHOST_TInt32 x_root = sdl_sub_evt.x + x_win;
+ GHOST_TInt32 y_root = sdl_sub_evt.y + y_win;
#if 0
- if (window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
- {
- GHOST_TInt32 x_new = x_root;
- GHOST_TInt32 y_new = y_root;
- GHOST_TInt32 x_accum, y_accum;
- GHOST_Rect bounds;
-
- /* fallback to window bounds */
- if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
- window->getClientBounds(bounds);
-
- /* could also clamp to screen bounds
- * wrap with a window outside the view will fail atm */
- bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
- window->getCursorGrabAccum(x_accum, y_accum);
-
- // cant use setCursorPosition because the mouse may have no focus!
- if (x_new != x_root || y_new != y_root) {
- if (1) { //xme.time > m_last_warp) {
- /* when wrapping we don't need to add an event because the
- * setCursorPosition call will cause a new event after */
- SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */
- window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new));
- // m_last_warp= lastEventTime(xme.time);
- }
- else {
- // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
- SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
- }
-
- g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new);
- }
- else {
- g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum);
- }
- }
- else
+ if (window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
+ {
+ GHOST_TInt32 x_new = x_root;
+ GHOST_TInt32 y_new = y_root;
+ GHOST_TInt32 x_accum, y_accum;
+ GHOST_Rect bounds;
+
+ /* fallback to window bounds */
+ if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
+ window->getClientBounds(bounds);
+
+ /* could also clamp to screen bounds
+ * wrap with a window outside the view will fail atm */
+ bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
+ window->getCursorGrabAccum(x_accum, y_accum);
+
+ // cant use setCursorPosition because the mouse may have no focus!
+ if (x_new != x_root || y_new != y_root) {
+ if (1) { //xme.time > m_last_warp) {
+ /* when wrapping we don't need to add an event because the
+ * setCursorPosition call will cause a new event after */
+ SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */
+ window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new));
+ // m_last_warp= lastEventTime(xme.time);
+ }
+ else {
+ // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
+ SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
+ }
+
+ g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new);
+ }
+ else {
+ g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum);
+ }
+ }
+ else
#endif
- {
- g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root);
- }
- break;
- }
- case SDL_MOUSEBUTTONUP:
- case SDL_MOUSEBUTTONDOWN:
- {
- SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button;
- GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
- GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp;
-
- GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
- assert(window != NULL);
-
- /* process rest of normal mouse buttons */
- if (sdl_sub_evt.button == SDL_BUTTON_LEFT)
- gbmask = GHOST_kButtonMaskLeft;
- else if (sdl_sub_evt.button == SDL_BUTTON_MIDDLE)
- gbmask = GHOST_kButtonMaskMiddle;
- else if (sdl_sub_evt.button == SDL_BUTTON_RIGHT)
- gbmask = GHOST_kButtonMaskRight;
- /* these buttons are untested! */
- else if (sdl_sub_evt.button == SDL_BUTTON_X1)
- gbmask = GHOST_kButtonMaskButton4;
- else if (sdl_sub_evt.button == SDL_BUTTON_X2)
- gbmask = GHOST_kButtonMaskButton5;
- else
- break;
-
- g_event = new GHOST_EventButton(getMilliSeconds(), type, window, gbmask);
- break;
- }
- case SDL_MOUSEWHEEL:
- {
- SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel;
- GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
- assert(window != NULL);
- g_event = new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y);
- break;
- }
- case SDL_KEYDOWN:
- case SDL_KEYUP:
- {
- SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key;
- SDL_Keycode sym = sdl_sub_evt.keysym.sym;
- GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
-
- GHOST_WindowSDL *window = findGhostWindow(SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
- assert(window != NULL);
-
- GHOST_TKey gkey = convertSDLKey(sdl_sub_evt.keysym.scancode);
- /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */
- /* printf("%d\n", sym); */
- if (sym > 127) {
- switch (sym) {
- case SDLK_KP_DIVIDE: sym = '/'; break;
- case SDLK_KP_MULTIPLY: sym = '*'; break;
- case SDLK_KP_MINUS: sym = '-'; break;
- case SDLK_KP_PLUS: sym = '+'; break;
- case SDLK_KP_1: sym = '1'; break;
- case SDLK_KP_2: sym = '2'; break;
- case SDLK_KP_3: sym = '3'; break;
- case SDLK_KP_4: sym = '4'; break;
- case SDLK_KP_5: sym = '5'; break;
- case SDLK_KP_6: sym = '6'; break;
- case SDLK_KP_7: sym = '7'; break;
- case SDLK_KP_8: sym = '8'; break;
- case SDLK_KP_9: sym = '9'; break;
- case SDLK_KP_0: sym = '0'; break;
- case SDLK_KP_PERIOD: sym = '.'; break;
- default: sym = 0; break;
- }
- }
- else {
- if (sdl_sub_evt.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
- /* lame US keyboard assumptions */
- if (sym >= 'a' && sym <= ('a' + 32)) {
- sym -= 32;
- }
- else {
- switch (sym) {
- case '`': sym = '~'; break;
- case '1': sym = '!'; break;
- case '2': sym = '@'; break;
- case '3': sym = '#'; break;
- case '4': sym = '$'; break;
- case '5': sym = '%'; break;
- case '6': sym = '^'; break;
- case '7': sym = '&'; break;
- case '8': sym = '*'; break;
- case '9': sym = '('; break;
- case '0': sym = ')'; break;
- case '-': sym = '_'; break;
- case '=': sym = '+'; break;
- case '[': sym = '{'; break;
- case ']': sym = '}'; break;
- case '\\': sym = '|'; break;
- case ';': sym = ':'; break;
- case '\'': sym = '"'; break;
- case ',': sym = '<'; break;
- case '.': sym = '>'; break;
- case '/': sym = '?'; break;
- default: break;
- }
- }
- }
- }
-
- g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL);
- break;
- }
- }
-
- if (g_event) {
- pushEvent(g_event);
- }
+ {
+ g_event = new GHOST_EventCursor(
+ getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root);
+ }
+ break;
+ }
+ case SDL_MOUSEBUTTONUP:
+ case SDL_MOUSEBUTTONDOWN: {
+ SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button;
+ GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
+ GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventButtonDown :
+ GHOST_kEventButtonUp;
+
+ GHOST_WindowSDL *window = findGhostWindow(
+ SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
+ assert(window != NULL);
+
+ /* process rest of normal mouse buttons */
+ if (sdl_sub_evt.button == SDL_BUTTON_LEFT)
+ gbmask = GHOST_kButtonMaskLeft;
+ else if (sdl_sub_evt.button == SDL_BUTTON_MIDDLE)
+ gbmask = GHOST_kButtonMaskMiddle;
+ else if (sdl_sub_evt.button == SDL_BUTTON_RIGHT)
+ gbmask = GHOST_kButtonMaskRight;
+ /* these buttons are untested! */
+ else if (sdl_sub_evt.button == SDL_BUTTON_X1)
+ gbmask = GHOST_kButtonMaskButton4;
+ else if (sdl_sub_evt.button == SDL_BUTTON_X2)
+ gbmask = GHOST_kButtonMaskButton5;
+ else
+ break;
+
+ g_event = new GHOST_EventButton(getMilliSeconds(), type, window, gbmask);
+ break;
+ }
+ case SDL_MOUSEWHEEL: {
+ SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel;
+ GHOST_WindowSDL *window = findGhostWindow(
+ SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
+ assert(window != NULL);
+ g_event = new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y);
+ break;
+ }
+ case SDL_KEYDOWN:
+ case SDL_KEYUP: {
+ SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key;
+ SDL_Keycode sym = sdl_sub_evt.keysym.sym;
+ GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown :
+ GHOST_kEventKeyUp;
+
+ GHOST_WindowSDL *window = findGhostWindow(
+ SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
+ assert(window != NULL);
+
+ GHOST_TKey gkey = convertSDLKey(sdl_sub_evt.keysym.scancode);
+ /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */
+ /* printf("%d\n", sym); */
+ if (sym > 127) {
+ switch (sym) {
+ case SDLK_KP_DIVIDE:
+ sym = '/';
+ break;
+ case SDLK_KP_MULTIPLY:
+ sym = '*';
+ break;
+ case SDLK_KP_MINUS:
+ sym = '-';
+ break;
+ case SDLK_KP_PLUS:
+ sym = '+';
+ break;
+ case SDLK_KP_1:
+ sym = '1';
+ break;
+ case SDLK_KP_2:
+ sym = '2';
+ break;
+ case SDLK_KP_3:
+ sym = '3';
+ break;
+ case SDLK_KP_4:
+ sym = '4';
+ break;
+ case SDLK_KP_5:
+ sym = '5';
+ break;
+ case SDLK_KP_6:
+ sym = '6';
+ break;
+ case SDLK_KP_7:
+ sym = '7';
+ break;
+ case SDLK_KP_8:
+ sym = '8';
+ break;
+ case SDLK_KP_9:
+ sym = '9';
+ break;
+ case SDLK_KP_0:
+ sym = '0';
+ break;
+ case SDLK_KP_PERIOD:
+ sym = '.';
+ break;
+ default:
+ sym = 0;
+ break;
+ }
+ }
+ else {
+ if (sdl_sub_evt.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
+ /* lame US keyboard assumptions */
+ if (sym >= 'a' && sym <= ('a' + 32)) {
+ sym -= 32;
+ }
+ else {
+ switch (sym) {
+ case '`':
+ sym = '~';
+ break;
+ case '1':
+ sym = '!';
+ break;
+ case '2':
+ sym = '@';
+ break;
+ case '3':
+ sym = '#';
+ break;
+ case '4':
+ sym = '$';
+ break;
+ case '5':
+ sym = '%';
+ break;
+ case '6':
+ sym = '^';
+ break;
+ case '7':
+ sym = '&';
+ break;
+ case '8':
+ sym = '*';
+ break;
+ case '9':
+ sym = '(';
+ break;
+ case '0':
+ sym = ')';
+ break;
+ case '-':
+ sym = '_';
+ break;
+ case '=':
+ sym = '+';
+ break;
+ case '[':
+ sym = '{';
+ break;
+ case ']':
+ sym = '}';
+ break;
+ case '\\':
+ sym = '|';
+ break;
+ case ';':
+ sym = ':';
+ break;
+ case '\'':
+ sym = '"';
+ break;
+ case ',':
+ sym = '<';
+ break;
+ case '.':
+ sym = '>';
+ break;
+ case '/':
+ sym = '?';
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL);
+ break;
+ }
+ }
+
+ if (g_event) {
+ pushEvent(g_event);
+ }
}
-GHOST_TSuccess
-GHOST_SystemSDL::getCursorPosition(GHOST_TInt32& x,
- GHOST_TInt32& y) const
+GHOST_TSuccess GHOST_SystemSDL::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- int x_win, y_win;
- SDL_Window *win = SDL_GetMouseFocus();
- SDL_GetWindowPosition(win, &x_win, &y_win);
+ int x_win, y_win;
+ SDL_Window *win = SDL_GetMouseFocus();
+ SDL_GetWindowPosition(win, &x_win, &y_win);
- int xi, yi;
- SDL_GetMouseState(&xi, &yi);
- x = xi + x_win;
- y = yi + x_win;
+ int xi, yi;
+ SDL_GetMouseState(&xi, &yi);
+ x = xi + x_win;
+ y = yi + x_win;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x,
- GHOST_TInt32 y)
+GHOST_TSuccess GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
{
- int x_win, y_win;
- SDL_Window *win = SDL_GetMouseFocus();
- SDL_GetWindowPosition(win, &x_win, &y_win);
-
- SDL_WarpMouseInWindow(win, x - x_win, y - y_win);
- return GHOST_kSuccess;
-}
+ int x_win, y_win;
+ SDL_Window *win = SDL_GetMouseFocus();
+ SDL_GetWindowPosition(win, &x_win, &y_win);
-bool
-GHOST_SystemSDL::generateWindowExposeEvents()
-{
- std::vector<GHOST_WindowSDL *>::iterator w_start = m_dirty_windows.begin();
- std::vector<GHOST_WindowSDL *>::const_iterator w_end = m_dirty_windows.end();
- bool anyProcessed = false;
-
- for (; w_start != w_end; ++w_start) {
- GHOST_Event *g_event = new
- GHOST_Event(
- getMilliSeconds(),
- GHOST_kEventWindowUpdate,
- *w_start
- );
-
- (*w_start)->validate();
-
- if (g_event) {
- //printf("Expose events pushed\n");
- pushEvent(g_event);
- anyProcessed = true;
- }
- }
-
- m_dirty_windows.clear();
- return anyProcessed;
+ SDL_WarpMouseInWindow(win, x - x_win, y - y_win);
+ return GHOST_kSuccess;
}
-
-bool
-GHOST_SystemSDL::processEvents(bool waitForEvent)
+bool GHOST_SystemSDL::generateWindowExposeEvents()
{
- // Get all the current events -- translate them into
- // ghost events and call base class pushEvent() method.
-
- bool anyProcessed = false;
-
- do {
- GHOST_TimerManager *timerMgr = getTimerManager();
-
- if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
- GHOST_TUns64 next = timerMgr->nextFireTime();
-
- if (next == GHOST_kFireTimeNever) {
- SDL_WaitEventTimeout(NULL, -1);
- //SleepTillEvent(m_display, -1);
- }
- else {
- GHOST_TInt64 maxSleep = next - getMilliSeconds();
-
- if (maxSleep >= 0) {
- SDL_WaitEventTimeout(NULL, next - getMilliSeconds());
- // SleepTillEvent(m_display, next - getMilliSeconds()); // X11
- }
- }
- }
-
- if (timerMgr->fireTimers(getMilliSeconds())) {
- anyProcessed = true;
- }
-
- SDL_Event sdl_event;
- while (SDL_PollEvent(&sdl_event)) {
- processEvent(&sdl_event);
- anyProcessed = true;
- }
-
- if (generateWindowExposeEvents()) {
- anyProcessed = true;
- }
- } while (waitForEvent && !anyProcessed);
-
- return anyProcessed;
-}
+ std::vector<GHOST_WindowSDL *>::iterator w_start = m_dirty_windows.begin();
+ std::vector<GHOST_WindowSDL *>::const_iterator w_end = m_dirty_windows.end();
+ bool anyProcessed = false;
+ for (; w_start != w_end; ++w_start) {
+ GHOST_Event *g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, *w_start);
-GHOST_WindowSDL *
-GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
-{
- if (sdl_win == NULL) return NULL;
-
- // It is not entirely safe to do this as the backptr may point
- // to a window that has recently been removed.
- // We should always check the window manager's list of windows
- // and only process events on these windows.
+ (*w_start)->validate();
- std::vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
+ if (g_event) {
+ //printf("Expose events pushed\n");
+ pushEvent(g_event);
+ anyProcessed = true;
+ }
+ }
- std::vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
- std::vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
+ m_dirty_windows.clear();
+ return anyProcessed;
+}
- for (; win_it != win_end; ++win_it) {
- GHOST_WindowSDL *window = static_cast<GHOST_WindowSDL *>(*win_it);
- if (window->getSDLWindow() == sdl_win) {
- return window;
- }
- }
- return NULL;
+bool GHOST_SystemSDL::processEvents(bool waitForEvent)
+{
+ // Get all the current events -- translate them into
+ // ghost events and call base class pushEvent() method.
+
+ bool anyProcessed = false;
+
+ do {
+ GHOST_TimerManager *timerMgr = getTimerManager();
+
+ if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
+ GHOST_TUns64 next = timerMgr->nextFireTime();
+
+ if (next == GHOST_kFireTimeNever) {
+ SDL_WaitEventTimeout(NULL, -1);
+ //SleepTillEvent(m_display, -1);
+ }
+ else {
+ GHOST_TInt64 maxSleep = next - getMilliSeconds();
+
+ if (maxSleep >= 0) {
+ SDL_WaitEventTimeout(NULL, next - getMilliSeconds());
+ // SleepTillEvent(m_display, next - getMilliSeconds()); // X11
+ }
+ }
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed = true;
+ }
+
+ SDL_Event sdl_event;
+ while (SDL_PollEvent(&sdl_event)) {
+ processEvent(&sdl_event);
+ anyProcessed = true;
+ }
+
+ if (generateWindowExposeEvents()) {
+ anyProcessed = true;
+ }
+ } while (waitForEvent && !anyProcessed);
+
+ return anyProcessed;
}
+GHOST_WindowSDL *GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
+{
+ if (sdl_win == NULL)
+ return NULL;
+
+ // It is not entirely safe to do this as the backptr may point
+ // to a window that has recently been removed.
+ // We should always check the window manager's list of windows
+ // and only process events on these windows.
+
+ std::vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
+
+ std::vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ std::vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
+
+ for (; win_it != win_end; ++win_it) {
+ GHOST_WindowSDL *window = static_cast<GHOST_WindowSDL *>(*win_it);
+ if (window->getSDLWindow() == sdl_win) {
+ return window;
+ }
+ }
+ return NULL;
+}
-void
-GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind)
+void GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind)
{
- GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
+ GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
- m_dirty_windows.push_back(bad_wind);
+ m_dirty_windows.push_back(bad_wind);
}
-bool
-GHOST_SystemSDL::supportsNativeDialogs(void)
+bool GHOST_SystemSDL::supportsNativeDialogs(void)
{
- return false;
+ return false;
}
-GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons& buttons) const
+GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons &buttons) const
{
- Uint8 state = SDL_GetMouseState(NULL, NULL);
- buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0);
- buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0);
- buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0);
+ Uint8 state = SDL_GetMouseState(NULL, NULL);
+ buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0);
+ buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0);
+ buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TUns8 *
-GHOST_SystemSDL::getClipboard(bool selection) const
+GHOST_TUns8 *GHOST_SystemSDL::getClipboard(bool selection) const
{
- return (GHOST_TUns8 *)SDL_GetClipboardText();
+ return (GHOST_TUns8 *)SDL_GetClipboardText();
}
-void
-GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const
+void GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const
{
- SDL_SetClipboardText(buffer);
+ SDL_SetClipboardText(buffer);
}
-GHOST_TUns64
-GHOST_SystemSDL::getMilliSeconds()
+GHOST_TUns64 GHOST_SystemSDL::getMilliSeconds()
{
- return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */
+ return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */
}
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index fabd15d3164..e51cc3d5b5d 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -30,104 +30,81 @@
#include "GHOST_Event.h"
extern "C" {
- #include "SDL.h"
+#include "SDL.h"
}
#if !SDL_VERSION_ATLEAST(2, 0, 0)
# error "SDL 2.0 or newer is needed to build with Ghost"
#endif
-
class GHOST_WindowSDL;
-
class GHOST_SystemSDL : public GHOST_System {
-public:
-
- void addDirtyWindow(GHOST_WindowSDL *bad_wind);
+ public:
+ void addDirtyWindow(GHOST_WindowSDL *bad_wind);
- GHOST_SystemSDL();
- ~GHOST_SystemSDL();
+ GHOST_SystemSDL();
+ ~GHOST_SystemSDL();
- bool
- processEvents(bool waitForEvent);
+ bool processEvents(bool waitForEvent);
- int
- toggleConsole(int action) { return 0; }
+ int toggleConsole(int action)
+ {
+ return 0;
+ }
- GHOST_TSuccess
- getModifierKeys(GHOST_ModifierKeys& keys) const;
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const;
- GHOST_TSuccess
- getButtons(GHOST_Buttons& buttons) const;
+ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
- GHOST_TUns8 *
- getClipboard(bool selection) const;
+ GHOST_TUns8 *getClipboard(bool selection) const;
- void
- putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
- GHOST_TUns64
- getMilliSeconds();
+ GHOST_TUns64 getMilliSeconds();
- GHOST_TUns8
- getNumDisplays() const;
+ GHOST_TUns8 getNumDisplays() const;
- GHOST_TSuccess
- getCursorPosition(GHOST_TInt32& x,
- GHOST_TInt32& y) const;
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- GHOST_TSuccess
- setCursorPosition(GHOST_TInt32 x,
- GHOST_TInt32 y);
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
- void
- getAllDisplayDimensions(GHOST_TUns32& width,
- GHOST_TUns32& height) const;
+ void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
- void
- getMainDisplayDimensions(GHOST_TUns32& width,
- GHOST_TUns32& height) const;
+ void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
- GHOST_IContext *
- createOffscreenContext();
+ GHOST_IContext *createOffscreenContext();
- GHOST_TSuccess
- disposeContext(GHOST_IContext *context);
+ GHOST_TSuccess disposeContext(GHOST_IContext *context);
- /**
- * Informs if the system provides native dialogs (eg. confirm quit)
- */
- virtual bool supportsNativeDialogs(void);
-private:
+ /**
+ * Informs if the system provides native dialogs (eg. confirm quit)
+ */
+ virtual bool supportsNativeDialogs(void);
- GHOST_TSuccess
- init();
+ private:
+ GHOST_TSuccess init();
- GHOST_IWindow *
- createWindow(const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive = false,
- const GHOST_TEmbedderWindowID parentWindow = 0
- );
+ GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive = false,
+ const GHOST_TEmbedderWindowID parentWindow = 0);
- /* SDL specific */
- GHOST_WindowSDL *findGhostWindow(SDL_Window *sdl_win);
+ /* SDL specific */
+ GHOST_WindowSDL *findGhostWindow(SDL_Window *sdl_win);
- bool
- generateWindowExposeEvents();
+ bool generateWindowExposeEvents();
- void
- processEvent(SDL_Event *sdl_event);
+ void processEvent(SDL_Event *sdl_event);
- /// The vector of windows that need to be updated.
- std::vector<GHOST_WindowSDL *> m_dirty_windows;
+ /// The vector of windows that need to be updated.
+ std::vector<GHOST_WindowSDL *> m_dirty_windows;
};
#endif
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 35a9cfac817..95f969bcb67 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
#include "GHOST_SystemWin32.h"
#include "GHOST_EventDragnDrop.h"
@@ -53,71 +52,71 @@
#endif
#ifdef WITH_INPUT_NDOF
- #include "GHOST_NDOFManagerWin32.h"
+# include "GHOST_NDOFManagerWin32.h"
#endif
// Key code values not found in winuser.h
#ifndef VK_MINUS
-#define VK_MINUS 0xBD
-#endif // VK_MINUS
+# define VK_MINUS 0xBD
+#endif // VK_MINUS
#ifndef VK_SEMICOLON
-#define VK_SEMICOLON 0xBA
-#endif // VK_SEMICOLON
+# define VK_SEMICOLON 0xBA
+#endif // VK_SEMICOLON
#ifndef VK_PERIOD
-#define VK_PERIOD 0xBE
-#endif // VK_PERIOD
+# define VK_PERIOD 0xBE
+#endif // VK_PERIOD
#ifndef VK_COMMA
-#define VK_COMMA 0xBC
-#endif // VK_COMMA
+# define VK_COMMA 0xBC
+#endif // VK_COMMA
#ifndef VK_QUOTE
-#define VK_QUOTE 0xDE
-#endif // VK_QUOTE
+# define VK_QUOTE 0xDE
+#endif // VK_QUOTE
#ifndef VK_BACK_QUOTE
-#define VK_BACK_QUOTE 0xC0
-#endif // VK_BACK_QUOTE
+# define VK_BACK_QUOTE 0xC0
+#endif // VK_BACK_QUOTE
#ifndef VK_SLASH
-#define VK_SLASH 0xBF
-#endif // VK_SLASH
+# define VK_SLASH 0xBF
+#endif // VK_SLASH
#ifndef VK_BACK_SLASH
-#define VK_BACK_SLASH 0xDC
-#endif // VK_BACK_SLASH
+# define VK_BACK_SLASH 0xDC
+#endif // VK_BACK_SLASH
#ifndef VK_EQUALS
-#define VK_EQUALS 0xBB
-#endif // VK_EQUALS
+# define VK_EQUALS 0xBB
+#endif // VK_EQUALS
#ifndef VK_OPEN_BRACKET
-#define VK_OPEN_BRACKET 0xDB
-#endif // VK_OPEN_BRACKET
+# define VK_OPEN_BRACKET 0xDB
+#endif // VK_OPEN_BRACKET
#ifndef VK_CLOSE_BRACKET
-#define VK_CLOSE_BRACKET 0xDD
-#endif // VK_CLOSE_BRACKET
+# define VK_CLOSE_BRACKET 0xDD
+#endif // VK_CLOSE_BRACKET
#ifndef VK_GR_LESS
-#define VK_GR_LESS 0xE2
-#endif // VK_GR_LESS
+# define VK_GR_LESS 0xE2
+#endif // VK_GR_LESS
#ifndef VK_MEDIA_NEXT_TRACK
-#define VK_MEDIA_NEXT_TRACK 0xB0
-#endif // VK_MEDIA_NEXT_TRACK
+# define VK_MEDIA_NEXT_TRACK 0xB0
+#endif // VK_MEDIA_NEXT_TRACK
#ifndef VK_MEDIA_PREV_TRACK
-#define VK_MEDIA_PREV_TRACK 0xB1
-#endif // VK_MEDIA_PREV_TRACK
+# define VK_MEDIA_PREV_TRACK 0xB1
+#endif // VK_MEDIA_PREV_TRACK
#ifndef VK_MEDIA_STOP
-#define VK_MEDIA_STOP 0xB2
-#endif // VK_MEDIA_STOP
+# define VK_MEDIA_STOP 0xB2
+#endif // VK_MEDIA_STOP
#ifndef VK_MEDIA_PLAY_PAUSE
-#define VK_MEDIA_PLAY_PAUSE 0xB3
-#endif // VK_MEDIA_PLAY_PAUSE
+# define VK_MEDIA_PLAY_PAUSE 0xB3
+#endif // VK_MEDIA_PLAY_PAUSE
// Window message newer than Windows 7
#ifndef WM_DPICHANGED
-#define WM_DPICHANGED 0x02E0
-#endif // WM_DPICHANGED
+# define WM_DPICHANGED 0x02E0
+#endif // WM_DPICHANGED
#ifndef WM_POINTERUPDATE
-#define WM_POINTERUPDATE 0x0245
-#endif // WM_POINTERUPDATE
+# define WM_POINTERUPDATE 0x0245
+#endif // WM_POINTERUPDATE
-#define WM_POINTERDOWN 0x0246
-#define WM_POINTERUP 0x0247
+#define WM_POINTERDOWN 0x0246
+#define WM_POINTERUP 0x0247
/* Workaround for some laptop touchpads, some of which seems to
* have driver issues which makes it so window function receives
@@ -133,175 +132,171 @@
static void initRawInput()
{
#ifdef WITH_INPUT_NDOF
- #define DEVICE_COUNT 2
+# define DEVICE_COUNT 2
#else
- #define DEVICE_COUNT 1
+# define DEVICE_COUNT 1
#endif
- RAWINPUTDEVICE devices[DEVICE_COUNT];
- memset(devices, 0, DEVICE_COUNT * sizeof(RAWINPUTDEVICE));
+ RAWINPUTDEVICE devices[DEVICE_COUNT];
+ memset(devices, 0, DEVICE_COUNT * sizeof(RAWINPUTDEVICE));
- // Initiates WM_INPUT messages from keyboard
- // That way GHOST can retrieve true keys
- devices[0].usUsagePage = 0x01;
- devices[0].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
+ // Initiates WM_INPUT messages from keyboard
+ // That way GHOST can retrieve true keys
+ devices[0].usUsagePage = 0x01;
+ devices[0].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
#ifdef WITH_INPUT_NDOF
- // multi-axis mouse (SpaceNavigator, etc.)
- devices[1].usUsagePage = 0x01;
- devices[1].usUsage = 0x08;
+ // multi-axis mouse (SpaceNavigator, etc.)
+ devices[1].usUsagePage = 0x01;
+ devices[1].usUsage = 0x08;
#endif
- if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE)))
- ; // yay!
- else
- GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError());
+ if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE)))
+ ; // yay!
+ else
+ GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError());
#undef DEVICE_COUNT
}
#ifndef DPI_ENUMS_DECLARED
typedef enum PROCESS_DPI_AWARENESS {
- PROCESS_DPI_UNAWARE = 0,
- PROCESS_SYSTEM_DPI_AWARE = 1,
- PROCESS_PER_MONITOR_DPI_AWARE = 2
+ PROCESS_DPI_UNAWARE = 0,
+ PROCESS_SYSTEM_DPI_AWARE = 1,
+ PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
typedef enum MONITOR_DPI_TYPE {
- MDT_EFFECTIVE_DPI = 0,
- MDT_ANGULAR_DPI = 1,
- MDT_RAW_DPI = 2,
- MDT_DEFAULT = MDT_EFFECTIVE_DPI
+ MDT_EFFECTIVE_DPI = 0,
+ MDT_ANGULAR_DPI = 1,
+ MDT_RAW_DPI = 2,
+ MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
-#define USER_DEFAULT_SCREEN_DPI 96
+# define USER_DEFAULT_SCREEN_DPI 96
-#define DPI_ENUMS_DECLARED
+# define DPI_ENUMS_DECLARED
#endif
-typedef HRESULT(API * GHOST_WIN32_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
-typedef BOOL(API * GHOST_WIN32_EnableNonClientDpiScaling)(HWND);
+typedef HRESULT(API *GHOST_WIN32_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
+typedef BOOL(API *GHOST_WIN32_EnableNonClientDpiScaling)(HWND);
-GHOST_SystemWin32::GHOST_SystemWin32()
- : m_hasPerformanceCounter(false), m_freq(0), m_start(0)
+GHOST_SystemWin32::GHOST_SystemWin32() : m_hasPerformanceCounter(false), m_freq(0), m_start(0)
{
- m_displayManager = new GHOST_DisplayManagerWin32();
- GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
- m_displayManager->initialize();
-
- m_consoleStatus = 1;
-
- // Tell Windows we are per monitor DPI aware. This disables the default
- // blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI.
- HMODULE m_shcore = ::LoadLibrary("Shcore.dll");
- if (m_shcore) {
- GHOST_WIN32_SetProcessDpiAwareness fpSetProcessDpiAwareness =
- (GHOST_WIN32_SetProcessDpiAwareness) ::GetProcAddress(m_shcore, "SetProcessDpiAwareness");
-
- if (fpSetProcessDpiAwareness) {
- fpSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
- }
- }
-
- // Check if current keyboard layout uses AltGr and save keylayout ID for
- // specialized handling if keys like VK_OEM_*. I.e. french keylayout
- // generates VK_OEM_8 for their exclamation key (key left of right shift)
- this->handleKeyboardChange();
- // Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
- OleInitialize(0);
+ m_displayManager = new GHOST_DisplayManagerWin32();
+ GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
+ m_displayManager->initialize();
+
+ m_consoleStatus = 1;
+
+ // Tell Windows we are per monitor DPI aware. This disables the default
+ // blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI.
+ HMODULE m_shcore = ::LoadLibrary("Shcore.dll");
+ if (m_shcore) {
+ GHOST_WIN32_SetProcessDpiAwareness fpSetProcessDpiAwareness =
+ (GHOST_WIN32_SetProcessDpiAwareness)::GetProcAddress(m_shcore, "SetProcessDpiAwareness");
+
+ if (fpSetProcessDpiAwareness) {
+ fpSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
+ }
+ }
+
+ // Check if current keyboard layout uses AltGr and save keylayout ID for
+ // specialized handling if keys like VK_OEM_*. I.e. french keylayout
+ // generates VK_OEM_8 for their exclamation key (key left of right shift)
+ this->handleKeyboardChange();
+ // Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
+ OleInitialize(0);
#ifdef WITH_INPUT_NDOF
- m_ndofManager = new GHOST_NDOFManagerWin32(*this);
+ m_ndofManager = new GHOST_NDOFManagerWin32(*this);
#endif
}
GHOST_SystemWin32::~GHOST_SystemWin32()
{
- // Shutdown COM
- OleUninitialize();
- toggleConsole(1);
+ // Shutdown COM
+ OleUninitialize();
+ toggleConsole(1);
}
-
GHOST_TUns64 GHOST_SystemWin32::getMilliSeconds() const
{
- // Hardware does not support high resolution timers. We will use GetTickCount instead then.
- if (!m_hasPerformanceCounter) {
- return ::GetTickCount();
- }
+ // Hardware does not support high resolution timers. We will use GetTickCount instead then.
+ if (!m_hasPerformanceCounter) {
+ return ::GetTickCount();
+ }
- // Retrieve current count
- __int64 count = 0;
- ::QueryPerformanceCounter((LARGE_INTEGER *)&count);
+ // Retrieve current count
+ __int64 count = 0;
+ ::QueryPerformanceCounter((LARGE_INTEGER *)&count);
- // Calculate the time passed since system initialization.
- __int64 delta = 1000 * (count - m_start);
+ // Calculate the time passed since system initialization.
+ __int64 delta = 1000 * (count - m_start);
- GHOST_TUns64 t = (GHOST_TUns64)(delta / m_freq);
- return t;
+ GHOST_TUns64 t = (GHOST_TUns64)(delta / m_freq);
+ return t;
}
-
GHOST_TUns8 GHOST_SystemWin32::getNumDisplays() const
{
- GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::getNumDisplays(): m_displayManager==0\n");
- GHOST_TUns8 numDisplays;
- m_displayManager->getNumDisplays(numDisplays);
- return numDisplays;
+ GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::getNumDisplays(): m_displayManager==0\n");
+ GHOST_TUns8 numDisplays;
+ m_displayManager->getNumDisplays(numDisplays);
+ return numDisplays;
}
-
void GHOST_SystemWin32::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- width = ::GetSystemMetrics(SM_CXSCREEN);
- height = ::GetSystemMetrics(SM_CYSCREEN);
+ width = ::GetSystemMetrics(SM_CXSCREEN);
+ height = ::GetSystemMetrics(SM_CYSCREEN);
}
void GHOST_SystemWin32::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- width = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
- height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ width = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
-GHOST_IWindow *GHOST_SystemWin32::createWindow(
- const STR_String &title,
- GHOST_TInt32 left, GHOST_TInt32 top,
- GHOST_TUns32 width, GHOST_TUns32 height,
- GHOST_TWindowState state, GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive,
- const GHOST_TEmbedderWindowID parentWindow)
+GHOST_IWindow *GHOST_SystemWin32::createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive,
+ const GHOST_TEmbedderWindowID parentWindow)
{
- GHOST_WindowWin32 *window =
- new GHOST_WindowWin32(
- this,
- title,
- left,
- top,
- width,
- height,
- state,
- type,
- ((glSettings.flags & GHOST_glStereoVisual) != 0),
- ((glSettings.flags & GHOST_glAlphaBackground) != 0),
- glSettings.numOfAASamples,
- parentWindow,
- ((glSettings.flags & GHOST_glDebugContext) != 0));
-
- if (window->getValid()) {
- // Store the pointer to the window
- m_windowManager->addWindow(window);
- m_windowManager->setActiveWindow(window);
- }
- else {
- GHOST_PRINT("GHOST_SystemWin32::createWindow(): window invalid\n");
- delete window;
- window = NULL;
- }
-
- return window;
+ GHOST_WindowWin32 *window = new GHOST_WindowWin32(
+ this,
+ title,
+ left,
+ top,
+ width,
+ height,
+ state,
+ type,
+ ((glSettings.flags & GHOST_glStereoVisual) != 0),
+ ((glSettings.flags & GHOST_glAlphaBackground) != 0),
+ glSettings.numOfAASamples,
+ parentWindow,
+ ((glSettings.flags & GHOST_glDebugContext) != 0));
+
+ if (window->getValid()) {
+ // Store the pointer to the window
+ m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemWin32::createWindow(): window invalid\n");
+ delete window;
+ window = NULL;
+ }
+
+ return window;
}
-
/**
* Create a new offscreen context.
* Never explicitly delete the window, use #disposeContext() instead.
@@ -309,85 +304,97 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(
*/
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext()
{
- bool debug_context = false; /* TODO: inform as a parameter */
-
- GHOST_Context *context;
-
- HWND wnd = CreateWindowA("STATIC",
- "BlenderGLEW",
- WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
- 0, 0, 64, 64,
- NULL, NULL,
- GetModuleHandle(NULL), NULL
- );
-
- HDC mHDC = GetDC(wnd);
- HDC prev_hdc = wglGetCurrentDC();
- HGLRC prev_context = wglGetCurrentContext();
+ bool debug_context = false; /* TODO: inform as a parameter */
+
+ GHOST_Context *context;
+
+ HWND wnd = CreateWindowA("STATIC",
+ "BlenderGLEW",
+ WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ 0,
+ 0,
+ 64,
+ 64,
+ NULL,
+ NULL,
+ GetModuleHandle(NULL),
+ NULL);
+
+ HDC mHDC = GetDC(wnd);
+ HDC prev_hdc = wglGetCurrentDC();
+ HGLRC prev_context = wglGetCurrentContext();
#if defined(WITH_GL_PROFILE_CORE)
- for (int minor = 5; minor >= 0; --minor) {
- context = new GHOST_ContextWGL(
- false, true, 0,
- wnd, mHDC,
- WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
- 4, minor,
- (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext()) {
- goto finished;
- }
- else {
- delete context;
- }
- }
-
- context = new GHOST_ContextWGL(
- false, true, 0,
- wnd, mHDC,
- WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
- 3, 3,
- (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext()) {
- goto finished;
- }
- else {
- MessageBox(
- NULL,
- "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n"
- "Installing the latest driver for your graphics card may resolve the issue.\n\n"
- "The program will now close.",
- "Blender - Unsupported Graphics Card or Driver",
- MB_OK | MB_ICONERROR);
- delete context;
- exit();
- }
+ for (int minor = 5; minor >= 0; --minor) {
+ context = new GHOST_ContextWGL(false,
+ true,
+ 0,
+ wnd,
+ mHDC,
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ 4,
+ minor,
+ (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext()) {
+ goto finished;
+ }
+ else {
+ delete context;
+ }
+ }
+
+ context = new GHOST_ContextWGL(false,
+ true,
+ 0,
+ wnd,
+ mHDC,
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ 3,
+ 3,
+ (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext()) {
+ goto finished;
+ }
+ else {
+ MessageBox(NULL,
+ "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n"
+ "Installing the latest driver for your graphics card may resolve the issue.\n\n"
+ "The program will now close.",
+ "Blender - Unsupported Graphics Card or Driver",
+ MB_OK | MB_ICONERROR);
+ delete context;
+ exit();
+ }
#elif defined(WITH_GL_PROFILE_COMPAT)
- // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile)
- // 2.1 ignores the profile bit & is incompatible with core profile
- context = new GHOST_ContextWGL(
- false, true, 0,
- NULL, NULL,
- 0, // no profile bit
- 2, 1,
- (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext()) {
- return context;
- }
- else {
- delete context;
- }
+ // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile)
+ // 2.1 ignores the profile bit & is incompatible with core profile
+ context = new GHOST_ContextWGL(false,
+ true,
+ 0,
+ NULL,
+ NULL,
+ 0, // no profile bit
+ 2,
+ 1,
+ (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext()) {
+ return context;
+ }
+ else {
+ delete context;
+ }
#else
-# error // must specify either core or compat at build time
+# error // must specify either core or compat at build time
#endif
finished:
- wglMakeCurrent(prev_hdc, prev_context);
- return context;
+ wglMakeCurrent(prev_hdc, prev_context);
+ return context;
}
/**
@@ -397,255 +404,244 @@ finished:
*/
GHOST_TSuccess GHOST_SystemWin32::disposeContext(GHOST_IContext *context)
{
- delete context;
+ delete context;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
bool GHOST_SystemWin32::processEvents(bool waitForEvent)
{
- MSG msg;
- bool hasEventHandled = false;
+ MSG msg;
+ bool hasEventHandled = false;
- do {
- GHOST_TimerManager *timerMgr = getTimerManager();
+ do {
+ GHOST_TimerManager *timerMgr = getTimerManager();
- if (waitForEvent && !::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
+ if (waitForEvent && !::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
#if 1
- ::Sleep(1);
+ ::Sleep(1);
#else
- GHOST_TUns64 next = timerMgr->nextFireTime();
- GHOST_TInt64 maxSleep = next - getMilliSeconds();
-
- if (next == GHOST_kFireTimeNever) {
- ::WaitMessage();
- }
- else if (maxSleep >= 0.0) {
- ::SetTimer(NULL, 0, maxSleep, NULL);
- ::WaitMessage();
- ::KillTimer(NULL, 0);
- }
+ GHOST_TUns64 next = timerMgr->nextFireTime();
+ GHOST_TInt64 maxSleep = next - getMilliSeconds();
+
+ if (next == GHOST_kFireTimeNever) {
+ ::WaitMessage();
+ }
+ else if (maxSleep >= 0.0) {
+ ::SetTimer(NULL, 0, maxSleep, NULL);
+ ::WaitMessage();
+ ::KillTimer(NULL, 0);
+ }
#endif
- }
-
- if (timerMgr->fireTimers(getMilliSeconds())) {
- hasEventHandled = true;
- }
-
- // Process all the events waiting for us
- while (::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
- // TranslateMessage doesn't alter the message, and doesn't change our raw keyboard data.
- // Needed for MapVirtualKey or if we ever need to get chars from wm_ime_char or similar.
- ::TranslateMessage(&msg);
- ::DispatchMessageW(&msg);
- hasEventHandled = true;
- }
- } while (waitForEvent && !hasEventHandled);
-
- return hasEventHandled;
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ hasEventHandled = true;
+ }
+
+ // Process all the events waiting for us
+ while (::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
+ // TranslateMessage doesn't alter the message, and doesn't change our raw keyboard data.
+ // Needed for MapVirtualKey or if we ever need to get chars from wm_ime_char or similar.
+ ::TranslateMessage(&msg);
+ ::DispatchMessageW(&msg);
+ hasEventHandled = true;
+ }
+ } while (waitForEvent && !hasEventHandled);
+
+ return hasEventHandled;
}
-
GHOST_TSuccess GHOST_SystemWin32::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- POINT point;
- if (::GetCursorPos(&point)) {
- x = point.x;
- y = point.y;
- return GHOST_kSuccess;
- }
- return GHOST_kFailure;
+ POINT point;
+ if (::GetCursorPos(&point)) {
+ x = point.x;
+ y = point.y;
+ return GHOST_kSuccess;
+ }
+ return GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
{
- if (!::GetActiveWindow())
- return GHOST_kFailure;
- return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ if (!::GetActiveWindow())
+ return GHOST_kFailure;
+ return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) const
{
- bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
- keys.set(GHOST_kModifierKeyLeftShift, down);
- down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
- keys.set(GHOST_kModifierKeyRightShift, down);
-
- down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
- keys.set(GHOST_kModifierKeyLeftAlt, down);
- down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
- keys.set(GHOST_kModifierKeyRightAlt, down);
-
- down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
- keys.set(GHOST_kModifierKeyLeftControl, down);
- down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
- keys.set(GHOST_kModifierKeyRightControl, down);
-
- bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
- bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
- if (lwindown || rwindown)
- keys.set(GHOST_kModifierKeyOS, true);
- else
- keys.set(GHOST_kModifierKeyOS, false);
- return GHOST_kSuccess;
+ bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
+ keys.set(GHOST_kModifierKeyLeftShift, down);
+ down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
+ keys.set(GHOST_kModifierKeyRightShift, down);
+
+ down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
+ keys.set(GHOST_kModifierKeyLeftAlt, down);
+ down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
+ keys.set(GHOST_kModifierKeyRightAlt, down);
+
+ down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
+ keys.set(GHOST_kModifierKeyLeftControl, down);
+ down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
+ keys.set(GHOST_kModifierKeyRightControl, down);
+
+ bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
+ bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
+ if (lwindown || rwindown)
+ keys.set(GHOST_kModifierKeyOS, true);
+ else
+ keys.set(GHOST_kModifierKeyOS, false);
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const
{
- /* Check for swapped buttons (left-handed mouse buttons)
- * GetAsyncKeyState() will give back the state of the physical mouse buttons.
- */
- bool swapped = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE;
+ /* Check for swapped buttons (left-handed mouse buttons)
+ * GetAsyncKeyState() will give back the state of the physical mouse buttons.
+ */
+ bool swapped = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE;
- bool down = HIBYTE(::GetKeyState(VK_LBUTTON)) != 0;
- buttons.set(swapped ? GHOST_kButtonMaskRight : GHOST_kButtonMaskLeft, down);
+ bool down = HIBYTE(::GetKeyState(VK_LBUTTON)) != 0;
+ buttons.set(swapped ? GHOST_kButtonMaskRight : GHOST_kButtonMaskLeft, down);
- down = HIBYTE(::GetKeyState(VK_MBUTTON)) != 0;
- buttons.set(GHOST_kButtonMaskMiddle, down);
+ down = HIBYTE(::GetKeyState(VK_MBUTTON)) != 0;
+ buttons.set(GHOST_kButtonMaskMiddle, down);
- down = HIBYTE(::GetKeyState(VK_RBUTTON)) != 0;
- buttons.set(swapped ? GHOST_kButtonMaskLeft : GHOST_kButtonMaskRight, down);
- return GHOST_kSuccess;
+ down = HIBYTE(::GetKeyState(VK_RBUTTON)) != 0;
+ buttons.set(swapped ? GHOST_kButtonMaskLeft : GHOST_kButtonMaskRight, down);
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_SystemWin32::init()
{
- GHOST_TSuccess success = GHOST_System::init();
-
- /* Disable scaling on high DPI displays on Vista */
- HMODULE
- user32 = ::LoadLibraryA("user32.dll");
- typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
- LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
- (LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
- if (SetProcessDPIAware)
- SetProcessDPIAware();
- FreeLibrary(user32);
- initRawInput();
-
- // Determine whether this system has a high frequency performance counter. */
- m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER *)&m_freq) == TRUE;
- if (m_hasPerformanceCounter) {
- GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer available\n");
- ::QueryPerformanceCounter((LARGE_INTEGER *)&m_start);
- }
- else {
- GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer not available\n");
- }
-
- if (success) {
- WNDCLASSW wc = {0};
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = s_wndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = ::GetModuleHandle(0);
- wc.hIcon = ::LoadIcon(wc.hInstance, "APPICON");
-
- if (!wc.hIcon) {
- ::LoadIcon(NULL, IDI_APPLICATION);
- }
- wc.hCursor = ::LoadCursor(0, IDC_ARROW);
- wc.hbrBackground =
+ GHOST_TSuccess success = GHOST_System::init();
+
+ /* Disable scaling on high DPI displays on Vista */
+ HMODULE
+ user32 = ::LoadLibraryA("user32.dll");
+ typedef BOOL(WINAPI * LPFNSETPROCESSDPIAWARE)();
+ LPFNSETPROCESSDPIAWARE SetProcessDPIAware = (LPFNSETPROCESSDPIAWARE)GetProcAddress(
+ user32, "SetProcessDPIAware");
+ if (SetProcessDPIAware)
+ SetProcessDPIAware();
+ FreeLibrary(user32);
+ initRawInput();
+
+ // Determine whether this system has a high frequency performance counter. */
+ m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER *)&m_freq) == TRUE;
+ if (m_hasPerformanceCounter) {
+ GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer available\n");
+ ::QueryPerformanceCounter((LARGE_INTEGER *)&m_start);
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer not available\n");
+ }
+
+ if (success) {
+ WNDCLASSW wc = {0};
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = s_wndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = ::GetModuleHandle(0);
+ wc.hIcon = ::LoadIcon(wc.hInstance, "APPICON");
+
+ if (!wc.hIcon) {
+ ::LoadIcon(NULL, IDI_APPLICATION);
+ }
+ wc.hCursor = ::LoadCursor(0, IDC_ARROW);
+ wc.hbrBackground =
#ifdef INW32_COMPISITING
- (HBRUSH)CreateSolidBrush
+ (HBRUSH)CreateSolidBrush
#endif
- (0x00000000);
- wc.lpszMenuName = 0;
- wc.lpszClassName = L"GHOST_WindowClass";
+ (0x00000000);
+ wc.lpszMenuName = 0;
+ wc.lpszClassName = L"GHOST_WindowClass";
- // Use RegisterClassEx for setting small icon
- if (::RegisterClassW(&wc) == 0) {
- success = GHOST_kFailure;
- }
- }
+ // Use RegisterClassEx for setting small icon
+ if (::RegisterClassW(&wc) == 0) {
+ success = GHOST_kFailure;
+ }
+ }
- return success;
+ return success;
}
-
GHOST_TSuccess GHOST_SystemWin32::exit()
{
- return GHOST_System::exit();
+ return GHOST_System::exit();
}
GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *vk)
{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- GHOST_TKey key = GHOST_kKeyUnknown;
- GHOST_ModifierKeys modifiers;
- system->retrieveModifierKeys(modifiers);
-
- // RI_KEY_BREAK doesn't work for sticky keys release, so we also
- // check for the up message
- unsigned int msg = raw.data.keyboard.Message;
- *keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP;
-
- key = this->convertKey(raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0)));
-
- // extra handling of modifier keys: don't send repeats out from GHOST
- if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) {
- bool changed = false;
- GHOST_TModifierKeyMask modifier;
- switch (key) {
- case GHOST_kKeyLeftShift:
- {
- changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyLeftShift;
- break;
- }
- case GHOST_kKeyRightShift:
- {
- changed = (modifiers.get(GHOST_kModifierKeyRightShift) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyRightShift;
- break;
- }
- case GHOST_kKeyLeftControl:
- {
- changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyLeftControl;
- break;
- }
- case GHOST_kKeyRightControl:
- {
- changed = (modifiers.get(GHOST_kModifierKeyRightControl) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyRightControl;
- break;
- }
- case GHOST_kKeyLeftAlt:
- {
- changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyLeftAlt;
- break;
- }
- case GHOST_kKeyRightAlt:
- {
- changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyRightAlt;
- break;
- }
- default:
- break;
- }
-
- if (changed) {
- modifiers.set(modifier, (bool)*keyDown);
- system->storeModifierKeys(modifiers);
- }
- else {
- key = GHOST_kKeyUnknown;
- }
- }
-
-
- if (vk) *vk = raw.data.keyboard.VKey;
-
- return key;
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ GHOST_TKey key = GHOST_kKeyUnknown;
+ GHOST_ModifierKeys modifiers;
+ system->retrieveModifierKeys(modifiers);
+
+ // RI_KEY_BREAK doesn't work for sticky keys release, so we also
+ // check for the up message
+ unsigned int msg = raw.data.keyboard.Message;
+ *keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP;
+
+ key = this->convertKey(raw.data.keyboard.VKey,
+ raw.data.keyboard.MakeCode,
+ (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0)));
+
+ // extra handling of modifier keys: don't send repeats out from GHOST
+ if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) {
+ bool changed = false;
+ GHOST_TModifierKeyMask modifier;
+ switch (key) {
+ case GHOST_kKeyLeftShift: {
+ changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyLeftShift;
+ break;
+ }
+ case GHOST_kKeyRightShift: {
+ changed = (modifiers.get(GHOST_kModifierKeyRightShift) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyRightShift;
+ break;
+ }
+ case GHOST_kKeyLeftControl: {
+ changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyLeftControl;
+ break;
+ }
+ case GHOST_kKeyRightControl: {
+ changed = (modifiers.get(GHOST_kModifierKeyRightControl) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyRightControl;
+ break;
+ }
+ case GHOST_kKeyLeftAlt: {
+ changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyLeftAlt;
+ break;
+ }
+ case GHOST_kKeyRightAlt: {
+ changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyRightAlt;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (changed) {
+ modifiers.set(modifier, (bool)*keyDown);
+ system->storeModifierKeys(modifiers);
+ }
+ else {
+ key = GHOST_kKeyUnknown;
+ }
+ }
+
+ if (vk)
+ *vk = raw.data.keyboard.VKey;
+
+ return key;
}
//! note: this function can be extended to include other exotic cases as they arise.
@@ -653,1167 +649,1229 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *v
// This is going to be a long list [T42426]
GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const
{
- GHOST_TKey key = GHOST_kKeyUnknown;
- switch (PRIMARYLANGID(m_langId)) {
- case LANG_FRENCH:
- if (vKey == VK_OEM_8) key = GHOST_kKeyF13; // oem key; used purely for shortcuts .
- break;
- case LANG_ENGLISH:
- if (SUBLANGID(m_langId) == SUBLANG_ENGLISH_UK && vKey == VK_OEM_8) // "`¬"
- key = GHOST_kKeyAccentGrave;
- break;
- }
-
- return key;
+ GHOST_TKey key = GHOST_kKeyUnknown;
+ switch (PRIMARYLANGID(m_langId)) {
+ case LANG_FRENCH:
+ if (vKey == VK_OEM_8)
+ key = GHOST_kKeyF13; // oem key; used purely for shortcuts .
+ break;
+ case LANG_ENGLISH:
+ if (SUBLANGID(m_langId) == SUBLANG_ENGLISH_UK && vKey == VK_OEM_8) // "`¬"
+ key = GHOST_kKeyAccentGrave;
+ break;
+ }
+
+ return key;
}
GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short extend) const
{
- GHOST_TKey key;
-
- if ((vKey >= '0') && (vKey <= '9')) {
- // VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39)
- key = (GHOST_TKey)(vKey - '0' + GHOST_kKey0);
- }
- else if ((vKey >= 'A') && (vKey <= 'Z')) {
- // VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A)
- key = (GHOST_TKey)(vKey - 'A' + GHOST_kKeyA);
- }
- else if ((vKey >= VK_F1) && (vKey <= VK_F24)) {
- key = (GHOST_TKey)(vKey - VK_F1 + GHOST_kKeyF1);
- }
- else {
- switch (vKey) {
- case VK_RETURN:
- key = (extend) ? GHOST_kKeyNumpadEnter : GHOST_kKeyEnter; break;
-
- case VK_BACK: key = GHOST_kKeyBackSpace; break;
- case VK_TAB: key = GHOST_kKeyTab; break;
- case VK_ESCAPE: key = GHOST_kKeyEsc; break;
- case VK_SPACE: key = GHOST_kKeySpace; break;
-
- case VK_INSERT:
- case VK_NUMPAD0:
- key = (extend) ? GHOST_kKeyInsert : GHOST_kKeyNumpad0; break;
- case VK_END:
- case VK_NUMPAD1:
- key = (extend) ? GHOST_kKeyEnd : GHOST_kKeyNumpad1; break;
- case VK_DOWN:
- case VK_NUMPAD2:
- key = (extend) ? GHOST_kKeyDownArrow : GHOST_kKeyNumpad2; break;
- case VK_NEXT:
- case VK_NUMPAD3:
- key = (extend) ? GHOST_kKeyDownPage : GHOST_kKeyNumpad3; break;
- case VK_LEFT:
- case VK_NUMPAD4:
- key = (extend) ? GHOST_kKeyLeftArrow : GHOST_kKeyNumpad4; break;
- case VK_CLEAR:
- case VK_NUMPAD5:
- key = (extend) ? GHOST_kKeyUnknown : GHOST_kKeyNumpad5; break;
- case VK_RIGHT:
- case VK_NUMPAD6:
- key = (extend) ? GHOST_kKeyRightArrow : GHOST_kKeyNumpad6; break;
- case VK_HOME:
- case VK_NUMPAD7:
- key = (extend) ? GHOST_kKeyHome : GHOST_kKeyNumpad7; break;
- case VK_UP:
- case VK_NUMPAD8:
- key = (extend) ? GHOST_kKeyUpArrow : GHOST_kKeyNumpad8; break;
- case VK_PRIOR:
- case VK_NUMPAD9:
- key = (extend) ? GHOST_kKeyUpPage : GHOST_kKeyNumpad9; break;
- case VK_DECIMAL:
- case VK_DELETE:
- key = (extend) ? GHOST_kKeyDelete : GHOST_kKeyNumpadPeriod; break;
-
- case VK_SNAPSHOT: key = GHOST_kKeyPrintScreen; break;
- case VK_PAUSE: key = GHOST_kKeyPause; break;
- case VK_MULTIPLY: key = GHOST_kKeyNumpadAsterisk; break;
- case VK_SUBTRACT: key = GHOST_kKeyNumpadMinus; break;
- case VK_DIVIDE: key = GHOST_kKeyNumpadSlash; break;
- case VK_ADD: key = GHOST_kKeyNumpadPlus; break;
-
- case VK_SEMICOLON: key = GHOST_kKeySemicolon; break;
- case VK_EQUALS: key = GHOST_kKeyEqual; break;
- case VK_COMMA: key = GHOST_kKeyComma; break;
- case VK_MINUS: key = GHOST_kKeyMinus; break;
- case VK_PERIOD: key = GHOST_kKeyPeriod; break;
- case VK_SLASH: key = GHOST_kKeySlash; break;
- case VK_BACK_QUOTE: key = GHOST_kKeyAccentGrave; break;
- case VK_OPEN_BRACKET: key = GHOST_kKeyLeftBracket; break;
- case VK_BACK_SLASH: key = GHOST_kKeyBackslash; break;
- case VK_CLOSE_BRACKET: key = GHOST_kKeyRightBracket; break;
- case VK_QUOTE: key = GHOST_kKeyQuote; break;
- case VK_GR_LESS: key = GHOST_kKeyGrLess; break;
-
- case VK_SHIFT:
- /* Check single shift presses */
- if (scanCode == 0x36) {
- key = GHOST_kKeyRightShift;
- }
- else if (scanCode == 0x2a) {
- key = GHOST_kKeyLeftShift;
- }
- else {
- /* Must be a combination SHIFT (Left or Right) + a Key
- * Ignore this as the next message will contain
- * the desired "Key" */
- key = GHOST_kKeyUnknown;
- }
- break;
- case VK_CONTROL:
- key = (extend) ? GHOST_kKeyRightControl : GHOST_kKeyLeftControl;
- break;
- case VK_MENU:
- key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt;
- break;
- case VK_LWIN:
- case VK_RWIN:
- key = GHOST_kKeyOS;
- break;
- case VK_NUMLOCK: key = GHOST_kKeyNumLock; break;
- case VK_SCROLL: key = GHOST_kKeyScrollLock; break;
- case VK_CAPITAL: key = GHOST_kKeyCapsLock; break;
- case VK_OEM_8:
- key = ((GHOST_SystemWin32 *)getSystem())->processSpecialKey(vKey, scanCode);
- break;
- case VK_MEDIA_PLAY_PAUSE: key = GHOST_kKeyMediaPlay; break;
- case VK_MEDIA_STOP: key = GHOST_kKeyMediaStop; break;
- case VK_MEDIA_PREV_TRACK: key = GHOST_kKeyMediaFirst; break;
- case VK_MEDIA_NEXT_TRACK: key = GHOST_kKeyMediaLast; break;
- default:
- key = GHOST_kKeyUnknown;
- break;
- }
- }
-
- return key;
+ GHOST_TKey key;
+
+ if ((vKey >= '0') && (vKey <= '9')) {
+ // VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39)
+ key = (GHOST_TKey)(vKey - '0' + GHOST_kKey0);
+ }
+ else if ((vKey >= 'A') && (vKey <= 'Z')) {
+ // VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A)
+ key = (GHOST_TKey)(vKey - 'A' + GHOST_kKeyA);
+ }
+ else if ((vKey >= VK_F1) && (vKey <= VK_F24)) {
+ key = (GHOST_TKey)(vKey - VK_F1 + GHOST_kKeyF1);
+ }
+ else {
+ switch (vKey) {
+ case VK_RETURN:
+ key = (extend) ? GHOST_kKeyNumpadEnter : GHOST_kKeyEnter;
+ break;
+
+ case VK_BACK:
+ key = GHOST_kKeyBackSpace;
+ break;
+ case VK_TAB:
+ key = GHOST_kKeyTab;
+ break;
+ case VK_ESCAPE:
+ key = GHOST_kKeyEsc;
+ break;
+ case VK_SPACE:
+ key = GHOST_kKeySpace;
+ break;
+
+ case VK_INSERT:
+ case VK_NUMPAD0:
+ key = (extend) ? GHOST_kKeyInsert : GHOST_kKeyNumpad0;
+ break;
+ case VK_END:
+ case VK_NUMPAD1:
+ key = (extend) ? GHOST_kKeyEnd : GHOST_kKeyNumpad1;
+ break;
+ case VK_DOWN:
+ case VK_NUMPAD2:
+ key = (extend) ? GHOST_kKeyDownArrow : GHOST_kKeyNumpad2;
+ break;
+ case VK_NEXT:
+ case VK_NUMPAD3:
+ key = (extend) ? GHOST_kKeyDownPage : GHOST_kKeyNumpad3;
+ break;
+ case VK_LEFT:
+ case VK_NUMPAD4:
+ key = (extend) ? GHOST_kKeyLeftArrow : GHOST_kKeyNumpad4;
+ break;
+ case VK_CLEAR:
+ case VK_NUMPAD5:
+ key = (extend) ? GHOST_kKeyUnknown : GHOST_kKeyNumpad5;
+ break;
+ case VK_RIGHT:
+ case VK_NUMPAD6:
+ key = (extend) ? GHOST_kKeyRightArrow : GHOST_kKeyNumpad6;
+ break;
+ case VK_HOME:
+ case VK_NUMPAD7:
+ key = (extend) ? GHOST_kKeyHome : GHOST_kKeyNumpad7;
+ break;
+ case VK_UP:
+ case VK_NUMPAD8:
+ key = (extend) ? GHOST_kKeyUpArrow : GHOST_kKeyNumpad8;
+ break;
+ case VK_PRIOR:
+ case VK_NUMPAD9:
+ key = (extend) ? GHOST_kKeyUpPage : GHOST_kKeyNumpad9;
+ break;
+ case VK_DECIMAL:
+ case VK_DELETE:
+ key = (extend) ? GHOST_kKeyDelete : GHOST_kKeyNumpadPeriod;
+ break;
+
+ case VK_SNAPSHOT:
+ key = GHOST_kKeyPrintScreen;
+ break;
+ case VK_PAUSE:
+ key = GHOST_kKeyPause;
+ break;
+ case VK_MULTIPLY:
+ key = GHOST_kKeyNumpadAsterisk;
+ break;
+ case VK_SUBTRACT:
+ key = GHOST_kKeyNumpadMinus;
+ break;
+ case VK_DIVIDE:
+ key = GHOST_kKeyNumpadSlash;
+ break;
+ case VK_ADD:
+ key = GHOST_kKeyNumpadPlus;
+ break;
+
+ case VK_SEMICOLON:
+ key = GHOST_kKeySemicolon;
+ break;
+ case VK_EQUALS:
+ key = GHOST_kKeyEqual;
+ break;
+ case VK_COMMA:
+ key = GHOST_kKeyComma;
+ break;
+ case VK_MINUS:
+ key = GHOST_kKeyMinus;
+ break;
+ case VK_PERIOD:
+ key = GHOST_kKeyPeriod;
+ break;
+ case VK_SLASH:
+ key = GHOST_kKeySlash;
+ break;
+ case VK_BACK_QUOTE:
+ key = GHOST_kKeyAccentGrave;
+ break;
+ case VK_OPEN_BRACKET:
+ key = GHOST_kKeyLeftBracket;
+ break;
+ case VK_BACK_SLASH:
+ key = GHOST_kKeyBackslash;
+ break;
+ case VK_CLOSE_BRACKET:
+ key = GHOST_kKeyRightBracket;
+ break;
+ case VK_QUOTE:
+ key = GHOST_kKeyQuote;
+ break;
+ case VK_GR_LESS:
+ key = GHOST_kKeyGrLess;
+ break;
+
+ case VK_SHIFT:
+ /* Check single shift presses */
+ if (scanCode == 0x36) {
+ key = GHOST_kKeyRightShift;
+ }
+ else if (scanCode == 0x2a) {
+ key = GHOST_kKeyLeftShift;
+ }
+ else {
+ /* Must be a combination SHIFT (Left or Right) + a Key
+ * Ignore this as the next message will contain
+ * the desired "Key" */
+ key = GHOST_kKeyUnknown;
+ }
+ break;
+ case VK_CONTROL:
+ key = (extend) ? GHOST_kKeyRightControl : GHOST_kKeyLeftControl;
+ break;
+ case VK_MENU:
+ key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt;
+ break;
+ case VK_LWIN:
+ case VK_RWIN:
+ key = GHOST_kKeyOS;
+ break;
+ case VK_NUMLOCK:
+ key = GHOST_kKeyNumLock;
+ break;
+ case VK_SCROLL:
+ key = GHOST_kKeyScrollLock;
+ break;
+ case VK_CAPITAL:
+ key = GHOST_kKeyCapsLock;
+ break;
+ case VK_OEM_8:
+ key = ((GHOST_SystemWin32 *)getSystem())->processSpecialKey(vKey, scanCode);
+ break;
+ case VK_MEDIA_PLAY_PAUSE:
+ key = GHOST_kKeyMediaPlay;
+ break;
+ case VK_MEDIA_STOP:
+ key = GHOST_kKeyMediaStop;
+ break;
+ case VK_MEDIA_PREV_TRACK:
+ key = GHOST_kKeyMediaFirst;
+ break;
+ case VK_MEDIA_NEXT_TRACK:
+ key = GHOST_kKeyMediaLast;
+ break;
+ default:
+ key = GHOST_kKeyUnknown;
+ break;
+ }
+ }
+
+ return key;
}
-GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(
- GHOST_TEventType type,
- GHOST_WindowWin32 *window,
- GHOST_TButtonMask mask)
+GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window,
+ GHOST_TButtonMask mask)
{
- GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
- if (window->useTabletAPI(GHOST_kTabletNative)) {
- window->setTabletData(NULL);
- }
- return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask);
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ if (window->useTabletAPI(GHOST_kTabletNative)) {
+ window->setTabletData(NULL);
+ }
+ return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask);
}
-GHOST_Event *GHOST_SystemWin32::processPointerEvent(
- GHOST_TEventType type,
- GHOST_WindowWin32 *window,
- WPARAM wParam,
- LPARAM lParam,
- bool& eventHandled)
+GHOST_Event *GHOST_SystemWin32::processPointerEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window,
+ WPARAM wParam,
+ LPARAM lParam,
+ bool &eventHandled)
{
- GHOST_PointerInfoWin32 pointerInfo;
- GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
-
- if (!window->useTabletAPI(GHOST_kTabletNative)) {
- return NULL;
- }
-
- if (window->getPointerInfo(&pointerInfo, wParam, lParam) != GHOST_kSuccess) {
- return NULL;
- }
-
- if (!pointerInfo.isPrimary) {
- eventHandled = true;
- return NULL; // For multi-touch displays we ignore these events
- }
-
- system->setCursorPosition(pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y);
-
- switch (type) {
- case GHOST_kEventButtonDown:
- window->setTabletData(&pointerInfo.tabletData);
- eventHandled = true;
- return new GHOST_EventButton(system->getMilliSeconds(), GHOST_kEventButtonDown, window, pointerInfo.buttonMask);
- case GHOST_kEventButtonUp:
- eventHandled = true;
- return new GHOST_EventButton(system->getMilliSeconds(), GHOST_kEventButtonUp, window, pointerInfo.buttonMask);
- case GHOST_kEventCursorMove:
- window->setTabletData(&pointerInfo.tabletData);
- eventHandled = true;
- return new GHOST_EventCursor(system->getMilliSeconds(), GHOST_kEventCursorMove, window,
- pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y);
- default:
- return NULL;
- }
+ GHOST_PointerInfoWin32 pointerInfo;
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+
+ if (!window->useTabletAPI(GHOST_kTabletNative)) {
+ return NULL;
+ }
+
+ if (window->getPointerInfo(&pointerInfo, wParam, lParam) != GHOST_kSuccess) {
+ return NULL;
+ }
+
+ if (!pointerInfo.isPrimary) {
+ eventHandled = true;
+ return NULL; // For multi-touch displays we ignore these events
+ }
+
+ system->setCursorPosition(pointerInfo.pixelLocation.x, pointerInfo.pixelLocation.y);
+
+ switch (type) {
+ case GHOST_kEventButtonDown:
+ window->setTabletData(&pointerInfo.tabletData);
+ eventHandled = true;
+ return new GHOST_EventButton(
+ system->getMilliSeconds(), GHOST_kEventButtonDown, window, pointerInfo.buttonMask);
+ case GHOST_kEventButtonUp:
+ eventHandled = true;
+ return new GHOST_EventButton(
+ system->getMilliSeconds(), GHOST_kEventButtonUp, window, pointerInfo.buttonMask);
+ case GHOST_kEventCursorMove:
+ window->setTabletData(&pointerInfo.tabletData);
+ eventHandled = true;
+ return new GHOST_EventCursor(system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ pointerInfo.pixelLocation.x,
+ pointerInfo.pixelLocation.y);
+ default:
+ return NULL;
+ }
}
-GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window)
+GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window)
{
- GHOST_TInt32 x_screen, y_screen;
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *) getSystem();
-
- system->getCursorPosition(x_screen, y_screen);
-
- /* TODO: CHECK IF THIS IS A TABLET EVENT */
- bool is_tablet = false;
-
- if (is_tablet == false && window->getCursorGrabModeIsWarp()) {
- GHOST_TInt32 x_new = x_screen;
- GHOST_TInt32 y_new = y_screen;
- GHOST_TInt32 x_accum, y_accum;
- GHOST_Rect bounds;
-
- /* fallback to window bounds */
- if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
- window->getClientBounds(bounds);
- }
-
- /* could also clamp to screen bounds
- * wrap with a window outside the view will fail atm */
-
- bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */
-
- window->getCursorGrabAccum(x_accum, y_accum);
- if (x_new != x_screen || y_new != y_screen) {
- /* when wrapping we don't need to add an event because the
- * setCursorPosition call will cause a new event after */
- system->setCursorPosition(x_new, y_new); /* wrap */
- window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new));
- }
- else {
- return new GHOST_EventCursor(system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- x_screen + x_accum,
- y_screen + y_accum
- );
- }
-
- }
- else {
- return new GHOST_EventCursor(system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- x_screen,
- y_screen
- );
- }
- return NULL;
+ GHOST_TInt32 x_screen, y_screen;
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+
+ system->getCursorPosition(x_screen, y_screen);
+
+ /* TODO: CHECK IF THIS IS A TABLET EVENT */
+ bool is_tablet = false;
+
+ if (is_tablet == false && window->getCursorGrabModeIsWarp()) {
+ GHOST_TInt32 x_new = x_screen;
+ GHOST_TInt32 y_new = y_screen;
+ GHOST_TInt32 x_accum, y_accum;
+ GHOST_Rect bounds;
+
+ /* fallback to window bounds */
+ if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
+ window->getClientBounds(bounds);
+ }
+
+ /* could also clamp to screen bounds
+ * wrap with a window outside the view will fail atm */
+
+ bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */
+
+ window->getCursorGrabAccum(x_accum, y_accum);
+ if (x_new != x_screen || y_new != y_screen) {
+ /* when wrapping we don't need to add an event because the
+ * setCursorPosition call will cause a new event after */
+ system->setCursorPosition(x_new, y_new); /* wrap */
+ window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new));
+ }
+ else {
+ return new GHOST_EventCursor(system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ x_screen + x_accum,
+ y_screen + y_accum);
+ }
+ }
+ else {
+ return new GHOST_EventCursor(
+ system->getMilliSeconds(), GHOST_kEventCursorMove, window, x_screen, y_screen);
+ }
+ return NULL;
}
-
void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam)
{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
-
- int acc = system->m_wheelDeltaAccum;
- int delta = GET_WHEEL_DELTA_WPARAM(wParam);
-
- if (acc * delta < 0) {
- // scroll direction reversed.
- acc = 0;
- }
- acc += delta;
- int direction = (acc >= 0) ? 1 : -1;
- acc = abs(acc);
-
- while (acc >= WHEEL_DELTA) {
- system->pushEvent(new GHOST_EventWheel(system->getMilliSeconds(), window, direction));
- acc -= WHEEL_DELTA;
- }
- system->m_wheelDeltaAccum = acc * direction;
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+
+ int acc = system->m_wheelDeltaAccum;
+ int delta = GET_WHEEL_DELTA_WPARAM(wParam);
+
+ if (acc * delta < 0) {
+ // scroll direction reversed.
+ acc = 0;
+ }
+ acc += delta;
+ int direction = (acc >= 0) ? 1 : -1;
+ acc = abs(acc);
+
+ while (acc >= WHEEL_DELTA) {
+ system->pushEvent(new GHOST_EventWheel(system->getMilliSeconds(), window, direction));
+ acc -= WHEEL_DELTA;
+ }
+ system->m_wheelDeltaAccum = acc * direction;
}
-
GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw)
{
- int keyDown = 0;
- char vk;
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- GHOST_TKey key = system->hardKey(raw, &keyDown, &vk);
- GHOST_EventKey *event;
-
- if (key != GHOST_kKeyUnknown) {
- char utf8_char[6] = {0};
- char ascii = 0;
-
- wchar_t utf16[3] = {0};
- BYTE state[256] = {0};
- int r;
- GetKeyboardState((PBYTE)state);
-
- // don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical composition.
- if (MapVirtualKeyW(vk, 2) != 0) {
- // todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). Could be up to 24 utf8 bytes.
- if ((r = ToUnicodeEx(vk, raw.data.keyboard.MakeCode, state, utf16, 2, 0, system->m_keylayout))) {
- if ((r > 0 && r < 3)) {
- utf16[r] = 0;
- conv_utf_16_to_8(utf16, utf8_char, 6);
- }
- else if (r == -1) {
- utf8_char[0] = '\0';
- }
- }
- }
-
- if (!keyDown) {
- utf8_char[0] = '\0';
- ascii = '\0';
- }
- else {
- ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0];
- }
-
- event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, ascii, utf8_char);
-
- // GHOST_PRINTF("%c\n", ascii); // we already get this info via EventPrinter
- }
- else {
- event = NULL;
- }
- return event;
+ int keyDown = 0;
+ char vk;
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ GHOST_TKey key = system->hardKey(raw, &keyDown, &vk);
+ GHOST_EventKey *event;
+
+ if (key != GHOST_kKeyUnknown) {
+ char utf8_char[6] = {0};
+ char ascii = 0;
+
+ wchar_t utf16[3] = {0};
+ BYTE state[256] = {0};
+ int r;
+ GetKeyboardState((PBYTE)state);
+
+ // don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical composition.
+ if (MapVirtualKeyW(vk, 2) != 0) {
+ // todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). Could be up to 24 utf8 bytes.
+ if ((r = ToUnicodeEx(
+ vk, raw.data.keyboard.MakeCode, state, utf16, 2, 0, system->m_keylayout))) {
+ if ((r > 0 && r < 3)) {
+ utf16[r] = 0;
+ conv_utf_16_to_8(utf16, utf8_char, 6);
+ }
+ else if (r == -1) {
+ utf8_char[0] = '\0';
+ }
+ }
+ }
+
+ if (!keyDown) {
+ utf8_char[0] = '\0';
+ ascii = '\0';
+ }
+ else {
+ ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0];
+ }
+
+ event = new GHOST_EventKey(system->getMilliSeconds(),
+ keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp,
+ window,
+ key,
+ ascii,
+ utf8_char);
+
+ // GHOST_PRINTF("%c\n", ascii); // we already get this info via EventPrinter
+ }
+ else {
+ event = NULL;
+ }
+ return event;
}
-
-GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window)
+GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window)
{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- if (type == GHOST_kEventWindowActivate) {
- system->getWindowManager()->setActiveWindow(window);
- window->bringTabletContextToFront();
- }
+ if (type == GHOST_kEventWindowActivate) {
+ system->getWindowManager()->setActiveWindow(window);
+ window->bringTabletContextToFront();
+ }
- return new GHOST_Event(system->getMilliSeconds(), type, window);
+ return new GHOST_Event(system->getMilliSeconds(), type, window);
}
#ifdef WITH_INPUT_IME
-GHOST_Event *GHOST_SystemWin32::processImeEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TEventImeData *data)
+GHOST_Event *GHOST_SystemWin32::processImeEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window,
+ GHOST_TEventImeData *data)
{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- return new GHOST_EventIME(system->getMilliSeconds(), type, window, data);
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ return new GHOST_EventIME(system->getMilliSeconds(), type, window, data);
}
#endif
-
-GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(
- GHOST_TEventType eventType,
- GHOST_TDragnDropTypes draggedObjectType,
- GHOST_WindowWin32 *window,
- int mouseX, int mouseY,
- void *data)
+GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType,
+ GHOST_TDragnDropTypes draggedObjectType,
+ GHOST_WindowWin32 *window,
+ int mouseX,
+ int mouseY,
+ void *data)
{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- return system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
- eventType,
- draggedObjectType,
- window, mouseX, mouseY, data)
- );
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ return system->pushEvent(new GHOST_EventDragnDrop(
+ system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data));
}
void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax)
{
- minmax->ptMinTrackSize.x = 320;
- minmax->ptMinTrackSize.y = 240;
+ minmax->ptMinTrackSize.x = 320;
+ minmax->ptMinTrackSize.y = 240;
}
#ifdef WITH_INPUT_NDOF
bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw)
{
- bool eventSent = false;
- GHOST_TUns64 now = getMilliSeconds();
-
- static bool firstEvent = true;
- if (firstEvent) { // determine exactly which device is plugged in
- RID_DEVICE_INFO info;
- unsigned infoSize = sizeof(RID_DEVICE_INFO);
- info.cbSize = infoSize;
-
- GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize);
- if (info.dwType == RIM_TYPEHID)
- m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId);
- else
- GHOST_PRINT("<!> not a HID device... mouse/kb perhaps?\n");
-
- firstEvent = false;
- }
-
- // The NDOF manager sends button changes immediately, and *pretends* to
- // send motion. Mark as 'sent' so motion will always get dispatched.
- eventSent = true;
-
- BYTE const *data = raw.data.hid.bRawData;
-
- BYTE packetType = data[0];
- switch (packetType) {
- case 1: // translation
- {
- const short *axis = (short *)(data + 1);
- // massage into blender view coords (same goes for rotation)
- const int t[3] = {axis[0], -axis[2], axis[1]};
- m_ndofManager->updateTranslation(t, now);
-
- if (raw.data.hid.dwSizeHid == 13) {
- // this report also includes rotation
- const int r[3] = {-axis[3], axis[5], -axis[4]};
- m_ndofManager->updateRotation(r, now);
-
- // I've never gotten one of these, has anyone else?
- GHOST_PRINT("ndof: combined T + R\n");
- }
- break;
- }
- case 2: // rotation
- {
- const short *axis = (short *)(data + 1);
- const int r[3] = {-axis[0], axis[2], -axis[1]};
- m_ndofManager->updateRotation(r, now);
- break;
- }
- case 3: // buttons
- {
- int button_bits;
- memcpy(&button_bits, data + 1, sizeof(button_bits));
- m_ndofManager->updateButtons(button_bits, now);
- break;
- }
- }
- return eventSent;
+ bool eventSent = false;
+ GHOST_TUns64 now = getMilliSeconds();
+
+ static bool firstEvent = true;
+ if (firstEvent) { // determine exactly which device is plugged in
+ RID_DEVICE_INFO info;
+ unsigned infoSize = sizeof(RID_DEVICE_INFO);
+ info.cbSize = infoSize;
+
+ GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize);
+ if (info.dwType == RIM_TYPEHID)
+ m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId);
+ else
+ GHOST_PRINT("<!> not a HID device... mouse/kb perhaps?\n");
+
+ firstEvent = false;
+ }
+
+ // The NDOF manager sends button changes immediately, and *pretends* to
+ // send motion. Mark as 'sent' so motion will always get dispatched.
+ eventSent = true;
+
+ BYTE const *data = raw.data.hid.bRawData;
+
+ BYTE packetType = data[0];
+ switch (packetType) {
+ case 1: // translation
+ {
+ const short *axis = (short *)(data + 1);
+ // massage into blender view coords (same goes for rotation)
+ const int t[3] = {axis[0], -axis[2], axis[1]};
+ m_ndofManager->updateTranslation(t, now);
+
+ if (raw.data.hid.dwSizeHid == 13) {
+ // this report also includes rotation
+ const int r[3] = {-axis[3], axis[5], -axis[4]};
+ m_ndofManager->updateRotation(r, now);
+
+ // I've never gotten one of these, has anyone else?
+ GHOST_PRINT("ndof: combined T + R\n");
+ }
+ break;
+ }
+ case 2: // rotation
+ {
+ const short *axis = (short *)(data + 1);
+ const int r[3] = {-axis[0], axis[2], -axis[1]};
+ m_ndofManager->updateRotation(r, now);
+ break;
+ }
+ case 3: // buttons
+ {
+ int button_bits;
+ memcpy(&button_bits, data + 1, sizeof(button_bits));
+ m_ndofManager->updateButtons(button_bits, now);
+ break;
+ }
+ }
+ return eventSent;
}
-#endif // WITH_INPUT_NDOF
+#endif // WITH_INPUT_NDOF
LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- GHOST_Event *event = NULL;
- bool eventHandled = false;
+ GHOST_Event *event = NULL;
+ bool eventHandled = false;
- LRESULT lResult = 0;
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- GHOST_EventManager *eventManager = system->getEventManager();
- GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized");
+ LRESULT lResult = 0;
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ GHOST_EventManager *eventManager = system->getEventManager();
+ GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized");
- if (hwnd) {
+ if (hwnd) {
#if 0
- // Disabled due to bug in Intel drivers, see T51959
- if(msg == WM_NCCREATE) {
- // Tell Windows to automatically handle scaling of non-client areas
- // such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10
- HMODULE m_user32 = ::LoadLibrary("User32.dll");
- if (m_user32) {
- GHOST_WIN32_EnableNonClientDpiScaling fpEnableNonClientDpiScaling =
- (GHOST_WIN32_EnableNonClientDpiScaling) ::GetProcAddress(m_user32, "EnableNonClientDpiScaling");
-
- if (fpEnableNonClientDpiScaling) {
- fpEnableNonClientDpiScaling(hwnd);
- }
- }
- }
+ // Disabled due to bug in Intel drivers, see T51959
+ if(msg == WM_NCCREATE) {
+ // Tell Windows to automatically handle scaling of non-client areas
+ // such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10
+ HMODULE m_user32 = ::LoadLibrary("User32.dll");
+ if (m_user32) {
+ GHOST_WIN32_EnableNonClientDpiScaling fpEnableNonClientDpiScaling =
+ (GHOST_WIN32_EnableNonClientDpiScaling) ::GetProcAddress(m_user32, "EnableNonClientDpiScaling");
+
+ if (fpEnableNonClientDpiScaling) {
+ fpEnableNonClientDpiScaling(hwnd);
+ }
+ }
+ }
#endif
- GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
- if (window) {
- switch (msg) {
- // we need to check if new key layout has AltGr
- case WM_INPUTLANGCHANGE:
- {
- system->handleKeyboardChange();
+ GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (window) {
+ switch (msg) {
+ // we need to check if new key layout has AltGr
+ case WM_INPUTLANGCHANGE: {
+ system->handleKeyboardChange();
#ifdef WITH_INPUT_IME
- window->getImeInput()->SetInputLanguage();
+ window->getImeInput()->SetInputLanguage();
#endif
- break;
- }
- ////////////////////////////////////////////////////////////////////////
- // Keyboard events, processed
- ////////////////////////////////////////////////////////////////////////
- case WM_INPUT:
- {
- // check WM_INPUT from input sink when ghost window is not in the foreground
- if (wParam == RIM_INPUTSINK) {
- if (GetFocus() != hwnd) // WM_INPUT message not for this window
- return 0;
- } //else wParam == RIM_INPUT
-
- RAWINPUT raw;
- RAWINPUT *raw_ptr = &raw;
- UINT rawSize = sizeof(RAWINPUT);
-
- GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER));
-
- switch (raw.header.dwType) {
- case RIM_TYPEKEYBOARD:
- event = processKeyEvent(window, raw);
- if (!event) {
- GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ");
- GHOST_PRINT(msg);
- GHOST_PRINT(" key ignored\n");
- }
- break;
+ break;
+ }
+ ////////////////////////////////////////////////////////////////////////
+ // Keyboard events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_INPUT: {
+ // check WM_INPUT from input sink when ghost window is not in the foreground
+ if (wParam == RIM_INPUTSINK) {
+ if (GetFocus() != hwnd) // WM_INPUT message not for this window
+ return 0;
+ } //else wParam == RIM_INPUT
+
+ RAWINPUT raw;
+ RAWINPUT *raw_ptr = &raw;
+ UINT rawSize = sizeof(RAWINPUT);
+
+ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER));
+
+ switch (raw.header.dwType) {
+ case RIM_TYPEKEYBOARD:
+ event = processKeyEvent(window, raw);
+ if (!event) {
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ");
+ GHOST_PRINT(msg);
+ GHOST_PRINT(" key ignored\n");
+ }
+ break;
#ifdef WITH_INPUT_NDOF
- case RIM_TYPEHID:
- if (system->processNDOF(raw)) {
- eventHandled = true;
- }
- break;
+ case RIM_TYPEHID:
+ if (system->processNDOF(raw)) {
+ eventHandled = true;
+ }
+ break;
#endif
- }
- break;
- }
+ }
+ break;
+ }
#ifdef WITH_INPUT_IME
- ////////////////////////////////////////////////////////////////////////
- // IME events, processed, read more in GHOST_IME.h
- ////////////////////////////////////////////////////////////////////////
- case WM_IME_SETCONTEXT:
- {
- GHOST_ImeWin32 *ime = window->getImeInput();
- ime->SetInputLanguage();
- ime->CreateImeWindow(hwnd);
- ime->CleanupComposition(hwnd);
- ime->CheckFirst(hwnd);
- break;
- }
- case WM_IME_STARTCOMPOSITION:
- {
- GHOST_ImeWin32 *ime = window->getImeInput();
- eventHandled = true;
- /* remove input event before start comp event, avoid redundant input */
- eventManager->removeTypeEvents(GHOST_kEventKeyDown, window);
- ime->CreateImeWindow(hwnd);
- ime->ResetComposition(hwnd);
- event = processImeEvent(
- GHOST_kEventImeCompositionStart,
- window,
- &ime->eventImeData);
- break;
- }
- case WM_IME_COMPOSITION:
- {
- GHOST_ImeWin32 *ime = window->getImeInput();
- eventHandled = true;
- ime->UpdateImeWindow(hwnd);
- ime->UpdateInfo(hwnd);
- if (ime->eventImeData.result_len) {
- /* remove redundant IME event */
- eventManager->removeTypeEvents(GHOST_kEventImeComposition, window);
- }
- event = processImeEvent(
- GHOST_kEventImeComposition,
- window,
- &ime->eventImeData);
- break;
- }
- case WM_IME_ENDCOMPOSITION:
- {
- GHOST_ImeWin32 *ime = window->getImeInput();
- eventHandled = true;
- /* remove input event after end comp event, avoid redundant input */
- eventManager->removeTypeEvents(GHOST_kEventKeyDown, window);
- ime->ResetComposition(hwnd);
- ime->DestroyImeWindow(hwnd);
- event = processImeEvent(
- GHOST_kEventImeCompositionEnd,
- window,
- &ime->eventImeData);
- break;
- }
+ ////////////////////////////////////////////////////////////////////////
+ // IME events, processed, read more in GHOST_IME.h
+ ////////////////////////////////////////////////////////////////////////
+ case WM_IME_SETCONTEXT: {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ ime->SetInputLanguage();
+ ime->CreateImeWindow(hwnd);
+ ime->CleanupComposition(hwnd);
+ ime->CheckFirst(hwnd);
+ break;
+ }
+ case WM_IME_STARTCOMPOSITION: {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ eventHandled = true;
+ /* remove input event before start comp event, avoid redundant input */
+ eventManager->removeTypeEvents(GHOST_kEventKeyDown, window);
+ ime->CreateImeWindow(hwnd);
+ ime->ResetComposition(hwnd);
+ event = processImeEvent(GHOST_kEventImeCompositionStart, window, &ime->eventImeData);
+ break;
+ }
+ case WM_IME_COMPOSITION: {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ eventHandled = true;
+ ime->UpdateImeWindow(hwnd);
+ ime->UpdateInfo(hwnd);
+ if (ime->eventImeData.result_len) {
+ /* remove redundant IME event */
+ eventManager->removeTypeEvents(GHOST_kEventImeComposition, window);
+ }
+ event = processImeEvent(GHOST_kEventImeComposition, window, &ime->eventImeData);
+ break;
+ }
+ case WM_IME_ENDCOMPOSITION: {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ eventHandled = true;
+ /* remove input event after end comp event, avoid redundant input */
+ eventManager->removeTypeEvents(GHOST_kEventKeyDown, window);
+ ime->ResetComposition(hwnd);
+ ime->DestroyImeWindow(hwnd);
+ event = processImeEvent(GHOST_kEventImeCompositionEnd, window, &ime->eventImeData);
+ break;
+ }
#endif /* WITH_INPUT_IME */
- ////////////////////////////////////////////////////////////////////////
- // Keyboard events, ignored
- ////////////////////////////////////////////////////////////////////////
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- case WM_KEYUP:
- case WM_SYSKEYUP:
- /* These functions were replaced by WM_INPUT*/
- case WM_CHAR:
- /* The WM_CHAR message is posted to the window with the keyboard focus when
- * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR
- * contains the character code of the key that was pressed.
- */
- case WM_DEADCHAR:
- /* The WM_DEADCHAR message is posted to the window with the keyboard focus when a
- * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR
- * specifies a character code generated by a dead key. A dead key is a key that
- * generates a character, such as the umlaut (double-dot), that is combined with
- * another character to form a composite character. For example, the umlaut-O
- * character (Ö) is generated by typing the dead key for the umlaut character, and
- * then typing the O key.
- */
- break;
- case WM_SYSDEADCHAR:
- /* The WM_SYSDEADCHAR message is sent to the window with the keyboard focus when
- * a WM_SYSKEYDOWN message is translated by the TranslateMessage function.
- * WM_SYSDEADCHAR specifies the character code of a system dead key - that is,
- * a dead key that is pressed while holding down the alt key.
- */
- case WM_SYSCHAR:
- /* The WM_SYSCHAR message is sent to the window with the keyboard focus when
- * a WM_SYSCHAR message is translated by the TranslateMessage function.
- * WM_SYSCHAR specifies the character code of a dead key - that is,
- * a dead key that is pressed while holding down the alt key.
- * To prevent the sound, DefWindowProc must be avoided by return
- */
- break;
- case WM_SYSCOMMAND:
- /* The WM_SYSCHAR message is sent to the window when system commands such as
- * maximize, minimize or close the window are triggered. Also it is sent when ALT
- * button is press for menu. To prevent this we must return preventing DefWindowProc.
- */
- if (wParam == SC_KEYMENU) {
- eventHandled = true;
- }
- break;
- ////////////////////////////////////////////////////////////////////////
- // Tablet events, processed
- ////////////////////////////////////////////////////////////////////////
- case WT_PACKET:
- window->processWin32TabletEvent(wParam, lParam);
- break;
- case WT_CSRCHANGE:
- case WT_PROXIMITY:
- window->processWin32TabletInitEvent();
- break;
- ////////////////////////////////////////////////////////////////////////
- // Pointer events, processed
- ////////////////////////////////////////////////////////////////////////
- case WM_POINTERDOWN:
- event = processPointerEvent(GHOST_kEventButtonDown, window, wParam, lParam, eventHandled);
- if (event && eventHandled) {
- window->registerMouseClickEvent(0);
- }
- break;
- case WM_POINTERUP:
- event = processPointerEvent(GHOST_kEventButtonUp, window, wParam, lParam, eventHandled);
- if (event && eventHandled) {
- window->registerMouseClickEvent(1);
- }
- break;
- case WM_POINTERUPDATE:
- event = processPointerEvent(GHOST_kEventCursorMove, window, wParam, lParam, eventHandled);
- break;
- ////////////////////////////////////////////////////////////////////////
- // Mouse events, processed
- ////////////////////////////////////////////////////////////////////////
- case WM_LBUTTONDOWN:
- window->registerMouseClickEvent(0);
- event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft);
- break;
- case WM_MBUTTONDOWN:
- window->registerMouseClickEvent(0);
- event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle);
- break;
- case WM_RBUTTONDOWN:
- window->registerMouseClickEvent(0);
- event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
- break;
- case WM_XBUTTONDOWN:
- window->registerMouseClickEvent(0);
- if ((short) HIWORD(wParam) == XBUTTON1) {
- event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4);
- }
- else if ((short) HIWORD(wParam) == XBUTTON2) {
- event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5);
- }
- break;
- case WM_LBUTTONUP:
- window->registerMouseClickEvent(1);
- event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
- break;
- case WM_MBUTTONUP:
- window->registerMouseClickEvent(1);
- event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle);
- break;
- case WM_RBUTTONUP:
- window->registerMouseClickEvent(1);
- event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
- break;
- case WM_XBUTTONUP:
- window->registerMouseClickEvent(1);
- if ((short) HIWORD(wParam) == XBUTTON1) {
- event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4);
- }
- else if ((short) HIWORD(wParam) == XBUTTON2) {
- event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5);
- }
- break;
- case WM_MOUSEMOVE:
- event = processCursorEvent(GHOST_kEventCursorMove, window);
- break;
- case WM_MOUSEWHEEL:
- {
- /* The WM_MOUSEWHEEL message is sent to the focus window
- * when the mouse wheel is rotated. The DefWindowProc
- * function propagates the message to the window's parent.
- * There should be no internal forwarding of the message,
- * since DefWindowProc propagates it up the parent chain
- * until it finds a window that processes it.
- */
-
- /* Get the window under the mouse and send event to its queue. */
- POINT mouse_pos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
- HWND mouse_hwnd = ChildWindowFromPoint(HWND_DESKTOP, mouse_pos);
- GHOST_WindowWin32 *mouse_window = (GHOST_WindowWin32 *)::GetWindowLongPtr(mouse_hwnd, GWLP_USERDATA);
-
- processWheelEvent(mouse_window ? mouse_window : window , wParam, lParam);
- eventHandled = true;
+ ////////////////////////////////////////////////////////////////////////
+ // Keyboard events, ignored
+ ////////////////////////////////////////////////////////////////////////
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ /* These functions were replaced by WM_INPUT*/
+ case WM_CHAR:
+ /* The WM_CHAR message is posted to the window with the keyboard focus when
+ * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR
+ * contains the character code of the key that was pressed.
+ */
+ case WM_DEADCHAR:
+ /* The WM_DEADCHAR message is posted to the window with the keyboard focus when a
+ * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR
+ * specifies a character code generated by a dead key. A dead key is a key that
+ * generates a character, such as the umlaut (double-dot), that is combined with
+ * another character to form a composite character. For example, the umlaut-O
+ * character (Ö) is generated by typing the dead key for the umlaut character, and
+ * then typing the O key.
+ */
+ break;
+ case WM_SYSDEADCHAR:
+ /* The WM_SYSDEADCHAR message is sent to the window with the keyboard focus when
+ * a WM_SYSKEYDOWN message is translated by the TranslateMessage function.
+ * WM_SYSDEADCHAR specifies the character code of a system dead key - that is,
+ * a dead key that is pressed while holding down the alt key.
+ */
+ case WM_SYSCHAR:
+ /* The WM_SYSCHAR message is sent to the window with the keyboard focus when
+ * a WM_SYSCHAR message is translated by the TranslateMessage function.
+ * WM_SYSCHAR specifies the character code of a dead key - that is,
+ * a dead key that is pressed while holding down the alt key.
+ * To prevent the sound, DefWindowProc must be avoided by return
+ */
+ break;
+ case WM_SYSCOMMAND:
+ /* The WM_SYSCHAR message is sent to the window when system commands such as
+ * maximize, minimize or close the window are triggered. Also it is sent when ALT
+ * button is press for menu. To prevent this we must return preventing DefWindowProc.
+ */
+ if (wParam == SC_KEYMENU) {
+ eventHandled = true;
+ }
+ break;
+ ////////////////////////////////////////////////////////////////////////
+ // Tablet events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WT_PACKET:
+ window->processWin32TabletEvent(wParam, lParam);
+ break;
+ case WT_CSRCHANGE:
+ case WT_PROXIMITY:
+ window->processWin32TabletInitEvent();
+ break;
+ ////////////////////////////////////////////////////////////////////////
+ // Pointer events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_POINTERDOWN:
+ event = processPointerEvent(
+ GHOST_kEventButtonDown, window, wParam, lParam, eventHandled);
+ if (event && eventHandled) {
+ window->registerMouseClickEvent(0);
+ }
+ break;
+ case WM_POINTERUP:
+ event = processPointerEvent(GHOST_kEventButtonUp, window, wParam, lParam, eventHandled);
+ if (event && eventHandled) {
+ window->registerMouseClickEvent(1);
+ }
+ break;
+ case WM_POINTERUPDATE:
+ event = processPointerEvent(
+ GHOST_kEventCursorMove, window, wParam, lParam, eventHandled);
+ break;
+ ////////////////////////////////////////////////////////////////////////
+ // Mouse events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_LBUTTONDOWN:
+ window->registerMouseClickEvent(0);
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft);
+ break;
+ case WM_MBUTTONDOWN:
+ window->registerMouseClickEvent(0);
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle);
+ break;
+ case WM_RBUTTONDOWN:
+ window->registerMouseClickEvent(0);
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
+ break;
+ case WM_XBUTTONDOWN:
+ window->registerMouseClickEvent(0);
+ if ((short)HIWORD(wParam) == XBUTTON1) {
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4);
+ }
+ else if ((short)HIWORD(wParam) == XBUTTON2) {
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5);
+ }
+ break;
+ case WM_LBUTTONUP:
+ window->registerMouseClickEvent(1);
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
+ break;
+ case WM_MBUTTONUP:
+ window->registerMouseClickEvent(1);
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle);
+ break;
+ case WM_RBUTTONUP:
+ window->registerMouseClickEvent(1);
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
+ break;
+ case WM_XBUTTONUP:
+ window->registerMouseClickEvent(1);
+ if ((short)HIWORD(wParam) == XBUTTON1) {
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4);
+ }
+ else if ((short)HIWORD(wParam) == XBUTTON2) {
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5);
+ }
+ break;
+ case WM_MOUSEMOVE:
+ event = processCursorEvent(GHOST_kEventCursorMove, window);
+ break;
+ case WM_MOUSEWHEEL: {
+ /* The WM_MOUSEWHEEL message is sent to the focus window
+ * when the mouse wheel is rotated. The DefWindowProc
+ * function propagates the message to the window's parent.
+ * There should be no internal forwarding of the message,
+ * since DefWindowProc propagates it up the parent chain
+ * until it finds a window that processes it.
+ */
+
+ /* Get the window under the mouse and send event to its queue. */
+ POINT mouse_pos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
+ HWND mouse_hwnd = ChildWindowFromPoint(HWND_DESKTOP, mouse_pos);
+ GHOST_WindowWin32 *mouse_window = (GHOST_WindowWin32 *)::GetWindowLongPtr(mouse_hwnd,
+ GWLP_USERDATA);
+
+ processWheelEvent(mouse_window ? mouse_window : window, wParam, lParam);
+ eventHandled = true;
#ifdef BROKEN_PEEK_TOUCHPAD
- PostMessage(hwnd, WM_USER, 0, 0);
+ PostMessage(hwnd, WM_USER, 0, 0);
#endif
- break;
- }
- case WM_SETCURSOR:
- /* The WM_SETCURSOR message is sent to a window if the mouse causes the cursor
- * to move within a window and mouse input is not captured.
- * This means we have to set the cursor shape every time the mouse moves!
- * The DefWindowProc function uses this message to set the cursor to an
- * arrow if it is not in the client area.
- */
- if (LOWORD(lParam) == HTCLIENT) {
- // Load the current cursor
- window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
- // Bypass call to DefWindowProc
- return 0;
- }
- else {
- // Outside of client area show standard cursor
- window->loadCursor(true, GHOST_kStandardCursorDefault);
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////
- // Mouse events, ignored
- ////////////////////////////////////////////////////////////////////////
- case WM_NCMOUSEMOVE:
- /* The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved
- * within the nonclient area of the window. This message is posted to the window
- * that contains the cursor. If a window has captured the mouse, this message is not posted.
- */
- case WM_NCHITTEST:
- /* The WM_NCHITTEST message is sent to a window when the cursor moves, or
- * when a mouse button is pressed or released. If the mouse is not captured,
- * the message is sent to the window beneath the cursor. Otherwise, the message
- * is sent to the window that has captured the mouse.
- */
- break;
-
- ////////////////////////////////////////////////////////////////////////
- // Window events, processed
- ////////////////////////////////////////////////////////////////////////
- case WM_CLOSE:
- /* The WM_CLOSE message is sent as a signal that a window or an application should terminate. */
- event = processWindowEvent(GHOST_kEventWindowClose, window);
- break;
- case WM_ACTIVATE:
- /* The WM_ACTIVATE message is sent to both the window being activated and the window being
- * deactivated. If the windows use the same input queue, the message is sent synchronously,
- * first to the window procedure of the top-level window being deactivated, then to the window
- * procedure of the top-level window being activated. If the windows use different input queues,
- * the message is sent asynchronously, so the window is activated immediately.
- */
- {
- GHOST_ModifierKeys modifiers;
- modifiers.clear();
- system->storeModifierKeys(modifiers);
- system->m_wheelDeltaAccum = 0;
- event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
- /* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
- * will not be dispatched to OUR active window if we minimize one of OUR windows. */
- if (LOWORD(wParam) == WA_INACTIVE)
- window->lostMouseCapture();
- window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam));
- lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
- break;
- }
- case WM_ENTERSIZEMOVE:
- /* The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving
- * or sizing modal loop. The window enters the moving or sizing modal loop when the user
- * clicks the window's title bar or sizing border, or when the window passes the
- * WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the
- * message specifies the SC_MOVE or SC_SIZE value. The operation is complete when
- * DefWindowProc returns.
- */
- window->m_inLiveResize = 1;
- break;
- case WM_EXITSIZEMOVE:
- window->m_inLiveResize = 0;
- break;
- case WM_PAINT:
- /* An application sends the WM_PAINT message when the system or another application
- * makes a request to paint a portion of an application's window. The message is sent
- * when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage
- * function when the application obtains a WM_PAINT message by using the GetMessage or
- * PeekMessage function.
- */
- if (!window->m_inLiveResize) {
- event = processWindowEvent(GHOST_kEventWindowUpdate, window);
- ::ValidateRect(hwnd, NULL);
- }
- else {
- eventHandled = true;
- }
- break;
- case WM_GETMINMAXINFO:
- /* The WM_GETMINMAXINFO message is sent to a window when the size or
- * position of the window is about to change. An application can use
- * this message to override the window's default maximized size and
- * position, or its default minimum or maximum tracking size.
- */
- processMinMaxInfo((MINMAXINFO *) lParam);
- /* Let DefWindowProc handle it. */
- break;
- case WM_SIZING:
- case WM_SIZE:
- /* The WM_SIZE message is sent to a window after its size has changed.
- * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
- * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
- * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
- * message without calling DefWindowProc.
- */
- /* we get first WM_SIZE before we fully init. So, do not dispatch before we continiously resizng */
- if (window->m_inLiveResize) {
- system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window));
- system->dispatchEvents();
- }
- else {
- event = processWindowEvent(GHOST_kEventWindowSize, window);
- }
- break;
- case WM_CAPTURECHANGED:
- window->lostMouseCapture();
- break;
- case WM_MOVING:
- /* The WM_MOVING message is sent to a window that the user is moving. By processing
- * this message, an application can monitor the size and position of the drag rectangle
- * and, if needed, change its size or position.
- */
- case WM_MOVE:
- /* The WM_SIZE and WM_MOVE messages are not sent if an application handles the
- * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
- * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
- * message without calling DefWindowProc.
- */
- /* see WM_SIZE comment*/
- if (window->m_inLiveResize) {
- system->pushEvent(processWindowEvent(GHOST_kEventWindowMove, window));
- system->dispatchEvents();
- }
- else {
- event = processWindowEvent(GHOST_kEventWindowMove, window);
- }
-
- break;
- case WM_DPICHANGED:
- /* The WM_DPICHANGED message is sent when the effective dots per inch (dpi) for a window has changed.
- * The DPI is the scale factor for a window. There are multiple events that can cause the DPI to
- * change such as when the window is moved to a monitor with a different DPI.
- */
- {
- // The suggested new size and position of the window.
- RECT* const suggestedWindowRect = (RECT*)lParam;
-
- // Push DPI change event first
- system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window));
- system->dispatchEvents();
- eventHandled = true;
-
- // Then move and resize window
- SetWindowPos(hwnd,
- NULL,
- suggestedWindowRect->left,
- suggestedWindowRect->top,
- suggestedWindowRect->right - suggestedWindowRect->left,
- suggestedWindowRect->bottom - suggestedWindowRect->top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
- break;
- ////////////////////////////////////////////////////////////////////////
- // Window events, ignored
- ////////////////////////////////////////////////////////////////////////
- case WM_WINDOWPOSCHANGED:
- /* The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place
- * in the Z order has changed as a result of a call to the SetWindowPos function or
- * another window-management function.
- * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
- * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
- * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
- * message without calling DefWindowProc.
- */
- case WM_ERASEBKGND:
- /* An application sends the WM_ERASEBKGND message when the window background must be
- * erased (for example, when a window is resized). The message is sent to prepare an
- * invalidated portion of a window for painting.
- */
- case WM_NCPAINT:
- /* An application sends the WM_NCPAINT message to a window when its frame must be painted. */
- case WM_NCACTIVATE:
- /* The WM_NCACTIVATE message is sent to a window when its nonclient area needs to be changed
- * to indicate an active or inactive state.
- */
- case WM_DESTROY:
- /* The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window
- * procedure of the window being destroyed after the window is removed from the screen.
- * This message is sent first to the window being destroyed and then to the child windows
- * (if any) as they are destroyed. During the processing of the message, it can be assumed
- * that all child windows still exist.
- */
- case WM_NCDESTROY:
- /* The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The
- * DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY
- * message. WM_DESTROY is used to free the allocated memory object associated with the window.
- */
- break;
- case WM_KILLFOCUS:
- /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus.
- * We want to prevent this if a window is still active and it loses focus to nowhere*/
- if (!wParam && hwnd == ::GetActiveWindow())
- ::SetFocus(hwnd);
- case WM_SHOWWINDOW:
- /* The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown. */
- case WM_WINDOWPOSCHANGING:
- /* The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in
- * the Z order is about to change as a result of a call to the SetWindowPos function or
- * another window-management function.
- */
- case WM_SETFOCUS:
- /* The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus. */
- break;
- ////////////////////////////////////////////////////////////////////////
- // Other events
- ////////////////////////////////////////////////////////////////////////
- case WM_GETTEXT:
- /* An application sends a WM_GETTEXT message to copy the text that
- * corresponds to a window into a buffer provided by the caller.
- */
- case WM_ACTIVATEAPP:
- /* The WM_ACTIVATEAPP message is sent when a window belonging to a
- * different application than the active window is about to be activated.
- * The message is sent to the application whose window is being activated
- * and to the application whose window is being deactivated.
- */
- case WM_TIMER:
- /* The WIN32 docs say:
- * The WM_TIMER message is posted to the installing thread's message queue
- * when a timer expires. You can process the message by providing a WM_TIMER
- * case in the window procedure. Otherwise, the default window procedure will
- * call the TimerProc callback function specified in the call to the SetTimer
- * function used to install the timer.
- *
- * In GHOST, we let DefWindowProc call the timer callback.
- */
- break;
-
- }
- }
- else {
- // Event found for a window before the pointer to the class has been set.
- GHOST_PRINT("GHOST_SystemWin32::wndProc: GHOST window event before creation\n");
- /* These are events we typically miss at this point:
- * WM_GETMINMAXINFO 0x24
- * WM_NCCREATE 0x81
- * WM_NCCALCSIZE 0x83
- * WM_CREATE 0x01
- * We let DefWindowProc do the work.
- */
- }
- }
- else {
- // Events without valid hwnd
- GHOST_PRINT("GHOST_SystemWin32::wndProc: event without window\n");
- }
-
- if (event) {
- system->pushEvent(event);
- eventHandled = true;
- }
-
- if (!eventHandled)
- lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam);
-
- return lResult;
+ break;
+ }
+ case WM_SETCURSOR:
+ /* The WM_SETCURSOR message is sent to a window if the mouse causes the cursor
+ * to move within a window and mouse input is not captured.
+ * This means we have to set the cursor shape every time the mouse moves!
+ * The DefWindowProc function uses this message to set the cursor to an
+ * arrow if it is not in the client area.
+ */
+ if (LOWORD(lParam) == HTCLIENT) {
+ // Load the current cursor
+ window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
+ // Bypass call to DefWindowProc
+ return 0;
+ }
+ else {
+ // Outside of client area show standard cursor
+ window->loadCursor(true, GHOST_kStandardCursorDefault);
+ }
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Mouse events, ignored
+ ////////////////////////////////////////////////////////////////////////
+ case WM_NCMOUSEMOVE:
+ /* The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved
+ * within the nonclient area of the window. This message is posted to the window
+ * that contains the cursor. If a window has captured the mouse, this message is not posted.
+ */
+ case WM_NCHITTEST:
+ /* The WM_NCHITTEST message is sent to a window when the cursor moves, or
+ * when a mouse button is pressed or released. If the mouse is not captured,
+ * the message is sent to the window beneath the cursor. Otherwise, the message
+ * is sent to the window that has captured the mouse.
+ */
+ break;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Window events, processed
+ ////////////////////////////////////////////////////////////////////////
+ case WM_CLOSE:
+ /* The WM_CLOSE message is sent as a signal that a window or an application should terminate. */
+ event = processWindowEvent(GHOST_kEventWindowClose, window);
+ break;
+ case WM_ACTIVATE:
+ /* The WM_ACTIVATE message is sent to both the window being activated and the window being
+ * deactivated. If the windows use the same input queue, the message is sent synchronously,
+ * first to the window procedure of the top-level window being deactivated, then to the window
+ * procedure of the top-level window being activated. If the windows use different input queues,
+ * the message is sent asynchronously, so the window is activated immediately.
+ */
+ {
+ GHOST_ModifierKeys modifiers;
+ modifiers.clear();
+ system->storeModifierKeys(modifiers);
+ system->m_wheelDeltaAccum = 0;
+ event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate :
+ GHOST_kEventWindowDeactivate,
+ window);
+ /* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
+ * will not be dispatched to OUR active window if we minimize one of OUR windows. */
+ if (LOWORD(wParam) == WA_INACTIVE)
+ window->lostMouseCapture();
+ window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam));
+ lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
+ break;
+ }
+ case WM_ENTERSIZEMOVE:
+ /* The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving
+ * or sizing modal loop. The window enters the moving or sizing modal loop when the user
+ * clicks the window's title bar or sizing border, or when the window passes the
+ * WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the
+ * message specifies the SC_MOVE or SC_SIZE value. The operation is complete when
+ * DefWindowProc returns.
+ */
+ window->m_inLiveResize = 1;
+ break;
+ case WM_EXITSIZEMOVE:
+ window->m_inLiveResize = 0;
+ break;
+ case WM_PAINT:
+ /* An application sends the WM_PAINT message when the system or another application
+ * makes a request to paint a portion of an application's window. The message is sent
+ * when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage
+ * function when the application obtains a WM_PAINT message by using the GetMessage or
+ * PeekMessage function.
+ */
+ if (!window->m_inLiveResize) {
+ event = processWindowEvent(GHOST_kEventWindowUpdate, window);
+ ::ValidateRect(hwnd, NULL);
+ }
+ else {
+ eventHandled = true;
+ }
+ break;
+ case WM_GETMINMAXINFO:
+ /* The WM_GETMINMAXINFO message is sent to a window when the size or
+ * position of the window is about to change. An application can use
+ * this message to override the window's default maximized size and
+ * position, or its default minimum or maximum tracking size.
+ */
+ processMinMaxInfo((MINMAXINFO *)lParam);
+ /* Let DefWindowProc handle it. */
+ break;
+ case WM_SIZING:
+ case WM_SIZE:
+ /* The WM_SIZE message is sent to a window after its size has changed.
+ * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * message without calling DefWindowProc.
+ */
+ /* we get first WM_SIZE before we fully init. So, do not dispatch before we continiously resizng */
+ if (window->m_inLiveResize) {
+ system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window));
+ system->dispatchEvents();
+ }
+ else {
+ event = processWindowEvent(GHOST_kEventWindowSize, window);
+ }
+ break;
+ case WM_CAPTURECHANGED:
+ window->lostMouseCapture();
+ break;
+ case WM_MOVING:
+ /* The WM_MOVING message is sent to a window that the user is moving. By processing
+ * this message, an application can monitor the size and position of the drag rectangle
+ * and, if needed, change its size or position.
+ */
+ case WM_MOVE:
+ /* The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * message without calling DefWindowProc.
+ */
+ /* see WM_SIZE comment*/
+ if (window->m_inLiveResize) {
+ system->pushEvent(processWindowEvent(GHOST_kEventWindowMove, window));
+ system->dispatchEvents();
+ }
+ else {
+ event = processWindowEvent(GHOST_kEventWindowMove, window);
+ }
+
+ break;
+ case WM_DPICHANGED:
+ /* The WM_DPICHANGED message is sent when the effective dots per inch (dpi) for a window has changed.
+ * The DPI is the scale factor for a window. There are multiple events that can cause the DPI to
+ * change such as when the window is moved to a monitor with a different DPI.
+ */
+ {
+ // The suggested new size and position of the window.
+ RECT *const suggestedWindowRect = (RECT *)lParam;
+
+ // Push DPI change event first
+ system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window));
+ system->dispatchEvents();
+ eventHandled = true;
+
+ // Then move and resize window
+ SetWindowPos(hwnd,
+ NULL,
+ suggestedWindowRect->left,
+ suggestedWindowRect->top,
+ suggestedWindowRect->right - suggestedWindowRect->left,
+ suggestedWindowRect->bottom - suggestedWindowRect->top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+ break;
+ ////////////////////////////////////////////////////////////////////////
+ // Window events, ignored
+ ////////////////////////////////////////////////////////////////////////
+ case WM_WINDOWPOSCHANGED:
+ /* The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place
+ * in the Z order has changed as a result of a call to the SetWindowPos function or
+ * another window-management function.
+ * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * message without calling DefWindowProc.
+ */
+ case WM_ERASEBKGND:
+ /* An application sends the WM_ERASEBKGND message when the window background must be
+ * erased (for example, when a window is resized). The message is sent to prepare an
+ * invalidated portion of a window for painting.
+ */
+ case WM_NCPAINT:
+ /* An application sends the WM_NCPAINT message to a window when its frame must be painted. */
+ case WM_NCACTIVATE:
+ /* The WM_NCACTIVATE message is sent to a window when its nonclient area needs to be changed
+ * to indicate an active or inactive state.
+ */
+ case WM_DESTROY:
+ /* The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window
+ * procedure of the window being destroyed after the window is removed from the screen.
+ * This message is sent first to the window being destroyed and then to the child windows
+ * (if any) as they are destroyed. During the processing of the message, it can be assumed
+ * that all child windows still exist.
+ */
+ case WM_NCDESTROY:
+ /* The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The
+ * DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY
+ * message. WM_DESTROY is used to free the allocated memory object associated with the window.
+ */
+ break;
+ case WM_KILLFOCUS:
+ /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus.
+ * We want to prevent this if a window is still active and it loses focus to nowhere*/
+ if (!wParam && hwnd == ::GetActiveWindow())
+ ::SetFocus(hwnd);
+ case WM_SHOWWINDOW:
+ /* The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown. */
+ case WM_WINDOWPOSCHANGING:
+ /* The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in
+ * the Z order is about to change as a result of a call to the SetWindowPos function or
+ * another window-management function.
+ */
+ case WM_SETFOCUS:
+ /* The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus. */
+ break;
+ ////////////////////////////////////////////////////////////////////////
+ // Other events
+ ////////////////////////////////////////////////////////////////////////
+ case WM_GETTEXT:
+ /* An application sends a WM_GETTEXT message to copy the text that
+ * corresponds to a window into a buffer provided by the caller.
+ */
+ case WM_ACTIVATEAPP:
+ /* The WM_ACTIVATEAPP message is sent when a window belonging to a
+ * different application than the active window is about to be activated.
+ * The message is sent to the application whose window is being activated
+ * and to the application whose window is being deactivated.
+ */
+ case WM_TIMER:
+ /* The WIN32 docs say:
+ * The WM_TIMER message is posted to the installing thread's message queue
+ * when a timer expires. You can process the message by providing a WM_TIMER
+ * case in the window procedure. Otherwise, the default window procedure will
+ * call the TimerProc callback function specified in the call to the SetTimer
+ * function used to install the timer.
+ *
+ * In GHOST, we let DefWindowProc call the timer callback.
+ */
+ break;
+ }
+ }
+ else {
+ // Event found for a window before the pointer to the class has been set.
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: GHOST window event before creation\n");
+ /* These are events we typically miss at this point:
+ * WM_GETMINMAXINFO 0x24
+ * WM_NCCREATE 0x81
+ * WM_NCCALCSIZE 0x83
+ * WM_CREATE 0x01
+ * We let DefWindowProc do the work.
+ */
+ }
+ }
+ else {
+ // Events without valid hwnd
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: event without window\n");
+ }
+
+ if (event) {
+ system->pushEvent(event);
+ eventHandled = true;
+ }
+
+ if (!eventHandled)
+ lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam);
+
+ return lResult;
}
GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const
{
- char *temp_buff;
-
- if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL) ) {
- wchar_t *buffer;
- HANDLE hData = GetClipboardData(CF_UNICODETEXT);
- if (hData == NULL) {
- CloseClipboard();
- return NULL;
- }
- buffer = (wchar_t *)GlobalLock(hData);
- if (!buffer) {
- CloseClipboard();
- return NULL;
- }
-
- temp_buff = alloc_utf_8_from_16(buffer, 0);
-
- /* Buffer mustn't be accessed after CloseClipboard
- * it would like accessing free-d memory */
- GlobalUnlock(hData);
- CloseClipboard();
-
- return (GHOST_TUns8 *)temp_buff;
- }
- else if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL) ) {
- char *buffer;
- size_t len = 0;
- HANDLE hData = GetClipboardData(CF_TEXT);
- if (hData == NULL) {
- CloseClipboard();
- return NULL;
- }
- buffer = (char *)GlobalLock(hData);
- if (!buffer) {
- CloseClipboard();
- return NULL;
- }
-
- len = strlen(buffer);
- temp_buff = (char *) malloc(len + 1);
- strncpy(temp_buff, buffer, len);
- temp_buff[len] = '\0';
-
- /* Buffer mustn't be accessed after CloseClipboard
- * it would like accessing free-d memory */
- GlobalUnlock(hData);
- CloseClipboard();
-
- return (GHOST_TUns8 *)temp_buff;
- }
- else {
- return NULL;
- }
+ char *temp_buff;
+
+ if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) {
+ wchar_t *buffer;
+ HANDLE hData = GetClipboardData(CF_UNICODETEXT);
+ if (hData == NULL) {
+ CloseClipboard();
+ return NULL;
+ }
+ buffer = (wchar_t *)GlobalLock(hData);
+ if (!buffer) {
+ CloseClipboard();
+ return NULL;
+ }
+
+ temp_buff = alloc_utf_8_from_16(buffer, 0);
+
+ /* Buffer mustn't be accessed after CloseClipboard
+ * it would like accessing free-d memory */
+ GlobalUnlock(hData);
+ CloseClipboard();
+
+ return (GHOST_TUns8 *)temp_buff;
+ }
+ else if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) {
+ char *buffer;
+ size_t len = 0;
+ HANDLE hData = GetClipboardData(CF_TEXT);
+ if (hData == NULL) {
+ CloseClipboard();
+ return NULL;
+ }
+ buffer = (char *)GlobalLock(hData);
+ if (!buffer) {
+ CloseClipboard();
+ return NULL;
+ }
+
+ len = strlen(buffer);
+ temp_buff = (char *)malloc(len + 1);
+ strncpy(temp_buff, buffer, len);
+ temp_buff[len] = '\0';
+
+ /* Buffer mustn't be accessed after CloseClipboard
+ * it would like accessing free-d memory */
+ GlobalUnlock(hData);
+ CloseClipboard();
+
+ return (GHOST_TUns8 *)temp_buff;
+ }
+ else {
+ return NULL;
+ }
}
void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const
{
- if (selection) {return; } // for copying the selection, used on X11
-
- if (OpenClipboard(NULL)) {
- HLOCAL clipbuffer;
- wchar_t *data;
-
- if (buffer) {
- size_t len = count_utf_16_from_8(buffer);
- EmptyClipboard();
-
- clipbuffer = LocalAlloc(LMEM_FIXED, sizeof(wchar_t) * len);
- data = (wchar_t *)GlobalLock(clipbuffer);
-
- conv_utf_8_to_16(buffer, data, len);
-
- LocalUnlock(clipbuffer);
- SetClipboardData(CF_UNICODETEXT, clipbuffer);
- }
- CloseClipboard();
- }
- else {
- return;
- }
+ if (selection) {
+ return;
+ } // for copying the selection, used on X11
+
+ if (OpenClipboard(NULL)) {
+ HLOCAL clipbuffer;
+ wchar_t *data;
+
+ if (buffer) {
+ size_t len = count_utf_16_from_8(buffer);
+ EmptyClipboard();
+
+ clipbuffer = LocalAlloc(LMEM_FIXED, sizeof(wchar_t) * len);
+ data = (wchar_t *)GlobalLock(clipbuffer);
+
+ conv_utf_8_to_16(buffer, data, len);
+
+ LocalUnlock(clipbuffer);
+ SetClipboardData(CF_UNICODETEXT, clipbuffer);
+ }
+ CloseClipboard();
+ }
+ else {
+ return;
+ }
}
static DWORD GetParentProcessID(void)
{
- HANDLE snapshot;
- PROCESSENTRY32 pe32 = {0};
- DWORD ppid = 0, pid = GetCurrentProcessId();
- snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
- if (snapshot == INVALID_HANDLE_VALUE) {
- return -1;
- }
- pe32.dwSize = sizeof( pe32 );
- if (!Process32First(snapshot, &pe32)) {
- CloseHandle(snapshot);
- return -1;
- }
- do {
- if (pe32.th32ProcessID == pid) {
- ppid = pe32.th32ParentProcessID;
- break;
- }
- } while (Process32Next(snapshot, &pe32));
- CloseHandle(snapshot);
- return ppid;
+ HANDLE snapshot;
+ PROCESSENTRY32 pe32 = {0};
+ DWORD ppid = 0, pid = GetCurrentProcessId();
+ snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (snapshot == INVALID_HANDLE_VALUE) {
+ return -1;
+ }
+ pe32.dwSize = sizeof(pe32);
+ if (!Process32First(snapshot, &pe32)) {
+ CloseHandle(snapshot);
+ return -1;
+ }
+ do {
+ if (pe32.th32ProcessID == pid) {
+ ppid = pe32.th32ParentProcessID;
+ break;
+ }
+ } while (Process32Next(snapshot, &pe32));
+ CloseHandle(snapshot);
+ return ppid;
}
static bool getProcessName(int pid, char *buffer, int max_len)
{
- bool result = false;
- HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE, pid);
- if (handle) {
- GetModuleFileNameEx(handle, 0, buffer, max_len);
- result = true;
- }
- CloseHandle(handle);
- return result;
+ bool result = false;
+ HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ if (handle) {
+ GetModuleFileNameEx(handle, 0, buffer, max_len);
+ result = true;
+ }
+ CloseHandle(handle);
+ return result;
}
static bool isStartedFromCommandPrompt()
{
- HWND hwnd = GetConsoleWindow();
-
- if (hwnd) {
- DWORD pid = (DWORD)-1;
- DWORD ppid = GetParentProcessID();
- char parent_name[MAX_PATH];
- bool start_from_launcher = false;
-
- GetWindowThreadProcessId(hwnd, &pid);
- if (getProcessName(ppid, parent_name, sizeof(parent_name))) {
- char *filename = strrchr(parent_name, '\\');
- if (filename != NULL) {
- start_from_launcher = strstr(filename, "blender.exe") != NULL;
- }
- }
-
- /* When we're starting from a wrapper we need to compare with parent process ID. */
- if (pid != (start_from_launcher ? ppid : GetCurrentProcessId()))
- return true;
- }
-
- return false;
+ HWND hwnd = GetConsoleWindow();
+
+ if (hwnd) {
+ DWORD pid = (DWORD)-1;
+ DWORD ppid = GetParentProcessID();
+ char parent_name[MAX_PATH];
+ bool start_from_launcher = false;
+
+ GetWindowThreadProcessId(hwnd, &pid);
+ if (getProcessName(ppid, parent_name, sizeof(parent_name))) {
+ char *filename = strrchr(parent_name, '\\');
+ if (filename != NULL) {
+ start_from_launcher = strstr(filename, "blender.exe") != NULL;
+ }
+ }
+
+ /* When we're starting from a wrapper we need to compare with parent process ID. */
+ if (pid != (start_from_launcher ? ppid : GetCurrentProcessId()))
+ return true;
+ }
+
+ return false;
}
int GHOST_SystemWin32::toggleConsole(int action)
{
- HWND wnd = GetConsoleWindow();
-
- switch (action) {
- case 3: // startup: hide if not started from command prompt
- {
- if (!isStartedFromCommandPrompt()) {
- ShowWindow(wnd, SW_HIDE);
- m_consoleStatus = 0;
- }
- break;
- }
- case 0: // hide
- ShowWindow(wnd, SW_HIDE);
- m_consoleStatus = 0;
- break;
- case 1: // show
- ShowWindow(wnd, SW_SHOW);
- if (!isStartedFromCommandPrompt()) {
- DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND);
- }
- m_consoleStatus = 1;
- break;
- case 2: // toggle
- ShowWindow(wnd, m_consoleStatus ? SW_HIDE : SW_SHOW);
- m_consoleStatus = !m_consoleStatus;
- if (m_consoleStatus && !isStartedFromCommandPrompt()) {
- DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND);
- }
- break;
- }
-
- return m_consoleStatus;
+ HWND wnd = GetConsoleWindow();
+
+ switch (action) {
+ case 3: // startup: hide if not started from command prompt
+ {
+ if (!isStartedFromCommandPrompt()) {
+ ShowWindow(wnd, SW_HIDE);
+ m_consoleStatus = 0;
+ }
+ break;
+ }
+ case 0: // hide
+ ShowWindow(wnd, SW_HIDE);
+ m_consoleStatus = 0;
+ break;
+ case 1: // show
+ ShowWindow(wnd, SW_SHOW);
+ if (!isStartedFromCommandPrompt()) {
+ DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND);
+ }
+ m_consoleStatus = 1;
+ break;
+ case 2: // toggle
+ ShowWindow(wnd, m_consoleStatus ? SW_HIDE : SW_SHOW);
+ m_consoleStatus = !m_consoleStatus;
+ if (m_consoleStatus && !isStartedFromCommandPrompt()) {
+ DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND);
+ }
+ break;
+ }
+
+ return m_consoleStatus;
}
int GHOST_SystemWin32::confirmQuit(GHOST_IWindow *window) const
{
- return (MessageBox(window ? ((GHOST_WindowWin32 *)window)->getHWND() : 0, "Some changes have not been saved.\nDo you really want to quit?",
- "Exit Blender", MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST) == IDOK);
+ return (MessageBox(window ? ((GHOST_WindowWin32 *)window)->getHWND() : 0,
+ "Some changes have not been saved.\nDo you really want to quit?",
+ "Exit Blender",
+ MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST) == IDOK);
}
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 62492e8d8b7..0eb91d511b1 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -26,8 +26,8 @@
#define __GHOST_SYSTEMWIN32_H__
#ifndef WIN32
-#error WIN32 only!
-#endif // WIN32
+# error WIN32 only!
+#endif // WIN32
/* require Windows XP or newer */
#undef _WIN32_WINNT
@@ -35,7 +35,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <ole2.h> // for drag-n-drop
+#include <ole2.h> // for drag-n-drop
#include "GHOST_System.h"
@@ -53,378 +53,392 @@ class GHOST_WindowWin32;
* \see GHOST_System.
*/
class GHOST_SystemWin32 : public GHOST_System {
-public:
- /**
- * Constructor.
- */
- GHOST_SystemWin32();
-
- /**
- * Destructor.
- */
- ~GHOST_SystemWin32();
-
- /***************************************************************************************
- ** Time(r) functionality
- ***************************************************************************************/
-
- /**
- * Returns the system time.
- * Returns the number of milliseconds since the start of the system process.
- * This overloaded method uses the high frequency timer if available.
- * \return The number of milliseconds.
- */
- GHOST_TUns64 getMilliSeconds() const;
-
- /***************************************************************************************
- ** Display/window management functionality
- ***************************************************************************************/
-
- /**
- * Returns the number of displays on this system.
- * \return The number of displays.
- */
- GHOST_TUns8 getNumDisplays() const;
-
- /**
- * Returns the dimensions of the main display on this system.
- * \return The dimension of the main display.
- */
- void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
-
- /**
- * Returns the dimensions of all displays on this system.
- * \return The dimension of the main display.
- */
- void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
-
- /**
- * Create a new window.
- * The new window is added to the list of windows managed.
- * Never explicitly delete the window, use disposeWindow() instead.
- * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
- * \param left The coordinate of the left edge of the window.
- * \param top The coordinate of the top edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state of the window when opened.
- * \param type The type of drawing context installed in this window.
- * \param glSettings: Misc OpenGL settings.
- * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
- * \param parentWindow Parent (embedder) window
- * \return The new window (or 0 if creation failed).
- */
- GHOST_IWindow *createWindow(
- const STR_String& title,
- GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
- GHOST_TWindowState state, GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive = false,
- const GHOST_TEmbedderWindowID parentWindow = 0);
-
-
- /**
- * Create a new offscreen context.
- * Never explicitly delete the window, use disposeContext() instead.
- * \return The new context (or 0 if creation failed).
- */
- GHOST_IContext *createOffscreenContext();
-
- /**
- * Dispose of a context.
- * \param context Pointer to the context to be disposed.
- * \return Indication of success.
- */
- GHOST_TSuccess disposeContext(GHOST_IContext *context);
-
- /***************************************************************************************
- ** Event management functionality
- ***************************************************************************************/
-
- /**
- * Gets events from the system and stores them in the queue.
- * \param waitForEvent Flag to wait for an event (or return immediately).
- * \return Indication of the presence of events.
- */
- bool processEvents(bool waitForEvent);
-
-
- /***************************************************************************************
- ** Cursor management functionality
- ***************************************************************************************/
-
- /**
- * Returns the current location of the cursor (location in screen coordinates)
- * \param x The x-coordinate of the cursor.
- * \param y The y-coordinate of the cursor.
- * \return Indication of success.
- */
- GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
-
- /**
- * Updates the location of the cursor (location in screen coordinates).
- * \param x The x-coordinate of the cursor.
- * \param y The y-coordinate of the cursor.
- * \return Indication of success.
- */
- GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
-
- /***************************************************************************************
- ** Access to mouse button and keyboard states.
- ***************************************************************************************/
-
- /**
- * Returns the state of all modifier keys.
- * \param keys The state of all modifier keys (true == pressed).
- * \return Indication of success.
- */
- GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
-
- /**
- * Returns the state of the mouse buttons (ouside the message queue).
- * \param buttons The state of the buttons.
- * \return Indication of success.
- */
- GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
-
- /**
- * Returns unsigned char from CUT_BUFFER0
- * \param selection Used by X11 only
- * \return Returns the Clipboard
- */
- GHOST_TUns8 *getClipboard(bool selection) const;
-
- /**
- * Puts buffer to system clipboard
- * \param selection Used by X11 only
- * \return No return
- */
- void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
-
- /**
- * Creates a drag'n'drop event and pushes it immediately onto the event queue.
- * Called by GHOST_DropTargetWin32 class.
- * \param eventType The type of drag'n'drop event
- * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
- * \param mouseX x mouse coordinate (in window coordinates)
- * \param mouseY y mouse coordinate
- * \param window The window on which the event occurred
- * \return Indication whether the event was handled.
- */
- static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_WindowWin32 *window, int mouseX, int mouseY, void *data);
-
- /**
- * Confirms quitting he program when there is just one window left open
- * in the application
- */
- int confirmQuit(GHOST_IWindow *window) const;
-
-protected:
- /**
- * Initializes the system.
- * For now, it just registers the window class (WNDCLASS).
- * \return A success value.
- */
- GHOST_TSuccess init();
-
- /**
- * Closes the system down.
- * \return A success value.
- */
- GHOST_TSuccess exit();
-
- /**
- * Converts raw WIN32 key codes from the wndproc to GHOST keys.
- * \param vKey The virtual key from hardKey
- * \param ScanCode The ScanCode of pressed key (similar to PS/2 Set 1)
- * \param extend Flag if key is not primly (left or right)
- * \return The GHOST key (GHOST_kKeyUnknown if no match).
- */
- GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const;
-
- /**
- * Catches raw WIN32 key codes from WM_INPUT in the wndproc.
- * \param raw RawInput structure with detailed info about the key event
- * \param keyDown Pointer flag that specify if a key is down
- * \param vk Pointer to virtual key
- * \return The GHOST key (GHOST_kKeyUnknown if no match).
- */
- GHOST_TKey hardKey(RAWINPUT const& raw, int *keyDown, char *vk);
-
- /**
- * Creates mouse button event.
- * \param type The type of event to create.
- * \param window The window receiving the event (the active window).
- * \param mask The button mask of this event.
- * \return The event created.
- */
- static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TButtonMask mask);
-
- /**
- * Creates pointer event.
- * \param type The type of event to create.
- * \param window The window receiving the event (the active window).
- * \param wParam The wParam from the wndproc
- * \param lParam The lParam from the wndproc
- * \param eventhandled true if the method handled the event
- * \return The event created.
- */
- static GHOST_Event *processPointerEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool & eventhandled);
-
- /**
- * Creates cursor event.
- * \param type The type of event to create.
- * \param window The window receiving the event (the active window).
- * \return The event created.
- */
- static GHOST_EventCursor *processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
-
- /**
- * Handles a mouse wheel event.
- * \param window The window receiving the event (the active window).
- * \param wParam The wParam from the wndproc
- * \param lParam The lParam from the wndproc
- */
- static void processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam);
-
- /**
- * Creates a key event and updates the key data stored locally (m_modifierKeys).
- * In most cases this is a straightforward conversion of key codes.
- * For the modifier keys however, we want to distinguish left and right keys.
- * \param window The window receiving the event (the active window).
- * \param raw RawInput structure with detailed info about the key event
- */
- static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const& raw);
-
- /**
- * Process special keys (VK_OEM_*), to see if current key layout
- * gives us anything special, like ! on french AZERTY.
- * \param vKey The virtual key from hardKey
- * \param scanCode The ScanCode of pressed key (simular to PS/2 Set 1)
- */
- GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
-
- /**
- * Creates a window event.
- * \param type The type of event to create.
- * \param window The window receiving the event (the active window).
- * \return The event created.
- */
- static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_SystemWin32();
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_SystemWin32();
+
+ /***************************************************************************************
+ ** Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * This overloaded method uses the high frequency timer if available.
+ * \return The number of milliseconds.
+ */
+ GHOST_TUns64 getMilliSeconds() const;
+
+ /***************************************************************************************
+ ** Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the number of displays on this system.
+ * \return The number of displays.
+ */
+ GHOST_TUns8 getNumDisplays() const;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * \return The dimension of the main display.
+ */
+ void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
+
+ /**
+ * Returns the dimensions of all displays on this system.
+ * \return The dimension of the main display.
+ */
+ void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * \param left The coordinate of the left edge of the window.
+ * \param top The coordinate of the top edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state of the window when opened.
+ * \param type The type of drawing context installed in this window.
+ * \param glSettings: Misc OpenGL settings.
+ * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
+ * \param parentWindow Parent (embedder) window
+ * \return The new window (or 0 if creation failed).
+ */
+ GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive = false,
+ const GHOST_TEmbedderWindowID parentWindow = 0);
+
+ /**
+ * Create a new offscreen context.
+ * Never explicitly delete the window, use disposeContext() instead.
+ * \return The new context (or 0 if creation failed).
+ */
+ GHOST_IContext *createOffscreenContext();
+
+ /**
+ * Dispose of a context.
+ * \param context Pointer to the context to be disposed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess disposeContext(GHOST_IContext *context);
+
+ /***************************************************************************************
+ ** Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Gets events from the system and stores them in the queue.
+ * \param waitForEvent Flag to wait for an event (or return immediately).
+ * \return Indication of the presence of events.
+ */
+ bool processEvents(bool waitForEvent);
+
+ /***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * \param x The x-coordinate of the cursor.
+ * \param y The y-coordinate of the cursor.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+
+ /**
+ * Updates the location of the cursor (location in screen coordinates).
+ * \param x The x-coordinate of the cursor.
+ * \param y The y-coordinate of the cursor.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
+
+ /***************************************************************************************
+ ** Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of all modifier keys.
+ * \param keys The state of all modifier keys (true == pressed).
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * \param buttons The state of the buttons.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
+
+ /**
+ * Returns unsigned char from CUT_BUFFER0
+ * \param selection Used by X11 only
+ * \return Returns the Clipboard
+ */
+ GHOST_TUns8 *getClipboard(bool selection) const;
+
+ /**
+ * Puts buffer to system clipboard
+ * \param selection Used by X11 only
+ * \return No return
+ */
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+
+ /**
+ * Creates a drag'n'drop event and pushes it immediately onto the event queue.
+ * Called by GHOST_DropTargetWin32 class.
+ * \param eventType The type of drag'n'drop event
+ * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
+ * \param mouseX x mouse coordinate (in window coordinates)
+ * \param mouseY y mouse coordinate
+ * \param window The window on which the event occurred
+ * \return Indication whether the event was handled.
+ */
+ static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType,
+ GHOST_TDragnDropTypes draggedObjectType,
+ GHOST_WindowWin32 *window,
+ int mouseX,
+ int mouseY,
+ void *data);
+
+ /**
+ * Confirms quitting he program when there is just one window left open
+ * in the application
+ */
+ int confirmQuit(GHOST_IWindow *window) const;
+
+ protected:
+ /**
+ * Initializes the system.
+ * For now, it just registers the window class (WNDCLASS).
+ * \return A success value.
+ */
+ GHOST_TSuccess init();
+
+ /**
+ * Closes the system down.
+ * \return A success value.
+ */
+ GHOST_TSuccess exit();
+
+ /**
+ * Converts raw WIN32 key codes from the wndproc to GHOST keys.
+ * \param vKey The virtual key from hardKey
+ * \param ScanCode The ScanCode of pressed key (similar to PS/2 Set 1)
+ * \param extend Flag if key is not primly (left or right)
+ * \return The GHOST key (GHOST_kKeyUnknown if no match).
+ */
+ GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const;
+
+ /**
+ * Catches raw WIN32 key codes from WM_INPUT in the wndproc.
+ * \param raw RawInput structure with detailed info about the key event
+ * \param keyDown Pointer flag that specify if a key is down
+ * \param vk Pointer to virtual key
+ * \return The GHOST key (GHOST_kKeyUnknown if no match).
+ */
+ GHOST_TKey hardKey(RAWINPUT const &raw, int *keyDown, char *vk);
+
+ /**
+ * Creates mouse button event.
+ * \param type The type of event to create.
+ * \param window The window receiving the event (the active window).
+ * \param mask The button mask of this event.
+ * \return The event created.
+ */
+ static GHOST_EventButton *processButtonEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window,
+ GHOST_TButtonMask mask);
+
+ /**
+ * Creates pointer event.
+ * \param type The type of event to create.
+ * \param window The window receiving the event (the active window).
+ * \param wParam The wParam from the wndproc
+ * \param lParam The lParam from the wndproc
+ * \param eventhandled true if the method handled the event
+ * \return The event created.
+ */
+ static GHOST_Event *processPointerEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window,
+ WPARAM wParam,
+ LPARAM lParam,
+ bool &eventhandled);
+
+ /**
+ * Creates cursor event.
+ * \param type The type of event to create.
+ * \param window The window receiving the event (the active window).
+ * \return The event created.
+ */
+ static GHOST_EventCursor *processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
+
+ /**
+ * Handles a mouse wheel event.
+ * \param window The window receiving the event (the active window).
+ * \param wParam The wParam from the wndproc
+ * \param lParam The lParam from the wndproc
+ */
+ static void processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam);
+
+ /**
+ * Creates a key event and updates the key data stored locally (m_modifierKeys).
+ * In most cases this is a straightforward conversion of key codes.
+ * For the modifier keys however, we want to distinguish left and right keys.
+ * \param window The window receiving the event (the active window).
+ * \param raw RawInput structure with detailed info about the key event
+ */
+ static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw);
+
+ /**
+ * Process special keys (VK_OEM_*), to see if current key layout
+ * gives us anything special, like ! on french AZERTY.
+ * \param vKey The virtual key from hardKey
+ * \param scanCode The ScanCode of pressed key (simular to PS/2 Set 1)
+ */
+ GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
+
+ /**
+ * Creates a window event.
+ * \param type The type of event to create.
+ * \param window The window receiving the event (the active window).
+ * \return The event created.
+ */
+ static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
#ifdef WITH_INPUT_IME
- /**
- * Creates a IME event.
- * \param type The type of event to create.
- * \param window The window receiving the event (the active window).
- * \param data IME data.
- * \return The event created.
- */
- static GHOST_Event *processImeEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TEventImeData *data);
-#endif // WITH_INPUT_IME
-
- /**
- * Handles minimum window size.
- * \param minmax The MINMAXINFO structure.
- */
- static void processMinMaxInfo(MINMAXINFO *minmax);
+ /**
+ * Creates a IME event.
+ * \param type The type of event to create.
+ * \param window The window receiving the event (the active window).
+ * \param data IME data.
+ * \return The event created.
+ */
+ static GHOST_Event *processImeEvent(GHOST_TEventType type,
+ GHOST_WindowWin32 *window,
+ GHOST_TEventImeData *data);
+#endif // WITH_INPUT_IME
+
+ /**
+ * Handles minimum window size.
+ * \param minmax The MINMAXINFO structure.
+ */
+ static void processMinMaxInfo(MINMAXINFO *minmax);
#ifdef WITH_INPUT_NDOF
- /**
- * Handles Motion and Button events from a SpaceNavigator or related device.
- * Instead of returning an event object, this function communicates directly
- * with the GHOST_NDOFManager.
- * \param raw RawInput structure with detailed info about the NDOF event
- * \return Whether an event was generated and sent.
- */
- bool processNDOF(RAWINPUT const& raw);
+ /**
+ * Handles Motion and Button events from a SpaceNavigator or related device.
+ * Instead of returning an event object, this function communicates directly
+ * with the GHOST_NDOFManager.
+ * \param raw RawInput structure with detailed info about the NDOF event
+ * \return Whether an event was generated and sent.
+ */
+ bool processNDOF(RAWINPUT const &raw);
#endif
- /**
- * Returns the local state of the modifier keys (from the message queue).
- * \param keys The state of the keys.
- */
- inline void retrieveModifierKeys(GHOST_ModifierKeys& keys) const;
-
- /**
- * Stores the state of the modifier keys locally.
- * For internal use only!
- * param keys The new state of the modifier keys.
- */
- inline void storeModifierKeys(const GHOST_ModifierKeys& keys);
-
- /**
- * Check current key layout for AltGr
- */
- inline void handleKeyboardChange(void);
-
- /**
- * Windows call back routine for our window class.
- */
- static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
- /**
- * Toggles console
- * \param action
- * - 0 - Hides
- * - 1 - Shows
- * - 2 - Toggles
- * - 3 - Hides if it runs not from command line
- * - * - Does nothing
- * \return current status (1 -visible, 0 - hidden)
- */
- int toggleConsole(int action);
-
- /** The current state of the modifier keys. */
- GHOST_ModifierKeys m_modifierKeys;
- /** State variable set at initialization. */
- bool m_hasPerformanceCounter;
- /** High frequency timer variable. */
- __int64 m_freq;
- /** High frequency timer variable. */
- __int64 m_start;
- /** AltGr on current keyboard layout. */
- bool m_hasAltGr;
- /** language identifier. */
- WORD m_langId;
- /** stores keyboard layout. */
- HKL m_keylayout;
-
- /** Console status */
- int m_consoleStatus;
-
- /** Wheel delta accumulator */
- int m_wheelDeltaAccum;
+ /**
+ * Returns the local state of the modifier keys (from the message queue).
+ * \param keys The state of the keys.
+ */
+ inline void retrieveModifierKeys(GHOST_ModifierKeys &keys) const;
+
+ /**
+ * Stores the state of the modifier keys locally.
+ * For internal use only!
+ * param keys The new state of the modifier keys.
+ */
+ inline void storeModifierKeys(const GHOST_ModifierKeys &keys);
+
+ /**
+ * Check current key layout for AltGr
+ */
+ inline void handleKeyboardChange(void);
+
+ /**
+ * Windows call back routine for our window class.
+ */
+ static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ /**
+ * Toggles console
+ * \param action
+ * - 0 - Hides
+ * - 1 - Shows
+ * - 2 - Toggles
+ * - 3 - Hides if it runs not from command line
+ * - * - Does nothing
+ * \return current status (1 -visible, 0 - hidden)
+ */
+ int toggleConsole(int action);
+
+ /** The current state of the modifier keys. */
+ GHOST_ModifierKeys m_modifierKeys;
+ /** State variable set at initialization. */
+ bool m_hasPerformanceCounter;
+ /** High frequency timer variable. */
+ __int64 m_freq;
+ /** High frequency timer variable. */
+ __int64 m_start;
+ /** AltGr on current keyboard layout. */
+ bool m_hasAltGr;
+ /** language identifier. */
+ WORD m_langId;
+ /** stores keyboard layout. */
+ HKL m_keylayout;
+
+ /** Console status */
+ int m_consoleStatus;
+
+ /** Wheel delta accumulator */
+ int m_wheelDeltaAccum;
};
-inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const
+inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys &keys) const
{
- keys = m_modifierKeys;
+ keys = m_modifierKeys;
}
-inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys& keys)
+inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys &keys)
{
- m_modifierKeys = keys;
+ m_modifierKeys = keys;
}
inline void GHOST_SystemWin32::handleKeyboardChange(void)
{
- m_keylayout = GetKeyboardLayout(0); // get keylayout for current thread
- int i;
- SHORT s;
-
- // save the language identifier.
- m_langId = LOWORD(m_keylayout);
-
- for (m_hasAltGr = false, i = 32; i < 256; ++i) {
- s = VkKeyScanEx((char)i, m_keylayout);
- // s == -1 means no key that translates passed char code
- // high byte contains shift state. bit 2 ctrl pressed, bit 4 alt pressed
- // if both are pressed, we have AltGr keycombo on keylayout
- if (s != -1 && (s & 0x600) == 0x600) {
- m_hasAltGr = true;
- break;
- }
- }
+ m_keylayout = GetKeyboardLayout(0); // get keylayout for current thread
+ int i;
+ SHORT s;
+
+ // save the language identifier.
+ m_langId = LOWORD(m_keylayout);
+
+ for (m_hasAltGr = false, i = 32; i < 256; ++i) {
+ s = VkKeyScanEx((char)i, m_keylayout);
+ // s == -1 means no key that translates passed char code
+ // high byte contains shift state. bit 2 ctrl pressed, bit 4 alt pressed
+ // if both are pressed, we have AltGr keycombo on keylayout
+ if (s != -1 && (s & 0x600) == 0x600) {
+ m_hasAltGr = true;
+ break;
+ }
+ }
}
-#endif // __GHOST_SYSTEMWIN32_H__
+#endif // __GHOST_SYSTEMWIN32_H__
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index ef08a6d7bb7..4d467f3b913 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -55,13 +55,13 @@
#endif
#ifdef WITH_XF86KEYSYM
-#include <X11/XF86keysym.h>
+# include <X11/XF86keysym.h>
#endif
#ifdef WITH_X11_XFIXES
# include <X11/extensions/Xfixes.h>
/* Workaround for XWayland grab glitch: T53004. */
-#define WITH_XWAYLAND_HACK
+# define WITH_XWAYLAND_HACK
#endif
/* for XIWarpPointer */
@@ -92,12 +92,11 @@
* See T47228 and D1746 */
#define USE_NON_LATIN_KB_WORKAROUND
-static GHOST_TKey ghost_key_from_keysym(
- const KeySym key);
-static GHOST_TKey ghost_key_from_keycode(
- const XkbDescPtr xkb_descr, const KeyCode keycode);
-static GHOST_TKey ghost_key_from_keysym_or_keycode(
- const KeySym key, const XkbDescPtr xkb_descr, const KeyCode keycode);
+static GHOST_TKey ghost_key_from_keysym(const KeySym key);
+static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode);
+static GHOST_TKey ghost_key_from_keysym_or_keycode(const KeySym key,
+ const XkbDescPtr xkb_descr,
+ const KeyCode keycode);
/* these are for copy and select copy */
static char *txt_cut_buffer = NULL;
@@ -109,285 +108,277 @@ static bool use_xwayland_hack = false;
using namespace std;
-GHOST_SystemX11::
-GHOST_SystemX11(
- )
- : GHOST_System(),
- m_xkb_descr(NULL),
- m_start_time(0)
+GHOST_SystemX11::GHOST_SystemX11() : GHOST_System(), m_xkb_descr(NULL), m_start_time(0)
{
- XInitThreads();
- m_display = XOpenDisplay(NULL);
+ XInitThreads();
+ m_display = XOpenDisplay(NULL);
- if (!m_display) {
- std::cerr << "Unable to open a display" << std::endl;
- abort(); /* was return before, but this would just mean it will crash later */
- }
+ if (!m_display) {
+ std::cerr << "Unable to open a display" << std::endl;
+ abort(); /* was return before, but this would just mean it will crash later */
+ }
#ifdef USE_X11_ERROR_HANDLERS
- (void) XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
- (void) XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
+ (void)XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
+ (void)XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
#endif
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- /* note -- don't open connection to XIM server here, because the locale
- * has to be set before opening the connection but setlocale() has not
- * been called yet. the connection will be opened after entering
- * the event loop. */
- m_xim = NULL;
+ /* note -- don't open connection to XIM server here, because the locale
+ * has to be set before opening the connection but setlocale() has not
+ * been called yet. the connection will be opened after entering
+ * the event loop. */
+ m_xim = NULL;
#endif
-#define GHOST_INTERN_ATOM_IF_EXISTS(atom) { m_atom.atom = XInternAtom(m_display, #atom , True); } (void)0
-#define GHOST_INTERN_ATOM(atom) { m_atom.atom = XInternAtom(m_display, #atom , False); } (void)0
-
- GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW);
- GHOST_INTERN_ATOM(WM_PROTOCOLS);
- GHOST_INTERN_ATOM(WM_TAKE_FOCUS);
- GHOST_INTERN_ATOM(WM_STATE);
- GHOST_INTERN_ATOM(WM_CHANGE_STATE);
- GHOST_INTERN_ATOM(_NET_WM_STATE);
- GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
- GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
-
- GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN);
- GHOST_INTERN_ATOM(_MOTIF_WM_HINTS);
- GHOST_INTERN_ATOM(TARGETS);
- GHOST_INTERN_ATOM(STRING);
- GHOST_INTERN_ATOM(COMPOUND_TEXT);
- GHOST_INTERN_ATOM(TEXT);
- GHOST_INTERN_ATOM(CLIPBOARD);
- GHOST_INTERN_ATOM(PRIMARY);
- GHOST_INTERN_ATOM(XCLIP_OUT);
- GHOST_INTERN_ATOM(INCR);
- GHOST_INTERN_ATOM(UTF8_STRING);
+#define GHOST_INTERN_ATOM_IF_EXISTS(atom) \
+ { \
+ m_atom.atom = XInternAtom(m_display, #atom, True); \
+ } \
+ (void)0
+#define GHOST_INTERN_ATOM(atom) \
+ { \
+ m_atom.atom = XInternAtom(m_display, #atom, False); \
+ } \
+ (void)0
+
+ GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW);
+ GHOST_INTERN_ATOM(WM_PROTOCOLS);
+ GHOST_INTERN_ATOM(WM_TAKE_FOCUS);
+ GHOST_INTERN_ATOM(WM_STATE);
+ GHOST_INTERN_ATOM(WM_CHANGE_STATE);
+ GHOST_INTERN_ATOM(_NET_WM_STATE);
+ GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
+ GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
+
+ GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN);
+ GHOST_INTERN_ATOM(_MOTIF_WM_HINTS);
+ GHOST_INTERN_ATOM(TARGETS);
+ GHOST_INTERN_ATOM(STRING);
+ GHOST_INTERN_ATOM(COMPOUND_TEXT);
+ GHOST_INTERN_ATOM(TEXT);
+ GHOST_INTERN_ATOM(CLIPBOARD);
+ GHOST_INTERN_ATOM(PRIMARY);
+ GHOST_INTERN_ATOM(XCLIP_OUT);
+ GHOST_INTERN_ATOM(INCR);
+ GHOST_INTERN_ATOM(UTF8_STRING);
#ifdef WITH_X11_XINPUT
- m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False);
+ m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False);
#endif
#undef GHOST_INTERN_ATOM_IF_EXISTS
#undef GHOST_INTERN_ATOM
- m_last_warp = 0;
- m_last_release_keycode = 0;
- m_last_release_time = 0;
+ m_last_warp = 0;
+ m_last_release_keycode = 0;
+ m_last_release_time = 0;
- /* compute the initial time */
- timeval tv;
- if (gettimeofday(&tv, NULL) == -1) {
- GHOST_ASSERT(false, "Could not instantiate timer!");
- }
+ /* compute the initial time */
+ timeval tv;
+ if (gettimeofday(&tv, NULL) == -1) {
+ GHOST_ASSERT(false, "Could not instantiate timer!");
+ }
- /* Taking care not to overflow the tv.tv_sec * 1000 */
- m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
+ m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
+ /* use detectable autorepeate, mac and windows also do this */
+ int use_xkb;
+ int xkb_opcode, xkb_event, xkb_error;
+ int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
- /* use detectable autorepeate, mac and windows also do this */
- int use_xkb;
- int xkb_opcode, xkb_event, xkb_error;
- int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
+ use_xkb = XkbQueryExtension(
+ m_display, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor);
+ if (use_xkb) {
+ XkbSetDetectableAutoRepeat(m_display, true, NULL);
- use_xkb = XkbQueryExtension(m_display, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor);
- if (use_xkb) {
- XkbSetDetectableAutoRepeat(m_display, true, NULL);
-
- m_xkb_descr = XkbGetMap(m_display, 0, XkbUseCoreKbd);
- if (m_xkb_descr) {
- XkbGetNames(m_display, XkbKeyNamesMask, m_xkb_descr);
- }
- }
+ m_xkb_descr = XkbGetMap(m_display, 0, XkbUseCoreKbd);
+ if (m_xkb_descr) {
+ XkbGetNames(m_display, XkbKeyNamesMask, m_xkb_descr);
+ }
+ }
#ifdef WITH_XWAYLAND_HACK
- use_xwayland_hack = getenv("WAYLAND_DISPLAY") != NULL;
+ use_xwayland_hack = getenv("WAYLAND_DISPLAY") != NULL;
#endif
#ifdef WITH_X11_XINPUT
- /* detect if we have xinput (for reuse) */
- {
- memset(&m_xinput_version, 0, sizeof(m_xinput_version));
- XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
- if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
- if (version->present) {
- m_xinput_version = *version;
- }
- XFree(version);
- }
- }
-
-#ifdef USE_XINPUT_HOTPLUG
- if (m_xinput_version.present) {
- XEventClass class_presence;
- int xi_presence;
- DevicePresence(m_display, xi_presence, class_presence);
- XSelectExtensionEvent(
- m_display,
- RootWindow(m_display, DefaultScreen(m_display)),
- &class_presence, 1);
- (void)xi_presence;
- }
-#endif /* USE_XINPUT_HOTPLUG */
-
- refreshXInputDevices();
-#endif /* WITH_X11_XINPUT */
+ /* detect if we have xinput (for reuse) */
+ {
+ memset(&m_xinput_version, 0, sizeof(m_xinput_version));
+ XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
+ if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
+ if (version->present) {
+ m_xinput_version = *version;
+ }
+ XFree(version);
+ }
+ }
+
+# ifdef USE_XINPUT_HOTPLUG
+ if (m_xinput_version.present) {
+ XEventClass class_presence;
+ int xi_presence;
+ DevicePresence(m_display, xi_presence, class_presence);
+ XSelectExtensionEvent(
+ m_display, RootWindow(m_display, DefaultScreen(m_display)), &class_presence, 1);
+ (void)xi_presence;
+ }
+# endif /* USE_XINPUT_HOTPLUG */
+
+ refreshXInputDevices();
+#endif /* WITH_X11_XINPUT */
}
-GHOST_SystemX11::
-~GHOST_SystemX11()
+GHOST_SystemX11::~GHOST_SystemX11()
{
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- if (m_xim) {
- XCloseIM(m_xim);
- }
+ if (m_xim) {
+ XCloseIM(m_xim);
+ }
#endif
#ifdef WITH_X11_XINPUT
- /* Close tablet devices. */
- clearXInputDevices();
+ /* Close tablet devices. */
+ clearXInputDevices();
#endif /* WITH_X11_XINPUT */
- if (m_xkb_descr) {
- XkbFreeKeyboard (m_xkb_descr, XkbAllComponentsMask, true);
- }
+ if (m_xkb_descr) {
+ XkbFreeKeyboard(m_xkb_descr, XkbAllComponentsMask, true);
+ }
- XCloseDisplay(m_display);
+ XCloseDisplay(m_display);
}
-
-GHOST_TSuccess
-GHOST_SystemX11::
-init()
+GHOST_TSuccess GHOST_SystemX11::init()
{
- GHOST_TSuccess success = GHOST_System::init();
+ GHOST_TSuccess success = GHOST_System::init();
- if (success) {
+ if (success) {
#ifdef WITH_INPUT_NDOF
- m_ndofManager = new GHOST_NDOFManagerUnix(*this);
+ m_ndofManager = new GHOST_NDOFManagerUnix(*this);
#endif
- m_displayManager = new GHOST_DisplayManagerX11(this);
+ m_displayManager = new GHOST_DisplayManagerX11(this);
- if (m_displayManager) {
- return GHOST_kSuccess;
- }
- }
+ if (m_displayManager) {
+ return GHOST_kSuccess;
+ }
+ }
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
-GHOST_TUns64
-GHOST_SystemX11::
-getMilliSeconds() const
+GHOST_TUns64 GHOST_SystemX11::getMilliSeconds() const
{
- timeval tv;
- if (gettimeofday(&tv, NULL) == -1) {
- GHOST_ASSERT(false, "Could not compute time!");
- }
+ timeval tv;
+ if (gettimeofday(&tv, NULL) == -1) {
+ GHOST_ASSERT(false, "Could not compute time!");
+ }
- /* Taking care not to overflow the tv.tv_sec * 1000 */
- return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
+ return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
}
-GHOST_TUns8
-GHOST_SystemX11::
-getNumDisplays() const
+GHOST_TUns8 GHOST_SystemX11::getNumDisplays() const
{
- return GHOST_TUns8(1);
+ return GHOST_TUns8(1);
}
/**
* Returns the dimensions of the main display on this system.
* \return The dimension of the main display.
*/
-void
-GHOST_SystemX11::
-getMainDisplayDimensions(
- GHOST_TUns32& width,
- GHOST_TUns32& height) const
+void GHOST_SystemX11::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- if (m_display) {
- /* note, for this to work as documented,
- * we would need to use Xinerama check r54370 for code that did this,
- * we've since removed since its not worth the extra dep - campbell */
- getAllDisplayDimensions(width, height);
- }
+ if (m_display) {
+ /* note, for this to work as documented,
+ * we would need to use Xinerama check r54370 for code that did this,
+ * we've since removed since its not worth the extra dep - campbell */
+ getAllDisplayDimensions(width, height);
+ }
}
-
/**
* Returns the dimensions of the main display on this system.
* \return The dimension of the main display.
*/
-void
-GHOST_SystemX11::
-getAllDisplayDimensions(
- GHOST_TUns32& width,
- GHOST_TUns32& height) const
+void GHOST_SystemX11::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- if (m_display) {
- width = DisplayWidth(m_display, DefaultScreen(m_display));
- height = DisplayHeight(m_display, DefaultScreen(m_display));
- }
+ if (m_display) {
+ width = DisplayWidth(m_display, DefaultScreen(m_display));
+ height = DisplayHeight(m_display, DefaultScreen(m_display));
+ }
}
/**
* Create a new window.
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
- * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
- * \param left The coordinate of the left edge of the window.
- * \param top The coordinate of the top edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state of the window when opened.
- * \param type The type of drawing context installed in this window.
+ * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * \param left The coordinate of the left edge of the window.
+ * \param top The coordinate of the top edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state of the window when opened.
+ * \param type The type of drawing context installed in this window.
* \param glSettings: Misc OpenGL settings.
* \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
- * \param parentWindow Parent (embedder) window
- * \return The new window (or 0 if creation failed).
+ * \param parentWindow Parent (embedder) window
+ * \return The new window (or 0 if creation failed).
*/
-GHOST_IWindow *
-GHOST_SystemX11::
-createWindow(const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive,
- const GHOST_TEmbedderWindowID parentWindow)
+GHOST_IWindow *GHOST_SystemX11::createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive,
+ const GHOST_TEmbedderWindowID parentWindow)
{
- GHOST_WindowX11 *window = NULL;
-
- if (!m_display) return 0;
-
- window = new GHOST_WindowX11(this, m_display, title,
- left, top, width, height,
- state, parentWindow, type,
- ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive,
- ((glSettings.flags & GHOST_glAlphaBackground) != 0),
- glSettings.numOfAASamples, (glSettings.flags & GHOST_glDebugContext) != 0);
-
- if (window) {
- /* Both are now handle in GHOST_WindowX11.cpp
- * Focus and Delete atoms. */
-
- if (window->getValid()) {
- /* Store the pointer to the window */
- m_windowManager->addWindow(window);
- m_windowManager->setActiveWindow(window);
- pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
- }
- else {
- delete window;
- window = NULL;
- }
- }
- return window;
+ GHOST_WindowX11 *window = NULL;
+
+ if (!m_display)
+ return 0;
+
+ window = new GHOST_WindowX11(this,
+ m_display,
+ title,
+ left,
+ top,
+ width,
+ height,
+ state,
+ parentWindow,
+ type,
+ ((glSettings.flags & GHOST_glStereoVisual) != 0),
+ exclusive,
+ ((glSettings.flags & GHOST_glAlphaBackground) != 0),
+ glSettings.numOfAASamples,
+ (glSettings.flags & GHOST_glDebugContext) != 0);
+
+ if (window) {
+ /* Both are now handle in GHOST_WindowX11.cpp
+ * Focus and Delete atoms. */
+
+ if (window->getValid()) {
+ /* Store the pointer to the window */
+ m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ delete window;
+ window = NULL;
+ }
+ }
+ return window;
}
bool GHOST_SystemX11::supportsNativeDialogs(void)
{
- return false;
+ return false;
}
/**
@@ -395,76 +386,76 @@ bool GHOST_SystemX11::supportsNativeDialogs(void)
* Never explicitly delete the context, use disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
-GHOST_IContext *
-GHOST_SystemX11::
-createOffscreenContext()
+GHOST_IContext *GHOST_SystemX11::createOffscreenContext()
{
- // During development:
- // try 4.x compatibility profile
- // try 3.3 compatibility profile
- // fall back to 3.0 if needed
- //
- // Final Blender 2.8:
- // try 4.x core profile
- // try 3.3 core profile
- // no fallbacks
+ // During development:
+ // try 4.x compatibility profile
+ // try 3.3 compatibility profile
+ // fall back to 3.0 if needed
+ //
+ // Final Blender 2.8:
+ // try 4.x core profile
+ // try 3.3 core profile
+ // no fallbacks
#if defined(WITH_GL_PROFILE_CORE)
- {
- const char *version_major = (char*)glewGetString(GLEW_VERSION_MAJOR);
- if (version_major != NULL && version_major[0] == '1') {
- fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n");
- abort();
- }
- }
+ {
+ const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR);
+ if (version_major != NULL && version_major[0] == '1') {
+ fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n");
+ abort();
+ }
+ }
#endif
- const int profile_mask =
+ const int profile_mask =
#if defined(WITH_GL_PROFILE_CORE)
- GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
#elif defined(WITH_GL_PROFILE_COMPAT)
- GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
#else
-# error // must specify either core or compat at build time
+# error // must specify either core or compat at build time
#endif
- GHOST_Context *context;
-
- for (int minor = 5; minor >= 0; --minor) {
- context = new GHOST_ContextGLX(
- false,
- 0,
- (Window)NULL,
- m_display,
- (GLXFBConfig)NULL,
- profile_mask,
- 4, minor,
- GHOST_OPENGL_GLX_CONTEXT_FLAGS | (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
- }
-
- context = new GHOST_ContextGLX(
- false,
- 0,
- (Window)NULL,
- m_display,
- (GLXFBConfig)NULL,
- profile_mask,
- 3, 3,
- GHOST_OPENGL_GLX_CONTEXT_FLAGS | (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
-
- return NULL;
+ GHOST_Context *context;
+
+ for (int minor = 5; minor >= 0; --minor) {
+ context = new GHOST_ContextGLX(false,
+ 0,
+ (Window)NULL,
+ m_display,
+ (GLXFBConfig)NULL,
+ profile_mask,
+ 4,
+ minor,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS |
+ (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+ }
+
+ context = new GHOST_ContextGLX(false,
+ 0,
+ (Window)NULL,
+ m_display,
+ (GLXFBConfig)NULL,
+ profile_mask,
+ 3,
+ 3,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS |
+ (false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+
+ return NULL;
}
/**
@@ -472,1743 +463,1695 @@ createOffscreenContext()
* \param context Pointer to the context to be disposed.
* \return Indication of success.
*/
-GHOST_TSuccess
-GHOST_SystemX11::
-disposeContext(GHOST_IContext *context)
+GHOST_TSuccess GHOST_SystemX11::disposeContext(GHOST_IContext *context)
{
- delete context;
+ delete context;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
static void destroyIMCallback(XIM /*xim*/, XPointer ptr, XPointer /*data*/)
{
- GHOST_PRINT("XIM server died\n");
+ GHOST_PRINT("XIM server died\n");
- if (ptr)
- *(XIM *)ptr = NULL;
+ if (ptr)
+ *(XIM *)ptr = NULL;
}
bool GHOST_SystemX11::openX11_IM()
{
- if (!m_display)
- return false;
+ if (!m_display)
+ return false;
- /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */
- XSetLocaleModifiers("");
+ /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */
+ XSetLocaleModifiers("");
- m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
- if (!m_xim)
- return false;
+ m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
+ if (!m_xim)
+ return false;
- XIMCallback destroy;
- destroy.callback = (XIMProc)destroyIMCallback;
- destroy.client_data = (XPointer)&m_xim;
- XSetIMValues(m_xim, XNDestroyCallback, &destroy, NULL);
- return true;
+ XIMCallback destroy;
+ destroy.callback = (XIMProc)destroyIMCallback;
+ destroy.client_data = (XPointer)&m_xim;
+ XSetIMValues(m_xim, XNDestroyCallback, &destroy, NULL);
+ return true;
}
#endif
-GHOST_WindowX11 *
-GHOST_SystemX11::
-findGhostWindow(
- Window xwind) const
+GHOST_WindowX11 *GHOST_SystemX11::findGhostWindow(Window xwind) const
{
- if (xwind == 0) return NULL;
+ if (xwind == 0)
+ return NULL;
- /* It is not entirely safe to do this as the backptr may point
- * to a window that has recently been removed.
- * We should always check the window manager's list of windows
- * and only process events on these windows. */
+ /* It is not entirely safe to do this as the backptr may point
+ * to a window that has recently been removed.
+ * We should always check the window manager's list of windows
+ * and only process events on these windows. */
- vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
+ vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
- vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
- vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
-
- for (; win_it != win_end; ++win_it) {
- GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
- if (window->getXWindow() == xwind) {
- return window;
- }
- }
- return NULL;
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
+ for (; win_it != win_end; ++win_it) {
+ GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
+ if (window->getXWindow() == xwind) {
+ return window;
+ }
+ }
+ return NULL;
}
static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep)
{
- int fd = ConnectionNumber(display);
- fd_set fds;
+ int fd = ConnectionNumber(display);
+ fd_set fds;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
- if (maxSleep == -1) {
- select(fd + 1, &fds, NULL, NULL, NULL);
- }
- else {
- timeval tv;
+ if (maxSleep == -1) {
+ select(fd + 1, &fds, NULL, NULL, NULL);
+ }
+ else {
+ timeval tv;
- tv.tv_sec = maxSleep / 1000;
- tv.tv_usec = (maxSleep - tv.tv_sec * 1000) * 1000;
+ tv.tv_sec = maxSleep / 1000;
+ tv.tv_usec = (maxSleep - tv.tv_sec * 1000) * 1000;
- select(fd + 1, &fds, NULL, NULL, &tv);
- }
+ select(fd + 1, &fds, NULL, NULL, &tv);
+ }
}
/* This function borrowed from Qt's X11 support
* qclipboard_x11.cpp
* */
struct init_timestamp_data {
- Time timestamp;
+ Time timestamp;
};
static Bool init_timestamp_scanner(Display *, XEvent *event, XPointer arg)
{
- init_timestamp_data *data =
- reinterpret_cast<init_timestamp_data *>(arg);
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- data->timestamp = event->xbutton.time;
- break;
- case MotionNotify:
- data->timestamp = event->xmotion.time;
- break;
- case KeyPress:
- case KeyRelease:
- data->timestamp = event->xkey.time;
- break;
- case PropertyNotify:
- data->timestamp = event->xproperty.time;
- break;
- case EnterNotify:
- case LeaveNotify:
- data->timestamp = event->xcrossing.time;
- break;
- case SelectionClear:
- data->timestamp = event->xselectionclear.time;
- break;
- default:
- break;
- }
-
- return false;
+ init_timestamp_data *data = reinterpret_cast<init_timestamp_data *>(arg);
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ data->timestamp = event->xbutton.time;
+ break;
+ case MotionNotify:
+ data->timestamp = event->xmotion.time;
+ break;
+ case KeyPress:
+ case KeyRelease:
+ data->timestamp = event->xkey.time;
+ break;
+ case PropertyNotify:
+ data->timestamp = event->xproperty.time;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ data->timestamp = event->xcrossing.time;
+ break;
+ case SelectionClear:
+ data->timestamp = event->xselectionclear.time;
+ break;
+ default:
+ break;
+ }
+
+ return false;
}
-Time
-GHOST_SystemX11::
-lastEventTime(Time default_time) {
- init_timestamp_data data;
- data.timestamp = default_time;
- XEvent ev;
- XCheckIfEvent(m_display, &ev, &init_timestamp_scanner, (XPointer) & data);
+Time GHOST_SystemX11::lastEventTime(Time default_time)
+{
+ init_timestamp_data data;
+ data.timestamp = default_time;
+ XEvent ev;
+ XCheckIfEvent(m_display, &ev, &init_timestamp_scanner, (XPointer)&data);
- return data.timestamp;
+ return data.timestamp;
}
-bool
-GHOST_SystemX11::
-processEvents(
- bool waitForEvent)
+bool GHOST_SystemX11::processEvents(bool waitForEvent)
{
- /* Get all the current events -- translate them into
- * ghost events and call base class pushEvent() method. */
+ /* Get all the current events -- translate them into
+ * ghost events and call base class pushEvent() method. */
- bool anyProcessed = false;
+ bool anyProcessed = false;
- do {
- GHOST_TimerManager *timerMgr = getTimerManager();
+ do {
+ GHOST_TimerManager *timerMgr = getTimerManager();
- if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) {
- GHOST_TUns64 next = timerMgr->nextFireTime();
+ if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) {
+ GHOST_TUns64 next = timerMgr->nextFireTime();
- if (next == GHOST_kFireTimeNever) {
- SleepTillEvent(m_display, -1);
- }
- else {
- GHOST_TInt64 maxSleep = next - getMilliSeconds();
+ if (next == GHOST_kFireTimeNever) {
+ SleepTillEvent(m_display, -1);
+ }
+ else {
+ GHOST_TInt64 maxSleep = next - getMilliSeconds();
- if (maxSleep >= 0)
- SleepTillEvent(m_display, next - getMilliSeconds());
- }
- }
+ if (maxSleep >= 0)
+ SleepTillEvent(m_display, next - getMilliSeconds());
+ }
+ }
- if (timerMgr->fireTimers(getMilliSeconds())) {
- anyProcessed = true;
- }
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed = true;
+ }
- while (XPending(m_display)) {
- XEvent xevent;
- XNextEvent(m_display, &xevent);
+ while (XPending(m_display)) {
+ XEvent xevent;
+ XNextEvent(m_display, &xevent);
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- /* open connection to XIM server and create input context (XIC)
- * when receiving the first FocusIn or KeyPress event after startup,
- * or recover XIM and XIC when the XIM server has been restarted */
- if (xevent.type == FocusIn || xevent.type == KeyPress) {
- if (!m_xim && openX11_IM()) {
- GHOST_PRINT("Connected to XIM server\n");
- }
-
- if (m_xim) {
- GHOST_WindowX11 * window = findGhostWindow(xevent.xany.window);
- if (window && !window->getX11_XIC() && window->createX11_XIC()) {
- GHOST_PRINT("XIM input context created\n");
- if (xevent.type == KeyPress)
- /* we can assume the window has input focus
- * here, because key events are received only
- * when the window is focused. */
- XSetICFocus(window->getX11_XIC());
- }
- }
- }
-
- /* dispatch event to XIM server */
- if ((XFilterEvent(&xevent, (Window)NULL) == True)) {
- /* do nothing now, the event is consumed by XIM. */
- continue;
- }
+ /* open connection to XIM server and create input context (XIC)
+ * when receiving the first FocusIn or KeyPress event after startup,
+ * or recover XIM and XIC when the XIM server has been restarted */
+ if (xevent.type == FocusIn || xevent.type == KeyPress) {
+ if (!m_xim && openX11_IM()) {
+ GHOST_PRINT("Connected to XIM server\n");
+ }
+
+ if (m_xim) {
+ GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window);
+ if (window && !window->getX11_XIC() && window->createX11_XIC()) {
+ GHOST_PRINT("XIM input context created\n");
+ if (xevent.type == KeyPress)
+ /* we can assume the window has input focus
+ * here, because key events are received only
+ * when the window is focused. */
+ XSetICFocus(window->getX11_XIC());
+ }
+ }
+ }
+
+ /* dispatch event to XIM server */
+ if ((XFilterEvent(&xevent, (Window)NULL) == True)) {
+ /* do nothing now, the event is consumed by XIM. */
+ continue;
+ }
#endif
- /* when using autorepeat, some keypress events can actually come *after* the
- * last keyrelease. The next code takes care of that */
- if (xevent.type == KeyRelease) {
- m_last_release_keycode = xevent.xkey.keycode;
- m_last_release_time = xevent.xkey.time;
- }
- else if (xevent.type == KeyPress) {
- if ((xevent.xkey.keycode == m_last_release_keycode) && ((xevent.xkey.time <= m_last_release_time)))
- continue;
- }
-
- processEvent(&xevent);
- anyProcessed = true;
-
+ /* when using autorepeat, some keypress events can actually come *after* the
+ * last keyrelease. The next code takes care of that */
+ if (xevent.type == KeyRelease) {
+ m_last_release_keycode = xevent.xkey.keycode;
+ m_last_release_time = xevent.xkey.time;
+ }
+ else if (xevent.type == KeyPress) {
+ if ((xevent.xkey.keycode == m_last_release_keycode) &&
+ ((xevent.xkey.time <= m_last_release_time)))
+ continue;
+ }
+
+ processEvent(&xevent);
+ anyProcessed = true;
#ifdef USE_UNITY_WORKAROUND
- /* note: processEvent() can't include this code because
- * KeymapNotify event have no valid window information. */
-
- /* the X server generates KeymapNotify event immediately after
- * every EnterNotify and FocusIn event. we handle this event
- * to correct modifier states. */
- if (xevent.type == FocusIn) {
- /* use previous event's window, because KeymapNotify event
- * has no window information. */
- GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window);
- if (window && XPending(m_display) >= 2) {
- XNextEvent(m_display, &xevent);
-
- if (xevent.type == KeymapNotify) {
- XEvent xev_next;
-
- /* check if KeyPress or KeyRelease event was generated
- * in order to confirm the window is active. */
- XPeekEvent(m_display, &xev_next);
-
- if (xev_next.type == KeyPress || xev_next.type == KeyRelease) {
- /* XK_Hyper_L/R currently unused */
- const static KeySym modifiers[8] = {XK_Shift_L, XK_Shift_R,
- XK_Control_L, XK_Control_R,
- XK_Alt_L, XK_Alt_R,
- XK_Super_L, XK_Super_R};
-
- for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) {
- KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
- if (((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
- pushEvent(new GHOST_EventKey(
- getMilliSeconds(),
- GHOST_kEventKeyDown,
- window,
- ghost_key_from_keysym(modifiers[i]),
- '\0',
- NULL));
- }
- }
- }
- }
- }
- }
-#endif /* USE_UNITY_WORKAROUND */
-
- }
-
- if (generateWindowExposeEvents()) {
- anyProcessed = true;
- }
+ /* note: processEvent() can't include this code because
+ * KeymapNotify event have no valid window information. */
+
+ /* the X server generates KeymapNotify event immediately after
+ * every EnterNotify and FocusIn event. we handle this event
+ * to correct modifier states. */
+ if (xevent.type == FocusIn) {
+ /* use previous event's window, because KeymapNotify event
+ * has no window information. */
+ GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window);
+ if (window && XPending(m_display) >= 2) {
+ XNextEvent(m_display, &xevent);
+
+ if (xevent.type == KeymapNotify) {
+ XEvent xev_next;
+
+ /* check if KeyPress or KeyRelease event was generated
+ * in order to confirm the window is active. */
+ XPeekEvent(m_display, &xev_next);
+
+ if (xev_next.type == KeyPress || xev_next.type == KeyRelease) {
+ /* XK_Hyper_L/R currently unused */
+ const static KeySym modifiers[8] = {XK_Shift_L,
+ XK_Shift_R,
+ XK_Control_L,
+ XK_Control_R,
+ XK_Alt_L,
+ XK_Alt_R,
+ XK_Super_L,
+ XK_Super_R};
+
+ for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) {
+ KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
+ if (((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
+ pushEvent(new GHOST_EventKey(getMilliSeconds(),
+ GHOST_kEventKeyDown,
+ window,
+ ghost_key_from_keysym(modifiers[i]),
+ '\0',
+ NULL));
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* USE_UNITY_WORKAROUND */
+ }
+
+ if (generateWindowExposeEvents()) {
+ anyProcessed = true;
+ }
#ifdef WITH_INPUT_NDOF
- if (static_cast<GHOST_NDOFManagerUnix *>(m_ndofManager)->processEvents()) {
- anyProcessed = true;
- }
+ if (static_cast<GHOST_NDOFManagerUnix *>(m_ndofManager)->processEvents()) {
+ anyProcessed = true;
+ }
#endif
- } while (waitForEvent && !anyProcessed);
+ } while (waitForEvent && !anyProcessed);
- return anyProcessed;
+ return anyProcessed;
}
-
#ifdef WITH_X11_XINPUT
static bool checkTabletProximity(Display *display, XDevice *device)
{
- /* we could have true/false/not-found return value, but for now false is OK */
-
- /* see: state.c from xinput, to get more data out of the device */
- XDeviceState *state;
-
- if (device == NULL) {
- return false;
- }
-
- /* needed since unplugging will abort() without this */
- GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
-
- state = XQueryDeviceState(display, device);
-
- GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
-
- if (state) {
- XInputClass *cls = state->data;
- // printf("%d class%s :\n", state->num_classes,
- // (state->num_classes > 1) ? "es" : "");
- for (int loop = 0; loop < state->num_classes; loop++) {
- switch (cls->c_class) {
- case ValuatorClass:
- XValuatorState *val_state = (XValuatorState *)cls;
- // printf("ValuatorClass Mode=%s Proximity=%s\n",
- // val_state->mode & 1 ? "Absolute" : "Relative",
- // val_state->mode & 2 ? "Out" : "In");
-
- if ((val_state->mode & 2) == 0) {
- XFreeDeviceState(state);
- return true;
- }
- break;
- }
- cls = (XInputClass *) ((char *)cls + cls->length);
- }
- XFreeDeviceState(state);
- }
- return false;
+ /* we could have true/false/not-found return value, but for now false is OK */
+
+ /* see: state.c from xinput, to get more data out of the device */
+ XDeviceState *state;
+
+ if (device == NULL) {
+ return false;
+ }
+
+ /* needed since unplugging will abort() without this */
+ GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
+
+ state = XQueryDeviceState(display, device);
+
+ GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
+
+ if (state) {
+ XInputClass *cls = state->data;
+ // printf("%d class%s :\n", state->num_classes,
+ // (state->num_classes > 1) ? "es" : "");
+ for (int loop = 0; loop < state->num_classes; loop++) {
+ switch (cls->c_class) {
+ case ValuatorClass:
+ XValuatorState *val_state = (XValuatorState *)cls;
+ // printf("ValuatorClass Mode=%s Proximity=%s\n",
+ // val_state->mode & 1 ? "Absolute" : "Relative",
+ // val_state->mode & 2 ? "Out" : "In");
+
+ if ((val_state->mode & 2) == 0) {
+ XFreeDeviceState(state);
+ return true;
+ }
+ break;
+ }
+ cls = (XInputClass *)((char *)cls + cls->length);
+ }
+ XFreeDeviceState(state);
+ }
+ return false;
}
#endif /* WITH_X11_XINPUT */
-void
-GHOST_SystemX11::processEvent(XEvent *xe)
+void GHOST_SystemX11::processEvent(XEvent *xe)
{
- GHOST_WindowX11 *window = findGhostWindow(xe->xany.window);
- GHOST_Event *g_event = NULL;
+ GHOST_WindowX11 *window = findGhostWindow(xe->xany.window);
+ GHOST_Event *g_event = NULL;
#ifdef USE_XINPUT_HOTPLUG
- /* Hot-Plug support */
- if (m_xinput_version.present) {
- XEventClass class_presence;
- int xi_presence;
-
- DevicePresence(m_display, xi_presence, class_presence);
- (void)class_presence;
-
- if (xe->type == xi_presence) {
- XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xe;
- if ((notify_event->devchange == DeviceEnabled) ||
- (notify_event->devchange == DeviceDisabled) ||
- (notify_event->devchange == DeviceAdded) ||
- (notify_event->devchange == DeviceRemoved))
- {
- refreshXInputDevices();
-
- /* update all window events */
- {
- vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
- vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
- vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
-
- for (; win_it != win_end; ++win_it) {
- GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
- window->refreshXInputDevices();
- }
- }
- }
- }
- }
-#endif /* USE_XINPUT_HOTPLUG */
-
-
- if (!window) {
- return;
- }
+ /* Hot-Plug support */
+ if (m_xinput_version.present) {
+ XEventClass class_presence;
+ int xi_presence;
+
+ DevicePresence(m_display, xi_presence, class_presence);
+ (void)class_presence;
+
+ if (xe->type == xi_presence) {
+ XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xe;
+ if ((notify_event->devchange == DeviceEnabled) ||
+ (notify_event->devchange == DeviceDisabled) ||
+ (notify_event->devchange == DeviceAdded) || (notify_event->devchange == DeviceRemoved)) {
+ refreshXInputDevices();
+
+ /* update all window events */
+ {
+ vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
+
+ for (; win_it != win_end; ++win_it) {
+ GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
+ window->refreshXInputDevices();
+ }
+ }
+ }
+ }
+ }
+#endif /* USE_XINPUT_HOTPLUG */
+
+ if (!window) {
+ return;
+ }
#ifdef WITH_X11_XINPUT
- /* Proximity-Out Events are not reliable, if the tablet is active - check on each event
- * this adds a little overhead but only while the tablet is in use.
- * in the future we could have a ghost call window->CheckTabletProximity()
- * but for now enough parts of the code are checking 'Active'
- * - campbell */
- if (window->GetTabletData()->Active != GHOST_kTabletModeNone) {
- bool any_proximity = false;
-
- for (GHOST_TabletX11& xtablet: m_xtablets) {
- if (checkTabletProximity(xe->xany.display, xtablet.Device)) {
- any_proximity = true;
- }
- }
-
- if (!any_proximity) {
- // printf("proximity disable\n");
- window->GetTabletData()->Active = GHOST_kTabletModeNone;
- }
- }
+ /* Proximity-Out Events are not reliable, if the tablet is active - check on each event
+ * this adds a little overhead but only while the tablet is in use.
+ * in the future we could have a ghost call window->CheckTabletProximity()
+ * but for now enough parts of the code are checking 'Active'
+ * - campbell */
+ if (window->GetTabletData()->Active != GHOST_kTabletModeNone) {
+ bool any_proximity = false;
+
+ for (GHOST_TabletX11 &xtablet : m_xtablets) {
+ if (checkTabletProximity(xe->xany.display, xtablet.Device)) {
+ any_proximity = true;
+ }
+ }
+
+ if (!any_proximity) {
+ // printf("proximity disable\n");
+ window->GetTabletData()->Active = GHOST_kTabletModeNone;
+ }
+ }
#endif /* WITH_X11_XINPUT */
- switch (xe->type) {
- case Expose:
- {
- XExposeEvent & xee = xe->xexpose;
-
- if (xee.count == 0) {
- /* Only generate a single expose event
- * per read of the event queue. */
-
- g_event = new
- GHOST_Event(
- getMilliSeconds(),
- GHOST_kEventWindowUpdate,
- window
- );
- }
- break;
- }
-
- case MotionNotify:
- {
- XMotionEvent &xme = xe->xmotion;
+ switch (xe->type) {
+ case Expose: {
+ XExposeEvent &xee = xe->xexpose;
+
+ if (xee.count == 0) {
+ /* Only generate a single expose event
+ * per read of the event queue. */
+
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
+ }
+ break;
+ }
+
+ case MotionNotify: {
+ XMotionEvent &xme = xe->xmotion;
#ifdef WITH_X11_XINPUT
- bool is_tablet = window->GetTabletData()->Active != GHOST_kTabletModeNone;
+ bool is_tablet = window->GetTabletData()->Active != GHOST_kTabletModeNone;
#else
- bool is_tablet = false;
+ bool is_tablet = false;
#endif
- if (is_tablet == false && window->getCursorGrabModeIsWarp()) {
- GHOST_TInt32 x_new = xme.x_root;
- GHOST_TInt32 y_new = xme.y_root;
- GHOST_TInt32 x_accum, y_accum;
- GHOST_Rect bounds;
-
- /* fallback to window bounds */
- if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
- window->getClientBounds(bounds);
-
- /* could also clamp to screen bounds
- * wrap with a window outside the view will fail atm */
- bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
- window->getCursorGrabAccum(x_accum, y_accum);
-
- if (x_new != xme.x_root || y_new != xme.y_root) {
- if (xme.time > m_last_warp) {
- /* when wrapping we don't need to add an event because the
- * setCursorPosition call will cause a new event after */
- setCursorPosition(x_new, y_new); /* wrap */
- window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), y_accum + (xme.y_root - y_new));
- m_last_warp = lastEventTime(xme.time);
- }
- else {
- setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
- }
- }
- else {
- g_event = new
- GHOST_EventCursor(
- getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- xme.x_root + x_accum,
- xme.y_root + y_accum
- );
- }
- }
- else {
- g_event = new
- GHOST_EventCursor(
- getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- xme.x_root,
- xme.y_root
- );
- }
- break;
- }
-
- case KeyPress:
- case KeyRelease:
- {
- XKeyEvent *xke = &(xe->xkey);
- KeySym key_sym;
- char ascii;
+ if (is_tablet == false && window->getCursorGrabModeIsWarp()) {
+ GHOST_TInt32 x_new = xme.x_root;
+ GHOST_TInt32 y_new = xme.y_root;
+ GHOST_TInt32 x_accum, y_accum;
+ GHOST_Rect bounds;
+
+ /* fallback to window bounds */
+ if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
+ window->getClientBounds(bounds);
+
+ /* could also clamp to screen bounds
+ * wrap with a window outside the view will fail atm */
+ bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
+ window->getCursorGrabAccum(x_accum, y_accum);
+
+ if (x_new != xme.x_root || y_new != xme.y_root) {
+ if (xme.time > m_last_warp) {
+ /* when wrapping we don't need to add an event because the
+ * setCursorPosition call will cause a new event after */
+ setCursorPosition(x_new, y_new); /* wrap */
+ window->setCursorGrabAccum(x_accum + (xme.x_root - x_new),
+ y_accum + (xme.y_root - y_new));
+ m_last_warp = lastEventTime(xme.time);
+ }
+ else {
+ setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
+ }
+ }
+ else {
+ g_event = new GHOST_EventCursor(getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ xme.x_root + x_accum,
+ xme.y_root + y_accum);
+ }
+ }
+ else {
+ g_event = new GHOST_EventCursor(
+ getMilliSeconds(), GHOST_kEventCursorMove, window, xme.x_root, xme.y_root);
+ }
+ break;
+ }
+
+ case KeyPress:
+ case KeyRelease: {
+ XKeyEvent *xke = &(xe->xkey);
+ KeySym key_sym;
+ char ascii;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- /* utf8_array[] is initial buffer used for Xutf8LookupString().
- * if the length of the utf8 string exceeds this array, allocate
- * another memory area and call Xutf8LookupString() again.
- * the last 5 bytes are used to avoid segfault that might happen
- * at the end of this buffer when the constructor of GHOST_EventKey
- * reads 6 bytes regardless of the effective data length. */
- char utf8_array[16 * 6 + 5]; /* 16 utf8 characters */
- char *utf8_buf = utf8_array;
- int len = 1; /* at least one null character will be stored */
+ /* utf8_array[] is initial buffer used for Xutf8LookupString().
+ * if the length of the utf8 string exceeds this array, allocate
+ * another memory area and call Xutf8LookupString() again.
+ * the last 5 bytes are used to avoid segfault that might happen
+ * at the end of this buffer when the constructor of GHOST_EventKey
+ * reads 6 bytes regardless of the effective data length. */
+ char utf8_array[16 * 6 + 5]; /* 16 utf8 characters */
+ char *utf8_buf = utf8_array;
+ int len = 1; /* at least one null character will be stored */
#else
- char *utf8_buf = NULL;
+ char *utf8_buf = NULL;
#endif
- GHOST_TEventType type = (xke->type == KeyPress) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
+ GHOST_TEventType type = (xke->type == KeyPress) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
- GHOST_TKey gkey;
+ GHOST_TKey gkey;
#ifdef USE_NON_LATIN_KB_WORKAROUND
- /* XXX Code below is kinda awfully convoluted... Issues are:
- *
- * - In keyboards like latin ones, numbers need a 'Shift' to be accessed but key_sym
- * is unmodified (or anyone swapping the keys with xmodmap).
- *
- * - XLookupKeysym seems to always use first defined keymap (see T47228), which generates
- * keycodes unusable by ghost_key_from_keysym for non-latin-compatible keymaps.
- *
- * To address this, we:
- *
- * - Try to get a 'number' key_sym using XLookupKeysym (with virtual shift modifier),
- * in a very restrictive set of cases.
- * - Fallback to XLookupString to get a key_sym from active user-defined keymap.
- *
- * Note that:
- * - This effectively 'lock' main number keys to always output number events (except when using alt-gr).
- * - This enforces users to use an ascii-compatible keymap with Blender - but at least it gives
- * predictable and consistent results.
- *
- * Also, note that nothing in XLib sources [1] makes it obvious why those two functions give different
- * key_sym results...
- *
- * [1] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/KeyBind.c
- */
- KeySym key_sym_str;
- /* Mode_switch 'modifier' is AltGr - when this one or Shift are enabled, we do not want to apply
- * that 'forced number' hack. */
- const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch);
- const unsigned int number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask;
- if ((xke->keycode >= 10 && xke->keycode < 20) && ((xke->state & number_hack_forbidden_kmods_mask) == 0)) {
- key_sym = XLookupKeysym(xke, ShiftMask);
- if (!((key_sym >= XK_0) && (key_sym <= XK_9))) {
- key_sym = XLookupKeysym(xke, 0);
- }
- }
- else {
- key_sym = XLookupKeysym(xke, 0);
- }
-
- if (!XLookupString(xke, &ascii, 1, &key_sym_str, NULL)) {
- ascii = '\0';
- }
-
- /* Only allow a limited set of keys from XLookupKeysym, all others we take from XLookupString,
- * unless it gives unknown key... */
- gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode);
- switch (gkey) {
- case GHOST_kKeyRightAlt:
- case GHOST_kKeyLeftAlt:
- case GHOST_kKeyRightShift:
- case GHOST_kKeyLeftShift:
- case GHOST_kKeyRightControl:
- case GHOST_kKeyLeftControl:
- case GHOST_kKeyOS:
- case GHOST_kKey0:
- case GHOST_kKey1:
- case GHOST_kKey2:
- case GHOST_kKey3:
- case GHOST_kKey4:
- case GHOST_kKey5:
- case GHOST_kKey6:
- case GHOST_kKey7:
- case GHOST_kKey8:
- case GHOST_kKey9:
- case GHOST_kKeyNumpad0:
- case GHOST_kKeyNumpad1:
- case GHOST_kKeyNumpad2:
- case GHOST_kKeyNumpad3:
- case GHOST_kKeyNumpad4:
- case GHOST_kKeyNumpad5:
- case GHOST_kKeyNumpad6:
- case GHOST_kKeyNumpad7:
- case GHOST_kKeyNumpad8:
- case GHOST_kKeyNumpad9:
- case GHOST_kKeyNumpadPeriod:
- case GHOST_kKeyNumpadEnter:
- case GHOST_kKeyNumpadPlus:
- case GHOST_kKeyNumpadMinus:
- case GHOST_kKeyNumpadAsterisk:
- case GHOST_kKeyNumpadSlash:
- break;
- default:
- {
- GHOST_TKey gkey_str = ghost_key_from_keysym(key_sym_str);
- if (gkey_str != GHOST_kKeyUnknown) {
- gkey = gkey_str;
- }
- }
- }
+ /* XXX Code below is kinda awfully convoluted... Issues are:
+ *
+ * - In keyboards like latin ones, numbers need a 'Shift' to be accessed but key_sym
+ * is unmodified (or anyone swapping the keys with xmodmap).
+ *
+ * - XLookupKeysym seems to always use first defined keymap (see T47228), which generates
+ * keycodes unusable by ghost_key_from_keysym for non-latin-compatible keymaps.
+ *
+ * To address this, we:
+ *
+ * - Try to get a 'number' key_sym using XLookupKeysym (with virtual shift modifier),
+ * in a very restrictive set of cases.
+ * - Fallback to XLookupString to get a key_sym from active user-defined keymap.
+ *
+ * Note that:
+ * - This effectively 'lock' main number keys to always output number events (except when using alt-gr).
+ * - This enforces users to use an ascii-compatible keymap with Blender - but at least it gives
+ * predictable and consistent results.
+ *
+ * Also, note that nothing in XLib sources [1] makes it obvious why those two functions give different
+ * key_sym results...
+ *
+ * [1] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/KeyBind.c
+ */
+ KeySym key_sym_str;
+ /* Mode_switch 'modifier' is AltGr - when this one or Shift are enabled, we do not want to apply
+ * that 'forced number' hack. */
+ const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch);
+ const unsigned int number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask;
+ if ((xke->keycode >= 10 && xke->keycode < 20) &&
+ ((xke->state & number_hack_forbidden_kmods_mask) == 0)) {
+ key_sym = XLookupKeysym(xke, ShiftMask);
+ if (!((key_sym >= XK_0) && (key_sym <= XK_9))) {
+ key_sym = XLookupKeysym(xke, 0);
+ }
+ }
+ else {
+ key_sym = XLookupKeysym(xke, 0);
+ }
+
+ if (!XLookupString(xke, &ascii, 1, &key_sym_str, NULL)) {
+ ascii = '\0';
+ }
+
+ /* Only allow a limited set of keys from XLookupKeysym, all others we take from XLookupString,
+ * unless it gives unknown key... */
+ gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode);
+ switch (gkey) {
+ case GHOST_kKeyRightAlt:
+ case GHOST_kKeyLeftAlt:
+ case GHOST_kKeyRightShift:
+ case GHOST_kKeyLeftShift:
+ case GHOST_kKeyRightControl:
+ case GHOST_kKeyLeftControl:
+ case GHOST_kKeyOS:
+ case GHOST_kKey0:
+ case GHOST_kKey1:
+ case GHOST_kKey2:
+ case GHOST_kKey3:
+ case GHOST_kKey4:
+ case GHOST_kKey5:
+ case GHOST_kKey6:
+ case GHOST_kKey7:
+ case GHOST_kKey8:
+ case GHOST_kKey9:
+ case GHOST_kKeyNumpad0:
+ case GHOST_kKeyNumpad1:
+ case GHOST_kKeyNumpad2:
+ case GHOST_kKeyNumpad3:
+ case GHOST_kKeyNumpad4:
+ case GHOST_kKeyNumpad5:
+ case GHOST_kKeyNumpad6:
+ case GHOST_kKeyNumpad7:
+ case GHOST_kKeyNumpad8:
+ case GHOST_kKeyNumpad9:
+ case GHOST_kKeyNumpadPeriod:
+ case GHOST_kKeyNumpadEnter:
+ case GHOST_kKeyNumpadPlus:
+ case GHOST_kKeyNumpadMinus:
+ case GHOST_kKeyNumpadAsterisk:
+ case GHOST_kKeyNumpadSlash:
+ break;
+ default: {
+ GHOST_TKey gkey_str = ghost_key_from_keysym(key_sym_str);
+ if (gkey_str != GHOST_kKeyUnknown) {
+ gkey = gkey_str;
+ }
+ }
+ }
#else
- /* In keyboards like latin ones,
- * numbers needs a 'Shift' to be accessed but key_sym
- * is unmodified (or anyone swapping the keys with xmodmap).
- *
- * Here we look at the 'Shifted' version of the key.
- * If it is a number, then we take it instead of the normal key.
- *
- * The modified key is sent in the 'ascii's variable anyway.
- */
- if ((xke->keycode >= 10 && xke->keycode < 20) &&
- ((key_sym = XLookupKeysym(xke, ShiftMask)) >= XK_0) && (key_sym <= XK_9))
- {
- /* pass (keep shift'ed key_sym) */
- }
- else {
- /* regular case */
- key_sym = XLookupKeysym(xke, 0);
- }
-
- gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode);
-
- if (!XLookupString(xke, &ascii, 1, NULL, NULL)) {
- ascii = '\0';
- }
+ /* In keyboards like latin ones,
+ * numbers needs a 'Shift' to be accessed but key_sym
+ * is unmodified (or anyone swapping the keys with xmodmap).
+ *
+ * Here we look at the 'Shifted' version of the key.
+ * If it is a number, then we take it instead of the normal key.
+ *
+ * The modified key is sent in the 'ascii's variable anyway.
+ */
+ if ((xke->keycode >= 10 && xke->keycode < 20) &&
+ ((key_sym = XLookupKeysym(xke, ShiftMask)) >= XK_0) && (key_sym <= XK_9)) {
+ /* pass (keep shift'ed key_sym) */
+ }
+ else {
+ /* regular case */
+ key_sym = XLookupKeysym(xke, 0);
+ }
+
+ gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode);
+
+ if (!XLookupString(xke, &ascii, 1, NULL, NULL)) {
+ ascii = '\0';
+ }
#endif
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- /* getting unicode on key-up events gives XLookupNone status */
- XIC xic = window->getX11_XIC();
- if (xic && xke->type == KeyPress) {
- Status status;
-
- /* use utf8 because its not locale depentant, from xorg docs */
- if (!(len = Xutf8LookupString(xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) {
- utf8_buf[0] = '\0';
- }
-
- if (status == XBufferOverflow) {
- utf8_buf = (char *) malloc(len + 5);
- len = Xutf8LookupString(xic, xke, utf8_buf, len, &key_sym, &status);
- }
-
- if ((status == XLookupChars || status == XLookupBoth)) {
- if ((unsigned char)utf8_buf[0] >= 32) { /* not an ascii control character */
- /* do nothing for now, this is valid utf8 */
- }
- else {
- utf8_buf[0] = '\0';
- }
- }
- else if (status == XLookupKeySym) {
- /* this key doesn't have a text representation, it is a command
- * key of some sort */
- }
- else {
- printf("Bad keycode lookup. Keysym 0x%x Status: %s\n",
- (unsigned int) key_sym,
- (status == XLookupNone ? "XLookupNone" :
- status == XLookupKeySym ? "XLookupKeySym" :
- "Unknown status"));
-
- printf("'%.*s' %p %p\n", len, utf8_buf, xic, m_xim);
- }
- }
- else {
- utf8_buf[0] = '\0';
- }
+ /* getting unicode on key-up events gives XLookupNone status */
+ XIC xic = window->getX11_XIC();
+ if (xic && xke->type == KeyPress) {
+ Status status;
+
+ /* use utf8 because its not locale depentant, from xorg docs */
+ if (!(len = Xutf8LookupString(
+ xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) {
+ utf8_buf[0] = '\0';
+ }
+
+ if (status == XBufferOverflow) {
+ utf8_buf = (char *)malloc(len + 5);
+ len = Xutf8LookupString(xic, xke, utf8_buf, len, &key_sym, &status);
+ }
+
+ if ((status == XLookupChars || status == XLookupBoth)) {
+ if ((unsigned char)utf8_buf[0] >= 32) { /* not an ascii control character */
+ /* do nothing for now, this is valid utf8 */
+ }
+ else {
+ utf8_buf[0] = '\0';
+ }
+ }
+ else if (status == XLookupKeySym) {
+ /* this key doesn't have a text representation, it is a command
+ * key of some sort */
+ }
+ else {
+ printf("Bad keycode lookup. Keysym 0x%x Status: %s\n",
+ (unsigned int)key_sym,
+ (status == XLookupNone ?
+ "XLookupNone" :
+ status == XLookupKeySym ? "XLookupKeySym" : "Unknown status"));
+
+ printf("'%.*s' %p %p\n", len, utf8_buf, xic, m_xim);
+ }
+ }
+ else {
+ utf8_buf[0] = '\0';
+ }
#endif
- g_event = new
- GHOST_EventKey(
- getMilliSeconds(),
- type,
- window,
- gkey,
- ascii,
- utf8_buf
- );
+ g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, ascii, utf8_buf);
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- /* when using IM for some languages such as Japanese,
- * one event inserts multiple utf8 characters */
- if (xic && xke->type == KeyPress) {
- unsigned char c;
- int i = 0;
- while (1) {
- /* search character boundary */
- if ((unsigned char)utf8_buf[i++] > 0x7f) {
- for (; i < len; ++i) {
- c = utf8_buf[i];
- if (c < 0x80 || c > 0xbf) break;
- }
- }
-
- if (i >= len) break;
-
- /* enqueue previous character */
- pushEvent(g_event);
-
- g_event = new
- GHOST_EventKey(
- getMilliSeconds(),
- type,
- window,
- gkey,
- '\0',
- &utf8_buf[i]
- );
- }
- }
-
- if (utf8_buf != utf8_array)
- free(utf8_buf);
+ /* when using IM for some languages such as Japanese,
+ * one event inserts multiple utf8 characters */
+ if (xic && xke->type == KeyPress) {
+ unsigned char c;
+ int i = 0;
+ while (1) {
+ /* search character boundary */
+ if ((unsigned char)utf8_buf[i++] > 0x7f) {
+ for (; i < len; ++i) {
+ c = utf8_buf[i];
+ if (c < 0x80 || c > 0xbf)
+ break;
+ }
+ }
+
+ if (i >= len)
+ break;
+
+ /* enqueue previous character */
+ pushEvent(g_event);
+
+ g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, '\0', &utf8_buf[i]);
+ }
+ }
+
+ if (utf8_buf != utf8_array)
+ free(utf8_buf);
#endif
- break;
- }
-
- case ButtonPress:
- case ButtonRelease:
- {
- XButtonEvent & xbe = xe->xbutton;
- GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
- GHOST_TEventType type = (xbe.type == ButtonPress) ?
- GHOST_kEventButtonDown : GHOST_kEventButtonUp;
-
- /* process wheel mouse events and break, only pass on press events */
- if (xbe.button == Button4) {
- if (xbe.type == ButtonPress)
- g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1);
- break;
- }
- else if (xbe.button == Button5) {
- if (xbe.type == ButtonPress)
- g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
- break;
- }
-
- /* process rest of normal mouse buttons */
- if (xbe.button == Button1)
- gbmask = GHOST_kButtonMaskLeft;
- else if (xbe.button == Button2)
- gbmask = GHOST_kButtonMaskMiddle;
- else if (xbe.button == Button3)
- gbmask = GHOST_kButtonMaskRight;
- /* It seems events 6 and 7 are for horizontal scrolling.
- * you can re-order button mapping like this... (swaps 6,7 with 8,9)
- * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"
- */
- else if (xbe.button == 6)
- gbmask = GHOST_kButtonMaskButton6;
- else if (xbe.button == 7)
- gbmask = GHOST_kButtonMaskButton7;
- else if (xbe.button == 8)
- gbmask = GHOST_kButtonMaskButton4;
- else if (xbe.button == 9)
- gbmask = GHOST_kButtonMaskButton5;
- else
- break;
-
- g_event = new
- GHOST_EventButton(
- getMilliSeconds(),
- type,
- window,
- gbmask
- );
- break;
- }
-
- /* change of size, border, layer etc. */
- case ConfigureNotify:
- {
- /* XConfigureEvent & xce = xe->xconfigure; */
-
- g_event = new
- GHOST_Event(
- getMilliSeconds(),
- GHOST_kEventWindowSize,
- window
- );
- break;
- }
-
- case FocusIn:
- case FocusOut:
- {
- XFocusChangeEvent &xfe = xe->xfocus;
-
- /* TODO: make sure this is the correct place for activate/deactivate */
- // printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
-
- /* May have to look at the type of event and filter some out. */
-
- GHOST_TEventType gtype = (xfe.type == FocusIn) ?
- GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
+ break;
+ }
+
+ case ButtonPress:
+ case ButtonRelease: {
+ XButtonEvent &xbe = xe->xbutton;
+ GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
+ GHOST_TEventType type = (xbe.type == ButtonPress) ? GHOST_kEventButtonDown :
+ GHOST_kEventButtonUp;
+
+ /* process wheel mouse events and break, only pass on press events */
+ if (xbe.button == Button4) {
+ if (xbe.type == ButtonPress)
+ g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1);
+ break;
+ }
+ else if (xbe.button == Button5) {
+ if (xbe.type == ButtonPress)
+ g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
+ break;
+ }
+
+ /* process rest of normal mouse buttons */
+ if (xbe.button == Button1)
+ gbmask = GHOST_kButtonMaskLeft;
+ else if (xbe.button == Button2)
+ gbmask = GHOST_kButtonMaskMiddle;
+ else if (xbe.button == Button3)
+ gbmask = GHOST_kButtonMaskRight;
+ /* It seems events 6 and 7 are for horizontal scrolling.
+ * you can re-order button mapping like this... (swaps 6,7 with 8,9)
+ * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"
+ */
+ else if (xbe.button == 6)
+ gbmask = GHOST_kButtonMaskButton6;
+ else if (xbe.button == 7)
+ gbmask = GHOST_kButtonMaskButton7;
+ else if (xbe.button == 8)
+ gbmask = GHOST_kButtonMaskButton4;
+ else if (xbe.button == 9)
+ gbmask = GHOST_kButtonMaskButton5;
+ else
+ break;
+
+ g_event = new GHOST_EventButton(getMilliSeconds(), type, window, gbmask);
+ break;
+ }
+
+ /* change of size, border, layer etc. */
+ case ConfigureNotify: {
+ /* XConfigureEvent & xce = xe->xconfigure; */
+
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
+ break;
+ }
+
+ case FocusIn:
+ case FocusOut: {
+ XFocusChangeEvent &xfe = xe->xfocus;
+
+ /* TODO: make sure this is the correct place for activate/deactivate */
+ // printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
+
+ /* May have to look at the type of event and filter some out. */
+
+ GHOST_TEventType gtype = (xfe.type == FocusIn) ? GHOST_kEventWindowActivate :
+ GHOST_kEventWindowDeactivate;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- XIC xic = window->getX11_XIC();
- if (xic) {
- if (xe->type == FocusIn)
- XSetICFocus(xic);
- else
- XUnsetICFocus(xic);
- }
+ XIC xic = window->getX11_XIC();
+ if (xic) {
+ if (xe->type == FocusIn)
+ XSetICFocus(xic);
+ else
+ XUnsetICFocus(xic);
+ }
#endif
- g_event = new
- GHOST_Event(
- getMilliSeconds(),
- gtype,
- window
- );
- break;
-
- }
- case ClientMessage:
- {
- XClientMessageEvent & xcme = xe->xclient;
-
- if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) {
- g_event = new
- GHOST_Event(
- getMilliSeconds(),
- GHOST_kEventWindowClose,
- window
- );
- }
- else if (((Atom)xcme.data.l[0]) == m_atom.WM_TAKE_FOCUS) {
- XWindowAttributes attr;
- Window fwin;
- int revert_to;
-
- /* as ICCCM say, we need reply this event
- * with a SetInputFocus, the data[1] have
- * the valid timestamp (send by the wm).
- *
- * Some WM send this event before the
- * window is really mapped (for example
- * change from virtual desktop), so we need
- * to be sure that our windows is mapped
- * or this call fail and close blender.
- */
- if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) {
- if (XGetInputFocus(m_display, &fwin, &revert_to) == True) {
- if (attr.map_state == IsViewable) {
- if (fwin != xcme.window)
- XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
- }
- }
- }
- }
- else {
+ g_event = new GHOST_Event(getMilliSeconds(), gtype, window);
+ break;
+ }
+ case ClientMessage: {
+ XClientMessageEvent &xcme = xe->xclient;
+
+ if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) {
+ g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
+ }
+ else if (((Atom)xcme.data.l[0]) == m_atom.WM_TAKE_FOCUS) {
+ XWindowAttributes attr;
+ Window fwin;
+ int revert_to;
+
+ /* as ICCCM say, we need reply this event
+ * with a SetInputFocus, the data[1] have
+ * the valid timestamp (send by the wm).
+ *
+ * Some WM send this event before the
+ * window is really mapped (for example
+ * change from virtual desktop), so we need
+ * to be sure that our windows is mapped
+ * or this call fail and close blender.
+ */
+ if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) {
+ if (XGetInputFocus(m_display, &fwin, &revert_to) == True) {
+ if (attr.map_state == IsViewable) {
+ if (fwin != xcme.window)
+ XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
+ }
+ }
+ }
+ }
+ else {
#ifdef WITH_XDND
- /* try to handle drag event (if there's no such events, GHOST_HandleClientMessage will return zero) */
- if (window->getDropTarget()->GHOST_HandleClientMessage(xe) == false) {
- /* Unknown client message, ignore */
- }
+ /* try to handle drag event (if there's no such events, GHOST_HandleClientMessage will return zero) */
+ if (window->getDropTarget()->GHOST_HandleClientMessage(xe) == false) {
+ /* Unknown client message, ignore */
+ }
#else
- /* Unknown client message, ignore */
+ /* Unknown client message, ignore */
#endif
- }
-
- break;
- }
-
- case DestroyNotify:
- ::exit(-1);
- /* We're not interested in the following things.(yet...) */
- case NoExpose:
- case GraphicsExpose:
- break;
-
- case EnterNotify:
- case LeaveNotify:
- {
- /* XCrossingEvents pointer leave enter window.
- * also do cursor move here, MotionNotify only
- * happens when motion starts & ends inside window.
- * we only do moves when the crossing mode is 'normal'
- * (really crossing between windows) since some windowmanagers
- * also send grab/ungrab crossings for mousewheel events.
- */
- XCrossingEvent &xce = xe->xcrossing;
- if (xce.mode == NotifyNormal) {
- g_event = new
- GHOST_EventCursor(
- getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- xce.x_root,
- xce.y_root
- );
- }
-
- // printf("X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window);
-
- if (xce.type == EnterNotify)
- m_windowManager->setActiveWindow(window);
- else
- m_windowManager->setWindowInactive(window);
-
- break;
- }
- case MapNotify:
- /*
- * From ICCCM:
- * [ Clients can select for StructureNotify on their
- * top-level windows to track transition between
- * Normal and Iconic states. Receipt of a MapNotify
- * event will indicate a transition to the Normal
- * state, and receipt of an UnmapNotify event will
- * indicate a transition to the Iconic state. ]
- */
- if (window->m_post_init == True) {
- /*
- * Now we are sure that the window is
- * mapped, so only need change the state.
- */
- window->setState(window->m_post_state);
- window->m_post_init = False;
- }
- break;
- case UnmapNotify:
- break;
- case MappingNotify:
- case ReparentNotify:
- break;
- case SelectionRequest:
- {
- XEvent nxe;
- Atom target, utf8_string, string, compound_text, c_string;
- XSelectionRequestEvent *xse = &xe->xselectionrequest;
-
- target = XInternAtom(m_display, "TARGETS", False);
- utf8_string = XInternAtom(m_display, "UTF8_STRING", False);
- string = XInternAtom(m_display, "STRING", False);
- compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
- c_string = XInternAtom(m_display, "C_STRING", False);
-
- /* support obsolete clients */
- if (xse->property == None) {
- xse->property = xse->target;
- }
-
- nxe.xselection.type = SelectionNotify;
- nxe.xselection.requestor = xse->requestor;
- nxe.xselection.property = xse->property;
- nxe.xselection.display = xse->display;
- nxe.xselection.selection = xse->selection;
- nxe.xselection.target = xse->target;
- nxe.xselection.time = xse->time;
-
- /* Check to see if the requestor is asking for String */
- if (xse->target == utf8_string ||
- xse->target == string ||
- xse->target == compound_text ||
- xse->target == c_string)
- {
- if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) {
- XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace,
- (unsigned char *)txt_select_buffer, strlen(txt_select_buffer));
- }
- else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) {
- XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace,
- (unsigned char *)txt_cut_buffer, strlen(txt_cut_buffer));
- }
- }
- else if (xse->target == target) {
- Atom alist[5];
- alist[0] = target;
- alist[1] = utf8_string;
- alist[2] = string;
- alist[3] = compound_text;
- alist[4] = c_string;
- XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 32, PropModeReplace,
- (unsigned char *)alist, 5);
- XFlush(m_display);
- }
- else {
- /* Change property to None because we do not support anything but STRING */
- nxe.xselection.property = None;
- }
-
- /* Send the event to the client 0 0 == False, SelectionNotify */
- XSendEvent(m_display, xse->requestor, 0, 0, &nxe);
- XFlush(m_display);
- break;
- }
-
- default:
- {
+ }
+
+ break;
+ }
+
+ case DestroyNotify:
+ ::exit(-1);
+ /* We're not interested in the following things.(yet...) */
+ case NoExpose:
+ case GraphicsExpose:
+ break;
+
+ case EnterNotify:
+ case LeaveNotify: {
+ /* XCrossingEvents pointer leave enter window.
+ * also do cursor move here, MotionNotify only
+ * happens when motion starts & ends inside window.
+ * we only do moves when the crossing mode is 'normal'
+ * (really crossing between windows) since some windowmanagers
+ * also send grab/ungrab crossings for mousewheel events.
+ */
+ XCrossingEvent &xce = xe->xcrossing;
+ if (xce.mode == NotifyNormal) {
+ g_event = new GHOST_EventCursor(
+ getMilliSeconds(), GHOST_kEventCursorMove, window, xce.x_root, xce.y_root);
+ }
+
+ // printf("X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window);
+
+ if (xce.type == EnterNotify)
+ m_windowManager->setActiveWindow(window);
+ else
+ m_windowManager->setWindowInactive(window);
+
+ break;
+ }
+ case MapNotify:
+ /*
+ * From ICCCM:
+ * [ Clients can select for StructureNotify on their
+ * top-level windows to track transition between
+ * Normal and Iconic states. Receipt of a MapNotify
+ * event will indicate a transition to the Normal
+ * state, and receipt of an UnmapNotify event will
+ * indicate a transition to the Iconic state. ]
+ */
+ if (window->m_post_init == True) {
+ /*
+ * Now we are sure that the window is
+ * mapped, so only need change the state.
+ */
+ window->setState(window->m_post_state);
+ window->m_post_init = False;
+ }
+ break;
+ case UnmapNotify:
+ break;
+ case MappingNotify:
+ case ReparentNotify:
+ break;
+ case SelectionRequest: {
+ XEvent nxe;
+ Atom target, utf8_string, string, compound_text, c_string;
+ XSelectionRequestEvent *xse = &xe->xselectionrequest;
+
+ target = XInternAtom(m_display, "TARGETS", False);
+ utf8_string = XInternAtom(m_display, "UTF8_STRING", False);
+ string = XInternAtom(m_display, "STRING", False);
+ compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
+ c_string = XInternAtom(m_display, "C_STRING", False);
+
+ /* support obsolete clients */
+ if (xse->property == None) {
+ xse->property = xse->target;
+ }
+
+ nxe.xselection.type = SelectionNotify;
+ nxe.xselection.requestor = xse->requestor;
+ nxe.xselection.property = xse->property;
+ nxe.xselection.display = xse->display;
+ nxe.xselection.selection = xse->selection;
+ nxe.xselection.target = xse->target;
+ nxe.xselection.time = xse->time;
+
+ /* Check to see if the requestor is asking for String */
+ if (xse->target == utf8_string || xse->target == string || xse->target == compound_text ||
+ xse->target == c_string) {
+ if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) {
+ XChangeProperty(m_display,
+ xse->requestor,
+ xse->property,
+ xse->target,
+ 8,
+ PropModeReplace,
+ (unsigned char *)txt_select_buffer,
+ strlen(txt_select_buffer));
+ }
+ else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) {
+ XChangeProperty(m_display,
+ xse->requestor,
+ xse->property,
+ xse->target,
+ 8,
+ PropModeReplace,
+ (unsigned char *)txt_cut_buffer,
+ strlen(txt_cut_buffer));
+ }
+ }
+ else if (xse->target == target) {
+ Atom alist[5];
+ alist[0] = target;
+ alist[1] = utf8_string;
+ alist[2] = string;
+ alist[3] = compound_text;
+ alist[4] = c_string;
+ XChangeProperty(m_display,
+ xse->requestor,
+ xse->property,
+ xse->target,
+ 32,
+ PropModeReplace,
+ (unsigned char *)alist,
+ 5);
+ XFlush(m_display);
+ }
+ else {
+ /* Change property to None because we do not support anything but STRING */
+ nxe.xselection.property = None;
+ }
+
+ /* Send the event to the client 0 0 == False, SelectionNotify */
+ XSendEvent(m_display, xse->requestor, 0, 0, &nxe);
+ XFlush(m_display);
+ break;
+ }
+
+ default: {
#ifdef WITH_X11_XINPUT
- for (GHOST_TabletX11& xtablet: m_xtablets) {
- if (xe->type == xtablet.MotionEvent || xe->type == xtablet.PressEvent) {
- XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe;
- if (data->deviceid != xtablet.ID) {
- continue;
- }
-
- const unsigned char axis_first = data->first_axis;
- const unsigned char axes_end = axis_first + data->axes_count; /* after the last */
- int axis_value;
-
- /* stroke might begin without leading ProxyIn event,
- * this happens when window is opened when stylus is already hovering
- * around tablet surface */
- window->GetTabletData()->Active = xtablet.mode;
-
- /* Note: This event might be generated with incomplete dataset (don't exactly know why, looks like in
- * some cases, if the value does not change, it is not included in subsequent XDeviceMotionEvent
- * events). So we have to check which values this event actually contains!
- */
-
-#define AXIS_VALUE_GET(axis, val) \
- ((axis_first <= axis && axes_end > axis) && ((void)(val = data->axis_data[axis - axis_first]), true))
-
- if (AXIS_VALUE_GET(2, axis_value)) {
- window->GetTabletData()->Pressure = axis_value / ((float)xtablet.PressureLevels);
- }
-
- /* the (short) cast and the & 0xffff is bizarre and unexplained anywhere,
- * but I got garbage data without it. Found it in the xidump.c source --matt
- *
- * The '& 0xffff' just truncates the value to its two lowest bytes, this probably means
- * some drivers do not properly set the whole int value? Since we convert to float afterward,
- * I don't think we need to cast to short here, but do not have a device to check this. --mont29
- */
- if (AXIS_VALUE_GET(3, axis_value)) {
- window->GetTabletData()->Xtilt = (short)(axis_value & 0xffff) /
- ((float)xtablet.XtiltLevels);
- }
- if (AXIS_VALUE_GET(4, axis_value)) {
- window->GetTabletData()->Ytilt = (short)(axis_value & 0xffff) /
- ((float)xtablet.YtiltLevels);
- }
-
-#undef AXIS_VALUE_GET
-
- }
- else if (xe->type == xtablet.ProxInEvent) {
- XProximityNotifyEvent *data = (XProximityNotifyEvent *)xe;
- if (data->deviceid != xtablet.ID) {
- continue;
- }
-
- window->GetTabletData()->Active = xtablet.mode;
- }
- else if (xe->type == xtablet.ProxOutEvent) {
- window->GetTabletData()->Active = GHOST_kTabletModeNone;
- }
- }
-#endif // WITH_X11_XINPUT
- break;
- }
- }
-
- if (g_event) {
- pushEvent(g_event);
- }
+ for (GHOST_TabletX11 &xtablet : m_xtablets) {
+ if (xe->type == xtablet.MotionEvent || xe->type == xtablet.PressEvent) {
+ XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe;
+ if (data->deviceid != xtablet.ID) {
+ continue;
+ }
+
+ const unsigned char axis_first = data->first_axis;
+ const unsigned char axes_end = axis_first + data->axes_count; /* after the last */
+ int axis_value;
+
+ /* stroke might begin without leading ProxyIn event,
+ * this happens when window is opened when stylus is already hovering
+ * around tablet surface */
+ window->GetTabletData()->Active = xtablet.mode;
+
+ /* Note: This event might be generated with incomplete dataset (don't exactly know why, looks like in
+ * some cases, if the value does not change, it is not included in subsequent XDeviceMotionEvent
+ * events). So we have to check which values this event actually contains!
+ */
+
+# define AXIS_VALUE_GET(axis, val) \
+ ((axis_first <= axis && axes_end > axis) && \
+ ((void)(val = data->axis_data[axis - axis_first]), true))
+
+ if (AXIS_VALUE_GET(2, axis_value)) {
+ window->GetTabletData()->Pressure = axis_value / ((float)xtablet.PressureLevels);
+ }
+
+ /* the (short) cast and the & 0xffff is bizarre and unexplained anywhere,
+ * but I got garbage data without it. Found it in the xidump.c source --matt
+ *
+ * The '& 0xffff' just truncates the value to its two lowest bytes, this probably means
+ * some drivers do not properly set the whole int value? Since we convert to float afterward,
+ * I don't think we need to cast to short here, but do not have a device to check this. --mont29
+ */
+ if (AXIS_VALUE_GET(3, axis_value)) {
+ window->GetTabletData()->Xtilt = (short)(axis_value & 0xffff) /
+ ((float)xtablet.XtiltLevels);
+ }
+ if (AXIS_VALUE_GET(4, axis_value)) {
+ window->GetTabletData()->Ytilt = (short)(axis_value & 0xffff) /
+ ((float)xtablet.YtiltLevels);
+ }
+
+# undef AXIS_VALUE_GET
+ }
+ else if (xe->type == xtablet.ProxInEvent) {
+ XProximityNotifyEvent *data = (XProximityNotifyEvent *)xe;
+ if (data->deviceid != xtablet.ID) {
+ continue;
+ }
+
+ window->GetTabletData()->Active = xtablet.mode;
+ }
+ else if (xe->type == xtablet.ProxOutEvent) {
+ window->GetTabletData()->Active = GHOST_kTabletModeNone;
+ }
+ }
+#endif // WITH_X11_XINPUT
+ break;
+ }
+ }
+
+ if (g_event) {
+ pushEvent(g_event);
+ }
}
-GHOST_TSuccess
-GHOST_SystemX11::
-getModifierKeys(
- GHOST_ModifierKeys& keys) const
+GHOST_TSuccess GHOST_SystemX11::getModifierKeys(GHOST_ModifierKeys &keys) const
{
- /* analyse the masks retuned from XQueryPointer. */
-
- memset((void *)m_keyboard_vector, 0, sizeof(m_keyboard_vector));
-
- XQueryKeymap(m_display, (char *)m_keyboard_vector);
-
- /* now translate key symbols into keycodes and
- * test with vector. */
-
- const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L);
- const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R);
- const static KeyCode control_l = XKeysymToKeycode(m_display, XK_Control_L);
- const static KeyCode control_r = XKeysymToKeycode(m_display, XK_Control_R);
- const static KeyCode alt_l = XKeysymToKeycode(m_display, XK_Alt_L);
- const static KeyCode alt_r = XKeysymToKeycode(m_display, XK_Alt_R);
- const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L);
- const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R);
-
- /* shift */
- keys.set(GHOST_kModifierKeyLeftShift, ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0);
- keys.set(GHOST_kModifierKeyRightShift, ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0);
- /* control */
- keys.set(GHOST_kModifierKeyLeftControl, ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0);
- keys.set(GHOST_kModifierKeyRightControl, ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0);
- /* alt */
- keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0);
- keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0);
- /* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */
- keys.set(GHOST_kModifierKeyOS, ( ((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
- ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) ) != 0);
-
- return GHOST_kSuccess;
+ /* analyse the masks retuned from XQueryPointer. */
+
+ memset((void *)m_keyboard_vector, 0, sizeof(m_keyboard_vector));
+
+ XQueryKeymap(m_display, (char *)m_keyboard_vector);
+
+ /* now translate key symbols into keycodes and
+ * test with vector. */
+
+ const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L);
+ const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R);
+ const static KeyCode control_l = XKeysymToKeycode(m_display, XK_Control_L);
+ const static KeyCode control_r = XKeysymToKeycode(m_display, XK_Control_R);
+ const static KeyCode alt_l = XKeysymToKeycode(m_display, XK_Alt_L);
+ const static KeyCode alt_r = XKeysymToKeycode(m_display, XK_Alt_R);
+ const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L);
+ const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R);
+
+ /* shift */
+ keys.set(GHOST_kModifierKeyLeftShift,
+ ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0);
+ keys.set(GHOST_kModifierKeyRightShift,
+ ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0);
+ /* control */
+ keys.set(GHOST_kModifierKeyLeftControl,
+ ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0);
+ keys.set(GHOST_kModifierKeyRightControl,
+ ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0);
+ /* alt */
+ keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0);
+ keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0);
+ /* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */
+ keys.set(GHOST_kModifierKeyOS,
+ (((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
+ ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1)) != 0);
+
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_SystemX11::
-getButtons(
- GHOST_Buttons& buttons) const
+GHOST_TSuccess GHOST_SystemX11::getButtons(GHOST_Buttons &buttons) const
{
- Window root_return, child_return;
- int rx, ry, wx, wy;
- unsigned int mask_return;
-
- if (XQueryPointer(m_display,
- RootWindow(m_display, DefaultScreen(m_display)),
- &root_return,
- &child_return,
- &rx, &ry,
- &wx, &wy,
- &mask_return) == True)
- {
- buttons.set(GHOST_kButtonMaskLeft, (mask_return & Button1Mask) != 0);
- buttons.set(GHOST_kButtonMaskMiddle, (mask_return & Button2Mask) != 0);
- buttons.set(GHOST_kButtonMaskRight, (mask_return & Button3Mask) != 0);
- }
- else {
- return GHOST_kFailure;
- }
-
- return GHOST_kSuccess;
+ Window root_return, child_return;
+ int rx, ry, wx, wy;
+ unsigned int mask_return;
+
+ if (XQueryPointer(m_display,
+ RootWindow(m_display, DefaultScreen(m_display)),
+ &root_return,
+ &child_return,
+ &rx,
+ &ry,
+ &wx,
+ &wy,
+ &mask_return) == True) {
+ buttons.set(GHOST_kButtonMaskLeft, (mask_return & Button1Mask) != 0);
+ buttons.set(GHOST_kButtonMaskMiddle, (mask_return & Button2Mask) != 0);
+ buttons.set(GHOST_kButtonMaskRight, (mask_return & Button3Mask) != 0);
+ }
+ else {
+ return GHOST_kFailure;
+ }
+
+ return GHOST_kSuccess;
}
-static GHOST_TSuccess getCursorPosition_impl(
- Display *display,
- GHOST_TInt32& x,
- GHOST_TInt32& y,
- Window *child_return)
+static GHOST_TSuccess getCursorPosition_impl(Display *display,
+ GHOST_TInt32 &x,
+ GHOST_TInt32 &y,
+ Window *child_return)
{
- int rx, ry, wx, wy;
- unsigned int mask_return;
- Window root_return;
-
- if (XQueryPointer(
- display,
- RootWindow(display, DefaultScreen(display)),
- &root_return,
- child_return,
- &rx, &ry,
- &wx, &wy,
- &mask_return
- ) == False) {
- return GHOST_kFailure;
- }
- else {
- x = rx;
- y = ry;
- }
- return GHOST_kSuccess;
+ int rx, ry, wx, wy;
+ unsigned int mask_return;
+ Window root_return;
+
+ if (XQueryPointer(display,
+ RootWindow(display, DefaultScreen(display)),
+ &root_return,
+ child_return,
+ &rx,
+ &ry,
+ &wx,
+ &wy,
+ &mask_return) == False) {
+ return GHOST_kFailure;
+ }
+ else {
+ x = rx;
+ y = ry;
+ }
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_SystemX11::
-getCursorPosition(
- GHOST_TInt32& x,
- GHOST_TInt32& y) const
+GHOST_TSuccess GHOST_SystemX11::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- Window child_return;
- return getCursorPosition_impl(m_display, x, y, &child_return);
+ Window child_return;
+ return getCursorPosition_impl(m_display, x, y, &child_return);
}
-
-GHOST_TSuccess
-GHOST_SystemX11::
-setCursorPosition(
- GHOST_TInt32 x,
- GHOST_TInt32 y)
+GHOST_TSuccess GHOST_SystemX11::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
{
- /* This is a brute force move in screen coordinates
- * XWarpPointer does relative moves so first determine the
- * current pointer position. */
+ /* This is a brute force move in screen coordinates
+ * XWarpPointer does relative moves so first determine the
+ * current pointer position. */
- int cx, cy;
+ int cx, cy;
#ifdef WITH_XWAYLAND_HACK
- Window child_return = None;
- if (getCursorPosition_impl(m_display, cx, cy, &child_return) == GHOST_kFailure) {
- return GHOST_kFailure;
- }
+ Window child_return = None;
+ if (getCursorPosition_impl(m_display, cx, cy, &child_return) == GHOST_kFailure) {
+ return GHOST_kFailure;
+ }
#else
- if (getCursorPosition(cx, cy) == GHOST_kFailure) {
- return GHOST_kFailure;
- }
+ if (getCursorPosition(cx, cy) == GHOST_kFailure) {
+ return GHOST_kFailure;
+ }
#endif
- int relx = x - cx;
- int rely = y - cy;
+ int relx = x - cx;
+ int rely = y - cy;
#ifdef WITH_XWAYLAND_HACK
- if (use_xwayland_hack) {
- if (child_return != None) {
- XFixesHideCursor(m_display, child_return);
- }
- }
+ if (use_xwayland_hack) {
+ if (child_return != None) {
+ XFixesHideCursor(m_display, child_return);
+ }
+ }
#endif
#if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
- if ((m_xinput_version.present) &&
- (m_xinput_version.major_version >= 2))
- {
- /* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */
- int device_id;
- if (XIGetClientPointer(m_display, None, &device_id) != False) {
- XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
- }
- }
- else
+ if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) {
+ /* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */
+ int device_id;
+ if (XIGetClientPointer(m_display, None, &device_id) != False) {
+ XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
+ }
+ }
+ else
#endif
- {
- XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely);
- }
+ {
+ XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely);
+ }
#ifdef WITH_XWAYLAND_HACK
- if (use_xwayland_hack) {
- if (child_return != None) {
- XFixesShowCursor(m_display, child_return);
- }
- }
+ if (use_xwayland_hack) {
+ if (child_return != None) {
+ XFixesShowCursor(m_display, child_return);
+ }
+ }
#endif
- XSync(m_display, 0); /* Sync to process all requests */
+ XSync(m_display, 0); /* Sync to process all requests */
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
-void
-GHOST_SystemX11::
-addDirtyWindow(
- GHOST_WindowX11 *bad_wind)
+void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind)
{
- GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
+ GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
- m_dirty_windows.push_back(bad_wind);
+ m_dirty_windows.push_back(bad_wind);
}
-
-bool
-GHOST_SystemX11::
-generateWindowExposeEvents()
+bool GHOST_SystemX11::generateWindowExposeEvents()
{
- vector<GHOST_WindowX11 *>::iterator w_start = m_dirty_windows.begin();
- vector<GHOST_WindowX11 *>::const_iterator w_end = m_dirty_windows.end();
- bool anyProcessed = false;
-
- for (; w_start != w_end; ++w_start) {
- GHOST_Event *g_event = new
- GHOST_Event(
- getMilliSeconds(),
- GHOST_kEventWindowUpdate,
- *w_start
- );
-
- (*w_start)->validate();
-
- if (g_event) {
- pushEvent(g_event);
- anyProcessed = true;
- }
- }
-
- m_dirty_windows.clear();
- return anyProcessed;
+ vector<GHOST_WindowX11 *>::iterator w_start = m_dirty_windows.begin();
+ vector<GHOST_WindowX11 *>::const_iterator w_end = m_dirty_windows.end();
+ bool anyProcessed = false;
+
+ for (; w_start != w_end; ++w_start) {
+ GHOST_Event *g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, *w_start);
+
+ (*w_start)->validate();
+
+ if (g_event) {
+ pushEvent(g_event);
+ anyProcessed = true;
+ }
+ }
+
+ m_dirty_windows.clear();
+ return anyProcessed;
}
-static GHOST_TKey
-ghost_key_from_keysym_or_keycode(const KeySym keysym, XkbDescPtr xkb_descr, const KeyCode keycode)
+static GHOST_TKey ghost_key_from_keysym_or_keycode(const KeySym keysym,
+ XkbDescPtr xkb_descr,
+ const KeyCode keycode)
{
- GHOST_TKey type = ghost_key_from_keysym(keysym);
- if (type == GHOST_kKeyUnknown) {
- if (xkb_descr) {
- type = ghost_key_from_keycode(xkb_descr, keycode);
- }
- }
- return type;
+ GHOST_TKey type = ghost_key_from_keysym(keysym);
+ if (type == GHOST_kKeyUnknown) {
+ if (xkb_descr) {
+ type = ghost_key_from_keycode(xkb_descr, keycode);
+ }
+ }
+ return type;
}
-#define GXMAP(k, x, y) case x: k = y; break
+#define GXMAP(k, x, y) \
+ case x: \
+ k = y; \
+ break
-static GHOST_TKey
-ghost_key_from_keysym(const KeySym key)
+static GHOST_TKey ghost_key_from_keysym(const KeySym key)
{
- GHOST_TKey type;
-
- if ((key >= XK_A) && (key <= XK_Z)) {
- type = GHOST_TKey(key - XK_A + int(GHOST_kKeyA));
- }
- else if ((key >= XK_a) && (key <= XK_z)) {
- type = GHOST_TKey(key - XK_a + int(GHOST_kKeyA));
- }
- else if ((key >= XK_0) && (key <= XK_9)) {
- type = GHOST_TKey(key - XK_0 + int(GHOST_kKey0));
- }
- else if ((key >= XK_F1) && (key <= XK_F24)) {
- type = GHOST_TKey(key - XK_F1 + int(GHOST_kKeyF1));
- }
- else {
- switch (key) {
- GXMAP(type, XK_BackSpace, GHOST_kKeyBackSpace);
- GXMAP(type, XK_Tab, GHOST_kKeyTab);
- GXMAP(type, XK_ISO_Left_Tab, GHOST_kKeyTab);
- GXMAP(type, XK_Return, GHOST_kKeyEnter);
- GXMAP(type, XK_Escape, GHOST_kKeyEsc);
- GXMAP(type, XK_space, GHOST_kKeySpace);
-
- GXMAP(type, XK_Linefeed, GHOST_kKeyLinefeed);
- GXMAP(type, XK_semicolon, GHOST_kKeySemicolon);
- GXMAP(type, XK_period, GHOST_kKeyPeriod);
- GXMAP(type, XK_comma, GHOST_kKeyComma);
- GXMAP(type, XK_quoteright, GHOST_kKeyQuote);
- GXMAP(type, XK_quoteleft, GHOST_kKeyAccentGrave);
- GXMAP(type, XK_minus, GHOST_kKeyMinus);
- GXMAP(type, XK_plus, GHOST_kKeyPlus);
- GXMAP(type, XK_slash, GHOST_kKeySlash);
- GXMAP(type, XK_backslash, GHOST_kKeyBackslash);
- GXMAP(type, XK_equal, GHOST_kKeyEqual);
- GXMAP(type, XK_bracketleft, GHOST_kKeyLeftBracket);
- GXMAP(type, XK_bracketright, GHOST_kKeyRightBracket);
- GXMAP(type, XK_Pause, GHOST_kKeyPause);
-
- GXMAP(type, XK_Shift_L, GHOST_kKeyLeftShift);
- GXMAP(type, XK_Shift_R, GHOST_kKeyRightShift);
- GXMAP(type, XK_Control_L, GHOST_kKeyLeftControl);
- GXMAP(type, XK_Control_R, GHOST_kKeyRightControl);
- GXMAP(type, XK_Alt_L, GHOST_kKeyLeftAlt);
- GXMAP(type, XK_Alt_R, GHOST_kKeyRightAlt);
- GXMAP(type, XK_Super_L, GHOST_kKeyOS);
- GXMAP(type, XK_Super_R, GHOST_kKeyOS);
-
- GXMAP(type, XK_Insert, GHOST_kKeyInsert);
- GXMAP(type, XK_Delete, GHOST_kKeyDelete);
- GXMAP(type, XK_Home, GHOST_kKeyHome);
- GXMAP(type, XK_End, GHOST_kKeyEnd);
- GXMAP(type, XK_Page_Up, GHOST_kKeyUpPage);
- GXMAP(type, XK_Page_Down, GHOST_kKeyDownPage);
-
- GXMAP(type, XK_Left, GHOST_kKeyLeftArrow);
- GXMAP(type, XK_Right, GHOST_kKeyRightArrow);
- GXMAP(type, XK_Up, GHOST_kKeyUpArrow);
- GXMAP(type, XK_Down, GHOST_kKeyDownArrow);
-
- GXMAP(type, XK_Caps_Lock, GHOST_kKeyCapsLock);
- GXMAP(type, XK_Scroll_Lock, GHOST_kKeyScrollLock);
- GXMAP(type, XK_Num_Lock, GHOST_kKeyNumLock);
-
- /* keypad events */
-
- GXMAP(type, XK_KP_0, GHOST_kKeyNumpad0);
- GXMAP(type, XK_KP_1, GHOST_kKeyNumpad1);
- GXMAP(type, XK_KP_2, GHOST_kKeyNumpad2);
- GXMAP(type, XK_KP_3, GHOST_kKeyNumpad3);
- GXMAP(type, XK_KP_4, GHOST_kKeyNumpad4);
- GXMAP(type, XK_KP_5, GHOST_kKeyNumpad5);
- GXMAP(type, XK_KP_6, GHOST_kKeyNumpad6);
- GXMAP(type, XK_KP_7, GHOST_kKeyNumpad7);
- GXMAP(type, XK_KP_8, GHOST_kKeyNumpad8);
- GXMAP(type, XK_KP_9, GHOST_kKeyNumpad9);
- GXMAP(type, XK_KP_Decimal, GHOST_kKeyNumpadPeriod);
-
- GXMAP(type, XK_KP_Insert, GHOST_kKeyNumpad0);
- GXMAP(type, XK_KP_End, GHOST_kKeyNumpad1);
- GXMAP(type, XK_KP_Down, GHOST_kKeyNumpad2);
- GXMAP(type, XK_KP_Page_Down, GHOST_kKeyNumpad3);
- GXMAP(type, XK_KP_Left, GHOST_kKeyNumpad4);
- GXMAP(type, XK_KP_Begin, GHOST_kKeyNumpad5);
- GXMAP(type, XK_KP_Right, GHOST_kKeyNumpad6);
- GXMAP(type, XK_KP_Home, GHOST_kKeyNumpad7);
- GXMAP(type, XK_KP_Up, GHOST_kKeyNumpad8);
- GXMAP(type, XK_KP_Page_Up, GHOST_kKeyNumpad9);
- GXMAP(type, XK_KP_Delete, GHOST_kKeyNumpadPeriod);
-
- GXMAP(type, XK_KP_Enter, GHOST_kKeyNumpadEnter);
- GXMAP(type, XK_KP_Add, GHOST_kKeyNumpadPlus);
- GXMAP(type, XK_KP_Subtract, GHOST_kKeyNumpadMinus);
- GXMAP(type, XK_KP_Multiply, GHOST_kKeyNumpadAsterisk);
- GXMAP(type, XK_KP_Divide, GHOST_kKeyNumpadSlash);
-
- /* Media keys in some keyboards and laptops with XFree86/Xorg */
+ GHOST_TKey type;
+
+ if ((key >= XK_A) && (key <= XK_Z)) {
+ type = GHOST_TKey(key - XK_A + int(GHOST_kKeyA));
+ }
+ else if ((key >= XK_a) && (key <= XK_z)) {
+ type = GHOST_TKey(key - XK_a + int(GHOST_kKeyA));
+ }
+ else if ((key >= XK_0) && (key <= XK_9)) {
+ type = GHOST_TKey(key - XK_0 + int(GHOST_kKey0));
+ }
+ else if ((key >= XK_F1) && (key <= XK_F24)) {
+ type = GHOST_TKey(key - XK_F1 + int(GHOST_kKeyF1));
+ }
+ else {
+ switch (key) {
+ GXMAP(type, XK_BackSpace, GHOST_kKeyBackSpace);
+ GXMAP(type, XK_Tab, GHOST_kKeyTab);
+ GXMAP(type, XK_ISO_Left_Tab, GHOST_kKeyTab);
+ GXMAP(type, XK_Return, GHOST_kKeyEnter);
+ GXMAP(type, XK_Escape, GHOST_kKeyEsc);
+ GXMAP(type, XK_space, GHOST_kKeySpace);
+
+ GXMAP(type, XK_Linefeed, GHOST_kKeyLinefeed);
+ GXMAP(type, XK_semicolon, GHOST_kKeySemicolon);
+ GXMAP(type, XK_period, GHOST_kKeyPeriod);
+ GXMAP(type, XK_comma, GHOST_kKeyComma);
+ GXMAP(type, XK_quoteright, GHOST_kKeyQuote);
+ GXMAP(type, XK_quoteleft, GHOST_kKeyAccentGrave);
+ GXMAP(type, XK_minus, GHOST_kKeyMinus);
+ GXMAP(type, XK_plus, GHOST_kKeyPlus);
+ GXMAP(type, XK_slash, GHOST_kKeySlash);
+ GXMAP(type, XK_backslash, GHOST_kKeyBackslash);
+ GXMAP(type, XK_equal, GHOST_kKeyEqual);
+ GXMAP(type, XK_bracketleft, GHOST_kKeyLeftBracket);
+ GXMAP(type, XK_bracketright, GHOST_kKeyRightBracket);
+ GXMAP(type, XK_Pause, GHOST_kKeyPause);
+
+ GXMAP(type, XK_Shift_L, GHOST_kKeyLeftShift);
+ GXMAP(type, XK_Shift_R, GHOST_kKeyRightShift);
+ GXMAP(type, XK_Control_L, GHOST_kKeyLeftControl);
+ GXMAP(type, XK_Control_R, GHOST_kKeyRightControl);
+ GXMAP(type, XK_Alt_L, GHOST_kKeyLeftAlt);
+ GXMAP(type, XK_Alt_R, GHOST_kKeyRightAlt);
+ GXMAP(type, XK_Super_L, GHOST_kKeyOS);
+ GXMAP(type, XK_Super_R, GHOST_kKeyOS);
+
+ GXMAP(type, XK_Insert, GHOST_kKeyInsert);
+ GXMAP(type, XK_Delete, GHOST_kKeyDelete);
+ GXMAP(type, XK_Home, GHOST_kKeyHome);
+ GXMAP(type, XK_End, GHOST_kKeyEnd);
+ GXMAP(type, XK_Page_Up, GHOST_kKeyUpPage);
+ GXMAP(type, XK_Page_Down, GHOST_kKeyDownPage);
+
+ GXMAP(type, XK_Left, GHOST_kKeyLeftArrow);
+ GXMAP(type, XK_Right, GHOST_kKeyRightArrow);
+ GXMAP(type, XK_Up, GHOST_kKeyUpArrow);
+ GXMAP(type, XK_Down, GHOST_kKeyDownArrow);
+
+ GXMAP(type, XK_Caps_Lock, GHOST_kKeyCapsLock);
+ GXMAP(type, XK_Scroll_Lock, GHOST_kKeyScrollLock);
+ GXMAP(type, XK_Num_Lock, GHOST_kKeyNumLock);
+
+ /* keypad events */
+
+ GXMAP(type, XK_KP_0, GHOST_kKeyNumpad0);
+ GXMAP(type, XK_KP_1, GHOST_kKeyNumpad1);
+ GXMAP(type, XK_KP_2, GHOST_kKeyNumpad2);
+ GXMAP(type, XK_KP_3, GHOST_kKeyNumpad3);
+ GXMAP(type, XK_KP_4, GHOST_kKeyNumpad4);
+ GXMAP(type, XK_KP_5, GHOST_kKeyNumpad5);
+ GXMAP(type, XK_KP_6, GHOST_kKeyNumpad6);
+ GXMAP(type, XK_KP_7, GHOST_kKeyNumpad7);
+ GXMAP(type, XK_KP_8, GHOST_kKeyNumpad8);
+ GXMAP(type, XK_KP_9, GHOST_kKeyNumpad9);
+ GXMAP(type, XK_KP_Decimal, GHOST_kKeyNumpadPeriod);
+
+ GXMAP(type, XK_KP_Insert, GHOST_kKeyNumpad0);
+ GXMAP(type, XK_KP_End, GHOST_kKeyNumpad1);
+ GXMAP(type, XK_KP_Down, GHOST_kKeyNumpad2);
+ GXMAP(type, XK_KP_Page_Down, GHOST_kKeyNumpad3);
+ GXMAP(type, XK_KP_Left, GHOST_kKeyNumpad4);
+ GXMAP(type, XK_KP_Begin, GHOST_kKeyNumpad5);
+ GXMAP(type, XK_KP_Right, GHOST_kKeyNumpad6);
+ GXMAP(type, XK_KP_Home, GHOST_kKeyNumpad7);
+ GXMAP(type, XK_KP_Up, GHOST_kKeyNumpad8);
+ GXMAP(type, XK_KP_Page_Up, GHOST_kKeyNumpad9);
+ GXMAP(type, XK_KP_Delete, GHOST_kKeyNumpadPeriod);
+
+ GXMAP(type, XK_KP_Enter, GHOST_kKeyNumpadEnter);
+ GXMAP(type, XK_KP_Add, GHOST_kKeyNumpadPlus);
+ GXMAP(type, XK_KP_Subtract, GHOST_kKeyNumpadMinus);
+ GXMAP(type, XK_KP_Multiply, GHOST_kKeyNumpadAsterisk);
+ GXMAP(type, XK_KP_Divide, GHOST_kKeyNumpadSlash);
+
+ /* Media keys in some keyboards and laptops with XFree86/Xorg */
#ifdef WITH_XF86KEYSYM
- GXMAP(type, XF86XK_AudioPlay, GHOST_kKeyMediaPlay);
- GXMAP(type, XF86XK_AudioStop, GHOST_kKeyMediaStop);
- GXMAP(type, XF86XK_AudioPrev, GHOST_kKeyMediaFirst);
- GXMAP(type, XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
- GXMAP(type, XF86XK_AudioNext, GHOST_kKeyMediaLast);
-#ifdef XF86XK_AudioForward /* Debian lenny's XF86keysym.h has no XF86XK_AudioForward define */
- GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast);
+ GXMAP(type, XF86XK_AudioPlay, GHOST_kKeyMediaPlay);
+ GXMAP(type, XF86XK_AudioStop, GHOST_kKeyMediaStop);
+ GXMAP(type, XF86XK_AudioPrev, GHOST_kKeyMediaFirst);
+ GXMAP(type, XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
+ GXMAP(type, XF86XK_AudioNext, GHOST_kKeyMediaLast);
+# ifdef XF86XK_AudioForward /* Debian lenny's XF86keysym.h has no XF86XK_AudioForward define */
+ GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast);
+# endif
#endif
-#endif
- default:
+ default:
#ifdef GHOST_DEBUG
- printf("%s: unknown key: %lu / 0x%lx\n", __func__, key, key);
+ printf("%s: unknown key: %lu / 0x%lx\n", __func__, key, key);
#endif
- type = GHOST_kKeyUnknown;
- break;
- }
- }
+ type = GHOST_kKeyUnknown;
+ break;
+ }
+ }
- return type;
+ return type;
}
#undef GXMAP
#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
-static GHOST_TKey
-ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode)
+static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode)
{
- GHOST_ASSERT(XkbKeyNameLength == 4, "Name length is invalid!");
- if (keycode >= xkb_descr->min_key_code && keycode <= xkb_descr->max_key_code) {
- const char *id_str = xkb_descr->names->keys[keycode].name;
- const uint32_t id = MAKE_ID(id_str[0], id_str[1], id_str[2], id_str[3]);
- switch (id) {
- case MAKE_ID('T', 'L', 'D', 'E'):
- return GHOST_kKeyAccentGrave;
+ GHOST_ASSERT(XkbKeyNameLength == 4, "Name length is invalid!");
+ if (keycode >= xkb_descr->min_key_code && keycode <= xkb_descr->max_key_code) {
+ const char *id_str = xkb_descr->names->keys[keycode].name;
+ const uint32_t id = MAKE_ID(id_str[0], id_str[1], id_str[2], id_str[3]);
+ switch (id) {
+ case MAKE_ID('T', 'L', 'D', 'E'):
+ return GHOST_kKeyAccentGrave;
#ifdef GHOST_DEBUG
- default:
- printf("%s unhandled keycode: %.*s\n", __func__, XkbKeyNameLength, id_str);
- break;
+ default:
+ printf("%s unhandled keycode: %.*s\n", __func__, XkbKeyNameLength, id_str);
+ break;
#endif
- }
- }
- else if (keycode != 0) {
- GHOST_ASSERT(false, "KeyCode out of range!");
- }
- return GHOST_kKeyUnknown;
+ }
+ }
+ else if (keycode != 0) {
+ GHOST_ASSERT(false, "KeyCode out of range!");
+ }
+ return GHOST_kKeyUnknown;
}
#undef MAKE_ID
/* from xclip.c xcout() v0.11 */
-#define XCLIB_XCOUT_NONE 0 /* no context */
-#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */
-#define XCLIB_XCOUT_INCR 2 /* in an incr loop */
-#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */
-#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */
-#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */
-#define XCLIB_XCOUT_FALLBACK_TEXT 6
+#define XCLIB_XCOUT_NONE 0 /* no context */
+#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */
+#define XCLIB_XCOUT_INCR 2 /* in an incr loop */
+#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */
+#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */
+#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */
+#define XCLIB_XCOUT_FALLBACK_TEXT 6
/* Retrieves the contents of a selections. */
void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
- Atom sel, Atom target, unsigned char **txt,
- unsigned long *len, unsigned int *context) const
+ Atom sel,
+ Atom target,
+ unsigned char **txt,
+ unsigned long *len,
+ unsigned int *context) const
{
- Atom pty_type;
- int pty_format;
- unsigned char *buffer;
- unsigned long pty_size, pty_items;
- unsigned char *ltxt = *txt;
-
- vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
- vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
- GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
- Window win = window->getXWindow();
-
- switch (*context) {
- /* There is no context, do an XConvertSelection() */
- case XCLIB_XCOUT_NONE:
- /* Initialise return length to 0 */
- if (*len > 0) {
- free(*txt);
- *len = 0;
- }
-
- /* Send a selection request */
- XConvertSelection(m_display, sel, target, m_atom.XCLIP_OUT, win, CurrentTime);
- *context = XCLIB_XCOUT_SENTCONVSEL;
- return;
-
- case XCLIB_XCOUT_SENTCONVSEL:
- if (evt->type != SelectionNotify)
- return;
-
- if (target == m_atom.UTF8_STRING && evt->xselection.property == None) {
- *context = XCLIB_XCOUT_FALLBACK_UTF8;
- return;
- }
- else if (target == m_atom.COMPOUND_TEXT && evt->xselection.property == None) {
- *context = XCLIB_XCOUT_FALLBACK_COMP;
- return;
- }
- else if (target == m_atom.TEXT && evt->xselection.property == None) {
- *context = XCLIB_XCOUT_FALLBACK_TEXT;
- return;
- }
-
- /* find the size and format of the data in property */
- XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
- AnyPropertyType, &pty_type, &pty_format,
- &pty_items, &pty_size, &buffer);
- XFree(buffer);
-
- if (pty_type == m_atom.INCR) {
- /* start INCR mechanism by deleting property */
- XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
- XFlush(m_display);
- *context = XCLIB_XCOUT_INCR;
- return;
- }
-
- /* if it's not incr, and not format == 8, then there's
- * nothing in the selection (that xclip understands, anyway) */
-
- if (pty_format != 8) {
- *context = XCLIB_XCOUT_NONE;
- return;
- }
-
- // not using INCR mechanism, just read the property
- XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
- False, AnyPropertyType, &pty_type,
- &pty_format, &pty_items, &pty_size, &buffer);
-
- /* finished with property, delete it */
- XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
-
- /* copy the buffer to the pointer for returned data */
- ltxt = (unsigned char *) malloc(pty_items);
- memcpy(ltxt, buffer, pty_items);
-
- /* set the length of the returned data */
- *len = pty_items;
- *txt = ltxt;
-
- /* free the buffer */
- XFree(buffer);
-
- *context = XCLIB_XCOUT_NONE;
-
- /* complete contents of selection fetched, return 1 */
- return;
-
- case XCLIB_XCOUT_INCR:
- /* To use the INCR method, we basically delete the
- * property with the selection in it, wait for an
- * event indicating that the property has been created,
- * then read it, delete it, etc. */
-
- /* make sure that the event is relevant */
- if (evt->type != PropertyNotify)
- return;
-
- /* skip unless the property has a new value */
- if (evt->xproperty.state != PropertyNewValue)
- return;
-
- /* check size and format of the property */
- XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
- AnyPropertyType, &pty_type, &pty_format,
- &pty_items, &pty_size, &buffer);
-
- if (pty_format != 8) {
- /* property does not contain text, delete it
- * to tell the other X client that we have read
- * it and to send the next property */
- XFree(buffer);
- XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
- return;
- }
-
- if (pty_size == 0) {
- /* no more data, exit from loop */
- XFree(buffer);
- XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
- *context = XCLIB_XCOUT_NONE;
-
- /* this means that an INCR transfer is now
- * complete, return 1 */
- return;
- }
-
- XFree(buffer);
-
- /* if we have come this far, the property contains
- * text, we know the size. */
- XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
- False, AnyPropertyType, &pty_type, &pty_format,
- &pty_items, &pty_size, &buffer);
-
- /* allocate memory to accommodate data in *txt */
- if (*len == 0) {
- *len = pty_items;
- ltxt = (unsigned char *) malloc(*len);
- }
- else {
- *len += pty_items;
- ltxt = (unsigned char *) realloc(ltxt, *len);
- }
-
- /* add data to ltxt */
- memcpy(&ltxt[*len - pty_items], buffer, pty_items);
-
- *txt = ltxt;
- XFree(buffer);
-
- /* delete property to get the next item */
- XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
- XFlush(m_display);
- return;
- }
- return;
+ Atom pty_type;
+ int pty_format;
+ unsigned char *buffer;
+ unsigned long pty_size, pty_items;
+ unsigned char *ltxt = *txt;
+
+ vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
+ Window win = window->getXWindow();
+
+ switch (*context) {
+ /* There is no context, do an XConvertSelection() */
+ case XCLIB_XCOUT_NONE:
+ /* Initialise return length to 0 */
+ if (*len > 0) {
+ free(*txt);
+ *len = 0;
+ }
+
+ /* Send a selection request */
+ XConvertSelection(m_display, sel, target, m_atom.XCLIP_OUT, win, CurrentTime);
+ *context = XCLIB_XCOUT_SENTCONVSEL;
+ return;
+
+ case XCLIB_XCOUT_SENTCONVSEL:
+ if (evt->type != SelectionNotify)
+ return;
+
+ if (target == m_atom.UTF8_STRING && evt->xselection.property == None) {
+ *context = XCLIB_XCOUT_FALLBACK_UTF8;
+ return;
+ }
+ else if (target == m_atom.COMPOUND_TEXT && evt->xselection.property == None) {
+ *context = XCLIB_XCOUT_FALLBACK_COMP;
+ return;
+ }
+ else if (target == m_atom.TEXT && evt->xselection.property == None) {
+ *context = XCLIB_XCOUT_FALLBACK_TEXT;
+ return;
+ }
+
+ /* find the size and format of the data in property */
+ XGetWindowProperty(m_display,
+ win,
+ m_atom.XCLIP_OUT,
+ 0,
+ 0,
+ False,
+ AnyPropertyType,
+ &pty_type,
+ &pty_format,
+ &pty_items,
+ &pty_size,
+ &buffer);
+ XFree(buffer);
+
+ if (pty_type == m_atom.INCR) {
+ /* start INCR mechanism by deleting property */
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
+ XFlush(m_display);
+ *context = XCLIB_XCOUT_INCR;
+ return;
+ }
+
+ /* if it's not incr, and not format == 8, then there's
+ * nothing in the selection (that xclip understands, anyway) */
+
+ if (pty_format != 8) {
+ *context = XCLIB_XCOUT_NONE;
+ return;
+ }
+
+ // not using INCR mechanism, just read the property
+ XGetWindowProperty(m_display,
+ win,
+ m_atom.XCLIP_OUT,
+ 0,
+ (long)pty_size,
+ False,
+ AnyPropertyType,
+ &pty_type,
+ &pty_format,
+ &pty_items,
+ &pty_size,
+ &buffer);
+
+ /* finished with property, delete it */
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
+
+ /* copy the buffer to the pointer for returned data */
+ ltxt = (unsigned char *)malloc(pty_items);
+ memcpy(ltxt, buffer, pty_items);
+
+ /* set the length of the returned data */
+ *len = pty_items;
+ *txt = ltxt;
+
+ /* free the buffer */
+ XFree(buffer);
+
+ *context = XCLIB_XCOUT_NONE;
+
+ /* complete contents of selection fetched, return 1 */
+ return;
+
+ case XCLIB_XCOUT_INCR:
+ /* To use the INCR method, we basically delete the
+ * property with the selection in it, wait for an
+ * event indicating that the property has been created,
+ * then read it, delete it, etc. */
+
+ /* make sure that the event is relevant */
+ if (evt->type != PropertyNotify)
+ return;
+
+ /* skip unless the property has a new value */
+ if (evt->xproperty.state != PropertyNewValue)
+ return;
+
+ /* check size and format of the property */
+ XGetWindowProperty(m_display,
+ win,
+ m_atom.XCLIP_OUT,
+ 0,
+ 0,
+ False,
+ AnyPropertyType,
+ &pty_type,
+ &pty_format,
+ &pty_items,
+ &pty_size,
+ &buffer);
+
+ if (pty_format != 8) {
+ /* property does not contain text, delete it
+ * to tell the other X client that we have read
+ * it and to send the next property */
+ XFree(buffer);
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
+ return;
+ }
+
+ if (pty_size == 0) {
+ /* no more data, exit from loop */
+ XFree(buffer);
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
+ *context = XCLIB_XCOUT_NONE;
+
+ /* this means that an INCR transfer is now
+ * complete, return 1 */
+ return;
+ }
+
+ XFree(buffer);
+
+ /* if we have come this far, the property contains
+ * text, we know the size. */
+ XGetWindowProperty(m_display,
+ win,
+ m_atom.XCLIP_OUT,
+ 0,
+ (long)pty_size,
+ False,
+ AnyPropertyType,
+ &pty_type,
+ &pty_format,
+ &pty_items,
+ &pty_size,
+ &buffer);
+
+ /* allocate memory to accommodate data in *txt */
+ if (*len == 0) {
+ *len = pty_items;
+ ltxt = (unsigned char *)malloc(*len);
+ }
+ else {
+ *len += pty_items;
+ ltxt = (unsigned char *)realloc(ltxt, *len);
+ }
+
+ /* add data to ltxt */
+ memcpy(&ltxt[*len - pty_items], buffer, pty_items);
+
+ *txt = ltxt;
+ XFree(buffer);
+
+ /* delete property to get the next item */
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
+ XFlush(m_display);
+ return;
+ }
+ return;
}
GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
{
- Atom sseln;
- Atom target = m_atom.UTF8_STRING;
- Window owner;
-
- /* from xclip.c doOut() v0.11 */
- unsigned char *sel_buf;
- unsigned long sel_len = 0;
- XEvent evt;
- unsigned int context = XCLIB_XCOUT_NONE;
-
- if (selection == True)
- sseln = m_atom.PRIMARY;
- else
- sseln = m_atom.CLIPBOARD;
-
- vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
- vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
- GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
- Window win = window->getXWindow();
-
- /* check if we are the owner. */
- owner = XGetSelectionOwner(m_display, sseln);
- if (owner == win) {
- if (sseln == m_atom.CLIPBOARD) {
- sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1);
- strcpy((char *)sel_buf, txt_cut_buffer);
- return sel_buf;
- }
- else {
- sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1);
- strcpy((char *)sel_buf, txt_select_buffer);
- return sel_buf;
- }
- }
- else if (owner == None)
- return(NULL);
-
- while (1) {
- /* only get an event if xcout() is doing something */
- if (context != XCLIB_XCOUT_NONE)
- XNextEvent(m_display, &evt);
-
- /* fetch the selection, or part of it */
- getClipboard_xcout(&evt, sseln, target, &sel_buf, &sel_len, &context);
-
- /* fallback is needed. set XA_STRING to target and restart the loop. */
- if (context == XCLIB_XCOUT_FALLBACK) {
- context = XCLIB_XCOUT_NONE;
- target = m_atom.STRING;
- continue;
- }
- else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
- /* utf8 fail, move to compouned text. */
- context = XCLIB_XCOUT_NONE;
- target = m_atom.COMPOUND_TEXT;
- continue;
- }
- else if (context == XCLIB_XCOUT_FALLBACK_COMP) {
- /* compouned text fail, move to text. */
- context = XCLIB_XCOUT_NONE;
- target = m_atom.TEXT;
- continue;
- }
- else if (context == XCLIB_XCOUT_FALLBACK_TEXT) {
- /* text fail, nothing else to try, break. */
- context = XCLIB_XCOUT_NONE;
- }
-
- /* only continue if xcout() is doing something */
- if (context == XCLIB_XCOUT_NONE)
- break;
- }
-
- if (sel_len) {
- /* only print the buffer out, and free it, if it's not
- * empty
- */
- unsigned char *tmp_data = (unsigned char *) malloc(sel_len + 1);
- memcpy((char *)tmp_data, (char *)sel_buf, sel_len);
- tmp_data[sel_len] = '\0';
-
- if (sseln == m_atom.STRING)
- XFree(sel_buf);
- else
- free(sel_buf);
-
- return tmp_data;
- }
- return(NULL);
+ Atom sseln;
+ Atom target = m_atom.UTF8_STRING;
+ Window owner;
+
+ /* from xclip.c doOut() v0.11 */
+ unsigned char *sel_buf;
+ unsigned long sel_len = 0;
+ XEvent evt;
+ unsigned int context = XCLIB_XCOUT_NONE;
+
+ if (selection == True)
+ sseln = m_atom.PRIMARY;
+ else
+ sseln = m_atom.CLIPBOARD;
+
+ vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
+ Window win = window->getXWindow();
+
+ /* check if we are the owner. */
+ owner = XGetSelectionOwner(m_display, sseln);
+ if (owner == win) {
+ if (sseln == m_atom.CLIPBOARD) {
+ sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1);
+ strcpy((char *)sel_buf, txt_cut_buffer);
+ return sel_buf;
+ }
+ else {
+ sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1);
+ strcpy((char *)sel_buf, txt_select_buffer);
+ return sel_buf;
+ }
+ }
+ else if (owner == None)
+ return (NULL);
+
+ while (1) {
+ /* only get an event if xcout() is doing something */
+ if (context != XCLIB_XCOUT_NONE)
+ XNextEvent(m_display, &evt);
+
+ /* fetch the selection, or part of it */
+ getClipboard_xcout(&evt, sseln, target, &sel_buf, &sel_len, &context);
+
+ /* fallback is needed. set XA_STRING to target and restart the loop. */
+ if (context == XCLIB_XCOUT_FALLBACK) {
+ context = XCLIB_XCOUT_NONE;
+ target = m_atom.STRING;
+ continue;
+ }
+ else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
+ /* utf8 fail, move to compouned text. */
+ context = XCLIB_XCOUT_NONE;
+ target = m_atom.COMPOUND_TEXT;
+ continue;
+ }
+ else if (context == XCLIB_XCOUT_FALLBACK_COMP) {
+ /* compouned text fail, move to text. */
+ context = XCLIB_XCOUT_NONE;
+ target = m_atom.TEXT;
+ continue;
+ }
+ else if (context == XCLIB_XCOUT_FALLBACK_TEXT) {
+ /* text fail, nothing else to try, break. */
+ context = XCLIB_XCOUT_NONE;
+ }
+
+ /* only continue if xcout() is doing something */
+ if (context == XCLIB_XCOUT_NONE)
+ break;
+ }
+
+ if (sel_len) {
+ /* only print the buffer out, and free it, if it's not
+ * empty
+ */
+ unsigned char *tmp_data = (unsigned char *)malloc(sel_len + 1);
+ memcpy((char *)tmp_data, (char *)sel_buf, sel_len);
+ tmp_data[sel_len] = '\0';
+
+ if (sseln == m_atom.STRING)
+ XFree(sel_buf);
+ else
+ free(sel_buf);
+
+ return tmp_data;
+ }
+ return (NULL);
}
void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
{
- Window m_window, owner;
-
- vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
- vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
- GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
- m_window = window->getXWindow();
-
- if (buffer) {
- if (selection == False) {
- XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime);
- owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD);
- if (txt_cut_buffer)
- free((void *)txt_cut_buffer);
-
- txt_cut_buffer = (char *) malloc(strlen(buffer) + 1);
- strcpy(txt_cut_buffer, buffer);
- }
- else {
- XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime);
- owner = XGetSelectionOwner(m_display, m_atom.PRIMARY);
- if (txt_select_buffer)
- free((void *)txt_select_buffer);
-
- txt_select_buffer = (char *) malloc(strlen(buffer) + 1);
- strcpy(txt_select_buffer, buffer);
- }
-
- if (owner != m_window)
- fprintf(stderr, "failed to own primary\n");
- }
+ Window m_window, owner;
+
+ vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
+ m_window = window->getXWindow();
+
+ if (buffer) {
+ if (selection == False) {
+ XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime);
+ owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD);
+ if (txt_cut_buffer)
+ free((void *)txt_cut_buffer);
+
+ txt_cut_buffer = (char *)malloc(strlen(buffer) + 1);
+ strcpy(txt_cut_buffer, buffer);
+ }
+ else {
+ XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime);
+ owner = XGetSelectionOwner(m_display, m_atom.PRIMARY);
+ if (txt_select_buffer)
+ free((void *)txt_select_buffer);
+
+ txt_select_buffer = (char *)malloc(strlen(buffer) + 1);
+ strcpy(txt_select_buffer, buffer);
+ }
+
+ if (owner != m_window)
+ fprintf(stderr, "failed to own primary\n");
+ }
}
#ifdef WITH_XDND
GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
- GHOST_TDragnDropTypes draggedObjectType,
- GHOST_IWindow *window,
- int mouseX, int mouseY,
- void *data)
+ GHOST_TDragnDropTypes draggedObjectType,
+ GHOST_IWindow *window,
+ int mouseX,
+ int mouseY,
+ void *data)
{
- GHOST_SystemX11 *system = ((GHOST_SystemX11 *)getSystem());
- return system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
- eventType,
- draggedObjectType,
- window, mouseX, mouseY, data)
- );
+ GHOST_SystemX11 *system = ((GHOST_SystemX11 *)getSystem());
+ return system->pushEvent(new GHOST_EventDragnDrop(
+ system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data));
}
#endif
/**
@@ -2220,28 +2163,31 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
*/
int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *event)
{
- char error_code_str[512];
-
- XGetErrorText(display, event->error_code, error_code_str, sizeof(error_code_str));
-
- fprintf(stderr,
- "Received X11 Error:\n"
- "\terror code: %d\n"
- "\trequest code: %d\n"
- "\tminor code: %d\n"
- "\terror text: %s\n",
- event->error_code, event->request_code, event->minor_code, error_code_str);
-
- /* No exit! - but keep lint happy */
- return 0;
+ char error_code_str[512];
+
+ XGetErrorText(display, event->error_code, error_code_str, sizeof(error_code_str));
+
+ fprintf(stderr,
+ "Received X11 Error:\n"
+ "\terror code: %d\n"
+ "\trequest code: %d\n"
+ "\tminor code: %d\n"
+ "\terror text: %s\n",
+ event->error_code,
+ event->request_code,
+ event->minor_code,
+ error_code_str);
+
+ /* No exit! - but keep lint happy */
+ return 0;
}
int GHOST_X11_ApplicationIOErrorHandler(Display * /*display*/)
{
- fprintf(stderr, "Ignoring Xlib error: error IO\n");
+ fprintf(stderr, "Ignoring Xlib error: error IO\n");
- /* No exit! - but keep lint happy */
- return 0;
+ /* No exit! - but keep lint happy */
+ return 0;
}
#ifdef WITH_X11_XINPUT
@@ -2249,22 +2195,22 @@ int GHOST_X11_ApplicationIOErrorHandler(Display * /*display*/)
/* These C functions are copied from Wine 3.12's wintab.c */
static bool match_token(const char *haystack, const char *needle)
{
- const char *p, *q;
- for (p = haystack; *p; ) {
- while (*p && isspace(*p))
- p++;
- if (!*p)
- break;
-
- for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
- p++;
- if (!*q && (isspace(*p) || !*p))
- return true;
-
- while (*p && !isspace(*p))
- p++;
- }
- return false;
+ const char *p, *q;
+ for (p = haystack; *p;) {
+ while (*p && isspace(*p))
+ p++;
+ if (!*p)
+ break;
+
+ for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
+ p++;
+ if (!*q && (isspace(*p) || !*p))
+ return true;
+
+ while (*p && !isspace(*p))
+ p++;
+ }
+ return false;
}
/* Determining if an X device is a Tablet style device is an imperfect science.
@@ -2279,130 +2225,118 @@ static bool match_token(const char *haystack, const char *needle)
*/
static GHOST_TTabletMode tablet_mode_from_name(const char *name, const char *type)
{
- int i;
- static const char* tablet_stylus_whitelist[] = {
- "stylus",
- "wizardpen",
- "acecad",
- "pen",
- NULL
- };
-
- static const char* type_blacklist[] = {
- "pad",
- "cursor",
- "touch",
- NULL
- };
-
- /* Skip some known unsupported types. */
- for (i=0; type_blacklist[i] != NULL; i++) {
- if (type && (strcasecmp(type, type_blacklist[i]) == 0)) {
- return GHOST_kTabletModeNone;
- }
- }
-
- /* First check device type to avoid cases where name is "Pen and Eraser" and type is "ERASER" */
- for (i=0; tablet_stylus_whitelist[i] != NULL; i++) {
- if (type && match_token(type, tablet_stylus_whitelist[i])) {
- return GHOST_kTabletModeStylus;
- }
- }
- if (type && match_token(type, "eraser")) {
- return GHOST_kTabletModeEraser;
- }
- for (i=0; tablet_stylus_whitelist[i] != NULL; i++) {
- if (name && match_token(name, tablet_stylus_whitelist[i])) {
- return GHOST_kTabletModeStylus;
- }
- }
- if (name && match_token(name, "eraser")) {
- return GHOST_kTabletModeEraser;
- }
-
- return GHOST_kTabletModeNone;
+ int i;
+ static const char *tablet_stylus_whitelist[] = {"stylus", "wizardpen", "acecad", "pen", NULL};
+
+ static const char *type_blacklist[] = {"pad", "cursor", "touch", NULL};
+
+ /* Skip some known unsupported types. */
+ for (i = 0; type_blacklist[i] != NULL; i++) {
+ if (type && (strcasecmp(type, type_blacklist[i]) == 0)) {
+ return GHOST_kTabletModeNone;
+ }
+ }
+
+ /* First check device type to avoid cases where name is "Pen and Eraser" and type is "ERASER" */
+ for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
+ if (type && match_token(type, tablet_stylus_whitelist[i])) {
+ return GHOST_kTabletModeStylus;
+ }
+ }
+ if (type && match_token(type, "eraser")) {
+ return GHOST_kTabletModeEraser;
+ }
+ for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
+ if (name && match_token(name, tablet_stylus_whitelist[i])) {
+ return GHOST_kTabletModeStylus;
+ }
+ }
+ if (name && match_token(name, "eraser")) {
+ return GHOST_kTabletModeEraser;
+ }
+
+ return GHOST_kTabletModeNone;
}
/* End code copied from Wine. */
void GHOST_SystemX11::refreshXInputDevices()
{
- if (m_xinput_version.present) {
- /* Close tablet devices. */
- clearXInputDevices();
-
- /* Install our error handler to override Xlib's termination behavior */
- GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
-
- {
- int device_count;
- XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
-
-
- for (int i = 0; i < device_count; ++i) {
- char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
- GHOST_TTabletMode tablet_mode = tablet_mode_from_name(device_info[i].name, device_type);
-
-// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
-
- if (device_type) {
- XFree((void *)device_type);
- }
-
- if (!(tablet_mode == GHOST_kTabletModeStylus || tablet_mode == GHOST_kTabletModeEraser)) {
- continue;
- }
-
- GHOST_TabletX11 xtablet = {tablet_mode};
- xtablet.ID = device_info[i].id;
- xtablet.Device = XOpenDevice(m_display, xtablet.ID);
-
- if (xtablet.Device != NULL) {
- /* Find how many pressure levels tablet has */
- XAnyClassPtr ici = device_info[i].inputclassinfo;
-
- for (int j = 0; j < xtablet.Device->num_classes; ++j) {
- if (ici->c_class == ValuatorClass) {
- XValuatorInfo *xvi = (XValuatorInfo *)ici;
- xtablet.PressureLevels = xvi->axes[2].max_value;
-
- if (xvi->num_axes > 3) {
- /* this is assuming that the tablet has the same tilt resolution in both
- * positive and negative directions. It would be rather weird if it didn't.. */
- xtablet.XtiltLevels = xvi->axes[3].max_value;
- xtablet.YtiltLevels = xvi->axes[4].max_value;
- }
- else {
- xtablet.XtiltLevels = 0;
- xtablet.YtiltLevels = 0;
- }
-
- break;
- }
-
- ici = (XAnyClassPtr)(((char *)ici) + ici->length);
- }
-
- m_xtablets.push_back(xtablet);
- }
-
- }
-
- XFreeDeviceList(device_info);
- }
-
- GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
- }
+ if (m_xinput_version.present) {
+ /* Close tablet devices. */
+ clearXInputDevices();
+
+ /* Install our error handler to override Xlib's termination behavior */
+ GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
+
+ {
+ int device_count;
+ XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
+
+ for (int i = 0; i < device_count; ++i) {
+ char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) :
+ NULL;
+ GHOST_TTabletMode tablet_mode = tablet_mode_from_name(device_info[i].name, device_type);
+
+ // printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
+
+ if (device_type) {
+ XFree((void *)device_type);
+ }
+
+ if (!(tablet_mode == GHOST_kTabletModeStylus || tablet_mode == GHOST_kTabletModeEraser)) {
+ continue;
+ }
+
+ GHOST_TabletX11 xtablet = {tablet_mode};
+ xtablet.ID = device_info[i].id;
+ xtablet.Device = XOpenDevice(m_display, xtablet.ID);
+
+ if (xtablet.Device != NULL) {
+ /* Find how many pressure levels tablet has */
+ XAnyClassPtr ici = device_info[i].inputclassinfo;
+
+ for (int j = 0; j < xtablet.Device->num_classes; ++j) {
+ if (ici->c_class == ValuatorClass) {
+ XValuatorInfo *xvi = (XValuatorInfo *)ici;
+ xtablet.PressureLevels = xvi->axes[2].max_value;
+
+ if (xvi->num_axes > 3) {
+ /* this is assuming that the tablet has the same tilt resolution in both
+ * positive and negative directions. It would be rather weird if it didn't.. */
+ xtablet.XtiltLevels = xvi->axes[3].max_value;
+ xtablet.YtiltLevels = xvi->axes[4].max_value;
+ }
+ else {
+ xtablet.XtiltLevels = 0;
+ xtablet.YtiltLevels = 0;
+ }
+
+ break;
+ }
+
+ ici = (XAnyClassPtr)(((char *)ici) + ici->length);
+ }
+
+ m_xtablets.push_back(xtablet);
+ }
+ }
+
+ XFreeDeviceList(device_info);
+ }
+
+ GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
+ }
}
void GHOST_SystemX11::clearXInputDevices()
{
- for (GHOST_TabletX11& xtablet: m_xtablets) {
- if (xtablet.Device)
- XCloseDevice(m_display, xtablet.Device);
- }
+ for (GHOST_TabletX11 &xtablet : m_xtablets) {
+ if (xtablet.Device)
+ XCloseDevice(m_display, xtablet.Device);
+ }
- m_xtablets.clear();
+ m_xtablets.clear();
}
#endif /* WITH_X11_XINPUT */
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index e415757d925..d73582b52fa 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -43,7 +43,7 @@
#endif
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
-# define GHOST_X11_RES_NAME "Blender" /* res_name */
+# define GHOST_X11_RES_NAME "Blender" /* res_name */
# define GHOST_X11_RES_CLASS "Blender" /* res_class */
#endif
@@ -52,19 +52,20 @@ int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent);
int GHOST_X11_ApplicationIOErrorHandler(Display *display);
#define GHOST_X11_ERROR_HANDLERS_OVERRIDE(var) \
- struct { \
- XErrorHandler handler; \
- XIOErrorHandler handler_io; \
- } var = { \
- XSetErrorHandler(GHOST_X11_ApplicationErrorHandler), \
- XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler), \
- }
+ struct { \
+ XErrorHandler handler; \
+ XIOErrorHandler handler_io; \
+ } var = { \
+ XSetErrorHandler(GHOST_X11_ApplicationErrorHandler), \
+ XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler), \
+ }
#define GHOST_X11_ERROR_HANDLERS_RESTORE(var) \
- { \
- (void)XSetErrorHandler(var.handler); \
- (void)XSetIOErrorHandler(var.handler_io); \
- } ((void)0)
+ { \
+ (void)XSetErrorHandler(var.handler); \
+ (void)XSetIOErrorHandler(var.handler_io); \
+ } \
+ ((void)0)
class GHOST_WindowX11;
@@ -74,358 +75,305 @@ class GHOST_WindowX11;
*/
class GHOST_SystemX11 : public GHOST_System {
-public:
-
- /**
- * Constructor
- * this class should only be instanciated by GHOST_ISystem.
- */
-
- GHOST_SystemX11(
- );
-
- /**
- * Destructor.
- */
- ~GHOST_SystemX11();
-
-
- GHOST_TSuccess
- init(
- );
-
- /**
- * Informs if the system provides native dialogs (eg. confirm quit)
- */
- virtual bool supportsNativeDialogs(void);
-
- /**
- * \section Interface Inherited from GHOST_ISystem
- */
-
- /**
- * Returns the system time.
- * Returns the number of milliseconds since the start of the system process.
- * \return The number of milliseconds.
- */
- GHOST_TUns64
- getMilliSeconds(
- ) const;
-
-
- /**
- * Returns the number of displays on this system.
- * \return The number of displays.
- */
- GHOST_TUns8
- getNumDisplays(
- ) const;
-
- /**
- * Returns the dimensions of the main display on this system.
- * \return The dimension of the main display.
- */
- void
- getMainDisplayDimensions(
- GHOST_TUns32& width,
- GHOST_TUns32& height
- ) const;
-
- /**
- * Returns the dimensions of all displays on this system.
- * \return The dimension of the main display.
- */
- void
- getAllDisplayDimensions(
- GHOST_TUns32& width,
- GHOST_TUns32& height
- ) const;
-
- /**
- * Create a new window.
- * The new window is added to the list of windows managed.
- * Never explicitly delete the window, use disposeWindow() instead.
- * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
- * \param left The coordinate of the left edge of the window.
- * \param top The coordinate of the top edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state of the window when opened.
- * \param type The type of drawing context installed in this window.
- * \param stereoVisual Create a stereo visual for quad buffered stereo.
- * \param exclusive Use to show the window ontop and ignore others
- * (used fullscreen).
- * \param parentWindow Parent (embedder) window
- * \return The new window (or 0 if creation failed).
- */
- GHOST_IWindow *
- createWindow(
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings,
- const bool exclusive = false,
- const GHOST_TEmbedderWindowID parentWindow = 0
- );
-
-
- /**
- * Create a new offscreen context.
- * Never explicitly delete the context, use disposeContext() instead.
- * \return The new context (or 0 if creation failed).
- */
- GHOST_IContext *
- createOffscreenContext(
- );
-
- /**
- * Dispose of a context.
- * \param context Pointer to the context to be disposed.
- * \return Indication of success.
- */
- GHOST_TSuccess
- disposeContext(
- GHOST_IContext *context
- );
-
- /**
- * Retrieves events from the system and stores them in the queue.
- * \param waitForEvent Flag to wait for an event (or return immediately).
- * \return Indication of the presence of events.
- */
- bool
- processEvents(
- bool waitForEvent
- );
-
- GHOST_TSuccess
- getCursorPosition(
- GHOST_TInt32& x,
- GHOST_TInt32& y
- ) const;
-
- GHOST_TSuccess
- setCursorPosition(
- GHOST_TInt32 x,
- GHOST_TInt32 y
- );
-
- /**
- * Returns the state of all modifier keys.
- * \param keys The state of all modifier keys (true == pressed).
- * \return Indication of success.
- */
- GHOST_TSuccess
- getModifierKeys(
- GHOST_ModifierKeys& keys
- ) const;
-
- /**
- * Returns the state of the mouse buttons (ouside the message queue).
- * \param buttons The state of the buttons.
- * \return Indication of success.
- */
- GHOST_TSuccess
- getButtons(
- GHOST_Buttons& buttons
- ) const;
-
- /**
- * Flag a window as dirty. This will
- * generate a GHOST window update event on a call to processEvents()
- */
-
- void
- addDirtyWindow(
- GHOST_WindowX11 *bad_wind
- );
-
-
- /**
- * return a pointer to the X11 display structure
- */
-
- Display *
- getXDisplay(
- ) {
- return m_display;
- }
+ public:
+ /**
+ * Constructor
+ * this class should only be instanciated by GHOST_ISystem.
+ */
+
+ GHOST_SystemX11();
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_SystemX11();
+
+ GHOST_TSuccess init();
+
+ /**
+ * Informs if the system provides native dialogs (eg. confirm quit)
+ */
+ virtual bool supportsNativeDialogs(void);
+
+ /**
+ * \section Interface Inherited from GHOST_ISystem
+ */
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * \return The number of milliseconds.
+ */
+ GHOST_TUns64 getMilliSeconds() const;
+
+ /**
+ * Returns the number of displays on this system.
+ * \return The number of displays.
+ */
+ GHOST_TUns8 getNumDisplays() const;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * \return The dimension of the main display.
+ */
+ void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
+
+ /**
+ * Returns the dimensions of all displays on this system.
+ * \return The dimension of the main display.
+ */
+ void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * \param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * \param left The coordinate of the left edge of the window.
+ * \param top The coordinate of the top edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state of the window when opened.
+ * \param type The type of drawing context installed in this window.
+ * \param stereoVisual Create a stereo visual for quad buffered stereo.
+ * \param exclusive Use to show the window ontop and ignore others
+ * (used fullscreen).
+ * \param parentWindow Parent (embedder) window
+ * \return The new window (or 0 if creation failed).
+ */
+ GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive = false,
+ const GHOST_TEmbedderWindowID parentWindow = 0);
+
+ /**
+ * Create a new offscreen context.
+ * Never explicitly delete the context, use disposeContext() instead.
+ * \return The new context (or 0 if creation failed).
+ */
+ GHOST_IContext *createOffscreenContext();
+
+ /**
+ * Dispose of a context.
+ * \param context Pointer to the context to be disposed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess disposeContext(GHOST_IContext *context);
+
+ /**
+ * Retrieves events from the system and stores them in the queue.
+ * \param waitForEvent Flag to wait for an event (or return immediately).
+ * \return Indication of the presence of events.
+ */
+ bool processEvents(bool waitForEvent);
+
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
+
+ /**
+ * Returns the state of all modifier keys.
+ * \param keys The state of all modifier keys (true == pressed).
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * \param buttons The state of the buttons.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
+
+ /**
+ * Flag a window as dirty. This will
+ * generate a GHOST window update event on a call to processEvents()
+ */
+
+ void addDirtyWindow(GHOST_WindowX11 *bad_wind);
+
+ /**
+ * return a pointer to the X11 display structure
+ */
+
+ Display *getXDisplay()
+ {
+ return m_display;
+ }
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- XIM
- getX11_XIM()
- {
- return m_xim;
- }
+ XIM getX11_XIM()
+ {
+ return m_xim;
+ }
#endif
- /* Helped function for get data from the clipboard. */
- void getClipboard_xcout(const XEvent *evt, Atom sel, Atom target,
- unsigned char **txt, unsigned long *len,
- unsigned int *context) const;
-
- /**
- * Returns unsigned char from CUT_BUFFER0
- * \param selection Get selection, X11 only feature
- * \return Returns the Clipboard indicated by Flag
- */
- GHOST_TUns8 *getClipboard(bool selection) const;
-
- /**
- * Puts buffer to system clipboard
- * \param buffer The buffer to copy to the clipboard
- * \param selection Set the selection into the clipboard, X11 only feature
- */
- void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+ /* Helped function for get data from the clipboard. */
+ void getClipboard_xcout(const XEvent *evt,
+ Atom sel,
+ Atom target,
+ unsigned char **txt,
+ unsigned long *len,
+ unsigned int *context) const;
+
+ /**
+ * Returns unsigned char from CUT_BUFFER0
+ * \param selection Get selection, X11 only feature
+ * \return Returns the Clipboard indicated by Flag
+ */
+ GHOST_TUns8 *getClipboard(bool selection) const;
+
+ /**
+ * Puts buffer to system clipboard
+ * \param buffer The buffer to copy to the clipboard
+ * \param selection Set the selection into the clipboard, X11 only feature
+ */
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
#ifdef WITH_XDND
- /**
- * Creates a drag'n'drop event and pushes it immediately onto the event queue.
- * Called by GHOST_DropTargetX11 class.
- * \param eventType The type of drag'n'drop event
- * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
- * \param mouseX x mouse coordinate (in window coordinates)
- * \param mouseY y mouse coordinate
- * \param window The window on which the event occurred
- * \return Indication whether the event was handled.
- */
- static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_IWindow *window, int mouseX, int mouseY, void *data);
+ /**
+ * Creates a drag'n'drop event and pushes it immediately onto the event queue.
+ * Called by GHOST_DropTargetX11 class.
+ * \param eventType The type of drag'n'drop event
+ * \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
+ * \param mouseX x mouse coordinate (in window coordinates)
+ * \param mouseY y mouse coordinate
+ * \param window The window on which the event occurred
+ * \return Indication whether the event was handled.
+ */
+ static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType,
+ GHOST_TDragnDropTypes draggedObjectType,
+ GHOST_IWindow *window,
+ int mouseX,
+ int mouseY,
+ void *data);
#endif
- /**
- * \see GHOST_ISystem
- */
- int toggleConsole(int /*action*/) {
- return 0;
- }
+ /**
+ * \see GHOST_ISystem
+ */
+ int toggleConsole(int /*action*/)
+ {
+ return 0;
+ }
#ifdef WITH_X11_XINPUT
- typedef struct GHOST_TabletX11 {
- GHOST_TTabletMode mode;
- XDevice *Device;
- XID ID;
-
- int MotionEvent;
- int ProxInEvent;
- int ProxOutEvent;
- int PressEvent;
-
- int PressureLevels;
- int XtiltLevels, YtiltLevels;
- } GHOST_TabletX11;
-
- std::vector<GHOST_TabletX11> &GetXTablets()
- {
- return m_xtablets;
- }
-#endif // WITH_X11_XINPUT
-
- struct {
- /**
- * Atom used for ICCCM, WM-spec and Motif.
- * We only need get this atom at the start, it's relative
- * to the display not the window and are public for every
- * window that need it.
- */
- Atom WM_STATE;
- Atom WM_CHANGE_STATE;
- Atom _NET_WM_STATE;
- Atom _NET_WM_STATE_MAXIMIZED_HORZ;
- Atom _NET_WM_STATE_MAXIMIZED_VERT;
- Atom _NET_WM_STATE_FULLSCREEN;
- Atom _MOTIF_WM_HINTS;
- Atom WM_TAKE_FOCUS;
- Atom WM_PROTOCOLS;
- Atom WM_DELETE_WINDOW;
-
- /* Atoms for Selection, copy & paste. */
- Atom TARGETS;
- Atom STRING;
- Atom COMPOUND_TEXT;
- Atom TEXT;
- Atom CLIPBOARD;
- Atom PRIMARY;
- Atom XCLIP_OUT;
- Atom INCR;
- Atom UTF8_STRING;
+ typedef struct GHOST_TabletX11 {
+ GHOST_TTabletMode mode;
+ XDevice *Device;
+ XID ID;
+
+ int MotionEvent;
+ int ProxInEvent;
+ int ProxOutEvent;
+ int PressEvent;
+
+ int PressureLevels;
+ int XtiltLevels, YtiltLevels;
+ } GHOST_TabletX11;
+
+ std::vector<GHOST_TabletX11> &GetXTablets()
+ {
+ return m_xtablets;
+ }
+#endif // WITH_X11_XINPUT
+
+ struct {
+ /**
+ * Atom used for ICCCM, WM-spec and Motif.
+ * We only need get this atom at the start, it's relative
+ * to the display not the window and are public for every
+ * window that need it.
+ */
+ Atom WM_STATE;
+ Atom WM_CHANGE_STATE;
+ Atom _NET_WM_STATE;
+ Atom _NET_WM_STATE_MAXIMIZED_HORZ;
+ Atom _NET_WM_STATE_MAXIMIZED_VERT;
+ Atom _NET_WM_STATE_FULLSCREEN;
+ Atom _MOTIF_WM_HINTS;
+ Atom WM_TAKE_FOCUS;
+ Atom WM_PROTOCOLS;
+ Atom WM_DELETE_WINDOW;
+
+ /* Atoms for Selection, copy & paste. */
+ Atom TARGETS;
+ Atom STRING;
+ Atom COMPOUND_TEXT;
+ Atom TEXT;
+ Atom CLIPBOARD;
+ Atom PRIMARY;
+ Atom XCLIP_OUT;
+ Atom INCR;
+ Atom UTF8_STRING;
#ifdef WITH_X11_XINPUT
- Atom TABLET;
+ Atom TABLET;
#endif
- } m_atom;
+ } m_atom;
#ifdef WITH_X11_XINPUT
- XExtensionVersion m_xinput_version;
+ XExtensionVersion m_xinput_version;
#endif
-private:
+ private:
+ Display *m_display;
- Display *m_display;
-
- /* Use for scancode lookups. */
- XkbDescRec *m_xkb_descr;
+ /* Use for scancode lookups. */
+ XkbDescRec *m_xkb_descr;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- XIM m_xim;
+ XIM m_xim;
#endif
#ifdef WITH_X11_XINPUT
- /* Tablet devices */
- std::vector<GHOST_TabletX11> m_xtablets;
+ /* Tablet devices */
+ std::vector<GHOST_TabletX11> m_xtablets;
#endif
- /// The vector of windows that need to be updated.
- std::vector<GHOST_WindowX11 *> m_dirty_windows;
+ /// The vector of windows that need to be updated.
+ std::vector<GHOST_WindowX11 *> m_dirty_windows;
- /// Start time at initialization.
- GHOST_TUns64 m_start_time;
+ /// Start time at initialization.
+ GHOST_TUns64 m_start_time;
- /// A vector of keyboard key masks
- char m_keyboard_vector[32];
+ /// A vector of keyboard key masks
+ char m_keyboard_vector[32];
- /* to prevent multiple warp, we store the time of the last warp event
- * and stop accumulating all events generated before that */
- Time m_last_warp;
+ /* to prevent multiple warp, we store the time of the last warp event
+ * and stop accumulating all events generated before that */
+ Time m_last_warp;
- /* detect autorepeat glitch */
- unsigned int m_last_release_keycode;
- Time m_last_release_time;
+ /* detect autorepeat glitch */
+ unsigned int m_last_release_keycode;
+ Time m_last_release_time;
- /**
- * Return the ghost window associated with the
- * X11 window xwind
- */
+ /**
+ * Return the ghost window associated with the
+ * X11 window xwind
+ */
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- bool openX11_IM();
+ bool openX11_IM();
#endif
#ifdef WITH_X11_XINPUT
- void clearXInputDevices();
- void refreshXInputDevices();
+ void clearXInputDevices();
+ void refreshXInputDevices();
#endif
- GHOST_WindowX11 *
- findGhostWindow(
- Window xwind
- ) const;
+ GHOST_WindowX11 *findGhostWindow(Window xwind) const;
- void
- processEvent(
- XEvent *xe
- );
+ void processEvent(XEvent *xe);
- Time
- lastEventTime(
- Time default_time
- );
+ Time lastEventTime(Time default_time);
- bool
- generateWindowExposeEvents(
- );
+ bool generateWindowExposeEvents();
};
#endif
diff --git a/intern/ghost/intern/GHOST_TaskbarWin32.h b/intern/ghost/intern/GHOST_TaskbarWin32.h
index 670272b30cd..b1b81337494 100644
--- a/intern/ghost/intern/GHOST_TaskbarWin32.h
+++ b/intern/ghost/intern/GHOST_TaskbarWin32.h
@@ -21,8 +21,8 @@
#define __GHOST_TASKBARWIN32_H__
#ifndef WIN32
-#error WIN32 only!
-#endif // WIN32
+# error WIN32 only!
+#endif // WIN32
/* require Windows XP or newer */
#undef _WIN32_WINNT
@@ -32,99 +32,105 @@
#include <windows.h>
#include <shlobj.h>
-
// ITaskbarList, ITaskbarList2 and ITaskbarList3 might be missing, present here in that case.
// Note, ITaskbarList3 is supported only since Windows 7, though. Check for that is done in
// GHOST_WindowWin32
#ifndef __ITaskbarList_INTERFACE_DEFINED__
-#define __ITaskbarList_INTERFACE_DEFINED__
+# define __ITaskbarList_INTERFACE_DEFINED__
extern "C" {
- const GUID CLSID_TaskbarList = {0x56FDF344, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};
- const GUID IID_ITaskbarList = {0x56FDF342, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};
+const GUID CLSID_TaskbarList = {
+ 0x56FDF344, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};
+const GUID IID_ITaskbarList = {
+ 0x56FDF342, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};
}
-class ITaskbarList : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE HrInit(void) = 0;
- virtual HRESULT STDMETHODCALLTYPE AddTab(HWND hwnd) = 0;
- virtual HRESULT STDMETHODCALLTYPE DeleteTab(HWND hwnd) = 0;
- virtual HRESULT STDMETHODCALLTYPE ActivateTab(HWND hwnd) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetActiveAlt(HWND hwnd) = 0;
+class ITaskbarList : public IUnknown {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE HrInit(void) = 0;
+ virtual HRESULT STDMETHODCALLTYPE AddTab(HWND hwnd) = 0;
+ virtual HRESULT STDMETHODCALLTYPE DeleteTab(HWND hwnd) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ActivateTab(HWND hwnd) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetActiveAlt(HWND hwnd) = 0;
};
-#endif /* ITaskbarList */
+#endif /* ITaskbarList */
#ifndef __ITaskbarList2_INTERFACE_DEFINED__
-#define __ITaskbarList2_INTERFACE_DEFINED__
+# define __ITaskbarList2_INTERFACE_DEFINED__
extern "C" {
- const GUID IID_ITaskbarList2 = {0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}};
+const GUID IID_ITaskbarList2 = {
+ 0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}};
}
-class ITaskbarList2 : public ITaskbarList
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0;
+class ITaskbarList2 : public ITaskbarList {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0;
};
-#endif /* ITaskbarList2 */
+#endif /* ITaskbarList2 */
#ifndef __ITaskbarList3_INTERFACE_DEFINED__
-#define __ITaskbarList3_INTERFACE_DEFINED__
+# define __ITaskbarList3_INTERFACE_DEFINED__
typedef enum THUMBBUTTONFLAGS {
- THBF_ENABLED = 0,
- THBF_DISABLED = 0x1,
- THBF_DISMISSONCLICK = 0x2,
- THBF_NOBACKGROUND = 0x4,
- THBF_HIDDEN = 0x8,
- THBF_NONINTERACTIVE = 0x10,
-}
-THUMBBUTTONFLAGS;
+ THBF_ENABLED = 0,
+ THBF_DISABLED = 0x1,
+ THBF_DISMISSONCLICK = 0x2,
+ THBF_NOBACKGROUND = 0x4,
+ THBF_HIDDEN = 0x8,
+ THBF_NONINTERACTIVE = 0x10,
+} THUMBBUTTONFLAGS;
typedef enum THUMBBUTTONMASK {
- THB_BITMAP = 0x1,
- THB_ICON = 0x2,
- THB_TOOLTIP = 0x4,
- THB_FLAGS = 0x8,
-}
-THUMBBUTTONMASK;
+ THB_BITMAP = 0x1,
+ THB_ICON = 0x2,
+ THB_TOOLTIP = 0x4,
+ THB_FLAGS = 0x8,
+} THUMBBUTTONMASK;
typedef struct THUMBBUTTON {
- THUMBBUTTONMASK dwMask;
- UINT iId;
- UINT iBitmap;
- HICON hIcon;
- WCHAR szTip[260];
- THUMBBUTTONFLAGS dwFlags;
+ THUMBBUTTONMASK dwMask;
+ UINT iId;
+ UINT iBitmap;
+ HICON hIcon;
+ WCHAR szTip[260];
+ THUMBBUTTONFLAGS dwFlags;
} THUMBBUTTON;
typedef enum TBPFLAG {
- TBPF_NOPROGRESS = 0,
- TBPF_INDETERMINATE = 0x1,
- TBPF_NORMAL = 0x2,
- TBPF_ERROR = 0x4,
- TBPF_PAUSED = 0x8,
+ TBPF_NOPROGRESS = 0,
+ TBPF_INDETERMINATE = 0x1,
+ TBPF_NORMAL = 0x2,
+ TBPF_ERROR = 0x4,
+ TBPF_PAUSED = 0x8,
} TBPFLAG;
-#define THBN_CLICKED 0x1800
+# define THBN_CLICKED 0x1800
extern "C" {
- const GUID IID_ITaskList3 = {0xEA1AFB91, 0x9E28, 0x4B86, {0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF}};
+const GUID IID_ITaskList3 = {
+ 0xEA1AFB91, 0x9E28, 0x4B86, {0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF}};
}
-class ITaskbarList3 : public ITaskbarList2
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags) = 0;
- virtual HRESULT STDMETHODCALLTYPE RegisterTab(HWND hwndTab, HWND hwndMDI) = 0;
- virtual HRESULT STDMETHODCALLTYPE UnregisterTab(HWND hwndTab) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetTabOrder(HWND hwndTab, HWND hwndInsertBefore) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetTabActive(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0;
- virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(HWND hwnd, UINT cButtons, THUMBBUTTON *pButton) = 0;
- virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(HWND hwnd, UINT cButtons, THUMBBUTTON *pButton) = 0;
- virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(HWND hwnd, HIMAGELIST himl) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(HWND hwnd, LPCWSTR pszTip) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT *prcClip) = 0;
+class ITaskbarList3 : public ITaskbarList2 {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd,
+ ULONGLONG ullCompleted,
+ ULONGLONG ullTotal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags) = 0;
+ virtual HRESULT STDMETHODCALLTYPE RegisterTab(HWND hwndTab, HWND hwndMDI) = 0;
+ virtual HRESULT STDMETHODCALLTYPE UnregisterTab(HWND hwndTab) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetTabOrder(HWND hwndTab, HWND hwndInsertBefore) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetTabActive(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(HWND hwnd,
+ UINT cButtons,
+ THUMBBUTTON *pButton) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(HWND hwnd,
+ UINT cButtons,
+ THUMBBUTTON *pButton) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(HWND hwnd, HIMAGELIST himl) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(HWND hwnd,
+ HICON hIcon,
+ LPCWSTR pszDescription) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(HWND hwnd, LPCWSTR pszTip) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT *prcClip) = 0;
};
-#endif /* ITaskbarList3 */
+#endif /* ITaskbarList3 */
#endif /*__GHOST_TASKBARWIN32_H__*/
diff --git a/intern/ghost/intern/GHOST_TaskbarX11.cpp b/intern/ghost/intern/GHOST_TaskbarX11.cpp
index fbf51605bf0..e33c84fe4d8 100644
--- a/intern/ghost/intern/GHOST_TaskbarX11.cpp
+++ b/intern/ghost/intern/GHOST_TaskbarX11.cpp
@@ -25,10 +25,10 @@
#include <cassert>
#include <cstdlib>
-typedef void*(*unity_get_entry_t)(const char*);
-typedef void(*unity_set_progress_t)(void*, double);
-typedef void(*unity_set_progress_visible_t)(void*, int);
-typedef int(*unity_event_loop_t)(void*, int);
+typedef void *(*unity_get_entry_t)(const char *);
+typedef void (*unity_set_progress_t)(void *, double);
+typedef void (*unity_set_progress_visible_t)(void *, int);
+typedef int (*unity_event_loop_t)(void *, int);
static unity_get_entry_t unity_get_entry;
static unity_set_progress_t unity_set_progress;
@@ -41,83 +41,87 @@ static void *libunity_handle = NULL;
void GHOST_TaskBarX11::free()
{
- if(libunity_handle) {
- dlclose(libunity_handle);
- libunity_handle = NULL;
- }
+ if (libunity_handle) {
+ dlclose(libunity_handle);
+ libunity_handle = NULL;
+ }
}
bool GHOST_TaskBarX11::init()
{
- if(libunity_initialized) {
- return libunity_available;
- }
-
- libunity_initialized = true;
-
- const char *libunity_names[] = {"libunity.so.4", "libunity.so.6", "libunity.so.9", "libunity.so", NULL};
- for(int i = 0; libunity_names[i]; i++) {
- libunity_handle = dlopen(libunity_names[i], RTLD_LAZY);
- if(libunity_handle) {
- break;
- }
- }
-
- if(!libunity_handle) {
- return false;
- }
-
- unity_get_entry = (unity_get_entry_t) dlsym(libunity_handle, "unity_launcher_entry_get_for_desktop_id");
- if(!unity_get_entry) {
- fprintf(stderr, "failed to load libunity: %s\n", dlerror());
- return false;
- }
- unity_set_progress = (unity_set_progress_t) dlsym(libunity_handle, "unity_launcher_entry_set_progress");
- if(!unity_set_progress) {
- fprintf(stderr, "failed to load libunity: %s\n", dlerror());
- return false;
- }
- unity_set_progress_visible = (unity_set_progress_visible_t) dlsym(libunity_handle, "unity_launcher_entry_set_progress_visible");
- if(!unity_set_progress_visible) {
- fprintf(stderr, "failed to load libunity: %s\n", dlerror());
- return false;
- }
- unity_event_loop = (unity_event_loop_t) dlsym(libunity_handle, "g_main_context_iteration");
- if(!unity_event_loop) {
- fprintf(stderr, "failed to load libunity: %s\n", dlerror());
- return false;
- }
-
- atexit(GHOST_TaskBarX11::free);
-
- libunity_available = true;
- return true;
+ if (libunity_initialized) {
+ return libunity_available;
+ }
+
+ libunity_initialized = true;
+
+ const char *libunity_names[] = {
+ "libunity.so.4", "libunity.so.6", "libunity.so.9", "libunity.so", NULL};
+ for (int i = 0; libunity_names[i]; i++) {
+ libunity_handle = dlopen(libunity_names[i], RTLD_LAZY);
+ if (libunity_handle) {
+ break;
+ }
+ }
+
+ if (!libunity_handle) {
+ return false;
+ }
+
+ unity_get_entry = (unity_get_entry_t)dlsym(libunity_handle,
+ "unity_launcher_entry_get_for_desktop_id");
+ if (!unity_get_entry) {
+ fprintf(stderr, "failed to load libunity: %s\n", dlerror());
+ return false;
+ }
+ unity_set_progress = (unity_set_progress_t)dlsym(libunity_handle,
+ "unity_launcher_entry_set_progress");
+ if (!unity_set_progress) {
+ fprintf(stderr, "failed to load libunity: %s\n", dlerror());
+ return false;
+ }
+ unity_set_progress_visible = (unity_set_progress_visible_t)dlsym(
+ libunity_handle, "unity_launcher_entry_set_progress_visible");
+ if (!unity_set_progress_visible) {
+ fprintf(stderr, "failed to load libunity: %s\n", dlerror());
+ return false;
+ }
+ unity_event_loop = (unity_event_loop_t)dlsym(libunity_handle, "g_main_context_iteration");
+ if (!unity_event_loop) {
+ fprintf(stderr, "failed to load libunity: %s\n", dlerror());
+ return false;
+ }
+
+ atexit(GHOST_TaskBarX11::free);
+
+ libunity_available = true;
+ return true;
}
GHOST_TaskBarX11::GHOST_TaskBarX11(const char *name)
{
- if(GHOST_TaskBarX11::init()) {
- handle = unity_get_entry(name);
- }
- else {
- handle = NULL;
- }
+ if (GHOST_TaskBarX11::init()) {
+ handle = unity_get_entry(name);
+ }
+ else {
+ handle = NULL;
+ }
}
bool GHOST_TaskBarX11::is_valid()
{
- return (handle != NULL);
+ return (handle != NULL);
}
void GHOST_TaskBarX11::set_progress(double progress)
{
- assert(is_valid());
- unity_set_progress(handle, progress);
+ assert(is_valid());
+ unity_set_progress(handle, progress);
}
void GHOST_TaskBarX11::set_progress_enabled(bool enabled)
{
- assert(is_valid());
- unity_set_progress_visible(handle, enabled ? 1 : 0);
- unity_event_loop(NULL, 0);
+ assert(is_valid());
+ unity_set_progress_visible(handle, enabled ? 1 : 0);
+ unity_event_loop(NULL, 0);
}
diff --git a/intern/ghost/intern/GHOST_TaskbarX11.h b/intern/ghost/intern/GHOST_TaskbarX11.h
index 65043635762..cd00e25106c 100644
--- a/intern/ghost/intern/GHOST_TaskbarX11.h
+++ b/intern/ghost/intern/GHOST_TaskbarX11.h
@@ -20,19 +20,19 @@
#ifndef __GHOST_TASKBARX11_H__
#define __GHOST_TASKBARX11_H__
-class GHOST_TaskBarX11
-{
-public:
- static bool init();
- static void free();
+class GHOST_TaskBarX11 {
+ public:
+ static bool init();
+ static void free();
- GHOST_TaskBarX11(const char *name);
+ GHOST_TaskBarX11(const char *name);
- bool is_valid();
- void set_progress(double progress);
- void set_progress_enabled(bool enabled);
-private:
- void *handle;
+ bool is_valid();
+ void set_progress(double progress);
+ void set_progress_enabled(bool enabled);
+
+ private:
+ void *handle;
};
#endif /*__GHOST_TASKBARX11_H__*/
diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp
index f1d0d13e5ba..22f646320ce 100644
--- a/intern/ghost/intern/GHOST_TimerManager.cpp
+++ b/intern/ghost/intern/GHOST_TimerManager.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
@@ -32,121 +31,113 @@
#include "GHOST_TimerTask.h"
-
GHOST_TimerManager::GHOST_TimerManager()
{
}
-
GHOST_TimerManager::~GHOST_TimerManager()
{
- disposeTimers();
+ disposeTimers();
}
-
GHOST_TUns32 GHOST_TimerManager::getNumTimers()
{
- return (GHOST_TUns32)m_timers.size();
+ return (GHOST_TUns32)m_timers.size();
}
-
bool GHOST_TimerManager::getTimerFound(GHOST_TimerTask *timer)
{
- TTimerVector::const_iterator iter = std::find(m_timers.begin(), m_timers.end(), timer);
- return iter != m_timers.end();
+ TTimerVector::const_iterator iter = std::find(m_timers.begin(), m_timers.end(), timer);
+ return iter != m_timers.end();
}
-
GHOST_TSuccess GHOST_TimerManager::addTimer(GHOST_TimerTask *timer)
{
- GHOST_TSuccess success;
- if (!getTimerFound(timer)) {
- // Add the timer task
- m_timers.push_back(timer);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ if (!getTimerFound(timer)) {
+ // Add the timer task
+ m_timers.push_back(timer);
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
GHOST_TSuccess GHOST_TimerManager::removeTimer(GHOST_TimerTask *timer)
{
- GHOST_TSuccess success;
- TTimerVector::iterator iter = std::find(m_timers.begin(), m_timers.end(), timer);
- if (iter != m_timers.end()) {
- // Remove the timer task
- m_timers.erase(iter);
- delete timer;
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ TTimerVector::iterator iter = std::find(m_timers.begin(), m_timers.end(), timer);
+ if (iter != m_timers.end()) {
+ // Remove the timer task
+ m_timers.erase(iter);
+ delete timer;
+ success = GHOST_kSuccess;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
GHOST_TUns64 GHOST_TimerManager::nextFireTime()
{
- GHOST_TUns64 smallest = GHOST_kFireTimeNever;
- TTimerVector::iterator iter;
+ GHOST_TUns64 smallest = GHOST_kFireTimeNever;
+ TTimerVector::iterator iter;
- for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) {
- GHOST_TUns64 next = (*iter)->getNext();
+ for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) {
+ GHOST_TUns64 next = (*iter)->getNext();
- if (next < smallest)
- smallest = next;
- }
+ if (next < smallest)
+ smallest = next;
+ }
- return smallest;
+ return smallest;
}
bool GHOST_TimerManager::fireTimers(GHOST_TUns64 time)
{
- TTimerVector::iterator iter;
- bool anyProcessed = false;
+ TTimerVector::iterator iter;
+ bool anyProcessed = false;
- for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) {
- if (fireTimer(time, *iter))
- anyProcessed = true;
- }
+ for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) {
+ if (fireTimer(time, *iter))
+ anyProcessed = true;
+ }
- return anyProcessed;
+ return anyProcessed;
}
-
bool GHOST_TimerManager::fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task)
{
- GHOST_TUns64 next = task->getNext();
-
- // Check if the timer should be fired
- if (time > next) {
- // Fire the timer
- GHOST_TimerProcPtr timerProc = task->getTimerProc();
- GHOST_TUns64 start = task->getStart();
- timerProc(task, time - start);
-
- // Update the time at which we will fire it again
- GHOST_TUns64 interval = task->getInterval();
- GHOST_TUns64 numCalls = (next - start) / interval;
- numCalls++;
- next = start + numCalls * interval;
- task->setNext(next);
-
- return true;
- }
- else {
- return false;
- }
+ GHOST_TUns64 next = task->getNext();
+
+ // Check if the timer should be fired
+ if (time > next) {
+ // Fire the timer
+ GHOST_TimerProcPtr timerProc = task->getTimerProc();
+ GHOST_TUns64 start = task->getStart();
+ timerProc(task, time - start);
+
+ // Update the time at which we will fire it again
+ GHOST_TUns64 interval = task->getInterval();
+ GHOST_TUns64 numCalls = (next - start) / interval;
+ numCalls++;
+ next = start + numCalls * interval;
+ task->setNext(next);
+
+ return true;
+ }
+ else {
+ return false;
+ }
}
-
void GHOST_TimerManager::disposeTimers()
{
- while (m_timers.empty() == false) {
- delete m_timers[0];
- m_timers.erase(m_timers.begin());
- }
+ while (m_timers.empty() == false) {
+ delete m_timers[0];
+ m_timers.erase(m_timers.begin());
+ }
}
diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h
index 538198e208d..039663a7a0e 100644
--- a/intern/ghost/intern/GHOST_TimerManager.h
+++ b/intern/ghost/intern/GHOST_TimerManager.h
@@ -31,89 +31,86 @@
class GHOST_TimerTask;
-
/**
* Manages a list of timer tasks.
* Timer tasks added are owned by the manager.
* Don't delete timer task objects.
*/
-class GHOST_TimerManager
-{
-public:
- /**
- * Constructor.
- */
- GHOST_TimerManager();
-
- /**
- * Destructor.
- */
- ~GHOST_TimerManager();
-
- /**
- * Returns the number of timer tasks.
- * \return The number of events on the stack.
- */
- GHOST_TUns32 getNumTimers();
-
- /**
- * Returns whether this timer task ins in our list.
- * \return Indication of presence.
- */
- bool getTimerFound(GHOST_TimerTask *timer);
-
- /**
- * Adds a timer task to the list.
- * It is only added when it not already present in the list.
- * \param timer The timer task added to the list.
- * \return Indication as to whether addition has succeeded.
- */
- GHOST_TSuccess addTimer(GHOST_TimerTask *timer);
-
- /**
- * Removes a timer task from the list.
- * It is only removed when it is found in the list.
- * \param timer The timer task to be removed from the list.
- * \return Indication as to whether removal has succeeded.
- */
- GHOST_TSuccess removeTimer(GHOST_TimerTask *timer);
-
- /**
- * Finds the soonest time the next timer would fire.
- * \return The soonest time the next timer would fire,
- * or GHOST_kFireTimeNever if no timers exist.
- */
- GHOST_TUns64 nextFireTime();
-
- /**
- * Checks all timer tasks to see if they are expired and fires them if needed.
- * \param time The current time.
- * \return True if any timers were fired.
- */
- bool fireTimers(GHOST_TUns64 time);
-
- /**
- * Checks this timer task to see if they are expired and fires them if needed.
- * \param time The current time.
- * \param task The timer task to check and optionally fire.
- * \return True if the timer fired.
- */
- bool fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task);
-
-protected:
- /**
- * Deletes all timers.
- */
- void disposeTimers();
-
- typedef std::vector<GHOST_TimerTask *> TTimerVector;
- /** The list with event consumers. */
- TTimerVector m_timers;
-
+class GHOST_TimerManager {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_TimerManager();
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_TimerManager();
+
+ /**
+ * Returns the number of timer tasks.
+ * \return The number of events on the stack.
+ */
+ GHOST_TUns32 getNumTimers();
+
+ /**
+ * Returns whether this timer task ins in our list.
+ * \return Indication of presence.
+ */
+ bool getTimerFound(GHOST_TimerTask *timer);
+
+ /**
+ * Adds a timer task to the list.
+ * It is only added when it not already present in the list.
+ * \param timer The timer task added to the list.
+ * \return Indication as to whether addition has succeeded.
+ */
+ GHOST_TSuccess addTimer(GHOST_TimerTask *timer);
+
+ /**
+ * Removes a timer task from the list.
+ * It is only removed when it is found in the list.
+ * \param timer The timer task to be removed from the list.
+ * \return Indication as to whether removal has succeeded.
+ */
+ GHOST_TSuccess removeTimer(GHOST_TimerTask *timer);
+
+ /**
+ * Finds the soonest time the next timer would fire.
+ * \return The soonest time the next timer would fire,
+ * or GHOST_kFireTimeNever if no timers exist.
+ */
+ GHOST_TUns64 nextFireTime();
+
+ /**
+ * Checks all timer tasks to see if they are expired and fires them if needed.
+ * \param time The current time.
+ * \return True if any timers were fired.
+ */
+ bool fireTimers(GHOST_TUns64 time);
+
+ /**
+ * Checks this timer task to see if they are expired and fires them if needed.
+ * \param time The current time.
+ * \param task The timer task to check and optionally fire.
+ * \return True if the timer fired.
+ */
+ bool fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task);
+
+ protected:
+ /**
+ * Deletes all timers.
+ */
+ void disposeTimers();
+
+ typedef std::vector<GHOST_TimerTask *> TTimerVector;
+ /** The list with event consumers. */
+ TTimerVector m_timers;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_TimerManager")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_TimerManager")
#endif
};
-#endif // __GHOST_TIMERMANAGER_H__
+#endif // __GHOST_TIMERMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h
index 375de377a25..561d9b3e705 100644
--- a/intern/ghost/intern/GHOST_TimerTask.h
+++ b/intern/ghost/intern/GHOST_TimerTask.h
@@ -27,159 +27,157 @@
#include "GHOST_ITimerTask.h"
-
/**
* Implementation of a timer task.
*/
-class GHOST_TimerTask : public GHOST_ITimerTask
-{
-public:
- /**
- * Constructor.
- * \param start The timer start time.
- * \param interval The interval between calls to the timerProc
- * \param timerProc The callback invoked when the interval expires.
- * \param userData: The timer user data.
- */
- GHOST_TimerTask(GHOST_TUns64 start,
- GHOST_TUns64 interval,
- GHOST_TimerProcPtr timerProc,
- GHOST_TUserDataPtr userData = NULL)
- : m_start(start),
- m_interval(interval),
- m_next(start),
- m_timerProc(timerProc),
- m_userData(userData),
- m_auxData(0)
- {
- }
-
- /**
- * Returns the timer start time.
- * \return The timer start time.
- */
- inline GHOST_TUns64 getStart() const
- {
- return m_start;
- }
-
- /**
- * Changes the timer start time.
- * \param start The timer start time.
- */
- void setStart(GHOST_TUns64 start)
- {
- m_start = start;
- }
-
- /**
- * Returns the timer interval.
- * \return The timer interval.
- */
- inline GHOST_TUns64 getInterval() const
- {
- return m_interval;
- }
-
- /**
- * Changes the timer interval.
- * \param interval The timer interval.
- */
- void setInterval(GHOST_TUns64 interval)
- {
- m_interval = interval;
- }
-
- /**
- * Returns the time the timerProc will be called.
- * \return The time the timerProc will be called.
- */
- inline GHOST_TUns64 getNext() const
- {
- return m_next;
- }
-
- /**
- * Changes the time the timerProc will be called.
- * \param next The time the timerProc will be called.
- */
- void setNext(GHOST_TUns64 next)
- {
- m_next = next;
- }
-
- /**
- * Returns the timer callback.
- * \return the timer callback.
- */
- inline GHOST_TimerProcPtr getTimerProc() const
- {
- return m_timerProc;
- }
-
- /**
- * Changes the timer callback.
- * \param timerProc: The timer callback.
- */
- inline void setTimerProc(const GHOST_TimerProcPtr timerProc)
- {
- m_timerProc = timerProc;
- }
-
- /**
- * Returns the timer user data.
- * \return The timer user data.
- */
- inline GHOST_TUserDataPtr getUserData() const
- {
- return m_userData;
- }
-
- /**
- * Changes the time user data.
- * \param userData: The timer user data.
- */
- void setUserData(const GHOST_TUserDataPtr userData)
- {
- m_userData = userData;
- }
-
- /**
- * Returns the auxiliary storage room.
- * \return The auxiliary storage room.
- */
- inline GHOST_TUns32 getAuxData() const
- {
- return m_auxData;
- }
-
- /**
- * Changes the auxiliary storage room.
- * \param auxData The auxiliary storage room.
- */
- void setAuxData(GHOST_TUns32 auxData)
- {
- m_auxData = auxData;
- }
-
-protected:
- /** The time the timer task was started. */
- GHOST_TUns64 m_start;
-
- /** The interval between calls. */
- GHOST_TUns64 m_interval;
-
- /** The time the timerProc will be called. */
- GHOST_TUns64 m_next;
-
- /** The callback invoked when the timer expires. */
- GHOST_TimerProcPtr m_timerProc;
-
- /** The timer task user data. */
- GHOST_TUserDataPtr m_userData;
-
- /** Auxiliary storage room. */
- GHOST_TUns32 m_auxData;
+class GHOST_TimerTask : public GHOST_ITimerTask {
+ public:
+ /**
+ * Constructor.
+ * \param start The timer start time.
+ * \param interval The interval between calls to the timerProc
+ * \param timerProc The callback invoked when the interval expires.
+ * \param userData: The timer user data.
+ */
+ GHOST_TimerTask(GHOST_TUns64 start,
+ GHOST_TUns64 interval,
+ GHOST_TimerProcPtr timerProc,
+ GHOST_TUserDataPtr userData = NULL)
+ : m_start(start),
+ m_interval(interval),
+ m_next(start),
+ m_timerProc(timerProc),
+ m_userData(userData),
+ m_auxData(0)
+ {
+ }
+
+ /**
+ * Returns the timer start time.
+ * \return The timer start time.
+ */
+ inline GHOST_TUns64 getStart() const
+ {
+ return m_start;
+ }
+
+ /**
+ * Changes the timer start time.
+ * \param start The timer start time.
+ */
+ void setStart(GHOST_TUns64 start)
+ {
+ m_start = start;
+ }
+
+ /**
+ * Returns the timer interval.
+ * \return The timer interval.
+ */
+ inline GHOST_TUns64 getInterval() const
+ {
+ return m_interval;
+ }
+
+ /**
+ * Changes the timer interval.
+ * \param interval The timer interval.
+ */
+ void setInterval(GHOST_TUns64 interval)
+ {
+ m_interval = interval;
+ }
+
+ /**
+ * Returns the time the timerProc will be called.
+ * \return The time the timerProc will be called.
+ */
+ inline GHOST_TUns64 getNext() const
+ {
+ return m_next;
+ }
+
+ /**
+ * Changes the time the timerProc will be called.
+ * \param next The time the timerProc will be called.
+ */
+ void setNext(GHOST_TUns64 next)
+ {
+ m_next = next;
+ }
+
+ /**
+ * Returns the timer callback.
+ * \return the timer callback.
+ */
+ inline GHOST_TimerProcPtr getTimerProc() const
+ {
+ return m_timerProc;
+ }
+
+ /**
+ * Changes the timer callback.
+ * \param timerProc: The timer callback.
+ */
+ inline void setTimerProc(const GHOST_TimerProcPtr timerProc)
+ {
+ m_timerProc = timerProc;
+ }
+
+ /**
+ * Returns the timer user data.
+ * \return The timer user data.
+ */
+ inline GHOST_TUserDataPtr getUserData() const
+ {
+ return m_userData;
+ }
+
+ /**
+ * Changes the time user data.
+ * \param userData: The timer user data.
+ */
+ void setUserData(const GHOST_TUserDataPtr userData)
+ {
+ m_userData = userData;
+ }
+
+ /**
+ * Returns the auxiliary storage room.
+ * \return The auxiliary storage room.
+ */
+ inline GHOST_TUns32 getAuxData() const
+ {
+ return m_auxData;
+ }
+
+ /**
+ * Changes the auxiliary storage room.
+ * \param auxData The auxiliary storage room.
+ */
+ void setAuxData(GHOST_TUns32 auxData)
+ {
+ m_auxData = auxData;
+ }
+
+ protected:
+ /** The time the timer task was started. */
+ GHOST_TUns64 m_start;
+
+ /** The interval between calls. */
+ GHOST_TUns64 m_interval;
+
+ /** The time the timerProc will be called. */
+ GHOST_TUns64 m_next;
+
+ /** The callback invoked when the timer expires. */
+ GHOST_TimerProcPtr m_timerProc;
+
+ /** The timer task user data. */
+ GHOST_TUserDataPtr m_userData;
+
+ /** Auxiliary storage room. */
+ GHOST_TUns32 m_auxData;
};
-#endif // __GHOST_TIMERTASK_H__
+#endif // __GHOST_TIMERTASK_H__
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index 0334cdf5f20..06b76aee23d 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
@@ -32,12 +31,12 @@
#include <assert.h>
-GHOST_Window::GHOST_Window(
- GHOST_TUns32 width, GHOST_TUns32 height,
- GHOST_TWindowState state,
- const bool wantStereoVisual,
- const bool /*exclusive*/,
- const GHOST_TUns16 wantNumOfAASamples)
+GHOST_Window::GHOST_Window(GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const bool wantStereoVisual,
+ const bool /*exclusive*/,
+ const GHOST_TUns16 wantNumOfAASamples)
: m_drawingContextType(GHOST_kDrawingContextTypeNone),
m_cursorVisible(true),
m_cursorGrab(GHOST_kGrabDisable),
@@ -46,189 +45,197 @@ GHOST_Window::GHOST_Window(
m_wantNumOfAASamples(wantNumOfAASamples),
m_context(new GHOST_ContextNone(false, 0))
{
- m_isUnsavedChanges = false;
- m_canAcceptDragOperation = false;
+ m_isUnsavedChanges = false;
+ m_canAcceptDragOperation = false;
- m_progressBarVisible = false;
+ m_progressBarVisible = false;
- m_cursorGrabAccumPos[0] = 0;
- m_cursorGrabAccumPos[1] = 0;
+ m_cursorGrabAccumPos[0] = 0;
+ m_cursorGrabAccumPos[1] = 0;
- m_nativePixelSize = 1.0f;
+ m_nativePixelSize = 1.0f;
- m_fullScreen = state == GHOST_kWindowStateFullScreen;
- if (m_fullScreen) {
- m_fullScreenWidth = width;
- m_fullScreenHeight = height;
- }
+ m_fullScreen = state == GHOST_kWindowStateFullScreen;
+ if (m_fullScreen) {
+ m_fullScreenWidth = width;
+ m_fullScreenHeight = height;
+ }
}
-
GHOST_Window::~GHOST_Window()
{
- delete m_context;
+ delete m_context;
}
void *GHOST_Window::getOSWindow() const
{
- return NULL;
+ return NULL;
}
GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType type)
{
- if (type != m_drawingContextType) {
- delete m_context;
- m_context = NULL;
+ if (type != m_drawingContextType) {
+ delete m_context;
+ m_context = NULL;
- if (type != GHOST_kDrawingContextTypeNone)
- m_context = newDrawingContext(type);
+ if (type != GHOST_kDrawingContextTypeNone)
+ m_context = newDrawingContext(type);
- if (m_context != NULL) {
- m_drawingContextType = type;
- }
- else {
- m_context = new GHOST_ContextNone(m_wantStereoVisual, m_wantNumOfAASamples);
- m_drawingContextType = GHOST_kDrawingContextTypeNone;
- }
+ if (m_context != NULL) {
+ m_drawingContextType = type;
+ }
+ else {
+ m_context = new GHOST_ContextNone(m_wantStereoVisual, m_wantNumOfAASamples);
+ m_drawingContextType = GHOST_kDrawingContextTypeNone;
+ }
- return (type == m_drawingContextType) ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- return GHOST_kSuccess;
- }
+ return (type == m_drawingContextType) ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ return GHOST_kSuccess;
+ }
}
GHOST_TSuccess GHOST_Window::swapBuffers()
{
- return m_context->swapBuffers();
+ return m_context->swapBuffers();
}
GHOST_TSuccess GHOST_Window::setSwapInterval(int interval)
{
- return m_context->setSwapInterval(interval);
+ return m_context->setSwapInterval(interval);
}
-GHOST_TSuccess GHOST_Window::getSwapInterval(int& intervalOut)
+GHOST_TSuccess GHOST_Window::getSwapInterval(int &intervalOut)
{
- return m_context->getSwapInterval(intervalOut);
+ return m_context->getSwapInterval(intervalOut);
}
GHOST_TUns16 GHOST_Window::getNumOfAASamples()
{
- return m_context->getNumOfAASamples();
+ return m_context->getNumOfAASamples();
}
GHOST_TSuccess GHOST_Window::activateDrawingContext()
{
- return m_context->activateDrawingContext();
+ return m_context->activateDrawingContext();
}
GHOST_TSuccess GHOST_Window::updateDrawingContext()
{
- return m_context->updateDrawingContext();
+ return m_context->updateDrawingContext();
}
GHOST_TSuccess GHOST_Window::releaseNativeHandles()
{
- return m_context->releaseNativeHandles();
+ return m_context->releaseNativeHandles();
}
GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
{
- if (setWindowCursorVisibility(visible)) {
- m_cursorVisible = visible;
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (setWindowCursorVisibility(visible)) {
+ m_cursorVisible = visible;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2])
+GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode,
+ GHOST_Rect *bounds,
+ GHOST_TInt32 mouse_ungrab_xy[2])
{
- if (m_cursorGrab == mode)
- return GHOST_kSuccess;
+ if (m_cursorGrab == mode)
+ return GHOST_kSuccess;
- /* override with new location */
- if (mouse_ungrab_xy) {
- assert(mode == GHOST_kGrabDisable);
- m_cursorGrabInitPos[0] = mouse_ungrab_xy[0];
- m_cursorGrabInitPos[1] = mouse_ungrab_xy[1];
- }
+ /* override with new location */
+ if (mouse_ungrab_xy) {
+ assert(mode == GHOST_kGrabDisable);
+ m_cursorGrabInitPos[0] = mouse_ungrab_xy[0];
+ m_cursorGrabInitPos[1] = mouse_ungrab_xy[1];
+ }
- if (setWindowCursorGrab(mode)) {
+ if (setWindowCursorGrab(mode)) {
- if (mode == GHOST_kGrabDisable)
- m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1;
- else if (bounds) {
- m_cursorGrabBounds = *bounds;
- }
- else { /* if bounds not defined, use window */
- getClientBounds(m_cursorGrabBounds);
- }
- m_cursorGrab = mode;
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (mode == GHOST_kGrabDisable)
+ m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1;
+ else if (bounds) {
+ m_cursorGrabBounds = *bounds;
+ }
+ else { /* if bounds not defined, use window */
+ getClientBounds(m_cursorGrabBounds);
+ }
+ m_cursorGrab = mode;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect& bounds)
+GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds)
{
- bounds = m_cursorGrabBounds;
- return (bounds.m_l == -1 && bounds.m_r == -1) ? GHOST_kFailure : GHOST_kSuccess;
+ bounds = m_cursorGrabBounds;
+ return (bounds.m_l == -1 && bounds.m_r == -1) ? GHOST_kFailure : GHOST_kSuccess;
}
GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
{
- if (setWindowCursorShape(cursorShape)) {
- m_cursorShape = cursorShape;
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (setWindowCursorShape(cursorShape)) {
+ m_cursorShape = cursorShape;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
-GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2],
- int hotX, int hotY)
+GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY)
{
- return setCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask,
- 16, 16, hotX, hotY, 0, 1);
+ return setCustomCursorShape(
+ (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1);
}
-GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
- int sizex, int sizey, int hotX, int hotY,
- int fg_color, int bg_color)
+GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color)
{
- if (setWindowCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, fg_color, bg_color)) {
- m_cursorShape = GHOST_kStandardCursorCustom;
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
+ if (setWindowCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, fg_color, bg_color)) {
+ m_cursorShape = GHOST_kStandardCursorCustom;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
}
void GHOST_Window::setAcceptDragOperation(bool canAccept)
{
- m_canAcceptDragOperation = canAccept;
+ m_canAcceptDragOperation = canAccept;
}
bool GHOST_Window::canAcceptDragOperation() const
{
- return m_canAcceptDragOperation;
+ return m_canAcceptDragOperation;
}
GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges)
{
- m_isUnsavedChanges = isUnsavedChanges;
+ m_isUnsavedChanges = isUnsavedChanges;
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
bool GHOST_Window::getModifiedState()
{
- return m_isUnsavedChanges;
+ return m_isUnsavedChanges;
}
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index c84fced2f2d..8c01d66bbfd 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -37,417 +37,425 @@ class GHOST_Context;
* Implements part of the GHOST_IWindow interface and adds some methods to
* be implemented by childs of this class.
*/
-class GHOST_Window : public GHOST_IWindow
-{
-public:
-
- /**
- * Constructor.
- * Creates a new window and opens it.
- * To check if the window was created properly, use the getValid() method.
- * \param width The width the window.
- * \param heigh The height the window.
- * \param state The state the window is initially opened with.
- * \param type The type of drawing context installed in this window.
- * \param stereoVisual Stereo visual for quad buffered stereo.
- * \param exclusive Use to show the window ontop and ignore others
- * (used fullscreen).
- * \param numOfAASamples Number of samples used for AA (zero if no AA)
- */
- GHOST_Window(
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- const bool wantStereoVisual = false,
- const bool exclusive = false,
- const GHOST_TUns16 wantNumOfAASamples = 0);
-
- /**
- * \section Interface inherited from GHOST_IWindow left for derived class
- * implementation.
- * virtual bool getValid() const = 0;
- * virtual void setTitle(const STR_String& title) = 0;
- * virtual void getTitle(STR_String& title) const = 0;
- * virtual void getWindowBounds(GHOST_Rect& bounds) const = 0;
- * virtual void getClientBounds(GHOST_Rect& bounds) const = 0;
- * virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
- * virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
- * virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
- * virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
- * virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
- * virtual GHOST_TWindowState getState() const = 0;
- * virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
- * virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
- * virtual GHOST_TSuccess swapBuffers() = 0;
- * virtual GHOST_TSuccess setSwapInterval() = 0;
- * virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0;
- * virtual GHOST_TSuccess activateDrawingContext() = 0;
- * virtual GHOST_TSuccess invalidate() = 0;
- */
-
- /**
- * Destructor.
- * Closes the window and disposes resources allocated.
- */
- virtual ~GHOST_Window();
-
- /**
- * Returns indication as to whether the window is valid.
- * \return The validity of the window.
- */
- virtual bool getValid() const {
- return m_context != NULL;
- }
-
- /**
- * Returns the associated OS object/handle
- * \return The associated OS object/handle
- */
- virtual void *getOSWindow() const;
-
- /**
- * Returns the current cursor shape.
- * \return The current cursor shape.
- */
- inline GHOST_TStandardCursor getCursorShape() const;
-
- /**
- * Set the shape of the cursor.
- * \param cursorShape: The new cursor shape type id.
- * \return Indication of success.
- */
- GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
-
- /**
- * Set the shape of the cursor to a custom cursor.
- * \param bitmap The bitmap data for the cursor.
- * \param mask The mask data for the cursor.
- * \param hotX The X coordinate of the cursor hotspot.
- * \param hotY The Y coordinate of the cursor hotspot.
- * \return Indication of success.
- */
- GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX,
- int hotY);
-
- GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex, int sizey,
- int hotX, int hotY,
- int fg_color, int bg_color);
-
- /**
- * Returns the visibility state of the cursor.
- * \return The visibility state of the cursor.
- */
- inline bool getCursorVisibility() const;
- inline GHOST_TGrabCursorMode getCursorGrabMode() const;
- inline bool getCursorGrabModeIsWarp() const;
- inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
-
- /**
- * Shows or hides the cursor.
- * \param visible The new visibility state of the cursor.
- * \return Indication of success.
- */
- GHOST_TSuccess setCursorVisibility(bool visible);
-
- /**
- * Sets the cursor grab.
- * \param mode The new grab state of the cursor.
- * \return Indication of success.
- */
- GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]);
-
- /**
- * Gets the cursor grab region, if unset the window is used.
- * reset when grab is disabled.
- */
- GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds);
-
- /**
- * Sets the progress bar value displayed in the window/application icon
- * \param progress The progress % (0.0 to 1.0)
- */
- virtual GHOST_TSuccess setProgressBar(float /*progress*/) {
- return GHOST_kFailure;
- }
-
- /**
- * Hides the progress bar in the icon
- */
- virtual GHOST_TSuccess endProgressBar() {
- return GHOST_kFailure;
- }
-
- /**
- * Sets the swap interval for swapBuffers.
- * \param interval The swap interval to use.
- * \return A boolean success indicator.
- */
- GHOST_TSuccess setSwapInterval(int interval);
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \return An integer.
- */
- GHOST_TSuccess getSwapInterval(int& intervalOut);
-
- /**
- * Gets the current swap interval for swapBuffers.
- * \return Number of AA Samples (0 if there is no multisample buffer)
- */
- GHOST_TUns16 getNumOfAASamples();
-
- /**
- * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
- */
- void setAcceptDragOperation(bool canAccept);
-
- /**
- * Returns acceptance of the dropped object
- * Usually called by the "object dropped" event handling function
- */
- bool canAcceptDragOperation() const;
-
- /**
- * Sets the window "modified" status, indicating unsaved changes
- * \param isUnsavedChanges Unsaved changes or not
- * \return Indication of success.
- */
- virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
-
- /**
- * Gets the window "modified" status, indicating unsaved changes
- * \return True if there are unsaved changes
- */
- virtual bool getModifiedState();
-
- /**
- * Returns the type of drawing context used in this window.
- * \return The current type of drawing context.
- */
- inline GHOST_TDrawingContextType getDrawingContextType();
-
- /**
- * Tries to install a rendering context in this window.
- * Child classes do not need to overload this method,
- * They should overload newDrawingContext instead.
- * \param type The type of rendering context installed.
- * \return Indication as to whether installation has succeeded.
- */
- GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
-
- /**
- * Swaps front and back buffers of a window.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess swapBuffers();
-
- /**
- * Activates the drawing context of this window.
- * \return A boolean success indicator.
- */
- virtual GHOST_TSuccess activateDrawingContext();
-
- /**
- * Updates the drawing context of this window. Needed
- * whenever the window is changed.
- * \return Indication of success.
- */
- GHOST_TSuccess updateDrawingContext();
-
- /**
- * Returns the window user data.
- * \return The window user data.
- */
- inline GHOST_TUserDataPtr getUserData() const
- {
- return m_userData;
- }
-
- /**
- * Changes the window user data.
- * \param userData: The window user data.
- */
- void setUserData(const GHOST_TUserDataPtr userData)
- {
- m_userData = userData;
- }
-
- float getNativePixelSize(void)
- {
- if (m_nativePixelSize > 0.0f)
- return m_nativePixelSize;
- return 1.0f;
- }
-
- /**
- * Returns the recommended DPI for this window.
- * \return The recommended DPI for this window.
- */
- virtual inline GHOST_TUns16 getDPIHint()
- {
- return 96;
- }
+class GHOST_Window : public GHOST_IWindow {
+ public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * \param width The width the window.
+ * \param heigh The height the window.
+ * \param state The state the window is initially opened with.
+ * \param type The type of drawing context installed in this window.
+ * \param stereoVisual Stereo visual for quad buffered stereo.
+ * \param exclusive Use to show the window ontop and ignore others
+ * (used fullscreen).
+ * \param numOfAASamples Number of samples used for AA (zero if no AA)
+ */
+ GHOST_Window(GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const bool wantStereoVisual = false,
+ const bool exclusive = false,
+ const GHOST_TUns16 wantNumOfAASamples = 0);
+
+ /**
+ * \section Interface inherited from GHOST_IWindow left for derived class
+ * implementation.
+ * virtual bool getValid() const = 0;
+ * virtual void setTitle(const STR_String& title) = 0;
+ * virtual void getTitle(STR_String& title) const = 0;
+ * virtual void getWindowBounds(GHOST_Rect& bounds) const = 0;
+ * virtual void getClientBounds(GHOST_Rect& bounds) const = 0;
+ * virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
+ * virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
+ * virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
+ * virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
+ * virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
+ * virtual GHOST_TWindowState getState() const = 0;
+ * virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
+ * virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
+ * virtual GHOST_TSuccess swapBuffers() = 0;
+ * virtual GHOST_TSuccess setSwapInterval() = 0;
+ * virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0;
+ * virtual GHOST_TSuccess activateDrawingContext() = 0;
+ * virtual GHOST_TSuccess invalidate() = 0;
+ */
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ virtual ~GHOST_Window();
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * \return The validity of the window.
+ */
+ virtual bool getValid() const
+ {
+ return m_context != NULL;
+ }
+
+ /**
+ * Returns the associated OS object/handle
+ * \return The associated OS object/handle
+ */
+ virtual void *getOSWindow() const;
+
+ /**
+ * Returns the current cursor shape.
+ * \return The current cursor shape.
+ */
+ inline GHOST_TStandardCursor getCursorShape() const;
+
+ /**
+ * Set the shape of the cursor.
+ * \param cursorShape: The new cursor shape type id.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
+
+ /**
+ * Set the shape of the cursor to a custom cursor.
+ * \param bitmap The bitmap data for the cursor.
+ * \param mask The mask data for the cursor.
+ * \param hotX The X coordinate of the cursor hotspot.
+ * \param hotY The Y coordinate of the cursor hotspot.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
+
+ GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color);
+
+ /**
+ * Returns the visibility state of the cursor.
+ * \return The visibility state of the cursor.
+ */
+ inline bool getCursorVisibility() const;
+ inline GHOST_TGrabCursorMode getCursorGrabMode() const;
+ inline bool getCursorGrabModeIsWarp() const;
+ inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+ inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+ inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
+
+ /**
+ * Shows or hides the cursor.
+ * \param visible The new visibility state of the cursor.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCursorVisibility(bool visible);
+
+ /**
+ * Sets the cursor grab.
+ * \param mode The new grab state of the cursor.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode,
+ GHOST_Rect *bounds,
+ GHOST_TInt32 mouse_ungrab_xy[2]);
+
+ /**
+ * Gets the cursor grab region, if unset the window is used.
+ * reset when grab is disabled.
+ */
+ GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds);
+
+ /**
+ * Sets the progress bar value displayed in the window/application icon
+ * \param progress The progress % (0.0 to 1.0)
+ */
+ virtual GHOST_TSuccess setProgressBar(float /*progress*/)
+ {
+ return GHOST_kFailure;
+ }
+
+ /**
+ * Hides the progress bar in the icon
+ */
+ virtual GHOST_TSuccess endProgressBar()
+ {
+ return GHOST_kFailure;
+ }
+
+ /**
+ * Sets the swap interval for swapBuffers.
+ * \param interval The swap interval to use.
+ * \return A boolean success indicator.
+ */
+ GHOST_TSuccess setSwapInterval(int interval);
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \return An integer.
+ */
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
+
+ /**
+ * Gets the current swap interval for swapBuffers.
+ * \return Number of AA Samples (0 if there is no multisample buffer)
+ */
+ GHOST_TUns16 getNumOfAASamples();
+
+ /**
+ * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
+ */
+ void setAcceptDragOperation(bool canAccept);
+
+ /**
+ * Returns acceptance of the dropped object
+ * Usually called by the "object dropped" event handling function
+ */
+ bool canAcceptDragOperation() const;
+
+ /**
+ * Sets the window "modified" status, indicating unsaved changes
+ * \param isUnsavedChanges Unsaved changes or not
+ * \return Indication of success.
+ */
+ virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
+
+ /**
+ * Gets the window "modified" status, indicating unsaved changes
+ * \return True if there are unsaved changes
+ */
+ virtual bool getModifiedState();
+
+ /**
+ * Returns the type of drawing context used in this window.
+ * \return The current type of drawing context.
+ */
+ inline GHOST_TDrawingContextType getDrawingContextType();
+
+ /**
+ * Tries to install a rendering context in this window.
+ * Child classes do not need to overload this method,
+ * They should overload newDrawingContext instead.
+ * \param type The type of rendering context installed.
+ * \return Indication as to whether installation has succeeded.
+ */
+ GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
+
+ /**
+ * Swaps front and back buffers of a window.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess swapBuffers();
+
+ /**
+ * Activates the drawing context of this window.
+ * \return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess activateDrawingContext();
+
+ /**
+ * Updates the drawing context of this window. Needed
+ * whenever the window is changed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess updateDrawingContext();
+
+ /**
+ * Returns the window user data.
+ * \return The window user data.
+ */
+ inline GHOST_TUserDataPtr getUserData() const
+ {
+ return m_userData;
+ }
+
+ /**
+ * Changes the window user data.
+ * \param userData: The window user data.
+ */
+ void setUserData(const GHOST_TUserDataPtr userData)
+ {
+ m_userData = userData;
+ }
+
+ float getNativePixelSize(void)
+ {
+ if (m_nativePixelSize > 0.0f)
+ return m_nativePixelSize;
+ return 1.0f;
+ }
+
+ /**
+ * Returns the recommended DPI for this window.
+ * \return The recommended DPI for this window.
+ */
+ virtual inline GHOST_TUns16 getDPIHint()
+ {
+ return 96;
+ }
#ifdef WITH_INPUT_IME
- virtual void beginIME(GHOST_TInt32 x,
- GHOST_TInt32 y,
- GHOST_TInt32 w,
- GHOST_TInt32 h,
- int completed)
- {
- /* do nothing temporarily if not in windows */
- }
-
- virtual void endIME()
- {
- /* do nothing temporarily if not in windows */
- }
+ virtual void beginIME(
+ GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed)
+ {
+ /* do nothing temporarily if not in windows */
+ }
+
+ virtual void endIME()
+ {
+ /* do nothing temporarily if not in windows */
+ }
#endif /* WITH_INPUT_IME */
-protected:
- /**
- * Tries to install a rendering context in this window.
- * \param type The type of rendering context installed.
- * \return Indication as to whether installation has succeeded.
- */
- virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) = 0;
-
- /**
- * Sets the cursor visibility on the window using
- * native window system calls.
- */
- virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0;
-
- /**
- * Sets the cursor grab on the window using
- * native window system calls.
- */
- virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/) {
- return GHOST_kSuccess;
- }
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) = 0;
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX, int hotY) = 0;
-
- virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
- int szx, int szy, int hotX, int hotY, int fg, int bg) = 0;
-
- GHOST_TSuccess releaseNativeHandles();
-
- /** The drawing context installed in this window. */
- GHOST_TDrawingContextType m_drawingContextType;
-
- /** The window user data */
- GHOST_TUserDataPtr m_userData;
-
- /** The current visibility of the cursor */
- bool m_cursorVisible;
-
- /** The current grabbed state of the cursor */
- GHOST_TGrabCursorMode m_cursorGrab;
-
- /** Initial grab location. */
- GHOST_TInt32 m_cursorGrabInitPos[2];
-
- /** Accumulated offset from m_cursorGrabInitPos. */
- GHOST_TInt32 m_cursorGrabAccumPos[2];
-
- /** Wrap the cursor within this region. */
- GHOST_Rect m_cursorGrabBounds;
-
- /** The current shape of the cursor */
- GHOST_TStandardCursor m_cursorShape;
-
- /** The presence of progress indicator with the application icon */
- bool m_progressBarVisible;
-
- /** The acceptance of the "drop candidate" of the current drag'n'drop operation */
- bool m_canAcceptDragOperation;
-
- /** Modified state : are there unsaved changes */
- bool m_isUnsavedChanges;
-
- /** Stores whether this is a full screen window. */
- bool m_fullScreen;
-
- /** Whether to attempt to initialize a context with a stereo framebuffer. */
- bool m_wantStereoVisual;
-
- /** Attempt to initialize a context with this many samples. */
- GHOST_TUns16 m_wantNumOfAASamples;
-
- /** Full-screen width */
- GHOST_TUns32 m_fullScreenWidth;
- /** Full-screen height */
- GHOST_TUns32 m_fullScreenHeight;
-
- /* OSX only, retina screens */
- float m_nativePixelSize;
-
-private:
- GHOST_Context *m_context;
+ protected:
+ /**
+ * Tries to install a rendering context in this window.
+ * \param type The type of rendering context installed.
+ * \return Indication as to whether installation has succeeded.
+ */
+ virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) = 0;
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0;
+
+ /**
+ * Sets the cursor grab on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/)
+ {
+ return GHOST_kSuccess;
+ }
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) = 0;
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY) = 0;
+
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int szx,
+ int szy,
+ int hotX,
+ int hotY,
+ int fg,
+ int bg) = 0;
+
+ GHOST_TSuccess releaseNativeHandles();
+
+ /** The drawing context installed in this window. */
+ GHOST_TDrawingContextType m_drawingContextType;
+
+ /** The window user data */
+ GHOST_TUserDataPtr m_userData;
+
+ /** The current visibility of the cursor */
+ bool m_cursorVisible;
+
+ /** The current grabbed state of the cursor */
+ GHOST_TGrabCursorMode m_cursorGrab;
+
+ /** Initial grab location. */
+ GHOST_TInt32 m_cursorGrabInitPos[2];
+
+ /** Accumulated offset from m_cursorGrabInitPos. */
+ GHOST_TInt32 m_cursorGrabAccumPos[2];
+
+ /** Wrap the cursor within this region. */
+ GHOST_Rect m_cursorGrabBounds;
+
+ /** The current shape of the cursor */
+ GHOST_TStandardCursor m_cursorShape;
+
+ /** The presence of progress indicator with the application icon */
+ bool m_progressBarVisible;
+
+ /** The acceptance of the "drop candidate" of the current drag'n'drop operation */
+ bool m_canAcceptDragOperation;
+
+ /** Modified state : are there unsaved changes */
+ bool m_isUnsavedChanges;
+
+ /** Stores whether this is a full screen window. */
+ bool m_fullScreen;
+
+ /** Whether to attempt to initialize a context with a stereo framebuffer. */
+ bool m_wantStereoVisual;
+
+ /** Attempt to initialize a context with this many samples. */
+ GHOST_TUns16 m_wantNumOfAASamples;
+
+ /** Full-screen width */
+ GHOST_TUns32 m_fullScreenWidth;
+ /** Full-screen height */
+ GHOST_TUns32 m_fullScreenHeight;
+
+ /* OSX only, retina screens */
+ float m_nativePixelSize;
+
+ private:
+ GHOST_Context *m_context;
};
-
inline GHOST_TDrawingContextType GHOST_Window::getDrawingContextType()
{
- return m_drawingContextType;
+ return m_drawingContextType;
}
inline bool GHOST_Window::getCursorVisibility() const
{
- return m_cursorVisible;
+ return m_cursorVisible;
}
inline GHOST_TGrabCursorMode GHOST_Window::getCursorGrabMode() const
{
- return m_cursorGrab;
+ return m_cursorGrab;
}
inline bool GHOST_Window::getCursorGrabModeIsWarp() const
{
- return (m_cursorGrab == GHOST_kGrabWrap) ||
- (m_cursorGrab == GHOST_kGrabHide);
+ return (m_cursorGrab == GHOST_kGrabWrap) || (m_cursorGrab == GHOST_kGrabHide);
}
inline void GHOST_Window::getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- x = m_cursorGrabInitPos[0];
- y = m_cursorGrabInitPos[1];
+ x = m_cursorGrabInitPos[0];
+ y = m_cursorGrabInitPos[1];
}
inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- x = m_cursorGrabAccumPos[0];
- y = m_cursorGrabAccumPos[1];
+ x = m_cursorGrabAccumPos[0];
+ y = m_cursorGrabAccumPos[1];
}
inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y)
{
- m_cursorGrabAccumPos[0] = x;
- m_cursorGrabAccumPos[1] = y;
+ m_cursorGrabAccumPos[0] = x;
+ m_cursorGrabAccumPos[1] = y;
}
inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
{
- return m_cursorShape;
+ return m_cursorShape;
}
-#endif // _GHOST_WINDOW_H
+#endif // _GHOST_WINDOW_H
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index 0b3aa6be732..acda109eb7f 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -26,8 +26,8 @@
#define __GHOST_WINDOWCOCOA_H__
#ifndef __APPLE__
-#error Apple OSX only!
-#endif // __APPLE__
+# error Apple OSX only!
+#endif // __APPLE__
#include "GHOST_Window.h"
#include "STR_String.h"
@@ -40,263 +40,295 @@
class GHOST_SystemCocoa;
class GHOST_WindowCocoa : public GHOST_Window {
-public:
- /**
- * Constructor.
- * Creates a new window and opens it.
- * To check if the window was created properly, use the getValid() method.
- * \param systemCocoa The associated system class to forward events to
- * \param title The text shown in the title bar of the window.
- * \param left The coordinate of the left edge of the window.
- * \param bottom The coordinate of the bottom edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state the window is initially opened with.
- * \param type The type of drawing context installed in this window.
- * \param stereoVisual Stereo visual for quad buffered stereo.
- * \param numOfAASamples Number of samples used for AA (zero if no AA)
- */
- GHOST_WindowCocoa(
- GHOST_SystemCocoa *systemCocoa,
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 bottom,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false,
- const GHOST_TUns16 numOfAASamples = 0,
- bool is_debug = false
- );
-
- /**
- * Destructor.
- * Closes the window and disposes resources allocated.
- */
- ~GHOST_WindowCocoa();
-
- /**
- * Returns indication as to whether the window is valid.
- * \return The validity of the window.
- */
- bool getValid() const;
-
- /**
- * Returns the associated NSWindow object
- * \return The associated NSWindow object
- */
- void *getOSWindow() const;
-
- /**
- * Sets the title displayed in the title bar.
- * \param title The title to display in the title bar.
- */
- void setTitle(const STR_String& title);
-
- /**
- * Returns the title displayed in the title bar.
- * \param title The title displayed in the title bar.
- */
- void getTitle(STR_String& title) const;
-
- /**
- * Returns the window rectangle dimensions.
- * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
- * \param bounds The bounding rectangle of the window.
- */
- void getWindowBounds(GHOST_Rect& bounds) const;
-
- /**
- * Returns the client rectangle dimensions.
- * The left and top members of the rectangle are always zero.
- * \param bounds The bounding rectangle of the client area of the window.
- */
- void getClientBounds(GHOST_Rect& bounds) const;
-
- /**
- * Resizes client rectangle width.
- * \param width The new width of the client area of the window.
- */
- GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
-
- /**
- * Resizes client rectangle height.
- * \param height The new height of the client area of the window.
- */
- GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
-
- /**
- * Resizes client rectangle.
- * \param width The new width of the client area of the window.
- * \param height The new height of the client area of the window.
- */
- GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
-
- /**
- * Returns the state of the window (normal, minimized, maximized).
- * \return The state of the window.
- */
- GHOST_TWindowState getState() const;
-
- /**
- * Sets the window "modified" status, indicating unsaved changes
- * \param isUnsavedChanges Unsaved changes or not
- * \return Indication of success.
- */
- GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates
- * \param inX The x-coordinate on the screen.
- * \param inY The y-coordinate on the screen.
- * \param outX The x-coordinate in the client rectangle.
- * \param outY The y-coordinate in the client rectangle.
- */
- void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates
- * \param inX The x-coordinate in the client rectangle.
- * \param inY The y-coordinate in the client rectangle.
- * \param outX The x-coordinate on the screen.
- * \param outY The y-coordinate on the screen.
- */
- void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates
- * but without the y coordinate conversion needed for ghost compatibility.
- * \param inX The x-coordinate in the client rectangle.
- * \param inY The y-coordinate in the client rectangle.
- * \param outX The x-coordinate on the screen.
- * \param outY The y-coordinate on the screen.
- */
- void clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates,
- * but without the y coordinate conversion needed for ghost compatibility.
- * \param inX The x-coordinate in the client rectangle.
- * \param inY The y-coordinate in the client rectangle.
- * \param outX The x-coordinate on the screen.
- * \param outY The y-coordinate on the screen.
- */
- void screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
-
- /**
- * Gets the screen the window is displayed in
- * \return The NSScreen object
- */
- NSScreen *getScreen();
-
- /**
- * Sets the state of the window (normal, minimized, maximized).
- * \param state The state of the window.
- * \return Indication of success.
- */
- GHOST_TSuccess setState(GHOST_TWindowState state);
-
- /**
- * Sets the order of the window (bottom, top).
- * \param order The order of the window.
- * \return Indication of success.
- */
- GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
-
- void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
-
- const GHOST_TabletData *GetTabletData()
- {
- return &m_tablet;
- }
-
- GHOST_TabletData& GetCocoaTabletData()
- {
- return m_tablet;
- }
-
- /**
- * Sets the progress bar value displayed in the window/application icon
- * \param progress The progress % (0.0 to 1.0)
- */
- GHOST_TSuccess setProgressBar(float progress);
-
- /**
- * Hides the progress bar icon
- */
- GHOST_TSuccess endProgressBar();
-
-
- void setNativePixelSize(void);
-
- GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
-
- GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
-
- /** public function to get the window containing the OpenGL view */
- CocoaWindow *getCocoaWindow() const {return m_window;};
-
- /* Internal value to ensure proper redraws during animations */
- void setImmediateDraw(bool value) { m_immediateDraw = value; }
- bool getImmediateDraw(void) const { return m_immediateDraw; }
-
-protected:
-
- /**
- * \param type The type of rendering context create.
- * \return Indication of success.
- */
- GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
-
- /**
- * Invalidates the contents of this window.
- * \return Indication of success.
- */
- GHOST_TSuccess invalidate();
-
- /**
- * Sets the cursor visibility on the window using
- * native window system calls.
- */
- GHOST_TSuccess setWindowCursorVisibility(bool visible);
-
- /**
- * Sets the cursor grab on the window using
- * native window system calls.
- */
- GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
- int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
-
- GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
-
- /** The window containing the OpenGL view */
- CocoaWindow *m_window;
-
- /** The openGL view */
- CocoaOpenGLView *m_openGLView;
-
- /** The mother SystemCocoa class to send events */
- GHOST_SystemCocoa *m_systemCocoa;
-
- NSCursor *m_customCursor;
-
- GHOST_TabletData m_tablet;
-
- bool m_immediateDraw;
- bool m_debug_context; // for debug messages during context setup
+ public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * \param systemCocoa The associated system class to forward events to
+ * \param title The text shown in the title bar of the window.
+ * \param left The coordinate of the left edge of the window.
+ * \param bottom The coordinate of the bottom edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state the window is initially opened with.
+ * \param type The type of drawing context installed in this window.
+ * \param stereoVisual Stereo visual for quad buffered stereo.
+ * \param numOfAASamples Number of samples used for AA (zero if no AA)
+ */
+ GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 bottom,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false,
+ const GHOST_TUns16 numOfAASamples = 0,
+ bool is_debug = false);
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ ~GHOST_WindowCocoa();
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * \return The validity of the window.
+ */
+ bool getValid() const;
+
+ /**
+ * Returns the associated NSWindow object
+ * \return The associated NSWindow object
+ */
+ void *getOSWindow() const;
+
+ /**
+ * Sets the title displayed in the title bar.
+ * \param title The title to display in the title bar.
+ */
+ void setTitle(const STR_String &title);
+
+ /**
+ * Returns the title displayed in the title bar.
+ * \param title The title displayed in the title bar.
+ */
+ void getTitle(STR_String &title) const;
+
+ /**
+ * Returns the window rectangle dimensions.
+ * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * \param bounds The bounding rectangle of the window.
+ */
+ void getWindowBounds(GHOST_Rect &bounds) const;
+
+ /**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * \param bounds The bounding rectangle of the client area of the window.
+ */
+ void getClientBounds(GHOST_Rect &bounds) const;
+
+ /**
+ * Resizes client rectangle width.
+ * \param width The new width of the client area of the window.
+ */
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+
+ /**
+ * Resizes client rectangle height.
+ * \param height The new height of the client area of the window.
+ */
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+
+ /**
+ * Resizes client rectangle.
+ * \param width The new width of the client area of the window.
+ * \param height The new height of the client area of the window.
+ */
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+
+ /**
+ * Returns the state of the window (normal, minimized, maximized).
+ * \return The state of the window.
+ */
+ GHOST_TWindowState getState() const;
+
+ /**
+ * Sets the window "modified" status, indicating unsaved changes
+ * \param isUnsavedChanges Unsaved changes or not
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * \param inX The x-coordinate on the screen.
+ * \param inY The y-coordinate on the screen.
+ * \param outX The x-coordinate in the client rectangle.
+ * \param outY The y-coordinate in the client rectangle.
+ */
+ void screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * \param inX The x-coordinate in the client rectangle.
+ * \param inY The y-coordinate in the client rectangle.
+ * \param outX The x-coordinate on the screen.
+ * \param outY The y-coordinate on the screen.
+ */
+ void clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * but without the y coordinate conversion needed for ghost compatibility.
+ * \param inX The x-coordinate in the client rectangle.
+ * \param inY The y-coordinate in the client rectangle.
+ * \param outX The x-coordinate on the screen.
+ * \param outY The y-coordinate on the screen.
+ */
+ void clientToScreenIntern(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates,
+ * but without the y coordinate conversion needed for ghost compatibility.
+ * \param inX The x-coordinate in the client rectangle.
+ * \param inY The y-coordinate in the client rectangle.
+ * \param outX The x-coordinate on the screen.
+ * \param outY The y-coordinate on the screen.
+ */
+ void screenToClientIntern(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ /**
+ * Gets the screen the window is displayed in
+ * \return The NSScreen object
+ */
+ NSScreen *getScreen();
+
+ /**
+ * Sets the state of the window (normal, minimized, maximized).
+ * \param state The state of the window.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setState(GHOST_TWindowState state);
+
+ /**
+ * Sets the order of the window (bottom, top).
+ * \param order The order of the window.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+
+ void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
+
+ const GHOST_TabletData *GetTabletData()
+ {
+ return &m_tablet;
+ }
+
+ GHOST_TabletData &GetCocoaTabletData()
+ {
+ return m_tablet;
+ }
+
+ /**
+ * Sets the progress bar value displayed in the window/application icon
+ * \param progress The progress % (0.0 to 1.0)
+ */
+ GHOST_TSuccess setProgressBar(float progress);
+
+ /**
+ * Hides the progress bar icon
+ */
+ GHOST_TSuccess endProgressBar();
+
+ void setNativePixelSize(void);
+
+ GHOST_TSuccess beginFullScreen() const
+ {
+ return GHOST_kFailure;
+ }
+
+ GHOST_TSuccess endFullScreen() const
+ {
+ return GHOST_kFailure;
+ }
+
+ /** public function to get the window containing the OpenGL view */
+ CocoaWindow *getCocoaWindow() const
+ {
+ return m_window;
+ };
+
+ /* Internal value to ensure proper redraws during animations */
+ void setImmediateDraw(bool value)
+ {
+ m_immediateDraw = value;
+ }
+ bool getImmediateDraw(void) const
+ {
+ return m_immediateDraw;
+ }
+
+ protected:
+ /**
+ * \param type The type of rendering context create.
+ * \return Indication of success.
+ */
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+
+ /**
+ * Invalidates the contents of this window.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess invalidate();
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorVisibility(bool visible);
+
+ /**
+ * Sets the cursor grab on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color);
+
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
+
+ /** The window containing the OpenGL view */
+ CocoaWindow *m_window;
+
+ /** The openGL view */
+ CocoaOpenGLView *m_openGLView;
+
+ /** The mother SystemCocoa class to send events */
+ GHOST_SystemCocoa *m_systemCocoa;
+
+ NSCursor *m_customCursor;
+
+ GHOST_TabletData m_tablet;
+
+ bool m_immediateDraw;
+ bool m_debug_context; // for debug messages during context setup
};
-#endif // __GHOST_WINDOWCOCOA_H__
+#endif // __GHOST_WINDOWCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 1af39f11f08..46343e17e46 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -34,14 +34,14 @@
#pragma mark Cocoa window delegate object
-@interface CocoaWindowDelegate : NSObject
-<NSWindowDelegate>
+@interface CocoaWindowDelegate : NSObject <NSWindowDelegate>
{
- GHOST_SystemCocoa *systemCocoa;
- GHOST_WindowCocoa *associatedWindow;
+ GHOST_SystemCocoa *systemCocoa;
+ GHOST_WindowCocoa *associatedWindow;
}
-- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa
+ windowCocoa:(GHOST_WindowCocoa *)winCocoa;
- (void)windowDidBecomeKey:(NSNotification *)notification;
- (void)windowDidResignKey:(NSNotification *)notification;
- (void)windowDidExpose:(NSNotification *)notification;
@@ -53,183 +53,207 @@
@end
@implementation CocoaWindowDelegate : NSObject
-- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa
+ windowCocoa:(GHOST_WindowCocoa *)winCocoa
{
- systemCocoa = sysCocoa;
- associatedWindow = winCocoa;
+ systemCocoa = sysCocoa;
+ associatedWindow = winCocoa;
}
- (void)windowDidBecomeKey:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow);
- // work around for broken appswitching when combining cmd-tab and missioncontrol
- [(NSWindow*)associatedWindow->getOSWindow() orderFrontRegardless];
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow);
+ // work around for broken appswitching when combining cmd-tab and missioncontrol
+ [(NSWindow *)associatedWindow->getOSWindow() orderFrontRegardless];
}
- (void)windowDidResignKey:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
}
- (void)windowDidExpose:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
}
- (void)windowDidMove:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow);
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow);
}
- (void)windowWillMove:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow);
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowMove, associatedWindow);
}
- (void)windowWillEnterFullScreen:(NSNotification *)notification
{
- associatedWindow->setImmediateDraw(true);
+ associatedWindow->setImmediateDraw(true);
}
- (void)windowDidEnterFullScreen:(NSNotification *)notification
{
- associatedWindow->setImmediateDraw(false);
+ associatedWindow->setImmediateDraw(false);
}
- (void)windowWillExitFullScreen:(NSNotification *)notification
{
- associatedWindow->setImmediateDraw(true);
+ associatedWindow->setImmediateDraw(true);
}
- (void)windowDidExitFullScreen:(NSNotification *)notification
{
- associatedWindow->setImmediateDraw(false);
+ associatedWindow->setImmediateDraw(false);
}
- (void)windowDidResize:(NSNotification *)notification
{
- //if (![[notification object] inLiveResize]) {
- //Send event only once, at end of resize operation (when user has released mouse button)
- systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
- //}
- /* Live resize, send event, gets handled in wm_window.c. Needed because live resize runs in a modal loop, not letting main loop run */
- if ([[notification object] inLiveResize]) {
- systemCocoa->dispatchEvents();
- }
+ //if (![[notification object] inLiveResize]) {
+ //Send event only once, at end of resize operation (when user has released mouse button)
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
+ //}
+ /* Live resize, send event, gets handled in wm_window.c. Needed because live resize runs in a modal loop, not letting main loop run */
+ if ([[notification object] inLiveResize]) {
+ systemCocoa->dispatchEvents();
+ }
}
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventNativeResolutionChange, associatedWindow);
+ systemCocoa->handleWindowEvent(GHOST_kEventNativeResolutionChange, associatedWindow);
}
- (BOOL)windowShouldClose:(id)sender;
{
- //Let Blender close the window rather than closing immediately
- systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
- return false;
+ //Let Blender close the window rather than closing immediately
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
+ return false;
}
@end
#pragma mark NSWindow subclass
//We need to subclass it to tell that even borderless (fullscreen), it can become key (receive user events)
-@interface CocoaWindow: NSWindow
+@interface CocoaWindow : NSWindow
{
- GHOST_SystemCocoa *systemCocoa;
- GHOST_WindowCocoa *associatedWindow;
- GHOST_TDragnDropTypes m_draggedObjectType;
+ GHOST_SystemCocoa *systemCocoa;
+ GHOST_WindowCocoa *associatedWindow;
+ GHOST_TDragnDropTypes m_draggedObjectType;
}
-- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
-- (GHOST_SystemCocoa*)systemCocoa;
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa
+ windowCocoa:(GHOST_WindowCocoa *)winCocoa;
+- (GHOST_SystemCocoa *)systemCocoa;
@end
@implementation CocoaWindow
-- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa
+ windowCocoa:(GHOST_WindowCocoa *)winCocoa
{
- systemCocoa = sysCocoa;
- associatedWindow = winCocoa;
+ systemCocoa = sysCocoa;
+ associatedWindow = winCocoa;
}
-- (GHOST_SystemCocoa*)systemCocoa
+- (GHOST_SystemCocoa *)systemCocoa
{
- return systemCocoa;
+ return systemCocoa;
}
--(BOOL)canBecomeKeyWindow
+- (BOOL)canBecomeKeyWindow
{
- return YES;
+ return YES;
}
//The drag'n'drop dragging destination methods
-- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender
-{
- NSPoint mouseLocation = [sender draggingLocation];
- NSPasteboard *draggingPBoard = [sender draggingPasteboard];
-
- if ([[draggingPBoard types] containsObject:NSTIFFPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeBitmap;
- else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeFilenames;
- else if ([[draggingPBoard types] containsObject:NSStringPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeString;
- else return NSDragOperationNone;
-
- associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default
- systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil);
- return NSDragOperationCopy;
+- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
+{
+ NSPoint mouseLocation = [sender draggingLocation];
+ NSPasteboard *draggingPBoard = [sender draggingPasteboard];
+
+ if ([[draggingPBoard types] containsObject:NSTIFFPboardType])
+ m_draggedObjectType = GHOST_kDragnDropTypeBitmap;
+ else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType])
+ m_draggedObjectType = GHOST_kDragnDropTypeFilenames;
+ else if ([[draggingPBoard types] containsObject:NSStringPboardType])
+ m_draggedObjectType = GHOST_kDragnDropTypeString;
+ else
+ return NSDragOperationNone;
+
+ associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default
+ systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered,
+ m_draggedObjectType,
+ associatedWindow,
+ mouseLocation.x,
+ mouseLocation.y,
+ nil);
+ return NSDragOperationCopy;
}
- (BOOL)wantsPeriodicDraggingUpdates
{
- return NO; //No need to overflow blender event queue. Events shall be sent only on changes
+ return NO; //No need to overflow blender event queue. Events shall be sent only on changes
}
-- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
+- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{
- NSPoint mouseLocation = [sender draggingLocation];
+ NSPoint mouseLocation = [sender draggingLocation];
- systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil);
- return associatedWindow->canAcceptDragOperation() ? NSDragOperationCopy : NSDragOperationNone;
+ systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated,
+ m_draggedObjectType,
+ associatedWindow,
+ mouseLocation.x,
+ mouseLocation.y,
+ nil);
+ return associatedWindow->canAcceptDragOperation() ? NSDragOperationCopy : NSDragOperationNone;
}
-- (void)draggingExited:(id < NSDraggingInfo >)sender
+- (void)draggingExited:(id<NSDraggingInfo>)sender
{
- systemCocoa->handleDraggingEvent(GHOST_kEventDraggingExited, m_draggedObjectType, associatedWindow, 0, 0, nil);
- m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+ systemCocoa->handleDraggingEvent(
+ GHOST_kEventDraggingExited, m_draggedObjectType, associatedWindow, 0, 0, nil);
+ m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
}
-- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
+- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender
{
- if (associatedWindow->canAcceptDragOperation())
- return YES;
- else
- return NO;
+ if (associatedWindow->canAcceptDragOperation())
+ return YES;
+ else
+ return NO;
}
-- (BOOL)performDragOperation:(id < NSDraggingInfo >)sender
+- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
- NSPoint mouseLocation = [sender draggingLocation];
- NSPasteboard *draggingPBoard = [sender draggingPasteboard];
- NSImage *droppedImg;
- id data;
+ NSPoint mouseLocation = [sender draggingLocation];
+ NSPasteboard *draggingPBoard = [sender draggingPasteboard];
+ NSImage *droppedImg;
+ id data;
- switch (m_draggedObjectType) {
- case GHOST_kDragnDropTypeBitmap:
- if ([NSImage canInitWithPasteboard:draggingPBoard]) {
- droppedImg = [[NSImage alloc]initWithPasteboard:draggingPBoard];
- data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType];
- }
- else return NO;
- break;
- case GHOST_kDragnDropTypeFilenames:
- data = [draggingPBoard propertyListForType:NSFilenamesPboardType];
- break;
- case GHOST_kDragnDropTypeString:
- data = [draggingPBoard stringForType:NSStringPboardType];
- break;
- default:
- return NO;
- break;
- }
- systemCocoa->handleDraggingEvent(GHOST_kEventDraggingDropDone, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, (void*)data);
- return YES;
+ switch (m_draggedObjectType) {
+ case GHOST_kDragnDropTypeBitmap:
+ if ([NSImage canInitWithPasteboard:draggingPBoard]) {
+ droppedImg = [[NSImage alloc] initWithPasteboard:draggingPBoard];
+ data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType];
+ }
+ else
+ return NO;
+ break;
+ case GHOST_kDragnDropTypeFilenames:
+ data = [draggingPBoard propertyListForType:NSFilenamesPboardType];
+ break;
+ case GHOST_kDragnDropTypeString:
+ data = [draggingPBoard stringForType:NSStringPboardType];
+ break;
+ default:
+ return NO;
+ break;
+ }
+ systemCocoa->handleDraggingEvent(GHOST_kEventDraggingDropDone,
+ m_draggedObjectType,
+ associatedWindow,
+ mouseLocation.x,
+ mouseLocation.y,
+ (void *)data);
+ return YES;
}
@end
@@ -238,204 +262,204 @@
//We need to subclass it in order to give Cocoa the feeling key events are trapped
@interface CocoaOpenGLView : NSOpenGLView <NSTextInput>
{
- GHOST_SystemCocoa *systemCocoa;
- GHOST_WindowCocoa *associatedWindow;
+ GHOST_SystemCocoa *systemCocoa;
+ GHOST_WindowCocoa *associatedWindow;
- bool composing;
- NSString *composing_text;
+ bool composing;
+ NSString *composing_text;
- bool immediate_draw;
+ bool immediate_draw;
}
-- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa
+ windowCocoa:(GHOST_WindowCocoa *)winCocoa;
@end
@implementation CocoaOpenGLView
-- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa
+ windowCocoa:(GHOST_WindowCocoa *)winCocoa
{
- systemCocoa = sysCocoa;
- associatedWindow = winCocoa;
+ systemCocoa = sysCocoa;
+ associatedWindow = winCocoa;
- composing = false;
- composing_text = nil;
+ composing = false;
+ composing_text = nil;
- immediate_draw = false;
+ immediate_draw = false;
}
- (BOOL)acceptsFirstResponder
{
- return YES;
+ return YES;
}
// The trick to prevent Cocoa from complaining (beeping)
- (void)keyDown:(NSEvent *)event
{
- systemCocoa->handleKeyEvent(event);
+ systemCocoa->handleKeyEvent(event);
- /* Start or continue composing? */
- if ([[event characters] length] == 0 ||
- [[event charactersIgnoringModifiers] length] == 0 ||
- composing)
- {
- composing = YES;
+ /* Start or continue composing? */
+ if ([[event characters] length] == 0 || [[event charactersIgnoringModifiers] length] == 0 ||
+ composing) {
+ composing = YES;
- // interpret event to call insertText
- NSMutableArray *events;
- events = [[NSMutableArray alloc] initWithCapacity:1];
- [events addObject:event];
- [self interpretKeyEvents:events]; // calls insertText
- [events removeObject:event];
- [events release];
- return;
- }
+ // interpret event to call insertText
+ NSMutableArray *events;
+ events = [[NSMutableArray alloc] initWithCapacity:1];
+ [events addObject:event];
+ [self interpretKeyEvents:events]; // calls insertText
+ [events removeObject:event];
+ [events release];
+ return;
+ }
}
- (void)keyUp:(NSEvent *)event
{
- systemCocoa->handleKeyEvent(event);
+ systemCocoa->handleKeyEvent(event);
}
- (void)flagsChanged:(NSEvent *)event
{
- systemCocoa->handleKeyEvent(event);
+ systemCocoa->handleKeyEvent(event);
}
- (void)mouseDown:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)mouseUp:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)rightMouseDown:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)rightMouseUp:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)mouseMoved:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)mouseDragged:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)rightMouseDragged:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)scrollWheel:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)otherMouseDown:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)otherMouseUp:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)otherMouseDragged:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)magnifyWithEvent:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)rotateWithEvent:(NSEvent *)event
{
- systemCocoa->handleMouseEvent(event);
+ systemCocoa->handleMouseEvent(event);
}
- (void)tabletPoint:(NSEvent *)event
{
- systemCocoa->handleTabletEvent(event,[event type]);
+ systemCocoa->handleTabletEvent(event, [event type]);
}
- (void)tabletProximity:(NSEvent *)event
{
- systemCocoa->handleTabletEvent(event,[event type]);
+ systemCocoa->handleTabletEvent(event, [event type]);
}
- (BOOL)isOpaque
{
- return YES;
+ return YES;
}
-- (void) drawRect:(NSRect)rect
+- (void)drawRect:(NSRect)rect
{
- if ([self inLiveResize]) {
- /* Don't redraw while in live resize */
- }
- else {
- [super drawRect:rect];
- systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
+ if ([self inLiveResize]) {
+ /* Don't redraw while in live resize */
+ }
+ else {
+ [super drawRect:rect];
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
- /* For some cases like entering fullscreen we need to redraw immediately
- * so our window does not show blank during the animation */
- if (associatedWindow->getImmediateDraw())
- systemCocoa->dispatchEvents();
- }
+ /* For some cases like entering fullscreen we need to redraw immediately
+ * so our window does not show blank during the animation */
+ if (associatedWindow->getImmediateDraw())
+ systemCocoa->dispatchEvents();
+ }
}
// Text input
- (void)composing_free
{
- composing = NO;
+ composing = NO;
- if (composing_text) {
- [composing_text release];
- composing_text = nil;
- }
+ if (composing_text) {
+ [composing_text release];
+ composing_text = nil;
+ }
}
- (void)insertText:(id)chars
{
- [self composing_free];
+ [self composing_free];
}
- (void)setMarkedText:(id)chars selectedRange:(NSRange)range
{
- [self composing_free];
- if ([chars length] == 0)
- return;
+ [self composing_free];
+ if ([chars length] == 0)
+ return;
- // start composing
- composing = YES;
- composing_text = [chars copy];
+ // start composing
+ composing = YES;
+ composing_text = [chars copy];
- // if empty, cancel
- if ([composing_text length] == 0)
- [self composing_free];
+ // if empty, cancel
+ if ([composing_text length] == 0)
+ [self composing_free];
}
- (void)unmarkText
{
- [self composing_free];
+ [self composing_free];
}
- (BOOL)hasMarkedText
{
- return (composing) ? YES : NO;
+ return (composing) ? YES : NO;
}
- (void)doCommandBySelector:(SEL)selector
@@ -444,457 +468,463 @@
- (BOOL)isComposing
{
- return composing;
+ return composing;
}
- (NSInteger)conversationIdentifier
{
- return (NSInteger)self;
+ return (NSInteger)self;
}
- (NSAttributedString *)attributedSubstringFromRange:(NSRange)range
{
- return [NSAttributedString new]; // XXX does this leak?
+ return [NSAttributedString new]; // XXX does this leak?
}
- (NSRange)markedRange
{
- unsigned int length = (composing_text) ? [composing_text length] : 0;
+ unsigned int length = (composing_text) ? [composing_text length] : 0;
- if (composing)
- return NSMakeRange(0, length);
+ if (composing)
+ return NSMakeRange(0, length);
- return NSMakeRange(NSNotFound, 0);
+ return NSMakeRange(NSNotFound, 0);
}
- (NSRange)selectedRange
{
- unsigned int length = (composing_text) ? [composing_text length] : 0;
- return NSMakeRange(0, length);
+ unsigned int length = (composing_text) ? [composing_text length] : 0;
+ return NSMakeRange(0, length);
}
- (NSRect)firstRectForCharacterRange:(NSRange)range
{
- return NSZeroRect;
+ return NSZeroRect;
}
- (NSUInteger)characterIndexForPoint:(NSPoint)point
{
- return NSNotFound;
+ return NSNotFound;
}
-- (NSArray*)validAttributesForMarkedText
+- (NSArray *)validAttributesForMarkedText
{
- return [NSArray array]; // XXX does this leak?
+ return [NSArray array]; // XXX does this leak?
}
@end
#pragma mark initialization / finalization
-GHOST_WindowCocoa::GHOST_WindowCocoa(
- GHOST_SystemCocoa *systemCocoa,
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 bottom,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- const bool stereoVisual, const GHOST_TUns16 numOfAASamples, bool is_debug
-) :
- GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples),
- m_customCursor(0),
- m_debug_context(is_debug)
+GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 bottom,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples,
+ bool is_debug)
+ : GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples),
+ m_customCursor(0),
+ m_debug_context(is_debug)
{
- m_systemCocoa = systemCocoa;
- m_fullScreen = false;
- m_immediateDraw = false;
+ m_systemCocoa = systemCocoa;
+ m_fullScreen = false;
+ m_immediateDraw = false;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- //Creates the window
- NSRect rect;
- NSSize minSize;
+ //Creates the window
+ NSRect rect;
+ NSSize minSize;
- rect.origin.x = left;
- rect.origin.y = bottom;
- rect.size.width = width;
- rect.size.height = height;
+ rect.origin.x = left;
+ rect.origin.y = bottom;
+ rect.size.width = width;
+ rect.size.height = height;
- m_window = [[CocoaWindow alloc] initWithContentRect:rect
- styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask
- backing:NSBackingStoreBuffered defer:NO];
+ m_window = [[CocoaWindow alloc]
+ initWithContentRect:rect
+ styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask |
+ NSMiniaturizableWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO];
- if (m_window == nil) {
- [pool drain];
- return;
- }
+ if (m_window == nil) {
+ [pool drain];
+ return;
+ }
- [m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
+ [m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
- //Forbid to resize the window below the blender defined minimum one
- minSize.width = 320;
- minSize.height = 240;
- [m_window setContentMinSize:minSize];
+ //Forbid to resize the window below the blender defined minimum one
+ minSize.width = 320;
+ minSize.height = 240;
+ [m_window setContentMinSize:minSize];
- //Creates the OpenGL View inside the window
- m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect];
+ //Creates the OpenGL View inside the window
+ m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect];
- if (m_systemCocoa->m_nativePixel) {
- // Needs to happen early when building with the 10.14 SDK, otherwise
- // has no effect until resizeing the window.
- if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
- [m_openGLView setWantsBestResolutionOpenGLSurface:YES];
- }
- }
+ if (m_systemCocoa->m_nativePixel) {
+ // Needs to happen early when building with the 10.14 SDK, otherwise
+ // has no effect until resizeing the window.
+ if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ [m_openGLView setWantsBestResolutionOpenGLSurface:YES];
+ }
+ }
- [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
+ [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
- [m_window setContentView:m_openGLView];
- [m_window setInitialFirstResponder:m_openGLView];
+ [m_window setContentView:m_openGLView];
+ [m_window setInitialFirstResponder:m_openGLView];
- [m_window makeKeyAndOrderFront:nil];
+ [m_window makeKeyAndOrderFront:nil];
- setDrawingContextType(type);
- updateDrawingContext();
- activateDrawingContext();
+ setDrawingContextType(type);
+ updateDrawingContext();
+ activateDrawingContext();
- setTitle(title);
+ setTitle(title);
- m_tablet.Active = GHOST_kTabletModeNone;
+ m_tablet.Active = GHOST_kTabletModeNone;
- CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init];
- [windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
- [m_window setDelegate:windowDelegate];
+ CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init];
+ [windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
+ [m_window setDelegate:windowDelegate];
- [m_window setAcceptsMouseMovedEvents:YES];
+ [m_window setAcceptsMouseMovedEvents:YES];
- NSView *view = [m_window contentView];
- [view setAcceptsTouchEvents:YES];
+ NSView *view = [m_window contentView];
+ [view setAcceptsTouchEvents:YES];
- [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
- NSStringPboardType, NSTIFFPboardType, nil]];
+ [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
+ NSStringPboardType,
+ NSTIFFPboardType,
+ nil]];
- if (state != GHOST_kWindowStateFullScreen) {
- [m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
- }
+ if (state != GHOST_kWindowStateFullScreen) {
+ [m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+ }
- if (state == GHOST_kWindowStateFullScreen)
- setState(GHOST_kWindowStateFullScreen);
+ if (state == GHOST_kWindowStateFullScreen)
+ setState(GHOST_kWindowStateFullScreen);
- setNativePixelSize();
+ setNativePixelSize();
- [pool drain];
+ [pool drain];
}
-
GHOST_WindowCocoa::~GHOST_WindowCocoa()
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if (m_customCursor) {
- [m_customCursor release];
- m_customCursor = nil;
- }
+ if (m_customCursor) {
+ [m_customCursor release];
+ m_customCursor = nil;
+ }
- releaseNativeHandles();
+ releaseNativeHandles();
- [m_openGLView release];
+ [m_openGLView release];
- if (m_window) {
- [m_window close];
- }
+ if (m_window) {
+ [m_window close];
+ }
- // Check for other blender opened windows and make the frontmost key
- // Note: for some reason the closed window is still in the list
- NSArray *windowsList = [NSApp orderedWindows];
- for (int a = 0; a < [windowsList count]; a++) {
- if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) {
- [[windowsList objectAtIndex:a] makeKeyWindow];
- break;
- }
- }
- m_window = nil;
+ // Check for other blender opened windows and make the frontmost key
+ // Note: for some reason the closed window is still in the list
+ NSArray *windowsList = [NSApp orderedWindows];
+ for (int a = 0; a < [windowsList count]; a++) {
+ if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) {
+ [[windowsList objectAtIndex:a] makeKeyWindow];
+ break;
+ }
+ }
+ m_window = nil;
- [pool drain];
+ [pool drain];
}
#pragma mark accessors
bool GHOST_WindowCocoa::getValid() const
{
- return GHOST_Window::getValid() && m_window != NULL && m_openGLView != NULL;
+ return GHOST_Window::getValid() && m_window != NULL && m_openGLView != NULL;
}
-void* GHOST_WindowCocoa::getOSWindow() const
+void *GHOST_WindowCocoa::getOSWindow() const
{
- return (void*)m_window;
+ return (void *)m_window;
}
-void GHOST_WindowCocoa::setTitle(const STR_String& title)
+void GHOST_WindowCocoa::setTitle(const STR_String &title)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding];
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid");
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- //Set associated file if applicable
- if (windowTitle && [windowTitle hasPrefix:@"Blender"]) {
- NSRange fileStrRange;
- NSString *associatedFileName;
- int len;
+ NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding];
- fileStrRange.location = [windowTitle rangeOfString:@"["].location+1;
- len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location;
+ //Set associated file if applicable
+ if (windowTitle && [windowTitle hasPrefix:@"Blender"]) {
+ NSRange fileStrRange;
+ NSString *associatedFileName;
+ int len;
- if (len > 0) {
- fileStrRange.length = len;
- associatedFileName = [windowTitle substringWithRange:fileStrRange];
- [m_window setTitle:[associatedFileName lastPathComponent]];
+ fileStrRange.location = [windowTitle rangeOfString:@"["].location + 1;
+ len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location;
- //Blender used file open/save functions converte file names into legal URL ones
- associatedFileName = [associatedFileName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- @try {
- [m_window setRepresentedFilename:associatedFileName];
- }
- @catch (NSException * e) {
- printf("\nInvalid file path given in window title");
- }
- }
- else {
- [m_window setTitle:windowTitle];
- [m_window setRepresentedFilename:@""];
- }
+ if (len > 0) {
+ fileStrRange.length = len;
+ associatedFileName = [windowTitle substringWithRange:fileStrRange];
+ [m_window setTitle:[associatedFileName lastPathComponent]];
- }
- else {
- [m_window setTitle:windowTitle];
- [m_window setRepresentedFilename:@""];
- }
+ //Blender used file open/save functions converte file names into legal URL ones
+ associatedFileName = [associatedFileName
+ stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+ @try {
+ [m_window setRepresentedFilename:associatedFileName];
+ }
+ @catch (NSException *e) {
+ printf("\nInvalid file path given in window title");
+ }
+ }
+ else {
+ [m_window setTitle:windowTitle];
+ [m_window setRepresentedFilename:@""];
+ }
+ }
+ else {
+ [m_window setTitle:windowTitle];
+ [m_window setRepresentedFilename:@""];
+ }
-
- [windowTitle release];
- [pool drain];
+ [windowTitle release];
+ [pool drain];
}
-
-void GHOST_WindowCocoa::getTitle(STR_String& title) const
+void GHOST_WindowCocoa::getTitle(STR_String &title) const
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid");
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSString *windowTitle = [m_window title];
+ NSString *windowTitle = [m_window title];
- if (windowTitle != nil) {
- title = [windowTitle UTF8String];
- }
+ if (windowTitle != nil) {
+ title = [windowTitle UTF8String];
+ }
- [pool drain];
+ [pool drain];
}
-
-void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
+void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect &bounds) const
{
- NSRect rect;
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid");
+ NSRect rect;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSRect screenSize = [[m_window screen] visibleFrame];
+ NSRect screenSize = [[m_window screen] visibleFrame];
- rect = [m_window frame];
+ rect = [m_window frame];
- bounds.m_b = screenSize.size.height - (rect.origin.y -screenSize.origin.y);
- bounds.m_l = rect.origin.x -screenSize.origin.x;
- bounds.m_r = rect.origin.x-screenSize.origin.x + rect.size.width;
- bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height -screenSize.origin.y);
+ bounds.m_b = screenSize.size.height - (rect.origin.y - screenSize.origin.y);
+ bounds.m_l = rect.origin.x - screenSize.origin.x;
+ bounds.m_r = rect.origin.x - screenSize.origin.x + rect.size.width;
+ bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height - screenSize.origin.y);
- [pool drain];
+ [pool drain];
}
-
-void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
+void GHOST_WindowCocoa::getClientBounds(GHOST_Rect &bounds) const
{
- NSRect rect;
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid");
+ NSRect rect;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSRect screenSize = [[m_window screen] visibleFrame];
+ NSRect screenSize = [[m_window screen] visibleFrame];
- //Max window contents as screen size (excluding title bar...)
- NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize
- styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
+ //Max window contents as screen size (excluding title bar...)
+ NSRect contentRect = [CocoaWindow
+ contentRectForFrameRect:screenSize
+ styleMask:(NSTitledWindowMask | NSClosableWindowMask |
+ NSMiniaturizableWindowMask | NSResizableWindowMask)];
- rect = [m_window contentRectForFrameRect:[m_window frame]];
+ rect = [m_window contentRectForFrameRect:[m_window frame]];
- bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y);
- bounds.m_l = rect.origin.x -contentRect.origin.x;
- bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width;
- bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y);
- [pool drain];
+ bounds.m_b = contentRect.size.height - (rect.origin.y - contentRect.origin.y);
+ bounds.m_l = rect.origin.x - contentRect.origin.x;
+ bounds.m_r = rect.origin.x - contentRect.origin.x + rect.size.width;
+ bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height - contentRect.origin.y);
+ [pool drain];
}
-
GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_Rect cBnds, wBnds;
- getClientBounds(cBnds);
- if (((GHOST_TUns32)cBnds.getWidth()) != width) {
- NSSize size;
- size.width=width;
- size.height=cBnds.getHeight();
- [m_window setContentSize:size];
- }
- [pool drain];
- return GHOST_kSuccess;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid");
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (((GHOST_TUns32)cBnds.getWidth()) != width) {
+ NSSize size;
+ size.width = width;
+ size.height = cBnds.getHeight();
+ [m_window setContentSize:size];
+ }
+ [pool drain];
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_Rect cBnds, wBnds;
- getClientBounds(cBnds);
- if (((GHOST_TUns32)cBnds.getHeight()) != height) {
- NSSize size;
- size.width=cBnds.getWidth();
- size.height=height;
- [m_window setContentSize:size];
- }
- [pool drain];
- return GHOST_kSuccess;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid");
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (((GHOST_TUns32)cBnds.getHeight()) != height) {
+ NSSize size;
+ size.width = cBnds.getWidth();
+ size.height = height;
+ [m_window setContentSize:size];
+ }
+ [pool drain];
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_Rect cBnds, wBnds;
- getClientBounds(cBnds);
- if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
- (((GHOST_TUns32)cBnds.getHeight()) != height))
- {
- NSSize size;
- size.width=width;
- size.height=height;
- [m_window setContentSize:size];
- }
- [pool drain];
- return GHOST_kSuccess;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid");
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
+ (((GHOST_TUns32)cBnds.getHeight()) != height)) {
+ NSSize size;
+ size.width = width;
+ size.height = height;
+ [m_window setContentSize:size];
+ }
+ [pool drain];
+ return GHOST_kSuccess;
}
-
GHOST_TWindowState GHOST_WindowCocoa::getState() const
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_TWindowState state;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid");
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GHOST_TWindowState state;
- NSUInteger masks = [m_window styleMask];
+ NSUInteger masks = [m_window styleMask];
- if (masks & NSFullScreenWindowMask) {
- // Lion style fullscreen
- if (!m_immediateDraw) {
- state = GHOST_kWindowStateFullScreen;
- }
- else {
- state = GHOST_kWindowStateNormal;
- }
- }
- else if ([m_window isMiniaturized]) {
- state = GHOST_kWindowStateMinimized;
- }
- else if ([m_window isZoomed]) {
- state = GHOST_kWindowStateMaximized;
- }
- else {
- if (m_immediateDraw) {
- state = GHOST_kWindowStateFullScreen;
- }
- else {
- state = GHOST_kWindowStateNormal;
- }
- }
- [pool drain];
- return state;
+ if (masks & NSFullScreenWindowMask) {
+ // Lion style fullscreen
+ if (!m_immediateDraw) {
+ state = GHOST_kWindowStateFullScreen;
+ }
+ else {
+ state = GHOST_kWindowStateNormal;
+ }
+ }
+ else if ([m_window isMiniaturized]) {
+ state = GHOST_kWindowStateMinimized;
+ }
+ else if ([m_window isZoomed]) {
+ state = GHOST_kWindowStateMaximized;
+ }
+ else {
+ if (m_immediateDraw) {
+ state = GHOST_kWindowStateFullScreen;
+ }
+ else {
+ state = GHOST_kWindowStateNormal;
+ }
+ }
+ [pool drain];
+ return state;
}
-
-void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid");
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid");
- screenToClientIntern(inX, inY, outX, outY);
+ screenToClientIntern(inX, inY, outX, outY);
- /* switch y to match ghost convention */
- GHOST_Rect cBnds;
- getClientBounds(cBnds);
- outY = (cBnds.getHeight() - 1) - outY;
+ /* switch y to match ghost convention */
+ GHOST_Rect cBnds;
+ getClientBounds(cBnds);
+ outY = (cBnds.getHeight() - 1) - outY;
}
-
-void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid");
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid");
- /* switch y to match ghost convention */
- GHOST_Rect cBnds;
- getClientBounds(cBnds);
- inY = (cBnds.getHeight() - 1) - inY;
+ /* switch y to match ghost convention */
+ GHOST_Rect cBnds;
+ getClientBounds(cBnds);
+ inY = (cBnds.getHeight() - 1) - inY;
- clientToScreenIntern(inX, inY, outX, outY);
+ clientToScreenIntern(inX, inY, outX, outY);
}
-void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- NSRect screenCoord;
- NSRect baseCoord;
+ NSRect screenCoord;
+ NSRect baseCoord;
- screenCoord.origin.x = inX;
- screenCoord.origin.y = inY;
+ screenCoord.origin.x = inX;
+ screenCoord.origin.y = inY;
- baseCoord = [m_window convertRectFromScreen:screenCoord];
+ baseCoord = [m_window convertRectFromScreen:screenCoord];
- outX = baseCoord.origin.x;
- outY = baseCoord.origin.y;
+ outX = baseCoord.origin.x;
+ outY = baseCoord.origin.y;
}
-void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- NSRect screenCoord;
- NSRect baseCoord;
+ NSRect screenCoord;
+ NSRect baseCoord;
- baseCoord.origin.x = inX;
- baseCoord.origin.y = inY;
+ baseCoord.origin.x = inX;
+ baseCoord.origin.y = inY;
- screenCoord = [m_window convertRectToScreen:baseCoord];
+ screenCoord = [m_window convertRectToScreen:baseCoord];
- outX = screenCoord.origin.x;
- outY = screenCoord.origin.y;
+ outX = screenCoord.origin.x;
+ outY = screenCoord.origin.y;
}
-
-NSScreen* GHOST_WindowCocoa::getScreen()
+NSScreen *GHOST_WindowCocoa::getScreen()
{
- return [m_window screen];
+ return [m_window screen];
}
/* called for event, when window leaves monitor to another */
void GHOST_WindowCocoa::setNativePixelSize(void)
{
- NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
+ NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
- GHOST_Rect rect;
- getClientBounds(rect);
+ GHOST_Rect rect;
+ getClientBounds(rect);
- m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth();
+ m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth();
}
/**
@@ -906,430 +936,436 @@ void GHOST_WindowCocoa::setNativePixelSize(void)
*/
GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid");
- switch (state) {
- case GHOST_kWindowStateMinimized:
- [m_window miniaturize:nil];
- break;
- case GHOST_kWindowStateMaximized:
- [m_window zoom:nil];
- break;
-
- case GHOST_kWindowStateFullScreen:
- {
- NSUInteger masks = [m_window styleMask];
-
- if (!(masks & NSFullScreenWindowMask)) {
- [m_window toggleFullScreen:nil];
- }
- break;
- }
- case GHOST_kWindowStateNormal:
- default:
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSUInteger masks = [m_window styleMask];
-
- if (masks & NSFullScreenWindowMask) {
- // Lion style fullscreen
- [m_window toggleFullScreen:nil];
- }
- else if ([m_window isMiniaturized])
- [m_window deminiaturize:nil];
- else if ([m_window isZoomed])
- [m_window zoom:nil];
- [pool drain];
- break;
- }
-
- return GHOST_kSuccess;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid");
+ switch (state) {
+ case GHOST_kWindowStateMinimized:
+ [m_window miniaturize:nil];
+ break;
+ case GHOST_kWindowStateMaximized:
+ [m_window zoom:nil];
+ break;
+
+ case GHOST_kWindowStateFullScreen: {
+ NSUInteger masks = [m_window styleMask];
+
+ if (!(masks & NSFullScreenWindowMask)) {
+ [m_window toggleFullScreen:nil];
+ }
+ break;
+ }
+ case GHOST_kWindowStateNormal:
+ default:
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSUInteger masks = [m_window styleMask];
+
+ if (masks & NSFullScreenWindowMask) {
+ // Lion style fullscreen
+ [m_window toggleFullScreen:nil];
+ }
+ else if ([m_window isMiniaturized])
+ [m_window deminiaturize:nil];
+ else if ([m_window isZoomed])
+ [m_window zoom:nil];
+ [pool drain];
+ break;
+ }
+
+ return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_window setDocumentEdited:isUnsavedChanges];
+ [m_window setDocumentEdited:isUnsavedChanges];
- [pool drain];
- return GHOST_Window::setModifiedState(isUnsavedChanges);
+ [pool drain];
+ return GHOST_Window::setModifiedState(isUnsavedChanges);
}
-
-
GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid");
- if (order == GHOST_kWindowOrderTop) {
- [m_window makeKeyAndOrderFront:nil];
- }
- else {
- NSArray *windowsList;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid");
+ if (order == GHOST_kWindowOrderTop) {
+ [m_window makeKeyAndOrderFront:nil];
+ }
+ else {
+ NSArray *windowsList;
- [m_window orderBack:nil];
+ [m_window orderBack:nil];
- //Check for other blender opened windows and make the frontmost key
- windowsList = [NSApp orderedWindows];
- if ([windowsList count]) {
- [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
- }
- }
+ //Check for other blender opened windows and make the frontmost key
+ windowsList = [NSApp orderedWindows];
+ if ([windowsList count]) {
+ [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
+ }
+ }
- [pool drain];
- return GHOST_kSuccess;
+ [pool drain];
+ return GHOST_kSuccess;
}
#pragma mark Drawing context
GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type)
{
- if (type == GHOST_kDrawingContextTypeOpenGL) {
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
- GHOST_Context *context = new GHOST_ContextCGL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_openGLView,
+ GHOST_Context *context = new GHOST_ContextCGL(m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_openGLView,
#if defined(WITH_GL_PROFILE_CORE)
- GL_CONTEXT_CORE_PROFILE_BIT,
- 3, 3,
+ GL_CONTEXT_CORE_PROFILE_BIT,
+ 3,
+ 3,
#else
- 0, // no profile bit
- 2, 1,
+ 0, // no profile bit
+ 2,
+ 1,
#endif
- GHOST_OPENGL_CGL_CONTEXT_FLAGS,
- GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
+ GHOST_OPENGL_CGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
- }
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+ }
- return NULL;
+ return NULL;
}
#pragma mark invalidate
GHOST_TSuccess GHOST_WindowCocoa::invalidate()
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid");
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLView setNeedsDisplay:YES];
- [pool drain];
- return GHOST_kSuccess;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid");
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLView setNeedsDisplay:YES];
+ [pool drain];
+ return GHOST_kSuccess;
}
#pragma mark Progress bar
GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if ((progress >=0.0) && (progress <=1.0)) {
- NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
+ if ((progress >= 0.0) && (progress <= 1.0)) {
+ NSImage *dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128, 128)];
- [dockIcon lockFocus];
- NSRect progressBox = {{4, 4}, {120, 16}};
+ [dockIcon lockFocus];
+ NSRect progressBox = {{4, 4}, {120, 16}};
- [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
+ [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint
+ fromRect:NSZeroRect
+ operation:NSCompositeSourceOver
+ fraction:1.0];
- // Track & Outline
- [[NSColor blackColor] setFill];
- NSRectFill(progressBox);
+ // Track & Outline
+ [[NSColor blackColor] setFill];
+ NSRectFill(progressBox);
- [[NSColor whiteColor] set];
- NSFrameRect(progressBox);
+ [[NSColor whiteColor] set];
+ NSFrameRect(progressBox);
- // Progress fill
- progressBox = NSInsetRect(progressBox, 1, 1);
+ // Progress fill
+ progressBox = NSInsetRect(progressBox, 1, 1);
- progressBox.size.width = progressBox.size.width * progress;
- NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor] endingColor:[NSColor lightGrayColor]];
- [gradient drawInRect:progressBox angle:90];
- [gradient release];
+ progressBox.size.width = progressBox.size.width * progress;
+ NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor]
+ endingColor:[NSColor lightGrayColor]];
+ [gradient drawInRect:progressBox angle:90];
+ [gradient release];
- [dockIcon unlockFocus];
+ [dockIcon unlockFocus];
- [NSApp setApplicationIconImage:dockIcon];
- [dockIcon release];
+ [NSApp setApplicationIconImage:dockIcon];
+ [dockIcon release];
- m_progressBarVisible = true;
- }
+ m_progressBarVisible = true;
+ }
- [pool drain];
- return GHOST_kSuccess;
+ [pool drain];
+ return GHOST_kSuccess;
}
static void postNotification()
{
- NSUserNotification *notification = [[NSUserNotification alloc] init];
- notification.title = @"Blender progress notification";
- notification.informativeText = @"Calculation is finished";
- notification.soundName = NSUserNotificationDefaultSoundName;
- [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
- [notification release];
+ NSUserNotification *notification = [[NSUserNotification alloc] init];
+ notification.title = @"Blender progress notification";
+ notification.informativeText = @"Calculation is finished";
+ notification.soundName = NSUserNotificationDefaultSoundName;
+ [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
+ [notification release];
}
GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
{
- if (!m_progressBarVisible) return GHOST_kFailure;
- m_progressBarVisible = false;
+ if (!m_progressBarVisible)
+ return GHOST_kFailure;
+ m_progressBarVisible = false;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
- [dockIcon lockFocus];
- [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
- [dockIcon unlockFocus];
- [NSApp setApplicationIconImage:dockIcon];
+ NSImage *dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128, 128)];
+ [dockIcon lockFocus];
+ [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint
+ fromRect:NSZeroRect
+ operation:NSCompositeSourceOver
+ fraction:1.0];
+ [dockIcon unlockFocus];
+ [NSApp setApplicationIconImage:dockIcon];
- // We use notifications to inform the user when the progress reached 100%
- // Atm. just fire this when the progressbar ends, the behavior is controlled
- // in the NotificationCenter If Blender is not frontmost window, a message
- // pops up with sound, in any case an entry in notifications
- if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) {
- postNotification();
- }
+ // We use notifications to inform the user when the progress reached 100%
+ // Atm. just fire this when the progressbar ends, the behavior is controlled
+ // in the NotificationCenter If Blender is not frontmost window, a message
+ // pops up with sound, in any case an entry in notifications
+ if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) {
+ postNotification();
+ }
- [dockIcon release];
+ [dockIcon release];
- [pool drain];
- return GHOST_kSuccess;
+ [pool drain];
+ return GHOST_kSuccess;
}
#pragma mark Cursor handling
void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
{
- static bool systemCursorVisible = true;
-
- NSCursor *tmpCursor =nil;
-
- if (visible != systemCursorVisible) {
- if (visible) {
- [NSCursor unhide];
- systemCursorVisible = true;
- }
- else {
- [NSCursor hide];
- systemCursorVisible = false;
- }
- }
-
- if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
- tmpCursor = m_customCursor;
- }
- else {
- switch (cursor) {
- case GHOST_kStandardCursorDestroy:
- tmpCursor = [NSCursor disappearingItemCursor];
- break;
- case GHOST_kStandardCursorText:
- tmpCursor = [NSCursor IBeamCursor];
- break;
- case GHOST_kStandardCursorCrosshair:
- tmpCursor = [NSCursor crosshairCursor];
- break;
- case GHOST_kStandardCursorUpDown:
- tmpCursor = [NSCursor resizeUpDownCursor];
- break;
- case GHOST_kStandardCursorLeftRight:
- tmpCursor = [NSCursor resizeLeftRightCursor];
- break;
- case GHOST_kStandardCursorTopSide:
- tmpCursor = [NSCursor resizeUpCursor];
- break;
- case GHOST_kStandardCursorBottomSide:
- tmpCursor = [NSCursor resizeDownCursor];
- break;
- case GHOST_kStandardCursorLeftSide:
- tmpCursor = [NSCursor resizeLeftCursor];
- break;
- case GHOST_kStandardCursorRightSide:
- tmpCursor = [NSCursor resizeRightCursor];
- break;
- case GHOST_kStandardCursorRightArrow:
- case GHOST_kStandardCursorInfo:
- case GHOST_kStandardCursorLeftArrow:
- case GHOST_kStandardCursorHelp:
- case GHOST_kStandardCursorCycle:
- case GHOST_kStandardCursorSpray:
- case GHOST_kStandardCursorWait:
- case GHOST_kStandardCursorTopLeftCorner:
- case GHOST_kStandardCursorTopRightCorner:
- case GHOST_kStandardCursorBottomRightCorner:
- case GHOST_kStandardCursorBottomLeftCorner:
- case GHOST_kStandardCursorCopy:
- case GHOST_kStandardCursorDefault:
- default:
- tmpCursor = [NSCursor arrowCursor];
- break;
- };
- }
- [tmpCursor set];
+ static bool systemCursorVisible = true;
+
+ NSCursor *tmpCursor = nil;
+
+ if (visible != systemCursorVisible) {
+ if (visible) {
+ [NSCursor unhide];
+ systemCursorVisible = true;
+ }
+ else {
+ [NSCursor hide];
+ systemCursorVisible = false;
+ }
+ }
+
+ if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
+ tmpCursor = m_customCursor;
+ }
+ else {
+ switch (cursor) {
+ case GHOST_kStandardCursorDestroy:
+ tmpCursor = [NSCursor disappearingItemCursor];
+ break;
+ case GHOST_kStandardCursorText:
+ tmpCursor = [NSCursor IBeamCursor];
+ break;
+ case GHOST_kStandardCursorCrosshair:
+ tmpCursor = [NSCursor crosshairCursor];
+ break;
+ case GHOST_kStandardCursorUpDown:
+ tmpCursor = [NSCursor resizeUpDownCursor];
+ break;
+ case GHOST_kStandardCursorLeftRight:
+ tmpCursor = [NSCursor resizeLeftRightCursor];
+ break;
+ case GHOST_kStandardCursorTopSide:
+ tmpCursor = [NSCursor resizeUpCursor];
+ break;
+ case GHOST_kStandardCursorBottomSide:
+ tmpCursor = [NSCursor resizeDownCursor];
+ break;
+ case GHOST_kStandardCursorLeftSide:
+ tmpCursor = [NSCursor resizeLeftCursor];
+ break;
+ case GHOST_kStandardCursorRightSide:
+ tmpCursor = [NSCursor resizeRightCursor];
+ break;
+ case GHOST_kStandardCursorRightArrow:
+ case GHOST_kStandardCursorInfo:
+ case GHOST_kStandardCursorLeftArrow:
+ case GHOST_kStandardCursorHelp:
+ case GHOST_kStandardCursorCycle:
+ case GHOST_kStandardCursorSpray:
+ case GHOST_kStandardCursorWait:
+ case GHOST_kStandardCursorTopLeftCorner:
+ case GHOST_kStandardCursorTopRightCorner:
+ case GHOST_kStandardCursorBottomRightCorner:
+ case GHOST_kStandardCursorBottomLeftCorner:
+ case GHOST_kStandardCursorCopy:
+ case GHOST_kStandardCursorDefault:
+ default:
+ tmpCursor = [NSCursor arrowCursor];
+ break;
+ };
+ }
+ [tmpCursor set];
}
-
-
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if ([m_window isVisible]) {
- loadCursor(visible, getCursorShape());
- }
+ if ([m_window isVisible]) {
+ loadCursor(visible, getCursorShape());
+ }
- [pool drain];
- return GHOST_kSuccess;
+ [pool drain];
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
{
- GHOST_TSuccess err = GHOST_kSuccess;
+ GHOST_TSuccess err = GHOST_kSuccess;
- if (mode != GHOST_kGrabDisable) {
- //No need to perform grab without warp as it is always on in OS X
- if (mode != GHOST_kGrabNormal) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ if (mode != GHOST_kGrabDisable) {
+ //No need to perform grab without warp as it is always on in OS X
+ if (mode != GHOST_kGrabNormal) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
- setCursorGrabAccum(0, 0);
+ m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ setCursorGrabAccum(0, 0);
- if (mode == GHOST_kGrabHide) {
- setWindowCursorVisibility(false);
- }
+ if (mode == GHOST_kGrabHide) {
+ setWindowCursorVisibility(false);
+ }
- //Make window key if it wasn't to get the mouse move events
- [m_window makeKeyWindow];
+ //Make window key if it wasn't to get the mouse move events
+ [m_window makeKeyWindow];
- [pool drain];
- }
- }
- else {
- if (m_cursorGrab==GHOST_kGrabHide) {
- m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
- setWindowCursorVisibility(true);
- }
+ [pool drain];
+ }
+ }
+ else {
+ if (m_cursorGrab == GHOST_kGrabHide) {
+ m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ setWindowCursorVisibility(true);
+ }
- /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
- setCursorGrabAccum(0, 0);
- m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
- }
- return err;
+ /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
+ setCursorGrabAccum(0, 0);
+ m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
+ }
+ return err;
}
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if (m_customCursor) {
- [m_customCursor release];
- m_customCursor = nil;
- }
+ if (m_customCursor) {
+ [m_customCursor release];
+ m_customCursor = nil;
+ }
- if ([m_window isVisible]) {
- loadCursor(getCursorVisibility(), shape);
- }
+ if ([m_window isVisible]) {
+ loadCursor(getCursorVisibility(), shape);
+ }
- [pool drain];
- return GHOST_kSuccess;
+ [pool drain];
+ return GHOST_kSuccess;
}
/** Reverse the bits in a GHOST_TUns8
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{
- ch= ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA);
- ch= ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC);
- ch= ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0);
- return ch;
+ ch= ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA);
+ ch= ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC);
+ ch= ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0);
+ return ch;
}
*/
-
/** Reverse the bits in a GHOST_TUns16 */
static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
{
- shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA);
- shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC);
- shrt = ((shrt >> 4) & 0x0F0F) | ((shrt << 4) & 0xF0F0);
- shrt = ((shrt >> 8) & 0x00FF) | ((shrt << 8) & 0xFF00);
- return shrt;
-}
-
-GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
- int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color)
-{
- int y,nbUns16;
- NSPoint hotSpotPoint;
- NSBitmapImageRep *cursorImageRep;
- NSImage *cursorImage;
- NSSize imSize;
- GHOST_TUns16 *cursorBitmap;
-
-
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- if (m_customCursor) {
- [m_customCursor release];
- m_customCursor = nil;
- }
-
-
- cursorImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
- pixelsWide:sizex
- pixelsHigh:sizey
- bitsPerSample:1
- samplesPerPixel:2
- hasAlpha:YES
- isPlanar:YES
- colorSpaceName:NSDeviceWhiteColorSpace
- bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0))
- bitsPerPixel:1];
-
-
- cursorBitmap = (GHOST_TUns16*)[cursorImageRep bitmapData];
- nbUns16 = [cursorImageRep bytesPerPlane]/2;
-
- for (y=0; y<nbUns16; y++) {
+ shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA);
+ shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC);
+ shrt = ((shrt >> 4) & 0x0F0F) | ((shrt << 4) & 0xF0F0);
+ shrt = ((shrt >> 8) & 0x00FF) | ((shrt << 8) & 0xFF00);
+ return shrt;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color)
+{
+ int y, nbUns16;
+ NSPoint hotSpotPoint;
+ NSBitmapImageRep *cursorImageRep;
+ NSImage *cursorImage;
+ NSSize imSize;
+ GHOST_TUns16 *cursorBitmap;
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ if (m_customCursor) {
+ [m_customCursor release];
+ m_customCursor = nil;
+ }
+
+ cursorImageRep = [[NSBitmapImageRep alloc]
+ initWithBitmapDataPlanes:nil
+ pixelsWide:sizex
+ pixelsHigh:sizey
+ bitsPerSample:1
+ samplesPerPixel:2
+ hasAlpha:YES
+ isPlanar:YES
+ colorSpaceName:NSDeviceWhiteColorSpace
+ bytesPerRow:(sizex / 8 + (sizex % 8 > 0 ? 1 : 0))
+ bitsPerPixel:1];
+
+ cursorBitmap = (GHOST_TUns16 *)[cursorImageRep bitmapData];
+ nbUns16 = [cursorImageRep bytesPerPlane] / 2;
+
+ for (y = 0; y < nbUns16; y++) {
#if !defined(__LITTLE_ENDIAN__)
- cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
- cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
+ cursorBitmap[y] = ~uns16ReverseBits((bitmap[2 * y] << 0) | (bitmap[2 * y + 1] << 8));
+ cursorBitmap[nbUns16 + y] = uns16ReverseBits((mask[2 * y] << 0) | (mask[2 * y + 1] << 8));
#else
- cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
- cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
+ cursorBitmap[y] = ~uns16ReverseBits((bitmap[2 * y + 1] << 0) | (bitmap[2 * y] << 8));
+ cursorBitmap[nbUns16 + y] = uns16ReverseBits((mask[2 * y + 1] << 0) | (mask[2 * y] << 8));
#endif
+ }
- }
-
-
- imSize.width = sizex;
- imSize.height= sizey;
- cursorImage = [[NSImage alloc] initWithSize:imSize];
- [cursorImage addRepresentation:cursorImageRep];
+ imSize.width = sizex;
+ imSize.height = sizey;
+ cursorImage = [[NSImage alloc] initWithSize:imSize];
+ [cursorImage addRepresentation:cursorImageRep];
- hotSpotPoint.x = hotX;
- hotSpotPoint.y = hotY;
+ hotSpotPoint.x = hotX;
+ hotSpotPoint.y = hotY;
- //foreground and background color parameter is not handled for now (10.6)
- m_customCursor = [[NSCursor alloc] initWithImage:cursorImage
- hotSpot:hotSpotPoint];
+ //foreground and background color parameter is not handled for now (10.6)
+ m_customCursor = [[NSCursor alloc] initWithImage:cursorImage hotSpot:hotSpotPoint];
- [cursorImageRep release];
- [cursorImage release];
+ [cursorImageRep release];
+ [cursorImage release];
- if ([m_window isVisible]) {
- loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
- }
- [pool drain];
- return GHOST_kSuccess;
+ if ([m_window isVisible]) {
+ loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
+ }
+ [pool drain];
+ return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2], int hotX, int hotY)
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY)
{
- return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1);
+ return setWindowCustomCursorShape(
+ (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1);
}
diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp
index d05f701be32..ca557e472f7 100644
--- a/intern/ghost/intern/GHOST_WindowManager.cpp
+++ b/intern/ghost/intern/GHOST_WindowManager.cpp
@@ -21,7 +21,6 @@
* \ingroup GHOST
*/
-
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
@@ -31,178 +30,164 @@
#include "GHOST_Debug.h"
#include "GHOST_Window.h"
-
-GHOST_WindowManager::GHOST_WindowManager() :
- m_fullScreenWindow(0),
- m_activeWindow(0),
- m_activeWindowBeforeFullScreen(0)
+GHOST_WindowManager::GHOST_WindowManager()
+ : m_fullScreenWindow(0), m_activeWindow(0), m_activeWindowBeforeFullScreen(0)
{
}
-
GHOST_WindowManager::~GHOST_WindowManager()
{
- /* m_windows is freed by GHOST_System::disposeWindow */
+ /* m_windows is freed by GHOST_System::disposeWindow */
}
-
GHOST_TSuccess GHOST_WindowManager::addWindow(GHOST_IWindow *window)
{
- GHOST_TSuccess success = GHOST_kFailure;
- if (window) {
- if (!getWindowFound(window)) {
- // Store the pointer to the window
- m_windows.push_back(window);
- success = GHOST_kSuccess;
- }
- }
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (window) {
+ if (!getWindowFound(window)) {
+ // Store the pointer to the window
+ m_windows.push_back(window);
+ success = GHOST_kSuccess;
+ }
+ }
+ return success;
}
-
GHOST_TSuccess GHOST_WindowManager::removeWindow(const GHOST_IWindow *window)
{
- GHOST_TSuccess success = GHOST_kFailure;
- if (window) {
- if (window == m_fullScreenWindow) {
- endFullScreen();
- }
- else {
- std::vector<GHOST_IWindow *>::iterator result = find(m_windows.begin(), m_windows.end(), window);
- if (result != m_windows.end()) {
- setWindowInactive(window);
- m_windows.erase(result);
- success = GHOST_kSuccess;
- }
- }
- }
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (window) {
+ if (window == m_fullScreenWindow) {
+ endFullScreen();
+ }
+ else {
+ std::vector<GHOST_IWindow *>::iterator result = find(
+ m_windows.begin(), m_windows.end(), window);
+ if (result != m_windows.end()) {
+ setWindowInactive(window);
+ m_windows.erase(result);
+ success = GHOST_kSuccess;
+ }
+ }
+ }
+ return success;
}
-
bool GHOST_WindowManager::getWindowFound(const GHOST_IWindow *window) const
{
- bool found = false;
- if (window) {
- if (getFullScreen() && (window == m_fullScreenWindow)) {
- found = true;
- }
- else {
- std::vector<GHOST_IWindow *>::const_iterator result = find(m_windows.begin(), m_windows.end(), window);
- if (result != m_windows.end()) {
- found = true;
- }
- }
- }
- return found;
+ bool found = false;
+ if (window) {
+ if (getFullScreen() && (window == m_fullScreenWindow)) {
+ found = true;
+ }
+ else {
+ std::vector<GHOST_IWindow *>::const_iterator result = find(
+ m_windows.begin(), m_windows.end(), window);
+ if (result != m_windows.end()) {
+ found = true;
+ }
+ }
+ }
+ return found;
}
-
bool GHOST_WindowManager::getFullScreen(void) const
{
- return m_fullScreenWindow != NULL;
+ return m_fullScreenWindow != NULL;
}
-
GHOST_IWindow *GHOST_WindowManager::getFullScreenWindow(void) const
{
- return m_fullScreenWindow;
+ return m_fullScreenWindow;
}
-
-GHOST_TSuccess GHOST_WindowManager::beginFullScreen(GHOST_IWindow *window,
- bool /*stereoVisual*/)
+GHOST_TSuccess GHOST_WindowManager::beginFullScreen(GHOST_IWindow *window, bool /*stereoVisual*/)
{
- GHOST_TSuccess success = GHOST_kFailure;
- GHOST_ASSERT(window, "GHOST_WindowManager::beginFullScreen(): invalid window");
- GHOST_ASSERT(window->getValid(), "GHOST_WindowManager::beginFullScreen(): invalid window");
- if (!getFullScreen()) {
- m_fullScreenWindow = window;
- m_activeWindowBeforeFullScreen = getActiveWindow();
- setActiveWindow(m_fullScreenWindow);
- m_fullScreenWindow->beginFullScreen();
- success = GHOST_kSuccess;
- }
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ GHOST_ASSERT(window, "GHOST_WindowManager::beginFullScreen(): invalid window");
+ GHOST_ASSERT(window->getValid(), "GHOST_WindowManager::beginFullScreen(): invalid window");
+ if (!getFullScreen()) {
+ m_fullScreenWindow = window;
+ m_activeWindowBeforeFullScreen = getActiveWindow();
+ setActiveWindow(m_fullScreenWindow);
+ m_fullScreenWindow->beginFullScreen();
+ success = GHOST_kSuccess;
+ }
+ return success;
}
GHOST_TSuccess GHOST_WindowManager::endFullScreen(void)
{
- GHOST_TSuccess success = GHOST_kFailure;
- if (getFullScreen()) {
- if (m_fullScreenWindow != NULL) {
- //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n");
- setWindowInactive(m_fullScreenWindow);
- m_fullScreenWindow->endFullScreen();
- delete m_fullScreenWindow;
- //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n");
- m_fullScreenWindow = NULL;
- if (m_activeWindowBeforeFullScreen) {
- setActiveWindow(m_activeWindowBeforeFullScreen);
- }
- }
- success = GHOST_kSuccess;
- }
- return success;
+ GHOST_TSuccess success = GHOST_kFailure;
+ if (getFullScreen()) {
+ if (m_fullScreenWindow != NULL) {
+ //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n");
+ setWindowInactive(m_fullScreenWindow);
+ m_fullScreenWindow->endFullScreen();
+ delete m_fullScreenWindow;
+ //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n");
+ m_fullScreenWindow = NULL;
+ if (m_activeWindowBeforeFullScreen) {
+ setActiveWindow(m_activeWindowBeforeFullScreen);
+ }
+ }
+ success = GHOST_kSuccess;
+ }
+ return success;
}
-
GHOST_TSuccess GHOST_WindowManager::setActiveWindow(GHOST_IWindow *window)
{
- GHOST_TSuccess success = GHOST_kSuccess;
- if (window != m_activeWindow) {
- if (getWindowFound(window)) {
- m_activeWindow = window;
- }
- else {
- success = GHOST_kFailure;
- }
- }
- return success;
+ GHOST_TSuccess success = GHOST_kSuccess;
+ if (window != m_activeWindow) {
+ if (getWindowFound(window)) {
+ m_activeWindow = window;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ }
+ return success;
}
-
GHOST_IWindow *GHOST_WindowManager::getActiveWindow(void) const
{
- return m_activeWindow;
+ return m_activeWindow;
}
-
void GHOST_WindowManager::setWindowInactive(const GHOST_IWindow *window)
{
- if (window == m_activeWindow) {
- m_activeWindow = NULL;
- }
+ if (window == m_activeWindow) {
+ m_activeWindow = NULL;
+ }
}
-
std::vector<GHOST_IWindow *> &GHOST_WindowManager::getWindows()
{
- return m_windows;
+ return m_windows;
}
-
GHOST_IWindow *GHOST_WindowManager::getWindowAssociatedWithOSWindow(void *osWindow)
{
- std::vector<GHOST_IWindow *>::iterator iter;
+ std::vector<GHOST_IWindow *>::iterator iter;
- for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) {
- if ((*iter)->getOSWindow() == osWindow)
- return *iter;
- }
+ for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) {
+ if ((*iter)->getOSWindow() == osWindow)
+ return *iter;
+ }
- return NULL;
+ return NULL;
}
bool GHOST_WindowManager::getAnyModifiedState()
{
- bool isAnyModified = false;
- std::vector<GHOST_IWindow *>::iterator iter;
+ bool isAnyModified = false;
+ std::vector<GHOST_IWindow *>::iterator iter;
- for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) {
- if ((*iter)->getModifiedState())
- isAnyModified = true;
- }
+ for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) {
+ if ((*iter)->getModifiedState())
+ isAnyModified = true;
+ }
- return isAnyModified;
+ return isAnyModified;
}
diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h
index fe1db0fed52..025d84f1f3d 100644
--- a/intern/ghost/intern/GHOST_WindowManager.h
+++ b/intern/ghost/intern/GHOST_WindowManager.h
@@ -30,131 +30,126 @@
#include "GHOST_Rect.h"
#include "GHOST_IWindow.h"
-
/**
* Manages system windows (platform independent implementation).
*/
-class GHOST_WindowManager
-{
-public:
- /**
- * Constructor.
- */
- GHOST_WindowManager();
-
- /**
- * Destructor.
- */
- ~GHOST_WindowManager();
-
- /**
- * Add a window to our list.
- * It is only added if it is not already in the list.
- * \param window Pointer to the window to be added.
- * \return Indication of success.
- */
- GHOST_TSuccess addWindow(GHOST_IWindow *window);
-
- /**
- * Remove a window from our list.
- * \param window Pointer to the window to be removed.
- * \return Indication of success.
- */
- GHOST_TSuccess removeWindow(const GHOST_IWindow *window);
-
- /**
- * Returns whether the window is in our list.
- * \param window Pointer to the window to query.
- * \return A boolean indicator.
- */
- bool getWindowFound(const GHOST_IWindow *window) const;
-
- /**
- * Returns whether one of the windows is fullscreen.
- * \return A boolean indicator.
- */
- bool getFullScreen(void) const;
-
- /**
- * Returns pointer to the full-screen window.
- * \return The full-screen window (NULL if not in full-screen).
- */
- GHOST_IWindow *getFullScreenWindow(void) const;
-
- /**
- * Activates fullscreen mode for a window.
- * \param window The window displayed fullscreen.
- * \return Indication of success.
- */
- GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual);
-
- /**
- * Closes fullscreen mode down.
- * \return Indication of success.
- */
- GHOST_TSuccess endFullScreen(void);
-
- /**
- * Sets new window as active window (the window receiving events).
- * There can be only one window active which should be in the current window list.
- * \param window The new active window.
- */
- GHOST_TSuccess setActiveWindow(GHOST_IWindow *window);
-
- /**
- * Returns the active window (the window receiving events).
- * There can be only one window active which should be in the current window list.
- * \return window The active window (or NULL if there is none).
- */
- GHOST_IWindow *getActiveWindow(void) const;
-
-
- /**
- * Set this window to be inactive (not receiving events).
- * \param window The window to deactivate.
- */
- void setWindowInactive(const GHOST_IWindow *window);
-
-
- /**
- * Return a vector of the windows currently managed by this
- * class.
- * \warning It is very dangerous to mess with the contents of
- * this vector. Please do not destroy or add windows use the
- * interface above for this,
- */
- std::vector<GHOST_IWindow *> & getWindows();
-
- /**
- * Finds the window associated with an OS window object/handle
- * \param osWindow The OS window object/handle
- * \return The associated window, null if none corresponds
- */
- GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow);
-
- /**
- * Return true if any windows has a modified status
- * \return True if any window has unsaved changes
- */
- bool getAnyModifiedState();
-
-protected:
- /** The list of windows managed */
- std::vector<GHOST_IWindow *> m_windows;
-
- /** Window in fullscreen state. There can be only one of this which is not in or window list. */
- GHOST_IWindow *m_fullScreenWindow;
-
- /** The active window. */
- GHOST_IWindow *m_activeWindow;
-
- /** Window that was active before entering fullscreen state. */
- GHOST_IWindow *m_activeWindowBeforeFullScreen;
+class GHOST_WindowManager {
+ public:
+ /**
+ * Constructor.
+ */
+ GHOST_WindowManager();
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_WindowManager();
+
+ /**
+ * Add a window to our list.
+ * It is only added if it is not already in the list.
+ * \param window Pointer to the window to be added.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess addWindow(GHOST_IWindow *window);
+
+ /**
+ * Remove a window from our list.
+ * \param window Pointer to the window to be removed.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess removeWindow(const GHOST_IWindow *window);
+
+ /**
+ * Returns whether the window is in our list.
+ * \param window Pointer to the window to query.
+ * \return A boolean indicator.
+ */
+ bool getWindowFound(const GHOST_IWindow *window) const;
+
+ /**
+ * Returns whether one of the windows is fullscreen.
+ * \return A boolean indicator.
+ */
+ bool getFullScreen(void) const;
+
+ /**
+ * Returns pointer to the full-screen window.
+ * \return The full-screen window (NULL if not in full-screen).
+ */
+ GHOST_IWindow *getFullScreenWindow(void) const;
+
+ /**
+ * Activates fullscreen mode for a window.
+ * \param window The window displayed fullscreen.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual);
+
+ /**
+ * Closes fullscreen mode down.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess endFullScreen(void);
+
+ /**
+ * Sets new window as active window (the window receiving events).
+ * There can be only one window active which should be in the current window list.
+ * \param window The new active window.
+ */
+ GHOST_TSuccess setActiveWindow(GHOST_IWindow *window);
+
+ /**
+ * Returns the active window (the window receiving events).
+ * There can be only one window active which should be in the current window list.
+ * \return window The active window (or NULL if there is none).
+ */
+ GHOST_IWindow *getActiveWindow(void) const;
+
+ /**
+ * Set this window to be inactive (not receiving events).
+ * \param window The window to deactivate.
+ */
+ void setWindowInactive(const GHOST_IWindow *window);
+
+ /**
+ * Return a vector of the windows currently managed by this
+ * class.
+ * \warning It is very dangerous to mess with the contents of
+ * this vector. Please do not destroy or add windows use the
+ * interface above for this,
+ */
+ std::vector<GHOST_IWindow *> &getWindows();
+
+ /**
+ * Finds the window associated with an OS window object/handle
+ * \param osWindow The OS window object/handle
+ * \return The associated window, null if none corresponds
+ */
+ GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow);
+
+ /**
+ * Return true if any windows has a modified status
+ * \return True if any window has unsaved changes
+ */
+ bool getAnyModifiedState();
+
+ protected:
+ /** The list of windows managed */
+ std::vector<GHOST_IWindow *> m_windows;
+
+ /** Window in fullscreen state. There can be only one of this which is not in or window list. */
+ GHOST_IWindow *m_fullScreenWindow;
+
+ /** The active window. */
+ GHOST_IWindow *m_activeWindow;
+
+ /** Window that was active before entering fullscreen state. */
+ GHOST_IWindow *m_activeWindowBeforeFullScreen;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_WindowManager")
+ MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_WindowManager")
#endif
-
};
-#endif // __GHOST_WINDOWMANAGER_H__
+#endif // __GHOST_WINDOWMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h
index c7d9efcdc51..3ac3389291d 100644
--- a/intern/ghost/intern/GHOST_WindowNULL.h
+++ b/intern/ghost/intern/GHOST_WindowNULL.h
@@ -29,69 +29,163 @@
class STR_String;
class GHOST_SystemNULL;
-class GHOST_WindowNULL : public GHOST_Window
-{
-public:
- const GHOST_TabletData* GetTabletData() { return NULL; }
+class GHOST_WindowNULL : public GHOST_Window {
+ public:
+ const GHOST_TabletData *GetTabletData()
+ {
+ return NULL;
+ }
- GHOST_WindowNULL(
- GHOST_SystemNULL *system,
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- const GHOST_TEmbedderWindowID parentWindow,
- GHOST_TDrawingContextType type,
- const bool stereoVisual,
- const GHOST_TUns16 numOfAASamples
- ) :
- GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples),
- m_system(system)
- {
- setTitle(title);
- }
+ GHOST_WindowNULL(GHOST_SystemNULL *system,
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const GHOST_TEmbedderWindowID parentWindow,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples)
+ : GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples), m_system(system)
+ {
+ setTitle(title);
+ }
-protected:
- GHOST_TSuccess installDrawingContext( GHOST_TDrawingContextType type ) { return GHOST_kSuccess; }
- GHOST_TSuccess removeDrawingContext( ) { return GHOST_kSuccess; }
- GHOST_TSuccess setWindowCursorGrab( GHOST_TGrabCursorMode mode ) { return GHOST_kSuccess; }
- GHOST_TSuccess setWindowCursorShape( GHOST_TStandardCursor shape ) { return GHOST_kSuccess; }
- GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY ) { return GHOST_kSuccess; }
- GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color ) { return GHOST_kSuccess; }
+ protected:
+ GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type)
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess removeDrawingContext()
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode)
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape)
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY)
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color)
+ {
+ return GHOST_kSuccess;
+ }
- bool getValid( ) const { return true; }
- void setTitle( const STR_String& title ) { /* nothing */ }
- void getTitle( STR_String& title ) const { title= "untitled"; }
- void getWindowBounds( GHOST_Rect& bounds ) const { getClientBounds(bounds); }
- void getClientBounds( GHOST_Rect& bounds ) const { /* nothing */ }
- GHOST_TSuccess setClientWidth( GHOST_TUns32 width ) { return GHOST_kFailure; }
- GHOST_TSuccess setClientHeight( GHOST_TUns32 height ) { return GHOST_kFailure; }
- GHOST_TSuccess setClientSize( GHOST_TUns32 width, GHOST_TUns32 height ) { return GHOST_kFailure; }
- void screenToClient( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; }
- void clientToScreen( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; }
- GHOST_TSuccess swapBuffers( ) { return GHOST_kFailure; }
- GHOST_TSuccess activateDrawingContext( ) { return GHOST_kFailure; }
- ~GHOST_WindowNULL( ) { /* nothing */ }
- GHOST_TSuccess setWindowCursorVisibility( bool visible ) { return GHOST_kSuccess; }
- GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; }
- GHOST_TWindowState getState() const { return GHOST_kWindowStateNormal; }
- GHOST_TSuccess invalidate() { return GHOST_kSuccess; }
- GHOST_TSuccess setOrder(GHOST_TWindowOrder order) { return GHOST_kSuccess; }
+ bool getValid() const
+ {
+ return true;
+ }
+ void setTitle(const STR_String &title)
+ { /* nothing */
+ }
+ void getTitle(STR_String &title) const
+ {
+ title = "untitled";
+ }
+ void getWindowBounds(GHOST_Rect &bounds) const
+ {
+ getClientBounds(bounds);
+ }
+ void getClientBounds(GHOST_Rect &bounds) const
+ { /* nothing */
+ }
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width)
+ {
+ return GHOST_kFailure;
+ }
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height)
+ {
+ return GHOST_kFailure;
+ }
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
+ {
+ return GHOST_kFailure;
+ }
+ void screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
+ {
+ outX = inX;
+ outY = inY;
+ }
+ void clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
+ {
+ outX = inX;
+ outY = inY;
+ }
+ GHOST_TSuccess swapBuffers()
+ {
+ return GHOST_kFailure;
+ }
+ GHOST_TSuccess activateDrawingContext()
+ {
+ return GHOST_kFailure;
+ }
+ ~GHOST_WindowNULL()
+ { /* nothing */
+ }
+ GHOST_TSuccess setWindowCursorVisibility(bool visible)
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess setState(GHOST_TWindowState state)
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TWindowState getState() const
+ {
+ return GHOST_kWindowStateNormal;
+ }
+ GHOST_TSuccess invalidate()
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order)
+ {
+ return GHOST_kSuccess;
+ }
- GHOST_TSuccess beginFullScreen() const { return GHOST_kSuccess; }
- GHOST_TSuccess endFullScreen() const { return GHOST_kSuccess; }
+ GHOST_TSuccess beginFullScreen() const
+ {
+ return GHOST_kSuccess;
+ }
+ GHOST_TSuccess endFullScreen() const
+ {
+ return GHOST_kSuccess;
+ }
-private:
- GHOST_SystemNULL *m_system;
+ private:
+ GHOST_SystemNULL *m_system;
- /**
- * \param type The type of rendering context create.
- * \return Indication of success.
- */
- GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) { return NULL; }
+ /**
+ * \param type The type of rendering context create.
+ * \return Indication of success.
+ */
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type)
+ {
+ return NULL;
+ }
};
-
-#endif // __GHOST_WINDOWNULL_H__
+#endif // __GHOST_WINDOWNULL_H__
diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp
index f9d1b7c3677..d40377acc3a 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.cpp
+++ b/intern/ghost/intern/GHOST_WindowSDL.cpp
@@ -27,7 +27,7 @@
#include <assert.h>
GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system,
- const STR_String& title,
+ const STR_String &title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -37,8 +37,7 @@ GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system,
GHOST_TDrawingContextType type,
const bool stereoVisual,
const bool exclusive,
- const GHOST_TUns16 numOfAASamples
- )
+ const GHOST_TUns16 numOfAASamples)
: GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples),
m_system(system),
m_valid_setup(false),
@@ -46,407 +45,541 @@ GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system,
m_sdl_custom_cursor(NULL)
{
- /* creating the window _must_ come after setting attributes */
- m_sdl_win = SDL_CreateWindow(
- title,
- left, top,
- width, height,
- SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
-
- /* now set up the rendering context. */
- if (setDrawingContextType(type) == GHOST_kSuccess) {
- m_valid_setup = true;
- GHOST_PRINT("Created window\n");
- }
-
- if (exclusive) {
- SDL_RaiseWindow(m_sdl_win);
- }
-
- setTitle(title);
+ /* creating the window _must_ come after setting attributes */
+ m_sdl_win = SDL_CreateWindow(title,
+ left,
+ top,
+ width,
+ height,
+ SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
+
+ /* now set up the rendering context. */
+ if (setDrawingContextType(type) == GHOST_kSuccess) {
+ m_valid_setup = true;
+ GHOST_PRINT("Created window\n");
+ }
+
+ if (exclusive) {
+ SDL_RaiseWindow(m_sdl_win);
+ }
+
+ setTitle(title);
}
GHOST_WindowSDL::~GHOST_WindowSDL()
{
- if (m_sdl_custom_cursor) {
- SDL_FreeCursor(m_sdl_custom_cursor);
- }
+ if (m_sdl_custom_cursor) {
+ SDL_FreeCursor(m_sdl_custom_cursor);
+ }
- releaseNativeHandles();
+ releaseNativeHandles();
- SDL_DestroyWindow(m_sdl_win);
+ SDL_DestroyWindow(m_sdl_win);
}
-
-GHOST_Context *
-GHOST_WindowSDL::newDrawingContext(GHOST_TDrawingContextType type)
+GHOST_Context *GHOST_WindowSDL::newDrawingContext(GHOST_TDrawingContextType type)
{
- if (type == GHOST_kDrawingContextTypeOpenGL) {
- GHOST_Context *context = new GHOST_ContextSDL(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_sdl_win,
- 0, // profile bit
- 3, 3,
- GHOST_OPENGL_SDL_CONTEXT_FLAGS,
- GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
- }
-
- return NULL;
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+ GHOST_Context *context = new GHOST_ContextSDL(m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_sdl_win,
+ 0, // profile bit
+ 3,
+ 3,
+ GHOST_OPENGL_SDL_CONTEXT_FLAGS,
+ GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+ }
+
+ return NULL;
}
-
-GHOST_TSuccess
-GHOST_WindowSDL::invalidate(void)
+GHOST_TSuccess GHOST_WindowSDL::invalidate(void)
{
- if (m_invalid_window == false) {
- m_system->addDirtyWindow(this);
- m_invalid_window = true;
- }
+ if (m_invalid_window == false) {
+ m_system->addDirtyWindow(this);
+ m_invalid_window = true;
+ }
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowSDL::setState(GHOST_TWindowState state)
+GHOST_TSuccess GHOST_WindowSDL::setState(GHOST_TWindowState state)
{
- switch (state) {
- case GHOST_kWindowStateNormal:
- SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE);
- SDL_RestoreWindow(m_sdl_win);
- break;
- case GHOST_kWindowStateMaximized:
- SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE);
- SDL_MaximizeWindow(m_sdl_win);
- break;
- case GHOST_kWindowStateMinimized:
- SDL_MinimizeWindow(m_sdl_win);
- break;
- case GHOST_kWindowStateFullScreen:
- SDL_SetWindowFullscreen(m_sdl_win, SDL_TRUE);
- break;
- default:
- break;
- }
-
- return GHOST_kSuccess;
+ switch (state) {
+ case GHOST_kWindowStateNormal:
+ SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE);
+ SDL_RestoreWindow(m_sdl_win);
+ break;
+ case GHOST_kWindowStateMaximized:
+ SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE);
+ SDL_MaximizeWindow(m_sdl_win);
+ break;
+ case GHOST_kWindowStateMinimized:
+ SDL_MinimizeWindow(m_sdl_win);
+ break;
+ case GHOST_kWindowStateFullScreen:
+ SDL_SetWindowFullscreen(m_sdl_win, SDL_TRUE);
+ break;
+ default:
+ break;
+ }
+
+ return GHOST_kSuccess;
}
-
-GHOST_TWindowState
-GHOST_WindowSDL::getState() const
+GHOST_TWindowState GHOST_WindowSDL::getState() const
{
- Uint32 flags = SDL_GetWindowFlags(m_sdl_win);
-
- if (flags & SDL_WINDOW_FULLSCREEN) return GHOST_kWindowStateFullScreen;
- else if (flags & SDL_WINDOW_MAXIMIZED) return GHOST_kWindowStateMaximized;
- else if (flags & SDL_WINDOW_MINIMIZED) return GHOST_kWindowStateMinimized;
- return GHOST_kWindowStateNormal;
+ Uint32 flags = SDL_GetWindowFlags(m_sdl_win);
+
+ if (flags & SDL_WINDOW_FULLSCREEN)
+ return GHOST_kWindowStateFullScreen;
+ else if (flags & SDL_WINDOW_MAXIMIZED)
+ return GHOST_kWindowStateMaximized;
+ else if (flags & SDL_WINDOW_MINIMIZED)
+ return GHOST_kWindowStateMinimized;
+ return GHOST_kWindowStateNormal;
}
-bool
-GHOST_WindowSDL::
-getValid() const
+bool GHOST_WindowSDL::getValid() const
{
- return GHOST_Window::getValid() && m_valid_setup;
+ return GHOST_Window::getValid() && m_valid_setup;
}
-void
-GHOST_WindowSDL::setTitle(const STR_String& title)
+void GHOST_WindowSDL::setTitle(const STR_String &title)
{
- SDL_SetWindowTitle(m_sdl_win, title.ReadPtr());
+ SDL_SetWindowTitle(m_sdl_win, title.ReadPtr());
}
-
-void
-GHOST_WindowSDL::getTitle(STR_String& title) const
+void GHOST_WindowSDL::getTitle(STR_String &title) const
{
- title = SDL_GetWindowTitle(m_sdl_win);
+ title = SDL_GetWindowTitle(m_sdl_win);
}
-
-void
-GHOST_WindowSDL::getWindowBounds(GHOST_Rect& bounds) const
+void GHOST_WindowSDL::getWindowBounds(GHOST_Rect &bounds) const
{
- getClientBounds(bounds);
+ getClientBounds(bounds);
}
-
-void
-GHOST_WindowSDL::getClientBounds(GHOST_Rect& bounds) const
+void GHOST_WindowSDL::getClientBounds(GHOST_Rect &bounds) const
{
- int x, y, w, h;
- SDL_GetWindowSize(m_sdl_win, &w, &h);
- SDL_GetWindowPosition(m_sdl_win, &x, &y);
-
- bounds.m_l = x;
- bounds.m_r = x + w;
- bounds.m_t = y;
- bounds.m_b = y + h;
+ int x, y, w, h;
+ SDL_GetWindowSize(m_sdl_win, &w, &h);
+ SDL_GetWindowPosition(m_sdl_win, &x, &y);
+
+ bounds.m_l = x;
+ bounds.m_r = x + w;
+ bounds.m_t = y;
+ bounds.m_b = y + h;
}
-GHOST_TSuccess
-GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width)
+GHOST_TSuccess GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width)
{
- int height;
- SDL_GetWindowSize(m_sdl_win, NULL, &height);
- SDL_SetWindowSize(m_sdl_win, width, height);
- return GHOST_kSuccess;
+ int height;
+ SDL_GetWindowSize(m_sdl_win, NULL, &height);
+ SDL_SetWindowSize(m_sdl_win, width, height);
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height)
+GHOST_TSuccess GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height)
{
- int width;
- SDL_GetWindowSize(m_sdl_win, &width, NULL);
- SDL_SetWindowSize(m_sdl_win, width, height);
- return GHOST_kSuccess;
+ int width;
+ SDL_GetWindowSize(m_sdl_win, &width, NULL);
+ SDL_SetWindowSize(m_sdl_win, width, height);
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowSDL::setClientSize(GHOST_TUns32 width,
- GHOST_TUns32 height)
+GHOST_TSuccess GHOST_WindowSDL::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
{
- SDL_SetWindowSize(m_sdl_win, width, height);
- return GHOST_kSuccess;
+ SDL_SetWindowSize(m_sdl_win, width, height);
+ return GHOST_kSuccess;
}
-void
-GHOST_WindowSDL::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+void GHOST_WindowSDL::screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- /* XXXSDL_WEAK_ABS_COORDS */
- int x_win, y_win;
- SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win);
+ /* XXXSDL_WEAK_ABS_COORDS */
+ int x_win, y_win;
+ SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win);
- outX = inX - x_win;
- outY = inY - y_win;
+ outX = inX - x_win;
+ outY = inY - y_win;
}
-void
-GHOST_WindowSDL::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+void GHOST_WindowSDL::clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- /* XXXSDL_WEAK_ABS_COORDS */
- int x_win, y_win;
- SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win);
+ /* XXXSDL_WEAK_ABS_COORDS */
+ int x_win, y_win;
+ SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win);
- outX = inX + x_win;
- outY = inY + y_win;
+ outX = inX + x_win;
+ outY = inY + y_win;
}
/* mouse cursor */
-static unsigned char sdl_std_cursor_mask_xterm[] = {0xef, 0x01, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xef, 0x01, };
-static unsigned char sdl_std_cursor_xterm[] = {0x00, 0x77, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_xterm 9
+static unsigned char sdl_std_cursor_mask_xterm[] = {
+ 0xef, 0x01, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00,
+ 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xef, 0x01,
+};
+static unsigned char sdl_std_cursor_xterm[] = {
+ 0x00, 0x77, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
+ 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_xterm 9
#define sdl_std_cursor_HEIGHT_xterm 16
-#define sdl_std_cursor_HOT_X_xterm -3
-#define sdl_std_cursor_HOT_Y_xterm -7
-
-static unsigned char sdl_std_cursor_mask_watch[] = {0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0x1f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, };
-static unsigned char sdl_std_cursor_watch[] = {0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0xfc, 0x0f, 0x86, 0x18, 0x83, 0x30, 0x81, 0xe0, 0xc1, 0xe1, 0xc1, 0xe1, 0x21, 0xe0, 0x13, 0x30, 0x06, 0x18, 0xfc, 0x0f, 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, };
-#define sdl_std_cursor_WIDTH_watch 16
+#define sdl_std_cursor_HOT_X_xterm -3
+#define sdl_std_cursor_HOT_Y_xterm -7
+
+static unsigned char sdl_std_cursor_mask_watch[] = {
+ 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0x1f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
+};
+static unsigned char sdl_std_cursor_watch[] = {
+ 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0xfc, 0x0f, 0x86, 0x18, 0x83, 0x30, 0x81, 0xe0, 0xc1, 0xe1,
+ 0xc1, 0xe1, 0x21, 0xe0, 0x13, 0x30, 0x06, 0x18, 0xfc, 0x0f, 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07,
+};
+#define sdl_std_cursor_WIDTH_watch 16
#define sdl_std_cursor_HEIGHT_watch 16
-#define sdl_std_cursor_HOT_X_watch -15
-#define sdl_std_cursor_HOT_Y_watch -7
-
-static unsigned char sdl_std_cursor_mask_umbrella[] = {0xe8, 0x76, 0xfb, 0xdf, 0xfd, 0x3f, 0xfe, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xcf, 0x79, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0x80, 0x03, };
-static unsigned char sdl_std_cursor_umbrella[] = {0x88, 0x04, 0x20, 0x0a, 0xc9, 0x32, 0xf2, 0x09, 0x4c, 0x06, 0x43, 0x18, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_umbrella 16
+#define sdl_std_cursor_HOT_X_watch -15
+#define sdl_std_cursor_HOT_Y_watch -7
+
+static unsigned char sdl_std_cursor_mask_umbrella[] = {
+ 0xe8, 0x76, 0xfb, 0xdf, 0xfd, 0x3f, 0xfe, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xcf, 0x79, 0xc0, 0x01,
+ 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0x80, 0x03,
+};
+static unsigned char sdl_std_cursor_umbrella[] = {
+ 0x88, 0x04, 0x20, 0x0a, 0xc9, 0x32, 0xf2, 0x09, 0x4c, 0x06, 0x43, 0x18, 0x40, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_umbrella 16
#define sdl_std_cursor_HEIGHT_umbrella 16
-#define sdl_std_cursor_HOT_X_umbrella -7
-#define sdl_std_cursor_HOT_Y_umbrella -12
-
-static unsigned char sdl_std_cursor_mask_top_side[] = {0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xdc, 0x1d, 0xcc, 0x19, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, };
-static unsigned char sdl_std_cursor_top_side[] = {0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x50, 0x01, 0x48, 0x02, 0x44, 0x04, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_top_side 15
+#define sdl_std_cursor_HOT_X_umbrella -7
+#define sdl_std_cursor_HOT_Y_umbrella -12
+
+static unsigned char sdl_std_cursor_mask_top_side[] = {
+ 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f,
+ 0xdc, 0x1d, 0xcc, 0x19, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
+};
+static unsigned char sdl_std_cursor_top_side[] = {
+ 0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x50, 0x01, 0x48, 0x02, 0x44, 0x04,
+ 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_top_side 15
#define sdl_std_cursor_HEIGHT_top_side 16
-#define sdl_std_cursor_HOT_X_top_side -6
-#define sdl_std_cursor_HOT_Y_top_side -14
-
-static unsigned char sdl_std_cursor_mask_top_right_corner[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0xc0, 0xf7, 0xe0, 0xf7, 0x70, 0xf7, 0x38, 0xf7, 0x1c, 0xf7, 0x0c, 0xf7, 0x00, 0xf0, 0x00, 0xf0, };
-static unsigned char sdl_std_cursor_top_right_corner[] = {0xff, 0x3f, 0xff, 0x3f, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xfc, 0x31, 0x80, 0x31, 0x40, 0x31, 0x20, 0x31, 0x10, 0x31, 0x08, 0x31, 0x04, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_top_right_corner 16
+#define sdl_std_cursor_HOT_X_top_side -6
+#define sdl_std_cursor_HOT_Y_top_side -14
+
+static unsigned char sdl_std_cursor_mask_top_right_corner[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7,
+ 0xc0, 0xf7, 0xe0, 0xf7, 0x70, 0xf7, 0x38, 0xf7, 0x1c, 0xf7, 0x0c, 0xf7, 0x00, 0xf0, 0x00, 0xf0,
+};
+static unsigned char sdl_std_cursor_top_right_corner[] = {
+ 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xfc, 0x31, 0x80, 0x31, 0x40, 0x31,
+ 0x20, 0x31, 0x10, 0x31, 0x08, 0x31, 0x04, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_top_right_corner 16
#define sdl_std_cursor_HEIGHT_top_right_corner 16
-#define sdl_std_cursor_HOT_X_top_right_corner -13
-#define sdl_std_cursor_HOT_Y_top_right_corner -14
-
-static unsigned char sdl_std_cursor_mask_top_left_corner[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x03, 0xef, 0x07, 0xef, 0x0e, 0xef, 0x1c, 0xef, 0x38, 0xef, 0x30, 0x0f, 0x00, 0x0f, 0x00, };
-static unsigned char sdl_std_cursor_top_left_corner[] = {0xff, 0x3f, 0xff, 0x3f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xe3, 0x0f, 0x63, 0x00, 0xa3, 0x00, 0x23, 0x01, 0x23, 0x02, 0x23, 0x04, 0x23, 0x08, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_top_left_corner 16
+#define sdl_std_cursor_HOT_X_top_right_corner -13
+#define sdl_std_cursor_HOT_Y_top_right_corner -14
+
+static unsigned char sdl_std_cursor_mask_top_left_corner[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f,
+ 0xef, 0x03, 0xef, 0x07, 0xef, 0x0e, 0xef, 0x1c, 0xef, 0x38, 0xef, 0x30, 0x0f, 0x00, 0x0f, 0x00,
+};
+static unsigned char sdl_std_cursor_top_left_corner[] = {
+ 0xff, 0x3f, 0xff, 0x3f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xe3, 0x0f, 0x63, 0x00, 0xa3, 0x00,
+ 0x23, 0x01, 0x23, 0x02, 0x23, 0x04, 0x23, 0x08, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_top_left_corner 16
#define sdl_std_cursor_HEIGHT_top_left_corner 16
-#define sdl_std_cursor_HOT_X_top_left_corner 0
-#define sdl_std_cursor_HOT_Y_top_left_corner -14
-
-static unsigned char sdl_std_cursor_mask_spraycan[] = {0x00, 0x0c, 0x18, 0x0d, 0x7c, 0x0d, 0x7c, 0x0d, 0x7e, 0x0d, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, };
-static unsigned char sdl_std_cursor_spraycan[] = {0x00, 0x06, 0x80, 0x00, 0x2c, 0x06, 0x9e, 0x00, 0x16, 0x06, 0x3f, 0x00, 0x21, 0x00, 0x27, 0x00, 0x25, 0x00, 0x27, 0x00, 0x25, 0x00, 0x27, 0x00, 0x27, 0x00, 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, };
-#define sdl_std_cursor_WIDTH_spraycan 12
+#define sdl_std_cursor_HOT_X_top_left_corner 0
+#define sdl_std_cursor_HOT_Y_top_left_corner -14
+
+static unsigned char sdl_std_cursor_mask_spraycan[] = {
+ 0x00, 0x0c, 0x18, 0x0d, 0x7c, 0x0d, 0x7c, 0x0d, 0x7e, 0x0d, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
+};
+static unsigned char sdl_std_cursor_spraycan[] = {
+ 0x00, 0x06, 0x80, 0x00, 0x2c, 0x06, 0x9e, 0x00, 0x16, 0x06, 0x3f, 0x00, 0x21, 0x00, 0x27, 0x00,
+ 0x25, 0x00, 0x27, 0x00, 0x25, 0x00, 0x27, 0x00, 0x27, 0x00, 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00,
+};
+#define sdl_std_cursor_WIDTH_spraycan 12
#define sdl_std_cursor_HEIGHT_spraycan 16
-#define sdl_std_cursor_HOT_X_spraycan -9
-#define sdl_std_cursor_HOT_Y_spraycan -14
-
-static unsigned char sdl_std_cursor_mask_sb_v_double_arrow[] = {0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, };
-static unsigned char sdl_std_cursor_sb_v_double_arrow[] = {0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00, };
-#define sdl_std_cursor_WIDTH_sb_v_double_arrow 9
+#define sdl_std_cursor_HOT_X_spraycan -9
+#define sdl_std_cursor_HOT_Y_spraycan -14
+
+static unsigned char sdl_std_cursor_mask_sb_v_double_arrow[] = {
+ 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x7c, 0x00, 0x7c,
+ 0x00, 0x7c, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00,
+};
+static unsigned char sdl_std_cursor_sb_v_double_arrow[] = {
+ 0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28,
+ 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00,
+};
+#define sdl_std_cursor_WIDTH_sb_v_double_arrow 9
#define sdl_std_cursor_HEIGHT_sb_v_double_arrow 15
-#define sdl_std_cursor_HOT_X_sb_v_double_arrow -3
-#define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8
-
-static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[] = {0x18, 0x0c, 0x1c, 0x1c, 0xfe, 0x3f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xfe, 0x3f, 0x1c, 0x1c, 0x18, 0x0c, };
-static unsigned char sdl_std_cursor_sb_h_double_arrow[] = {0x00, 0x00, 0x08, 0x08, 0x0c, 0x18, 0xfe, 0x3f, 0x0f, 0x78, 0xfe, 0x3f, 0x0c, 0x18, 0x08, 0x08, 0x00, 0x00};
-#define sdl_std_cursor_WIDTH_sb_h_double_arrow 15
+#define sdl_std_cursor_HOT_X_sb_v_double_arrow -3
+#define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8
+
+static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[] = {
+ 0x18,
+ 0x0c,
+ 0x1c,
+ 0x1c,
+ 0xfe,
+ 0x3f,
+ 0xff,
+ 0x7f,
+ 0xff,
+ 0x7f,
+ 0xff,
+ 0x7f,
+ 0xfe,
+ 0x3f,
+ 0x1c,
+ 0x1c,
+ 0x18,
+ 0x0c,
+};
+static unsigned char sdl_std_cursor_sb_h_double_arrow[] = {0x00,
+ 0x00,
+ 0x08,
+ 0x08,
+ 0x0c,
+ 0x18,
+ 0xfe,
+ 0x3f,
+ 0x0f,
+ 0x78,
+ 0xfe,
+ 0x3f,
+ 0x0c,
+ 0x18,
+ 0x08,
+ 0x08,
+ 0x00,
+ 0x00};
+#define sdl_std_cursor_WIDTH_sb_h_double_arrow 15
#define sdl_std_cursor_HEIGHT_sb_h_double_arrow 9
-#define sdl_std_cursor_HOT_X_sb_h_double_arrow -7
-#define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4
-
-static unsigned char sdl_std_cursor_mask_right_side[] = {0x00, 0xf0, 0x00, 0xf0, 0xc0, 0xf0, 0xc0, 0xf1, 0x80, 0xf3, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf7, 0x80, 0xf3, 0xc0, 0xf1, 0xc0, 0xf0, 0x00, 0xf0, 0x00, 0xf0, };
-static unsigned char sdl_std_cursor_right_side[] = {0x00, 0x30, 0x00, 0x30, 0x40, 0x30, 0x80, 0x30, 0x00, 0x31, 0x00, 0x32, 0xff, 0x37, 0x00, 0x32, 0x00, 0x31, 0x80, 0x30, 0x40, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_right_side 16
+#define sdl_std_cursor_HOT_X_sb_h_double_arrow -7
+#define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4
+
+static unsigned char sdl_std_cursor_mask_right_side[] = {
+ 0x00, 0xf0, 0x00, 0xf0, 0xc0, 0xf0, 0xc0, 0xf1, 0x80, 0xf3, 0x00, 0xf7, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x00, 0xf7, 0x80, 0xf3, 0xc0, 0xf1, 0xc0, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+};
+static unsigned char sdl_std_cursor_right_side[] = {
+ 0x00, 0x30, 0x00, 0x30, 0x40, 0x30, 0x80, 0x30, 0x00, 0x31, 0x00, 0x32, 0xff, 0x37, 0x00,
+ 0x32, 0x00, 0x31, 0x80, 0x30, 0x40, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_right_side 16
#define sdl_std_cursor_HEIGHT_right_side 15
-#define sdl_std_cursor_HOT_X_right_side -13
-#define sdl_std_cursor_HOT_Y_right_side -7
-
-static unsigned char sdl_std_cursor_mask_right_ptr[] = {0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0xf0, 0x03, 0xf8, 0x03, 0xfc, 0x03, 0xfe, 0x03, 0xff, 0x03, 0xff, 0x03, 0xf8, 0x03, 0xbc, 0x03, 0x3c, 0x03, 0x1e, 0x00, 0x1e, 0x00, 0x0c, 0x00, };
-static unsigned char sdl_std_cursor_right_ptr[] = {0x00, 0x80, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0xfe, 0x00, 0xff, 0x00, 0xf8, 0x00, 0xd8, 0x00, 0x8c, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_right_ptr 10
+#define sdl_std_cursor_HOT_X_right_side -13
+#define sdl_std_cursor_HOT_Y_right_side -7
+
+static unsigned char sdl_std_cursor_mask_right_ptr[] = {
+ 0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0xf0, 0x03, 0xf8, 0x03, 0xfc, 0x03, 0xfe, 0x03,
+ 0xff, 0x03, 0xff, 0x03, 0xf8, 0x03, 0xbc, 0x03, 0x3c, 0x03, 0x1e, 0x00, 0x1e, 0x00, 0x0c, 0x00,
+};
+static unsigned char sdl_std_cursor_right_ptr[] = {
+ 0x00, 0x80, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0xfe, 0x00, 0xff,
+ 0x00, 0xf8, 0x00, 0xd8, 0x00, 0x8c, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_right_ptr 10
#define sdl_std_cursor_HEIGHT_right_ptr 16
-#define sdl_std_cursor_HOT_X_right_ptr -7
-#define sdl_std_cursor_HOT_Y_right_ptr -14
-
-static unsigned char sdl_std_cursor_mask_question_arrow[] = {0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xff, 0x07, 0x8f, 0x07, 0x9f, 0x07, 0xde, 0x07, 0xfc, 0x03, 0xf8, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00, };
-static unsigned char sdl_std_cursor_question_arrow[] = {0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x87, 0x01, 0xc6, 0x01, 0xe0, 0x00, 0x78, 0x00, 0x38, 0x00, 0x28, 0x00, 0x28, 0x00, 0xee, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_question_arrow 11
+#define sdl_std_cursor_HOT_X_right_ptr -7
+#define sdl_std_cursor_HOT_Y_right_ptr -14
+
+static unsigned char sdl_std_cursor_mask_question_arrow[] = {
+ 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xff, 0x07, 0x8f, 0x07, 0x9f, 0x07, 0xde, 0x07, 0xfc, 0x03,
+ 0xf8, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00,
+};
+static unsigned char sdl_std_cursor_question_arrow[] = {
+ 0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x87, 0x01, 0xc6, 0x01, 0xe0, 0x00, 0x78, 0x00,
+ 0x38, 0x00, 0x28, 0x00, 0x28, 0x00, 0xee, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_question_arrow 11
#define sdl_std_cursor_HEIGHT_question_arrow 16
-#define sdl_std_cursor_HOT_X_question_arrow -4
-#define sdl_std_cursor_HOT_Y_question_arrow -8
-
-static unsigned char sdl_std_cursor_mask_pirate[] = {0xf0, 0x03, 0xf8, 0x07, 0xfc, 0x0f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfc, 0x0f, 0xf8, 0x07, 0xf1, 0x83, 0xf1, 0xe3, 0xf3, 0xf3, 0xef, 0x39, 0x1e, 0x1e, 0xe0, 0x01, 0xfe, 0xc7, 0xff, 0xff, 0x0f, 0x7c, };
-static unsigned char sdl_std_cursor_pirate[] = {0xe0, 0x01, 0xf0, 0x03, 0xf8, 0x07, 0xcc, 0x0c, 0xcc, 0x0c, 0xf8, 0x07, 0xf0, 0x03, 0xe0, 0x01, 0xe1, 0x21, 0xe1, 0x61, 0xc2, 0x10, 0x1c, 0x0e, 0xe0, 0x01, 0xf8, 0x47, 0x0f, 0x7c, 0x01, 0x20, };
-#define sdl_std_cursor_WIDTH_pirate 16
+#define sdl_std_cursor_HOT_X_question_arrow -4
+#define sdl_std_cursor_HOT_Y_question_arrow -8
+
+static unsigned char sdl_std_cursor_mask_pirate[] = {
+ 0xf0, 0x03, 0xf8, 0x07, 0xfc, 0x0f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfc, 0x0f, 0xf8, 0x07, 0xf1, 0x83,
+ 0xf1, 0xe3, 0xf3, 0xf3, 0xef, 0x39, 0x1e, 0x1e, 0xe0, 0x01, 0xfe, 0xc7, 0xff, 0xff, 0x0f, 0x7c,
+};
+static unsigned char sdl_std_cursor_pirate[] = {
+ 0xe0, 0x01, 0xf0, 0x03, 0xf8, 0x07, 0xcc, 0x0c, 0xcc, 0x0c, 0xf8, 0x07, 0xf0, 0x03, 0xe0, 0x01,
+ 0xe1, 0x21, 0xe1, 0x61, 0xc2, 0x10, 0x1c, 0x0e, 0xe0, 0x01, 0xf8, 0x47, 0x0f, 0x7c, 0x01, 0x20,
+};
+#define sdl_std_cursor_WIDTH_pirate 16
#define sdl_std_cursor_HEIGHT_pirate 16
-#define sdl_std_cursor_HOT_X_pirate -7
-#define sdl_std_cursor_HOT_Y_pirate -4
-
-static unsigned char sdl_std_cursor_mask_left_side[] = {0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x03, 0x8f, 0x03, 0xcf, 0x01, 0xef, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x00, 0xcf, 0x01, 0x8f, 0x03, 0x0f, 0x03, 0x0f, 0x00, 0x0f, 0x00, };
-static unsigned char sdl_std_cursor_left_side[] = {0x03, 0x00, 0x03, 0x00, 0x83, 0x00, 0x43, 0x00, 0x23, 0x00, 0x13, 0x00, 0xfb, 0x3f, 0x13, 0x00, 0x23, 0x00, 0x43, 0x00, 0x83, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_left_side 16
+#define sdl_std_cursor_HOT_X_pirate -7
+#define sdl_std_cursor_HOT_Y_pirate -4
+
+static unsigned char sdl_std_cursor_mask_left_side[] = {
+ 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x03, 0x8f, 0x03, 0xcf, 0x01, 0xef, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xef, 0x00, 0xcf, 0x01, 0x8f, 0x03, 0x0f, 0x03, 0x0f, 0x00, 0x0f, 0x00,
+};
+static unsigned char sdl_std_cursor_left_side[] = {
+ 0x03, 0x00, 0x03, 0x00, 0x83, 0x00, 0x43, 0x00, 0x23, 0x00, 0x13, 0x00, 0xfb, 0x3f, 0x13,
+ 0x00, 0x23, 0x00, 0x43, 0x00, 0x83, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_left_side 16
#define sdl_std_cursor_HEIGHT_left_side 15
-#define sdl_std_cursor_HOT_X_left_side 0
-#define sdl_std_cursor_HOT_Y_left_side -7
-
-static unsigned char sdl_std_cursor_mask_left_ptr[] = {0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x03, 0x7f, 0x00, 0xf7, 0x00, 0xf3, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xc0, 0x00, };
-static unsigned char sdl_std_cursor_left_ptr[] = {0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x3e, 0x00, 0x36, 0x00, 0x62, 0x00, 0x60, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_left_ptr 10
+#define sdl_std_cursor_HOT_X_left_side 0
+#define sdl_std_cursor_HOT_Y_left_side -7
+
+static unsigned char sdl_std_cursor_mask_left_ptr[] = {
+ 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01,
+ 0xff, 0x03, 0xff, 0x03, 0x7f, 0x00, 0xf7, 0x00, 0xf3, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xc0, 0x00,
+};
+static unsigned char sdl_std_cursor_left_ptr[] = {
+ 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0xfe, 0x00,
+ 0xfe, 0x00, 0x3e, 0x00, 0x36, 0x00, 0x62, 0x00, 0x60, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_left_ptr 10
#define sdl_std_cursor_HEIGHT_left_ptr 16
-#define sdl_std_cursor_HOT_X_left_ptr -8
-#define sdl_std_cursor_HOT_Y_left_ptr -14
-
-static unsigned char sdl_std_cursor_mask_exchange[] = {0xe3, 0x07, 0xf7, 0x0f, 0xff, 0x1f, 0xff, 0x3f, 0x3f, 0x38, 0xff, 0x30, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x0c, 0xfe, 0x1c, 0xfc, 0xfc, 0xff, 0xf8, 0xff, 0xf0, 0xef, 0xe0, 0xc7, };
-static unsigned char sdl_std_cursor_exchange[] = {0xf1, 0x03, 0xfb, 0x07, 0x1f, 0x0c, 0x09, 0x08, 0x19, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x26, 0x04, 0x24, 0x0c, 0x3e, 0xf8, 0x37, 0xf0, 0x23, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_exchange 16
+#define sdl_std_cursor_HOT_X_left_ptr -8
+#define sdl_std_cursor_HOT_Y_left_ptr -14
+
+static unsigned char sdl_std_cursor_mask_exchange[] = {
+ 0xe3, 0x07, 0xf7, 0x0f, 0xff, 0x1f, 0xff, 0x3f, 0x3f, 0x38, 0xff, 0x30, 0xff, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00, 0xff, 0x0c, 0xfe, 0x1c, 0xfc, 0xfc, 0xff, 0xf8, 0xff, 0xf0, 0xef, 0xe0, 0xc7,
+};
+static unsigned char sdl_std_cursor_exchange[] = {
+ 0xf1, 0x03, 0xfb, 0x07, 0x1f, 0x0c, 0x09, 0x08, 0x19, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0x00, 0x26, 0x04, 0x24, 0x0c, 0x3e, 0xf8, 0x37, 0xf0, 0x23, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_exchange 16
#define sdl_std_cursor_HEIGHT_exchange 16
-#define sdl_std_cursor_HOT_X_exchange -6
-#define sdl_std_cursor_HOT_Y_exchange -8
-
-static unsigned char sdl_std_cursor_mask_crosshair[] = {0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, };
-static unsigned char sdl_std_cursor_crosshair[] = {0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_crosshair 16
+#define sdl_std_cursor_HOT_X_exchange -6
+#define sdl_std_cursor_HOT_Y_exchange -8
+
+static unsigned char sdl_std_cursor_mask_crosshair[] = {
+ 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
+};
+static unsigned char sdl_std_cursor_crosshair[] = {
+ 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7f, 0xff,
+ 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_crosshair 16
#define sdl_std_cursor_HEIGHT_crosshair 16
-#define sdl_std_cursor_HOT_X_crosshair -7
-#define sdl_std_cursor_HOT_Y_crosshair -8
-
-static unsigned char sdl_std_cursor_mask_bottom_side[] = {0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xcc, 0x19, 0xdc, 0x1d, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, };
-static unsigned char sdl_std_cursor_bottom_side[] = {0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x44, 0x04, 0x48, 0x02, 0x50, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_bottom_side 15
+#define sdl_std_cursor_HOT_X_crosshair -7
+#define sdl_std_cursor_HOT_Y_crosshair -8
+
+static unsigned char sdl_std_cursor_mask_bottom_side[] = {
+ 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xcc, 0x19, 0xdc, 0x1d,
+ 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f,
+};
+static unsigned char sdl_std_cursor_bottom_side[] = {
+ 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x44, 0x04, 0x48, 0x02,
+ 0x50, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_bottom_side 15
#define sdl_std_cursor_HEIGHT_bottom_side 16
-#define sdl_std_cursor_HOT_X_bottom_side -6
-#define sdl_std_cursor_HOT_Y_bottom_side -1
-
-static unsigned char sdl_std_cursor_mask_bottom_right_corner[] = {0x00, 0xf0, 0x00, 0xf0, 0x0c, 0xf7, 0x1c, 0xf7, 0x38, 0xf7, 0x70, 0xf7, 0xe0, 0xf7, 0xc0, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
-static unsigned char sdl_std_cursor_bottom_right_corner[] = {0x00, 0x30, 0x00, 0x30, 0x04, 0x31, 0x08, 0x31, 0x10, 0x31, 0x20, 0x31, 0x40, 0x31, 0x80, 0x31, 0xfc, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_bottom_right_corner 16
+#define sdl_std_cursor_HOT_X_bottom_side -6
+#define sdl_std_cursor_HOT_Y_bottom_side -1
+
+static unsigned char sdl_std_cursor_mask_bottom_right_corner[] = {
+ 0x00, 0xf0, 0x00, 0xf0, 0x0c, 0xf7, 0x1c, 0xf7, 0x38, 0xf7, 0x70, 0xf7, 0xe0, 0xf7, 0xc0, 0xf7,
+ 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+static unsigned char sdl_std_cursor_bottom_right_corner[] = {
+ 0x00, 0x30, 0x00, 0x30, 0x04, 0x31, 0x08, 0x31, 0x10, 0x31, 0x20, 0x31, 0x40, 0x31, 0x80, 0x31,
+ 0xfc, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_bottom_right_corner 16
#define sdl_std_cursor_HEIGHT_bottom_right_corner 16
-#define sdl_std_cursor_HOT_X_bottom_right_corner -13
-#define sdl_std_cursor_HOT_Y_bottom_right_corner -1
-
-static unsigned char sdl_std_cursor_mask_bottom_left_corner[] = {0x0f, 0x00, 0x0f, 0x00, 0xef, 0x30, 0xef, 0x38, 0xef, 0x1c, 0xef, 0x0e, 0xef, 0x07, 0xef, 0x03, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
-static unsigned char sdl_std_cursor_bottom_left_corner[] = {0x03, 0x00, 0x03, 0x00, 0x23, 0x08, 0x23, 0x04, 0x23, 0x02, 0x23, 0x01, 0xa3, 0x00, 0x63, 0x00, 0xe3, 0x0f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_bottom_left_corner 16
+#define sdl_std_cursor_HOT_X_bottom_right_corner -13
+#define sdl_std_cursor_HOT_Y_bottom_right_corner -1
+
+static unsigned char sdl_std_cursor_mask_bottom_left_corner[] = {
+ 0x0f, 0x00, 0x0f, 0x00, 0xef, 0x30, 0xef, 0x38, 0xef, 0x1c, 0xef, 0x0e, 0xef, 0x07, 0xef, 0x03,
+ 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+static unsigned char sdl_std_cursor_bottom_left_corner[] = {
+ 0x03, 0x00, 0x03, 0x00, 0x23, 0x08, 0x23, 0x04, 0x23, 0x02, 0x23, 0x01, 0xa3, 0x00, 0x63, 0x00,
+ 0xe3, 0x0f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_bottom_left_corner 16
#define sdl_std_cursor_HEIGHT_bottom_left_corner 16
-#define sdl_std_cursor_HOT_X_bottom_left_corner 0
-#define sdl_std_cursor_HOT_Y_bottom_left_corner -1
-
-static unsigned char sdl_std_cursor_mask_arrow[] = {0x00, 0xe0, 0x00, 0xf8, 0x00, 0xfe, 0x80, 0x7f, 0xe0, 0x7f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 0x1f, 0xe0, 0x1f, 0xf0, 0x0f, 0xf8, 0x0f, 0x7c, 0x07, 0x3e, 0x07, 0x1f, 0x02, 0x0e, 0x00, 0x04, 0x00, };
-static unsigned char sdl_std_cursor_arrow[] = {0x00, 0x30, 0x00, 0x3c, 0x00, 0x1f, 0xc0, 0x1f, 0xf0, 0x0f, 0xfc, 0x0f, 0xc0, 0x07, 0xe0, 0x07, 0x70, 0x03, 0x38, 0x03, 0x1c, 0x01, 0x0e, 0x01, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, };
-#define sdl_std_cursor_WIDTH_arrow 16
+#define sdl_std_cursor_HOT_X_bottom_left_corner 0
+#define sdl_std_cursor_HOT_Y_bottom_left_corner -1
+
+static unsigned char sdl_std_cursor_mask_arrow[] = {
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0xfe, 0x80, 0x7f, 0xe0, 0x7f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 0x1f,
+ 0xe0, 0x1f, 0xf0, 0x0f, 0xf8, 0x0f, 0x7c, 0x07, 0x3e, 0x07, 0x1f, 0x02, 0x0e, 0x00, 0x04, 0x00,
+};
+static unsigned char sdl_std_cursor_arrow[] = {
+ 0x00, 0x30, 0x00, 0x3c, 0x00, 0x1f, 0xc0, 0x1f, 0xf0, 0x0f, 0xfc, 0x0f, 0xc0, 0x07, 0xe0, 0x07,
+ 0x70, 0x03, 0x38, 0x03, 0x1c, 0x01, 0x0e, 0x01, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+#define sdl_std_cursor_WIDTH_arrow 16
#define sdl_std_cursor_HEIGHT_arrow 16
-#define sdl_std_cursor_HOT_X_arrow -13
-#define sdl_std_cursor_HOT_Y_arrow -14
+#define sdl_std_cursor_HOT_X_arrow -13
+#define sdl_std_cursor_HOT_Y_arrow -14
/* end cursor data */
-
static SDL_Cursor *sdl_std_cursor_array[(int)GHOST_kStandardCursorNumCursors] = {0};
/* utility function mostly a copy of SDL_CreateCursor but allows us to change
* color and supports blenders flipped bits */
-static SDL_Cursor *
-sdl_ghost_CreateCursor(const Uint8 *data,
- const Uint8 *mask,
- int w,
- int h,
- int hot_x,
- int hot_y)
+static SDL_Cursor *sdl_ghost_CreateCursor(
+ const Uint8 *data, const Uint8 *mask, int w, int h, int hot_x, int hot_y)
{
- SDL_Surface *surface;
- SDL_Cursor *cursor;
- int x, y;
- Uint32 *pixel;
- Uint8 datab = 0, maskb = 0;
- const Uint32 black = 0xFF000000;
- const Uint32 white = 0xFFFFFFFF;
- const Uint32 transparent = 0x00000000;
-
- /* Make sure the width is a multiple of 8 */
- w = ((w + 7) & ~7);
-
- /* Create the surface from a bitmap */
- surface = SDL_CreateRGBSurface(0, w, h, 32,
- 0x00FF0000,
- 0x0000FF00,
- 0x000000FF,
- 0xFF000000);
- if (!surface) {
- return NULL;
- }
- for (y = 0; y < h; ++y) {
- pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
- for (x = 0; x < w; ++x) {
- if ((x % 8) == 0) {
- datab = *data++;
- maskb = *mask++;
-
- /* reverse bit order */
- datab = (datab * 0x0202020202ULL & 0x010884422010ULL) % 1023;
- maskb = (maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023;
- }
- if (maskb & 0x80) {
- *pixel++ = (datab & 0x80) ? white : black;
- }
- else {
- *pixel++ = (datab & 0x80) ? white : transparent;
- }
- datab <<= 1;
- maskb <<= 1;
- }
- }
-
- cursor = SDL_CreateColorCursor(surface, hot_x, hot_y);
-
- SDL_FreeSurface(surface);
-
- return cursor;
+ SDL_Surface *surface;
+ SDL_Cursor *cursor;
+ int x, y;
+ Uint32 *pixel;
+ Uint8 datab = 0, maskb = 0;
+ const Uint32 black = 0xFF000000;
+ const Uint32 white = 0xFFFFFFFF;
+ const Uint32 transparent = 0x00000000;
+
+ /* Make sure the width is a multiple of 8 */
+ w = ((w + 7) & ~7);
+
+ /* Create the surface from a bitmap */
+ surface = SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+ if (!surface) {
+ return NULL;
+ }
+ for (y = 0; y < h; ++y) {
+ pixel = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch);
+ for (x = 0; x < w; ++x) {
+ if ((x % 8) == 0) {
+ datab = *data++;
+ maskb = *mask++;
+
+ /* reverse bit order */
+ datab = (datab * 0x0202020202ULL & 0x010884422010ULL) % 1023;
+ maskb = (maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023;
+ }
+ if (maskb & 0x80) {
+ *pixel++ = (datab & 0x80) ? white : black;
+ }
+ else {
+ *pixel++ = (datab & 0x80) ? white : transparent;
+ }
+ datab <<= 1;
+ maskb <<= 1;
+ }
+ }
+
+ cursor = SDL_CreateColorCursor(surface, hot_x, hot_y);
+
+ SDL_FreeSurface(surface);
+
+ return cursor;
}
/* TODO, this is currently never freed but it wont leak either. */
@@ -454,122 +587,107 @@ static void sdl_cursor_init(void)
{
#define DEF_CURSOR(name, ind) \
- { \
- sdl_std_cursor_array[(int)ind] = \
- sdl_ghost_CreateCursor(sdl_std_cursor_##name, \
- sdl_std_cursor_mask_##name, \
- sdl_std_cursor_WIDTH_##name, \
- sdl_std_cursor_HEIGHT_##name, \
- (sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \
- (sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1); \
- assert(sdl_std_cursor_array[(int)ind] != NULL); \
- } (void)0
-
-
- DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault);
- DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow);
- DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow);
- DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo); // TODO, replace this one.
- DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy);
- DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp);
- DEF_CURSOR(exchange, GHOST_kStandardCursorCycle);
- DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray);
- DEF_CURSOR(watch, GHOST_kStandardCursorWait);
- DEF_CURSOR(xterm, GHOST_kStandardCursorText);
- DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair);
- DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown);
- DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight);
- DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide);
- DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide);
- DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide);
- DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide);
- DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner);
- DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner);
- DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner);
- DEF_CURSOR(bottom_left_corner, GHOST_kStandardCursorBottomLeftCorner);
- DEF_CURSOR(arrow, GHOST_kStandardCursorCopy);
- //DEF_CURSOR(arrow, GHOST_kStandardCursorCustom);
- DEF_CURSOR(arrow, GHOST_kStandardCursorPencil);
+ { \
+ sdl_std_cursor_array[(int)ind] = sdl_ghost_CreateCursor( \
+ sdl_std_cursor_##name, \
+ sdl_std_cursor_mask_##name, \
+ sdl_std_cursor_WIDTH_##name, \
+ sdl_std_cursor_HEIGHT_##name, \
+ (sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \
+ (sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1); \
+ assert(sdl_std_cursor_array[(int)ind] != NULL); \
+ } \
+ (void)0
+
+ DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault);
+ DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow);
+ DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow);
+ DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo); // TODO, replace this one.
+ DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy);
+ DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp);
+ DEF_CURSOR(exchange, GHOST_kStandardCursorCycle);
+ DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray);
+ DEF_CURSOR(watch, GHOST_kStandardCursorWait);
+ DEF_CURSOR(xterm, GHOST_kStandardCursorText);
+ DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair);
+ DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown);
+ DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight);
+ DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide);
+ DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide);
+ DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide);
+ DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide);
+ DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner);
+ DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner);
+ DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner);
+ DEF_CURSOR(bottom_left_corner, GHOST_kStandardCursorBottomLeftCorner);
+ DEF_CURSOR(arrow, GHOST_kStandardCursorCopy);
+ //DEF_CURSOR(arrow, GHOST_kStandardCursorCustom);
+ DEF_CURSOR(arrow, GHOST_kStandardCursorPencil);
#undef DEF_CURSOR
-
}
-
-
-GHOST_TSuccess
-GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
+GHOST_TSuccess GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
{
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess
-GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape)
+GHOST_TSuccess GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape)
{
- if (sdl_std_cursor_array[0] == NULL) {
- sdl_cursor_init();
- }
+ if (sdl_std_cursor_array[0] == NULL) {
+ sdl_cursor_init();
+ }
- SDL_SetCursor(sdl_std_cursor_array[(int)shape]);
- return GHOST_kSuccess;
+ SDL_SetCursor(sdl_std_cursor_array[(int)shape]);
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess
-GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX,
- int hotY)
+GHOST_TSuccess GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY)
{
- return setWindowCustomCursorShape((GHOST_TUns8 *)bitmap,
- (GHOST_TUns8 *)mask,
- 16, 16,
- hotX, hotY,
- 0, 1);
+ return setWindowCustomCursorShape(
+ (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1);
}
-
-GHOST_TSuccess
-GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex, int sizey,
- int hotX, int hotY,
- int fg_color, int bg_color)
+GHOST_TSuccess GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color)
{
- if (m_sdl_custom_cursor) {
- SDL_FreeCursor(m_sdl_custom_cursor);
- }
+ if (m_sdl_custom_cursor) {
+ SDL_FreeCursor(m_sdl_custom_cursor);
+ }
- m_sdl_custom_cursor = sdl_ghost_CreateCursor((const Uint8 *)bitmap,
- (const Uint8 *)mask,
- sizex, sizex,
- hotX, hotY);
+ m_sdl_custom_cursor = sdl_ghost_CreateCursor(
+ (const Uint8 *)bitmap, (const Uint8 *)mask, sizex, sizex, hotX, hotY);
- SDL_SetCursor(m_sdl_custom_cursor);
- return GHOST_kSuccess;
+ SDL_SetCursor(m_sdl_custom_cursor);
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess
-GHOST_WindowSDL::setWindowCursorVisibility(bool visible)
+GHOST_TSuccess GHOST_WindowSDL::setWindowCursorVisibility(bool visible)
{
- SDL_ShowCursor(visible);
- return GHOST_kSuccess;
+ SDL_ShowCursor(visible);
+ return GHOST_kSuccess;
}
-GHOST_TUns16
-GHOST_WindowSDL::getDPIHint()
+GHOST_TUns16 GHOST_WindowSDL::getDPIHint()
{
- int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win);
- if (displayIndex < 0) {
- return 96;
- }
+ int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win);
+ if (displayIndex < 0) {
+ return 96;
+ }
- float ddpi;
- if (SDL_GetDisplayDPI(displayIndex, &ddpi, NULL, NULL) != 0) {
- return 96;
- }
+ float ddpi;
+ if (SDL_GetDisplayDPI(displayIndex, &ddpi, NULL, NULL) != 0) {
+ return 96;
+ }
- return (int)ddpi;
+ return (int)ddpi;
}
diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h
index c7325240862..3a9a1ad7df2 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.h
+++ b/intern/ghost/intern/GHOST_WindowSDL.h
@@ -28,7 +28,7 @@
#include <map>
extern "C" {
- #include "SDL.h"
+#include "SDL.h"
}
#if !SDL_VERSION_ATLEAST(2, 0, 0)
@@ -38,133 +38,128 @@ extern "C" {
class STR_String;
class GHOST_SystemSDL;
-class GHOST_WindowSDL : public GHOST_Window
-{
-private:
- GHOST_SystemSDL *m_system;
- bool m_valid_setup;
- bool m_invalid_window;
+class GHOST_WindowSDL : public GHOST_Window {
+ private:
+ GHOST_SystemSDL *m_system;
+ bool m_valid_setup;
+ bool m_invalid_window;
- SDL_Window *m_sdl_win;
- SDL_Cursor *m_sdl_custom_cursor;
+ SDL_Window *m_sdl_win;
+ SDL_Cursor *m_sdl_custom_cursor;
-public:
+ public:
+ const GHOST_TabletData *GetTabletData()
+ {
+ return NULL;
+ }
+
+ GHOST_WindowSDL(GHOST_SystemSDL *system,
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const GHOST_TEmbedderWindowID parentWindow,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false,
+ const bool exclusive = false,
+ const GHOST_TUns16 numOfAASamples = 0);
- const GHOST_TabletData *GetTabletData() {
- return NULL;
- }
+ ~GHOST_WindowSDL();
- GHOST_WindowSDL(GHOST_SystemSDL *system,
- const STR_String& title,
- GHOST_TInt32 left, GHOST_TInt32 top,
- GHOST_TUns32 width, GHOST_TUns32 height,
- GHOST_TWindowState state,
- const GHOST_TEmbedderWindowID parentWindow,
- GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false,
- const bool exclusive = false,
- const GHOST_TUns16 numOfAASamples = 0
- );
+ /* SDL specific */
+ SDL_Window *getSDLWindow()
+ {
+ return m_sdl_win;
+ }
- ~GHOST_WindowSDL();
+ GHOST_TSuccess invalidate(void);
- /* SDL specific */
- SDL_Window *
- getSDLWindow()
- {
- return m_sdl_win;
- }
+ /**
+ * called by the X11 system implementation when expose events
+ * for the window have been pushed onto the GHOST queue
+ */
+ void validate()
+ {
+ m_invalid_window = false;
+ }
- GHOST_TSuccess invalidate(void);
+ bool getValid() const;
- /**
- * called by the X11 system implementation when expose events
- * for the window have been pushed onto the GHOST queue
- */
+ void getWindowBounds(GHOST_Rect &bounds) const;
+ void getClientBounds(GHOST_Rect &bounds) const;
- void validate()
- {
- m_invalid_window = false;
- }
+ protected:
+ /**
+ * \param type The type of rendering context create.
+ * \return Indication of success.
+ */
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
- bool getValid() const;
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
- void getWindowBounds(GHOST_Rect& bounds) const;
- void getClientBounds(GHOST_Rect& bounds) const;
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
-protected:
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
- /**
- * \param type The type of rendering context create.
- * \return Indication of success.
- */
- GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color);
- GHOST_TSuccess
- setWindowCursorGrab(GHOST_TGrabCursorMode mode);
+ GHOST_TSuccess setWindowCursorVisibility(bool visible);
- GHOST_TSuccess
- setWindowCursorShape(GHOST_TStandardCursor shape);
+ void setTitle(const STR_String &title);
- GHOST_TSuccess
- setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX, int hotY);
+ void getTitle(STR_String &title) const;
- GHOST_TSuccess
- setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex, int sizey,
- int hotX, int hotY,
- int fg_color, int bg_color);
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
- GHOST_TSuccess
- setWindowCursorVisibility(bool visible);
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
- void
- setTitle(const STR_String& title);
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
- void
- getTitle(STR_String& title) const;
+ void screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
- GHOST_TSuccess
- setClientWidth(GHOST_TUns32 width);
+ void clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
- GHOST_TSuccess
- setClientHeight(GHOST_TUns32 height);
+ GHOST_TSuccess setState(GHOST_TWindowState state);
+
+ GHOST_TWindowState getState() const;
- GHOST_TSuccess
- setClientSize(GHOST_TUns32 width,
- GHOST_TUns32 height);
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order)
+ {
+ // TODO
+ return GHOST_kSuccess;
+ }
+
+ // TODO
+ GHOST_TSuccess beginFullScreen() const
+ {
+ return GHOST_kFailure;
+ }
- void
- screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY,
- GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+ GHOST_TSuccess endFullScreen() const
+ {
+ return GHOST_kFailure;
+ }
- void
- clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY,
- GHOST_TInt32& outX, GHOST_TInt32& outY) const;
-
- GHOST_TSuccess
- setState(GHOST_TWindowState state);
-
- GHOST_TWindowState
- getState() const;
-
- GHOST_TSuccess setOrder(GHOST_TWindowOrder order)
- {
- // TODO
- return GHOST_kSuccess;
- }
-
- // TODO
- GHOST_TSuccess beginFullScreen() const { return GHOST_kFailure; }
-
- GHOST_TSuccess endFullScreen() const { return GHOST_kFailure; }
-
- GHOST_TUns16 getDPIHint();
+ GHOST_TUns16 getDPIHint();
};
-
-#endif // __GHOST_WINDOWSDL_H__
+#endif // __GHOST_WINDOWSDL_H__
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 21d1ec0c5b1..2feda927998 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -36,7 +36,7 @@
# include "GHOST_ContextWGL.h"
#endif
#ifdef WIN32_COMPOSITING
-#include <Dwmapi.h>
+# include <Dwmapi.h>
#endif
#include <windowsx.h>
@@ -45,35 +45,31 @@
#include <assert.h>
#ifndef GET_POINTERID_WPARAM
-#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
-#endif // GET_POINTERID_WPARAM
+# define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
+#endif // GET_POINTERID_WPARAM
const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass";
const int GHOST_WindowWin32::s_maxTitleLength = 128;
-
-
-
/* force NVidia Optimus to used dedicated graphics */
extern "C" {
- __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
- const STR_String &title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- bool wantStereoVisual,
- bool alphaBackground,
- GHOST_TUns16 wantNumOfAASamples,
- GHOST_TEmbedderWindowID parentwindowhwnd,
- bool is_debug)
- : GHOST_Window(width, height, state,
- wantStereoVisual, false, wantNumOfAASamples),
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ bool wantStereoVisual,
+ bool alphaBackground,
+ GHOST_TUns16 wantNumOfAASamples,
+ GHOST_TEmbedderWindowID parentwindowhwnd,
+ bool is_debug)
+ : GHOST_Window(width, height, state, wantStereoVisual, false, wantNumOfAASamples),
m_inLiveResize(false),
m_system(system),
m_hDC(0),
@@ -90,1144 +86,1196 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_parentWindowHwnd(parentwindowhwnd),
m_debug_context(is_debug)
{
- // Initialize tablet variables
- memset(&m_wintab, 0, sizeof(m_wintab));
- memset(&m_tabletData, 0, sizeof(m_tabletData));
- m_tabletData.Active = GHOST_kTabletModeNone;
+ // Initialize tablet variables
+ memset(&m_wintab, 0, sizeof(m_wintab));
+ memset(&m_tabletData, 0, sizeof(m_tabletData));
+ m_tabletData.Active = GHOST_kTabletModeNone;
- // Create window
- if (state != GHOST_kWindowStateFullScreen) {
- RECT rect;
- MONITORINFO monitor;
- GHOST_TUns32 tw, th;
+ // Create window
+ if (state != GHOST_kWindowStateFullScreen) {
+ RECT rect;
+ MONITORINFO monitor;
+ GHOST_TUns32 tw, th;
#ifndef _MSC_VER
- int cxsizeframe = GetSystemMetrics(SM_CXSIZEFRAME);
- int cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME);
+ int cxsizeframe = GetSystemMetrics(SM_CXSIZEFRAME);
+ int cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME);
#else
- // MSVC 2012+ returns bogus values from GetSystemMetrics, bug in Windows
- // http://connect.microsoft.com/VisualStudio/feedback/details/753224/regression-getsystemmetrics-delivers-different-values
- RECT cxrect = {0, 0, 0, 0};
- AdjustWindowRectEx(&cxrect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0);
-
- int cxsizeframe = abs(cxrect.bottom);
- int cysizeframe = abs(cxrect.left);
+ // MSVC 2012+ returns bogus values from GetSystemMetrics, bug in Windows
+ // http://connect.microsoft.com/VisualStudio/feedback/details/753224/regression-getsystemmetrics-delivers-different-values
+ RECT cxrect = {0, 0, 0, 0};
+ AdjustWindowRectEx(
+ &cxrect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0);
+
+ int cxsizeframe = abs(cxrect.bottom);
+ int cysizeframe = abs(cxrect.left);
#endif
- width += cxsizeframe * 2;
- height += cysizeframe * 2 + GetSystemMetrics(SM_CYCAPTION);
-
- rect.left = left;
- rect.right = left + width;
- rect.top = top;
- rect.bottom = top + height;
-
- monitor.cbSize = sizeof(monitor);
- monitor.dwFlags = 0;
-
- // take taskbar into account
- GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &monitor);
-
- th = monitor.rcWork.bottom - monitor.rcWork.top;
- tw = monitor.rcWork.right - monitor.rcWork.left;
-
- if (tw < width) {
- width = tw;
- left = monitor.rcWork.left;
- }
- else if (monitor.rcWork.right < left + (int)width)
- left = monitor.rcWork.right - width;
- else if (left < monitor.rcWork.left)
- left = monitor.rcWork.left;
-
- if (th < height) {
- height = th;
- top = monitor.rcWork.top;
- }
- else if (monitor.rcWork.bottom < top + (int)height)
- top = monitor.rcWork.bottom - height;
- else if (top < monitor.rcWork.top)
- top = monitor.rcWork.top;
-
- int wintype = WS_OVERLAPPEDWINDOW;
- if (m_parentWindowHwnd != 0) {
- wintype = WS_CHILD;
- GetWindowRect((HWND)m_parentWindowHwnd, &rect);
- left = 0;
- top = 0;
- width = rect.right - rect.left;
- height = rect.bottom - rect.top;
- }
-
- wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
- m_hWnd = ::CreateWindowW(
- s_windowClassName, // pointer to registered class name
- title_16, // pointer to window name
- wintype, // window style
- left, // horizontal position of window
- top, // vertical position of window
- width, // window width
- height, // window height
- (HWND)m_parentWindowHwnd, // handle to parent or owner window
- 0, // handle to menu or child-window identifier
- ::GetModuleHandle(0), // handle to application instance
- 0); // pointer to window-creation data
- free(title_16);
- }
- else {
- wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
- m_hWnd = ::CreateWindowW(
- s_windowClassName, // pointer to registered class name
- title_16, // pointer to window name
- WS_MAXIMIZE, // window style
- left, // horizontal position of window
- top, // vertical position of window
- width, // window width
- height, // window height
- HWND_DESKTOP, // handle to parent or owner window
- 0, // handle to menu or child-window identifier
- ::GetModuleHandle(0), // handle to application instance
- 0); // pointer to window-creation data
- free(title_16);
- }
-
- m_user32 = ::LoadLibrary("user32.dll");
-
- if (m_hWnd) {
- if (m_user32) {
- // Touch enabled screens with pen support by default have gestures
- // enabled, which results in a delay between the pointer down event
- // and the first move when using the stylus. RegisterTouchWindow
- // disables the new gesture architecture enabling the events to be
- // sent immediately to the application rather than being absorbed by
- // the gesture API.
- GHOST_WIN32_RegisterTouchWindow pRegisterTouchWindow =
- (GHOST_WIN32_RegisterTouchWindow)GetProcAddress(m_user32, "RegisterTouchWindow");
- if (pRegisterTouchWindow) {
- pRegisterTouchWindow(m_hWnd, 0);
- }
- }
-
- // Register this window as a droptarget. Requires m_hWnd to be valid.
- // Note that OleInitialize(0) has to be called prior to this. Done in GHOST_SystemWin32.
- m_dropTarget = new GHOST_DropTargetWin32(this, m_system);
- if (m_dropTarget) {
- ::RegisterDragDrop(m_hWnd, m_dropTarget);
- }
-
- // Store a pointer to this class in the window structure
- ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR) this);
-
- if (!m_system->m_windowFocus) {
- // Lower to bottom and don't activate if we don't want focus
- ::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- }
-
- // Store the device context
- m_hDC = ::GetDC(m_hWnd);
-
- GHOST_TSuccess success = setDrawingContextType(type);
-
- if (success) {
- // Show the window
- int nCmdShow;
- switch (state) {
- case GHOST_kWindowStateMaximized:
- nCmdShow = SW_SHOWMAXIMIZED;
- break;
- case GHOST_kWindowStateMinimized:
- nCmdShow = (m_system->m_windowFocus) ? SW_SHOWMINIMIZED : SW_SHOWMINNOACTIVE;
- break;
- case GHOST_kWindowStateNormal:
- default:
- nCmdShow = (m_system->m_windowFocus) ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
- break;
- }
-
- ::ShowWindow(m_hWnd, nCmdShow);
+ width += cxsizeframe * 2;
+ height += cysizeframe * 2 + GetSystemMetrics(SM_CYCAPTION);
+
+ rect.left = left;
+ rect.right = left + width;
+ rect.top = top;
+ rect.bottom = top + height;
+
+ monitor.cbSize = sizeof(monitor);
+ monitor.dwFlags = 0;
+
+ // take taskbar into account
+ GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &monitor);
+
+ th = monitor.rcWork.bottom - monitor.rcWork.top;
+ tw = monitor.rcWork.right - monitor.rcWork.left;
+
+ if (tw < width) {
+ width = tw;
+ left = monitor.rcWork.left;
+ }
+ else if (monitor.rcWork.right < left + (int)width)
+ left = monitor.rcWork.right - width;
+ else if (left < monitor.rcWork.left)
+ left = monitor.rcWork.left;
+
+ if (th < height) {
+ height = th;
+ top = monitor.rcWork.top;
+ }
+ else if (monitor.rcWork.bottom < top + (int)height)
+ top = monitor.rcWork.bottom - height;
+ else if (top < monitor.rcWork.top)
+ top = monitor.rcWork.top;
+
+ int wintype = WS_OVERLAPPEDWINDOW;
+ if (m_parentWindowHwnd != 0) {
+ wintype = WS_CHILD;
+ GetWindowRect((HWND)m_parentWindowHwnd, &rect);
+ left = 0;
+ top = 0;
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+ }
+
+ wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
+ m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name
+ title_16, // pointer to window name
+ wintype, // window style
+ left, // horizontal position of window
+ top, // vertical position of window
+ width, // window width
+ height, // window height
+ (HWND)m_parentWindowHwnd, // handle to parent or owner window
+ 0, // handle to menu or child-window identifier
+ ::GetModuleHandle(0), // handle to application instance
+ 0); // pointer to window-creation data
+ free(title_16);
+ }
+ else {
+ wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
+ m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name
+ title_16, // pointer to window name
+ WS_MAXIMIZE, // window style
+ left, // horizontal position of window
+ top, // vertical position of window
+ width, // window width
+ height, // window height
+ HWND_DESKTOP, // handle to parent or owner window
+ 0, // handle to menu or child-window identifier
+ ::GetModuleHandle(0), // handle to application instance
+ 0); // pointer to window-creation data
+ free(title_16);
+ }
+
+ m_user32 = ::LoadLibrary("user32.dll");
+
+ if (m_hWnd) {
+ if (m_user32) {
+ // Touch enabled screens with pen support by default have gestures
+ // enabled, which results in a delay between the pointer down event
+ // and the first move when using the stylus. RegisterTouchWindow
+ // disables the new gesture architecture enabling the events to be
+ // sent immediately to the application rather than being absorbed by
+ // the gesture API.
+ GHOST_WIN32_RegisterTouchWindow pRegisterTouchWindow = (GHOST_WIN32_RegisterTouchWindow)
+ GetProcAddress(m_user32, "RegisterTouchWindow");
+ if (pRegisterTouchWindow) {
+ pRegisterTouchWindow(m_hWnd, 0);
+ }
+ }
+
+ // Register this window as a droptarget. Requires m_hWnd to be valid.
+ // Note that OleInitialize(0) has to be called prior to this. Done in GHOST_SystemWin32.
+ m_dropTarget = new GHOST_DropTargetWin32(this, m_system);
+ if (m_dropTarget) {
+ ::RegisterDragDrop(m_hWnd, m_dropTarget);
+ }
+
+ // Store a pointer to this class in the window structure
+ ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);
+
+ if (!m_system->m_windowFocus) {
+ // Lower to bottom and don't activate if we don't want focus
+ ::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ }
+
+ // Store the device context
+ m_hDC = ::GetDC(m_hWnd);
+
+ GHOST_TSuccess success = setDrawingContextType(type);
+
+ if (success) {
+ // Show the window
+ int nCmdShow;
+ switch (state) {
+ case GHOST_kWindowStateMaximized:
+ nCmdShow = SW_SHOWMAXIMIZED;
+ break;
+ case GHOST_kWindowStateMinimized:
+ nCmdShow = (m_system->m_windowFocus) ? SW_SHOWMINIMIZED : SW_SHOWMINNOACTIVE;
+ break;
+ case GHOST_kWindowStateNormal:
+ default:
+ nCmdShow = (m_system->m_windowFocus) ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
+ break;
+ }
+
+ ::ShowWindow(m_hWnd, nCmdShow);
#ifdef WIN32_COMPOSITING
- if (alphaBackground && parentwindowhwnd == 0) {
+ if (alphaBackground && parentwindowhwnd == 0) {
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- // Create and populate the Blur Behind structure
- DWM_BLURBEHIND bb = { 0 };
+ // Create and populate the Blur Behind structure
+ DWM_BLURBEHIND bb = {0};
- // Enable Blur Behind and apply to the entire client area
- bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
- bb.fEnable = true;
- bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
+ // Enable Blur Behind and apply to the entire client area
+ bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
+ bb.fEnable = true;
+ bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
- // Apply Blur Behind
- hr = DwmEnableBlurBehindWindow(m_hWnd, &bb);
- DeleteObject(bb.hRgnBlur);
- }
+ // Apply Blur Behind
+ hr = DwmEnableBlurBehindWindow(m_hWnd, &bb);
+ DeleteObject(bb.hRgnBlur);
+ }
#endif
- // Force an initial paint of the window
- ::UpdateWindow(m_hWnd);
- }
- else {
- //invalidate the window
- ::DestroyWindow(m_hWnd);
- m_hWnd = NULL;
- }
- }
-
- if (parentwindowhwnd != 0) {
- RAWINPUTDEVICE device = {0};
- device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/
- device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
- device.dwFlags |= RIDEV_INPUTSINK; // makes WM_INPUT is visible for ghost when has parent window
- device.hwndTarget = m_hWnd;
- RegisterRawInputDevices(&device, 1, sizeof(device));
- }
-
- // Initialize Windows Ink
- if (m_user32) {
- m_fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo) ::GetProcAddress(m_user32, "GetPointerInfo");
- m_fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo) ::GetProcAddress(m_user32, "GetPointerPenInfo");
- m_fpGetPointerTouchInfo = (GHOST_WIN32_GetPointerTouchInfo) ::GetProcAddress(m_user32, "GetPointerTouchInfo");
- }
-
- // Initialize Wintab
- m_wintab.handle = ::LoadLibrary("Wintab32.dll");
- if (m_wintab.handle) {
- // Get API functions
- m_wintab.info = (GHOST_WIN32_WTInfo) ::GetProcAddress(m_wintab.handle, "WTInfoA");
- m_wintab.open = (GHOST_WIN32_WTOpen) ::GetProcAddress(m_wintab.handle, "WTOpenA");
- m_wintab.close = (GHOST_WIN32_WTClose) ::GetProcAddress(m_wintab.handle, "WTClose");
- m_wintab.packet = (GHOST_WIN32_WTPacket) ::GetProcAddress(m_wintab.handle, "WTPacket");
- m_wintab.enable = (GHOST_WIN32_WTEnable) ::GetProcAddress(m_wintab.handle, "WTEnable");
- m_wintab.overlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab.handle, "WTOverlap");
-
- // Let's see if we can initialize tablet here.
- // Check if WinTab available by getting system context info.
- LOGCONTEXT lc = { 0 };
- lc.lcOptions |= CXO_SYSTEM;
- if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
- // Now init the tablet
- /* The maximum tablet size, pressure and orientation (tilt) */
- AXIS TabletX, TabletY, Pressure, Orientation[3];
-
- // Open a Wintab context
-
- // Open the context
- lc.lcPktData = PACKETDATA;
- lc.lcPktMode = PACKETMODE;
- lc.lcOptions |= CXO_MESSAGES;
- lc.lcMoveMask = PACKETDATA;
-
- /* Set the entire tablet as active */
- m_wintab.info(WTI_DEVICES, DVC_X, &TabletX);
- m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY);
-
- /* get the max pressure, to divide into a float */
- BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
- if (pressureSupport)
- m_wintab.maxPressure = Pressure.axMax;
- else
- m_wintab.maxPressure = 0;
-
- /* get the max tilt axes, to divide into floats */
- BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
- if (tiltSupport) {
- /* does the tablet support azimuth ([0]) and altitude ([1]) */
- if (Orientation[0].axResolution && Orientation[1].axResolution) {
- /* all this assumes the minimum is 0 */
- m_wintab.maxAzimuth = Orientation[0].axMax;
- m_wintab.maxAltitude = Orientation[1].axMax;
- }
- else { /* no so dont do tilt stuff */
- m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
- }
- }
-
- // The Wintab spec says we must open the context disabled if we are using cursor masks.
- m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE);
- if (m_wintab.enable && m_wintab.tablet) {
- m_wintab.enable(m_wintab.tablet, TRUE);
- }
- }
- }
- CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar);
+ // Force an initial paint of the window
+ ::UpdateWindow(m_hWnd);
+ }
+ else {
+ //invalidate the window
+ ::DestroyWindow(m_hWnd);
+ m_hWnd = NULL;
+ }
+ }
+
+ if (parentwindowhwnd != 0) {
+ RAWINPUTDEVICE device = {0};
+ device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/
+ device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
+ device.dwFlags |=
+ RIDEV_INPUTSINK; // makes WM_INPUT is visible for ghost when has parent window
+ device.hwndTarget = m_hWnd;
+ RegisterRawInputDevices(&device, 1, sizeof(device));
+ }
+
+ // Initialize Windows Ink
+ if (m_user32) {
+ m_fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo)::GetProcAddress(m_user32, "GetPointerInfo");
+ m_fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo)::GetProcAddress(m_user32,
+ "GetPointerPenInfo");
+ m_fpGetPointerTouchInfo = (GHOST_WIN32_GetPointerTouchInfo)::GetProcAddress(
+ m_user32, "GetPointerTouchInfo");
+ }
+
+ // Initialize Wintab
+ m_wintab.handle = ::LoadLibrary("Wintab32.dll");
+ if (m_wintab.handle) {
+ // Get API functions
+ m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA");
+ m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA");
+ m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose");
+ m_wintab.packet = (GHOST_WIN32_WTPacket)::GetProcAddress(m_wintab.handle, "WTPacket");
+ m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable");
+ m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap");
+
+ // Let's see if we can initialize tablet here.
+ // Check if WinTab available by getting system context info.
+ LOGCONTEXT lc = {0};
+ lc.lcOptions |= CXO_SYSTEM;
+ if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
+ // Now init the tablet
+ /* The maximum tablet size, pressure and orientation (tilt) */
+ AXIS TabletX, TabletY, Pressure, Orientation[3];
+
+ // Open a Wintab context
+
+ // Open the context
+ lc.lcPktData = PACKETDATA;
+ lc.lcPktMode = PACKETMODE;
+ lc.lcOptions |= CXO_MESSAGES;
+ lc.lcMoveMask = PACKETDATA;
+
+ /* Set the entire tablet as active */
+ m_wintab.info(WTI_DEVICES, DVC_X, &TabletX);
+ m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY);
+
+ /* get the max pressure, to divide into a float */
+ BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
+ if (pressureSupport)
+ m_wintab.maxPressure = Pressure.axMax;
+ else
+ m_wintab.maxPressure = 0;
+
+ /* get the max tilt axes, to divide into floats */
+ BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
+ if (tiltSupport) {
+ /* does the tablet support azimuth ([0]) and altitude ([1]) */
+ if (Orientation[0].axResolution && Orientation[1].axResolution) {
+ /* all this assumes the minimum is 0 */
+ m_wintab.maxAzimuth = Orientation[0].axMax;
+ m_wintab.maxAltitude = Orientation[1].axMax;
+ }
+ else { /* no so dont do tilt stuff */
+ m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
+ }
+ }
+
+ // The Wintab spec says we must open the context disabled if we are using cursor masks.
+ m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE);
+ if (m_wintab.enable && m_wintab.tablet) {
+ m_wintab.enable(m_wintab.tablet, TRUE);
+ }
+ }
+ }
+ CoCreateInstance(
+ CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar);
}
-
GHOST_WindowWin32::~GHOST_WindowWin32()
{
- if (m_Bar) {
- m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
- m_Bar->Release();
- m_Bar = NULL;
- }
-
- if (m_wintab.handle) {
- if (m_wintab.close && m_wintab.tablet) {
- m_wintab.close(m_wintab.tablet);
- }
-
- FreeLibrary(m_wintab.handle);
- memset(&m_wintab, 0, sizeof(m_wintab));
- }
-
- if (m_user32) {
- FreeLibrary(m_user32);
- m_user32 = NULL;
- m_fpGetPointerInfo = NULL;
- m_fpGetPointerPenInfo = NULL;
- m_fpGetPointerTouchInfo = NULL;
- }
-
- if (m_customCursor) {
- DestroyCursor(m_customCursor);
- m_customCursor = NULL;
- }
-
- if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) {
- ::ReleaseDC(m_hWnd, m_hDC);
- m_hDC = NULL;
- }
-
- if (m_hWnd) {
- if (m_dropTarget) {
- // Disable DragDrop
- RevokeDragDrop(m_hWnd);
- // Release our reference of the DropTarget and it will delete itself eventually.
- m_dropTarget->Release();
- m_dropTarget = NULL;
- }
- ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
- ::DestroyWindow(m_hWnd);
- m_hWnd = 0;
- }
+ if (m_Bar) {
+ m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
+ m_Bar->Release();
+ m_Bar = NULL;
+ }
+
+ if (m_wintab.handle) {
+ if (m_wintab.close && m_wintab.tablet) {
+ m_wintab.close(m_wintab.tablet);
+ }
+
+ FreeLibrary(m_wintab.handle);
+ memset(&m_wintab, 0, sizeof(m_wintab));
+ }
+
+ if (m_user32) {
+ FreeLibrary(m_user32);
+ m_user32 = NULL;
+ m_fpGetPointerInfo = NULL;
+ m_fpGetPointerPenInfo = NULL;
+ m_fpGetPointerTouchInfo = NULL;
+ }
+
+ if (m_customCursor) {
+ DestroyCursor(m_customCursor);
+ m_customCursor = NULL;
+ }
+
+ if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) {
+ ::ReleaseDC(m_hWnd, m_hDC);
+ m_hDC = NULL;
+ }
+
+ if (m_hWnd) {
+ if (m_dropTarget) {
+ // Disable DragDrop
+ RevokeDragDrop(m_hWnd);
+ // Release our reference of the DropTarget and it will delete itself eventually.
+ m_dropTarget->Release();
+ m_dropTarget = NULL;
+ }
+ ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
+ ::DestroyWindow(m_hWnd);
+ m_hWnd = 0;
+ }
}
bool GHOST_WindowWin32::getValid() const
{
- return GHOST_Window::getValid() && m_hWnd != 0 && m_hDC != 0;
+ return GHOST_Window::getValid() && m_hWnd != 0 && m_hDC != 0;
}
HWND GHOST_WindowWin32::getHWND() const
{
- return m_hWnd;
+ return m_hWnd;
}
void GHOST_WindowWin32::setTitle(const STR_String &title)
{
- wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
- ::SetWindowTextW(m_hWnd, (wchar_t *)title_16);
- free(title_16);
+ wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
+ ::SetWindowTextW(m_hWnd, (wchar_t *)title_16);
+ free(title_16);
}
-
void GHOST_WindowWin32::getTitle(STR_String &title) const
{
- char buf[s_maxTitleLength]; /*CHANGE + never used yet*/
- ::GetWindowText(m_hWnd, buf, s_maxTitleLength);
- STR_String temp(buf);
- title = buf;
+ char buf[s_maxTitleLength]; /*CHANGE + never used yet*/
+ ::GetWindowText(m_hWnd, buf, s_maxTitleLength);
+ STR_String temp(buf);
+ title = buf;
}
-
void GHOST_WindowWin32::getWindowBounds(GHOST_Rect &bounds) const
{
- RECT rect;
- ::GetWindowRect(m_hWnd, &rect);
- bounds.m_b = rect.bottom;
- bounds.m_l = rect.left;
- bounds.m_r = rect.right;
- bounds.m_t = rect.top;
+ RECT rect;
+ ::GetWindowRect(m_hWnd, &rect);
+ bounds.m_b = rect.bottom;
+ bounds.m_l = rect.left;
+ bounds.m_r = rect.right;
+ bounds.m_t = rect.top;
}
-
void GHOST_WindowWin32::getClientBounds(GHOST_Rect &bounds) const
{
- RECT rect;
- POINT coord;
- if (!IsIconic(m_hWnd)) {
- ::GetClientRect(m_hWnd, &rect);
-
- coord.x = rect.left;
- coord.y = rect.top;
- ::ClientToScreen(m_hWnd, &coord);
-
- bounds.m_l = coord.x;
- bounds.m_t = coord.y;
-
- coord.x = rect.right;
- coord.y = rect.bottom;
- ::ClientToScreen(m_hWnd, &coord);
-
- bounds.m_r = coord.x;
- bounds.m_b = coord.y;
- }
- else {
- bounds.m_b = 0;
- bounds.m_l = 0;
- bounds.m_r = 0;
- bounds.m_t = 0;
- }
+ RECT rect;
+ POINT coord;
+ if (!IsIconic(m_hWnd)) {
+ ::GetClientRect(m_hWnd, &rect);
+
+ coord.x = rect.left;
+ coord.y = rect.top;
+ ::ClientToScreen(m_hWnd, &coord);
+
+ bounds.m_l = coord.x;
+ bounds.m_t = coord.y;
+
+ coord.x = rect.right;
+ coord.y = rect.bottom;
+ ::ClientToScreen(m_hWnd, &coord);
+
+ bounds.m_r = coord.x;
+ bounds.m_b = coord.y;
+ }
+ else {
+ bounds.m_b = 0;
+ bounds.m_l = 0;
+ bounds.m_r = 0;
+ bounds.m_t = 0;
+ }
}
-
GHOST_TSuccess GHOST_WindowWin32::setClientWidth(GHOST_TUns32 width)
{
- GHOST_TSuccess success;
- GHOST_Rect cBnds, wBnds;
- getClientBounds(cBnds);
- if (cBnds.getWidth() != (GHOST_TInt32)width) {
- getWindowBounds(wBnds);
- int cx = wBnds.getWidth() + width - cBnds.getWidth();
- int cy = wBnds.getHeight();
- success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
- GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- success = GHOST_kSuccess;
- }
- return success;
+ GHOST_TSuccess success;
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (cBnds.getWidth() != (GHOST_TInt32)width) {
+ getWindowBounds(wBnds);
+ int cx = wBnds.getWidth() + width - cBnds.getWidth();
+ int cy = wBnds.getHeight();
+ success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
+ GHOST_kSuccess :
+ GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
}
-
GHOST_TSuccess GHOST_WindowWin32::setClientHeight(GHOST_TUns32 height)
{
- GHOST_TSuccess success;
- GHOST_Rect cBnds, wBnds;
- getClientBounds(cBnds);
- if (cBnds.getHeight() != (GHOST_TInt32)height) {
- getWindowBounds(wBnds);
- int cx = wBnds.getWidth();
- int cy = wBnds.getHeight() + height - cBnds.getHeight();
- success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
- GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- success = GHOST_kSuccess;
- }
- return success;
+ GHOST_TSuccess success;
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (cBnds.getHeight() != (GHOST_TInt32)height) {
+ getWindowBounds(wBnds);
+ int cx = wBnds.getWidth();
+ int cy = wBnds.getHeight() + height - cBnds.getHeight();
+ success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
+ GHOST_kSuccess :
+ GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
}
-
GHOST_TSuccess GHOST_WindowWin32::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
{
- GHOST_TSuccess success;
- GHOST_Rect cBnds, wBnds;
- getClientBounds(cBnds);
- if ((cBnds.getWidth() != (GHOST_TInt32)width) || (cBnds.getHeight() != (GHOST_TInt32)height)) {
- getWindowBounds(wBnds);
- int cx = wBnds.getWidth() + width - cBnds.getWidth();
- int cy = wBnds.getHeight() + height - cBnds.getHeight();
- success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
- GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- success = GHOST_kSuccess;
- }
- return success;
+ GHOST_TSuccess success;
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if ((cBnds.getWidth() != (GHOST_TInt32)width) || (cBnds.getHeight() != (GHOST_TInt32)height)) {
+ getWindowBounds(wBnds);
+ int cx = wBnds.getWidth() + width - cBnds.getWidth();
+ int cy = wBnds.getHeight() + height - cBnds.getHeight();
+ success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
+ GHOST_kSuccess :
+ GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kSuccess;
+ }
+ return success;
}
-
GHOST_TWindowState GHOST_WindowWin32::getState() const
{
- GHOST_TWindowState state;
-
- // XXX 27.04.2011
- // we need to find a way to combine parented windows + resizing if we simply set the
- // state as GHOST_kWindowStateEmbedded we will need to check for them somewhere else.
- // It's also strange that in Windows is the only platform we need to make this separation.
- if (m_parentWindowHwnd != 0) {
- state = GHOST_kWindowStateEmbedded;
- return state;
- }
-
- if (::IsIconic(m_hWnd)) {
- state = GHOST_kWindowStateMinimized;
- }
- else if (::IsZoomed(m_hWnd)) {
- LONG_PTR result = ::GetWindowLongPtr(m_hWnd, GWL_STYLE);
- if ((result & (WS_DLGFRAME | WS_MAXIMIZE)) == (WS_DLGFRAME | WS_MAXIMIZE))
- state = GHOST_kWindowStateMaximized;
- else
- state = GHOST_kWindowStateFullScreen;
- }
- else {
- state = GHOST_kWindowStateNormal;
- }
- return state;
+ GHOST_TWindowState state;
+
+ // XXX 27.04.2011
+ // we need to find a way to combine parented windows + resizing if we simply set the
+ // state as GHOST_kWindowStateEmbedded we will need to check for them somewhere else.
+ // It's also strange that in Windows is the only platform we need to make this separation.
+ if (m_parentWindowHwnd != 0) {
+ state = GHOST_kWindowStateEmbedded;
+ return state;
+ }
+
+ if (::IsIconic(m_hWnd)) {
+ state = GHOST_kWindowStateMinimized;
+ }
+ else if (::IsZoomed(m_hWnd)) {
+ LONG_PTR result = ::GetWindowLongPtr(m_hWnd, GWL_STYLE);
+ if ((result & (WS_DLGFRAME | WS_MAXIMIZE)) == (WS_DLGFRAME | WS_MAXIMIZE))
+ state = GHOST_kWindowStateMaximized;
+ else
+ state = GHOST_kWindowStateFullScreen;
+ }
+ else {
+ state = GHOST_kWindowStateNormal;
+ }
+ return state;
}
-
-void GHOST_WindowWin32::screenToClient(
- GHOST_TInt32 inX, GHOST_TInt32 inY,
- GHOST_TInt32 &outX, GHOST_TInt32 &outY) const
+void GHOST_WindowWin32::screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- POINT point = {inX, inY};
- ::ScreenToClient(m_hWnd, &point);
- outX = point.x;
- outY = point.y;
+ POINT point = {inX, inY};
+ ::ScreenToClient(m_hWnd, &point);
+ outX = point.x;
+ outY = point.y;
}
-
-void GHOST_WindowWin32::clientToScreen(
- GHOST_TInt32 inX, GHOST_TInt32 inY,
- GHOST_TInt32 &outX, GHOST_TInt32 &outY) const
+void GHOST_WindowWin32::clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- POINT point = {inX, inY};
- ::ClientToScreen(m_hWnd, &point);
- outX = point.x;
- outY = point.y;
+ POINT point = {inX, inY};
+ ::ClientToScreen(m_hWnd, &point);
+ outX = point.x;
+ outY = point.y;
}
-
GHOST_TSuccess GHOST_WindowWin32::setState(GHOST_TWindowState state)
{
- GHOST_TWindowState curstate = getState();
- WINDOWPLACEMENT wp;
- wp.length = sizeof(WINDOWPLACEMENT);
- ::GetWindowPlacement(m_hWnd, &wp);
-
- if (state == GHOST_kWindowStateNormal)
- state = m_normal_state;
-
- switch (state) {
- case GHOST_kWindowStateMinimized:
- wp.showCmd = SW_SHOWMINIMIZED;
- break;
- case GHOST_kWindowStateMaximized:
- wp.showCmd = SW_SHOWMAXIMIZED;
- ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
- break;
- case GHOST_kWindowStateFullScreen:
- if (curstate != state && curstate != GHOST_kWindowStateMinimized)
- m_normal_state = curstate;
- wp.showCmd = SW_SHOWMAXIMIZED;
- wp.ptMaxPosition.x = 0;
- wp.ptMaxPosition.y = 0;
- ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_MAXIMIZE);
- break;
- case GHOST_kWindowStateEmbedded:
- ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_CHILD);
- break;
- case GHOST_kWindowStateNormal:
- default:
- wp.showCmd = SW_SHOWNORMAL;
- ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
- break;
- }
- /* Clears window cache for SetWindowLongPtr */
- ::SetWindowPos(m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
-
- return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ GHOST_TWindowState curstate = getState();
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(WINDOWPLACEMENT);
+ ::GetWindowPlacement(m_hWnd, &wp);
+
+ if (state == GHOST_kWindowStateNormal)
+ state = m_normal_state;
+
+ switch (state) {
+ case GHOST_kWindowStateMinimized:
+ wp.showCmd = SW_SHOWMINIMIZED;
+ break;
+ case GHOST_kWindowStateMaximized:
+ wp.showCmd = SW_SHOWMAXIMIZED;
+ ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
+ break;
+ case GHOST_kWindowStateFullScreen:
+ if (curstate != state && curstate != GHOST_kWindowStateMinimized)
+ m_normal_state = curstate;
+ wp.showCmd = SW_SHOWMAXIMIZED;
+ wp.ptMaxPosition.x = 0;
+ wp.ptMaxPosition.y = 0;
+ ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_MAXIMIZE);
+ break;
+ case GHOST_kWindowStateEmbedded:
+ ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_CHILD);
+ break;
+ case GHOST_kWindowStateNormal:
+ default:
+ wp.showCmd = SW_SHOWNORMAL;
+ ::SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
+ break;
+ }
+ /* Clears window cache for SetWindowLongPtr */
+ ::SetWindowPos(m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+
+ return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
}
-
GHOST_TSuccess GHOST_WindowWin32::setOrder(GHOST_TWindowOrder order)
{
- HWND hWndInsertAfter, hWndToRaise;
-
- if (order == GHOST_kWindowOrderBottom) {
- hWndInsertAfter = HWND_BOTTOM;
- hWndToRaise = ::GetWindow(m_hWnd, GW_HWNDNEXT); /* the window to raise */
- }
- else {
- hWndInsertAfter = HWND_TOP;
- hWndToRaise = NULL;
- }
-
- if (::SetWindowPos(m_hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
- return GHOST_kFailure;
- }
-
- if (hWndToRaise && ::SetWindowPos(hWndToRaise, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
- return GHOST_kFailure;
- }
- return GHOST_kSuccess;
+ HWND hWndInsertAfter, hWndToRaise;
+
+ if (order == GHOST_kWindowOrderBottom) {
+ hWndInsertAfter = HWND_BOTTOM;
+ hWndToRaise = ::GetWindow(m_hWnd, GW_HWNDNEXT); /* the window to raise */
+ }
+ else {
+ hWndInsertAfter = HWND_TOP;
+ hWndToRaise = NULL;
+ }
+
+ if (::SetWindowPos(m_hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
+ return GHOST_kFailure;
+ }
+
+ if (hWndToRaise &&
+ ::SetWindowPos(hWndToRaise, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
+ return GHOST_kFailure;
+ }
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_WindowWin32::invalidate()
{
- GHOST_TSuccess success;
- if (m_hWnd) {
- success = ::InvalidateRect(m_hWnd, 0, FALSE) != 0 ? GHOST_kSuccess : GHOST_kFailure;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ GHOST_TSuccess success;
+ if (m_hWnd) {
+ success = ::InvalidateRect(m_hWnd, 0, FALSE) != 0 ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ success = GHOST_kFailure;
+ }
+ return success;
}
-
GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType type)
{
- if (type == GHOST_kDrawingContextTypeOpenGL) {
- GHOST_Context *context;
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+ GHOST_Context *context;
#if defined(WITH_GL_PROFILE_CORE)
- /* - AMD and Intel give us exactly this version
- * - NVIDIA gives at least this version <-- desired behavior
- * So we ask for 4.5, 4.4 ... 3.3 in descending order to get the best version on the user's system. */
- for (int minor = 5; minor >= 0; --minor) {
- context = new GHOST_ContextWGL(
- m_wantStereoVisual,
- m_wantAlphaBackground,
- m_wantNumOfAASamples,
- m_hWnd,
- m_hDC,
- WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
- 4, minor,
- (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext()) {
- return context;
- }
- else {
- delete context;
- }
- }
- context = new GHOST_ContextWGL(
- m_wantStereoVisual,
- m_wantAlphaBackground,
- m_wantNumOfAASamples,
- m_hWnd,
- m_hDC,
- WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
- 3, 3,
- (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext()) {
- return context;
- }
- else {
- MessageBox(
- m_hWnd,
- "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n"
- "Installing the latest driver for your graphics card may resolve the issue.\n\n"
- "The program will now close.",
- "Blender - Unsupported Graphics Card or Driver",
- MB_OK | MB_ICONERROR);
- delete context;
- exit(0);
- }
+ /* - AMD and Intel give us exactly this version
+ * - NVIDIA gives at least this version <-- desired behavior
+ * So we ask for 4.5, 4.4 ... 3.3 in descending order to get the best version on the user's system. */
+ for (int minor = 5; minor >= 0; --minor) {
+ context = new GHOST_ContextWGL(m_wantStereoVisual,
+ m_wantAlphaBackground,
+ m_wantNumOfAASamples,
+ m_hWnd,
+ m_hDC,
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ 4,
+ minor,
+ (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext()) {
+ return context;
+ }
+ else {
+ delete context;
+ }
+ }
+ context = new GHOST_ContextWGL(m_wantStereoVisual,
+ m_wantAlphaBackground,
+ m_wantNumOfAASamples,
+ m_hWnd,
+ m_hDC,
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ 3,
+ 3,
+ (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext()) {
+ return context;
+ }
+ else {
+ MessageBox(m_hWnd,
+ "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n"
+ "Installing the latest driver for your graphics card may resolve the issue.\n\n"
+ "The program will now close.",
+ "Blender - Unsupported Graphics Card or Driver",
+ MB_OK | MB_ICONERROR);
+ delete context;
+ exit(0);
+ }
#elif defined(WITH_GL_PROFILE_COMPAT)
- // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile)
- // 2.1 ignores the profile bit & is incompatible with core profile
- context = new GHOST_ContextWGL(
- m_wantStereoVisual,
- m_wantAlphaBackground,
- m_wantNumOfAASamples,
- m_hWnd,
- m_hDC,
- 0, // no profile bit
- 2, 1,
- (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext()) {
- return context;
- }
- else {
- delete context;
- }
+ // ask for 2.1 context, driver gives any GL version >= 2.1 (hopefully the latest compatibility profile)
+ // 2.1 ignores the profile bit & is incompatible with core profile
+ context = new GHOST_ContextWGL(m_wantStereoVisual,
+ m_wantAlphaBackground,
+ m_wantNumOfAASamples,
+ m_hWnd,
+ m_hDC,
+ 0, // no profile bit
+ 2,
+ 1,
+ (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext()) {
+ return context;
+ }
+ else {
+ delete context;
+ }
#else
-# error // must specify either core or compat at build time
+# error // must specify either core or compat at build time
#endif
- }
+ }
- return NULL;
+ return NULL;
}
void GHOST_WindowWin32::lostMouseCapture()
{
- if (m_hasMouseCaptured) {
- m_hasGrabMouse = false;
- m_nPressedButtons = 0;
- m_hasMouseCaptured = false;
- }
+ if (m_hasMouseCaptured) {
+ m_hasGrabMouse = false;
+ m_nPressedButtons = 0;
+ m_hasMouseCaptured = false;
+ }
}
void GHOST_WindowWin32::registerMouseClickEvent(int press)
{
- switch (press) {
- case 0: m_nPressedButtons++; break;
- case 1: if (m_nPressedButtons) m_nPressedButtons--; break;
- case 2: m_hasGrabMouse = true; break;
- case 3: m_hasGrabMouse = false; break;
- }
-
- if (!m_nPressedButtons && !m_hasGrabMouse && m_hasMouseCaptured) {
- ::ReleaseCapture();
- m_hasMouseCaptured = false;
- }
- else if ((m_nPressedButtons || m_hasGrabMouse) && !m_hasMouseCaptured) {
- ::SetCapture(m_hWnd);
- m_hasMouseCaptured = true;
-
- }
+ switch (press) {
+ case 0:
+ m_nPressedButtons++;
+ break;
+ case 1:
+ if (m_nPressedButtons)
+ m_nPressedButtons--;
+ break;
+ case 2:
+ m_hasGrabMouse = true;
+ break;
+ case 3:
+ m_hasGrabMouse = false;
+ break;
+ }
+
+ if (!m_nPressedButtons && !m_hasGrabMouse && m_hasMouseCaptured) {
+ ::ReleaseCapture();
+ m_hasMouseCaptured = false;
+ }
+ else if ((m_nPressedButtons || m_hasGrabMouse) && !m_hasMouseCaptured) {
+ ::SetCapture(m_hWnd);
+ m_hasMouseCaptured = true;
+ }
}
-
void GHOST_WindowWin32::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
{
- if (!visible) {
- while (::ShowCursor(FALSE) >= 0) ;
- }
- else {
- while (::ShowCursor(TRUE) < 0) ;
- }
-
- if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
- ::SetCursor(m_customCursor);
- }
- else {
- // Convert GHOST cursor to Windows OEM cursor
- bool success = true;
- LPCSTR id;
- switch (cursor) {
- case GHOST_kStandardCursorDefault: id = IDC_ARROW; break;
- case GHOST_kStandardCursorRightArrow: id = IDC_ARROW; break;
- case GHOST_kStandardCursorLeftArrow: id = IDC_ARROW; break;
- case GHOST_kStandardCursorInfo: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
- case GHOST_kStandardCursorDestroy: id = IDC_NO; break; // Slashed circle
- case GHOST_kStandardCursorHelp: id = IDC_HELP; break; // Arrow and question mark
- case GHOST_kStandardCursorCycle: id = IDC_NO; break; // Slashed circle
- case GHOST_kStandardCursorSpray: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
- case GHOST_kStandardCursorWait: id = IDC_WAIT; break; // Hourglass
- case GHOST_kStandardCursorText: id = IDC_IBEAM; break; // I-beam
- case GHOST_kStandardCursorCrosshair: id = IDC_CROSS; break; // Crosshair
- case GHOST_kStandardCursorUpDown: id = IDC_SIZENS; break; // Double-pointed arrow pointing north and south
- case GHOST_kStandardCursorLeftRight: id = IDC_SIZEWE; break; // Double-pointed arrow pointing west and east
- case GHOST_kStandardCursorTopSide: id = IDC_UPARROW; break; // Vertical arrow
- case GHOST_kStandardCursorBottomSide: id = IDC_SIZENS; break;
- case GHOST_kStandardCursorLeftSide: id = IDC_SIZEWE; break;
- case GHOST_kStandardCursorTopLeftCorner: id = IDC_SIZENWSE; break;
- case GHOST_kStandardCursorTopRightCorner: id = IDC_SIZENESW; break;
- case GHOST_kStandardCursorBottomRightCorner: id = IDC_SIZENWSE; break;
- case GHOST_kStandardCursorBottomLeftCorner: id = IDC_SIZENESW; break;
- case GHOST_kStandardCursorPencil: id = IDC_ARROW; break;
- case GHOST_kStandardCursorCopy: id = IDC_ARROW; break;
- default:
- success = false;
- }
-
- if (success) {
- ::SetCursor(::LoadCursor(0, id));
- }
- }
+ if (!visible) {
+ while (::ShowCursor(FALSE) >= 0)
+ ;
+ }
+ else {
+ while (::ShowCursor(TRUE) < 0)
+ ;
+ }
+
+ if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
+ ::SetCursor(m_customCursor);
+ }
+ else {
+ // Convert GHOST cursor to Windows OEM cursor
+ bool success = true;
+ LPCSTR id;
+ switch (cursor) {
+ case GHOST_kStandardCursorDefault:
+ id = IDC_ARROW;
+ break;
+ case GHOST_kStandardCursorRightArrow:
+ id = IDC_ARROW;
+ break;
+ case GHOST_kStandardCursorLeftArrow:
+ id = IDC_ARROW;
+ break;
+ case GHOST_kStandardCursorInfo:
+ id = IDC_SIZEALL;
+ break; // Four-pointed arrow pointing north, south, east, and west
+ case GHOST_kStandardCursorDestroy:
+ id = IDC_NO;
+ break; // Slashed circle
+ case GHOST_kStandardCursorHelp:
+ id = IDC_HELP;
+ break; // Arrow and question mark
+ case GHOST_kStandardCursorCycle:
+ id = IDC_NO;
+ break; // Slashed circle
+ case GHOST_kStandardCursorSpray:
+ id = IDC_SIZEALL;
+ break; // Four-pointed arrow pointing north, south, east, and west
+ case GHOST_kStandardCursorWait:
+ id = IDC_WAIT;
+ break; // Hourglass
+ case GHOST_kStandardCursorText:
+ id = IDC_IBEAM;
+ break; // I-beam
+ case GHOST_kStandardCursorCrosshair:
+ id = IDC_CROSS;
+ break; // Crosshair
+ case GHOST_kStandardCursorUpDown:
+ id = IDC_SIZENS;
+ break; // Double-pointed arrow pointing north and south
+ case GHOST_kStandardCursorLeftRight:
+ id = IDC_SIZEWE;
+ break; // Double-pointed arrow pointing west and east
+ case GHOST_kStandardCursorTopSide:
+ id = IDC_UPARROW;
+ break; // Vertical arrow
+ case GHOST_kStandardCursorBottomSide:
+ id = IDC_SIZENS;
+ break;
+ case GHOST_kStandardCursorLeftSide:
+ id = IDC_SIZEWE;
+ break;
+ case GHOST_kStandardCursorTopLeftCorner:
+ id = IDC_SIZENWSE;
+ break;
+ case GHOST_kStandardCursorTopRightCorner:
+ id = IDC_SIZENESW;
+ break;
+ case GHOST_kStandardCursorBottomRightCorner:
+ id = IDC_SIZENWSE;
+ break;
+ case GHOST_kStandardCursorBottomLeftCorner:
+ id = IDC_SIZENESW;
+ break;
+ case GHOST_kStandardCursorPencil:
+ id = IDC_ARROW;
+ break;
+ case GHOST_kStandardCursorCopy:
+ id = IDC_ARROW;
+ break;
+ default:
+ success = false;
+ }
+
+ if (success) {
+ ::SetCursor(::LoadCursor(0, id));
+ }
+ }
}
GHOST_TSuccess GHOST_WindowWin32::setWindowCursorVisibility(bool visible)
{
- if (::GetForegroundWindow() == m_hWnd) {
- loadCursor(visible, getCursorShape());
- }
+ if (::GetForegroundWindow() == m_hWnd) {
+ loadCursor(visible, getCursorShape());
+ }
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
{
- if (mode != GHOST_kGrabDisable) {
- if (mode != GHOST_kGrabNormal) {
- m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
- setCursorGrabAccum(0, 0);
-
- if (mode == GHOST_kGrabHide)
- setWindowCursorVisibility(false);
- }
- registerMouseClickEvent(2);
- }
- else {
- if (m_cursorGrab == GHOST_kGrabHide) {
- m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
- setWindowCursorVisibility(true);
- }
- if (m_cursorGrab != GHOST_kGrabNormal) {
- /* use to generate a mouse move event, otherwise the last event
- * blender gets can be outside the screen causing menus not to show
- * properly unless the user moves the mouse */
- GHOST_TInt32 pos[2];
- m_system->getCursorPosition(pos[0], pos[1]);
- m_system->setCursorPosition(pos[0], pos[1]);
- }
-
- /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
- setCursorGrabAccum(0, 0);
- m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
- registerMouseClickEvent(3);
- }
-
- return GHOST_kSuccess;
+ if (mode != GHOST_kGrabDisable) {
+ if (mode != GHOST_kGrabNormal) {
+ m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ setCursorGrabAccum(0, 0);
+
+ if (mode == GHOST_kGrabHide)
+ setWindowCursorVisibility(false);
+ }
+ registerMouseClickEvent(2);
+ }
+ else {
+ if (m_cursorGrab == GHOST_kGrabHide) {
+ m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ setWindowCursorVisibility(true);
+ }
+ if (m_cursorGrab != GHOST_kGrabNormal) {
+ /* use to generate a mouse move event, otherwise the last event
+ * blender gets can be outside the screen causing menus not to show
+ * properly unless the user moves the mouse */
+ GHOST_TInt32 pos[2];
+ m_system->getCursorPosition(pos[0], pos[1]);
+ m_system->setCursorPosition(pos[0], pos[1]);
+ }
+
+ /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
+ setCursorGrabAccum(0, 0);
+ m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
+ registerMouseClickEvent(3);
+ }
+
+ return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cursorShape)
{
- if (m_customCursor) {
- DestroyCursor(m_customCursor);
- m_customCursor = NULL;
- }
+ if (m_customCursor) {
+ DestroyCursor(m_customCursor);
+ m_customCursor = NULL;
+ }
- if (::GetForegroundWindow() == m_hWnd) {
- loadCursor(getCursorVisibility(), cursorShape);
- }
+ if (::GetForegroundWindow() == m_hWnd) {
+ loadCursor(getCursorVisibility(), cursorShape);
+ }
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam)
+GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo,
+ WPARAM wParam,
+ LPARAM lParam)
{
- ZeroMemory(pointerInfo, sizeof(GHOST_PointerInfoWin32));
-
- // Obtain the basic information from the event
- pointerInfo->pointerId = GET_POINTERID_WPARAM(wParam);
- pointerInfo->isInContact = IS_POINTER_INCONTACT_WPARAM(wParam);
- pointerInfo->isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
-
- // Obtain more accurate and predicted information from the Pointer API
- POINTER_INFO pointerApiInfo;
- if (!(m_fpGetPointerInfo && m_fpGetPointerInfo(pointerInfo->pointerId, &pointerApiInfo))) {
- return GHOST_kFailure;
- }
-
- pointerInfo->hasButtonMask = GHOST_kSuccess;
- switch (pointerApiInfo.ButtonChangeType) {
- case POINTER_CHANGE_FIRSTBUTTON_DOWN:
- case POINTER_CHANGE_FIRSTBUTTON_UP:
- pointerInfo->buttonMask = GHOST_kButtonMaskLeft;
- break;
- case POINTER_CHANGE_SECONDBUTTON_DOWN:
- case POINTER_CHANGE_SECONDBUTTON_UP:
- pointerInfo->buttonMask = GHOST_kButtonMaskRight;
- break;
- case POINTER_CHANGE_THIRDBUTTON_DOWN:
- case POINTER_CHANGE_THIRDBUTTON_UP:
- pointerInfo->buttonMask = GHOST_kButtonMaskMiddle;
- break;
- case POINTER_CHANGE_FOURTHBUTTON_DOWN:
- case POINTER_CHANGE_FOURTHBUTTON_UP:
- pointerInfo->buttonMask = GHOST_kButtonMaskButton4;
- break;
- case POINTER_CHANGE_FIFTHBUTTON_DOWN:
- case POINTER_CHANGE_FIFTHBUTTON_UP:
- pointerInfo->buttonMask = GHOST_kButtonMaskButton5;
- break;
- default:
- pointerInfo->hasButtonMask = GHOST_kFailure;
- break;
- }
-
- pointerInfo->pixelLocation = pointerApiInfo.ptPixelLocation;
- pointerInfo->tabletData.Active = GHOST_kTabletModeNone;
- pointerInfo->tabletData.Pressure = 1.0f;
- pointerInfo->tabletData.Xtilt = 0.0f;
- pointerInfo->tabletData.Ytilt = 0.0f;
-
- if (pointerApiInfo.pointerType != PT_PEN) {
- return GHOST_kFailure;
- }
-
- POINTER_PEN_INFO pointerPenInfo;
- if (m_fpGetPointerPenInfo && m_fpGetPointerPenInfo(pointerInfo->pointerId, &pointerPenInfo)) {
- pointerInfo->tabletData.Active = GHOST_kTabletModeStylus;
-
- if (pointerPenInfo.penMask & PEN_MASK_PRESSURE) {
- pointerInfo->tabletData.Pressure = pointerPenInfo.pressure / 1024.0f;
- }
-
- if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) {
- pointerInfo->tabletData.Active = GHOST_kTabletModeEraser;
- }
-
- if (pointerPenInfo.penFlags & PEN_MASK_TILT_X) {
- pointerInfo->tabletData.Xtilt = fmin(fabs(pointerPenInfo.tiltX / 90), 1.0f);
- }
-
- if (pointerPenInfo.penFlags & PEN_MASK_TILT_Y) {
- pointerInfo->tabletData.Ytilt = fmin(fabs(pointerPenInfo.tiltY / 90), 1.0f);
- }
- }
-
- return GHOST_kSuccess;
+ ZeroMemory(pointerInfo, sizeof(GHOST_PointerInfoWin32));
+
+ // Obtain the basic information from the event
+ pointerInfo->pointerId = GET_POINTERID_WPARAM(wParam);
+ pointerInfo->isInContact = IS_POINTER_INCONTACT_WPARAM(wParam);
+ pointerInfo->isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
+
+ // Obtain more accurate and predicted information from the Pointer API
+ POINTER_INFO pointerApiInfo;
+ if (!(m_fpGetPointerInfo && m_fpGetPointerInfo(pointerInfo->pointerId, &pointerApiInfo))) {
+ return GHOST_kFailure;
+ }
+
+ pointerInfo->hasButtonMask = GHOST_kSuccess;
+ switch (pointerApiInfo.ButtonChangeType) {
+ case POINTER_CHANGE_FIRSTBUTTON_DOWN:
+ case POINTER_CHANGE_FIRSTBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskLeft;
+ break;
+ case POINTER_CHANGE_SECONDBUTTON_DOWN:
+ case POINTER_CHANGE_SECONDBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskRight;
+ break;
+ case POINTER_CHANGE_THIRDBUTTON_DOWN:
+ case POINTER_CHANGE_THIRDBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskMiddle;
+ break;
+ case POINTER_CHANGE_FOURTHBUTTON_DOWN:
+ case POINTER_CHANGE_FOURTHBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskButton4;
+ break;
+ case POINTER_CHANGE_FIFTHBUTTON_DOWN:
+ case POINTER_CHANGE_FIFTHBUTTON_UP:
+ pointerInfo->buttonMask = GHOST_kButtonMaskButton5;
+ break;
+ default:
+ pointerInfo->hasButtonMask = GHOST_kFailure;
+ break;
+ }
+
+ pointerInfo->pixelLocation = pointerApiInfo.ptPixelLocation;
+ pointerInfo->tabletData.Active = GHOST_kTabletModeNone;
+ pointerInfo->tabletData.Pressure = 1.0f;
+ pointerInfo->tabletData.Xtilt = 0.0f;
+ pointerInfo->tabletData.Ytilt = 0.0f;
+
+ if (pointerApiInfo.pointerType != PT_PEN) {
+ return GHOST_kFailure;
+ }
+
+ POINTER_PEN_INFO pointerPenInfo;
+ if (m_fpGetPointerPenInfo && m_fpGetPointerPenInfo(pointerInfo->pointerId, &pointerPenInfo)) {
+ pointerInfo->tabletData.Active = GHOST_kTabletModeStylus;
+
+ if (pointerPenInfo.penMask & PEN_MASK_PRESSURE) {
+ pointerInfo->tabletData.Pressure = pointerPenInfo.pressure / 1024.0f;
+ }
+
+ if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) {
+ pointerInfo->tabletData.Active = GHOST_kTabletModeEraser;
+ }
+
+ if (pointerPenInfo.penFlags & PEN_MASK_TILT_X) {
+ pointerInfo->tabletData.Xtilt = fmin(fabs(pointerPenInfo.tiltX / 90), 1.0f);
+ }
+
+ if (pointerPenInfo.penFlags & PEN_MASK_TILT_Y) {
+ pointerInfo->tabletData.Ytilt = fmin(fabs(pointerPenInfo.tiltY / 90), 1.0f);
+ }
+ }
+
+ return GHOST_kSuccess;
}
-void GHOST_WindowWin32::setTabletData(GHOST_TabletData * pTabletData)
+void GHOST_WindowWin32::setTabletData(GHOST_TabletData *pTabletData)
{
- if (pTabletData) {
- m_tabletData = *pTabletData;
- }
- else {
- m_tabletData.Active = GHOST_kTabletModeNone;
- m_tabletData.Pressure = 1.0f;
- m_tabletData.Xtilt = 0.0f;
- m_tabletData.Ytilt = 0.0f;
- }
+ if (pTabletData) {
+ m_tabletData = *pTabletData;
+ }
+ else {
+ m_tabletData.Active = GHOST_kTabletModeNone;
+ m_tabletData.Pressure = 1.0f;
+ m_tabletData.Xtilt = 0.0f;
+ m_tabletData.Ytilt = 0.0f;
+ }
}
void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
{
- if (!useTabletAPI(GHOST_kTabletWintab)) {
- return;
- }
+ if (!useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
- if (m_wintab.enable && m_wintab.tablet) {
- m_wintab.enable(m_wintab.tablet, state);
+ if (m_wintab.enable && m_wintab.tablet) {
+ m_wintab.enable(m_wintab.tablet, state);
- if (m_wintab.overlap && state) {
- m_wintab.overlap(m_wintab.tablet, TRUE);
- }
- }
+ if (m_wintab.overlap && state) {
+ m_wintab.overlap(m_wintab.tablet, TRUE);
+ }
+ }
}
bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const
{
- if (m_system->getTabletAPI() == api) {
- return true;
- }
- else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) {
- if (m_wintab.tablet)
- return api == GHOST_kTabletWintab;
- else
- return api == GHOST_kTabletNative;
- }
- else {
- return false;
- }
+ if (m_system->getTabletAPI() == api) {
+ return true;
+ }
+ else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) {
+ if (m_wintab.tablet)
+ return api == GHOST_kTabletWintab;
+ else
+ return api == GHOST_kTabletNative;
+ }
+ else {
+ return false;
+ }
}
void GHOST_WindowWin32::processWin32TabletInitEvent()
{
- if (!useTabletAPI(GHOST_kTabletWintab)) {
- return;
- }
-
- // Let's see if we can initialize tablet here
- if (m_wintab.info && m_wintab.tablet) {
- AXIS Pressure, Orientation[3]; /* The maximum tablet size */
-
- BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
- if (pressureSupport)
- m_wintab.maxPressure = Pressure.axMax;
- else
- m_wintab.maxPressure = 0;
-
- BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
- if (tiltSupport) {
- /* does the tablet support azimuth ([0]) and altitude ([1]) */
- if (Orientation[0].axResolution && Orientation[1].axResolution) {
- m_wintab.maxAzimuth = Orientation[0].axMax;
- m_wintab.maxAltitude = Orientation[1].axMax;
- }
- else { /* no so dont do tilt stuff */
- m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
- }
- }
-
- m_tabletData.Active = GHOST_kTabletModeNone;
- }
-
- m_tabletData.Active = GHOST_kTabletModeNone;
+ if (!useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
+ // Let's see if we can initialize tablet here
+ if (m_wintab.info && m_wintab.tablet) {
+ AXIS Pressure, Orientation[3]; /* The maximum tablet size */
+
+ BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
+ if (pressureSupport)
+ m_wintab.maxPressure = Pressure.axMax;
+ else
+ m_wintab.maxPressure = 0;
+
+ BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
+ if (tiltSupport) {
+ /* does the tablet support azimuth ([0]) and altitude ([1]) */
+ if (Orientation[0].axResolution && Orientation[1].axResolution) {
+ m_wintab.maxAzimuth = Orientation[0].axMax;
+ m_wintab.maxAltitude = Orientation[1].axMax;
+ }
+ else { /* no so dont do tilt stuff */
+ m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
+ }
+ }
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
+ }
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
}
void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
{
- if (!useTabletAPI(GHOST_kTabletWintab)) {
- return;
- }
-
- if (m_wintab.packet && m_wintab.tablet) {
- PACKET pkt;
- if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
- switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
- case 0:
- m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
- break;
- case 1:
- m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
- break;
- case 2:
- m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
- break;
- }
-
- if (m_wintab.maxPressure > 0) {
- m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
- }
- else {
- m_tabletData.Pressure = 1.0f;
- }
-
- if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
- ORIENTATION ort = pkt.pkOrientation;
- float vecLen;
- float altRad, azmRad; /* in radians */
-
- /*
- * from the wintab spec:
- * orAzimuth Specifies the clockwise rotation of the
- * cursor about the z axis through a full circular range.
- *
- * orAltitude Specifies the angle with the x-y plane
- * through a signed, semicircular range. Positive values
- * specify an angle upward toward the positive z axis;
- * negative values specify an angle downward toward the negative z axis.
- *
- * wintab.h defines .orAltitude as a UINT but documents .orAltitude
- * as positive for upward angles and negative for downward angles.
- * WACOM uses negative altitude values to show that the pen is inverted;
- * therefore we cast .orAltitude as an (int) and then use the absolute value.
- */
-
- /* convert raw fixed point data to radians */
- altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0);
- azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0);
-
- /* find length of the stylus' projected vector on the XY plane */
- vecLen = cos(altRad);
-
- /* from there calculate X and Y components based on azimuth */
- m_tabletData.Xtilt = sin(azmRad) * vecLen;
- m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
-
- }
- else {
- m_tabletData.Xtilt = 0.0f;
- m_tabletData.Ytilt = 0.0f;
- }
- }
- }
+ if (!useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
+ if (m_wintab.packet && m_wintab.tablet) {
+ PACKET pkt;
+ if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
+ switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
+ case 0:
+ m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
+ break;
+ case 1:
+ m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
+ break;
+ case 2:
+ m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
+ break;
+ }
+
+ if (m_wintab.maxPressure > 0) {
+ m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
+ }
+ else {
+ m_tabletData.Pressure = 1.0f;
+ }
+
+ if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
+ ORIENTATION ort = pkt.pkOrientation;
+ float vecLen;
+ float altRad, azmRad; /* in radians */
+
+ /*
+ * from the wintab spec:
+ * orAzimuth Specifies the clockwise rotation of the
+ * cursor about the z axis through a full circular range.
+ *
+ * orAltitude Specifies the angle with the x-y plane
+ * through a signed, semicircular range. Positive values
+ * specify an angle upward toward the positive z axis;
+ * negative values specify an angle downward toward the negative z axis.
+ *
+ * wintab.h defines .orAltitude as a UINT but documents .orAltitude
+ * as positive for upward angles and negative for downward angles.
+ * WACOM uses negative altitude values to show that the pen is inverted;
+ * therefore we cast .orAltitude as an (int) and then use the absolute value.
+ */
+
+ /* convert raw fixed point data to radians */
+ altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0);
+ azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0);
+
+ /* find length of the stylus' projected vector on the XY plane */
+ vecLen = cos(altRad);
+
+ /* from there calculate X and Y components based on azimuth */
+ m_tabletData.Xtilt = sin(azmRad) * vecLen;
+ m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
+ }
+ else {
+ m_tabletData.Xtilt = 0.0f;
+ m_tabletData.Ytilt = 0.0f;
+ }
+ }
+ }
}
void GHOST_WindowWin32::bringTabletContextToFront()
{
- if (!useTabletAPI(GHOST_kTabletWintab)) {
- return;
- }
+ if (!useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
- if (m_wintab.overlap && m_wintab.tablet) {
- m_wintab.overlap(m_wintab.tablet, TRUE);
- }
+ if (m_wintab.overlap && m_wintab.tablet) {
+ m_wintab.overlap(m_wintab.tablet, TRUE);
+ }
}
GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
{
- if (m_user32) {
- GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow) ::GetProcAddress(m_user32, "GetDpiForWindow");
+ if (m_user32) {
+ GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow)::GetProcAddress(
+ m_user32, "GetDpiForWindow");
- if (fpGetDpiForWindow) {
- return fpGetDpiForWindow(this->m_hWnd);
- }
- }
+ if (fpGetDpiForWindow) {
+ return fpGetDpiForWindow(this->m_hWnd);
+ }
+ }
- return USER_DEFAULT_SCREEN_DPI;
+ return USER_DEFAULT_SCREEN_DPI;
}
/** Reverse the bits in a GHOST_TUns8 */
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{
- ch = ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA);
- ch = ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC);
- ch = ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0);
- return ch;
+ ch = ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA);
+ ch = ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC);
+ ch = ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0);
+ return ch;
}
-#if 0 /* UNUSED */
+#if 0 /* UNUSED */
/** Reverse the bits in a GHOST_TUns16 */
static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
{
- shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA);
- shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC);
- shrt = ((shrt >> 4) & 0x0F0F) | ((shrt << 4) & 0xF0F0);
- shrt = ((shrt >> 8) & 0x00FF) | ((shrt << 8) & 0xFF00);
- return shrt;
+ shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA);
+ shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC);
+ shrt = ((shrt >> 4) & 0x0F0F) | ((shrt << 4) & 0xF0F0);
+ shrt = ((shrt >> 8) & 0x00FF) | ((shrt << 8) & 0xFF00);
+ return shrt;
}
#endif
-GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(
- GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX, int hotY)
+GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY)
{
- return setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask,
- 16, 16, hotX, hotY, 0, 1);
+ return setWindowCustomCursorShape(
+ (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1);
}
-GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(
- GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask, int sizeX, int sizeY, int hotX, int hotY,
- int fg_color, int bg_color)
+GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizeX,
+ int sizeY,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color)
{
- GHOST_TUns32 andData[32];
- GHOST_TUns32 xorData[32];
- GHOST_TUns32 fullBitRow, fullMaskRow;
- int x, y, cols;
-
- cols = sizeX / 8; /* Num of whole bytes per row (width of bm/mask) */
- if (sizeX % 8) cols++;
-
- if (m_customCursor) {
- DestroyCursor(m_customCursor);
- m_customCursor = NULL;
- }
-
- memset(&andData, 0xFF, sizeof(andData));
- memset(&xorData, 0, sizeof(xorData));
-
- for (y = 0; y < sizeY; y++) {
- fullBitRow = 0;
- fullMaskRow = 0;
- for (x = cols - 1; x >= 0; x--) {
- fullBitRow <<= 8;
- fullMaskRow <<= 8;
- fullBitRow |= uns8ReverseBits(bitmap[cols * y + x]);
- fullMaskRow |= uns8ReverseBits(mask[cols * y + x]);
- }
- xorData[y] = fullBitRow & fullMaskRow;
- andData[y] = ~fullMaskRow;
- }
-
- m_customCursor = ::CreateCursor(::GetModuleHandle(0), hotX, hotY, 32, 32, andData, xorData);
- if (!m_customCursor) {
- return GHOST_kFailure;
- }
-
- if (::GetForegroundWindow() == m_hWnd) {
- loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
- }
-
- return GHOST_kSuccess;
+ GHOST_TUns32 andData[32];
+ GHOST_TUns32 xorData[32];
+ GHOST_TUns32 fullBitRow, fullMaskRow;
+ int x, y, cols;
+
+ cols = sizeX / 8; /* Num of whole bytes per row (width of bm/mask) */
+ if (sizeX % 8)
+ cols++;
+
+ if (m_customCursor) {
+ DestroyCursor(m_customCursor);
+ m_customCursor = NULL;
+ }
+
+ memset(&andData, 0xFF, sizeof(andData));
+ memset(&xorData, 0, sizeof(xorData));
+
+ for (y = 0; y < sizeY; y++) {
+ fullBitRow = 0;
+ fullMaskRow = 0;
+ for (x = cols - 1; x >= 0; x--) {
+ fullBitRow <<= 8;
+ fullMaskRow <<= 8;
+ fullBitRow |= uns8ReverseBits(bitmap[cols * y + x]);
+ fullMaskRow |= uns8ReverseBits(mask[cols * y + x]);
+ }
+ xorData[y] = fullBitRow & fullMaskRow;
+ andData[y] = ~fullMaskRow;
+ }
+
+ m_customCursor = ::CreateCursor(::GetModuleHandle(0), hotX, hotY, 32, 32, andData, xorData);
+ if (!m_customCursor) {
+ return GHOST_kFailure;
+ }
+
+ if (::GetForegroundWindow() == m_hWnd) {
+ loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
+ }
+
+ return GHOST_kSuccess;
}
-
GHOST_TSuccess GHOST_WindowWin32::setProgressBar(float progress)
{
- /*SetProgressValue sets state to TBPF_NORMAL automaticly*/
- if (m_Bar && S_OK == m_Bar->SetProgressValue(m_hWnd, 10000 * progress, 10000))
- return GHOST_kSuccess;
+ /*SetProgressValue sets state to TBPF_NORMAL automaticly*/
+ if (m_Bar && S_OK == m_Bar->SetProgressValue(m_hWnd, 10000 * progress, 10000))
+ return GHOST_kSuccess;
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
GHOST_TSuccess GHOST_WindowWin32::endProgressBar()
{
- if (m_Bar && S_OK == m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS))
- return GHOST_kSuccess;
+ if (m_Bar && S_OK == m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS))
+ return GHOST_kSuccess;
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
-
#ifdef WITH_INPUT_IME
-void GHOST_WindowWin32::beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed)
+void GHOST_WindowWin32::beginIME(
+ GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed)
{
- m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), (bool)completed);
+ m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), (bool)completed);
}
-
void GHOST_WindowWin32::endIME()
{
- m_imeInput.EndIME(m_hWnd);
+ m_imeInput.EndIME(m_hWnd);
}
#endif /* WITH_INPUT_IME */
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 5de6a62380a..73791d3fbbf 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -26,8 +26,8 @@
#define __GHOST_WINDOWWIN32_H__
#ifndef WIN32
-#error WIN32 only!
-#endif // WIN32
+# error WIN32 only!
+#endif // WIN32
#include "GHOST_Window.h"
#include "GHOST_TaskbarWin32.h"
@@ -36,491 +36,511 @@
#endif
#include <wintab.h>
-#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
-#define PACKETMODE PK_BUTTONS
+#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
+#define PACKETMODE PK_BUTTONS
#include <pktdef.h>
class GHOST_SystemWin32;
class GHOST_DropTargetWin32;
// typedefs for WinTab functions to allow dynamic loading
-typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
-typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
-typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX);
-typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
-typedef BOOL (API * GHOST_WIN32_WTEnable)(HCTX, BOOL);
-typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL);
+typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
+typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
+typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX);
+typedef BOOL(API *GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
+typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL);
+typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL);
// typedef to user32 functions to disable gestures on windows
-typedef BOOL(API * GHOST_WIN32_RegisterTouchWindow)(HWND hwnd, ULONG ulFlags);
+typedef BOOL(API *GHOST_WIN32_RegisterTouchWindow)(HWND hwnd, ULONG ulFlags);
// typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions
-typedef UINT(API * GHOST_WIN32_GetDpiForWindow)(HWND);
+typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND);
#ifndef USER_DEFAULT_SCREEN_DPI
-#define USER_DEFAULT_SCREEN_DPI 96
-#endif // USER_DEFAULT_SCREEN_DPI
+# define USER_DEFAULT_SCREEN_DPI 96
+#endif // USER_DEFAULT_SCREEN_DPI
// typedefs for user32 functions to allow pointer functions
enum tagPOINTER_INPUT_TYPE {
- PT_POINTER = 1, // Generic pointer
- PT_TOUCH = 2, // Touch
- PT_PEN = 3, // Pen
- PT_MOUSE = 4, // Mouse
-#if(WINVER >= 0x0603)
- PT_TOUCHPAD = 5, // Touchpad
-#endif /* WINVER >= 0x0603 */
+ PT_POINTER = 1, // Generic pointer
+ PT_TOUCH = 2, // Touch
+ PT_PEN = 3, // Pen
+ PT_MOUSE = 4, // Mouse
+#if (WINVER >= 0x0603)
+ PT_TOUCHPAD = 5, // Touchpad
+#endif /* WINVER >= 0x0603 */
};
typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
- POINTER_CHANGE_NONE,
- POINTER_CHANGE_FIRSTBUTTON_DOWN,
- POINTER_CHANGE_FIRSTBUTTON_UP,
- POINTER_CHANGE_SECONDBUTTON_DOWN,
- POINTER_CHANGE_SECONDBUTTON_UP,
- POINTER_CHANGE_THIRDBUTTON_DOWN,
- POINTER_CHANGE_THIRDBUTTON_UP,
- POINTER_CHANGE_FOURTHBUTTON_DOWN,
- POINTER_CHANGE_FOURTHBUTTON_UP,
- POINTER_CHANGE_FIFTHBUTTON_DOWN,
- POINTER_CHANGE_FIFTHBUTTON_UP,
+ POINTER_CHANGE_NONE,
+ POINTER_CHANGE_FIRSTBUTTON_DOWN,
+ POINTER_CHANGE_FIRSTBUTTON_UP,
+ POINTER_CHANGE_SECONDBUTTON_DOWN,
+ POINTER_CHANGE_SECONDBUTTON_UP,
+ POINTER_CHANGE_THIRDBUTTON_DOWN,
+ POINTER_CHANGE_THIRDBUTTON_UP,
+ POINTER_CHANGE_FOURTHBUTTON_DOWN,
+ POINTER_CHANGE_FOURTHBUTTON_UP,
+ POINTER_CHANGE_FIFTHBUTTON_DOWN,
+ POINTER_CHANGE_FIFTHBUTTON_UP,
} POINTER_BUTTON_CHANGE_TYPE;
typedef DWORD POINTER_INPUT_TYPE;
typedef UINT32 POINTER_FLAGS;
typedef struct tagPOINTER_INFO {
- POINTER_INPUT_TYPE pointerType;
- UINT32 pointerId;
- UINT32 frameId;
- POINTER_FLAGS pointerFlags;
- HANDLE sourceDevice;
- HWND hwndTarget;
- POINT ptPixelLocation;
- POINT ptHimetricLocation;
- POINT ptPixelLocationRaw;
- POINT ptHimetricLocationRaw;
- DWORD dwTime;
- UINT32 historyCount;
- INT32 InputData;
- DWORD dwKeyStates;
- UINT64 PerformanceCount;
- POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
+ POINTER_INPUT_TYPE pointerType;
+ UINT32 pointerId;
+ UINT32 frameId;
+ POINTER_FLAGS pointerFlags;
+ HANDLE sourceDevice;
+ HWND hwndTarget;
+ POINT ptPixelLocation;
+ POINT ptHimetricLocation;
+ POINT ptPixelLocationRaw;
+ POINT ptHimetricLocationRaw;
+ DWORD dwTime;
+ UINT32 historyCount;
+ INT32 InputData;
+ DWORD dwKeyStates;
+ UINT64 PerformanceCount;
+ POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
} POINTER_INFO;
typedef UINT32 PEN_FLAGS;
-#define PEN_FLAG_NONE 0x00000000 // Default
-#define PEN_FLAG_BARREL 0x00000001 // The barrel button is pressed
-#define PEN_FLAG_INVERTED 0x00000002 // The pen is inverted
-#define PEN_FLAG_ERASER 0x00000004 // The eraser button is pressed
+#define PEN_FLAG_NONE 0x00000000 // Default
+#define PEN_FLAG_BARREL 0x00000001 // The barrel button is pressed
+#define PEN_FLAG_INVERTED 0x00000002 // The pen is inverted
+#define PEN_FLAG_ERASER 0x00000004 // The eraser button is pressed
typedef UINT32 PEN_MASK;
-#define PEN_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
-#define PEN_MASK_PRESSURE 0x00000001 // The pressure field is valid
-#define PEN_MASK_ROTATION 0x00000002 // The rotation field is valid
-#define PEN_MASK_TILT_X 0x00000004 // The tiltX field is valid
-#define PEN_MASK_TILT_Y 0x00000008 // The tiltY field is valid
+#define PEN_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
+#define PEN_MASK_PRESSURE 0x00000001 // The pressure field is valid
+#define PEN_MASK_ROTATION 0x00000002 // The rotation field is valid
+#define PEN_MASK_TILT_X 0x00000004 // The tiltX field is valid
+#define PEN_MASK_TILT_Y 0x00000008 // The tiltY field is valid
typedef struct tagPOINTER_PEN_INFO {
- POINTER_INFO pointerInfo;
- PEN_FLAGS penFlags;
- PEN_MASK penMask;
- UINT32 pressure;
- UINT32 rotation;
- INT32 tiltX;
- INT32 tiltY;
+ POINTER_INFO pointerInfo;
+ PEN_FLAGS penFlags;
+ PEN_MASK penMask;
+ UINT32 pressure;
+ UINT32 rotation;
+ INT32 tiltX;
+ INT32 tiltY;
} POINTER_PEN_INFO;
/*
* Flags that appear in pointer input message parameters
*/
-#define POINTER_MESSAGE_FLAG_NEW 0x00000001 // New pointer
-#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002 // Pointer has not departed
-#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004 // Pointer is in contact
-#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 // Primary action
-#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020 // Secondary action
-#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040 // Third button
-#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080 // Fourth button
-#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100 // Fifth button
-#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000 // Pointer is primary
-#define POINTER_MESSAGE_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental
-#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner
+#define POINTER_MESSAGE_FLAG_NEW 0x00000001 // New pointer
+#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002 // Pointer has not departed
+#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004 // Pointer is in contact
+#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 // Primary action
+#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020 // Secondary action
+#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040 // Third button
+#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080 // Fourth button
+#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100 // Fifth button
+#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000 // Pointer is primary
+#define POINTER_MESSAGE_FLAG_CONFIDENCE \
+ 0x00004000 // Pointer is considered unlikely to be accidental
+#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner
typedef UINT32 TOUCH_FLAGS;
-#define TOUCH_FLAG_NONE 0x00000000 // Default
+#define TOUCH_FLAG_NONE 0x00000000 // Default
typedef UINT32 TOUCH_MASK;
-#define TOUCH_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
-#define TOUCH_MASK_CONTACTAREA 0x00000001 // The rcContact field is valid
-#define TOUCH_MASK_ORIENTATION 0x00000002 // The orientation field is valid
-#define TOUCH_MASK_PRESSURE 0x00000004 // The pressure field is valid
+#define TOUCH_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
+#define TOUCH_MASK_CONTACTAREA 0x00000001 // The rcContact field is valid
+#define TOUCH_MASK_ORIENTATION 0x00000002 // The orientation field is valid
+#define TOUCH_MASK_PRESSURE 0x00000004 // The pressure field is valid
typedef struct tagPOINTER_TOUCH_INFO {
- POINTER_INFO pointerInfo;
- TOUCH_FLAGS touchFlags;
- TOUCH_MASK touchMask;
- RECT rcContact;
- RECT rcContactRaw;
- UINT32 orientation;
- UINT32 pressure;
+ POINTER_INFO pointerInfo;
+ TOUCH_FLAGS touchFlags;
+ TOUCH_MASK touchMask;
+ RECT rcContact;
+ RECT rcContactRaw;
+ UINT32 orientation;
+ UINT32 pressure;
} POINTER_TOUCH_INFO;
- /*
+/*
* Macros to retrieve information from pointer input message parameters
*/
-#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
-#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag))
-#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW)
-#define IS_POINTER_INRANGE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE)
-#define IS_POINTER_INCONTACT_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT)
-#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON)
-#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON)
-#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON)
-#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON)
-#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON)
-#define IS_POINTER_PRIMARY_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY)
-#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE)
-#define IS_POINTER_CANCELED_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED)
-
-typedef BOOL (API * GHOST_WIN32_GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo);
-typedef BOOL (API * GHOST_WIN32_GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo);
-typedef BOOL (API * GHOST_WIN32_GetPointerTouchInfo)(UINT32 pointerId, POINTER_TOUCH_INFO *penInfo);
+#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
+#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag))
+#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW)
+#define IS_POINTER_INRANGE_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE)
+#define IS_POINTER_INCONTACT_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT)
+#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON)
+#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON)
+#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON)
+#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON)
+#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON)
+#define IS_POINTER_PRIMARY_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY)
+#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE)
+#define IS_POINTER_CANCELED_WPARAM(wParam) \
+ IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED)
+
+typedef BOOL(API *GHOST_WIN32_GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo);
+typedef BOOL(API *GHOST_WIN32_GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo);
+typedef BOOL(API *GHOST_WIN32_GetPointerTouchInfo)(UINT32 pointerId, POINTER_TOUCH_INFO *penInfo);
struct GHOST_PointerInfoWin32 {
- GHOST_TInt32 pointerId;
- GHOST_TInt32 isInContact;
- GHOST_TInt32 isPrimary;
- GHOST_TSuccess hasButtonMask;
- GHOST_TButtonMask buttonMask;
- POINT pixelLocation;
- GHOST_TabletData tabletData;
+ GHOST_TInt32 pointerId;
+ GHOST_TInt32 isInContact;
+ GHOST_TInt32 isPrimary;
+ GHOST_TSuccess hasButtonMask;
+ GHOST_TButtonMask buttonMask;
+ POINT pixelLocation;
+ GHOST_TabletData tabletData;
};
/**
* GHOST window on M$ Windows OSs.
*/
class GHOST_WindowWin32 : public GHOST_Window {
-public:
- /**
- * Constructor.
- * Creates a new window and opens it.
- * To check if the window was created properly, use the getValid() method.
- * \param title The text shown in the title bar of the window.
- * \param left The coordinate of the left edge of the window.
- * \param top The coordinate of the top edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state the window is initially opened with.
- * \param type The type of drawing context installed in this window.
- * \param wantStereoVisual Stereo visual for quad buffered stereo.
- * \param wantNumOfAASamples Number of samples used for AA (zero if no AA)
- * \param parentWindowHwnd
- */
- GHOST_WindowWin32(GHOST_SystemWin32 *system,
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- bool wantStereoVisual = false,
- bool alphaBackground = false,
- GHOST_TUns16 wantNumOfAASamples = 0,
- GHOST_TEmbedderWindowID parentWindowHwnd = 0,
- bool is_debug = false);
-
- /**
- * Destructor.
- * Closes the window and disposes resources allocated.
- */
- ~GHOST_WindowWin32();
-
- /**
- * Returns indication as to whether the window is valid.
- * \return The validity of the window.
- */
- bool getValid() const;
-
- /**
- * Access to the handle of the window.
- * \return The handle of the window.
- */
- HWND getHWND() const;
-
- /**
- * Sets the title displayed in the title bar.
- * \param title The title to display in the title bar.
- */
- void setTitle(const STR_String& title);
-
- /**
- * Returns the title displayed in the title bar.
- * \param title The title displayed in the title bar.
- */
- void getTitle(STR_String& title) const;
-
- /**
- * Returns the window rectangle dimensions.
- * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
- * \param bounds The bounding rectangle of the window.
- */
- void getWindowBounds(GHOST_Rect& bounds) const;
-
- /**
- * Returns the client rectangle dimensions.
- * The left and top members of the rectangle are always zero.
- * \param bounds The bounding rectangle of the client area of the window.
- */
- void getClientBounds(GHOST_Rect& bounds) const;
-
- /**
- * Resizes client rectangle width.
- * \param width The new width of the client area of the window.
- */
- GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
-
- /**
- * Resizes client rectangle height.
- * \param height The new height of the client area of the window.
- */
- GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
-
- /**
- * Resizes client rectangle.
- * \param width The new width of the client area of the window.
- * \param height The new height of the client area of the window.
- */
- GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
-
- /**
- * Returns the state of the window (normal, minimized, maximized).
- * \return The state of the window.
- */
- GHOST_TWindowState getState() const;
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates
- * \param inX The x-coordinate on the screen.
- * \param inY The y-coordinate on the screen.
- * \param outX The x-coordinate in the client rectangle.
- * \param outY The y-coordinate in the client rectangle.
- */
- void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
-
- /**
- * Converts a point in screen coordinates to client rectangle coordinates
- * \param inX The x-coordinate in the client rectangle.
- * \param inY The y-coordinate in the client rectangle.
- * \param outX The x-coordinate on the screen.
- * \param outY The y-coordinate on the screen.
- */
- void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
-
- /**
- * Sets the state of the window (normal, minimized, maximized).
- * \param state The state of the window.
- * \return Indication of success.
- */
- GHOST_TSuccess setState(GHOST_TWindowState state);
-
- /**
- * Sets the order of the window (bottom, top).
- * \param order The order of the window.
- * \return Indication of success.
- */
- GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
-
- /**
- * Invalidates the contents of this window.
- */
- GHOST_TSuccess invalidate();
-
- /**
- * Sets the progress bar value displayed in the window/application icon
- * \param progress The progress %
- */
- GHOST_TSuccess setProgressBar(float progress);
-
- /**
- * Hides the progress bar in the icon
- */
- GHOST_TSuccess endProgressBar();
-
-
- /**
- * Register a mouse click event (should be called
- * for any real button press, controls mouse
- * capturing).
- *
- * \param press
- * 0 - mouse pressed
- * 1 - mouse released
- * 2 - operator grab
- * 3 - operator ungrab
- */
- void registerMouseClickEvent(int press);
-
- /**
- * Inform the window that it has lost mouse capture,
- * called in response to native window system messages.
- */
- void lostMouseCapture();
-
- /**
- * Loads the windows equivalent of a standard GHOST cursor.
- * \param visible Flag for cursor visibility.
- * \param cursorShape The cursor shape.
- */
- void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
-
- const GHOST_TabletData *GetTabletData()
- {
- return &m_tabletData;
- }
-
- void setTabletData(GHOST_TabletData * tabletData);
- bool useTabletAPI(GHOST_TTabletAPI api) const;
- void getPointerInfo(WPARAM wParam);
-
- void processWin32PointerEvent(WPARAM wParam);
- void processWin32TabletActivateEvent(WORD state);
- void processWin32TabletInitEvent();
- void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
- void bringTabletContextToFront();
-
- GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
-
- GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
-
- GHOST_TUns16 getDPIHint() override;
-
- GHOST_TSuccess getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam);
-
- /** if the window currently resizing */
- bool m_inLiveResize;
+ public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * \param title The text shown in the title bar of the window.
+ * \param left The coordinate of the left edge of the window.
+ * \param top The coordinate of the top edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state the window is initially opened with.
+ * \param type The type of drawing context installed in this window.
+ * \param wantStereoVisual Stereo visual for quad buffered stereo.
+ * \param wantNumOfAASamples Number of samples used for AA (zero if no AA)
+ * \param parentWindowHwnd
+ */
+ GHOST_WindowWin32(GHOST_SystemWin32 *system,
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ bool wantStereoVisual = false,
+ bool alphaBackground = false,
+ GHOST_TUns16 wantNumOfAASamples = 0,
+ GHOST_TEmbedderWindowID parentWindowHwnd = 0,
+ bool is_debug = false);
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ ~GHOST_WindowWin32();
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * \return The validity of the window.
+ */
+ bool getValid() const;
+
+ /**
+ * Access to the handle of the window.
+ * \return The handle of the window.
+ */
+ HWND getHWND() const;
+
+ /**
+ * Sets the title displayed in the title bar.
+ * \param title The title to display in the title bar.
+ */
+ void setTitle(const STR_String &title);
+
+ /**
+ * Returns the title displayed in the title bar.
+ * \param title The title displayed in the title bar.
+ */
+ void getTitle(STR_String &title) const;
+
+ /**
+ * Returns the window rectangle dimensions.
+ * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * \param bounds The bounding rectangle of the window.
+ */
+ void getWindowBounds(GHOST_Rect &bounds) const;
+
+ /**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * \param bounds The bounding rectangle of the client area of the window.
+ */
+ void getClientBounds(GHOST_Rect &bounds) const;
+
+ /**
+ * Resizes client rectangle width.
+ * \param width The new width of the client area of the window.
+ */
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+
+ /**
+ * Resizes client rectangle height.
+ * \param height The new height of the client area of the window.
+ */
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+
+ /**
+ * Resizes client rectangle.
+ * \param width The new width of the client area of the window.
+ * \param height The new height of the client area of the window.
+ */
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+
+ /**
+ * Returns the state of the window (normal, minimized, maximized).
+ * \return The state of the window.
+ */
+ GHOST_TWindowState getState() const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * \param inX The x-coordinate on the screen.
+ * \param inY The y-coordinate on the screen.
+ * \param outX The x-coordinate in the client rectangle.
+ * \param outY The y-coordinate in the client rectangle.
+ */
+ void screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * \param inX The x-coordinate in the client rectangle.
+ * \param inY The y-coordinate in the client rectangle.
+ * \param outX The x-coordinate on the screen.
+ * \param outY The y-coordinate on the screen.
+ */
+ void clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ /**
+ * Sets the state of the window (normal, minimized, maximized).
+ * \param state The state of the window.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setState(GHOST_TWindowState state);
+
+ /**
+ * Sets the order of the window (bottom, top).
+ * \param order The order of the window.
+ * \return Indication of success.
+ */
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+
+ /**
+ * Invalidates the contents of this window.
+ */
+ GHOST_TSuccess invalidate();
+
+ /**
+ * Sets the progress bar value displayed in the window/application icon
+ * \param progress The progress %
+ */
+ GHOST_TSuccess setProgressBar(float progress);
+
+ /**
+ * Hides the progress bar in the icon
+ */
+ GHOST_TSuccess endProgressBar();
+
+ /**
+ * Register a mouse click event (should be called
+ * for any real button press, controls mouse
+ * capturing).
+ *
+ * \param press
+ * 0 - mouse pressed
+ * 1 - mouse released
+ * 2 - operator grab
+ * 3 - operator ungrab
+ */
+ void registerMouseClickEvent(int press);
+
+ /**
+ * Inform the window that it has lost mouse capture,
+ * called in response to native window system messages.
+ */
+ void lostMouseCapture();
+
+ /**
+ * Loads the windows equivalent of a standard GHOST cursor.
+ * \param visible Flag for cursor visibility.
+ * \param cursorShape The cursor shape.
+ */
+ void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
+
+ const GHOST_TabletData *GetTabletData()
+ {
+ return &m_tabletData;
+ }
+
+ void setTabletData(GHOST_TabletData *tabletData);
+ bool useTabletAPI(GHOST_TTabletAPI api) const;
+ void getPointerInfo(WPARAM wParam);
+
+ void processWin32PointerEvent(WPARAM wParam);
+ void processWin32TabletActivateEvent(WORD state);
+ void processWin32TabletInitEvent();
+ void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
+ void bringTabletContextToFront();
+
+ GHOST_TSuccess beginFullScreen() const
+ {
+ return GHOST_kFailure;
+ }
+
+ GHOST_TSuccess endFullScreen() const
+ {
+ return GHOST_kFailure;
+ }
+
+ GHOST_TUns16 getDPIHint() override;
+
+ GHOST_TSuccess getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo, WPARAM wParam, LPARAM lParam);
+
+ /** if the window currently resizing */
+ bool m_inLiveResize;
#ifdef WITH_INPUT_IME
- GHOST_ImeWin32 *getImeInput() {return &m_imeInput;}
+ GHOST_ImeWin32 *getImeInput()
+ {
+ return &m_imeInput;
+ }
- void beginIME(
- GHOST_TInt32 x, GHOST_TInt32 y,
- GHOST_TInt32 w, GHOST_TInt32 h,
- int completed);
+ void beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed);
- void endIME();
+ void endIME();
#endif /* WITH_INPUT_IME */
-private:
-
- /**
- * \param type The type of rendering context create.
- * \return Indication of success.
- */
- GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
-
- /**
- * Sets the cursor visibility on the window using
- * native window system calls.
- */
- GHOST_TSuccess setWindowCursorVisibility(bool visible);
-
- /**
- * Sets the cursor grab on the window using native window system calls.
- * Using registerMouseClickEvent.
- * \param mode GHOST_TGrabCursorMode.
- */
- GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX, int hotY);
-
- GHOST_TSuccess setWindowCustomCursorShape(
- GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex,
- int sizey,
- int hotX,
- int hotY,
- int fg_color,
- int bg_color
- );
-
- /** Pointer to system */
- GHOST_SystemWin32 *m_system;
- /** Pointer to COM IDropTarget implementor */
- GHOST_DropTargetWin32 *m_dropTarget;
- /** Window handle. */
- HWND m_hWnd;
- /** Device context handle. */
- HDC m_hDC;
-
- /** Flag for if window has captured the mouse */
- bool m_hasMouseCaptured;
- /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
- * Multiple grabs must be released with a single ungrab */
- bool m_hasGrabMouse;
- /** Count of number of pressed buttons */
- int m_nPressedButtons;
- /** HCURSOR structure of the custom cursor */
- HCURSOR m_customCursor;
- /** request GL context aith alpha channel */
- bool m_wantAlphaBackground;
-
- /** ITaskbarList3 structure for progress bar*/
- ITaskbarList3 *m_Bar;
-
- static const wchar_t *s_windowClassName;
- static const int s_maxTitleLength;
-
- /** Tablet data for GHOST */
- GHOST_TabletData m_tabletData;
-
- /* Wintab API */
- struct {
- /** WinTab dll handle */
- HMODULE handle;
-
- /** API functions */
- GHOST_WIN32_WTInfo info;
- GHOST_WIN32_WTOpen open;
- GHOST_WIN32_WTClose close;
- GHOST_WIN32_WTPacket packet;
- GHOST_WIN32_WTEnable enable;
- GHOST_WIN32_WTOverlap overlap;
-
- /** Stores the Tablet context if detected Tablet features using WinTab.dll */
- HCTX tablet;
- LONG maxPressure;
- LONG maxAzimuth, maxAltitude;
- } m_wintab;
-
- GHOST_TWindowState m_normal_state;
-
- /** user32 dll handle*/
- HMODULE m_user32;
- GHOST_WIN32_GetPointerInfo m_fpGetPointerInfo;
- GHOST_WIN32_GetPointerPenInfo m_fpGetPointerPenInfo;
- GHOST_WIN32_GetPointerTouchInfo m_fpGetPointerTouchInfo;
-
- /** Hwnd to parent window */
- GHOST_TEmbedderWindowID m_parentWindowHwnd;
+ private:
+ /**
+ * \param type The type of rendering context create.
+ * \return Indication of success.
+ */
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorVisibility(bool visible);
+
+ /**
+ * Sets the cursor grab on the window using native window system calls.
+ * Using registerMouseClickEvent.
+ * \param mode GHOST_TGrabCursorMode.
+ */
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
+
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color);
+
+ /** Pointer to system */
+ GHOST_SystemWin32 *m_system;
+ /** Pointer to COM IDropTarget implementor */
+ GHOST_DropTargetWin32 *m_dropTarget;
+ /** Window handle. */
+ HWND m_hWnd;
+ /** Device context handle. */
+ HDC m_hDC;
+
+ /** Flag for if window has captured the mouse */
+ bool m_hasMouseCaptured;
+ /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
+ * Multiple grabs must be released with a single ungrab */
+ bool m_hasGrabMouse;
+ /** Count of number of pressed buttons */
+ int m_nPressedButtons;
+ /** HCURSOR structure of the custom cursor */
+ HCURSOR m_customCursor;
+ /** request GL context aith alpha channel */
+ bool m_wantAlphaBackground;
+
+ /** ITaskbarList3 structure for progress bar*/
+ ITaskbarList3 *m_Bar;
+
+ static const wchar_t *s_windowClassName;
+ static const int s_maxTitleLength;
+
+ /** Tablet data for GHOST */
+ GHOST_TabletData m_tabletData;
+
+ /* Wintab API */
+ struct {
+ /** WinTab dll handle */
+ HMODULE handle;
+
+ /** API functions */
+ GHOST_WIN32_WTInfo info;
+ GHOST_WIN32_WTOpen open;
+ GHOST_WIN32_WTClose close;
+ GHOST_WIN32_WTPacket packet;
+ GHOST_WIN32_WTEnable enable;
+ GHOST_WIN32_WTOverlap overlap;
+
+ /** Stores the Tablet context if detected Tablet features using WinTab.dll */
+ HCTX tablet;
+ LONG maxPressure;
+ LONG maxAzimuth, maxAltitude;
+ } m_wintab;
+
+ GHOST_TWindowState m_normal_state;
+
+ /** user32 dll handle*/
+ HMODULE m_user32;
+ GHOST_WIN32_GetPointerInfo m_fpGetPointerInfo;
+ GHOST_WIN32_GetPointerPenInfo m_fpGetPointerPenInfo;
+ GHOST_WIN32_GetPointerTouchInfo m_fpGetPointerTouchInfo;
+
+ /** Hwnd to parent window */
+ GHOST_TEmbedderWindowID m_parentWindowHwnd;
#ifdef WITH_INPUT_IME
- /** Handle input method editors event */
- GHOST_ImeWin32 m_imeInput;
+ /** Handle input method editors event */
+ GHOST_ImeWin32 m_imeInput;
#endif
- bool m_debug_context;
+ bool m_debug_context;
};
-#endif // __GHOST_WINDOWWIN32_H__
+#endif // __GHOST_WINDOWWIN32_H__
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 7a2c9967198..21e42e01aea 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -26,7 +26,7 @@
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#ifdef WITH_X11_ALPHA
-#include <X11/extensions/Xrender.h>
+# include <X11/extensions/Xrender.h>
#endif
#include "GHOST_WindowX11.h"
#include "GHOST_SystemX11.h"
@@ -66,13 +66,13 @@
* lifted verbatim from blut. */
typedef struct {
- long flags;
- long functions;
- long decorations;
- long input_mode;
+ long flags;
+ long functions;
+ long decorations;
+ long input_mode;
} MotifWmHints;
-#define MWM_HINTS_DECORATIONS (1L << 1)
+#define MWM_HINTS_DECORATIONS (1L << 1)
#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX 64
@@ -90,161 +90,166 @@ typedef struct {
#define _NET_WM_STATE_ADD 1
// #define _NET_WM_STATE_TOGGLE 2 // UNUSED
-static XVisualInfo *x11_visualinfo_from_glx(
- Display *display,
- bool stereoVisual,
- GHOST_TUns16 *r_numOfAASamples,
- bool needAlpha,
- GLXFBConfig *fbconfig)
+static XVisualInfo *x11_visualinfo_from_glx(Display *display,
+ bool stereoVisual,
+ GHOST_TUns16 *r_numOfAASamples,
+ bool needAlpha,
+ GLXFBConfig *fbconfig)
{
- XVisualInfo *visual = NULL;
- GHOST_TUns16 numOfAASamples = *r_numOfAASamples;
- int glx_major, glx_minor, glx_version; /* GLX version: major.minor */
- GHOST_TUns16 actualSamples;
- int glx_attribs[64];
-
- *fbconfig = NULL;
-
- /* Set up the minimum attributes that we require and see if
- * X can find us a visual matching those requirements. */
-
- if (!glXQueryVersion(display, &glx_major, &glx_minor)) {
- fprintf(stderr,
- "%s:%d: X11 glXQueryVersion() failed, "
- "verify working openGL system!\n",
- __FILE__, __LINE__);
-
- return NULL;
- }
- glx_version = glx_major*100 + glx_minor;
-
- if (glx_version >= 104) {
- actualSamples = numOfAASamples;
- }
- else {
- numOfAASamples = 0;
- actualSamples = 0;
- }
+ XVisualInfo *visual = NULL;
+ GHOST_TUns16 numOfAASamples = *r_numOfAASamples;
+ int glx_major, glx_minor, glx_version; /* GLX version: major.minor */
+ GHOST_TUns16 actualSamples;
+ int glx_attribs[64];
+
+ *fbconfig = NULL;
+
+ /* Set up the minimum attributes that we require and see if
+ * X can find us a visual matching those requirements. */
+
+ if (!glXQueryVersion(display, &glx_major, &glx_minor)) {
+ fprintf(stderr,
+ "%s:%d: X11 glXQueryVersion() failed, "
+ "verify working openGL system!\n",
+ __FILE__,
+ __LINE__);
+
+ return NULL;
+ }
+ glx_version = glx_major * 100 + glx_minor;
+
+ if (glx_version >= 104) {
+ actualSamples = numOfAASamples;
+ }
+ else {
+ numOfAASamples = 0;
+ actualSamples = 0;
+ }
#ifdef WITH_X11_ALPHA
- if ( needAlpha
- && glx_version >= 103
- && (glXChooseFBConfig ||
- (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXChooseFBConfig")) != NULL)
- && (glXGetVisualFromFBConfig ||
- (glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXGetVisualFromFBConfig")) != NULL)
- ) {
- GLXFBConfig *fbconfigs;
- int nbfbconfig;
- int i;
-
- for (;;) {
-
- GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, true);
-
- fbconfigs = glXChooseFBConfig(display, DefaultScreen(display), glx_attribs, &nbfbconfig);
-
- /* Any sample level or even zero, which means oversampling disabled, is good
- * but we need a valid visual to continue */
- if (nbfbconfig > 0) {
- /* take a frame buffer config that has alpha cap */
- for (i=0 ;i<nbfbconfig; i++) {
- visual = (XVisualInfo*)glXGetVisualFromFBConfig(display, fbconfigs[i]);
- if (!visual)
- continue;
- /* if we don't need a alpha background, the first config will do, otherwise
- * test the alphaMask as it won't necessarily be present */
- if (needAlpha) {
- XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual);
- if (!pict_format)
- continue;
- if (pict_format->direct.alphaMask <= 0)
- continue;
- }
- *fbconfig = fbconfigs[i];
- break;
- }
- XFree(fbconfigs);
- if (i<nbfbconfig) {
- if (actualSamples < numOfAASamples) {
- fprintf(stderr,
- "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
- "Substituting one that uses %d samples.\n",
- numOfAASamples, actualSamples);
- }
- break;
- }
- visual = NULL;
- }
-
- if (actualSamples == 0) {
- /* All options exhausted, cannot continue */
- fprintf(stderr,
- "%s:%d: X11 glXChooseVisual() failed, "
- "verify working openGL system!\n",
- __FILE__, __LINE__);
-
- return NULL;
- }
- else {
- --actualSamples;
- }
- }
- }
- else
+ if (needAlpha && glx_version >= 103 &&
+ (glXChooseFBConfig || (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB(
+ (const GLubyte *)"glXChooseFBConfig")) != NULL) &&
+ (glXGetVisualFromFBConfig ||
+ (glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddressARB(
+ (const GLubyte *)"glXGetVisualFromFBConfig")) != NULL)) {
+ GLXFBConfig *fbconfigs;
+ int nbfbconfig;
+ int i;
+
+ for (;;) {
+
+ GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, true);
+
+ fbconfigs = glXChooseFBConfig(display, DefaultScreen(display), glx_attribs, &nbfbconfig);
+
+ /* Any sample level or even zero, which means oversampling disabled, is good
+ * but we need a valid visual to continue */
+ if (nbfbconfig > 0) {
+ /* take a frame buffer config that has alpha cap */
+ for (i = 0; i < nbfbconfig; i++) {
+ visual = (XVisualInfo *)glXGetVisualFromFBConfig(display, fbconfigs[i]);
+ if (!visual)
+ continue;
+ /* if we don't need a alpha background, the first config will do, otherwise
+ * test the alphaMask as it won't necessarily be present */
+ if (needAlpha) {
+ XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual);
+ if (!pict_format)
+ continue;
+ if (pict_format->direct.alphaMask <= 0)
+ continue;
+ }
+ *fbconfig = fbconfigs[i];
+ break;
+ }
+ XFree(fbconfigs);
+ if (i < nbfbconfig) {
+ if (actualSamples < numOfAASamples) {
+ fprintf(stderr,
+ "Warning! Unable to find a multisample pixel format that supports exactly %d "
+ "samples. "
+ "Substituting one that uses %d samples.\n",
+ numOfAASamples,
+ actualSamples);
+ }
+ break;
+ }
+ visual = NULL;
+ }
+
+ if (actualSamples == 0) {
+ /* All options exhausted, cannot continue */
+ fprintf(stderr,
+ "%s:%d: X11 glXChooseVisual() failed, "
+ "verify working openGL system!\n",
+ __FILE__,
+ __LINE__);
+
+ return NULL;
+ }
+ else {
+ --actualSamples;
+ }
+ }
+ }
+ else
#endif
- {
- /* legacy, don't use extension */
- for (;;) {
- GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, false);
-
- visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs);
-
- /* Any sample level or even zero, which means oversampling disabled, is good
- * but we need a valid visual to continue */
- if (visual != NULL) {
- if (actualSamples < numOfAASamples) {
- fprintf(stderr,
- "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
- "Substituting one that uses %d samples.\n",
- numOfAASamples, actualSamples);
- }
- break;
- }
-
- if (actualSamples == 0) {
- /* All options exhausted, cannot continue */
- fprintf(stderr,
- "%s:%d: X11 glXChooseVisual() failed, "
- "verify working openGL system!\n",
- __FILE__, __LINE__);
-
- return NULL;
- }
- else {
- --actualSamples;
- }
- }
- }
- *r_numOfAASamples = actualSamples;
- return visual;
+ {
+ /* legacy, don't use extension */
+ for (;;) {
+ GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, false);
+
+ visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs);
+
+ /* Any sample level or even zero, which means oversampling disabled, is good
+ * but we need a valid visual to continue */
+ if (visual != NULL) {
+ if (actualSamples < numOfAASamples) {
+ fprintf(stderr,
+ "Warning! Unable to find a multisample pixel format that supports exactly %d "
+ "samples. "
+ "Substituting one that uses %d samples.\n",
+ numOfAASamples,
+ actualSamples);
+ }
+ break;
+ }
+
+ if (actualSamples == 0) {
+ /* All options exhausted, cannot continue */
+ fprintf(stderr,
+ "%s:%d: X11 glXChooseVisual() failed, "
+ "verify working openGL system!\n",
+ __FILE__,
+ __LINE__);
+
+ return NULL;
+ }
+ else {
+ --actualSamples;
+ }
+ }
+ }
+ *r_numOfAASamples = actualSamples;
+ return visual;
}
-GHOST_WindowX11::
-GHOST_WindowX11(GHOST_SystemX11 *system,
- Display *display,
- const STR_String &title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- const GHOST_TEmbedderWindowID parentWindow,
- GHOST_TDrawingContextType type,
- const bool stereoVisual,
- const bool exclusive,
- const bool alphaBackground,
- const GHOST_TUns16 numOfAASamples, const bool is_debug)
+GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
+ Display *display,
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const GHOST_TEmbedderWindowID parentWindow,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual,
+ const bool exclusive,
+ const bool alphaBackground,
+ const GHOST_TUns16 numOfAASamples,
+ const bool is_debug)
: GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples),
m_display(display),
m_visualInfo(NULL),
@@ -265,893 +270,927 @@ GHOST_WindowX11(GHOST_SystemX11 *system,
m_valid_setup(false),
m_is_debug_context(is_debug)
{
- if (type == GHOST_kDrawingContextTypeOpenGL) {
- m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples, alphaBackground, (GLXFBConfig*)&m_fbconfig);
- }
- else {
- XVisualInfo tmp = {0};
- int n;
- m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n);
- }
-
- /* caller needs to check 'getValid()' */
- if (m_visualInfo == NULL) {
- fprintf(stderr, "initial window could not find the GLX extension\n");
- return;
- }
-
- unsigned int xattributes_valuemask = 0;
-
- XSetWindowAttributes xattributes;
- memset(&xattributes, 0, sizeof(xattributes));
-
- xattributes_valuemask |= CWBorderPixel;
- xattributes.border_pixel = 0;
-
- /* Specify which events we are interested in hearing. */
-
- xattributes_valuemask |= CWEventMask;
- xattributes.event_mask =
- ExposureMask | StructureNotifyMask |
- KeyPressMask | KeyReleaseMask |
- EnterWindowMask | LeaveWindowMask |
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | FocusChangeMask |
- PropertyChangeMask | KeymapStateMask;
-
- if (exclusive) {
- xattributes_valuemask |= CWOverrideRedirect;
- xattributes.override_redirect = True;
- }
-
- xattributes_valuemask |= CWColormap;
- xattributes.colormap = XCreateColormap(
- m_display,
- RootWindow(m_display, m_visualInfo->screen),
- m_visualInfo->visual,
- AllocNone
- );
-
- /* create the window! */
- if (parentWindow == 0) {
- m_window = XCreateWindow(
- m_display,
- RootWindow(m_display, m_visualInfo->screen),
- left, top, width, height,
- 0, /* no border. */
- m_visualInfo->depth,
- InputOutput,
- m_visualInfo->visual,
- xattributes_valuemask,
- &xattributes);
- }
- else {
- Window root_return;
- int x_return, y_return;
- unsigned int w_return, h_return, border_w_return, depth_return;
-
- XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return,
- &w_return, &h_return, &border_w_return, &depth_return);
-
- left = 0;
- top = 0;
- width = w_return;
- height = h_return;
-
-
- m_window = XCreateWindow(
- m_display,
- parentWindow, /* reparent against embedder */
- left, top, width, height,
- 0, /* no border. */
- m_visualInfo->depth,
- InputOutput,
- m_visualInfo->visual,
- xattributes_valuemask,
- &xattributes);
-
- XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
-
- }
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+ m_visualInfo = x11_visualinfo_from_glx(m_display,
+ stereoVisual,
+ &m_wantNumOfAASamples,
+ alphaBackground,
+ (GLXFBConfig *)&m_fbconfig);
+ }
+ else {
+ XVisualInfo tmp = {0};
+ int n;
+ m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n);
+ }
+
+ /* caller needs to check 'getValid()' */
+ if (m_visualInfo == NULL) {
+ fprintf(stderr, "initial window could not find the GLX extension\n");
+ return;
+ }
+
+ unsigned int xattributes_valuemask = 0;
+
+ XSetWindowAttributes xattributes;
+ memset(&xattributes, 0, sizeof(xattributes));
+
+ xattributes_valuemask |= CWBorderPixel;
+ xattributes.border_pixel = 0;
+
+ /* Specify which events we are interested in hearing. */
+
+ xattributes_valuemask |= CWEventMask;
+ xattributes.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask |
+ EnterWindowMask | LeaveWindowMask | ButtonPressMask |
+ ButtonReleaseMask | PointerMotionMask | FocusChangeMask |
+ PropertyChangeMask | KeymapStateMask;
+
+ if (exclusive) {
+ xattributes_valuemask |= CWOverrideRedirect;
+ xattributes.override_redirect = True;
+ }
+
+ xattributes_valuemask |= CWColormap;
+ xattributes.colormap = XCreateColormap(
+ m_display, RootWindow(m_display, m_visualInfo->screen), m_visualInfo->visual, AllocNone);
+
+ /* create the window! */
+ if (parentWindow == 0) {
+ m_window = XCreateWindow(m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ left,
+ top,
+ width,
+ height,
+ 0, /* no border. */
+ m_visualInfo->depth,
+ InputOutput,
+ m_visualInfo->visual,
+ xattributes_valuemask,
+ &xattributes);
+ }
+ else {
+ Window root_return;
+ int x_return, y_return;
+ unsigned int w_return, h_return, border_w_return, depth_return;
+
+ XGetGeometry(m_display,
+ parentWindow,
+ &root_return,
+ &x_return,
+ &y_return,
+ &w_return,
+ &h_return,
+ &border_w_return,
+ &depth_return);
+
+ left = 0;
+ top = 0;
+ width = w_return;
+ height = h_return;
+
+ m_window = XCreateWindow(m_display,
+ parentWindow, /* reparent against embedder */
+ left,
+ top,
+ width,
+ height,
+ 0, /* no border. */
+ m_visualInfo->depth,
+ InputOutput,
+ m_visualInfo->visual,
+ xattributes_valuemask,
+ &xattributes);
+
+ XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
+ }
#ifdef WITH_XDND
- /* initialize drop target for newly created window */
- m_dropTarget = new GHOST_DropTargetX11(this, m_system);
- GHOST_PRINT("Set drop target\n");
+ /* initialize drop target for newly created window */
+ m_dropTarget = new GHOST_DropTargetX11(this, m_system);
+ GHOST_PRINT("Set drop target\n");
#endif
- if (state == GHOST_kWindowStateMaximized || state == GHOST_kWindowStateFullScreen) {
- Atom atoms[2];
- int count = 0;
- if (state == GHOST_kWindowStateMaximized) {
- atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
- atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
- }
- else {
- atoms[count++] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
- }
-
- XChangeProperty(m_display, m_window, m_system->m_atom._NET_WM_STATE, XA_ATOM, 32,
- PropModeReplace, (unsigned char *)atoms, count);
- m_post_init = False;
- }
- /*
- * One of the problem with WM-spec is that can't set a property
- * to a window that isn't mapped. That is why we can't "just
- * call setState" here.
- *
- * To fix this, we first need know that the window is really
- * map waiting for the MapNotify event.
- *
- * So, m_post_init indicate that we need wait for the MapNotify
- * event and then set the Window state to the m_post_state.
- */
- else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
- m_post_init = True;
- m_post_state = state;
- }
- else {
- m_post_init = False;
- m_post_state = GHOST_kWindowStateNormal;
- }
-
-
- /* Create some hints for the window manager on how
- * we want this window treated. */
- {
- XSizeHints *xsizehints = XAllocSizeHints();
- xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
- xsizehints->x = left;
- xsizehints->y = top;
- xsizehints->width = width;
- xsizehints->height = height;
- xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
- xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
- xsizehints->max_width = 65535;
- xsizehints->max_height = 65535;
- XSetWMNormalHints(m_display, m_window, xsizehints);
- XFree(xsizehints);
- }
-
-
- /* XClassHint, title */
- {
- XClassHint *xclasshint = XAllocClassHint();
- const int len = title.Length() + 1;
- char *wmclass = (char *)malloc(sizeof(char) * len);
- memcpy(wmclass, title.ReadPtr(), len * sizeof(char));
- xclasshint->res_name = wmclass;
- xclasshint->res_class = wmclass;
- XSetClassHint(m_display, m_window, xclasshint);
- free(wmclass);
- XFree(xclasshint);
- }
-
-
- /* The basic for a good ICCCM "work" */
- if (m_system->m_atom.WM_PROTOCOLS) {
- Atom atoms[2];
- int natom = 0;
-
- if (m_system->m_atom.WM_DELETE_WINDOW) {
- atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW;
- natom++;
- }
-
- if (m_system->m_atom.WM_TAKE_FOCUS && m_system->m_windowFocus) {
- atoms[natom] = m_system->m_atom.WM_TAKE_FOCUS;
- natom++;
- }
-
- if (natom) {
- /* printf("Register atoms: %d\n", natom); */
- XSetWMProtocols(m_display, m_window, atoms, natom);
- }
- }
-
- /* Set the window hints */
- {
- XWMHints *xwmhints = XAllocWMHints();
- xwmhints->initial_state = NormalState;
- xwmhints->input = (m_system->m_windowFocus) ? True : False;
- xwmhints->flags = InputHint | StateHint;
- XSetWMHints(display, m_window, xwmhints);
- XFree(xwmhints);
- }
-
-
- /* set the icon */
- {
- Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False);
- XChangeProperty(m_display, m_window, _NET_WM_ICON, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)BLENDER_ICONS_WM_X11,
- sizeof(BLENDER_ICONS_WM_X11) / sizeof(unsigned long));
- }
-
- /* set the process ID (_NET_WM_PID) */
- {
- Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False);
- pid_t pid = getpid();
- XChangeProperty(m_display, m_window, _NET_WM_PID, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)&pid, 1);
- }
-
-
- /* set the hostname (WM_CLIENT_MACHINE) */
- {
- char hostname[HOST_NAME_MAX];
- char *text_array[1];
- XTextProperty text_prop;
-
- gethostname(hostname, sizeof(hostname));
- hostname[sizeof(hostname) - 1] = '\0';
- text_array[0] = hostname;
-
- XStringListToTextProperty(text_array, 1, &text_prop);
- XSetWMClientMachine(m_display, m_window, &text_prop);
- XFree(text_prop.value);
- }
+ if (state == GHOST_kWindowStateMaximized || state == GHOST_kWindowStateFullScreen) {
+ Atom atoms[2];
+ int count = 0;
+ if (state == GHOST_kWindowStateMaximized) {
+ atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
+ atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
+ }
+ else {
+ atoms[count++] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
+ }
+
+ XChangeProperty(m_display,
+ m_window,
+ m_system->m_atom._NET_WM_STATE,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (unsigned char *)atoms,
+ count);
+ m_post_init = False;
+ }
+ /*
+ * One of the problem with WM-spec is that can't set a property
+ * to a window that isn't mapped. That is why we can't "just
+ * call setState" here.
+ *
+ * To fix this, we first need know that the window is really
+ * map waiting for the MapNotify event.
+ *
+ * So, m_post_init indicate that we need wait for the MapNotify
+ * event and then set the Window state to the m_post_state.
+ */
+ else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
+ m_post_init = True;
+ m_post_state = state;
+ }
+ else {
+ m_post_init = False;
+ m_post_state = GHOST_kWindowStateNormal;
+ }
+
+ /* Create some hints for the window manager on how
+ * we want this window treated. */
+ {
+ XSizeHints *xsizehints = XAllocSizeHints();
+ xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
+ xsizehints->x = left;
+ xsizehints->y = top;
+ xsizehints->width = width;
+ xsizehints->height = height;
+ xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
+ xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
+ xsizehints->max_width = 65535;
+ xsizehints->max_height = 65535;
+ XSetWMNormalHints(m_display, m_window, xsizehints);
+ XFree(xsizehints);
+ }
+
+ /* XClassHint, title */
+ {
+ XClassHint *xclasshint = XAllocClassHint();
+ const int len = title.Length() + 1;
+ char *wmclass = (char *)malloc(sizeof(char) * len);
+ memcpy(wmclass, title.ReadPtr(), len * sizeof(char));
+ xclasshint->res_name = wmclass;
+ xclasshint->res_class = wmclass;
+ XSetClassHint(m_display, m_window, xclasshint);
+ free(wmclass);
+ XFree(xclasshint);
+ }
+
+ /* The basic for a good ICCCM "work" */
+ if (m_system->m_atom.WM_PROTOCOLS) {
+ Atom atoms[2];
+ int natom = 0;
+
+ if (m_system->m_atom.WM_DELETE_WINDOW) {
+ atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW;
+ natom++;
+ }
+
+ if (m_system->m_atom.WM_TAKE_FOCUS && m_system->m_windowFocus) {
+ atoms[natom] = m_system->m_atom.WM_TAKE_FOCUS;
+ natom++;
+ }
+
+ if (natom) {
+ /* printf("Register atoms: %d\n", natom); */
+ XSetWMProtocols(m_display, m_window, atoms, natom);
+ }
+ }
+
+ /* Set the window hints */
+ {
+ XWMHints *xwmhints = XAllocWMHints();
+ xwmhints->initial_state = NormalState;
+ xwmhints->input = (m_system->m_windowFocus) ? True : False;
+ xwmhints->flags = InputHint | StateHint;
+ XSetWMHints(display, m_window, xwmhints);
+ XFree(xwmhints);
+ }
+
+ /* set the icon */
+ {
+ Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False);
+ XChangeProperty(m_display,
+ m_window,
+ _NET_WM_ICON,
+ XA_CARDINAL,
+ 32,
+ PropModeReplace,
+ (unsigned char *)BLENDER_ICONS_WM_X11,
+ sizeof(BLENDER_ICONS_WM_X11) / sizeof(unsigned long));
+ }
+
+ /* set the process ID (_NET_WM_PID) */
+ {
+ Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False);
+ pid_t pid = getpid();
+ XChangeProperty(m_display,
+ m_window,
+ _NET_WM_PID,
+ XA_CARDINAL,
+ 32,
+ PropModeReplace,
+ (unsigned char *)&pid,
+ 1);
+ }
+
+ /* set the hostname (WM_CLIENT_MACHINE) */
+ {
+ char hostname[HOST_NAME_MAX];
+ char *text_array[1];
+ XTextProperty text_prop;
+
+ gethostname(hostname, sizeof(hostname));
+ hostname[sizeof(hostname) - 1] = '\0';
+ text_array[0] = hostname;
+
+ XStringListToTextProperty(text_array, 1, &text_prop);
+ XSetWMClientMachine(m_display, m_window, &text_prop);
+ XFree(text_prop.value);
+ }
#ifdef WITH_X11_XINPUT
- refreshXInputDevices();
+ refreshXInputDevices();
- m_tabletData.Active = GHOST_kTabletModeNone;
+ m_tabletData.Active = GHOST_kTabletModeNone;
#endif
+ /* now set up the rendering context. */
+ if (setDrawingContextType(type) == GHOST_kSuccess) {
+ m_valid_setup = true;
+ GHOST_PRINT("Created window\n");
+ }
- /* now set up the rendering context. */
- if (setDrawingContextType(type) == GHOST_kSuccess) {
- m_valid_setup = true;
- GHOST_PRINT("Created window\n");
- }
+ setTitle(title);
- setTitle(title);
+ if (exclusive && system->m_windowFocus) {
+ XMapRaised(m_display, m_window);
+ }
+ else {
+ XMapWindow(m_display, m_window);
- if (exclusive && system->m_windowFocus) {
- XMapRaised(m_display, m_window);
- }
- else {
- XMapWindow(m_display, m_window);
+ if (!system->m_windowFocus) {
+ XLowerWindow(m_display, m_window);
+ }
+ }
+ GHOST_PRINT("Mapped window\n");
- if (!system->m_windowFocus) {
- XLowerWindow(m_display, m_window);
- }
- }
- GHOST_PRINT("Mapped window\n");
-
- XFlush(m_display);
+ XFlush(m_display);
}
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
static Bool destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/)
{
- GHOST_PRINT("XIM input context destroyed\n");
+ GHOST_PRINT("XIM input context destroyed\n");
- if (ptr) {
- *(XIC *)ptr = NULL;
- }
- /* Ignored by X11. */
- return True;
+ if (ptr) {
+ *(XIC *)ptr = NULL;
+ }
+ /* Ignored by X11. */
+ return True;
}
bool GHOST_WindowX11::createX11_XIC()
{
- XIM xim = m_system->getX11_XIM();
- if (!xim)
- return false;
-
- XICCallback destroy;
- destroy.callback = (XICProc)destroyICCallback;
- destroy.client_data = (XPointer)&m_xic;
- m_xic = XCreateIC(xim, XNClientWindow, m_window, XNFocusWindow, m_window,
- XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
- XNResourceName, GHOST_X11_RES_NAME,
- XNResourceClass, GHOST_X11_RES_CLASS,
- XNDestroyCallback, &destroy,
- NULL);
- if (!m_xic)
- return false;
-
- unsigned long fevent;
- XGetICValues(m_xic, XNFilterEvents, &fevent, NULL);
- XSelectInput(m_display, m_window,
- ExposureMask | StructureNotifyMask |
- KeyPressMask | KeyReleaseMask |
- EnterWindowMask | LeaveWindowMask |
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | FocusChangeMask |
- PropertyChangeMask | KeymapStateMask | fevent);
- return true;
+ XIM xim = m_system->getX11_XIM();
+ if (!xim)
+ return false;
+
+ XICCallback destroy;
+ destroy.callback = (XICProc)destroyICCallback;
+ destroy.client_data = (XPointer)&m_xic;
+ m_xic = XCreateIC(xim,
+ XNClientWindow,
+ m_window,
+ XNFocusWindow,
+ m_window,
+ XNInputStyle,
+ XIMPreeditNothing | XIMStatusNothing,
+ XNResourceName,
+ GHOST_X11_RES_NAME,
+ XNResourceClass,
+ GHOST_X11_RES_CLASS,
+ XNDestroyCallback,
+ &destroy,
+ NULL);
+ if (!m_xic)
+ return false;
+
+ unsigned long fevent;
+ XGetICValues(m_xic, XNFilterEvents, &fevent, NULL);
+ XSelectInput(m_display,
+ m_window,
+ ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask |
+ EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | FocusChangeMask | PropertyChangeMask | KeymapStateMask |
+ fevent);
+ return true;
}
#endif
#ifdef WITH_X11_XINPUT
void GHOST_WindowX11::refreshXInputDevices()
{
- if (m_system->m_xinput_version.present) {
- std::vector<XEventClass> xevents;
-
- for (GHOST_SystemX11::GHOST_TabletX11& xtablet: m_system->GetXTablets()) {
- /* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
- * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
- * otherwise we do not get any tablet motion event once pen is pressed... See T43367.
- */
- XEventClass ev;
-
- DeviceMotionNotify(xtablet.Device, xtablet.MotionEvent, ev);
- if (ev) xevents.push_back(ev);
- DeviceButtonPress(xtablet.Device, xtablet.PressEvent, ev);
- if (ev) xevents.push_back(ev);
- ProximityIn(xtablet.Device, xtablet.ProxInEvent, ev);
- if (ev) xevents.push_back(ev);
- ProximityOut(xtablet.Device, xtablet.ProxOutEvent, ev);
- if (ev) xevents.push_back(ev);
- }
-
- XSelectExtensionEvent(m_display, m_window, xevents.data(), (int)xevents.size());
- }
+ if (m_system->m_xinput_version.present) {
+ std::vector<XEventClass> xevents;
+
+ for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
+ /* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
+ * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
+ * otherwise we do not get any tablet motion event once pen is pressed... See T43367.
+ */
+ XEventClass ev;
+
+ DeviceMotionNotify(xtablet.Device, xtablet.MotionEvent, ev);
+ if (ev)
+ xevents.push_back(ev);
+ DeviceButtonPress(xtablet.Device, xtablet.PressEvent, ev);
+ if (ev)
+ xevents.push_back(ev);
+ ProximityIn(xtablet.Device, xtablet.ProxInEvent, ev);
+ if (ev)
+ xevents.push_back(ev);
+ ProximityOut(xtablet.Device, xtablet.ProxOutEvent, ev);
+ if (ev)
+ xevents.push_back(ev);
+ }
+
+ XSelectExtensionEvent(m_display, m_window, xevents.data(), (int)xevents.size());
+ }
}
#endif /* WITH_X11_XINPUT */
-Window
-GHOST_WindowX11::
-getXWindow()
+Window GHOST_WindowX11::getXWindow()
{
- return m_window;
+ return m_window;
}
-bool
-GHOST_WindowX11::
-getValid() const
+bool GHOST_WindowX11::getValid() const
{
- return GHOST_Window::getValid() && m_valid_setup;
+ return GHOST_Window::getValid() && m_valid_setup;
}
-void
-GHOST_WindowX11::
-setTitle(
- const STR_String& title)
+void GHOST_WindowX11::setTitle(const STR_String &title)
{
- Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
- Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
- XChangeProperty(m_display, m_window,
- name, utf8str, 8, PropModeReplace,
- (const unsigned char *) title.ReadPtr(),
- title.Length());
-
- /* This should convert to valid x11 string
- * and getTitle would need matching change */
- XStoreName(m_display, m_window, title);
-
- XFlush(m_display);
+ Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
+ Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
+ XChangeProperty(m_display,
+ m_window,
+ name,
+ utf8str,
+ 8,
+ PropModeReplace,
+ (const unsigned char *)title.ReadPtr(),
+ title.Length());
+
+ /* This should convert to valid x11 string
+ * and getTitle would need matching change */
+ XStoreName(m_display, m_window, title);
+
+ XFlush(m_display);
}
-void
-GHOST_WindowX11::
-getTitle(
- STR_String& title) const
+void GHOST_WindowX11::getTitle(STR_String &title) const
{
- char *name = NULL;
+ char *name = NULL;
- XFetchName(m_display, m_window, &name);
- title = name ? name : "untitled";
- XFree(name);
+ XFetchName(m_display, m_window, &name);
+ title = name ? name : "untitled";
+ XFree(name);
}
-void
-GHOST_WindowX11::
-getWindowBounds(
- GHOST_Rect& bounds) const
+void GHOST_WindowX11::getWindowBounds(GHOST_Rect &bounds) const
{
- /* Getting the window bounds under X11 is not
- * really supported (nor should it be desired). */
- getClientBounds(bounds);
+ /* Getting the window bounds under X11 is not
+ * really supported (nor should it be desired). */
+ getClientBounds(bounds);
}
-void
-GHOST_WindowX11::
-getClientBounds(
- GHOST_Rect& bounds) const
+void GHOST_WindowX11::getClientBounds(GHOST_Rect &bounds) const
{
- Window root_return;
- int x_return, y_return;
- unsigned int w_return, h_return, border_w_return, depth_return;
- GHOST_TInt32 screen_x, screen_y;
-
- XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
- &w_return, &h_return, &border_w_return, &depth_return);
-
- clientToScreen(0, 0, screen_x, screen_y);
-
- bounds.m_l = screen_x;
- bounds.m_r = bounds.m_l + w_return;
- bounds.m_t = screen_y;
- bounds.m_b = bounds.m_t + h_return;
-
+ Window root_return;
+ int x_return, y_return;
+ unsigned int w_return, h_return, border_w_return, depth_return;
+ GHOST_TInt32 screen_x, screen_y;
+
+ XGetGeometry(m_display,
+ m_window,
+ &root_return,
+ &x_return,
+ &y_return,
+ &w_return,
+ &h_return,
+ &border_w_return,
+ &depth_return);
+
+ clientToScreen(0, 0, screen_x, screen_y);
+
+ bounds.m_l = screen_x;
+ bounds.m_r = bounds.m_l + w_return;
+ bounds.m_t = screen_y;
+ bounds.m_b = bounds.m_t + h_return;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setClientWidth(
- GHOST_TUns32 width)
+GHOST_TSuccess GHOST_WindowX11::setClientWidth(GHOST_TUns32 width)
{
- XWindowChanges values;
- unsigned int value_mask = CWWidth;
- values.width = width;
- XConfigureWindow(m_display, m_window, value_mask, &values);
+ XWindowChanges values;
+ unsigned int value_mask = CWWidth;
+ values.width = width;
+ XConfigureWindow(m_display, m_window, value_mask, &values);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setClientHeight(
- GHOST_TUns32 height)
+GHOST_TSuccess GHOST_WindowX11::setClientHeight(GHOST_TUns32 height)
{
- XWindowChanges values;
- unsigned int value_mask = CWHeight;
- values.height = height;
- XConfigureWindow(m_display, m_window, value_mask, &values);
- return GHOST_kSuccess;
-
+ XWindowChanges values;
+ unsigned int value_mask = CWHeight;
+ values.height = height;
+ XConfigureWindow(m_display, m_window, value_mask, &values);
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setClientSize(
- GHOST_TUns32 width,
- GHOST_TUns32 height)
+GHOST_TSuccess GHOST_WindowX11::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
{
- XWindowChanges values;
- unsigned int value_mask = CWWidth | CWHeight;
- values.width = width;
- values.height = height;
- XConfigureWindow(m_display, m_window, value_mask, &values);
- return GHOST_kSuccess;
-
+ XWindowChanges values;
+ unsigned int value_mask = CWWidth | CWHeight;
+ values.width = width;
+ values.height = height;
+ XConfigureWindow(m_display, m_window, value_mask, &values);
+ return GHOST_kSuccess;
}
-void
-GHOST_WindowX11::
-screenToClient(
- GHOST_TInt32 inX,
- GHOST_TInt32 inY,
- GHOST_TInt32& outX,
- GHOST_TInt32& outY) const
+void GHOST_WindowX11::screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- /* This is correct! */
-
- int ax, ay;
- Window temp;
-
- XTranslateCoordinates(m_display,
- RootWindow(m_display, m_visualInfo->screen),
- m_window,
- inX, inY,
- &ax, &ay,
- &temp);
- outX = ax;
- outY = ay;
+ /* This is correct! */
+
+ int ax, ay;
+ Window temp;
+
+ XTranslateCoordinates(
+ m_display, RootWindow(m_display, m_visualInfo->screen), m_window, inX, inY, &ax, &ay, &temp);
+ outX = ax;
+ outY = ay;
}
-void
-GHOST_WindowX11::
-clientToScreen(
- GHOST_TInt32 inX,
- GHOST_TInt32 inY,
- GHOST_TInt32& outX,
- GHOST_TInt32& outY) const
+void GHOST_WindowX11::clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
{
- int ax, ay;
- Window temp;
-
- XTranslateCoordinates(
- m_display,
- m_window,
- RootWindow(m_display, m_visualInfo->screen),
- inX, inY,
- &ax, &ay,
- &temp);
- outX = ax;
- outY = ay;
+ int ax, ay;
+ Window temp;
+
+ XTranslateCoordinates(
+ m_display, m_window, RootWindow(m_display, m_visualInfo->screen), inX, inY, &ax, &ay, &temp);
+ outX = ax;
+ outY = ay;
}
void GHOST_WindowX11::icccmSetState(int state)
{
- XEvent xev;
-
- if (state != IconicState)
- return;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = m_display;
- xev.xclient.window = m_window;
- xev.xclient.format = 32;
- xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE;
- xev.xclient.data.l[0] = state;
- XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
- False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+ XEvent xev;
+
+ if (state != IconicState)
+ return;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = m_display;
+ xev.xclient.window = m_window;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE;
+ xev.xclient.data.l[0] = state;
+ XSendEvent(m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ False,
+ SubstructureNotifyMask | SubstructureRedirectMask,
+ &xev);
}
int GHOST_WindowX11::icccmGetState(void) const
{
- struct {
- CARD32 state;
- XID icon;
- } *prop_ret;
- unsigned long bytes_after, num_ret;
- Atom type_ret;
- int ret, format_ret;
- CARD32 st;
-
- prop_ret = NULL;
- ret = XGetWindowProperty(
- m_display, m_window, m_system->m_atom.WM_STATE, 0, 2,
- False, m_system->m_atom.WM_STATE, &type_ret,
- &format_ret, &num_ret, &bytes_after, ((unsigned char **)&prop_ret));
- if ((ret == Success) && (prop_ret != NULL) && (num_ret == 2)) {
- st = prop_ret->state;
- }
- else {
- st = NormalState;
- }
-
- if (prop_ret) {
- XFree(prop_ret);
- }
-
- return st;
+ struct {
+ CARD32 state;
+ XID icon;
+ } * prop_ret;
+ unsigned long bytes_after, num_ret;
+ Atom type_ret;
+ int ret, format_ret;
+ CARD32 st;
+
+ prop_ret = NULL;
+ ret = XGetWindowProperty(m_display,
+ m_window,
+ m_system->m_atom.WM_STATE,
+ 0,
+ 2,
+ False,
+ m_system->m_atom.WM_STATE,
+ &type_ret,
+ &format_ret,
+ &num_ret,
+ &bytes_after,
+ ((unsigned char **)&prop_ret));
+ if ((ret == Success) && (prop_ret != NULL) && (num_ret == 2)) {
+ st = prop_ret->state;
+ }
+ else {
+ st = NormalState;
+ }
+
+ if (prop_ret) {
+ XFree(prop_ret);
+ }
+
+ return st;
}
void GHOST_WindowX11::netwmMaximized(bool set)
{
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.window = m_window;
- xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
- xev.xclient.format = 32;
-
- if (set == True)
- xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
- else
- xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
-
- xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
- xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
- XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
- False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = m_window;
+ xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
+ xev.xclient.format = 32;
+
+ if (set == True)
+ xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
+ else
+ xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
+
+ xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
+ xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+ XSendEvent(m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
}
bool GHOST_WindowX11::netwmIsMaximized(void) const
{
- Atom *prop_ret;
- unsigned long bytes_after, num_ret, i;
- Atom type_ret;
- bool st;
- int format_ret, ret, count;
-
- prop_ret = NULL;
- st = False;
- ret = XGetWindowProperty(
- m_display, m_window, m_system->m_atom._NET_WM_STATE, 0, INT_MAX,
- False, XA_ATOM, &type_ret, &format_ret,
- &num_ret, &bytes_after, (unsigned char **)&prop_ret);
- if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
- count = 0;
- for (i = 0; i < num_ret; i++) {
- if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ) {
- count++;
- }
- if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT) {
- count++;
- }
- if (count == 2) {
- st = True;
- break;
- }
- }
- }
-
- if (prop_ret)
- XFree(prop_ret);
- return (st);
+ Atom *prop_ret;
+ unsigned long bytes_after, num_ret, i;
+ Atom type_ret;
+ bool st;
+ int format_ret, ret, count;
+
+ prop_ret = NULL;
+ st = False;
+ ret = XGetWindowProperty(m_display,
+ m_window,
+ m_system->m_atom._NET_WM_STATE,
+ 0,
+ INT_MAX,
+ False,
+ XA_ATOM,
+ &type_ret,
+ &format_ret,
+ &num_ret,
+ &bytes_after,
+ (unsigned char **)&prop_ret);
+ if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
+ count = 0;
+ for (i = 0; i < num_ret; i++) {
+ if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ) {
+ count++;
+ }
+ if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT) {
+ count++;
+ }
+ if (count == 2) {
+ st = True;
+ break;
+ }
+ }
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+ return (st);
}
void GHOST_WindowX11::netwmFullScreen(bool set)
{
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.window = m_window;
- xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
- xev.xclient.format = 32;
-
- if (set == True)
- xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
- else
- xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
-
- xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
- XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
- False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = m_window;
+ xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
+ xev.xclient.format = 32;
+
+ if (set == True)
+ xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
+ else
+ xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
+
+ xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+ XSendEvent(m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
}
bool GHOST_WindowX11::netwmIsFullScreen(void) const
{
- Atom *prop_ret;
- unsigned long bytes_after, num_ret, i;
- Atom type_ret;
- bool st;
- int format_ret, ret;
-
- prop_ret = NULL;
- st = False;
- ret = XGetWindowProperty(
- m_display, m_window, m_system->m_atom._NET_WM_STATE, 0, INT_MAX,
- False, XA_ATOM, &type_ret, &format_ret,
- &num_ret, &bytes_after, (unsigned char **)&prop_ret);
- if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
- for (i = 0; i < num_ret; i++) {
- if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) {
- st = True;
- break;
- }
- }
- }
-
- if (prop_ret)
- XFree(prop_ret);
- return (st);
+ Atom *prop_ret;
+ unsigned long bytes_after, num_ret, i;
+ Atom type_ret;
+ bool st;
+ int format_ret, ret;
+
+ prop_ret = NULL;
+ st = False;
+ ret = XGetWindowProperty(m_display,
+ m_window,
+ m_system->m_atom._NET_WM_STATE,
+ 0,
+ INT_MAX,
+ False,
+ XA_ATOM,
+ &type_ret,
+ &format_ret,
+ &num_ret,
+ &bytes_after,
+ (unsigned char **)&prop_ret);
+ if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
+ for (i = 0; i < num_ret; i++) {
+ if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) {
+ st = True;
+ break;
+ }
+ }
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+ return (st);
}
void GHOST_WindowX11::motifFullScreen(bool set)
{
- MotifWmHints hints;
-
- hints.flags = MWM_HINTS_DECORATIONS;
- if (set == True)
- hints.decorations = 0;
- else
- hints.decorations = 1;
-
- XChangeProperty(m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS,
- m_system->m_atom._MOTIF_WM_HINTS, 32, PropModeReplace,
- (unsigned char *) &hints, 4);
+ MotifWmHints hints;
+
+ hints.flags = MWM_HINTS_DECORATIONS;
+ if (set == True)
+ hints.decorations = 0;
+ else
+ hints.decorations = 1;
+
+ XChangeProperty(m_display,
+ m_window,
+ m_system->m_atom._MOTIF_WM_HINTS,
+ m_system->m_atom._MOTIF_WM_HINTS,
+ 32,
+ PropModeReplace,
+ (unsigned char *)&hints,
+ 4);
}
bool GHOST_WindowX11::motifIsFullScreen(void) const
{
- MotifWmHints *prop_ret;
- unsigned long bytes_after, num_ret;
- Atom type_ret;
- bool state;
- int format_ret, st;
-
- prop_ret = NULL;
- state = False;
- st = XGetWindowProperty(
- m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS, 0, INT_MAX,
- False, m_system->m_atom._MOTIF_WM_HINTS,
- &type_ret, &format_ret, &num_ret,
- &bytes_after, (unsigned char **)&prop_ret);
- if ((st == Success) && prop_ret) {
- if (prop_ret->flags & MWM_HINTS_DECORATIONS) {
- if (!prop_ret->decorations)
- state = True;
- }
- }
-
- if (prop_ret)
- XFree(prop_ret);
- return (state);
+ MotifWmHints *prop_ret;
+ unsigned long bytes_after, num_ret;
+ Atom type_ret;
+ bool state;
+ int format_ret, st;
+
+ prop_ret = NULL;
+ state = False;
+ st = XGetWindowProperty(m_display,
+ m_window,
+ m_system->m_atom._MOTIF_WM_HINTS,
+ 0,
+ INT_MAX,
+ False,
+ m_system->m_atom._MOTIF_WM_HINTS,
+ &type_ret,
+ &format_ret,
+ &num_ret,
+ &bytes_after,
+ (unsigned char **)&prop_ret);
+ if ((st == Success) && prop_ret) {
+ if (prop_ret->flags & MWM_HINTS_DECORATIONS) {
+ if (!prop_ret->decorations)
+ state = True;
+ }
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+ return (state);
}
GHOST_TWindowState GHOST_WindowX11::getState() const
{
- GHOST_TWindowState state_ret;
- int state;
-
- state_ret = GHOST_kWindowStateNormal;
- state = icccmGetState();
- /*
- * In the Iconic and Withdrawn state, the window
- * is unmaped, so only need return a Minimized state.
- */
- if ((state == IconicState) || (state == WithdrawnState))
- state_ret = GHOST_kWindowStateMinimized;
- else if (netwmIsFullScreen() == True)
- state_ret = GHOST_kWindowStateFullScreen;
- else if (motifIsFullScreen() == True)
- state_ret = GHOST_kWindowStateFullScreen;
- else if (netwmIsMaximized() == True)
- state_ret = GHOST_kWindowStateMaximized;
- return (state_ret);
+ GHOST_TWindowState state_ret;
+ int state;
+
+ state_ret = GHOST_kWindowStateNormal;
+ state = icccmGetState();
+ /*
+ * In the Iconic and Withdrawn state, the window
+ * is unmaped, so only need return a Minimized state.
+ */
+ if ((state == IconicState) || (state == WithdrawnState))
+ state_ret = GHOST_kWindowStateMinimized;
+ else if (netwmIsFullScreen() == True)
+ state_ret = GHOST_kWindowStateFullScreen;
+ else if (motifIsFullScreen() == True)
+ state_ret = GHOST_kWindowStateFullScreen;
+ else if (netwmIsMaximized() == True)
+ state_ret = GHOST_kWindowStateMaximized;
+ return (state_ret);
}
GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
{
- GHOST_TWindowState cur_state;
- bool is_max, is_full, is_motif_full;
-
- cur_state = getState();
- if (state == (int)cur_state)
- return GHOST_kSuccess;
-
- if (cur_state != GHOST_kWindowStateMinimized) {
- /*
- * The window don't have this property's
- * if it's not mapped.
- */
- is_max = netwmIsMaximized();
- is_full = netwmIsFullScreen();
- }
- else {
- is_max = False;
- is_full = False;
- }
-
- is_motif_full = motifIsFullScreen();
-
- if (state == GHOST_kWindowStateNormal)
- state = m_normal_state;
-
- if (state == GHOST_kWindowStateNormal) {
- if (is_max == True)
- netwmMaximized(False);
- if (is_full == True)
- netwmFullScreen(False);
- if (is_motif_full == True)
- motifFullScreen(False);
- icccmSetState(NormalState);
- return (GHOST_kSuccess);
- }
-
- if (state == GHOST_kWindowStateFullScreen) {
- /*
- * We can't change to full screen if the window
- * isn't mapped.
- */
- if (cur_state == GHOST_kWindowStateMinimized)
- return (GHOST_kFailure);
-
- m_normal_state = cur_state;
-
- if (is_max == True)
- netwmMaximized(False);
- if (is_full == False)
- netwmFullScreen(True);
- if (is_motif_full == False)
- motifFullScreen(True);
- return (GHOST_kSuccess);
- }
-
- if (state == GHOST_kWindowStateMaximized) {
- /*
- * We can't change to Maximized if the window
- * isn't mapped.
- */
- if (cur_state == GHOST_kWindowStateMinimized)
- return (GHOST_kFailure);
-
- if (is_full == True)
- netwmFullScreen(False);
- if (is_motif_full == True)
- motifFullScreen(False);
- if (is_max == False)
- netwmMaximized(True);
- return (GHOST_kSuccess);
- }
-
- if (state == GHOST_kWindowStateMinimized) {
- /*
- * The window manager need save the current state of
- * the window (maximized, full screen, etc).
- */
- icccmSetState(IconicState);
- return (GHOST_kSuccess);
- }
-
- return (GHOST_kFailure);
+ GHOST_TWindowState cur_state;
+ bool is_max, is_full, is_motif_full;
+
+ cur_state = getState();
+ if (state == (int)cur_state)
+ return GHOST_kSuccess;
+
+ if (cur_state != GHOST_kWindowStateMinimized) {
+ /*
+ * The window don't have this property's
+ * if it's not mapped.
+ */
+ is_max = netwmIsMaximized();
+ is_full = netwmIsFullScreen();
+ }
+ else {
+ is_max = False;
+ is_full = False;
+ }
+
+ is_motif_full = motifIsFullScreen();
+
+ if (state == GHOST_kWindowStateNormal)
+ state = m_normal_state;
+
+ if (state == GHOST_kWindowStateNormal) {
+ if (is_max == True)
+ netwmMaximized(False);
+ if (is_full == True)
+ netwmFullScreen(False);
+ if (is_motif_full == True)
+ motifFullScreen(False);
+ icccmSetState(NormalState);
+ return (GHOST_kSuccess);
+ }
+
+ if (state == GHOST_kWindowStateFullScreen) {
+ /*
+ * We can't change to full screen if the window
+ * isn't mapped.
+ */
+ if (cur_state == GHOST_kWindowStateMinimized)
+ return (GHOST_kFailure);
+
+ m_normal_state = cur_state;
+
+ if (is_max == True)
+ netwmMaximized(False);
+ if (is_full == False)
+ netwmFullScreen(True);
+ if (is_motif_full == False)
+ motifFullScreen(True);
+ return (GHOST_kSuccess);
+ }
+
+ if (state == GHOST_kWindowStateMaximized) {
+ /*
+ * We can't change to Maximized if the window
+ * isn't mapped.
+ */
+ if (cur_state == GHOST_kWindowStateMinimized)
+ return (GHOST_kFailure);
+
+ if (is_full == True)
+ netwmFullScreen(False);
+ if (is_motif_full == True)
+ motifFullScreen(False);
+ if (is_max == False)
+ netwmMaximized(True);
+ return (GHOST_kSuccess);
+ }
+
+ if (state == GHOST_kWindowStateMinimized) {
+ /*
+ * The window manager need save the current state of
+ * the window (maximized, full screen, etc).
+ */
+ icccmSetState(IconicState);
+ return (GHOST_kSuccess);
+ }
+
+ return (GHOST_kFailure);
}
#include <iostream>
-GHOST_TSuccess
-GHOST_WindowX11::
-setOrder(
- GHOST_TWindowOrder order)
+GHOST_TSuccess GHOST_WindowX11::setOrder(GHOST_TWindowOrder order)
{
- if (order == GHOST_kWindowOrderTop) {
- XWindowAttributes attr;
- Atom atom;
-
- /* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some
- * window managers ignore the former (e.g. kwin from kde) and others
- * don't implement the latter (e.g. fluxbox pre 0.9.9) */
-
- XRaiseWindow(m_display, m_window);
-
- atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True);
-
- if (atom != None) {
- Window root;
- XEvent xev;
- long eventmask;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.window = m_window;
- xev.xclient.message_type = atom;
-
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 1;
- xev.xclient.data.l[1] = CurrentTime;
- xev.xclient.data.l[2] = m_window;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
-
- root = RootWindow(m_display, m_visualInfo->screen);
- eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
-
- XSendEvent(m_display, root, False, eventmask, &xev);
- }
-
- XGetWindowAttributes(m_display, m_window, &attr);
-
- /* iconized windows give bad match error */
- if (attr.map_state == IsViewable)
- XSetInputFocus(m_display, m_window, RevertToPointerRoot,
- CurrentTime);
- XFlush(m_display);
- }
- else if (order == GHOST_kWindowOrderBottom) {
- XLowerWindow(m_display, m_window);
- XFlush(m_display);
- }
- else {
- return GHOST_kFailure;
- }
-
- return GHOST_kSuccess;
+ if (order == GHOST_kWindowOrderTop) {
+ XWindowAttributes attr;
+ Atom atom;
+
+ /* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some
+ * window managers ignore the former (e.g. kwin from kde) and others
+ * don't implement the latter (e.g. fluxbox pre 0.9.9) */
+
+ XRaiseWindow(m_display, m_window);
+
+ atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True);
+
+ if (atom != None) {
+ Window root;
+ XEvent xev;
+ long eventmask;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = m_window;
+ xev.xclient.message_type = atom;
+
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = CurrentTime;
+ xev.xclient.data.l[2] = m_window;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ root = RootWindow(m_display, m_visualInfo->screen);
+ eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
+
+ XSendEvent(m_display, root, False, eventmask, &xev);
+ }
+
+ XGetWindowAttributes(m_display, m_window, &attr);
+
+ /* iconized windows give bad match error */
+ if (attr.map_state == IsViewable)
+ XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime);
+ XFlush(m_display);
+ }
+ else if (order == GHOST_kWindowOrderBottom) {
+ XLowerWindow(m_display, m_window);
+ XFlush(m_display);
+ }
+ else {
+ return GHOST_kFailure;
+ }
+
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-invalidate()
+GHOST_TSuccess GHOST_WindowX11::invalidate()
{
- /* So the idea of this function is to generate an expose event
- * for the window.
- * Unfortunately X does not handle expose events for you and
- * it is the client's job to refresh the dirty part of the window.
- * We need to queue up invalidate calls and generate GHOST events
- * for them in the system.
- *
- * We implement this by setting a boolean in this class to concatenate
- * all such calls into a single event for this window.
- *
- * At the same time we queue the dirty windows in the system class
- * and generate events for them at the next processEvents call. */
-
- if (m_invalid_window == false) {
- m_system->addDirtyWindow(this);
- m_invalid_window = true;
- }
-
- return GHOST_kSuccess;
+ /* So the idea of this function is to generate an expose event
+ * for the window.
+ * Unfortunately X does not handle expose events for you and
+ * it is the client's job to refresh the dirty part of the window.
+ * We need to queue up invalidate calls and generate GHOST events
+ * for them in the system.
+ *
+ * We implement this by setting a boolean in this class to concatenate
+ * all such calls into a single event for this window.
+ *
+ * At the same time we queue the dirty windows in the system class
+ * and generate events for them at the next processEvents call. */
+
+ if (m_invalid_window == false) {
+ m_system->addDirtyWindow(this);
+ m_invalid_window = true;
+ }
+
+ return GHOST_kSuccess;
}
/**
@@ -1159,486 +1198,496 @@ invalidate()
* for the window have been pushed onto the GHOST queue
*/
-void
-GHOST_WindowX11::
-validate()
+void GHOST_WindowX11::validate()
{
- m_invalid_window = false;
+ m_invalid_window = false;
}
-
/**
* Destructor.
* Closes the window and disposes resources allocated.
*/
-GHOST_WindowX11::
-~GHOST_WindowX11()
+GHOST_WindowX11::~GHOST_WindowX11()
{
- std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
- for (; it != m_standard_cursors.end(); ++it) {
- XFreeCursor(m_display, it->second);
- }
-
- if (m_empty_cursor) {
- XFreeCursor(m_display, m_empty_cursor);
- }
- if (m_custom_cursor) {
- XFreeCursor(m_display, m_custom_cursor);
- }
-
- if (m_valid_setup) {
- static Atom Primary_atom, Clipboard_atom;
- Window p_owner, c_owner;
- /*Change the owner of the Atoms to None if we are the owner*/
- Primary_atom = XInternAtom(m_display, "PRIMARY", False);
- Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
-
-
- p_owner = XGetSelectionOwner(m_display, Primary_atom);
- c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
-
- if (p_owner == m_window) {
- XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
- }
- if (c_owner == m_window) {
- XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
- }
- }
-
- if (m_visualInfo) {
- XFree(m_visualInfo);
- }
+ std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
+ for (; it != m_standard_cursors.end(); ++it) {
+ XFreeCursor(m_display, it->second);
+ }
+
+ if (m_empty_cursor) {
+ XFreeCursor(m_display, m_empty_cursor);
+ }
+ if (m_custom_cursor) {
+ XFreeCursor(m_display, m_custom_cursor);
+ }
+
+ if (m_valid_setup) {
+ static Atom Primary_atom, Clipboard_atom;
+ Window p_owner, c_owner;
+ /*Change the owner of the Atoms to None if we are the owner*/
+ Primary_atom = XInternAtom(m_display, "PRIMARY", False);
+ Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
+
+ p_owner = XGetSelectionOwner(m_display, Primary_atom);
+ c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
+
+ if (p_owner == m_window) {
+ XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
+ }
+ if (c_owner == m_window) {
+ XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
+ }
+ }
+
+ if (m_visualInfo) {
+ XFree(m_visualInfo);
+ }
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- if (m_xic) {
- XDestroyIC(m_xic);
- }
+ if (m_xic) {
+ XDestroyIC(m_xic);
+ }
#endif
#ifdef WITH_XDND
- delete m_dropTarget;
+ delete m_dropTarget;
#endif
- releaseNativeHandles();
+ releaseNativeHandles();
- if (m_valid_setup) {
- XDestroyWindow(m_display, m_window);
- }
+ if (m_valid_setup) {
+ XDestroyWindow(m_display, m_window);
+ }
}
-
GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
{
- if (type == GHOST_kDrawingContextTypeOpenGL) {
-
- // During development:
- // try 4.x compatibility profile
- // try 3.3 compatibility profile
- // fall back to 3.0 if needed
- //
- // Final Blender 2.8:
- // try 4.x core profile
- // try 3.3 core profile
- // no fallbacks
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+
+ // During development:
+ // try 4.x compatibility profile
+ // try 3.3 compatibility profile
+ // fall back to 3.0 if needed
+ //
+ // Final Blender 2.8:
+ // try 4.x core profile
+ // try 3.3 core profile
+ // no fallbacks
#if defined(WITH_GL_PROFILE_CORE)
- {
- const char *version_major = (char*)glewGetString(GLEW_VERSION_MAJOR);
- if (version_major != NULL && version_major[0] == '1') {
- fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n");
- abort();
- }
- }
+ {
+ const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR);
+ if (version_major != NULL && version_major[0] == '1') {
+ fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n");
+ abort();
+ }
+ }
#endif
- const int profile_mask =
+ const int profile_mask =
#if defined(WITH_GL_PROFILE_CORE)
- GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
#elif defined(WITH_GL_PROFILE_COMPAT)
- GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
#else
-# error // must specify either core or compat at build time
+# error // must specify either core or compat at build time
#endif
- GHOST_Context *context;
-
- for (int minor = 5; minor >= 0; --minor) {
- context = new GHOST_ContextGLX(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_display,
- (GLXFBConfig)m_fbconfig,
- profile_mask,
- 4, minor,
- GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
- }
-
- context = new GHOST_ContextGLX(
- m_wantStereoVisual,
- m_wantNumOfAASamples,
- m_window,
- m_display,
- (GLXFBConfig)m_fbconfig,
- profile_mask,
- 3, 3,
- GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
- GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
-
- if (context->initializeDrawingContext())
- return context;
- else
- delete context;
-
- /* Ugly, but we get crashes unless a whole bunch of systems are patched. */
- fprintf(stderr, "Error! Unsupported graphics card or driver.\n");
- fprintf(stderr, "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n");
- fprintf(stderr, "The program will now close.\n");
- fflush(stderr);
- exit(1);
- }
-
- return NULL;
+ GHOST_Context *context;
+
+ for (int minor = 5; minor >= 0; --minor) {
+ context = new GHOST_ContextGLX(m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ (GLXFBConfig)m_fbconfig,
+ profile_mask,
+ 4,
+ minor,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS |
+ (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+ }
+
+ context = new GHOST_ContextGLX(m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ (GLXFBConfig)m_fbconfig,
+ profile_mask,
+ 3,
+ 3,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS |
+ (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+
+ /* Ugly, but we get crashes unless a whole bunch of systems are patched. */
+ fprintf(stderr, "Error! Unsupported graphics card or driver.\n");
+ fprintf(stderr,
+ "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n");
+ fprintf(stderr, "The program will now close.\n");
+ fflush(stderr);
+ exit(1);
+ }
+
+ return NULL;
}
-
-Cursor
-GHOST_WindowX11::
-getStandardCursor(
- GHOST_TStandardCursor g_cursor)
+Cursor GHOST_WindowX11::getStandardCursor(GHOST_TStandardCursor g_cursor)
{
- unsigned int xcursor_id;
-
-#define GtoX(gcurs, xcurs) case gcurs: xcursor_id = xcurs
- switch (g_cursor) {
- GtoX(GHOST_kStandardCursorRightArrow, XC_arrow); break;
- GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow); break;
- GtoX(GHOST_kStandardCursorInfo, XC_hand1); break;
- GtoX(GHOST_kStandardCursorDestroy, XC_pirate); break;
- GtoX(GHOST_kStandardCursorHelp, XC_question_arrow); break;
- GtoX(GHOST_kStandardCursorCycle, XC_exchange); break;
- GtoX(GHOST_kStandardCursorSpray, XC_spraycan); break;
- GtoX(GHOST_kStandardCursorWait, XC_watch); break;
- GtoX(GHOST_kStandardCursorText, XC_xterm); break;
- GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair); break;
- GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow); break;
- GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow); break;
- GtoX(GHOST_kStandardCursorTopSide, XC_top_side); break;
- GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side); break;
- GtoX(GHOST_kStandardCursorLeftSide, XC_left_side); break;
- GtoX(GHOST_kStandardCursorRightSide, XC_right_side); break;
- GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner); break;
- GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner); break;
- GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner); break;
- GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner); break;
- GtoX(GHOST_kStandardCursorPencil, XC_pencil); break;
- GtoX(GHOST_kStandardCursorCopy, XC_arrow); break;
- default:
- xcursor_id = 0;
- }
+ unsigned int xcursor_id;
+
+#define GtoX(gcurs, xcurs) \
+ case gcurs: \
+ xcursor_id = xcurs
+ switch (g_cursor) {
+ GtoX(GHOST_kStandardCursorRightArrow, XC_arrow);
+ break;
+ GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow);
+ break;
+ GtoX(GHOST_kStandardCursorInfo, XC_hand1);
+ break;
+ GtoX(GHOST_kStandardCursorDestroy, XC_pirate);
+ break;
+ GtoX(GHOST_kStandardCursorHelp, XC_question_arrow);
+ break;
+ GtoX(GHOST_kStandardCursorCycle, XC_exchange);
+ break;
+ GtoX(GHOST_kStandardCursorSpray, XC_spraycan);
+ break;
+ GtoX(GHOST_kStandardCursorWait, XC_watch);
+ break;
+ GtoX(GHOST_kStandardCursorText, XC_xterm);
+ break;
+ GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair);
+ break;
+ GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow);
+ break;
+ GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow);
+ break;
+ GtoX(GHOST_kStandardCursorTopSide, XC_top_side);
+ break;
+ GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side);
+ break;
+ GtoX(GHOST_kStandardCursorLeftSide, XC_left_side);
+ break;
+ GtoX(GHOST_kStandardCursorRightSide, XC_right_side);
+ break;
+ GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner);
+ break;
+ GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner);
+ break;
+ GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner);
+ break;
+ GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner);
+ break;
+ GtoX(GHOST_kStandardCursorPencil, XC_pencil);
+ break;
+ GtoX(GHOST_kStandardCursorCopy, XC_arrow);
+ break;
+ default:
+ xcursor_id = 0;
+ }
#undef GtoX
- if (xcursor_id) {
- Cursor xcursor = m_standard_cursors[xcursor_id];
+ if (xcursor_id) {
+ Cursor xcursor = m_standard_cursors[xcursor_id];
- if (!xcursor) {
- xcursor = XCreateFontCursor(m_display, xcursor_id);
+ if (!xcursor) {
+ xcursor = XCreateFontCursor(m_display, xcursor_id);
- m_standard_cursors[xcursor_id] = xcursor;
- }
+ m_standard_cursors[xcursor_id] = xcursor;
+ }
- return xcursor;
- }
- else {
- return None;
- }
+ return xcursor;
+ }
+ else {
+ return None;
+ }
}
-Cursor
-GHOST_WindowX11::
-getEmptyCursor(
- ) {
- if (!m_empty_cursor) {
- Pixmap blank;
- XColor dummy = {0};
- char data[1] = {0};
-
- /* make a blank cursor */
- blank = XCreateBitmapFromData(
- m_display,
- RootWindow(m_display, m_visualInfo->screen),
- data, 1, 1
- );
-
- m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0);
- XFreePixmap(m_display, blank);
- }
-
- return m_empty_cursor;
+Cursor GHOST_WindowX11::getEmptyCursor()
+{
+ if (!m_empty_cursor) {
+ Pixmap blank;
+ XColor dummy = {0};
+ char data[1] = {0};
+
+ /* make a blank cursor */
+ blank = XCreateBitmapFromData(
+ m_display, RootWindow(m_display, m_visualInfo->screen), data, 1, 1);
+
+ m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0);
+ XFreePixmap(m_display, blank);
+ }
+
+ return m_empty_cursor;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setWindowCursorVisibility(
- bool visible)
+GHOST_TSuccess GHOST_WindowX11::setWindowCursorVisibility(bool visible)
{
- Cursor xcursor;
-
- if (visible) {
- if (m_visible_cursor)
- xcursor = m_visible_cursor;
- else
- xcursor = getStandardCursor(getCursorShape() );
- }
- else {
- xcursor = getEmptyCursor();
- }
-
- XDefineCursor(m_display, m_window, xcursor);
- XFlush(m_display);
-
- return GHOST_kSuccess;
+ Cursor xcursor;
+
+ if (visible) {
+ if (m_visible_cursor)
+ xcursor = m_visible_cursor;
+ else
+ xcursor = getStandardCursor(getCursorShape());
+ }
+ else {
+ xcursor = getEmptyCursor();
+ }
+
+ XDefineCursor(m_display, m_window, xcursor);
+ XFlush(m_display);
+
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setWindowCursorGrab(
- GHOST_TGrabCursorMode mode)
+GHOST_TSuccess GHOST_WindowX11::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
{
- if (mode != GHOST_kGrabDisable) {
- if (mode != GHOST_kGrabNormal) {
- m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
- setCursorGrabAccum(0, 0);
-
- if (mode == GHOST_kGrabHide)
- setWindowCursorVisibility(false);
-
- }
+ if (mode != GHOST_kGrabDisable) {
+ if (mode != GHOST_kGrabNormal) {
+ m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ setCursorGrabAccum(0, 0);
+
+ if (mode == GHOST_kGrabHide)
+ setWindowCursorVisibility(false);
+ }
#ifdef GHOST_X11_GRAB
- XGrabPointer(m_display, m_window, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
+ XGrabPointer(m_display,
+ m_window,
+ False,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ None,
+ None,
+ CurrentTime);
#endif
- }
- else {
- if (m_cursorGrab == GHOST_kGrabHide) {
- m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
- }
+ }
+ else {
+ if (m_cursorGrab == GHOST_kGrabHide) {
+ m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ }
- if (m_cursorGrab != GHOST_kGrabNormal) {
- /* use to generate a mouse move event, otherwise the last event
- * blender gets can be outside the screen causing menus not to show
- * properly unless the user moves the mouse */
+ if (m_cursorGrab != GHOST_kGrabNormal) {
+ /* use to generate a mouse move event, otherwise the last event
+ * blender gets can be outside the screen causing menus not to show
+ * properly unless the user moves the mouse */
#if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
- if ((m_system->m_xinput_version.present) &&
- (m_system->m_xinput_version.major_version >= 2))
- {
- int device_id;
- if (XIGetClientPointer(m_display, None, &device_id) != False) {
- XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, 0, 0);
- }
- }
- else
+ if ((m_system->m_xinput_version.present) &&
+ (m_system->m_xinput_version.major_version >= 2)) {
+ int device_id;
+ if (XIGetClientPointer(m_display, None, &device_id) != False) {
+ XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, 0, 0);
+ }
+ }
+ else
#endif
- {
- XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0);
- }
- }
-
- /* Perform this last so to workaround XWayland bug, see: T53004. */
- if (m_cursorGrab == GHOST_kGrabHide) {
- setWindowCursorVisibility(true);
- }
-
- /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
- setCursorGrabAccum(0, 0);
- m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
+ {
+ XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0);
+ }
+ }
+
+ /* Perform this last so to workaround XWayland bug, see: T53004. */
+ if (m_cursorGrab == GHOST_kGrabHide) {
+ setWindowCursorVisibility(true);
+ }
+
+ /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
+ setCursorGrabAccum(0, 0);
+ m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
#ifdef GHOST_X11_GRAB
- XUngrabPointer(m_display, CurrentTime);
+ XUngrabPointer(m_display, CurrentTime);
#endif
- }
+ }
- XFlush(m_display);
+ XFlush(m_display);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setWindowCursorShape(
- GHOST_TStandardCursor shape)
+GHOST_TSuccess GHOST_WindowX11::setWindowCursorShape(GHOST_TStandardCursor shape)
{
- Cursor xcursor = getStandardCursor(shape);
+ Cursor xcursor = getStandardCursor(shape);
- m_visible_cursor = xcursor;
+ m_visible_cursor = xcursor;
- XDefineCursor(m_display, m_window, xcursor);
- XFlush(m_display);
+ XDefineCursor(m_display, m_window, xcursor);
+ XFlush(m_display);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setWindowCustomCursorShape(
- GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX,
- int hotY)
+GHOST_TSuccess GHOST_WindowX11::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY)
{
- setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask,
- 16, 16, hotX, hotY, 0, 1);
- return GHOST_kSuccess;
+ setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotX, hotY, 0, 1);
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-setWindowCustomCursorShape(
- GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex,
- int sizey,
- int hotX,
- int hotY,
- int /*fg_color*/,
- int /*bg_color*/)
+GHOST_TSuccess GHOST_WindowX11::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int /*fg_color*/,
+ int /*bg_color*/)
{
- Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen);
- Pixmap bitmap_pix, mask_pix;
- XColor fg, bg;
+ Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen);
+ Pixmap bitmap_pix, mask_pix;
+ XColor fg, bg;
- if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure;
- if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure;
+ if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0)
+ return GHOST_kFailure;
+ if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0)
+ return GHOST_kFailure;
- if (m_custom_cursor) {
- XFreeCursor(m_display, m_custom_cursor);
- }
+ if (m_custom_cursor) {
+ XFreeCursor(m_display, m_custom_cursor);
+ }
- bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *) bitmap, sizex, sizey);
- mask_pix = XCreateBitmapFromData(m_display, m_window, (char *) mask, sizex, sizey);
+ bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *)bitmap, sizex, sizey);
+ mask_pix = XCreateBitmapFromData(m_display, m_window, (char *)mask, sizex, sizey);
- m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
- XDefineCursor(m_display, m_window, m_custom_cursor);
- XFlush(m_display);
+ m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
+ XDefineCursor(m_display, m_window, m_custom_cursor);
+ XFlush(m_display);
- m_visible_cursor = m_custom_cursor;
+ m_visible_cursor = m_custom_cursor;
- XFreePixmap(m_display, bitmap_pix);
- XFreePixmap(m_display, mask_pix);
+ XFreePixmap(m_display, bitmap_pix);
+ XFreePixmap(m_display, mask_pix);
- XFreeColors(m_display, colormap, &fg.pixel, 1, 0L);
- XFreeColors(m_display, colormap, &bg.pixel, 1, 0L);
+ XFreeColors(m_display, colormap, &fg.pixel, 1, 0L);
+ XFreeColors(m_display, colormap, &bg.pixel, 1, 0L);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-
-GHOST_TSuccess
-GHOST_WindowX11::
-beginFullScreen() const
+GHOST_TSuccess GHOST_WindowX11::beginFullScreen() const
{
- {
- Window root_return;
- int x_return, y_return;
- unsigned int w_return, h_return, border_w_return, depth_return;
-
- XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
- &w_return, &h_return, &border_w_return, &depth_return);
-
- m_system->setCursorPosition(w_return / 2, h_return / 2);
- }
-
-
- /* Grab Keyboard & Mouse */
- int err;
-
- err = XGrabKeyboard(m_display, m_window, False,
- GrabModeAsync, GrabModeAsync, CurrentTime);
- if (err != GrabSuccess) printf("XGrabKeyboard failed %d\n", err);
-
- err = XGrabPointer(m_display, m_window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
- GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
- if (err != GrabSuccess) printf("XGrabPointer failed %d\n", err);
-
- return GHOST_kSuccess;
+ {
+ Window root_return;
+ int x_return, y_return;
+ unsigned int w_return, h_return, border_w_return, depth_return;
+
+ XGetGeometry(m_display,
+ m_window,
+ &root_return,
+ &x_return,
+ &y_return,
+ &w_return,
+ &h_return,
+ &border_w_return,
+ &depth_return);
+
+ m_system->setCursorPosition(w_return / 2, h_return / 2);
+ }
+
+ /* Grab Keyboard & Mouse */
+ int err;
+
+ err = XGrabKeyboard(m_display, m_window, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ if (err != GrabSuccess)
+ printf("XGrabKeyboard failed %d\n", err);
+
+ err = XGrabPointer(m_display,
+ m_window,
+ False,
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ m_window,
+ None,
+ CurrentTime);
+ if (err != GrabSuccess)
+ printf("XGrabPointer failed %d\n", err);
+
+ return GHOST_kSuccess;
}
-GHOST_TSuccess
-GHOST_WindowX11::
-endFullScreen() const
+GHOST_TSuccess GHOST_WindowX11::endFullScreen() const
{
- XUngrabKeyboard(m_display, CurrentTime);
- XUngrabPointer(m_display, CurrentTime);
+ XUngrabKeyboard(m_display, CurrentTime);
+ XUngrabPointer(m_display, CurrentTime);
- return GHOST_kSuccess;
+ return GHOST_kSuccess;
}
-GHOST_TUns16
-GHOST_WindowX11::
-getDPIHint()
+GHOST_TUns16 GHOST_WindowX11::getDPIHint()
{
- /* Try to read DPI setting set using xrdb */
- char* resMan = XResourceManagerString(m_display);
- if (resMan) {
- XrmDatabase xrdb = XrmGetStringDatabase(resMan);
- if (xrdb) {
- char* type = NULL;
- XrmValue val;
-
- int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val);
- if (success && type) {
- if (strcmp(type, "String") == 0) {
- return atoi((char*)val.addr);
- }
- }
- }
- XrmDestroyDatabase(xrdb);
- }
-
- /* Fallback to calculating DPI using X reported DPI, set using xrandr --dpi */
- XWindowAttributes attr;
- if (!XGetWindowAttributes(m_display, m_window, &attr)) {
- /* Failed to get window attributes, return X11 default DPI */
- return 96;
- }
-
- Screen* screen = attr.screen;
- int pixelWidth = WidthOfScreen(screen);
- int pixelHeight = HeightOfScreen(screen);
- int mmWidth = WidthMMOfScreen(screen);
- int mmHeight = HeightMMOfScreen(screen);
-
- double pixelDiagonal = sqrt((pixelWidth * pixelWidth) + (pixelHeight * pixelHeight));
- double mmDiagonal = sqrt((mmWidth * mmWidth) + (mmHeight * mmHeight));
- float inchDiagonal = mmDiagonal * 0.039f;
- int dpi = pixelDiagonal / inchDiagonal;
- return dpi;
+ /* Try to read DPI setting set using xrdb */
+ char *resMan = XResourceManagerString(m_display);
+ if (resMan) {
+ XrmDatabase xrdb = XrmGetStringDatabase(resMan);
+ if (xrdb) {
+ char *type = NULL;
+ XrmValue val;
+
+ int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val);
+ if (success && type) {
+ if (strcmp(type, "String") == 0) {
+ return atoi((char *)val.addr);
+ }
+ }
+ }
+ XrmDestroyDatabase(xrdb);
+ }
+
+ /* Fallback to calculating DPI using X reported DPI, set using xrandr --dpi */
+ XWindowAttributes attr;
+ if (!XGetWindowAttributes(m_display, m_window, &attr)) {
+ /* Failed to get window attributes, return X11 default DPI */
+ return 96;
+ }
+
+ Screen *screen = attr.screen;
+ int pixelWidth = WidthOfScreen(screen);
+ int pixelHeight = HeightOfScreen(screen);
+ int mmWidth = WidthMMOfScreen(screen);
+ int mmHeight = HeightMMOfScreen(screen);
+
+ double pixelDiagonal = sqrt((pixelWidth * pixelWidth) + (pixelHeight * pixelHeight));
+ double mmDiagonal = sqrt((mmWidth * mmWidth) + (mmHeight * mmHeight));
+ float inchDiagonal = mmDiagonal * 0.039f;
+ int dpi = pixelDiagonal / inchDiagonal;
+ return dpi;
}
GHOST_TSuccess GHOST_WindowX11::setProgressBar(float progress)
{
- if (m_taskbar.is_valid()) {
- m_taskbar.set_progress(progress);
- m_taskbar.set_progress_enabled(true);
- return GHOST_kSuccess;
- }
+ if (m_taskbar.is_valid()) {
+ m_taskbar.set_progress(progress);
+ m_taskbar.set_progress_enabled(true);
+ return GHOST_kSuccess;
+ }
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
GHOST_TSuccess GHOST_WindowX11::endProgressBar()
{
- if (m_taskbar.is_valid()) {
- m_taskbar.set_progress_enabled(false);
- return GHOST_kSuccess;
- }
+ if (m_taskbar.is_valid()) {
+ m_taskbar.set_progress_enabled(false);
+ return GHOST_kSuccess;
+ }
- return GHOST_kFailure;
+ return GHOST_kFailure;
}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 29f4f212e1e..8378a8b5ef8 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -49,327 +49,258 @@ class GHOST_DropTargetX11;
* Dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
*/
-class GHOST_WindowX11 : public GHOST_Window
-{
-public:
- /**
- * Constructor.
- * Creates a new window and opens it.
- * To check if the window was created properly, use the getValid() method.
- * \param title The text shown in the title bar of the window.
- * \param left The coordinate of the left edge of the window.
- * \param top The coordinate of the top edge of the window.
- * \param width The width the window.
- * \param height The height the window.
- * \param state The state the window is initially opened with.
- * \param parentWindow Parent (embedder) window
- * \param type The type of drawing context installed in this window.
- * \param stereoVisual Stereo visual for quad buffered stereo.
- * \param alphaBackground Enable alpha blending of window with display background
- * \param numOfAASamples Number of samples used for AA (zero if no AA)
- */
- GHOST_WindowX11(
- GHOST_SystemX11 *system,
- Display *display,
- const STR_String& title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- const GHOST_TEmbedderWindowID parentWindow,
- GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
- const bool stereoVisual = false,
- const bool exclusive = false,
- const bool alphaBackground = false,
- const GHOST_TUns16 numOfAASamples = 0,
- const bool is_debug = false
- );
-
- bool
- getValid(
- ) const;
-
- void
- setTitle(const STR_String& title);
-
- void
- getTitle(
- STR_String& title
- ) const;
-
- void
- getWindowBounds(
- GHOST_Rect& bounds
- ) const;
-
- void
- getClientBounds(
- GHOST_Rect& bounds
- ) const;
-
- GHOST_TSuccess
- setClientWidth(
- GHOST_TUns32 width
- );
-
- GHOST_TSuccess
- setClientHeight(
- GHOST_TUns32 height
- );
-
- GHOST_TSuccess
- setClientSize(
- GHOST_TUns32 width,
- GHOST_TUns32 height
- );
-
- void
- screenToClient(
- GHOST_TInt32 inX,
- GHOST_TInt32 inY,
- GHOST_TInt32& outX,
- GHOST_TInt32& outY
- ) const;
-
- void
- clientToScreen(
- GHOST_TInt32 inX,
- GHOST_TInt32 inY,
- GHOST_TInt32& outX,
- GHOST_TInt32& outY
- ) const;
-
- GHOST_TWindowState
- getState(
- ) const;
-
- GHOST_TSuccess
- setState(
- GHOST_TWindowState state
- );
-
- GHOST_TSuccess
- setOrder(
- GHOST_TWindowOrder order
- );
-
- GHOST_TSuccess
- invalidate(
- );
-
- GHOST_TSuccess setProgressBar(float progress);
- GHOST_TSuccess endProgressBar();
-
- /**
- * Destructor.
- * Closes the window and disposes resources allocated.
- */
- ~GHOST_WindowX11();
-
- /**
- * \section x11specific X11 system specific calls
- */
-
- /**
- * The reverse of invalidate! Tells this window
- * that all events for it have been pushed into
- * the GHOST event queue.
- */
-
- void
- validate(
- );
-
- /**
- * Return a handle to the x11 window type.
- */
- Window
- getXWindow(
- );
+class GHOST_WindowX11 : public GHOST_Window {
+ public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * \param title The text shown in the title bar of the window.
+ * \param left The coordinate of the left edge of the window.
+ * \param top The coordinate of the top edge of the window.
+ * \param width The width the window.
+ * \param height The height the window.
+ * \param state The state the window is initially opened with.
+ * \param parentWindow Parent (embedder) window
+ * \param type The type of drawing context installed in this window.
+ * \param stereoVisual Stereo visual for quad buffered stereo.
+ * \param alphaBackground Enable alpha blending of window with display background
+ * \param numOfAASamples Number of samples used for AA (zero if no AA)
+ */
+ GHOST_WindowX11(GHOST_SystemX11 *system,
+ Display *display,
+ const STR_String &title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const GHOST_TEmbedderWindowID parentWindow,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false,
+ const bool exclusive = false,
+ const bool alphaBackground = false,
+ const GHOST_TUns16 numOfAASamples = 0,
+ const bool is_debug = false);
+
+ bool getValid() const;
+
+ void setTitle(const STR_String &title);
+
+ void getTitle(STR_String &title) const;
+
+ void getWindowBounds(GHOST_Rect &bounds) const;
+
+ void getClientBounds(GHOST_Rect &bounds) const;
+
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+
+ void screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ void clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const;
+
+ GHOST_TWindowState getState() const;
+
+ GHOST_TSuccess setState(GHOST_TWindowState state);
+
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+
+ GHOST_TSuccess invalidate();
+
+ GHOST_TSuccess setProgressBar(float progress);
+ GHOST_TSuccess endProgressBar();
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ ~GHOST_WindowX11();
+
+ /**
+ * \section x11specific X11 system specific calls
+ */
+
+ /**
+ * The reverse of invalidate! Tells this window
+ * that all events for it have been pushed into
+ * the GHOST event queue.
+ */
+
+ void validate();
+
+ /**
+ * Return a handle to the x11 window type.
+ */
+ Window getXWindow();
#ifdef WITH_X11_XINPUT
- GHOST_TabletData *GetTabletData()
- {
- return &m_tabletData;
- }
-#else // WITH_X11_XINPUT
- const GHOST_TabletData *GetTabletData()
- {
- return NULL;
- }
-#endif // WITH_X11_XINPUT
+ GHOST_TabletData *GetTabletData()
+ {
+ return &m_tabletData;
+ }
+#else // WITH_X11_XINPUT
+ const GHOST_TabletData *GetTabletData()
+ {
+ return NULL;
+ }
+#endif // WITH_X11_XINPUT
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- XIC getX11_XIC() {
- return m_xic;
- }
+ XIC getX11_XIC()
+ {
+ return m_xic;
+ }
- bool createX11_XIC();
+ bool createX11_XIC();
#endif
#ifdef WITH_X11_XINPUT
- void refreshXInputDevices();
+ void refreshXInputDevices();
#endif
#ifdef WITH_XDND
- GHOST_DropTargetX11 *getDropTarget()
- {
- return m_dropTarget;
- }
+ GHOST_DropTargetX11 *getDropTarget()
+ {
+ return m_dropTarget;
+ }
#endif
- /*
- * Need this in case that we want start the window
- * in FullScree or Maximized state.
- * Check GHOST_WindowX11.cpp
- */
- bool m_post_init;
- GHOST_TWindowState m_post_state;
-
- GHOST_TSuccess beginFullScreen() const;
-
- GHOST_TSuccess endFullScreen() const;
-
- GHOST_TUns16 getDPIHint();
-
-protected:
- /**
- * \param type The type of rendering context create.
- * \return Indication of success.
- */
- GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
-
- /**
- * Sets the cursor visibility on the window using
- * native window system calls.
- */
- GHOST_TSuccess
- setWindowCursorVisibility(
- bool visible
- );
-
- /**
- * Sets the cursor grab on the window using
- * native window system calls.
- */
- GHOST_TSuccess
- setWindowCursorGrab(
- GHOST_TGrabCursorMode mode
- );
-
- GHOST_TGrabCursorMode
- getWindowCursorGrab() const;
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- GHOST_TSuccess
- setWindowCursorShape(
- GHOST_TStandardCursor shape
- );
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls.
- */
- GHOST_TSuccess
- setWindowCustomCursorShape(
- GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX,
- int hotY
- );
-
- /**
- * Sets the cursor shape on the window using
- * native window system calls (Arbitrary size/color).
- */
- GHOST_TSuccess
- setWindowCustomCursorShape(
- GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex,
- int sizey,
- int hotX,
- int hotY,
- int fg_color,
- int bg_color
- );
-
-private:
-
- /// Force use of public constructor.
-
- GHOST_WindowX11(
- );
-
- GHOST_WindowX11(
- const GHOST_WindowX11 &
- );
-
- Cursor
- getStandardCursor(
- GHOST_TStandardCursor g_cursor
- );
-
- Cursor
- getEmptyCursor(
- );
-
- Window m_window;
- Display *m_display;
- XVisualInfo *m_visualInfo;
- void *m_fbconfig;
-
- GHOST_TWindowState m_normal_state;
-
- /** A pointer to the typed system class. */
- GHOST_SystemX11 *m_system;
-
- /** Used to concatenate calls to invalidate() on this window. */
- bool m_invalid_window;
-
- /** XCursor structure of an empty (blank) cursor */
- Cursor m_empty_cursor;
-
- /** XCursor structure of the custom cursor */
- Cursor m_custom_cursor;
-
- /** XCursor to show when cursor is visible */
- Cursor m_visible_cursor;
-
- /** Cache of XC_* ID's to XCursor structures */
- std::map<unsigned int, Cursor> m_standard_cursors;
-
- GHOST_TaskBarX11 m_taskbar;
+ /*
+ * Need this in case that we want start the window
+ * in FullScree or Maximized state.
+ * Check GHOST_WindowX11.cpp
+ */
+ bool m_post_init;
+ GHOST_TWindowState m_post_state;
+
+ GHOST_TSuccess beginFullScreen() const;
+
+ GHOST_TSuccess endFullScreen() const;
+
+ GHOST_TUns16 getDPIHint();
+
+ protected:
+ /**
+ * \param type The type of rendering context create.
+ * \return Indication of success.
+ */
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorVisibility(bool visible);
+
+ /**
+ * Sets the cursor grab on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
+
+ GHOST_TGrabCursorMode getWindowCursorGrab() const;
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls (Arbitrary size/color).
+ */
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ int fg_color,
+ int bg_color);
+
+ private:
+ /// Force use of public constructor.
+
+ GHOST_WindowX11();
+
+ GHOST_WindowX11(const GHOST_WindowX11 &);
+
+ Cursor getStandardCursor(GHOST_TStandardCursor g_cursor);
+
+ Cursor getEmptyCursor();
+
+ Window m_window;
+ Display *m_display;
+ XVisualInfo *m_visualInfo;
+ void *m_fbconfig;
+
+ GHOST_TWindowState m_normal_state;
+
+ /** A pointer to the typed system class. */
+ GHOST_SystemX11 *m_system;
+
+ /** Used to concatenate calls to invalidate() on this window. */
+ bool m_invalid_window;
+
+ /** XCursor structure of an empty (blank) cursor */
+ Cursor m_empty_cursor;
+
+ /** XCursor structure of the custom cursor */
+ Cursor m_custom_cursor;
+
+ /** XCursor to show when cursor is visible */
+ Cursor m_visible_cursor;
+
+ /** Cache of XC_* ID's to XCursor structures */
+ std::map<unsigned int, Cursor> m_standard_cursors;
+
+ GHOST_TaskBarX11 m_taskbar;
#ifdef WITH_XDND
- GHOST_DropTargetX11 *m_dropTarget;
+ GHOST_DropTargetX11 *m_dropTarget;
#endif
#ifdef WITH_X11_XINPUT
- GHOST_TabletData m_tabletData;
+ GHOST_TabletData m_tabletData;
#endif
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- XIC m_xic;
+ XIC m_xic;
#endif
- bool m_valid_setup;
- bool m_is_debug_context;
+ bool m_valid_setup;
+ bool m_is_debug_context;
- void icccmSetState(int state);
- int icccmGetState() const;
+ void icccmSetState(int state);
+ int icccmGetState() const;
- void netwmMaximized(bool set);
- bool netwmIsMaximized() const;
+ void netwmMaximized(bool set);
+ bool netwmIsMaximized() const;
- void netwmFullScreen(bool set);
- bool netwmIsFullScreen() const;
+ void netwmFullScreen(bool set);
+ bool netwmIsFullScreen() const;
- void motifFullScreen(bool set);
- bool motifIsFullScreen() const;
+ void motifFullScreen(bool set);
+ bool motifIsFullScreen() const;
};
-#endif // __GHOST_WINDOWX11_H__
+#endif // __GHOST_WINDOWX11_H__
diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt
index 9f714ae4fba..a5a41209603 100644
--- a/intern/ghost/test/CMakeLists.txt
+++ b/intern/ghost/test/CMakeLists.txt
@@ -14,43 +14,43 @@ set(WITH_GUARDEDALLOC ON)
# stub macro, does nothing
macro(blender_add_lib
- name
- sources
- includes
- includes_sys
- )
+ name
+ sources
+ includes
+ includes_sys
+ )
endmacro()
# suffix relative paths so we can use external cmake files
macro(suffix_relpaths
- new_files files prefix)
-
- set(${new_files})
- foreach(_file ${files})
- if(IS_ABSOLUTE _file)
- list(APPEND ${new_files} ${_file})
- else()
- list(APPEND ${new_files} "${prefix}${_file}")
- endif()
- endforeach()
- unset(_file)
+ new_files files prefix)
+
+ set(${new_files})
+ foreach(_file ${files})
+ if(IS_ABSOLUTE _file)
+ list(APPEND ${new_files} ${_file})
+ else()
+ list(APPEND ${new_files} "${prefix}${_file}")
+ endif()
+ endforeach()
+ unset(_file)
endmacro()
macro(data_to_c
file_from file_to
list_to_add)
- list(APPEND ${list_to_add} ${file_to})
+ list(APPEND ${list_to_add} ${file_to})
- get_filename_component(_file_to_path ${file_to} PATH)
+ get_filename_component(_file_to_path ${file_to} PATH)
- add_custom_command(
- OUTPUT ${file_to}
- COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
- COMMAND ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/datatoc ${file_from} ${file_to}
- DEPENDS ${file_from} datatoc)
- unset(_file_to_path)
+ add_custom_command(
+ OUTPUT ${file_to}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
+ COMMAND ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/datatoc ${file_from} ${file_to}
+ DEPENDS ${file_from} datatoc)
+ unset(_file_to_path)
endmacro()
# -----------------------------------------------------------------------------
@@ -58,24 +58,24 @@ endmacro()
# set the endian define
if(MSVC)
- # for some reason this fails on msvc
- add_definitions(-D__LITTLE_ENDIAN__)
+ # for some reason this fails on msvc
+ add_definitions(-D__LITTLE_ENDIAN__)
else()
- include(TestBigEndian)
- test_big_endian(_SYSTEM_BIG_ENDIAN)
- if(_SYSTEM_BIG_ENDIAN)
- add_definitions(-D__BIG_ENDIAN__)
- else()
- add_definitions(-D__LITTLE_ENDIAN__)
- endif()
- unset(_SYSTEM_BIG_ENDIAN)
+ include(TestBigEndian)
+ test_big_endian(_SYSTEM_BIG_ENDIAN)
+ if(_SYSTEM_BIG_ENDIAN)
+ add_definitions(-D__BIG_ENDIAN__)
+ else()
+ add_definitions(-D__LITTLE_ENDIAN__)
+ endif()
+ unset(_SYSTEM_BIG_ENDIAN)
endif()
# -----------------------------------------------------------------------------
# Libraries
if(UNIX AND NOT APPLE)
- set(WITH_X11 ON)
+ set(WITH_X11 ON)
endif()
# for now... default to this
add_definitions(-DWITH_GL_PROFILE_COMPAT)
@@ -126,27 +126,27 @@ add_library(glewmx_lib ${SRC_NEW})
# grr, blenfont needs BLI
include_directories(
- "../../../source/blender/blenlib"
- )
+ "../../../source/blender/blenlib"
+ )
add_library(bli_lib
- "../../../source/blender/blenlib/intern/fileops.c"
- "../../../source/blender/blenlib/intern/gsqueue.c"
- "../../../source/blender/blenlib/intern/rct.c"
- "../../../source/blender/blenlib/intern/string.c"
- "../../../source/blender/blenlib/intern/string_utf8.c"
- "../../../source/blender/blenlib/intern/listbase.c"
- "../../../source/blender/blenlib/intern/math_color.c"
- "../../../source/blender/blenlib/intern/storage.c"
- "../../../source/blender/blenlib/intern/task.c"
- "../../../source/blender/blenlib/intern/threads.c"
- "../../../source/blender/blenlib/intern/time.c"
- "../../../source/blender/blenlib/intern/path_util.c"
- "../../../source/blender/blenlib/intern/BLI_dynstr.c"
- "../../../source/blender/blenlib/intern/BLI_linklist.c"
- "../../../source/blender/blenlib/intern/BLI_memarena.c"
- "../../../source/blender/blenlib/intern/BLI_mempool.c"
- "../../../source/blender/blenlib/intern/system.c"
- )
+ "../../../source/blender/blenlib/intern/fileops.c"
+ "../../../source/blender/blenlib/intern/gsqueue.c"
+ "../../../source/blender/blenlib/intern/rct.c"
+ "../../../source/blender/blenlib/intern/string.c"
+ "../../../source/blender/blenlib/intern/string_utf8.c"
+ "../../../source/blender/blenlib/intern/listbase.c"
+ "../../../source/blender/blenlib/intern/math_color.c"
+ "../../../source/blender/blenlib/intern/storage.c"
+ "../../../source/blender/blenlib/intern/task.c"
+ "../../../source/blender/blenlib/intern/threads.c"
+ "../../../source/blender/blenlib/intern/time.c"
+ "../../../source/blender/blenlib/intern/path_util.c"
+ "../../../source/blender/blenlib/intern/BLI_dynstr.c"
+ "../../../source/blender/blenlib/intern/BLI_linklist.c"
+ "../../../source/blender/blenlib/intern/BLI_memarena.c"
+ "../../../source/blender/blenlib/intern/BLI_mempool.c"
+ "../../../source/blender/blenlib/intern/system.c"
+ )
set(PLATFORM_CGLAGS)
@@ -162,26 +162,26 @@ include_directories(${FREETYPE_INCLUDE_DIRS})
include_directories(${CMAKE_SOURCE_DIR}/../../../source/blender/blenfont)
if(CMAKE_COMPILER_IS_GNUCC)
- set(PLATFORM_CFLAGS "-funsigned-char")
+ set(PLATFORM_CFLAGS "-funsigned-char")
endif()
if(UNIX AND NOT APPLE)
- find_package(X11 REQUIRED)
- find_package(GLEW)
-
- if(NOT GLEW_FOUND)
- message(FATAL_ERROR "GLEW is required to build blender, install it or disable WITH_SYSTEM_GLEW")
- endif()
-
- set(PLATFORM_LINKLIBS
- ${X11_X11_LIB}
- ${X11_Xinput_LIB}
- ${GLEW_LIBRARY}
- -lpthread
- )
+ find_package(X11 REQUIRED)
+ find_package(GLEW)
+
+ if(NOT GLEW_FOUND)
+ message(FATAL_ERROR "GLEW is required to build blender, install it or disable WITH_SYSTEM_GLEW")
+ endif()
+
+ set(PLATFORM_LINKLIBS
+ ${X11_X11_LIB}
+ ${X11_Xinput_LIB}
+ ${GLEW_LIBRARY}
+ -lpthread
+ )
else()
- # set(GLEW_LIBRARY "") # unused
- set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include")
+ # set(GLEW_LIBRARY "") # unused
+ set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS}")
@@ -192,34 +192,34 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS}")
# DataToC
add_executable(datatoc
- ${CMAKE_SOURCE_DIR}/../../../source/blender/datatoc/datatoc.c)
+ ${CMAKE_SOURCE_DIR}/../../../source/blender/datatoc/datatoc.c)
# Gears (C)
add_executable(gears_c
- ${CMAKE_SOURCE_DIR}/gears/GHOST_C-Test.c)
+ ${CMAKE_SOURCE_DIR}/gears/GHOST_C-Test.c)
target_link_libraries(gears_c
- ghost_lib
- glewmx_lib
- string_lib
- ${OPENGL_gl_LIBRARY}
- ${CMAKE_DL_LIBS}
- ${PLATFORM_LINKLIBS}
- )
+ ghost_lib
+ glewmx_lib
+ string_lib
+ ${OPENGL_gl_LIBRARY}
+ ${CMAKE_DL_LIBS}
+ ${PLATFORM_LINKLIBS}
+ )
# Gears (C++)
add_executable(gears_cpp
- ${CMAKE_SOURCE_DIR}/gears/GHOST_Test.cpp)
+ ${CMAKE_SOURCE_DIR}/gears/GHOST_Test.cpp)
target_link_libraries(gears_cpp
- ghost_lib
- glewmx_lib
- string_lib
- ${OPENGL_gl_LIBRARY}
- ${CMAKE_DL_LIBS}
- ${PLATFORM_LINKLIBS}
- )
+ ghost_lib
+ glewmx_lib
+ string_lib
+ ${OPENGL_gl_LIBRARY}
+ ${CMAKE_DL_LIBS}
+ ${PLATFORM_LINKLIBS}
+ )
# MultiTest (C)
@@ -228,28 +228,28 @@ data_to_c(${CMAKE_SOURCE_DIR}/../../../release/datafiles/bfont.ttf
${CMAKE_CURRENT_BINARY_DIR}/bfont.ttf.c data_to_c_files)
add_executable(multitest_c
- ${CMAKE_SOURCE_DIR}/multitest/Basic.c
- ${CMAKE_SOURCE_DIR}/multitest/EventToBuf.c
- ${CMAKE_SOURCE_DIR}/multitest/MultiTest.c
- ${CMAKE_SOURCE_DIR}/multitest/ScrollBar.c
- ${CMAKE_SOURCE_DIR}/multitest/Util.c
- ${CMAKE_SOURCE_DIR}/multitest/WindowData.c
- ${CMAKE_SOURCE_DIR}/multitest/stubs.c
- ${data_to_c_files}
+ ${CMAKE_SOURCE_DIR}/multitest/Basic.c
+ ${CMAKE_SOURCE_DIR}/multitest/EventToBuf.c
+ ${CMAKE_SOURCE_DIR}/multitest/MultiTest.c
+ ${CMAKE_SOURCE_DIR}/multitest/ScrollBar.c
+ ${CMAKE_SOURCE_DIR}/multitest/Util.c
+ ${CMAKE_SOURCE_DIR}/multitest/WindowData.c
+ ${CMAKE_SOURCE_DIR}/multitest/stubs.c
+ ${data_to_c_files}
)
target_link_libraries(multitest_c
- blenfont_lib
- bli_lib
- ghost_lib
- glewmx_lib
- string_lib
- guardedalloc_lib
- wcwidth_lib
- ${OPENGL_gl_LIBRARY}
- ${FREETYPE_LIBRARY}
- ${ZLIB_LIBRARIES}
- ${CMAKE_DL_LIBS}
- ${PLATFORM_LINKLIBS}
- )
+ blenfont_lib
+ bli_lib
+ ghost_lib
+ glewmx_lib
+ string_lib
+ guardedalloc_lib
+ wcwidth_lib
+ ${OPENGL_gl_LIBRARY}
+ ${FREETYPE_LIBRARY}
+ ${ZLIB_LIBRARIES}
+ ${CMAKE_DL_LIBS}
+ ${PLATFORM_LINKLIBS}
+ )
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c
index b308ac61e57..80675ac5e3d 100644
--- a/intern/ghost/test/gears/GHOST_C-Test.c
+++ b/intern/ghost/test/gears/GHOST_C-Test.c
@@ -39,14 +39,13 @@
# include <windows.h>
# include <GL/gl.h>
# else /* WIN32 */
- /* __APPLE__ is defined */
+/* __APPLE__ is defined */
# include <AGL/gl.h>
# endif /* WIN32 */
-#else /* defined(WIN32) || defined(__APPLE__) */
+#else /* defined(WIN32) || defined(__APPLE__) */
# include <GL/gl.h>
#endif /* defined(WIN32) || defined(__APPLE__) */
-
static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time);
int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData);
@@ -63,472 +62,454 @@ static GHOST_TimerTaskHandle sGearsTimer;
static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
{
- printf("timer1, time=%d\n", (int)time);
+ printf("timer1, time=%d\n", (int)time);
}
-
-static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
+static void gearGL(
+ GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
{
- GLint i;
- GLfloat r0, r1, r2;
- GLfloat angle, da;
- GLfloat u, v, len;
- const double pi = 3.14159264;
-
- r0 = inner_radius;
- r1 = (float)(outer_radius - tooth_depth / 2.0);
- r2 = (float)(outer_radius + tooth_depth / 2.0);
-
- da = (float)(2.0 * pi / teeth / 4.0);
-
- glShadeModel(GL_FLAT);
- glNormal3f(0.0, 0.0, 1.0);
-
- /* draw front face */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= teeth; i++) {
- angle = (float)(i * 2.0 * pi / teeth);
- glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
- glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
- glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
- glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
- }
- glEnd();
-
- /* draw front sides of teeth */
- glBegin(GL_QUADS);
- da = (float)(2.0 * pi / teeth / 4.0);
- for (i = 0; i < teeth; i++) {
- angle = (float)(i * 2.0 * pi / teeth);
- glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
- glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
- glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(width * 0.5));
- glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
- }
- glEnd();
-
- glNormal3f(0.0, 0.0, -1.0);
-
- /* draw back face */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= teeth; i++) {
- angle = (float)(i * 2.0 * pi / teeth);
- glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
- glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
- glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(-width * 0.5));
- glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
- }
- glEnd();
-
- /* draw back sides of teeth */
- glBegin(GL_QUADS);
- da = (float)(2.0 * pi / teeth / 4.0);
- for (i = 0; i < teeth; i++) {
- angle = (float)(i * 2.0 * pi / teeth);
- glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(-width * 0.5));
- glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(-width * 0.5));
- glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
- glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
- }
- glEnd();
-
- /* draw outward faces of teeth */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i < teeth; i++) {
- angle = (float)(i * 2.0 * pi / teeth);
- glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
- glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
- u = (float)(r2 * cos(angle + da) - r1 * cos(angle));
- v = (float)(r2 * sin(angle + da) - r1 * sin(angle));
- len = (float)(sqrt(u * u + v * v));
- u /= len;
- v /= len;
- glNormal3f(v, -u, 0.0);
- glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
- glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
- glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
- glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(width * 0.5));
- glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(-width * 0.5));
- u = (float)(r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da));
- v = (float)(r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da));
- glNormal3f(v, -u, 0.0);
- glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
- glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(-width * 0.5));
- glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
- }
- glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(width * 0.5));
- glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(-width * 0.5));
- glEnd();
-
- glShadeModel(GL_SMOOTH);
-
- /* draw inside radius cylinder */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= teeth; i++) {
- angle = (float)(i * 2.0 * pi / teeth);
- glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
- glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
- glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
- }
- glEnd();
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+ const double pi = 3.14159264;
+
+ r0 = inner_radius;
+ r1 = (float)(outer_radius - tooth_depth / 2.0);
+ r2 = (float)(outer_radius + tooth_depth / 2.0);
+
+ da = (float)(2.0 * pi / teeth / 4.0);
+
+ glShadeModel(GL_FLAT);
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = (float)(i * 2.0 * pi / teeth);
+ glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
+ glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
+ glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
+ glVertex3f((float)(r1 * cos(angle + 3 * da)),
+ (float)(r1 * sin(angle + 3 * da)),
+ (float)(width * 0.5));
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = (float)(2.0 * pi / teeth / 4.0);
+ for (i = 0; i < teeth; i++) {
+ angle = (float)(i * 2.0 * pi / teeth);
+ glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
+ glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
+ glVertex3f((float)(r2 * cos(angle + 2 * da)),
+ (float)(r2 * sin(angle + 2 * da)),
+ (float)(width * 0.5));
+ glVertex3f((float)(r1 * cos(angle + 3 * da)),
+ (float)(r1 * sin(angle + 3 * da)),
+ (float)(width * 0.5));
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = (float)(i * 2.0 * pi / teeth);
+ glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
+ glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
+ glVertex3f((float)(r1 * cos(angle + 3 * da)),
+ (float)(r1 * sin(angle + 3 * da)),
+ (float)(-width * 0.5));
+ glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = (float)(2.0 * pi / teeth / 4.0);
+ for (i = 0; i < teeth; i++) {
+ angle = (float)(i * 2.0 * pi / teeth);
+ glVertex3f((float)(r1 * cos(angle + 3 * da)),
+ (float)(r1 * sin(angle + 3 * da)),
+ (float)(-width * 0.5));
+ glVertex3f((float)(r2 * cos(angle + 2 * da)),
+ (float)(r2 * sin(angle + 2 * da)),
+ (float)(-width * 0.5));
+ glVertex3f(
+ (float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
+ glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++) {
+ angle = (float)(i * 2.0 * pi / teeth);
+ glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
+ glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
+ u = (float)(r2 * cos(angle + da) - r1 * cos(angle));
+ v = (float)(r2 * sin(angle + da) - r1 * sin(angle));
+ len = (float)(sqrt(u * u + v * v));
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
+ glVertex3f(
+ (float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
+ glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
+ glVertex3f((float)(r2 * cos(angle + 2 * da)),
+ (float)(r2 * sin(angle + 2 * da)),
+ (float)(width * 0.5));
+ glVertex3f((float)(r2 * cos(angle + 2 * da)),
+ (float)(r2 * sin(angle + 2 * da)),
+ (float)(-width * 0.5));
+ u = (float)(r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da));
+ v = (float)(r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da));
+ glNormal3f(v, -u, 0.0);
+ glVertex3f((float)(r1 * cos(angle + 3 * da)),
+ (float)(r1 * sin(angle + 3 * da)),
+ (float)(width * 0.5));
+ glVertex3f((float)(r1 * cos(angle + 3 * da)),
+ (float)(r1 * sin(angle + 3 * da)),
+ (float)(-width * 0.5));
+ glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
+ }
+ glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(width * 0.5));
+ glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(-width * 0.5));
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = (float)(i * 2.0 * pi / teeth);
+ glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
+ glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
+ glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
+ }
+ glEnd();
}
-
-
static void drawGearGL(int id)
{
- static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
- static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
- static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
- static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
-
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glEnable(GL_CULL_FACE);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_DEPTH_TEST);
-
- switch (id)
- {
- case 1:
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
- gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
- break;
- case 2:
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
- gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
- break;
- case 3:
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
- gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
- break;
- default:
- break;
- }
- glEnable(GL_NORMALIZE);
+ static GLfloat pos[4] = {5.0f, 5.0f, 10.0f, 1.0f};
+ static GLfloat ared[4] = {0.8f, 0.1f, 0.0f, 1.0f};
+ static GLfloat agreen[4] = {0.0f, 0.8f, 0.2f, 1.0f};
+ static GLfloat ablue[4] = {0.2f, 0.2f, 1.0f, 1.0f};
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ switch (id) {
+ case 1:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
+ gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ break;
+ case 2:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
+ gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ break;
+ case 3:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
+ gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ break;
+ default:
+ break;
+ }
+ glEnable(GL_NORMALIZE);
}
-
static void drawGL(void)
{
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix();
-
- glRotatef(view_rotx, 1.0, 0.0, 0.0);
- glRotatef(view_roty, 0.0, 1.0, 0.0);
- glRotatef(view_rotz, 0.0, 0.0, 1.0);
-
- glPushMatrix();
- glTranslatef(-3.0, -2.0, 0.0);
- glRotatef(fAngle, 0.0, 0.0, 1.0);
- drawGearGL(1);
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef(3.1f, -2.0f, 0.0f);
- glRotatef((float)(-2.0 * fAngle - 9.0), 0.0, 0.0, 1.0);
- drawGearGL(2);
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef(-3.1f, 2.2f, -1.8f);
- glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
- glRotatef((float)(2.0 * fAngle - 2.0), 0.0, 0.0, 1.0);
- drawGearGL(3);
- glPopMatrix();
-
- glPopMatrix();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(fAngle, 0.0, 0.0, 1.0);
+ drawGearGL(1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1f, -2.0f, 0.0f);
+ glRotatef((float)(-2.0 * fAngle - 9.0), 0.0, 0.0, 1.0);
+ drawGearGL(2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1f, 2.2f, -1.8f);
+ glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef((float)(2.0 * fAngle - 2.0), 0.0, 0.0, 1.0);
+ drawGearGL(3);
+ glPopMatrix();
+
+ glPopMatrix();
}
-
static void setViewPortGL(GHOST_WindowHandle hWindow)
{
- GHOST_RectangleHandle hRect = NULL;
- GLfloat w, h;
+ GHOST_RectangleHandle hRect = NULL;
+ GLfloat w, h;
- GHOST_ActivateWindowDrawingContext(hWindow);
- hRect = GHOST_GetClientBounds(hWindow);
+ GHOST_ActivateWindowDrawingContext(hWindow);
+ hRect = GHOST_GetClientBounds(hWindow);
- w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
- h = 1.0;
+ w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
+ h = 1.0;
- glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
+ glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-w, w, -h, h, 5.0, 60.0);
- /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -40.0);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-w, w, -h, h, 5.0, 60.0);
+ /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
- glClearColor(.2f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClearColor(.2f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
- GHOST_DisposeRectangle(hRect);
+ GHOST_DisposeRectangle(hRect);
}
-
-
int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
{
- int handled = 1;
- int cursor;
- int visibility;
- GHOST_TEventKeyData *keyData = NULL;
- GHOST_TEventWheelData *wheelData = NULL;
- GHOST_DisplaySetting setting;
- GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
-
- switch (GHOST_GetEventType(hEvent))
- {
+ int handled = 1;
+ int cursor;
+ int visibility;
+ GHOST_TEventKeyData *keyData = NULL;
+ GHOST_TEventWheelData *wheelData = NULL;
+ GHOST_DisplaySetting setting;
+ GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
+
+ switch (GHOST_GetEventType(hEvent)) {
#if 0
- case GHOST_kEventUnknown:
- break;
- case GHOST_kEventCursorButton:
- break;
- case GHOST_kEventCursorMove:
- break;
+ case GHOST_kEventUnknown:
+ break;
+ case GHOST_kEventCursorButton:
+ break;
+ case GHOST_kEventCursorMove:
+ break;
#endif
- case GHOST_kEventWheel:
- {
- wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent);
- if (wheelData->z > 0)
- {
- view_rotz += 5.f;
- }
- else {
- view_rotz -= 5.f;
- }
- }
- break;
-
- case GHOST_kEventKeyUp:
- break;
-
- case GHOST_kEventKeyDown:
- {
- keyData = (GHOST_TEventKeyData *)GHOST_GetEventData(hEvent);
- switch (keyData->key)
- {
- case GHOST_kKeyC:
- {
- cursor = sCursor;
- cursor++;
- if (cursor >= GHOST_kStandardCursorNumCursors)
- {
- cursor = GHOST_kStandardCursorFirstCursor;
- }
- sCursor = (GHOST_TStandardCursor)cursor;
- GHOST_SetCursorShape(window, sCursor);
- }
- break;
- case GHOST_kKeyF:
- if (!GHOST_GetFullScreen(shSystem))
- {
- /* Begin fullscreen mode */
- setting.bpp = 24;
- setting.frequency = 85;
- setting.xPixels = 640;
- setting.yPixels = 480;
-
- /*
- * setting.bpp = 16;
- * setting.frequency = 75;
- * setting.xPixels = 640;
- * setting.yPixels = 480;
- */
-
- sFullScreenWindow = GHOST_BeginFullScreen(shSystem, &setting,
-
- FALSE /* stereo flag */);
- }
- else {
- GHOST_EndFullScreen(shSystem);
- sFullScreenWindow = 0;
- }
- break;
- case GHOST_kKeyH:
- {
- visibility = GHOST_GetCursorVisibility(window);
- GHOST_SetCursorVisibility(window, !visibility);
- }
- break;
- case GHOST_kKeyQ:
- if (GHOST_GetFullScreen(shSystem))
- {
- GHOST_EndFullScreen(shSystem);
- sFullScreenWindow = 0;
- }
- sExitRequested = 1;
- case GHOST_kKeyT:
- if (!sTestTimer)
- {
- sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
- }
- else {
- GHOST_RemoveTimer(shSystem, sTestTimer);
- sTestTimer = 0;
- }
- break;
- case GHOST_kKeyW:
- {
- if (sMainWindow)
- {
- char *title = GHOST_GetTitle(sMainWindow);
- char *ntitle = malloc(strlen(title) + 2);
-
- sprintf(ntitle, "%s-", title);
- GHOST_SetTitle(sMainWindow, ntitle);
-
- free(ntitle);
- free(title);
- }
- }
- break;
- default:
- break;
- }
- }
- break;
-
- case GHOST_kEventWindowClose:
- {
- GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
- if (window2 == sMainWindow)
- {
- sExitRequested = 1;
- }
- else {
- if (sGearsTimer)
- {
- GHOST_RemoveTimer(shSystem, sGearsTimer);
- sGearsTimer = 0;
- }
- GHOST_DisposeWindow(shSystem, window2);
- }
- }
- break;
-
- case GHOST_kEventWindowActivate:
- handled = 0;
- break;
- case GHOST_kEventWindowDeactivate:
- handled = 0;
- break;
- case GHOST_kEventWindowUpdate:
- {
- GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
- if (!GHOST_ValidWindow(shSystem, window2))
- break;
- setViewPortGL(window2);
- drawGL();
- GHOST_SwapWindowBuffers(window2);
- }
- break;
-
- default:
- handled = 0;
- break;
- }
- return handled;
+ case GHOST_kEventWheel: {
+ wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent);
+ if (wheelData->z > 0) {
+ view_rotz += 5.f;
+ }
+ else {
+ view_rotz -= 5.f;
+ }
+ } break;
+
+ case GHOST_kEventKeyUp:
+ break;
+
+ case GHOST_kEventKeyDown: {
+ keyData = (GHOST_TEventKeyData *)GHOST_GetEventData(hEvent);
+ switch (keyData->key) {
+ case GHOST_kKeyC: {
+ cursor = sCursor;
+ cursor++;
+ if (cursor >= GHOST_kStandardCursorNumCursors) {
+ cursor = GHOST_kStandardCursorFirstCursor;
+ }
+ sCursor = (GHOST_TStandardCursor)cursor;
+ GHOST_SetCursorShape(window, sCursor);
+ } break;
+ case GHOST_kKeyF:
+ if (!GHOST_GetFullScreen(shSystem)) {
+ /* Begin fullscreen mode */
+ setting.bpp = 24;
+ setting.frequency = 85;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+
+ /*
+ * setting.bpp = 16;
+ * setting.frequency = 75;
+ * setting.xPixels = 640;
+ * setting.yPixels = 480;
+ */
+
+ sFullScreenWindow = GHOST_BeginFullScreen(shSystem,
+ &setting,
+
+ FALSE /* stereo flag */);
+ }
+ else {
+ GHOST_EndFullScreen(shSystem);
+ sFullScreenWindow = 0;
+ }
+ break;
+ case GHOST_kKeyH: {
+ visibility = GHOST_GetCursorVisibility(window);
+ GHOST_SetCursorVisibility(window, !visibility);
+ } break;
+ case GHOST_kKeyQ:
+ if (GHOST_GetFullScreen(shSystem)) {
+ GHOST_EndFullScreen(shSystem);
+ sFullScreenWindow = 0;
+ }
+ sExitRequested = 1;
+ case GHOST_kKeyT:
+ if (!sTestTimer) {
+ sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
+ }
+ else {
+ GHOST_RemoveTimer(shSystem, sTestTimer);
+ sTestTimer = 0;
+ }
+ break;
+ case GHOST_kKeyW: {
+ if (sMainWindow) {
+ char *title = GHOST_GetTitle(sMainWindow);
+ char *ntitle = malloc(strlen(title) + 2);
+
+ sprintf(ntitle, "%s-", title);
+ GHOST_SetTitle(sMainWindow, ntitle);
+
+ free(ntitle);
+ free(title);
+ }
+ } break;
+ default:
+ break;
+ }
+ } break;
+
+ case GHOST_kEventWindowClose: {
+ GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
+ if (window2 == sMainWindow) {
+ sExitRequested = 1;
+ }
+ else {
+ if (sGearsTimer) {
+ GHOST_RemoveTimer(shSystem, sGearsTimer);
+ sGearsTimer = 0;
+ }
+ GHOST_DisposeWindow(shSystem, window2);
+ }
+ } break;
+
+ case GHOST_kEventWindowActivate:
+ handled = 0;
+ break;
+ case GHOST_kEventWindowDeactivate:
+ handled = 0;
+ break;
+ case GHOST_kEventWindowUpdate: {
+ GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
+ if (!GHOST_ValidWindow(shSystem, window2))
+ break;
+ setViewPortGL(window2);
+ drawGL();
+ GHOST_SwapWindowBuffers(window2);
+ } break;
+
+ default:
+ handled = 0;
+ break;
+ }
+ return handled;
}
-
int main(int argc, char **argv)
{
- GHOST_GLSettings glSettings = {0};
- char *title1 = "gears - main window";
- char *title2 = "gears - secondary window";
- GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
-
- /* Create the system */
- shSystem = GHOST_CreateSystem();
- GHOST_AddEventConsumer(shSystem, consumer);
-
- if (shSystem)
- {
- /* Create the main window */
- sMainWindow = GHOST_CreateWindow(
- shSystem, title1,
- 10, 64, 320, 200,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
- if (!sMainWindow)
- {
- printf("could not create main window\n");
- exit(-1);
- }
-
- /* Create a secondary window */
- sSecondaryWindow = GHOST_CreateWindow(
- shSystem,
- title2,
- 340, 64, 320, 200,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
- if (!sSecondaryWindow)
- {
- printf("could not create secondary window\n");
- exit(-1);
- }
-
- /* Install a timer to have the gears running */
- sGearsTimer = GHOST_InstallTimer(shSystem,
- 0,
- 10,
- gearsTimerProc,
- sMainWindow);
-
- /* Enter main loop */
- while (!sExitRequested)
- {
- if (!GHOST_ProcessEvents(shSystem, 0))
- {
+ GHOST_GLSettings glSettings = {0};
+ char *title1 = "gears - main window";
+ char *title2 = "gears - secondary window";
+ GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
+
+ /* Create the system */
+ shSystem = GHOST_CreateSystem();
+ GHOST_AddEventConsumer(shSystem, consumer);
+
+ if (shSystem) {
+ /* Create the main window */
+ sMainWindow = GHOST_CreateWindow(shSystem,
+ title1,
+ 10,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
+ if (!sMainWindow) {
+ printf("could not create main window\n");
+ exit(-1);
+ }
+
+ /* Create a secondary window */
+ sSecondaryWindow = GHOST_CreateWindow(shSystem,
+ title2,
+ 340,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
+ if (!sSecondaryWindow) {
+ printf("could not create secondary window\n");
+ exit(-1);
+ }
+
+ /* Install a timer to have the gears running */
+ sGearsTimer = GHOST_InstallTimer(shSystem, 0, 10, gearsTimerProc, sMainWindow);
+
+ /* Enter main loop */
+ while (!sExitRequested) {
+ if (!GHOST_ProcessEvents(shSystem, 0)) {
#ifdef WIN32
- /* If there were no events, be nice to other applications */
- Sleep(10);
+ /* If there were no events, be nice to other applications */
+ Sleep(10);
#endif
- }
- GHOST_DispatchEvents(shSystem);
- }
- }
-
- /* Dispose windows */
- if (GHOST_ValidWindow(shSystem, sMainWindow))
- {
- GHOST_DisposeWindow(shSystem, sMainWindow);
- }
- if (GHOST_ValidWindow(shSystem, sSecondaryWindow))
- {
- GHOST_DisposeWindow(shSystem, sSecondaryWindow);
- }
-
- /* Dispose the system */
- GHOST_DisposeSystem(shSystem);
-
- return 0;
+ }
+ GHOST_DispatchEvents(shSystem);
+ }
+ }
+
+ /* Dispose windows */
+ if (GHOST_ValidWindow(shSystem, sMainWindow)) {
+ GHOST_DisposeWindow(shSystem, sMainWindow);
+ }
+ if (GHOST_ValidWindow(shSystem, sSecondaryWindow)) {
+ GHOST_DisposeWindow(shSystem, sSecondaryWindow);
+ }
+
+ /* Dispose the system */
+ GHOST_DisposeSystem(shSystem);
+
+ return 0;
}
-
static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time)
{
- GHOST_WindowHandle hWindow = NULL;
- fAngle += 2.0;
- view_roty += 1.0;
- hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
- if (GHOST_GetFullScreen(shSystem))
- {
- /* Running full screen */
- GHOST_InvalidateWindow(sFullScreenWindow);
- }
- else {
- if (GHOST_ValidWindow(shSystem, hWindow))
- {
- GHOST_InvalidateWindow(hWindow);
- }
- }
+ GHOST_WindowHandle hWindow = NULL;
+ fAngle += 2.0;
+ view_roty += 1.0;
+ hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
+ if (GHOST_GetFullScreen(shSystem)) {
+ /* Running full screen */
+ GHOST_InvalidateWindow(sFullScreenWindow);
+ }
+ else {
+ if (GHOST_ValidWindow(shSystem, hWindow)) {
+ GHOST_InvalidateWindow(hWindow);
+ }
+ }
}
diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp
index 23564faf38d..76386fb114a 100644
--- a/intern/ghost/test/gears/GHOST_Test.cpp
+++ b/intern/ghost/test/gears/GHOST_Test.cpp
@@ -34,13 +34,13 @@
# include <atlbase.h>
# include <GL/gl.h>
-# else // WIN32
- // __APPLE__ is defined
+# else // WIN32 \
+ // __APPLE__ is defined
# include <AGL/gl.h>
-# endif // WIN32
-#else // defined(WIN32) || defined(__APPLE__)
+# endif // WIN32
+#else // defined(WIN32) || defined(__APPLE__)
# include <GL/gl.h>
-#endif // defined(WIN32) || defined(__APPLE__)
+#endif // defined(WIN32) || defined(__APPLE__)
#include "STR_String.h"
#include "GHOST_Rect.h"
@@ -49,290 +49,302 @@
#include "GHOST_IEvent.h"
#include "GHOST_IEventConsumer.h"
-
-#define LEFT_EYE 0
+#define LEFT_EYE 0
#define RIGHT_EYE 1
static bool nVidiaWindows; // very dirty but hey, it's for testing only
static void gearsTimerProc(GHOST_ITimerTask *task, GHOST_TUns64 time);
-static class Application * fApp;
+static class Application *fApp;
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
static GLfloat fAngle = 0.0;
static GHOST_ISystem *fSystem = 0;
-
-void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
- float zero_plane, float dist,
+void StereoProjection(float left,
+ float right,
+ float bottom,
+ float top,
+ float nearplane,
+ float farplane,
+ float zero_plane,
+ float dist,
float eye);
-
static void testTimerProc(GHOST_ITimerTask * /*task*/, GHOST_TUns64 time)
{
- std::cout << "timer1, time=" << (int)time << "\n";
+ std::cout << "timer1, time=" << (int)time << "\n";
}
-
-static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
+static void gearGL(
+ GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
{
- GLint i;
- GLfloat r0, r1, r2;
- GLfloat angle, da;
- GLfloat u, v, len;
-
- r0 = inner_radius;
- r1 = outer_radius - tooth_depth / 2.0;
- r2 = outer_radius + tooth_depth / 2.0;
-
- const double pi = 3.14159264;
- da = 2.0 * pi / teeth / 4.0;
-
- glShadeModel(GL_FLAT);
- glNormal3f(0.0, 0.0, 1.0);
-
- /* draw front face */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= teeth; i++) {
- angle = i * 2.0 * pi / teeth;
- glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
- glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
- }
- glEnd();
-
- /* draw front sides of teeth */
- glBegin(GL_QUADS);
- da = 2.0 * pi / teeth / 4.0;
- for (i = 0; i < teeth; i++) {
- angle = i * 2.0 * pi / teeth;
- glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
- }
- glEnd();
-
- glNormal3f(0.0, 0.0, -1.0);
-
- /* draw back face */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= teeth; i++) {
- angle = i * 2.0 * pi / teeth;
- glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
- }
- glEnd();
-
- /* draw back sides of teeth */
- glBegin(GL_QUADS);
- da = 2.0 * pi / teeth / 4.0;
- for (i = 0; i < teeth; i++) {
- angle = i * 2.0 * pi / teeth;
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
- glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
- }
- glEnd();
-
- /* draw outward faces of teeth */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i < teeth; i++) {
- angle = i * 2.0 * pi / teeth;
- glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
- glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
- u = r2 * cos(angle + da) - r1 *cos(angle);
- v = r2 * sin(angle + da) - r1 *sin(angle);
- len = sqrt(u * u + v * v);
- u /= len;
- v /= len;
- glNormal3f(v, -u, 0.0);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
- glNormal3f(cos(angle), sin(angle), 0.0);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
- u = r1 * cos(angle + 3 * da) - r2 *cos(angle + 2 * da);
- v = r1 * sin(angle + 3 * da) - r2 *sin(angle + 2 * da);
- glNormal3f(v, -u, 0.0);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
- glNormal3f(cos(angle), sin(angle), 0.0);
- }
- glVertex3f(r1 * cos(0.0), r1 * sin(0.0), width * 0.5);
- glVertex3f(r1 * cos(0.0), r1 * sin(0.0), -width * 0.5);
- glEnd();
-
- glShadeModel(GL_SMOOTH);
-
- /* draw inside radius cylinder */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= teeth; i++) {
- angle = i * 2.0 * pi / teeth;
- glNormal3f(-cos(angle), -sin(angle), 0.0);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
- }
- glEnd();
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0;
+ r2 = outer_radius + tooth_depth / 2.0;
+
+ const double pi = 3.14159264;
+ da = 2.0 * pi / teeth / 4.0;
+
+ glShadeModel(GL_FLAT);
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * pi / teeth;
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * pi / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * pi / teeth;
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * pi / teeth;
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * pi / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * pi / teeth;
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * pi / teeth;
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ u = r2 * cos(angle + da) - r1 * cos(angle);
+ v = r2 * sin(angle + da) - r1 * sin(angle);
+ len = sqrt(u * u + v * v);
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
+ u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
+ v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ }
+ glVertex3f(r1 * cos(0.0), r1 * sin(0.0), width * 0.5);
+ glVertex3f(r1 * cos(0.0), r1 * sin(0.0), -width * 0.5);
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * pi / teeth;
+ glNormal3f(-cos(angle), -sin(angle), 0.0);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ }
+ glEnd();
}
-
-
static void drawGearGL(int id)
{
- static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
- static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
- static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
- static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
-
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glEnable(GL_CULL_FACE);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_DEPTH_TEST);
-
- switch (id)
- {
- case 1:
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
- gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
- break;
- case 2:
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
- gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
- break;
- case 3:
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
- gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
- break;
- default:
- break;
- }
- glEnable(GL_NORMALIZE);
+ static GLfloat pos[4] = {5.0f, 5.0f, 10.0f, 1.0f};
+ static GLfloat ared[4] = {0.8f, 0.1f, 0.0f, 1.0f};
+ static GLfloat agreen[4] = {0.0f, 0.8f, 0.2f, 1.0f};
+ static GLfloat ablue[4] = {0.2f, 0.2f, 1.0f, 1.0f};
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ switch (id) {
+ case 1:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
+ gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ break;
+ case 2:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
+ gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ break;
+ case 3:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
+ gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ break;
+ default:
+ break;
+ }
+ glEnable(GL_NORMALIZE);
}
-
void RenderCamera()
{
- glRotatef(view_rotx, 1.0, 0.0, 0.0);
- glRotatef(view_roty, 0.0, 1.0, 0.0);
- glRotatef(view_rotz, 0.0, 0.0, 1.0);
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
}
-
void RenderScene()
{
- glPushMatrix();
- glTranslatef(-3.0, -2.0, 0.0);
- glRotatef(fAngle, 0.0, 0.0, 1.0);
- drawGearGL(1);
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef(3.1f, -2.0f, 0.0f);
- glRotatef(-2.0 * fAngle - 9.0, 0.0, 0.0, 1.0);
- drawGearGL(2);
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef(-3.1f, 2.2f, -1.8f);
- glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
- glRotatef(2.0 * fAngle - 2.0, 0.0, 0.0, 1.0);
- drawGearGL(3);
- glPopMatrix();
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(fAngle, 0.0, 0.0, 1.0);
+ drawGearGL(1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1f, -2.0f, 0.0f);
+ glRotatef(-2.0 * fAngle - 9.0, 0.0, 0.0, 1.0);
+ drawGearGL(2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1f, 2.2f, -1.8f);
+ glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef(2.0 * fAngle - 2.0, 0.0, 0.0, 1.0);
+ drawGearGL(3);
+ glPopMatrix();
}
-
static void View(GHOST_IWindow *window, bool stereo, int eye = 0)
{
- window->activateDrawingContext();
- GHOST_Rect bnds;
- int noOfScanlines = 0, lowerScanline = 0;
- /* hard coded for testing purposes, display device dependent */
- int verticalBlankingInterval = 32;
- float left, right, bottom, top;
- float nearplane, farplane, zeroPlane, distance;
- float eyeSeparation = 0.62f;
- window->getClientBounds(bnds);
-
- // viewport
- if (stereo)
- {
- if (nVidiaWindows)
- {
- // handled by nVidia driver so act as normal (explicitly put here since
- // it -is- stereo)
- glViewport(0, 0, bnds.getWidth(), bnds.getHeight());
- }
- else { // generic cross platform above-below stereo
- noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2;
- switch (eye)
- {
- case LEFT_EYE:
- // upper half of window
- lowerScanline = bnds.getHeight() - noOfScanlines;
- break;
- case RIGHT_EYE:
- // lower half of window
- lowerScanline = 0;
- break;
- }
- }
- }
- else {
- noOfScanlines = bnds.getHeight();
- lowerScanline = 0;
- }
-
- glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines);
-
- // projection
- left = -6.0;
- right = 6.0;
- bottom = -4.8f;
- top = 4.8f;
- nearplane = 5.0;
- farplane = 60.0;
-
- if (stereo)
- {
- zeroPlane = 0.0;
- distance = 14.5;
- switch (eye)
- {
- case LEFT_EYE:
- StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, -eyeSeparation / 2.0);
- break;
- case RIGHT_EYE:
- StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, eyeSeparation / 2.0);
- break;
- }
- }
- else {
-// left = -w;
-// right = w;
-// bottom = -h;
-// top = h;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(left, right, bottom, top, 5.0, 60.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -40.0);
-
- }
-
- glClearColor(.2f, 0.0f, 0.0f, 0.0f);
+ window->activateDrawingContext();
+ GHOST_Rect bnds;
+ int noOfScanlines = 0, lowerScanline = 0;
+ /* hard coded for testing purposes, display device dependent */
+ int verticalBlankingInterval = 32;
+ float left, right, bottom, top;
+ float nearplane, farplane, zeroPlane, distance;
+ float eyeSeparation = 0.62f;
+ window->getClientBounds(bnds);
+
+ // viewport
+ if (stereo) {
+ if (nVidiaWindows) {
+ // handled by nVidia driver so act as normal (explicitly put here since
+ // it -is- stereo)
+ glViewport(0, 0, bnds.getWidth(), bnds.getHeight());
+ }
+ else { // generic cross platform above-below stereo
+ noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2;
+ switch (eye) {
+ case LEFT_EYE:
+ // upper half of window
+ lowerScanline = bnds.getHeight() - noOfScanlines;
+ break;
+ case RIGHT_EYE:
+ // lower half of window
+ lowerScanline = 0;
+ break;
+ }
+ }
+ }
+ else {
+ noOfScanlines = bnds.getHeight();
+ lowerScanline = 0;
+ }
+
+ glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines);
+
+ // projection
+ left = -6.0;
+ right = 6.0;
+ bottom = -4.8f;
+ top = 4.8f;
+ nearplane = 5.0;
+ farplane = 60.0;
+
+ if (stereo) {
+ zeroPlane = 0.0;
+ distance = 14.5;
+ switch (eye) {
+ case LEFT_EYE:
+ StereoProjection(left,
+ right,
+ bottom,
+ top,
+ nearplane,
+ farplane,
+ zeroPlane,
+ distance,
+ -eyeSeparation / 2.0);
+ break;
+ case RIGHT_EYE:
+ StereoProjection(left,
+ right,
+ bottom,
+ top,
+ nearplane,
+ farplane,
+ zeroPlane,
+ distance,
+ eyeSeparation / 2.0);
+ break;
+ }
+ }
+ else {
+ // left = -w;
+ // right = w;
+ // bottom = -h;
+ // top = h;
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(left, right, bottom, top, 5.0, 60.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+ }
+
+ glClearColor(.2f, 0.0f, 0.0f, 0.0f);
}
-
-void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
- float zero_plane, float dist,
- float eye)
+void StereoProjection(float left,
+ float right,
+ float bottom,
+ float top,
+ float nearplane,
+ float farplane,
+ float zero_plane,
+ float dist,
+ float eye)
/* Perform the perspective projection for one eye's subfield.
* The projection is in the direction of the negative z axis.
*
@@ -357,395 +369,380 @@ void StereoProjection(float left, float right, float bottom, float top, float ne
* negative for the left eye subfield.
*/
{
- float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw,
- dx, dy, n_over_d;
+ float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw, dx, dy, n_over_d;
- dx = right - left;
- dy = top - bottom;
+ dx = right - left;
+ dy = top - bottom;
- xmid = (right + left) / 2.0;
- ymid = (top + bottom) / 2.0;
+ xmid = (right + left) / 2.0;
+ ymid = (top + bottom) / 2.0;
- clip_near = dist + zero_plane - nearplane;
- clip_far = dist + zero_plane - farplane;
+ clip_near = dist + zero_plane - nearplane;
+ clip_far = dist + zero_plane - farplane;
- n_over_d = clip_near / dist;
+ n_over_d = clip_near / dist;
- topw = n_over_d * dy / 2.0;
- bottomw = -topw;
- rightw = n_over_d * (dx / 2.0 - eye);
- leftw = n_over_d * (-dx / 2.0 - eye);
+ topw = n_over_d * dy / 2.0;
+ bottomw = -topw;
+ rightw = n_over_d * (dx / 2.0 - eye);
+ leftw = n_over_d * (-dx / 2.0 - eye);
- /* Need to be in projection mode for this. */
- glLoadIdentity();
- glFrustum(leftw, rightw, bottomw, topw, clip_near, clip_far);
+ /* Need to be in projection mode for this. */
+ glLoadIdentity();
+ glFrustum(leftw, rightw, bottomw, topw, clip_near, clip_far);
- glTranslatef(-xmid - eye, -ymid, -zero_plane - dist);
- return;
+ glTranslatef(-xmid - eye, -ymid, -zero_plane - dist);
+ return;
} /* stereoproj */
-
class Application : public GHOST_IEventConsumer {
-public:
- Application(GHOST_ISystem *system);
- ~Application(void);
- virtual bool processEvent(GHOST_IEvent *event);
-
- GHOST_ISystem *m_system;
- GHOST_IWindow *m_mainWindow;
- GHOST_IWindow *m_secondaryWindow;
- GHOST_IWindow *m_fullScreenWindow;
- GHOST_ITimerTask *m_gearsTimer, *m_testTimer;
- GHOST_TStandardCursor m_cursor;
- bool m_exitRequested;
-
- bool stereo;
+ public:
+ Application(GHOST_ISystem *system);
+ ~Application(void);
+ virtual bool processEvent(GHOST_IEvent *event);
+
+ GHOST_ISystem *m_system;
+ GHOST_IWindow *m_mainWindow;
+ GHOST_IWindow *m_secondaryWindow;
+ GHOST_IWindow *m_fullScreenWindow;
+ GHOST_ITimerTask *m_gearsTimer, *m_testTimer;
+ GHOST_TStandardCursor m_cursor;
+ bool m_exitRequested;
+
+ bool stereo;
};
-
Application::Application(GHOST_ISystem *system)
- : m_system(system), m_mainWindow(0), m_secondaryWindow(0), m_fullScreenWindow(0),
- m_gearsTimer(0), m_testTimer(0), m_cursor(GHOST_kStandardCursorFirstCursor),
- m_exitRequested(false), stereo(false)
+ : m_system(system),
+ m_mainWindow(0),
+ m_secondaryWindow(0),
+ m_fullScreenWindow(0),
+ m_gearsTimer(0),
+ m_testTimer(0),
+ m_cursor(GHOST_kStandardCursorFirstCursor),
+ m_exitRequested(false),
+ stereo(false)
{
- GHOST_GLSettings glSettings = {0};
- fApp = this;
-
- // Create the main window
- STR_String title1("gears - main window");
- m_mainWindow = system->createWindow(
- title1,
- 10, 64, 320, 200,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
-
- if (!m_mainWindow) {
- std::cout << "could not create main window\n";
- exit(-1);
- }
-
- // Create a secondary window
- STR_String title2("gears - secondary window");
- m_secondaryWindow = system->createWindow(
- title2,
- 340, 64, 320, 200,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
- if (!m_secondaryWindow) {
- std::cout << "could not create secondary window\n";
- exit(-1);
- }
-
- // Install a timer to have the gears running
- m_gearsTimer = system->installTimer(0 /*delay*/, 20 /*interval*/, gearsTimerProc, m_mainWindow);
+ GHOST_GLSettings glSettings = {0};
+ fApp = this;
+
+ // Create the main window
+ STR_String title1("gears - main window");
+ m_mainWindow = system->createWindow(title1,
+ 10,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
+
+ if (!m_mainWindow) {
+ std::cout << "could not create main window\n";
+ exit(-1);
+ }
+
+ // Create a secondary window
+ STR_String title2("gears - secondary window");
+ m_secondaryWindow = system->createWindow(title2,
+ 340,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
+ if (!m_secondaryWindow) {
+ std::cout << "could not create secondary window\n";
+ exit(-1);
+ }
+
+ // Install a timer to have the gears running
+ m_gearsTimer = system->installTimer(0 /*delay*/, 20 /*interval*/, gearsTimerProc, m_mainWindow);
}
-
Application::~Application(void)
{
- // Dispose windows
- if (m_system->validWindow(m_mainWindow)) {
- m_system->disposeWindow(m_mainWindow);
- }
- if (m_system->validWindow(m_secondaryWindow)) {
- m_system->disposeWindow(m_secondaryWindow);
- }
+ // Dispose windows
+ if (m_system->validWindow(m_mainWindow)) {
+ m_system->disposeWindow(m_mainWindow);
+ }
+ if (m_system->validWindow(m_secondaryWindow)) {
+ m_system->disposeWindow(m_secondaryWindow);
+ }
}
-
bool Application::processEvent(GHOST_IEvent *event)
{
- GHOST_IWindow *window = event->getWindow();
- bool handled = true;
+ GHOST_IWindow *window = event->getWindow();
+ bool handled = true;
- switch (event->getType()) {
+ switch (event->getType()) {
#if 0
- case GHOST_kEventUnknown:
- break;
- case GHOST_kEventCursorButton:
- std::cout << "GHOST_kEventCursorButton"; break;
- case GHOST_kEventCursorMove:
- std::cout << "GHOST_kEventCursorMove"; break;
+ case GHOST_kEventUnknown:
+ break;
+ case GHOST_kEventCursorButton:
+ std::cout << "GHOST_kEventCursorButton"; break;
+ case GHOST_kEventCursorMove:
+ std::cout << "GHOST_kEventCursorMove"; break;
#endif
- case GHOST_kEventWheel:
- {
- GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *) event->getData();
- if (wheelData->z > 0)
- {
- view_rotz += 5.f;
- }
- else {
- view_rotz -= 5.f;
- }
- }
- break;
-
- case GHOST_kEventKeyUp:
- break;
-
- case GHOST_kEventKeyDown:
- {
- GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *) event->getData();
- switch (keyData->key) {
- case GHOST_kKeyC:
- {
- int cursor = m_cursor;
- cursor++;
- if (cursor >= GHOST_kStandardCursorNumCursors) {
- cursor = GHOST_kStandardCursorFirstCursor;
- }
- m_cursor = (GHOST_TStandardCursor)cursor;
- window->setCursorShape(m_cursor);
- }
- break;
-
- case GHOST_kKeyE:
- {
- int x = 200, y = 200;
- m_system->setCursorPosition(x, y);
- break;
- }
-
- case GHOST_kKeyF:
- if (!m_system->getFullScreen()) {
- // Begin fullscreen mode
- GHOST_DisplaySetting setting;
-
- setting.bpp = 16;
- setting.frequency = 50;
- setting.xPixels = 640;
- setting.yPixels = 480;
- m_system->beginFullScreen(setting, &m_fullScreenWindow, false /* stereo flag */);
- }
- else {
- m_system->endFullScreen();
- m_fullScreenWindow = 0;
- }
- break;
-
- case GHOST_kKeyH:
- window->setCursorVisibility(!window->getCursorVisibility());
- break;
-
- case GHOST_kKeyM:
- {
- bool down = false;
- m_system->getModifierKeyState(GHOST_kModifierKeyLeftShift, down);
- if (down) {
- std::cout << "left shift down\n";
- }
- m_system->getModifierKeyState(GHOST_kModifierKeyRightShift, down);
- if (down) {
- std::cout << "right shift down\n";
- }
- m_system->getModifierKeyState(GHOST_kModifierKeyLeftAlt, down);
- if (down) {
- std::cout << "left Alt down\n";
- }
- m_system->getModifierKeyState(GHOST_kModifierKeyRightAlt, down);
- if (down) {
- std::cout << "right Alt down\n";
- }
- m_system->getModifierKeyState(GHOST_kModifierKeyLeftControl, down);
- if (down) {
- std::cout << "left control down\n";
- }
- m_system->getModifierKeyState(GHOST_kModifierKeyRightControl, down);
- if (down) {
- std::cout << "right control down\n";
- }
- }
- break;
-
- case GHOST_kKeyQ:
- if (m_system->getFullScreen())
- {
- m_system->endFullScreen();
- m_fullScreenWindow = 0;
- }
- m_exitRequested = true;
- break;
-
- case GHOST_kKeyS: // toggle mono and stereo
- if (stereo)
- stereo = false;
- else
- stereo = true;
- break;
-
- case GHOST_kKeyT:
- if (!m_testTimer) {
- m_testTimer = m_system->installTimer(0, 1000, testTimerProc);
- }
-
- else {
- m_system->removeTimer(m_testTimer);
- m_testTimer = 0;
- }
-
- break;
-
- case GHOST_kKeyW:
- if (m_mainWindow)
- {
- STR_String title;
- m_mainWindow->getTitle(title);
- title += "-";
- m_mainWindow->setTitle(title);
-
- }
- break;
-
- default:
- break;
- }
- }
- break;
-
- case GHOST_kEventWindowClose:
- {
- GHOST_IWindow *window2 = event->getWindow();
- if (window2 == m_mainWindow) {
- m_exitRequested = true;
- }
- else {
- m_system->disposeWindow(window2);
- }
- }
- break;
-
- case GHOST_kEventWindowActivate:
- handled = false;
- break;
-
- case GHOST_kEventWindowDeactivate:
- handled = false;
- break;
-
- case GHOST_kEventWindowUpdate:
- {
- GHOST_IWindow *window2 = event->getWindow();
- if (!m_system->validWindow(window2))
- break;
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if (stereo)
- {
- View(window2, stereo, LEFT_EYE);
- glPushMatrix();
- RenderCamera();
- RenderScene();
- glPopMatrix();
-
- View(window2, stereo, RIGHT_EYE);
- glPushMatrix();
- RenderCamera();
- RenderScene();
- glPopMatrix();
- }
- else {
- View(window2, stereo);
- glPushMatrix();
- RenderCamera();
- RenderScene();
- glPopMatrix();
- }
- window2->swapBuffers();
- }
- break;
-
- default:
- handled = false;
- break;
- }
- return handled;
+ case GHOST_kEventWheel: {
+ GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *)event->getData();
+ if (wheelData->z > 0) {
+ view_rotz += 5.f;
+ }
+ else {
+ view_rotz -= 5.f;
+ }
+ } break;
+
+ case GHOST_kEventKeyUp:
+ break;
+
+ case GHOST_kEventKeyDown: {
+ GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)event->getData();
+ switch (keyData->key) {
+ case GHOST_kKeyC: {
+ int cursor = m_cursor;
+ cursor++;
+ if (cursor >= GHOST_kStandardCursorNumCursors) {
+ cursor = GHOST_kStandardCursorFirstCursor;
+ }
+ m_cursor = (GHOST_TStandardCursor)cursor;
+ window->setCursorShape(m_cursor);
+ } break;
+
+ case GHOST_kKeyE: {
+ int x = 200, y = 200;
+ m_system->setCursorPosition(x, y);
+ break;
+ }
+
+ case GHOST_kKeyF:
+ if (!m_system->getFullScreen()) {
+ // Begin fullscreen mode
+ GHOST_DisplaySetting setting;
+
+ setting.bpp = 16;
+ setting.frequency = 50;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+ m_system->beginFullScreen(setting, &m_fullScreenWindow, false /* stereo flag */);
+ }
+ else {
+ m_system->endFullScreen();
+ m_fullScreenWindow = 0;
+ }
+ break;
+
+ case GHOST_kKeyH:
+ window->setCursorVisibility(!window->getCursorVisibility());
+ break;
+
+ case GHOST_kKeyM: {
+ bool down = false;
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftShift, down);
+ if (down) {
+ std::cout << "left shift down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightShift, down);
+ if (down) {
+ std::cout << "right shift down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftAlt, down);
+ if (down) {
+ std::cout << "left Alt down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightAlt, down);
+ if (down) {
+ std::cout << "right Alt down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftControl, down);
+ if (down) {
+ std::cout << "left control down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightControl, down);
+ if (down) {
+ std::cout << "right control down\n";
+ }
+ } break;
+
+ case GHOST_kKeyQ:
+ if (m_system->getFullScreen()) {
+ m_system->endFullScreen();
+ m_fullScreenWindow = 0;
+ }
+ m_exitRequested = true;
+ break;
+
+ case GHOST_kKeyS: // toggle mono and stereo
+ if (stereo)
+ stereo = false;
+ else
+ stereo = true;
+ break;
+
+ case GHOST_kKeyT:
+ if (!m_testTimer) {
+ m_testTimer = m_system->installTimer(0, 1000, testTimerProc);
+ }
+
+ else {
+ m_system->removeTimer(m_testTimer);
+ m_testTimer = 0;
+ }
+
+ break;
+
+ case GHOST_kKeyW:
+ if (m_mainWindow) {
+ STR_String title;
+ m_mainWindow->getTitle(title);
+ title += "-";
+ m_mainWindow->setTitle(title);
+ }
+ break;
+
+ default:
+ break;
+ }
+ } break;
+
+ case GHOST_kEventWindowClose: {
+ GHOST_IWindow *window2 = event->getWindow();
+ if (window2 == m_mainWindow) {
+ m_exitRequested = true;
+ }
+ else {
+ m_system->disposeWindow(window2);
+ }
+ } break;
+
+ case GHOST_kEventWindowActivate:
+ handled = false;
+ break;
+
+ case GHOST_kEventWindowDeactivate:
+ handled = false;
+ break;
+
+ case GHOST_kEventWindowUpdate: {
+ GHOST_IWindow *window2 = event->getWindow();
+ if (!m_system->validWindow(window2))
+ break;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (stereo) {
+ View(window2, stereo, LEFT_EYE);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+
+ View(window2, stereo, RIGHT_EYE);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+ }
+ else {
+ View(window2, stereo);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+ }
+ window2->swapBuffers();
+ } break;
+
+ default:
+ handled = false;
+ break;
+ }
+ return handled;
}
-
int main(int /*argc*/, char ** /*argv*/)
{
- nVidiaWindows = false;
-// nVidiaWindows = true;
+ nVidiaWindows = false;
+ // nVidiaWindows = true;
#ifdef WIN32
- /* Set a couple of settings in the registry for the nVidia detonator driver.
- * So this is very specific...
- */
- if (nVidiaWindows)
- {
- LONG lresult;
- HKEY hkey = 0;
- DWORD dwd = 0;
- //unsigned char buffer[128];
-
- CRegKey regkey;
- //DWORD keyValue;
-// lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable");
- lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
- KEY_ALL_ACCESS);
-
- if (lresult == ERROR_SUCCESS)
- printf("Successfully opened key\n");
-#if 0
- lresult = regkey.QueryValue(&keyValue, "StereoEnable");
- if (lresult == ERROR_SUCCESS)
- printf("Successfully queried key\n");
-#endif
- lresult = regkey.SetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
- "1");
- if (lresult == ERROR_SUCCESS)
- printf("Successfully set value for key\n");
- regkey.Close();
- if (lresult == ERROR_SUCCESS)
- printf("Successfully closed key\n");
-// regkey.Write("2");
- }
+ /* Set a couple of settings in the registry for the nVidia detonator driver.
+ * So this is very specific...
+ */
+ if (nVidiaWindows) {
+ LONG lresult;
+ HKEY hkey = 0;
+ DWORD dwd = 0;
+ //unsigned char buffer[128];
+
+ CRegKey regkey;
+ //DWORD keyValue;
+ // lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable");
+ lresult = regkey.Open(HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
+ KEY_ALL_ACCESS);
+
+ if (lresult == ERROR_SUCCESS)
+ printf("Successfully opened key\n");
+# if 0
+ lresult = regkey.QueryValue(&keyValue, "StereoEnable");
+ if (lresult == ERROR_SUCCESS)
+ printf("Successfully queried key\n");
+# endif
+ lresult = regkey.SetValue(
+ HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable", "1");
+ if (lresult == ERROR_SUCCESS)
+ printf("Successfully set value for key\n");
+ regkey.Close();
+ if (lresult == ERROR_SUCCESS)
+ printf("Successfully closed key\n");
+ // regkey.Write("2");
+ }
#endif // WIN32
- // Create the system
- GHOST_ISystem::createSystem();
- fSystem = GHOST_ISystem::getSystem();
+ // Create the system
+ GHOST_ISystem::createSystem();
+ fSystem = GHOST_ISystem::getSystem();
- if (fSystem) {
- // Create an application object
- Application app(fSystem);
+ if (fSystem) {
+ // Create an application object
+ Application app(fSystem);
- // Add the application as event consumer
- fSystem->addEventConsumer(&app);
+ // Add the application as event consumer
+ fSystem->addEventConsumer(&app);
- // Enter main loop
- while (!app.m_exitRequested) {
- //printf("main: loop\n");
- fSystem->processEvents(true);
- fSystem->dispatchEvents();
- }
+ // Enter main loop
+ while (!app.m_exitRequested) {
+ //printf("main: loop\n");
+ fSystem->processEvents(true);
+ fSystem->dispatchEvents();
+ }
- // Remove so ghost doesn't do a double free
- fSystem->removeEventConsumer(&app);
- }
+ // Remove so ghost doesn't do a double free
+ fSystem->removeEventConsumer(&app);
+ }
- // Dispose the system
- GHOST_ISystem::disposeSystem();
+ // Dispose the system
+ GHOST_ISystem::disposeSystem();
- return 0;
+ return 0;
}
-
static void gearsTimerProc(GHOST_ITimerTask *task, GHOST_TUns64 /*time*/)
{
- fAngle += 2.0;
- view_roty += 1.0;
- GHOST_IWindow *window = (GHOST_IWindow *)task->getUserData();
- if (fApp->m_fullScreenWindow) {
- // Running full screen
- fApp->m_fullScreenWindow->invalidate();
- }
- else {
- if (fSystem->validWindow(window)) {
- window->invalidate();
- }
- }
+ fAngle += 2.0;
+ view_roty += 1.0;
+ GHOST_IWindow *window = (GHOST_IWindow *)task->getUserData();
+ if (fApp->m_fullScreenWindow) {
+ // Running full screen
+ fApp->m_fullScreenWindow->invalidate();
+ }
+ else {
+ if (fSystem->validWindow(window)) {
+ window->invalidate();
+ }
+ }
}
diff --git a/intern/ghost/test/multitest/Basic.c b/intern/ghost/test/multitest/Basic.c
index 17f1fc0de48..670c7583fe5 100644
--- a/intern/ghost/test/multitest/Basic.c
+++ b/intern/ghost/test/multitest/Basic.c
@@ -21,45 +21,45 @@
int min_i(int a, int b)
{
- return (a < b) ? a : b;
+ return (a < b) ? a : b;
}
int max_i(int a, int b)
{
- return (b < a) ? a : b;
+ return (b < a) ? a : b;
}
int clamp_i(int val, int min, int max)
{
- return min_i(max_i(val, min), max);
+ return min_i(max_i(val, min), max);
}
float min_f(float a, float b)
{
- return (a < b) ? a : b;
+ return (a < b) ? a : b;
}
float max_f(float a, float b)
{
- return (b < a) ? a : b;
+ return (b < a) ? a : b;
}
float clamp_f(float val, float min, float max)
{
- return min_f(max_f(val, min), max);
+ return min_f(max_f(val, min), max);
}
void rect_copy(int dst[2][2], int src[2][2])
{
- dst[0][0] = src[0][0], dst[0][1] = src[0][1];
- dst[1][0] = src[1][0], dst[1][1] = src[1][1];
+ dst[0][0] = src[0][0], dst[0][1] = src[0][1];
+ dst[1][0] = src[1][0], dst[1][1] = src[1][1];
}
int rect_contains_pt(int rect[2][2], int pt[2])
{
- return ((rect[0][0] <= pt[0] && pt[0] <= rect[1][0]) &&
- (rect[0][1] <= pt[1] && pt[1] <= rect[1][1]));
+ return ((rect[0][0] <= pt[0] && pt[0] <= rect[1][0]) &&
+ (rect[0][1] <= pt[1] && pt[1] <= rect[1][1]));
}
int rect_width(int rect[2][2])
{
- return (rect[1][0] - rect[0][0]);
+ return (rect[1][0] - rect[0][0]);
}
int rect_height(int rect[2][2])
{
- return (rect[1][1] - rect[0][1]);
+ return (rect[1][1] - rect[0][1]);
}
diff --git a/intern/ghost/test/multitest/Basic.h b/intern/ghost/test/multitest/Basic.h
index 16af83be8dd..1557be8433e 100644
--- a/intern/ghost/test/multitest/Basic.h
+++ b/intern/ghost/test/multitest/Basic.h
@@ -17,16 +17,16 @@
* All rights reserved.
*/
-int min_i (int a, int b);
+int min_i(int a, int b);
-int max_i (int a, int b);
-int clamp_i (int val, int min, int max);
+int max_i(int a, int b);
+int clamp_i(int val, int min, int max);
-float min_f (float a, float b);
-float max_f (float a, float b);
-float clamp_f (float val, float min, float max);
+float min_f(float a, float b);
+float max_f(float a, float b);
+float clamp_f(float val, float min, float max);
-void rect_copy (int dst[2][2], int src[2][2]);
-int rect_contains_pt (int rect[2][2], int pt[2]);
-int rect_width (int rect[2][2]);
-int rect_height (int rect[2][2]);
+void rect_copy(int dst[2][2], int src[2][2]);
+int rect_contains_pt(int rect[2][2], int pt[2]);
+int rect_width(int rect[2][2]);
+int rect_height(int rect[2][2]);
diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c
index 4edebec8066..5aee8a50a8d 100644
--- a/intern/ghost/test/multitest/EventToBuf.c
+++ b/intern/ghost/test/multitest/EventToBuf.c
@@ -28,204 +28,215 @@
char *eventtype_to_string(GHOST_TEventType type)
{
- switch (type) {
- case GHOST_kEventCursorMove: return "CursorMove";
- case GHOST_kEventButtonDown: return "ButtonDown";
- case GHOST_kEventButtonUp: return "ButtonUp";
-
- case GHOST_kEventKeyDown: return "KeyDown";
- case GHOST_kEventKeyUp: return "KeyUp";
-
- case GHOST_kEventQuit: return "Quit";
-
- case GHOST_kEventWindowClose: return "WindowClose";
- case GHOST_kEventWindowActivate: return "WindowActivate";
- case GHOST_kEventWindowDeactivate: return "WindowDeactivate";
- case GHOST_kEventWindowUpdate: return "WindowUpdate";
- case GHOST_kEventWindowSize: return "WindowSize";
- default:
- return "<invalid>";
- }
+ switch (type) {
+ case GHOST_kEventCursorMove:
+ return "CursorMove";
+ case GHOST_kEventButtonDown:
+ return "ButtonDown";
+ case GHOST_kEventButtonUp:
+ return "ButtonUp";
+
+ case GHOST_kEventKeyDown:
+ return "KeyDown";
+ case GHOST_kEventKeyUp:
+ return "KeyUp";
+
+ case GHOST_kEventQuit:
+ return "Quit";
+
+ case GHOST_kEventWindowClose:
+ return "WindowClose";
+ case GHOST_kEventWindowActivate:
+ return "WindowActivate";
+ case GHOST_kEventWindowDeactivate:
+ return "WindowDeactivate";
+ case GHOST_kEventWindowUpdate:
+ return "WindowUpdate";
+ case GHOST_kEventWindowSize:
+ return "WindowSize";
+ default:
+ return "<invalid>";
+ }
}
static char *keytype_to_string(GHOST_TKey key)
{
-#define K(key) case GHOST_k##key: return #key;
- switch (key) {
- K(KeyBackSpace);
- K(KeyTab);
- K(KeyLinefeed);
- K(KeyClear);
- K(KeyEnter);
-
- K(KeyEsc);
- K(KeySpace);
- K(KeyQuote);
- K(KeyComma);
- K(KeyMinus);
- K(KeyPeriod);
- K(KeySlash);
-
- K(Key0);
- K(Key1);
- K(Key2);
- K(Key3);
- K(Key4);
- K(Key5);
- K(Key6);
- K(Key7);
- K(Key8);
- K(Key9);
-
- K(KeySemicolon);
- K(KeyEqual);
-
- K(KeyA);
- K(KeyB);
- K(KeyC);
- K(KeyD);
- K(KeyE);
- K(KeyF);
- K(KeyG);
- K(KeyH);
- K(KeyI);
- K(KeyJ);
- K(KeyK);
- K(KeyL);
- K(KeyM);
- K(KeyN);
- K(KeyO);
- K(KeyP);
- K(KeyQ);
- K(KeyR);
- K(KeyS);
- K(KeyT);
- K(KeyU);
- K(KeyV);
- K(KeyW);
- K(KeyX);
- K(KeyY);
- K(KeyZ);
-
- K(KeyLeftBracket);
- K(KeyRightBracket);
- K(KeyBackslash);
- K(KeyAccentGrave);
-
- K(KeyLeftShift);
- K(KeyRightShift);
- K(KeyLeftControl);
- K(KeyRightControl);
- K(KeyLeftAlt);
- K(KeyRightAlt);
- K(KeyOS);
-
- K(KeyCapsLock);
- K(KeyNumLock);
- K(KeyScrollLock);
-
- K(KeyLeftArrow);
- K(KeyRightArrow);
- K(KeyUpArrow);
- K(KeyDownArrow);
-
- K(KeyPrintScreen);
- K(KeyPause);
-
- K(KeyInsert);
- K(KeyDelete);
- K(KeyHome);
- K(KeyEnd);
- K(KeyUpPage);
- K(KeyDownPage);
-
- K(KeyNumpad0);
- K(KeyNumpad1);
- K(KeyNumpad2);
- K(KeyNumpad3);
- K(KeyNumpad4);
- K(KeyNumpad5);
- K(KeyNumpad6);
- K(KeyNumpad7);
- K(KeyNumpad8);
- K(KeyNumpad9);
- K(KeyNumpadPeriod);
- K(KeyNumpadEnter);
- K(KeyNumpadPlus);
- K(KeyNumpadMinus);
- K(KeyNumpadAsterisk);
- K(KeyNumpadSlash);
-
- K(KeyF1);
- K(KeyF2);
- K(KeyF3);
- K(KeyF4);
- K(KeyF5);
- K(KeyF6);
- K(KeyF7);
- K(KeyF8);
- K(KeyF9);
- K(KeyF10);
- K(KeyF11);
- K(KeyF12);
- K(KeyF13);
- K(KeyF14);
- K(KeyF15);
- K(KeyF16);
- K(KeyF17);
- K(KeyF18);
- K(KeyF19);
- K(KeyF20);
- K(KeyF21);
- K(KeyF22);
- K(KeyF23);
- K(KeyF24);
-
- default:
- return "KeyUnknown";
- }
+#define K(key) \
+ case GHOST_k##key: \
+ return #key;
+ switch (key) {
+ K(KeyBackSpace);
+ K(KeyTab);
+ K(KeyLinefeed);
+ K(KeyClear);
+ K(KeyEnter);
+
+ K(KeyEsc);
+ K(KeySpace);
+ K(KeyQuote);
+ K(KeyComma);
+ K(KeyMinus);
+ K(KeyPeriod);
+ K(KeySlash);
+
+ K(Key0);
+ K(Key1);
+ K(Key2);
+ K(Key3);
+ K(Key4);
+ K(Key5);
+ K(Key6);
+ K(Key7);
+ K(Key8);
+ K(Key9);
+
+ K(KeySemicolon);
+ K(KeyEqual);
+
+ K(KeyA);
+ K(KeyB);
+ K(KeyC);
+ K(KeyD);
+ K(KeyE);
+ K(KeyF);
+ K(KeyG);
+ K(KeyH);
+ K(KeyI);
+ K(KeyJ);
+ K(KeyK);
+ K(KeyL);
+ K(KeyM);
+ K(KeyN);
+ K(KeyO);
+ K(KeyP);
+ K(KeyQ);
+ K(KeyR);
+ K(KeyS);
+ K(KeyT);
+ K(KeyU);
+ K(KeyV);
+ K(KeyW);
+ K(KeyX);
+ K(KeyY);
+ K(KeyZ);
+
+ K(KeyLeftBracket);
+ K(KeyRightBracket);
+ K(KeyBackslash);
+ K(KeyAccentGrave);
+
+ K(KeyLeftShift);
+ K(KeyRightShift);
+ K(KeyLeftControl);
+ K(KeyRightControl);
+ K(KeyLeftAlt);
+ K(KeyRightAlt);
+ K(KeyOS);
+
+ K(KeyCapsLock);
+ K(KeyNumLock);
+ K(KeyScrollLock);
+
+ K(KeyLeftArrow);
+ K(KeyRightArrow);
+ K(KeyUpArrow);
+ K(KeyDownArrow);
+
+ K(KeyPrintScreen);
+ K(KeyPause);
+
+ K(KeyInsert);
+ K(KeyDelete);
+ K(KeyHome);
+ K(KeyEnd);
+ K(KeyUpPage);
+ K(KeyDownPage);
+
+ K(KeyNumpad0);
+ K(KeyNumpad1);
+ K(KeyNumpad2);
+ K(KeyNumpad3);
+ K(KeyNumpad4);
+ K(KeyNumpad5);
+ K(KeyNumpad6);
+ K(KeyNumpad7);
+ K(KeyNumpad8);
+ K(KeyNumpad9);
+ K(KeyNumpadPeriod);
+ K(KeyNumpadEnter);
+ K(KeyNumpadPlus);
+ K(KeyNumpadMinus);
+ K(KeyNumpadAsterisk);
+ K(KeyNumpadSlash);
+
+ K(KeyF1);
+ K(KeyF2);
+ K(KeyF3);
+ K(KeyF4);
+ K(KeyF5);
+ K(KeyF6);
+ K(KeyF7);
+ K(KeyF8);
+ K(KeyF9);
+ K(KeyF10);
+ K(KeyF11);
+ K(KeyF12);
+ K(KeyF13);
+ K(KeyF14);
+ K(KeyF15);
+ K(KeyF16);
+ K(KeyF17);
+ K(KeyF18);
+ K(KeyF19);
+ K(KeyF20);
+ K(KeyF21);
+ K(KeyF22);
+ K(KeyF23);
+ K(KeyF24);
+
+ default:
+ return "KeyUnknown";
+ }
#undef K
}
void event_to_buf(GHOST_EventHandle evt, char buf[128])
{
- GHOST_TEventType type = GHOST_GetEventType(evt);
- double time = (double) ((GHOST_TInt64) GHOST_GetEventTime(evt))/1000;
- GHOST_WindowHandle win = GHOST_GetEventWindow(evt);
- void *data = GHOST_GetEventData(evt);
- char *pos = buf;
-
- pos += sprintf(pos, "event: %6.2f, %16s", time, eventtype_to_string(type));
- if (win) {
- char *s = GHOST_GetTitle(win);
- pos += sprintf(pos, " - win: %s", s);
- free(s);
- }
- else {
- pos+= sprintf(pos, " - sys evt");
- }
- switch (type) {
- case GHOST_kEventCursorMove:
- {
- GHOST_TEventCursorData *cd = data;
- pos += sprintf(pos, " - pos: (%d, %d)", cd->x, cd->y);
- break;
- }
- case GHOST_kEventButtonDown:
- case GHOST_kEventButtonUp:
- {
- GHOST_TEventButtonData *bd = data;
- pos += sprintf(pos, " - but: %d", bd->button);
- break;
- }
-
- case GHOST_kEventKeyDown:
- case GHOST_kEventKeyUp:
- {
- GHOST_TEventKeyData *kd = data;
- pos += sprintf(pos, " - key: %s (%d)", keytype_to_string(kd->key), kd->key);
- if (kd->ascii) pos+= sprintf(pos, " ascii: '%c' (%d)", kd->ascii, kd->ascii);
- break;
- }
- }
+ GHOST_TEventType type = GHOST_GetEventType(evt);
+ double time = (double)((GHOST_TInt64)GHOST_GetEventTime(evt)) / 1000;
+ GHOST_WindowHandle win = GHOST_GetEventWindow(evt);
+ void *data = GHOST_GetEventData(evt);
+ char *pos = buf;
+
+ pos += sprintf(pos, "event: %6.2f, %16s", time, eventtype_to_string(type));
+ if (win) {
+ char *s = GHOST_GetTitle(win);
+ pos += sprintf(pos, " - win: %s", s);
+ free(s);
+ }
+ else {
+ pos += sprintf(pos, " - sys evt");
+ }
+ switch (type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd = data;
+ pos += sprintf(pos, " - pos: (%d, %d)", cd->x, cd->y);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd = data;
+ pos += sprintf(pos, " - but: %d", bd->button);
+ break;
+ }
+
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd = data;
+ pos += sprintf(pos, " - key: %s (%d)", keytype_to_string(kd->key), kd->key);
+ if (kd->ascii)
+ pos += sprintf(pos, " ascii: '%c' (%d)", kd->ascii, kd->ascii);
+ break;
+ }
+ }
}
diff --git a/intern/ghost/test/multitest/GL.h b/intern/ghost/test/multitest/GL.h
index 9afa4e22fdb..2a7d95212e1 100644
--- a/intern/ghost/test/multitest/GL.h
+++ b/intern/ghost/test/multitest/GL.h
@@ -19,13 +19,13 @@
#if defined(WIN32) || defined(__APPLE__)
- #ifdef WIN32
- #include <windows.h>
- #include <GL/gl.h>
- #else // WIN32
- // __APPLE__ is defined
- #include <AGL/gl.h>
- #endif // WIN32
-#else // defined(WIN32) || defined(__APPLE__)
- #include <GL/gl.h>
-#endif // defined(WIN32) || defined(__APPLE__)
+# ifdef WIN32
+# include <windows.h>
+# include <GL/gl.h>
+# else // WIN32
+// __APPLE__ is defined
+# include <AGL/gl.h>
+# endif // WIN32
+#else // defined(WIN32) || defined(__APPLE__)
+# include <GL/gl.h>
+#endif // defined(WIN32) || defined(__APPLE__)
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index 8d6a3e94fb7..25e9f6b2bf1 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -19,7 +19,7 @@
#define FALSE 0
#ifdef _MSC_VER
-# pragma warning(disable: 4244 4305)
+# pragma warning(disable : 4244 4305)
#endif
#include <stdlib.h>
@@ -68,56 +68,56 @@ void multitestapp_exit(MultiTestApp *app);
void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, const float col[3], int width)
{
- int ltidx = (side / 2) % 4;
- int dkidx = (ltidx + 1 + (side & 1)) % 4;
- int i, corner;
+ int ltidx = (side / 2) % 4;
+ int dkidx = (ltidx + 1 + (side & 1)) % 4;
+ int i, corner;
- glBegin(GL_LINES);
- for (i = 0; i < width; i++) {
- float ltf = pow(lt[i], 1.0 / 2.2), dkf = pow(dk[i], 1.0 / 2.2);
- float stf = (dkidx > ltidx) ? dkf : ltf;
- int lx = rect[1][0] - i - 1;
- int ly = rect[0][1] + i;
+ glBegin(GL_LINES);
+ for (i = 0; i < width; i++) {
+ float ltf = pow(lt[i], 1.0 / 2.2), dkf = pow(dk[i], 1.0 / 2.2);
+ float stf = (dkidx > ltidx) ? dkf : ltf;
+ int lx = rect[1][0] - i - 1;
+ int ly = rect[0][1] + i;
- glColor3f(col[0] * stf, col[1] * stf, col[2] * stf);
- for (corner = 0; corner < 4; corner++) {
- int x = (corner == 0 || corner == 1) ? (rect[0][0] + i) : (rect[1][0] - i - 1);
- int y = (corner == 0 || corner == 3) ? (rect[0][1] + i) : (rect[1][1] - i - 1);
+ glColor3f(col[0] * stf, col[1] * stf, col[2] * stf);
+ for (corner = 0; corner < 4; corner++) {
+ int x = (corner == 0 || corner == 1) ? (rect[0][0] + i) : (rect[1][0] - i - 1);
+ int y = (corner == 0 || corner == 3) ? (rect[0][1] + i) : (rect[1][1] - i - 1);
- if (ltidx == corner)
- glColor3f(col[0] * ltf, col[1] * ltf, col[2] * ltf);
- if (dkidx == corner)
- glColor3f(col[0] * dkf, col[1] * dkf, col[2] * dkf);
+ if (ltidx == corner)
+ glColor3f(col[0] * ltf, col[1] * ltf, col[2] * ltf);
+ if (dkidx == corner)
+ glColor3f(col[0] * dkf, col[1] * dkf, col[2] * dkf);
- glVertex2i(lx, ly);
- glVertex2i(lx = x, ly = y);
- }
- }
- glEnd();
+ glVertex2i(lx, ly);
+ glVertex2i(lx = x, ly = y);
+ }
+ }
+ glEnd();
- glColor3fv(col);
- glRecti(rect[0][0] + width, rect[0][1] + width, rect[1][0] - width, rect[1][1] - width);
+ glColor3fv(col);
+ glRecti(rect[0][0] + width, rect[0][1] + width, rect[1][0] - width, rect[1][1] - width);
}
void rect_bevel_smooth(int rect[2][2], int width)
{
- float *lt = malloc(sizeof(*lt) * width);
- float *dk = malloc(sizeof(*dk) * width);
- float col[4];
- int i;
+ float *lt = malloc(sizeof(*lt) * width);
+ float *dk = malloc(sizeof(*dk) * width);
+ float col[4];
+ int i;
- for (i = 0; i < width; i++) {
- float v = width - 1 ? ((float) i / (width - 1)) : 0;
- lt[i] = 1.2 + (1.0 - 1.2) * v;
- dk[i] = 0.2 + (1.0 - 0.2) * v;
- }
+ for (i = 0; i < width; i++) {
+ float v = width - 1 ? ((float)i / (width - 1)) : 0;
+ lt[i] = 1.2 + (1.0 - 1.2) * v;
+ dk[i] = 0.2 + (1.0 - 0.2) * v;
+ }
- glGetFloatv(GL_CURRENT_COLOR, col);
+ glGetFloatv(GL_CURRENT_COLOR, col);
- rect_bevel_side(rect, 3, lt, dk, col, width);
+ rect_bevel_side(rect, 3, lt, dk, col, width);
- free(lt);
- free(dk);
+ free(lt);
+ free(dk);
}
/*
@@ -125,218 +125,219 @@ void rect_bevel_smooth(int rect[2][2], int width)
*/
typedef struct {
- MultiTestApp *app;
+ MultiTestApp *app;
- GHOST_WindowHandle win;
+ GHOST_WindowHandle win;
- int size[2];
+ int size[2];
- int lmouse[2], lmbut[3];
+ int lmouse[2], lmbut[3];
- int tmouse[2];
+ int tmouse[2];
} MainWindow;
static void mainwindow_log(MainWindow *mw, char *str)
{
- loggerwindow_log(multitestapp_get_logger(mw->app), str);
+ loggerwindow_log(multitestapp_get_logger(mw->app), str);
}
static void mainwindow_do_draw(MainWindow *mw)
{
- GHOST_ActivateWindowDrawingContext(mw->win);
+ GHOST_ActivateWindowDrawingContext(mw->win);
- if (mw->lmbut[0]) {
- glClearColor(0.5, 0.5, 0.5, 1);
- }
- else {
- glClearColor(1, 1, 1, 1);
- }
- glClear(GL_COLOR_BUFFER_BIT);
+ if (mw->lmbut[0]) {
+ glClearColor(0.5, 0.5, 0.5, 1);
+ }
+ else {
+ glClearColor(1, 1, 1, 1);
+ }
+ glClear(GL_COLOR_BUFFER_BIT);
- glColor3f(0.5, 0.6, 0.8);
- glRecti(mw->tmouse[0] - 5, mw->tmouse[1] - 5, mw->tmouse[0] + 5, mw->tmouse[1] + 5);
+ glColor3f(0.5, 0.6, 0.8);
+ glRecti(mw->tmouse[0] - 5, mw->tmouse[1] - 5, mw->tmouse[0] + 5, mw->tmouse[1] + 5);
- GHOST_SwapWindowBuffers(mw->win);
+ GHOST_SwapWindowBuffers(mw->win);
}
static void mainwindow_do_reshape(MainWindow *mw)
{
- GHOST_RectangleHandle bounds = GHOST_GetClientBounds(mw->win);
+ GHOST_RectangleHandle bounds = GHOST_GetClientBounds(mw->win);
- GHOST_ActivateWindowDrawingContext(mw->win);
+ GHOST_ActivateWindowDrawingContext(mw->win);
- mw->size[0] = GHOST_GetWidthRectangle(bounds);
- mw->size[1] = GHOST_GetHeightRectangle(bounds);
+ mw->size[0] = GHOST_GetWidthRectangle(bounds);
+ mw->size[1] = GHOST_GetHeightRectangle(bounds);
- glViewport(0, 0, mw->size[0], mw->size[1]);
+ glViewport(0, 0, mw->size[0], mw->size[1]);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1);
- glTranslatef(0.375, 0.375, 0.0);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
}
static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press)
{
- switch (key) {
- case GHOST_kKeyC:
- if (press)
- GHOST_SetCursorShape(mw->win, (GHOST_TStandardCursor) (rand() % (GHOST_kStandardCursorNumCursors)));
- break;
- case GHOST_kKeyLeftBracket:
- if (press)
- GHOST_SetCursorVisibility(mw->win, 0);
- break;
- case GHOST_kKeyRightBracket:
- if (press)
- GHOST_SetCursorVisibility(mw->win, 1);
- break;
- case GHOST_kKeyE:
- if (press)
- multitestapp_toggle_extra_window(mw->app);
- break;
- case GHOST_kKeyQ:
- if (press)
- multitestapp_exit(mw->app);
- break;
- case GHOST_kKeyT:
- if (press)
- mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/");
- break;
- case GHOST_kKeyR:
- if (press) {
- int i;
-
- mainwindow_log(mw, "Invalidating window 10 times");
- for (i = 0; i < 10; i++)
- GHOST_InvalidateWindow(mw->win);
- }
- break;
- case GHOST_kKeyF11:
- if (press) {
- GHOST_SetWindowOrder(mw->win, GHOST_kWindowOrderBottom);
- }
- break;
- }
+ switch (key) {
+ case GHOST_kKeyC:
+ if (press)
+ GHOST_SetCursorShape(mw->win,
+ (GHOST_TStandardCursor)(rand() % (GHOST_kStandardCursorNumCursors)));
+ break;
+ case GHOST_kKeyLeftBracket:
+ if (press)
+ GHOST_SetCursorVisibility(mw->win, 0);
+ break;
+ case GHOST_kKeyRightBracket:
+ if (press)
+ GHOST_SetCursorVisibility(mw->win, 1);
+ break;
+ case GHOST_kKeyE:
+ if (press)
+ multitestapp_toggle_extra_window(mw->app);
+ break;
+ case GHOST_kKeyQ:
+ if (press)
+ multitestapp_exit(mw->app);
+ break;
+ case GHOST_kKeyT:
+ if (press)
+ mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/");
+ break;
+ case GHOST_kKeyR:
+ if (press) {
+ int i;
+
+ mainwindow_log(mw, "Invalidating window 10 times");
+ for (i = 0; i < 10; i++)
+ GHOST_InvalidateWindow(mw->win);
+ }
+ break;
+ case GHOST_kKeyF11:
+ if (press) {
+ GHOST_SetWindowOrder(mw->win, GHOST_kWindowOrderBottom);
+ }
+ break;
+ }
}
static void mainwindow_do_move(MainWindow *mw, int x, int y)
{
- mw->lmouse[0] = x, mw->lmouse[1] = y;
+ mw->lmouse[0] = x, mw->lmouse[1] = y;
- if (mw->lmbut[0]) {
- mw->tmouse[0] = x, mw->tmouse[1] = y;
- GHOST_InvalidateWindow(mw->win);
- }
+ if (mw->lmbut[0]) {
+ mw->tmouse[0] = x, mw->tmouse[1] = y;
+ GHOST_InvalidateWindow(mw->win);
+ }
}
static void mainwindow_do_button(MainWindow *mw, int which, int press)
{
- if (which == GHOST_kButtonMaskLeft) {
- mw->lmbut[0] = press;
- mw->tmouse[0] = mw->lmouse[0], mw->tmouse[1] = mw->lmouse[1];
- GHOST_InvalidateWindow(mw->win);
- }
- else if (which == GHOST_kButtonMaskLeft) {
- mw->lmbut[1] = press;
- }
- else if (which == GHOST_kButtonMaskLeft) {
- mw->lmbut[2] = press;
- }
+ if (which == GHOST_kButtonMaskLeft) {
+ mw->lmbut[0] = press;
+ mw->tmouse[0] = mw->lmouse[0], mw->tmouse[1] = mw->lmouse[1];
+ GHOST_InvalidateWindow(mw->win);
+ }
+ else if (which == GHOST_kButtonMaskLeft) {
+ mw->lmbut[1] = press;
+ }
+ else if (which == GHOST_kButtonMaskLeft) {
+ mw->lmbut[2] = press;
+ }
}
static void mainwindow_handle(void *priv, GHOST_EventHandle evt)
{
- MainWindow *mw = priv;
- GHOST_TEventType type = GHOST_GetEventType(evt);
- char buf[256];
-
- event_to_buf(evt, buf);
- mainwindow_log(mw, buf);
-
- switch (type) {
- case GHOST_kEventCursorMove:
- {
- GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
- int x, y;
- GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y);
- mainwindow_do_move(mw, x, mw->size[1] - y - 1);
- break;
- }
- case GHOST_kEventButtonDown:
- case GHOST_kEventButtonUp:
- {
- GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
- mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown));
- break;
- }
- case GHOST_kEventKeyDown:
- case GHOST_kEventKeyUp:
- {
- GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
- mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown));
- break;
- }
-
- case GHOST_kEventWindowUpdate:
- mainwindow_do_draw(mw);
- break;
- case GHOST_kEventWindowSize:
- mainwindow_do_reshape(mw);
- break;
- }
+ MainWindow *mw = priv;
+ GHOST_TEventType type = GHOST_GetEventType(evt);
+ char buf[256];
+
+ event_to_buf(evt, buf);
+ mainwindow_log(mw, buf);
+
+ switch (type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
+ int x, y;
+ GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y);
+ mainwindow_do_move(mw, x, mw->size[1] - y - 1);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
+ mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown));
+ break;
+ }
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
+ mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventWindowUpdate:
+ mainwindow_do_draw(mw);
+ break;
+ case GHOST_kEventWindowSize:
+ mainwindow_do_reshape(mw);
+ break;
+ }
}
/**/
static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
{
- MainWindow *mw = GHOST_GetTimerTaskUserData(task);
- char buf[64];
+ MainWindow *mw = GHOST_GetTimerTaskUserData(task);
+ char buf[64];
- sprintf(buf, "timer: %6.2f", (double) ((GHOST_TInt64) time) / 1000);
- mainwindow_log(mw, buf);
+ sprintf(buf, "timer: %6.2f", (double)((GHOST_TInt64)time) / 1000);
+ mainwindow_log(mw, buf);
}
MainWindow *mainwindow_new(MultiTestApp *app)
{
- GHOST_SystemHandle sys = multitestapp_get_system(app);
- GHOST_WindowHandle win;
- GHOST_GLSettings glSettings = {0};
+ GHOST_SystemHandle sys = multitestapp_get_system(app);
+ GHOST_WindowHandle win;
+ GHOST_GLSettings glSettings = {0};
- win = GHOST_CreateWindow(
- sys, "MultiTest:Main",
- 40, 40, 400, 400,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
+ win = GHOST_CreateWindow(sys,
+ "MultiTest:Main",
+ 40,
+ 40,
+ 400,
+ 400,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
- if (win) {
- MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
- mw->app = app;
- mw->win = win;
+ if (win) {
+ MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
+ mw->app = app;
+ mw->win = win;
- GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle));
+ GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle));
- GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw);
+ GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw);
- return mw;
- }
- else {
- return NULL;
- }
+ return mw;
+ }
+ else {
+ return NULL;
+ }
}
void mainwindow_free(MainWindow *mw)
{
- GHOST_SystemHandle sys = multitestapp_get_system(mw->app);
+ GHOST_SystemHandle sys = multitestapp_get_system(mw->app);
- windowdata_free(GHOST_GetWindowUserData(mw->win));
- GHOST_DisposeWindow(sys, mw->win);
- MEM_freeN(mw);
+ windowdata_free(GHOST_GetWindowUserData(mw->win));
+ GHOST_DisposeWindow(sys, mw->win);
+ MEM_freeN(mw);
}
/*
@@ -344,29 +345,29 @@ void mainwindow_free(MainWindow *mw)
*/
struct _LoggerWindow {
- MultiTestApp *app;
+ MultiTestApp *app;
- GHOST_WindowHandle win;
+ GHOST_WindowHandle win;
#ifdef USE_BMF
- BMF_Font *font;
+ BMF_Font *font;
#else
- int font;
+ int font;
#endif
- int fonttexid;
- int fontheight;
+ int fonttexid;
+ int fontheight;
- int size[2];
+ int size[2];
- int ndisplines;
- int textarea[2][2];
- ScrollBar *scroll;
+ int ndisplines;
+ int textarea[2][2];
+ ScrollBar *scroll;
- char **loglines;
- int nloglines, logsize;
+ char **loglines;
+ int nloglines, logsize;
- int lmbut[3];
- int lmouse[2];
+ int lmbut[3];
+ int lmouse[2];
};
#define SCROLLBAR_PAD 2
@@ -374,443 +375,443 @@ struct _LoggerWindow {
#define TEXTAREA_PAD 2
static void loggerwindow_recalc_regions(LoggerWindow *lw)
{
- int nscroll[2][2];
+ int nscroll[2][2];
- nscroll[0][0] = SCROLLBAR_PAD;
- nscroll[0][1] = SCROLLBAR_PAD;
- nscroll[1][0] = nscroll[0][0] + SCROLLBAR_WIDTH;
- nscroll[1][1] = lw->size[1] - SCROLLBAR_PAD - 1;
+ nscroll[0][0] = SCROLLBAR_PAD;
+ nscroll[0][1] = SCROLLBAR_PAD;
+ nscroll[1][0] = nscroll[0][0] + SCROLLBAR_WIDTH;
+ nscroll[1][1] = lw->size[1] - SCROLLBAR_PAD - 1;
- lw->textarea[0][0] = nscroll[1][0] + TEXTAREA_PAD;
- lw->textarea[0][1] = TEXTAREA_PAD;
- lw->textarea[1][0] = lw->size[0] - TEXTAREA_PAD - 1;
- lw->textarea[1][1] = lw->size[1] - TEXTAREA_PAD - 1;
+ lw->textarea[0][0] = nscroll[1][0] + TEXTAREA_PAD;
+ lw->textarea[0][1] = TEXTAREA_PAD;
+ lw->textarea[1][0] = lw->size[0] - TEXTAREA_PAD - 1;
+ lw->textarea[1][1] = lw->size[1] - TEXTAREA_PAD - 1;
- lw->ndisplines = (lw->textarea[1][1] - lw->textarea[0][1]) / lw->fontheight;
+ lw->ndisplines = (lw->textarea[1][1] - lw->textarea[0][1]) / lw->fontheight;
- scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines / lw->nloglines);
- scrollbar_set_rect(lw->scroll, nscroll);
+ scrollbar_set_thumbpct(lw->scroll, (float)lw->ndisplines / lw->nloglines);
+ scrollbar_set_rect(lw->scroll, nscroll);
}
static void loggerwindow_setup_window_gl(LoggerWindow *lw)
{
- glViewport(0, 0, lw->size[0], lw->size[1]);
+ glViewport(0, 0, lw->size[0], lw->size[1]);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1);
- glTranslatef(0.375, 0.375, 0.0);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
}
static void loggerwindow_do_reshape(LoggerWindow *lw)
{
- GHOST_RectangleHandle bounds = GHOST_GetClientBounds(lw->win);
+ GHOST_RectangleHandle bounds = GHOST_GetClientBounds(lw->win);
- GHOST_ActivateWindowDrawingContext(lw->win);
+ GHOST_ActivateWindowDrawingContext(lw->win);
- lw->size[0] = GHOST_GetWidthRectangle(bounds);
- lw->size[1] = GHOST_GetHeightRectangle(bounds);
+ lw->size[0] = GHOST_GetWidthRectangle(bounds);
+ lw->size[1] = GHOST_GetHeightRectangle(bounds);
- loggerwindow_recalc_regions(lw);
- loggerwindow_setup_window_gl(lw);
+ loggerwindow_recalc_regions(lw);
+ loggerwindow_setup_window_gl(lw);
}
static void loggerwindow_do_draw(LoggerWindow *lw)
{
- int i, ndisplines, startline;
- int sb_rect[2][2], sb_thumb[2][2];
+ int i, ndisplines, startline;
+ int sb_rect[2][2], sb_thumb[2][2];
- GHOST_ActivateWindowDrawingContext(lw->win);
+ GHOST_ActivateWindowDrawingContext(lw->win);
- glClearColor(1, 1, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
- glColor3f(0.8, 0.8, 0.8);
- rect_bevel_smooth(lw->textarea, 4);
+ glColor3f(0.8, 0.8, 0.8);
+ rect_bevel_smooth(lw->textarea, 4);
- scrollbar_get_rect(lw->scroll, sb_rect);
- scrollbar_get_thumb(lw->scroll, sb_thumb);
+ scrollbar_get_rect(lw->scroll, sb_rect);
+ scrollbar_get_thumb(lw->scroll, sb_thumb);
- glColor3f(0.6, 0.6, 0.6);
- rect_bevel_smooth(sb_rect, 1);
+ glColor3f(0.6, 0.6, 0.6);
+ rect_bevel_smooth(sb_rect, 1);
- if (scrollbar_is_scrolling(lw->scroll)) {
- glColor3f(0.6, 0.7, 0.5);
- }
- else {
- glColor3f(0.9, 0.9, 0.92);
- }
- rect_bevel_smooth(sb_thumb, 1);
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ glColor3f(0.6, 0.7, 0.5);
+ }
+ else {
+ glColor3f(0.9, 0.9, 0.92);
+ }
+ rect_bevel_smooth(sb_thumb, 1);
- startline = scrollbar_get_thumbpos(lw->scroll) * (lw->nloglines - 1);
- ndisplines = min_i(lw->ndisplines, lw->nloglines - startline);
+ startline = scrollbar_get_thumbpos(lw->scroll) * (lw->nloglines - 1);
+ ndisplines = min_i(lw->ndisplines, lw->nloglines - startline);
- if (lw->fonttexid != -1) {
- glBindTexture(GL_TEXTURE_2D, lw->fonttexid);
+ if (lw->fonttexid != -1) {
+ glBindTexture(GL_TEXTURE_2D, lw->fonttexid);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- }
- glColor3f(0, 0, 0);
- for (i = 0; i < ndisplines; i++) {
- /* stored in reverse order */
- char *line = lw->loglines[(lw->nloglines - 1) - (i + startline)];
- int x_pos = lw->textarea[0][0] + 4;
- int y_pos = lw->textarea[0][1] + 4 + i * lw->fontheight;
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ }
+ glColor3f(0, 0, 0);
+ for (i = 0; i < ndisplines; i++) {
+ /* stored in reverse order */
+ char *line = lw->loglines[(lw->nloglines - 1) - (i + startline)];
+ int x_pos = lw->textarea[0][0] + 4;
+ int y_pos = lw->textarea[0][1] + 4 + i * lw->fontheight;
#ifdef USE_BMF
- if (lw->fonttexid == -1) {
- glRasterPos2i(x_pos, y_pos);
- BMF_DrawString(lw->font, line);
- }
- else {
- BMF_DrawStringTexture(lw->font, line, x_pos, y_pos, 0.0);
- }
+ if (lw->fonttexid == -1) {
+ glRasterPos2i(x_pos, y_pos);
+ BMF_DrawString(lw->font, line);
+ }
+ else {
+ BMF_DrawStringTexture(lw->font, line, x_pos, y_pos, 0.0);
+ }
#else
- BLF_position(lw->font, x_pos, y_pos, 0.0);
- BLF_draw(lw->font, line, 256); // XXX
+ BLF_position(lw->font, x_pos, y_pos, 0.0);
+ BLF_draw(lw->font, line, 256); // XXX
#endif
- }
+ }
#ifdef USE_BMF
- if (lw->fonttexid != -1) {
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- }
+ if (lw->fonttexid != -1) {
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ }
#endif
- GHOST_SwapWindowBuffers(lw->win);
+ GHOST_SwapWindowBuffers(lw->win);
}
static void loggerwindow_do_move(LoggerWindow *lw, int x, int y)
{
- lw->lmouse[0] = x, lw->lmouse[1] = y;
+ lw->lmouse[0] = x, lw->lmouse[1] = y;
- if (scrollbar_is_scrolling(lw->scroll)) {
- scrollbar_keep_scrolling(lw->scroll, y);
- GHOST_InvalidateWindow(lw->win);
- }
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ scrollbar_keep_scrolling(lw->scroll, y);
+ GHOST_InvalidateWindow(lw->win);
+ }
}
static void loggerwindow_do_button(LoggerWindow *lw, int which, int press)
{
- if (which == GHOST_kButtonMaskLeft) {
- lw->lmbut[0] = press;
-
- if (press) {
- if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) {
- scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);
- GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown);
- GHOST_InvalidateWindow(lw->win);
- }
- }
- else {
- if (scrollbar_is_scrolling(lw->scroll)) {
- scrollbar_stop_scrolling(lw->scroll);
- GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorDefault);
- GHOST_InvalidateWindow(lw->win);
- }
- }
- }
- else if (which == GHOST_kButtonMaskMiddle) {
- lw->lmbut[1] = press;
- }
- else if (which == GHOST_kButtonMaskRight) {
- lw->lmbut[2] = press;
- }
+ if (which == GHOST_kButtonMaskLeft) {
+ lw->lmbut[0] = press;
+
+ if (press) {
+ if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) {
+ scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);
+ GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown);
+ GHOST_InvalidateWindow(lw->win);
+ }
+ }
+ else {
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ scrollbar_stop_scrolling(lw->scroll);
+ GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorDefault);
+ GHOST_InvalidateWindow(lw->win);
+ }
+ }
+ }
+ else if (which == GHOST_kButtonMaskMiddle) {
+ lw->lmbut[1] = press;
+ }
+ else if (which == GHOST_kButtonMaskRight) {
+ lw->lmbut[2] = press;
+ }
}
static void loggerwindow_do_key(LoggerWindow *lw, GHOST_TKey key, int press)
{
- switch (key) {
- case GHOST_kKeyQ:
- if (press)
- multitestapp_exit(lw->app);
- break;
- }
+ switch (key) {
+ case GHOST_kKeyQ:
+ if (press)
+ multitestapp_exit(lw->app);
+ break;
+ }
}
static void loggerwindow_handle(void *priv, GHOST_EventHandle evt)
{
- LoggerWindow *lw = priv;
- GHOST_TEventType type = GHOST_GetEventType(evt);
-
- switch (type) {
- case GHOST_kEventCursorMove:
- {
- GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
- int x, y;
- GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y);
- loggerwindow_do_move(lw, x, lw->size[1] - y - 1);
- break;
- }
- case GHOST_kEventButtonDown:
- case GHOST_kEventButtonUp:
- {
- GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
- loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown));
- break;
- }
- case GHOST_kEventKeyDown:
- case GHOST_kEventKeyUp:
- {
- GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
- loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown));
- break;
- }
-
- case GHOST_kEventWindowUpdate:
- loggerwindow_do_draw(lw);
- break;
- case GHOST_kEventWindowSize:
- loggerwindow_do_reshape(lw);
- break;
- }
+ LoggerWindow *lw = priv;
+ GHOST_TEventType type = GHOST_GetEventType(evt);
+
+ switch (type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
+ int x, y;
+ GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y);
+ loggerwindow_do_move(lw, x, lw->size[1] - y - 1);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
+ loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown));
+ break;
+ }
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
+ loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventWindowUpdate:
+ loggerwindow_do_draw(lw);
+ break;
+ case GHOST_kEventWindowSize:
+ loggerwindow_do_reshape(lw);
+ break;
+ }
}
/**/
LoggerWindow *loggerwindow_new(MultiTestApp *app)
{
- GHOST_GLSettings glSettings = {0};
- GHOST_SystemHandle sys = multitestapp_get_system(app);
- GHOST_TUns32 screensize[2];
- GHOST_WindowHandle win;
-
- GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]);
- win = GHOST_CreateWindow(
- sys, "MultiTest:Logger",
- 40, screensize[1] - 432, 800, 300,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
-
- if (win) {
- LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
- int bbox[2][2];
- lw->app = app;
- lw->win = win;
+ GHOST_GLSettings glSettings = {0};
+ GHOST_SystemHandle sys = multitestapp_get_system(app);
+ GHOST_TUns32 screensize[2];
+ GHOST_WindowHandle win;
+
+ GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]);
+ win = GHOST_CreateWindow(sys,
+ "MultiTest:Logger",
+ 40,
+ screensize[1] - 432,
+ 800,
+ 300,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
+
+ if (win) {
+ LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
+ int bbox[2][2];
+ lw->app = app;
+ lw->win = win;
#ifdef USE_BMF
- lw->font = BMF_GetFont(BMF_kScreen12);
- lw->fonttexid = BMF_GetFontTexture(lw->font);
+ lw->font = BMF_GetFont(BMF_kScreen12);
+ lw->fonttexid = BMF_GetFontTexture(lw->font);
- BMF_GetBoundingBox(lw->font, &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1]);
- lw->fontheight = rect_height(bbox);
+ BMF_GetBoundingBox(lw->font, &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1]);
+ lw->fontheight = rect_height(bbox);
#else
- lw->font = BLF_load_mem("default", (unsigned char *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
- BLF_size(lw->font, 11, 72);
- lw->fontheight = BLF_height(lw->font, "A_", 2);
+ lw->font = BLF_load_mem("default", (unsigned char *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
+ BLF_size(lw->font, 11, 72);
+ lw->fontheight = BLF_height(lw->font, "A_", 2);
#endif
- lw->nloglines = lw->logsize = 0;
- lw->loglines = MEM_mallocN(sizeof(*lw->loglines) * lw->nloglines, "loglines");
+ lw->nloglines = lw->logsize = 0;
+ lw->loglines = MEM_mallocN(sizeof(*lw->loglines) * lw->nloglines, "loglines");
- lw->scroll = scrollbar_new(2, 40);
+ lw->scroll = scrollbar_new(2, 40);
- GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle));
+ GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle));
- loggerwindow_do_reshape(lw);
+ loggerwindow_do_reshape(lw);
- return lw;
- }
- else {
- return NULL;
- }
+ return lw;
+ }
+ else {
+ return NULL;
+ }
}
void loggerwindow_log(LoggerWindow *lw, char *line)
{
- if (lw->nloglines == lw->logsize) {
- lw->loglines = memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines));
- }
+ if (lw->nloglines == lw->logsize) {
+ lw->loglines = memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines));
+ }
- lw->loglines[lw->nloglines++] = string_dup(line);
- scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines / lw->nloglines);
+ lw->loglines[lw->nloglines++] = string_dup(line);
+ scrollbar_set_thumbpct(lw->scroll, (float)lw->ndisplines / lw->nloglines);
- GHOST_InvalidateWindow(lw->win);
+ GHOST_InvalidateWindow(lw->win);
}
void loggerwindow_free(LoggerWindow *lw)
{
- GHOST_SystemHandle sys = multitestapp_get_system(lw->app);
- int i;
+ GHOST_SystemHandle sys = multitestapp_get_system(lw->app);
+ int i;
- for (i = 0; i < lw->nloglines; i++) {
- MEM_freeN(lw->loglines[i]);
- }
- MEM_freeN(lw->loglines);
+ for (i = 0; i < lw->nloglines; i++) {
+ MEM_freeN(lw->loglines[i]);
+ }
+ MEM_freeN(lw->loglines);
- windowdata_free(GHOST_GetWindowUserData(lw->win));
- GHOST_DisposeWindow(sys, lw->win);
- MEM_freeN(lw);
+ windowdata_free(GHOST_GetWindowUserData(lw->win));
+ GHOST_DisposeWindow(sys, lw->win);
+ MEM_freeN(lw);
}
/*
* ExtraWindow
*/
-
typedef struct {
- MultiTestApp *app;
+ MultiTestApp *app;
- GHOST_WindowHandle win;
+ GHOST_WindowHandle win;
- int size[2];
+ int size[2];
} ExtraWindow;
static void extrawindow_do_draw(ExtraWindow *ew)
{
- GHOST_ActivateWindowDrawingContext(ew->win);
+ GHOST_ActivateWindowDrawingContext(ew->win);
- glClearColor(1, 1, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
- glColor3f(0.8, 0.8, 0.8);
- glRecti(10, 10, ew->size[0] - 10, ew->size[1] - 10);
+ glColor3f(0.8, 0.8, 0.8);
+ glRecti(10, 10, ew->size[0] - 10, ew->size[1] - 10);
- GHOST_SwapWindowBuffers(ew->win);
+ GHOST_SwapWindowBuffers(ew->win);
}
static void extrawindow_do_reshape(ExtraWindow *ew)
{
- GHOST_RectangleHandle bounds = GHOST_GetClientBounds(ew->win);
+ GHOST_RectangleHandle bounds = GHOST_GetClientBounds(ew->win);
- GHOST_ActivateWindowDrawingContext(ew->win);
+ GHOST_ActivateWindowDrawingContext(ew->win);
- ew->size[0] = GHOST_GetWidthRectangle(bounds);
- ew->size[1] = GHOST_GetHeightRectangle(bounds);
+ ew->size[0] = GHOST_GetWidthRectangle(bounds);
+ ew->size[1] = GHOST_GetHeightRectangle(bounds);
- glViewport(0, 0, ew->size[0], ew->size[1]);
+ glViewport(0, 0, ew->size[0], ew->size[1]);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1);
- glTranslatef(0.375, 0.375, 0.0);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
}
static void extrawindow_do_key(ExtraWindow *ew, GHOST_TKey key, int press)
{
- switch (key) {
- case GHOST_kKeyE:
- if (press)
- multitestapp_toggle_extra_window(ew->app);
- break;
- }
+ switch (key) {
+ case GHOST_kKeyE:
+ if (press)
+ multitestapp_toggle_extra_window(ew->app);
+ break;
+ }
}
static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time)
{
- GHOST_TUns8 bitmap[16][2];
- GHOST_TUns8 mask[16][2];
- double ftime = (double) ((GHOST_TInt64) time) / 1000;
- float angle = fmod(ftime, 1.0) * 3.1415 * 2;
- int i;
+ GHOST_TUns8 bitmap[16][2];
+ GHOST_TUns8 mask[16][2];
+ double ftime = (double)((GHOST_TInt64)time) / 1000;
+ float angle = fmod(ftime, 1.0) * 3.1415 * 2;
+ int i;
- memset(&bitmap, 0, sizeof(bitmap));
- memset(&mask, 0, sizeof(mask));
+ memset(&bitmap, 0, sizeof(bitmap));
+ memset(&mask, 0, sizeof(mask));
- bitmap[0][0] |= mask[0][0] |= 0xF;
- bitmap[1][0] |= mask[1][0] |= 0xF;
- bitmap[2][0] |= mask[2][0] |= 0xF;
- bitmap[3][0] |= mask[3][0] |= 0xF;
+ bitmap[0][0] |= mask[0][0] |= 0xF;
+ bitmap[1][0] |= mask[1][0] |= 0xF;
+ bitmap[2][0] |= mask[2][0] |= 0xF;
+ bitmap[3][0] |= mask[3][0] |= 0xF;
- for (i = 0; i < 7; i++) {
- int x = 7 + cos(angle) * i;
- int y = 7 + sin(angle) * i;
+ for (i = 0; i < 7; i++) {
+ int x = 7 + cos(angle) * i;
+ int y = 7 + sin(angle) * i;
- mask[y][x / 8] |= (1 << (x % 8));
- }
- for (i = 0; i < 64; i++) {
- float v = (i / 63.0) * 3.1415 * 2;
- int x = 7 + cos(v) * 7;
- int y = 7 + sin(v) * 7;
+ mask[y][x / 8] |= (1 << (x % 8));
+ }
+ for (i = 0; i < 64; i++) {
+ float v = (i / 63.0) * 3.1415 * 2;
+ int x = 7 + cos(v) * 7;
+ int y = 7 + sin(v) * 7;
- mask[y][x / 8] |= (1 << (x % 8));
- }
+ mask[y][x / 8] |= (1 << (x % 8));
+ }
- GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0);
+ GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0);
}
static void extrawindow_handle(void *priv, GHOST_EventHandle evt)
{
- ExtraWindow *ew = priv;
- GHOST_TEventType type = GHOST_GetEventType(evt);
- char buf[256];
-
- event_to_buf(evt, buf);
- loggerwindow_log(multitestapp_get_logger(ew->app), buf);
-
- switch (type) {
- case GHOST_kEventKeyDown:
- case GHOST_kEventKeyUp:
- {
- GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
- extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown));
- break;
- }
-
- case GHOST_kEventCursorMove:
- {
- extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt));
- break;
- }
-
- case GHOST_kEventWindowClose:
- multitestapp_free_extrawindow(ew->app);
- break;
- case GHOST_kEventWindowUpdate:
- extrawindow_do_draw(ew);
- break;
- case GHOST_kEventWindowSize:
- extrawindow_do_reshape(ew);
- break;
- }
+ ExtraWindow *ew = priv;
+ GHOST_TEventType type = GHOST_GetEventType(evt);
+ char buf[256];
+
+ event_to_buf(evt, buf);
+ loggerwindow_log(multitestapp_get_logger(ew->app), buf);
+
+ switch (type) {
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
+ extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventCursorMove: {
+ extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt));
+ break;
+ }
+
+ case GHOST_kEventWindowClose:
+ multitestapp_free_extrawindow(ew->app);
+ break;
+ case GHOST_kEventWindowUpdate:
+ extrawindow_do_draw(ew);
+ break;
+ case GHOST_kEventWindowSize:
+ extrawindow_do_reshape(ew);
+ break;
+ }
}
/**/
ExtraWindow *extrawindow_new(MultiTestApp *app)
{
- GHOST_GLSettings glSettings = {0};
- GHOST_SystemHandle sys = multitestapp_get_system(app);
- GHOST_WindowHandle win;
+ GHOST_GLSettings glSettings = {0};
+ GHOST_SystemHandle sys = multitestapp_get_system(app);
+ GHOST_WindowHandle win;
- win = GHOST_CreateWindow(
- sys, "MultiTest:Extra",
- 500, 40, 400, 400,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
+ win = GHOST_CreateWindow(sys,
+ "MultiTest:Extra",
+ 500,
+ 40,
+ 400,
+ 400,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
- if (win) {
- ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");
- ew->app = app;
- ew->win = win;
+ if (win) {
+ ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");
+ ew->app = app;
+ ew->win = win;
- GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle));
+ GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle));
- return ew;
- }
- else {
- return NULL;
- }
+ return ew;
+ }
+ else {
+ return NULL;
+ }
}
void extrawindow_free(ExtraWindow *ew)
{
- GHOST_SystemHandle sys = multitestapp_get_system(ew->app);
+ GHOST_SystemHandle sys = multitestapp_get_system(ew->app);
- windowdata_free(GHOST_GetWindowUserData(ew->win));
- GHOST_DisposeWindow(sys, ew->win);
- MEM_freeN(ew);
+ windowdata_free(GHOST_GetWindowUserData(ew->win));
+ GHOST_DisposeWindow(sys, ew->win);
+ MEM_freeN(ew);
}
/*
@@ -818,136 +819,139 @@ void extrawindow_free(ExtraWindow *ew)
*/
struct _MultiTestApp {
- GHOST_SystemHandle sys;
- MainWindow *main;
- LoggerWindow *logger;
- ExtraWindow *extra;
+ GHOST_SystemHandle sys;
+ MainWindow *main;
+ LoggerWindow *logger;
+ ExtraWindow *extra;
- int exit;
+ int exit;
};
static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data)
{
- MultiTestApp *app = data;
- GHOST_WindowHandle win;
+ MultiTestApp *app = data;
+ GHOST_WindowHandle win;
- win = GHOST_GetEventWindow(evt);
- if (win && !GHOST_ValidWindow(app->sys, win)) {
- loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
- return 1;
- }
+ win = GHOST_GetEventWindow(evt);
+ if (win && !GHOST_ValidWindow(app->sys, win)) {
+ loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
+ return 1;
+ }
- if (win) {
- WindowData *wb = GHOST_GetWindowUserData(win);
+ if (win) {
+ WindowData *wb = GHOST_GetWindowUserData(win);
- windowdata_handle(wb, evt);
- }
- else {
- GHOST_TEventType type = GHOST_GetEventType(evt);
+ windowdata_handle(wb, evt);
+ }
+ else {
+ GHOST_TEventType type = GHOST_GetEventType(evt);
- /* GHOST_kEventQuit are the only 'system' events,
- * that is, events without a window.
- */
- switch (type) {
- case GHOST_kEventQuit:
- app->exit = 1;
- break;
+ /* GHOST_kEventQuit are the only 'system' events,
+ * that is, events without a window.
+ */
+ switch (type) {
+ case GHOST_kEventQuit:
+ app->exit = 1;
+ break;
- default:
- fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type));
- break;
- }
- }
+ default:
+ fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type));
+ break;
+ }
+ }
- return 1;
+ return 1;
}
/**/
-MultiTestApp *multitestapp_new(void) {
- MultiTestApp *app = MEM_mallocN(sizeof(*app), "multitestapp_new");
- GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(multitest_event_handler, app);
+MultiTestApp *multitestapp_new(void)
+{
+ MultiTestApp *app = MEM_mallocN(sizeof(*app), "multitestapp_new");
+ GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(multitest_event_handler, app);
- app->sys = GHOST_CreateSystem();
- if (!app->sys)
- fatal("Unable to create ghost system");
+ app->sys = GHOST_CreateSystem();
+ if (!app->sys)
+ fatal("Unable to create ghost system");
- if (!GHOST_AddEventConsumer(app->sys, consumer))
- fatal("Unable to add multitest event consumer ");
+ if (!GHOST_AddEventConsumer(app->sys, consumer))
+ fatal("Unable to add multitest event consumer ");
- app->main = mainwindow_new(app);
- if (!app->main)
- fatal("Unable to create main window");
+ app->main = mainwindow_new(app);
+ if (!app->main)
+ fatal("Unable to create main window");
- app->logger = loggerwindow_new(app);
- if (!app->logger)
- fatal("Unable to create logger window");
+ app->logger = loggerwindow_new(app);
+ if (!app->logger)
+ fatal("Unable to create logger window");
- app->extra = NULL;
- app->exit = 0;
+ app->extra = NULL;
+ app->exit = 0;
- return app;
+ return app;
}
-LoggerWindow *multitestapp_get_logger(MultiTestApp *app) {
- return app->logger;
+LoggerWindow *multitestapp_get_logger(MultiTestApp *app)
+{
+ return app->logger;
}
-GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) {
- return app->sys;
+GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app)
+{
+ return app->sys;
}
void multitestapp_free_extrawindow(MultiTestApp *app)
{
- extrawindow_free(app->extra);
- app->extra = NULL;
+ extrawindow_free(app->extra);
+ app->extra = NULL;
}
void multitestapp_toggle_extra_window(MultiTestApp *app)
{
- if (app->extra) {
- multitestapp_free_extrawindow(app);
- }
- else {
- app->extra = extrawindow_new(app);
- }
+ if (app->extra) {
+ multitestapp_free_extrawindow(app);
+ }
+ else {
+ app->extra = extrawindow_new(app);
+ }
}
void multitestapp_exit(MultiTestApp *app)
{
- app->exit = 1;
+ app->exit = 1;
}
void multitestapp_run(MultiTestApp *app)
{
- while (!app->exit) {
- GHOST_ProcessEvents(app->sys, 1);
- GHOST_DispatchEvents(app->sys);
- }
+ while (!app->exit) {
+ GHOST_ProcessEvents(app->sys, 1);
+ GHOST_DispatchEvents(app->sys);
+ }
}
void multitestapp_free(MultiTestApp *app)
{
- mainwindow_free(app->main);
- loggerwindow_free(app->logger);
- GHOST_DisposeSystem(app->sys);
- MEM_freeN(app);
+ mainwindow_free(app->main);
+ loggerwindow_free(app->logger);
+ GHOST_DisposeSystem(app->sys);
+ MEM_freeN(app);
}
/***/
int main(int argc, char **argv)
{
- MultiTestApp *app;
+ MultiTestApp *app;
#ifndef USE_BMF
- BLF_init();
+ BLF_init();
#endif
- app = multitestapp_new();
+ app = multitestapp_new();
- multitestapp_run(app);
- multitestapp_free(app);
+ multitestapp_run(app);
+ multitestapp_free(app);
- return 0;
+ return 0;
}
diff --git a/intern/ghost/test/multitest/ScrollBar.c b/intern/ghost/test/multitest/ScrollBar.c
index fbc3ab2f967..f14e726a077 100644
--- a/intern/ghost/test/multitest/ScrollBar.c
+++ b/intern/ghost/test/multitest/ScrollBar.c
@@ -27,125 +27,125 @@
#include "ScrollBar.h"
struct _ScrollBar {
- int rect[2][2];
- float thumbpos, thumbpct;
+ int rect[2][2];
+ float thumbpos, thumbpct;
- int inset;
- int minthumb;
+ int inset;
+ int minthumb;
- int scrolling;
- float scrolloffs;
+ int scrolling;
+ float scrolloffs;
};
static int scrollbar_get_thumbH(ScrollBar *sb)
{
- int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
+ int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
- return clamp_i(sb->thumbpct * scrollable_h, sb->minthumb, scrollable_h);
+ return clamp_i(sb->thumbpct * scrollable_h, sb->minthumb, scrollable_h);
}
static int scrollbar_get_thumbableH(ScrollBar *sb)
{
- int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
- int thumb_h = scrollbar_get_thumbH(sb);
+ int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
+ int thumb_h = scrollbar_get_thumbH(sb);
- return scrollable_h - thumb_h;
+ return scrollable_h - thumb_h;
}
static float scrollbar_co_to_pos(ScrollBar *sb, int yco)
{
- int thumb_h = scrollbar_get_thumbH(sb);
- int thumbable_h = scrollbar_get_thumbableH(sb);
- int thumbable_y = (sb->rect[0][1] + sb->inset) + thumb_h / 2;
+ int thumb_h = scrollbar_get_thumbH(sb);
+ int thumbable_h = scrollbar_get_thumbableH(sb);
+ int thumbable_y = (sb->rect[0][1] + sb->inset) + thumb_h / 2;
- return (float) (yco - thumbable_y) / thumbable_h;
+ return (float)(yco - thumbable_y) / thumbable_h;
}
/**/
ScrollBar *scrollbar_new(int inset, int minthumb)
{
- ScrollBar *sb = MEM_callocN(sizeof(*sb), "scrollbar_new");
- sb->inset = inset;
- sb->minthumb = minthumb;
+ ScrollBar *sb = MEM_callocN(sizeof(*sb), "scrollbar_new");
+ sb->inset = inset;
+ sb->minthumb = minthumb;
- return sb;
+ return sb;
}
void scrollbar_get_thumb(ScrollBar *sb, int thumb_r[2][2])
{
- int thumb_h = scrollbar_get_thumbH(sb);
- int thumbable_h = scrollbar_get_thumbableH(sb);
+ int thumb_h = scrollbar_get_thumbH(sb);
+ int thumbable_h = scrollbar_get_thumbableH(sb);
- thumb_r[0][0] = sb->rect[0][0] + sb->inset;
- thumb_r[1][0] = sb->rect[1][0] - sb->inset;
+ thumb_r[0][0] = sb->rect[0][0] + sb->inset;
+ thumb_r[1][0] = sb->rect[1][0] - sb->inset;
- thumb_r[0][1] = sb->rect[0][1] + sb->inset + sb->thumbpos * thumbable_h;
- thumb_r[1][1] = thumb_r[0][1] + thumb_h;
+ thumb_r[0][1] = sb->rect[0][1] + sb->inset + sb->thumbpos * thumbable_h;
+ thumb_r[1][1] = thumb_r[0][1] + thumb_h;
}
int scrollbar_is_scrolling(ScrollBar *sb)
{
- return sb->scrolling;
+ return sb->scrolling;
}
int scrollbar_contains_pt(ScrollBar *sb, int pt[2])
{
- return rect_contains_pt(sb->rect, pt);
+ return rect_contains_pt(sb->rect, pt);
}
void scrollbar_start_scrolling(ScrollBar *sb, int yco)
{
- int thumb_h_2 = scrollbar_get_thumbH(sb) / 2;
- int thumbable_h = scrollbar_get_thumbableH(sb);
- float npos = scrollbar_co_to_pos(sb, yco);
+ int thumb_h_2 = scrollbar_get_thumbH(sb) / 2;
+ int thumbable_h = scrollbar_get_thumbableH(sb);
+ float npos = scrollbar_co_to_pos(sb, yco);
- sb->scrolloffs = sb->thumbpos - npos;
- if (fabs(sb->scrolloffs) >= (float) thumb_h_2 / thumbable_h) {
- sb->scrolloffs = 0.0;
- }
+ sb->scrolloffs = sb->thumbpos - npos;
+ if (fabs(sb->scrolloffs) >= (float)thumb_h_2 / thumbable_h) {
+ sb->scrolloffs = 0.0;
+ }
- sb->scrolling = 1;
- sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
+ sb->scrolling = 1;
+ sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
}
void scrollbar_keep_scrolling(ScrollBar *sb, int yco)
{
- float npos = scrollbar_co_to_pos(sb, yco);
+ float npos = scrollbar_co_to_pos(sb, yco);
- sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
+ sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
}
void scrollbar_stop_scrolling(ScrollBar *sb)
{
- sb->scrolling = 0;
- sb->scrolloffs = 0.0;
+ sb->scrolling = 0;
+ sb->scrolloffs = 0.0;
}
void scrollbar_set_thumbpct(ScrollBar *sb, float pct)
{
- sb->thumbpct = pct;
+ sb->thumbpct = pct;
}
void scrollbar_set_thumbpos(ScrollBar *sb, float pos)
{
- sb->thumbpos = clamp_f(pos, 0.0, 1.0);
+ sb->thumbpos = clamp_f(pos, 0.0, 1.0);
}
void scrollbar_set_rect(ScrollBar *sb, int rect[2][2])
{
- rect_copy(sb->rect, rect);
+ rect_copy(sb->rect, rect);
}
float scrollbar_get_thumbpct(ScrollBar *sb)
{
- return sb->thumbpct;
+ return sb->thumbpct;
}
float scrollbar_get_thumbpos(ScrollBar *sb)
{
- return sb->thumbpos;
+ return sb->thumbpos;
}
void scrollbar_get_rect(ScrollBar *sb, int rect_r[2][2])
{
- rect_copy(rect_r, sb->rect);
+ rect_copy(rect_r, sb->rect);
}
void scrollbar_free(ScrollBar *sb)
{
- MEM_freeN(sb);
+ MEM_freeN(sb);
}
diff --git a/intern/ghost/test/multitest/ScrollBar.h b/intern/ghost/test/multitest/ScrollBar.h
index 015af7a1e07..7108f9ce2df 100644
--- a/intern/ghost/test/multitest/ScrollBar.h
+++ b/intern/ghost/test/multitest/ScrollBar.h
@@ -19,26 +19,25 @@
typedef struct _ScrollBar ScrollBar;
+/***/
- /***/
+ScrollBar *scrollbar_new(int inset, int minthumb);
-ScrollBar* scrollbar_new (int inset, int minthumb);
+int scrollbar_is_scrolling(ScrollBar *sb);
+int scrollbar_contains_pt(ScrollBar *sb, int pt[2]);
-int scrollbar_is_scrolling (ScrollBar *sb);
-int scrollbar_contains_pt (ScrollBar *sb, int pt[2]);
+void scrollbar_start_scrolling(ScrollBar *sb, int yco);
+void scrollbar_keep_scrolling(ScrollBar *sb, int yco);
+void scrollbar_stop_scrolling(ScrollBar *sb);
-void scrollbar_start_scrolling (ScrollBar *sb, int yco);
-void scrollbar_keep_scrolling (ScrollBar *sb, int yco);
-void scrollbar_stop_scrolling (ScrollBar *sb);
+void scrollbar_set_thumbpct(ScrollBar *sb, float pct);
+void scrollbar_set_thumbpos(ScrollBar *sb, float pos);
+void scrollbar_set_rect(ScrollBar *sb, int rect[2][2]);
-void scrollbar_set_thumbpct (ScrollBar *sb, float pct);
-void scrollbar_set_thumbpos (ScrollBar *sb, float pos);
-void scrollbar_set_rect (ScrollBar *sb, int rect[2][2]);
+float scrollbar_get_thumbpct(ScrollBar *sb);
+float scrollbar_get_thumbpos(ScrollBar *sb);
+void scrollbar_get_rect(ScrollBar *sb, int rect_r[2][2]);
-float scrollbar_get_thumbpct (ScrollBar *sb);
-float scrollbar_get_thumbpos (ScrollBar *sb);
-void scrollbar_get_rect (ScrollBar *sb, int rect_r[2][2]);
+void scrollbar_get_thumb(ScrollBar *sb, int thumb_r[2][2]);
-void scrollbar_get_thumb (ScrollBar *sb, int thumb_r[2][2]);
-
-void scrollbar_free (ScrollBar *sb);
+void scrollbar_free(ScrollBar *sb);
diff --git a/intern/ghost/test/multitest/Util.c b/intern/ghost/test/multitest/Util.c
index abaeb4407dc..c6cdebd39ce 100644
--- a/intern/ghost/test/multitest/Util.c
+++ b/intern/ghost/test/multitest/Util.c
@@ -29,36 +29,36 @@
void *memdbl(void *mem, int *size_pr, int item_size)
{
- int cur_size = *size_pr;
- int new_size = cur_size ? (cur_size * 2) : 1;
- void *nmem = MEM_mallocN(new_size * item_size, "memdbl");
+ int cur_size = *size_pr;
+ int new_size = cur_size ? (cur_size * 2) : 1;
+ void *nmem = MEM_mallocN(new_size * item_size, "memdbl");
- memcpy(nmem, mem, cur_size * item_size);
- MEM_freeN(mem);
+ memcpy(nmem, mem, cur_size * item_size);
+ MEM_freeN(mem);
- *size_pr = new_size;
- return nmem;
+ *size_pr = new_size;
+ return nmem;
}
char *string_dup(char *str)
{
- int len = strlen(str);
- char *nstr = MEM_mallocN(len + 1, "string_dup");
+ int len = strlen(str);
+ char *nstr = MEM_mallocN(len + 1, "string_dup");
- memcpy(nstr, str, len + 1);
+ memcpy(nstr, str, len + 1);
- return nstr;
+ return nstr;
}
void fatal(char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- fprintf(stderr, "FATAL: ");
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\n");
+ fprintf(stderr, "FATAL: ");
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
- exit(1);
+ exit(1);
}
diff --git a/intern/ghost/test/multitest/Util.h b/intern/ghost/test/multitest/Util.h
index 5bd8f84b35f..24f963a6d89 100644
--- a/intern/ghost/test/multitest/Util.h
+++ b/intern/ghost/test/multitest/Util.h
@@ -17,7 +17,7 @@
* All rights reserved.
*/
-void* memdbl (void *mem, int *size_pr, int item_size);
+void *memdbl(void *mem, int *size_pr, int item_size);
-char* string_dup (char *str);
-void fatal (char *fmt, ...);
+char *string_dup(char *str);
+void fatal(char *fmt, ...);
diff --git a/intern/ghost/test/multitest/WindowData.c b/intern/ghost/test/multitest/WindowData.c
index ea341ffa3be..7d3cbec43f3 100644
--- a/intern/ghost/test/multitest/WindowData.c
+++ b/intern/ghost/test/multitest/WindowData.c
@@ -26,25 +26,25 @@
#include "WindowData.h"
struct _WindowData {
- void *data;
- WindowDataHandler handler;
+ void *data;
+ WindowDataHandler handler;
};
WindowData *windowdata_new(void *data, WindowDataHandler handler)
{
- WindowData *wb = MEM_mallocN(sizeof(*wb), "windowdata_new");
- wb->data = data;
- wb->handler = handler;
+ WindowData *wb = MEM_mallocN(sizeof(*wb), "windowdata_new");
+ wb->data = data;
+ wb->handler = handler;
- return wb;
+ return wb;
}
void windowdata_handle(WindowData *wb, GHOST_EventHandle evt)
{
- wb->handler(wb->data, evt);
+ wb->handler(wb->data, evt);
}
void windowdata_free(WindowData *wb)
{
- MEM_freeN(wb);
+ MEM_freeN(wb);
}
diff --git a/intern/ghost/test/multitest/WindowData.h b/intern/ghost/test/multitest/WindowData.h
index 073da0dad2b..9d39377bb0a 100644
--- a/intern/ghost/test/multitest/WindowData.h
+++ b/intern/ghost/test/multitest/WindowData.h
@@ -20,8 +20,8 @@
typedef void (*WindowDataHandler)(void *priv, GHOST_EventHandle evt);
typedef struct _WindowData WindowData;
- /***/
+/***/
-WindowData* windowdata_new (void *data, WindowDataHandler handler);
-void windowdata_handle (WindowData *wb, GHOST_EventHandle evt);
-void windowdata_free (WindowData *wb);
+WindowData *windowdata_new(void *data, WindowDataHandler handler);
+void windowdata_handle(WindowData *wb, GHOST_EventHandle evt);
+void windowdata_free(WindowData *wb);
diff --git a/intern/ghost/test/multitest/stubs.c b/intern/ghost/test/multitest/stubs.c
index ad4b9812e98..f0b076eeba0 100644
--- a/intern/ghost/test/multitest/stubs.c
+++ b/intern/ghost/test/multitest/stubs.c
@@ -24,5 +24,10 @@
struct ImBuf;
-void IMB_freeImBuf(struct ImBuf *UNUSED(ibuf)) {}
-void IMB_colormanagement_display_to_scene_linear_v3(float UNUSED(pixel[3]), struct ColorManagedDisplay *UNUSED(display)) {}
+void IMB_freeImBuf(struct ImBuf *UNUSED(ibuf))
+{
+}
+void IMB_colormanagement_display_to_scene_linear_v3(float UNUSED(pixel[3]),
+ struct ColorManagedDisplay *UNUSED(display))
+{
+}
diff --git a/intern/glew-mx/CMakeLists.txt b/intern/glew-mx/CMakeLists.txt
index f0b0b2d0ee7..51e5c8b8990 100644
--- a/intern/glew-mx/CMakeLists.txt
+++ b/intern/glew-mx/CMakeLists.txt
@@ -19,19 +19,19 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
+ .
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- intern/glew-mx.c
+ intern/glew-mx.c
- glew-mx.h
- intern/gl-deprecated.h
- intern/symbol-binding.h
+ glew-mx.h
+ intern/gl-deprecated.h
+ intern/symbol-binding.h
)
set(LIB
diff --git a/intern/glew-mx/glew-mx.h b/intern/glew-mx/glew-mx.h
index a06fd7d977c..f9b3e55179f 100644
--- a/intern/glew-mx/glew-mx.h
+++ b/intern/glew-mx/glew-mx.h
@@ -43,25 +43,25 @@
#include <GL/glew.h>
-
#ifdef __cplusplus
extern "C" {
#endif
#include "intern/symbol-binding.h"
-
/* If compiling only for OpenGL 3.2 Core Profile then we should make sure
* no legacy API entries or symbolic constants are used.
*/
-#if (!defined(WITH_LEGACY_OPENGL)) || defined(WITH_GL_PROFILE_CORE) && !defined(WITH_GL_PROFILE_COMPAT) && !defined(WITH_GL_PROFILE_ES20)
+#if (!defined(WITH_LEGACY_OPENGL)) || defined(WITH_GL_PROFILE_CORE) && \
+ !defined(WITH_GL_PROFILE_COMPAT) && \
+ !defined(WITH_GL_PROFILE_ES20)
# include "intern/gl-deprecated.h"
#endif
GLenum glew_chk(GLenum error, const char *file, int line, const char *text);
#ifndef NDEBUG
-# define GLEW_CHK(x) glew_chk((x), __FILE__, __LINE__, #x)
+# define GLEW_CHK(x) glew_chk((x), __FILE__, __LINE__, # x)
#else
# define GLEW_CHK(x) glew_chk((x), NULL, 0, NULL)
#endif
@@ -70,5 +70,4 @@ GLenum glew_chk(GLenum error, const char *file, int line, const char *text);
}
#endif
-
-#endif /* __GLEW_MX_H__ */
+#endif /* __GLEW_MX_H__ */
diff --git a/intern/glew-mx/intern/gl-deprecated.h b/intern/glew-mx/intern/gl-deprecated.h
index 50049eaeb54..b6524cd5197 100644
--- a/intern/glew-mx/intern/gl-deprecated.h
+++ b/intern/glew-mx/intern/gl-deprecated.h
@@ -835,28 +835,28 @@
#if 0 /* Those are deprecated but still valid */
// Old Token Names 3.0
-#undef GL_CLIP_PLANE0
-#define GL_CLIP_PLANE0 USE_GL_CLIP_DISTANCE0
-#undef GL_CLIP_PLANE1
-#define GL_CLIP_PLANE1 USE_GL_CLIP_DISTANCE1
-#undef GL_CLIP_PLANE2
-#define GL_CLIP_PLANE2 USE_GL_CLIP_DISTANCE2
-#undef GL_CLIP_PLANE3
-#define GL_CLIP_PLANE3 USE_GL_CLIP_DISTANCE3
-#undef GL_CLIP_PLANE4
-#define GL_CLIP_PLANE4 USE_GL_CLIP_DISTANCE4
-#undef GL_CLIP_PLANE5
-#define GL_CLIP_PLANE5 USE_GL_CLIP_DISTANCE5
-#undef GL_COMPARE_R_TO_TEXTURE
-#define GL_COMPARE_R_TO_TEXTURE USE_GL_COMPARE_REF_TO_TEXTURE
-#undef GL_MAX_CLIP_PLANES
-#define GL_MAX_CLIP_PLANES USE_GL_MAX_CLIP_DISTANCES
-#undef GL_MAX_VARYING_FLOATS
-#define GL_MAX_VARYING_FLOATS USE__MAX_VARYING_COMPONENTS
+# undef GL_CLIP_PLANE0
+# define GL_CLIP_PLANE0 USE_GL_CLIP_DISTANCE0
+# undef GL_CLIP_PLANE1
+# define GL_CLIP_PLANE1 USE_GL_CLIP_DISTANCE1
+# undef GL_CLIP_PLANE2
+# define GL_CLIP_PLANE2 USE_GL_CLIP_DISTANCE2
+# undef GL_CLIP_PLANE3
+# define GL_CLIP_PLANE3 USE_GL_CLIP_DISTANCE3
+# undef GL_CLIP_PLANE4
+# define GL_CLIP_PLANE4 USE_GL_CLIP_DISTANCE4
+# undef GL_CLIP_PLANE5
+# define GL_CLIP_PLANE5 USE_GL_CLIP_DISTANCE5
+# undef GL_COMPARE_R_TO_TEXTURE
+# define GL_COMPARE_R_TO_TEXTURE USE_GL_COMPARE_REF_TO_TEXTURE
+# undef GL_MAX_CLIP_PLANES
+# define GL_MAX_CLIP_PLANES USE_GL_MAX_CLIP_DISTANCES
+# undef GL_MAX_VARYING_FLOATS
+# define GL_MAX_VARYING_FLOATS USE__MAX_VARYING_COMPONENTS
// Old Token Names 3.2
-#undef GL_VERTEX_PROGRAM_POINT_SIZE
-#define GL_VERTEX_PROGRAM_POINT_SIZE USE_GL_PROGRAM_POINT_SIZE
+# undef GL_VERTEX_PROGRAM_POINT_SIZE
+# define GL_VERTEX_PROGRAM_POINT_SIZE USE_GL_PROGRAM_POINT_SIZE
#endif
#endif /* __GL_DEPRECATED_H__ */
diff --git a/intern/glew-mx/intern/glew-mx.c b/intern/glew-mx/intern/glew-mx.c
index fcd8e83f530..541d3c5efbe 100644
--- a/intern/glew-mx/intern/glew-mx.c
+++ b/intern/glew-mx/intern/glew-mx.c
@@ -26,53 +26,57 @@
#include <stdio.h>
#include <stdlib.h>
-#define CASE_CODE_RETURN_STR(code) case code: return #code;
+#define CASE_CODE_RETURN_STR(code) \
+ case code: \
+ return #code;
static const char *get_glew_error_enum_string(GLenum error)
{
- switch (error) {
- CASE_CODE_RETURN_STR(GLEW_OK) /* also GLEW_NO_ERROR */
- CASE_CODE_RETURN_STR(GLEW_ERROR_NO_GL_VERSION)
- CASE_CODE_RETURN_STR(GLEW_ERROR_GL_VERSION_10_ONLY)
- CASE_CODE_RETURN_STR(GLEW_ERROR_GLX_VERSION_11_ONLY)
+ switch (error) {
+ CASE_CODE_RETURN_STR(GLEW_OK) /* also GLEW_NO_ERROR */
+ CASE_CODE_RETURN_STR(GLEW_ERROR_NO_GL_VERSION)
+ CASE_CODE_RETURN_STR(GLEW_ERROR_GL_VERSION_10_ONLY)
+ CASE_CODE_RETURN_STR(GLEW_ERROR_GLX_VERSION_11_ONLY)
#ifdef WITH_GLEW_ES
- CASE_CODE_RETURN_STR(GLEW_ERROR_NOT_GLES_VERSION)
- CASE_CODE_RETURN_STR(GLEW_ERROR_GLES_VERSION)
- CASE_CODE_RETURN_STR(GLEW_ERROR_NO_EGL_VERSION)
- CASE_CODE_RETURN_STR(GLEW_ERROR_EGL_VERSION_10_ONLY)
+ CASE_CODE_RETURN_STR(GLEW_ERROR_NOT_GLES_VERSION)
+ CASE_CODE_RETURN_STR(GLEW_ERROR_GLES_VERSION)
+ CASE_CODE_RETURN_STR(GLEW_ERROR_NO_EGL_VERSION)
+ CASE_CODE_RETURN_STR(GLEW_ERROR_EGL_VERSION_10_ONLY)
#endif
- default:
- return NULL;
- }
+ default:
+ return NULL;
+ }
}
-
GLenum glew_chk(GLenum error, const char *file, int line, const char *text)
{
- if (error != GLEW_OK) {
- const char *code = get_glew_error_enum_string(error);
- const char *msg = (const char *)glewGetErrorString(error);
+ if (error != GLEW_OK) {
+ const char *code = get_glew_error_enum_string(error);
+ const char *msg = (const char *)glewGetErrorString(error);
- if (error == GLEW_ERROR_NO_GL_VERSION)
- return GLEW_OK;
+ if (error == GLEW_ERROR_NO_GL_VERSION)
+ return GLEW_OK;
#ifndef NDEBUG
- fprintf(stderr,
- "%s(%d):[%s] -> GLEW Error (0x%04X): %s: %s\n",
- file, line, text, error,
- code ? code : "<no symbol>",
- msg ? msg : "<no message>");
+ fprintf(stderr,
+ "%s(%d):[%s] -> GLEW Error (0x%04X): %s: %s\n",
+ file,
+ line,
+ text,
+ error,
+ code ? code : "<no symbol>",
+ msg ? msg : "<no message>");
#else
- (void) file;
- (void) line;
- (void) text;
- fprintf(stderr,
- "GLEW Error (0x%04X): %s: %s\n",
- error,
- code ? code : "<no symbol>",
- msg ? msg : "<no message>");
+ (void)file;
+ (void)line;
+ (void)text;
+ fprintf(stderr,
+ "GLEW Error (0x%04X): %s: %s\n",
+ error,
+ code ? code : "<no symbol>",
+ msg ? msg : "<no message>");
#endif
- }
+ }
- return error;
+ return error;
}
diff --git a/intern/glew-mx/intern/symbol-binding.h b/intern/glew-mx/intern/symbol-binding.h
index 2950a8f325a..0dc7d859fca 100644
--- a/intern/glew-mx/intern/symbol-binding.h
+++ b/intern/glew-mx/intern/symbol-binding.h
@@ -32,114 +32,112 @@
#define __SYMBOL_BINDING_H__
#ifndef __GLEW_MX_H__
-#error This file is meant to be included from glew-mx.h
+# error This file is meant to be included from glew-mx.h
#endif
-
#ifdef GLEW_ES_ONLY
/* ES does not support the GLdouble type. */
-#ifndef GLdouble
-#define GLdouble double
-#endif
+# ifndef GLdouble
+# define GLdouble double
+# endif
/*
* Need stubs for these version checks if compiling with only ES support.
* Rely on compiler to eliminate unreachable code when version checks become constants.
*/
-#ifndef GLEW_VERSION_1_1
-#define GLEW_VERSION_1_1 0
-#endif
+# ifndef GLEW_VERSION_1_1
+# define GLEW_VERSION_1_1 0
+# endif
-#ifndef GLEW_VERSION_1_2
-#define GLEW_VERSION_1_2 0
-#endif
+# ifndef GLEW_VERSION_1_2
+# define GLEW_VERSION_1_2 0
+# endif
-#ifndef GLEW_VERSION_1_3
-#define GLEW_VERSION_1_3 0
-#endif
+# ifndef GLEW_VERSION_1_3
+# define GLEW_VERSION_1_3 0
+# endif
-#ifndef GLEW_VERSION_1_4
-#define GLEW_VERSION_1_4 0
-#endif
+# ifndef GLEW_VERSION_1_4
+# define GLEW_VERSION_1_4 0
+# endif
-#ifndef GLEW_VERSION_1_5
-#define GLEW_VERSION_1_5 0
-#endif
+# ifndef GLEW_VERSION_1_5
+# define GLEW_VERSION_1_5 0
+# endif
-#ifndef GLEW_VERSION_2_0
-#define GLEW_VERSION_2_0 0
-#endif
+# ifndef GLEW_VERSION_2_0
+# define GLEW_VERSION_2_0 0
+# endif
-#ifndef GLEW_VERSION_3_0
-#define GLEW_VERSION_3_0 0
-#endif
+# ifndef GLEW_VERSION_3_0
+# define GLEW_VERSION_3_0 0
+# endif
-#ifndef GLEW_ARB_shader_objects
-#define GLEW_ARB_shader_objects 0
-#endif
+# ifndef GLEW_ARB_shader_objects
+# define GLEW_ARB_shader_objects 0
+# endif
-#ifndef GLEW_ARB_vertex_shader
-#define GLEW_ARB_vertex_shader 0
-#endif
+# ifndef GLEW_ARB_vertex_shader
+# define GLEW_ARB_vertex_shader 0
+# endif
-#ifndef GLEW_ARB_vertex_program
-#define GLEW_ARB_vertex_program 0
-#endif
+# ifndef GLEW_ARB_vertex_program
+# define GLEW_ARB_vertex_program 0
+# endif
-#ifndef GLEW_ARB_fragment_program
-#define GLEW_ARB_fragment_program 0
-#endif
-
-#ifndef GLEW_ARB_vertex_buffer_object
-#define GLEW_ARB_vertex_buffer_object 0
-#endif
+# ifndef GLEW_ARB_fragment_program
+# define GLEW_ARB_fragment_program 0
+# endif
-#ifndef GLEW_ARB_framebuffer_object
-#define GLEW_ARB_framebuffer_object 0
-#endif
+# ifndef GLEW_ARB_vertex_buffer_object
+# define GLEW_ARB_vertex_buffer_object 0
+# endif
-#ifndef GLEW_ARB_multitexture
-#define GLEW_ARB_multitexture 0
-#endif
+# ifndef GLEW_ARB_framebuffer_object
+# define GLEW_ARB_framebuffer_object 0
+# endif
-#ifndef GLEW_EXT_framebuffer_object
-#define GLEW_EXT_framebuffer_object 0
-#endif
+# ifndef GLEW_ARB_multitexture
+# define GLEW_ARB_multitexture 0
+# endif
-#ifndef GLEW_ARB_depth_texture
-#define GLEW_ARB_depth_texture 0
-#endif
+# ifndef GLEW_EXT_framebuffer_object
+# define GLEW_EXT_framebuffer_object 0
+# endif
-#ifndef GLEW_ARB_shadow
-#define GLEW_ARB_shadow 0
-#endif
+# ifndef GLEW_ARB_depth_texture
+# define GLEW_ARB_depth_texture 0
+# endif
-#ifndef GLEW_ARB_texture_float
-#define GLEW_ARB_texture_float 0
-#endif
+# ifndef GLEW_ARB_shadow
+# define GLEW_ARB_shadow 0
+# endif
-#ifndef GLEW_ARB_texture_non_power_of_two
-#define GLEW_ARB_texture_non_power_of_two 0
-#endif
+# ifndef GLEW_ARB_texture_float
+# define GLEW_ARB_texture_float 0
+# endif
-#ifndef GLEW_ARB_texture3D
-#define GLEW_ARB_texture3D 0
-#endif
+# ifndef GLEW_ARB_texture_non_power_of_two
+# define GLEW_ARB_texture_non_power_of_two 0
+# endif
-#ifndef GLEW_EXT_texture3D
-#define GLEW_EXT_texture3D 0
-#endif
+# ifndef GLEW_ARB_texture3D
+# define GLEW_ARB_texture3D 0
+# endif
-#ifndef GLEW_ARB_texture_rg
-#define GLEW_ARB_texture_rg 0
-#endif
+# ifndef GLEW_EXT_texture3D
+# define GLEW_EXT_texture3D 0
+# endif
-#ifndef GLEW_ARB_texture_query_lod
-#define GLEW_ARB_texture_query_lod 0
-#endif
+# ifndef GLEW_ARB_texture_rg
+# define GLEW_ARB_texture_rg 0
+# endif
+# ifndef GLEW_ARB_texture_query_lod
+# define GLEW_ARB_texture_query_lod 0
+# endif
/*
* The following symbolic constants are missing from an ES only header,
@@ -150,128 +148,125 @@
* Some of these may be here simply to patch inconsistencies in the header files.
*/
-#ifndef GL_TEXTURE_3D
-#define GL_TEXTURE_3D GL_TEXTURE_3D_OES
-#endif
+# ifndef GL_TEXTURE_3D
+# define GL_TEXTURE_3D GL_TEXTURE_3D_OES
+# endif
-#ifndef GL_TEXTURE_WRAP_R
-#define GL_TEXTURE_WRAP_R GL_TEXTURE_WRAP_R_OES
-#endif
-
-#ifndef GL_TEXTURE_COMPARE_MODE
-#define GL_TEXTURE_COMPARE_MODE GL_TEXTURE_COMPARE_MODE_EXT
-#endif
+# ifndef GL_TEXTURE_WRAP_R
+# define GL_TEXTURE_WRAP_R GL_TEXTURE_WRAP_R_OES
+# endif
-#ifndef GL_COMPARE_REF_TO_TEXTURE
-#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_REF_TO_TEXTURE_EXT
-#endif
+# ifndef GL_TEXTURE_COMPARE_MODE
+# define GL_TEXTURE_COMPARE_MODE GL_TEXTURE_COMPARE_MODE_EXT
+# endif
-#ifndef GL_TEXTURE_COMPARE_FUNC
-#define GL_TEXTURE_COMPARE_FUNC GL_TEXTURE_COMPARE_FUNC_EXT
-#endif
+# ifndef GL_COMPARE_REF_TO_TEXTURE
+# define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_REF_TO_TEXTURE_EXT
+# endif
-#ifndef GL_RGBA8
-#define GL_RGBA8 GL_RGBA8_OES
-#endif
+# ifndef GL_TEXTURE_COMPARE_FUNC
+# define GL_TEXTURE_COMPARE_FUNC GL_TEXTURE_COMPARE_FUNC_EXT
+# endif
-#ifndef GL_RGBA16F
-#define GL_RGBA16F GL_RGBA16F_EXT
-#endif
+# ifndef GL_RGBA8
+# define GL_RGBA8 GL_RGBA8_OES
+# endif
-#ifndef GL_RG32F
-#define GL_RG32F GL_RG32F_EXT
-#endif
+# ifndef GL_RGBA16F
+# define GL_RGBA16F GL_RGBA16F_EXT
+# endif
-#ifndef GL_RGB8
-#define GL_RGB8 GL_RGB8_OES
-#endif
+# ifndef GL_RG32F
+# define GL_RG32F GL_RG32F_EXT
+# endif
-#ifndef GL_RG
-#define GL_RG GL_RG_EXT
-#endif
+# ifndef GL_RGB8
+# define GL_RGB8 GL_RGB8_OES
+# endif
-#ifndef GL_RED
-#define GL_RED GL_RED_EXT
-#endif
+# ifndef GL_RG
+# define GL_RG GL_RG_EXT
+# endif
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES
-#endif
+# ifndef GL_RED
+# define GL_RED GL_RED_EXT
+# endif
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES
-#endif
+# ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
+# define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES
+# endif
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES
-#endif
+# ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
+# define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES
+# endif
-#ifndef GL_WRITE_ONLY
-#define GL_WRITE_ONLY GL_WRITE_ONLY_OES
-#endif
+# ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
+# define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES
+# endif
-#ifndef GLEW_ARB_vertex_array_object
-#define GLEW_ARB_vertex_array_object 0
-#endif
+# ifndef GL_WRITE_ONLY
+# define GL_WRITE_ONLY GL_WRITE_ONLY_OES
+# endif
+# ifndef GLEW_ARB_vertex_array_object
+# define GLEW_ARB_vertex_array_object 0
+# endif
/* end of ifdef GLEW_ES_ONLY */
#elif defined(GLEW_NO_ES)
-
/*
* Need stubs for these version checks if compiling without any support.
* Rely on compiler to eliminate unreachable code when version checks become constants
*/
-#ifndef GLEW_ES_VERSION_2_0
-#define GLEW_ES_VERSION_2_0 0
-#endif
-
-#ifndef GLEW_EXT_texture_storage
-#define GLEW_EXT_texture_storage 0
-#endif
+# ifndef GLEW_ES_VERSION_2_0
+# define GLEW_ES_VERSION_2_0 0
+# endif
-#ifndef GLEW_OES_framebuffer_object
-#define GLEW_OES_framebuffer_object 0
-#endif
+# ifndef GLEW_EXT_texture_storage
+# define GLEW_EXT_texture_storage 0
+# endif
-#ifndef GLEW_OES_mapbuffer
-#define GLEW_OES_mapbuffer 0
-#endif
+# ifndef GLEW_OES_framebuffer_object
+# define GLEW_OES_framebuffer_object 0
+# endif
-#ifndef GLEW_OES_required_internalformat
-#define GLEW_OES_required_internalformat 0
-#endif
+# ifndef GLEW_OES_mapbuffer
+# define GLEW_OES_mapbuffer 0
+# endif
-#ifndef GLEW_EXT_color_buffer_half_float
-#define GLEW_EXT_color_buffer_half_float 0
-#endif
+# ifndef GLEW_OES_required_internalformat
+# define GLEW_OES_required_internalformat 0
+# endif
-#ifndef GLEW_OES_depth_texture
-#define GLEW_OES_depth_texture 0
-#endif
+# ifndef GLEW_EXT_color_buffer_half_float
+# define GLEW_EXT_color_buffer_half_float 0
+# endif
-#ifndef GLEW_EXT_shadow_samplers
-#define GLEW_EXT_shadow_samplers 0
-#endif
+# ifndef GLEW_OES_depth_texture
+# define GLEW_OES_depth_texture 0
+# endif
-#ifndef GLEW_ARB_texture3D
-#define GLEW_ARB_texture3D 0
-#endif
+# ifndef GLEW_EXT_shadow_samplers
+# define GLEW_EXT_shadow_samplers 0
+# endif
-#ifndef GLEW_OES_texture_3D
-#define GLEW_OES_texture_3D 0
-#endif
+# ifndef GLEW_ARB_texture3D
+# define GLEW_ARB_texture3D 0
+# endif
-#ifndef GLEW_EXT_texture_rg
-#define GLEW_EXT_texture_rg 0
-#endif
+# ifndef GLEW_OES_texture_3D
+# define GLEW_OES_texture_3D 0
+# endif
-#ifndef GLEW_OES_vertex_array_object
-#define GLEW_OES_vertex_array_object 0
-#endif
+# ifndef GLEW_EXT_texture_rg
+# define GLEW_EXT_texture_rg 0
+# endif
+# ifndef GLEW_OES_vertex_array_object
+# define GLEW_OES_vertex_array_object 0
+# endif
/*
* The following symbolic constants are missing when there is no ES support,
@@ -283,15 +278,14 @@
* For that reason these aliases are more likely just patching inconsistencies in the header files.
*/
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
-#endif
+# ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
+# define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
+# endif
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
-#endif
+# ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
+# define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
+# endif
#endif /* ifdef GLEW_NO_ES */
-
#endif /* __SYMBOL_BINDING_H__*/
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 72c3395156e..dab24af7f8d 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -19,8 +19,8 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../atomic
+ .
+ ../atomic
)
set(INC_SYS
@@ -28,40 +28,40 @@ set(INC_SYS
)
set(SRC
- ./intern/mallocn.c
- ./intern/mallocn_guarded_impl.c
- ./intern/mallocn_lockfree_impl.c
+ ./intern/mallocn.c
+ ./intern/mallocn_guarded_impl.c
+ ./intern/mallocn_lockfree_impl.c
- MEM_guardedalloc.h
- ./intern/mallocn_inline.h
- ./intern/mallocn_intern.h
+ MEM_guardedalloc.h
+ ./intern/mallocn_inline.h
+ ./intern/mallocn_intern.h
- # only so the header is known by cmake
- ../atomic/atomic_ops.h
+ # only so the header is known by cmake
+ ../atomic/atomic_ops.h
)
set(LIB
)
if(WIN32 AND NOT UNIX)
- list(APPEND SRC
- intern/mmap_win.c
+ list(APPEND SRC
+ intern/mmap_win.c
- mmap_win.h
- )
+ mmap_win.h
+ )
endif()
# Jemalloc 5.0.0+ needs extra configuration.
if(WITH_MEM_JEMALLOC AND NOT ("${JEMALLOC_VERSION}" VERSION_LESS "5.0.0"))
- add_definitions(-DWITH_JEMALLOC_CONF)
+ add_definitions(-DWITH_JEMALLOC_CONF)
endif()
blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# Override C++ alloc, optional.
if(WITH_CXX_GUARDEDALLOC)
- set(SRC
- cpp/mallocn.cpp
- )
- blender_add_lib(bf_intern_guardedalloc_cpp "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+ set(SRC
+ cpp/mallocn.cpp
+ )
+ blender_add_lib(bf_intern_guardedalloc_cpp "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
endif()
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 91d328afbad..4cefc27bc54 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -49,7 +49,7 @@
#ifndef __MEM_GUARDEDALLOC_H__
#define __MEM_GUARDEDALLOC_H__
-#include <stdio.h> /* needed for FILE* */
+#include <stdio.h> /* needed for FILE* */
/* needed for uintptr_t and attributes, exception, dont use BLI anywhere else in MEM_* */
#include "../../source/blender/blenlib/BLI_sys_types.h"
@@ -59,148 +59,169 @@
extern "C" {
#endif
- /** Returns the length of the allocated memory segment pointed at
- * by vmemh. If the pointer was not previously allocated by this
- * module, the result is undefined.*/
- extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
-
- /**
- * Release memory previously allocated by this module.
- */
- extern void (*MEM_freeN)(void *vmemh);
-
-#if 0 /* UNUSED */
- /**
- * Return zero if memory is not in allocated list
- */
- extern short (*MEM_testN)(void *vmemh);
+/** Returns the length of the allocated memory segment pointed at
+ * by vmemh. If the pointer was not previously allocated by this
+ * module, the result is undefined.*/
+extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
+
+/**
+ * Release memory previously allocated by this module.
+ */
+extern void (*MEM_freeN)(void *vmemh);
+
+#if 0 /* UNUSED */
+ /**
+ * Return zero if memory is not in allocated list
+ */
+ extern short (*MEM_testN)(void *vmemh);
#endif
- /**
- * Duplicates a block of memory, and returns a pointer to the
- * newly allocated block. */
- extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
-
- /**
- * Reallocates a block of memory, and returns pointer to the newly
- * allocated block, the old one is freed. this is not as optimized
- * as a system realloc but just makes a new allocation and copies
- * over from existing memory. */
- extern void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-
- /**
- * A variant of realloc which zeros new bytes
- */
- extern void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
+/**
+ * Duplicates a block of memory, and returns a pointer to the
+ * newly allocated block. */
+extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
+
+/**
+ * Reallocates a block of memory, and returns pointer to the newly
+ * allocated block, the old one is freed. this is not as optimized
+ * as a system realloc but just makes a new allocation and copies
+ * over from existing memory. */
+extern void *(*MEM_reallocN_id)(void *vmemh,
+ size_t len,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+
+/**
+ * A variant of realloc which zeros new bytes
+ */
+extern void *(*MEM_recallocN_id)(void *vmemh,
+ size_t len,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
#define MEM_reallocN(vmemh, len) MEM_reallocN_id(vmemh, len, __func__)
#define MEM_recallocN(vmemh, len) MEM_recallocN_id(vmemh, len, __func__)
- /**
- * Allocate a block of memory of size len, with tag name str. The
- * memory is cleared. The name must be static, because only a
- * pointer to it is stored ! */
- extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-
- /**
- * Allocate a block of memory of size (len * size), with tag name
- * str, aborting in case of integer overflows to prevent vulnerabilities.
- * The memory is cleared. The name must be static, because only a
- * pointer to it is stored ! */
- extern void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-
- /**
- * Allocate a block of memory of size len, with tag name str. The
- * name must be a static, because only a pointer to it is stored !
- * */
- extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-
- /**
- * Allocate a block of memory of size (len * size), with tag name str,
- * aborting in case of integer overflow to prevent vulnerabilities. The
- * name must be a static, because only a pointer to it is stored !
- * */
- extern void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-
- /**
- * Allocate an aligned block of memory of size len, with tag name str. The
- * name must be a static, because only a pointer to it is stored !
- * */
- extern void *(*MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
-
- /**
- * Same as callocN, clears memory and uses mmap (disk cached) if supported.
- * Can be free'd with MEM_freeN as usual.
- * */
- extern void *(*MEM_mapallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-
- /** Print a list of the names and sizes of all allocated memory
- * blocks. as a python dict for easy investigation */
- extern void (*MEM_printmemlist_pydict)(void);
-
- /** Print a list of the names and sizes of all allocated memory
- * blocks. */
- extern void (*MEM_printmemlist)(void);
-
- /** calls the function on all allocated memory blocks. */
- extern void (*MEM_callbackmemlist)(void (*func)(void *));
-
- /** Print statistics about memory usage */
- extern void (*MEM_printmemlist_stats)(void);
-
- /** Set the callback function for error output. */
- extern void (*MEM_set_error_callback)(void (*func)(const char *));
-
- /**
- * Are the start/end block markers still correct ?
- *
- * @retval true for correct memory, false for corrupted memory. */
- extern bool (*MEM_consistency_check)(void);
-
- /** Set thread locking functions for safe memory allocation from multiple
- * threads, pass NULL pointers to disable thread locking again. */
- extern void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void));
-
- /** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
- extern void (*MEM_set_memory_debug)(void);
-
- /**
- * Memory usage stats
- * - MEM_get_memory_in_use is all memory
- * - MEM_get_mapped_memory_in_use is a subset of all memory */
- extern size_t (*MEM_get_memory_in_use)(void);
- /** Get mapped memory usage. */
- extern size_t (*MEM_get_mapped_memory_in_use)(void);
- /** Get amount of memory blocks in use. */
- extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
-
- /** Reset the peak memory statistic to zero. */
- extern void (*MEM_reset_peak_memory)(void);
-
- /** Get the peak memory usage in bytes, including mmap allocations. */
- extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
+/**
+ * Allocate a block of memory of size len, with tag name str. The
+ * memory is cleared. The name must be static, because only a
+ * pointer to it is stored ! */
+extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+
+/**
+ * Allocate a block of memory of size (len * size), with tag name
+ * str, aborting in case of integer overflows to prevent vulnerabilities.
+ * The memory is cleared. The name must be static, because only a
+ * pointer to it is stored ! */
+extern void *(*MEM_calloc_arrayN)(size_t len,
+ size_t size,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+
+/**
+ * Allocate a block of memory of size len, with tag name str. The
+ * name must be a static, because only a pointer to it is stored !
+ * */
+extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+
+/**
+ * Allocate a block of memory of size (len * size), with tag name str,
+ * aborting in case of integer overflow to prevent vulnerabilities. The
+ * name must be a static, because only a pointer to it is stored !
+ * */
+extern void *(*MEM_malloc_arrayN)(size_t len,
+ size_t size,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+
+/**
+ * Allocate an aligned block of memory of size len, with tag name str. The
+ * name must be a static, because only a pointer to it is stored !
+ * */
+extern void *(*MEM_mallocN_aligned)(size_t len,
+ size_t alignment,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
+
+/**
+ * Same as callocN, clears memory and uses mmap (disk cached) if supported.
+ * Can be free'd with MEM_freeN as usual.
+ * */
+extern void *(*MEM_mapallocN)(size_t len,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+
+/** Print a list of the names and sizes of all allocated memory
+ * blocks. as a python dict for easy investigation */
+extern void (*MEM_printmemlist_pydict)(void);
+
+/** Print a list of the names and sizes of all allocated memory
+ * blocks. */
+extern void (*MEM_printmemlist)(void);
+
+/** calls the function on all allocated memory blocks. */
+extern void (*MEM_callbackmemlist)(void (*func)(void *));
+
+/** Print statistics about memory usage */
+extern void (*MEM_printmemlist_stats)(void);
+
+/** Set the callback function for error output. */
+extern void (*MEM_set_error_callback)(void (*func)(const char *));
+
+/**
+ * Are the start/end block markers still correct ?
+ *
+ * @retval true for correct memory, false for corrupted memory. */
+extern bool (*MEM_consistency_check)(void);
+
+/** Set thread locking functions for safe memory allocation from multiple
+ * threads, pass NULL pointers to disable thread locking again. */
+extern void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void));
+
+/** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
+extern void (*MEM_set_memory_debug)(void);
+
+/**
+ * Memory usage stats
+ * - MEM_get_memory_in_use is all memory
+ * - MEM_get_mapped_memory_in_use is a subset of all memory */
+extern size_t (*MEM_get_memory_in_use)(void);
+/** Get mapped memory usage. */
+extern size_t (*MEM_get_mapped_memory_in_use)(void);
+/** Get amount of memory blocks in use. */
+extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
+
+/** Reset the peak memory statistic to zero. */
+extern void (*MEM_reset_peak_memory)(void);
+
+/** Get the peak memory usage in bytes, including mmap allocations. */
+extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
#ifdef __GNUC__
-#define MEM_SAFE_FREE(v) do { \
- typeof(&(v)) _v = &(v); \
- if (*_v) { \
- MEM_freeN(*_v); \
- *_v = NULL; \
- } \
-} while (0)
+# define MEM_SAFE_FREE(v) \
+ do { \
+ typeof(&(v)) _v = &(v); \
+ if (*_v) { \
+ MEM_freeN(*_v); \
+ *_v = NULL; \
+ } \
+ } while (0)
#else
-#define MEM_SAFE_FREE(v) do { \
- void ** _v = (void **)&(v); \
- if (*_v) { \
- MEM_freeN(*_v); \
- *_v = NULL; \
- } \
-} while (0)
+# define MEM_SAFE_FREE(v) \
+ do { \
+ void **_v = (void **)&(v); \
+ if (*_v) { \
+ MEM_freeN(*_v); \
+ *_v = NULL; \
+ } \
+ } while (0)
#endif
/* overhead for lockfree allocator (use to avoid slop-space) */
#define MEM_SIZE_OVERHEAD sizeof(size_t)
-#define MEM_SIZE_OPTIMAL(size) ((size) - MEM_SIZE_OVERHEAD)
+#define MEM_SIZE_OPTIMAL(size) ((size)-MEM_SIZE_OVERHEAD)
#ifndef NDEBUG
extern const char *(*MEM_name_ptr)(void *vmemh);
@@ -211,39 +232,45 @@ void MEM_use_guarded_allocator(void);
#ifdef __cplusplus
/* alloc funcs for C++ only */
-#define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
-public: \
- void *operator new(size_t num_bytes) { \
- return MEM_mallocN(num_bytes, _id); \
- } \
- void operator delete(void *mem) { \
- if (mem) \
- MEM_freeN(mem); \
- } \
- void *operator new[](size_t num_bytes) { \
- return MEM_mallocN(num_bytes, _id "[]"); \
- } \
- void operator delete[](void *mem) { \
- if (mem) \
- MEM_freeN(mem); \
- } \
-
-#if defined __GNUC__
-# define OBJECT_GUARDED_NEW(type, args ...) \
- new(MEM_mallocN(sizeof(type), __func__)) type(args)
-#else
-# define OBJECT_GUARDED_NEW(type, ...) \
- new(MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
-#endif
-#define OBJECT_GUARDED_DELETE(what, type) \
- { if(what) { \
- ((type*)(what))->~type(); \
- MEM_freeN(what); \
- } } (void)0
-#endif /* __cplusplus */
+# define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
+ public: \
+ void *operator new(size_t num_bytes) \
+ { \
+ return MEM_mallocN(num_bytes, _id); \
+ } \
+ void operator delete(void *mem) \
+ { \
+ if (mem) \
+ MEM_freeN(mem); \
+ } \
+ void *operator new[](size_t num_bytes) \
+ { \
+ return MEM_mallocN(num_bytes, _id "[]"); \
+ } \
+ void operator delete[](void *mem) \
+ { \
+ if (mem) \
+ MEM_freeN(mem); \
+ }
+
+# if defined __GNUC__
+# define OBJECT_GUARDED_NEW(type, args...) new (MEM_mallocN(sizeof(type), __func__)) type(args)
+# else
+# define OBJECT_GUARDED_NEW(type, ...) \
+ new (MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
+# endif
+# define OBJECT_GUARDED_DELETE(what, type) \
+ { \
+ if (what) { \
+ ((type *)(what))->~type(); \
+ MEM_freeN(what); \
+ } \
+ } \
+ (void)0
+#endif /* __cplusplus */
#ifdef __cplusplus
}
-#endif /* __cplusplus */
+#endif /* __cplusplus */
-#endif /* __MEM_GUARDEDALLOC_H__ */
+#endif /* __MEM_GUARDEDALLOC_H__ */
diff --git a/intern/guardedalloc/cpp/mallocn.cpp b/intern/guardedalloc/cpp/mallocn.cpp
index 6582bf49545..0804e096dc6 100644
--- a/intern/guardedalloc/cpp/mallocn.cpp
+++ b/intern/guardedalloc/cpp/mallocn.cpp
@@ -18,7 +18,6 @@
* \ingroup MEM
*/
-
#include <new>
#include "../MEM_guardedalloc.h"
@@ -28,33 +27,31 @@ void *operator new[](size_t size, const char *str) throw(std::bad_alloc);
/* not default but can be used when needing to set a string */
void *operator new(size_t size, const char *str) throw(std::bad_alloc)
{
- return MEM_mallocN(size, str);
+ return MEM_mallocN(size, str);
}
void *operator new[](size_t size, const char *str) throw(std::bad_alloc)
{
- return MEM_mallocN(size, str);
+ return MEM_mallocN(size, str);
}
-
void *operator new(size_t size) throw(std::bad_alloc)
{
- return MEM_mallocN(size, "C++/anonymous");
+ return MEM_mallocN(size, "C++/anonymous");
}
void *operator new[](size_t size) throw(std::bad_alloc)
{
- return MEM_mallocN(size, "C++/anonymous[]");
+ return MEM_mallocN(size, "C++/anonymous[]");
}
-
void operator delete(void *p) throw()
{
- /* delete NULL is valid in c++ */
- if (p)
- MEM_freeN(p);
+ /* delete NULL is valid in c++ */
+ if (p)
+ MEM_freeN(p);
}
void operator delete[](void *p) throw()
{
- /* delete NULL is valid in c++ */
- if (p)
- MEM_freeN(p);
+ /* delete NULL is valid in c++ */
+ if (p)
+ MEM_freeN(p);
}
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index fb778da015a..1c96856fd0d 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -45,7 +45,9 @@ void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_calloc_arrayN;
void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_malloc_arrayN;
-void *(*MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str) = MEM_lockfree_mallocN_aligned;
+void *(*MEM_mallocN_aligned)(size_t len,
+ size_t alignment,
+ const char *str) = MEM_lockfree_mallocN_aligned;
void *(*MEM_mapallocN)(size_t len, const char *str) = MEM_lockfree_mapallocN;
void (*MEM_printmemlist_pydict)(void) = MEM_lockfree_printmemlist_pydict;
void (*MEM_printmemlist)(void) = MEM_lockfree_printmemlist;
@@ -53,7 +55,8 @@ void (*MEM_callbackmemlist)(void (*func)(void *)) = MEM_lockfree_callbackmemlist
void (*MEM_printmemlist_stats)(void) = MEM_lockfree_printmemlist_stats;
void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_error_callback;
bool (*MEM_consistency_check)(void) = MEM_lockfree_consistency_check;
-void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void)) = MEM_lockfree_set_lock_callback;
+void (*MEM_set_lock_callback)(void (*lock)(void),
+ void (*unlock)(void)) = MEM_lockfree_set_lock_callback;
void (*MEM_set_memory_debug)(void) = MEM_lockfree_set_memory_debug;
size_t (*MEM_get_memory_in_use)(void) = MEM_lockfree_get_memory_in_use;
size_t (*MEM_get_mapped_memory_in_use)(void) = MEM_lockfree_get_mapped_memory_in_use;
@@ -68,66 +71,66 @@ const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr;
void *aligned_malloc(size_t size, size_t alignment)
{
#ifdef _WIN32
- return _aligned_malloc(size, alignment);
+ return _aligned_malloc(size, alignment);
#elif defined(__APPLE__)
- /* On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
- * they work natively with SSE types with no further work.
- */
- assert(alignment == 16);
- (void)alignment;
- return malloc(size);
+ /* On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
+ * they work natively with SSE types with no further work.
+ */
+ assert(alignment == 16);
+ (void)alignment;
+ return malloc(size);
#elif defined(__FreeBSD__) || defined(__NetBSD__)
- void *result;
+ void *result;
- if (posix_memalign(&result, alignment, size)) {
- /* non-zero means allocation error
- * either no allocation or bad alignment value
- */
- return NULL;
- }
- return result;
-#else /* This is for Linux. */
- return memalign(alignment, size);
+ if (posix_memalign(&result, alignment, size)) {
+ /* non-zero means allocation error
+ * either no allocation or bad alignment value
+ */
+ return NULL;
+ }
+ return result;
+#else /* This is for Linux. */
+ return memalign(alignment, size);
#endif
}
void aligned_free(void *ptr)
{
#ifdef _WIN32
- _aligned_free(ptr);
+ _aligned_free(ptr);
#else
- free(ptr);
+ free(ptr);
#endif
}
void MEM_use_guarded_allocator(void)
{
- MEM_allocN_len = MEM_guarded_allocN_len;
- MEM_freeN = MEM_guarded_freeN;
- MEM_dupallocN = MEM_guarded_dupallocN;
- MEM_reallocN_id = MEM_guarded_reallocN_id;
- MEM_recallocN_id = MEM_guarded_recallocN_id;
- MEM_callocN = MEM_guarded_callocN;
- MEM_calloc_arrayN = MEM_guarded_calloc_arrayN;
- MEM_mallocN = MEM_guarded_mallocN;
- MEM_malloc_arrayN = MEM_guarded_malloc_arrayN;
- MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
- MEM_mapallocN = MEM_guarded_mapallocN;
- MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
- MEM_printmemlist = MEM_guarded_printmemlist;
- MEM_callbackmemlist = MEM_guarded_callbackmemlist;
- MEM_printmemlist_stats = MEM_guarded_printmemlist_stats;
- MEM_set_error_callback = MEM_guarded_set_error_callback;
- MEM_consistency_check = MEM_guarded_consistency_check;
- MEM_set_lock_callback = MEM_guarded_set_lock_callback;
- MEM_set_memory_debug = MEM_guarded_set_memory_debug;
- MEM_get_memory_in_use = MEM_guarded_get_memory_in_use;
- MEM_get_mapped_memory_in_use = MEM_guarded_get_mapped_memory_in_use;
- MEM_get_memory_blocks_in_use = MEM_guarded_get_memory_blocks_in_use;
- MEM_reset_peak_memory = MEM_guarded_reset_peak_memory;
- MEM_get_peak_memory = MEM_guarded_get_peak_memory;
+ MEM_allocN_len = MEM_guarded_allocN_len;
+ MEM_freeN = MEM_guarded_freeN;
+ MEM_dupallocN = MEM_guarded_dupallocN;
+ MEM_reallocN_id = MEM_guarded_reallocN_id;
+ MEM_recallocN_id = MEM_guarded_recallocN_id;
+ MEM_callocN = MEM_guarded_callocN;
+ MEM_calloc_arrayN = MEM_guarded_calloc_arrayN;
+ MEM_mallocN = MEM_guarded_mallocN;
+ MEM_malloc_arrayN = MEM_guarded_malloc_arrayN;
+ MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
+ MEM_mapallocN = MEM_guarded_mapallocN;
+ MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
+ MEM_printmemlist = MEM_guarded_printmemlist;
+ MEM_callbackmemlist = MEM_guarded_callbackmemlist;
+ MEM_printmemlist_stats = MEM_guarded_printmemlist_stats;
+ MEM_set_error_callback = MEM_guarded_set_error_callback;
+ MEM_consistency_check = MEM_guarded_consistency_check;
+ MEM_set_lock_callback = MEM_guarded_set_lock_callback;
+ MEM_set_memory_debug = MEM_guarded_set_memory_debug;
+ MEM_get_memory_in_use = MEM_guarded_get_memory_in_use;
+ MEM_get_mapped_memory_in_use = MEM_guarded_get_mapped_memory_in_use;
+ MEM_get_memory_blocks_in_use = MEM_guarded_get_memory_blocks_in_use;
+ MEM_reset_peak_memory = MEM_guarded_reset_peak_memory;
+ MEM_get_peak_memory = MEM_guarded_get_peak_memory;
#ifndef NDEBUG
- MEM_name_ptr = MEM_guarded_name_ptr;
+ MEM_name_ptr = MEM_guarded_name_ptr;
#endif
}
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index 9305c11df19..b24e1c8c984 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -73,14 +73,14 @@
#endif
#ifdef DEBUG_MEMCOUNTER
- /* set this to the value that isn't being freed */
+/* set this to the value that isn't being freed */
# define DEBUG_MEMCOUNTER_ERROR_VAL 0
static int _mallocn_count = 0;
/* breakpoint here */
static void memcount_raise(const char *name)
{
- fprintf(stderr, "%s: memcount-leak, %d\n", name, _mallocn_count);
+ fprintf(stderr, "%s: memcount-leak, %d\n", name, _mallocn_count);
}
#endif
@@ -89,36 +89,36 @@ static void memcount_raise(const char *name)
/* --------------------------------------------------------------------- */
/* all memory chunks are put in linked lists */
typedef struct localLink {
- struct localLink *next, *prev;
+ struct localLink *next, *prev;
} localLink;
typedef struct localListBase {
- void *first, *last;
+ void *first, *last;
} localListBase;
/* note: keep this struct aligned (e.g., irix/gcc) - Hos */
typedef struct MemHead {
- int tag1;
- size_t len;
- struct MemHead *next, *prev;
- const char *name;
- const char *nextname;
- int tag2;
- short mmap; /* if true, memory was mmapped */
- short alignment; /* if non-zero aligned alloc was used
- * and alignment is stored here.
- */
+ int tag1;
+ size_t len;
+ struct MemHead *next, *prev;
+ const char *name;
+ const char *nextname;
+ int tag2;
+ short mmap; /* if true, memory was mmapped */
+ short alignment; /* if non-zero aligned alloc was used
+ * and alignment is stored here.
+ */
#ifdef DEBUG_MEMCOUNTER
- int _count;
+ int _count;
#endif
#ifdef DEBUG_MEMDUPLINAME
- int need_free_name, pad;
+ int need_free_name, pad;
#endif
#ifdef DEBUG_BACKTRACE
- void *backtrace[BACKTRACE_SIZE];
- int backtrace_size;
+ void *backtrace[BACKTRACE_SIZE];
+ int backtrace_size;
#endif
} MemHead;
@@ -128,12 +128,12 @@ typedef MemHead MemHeadAligned;
* we may need to extend this if blender code starts using MEM_
* functions inside OpenMP correctly with omp_set_lock() */
-#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
-#if defined(_OPENMP) && defined(DEBUG)
-# include <assert.h>
-# include <omp.h>
-# define DEBUG_OMP_MALLOC
-#endif
+#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
+# if defined(_OPENMP) && defined(DEBUG)
+# include <assert.h>
+# include <omp.h>
+# define DEBUG_OMP_MALLOC
+# endif
#endif
#ifdef DEBUG_THREADS
@@ -152,10 +152,9 @@ static pthread_t mainid;
#endif
typedef struct MemTail {
- int tag3, pad;
+ int tag3, pad;
} MemTail;
-
/* --------------------------------------------------------------------- */
/* local functions */
/* --------------------------------------------------------------------- */
@@ -181,14 +180,12 @@ static const char *check_memlist(MemHead *memh);
#define MEMTAG3 MAKE_ID('O', 'C', 'K', '!')
#define MEMFREE MAKE_ID('F', 'R', 'E', 'E')
-#define MEMNEXT(x) \
- ((MemHead *)(((char *) x) - ((char *) &(((MemHead *)0)->next))))
+#define MEMNEXT(x) ((MemHead *)(((char *)x) - ((char *)&(((MemHead *)0)->next))))
/* --------------------------------------------------------------------- */
/* vars */
/* --------------------------------------------------------------------- */
-
static unsigned int totblock = 0;
static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
@@ -201,777 +198,808 @@ static void (*thread_unlock_callback)(void) = NULL;
static bool malloc_debug_memset = false;
#ifdef malloc
-#undef malloc
+# undef malloc
#endif
#ifdef calloc
-#undef calloc
+# undef calloc
#endif
#ifdef free
-#undef free
+# undef free
#endif
-
/* --------------------------------------------------------------------- */
/* implementation */
/* --------------------------------------------------------------------- */
#ifdef __GNUC__
-__attribute__ ((format(printf, 1, 2)))
+__attribute__((format(printf, 1, 2)))
#endif
-static void print_error(const char *str, ...)
+static void
+print_error(const char *str, ...)
{
- char buf[1024];
- va_list ap;
-
- va_start(ap, str);
- vsnprintf(buf, sizeof(buf), str, ap);
- va_end(ap);
- buf[sizeof(buf) - 1] = '\0';
-
- if (error_callback)
- error_callback(buf);
- else
- fputs(buf, stderr);
+ char buf[1024];
+ va_list ap;
+
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+ buf[sizeof(buf) - 1] = '\0';
+
+ if (error_callback)
+ error_callback(buf);
+ else
+ fputs(buf, stderr);
}
static void mem_lock_thread(void)
{
#ifdef DEBUG_THREADS
- static int initialized = 0;
+ static int initialized = 0;
- if (initialized == 0) {
- /* assume first allocation happens from main thread */
- mainid = pthread_self();
- initialized = 1;
- }
+ if (initialized == 0) {
+ /* assume first allocation happens from main thread */
+ mainid = pthread_self();
+ initialized = 1;
+ }
- if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
- assert(!"Memory function is called from non-main thread without lock");
- }
+ if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
+ assert(!"Memory function is called from non-main thread without lock");
+ }
#endif
#ifdef DEBUG_OMP_MALLOC
- assert(omp_in_parallel() == 0);
+ assert(omp_in_parallel() == 0);
#endif
- if (thread_lock_callback)
- thread_lock_callback();
+ if (thread_lock_callback)
+ thread_lock_callback();
}
static void mem_unlock_thread(void)
{
#ifdef DEBUG_THREADS
- if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
- assert(!"Thread lock was removed while allocation from thread is in progress");
- }
+ if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
+ assert(!"Thread lock was removed while allocation from thread is in progress");
+ }
#endif
- if (thread_unlock_callback)
- thread_unlock_callback();
+ if (thread_unlock_callback)
+ thread_unlock_callback();
}
bool MEM_guarded_consistency_check(void)
{
- const char *err_val = NULL;
- MemHead *listend;
- /* check_memlist starts from the front, and runs until it finds
- * the requested chunk. For this test, that's the last one. */
- listend = membase->last;
+ const char *err_val = NULL;
+ MemHead *listend;
+ /* check_memlist starts from the front, and runs until it finds
+ * the requested chunk. For this test, that's the last one. */
+ listend = membase->last;
- err_val = check_memlist(listend);
+ err_val = check_memlist(listend);
- return (err_val == NULL);
+ return (err_val == NULL);
}
-
void MEM_guarded_set_error_callback(void (*func)(const char *))
{
- error_callback = func;
+ error_callback = func;
}
void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void))
{
- thread_lock_callback = lock;
- thread_unlock_callback = unlock;
+ thread_lock_callback = lock;
+ thread_unlock_callback = unlock;
}
void MEM_guarded_set_memory_debug(void)
{
- malloc_debug_memset = true;
+ malloc_debug_memset = true;
}
size_t MEM_guarded_allocN_len(const void *vmemh)
{
- if (vmemh) {
- const MemHead *memh = vmemh;
-
- memh--;
- return memh->len;
- }
- else {
- return 0;
- }
+ if (vmemh) {
+ const MemHead *memh = vmemh;
+
+ memh--;
+ return memh->len;
+ }
+ else {
+ return 0;
+ }
}
void *MEM_guarded_dupallocN(const void *vmemh)
{
- void *newp = NULL;
+ void *newp = NULL;
- if (vmemh) {
- const MemHead *memh = vmemh;
- memh--;
+ if (vmemh) {
+ const MemHead *memh = vmemh;
+ memh--;
#ifndef DEBUG_MEMDUPLINAME
- if (UNLIKELY(memh->mmap))
- newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
- else if (LIKELY(memh->alignment == 0))
- newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
- else
- newp = MEM_guarded_mallocN_aligned(memh->len, (size_t) memh->alignment, "dupli_alloc");
-
- if (newp == NULL) return NULL;
+ if (UNLIKELY(memh->mmap))
+ newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
+ else if (LIKELY(memh->alignment == 0))
+ newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
+ else
+ newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, "dupli_alloc");
+
+ if (newp == NULL)
+ return NULL;
#else
- {
- MemHead *nmemh;
- char *name = malloc(strlen(memh->name) + 24);
-
- if (UNLIKELY(memh->mmap)) {
- sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
- newp = MEM_guarded_mapallocN(memh->len, name);
- }
- else if (LIKELY(memh->alignment == 0)) {
- sprintf(name, "%s %s", "dupli_alloc", memh->name);
- newp = MEM_guarded_mallocN(memh->len, name);
- }
- else {
- sprintf(name, "%s %s", "dupli_alloc", memh->name);
- newp = MEM_guarded_mallocN_aligned(memh->len, (size_t) memh->alignment, name);
- }
-
- if (newp == NULL) return NULL;
-
- nmemh = newp;
- nmemh--;
-
- nmemh->need_free_name = 1;
- }
+ {
+ MemHead *nmemh;
+ char *name = malloc(strlen(memh->name) + 24);
+
+ if (UNLIKELY(memh->mmap)) {
+ sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
+ newp = MEM_guarded_mapallocN(memh->len, name);
+ }
+ else if (LIKELY(memh->alignment == 0)) {
+ sprintf(name, "%s %s", "dupli_alloc", memh->name);
+ newp = MEM_guarded_mallocN(memh->len, name);
+ }
+ else {
+ sprintf(name, "%s %s", "dupli_alloc", memh->name);
+ newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, name);
+ }
+
+ if (newp == NULL)
+ return NULL;
+
+ nmemh = newp;
+ nmemh--;
+
+ nmemh->need_free_name = 1;
+ }
#endif
- memcpy(newp, vmemh, memh->len);
- }
+ memcpy(newp, vmemh, memh->len);
+ }
- return newp;
+ return newp;
}
void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
-
- if (LIKELY(memh->alignment == 0)) {
- newp = MEM_guarded_mallocN(len, memh->name);
- }
- else {
- newp = MEM_guarded_mallocN_aligned(len, (size_t) memh->alignment, memh->name);
- }
-
- if (newp) {
- if (len < memh->len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- /* grow (or remain same size) */
- memcpy(newp, vmemh, memh->len);
- }
- }
-
- MEM_guarded_freeN(vmemh);
- }
- else {
- newp = MEM_guarded_mallocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+
+ if (LIKELY(memh->alignment == 0)) {
+ newp = MEM_guarded_mallocN(len, memh->name);
+ }
+ else {
+ newp = MEM_guarded_mallocN_aligned(len, (size_t)memh->alignment, memh->name);
+ }
+
+ if (newp) {
+ if (len < memh->len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ /* grow (or remain same size) */
+ memcpy(newp, vmemh, memh->len);
+ }
+ }
+
+ MEM_guarded_freeN(vmemh);
+ }
+ else {
+ newp = MEM_guarded_mallocN(len, str);
+ }
+
+ return newp;
}
void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
-
- if (LIKELY(memh->alignment == 0)) {
- newp = MEM_guarded_mallocN(len, memh->name);
- }
- else {
- newp = MEM_guarded_mallocN_aligned(len, (size_t) memh->alignment, memh->name);
- }
-
- if (newp) {
- if (len < memh->len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- memcpy(newp, vmemh, memh->len);
-
- if (len > memh->len) {
- /* grow */
- /* zero new bytes */
- memset(((char *)newp) + memh->len, 0, len - memh->len);
- }
- }
- }
-
- MEM_guarded_freeN(vmemh);
- }
- else {
- newp = MEM_guarded_callocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+
+ if (LIKELY(memh->alignment == 0)) {
+ newp = MEM_guarded_mallocN(len, memh->name);
+ }
+ else {
+ newp = MEM_guarded_mallocN_aligned(len, (size_t)memh->alignment, memh->name);
+ }
+
+ if (newp) {
+ if (len < memh->len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ memcpy(newp, vmemh, memh->len);
+
+ if (len > memh->len) {
+ /* grow */
+ /* zero new bytes */
+ memset(((char *)newp) + memh->len, 0, len - memh->len);
+ }
+ }
+ }
+
+ MEM_guarded_freeN(vmemh);
+ }
+ else {
+ newp = MEM_guarded_callocN(len, str);
+ }
+
+ return newp;
}
#ifdef DEBUG_BACKTRACE
# if defined(__linux__) || defined(__APPLE__)
static void make_memhead_backtrace(MemHead *memh)
{
- memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE);
+ memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE);
}
static void print_memhead_backtrace(MemHead *memh)
{
- char **strings;
- int i;
+ char **strings;
+ int i;
- strings = backtrace_symbols(memh->backtrace, memh->backtrace_size);
- for (i = 0; i < memh->backtrace_size; i++) {
- print_error(" %s\n", strings[i]);
- }
+ strings = backtrace_symbols(memh->backtrace, memh->backtrace_size);
+ for (i = 0; i < memh->backtrace_size; i++) {
+ print_error(" %s\n", strings[i]);
+ }
- free(strings);
+ free(strings);
}
# else
static void make_memhead_backtrace(MemHead *memh)
{
- (void) memh; /* Ignored. */
+ (void)memh; /* Ignored. */
}
static void print_memhead_backtrace(MemHead *memh)
{
- (void) memh; /* Ignored. */
+ (void)memh; /* Ignored. */
}
-# endif /* defined(__linux__) || defined(__APPLE__) */
-#endif /* DEBUG_BACKTRACE */
+# endif /* defined(__linux__) || defined(__APPLE__) */
+#endif /* DEBUG_BACKTRACE */
static void make_memhead_header(MemHead *memh, size_t len, const char *str)
{
- MemTail *memt;
+ MemTail *memt;
- memh->tag1 = MEMTAG1;
- memh->name = str;
- memh->nextname = NULL;
- memh->len = len;
- memh->mmap = 0;
- memh->alignment = 0;
- memh->tag2 = MEMTAG2;
+ memh->tag1 = MEMTAG1;
+ memh->name = str;
+ memh->nextname = NULL;
+ memh->len = len;
+ memh->mmap = 0;
+ memh->alignment = 0;
+ memh->tag2 = MEMTAG2;
#ifdef DEBUG_MEMDUPLINAME
- memh->need_free_name = 0;
+ memh->need_free_name = 0;
#endif
#ifdef DEBUG_BACKTRACE
- make_memhead_backtrace(memh);
+ make_memhead_backtrace(memh);
#endif
- memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len);
- memt->tag3 = MEMTAG3;
+ memt = (MemTail *)(((char *)memh) + sizeof(MemHead) + len);
+ memt->tag3 = MEMTAG3;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
- mem_lock_thread();
- addtail(membase, &memh->next);
- if (memh->next) {
- memh->nextname = MEMNEXT(memh->next)->name;
- }
- peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
- mem_unlock_thread();
+ mem_lock_thread();
+ addtail(membase, &memh->next);
+ if (memh->next) {
+ memh->nextname = MEMNEXT(memh->next)->name;
+ }
+ peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+ mem_unlock_thread();
}
void *MEM_guarded_mallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
+ memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
- if (LIKELY(memh)) {
- make_memhead_header(memh, len, str);
- if (UNLIKELY(malloc_debug_memset && len))
- memset(memh + 1, 255, len);
+ if (LIKELY(memh)) {
+ make_memhead_header(memh, len, str);
+ if (UNLIKELY(malloc_debug_memset && len))
+ memset(memh + 1, 255, len);
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return (++memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Malloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_guarded_mallocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Malloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_guarded_mallocN(total_size, str);
}
void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- /* It's possible that MemHead's size is not properly aligned,
- * do extra padding to deal with this.
- *
- * We only support small alignments which fits into short in
- * order to save some bits in MemHead structure.
- */
- size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
+ /* It's possible that MemHead's size is not properly aligned,
+ * do extra padding to deal with this.
+ *
+ * We only support small alignments which fits into short in
+ * order to save some bits in MemHead structure.
+ */
+ size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
- /* Huge alignment values doesn't make sense and they
- * wouldn't fit into 'short' used in the MemHead.
- */
- assert(alignment < 1024);
+ /* Huge alignment values doesn't make sense and they
+ * wouldn't fit into 'short' used in the MemHead.
+ */
+ assert(alignment < 1024);
- /* We only support alignment to a power of two. */
- assert(IS_POW2(alignment));
+ /* We only support alignment to a power of two. */
+ assert(IS_POW2(alignment));
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)aligned_malloc(len + extra_padding + sizeof(MemHead) + sizeof(MemTail), alignment);
+ memh = (MemHead *)aligned_malloc(len + extra_padding + sizeof(MemHead) + sizeof(MemTail),
+ alignment);
- if (LIKELY(memh)) {
- /* We keep padding in the beginning of MemHead,
- * this way it's always possible to get MemHead
- * from the data pointer.
- */
- memh = (MemHead *)((char *)memh + extra_padding);
+ if (LIKELY(memh)) {
+ /* We keep padding in the beginning of MemHead,
+ * this way it's always possible to get MemHead
+ * from the data pointer.
+ */
+ memh = (MemHead *)((char *)memh + extra_padding);
- make_memhead_header(memh, len, str);
- memh->alignment = (short) alignment;
- if (UNLIKELY(malloc_debug_memset && len))
- memset(memh + 1, 255, len);
+ make_memhead_header(memh, len, str);
+ memh->alignment = (short)alignment;
+ if (UNLIKELY(malloc_debug_memset && len))
+ memset(memh + 1, 255, len);
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- print_error("aligned_malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return (++memh);
+ }
+ print_error("aligned_malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_guarded_callocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)calloc(len + sizeof(MemHead) + sizeof(MemTail), 1);
+ memh = (MemHead *)calloc(len + sizeof(MemHead) + sizeof(MemTail), 1);
- if (memh) {
- make_memhead_header(memh, len, str);
+ if (memh) {
+ make_memhead_header(memh, len, str);
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return (++memh);
+ }
+ print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Calloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_guarded_callocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Calloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_guarded_callocN(total_size, str);
}
/* note; mmap returns zero'd memory */
void *MEM_guarded_mapallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- /* on 64 bit, simply use calloc instead, as mmap does not support
- * allocating > 4 GB on Windows. the only reason mapalloc exists
- * is to get around address space limitations in 32 bit OSes. */
- if (sizeof(void *) >= 8)
- return MEM_guarded_callocN(len, str);
+ /* on 64 bit, simply use calloc instead, as mmap does not support
+ * allocating > 4 GB on Windows. the only reason mapalloc exists
+ * is to get around address space limitations in 32 bit OSes. */
+ if (sizeof(void *) >= 8)
+ return MEM_guarded_callocN(len, str);
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- memh = mmap(NULL, len + sizeof(MemHead) + sizeof(MemTail),
- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+ memh = mmap(NULL,
+ len + sizeof(MemHead) + sizeof(MemTail),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANON,
+ -1,
+ 0);
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- if (memh != (MemHead *)-1) {
- make_memhead_header(memh, len, str);
- memh->mmap = 1;
- atomic_add_and_fetch_z(&mmap_in_use, len);
- mem_lock_thread();
- peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
- mem_unlock_thread();
+ if (memh != (MemHead *)-1) {
+ make_memhead_header(memh, len, str);
+ memh->mmap = 1;
+ atomic_add_and_fetch_z(&mmap_in_use, len);
+ mem_lock_thread();
+ peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
+ mem_unlock_thread();
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- else {
- print_error("Mapalloc returns null, fallback to regular malloc: "
- "len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mmap_in_use);
- return MEM_guarded_callocN(len, str);
- }
+ return (++memh);
+ }
+ else {
+ print_error(
+ "Mapalloc returns null, fallback to regular malloc: "
+ "len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mmap_in_use);
+ return MEM_guarded_callocN(len, str);
+ }
}
/* Memory statistics print */
typedef struct MemPrintBlock {
- const char *name;
- uintptr_t len;
- int items;
+ const char *name;
+ uintptr_t len;
+ int items;
} MemPrintBlock;
static int compare_name(const void *p1, const void *p2)
{
- const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
- const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
+ const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
+ const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
- return strcmp(pb1->name, pb2->name);
+ return strcmp(pb1->name, pb2->name);
}
static int compare_len(const void *p1, const void *p2)
{
- const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
- const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
-
- if (pb1->len < pb2->len)
- return 1;
- else if (pb1->len == pb2->len)
- return 0;
- else
- return -1;
+ const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
+ const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
+
+ if (pb1->len < pb2->len)
+ return 1;
+ else if (pb1->len == pb2->len)
+ return 0;
+ else
+ return -1;
}
void MEM_guarded_printmemlist_stats(void)
{
- MemHead *membl;
- MemPrintBlock *pb, *printblock;
- unsigned int totpb, a, b;
- size_t mem_in_use_slop = 0;
+ MemHead *membl;
+ MemPrintBlock *pb, *printblock;
+ unsigned int totpb, a, b;
+ size_t mem_in_use_slop = 0;
- mem_lock_thread();
+ mem_lock_thread();
- /* put memory blocks into array */
- printblock = malloc(sizeof(MemPrintBlock) * totblock);
+ /* put memory blocks into array */
+ printblock = malloc(sizeof(MemPrintBlock) * totblock);
- pb = printblock;
- totpb = 0;
+ pb = printblock;
+ totpb = 0;
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
+ membl = membase->first;
+ if (membl)
+ membl = MEMNEXT(membl);
- while (membl) {
- pb->name = membl->name;
- pb->len = membl->len;
- pb->items = 1;
+ while (membl) {
+ pb->name = membl->name;
+ pb->len = membl->len;
+ pb->items = 1;
- totpb++;
- pb++;
+ totpb++;
+ pb++;
#ifdef USE_MALLOC_USABLE_SIZE
- if (!membl->mmap && membl->alignment == 0) {
- mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) +
- malloc_usable_size((void *)membl)) - membl->len;
- }
+ if (!membl->mmap && membl->alignment == 0) {
+ mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) + malloc_usable_size((void *)membl)) -
+ membl->len;
+ }
#endif
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
-
- /* sort by name and add together blocks with the same name */
- qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
- for (a = 0, b = 0; a < totpb; a++) {
- if (a == b) {
- continue;
- }
- else if (strcmp(printblock[a].name, printblock[b].name) == 0) {
- printblock[b].len += printblock[a].len;
- printblock[b].items++;
- }
- else {
- b++;
- memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
- }
- }
- totpb = b + 1;
-
- /* sort by length and print */
- qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
- printf("\ntotal memory len: %.3f MB\n",
- (double)mem_in_use / (double)(1024 * 1024));
- printf("peak memory len: %.3f MB\n",
- (double)peak_mem / (double)(1024 * 1024));
- printf("slop memory len: %.3f MB\n",
- (double)mem_in_use_slop / (double)(1024 * 1024));
- printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
- for (a = 0, pb = printblock; a < totpb; a++, pb++) {
- printf("%6d (%8.3f %8.3f) %s\n",
- pb->items, (double)pb->len / (double)(1024 * 1024),
- (double)pb->len / 1024.0 / (double)pb->items, pb->name);
- }
- free(printblock);
-
- mem_unlock_thread();
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else
+ break;
+ }
+
+ /* sort by name and add together blocks with the same name */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
+ for (a = 0, b = 0; a < totpb; a++) {
+ if (a == b) {
+ continue;
+ }
+ else if (strcmp(printblock[a].name, printblock[b].name) == 0) {
+ printblock[b].len += printblock[a].len;
+ printblock[b].items++;
+ }
+ else {
+ b++;
+ memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
+ }
+ }
+ totpb = b + 1;
+
+ /* sort by length and print */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
+ printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n", (double)peak_mem / (double)(1024 * 1024));
+ printf("slop memory len: %.3f MB\n", (double)mem_in_use_slop / (double)(1024 * 1024));
+ printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
+ for (a = 0, pb = printblock; a < totpb; a++, pb++) {
+ printf("%6d (%8.3f %8.3f) %s\n",
+ pb->items,
+ (double)pb->len / (double)(1024 * 1024),
+ (double)pb->len / 1024.0 / (double)pb->items,
+ pb->name);
+ }
+ free(printblock);
+
+ mem_unlock_thread();
#ifdef HAVE_MALLOC_STATS
- printf("System Statistics:\n");
- malloc_stats();
+ printf("System Statistics:\n");
+ malloc_stats();
#endif
}
static const char mem_printmemlist_pydict_script[] =
-"mb_userinfo = {}\n"
-"totmem = 0\n"
-"for mb_item in membase:\n"
-" mb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n"
-" mb_item_user_size[0] += 1 # Add a user\n"
-" mb_item_user_size[1] += mb_item['len'] # Increment the size\n"
-" totmem += mb_item['len']\n"
-"print('(membase) items:', len(membase), '| unique-names:',\n"
-" len(mb_userinfo), '| total-mem:', totmem)\n"
-"mb_userinfo_sort = list(mb_userinfo.items())\n"
-"for sort_name, sort_func in (('size', lambda a: -a[1][1]),\n"
-" ('users', lambda a: -a[1][0]),\n"
-" ('name', lambda a: a[0])):\n"
-" print('\\nSorting by:', sort_name)\n"
-" mb_userinfo_sort.sort(key = sort_func)\n"
-" for item in mb_userinfo_sort:\n"
-" print('name:%%s, users:%%i, len:%%i' %%\n"
-" (item[0], item[1][0], item[1][1]))\n";
+ "mb_userinfo = {}\n"
+ "totmem = 0\n"
+ "for mb_item in membase:\n"
+ " mb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n"
+ " mb_item_user_size[0] += 1 # Add a user\n"
+ " mb_item_user_size[1] += mb_item['len'] # Increment the size\n"
+ " totmem += mb_item['len']\n"
+ "print('(membase) items:', len(membase), '| unique-names:',\n"
+ " len(mb_userinfo), '| total-mem:', totmem)\n"
+ "mb_userinfo_sort = list(mb_userinfo.items())\n"
+ "for sort_name, sort_func in (('size', lambda a: -a[1][1]),\n"
+ " ('users', lambda a: -a[1][0]),\n"
+ " ('name', lambda a: a[0])):\n"
+ " print('\\nSorting by:', sort_name)\n"
+ " mb_userinfo_sort.sort(key = sort_func)\n"
+ " for item in mb_userinfo_sort:\n"
+ " print('name:%%s, users:%%i, len:%%i' %%\n"
+ " (item[0], item[1][0], item[1][1]))\n";
/* Prints in python syntax for easy */
static void MEM_guarded_printmemlist_internal(int pydict)
{
- MemHead *membl;
-
- mem_lock_thread();
-
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
-
- if (pydict) {
- print_error("# membase_debug.py\n");
- print_error("membase = [\n");
- }
- while (membl) {
- if (pydict) {
- print_error(" {'len':" SIZET_FORMAT ", "
- "'name':'''%s''', "
- "'pointer':'%p'},\n",
- SIZET_ARG(membl->len), membl->name, (void *)(membl + 1));
- }
- else {
+ MemHead *membl;
+
+ mem_lock_thread();
+
+ membl = membase->first;
+ if (membl)
+ membl = MEMNEXT(membl);
+
+ if (pydict) {
+ print_error("# membase_debug.py\n");
+ print_error("membase = [\n");
+ }
+ while (membl) {
+ if (pydict) {
+ print_error(" {'len':" SIZET_FORMAT
+ ", "
+ "'name':'''%s''', "
+ "'pointer':'%p'},\n",
+ SIZET_ARG(membl->len),
+ membl->name,
+ (void *)(membl + 1));
+ }
+ else {
#ifdef DEBUG_MEMCOUNTER
- print_error("%s len: " SIZET_FORMAT " %p, count: %d\n",
- membl->name, SIZET_ARG(membl->len), membl + 1,
- membl->_count);
+ print_error("%s len: " SIZET_FORMAT " %p, count: %d\n",
+ membl->name,
+ SIZET_ARG(membl->len),
+ membl + 1,
+ membl->_count);
#else
- print_error("%s len: " SIZET_FORMAT " %p\n",
- membl->name, SIZET_ARG(membl->len), (void *)(membl + 1));
+ print_error("%s len: " SIZET_FORMAT " %p\n",
+ membl->name,
+ SIZET_ARG(membl->len),
+ (void *)(membl + 1));
#endif
#ifdef DEBUG_BACKTRACE
- print_memhead_backtrace(membl);
+ print_memhead_backtrace(membl);
#endif
- }
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
- if (pydict) {
- print_error("]\n\n");
- print_error(mem_printmemlist_pydict_script);
- }
-
- mem_unlock_thread();
+ }
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else
+ break;
+ }
+ if (pydict) {
+ print_error("]\n\n");
+ print_error(mem_printmemlist_pydict_script);
+ }
+
+ mem_unlock_thread();
}
void MEM_guarded_callbackmemlist(void (*func)(void *))
{
- MemHead *membl;
+ MemHead *membl;
- mem_lock_thread();
+ mem_lock_thread();
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
+ membl = membase->first;
+ if (membl)
+ membl = MEMNEXT(membl);
- while (membl) {
- func(membl + 1);
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
+ while (membl) {
+ func(membl + 1);
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else
+ break;
+ }
- mem_unlock_thread();
+ mem_unlock_thread();
}
#if 0
short MEM_guarded_testN(void *vmemh)
{
- MemHead *membl;
+ MemHead *membl;
- mem_lock_thread();
+ mem_lock_thread();
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
- while (membl) {
- if (vmemh == membl + 1) {
- mem_unlock_thread();
- return 1;
- }
+ while (membl) {
+ if (vmemh == membl + 1) {
+ mem_unlock_thread();
+ return 1;
+ }
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else break;
+ }
- mem_unlock_thread();
+ mem_unlock_thread();
- print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
- return 0;
+ print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
+ return 0;
}
#endif
void MEM_guarded_printmemlist(void)
{
- MEM_guarded_printmemlist_internal(0);
+ MEM_guarded_printmemlist_internal(0);
}
void MEM_guarded_printmemlist_pydict(void)
{
- MEM_guarded_printmemlist_internal(1);
+ MEM_guarded_printmemlist_internal(1);
}
void MEM_guarded_freeN(void *vmemh)
{
- MemTail *memt;
- MemHead *memh = vmemh;
- const char *name;
-
- if (memh == NULL) {
- MemorY_ErroR("free", "attempt to free NULL pointer");
- /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
- return;
- }
-
- if (sizeof(intptr_t) == 8) {
- if (((intptr_t) memh) & 0x7) {
- MemorY_ErroR("free", "attempt to free illegal pointer");
- return;
- }
- }
- else {
- if (((intptr_t) memh) & 0x3) {
- MemorY_ErroR("free", "attempt to free illegal pointer");
- return;
- }
- }
-
- memh--;
- if (memh->tag1 == MEMFREE && memh->tag2 == MEMFREE) {
- MemorY_ErroR(memh->name, "double free");
- return;
- }
-
- if ((memh->tag1 == MEMTAG1) &&
- (memh->tag2 == MEMTAG2) &&
- ((memh->len & 0x3) == 0))
- {
- memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + memh->len);
- if (memt->tag3 == MEMTAG3) {
-
- memh->tag1 = MEMFREE;
- memh->tag2 = MEMFREE;
- memt->tag3 = MEMFREE;
- /* after tags !!! */
- rem_memblock(memh);
-
- return;
- }
- MemorY_ErroR(memh->name, "end corrupt");
- name = check_memlist(memh);
- if (name != NULL) {
- if (name != memh->name) MemorY_ErroR(name, "is also corrupt");
- }
- }
- else {
- mem_lock_thread();
- name = check_memlist(memh);
- mem_unlock_thread();
- if (name == NULL)
- MemorY_ErroR("free", "pointer not in memlist");
- else
- MemorY_ErroR(name, "error in header");
- }
-
- totblock--;
- /* here a DUMP should happen */
-
- return;
+ MemTail *memt;
+ MemHead *memh = vmemh;
+ const char *name;
+
+ if (memh == NULL) {
+ MemorY_ErroR("free", "attempt to free NULL pointer");
+ /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
+ return;
+ }
+
+ if (sizeof(intptr_t) == 8) {
+ if (((intptr_t)memh) & 0x7) {
+ MemorY_ErroR("free", "attempt to free illegal pointer");
+ return;
+ }
+ }
+ else {
+ if (((intptr_t)memh) & 0x3) {
+ MemorY_ErroR("free", "attempt to free illegal pointer");
+ return;
+ }
+ }
+
+ memh--;
+ if (memh->tag1 == MEMFREE && memh->tag2 == MEMFREE) {
+ MemorY_ErroR(memh->name, "double free");
+ return;
+ }
+
+ if ((memh->tag1 == MEMTAG1) && (memh->tag2 == MEMTAG2) && ((memh->len & 0x3) == 0)) {
+ memt = (MemTail *)(((char *)memh) + sizeof(MemHead) + memh->len);
+ if (memt->tag3 == MEMTAG3) {
+
+ memh->tag1 = MEMFREE;
+ memh->tag2 = MEMFREE;
+ memt->tag3 = MEMFREE;
+ /* after tags !!! */
+ rem_memblock(memh);
+
+ return;
+ }
+ MemorY_ErroR(memh->name, "end corrupt");
+ name = check_memlist(memh);
+ if (name != NULL) {
+ if (name != memh->name)
+ MemorY_ErroR(name, "is also corrupt");
+ }
+ }
+ else {
+ mem_lock_thread();
+ name = check_memlist(memh);
+ mem_unlock_thread();
+ if (name == NULL)
+ MemorY_ErroR("free", "pointer not in memlist");
+ else
+ MemorY_ErroR(name, "error in header");
+ }
+
+ totblock--;
+ /* here a DUMP should happen */
+
+ return;
}
/* --------------------------------------------------------------------- */
@@ -980,243 +1008,271 @@ void MEM_guarded_freeN(void *vmemh)
static void addtail(volatile localListBase *listbase, void *vlink)
{
- struct localLink *link = vlink;
+ struct localLink *link = vlink;
- /* for a generic API error checks here is fine but
- * the limited use here they will never be NULL */
+ /* for a generic API error checks here is fine but
+ * the limited use here they will never be NULL */
#if 0
- if (link == NULL) return;
- if (listbase == NULL) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
#endif
- link->next = NULL;
- link->prev = listbase->last;
+ link->next = NULL;
+ link->prev = listbase->last;
- if (listbase->last) ((struct localLink *)listbase->last)->next = link;
- if (listbase->first == NULL) listbase->first = link;
- listbase->last = link;
+ if (listbase->last)
+ ((struct localLink *)listbase->last)->next = link;
+ if (listbase->first == NULL)
+ listbase->first = link;
+ listbase->last = link;
}
static void remlink(volatile localListBase *listbase, void *vlink)
{
- struct localLink *link = vlink;
+ struct localLink *link = vlink;
- /* for a generic API error checks here is fine but
- * the limited use here they will never be NULL */
+ /* for a generic API error checks here is fine but
+ * the limited use here they will never be NULL */
#if 0
- if (link == NULL) return;
- if (listbase == NULL) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
#endif
- if (link->next) link->next->prev = link->prev;
- if (link->prev) link->prev->next = link->next;
+ if (link->next)
+ link->next->prev = link->prev;
+ if (link->prev)
+ link->prev->next = link->next;
- if (listbase->last == link) listbase->last = link->prev;
- if (listbase->first == link) listbase->first = link->next;
+ if (listbase->last == link)
+ listbase->last = link->prev;
+ if (listbase->first == link)
+ listbase->first = link->next;
}
static void rem_memblock(MemHead *memh)
{
- mem_lock_thread();
- remlink(membase, &memh->next);
- if (memh->prev) {
- if (memh->next)
- MEMNEXT(memh->prev)->nextname = MEMNEXT(memh->next)->name;
- else
- MEMNEXT(memh->prev)->nextname = NULL;
- }
- mem_unlock_thread();
-
- atomic_sub_and_fetch_u(&totblock, 1);
- atomic_sub_and_fetch_z(&mem_in_use, memh->len);
+ mem_lock_thread();
+ remlink(membase, &memh->next);
+ if (memh->prev) {
+ if (memh->next)
+ MEMNEXT(memh->prev)->nextname = MEMNEXT(memh->next)->name;
+ else
+ MEMNEXT(memh->prev)->nextname = NULL;
+ }
+ mem_unlock_thread();
+
+ atomic_sub_and_fetch_u(&totblock, 1);
+ atomic_sub_and_fetch_z(&mem_in_use, memh->len);
#ifdef DEBUG_MEMDUPLINAME
- if (memh->need_free_name)
- free((char *) memh->name);
+ if (memh->need_free_name)
+ free((char *)memh->name);
#endif
- if (memh->mmap) {
- atomic_sub_and_fetch_z(&mmap_in_use, memh->len);
+ if (memh->mmap) {
+ atomic_sub_and_fetch_z(&mmap_in_use, memh->len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
- printf("Couldn't unmap memory %s\n", memh->name);
+ if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
+ printf("Couldn't unmap memory %s\n", memh->name);
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- }
- else {
- if (UNLIKELY(malloc_debug_memset && memh->len))
- memset(memh + 1, 255, memh->len);
- if (LIKELY(memh->alignment == 0)) {
- free(memh);
- }
- else {
- aligned_free(MEMHEAD_REAL_PTR(memh));
- }
- }
+ }
+ else {
+ if (UNLIKELY(malloc_debug_memset && memh->len))
+ memset(memh + 1, 255, memh->len);
+ if (LIKELY(memh->alignment == 0)) {
+ free(memh);
+ }
+ else {
+ aligned_free(MEMHEAD_REAL_PTR(memh));
+ }
+ }
}
static void MemorY_ErroR(const char *block, const char *error)
{
- print_error("Memoryblock %s: %s\n", block, error);
+ print_error("Memoryblock %s: %s\n", block, error);
#ifdef WITH_ASSERT_ABORT
- abort();
+ abort();
#endif
}
static const char *check_memlist(MemHead *memh)
{
- MemHead *forw, *back, *forwok, *backok;
- const char *name;
-
- forw = membase->first;
- if (forw) forw = MEMNEXT(forw);
- forwok = NULL;
- while (forw) {
- if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
- forwok = forw;
- if (forw->next) forw = MEMNEXT(forw->next);
- else forw = NULL;
- }
-
- back = (MemHead *) membase->last;
- if (back) back = MEMNEXT(back);
- backok = NULL;
- while (back) {
- if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
- backok = back;
- if (back->prev) back = MEMNEXT(back->prev);
- else back = NULL;
- }
-
- if (forw != back) return ("MORE THAN 1 MEMORYBLOCK CORRUPT");
-
- if (forw == NULL && back == NULL) {
- /* no wrong headers found then but in search of memblock */
-
- forw = membase->first;
- if (forw) forw = MEMNEXT(forw);
- forwok = NULL;
- while (forw) {
- if (forw == memh) break;
- if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
- forwok = forw;
- if (forw->next) forw = MEMNEXT(forw->next);
- else forw = NULL;
- }
- if (forw == NULL) return NULL;
-
- back = (MemHead *) membase->last;
- if (back) back = MEMNEXT(back);
- backok = NULL;
- while (back) {
- if (back == memh) break;
- if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
- backok = back;
- if (back->prev) back = MEMNEXT(back->prev);
- else back = NULL;
- }
- }
-
- if (forwok) name = forwok->nextname;
- else name = "No name found";
-
- if (forw == memh) {
- /* to be sure but this block is removed from the list */
- if (forwok) {
- if (backok) {
- forwok->next = (MemHead *)&backok->next;
- backok->prev = (MemHead *)&forwok->next;
- forwok->nextname = backok->name;
- }
- else {
- forwok->next = NULL;
- membase->last = (struct localLink *) &forwok->next;
- }
- }
- else {
- if (backok) {
- backok->prev = NULL;
- membase->first = &backok->next;
- }
- else {
- membase->first = membase->last = NULL;
- }
- }
- }
- else {
- MemorY_ErroR(name, "Additional error in header");
- return("Additional error in header");
- }
-
- return(name);
+ MemHead *forw, *back, *forwok, *backok;
+ const char *name;
+
+ forw = membase->first;
+ if (forw)
+ forw = MEMNEXT(forw);
+ forwok = NULL;
+ while (forw) {
+ if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2)
+ break;
+ forwok = forw;
+ if (forw->next)
+ forw = MEMNEXT(forw->next);
+ else
+ forw = NULL;
+ }
+
+ back = (MemHead *)membase->last;
+ if (back)
+ back = MEMNEXT(back);
+ backok = NULL;
+ while (back) {
+ if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2)
+ break;
+ backok = back;
+ if (back->prev)
+ back = MEMNEXT(back->prev);
+ else
+ back = NULL;
+ }
+
+ if (forw != back)
+ return ("MORE THAN 1 MEMORYBLOCK CORRUPT");
+
+ if (forw == NULL && back == NULL) {
+ /* no wrong headers found then but in search of memblock */
+
+ forw = membase->first;
+ if (forw)
+ forw = MEMNEXT(forw);
+ forwok = NULL;
+ while (forw) {
+ if (forw == memh)
+ break;
+ if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2)
+ break;
+ forwok = forw;
+ if (forw->next)
+ forw = MEMNEXT(forw->next);
+ else
+ forw = NULL;
+ }
+ if (forw == NULL)
+ return NULL;
+
+ back = (MemHead *)membase->last;
+ if (back)
+ back = MEMNEXT(back);
+ backok = NULL;
+ while (back) {
+ if (back == memh)
+ break;
+ if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2)
+ break;
+ backok = back;
+ if (back->prev)
+ back = MEMNEXT(back->prev);
+ else
+ back = NULL;
+ }
+ }
+
+ if (forwok)
+ name = forwok->nextname;
+ else
+ name = "No name found";
+
+ if (forw == memh) {
+ /* to be sure but this block is removed from the list */
+ if (forwok) {
+ if (backok) {
+ forwok->next = (MemHead *)&backok->next;
+ backok->prev = (MemHead *)&forwok->next;
+ forwok->nextname = backok->name;
+ }
+ else {
+ forwok->next = NULL;
+ membase->last = (struct localLink *)&forwok->next;
+ }
+ }
+ else {
+ if (backok) {
+ backok->prev = NULL;
+ membase->first = &backok->next;
+ }
+ else {
+ membase->first = membase->last = NULL;
+ }
+ }
+ }
+ else {
+ MemorY_ErroR(name, "Additional error in header");
+ return ("Additional error in header");
+ }
+
+ return (name);
}
size_t MEM_guarded_get_peak_memory(void)
{
- size_t _peak_mem;
+ size_t _peak_mem;
- mem_lock_thread();
- _peak_mem = peak_mem;
- mem_unlock_thread();
+ mem_lock_thread();
+ _peak_mem = peak_mem;
+ mem_unlock_thread();
- return _peak_mem;
+ return _peak_mem;
}
void MEM_guarded_reset_peak_memory(void)
{
- mem_lock_thread();
- peak_mem = mem_in_use;
- mem_unlock_thread();
+ mem_lock_thread();
+ peak_mem = mem_in_use;
+ mem_unlock_thread();
}
size_t MEM_guarded_get_memory_in_use(void)
{
- size_t _mem_in_use;
+ size_t _mem_in_use;
- mem_lock_thread();
- _mem_in_use = mem_in_use;
- mem_unlock_thread();
+ mem_lock_thread();
+ _mem_in_use = mem_in_use;
+ mem_unlock_thread();
- return _mem_in_use;
+ return _mem_in_use;
}
size_t MEM_guarded_get_mapped_memory_in_use(void)
{
- size_t _mmap_in_use;
+ size_t _mmap_in_use;
- mem_lock_thread();
- _mmap_in_use = mmap_in_use;
- mem_unlock_thread();
+ mem_lock_thread();
+ _mmap_in_use = mmap_in_use;
+ mem_unlock_thread();
- return _mmap_in_use;
+ return _mmap_in_use;
}
unsigned int MEM_guarded_get_memory_blocks_in_use(void)
{
- unsigned int _totblock;
+ unsigned int _totblock;
- mem_lock_thread();
- _totblock = totblock;
- mem_unlock_thread();
+ mem_lock_thread();
+ _totblock = totblock;
+ mem_unlock_thread();
- return _totblock;
+ return _totblock;
}
#ifndef NDEBUG
const char *MEM_guarded_name_ptr(void *vmemh)
{
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
- return memh->name;
- }
- else {
- return "MEM_guarded_name_ptr(NULL)";
- }
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+ return memh->name;
+ }
+ else {
+ return "MEM_guarded_name_ptr(NULL)";
+ }
}
-#endif /* NDEBUG */
+#endif /* NDEBUG */
diff --git a/intern/guardedalloc/intern/mallocn_inline.h b/intern/guardedalloc/intern/mallocn_inline.h
index 064cc063668..f8bb7861fc9 100644
--- a/intern/guardedalloc/intern/mallocn_inline.h
+++ b/intern/guardedalloc/intern/mallocn_inline.h
@@ -35,21 +35,21 @@
MEM_INLINE bool MEM_size_safe_multiply(size_t a, size_t b, size_t *result)
{
- /* A size_t with its high-half bits all set to 1. */
- const size_t high_bits = SIZE_MAX << (sizeof(size_t) * 8 / 2);
- *result = a * b;
+ /* A size_t with its high-half bits all set to 1. */
+ const size_t high_bits = SIZE_MAX << (sizeof(size_t) * 8 / 2);
+ *result = a * b;
- if (UNLIKELY(*result == 0)) {
- return (a == 0 || b == 0);
- }
+ if (UNLIKELY(*result == 0)) {
+ return (a == 0 || b == 0);
+ }
- /*
- * We got a non-zero size, but we don't know if we overflowed to get
- * there. To avoid having to do a divide, we'll be clever and note that
- * if both A and B can be represented in N/2 bits, then their product
- * can be represented in N bits (without the possibility of overflow).
- */
- return ((high_bits & (a | b)) == 0 || (*result / b == a));
+ /*
+ * We got a non-zero size, but we don't know if we overflowed to get
+ * there. To avoid having to do a divide, we'll be clever and note that
+ * if both A and B can be represented in N/2 bits, then their product
+ * can be represented in N bits (without the possibility of overflow).
+ */
+ return ((high_bits & (a | b)) == 0 || (*result / b == a));
}
-#endif /* __MALLOCN_INLINE_H__ */
+#endif /* __MALLOCN_INLINE_H__ */
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index 7479f11f70c..e6e090703d4 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -32,15 +32,16 @@
#endif
#ifdef __GNUC__
-# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
+# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#else
-# define UNUSED(x) UNUSED_ ## x
+# define UNUSED(x) UNUSED_##x
#endif
#undef HAVE_MALLOC_STATS
-#define USE_MALLOC_USABLE_SIZE /* internal, when we have malloc_usable_size() */
+#define USE_MALLOC_USABLE_SIZE /* internal, when we have malloc_usable_size() */
-#if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__)) || defined(__GLIBC__)
+#if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__)) || \
+ defined(__GLIBC__)
# include <malloc.h>
# define HAVE_MALLOC_STATS
#elif defined(__FreeBSD__)
@@ -71,11 +72,11 @@ size_t malloc_usable_size(void *ptr);
#define SIZET_ALIGN_4(len) ((len + 3) & ~(size_t)3)
#ifdef __GNUC__
-# define LIKELY(x) __builtin_expect(!!(x), 1)
-# define UNLIKELY(x) __builtin_expect(!!(x), 0)
+# define LIKELY(x) __builtin_expect(!!(x), 1)
+# define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
-# define LIKELY(x) (x)
-# define UNLIKELY(x) (x)
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
@@ -95,10 +96,11 @@ size_t malloc_usable_size(void *ptr);
# define MEM_INLINE static inline
#endif
-#define IS_POW2(a) (((a) & ((a) - 1)) == 0)
+#define IS_POW2(a) (((a) & ((a)-1)) == 0)
/* Extra padding which needs to be applied on MemHead to make it aligned. */
-#define MEMHEAD_ALIGN_PADDING(alignment) ((size_t)alignment - (sizeof(MemHeadAligned) % (size_t)alignment))
+#define MEMHEAD_ALIGN_PADDING(alignment) \
+ ((size_t)alignment - (sizeof(MemHeadAligned) % (size_t)alignment))
/* Real pointer returned by the malloc or aligned_alloc. */
#define MEMHEAD_REAL_PTR(memh) ((char *)memh - MEMHEAD_ALIGN_PADDING(memh->alignment))
@@ -112,14 +114,33 @@ void aligned_free(void *ptr);
size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
void MEM_lockfree_freeN(void *vmemh);
void *MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-void *MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
-void *MEM_lockfree_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_lockfree_reallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_lockfree_recallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_lockfree_calloc_arrayN(size_t len,
+ size_t size,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_lockfree_malloc_arrayN(size_t len,
+ size_t size,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+void *MEM_lockfree_mallocN_aligned(size_t len,
+ size_t alignment,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
+void *MEM_lockfree_mapallocN(size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
void MEM_lockfree_printmemlist_pydict(void);
void MEM_lockfree_printmemlist(void);
void MEM_lockfree_callbackmemlist(void (*func)(void *));
@@ -141,14 +162,33 @@ const char *MEM_lockfree_name_ptr(void *vmemh);
size_t MEM_guarded_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
void MEM_guarded_freeN(void *vmemh);
void *MEM_guarded_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-void *MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
-void *MEM_guarded_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_guarded_reallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_guarded_recallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_guarded_calloc_arrayN(size_t len,
+ size_t size,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_guarded_malloc_arrayN(size_t len,
+ size_t size,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+void *MEM_guarded_mallocN_aligned(size_t len,
+ size_t alignment,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
+void *MEM_guarded_mapallocN(size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
void MEM_guarded_printmemlist_pydict(void);
void MEM_guarded_printmemlist(void);
void MEM_guarded_callbackmemlist(void (*func)(void *));
@@ -166,4 +206,4 @@ size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
const char *MEM_guarded_name_ptr(void *vmemh);
#endif
-#endif /* __MALLOCN_INTERN_H__ */
+#endif /* __MALLOCN_INTERN_H__ */
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index 9ca0bc38b66..e8fd8de738b 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -34,13 +34,13 @@
#include "mallocn_intern.h"
typedef struct MemHead {
- /* Length of allocated memory block. */
- size_t len;
+ /* Length of allocated memory block. */
+ size_t len;
} MemHead;
typedef struct MemHeadAligned {
- short alignment;
- size_t len;
+ short alignment;
+ size_t len;
} MemHeadAligned;
static unsigned int totblock = 0;
@@ -52,15 +52,15 @@ static void (*thread_lock_callback)(void) = NULL;
static void (*thread_unlock_callback)(void) = NULL;
enum {
- MEMHEAD_MMAP_FLAG = 1,
- MEMHEAD_ALIGN_FLAG = 2,
+ MEMHEAD_MMAP_FLAG = 1,
+ MEMHEAD_ALIGN_FLAG = 2,
};
-#define MEMHEAD_FROM_PTR(ptr) (((MemHead*) ptr) - 1)
+#define MEMHEAD_FROM_PTR(ptr) (((MemHead *)ptr) - 1)
#define PTR_FROM_MEMHEAD(memhead) (memhead + 1)
-#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned*) ptr) - 1)
-#define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t) MEMHEAD_MMAP_FLAG)
-#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t) MEMHEAD_ALIGN_FLAG)
+#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned *)ptr) - 1)
+#define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t)MEMHEAD_MMAP_FLAG)
+#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t)MEMHEAD_ALIGN_FLAG)
/* Uncomment this to have proper peak counter. */
#define USE_ATOMIC_MAX
@@ -68,365 +68,371 @@ enum {
MEM_INLINE void update_maximum(size_t *maximum_value, size_t value)
{
#ifdef USE_ATOMIC_MAX
- atomic_fetch_and_update_max_z(maximum_value, value);
+ atomic_fetch_and_update_max_z(maximum_value, value);
#else
- *maximum_value = value > *maximum_value ? value : *maximum_value;
+ *maximum_value = value > *maximum_value ? value : *maximum_value;
#endif
}
#ifdef __GNUC__
-__attribute__ ((format(printf, 1, 2)))
+__attribute__((format(printf, 1, 2)))
#endif
-static void print_error(const char *str, ...)
+static void
+print_error(const char *str, ...)
{
- char buf[512];
- va_list ap;
+ char buf[512];
+ va_list ap;
- va_start(ap, str);
- vsnprintf(buf, sizeof(buf), str, ap);
- va_end(ap);
- buf[sizeof(buf) - 1] = '\0';
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+ buf[sizeof(buf) - 1] = '\0';
- if (error_callback) {
- error_callback(buf);
- }
+ if (error_callback) {
+ error_callback(buf);
+ }
}
#if defined(WIN32)
static void mem_lock_thread(void)
{
- if (thread_lock_callback)
- thread_lock_callback();
+ if (thread_lock_callback)
+ thread_lock_callback();
}
static void mem_unlock_thread(void)
{
- if (thread_unlock_callback)
- thread_unlock_callback();
+ if (thread_unlock_callback)
+ thread_unlock_callback();
}
#endif
size_t MEM_lockfree_allocN_len(const void *vmemh)
{
- if (vmemh) {
- return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t) (MEMHEAD_MMAP_FLAG | MEMHEAD_ALIGN_FLAG));
- }
- else {
- return 0;
- }
+ if (vmemh) {
+ return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t)(MEMHEAD_MMAP_FLAG | MEMHEAD_ALIGN_FLAG));
+ }
+ else {
+ return 0;
+ }
}
void MEM_lockfree_freeN(void *vmemh)
{
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- size_t len = MEM_lockfree_allocN_len(vmemh);
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ size_t len = MEM_lockfree_allocN_len(vmemh);
- if (vmemh == NULL) {
- print_error("Attempt to free NULL pointer\n");
+ if (vmemh == NULL) {
+ print_error("Attempt to free NULL pointer\n");
#ifdef WITH_ASSERT_ABORT
- abort();
+ abort();
#endif
- return;
- }
+ return;
+ }
- atomic_sub_and_fetch_u(&totblock, 1);
- atomic_sub_and_fetch_z(&mem_in_use, len);
+ atomic_sub_and_fetch_u(&totblock, 1);
+ atomic_sub_and_fetch_z(&mem_in_use, len);
- if (MEMHEAD_IS_MMAP(memh)) {
- atomic_sub_and_fetch_z(&mmap_in_use, len);
+ if (MEMHEAD_IS_MMAP(memh)) {
+ atomic_sub_and_fetch_z(&mmap_in_use, len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- if (munmap(memh, len + sizeof(MemHead)))
- printf("Couldn't unmap memory\n");
+ if (munmap(memh, len + sizeof(MemHead)))
+ printf("Couldn't unmap memory\n");
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- }
- else {
- if (UNLIKELY(malloc_debug_memset && len)) {
- memset(memh + 1, 255, len);
- }
- if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
- }
- else {
- free(memh);
- }
- }
+ }
+ else {
+ if (UNLIKELY(malloc_debug_memset && len)) {
+ memset(memh + 1, 255, len);
+ }
+ if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
+ }
+ else {
+ free(memh);
+ }
+ }
}
void *MEM_lockfree_dupallocN(const void *vmemh)
{
- void *newp = NULL;
- if (vmemh) {
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- const size_t prev_size = MEM_lockfree_allocN_len(vmemh);
- if (UNLIKELY(MEMHEAD_IS_MMAP(memh))) {
- newp = MEM_lockfree_mapallocN(prev_size, "dupli_mapalloc");
- }
- else if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- newp = MEM_lockfree_mallocN_aligned(
- prev_size,
- (size_t)memh_aligned->alignment,
- "dupli_malloc");
- }
- else {
- newp = MEM_lockfree_mallocN(prev_size, "dupli_malloc");
- }
- memcpy(newp, vmemh, prev_size);
- }
- return newp;
+ void *newp = NULL;
+ if (vmemh) {
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ const size_t prev_size = MEM_lockfree_allocN_len(vmemh);
+ if (UNLIKELY(MEMHEAD_IS_MMAP(memh))) {
+ newp = MEM_lockfree_mapallocN(prev_size, "dupli_mapalloc");
+ }
+ else if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ newp = MEM_lockfree_mallocN_aligned(
+ prev_size, (size_t)memh_aligned->alignment, "dupli_malloc");
+ }
+ else {
+ newp = MEM_lockfree_mallocN(prev_size, "dupli_malloc");
+ }
+ memcpy(newp, vmemh, prev_size);
+ }
+ return newp;
}
void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- size_t old_len = MEM_lockfree_allocN_len(vmemh);
-
- if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
- newp = MEM_lockfree_mallocN(len, "realloc");
- }
- else {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- newp = MEM_lockfree_mallocN_aligned(
- len,
- (size_t)memh_aligned->alignment,
- "realloc");
- }
-
- if (newp) {
- if (len < old_len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- /* grow (or remain same size) */
- memcpy(newp, vmemh, old_len);
- }
- }
-
- MEM_lockfree_freeN(vmemh);
- }
- else {
- newp = MEM_lockfree_mallocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ size_t old_len = MEM_lockfree_allocN_len(vmemh);
+
+ if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
+ newp = MEM_lockfree_mallocN(len, "realloc");
+ }
+ else {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ newp = MEM_lockfree_mallocN_aligned(len, (size_t)memh_aligned->alignment, "realloc");
+ }
+
+ if (newp) {
+ if (len < old_len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ /* grow (or remain same size) */
+ memcpy(newp, vmemh, old_len);
+ }
+ }
+
+ MEM_lockfree_freeN(vmemh);
+ }
+ else {
+ newp = MEM_lockfree_mallocN(len, str);
+ }
+
+ return newp;
}
void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- size_t old_len = MEM_lockfree_allocN_len(vmemh);
-
- if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
- newp = MEM_lockfree_mallocN(len, "recalloc");
- }
- else {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- newp = MEM_lockfree_mallocN_aligned(
- len,
- (size_t)memh_aligned->alignment,
- "recalloc");
- }
-
- if (newp) {
- if (len < old_len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- memcpy(newp, vmemh, old_len);
-
- if (len > old_len) {
- /* grow */
- /* zero new bytes */
- memset(((char *)newp) + old_len, 0, len - old_len);
- }
- }
- }
-
- MEM_lockfree_freeN(vmemh);
- }
- else {
- newp = MEM_lockfree_callocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ size_t old_len = MEM_lockfree_allocN_len(vmemh);
+
+ if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
+ newp = MEM_lockfree_mallocN(len, "recalloc");
+ }
+ else {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ newp = MEM_lockfree_mallocN_aligned(len, (size_t)memh_aligned->alignment, "recalloc");
+ }
+
+ if (newp) {
+ if (len < old_len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ memcpy(newp, vmemh, old_len);
+
+ if (len > old_len) {
+ /* grow */
+ /* zero new bytes */
+ memset(((char *)newp) + old_len, 0, len - old_len);
+ }
+ }
+ }
+
+ MEM_lockfree_freeN(vmemh);
+ }
+ else {
+ newp = MEM_lockfree_callocN(len, str);
+ }
+
+ return newp;
}
void *MEM_lockfree_callocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)calloc(1, len + sizeof(MemHead));
+ memh = (MemHead *)calloc(1, len + sizeof(MemHead));
- if (LIKELY(memh)) {
- memh->len = len;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- update_maximum(&peak_mem, mem_in_use);
+ if (LIKELY(memh)) {
+ memh->len = len;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ update_maximum(&peak_mem, mem_in_use);
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Calloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_lockfree_callocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Calloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_lockfree_callocN(total_size, str);
}
void *MEM_lockfree_mallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)malloc(len + sizeof(MemHead));
+ memh = (MemHead *)malloc(len + sizeof(MemHead));
- if (LIKELY(memh)) {
- if (UNLIKELY(malloc_debug_memset && len)) {
- memset(memh + 1, 255, len);
- }
+ if (LIKELY(memh)) {
+ if (UNLIKELY(malloc_debug_memset && len)) {
+ memset(memh + 1, 255, len);
+ }
- memh->len = len;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- update_maximum(&peak_mem, mem_in_use);
+ memh->len = len;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ update_maximum(&peak_mem, mem_in_use);
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Malloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_lockfree_mallocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Malloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_lockfree_mallocN(total_size, str);
}
void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str)
{
- MemHeadAligned *memh;
-
- /* It's possible that MemHead's size is not properly aligned,
- * do extra padding to deal with this.
- *
- * We only support small alignments which fits into short in
- * order to save some bits in MemHead structure.
- */
- size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
-
- /* Huge alignment values doesn't make sense and they
- * wouldn't fit into 'short' used in the MemHead.
- */
- assert(alignment < 1024);
-
- /* We only support alignment to a power of two. */
- assert(IS_POW2(alignment));
-
- len = SIZET_ALIGN_4(len);
-
- memh = (MemHeadAligned *)aligned_malloc(
- len + extra_padding + sizeof(MemHeadAligned), alignment);
-
- if (LIKELY(memh)) {
- /* We keep padding in the beginning of MemHead,
- * this way it's always possible to get MemHead
- * from the data pointer.
- */
- memh = (MemHeadAligned *)((char *)memh + extra_padding);
-
- if (UNLIKELY(malloc_debug_memset && len)) {
- memset(memh + 1, 255, len);
- }
-
- memh->len = len | (size_t) MEMHEAD_ALIGN_FLAG;
- memh->alignment = (short) alignment;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- update_maximum(&peak_mem, mem_in_use);
-
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ MemHeadAligned *memh;
+
+ /* It's possible that MemHead's size is not properly aligned,
+ * do extra padding to deal with this.
+ *
+ * We only support small alignments which fits into short in
+ * order to save some bits in MemHead structure.
+ */
+ size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
+
+ /* Huge alignment values doesn't make sense and they
+ * wouldn't fit into 'short' used in the MemHead.
+ */
+ assert(alignment < 1024);
+
+ /* We only support alignment to a power of two. */
+ assert(IS_POW2(alignment));
+
+ len = SIZET_ALIGN_4(len);
+
+ memh = (MemHeadAligned *)aligned_malloc(len + extra_padding + sizeof(MemHeadAligned), alignment);
+
+ if (LIKELY(memh)) {
+ /* We keep padding in the beginning of MemHead,
+ * this way it's always possible to get MemHead
+ * from the data pointer.
+ */
+ memh = (MemHeadAligned *)((char *)memh + extra_padding);
+
+ if (UNLIKELY(malloc_debug_memset && len)) {
+ memset(memh + 1, 255, len);
+ }
+
+ memh->len = len | (size_t)MEMHEAD_ALIGN_FLAG;
+ memh->alignment = (short)alignment;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ update_maximum(&peak_mem, mem_in_use);
+
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_lockfree_mapallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- /* on 64 bit, simply use calloc instead, as mmap does not support
- * allocating > 4 GB on Windows. the only reason mapalloc exists
- * is to get around address space limitations in 32 bit OSes. */
- if (sizeof(void *) >= 8)
- return MEM_lockfree_callocN(len, str);
+ /* on 64 bit, simply use calloc instead, as mmap does not support
+ * allocating > 4 GB on Windows. the only reason mapalloc exists
+ * is to get around address space limitations in 32 bit OSes. */
+ if (sizeof(void *) >= 8)
+ return MEM_lockfree_callocN(len, str);
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- memh = mmap(NULL, len + sizeof(MemHead),
- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+ memh = mmap(NULL, len + sizeof(MemHead), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- if (memh != (MemHead *)-1) {
- memh->len = len | (size_t) MEMHEAD_MMAP_FLAG;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- atomic_add_and_fetch_z(&mmap_in_use, len);
-
- update_maximum(&peak_mem, mem_in_use);
- update_maximum(&peak_mem, mmap_in_use);
-
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Mapalloc returns null, fallback to regular malloc: "
- "len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mmap_in_use);
- return MEM_lockfree_callocN(len, str);
+ if (memh != (MemHead *)-1) {
+ memh->len = len | (size_t)MEMHEAD_MMAP_FLAG;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ atomic_add_and_fetch_z(&mmap_in_use, len);
+
+ update_maximum(&peak_mem, mem_in_use);
+ update_maximum(&peak_mem, mmap_in_use);
+
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error(
+ "Mapalloc returns null, fallback to regular malloc: "
+ "len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mmap_in_use);
+ return MEM_lockfree_callocN(len, str);
}
void MEM_lockfree_printmemlist_pydict(void)
@@ -440,78 +446,78 @@ void MEM_lockfree_printmemlist(void)
/* unused */
void MEM_lockfree_callbackmemlist(void (*func)(void *))
{
- (void) func; /* Ignored. */
+ (void)func; /* Ignored. */
}
void MEM_lockfree_printmemlist_stats(void)
{
- printf("\ntotal memory len: %.3f MB\n",
- (double)mem_in_use / (double)(1024 * 1024));
- printf("peak memory len: %.3f MB\n",
- (double)peak_mem / (double)(1024 * 1024));
- printf("\nFor more detailed per-block statistics run Blender with memory debugging command line argument.\n");
+ printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n", (double)peak_mem / (double)(1024 * 1024));
+ printf(
+ "\nFor more detailed per-block statistics run Blender with memory debugging command line "
+ "argument.\n");
#ifdef HAVE_MALLOC_STATS
- printf("System Statistics:\n");
- malloc_stats();
+ printf("System Statistics:\n");
+ malloc_stats();
#endif
}
void MEM_lockfree_set_error_callback(void (*func)(const char *))
{
- error_callback = func;
+ error_callback = func;
}
bool MEM_lockfree_consistency_check(void)
{
- return true;
+ return true;
}
void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void))
{
- thread_lock_callback = lock;
- thread_unlock_callback = unlock;
+ thread_lock_callback = lock;
+ thread_unlock_callback = unlock;
}
void MEM_lockfree_set_memory_debug(void)
{
- malloc_debug_memset = true;
+ malloc_debug_memset = true;
}
size_t MEM_lockfree_get_memory_in_use(void)
{
- return mem_in_use;
+ return mem_in_use;
}
size_t MEM_lockfree_get_mapped_memory_in_use(void)
{
- return mmap_in_use;
+ return mmap_in_use;
}
unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
{
- return totblock;
+ return totblock;
}
/* dummy */
void MEM_lockfree_reset_peak_memory(void)
{
- peak_mem = mem_in_use;
+ peak_mem = mem_in_use;
}
size_t MEM_lockfree_get_peak_memory(void)
{
- return peak_mem;
+ return peak_mem;
}
#ifndef NDEBUG
const char *MEM_lockfree_name_ptr(void *vmemh)
{
- if (vmemh) {
- return "unknown block name ptr";
- }
- else {
- return "MEM_lockfree_name_ptr(NULL)";
- }
+ if (vmemh) {
+ return "unknown block name ptr";
+ }
+ else {
+ return "MEM_lockfree_name_ptr(NULL)";
+ }
}
-#endif /* NDEBUG */
+#endif /* NDEBUG */
diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c
index 93b0370a011..d5488351700 100644
--- a/intern/guardedalloc/intern/mmap_win.c
+++ b/intern/guardedalloc/intern/mmap_win.c
@@ -23,43 +23,43 @@
#ifdef WIN32
-#include <windows.h>
-#include <errno.h>
-#include <io.h>
-#include <sys/types.h>
-#include <stdio.h>
+# include <windows.h>
+# include <errno.h>
+# include <io.h>
+# include <sys/types.h>
+# include <stdio.h>
-#include "mmap_win.h"
+# include "mmap_win.h"
-#ifndef FILE_MAP_EXECUTE
+# ifndef FILE_MAP_EXECUTE
//not defined in earlier versions of the Platform SDK (before February 2003)
-#define FILE_MAP_EXECUTE 0x0020
-#endif
+# define FILE_MAP_EXECUTE 0x0020
+# endif
/* copied from BLI_utildefines.h, ugh */
-#ifdef __GNUC__
-# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
-#else
-# define UNUSED(x) x
-#endif
+# ifdef __GNUC__
+# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
+# else
+# define UNUSED(x) x
+# endif
/* --------------------------------------------------------------------- */
/* local storage definitions */
/* --------------------------------------------------------------------- */
/* all memory mapped chunks are put in linked lists */
typedef struct mmapLink {
- struct mmapLink *next, *prev;
+ struct mmapLink *next, *prev;
} mmapLink;
typedef struct mmapListBase {
- void *first, *last;
+ void *first, *last;
} mmapListBase;
typedef struct MemMap {
- struct MemMap *next, *prev;
- void *mmap;
- HANDLE fhandle;
- HANDLE maphandle;
+ struct MemMap *next, *prev;
+ void *mmap;
+ HANDLE fhandle;
+ HANDLE maphandle;
} MemMap;
/* --------------------------------------------------------------------- */
@@ -79,7 +79,6 @@ static int mmap_get_access_flags(int flags);
volatile static struct mmapListBase _mmapbase;
volatile static struct mmapListBase *mmapbase = &_mmapbase;
-
/* --------------------------------------------------------------------- */
/* implementation */
/* --------------------------------------------------------------------- */
@@ -87,84 +86,89 @@ volatile static struct mmapListBase *mmapbase = &_mmapbase;
/* mmap for windows */
void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t offset)
{
- HANDLE fhandle = INVALID_HANDLE_VALUE;
- HANDLE maphandle;
- int prot_flags = mmap_get_prot_flags(prot);
- int access_flags = mmap_get_access_flags(prot);
- MemMap *mm = NULL;
- void *ptr = NULL;
-
- if (flags & MAP_FIXED) {
- return MAP_FAILED;
- }
-
-#if 0
- if ( fd == -1 ) {
- _set_errno( EBADF );
- return MAP_FAILED;
- }
-#endif
-
- if (fd != -1) {
- fhandle = (HANDLE) _get_osfhandle(fd);
- }
- if (fhandle == INVALID_HANDLE_VALUE) {
- if (!(flags & MAP_ANONYMOUS)) {
- errno = EBADF;
- return MAP_FAILED;
- }
- }
- else {
- if (!DuplicateHandle(GetCurrentProcess(), fhandle, GetCurrentProcess(),
- &fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS) ) {
- return MAP_FAILED;
- }
- }
-
- /* note len is passed to a 32 bit DWORD, so can't be > 4 GB */
- maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
- if (maphandle == 0) {
- errno = EBADF;
- return MAP_FAILED;
- }
-
- ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
- if (ptr == NULL) {
- DWORD dwLastErr = GetLastError();
- if (dwLastErr == ERROR_MAPPED_ALIGNMENT)
- errno = EINVAL;
- else
- errno = EACCES;
- CloseHandle(maphandle);
- return MAP_FAILED;
- }
-
- mm = (MemMap *)malloc(sizeof(MemMap));
- if (!mm) {
- errno = ENOMEM;
- }
- mm->fhandle = fhandle;
- mm->maphandle = maphandle;
- mm->mmap = ptr;
- mmap_addtail(mmapbase, mm);
-
- return ptr;
+ HANDLE fhandle = INVALID_HANDLE_VALUE;
+ HANDLE maphandle;
+ int prot_flags = mmap_get_prot_flags(prot);
+ int access_flags = mmap_get_access_flags(prot);
+ MemMap *mm = NULL;
+ void *ptr = NULL;
+
+ if (flags & MAP_FIXED) {
+ return MAP_FAILED;
+ }
+
+# if 0
+ if ( fd == -1 ) {
+ _set_errno( EBADF );
+ return MAP_FAILED;
+ }
+# endif
+
+ if (fd != -1) {
+ fhandle = (HANDLE)_get_osfhandle(fd);
+ }
+ if (fhandle == INVALID_HANDLE_VALUE) {
+ if (!(flags & MAP_ANONYMOUS)) {
+ errno = EBADF;
+ return MAP_FAILED;
+ }
+ }
+ else {
+ if (!DuplicateHandle(GetCurrentProcess(),
+ fhandle,
+ GetCurrentProcess(),
+ &fhandle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS)) {
+ return MAP_FAILED;
+ }
+ }
+
+ /* note len is passed to a 32 bit DWORD, so can't be > 4 GB */
+ maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
+ if (maphandle == 0) {
+ errno = EBADF;
+ return MAP_FAILED;
+ }
+
+ ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
+ if (ptr == NULL) {
+ DWORD dwLastErr = GetLastError();
+ if (dwLastErr == ERROR_MAPPED_ALIGNMENT)
+ errno = EINVAL;
+ else
+ errno = EACCES;
+ CloseHandle(maphandle);
+ return MAP_FAILED;
+ }
+
+ mm = (MemMap *)malloc(sizeof(MemMap));
+ if (!mm) {
+ errno = ENOMEM;
+ }
+ mm->fhandle = fhandle;
+ mm->maphandle = maphandle;
+ mm->mmap = ptr;
+ mmap_addtail(mmapbase, mm);
+
+ return ptr;
}
/* munmap for windows */
intptr_t munmap(void *ptr, size_t UNUSED(size))
{
- MemMap *mm = mmap_findlink(mmapbase, ptr);
- if (!mm) {
- errno = EINVAL;
- return -1;
- }
- UnmapViewOfFile(mm->mmap);
- CloseHandle(mm->maphandle);
- CloseHandle(mm->fhandle);
- mmap_remlink(mmapbase, mm);
- free(mm);
- return 0;
+ MemMap *mm = mmap_findlink(mmapbase, ptr);
+ if (!mm) {
+ errno = EINVAL;
+ return -1;
+ }
+ UnmapViewOfFile(mm->mmap);
+ CloseHandle(mm->maphandle);
+ CloseHandle(mm->fhandle);
+ mmap_remlink(mmapbase, mm);
+ free(mm);
+ return 0;
}
/* --------------------------------------------------------------------- */
@@ -173,90 +177,102 @@ intptr_t munmap(void *ptr, size_t UNUSED(size))
static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
{
- struct mmapLink *link = vlink;
+ struct mmapLink *link = vlink;
- if (link == NULL) return;
- if (listbase == NULL) return;
+ if (link == NULL)
+ return;
+ if (listbase == NULL)
+ return;
- link->next = 0;
- link->prev = listbase->last;
+ link->next = 0;
+ link->prev = listbase->last;
- if (listbase->last) ((struct mmapLink *)listbase->last)->next = link;
- if (listbase->first == NULL) listbase->first = link;
- listbase->last = link;
+ if (listbase->last)
+ ((struct mmapLink *)listbase->last)->next = link;
+ if (listbase->first == NULL)
+ listbase->first = link;
+ listbase->last = link;
}
static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
{
- struct mmapLink *link = vlink;
-
- if (link == NULL) return;
- if (listbase == NULL) return;
-
- if (link->next) link->next->prev = link->prev;
- if (link->prev) link->prev->next = link->next;
-
- if (listbase->last == link) listbase->last = link->prev;
- if (listbase->first == link) listbase->first = link->next;
+ struct mmapLink *link = vlink;
+
+ if (link == NULL)
+ return;
+ if (listbase == NULL)
+ return;
+
+ if (link->next)
+ link->next->prev = link->prev;
+ if (link->prev)
+ link->prev->next = link->next;
+
+ if (listbase->last == link)
+ listbase->last = link->prev;
+ if (listbase->first == link)
+ listbase->first = link->next;
}
static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
{
- MemMap *mm;
-
- if (ptr == NULL) return NULL;
- if (listbase == NULL) return NULL;
-
- mm = (MemMap *)listbase->first;
- while (mm) {
- if (mm->mmap == ptr) {
- return mm;
- }
- mm = mm->next;
- }
- return NULL;
+ MemMap *mm;
+
+ if (ptr == NULL)
+ return NULL;
+ if (listbase == NULL)
+ return NULL;
+
+ mm = (MemMap *)listbase->first;
+ while (mm) {
+ if (mm->mmap == ptr) {
+ return mm;
+ }
+ mm = mm->next;
+ }
+ return NULL;
}
static int mmap_get_prot_flags(int flags)
{
- int prot = PAGE_NOACCESS;
-
- if ( (flags & PROT_READ) == PROT_READ) {
- if ( (flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
- }
- else {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
- }
- }
- else if ( (flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
- }
- else if ( (flags & PROT_EXEC) == PROT_EXEC) {
- prot = PAGE_EXECUTE_READ;
- }
- return prot;
+ int prot = PAGE_NOACCESS;
+
+ if ((flags & PROT_READ) == PROT_READ) {
+ if ((flags & PROT_WRITE) == PROT_WRITE) {
+ prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
+ }
+ else {
+ prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
+ }
+ }
+ else if ((flags & PROT_WRITE) == PROT_WRITE) {
+ prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
+ }
+ else if ((flags & PROT_EXEC) == PROT_EXEC) {
+ prot = PAGE_EXECUTE_READ;
+ }
+ return prot;
}
static int mmap_get_access_flags(int flags)
{
- int access = 0;
-
- if ( (flags & PROT_READ) == PROT_READ) {
- if ( (flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_WRITE;
- }
- else {
- access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
- }
- }
- else if ( (flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_COPY;
- }
- else if ( (flags & PROT_EXEC) == PROT_EXEC) {
- access = FILE_MAP_EXECUTE;
- }
- return access;
+ int access = 0;
+
+ if ((flags & PROT_READ) == PROT_READ) {
+ if ((flags & PROT_WRITE) == PROT_WRITE) {
+ access = FILE_MAP_WRITE;
+ }
+ else {
+ access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
+ }
+ }
+ else if ((flags & PROT_WRITE) == PROT_WRITE) {
+ access = FILE_MAP_COPY;
+ }
+ else if ((flags & PROT_EXEC) == PROT_EXEC) {
+ access = FILE_MAP_EXECUTE;
+ }
+ return access;
}
-#endif // WIN32
+#endif // WIN32
diff --git a/intern/guardedalloc/test/simpletest/memtest.c b/intern/guardedalloc/test/simpletest/memtest.c
index 2ab3653b435..576e502b72e 100644
--- a/intern/guardedalloc/test/simpletest/memtest.c
+++ b/intern/guardedalloc/test/simpletest/memtest.c
@@ -36,118 +36,122 @@
static void mem_error_cb(const char *errorStr)
{
- fprintf(stderr, "%s", errorStr);
- fflush(stderr);
+ fprintf(stderr, "%s", errorStr);
+ fflush(stderr);
}
int main(int argc, char *argv[])
{
- int verbose = 0;
- int error_status = 0;
- int retval = 0;
- int *ip;
-
- void *p[NUM_BLOCKS];
- int i = 0;
-
- /* ----------------------------------------------------------------- */
- switch (argc) {
- case 2:
- verbose = atoi(argv[1]);
- if (verbose < 0) verbose = 0;
- break;
- case 1:
- default:
- verbose = 0;
- }
- if (verbose) {
- fprintf(stderr,"\n*** Simple memory test\n|\n");
- }
-
- /* ----------------------------------------------------------------- */
- /* Round one, do a normal allocation, and free the blocks again. */
- /* ----------------------------------------------------------------- */
- /* flush mem lib output to stderr */
- MEM_set_error_callback(mem_error_cb);
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- int blocksize = 10000;
- char tagstring[1000];
- if (verbose > 1) printf("|--* Allocating block %d\n", i);
- sprintf(tagstring,"Memblock no. %d : ", i);
- p[i]= MEM_callocN(blocksize, strdup(tagstring));
- }
-
- /* report on that */
- if (verbose > 1) MEM_printmemlist();
-
- /* memory is there: test it */
- error_status = MEM_consistency_check();
-
- if (verbose) {
- if (error_status) {
- fprintf(stderr, "|--* Memory test FAILED\n|\n");
- }
- else {
- fprintf(stderr, "|--* Memory tested as good (as it should be)\n|\n");
- }
- }
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- MEM_freeN(p[i]);
- }
-
- /* ----------------------------------------------------------------- */
- /* Round two, do a normal allocation, and corrupt some blocks. */
- /* ----------------------------------------------------------------- */
- /* switch off, because it will complain about some things. */
- MEM_set_error_callback(NULL);
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- int blocksize = 10000;
- char tagstring[1000];
- if (verbose > 1) printf("|--* Allocating block %d\n", i);
- sprintf(tagstring,"Memblock no. %d : ", i);
- p[i]= MEM_callocN(blocksize, strdup(tagstring));
- }
-
- /* now corrupt a few blocks...*/
- ip = (int*) p[5] - 50;
- for (i = 0; i< 1000; i++,ip++) *ip = i+1;
- ip = (int*) p[6];
- *(ip+10005) = 0;
-
- retval = MEM_consistency_check();
-
- /* the test should have failed */
- error_status |= !retval;
- if (verbose) {
- if (retval) {
- fprintf(stderr, "|--* Memory test failed (as it should be)\n");
- }
- else {
- fprintf(stderr, "|--* Memory test FAILED to find corrupted blocks \n");
- }
- }
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- MEM_freeN(p[i]);
- }
-
-
- if (verbose && error_status) {
- fprintf(stderr,"|--* Memory was corrupted\n");
- }
- /* ----------------------------------------------------------------- */
- if (verbose) {
- if (error_status) {
- fprintf(stderr,"|\n|--* Errors were detected\n");
- }
- else {
- fprintf(stderr,"|\n|--* Test exited succesfully\n");
- }
-
- fprintf(stderr,"|\n*** Finished test\n\n");
- }
- return error_status;
+ int verbose = 0;
+ int error_status = 0;
+ int retval = 0;
+ int *ip;
+
+ void *p[NUM_BLOCKS];
+ int i = 0;
+
+ /* ----------------------------------------------------------------- */
+ switch (argc) {
+ case 2:
+ verbose = atoi(argv[1]);
+ if (verbose < 0)
+ verbose = 0;
+ break;
+ case 1:
+ default:
+ verbose = 0;
+ }
+ if (verbose) {
+ fprintf(stderr, "\n*** Simple memory test\n|\n");
+ }
+
+ /* ----------------------------------------------------------------- */
+ /* Round one, do a normal allocation, and free the blocks again. */
+ /* ----------------------------------------------------------------- */
+ /* flush mem lib output to stderr */
+ MEM_set_error_callback(mem_error_cb);
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ int blocksize = 10000;
+ char tagstring[1000];
+ if (verbose > 1)
+ printf("|--* Allocating block %d\n", i);
+ sprintf(tagstring, "Memblock no. %d : ", i);
+ p[i] = MEM_callocN(blocksize, strdup(tagstring));
+ }
+
+ /* report on that */
+ if (verbose > 1)
+ MEM_printmemlist();
+
+ /* memory is there: test it */
+ error_status = MEM_consistency_check();
+
+ if (verbose) {
+ if (error_status) {
+ fprintf(stderr, "|--* Memory test FAILED\n|\n");
+ }
+ else {
+ fprintf(stderr, "|--* Memory tested as good (as it should be)\n|\n");
+ }
+ }
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ MEM_freeN(p[i]);
+ }
+
+ /* ----------------------------------------------------------------- */
+ /* Round two, do a normal allocation, and corrupt some blocks. */
+ /* ----------------------------------------------------------------- */
+ /* switch off, because it will complain about some things. */
+ MEM_set_error_callback(NULL);
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ int blocksize = 10000;
+ char tagstring[1000];
+ if (verbose > 1)
+ printf("|--* Allocating block %d\n", i);
+ sprintf(tagstring, "Memblock no. %d : ", i);
+ p[i] = MEM_callocN(blocksize, strdup(tagstring));
+ }
+
+ /* now corrupt a few blocks...*/
+ ip = (int *)p[5] - 50;
+ for (i = 0; i < 1000; i++, ip++)
+ *ip = i + 1;
+ ip = (int *)p[6];
+ *(ip + 10005) = 0;
+
+ retval = MEM_consistency_check();
+
+ /* the test should have failed */
+ error_status |= !retval;
+ if (verbose) {
+ if (retval) {
+ fprintf(stderr, "|--* Memory test failed (as it should be)\n");
+ }
+ else {
+ fprintf(stderr, "|--* Memory test FAILED to find corrupted blocks \n");
+ }
+ }
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ MEM_freeN(p[i]);
+ }
+
+ if (verbose && error_status) {
+ fprintf(stderr, "|--* Memory was corrupted\n");
+ }
+ /* ----------------------------------------------------------------- */
+ if (verbose) {
+ if (error_status) {
+ fprintf(stderr, "|\n|--* Errors were detected\n");
+ }
+ else {
+ fprintf(stderr, "|\n|--* Test exited succesfully\n");
+ }
+
+ fprintf(stderr, "|\n*** Finished test\n\n");
+ }
+ return error_status;
}
diff --git a/intern/iksolver/CMakeLists.txt b/intern/iksolver/CMakeLists.txt
index 362e6e2bb6b..5e12cdbcc2f 100644
--- a/intern/iksolver/CMakeLists.txt
+++ b/intern/iksolver/CMakeLists.txt
@@ -19,27 +19,27 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- intern
- ../memutil
+ intern
+ ../memutil
)
set(INC_SYS
- ${EIGEN3_INCLUDE_DIRS}
+ ${EIGEN3_INCLUDE_DIRS}
)
set(SRC
- intern/IK_QJacobian.cpp
- intern/IK_QJacobianSolver.cpp
- intern/IK_QSegment.cpp
- intern/IK_QTask.cpp
- intern/IK_Solver.cpp
+ intern/IK_QJacobian.cpp
+ intern/IK_QJacobianSolver.cpp
+ intern/IK_QSegment.cpp
+ intern/IK_QTask.cpp
+ intern/IK_Solver.cpp
- extern/IK_solver.h
- intern/IK_Math.h
- intern/IK_QJacobian.h
- intern/IK_QJacobianSolver.h
- intern/IK_QSegment.h
- intern/IK_QTask.h
+ extern/IK_solver.h
+ intern/IK_Math.h
+ intern/IK_QJacobian.h
+ intern/IK_QJacobianSolver.h
+ intern/IK_QSegment.h
+ intern/IK_QTask.h
)
set(LIB
diff --git a/intern/iksolver/extern/IK_solver.h b/intern/iksolver/extern/IK_solver.h
index 9af6cc6988f..79c57b7f44b 100644
--- a/intern/iksolver/extern/IK_solver.h
+++ b/intern/iksolver/extern/IK_solver.h
@@ -22,7 +22,6 @@
* \ingroup iksolver
*/
-
/**
* \page IK - Blender inverse kinematics module.
*
@@ -97,28 +96,29 @@ extern "C" {
typedef void IK_Segment;
enum IK_SegmentFlag {
- IK_XDOF = 1,
- IK_YDOF = 2,
- IK_ZDOF = 4,
- IK_TRANS_XDOF = 8,
- IK_TRANS_YDOF = 16,
- IK_TRANS_ZDOF = 32
+ IK_XDOF = 1,
+ IK_YDOF = 2,
+ IK_ZDOF = 4,
+ IK_TRANS_XDOF = 8,
+ IK_TRANS_YDOF = 16,
+ IK_TRANS_ZDOF = 32
};
typedef enum IK_SegmentAxis {
- IK_X = 0,
- IK_Y = 1,
- IK_Z = 2,
- IK_TRANS_X = 3,
- IK_TRANS_Y = 4,
- IK_TRANS_Z = 5
+ IK_X = 0,
+ IK_Y = 1,
+ IK_Z = 2,
+ IK_TRANS_X = 3,
+ IK_TRANS_Y = 4,
+ IK_TRANS_Z = 5
} IK_SegmentAxis;
extern IK_Segment *IK_CreateSegment(int flag);
extern void IK_FreeSegment(IK_Segment *seg);
extern void IK_SetParent(IK_Segment *seg, IK_Segment *parent);
-extern void IK_SetTransform(IK_Segment *seg, float start[3], float rest_basis[][3], float basis[][3], float length);
+extern void IK_SetTransform(
+ IK_Segment *seg, float start[3], float rest_basis[][3], float basis[][3], float length);
extern void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax);
extern void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness);
@@ -144,8 +144,16 @@ IK_Solver *IK_CreateSolver(IK_Segment *root);
void IK_FreeSolver(IK_Solver *solver);
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight);
-void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight);
-void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle);
+void IK_SolverAddGoalOrientation(IK_Solver *solver,
+ IK_Segment *tip,
+ float goal[][3],
+ float weight);
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver,
+ IK_Segment *tip,
+ float goal[3],
+ float polegoal[3],
+ float poleangle,
+ int getangle);
float IK_SolverGetPoleAngle(IK_Solver *solver);
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations);
@@ -158,4 +166,4 @@ int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations);
}
#endif
-#endif // __IK_SOLVER_H__
+#endif // __IK_SOLVER_H__
diff --git a/intern/iksolver/intern/IK_Math.h b/intern/iksolver/intern/IK_Math.h
index b10aafaae27..ce99c3923f3 100644
--- a/intern/iksolver/intern/IK_Math.h
+++ b/intern/iksolver/intern/IK_Math.h
@@ -35,219 +35,227 @@ static const double IK_EPSILON = 1e-20;
static inline bool FuzzyZero(double x)
{
- return fabs(x) < IK_EPSILON;
+ return fabs(x) < IK_EPSILON;
}
static inline double Clamp(const double x, const double min, const double max)
{
- return (x < min) ? min : (x > max) ? max : x;
+ return (x < min) ? min : (x > max) ? max : x;
}
-static inline Eigen::Matrix3d CreateMatrix(double xx, double xy, double xz,
- double yx, double yy, double yz,
- double zx, double zy, double zz)
+static inline Eigen::Matrix3d CreateMatrix(double xx,
+ double xy,
+ double xz,
+ double yx,
+ double yy,
+ double yz,
+ double zx,
+ double zy,
+ double zz)
{
- Eigen::Matrix3d M;
- M(0, 0) = xx; M(0, 1) = xy; M(0, 2) = xz;
- M(1, 0) = yx; M(1, 1) = yy; M(1, 2) = yz;
- M(2, 0) = zx; M(2, 1) = zy; M(2, 2) = zz;
- return M;
+ Eigen::Matrix3d M;
+ M(0, 0) = xx;
+ M(0, 1) = xy;
+ M(0, 2) = xz;
+ M(1, 0) = yx;
+ M(1, 1) = yy;
+ M(1, 2) = yz;
+ M(2, 0) = zx;
+ M(2, 1) = zy;
+ M(2, 2) = zz;
+ return M;
}
static inline Eigen::Matrix3d RotationMatrix(double sine, double cosine, int axis)
{
- if (axis == 0)
- return CreateMatrix(1.0, 0.0, 0.0,
- 0.0, cosine, -sine,
- 0.0, sine, cosine);
- else if (axis == 1)
- return CreateMatrix(cosine, 0.0, sine,
- 0.0, 1.0, 0.0,
- -sine, 0.0, cosine);
- else
- return CreateMatrix(cosine, -sine, 0.0,
- sine, cosine, 0.0,
- 0.0, 0.0, 1.0);
+ if (axis == 0)
+ return CreateMatrix(1.0, 0.0, 0.0, 0.0, cosine, -sine, 0.0, sine, cosine);
+ else if (axis == 1)
+ return CreateMatrix(cosine, 0.0, sine, 0.0, 1.0, 0.0, -sine, 0.0, cosine);
+ else
+ return CreateMatrix(cosine, -sine, 0.0, sine, cosine, 0.0, 0.0, 0.0, 1.0);
}
static inline Eigen::Matrix3d RotationMatrix(double angle, int axis)
{
- return RotationMatrix(sin(angle), cos(angle), axis);
+ return RotationMatrix(sin(angle), cos(angle), axis);
}
-
-static inline double EulerAngleFromMatrix(const Eigen::Matrix3d& R, int axis)
+static inline double EulerAngleFromMatrix(const Eigen::Matrix3d &R, int axis)
{
- double t = sqrt(R(0, 0) * R(0, 0) + R(0, 1) * R(0, 1));
-
- if (t > 16.0 * IK_EPSILON) {
- if (axis == 0) return -atan2(R(1, 2), R(2, 2));
- else if (axis == 1) return atan2(-R(0, 2), t);
- else return -atan2(R(0, 1), R(0, 0));
- }
- else {
- if (axis == 0) return -atan2(-R(2, 1), R(1, 1));
- else if (axis == 1) return atan2(-R(0, 2), t);
- else return 0.0f;
- }
+ double t = sqrt(R(0, 0) * R(0, 0) + R(0, 1) * R(0, 1));
+
+ if (t > 16.0 * IK_EPSILON) {
+ if (axis == 0)
+ return -atan2(R(1, 2), R(2, 2));
+ else if (axis == 1)
+ return atan2(-R(0, 2), t);
+ else
+ return -atan2(R(0, 1), R(0, 0));
+ }
+ else {
+ if (axis == 0)
+ return -atan2(-R(2, 1), R(1, 1));
+ else if (axis == 1)
+ return atan2(-R(0, 2), t);
+ else
+ return 0.0f;
+ }
}
static inline double safe_acos(double f)
{
- // acos that does not return NaN with rounding errors
- if (f <= -1.0)
- return M_PI;
- else if (f >= 1.0)
- return 0.0;
- else
- return acos(f);
+ // acos that does not return NaN with rounding errors
+ if (f <= -1.0)
+ return M_PI;
+ else if (f >= 1.0)
+ return 0.0;
+ else
+ return acos(f);
}
-static inline Eigen::Vector3d normalize(const Eigen::Vector3d& v)
+static inline Eigen::Vector3d normalize(const Eigen::Vector3d &v)
{
- // a sane normalize function that doesn't give (1, 0, 0) in case
- // of a zero length vector
- double len = v.norm();
- return FuzzyZero(len) ? Eigen::Vector3d(0, 0, 0) : Eigen::Vector3d(v / len);
+ // a sane normalize function that doesn't give (1, 0, 0) in case
+ // of a zero length vector
+ double len = v.norm();
+ return FuzzyZero(len) ? Eigen::Vector3d(0, 0, 0) : Eigen::Vector3d(v / len);
}
-static inline double angle(const Eigen::Vector3d& v1, const Eigen::Vector3d& v2)
+static inline double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
{
- return safe_acos(v1.dot(v2));
+ return safe_acos(v1.dot(v2));
}
-static inline double ComputeTwist(const Eigen::Matrix3d& R)
+static inline double ComputeTwist(const Eigen::Matrix3d &R)
{
- // qy and qw are the y and w components of the quaternion from R
- double qy = R(0, 2) - R(2, 0);
- double qw = R(0, 0) + R(1, 1) + R(2, 2) + 1;
+ // qy and qw are the y and w components of the quaternion from R
+ double qy = R(0, 2) - R(2, 0);
+ double qw = R(0, 0) + R(1, 1) + R(2, 2) + 1;
- double tau = 2.0 * atan2(qy, qw);
+ double tau = 2.0 * atan2(qy, qw);
- return tau;
+ return tau;
}
static inline Eigen::Matrix3d ComputeTwistMatrix(double tau)
{
- return RotationMatrix(tau, 1);
+ return RotationMatrix(tau, 1);
}
-static inline void RemoveTwist(Eigen::Matrix3d& R)
+static inline void RemoveTwist(Eigen::Matrix3d &R)
{
- // compute twist parameter
- double tau = ComputeTwist(R);
+ // compute twist parameter
+ double tau = ComputeTwist(R);
- // compute twist matrix
- Eigen::Matrix3d T = ComputeTwistMatrix(tau);
+ // compute twist matrix
+ Eigen::Matrix3d T = ComputeTwistMatrix(tau);
- // remove twist
- R = R * T.transpose();
+ // remove twist
+ R = R * T.transpose();
}
-static inline Eigen::Vector3d SphericalRangeParameters(const Eigen::Matrix3d& R)
+static inline Eigen::Vector3d SphericalRangeParameters(const Eigen::Matrix3d &R)
{
- // compute twist parameter
- double tau = ComputeTwist(R);
+ // compute twist parameter
+ double tau = ComputeTwist(R);
- // compute swing parameters
- double num = 2.0 * (1.0 + R(1, 1));
+ // compute swing parameters
+ double num = 2.0 * (1.0 + R(1, 1));
- // singularity at pi
- if (fabs(num) < IK_EPSILON)
- // TODO: this does now rotation of size pi over z axis, but could
- // be any axis, how to deal with this i'm not sure, maybe don't
- // enforce limits at all then
- return Eigen::Vector3d(0.0, tau, 1.0);
+ // singularity at pi
+ if (fabs(num) < IK_EPSILON)
+ // TODO: this does now rotation of size pi over z axis, but could
+ // be any axis, how to deal with this i'm not sure, maybe don't
+ // enforce limits at all then
+ return Eigen::Vector3d(0.0, tau, 1.0);
- num = 1.0 / sqrt(num);
- double ax = -R(2, 1) * num;
- double az = R(0, 1) * num;
+ num = 1.0 / sqrt(num);
+ double ax = -R(2, 1) * num;
+ double az = R(0, 1) * num;
- return Eigen::Vector3d(ax, tau, az);
+ return Eigen::Vector3d(ax, tau, az);
}
static inline Eigen::Matrix3d ComputeSwingMatrix(double ax, double az)
{
- // length of (ax, 0, az) = sin(theta/2)
- double sine2 = ax * ax + az * az;
- double cosine2 = sqrt((sine2 >= 1.0) ? 0.0 : 1.0 - sine2);
-
- // compute swing matrix
- Eigen::Matrix3d S(Eigen::Quaterniond(-cosine2, ax, 0.0, az));
-
- return S;
-}
-
-static inline Eigen::Vector3d MatrixToAxisAngle(const Eigen::Matrix3d& R)
-{
- Eigen::Vector3d delta = Eigen::Vector3d(R(2, 1) - R(1, 2),
- R(0, 2) - R(2, 0),
- R(1, 0) - R(0, 1));
-
- double c = safe_acos((R(0, 0) + R(1, 1) + R(2, 2) - 1) / 2);
- double l = delta.norm();
-
- if (!FuzzyZero(l))
- delta *= c / l;
-
- return delta;
-}
-
-static inline bool EllipseClamp(double& ax, double& az, double *amin, double *amax)
-{
- double xlim, zlim, x, z;
-
- if (ax < 0.0) {
- x = -ax;
- xlim = -amin[0];
- }
- else {
- x = ax;
- xlim = amax[0];
- }
-
- if (az < 0.0) {
- z = -az;
- zlim = -amin[1];
- }
- else {
- z = az;
- zlim = amax[1];
- }
-
- if (FuzzyZero(xlim) || FuzzyZero(zlim)) {
- if (x <= xlim && z <= zlim)
- return false;
-
- if (x > xlim)
- x = xlim;
- if (z > zlim)
- z = zlim;
- }
- else {
- double invx = 1.0 / (xlim * xlim);
- double invz = 1.0 / (zlim * zlim);
-
- if ((x * x * invx + z * z * invz) <= 1.0)
- return false;
-
- if (FuzzyZero(x)) {
- x = 0.0;
- z = zlim;
- }
- else {
- double rico = z / x;
- double old_x = x;
- x = sqrt(1.0 / (invx + invz * rico * rico));
- if (old_x < 0.0)
- x = -x;
- z = rico * x;
- }
- }
-
- ax = (ax < 0.0) ? -x : x;
- az = (az < 0.0) ? -z : z;
-
- return true;
+ // length of (ax, 0, az) = sin(theta/2)
+ double sine2 = ax * ax + az * az;
+ double cosine2 = sqrt((sine2 >= 1.0) ? 0.0 : 1.0 - sine2);
+
+ // compute swing matrix
+ Eigen::Matrix3d S(Eigen::Quaterniond(-cosine2, ax, 0.0, az));
+
+ return S;
+}
+
+static inline Eigen::Vector3d MatrixToAxisAngle(const Eigen::Matrix3d &R)
+{
+ Eigen::Vector3d delta = Eigen::Vector3d(R(2, 1) - R(1, 2), R(0, 2) - R(2, 0), R(1, 0) - R(0, 1));
+
+ double c = safe_acos((R(0, 0) + R(1, 1) + R(2, 2) - 1) / 2);
+ double l = delta.norm();
+
+ if (!FuzzyZero(l))
+ delta *= c / l;
+
+ return delta;
}
+static inline bool EllipseClamp(double &ax, double &az, double *amin, double *amax)
+{
+ double xlim, zlim, x, z;
+
+ if (ax < 0.0) {
+ x = -ax;
+ xlim = -amin[0];
+ }
+ else {
+ x = ax;
+ xlim = amax[0];
+ }
+
+ if (az < 0.0) {
+ z = -az;
+ zlim = -amin[1];
+ }
+ else {
+ z = az;
+ zlim = amax[1];
+ }
+
+ if (FuzzyZero(xlim) || FuzzyZero(zlim)) {
+ if (x <= xlim && z <= zlim)
+ return false;
+
+ if (x > xlim)
+ x = xlim;
+ if (z > zlim)
+ z = zlim;
+ }
+ else {
+ double invx = 1.0 / (xlim * xlim);
+ double invz = 1.0 / (zlim * zlim);
+
+ if ((x * x * invx + z * z * invz) <= 1.0)
+ return false;
+
+ if (FuzzyZero(x)) {
+ x = 0.0;
+ z = zlim;
+ }
+ else {
+ double rico = z / x;
+ double old_x = x;
+ x = sqrt(1.0 / (invx + invz * rico * rico));
+ if (old_x < 0.0)
+ x = -x;
+ z = rico * x;
+ }
+ }
+
+ ax = (ax < 0.0) ? -x : x;
+ az = (az < 0.0) ? -z : z;
+
+ return true;
+}
diff --git a/intern/iksolver/intern/IK_QJacobian.cpp b/intern/iksolver/intern/IK_QJacobian.cpp
index 678486e36f4..7f77968a5d4 100644
--- a/intern/iksolver/intern/IK_QJacobian.cpp
+++ b/intern/iksolver/intern/IK_QJacobian.cpp
@@ -21,11 +21,9 @@
* \ingroup iksolver
*/
-
#include "IK_QJacobian.h"
-IK_QJacobian::IK_QJacobian()
- : m_sdls(true), m_min_damp(1.0)
+IK_QJacobian::IK_QJacobian() : m_sdls(true), m_min_damp(1.0)
{
}
@@ -35,392 +33,393 @@ IK_QJacobian::~IK_QJacobian()
void IK_QJacobian::ArmMatrices(int dof, int task_size)
{
- m_dof = dof;
- m_task_size = task_size;
+ m_dof = dof;
+ m_task_size = task_size;
- m_jacobian.resize(task_size, dof);
- m_jacobian.setZero();
+ m_jacobian.resize(task_size, dof);
+ m_jacobian.setZero();
- m_alpha.resize(dof);
- m_alpha.setZero();
+ m_alpha.resize(dof);
+ m_alpha.setZero();
- m_nullspace.resize(dof, dof);
+ m_nullspace.resize(dof, dof);
- m_d_theta.resize(dof);
- m_d_theta_tmp.resize(dof);
- m_d_norm_weight.resize(dof);
+ m_d_theta.resize(dof);
+ m_d_theta_tmp.resize(dof);
+ m_d_norm_weight.resize(dof);
- m_norm.resize(dof);
- m_norm.setZero();
+ m_norm.resize(dof);
+ m_norm.setZero();
- m_beta.resize(task_size);
+ m_beta.resize(task_size);
- m_weight.resize(dof);
- m_weight_sqrt.resize(dof);
- m_weight.setOnes();
- m_weight_sqrt.setOnes();
+ m_weight.resize(dof);
+ m_weight_sqrt.resize(dof);
+ m_weight.setOnes();
+ m_weight_sqrt.setOnes();
- if (task_size >= dof) {
- m_transpose = false;
+ if (task_size >= dof) {
+ m_transpose = false;
- m_jacobian_tmp.resize(task_size, dof);
+ m_jacobian_tmp.resize(task_size, dof);
- m_svd_u.resize(task_size, dof);
- m_svd_v.resize(dof, dof);
- m_svd_w.resize(dof);
+ m_svd_u.resize(task_size, dof);
+ m_svd_v.resize(dof, dof);
+ m_svd_w.resize(dof);
- m_svd_u_beta.resize(dof);
- }
- else {
- // use the SVD of the transpose jacobian, it works just as well
- // as the original, and often allows using smaller matrices.
- m_transpose = true;
+ m_svd_u_beta.resize(dof);
+ }
+ else {
+ // use the SVD of the transpose jacobian, it works just as well
+ // as the original, and often allows using smaller matrices.
+ m_transpose = true;
- m_jacobian_tmp.resize(dof, task_size);
+ m_jacobian_tmp.resize(dof, task_size);
- m_svd_u.resize(task_size, task_size);
- m_svd_v.resize(dof, task_size);
- m_svd_w.resize(task_size);
+ m_svd_u.resize(task_size, task_size);
+ m_svd_v.resize(dof, task_size);
+ m_svd_w.resize(task_size);
- m_svd_u_beta.resize(task_size);
- }
+ m_svd_u_beta.resize(task_size);
+ }
}
-void IK_QJacobian::SetBetas(int id, int, const Vector3d& v)
+void IK_QJacobian::SetBetas(int id, int, const Vector3d &v)
{
- m_beta[id + 0] = v.x();
- m_beta[id + 1] = v.y();
- m_beta[id + 2] = v.z();
+ m_beta[id + 0] = v.x();
+ m_beta[id + 1] = v.y();
+ m_beta[id + 2] = v.z();
}
-void IK_QJacobian::SetDerivatives(int id, int dof_id, const Vector3d& v, double norm_weight)
+void IK_QJacobian::SetDerivatives(int id, int dof_id, const Vector3d &v, double norm_weight)
{
- m_jacobian(id + 0, dof_id) = v.x() * m_weight_sqrt[dof_id];
- m_jacobian(id + 1, dof_id) = v.y() * m_weight_sqrt[dof_id];
- m_jacobian(id + 2, dof_id) = v.z() * m_weight_sqrt[dof_id];
+ m_jacobian(id + 0, dof_id) = v.x() * m_weight_sqrt[dof_id];
+ m_jacobian(id + 1, dof_id) = v.y() * m_weight_sqrt[dof_id];
+ m_jacobian(id + 2, dof_id) = v.z() * m_weight_sqrt[dof_id];
- m_d_norm_weight[dof_id] = norm_weight;
+ m_d_norm_weight[dof_id] = norm_weight;
}
void IK_QJacobian::Invert()
{
- if (m_transpose) {
- // SVD will decompose Jt into V*W*Ut with U,V orthogonal and W diagonal,
- // so J = U*W*Vt and Jinv = V*Winv*Ut
- Eigen::JacobiSVD<MatrixXd> svd(m_jacobian.transpose(), Eigen::ComputeThinU | Eigen::ComputeThinV);
- m_svd_u = svd.matrixV();
- m_svd_w = svd.singularValues();
- m_svd_v = svd.matrixU();
- }
- else {
- // SVD will decompose J into U*W*Vt with U,V orthogonal and W diagonal,
- // so Jinv = V*Winv*Ut
- Eigen::JacobiSVD<MatrixXd> svd(m_jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
- m_svd_u = svd.matrixU();
- m_svd_w = svd.singularValues();
- m_svd_v = svd.matrixV();
- }
-
- if (m_sdls)
- InvertSDLS();
- else
- InvertDLS();
+ if (m_transpose) {
+ // SVD will decompose Jt into V*W*Ut with U,V orthogonal and W diagonal,
+ // so J = U*W*Vt and Jinv = V*Winv*Ut
+ Eigen::JacobiSVD<MatrixXd> svd(m_jacobian.transpose(),
+ Eigen::ComputeThinU | Eigen::ComputeThinV);
+ m_svd_u = svd.matrixV();
+ m_svd_w = svd.singularValues();
+ m_svd_v = svd.matrixU();
+ }
+ else {
+ // SVD will decompose J into U*W*Vt with U,V orthogonal and W diagonal,
+ // so Jinv = V*Winv*Ut
+ Eigen::JacobiSVD<MatrixXd> svd(m_jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
+ m_svd_u = svd.matrixU();
+ m_svd_w = svd.singularValues();
+ m_svd_v = svd.matrixV();
+ }
+
+ if (m_sdls)
+ InvertSDLS();
+ else
+ InvertDLS();
}
bool IK_QJacobian::ComputeNullProjection()
{
- double epsilon = 1e-10;
-
- // compute null space projection based on V
- int i, j, rank = 0;
- for (i = 0; i < m_svd_w.size(); i++)
- if (m_svd_w[i] > epsilon)
- rank++;
-
- if (rank < m_task_size)
- return false;
-
- MatrixXd basis(m_svd_v.rows(), rank);
- int b = 0;
-
- for (i = 0; i < m_svd_w.size(); i++)
- if (m_svd_w[i] > epsilon) {
- for (j = 0; j < m_svd_v.rows(); j++)
- basis(j, b) = m_svd_v(j, i);
- b++;
- }
-
- m_nullspace = basis * basis.transpose();
-
- for (i = 0; i < m_nullspace.rows(); i++)
- for (j = 0; j < m_nullspace.cols(); j++)
- if (i == j)
- m_nullspace(i, j) = 1.0 - m_nullspace(i, j);
- else
- m_nullspace(i, j) = -m_nullspace(i, j);
-
- return true;
+ double epsilon = 1e-10;
+
+ // compute null space projection based on V
+ int i, j, rank = 0;
+ for (i = 0; i < m_svd_w.size(); i++)
+ if (m_svd_w[i] > epsilon)
+ rank++;
+
+ if (rank < m_task_size)
+ return false;
+
+ MatrixXd basis(m_svd_v.rows(), rank);
+ int b = 0;
+
+ for (i = 0; i < m_svd_w.size(); i++)
+ if (m_svd_w[i] > epsilon) {
+ for (j = 0; j < m_svd_v.rows(); j++)
+ basis(j, b) = m_svd_v(j, i);
+ b++;
+ }
+
+ m_nullspace = basis * basis.transpose();
+
+ for (i = 0; i < m_nullspace.rows(); i++)
+ for (j = 0; j < m_nullspace.cols(); j++)
+ if (i == j)
+ m_nullspace(i, j) = 1.0 - m_nullspace(i, j);
+ else
+ m_nullspace(i, j) = -m_nullspace(i, j);
+
+ return true;
}
-void IK_QJacobian::SubTask(IK_QJacobian& jacobian)
+void IK_QJacobian::SubTask(IK_QJacobian &jacobian)
{
- if (!ComputeNullProjection())
- return;
+ if (!ComputeNullProjection())
+ return;
- // restrict lower priority jacobian
- jacobian.Restrict(m_d_theta, m_nullspace);
+ // restrict lower priority jacobian
+ jacobian.Restrict(m_d_theta, m_nullspace);
- // add angle update from lower priority
- jacobian.Invert();
+ // add angle update from lower priority
+ jacobian.Invert();
- // note: now damps secondary angles with minimum damping value from
- // SDLS, to avoid shaking when the primary task is near singularities,
- // doesn't work well at all
- int i;
- for (i = 0; i < m_d_theta.size(); i++)
- m_d_theta[i] = m_d_theta[i] + /*m_min_damp * */ jacobian.AngleUpdate(i);
+ // note: now damps secondary angles with minimum damping value from
+ // SDLS, to avoid shaking when the primary task is near singularities,
+ // doesn't work well at all
+ int i;
+ for (i = 0; i < m_d_theta.size(); i++)
+ m_d_theta[i] = m_d_theta[i] + /*m_min_damp * */ jacobian.AngleUpdate(i);
}
-void IK_QJacobian::Restrict(VectorXd& d_theta, MatrixXd& nullspace)
+void IK_QJacobian::Restrict(VectorXd &d_theta, MatrixXd &nullspace)
{
- // subtract part already moved by higher task from beta
- m_beta = m_beta - m_jacobian * d_theta;
+ // subtract part already moved by higher task from beta
+ m_beta = m_beta - m_jacobian * d_theta;
+
+ // note: should we be using the norm of the unrestricted jacobian for SDLS?
- // note: should we be using the norm of the unrestricted jacobian for SDLS?
-
- // project jacobian on to null space of higher priority task
- m_jacobian = m_jacobian * nullspace;
+ // project jacobian on to null space of higher priority task
+ m_jacobian = m_jacobian * nullspace;
}
void IK_QJacobian::InvertSDLS()
{
- // Compute the dampeds least squeares pseudo inverse of J.
- //
- // Since J is usually not invertible (most of the times it's not even
- // square), the psuedo inverse is used. This gives us a least squares
- // solution.
- //
- // This is fine when the J*Jt is of full rank. When J*Jt is near to
- // singular the least squares inverse tries to minimize |J(dtheta) - dX)|
- // and doesn't try to minimize dTheta. This results in eratic changes in
- // angle. The damped least squares minimizes |dtheta| to try and reduce this
- // erratic behaviour.
- //
- // The selectively damped least squares (SDLS) is used here instead of the
- // DLS. The SDLS damps individual singular values, instead of using a single
- // damping term.
-
- double max_angle_change = M_PI / 4.0;
- double epsilon = 1e-10;
- int i, j;
-
- m_d_theta.setZero();
- m_min_damp = 1.0;
-
- for (i = 0; i < m_dof; i++) {
- m_norm[i] = 0.0;
- for (j = 0; j < m_task_size; j += 3) {
- double n = 0.0;
- n += m_jacobian(j, i) * m_jacobian(j, i);
- n += m_jacobian(j + 1, i) * m_jacobian(j + 1, i);
- n += m_jacobian(j + 2, i) * m_jacobian(j + 2, i);
- m_norm[i] += sqrt(n);
- }
- }
-
- for (i = 0; i < m_svd_w.size(); i++) {
- if (m_svd_w[i] <= epsilon)
- continue;
-
- double wInv = 1.0 / m_svd_w[i];
- double alpha = 0.0;
- double N = 0.0;
-
- // compute alpha and N
- for (j = 0; j < m_svd_u.rows(); j += 3) {
- alpha += m_svd_u(j, i) * m_beta[j];
- alpha += m_svd_u(j + 1, i) * m_beta[j + 1];
- alpha += m_svd_u(j + 2, i) * m_beta[j + 2];
-
- // note: for 1 end effector, N will always be 1, since U is
- // orthogonal, .. so could be optimized
- double tmp;
- tmp = m_svd_u(j, i) * m_svd_u(j, i);
- tmp += m_svd_u(j + 1, i) * m_svd_u(j + 1, i);
- tmp += m_svd_u(j + 2, i) * m_svd_u(j + 2, i);
- N += sqrt(tmp);
- }
- alpha *= wInv;
-
- // compute M, dTheta and max_dtheta
- double M = 0.0;
- double max_dtheta = 0.0, abs_dtheta;
-
- for (j = 0; j < m_d_theta.size(); j++) {
- double v = m_svd_v(j, i);
- M += fabs(v) * m_norm[j];
-
- // compute tmporary dTheta's
- m_d_theta_tmp[j] = v * alpha;
-
- // find largest absolute dTheta
- // multiply with weight to prevent unnecessary damping
- abs_dtheta = fabs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
- if (abs_dtheta > max_dtheta)
- max_dtheta = abs_dtheta;
- }
-
- M *= wInv;
-
- // compute damping term and damp the dTheta's
- double gamma = max_angle_change;
- if (N < M)
- gamma *= N / M;
-
- double damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0;
-
- for (j = 0; j < m_d_theta.size(); j++) {
- // slight hack: we do 0.80*, so that if there is some oscillation,
- // the system can still converge (for joint limits). also, it's
- // better to go a little to slow than to far
-
- double dofdamp = damp / m_weight[j];
- if (dofdamp > 1.0) dofdamp = 1.0;
-
- m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
- }
-
- if (damp < m_min_damp)
- m_min_damp = damp;
- }
-
- // weight + prevent from doing angle updates with angles > max_angle_change
- double max_angle = 0.0, abs_angle;
-
- for (j = 0; j < m_dof; j++) {
- m_d_theta[j] *= m_weight[j];
-
- abs_angle = fabs(m_d_theta[j]);
-
- if (abs_angle > max_angle)
- max_angle = abs_angle;
- }
-
- if (max_angle > max_angle_change) {
- double damp = (max_angle_change) / (max_angle_change + max_angle);
-
- for (j = 0; j < m_dof; j++)
- m_d_theta[j] *= damp;
- }
+ // Compute the dampeds least squeares pseudo inverse of J.
+ //
+ // Since J is usually not invertible (most of the times it's not even
+ // square), the psuedo inverse is used. This gives us a least squares
+ // solution.
+ //
+ // This is fine when the J*Jt is of full rank. When J*Jt is near to
+ // singular the least squares inverse tries to minimize |J(dtheta) - dX)|
+ // and doesn't try to minimize dTheta. This results in eratic changes in
+ // angle. The damped least squares minimizes |dtheta| to try and reduce this
+ // erratic behaviour.
+ //
+ // The selectively damped least squares (SDLS) is used here instead of the
+ // DLS. The SDLS damps individual singular values, instead of using a single
+ // damping term.
+
+ double max_angle_change = M_PI / 4.0;
+ double epsilon = 1e-10;
+ int i, j;
+
+ m_d_theta.setZero();
+ m_min_damp = 1.0;
+
+ for (i = 0; i < m_dof; i++) {
+ m_norm[i] = 0.0;
+ for (j = 0; j < m_task_size; j += 3) {
+ double n = 0.0;
+ n += m_jacobian(j, i) * m_jacobian(j, i);
+ n += m_jacobian(j + 1, i) * m_jacobian(j + 1, i);
+ n += m_jacobian(j + 2, i) * m_jacobian(j + 2, i);
+ m_norm[i] += sqrt(n);
+ }
+ }
+
+ for (i = 0; i < m_svd_w.size(); i++) {
+ if (m_svd_w[i] <= epsilon)
+ continue;
+
+ double wInv = 1.0 / m_svd_w[i];
+ double alpha = 0.0;
+ double N = 0.0;
+
+ // compute alpha and N
+ for (j = 0; j < m_svd_u.rows(); j += 3) {
+ alpha += m_svd_u(j, i) * m_beta[j];
+ alpha += m_svd_u(j + 1, i) * m_beta[j + 1];
+ alpha += m_svd_u(j + 2, i) * m_beta[j + 2];
+
+ // note: for 1 end effector, N will always be 1, since U is
+ // orthogonal, .. so could be optimized
+ double tmp;
+ tmp = m_svd_u(j, i) * m_svd_u(j, i);
+ tmp += m_svd_u(j + 1, i) * m_svd_u(j + 1, i);
+ tmp += m_svd_u(j + 2, i) * m_svd_u(j + 2, i);
+ N += sqrt(tmp);
+ }
+ alpha *= wInv;
+
+ // compute M, dTheta and max_dtheta
+ double M = 0.0;
+ double max_dtheta = 0.0, abs_dtheta;
+
+ for (j = 0; j < m_d_theta.size(); j++) {
+ double v = m_svd_v(j, i);
+ M += fabs(v) * m_norm[j];
+
+ // compute tmporary dTheta's
+ m_d_theta_tmp[j] = v * alpha;
+
+ // find largest absolute dTheta
+ // multiply with weight to prevent unnecessary damping
+ abs_dtheta = fabs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
+ if (abs_dtheta > max_dtheta)
+ max_dtheta = abs_dtheta;
+ }
+
+ M *= wInv;
+
+ // compute damping term and damp the dTheta's
+ double gamma = max_angle_change;
+ if (N < M)
+ gamma *= N / M;
+
+ double damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0;
+
+ for (j = 0; j < m_d_theta.size(); j++) {
+ // slight hack: we do 0.80*, so that if there is some oscillation,
+ // the system can still converge (for joint limits). also, it's
+ // better to go a little to slow than to far
+
+ double dofdamp = damp / m_weight[j];
+ if (dofdamp > 1.0)
+ dofdamp = 1.0;
+
+ m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
+ }
+
+ if (damp < m_min_damp)
+ m_min_damp = damp;
+ }
+
+ // weight + prevent from doing angle updates with angles > max_angle_change
+ double max_angle = 0.0, abs_angle;
+
+ for (j = 0; j < m_dof; j++) {
+ m_d_theta[j] *= m_weight[j];
+
+ abs_angle = fabs(m_d_theta[j]);
+
+ if (abs_angle > max_angle)
+ max_angle = abs_angle;
+ }
+
+ if (max_angle > max_angle_change) {
+ double damp = (max_angle_change) / (max_angle_change + max_angle);
+
+ for (j = 0; j < m_dof; j++)
+ m_d_theta[j] *= damp;
+ }
}
void IK_QJacobian::InvertDLS()
{
- // Compute damped least squares inverse of pseudo inverse
- // Compute damping term lambda
+ // Compute damped least squares inverse of pseudo inverse
+ // Compute damping term lambda
+
+ // Note when lambda is zero this is equivalent to the
+ // least squares solution. This is fine when the m_jjt is
+ // of full rank. When m_jjt is near to singular the least squares
+ // inverse tries to minimize |J(dtheta) - dX)| and doesn't
+ // try to minimize dTheta. This results in eratic changes in angle.
+ // Damped least squares minimizes |dtheta| to try and reduce this
+ // erratic behaviour.
- // Note when lambda is zero this is equivalent to the
- // least squares solution. This is fine when the m_jjt is
- // of full rank. When m_jjt is near to singular the least squares
- // inverse tries to minimize |J(dtheta) - dX)| and doesn't
- // try to minimize dTheta. This results in eratic changes in angle.
- // Damped least squares minimizes |dtheta| to try and reduce this
- // erratic behaviour.
+ // We don't want to use the damped solution everywhere so we
+ // only increase lamda from zero as we approach a singularity.
- // We don't want to use the damped solution everywhere so we
- // only increase lamda from zero as we approach a singularity.
+ // find the smallest non-zero W value, anything below epsilon is
+ // treated as zero
- // find the smallest non-zero W value, anything below epsilon is
- // treated as zero
+ double epsilon = 1e-10;
+ double max_angle_change = 0.1;
+ double x_length = sqrt(m_beta.dot(m_beta));
- double epsilon = 1e-10;
- double max_angle_change = 0.1;
- double x_length = sqrt(m_beta.dot(m_beta));
+ int i, j;
+ double w_min = std::numeric_limits<double>::max();
- int i, j;
- double w_min = std::numeric_limits<double>::max();
+ for (i = 0; i < m_svd_w.size(); i++) {
+ if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min)
+ w_min = m_svd_w[i];
+ }
- for (i = 0; i < m_svd_w.size(); i++) {
- if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min)
- w_min = m_svd_w[i];
- }
-
- // compute lambda damping term
+ // compute lambda damping term
- double d = x_length / max_angle_change;
- double lambda;
+ double d = x_length / max_angle_change;
+ double lambda;
- if (w_min <= d / 2)
- lambda = d / 2;
- else if (w_min < d)
- lambda = sqrt(w_min * (d - w_min));
- else
- lambda = 0.0;
+ if (w_min <= d / 2)
+ lambda = d / 2;
+ else if (w_min < d)
+ lambda = sqrt(w_min * (d - w_min));
+ else
+ lambda = 0.0;
- lambda *= lambda;
+ lambda *= lambda;
- if (lambda > 10)
- lambda = 10;
+ if (lambda > 10)
+ lambda = 10;
- // immediately multiply with Beta, so we can do matrix*vector products
- // rather than matrix*matrix products
+ // immediately multiply with Beta, so we can do matrix*vector products
+ // rather than matrix*matrix products
- // compute Ut*Beta
- m_svd_u_beta = m_svd_u.transpose() * m_beta;
+ // compute Ut*Beta
+ m_svd_u_beta = m_svd_u.transpose() * m_beta;
- m_d_theta.setZero();
+ m_d_theta.setZero();
- for (i = 0; i < m_svd_w.size(); i++) {
- if (m_svd_w[i] > epsilon) {
- double wInv = m_svd_w[i] / (m_svd_w[i] * m_svd_w[i] + lambda);
+ for (i = 0; i < m_svd_w.size(); i++) {
+ if (m_svd_w[i] > epsilon) {
+ double wInv = m_svd_w[i] / (m_svd_w[i] * m_svd_w[i] + lambda);
- // compute V*Winv*Ut*Beta
- m_svd_u_beta[i] *= wInv;
+ // compute V*Winv*Ut*Beta
+ m_svd_u_beta[i] *= wInv;
- for (j = 0; j < m_d_theta.size(); j++)
- m_d_theta[j] += m_svd_v(j, i) * m_svd_u_beta[i];
- }
- }
+ for (j = 0; j < m_d_theta.size(); j++)
+ m_d_theta[j] += m_svd_v(j, i) * m_svd_u_beta[i];
+ }
+ }
- for (j = 0; j < m_d_theta.size(); j++)
- m_d_theta[j] *= m_weight[j];
+ for (j = 0; j < m_d_theta.size(); j++)
+ m_d_theta[j] *= m_weight[j];
}
void IK_QJacobian::Lock(int dof_id, double delta)
{
- int i;
+ int i;
- for (i = 0; i < m_task_size; i++) {
- m_beta[i] -= m_jacobian(i, dof_id) * delta;
- m_jacobian(i, dof_id) = 0.0;
- }
+ for (i = 0; i < m_task_size; i++) {
+ m_beta[i] -= m_jacobian(i, dof_id) * delta;
+ m_jacobian(i, dof_id) = 0.0;
+ }
- m_norm[dof_id] = 0.0; // unneeded
- m_d_theta[dof_id] = 0.0;
+ m_norm[dof_id] = 0.0; // unneeded
+ m_d_theta[dof_id] = 0.0;
}
double IK_QJacobian::AngleUpdate(int dof_id) const
{
- return m_d_theta[dof_id];
+ return m_d_theta[dof_id];
}
double IK_QJacobian::AngleUpdateNorm() const
{
- int i;
- double mx = 0.0, dtheta_abs;
-
- for (i = 0; i < m_d_theta.size(); i++) {
- dtheta_abs = fabs(m_d_theta[i] * m_d_norm_weight[i]);
- if (dtheta_abs > mx)
- mx = dtheta_abs;
- }
-
- return mx;
+ int i;
+ double mx = 0.0, dtheta_abs;
+
+ for (i = 0; i < m_d_theta.size(); i++) {
+ dtheta_abs = fabs(m_d_theta[i] * m_d_norm_weight[i]);
+ if (dtheta_abs > mx)
+ mx = dtheta_abs;
+ }
+
+ return mx;
}
void IK_QJacobian::SetDoFWeight(int dof, double weight)
{
- m_weight[dof] = weight;
- m_weight_sqrt[dof] = sqrt(weight);
+ m_weight[dof] = weight;
+ m_weight_sqrt[dof] = sqrt(weight);
}
-
diff --git a/intern/iksolver/intern/IK_QJacobian.h b/intern/iksolver/intern/IK_QJacobian.h
index f7b26ad6d33..1b18107fb67 100644
--- a/intern/iksolver/intern/IK_QJacobian.h
+++ b/intern/iksolver/intern/IK_QJacobian.h
@@ -26,72 +26,69 @@
#include "IK_Math.h"
-class IK_QJacobian
-{
-public:
- IK_QJacobian();
- ~IK_QJacobian();
+class IK_QJacobian {
+ public:
+ IK_QJacobian();
+ ~IK_QJacobian();
- // Call once to initialize
- void ArmMatrices(int dof, int task_size);
- void SetDoFWeight(int dof, double weight);
+ // Call once to initialize
+ void ArmMatrices(int dof, int task_size);
+ void SetDoFWeight(int dof, double weight);
- // Iteratively called
- void SetBetas(int id, int size, const Vector3d& v);
- void SetDerivatives(int id, int dof_id, const Vector3d& v, double norm_weight);
+ // Iteratively called
+ void SetBetas(int id, int size, const Vector3d &v);
+ void SetDerivatives(int id, int dof_id, const Vector3d &v, double norm_weight);
- void Invert();
+ void Invert();
- double AngleUpdate(int dof_id) const;
- double AngleUpdateNorm() const;
+ double AngleUpdate(int dof_id) const;
+ double AngleUpdateNorm() const;
- // DoF locking for inner clamping loop
- void Lock(int dof_id, double delta);
+ // DoF locking for inner clamping loop
+ void Lock(int dof_id, double delta);
- // Secondary task
- bool ComputeNullProjection();
+ // Secondary task
+ bool ComputeNullProjection();
- void Restrict(VectorXd& d_theta, MatrixXd& nullspace);
- void SubTask(IK_QJacobian& jacobian);
+ void Restrict(VectorXd &d_theta, MatrixXd &nullspace);
+ void SubTask(IK_QJacobian &jacobian);
-private:
-
- void InvertSDLS();
- void InvertDLS();
+ private:
+ void InvertSDLS();
+ void InvertDLS();
- int m_dof, m_task_size;
- bool m_transpose;
+ int m_dof, m_task_size;
+ bool m_transpose;
- // the jacobian matrix and it's null space projector
- MatrixXd m_jacobian, m_jacobian_tmp;
- MatrixXd m_nullspace;
+ // the jacobian matrix and it's null space projector
+ MatrixXd m_jacobian, m_jacobian_tmp;
+ MatrixXd m_nullspace;
- /// the vector of intermediate betas
- VectorXd m_beta;
+ /// the vector of intermediate betas
+ VectorXd m_beta;
- /// the vector of computed angle changes
- VectorXd m_d_theta;
- VectorXd m_d_norm_weight;
+ /// the vector of computed angle changes
+ VectorXd m_d_theta;
+ VectorXd m_d_norm_weight;
- /// space required for SVD computation
- VectorXd m_svd_w;
- MatrixXd m_svd_v;
- MatrixXd m_svd_u;
+ /// space required for SVD computation
+ VectorXd m_svd_w;
+ MatrixXd m_svd_v;
+ MatrixXd m_svd_u;
- VectorXd m_svd_u_beta;
+ VectorXd m_svd_u_beta;
- // space required for SDLS
+ // space required for SDLS
- bool m_sdls;
- VectorXd m_norm;
- VectorXd m_d_theta_tmp;
- double m_min_damp;
+ bool m_sdls;
+ VectorXd m_norm;
+ VectorXd m_d_theta_tmp;
+ double m_min_damp;
- // null space task vector
- VectorXd m_alpha;
+ // null space task vector
+ VectorXd m_alpha;
- // dof weighting
- VectorXd m_weight;
- VectorXd m_weight_sqrt;
+ // dof weighting
+ VectorXd m_weight;
+ VectorXd m_weight_sqrt;
};
-
diff --git a/intern/iksolver/intern/IK_QJacobianSolver.cpp b/intern/iksolver/intern/IK_QJacobianSolver.cpp
index 5288def7f55..90032096d37 100644
--- a/intern/iksolver/intern/IK_QJacobianSolver.cpp
+++ b/intern/iksolver/intern/IK_QJacobianSolver.cpp
@@ -21,7 +21,6 @@
* \ingroup iksolver
*/
-
#include <stdio.h>
#include "IK_QJacobianSolver.h"
@@ -29,340 +28,338 @@
//#include "analyze.h"
IK_QJacobianSolver::IK_QJacobianSolver()
{
- m_poleconstraint = false;
- m_getpoleangle = false;
- m_rootmatrix.setIdentity();
+ m_poleconstraint = false;
+ m_getpoleangle = false;
+ m_rootmatrix.setIdentity();
}
double IK_QJacobianSolver::ComputeScale()
{
- std::vector<IK_QSegment *>::iterator seg;
- double length = 0.0f;
-
- for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
- length += (*seg)->MaxExtension();
-
- if (length == 0.0)
- return 1.0;
- else
- return 1.0 / length;
+ std::vector<IK_QSegment *>::iterator seg;
+ double length = 0.0f;
+
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+ length += (*seg)->MaxExtension();
+
+ if (length == 0.0)
+ return 1.0;
+ else
+ return 1.0 / length;
}
-void IK_QJacobianSolver::Scale(double scale, std::list<IK_QTask *>& tasks)
+void IK_QJacobianSolver::Scale(double scale, std::list<IK_QTask *> &tasks)
{
- std::list<IK_QTask *>::iterator task;
- std::vector<IK_QSegment *>::iterator seg;
-
- for (task = tasks.begin(); task != tasks.end(); task++)
- (*task)->Scale(scale);
-
- for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
- (*seg)->Scale(scale);
-
- m_rootmatrix.translation() *= scale;
- m_goal *= scale;
- m_polegoal *= scale;
+ std::list<IK_QTask *>::iterator task;
+ std::vector<IK_QSegment *>::iterator seg;
+
+ for (task = tasks.begin(); task != tasks.end(); task++)
+ (*task)->Scale(scale);
+
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+ (*seg)->Scale(scale);
+
+ m_rootmatrix.translation() *= scale;
+ m_goal *= scale;
+ m_polegoal *= scale;
}
void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg)
{
- m_segments.push_back(seg);
+ m_segments.push_back(seg);
- IK_QSegment *child;
- for (child = seg->Child(); child; child = child->Sibling())
- AddSegmentList(child);
+ IK_QSegment *child;
+ for (child = seg->Child(); child; child = child->Sibling())
+ AddSegmentList(child);
}
-bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *>& tasks)
+bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks)
{
- m_segments.clear();
- AddSegmentList(root);
-
- // assign each segment a unique id for the jacobian
- std::vector<IK_QSegment *>::iterator seg;
- int num_dof = 0;
-
- for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
- (*seg)->SetDoFId(num_dof);
- num_dof += (*seg)->NumberOfDoF();
- }
-
- if (num_dof == 0)
- return false;
-
- // compute task id's and assing weights to task
- int primary_size = 0, primary = 0;
- int secondary_size = 0, secondary = 0;
- double primary_weight = 0.0, secondary_weight = 0.0;
- std::list<IK_QTask *>::iterator task;
-
- for (task = tasks.begin(); task != tasks.end(); task++) {
- IK_QTask *qtask = *task;
-
- if (qtask->Primary()) {
- qtask->SetId(primary_size);
- primary_size += qtask->Size();
- primary_weight += qtask->Weight();
- primary++;
- }
- else {
- qtask->SetId(secondary_size);
- secondary_size += qtask->Size();
- secondary_weight += qtask->Weight();
- secondary++;
- }
- }
-
- if (primary_size == 0 || FuzzyZero(primary_weight))
- return false;
-
- m_secondary_enabled = (secondary > 0);
-
- // rescale weights of tasks to sum up to 1
- double primary_rescale = 1.0 / primary_weight;
- double secondary_rescale;
- if (FuzzyZero(secondary_weight))
- secondary_rescale = 0.0;
- else
- secondary_rescale = 1.0 / secondary_weight;
-
- for (task = tasks.begin(); task != tasks.end(); task++) {
- IK_QTask *qtask = *task;
-
- if (qtask->Primary())
- qtask->SetWeight(qtask->Weight() * primary_rescale);
- else
- qtask->SetWeight(qtask->Weight() * secondary_rescale);
- }
-
- // set matrix sizes
- m_jacobian.ArmMatrices(num_dof, primary_size);
- if (secondary > 0)
- m_jacobian_sub.ArmMatrices(num_dof, secondary_size);
-
- // set dof weights
- int i;
-
- for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
- for (i = 0; i < (*seg)->NumberOfDoF(); i++)
- m_jacobian.SetDoFWeight((*seg)->DoFId() + i, (*seg)->Weight(i));
-
- return true;
+ m_segments.clear();
+ AddSegmentList(root);
+
+ // assign each segment a unique id for the jacobian
+ std::vector<IK_QSegment *>::iterator seg;
+ int num_dof = 0;
+
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
+ (*seg)->SetDoFId(num_dof);
+ num_dof += (*seg)->NumberOfDoF();
+ }
+
+ if (num_dof == 0)
+ return false;
+
+ // compute task id's and assing weights to task
+ int primary_size = 0, primary = 0;
+ int secondary_size = 0, secondary = 0;
+ double primary_weight = 0.0, secondary_weight = 0.0;
+ std::list<IK_QTask *>::iterator task;
+
+ for (task = tasks.begin(); task != tasks.end(); task++) {
+ IK_QTask *qtask = *task;
+
+ if (qtask->Primary()) {
+ qtask->SetId(primary_size);
+ primary_size += qtask->Size();
+ primary_weight += qtask->Weight();
+ primary++;
+ }
+ else {
+ qtask->SetId(secondary_size);
+ secondary_size += qtask->Size();
+ secondary_weight += qtask->Weight();
+ secondary++;
+ }
+ }
+
+ if (primary_size == 0 || FuzzyZero(primary_weight))
+ return false;
+
+ m_secondary_enabled = (secondary > 0);
+
+ // rescale weights of tasks to sum up to 1
+ double primary_rescale = 1.0 / primary_weight;
+ double secondary_rescale;
+ if (FuzzyZero(secondary_weight))
+ secondary_rescale = 0.0;
+ else
+ secondary_rescale = 1.0 / secondary_weight;
+
+ for (task = tasks.begin(); task != tasks.end(); task++) {
+ IK_QTask *qtask = *task;
+
+ if (qtask->Primary())
+ qtask->SetWeight(qtask->Weight() * primary_rescale);
+ else
+ qtask->SetWeight(qtask->Weight() * secondary_rescale);
+ }
+
+ // set matrix sizes
+ m_jacobian.ArmMatrices(num_dof, primary_size);
+ if (secondary > 0)
+ m_jacobian_sub.ArmMatrices(num_dof, secondary_size);
+
+ // set dof weights
+ int i;
+
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+ for (i = 0; i < (*seg)->NumberOfDoF(); i++)
+ m_jacobian.SetDoFWeight((*seg)->DoFId() + i, (*seg)->Weight(i));
+
+ return true;
}
-void IK_QJacobianSolver::SetPoleVectorConstraint(IK_QSegment *tip, Vector3d& goal, Vector3d& polegoal, float poleangle, bool getangle)
+void IK_QJacobianSolver::SetPoleVectorConstraint(
+ IK_QSegment *tip, Vector3d &goal, Vector3d &polegoal, float poleangle, bool getangle)
{
- m_poleconstraint = true;
- m_poletip = tip;
- m_goal = goal;
- m_polegoal = polegoal;
- m_poleangle = (getangle) ? 0.0f : poleangle;
- m_getpoleangle = getangle;
+ m_poleconstraint = true;
+ m_poletip = tip;
+ m_goal = goal;
+ m_polegoal = polegoal;
+ m_poleangle = (getangle) ? 0.0f : poleangle;
+ m_getpoleangle = getangle;
}
-void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask *>& tasks)
+void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask *> &tasks)
{
- // this function will be called before and after solving. calling it before
- // solving gives predictable solutions by rotating towards the solution,
- // and calling it afterwards ensures the solution is exact.
-
- if (!m_poleconstraint)
- return;
-
- // disable pole vector constraint in case of multiple position tasks
- std::list<IK_QTask *>::iterator task;
- int positiontasks = 0;
-
- for (task = tasks.begin(); task != tasks.end(); task++)
- if ((*task)->PositionTask())
- positiontasks++;
-
- if (positiontasks >= 2) {
- m_poleconstraint = false;
- return;
- }
-
- // get positions and rotations
- root->UpdateTransform(m_rootmatrix);
-
- const Vector3d rootpos = root->GlobalStart();
- const Vector3d endpos = m_poletip->GlobalEnd();
- const Matrix3d& rootbasis = root->GlobalTransform().linear();
-
- // construct "lookat" matrices (like gluLookAt), based on a direction and
- // an up vector, with the direction going from the root to the end effector
- // and the up vector going from the root to the pole constraint position.
- Vector3d dir = normalize(endpos - rootpos);
- Vector3d rootx = rootbasis.col(0);
- Vector3d rootz = rootbasis.col(2);
- Vector3d up = rootx * cos(m_poleangle) + rootz *sin(m_poleangle);
-
- // in post, don't rotate towards the goal but only correct the pole up
- Vector3d poledir = (m_getpoleangle) ? dir : normalize(m_goal - rootpos);
- Vector3d poleup = normalize(m_polegoal - rootpos);
-
- Matrix3d mat, polemat;
-
- mat.row(0) = normalize(dir.cross(up));
- mat.row(1) = mat.row(0).cross(dir);
- mat.row(2) = -dir;
-
- polemat.row(0) = normalize(poledir.cross(poleup));
- polemat.row(1) = polemat.row(0).cross(poledir);
- polemat.row(2) = -poledir;
-
- if (m_getpoleangle) {
- // we compute the pole angle that to rotate towards the target
- m_poleangle = angle(mat.row(1), polemat.row(1));
-
- double dt = rootz.dot(mat.row(1) * cos(m_poleangle) + mat.row(0) * sin(m_poleangle));
- if (dt > 0.0)
- m_poleangle = -m_poleangle;
-
- // solve again, with the pole angle we just computed
- m_getpoleangle = false;
- ConstrainPoleVector(root, tasks);
- }
- else {
- // now we set as root matrix the difference between the current and
- // desired rotation based on the pole vector constraint. we use
- // transpose instead of inverse because we have orthogonal matrices
- // anyway, and in case of a singular matrix we don't get NaN's.
- Affine3d trans;
- trans.linear() = polemat.transpose() * mat;
- trans.translation() = Vector3d(0, 0, 0);
- m_rootmatrix = trans * m_rootmatrix;
- }
+ // this function will be called before and after solving. calling it before
+ // solving gives predictable solutions by rotating towards the solution,
+ // and calling it afterwards ensures the solution is exact.
+
+ if (!m_poleconstraint)
+ return;
+
+ // disable pole vector constraint in case of multiple position tasks
+ std::list<IK_QTask *>::iterator task;
+ int positiontasks = 0;
+
+ for (task = tasks.begin(); task != tasks.end(); task++)
+ if ((*task)->PositionTask())
+ positiontasks++;
+
+ if (positiontasks >= 2) {
+ m_poleconstraint = false;
+ return;
+ }
+
+ // get positions and rotations
+ root->UpdateTransform(m_rootmatrix);
+
+ const Vector3d rootpos = root->GlobalStart();
+ const Vector3d endpos = m_poletip->GlobalEnd();
+ const Matrix3d &rootbasis = root->GlobalTransform().linear();
+
+ // construct "lookat" matrices (like gluLookAt), based on a direction and
+ // an up vector, with the direction going from the root to the end effector
+ // and the up vector going from the root to the pole constraint position.
+ Vector3d dir = normalize(endpos - rootpos);
+ Vector3d rootx = rootbasis.col(0);
+ Vector3d rootz = rootbasis.col(2);
+ Vector3d up = rootx * cos(m_poleangle) + rootz * sin(m_poleangle);
+
+ // in post, don't rotate towards the goal but only correct the pole up
+ Vector3d poledir = (m_getpoleangle) ? dir : normalize(m_goal - rootpos);
+ Vector3d poleup = normalize(m_polegoal - rootpos);
+
+ Matrix3d mat, polemat;
+
+ mat.row(0) = normalize(dir.cross(up));
+ mat.row(1) = mat.row(0).cross(dir);
+ mat.row(2) = -dir;
+
+ polemat.row(0) = normalize(poledir.cross(poleup));
+ polemat.row(1) = polemat.row(0).cross(poledir);
+ polemat.row(2) = -poledir;
+
+ if (m_getpoleangle) {
+ // we compute the pole angle that to rotate towards the target
+ m_poleangle = angle(mat.row(1), polemat.row(1));
+
+ double dt = rootz.dot(mat.row(1) * cos(m_poleangle) + mat.row(0) * sin(m_poleangle));
+ if (dt > 0.0)
+ m_poleangle = -m_poleangle;
+
+ // solve again, with the pole angle we just computed
+ m_getpoleangle = false;
+ ConstrainPoleVector(root, tasks);
+ }
+ else {
+ // now we set as root matrix the difference between the current and
+ // desired rotation based on the pole vector constraint. we use
+ // transpose instead of inverse because we have orthogonal matrices
+ // anyway, and in case of a singular matrix we don't get NaN's.
+ Affine3d trans;
+ trans.linear() = polemat.transpose() * mat;
+ trans.translation() = Vector3d(0, 0, 0);
+ m_rootmatrix = trans * m_rootmatrix;
+ }
}
-bool IK_QJacobianSolver::UpdateAngles(double& norm)
+bool IK_QJacobianSolver::UpdateAngles(double &norm)
{
- // assing each segment a unique id for the jacobian
- std::vector<IK_QSegment *>::iterator seg;
- IK_QSegment *qseg, *minseg = NULL;
- double minabsdelta = 1e10, absdelta;
- Vector3d delta, mindelta;
- bool locked = false, clamp[3];
- int i, mindof = 0;
-
- // here we check if any angle limits were violated. angles whose clamped
- // position is the same as it was before, are locked immediate. of the
- // other violation angles the most violating angle is rememberd
- for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
- qseg = *seg;
- if (qseg->UpdateAngle(m_jacobian, delta, clamp)) {
- for (i = 0; i < qseg->NumberOfDoF(); i++) {
- if (clamp[i] && !qseg->Locked(i)) {
- absdelta = fabs(delta[i]);
-
- if (absdelta < IK_EPSILON) {
- qseg->Lock(i, m_jacobian, delta);
- locked = true;
- }
- else if (absdelta < minabsdelta) {
- minabsdelta = absdelta;
- mindelta = delta;
- minseg = qseg;
- mindof = i;
- }
- }
- }
- }
- }
-
- // lock most violating angle
- if (minseg) {
- minseg->Lock(mindof, m_jacobian, mindelta);
- locked = true;
-
- if (minabsdelta > norm)
- norm = minabsdelta;
- }
-
- if (locked == false)
- // no locking done, last inner iteration, apply the angles
- for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
- (*seg)->UnLock();
- (*seg)->UpdateAngleApply();
- }
-
- // signal if another inner iteration is needed
- return locked;
+ // assing each segment a unique id for the jacobian
+ std::vector<IK_QSegment *>::iterator seg;
+ IK_QSegment *qseg, *minseg = NULL;
+ double minabsdelta = 1e10, absdelta;
+ Vector3d delta, mindelta;
+ bool locked = false, clamp[3];
+ int i, mindof = 0;
+
+ // here we check if any angle limits were violated. angles whose clamped
+ // position is the same as it was before, are locked immediate. of the
+ // other violation angles the most violating angle is rememberd
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
+ qseg = *seg;
+ if (qseg->UpdateAngle(m_jacobian, delta, clamp)) {
+ for (i = 0; i < qseg->NumberOfDoF(); i++) {
+ if (clamp[i] && !qseg->Locked(i)) {
+ absdelta = fabs(delta[i]);
+
+ if (absdelta < IK_EPSILON) {
+ qseg->Lock(i, m_jacobian, delta);
+ locked = true;
+ }
+ else if (absdelta < minabsdelta) {
+ minabsdelta = absdelta;
+ mindelta = delta;
+ minseg = qseg;
+ mindof = i;
+ }
+ }
+ }
+ }
+ }
+
+ // lock most violating angle
+ if (minseg) {
+ minseg->Lock(mindof, m_jacobian, mindelta);
+ locked = true;
+
+ if (minabsdelta > norm)
+ norm = minabsdelta;
+ }
+
+ if (locked == false)
+ // no locking done, last inner iteration, apply the angles
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
+ (*seg)->UnLock();
+ (*seg)->UpdateAngleApply();
+ }
+
+ // signal if another inner iteration is needed
+ return locked;
}
-bool IK_QJacobianSolver::Solve(
- IK_QSegment *root,
- std::list<IK_QTask *> tasks,
- const double,
- const int max_iterations
- )
+bool IK_QJacobianSolver::Solve(IK_QSegment *root,
+ std::list<IK_QTask *> tasks,
+ const double,
+ const int max_iterations)
{
- float scale = ComputeScale();
- bool solved = false;
- //double dt = analyze_time();
+ float scale = ComputeScale();
+ bool solved = false;
+ //double dt = analyze_time();
- Scale(scale, tasks);
+ Scale(scale, tasks);
- ConstrainPoleVector(root, tasks);
+ ConstrainPoleVector(root, tasks);
- root->UpdateTransform(m_rootmatrix);
+ root->UpdateTransform(m_rootmatrix);
- // iterate
- for (int iterations = 0; iterations < max_iterations; iterations++) {
- // update transform
- root->UpdateTransform(m_rootmatrix);
+ // iterate
+ for (int iterations = 0; iterations < max_iterations; iterations++) {
+ // update transform
+ root->UpdateTransform(m_rootmatrix);
- std::list<IK_QTask *>::iterator task;
+ std::list<IK_QTask *>::iterator task;
- // compute jacobian
- for (task = tasks.begin(); task != tasks.end(); task++) {
- if ((*task)->Primary())
- (*task)->ComputeJacobian(m_jacobian);
- else
- (*task)->ComputeJacobian(m_jacobian_sub);
- }
+ // compute jacobian
+ for (task = tasks.begin(); task != tasks.end(); task++) {
+ if ((*task)->Primary())
+ (*task)->ComputeJacobian(m_jacobian);
+ else
+ (*task)->ComputeJacobian(m_jacobian_sub);
+ }
- double norm = 0.0;
+ double norm = 0.0;
- do {
- // invert jacobian
- try {
- m_jacobian.Invert();
- if (m_secondary_enabled)
- m_jacobian.SubTask(m_jacobian_sub);
- }
- catch (...) {
- fprintf(stderr, "IK Exception\n");
- return false;
- }
+ do {
+ // invert jacobian
+ try {
+ m_jacobian.Invert();
+ if (m_secondary_enabled)
+ m_jacobian.SubTask(m_jacobian_sub);
+ }
+ catch (...) {
+ fprintf(stderr, "IK Exception\n");
+ return false;
+ }
- // update angles and check limits
- } while (UpdateAngles(norm));
+ // update angles and check limits
+ } while (UpdateAngles(norm));
- // unlock segments again after locking in clamping loop
- std::vector<IK_QSegment *>::iterator seg;
- for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
- (*seg)->UnLock();
+ // unlock segments again after locking in clamping loop
+ std::vector<IK_QSegment *>::iterator seg;
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+ (*seg)->UnLock();
- // compute angle update norm
- double maxnorm = m_jacobian.AngleUpdateNorm();
- if (maxnorm > norm)
- norm = maxnorm;
+ // compute angle update norm
+ double maxnorm = m_jacobian.AngleUpdateNorm();
+ if (maxnorm > norm)
+ norm = maxnorm;
- // check for convergence
- if (norm < 1e-3 && iterations > 10) {
- solved = true;
- break;
- }
- }
+ // check for convergence
+ if (norm < 1e-3 && iterations > 10) {
+ solved = true;
+ break;
+ }
+ }
- if (m_poleconstraint)
- root->PrependBasis(m_rootmatrix.linear());
+ if (m_poleconstraint)
+ root->PrependBasis(m_rootmatrix.linear());
- Scale(1.0f / scale, tasks);
+ Scale(1.0f / scale, tasks);
- //analyze_add_run(max_iterations, analyze_time()-dt);
+ //analyze_add_run(max_iterations, analyze_time()-dt);
- return solved;
+ return solved;
}
-
diff --git a/intern/iksolver/intern/IK_QJacobianSolver.h b/intern/iksolver/intern/IK_QJacobianSolver.h
index 5434edf28b8..1ba3a1bebe1 100644
--- a/intern/iksolver/intern/IK_QJacobianSolver.h
+++ b/intern/iksolver/intern/IK_QJacobianSolver.h
@@ -36,52 +36,52 @@
#include "IK_QSegment.h"
#include "IK_QTask.h"
-class IK_QJacobianSolver
-{
-public:
- IK_QJacobianSolver();
- ~IK_QJacobianSolver() {}
-
- // setup pole vector constraint
- void SetPoleVectorConstraint(IK_QSegment *tip, Vector3d& goal,
- Vector3d& polegoal, float poleangle, bool getangle);
- float GetPoleAngle() { return m_poleangle; }
-
- // call setup once before solving, if it fails don't solve
- bool Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks);
-
- // returns true if converged, false if max number of iterations was used
- bool Solve(
- IK_QSegment *root,
- std::list<IK_QTask*> tasks,
- const double tolerance,
- const int max_iterations
- );
-
-private:
- void AddSegmentList(IK_QSegment *seg);
- bool UpdateAngles(double& norm);
- void ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks);
-
- double ComputeScale();
- void Scale(double scale, std::list<IK_QTask*>& tasks);
-
-private:
-
- IK_QJacobian m_jacobian;
- IK_QJacobian m_jacobian_sub;
-
- bool m_secondary_enabled;
-
- std::vector<IK_QSegment*> m_segments;
-
- Affine3d m_rootmatrix;
-
- bool m_poleconstraint;
- bool m_getpoleangle;
- Vector3d m_goal;
- Vector3d m_polegoal;
- float m_poleangle;
- IK_QSegment *m_poletip;
+class IK_QJacobianSolver {
+ public:
+ IK_QJacobianSolver();
+ ~IK_QJacobianSolver()
+ {
+ }
+
+ // setup pole vector constraint
+ void SetPoleVectorConstraint(
+ IK_QSegment *tip, Vector3d &goal, Vector3d &polegoal, float poleangle, bool getangle);
+ float GetPoleAngle()
+ {
+ return m_poleangle;
+ }
+
+ // call setup once before solving, if it fails don't solve
+ bool Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks);
+
+ // returns true if converged, false if max number of iterations was used
+ bool Solve(IK_QSegment *root,
+ std::list<IK_QTask *> tasks,
+ const double tolerance,
+ const int max_iterations);
+
+ private:
+ void AddSegmentList(IK_QSegment *seg);
+ bool UpdateAngles(double &norm);
+ void ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask *> &tasks);
+
+ double ComputeScale();
+ void Scale(double scale, std::list<IK_QTask *> &tasks);
+
+ private:
+ IK_QJacobian m_jacobian;
+ IK_QJacobian m_jacobian_sub;
+
+ bool m_secondary_enabled;
+
+ std::vector<IK_QSegment *> m_segments;
+
+ Affine3d m_rootmatrix;
+
+ bool m_poleconstraint;
+ bool m_getpoleangle;
+ Vector3d m_goal;
+ Vector3d m_polegoal;
+ float m_poleangle;
+ IK_QSegment *m_poletip;
};
-
diff --git a/intern/iksolver/intern/IK_QSegment.cpp b/intern/iksolver/intern/IK_QSegment.cpp
index 09bceee0600..89a1afaafbd 100644
--- a/intern/iksolver/intern/IK_QSegment.cpp
+++ b/intern/iksolver/intern/IK_QSegment.cpp
@@ -21,837 +21,848 @@
* \ingroup iksolver
*/
-
#include "IK_QSegment.h"
// IK_QSegment
IK_QSegment::IK_QSegment(int num_DoF, bool translational)
- : m_parent(NULL), m_child(NULL), m_sibling(NULL), m_composite(NULL),
- m_num_DoF(num_DoF), m_translational(translational)
+ : m_parent(NULL),
+ m_child(NULL),
+ m_sibling(NULL),
+ m_composite(NULL),
+ m_num_DoF(num_DoF),
+ m_translational(translational)
{
- m_locked[0] = m_locked[1] = m_locked[2] = false;
- m_weight[0] = m_weight[1] = m_weight[2] = 1.0;
+ m_locked[0] = m_locked[1] = m_locked[2] = false;
+ m_weight[0] = m_weight[1] = m_weight[2] = 1.0;
- m_max_extension = 0.0;
+ m_max_extension = 0.0;
- m_start = Vector3d(0, 0, 0);
- m_rest_basis.setIdentity();
- m_basis.setIdentity();
- m_translation = Vector3d(0, 0, 0);
+ m_start = Vector3d(0, 0, 0);
+ m_rest_basis.setIdentity();
+ m_basis.setIdentity();
+ m_translation = Vector3d(0, 0, 0);
- m_orig_basis = m_basis;
- m_orig_translation = m_translation;
+ m_orig_basis = m_basis;
+ m_orig_translation = m_translation;
}
void IK_QSegment::Reset()
{
- m_locked[0] = m_locked[1] = m_locked[2] = false;
+ m_locked[0] = m_locked[1] = m_locked[2] = false;
- m_basis = m_orig_basis;
- m_translation = m_orig_translation;
- SetBasis(m_basis);
+ m_basis = m_orig_basis;
+ m_translation = m_orig_translation;
+ SetBasis(m_basis);
- for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
- seg->Reset();
+ for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
+ seg->Reset();
}
-void IK_QSegment::SetTransform(
- const Vector3d& start,
- const Matrix3d& rest_basis,
- const Matrix3d& basis,
- const double length
- )
+void IK_QSegment::SetTransform(const Vector3d &start,
+ const Matrix3d &rest_basis,
+ const Matrix3d &basis,
+ const double length)
{
- m_max_extension = start.norm() + length;
+ m_max_extension = start.norm() + length;
- m_start = start;
- m_rest_basis = rest_basis;
+ m_start = start;
+ m_rest_basis = rest_basis;
- m_orig_basis = basis;
- SetBasis(basis);
+ m_orig_basis = basis;
+ SetBasis(basis);
- m_translation = Vector3d(0, length, 0);
- m_orig_translation = m_translation;
+ m_translation = Vector3d(0, length, 0);
+ m_orig_translation = m_translation;
}
Matrix3d IK_QSegment::BasisChange() const
{
- return m_orig_basis.transpose() * m_basis;
+ return m_orig_basis.transpose() * m_basis;
}
Vector3d IK_QSegment::TranslationChange() const
{
- return m_translation - m_orig_translation;
+ return m_translation - m_orig_translation;
}
IK_QSegment::~IK_QSegment()
{
- if (m_parent)
- m_parent->RemoveChild(this);
+ if (m_parent)
+ m_parent->RemoveChild(this);
- for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
- seg->m_parent = NULL;
+ for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
+ seg->m_parent = NULL;
}
void IK_QSegment::SetParent(IK_QSegment *parent)
{
- if (m_parent == parent)
- return;
-
- if (m_parent)
- m_parent->RemoveChild(this);
-
- if (parent) {
- m_sibling = parent->m_child;
- parent->m_child = this;
- }
+ if (m_parent == parent)
+ return;
+
+ if (m_parent)
+ m_parent->RemoveChild(this);
- m_parent = parent;
+ if (parent) {
+ m_sibling = parent->m_child;
+ parent->m_child = this;
+ }
+
+ m_parent = parent;
}
void IK_QSegment::SetComposite(IK_QSegment *seg)
{
- m_composite = seg;
+ m_composite = seg;
}
void IK_QSegment::RemoveChild(IK_QSegment *child)
{
- if (m_child == NULL)
- return;
- else if (m_child == child)
- m_child = m_child->m_sibling;
- else {
- IK_QSegment *seg = m_child;
+ if (m_child == NULL)
+ return;
+ else if (m_child == child)
+ m_child = m_child->m_sibling;
+ else {
+ IK_QSegment *seg = m_child;
- while (seg->m_sibling != child)
- seg = seg->m_sibling;
+ while (seg->m_sibling != child)
+ seg = seg->m_sibling;
- if (child == seg->m_sibling)
- seg->m_sibling = child->m_sibling;
- }
+ if (child == seg->m_sibling)
+ seg->m_sibling = child->m_sibling;
+ }
}
-void IK_QSegment::UpdateTransform(const Affine3d& global)
+void IK_QSegment::UpdateTransform(const Affine3d &global)
{
- // compute the global transform at the end of the segment
- m_global_start = global.translation() + global.linear() * m_start;
+ // compute the global transform at the end of the segment
+ m_global_start = global.translation() + global.linear() * m_start;
- m_global_transform.translation() = m_global_start;
- m_global_transform.linear() = global.linear() * m_rest_basis * m_basis;
- m_global_transform.translate(m_translation);
+ m_global_transform.translation() = m_global_start;
+ m_global_transform.linear() = global.linear() * m_rest_basis * m_basis;
+ m_global_transform.translate(m_translation);
- // update child transforms
- for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
- seg->UpdateTransform(m_global_transform);
+ // update child transforms
+ for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
+ seg->UpdateTransform(m_global_transform);
}
-void IK_QSegment::PrependBasis(const Matrix3d& mat)
+void IK_QSegment::PrependBasis(const Matrix3d &mat)
{
- m_basis = m_rest_basis.inverse() * mat * m_rest_basis * m_basis;
+ m_basis = m_rest_basis.inverse() * mat * m_rest_basis * m_basis;
}
void IK_QSegment::Scale(double scale)
{
- m_start *= scale;
- m_translation *= scale;
- m_orig_translation *= scale;
- m_global_start *= scale;
- m_global_transform.translation() *= scale;
- m_max_extension *= scale;
+ m_start *= scale;
+ m_translation *= scale;
+ m_orig_translation *= scale;
+ m_global_start *= scale;
+ m_global_transform.translation() *= scale;
+ m_max_extension *= scale;
}
// IK_QSphericalSegment
IK_QSphericalSegment::IK_QSphericalSegment()
- : IK_QSegment(3, false), m_limit_x(false), m_limit_y(false), m_limit_z(false)
+ : IK_QSegment(3, false), m_limit_x(false), m_limit_y(false), m_limit_z(false)
{
}
Vector3d IK_QSphericalSegment::Axis(int dof) const
{
- return m_global_transform.linear().col(dof);
+ return m_global_transform.linear().col(dof);
}
void IK_QSphericalSegment::SetLimit(int axis, double lmin, double lmax)
{
- if (lmin > lmax)
- return;
-
- if (axis == 1) {
- lmin = Clamp(lmin, -M_PI, M_PI);
- lmax = Clamp(lmax, -M_PI, M_PI);
-
- m_min_y = lmin;
- m_max_y = lmax;
-
- m_limit_y = true;
- }
- else {
- // clamp and convert to axis angle parameters
- lmin = Clamp(lmin, -M_PI, M_PI);
- lmax = Clamp(lmax, -M_PI, M_PI);
-
- lmin = sin(lmin * 0.5);
- lmax = sin(lmax * 0.5);
-
- if (axis == 0) {
- m_min[0] = -lmax;
- m_max[0] = -lmin;
- m_limit_x = true;
- }
- else if (axis == 2) {
- m_min[1] = -lmax;
- m_max[1] = -lmin;
- m_limit_z = true;
- }
- }
+ if (lmin > lmax)
+ return;
+
+ if (axis == 1) {
+ lmin = Clamp(lmin, -M_PI, M_PI);
+ lmax = Clamp(lmax, -M_PI, M_PI);
+
+ m_min_y = lmin;
+ m_max_y = lmax;
+
+ m_limit_y = true;
+ }
+ else {
+ // clamp and convert to axis angle parameters
+ lmin = Clamp(lmin, -M_PI, M_PI);
+ lmax = Clamp(lmax, -M_PI, M_PI);
+
+ lmin = sin(lmin * 0.5);
+ lmax = sin(lmax * 0.5);
+
+ if (axis == 0) {
+ m_min[0] = -lmax;
+ m_max[0] = -lmin;
+ m_limit_x = true;
+ }
+ else if (axis == 2) {
+ m_min[1] = -lmax;
+ m_max[1] = -lmin;
+ m_limit_z = true;
+ }
+ }
}
void IK_QSphericalSegment::SetWeight(int axis, double weight)
{
- m_weight[axis] = weight;
-}
-
-bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp)
-{
- if (m_locked[0] && m_locked[1] && m_locked[2])
- return false;
-
- Vector3d dq;
- dq.x() = jacobian.AngleUpdate(m_DoF_id);
- dq.y() = jacobian.AngleUpdate(m_DoF_id + 1);
- dq.z() = jacobian.AngleUpdate(m_DoF_id + 2);
-
- // Directly update the rotation matrix, with Rodrigues' rotation formula,
- // to avoid singularities and allow smooth integration.
-
- double theta = dq.norm();
-
- if (!FuzzyZero(theta)) {
- Vector3d w = dq * (1.0 / theta);
-
- double sine = sin(theta);
- double cosine = cos(theta);
- double cosineInv = 1 - cosine;
-
- double xsine = w.x() * sine;
- double ysine = w.y() * sine;
- double zsine = w.z() * sine;
-
- double xxcosine = w.x() * w.x() * cosineInv;
- double xycosine = w.x() * w.y() * cosineInv;
- double xzcosine = w.x() * w.z() * cosineInv;
- double yycosine = w.y() * w.y() * cosineInv;
- double yzcosine = w.y() * w.z() * cosineInv;
- double zzcosine = w.z() * w.z() * cosineInv;
-
- Matrix3d M = CreateMatrix(
- cosine + xxcosine, -zsine + xycosine, ysine + xzcosine,
- zsine + xycosine, cosine + yycosine, -xsine + yzcosine,
- -ysine + xzcosine, xsine + yzcosine, cosine + zzcosine);
-
- m_new_basis = m_basis * M;
- }
- else
- m_new_basis = m_basis;
-
-
- if (m_limit_y == false && m_limit_x == false && m_limit_z == false)
- return false;
-
- Vector3d a = SphericalRangeParameters(m_new_basis);
-
- if (m_locked[0])
- a.x() = m_locked_ax;
- if (m_locked[1])
- a.y() = m_locked_ay;
- if (m_locked[2])
- a.z() = m_locked_az;
-
- double ax = a.x(), ay = a.y(), az = a.z();
-
- clamp[0] = clamp[1] = clamp[2] = false;
-
- if (m_limit_y) {
- if (a.y() > m_max_y) {
- ay = m_max_y;
- clamp[1] = true;
- }
- else if (a.y() < m_min_y) {
- ay = m_min_y;
- clamp[1] = true;
- }
- }
-
- if (m_limit_x && m_limit_z) {
- if (EllipseClamp(ax, az, m_min, m_max))
- clamp[0] = clamp[2] = true;
- }
- else if (m_limit_x) {
- if (ax < m_min[0]) {
- ax = m_min[0];
- clamp[0] = true;
- }
- else if (ax > m_max[0]) {
- ax = m_max[0];
- clamp[0] = true;
- }
- }
- else if (m_limit_z) {
- if (az < m_min[1]) {
- az = m_min[1];
- clamp[2] = true;
- }
- else if (az > m_max[1]) {
- az = m_max[1];
- clamp[2] = true;
- }
- }
-
- if (clamp[0] == false && clamp[1] == false && clamp[2] == false) {
- if (m_locked[0] || m_locked[1] || m_locked[2])
- m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
- return false;
- }
-
- m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
-
- delta = MatrixToAxisAngle(m_basis.transpose() * m_new_basis);
-
- if (!(m_locked[0] || m_locked[2]) && (clamp[0] || clamp[2])) {
- m_locked_ax = ax;
- m_locked_az = az;
- }
-
- if (!m_locked[1] && clamp[1])
- m_locked_ay = ay;
-
- return true;
-}
-
-void IK_QSphericalSegment::Lock(int dof, IK_QJacobian& jacobian, Vector3d& delta)
-{
- if (dof == 1) {
- m_locked[1] = true;
- jacobian.Lock(m_DoF_id + 1, delta[1]);
- }
- else {
- m_locked[0] = m_locked[2] = true;
- jacobian.Lock(m_DoF_id, delta[0]);
- jacobian.Lock(m_DoF_id + 2, delta[2]);
- }
+ m_weight[axis] = weight;
+}
+
+bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
+{
+ if (m_locked[0] && m_locked[1] && m_locked[2])
+ return false;
+
+ Vector3d dq;
+ dq.x() = jacobian.AngleUpdate(m_DoF_id);
+ dq.y() = jacobian.AngleUpdate(m_DoF_id + 1);
+ dq.z() = jacobian.AngleUpdate(m_DoF_id + 2);
+
+ // Directly update the rotation matrix, with Rodrigues' rotation formula,
+ // to avoid singularities and allow smooth integration.
+
+ double theta = dq.norm();
+
+ if (!FuzzyZero(theta)) {
+ Vector3d w = dq * (1.0 / theta);
+
+ double sine = sin(theta);
+ double cosine = cos(theta);
+ double cosineInv = 1 - cosine;
+
+ double xsine = w.x() * sine;
+ double ysine = w.y() * sine;
+ double zsine = w.z() * sine;
+
+ double xxcosine = w.x() * w.x() * cosineInv;
+ double xycosine = w.x() * w.y() * cosineInv;
+ double xzcosine = w.x() * w.z() * cosineInv;
+ double yycosine = w.y() * w.y() * cosineInv;
+ double yzcosine = w.y() * w.z() * cosineInv;
+ double zzcosine = w.z() * w.z() * cosineInv;
+
+ Matrix3d M = CreateMatrix(cosine + xxcosine,
+ -zsine + xycosine,
+ ysine + xzcosine,
+ zsine + xycosine,
+ cosine + yycosine,
+ -xsine + yzcosine,
+ -ysine + xzcosine,
+ xsine + yzcosine,
+ cosine + zzcosine);
+
+ m_new_basis = m_basis * M;
+ }
+ else
+ m_new_basis = m_basis;
+
+ if (m_limit_y == false && m_limit_x == false && m_limit_z == false)
+ return false;
+
+ Vector3d a = SphericalRangeParameters(m_new_basis);
+
+ if (m_locked[0])
+ a.x() = m_locked_ax;
+ if (m_locked[1])
+ a.y() = m_locked_ay;
+ if (m_locked[2])
+ a.z() = m_locked_az;
+
+ double ax = a.x(), ay = a.y(), az = a.z();
+
+ clamp[0] = clamp[1] = clamp[2] = false;
+
+ if (m_limit_y) {
+ if (a.y() > m_max_y) {
+ ay = m_max_y;
+ clamp[1] = true;
+ }
+ else if (a.y() < m_min_y) {
+ ay = m_min_y;
+ clamp[1] = true;
+ }
+ }
+
+ if (m_limit_x && m_limit_z) {
+ if (EllipseClamp(ax, az, m_min, m_max))
+ clamp[0] = clamp[2] = true;
+ }
+ else if (m_limit_x) {
+ if (ax < m_min[0]) {
+ ax = m_min[0];
+ clamp[0] = true;
+ }
+ else if (ax > m_max[0]) {
+ ax = m_max[0];
+ clamp[0] = true;
+ }
+ }
+ else if (m_limit_z) {
+ if (az < m_min[1]) {
+ az = m_min[1];
+ clamp[2] = true;
+ }
+ else if (az > m_max[1]) {
+ az = m_max[1];
+ clamp[2] = true;
+ }
+ }
+
+ if (clamp[0] == false && clamp[1] == false && clamp[2] == false) {
+ if (m_locked[0] || m_locked[1] || m_locked[2])
+ m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
+ return false;
+ }
+
+ m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
+
+ delta = MatrixToAxisAngle(m_basis.transpose() * m_new_basis);
+
+ if (!(m_locked[0] || m_locked[2]) && (clamp[0] || clamp[2])) {
+ m_locked_ax = ax;
+ m_locked_az = az;
+ }
+
+ if (!m_locked[1] && clamp[1])
+ m_locked_ay = ay;
+
+ return true;
+}
+
+void IK_QSphericalSegment::Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta)
+{
+ if (dof == 1) {
+ m_locked[1] = true;
+ jacobian.Lock(m_DoF_id + 1, delta[1]);
+ }
+ else {
+ m_locked[0] = m_locked[2] = true;
+ jacobian.Lock(m_DoF_id, delta[0]);
+ jacobian.Lock(m_DoF_id + 2, delta[2]);
+ }
}
void IK_QSphericalSegment::UpdateAngleApply()
{
- m_basis = m_new_basis;
+ m_basis = m_new_basis;
}
// IK_QNullSegment
-IK_QNullSegment::IK_QNullSegment()
- : IK_QSegment(0, false)
+IK_QNullSegment::IK_QNullSegment() : IK_QSegment(0, false)
{
}
// IK_QRevoluteSegment
IK_QRevoluteSegment::IK_QRevoluteSegment(int axis)
- : IK_QSegment(1, false), m_axis(axis), m_angle(0.0), m_limit(false)
+ : IK_QSegment(1, false), m_axis(axis), m_angle(0.0), m_limit(false)
{
}
-void IK_QRevoluteSegment::SetBasis(const Matrix3d& basis)
+void IK_QRevoluteSegment::SetBasis(const Matrix3d &basis)
{
- if (m_axis == 1) {
- m_angle = ComputeTwist(basis);
- m_basis = ComputeTwistMatrix(m_angle);
- }
- else {
- m_angle = EulerAngleFromMatrix(basis, m_axis);
- m_basis = RotationMatrix(m_angle, m_axis);
- }
+ if (m_axis == 1) {
+ m_angle = ComputeTwist(basis);
+ m_basis = ComputeTwistMatrix(m_angle);
+ }
+ else {
+ m_angle = EulerAngleFromMatrix(basis, m_axis);
+ m_basis = RotationMatrix(m_angle, m_axis);
+ }
}
Vector3d IK_QRevoluteSegment::Axis(int) const
{
- return m_global_transform.linear().col(m_axis);
+ return m_global_transform.linear().col(m_axis);
}
-bool IK_QRevoluteSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp)
+bool IK_QRevoluteSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
{
- if (m_locked[0])
- return false;
+ if (m_locked[0])
+ return false;
+
+ m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);
- m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);
+ clamp[0] = false;
- clamp[0] = false;
+ if (m_limit == false)
+ return false;
- if (m_limit == false)
- return false;
+ if (m_new_angle > m_max)
+ delta[0] = m_max - m_angle;
+ else if (m_new_angle < m_min)
+ delta[0] = m_min - m_angle;
+ else
+ return false;
- if (m_new_angle > m_max)
- delta[0] = m_max - m_angle;
- else if (m_new_angle < m_min)
- delta[0] = m_min - m_angle;
- else
- return false;
-
- clamp[0] = true;
- m_new_angle = m_angle + delta[0];
+ clamp[0] = true;
+ m_new_angle = m_angle + delta[0];
- return true;
+ return true;
}
-void IK_QRevoluteSegment::Lock(int, IK_QJacobian& jacobian, Vector3d& delta)
+void IK_QRevoluteSegment::Lock(int, IK_QJacobian &jacobian, Vector3d &delta)
{
- m_locked[0] = true;
- jacobian.Lock(m_DoF_id, delta[0]);
+ m_locked[0] = true;
+ jacobian.Lock(m_DoF_id, delta[0]);
}
void IK_QRevoluteSegment::UpdateAngleApply()
{
- m_angle = m_new_angle;
- m_basis = RotationMatrix(m_angle, m_axis);
+ m_angle = m_new_angle;
+ m_basis = RotationMatrix(m_angle, m_axis);
}
void IK_QRevoluteSegment::SetLimit(int axis, double lmin, double lmax)
{
- if (lmin > lmax || m_axis != axis)
- return;
-
- // clamp and convert to axis angle parameters
- lmin = Clamp(lmin, -M_PI, M_PI);
- lmax = Clamp(lmax, -M_PI, M_PI);
+ if (lmin > lmax || m_axis != axis)
+ return;
+
+ // clamp and convert to axis angle parameters
+ lmin = Clamp(lmin, -M_PI, M_PI);
+ lmax = Clamp(lmax, -M_PI, M_PI);
- m_min = lmin;
- m_max = lmax;
+ m_min = lmin;
+ m_max = lmax;
- m_limit = true;
+ m_limit = true;
}
void IK_QRevoluteSegment::SetWeight(int axis, double weight)
{
- if (axis == m_axis)
- m_weight[0] = weight;
+ if (axis == m_axis)
+ m_weight[0] = weight;
}
// IK_QSwingSegment
-IK_QSwingSegment::IK_QSwingSegment()
- : IK_QSegment(2, false), m_limit_x(false), m_limit_z(false)
+IK_QSwingSegment::IK_QSwingSegment() : IK_QSegment(2, false), m_limit_x(false), m_limit_z(false)
{
}
-void IK_QSwingSegment::SetBasis(const Matrix3d& basis)
+void IK_QSwingSegment::SetBasis(const Matrix3d &basis)
{
- m_basis = basis;
- RemoveTwist(m_basis);
+ m_basis = basis;
+ RemoveTwist(m_basis);
}
Vector3d IK_QSwingSegment::Axis(int dof) const
{
- return m_global_transform.linear().col((dof == 0) ? 0 : 2);
+ return m_global_transform.linear().col((dof == 0) ? 0 : 2);
}
-bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp)
+bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
{
- if (m_locked[0] && m_locked[1])
- return false;
+ if (m_locked[0] && m_locked[1])
+ return false;
- Vector3d dq;
- dq.x() = jacobian.AngleUpdate(m_DoF_id);
- dq.y() = 0.0;
- dq.z() = jacobian.AngleUpdate(m_DoF_id + 1);
+ Vector3d dq;
+ dq.x() = jacobian.AngleUpdate(m_DoF_id);
+ dq.y() = 0.0;
+ dq.z() = jacobian.AngleUpdate(m_DoF_id + 1);
- // Directly update the rotation matrix, with Rodrigues' rotation formula,
- // to avoid singularities and allow smooth integration.
+ // Directly update the rotation matrix, with Rodrigues' rotation formula,
+ // to avoid singularities and allow smooth integration.
- double theta = dq.norm();
+ double theta = dq.norm();
- if (!FuzzyZero(theta)) {
- Vector3d w = dq * (1.0 / theta);
+ if (!FuzzyZero(theta)) {
+ Vector3d w = dq * (1.0 / theta);
- double sine = sin(theta);
- double cosine = cos(theta);
- double cosineInv = 1 - cosine;
+ double sine = sin(theta);
+ double cosine = cos(theta);
+ double cosineInv = 1 - cosine;
- double xsine = w.x() * sine;
- double zsine = w.z() * sine;
+ double xsine = w.x() * sine;
+ double zsine = w.z() * sine;
- double xxcosine = w.x() * w.x() * cosineInv;
- double xzcosine = w.x() * w.z() * cosineInv;
- double zzcosine = w.z() * w.z() * cosineInv;
+ double xxcosine = w.x() * w.x() * cosineInv;
+ double xzcosine = w.x() * w.z() * cosineInv;
+ double zzcosine = w.z() * w.z() * cosineInv;
- Matrix3d M = CreateMatrix(
- cosine + xxcosine, -zsine, xzcosine,
- zsine, cosine, -xsine,
- xzcosine, xsine, cosine + zzcosine);
+ Matrix3d M = CreateMatrix(cosine + xxcosine,
+ -zsine,
+ xzcosine,
+ zsine,
+ cosine,
+ -xsine,
+ xzcosine,
+ xsine,
+ cosine + zzcosine);
- m_new_basis = m_basis * M;
+ m_new_basis = m_basis * M;
- RemoveTwist(m_new_basis);
- }
- else
- m_new_basis = m_basis;
+ RemoveTwist(m_new_basis);
+ }
+ else
+ m_new_basis = m_basis;
- if (m_limit_x == false && m_limit_z == false)
- return false;
+ if (m_limit_x == false && m_limit_z == false)
+ return false;
- Vector3d a = SphericalRangeParameters(m_new_basis);
- double ax = 0, az = 0;
+ Vector3d a = SphericalRangeParameters(m_new_basis);
+ double ax = 0, az = 0;
- clamp[0] = clamp[1] = false;
-
- if (m_limit_x && m_limit_z) {
- ax = a.x();
- az = a.z();
+ clamp[0] = clamp[1] = false;
- if (EllipseClamp(ax, az, m_min, m_max))
- clamp[0] = clamp[1] = true;
- }
- else if (m_limit_x) {
- if (ax < m_min[0]) {
- ax = m_min[0];
- clamp[0] = true;
- }
- else if (ax > m_max[0]) {
- ax = m_max[0];
- clamp[0] = true;
- }
- }
- else if (m_limit_z) {
- if (az < m_min[1]) {
- az = m_min[1];
- clamp[1] = true;
- }
- else if (az > m_max[1]) {
- az = m_max[1];
- clamp[1] = true;
- }
- }
+ if (m_limit_x && m_limit_z) {
+ ax = a.x();
+ az = a.z();
- if (clamp[0] == false && clamp[1] == false)
- return false;
+ if (EllipseClamp(ax, az, m_min, m_max))
+ clamp[0] = clamp[1] = true;
+ }
+ else if (m_limit_x) {
+ if (ax < m_min[0]) {
+ ax = m_min[0];
+ clamp[0] = true;
+ }
+ else if (ax > m_max[0]) {
+ ax = m_max[0];
+ clamp[0] = true;
+ }
+ }
+ else if (m_limit_z) {
+ if (az < m_min[1]) {
+ az = m_min[1];
+ clamp[1] = true;
+ }
+ else if (az > m_max[1]) {
+ az = m_max[1];
+ clamp[1] = true;
+ }
+ }
- m_new_basis = ComputeSwingMatrix(ax, az);
+ if (clamp[0] == false && clamp[1] == false)
+ return false;
- delta = MatrixToAxisAngle(m_basis.transpose() * m_new_basis);
- delta[1] = delta[2]; delta[2] = 0.0;
+ m_new_basis = ComputeSwingMatrix(ax, az);
- return true;
+ delta = MatrixToAxisAngle(m_basis.transpose() * m_new_basis);
+ delta[1] = delta[2];
+ delta[2] = 0.0;
+
+ return true;
}
-void IK_QSwingSegment::Lock(int, IK_QJacobian& jacobian, Vector3d& delta)
+void IK_QSwingSegment::Lock(int, IK_QJacobian &jacobian, Vector3d &delta)
{
- m_locked[0] = m_locked[1] = true;
- jacobian.Lock(m_DoF_id, delta[0]);
- jacobian.Lock(m_DoF_id + 1, delta[1]);
+ m_locked[0] = m_locked[1] = true;
+ jacobian.Lock(m_DoF_id, delta[0]);
+ jacobian.Lock(m_DoF_id + 1, delta[1]);
}
void IK_QSwingSegment::UpdateAngleApply()
{
- m_basis = m_new_basis;
+ m_basis = m_new_basis;
}
void IK_QSwingSegment::SetLimit(int axis, double lmin, double lmax)
{
- if (lmin > lmax)
- return;
-
- // clamp and convert to axis angle parameters
- lmin = Clamp(lmin, -M_PI, M_PI);
- lmax = Clamp(lmax, -M_PI, M_PI);
+ if (lmin > lmax)
+ return;
+
+ // clamp and convert to axis angle parameters
+ lmin = Clamp(lmin, -M_PI, M_PI);
+ lmax = Clamp(lmax, -M_PI, M_PI);
- lmin = sin(lmin * 0.5);
- lmax = sin(lmax * 0.5);
+ lmin = sin(lmin * 0.5);
+ lmax = sin(lmax * 0.5);
- // put center of ellispe in the middle between min and max
- double offset = 0.5 * (lmin + lmax);
- //lmax = lmax - offset;
+ // put center of ellispe in the middle between min and max
+ double offset = 0.5 * (lmin + lmax);
+ //lmax = lmax - offset;
- if (axis == 0) {
- m_min[0] = -lmax;
- m_max[0] = -lmin;
+ if (axis == 0) {
+ m_min[0] = -lmax;
+ m_max[0] = -lmin;
- m_limit_x = true;
- m_offset_x = offset;
- m_max_x = lmax;
- }
- else if (axis == 2) {
- m_min[1] = -lmax;
- m_max[1] = -lmin;
+ m_limit_x = true;
+ m_offset_x = offset;
+ m_max_x = lmax;
+ }
+ else if (axis == 2) {
+ m_min[1] = -lmax;
+ m_max[1] = -lmin;
- m_limit_z = true;
- m_offset_z = offset;
- m_max_z = lmax;
- }
+ m_limit_z = true;
+ m_offset_z = offset;
+ m_max_z = lmax;
+ }
}
void IK_QSwingSegment::SetWeight(int axis, double weight)
{
- if (axis == 0)
- m_weight[0] = weight;
- else if (axis == 2)
- m_weight[1] = weight;
+ if (axis == 0)
+ m_weight[0] = weight;
+ else if (axis == 2)
+ m_weight[1] = weight;
}
// IK_QElbowSegment
IK_QElbowSegment::IK_QElbowSegment(int axis)
- : IK_QSegment(2, false), m_axis(axis), m_twist(0.0), m_angle(0.0),
- m_cos_twist(1.0), m_sin_twist(0.0), m_limit(false), m_limit_twist(false)
+ : IK_QSegment(2, false),
+ m_axis(axis),
+ m_twist(0.0),
+ m_angle(0.0),
+ m_cos_twist(1.0),
+ m_sin_twist(0.0),
+ m_limit(false),
+ m_limit_twist(false)
{
}
-void IK_QElbowSegment::SetBasis(const Matrix3d& basis)
+void IK_QElbowSegment::SetBasis(const Matrix3d &basis)
{
- m_basis = basis;
+ m_basis = basis;
- m_twist = ComputeTwist(m_basis);
- RemoveTwist(m_basis);
- m_angle = EulerAngleFromMatrix(basis, m_axis);
+ m_twist = ComputeTwist(m_basis);
+ RemoveTwist(m_basis);
+ m_angle = EulerAngleFromMatrix(basis, m_axis);
- m_basis = RotationMatrix(m_angle, m_axis) * ComputeTwistMatrix(m_twist);
+ m_basis = RotationMatrix(m_angle, m_axis) * ComputeTwistMatrix(m_twist);
}
Vector3d IK_QElbowSegment::Axis(int dof) const
{
- if (dof == 0) {
- Vector3d v;
- if (m_axis == 0)
- v = Vector3d(m_cos_twist, 0, m_sin_twist);
- else
- v = Vector3d(-m_sin_twist, 0, m_cos_twist);
-
- return m_global_transform.linear() * v;
- }
- else
- return m_global_transform.linear().col(1);
-}
-
-bool IK_QElbowSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp)
-{
- if (m_locked[0] && m_locked[1])
- return false;
-
- clamp[0] = clamp[1] = false;
-
- if (!m_locked[0]) {
- m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);
-
- if (m_limit) {
- if (m_new_angle > m_max) {
- delta[0] = m_max - m_angle;
- m_new_angle = m_max;
- clamp[0] = true;
- }
- else if (m_new_angle < m_min) {
- delta[0] = m_min - m_angle;
- m_new_angle = m_min;
- clamp[0] = true;
- }
- }
- }
-
- if (!m_locked[1]) {
- m_new_twist = m_twist + jacobian.AngleUpdate(m_DoF_id + 1);
-
- if (m_limit_twist) {
- if (m_new_twist > m_max_twist) {
- delta[1] = m_max_twist - m_twist;
- m_new_twist = m_max_twist;
- clamp[1] = true;
- }
- else if (m_new_twist < m_min_twist) {
- delta[1] = m_min_twist - m_twist;
- m_new_twist = m_min_twist;
- clamp[1] = true;
- }
- }
- }
-
- return (clamp[0] || clamp[1]);
-}
-
-void IK_QElbowSegment::Lock(int dof, IK_QJacobian& jacobian, Vector3d& delta)
-{
- if (dof == 0) {
- m_locked[0] = true;
- jacobian.Lock(m_DoF_id, delta[0]);
- }
- else {
- m_locked[1] = true;
- jacobian.Lock(m_DoF_id + 1, delta[1]);
- }
+ if (dof == 0) {
+ Vector3d v;
+ if (m_axis == 0)
+ v = Vector3d(m_cos_twist, 0, m_sin_twist);
+ else
+ v = Vector3d(-m_sin_twist, 0, m_cos_twist);
+
+ return m_global_transform.linear() * v;
+ }
+ else
+ return m_global_transform.linear().col(1);
+}
+
+bool IK_QElbowSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
+{
+ if (m_locked[0] && m_locked[1])
+ return false;
+
+ clamp[0] = clamp[1] = false;
+
+ if (!m_locked[0]) {
+ m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);
+
+ if (m_limit) {
+ if (m_new_angle > m_max) {
+ delta[0] = m_max - m_angle;
+ m_new_angle = m_max;
+ clamp[0] = true;
+ }
+ else if (m_new_angle < m_min) {
+ delta[0] = m_min - m_angle;
+ m_new_angle = m_min;
+ clamp[0] = true;
+ }
+ }
+ }
+
+ if (!m_locked[1]) {
+ m_new_twist = m_twist + jacobian.AngleUpdate(m_DoF_id + 1);
+
+ if (m_limit_twist) {
+ if (m_new_twist > m_max_twist) {
+ delta[1] = m_max_twist - m_twist;
+ m_new_twist = m_max_twist;
+ clamp[1] = true;
+ }
+ else if (m_new_twist < m_min_twist) {
+ delta[1] = m_min_twist - m_twist;
+ m_new_twist = m_min_twist;
+ clamp[1] = true;
+ }
+ }
+ }
+
+ return (clamp[0] || clamp[1]);
+}
+
+void IK_QElbowSegment::Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta)
+{
+ if (dof == 0) {
+ m_locked[0] = true;
+ jacobian.Lock(m_DoF_id, delta[0]);
+ }
+ else {
+ m_locked[1] = true;
+ jacobian.Lock(m_DoF_id + 1, delta[1]);
+ }
}
void IK_QElbowSegment::UpdateAngleApply()
{
- m_angle = m_new_angle;
- m_twist = m_new_twist;
+ m_angle = m_new_angle;
+ m_twist = m_new_twist;
- m_sin_twist = sin(m_twist);
- m_cos_twist = cos(m_twist);
+ m_sin_twist = sin(m_twist);
+ m_cos_twist = cos(m_twist);
- Matrix3d A = RotationMatrix(m_angle, m_axis);
- Matrix3d T = RotationMatrix(m_sin_twist, m_cos_twist, 1);
+ Matrix3d A = RotationMatrix(m_angle, m_axis);
+ Matrix3d T = RotationMatrix(m_sin_twist, m_cos_twist, 1);
- m_basis = A * T;
+ m_basis = A * T;
}
void IK_QElbowSegment::SetLimit(int axis, double lmin, double lmax)
{
- if (lmin > lmax)
- return;
+ if (lmin > lmax)
+ return;
- // clamp and convert to axis angle parameters
- lmin = Clamp(lmin, -M_PI, M_PI);
- lmax = Clamp(lmax, -M_PI, M_PI);
+ // clamp and convert to axis angle parameters
+ lmin = Clamp(lmin, -M_PI, M_PI);
+ lmax = Clamp(lmax, -M_PI, M_PI);
- if (axis == 1) {
- m_min_twist = lmin;
- m_max_twist = lmax;
- m_limit_twist = true;
- }
- else if (axis == m_axis) {
- m_min = lmin;
- m_max = lmax;
- m_limit = true;
- }
+ if (axis == 1) {
+ m_min_twist = lmin;
+ m_max_twist = lmax;
+ m_limit_twist = true;
+ }
+ else if (axis == m_axis) {
+ m_min = lmin;
+ m_max = lmax;
+ m_limit = true;
+ }
}
void IK_QElbowSegment::SetWeight(int axis, double weight)
{
- if (axis == m_axis)
- m_weight[0] = weight;
- else if (axis == 1)
- m_weight[1] = weight;
+ if (axis == m_axis)
+ m_weight[0] = weight;
+ else if (axis == 1)
+ m_weight[1] = weight;
}
// IK_QTranslateSegment
-IK_QTranslateSegment::IK_QTranslateSegment(int axis1)
- : IK_QSegment(1, true)
+IK_QTranslateSegment::IK_QTranslateSegment(int axis1) : IK_QSegment(1, true)
{
- m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false;
- m_axis_enabled[axis1] = true;
+ m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false;
+ m_axis_enabled[axis1] = true;
- m_axis[0] = axis1;
+ m_axis[0] = axis1;
- m_limit[0] = m_limit[1] = m_limit[2] = false;
+ m_limit[0] = m_limit[1] = m_limit[2] = false;
}
-IK_QTranslateSegment::IK_QTranslateSegment(int axis1, int axis2)
- : IK_QSegment(2, true)
+IK_QTranslateSegment::IK_QTranslateSegment(int axis1, int axis2) : IK_QSegment(2, true)
{
- m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false;
- m_axis_enabled[axis1] = true;
- m_axis_enabled[axis2] = true;
+ m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false;
+ m_axis_enabled[axis1] = true;
+ m_axis_enabled[axis2] = true;
- m_axis[0] = axis1;
- m_axis[1] = axis2;
+ m_axis[0] = axis1;
+ m_axis[1] = axis2;
- m_limit[0] = m_limit[1] = m_limit[2] = false;
+ m_limit[0] = m_limit[1] = m_limit[2] = false;
}
-IK_QTranslateSegment::IK_QTranslateSegment()
- : IK_QSegment(3, true)
+IK_QTranslateSegment::IK_QTranslateSegment() : IK_QSegment(3, true)
{
- m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = true;
+ m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = true;
- m_axis[0] = 0;
- m_axis[1] = 1;
- m_axis[2] = 2;
+ m_axis[0] = 0;
+ m_axis[1] = 1;
+ m_axis[2] = 2;
- m_limit[0] = m_limit[1] = m_limit[2] = false;
+ m_limit[0] = m_limit[1] = m_limit[2] = false;
}
Vector3d IK_QTranslateSegment::Axis(int dof) const
{
- return m_global_transform.linear().col(m_axis[dof]);
+ return m_global_transform.linear().col(m_axis[dof]);
}
-bool IK_QTranslateSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp)
+bool IK_QTranslateSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
{
- int dof_id = m_DoF_id, dof = 0, i, clamped = false;
+ int dof_id = m_DoF_id, dof = 0, i, clamped = false;
- Vector3d dx(0.0, 0.0, 0.0);
+ Vector3d dx(0.0, 0.0, 0.0);
- for (i = 0; i < 3; i++) {
- if (!m_axis_enabled[i]) {
- m_new_translation[i] = m_translation[i];
- continue;
- }
+ for (i = 0; i < 3; i++) {
+ if (!m_axis_enabled[i]) {
+ m_new_translation[i] = m_translation[i];
+ continue;
+ }
- clamp[dof] = false;
+ clamp[dof] = false;
- if (!m_locked[dof]) {
- m_new_translation[i] = m_translation[i] + jacobian.AngleUpdate(dof_id);
+ if (!m_locked[dof]) {
+ m_new_translation[i] = m_translation[i] + jacobian.AngleUpdate(dof_id);
- if (m_limit[i]) {
- if (m_new_translation[i] > m_max[i]) {
- delta[dof] = m_max[i] - m_translation[i];
- m_new_translation[i] = m_max[i];
- clamped = clamp[dof] = true;
- }
- else if (m_new_translation[i] < m_min[i]) {
- delta[dof] = m_min[i] - m_translation[i];
- m_new_translation[i] = m_min[i];
- clamped = clamp[dof] = true;
- }
- }
- }
+ if (m_limit[i]) {
+ if (m_new_translation[i] > m_max[i]) {
+ delta[dof] = m_max[i] - m_translation[i];
+ m_new_translation[i] = m_max[i];
+ clamped = clamp[dof] = true;
+ }
+ else if (m_new_translation[i] < m_min[i]) {
+ delta[dof] = m_min[i] - m_translation[i];
+ m_new_translation[i] = m_min[i];
+ clamped = clamp[dof] = true;
+ }
+ }
+ }
- dof_id++;
- dof++;
- }
+ dof_id++;
+ dof++;
+ }
- return clamped;
+ return clamped;
}
void IK_QTranslateSegment::UpdateAngleApply()
{
- m_translation = m_new_translation;
+ m_translation = m_new_translation;
}
-void IK_QTranslateSegment::Lock(int dof, IK_QJacobian& jacobian, Vector3d& delta)
+void IK_QTranslateSegment::Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta)
{
- m_locked[dof] = true;
- jacobian.Lock(m_DoF_id + dof, delta[dof]);
+ m_locked[dof] = true;
+ jacobian.Lock(m_DoF_id + dof, delta[dof]);
}
void IK_QTranslateSegment::SetWeight(int axis, double weight)
{
- int i;
+ int i;
- for (i = 0; i < m_num_DoF; i++)
- if (m_axis[i] == axis)
- m_weight[i] = weight;
+ for (i = 0; i < m_num_DoF; i++)
+ if (m_axis[i] == axis)
+ m_weight[i] = weight;
}
void IK_QTranslateSegment::SetLimit(int axis, double lmin, double lmax)
{
- if (lmax < lmin)
- return;
+ if (lmax < lmin)
+ return;
- m_min[axis] = lmin;
- m_max[axis] = lmax;
- m_limit[axis] = true;
+ m_min[axis] = lmin;
+ m_max[axis] = lmax;
+ m_limit[axis] = true;
}
void IK_QTranslateSegment::Scale(double scale)
{
- int i;
+ int i;
- IK_QSegment::Scale(scale);
+ IK_QSegment::Scale(scale);
- for (i = 0; i < 3; i++) {
- m_min[0] *= scale;
- m_max[1] *= scale;
- }
+ for (i = 0; i < 3; i++) {
+ m_min[0] *= scale;
+ m_max[1] *= scale;
+ }
- m_new_translation *= scale;
+ m_new_translation *= scale;
}
-
diff --git a/intern/iksolver/intern/IK_QSegment.h b/intern/iksolver/intern/IK_QSegment.h
index c4576c08145..47125db3865 100644
--- a/intern/iksolver/intern/IK_QSegment.h
+++ b/intern/iksolver/intern/IK_QSegment.h
@@ -49,289 +49,330 @@
* use exactly the same transformations when displaying the segments
*/
-class IK_QSegment
-{
-public:
- EIGEN_MAKE_ALIGNED_OPERATOR_NEW
- virtual ~IK_QSegment();
-
- // start: a user defined translation
- // rest_basis: a user defined rotation
- // basis: a user defined rotation
- // length: length of this segment
-
- void SetTransform(
- const Vector3d& start,
- const Matrix3d& rest_basis,
- const Matrix3d& basis,
- const double length
- );
-
- // tree structure access
- void SetParent(IK_QSegment *parent);
-
- IK_QSegment *Child() const
- { return m_child; }
-
- IK_QSegment *Sibling() const
- { return m_sibling; }
-
- IK_QSegment *Parent() const
- { return m_parent; }
-
- // for combining two joints into one from the interface
- void SetComposite(IK_QSegment *seg);
-
- IK_QSegment *Composite() const
- { return m_composite; }
-
- // number of degrees of freedom
- int NumberOfDoF() const
- { return m_num_DoF; }
-
- // unique id for this segment, for identification in the jacobian
- int DoFId() const
- { return m_DoF_id; }
-
- void SetDoFId(int dof_id)
- { m_DoF_id = dof_id; }
-
- // the max distance of the end of this bone from the local origin.
- const double MaxExtension() const
- { return m_max_extension; }
-
- // the change in rotation and translation w.r.t. the rest pose
- Matrix3d BasisChange() const;
- Vector3d TranslationChange() const;
-
- // the start and end of the segment
- const Vector3d GlobalStart() const
- { return m_global_start; }
-
- const Vector3d GlobalEnd() const
- { return m_global_transform.translation(); }
-
- // the global transformation at the end of the segment
- const Affine3d &GlobalTransform() const
- { return m_global_transform; }
-
- // is a translational segment?
- bool Translational() const
- { return m_translational; }
-
- // locking (during inner clamping loop)
- bool Locked(int dof) const
- { return m_locked[dof]; }
-
- void UnLock()
- { m_locked[0] = m_locked[1] = m_locked[2] = false; }
-
- // per dof joint weighting
- double Weight(int dof) const
- { return m_weight[dof]; }
-
- void ScaleWeight(int dof, double scale)
- { m_weight[dof] *= scale; }
-
- // recursively update the global coordinates of this segment, 'global'
- // is the global transformation from the parent segment
- void UpdateTransform(const Affine3d &global);
-
- // get axis from rotation matrix for derivative computation
- virtual Vector3d Axis(int dof) const=0;
-
- // update the angles using the dTheta's computed using the jacobian matrix
- virtual bool UpdateAngle(const IK_QJacobian&, Vector3d&, bool*)=0;
- virtual void Lock(int, IK_QJacobian&, Vector3d&) {}
- virtual void UpdateAngleApply()=0;
-
- // set joint limits
- virtual void SetLimit(int, double, double) {}
-
- // set joint weights (per axis)
- virtual void SetWeight(int, double) {}
-
- virtual void SetBasis(const Matrix3d& basis) { m_basis = basis; }
-
- // functions needed for pole vector constraint
- void PrependBasis(const Matrix3d& mat);
- void Reset();
-
- // scale
- virtual void Scale(double scale);
-
-protected:
-
- // num_DoF: number of degrees of freedom
- IK_QSegment(int num_DoF, bool translational);
-
- // remove child as a child of this segment
- void RemoveChild(IK_QSegment *child);
-
- // tree structure variables
- IK_QSegment *m_parent;
- IK_QSegment *m_child;
- IK_QSegment *m_sibling;
- IK_QSegment *m_composite;
-
- // full transform =
- // start * rest_basis * basis * translation
- Vector3d m_start;
- Matrix3d m_rest_basis;
- Matrix3d m_basis;
- Vector3d m_translation;
-
- // original basis
- Matrix3d m_orig_basis;
- Vector3d m_orig_translation;
-
- // maximum extension of this segment
- double m_max_extension;
-
- // accumulated transformations starting from root
- Vector3d m_global_start;
- Affine3d m_global_transform;
-
- // number degrees of freedom, (first) id of this segments DOF's
- int m_num_DoF, m_DoF_id;
-
- bool m_locked[3];
- bool m_translational;
- double m_weight[3];
+class IK_QSegment {
+ public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+ virtual ~IK_QSegment();
+
+ // start: a user defined translation
+ // rest_basis: a user defined rotation
+ // basis: a user defined rotation
+ // length: length of this segment
+
+ void SetTransform(const Vector3d &start,
+ const Matrix3d &rest_basis,
+ const Matrix3d &basis,
+ const double length);
+
+ // tree structure access
+ void SetParent(IK_QSegment *parent);
+
+ IK_QSegment *Child() const
+ {
+ return m_child;
+ }
+
+ IK_QSegment *Sibling() const
+ {
+ return m_sibling;
+ }
+
+ IK_QSegment *Parent() const
+ {
+ return m_parent;
+ }
+
+ // for combining two joints into one from the interface
+ void SetComposite(IK_QSegment *seg);
+
+ IK_QSegment *Composite() const
+ {
+ return m_composite;
+ }
+
+ // number of degrees of freedom
+ int NumberOfDoF() const
+ {
+ return m_num_DoF;
+ }
+
+ // unique id for this segment, for identification in the jacobian
+ int DoFId() const
+ {
+ return m_DoF_id;
+ }
+
+ void SetDoFId(int dof_id)
+ {
+ m_DoF_id = dof_id;
+ }
+
+ // the max distance of the end of this bone from the local origin.
+ const double MaxExtension() const
+ {
+ return m_max_extension;
+ }
+
+ // the change in rotation and translation w.r.t. the rest pose
+ Matrix3d BasisChange() const;
+ Vector3d TranslationChange() const;
+
+ // the start and end of the segment
+ const Vector3d GlobalStart() const
+ {
+ return m_global_start;
+ }
+
+ const Vector3d GlobalEnd() const
+ {
+ return m_global_transform.translation();
+ }
+
+ // the global transformation at the end of the segment
+ const Affine3d &GlobalTransform() const
+ {
+ return m_global_transform;
+ }
+
+ // is a translational segment?
+ bool Translational() const
+ {
+ return m_translational;
+ }
+
+ // locking (during inner clamping loop)
+ bool Locked(int dof) const
+ {
+ return m_locked[dof];
+ }
+
+ void UnLock()
+ {
+ m_locked[0] = m_locked[1] = m_locked[2] = false;
+ }
+
+ // per dof joint weighting
+ double Weight(int dof) const
+ {
+ return m_weight[dof];
+ }
+
+ void ScaleWeight(int dof, double scale)
+ {
+ m_weight[dof] *= scale;
+ }
+
+ // recursively update the global coordinates of this segment, 'global'
+ // is the global transformation from the parent segment
+ void UpdateTransform(const Affine3d &global);
+
+ // get axis from rotation matrix for derivative computation
+ virtual Vector3d Axis(int dof) const = 0;
+
+ // update the angles using the dTheta's computed using the jacobian matrix
+ virtual bool UpdateAngle(const IK_QJacobian &, Vector3d &, bool *) = 0;
+ virtual void Lock(int, IK_QJacobian &, Vector3d &)
+ {
+ }
+ virtual void UpdateAngleApply() = 0;
+
+ // set joint limits
+ virtual void SetLimit(int, double, double)
+ {
+ }
+
+ // set joint weights (per axis)
+ virtual void SetWeight(int, double)
+ {
+ }
+
+ virtual void SetBasis(const Matrix3d &basis)
+ {
+ m_basis = basis;
+ }
+
+ // functions needed for pole vector constraint
+ void PrependBasis(const Matrix3d &mat);
+ void Reset();
+
+ // scale
+ virtual void Scale(double scale);
+
+ protected:
+ // num_DoF: number of degrees of freedom
+ IK_QSegment(int num_DoF, bool translational);
+
+ // remove child as a child of this segment
+ void RemoveChild(IK_QSegment *child);
+
+ // tree structure variables
+ IK_QSegment *m_parent;
+ IK_QSegment *m_child;
+ IK_QSegment *m_sibling;
+ IK_QSegment *m_composite;
+
+ // full transform =
+ // start * rest_basis * basis * translation
+ Vector3d m_start;
+ Matrix3d m_rest_basis;
+ Matrix3d m_basis;
+ Vector3d m_translation;
+
+ // original basis
+ Matrix3d m_orig_basis;
+ Vector3d m_orig_translation;
+
+ // maximum extension of this segment
+ double m_max_extension;
+
+ // accumulated transformations starting from root
+ Vector3d m_global_start;
+ Affine3d m_global_transform;
+
+ // number degrees of freedom, (first) id of this segments DOF's
+ int m_num_DoF, m_DoF_id;
+
+ bool m_locked[3];
+ bool m_translational;
+ double m_weight[3];
};
-class IK_QSphericalSegment : public IK_QSegment
-{
-public:
- IK_QSphericalSegment();
+class IK_QSphericalSegment : public IK_QSegment {
+ public:
+ IK_QSphericalSegment();
- Vector3d Axis(int dof) const;
+ Vector3d Axis(int dof) const;
- bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp);
- void Lock(int dof, IK_QJacobian& jacobian, Vector3d& delta);
- void UpdateAngleApply();
+ bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
+ void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
+ void UpdateAngleApply();
- bool ComputeClampRotation(Vector3d& clamp);
+ bool ComputeClampRotation(Vector3d &clamp);
- void SetLimit(int axis, double lmin, double lmax);
- void SetWeight(int axis, double weight);
+ void SetLimit(int axis, double lmin, double lmax);
+ void SetWeight(int axis, double weight);
-private:
- Matrix3d m_new_basis;
- bool m_limit_x, m_limit_y, m_limit_z;
- double m_min[2], m_max[2];
- double m_min_y, m_max_y, m_max_x, m_max_z, m_offset_x, m_offset_z;
- double m_locked_ax, m_locked_ay, m_locked_az;
+ private:
+ Matrix3d m_new_basis;
+ bool m_limit_x, m_limit_y, m_limit_z;
+ double m_min[2], m_max[2];
+ double m_min_y, m_max_y, m_max_x, m_max_z, m_offset_x, m_offset_z;
+ double m_locked_ax, m_locked_ay, m_locked_az;
};
-class IK_QNullSegment : public IK_QSegment
-{
-public:
- IK_QNullSegment();
-
- bool UpdateAngle(const IK_QJacobian&, Vector3d&, bool*) { return false; }
- void UpdateAngleApply() {}
-
- Vector3d Axis(int) const { return Vector3d(0, 0, 0); }
- void SetBasis(const Matrix3d&) { m_basis.setIdentity(); }
+class IK_QNullSegment : public IK_QSegment {
+ public:
+ IK_QNullSegment();
+
+ bool UpdateAngle(const IK_QJacobian &, Vector3d &, bool *)
+ {
+ return false;
+ }
+ void UpdateAngleApply()
+ {
+ }
+
+ Vector3d Axis(int) const
+ {
+ return Vector3d(0, 0, 0);
+ }
+ void SetBasis(const Matrix3d &)
+ {
+ m_basis.setIdentity();
+ }
};
-class IK_QRevoluteSegment : public IK_QSegment
-{
-public:
- // axis: the axis of the DoF, in range 0..2
- IK_QRevoluteSegment(int axis);
+class IK_QRevoluteSegment : public IK_QSegment {
+ public:
+ // axis: the axis of the DoF, in range 0..2
+ IK_QRevoluteSegment(int axis);
- Vector3d Axis(int dof) const;
+ Vector3d Axis(int dof) const;
- bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp);
- void Lock(int dof, IK_QJacobian& jacobian, Vector3d& delta);
- void UpdateAngleApply();
+ bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
+ void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
+ void UpdateAngleApply();
- void SetLimit(int axis, double lmin, double lmax);
- void SetWeight(int axis, double weight);
- void SetBasis(const Matrix3d& basis);
+ void SetLimit(int axis, double lmin, double lmax);
+ void SetWeight(int axis, double weight);
+ void SetBasis(const Matrix3d &basis);
-private:
- int m_axis;
- double m_angle, m_new_angle;
- bool m_limit;
- double m_min, m_max;
+ private:
+ int m_axis;
+ double m_angle, m_new_angle;
+ bool m_limit;
+ double m_min, m_max;
};
-class IK_QSwingSegment : public IK_QSegment
-{
-public:
- // XZ DOF, uses one direct rotation
- IK_QSwingSegment();
+class IK_QSwingSegment : public IK_QSegment {
+ public:
+ // XZ DOF, uses one direct rotation
+ IK_QSwingSegment();
- Vector3d Axis(int dof) const;
+ Vector3d Axis(int dof) const;
- bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp);
- void Lock(int dof, IK_QJacobian& jacobian, Vector3d& delta);
- void UpdateAngleApply();
+ bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
+ void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
+ void UpdateAngleApply();
- void SetLimit(int axis, double lmin, double lmax);
- void SetWeight(int axis, double weight);
- void SetBasis(const Matrix3d& basis);
+ void SetLimit(int axis, double lmin, double lmax);
+ void SetWeight(int axis, double weight);
+ void SetBasis(const Matrix3d &basis);
-private:
- Matrix3d m_new_basis;
- bool m_limit_x, m_limit_z;
- double m_min[2], m_max[2];
- double m_max_x, m_max_z, m_offset_x, m_offset_z;
+ private:
+ Matrix3d m_new_basis;
+ bool m_limit_x, m_limit_z;
+ double m_min[2], m_max[2];
+ double m_max_x, m_max_z, m_offset_x, m_offset_z;
};
-class IK_QElbowSegment : public IK_QSegment
-{
-public:
- // XY or ZY DOF, uses two sequential rotations: first rotate around
- // X or Z, then rotate around Y (twist)
- IK_QElbowSegment(int axis);
+class IK_QElbowSegment : public IK_QSegment {
+ public:
+ // XY or ZY DOF, uses two sequential rotations: first rotate around
+ // X or Z, then rotate around Y (twist)
+ IK_QElbowSegment(int axis);
- Vector3d Axis(int dof) const;
+ Vector3d Axis(int dof) const;
- bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp);
- void Lock(int dof, IK_QJacobian& jacobian, Vector3d& delta);
- void UpdateAngleApply();
+ bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
+ void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
+ void UpdateAngleApply();
- void SetLimit(int axis, double lmin, double lmax);
- void SetWeight(int axis, double weight);
- void SetBasis(const Matrix3d& basis);
+ void SetLimit(int axis, double lmin, double lmax);
+ void SetWeight(int axis, double weight);
+ void SetBasis(const Matrix3d &basis);
-private:
- int m_axis;
+ private:
+ int m_axis;
- double m_twist, m_angle, m_new_twist, m_new_angle;
- double m_cos_twist, m_sin_twist;
+ double m_twist, m_angle, m_new_twist, m_new_angle;
+ double m_cos_twist, m_sin_twist;
- bool m_limit, m_limit_twist;
- double m_min, m_max, m_min_twist, m_max_twist;
+ bool m_limit, m_limit_twist;
+ double m_min, m_max, m_min_twist, m_max_twist;
};
-class IK_QTranslateSegment : public IK_QSegment
-{
-public:
- // 1DOF, 2DOF or 3DOF translational segments
- IK_QTranslateSegment(int axis1);
- IK_QTranslateSegment(int axis1, int axis2);
- IK_QTranslateSegment();
+class IK_QTranslateSegment : public IK_QSegment {
+ public:
+ // 1DOF, 2DOF or 3DOF translational segments
+ IK_QTranslateSegment(int axis1);
+ IK_QTranslateSegment(int axis1, int axis2);
+ IK_QTranslateSegment();
- Vector3d Axis(int dof) const;
+ Vector3d Axis(int dof) const;
- bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d& delta, bool *clamp);
- void Lock(int, IK_QJacobian&, Vector3d&);
- void UpdateAngleApply();
+ bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
+ void Lock(int, IK_QJacobian &, Vector3d &);
+ void UpdateAngleApply();
- void SetWeight(int axis, double weight);
- void SetLimit(int axis, double lmin, double lmax);
+ void SetWeight(int axis, double weight);
+ void SetLimit(int axis, double lmin, double lmax);
- void Scale(double scale);
+ void Scale(double scale);
-private:
- int m_axis[3];
- bool m_axis_enabled[3], m_limit[3];
- Vector3d m_new_translation;
- double m_min[3], m_max[3];
+ private:
+ int m_axis[3];
+ bool m_axis_enabled[3], m_limit[3];
+ Vector3d m_new_translation;
+ double m_min[3], m_max[3];
};
-
diff --git a/intern/iksolver/intern/IK_QTask.cpp b/intern/iksolver/intern/IK_QTask.cpp
index c2ae46d7205..f3fe24bef18 100644
--- a/intern/iksolver/intern/IK_QTask.cpp
+++ b/intern/iksolver/intern/IK_QTask.cpp
@@ -21,210 +21,196 @@
* \ingroup iksolver
*/
-
#include "IK_QTask.h"
// IK_QTask
-IK_QTask::IK_QTask(
- int size,
- bool primary,
- bool active,
- const IK_QSegment *segment
- ) :
- m_size(size), m_primary(primary), m_active(active), m_segment(segment),
- m_weight(1.0)
+IK_QTask::IK_QTask(int size, bool primary, bool active, const IK_QSegment *segment)
+ : m_size(size), m_primary(primary), m_active(active), m_segment(segment), m_weight(1.0)
{
}
// IK_QPositionTask
-IK_QPositionTask::IK_QPositionTask(
- bool primary,
- const IK_QSegment *segment,
- const Vector3d& goal
- ) :
- IK_QTask(3, primary, true, segment), m_goal(goal)
+IK_QPositionTask::IK_QPositionTask(bool primary, const IK_QSegment *segment, const Vector3d &goal)
+ : IK_QTask(3, primary, true, segment), m_goal(goal)
{
- // computing clamping length
- int num;
- const IK_QSegment *seg;
+ // computing clamping length
+ int num;
+ const IK_QSegment *seg;
- m_clamp_length = 0.0;
- num = 0;
+ m_clamp_length = 0.0;
+ num = 0;
- for (seg = m_segment; seg; seg = seg->Parent()) {
- m_clamp_length += seg->MaxExtension();
- num++;
- }
+ for (seg = m_segment; seg; seg = seg->Parent()) {
+ m_clamp_length += seg->MaxExtension();
+ num++;
+ }
- m_clamp_length /= 2 * num;
+ m_clamp_length /= 2 * num;
}
-void IK_QPositionTask::ComputeJacobian(IK_QJacobian& jacobian)
+void IK_QPositionTask::ComputeJacobian(IK_QJacobian &jacobian)
{
- // compute beta
- const Vector3d& pos = m_segment->GlobalEnd();
-
- Vector3d d_pos = m_goal - pos;
- double length = d_pos.norm();
-
- if (length > m_clamp_length)
- d_pos = (m_clamp_length / length) * d_pos;
-
- jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
-
- // compute derivatives
- int i;
- const IK_QSegment *seg;
-
- for (seg = m_segment; seg; seg = seg->Parent()) {
- Vector3d p = seg->GlobalStart() - pos;
-
- for (i = 0; i < seg->NumberOfDoF(); i++) {
- Vector3d axis = seg->Axis(i) * m_weight;
-
- if (seg->Translational())
- jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e2);
- else {
- Vector3d pa = p.cross(axis);
- jacobian.SetDerivatives(m_id, seg->DoFId() + i, pa, 1e0);
- }
- }
- }
+ // compute beta
+ const Vector3d &pos = m_segment->GlobalEnd();
+
+ Vector3d d_pos = m_goal - pos;
+ double length = d_pos.norm();
+
+ if (length > m_clamp_length)
+ d_pos = (m_clamp_length / length) * d_pos;
+
+ jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
+
+ // compute derivatives
+ int i;
+ const IK_QSegment *seg;
+
+ for (seg = m_segment; seg; seg = seg->Parent()) {
+ Vector3d p = seg->GlobalStart() - pos;
+
+ for (i = 0; i < seg->NumberOfDoF(); i++) {
+ Vector3d axis = seg->Axis(i) * m_weight;
+
+ if (seg->Translational())
+ jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e2);
+ else {
+ Vector3d pa = p.cross(axis);
+ jacobian.SetDerivatives(m_id, seg->DoFId() + i, pa, 1e0);
+ }
+ }
+ }
}
double IK_QPositionTask::Distance() const
{
- const Vector3d& pos = m_segment->GlobalEnd();
- Vector3d d_pos = m_goal - pos;
- return d_pos.norm();
+ const Vector3d &pos = m_segment->GlobalEnd();
+ Vector3d d_pos = m_goal - pos;
+ return d_pos.norm();
}
// IK_QOrientationTask
-IK_QOrientationTask::IK_QOrientationTask(
- bool primary,
- const IK_QSegment *segment,
- const Matrix3d& goal
- ) :
- IK_QTask(3, primary, true, segment), m_goal(goal), m_distance(0.0)
+IK_QOrientationTask::IK_QOrientationTask(bool primary,
+ const IK_QSegment *segment,
+ const Matrix3d &goal)
+ : IK_QTask(3, primary, true, segment), m_goal(goal), m_distance(0.0)
{
}
-void IK_QOrientationTask::ComputeJacobian(IK_QJacobian& jacobian)
+void IK_QOrientationTask::ComputeJacobian(IK_QJacobian &jacobian)
{
- // compute betas
- const Matrix3d& rot = m_segment->GlobalTransform().linear();
+ // compute betas
+ const Matrix3d &rot = m_segment->GlobalTransform().linear();
- Matrix3d d_rotm = (m_goal * rot.transpose()).transpose();
+ Matrix3d d_rotm = (m_goal * rot.transpose()).transpose();
- Vector3d d_rot;
- d_rot = -0.5 * Vector3d(d_rotm(2, 1) - d_rotm(1, 2),
- d_rotm(0, 2) - d_rotm(2, 0),
- d_rotm(1, 0) - d_rotm(0, 1));
+ Vector3d d_rot;
+ d_rot = -0.5 * Vector3d(d_rotm(2, 1) - d_rotm(1, 2),
+ d_rotm(0, 2) - d_rotm(2, 0),
+ d_rotm(1, 0) - d_rotm(0, 1));
- m_distance = d_rot.norm();
+ m_distance = d_rot.norm();
- jacobian.SetBetas(m_id, m_size, m_weight * d_rot);
+ jacobian.SetBetas(m_id, m_size, m_weight * d_rot);
- // compute derivatives
- int i;
- const IK_QSegment *seg;
+ // compute derivatives
+ int i;
+ const IK_QSegment *seg;
- for (seg = m_segment; seg; seg = seg->Parent())
- for (i = 0; i < seg->NumberOfDoF(); i++) {
+ for (seg = m_segment; seg; seg = seg->Parent())
+ for (i = 0; i < seg->NumberOfDoF(); i++) {
- if (seg->Translational())
- jacobian.SetDerivatives(m_id, seg->DoFId() + i, Vector3d(0, 0, 0), 1e2);
- else {
- Vector3d axis = seg->Axis(i) * m_weight;
- jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e0);
- }
- }
+ if (seg->Translational())
+ jacobian.SetDerivatives(m_id, seg->DoFId() + i, Vector3d(0, 0, 0), 1e2);
+ else {
+ Vector3d axis = seg->Axis(i) * m_weight;
+ jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e0);
+ }
+ }
}
// IK_QCenterOfMassTask
// Note: implementation not finished!
-IK_QCenterOfMassTask::IK_QCenterOfMassTask(
- bool primary,
- const IK_QSegment *segment,
- const Vector3d& goal_center
- ) :
- IK_QTask(3, primary, true, segment), m_goal_center(goal_center)
+IK_QCenterOfMassTask::IK_QCenterOfMassTask(bool primary,
+ const IK_QSegment *segment,
+ const Vector3d &goal_center)
+ : IK_QTask(3, primary, true, segment), m_goal_center(goal_center)
{
- m_total_mass_inv = ComputeTotalMass(m_segment);
- if (!FuzzyZero(m_total_mass_inv))
- m_total_mass_inv = 1.0 / m_total_mass_inv;
+ m_total_mass_inv = ComputeTotalMass(m_segment);
+ if (!FuzzyZero(m_total_mass_inv))
+ m_total_mass_inv = 1.0 / m_total_mass_inv;
}
double IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment)
{
- double mass = /*seg->Mass()*/ 1.0;
+ double mass = /*seg->Mass()*/ 1.0;
+
+ const IK_QSegment *seg;
+ for (seg = segment->Child(); seg; seg = seg->Sibling())
+ mass += ComputeTotalMass(seg);
- const IK_QSegment *seg;
- for (seg = segment->Child(); seg; seg = seg->Sibling())
- mass += ComputeTotalMass(seg);
-
- return mass;
+ return mass;
}
Vector3d IK_QCenterOfMassTask::ComputeCenter(const IK_QSegment *segment)
{
- Vector3d center = /*seg->Mass()**/ segment->GlobalStart();
+ Vector3d center = /*seg->Mass()**/ segment->GlobalStart();
- const IK_QSegment *seg;
- for (seg = segment->Child(); seg; seg = seg->Sibling())
- center += ComputeCenter(seg);
-
- return center;
+ const IK_QSegment *seg;
+ for (seg = segment->Child(); seg; seg = seg->Sibling())
+ center += ComputeCenter(seg);
+
+ return center;
}
-void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian& jacobian, Vector3d& center, const IK_QSegment *segment)
+void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian &jacobian,
+ Vector3d &center,
+ const IK_QSegment *segment)
{
- int i;
- Vector3d p = center - segment->GlobalStart();
-
- for (i = 0; i < segment->NumberOfDoF(); i++) {
- Vector3d axis = segment->Axis(i) * m_weight;
- axis *= /*segment->Mass()**/ m_total_mass_inv;
-
- if (segment->Translational())
- jacobian.SetDerivatives(m_id, segment->DoFId() + i, axis, 1e2);
- else {
- Vector3d pa = axis.cross(p);
- jacobian.SetDerivatives(m_id, segment->DoFId() + i, pa, 1e0);
- }
- }
-
- const IK_QSegment *seg;
- for (seg = segment->Child(); seg; seg = seg->Sibling())
- JacobianSegment(jacobian, center, seg);
+ int i;
+ Vector3d p = center - segment->GlobalStart();
+
+ for (i = 0; i < segment->NumberOfDoF(); i++) {
+ Vector3d axis = segment->Axis(i) * m_weight;
+ axis *= /*segment->Mass()**/ m_total_mass_inv;
+
+ if (segment->Translational())
+ jacobian.SetDerivatives(m_id, segment->DoFId() + i, axis, 1e2);
+ else {
+ Vector3d pa = axis.cross(p);
+ jacobian.SetDerivatives(m_id, segment->DoFId() + i, pa, 1e0);
+ }
+ }
+
+ const IK_QSegment *seg;
+ for (seg = segment->Child(); seg; seg = seg->Sibling())
+ JacobianSegment(jacobian, center, seg);
}
-void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian& jacobian)
+void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian &jacobian)
{
- Vector3d center = ComputeCenter(m_segment) * m_total_mass_inv;
+ Vector3d center = ComputeCenter(m_segment) * m_total_mass_inv;
- // compute beta
- Vector3d d_pos = m_goal_center - center;
+ // compute beta
+ Vector3d d_pos = m_goal_center - center;
- m_distance = d_pos.norm();
+ m_distance = d_pos.norm();
#if 0
- if (m_distance > m_clamp_length)
- d_pos = (m_clamp_length / m_distance) * d_pos;
+ if (m_distance > m_clamp_length)
+ d_pos = (m_clamp_length / m_distance) * d_pos;
#endif
-
- jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
- // compute derivatives
- JacobianSegment(jacobian, center, m_segment);
+ jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
+
+ // compute derivatives
+ JacobianSegment(jacobian, center, m_segment);
}
double IK_QCenterOfMassTask::Distance() const
{
- return m_distance;
+ return m_distance;
}
-
diff --git a/intern/iksolver/intern/IK_QTask.h b/intern/iksolver/intern/IK_QTask.h
index 58b832177db..595d1454872 100644
--- a/intern/iksolver/intern/IK_QTask.h
+++ b/intern/iksolver/intern/IK_QTask.h
@@ -28,116 +28,128 @@
#include "IK_QJacobian.h"
#include "IK_QSegment.h"
-class IK_QTask
-{
-public:
- IK_QTask(
- int size,
- bool primary,
- bool active,
- const IK_QSegment *segment
- );
- virtual ~IK_QTask() {}
-
- int Id() const
- { return m_size; }
-
- void SetId(int id)
- { m_id = id; }
-
- int Size() const
- { return m_size; }
-
- bool Primary() const
- { return m_primary; }
-
- bool Active() const
- { return m_active; }
-
- double Weight() const
- { return m_weight*m_weight; }
-
- void SetWeight(double weight)
- { m_weight = sqrt(weight); }
+class IK_QTask {
+ public:
+ IK_QTask(int size, bool primary, bool active, const IK_QSegment *segment);
+ virtual ~IK_QTask()
+ {
+ }
+
+ int Id() const
+ {
+ return m_size;
+ }
+
+ void SetId(int id)
+ {
+ m_id = id;
+ }
+
+ int Size() const
+ {
+ return m_size;
+ }
+
+ bool Primary() const
+ {
+ return m_primary;
+ }
+
+ bool Active() const
+ {
+ return m_active;
+ }
+
+ double Weight() const
+ {
+ return m_weight * m_weight;
+ }
+
+ void SetWeight(double weight)
+ {
+ m_weight = sqrt(weight);
+ }
+
+ virtual void ComputeJacobian(IK_QJacobian &jacobian) = 0;
+
+ virtual double Distance() const = 0;
+
+ virtual bool PositionTask() const
+ {
+ return false;
+ }
+
+ virtual void Scale(double)
+ {
+ }
+
+ protected:
+ int m_id;
+ int m_size;
+ bool m_primary;
+ bool m_active;
+ const IK_QSegment *m_segment;
+ double m_weight;
+};
- virtual void ComputeJacobian(IK_QJacobian& jacobian)=0;
+class IK_QPositionTask : public IK_QTask {
+ public:
+ IK_QPositionTask(bool primary, const IK_QSegment *segment, const Vector3d &goal);
- virtual double Distance() const=0;
+ void ComputeJacobian(IK_QJacobian &jacobian);
- virtual bool PositionTask() const { return false; }
+ double Distance() const;
- virtual void Scale(double) {}
+ bool PositionTask() const
+ {
+ return true;
+ }
+ void Scale(double scale)
+ {
+ m_goal *= scale;
+ m_clamp_length *= scale;
+ }
-protected:
- int m_id;
- int m_size;
- bool m_primary;
- bool m_active;
- const IK_QSegment *m_segment;
- double m_weight;
+ private:
+ Vector3d m_goal;
+ double m_clamp_length;
};
-class IK_QPositionTask : public IK_QTask
-{
-public:
- IK_QPositionTask(
- bool primary,
- const IK_QSegment *segment,
- const Vector3d& goal
- );
-
- void ComputeJacobian(IK_QJacobian& jacobian);
+class IK_QOrientationTask : public IK_QTask {
+ public:
+ IK_QOrientationTask(bool primary, const IK_QSegment *segment, const Matrix3d &goal);
- double Distance() const;
+ double Distance() const
+ {
+ return m_distance;
+ }
+ void ComputeJacobian(IK_QJacobian &jacobian);
- bool PositionTask() const { return true; }
- void Scale(double scale) { m_goal *= scale; m_clamp_length *= scale; }
-
-private:
- Vector3d m_goal;
- double m_clamp_length;
+ private:
+ Matrix3d m_goal;
+ double m_distance;
};
-class IK_QOrientationTask : public IK_QTask
-{
-public:
- IK_QOrientationTask(
- bool primary,
- const IK_QSegment *segment,
- const Matrix3d& goal
- );
-
- double Distance() const { return m_distance; }
- void ComputeJacobian(IK_QJacobian& jacobian);
-
-private:
- Matrix3d m_goal;
- double m_distance;
-};
+class IK_QCenterOfMassTask : public IK_QTask {
+ public:
+ IK_QCenterOfMassTask(bool primary, const IK_QSegment *segment, const Vector3d &center);
+ void ComputeJacobian(IK_QJacobian &jacobian);
-class IK_QCenterOfMassTask : public IK_QTask
-{
-public:
- IK_QCenterOfMassTask(
- bool primary,
- const IK_QSegment *segment,
- const Vector3d& center
- );
+ double Distance() const;
- void ComputeJacobian(IK_QJacobian& jacobian);
+ void Scale(double scale)
+ {
+ m_goal_center *= scale;
+ m_distance *= scale;
+ }
- double Distance() const;
+ private:
+ double ComputeTotalMass(const IK_QSegment *segment);
+ Vector3d ComputeCenter(const IK_QSegment *segment);
+ void JacobianSegment(IK_QJacobian &jacobian, Vector3d &center, const IK_QSegment *segment);
- void Scale(double scale) { m_goal_center *= scale; m_distance *= scale; }
-
-private:
- double ComputeTotalMass(const IK_QSegment *segment);
- Vector3d ComputeCenter(const IK_QSegment *segment);
- void JacobianSegment(IK_QJacobian& jacobian, Vector3d& center, const IK_QSegment *segment);
-
- Vector3d m_goal_center;
- double m_total_mass_inv;
- double m_distance;
+ Vector3d m_goal_center;
+ double m_total_mass_inv;
+ double m_distance;
};
-
diff --git a/intern/iksolver/intern/IK_Solver.cpp b/intern/iksolver/intern/IK_Solver.cpp
index beec5da983f..5205fd6e16c 100644
--- a/intern/iksolver/intern/IK_Solver.cpp
+++ b/intern/iksolver/intern/IK_Solver.cpp
@@ -21,7 +21,6 @@
* \ingroup iksolver
*/
-
#include "../extern/IK_solver.h"
#include "IK_QJacobianSolver.h"
@@ -32,355 +31,387 @@
using namespace std;
class IK_QSolver {
-public:
- EIGEN_MAKE_ALIGNED_OPERATOR_NEW
- IK_QSolver() : root(NULL) {
- }
-
- IK_QJacobianSolver solver;
- IK_QSegment *root;
- std::list<IK_QTask *> tasks;
+ public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+ IK_QSolver() : root(NULL)
+ {
+ }
+
+ IK_QJacobianSolver solver;
+ IK_QSegment *root;
+ std::list<IK_QTask *> tasks;
};
// FIXME: locks still result in small "residual" changes to the locked axes...
static IK_QSegment *CreateSegment(int flag, bool translate)
{
- int ndof = 0;
- ndof += (flag & IK_XDOF) ? 1 : 0;
- ndof += (flag & IK_YDOF) ? 1 : 0;
- ndof += (flag & IK_ZDOF) ? 1 : 0;
-
- IK_QSegment *seg;
-
- if (ndof == 0)
- return NULL;
- else if (ndof == 1) {
- int axis;
-
- if (flag & IK_XDOF) axis = 0;
- else if (flag & IK_YDOF) axis = 1;
- else axis = 2;
-
- if (translate)
- seg = new IK_QTranslateSegment(axis);
- else
- seg = new IK_QRevoluteSegment(axis);
- }
- else if (ndof == 2) {
- int axis1, axis2;
-
- if (flag & IK_XDOF) {
- axis1 = 0;
- axis2 = (flag & IK_YDOF) ? 1 : 2;
- }
- else {
- axis1 = 1;
- axis2 = 2;
- }
-
- if (translate)
- seg = new IK_QTranslateSegment(axis1, axis2);
- else {
- if (axis1 + axis2 == 2)
- seg = new IK_QSwingSegment();
- else
- seg = new IK_QElbowSegment((axis1 == 0) ? 0 : 2);
- }
- }
- else {
- if (translate)
- seg = new IK_QTranslateSegment();
- else
- seg = new IK_QSphericalSegment();
- }
-
- return seg;
+ int ndof = 0;
+ ndof += (flag & IK_XDOF) ? 1 : 0;
+ ndof += (flag & IK_YDOF) ? 1 : 0;
+ ndof += (flag & IK_ZDOF) ? 1 : 0;
+
+ IK_QSegment *seg;
+
+ if (ndof == 0)
+ return NULL;
+ else if (ndof == 1) {
+ int axis;
+
+ if (flag & IK_XDOF)
+ axis = 0;
+ else if (flag & IK_YDOF)
+ axis = 1;
+ else
+ axis = 2;
+
+ if (translate)
+ seg = new IK_QTranslateSegment(axis);
+ else
+ seg = new IK_QRevoluteSegment(axis);
+ }
+ else if (ndof == 2) {
+ int axis1, axis2;
+
+ if (flag & IK_XDOF) {
+ axis1 = 0;
+ axis2 = (flag & IK_YDOF) ? 1 : 2;
+ }
+ else {
+ axis1 = 1;
+ axis2 = 2;
+ }
+
+ if (translate)
+ seg = new IK_QTranslateSegment(axis1, axis2);
+ else {
+ if (axis1 + axis2 == 2)
+ seg = new IK_QSwingSegment();
+ else
+ seg = new IK_QElbowSegment((axis1 == 0) ? 0 : 2);
+ }
+ }
+ else {
+ if (translate)
+ seg = new IK_QTranslateSegment();
+ else
+ seg = new IK_QSphericalSegment();
+ }
+
+ return seg;
}
IK_Segment *IK_CreateSegment(int flag)
{
- IK_QSegment *rot = CreateSegment(flag, false);
- IK_QSegment *trans = CreateSegment(flag >> 3, true);
-
- IK_QSegment *seg;
-
- if (rot == NULL && trans == NULL)
- seg = new IK_QNullSegment();
- else if (rot == NULL)
- seg = trans;
- else {
- seg = rot;
-
- // make it seem from the interface as if the rotation and translation
- // segment are one
- if (trans) {
- seg->SetComposite(trans);
- trans->SetParent(seg);
- }
- }
-
- return seg;
+ IK_QSegment *rot = CreateSegment(flag, false);
+ IK_QSegment *trans = CreateSegment(flag >> 3, true);
+
+ IK_QSegment *seg;
+
+ if (rot == NULL && trans == NULL)
+ seg = new IK_QNullSegment();
+ else if (rot == NULL)
+ seg = trans;
+ else {
+ seg = rot;
+
+ // make it seem from the interface as if the rotation and translation
+ // segment are one
+ if (trans) {
+ seg->SetComposite(trans);
+ trans->SetParent(seg);
+ }
+ }
+
+ return seg;
}
void IK_FreeSegment(IK_Segment *seg)
{
- IK_QSegment *qseg = (IK_QSegment *)seg;
+ IK_QSegment *qseg = (IK_QSegment *)seg;
- if (qseg->Composite())
- delete qseg->Composite();
- delete qseg;
+ if (qseg->Composite())
+ delete qseg->Composite();
+ delete qseg;
}
void IK_SetParent(IK_Segment *seg, IK_Segment *parent)
{
- IK_QSegment *qseg = (IK_QSegment *)seg;
- IK_QSegment *qparent = (IK_QSegment *)parent;
+ IK_QSegment *qseg = (IK_QSegment *)seg;
+ IK_QSegment *qparent = (IK_QSegment *)parent;
- if (qparent && qparent->Composite())
- qseg->SetParent(qparent->Composite());
- else
- qseg->SetParent(qparent);
+ if (qparent && qparent->Composite())
+ qseg->SetParent(qparent->Composite());
+ else
+ qseg->SetParent(qparent);
}
-void IK_SetTransform(IK_Segment *seg, float start[3], float rest[][3], float basis[][3], float length)
+void IK_SetTransform(
+ IK_Segment *seg, float start[3], float rest[][3], float basis[][3], float length)
{
- IK_QSegment *qseg = (IK_QSegment *)seg;
-
- Vector3d mstart(start[0], start[1], start[2]);
- // convert from blender column major
- Matrix3d mbasis = CreateMatrix(basis[0][0], basis[1][0], basis[2][0],
- basis[0][1], basis[1][1], basis[2][1],
- basis[0][2], basis[1][2], basis[2][2]);
- Matrix3d mrest = CreateMatrix(rest[0][0], rest[1][0], rest[2][0],
- rest[0][1], rest[1][1], rest[2][1],
- rest[0][2], rest[1][2], rest[2][2]);
- double mlength(length);
-
- if (qseg->Composite()) {
- Vector3d cstart(0, 0, 0);
- Matrix3d cbasis;
- cbasis.setIdentity();
-
- qseg->SetTransform(mstart, mrest, mbasis, 0.0);
- qseg->Composite()->SetTransform(cstart, cbasis, cbasis, mlength);
- }
- else
- qseg->SetTransform(mstart, mrest, mbasis, mlength);
+ IK_QSegment *qseg = (IK_QSegment *)seg;
+
+ Vector3d mstart(start[0], start[1], start[2]);
+ // convert from blender column major
+ Matrix3d mbasis = CreateMatrix(basis[0][0],
+ basis[1][0],
+ basis[2][0],
+ basis[0][1],
+ basis[1][1],
+ basis[2][1],
+ basis[0][2],
+ basis[1][2],
+ basis[2][2]);
+ Matrix3d mrest = CreateMatrix(rest[0][0],
+ rest[1][0],
+ rest[2][0],
+ rest[0][1],
+ rest[1][1],
+ rest[2][1],
+ rest[0][2],
+ rest[1][2],
+ rest[2][2]);
+ double mlength(length);
+
+ if (qseg->Composite()) {
+ Vector3d cstart(0, 0, 0);
+ Matrix3d cbasis;
+ cbasis.setIdentity();
+
+ qseg->SetTransform(mstart, mrest, mbasis, 0.0);
+ qseg->Composite()->SetTransform(cstart, cbasis, cbasis, mlength);
+ }
+ else
+ qseg->SetTransform(mstart, mrest, mbasis, mlength);
}
void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
{
- IK_QSegment *qseg = (IK_QSegment *)seg;
-
- if (axis >= IK_TRANS_X) {
- if (!qseg->Translational()) {
- if (qseg->Composite() && qseg->Composite()->Translational())
- qseg = qseg->Composite();
- else
- return;
- }
-
- if (axis == IK_TRANS_X) axis = IK_X;
- else if (axis == IK_TRANS_Y) axis = IK_Y;
- else axis = IK_Z;
- }
-
- qseg->SetLimit(axis, lmin, lmax);
+ IK_QSegment *qseg = (IK_QSegment *)seg;
+
+ if (axis >= IK_TRANS_X) {
+ if (!qseg->Translational()) {
+ if (qseg->Composite() && qseg->Composite()->Translational())
+ qseg = qseg->Composite();
+ else
+ return;
+ }
+
+ if (axis == IK_TRANS_X)
+ axis = IK_X;
+ else if (axis == IK_TRANS_Y)
+ axis = IK_Y;
+ else
+ axis = IK_Z;
+ }
+
+ qseg->SetLimit(axis, lmin, lmax);
}
void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
{
- if (stiffness < 0.0f)
- return;
-
- if (stiffness > (1.0 - IK_STRETCH_STIFF_EPS))
- stiffness = (1.0 - IK_STRETCH_STIFF_EPS);
-
- IK_QSegment *qseg = (IK_QSegment *)seg;
- double weight = 1.0f - stiffness;
-
- if (axis >= IK_TRANS_X) {
- if (!qseg->Translational()) {
- if (qseg->Composite() && qseg->Composite()->Translational())
- qseg = qseg->Composite();
- else
- return;
- }
-
- if (axis == IK_TRANS_X) axis = IK_X;
- else if (axis == IK_TRANS_Y) axis = IK_Y;
- else axis = IK_Z;
- }
-
- qseg->SetWeight(axis, weight);
+ if (stiffness < 0.0f)
+ return;
+
+ if (stiffness > (1.0 - IK_STRETCH_STIFF_EPS))
+ stiffness = (1.0 - IK_STRETCH_STIFF_EPS);
+
+ IK_QSegment *qseg = (IK_QSegment *)seg;
+ double weight = 1.0f - stiffness;
+
+ if (axis >= IK_TRANS_X) {
+ if (!qseg->Translational()) {
+ if (qseg->Composite() && qseg->Composite()->Translational())
+ qseg = qseg->Composite();
+ else
+ return;
+ }
+
+ if (axis == IK_TRANS_X)
+ axis = IK_X;
+ else if (axis == IK_TRANS_Y)
+ axis = IK_Y;
+ else
+ axis = IK_Z;
+ }
+
+ qseg->SetWeight(axis, weight);
}
void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3])
{
- IK_QSegment *qseg = (IK_QSegment *)seg;
-
- if (qseg->Translational() && qseg->Composite())
- qseg = qseg->Composite();
-
- const Matrix3d& change = qseg->BasisChange();
-
- // convert to blender column major
- basis_change[0][0] = (float)change(0, 0);
- basis_change[1][0] = (float)change(0, 1);
- basis_change[2][0] = (float)change(0, 2);
- basis_change[0][1] = (float)change(1, 0);
- basis_change[1][1] = (float)change(1, 1);
- basis_change[2][1] = (float)change(1, 2);
- basis_change[0][2] = (float)change(2, 0);
- basis_change[1][2] = (float)change(2, 1);
- basis_change[2][2] = (float)change(2, 2);
+ IK_QSegment *qseg = (IK_QSegment *)seg;
+
+ if (qseg->Translational() && qseg->Composite())
+ qseg = qseg->Composite();
+
+ const Matrix3d &change = qseg->BasisChange();
+
+ // convert to blender column major
+ basis_change[0][0] = (float)change(0, 0);
+ basis_change[1][0] = (float)change(0, 1);
+ basis_change[2][0] = (float)change(0, 2);
+ basis_change[0][1] = (float)change(1, 0);
+ basis_change[1][1] = (float)change(1, 1);
+ basis_change[2][1] = (float)change(1, 2);
+ basis_change[0][2] = (float)change(2, 0);
+ basis_change[1][2] = (float)change(2, 1);
+ basis_change[2][2] = (float)change(2, 2);
}
void IK_GetTranslationChange(IK_Segment *seg, float *translation_change)
{
- IK_QSegment *qseg = (IK_QSegment *)seg;
+ IK_QSegment *qseg = (IK_QSegment *)seg;
+
+ if (!qseg->Translational() && qseg->Composite())
+ qseg = qseg->Composite();
- if (!qseg->Translational() && qseg->Composite())
- qseg = qseg->Composite();
-
- const Vector3d& change = qseg->TranslationChange();
+ const Vector3d &change = qseg->TranslationChange();
- translation_change[0] = (float)change[0];
- translation_change[1] = (float)change[1];
- translation_change[2] = (float)change[2];
+ translation_change[0] = (float)change[0];
+ translation_change[1] = (float)change[1];
+ translation_change[2] = (float)change[2];
}
IK_Solver *IK_CreateSolver(IK_Segment *root)
{
- if (root == NULL)
- return NULL;
-
- IK_QSolver *solver = new IK_QSolver();
- solver->root = (IK_QSegment *)root;
+ if (root == NULL)
+ return NULL;
+
+ IK_QSolver *solver = new IK_QSolver();
+ solver->root = (IK_QSegment *)root;
- return (IK_Solver *)solver;
+ return (IK_Solver *)solver;
}
void IK_FreeSolver(IK_Solver *solver)
{
- if (solver == NULL)
- return;
+ if (solver == NULL)
+ return;
- IK_QSolver *qsolver = (IK_QSolver *)solver;
- std::list<IK_QTask *>& tasks = qsolver->tasks;
- std::list<IK_QTask *>::iterator task;
+ IK_QSolver *qsolver = (IK_QSolver *)solver;
+ std::list<IK_QTask *> &tasks = qsolver->tasks;
+ std::list<IK_QTask *>::iterator task;
- for (task = tasks.begin(); task != tasks.end(); task++)
- delete (*task);
-
- delete qsolver;
+ for (task = tasks.begin(); task != tasks.end(); task++)
+ delete (*task);
+
+ delete qsolver;
}
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight)
{
- if (solver == NULL || tip == NULL)
- return;
+ if (solver == NULL || tip == NULL)
+ return;
- IK_QSolver *qsolver = (IK_QSolver *)solver;
- IK_QSegment *qtip = (IK_QSegment *)tip;
+ IK_QSolver *qsolver = (IK_QSolver *)solver;
+ IK_QSegment *qtip = (IK_QSegment *)tip;
- // in case of composite segment the second segment is the tip
- if (qtip->Composite())
- qtip = qtip->Composite();
+ // in case of composite segment the second segment is the tip
+ if (qtip->Composite())
+ qtip = qtip->Composite();
- Vector3d pos(goal[0], goal[1], goal[2]);
+ Vector3d pos(goal[0], goal[1], goal[2]);
- IK_QTask *ee = new IK_QPositionTask(true, qtip, pos);
- ee->SetWeight(weight);
- qsolver->tasks.push_back(ee);
+ IK_QTask *ee = new IK_QPositionTask(true, qtip, pos);
+ ee->SetWeight(weight);
+ qsolver->tasks.push_back(ee);
}
void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight)
{
- if (solver == NULL || tip == NULL)
- return;
-
- IK_QSolver *qsolver = (IK_QSolver *)solver;
- IK_QSegment *qtip = (IK_QSegment *)tip;
-
- // in case of composite segment the second segment is the tip
- if (qtip->Composite())
- qtip = qtip->Composite();
-
- // convert from blender column major
- Matrix3d rot = CreateMatrix(goal[0][0], goal[1][0], goal[2][0],
- goal[0][1], goal[1][1], goal[2][1],
- goal[0][2], goal[1][2], goal[2][2]);
-
- IK_QTask *orient = new IK_QOrientationTask(true, qtip, rot);
- orient->SetWeight(weight);
- qsolver->tasks.push_back(orient);
+ if (solver == NULL || tip == NULL)
+ return;
+
+ IK_QSolver *qsolver = (IK_QSolver *)solver;
+ IK_QSegment *qtip = (IK_QSegment *)tip;
+
+ // in case of composite segment the second segment is the tip
+ if (qtip->Composite())
+ qtip = qtip->Composite();
+
+ // convert from blender column major
+ Matrix3d rot = CreateMatrix(goal[0][0],
+ goal[1][0],
+ goal[2][0],
+ goal[0][1],
+ goal[1][1],
+ goal[2][1],
+ goal[0][2],
+ goal[1][2],
+ goal[2][2]);
+
+ IK_QTask *orient = new IK_QOrientationTask(true, qtip, rot);
+ orient->SetWeight(weight);
+ qsolver->tasks.push_back(orient);
}
-void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle)
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver,
+ IK_Segment *tip,
+ float goal[3],
+ float polegoal[3],
+ float poleangle,
+ int getangle)
{
- if (solver == NULL || tip == NULL)
- return;
+ if (solver == NULL || tip == NULL)
+ return;
- IK_QSolver *qsolver = (IK_QSolver *)solver;
- IK_QSegment *qtip = (IK_QSegment *)tip;
+ IK_QSolver *qsolver = (IK_QSolver *)solver;
+ IK_QSegment *qtip = (IK_QSegment *)tip;
- // in case of composite segment the second segment is the tip
- if (qtip->Composite())
- qtip = qtip->Composite();
+ // in case of composite segment the second segment is the tip
+ if (qtip->Composite())
+ qtip = qtip->Composite();
- Vector3d qgoal(goal[0], goal[1], goal[2]);
- Vector3d qpolegoal(polegoal[0], polegoal[1], polegoal[2]);
+ Vector3d qgoal(goal[0], goal[1], goal[2]);
+ Vector3d qpolegoal(polegoal[0], polegoal[1], polegoal[2]);
- qsolver->solver.SetPoleVectorConstraint(
- qtip, qgoal, qpolegoal, poleangle, getangle);
+ qsolver->solver.SetPoleVectorConstraint(qtip, qgoal, qpolegoal, poleangle, getangle);
}
float IK_SolverGetPoleAngle(IK_Solver *solver)
{
- if (solver == NULL)
- return 0.0f;
+ if (solver == NULL)
+ return 0.0f;
- IK_QSolver *qsolver = (IK_QSolver *)solver;
+ IK_QSolver *qsolver = (IK_QSolver *)solver;
- return qsolver->solver.GetPoleAngle();
+ return qsolver->solver.GetPoleAngle();
}
#if 0
static void IK_SolverAddCenterOfMass(IK_Solver *solver, IK_Segment *root, float goal[3], float weight)
{
- if (solver == NULL || root == NULL)
- return;
+ if (solver == NULL || root == NULL)
+ return;
- IK_QSolver *qsolver = (IK_QSolver *)solver;
- IK_QSegment *qroot = (IK_QSegment *)root;
+ IK_QSolver *qsolver = (IK_QSolver *)solver;
+ IK_QSegment *qroot = (IK_QSegment *)root;
- // convert from blender column major
- Vector3d center(goal);
+ // convert from blender column major
+ Vector3d center(goal);
- IK_QTask *com = new IK_QCenterOfMassTask(true, qroot, center);
- com->SetWeight(weight);
- qsolver->tasks.push_back(com);
+ IK_QTask *com = new IK_QCenterOfMassTask(true, qroot, center);
+ com->SetWeight(weight);
+ qsolver->tasks.push_back(com);
}
#endif
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
{
- if (solver == NULL)
- return 0;
+ if (solver == NULL)
+ return 0;
- IK_QSolver *qsolver = (IK_QSolver *)solver;
+ IK_QSolver *qsolver = (IK_QSolver *)solver;
- IK_QSegment *root = qsolver->root;
- IK_QJacobianSolver& jacobian = qsolver->solver;
- std::list<IK_QTask *>& tasks = qsolver->tasks;
- double tol = tolerance;
+ IK_QSegment *root = qsolver->root;
+ IK_QJacobianSolver &jacobian = qsolver->solver;
+ std::list<IK_QTask *> &tasks = qsolver->tasks;
+ double tol = tolerance;
- if (!jacobian.Setup(root, tasks))
- return 0;
+ if (!jacobian.Setup(root, tasks))
+ return 0;
- bool result = jacobian.Solve(root, tasks, tol, max_iterations);
+ bool result = jacobian.Solve(root, tasks, tol, max_iterations);
- return ((result) ? 1 : 0);
+ return ((result) ? 1 : 0);
}
-
diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt
index 31b9e690b29..5c5da31482d 100644
--- a/intern/locale/CMakeLists.txt
+++ b/intern/locale/CMakeLists.txt
@@ -19,42 +19,42 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
+ .
)
set(INC_SYS
)
set(SRC
- boost_locale_wrapper.cpp
+ boost_locale_wrapper.cpp
- boost_locale_wrapper.h
+ boost_locale_wrapper.h
)
set(LIB
)
if(APPLE)
- # Cocoa code to read the locale on OSX
- list(APPEND SRC
- osx_user_locale.mm
- )
+ # Cocoa code to read the locale on OSX
+ list(APPEND SRC
+ osx_user_locale.mm
+ )
endif()
if(WITH_HEADLESS)
- add_definitions(-DWITH_HEADLESS)
+ add_definitions(-DWITH_HEADLESS)
endif()
if(WITH_GHOST_SDL)
- add_definitions(-DWITH_GHOST_SDL)
+ add_definitions(-DWITH_GHOST_SDL)
endif()
if(WITH_INTERNATIONAL)
- list(APPEND INC_SYS
- ${BOOST_INCLUDE_DIR}
- )
- add_definitions(-DWITH_INTERNATIONAL)
- add_definitions(${BOOST_DEFINITIONS})
+ list(APPEND INC_SYS
+ ${BOOST_INCLUDE_DIR}
+ )
+ add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(${BOOST_DEFINITIONS})
endif()
blender_add_lib(bf_intern_locale "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
index 04b106335bb..bb46f48a14f 100644
--- a/intern/locale/boost_locale_wrapper.cpp
+++ b/intern/locale/boost_locale_wrapper.cpp
@@ -35,104 +35,105 @@ static char_message_facet const *facet_global = NULL;
static void bl_locale_global_cache()
{
- /* Cache facet in global variable. Not only is it better for performance,
- * it also fixes crashes on macOS when doing translation from threads other
- * than main. Likely because of some internal thread local variables. */
- try {
- /* facet_global reference is valid as long as local_global exists,
- * so we store both. */
- locale_global = std::locale();
- facet_global = &std::use_facet<char_message_facet>(locale_global);
- }
- catch(const std::bad_cast &e) { /* if std::has_facet<char_message_facet>(l) == false, LC_ALL = "C" case */
+ /* Cache facet in global variable. Not only is it better for performance,
+ * it also fixes crashes on macOS when doing translation from threads other
+ * than main. Likely because of some internal thread local variables. */
+ try {
+ /* facet_global reference is valid as long as local_global exists,
+ * so we store both. */
+ locale_global = std::locale();
+ facet_global = &std::use_facet<char_message_facet>(locale_global);
+ }
+ catch (const std::bad_cast
+ &e) { /* if std::has_facet<char_message_facet>(l) == false, LC_ALL = "C" case */
#ifndef NDEBUG
- std::cout << "bl_locale_global_cache:" << e.what() << " \n";
+ std::cout << "bl_locale_global_cache:" << e.what() << " \n";
#endif
- (void)e;
- facet_global = NULL;
- }
- catch(const std::exception &e) {
+ (void)e;
+ facet_global = NULL;
+ }
+ catch (const std::exception &e) {
#ifndef NDEBUG
- std::cout << "bl_locale_global_cache:" << e.what() << " \n";
+ std::cout << "bl_locale_global_cache:" << e.what() << " \n";
#endif
- (void)e;
- facet_global = NULL;
- }
+ (void)e;
+ facet_global = NULL;
+ }
}
void bl_locale_init(const char *_messages_path, const char *_default_domain)
{
- // Avoid using ICU backend, we do not need its power and it's rather heavy!
- boost::locale::localization_backend_manager lman = boost::locale::localization_backend_manager::global();
-#if defined (_WIN32)
- lman.select("winapi");
+ // Avoid using ICU backend, we do not need its power and it's rather heavy!
+ boost::locale::localization_backend_manager lman =
+ boost::locale::localization_backend_manager::global();
+#if defined(_WIN32)
+ lman.select("winapi");
#else
- lman.select("posix");
+ lman.select("posix");
#endif
- boost::locale::localization_backend_manager::global(lman);
+ boost::locale::localization_backend_manager::global(lman);
- messages_path = _messages_path;
- default_domain = _default_domain;
+ messages_path = _messages_path;
+ default_domain = _default_domain;
}
void bl_locale_set(const char *locale)
{
- boost::locale::generator gen;
- std::locale _locale;
- // Specify location of dictionaries.
- gen.add_messages_path(messages_path);
- gen.add_messages_domain(default_domain);
- //gen.set_default_messages_domain(default_domain);
-
- try {
- if (locale && locale[0]) {
- _locale = gen(locale);
- }
- else {
+ boost::locale::generator gen;
+ std::locale _locale;
+ // Specify location of dictionaries.
+ gen.add_messages_path(messages_path);
+ gen.add_messages_domain(default_domain);
+ //gen.set_default_messages_domain(default_domain);
+
+ try {
+ if (locale && locale[0]) {
+ _locale = gen(locale);
+ }
+ else {
#if defined(__APPLE__) && !defined(WITH_HEADLESS) && !defined(WITH_GHOST_SDL)
- std::string locale_osx = osx_user_locale() + std::string(".UTF-8");
- _locale = gen(locale_osx.c_str());
+ std::string locale_osx = osx_user_locale() + std::string(".UTF-8");
+ _locale = gen(locale_osx.c_str());
#else
- _locale = gen("");
+ _locale = gen("");
#endif
- }
- std::locale::global(_locale);
- // Note: boost always uses "C" LC_NUMERIC by default!
+ }
+ std::locale::global(_locale);
+ // Note: boost always uses "C" LC_NUMERIC by default!
- bl_locale_global_cache();
+ bl_locale_global_cache();
- // Generate the locale string (useful to know which locale we are actually using in case of "default" one).
+ // Generate the locale string (useful to know which locale we are actually using in case of "default" one).
#define LOCALE_INFO std::use_facet<boost::locale::info>(_locale)
- locale_str = LOCALE_INFO.language();
- if (LOCALE_INFO.country() != "") {
- locale_str += "_" + LOCALE_INFO.country();
- }
- if (LOCALE_INFO.variant() != "") {
- locale_str += "@" + LOCALE_INFO.variant();
- }
+ locale_str = LOCALE_INFO.language();
+ if (LOCALE_INFO.country() != "") {
+ locale_str += "_" + LOCALE_INFO.country();
+ }
+ if (LOCALE_INFO.variant() != "") {
+ locale_str += "@" + LOCALE_INFO.variant();
+ }
#undef LOCALE_INFO
-
- }
- catch(std::exception const &e) {
- std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
- }
+ }
+ catch (std::exception const &e) {
+ std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
+ }
}
const char *bl_locale_get(void)
{
- return locale_str.c_str();
+ return locale_str.c_str();
}
const char *bl_locale_pgettext(const char *msgctxt, const char *msgid)
{
- if (facet_global) {
- char const *r = facet_global->get(0, msgctxt, msgid);
- if (r) {
- return r;
- }
- }
-
- return msgid;
+ if (facet_global) {
+ char const *r = facet_global->get(0, msgctxt, msgid);
+ if (r) {
+ return r;
+ }
+ }
+
+ return msgid;
}
diff --git a/intern/locale/boost_locale_wrapper.h b/intern/locale/boost_locale_wrapper.h
index b438b1bf9cc..deb552e4871 100644
--- a/intern/locale/boost_locale_wrapper.h
+++ b/intern/locale/boost_locale_wrapper.h
@@ -35,7 +35,7 @@ const char *bl_locale_get(void);
const char *bl_locale_pgettext(const char *msgctxt, const char *msgid);
#if defined(__APPLE__) && !defined(WITH_HEADLESS) && !defined(WITH_GHOST_SDL)
-const char* osx_user_locale(void);
+const char *osx_user_locale(void);
#endif
#ifdef __cplusplus
diff --git a/intern/locale/osx_user_locale.mm b/intern/locale/osx_user_locale.mm
index 1ed33bb1713..e2f65d39df9 100644
--- a/intern/locale/osx_user_locale.mm
+++ b/intern/locale/osx_user_locale.mm
@@ -4,19 +4,19 @@
#include <cstdlib>
-static char* user_locale = NULL;
+static char *user_locale = NULL;
// get current locale
-const char* osx_user_locale()
+const char *osx_user_locale()
{
- ::free(user_locale);
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
- NSLocale * myNSLocale = (NSLocale *) myCFLocale;
- [myNSLocale autorelease];
- NSString *nsIdentifier = [myNSLocale localeIdentifier];
- user_locale = ::strdup([nsIdentifier UTF8String]);
- [pool drain];
+ ::free(user_locale);
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
+ NSLocale *myNSLocale = (NSLocale *)myCFLocale;
+ [myNSLocale autorelease];
+ NSString *nsIdentifier = [myNSLocale localeIdentifier];
+ user_locale = ::strdup([nsIdentifier UTF8String]);
+ [pool drain];
- return user_locale;
+ return user_locale;
}
diff --git a/intern/memutil/CMakeLists.txt b/intern/memutil/CMakeLists.txt
index dc1cf0e0ebf..567e5d63ff9 100644
--- a/intern/memutil/CMakeLists.txt
+++ b/intern/memutil/CMakeLists.txt
@@ -19,8 +19,8 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ..
+ .
+ ..
)
set(INC_SYS
@@ -28,14 +28,14 @@ set(INC_SYS
)
set(SRC
- intern/MEM_CacheLimiterC-Api.cpp
- intern/MEM_RefCountedC-Api.cpp
+ intern/MEM_CacheLimiterC-Api.cpp
+ intern/MEM_RefCountedC-Api.cpp
- MEM_Allocator.h
- MEM_CacheLimiter.h
- MEM_CacheLimiterC-Api.h
- MEM_RefCounted.h
- MEM_RefCountedC-Api.h
+ MEM_Allocator.h
+ MEM_CacheLimiter.h
+ MEM_CacheLimiterC-Api.h
+ MEM_RefCounted.h
+ MEM_RefCountedC-Api.h
)
set(LIB
diff --git a/intern/memutil/MEM_Allocator.h b/intern/memutil/MEM_Allocator.h
index 229a7c46b2c..dc7ddcefeeb 100644
--- a/intern/memutil/MEM_Allocator.h
+++ b/intern/memutil/MEM_Allocator.h
@@ -18,68 +18,80 @@
* \ingroup memutil
*/
-
#ifndef __MEM_ALLOCATOR_H__
#define __MEM_ALLOCATOR_H__
#include <stddef.h>
#include "guardedalloc/MEM_guardedalloc.h"
-template<typename _Tp>
-struct MEM_Allocator
-{
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Tp* pointer;
- typedef const _Tp* const_pointer;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
- typedef _Tp value_type;
-
- template<typename _Tp1>
- struct rebind {
- typedef MEM_Allocator<_Tp1> other;
- };
-
- MEM_Allocator() throw() {}
- MEM_Allocator(const MEM_Allocator&) throw() {}
-
- template<typename _Tp1>
- MEM_Allocator(const MEM_Allocator<_Tp1>) throw() { }
-
- ~MEM_Allocator() throw() {}
-
- pointer address(reference __x) const { return &__x; }
-
- const_pointer address(const_reference __x) const { return &__x; }
-
- // NB: __n is permitted to be 0. The C++ standard says nothing
- // about what the return value is when __n == 0.
- _Tp* allocate(size_type __n, const void* = 0) {
- _Tp* __ret = NULL;
- if (__n)
- __ret = static_cast<_Tp*>(
- MEM_mallocN(__n * sizeof(_Tp),
- "STL MEM_Allocator"));
- return __ret;
- }
-
- // __p is not permitted to be a null pointer.
- void deallocate(pointer __p, size_type) {
- MEM_freeN(__p);
- }
-
- size_type max_size() const throw() {
- return size_t(-1) / sizeof(_Tp);
- }
-
- void construct(pointer __p, const _Tp& __val) {
- new(__p) _Tp(__val);
- }
-
- void destroy(pointer __p) {
- __p->~_Tp();
- }
+template<typename _Tp> struct MEM_Allocator {
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp *pointer;
+ typedef const _Tp *const_pointer;
+ typedef _Tp &reference;
+ typedef const _Tp &const_reference;
+ typedef _Tp value_type;
+
+ template<typename _Tp1> struct rebind {
+ typedef MEM_Allocator<_Tp1> other;
+ };
+
+ MEM_Allocator() throw()
+ {
+ }
+ MEM_Allocator(const MEM_Allocator &) throw()
+ {
+ }
+
+ template<typename _Tp1> MEM_Allocator(const MEM_Allocator<_Tp1>) throw()
+ {
+ }
+
+ ~MEM_Allocator() throw()
+ {
+ }
+
+ pointer address(reference __x) const
+ {
+ return &__x;
+ }
+
+ const_pointer address(const_reference __x) const
+ {
+ return &__x;
+ }
+
+ // NB: __n is permitted to be 0. The C++ standard says nothing
+ // about what the return value is when __n == 0.
+ _Tp *allocate(size_type __n, const void * = 0)
+ {
+ _Tp *__ret = NULL;
+ if (__n)
+ __ret = static_cast<_Tp *>(MEM_mallocN(__n * sizeof(_Tp), "STL MEM_Allocator"));
+ return __ret;
+ }
+
+ // __p is not permitted to be a null pointer.
+ void deallocate(pointer __p, size_type)
+ {
+ MEM_freeN(__p);
+ }
+
+ size_type max_size() const throw()
+ {
+ return size_t(-1) / sizeof(_Tp);
+ }
+
+ void construct(pointer __p, const _Tp &__val)
+ {
+ new (__p) _Tp(__val);
+ }
+
+ void destroy(pointer __p)
+ {
+ __p->~_Tp();
+ }
};
-#endif // __MEM_ALLOCATOR_H__
+#endif // __MEM_ALLOCATOR_H__
diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index 89d6a9b79d2..a13c3f518db 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -18,7 +18,6 @@
* \ingroup memutil
*/
-
#ifndef __MEM_CACHELIMITER_H__
#define __MEM_CACHELIMITER_H__
@@ -59,252 +58,267 @@
#include <vector>
#include "MEM_Allocator.h"
-template<class T>
-class MEM_CacheLimiter;
+template<class T> class MEM_CacheLimiter;
#ifndef __MEM_CACHELIMITERC_API_H__
extern "C" {
- void MEM_CacheLimiter_set_maximum(size_t m);
- size_t MEM_CacheLimiter_get_maximum();
- void MEM_CacheLimiter_set_disabled(bool disabled);
- bool MEM_CacheLimiter_is_disabled(void);
+void MEM_CacheLimiter_set_maximum(size_t m);
+size_t MEM_CacheLimiter_get_maximum();
+void MEM_CacheLimiter_set_disabled(bool disabled);
+bool MEM_CacheLimiter_is_disabled(void);
};
#endif
-template<class T>
-class MEM_CacheLimiterHandle {
-public:
- explicit MEM_CacheLimiterHandle(T * data_,MEM_CacheLimiter<T> *parent_) :
- data(data_),
- refcount(0),
- parent(parent_)
- { }
-
- void ref() {
- refcount++;
- }
-
- void unref() {
- refcount--;
- }
-
- T *get() {
- return data;
- }
-
- const T *get() const {
- return data;
- }
-
- int get_refcount() const {
- return refcount;
- }
-
- bool can_destroy() const {
- return !data || !refcount;
- }
-
- bool destroy_if_possible() {
- if (can_destroy()) {
- delete data;
- data = NULL;
- unmanage();
- return true;
- }
- return false;
- }
-
- void unmanage() {
- parent->unmanage(this);
- }
-
- void touch() {
- parent->touch(this);
- }
-
-private:
- friend class MEM_CacheLimiter<T>;
-
- T * data;
- int refcount;
- int pos;
- MEM_CacheLimiter<T> * parent;
+template<class T> class MEM_CacheLimiterHandle {
+ public:
+ explicit MEM_CacheLimiterHandle(T *data_, MEM_CacheLimiter<T> *parent_)
+ : data(data_), refcount(0), parent(parent_)
+ {
+ }
+
+ void ref()
+ {
+ refcount++;
+ }
+
+ void unref()
+ {
+ refcount--;
+ }
+
+ T *get()
+ {
+ return data;
+ }
+
+ const T *get() const
+ {
+ return data;
+ }
+
+ int get_refcount() const
+ {
+ return refcount;
+ }
+
+ bool can_destroy() const
+ {
+ return !data || !refcount;
+ }
+
+ bool destroy_if_possible()
+ {
+ if (can_destroy()) {
+ delete data;
+ data = NULL;
+ unmanage();
+ return true;
+ }
+ return false;
+ }
+
+ void unmanage()
+ {
+ parent->unmanage(this);
+ }
+
+ void touch()
+ {
+ parent->touch(this);
+ }
+
+ private:
+ friend class MEM_CacheLimiter<T>;
+
+ T *data;
+ int refcount;
+ int pos;
+ MEM_CacheLimiter<T> *parent;
};
-template<class T>
-class MEM_CacheLimiter {
-public:
- typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
- typedef int (*MEM_CacheLimiter_ItemPriority_Func) (void *item, int default_priority);
- typedef bool (*MEM_CacheLimiter_ItemDestroyable_Func) (void *item);
-
- MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func data_size_func)
- : data_size_func(data_size_func) {
- }
-
- ~MEM_CacheLimiter() {
- int i;
- for (i = 0; i < queue.size(); i++) {
- delete queue[i];
- }
- }
-
- MEM_CacheLimiterHandle<T> *insert(T * elem) {
- queue.push_back(new MEM_CacheLimiterHandle<T>(elem, this));
- queue.back()->pos = queue.size() - 1;
- return queue.back();
- }
-
- void unmanage(MEM_CacheLimiterHandle<T> *handle) {
- int pos = handle->pos;
- queue[pos] = queue.back();
- queue[pos]->pos = pos;
- queue.pop_back();
- delete handle;
- }
-
- size_t get_memory_in_use() {
- size_t size = 0;
- if (data_size_func) {
- int i;
- for (i = 0; i < queue.size(); i++) {
- size += data_size_func(queue[i]->get()->get_data());
- }
- }
- else {
- size = MEM_get_memory_in_use();
- }
- return size;
- }
-
- void enforce_limits() {
- size_t max = MEM_CacheLimiter_get_maximum();
- bool is_disabled = MEM_CacheLimiter_is_disabled();
- size_t mem_in_use, cur_size;
-
- if (is_disabled) {
- return;
- }
-
- if (max == 0) {
- return;
- }
-
- mem_in_use = get_memory_in_use();
-
- if (mem_in_use <= max) {
- return;
- }
-
- while (!queue.empty() && mem_in_use > max) {
- MEM_CacheElementPtr elem = get_least_priority_destroyable_element();
-
- if (!elem)
- break;
-
- if (data_size_func) {
- cur_size = data_size_func(elem->get()->get_data());
- }
- else {
- cur_size = mem_in_use;
- }
-
- if (elem->destroy_if_possible()) {
- if (data_size_func) {
- mem_in_use -= cur_size;
- }
- else {
- mem_in_use -= cur_size - MEM_get_memory_in_use();
- }
- }
- }
- }
-
- void touch(MEM_CacheLimiterHandle<T> * handle) {
- /* If we're using custom priority callback re-arranging the queue
- * doesn't make much sense because we'll iterate it all to get
- * least priority element anyway.
- */
- if (item_priority_func == NULL) {
- queue[handle->pos] = queue.back();
- queue[handle->pos]->pos = handle->pos;
- queue.pop_back();
- queue.push_back(handle);
- handle->pos = queue.size() - 1;
- }
- }
-
- void set_item_priority_func(MEM_CacheLimiter_ItemPriority_Func item_priority_func) {
- this->item_priority_func = item_priority_func;
- }
-
- void set_item_destroyable_func(MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func) {
- this->item_destroyable_func = item_destroyable_func;
- }
-
-private:
- typedef MEM_CacheLimiterHandle<T> *MEM_CacheElementPtr;
- typedef std::vector<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
- typedef typename MEM_CacheQueue::iterator iterator;
-
- /* Check whether element can be destroyed when enforcing cache limits */
- bool can_destroy_element(MEM_CacheElementPtr &elem) {
- if (!elem->can_destroy()) {
- /* Element is referenced */
- return false;
- }
- if (item_destroyable_func) {
- if (!item_destroyable_func(elem->get()->get_data()))
- return false;
- }
- return true;
- }
-
- MEM_CacheElementPtr get_least_priority_destroyable_element(void) {
- if (queue.empty())
- return NULL;
-
- MEM_CacheElementPtr best_match_elem = NULL;
-
- if (!item_priority_func) {
- for (iterator it = queue.begin(); it != queue.end(); it++) {
- MEM_CacheElementPtr elem = *it;
- if (!can_destroy_element(elem))
- continue;
- best_match_elem = elem;
- break;
- }
- }
- else {
- int best_match_priority = 0;
- int i;
-
- for (i = 0; i < queue.size(); i++) {
- MEM_CacheElementPtr elem = queue[i];
-
- if (!can_destroy_element(elem))
- continue;
-
- /* by default 0 means highest priority element */
- /* casting a size type to int is questionable,
- but unlikely to cause problems */
- int priority = -((int)(queue.size()) - i - 1);
- priority = item_priority_func(elem->get()->get_data(), priority);
-
- if (priority < best_match_priority || best_match_elem == NULL) {
- best_match_priority = priority;
- best_match_elem = elem;
- }
- }
- }
-
- return best_match_elem;
- }
-
- MEM_CacheQueue queue;
- MEM_CacheLimiter_DataSize_Func data_size_func;
- MEM_CacheLimiter_ItemPriority_Func item_priority_func;
- MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func;
+template<class T> class MEM_CacheLimiter {
+ public:
+ typedef size_t (*MEM_CacheLimiter_DataSize_Func)(void *data);
+ typedef int (*MEM_CacheLimiter_ItemPriority_Func)(void *item, int default_priority);
+ typedef bool (*MEM_CacheLimiter_ItemDestroyable_Func)(void *item);
+
+ MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func data_size_func) : data_size_func(data_size_func)
+ {
+ }
+
+ ~MEM_CacheLimiter()
+ {
+ int i;
+ for (i = 0; i < queue.size(); i++) {
+ delete queue[i];
+ }
+ }
+
+ MEM_CacheLimiterHandle<T> *insert(T *elem)
+ {
+ queue.push_back(new MEM_CacheLimiterHandle<T>(elem, this));
+ queue.back()->pos = queue.size() - 1;
+ return queue.back();
+ }
+
+ void unmanage(MEM_CacheLimiterHandle<T> *handle)
+ {
+ int pos = handle->pos;
+ queue[pos] = queue.back();
+ queue[pos]->pos = pos;
+ queue.pop_back();
+ delete handle;
+ }
+
+ size_t get_memory_in_use()
+ {
+ size_t size = 0;
+ if (data_size_func) {
+ int i;
+ for (i = 0; i < queue.size(); i++) {
+ size += data_size_func(queue[i]->get()->get_data());
+ }
+ }
+ else {
+ size = MEM_get_memory_in_use();
+ }
+ return size;
+ }
+
+ void enforce_limits()
+ {
+ size_t max = MEM_CacheLimiter_get_maximum();
+ bool is_disabled = MEM_CacheLimiter_is_disabled();
+ size_t mem_in_use, cur_size;
+
+ if (is_disabled) {
+ return;
+ }
+
+ if (max == 0) {
+ return;
+ }
+
+ mem_in_use = get_memory_in_use();
+
+ if (mem_in_use <= max) {
+ return;
+ }
+
+ while (!queue.empty() && mem_in_use > max) {
+ MEM_CacheElementPtr elem = get_least_priority_destroyable_element();
+
+ if (!elem)
+ break;
+
+ if (data_size_func) {
+ cur_size = data_size_func(elem->get()->get_data());
+ }
+ else {
+ cur_size = mem_in_use;
+ }
+
+ if (elem->destroy_if_possible()) {
+ if (data_size_func) {
+ mem_in_use -= cur_size;
+ }
+ else {
+ mem_in_use -= cur_size - MEM_get_memory_in_use();
+ }
+ }
+ }
+ }
+
+ void touch(MEM_CacheLimiterHandle<T> *handle)
+ {
+ /* If we're using custom priority callback re-arranging the queue
+ * doesn't make much sense because we'll iterate it all to get
+ * least priority element anyway.
+ */
+ if (item_priority_func == NULL) {
+ queue[handle->pos] = queue.back();
+ queue[handle->pos]->pos = handle->pos;
+ queue.pop_back();
+ queue.push_back(handle);
+ handle->pos = queue.size() - 1;
+ }
+ }
+
+ void set_item_priority_func(MEM_CacheLimiter_ItemPriority_Func item_priority_func)
+ {
+ this->item_priority_func = item_priority_func;
+ }
+
+ void set_item_destroyable_func(MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func)
+ {
+ this->item_destroyable_func = item_destroyable_func;
+ }
+
+ private:
+ typedef MEM_CacheLimiterHandle<T> *MEM_CacheElementPtr;
+ typedef std::vector<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr>> MEM_CacheQueue;
+ typedef typename MEM_CacheQueue::iterator iterator;
+
+ /* Check whether element can be destroyed when enforcing cache limits */
+ bool can_destroy_element(MEM_CacheElementPtr &elem)
+ {
+ if (!elem->can_destroy()) {
+ /* Element is referenced */
+ return false;
+ }
+ if (item_destroyable_func) {
+ if (!item_destroyable_func(elem->get()->get_data()))
+ return false;
+ }
+ return true;
+ }
+
+ MEM_CacheElementPtr get_least_priority_destroyable_element(void)
+ {
+ if (queue.empty())
+ return NULL;
+
+ MEM_CacheElementPtr best_match_elem = NULL;
+
+ if (!item_priority_func) {
+ for (iterator it = queue.begin(); it != queue.end(); it++) {
+ MEM_CacheElementPtr elem = *it;
+ if (!can_destroy_element(elem))
+ continue;
+ best_match_elem = elem;
+ break;
+ }
+ }
+ else {
+ int best_match_priority = 0;
+ int i;
+
+ for (i = 0; i < queue.size(); i++) {
+ MEM_CacheElementPtr elem = queue[i];
+
+ if (!can_destroy_element(elem))
+ continue;
+
+ /* by default 0 means highest priority element */
+ /* casting a size type to int is questionable,
+ but unlikely to cause problems */
+ int priority = -((int)(queue.size()) - i - 1);
+ priority = item_priority_func(elem->get()->get_data(), priority);
+
+ if (priority < best_match_priority || best_match_elem == NULL) {
+ best_match_priority = priority;
+ best_match_elem = elem;
+ }
+ }
+ }
+
+ return best_match_elem;
+ }
+
+ MEM_CacheQueue queue;
+ MEM_CacheLimiter_DataSize_Func data_size_func;
+ MEM_CacheLimiter_ItemPriority_Func item_priority_func;
+ MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func;
};
#endif // __MEM_CACHELIMITER_H__
diff --git a/intern/memutil/MEM_CacheLimiterC-Api.h b/intern/memutil/MEM_CacheLimiterC-Api.h
index b0446c066f3..7ea3821d5ed 100644
--- a/intern/memutil/MEM_CacheLimiterC-Api.h
+++ b/intern/memutil/MEM_CacheLimiterC-Api.h
@@ -18,7 +18,6 @@
* \ingroup memutil
*/
-
#ifndef __MEM_CACHELIMITERC_API_H__
#define __MEM_CACHELIMITERC_API_H__
@@ -33,16 +32,16 @@ typedef struct MEM_CacheLimiter_s MEM_CacheLimiterC;
typedef struct MEM_CacheLimiterHandle_s MEM_CacheLimiterHandleC;
/* function used to remove data from memory */
-typedef void (*MEM_CacheLimiter_Destruct_Func)(void*);
+typedef void (*MEM_CacheLimiter_Destruct_Func)(void *);
/* function used to measure stored data element size */
-typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void*);
+typedef size_t (*MEM_CacheLimiter_DataSize_Func)(void *);
/* function used to measure priority of item when freeing memory */
-typedef int (*MEM_CacheLimiter_ItemPriority_Func) (void*, int);
+typedef int (*MEM_CacheLimiter_ItemPriority_Func)(void *, int);
/* function to check whether item could be destroyed */
-typedef bool (*MEM_CacheLimiter_ItemDestroyable_Func) (void*);
+typedef bool (*MEM_CacheLimiter_ItemDestroyable_Func)(void *);
#ifndef __MEM_CACHELIMITER_H__
void MEM_CacheLimiter_set_maximum(size_t m);
@@ -60,7 +59,7 @@ bool MEM_CacheLimiter_is_disabled(void);
*/
MEM_CacheLimiterC *new_MEM_CacheLimiter(MEM_CacheLimiter_Destruct_Func data_destructor,
- MEM_CacheLimiter_DataSize_Func data_size);
+ MEM_CacheLimiter_DataSize_Func data_size);
/**
* Delete MEM_CacheLimiter
@@ -98,7 +97,6 @@ void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC *This);
void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC *handle);
-
/**
* Raise priority of object (put it at the tail of the deletion chain)
*
@@ -144,8 +142,8 @@ void *MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle);
void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
MEM_CacheLimiter_ItemPriority_Func item_priority_func);
-void MEM_CacheLimiter_ItemDestroyable_Func_set(MEM_CacheLimiterC *This,
- MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func);
+void MEM_CacheLimiter_ItemDestroyable_Func_set(
+ MEM_CacheLimiterC *This, MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func);
size_t MEM_CacheLimiter_get_memory_in_use(MEM_CacheLimiterC *This);
@@ -153,5 +151,4 @@ size_t MEM_CacheLimiter_get_memory_in_use(MEM_CacheLimiterC *This);
}
#endif
-
-#endif // __MEM_CACHELIMITERC_API_H__
+#endif // __MEM_CACHELIMITERC_API_H__
diff --git a/intern/memutil/MEM_RefCounted.h b/intern/memutil/MEM_RefCounted.h
index 0dccf790caa..28b24d04586 100644
--- a/intern/memutil/MEM_RefCounted.h
+++ b/intern/memutil/MEM_RefCounted.h
@@ -34,71 +34,70 @@
* The default destructor of this object has been made protected on purpose.
* This disables the creation of shared objects on the stack.
*
- * @author Maarten Gribnau
- * @date March 31, 2001
+ * @author Maarten Gribnau
+ * @date March 31, 2001
*/
class MEM_RefCounted {
-public:
- /**
- * Constructs a a shared object.
- */
- MEM_RefCounted() : m_refCount(1)
- {
- }
+ public:
+ /**
+ * Constructs a a shared object.
+ */
+ MEM_RefCounted() : m_refCount(1)
+ {
+ }
- /**
- * Returns the reference count of this object.
- * @return the reference count.
- */
- inline virtual int getRef() const;
+ /**
+ * Returns the reference count of this object.
+ * @return the reference count.
+ */
+ inline virtual int getRef() const;
- /**
- * Increases the reference count of this object.
- * @return the new reference count.
- */
- inline virtual int incRef();
+ /**
+ * Increases the reference count of this object.
+ * @return the new reference count.
+ */
+ inline virtual int incRef();
- /**
- * Decreases the reference count of this object.
- * If the reference count reaches zero, the object self-destructs.
- * @return the new reference count.
- */
- inline virtual int decRef();
+ /**
+ * Decreases the reference count of this object.
+ * If the reference count reaches zero, the object self-destructs.
+ * @return the new reference count.
+ */
+ inline virtual int decRef();
-protected:
- /**
- * Destructs a shared object.
- * The destructor is protected to force the use of incRef and decRef.
- */
- virtual ~MEM_RefCounted()
- {
- }
+ protected:
+ /**
+ * Destructs a shared object.
+ * The destructor is protected to force the use of incRef and decRef.
+ */
+ virtual ~MEM_RefCounted()
+ {
+ }
-protected:
- /// The reference count.
- int m_refCount;
+ protected:
+ /// The reference count.
+ int m_refCount;
};
-
inline int MEM_RefCounted::getRef() const
{
- return m_refCount;
+ return m_refCount;
}
inline int MEM_RefCounted::incRef()
{
- return ++m_refCount;
+ return ++m_refCount;
}
inline int MEM_RefCounted::decRef()
{
- m_refCount--;
- if (m_refCount == 0) {
- delete this;
- return 0;
- }
- return m_refCount;
+ m_refCount--;
+ if (m_refCount == 0) {
+ delete this;
+ return 0;
+ }
+ return m_refCount;
}
-#endif // __MEM_REFCOUNTED_H__
+#endif // __MEM_REFCOUNTED_H__
diff --git a/intern/memutil/MEM_RefCountedC-Api.h b/intern/memutil/MEM_RefCountedC-Api.h
index 986ddb01a65..25dcf11b7aa 100644
--- a/intern/memutil/MEM_RefCountedC-Api.h
+++ b/intern/memutil/MEM_RefCountedC-Api.h
@@ -27,29 +27,27 @@
#define __MEM_REFCOUNTEDC_API_H__
/** A pointer to a private object. */
-typedef struct MEM_TOpaqueObject* MEM_TObjectPtr;
+typedef struct MEM_TOpaqueObject *MEM_TObjectPtr;
/** A pointer to a shared object. */
typedef MEM_TObjectPtr MEM_TRefCountedObjectPtr;
-
#ifdef __cplusplus
extern "C" {
#endif
-
/**
* Returns the reference count of this object.
* @param shared The object to query.
* @return The current reference count.
*/
-extern int MEM_RefCountedGetRef(MEM_TRefCountedObjectPtr shared);
+extern int MEM_RefCountedGetRef(MEM_TRefCountedObjectPtr shared);
/**
* Increases the reference count of this object.
* @param shared The object to query.
* @return The new reference count.
*/
-extern int MEM_RefCountedIncRef(MEM_TRefCountedObjectPtr shared);
+extern int MEM_RefCountedIncRef(MEM_TRefCountedObjectPtr shared);
/**
* Decreases the reference count of this object.
@@ -57,11 +55,10 @@ extern int MEM_RefCountedIncRef(MEM_TRefCountedObjectPtr shared);
* @param shared The object to query.
* @return The new reference count.
*/
-extern int MEM_RefCountedDecRef(MEM_TRefCountedObjectPtr shared);
-
+extern int MEM_RefCountedDecRef(MEM_TRefCountedObjectPtr shared);
#ifdef __cplusplus
}
#endif
-#endif // __MEM_REFCOUNTEDC_API_H__
+#endif // __MEM_REFCOUNTEDC_API_H__
diff --git a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
index 8bcbf3eebf5..9f583c948ee 100644
--- a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
+++ b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
@@ -25,30 +25,30 @@
static bool is_disabled = false;
-static size_t & get_max()
+static size_t &get_max()
{
- static size_t m = 32 * 1024 * 1024;
- return m;
+ static size_t m = 32 * 1024 * 1024;
+ return m;
}
void MEM_CacheLimiter_set_maximum(size_t m)
{
- get_max() = m;
+ get_max() = m;
}
size_t MEM_CacheLimiter_get_maximum()
{
- return get_max();
+ return get_max();
}
void MEM_CacheLimiter_set_disabled(bool disabled)
{
- is_disabled = disabled;
+ is_disabled = disabled;
}
bool MEM_CacheLimiter_is_disabled(void)
{
- return is_disabled;
+ return is_disabled;
}
class MEM_CacheLimiterHandleCClass;
@@ -56,166 +56,174 @@ class MEM_CacheLimiterCClass;
typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t;
typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t;
-typedef std::list<MEM_CacheLimiterHandleCClass*, MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t;
+typedef std::list<MEM_CacheLimiterHandleCClass *, MEM_Allocator<MEM_CacheLimiterHandleCClass *>>
+ list_t;
class MEM_CacheLimiterCClass {
-public:
- MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_, MEM_CacheLimiter_DataSize_Func data_size)
- : data_destructor(data_destructor_), cache(data_size) {
- }
- ~MEM_CacheLimiterCClass();
+ public:
+ MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_,
+ MEM_CacheLimiter_DataSize_Func data_size)
+ : data_destructor(data_destructor_), cache(data_size)
+ {
+ }
+ ~MEM_CacheLimiterCClass();
- handle_t * insert(void *data);
+ handle_t *insert(void *data);
- void destruct(void *data, list_t::iterator it);
+ void destruct(void *data, list_t::iterator it);
- cache_t * get_cache() {
- return &cache;
- }
-private:
- MEM_CacheLimiter_Destruct_Func data_destructor;
+ cache_t *get_cache()
+ {
+ return &cache;
+ }
- MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache;
+ private:
+ MEM_CacheLimiter_Destruct_Func data_destructor;
- list_t cclass_list;
+ MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache;
+
+ list_t cclass_list;
};
class MEM_CacheLimiterHandleCClass {
-public:
- MEM_CacheLimiterHandleCClass(void *data_, MEM_CacheLimiterCClass *parent_) :
- data(data_),
- parent(parent_)
- { }
-
- ~MEM_CacheLimiterHandleCClass();
-
- void set_iter(list_t::iterator it_) {
- it = it_;
- }
-
- void set_data(void *data_) {
- data = data_;
- }
-
- void *get_data() const {
- return data;
- }
-
-private:
- void *data;
- MEM_CacheLimiterCClass *parent;
- list_t::iterator it;
+ public:
+ MEM_CacheLimiterHandleCClass(void *data_, MEM_CacheLimiterCClass *parent_)
+ : data(data_), parent(parent_)
+ {
+ }
+
+ ~MEM_CacheLimiterHandleCClass();
+
+ void set_iter(list_t::iterator it_)
+ {
+ it = it_;
+ }
+
+ void set_data(void *data_)
+ {
+ data = data_;
+ }
+
+ void *get_data() const
+ {
+ return data;
+ }
+
+ private:
+ void *data;
+ MEM_CacheLimiterCClass *parent;
+ list_t::iterator it;
};
handle_t *MEM_CacheLimiterCClass::insert(void *data)
{
- cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
- list_t::iterator it = cclass_list.end();
- --it;
- cclass_list.back()->set_iter(it);
+ cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
+ list_t::iterator it = cclass_list.end();
+ --it;
+ cclass_list.back()->set_iter(it);
- return cache.insert(cclass_list.back());
+ return cache.insert(cclass_list.back());
}
void MEM_CacheLimiterCClass::destruct(void *data, list_t::iterator it)
{
- data_destructor(data);
- cclass_list.erase(it);
+ data_destructor(data);
+ cclass_list.erase(it);
}
MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass()
{
- if (data) {
- parent->destruct(data, it);
- }
+ if (data) {
+ parent->destruct(data, it);
+ }
}
MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass()
{
- // should not happen, but don't leak memory in this case...
- for (list_t::iterator it = cclass_list.begin(); it != cclass_list.end(); it++) {
- (*it)->set_data(NULL);
+ // should not happen, but don't leak memory in this case...
+ for (list_t::iterator it = cclass_list.begin(); it != cclass_list.end(); it++) {
+ (*it)->set_data(NULL);
- delete *it;
- }
+ delete *it;
+ }
}
// ----------------------------------------------------------------------
static inline MEM_CacheLimiterCClass *cast(MEM_CacheLimiterC *l)
{
- return (MEM_CacheLimiterCClass *) l;
+ return (MEM_CacheLimiterCClass *)l;
}
static inline handle_t *cast(MEM_CacheLimiterHandleC *l)
{
- return (handle_t *) l;
+ return (handle_t *)l;
}
MEM_CacheLimiterC *new_MEM_CacheLimiter(MEM_CacheLimiter_Destruct_Func data_destructor,
MEM_CacheLimiter_DataSize_Func data_size)
{
- return (MEM_CacheLimiterC *) new MEM_CacheLimiterCClass(data_destructor, data_size);
+ return (MEM_CacheLimiterC *)new MEM_CacheLimiterCClass(data_destructor, data_size);
}
void delete_MEM_CacheLimiter(MEM_CacheLimiterC *This)
{
- delete cast(This);
+ delete cast(This);
}
MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC *This, void *data)
{
- return (MEM_CacheLimiterHandleC *) cast(This)->insert(data);
+ return (MEM_CacheLimiterHandleC *)cast(This)->insert(data);
}
void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC *This)
{
- cast(This)->get_cache()->enforce_limits();
+ cast(This)->get_cache()->enforce_limits();
}
void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC *handle)
{
- cast(handle)->unmanage();
+ cast(handle)->unmanage();
}
void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC *handle)
{
- cast(handle)->touch();
+ cast(handle)->touch();
}
void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC *handle)
{
- cast(handle)->ref();
+ cast(handle)->ref();
}
void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC *handle)
{
- cast(handle)->unref();
+ cast(handle)->unref();
}
int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC *handle)
{
- return cast(handle)->get_refcount();
+ return cast(handle)->get_refcount();
}
void *MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle)
{
- return cast(handle)->get()->get_data();
+ return cast(handle)->get()->get_data();
}
void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
MEM_CacheLimiter_ItemPriority_Func item_priority_func)
{
- cast(This)->get_cache()->set_item_priority_func(item_priority_func);
+ cast(This)->get_cache()->set_item_priority_func(item_priority_func);
}
-void MEM_CacheLimiter_ItemDestroyable_Func_set(MEM_CacheLimiterC *This,
- MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func)
+void MEM_CacheLimiter_ItemDestroyable_Func_set(
+ MEM_CacheLimiterC *This, MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func)
{
- cast(This)->get_cache()->set_item_destroyable_func(item_destroyable_func);
+ cast(This)->get_cache()->set_item_destroyable_func(item_destroyable_func);
}
size_t MEM_CacheLimiter_get_memory_in_use(MEM_CacheLimiterC *This)
{
- return cast(This)->get_cache()->get_memory_in_use();
+ return cast(This)->get_cache()->get_memory_in_use();
}
diff --git a/intern/memutil/intern/MEM_RefCountedC-Api.cpp b/intern/memutil/intern/MEM_RefCountedC-Api.cpp
index 27195e25f82..c319d6321f4 100644
--- a/intern/memutil/intern/MEM_RefCountedC-Api.cpp
+++ b/intern/memutil/intern/MEM_RefCountedC-Api.cpp
@@ -21,25 +21,20 @@
* \ingroup memutil
*/
-
#include "MEM_RefCountedC-Api.h"
#include "MEM_RefCounted.h"
-
-
int MEM_RefCountedGetRef(MEM_TRefCountedObjectPtr shared)
{
- return shared ? ((MEM_RefCounted*)shared)->getRef() : 0;
+ return shared ? ((MEM_RefCounted *)shared)->getRef() : 0;
}
-
int MEM_RefCountedIncRef(MEM_TRefCountedObjectPtr shared)
{
- return shared ? ((MEM_RefCounted*)shared)->incRef() : 0;
+ return shared ? ((MEM_RefCounted *)shared)->incRef() : 0;
}
-
int MEM_RefCountedDecRef(MEM_TRefCountedObjectPtr shared)
{
- return shared ? ((MEM_RefCounted*)shared)->decRef() : 0;
+ return shared ? ((MEM_RefCounted *)shared)->decRef() : 0;
}
diff --git a/intern/mikktspace/CMakeLists.txt b/intern/mikktspace/CMakeLists.txt
index 1dc508a66a4..44680b5fc57 100644
--- a/intern/mikktspace/CMakeLists.txt
+++ b/intern/mikktspace/CMakeLists.txt
@@ -19,14 +19,14 @@
# ***** END GPL LICENSE BLOCK *****
if(CMAKE_COMPILER_IS_GNUCC)
- remove_cc_flag(
- "-Wshadow"
- "-Werror=shadow"
- )
+ remove_cc_flag(
+ "-Wshadow"
+ "-Werror=shadow"
+ )
endif()
set(INC
- .
+ .
)
set(INC_SYS
@@ -34,9 +34,9 @@ set(INC_SYS
)
set(SRC
- mikktspace.c
+ mikktspace.c
- mikktspace.h
+ mikktspace.h
)
set(LIB
diff --git a/intern/mikktspace/mikktspace.c b/intern/mikktspace/mikktspace.c
index 8721d4c669d..1ea17c273ed 100644
--- a/intern/mikktspace/mikktspace.c
+++ b/intern/mikktspace/mikktspace.c
@@ -30,14 +30,14 @@
#include "mikktspace.h"
-#define TFALSE 0
-#define TTRUE 1
+#define TFALSE 0
+#define TTRUE 1
#ifndef M_PI
-#define M_PI 3.1415926535897932384626433832795
+# define M_PI 3.1415926535897932384626433832795
#endif
-#define INTERNAL_RND_SORT_SEED 39871946
+#define INTERNAL_RND_SORT_SEED 39871946
#ifdef _MSC_VER
# define MIKK_INLINE static __forceinline
@@ -47,444 +47,468 @@
// internal structure
typedef struct {
- float x, y, z;
+ float x, y, z;
} SVec3;
-MIKK_INLINE tbool veq( const SVec3 v1, const SVec3 v2 )
+MIKK_INLINE tbool veq(const SVec3 v1, const SVec3 v2)
{
- return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z);
+ return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z);
}
-MIKK_INLINE SVec3 vadd( const SVec3 v1, const SVec3 v2 )
+MIKK_INLINE SVec3 vadd(const SVec3 v1, const SVec3 v2)
{
- SVec3 vRes;
+ SVec3 vRes;
- vRes.x = v1.x + v2.x;
- vRes.y = v1.y + v2.y;
- vRes.z = v1.z + v2.z;
+ vRes.x = v1.x + v2.x;
+ vRes.y = v1.y + v2.y;
+ vRes.z = v1.z + v2.z;
- return vRes;
+ return vRes;
}
-
-MIKK_INLINE SVec3 vsub( const SVec3 v1, const SVec3 v2 )
+MIKK_INLINE SVec3 vsub(const SVec3 v1, const SVec3 v2)
{
- SVec3 vRes;
+ SVec3 vRes;
- vRes.x = v1.x - v2.x;
- vRes.y = v1.y - v2.y;
- vRes.z = v1.z - v2.z;
+ vRes.x = v1.x - v2.x;
+ vRes.y = v1.y - v2.y;
+ vRes.z = v1.z - v2.z;
- return vRes;
+ return vRes;
}
-MIKK_INLINE SVec3 vscale(const float fS, const SVec3 v)
+MIKK_INLINE SVec3 vscale(const float fS, const SVec3 v)
{
- SVec3 vRes;
+ SVec3 vRes;
- vRes.x = fS * v.x;
- vRes.y = fS * v.y;
- vRes.z = fS * v.z;
+ vRes.x = fS * v.x;
+ vRes.y = fS * v.y;
+ vRes.z = fS * v.z;
- return vRes;
+ return vRes;
}
-MIKK_INLINE float LengthSquared( const SVec3 v )
+MIKK_INLINE float LengthSquared(const SVec3 v)
{
- return v.x*v.x + v.y*v.y + v.z*v.z;
+ return v.x * v.x + v.y * v.y + v.z * v.z;
}
-MIKK_INLINE float Length( const SVec3 v )
+MIKK_INLINE float Length(const SVec3 v)
{
- return sqrtf(LengthSquared(v));
+ return sqrtf(LengthSquared(v));
}
#if 0 // UNUSED
-MIKK_INLINE SVec3 Normalize( const SVec3 v )
+MIKK_INLINE SVec3 Normalize( const SVec3 v )
{
- return vscale(1.0f / Length(v), v);
+ return vscale(1.0f / Length(v), v);
}
#endif
-MIKK_INLINE SVec3 NormalizeSafe( const SVec3 v )
+MIKK_INLINE SVec3 NormalizeSafe(const SVec3 v)
{
- const float len = Length(v);
- if (len != 0.0f) {
- return vscale(1.0f / len, v);
- }
- else
- {
- return v;
- }
+ const float len = Length(v);
+ if (len != 0.0f) {
+ return vscale(1.0f / len, v);
+ }
+ else {
+ return v;
+ }
}
-MIKK_INLINE float vdot( const SVec3 v1, const SVec3 v2)
+MIKK_INLINE float vdot(const SVec3 v1, const SVec3 v2)
{
- return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
+ return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
-
MIKK_INLINE tbool NotZero(const float fX)
{
- // could possibly use FLT_EPSILON instead
- return fabsf(fX) > FLT_MIN;
+ // could possibly use FLT_EPSILON instead
+ return fabsf(fX) > FLT_MIN;
}
#if 0 // UNUSED
MIKK_INLINE tbool VNotZero(const SVec3 v)
{
- // might change this to an epsilon based test
- return NotZero(v.x) || NotZero(v.y) || NotZero(v.z);
+ // might change this to an epsilon based test
+ return NotZero(v.x) || NotZero(v.y) || NotZero(v.z);
}
#endif
-
typedef struct {
- int iNrFaces;
- int * pTriMembers;
+ int iNrFaces;
+ int *pTriMembers;
} SSubGroup;
typedef struct {
- int iNrFaces;
- int * pFaceIndices;
- int iVertexRepresentitive;
- tbool bOrientPreservering;
+ int iNrFaces;
+ int *pFaceIndices;
+ int iVertexRepresentitive;
+ tbool bOrientPreservering;
} SGroup;
-//
-#define MARK_DEGENERATE 1
-#define QUAD_ONE_DEGEN_TRI 2
-#define GROUP_WITH_ANY 4
-#define ORIENT_PRESERVING 8
+//
+#define MARK_DEGENERATE 1
+#define QUAD_ONE_DEGEN_TRI 2
+#define GROUP_WITH_ANY 4
+#define ORIENT_PRESERVING 8
+typedef struct {
+ int FaceNeighbors[3];
+ SGroup *AssignedGroup[3];
+ // normalized first order face derivatives
+ SVec3 vOs, vOt;
+ float fMagS, fMagT; // original magnitudes
-typedef struct {
- int FaceNeighbors[3];
- SGroup * AssignedGroup[3];
-
- // normalized first order face derivatives
- SVec3 vOs, vOt;
- float fMagS, fMagT; // original magnitudes
-
- // determines if the current and the next triangle are a quad.
- int iOrgFaceNumber;
- int iFlag, iTSpacesOffs;
- unsigned char vert_num[4];
+ // determines if the current and the next triangle are a quad.
+ int iOrgFaceNumber;
+ int iFlag, iTSpacesOffs;
+ unsigned char vert_num[4];
} STriInfo;
typedef struct {
- SVec3 vOs;
- float fMagS;
- SVec3 vOt;
- float fMagT;
- int iCounter; // this is to average back into quads.
- tbool bOrient;
+ SVec3 vOs;
+ float fMagS;
+ SVec3 vOt;
+ float fMagT;
+ int iCounter; // this is to average back into quads.
+ tbool bOrient;
} STSpace;
-static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
-static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
-static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
-static int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn);
-static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
- const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
- const SMikkTSpaceContext * pContext);
+static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[],
+ int piTriList_out[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn);
+static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn);
+static void InitTriInfo(STriInfo pTriInfos[],
+ const int piTriListIn[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn);
+static int Build4RuleGroups(STriInfo pTriInfos[],
+ SGroup pGroups[],
+ int piGroupTrianglesBuffer[],
+ const int piTriListIn[],
+ const int iNrTrianglesIn);
+static tbool GenerateTSpaces(STSpace psTspace[],
+ const STriInfo pTriInfos[],
+ const SGroup pGroups[],
+ const int iNrActiveGroups,
+ const int piTriListIn[],
+ const float fThresCos,
+ const SMikkTSpaceContext *pContext);
MIKK_INLINE int MakeIndex(const int iFace, const int iVert)
{
- assert(iVert>=0 && iVert<4 && iFace>=0);
- return (iFace<<2) | (iVert&0x3);
+ assert(iVert >= 0 && iVert < 4 && iFace >= 0);
+ return (iFace << 2) | (iVert & 0x3);
}
-MIKK_INLINE void IndexToData(int * piFace, int * piVert, const int iIndexIn)
+MIKK_INLINE void IndexToData(int *piFace, int *piVert, const int iIndexIn)
{
- piVert[0] = iIndexIn&0x3;
- piFace[0] = iIndexIn>>2;
+ piVert[0] = iIndexIn & 0x3;
+ piFace[0] = iIndexIn >> 2;
}
-static STSpace AvgTSpace(const STSpace * pTS0, const STSpace * pTS1)
+static STSpace AvgTSpace(const STSpace *pTS0, const STSpace *pTS1)
{
- STSpace ts_res;
-
- // this if is important. Due to floating point precision
- // averaging when ts0==ts1 will cause a slight difference
- // which results in tangent space splits later on
- if (pTS0->fMagS==pTS1->fMagS && pTS0->fMagT==pTS1->fMagT &&
- veq(pTS0->vOs,pTS1->vOs) && veq(pTS0->vOt, pTS1->vOt))
- {
- ts_res.fMagS = pTS0->fMagS;
- ts_res.fMagT = pTS0->fMagT;
- ts_res.vOs = pTS0->vOs;
- ts_res.vOt = pTS0->vOt;
- }
- else
- {
- ts_res.fMagS = 0.5f*(pTS0->fMagS+pTS1->fMagS);
- ts_res.fMagT = 0.5f*(pTS0->fMagT+pTS1->fMagT);
- ts_res.vOs = vadd(pTS0->vOs,pTS1->vOs);
- ts_res.vOt = vadd(pTS0->vOt,pTS1->vOt);
- ts_res.vOs = NormalizeSafe(ts_res.vOs);
- ts_res.vOt = NormalizeSafe(ts_res.vOt);
- }
-
- return ts_res;
+ STSpace ts_res;
+
+ // this if is important. Due to floating point precision
+ // averaging when ts0==ts1 will cause a slight difference
+ // which results in tangent space splits later on
+ if (pTS0->fMagS == pTS1->fMagS && pTS0->fMagT == pTS1->fMagT && veq(pTS0->vOs, pTS1->vOs) &&
+ veq(pTS0->vOt, pTS1->vOt)) {
+ ts_res.fMagS = pTS0->fMagS;
+ ts_res.fMagT = pTS0->fMagT;
+ ts_res.vOs = pTS0->vOs;
+ ts_res.vOt = pTS0->vOt;
+ }
+ else {
+ ts_res.fMagS = 0.5f * (pTS0->fMagS + pTS1->fMagS);
+ ts_res.fMagT = 0.5f * (pTS0->fMagT + pTS1->fMagT);
+ ts_res.vOs = vadd(pTS0->vOs, pTS1->vOs);
+ ts_res.vOt = vadd(pTS0->vOt, pTS1->vOt);
+ ts_res.vOs = NormalizeSafe(ts_res.vOs);
+ ts_res.vOt = NormalizeSafe(ts_res.vOt);
+ }
+
+ return ts_res;
}
-
-
-MIKK_INLINE SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index);
-MIKK_INLINE SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index);
-MIKK_INLINE SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index);
-
+MIKK_INLINE SVec3 GetPosition(const SMikkTSpaceContext *pContext, const int index);
+MIKK_INLINE SVec3 GetNormal(const SMikkTSpaceContext *pContext, const int index);
+MIKK_INLINE SVec3 GetTexCoord(const SMikkTSpaceContext *pContext, const int index);
// degen triangles
-static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris);
-static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris);
-
+static void DegenPrologue(STriInfo pTriInfos[],
+ int piTriList_out[],
+ const int iNrTrianglesIn,
+ const int iTotTris);
+static void DegenEpilogue(STSpace psTspace[],
+ STriInfo pTriInfos[],
+ int piTriListIn[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn,
+ const int iTotTris);
-tbool genTangSpaceDefault(const SMikkTSpaceContext * pContext)
+tbool genTangSpaceDefault(const SMikkTSpaceContext *pContext)
{
- return genTangSpace(pContext, 180.0f);
+ return genTangSpace(pContext, 180.0f);
}
-tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThreshold)
+tbool genTangSpace(const SMikkTSpaceContext *pContext, const float fAngularThreshold)
{
- // count nr_triangles
- int * piTriListIn = NULL, * piGroupTrianglesBuffer = NULL;
- STriInfo * pTriInfos = NULL;
- SGroup * pGroups = NULL;
- STSpace * psTspace = NULL;
- int iNrTrianglesIn = 0, f=0, t=0, i=0;
- int iNrTSPaces = 0, iTotTris = 0, iDegenTriangles = 0, iNrMaxGroups = 0;
- int iNrActiveGroups = 0, index = 0;
- const int iNrFaces = pContext->m_pInterface->m_getNumFaces(pContext);
- tbool bRes = TFALSE;
- const float fThresCos = cosf((fAngularThreshold*(float)M_PI)/180.0f);
-
- // verify all call-backs have been set
- if ( pContext->m_pInterface->m_getNumFaces==NULL ||
- pContext->m_pInterface->m_getNumVerticesOfFace==NULL ||
- pContext->m_pInterface->m_getPosition==NULL ||
- pContext->m_pInterface->m_getNormal==NULL ||
- pContext->m_pInterface->m_getTexCoord==NULL )
- return TFALSE;
-
- // count triangles on supported faces
- for (f=0; f<iNrFaces; f++)
- {
- const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
- if (verts==3) ++iNrTrianglesIn;
- else if (verts==4) iNrTrianglesIn += 2;
- }
- if (iNrTrianglesIn<=0) return TFALSE;
-
- // allocate memory for an index list
- piTriListIn = (int *) malloc(sizeof(int[3])*iNrTrianglesIn);
- pTriInfos = (STriInfo *) malloc(sizeof(STriInfo)*iNrTrianglesIn);
- if (piTriListIn==NULL || pTriInfos==NULL)
- {
- if (piTriListIn!=NULL) free(piTriListIn);
- if (pTriInfos!=NULL) free(pTriInfos);
- return TFALSE;
- }
-
- // make an initial triangle --> face index list
- iNrTSPaces = GenerateInitialVerticesIndexList(pTriInfos, piTriListIn, pContext, iNrTrianglesIn);
-
- // make a welded index list of identical positions and attributes (pos, norm, texc)
- //printf("gen welded index list begin\n");
- GenerateSharedVerticesIndexList(piTriListIn, pContext, iNrTrianglesIn);
- //printf("gen welded index list end\n");
-
- // Mark all degenerate triangles
- iTotTris = iNrTrianglesIn;
- iDegenTriangles = 0;
- for (t=0; t<iTotTris; t++)
- {
- const int i0 = piTriListIn[t*3+0];
- const int i1 = piTriListIn[t*3+1];
- const int i2 = piTriListIn[t*3+2];
- const SVec3 p0 = GetPosition(pContext, i0);
- const SVec3 p1 = GetPosition(pContext, i1);
- const SVec3 p2 = GetPosition(pContext, i2);
- if (veq(p0,p1) || veq(p0,p2) || veq(p1,p2)) // degenerate
- {
- pTriInfos[t].iFlag |= MARK_DEGENERATE;
- ++iDegenTriangles;
- }
- }
- iNrTrianglesIn = iTotTris - iDegenTriangles;
-
- // mark all triangle pairs that belong to a quad with only one
- // good triangle. These need special treatment in DegenEpilogue().
- // Additionally, move all good triangles to the start of
- // pTriInfos[] and piTriListIn[] without changing order and
- // put the degenerate triangles last.
- DegenPrologue(pTriInfos, piTriListIn, iNrTrianglesIn, iTotTris);
-
-
- // evaluate triangle level attributes and neighbor list
- //printf("gen neighbors list begin\n");
- InitTriInfo(pTriInfos, piTriListIn, pContext, iNrTrianglesIn);
- //printf("gen neighbors list end\n");
-
-
- // based on the 4 rules, identify groups based on connectivity
- iNrMaxGroups = iNrTrianglesIn*3;
- pGroups = (SGroup *) malloc(sizeof(SGroup)*iNrMaxGroups);
- piGroupTrianglesBuffer = (int *) malloc(sizeof(int[3])*iNrTrianglesIn);
- if (pGroups==NULL || piGroupTrianglesBuffer==NULL)
- {
- if (pGroups!=NULL) free(pGroups);
- if (piGroupTrianglesBuffer!=NULL) free(piGroupTrianglesBuffer);
- free(piTriListIn);
- free(pTriInfos);
- return TFALSE;
- }
- //printf("gen 4rule groups begin\n");
- iNrActiveGroups =
- Build4RuleGroups(pTriInfos, pGroups, piGroupTrianglesBuffer, piTriListIn, iNrTrianglesIn);
- //printf("gen 4rule groups end\n");
-
- //
-
- psTspace = (STSpace *) malloc(sizeof(STSpace)*iNrTSPaces);
- if (psTspace==NULL)
- {
- free(piTriListIn);
- free(pTriInfos);
- free(pGroups);
- free(piGroupTrianglesBuffer);
- return TFALSE;
- }
- memset(psTspace, 0, sizeof(STSpace)*iNrTSPaces);
- for (t=0; t<iNrTSPaces; t++)
- {
- psTspace[t].vOs.x=1.0f; psTspace[t].vOs.y=0.0f; psTspace[t].vOs.z=0.0f; psTspace[t].fMagS = 1.0f;
- psTspace[t].vOt.x=0.0f; psTspace[t].vOt.y=1.0f; psTspace[t].vOt.z=0.0f; psTspace[t].fMagT = 1.0f;
- }
-
- // make tspaces, each group is split up into subgroups if necessary
- // based on fAngularThreshold. Finally a tangent space is made for
- // every resulting subgroup
- //printf("gen tspaces begin\n");
- bRes = GenerateTSpaces(psTspace, pTriInfos, pGroups, iNrActiveGroups, piTriListIn, fThresCos, pContext);
- //printf("gen tspaces end\n");
-
- // clean up
- free(pGroups);
- free(piGroupTrianglesBuffer);
-
- if (!bRes) // if an allocation in GenerateTSpaces() failed
- {
- // clean up and return false
- free(pTriInfos); free(piTriListIn); free(psTspace);
- return TFALSE;
- }
-
-
- // degenerate quads with one good triangle will be fixed by copying a space from
- // the good triangle to the coinciding vertex.
- // all other degenerate triangles will just copy a space from any good triangle
- // with the same welded index in piTriListIn[].
- DegenEpilogue(psTspace, pTriInfos, piTriListIn, pContext, iNrTrianglesIn, iTotTris);
-
- free(pTriInfos); free(piTriListIn);
-
- index = 0;
- for (f=0; f<iNrFaces; f++)
- {
- const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
- if (verts!=3 && verts!=4) continue;
-
-
- // I've decided to let degenerate triangles and group-with-anythings
- // vary between left/right hand coordinate systems at the vertices.
- // All healthy triangles on the other hand are built to always be either or.
-
- /*// force the coordinate system orientation to be uniform for every face.
- // (this is already the case for good triangles but not for
- // degenerate ones and those with bGroupWithAnything==true)
- bool bOrient = psTspace[index].bOrient;
- if (psTspace[index].iCounter == 0) // tspace was not derived from a group
- {
- // look for a space created in GenerateTSpaces() by iCounter>0
- bool bNotFound = true;
- int i=1;
- while (i<verts && bNotFound)
- {
- if (psTspace[index+i].iCounter > 0) bNotFound=false;
- else ++i;
- }
- if (!bNotFound) bOrient = psTspace[index+i].bOrient;
- }*/
-
- // set data
- for (i=0; i<verts; i++)
- {
- const STSpace * pTSpace = &psTspace[index];
- float tang[] = {pTSpace->vOs.x, pTSpace->vOs.y, pTSpace->vOs.z};
- float bitang[] = {pTSpace->vOt.x, pTSpace->vOt.y, pTSpace->vOt.z};
- if (pContext->m_pInterface->m_setTSpace!=NULL)
- pContext->m_pInterface->m_setTSpace(pContext, tang, bitang, pTSpace->fMagS, pTSpace->fMagT, pTSpace->bOrient, f, i);
- if (pContext->m_pInterface->m_setTSpaceBasic!=NULL)
- pContext->m_pInterface->m_setTSpaceBasic(pContext, tang, pTSpace->bOrient==TTRUE ? 1.0f : (-1.0f), f, i);
-
- ++index;
- }
- }
-
- free(psTspace);
-
-
- return TTRUE;
+ // count nr_triangles
+ int *piTriListIn = NULL, *piGroupTrianglesBuffer = NULL;
+ STriInfo *pTriInfos = NULL;
+ SGroup *pGroups = NULL;
+ STSpace *psTspace = NULL;
+ int iNrTrianglesIn = 0, f = 0, t = 0, i = 0;
+ int iNrTSPaces = 0, iTotTris = 0, iDegenTriangles = 0, iNrMaxGroups = 0;
+ int iNrActiveGroups = 0, index = 0;
+ const int iNrFaces = pContext->m_pInterface->m_getNumFaces(pContext);
+ tbool bRes = TFALSE;
+ const float fThresCos = cosf((fAngularThreshold * (float)M_PI) / 180.0f);
+
+ // verify all call-backs have been set
+ if (pContext->m_pInterface->m_getNumFaces == NULL ||
+ pContext->m_pInterface->m_getNumVerticesOfFace == NULL ||
+ pContext->m_pInterface->m_getPosition == NULL ||
+ pContext->m_pInterface->m_getNormal == NULL || pContext->m_pInterface->m_getTexCoord == NULL)
+ return TFALSE;
+
+ // count triangles on supported faces
+ for (f = 0; f < iNrFaces; f++) {
+ const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
+ if (verts == 3)
+ ++iNrTrianglesIn;
+ else if (verts == 4)
+ iNrTrianglesIn += 2;
+ }
+ if (iNrTrianglesIn <= 0)
+ return TFALSE;
+
+ // allocate memory for an index list
+ piTriListIn = (int *)malloc(sizeof(int[3]) * iNrTrianglesIn);
+ pTriInfos = (STriInfo *)malloc(sizeof(STriInfo) * iNrTrianglesIn);
+ if (piTriListIn == NULL || pTriInfos == NULL) {
+ if (piTriListIn != NULL)
+ free(piTriListIn);
+ if (pTriInfos != NULL)
+ free(pTriInfos);
+ return TFALSE;
+ }
+
+ // make an initial triangle --> face index list
+ iNrTSPaces = GenerateInitialVerticesIndexList(pTriInfos, piTriListIn, pContext, iNrTrianglesIn);
+
+ // make a welded index list of identical positions and attributes (pos, norm, texc)
+ //printf("gen welded index list begin\n");
+ GenerateSharedVerticesIndexList(piTriListIn, pContext, iNrTrianglesIn);
+ //printf("gen welded index list end\n");
+
+ // Mark all degenerate triangles
+ iTotTris = iNrTrianglesIn;
+ iDegenTriangles = 0;
+ for (t = 0; t < iTotTris; t++) {
+ const int i0 = piTriListIn[t * 3 + 0];
+ const int i1 = piTriListIn[t * 3 + 1];
+ const int i2 = piTriListIn[t * 3 + 2];
+ const SVec3 p0 = GetPosition(pContext, i0);
+ const SVec3 p1 = GetPosition(pContext, i1);
+ const SVec3 p2 = GetPosition(pContext, i2);
+ if (veq(p0, p1) || veq(p0, p2) || veq(p1, p2)) // degenerate
+ {
+ pTriInfos[t].iFlag |= MARK_DEGENERATE;
+ ++iDegenTriangles;
+ }
+ }
+ iNrTrianglesIn = iTotTris - iDegenTriangles;
+
+ // mark all triangle pairs that belong to a quad with only one
+ // good triangle. These need special treatment in DegenEpilogue().
+ // Additionally, move all good triangles to the start of
+ // pTriInfos[] and piTriListIn[] without changing order and
+ // put the degenerate triangles last.
+ DegenPrologue(pTriInfos, piTriListIn, iNrTrianglesIn, iTotTris);
+
+ // evaluate triangle level attributes and neighbor list
+ //printf("gen neighbors list begin\n");
+ InitTriInfo(pTriInfos, piTriListIn, pContext, iNrTrianglesIn);
+ //printf("gen neighbors list end\n");
+
+ // based on the 4 rules, identify groups based on connectivity
+ iNrMaxGroups = iNrTrianglesIn * 3;
+ pGroups = (SGroup *)malloc(sizeof(SGroup) * iNrMaxGroups);
+ piGroupTrianglesBuffer = (int *)malloc(sizeof(int[3]) * iNrTrianglesIn);
+ if (pGroups == NULL || piGroupTrianglesBuffer == NULL) {
+ if (pGroups != NULL)
+ free(pGroups);
+ if (piGroupTrianglesBuffer != NULL)
+ free(piGroupTrianglesBuffer);
+ free(piTriListIn);
+ free(pTriInfos);
+ return TFALSE;
+ }
+ //printf("gen 4rule groups begin\n");
+ iNrActiveGroups = Build4RuleGroups(
+ pTriInfos, pGroups, piGroupTrianglesBuffer, piTriListIn, iNrTrianglesIn);
+ //printf("gen 4rule groups end\n");
+
+ //
+
+ psTspace = (STSpace *)malloc(sizeof(STSpace) * iNrTSPaces);
+ if (psTspace == NULL) {
+ free(piTriListIn);
+ free(pTriInfos);
+ free(pGroups);
+ free(piGroupTrianglesBuffer);
+ return TFALSE;
+ }
+ memset(psTspace, 0, sizeof(STSpace) * iNrTSPaces);
+ for (t = 0; t < iNrTSPaces; t++) {
+ psTspace[t].vOs.x = 1.0f;
+ psTspace[t].vOs.y = 0.0f;
+ psTspace[t].vOs.z = 0.0f;
+ psTspace[t].fMagS = 1.0f;
+ psTspace[t].vOt.x = 0.0f;
+ psTspace[t].vOt.y = 1.0f;
+ psTspace[t].vOt.z = 0.0f;
+ psTspace[t].fMagT = 1.0f;
+ }
+
+ // make tspaces, each group is split up into subgroups if necessary
+ // based on fAngularThreshold. Finally a tangent space is made for
+ // every resulting subgroup
+ //printf("gen tspaces begin\n");
+ bRes = GenerateTSpaces(
+ psTspace, pTriInfos, pGroups, iNrActiveGroups, piTriListIn, fThresCos, pContext);
+ //printf("gen tspaces end\n");
+
+ // clean up
+ free(pGroups);
+ free(piGroupTrianglesBuffer);
+
+ if (!bRes) // if an allocation in GenerateTSpaces() failed
+ {
+ // clean up and return false
+ free(pTriInfos);
+ free(piTriListIn);
+ free(psTspace);
+ return TFALSE;
+ }
+
+ // degenerate quads with one good triangle will be fixed by copying a space from
+ // the good triangle to the coinciding vertex.
+ // all other degenerate triangles will just copy a space from any good triangle
+ // with the same welded index in piTriListIn[].
+ DegenEpilogue(psTspace, pTriInfos, piTriListIn, pContext, iNrTrianglesIn, iTotTris);
+
+ free(pTriInfos);
+ free(piTriListIn);
+
+ index = 0;
+ for (f = 0; f < iNrFaces; f++) {
+ const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
+ if (verts != 3 && verts != 4)
+ continue;
+
+ // I've decided to let degenerate triangles and group-with-anythings
+ // vary between left/right hand coordinate systems at the vertices.
+ // All healthy triangles on the other hand are built to always be either or.
+
+ /*// force the coordinate system orientation to be uniform for every face.
+ // (this is already the case for good triangles but not for
+ // degenerate ones and those with bGroupWithAnything==true)
+ bool bOrient = psTspace[index].bOrient;
+ if (psTspace[index].iCounter == 0) // tspace was not derived from a group
+ {
+ // look for a space created in GenerateTSpaces() by iCounter>0
+ bool bNotFound = true;
+ int i=1;
+ while (i<verts && bNotFound)
+ {
+ if (psTspace[index+i].iCounter > 0) bNotFound=false;
+ else ++i;
+ }
+ if (!bNotFound) bOrient = psTspace[index+i].bOrient;
+ }*/
+
+ // set data
+ for (i = 0; i < verts; i++) {
+ const STSpace *pTSpace = &psTspace[index];
+ float tang[] = {pTSpace->vOs.x, pTSpace->vOs.y, pTSpace->vOs.z};
+ float bitang[] = {pTSpace->vOt.x, pTSpace->vOt.y, pTSpace->vOt.z};
+ if (pContext->m_pInterface->m_setTSpace != NULL)
+ pContext->m_pInterface->m_setTSpace(
+ pContext, tang, bitang, pTSpace->fMagS, pTSpace->fMagT, pTSpace->bOrient, f, i);
+ if (pContext->m_pInterface->m_setTSpaceBasic != NULL)
+ pContext->m_pInterface->m_setTSpaceBasic(
+ pContext, tang, pTSpace->bOrient == TTRUE ? 1.0f : (-1.0f), f, i);
+
+ ++index;
+ }
+ }
+
+ free(psTspace);
+
+ return TTRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct {
- float vert[3];
- int index;
+ float vert[3];
+ int index;
} STmpVert;
-static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
+static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn);
typedef unsigned int uint;
static uint float_as_uint(const float v)
{
- return *((uint*)(&v));
+ return *((uint *)(&v));
}
-#define HASH(x, y, z) (((x) * 73856093) ^ ((y) * 19349663) ^ ((z) * 83492791))
+#define HASH(x, y, z) (((x)*73856093) ^ ((y)*19349663) ^ ((z)*83492791))
#define HASH_F(x, y, z) HASH(float_as_uint(x), float_as_uint(y), float_as_uint(z))
/* Sort comp and data based on comp.
* comp2 and data2 are used as temporary storage. */
static void radixsort_pair(uint *comp, int *data, uint *comp2, int *data2, int n)
{
- int shift = 0;
- for(int pass = 0; pass < 4; pass++, shift+=8) {
- int bins[257] = {0};
- /* Count number of elements per bin. */
- for(int i = 0; i < n; i++) {
- bins[((comp[i] >> shift) & 0xff) + 1]++;
- }
- /* Compute prefix sum to find position of each bin in the sorted array. */
- for(int i = 2; i < 256; i++) {
- bins[i] += bins[i-1];
- }
- /* Insert the elements in their correct location based on their bin. */
- for(int i = 0; i < n; i++) {
- int pos = bins[(comp[i] >> shift) & 0xff]++;
- comp2[pos] = comp[i];
- data2[pos] = data[i];
- }
-
- /* Swap arrays. */
- int *tmpdata = data; data = data2; data2 = tmpdata;
- uint *tmpcomp = comp; comp = comp2; comp2 = tmpcomp;
- }
+ int shift = 0;
+ for (int pass = 0; pass < 4; pass++, shift += 8) {
+ int bins[257] = {0};
+ /* Count number of elements per bin. */
+ for (int i = 0; i < n; i++) {
+ bins[((comp[i] >> shift) & 0xff) + 1]++;
+ }
+ /* Compute prefix sum to find position of each bin in the sorted array. */
+ for (int i = 2; i < 256; i++) {
+ bins[i] += bins[i - 1];
+ }
+ /* Insert the elements in their correct location based on their bin. */
+ for (int i = 0; i < n; i++) {
+ int pos = bins[(comp[i] >> shift) & 0xff]++;
+ comp2[pos] = comp[i];
+ data2[pos] = data[i];
+ }
+
+ /* Swap arrays. */
+ int *tmpdata = data;
+ data = data2;
+ data2 = tmpdata;
+ uint *tmpcomp = comp;
+ comp = comp2;
+ comp2 = tmpcomp;
+ }
}
/* Merge identical vertices.
@@ -493,1351 +517,1396 @@ static void radixsort_pair(uint *comp, int *data, uint *comp2, int *data2, int n
* Since there might be hash collisions, the elements of each block are then compared with each other and duplicates
* are merged.
*/
-static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn)
{
- int numVertices = iNrTrianglesIn*3;
-
- uint *hashes = (uint*) malloc(sizeof(uint)*numVertices);
- int *indices = (int*) malloc(sizeof(int)*numVertices);
- uint *temp_hashes = (uint*) malloc(sizeof(uint)*numVertices);
- int *temp_indices = (int*) malloc(sizeof(int)*numVertices);
-
- if(hashes == NULL || indices == NULL || temp_hashes == NULL || temp_indices == NULL) {
- free(hashes);
- free(indices);
- free(temp_hashes);
- free(temp_indices);
-
- GenerateSharedVerticesIndexListSlow(piTriList_in_and_out, pContext, iNrTrianglesIn);
- return;
- }
-
- for (int i = 0; i < numVertices; i++) {
- const int index = piTriList_in_and_out[i];
-
- const SVec3 vP = GetPosition(pContext, index);
- const uint hashP = HASH_F(vP.x, vP.y, vP.z);
-
- const SVec3 vN = GetNormal(pContext, index);
- const uint hashN = HASH_F(vN.x, vN.y, vN.z);
-
- const SVec3 vT = GetTexCoord(pContext, index);
- const uint hashT = HASH_F(vT.x, vT.y, vT.z);
-
- hashes[i] = HASH(hashP, hashN, hashT);
- indices[i] = i;
- }
-
- radixsort_pair(hashes, indices, temp_hashes, temp_indices, numVertices);
-
- free(temp_hashes);
- free(temp_indices);
-
- /* Process blocks of vertices with the same hash.
- * Vertices in the block might still be separate, but we know for sure that
- * vertices in different blocks will never be identical. */
- int blockstart = 0;
- while (blockstart < numVertices) {
- /* Find end of this block (exclusive). */
- uint hash = hashes[blockstart];
- int blockend = blockstart+1;
- for(; blockend < numVertices; blockend++) {
- if(hashes[blockend] != hash) break;
- }
-
- for(int i = blockstart; i < blockend; i++) {
- int index1 = piTriList_in_and_out[indices[i]];
- const SVec3 vP = GetPosition(pContext, index1);
- const SVec3 vN = GetNormal(pContext, index1);
- const SVec3 vT = GetTexCoord(pContext, index1);
- for(int i2 = i+1; i2 < blockend; i2++) {
- int index2 = piTriList_in_and_out[indices[i2]];
- if(index1 == index2) continue;
-
- if(veq(vP, GetPosition(pContext, index2)) &&
- veq(vN, GetNormal(pContext, index2)) &&
- veq(vT, GetTexCoord(pContext, index2)))
- {
- piTriList_in_and_out[indices[i2]] = index1;
- /* Once i2>i has been identified as a duplicate, we can stop since any
- * i3>i2>i that is a duplicate of i (and therefore also i2) will also be
- * compared to i2 and therefore be identified there anyways. */
- break;
- }
- }
- }
-
- /* Advance to next block. */
- blockstart = blockend;
- }
-
- free(hashes);
- free(indices);
+ int numVertices = iNrTrianglesIn * 3;
+
+ uint *hashes = (uint *)malloc(sizeof(uint) * numVertices);
+ int *indices = (int *)malloc(sizeof(int) * numVertices);
+ uint *temp_hashes = (uint *)malloc(sizeof(uint) * numVertices);
+ int *temp_indices = (int *)malloc(sizeof(int) * numVertices);
+
+ if (hashes == NULL || indices == NULL || temp_hashes == NULL || temp_indices == NULL) {
+ free(hashes);
+ free(indices);
+ free(temp_hashes);
+ free(temp_indices);
+
+ GenerateSharedVerticesIndexListSlow(piTriList_in_and_out, pContext, iNrTrianglesIn);
+ return;
+ }
+
+ for (int i = 0; i < numVertices; i++) {
+ const int index = piTriList_in_and_out[i];
+
+ const SVec3 vP = GetPosition(pContext, index);
+ const uint hashP = HASH_F(vP.x, vP.y, vP.z);
+
+ const SVec3 vN = GetNormal(pContext, index);
+ const uint hashN = HASH_F(vN.x, vN.y, vN.z);
+
+ const SVec3 vT = GetTexCoord(pContext, index);
+ const uint hashT = HASH_F(vT.x, vT.y, vT.z);
+
+ hashes[i] = HASH(hashP, hashN, hashT);
+ indices[i] = i;
+ }
+
+ radixsort_pair(hashes, indices, temp_hashes, temp_indices, numVertices);
+
+ free(temp_hashes);
+ free(temp_indices);
+
+ /* Process blocks of vertices with the same hash.
+ * Vertices in the block might still be separate, but we know for sure that
+ * vertices in different blocks will never be identical. */
+ int blockstart = 0;
+ while (blockstart < numVertices) {
+ /* Find end of this block (exclusive). */
+ uint hash = hashes[blockstart];
+ int blockend = blockstart + 1;
+ for (; blockend < numVertices; blockend++) {
+ if (hashes[blockend] != hash)
+ break;
+ }
+
+ for (int i = blockstart; i < blockend; i++) {
+ int index1 = piTriList_in_and_out[indices[i]];
+ const SVec3 vP = GetPosition(pContext, index1);
+ const SVec3 vN = GetNormal(pContext, index1);
+ const SVec3 vT = GetTexCoord(pContext, index1);
+ for (int i2 = i + 1; i2 < blockend; i2++) {
+ int index2 = piTriList_in_and_out[indices[i2]];
+ if (index1 == index2)
+ continue;
+
+ if (veq(vP, GetPosition(pContext, index2)) && veq(vN, GetNormal(pContext, index2)) &&
+ veq(vT, GetTexCoord(pContext, index2))) {
+ piTriList_in_and_out[indices[i2]] = index1;
+ /* Once i2>i has been identified as a duplicate, we can stop since any
+ * i3>i2>i that is a duplicate of i (and therefore also i2) will also be
+ * compared to i2 and therefore be identified there anyways. */
+ break;
+ }
+ }
+ }
+
+ /* Advance to next block. */
+ blockstart = blockend;
+ }
+
+ free(hashes);
+ free(indices);
}
-static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn)
{
- int iNumUniqueVerts = 0, t=0, i=0;
- for (t=0; t<iNrTrianglesIn; t++)
- {
- for (i=0; i<3; i++)
- {
- const int offs = t*3 + i;
- const int index = piTriList_in_and_out[offs];
-
- const SVec3 vP = GetPosition(pContext, index);
- const SVec3 vN = GetNormal(pContext, index);
- const SVec3 vT = GetTexCoord(pContext, index);
-
- tbool bFound = TFALSE;
- int t2=0, index2rec=-1;
- while (!bFound && t2<=t)
- {
- int j=0;
- while (!bFound && j<3)
- {
- const int index2 = piTriList_in_and_out[t2*3 + j];
- const SVec3 vP2 = GetPosition(pContext, index2);
- const SVec3 vN2 = GetNormal(pContext, index2);
- const SVec3 vT2 = GetTexCoord(pContext, index2);
-
- if (veq(vP,vP2) && veq(vN,vN2) && veq(vT,vT2))
- bFound = TTRUE;
- else
- ++j;
- }
- if (!bFound) ++t2;
- }
-
- assert(bFound);
- // if we found our own
- if (index2rec == index) { ++iNumUniqueVerts; }
-
- piTriList_in_and_out[offs] = index2rec;
- }
- }
+ int iNumUniqueVerts = 0, t = 0, i = 0;
+ for (t = 0; t < iNrTrianglesIn; t++) {
+ for (i = 0; i < 3; i++) {
+ const int offs = t * 3 + i;
+ const int index = piTriList_in_and_out[offs];
+
+ const SVec3 vP = GetPosition(pContext, index);
+ const SVec3 vN = GetNormal(pContext, index);
+ const SVec3 vT = GetTexCoord(pContext, index);
+
+ tbool bFound = TFALSE;
+ int t2 = 0, index2rec = -1;
+ while (!bFound && t2 <= t) {
+ int j = 0;
+ while (!bFound && j < 3) {
+ const int index2 = piTriList_in_and_out[t2 * 3 + j];
+ const SVec3 vP2 = GetPosition(pContext, index2);
+ const SVec3 vN2 = GetNormal(pContext, index2);
+ const SVec3 vT2 = GetTexCoord(pContext, index2);
+
+ if (veq(vP, vP2) && veq(vN, vN2) && veq(vT, vT2))
+ bFound = TTRUE;
+ else
+ ++j;
+ }
+ if (!bFound)
+ ++t2;
+ }
+
+ assert(bFound);
+ // if we found our own
+ if (index2rec == index) {
+ ++iNumUniqueVerts;
+ }
+
+ piTriList_in_and_out[offs] = index2rec;
+ }
+ }
}
-static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[],
+ int piTriList_out[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn)
{
- int iTSpacesOffs = 0, f=0, t=0;
- int iDstTriIndex = 0;
- for (f=0; f<pContext->m_pInterface->m_getNumFaces(pContext); f++)
- {
- const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
- if (verts!=3 && verts!=4) continue;
-
- pTriInfos[iDstTriIndex].iOrgFaceNumber = f;
- pTriInfos[iDstTriIndex].iTSpacesOffs = iTSpacesOffs;
-
- if (verts==3)
- {
- unsigned char * pVerts = pTriInfos[iDstTriIndex].vert_num;
- pVerts[0]=0; pVerts[1]=1; pVerts[2]=2;
- piTriList_out[iDstTriIndex*3+0] = MakeIndex(f, 0);
- piTriList_out[iDstTriIndex*3+1] = MakeIndex(f, 1);
- piTriList_out[iDstTriIndex*3+2] = MakeIndex(f, 2);
- ++iDstTriIndex; // next
- }
- else
- {
- {
- pTriInfos[iDstTriIndex+1].iOrgFaceNumber = f;
- pTriInfos[iDstTriIndex+1].iTSpacesOffs = iTSpacesOffs;
- }
-
- {
- // need an order independent way to evaluate
- // tspace on quads. This is done by splitting
- // along the shortest diagonal.
- const int i0 = MakeIndex(f, 0);
- const int i1 = MakeIndex(f, 1);
- const int i2 = MakeIndex(f, 2);
- const int i3 = MakeIndex(f, 3);
- const SVec3 T0 = GetTexCoord(pContext, i0);
- const SVec3 T1 = GetTexCoord(pContext, i1);
- const SVec3 T2 = GetTexCoord(pContext, i2);
- const SVec3 T3 = GetTexCoord(pContext, i3);
- const float distSQ_02 = LengthSquared(vsub(T2,T0));
- const float distSQ_13 = LengthSquared(vsub(T3,T1));
- tbool bQuadDiagIs_02;
- if (distSQ_02<distSQ_13)
- bQuadDiagIs_02 = TTRUE;
- else if (distSQ_13<distSQ_02)
- bQuadDiagIs_02 = TFALSE;
- else
- {
- const SVec3 P0 = GetPosition(pContext, i0);
- const SVec3 P1 = GetPosition(pContext, i1);
- const SVec3 P2 = GetPosition(pContext, i2);
- const SVec3 P3 = GetPosition(pContext, i3);
- const float distSQ_02 = LengthSquared(vsub(P2,P0));
- const float distSQ_13 = LengthSquared(vsub(P3,P1));
-
- bQuadDiagIs_02 = distSQ_13<distSQ_02 ? TFALSE : TTRUE;
- }
-
- if (bQuadDiagIs_02)
- {
- {
- unsigned char * pVerts_A = pTriInfos[iDstTriIndex].vert_num;
- pVerts_A[0]=0; pVerts_A[1]=1; pVerts_A[2]=2;
- }
- piTriList_out[iDstTriIndex*3+0] = i0;
- piTriList_out[iDstTriIndex*3+1] = i1;
- piTriList_out[iDstTriIndex*3+2] = i2;
- ++iDstTriIndex; // next
- {
- unsigned char * pVerts_B = pTriInfos[iDstTriIndex].vert_num;
- pVerts_B[0]=0; pVerts_B[1]=2; pVerts_B[2]=3;
- }
- piTriList_out[iDstTriIndex*3+0] = i0;
- piTriList_out[iDstTriIndex*3+1] = i2;
- piTriList_out[iDstTriIndex*3+2] = i3;
- ++iDstTriIndex; // next
- }
- else
- {
- {
- unsigned char * pVerts_A = pTriInfos[iDstTriIndex].vert_num;
- pVerts_A[0]=0; pVerts_A[1]=1; pVerts_A[2]=3;
- }
- piTriList_out[iDstTriIndex*3+0] = i0;
- piTriList_out[iDstTriIndex*3+1] = i1;
- piTriList_out[iDstTriIndex*3+2] = i3;
- ++iDstTriIndex; // next
- {
- unsigned char * pVerts_B = pTriInfos[iDstTriIndex].vert_num;
- pVerts_B[0]=1; pVerts_B[1]=2; pVerts_B[2]=3;
- }
- piTriList_out[iDstTriIndex*3+0] = i1;
- piTriList_out[iDstTriIndex*3+1] = i2;
- piTriList_out[iDstTriIndex*3+2] = i3;
- ++iDstTriIndex; // next
- }
- }
- }
-
- iTSpacesOffs += verts;
- assert(iDstTriIndex<=iNrTrianglesIn);
- }
-
- for (t=0; t<iNrTrianglesIn; t++)
- pTriInfos[t].iFlag = 0;
-
- // return total amount of tspaces
- return iTSpacesOffs;
+ int iTSpacesOffs = 0, f = 0, t = 0;
+ int iDstTriIndex = 0;
+ for (f = 0; f < pContext->m_pInterface->m_getNumFaces(pContext); f++) {
+ const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
+ if (verts != 3 && verts != 4)
+ continue;
+
+ pTriInfos[iDstTriIndex].iOrgFaceNumber = f;
+ pTriInfos[iDstTriIndex].iTSpacesOffs = iTSpacesOffs;
+
+ if (verts == 3) {
+ unsigned char *pVerts = pTriInfos[iDstTriIndex].vert_num;
+ pVerts[0] = 0;
+ pVerts[1] = 1;
+ pVerts[2] = 2;
+ piTriList_out[iDstTriIndex * 3 + 0] = MakeIndex(f, 0);
+ piTriList_out[iDstTriIndex * 3 + 1] = MakeIndex(f, 1);
+ piTriList_out[iDstTriIndex * 3 + 2] = MakeIndex(f, 2);
+ ++iDstTriIndex; // next
+ }
+ else {
+ {
+ pTriInfos[iDstTriIndex + 1].iOrgFaceNumber = f;
+ pTriInfos[iDstTriIndex + 1].iTSpacesOffs = iTSpacesOffs;
+ }
+
+ {
+ // need an order independent way to evaluate
+ // tspace on quads. This is done by splitting
+ // along the shortest diagonal.
+ const int i0 = MakeIndex(f, 0);
+ const int i1 = MakeIndex(f, 1);
+ const int i2 = MakeIndex(f, 2);
+ const int i3 = MakeIndex(f, 3);
+ const SVec3 T0 = GetTexCoord(pContext, i0);
+ const SVec3 T1 = GetTexCoord(pContext, i1);
+ const SVec3 T2 = GetTexCoord(pContext, i2);
+ const SVec3 T3 = GetTexCoord(pContext, i3);
+ const float distSQ_02 = LengthSquared(vsub(T2, T0));
+ const float distSQ_13 = LengthSquared(vsub(T3, T1));
+ tbool bQuadDiagIs_02;
+ if (distSQ_02 < distSQ_13)
+ bQuadDiagIs_02 = TTRUE;
+ else if (distSQ_13 < distSQ_02)
+ bQuadDiagIs_02 = TFALSE;
+ else {
+ const SVec3 P0 = GetPosition(pContext, i0);
+ const SVec3 P1 = GetPosition(pContext, i1);
+ const SVec3 P2 = GetPosition(pContext, i2);
+ const SVec3 P3 = GetPosition(pContext, i3);
+ const float distSQ_02 = LengthSquared(vsub(P2, P0));
+ const float distSQ_13 = LengthSquared(vsub(P3, P1));
+
+ bQuadDiagIs_02 = distSQ_13 < distSQ_02 ? TFALSE : TTRUE;
+ }
+
+ if (bQuadDiagIs_02) {
+ {
+ unsigned char *pVerts_A = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_A[0] = 0;
+ pVerts_A[1] = 1;
+ pVerts_A[2] = 2;
+ }
+ piTriList_out[iDstTriIndex * 3 + 0] = i0;
+ piTriList_out[iDstTriIndex * 3 + 1] = i1;
+ piTriList_out[iDstTriIndex * 3 + 2] = i2;
+ ++iDstTriIndex; // next
+ {
+ unsigned char *pVerts_B = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_B[0] = 0;
+ pVerts_B[1] = 2;
+ pVerts_B[2] = 3;
+ }
+ piTriList_out[iDstTriIndex * 3 + 0] = i0;
+ piTriList_out[iDstTriIndex * 3 + 1] = i2;
+ piTriList_out[iDstTriIndex * 3 + 2] = i3;
+ ++iDstTriIndex; // next
+ }
+ else {
+ {
+ unsigned char *pVerts_A = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_A[0] = 0;
+ pVerts_A[1] = 1;
+ pVerts_A[2] = 3;
+ }
+ piTriList_out[iDstTriIndex * 3 + 0] = i0;
+ piTriList_out[iDstTriIndex * 3 + 1] = i1;
+ piTriList_out[iDstTriIndex * 3 + 2] = i3;
+ ++iDstTriIndex; // next
+ {
+ unsigned char *pVerts_B = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_B[0] = 1;
+ pVerts_B[1] = 2;
+ pVerts_B[2] = 3;
+ }
+ piTriList_out[iDstTriIndex * 3 + 0] = i1;
+ piTriList_out[iDstTriIndex * 3 + 1] = i2;
+ piTriList_out[iDstTriIndex * 3 + 2] = i3;
+ ++iDstTriIndex; // next
+ }
+ }
+ }
+
+ iTSpacesOffs += verts;
+ assert(iDstTriIndex <= iNrTrianglesIn);
+ }
+
+ for (t = 0; t < iNrTrianglesIn; t++)
+ pTriInfos[t].iFlag = 0;
+
+ // return total amount of tspaces
+ return iTSpacesOffs;
}
-MIKK_INLINE SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index)
+MIKK_INLINE SVec3 GetPosition(const SMikkTSpaceContext *pContext, const int index)
{
- int iF, iI;
- SVec3 res; float pos[3];
- IndexToData(&iF, &iI, index);
- pContext->m_pInterface->m_getPosition(pContext, pos, iF, iI);
- res.x=pos[0]; res.y=pos[1]; res.z=pos[2];
- return res;
+ int iF, iI;
+ SVec3 res;
+ float pos[3];
+ IndexToData(&iF, &iI, index);
+ pContext->m_pInterface->m_getPosition(pContext, pos, iF, iI);
+ res.x = pos[0];
+ res.y = pos[1];
+ res.z = pos[2];
+ return res;
}
-MIKK_INLINE SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index)
+MIKK_INLINE SVec3 GetNormal(const SMikkTSpaceContext *pContext, const int index)
{
- int iF, iI;
- SVec3 res; float norm[3];
- IndexToData(&iF, &iI, index);
- pContext->m_pInterface->m_getNormal(pContext, norm, iF, iI);
- res.x=norm[0]; res.y=norm[1]; res.z=norm[2];
- return res;
+ int iF, iI;
+ SVec3 res;
+ float norm[3];
+ IndexToData(&iF, &iI, index);
+ pContext->m_pInterface->m_getNormal(pContext, norm, iF, iI);
+ res.x = norm[0];
+ res.y = norm[1];
+ res.z = norm[2];
+ return res;
}
-MIKK_INLINE SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index)
+MIKK_INLINE SVec3 GetTexCoord(const SMikkTSpaceContext *pContext, const int index)
{
- int iF, iI;
- SVec3 res; float texc[2];
- IndexToData(&iF, &iI, index);
- pContext->m_pInterface->m_getTexCoord(pContext, texc, iF, iI);
- res.x=texc[0]; res.y=texc[1]; res.z=1.0f;
- return res;
+ int iF, iI;
+ SVec3 res;
+ float texc[2];
+ IndexToData(&iF, &iI, index);
+ pContext->m_pInterface->m_getTexCoord(pContext, texc, iF, iI);
+ res.x = texc[0];
+ res.y = texc[1];
+ res.z = 1.0f;
+ return res;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
typedef union {
- struct
- {
- int i0, i1, f;
- };
- int array[3];
+ struct {
+ int i0, i1, f;
+ };
+ int array[3];
} SEdge;
-static void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn);
-static void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn);
+static void BuildNeighborsFast(STriInfo pTriInfos[],
+ SEdge *pEdges,
+ const int piTriListIn[],
+ const int iNrTrianglesIn);
+static void BuildNeighborsSlow(STriInfo pTriInfos[],
+ const int piTriListIn[],
+ const int iNrTrianglesIn);
// returns the texture area times 2
-static float CalcTexArea(const SMikkTSpaceContext * pContext, const int indices[])
+static float CalcTexArea(const SMikkTSpaceContext *pContext, const int indices[])
{
- const SVec3 t1 = GetTexCoord(pContext, indices[0]);
- const SVec3 t2 = GetTexCoord(pContext, indices[1]);
- const SVec3 t3 = GetTexCoord(pContext, indices[2]);
+ const SVec3 t1 = GetTexCoord(pContext, indices[0]);
+ const SVec3 t2 = GetTexCoord(pContext, indices[1]);
+ const SVec3 t3 = GetTexCoord(pContext, indices[2]);
- const float t21x = t2.x-t1.x;
- const float t21y = t2.y-t1.y;
- const float t31x = t3.x-t1.x;
- const float t31y = t3.y-t1.y;
+ const float t21x = t2.x - t1.x;
+ const float t21y = t2.y - t1.y;
+ const float t31x = t3.x - t1.x;
+ const float t31y = t3.y - t1.y;
- const float fSignedAreaSTx2 = t21x*t31y - t21y*t31x;
+ const float fSignedAreaSTx2 = t21x * t31y - t21y * t31x;
- return fSignedAreaSTx2<0 ? (-fSignedAreaSTx2) : fSignedAreaSTx2;
+ return fSignedAreaSTx2 < 0 ? (-fSignedAreaSTx2) : fSignedAreaSTx2;
}
-static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+static void InitTriInfo(STriInfo pTriInfos[],
+ const int piTriListIn[],
+ const SMikkTSpaceContext *pContext,
+ const int iNrTrianglesIn)
{
- int f=0, i=0, t=0;
- // pTriInfos[f].iFlag is cleared in GenerateInitialVerticesIndexList() which is called before this function.
-
- // generate neighbor info list
- for (f=0; f<iNrTrianglesIn; f++)
- for (i=0; i<3; i++)
- {
- pTriInfos[f].FaceNeighbors[i] = -1;
- pTriInfos[f].AssignedGroup[i] = NULL;
-
- pTriInfos[f].vOs.x=0.0f; pTriInfos[f].vOs.y=0.0f; pTriInfos[f].vOs.z=0.0f;
- pTriInfos[f].vOt.x=0.0f; pTriInfos[f].vOt.y=0.0f; pTriInfos[f].vOt.z=0.0f;
- pTriInfos[f].fMagS = 0;
- pTriInfos[f].fMagT = 0;
-
- // assumed bad
- pTriInfos[f].iFlag |= GROUP_WITH_ANY;
- }
-
- // evaluate first order derivatives
- for (f=0; f<iNrTrianglesIn; f++)
- {
- // initial values
- const SVec3 v1 = GetPosition(pContext, piTriListIn[f*3+0]);
- const SVec3 v2 = GetPosition(pContext, piTriListIn[f*3+1]);
- const SVec3 v3 = GetPosition(pContext, piTriListIn[f*3+2]);
- const SVec3 t1 = GetTexCoord(pContext, piTriListIn[f*3+0]);
- const SVec3 t2 = GetTexCoord(pContext, piTriListIn[f*3+1]);
- const SVec3 t3 = GetTexCoord(pContext, piTriListIn[f*3+2]);
-
- const float t21x = t2.x-t1.x;
- const float t21y = t2.y-t1.y;
- const float t31x = t3.x-t1.x;
- const float t31y = t3.y-t1.y;
- const SVec3 d1 = vsub(v2,v1);
- const SVec3 d2 = vsub(v3,v1);
-
- const float fSignedAreaSTx2 = t21x*t31y - t21y*t31x;
- //assert(fSignedAreaSTx2!=0);
- SVec3 vOs = vsub(vscale(t31y,d1), vscale(t21y,d2)); // eq 18
- SVec3 vOt = vadd(vscale(-t31x,d1), vscale(t21x,d2)); // eq 19
-
- pTriInfos[f].iFlag |= (fSignedAreaSTx2>0 ? ORIENT_PRESERVING : 0);
-
- if ( NotZero(fSignedAreaSTx2) )
- {
- const float fAbsArea = fabsf(fSignedAreaSTx2);
- const float fLenOs = Length(vOs);
- const float fLenOt = Length(vOt);
- const float fS = (pTriInfos[f].iFlag&ORIENT_PRESERVING)==0 ? (-1.0f) : 1.0f;
- if ( NotZero(fLenOs) ) pTriInfos[f].vOs = vscale(fS/fLenOs, vOs);
- if ( NotZero(fLenOt) ) pTriInfos[f].vOt = vscale(fS/fLenOt, vOt);
-
- // evaluate magnitudes prior to normalization of vOs and vOt
- pTriInfos[f].fMagS = fLenOs / fAbsArea;
- pTriInfos[f].fMagT = fLenOt / fAbsArea;
-
- // if this is a good triangle
- if ( NotZero(pTriInfos[f].fMagS) && NotZero(pTriInfos[f].fMagT))
- pTriInfos[f].iFlag &= (~GROUP_WITH_ANY);
- }
- }
-
- // force otherwise healthy quads to a fixed orientation
- while (t<(iNrTrianglesIn-1))
- {
- const int iFO_a = pTriInfos[t].iOrgFaceNumber;
- const int iFO_b = pTriInfos[t+1].iOrgFaceNumber;
- if (iFO_a==iFO_b) // this is a quad
- {
- const tbool bIsDeg_a = (pTriInfos[t].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
- const tbool bIsDeg_b = (pTriInfos[t+1].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
-
- // bad triangles should already have been removed by
- // DegenPrologue(), but just in case check bIsDeg_a and bIsDeg_a are false
- if ((bIsDeg_a||bIsDeg_b)==TFALSE)
- {
- const tbool bOrientA = (pTriInfos[t].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
- const tbool bOrientB = (pTriInfos[t+1].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
- // if this happens the quad has extremely bad mapping!!
- if (bOrientA!=bOrientB)
- {
- //printf("found quad with bad mapping\n");
- tbool bChooseOrientFirstTri = TFALSE;
- if ((pTriInfos[t+1].iFlag&GROUP_WITH_ANY)!=0) bChooseOrientFirstTri = TTRUE;
- else if ( CalcTexArea(pContext, &piTriListIn[t*3+0]) >= CalcTexArea(pContext, &piTriListIn[(t+1)*3+0]) )
- bChooseOrientFirstTri = TTRUE;
-
- // force match
- {
- const int t0 = bChooseOrientFirstTri ? t : (t+1);
- const int t1 = bChooseOrientFirstTri ? (t+1) : t;
- pTriInfos[t1].iFlag &= (~ORIENT_PRESERVING); // clear first
- pTriInfos[t1].iFlag |= (pTriInfos[t0].iFlag&ORIENT_PRESERVING); // copy bit
- }
- }
- }
- t += 2;
- }
- else
- ++t;
- }
-
- // match up edge pairs
- {
- SEdge * pEdges = (SEdge *) malloc(sizeof(SEdge[3])*iNrTrianglesIn);
- if (pEdges==NULL)
- BuildNeighborsSlow(pTriInfos, piTriListIn, iNrTrianglesIn);
- else
- {
- BuildNeighborsFast(pTriInfos, pEdges, piTriListIn, iNrTrianglesIn);
-
- free(pEdges);
- }
- }
+ int f = 0, i = 0, t = 0;
+ // pTriInfos[f].iFlag is cleared in GenerateInitialVerticesIndexList() which is called before this function.
+
+ // generate neighbor info list
+ for (f = 0; f < iNrTrianglesIn; f++)
+ for (i = 0; i < 3; i++) {
+ pTriInfos[f].FaceNeighbors[i] = -1;
+ pTriInfos[f].AssignedGroup[i] = NULL;
+
+ pTriInfos[f].vOs.x = 0.0f;
+ pTriInfos[f].vOs.y = 0.0f;
+ pTriInfos[f].vOs.z = 0.0f;
+ pTriInfos[f].vOt.x = 0.0f;
+ pTriInfos[f].vOt.y = 0.0f;
+ pTriInfos[f].vOt.z = 0.0f;
+ pTriInfos[f].fMagS = 0;
+ pTriInfos[f].fMagT = 0;
+
+ // assumed bad
+ pTriInfos[f].iFlag |= GROUP_WITH_ANY;
+ }
+
+ // evaluate first order derivatives
+ for (f = 0; f < iNrTrianglesIn; f++) {
+ // initial values
+ const SVec3 v1 = GetPosition(pContext, piTriListIn[f * 3 + 0]);
+ const SVec3 v2 = GetPosition(pContext, piTriListIn[f * 3 + 1]);
+ const SVec3 v3 = GetPosition(pContext, piTriListIn[f * 3 + 2]);
+ const SVec3 t1 = GetTexCoord(pContext, piTriListIn[f * 3 + 0]);
+ const SVec3 t2 = GetTexCoord(pContext, piTriListIn[f * 3 + 1]);
+ const SVec3 t3 = GetTexCoord(pContext, piTriListIn[f * 3 + 2]);
+
+ const float t21x = t2.x - t1.x;
+ const float t21y = t2.y - t1.y;
+ const float t31x = t3.x - t1.x;
+ const float t31y = t3.y - t1.y;
+ const SVec3 d1 = vsub(v2, v1);
+ const SVec3 d2 = vsub(v3, v1);
+
+ const float fSignedAreaSTx2 = t21x * t31y - t21y * t31x;
+ //assert(fSignedAreaSTx2!=0);
+ SVec3 vOs = vsub(vscale(t31y, d1), vscale(t21y, d2)); // eq 18
+ SVec3 vOt = vadd(vscale(-t31x, d1), vscale(t21x, d2)); // eq 19
+
+ pTriInfos[f].iFlag |= (fSignedAreaSTx2 > 0 ? ORIENT_PRESERVING : 0);
+
+ if (NotZero(fSignedAreaSTx2)) {
+ const float fAbsArea = fabsf(fSignedAreaSTx2);
+ const float fLenOs = Length(vOs);
+ const float fLenOt = Length(vOt);
+ const float fS = (pTriInfos[f].iFlag & ORIENT_PRESERVING) == 0 ? (-1.0f) : 1.0f;
+ if (NotZero(fLenOs))
+ pTriInfos[f].vOs = vscale(fS / fLenOs, vOs);
+ if (NotZero(fLenOt))
+ pTriInfos[f].vOt = vscale(fS / fLenOt, vOt);
+
+ // evaluate magnitudes prior to normalization of vOs and vOt
+ pTriInfos[f].fMagS = fLenOs / fAbsArea;
+ pTriInfos[f].fMagT = fLenOt / fAbsArea;
+
+ // if this is a good triangle
+ if (NotZero(pTriInfos[f].fMagS) && NotZero(pTriInfos[f].fMagT))
+ pTriInfos[f].iFlag &= (~GROUP_WITH_ANY);
+ }
+ }
+
+ // force otherwise healthy quads to a fixed orientation
+ while (t < (iNrTrianglesIn - 1)) {
+ const int iFO_a = pTriInfos[t].iOrgFaceNumber;
+ const int iFO_b = pTriInfos[t + 1].iOrgFaceNumber;
+ if (iFO_a == iFO_b) // this is a quad
+ {
+ const tbool bIsDeg_a = (pTriInfos[t].iFlag & MARK_DEGENERATE) != 0 ? TTRUE : TFALSE;
+ const tbool bIsDeg_b = (pTriInfos[t + 1].iFlag & MARK_DEGENERATE) != 0 ? TTRUE : TFALSE;
+
+ // bad triangles should already have been removed by
+ // DegenPrologue(), but just in case check bIsDeg_a and bIsDeg_a are false
+ if ((bIsDeg_a || bIsDeg_b) == TFALSE) {
+ const tbool bOrientA = (pTriInfos[t].iFlag & ORIENT_PRESERVING) != 0 ? TTRUE : TFALSE;
+ const tbool bOrientB = (pTriInfos[t + 1].iFlag & ORIENT_PRESERVING) != 0 ? TTRUE : TFALSE;
+ // if this happens the quad has extremely bad mapping!!
+ if (bOrientA != bOrientB) {
+ //printf("found quad with bad mapping\n");
+ tbool bChooseOrientFirstTri = TFALSE;
+ if ((pTriInfos[t + 1].iFlag & GROUP_WITH_ANY) != 0)
+ bChooseOrientFirstTri = TTRUE;
+ else if (CalcTexArea(pContext, &piTriListIn[t * 3 + 0]) >=
+ CalcTexArea(pContext, &piTriListIn[(t + 1) * 3 + 0]))
+ bChooseOrientFirstTri = TTRUE;
+
+ // force match
+ {
+ const int t0 = bChooseOrientFirstTri ? t : (t + 1);
+ const int t1 = bChooseOrientFirstTri ? (t + 1) : t;
+ pTriInfos[t1].iFlag &= (~ORIENT_PRESERVING); // clear first
+ pTriInfos[t1].iFlag |= (pTriInfos[t0].iFlag & ORIENT_PRESERVING); // copy bit
+ }
+ }
+ }
+ t += 2;
+ }
+ else
+ ++t;
+ }
+
+ // match up edge pairs
+ {
+ SEdge *pEdges = (SEdge *)malloc(sizeof(SEdge[3]) * iNrTrianglesIn);
+ if (pEdges == NULL)
+ BuildNeighborsSlow(pTriInfos, piTriListIn, iNrTrianglesIn);
+ else {
+ BuildNeighborsFast(pTriInfos, pEdges, piTriListIn, iNrTrianglesIn);
+
+ free(pEdges);
+ }
+ }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
-static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[], const int iMyTriIndex, SGroup * pGroup);
-MIKK_INLINE void AddTriToGroup(SGroup * pGroup, const int iTriIndex);
-
-static int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn)
+static tbool AssignRecur(const int piTriListIn[],
+ STriInfo psTriInfos[],
+ const int iMyTriIndex,
+ SGroup *pGroup);
+MIKK_INLINE void AddTriToGroup(SGroup *pGroup, const int iTriIndex);
+
+static int Build4RuleGroups(STriInfo pTriInfos[],
+ SGroup pGroups[],
+ int piGroupTrianglesBuffer[],
+ const int piTriListIn[],
+ const int iNrTrianglesIn)
{
- const int iNrMaxGroups = iNrTrianglesIn*3;
- int iNrActiveGroups = 0;
- int iOffset = 0, f=0, i=0;
- (void)iNrMaxGroups; /* quiet warnings in non debug mode */
- for (f=0; f<iNrTrianglesIn; f++)
- {
- for (i=0; i<3; i++)
- {
- // if not assigned to a group
- if ((pTriInfos[f].iFlag&GROUP_WITH_ANY)==0 && pTriInfos[f].AssignedGroup[i]==NULL)
- {
- tbool bOrPre;
- int neigh_indexL, neigh_indexR;
- const int vert_index = piTriListIn[f*3+i];
- assert(iNrActiveGroups<iNrMaxGroups);
- pTriInfos[f].AssignedGroup[i] = &pGroups[iNrActiveGroups];
- pTriInfos[f].AssignedGroup[i]->iVertexRepresentitive = vert_index;
- pTriInfos[f].AssignedGroup[i]->bOrientPreservering = (pTriInfos[f].iFlag&ORIENT_PRESERVING)!=0;
- pTriInfos[f].AssignedGroup[i]->iNrFaces = 0;
- pTriInfos[f].AssignedGroup[i]->pFaceIndices = &piGroupTrianglesBuffer[iOffset];
- ++iNrActiveGroups;
-
- AddTriToGroup(pTriInfos[f].AssignedGroup[i], f);
- bOrPre = (pTriInfos[f].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
- neigh_indexL = pTriInfos[f].FaceNeighbors[i];
- neigh_indexR = pTriInfos[f].FaceNeighbors[i>0?(i-1):2];
- if (neigh_indexL>=0) // neighbor
- {
- const tbool bAnswer =
- AssignRecur(piTriListIn, pTriInfos, neigh_indexL,
- pTriInfos[f].AssignedGroup[i] );
-
- const tbool bOrPre2 = (pTriInfos[neigh_indexL].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
- const tbool bDiff = bOrPre!=bOrPre2 ? TTRUE : TFALSE;
- assert(bAnswer || bDiff);
- (void)bAnswer, (void)bDiff; /* quiet warnings in non debug mode */
- }
- if (neigh_indexR>=0) // neighbor
- {
- const tbool bAnswer =
- AssignRecur(piTriListIn, pTriInfos, neigh_indexR,
- pTriInfos[f].AssignedGroup[i] );
-
- const tbool bOrPre2 = (pTriInfos[neigh_indexR].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
- const tbool bDiff = bOrPre!=bOrPre2 ? TTRUE : TFALSE;
- assert(bAnswer || bDiff);
- (void)bAnswer, (void)bDiff; /* quiet warnings in non debug mode */
- }
-
- // update offset
- iOffset += pTriInfos[f].AssignedGroup[i]->iNrFaces;
- // since the groups are disjoint a triangle can never
- // belong to more than 3 groups. Subsequently something
- // is completely screwed if this assertion ever hits.
- assert(iOffset <= iNrMaxGroups);
- }
- }
- }
-
- return iNrActiveGroups;
+ const int iNrMaxGroups = iNrTrianglesIn * 3;
+ int iNrActiveGroups = 0;
+ int iOffset = 0, f = 0, i = 0;
+ (void)iNrMaxGroups; /* quiet warnings in non debug mode */
+ for (f = 0; f < iNrTrianglesIn; f++) {
+ for (i = 0; i < 3; i++) {
+ // if not assigned to a group
+ if ((pTriInfos[f].iFlag & GROUP_WITH_ANY) == 0 && pTriInfos[f].AssignedGroup[i] == NULL) {
+ tbool bOrPre;
+ int neigh_indexL, neigh_indexR;
+ const int vert_index = piTriListIn[f * 3 + i];
+ assert(iNrActiveGroups < iNrMaxGroups);
+ pTriInfos[f].AssignedGroup[i] = &pGroups[iNrActiveGroups];
+ pTriInfos[f].AssignedGroup[i]->iVertexRepresentitive = vert_index;
+ pTriInfos[f].AssignedGroup[i]->bOrientPreservering = (pTriInfos[f].iFlag &
+ ORIENT_PRESERVING) != 0;
+ pTriInfos[f].AssignedGroup[i]->iNrFaces = 0;
+ pTriInfos[f].AssignedGroup[i]->pFaceIndices = &piGroupTrianglesBuffer[iOffset];
+ ++iNrActiveGroups;
+
+ AddTriToGroup(pTriInfos[f].AssignedGroup[i], f);
+ bOrPre = (pTriInfos[f].iFlag & ORIENT_PRESERVING) != 0 ? TTRUE : TFALSE;
+ neigh_indexL = pTriInfos[f].FaceNeighbors[i];
+ neigh_indexR = pTriInfos[f].FaceNeighbors[i > 0 ? (i - 1) : 2];
+ if (neigh_indexL >= 0) // neighbor
+ {
+ const tbool bAnswer = AssignRecur(
+ piTriListIn, pTriInfos, neigh_indexL, pTriInfos[f].AssignedGroup[i]);
+
+ const tbool bOrPre2 = (pTriInfos[neigh_indexL].iFlag & ORIENT_PRESERVING) != 0 ? TTRUE :
+ TFALSE;
+ const tbool bDiff = bOrPre != bOrPre2 ? TTRUE : TFALSE;
+ assert(bAnswer || bDiff);
+ (void)bAnswer, (void)bDiff; /* quiet warnings in non debug mode */
+ }
+ if (neigh_indexR >= 0) // neighbor
+ {
+ const tbool bAnswer = AssignRecur(
+ piTriListIn, pTriInfos, neigh_indexR, pTriInfos[f].AssignedGroup[i]);
+
+ const tbool bOrPre2 = (pTriInfos[neigh_indexR].iFlag & ORIENT_PRESERVING) != 0 ? TTRUE :
+ TFALSE;
+ const tbool bDiff = bOrPre != bOrPre2 ? TTRUE : TFALSE;
+ assert(bAnswer || bDiff);
+ (void)bAnswer, (void)bDiff; /* quiet warnings in non debug mode */
+ }
+
+ // update offset
+ iOffset += pTriInfos[f].AssignedGroup[i]->iNrFaces;
+ // since the groups are disjoint a triangle can never
+ // belong to more than 3 groups. Subsequently something
+ // is completely screwed if this assertion ever hits.
+ assert(iOffset <= iNrMaxGroups);
+ }
+ }
+ }
+
+ return iNrActiveGroups;
}
-MIKK_INLINE void AddTriToGroup(SGroup * pGroup, const int iTriIndex)
+MIKK_INLINE void AddTriToGroup(SGroup *pGroup, const int iTriIndex)
{
- pGroup->pFaceIndices[pGroup->iNrFaces] = iTriIndex;
- ++pGroup->iNrFaces;
+ pGroup->pFaceIndices[pGroup->iNrFaces] = iTriIndex;
+ ++pGroup->iNrFaces;
}
-static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[],
- const int iMyTriIndex, SGroup * pGroup)
+static tbool AssignRecur(const int piTriListIn[],
+ STriInfo psTriInfos[],
+ const int iMyTriIndex,
+ SGroup *pGroup)
{
- STriInfo * pMyTriInfo = &psTriInfos[iMyTriIndex];
-
- // track down vertex
- const int iVertRep = pGroup->iVertexRepresentitive;
- const int * pVerts = &piTriListIn[3*iMyTriIndex+0];
- int i=-1;
- if (pVerts[0]==iVertRep) i=0;
- else if (pVerts[1]==iVertRep) i=1;
- else if (pVerts[2]==iVertRep) i=2;
- assert(i>=0 && i<3);
-
- // early out
- if (pMyTriInfo->AssignedGroup[i] == pGroup) return TTRUE;
- else if (pMyTriInfo->AssignedGroup[i]!=NULL) return TFALSE;
- if ((pMyTriInfo->iFlag&GROUP_WITH_ANY)!=0)
- {
- // first to group with a group-with-anything triangle
- // determines it's orientation.
- // This is the only existing order dependency in the code!!
- if ( pMyTriInfo->AssignedGroup[0] == NULL &&
- pMyTriInfo->AssignedGroup[1] == NULL &&
- pMyTriInfo->AssignedGroup[2] == NULL )
- {
- pMyTriInfo->iFlag &= (~ORIENT_PRESERVING);
- pMyTriInfo->iFlag |= (pGroup->bOrientPreservering ? ORIENT_PRESERVING : 0);
- }
- }
- {
- const tbool bOrient = (pMyTriInfo->iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
- if (bOrient != pGroup->bOrientPreservering) return TFALSE;
- }
-
- AddTriToGroup(pGroup, iMyTriIndex);
- pMyTriInfo->AssignedGroup[i] = pGroup;
-
- {
- const int neigh_indexL = pMyTriInfo->FaceNeighbors[i];
- const int neigh_indexR = pMyTriInfo->FaceNeighbors[i>0?(i-1):2];
- if (neigh_indexL>=0)
- AssignRecur(piTriListIn, psTriInfos, neigh_indexL, pGroup);
- if (neigh_indexR>=0)
- AssignRecur(piTriListIn, psTriInfos, neigh_indexR, pGroup);
- }
-
-
-
- return TTRUE;
+ STriInfo *pMyTriInfo = &psTriInfos[iMyTriIndex];
+
+ // track down vertex
+ const int iVertRep = pGroup->iVertexRepresentitive;
+ const int *pVerts = &piTriListIn[3 * iMyTriIndex + 0];
+ int i = -1;
+ if (pVerts[0] == iVertRep)
+ i = 0;
+ else if (pVerts[1] == iVertRep)
+ i = 1;
+ else if (pVerts[2] == iVertRep)
+ i = 2;
+ assert(i >= 0 && i < 3);
+
+ // early out
+ if (pMyTriInfo->AssignedGroup[i] == pGroup)
+ return TTRUE;
+ else if (pMyTriInfo->AssignedGroup[i] != NULL)
+ return TFALSE;
+ if ((pMyTriInfo->iFlag & GROUP_WITH_ANY) != 0) {
+ // first to group with a group-with-anything triangle
+ // determines it's orientation.
+ // This is the only existing order dependency in the code!!
+ if (pMyTriInfo->AssignedGroup[0] == NULL && pMyTriInfo->AssignedGroup[1] == NULL &&
+ pMyTriInfo->AssignedGroup[2] == NULL) {
+ pMyTriInfo->iFlag &= (~ORIENT_PRESERVING);
+ pMyTriInfo->iFlag |= (pGroup->bOrientPreservering ? ORIENT_PRESERVING : 0);
+ }
+ }
+ {
+ const tbool bOrient = (pMyTriInfo->iFlag & ORIENT_PRESERVING) != 0 ? TTRUE : TFALSE;
+ if (bOrient != pGroup->bOrientPreservering)
+ return TFALSE;
+ }
+
+ AddTriToGroup(pGroup, iMyTriIndex);
+ pMyTriInfo->AssignedGroup[i] = pGroup;
+
+ {
+ const int neigh_indexL = pMyTriInfo->FaceNeighbors[i];
+ const int neigh_indexR = pMyTriInfo->FaceNeighbors[i > 0 ? (i - 1) : 2];
+ if (neigh_indexL >= 0)
+ AssignRecur(piTriListIn, psTriInfos, neigh_indexL, pGroup);
+ if (neigh_indexR >= 0)
+ AssignRecur(piTriListIn, psTriInfos, neigh_indexR, pGroup);
+ }
+
+ return TTRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
-static tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2);
-static void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed);
-static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[], const SMikkTSpaceContext * pContext, const int iVertexRepresentitive);
-
-static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
- const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
- const SMikkTSpaceContext * pContext)
+static tbool CompareSubGroups(const SSubGroup *pg1, const SSubGroup *pg2);
+static void QuickSort(int *pSortBuffer, int iLeft, int iRight, unsigned int uSeed);
+static STSpace EvalTspace(int face_indices[],
+ const int iFaces,
+ const int piTriListIn[],
+ const STriInfo pTriInfos[],
+ const SMikkTSpaceContext *pContext,
+ const int iVertexRepresentitive);
+
+static tbool GenerateTSpaces(STSpace psTspace[],
+ const STriInfo pTriInfos[],
+ const SGroup pGroups[],
+ const int iNrActiveGroups,
+ const int piTriListIn[],
+ const float fThresCos,
+ const SMikkTSpaceContext *pContext)
{
- STSpace * pSubGroupTspace = NULL;
- SSubGroup * pUniSubGroups = NULL;
- int * pTmpMembers = NULL;
- int iMaxNrFaces=0, iUniqueTspaces=0, g=0, i=0;
- for (g=0; g<iNrActiveGroups; g++)
- if (iMaxNrFaces < pGroups[g].iNrFaces)
- iMaxNrFaces = pGroups[g].iNrFaces;
-
- if (iMaxNrFaces == 0) return TTRUE;
-
- // make initial allocations
- pSubGroupTspace = (STSpace *) malloc(sizeof(STSpace)*iMaxNrFaces);
- pUniSubGroups = (SSubGroup *) malloc(sizeof(SSubGroup)*iMaxNrFaces);
- pTmpMembers = (int *) malloc(sizeof(int)*iMaxNrFaces);
- if (pSubGroupTspace==NULL || pUniSubGroups==NULL || pTmpMembers==NULL)
- {
- if (pSubGroupTspace!=NULL) free(pSubGroupTspace);
- if (pUniSubGroups!=NULL) free(pUniSubGroups);
- if (pTmpMembers!=NULL) free(pTmpMembers);
- return TFALSE;
- }
-
-
- iUniqueTspaces = 0;
- for (g=0; g<iNrActiveGroups; g++)
- {
- const SGroup * pGroup = &pGroups[g];
- int iUniqueSubGroups = 0, s=0;
-
- for (i=0; i<pGroup->iNrFaces; i++) // triangles
- {
- const int f = pGroup->pFaceIndices[i]; // triangle number
- int index=-1, iVertIndex=-1, iOF_1=-1, iMembers=0, j=0, l=0;
- SSubGroup tmp_group;
- tbool bFound;
- SVec3 n, vOs, vOt;
- if (pTriInfos[f].AssignedGroup[0]==pGroup) index=0;
- else if (pTriInfos[f].AssignedGroup[1]==pGroup) index=1;
- else if (pTriInfos[f].AssignedGroup[2]==pGroup) index=2;
- assert(index>=0 && index<3);
-
- iVertIndex = piTriListIn[f*3+index];
- assert(iVertIndex==pGroup->iVertexRepresentitive);
-
- // is normalized already
- n = GetNormal(pContext, iVertIndex);
-
- // project
- vOs = NormalizeSafe(vsub(pTriInfos[f].vOs, vscale(vdot(n,pTriInfos[f].vOs), n)));
- vOt = NormalizeSafe(vsub(pTriInfos[f].vOt, vscale(vdot(n,pTriInfos[f].vOt), n)));
-
- // original face number
- iOF_1 = pTriInfos[f].iOrgFaceNumber;
-
- iMembers = 0;
- for (j=0; j<pGroup->iNrFaces; j++)
- {
- const int t = pGroup->pFaceIndices[j]; // triangle number
- const int iOF_2 = pTriInfos[t].iOrgFaceNumber;
-
- // project
- SVec3 vOs2 = NormalizeSafe(vsub(pTriInfos[t].vOs, vscale(vdot(n,pTriInfos[t].vOs), n)));
- SVec3 vOt2 = NormalizeSafe(vsub(pTriInfos[t].vOt, vscale(vdot(n,pTriInfos[t].vOt), n)));
-
- {
- const tbool bAny = ( (pTriInfos[f].iFlag | pTriInfos[t].iFlag) & GROUP_WITH_ANY )!=0 ? TTRUE : TFALSE;
- // make sure triangles which belong to the same quad are joined.
- const tbool bSameOrgFace = iOF_1==iOF_2 ? TTRUE : TFALSE;
-
- const float fCosS = vdot(vOs,vOs2);
- const float fCosT = vdot(vOt,vOt2);
-
- assert(f!=t || bSameOrgFace); // sanity check
- if (bAny || bSameOrgFace || (fCosS>fThresCos && fCosT>fThresCos))
- pTmpMembers[iMembers++] = t;
- }
- }
-
- // sort pTmpMembers
- tmp_group.iNrFaces = iMembers;
- tmp_group.pTriMembers = pTmpMembers;
- if (iMembers>1)
- {
- unsigned int uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed?
- QuickSort(pTmpMembers, 0, iMembers-1, uSeed);
- }
-
- // look for an existing match
- bFound = TFALSE;
- l=0;
- while (l<iUniqueSubGroups && !bFound)
- {
- bFound = CompareSubGroups(&tmp_group, &pUniSubGroups[l]);
- if (!bFound) ++l;
- }
-
- // assign tangent space index
- assert(bFound || l==iUniqueSubGroups);
- //piTempTangIndices[f*3+index] = iUniqueTspaces+l;
-
- // if no match was found we allocate a new subgroup
- if (!bFound)
- {
- // insert new subgroup
- int * pIndices = (int *) malloc(sizeof(int)*iMembers);
- if (pIndices==NULL)
- {
- // clean up and return false
- int s=0;
- for (s=0; s<iUniqueSubGroups; s++)
- free(pUniSubGroups[s].pTriMembers);
- free(pUniSubGroups);
- free(pTmpMembers);
- free(pSubGroupTspace);
- return TFALSE;
- }
- pUniSubGroups[iUniqueSubGroups].iNrFaces = iMembers;
- pUniSubGroups[iUniqueSubGroups].pTriMembers = pIndices;
- memcpy(pIndices, tmp_group.pTriMembers, sizeof(int)*iMembers);
- pSubGroupTspace[iUniqueSubGroups] =
- EvalTspace(tmp_group.pTriMembers, iMembers, piTriListIn, pTriInfos, pContext, pGroup->iVertexRepresentitive);
- ++iUniqueSubGroups;
- }
-
- // output tspace
- {
- const int iOffs = pTriInfos[f].iTSpacesOffs;
- const int iVert = pTriInfos[f].vert_num[index];
- STSpace * pTS_out = &psTspace[iOffs+iVert];
- assert(pTS_out->iCounter<2);
- assert(((pTriInfos[f].iFlag&ORIENT_PRESERVING)!=0) == pGroup->bOrientPreservering);
- if (pTS_out->iCounter==1)
- {
- *pTS_out = AvgTSpace(pTS_out, &pSubGroupTspace[l]);
- pTS_out->iCounter = 2; // update counter
- pTS_out->bOrient = pGroup->bOrientPreservering;
- }
- else
- {
- assert(pTS_out->iCounter==0);
- *pTS_out = pSubGroupTspace[l];
- pTS_out->iCounter = 1; // update counter
- pTS_out->bOrient = pGroup->bOrientPreservering;
- }
- }
- }
-
- // clean up and offset iUniqueTspaces
- for (s=0; s<iUniqueSubGroups; s++)
- free(pUniSubGroups[s].pTriMembers);
- iUniqueTspaces += iUniqueSubGroups;
- }
-
- // clean up
- free(pUniSubGroups);
- free(pTmpMembers);
- free(pSubGroupTspace);
-
- return TTRUE;
+ STSpace *pSubGroupTspace = NULL;
+ SSubGroup *pUniSubGroups = NULL;
+ int *pTmpMembers = NULL;
+ int iMaxNrFaces = 0, iUniqueTspaces = 0, g = 0, i = 0;
+ for (g = 0; g < iNrActiveGroups; g++)
+ if (iMaxNrFaces < pGroups[g].iNrFaces)
+ iMaxNrFaces = pGroups[g].iNrFaces;
+
+ if (iMaxNrFaces == 0)
+ return TTRUE;
+
+ // make initial allocations
+ pSubGroupTspace = (STSpace *)malloc(sizeof(STSpace) * iMaxNrFaces);
+ pUniSubGroups = (SSubGroup *)malloc(sizeof(SSubGroup) * iMaxNrFaces);
+ pTmpMembers = (int *)malloc(sizeof(int) * iMaxNrFaces);
+ if (pSubGroupTspace == NULL || pUniSubGroups == NULL || pTmpMembers == NULL) {
+ if (pSubGroupTspace != NULL)
+ free(pSubGroupTspace);
+ if (pUniSubGroups != NULL)
+ free(pUniSubGroups);
+ if (pTmpMembers != NULL)
+ free(pTmpMembers);
+ return TFALSE;
+ }
+
+ iUniqueTspaces = 0;
+ for (g = 0; g < iNrActiveGroups; g++) {
+ const SGroup *pGroup = &pGroups[g];
+ int iUniqueSubGroups = 0, s = 0;
+
+ for (i = 0; i < pGroup->iNrFaces; i++) // triangles
+ {
+ const int f = pGroup->pFaceIndices[i]; // triangle number
+ int index = -1, iVertIndex = -1, iOF_1 = -1, iMembers = 0, j = 0, l = 0;
+ SSubGroup tmp_group;
+ tbool bFound;
+ SVec3 n, vOs, vOt;
+ if (pTriInfos[f].AssignedGroup[0] == pGroup)
+ index = 0;
+ else if (pTriInfos[f].AssignedGroup[1] == pGroup)
+ index = 1;
+ else if (pTriInfos[f].AssignedGroup[2] == pGroup)
+ index = 2;
+ assert(index >= 0 && index < 3);
+
+ iVertIndex = piTriListIn[f * 3 + index];
+ assert(iVertIndex == pGroup->iVertexRepresentitive);
+
+ // is normalized already
+ n = GetNormal(pContext, iVertIndex);
+
+ // project
+ vOs = NormalizeSafe(vsub(pTriInfos[f].vOs, vscale(vdot(n, pTriInfos[f].vOs), n)));
+ vOt = NormalizeSafe(vsub(pTriInfos[f].vOt, vscale(vdot(n, pTriInfos[f].vOt), n)));
+
+ // original face number
+ iOF_1 = pTriInfos[f].iOrgFaceNumber;
+
+ iMembers = 0;
+ for (j = 0; j < pGroup->iNrFaces; j++) {
+ const int t = pGroup->pFaceIndices[j]; // triangle number
+ const int iOF_2 = pTriInfos[t].iOrgFaceNumber;
+
+ // project
+ SVec3 vOs2 = NormalizeSafe(vsub(pTriInfos[t].vOs, vscale(vdot(n, pTriInfos[t].vOs), n)));
+ SVec3 vOt2 = NormalizeSafe(vsub(pTriInfos[t].vOt, vscale(vdot(n, pTriInfos[t].vOt), n)));
+
+ {
+ const tbool bAny = ((pTriInfos[f].iFlag | pTriInfos[t].iFlag) & GROUP_WITH_ANY) != 0 ?
+ TTRUE :
+ TFALSE;
+ // make sure triangles which belong to the same quad are joined.
+ const tbool bSameOrgFace = iOF_1 == iOF_2 ? TTRUE : TFALSE;
+
+ const float fCosS = vdot(vOs, vOs2);
+ const float fCosT = vdot(vOt, vOt2);
+
+ assert(f != t || bSameOrgFace); // sanity check
+ if (bAny || bSameOrgFace || (fCosS > fThresCos && fCosT > fThresCos))
+ pTmpMembers[iMembers++] = t;
+ }
+ }
+
+ // sort pTmpMembers
+ tmp_group.iNrFaces = iMembers;
+ tmp_group.pTriMembers = pTmpMembers;
+ if (iMembers > 1) {
+ unsigned int uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed?
+ QuickSort(pTmpMembers, 0, iMembers - 1, uSeed);
+ }
+
+ // look for an existing match
+ bFound = TFALSE;
+ l = 0;
+ while (l < iUniqueSubGroups && !bFound) {
+ bFound = CompareSubGroups(&tmp_group, &pUniSubGroups[l]);
+ if (!bFound)
+ ++l;
+ }
+
+ // assign tangent space index
+ assert(bFound || l == iUniqueSubGroups);
+ //piTempTangIndices[f*3+index] = iUniqueTspaces+l;
+
+ // if no match was found we allocate a new subgroup
+ if (!bFound) {
+ // insert new subgroup
+ int *pIndices = (int *)malloc(sizeof(int) * iMembers);
+ if (pIndices == NULL) {
+ // clean up and return false
+ int s = 0;
+ for (s = 0; s < iUniqueSubGroups; s++)
+ free(pUniSubGroups[s].pTriMembers);
+ free(pUniSubGroups);
+ free(pTmpMembers);
+ free(pSubGroupTspace);
+ return TFALSE;
+ }
+ pUniSubGroups[iUniqueSubGroups].iNrFaces = iMembers;
+ pUniSubGroups[iUniqueSubGroups].pTriMembers = pIndices;
+ memcpy(pIndices, tmp_group.pTriMembers, sizeof(int) * iMembers);
+ pSubGroupTspace[iUniqueSubGroups] = EvalTspace(tmp_group.pTriMembers,
+ iMembers,
+ piTriListIn,
+ pTriInfos,
+ pContext,
+ pGroup->iVertexRepresentitive);
+ ++iUniqueSubGroups;
+ }
+
+ // output tspace
+ {
+ const int iOffs = pTriInfos[f].iTSpacesOffs;
+ const int iVert = pTriInfos[f].vert_num[index];
+ STSpace *pTS_out = &psTspace[iOffs + iVert];
+ assert(pTS_out->iCounter < 2);
+ assert(((pTriInfos[f].iFlag & ORIENT_PRESERVING) != 0) == pGroup->bOrientPreservering);
+ if (pTS_out->iCounter == 1) {
+ *pTS_out = AvgTSpace(pTS_out, &pSubGroupTspace[l]);
+ pTS_out->iCounter = 2; // update counter
+ pTS_out->bOrient = pGroup->bOrientPreservering;
+ }
+ else {
+ assert(pTS_out->iCounter == 0);
+ *pTS_out = pSubGroupTspace[l];
+ pTS_out->iCounter = 1; // update counter
+ pTS_out->bOrient = pGroup->bOrientPreservering;
+ }
+ }
+ }
+
+ // clean up and offset iUniqueTspaces
+ for (s = 0; s < iUniqueSubGroups; s++)
+ free(pUniSubGroups[s].pTriMembers);
+ iUniqueTspaces += iUniqueSubGroups;
+ }
+
+ // clean up
+ free(pUniSubGroups);
+ free(pTmpMembers);
+ free(pSubGroupTspace);
+
+ return TTRUE;
}
-static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[],
- const SMikkTSpaceContext * pContext, const int iVertexRepresentitive)
+static STSpace EvalTspace(int face_indices[],
+ const int iFaces,
+ const int piTriListIn[],
+ const STriInfo pTriInfos[],
+ const SMikkTSpaceContext *pContext,
+ const int iVertexRepresentitive)
{
- STSpace res;
- float fAngleSum = 0;
- int face=0;
- res.vOs.x=0.0f; res.vOs.y=0.0f; res.vOs.z=0.0f;
- res.vOt.x=0.0f; res.vOt.y=0.0f; res.vOt.z=0.0f;
- res.fMagS = 0; res.fMagT = 0;
-
- for (face=0; face<iFaces; face++)
- {
- const int f = face_indices[face];
-
- // only valid triangles get to add their contribution
- if ( (pTriInfos[f].iFlag&GROUP_WITH_ANY)==0 )
- {
- SVec3 n, vOs, vOt, p0, p1, p2, v1, v2;
- float fCos, fAngle, fMagS, fMagT;
- int i=-1, index=-1, i0=-1, i1=-1, i2=-1;
- if (piTriListIn[3*f+0]==iVertexRepresentitive) i=0;
- else if (piTriListIn[3*f+1]==iVertexRepresentitive) i=1;
- else if (piTriListIn[3*f+2]==iVertexRepresentitive) i=2;
- assert(i>=0 && i<3);
-
- // project
- index = piTriListIn[3*f+i];
- n = GetNormal(pContext, index);
- vOs = NormalizeSafe(vsub(pTriInfos[f].vOs, vscale(vdot(n,pTriInfos[f].vOs), n)));
- vOt = NormalizeSafe(vsub(pTriInfos[f].vOt, vscale(vdot(n,pTriInfos[f].vOt), n)));
-
- i2 = piTriListIn[3*f + (i<2?(i+1):0)];
- i1 = piTriListIn[3*f + i];
- i0 = piTriListIn[3*f + (i>0?(i-1):2)];
-
- p0 = GetPosition(pContext, i0);
- p1 = GetPosition(pContext, i1);
- p2 = GetPosition(pContext, i2);
- v1 = vsub(p0,p1);
- v2 = vsub(p2,p1);
-
- // project
- v1 = NormalizeSafe(vsub(v1, vscale(vdot(n,v1),n)));
- v2 = NormalizeSafe(vsub(v2, vscale(vdot(n,v2),n)));
-
- // weight contribution by the angle
- // between the two edge vectors
- fCos = vdot(v1,v2); fCos=fCos>1?1:(fCos<(-1) ? (-1) : fCos);
- fAngle = (float) acos(fCos);
- fMagS = pTriInfos[f].fMagS;
- fMagT = pTriInfos[f].fMagT;
-
- res.vOs=vadd(res.vOs, vscale(fAngle,vOs));
- res.vOt=vadd(res.vOt,vscale(fAngle,vOt));
- res.fMagS+=(fAngle*fMagS);
- res.fMagT+=(fAngle*fMagT);
- fAngleSum += fAngle;
- }
- }
-
- // normalize
- res.vOs = NormalizeSafe(res.vOs);
- res.vOt = NormalizeSafe(res.vOt);
- if (fAngleSum>0)
- {
- res.fMagS /= fAngleSum;
- res.fMagT /= fAngleSum;
- }
-
- return res;
+ STSpace res;
+ float fAngleSum = 0;
+ int face = 0;
+ res.vOs.x = 0.0f;
+ res.vOs.y = 0.0f;
+ res.vOs.z = 0.0f;
+ res.vOt.x = 0.0f;
+ res.vOt.y = 0.0f;
+ res.vOt.z = 0.0f;
+ res.fMagS = 0;
+ res.fMagT = 0;
+
+ for (face = 0; face < iFaces; face++) {
+ const int f = face_indices[face];
+
+ // only valid triangles get to add their contribution
+ if ((pTriInfos[f].iFlag & GROUP_WITH_ANY) == 0) {
+ SVec3 n, vOs, vOt, p0, p1, p2, v1, v2;
+ float fCos, fAngle, fMagS, fMagT;
+ int i = -1, index = -1, i0 = -1, i1 = -1, i2 = -1;
+ if (piTriListIn[3 * f + 0] == iVertexRepresentitive)
+ i = 0;
+ else if (piTriListIn[3 * f + 1] == iVertexRepresentitive)
+ i = 1;
+ else if (piTriListIn[3 * f + 2] == iVertexRepresentitive)
+ i = 2;
+ assert(i >= 0 && i < 3);
+
+ // project
+ index = piTriListIn[3 * f + i];
+ n = GetNormal(pContext, index);
+ vOs = NormalizeSafe(vsub(pTriInfos[f].vOs, vscale(vdot(n, pTriInfos[f].vOs), n)));
+ vOt = NormalizeSafe(vsub(pTriInfos[f].vOt, vscale(vdot(n, pTriInfos[f].vOt), n)));
+
+ i2 = piTriListIn[3 * f + (i < 2 ? (i + 1) : 0)];
+ i1 = piTriListIn[3 * f + i];
+ i0 = piTriListIn[3 * f + (i > 0 ? (i - 1) : 2)];
+
+ p0 = GetPosition(pContext, i0);
+ p1 = GetPosition(pContext, i1);
+ p2 = GetPosition(pContext, i2);
+ v1 = vsub(p0, p1);
+ v2 = vsub(p2, p1);
+
+ // project
+ v1 = NormalizeSafe(vsub(v1, vscale(vdot(n, v1), n)));
+ v2 = NormalizeSafe(vsub(v2, vscale(vdot(n, v2), n)));
+
+ // weight contribution by the angle
+ // between the two edge vectors
+ fCos = vdot(v1, v2);
+ fCos = fCos > 1 ? 1 : (fCos < (-1) ? (-1) : fCos);
+ fAngle = (float)acos(fCos);
+ fMagS = pTriInfos[f].fMagS;
+ fMagT = pTriInfos[f].fMagT;
+
+ res.vOs = vadd(res.vOs, vscale(fAngle, vOs));
+ res.vOt = vadd(res.vOt, vscale(fAngle, vOt));
+ res.fMagS += (fAngle * fMagS);
+ res.fMagT += (fAngle * fMagT);
+ fAngleSum += fAngle;
+ }
+ }
+
+ // normalize
+ res.vOs = NormalizeSafe(res.vOs);
+ res.vOt = NormalizeSafe(res.vOt);
+ if (fAngleSum > 0) {
+ res.fMagS /= fAngleSum;
+ res.fMagT /= fAngleSum;
+ }
+
+ return res;
}
-static tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2)
+static tbool CompareSubGroups(const SSubGroup *pg1, const SSubGroup *pg2)
{
- tbool bStillSame=TTRUE;
- int i=0;
- if (pg1->iNrFaces!=pg2->iNrFaces) return TFALSE;
- while (i<pg1->iNrFaces && bStillSame)
- {
- bStillSame = pg1->pTriMembers[i]==pg2->pTriMembers[i] ? TTRUE : TFALSE;
- if (bStillSame) ++i;
- }
- return bStillSame;
+ tbool bStillSame = TTRUE;
+ int i = 0;
+ if (pg1->iNrFaces != pg2->iNrFaces)
+ return TFALSE;
+ while (i < pg1->iNrFaces && bStillSame) {
+ bStillSame = pg1->pTriMembers[i] == pg2->pTriMembers[i] ? TTRUE : TFALSE;
+ if (bStillSame)
+ ++i;
+ }
+ return bStillSame;
}
-static void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed)
+static void QuickSort(int *pSortBuffer, int iLeft, int iRight, unsigned int uSeed)
{
- int iL, iR, n, index, iMid, iTmp;
-
- // Random
- unsigned int t=uSeed&31;
- t=(uSeed<<t)|(uSeed>>(32-t));
- uSeed=uSeed+t+3;
- // Random end
-
- iL=iLeft; iR=iRight;
- n = (iR-iL)+1;
- assert(n>=0);
- index = (int) (uSeed%(unsigned int)n);
-
- iMid=pSortBuffer[index + iL];
-
-
- do
- {
- while (pSortBuffer[iL] < iMid)
- ++iL;
- while (pSortBuffer[iR] > iMid)
- --iR;
-
- if (iL <= iR)
- {
- iTmp = pSortBuffer[iL];
- pSortBuffer[iL] = pSortBuffer[iR];
- pSortBuffer[iR] = iTmp;
- ++iL; --iR;
- }
- }
- while (iL <= iR);
-
- if (iLeft < iR)
- QuickSort(pSortBuffer, iLeft, iR, uSeed);
- if (iL < iRight)
- QuickSort(pSortBuffer, iL, iRight, uSeed);
+ int iL, iR, n, index, iMid, iTmp;
+
+ // Random
+ unsigned int t = uSeed & 31;
+ t = (uSeed << t) | (uSeed >> (32 - t));
+ uSeed = uSeed + t + 3;
+ // Random end
+
+ iL = iLeft;
+ iR = iRight;
+ n = (iR - iL) + 1;
+ assert(n >= 0);
+ index = (int)(uSeed % (unsigned int)n);
+
+ iMid = pSortBuffer[index + iL];
+
+ do {
+ while (pSortBuffer[iL] < iMid)
+ ++iL;
+ while (pSortBuffer[iR] > iMid)
+ --iR;
+
+ if (iL <= iR) {
+ iTmp = pSortBuffer[iL];
+ pSortBuffer[iL] = pSortBuffer[iR];
+ pSortBuffer[iR] = iTmp;
+ ++iL;
+ --iR;
+ }
+ } while (iL <= iR);
+
+ if (iLeft < iR)
+ QuickSort(pSortBuffer, iLeft, iR, uSeed);
+ if (iL < iRight)
+ QuickSort(pSortBuffer, iL, iRight, uSeed);
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
-static void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed);
-static void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in);
-
-static void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn)
+static void QuickSortEdges(
+ SEdge *pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed);
+static void GetEdge(int *i0_out,
+ int *i1_out,
+ int *edgenum_out,
+ const int indices[],
+ const int i0_in,
+ const int i1_in);
+
+static void BuildNeighborsFast(STriInfo pTriInfos[],
+ SEdge *pEdges,
+ const int piTriListIn[],
+ const int iNrTrianglesIn)
{
- // build array of edges
- unsigned int uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed?
- int iEntries=0, iCurStartIndex=-1, f=0, i=0;
- for (f=0; f<iNrTrianglesIn; f++)
- for (i=0; i<3; i++)
- {
- const int i0 = piTriListIn[f*3+i];
- const int i1 = piTriListIn[f*3+(i<2?(i+1):0)];
- pEdges[f*3+i].i0 = i0 < i1 ? i0 : i1; // put minimum index in i0
- pEdges[f*3+i].i1 = !(i0 < i1) ? i0 : i1; // put maximum index in i1
- pEdges[f*3+i].f = f; // record face number
- }
-
- // sort over all edges by i0, this is the pricy one.
- QuickSortEdges(pEdges, 0, iNrTrianglesIn*3-1, 0, uSeed); // sort channel 0 which is i0
-
- // sub sort over i1, should be fast.
- // could replace this with a 64 bit int sort over (i0,i1)
- // with i0 as msb in the quicksort call above.
- iEntries = iNrTrianglesIn*3;
- iCurStartIndex = 0;
- for (i=1; i<iEntries; i++)
- {
- if (pEdges[iCurStartIndex].i0 != pEdges[i].i0)
- {
- const int iL = iCurStartIndex;
- const int iR = i-1;
- //const int iElems = i-iL;
- iCurStartIndex = i;
- QuickSortEdges(pEdges, iL, iR, 1, uSeed); // sort channel 1 which is i1
- }
- }
-
- // sub sort over f, which should be fast.
- // this step is to remain compliant with BuildNeighborsSlow() when
- // more than 2 triangles use the same edge (such as a butterfly topology).
- iCurStartIndex = 0;
- for (i=1; i<iEntries; i++)
- {
- if (pEdges[iCurStartIndex].i0 != pEdges[i].i0 || pEdges[iCurStartIndex].i1 != pEdges[i].i1)
- {
- const int iL = iCurStartIndex;
- const int iR = i-1;
- //const int iElems = i-iL;
- iCurStartIndex = i;
- QuickSortEdges(pEdges, iL, iR, 2, uSeed); // sort channel 2 which is f
- }
- }
-
- // pair up, adjacent triangles
- for (i=0; i<iEntries; i++)
- {
- const int i0=pEdges[i].i0;
- const int i1=pEdges[i].i1;
- const int f = pEdges[i].f;
- tbool bUnassigned_A;
-
- int i0_A, i1_A;
- int edgenum_A, edgenum_B=0; // 0,1 or 2
- GetEdge(&i0_A, &i1_A, &edgenum_A, &piTriListIn[f*3], i0, i1); // resolve index ordering and edge_num
- bUnassigned_A = pTriInfos[f].FaceNeighbors[edgenum_A] == -1 ? TTRUE : TFALSE;
-
- if (bUnassigned_A)
- {
- // get true index ordering
- int j=i+1, t;
- tbool bNotFound = TTRUE;
- while (j<iEntries && i0==pEdges[j].i0 && i1==pEdges[j].i1 && bNotFound)
- {
- tbool bUnassigned_B;
- int i0_B, i1_B;
- t = pEdges[j].f;
- // flip i0_B and i1_B
- GetEdge(&i1_B, &i0_B, &edgenum_B, &piTriListIn[t*3], pEdges[j].i0, pEdges[j].i1); // resolve index ordering and edge_num
- //assert(!(i0_A==i1_B && i1_A==i0_B));
- bUnassigned_B = pTriInfos[t].FaceNeighbors[edgenum_B]==-1 ? TTRUE : TFALSE;
- if (i0_A==i0_B && i1_A==i1_B && bUnassigned_B)
- bNotFound = TFALSE;
- else
- ++j;
- }
-
- if (!bNotFound)
- {
- int t = pEdges[j].f;
- pTriInfos[f].FaceNeighbors[edgenum_A] = t;
- //assert(pTriInfos[t].FaceNeighbors[edgenum_B]==-1);
- pTriInfos[t].FaceNeighbors[edgenum_B] = f;
- }
- }
- }
+ // build array of edges
+ unsigned int uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed?
+ int iEntries = 0, iCurStartIndex = -1, f = 0, i = 0;
+ for (f = 0; f < iNrTrianglesIn; f++)
+ for (i = 0; i < 3; i++) {
+ const int i0 = piTriListIn[f * 3 + i];
+ const int i1 = piTriListIn[f * 3 + (i < 2 ? (i + 1) : 0)];
+ pEdges[f * 3 + i].i0 = i0 < i1 ? i0 : i1; // put minimum index in i0
+ pEdges[f * 3 + i].i1 = !(i0 < i1) ? i0 : i1; // put maximum index in i1
+ pEdges[f * 3 + i].f = f; // record face number
+ }
+
+ // sort over all edges by i0, this is the pricy one.
+ QuickSortEdges(pEdges, 0, iNrTrianglesIn * 3 - 1, 0, uSeed); // sort channel 0 which is i0
+
+ // sub sort over i1, should be fast.
+ // could replace this with a 64 bit int sort over (i0,i1)
+ // with i0 as msb in the quicksort call above.
+ iEntries = iNrTrianglesIn * 3;
+ iCurStartIndex = 0;
+ for (i = 1; i < iEntries; i++) {
+ if (pEdges[iCurStartIndex].i0 != pEdges[i].i0) {
+ const int iL = iCurStartIndex;
+ const int iR = i - 1;
+ //const int iElems = i-iL;
+ iCurStartIndex = i;
+ QuickSortEdges(pEdges, iL, iR, 1, uSeed); // sort channel 1 which is i1
+ }
+ }
+
+ // sub sort over f, which should be fast.
+ // this step is to remain compliant with BuildNeighborsSlow() when
+ // more than 2 triangles use the same edge (such as a butterfly topology).
+ iCurStartIndex = 0;
+ for (i = 1; i < iEntries; i++) {
+ if (pEdges[iCurStartIndex].i0 != pEdges[i].i0 || pEdges[iCurStartIndex].i1 != pEdges[i].i1) {
+ const int iL = iCurStartIndex;
+ const int iR = i - 1;
+ //const int iElems = i-iL;
+ iCurStartIndex = i;
+ QuickSortEdges(pEdges, iL, iR, 2, uSeed); // sort channel 2 which is f
+ }
+ }
+
+ // pair up, adjacent triangles
+ for (i = 0; i < iEntries; i++) {
+ const int i0 = pEdges[i].i0;
+ const int i1 = pEdges[i].i1;
+ const int f = pEdges[i].f;
+ tbool bUnassigned_A;
+
+ int i0_A, i1_A;
+ int edgenum_A, edgenum_B = 0; // 0,1 or 2
+ GetEdge(&i0_A,
+ &i1_A,
+ &edgenum_A,
+ &piTriListIn[f * 3],
+ i0,
+ i1); // resolve index ordering and edge_num
+ bUnassigned_A = pTriInfos[f].FaceNeighbors[edgenum_A] == -1 ? TTRUE : TFALSE;
+
+ if (bUnassigned_A) {
+ // get true index ordering
+ int j = i + 1, t;
+ tbool bNotFound = TTRUE;
+ while (j < iEntries && i0 == pEdges[j].i0 && i1 == pEdges[j].i1 && bNotFound) {
+ tbool bUnassigned_B;
+ int i0_B, i1_B;
+ t = pEdges[j].f;
+ // flip i0_B and i1_B
+ GetEdge(&i1_B,
+ &i0_B,
+ &edgenum_B,
+ &piTriListIn[t * 3],
+ pEdges[j].i0,
+ pEdges[j].i1); // resolve index ordering and edge_num
+ //assert(!(i0_A==i1_B && i1_A==i0_B));
+ bUnassigned_B = pTriInfos[t].FaceNeighbors[edgenum_B] == -1 ? TTRUE : TFALSE;
+ if (i0_A == i0_B && i1_A == i1_B && bUnassigned_B)
+ bNotFound = TFALSE;
+ else
+ ++j;
+ }
+
+ if (!bNotFound) {
+ int t = pEdges[j].f;
+ pTriInfos[f].FaceNeighbors[edgenum_A] = t;
+ //assert(pTriInfos[t].FaceNeighbors[edgenum_B]==-1);
+ pTriInfos[t].FaceNeighbors[edgenum_B] = f;
+ }
+ }
+ }
}
-static void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn)
+static void BuildNeighborsSlow(STriInfo pTriInfos[],
+ const int piTriListIn[],
+ const int iNrTrianglesIn)
{
- int f=0, i=0;
- for (f=0; f<iNrTrianglesIn; f++)
- {
- for (i=0; i<3; i++)
- {
- // if unassigned
- if (pTriInfos[f].FaceNeighbors[i] == -1)
- {
- const int i0_A = piTriListIn[f*3+i];
- const int i1_A = piTriListIn[f*3+(i<2?(i+1):0)];
-
- // search for a neighbor
- tbool bFound = TFALSE;
- int t=0, j=0;
- while (!bFound && t<iNrTrianglesIn)
- {
- if (t!=f)
- {
- j=0;
- while (!bFound && j<3)
- {
- // in rev order
- const int i1_B = piTriListIn[t*3+j];
- const int i0_B = piTriListIn[t*3+(j<2?(j+1):0)];
- //assert(!(i0_A==i1_B && i1_A==i0_B));
- if (i0_A==i0_B && i1_A==i1_B)
- bFound = TTRUE;
- else
- ++j;
- }
- }
-
- if (!bFound) ++t;
- }
-
- // assign neighbors
- if (bFound)
- {
- pTriInfos[f].FaceNeighbors[i] = t;
- //assert(pTriInfos[t].FaceNeighbors[j]==-1);
- pTriInfos[t].FaceNeighbors[j] = f;
- }
- }
- }
- }
+ int f = 0, i = 0;
+ for (f = 0; f < iNrTrianglesIn; f++) {
+ for (i = 0; i < 3; i++) {
+ // if unassigned
+ if (pTriInfos[f].FaceNeighbors[i] == -1) {
+ const int i0_A = piTriListIn[f * 3 + i];
+ const int i1_A = piTriListIn[f * 3 + (i < 2 ? (i + 1) : 0)];
+
+ // search for a neighbor
+ tbool bFound = TFALSE;
+ int t = 0, j = 0;
+ while (!bFound && t < iNrTrianglesIn) {
+ if (t != f) {
+ j = 0;
+ while (!bFound && j < 3) {
+ // in rev order
+ const int i1_B = piTriListIn[t * 3 + j];
+ const int i0_B = piTriListIn[t * 3 + (j < 2 ? (j + 1) : 0)];
+ //assert(!(i0_A==i1_B && i1_A==i0_B));
+ if (i0_A == i0_B && i1_A == i1_B)
+ bFound = TTRUE;
+ else
+ ++j;
+ }
+ }
+
+ if (!bFound)
+ ++t;
+ }
+
+ // assign neighbors
+ if (bFound) {
+ pTriInfos[f].FaceNeighbors[i] = t;
+ //assert(pTriInfos[t].FaceNeighbors[j]==-1);
+ pTriInfos[t].FaceNeighbors[j] = f;
+ }
+ }
+ }
+ }
}
-static void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed)
+static void QuickSortEdges(
+ SEdge *pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed)
{
- unsigned int t;
- int iL, iR, n, index, iMid;
-
- // early out
- SEdge sTmp;
- const int iElems = iRight-iLeft+1;
- if (iElems<2) return;
- else if (iElems==2)
- {
- if (pSortBuffer[iLeft].array[channel] > pSortBuffer[iRight].array[channel])
- {
- sTmp = pSortBuffer[iLeft];
- pSortBuffer[iLeft] = pSortBuffer[iRight];
- pSortBuffer[iRight] = sTmp;
- }
- return;
- }
- else if(iElems < 16) {
- int i, j;
- for (i = 0; i < iElems - 1; i++) {
- for (j = 0; j < iElems - i - 1; j++) {
- int index = iLeft + j;
- if (pSortBuffer[index].array[channel] > pSortBuffer[index + 1].array[channel]) {
- sTmp = pSortBuffer[index];
- pSortBuffer[index] = pSortBuffer[index + 1];
- pSortBuffer[index + 1] = sTmp;
- }
- }
- }
- return;
- }
-
- // Random
- t=uSeed&31;
- t=(uSeed<<t)|(uSeed>>(32-t));
- uSeed=uSeed+t+3;
- // Random end
-
- iL = iLeft;
- iR = iRight;
- n = (iR-iL)+1;
- assert(n>=0);
- index = (int) (uSeed%(unsigned int)n);
-
- iMid=pSortBuffer[index + iL].array[channel];
-
- do
- {
- while (pSortBuffer[iL].array[channel] < iMid)
- ++iL;
- while (pSortBuffer[iR].array[channel] > iMid)
- --iR;
-
- if (iL <= iR)
- {
- sTmp = pSortBuffer[iL];
- pSortBuffer[iL] = pSortBuffer[iR];
- pSortBuffer[iR] = sTmp;
- ++iL; --iR;
- }
- }
- while (iL <= iR);
-
- if (iLeft < iR)
- QuickSortEdges(pSortBuffer, iLeft, iR, channel, uSeed);
- if (iL < iRight)
- QuickSortEdges(pSortBuffer, iL, iRight, channel, uSeed);
+ unsigned int t;
+ int iL, iR, n, index, iMid;
+
+ // early out
+ SEdge sTmp;
+ const int iElems = iRight - iLeft + 1;
+ if (iElems < 2)
+ return;
+ else if (iElems == 2) {
+ if (pSortBuffer[iLeft].array[channel] > pSortBuffer[iRight].array[channel]) {
+ sTmp = pSortBuffer[iLeft];
+ pSortBuffer[iLeft] = pSortBuffer[iRight];
+ pSortBuffer[iRight] = sTmp;
+ }
+ return;
+ }
+ else if (iElems < 16) {
+ int i, j;
+ for (i = 0; i < iElems - 1; i++) {
+ for (j = 0; j < iElems - i - 1; j++) {
+ int index = iLeft + j;
+ if (pSortBuffer[index].array[channel] > pSortBuffer[index + 1].array[channel]) {
+ sTmp = pSortBuffer[index];
+ pSortBuffer[index] = pSortBuffer[index + 1];
+ pSortBuffer[index + 1] = sTmp;
+ }
+ }
+ }
+ return;
+ }
+
+ // Random
+ t = uSeed & 31;
+ t = (uSeed << t) | (uSeed >> (32 - t));
+ uSeed = uSeed + t + 3;
+ // Random end
+
+ iL = iLeft;
+ iR = iRight;
+ n = (iR - iL) + 1;
+ assert(n >= 0);
+ index = (int)(uSeed % (unsigned int)n);
+
+ iMid = pSortBuffer[index + iL].array[channel];
+
+ do {
+ while (pSortBuffer[iL].array[channel] < iMid)
+ ++iL;
+ while (pSortBuffer[iR].array[channel] > iMid)
+ --iR;
+
+ if (iL <= iR) {
+ sTmp = pSortBuffer[iL];
+ pSortBuffer[iL] = pSortBuffer[iR];
+ pSortBuffer[iR] = sTmp;
+ ++iL;
+ --iR;
+ }
+ } while (iL <= iR);
+
+ if (iLeft < iR)
+ QuickSortEdges(pSortBuffer, iLeft, iR, channel, uSeed);
+ if (iL < iRight)
+ QuickSortEdges(pSortBuffer, iL, iRight, channel, uSeed);
}
// resolve ordering and edge number
-static void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in)
+static void GetEdge(int *i0_out,
+ int *i1_out,
+ int *edgenum_out,
+ const int indices[],
+ const int i0_in,
+ const int i1_in)
{
- *edgenum_out = -1;
-
- // test if first index is on the edge
- if (indices[0]==i0_in || indices[0]==i1_in)
- {
- // test if second index is on the edge
- if (indices[1]==i0_in || indices[1]==i1_in)
- {
- edgenum_out[0]=0; // first edge
- i0_out[0]=indices[0];
- i1_out[0]=indices[1];
- }
- else
- {
- edgenum_out[0]=2; // third edge
- i0_out[0]=indices[2];
- i1_out[0]=indices[0];
- }
- }
- else
- {
- // only second and third index is on the edge
- edgenum_out[0]=1; // second edge
- i0_out[0]=indices[1];
- i1_out[0]=indices[2];
- }
+ *edgenum_out = -1;
+
+ // test if first index is on the edge
+ if (indices[0] == i0_in || indices[0] == i1_in) {
+ // test if second index is on the edge
+ if (indices[1] == i0_in || indices[1] == i1_in) {
+ edgenum_out[0] = 0; // first edge
+ i0_out[0] = indices[0];
+ i1_out[0] = indices[1];
+ }
+ else {
+ edgenum_out[0] = 2; // third edge
+ i0_out[0] = indices[2];
+ i1_out[0] = indices[0];
+ }
+ }
+ else {
+ // only second and third index is on the edge
+ edgenum_out[0] = 1; // second edge
+ i0_out[0] = indices[1];
+ i1_out[0] = indices[2];
+ }
}
-
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Degenerate triangles ////////////////////////////////////
-static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris)
+static void DegenPrologue(STriInfo pTriInfos[],
+ int piTriList_out[],
+ const int iNrTrianglesIn,
+ const int iTotTris)
{
- int iNextGoodTriangleSearchIndex=-1;
- tbool bStillFindingGoodOnes;
-
- // locate quads with only one good triangle
- int t=0;
- while (t<(iTotTris-1))
- {
- const int iFO_a = pTriInfos[t].iOrgFaceNumber;
- const int iFO_b = pTriInfos[t+1].iOrgFaceNumber;
- if (iFO_a==iFO_b) // this is a quad
- {
- const tbool bIsDeg_a = (pTriInfos[t].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
- const tbool bIsDeg_b = (pTriInfos[t+1].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
- if ((bIsDeg_a^bIsDeg_b)!=0)
- {
- pTriInfos[t].iFlag |= QUAD_ONE_DEGEN_TRI;
- pTriInfos[t+1].iFlag |= QUAD_ONE_DEGEN_TRI;
- }
- t += 2;
- }
- else
- ++t;
- }
-
- // reorder list so all degen triangles are moved to the back
- // without reordering the good triangles
- iNextGoodTriangleSearchIndex = 1;
- t=0;
- bStillFindingGoodOnes = TTRUE;
- while (t<iNrTrianglesIn && bStillFindingGoodOnes)
- {
- const tbool bIsGood = (pTriInfos[t].iFlag&MARK_DEGENERATE)==0 ? TTRUE : TFALSE;
- if (bIsGood)
- {
- if (iNextGoodTriangleSearchIndex < (t+2))
- iNextGoodTriangleSearchIndex = t+2;
- }
- else
- {
- int t0, t1;
- // search for the first good triangle.
- tbool bJustADegenerate = TTRUE;
- while (bJustADegenerate && iNextGoodTriangleSearchIndex<iTotTris)
- {
- const tbool bIsGood = (pTriInfos[iNextGoodTriangleSearchIndex].iFlag&MARK_DEGENERATE)==0 ? TTRUE : TFALSE;
- if (bIsGood) bJustADegenerate=TFALSE;
- else ++iNextGoodTriangleSearchIndex;
- }
-
- t0 = t;
- t1 = iNextGoodTriangleSearchIndex;
- ++iNextGoodTriangleSearchIndex;
- assert(iNextGoodTriangleSearchIndex > (t+1));
-
- // swap triangle t0 and t1
- if (!bJustADegenerate)
- {
- int i=0;
- for (i=0; i<3; i++)
- {
- const int index = piTriList_out[t0*3+i];
- piTriList_out[t0*3+i] = piTriList_out[t1*3+i];
- piTriList_out[t1*3+i] = index;
- }
- {
- const STriInfo tri_info = pTriInfos[t0];
- pTriInfos[t0] = pTriInfos[t1];
- pTriInfos[t1] = tri_info;
- }
- }
- else
- bStillFindingGoodOnes = TFALSE; // this is not supposed to happen
- }
-
- if (bStillFindingGoodOnes) ++t;
- }
-
- assert(bStillFindingGoodOnes); // code will still work.
- assert(iNrTrianglesIn == t);
+ int iNextGoodTriangleSearchIndex = -1;
+ tbool bStillFindingGoodOnes;
+
+ // locate quads with only one good triangle
+ int t = 0;
+ while (t < (iTotTris - 1)) {
+ const int iFO_a = pTriInfos[t].iOrgFaceNumber;
+ const int iFO_b = pTriInfos[t + 1].iOrgFaceNumber;
+ if (iFO_a == iFO_b) // this is a quad
+ {
+ const tbool bIsDeg_a = (pTriInfos[t].iFlag & MARK_DEGENERATE) != 0 ? TTRUE : TFALSE;
+ const tbool bIsDeg_b = (pTriInfos[t + 1].iFlag & MARK_DEGENERATE) != 0 ? TTRUE : TFALSE;
+ if ((bIsDeg_a ^ bIsDeg_b) != 0) {
+ pTriInfos[t].iFlag |= QUAD_ONE_DEGEN_TRI;
+ pTriInfos[t + 1].iFlag |= QUAD_ONE_DEGEN_TRI;
+ }
+ t += 2;
+ }
+ else
+ ++t;
+ }
+
+ // reorder list so all degen triangles are moved to the back
+ // without reordering the good triangles
+ iNextGoodTriangleSearchIndex = 1;
+ t = 0;
+ bStillFindingGoodOnes = TTRUE;
+ while (t < iNrTrianglesIn && bStillFindingGoodOnes) {
+ const tbool bIsGood = (pTriInfos[t].iFlag & MARK_DEGENERATE) == 0 ? TTRUE : TFALSE;
+ if (bIsGood) {
+ if (iNextGoodTriangleSearchIndex < (t + 2))
+ iNextGoodTriangleSearchIndex = t + 2;
+ }
+ else {
+ int t0, t1;
+ // search for the first good triangle.
+ tbool bJustADegenerate = TTRUE;
+ while (bJustADegenerate && iNextGoodTriangleSearchIndex < iTotTris) {
+ const tbool bIsGood = (pTriInfos[iNextGoodTriangleSearchIndex].iFlag & MARK_DEGENERATE) ==
+ 0 ?
+ TTRUE :
+ TFALSE;
+ if (bIsGood)
+ bJustADegenerate = TFALSE;
+ else
+ ++iNextGoodTriangleSearchIndex;
+ }
+
+ t0 = t;
+ t1 = iNextGoodTriangleSearchIndex;
+ ++iNextGoodTriangleSearchIndex;
+ assert(iNextGoodTriangleSearchIndex > (t + 1));
+
+ // swap triangle t0 and t1
+ if (!bJustADegenerate) {
+ int i = 0;
+ for (i = 0; i < 3; i++) {
+ const int index = piTriList_out[t0 * 3 + i];
+ piTriList_out[t0 * 3 + i] = piTriList_out[t1 * 3 + i];
+ piTriList_out[t1 * 3 + i] = index;
+ }
+ {
+ const STriInfo tri_info = pTriInfos[t0];
+ pTriInfos[t0] = pTriInfos[t1];
+ pTriInfos[t1] = tri_info;
+ }
+ }
+ else
+ bStillFindingGoodOnes = TFALSE; // this is not supposed to happen
+ }
+
+ if (bStillFindingGoodOnes)
+ ++t;
+ }
+
+ assert(bStillFindingGoodOnes); // code will still work.
+ assert(iNrTrianglesIn == t);
}
typedef struct VertReverseLookupContext {
- tbool bIsInitialized;
- int * pLookup;
- int iMaxVertIndex;
+ tbool bIsInitialized;
+ int *pLookup;
+ int iMaxVertIndex;
} VertReverseLookupContext;
-static void GenerateReverseLookup(
- const int piTriListIn[],
- const int iNrTrianglesIn,
- VertReverseLookupContext *pLookupCtx)
+static void GenerateReverseLookup(const int piTriListIn[],
+ const int iNrTrianglesIn,
+ VertReverseLookupContext *pLookupCtx)
{
- int t;
- // Figure out what size of lookup array we need.
- pLookupCtx->iMaxVertIndex = -1;
- for (t=0; t<3*iNrTrianglesIn; t++)
- {
- int iVertIndex = piTriListIn[t];
- if (iVertIndex > pLookupCtx->iMaxVertIndex) {
- pLookupCtx->iMaxVertIndex = iVertIndex;
- }
- }
- // Allocate memory.
- if (pLookupCtx->iMaxVertIndex < 1)
- {
- // Nothing to allocate, all triangles are degenerate.
- return;
- }
- pLookupCtx->pLookup = malloc(sizeof(int) * (pLookupCtx->iMaxVertIndex + 1));
- if (pLookupCtx->pLookup == NULL)
- {
- // Most likely run out of memory.
- return;
- }
- // Fill in lookup.
- for (t=0; t<=pLookupCtx->iMaxVertIndex; t++) {
- pLookupCtx->pLookup[t] = -1;
- }
- for (t=0; t<3*iNrTrianglesIn; t++)
- {
- int iVertIndex = piTriListIn[t];
- if (pLookupCtx->pLookup[iVertIndex] != -1)
- {
- continue;
- }
- pLookupCtx->pLookup[iVertIndex] = t;
- }
+ int t;
+ // Figure out what size of lookup array we need.
+ pLookupCtx->iMaxVertIndex = -1;
+ for (t = 0; t < 3 * iNrTrianglesIn; t++) {
+ int iVertIndex = piTriListIn[t];
+ if (iVertIndex > pLookupCtx->iMaxVertIndex) {
+ pLookupCtx->iMaxVertIndex = iVertIndex;
+ }
+ }
+ // Allocate memory.
+ if (pLookupCtx->iMaxVertIndex < 1) {
+ // Nothing to allocate, all triangles are degenerate.
+ return;
+ }
+ pLookupCtx->pLookup = malloc(sizeof(int) * (pLookupCtx->iMaxVertIndex + 1));
+ if (pLookupCtx->pLookup == NULL) {
+ // Most likely run out of memory.
+ return;
+ }
+ // Fill in lookup.
+ for (t = 0; t <= pLookupCtx->iMaxVertIndex; t++) {
+ pLookupCtx->pLookup[t] = -1;
+ }
+ for (t = 0; t < 3 * iNrTrianglesIn; t++) {
+ int iVertIndex = piTriListIn[t];
+ if (pLookupCtx->pLookup[iVertIndex] != -1) {
+ continue;
+ }
+ pLookupCtx->pLookup[iVertIndex] = t;
+ }
}
-static int LookupVertexIndexFromGoodTriangle(
- VertReverseLookupContext *pLookupCtx,
- int piTriListIn[],
- const int iNrTrianglesIn,
- const int iVertexIndex)
+static int LookupVertexIndexFromGoodTriangle(VertReverseLookupContext *pLookupCtx,
+ int piTriListIn[],
+ const int iNrTrianglesIn,
+ const int iVertexIndex)
{
- // Allocate lookup on demand.
- if (!pLookupCtx->bIsInitialized)
- {
- GenerateReverseLookup(piTriListIn,
- iNrTrianglesIn,
- pLookupCtx);
- pLookupCtx->bIsInitialized = TTRUE;
- }
- // Make sure vertex index is in the mapping.
- if (iVertexIndex > pLookupCtx->iMaxVertIndex)
- {
- return -1;
- }
- if (pLookupCtx->pLookup == NULL) {
- return -1;
- }
- // Perform actual lookup.
- return pLookupCtx->pLookup[iVertexIndex];
+ // Allocate lookup on demand.
+ if (!pLookupCtx->bIsInitialized) {
+ GenerateReverseLookup(piTriListIn, iNrTrianglesIn, pLookupCtx);
+ pLookupCtx->bIsInitialized = TTRUE;
+ }
+ // Make sure vertex index is in the mapping.
+ if (iVertexIndex > pLookupCtx->iMaxVertIndex) {
+ return -1;
+ }
+ if (pLookupCtx->pLookup == NULL) {
+ return -1;
+ }
+ // Perform actual lookup.
+ return pLookupCtx->pLookup[iVertexIndex];
}
static void FreeReverseLookup(VertReverseLookupContext *pLookupCtx)
{
- if (!pLookupCtx->bIsInitialized) {
- return;
- }
- if (pLookupCtx->pLookup != NULL) {
- free(pLookupCtx->pLookup);
- }
+ if (!pLookupCtx->bIsInitialized) {
+ return;
+ }
+ if (pLookupCtx->pLookup != NULL) {
+ free(pLookupCtx->pLookup);
+ }
}
static void DegenEpilogue(STSpace psTspace[],
STriInfo pTriInfos[],
int piTriListIn[],
- const SMikkTSpaceContext * pContext,
+ const SMikkTSpaceContext *pContext,
const int iNrTrianglesIn,
const int iTotTris)
{
- int t=0, i=0;
- VertReverseLookupContext lookupCtx = { TFALSE };
- // deal with degenerate triangles
- // punishment for degenerate triangles is O(iNrTrianglesIn) extra memory.
- for (t=iNrTrianglesIn; t<iTotTris; t++)
- {
- // degenerate triangles on a quad with one good triangle are skipped
- // here but processed in the next loop
- const tbool bSkip = (pTriInfos[t].iFlag&QUAD_ONE_DEGEN_TRI)!=0 ? TTRUE : TFALSE;
- if (bSkip) {
- continue;
- }
-
- for (i=0; i<3; i++)
- {
- const int index1 = piTriListIn[t*3+i];
- int j = LookupVertexIndexFromGoodTriangle(&lookupCtx,
- piTriListIn,
- iNrTrianglesIn,
- index1);
- if (j < 0)
- {
- // Matching vertex from good triangle is not found.
- continue;
- }
-
- const int iTri = j/3;
- const int iVert = j%3;
- const int iSrcVert=pTriInfos[iTri].vert_num[iVert];
- const int iSrcOffs=pTriInfos[iTri].iTSpacesOffs;
- const int iDstVert=pTriInfos[t].vert_num[i];
- const int iDstOffs=pTriInfos[t].iTSpacesOffs;
- // copy tspace
- psTspace[iDstOffs+iDstVert] = psTspace[iSrcOffs+iSrcVert];
- }
- }
- FreeReverseLookup(&lookupCtx);
-
- // deal with degenerate quads with one good triangle
- for (t=0; t<iNrTrianglesIn; t++)
- {
- // this triangle belongs to a quad where the
- // other triangle is degenerate
- if ( (pTriInfos[t].iFlag&QUAD_ONE_DEGEN_TRI)!=0 )
- {
- SVec3 vDstP;
- int iOrgF=-1, i=0;
- tbool bNotFound;
- unsigned char * pV = pTriInfos[t].vert_num;
- int iFlag = (1<<pV[0]) | (1<<pV[1]) | (1<<pV[2]);
- int iMissingIndex = 0;
- if ((iFlag&2)==0) iMissingIndex=1;
- else if ((iFlag&4)==0) iMissingIndex=2;
- else if ((iFlag&8)==0) iMissingIndex=3;
-
- iOrgF = pTriInfos[t].iOrgFaceNumber;
- vDstP = GetPosition(pContext, MakeIndex(iOrgF, iMissingIndex));
- bNotFound = TTRUE;
- i=0;
- while (bNotFound && i<3)
- {
- const int iVert = pV[i];
- const SVec3 vSrcP = GetPosition(pContext, MakeIndex(iOrgF, iVert));
- if (veq(vSrcP, vDstP)==TTRUE)
- {
- const int iOffs = pTriInfos[t].iTSpacesOffs;
- psTspace[iOffs+iMissingIndex] = psTspace[iOffs+iVert];
- bNotFound=TFALSE;
- }
- else
- ++i;
- }
- assert(!bNotFound);
- }
- }
+ int t = 0, i = 0;
+ VertReverseLookupContext lookupCtx = {TFALSE};
+ // deal with degenerate triangles
+ // punishment for degenerate triangles is O(iNrTrianglesIn) extra memory.
+ for (t = iNrTrianglesIn; t < iTotTris; t++) {
+ // degenerate triangles on a quad with one good triangle are skipped
+ // here but processed in the next loop
+ const tbool bSkip = (pTriInfos[t].iFlag & QUAD_ONE_DEGEN_TRI) != 0 ? TTRUE : TFALSE;
+ if (bSkip) {
+ continue;
+ }
+
+ for (i = 0; i < 3; i++) {
+ const int index1 = piTriListIn[t * 3 + i];
+ int j = LookupVertexIndexFromGoodTriangle(&lookupCtx, piTriListIn, iNrTrianglesIn, index1);
+ if (j < 0) {
+ // Matching vertex from good triangle is not found.
+ continue;
+ }
+
+ const int iTri = j / 3;
+ const int iVert = j % 3;
+ const int iSrcVert = pTriInfos[iTri].vert_num[iVert];
+ const int iSrcOffs = pTriInfos[iTri].iTSpacesOffs;
+ const int iDstVert = pTriInfos[t].vert_num[i];
+ const int iDstOffs = pTriInfos[t].iTSpacesOffs;
+ // copy tspace
+ psTspace[iDstOffs + iDstVert] = psTspace[iSrcOffs + iSrcVert];
+ }
+ }
+ FreeReverseLookup(&lookupCtx);
+
+ // deal with degenerate quads with one good triangle
+ for (t = 0; t < iNrTrianglesIn; t++) {
+ // this triangle belongs to a quad where the
+ // other triangle is degenerate
+ if ((pTriInfos[t].iFlag & QUAD_ONE_DEGEN_TRI) != 0) {
+ SVec3 vDstP;
+ int iOrgF = -1, i = 0;
+ tbool bNotFound;
+ unsigned char *pV = pTriInfos[t].vert_num;
+ int iFlag = (1 << pV[0]) | (1 << pV[1]) | (1 << pV[2]);
+ int iMissingIndex = 0;
+ if ((iFlag & 2) == 0)
+ iMissingIndex = 1;
+ else if ((iFlag & 4) == 0)
+ iMissingIndex = 2;
+ else if ((iFlag & 8) == 0)
+ iMissingIndex = 3;
+
+ iOrgF = pTriInfos[t].iOrgFaceNumber;
+ vDstP = GetPosition(pContext, MakeIndex(iOrgF, iMissingIndex));
+ bNotFound = TTRUE;
+ i = 0;
+ while (bNotFound && i < 3) {
+ const int iVert = pV[i];
+ const SVec3 vSrcP = GetPosition(pContext, MakeIndex(iOrgF, iVert));
+ if (veq(vSrcP, vDstP) == TTRUE) {
+ const int iOffs = pTriInfos[t].iTSpacesOffs;
+ psTspace[iOffs + iMissingIndex] = psTspace[iOffs + iVert];
+ bNotFound = TFALSE;
+ }
+ else
+ ++i;
+ }
+ assert(!bNotFound);
+ }
+ }
}
diff --git a/intern/mikktspace/mikktspace.h b/intern/mikktspace/mikktspace.h
index dbc8bd59b58..bc5c0d62f4f 100644
--- a/intern/mikktspace/mikktspace.h
+++ b/intern/mikktspace/mikktspace.h
@@ -24,7 +24,6 @@
#ifndef __MIKKTSPACE_H__
#define __MIKKTSPACE_H__
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -58,61 +57,80 @@ extern "C" {
* and also quad triangulator plugin.
*/
-
typedef int tbool;
typedef struct SMikkTSpaceContext SMikkTSpaceContext;
typedef struct {
- // Returns the number of faces (triangles/quads) on the mesh to be processed.
- int (*m_getNumFaces)(const SMikkTSpaceContext * pContext);
-
- // Returns the number of vertices on face number iFace
- // iFace is a number in the range {0, 1, ..., getNumFaces()-1}
- int (*m_getNumVerticesOfFace)(const SMikkTSpaceContext * pContext, const int iFace);
-
- // returns the position/normal/texcoord of the referenced face of vertex number iVert.
- // iVert is in the range {0,1,2} for triangles and {0,1,2,3} for quads.
- void (*m_getPosition)(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert);
- void (*m_getNormal)(const SMikkTSpaceContext * pContext, float fvNormOut[], const int iFace, const int iVert);
- void (*m_getTexCoord)(const SMikkTSpaceContext * pContext, float fvTexcOut[], const int iFace, const int iVert);
-
- // either (or both) of the two setTSpace callbacks can be set.
- // The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
-
- // This function is used to return the tangent and fSign to the application.
- // fvTangent is a unit length vector.
- // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
- // bitangent = fSign * cross(vN, tangent);
- // Note that the results are returned unindexed. It is possible to generate a new index list
- // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
- // DO NOT! use an already existing index list.
- void (*m_setTSpaceBasic)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
-
- // This function is used to return tangent space results to the application.
- // fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are their
- // true magnitudes which can be used for relief mapping effects.
- // fvBiTangent is the "real" bitangent and thus may not be perpendicular to fvTangent.
- // However, both are perpendicular to the vertex normal.
- // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
- // fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
- // bitangent = fSign * cross(vN, tangent);
- // Note that the results are returned unindexed. It is possible to generate a new index list
- // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
- // DO NOT! use an already existing index list.
- void (*m_setTSpace)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
- const tbool bIsOrientationPreserving, const int iFace, const int iVert);
+ // Returns the number of faces (triangles/quads) on the mesh to be processed.
+ int (*m_getNumFaces)(const SMikkTSpaceContext *pContext);
+
+ // Returns the number of vertices on face number iFace
+ // iFace is a number in the range {0, 1, ..., getNumFaces()-1}
+ int (*m_getNumVerticesOfFace)(const SMikkTSpaceContext *pContext, const int iFace);
+
+ // returns the position/normal/texcoord of the referenced face of vertex number iVert.
+ // iVert is in the range {0,1,2} for triangles and {0,1,2,3} for quads.
+ void (*m_getPosition)(const SMikkTSpaceContext *pContext,
+ float fvPosOut[],
+ const int iFace,
+ const int iVert);
+ void (*m_getNormal)(const SMikkTSpaceContext *pContext,
+ float fvNormOut[],
+ const int iFace,
+ const int iVert);
+ void (*m_getTexCoord)(const SMikkTSpaceContext *pContext,
+ float fvTexcOut[],
+ const int iFace,
+ const int iVert);
+
+ // either (or both) of the two setTSpace callbacks can be set.
+ // The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
+
+ // This function is used to return the tangent and fSign to the application.
+ // fvTangent is a unit length vector.
+ // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
+ // bitangent = fSign * cross(vN, tangent);
+ // Note that the results are returned unindexed. It is possible to generate a new index list
+ // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
+ // DO NOT! use an already existing index list.
+ void (*m_setTSpaceBasic)(const SMikkTSpaceContext *pContext,
+ const float fvTangent[],
+ const float fSign,
+ const int iFace,
+ const int iVert);
+
+ // This function is used to return tangent space results to the application.
+ // fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are their
+ // true magnitudes which can be used for relief mapping effects.
+ // fvBiTangent is the "real" bitangent and thus may not be perpendicular to fvTangent.
+ // However, both are perpendicular to the vertex normal.
+ // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
+ // fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
+ // bitangent = fSign * cross(vN, tangent);
+ // Note that the results are returned unindexed. It is possible to generate a new index list
+ // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
+ // DO NOT! use an already existing index list.
+ void (*m_setTSpace)(const SMikkTSpaceContext *pContext,
+ const float fvTangent[],
+ const float fvBiTangent[],
+ const float fMagS,
+ const float fMagT,
+ const tbool bIsOrientationPreserving,
+ const int iFace,
+ const int iVert);
} SMikkTSpaceInterface;
-struct SMikkTSpaceContext
-{
- SMikkTSpaceInterface * m_pInterface; // initialized with callback functions
- void * m_pUserData; // pointer to client side mesh data etc. (passed as the first parameter with every interface call)
+struct SMikkTSpaceContext {
+ SMikkTSpaceInterface *m_pInterface; // initialized with callback functions
+ void *
+ m_pUserData; // pointer to client side mesh data etc. (passed as the first parameter with every interface call)
};
// these are both thread safe!
-tbool genTangSpaceDefault(const SMikkTSpaceContext * pContext); // Default (recommended) fAngularThreshold is 180 degrees (which means threshold disabled)
-tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThreshold);
-
+tbool genTangSpaceDefault(
+ const SMikkTSpaceContext *
+ pContext); // Default (recommended) fAngularThreshold is 180 degrees (which means threshold disabled)
+tbool genTangSpace(const SMikkTSpaceContext *pContext, const float fAngularThreshold);
// To avoid visual errors (distortions/unwanted hard edges in lighting), when using sampled normal maps, the
// normal map sampler must use the exact inverse of the pixel shader transformation.
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt
index 48d619d8d71..da0956cee86 100644
--- a/intern/opencolorio/CMakeLists.txt
+++ b/intern/opencolorio/CMakeLists.txt
@@ -19,11 +19,11 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../glew-mx
- ../guardedalloc
- ../../source/blender/blenlib
- ../../source/blender/gpu
+ .
+ ../glew-mx
+ ../guardedalloc
+ ../../source/blender/blenlib
+ ../../source/blender/gpu
)
set(INC_SYS
@@ -31,44 +31,44 @@ set(INC_SYS
)
set(SRC
- ocio_capi.cc
- fallback_impl.cc
+ ocio_capi.cc
+ fallback_impl.cc
- ocio_capi.h
- ocio_impl.h
+ ocio_capi.h
+ ocio_impl.h
)
set(LIB
)
if(WITH_OPENCOLORIO)
- add_definitions(
- -DWITH_OCIO
- )
+ add_definitions(
+ -DWITH_OCIO
+ )
- add_definitions(${GL_DEFINITIONS})
+ add_definitions(${GL_DEFINITIONS})
- list(APPEND INC_SYS
- ${OPENCOLORIO_INCLUDE_DIRS}
- ${GLEW_INCLUDE_PATH}
- )
+ list(APPEND INC_SYS
+ ${OPENCOLORIO_INCLUDE_DIRS}
+ ${GLEW_INCLUDE_PATH}
+ )
- list(APPEND SRC
- ocio_impl.cc
- ocio_impl_glsl.cc
- )
+ list(APPEND SRC
+ ocio_impl.cc
+ ocio_impl_glsl.cc
+ )
- if(WIN32)
- list(APPEND INC_SYS
- ${BOOST_INCLUDE_DIR}
- )
- add_definitions(
- -DOpenColorIO_STATIC
- )
- endif()
+ if(WIN32)
+ list(APPEND INC_SYS
+ ${BOOST_INCLUDE_DIR}
+ )
+ add_definitions(
+ -DOpenColorIO_STATIC
+ )
+ endif()
- data_to_c_simple(gpu_shader_display_transform.glsl SRC)
- data_to_c_simple(gpu_shader_display_transform_vertex.glsl SRC)
+ data_to_c_simple(gpu_shader_display_transform.glsl SRC)
+ data_to_c_simple(gpu_shader_display_transform_vertex.glsl SRC)
endif()
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 33e7e4f46e3..91f009b3b57 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -28,171 +28,168 @@
using std::max;
-#define CONFIG_DEFAULT ((OCIO_ConstConfigRcPtr*)1)
+#define CONFIG_DEFAULT ((OCIO_ConstConfigRcPtr *)1)
enum TransformType {
- TRANSFORM_LINEAR_TO_SRGB,
- TRANSFORM_SRGB_TO_LINEAR,
- TRANSFORM_MATRIX,
- TRANSFORM_EXPONENT,
- TRANSFORM_UNKNOWN,
+ TRANSFORM_LINEAR_TO_SRGB,
+ TRANSFORM_SRGB_TO_LINEAR,
+ TRANSFORM_MATRIX,
+ TRANSFORM_EXPONENT,
+ TRANSFORM_UNKNOWN,
};
-#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr*)1)
-#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr*)2)
+#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr *)1)
+#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr *)2)
typedef struct OCIO_PackedImageDescription {
- float *data;
- long width;
- long height;
- long numChannels;
- long chanStrideBytes;
- long xStrideBytes;
- long yStrideBytes;
+ float *data;
+ long width;
+ long height;
+ long numChannels;
+ long chanStrideBytes;
+ long xStrideBytes;
+ long yStrideBytes;
} OCIO_PackedImageDescription;
struct FallbackTransform {
- FallbackTransform()
- : type(TRANSFORM_UNKNOWN),
- linear_transform(NULL),
- display_transform(NULL)
- {
- }
-
- ~FallbackTransform()
- {
- delete linear_transform;
- delete display_transform;
- }
-
- void applyRGB(float *pixel)
- {
- if (type == TRANSFORM_LINEAR_TO_SRGB) {
- applyLinearRGB(pixel);
- linearrgb_to_srgb_v3_v3(pixel, pixel);
- applyDisplayRGB(pixel);
- }
- else if (type == TRANSFORM_SRGB_TO_LINEAR) {
- srgb_to_linearrgb_v3_v3(pixel, pixel);
- }
- else if (type == TRANSFORM_EXPONENT) {
- pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
- pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
- pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
- }
- else if (type == TRANSFORM_MATRIX) {
- float r = pixel[0];
- float g = pixel[1];
- float b = pixel[2];
- pixel[0] = r*matrix[0] + g*matrix[1] + b*matrix[2];
- pixel[1] = r*matrix[4] + g*matrix[5] + b*matrix[6];
- pixel[2] = r*matrix[8] + g*matrix[9] + b*matrix[10];
- pixel[0] += offset[0];
- pixel[1] += offset[1];
- pixel[2] += offset[2];
- }
- }
-
- void applyRGBA(float *pixel)
- {
- if (type == TRANSFORM_LINEAR_TO_SRGB) {
- applyLinearRGBA(pixel);
- linearrgb_to_srgb_v4(pixel, pixel);
- applyDisplayRGBA(pixel);
- }
- else if (type == TRANSFORM_SRGB_TO_LINEAR) {
- srgb_to_linearrgb_v4(pixel, pixel);
- }
- else if (type == TRANSFORM_EXPONENT) {
- pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
- pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
- pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
- pixel[3] = powf(max(0.0f, pixel[3]), exponent[3]);
- }
- else if (type == TRANSFORM_MATRIX) {
- float r = pixel[0];
- float g = pixel[1];
- float b = pixel[2];
- float a = pixel[3];
- pixel[0] = r*matrix[0] + g*matrix[1] + b*matrix[2] + a*matrix[3];
- pixel[1] = r*matrix[4] + g*matrix[5] + b*matrix[6] + a*matrix[7];
- pixel[2] = r*matrix[8] + g*matrix[9] + b*matrix[10] + a*matrix[11];
- pixel[3] = r*matrix[12] + g*matrix[13] + b*matrix[14] + a*matrix[15];
- pixel[0] += offset[0];
- pixel[1] += offset[1];
- pixel[2] += offset[2];
- pixel[3] += offset[3];
- }
- }
-
- void applyLinearRGB(float *pixel)
- {
- if (linear_transform != NULL) {
- linear_transform->applyRGB(pixel);
- }
- }
-
- void applyLinearRGBA(float *pixel)
- {
- if (linear_transform != NULL) {
- linear_transform->applyRGBA(pixel);
- }
- }
-
- void applyDisplayRGB(float *pixel)
- {
- if (display_transform != NULL) {
- display_transform->applyRGB(pixel);
- }
- }
-
- void applyDisplayRGBA(float *pixel)
- {
- if (display_transform != NULL) {
- display_transform->applyRGBA(pixel);
- }
- }
-
- TransformType type;
- FallbackTransform *linear_transform;
- FallbackTransform *display_transform;
- /* Exponent transform. */
- float exponent[4];
- /* Matrix transform. */
- float matrix[16];
- float offset[4];
-
- MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
+ FallbackTransform() : type(TRANSFORM_UNKNOWN), linear_transform(NULL), display_transform(NULL)
+ {
+ }
+
+ ~FallbackTransform()
+ {
+ delete linear_transform;
+ delete display_transform;
+ }
+
+ void applyRGB(float *pixel)
+ {
+ if (type == TRANSFORM_LINEAR_TO_SRGB) {
+ applyLinearRGB(pixel);
+ linearrgb_to_srgb_v3_v3(pixel, pixel);
+ applyDisplayRGB(pixel);
+ }
+ else if (type == TRANSFORM_SRGB_TO_LINEAR) {
+ srgb_to_linearrgb_v3_v3(pixel, pixel);
+ }
+ else if (type == TRANSFORM_EXPONENT) {
+ pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
+ pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
+ pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
+ }
+ else if (type == TRANSFORM_MATRIX) {
+ float r = pixel[0];
+ float g = pixel[1];
+ float b = pixel[2];
+ pixel[0] = r * matrix[0] + g * matrix[1] + b * matrix[2];
+ pixel[1] = r * matrix[4] + g * matrix[5] + b * matrix[6];
+ pixel[2] = r * matrix[8] + g * matrix[9] + b * matrix[10];
+ pixel[0] += offset[0];
+ pixel[1] += offset[1];
+ pixel[2] += offset[2];
+ }
+ }
+
+ void applyRGBA(float *pixel)
+ {
+ if (type == TRANSFORM_LINEAR_TO_SRGB) {
+ applyLinearRGBA(pixel);
+ linearrgb_to_srgb_v4(pixel, pixel);
+ applyDisplayRGBA(pixel);
+ }
+ else if (type == TRANSFORM_SRGB_TO_LINEAR) {
+ srgb_to_linearrgb_v4(pixel, pixel);
+ }
+ else if (type == TRANSFORM_EXPONENT) {
+ pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
+ pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
+ pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
+ pixel[3] = powf(max(0.0f, pixel[3]), exponent[3]);
+ }
+ else if (type == TRANSFORM_MATRIX) {
+ float r = pixel[0];
+ float g = pixel[1];
+ float b = pixel[2];
+ float a = pixel[3];
+ pixel[0] = r * matrix[0] + g * matrix[1] + b * matrix[2] + a * matrix[3];
+ pixel[1] = r * matrix[4] + g * matrix[5] + b * matrix[6] + a * matrix[7];
+ pixel[2] = r * matrix[8] + g * matrix[9] + b * matrix[10] + a * matrix[11];
+ pixel[3] = r * matrix[12] + g * matrix[13] + b * matrix[14] + a * matrix[15];
+ pixel[0] += offset[0];
+ pixel[1] += offset[1];
+ pixel[2] += offset[2];
+ pixel[3] += offset[3];
+ }
+ }
+
+ void applyLinearRGB(float *pixel)
+ {
+ if (linear_transform != NULL) {
+ linear_transform->applyRGB(pixel);
+ }
+ }
+
+ void applyLinearRGBA(float *pixel)
+ {
+ if (linear_transform != NULL) {
+ linear_transform->applyRGBA(pixel);
+ }
+ }
+
+ void applyDisplayRGB(float *pixel)
+ {
+ if (display_transform != NULL) {
+ display_transform->applyRGB(pixel);
+ }
+ }
+
+ void applyDisplayRGBA(float *pixel)
+ {
+ if (display_transform != NULL) {
+ display_transform->applyRGBA(pixel);
+ }
+ }
+
+ TransformType type;
+ FallbackTransform *linear_transform;
+ FallbackTransform *display_transform;
+ /* Exponent transform. */
+ float exponent[4];
+ /* Matrix transform. */
+ float matrix[16];
+ float offset[4];
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
};
struct FallbackProcessor {
- FallbackProcessor()
- : transform(NULL)
- {
- }
+ FallbackProcessor() : transform(NULL)
+ {
+ }
- ~FallbackProcessor() {
- delete transform;
- }
+ ~FallbackProcessor()
+ {
+ delete transform;
+ }
- void applyRGB(float *pixel)
- {
- transform->applyRGB(pixel);
- }
+ void applyRGB(float *pixel)
+ {
+ transform->applyRGB(pixel);
+ }
- void applyRGBA(float *pixel)
- {
- transform->applyRGBA(pixel);
- }
+ void applyRGBA(float *pixel)
+ {
+ transform->applyRGBA(pixel);
+ }
- FallbackTransform *transform;
+ FallbackTransform *transform;
- MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
+ MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
};
OCIO_ConstConfigRcPtr *FallbackImpl::getCurrentConfig(void)
{
- return CONFIG_DEFAULT;
+ return CONFIG_DEFAULT;
}
void FallbackImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr * /*config*/)
@@ -201,12 +198,12 @@ void FallbackImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr * /*config*/)
OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromEnv(void)
{
- return NULL;
+ return NULL;
}
OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromFile(const char * /*filename*/)
{
- return CONFIG_DEFAULT;
+ return CONFIG_DEFAULT;
}
void FallbackImpl::configRelease(OCIO_ConstConfigRcPtr * /*config*/)
@@ -215,145 +212,141 @@ void FallbackImpl::configRelease(OCIO_ConstConfigRcPtr * /*config*/)
int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr * /*config*/)
{
- return 2;
+ return 2;
}
const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
int index)
{
- if (index == 0)
- return "Linear";
- else if (index == 1)
- return "sRGB";
-
- return NULL;
+ if (index == 0)
+ return "Linear";
+ else if (index == 1)
+ return "sRGB";
+
+ return NULL;
}
OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/,
const char *name)
{
- if (strcmp(name, "scene_linear") == 0)
- return COLORSPACE_LINEAR;
- else if (strcmp(name, "color_picking") == 0)
- return COLORSPACE_SRGB;
- else if (strcmp(name, "texture_paint") == 0)
- return COLORSPACE_LINEAR;
- else if (strcmp(name, "default_byte") == 0)
- return COLORSPACE_SRGB;
- else if (strcmp(name, "default_float") == 0)
- return COLORSPACE_LINEAR;
- else if (strcmp(name, "default_sequencer") == 0)
- return COLORSPACE_SRGB;
- else if (strcmp(name, "Linear") == 0)
- return COLORSPACE_LINEAR;
- else if (strcmp(name, "sRGB") == 0)
- return COLORSPACE_SRGB;
+ if (strcmp(name, "scene_linear") == 0)
+ return COLORSPACE_LINEAR;
+ else if (strcmp(name, "color_picking") == 0)
+ return COLORSPACE_SRGB;
+ else if (strcmp(name, "texture_paint") == 0)
+ return COLORSPACE_LINEAR;
+ else if (strcmp(name, "default_byte") == 0)
+ return COLORSPACE_SRGB;
+ else if (strcmp(name, "default_float") == 0)
+ return COLORSPACE_LINEAR;
+ else if (strcmp(name, "default_sequencer") == 0)
+ return COLORSPACE_SRGB;
+ else if (strcmp(name, "Linear") == 0)
+ return COLORSPACE_LINEAR;
+ else if (strcmp(name, "sRGB") == 0)
+ return COLORSPACE_SRGB;
- return NULL;
+ return NULL;
}
-int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config,
- const char *name)
+int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
{
- OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name);
+ OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name);
- if (cs == COLORSPACE_LINEAR) {
- return 0;
- }
- else if (cs == COLORSPACE_SRGB) {
- return 1;
- }
- return -1;
+ if (cs == COLORSPACE_LINEAR) {
+ return 0;
+ }
+ else if (cs == COLORSPACE_SRGB) {
+ return 1;
+ }
+ return -1;
}
const char *FallbackImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr * /*config*/)
{
- return "sRGB";
+ return "sRGB";
}
int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr * /*config*/)
{
- return 1;
+ return 1;
}
-const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/,
- int index)
+const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, int index)
{
- if (index == 0) {
- return "sRGB";
- }
- return NULL;
+ if (index == 0) {
+ return "sRGB";
+ }
+ return NULL;
}
const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/,
const char * /*display*/)
{
- return "Default";
+ return "Default";
}
-int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/,
- const char * /*display*/)
+int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/)
{
- return 1;
+ return 1;
}
const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/,
- const char * /*display*/, int index)
+ const char * /*display*/,
+ int index)
{
- if (index == 0) {
- return "Default";
- }
- return NULL;
+ if (index == 0) {
+ return "Default";
+ }
+ return NULL;
}
const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/,
const char * /*display*/,
const char * /*view*/)
{
- return "sRGB";
+ return "sRGB";
}
-void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/,
- float *rgb)
+void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, float *rgb)
{
- /* Here we simply use the older Blender assumed primaries of
- * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute
- * force stupid, but only plausible option given no color management
- * system in place.
- */
+ /* Here we simply use the older Blender assumed primaries of
+ * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute
+ * force stupid, but only plausible option given no color management
+ * system in place.
+ */
- rgb[0] = 0.2126f;
- rgb[1] = 0.7152f;
- rgb[2] = 0.0722f;
+ rgb[0] = 0.2126f;
+ rgb[1] = 0.7152f;
+ rgb[2] = 0.0722f;
}
-void FallbackImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr * /*config*/,
- float xyz_to_rgb[3][3])
+void FallbackImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr * /*config*/, float xyz_to_rgb[3][3])
{
- /* Default to ITU-BT.709. */
- memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
+ /* Default to ITU-BT.709. */
+ memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
}
int FallbackImpl::configGetNumLooks(OCIO_ConstConfigRcPtr * /*config*/)
{
- return 0;
+ return 0;
}
const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
int /*index*/)
{
- return "";
+ return "";
}
OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/,
const char * /*name*/)
{
- return NULL;
+ return NULL;
}
const char *FallbackImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr * /*look*/)
{
- return NULL;
+ return NULL;
}
void FallbackImpl::lookRelease(OCIO_ConstLookRcPtr * /*look*/)
@@ -362,161 +355,156 @@ void FallbackImpl::lookRelease(OCIO_ConstLookRcPtr * /*look*/)
int FallbackImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr * /*cs*/)
{
- return 1;
+ return 1;
}
int FallbackImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr * /*cs*/)
{
- return 0;
+ return 0;
}
void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr * /*cs*/)
{
}
-OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(
- OCIO_ConstConfigRcPtr *config,
- const char *srcName,
- const char *dstName)
+OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName)
{
- OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
- OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
- FallbackTransform *transform = new FallbackTransform();
- if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
- transform->type = TRANSFORM_LINEAR_TO_SRGB;
- }
- else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
- transform->type = TRANSFORM_SRGB_TO_LINEAR;
- }
- else {
- transform->type = TRANSFORM_UNKNOWN;
- }
- FallbackProcessor *processor = new FallbackProcessor();
- processor->transform = transform;
- return (OCIO_ConstProcessorRcPtr *)processor;
+ OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
+ OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
+ FallbackTransform *transform = new FallbackTransform();
+ if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
+ transform->type = TRANSFORM_LINEAR_TO_SRGB;
+ }
+ else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
+ transform->type = TRANSFORM_SRGB_TO_LINEAR;
+ }
+ else {
+ transform->type = TRANSFORM_UNKNOWN;
+ }
+ FallbackProcessor *processor = new FallbackProcessor();
+ processor->transform = transform;
+ return (OCIO_ConstProcessorRcPtr *)processor;
}
OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/,
OCIO_ConstTransformRcPtr *transform)
{
- FallbackProcessor *processor = new FallbackProcessor();
- processor->transform = (FallbackTransform *)transform;
- return (OCIO_ConstProcessorRcPtr *)processor;
+ FallbackProcessor *processor = new FallbackProcessor();
+ processor->transform = (FallbackTransform *)transform;
+ return (OCIO_ConstProcessorRcPtr *)processor;
}
-void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor,
- OCIO_PackedImageDesc *img)
+void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
{
- /* OCIO_TODO stride not respected, channels must be 3 or 4 */
- OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img;
- int channels = desc->numChannels;
- float *pixels = desc->data;
- int width = desc->width;
- int height = desc->height;
- int x, y;
+ /* OCIO_TODO stride not respected, channels must be 3 or 4 */
+ OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription *)img;
+ int channels = desc->numChannels;
+ float *pixels = desc->data;
+ int width = desc->width;
+ int height = desc->height;
+ int x, y;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- float *pixel = pixels + channels * (y * width + x);
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ float *pixel = pixels + channels * (y * width + x);
- if (channels == 4)
- processorApplyRGBA(processor, pixel);
- else if (channels == 3)
- processorApplyRGB(processor, pixel);
- }
- }
+ if (channels == 4)
+ processorApplyRGBA(processor, pixel);
+ else if (channels == 3)
+ processorApplyRGB(processor, pixel);
+ }
+ }
}
void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
OCIO_PackedImageDesc *img)
{
- /* OCIO_TODO stride not respected, channels must be 3 or 4 */
- OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img;
- int channels = desc->numChannels;
- float *pixels = desc->data;
- int width = desc->width;
- int height = desc->height;
- int x, y;
+ /* OCIO_TODO stride not respected, channels must be 3 or 4 */
+ OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription *)img;
+ int channels = desc->numChannels;
+ float *pixels = desc->data;
+ int width = desc->width;
+ int height = desc->height;
+ int x, y;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- float *pixel = pixels + channels * (y * width + x);
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ float *pixel = pixels + channels * (y * width + x);
- if (channels == 4)
- processorApplyRGBA_predivide(processor, pixel);
- else if (channels == 3)
- processorApplyRGB(processor, pixel);
- }
- }
+ if (channels == 4)
+ processorApplyRGBA_predivide(processor, pixel);
+ else if (channels == 3)
+ processorApplyRGB(processor, pixel);
+ }
+ }
}
-void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor,
- float *pixel)
+void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- ((FallbackProcessor *)processor)->applyRGB(pixel);
+ ((FallbackProcessor *)processor)->applyRGB(pixel);
}
-void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor,
- float *pixel)
+void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- ((FallbackProcessor *)processor)->applyRGBA(pixel);
+ ((FallbackProcessor *)processor)->applyRGBA(pixel);
}
-void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor,
- float *pixel)
+void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
- processorApplyRGBA(processor, pixel);
- }
- else {
- float alpha, inv_alpha;
+ if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
+ processorApplyRGBA(processor, pixel);
+ }
+ else {
+ float alpha, inv_alpha;
- alpha = pixel[3];
- inv_alpha = 1.0f / alpha;
+ alpha = pixel[3];
+ inv_alpha = 1.0f / alpha;
- pixel[0] *= inv_alpha;
- pixel[1] *= inv_alpha;
- pixel[2] *= inv_alpha;
+ pixel[0] *= inv_alpha;
+ pixel[1] *= inv_alpha;
+ pixel[2] *= inv_alpha;
- processorApplyRGBA(processor, pixel);
+ processorApplyRGBA(processor, pixel);
- pixel[0] *= alpha;
- pixel[1] *= alpha;
- pixel[2] *= alpha;
- }
+ pixel[0] *= alpha;
+ pixel[1] *= alpha;
+ pixel[2] *= alpha;
+ }
}
void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
{
- delete (FallbackProcessor*)(processor);
+ delete (FallbackProcessor *)(processor);
}
const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
{
- if (cs == COLORSPACE_LINEAR) {
- return "Linear";
- }
- else if (cs == COLORSPACE_SRGB) {
- return "sRGB";
- }
- return NULL;
+ if (cs == COLORSPACE_LINEAR) {
+ return "Linear";
+ }
+ else if (cs == COLORSPACE_SRGB) {
+ return "sRGB";
+ }
+ return NULL;
}
const char *FallbackImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr * /*cs*/)
{
- return "";
+ return "";
}
const char *FallbackImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr * /*cs*/)
{
- return "";
+ return "";
}
OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void)
{
- FallbackTransform *transform = new FallbackTransform();
- transform->type = TRANSFORM_LINEAR_TO_SRGB;
- return (OCIO_DisplayTransformRcPtr*)transform;
+ FallbackTransform *transform = new FallbackTransform();
+ transform->type = TRANSFORM_LINEAR_TO_SRGB;
+ return (OCIO_DisplayTransformRcPtr *)transform;
}
void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/,
@@ -537,15 +525,15 @@ void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/,
void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
OCIO_ConstTransformRcPtr *et)
{
- FallbackTransform *transform = (FallbackTransform *)dt;
- transform->display_transform = (FallbackTransform *)et;
+ FallbackTransform *transform = (FallbackTransform *)dt;
+ transform->display_transform = (FallbackTransform *)et;
}
void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
OCIO_ConstTransformRcPtr *et)
{
- FallbackTransform *transform = (FallbackTransform *)dt;
- transform->linear_transform = (FallbackTransform *)et;
+ FallbackTransform *transform = (FallbackTransform *)dt;
+ transform->linear_transform = (FallbackTransform *)et;
}
void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/,
@@ -562,41 +550,43 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr * /*dt*/)
{
}
-OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(
- float *data,
- long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data,
+ long width,
+ long height,
+ long numChannels,
+ long chanStrideBytes,
+ long xStrideBytes,
+ long yStrideBytes)
{
- OCIO_PackedImageDescription *desc =
- (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription),
- "OCIO_PackedImageDescription");
- desc->data = data;
- desc->width = width;
- desc->height = height;
- desc->numChannels = numChannels;
- desc->chanStrideBytes = chanStrideBytes;
- desc->xStrideBytes = xStrideBytes;
- desc->yStrideBytes = yStrideBytes;
- return (OCIO_PackedImageDesc*)desc;
+ OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription *)MEM_callocN(
+ sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription");
+ desc->data = data;
+ desc->width = width;
+ desc->height = height;
+ desc->numChannels = numChannels;
+ desc->chanStrideBytes = chanStrideBytes;
+ desc->xStrideBytes = xStrideBytes;
+ desc->yStrideBytes = yStrideBytes;
+ return (OCIO_PackedImageDesc *)desc;
}
-void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
+void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
{
- MEM_freeN(id);
+ MEM_freeN(id);
}
OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void)
{
- FallbackTransform *transform = new FallbackTransform();
- transform->type = TRANSFORM_EXPONENT;
- return (OCIO_ExponentTransformRcPtr *)transform;
+ FallbackTransform *transform = new FallbackTransform();
+ transform->type = TRANSFORM_EXPONENT;
+ return (OCIO_ExponentTransformRcPtr *)transform;
}
void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et,
const float *exponent)
{
- FallbackTransform *transform = (FallbackTransform *)et;
- copy_v4_v4(transform->exponent, exponent);
+ FallbackTransform *transform = (FallbackTransform *)et;
+ copy_v4_v4(transform->exponent, exponent);
}
void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr * /*et*/)
@@ -605,49 +595,47 @@ void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr * /*et*/
OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void)
{
- FallbackTransform *transform = new FallbackTransform();
- transform->type = TRANSFORM_MATRIX;
- return (OCIO_MatrixTransformRcPtr *)transform;
+ FallbackTransform *transform = new FallbackTransform();
+ transform->type = TRANSFORM_MATRIX;
+ return (OCIO_MatrixTransformRcPtr *)transform;
}
void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
const float *m44,
const float *offset4)
{
- FallbackTransform *transform = (FallbackTransform *)mt;
- copy_m4_m4((float (*)[4])transform->matrix, (float (*)[4])m44);
- copy_v4_v4(transform->offset, offset4);
+ FallbackTransform *transform = (FallbackTransform *)mt;
+ copy_m4_m4((float(*)[4])transform->matrix, (float(*)[4])m44);
+ copy_v4_v4(transform->offset, offset4);
}
void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr * /*mt*/)
{
}
-void FallbackImpl::matrixTransformScale(float *m44,
- float *offset4,
- const float *scale4)
+void FallbackImpl::matrixTransformScale(float *m44, float *offset4, const float *scale4)
{
- if (scale4 == NULL) {
- return;
- }
- if (m44 != NULL) {
- memset(m44, 0, 16*sizeof(float));
- m44[0] = scale4[0];
- m44[5] = scale4[1];
- m44[10] = scale4[2];
- m44[15] = scale4[3];
- }
- if (offset4 != NULL) {
- offset4[0] = 0.0f;
- offset4[1] = 0.0f;
- offset4[2] = 0.0f;
- offset4[3] = 0.0f;
- }
+ if (scale4 == NULL) {
+ return;
+ }
+ if (m44 != NULL) {
+ memset(m44, 0, 16 * sizeof(float));
+ m44[0] = scale4[0];
+ m44[5] = scale4[1];
+ m44[10] = scale4[2];
+ m44[15] = scale4[3];
+ }
+ if (offset4 != NULL) {
+ offset4[0] = 0.0f;
+ offset4[1] = 0.0f;
+ offset4[2] = 0.0f;
+ offset4[3] = 0.0f;
+ }
}
bool FallbackImpl::supportGLSLDraw(void)
{
- return false;
+ return false;
}
bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/,
@@ -656,7 +644,7 @@ bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/,
float /*dither*/,
bool /*predivide*/)
{
- return false;
+ return false;
}
void FallbackImpl::finishGLSLDraw(OCIO_GLSLDrawState * /*state*/)
@@ -669,10 +657,10 @@ void FallbackImpl::freeGLState(struct OCIO_GLSLDrawState * /*state_r*/)
const char *FallbackImpl::getVersionString(void)
{
- return "fallback";
+ return "fallback";
}
int FallbackImpl::getVersionHex(void)
{
- return 0;
+ return 0;
}
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl
index f1dca04b823..04e96e8ed3c 100644
--- a/intern/opencolorio/gpu_shader_display_transform.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform.glsl
@@ -32,135 +32,140 @@ uniform vec3 curve_mapping_bwmul;
float read_curve_mapping(int table, int index)
{
- /* TODO(sergey): Without -1 here image is getting darken after applying unite curve.
- * But is it actually correct to subtract 1 here?
- */
- float texture_index = float(index) / float(curve_mapping_lut_size - 1);
- return texture(curve_mapping_texture, texture_index)[table];
+ /* TODO(sergey): Without -1 here image is getting darken after applying unite curve.
+ * But is it actually correct to subtract 1 here?
+ */
+ float texture_index = float(index) / float(curve_mapping_lut_size - 1);
+ return texture(curve_mapping_texture, texture_index)[table];
}
float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
{
- if (x <= first[0]) {
- if (use_curve_mapping_extend_extrapolate[table] == 0) {
- /* no extrapolate */
- return first[1];
- }
- else {
- if (curve_mapping_ext_in_x[table] == 0.0)
- return first[1] + curve_mapping_ext_in_y[table] * 10000.0;
- else
- return first[1] + curve_mapping_ext_in_y[table] * (x - first[0]) / curve_mapping_ext_in_x[table];
- }
- }
- else if (x >= last[0]) {
- if (use_curve_mapping_extend_extrapolate[table] == 0) {
- /* no extrapolate */
- return last[1];
- }
- else {
- if (curve_mapping_ext_out_x[table] == 0.0)
- return last[1] - curve_mapping_ext_out_y[table] * 10000.0;
- else
- return last[1] + curve_mapping_ext_out_y[table] * (x - last[0]) / curve_mapping_ext_out_x[table];
- }
- }
- return 0.0;
+ if (x <= first[0]) {
+ if (use_curve_mapping_extend_extrapolate[table] == 0) {
+ /* no extrapolate */
+ return first[1];
+ }
+ else {
+ if (curve_mapping_ext_in_x[table] == 0.0)
+ return first[1] + curve_mapping_ext_in_y[table] * 10000.0;
+ else
+ return first[1] +
+ curve_mapping_ext_in_y[table] * (x - first[0]) / curve_mapping_ext_in_x[table];
+ }
+ }
+ else if (x >= last[0]) {
+ if (use_curve_mapping_extend_extrapolate[table] == 0) {
+ /* no extrapolate */
+ return last[1];
+ }
+ else {
+ if (curve_mapping_ext_out_x[table] == 0.0)
+ return last[1] - curve_mapping_ext_out_y[table] * 10000.0;
+ else
+ return last[1] +
+ curve_mapping_ext_out_y[table] * (x - last[0]) / curve_mapping_ext_out_x[table];
+ }
+ }
+ return 0.0;
}
float curvemap_evaluateF(int table, float value)
{
- float mintable_ = curve_mapping_mintable[table];
- float range = curve_mapping_range[table];
- float mintable = 0.0;
- int CM_TABLE = curve_mapping_lut_size - 1;
-
- float fi;
- int i;
-
- /* index in table */
- fi = (value - mintable) * range;
- i = int(fi);
-
- /* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
- if (fi < 0.0 || fi > float(CM_TABLE)) {
- return curvemap_calc_extend(table, value,
- vec2(curve_mapping_first_x[table], curve_mapping_first_y[table]),
- vec2(curve_mapping_last_x[table], curve_mapping_last_y[table]));
- }
- else {
- if (i < 0) return read_curve_mapping(table, 0);
- if (i >= CM_TABLE) return read_curve_mapping(table, CM_TABLE);
-
- fi = fi - float(i);
- return (1.0 - fi) * read_curve_mapping(table, i) + fi * read_curve_mapping(table, i + 1);
- }
+ float mintable_ = curve_mapping_mintable[table];
+ float range = curve_mapping_range[table];
+ float mintable = 0.0;
+ int CM_TABLE = curve_mapping_lut_size - 1;
+
+ float fi;
+ int i;
+
+ /* index in table */
+ fi = (value - mintable) * range;
+ i = int(fi);
+
+ /* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
+ if (fi < 0.0 || fi > float(CM_TABLE)) {
+ return curvemap_calc_extend(table,
+ value,
+ vec2(curve_mapping_first_x[table], curve_mapping_first_y[table]),
+ vec2(curve_mapping_last_x[table], curve_mapping_last_y[table]));
+ }
+ else {
+ if (i < 0)
+ return read_curve_mapping(table, 0);
+ if (i >= CM_TABLE)
+ return read_curve_mapping(table, CM_TABLE);
+
+ fi = fi - float(i);
+ return (1.0 - fi) * read_curve_mapping(table, i) + fi * read_curve_mapping(table, i + 1);
+ }
}
vec4 curvemapping_evaluate_premulRGBF(vec4 col)
{
- vec4 result = col;
- result[0] = curvemap_evaluateF(0, (col[0] - curve_mapping_black[0]) * curve_mapping_bwmul[0]);
- result[1] = curvemap_evaluateF(1, (col[1] - curve_mapping_black[1]) * curve_mapping_bwmul[1]);
- result[2] = curvemap_evaluateF(2, (col[2] - curve_mapping_black[2]) * curve_mapping_bwmul[2]);
- result[3] = col[3];
- return result;
+ vec4 result = col;
+ result[0] = curvemap_evaluateF(0, (col[0] - curve_mapping_black[0]) * curve_mapping_bwmul[0]);
+ result[1] = curvemap_evaluateF(1, (col[1] - curve_mapping_black[1]) * curve_mapping_bwmul[1]);
+ result[2] = curvemap_evaluateF(2, (col[2] - curve_mapping_black[2]) * curve_mapping_bwmul[2]);
+ result[3] = col[3];
+ return result;
}
#endif
#ifdef USE_DITHER
float dither_random_value(vec2 co)
{
- return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.005 * dither;
+ return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.005 * dither;
}
vec2 round_to_pixel(vec2 st)
{
- vec2 result;
- vec2 size = textureSize(image_texture, 0);
- result.x = float(int(st.x * size.x)) / size.x;
- result.y = float(int(st.y * size.y)) / size.y;
- return result;
+ vec2 result;
+ vec2 size = textureSize(image_texture, 0);
+ result.x = float(int(st.x * size.x)) / size.x;
+ result.y = float(int(st.y * size.y)) / size.y;
+ return result;
}
vec4 apply_dither(vec2 st, vec4 col)
{
- vec4 result;
- float random_value = dither_random_value(round_to_pixel(st));
- result.r = col.r + random_value;
- result.g = col.g + random_value;
- result.b = col.b + random_value;
- result.a = col.a;
- return result;
+ vec4 result;
+ float random_value = dither_random_value(round_to_pixel(st));
+ result.r = col.r + random_value;
+ result.g = col.g + random_value;
+ result.b = col.b + random_value;
+ result.a = col.a;
+ return result;
}
#endif
void main()
{
- vec4 col = texture(image_texture, texCoord_interp.st);
+ vec4 col = texture(image_texture, texCoord_interp.st);
#ifdef USE_CURVE_MAPPING
- col = curvemapping_evaluate_premulRGBF(col);
+ col = curvemapping_evaluate_premulRGBF(col);
#endif
#ifdef USE_PREDIVIDE
- if (col[3] > 0.0 && col[3] < 1.0) {
- float inv_alpha = 1.0 / col[3];
- col[0] *= inv_alpha;
- col[1] *= inv_alpha;
- col[2] *= inv_alpha;
- }
+ if (col[3] > 0.0 && col[3] < 1.0) {
+ float inv_alpha = 1.0 / col[3];
+ col[0] *= inv_alpha;
+ col[1] *= inv_alpha;
+ col[2] *= inv_alpha;
+ }
#endif
- /* NOTE: This is true we only do de-premul here and NO premul
- * and the reason is simple -- opengl is always configured
- * for straight alpha at this moment
- */
+ /* NOTE: This is true we only do de-premul here and NO premul
+ * and the reason is simple -- opengl is always configured
+ * for straight alpha at this moment
+ */
- vec4 result = OCIODisplay(col, lut3d_texture);
+ vec4 result = OCIODisplay(col, lut3d_texture);
#ifdef USE_DITHER
- result = apply_dither(texCoord_interp.st, result);
+ result = apply_dither(texCoord_interp.st, result);
#endif
- fragColor = result;
+ fragColor = result;
}
diff --git a/intern/opencolorio/gpu_shader_display_transform_vertex.glsl b/intern/opencolorio/gpu_shader_display_transform_vertex.glsl
index 054f7f3ec91..8cf9628b06b 100644
--- a/intern/opencolorio/gpu_shader_display_transform_vertex.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform_vertex.glsl
@@ -7,6 +7,6 @@ out vec2 texCoord_interp;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f);
- texCoord_interp = texCoord;
+ gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f);
+ texCoord_interp = texCoord;
}
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index bec452db260..530d1fb8a27 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -26,329 +26,346 @@ static IOCIOImpl *impl = NULL;
void OCIO_init(void)
{
#ifdef WITH_OCIO
- impl = new OCIOImpl();
+ impl = new OCIOImpl();
#else
- impl = new FallbackImpl();
+ impl = new FallbackImpl();
#endif
}
void OCIO_exit(void)
{
- delete impl;
- impl = NULL;
+ delete impl;
+ impl = NULL;
}
OCIO_ConstConfigRcPtr *OCIO_getCurrentConfig(void)
{
- return impl->getCurrentConfig();
+ return impl->getCurrentConfig();
}
OCIO_ConstConfigRcPtr *OCIO_configCreateFallback(void)
{
- delete impl;
- impl = new FallbackImpl();
+ delete impl;
+ impl = new FallbackImpl();
- return impl->getCurrentConfig();
+ return impl->getCurrentConfig();
}
void OCIO_setCurrentConfig(const OCIO_ConstConfigRcPtr *config)
{
- impl->setCurrentConfig(config);
+ impl->setCurrentConfig(config);
}
OCIO_ConstConfigRcPtr *OCIO_configCreateFromEnv(void)
{
- return impl->configCreateFromEnv();
+ return impl->configCreateFromEnv();
}
OCIO_ConstConfigRcPtr *OCIO_configCreateFromFile(const char *filename)
{
- return impl->configCreateFromFile(filename);
+ return impl->configCreateFromFile(filename);
}
void OCIO_configRelease(OCIO_ConstConfigRcPtr *config)
{
- impl->configRelease(config);
+ impl->configRelease(config);
}
int OCIO_configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
{
- return impl->configGetNumColorSpaces(config);
+ return impl->configGetNumColorSpaces(config);
}
const char *OCIO_configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
{
- return impl->configGetColorSpaceNameByIndex(config, index);
+ return impl->configGetColorSpaceNameByIndex(config, index);
}
-OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
+OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config,
+ const char *name)
{
- return impl->configGetColorSpace(config, name);
+ return impl->configGetColorSpace(config, name);
}
int OCIO_configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
{
- return impl->configGetIndexForColorSpace(config, name);
+ return impl->configGetIndexForColorSpace(config, name);
}
const char *OCIO_configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config)
{
- return impl->configGetDefaultDisplay(config);
+ return impl->configGetDefaultDisplay(config);
}
-int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr* config)
+int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr *config)
{
- return impl->configGetNumDisplays(config);
+ return impl->configGetNumDisplays(config);
}
const char *OCIO_configGetDisplay(OCIO_ConstConfigRcPtr *config, int index)
{
- return impl->configGetDisplay(config, index);
+ return impl->configGetDisplay(config, index);
}
const char *OCIO_configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display)
{
- return impl->configGetDefaultView(config, display);
+ return impl->configGetDefaultView(config, display);
}
int OCIO_configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display)
{
- return impl->configGetNumViews(config, display);
+ return impl->configGetNumViews(config, display);
}
const char *OCIO_configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index)
{
- return impl->configGetView(config, display, index);
+ return impl->configGetView(config, display, index);
}
-const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view)
+const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
+ const char *display,
+ const char *view)
{
- return impl->configGetDisplayColorSpaceName(config, display, view);
+ return impl->configGetDisplayColorSpaceName(config, display, view);
}
void OCIO_configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb)
{
- impl->configGetDefaultLumaCoefs(config, rgb);
+ impl->configGetDefaultLumaCoefs(config, rgb);
}
void OCIO_configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3])
{
- impl->configGetXYZtoRGB(config, xyz_to_rgb);
+ impl->configGetXYZtoRGB(config, xyz_to_rgb);
}
int OCIO_configGetNumLooks(OCIO_ConstConfigRcPtr *config)
{
- return impl->configGetNumLooks(config);
+ return impl->configGetNumLooks(config);
}
const char *OCIO_configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
{
- return impl->configGetLookNameByIndex(config, index);
+ return impl->configGetLookNameByIndex(config, index);
}
OCIO_ConstLookRcPtr *OCIO_configGetLook(OCIO_ConstConfigRcPtr *config, const char *name)
{
- return impl->configGetLook(config, name);
+ return impl->configGetLook(config, name);
}
const char *OCIO_lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
{
- return impl->lookGetProcessSpace(look);
+ return impl->lookGetProcessSpace(look);
}
void OCIO_lookRelease(OCIO_ConstLookRcPtr *look)
{
- impl->lookRelease(look);
+ impl->lookRelease(look);
}
int OCIO_colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs)
{
- return impl->colorSpaceIsInvertible(cs);
+ return impl->colorSpaceIsInvertible(cs);
}
int OCIO_colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs)
{
- return impl->colorSpaceIsData(cs);
+ return impl->colorSpaceIsData(cs);
}
void OCIO_colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
{
- impl->colorSpaceRelease(cs);
+ impl->colorSpaceRelease(cs);
}
-OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName)
+OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName)
{
- return impl->configGetProcessorWithNames(config, srcName, dstName);
+ return impl->configGetProcessorWithNames(config, srcName, dstName);
}
-OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform)
+OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config,
+ OCIO_ConstTransformRcPtr *transform)
{
- return impl->configGetProcessor(config, transform);
+ return impl->configGetProcessor(config, transform);
}
void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
{
- impl->processorApply(processor, img);
+ impl->processorApply(processor, img);
}
void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
{
- impl->processorApply_predivide(processor, img);
+ impl->processorApply_predivide(processor, img);
}
void OCIO_processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- impl->processorApplyRGB(processor, pixel);
+ impl->processorApplyRGB(processor, pixel);
}
void OCIO_processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- impl->processorApplyRGBA(processor, pixel);
+ impl->processorApplyRGBA(processor, pixel);
}
void OCIO_processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- impl->processorApplyRGBA_predivide(processor, pixel);
+ impl->processorApplyRGBA_predivide(processor, pixel);
}
void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *p)
{
- impl->processorRelease(p);
+ impl->processorRelease(p);
}
const char *OCIO_colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
{
- return impl->colorSpaceGetName(cs);
+ return impl->colorSpaceGetName(cs);
}
const char *OCIO_colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs)
{
- return impl->colorSpaceGetDescription(cs);
+ return impl->colorSpaceGetDescription(cs);
}
const char *OCIO_colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
{
- return impl->colorSpaceGetFamily(cs);
+ return impl->colorSpaceGetFamily(cs);
}
OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void)
{
- return impl->createDisplayTransform();
+ return impl->createDisplayTransform();
}
void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name)
{
- impl->displayTransformSetInputColorSpaceName(dt, name);
+ impl->displayTransformSetInputColorSpaceName(dt, name);
}
void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name)
{
- impl->displayTransformSetDisplay(dt, name);
+ impl->displayTransformSetDisplay(dt, name);
}
void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name)
{
- impl->displayTransformSetView(dt, name);
+ impl->displayTransformSetView(dt, name);
}
void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t)
{
- impl->displayTransformSetDisplayCC(dt, t);
+ impl->displayTransformSetDisplayCC(dt, t);
}
void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t)
{
- impl->displayTransformSetLinearCC(dt, t);
+ impl->displayTransformSetLinearCC(dt, t);
}
void OCIO_displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks)
{
- impl->displayTransformSetLooksOverride(dt, looks);
+ impl->displayTransformSetLooksOverride(dt, looks);
}
void OCIO_displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled)
{
- impl->displayTransformSetLooksOverrideEnabled(dt, enabled);
+ impl->displayTransformSetLooksOverrideEnabled(dt, enabled);
}
void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
{
- impl->displayTransformRelease(dt);
+ impl->displayTransformRelease(dt);
}
-OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data,
+ long width,
+ long height,
+ long numChannels,
+ long chanStrideBytes,
+ long xStrideBytes,
+ long yStrideBytes)
{
- return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
+ return impl->createOCIO_PackedImageDesc(
+ data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
}
-void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
+void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
{
- impl->OCIO_PackedImageDescRelease(id);
+ impl->OCIO_PackedImageDescRelease(id);
}
OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void)
{
- return impl->createExponentTransform();
+ return impl->createExponentTransform();
}
void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent)
{
- impl->exponentTransformSetValue(et, exponent);
+ impl->exponentTransformSetValue(et, exponent);
}
void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et)
{
- impl->exponentTransformRelease(et);
+ impl->exponentTransformRelease(et);
}
OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void)
{
- return impl->createMatrixTransform();
+ return impl->createMatrixTransform();
}
-void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4)
+void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
+ const float *m44,
+ const float *offset4)
{
- impl->matrixTransformSetValue(mt, m44, offset4);
+ impl->matrixTransformSetValue(mt, m44, offset4);
}
void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt)
{
- impl->matrixTransformRelease(mt);
+ impl->matrixTransformRelease(mt);
}
void OCIO_matrixTransformScale(float *m44, float *offset4, const float *scale4f)
{
- impl->matrixTransformScale(m44, offset4, scale4f);
+ impl->matrixTransformScale(m44, offset4, scale4f);
}
int OCIO_supportGLSLDraw(void)
{
- return (int) impl->supportGLSLDraw();
+ return (int)impl->supportGLSLDraw();
}
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
- OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide)
+int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
+ OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ float dither,
+ bool predivide)
{
- return (int) impl->setupGLSLDraw(state_r, processor, curve_mapping_settings, dither, predivide);
+ return (int)impl->setupGLSLDraw(state_r, processor, curve_mapping_settings, dither, predivide);
}
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state)
{
- impl->finishGLSLDraw(state);
+ impl->finishGLSLDraw(state);
}
void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state)
{
- impl->freeGLState(state);
+ impl->freeGLState(state);
}
const char *OCIO_getVersionString(void)
{
- return impl->getVersionString();
+ return impl->getVersionString();
}
int OCIO_getVersionHex(void)
{
- return impl->getVersionHex();
+ return impl->getVersionHex();
}
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index bc1667398fb..9af302647a3 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -26,14 +26,17 @@ extern "C" {
struct OCIO_GLSLDrawState;
-#define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
-
-#define OCIO_ROLE_SCENE_LINEAR "scene_linear"
-#define OCIO_ROLE_COLOR_PICKING "color_picking"
-#define OCIO_ROLE_TEXTURE_PAINT "texture_paint"
-#define OCIO_ROLE_DEFAULT_BYTE "default_byte"
-#define OCIO_ROLE_DEFAULT_FLOAT "default_float"
-#define OCIO_ROLE_DEFAULT_SEQUENCER "default_sequencer"
+#define OCIO_DECLARE_HANDLE(name) \
+ typedef struct name##__ { \
+ int unused; \
+ } * name
+
+#define OCIO_ROLE_SCENE_LINEAR "scene_linear"
+#define OCIO_ROLE_COLOR_PICKING "color_picking"
+#define OCIO_ROLE_TEXTURE_PAINT "texture_paint"
+#define OCIO_ROLE_DEFAULT_BYTE "default_byte"
+#define OCIO_ROLE_DEFAULT_FLOAT "default_float"
+#define OCIO_ROLE_DEFAULT_SEQUENCER "default_sequencer"
OCIO_DECLARE_HANDLE(OCIO_ConstConfigRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstColorSpaceRcPtr);
@@ -47,66 +50,64 @@ OCIO_DECLARE_HANDLE(OCIO_MatrixTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstLookRcPtr);
/* Standard XYZ to linear sRGB transform, for fallback. */
-static const float OCIO_XYZ_TO_LINEAR_SRGB[3][3] = {
- {3.2404542f, -0.9692660f, 0.0556434f},
- {-1.5371385f, 1.8760108f, -0.2040259f},
- {-0.4985314f, 0.0415560f, 1.0572252f}};
-
+static const float OCIO_XYZ_TO_LINEAR_SRGB[3][3] = {{3.2404542f, -0.9692660f, 0.0556434f},
+ {-1.5371385f, 1.8760108f, -0.2040259f},
+ {-0.4985314f, 0.0415560f, 1.0572252f}};
/* This structure is used to pass curve mapping settings from
* blender's DNA structure stored in view transform settings
* to a generic OpenColorIO C-API.
*/
typedef struct OCIO_CurveMappingSettings {
- /* This is a LUT which contain values for all 4 curve mapping tables
- * (combined, R, G and B).
- *
- * Element I for table T is stored at I * 4 + T element of this LUT.
- *
- * This array is usually returned by curvemapping_table_RGBA().
- */
- float *lut;
-
- /* Size of single curve mapping table, 1/4 size of lut array. */
- int lut_size;
-
- /* Extend extrapolation flags for all the tables.
- * if use_extend_extrapolate[T] != 0 means extrapolation for
- * table T is needed.
- */
- int use_extend_extrapolate[4];
-
- /* Minimal X value of the curve mapping tables. */
- float mintable[4];
-
- /* Per curve mapping table range. */
- float range[4];
-
- /* Lower extension value, stored as per-component arrays. */
- float ext_in_x[4], ext_in_y[4];
-
- /* Higher extension value, stored as per-component arrays. */
- float ext_out_x[4], ext_out_y[4];
-
- /* First points of the tables, both X and Y values.
- * Needed for easier and faster access when extrapolating.
- */
- float first_x[4], first_y[4];
-
- /* Last points of the tables, both X and Y values.
- * Needed for easier and faster access when extrapolating.
- */
- float last_x[4], last_y[4];
-
- /* Premultiplication settings: black level and scale to match
- * with white level.
- */
- float black[3], bwmul[3];
-
- /* Cache id of the original curve mapping, used to detect when
- * upload of new settings to GPU is needed.
- */
- size_t cache_id;
+ /* This is a LUT which contain values for all 4 curve mapping tables
+ * (combined, R, G and B).
+ *
+ * Element I for table T is stored at I * 4 + T element of this LUT.
+ *
+ * This array is usually returned by curvemapping_table_RGBA().
+ */
+ float *lut;
+
+ /* Size of single curve mapping table, 1/4 size of lut array. */
+ int lut_size;
+
+ /* Extend extrapolation flags for all the tables.
+ * if use_extend_extrapolate[T] != 0 means extrapolation for
+ * table T is needed.
+ */
+ int use_extend_extrapolate[4];
+
+ /* Minimal X value of the curve mapping tables. */
+ float mintable[4];
+
+ /* Per curve mapping table range. */
+ float range[4];
+
+ /* Lower extension value, stored as per-component arrays. */
+ float ext_in_x[4], ext_in_y[4];
+
+ /* Higher extension value, stored as per-component arrays. */
+ float ext_out_x[4], ext_out_y[4];
+
+ /* First points of the tables, both X and Y values.
+ * Needed for easier and faster access when extrapolating.
+ */
+ float first_x[4], first_y[4];
+
+ /* Last points of the tables, both X and Y values.
+ * Needed for easier and faster access when extrapolating.
+ */
+ float last_x[4], last_y[4];
+
+ /* Premultiplication settings: black level and scale to match
+ * with white level.
+ */
+ float black[3], bwmul[3];
+
+ /* Cache id of the original curve mapping, used to detect when
+ * upload of new settings to GPU is needed.
+ */
+ size_t cache_id;
} OCIO_CurveMappingSettings;
void OCIO_init(void);
@@ -116,14 +117,15 @@ OCIO_ConstConfigRcPtr *OCIO_getCurrentConfig(void);
void OCIO_setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
OCIO_ConstConfigRcPtr *OCIO_configCreateFromEnv(void);
-OCIO_ConstConfigRcPtr *OCIO_configCreateFromFile(const char* filename);
+OCIO_ConstConfigRcPtr *OCIO_configCreateFromFile(const char *filename);
OCIO_ConstConfigRcPtr *OCIO_configCreateFallback(void);
void OCIO_configRelease(OCIO_ConstConfigRcPtr *config);
int OCIO_configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config);
const char *OCIO_configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
-OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
+OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config,
+ const char *name);
int OCIO_configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
int OCIO_colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs);
@@ -132,25 +134,30 @@ int OCIO_colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs);
void OCIO_colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs);
const char *OCIO_configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config);
-int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
+int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
const char *OCIO_configGetDisplay(OCIO_ConstConfigRcPtr *config, int index);
const char *OCIO_configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display);
-int OCIO_configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
+int OCIO_configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
const char *OCIO_configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index);
-const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view);
+const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
+ const char *display,
+ const char *view);
-void OCIO_configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
-void OCIO_configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
+void OCIO_configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
+void OCIO_configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
-int OCIO_configGetNumLooks(OCIO_ConstConfigRcPtr *config);
-const char *OCIO_configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
+int OCIO_configGetNumLooks(OCIO_ConstConfigRcPtr *config);
+const char *OCIO_configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
OCIO_ConstLookRcPtr *OCIO_configGetLook(OCIO_ConstConfigRcPtr *config, const char *name);
const char *OCIO_lookGetProcessSpace(OCIO_ConstLookRcPtr *look);
void OCIO_lookRelease(OCIO_ConstLookRcPtr *look);
-OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName);
-OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform);
+OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName);
+OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config,
+ OCIO_ConstTransformRcPtr *transform);
void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
@@ -168,14 +175,21 @@ OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void);
void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
-void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
-void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
+void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *et);
+void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *et);
void OCIO_displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
void OCIO_displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
-OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes);
+OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data,
+ long width,
+ long height,
+ long numChannels,
+ long chanStrideBytes,
+ long xStrideBytes,
+ long yStrideBytes);
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
@@ -184,14 +198,19 @@ void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float
void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void);
-void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4);
+void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
+ const float *m44,
+ const float *offset4);
void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
void OCIO_matrixTransformScale(float *m44, float *offset4, const float *scale4);
int OCIO_supportGLSLDraw(void);
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
- OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide);
+int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
+ OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ float dither,
+ bool predivide);
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index 729f6fa3f90..3917ed234c7 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -62,248 +62,249 @@ using namespace OCIO_NAMESPACE;
# include <vector>
# include <string>
# include <set>
-using std::vector;
+using std::map;
using std::set;
using std::string;
-using std::map;
+using std::vector;
#endif
static void OCIO_reportError(const char *err)
{
- std::cerr << "OpenColorIO Error: " << err << std::endl;
+ std::cerr << "OpenColorIO Error: " << err << std::endl;
- OCIO_abort();
+ OCIO_abort();
}
static void OCIO_reportException(Exception &exception)
{
- OCIO_reportError(exception.what());
+ OCIO_reportError(exception.what());
}
OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
{
- ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
+ ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
- try {
- *config = GetCurrentConfig();
+ try {
+ *config = GetCurrentConfig();
- if (*config)
- return (OCIO_ConstConfigRcPtr *) config;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ if (*config)
+ return (OCIO_ConstConfigRcPtr *)config;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
- return NULL;
+ return NULL;
}
void OCIOImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *config)
{
- try {
- SetCurrentConfig(*(ConstConfigRcPtr *) config);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ SetCurrentConfig(*(ConstConfigRcPtr *)config);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
}
OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
{
- ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
+ ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
- try {
- *config = Config::CreateFromEnv();
+ try {
+ *config = Config::CreateFromEnv();
- if (*config)
- return (OCIO_ConstConfigRcPtr *) config;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ if (*config)
+ return (OCIO_ConstConfigRcPtr *)config;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
- return NULL;
+ return NULL;
}
-
OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
{
- ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
+ ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
- try {
- *config = Config::CreateFromFile(filename);
+ try {
+ *config = Config::CreateFromFile(filename);
- if (*config)
- return (OCIO_ConstConfigRcPtr *) config;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ if (*config)
+ return (OCIO_ConstConfigRcPtr *)config;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
- return NULL;
+ return NULL;
}
void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config)
{
- OBJECT_GUARDED_DELETE((ConstConfigRcPtr *) config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE((ConstConfigRcPtr *)config, ConstConfigRcPtr);
}
int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getNumColorSpaces();
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getNumColorSpaces();
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return 0;
+ return 0;
}
const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getColorSpaceNameByIndex(index);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getColorSpaceNameByIndex(index);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
-OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
+OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config,
+ const char *name)
{
- ConstColorSpaceRcPtr *cs = OBJECT_GUARDED_NEW(ConstColorSpaceRcPtr);
+ ConstColorSpaceRcPtr *cs = OBJECT_GUARDED_NEW(ConstColorSpaceRcPtr);
- try {
- *cs = (*(ConstConfigRcPtr *) config)->getColorSpace(name);
+ try {
+ *cs = (*(ConstConfigRcPtr *)config)->getColorSpace(name);
- if (*cs)
- return (OCIO_ConstColorSpaceRcPtr *) cs;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ if (*cs)
+ return (OCIO_ConstColorSpaceRcPtr *)cs;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- OBJECT_GUARDED_DELETE(cs, ConstColorSpaceRcPtr);
+ OBJECT_GUARDED_DELETE(cs, ConstColorSpaceRcPtr);
- return NULL;
+ return NULL;
}
int OCIOImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getIndexForColorSpace(name);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getIndexForColorSpace(name);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return -1;
+ return -1;
}
const char *OCIOImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config)
{
#ifdef DEFAULT_DISPLAY_WORKAROUND
- if (getenv("OCIO_ACTIVE_DISPLAYS") == NULL) {
- const char *active_displays =
- (*(ConstConfigRcPtr *) config)->getActiveDisplays();
- if (active_displays[0] != '\0') {
- const char *separator_pos = strchr(active_displays, ',');
- if (separator_pos == NULL) {
- return active_displays;
- }
- static std::string active_display;
- /* NOTE: Configuration is shared and is never changed during
- * runtime, so we only guarantee two threads don't initialize at the
- * same. */
- static std::mutex mutex;
- mutex.lock();
- if (active_display.empty()) {
- active_display = active_displays;
- active_display[separator_pos - active_displays] = '\0';
- }
- mutex.unlock();
- return active_display.c_str();
- }
- }
+ if (getenv("OCIO_ACTIVE_DISPLAYS") == NULL) {
+ const char *active_displays = (*(ConstConfigRcPtr *)config)->getActiveDisplays();
+ if (active_displays[0] != '\0') {
+ const char *separator_pos = strchr(active_displays, ',');
+ if (separator_pos == NULL) {
+ return active_displays;
+ }
+ static std::string active_display;
+ /* NOTE: Configuration is shared and is never changed during
+ * runtime, so we only guarantee two threads don't initialize at the
+ * same. */
+ static std::mutex mutex;
+ mutex.lock();
+ if (active_display.empty()) {
+ active_display = active_displays;
+ active_display[separator_pos - active_displays] = '\0';
+ }
+ mutex.unlock();
+ return active_display.c_str();
+ }
+ }
#endif
- try {
- return (*(ConstConfigRcPtr *) config)->getDefaultDisplay();
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getDefaultDisplay();
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
-int OCIOImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr* config)
+int OCIOImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr *config)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getNumDisplays();
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getNumDisplays();
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return 0;
+ return 0;
}
const char *OCIOImpl::configGetDisplay(OCIO_ConstConfigRcPtr *config, int index)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getDisplay(index);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getDisplay(index);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
#ifdef DEFAULT_DISPLAY_WORKAROUND
namespace {
-void splitStringEnvStyle(vector<string>* tokens, const string& str)
-{
- tokens->clear();
- const int len = str.length();
- int token_start = 0, token_length = 0;
- for (int i = 0; i < len; ++i) {
- const char ch = str[i];
- if (ch != ',' && ch != ':') {
- /* Append non-separator char to a token. */
- ++token_length;
- } else {
- /* Append current token to the list (if any). */
- if (token_length > 0) {
- string token = str.substr(token_start, token_length);
- tokens->push_back(token);
- }
- /* Re-set token pointers. */
- token_start = i + 1;
- token_length = 0;
- }
- }
- /* Append token which might be at the end of the string. */
- if (token_length != 0) {
- string token = str.substr(token_start, token_length);
- tokens->push_back(token);
- }
-}
-
-string stringToLower(const string& str) {
- string lower = str;
- std::transform(lower.begin(), lower.end(), lower.begin(), tolower);
- return lower;
+void splitStringEnvStyle(vector<string> *tokens, const string &str)
+{
+ tokens->clear();
+ const int len = str.length();
+ int token_start = 0, token_length = 0;
+ for (int i = 0; i < len; ++i) {
+ const char ch = str[i];
+ if (ch != ',' && ch != ':') {
+ /* Append non-separator char to a token. */
+ ++token_length;
+ }
+ else {
+ /* Append current token to the list (if any). */
+ if (token_length > 0) {
+ string token = str.substr(token_start, token_length);
+ tokens->push_back(token);
+ }
+ /* Re-set token pointers. */
+ token_start = i + 1;
+ token_length = 0;
+ }
+ }
+ /* Append token which might be at the end of the string. */
+ if (token_length != 0) {
+ string token = str.substr(token_start, token_length);
+ tokens->push_back(token);
+ }
+}
+
+string stringToLower(const string &str)
+{
+ string lower = str;
+ std::transform(lower.begin(), lower.end(), lower.begin(), tolower);
+ return lower;
}
} // namespace
@@ -312,469 +313,483 @@ string stringToLower(const string& str) {
const char *OCIOImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display)
{
#ifdef DEFAULT_DISPLAY_WORKAROUND
- /* NOTE: We assume that first active view always exists for a default
- * display. */
- if (getenv("OCIO_ACTIVE_VIEWS") == NULL) {
- ConstConfigRcPtr config_ptr = *((ConstConfigRcPtr *) config);
- const char *active_views_encoded = config_ptr->getActiveViews();
- if (active_views_encoded[0] != '\0') {
- const string display_lower = stringToLower(display);
- static map<string, string> default_display_views;
- static std::mutex mutex;
- mutex.lock();
- /* Check if the view is already known. */
- map<string, string>::const_iterator it =
- default_display_views.find(display_lower);
- if (it != default_display_views.end()) {
- mutex.unlock();
- return it->second.c_str();
- }
- /* Active views. */
- vector<string> active_views;
- splitStringEnvStyle(&active_views, active_views_encoded);
- /* Get all views supported by tge display. */
- set<string> display_views;
- const int num_display_views = config_ptr->getNumViews(display);
- for (int view_index = 0;
- view_index < num_display_views;
- ++view_index)
- {
- const char *view = config_ptr->getView(display, view_index);
- display_views.insert(stringToLower(view));
- }
- /* Get first view which is supported by tge display. */
- for (const string& view : active_views) {
- const string view_lower = stringToLower(view);
- if (display_views.find(view_lower) != display_views.end()) {
- default_display_views[display_lower] = view;
- mutex.unlock();
- return default_display_views[display_lower].c_str();
- }
- }
- mutex.unlock();
- }
- }
+ /* NOTE: We assume that first active view always exists for a default
+ * display. */
+ if (getenv("OCIO_ACTIVE_VIEWS") == NULL) {
+ ConstConfigRcPtr config_ptr = *((ConstConfigRcPtr *)config);
+ const char *active_views_encoded = config_ptr->getActiveViews();
+ if (active_views_encoded[0] != '\0') {
+ const string display_lower = stringToLower(display);
+ static map<string, string> default_display_views;
+ static std::mutex mutex;
+ mutex.lock();
+ /* Check if the view is already known. */
+ map<string, string>::const_iterator it = default_display_views.find(display_lower);
+ if (it != default_display_views.end()) {
+ mutex.unlock();
+ return it->second.c_str();
+ }
+ /* Active views. */
+ vector<string> active_views;
+ splitStringEnvStyle(&active_views, active_views_encoded);
+ /* Get all views supported by tge display. */
+ set<string> display_views;
+ const int num_display_views = config_ptr->getNumViews(display);
+ for (int view_index = 0; view_index < num_display_views; ++view_index) {
+ const char *view = config_ptr->getView(display, view_index);
+ display_views.insert(stringToLower(view));
+ }
+ /* Get first view which is supported by tge display. */
+ for (const string &view : active_views) {
+ const string view_lower = stringToLower(view);
+ if (display_views.find(view_lower) != display_views.end()) {
+ default_display_views[display_lower] = view;
+ mutex.unlock();
+ return default_display_views[display_lower].c_str();
+ }
+ }
+ mutex.unlock();
+ }
+ }
#endif
- try {
- return (*(ConstConfigRcPtr *) config)->getDefaultView(display);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getDefaultView(display);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
int OCIOImpl::configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getNumViews(display);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getNumViews(display);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return 0;
+ return 0;
}
const char *OCIOImpl::configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getView(display, index);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getView(display, index);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
-const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view)
+const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
+ const char *display,
+ const char *view)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getDisplayColorSpaceName(display, view);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getDisplayColorSpaceName(display, view);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
void OCIOImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb)
{
- try {
- (*(ConstConfigRcPtr *) config)->getDefaultLumaCoefs(rgb);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ (*(ConstConfigRcPtr *)config)->getDefaultLumaCoefs(rgb);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
}
void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rgb[3][3])
{
- ConstConfigRcPtr config = (*(ConstConfigRcPtr *) config_);
-
- /* Default to ITU-BT.709 in case no appropriate transform found. */
- memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
-
- /* Auto estimate from XYZ and scene_linear roles, assumed to be a linear transform. */
- if(config->hasRole("XYZ") && config->hasRole("scene_linear")) {
- ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
- if(to_rgb_processor) {
- xyz_to_rgb[0][0] = 1.0f;
- xyz_to_rgb[0][1] = 0.0f;
- xyz_to_rgb[0][2] = 0.0f;
- xyz_to_rgb[1][0] = 0.0f;
- xyz_to_rgb[1][1] = 1.0f;
- xyz_to_rgb[1][2] = 0.0f;
- xyz_to_rgb[2][0] = 0.0f;
- xyz_to_rgb[2][1] = 0.0f;
- xyz_to_rgb[2][2] = 1.0f;
- to_rgb_processor->applyRGB(xyz_to_rgb[0]);
- to_rgb_processor->applyRGB(xyz_to_rgb[1]);
- to_rgb_processor->applyRGB(xyz_to_rgb[2]);
- }
- }
+ ConstConfigRcPtr config = (*(ConstConfigRcPtr *)config_);
+
+ /* Default to ITU-BT.709 in case no appropriate transform found. */
+ memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
+
+ /* Auto estimate from XYZ and scene_linear roles, assumed to be a linear transform. */
+ if (config->hasRole("XYZ") && config->hasRole("scene_linear")) {
+ ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
+ if (to_rgb_processor) {
+ xyz_to_rgb[0][0] = 1.0f;
+ xyz_to_rgb[0][1] = 0.0f;
+ xyz_to_rgb[0][2] = 0.0f;
+ xyz_to_rgb[1][0] = 0.0f;
+ xyz_to_rgb[1][1] = 1.0f;
+ xyz_to_rgb[1][2] = 0.0f;
+ xyz_to_rgb[2][0] = 0.0f;
+ xyz_to_rgb[2][1] = 0.0f;
+ xyz_to_rgb[2][2] = 1.0f;
+ to_rgb_processor->applyRGB(xyz_to_rgb[0]);
+ to_rgb_processor->applyRGB(xyz_to_rgb[1]);
+ to_rgb_processor->applyRGB(xyz_to_rgb[2]);
+ }
+ }
}
int OCIOImpl::configGetNumLooks(OCIO_ConstConfigRcPtr *config)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getNumLooks();
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getNumLooks();
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return 0;
+ return 0;
}
const char *OCIOImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
{
- try {
- return (*(ConstConfigRcPtr *) config)->getLookNameByIndex(index);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ return (*(ConstConfigRcPtr *)config)->getLookNameByIndex(index);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, const char *name)
{
- ConstLookRcPtr *look = OBJECT_GUARDED_NEW(ConstLookRcPtr);
+ ConstLookRcPtr *look = OBJECT_GUARDED_NEW(ConstLookRcPtr);
- try {
- *look = (*(ConstConfigRcPtr *) config)->getLook(name);
+ try {
+ *look = (*(ConstConfigRcPtr *)config)->getLook(name);
- if (*look)
- return (OCIO_ConstLookRcPtr *) look;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ if (*look)
+ return (OCIO_ConstLookRcPtr *)look;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- OBJECT_GUARDED_DELETE(look, ConstLookRcPtr);
+ OBJECT_GUARDED_DELETE(look, ConstLookRcPtr);
- return NULL;
+ return NULL;
}
const char *OCIOImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
{
- return (*(ConstLookRcPtr *) look)->getProcessSpace();
+ return (*(ConstLookRcPtr *)look)->getProcessSpace();
}
void OCIOImpl::lookRelease(OCIO_ConstLookRcPtr *look)
{
- OBJECT_GUARDED_DELETE((ConstLookRcPtr *) look, ConstLookRcPtr);
+ OBJECT_GUARDED_DELETE((ConstLookRcPtr *)look, ConstLookRcPtr);
}
int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_)
{
- ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *) cs_;
- const char *family = (*cs)->getFamily();
+ ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *)cs_;
+ const char *family = (*cs)->getFamily();
- if (!strcmp(family, "rrt") || !strcmp(family, "display")) {
- /* assume display and rrt transformations are not invertible
- * in fact some of them could be, but it doesn't make much sense to allow use them as invertible
- */
- return false;
- }
+ if (!strcmp(family, "rrt") || !strcmp(family, "display")) {
+ /* assume display and rrt transformations are not invertible
+ * in fact some of them could be, but it doesn't make much sense to allow use them as invertible
+ */
+ return false;
+ }
- if ((*cs)->isData()) {
- /* data color spaces don't have transformation at all */
- return true;
- }
+ if ((*cs)->isData()) {
+ /* data color spaces don't have transformation at all */
+ return true;
+ }
- if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) {
- /* if there's defined transform to reference space, color space could be converted to scene linear */
- return true;
- }
+ if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) {
+ /* if there's defined transform to reference space, color space could be converted to scene linear */
+ return true;
+ }
- return true;
+ return true;
}
int OCIOImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs)
{
- return (*(ConstColorSpaceRcPtr *) cs)->isData();
+ return (*(ConstColorSpaceRcPtr *)cs)->isData();
}
void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
{
- OBJECT_GUARDED_DELETE((ConstColorSpaceRcPtr *) cs, ConstColorSpaceRcPtr);
+ OBJECT_GUARDED_DELETE((ConstColorSpaceRcPtr *)cs, ConstColorSpaceRcPtr);
}
-OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName)
+OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName)
{
- ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
+ ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
- try {
- *p = (*(ConstConfigRcPtr *) config)->getProcessor(srcName, dstName);
+ try {
+ *p = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
- if (*p)
- return (OCIO_ConstProcessorRcPtr *) p;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ if (*p)
+ return (OCIO_ConstProcessorRcPtr *)p;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
- return 0;
+ return 0;
}
-OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform)
+OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessor(OCIO_ConstConfigRcPtr *config,
+ OCIO_ConstTransformRcPtr *transform)
{
- ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
+ ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
- try {
- *p = (*(ConstConfigRcPtr *) config)->getProcessor(*(ConstTransformRcPtr *) transform);
+ try {
+ *p = (*(ConstConfigRcPtr *)config)->getProcessor(*(ConstTransformRcPtr *)transform);
- if (*p)
- return (OCIO_ConstProcessorRcPtr *) p;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ if (*p)
+ return (OCIO_ConstProcessorRcPtr *)p;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
- return NULL;
+ return NULL;
}
void OCIOImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
{
- try {
- (*(ConstProcessorRcPtr *) processor)->apply(*(PackedImageDesc *) img);
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ try {
+ (*(ConstProcessorRcPtr *)processor)->apply(*(PackedImageDesc *)img);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
}
-void OCIOImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img_)
+void OCIOImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
+ OCIO_PackedImageDesc *img_)
{
- try {
- PackedImageDesc *img = (PackedImageDesc *) img_;
- int channels = img->getNumChannels();
+ try {
+ PackedImageDesc *img = (PackedImageDesc *)img_;
+ int channels = img->getNumChannels();
- if (channels == 4) {
- float *pixels = img->getData();
+ if (channels == 4) {
+ float *pixels = img->getData();
- int width = img->getWidth();
- int height = img->getHeight();
+ int width = img->getWidth();
+ int height = img->getHeight();
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- float *pixel = pixels + 4 * (y * width + x);
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ float *pixel = pixels + 4 * (y * width + x);
- processorApplyRGBA_predivide(processor, pixel);
- }
- }
- }
- else {
- (*(ConstProcessorRcPtr *) processor)->apply(*img);
- }
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ processorApplyRGBA_predivide(processor, pixel);
+ }
+ }
+ }
+ else {
+ (*(ConstProcessorRcPtr *)processor)->apply(*img);
+ }
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
}
void OCIOImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- (*(ConstProcessorRcPtr *) processor)->applyRGB(pixel);
+ (*(ConstProcessorRcPtr *)processor)->applyRGB(pixel);
}
void OCIOImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel);
+ (*(ConstProcessorRcPtr *)processor)->applyRGBA(pixel);
}
void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
{
- if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
- (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel);
- }
- else {
- float alpha, inv_alpha;
+ if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
+ (*(ConstProcessorRcPtr *)processor)->applyRGBA(pixel);
+ }
+ else {
+ float alpha, inv_alpha;
- alpha = pixel[3];
- inv_alpha = 1.0f / alpha;
+ alpha = pixel[3];
+ inv_alpha = 1.0f / alpha;
- pixel[0] *= inv_alpha;
- pixel[1] *= inv_alpha;
- pixel[2] *= inv_alpha;
+ pixel[0] *= inv_alpha;
+ pixel[1] *= inv_alpha;
+ pixel[2] *= inv_alpha;
- (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel);
+ (*(ConstProcessorRcPtr *)processor)->applyRGBA(pixel);
- pixel[0] *= alpha;
- pixel[1] *= alpha;
- pixel[2] *= alpha;
- }
+ pixel[0] *= alpha;
+ pixel[1] *= alpha;
+ pixel[2] *= alpha;
+ }
}
void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *p)
{
- OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
}
const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
{
- return (*(ConstColorSpaceRcPtr *) cs)->getName();
+ return (*(ConstColorSpaceRcPtr *)cs)->getName();
}
const char *OCIOImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs)
{
- return (*(ConstColorSpaceRcPtr *) cs)->getDescription();
+ return (*(ConstColorSpaceRcPtr *)cs)->getDescription();
}
const char *OCIOImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
{
- return (*(ConstColorSpaceRcPtr *)cs)->getFamily();
+ return (*(ConstColorSpaceRcPtr *)cs)->getFamily();
}
OCIO_DisplayTransformRcPtr *OCIOImpl::createDisplayTransform(void)
{
- DisplayTransformRcPtr *dt = OBJECT_GUARDED_NEW(DisplayTransformRcPtr);
+ DisplayTransformRcPtr *dt = OBJECT_GUARDED_NEW(DisplayTransformRcPtr);
- *dt = DisplayTransform::Create();
+ *dt = DisplayTransform::Create();
- return (OCIO_DisplayTransformRcPtr *) dt;
+ return (OCIO_DisplayTransformRcPtr *)dt;
}
-void OCIOImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name)
+void OCIOImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt,
+ const char *name)
{
- (*(DisplayTransformRcPtr *) dt)->setInputColorSpaceName(name);
+ (*(DisplayTransformRcPtr *)dt)->setInputColorSpaceName(name);
}
void OCIOImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name)
{
- (*(DisplayTransformRcPtr *) dt)->setDisplay(name);
+ (*(DisplayTransformRcPtr *)dt)->setDisplay(name);
}
void OCIOImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name)
{
- (*(DisplayTransformRcPtr *) dt)->setView(name);
+ (*(DisplayTransformRcPtr *)dt)->setView(name);
}
-void OCIOImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t)
+void OCIOImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *t)
{
- (*(DisplayTransformRcPtr *) dt)->setDisplayCC(* (ConstTransformRcPtr *) t);
+ (*(DisplayTransformRcPtr *)dt)->setDisplayCC(*(ConstTransformRcPtr *)t);
}
-void OCIOImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t)
+void OCIOImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *t)
{
- (*(DisplayTransformRcPtr *) dt)->setLinearCC(*(ConstTransformRcPtr *) t);
+ (*(DisplayTransformRcPtr *)dt)->setLinearCC(*(ConstTransformRcPtr *)t);
}
void OCIOImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks)
{
- (*(DisplayTransformRcPtr *) dt)->setLooksOverride(looks);
+ (*(DisplayTransformRcPtr *)dt)->setLooksOverride(looks);
}
-void OCIOImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled)
+void OCIOImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt,
+ bool enabled)
{
- (*(DisplayTransformRcPtr *) dt)->setLooksOverrideEnabled(enabled);
+ (*(DisplayTransformRcPtr *)dt)->setLooksOverrideEnabled(enabled);
}
void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
{
- OBJECT_GUARDED_DELETE((DisplayTransformRcPtr *) dt, DisplayTransformRcPtr);
+ OBJECT_GUARDED_DELETE((DisplayTransformRcPtr *)dt, DisplayTransformRcPtr);
}
-OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data,
+ long width,
+ long height,
+ long numChannels,
+ long chanStrideBytes,
+ long xStrideBytes,
+ long yStrideBytes)
{
- try {
- void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__);
- PackedImageDesc *id = new(mem) PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
+ try {
+ void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__);
+ PackedImageDesc *id = new (mem) PackedImageDesc(
+ data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
- return (OCIO_PackedImageDesc *) id;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
+ return (OCIO_PackedImageDesc *)id;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
- return NULL;
+ return NULL;
}
-void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
+void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
{
- OBJECT_GUARDED_DELETE((PackedImageDesc *) id, PackedImageDesc);
+ OBJECT_GUARDED_DELETE((PackedImageDesc *)id, PackedImageDesc);
}
OCIO_ExponentTransformRcPtr *OCIOImpl::createExponentTransform(void)
{
- ExponentTransformRcPtr *et = OBJECT_GUARDED_NEW(ExponentTransformRcPtr);
+ ExponentTransformRcPtr *et = OBJECT_GUARDED_NEW(ExponentTransformRcPtr);
- *et = ExponentTransform::Create();
+ *et = ExponentTransform::Create();
- return (OCIO_ExponentTransformRcPtr *) et;
+ return (OCIO_ExponentTransformRcPtr *)et;
}
void OCIOImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent)
{
- (*(ExponentTransformRcPtr *) et)->setValue(exponent);
+ (*(ExponentTransformRcPtr *)et)->setValue(exponent);
}
void OCIOImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr *et)
{
- OBJECT_GUARDED_DELETE((ExponentTransformRcPtr *) et, ExponentTransformRcPtr);
+ OBJECT_GUARDED_DELETE((ExponentTransformRcPtr *)et, ExponentTransformRcPtr);
}
OCIO_MatrixTransformRcPtr *OCIOImpl::createMatrixTransform(void)
{
- MatrixTransformRcPtr *mt = OBJECT_GUARDED_NEW(MatrixTransformRcPtr);
+ MatrixTransformRcPtr *mt = OBJECT_GUARDED_NEW(MatrixTransformRcPtr);
- *mt = MatrixTransform::Create();
+ *mt = MatrixTransform::Create();
- return (OCIO_MatrixTransformRcPtr *) mt;
+ return (OCIO_MatrixTransformRcPtr *)mt;
}
-void OCIOImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4)
+void OCIOImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
+ const float *m44,
+ const float *offset4)
{
- (*(MatrixTransformRcPtr *) mt)->setValue(m44, offset4);
+ (*(MatrixTransformRcPtr *)mt)->setValue(m44, offset4);
}
void OCIOImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt)
{
- OBJECT_GUARDED_DELETE((MatrixTransformRcPtr *) mt, MatrixTransformRcPtr);
+ OBJECT_GUARDED_DELETE((MatrixTransformRcPtr *)mt, MatrixTransformRcPtr);
}
void OCIOImpl::matrixTransformScale(float *m44, float *offset4, const float *scale4f)
{
- MatrixTransform::Scale(m44, offset4, scale4f);
+ MatrixTransform::Scale(m44, offset4, scale4f);
}
const char *OCIOImpl::getVersionString(void)
{
- return GetVersion();
+ return GetVersion();
}
int OCIOImpl::getVersionHex(void)
{
- return GetVersionHex();
+ return GetVersionHex();
}
diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h
index 991e65cc892..0952e7e16d0 100644
--- a/intern/opencolorio/ocio_impl.h
+++ b/intern/opencolorio/ocio_impl.h
@@ -23,274 +23,333 @@
#include "ocio_capi.h"
class IOCIOImpl {
-public:
- virtual ~IOCIOImpl() {}
-
- virtual OCIO_ConstConfigRcPtr *getCurrentConfig(void) = 0;
- virtual void setCurrentConfig(const OCIO_ConstConfigRcPtr *config) = 0;
-
- virtual OCIO_ConstConfigRcPtr *configCreateFromEnv(void) = 0;
- virtual OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename) = 0;
-
- virtual void configRelease(OCIO_ConstConfigRcPtr *config) = 0;
-
- virtual int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) = 0;
- virtual const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0;
- virtual OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0;
- virtual int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0;
-
- virtual int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) = 0;
- virtual int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) = 0;
-
- virtual void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) = 0;
-
- virtual const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) = 0;
- virtual int configGetNumDisplays(OCIO_ConstConfigRcPtr *config) = 0;
- virtual const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) = 0;
- virtual const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) = 0;
- virtual int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) = 0;
- virtual const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index) = 0;
- virtual const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view) = 0;
-
- virtual void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb) = 0;
- virtual void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]) = 0;
-
- virtual int configGetNumLooks(OCIO_ConstConfigRcPtr *config) = 0;
- virtual const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0;
- virtual OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name) = 0;
-
- virtual const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look) = 0;
- virtual void lookRelease(OCIO_ConstLookRcPtr *look) = 0;
-
- virtual OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) = 0;
- virtual OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform) = 0;
-
- virtual void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0;
- virtual void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0;
- virtual void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
- virtual void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
- virtual void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
-
- virtual void processorRelease(OCIO_ConstProcessorRcPtr *p) = 0;
-
- virtual const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) = 0;
- virtual const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) = 0;
- virtual const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) = 0;
-
- virtual OCIO_DisplayTransformRcPtr *createDisplayTransform(void) = 0;
- virtual void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0;
- virtual void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0;
- virtual void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0;
- virtual void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et) = 0;
- virtual void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et) = 0;
- virtual void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks) = 0;
- virtual void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled) = 0;
- virtual void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) = 0;
-
- virtual OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes) = 0;
-
- virtual void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p) = 0;
-
- virtual OCIO_ExponentTransformRcPtr *createExponentTransform(void) = 0;
- virtual void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent) = 0;
- virtual void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) = 0;
-
- virtual OCIO_MatrixTransformRcPtr *createMatrixTransform(void) = 0;
- virtual void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4) = 0;
- virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0;
-
- virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0;
-
- virtual bool supportGLSLDraw(void) = 0;
- virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
- OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide) = 0;
- virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
- virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
-
- virtual const char *getVersionString(void) = 0;
- virtual int getVersionHex(void) = 0;
+ public:
+ virtual ~IOCIOImpl()
+ {
+ }
+
+ virtual OCIO_ConstConfigRcPtr *getCurrentConfig(void) = 0;
+ virtual void setCurrentConfig(const OCIO_ConstConfigRcPtr *config) = 0;
+
+ virtual OCIO_ConstConfigRcPtr *configCreateFromEnv(void) = 0;
+ virtual OCIO_ConstConfigRcPtr *configCreateFromFile(const char *filename) = 0;
+
+ virtual void configRelease(OCIO_ConstConfigRcPtr *config) = 0;
+
+ virtual int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) = 0;
+ virtual const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0;
+ virtual OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config,
+ const char *name) = 0;
+ virtual int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0;
+
+ virtual int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) = 0;
+ virtual int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) = 0;
+
+ virtual void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) = 0;
+
+ virtual const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) = 0;
+ virtual int configGetNumDisplays(OCIO_ConstConfigRcPtr *config) = 0;
+ virtual const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) = 0;
+ virtual const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) = 0;
+ virtual int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) = 0;
+ virtual const char *configGetView(OCIO_ConstConfigRcPtr *config,
+ const char *display,
+ int index) = 0;
+ virtual const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
+ const char *display,
+ const char *view) = 0;
+
+ virtual void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb) = 0;
+ virtual void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]) = 0;
+
+ virtual int configGetNumLooks(OCIO_ConstConfigRcPtr *config) = 0;
+ virtual const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0;
+ virtual OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name) = 0;
+
+ virtual const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look) = 0;
+ virtual void lookRelease(OCIO_ConstLookRcPtr *look) = 0;
+
+ virtual OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName) = 0;
+ virtual OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config,
+ OCIO_ConstTransformRcPtr *transform) = 0;
+
+ virtual void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0;
+ virtual void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
+ OCIO_PackedImageDesc *img) = 0;
+ virtual void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
+ virtual void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
+ virtual void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
+
+ virtual void processorRelease(OCIO_ConstProcessorRcPtr *p) = 0;
+
+ virtual const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) = 0;
+ virtual const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) = 0;
+ virtual const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) = 0;
+
+ virtual OCIO_DisplayTransformRcPtr *createDisplayTransform(void) = 0;
+ virtual void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt,
+ const char *name) = 0;
+ virtual void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0;
+ virtual void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0;
+ virtual void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *et) = 0;
+ virtual void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *et) = 0;
+ virtual void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt,
+ const char *looks) = 0;
+ virtual void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt,
+ bool enabled) = 0;
+ virtual void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) = 0;
+
+ virtual OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data,
+ long width,
+ long height,
+ long numChannels,
+ long chanStrideBytes,
+ long xStrideBytes,
+ long yStrideBytes) = 0;
+
+ virtual void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p) = 0;
+
+ virtual OCIO_ExponentTransformRcPtr *createExponentTransform(void) = 0;
+ virtual void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et,
+ const float *exponent) = 0;
+ virtual void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) = 0;
+
+ virtual OCIO_MatrixTransformRcPtr *createMatrixTransform(void) = 0;
+ virtual void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
+ const float *m44,
+ const float *offset4) = 0;
+ virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0;
+
+ virtual void matrixTransformScale(float *m44, float *offset4, const float *scale4) = 0;
+
+ virtual bool supportGLSLDraw(void) = 0;
+ virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
+ OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ float dither,
+ bool predivide) = 0;
+ virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
+ virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
+
+ virtual const char *getVersionString(void) = 0;
+ virtual int getVersionHex(void) = 0;
};
class FallbackImpl : public IOCIOImpl {
-public:
- FallbackImpl() {}
-
- OCIO_ConstConfigRcPtr *getCurrentConfig(void);
- void setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
-
- OCIO_ConstConfigRcPtr *configCreateFromEnv(void);
- OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename);
-
- void configRelease(OCIO_ConstConfigRcPtr *config);
-
- int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config);
- const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
- OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
- int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
-
- int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs);
- int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs);
-
- void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs);
-
- const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config);
- int configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
- const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index);
- const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display);
- int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
- const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index);
- const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view);
-
- void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
- void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
-
- int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
- const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
- OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name);
-
- const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look);
- void lookRelease(OCIO_ConstLookRcPtr *look);
-
- OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName);
- OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform);
-
- void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel);
-
- void processorRelease(OCIO_ConstProcessorRcPtr *p);
-
- const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs);
- const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs);
- const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs);
-
- OCIO_DisplayTransformRcPtr *createDisplayTransform(void);
- void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
- void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
- void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
-
- OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes);
-
- void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
-
- OCIO_ExponentTransformRcPtr *createExponentTransform(void);
- void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
- void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
-
- OCIO_MatrixTransformRcPtr *createMatrixTransform(void);
- void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4);
- void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
-
- void matrixTransformScale(float *m44, float *offset4, const float *scale4);
-
- bool supportGLSLDraw(void);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
- OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide);
- void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
- void freeGLState(struct OCIO_GLSLDrawState *state_r);
-
- const char *getVersionString(void);
- int getVersionHex(void);
+ public:
+ FallbackImpl()
+ {
+ }
+
+ OCIO_ConstConfigRcPtr *getCurrentConfig(void);
+ void setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
+
+ OCIO_ConstConfigRcPtr *configCreateFromEnv(void);
+ OCIO_ConstConfigRcPtr *configCreateFromFile(const char *filename);
+
+ void configRelease(OCIO_ConstConfigRcPtr *config);
+
+ int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config);
+ const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
+ OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
+ int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
+
+ int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs);
+ int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs);
+
+ void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs);
+
+ const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config);
+ int configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
+ const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index);
+ const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display);
+ int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
+ const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index);
+ const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
+ const char *display,
+ const char *view);
+
+ void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
+ void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
+
+ int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
+ const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
+ OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name);
+
+ const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look);
+ void lookRelease(OCIO_ConstLookRcPtr *look);
+
+ OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName);
+ OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config,
+ OCIO_ConstTransformRcPtr *transform);
+
+ void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
+ void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
+ void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel);
+ void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel);
+ void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel);
+
+ void processorRelease(OCIO_ConstProcessorRcPtr *p);
+
+ const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs);
+ const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs);
+ const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs);
+
+ OCIO_DisplayTransformRcPtr *createDisplayTransform(void);
+ void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
+ void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
+ void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
+ void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
+ void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
+ void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
+ void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
+ void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
+
+ OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data,
+ long width,
+ long height,
+ long numChannels,
+ long chanStrideBytes,
+ long xStrideBytes,
+ long yStrideBytes);
+
+ void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
+
+ OCIO_ExponentTransformRcPtr *createExponentTransform(void);
+ void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
+ void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
+
+ OCIO_MatrixTransformRcPtr *createMatrixTransform(void);
+ void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
+ const float *m44,
+ const float *offset4);
+ void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
+
+ void matrixTransformScale(float *m44, float *offset4, const float *scale4);
+
+ bool supportGLSLDraw(void);
+ bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
+ OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ float dither,
+ bool predivide);
+ void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
+ void freeGLState(struct OCIO_GLSLDrawState *state_r);
+
+ const char *getVersionString(void);
+ int getVersionHex(void);
};
#ifdef WITH_OCIO
class OCIOImpl : public IOCIOImpl {
-public:
- OCIOImpl() {};
-
- OCIO_ConstConfigRcPtr *getCurrentConfig(void);
- void setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
-
- OCIO_ConstConfigRcPtr *configCreateFromEnv(void);
- OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename);
-
- void configRelease(OCIO_ConstConfigRcPtr *config);
-
- int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config);
- const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
- OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
- int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
-
- int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs);
- int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs);
-
- void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs);
-
- const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config);
- int configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
- const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index);
- const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display);
- int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
- const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index);
- const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view);
-
- void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
- void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
-
- int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
- const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
- OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name);
-
- const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look);
- void lookRelease(OCIO_ConstLookRcPtr *look);
-
- OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName);
- OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform);
-
- void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel);
-
- void processorRelease(OCIO_ConstProcessorRcPtr *p);
-
- const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs);
- const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs);
- const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs);
-
- OCIO_DisplayTransformRcPtr *createDisplayTransform(void);
- void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
- void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
- void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
-
- OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes);
-
- void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
-
- OCIO_ExponentTransformRcPtr *createExponentTransform(void);
- void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
- void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
-
- OCIO_MatrixTransformRcPtr *createMatrixTransform(void);
- void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4);
- void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
-
- void matrixTransformScale(float * m44, float * offset4, const float * scale4);
-
- bool supportGLSLDraw(void);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
- OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide);
- void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
- void freeGLState(struct OCIO_GLSLDrawState *state_r);
-
- const char *getVersionString(void);
- int getVersionHex(void);
+ public:
+ OCIOImpl(){};
+
+ OCIO_ConstConfigRcPtr *getCurrentConfig(void);
+ void setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
+
+ OCIO_ConstConfigRcPtr *configCreateFromEnv(void);
+ OCIO_ConstConfigRcPtr *configCreateFromFile(const char *filename);
+
+ void configRelease(OCIO_ConstConfigRcPtr *config);
+
+ int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config);
+ const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
+ OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
+ int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
+
+ int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs);
+ int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs);
+
+ void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs);
+
+ const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config);
+ int configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
+ const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index);
+ const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display);
+ int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
+ const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index);
+ const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
+ const char *display,
+ const char *view);
+
+ void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
+ void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
+
+ int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
+ const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
+ OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name);
+
+ const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look);
+ void lookRelease(OCIO_ConstLookRcPtr *look);
+
+ OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName);
+ OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config,
+ OCIO_ConstTransformRcPtr *transform);
+
+ void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
+ void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
+ void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel);
+ void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel);
+ void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel);
+
+ void processorRelease(OCIO_ConstProcessorRcPtr *p);
+
+ const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs);
+ const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs);
+ const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs);
+
+ OCIO_DisplayTransformRcPtr *createDisplayTransform(void);
+ void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
+ void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
+ void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
+ void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
+ void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
+ void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
+ void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
+ void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
+
+ OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data,
+ long width,
+ long height,
+ long numChannels,
+ long chanStrideBytes,
+ long xStrideBytes,
+ long yStrideBytes);
+
+ void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
+
+ OCIO_ExponentTransformRcPtr *createExponentTransform(void);
+ void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
+ void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
+
+ OCIO_MatrixTransformRcPtr *createMatrixTransform(void);
+ void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
+ const float *m44,
+ const float *offset4);
+ void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
+
+ void matrixTransformScale(float *m44, float *offset4, const float *scale4);
+
+ bool supportGLSLDraw(void);
+ bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
+ OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ float dither,
+ bool predivide);
+ void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
+ void freeGLState(struct OCIO_GLSLDrawState *state_r);
+
+ const char *getVersionString(void);
+ int getVersionHex(void);
};
#endif
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index cf41d0a4983..4d0908eafd5 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -64,211 +64,224 @@ extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[];
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
typedef struct OCIO_GLSLShader {
- /* Cache ID */
- std::string lut3dCacheID;
- std::string shaderCacheID;
-
- /* LUT */
- bool lut3d_texture_allocated; /* boolean flag indicating whether
- * lut texture is allocated
- */
- bool lut3d_texture_valid;
-
- GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
-
- float *lut3d; /* 3D LUT table */
-
- /* Dither */
- bool use_dither;
-
- /* Curve Mapping */
- bool use_curve_mapping;
- bool curve_mapping_texture_allocated;
- bool curve_mapping_texture_valid;
- GLuint curve_mapping_texture;
- size_t curve_mapping_cache_id;
-
- /* Alpha Predivide */
- bool use_predivide;
-
- /* GLSL stuff */
- GLuint ocio_shader;
- GLuint vert_shader;
- GLuint program;
- GPUShaderInterface *shader_interface;
+ /* Cache ID */
+ std::string lut3dCacheID;
+ std::string shaderCacheID;
+
+ /* LUT */
+ bool lut3d_texture_allocated; /* boolean flag indicating whether
+ * lut texture is allocated
+ */
+ bool lut3d_texture_valid;
+
+ GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
+
+ float *lut3d; /* 3D LUT table */
+
+ /* Dither */
+ bool use_dither;
+
+ /* Curve Mapping */
+ bool use_curve_mapping;
+ bool curve_mapping_texture_allocated;
+ bool curve_mapping_texture_valid;
+ GLuint curve_mapping_texture;
+ size_t curve_mapping_cache_id;
+
+ /* Alpha Predivide */
+ bool use_predivide;
+
+ /* GLSL stuff */
+ GLuint ocio_shader;
+ GLuint vert_shader;
+ GLuint program;
+ GPUShaderInterface *shader_interface;
} GLSLDrawState;
typedef struct OCIO_GLSLDrawState {
- /* Shader Cache */
- OCIO_GLSLShader *shader_cache[SHADER_CACHE_SIZE];
+ /* Shader Cache */
+ OCIO_GLSLShader *shader_cache[SHADER_CACHE_SIZE];
- /* Previous OpenGL state. */
- GLint last_texture, last_texture_unit;
+ /* Previous OpenGL state. */
+ GLint last_texture, last_texture_unit;
} OCIO_GLSLDrawState;
static GLuint compileShaderText(GLenum shaderType, const char *text)
{
- GLuint shader;
- GLint stat;
-
- shader = glCreateShader(shaderType);
- glShaderSource(shader, 1, (const GLchar **) &text, NULL);
- glCompileShader(shader);
- glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
-
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog(shader, 1000, &len, log);
- fprintf(stderr, "Shader compile error:\n%s\n", log);
- return 0;
- }
-
- return shader;
+ GLuint shader;
+ GLint stat;
+
+ shader = glCreateShader(shaderType);
+ glShaderSource(shader, 1, (const GLchar **)&text, NULL);
+ glCompileShader(shader);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
+
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetShaderInfoLog(shader, 1000, &len, log);
+ fprintf(stderr, "Shader compile error:\n%s\n", log);
+ return 0;
+ }
+
+ return shader;
}
static GLuint linkShaders(GLuint ocio_shader, GLuint vert_shader)
{
- if (!ocio_shader || !vert_shader)
- return 0;
-
- GLuint program = glCreateProgram();
-
- glAttachShader(program, ocio_shader);
- glAttachShader(program, vert_shader);
-
- glLinkProgram(program);
-
- /* check link */
- {
- GLint stat;
- glGetProgramiv(program, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog(program, 1000, &len, log);
- fprintf(stderr, "Shader link error:\n%s\n", log);
- return 0;
- }
- }
-
- return program;
+ if (!ocio_shader || !vert_shader)
+ return 0;
+
+ GLuint program = glCreateProgram();
+
+ glAttachShader(program, ocio_shader);
+ glAttachShader(program, vert_shader);
+
+ glLinkProgram(program);
+
+ /* check link */
+ {
+ GLint stat;
+ glGetProgramiv(program, GL_LINK_STATUS, &stat);
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetProgramInfoLog(program, 1000, &len, log);
+ fprintf(stderr, "Shader link error:\n%s\n", log);
+ return 0;
+ }
+ }
+
+ return program;
}
static OCIO_GLSLDrawState *allocateOpenGLState(void)
{
- return (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState),
- "OCIO OpenGL State struct");
+ return (OCIO_GLSLDrawState *)MEM_callocN(sizeof(OCIO_GLSLDrawState), "OCIO OpenGL State struct");
}
/* Ensure LUT texture and array are allocated */
static bool ensureLUT3DAllocated(OCIO_GLSLShader *shader)
{
- int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
-
- if (shader->lut3d_texture_allocated)
- return shader->lut3d_texture_valid;
-
- glGenTextures(1, &shader->lut3d_texture);
-
- shader->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
-
- /* clean glError buffer */
- while (glGetError() != GL_NO_ERROR) {}
-
- glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
- LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
- 0, GL_RGB, GL_FLOAT, shader->lut3d);
-
- shader->lut3d_texture_allocated = true;
-
- /* GL_RGB16F_ARB could be not supported at some drivers
- * in this case we could not use GLSL display
- */
- shader->lut3d_texture_valid = glGetError() == GL_NO_ERROR;
-
- return shader->lut3d_texture_valid;
+ int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
+
+ if (shader->lut3d_texture_allocated)
+ return shader->lut3d_texture_valid;
+
+ glGenTextures(1, &shader->lut3d_texture);
+
+ shader->lut3d = (float *)MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ /* clean glError buffer */
+ while (glGetError() != GL_NO_ERROR) {
+ }
+
+ glTexImage3D(GL_TEXTURE_3D,
+ 0,
+ GL_RGB16F_ARB,
+ LUT3D_EDGE_SIZE,
+ LUT3D_EDGE_SIZE,
+ LUT3D_EDGE_SIZE,
+ 0,
+ GL_RGB,
+ GL_FLOAT,
+ shader->lut3d);
+
+ shader->lut3d_texture_allocated = true;
+
+ /* GL_RGB16F_ARB could be not supported at some drivers
+ * in this case we could not use GLSL display
+ */
+ shader->lut3d_texture_valid = glGetError() == GL_NO_ERROR;
+
+ return shader->lut3d_texture_valid;
}
-static bool ensureCurveMappingAllocated(OCIO_GLSLShader *shader, OCIO_CurveMappingSettings *curve_mapping_settings)
+static bool ensureCurveMappingAllocated(OCIO_GLSLShader *shader,
+ OCIO_CurveMappingSettings *curve_mapping_settings)
{
- if (shader->curve_mapping_texture_allocated)
- return shader->curve_mapping_texture_valid;
-
- glGenTextures(1, &shader->curve_mapping_texture);
-
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
-
- /* clean glError buffer */
- while (glGetError() != GL_NO_ERROR) {}
-
- glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F, curve_mapping_settings->lut_size,
- 0, GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
-
- shader->curve_mapping_texture_allocated = true;
-
- /* GL_RGB16F_ARB could be not supported at some drivers
- * in this case we could not use GLSL display
- */
- shader->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR;
-
- return shader->curve_mapping_texture_valid;
+ if (shader->curve_mapping_texture_allocated)
+ return shader->curve_mapping_texture_valid;
+
+ glGenTextures(1, &shader->curve_mapping_texture);
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ /* clean glError buffer */
+ while (glGetError() != GL_NO_ERROR) {
+ }
+
+ glTexImage1D(GL_TEXTURE_1D,
+ 0,
+ GL_RGBA16F,
+ curve_mapping_settings->lut_size,
+ 0,
+ GL_RGBA,
+ GL_FLOAT,
+ curve_mapping_settings->lut);
+
+ shader->curve_mapping_texture_allocated = true;
+
+ /* GL_RGB16F_ARB could be not supported at some drivers
+ * in this case we could not use GLSL display
+ */
+ shader->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR;
+
+ return shader->curve_mapping_texture_valid;
}
static void freeGLSLShader(OCIO_GLSLShader *shader)
{
- if (shader->curve_mapping_texture_allocated) {
- glDeleteTextures(1, &shader->curve_mapping_texture);
- }
+ if (shader->curve_mapping_texture_allocated) {
+ glDeleteTextures(1, &shader->curve_mapping_texture);
+ }
- if (shader->lut3d_texture_allocated) {
- glDeleteTextures(1, &shader->lut3d_texture);
- }
+ if (shader->lut3d_texture_allocated) {
+ glDeleteTextures(1, &shader->lut3d_texture);
+ }
- if (shader->lut3d) {
- MEM_freeN(shader->lut3d);
- }
+ if (shader->lut3d) {
+ MEM_freeN(shader->lut3d);
+ }
- if (shader->program) {
- glDeleteProgram(shader->program);
- }
+ if (shader->program) {
+ glDeleteProgram(shader->program);
+ }
- if (shader->shader_interface) {
- GPU_shaderinterface_discard(shader->shader_interface);
- }
+ if (shader->shader_interface) {
+ GPU_shaderinterface_discard(shader->shader_interface);
+ }
- if (shader->ocio_shader) {
- glDeleteShader(shader->ocio_shader);
- }
+ if (shader->ocio_shader) {
+ glDeleteShader(shader->ocio_shader);
+ }
- using std::string;
- shader->lut3dCacheID.~string();
- shader->shaderCacheID.~string();
+ using std::string;
+ shader->lut3dCacheID.~string();
+ shader->shaderCacheID.~string();
- MEM_freeN(shader);
+ MEM_freeN(shader);
}
-
-
/* Detect if we can support GLSL drawing */
bool OCIOImpl::supportGLSLDraw()
{
- /* uses GL_RGB16F_ARB */
- return GLEW_VERSION_3_0 || GLEW_ARB_texture_float;
+ /* uses GL_RGB16F_ARB */
+ return GLEW_VERSION_3_0 || GLEW_ARB_texture_float;
}
/**
@@ -281,237 +294,251 @@ bool OCIOImpl::supportGLSLDraw()
* When all drawing is finished, finishGLSLDraw shall be called to
* restore OpenGL context to it's pre-GLSL draw state.
*/
-bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
+bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r,
+ OCIO_ConstProcessorRcPtr *processor,
OCIO_CurveMappingSettings *curve_mapping_settings,
- float dither, bool use_predivide)
+ float dither,
+ bool use_predivide)
{
- ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor;
- bool use_curve_mapping = curve_mapping_settings != NULL;
- bool use_dither = dither > std::numeric_limits<float>::epsilon();
-
- /* Create state if needed. */
- OCIO_GLSLDrawState *state;
- if (!*state_r)
- *state_r = allocateOpenGLState();
- state = *state_r;
-
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &state->last_texture);
- glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
-
- /* Compute cache IDs. */
- GpuShaderDesc shaderDesc;
- shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3);
- shaderDesc.setFunctionName("OCIODisplay");
- shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
-
- std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
- std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
-
- /* Find matching cached shader. */
- OCIO_GLSLShader *shader = NULL;
- for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
- OCIO_GLSLShader *cached_shader = state->shader_cache[i];
- if (cached_shader == NULL) {
- continue;
- }
-
- if (cached_shader->lut3dCacheID == lut3dCacheID &&
- cached_shader->shaderCacheID == shaderCacheID &&
- cached_shader->use_predivide == use_predivide &&
- cached_shader->use_curve_mapping == use_curve_mapping &&
- cached_shader->use_dither == use_dither)
- {
- /* LRU cache, so move to front. */
- for (int j = i; j > 0; j--) {
- state->shader_cache[j] = state->shader_cache[j - 1];
- }
- state->shader_cache[0] = cached_shader;
-
- shader = cached_shader;
- break;
- }
- }
-
- if (shader == NULL) {
- /* LRU cache, shift other items back so we can insert at the front. */
- OCIO_GLSLShader *last_shader = state->shader_cache[SHADER_CACHE_SIZE - 1];
- if (last_shader) {
- freeGLSLShader(last_shader);
- }
- for (int j = SHADER_CACHE_SIZE - 1; j > 0; j--) {
- state->shader_cache[j] = state->shader_cache[j - 1];
- }
-
- /* Allocate memory for shader. */
- shader = (OCIO_GLSLShader *) MEM_callocN(sizeof(OCIO_GLSLShader),
- "OCIO GLSL Shader");
- state->shader_cache[0] = shader;
-
- new (&shader->lut3dCacheID) std::string();
- new (&shader->shaderCacheID) std::string();
-
- shader->lut3dCacheID = lut3dCacheID;
- shader->shaderCacheID = shaderCacheID;
- shader->use_curve_mapping = use_curve_mapping;
- shader->use_dither = use_dither;
- shader->use_predivide = use_predivide;
-
- bool valid = true;
-
- /* Compute 3D LUT. */
- if (valid && ensureLUT3DAllocated(shader)) {
- ocio_processor->getGpuLut3D(shader->lut3d, shaderDesc);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
- glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
- LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
- GL_RGB, GL_FLOAT, shader->lut3d);
- }
- else {
- valid = false;
- }
-
- /* Allocate curve mapping texture. */
- if (valid && use_curve_mapping) {
- if (!ensureCurveMappingAllocated(shader, curve_mapping_settings)) {
- valid = false;
- }
- }
-
- if (valid) {
- /* Vertex shader */
- std::ostringstream osv;
-
- osv << "#version 330\n";
- osv << datatoc_gpu_shader_display_transform_vertex_glsl;
-
- shader->vert_shader = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
-
- /* Fragment shader */
- std::ostringstream os;
-
- os << "#version 330\n";
-
- /* Work around OpenColorIO not supporting latest GLSL yet. */
- os << "#define texture2D texture\n";
- os << "#define texture3D texture\n";
-
- if (use_predivide) {
- os << "#define USE_PREDIVIDE\n";
- }
-
- if (use_dither) {
- os << "#define USE_DITHER\n";
- }
-
- if (use_curve_mapping) {
- os << "#define USE_CURVE_MAPPING\n";
- }
-
- os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
- os << datatoc_gpu_shader_display_transform_glsl;
-
- shader->ocio_shader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
-
- /* Program */
- if (shader->ocio_shader && shader->vert_shader) {
- shader->program = linkShaders(shader->ocio_shader, shader->vert_shader);
- }
-
- if (shader->program) {
- if (shader->shader_interface) {
- GPU_shaderinterface_discard(shader->shader_interface);
- }
- shader->shader_interface = GPU_shaderinterface_create(shader->program);
- }
- }
- }
-
- /* Update curve mapping texture. */
- if (use_curve_mapping && shader->curve_mapping_texture_allocated) {
- if (shader->curve_mapping_cache_id != curve_mapping_settings->cache_id) {
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
- glTexSubImage1D(GL_TEXTURE_1D, 0, 0, curve_mapping_settings->lut_size,
- GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
- }
- }
-
- /* Bind Shader. */
- if (shader->program) {
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
-
- if (use_curve_mapping) {
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
- }
-
- glActiveTexture(GL_TEXTURE0);
-
- /* IMM needs vertex format even if we don't draw with it.
- *
- * NOTE: The only reason why it's here is because of Cycles viewport.
- * All other areas are managing their own vertex formats.
- * Doing it here is probably harmless, but kind of stupid.
- *
- * TODO(sergey): Look into some nicer solution.
- */
- GPUVertFormat *format = immVertexFormat();
- GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindProgram(shader->program, shader->shader_interface);
-
- immUniform1i("image_texture", 0);
- immUniform1i("lut3d_texture", 1);
-
- if (use_dither) {
- immUniform1f("dither", dither);
- }
-
- if (use_curve_mapping) {
- immUniform1i("curve_mapping_texture", 2);
- immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size);
- immUniform4iv("use_curve_mapping_extend_extrapolate", curve_mapping_settings->use_extend_extrapolate);
- immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable);
- immUniform4fv("curve_mapping_range", curve_mapping_settings->range);
- immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x);
- immUniform4fv("curve_mapping_ext_in_y", curve_mapping_settings->ext_in_y);
- immUniform4fv("curve_mapping_ext_out_x", curve_mapping_settings->ext_out_x);
- immUniform4fv("curve_mapping_ext_out_y", curve_mapping_settings->ext_out_y);
- immUniform4fv("curve_mapping_first_x", curve_mapping_settings->first_x);
- immUniform4fv("curve_mapping_first_y", curve_mapping_settings->first_y);
- immUniform4fv("curve_mapping_last_x", curve_mapping_settings->last_x);
- immUniform4fv("curve_mapping_last_y", curve_mapping_settings->last_y);
- immUniform3fv("curve_mapping_black", curve_mapping_settings->black);
- immUniform3fv("curve_mapping_bwmul", curve_mapping_settings->bwmul);
- }
-
- return true;
- }
- else {
- glActiveTexture(state->last_texture_unit);
- glBindTexture(GL_TEXTURE_2D, state->last_texture);
-
- return false;
- }
+ ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *)processor;
+ bool use_curve_mapping = curve_mapping_settings != NULL;
+ bool use_dither = dither > std::numeric_limits<float>::epsilon();
+
+ /* Create state if needed. */
+ OCIO_GLSLDrawState *state;
+ if (!*state_r)
+ *state_r = allocateOpenGLState();
+ state = *state_r;
+
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &state->last_texture);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
+
+ /* Compute cache IDs. */
+ GpuShaderDesc shaderDesc;
+ shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3);
+ shaderDesc.setFunctionName("OCIODisplay");
+ shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
+
+ std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
+ std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
+
+ /* Find matching cached shader. */
+ OCIO_GLSLShader *shader = NULL;
+ for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
+ OCIO_GLSLShader *cached_shader = state->shader_cache[i];
+ if (cached_shader == NULL) {
+ continue;
+ }
+
+ if (cached_shader->lut3dCacheID == lut3dCacheID &&
+ cached_shader->shaderCacheID == shaderCacheID &&
+ cached_shader->use_predivide == use_predivide &&
+ cached_shader->use_curve_mapping == use_curve_mapping &&
+ cached_shader->use_dither == use_dither) {
+ /* LRU cache, so move to front. */
+ for (int j = i; j > 0; j--) {
+ state->shader_cache[j] = state->shader_cache[j - 1];
+ }
+ state->shader_cache[0] = cached_shader;
+
+ shader = cached_shader;
+ break;
+ }
+ }
+
+ if (shader == NULL) {
+ /* LRU cache, shift other items back so we can insert at the front. */
+ OCIO_GLSLShader *last_shader = state->shader_cache[SHADER_CACHE_SIZE - 1];
+ if (last_shader) {
+ freeGLSLShader(last_shader);
+ }
+ for (int j = SHADER_CACHE_SIZE - 1; j > 0; j--) {
+ state->shader_cache[j] = state->shader_cache[j - 1];
+ }
+
+ /* Allocate memory for shader. */
+ shader = (OCIO_GLSLShader *)MEM_callocN(sizeof(OCIO_GLSLShader), "OCIO GLSL Shader");
+ state->shader_cache[0] = shader;
+
+ new (&shader->lut3dCacheID) std::string();
+ new (&shader->shaderCacheID) std::string();
+
+ shader->lut3dCacheID = lut3dCacheID;
+ shader->shaderCacheID = shaderCacheID;
+ shader->use_curve_mapping = use_curve_mapping;
+ shader->use_dither = use_dither;
+ shader->use_predivide = use_predivide;
+
+ bool valid = true;
+
+ /* Compute 3D LUT. */
+ if (valid && ensureLUT3DAllocated(shader)) {
+ ocio_processor->getGpuLut3D(shader->lut3d, shaderDesc);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
+ glTexSubImage3D(GL_TEXTURE_3D,
+ 0,
+ 0,
+ 0,
+ 0,
+ LUT3D_EDGE_SIZE,
+ LUT3D_EDGE_SIZE,
+ LUT3D_EDGE_SIZE,
+ GL_RGB,
+ GL_FLOAT,
+ shader->lut3d);
+ }
+ else {
+ valid = false;
+ }
+
+ /* Allocate curve mapping texture. */
+ if (valid && use_curve_mapping) {
+ if (!ensureCurveMappingAllocated(shader, curve_mapping_settings)) {
+ valid = false;
+ }
+ }
+
+ if (valid) {
+ /* Vertex shader */
+ std::ostringstream osv;
+
+ osv << "#version 330\n";
+ osv << datatoc_gpu_shader_display_transform_vertex_glsl;
+
+ shader->vert_shader = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
+
+ /* Fragment shader */
+ std::ostringstream os;
+
+ os << "#version 330\n";
+
+ /* Work around OpenColorIO not supporting latest GLSL yet. */
+ os << "#define texture2D texture\n";
+ os << "#define texture3D texture\n";
+
+ if (use_predivide) {
+ os << "#define USE_PREDIVIDE\n";
+ }
+
+ if (use_dither) {
+ os << "#define USE_DITHER\n";
+ }
+
+ if (use_curve_mapping) {
+ os << "#define USE_CURVE_MAPPING\n";
+ }
+
+ os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
+ os << datatoc_gpu_shader_display_transform_glsl;
+
+ shader->ocio_shader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
+
+ /* Program */
+ if (shader->ocio_shader && shader->vert_shader) {
+ shader->program = linkShaders(shader->ocio_shader, shader->vert_shader);
+ }
+
+ if (shader->program) {
+ if (shader->shader_interface) {
+ GPU_shaderinterface_discard(shader->shader_interface);
+ }
+ shader->shader_interface = GPU_shaderinterface_create(shader->program);
+ }
+ }
+ }
+
+ /* Update curve mapping texture. */
+ if (use_curve_mapping && shader->curve_mapping_texture_allocated) {
+ if (shader->curve_mapping_cache_id != curve_mapping_settings->cache_id) {
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
+ glTexSubImage1D(GL_TEXTURE_1D,
+ 0,
+ 0,
+ curve_mapping_settings->lut_size,
+ GL_RGBA,
+ GL_FLOAT,
+ curve_mapping_settings->lut);
+ }
+ }
+
+ /* Bind Shader. */
+ if (shader->program) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
+
+ if (use_curve_mapping) {
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
+ }
+
+ glActiveTexture(GL_TEXTURE0);
+
+ /* IMM needs vertex format even if we don't draw with it.
+ *
+ * NOTE: The only reason why it's here is because of Cycles viewport.
+ * All other areas are managing their own vertex formats.
+ * Doing it here is probably harmless, but kind of stupid.
+ *
+ * TODO(sergey): Look into some nicer solution.
+ */
+ GPUVertFormat *format = immVertexFormat();
+ GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindProgram(shader->program, shader->shader_interface);
+
+ immUniform1i("image_texture", 0);
+ immUniform1i("lut3d_texture", 1);
+
+ if (use_dither) {
+ immUniform1f("dither", dither);
+ }
+
+ if (use_curve_mapping) {
+ immUniform1i("curve_mapping_texture", 2);
+ immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size);
+ immUniform4iv("use_curve_mapping_extend_extrapolate",
+ curve_mapping_settings->use_extend_extrapolate);
+ immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable);
+ immUniform4fv("curve_mapping_range", curve_mapping_settings->range);
+ immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x);
+ immUniform4fv("curve_mapping_ext_in_y", curve_mapping_settings->ext_in_y);
+ immUniform4fv("curve_mapping_ext_out_x", curve_mapping_settings->ext_out_x);
+ immUniform4fv("curve_mapping_ext_out_y", curve_mapping_settings->ext_out_y);
+ immUniform4fv("curve_mapping_first_x", curve_mapping_settings->first_x);
+ immUniform4fv("curve_mapping_first_y", curve_mapping_settings->first_y);
+ immUniform4fv("curve_mapping_last_x", curve_mapping_settings->last_x);
+ immUniform4fv("curve_mapping_last_y", curve_mapping_settings->last_y);
+ immUniform3fv("curve_mapping_black", curve_mapping_settings->black);
+ immUniform3fv("curve_mapping_bwmul", curve_mapping_settings->bwmul);
+ }
+
+ return true;
+ }
+ else {
+ glActiveTexture(state->last_texture_unit);
+ glBindTexture(GL_TEXTURE_2D, state->last_texture);
+
+ return false;
+ }
}
void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
{
- glActiveTexture(state->last_texture_unit);
- glBindTexture(GL_TEXTURE_2D, state->last_texture);
- immUnbindProgram();
+ glActiveTexture(state->last_texture_unit);
+ glBindTexture(GL_TEXTURE_2D, state->last_texture);
+ immUnbindProgram();
}
void OCIOImpl::freeGLState(OCIO_GLSLDrawState *state)
{
- for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
- if (state->shader_cache[i]) {
- freeGLSLShader(state->shader_cache[i]);
- }
- }
+ for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
+ if (state->shader_cache[i]) {
+ freeGLSLShader(state->shader_cache[i]);
+ }
+ }
- MEM_freeN(state);
+ MEM_freeN(state);
}
diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt
index 62ecb314a80..be0c213b6e6 100644
--- a/intern/opensubdiv/CMakeLists.txt
+++ b/intern/opensubdiv/CMakeLists.txt
@@ -19,110 +19,110 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../guardedalloc
+ .
+ ../guardedalloc
)
set(INC_SYS
)
set(SRC
- opensubdiv_capi.h
- opensubdiv_capi_type.h
- opensubdiv_converter_capi.h
- opensubdiv_evaluator_capi.h
- opensubdiv_gl_mesh_capi.h
- opensubdiv_topology_refiner_capi.h
+ opensubdiv_capi.h
+ opensubdiv_capi_type.h
+ opensubdiv_converter_capi.h
+ opensubdiv_evaluator_capi.h
+ opensubdiv_gl_mesh_capi.h
+ opensubdiv_topology_refiner_capi.h
)
set(LIB
)
if(WITH_OPENSUBDIV)
- macro(OPENSUBDIV_DEFINE_COMPONENT component)
- if(${${component}})
- add_definitions(-D${component})
- endif()
- endmacro()
+ macro(OPENSUBDIV_DEFINE_COMPONENT component)
+ if(${${component}})
+ add_definitions(-D${component})
+ endif()
+ endmacro()
- list(APPEND INC_SYS
- ${OPENSUBDIV_INCLUDE_DIR}
- ${GLEW_INCLUDE_PATH}
- )
+ list(APPEND INC_SYS
+ ${OPENSUBDIV_INCLUDE_DIR}
+ ${GLEW_INCLUDE_PATH}
+ )
- list(APPEND SRC
- internal/opensubdiv.cc
- internal/opensubdiv_converter_factory.cc
- internal/opensubdiv_converter_internal.cc
- internal/opensubdiv_converter_orient.cc
- internal/opensubdiv_device_context_cuda.cc
- internal/opensubdiv_device_context_opencl.cc
- internal/opensubdiv_evaluator.cc
- internal/opensubdiv_evaluator_internal.cc
- internal/opensubdiv_gl_mesh.cc
- internal/opensubdiv_gl_mesh_draw.cc
- internal/opensubdiv_gl_mesh_fvar.cc
- internal/opensubdiv_gl_mesh_internal.cc
- internal/opensubdiv_topology_refiner.cc
- internal/opensubdiv_topology_refiner_internal.cc
- internal/opensubdiv_util.cc
+ list(APPEND SRC
+ internal/opensubdiv.cc
+ internal/opensubdiv_converter_factory.cc
+ internal/opensubdiv_converter_internal.cc
+ internal/opensubdiv_converter_orient.cc
+ internal/opensubdiv_device_context_cuda.cc
+ internal/opensubdiv_device_context_opencl.cc
+ internal/opensubdiv_evaluator.cc
+ internal/opensubdiv_evaluator_internal.cc
+ internal/opensubdiv_gl_mesh.cc
+ internal/opensubdiv_gl_mesh_draw.cc
+ internal/opensubdiv_gl_mesh_fvar.cc
+ internal/opensubdiv_gl_mesh_internal.cc
+ internal/opensubdiv_topology_refiner.cc
+ internal/opensubdiv_topology_refiner_internal.cc
+ internal/opensubdiv_util.cc
- internal/opensubdiv_converter_factory.h
- internal/opensubdiv_converter_internal.h
- internal/opensubdiv_converter_orient.h
- internal/opensubdiv_converter_orient_impl.h
- internal/opensubdiv_device_context_cuda.h
- internal/opensubdiv_device_context_opencl.h
- internal/opensubdiv_edge_map.h
- internal/opensubdiv_evaluator_internal.h
- internal/opensubdiv_gl_mesh_draw.h
- internal/opensubdiv_gl_mesh_fvar.h
- internal/opensubdiv_gl_mesh_internal.h
- internal/opensubdiv_internal.h
- internal/opensubdiv_topology_refiner_internal.h
- internal/opensubdiv_util.h
- )
+ internal/opensubdiv_converter_factory.h
+ internal/opensubdiv_converter_internal.h
+ internal/opensubdiv_converter_orient.h
+ internal/opensubdiv_converter_orient_impl.h
+ internal/opensubdiv_device_context_cuda.h
+ internal/opensubdiv_device_context_opencl.h
+ internal/opensubdiv_edge_map.h
+ internal/opensubdiv_evaluator_internal.h
+ internal/opensubdiv_gl_mesh_draw.h
+ internal/opensubdiv_gl_mesh_fvar.h
+ internal/opensubdiv_gl_mesh_internal.h
+ internal/opensubdiv_internal.h
+ internal/opensubdiv_topology_refiner_internal.h
+ internal/opensubdiv_util.h
+ )
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP)
- # TODO(sergey): OpenCL is not tested and totally unstable atm.
- # OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
- # TODO(sergey): CUDA stays disabled for util it's ported to drievr API.
- # OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
+ OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP)
+ # TODO(sergey): OpenCL is not tested and totally unstable atm.
+ # OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
+ # TODO(sergey): CUDA stays disabled for util it's ported to drievr API.
+ # OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
+ OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
+ OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
- data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC)
- data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC)
- data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC)
+ data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC)
+ data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC)
+ data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC)
- add_definitions(-DGLEW_STATIC)
+ add_definitions(-DGLEW_STATIC)
- if(WIN32)
- add_definitions(-DNOMINMAX)
- add_definitions(-D_USE_MATH_DEFINES)
- endif()
+ if(WIN32)
+ add_definitions(-DNOMINMAX)
+ add_definitions(-D_USE_MATH_DEFINES)
+ endif()
- # TODO(sergey): Put CUEW back when CUDA is officially supported by OSD.
- #if(OPENSUBDIV_HAS_CUDA)
- # list(APPEND INC
- # ../../extern/cuew/include
- # )
- # add_definitions(-DOPENSUBDIV_HAS_CUEW)
- #endif()
+ # TODO(sergey): Put CUEW back when CUDA is officially supported by OSD.
+ #if(OPENSUBDIV_HAS_CUDA)
+ # list(APPEND INC
+ # ../../extern/cuew/include
+ # )
+ # add_definitions(-DOPENSUBDIV_HAS_CUEW)
+ #endif()
- if(OPENSUBDIV_HAS_OPENCL)
- list(APPEND INC
- ../../extern/clew/include
- )
- add_definitions(-DOPENSUBDIV_HAS_CLEW)
- endif()
+ if(OPENSUBDIV_HAS_OPENCL)
+ list(APPEND INC
+ ../../extern/clew/include
+ )
+ add_definitions(-DOPENSUBDIV_HAS_CLEW)
+ endif()
else()
- list(APPEND SRC
- stub/opensubdiv_stub.cc
- stub/opensubdiv_evaluator_stub.cc
- stub/opensubdiv_gl_mesh_stub.cc
- stub/opensubdiv_topology_refiner_stub.cc
- )
+ list(APPEND SRC
+ stub/opensubdiv_stub.cc
+ stub/opensubdiv_evaluator_stub.cc
+ stub/opensubdiv_gl_mesh_stub.cc
+ stub/opensubdiv_topology_refiner_stub.cc
+ )
endif()
blender_add_lib(bf_intern_opensubdiv "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/opensubdiv/internal/opensubdiv.cc b/intern/opensubdiv/internal/opensubdiv.cc
index b535532b3ae..dc19d3d9306 100644
--- a/intern/opensubdiv/internal/opensubdiv.cc
+++ b/intern/opensubdiv/internal/opensubdiv.cc
@@ -26,16 +26,19 @@
#include "opensubdiv_device_context_cuda.h"
#include "opensubdiv_gl_mesh_capi.h"
-void openSubdiv_init(void) {
+void openSubdiv_init(void)
+{
// Ensure all OpenGL strings are cached.
openSubdiv_getAvailableEvaluators();
}
-void openSubdiv_cleanup(void) {
+void openSubdiv_cleanup(void)
+{
openSubdiv_deinitGLMeshDrawingResources();
}
-int openSubdiv_getAvailableEvaluators(void) {
+int openSubdiv_getAvailableEvaluators(void)
+{
int flags = OPENSUBDIV_EVALUATOR_CPU;
#ifdef OPENSUBDIV_HAS_OPENMP
@@ -69,15 +72,15 @@ int openSubdiv_getAvailableEvaluators(void) {
return flags;
}
-int openSubdiv_getVersionHex(void) {
+int openSubdiv_getVersionHex(void)
+{
#if defined(OPENSUBDIV_VERSION_NUMBER)
return OPENSUBDIV_VERSION_NUMBER;
#elif defined(OPENSUBDIV_VERSION_MAJOR)
- return OPENSUBDIV_VERSION_MAJOR * 10000 +
- OPENSUBDIV_VERSION_MINOR * 100 +
+ return OPENSUBDIV_VERSION_MAJOR * 10000 + OPENSUBDIV_VERSION_MINOR * 100 +
OPENSUBDIV_VERSION_PATCH;
#elif defined(OPENSUBDIV_VERSION)
- const char* version = STRINGIFY(OPENSUBDIV_VERSION);
+ const char *version = STRINGIFY(OPENSUBDIV_VERSION);
if (version[0] == 'v') {
version += 1;
}
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
index e07880b7d8d..0c1514f2fea 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
@@ -34,29 +34,27 @@
#include "opensubdiv_converter_capi.h"
using opensubdiv_capi::min;
-using opensubdiv_capi::vector;
using opensubdiv_capi::stack;
+using opensubdiv_capi::vector;
struct TopologyRefinerData {
- const OpenSubdiv_Converter* converter;
+ const OpenSubdiv_Converter *converter;
};
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far {
-template <>
-inline bool
-TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology(
- TopologyRefiner& refiner,
- const TopologyRefinerData& cb_data) {
- const OpenSubdiv_Converter* converter = cb_data.converter;
+template<>
+inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology(
+ TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
+{
+ const OpenSubdiv_Converter *converter = cb_data.converter;
// Faces and face-vertices.
const int num_faces = converter->getNumFaces(converter);
setNumBaseFaces(refiner, num_faces);
for (int face_index = 0; face_index < num_faces; ++face_index) {
- const int num_face_vertices =
- converter->getNumFaceVertices(converter, face_index);
+ const int num_face_vertices = converter->getNumFaceVertices(converter, face_index);
setNumBaseFaceVertices(refiner, face_index, num_face_vertices);
}
// Vertices.
@@ -70,31 +68,26 @@ TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology(
const int num_edges = converter->getNumEdges(converter);
setNumBaseEdges(refiner, num_edges);
for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
- const int num_edge_faces =
- converter->getNumEdgeFaces(converter, edge_index);
+ const int num_edge_faces = converter->getNumEdgeFaces(converter, edge_index);
setNumBaseEdgeFaces(refiner, edge_index, num_edge_faces);
}
// Vertex-faces and vertex-edges.
for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
- const int num_vert_edges =
- converter->getNumVertexEdges(converter, vertex_index);
- const int num_vert_faces =
- converter->getNumVertexFaces(converter, vertex_index);
+ const int num_vert_edges = converter->getNumVertexEdges(converter, vertex_index);
+ const int num_vert_faces = converter->getNumVertexFaces(converter, vertex_index);
setNumBaseVertexEdges(refiner, vertex_index, num_vert_edges);
setNumBaseVertexFaces(refiner, vertex_index, num_vert_faces);
}
return true;
}
-template <>
-inline bool
-TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology(
- TopologyRefiner& refiner,
- const TopologyRefinerData& cb_data) {
+template<>
+inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology(
+ TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
+{
using Far::IndexArray;
- const OpenSubdiv_Converter* converter = cb_data.converter;
- const bool full_topology_specified =
- converter->specifiesFullTopology(converter);
+ const OpenSubdiv_Converter *converter = cb_data.converter;
+ const bool full_topology_specified = converter->specifiesFullTopology(converter);
// Face relations.
const int num_faces = converter->getNumFaces(converter);
for (int face_index = 0; face_index < num_faces; ++face_index) {
@@ -125,47 +118,41 @@ TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology(
for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
// Vertex-faces.
IndexArray dst_vertex_faces = getBaseVertexFaces(refiner, vertex_index);
- const int num_vertex_faces =
- converter->getNumVertexFaces(converter, vertex_index);
+ const int num_vertex_faces = converter->getNumVertexFaces(converter, vertex_index);
vertex_faces.resize(num_vertex_faces);
converter->getVertexFaces(converter, vertex_index, &vertex_faces[0]);
// Vertex-edges.
IndexArray dst_vertex_edges = getBaseVertexEdges(refiner, vertex_index);
- const int num_vertex_edges =
- converter->getNumVertexEdges(converter, vertex_index);
+ const int num_vertex_edges = converter->getNumVertexEdges(converter, vertex_index);
vertex_edges.resize(num_vertex_edges);
converter->getVertexEdges(converter, vertex_index, &vertex_edges[0]);
- memcpy(&dst_vertex_edges[0], &vertex_edges[0],
- sizeof(int) * num_vertex_edges);
- memcpy(&dst_vertex_faces[0], &vertex_faces[0],
- sizeof(int) * num_vertex_faces);
+ memcpy(&dst_vertex_edges[0], &vertex_edges[0], sizeof(int) * num_vertex_edges);
+ memcpy(&dst_vertex_faces[0], &vertex_faces[0], sizeof(int) * num_vertex_faces);
}
populateBaseLocalIndices(refiner);
return true;
}
-template <>
+template<>
inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
- TopologyRefiner& refiner,
- const TopologyRefinerData& cb_data) {
+ TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
+{
using OpenSubdiv::Sdc::Crease;
- const OpenSubdiv_Converter* converter = cb_data.converter;
- const bool full_topology_specified =
- converter->specifiesFullTopology(converter);
+ const OpenSubdiv_Converter *converter = cb_data.converter;
+ const bool full_topology_specified = converter->specifiesFullTopology(converter);
const int num_edges = converter->getNumEdges(converter);
for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
- const float sharpness =
- converter->getEdgeSharpness(converter, edge_index);
+ const float sharpness = converter->getEdgeSharpness(converter, edge_index);
if (sharpness < 1e-6f) {
continue;
}
if (full_topology_specified) {
setBaseEdgeSharpness(refiner, edge_index, sharpness);
- } else {
+ }
+ else {
int edge_vertices[2];
converter->getEdgeVertices(converter, edge_index, edge_vertices);
- const int base_edge_index = findBaseEdge(
- refiner, edge_vertices[0], edge_vertices[1]);
+ const int base_edge_index = findBaseEdge(refiner, edge_vertices[0], edge_vertices[1]);
if (base_edge_index == OpenSubdiv::Far::INDEX_INVALID) {
printf("OpenSubdiv Error: failed to find reconstructed edge\n");
return false;
@@ -181,8 +168,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
ConstIndexArray vertex_edges = getBaseVertexEdges(refiner, vertex_index);
if (converter->isInfiniteSharpVertex(converter, vertex_index)) {
- setBaseVertexSharpness(
- refiner, vertex_index, Crease::SHARPNESS_INFINITE);
+ setBaseVertexSharpness(refiner, vertex_index, Crease::SHARPNESS_INFINITE);
continue;
}
float sharpness = converter->getVertexSharpness(converter, vertex_index);
@@ -199,12 +185,11 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
return true;
}
-template <>
-inline bool
-TopologyRefinerFactory<TopologyRefinerData>::assignFaceVaryingTopology(
- TopologyRefiner& refiner,
- const TopologyRefinerData& cb_data) {
- const OpenSubdiv_Converter* converter = cb_data.converter;
+template<>
+inline bool TopologyRefinerFactory<TopologyRefinerData>::assignFaceVaryingTopology(
+ TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
+{
+ const OpenSubdiv_Converter *converter = cb_data.converter;
const int num_layers = converter->getNumUVLayers(converter);
if (num_layers <= 0) {
// No UV maps, we can skip any face-varying data.
@@ -219,11 +204,9 @@ TopologyRefinerFactory<TopologyRefinerData>::assignFaceVaryingTopology(
// TODO(sergey): Need to check whether converter changed the winding of
// face to match OpenSubdiv's expectations.
for (int face_index = 0; face_index < num_faces; ++face_index) {
- Far::IndexArray dst_face_uvs =
- getBaseFaceFVarValues(refiner, face_index, channel);
+ Far::IndexArray dst_face_uvs = getBaseFaceFVarValues(refiner, face_index, channel);
for (int corner = 0; corner < dst_face_uvs.size(); ++corner) {
- const int uv_index =
- converter->getFaceCornerUVIndex(converter, face_index, corner);
+ const int uv_index = converter->getFaceCornerUVIndex(converter, face_index, corner);
dst_face_uvs[corner] = uv_index;
}
}
@@ -232,10 +215,10 @@ TopologyRefinerFactory<TopologyRefinerData>::assignFaceVaryingTopology(
return true;
}
-template <>
+template<>
inline void TopologyRefinerFactory<TopologyRefinerData>::reportInvalidTopology(
- TopologyError /*errCode*/, const char* msg,
- const TopologyRefinerData& /*mesh*/) {
+ TopologyError /*errCode*/, const char *msg, const TopologyRefinerData & /*mesh*/)
+{
printf("OpenSubdiv Error: %s\n", msg);
}
@@ -247,9 +230,9 @@ namespace opensubdiv_capi {
namespace {
-OpenSubdiv::Sdc::Options::VtxBoundaryInterpolation
-getVtxBoundaryInterpolationFromCAPI(
- OpenSubdiv_VtxBoundaryInterpolation boundary_interpolation) {
+OpenSubdiv::Sdc::Options::VtxBoundaryInterpolation getVtxBoundaryInterpolationFromCAPI(
+ OpenSubdiv_VtxBoundaryInterpolation boundary_interpolation)
+{
using OpenSubdiv::Sdc::Options;
switch (boundary_interpolation) {
case OSD_VTX_BOUNDARY_NONE:
@@ -265,31 +248,28 @@ getVtxBoundaryInterpolationFromCAPI(
} // namespace
-OpenSubdiv::Far::TopologyRefiner* createOSDTopologyRefinerFromConverter(
- OpenSubdiv_Converter* converter) {
- using OpenSubdiv::Sdc::Options;
+OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter(
+ OpenSubdiv_Converter *converter)
+{
using OpenSubdiv::Far::TopologyRefinerFactory;
- const OpenSubdiv::Sdc::SchemeType scheme_type =
- getSchemeTypeFromCAPI(converter->getSchemeType(converter));
- const Options::FVarLinearInterpolation linear_interpolation =
- getFVarLinearInterpolationFromCAPI(
- converter->getFVarLinearInterpolation(converter));
+ using OpenSubdiv::Sdc::Options;
+ const OpenSubdiv::Sdc::SchemeType scheme_type = getSchemeTypeFromCAPI(
+ converter->getSchemeType(converter));
+ const Options::FVarLinearInterpolation linear_interpolation = getFVarLinearInterpolationFromCAPI(
+ converter->getFVarLinearInterpolation(converter));
Options options;
options.SetVtxBoundaryInterpolation(
- getVtxBoundaryInterpolationFromCAPI(
- converter->getVtxBoundaryInterpolation(converter)));
+ getVtxBoundaryInterpolationFromCAPI(converter->getVtxBoundaryInterpolation(converter)));
options.SetCreasingMethod(Options::CREASE_UNIFORM);
options.SetFVarLinearInterpolation(linear_interpolation);
- TopologyRefinerFactory<TopologyRefinerData>::Options topology_options(
- scheme_type, options);
+ TopologyRefinerFactory<TopologyRefinerData>::Options topology_options(scheme_type, options);
#ifdef OPENSUBDIV_VALIDATE_TOPOLOGY
topology_options.validateFullTopology = true;
#endif
TopologyRefinerData cb_data;
cb_data.converter = converter;
- return TopologyRefinerFactory<TopologyRefinerData>::Create(
- cb_data, topology_options);
+ return TopologyRefinerFactory<TopologyRefinerData>::Create(cb_data, topology_options);
}
} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.h b/intern/opensubdiv/internal/opensubdiv_converter_factory.h
index 451418813e1..a1038474d33 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_factory.h
+++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.h
@@ -29,8 +29,8 @@ struct OpenSubdiv_Converter;
namespace opensubdiv_capi {
-OpenSubdiv::Far::TopologyRefiner* createOSDTopologyRefinerFromConverter(
- struct OpenSubdiv_Converter* converter);
+OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter(
+ struct OpenSubdiv_Converter *converter);
} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
index 2f7a7109ea1..e8d2f237936 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
@@ -27,7 +27,8 @@
namespace opensubdiv_capi {
-OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type) {
+OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type)
+{
switch (type) {
case OSD_SCHEME_BILINEAR:
return OpenSubdiv::Sdc::SCHEME_BILINEAR;
@@ -40,9 +41,9 @@ OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type) {
return OpenSubdiv::Sdc::SCHEME_CATMARK;
}
-OpenSubdiv::Sdc::Options::FVarLinearInterpolation
-getFVarLinearInterpolationFromCAPI(
- OpenSubdiv_FVarLinearInterpolation linear_interpolation) {
+OpenSubdiv::Sdc::Options::FVarLinearInterpolation getFVarLinearInterpolationFromCAPI(
+ OpenSubdiv_FVarLinearInterpolation linear_interpolation)
+{
typedef OpenSubdiv::Sdc::Options Options;
switch (linear_interpolation) {
case OSD_FVAR_LINEAR_INTERPOLATION_NONE:
@@ -62,9 +63,9 @@ getFVarLinearInterpolationFromCAPI(
return Options::FVAR_LINEAR_NONE;
}
-OpenSubdiv_FVarLinearInterpolation
-getCAPIFVarLinearInterpolationFromOSD(
- OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation) {
+OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD(
+ OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation)
+{
typedef OpenSubdiv::Sdc::Options Options;
switch (linear_interpolation) {
case Options::FVAR_LINEAR_NONE:
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.h b/intern/opensubdiv/internal/opensubdiv_converter_internal.h
index 411514c45dc..11c6bdd7f3b 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.h
@@ -37,14 +37,12 @@ OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type);
// Convert face-varying interpolation type from C-API to an OpenSubdiv
// native enum.
-OpenSubdiv::Sdc::Options::FVarLinearInterpolation
-getFVarLinearInterpolationFromCAPI(
+OpenSubdiv::Sdc::Options::FVarLinearInterpolation getFVarLinearInterpolationFromCAPI(
OpenSubdiv_FVarLinearInterpolation linear_interpolation);
// Similar to above, just other way around.
-OpenSubdiv_FVarLinearInterpolation
-getCAPIFVarLinearInterpolationFromOSD(
- OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation);
+OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD(
+ OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation);
} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient.cc b/intern/opensubdiv/internal/opensubdiv_converter_orient.cc
index 449e9028180..e3367fc6314 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_orient.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_orient.cc
@@ -24,10 +24,11 @@ namespace opensubdiv_capi {
void checkOrientedVertexConnectivity(const int num_vertex_edges,
const int num_vertex_faces,
- const int* vertex_edges,
- const int* vertex_faces,
- const int* dst_vertex_edges,
- const int* dst_vertex_faces) {
+ const int *vertex_edges,
+ const int *vertex_faces,
+ const int *dst_vertex_edges,
+ const int *dst_vertex_faces)
+{
#ifndef NDEBUG
for (int i = 0; i < num_vertex_faces; ++i) {
bool found = false;
@@ -54,12 +55,12 @@ void checkOrientedVertexConnectivity(const int num_vertex_edges,
}
}
#else
- (void) num_vertex_edges;
- (void) num_vertex_faces;
- (void) vertex_edges;
- (void) vertex_faces;
- (void) dst_vertex_edges;
- (void) dst_vertex_faces;
+ (void)num_vertex_edges;
+ (void)num_vertex_faces;
+ (void)vertex_edges;
+ (void)vertex_faces;
+ (void)dst_vertex_edges;
+ (void)dst_vertex_faces;
#endif
}
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient.h b/intern/opensubdiv/internal/opensubdiv_converter_orient.h
index b783007a0cb..967871845cb 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_orient.h
+++ b/intern/opensubdiv/internal/opensubdiv_converter_orient.h
@@ -17,31 +17,30 @@
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_CONVERTER_ORIENT_H_
-#define OPENSUBDIV_CONVERTER_ORIENT_H_
+# define OPENSUBDIV_CONVERTER_ORIENT_H_
-#include <opensubdiv/far/types.h>
+# include <opensubdiv/far/types.h>
// Set of utility functions which are needed to bring topology to an orientation
// (or, winding, if you wish) which OpenSubdiv expects.
namespace opensubdiv_capi {
-inline void reverseFaceVertices(int* face_vertices, const int num_vertices);
+inline void reverseFaceVertices(int *face_vertices, const int num_vertices);
// TODO(sergey): Document which value corresponds to which winding.
inline int getLoopWinding(int vert0_of_face, int vert1_of_face);
-inline void reverseFaceLoops(
- OpenSubdiv::Far::IndexArray* face_vertices,
- OpenSubdiv::Far::IndexArray* face_edges);
+inline void reverseFaceLoops(OpenSubdiv::Far::IndexArray *face_vertices,
+ OpenSubdiv::Far::IndexArray *face_edges);
// Used for debugging, checks whether orientation happened correct.
void checkOrientedVertexConnectivity(const int num_vertex_edges,
const int num_vertex_faces,
- const int* vertex_edges,
- const int* vertex_faces,
- const int* dst_vertex_edges,
- const int* dst_vertex_faces);
+ const int *vertex_edges,
+ const int *vertex_faces,
+ const int *dst_vertex_edges,
+ const int *dst_vertex_faces);
} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h b/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h
index 3e946595bba..aa717f5d99d 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h
+++ b/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h
@@ -27,7 +27,8 @@
namespace opensubdiv_capi {
-inline void reverseFaceVertices(int* face_vertices, const int num_vertices) {
+inline void reverseFaceVertices(int *face_vertices, const int num_vertices)
+{
int last_vert = face_vertices[num_vertices - 1];
for (int i = num_vertices - 1; i > 0; --i) {
face_vertices[i] = face_vertices[i - 1];
@@ -35,21 +36,23 @@ inline void reverseFaceVertices(int* face_vertices, const int num_vertices) {
face_vertices[0] = last_vert;
}
-inline int getLoopWinding(int vert0_of_face, int vert1_of_face) {
+inline int getLoopWinding(int vert0_of_face, int vert1_of_face)
+{
int delta_face = vert1_of_face - vert0_of_face;
if (abs(delta_face) != 1) {
if (delta_face > 0) {
delta_face = -1;
- } else {
+ }
+ else {
delta_face = 1;
}
}
return delta_face;
}
-inline void reverseFaceLoops(
- OpenSubdiv::Far::IndexArray* face_vertices,
- OpenSubdiv::Far::IndexArray* face_edges) {
+inline void reverseFaceLoops(OpenSubdiv::Far::IndexArray *face_vertices,
+ OpenSubdiv::Far::IndexArray *face_edges)
+{
const int num_face_vertices = face_vertices->size();
for (int i = 0; i < num_face_vertices / 2; ++i) {
const int j = num_face_vertices - i - 1;
diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc
index f5bc12efa84..5ce8af0434e 100644
--- a/intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc
+++ b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc
@@ -24,68 +24,70 @@
#ifdef OPENSUBDIV_HAS_CUDA
-#ifdef _MSC_VER
-# include <iso646.h>
-#endif
+# ifdef _MSC_VER
+# include <iso646.h>
+# endif
-#include "opensubdiv_device_context_cuda.h"
+# include "opensubdiv_device_context_cuda.h"
-#if defined(_WIN32)
-# include <windows.h>
-#elif defined(__APPLE__)
-# include <OpenGL/OpenGL.h>
-#else
-# include <GL/glx.h>
-# include <X11/Xlib.h>
-#endif
+# if defined(_WIN32)
+# include <windows.h>
+# elif defined(__APPLE__)
+# include <OpenGL/OpenGL.h>
+# else
+# include <GL/glx.h>
+# include <X11/Xlib.h>
+# endif
-#include <cuda.h>
-#include <cuda_gl_interop.h>
-#include <cuda_runtime_api.h>
-#include <cstdio>
+# include <cuda.h>
+# include <cuda_gl_interop.h>
+# include <cuda_runtime_api.h>
+# include <cstdio>
-#include "internal/opensubdiv_util.h"
+# include "internal/opensubdiv_util.h"
-#define message(fmt, ...)
+# define message(fmt, ...)
// #define message(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
-#define error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
+# define error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
namespace {
-int getCudaDeviceForCurrentGLContext() {
+int getCudaDeviceForCurrentGLContext()
+{
// Find and use the CUDA device for the current GL context
unsigned int interop_device_count = 0;
int interopDevices[1];
- cudaError_t status = cudaGLGetDevices(&interop_device_count,
- interopDevices,
- 1,
- cudaGLDeviceListCurrentFrame);
+ cudaError_t status = cudaGLGetDevices(
+ &interop_device_count, interopDevices, 1, cudaGLDeviceListCurrentFrame);
if (status == cudaErrorNoDevice || interop_device_count != 1) {
message("CUDA no interop devices found.\n");
return 0;
}
int device = interopDevices[0];
-#if defined(_WIN32)
+# if defined(_WIN32)
return device;
-#elif defined(__APPLE__)
+# elif defined(__APPLE__)
return device;
-#else // X11
- Display* display = glXGetCurrentDisplay();
+# else // X11
+ Display *display = glXGetCurrentDisplay();
int screen = DefaultScreen(display);
if (device != screen) {
- error("The CUDA interop device (%d) does not match "
- "the screen used by the current GL context (%d), "
- "which may cause slow performance on systems "
- "with multiple GPU devices.",
- device, screen);
+ error(
+ "The CUDA interop device (%d) does not match "
+ "the screen used by the current GL context (%d), "
+ "which may cause slow performance on systems "
+ "with multiple GPU devices.",
+ device,
+ screen);
}
message("CUDA init using device for current GL context: %d\n", device);
return device;
-#endif
+# endif
}
// Beginning of GPU Architecture definitions.
-int convertSMVer2Cores_local(int major, int minor) {
+int convertSMVer2Cores_local(int major, int minor)
+{
// Defines for GPU Architecture types (using the SM version to determine
// the # of cores per SM
typedef struct {
@@ -95,15 +97,14 @@ int convertSMVer2Cores_local(int major, int minor) {
int Cores;
} sSMtoCores;
- sSMtoCores nGpuArchCoresPerSM[] = {
- {0x10, 8}, // Tesla Generation (SM 1.0) G80 class.
- {0x11, 8}, // Tesla Generation (SM 1.1) G8x class.
- {0x12, 8}, // Tesla Generation (SM 1.2) G9x class.
- {0x13, 8}, // Tesla Generation (SM 1.3) GT200 class.
- {0x20, 32}, // Fermi Generation (SM 2.0) GF100 class.
- {0x21, 48}, // Fermi Generation (SM 2.1) GF10x class.
- {0x30, 192}, // Fermi Generation (SM 3.0) GK10x class.
- {-1, -1}};
+ sSMtoCores nGpuArchCoresPerSM[] = {{0x10, 8}, // Tesla Generation (SM 1.0) G80 class.
+ {0x11, 8}, // Tesla Generation (SM 1.1) G8x class.
+ {0x12, 8}, // Tesla Generation (SM 1.2) G9x class.
+ {0x13, 8}, // Tesla Generation (SM 1.3) GT200 class.
+ {0x20, 32}, // Fermi Generation (SM 2.0) GF100 class.
+ {0x21, 48}, // Fermi Generation (SM 2.1) GF10x class.
+ {0x30, 192}, // Fermi Generation (SM 3.0) GK10x class.
+ {-1, -1}};
int index = 0;
while (nGpuArchCoresPerSM[index].SM != -1) {
if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) {
@@ -116,7 +117,8 @@ int convertSMVer2Cores_local(int major, int minor) {
}
// This function returns the best GPU (with maximum GFLOPS).
-int cutGetMaxGflopsDeviceId() {
+int cutGetMaxGflopsDeviceId()
+{
int current_device = 0, sm_per_multiproc = 0;
int max_compute_perf = 0, max_perf_device = -1;
int device_count = 0, best_SM_arch = 0;
@@ -136,16 +138,15 @@ int cutGetMaxGflopsDeviceId() {
cuDeviceComputeCapability(&compat_major, &compat_minor, current_device);
if (compat_major == 9999 && compat_minor == 9999) {
sm_per_multiproc = 1;
- } else {
+ }
+ else {
sm_per_multiproc = convertSMVer2Cores_local(compat_major, compat_minor);
}
int multi_processor_count;
- cuDeviceGetAttribute(&multi_processor_count,
- CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
- current_device);
+ cuDeviceGetAttribute(
+ &multi_processor_count, CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, current_device);
int clock_rate;
- cuDeviceGetAttribute(&clock_rate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE,
- current_device);
+ cuDeviceGetAttribute(&clock_rate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, current_device);
int compute_perf = multi_processor_count * sm_per_multiproc * clock_rate;
if (compute_perf > max_compute_perf) {
/* If we find GPU with SM major > 2, search only these */
@@ -155,7 +156,8 @@ int cutGetMaxGflopsDeviceId() {
max_compute_perf = compute_perf;
max_perf_device = current_device;
}
- } else {
+ }
+ else {
max_compute_perf = compute_perf;
max_perf_device = current_device;
}
@@ -167,19 +169,20 @@ int cutGetMaxGflopsDeviceId() {
} // namespace
-bool CudaDeviceContext::HAS_CUDA_VERSION_4_0() {
-#ifdef OPENSUBDIV_HAS_CUDA
+bool CudaDeviceContext::HAS_CUDA_VERSION_4_0()
+{
+# ifdef OPENSUBDIV_HAS_CUDA
static bool cuda_initialized = false;
static bool cuda_load_success = true;
if (!cuda_initialized) {
cuda_initialized = true;
-#ifdef OPENSUBDIV_HAS_CUEW
+# ifdef OPENSUBDIV_HAS_CUEW
cuda_load_success = cuewInit(CUEW_INIT_CUDA) == CUEW_SUCCESS;
if (!cuda_load_success) {
fprintf(stderr, "Loading CUDA failed.\n");
}
-#endif
+# endif
// Need to initialize CUDA here so getting device
// with the maximum FPLOS works fine.
if (cuInit(0) == CUDA_SUCCESS) {
@@ -189,25 +192,28 @@ bool CudaDeviceContext::HAS_CUDA_VERSION_4_0() {
if (cutGetMaxGflopsDeviceId() < 0) {
cuda_load_success = false;
}
- } else {
+ }
+ else {
cuda_load_success = false;
}
}
return cuda_load_success;
-#else
+# else
return false;
-#endif
+# endif
}
-CudaDeviceContext::CudaDeviceContext()
- : initialized_(false) {
+CudaDeviceContext::CudaDeviceContext() : initialized_(false)
+{
}
-CudaDeviceContext::~CudaDeviceContext() {
+CudaDeviceContext::~CudaDeviceContext()
+{
cudaDeviceReset();
}
-bool CudaDeviceContext::Initialize() {
+bool CudaDeviceContext::Initialize()
+{
// See if any cuda device is available.
int device_count = 0;
cudaGetDeviceCount(&device_count);
@@ -220,7 +226,8 @@ bool CudaDeviceContext::Initialize() {
return true;
}
-bool CudaDeviceContext::IsInitialized() const {
+bool CudaDeviceContext::IsInitialized() const
+{
return initialized_;
}
diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_cuda.h b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.h
index ef212df10f0..10164e0cfc5 100644
--- a/intern/opensubdiv/internal/opensubdiv_device_context_cuda.h
+++ b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.h
@@ -40,7 +40,7 @@ class CudaDeviceContext {
bool Initialize();
// Initialze cuda device from the ID3D11Device.
- bool Initialize(ID3D11Device* device);
+ bool Initialize(ID3D11Device *device);
// Returns true if the cuda device has already been initialized.
bool IsInitialized() const;
diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc
index f6f1458b189..12f6ced4bbb 100644
--- a/intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc
+++ b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc
@@ -26,26 +26,27 @@
#ifdef OPENSUBDIV_HAS_OPENCL
-#if defined(_WIN32)
-# include <windows.h>
-#elif defined(__APPLE__)
-# include <OpenGL/OpenGL.h>
-#else
-# include <GL/glx.h>
-#endif
+# if defined(_WIN32)
+# include <windows.h>
+# elif defined(__APPLE__)
+# include <OpenGL/OpenGL.h>
+# else
+# include <GL/glx.h>
+# endif
-#include <cstdio>
-#include <cstring>
+# include <cstdio>
+# include <cstring>
-#include "internal/opensubdiv_util.h"
+# include "internal/opensubdiv_util.h"
-#define message(...) // fprintf(stderr, __VA_ARGS__)
-#define error(...) fprintf(stderr, __VA_ARGS__)
+# define message(...) // fprintf(stderr, __VA_ARGS__)
+# define error(...) fprintf(stderr, __VA_ARGS__)
namespace {
// Returns the first found platform.
-cl_platform_id findPlatform() {
+cl_platform_id findPlatform()
+{
cl_uint num_platforms;
cl_int ci_error_number = clGetPlatformIDs(0, NULL, &num_platforms);
if (ci_error_number != CL_SUCCESS) {
@@ -60,11 +61,8 @@ cl_platform_id findPlatform() {
ci_error_number = clGetPlatformIDs(num_platforms, &cl_platform_ids[0], NULL);
char ch_buffer[1024];
for (cl_uint i = 0; i < num_platforms; ++i) {
- ci_error_number = clGetPlatformInfo(cl_platform_ids[i],
- CL_PLATFORM_NAME,
- sizeof(ch_buffer),
- ch_buffer,
- NULL);
+ ci_error_number = clGetPlatformInfo(
+ cl_platform_ids[i], CL_PLATFORM_NAME, sizeof(ch_buffer), ch_buffer, NULL);
if (ci_error_number == CL_SUCCESS) {
cl_platform_id platform_id = cl_platform_ids[i];
return platform_id;
@@ -74,20 +72,18 @@ cl_platform_id findPlatform() {
}
// Return the device in cl_devices which supports the extension.
-int findExtensionSupportedDevice(cl_device_id* cl_devices,
+int findExtensionSupportedDevice(cl_device_id *cl_devices,
int num_devices,
- const char* extension_name) {
+ const char *extension_name)
+{
// Find a device that supports sharing with GL/D3D11
// (SLI / X-fire configurations)
cl_int cl_error_number;
for (int i = 0; i < num_devices; ++i) {
// Get extensions string size.
size_t extensions_size;
- cl_error_number = clGetDeviceInfo(cl_devices[i],
- CL_DEVICE_EXTENSIONS,
- 0,
- NULL,
- &extensions_size);
+ cl_error_number = clGetDeviceInfo(
+ cl_devices[i], CL_DEVICE_EXTENSIONS, 0, NULL, &extensions_size);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clGetDeviceInfo\n", cl_error_number);
return -1;
@@ -95,11 +91,8 @@ int findExtensionSupportedDevice(cl_device_id* cl_devices,
if (extensions_size > 0) {
// Get extensions string.
string extensions('\0', extensions_size);
- cl_error_number = clGetDeviceInfo(cl_devices[i],
- CL_DEVICE_EXTENSIONS,
- extensions_size,
- &extensions[0],
- &extensions_size);
+ cl_error_number = clGetDeviceInfo(
+ cl_devices[i], CL_DEVICE_EXTENSIONS, extensions_size, &extensions[0], &extensions_size);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clGetDeviceInfo\n", cl_error_number);
continue;
@@ -119,12 +112,12 @@ int findExtensionSupportedDevice(cl_device_id* cl_devices,
} // namespace
-CLDeviceContext::CLDeviceContext()
- : cl_context_(NULL),
- cl_command_queue_(NULL) {
+CLDeviceContext::CLDeviceContext() : cl_context_(NULL), cl_command_queue_(NULL)
+{
}
-CLDeviceContext::~CLDeviceContext() {
+CLDeviceContext::~CLDeviceContext()
+{
if (cl_command_queue_) {
clReleaseCommandQueue(cl_command_queue_);
}
@@ -133,8 +126,9 @@ CLDeviceContext::~CLDeviceContext() {
}
}
-bool CLDeviceContext::HAS_CL_VERSION_1_1() {
-#ifdef OPENSUBDIV_HAS_CLEW
+bool CLDeviceContext::HAS_CL_VERSION_1_1()
+{
+# ifdef OPENSUBDIV_HAS_CLEW
static bool clew_initialized = false;
static bool clew_load_success;
if (!clew_initialized) {
@@ -145,55 +139,53 @@ bool CLDeviceContext::HAS_CL_VERSION_1_1() {
}
}
return clew_load_success;
-#endif
+# endif
return true;
}
-bool CLDeviceContext::Initialize() {
-#ifdef OPENSUBDIV_HAS_CLEW
+bool CLDeviceContext::Initialize()
+{
+# ifdef OPENSUBDIV_HAS_CLEW
if (!clGetPlatformIDs) {
error("Error clGetPlatformIDs function not bound.\n");
return false;
}
-#endif
+# endif
cl_int cl_error_number;
cl_platform_id cp_platform = findPlatform();
-#if defined(_WIN32)
- cl_context_properties props[] = {
- CL_GL_CONTEXT_KHR,
- (cl_context_properties)wglGetCurrentContext(),
- CL_WGL_HDC_KHR,
- (cl_context_properties)wglGetCurrentDC(),
- CL_CONTEXT_PLATFORM,
- (cl_context_properties)cp_platform,
- 0};
-#elif defined(__APPLE__)
+# if defined(_WIN32)
+ cl_context_properties props[] = {CL_GL_CONTEXT_KHR,
+ (cl_context_properties)wglGetCurrentContext(),
+ CL_WGL_HDC_KHR,
+ (cl_context_properties)wglGetCurrentDC(),
+ CL_CONTEXT_PLATFORM,
+ (cl_context_properties)cp_platform,
+ 0};
+# elif defined(__APPLE__)
CGLContextObj kCGLContext = CGLGetCurrentContext();
CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext);
- cl_context_properties props[] = {CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
- (cl_context_properties)kCGLShareGroup,
- 0};
-#else
cl_context_properties props[] = {
- CL_GL_CONTEXT_KHR,
- (cl_context_properties)glXGetCurrentContext(),
- CL_GLX_DISPLAY_KHR,
- (cl_context_properties)glXGetCurrentDisplay(),
- CL_CONTEXT_PLATFORM,
- (cl_context_properties)cp_platform,
- 0};
-#endif
+ CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0};
+# else
+ cl_context_properties props[] = {CL_GL_CONTEXT_KHR,
+ (cl_context_properties)glXGetCurrentContext(),
+ CL_GLX_DISPLAY_KHR,
+ (cl_context_properties)glXGetCurrentDisplay(),
+ CL_CONTEXT_PLATFORM,
+ (cl_context_properties)cp_platform,
+ 0};
+# endif
-#if defined(__APPLE__)
- _clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL,
- &cl_error_number);
+# if defined(__APPLE__)
+ _clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL, &cl_error_number);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clCreateContext\n", cl_error_number);
return false;
}
size_t devices_size = 0;
- clGetGLContextInfoAPPLE(_clContext, kCGLContext,
+ clGetGLContextInfoAPPLE(_clContext,
+ kCGLContext,
CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
0,
NULL,
@@ -204,13 +196,14 @@ bool CLDeviceContext::Initialize() {
return false;
}
vector<cl_device_id> cl_devices(num_devices);
- clGetGLContextInfoAPPLE(_clContext, kCGLContext,
+ clGetGLContextInfoAPPLE(_clContext,
+ kCGLContext,
CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
num_devices * sizeof(cl_device_id),
&cl_devices[0],
NULL);
int cl_device_used = 0;
-#else // not __APPLE__
+# else // not __APPLE__
// Get the number of GPU devices available to the platform.
cl_uint num_devices = 0;
clGetDeviceIDs(cp_platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices);
@@ -220,33 +213,22 @@ bool CLDeviceContext::Initialize() {
}
// Create the device list.
vector<cl_device_id> cl_devices(num_devices);
- clGetDeviceIDs(cp_platform,
- CL_DEVICE_TYPE_GPU,
- num_devices,
- &cl_devices[0],
- NULL);
- const char* extension = "cl_khr_gl_sharing";
- int cl_device_used = findExtensionSupportedDevice(&cl_devices[0],
- num_devices,
- extension);
+ clGetDeviceIDs(cp_platform, CL_DEVICE_TYPE_GPU, num_devices, &cl_devices[0], NULL);
+ const char *extension = "cl_khr_gl_sharing";
+ int cl_device_used = findExtensionSupportedDevice(&cl_devices[0], num_devices, extension);
if (cl_device_used < 0) {
error("No device found that supports CL/GL context sharing\n");
return false;
}
- cl_context_ = clCreateContext(props,
- 1,
- &cl_devices[cl_device_used],
- NULL, NULL,
- &cl_error_number);
-#endif // not __APPLE__
+ cl_context_ = clCreateContext(
+ props, 1, &cl_devices[cl_device_used], NULL, NULL, &cl_error_number);
+# endif // not __APPLE__
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clCreateContext\n", cl_error_number);
return false;
}
- cl_command_queue_ = clCreateCommandQueue(cl_context_,
- cl_devices[cl_device_used],
- 0,
- &cl_error_number);
+ cl_command_queue_ = clCreateCommandQueue(
+ cl_context_, cl_devices[cl_device_used], 0, &cl_error_number);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clCreateCommandQueue\n", cl_error_number);
return false;
@@ -254,15 +236,18 @@ bool CLDeviceContext::Initialize() {
return true;
}
-bool CLDeviceContext::IsInitialized() const {
+bool CLDeviceContext::IsInitialized() const
+{
return (cl_context_ != NULL);
}
-cl_context CLDeviceContext::GetContext() const {
+cl_context CLDeviceContext::GetContext() const
+{
return cl_context_;
}
-cl_command_queue CLDeviceContext::GetCommandQueue() const {
+cl_command_queue CLDeviceContext::GetCommandQueue() const
+{
return cl_command_queue_;
}
diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_opencl.h b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.h
index bc751cb6954..6baf0774319 100644
--- a/intern/opensubdiv/internal/opensubdiv_device_context_opencl.h
+++ b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.h
@@ -26,7 +26,7 @@
#define OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_
#ifdef OPENSUBDIV_HAS_OPENCL
-#include <opensubdiv/osd/opencl.h>
+# include <opensubdiv/osd/opencl.h>
class CLDeviceContext {
public:
diff --git a/intern/opensubdiv/internal/opensubdiv_edge_map.h b/intern/opensubdiv/internal/opensubdiv_edge_map.h
index 8825f663c15..661b8a10eda 100644
--- a/intern/opensubdiv/internal/opensubdiv_edge_map.h
+++ b/intern/opensubdiv/internal/opensubdiv_edge_map.h
@@ -31,7 +31,7 @@ class EdgeKey {
inline EdgeKey(int v1, int v2);
inline size_t hash() const;
- inline bool operator==(const EdgeKey& other) const;
+ inline bool operator==(const EdgeKey &other) const;
// These indices are guaranteed to be so v1 < v2.
int v1;
@@ -39,8 +39,7 @@ class EdgeKey {
};
// Map from an edge defined by its verticies index to a custom tag value.
-template<typename T>
-class EdgeTagMap {
+template<typename T> class EdgeTagMap {
public:
typedef EdgeKey key_type;
typedef T value_type;
@@ -49,16 +48,16 @@ class EdgeTagMap {
// Modifiers.
inline void clear();
- inline void insert(const key_type& key, const value_type& value);
- inline void insert(int v1, int v2, const value_type& value);
+ inline void insert(const key_type &key, const value_type &value);
+ inline void insert(int v1, int v2, const value_type &value);
// Lookup.
- value_type& at(const key_type& key);
- value_type& at(key_type&& key);
- value_type& at(int v1, int v2);
+ value_type &at(const key_type &key);
+ value_type &at(key_type &&key);
+ value_type &at(int v1, int v2);
- value_type& operator[](const key_type& key);
- value_type& operator[](key_type&& key);
+ value_type &operator[](const key_type &key);
+ value_type &operator[](key_type &&key);
protected:
unordered_map<key_type, value_type> edge_tags_;
@@ -69,77 +68,79 @@ class EdgeTagMap {
// EdgeKey.
-EdgeKey::EdgeKey()
- : v1(-1),
- v2(-1) {
+EdgeKey::EdgeKey() : v1(-1), v2(-1)
+{
}
-EdgeKey::EdgeKey(int v1, int v2) {
+EdgeKey::EdgeKey(int v1, int v2)
+{
assert(v1 >= 0);
assert(v2 >= 0);
assert(v1 != v2);
if (v1 < v2) {
this->v1 = v1;
this->v2 = v2;
- } else {
+ }
+ else {
this->v1 = v2;
this->v2 = v1;
}
}
-size_t EdgeKey::hash() const {
+size_t EdgeKey::hash() const
+{
return (static_cast<uint64_t>(v1) << 32) | v2;
}
-bool EdgeKey::operator==(const EdgeKey& other) const {
- return v1 == other.v1 &&
- v2 == other.v2;
+bool EdgeKey::operator==(const EdgeKey &other) const
+{
+ return v1 == other.v1 && v2 == other.v2;
}
// EdgeTagMap.
-template<typename T>
-EdgeTagMap<T>::EdgeTagMap() {
+template<typename T> EdgeTagMap<T>::EdgeTagMap()
+{
}
-template<typename T>
-void EdgeTagMap<T>::clear() {
+template<typename T> void EdgeTagMap<T>::clear()
+{
edge_tags_.clear();
}
-template<typename T>
-void EdgeTagMap<T>::insert(const key_type& key, const value_type& value) {
+template<typename T> void EdgeTagMap<T>::insert(const key_type &key, const value_type &value)
+{
edge_tags_.insert(make_pair(key, value));
}
-template<typename T>
-void EdgeTagMap<T>::insert(int v1, int v2, const value_type& value) {
+template<typename T> void EdgeTagMap<T>::insert(int v1, int v2, const value_type &value)
+{
insert(EdgeKey(v1, v2), value);
}
-template<typename T>
-typename EdgeTagMap<T>::value_type& EdgeTagMap<T>::at(const key_type& key) {
+template<typename T> typename EdgeTagMap<T>::value_type &EdgeTagMap<T>::at(const key_type &key)
+{
return edge_tags_.at[key];
}
-template<typename T>
-typename EdgeTagMap<T>::value_type& EdgeTagMap<T>::at(key_type&& key) {
+template<typename T> typename EdgeTagMap<T>::value_type &EdgeTagMap<T>::at(key_type &&key)
+{
return edge_tags_.at[key];
}
-template<typename T>
-typename EdgeTagMap<T>::value_type& EdgeTagMap<T>::at(int v1, int v2) {
+template<typename T> typename EdgeTagMap<T>::value_type &EdgeTagMap<T>::at(int v1, int v2)
+{
return edge_tags_.at(EdgeKey(v1, v2));
}
template<typename T>
-typename EdgeTagMap<T>::value_type& EdgeTagMap<T>::operator[](
- const key_type& key) {
+typename EdgeTagMap<T>::value_type &EdgeTagMap<T>::operator[](const key_type &key)
+{
return edge_tags_[key];
}
-template<typename T>
-typename EdgeTagMap<T>::value_type& EdgeTagMap<T>::operator[](key_type&& key) {
+template<typename T> typename EdgeTagMap<T>::value_type &EdgeTagMap<T>::operator[](key_type &&key)
+{
return edge_tags_[key];
}
@@ -147,9 +148,9 @@ typename EdgeTagMap<T>::value_type& EdgeTagMap<T>::operator[](key_type&& key) {
namespace std {
-template <>
-struct hash<opensubdiv_capi::EdgeKey> {
- std::size_t operator()(const opensubdiv_capi::EdgeKey& key) const {
+template<> struct hash<opensubdiv_capi::EdgeKey> {
+ std::size_t operator()(const opensubdiv_capi::EdgeKey &key) const
+ {
return key.hash();
}
};
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator.cc b/intern/opensubdiv/internal/opensubdiv_evaluator.cc
index 49b8626448b..2500691885c 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator.cc
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator.cc
@@ -25,108 +25,105 @@
namespace {
-void setCoarsePositions(OpenSubdiv_Evaluator* evaluator,
- const float* positions,
- const int start_vertex_index, const int num_vertices) {
- evaluator->internal->eval_output->setCoarsePositions(positions,
- start_vertex_index,
- num_vertices);
+void setCoarsePositions(OpenSubdiv_Evaluator *evaluator,
+ const float *positions,
+ const int start_vertex_index,
+ const int num_vertices)
+{
+ evaluator->internal->eval_output->setCoarsePositions(
+ positions, start_vertex_index, num_vertices);
}
-void setVaryingData(OpenSubdiv_Evaluator* evaluator,
- const float* varying_data,
- const int start_vertex_index, const int num_vertices) {
- evaluator->internal->eval_output->setVaryingData(varying_data,
- start_vertex_index,
- num_vertices);
+void setVaryingData(OpenSubdiv_Evaluator *evaluator,
+ const float *varying_data,
+ const int start_vertex_index,
+ const int num_vertices)
+{
+ evaluator->internal->eval_output->setVaryingData(varying_data, start_vertex_index, num_vertices);
}
-void setFaceVaryingData(OpenSubdiv_Evaluator* evaluator,
+void setFaceVaryingData(OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
- const float* face_varying_data,
- const int start_vertex_index, const int num_vertices) {
- evaluator->internal->eval_output->setFaceVaryingData(face_varying_channel,
- face_varying_data,
- start_vertex_index,
- num_vertices);
+ const float *face_varying_data,
+ const int start_vertex_index,
+ const int num_vertices)
+{
+ evaluator->internal->eval_output->setFaceVaryingData(
+ face_varying_channel, face_varying_data, start_vertex_index, num_vertices);
}
-void setCoarsePositionsFromBuffer(OpenSubdiv_Evaluator* evaluator,
- const void* buffer,
+void setCoarsePositionsFromBuffer(OpenSubdiv_Evaluator *evaluator,
+ const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
- const int num_vertices) {
+ const int num_vertices)
+{
evaluator->internal->eval_output->setCoarsePositionsFromBuffer(
- buffer,
- start_offset,
- stride,
- start_vertex_index,
- num_vertices);
+ buffer, start_offset, stride, start_vertex_index, num_vertices);
}
-void setVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator,
- const void* buffer,
+void setVaryingDataFromBuffer(OpenSubdiv_Evaluator *evaluator,
+ const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
- const int num_vertices) {
+ const int num_vertices)
+{
evaluator->internal->eval_output->setVaryingDataFromBuffer(
- buffer,
- start_offset,
- stride,
- start_vertex_index,
- num_vertices);
+ buffer, start_offset, stride, start_vertex_index, num_vertices);
}
-void setFaceVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator,
+void setFaceVaryingDataFromBuffer(OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
- const void* buffer,
+ const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
- const int num_vertices) {
+ const int num_vertices)
+{
evaluator->internal->eval_output->setFaceVaryingDataFromBuffer(
- face_varying_channel,
- buffer,
- start_offset,
- stride,
- start_vertex_index,
- num_vertices);
+ face_varying_channel, buffer, start_offset, stride, start_vertex_index, num_vertices);
}
-void refine(OpenSubdiv_Evaluator* evaluator) {
+void refine(OpenSubdiv_Evaluator *evaluator)
+{
evaluator->internal->eval_output->refine();
}
-void evaluateLimit(OpenSubdiv_Evaluator* evaluator,
+void evaluateLimit(OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
- const float face_u, const float face_v,
- float P[3], float dPdu[3], float dPdv[3]) {
- evaluator->internal->eval_output->evaluateLimit(ptex_face_index,
- face_u, face_v,
- P, dPdu, dPdv);
+ const float face_u,
+ const float face_v,
+ float P[3],
+ float dPdu[3],
+ float dPdv[3])
+{
+ evaluator->internal->eval_output->evaluateLimit(ptex_face_index, face_u, face_v, P, dPdu, dPdv);
}
-void evaluateVarying(OpenSubdiv_Evaluator* evaluator,
+void evaluateVarying(OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
- float face_u, float face_v,
- float varying[3]) {
- evaluator->internal->eval_output->evaluateVarying(ptex_face_index,
- face_u, face_v,
- varying);
+ float face_u,
+ float face_v,
+ float varying[3])
+{
+ evaluator->internal->eval_output->evaluateVarying(ptex_face_index, face_u, face_v, varying);
}
-void evaluateFaceVarying(OpenSubdiv_Evaluator* evaluator,
+void evaluateFaceVarying(OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
const int ptex_face_index,
- float face_u, float face_v,
- float face_varying[2]) {
+ float face_u,
+ float face_v,
+ float face_varying[2])
+{
evaluator->internal->eval_output->evaluateFaceVarying(
face_varying_channel, ptex_face_index, face_u, face_v, face_varying);
}
-void assignFunctionPointers(OpenSubdiv_Evaluator* evaluator) {
+void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
+{
evaluator->setCoarsePositions = setCoarsePositions;
evaluator->setVaryingData = setVaryingData;
evaluator->setFaceVaryingData = setFaceVaryingData;
@@ -144,15 +141,17 @@ void assignFunctionPointers(OpenSubdiv_Evaluator* evaluator) {
} // namespace
-OpenSubdiv_Evaluator* openSubdiv_createEvaluatorFromTopologyRefiner(
- OpenSubdiv_TopologyRefiner* topology_refiner) {
- OpenSubdiv_Evaluator* evaluator = OBJECT_GUARDED_NEW(OpenSubdiv_Evaluator);
+OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
+ OpenSubdiv_TopologyRefiner *topology_refiner)
+{
+ OpenSubdiv_Evaluator *evaluator = OBJECT_GUARDED_NEW(OpenSubdiv_Evaluator);
assignFunctionPointers(evaluator);
evaluator->internal = openSubdiv_createEvaluatorInternal(topology_refiner);
return evaluator;
}
-void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator* evaluator) {
+void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator *evaluator)
+{
openSubdiv_deleteEvaluatorInternal(evaluator->internal);
OBJECT_GUARDED_DELETE(evaluator, OpenSubdiv_Evaluator);
}
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
index 9a8729ccda4..fa45c0119ec 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
@@ -42,17 +42,17 @@
#include "internal/opensubdiv_util.h"
#include "opensubdiv_topology_refiner_capi.h"
-using OpenSubdiv::Osd::BufferDescriptor;
-using OpenSubdiv::Osd::CpuEvaluator;
-using OpenSubdiv::Osd::CpuPatchTable;
-using OpenSubdiv::Osd::CpuVertexBuffer;
-using OpenSubdiv::Osd::PatchCoord;
using OpenSubdiv::Far::PatchMap;
using OpenSubdiv::Far::PatchTable;
using OpenSubdiv::Far::PatchTableFactory;
using OpenSubdiv::Far::StencilTable;
using OpenSubdiv::Far::StencilTableFactory;
using OpenSubdiv::Far::TopologyRefiner;
+using OpenSubdiv::Osd::BufferDescriptor;
+using OpenSubdiv::Osd::CpuEvaluator;
+using OpenSubdiv::Osd::CpuPatchTable;
+using OpenSubdiv::Osd::CpuVertexBuffer;
+using OpenSubdiv::Osd::PatchCoord;
// TODO(sergey): Remove after official requirement bump for OSD version.
#if OPENSUBDIV_VERSION_NUMBER >= 30200
@@ -70,23 +70,27 @@ namespace {
// supported.
class PatchCoordBuffer : public vector<PatchCoord> {
public:
- static PatchCoordBuffer* Create(int size) {
- PatchCoordBuffer* buffer = new PatchCoordBuffer();
+ static PatchCoordBuffer *Create(int size)
+ {
+ PatchCoordBuffer *buffer = new PatchCoordBuffer();
buffer->resize(size);
return buffer;
}
- PatchCoord* BindCpuBuffer() {
- return reinterpret_cast<PatchCoord*>(&(*this)[0]);
+ PatchCoord *BindCpuBuffer()
+ {
+ return reinterpret_cast<PatchCoord *>(&(*this)[0]);
}
- int GetNumVertices() {
+ int GetNumVertices()
+ {
return size();
}
- void UpdateData(const PatchCoord* patch_coords, int num_patch_coords) {
+ void UpdateData(const PatchCoord *patch_coords, int num_patch_coords)
+ {
memcpy(&(*this)[0],
- reinterpret_cast<const void*>(patch_coords),
+ reinterpret_cast<const void *>(patch_coords),
sizeof(PatchCoord) * num_patch_coords);
}
};
@@ -95,26 +99,31 @@ class PatchCoordBuffer : public vector<PatchCoord> {
// coordinates to the CPU evaluator. Other evaluators are not supported.
class SinglePatchCoordBuffer {
public:
- static SinglePatchCoordBuffer* Create() {
+ static SinglePatchCoordBuffer *Create()
+ {
return new SinglePatchCoordBuffer();
}
- SinglePatchCoordBuffer() {
+ SinglePatchCoordBuffer()
+ {
}
- explicit SinglePatchCoordBuffer(const PatchCoord &patch_coord)
- : patch_coord_(patch_coord) {
+ explicit SinglePatchCoordBuffer(const PatchCoord &patch_coord) : patch_coord_(patch_coord)
+ {
}
- PatchCoord* BindCpuBuffer() {
+ PatchCoord *BindCpuBuffer()
+ {
return &patch_coord_;
}
- int GetNumVertices() {
+ int GetNumVertices()
+ {
return 1;
}
- void UpdateData(const PatchCoord &patch_coord) {
+ void UpdateData(const PatchCoord &patch_coord)
+ {
patch_coord_ = patch_coord;
}
@@ -126,20 +135,22 @@ class SinglePatchCoordBuffer {
// and better to be allocated in stack rather than in heap.
//
// TODO(sergey): Check if bare arrays could be used by CPU evaluator.
-template <int element_size, int num_vertices>
-class StackAllocatedBuffer {
+template<int element_size, int num_vertices> class StackAllocatedBuffer {
public:
- static PatchCoordBuffer* Create(int /*size*/) {
+ static PatchCoordBuffer *Create(int /*size*/)
+ {
// TODO(sergey): Validate that requested size is smaller than static
// stack memory size.
return new StackAllocatedBuffer<element_size, num_vertices>();
}
- float* BindCpuBuffer() {
+ float *BindCpuBuffer()
+ {
return &data_[0];
}
- int GetNumVertices() {
+ int GetNumVertices()
+ {
return num_vertices;
}
@@ -148,87 +159,82 @@ class StackAllocatedBuffer {
float data_[element_size * num_vertices];
};
-template <typename EVAL_VERTEX_BUFFER,
- typename STENCIL_TABLE,
- typename PATCH_TABLE,
- typename EVALUATOR,
- typename DEVICE_CONTEXT = void>
+template<typename EVAL_VERTEX_BUFFER,
+ typename STENCIL_TABLE,
+ typename PATCH_TABLE,
+ typename EVALUATOR,
+ typename DEVICE_CONTEXT = void>
class FaceVaryingVolatileEval {
public:
typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
FaceVaryingVolatileEval(int face_varying_channel,
- const StencilTable* face_varying_stencils,
+ const StencilTable *face_varying_stencils,
int face_varying_width,
- PATCH_TABLE* patch_table,
- EvaluatorCache* evaluator_cache = NULL,
- DEVICE_CONTEXT* device_context = NULL)
+ PATCH_TABLE *patch_table,
+ EvaluatorCache *evaluator_cache = NULL,
+ DEVICE_CONTEXT *device_context = NULL)
: face_varying_channel_(face_varying_channel),
src_face_varying_desc_(0, face_varying_width, face_varying_width),
patch_table_(patch_table),
evaluator_cache_(evaluator_cache),
- device_context_(device_context) {
+ device_context_(device_context)
+ {
using OpenSubdiv::Osd::convertToCompatibleStencilTable;
- num_coarse_face_varying_vertices_ =
- face_varying_stencils->GetNumControlVertices();
- const int num_total_face_varying_vertices =
- face_varying_stencils->GetNumControlVertices() +
- face_varying_stencils->GetNumStencils();
- src_face_varying_data_ =
- EVAL_VERTEX_BUFFER::Create(2,
- num_total_face_varying_vertices,
- device_context);
- face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(
- face_varying_stencils, device_context_);
- }
-
- ~FaceVaryingVolatileEval() {
+ num_coarse_face_varying_vertices_ = face_varying_stencils->GetNumControlVertices();
+ const int num_total_face_varying_vertices = face_varying_stencils->GetNumControlVertices() +
+ face_varying_stencils->GetNumStencils();
+ src_face_varying_data_ = EVAL_VERTEX_BUFFER::Create(
+ 2, num_total_face_varying_vertices, device_context);
+ face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(face_varying_stencils,
+ device_context_);
+ }
+
+ ~FaceVaryingVolatileEval()
+ {
delete src_face_varying_data_;
delete face_varying_stencils_;
}
- void updateData(const float* src, int start_vertex, int num_vertices) {
- src_face_varying_data_->UpdateData(src,
- start_vertex,
- num_vertices,
- device_context_);
+ void updateData(const float *src, int start_vertex, int num_vertices)
+ {
+ src_face_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
}
- void refine() {
+ void refine()
+ {
BufferDescriptor dst_face_varying_desc = src_face_varying_desc_;
dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ *
src_face_varying_desc_.stride;
- const EVALUATOR* eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
- evaluator_cache_,
- src_face_varying_desc_,
- dst_face_varying_desc,
- device_context_);
- EVALUATOR::EvalStencils(src_face_varying_data_, src_face_varying_desc_,
- src_face_varying_data_, dst_face_varying_desc,
+ const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+ evaluator_cache_, src_face_varying_desc_, dst_face_varying_desc, device_context_);
+ EVALUATOR::EvalStencils(src_face_varying_data_,
+ src_face_varying_desc_,
+ src_face_varying_data_,
+ dst_face_varying_desc,
face_varying_stencils_,
eval_instance,
device_context_);
}
- void evalPatch(const PatchCoord& patch_coord, float face_varying[2]) {
+ void evalPatch(const PatchCoord &patch_coord, float face_varying[2])
+ {
StackAllocatedBuffer<2, 1> face_varying_data;
BufferDescriptor face_varying_desc(0, 2, 2);
SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- const EVALUATOR* eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_face_varying_desc_,
- face_varying_desc,
- device_context_);
- EVALUATOR::EvalPatchesFaceVarying(
- src_face_varying_data_, src_face_varying_desc_,
- &face_varying_data, face_varying_desc,
- patch_coord_buffer.GetNumVertices(),
- &patch_coord_buffer,
- patch_table_,
- face_varying_channel_,
- eval_instance,
- device_context_);
- const float* refined_face_varying = face_varying_data.BindCpuBuffer();
+ const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+ evaluator_cache_, src_face_varying_desc_, face_varying_desc, device_context_);
+ EVALUATOR::EvalPatchesFaceVarying(src_face_varying_data_,
+ src_face_varying_desc_,
+ &face_varying_data,
+ face_varying_desc,
+ patch_coord_buffer.GetNumVertices(),
+ &patch_coord_buffer,
+ patch_table_,
+ face_varying_channel_,
+ eval_instance,
+ device_context_);
+ const float *refined_face_varying = face_varying_data.BindCpuBuffer();
memcpy(face_varying, refined_face_varying, sizeof(float) * 2);
}
@@ -238,14 +244,14 @@ class FaceVaryingVolatileEval {
BufferDescriptor src_face_varying_desc_;
int num_coarse_face_varying_vertices_;
- EVAL_VERTEX_BUFFER* src_face_varying_data_;
- const STENCIL_TABLE* face_varying_stencils_;
+ EVAL_VERTEX_BUFFER *src_face_varying_data_;
+ const STENCIL_TABLE *face_varying_stencils_;
// NOTE: We reference this, do not own it.
- PATCH_TABLE* patch_table_;
+ PATCH_TABLE *patch_table_;
- EvaluatorCache* evaluator_cache_;
- DEVICE_CONTEXT* device_context_;
+ EvaluatorCache *evaluator_cache_;
+ DEVICE_CONTEXT *device_context_;
};
// Volatile evaluator which can be used from threads.
@@ -254,12 +260,12 @@ class FaceVaryingVolatileEval {
// TODO(sergey): Make it possible to evaluate multiple face varying layers.
// (or maybe, it's cheap to create new evaluator for existing
// topology to evaluate all needed face varying layers?)
-template <typename SRC_VERTEX_BUFFER,
- typename EVAL_VERTEX_BUFFER,
- typename STENCIL_TABLE,
- typename PATCH_TABLE,
- typename EVALUATOR,
- typename DEVICE_CONTEXT = void>
+template<typename SRC_VERTEX_BUFFER,
+ typename EVAL_VERTEX_BUFFER,
+ typename STENCIL_TABLE,
+ typename PATCH_TABLE,
+ typename EVALUATOR,
+ typename DEVICE_CONTEXT = void>
class VolatileEvalOutput {
public:
typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
@@ -267,146 +273,141 @@ class VolatileEvalOutput {
STENCIL_TABLE,
PATCH_TABLE,
EVALUATOR,
- DEVICE_CONTEXT> FaceVaryingEval;
-
- VolatileEvalOutput(
- const StencilTable* vertex_stencils,
- const StencilTable* varying_stencils,
- const vector<const StencilTable*>& all_face_varying_stencils,
- const int face_varying_width,
- const PatchTable* patch_table,
- EvaluatorCache* evaluator_cache = NULL,
- DEVICE_CONTEXT* device_context = NULL)
+ DEVICE_CONTEXT>
+ FaceVaryingEval;
+
+ VolatileEvalOutput(const StencilTable *vertex_stencils,
+ const StencilTable *varying_stencils,
+ const vector<const StencilTable *> &all_face_varying_stencils,
+ const int face_varying_width,
+ const PatchTable *patch_table,
+ EvaluatorCache *evaluator_cache = NULL,
+ DEVICE_CONTEXT *device_context = NULL)
: src_desc_(0, 3, 3),
src_varying_desc_(0, 3, 3),
face_varying_width_(face_varying_width),
evaluator_cache_(evaluator_cache),
- device_context_(device_context) {
+ device_context_(device_context)
+ {
// Total number of vertices = coarse points + refined points + local points.
int num_total_vertices = vertex_stencils->GetNumControlVertices() +
vertex_stencils->GetNumStencils();
num_coarse_vertices_ = vertex_stencils->GetNumControlVertices();
using OpenSubdiv::Osd::convertToCompatibleStencilTable;
- src_data_ =
- SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
- src_varying_data_ =
- SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
+ src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
+ src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
patch_table_ = PATCH_TABLE::Create(patch_table, device_context_);
patch_coords_ = NULL;
- vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(
- vertex_stencils, device_context_);
- varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(
- varying_stencils, device_context_);
+ vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
+ device_context_);
+ varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
+ device_context_);
// Create evaluators for every face varying channel.
face_varying_evaluators.reserve(all_face_varying_stencils.size());
int face_varying_channel = 0;
- foreach (const StencilTable* face_varying_stencils,
- all_face_varying_stencils) {
- face_varying_evaluators.push_back(
- new FaceVaryingEval(face_varying_channel,
- face_varying_stencils,
- face_varying_width,
- patch_table_,
- evaluator_cache_,
- device_context_));
+ foreach (const StencilTable *face_varying_stencils, all_face_varying_stencils) {
+ face_varying_evaluators.push_back(new FaceVaryingEval(face_varying_channel,
+ face_varying_stencils,
+ face_varying_width,
+ patch_table_,
+ evaluator_cache_,
+ device_context_));
++face_varying_channel;
}
}
- ~VolatileEvalOutput() {
+ ~VolatileEvalOutput()
+ {
delete src_data_;
delete src_varying_data_;
delete patch_table_;
delete vertex_stencils_;
delete varying_stencils_;
- foreach (FaceVaryingEval* face_varying_evaluator, face_varying_evaluators) {
+ foreach (FaceVaryingEval *face_varying_evaluator, face_varying_evaluators) {
delete face_varying_evaluator;
}
}
// TODO(sergey): Implement binding API.
- void updateData(const float* src, int start_vertex, int num_vertices) {
+ void updateData(const float *src, int start_vertex, int num_vertices)
+ {
src_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
}
- void updateVaryingData(const float* src, int start_vertex, int num_vertices) {
- src_varying_data_->UpdateData(src,
- start_vertex,
- num_vertices,
- device_context_);
+ void updateVaryingData(const float *src, int start_vertex, int num_vertices)
+ {
+ src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
}
void updateFaceVaryingData(const int face_varying_channel,
- const float* src,
+ const float *src,
int start_vertex,
- int num_vertices) {
+ int num_vertices)
+ {
assert(face_varying_channel >= 0);
assert(face_varying_channel < face_varying_evaluators.size());
- face_varying_evaluators[face_varying_channel]->updateData(
- src, start_vertex, num_vertices);
+ face_varying_evaluators[face_varying_channel]->updateData(src, start_vertex, num_vertices);
}
- bool hasVaryingData() const {
+ bool hasVaryingData() const
+ {
// return varying_stencils_ != NULL;
// TODO(sergey): Check this based on actual topology.
return false;
}
- bool hasFaceVaryingData() const {
+ bool hasFaceVaryingData() const
+ {
return face_varying_evaluators.size() != 0;
}
- void refine() {
+ void refine()
+ {
// Evaluate vertex positions.
BufferDescriptor dst_desc = src_desc_;
dst_desc.offset += num_coarse_vertices_ * src_desc_.stride;
- const EVALUATOR* eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_desc_,
- dst_desc,
- device_context_);
- EVALUATOR::EvalStencils(src_data_, src_desc_,
- src_data_, dst_desc,
+ const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+ evaluator_cache_, src_desc_, dst_desc, device_context_);
+ EVALUATOR::EvalStencils(src_data_,
+ src_desc_,
+ src_data_,
+ dst_desc,
vertex_stencils_,
eval_instance,
device_context_);
// Evaluate varying data.
if (hasVaryingData()) {
BufferDescriptor dst_varying_desc = src_varying_desc_;
- dst_varying_desc.offset +=
- num_coarse_vertices_ * src_varying_desc_.stride;
+ dst_varying_desc.offset += num_coarse_vertices_ * src_varying_desc_.stride;
eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
- evaluator_cache_,
- src_varying_desc_,
- dst_varying_desc,
- device_context_);
- EVALUATOR::EvalStencils(src_varying_data_, src_varying_desc_,
- src_varying_data_, dst_varying_desc,
+ evaluator_cache_, src_varying_desc_, dst_varying_desc, device_context_);
+ EVALUATOR::EvalStencils(src_varying_data_,
+ src_varying_desc_,
+ src_varying_data_,
+ dst_varying_desc,
varying_stencils_,
- eval_instance, device_context_);
+ eval_instance,
+ device_context_);
}
// Evaluate face-varying data.
if (hasFaceVaryingData()) {
- foreach (FaceVaryingEval* face_varying_evaluator,
- face_varying_evaluators) {
+ foreach (FaceVaryingEval *face_varying_evaluator, face_varying_evaluators) {
face_varying_evaluator->refine();
}
}
}
- void evalPatchCoord(const PatchCoord& patch_coord, float P[3]) {
+ void evalPatchCoord(const PatchCoord &patch_coord, float P[3])
+ {
StackAllocatedBuffer<6, 1> vertex_data;
// TODO(sergey): Varying data is interleaved in vertex array, so need to
// adjust stride if there is a varying data.
// BufferDescriptor vertex_desc(0, 3, 6);
BufferDescriptor vertex_desc(0, 3, 3);
SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- const EVALUATOR* eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_desc_,
- vertex_desc,
- device_context_);
+ const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+ evaluator_cache_, src_desc_, vertex_desc, device_context_);
EVALUATOR::EvalPatches(src_data_,
src_desc_,
&vertex_data,
@@ -416,13 +417,15 @@ class VolatileEvalOutput {
patch_table_,
eval_instance,
device_context_);
- const float* refined_vertices = vertex_data.BindCpuBuffer();
+ const float *refined_vertices = vertex_data.BindCpuBuffer();
memcpy(P, refined_vertices, sizeof(float) * 3);
}
- void evalPatchesWithDerivatives(const PatchCoord& patch_coord,
+ void evalPatchesWithDerivatives(const PatchCoord &patch_coord,
float P[3],
- float dPdu[3], float dPdv[3]) {
+ float dPdu[3],
+ float dPdv[3])
+ {
StackAllocatedBuffer<6, 1> vertex_data, derivatives;
// TODO(sergey): Varying data is interleaved in vertex array, so need to
// adjust stride if there is a varying data.
@@ -430,25 +433,25 @@ class VolatileEvalOutput {
BufferDescriptor vertex_desc(0, 3, 3);
BufferDescriptor du_desc(0, 3, 6), dv_desc(3, 3, 6);
SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- const EVALUATOR* eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_desc_,
- vertex_desc,
- du_desc, dv_desc,
- device_context_);
- EVALUATOR::EvalPatches(src_data_, src_desc_,
- &vertex_data, vertex_desc,
- &derivatives, du_desc,
- &derivatives, dv_desc,
+ const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+ evaluator_cache_, src_desc_, vertex_desc, du_desc, dv_desc, device_context_);
+ EVALUATOR::EvalPatches(src_data_,
+ src_desc_,
+ &vertex_data,
+ vertex_desc,
+ &derivatives,
+ du_desc,
+ &derivatives,
+ dv_desc,
patch_coord_buffer.GetNumVertices(),
&patch_coord_buffer,
patch_table_,
eval_instance,
device_context_);
- const float* refined_vertices = vertex_data.BindCpuBuffer();
+ const float *refined_vertices = vertex_data.BindCpuBuffer();
memcpy(P, refined_vertices, sizeof(float) * 3);
if (dPdu != NULL || dPdv != NULL) {
- const float* refined_derivatives = derivatives.BindCpuBuffer();
+ const float *refined_derivatives = derivatives.BindCpuBuffer();
if (dPdu != NULL) {
memcpy(dPdu, refined_derivatives, sizeof(float) * 3);
}
@@ -458,53 +461,53 @@ class VolatileEvalOutput {
}
}
- void evalPatchVarying(const PatchCoord& patch_coord, float varying[3]) {
+ void evalPatchVarying(const PatchCoord &patch_coord, float varying[3])
+ {
StackAllocatedBuffer<6, 1> varying_data;
BufferDescriptor varying_desc(3, 3, 6);
SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- const EVALUATOR* eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_varying_desc_,
- varying_desc,
- device_context_);
- EVALUATOR::EvalPatchesVarying(src_varying_data_, src_varying_desc_,
- &varying_data, varying_desc,
+ const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+ evaluator_cache_, src_varying_desc_, varying_desc, device_context_);
+ EVALUATOR::EvalPatchesVarying(src_varying_data_,
+ src_varying_desc_,
+ &varying_data,
+ varying_desc,
patch_coord_buffer.GetNumVertices(),
&patch_coord_buffer,
patch_table_,
eval_instance,
device_context_);
- const float* refined_varying = varying_data.BindCpuBuffer();
+ const float *refined_varying = varying_data.BindCpuBuffer();
memcpy(varying, refined_varying, sizeof(float) * 3);
}
void evalPatchFaceVarying(const int face_varying_channel,
- const PatchCoord& patch_coord,
- float face_varying[2]) {
+ const PatchCoord &patch_coord,
+ float face_varying[2])
+ {
assert(face_varying_channel >= 0);
assert(face_varying_channel < face_varying_evaluators.size());
- face_varying_evaluators[face_varying_channel]->evalPatch(
- patch_coord, face_varying);
+ face_varying_evaluators[face_varying_channel]->evalPatch(patch_coord, face_varying);
}
private:
- SRC_VERTEX_BUFFER* src_data_;
- SRC_VERTEX_BUFFER* src_varying_data_;
- PatchCoordBuffer* patch_coords_;
- PATCH_TABLE* patch_table_;
+ SRC_VERTEX_BUFFER *src_data_;
+ SRC_VERTEX_BUFFER *src_varying_data_;
+ PatchCoordBuffer *patch_coords_;
+ PATCH_TABLE *patch_table_;
BufferDescriptor src_desc_;
BufferDescriptor src_varying_desc_;
int num_coarse_vertices_;
- const STENCIL_TABLE* vertex_stencils_;
- const STENCIL_TABLE* varying_stencils_;
+ const STENCIL_TABLE *vertex_stencils_;
+ const STENCIL_TABLE *varying_stencils_;
int face_varying_width_;
- vector<FaceVaryingEval*> face_varying_evaluators;
+ vector<FaceVaryingEval *> face_varying_evaluators;
- EvaluatorCache* evaluator_cache_;
- DEVICE_CONTEXT* device_context_;
+ EvaluatorCache *evaluator_cache_;
+ DEVICE_CONTEXT *device_context_;
};
} // namespace
@@ -517,12 +520,12 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
CpuPatchTable,
CpuEvaluator> {
public:
- CpuEvalOutput(const StencilTable* vertex_stencils,
- const StencilTable* varying_stencils,
- const vector<const StencilTable*>& all_face_varying_stencils,
+ CpuEvalOutput(const StencilTable *vertex_stencils,
+ const StencilTable *varying_stencils,
+ const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
- const PatchTable* patch_table,
- EvaluatorCache* evaluator_cache = NULL)
+ const PatchTable *patch_table,
+ EvaluatorCache *evaluator_cache = NULL)
: VolatileEvalOutput<CpuVertexBuffer,
CpuVertexBuffer,
StencilTable,
@@ -532,171 +535,179 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
all_face_varying_stencils,
face_varying_width,
patch_table,
- evaluator_cache) {
+ evaluator_cache)
+ {
}
};
////////////////////////////////////////////////////////////////////////////////
// Evaluator wrapper for anonymous API.
-CpuEvalOutputAPI::CpuEvalOutputAPI(CpuEvalOutput* implementation,
- OpenSubdiv::Far::PatchMap* patch_map)
- : implementation_(implementation),
- patch_map_(patch_map) {
+CpuEvalOutputAPI::CpuEvalOutputAPI(CpuEvalOutput *implementation,
+ OpenSubdiv::Far::PatchMap *patch_map)
+ : implementation_(implementation), patch_map_(patch_map)
+{
}
-CpuEvalOutputAPI::~CpuEvalOutputAPI() {
+CpuEvalOutputAPI::~CpuEvalOutputAPI()
+{
delete implementation_;
}
-void CpuEvalOutputAPI::setCoarsePositions(const float* positions,
+void CpuEvalOutputAPI::setCoarsePositions(const float *positions,
const int start_vertex_index,
- const int num_vertices) {
+ const int num_vertices)
+{
// TODO(sergey): Add sanity check on indices.
implementation_->updateData(positions, start_vertex_index, num_vertices);
}
-void CpuEvalOutputAPI::setVaryingData(const float* varying_data,
+void CpuEvalOutputAPI::setVaryingData(const float *varying_data,
const int start_vertex_index,
- const int num_vertices) {
+ const int num_vertices)
+{
// TODO(sergey): Add sanity check on indices.
- implementation_->updateVaryingData(varying_data,
- start_vertex_index,
- num_vertices);
+ implementation_->updateVaryingData(varying_data, start_vertex_index, num_vertices);
}
void CpuEvalOutputAPI::setFaceVaryingData(const int face_varying_channel,
- const float* face_varying_data,
+ const float *face_varying_data,
const int start_vertex_index,
- const int num_vertices) {
+ const int num_vertices)
+{
// TODO(sergey): Add sanity check on indices.
- implementation_->updateFaceVaryingData(face_varying_channel,
- face_varying_data,
- start_vertex_index,
- num_vertices);
+ implementation_->updateFaceVaryingData(
+ face_varying_channel, face_varying_data, start_vertex_index, num_vertices);
}
-void CpuEvalOutputAPI::setCoarsePositionsFromBuffer(
- const void* buffer,
- const int start_offset,
- const int stride,
- const int start_vertex_index,
- const int num_vertices) {
+void CpuEvalOutputAPI::setCoarsePositionsFromBuffer(const void *buffer,
+ const int start_offset,
+ const int stride,
+ const int start_vertex_index,
+ const int num_vertices)
+{
// TODO(sergey): Add sanity check on indices.
- const unsigned char* current_buffer = (unsigned char *)buffer;
+ const unsigned char *current_buffer = (unsigned char *)buffer;
current_buffer += start_offset;
for (int i = 0; i < num_vertices; ++i) {
const int current_vertex_index = start_vertex_index + i;
- implementation_->updateData(reinterpret_cast<const float*>(current_buffer),
- current_vertex_index, 1);
+ implementation_->updateData(
+ reinterpret_cast<const float *>(current_buffer), current_vertex_index, 1);
current_buffer += stride;
}
}
-void CpuEvalOutputAPI::setVaryingDataFromBuffer(
- const void* buffer,
- const int start_offset,
- const int stride,
- const int start_vertex_index,
- const int num_vertices) {
+void CpuEvalOutputAPI::setVaryingDataFromBuffer(const void *buffer,
+ const int start_offset,
+ const int stride,
+ const int start_vertex_index,
+ const int num_vertices)
+{
// TODO(sergey): Add sanity check on indices.
- const unsigned char* current_buffer = (unsigned char *)buffer;
+ const unsigned char *current_buffer = (unsigned char *)buffer;
current_buffer += start_offset;
for (int i = 0; i < num_vertices; ++i) {
const int current_vertex_index = start_vertex_index + i;
implementation_->updateVaryingData(
- reinterpret_cast<const float*>(current_buffer),
- current_vertex_index, 1);
+ reinterpret_cast<const float *>(current_buffer), current_vertex_index, 1);
current_buffer += stride;
}
}
-void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer(
- const int face_varying_channel,
- const void* buffer,
- const int start_offset,
- const int stride,
- const int start_vertex_index,
- const int num_vertices) {
+void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer(const int face_varying_channel,
+ const void *buffer,
+ const int start_offset,
+ const int stride,
+ const int start_vertex_index,
+ const int num_vertices)
+{
// TODO(sergey): Add sanity check on indices.
- const unsigned char* current_buffer = (unsigned char *)buffer;
+ const unsigned char *current_buffer = (unsigned char *)buffer;
current_buffer += start_offset;
for (int i = 0; i < num_vertices; ++i) {
const int current_vertex_index = start_vertex_index + i;
- implementation_->updateFaceVaryingData(
- face_varying_channel,
- reinterpret_cast<const float*>(current_buffer),
- current_vertex_index, 1);
+ implementation_->updateFaceVaryingData(face_varying_channel,
+ reinterpret_cast<const float *>(current_buffer),
+ current_vertex_index,
+ 1);
current_buffer += stride;
}
}
-void CpuEvalOutputAPI::refine() {
+void CpuEvalOutputAPI::refine()
+{
implementation_->refine();
}
void CpuEvalOutputAPI::evaluateLimit(const int ptex_face_index,
- float face_u, float face_v,
- float P[3], float dPdu[3], float dPdv[3]) {
+ float face_u,
+ float face_v,
+ float P[3],
+ float dPdu[3],
+ float dPdv[3])
+{
assert(face_u >= 0.0f);
assert(face_u <= 1.0f);
assert(face_v >= 0.0f);
assert(face_v <= 1.0f);
- const PatchTable::PatchHandle* handle =
- patch_map_->FindPatch(ptex_face_index, face_u, face_v);
+ const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
PatchCoord patch_coord(*handle, face_u, face_v);
if (dPdu != NULL || dPdv != NULL) {
implementation_->evalPatchesWithDerivatives(patch_coord, P, dPdu, dPdv);
- } else {
+ }
+ else {
implementation_->evalPatchCoord(patch_coord, P);
- }}
+ }
+}
void CpuEvalOutputAPI::evaluateVarying(const int ptex_face_index,
- float face_u, float face_v,
- float varying[3]) {
+ float face_u,
+ float face_v,
+ float varying[3])
+{
assert(face_u >= 0.0f);
assert(face_u <= 1.0f);
assert(face_v >= 0.0f);
assert(face_v <= 1.0f);
- const PatchTable::PatchHandle* handle =
- patch_map_->FindPatch(ptex_face_index, face_u, face_v);
+ const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
PatchCoord patch_coord(*handle, face_u, face_v);
implementation_->evalPatchVarying(patch_coord, varying);
}
void CpuEvalOutputAPI::evaluateFaceVarying(const int face_varying_channel,
const int ptex_face_index,
- float face_u, float face_v,
- float face_varying[2]) {
+ float face_u,
+ float face_v,
+ float face_varying[2])
+{
assert(face_u >= 0.0f);
assert(face_u <= 1.0f);
assert(face_v >= 0.0f);
assert(face_v <= 1.0f);
- const PatchTable::PatchHandle* handle =
- patch_map_->FindPatch(ptex_face_index, face_u, face_v);
+ const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
PatchCoord patch_coord(*handle, face_u, face_v);
- implementation_->evalPatchFaceVarying(
- face_varying_channel, patch_coord, face_varying);
+ implementation_->evalPatchFaceVarying(face_varying_channel, patch_coord, face_varying);
}
} // namespace opensubdiv_capi
OpenSubdiv_EvaluatorInternal::OpenSubdiv_EvaluatorInternal()
- : eval_output(NULL),
- patch_map(NULL),
- patch_table(NULL) {
+ : eval_output(NULL), patch_map(NULL), patch_table(NULL)
+{
}
-OpenSubdiv_EvaluatorInternal::~OpenSubdiv_EvaluatorInternal() {
+OpenSubdiv_EvaluatorInternal::~OpenSubdiv_EvaluatorInternal()
+{
delete eval_output;
delete patch_map;
delete patch_table;
}
-OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
- OpenSubdiv_TopologyRefiner* topology_refiner) {
+OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal(
+ OpenSubdiv_TopologyRefiner *topology_refiner)
+{
using opensubdiv_capi::vector;
- TopologyRefiner* refiner = topology_refiner->internal->osd_topology_refiner;
+ TopologyRefiner *refiner = topology_refiner->internal->osd_topology_refiner;
if (refiner == NULL) {
// Happens on bad topology.
return NULL;
@@ -718,7 +729,8 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
options.considerFVarChannels = has_face_varying_data;
options.useInfSharpPatch = use_inf_sharp_patch;
refiner->RefineAdaptive(options);
- } else {
+ }
+ else {
TopologyRefiner::UniformOptions options(level);
refiner->RefineUniform(options);
}
@@ -728,38 +740,31 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
// Vertex stencils.
StencilTableFactory::Options vertex_stencil_options;
vertex_stencil_options.generateOffsets = stencil_generate_offsets;
- vertex_stencil_options.generateIntermediateLevels =
- stencil_generate_intermediate_levels;
- const StencilTable* vertex_stencils =
- StencilTableFactory::Create(*refiner, vertex_stencil_options);
+ vertex_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
+ const StencilTable *vertex_stencils = StencilTableFactory::Create(*refiner,
+ vertex_stencil_options);
// Varying stencils.
//
// TODO(sergey): Seems currently varying stencils are always required in
// OpenSubdiv itself.
- const StencilTable* varying_stencils = NULL;
+ const StencilTable *varying_stencils = NULL;
if (has_varying_data) {
StencilTableFactory::Options varying_stencil_options;
varying_stencil_options.generateOffsets = stencil_generate_offsets;
- varying_stencil_options.generateIntermediateLevels =
- stencil_generate_intermediate_levels;
- varying_stencil_options.interpolationMode =
- StencilTableFactory::INTERPOLATE_VARYING;
- varying_stencils =
- StencilTableFactory::Create(*refiner, varying_stencil_options);
+ varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
+ varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_VARYING;
+ varying_stencils = StencilTableFactory::Create(*refiner, varying_stencil_options);
}
// Face warying stencil.
-vector<const StencilTable*> all_face_varying_stencils;
+ vector<const StencilTable *> all_face_varying_stencils;
#ifdef OPENSUBDIV_HAS_FVAR_EVALUATION
all_face_varying_stencils.reserve(num_face_varying_channels);
- for (int face_varying_channel = 0;
- face_varying_channel < num_face_varying_channels;
+ for (int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
++face_varying_channel) {
StencilTableFactory::Options face_varying_stencil_options;
face_varying_stencil_options.generateOffsets = stencil_generate_offsets;
- face_varying_stencil_options.generateIntermediateLevels =
- stencil_generate_intermediate_levels;
- face_varying_stencil_options.interpolationMode =
- StencilTableFactory::INTERPOLATE_FACE_VARYING;
+ face_varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
+ face_varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_FACE_VARYING;
face_varying_stencil_options.fvarChannel = face_varying_channel;
all_face_varying_stencils.push_back(
StencilTableFactory::Create(*refiner, face_varying_stencil_options));
@@ -774,42 +779,35 @@ vector<const StencilTable*> all_face_varying_stencils;
patch_options.useInfSharpPatch = use_inf_sharp_patch;
patch_options.generateFVarTables = has_face_varying_data;
patch_options.generateFVarLegacyLinearPatches = false;
- const PatchTable* patch_table = PatchTableFactory::Create(
- *refiner, patch_options);
+ const PatchTable *patch_table = PatchTableFactory::Create(*refiner, patch_options);
// Append local points stencils.
// Point stencils.
- const StencilTable* local_point_stencil_table =
- patch_table->GetLocalPointStencilTable();
+ const StencilTable *local_point_stencil_table = patch_table->GetLocalPointStencilTable();
if (local_point_stencil_table != NULL) {
- const StencilTable* table =
- StencilTableFactory::AppendLocalPointStencilTable(
- *refiner, vertex_stencils, local_point_stencil_table);
+ const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
+ *refiner, vertex_stencils, local_point_stencil_table);
delete vertex_stencils;
vertex_stencils = table;
}
// Varying stencils.
if (has_varying_data) {
- const StencilTable* local_point_varying_stencil_table =
+ const StencilTable *local_point_varying_stencil_table =
patch_table->GetLocalPointVaryingStencilTable();
if (local_point_varying_stencil_table != NULL) {
- const StencilTable* table =
- StencilTableFactory::AppendLocalPointStencilTable(
- *refiner, varying_stencils, local_point_varying_stencil_table);
+ const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
+ *refiner, varying_stencils, local_point_varying_stencil_table);
delete varying_stencils;
varying_stencils = table;
}
}
#ifdef OPENSUBDIV_HAS_FVAR_EVALUATION
- for (int face_varying_channel = 0;
- face_varying_channel < num_face_varying_channels;
+ for (int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
++face_varying_channel) {
- const StencilTable* table =
- StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
- *refiner,
- all_face_varying_stencils[face_varying_channel],
- patch_table->GetLocalPointFaceVaryingStencilTable(
- face_varying_channel),
- face_varying_channel);
+ const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
+ *refiner,
+ all_face_varying_stencils[face_varying_channel],
+ patch_table->GetLocalPointFaceVaryingStencilTable(face_varying_channel),
+ face_varying_channel);
if (table != NULL) {
delete all_face_varying_stencils[face_varying_channel];
all_face_varying_stencils[face_varying_channel] = table;
@@ -818,30 +816,25 @@ vector<const StencilTable*> all_face_varying_stencils;
#endif
// Create OpenSubdiv's CPU side evaluator.
// TODO(sergey): Make it possible to use different evaluators.
- opensubdiv_capi::CpuEvalOutput* eval_output =
- new opensubdiv_capi::CpuEvalOutput(vertex_stencils,
- varying_stencils,
- all_face_varying_stencils,
- 2,
- patch_table);
- OpenSubdiv::Far::PatchMap* patch_map = new PatchMap(*patch_table);
+ opensubdiv_capi::CpuEvalOutput *eval_output = new opensubdiv_capi::CpuEvalOutput(
+ vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
+ OpenSubdiv::Far::PatchMap *patch_map = new PatchMap(*patch_table);
// Wrap everything we need into an object which we control from our side.
- OpenSubdiv_EvaluatorInternal* evaluator_descr;
+ OpenSubdiv_EvaluatorInternal *evaluator_descr;
evaluator_descr = OBJECT_GUARDED_NEW(OpenSubdiv_EvaluatorInternal);
- evaluator_descr->eval_output =
- new opensubdiv_capi::CpuEvalOutputAPI(eval_output, patch_map);
+ evaluator_descr->eval_output = new opensubdiv_capi::CpuEvalOutputAPI(eval_output, patch_map);
evaluator_descr->patch_map = patch_map;
evaluator_descr->patch_table = patch_table;
// TOOD(sergey): Look into whether we've got duplicated stencils arrays.
delete vertex_stencils;
delete varying_stencils;
- foreach (const StencilTable* table, all_face_varying_stencils) {
+ foreach (const StencilTable *table, all_face_varying_stencils) {
delete table;
}
return evaluator_descr;
}
-void openSubdiv_deleteEvaluatorInternal(
- OpenSubdiv_EvaluatorInternal* evaluator) {
+void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorInternal *evaluator)
+{
OBJECT_GUARDED_DELETE(evaluator, OpenSubdiv_EvaluatorInternal);
}
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
index 7d9178f38dc..7c963227d17 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
@@ -42,29 +42,30 @@ class CpuEvalOutput;
class CpuEvalOutputAPI {
public:
// NOTE: API object becomes an owner of evaluator. Patch we are referencing.
- CpuEvalOutputAPI(CpuEvalOutput* implementation,
- OpenSubdiv::Far::PatchMap* patch_map);
+ CpuEvalOutputAPI(CpuEvalOutput *implementation, OpenSubdiv::Far::PatchMap *patch_map);
~CpuEvalOutputAPI();
// Set coarse positions from a continuous array of coordinates.
- void setCoarsePositions(const float* positions,
+ void setCoarsePositions(const float *positions,
const int start_vertex_index,
const int num_vertices);
// Set varying data from a continuous array of data.
- void setVaryingData(const float* varying_data,
- const int start_vertex_index, const int num_vertices);
+ void setVaryingData(const float *varying_data,
+ const int start_vertex_index,
+ const int num_vertices);
// Set face varying data from a continuous array of data.
//
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
void setFaceVaryingData(const int face_varying_channel,
- const float* varying_data,
- const int start_vertex_index, const int num_vertices);
+ const float *varying_data,
+ const int start_vertex_index,
+ const int num_vertices);
// Set coarse vertex position from a continuous memory buffer where
// first coordinate starts at offset of `start_offset` and there is `stride`
// bytes between adjacent vertex coordinates.
- void setCoarsePositionsFromBuffer(const void* buffer,
+ void setCoarsePositionsFromBuffer(const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
@@ -72,7 +73,7 @@ class CpuEvalOutputAPI {
// Set varying data from a continuous memory buffer where
// first coordinate starts at offset of `start_offset` and there is `stride`
// bytes between adjacent vertex coordinates.
- void setVaryingDataFromBuffer(const void* buffer,
+ void setVaryingDataFromBuffer(const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
@@ -84,7 +85,7 @@ class CpuEvalOutputAPI {
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
void setFaceVaryingDataFromBuffer(const int face_varying_channel,
- const void* buffer,
+ const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
@@ -96,24 +97,26 @@ class CpuEvalOutputAPI {
// Evaluate given ptex face at given bilinear coordinate.
// If derivatives are NULL, they will not be evaluated.
void evaluateLimit(const int ptex_face_index,
- float face_u, float face_v,
- float P[3], float dPdu[3], float dPdv[3]);
+ float face_u,
+ float face_v,
+ float P[3],
+ float dPdu[3],
+ float dPdv[3]);
// Evaluate varying data at a given bilinear coordinate of given ptex face.
- void evaluateVarying(const int ptes_face_index,
- float face_u, float face_v,
- float varying[3]);
+ void evaluateVarying(const int ptes_face_index, float face_u, float face_v, float varying[3]);
// Evaluate facee-varying data at a given bilinear coordinate of given
// ptex face.
void evaluateFaceVarying(const int face_varying_channel,
const int ptes_face_index,
- float face_u, float face_v,
+ float face_u,
+ float face_v,
float face_varying[2]);
protected:
- CpuEvalOutput* implementation_;
- OpenSubdiv::Far::PatchMap* patch_map_;
+ CpuEvalOutput *implementation_;
+ OpenSubdiv::Far::PatchMap *patch_map_;
};
} // namespace opensubdiv_capi
@@ -123,15 +126,14 @@ struct OpenSubdiv_EvaluatorInternal {
OpenSubdiv_EvaluatorInternal();
~OpenSubdiv_EvaluatorInternal();
- opensubdiv_capi::CpuEvalOutputAPI* eval_output;
- const OpenSubdiv::Far::PatchMap* patch_map;
- const OpenSubdiv::Far::PatchTable* patch_table;
+ opensubdiv_capi::CpuEvalOutputAPI *eval_output;
+ const OpenSubdiv::Far::PatchMap *patch_map;
+ const OpenSubdiv::Far::PatchTable *patch_table;
};
-OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal(
- struct OpenSubdiv_TopologyRefiner* topology_refiner);
+OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal(
+ struct OpenSubdiv_TopologyRefiner *topology_refiner);
-void openSubdiv_deleteEvaluatorInternal(
- OpenSubdiv_EvaluatorInternal* evaluator);
+void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorInternal *evaluator);
#endif // OPENSUBDIV_EVALUATOR_INTERNAL_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc
index 469480e0fcd..0e4d9ce0a83 100644
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc
+++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc
@@ -33,20 +33,14 @@ using OpenSubdiv::Osd::MeshBitset;
// CPU backend.
#include <opensubdiv/osd/cpuEvaluator.h>
#include <opensubdiv/osd/cpuGLVertexBuffer.h>
-using OpenSubdiv::Osd::CpuGLVertexBuffer;
using OpenSubdiv::Osd::CpuEvaluator;
-typedef Mesh<CpuGLVertexBuffer,
- StencilTable,
- CpuEvaluator,
- GLPatchTable> OsdCpuMesh;
+using OpenSubdiv::Osd::CpuGLVertexBuffer;
+typedef Mesh<CpuGLVertexBuffer, StencilTable, CpuEvaluator, GLPatchTable> OsdCpuMesh;
// OpenMP backend.
#ifdef OPENSUBDIV_HAS_OPENMP
# include <opensubdiv/osd/ompEvaluator.h>
using OpenSubdiv::Osd::OmpEvaluator;
-typedef Mesh<CpuGLVertexBuffer,
- StencilTable,
- OmpEvaluator,
- GLPatchTable> OsdOmpMesh;
+typedef Mesh<CpuGLVertexBuffer, StencilTable, OmpEvaluator, GLPatchTable> OsdOmpMesh;
#endif
// OpenCL backend.
#ifdef OPENSUBDIV_HAS_OPENCL
@@ -57,11 +51,8 @@ using OpenSubdiv::Osd::CLEvaluator;
using OpenSubdiv::Osd::CLGLVertexBuffer;
using OpenSubdiv::Osd::CLStencilTable;
/* TODO(sergey): Use CLDeviceContext similar to OSD examples? */
-typedef Mesh<CLGLVertexBuffer,
- CLStencilTable,
- CLEvaluator,
- GLPatchTable,
- CLDeviceContext> OsdCLMesh;
+typedef Mesh<CLGLVertexBuffer, CLStencilTable, CLEvaluator, GLPatchTable, CLDeviceContext>
+ OsdCLMesh;
static CLDeviceContext g_cl_device_context;
#endif
// CUDA backend.
@@ -72,23 +63,18 @@ static CLDeviceContext g_cl_device_context;
using OpenSubdiv::Osd::CudaEvaluator;
using OpenSubdiv::Osd::CudaGLVertexBuffer;
using OpenSubdiv::Osd::CudaStencilTable;
-typedef Mesh<CudaGLVertexBuffer,
- CudaStencilTable,
- CudaEvaluator,
- GLPatchTable> OsdCudaMesh;
+typedef Mesh<CudaGLVertexBuffer, CudaStencilTable, CudaEvaluator, GLPatchTable> OsdCudaMesh;
static CudaDeviceContext g_cuda_device_context;
#endif
// Transform feedback backend.
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
# include <opensubdiv/osd/glVertexBuffer.h>
# include <opensubdiv/osd/glXFBEvaluator.h>
-using OpenSubdiv::Osd::GLXFBEvaluator;
using OpenSubdiv::Osd::GLStencilTableTBO;
using OpenSubdiv::Osd::GLVertexBuffer;
-typedef Mesh<GLVertexBuffer,
- GLStencilTableTBO,
- GLXFBEvaluator,
- GLPatchTable> OsdGLSLTransformFeedbackMesh;
+using OpenSubdiv::Osd::GLXFBEvaluator;
+typedef Mesh<GLVertexBuffer, GLStencilTableTBO, GLXFBEvaluator, GLPatchTable>
+ OsdGLSLTransformFeedbackMesh;
#endif
// GLSL compute backend.
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
@@ -97,10 +83,8 @@ typedef Mesh<GLVertexBuffer,
using OpenSubdiv::Osd::GLComputeEvaluator;
using OpenSubdiv::Osd::GLStencilTableSSBO;
using OpenSubdiv::Osd::GLVertexBuffer;
-typedef Mesh<GLVertexBuffer,
- GLStencilTableSSBO,
- GLComputeEvaluator,
- GLPatchTable> OsdGLSLComputeMesh;
+typedef Mesh<GLVertexBuffer, GLStencilTableSSBO, GLComputeEvaluator, GLPatchTable>
+ OsdGLSLComputeMesh;
#endif
#include "MEM_guardedalloc.h"
@@ -116,27 +100,23 @@ using opensubdiv_capi::vector;
namespace {
-GLMeshInterface* createGLMeshInterface(
- OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const MeshBitset& bits,
- const int num_vertex_elements,
- const int num_varying_elements,
- const int level,
- eOpenSubdivEvaluator evaluator_type) {
- GLMeshInterface* mesh = NULL;
+GLMeshInterface *createGLMeshInterface(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const MeshBitset &bits,
+ const int num_vertex_elements,
+ const int num_varying_elements,
+ const int level,
+ eOpenSubdivEvaluator evaluator_type)
+{
+ GLMeshInterface *mesh = NULL;
switch (evaluator_type) {
-#define CHECK_EVALUATOR_TYPE(type, class) \
- case OPENSUBDIV_EVALUATOR_##type: \
- mesh = new class(topology_refiner, \
- num_vertex_elements, \
- num_varying_elements, \
- level, \
- bits); \
+#define CHECK_EVALUATOR_TYPE(type, class) \
+ case OPENSUBDIV_EVALUATOR_##type: \
+ mesh = new class(topology_refiner, num_vertex_elements, num_varying_elements, level, bits); \
break;
-#define CHECK_EVALUATOR_TYPE_STUB(type) \
- case OPENSUBDIV_EVALUATOR_##type: \
- mesh = NULL; \
+#define CHECK_EVALUATOR_TYPE_STUB(type) \
+ case OPENSUBDIV_EVALUATOR_##type: \
+ mesh = NULL; \
break;
CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh)
@@ -175,47 +155,46 @@ GLMeshInterface* createGLMeshInterface(
////////////////////////////////////////////////////////////////////////////////
// GLMesh structure "methods".
-opensubdiv_capi::GLMeshFVarData* createFVarData(
- OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- GLMeshInterface* mesh,
- const float *fvar_src_buffer) {
+opensubdiv_capi::GLMeshFVarData *createFVarData(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ GLMeshInterface *mesh,
+ const float *fvar_src_buffer)
+{
using opensubdiv_capi::GLMeshFVarData;
- GLMeshFVarData* fvar_data = new GLMeshFVarData();
- fvar_data->create(topology_refiner,
- mesh->GetFarPatchTable(),
- 2,
- fvar_src_buffer);
+ GLMeshFVarData *fvar_data = new GLMeshFVarData();
+ fvar_data->create(topology_refiner, mesh->GetFarPatchTable(), 2, fvar_src_buffer);
return fvar_data;
}
-unsigned int getPatchIndexBuffer(OpenSubdiv_GLMesh* gl_mesh) {
- return gl_mesh->internal->mesh_interface
- ->GetPatchTable()
- ->GetPatchIndexBuffer();
+unsigned int getPatchIndexBuffer(OpenSubdiv_GLMesh *gl_mesh)
+{
+ return gl_mesh->internal->mesh_interface->GetPatchTable()->GetPatchIndexBuffer();
}
-void bindVertexBuffer(OpenSubdiv_GLMesh* gl_mesh) {
+void bindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh)
+{
gl_mesh->internal->mesh_interface->BindVertexBuffer();
}
-void setCoarsePositions(OpenSubdiv_GLMesh* gl_mesh,
- const float* positions,
+void setCoarsePositions(OpenSubdiv_GLMesh *gl_mesh,
+ const float *positions,
const int start_vertex,
- const int num_vertices) {
- gl_mesh->internal->mesh_interface->UpdateVertexBuffer(positions,
- start_vertex,
- num_vertices);
+ const int num_vertices)
+{
+ gl_mesh->internal->mesh_interface->UpdateVertexBuffer(positions, start_vertex, num_vertices);
}
-void refine(OpenSubdiv_GLMesh* gl_mesh) {
+void refine(OpenSubdiv_GLMesh *gl_mesh)
+{
gl_mesh->internal->mesh_interface->Refine();
}
-void synchronize(struct OpenSubdiv_GLMesh* gl_mesh) {
+void synchronize(struct OpenSubdiv_GLMesh *gl_mesh)
+{
gl_mesh->internal->mesh_interface->Synchronize();
}
-void assignFunctionPointers(OpenSubdiv_GLMesh* gl_mesh) {
+void assignFunctionPointers(OpenSubdiv_GLMesh *gl_mesh)
+{
gl_mesh->getPatchIndexBuffer = getPatchIndexBuffer;
gl_mesh->bindVertexBuffer = bindVertexBuffer;
gl_mesh->setCoarsePositions = setCoarsePositions;
@@ -229,11 +208,10 @@ void assignFunctionPointers(OpenSubdiv_GLMesh* gl_mesh) {
} // namespace
struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
- OpenSubdiv_TopologyRefiner* topology_refiner,
- eOpenSubdivEvaluator evaluator_type) {
+ OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type)
+{
using OpenSubdiv::Far::TopologyRefiner;
- TopologyRefiner* osd_topology_refiner =
- topology_refiner->internal->osd_topology_refiner;
+ TopologyRefiner *osd_topology_refiner = topology_refiner->internal->osd_topology_refiner;
// TODO(sergey): Query this from refiner.
const bool is_adaptive = false;
MeshBitset bits;
@@ -244,17 +222,16 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1);
const int num_vertex_elements = 3;
const int num_varying_elements = 3;
- GLMeshInterface* mesh = createGLMeshInterface(
- osd_topology_refiner,
- bits,
- num_vertex_elements,
- num_varying_elements,
- osd_topology_refiner->GetMaxLevel(),
- evaluator_type);
+ GLMeshInterface *mesh = createGLMeshInterface(osd_topology_refiner,
+ bits,
+ num_vertex_elements,
+ num_varying_elements,
+ osd_topology_refiner->GetMaxLevel(),
+ evaluator_type);
if (mesh == NULL) {
return NULL;
}
- OpenSubdiv_GLMesh* gl_mesh = OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh);
+ OpenSubdiv_GLMesh *gl_mesh = OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh);
assignFunctionPointers(gl_mesh);
gl_mesh->internal = new OpenSubdiv_GLMeshInternal();
gl_mesh->internal->evaluator_type = evaluator_type;
@@ -266,19 +243,18 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
// to store base level UVs somewhere else.
vector<float> uvs;
vector<float> fvar_data_buffer;
- opensubdiv_capi::interpolateFVarData(*osd_topology_refiner,
- uvs,
- &fvar_data_buffer);
- gl_mesh->internal->fvar_data = createFVarData(osd_topology_refiner,
- mesh,
- &fvar_data_buffer[0]);
- } else {
+ opensubdiv_capi::interpolateFVarData(*osd_topology_refiner, uvs, &fvar_data_buffer);
+ gl_mesh->internal->fvar_data = createFVarData(
+ osd_topology_refiner, mesh, &fvar_data_buffer[0]);
+ }
+ else {
gl_mesh->internal->fvar_data = NULL;
}
return gl_mesh;
}
-void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh* gl_mesh) {
+void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh)
+{
delete gl_mesh->internal;
OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh);
}
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc
index c1efc439b2e..cbccf69e02d 100644
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc
+++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc
@@ -111,11 +111,13 @@ static Transform g_transform;
namespace {
GLuint compileShader(GLenum shaderType,
- const char* version,
- const char* define,
- const char* source) {
- const char* sources[] = {
- version, define,
+ const char *version,
+ const char *define,
+ const char *source)
+{
+ const char *sources[] = {
+ version,
+ define,
#ifdef SUPPORT_COLOR_MATERIAL
"#define SUPPORT_COLOR_MATERIAL\n",
#else
@@ -143,22 +145,20 @@ GLuint compileShader(GLenum shaderType,
return shader;
}
-GLuint linkProgram(const char* version, const char* define) {
- GLuint vertexShader =
- compileShader(GL_VERTEX_SHADER, version, define,
- datatoc_gpu_shader_opensubdiv_vertex_glsl);
+GLuint linkProgram(const char *version, const char *define)
+{
+ GLuint vertexShader = compileShader(
+ GL_VERTEX_SHADER, version, define, datatoc_gpu_shader_opensubdiv_vertex_glsl);
if (vertexShader == 0) {
return 0;
}
- GLuint geometryShader =
- compileShader(GL_GEOMETRY_SHADER, version, define,
- datatoc_gpu_shader_opensubdiv_geometry_glsl);
+ GLuint geometryShader = compileShader(
+ GL_GEOMETRY_SHADER, version, define, datatoc_gpu_shader_opensubdiv_geometry_glsl);
if (geometryShader == 0) {
return 0;
}
- GLuint fragmentShader =
- compileShader(GL_FRAGMENT_SHADER, version, define,
- datatoc_gpu_shader_opensubdiv_fragment_glsl);
+ GLuint fragmentShader = compileShader(
+ GL_FRAGMENT_SHADER, version, define, datatoc_gpu_shader_opensubdiv_fragment_glsl);
if (fragmentShader == 0) {
return 0;
}
@@ -189,17 +189,14 @@ GLuint linkProgram(const char* version, const char* define) {
return 0;
}
- glUniformBlockBinding(program, glGetUniformBlockIndex(program, "Lighting"),
- 0);
+ glUniformBlockBinding(program, glGetUniformBlockIndex(program, "Lighting"), 0);
if (GLEW_VERSION_4_1) {
- glProgramUniform1i(
- program, glGetUniformLocation(program, "texture_buffer"), 0);
- glProgramUniform1i(
- program, glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
- glProgramUniform1i(
- program, glGetUniformLocation(program, "FVarDataBuffer"), 31);
- } else {
+ glProgramUniform1i(program, glGetUniformLocation(program, "texture_buffer"), 0);
+ glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
+ glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataBuffer"), 31);
+ }
+ else {
glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0);
glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
@@ -210,25 +207,19 @@ GLuint linkProgram(const char* version, const char* define) {
return program;
}
-void bindProgram(OpenSubdiv_GLMesh* gl_mesh, int program) {
+void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program)
+{
glUseProgram(program);
// Matrices
- glUniformMatrix4fv(glGetUniformLocation(program, "modelViewMatrix"),
- 1,
- false,
- g_transform.model_view_matrix);
- glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"),
- 1,
- false,
- g_transform.projection_matrix);
- glUniformMatrix3fv(glGetUniformLocation(program, "normalMatrix"),
- 1,
- false,
- g_transform.normal_matrix);
+ glUniformMatrix4fv(
+ glGetUniformLocation(program, "modelViewMatrix"), 1, false, g_transform.model_view_matrix);
+ glUniformMatrix4fv(
+ glGetUniformLocation(program, "projectionMatrix"), 1, false, g_transform.projection_matrix);
+ glUniformMatrix3fv(
+ glGetUniformLocation(program, "normalMatrix"), 1, false, g_transform.normal_matrix);
// Lighting.
glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
- glBufferSubData(
- GL_UNIFORM_BUFFER, 0, sizeof(g_lighting_data), &g_lighting_data);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(g_lighting_data), &g_lighting_data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
// Color.
@@ -243,7 +234,7 @@ void bindProgram(OpenSubdiv_GLMesh* gl_mesh, int program) {
glUniform1f(glGetUniformLocation(program, "shininess"), color[0]);
}
// Face-vertex data.
- opensubdiv_capi::GLMeshFVarData* fvar_data = gl_mesh->internal->fvar_data;
+ opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
if (fvar_data != NULL) {
if (fvar_data->texture_buffer) {
glActiveTexture(GL_TEXTURE31);
@@ -255,15 +246,16 @@ void bindProgram(OpenSubdiv_GLMesh* gl_mesh, int program) {
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer);
glActiveTexture(GL_TEXTURE0);
}
- glUniform1i(glGetUniformLocation(program, "osd_fvar_count"),
- fvar_data->fvar_width);
+ glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), fvar_data->fvar_width);
if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"),
fvar_data->channel_offsets[g_active_uv_index]);
- } else {
+ }
+ else {
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
- } else {
+ }
+ else {
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
@@ -271,7 +263,8 @@ void bindProgram(OpenSubdiv_GLMesh* gl_mesh, int program) {
} // namespace
-bool openSubdiv_initGLMeshDrawingResources(void) {
+bool openSubdiv_initGLMeshDrawingResources(void)
+{
static bool need_init = true;
static bool init_success = false;
if (!need_init) {
@@ -280,16 +273,19 @@ bool openSubdiv_initGLMeshDrawingResources(void) {
// TODO(sergey): Update OSD drawing to OpenGL 3.3 core,
// then remove following line.
return false;
- const char* version = "";
+ const char *version = "";
if (GLEW_VERSION_3_2) {
version = "#version 150 compatibility\n";
- } else if (GLEW_VERSION_3_1) {
- version = "#version 140\n"
- "#extension GL_ARB_compatibility: enable\n";
- } else {
+ }
+ else if (GLEW_VERSION_3_1) {
+ version =
+ "#version 140\n"
+ "#extension GL_ARB_compatibility: enable\n";
+ }
+ else {
version = "#version 130\n";
// Minimum supported for OpenSubdiv.
- }
+ }
g_flat_fill_solid_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
@@ -309,49 +305,42 @@ bool openSubdiv_initGLMeshDrawingResources(void) {
"#define USE_TEXTURE_2D\n"
"#define SMOOTH_SHADING\n");
- g_flat_fill_solid_shadeless_program =
- linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define FLAT_SHADING\n");
- g_flat_fill_texture2d_shadeless_program =
- linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_TEXTURE_2D\n"
- "#define FLAT_SHADING\n");
- g_smooth_fill_solid_shadeless_program =
- linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define SMOOTH_SHADING\n");
- g_smooth_fill_texture2d_shadeless_program =
- linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_TEXTURE_2D\n"
- "#define SMOOTH_SHADING\n");
+ g_flat_fill_solid_shadeless_program = linkProgram(version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define FLAT_SHADING\n");
+ g_flat_fill_texture2d_shadeless_program = linkProgram(version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define USE_TEXTURE_2D\n"
+ "#define FLAT_SHADING\n");
+ g_smooth_fill_solid_shadeless_program = linkProgram(version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define SMOOTH_SHADING\n");
+ g_smooth_fill_texture2d_shadeless_program = linkProgram(version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define USE_TEXTURE_2D\n"
+ "#define SMOOTH_SHADING\n");
g_wireframe_program = linkProgram(version, "#define WIREFRAME\n");
glGenBuffers(1, &g_lighting_ub);
glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
- glBufferData(GL_UNIFORM_BUFFER,
- sizeof(g_lighting_data),
- NULL,
- GL_STATIC_DRAW);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(g_lighting_data), NULL, GL_STATIC_DRAW);
need_init = false;
- init_success = g_flat_fill_solid_program != 0 &&
- g_flat_fill_texture2d_program != 0 &&
- g_smooth_fill_solid_program != 0 &&
- g_smooth_fill_texture2d_program != 0 && g_wireframe_program;
+ init_success = g_flat_fill_solid_program != 0 && g_flat_fill_texture2d_program != 0 &&
+ g_smooth_fill_solid_program != 0 && g_smooth_fill_texture2d_program != 0 &&
+ g_wireframe_program;
return init_success;
}
-void openSubdiv_deinitGLMeshDrawingResources(void) {
+void openSubdiv_deinitGLMeshDrawingResources(void)
+{
if (g_lighting_ub != 0) {
glDeleteBuffers(1, &g_lighting_ub);
}
-#define SAFE_DELETE_PROGRAM(program) \
- do { \
- if (program) { \
- glDeleteProgram(program); \
- } \
+#define SAFE_DELETE_PROGRAM(program) \
+ do { \
+ if (program) { \
+ glDeleteProgram(program); \
+ } \
} while (false)
SAFE_DELETE_PROGRAM(g_flat_fill_solid_program);
@@ -371,7 +360,8 @@ namespace opensubdiv_capi {
namespace {
-GLuint prepare_patchDraw(OpenSubdiv_GLMesh* gl_mesh, bool fill_quads) {
+GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, bool fill_quads)
+{
GLint program = 0;
if (!g_use_osd_glsl) {
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
@@ -383,7 +373,7 @@ GLuint prepare_patchDraw(OpenSubdiv_GLMesh* gl_mesh, bool fill_quads) {
glUniform1i(location, model == GL_FLAT);
}
// Face-vertex data.
- opensubdiv_capi::GLMeshFVarData* fvar_data = gl_mesh->internal->fvar_data;
+ opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
if (fvar_data != NULL) {
if (fvar_data->texture_buffer) {
glActiveTexture(GL_TEXTURE31);
@@ -402,13 +392,14 @@ GLuint prepare_patchDraw(OpenSubdiv_GLMesh* gl_mesh, bool fill_quads) {
location = glGetUniformLocation(program, "osd_active_uv_offset");
if (location != -1) {
if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
- glUniform1i(location,
- fvar_data->channel_offsets[g_active_uv_index]);
- } else {
+ glUniform1i(location, fvar_data->channel_offsets[g_active_uv_index]);
+ }
+ else {
glUniform1i(location, 0);
}
}
- } else {
+ }
+ else {
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
@@ -423,18 +414,21 @@ GLuint prepare_patchDraw(OpenSubdiv_GLMesh* gl_mesh, bool fill_quads) {
if (model == GL_FLAT) {
if (use_texture_2d) {
program = g_flat_fill_texture2d_program;
- } else {
+ }
+ else {
program = g_flat_fill_solid_program;
}
- } else {
+ }
+ else {
if (use_texture_2d) {
program = g_smooth_fill_texture2d_program;
- } else {
+ }
+ else {
program = g_smooth_fill_solid_program;
}
}
-
- } else {
+ }
+ else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
program = g_wireframe_program;
}
@@ -442,20 +436,19 @@ GLuint prepare_patchDraw(OpenSubdiv_GLMesh* gl_mesh, bool fill_quads) {
return program;
}
-void perform_drawElements(GLuint program,
- int patch_index,
- int num_elements,
- int start_element) {
+void perform_drawElements(GLuint program, int patch_index, int num_elements, int start_element)
+{
if (program) {
glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), patch_index);
}
glDrawElements(GL_LINES_ADJACENCY,
num_elements,
GL_UNSIGNED_INT,
- reinterpret_cast<void*>(start_element * sizeof(unsigned int)));
+ reinterpret_cast<void *>(start_element * sizeof(unsigned int)));
}
-void finishPatchDraw(bool fill_quads) {
+void finishPatchDraw(bool fill_quads)
+{
// TODO(sergey): Some of the stuff could be done once after the whole
// mesh is displayed.
/// Restore state.
@@ -469,13 +462,13 @@ void finishPatchDraw(bool fill_quads) {
}
}
-void drawPartitionPatchesRange(GLMeshInterface* mesh,
+void drawPartitionPatchesRange(GLMeshInterface *mesh,
GLuint program,
int start_patch,
- int num_patches) {
+ int num_patches)
+{
int traversed_patches = 0, num_remained_patches = num_patches;
- const OpenSubdiv::Osd::PatchArrayVector &patches =
- mesh->GetPatchTable()->GetPatchArrays();
+ const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
for (int i = 0; i < patches.size(); ++i) {
const OpenSubdiv::Osd::PatchArray &patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
@@ -486,11 +479,12 @@ void drawPartitionPatchesRange(GLMeshInterface* mesh,
start_patch < traversed_patches + num_block_patches) {
const int num_control_verts = desc.GetNumControlVertices();
const int start_draw_patch = start_patch - traversed_patches;
- const int num_draw_patches = min(
- num_remained_patches, num_block_patches - start_draw_patch);
- perform_drawElements(
- program, i + start_draw_patch, num_draw_patches * num_control_verts,
- patch.GetIndexBase() + start_draw_patch * num_control_verts);
+ const int num_draw_patches = min(num_remained_patches,
+ num_block_patches - start_draw_patch);
+ perform_drawElements(program,
+ i + start_draw_patch,
+ num_draw_patches * num_control_verts,
+ patch.GetIndexBase() + start_draw_patch * num_control_verts);
num_remained_patches -= num_draw_patches;
}
if (num_remained_patches == 0) {
@@ -501,34 +495,33 @@ void drawPartitionPatchesRange(GLMeshInterface* mesh,
}
}
-static void drawAllPatches(GLMeshInterface* mesh, GLuint program) {
- const OpenSubdiv::Osd::PatchArrayVector &patches =
- mesh->GetPatchTable()->GetPatchArrays();
+static void drawAllPatches(GLMeshInterface *mesh, GLuint program)
+{
+ const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
for (int i = 0; i < patches.size(); ++i) {
const OpenSubdiv::Osd::PatchArray &patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
- perform_drawElements(program, i,
- patch.GetNumPatches() * desc.GetNumControlVertices(),
- patch.GetIndexBase());
+ perform_drawElements(
+ program, i, patch.GetNumPatches() * desc.GetNumControlVertices(), patch.GetIndexBase());
}
}
}
} // namespace
-void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh* /*gl_mesh*/,
+void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh * /*gl_mesh*/,
const bool use_osd_glsl,
- const int active_uv_index) {
+ const int active_uv_index)
+{
g_active_uv_index = active_uv_index;
g_use_osd_glsl = (use_osd_glsl != 0);
// Update transformation matrices.
glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix);
glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix);
- copy_m3_m4((float(*)[3])g_transform.normal_matrix,
- (float(*)[4])g_transform.model_view_matrix);
+ copy_m3_m4((float(*)[3])g_transform.normal_matrix, (float(*)[4])g_transform.model_view_matrix);
invert_m3((float(*)[3])g_transform.normal_matrix);
transpose_m3((float(*)[3])g_transform.normal_matrix);
// Update OpenGL lights positions, colors etc.
@@ -540,36 +533,31 @@ void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh* /*gl_mesh*/,
g_lighting_data.num_enabled++;
}
// TODO(sergey): Stop using glGetLight.
- glGetLightfv(GL_LIGHT0 + i, GL_POSITION,
- g_lighting_data.lights[i].position);
+ glGetLightfv(GL_LIGHT0 + i, GL_POSITION, g_lighting_data.lights[i].position);
glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, g_lighting_data.lights[i].ambient);
glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, g_lighting_data.lights[i].diffuse);
- glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR,
- g_lighting_data.lights[i].specular);
- glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION,
- g_lighting_data.lights[i].spot_direction);
+ glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, g_lighting_data.lights[i].specular);
+ glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, g_lighting_data.lights[i].spot_direction);
#ifdef SUPPORT_COLOR_MATERIAL
- glGetLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION,
- &g_lighting_data.lights[i].constant_attenuation);
- glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION,
- &g_lighting_data.lights[i].linear_attenuation);
- glGetLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION,
- &g_lighting_data.lights[i].quadratic_attenuation);
- glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF,
- &g_lighting_data.lights[i].spot_cutoff);
- glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT,
- &g_lighting_data.lights[i].spot_exponent);
- g_lighting_data.lights[i].spot_cos_cutoff =
- cos(g_lighting_data.lights[i].spot_cutoff);
+ glGetLightfv(
+ GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &g_lighting_data.lights[i].constant_attenuation);
+ glGetLightfv(
+ GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &g_lighting_data.lights[i].linear_attenuation);
+ glGetLightfv(
+ GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &g_lighting_data.lights[i].quadratic_attenuation);
+ glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &g_lighting_data.lights[i].spot_cutoff);
+ glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &g_lighting_data.lights[i].spot_exponent);
+ g_lighting_data.lights[i].spot_cos_cutoff = cos(g_lighting_data.lights[i].spot_cutoff);
#endif
}
}
-void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh* gl_mesh,
+void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
const int start_patch,
- const int num_patches) {
- GLMeshInterface* mesh = gl_mesh->internal->mesh_interface;
+ const int num_patches)
+{
+ GLMeshInterface *mesh = gl_mesh->internal->mesh_interface;
// Make sure all global invariants are initialized.
if (!openSubdiv_initGLMeshDrawingResources()) {
return;
@@ -578,7 +566,8 @@ void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh* gl_mesh,
GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0);
if (start_patch != -1) {
drawPartitionPatchesRange(mesh, program, start_patch, num_patches);
- } else {
+ }
+ else {
drawAllPatches(mesh, program);
}
// Finish patch drawing by restoring all changes to the OpenGL context.
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h
index 5421b5cf707..599ab9550e7 100644
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h
+++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h
@@ -25,11 +25,11 @@ struct OpenSubdiv_GLMesh;
namespace opensubdiv_capi {
-void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh* gl_mesh,
+void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh *gl_mesh,
const bool use_osd_glsl,
const int active_uv_index);
-void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh* gl_mesh,
+void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
const int start_patch,
const int num_patches);
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc
index 32787ef05a3..6efbe93d2d8 100644
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc
+++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc
@@ -28,16 +28,17 @@ namespace opensubdiv_capi {
////////////////////////////////////////////////////////////////////////////////
// GLMeshFVarData
-GLMeshFVarData::GLMeshFVarData()
- : texture_buffer(0),
- offset_buffer(0) {
+GLMeshFVarData::GLMeshFVarData() : texture_buffer(0), offset_buffer(0)
+{
}
-GLMeshFVarData::~GLMeshFVarData() {
+GLMeshFVarData::~GLMeshFVarData()
+{
release();
}
-void GLMeshFVarData::release() {
+void GLMeshFVarData::release()
+{
if (texture_buffer) {
glDeleteTextures(1, &texture_buffer);
}
@@ -50,11 +51,11 @@ void GLMeshFVarData::release() {
channel_offsets.clear();
}
-void GLMeshFVarData::create(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv::Far::PatchTable* patch_table,
- int fvar_width,
- const float* fvar_src_data) {
+void GLMeshFVarData::create(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv::Far::PatchTable *patch_table,
+ int fvar_width,
+ const float *fvar_src_data)
+{
release();
this->fvar_width = fvar_width;
/// Expand fvar data to per-patch array.
@@ -64,8 +65,7 @@ void GLMeshFVarData::create(
int fvar_data_offset = 0;
channel_offsets.resize(num_channels);
for (int channel = 0; channel < num_channels; ++channel) {
- OpenSubdiv::Far::ConstIndexArray indices =
- patch_table->GetFVarValues(channel);
+ OpenSubdiv::Far::ConstIndexArray indices = patch_table->GetFVarValues(channel);
channel_offsets[channel] = data.size();
data.reserve(data.size() + indices.size() * fvar_width);
for (int fvert = 0; fvert < indices.size(); ++fvert) {
@@ -75,31 +75,26 @@ void GLMeshFVarData::create(
}
}
if (topology_refiner->IsUniform()) {
- const int num_values_max =
- topology_refiner->GetLevel(max_level).GetNumFVarValues(channel);
+ const int num_values_max = topology_refiner->GetLevel(max_level).GetNumFVarValues(channel);
fvar_data_offset += num_values_max * fvar_width;
- } else {
- const int num_values_total =
- topology_refiner->GetNumFVarValuesTotal(channel);
+ }
+ else {
+ const int num_values_total = topology_refiner->GetNumFVarValuesTotal(channel);
fvar_data_offset += num_values_total * fvar_width;
}
}
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(GL_ARRAY_BUFFER,
- data.size() * sizeof(float), &data[0],
- GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
glGenTextures(1, &texture_buffer);
glBindTexture(GL_TEXTURE_BUFFER, texture_buffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
glDeleteBuffers(1, &buffer);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(GL_ARRAY_BUFFER,
- channel_offsets.size() * sizeof(int),
- &channel_offsets[0],
- GL_STATIC_DRAW);
+ glBufferData(
+ GL_ARRAY_BUFFER, channel_offsets.size() * sizeof(int), &channel_offsets[0], GL_STATIC_DRAW);
glGenTextures(1, &offset_buffer);
glBindTexture(GL_TEXTURE_BUFFER, offset_buffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer);
@@ -113,26 +108,28 @@ void GLMeshFVarData::create(
struct FVarVertex {
float u, v;
- void Clear() {
+ void Clear()
+ {
u = v = 0.0f;
}
- void AddWithWeight(FVarVertex const& src, float weight) {
+ void AddWithWeight(FVarVertex const &src, float weight)
+ {
u += weight * src.u;
v += weight * src.v;
}
};
-void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner& refiner,
- const vector<float>& uvs,
- vector<float>* fvar_data) {
+void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
+ const vector<float> &uvs,
+ vector<float> *fvar_data)
+{
const int fvar_width = 2;
const int max_level = refiner.GetMaxLevel();
size_t fvar_data_offset = 0, values_offset = 0;
for (int channel = 0; channel < refiner.GetNumFVarChannels(); ++channel) {
const int num_values = refiner.GetLevel(0).GetNumFVarValues(channel) * 2;
- const int num_values_max =
- refiner.GetLevel(max_level).GetNumFVarValues(channel);
+ const int num_values_max = refiner.GetLevel(max_level).GetNumFVarValues(channel);
const int num_values_total = refiner.GetNumFVarValuesTotal(channel);
if (num_values_total <= 0) {
continue;
@@ -142,29 +139,26 @@ void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner& refiner,
// For uniform we only keep the highest level of refinement.
fvar_data->resize(fvar_data->size() + num_values_max * fvar_width);
vector<FVarVertex> buffer(num_values_total - num_values_max);
- FVarVertex* src = &buffer[0];
+ FVarVertex *src = &buffer[0];
memcpy(src, &uvs[values_offset], num_values * sizeof(float));
// Defer the last level to treat separately with its alternate
// destination.
for (int level = 1; level < max_level; ++level) {
- FVarVertex* dst =
- src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
+ FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
src = dst;
}
- FVarVertex* dst =
- reinterpret_cast<FVarVertex*>(&(*fvar_data)[fvar_data_offset]);
+ FVarVertex *dst = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel);
fvar_data_offset += num_values_max * fvar_width;
- } else {
+ }
+ else {
// For adaptive we keep all levels.
fvar_data->resize(fvar_data->size() + num_values_total * fvar_width);
- FVarVertex* src =
- reinterpret_cast<FVarVertex*>(&(*fvar_data)[fvar_data_offset]);
+ FVarVertex *src = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
memcpy(src, &uvs[values_offset], num_values * sizeof(float));
for (int level = 1; level <= max_level; ++level) {
- FVarVertex* dst =
- src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
+ FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
src = dst;
}
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h
index 0c5982f2c8b..cef78daced7 100644
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h
+++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h
@@ -37,10 +37,10 @@ class GLMeshFVarData {
~GLMeshFVarData();
void release();
- void create(const OpenSubdiv::Far::TopologyRefiner* refiner,
- const OpenSubdiv::Far::PatchTable* patch_table,
+ void create(const OpenSubdiv::Far::TopologyRefiner *refiner,
+ const OpenSubdiv::Far::PatchTable *patch_table,
int fvar_width,
- const float* fvar_src_data);
+ const float *fvar_src_data);
unsigned int texture_buffer;
unsigned int offset_buffer;
@@ -48,9 +48,9 @@ class GLMeshFVarData {
int fvar_width;
};
-void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner& refiner,
- const vector<float>& uvs,
- vector<float>* fvar_data);
+void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
+ const vector<float> &uvs,
+ vector<float> *fvar_data);
} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc
index 3abba9cf8f8..57e56bad3fb 100644
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc
@@ -21,12 +21,12 @@
#include "internal/opensubdiv_gl_mesh_fvar.h"
OpenSubdiv_GLMeshInternal::OpenSubdiv_GLMeshInternal()
- : evaluator_type(OPENSUBDIV_EVALUATOR_CPU),
- mesh_interface(NULL),
- fvar_data(NULL) {
+ : evaluator_type(OPENSUBDIV_EVALUATOR_CPU), mesh_interface(NULL), fvar_data(NULL)
+{
}
-OpenSubdiv_GLMeshInternal::~OpenSubdiv_GLMeshInternal() {
+OpenSubdiv_GLMeshInternal::~OpenSubdiv_GLMeshInternal()
+{
delete mesh_interface;
delete fvar_data;
}
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h
index 7796b450e69..cb92fb18362 100644
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h
@@ -36,8 +36,8 @@ typedef struct OpenSubdiv_GLMeshInternal {
~OpenSubdiv_GLMeshInternal();
eOpenSubdivEvaluator evaluator_type;
- OpenSubdiv::Osd::GLMeshInterface* mesh_interface;
- opensubdiv_capi::GLMeshFVarData* fvar_data;
+ OpenSubdiv::Osd::GLMeshInterface *mesh_interface;
+ opensubdiv_capi::GLMeshFVarData *fvar_data;
} OpenSubdiv_GLMeshInternal;
#endif // OPENSUBDIV_GL_MESH_INTERNAL_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
index c77ddc49df7..69907da8a8c 100644
--- a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
+++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
@@ -32,164 +32,164 @@ using opensubdiv_capi::vector;
namespace {
-const OpenSubdiv::Far::TopologyRefiner* getOSDTopologyRefiner(
- const OpenSubdiv_TopologyRefiner* topology_refiner) {
+const OpenSubdiv::Far::TopologyRefiner *getOSDTopologyRefiner(
+ const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return topology_refiner->internal->osd_topology_refiner;
}
-const OpenSubdiv::Far::TopologyLevel* getOSDTopologyBaseLevel(
- const OpenSubdiv_TopologyRefiner* topology_refiner) {
+const OpenSubdiv::Far::TopologyLevel *getOSDTopologyBaseLevel(
+ const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return &getOSDTopologyRefiner(topology_refiner)->GetLevel(0);
}
-int getSubdivisionLevel(const OpenSubdiv_TopologyRefiner* topology_refiner) {
+int getSubdivisionLevel(const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return topology_refiner->internal->settings.level;
}
-bool getIsAdaptive(const OpenSubdiv_TopologyRefiner* topology_refiner) {
+bool getIsAdaptive(const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return topology_refiner->internal->settings.is_adaptive;
}
////////////////////////////////////////////////////////////////////////////////
// Query basic topology information from base level.
-int getNumVertices(const OpenSubdiv_TopologyRefiner* topology_refiner) {
+int getNumVertices(const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return getOSDTopologyBaseLevel(topology_refiner)->GetNumVertices();
}
-int getNumEdges(const OpenSubdiv_TopologyRefiner* topology_refiner) {
+int getNumEdges(const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return getOSDTopologyBaseLevel(topology_refiner)->GetNumEdges();
}
-int getNumFaces(const OpenSubdiv_TopologyRefiner* topology_refiner) {
+int getNumFaces(const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return getOSDTopologyBaseLevel(topology_refiner)->GetNumFaces();
}
////////////////////////////////////////////////////////////////////////////////
// PTex face geometry queries.
-static void convertArrayToRaw(
- const OpenSubdiv::Far::ConstIndexArray& array,
- int* raw_array) {
+static void convertArrayToRaw(const OpenSubdiv::Far::ConstIndexArray &array, int *raw_array)
+{
for (int i = 0; i < array.size(); ++i) {
raw_array[i] = array[i];
}
}
-int getNumFaceVertices(const OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
+int getNumFaceVertices(const OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
return base_level->GetFaceVertices(face_index).size();
}
-void getFaceVertices(const OpenSubdiv_TopologyRefiner* topology_refiner,
+void getFaceVertices(const OpenSubdiv_TopologyRefiner *topology_refiner,
const int face_index,
- int* face_vertices_indices) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
- OpenSubdiv::Far::ConstIndexArray array =
- base_level->GetFaceVertices(face_index);
+ int *face_vertices_indices)
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
+ OpenSubdiv::Far::ConstIndexArray array = base_level->GetFaceVertices(face_index);
convertArrayToRaw(array, face_vertices_indices);
}
-int getNumFaceEdges(const OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
+int getNumFaceEdges(const OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
return base_level->GetFaceEdges(face_index).size();
}
-void getFaceEdges(const OpenSubdiv_TopologyRefiner* topology_refiner,
+void getFaceEdges(const OpenSubdiv_TopologyRefiner *topology_refiner,
const int face_index,
- int* face_edges_indices) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
+ int *face_edges_indices)
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
OpenSubdiv::Far::ConstIndexArray array = base_level->GetFaceEdges(face_index);
convertArrayToRaw(array, face_edges_indices);
}
-void getEdgeVertices(const OpenSubdiv_TopologyRefiner* topology_refiner,
+void getEdgeVertices(const OpenSubdiv_TopologyRefiner *topology_refiner,
const int edge_index,
- int edge_vertices_indices[2]) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
- OpenSubdiv::Far::ConstIndexArray array =
- base_level->GetEdgeVertices(edge_index);
+ int edge_vertices_indices[2])
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
+ OpenSubdiv::Far::ConstIndexArray array = base_level->GetEdgeVertices(edge_index);
assert(array.size() == 2);
edge_vertices_indices[0] = array[0];
edge_vertices_indices[1] = array[1];
}
-int getNumFacePtexFaces(const OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index) {
- const int num_face_vertices =
- topology_refiner->getNumFaceVertices(topology_refiner, face_index);
+int getNumFacePtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
+{
+ const int num_face_vertices = topology_refiner->getNumFaceVertices(topology_refiner, face_index);
if (num_face_vertices == 4) {
return 1;
- } else {
+ }
+ else {
return num_face_vertices;
}
}
-int getNumPtexFaces(const OpenSubdiv_TopologyRefiner* topology_refiner) {
+int getNumPtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner)
+{
const int num_faces = topology_refiner->getNumFaces(topology_refiner);
int num_ptex_faces = 0;
for (int face_index = 0; face_index < num_faces; ++face_index) {
- num_ptex_faces +=
- topology_refiner->getNumFacePtexFaces(topology_refiner, face_index);
+ num_ptex_faces += topology_refiner->getNumFacePtexFaces(topology_refiner, face_index);
}
return num_ptex_faces;
}
-void fillFacePtexIndexOffset(const OpenSubdiv_TopologyRefiner* topology_refiner,
- int* face_ptex_index_offset) {
+void fillFacePtexIndexOffset(const OpenSubdiv_TopologyRefiner *topology_refiner,
+ int *face_ptex_index_offset)
+{
const int num_faces = topology_refiner->getNumFaces(topology_refiner);
int num_ptex_faces = 0;
for (int face_index = 0; face_index < num_faces; ++face_index) {
face_ptex_index_offset[face_index] = num_ptex_faces;
- num_ptex_faces +=
- topology_refiner->getNumFacePtexFaces(topology_refiner, face_index);
+ num_ptex_faces += topology_refiner->getNumFacePtexFaces(topology_refiner, face_index);
}
}
////////////////////////////////////////////////////////////////////////////////
// Face-varying data.
-int getNumFVarChannels(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
+int getNumFVarChannels(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
return base_level->GetNumFVarChannels();
}
OpenSubdiv_FVarLinearInterpolation getFVarLinearInterpolation(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner) {
+ const struct OpenSubdiv_TopologyRefiner *topology_refiner)
+{
return opensubdiv_capi::getCAPIFVarLinearInterpolationFromOSD(
- getOSDTopologyRefiner(topology_refiner)->GetFVarLinearInterpolation());
+ getOSDTopologyRefiner(topology_refiner)->GetFVarLinearInterpolation());
}
-int getNumFVarValues(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int channel) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
+int getNumFVarValues(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int channel)
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
return base_level->GetNumFVarValues(channel);
}
-const int* getFaceFVarValueIndices(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index,
- const int channel) {
- const OpenSubdiv::Far::TopologyLevel* base_level =
- getOSDTopologyBaseLevel(topology_refiner);
+const int *getFaceFVarValueIndices(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int face_index,
+ const int channel)
+{
+ const OpenSubdiv::Far::TopologyLevel *base_level = getOSDTopologyBaseLevel(topology_refiner);
return &base_level->GetFaceFVarValues(face_index, channel)[0];
}
////////////////////////////////////////////////////////////////////////////////
// Internal helpers.
-void assignFunctionPointers(OpenSubdiv_TopologyRefiner* topology_refiner) {
+void assignFunctionPointers(OpenSubdiv_TopologyRefiner *topology_refiner)
+{
topology_refiner->getSubdivisionLevel = getSubdivisionLevel;
topology_refiner->getIsAdaptive = getIsAdaptive;
// Basic topology information.
@@ -212,27 +212,26 @@ void assignFunctionPointers(OpenSubdiv_TopologyRefiner* topology_refiner) {
topology_refiner->getFaceFVarValueIndices = getFaceFVarValueIndices;
}
-OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() {
- OpenSubdiv_TopologyRefiner* topology_refiner =
- OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner);
- topology_refiner->internal =
- OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefinerInternal);
+OpenSubdiv_TopologyRefiner *allocateTopologyRefiner()
+{
+ OpenSubdiv_TopologyRefiner *topology_refiner = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner);
+ topology_refiner->internal = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefinerInternal);
assignFunctionPointers(topology_refiner);
return topology_refiner;
}
} // namespace
-OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
- OpenSubdiv_Converter* converter,
- const OpenSubdiv_TopologyRefinerSettings* settings) {
- OpenSubdiv::Far::TopologyRefiner* osd_topology_refiner =
+OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter(
+ OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings)
+{
+ OpenSubdiv::Far::TopologyRefiner *osd_topology_refiner =
opensubdiv_capi::createOSDTopologyRefinerFromConverter(converter);
if (osd_topology_refiner == NULL) {
// Happens on empty or bad topology.
return NULL;
}
- OpenSubdiv_TopologyRefiner* topology_refiner = allocateTopologyRefiner();
+ OpenSubdiv_TopologyRefiner *topology_refiner = allocateTopologyRefiner();
topology_refiner->internal->osd_topology_refiner = osd_topology_refiner;
// Store setting which we want to keep track of and which can not be stored
// in OpenSubdiv's descriptor yet.
@@ -240,10 +239,9 @@ OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
return topology_refiner;
}
-void openSubdiv_deleteTopologyRefiner(
- OpenSubdiv_TopologyRefiner* topology_refiner) {
- OBJECT_GUARDED_DELETE(topology_refiner->internal,
- OpenSubdiv_TopologyRefinerInternal);
+void openSubdiv_deleteTopologyRefiner(OpenSubdiv_TopologyRefiner *topology_refiner)
+{
+ OBJECT_GUARDED_DELETE(topology_refiner->internal, OpenSubdiv_TopologyRefinerInternal);
OBJECT_GUARDED_DELETE(topology_refiner, OpenSubdiv_TopologyRefiner);
}
@@ -256,22 +254,20 @@ namespace {
///////////////////////////////////////////////////////////
// Quick preliminary checks.
-bool checkSchemeTypeMatches(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
- const OpenSubdiv::Sdc::SchemeType converter_scheme_type =
- opensubdiv_capi::getSchemeTypeFromCAPI(
- converter->getSchemeType(converter));
+bool checkSchemeTypeMatches(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
+ const OpenSubdiv::Sdc::SchemeType converter_scheme_type = opensubdiv_capi::getSchemeTypeFromCAPI(
+ converter->getSchemeType(converter));
return (converter_scheme_type == topology_refiner->GetSchemeType());
}
-bool checkOptionsMatches(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkOptionsMatches(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
typedef OpenSubdiv::Sdc::Options Options;
const Options options = topology_refiner->GetSchemeOptions();
- const Options::FVarLinearInterpolation fvar_interpolation =
- options.GetFVarLinearInterpolation();
+ const Options::FVarLinearInterpolation fvar_interpolation = options.GetFVarLinearInterpolation();
const Options::FVarLinearInterpolation converter_fvar_interpolation =
opensubdiv_capi::getFVarLinearInterpolationFromCAPI(
converter->getFVarLinearInterpolation(converter));
@@ -281,20 +277,19 @@ bool checkOptionsMatches(
return true;
}
-bool checkGeometryCountersMatches(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkGeometryCountersMatches(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
using OpenSubdiv::Far::TopologyLevel;
- const TopologyLevel& base_level = topology_refiner->GetLevel(0);
- return (
- (converter->getNumVertices(converter) == base_level.GetNumVertices()) &&
- (converter->getNumEdges(converter) == base_level.GetNumEdges()) &&
- (converter->getNumFaces(converter) == base_level.GetNumFaces()));
+ const TopologyLevel &base_level = topology_refiner->GetLevel(0);
+ return ((converter->getNumVertices(converter) == base_level.GetNumVertices()) &&
+ (converter->getNumEdges(converter) == base_level.GetNumEdges()) &&
+ (converter->getNumFaces(converter) == base_level.GetNumFaces()));
}
-bool checkPreliminaryMatches(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkPreliminaryMatches(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
return checkSchemeTypeMatches(topology_refiner, converter) &&
checkOptionsMatches(topology_refiner, converter) &&
checkGeometryCountersMatches(topology_refiner, converter);
@@ -315,29 +310,31 @@ class CyclicArray {
typedef int size_type;
static constexpr size_type npos = -1;
- explicit CyclicArray(const std::vector<int>& data)
- : data_(data.data()),
- size_(data.size()) {
+ explicit CyclicArray(const std::vector<int> &data) : data_(data.data()), size_(data.size())
+ {
}
- explicit CyclicArray(const OpenSubdiv::Far::ConstIndexArray& data)
- : data_(&data[0]),
- size_(data.size()) {
+ explicit CyclicArray(const OpenSubdiv::Far::ConstIndexArray &data)
+ : data_(&data[0]), size_(data.size())
+ {
}
- inline value_type operator[](int index) const {
+ inline value_type operator[](int index) const
+ {
assert(index >= 0);
// TODO(sergey): Check whether doing check for element index exceeding total
// number of indices prior to modulo helps performance.
return data_[index % size()];
}
- inline size_type size() const {
+ inline size_type size() const
+ {
return size_;
}
// Find index of first occurrence of a given value.
- inline size_type find(const value_type value) const {
+ inline size_type find(const value_type value) const
+ {
const int num_indices = size();
for (size_type i = 0; i < num_indices; ++i) {
if (value == (*this)[i]) {
@@ -348,14 +345,15 @@ class CyclicArray {
}
protected:
- const value_type* data_;
+ const value_type *data_;
const size_type size_;
};
-bool compareCyclicForward(const CyclicArray& array_a,
+bool compareCyclicForward(const CyclicArray &array_a,
const int start_a,
- const CyclicArray& array_b,
- const int start_b) {
+ const CyclicArray &array_b,
+ const int start_b)
+{
const int num_elements = array_a.size();
for (int i = 0; i < num_elements; ++i) {
if (array_a[start_a + i] != array_b[start_b + i]) {
@@ -365,15 +363,15 @@ bool compareCyclicForward(const CyclicArray& array_a,
return true;
}
-bool compareCyclicBackward(const CyclicArray& array_a,
+bool compareCyclicBackward(const CyclicArray &array_a,
const int start_a,
- const CyclicArray& array_b,
- const int start_b) {
+ const CyclicArray &array_b,
+ const int start_b)
+{
const int num_elements = array_a.size();
// TODO(sergey): Some optimization might be possible with memcmp trickery.
for (int i = 0; i < num_elements; ++i) {
- if (array_a[start_a + (num_elements - i - 1)] !=
- array_b[start_b + (num_elements - i - 1)]) {
+ if (array_a[start_a + (num_elements - i - 1)] != array_b[start_b + (num_elements - i - 1)]) {
return false;
}
}
@@ -389,8 +387,8 @@ bool compareCyclicBackward(const CyclicArray& array_a,
// TODO(sergey): Check whether this is needed, ot whether OpenSubdiv is only
// creating edges in a proper orientation without modifying indices of face
// verticies.
-bool checkVerticesOfFacesMatch(const CyclicArray& indices_a,
- const CyclicArray& indices_b) {
+bool checkVerticesOfFacesMatch(const CyclicArray &indices_a, const CyclicArray &indices_b)
+{
if (indices_a.size() != indices_a.size()) {
return false;
}
@@ -410,37 +408,34 @@ bool checkVerticesOfFacesMatch(const CyclicArray& indices_a,
return false;
}
-bool checkGeometryFacesMatch(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkGeometryFacesMatch(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
using OpenSubdiv::Far::ConstIndexArray;
using OpenSubdiv::Far::TopologyLevel;
- const TopologyLevel& base_level = topology_refiner->GetLevel(0);
+ const TopologyLevel &base_level = topology_refiner->GetLevel(0);
const int num_faces = base_level.GetNumFaces();
// TODO(sergey): Consider using data structure which keeps handful of
// elements on stack before doing heep allocation.
vector<int> conv_face_vertices;
for (int face_index = 0; face_index < num_faces; ++face_index) {
- const ConstIndexArray& face_vertices =
- base_level.GetFaceVertices(face_index);
+ const ConstIndexArray &face_vertices = base_level.GetFaceVertices(face_index);
const int num_face_vertices = face_vertices.size();
- if (num_face_vertices !=
- converter->getNumFaceVertices(converter, face_index)) {
+ if (num_face_vertices != converter->getNumFaceVertices(converter, face_index)) {
return false;
}
conv_face_vertices.resize(num_face_vertices);
converter->getFaceVertices(converter, face_index, &conv_face_vertices[0]);
- if (!checkVerticesOfFacesMatch(CyclicArray(conv_face_vertices),
- CyclicArray(face_vertices))) {
+ if (!checkVerticesOfFacesMatch(CyclicArray(conv_face_vertices), CyclicArray(face_vertices))) {
return false;
}
}
return true;
}
-bool checkGeometryMatches(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkGeometryMatches(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
// NOTE: Since OpenSubdiv's topology refiner doesn't contain loose edges, we
// are only checking for faces to be matched. Changes in edges we don't care
// here too much (they'll be checked for creases changes later).
@@ -450,11 +445,11 @@ bool checkGeometryMatches(
///////////////////////////////////////////////////////////
// Compare attributes which affects on topology
-inline bool checkSingleEdgeSharpnessMatch(
- const OpenSubdiv::Far::TopologyLevel& base_level,
- int base_level_edge_index,
- const OpenSubdiv_Converter* converter,
- int converter_edge_index) {
+inline bool checkSingleEdgeSharpnessMatch(const OpenSubdiv::Far::TopologyLevel &base_level,
+ int base_level_edge_index,
+ const OpenSubdiv_Converter *converter,
+ int converter_edge_index)
+{
// NOTE: Boundary and non-manifold edges are internally forced to an infinite
// sharpness. So we can not reliably compare those.
//
@@ -464,36 +459,34 @@ inline bool checkSingleEdgeSharpnessMatch(
return true;
}
const float sharpness = base_level.GetEdgeSharpness(base_level_edge_index);
- const float converter_sharpness =
- converter->getEdgeSharpness(converter, converter_edge_index);
+ const float converter_sharpness = converter->getEdgeSharpness(converter, converter_edge_index);
if (sharpness != converter_sharpness) {
return false;
}
return true;
}
-inline bool checkSingleEdgeTagMatch(
- const OpenSubdiv::Far::TopologyLevel& base_level,
- int base_level_edge_index,
- const OpenSubdiv_Converter* converter,
- int converter_edge_index) {
- return checkSingleEdgeSharpnessMatch(base_level, base_level_edge_index,
- converter, converter_edge_index);
+inline bool checkSingleEdgeTagMatch(const OpenSubdiv::Far::TopologyLevel &base_level,
+ int base_level_edge_index,
+ const OpenSubdiv_Converter *converter,
+ int converter_edge_index)
+{
+ return checkSingleEdgeSharpnessMatch(
+ base_level, base_level_edge_index, converter, converter_edge_index);
}
// Compares edge tags between topology refiner and converter in a case when
// converter specifies a full topology.
// This is simplest loop, since we know that order of edges matches.
-bool checkEdgeTagsMatchFullTopology(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkEdgeTagsMatchFullTopology(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
using OpenSubdiv::Far::ConstIndexArray;
using OpenSubdiv::Far::TopologyLevel;
- const TopologyLevel& base_level = topology_refiner->GetLevel(0);
+ const TopologyLevel &base_level = topology_refiner->GetLevel(0);
const int num_edges = base_level.GetNumEdges();
for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
- if (!checkSingleEdgeTagMatch(
- base_level, edge_index, converter, edge_index)) {
+ if (!checkSingleEdgeTagMatch(base_level, edge_index, converter, edge_index)) {
return false;
}
}
@@ -503,12 +496,12 @@ bool checkEdgeTagsMatchFullTopology(
// Compares tags of edges in the case when orientation of edges is left up to
// OpenSubdiv. In this case we do need to take care of mapping edges from the
// converter to current topology refiner, since the order is not guaranteed.
-bool checkEdgeTagsMatchAutoOrient(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkEdgeTagsMatchAutoOrient(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
using OpenSubdiv::Far::ConstIndexArray;
using OpenSubdiv::Far::TopologyLevel;
- const TopologyLevel& base_level = topology_refiner->GetLevel(0);
+ const TopologyLevel &base_level = topology_refiner->GetLevel(0);
const int num_edges = base_level.GetNumEdges();
// Create mapping for quick lookup of edge index from its verticies indices.
//
@@ -520,41 +513,39 @@ bool checkEdgeTagsMatchAutoOrient(
edge_map.insert(edge_vertices[0], edge_vertices[1], edge_index);
}
// Compare all edges.
- for (int converter_edge_index = 0;
- converter_edge_index < num_edges;
- ++converter_edge_index) {
+ for (int converter_edge_index = 0; converter_edge_index < num_edges; ++converter_edge_index) {
// Get edge verticies indices, and lookup corresponding edge index in the
// base topology level.
int edge_vertices[2];
converter->getEdgeVertices(converter, converter_edge_index, edge_vertices);
- const int base_level_edge_index = edge_map.at(
- edge_vertices[0], edge_vertices[1]);
+ const int base_level_edge_index = edge_map.at(edge_vertices[0], edge_vertices[1]);
// Perform actual test.
if (!checkSingleEdgeTagMatch(
- base_level, base_level_edge_index, converter, converter_edge_index)) {
+ base_level, base_level_edge_index, converter, converter_edge_index)) {
return false;
}
}
return true;
}
-bool checkEdgeTagsMatch(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkEdgeTagsMatch(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
if (converter->specifiesFullTopology(converter)) {
return checkEdgeTagsMatchFullTopology(topology_refiner, converter);
- } else {
+ }
+ else {
return checkEdgeTagsMatchAutoOrient(topology_refiner, converter);
}
}
-bool checkvertexSharpnessMatch(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkvertexSharpnessMatch(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
using OpenSubdiv::Far::ConstIndexArray;
using OpenSubdiv::Far::TopologyLevel;
using OpenSubdiv::Sdc::Crease;
- const TopologyLevel& base_level = topology_refiner->GetLevel(0);
+ const TopologyLevel &base_level = topology_refiner->GetLevel(0);
// Create mapping for quick lookup of edge index from its verticies indices.
//
// TODO(sergey): Consider caching it in some sort of wrapper around topology
@@ -573,7 +564,8 @@ bool checkvertexSharpnessMatch(
if (current_sharpness != Crease::SHARPNESS_INFINITE) {
return false;
}
- } else {
+ }
+ else {
ConstIndexArray vertex_edges = base_level.GetVertexEdges(vertex_index);
float sharpness = converter->getVertexSharpness(converter, vertex_index);
if (vertex_edges.size() == 2) {
@@ -587,10 +579,8 @@ bool checkvertexSharpnessMatch(
const int edge0_converter_index = edge_map[edge0_key];
const int edge1_converter_index = edge_map[edge1_key];
// Lookup sharpness.
- const float sharpness0 = converter->getEdgeSharpness(
- converter, edge0_converter_index);
- const float sharpness1 = converter->getEdgeSharpness(
- converter, edge1_converter_index);
+ const float sharpness0 = converter->getEdgeSharpness(converter, edge0_converter_index);
+ const float sharpness1 = converter->getEdgeSharpness(converter, edge1_converter_index);
// TODO(sergey): Find a better mixing between edge and vertex sharpness.
sharpness += min(sharpness0, sharpness1);
sharpness = min(sharpness, 10.0f);
@@ -603,20 +593,19 @@ bool checkvertexSharpnessMatch(
return true;
}
-bool checkSingleUVLayerMatch(
- const OpenSubdiv::Far::TopologyLevel& base_level,
- const OpenSubdiv_Converter* converter,
- const int layer_index) {
+bool checkSingleUVLayerMatch(const OpenSubdiv::Far::TopologyLevel &base_level,
+ const OpenSubdiv_Converter *converter,
+ const int layer_index)
+{
converter->precalcUVLayer(converter, layer_index);
const int num_faces = base_level.GetNumFaces();
// TODO(sergey): Need to check whether converter changed the winding of
// face to match OpenSubdiv's expectations.
for (int face_index = 0; face_index < num_faces; ++face_index) {
- OpenSubdiv::Far::ConstIndexArray base_level_face_uvs =
- base_level.GetFaceFVarValues(face_index, layer_index);
+ OpenSubdiv::Far::ConstIndexArray base_level_face_uvs = base_level.GetFaceFVarValues(
+ face_index, layer_index);
for (int corner = 0; corner < base_level_face_uvs.size(); ++corner) {
- const int uv_index =
- converter->getFaceCornerUVIndex(converter, face_index, corner);
+ const int uv_index = converter->getFaceCornerUVIndex(converter, face_index, corner);
if (base_level_face_uvs[corner] != uv_index) {
converter->finishUVLayer(converter);
return false;
@@ -627,12 +616,12 @@ bool checkSingleUVLayerMatch(
return true;
}
-bool checkUVLayersMatch(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkUVLayersMatch(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
using OpenSubdiv::Far::TopologyLevel;
const int num_layers = converter->getNumUVLayers(converter);
- const TopologyLevel& base_level = topology_refiner->GetLevel(0);
+ const TopologyLevel &base_level = topology_refiner->GetLevel(0);
// Number of UV layers should match.
if (base_level.GetNumFVarChannels() != num_layers) {
return false;
@@ -645,9 +634,9 @@ bool checkUVLayersMatch(
return true;
}
-bool checkTopologyAttributesMatch(
- const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
+bool checkTopologyAttributesMatch(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
return checkEdgeTagsMatch(topology_refiner, converter) &&
checkvertexSharpnessMatch(topology_refiner, converter) &&
checkUVLayersMatch(topology_refiner, converter);
@@ -657,10 +646,9 @@ bool checkTopologyAttributesMatch(
} // namespace opensubdiv_capi
bool openSubdiv_topologyRefinerCompareWithConverter(
- const OpenSubdiv_TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter) {
- const OpenSubdiv::Far::TopologyRefiner* refiner =
- getOSDTopologyRefiner(topology_refiner);
+ const OpenSubdiv_TopologyRefiner *topology_refiner, const OpenSubdiv_Converter *converter)
+{
+ const OpenSubdiv::Far::TopologyRefiner *refiner = getOSDTopologyRefiner(topology_refiner);
return (opensubdiv_capi::checkPreliminaryMatches(refiner, converter) &&
opensubdiv_capi::checkGeometryMatches(refiner, converter) &&
opensubdiv_capi::checkTopologyAttributesMatch(refiner, converter));
diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc
index 4636679761f..f3054a17da2 100644
--- a/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc
@@ -19,8 +19,11 @@
#include "internal/opensubdiv_topology_refiner_internal.h"
OpenSubdiv_TopologyRefinerInternal::OpenSubdiv_TopologyRefinerInternal()
- : osd_topology_refiner(NULL) {}
+ : osd_topology_refiner(NULL)
+{
+}
-OpenSubdiv_TopologyRefinerInternal::~OpenSubdiv_TopologyRefinerInternal() {
+OpenSubdiv_TopologyRefinerInternal::~OpenSubdiv_TopologyRefinerInternal()
+{
delete osd_topology_refiner;
}
diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h
index f7ca6a7ad5e..b0f5d4079ef 100644
--- a/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h
@@ -32,7 +32,7 @@ struct OpenSubdiv_TopologyRefinerInternal {
OpenSubdiv_TopologyRefinerInternal();
~OpenSubdiv_TopologyRefinerInternal();
- OpenSubdiv::Far::TopologyRefiner* osd_topology_refiner;
+ OpenSubdiv::Far::TopologyRefiner *osd_topology_refiner;
// Subdivision settingsa this refiner is created for.
//
diff --git a/intern/opensubdiv/internal/opensubdiv_util.cc b/intern/opensubdiv/internal/opensubdiv_util.cc
index 040c9a07512..6e6f3a0920f 100644
--- a/intern/opensubdiv/internal/opensubdiv_util.cc
+++ b/intern/opensubdiv/internal/opensubdiv_util.cc
@@ -25,17 +25,19 @@
namespace opensubdiv_capi {
-void stringSplit(vector<string>* tokens,
- const string& str,
- const string& separators,
- bool skip_empty) {
+void stringSplit(vector<string> *tokens,
+ const string &str,
+ const string &separators,
+ bool skip_empty)
+{
size_t token_start = 0, token_length = 0;
for (size_t i = 0; i < str.length(); ++i) {
const char ch = str[i];
if (separators.find(ch) == string::npos) {
// Append non-separator char to a token.
++token_length;
- } else {
+ }
+ else {
// Append current token to the list (if any).
if (token_length > 0 || !skip_empty) {
string token = str.substr(token_start, token_length);
@@ -48,8 +50,7 @@ void stringSplit(vector<string>* tokens,
}
// Append token which might be at the end of the string.
if ((token_length != 0) ||
- (!skip_empty && token_start > 0 &&
- separators.find(str[token_start-1]) != string::npos)) {
+ (!skip_empty && token_start > 0 && separators.find(str[token_start - 1]) != string::npos)) {
string token = str.substr(token_start, token_length);
tokens->push_back(token);
}
diff --git a/intern/opensubdiv/internal/opensubdiv_util.h b/intern/opensubdiv/internal/opensubdiv_util.h
index 067c194478c..7817ebac96e 100644
--- a/intern/opensubdiv/internal/opensubdiv_util.h
+++ b/intern/opensubdiv/internal/opensubdiv_util.h
@@ -46,9 +46,9 @@ using std::vector;
#define STRINGIFY_APPEND(a, b) "" a #b
#define STRINGIFY(x) STRINGIFY_APPEND("", x)
-void stringSplit(vector<string>* tokens,
- const string& str,
- const string& separators,
+void stringSplit(vector<string> *tokens,
+ const string &str,
+ const string &separators,
bool skip_empty);
} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/opensubdiv_capi_type.h b/intern/opensubdiv/opensubdiv_capi_type.h
index 57f62fd9888..35eeb71dede 100644
--- a/intern/opensubdiv/opensubdiv_capi_type.h
+++ b/intern/opensubdiv/opensubdiv_capi_type.h
@@ -26,12 +26,12 @@ extern "C" {
// Keep this a bitmask os it's possible to pass available
// evaluators to Blender.
typedef enum eOpenSubdivEvaluator {
- OPENSUBDIV_EVALUATOR_CPU = (1 << 0),
- OPENSUBDIV_EVALUATOR_OPENMP = (1 << 1),
- OPENSUBDIV_EVALUATOR_OPENCL = (1 << 2),
- OPENSUBDIV_EVALUATOR_CUDA = (1 << 3),
+ OPENSUBDIV_EVALUATOR_CPU = (1 << 0),
+ OPENSUBDIV_EVALUATOR_OPENMP = (1 << 1),
+ OPENSUBDIV_EVALUATOR_OPENCL = (1 << 2),
+ OPENSUBDIV_EVALUATOR_CUDA = (1 << 3),
OPENSUBDIV_EVALUATOR_GLSL_TRANSFORM_FEEDBACK = (1 << 4),
- OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5),
+ OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5),
} eOpenSubdivEvaluator;
typedef enum OpenSubdiv_SchemeType {
diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h
index 389e16e0f3f..2f3850665c2 100644
--- a/intern/opensubdiv/opensubdiv_converter_capi.h
+++ b/intern/opensubdiv/opensubdiv_converter_capi.h
@@ -28,13 +28,12 @@ extern "C" {
#endif
typedef struct OpenSubdiv_Converter {
- OpenSubdiv_SchemeType (*getSchemeType)(
- const struct OpenSubdiv_Converter* converter);
+ OpenSubdiv_SchemeType (*getSchemeType)(const struct OpenSubdiv_Converter *converter);
OpenSubdiv_VtxBoundaryInterpolation (*getVtxBoundaryInterpolation)(
- const struct OpenSubdiv_Converter* converter);
+ const struct OpenSubdiv_Converter *converter);
OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)(
- const struct OpenSubdiv_Converter* converter);
+ const struct OpenSubdiv_Converter *converter);
// Denotes whether this converter specifies full topology, which includes
// vertices, edges, faces, vertices+edges of a face and edges/faces of a
@@ -45,26 +44,25 @@ typedef struct OpenSubdiv_Converter {
// NOTE: Even if converter does not provide full topology, it still needs
// to provide number of edges and vertices-of-edge. Those are used to assign
// topology tags.
- bool (*specifiesFullTopology)(const struct OpenSubdiv_Converter* converter);
+ bool (*specifiesFullTopology)(const struct OpenSubdiv_Converter *converter);
//////////////////////////////////////////////////////////////////////////////
// Global geometry counters.
// Number of faces/edges/vertices in the base mesh.
- int (*getNumFaces)(const struct OpenSubdiv_Converter* converter);
- int (*getNumEdges)(const struct OpenSubdiv_Converter* converter);
- int (*getNumVertices)(const struct OpenSubdiv_Converter* converter);
+ int (*getNumFaces)(const struct OpenSubdiv_Converter *converter);
+ int (*getNumEdges)(const struct OpenSubdiv_Converter *converter);
+ int (*getNumVertices)(const struct OpenSubdiv_Converter *converter);
//////////////////////////////////////////////////////////////////////////////
// Face relationships.
// Number of vertices the face consists of.
- int (*getNumFaceVertices)(const struct OpenSubdiv_Converter* converter,
- const int face_index);
+ int (*getNumFaceVertices)(const struct OpenSubdiv_Converter *converter, const int face_index);
// Array of vertex indices the face consists of.
- void (*getFaceVertices)(const struct OpenSubdiv_Converter* converter,
+ void (*getFaceVertices)(const struct OpenSubdiv_Converter *converter,
const int face_index,
- int* face_vertices);
+ int *face_vertices);
// Array of edge indices the face consists of.
// Aligned with the vertex indices array, edge i connects face vertex i
// with face index i+1.
@@ -76,45 +74,41 @@ typedef struct OpenSubdiv_Converter {
// Edge relationships.
// Vertices the edge consists of.
- void (*getEdgeVertices)(const struct OpenSubdiv_Converter* converter,
+ void (*getEdgeVertices)(const struct OpenSubdiv_Converter *converter,
const int edge_index,
int edge_vertices[2]);
// Number of faces which are sharing the given edge.
- int (*getNumEdgeFaces)(const struct OpenSubdiv_Converter* converter,
- const int edge_index);
+ int (*getNumEdgeFaces)(const struct OpenSubdiv_Converter *converter, const int edge_index);
// Array of face indices which are sharing the given edge.
- void (*getEdgeFaces)(const struct OpenSubdiv_Converter* converter,
+ void (*getEdgeFaces)(const struct OpenSubdiv_Converter *converter,
const int edge,
- int* edge_faces);
+ int *edge_faces);
// Edge sharpness (aka crease).
- float (*getEdgeSharpness)(const struct OpenSubdiv_Converter* converter,
- const int edge_index);
+ float (*getEdgeSharpness)(const struct OpenSubdiv_Converter *converter, const int edge_index);
//////////////////////////////////////////////////////////////////////////////
// Vertex relationships.
// Number of edges which are adjacent to the given vertex.
- int (*getNumVertexEdges)(const struct OpenSubdiv_Converter* converter,
- const int vertex_index);
+ int (*getNumVertexEdges)(const struct OpenSubdiv_Converter *converter, const int vertex_index);
// Array fo edge indices which are adjacent to the given vertex.
- void (*getVertexEdges)(const struct OpenSubdiv_Converter* converter,
+ void (*getVertexEdges)(const struct OpenSubdiv_Converter *converter,
const int vertex_index,
- int* vertex_edges);
+ int *vertex_edges);
// Number of faces which are adjacent to the given vertex.
- int (*getNumVertexFaces)(const struct OpenSubdiv_Converter* converter,
- const int vertex_index);
+ int (*getNumVertexFaces)(const struct OpenSubdiv_Converter *converter, const int vertex_index);
// Array fo face indices which are adjacent to the given vertex.
- void (*getVertexFaces)(const struct OpenSubdiv_Converter* converter,
+ void (*getVertexFaces)(const struct OpenSubdiv_Converter *converter,
const int vertex_index,
- int* vertex_faces);
+ int *vertex_faces);
// Check whether vertex is to be marked as an infinite sharp.
// This is a way to make sharp vertices which are adjacent to a loose edges.
- bool (*isInfiniteSharpVertex)(const struct OpenSubdiv_Converter* converter,
+ bool (*isInfiniteSharpVertex)(const struct OpenSubdiv_Converter *converter,
const int vertex_index);
// If vertex is not infinitely sharp, this is it's actual sharpness.
- float (*getVertexSharpness)(const struct OpenSubdiv_Converter* converter,
+ float (*getVertexSharpness)(const struct OpenSubdiv_Converter *converter,
const int vertex_index);
//////////////////////////////////////////////////////////////////////////////
@@ -124,7 +118,7 @@ typedef struct OpenSubdiv_Converter {
// UV coordinates.
// Number of UV layers.
- int (*getNumUVLayers)(const struct OpenSubdiv_Converter* converter);
+ int (*getNumUVLayers)(const struct OpenSubdiv_Converter *converter);
// We need some corner connectivity information, which might not be trivial
// to be gathered (might require multiple matching calculations per corver
@@ -134,24 +128,23 @@ typedef struct OpenSubdiv_Converter {
// complex complex-to-calculate information.
// finish() is called after converter is done porting UV layer to OpenSubdiv,
// allowing to free cached data.
- void (*precalcUVLayer)(const struct OpenSubdiv_Converter* converter,
- const int layer_index);
- void (*finishUVLayer)(const struct OpenSubdiv_Converter* converter);
+ void (*precalcUVLayer)(const struct OpenSubdiv_Converter *converter, const int layer_index);
+ void (*finishUVLayer)(const struct OpenSubdiv_Converter *converter);
// Get number of UV coordinates in the current layer (layer which was
// specified in precalcUVLayer().
- int (*getNumUVCoordinates)(const struct OpenSubdiv_Converter* converter);
+ int (*getNumUVCoordinates)(const struct OpenSubdiv_Converter *converter);
// For the given face index and its corner (known as loop in Blender)
// get corrsponding UV coordinate index.
- int (*getFaceCornerUVIndex)(const struct OpenSubdiv_Converter* converter,
+ int (*getFaceCornerUVIndex)(const struct OpenSubdiv_Converter *converter,
const int face_index,
const int corner_index);
//////////////////////////////////////////////////////////////////////////////
// User data associated with this converter.
- void (*freeUserData)(const struct OpenSubdiv_Converter* converter);
- void* user_data;
+ void (*freeUserData)(const struct OpenSubdiv_Converter *converter);
+ void *user_data;
} OpenSubdiv_Converter;
#ifdef __cplusplus
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.h b/intern/opensubdiv/opensubdiv_evaluator_capi.h
index eda5d614635..ceb0c58feba 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.h
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.h
@@ -28,29 +28,30 @@ struct OpenSubdiv_TopologyRefiner;
typedef struct OpenSubdiv_Evaluator {
// Set coarse positions from a continuous array of coordinates.
- void (*setCoarsePositions)(struct OpenSubdiv_Evaluator* evaluator,
- const float* positions,
+ void (*setCoarsePositions)(struct OpenSubdiv_Evaluator *evaluator,
+ const float *positions,
const int start_vertex_index,
const int num_vertices);
// Set varying data from a continuous array of data.
- void (*setVaryingData)(struct OpenSubdiv_Evaluator* evaluator,
- const float* varying_data,
- const int start_vertex_index, const int num_vertices);
+ void (*setVaryingData)(struct OpenSubdiv_Evaluator *evaluator,
+ const float *varying_data,
+ const int start_vertex_index,
+ const int num_vertices);
// Set face varying data from a continuous array of data.
//
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
- void (*setFaceVaryingData)(struct OpenSubdiv_Evaluator* evaluator,
+ void (*setFaceVaryingData)(struct OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
- const float* face_varying_data,
+ const float *face_varying_data,
const int start_vertex_index,
const int num_vertices);
// Set coarse vertex position from a continuous memory buffer where
// first coordinate starts at offset of `start_offset` and there is `stride`
// bytes between adjacent vertex coordinates.
- void (*setCoarsePositionsFromBuffer)(struct OpenSubdiv_Evaluator* evaluator,
- const void* buffer,
+ void (*setCoarsePositionsFromBuffer)(struct OpenSubdiv_Evaluator *evaluator,
+ const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
@@ -58,8 +59,8 @@ typedef struct OpenSubdiv_Evaluator {
// Set varying data from a continuous memory buffer where
// first coordinate starts at offset of `start_offset` and there is `stride`
// bytes between adjacent vertex coordinates.
- void (*setVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator* evaluator,
- const void* buffer,
+ void (*setVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator *evaluator,
+ const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
@@ -70,48 +71,53 @@ typedef struct OpenSubdiv_Evaluator {
//
// TODO(sergey): Find a better name for vertex here. It is not the vertex of
// geometry, but a vertex of UV map.
- void (*setFaceVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator* evaluator,
+ void (*setFaceVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
- const void* buffer,
+ const void *buffer,
const int start_offset,
const int stride,
const int start_vertex_index,
const int num_vertices);
// Refine after coarse positions update.
- void (*refine)(struct OpenSubdiv_Evaluator* evaluator);
+ void (*refine)(struct OpenSubdiv_Evaluator *evaluator);
// Evaluate given ptex face at given bilinear coordinate.
// If derivatives are NULL, they will not be evaluated.
- void (*evaluateLimit)(struct OpenSubdiv_Evaluator* evaluator,
+ void (*evaluateLimit)(struct OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
- float face_u, float face_v,
- float P[3], float dPdu[3], float dPdv[3]);
+ float face_u,
+ float face_v,
+ float P[3],
+ float dPdu[3],
+ float dPdv[3]);
// Evaluate varying data at a given bilinear coordinate of given ptex face.
- void (*evaluateVarying)(struct OpenSubdiv_Evaluator* evaluator,
+ void (*evaluateVarying)(struct OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
- float face_u, float face_v,
+ float face_u,
+ float face_v,
float varying[3]);
// Evaluate face-varying data at a given bilinear coordinate of given
// ptex face.
- void (*evaluateFaceVarying)(struct OpenSubdiv_Evaluator* evaluator,
+ void (*evaluateFaceVarying)(struct OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
const int ptex_face_index,
- float face_u, float face_v,
+ float face_u,
+ float face_v,
float face_varying[2]);
// Internal storage for the use in this module only.
//
// This is where actual OpenSubdiv's evaluator is living.
- struct OpenSubdiv_EvaluatorInternal* internal;
+ struct OpenSubdiv_EvaluatorInternal *internal;
} OpenSubdiv_Evaluator;
-OpenSubdiv_Evaluator* openSubdiv_createEvaluatorFromTopologyRefiner(
- struct OpenSubdiv_TopologyRefiner* topology_refiner);
+OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
+ struct OpenSubdiv_TopologyRefiner *topology_refiner);
-void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator* evaluator);
+void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator *evaluator);
#ifdef __cplusplus
}
diff --git a/intern/opensubdiv/opensubdiv_gl_mesh_capi.h b/intern/opensubdiv/opensubdiv_gl_mesh_capi.h
index 971f6b9dcd3..f7dd6f83434 100644
--- a/intern/opensubdiv/opensubdiv_gl_mesh_capi.h
+++ b/intern/opensubdiv/opensubdiv_gl_mesh_capi.h
@@ -35,30 +35,30 @@ typedef struct OpenSubdiv_GLMesh {
// Subdivision/topology part.
// Returns the GL index buffer containing the patch control vertices.
- unsigned int (*getPatchIndexBuffer)(struct OpenSubdiv_GLMesh* gl_mesh);
+ unsigned int (*getPatchIndexBuffer)(struct OpenSubdiv_GLMesh *gl_mesh);
// Bind GL buffer which contains vertices (VBO).
// TODO(sergey): Is this a coarse vertices?
- void (*bindVertexBuffer)(struct OpenSubdiv_GLMesh* gl_mesh);
+ void (*bindVertexBuffer)(struct OpenSubdiv_GLMesh *gl_mesh);
// Set coarse positions from a continuous array of coordinates.
- void (*setCoarsePositions)(struct OpenSubdiv_GLMesh* gl_mesh,
- const float* positions,
+ void (*setCoarsePositions)(struct OpenSubdiv_GLMesh *gl_mesh,
+ const float *positions,
const int start_vertex,
const int num_vertices);
// TODO(sergey): setCoarsePositionsFromBuffer().
// Refine after coarse positions update.
- void (*refine)(struct OpenSubdiv_GLMesh* gl_mesh);
+ void (*refine)(struct OpenSubdiv_GLMesh *gl_mesh);
// Synchronize after coarse positions update and refine.
- void (*synchronize)(struct OpenSubdiv_GLMesh* gl_mesh);
+ void (*synchronize)(struct OpenSubdiv_GLMesh *gl_mesh);
//////////////////////////////////////////////////////////////////////////////
// Drawing part.
// Prepare mesh for display.
- void (*prepareDraw)(struct OpenSubdiv_GLMesh* gl_mesh,
+ void (*prepareDraw)(struct OpenSubdiv_GLMesh *gl_mesh,
const bool use_osd_glsl,
const int active_uv_index);
@@ -67,17 +67,17 @@ typedef struct OpenSubdiv_GLMesh {
// If fill_quads is false, then patches are drawn in wireframe.
void (*drawPatches)(struct OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
- const int start_patch, const int num_patches);
+ const int start_patch,
+ const int num_patches);
// Internal storage for the use in this module only.
//
// Tease: This contains an actual OpenSubdiv's Mesh object.
- struct OpenSubdiv_GLMeshInternal* internal;
+ struct OpenSubdiv_GLMeshInternal *internal;
} OpenSubdiv_GLMesh;
-OpenSubdiv_GLMesh* openSubdiv_createOsdGLMeshFromTopologyRefiner(
- struct OpenSubdiv_TopologyRefiner* topology_refiner,
- eOpenSubdivEvaluator evaluator_type);
+OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
+ struct OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type);
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh);
diff --git a/intern/opensubdiv/opensubdiv_topology_refiner_capi.h b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h
index 771eb8d62a8..cf7f59adf2f 100644
--- a/intern/opensubdiv/opensubdiv_topology_refiner_capi.h
+++ b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h
@@ -42,10 +42,8 @@ typedef struct OpenSubdiv_TopologyRefinerSettings {
typedef struct OpenSubdiv_TopologyRefiner {
// Query subdivision level the refiner is created for.
- int (*getSubdivisionLevel)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
- bool (*getIsAdaptive)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
+ int (*getSubdivisionLevel)(const struct OpenSubdiv_TopologyRefiner *topology_refiner);
+ bool (*getIsAdaptive)(const struct OpenSubdiv_TopologyRefiner *topology_refiner);
// NOTE: All queries are querying base level.
//
@@ -57,30 +55,22 @@ typedef struct OpenSubdiv_TopologyRefiner {
//////////////////////////////////////////////////////////////////////////////
// Query basic topology information from base level.
- int (*getNumVertices)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
- int (*getNumEdges)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
- int (*getNumFaces)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
- int (*getNumFaceVertices)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index);
- void (*getFaceVertices)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index,
- int* face_vertices_indices);
- int (*getNumFaceEdges)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index);
- void (*getFaceEdges)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index,
- int* face_edges_indices);
- void (*getEdgeVertices)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int edge_index,
- int edge_vertices_indices[2]);
+ int (*getNumVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner);
+ int (*getNumEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner);
+ int (*getNumFaces)(const struct OpenSubdiv_TopologyRefiner *topology_refiner);
+ int (*getNumFaceVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int face_index);
+ void (*getFaceVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int face_index,
+ int *face_vertices_indices);
+ int (*getNumFaceEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int face_index);
+ void (*getFaceEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int face_index,
+ int *face_edges_indices);
+ void (*getEdgeVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int edge_index,
+ int edge_vertices_indices[2]);
//////////////////////////////////////////////////////////////////////////////
// PTex face geometry queries.
@@ -92,11 +82,9 @@ typedef struct OpenSubdiv_TopologyRefiner {
// - Quad face consists of a single ptex face.
// - N-gons (similar to triangle) consists of N ptex faces, ordered same
// way as for triangle.
- int (*getNumFacePtexFaces)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index);
- int (*getNumPtexFaces)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
+ int (*getNumFacePtexFaces)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int face_index);
+ int (*getNumPtexFaces)(const struct OpenSubdiv_TopologyRefiner *topology_refiner);
// Initialize a per-base-face offset measured in ptex face indices.
//
@@ -104,31 +92,27 @@ typedef struct OpenSubdiv_TopologyRefiner {
// faces created for bases faces [0 .. base_face_index - 1].
//
// The array must contain at least total number of ptex faces elements.
- void (*fillFacePtexIndexOffset)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- int* face_ptex_index_offset);
+ void (*fillFacePtexIndexOffset)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ int *face_ptex_index_offset);
//////////////////////////////////////////////////////////////////////////////
// Face-varying data.
// Number of face-varying channels (or how they are called in Blender layers).
- int (*getNumFVarChannels)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
+ int (*getNumFVarChannels)(const struct OpenSubdiv_TopologyRefiner *topology_refiner);
// Get face-varying interpolation type.
OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner);
+ const struct OpenSubdiv_TopologyRefiner *topology_refiner);
// Get total number of face-varying values in a particular channel.
- int (*getNumFVarValues)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int channel);
+ int (*getNumFVarValues)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int channel);
// Get face-varying value indices associated with a particular face.
//
// This is an array of indices inside of face-varying array, array elements
// are aligned with face corners (or loops in Blender terminology).
- const int* (*getFaceFVarValueIndices)(
- const struct OpenSubdiv_TopologyRefiner* topology_refiner,
- const int face_index,
- const int channel);
+ const int *(*getFaceFVarValueIndices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
+ const int face_index,
+ const int channel);
//////////////////////////////////////////////////////////////////////////////
// Internal use.
@@ -137,17 +121,15 @@ typedef struct OpenSubdiv_TopologyRefiner {
//
// Tease: Contains actual OpenSubdiv's refiner and (optionally) some other
// data and state needed for an internbal use.
- struct OpenSubdiv_TopologyRefinerInternal* internal;
+ struct OpenSubdiv_TopologyRefinerInternal *internal;
} OpenSubdiv_TopologyRefiner;
// NOTE: Will return NULL in cases of bad topology.
// NOTE: Mesh without faces is considered a bad topology.
-OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
- struct OpenSubdiv_Converter* converter,
- const OpenSubdiv_TopologyRefinerSettings* settings);
+OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter(
+ struct OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings);
-void openSubdiv_deleteTopologyRefiner(
- OpenSubdiv_TopologyRefiner* topology_refiner);
+void openSubdiv_deleteTopologyRefiner(OpenSubdiv_TopologyRefiner *topology_refiner);
// Compare given topology refiner with converter. Returns truth if topology
// refiner matches given converter, false otherwise.
@@ -156,8 +138,8 @@ void openSubdiv_deleteTopologyRefiner(
// and compare with existing refiner before going into more computationally
// complicated parts of subdivision process.
bool openSubdiv_topologyRefinerCompareWithConverter(
- const OpenSubdiv_TopologyRefiner* topology_refiner,
- const struct OpenSubdiv_Converter* converter);
+ const OpenSubdiv_TopologyRefiner *topology_refiner,
+ const struct OpenSubdiv_Converter *converter);
#ifdef __cplusplus
}
diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl
index 76a18df8c32..7f08182d78a 100644
--- a/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl
+++ b/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl
@@ -18,34 +18,35 @@
*/
struct VertexData {
- vec4 position;
- vec3 normal;
- vec2 uv;
+ vec4 position;
+ vec3 normal;
+ vec2 uv;
};
#define MAX_LIGHTS 8
#define NUM_SOLID_LIGHTS 3
struct LightSource {
- vec4 position;
- vec4 ambient;
- vec4 diffuse;
- vec4 specular;
- vec4 spotDirection;
+ vec4 position;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 spotDirection;
#ifdef SUPPORT_COLOR_MATERIAL
- float constantAttenuation;
- float linearAttenuation;
- float quadraticAttenuation;
- float spotCutoff;
- float spotExponent;
- float spotCosCutoff;
- float pad, pad2;
+ float constantAttenuation;
+ float linearAttenuation;
+ float quadraticAttenuation;
+ float spotCutoff;
+ float spotExponent;
+ float spotCosCutoff;
+ float pad, pad2;
#endif
};
-layout(std140) uniform Lighting {
- LightSource lightSource[MAX_LIGHTS];
- int num_enabled_lights;
+layout(std140) uniform Lighting
+{
+ LightSource lightSource[MAX_LIGHTS];
+ int num_enabled_lights;
};
uniform vec4 diffuse;
@@ -54,113 +55,109 @@ uniform float shininess;
uniform sampler2D texture_buffer;
-in block {
- VertexData v;
-} inpt;
+in block
+{
+ VertexData v;
+}
+inpt;
void main()
{
#ifdef WIREFRAME
- gl_FragColor = diffuse;
+ gl_FragColor = diffuse;
#else
- vec3 N = inpt.v.normal;
-
- if (!gl_FrontFacing)
- N = -N;
-
- /* Compute diffuse and specular lighting. */
- vec3 L_diffuse = vec3(0.0);
- vec3 L_specular = vec3(0.0);
-
-#ifdef USE_LIGHTING
-#ifndef USE_COLOR_MATERIAL
- /* Assume NUM_SOLID_LIGHTS directional lights. */
- for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
- vec4 Plight = lightSource[i].position;
-#ifdef USE_DIRECTIONAL_LIGHT
- vec3 l = (Plight.w == 0.0)
- ? normalize(Plight.xyz)
- : normalize(inpt.v.position.xyz);
-#else /* USE_DIRECTIONAL_LIGHT */
- /* TODO(sergey): We can normalize it outside of the shader. */
- vec3 l = normalize(Plight.xyz);
-#endif /* USE_DIRECTIONAL_LIGHT */
- vec3 h = normalize(l + vec3(0, 0, 1));
- float d = max(0.0, dot(N, l));
- float s = pow(max(0.0, dot(N, h)), shininess);
- L_diffuse += d * lightSource[i].diffuse.rgb;
- L_specular += s * lightSource[i].specular.rgb;
- }
-#else /* USE_COLOR_MATERIAL */
- vec3 varying_position = inpt.v.position.xyz;
- vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ?
- normalize(varying_position) : vec3(0.0, 0.0, -1.0);
- for (int i = 0; i < num_enabled_lights; i++) {
- /* todo: this is a slow check for disabled lights */
- if (lightSource[i].specular.a == 0.0)
- continue;
-
- float intensity = 1.0;
- vec3 light_direction;
-
- if (lightSource[i].position.w == 0.0) {
- /* directional light */
- light_direction = lightSource[i].position.xyz;
- }
- else {
- /* point light */
- vec3 d = lightSource[i].position.xyz - varying_position;
- light_direction = normalize(d);
-
- /* spot light cone */
- if (lightSource[i].spotCutoff < 90.0) {
- float cosine = max(dot(light_direction,
- -lightSource[i].spotDirection.xyz),
- 0.0);
- intensity = pow(cosine, lightSource[i].spotExponent);
- intensity *= step(lightSource[i].spotCosCutoff, cosine);
- }
-
- /* falloff */
- float distance = length(d);
-
- intensity /= lightSource[i].constantAttenuation +
- lightSource[i].linearAttenuation * distance +
- lightSource[i].quadraticAttenuation * distance * distance;
- }
-
- /* diffuse light */
- vec3 light_diffuse = lightSource[i].diffuse.rgb;
- float diffuse_bsdf = max(dot(N, light_direction), 0.0);
- L_diffuse += light_diffuse * diffuse_bsdf * intensity;
-
- /* specular light */
- vec3 light_specular = lightSource[i].specular.rgb;
- vec3 H = normalize(light_direction - V);
-
- float specular_bsdf = pow(max(dot(N, H), 0.0),
- gl_FrontMaterial.shininess);
- L_specular += light_specular * specular_bsdf * intensity;
- }
-#endif /* USE_COLOR_MATERIAL */
-#else /* USE_LIGHTING */
- L_diffuse = vec3(1.0);
-#endif
-
- /* Compute diffuse color. */
-#ifdef USE_TEXTURE_2D
- L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
-#else
- L_diffuse *= diffuse.rgb;
-#endif
-
- /* Sum lighting. */
- vec3 L = L_diffuse;
- if (shininess != 0) {
- L += L_specular * specular.rgb;
- }
-
- /* Write out fragment color. */
- gl_FragColor = vec4(L, diffuse.a);
+ vec3 N = inpt.v.normal;
+
+ if (!gl_FrontFacing)
+ N = -N;
+
+ /* Compute diffuse and specular lighting. */
+ vec3 L_diffuse = vec3(0.0);
+ vec3 L_specular = vec3(0.0);
+
+# ifdef USE_LIGHTING
+# ifndef USE_COLOR_MATERIAL
+ /* Assume NUM_SOLID_LIGHTS directional lights. */
+ for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
+ vec4 Plight = lightSource[i].position;
+# ifdef USE_DIRECTIONAL_LIGHT
+ vec3 l = (Plight.w == 0.0) ? normalize(Plight.xyz) : normalize(inpt.v.position.xyz);
+# else /* USE_DIRECTIONAL_LIGHT */
+ /* TODO(sergey): We can normalize it outside of the shader. */
+ vec3 l = normalize(Plight.xyz);
+# endif /* USE_DIRECTIONAL_LIGHT */
+ vec3 h = normalize(l + vec3(0, 0, 1));
+ float d = max(0.0, dot(N, l));
+ float s = pow(max(0.0, dot(N, h)), shininess);
+ L_diffuse += d * lightSource[i].diffuse.rgb;
+ L_specular += s * lightSource[i].specular.rgb;
+ }
+# else /* USE_COLOR_MATERIAL */
+ vec3 varying_position = inpt.v.position.xyz;
+ vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
+ for (int i = 0; i < num_enabled_lights; i++) {
+ /* todo: this is a slow check for disabled lights */
+ if (lightSource[i].specular.a == 0.0)
+ continue;
+
+ float intensity = 1.0;
+ vec3 light_direction;
+
+ if (lightSource[i].position.w == 0.0) {
+ /* directional light */
+ light_direction = lightSource[i].position.xyz;
+ }
+ else {
+ /* point light */
+ vec3 d = lightSource[i].position.xyz - varying_position;
+ light_direction = normalize(d);
+
+ /* spot light cone */
+ if (lightSource[i].spotCutoff < 90.0) {
+ float cosine = max(dot(light_direction, -lightSource[i].spotDirection.xyz), 0.0);
+ intensity = pow(cosine, lightSource[i].spotExponent);
+ intensity *= step(lightSource[i].spotCosCutoff, cosine);
+ }
+
+ /* falloff */
+ float distance = length(d);
+
+ intensity /= lightSource[i].constantAttenuation +
+ lightSource[i].linearAttenuation * distance +
+ lightSource[i].quadraticAttenuation * distance * distance;
+ }
+
+ /* diffuse light */
+ vec3 light_diffuse = lightSource[i].diffuse.rgb;
+ float diffuse_bsdf = max(dot(N, light_direction), 0.0);
+ L_diffuse += light_diffuse * diffuse_bsdf * intensity;
+
+ /* specular light */
+ vec3 light_specular = lightSource[i].specular.rgb;
+ vec3 H = normalize(light_direction - V);
+
+ float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
+ L_specular += light_specular * specular_bsdf * intensity;
+ }
+# endif /* USE_COLOR_MATERIAL */
+# else /* USE_LIGHTING */
+ L_diffuse = vec3(1.0);
+# endif
+
+ /* Compute diffuse color. */
+# ifdef USE_TEXTURE_2D
+ L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
+# else
+ L_diffuse *= diffuse.rgb;
+# endif
+
+ /* Sum lighting. */
+ vec3 L = L_diffuse;
+ if (shininess != 0) {
+ L += L_specular * specular.rgb;
+ }
+
+ /* Write out fragment color. */
+ gl_FragColor = vec4(L, diffuse.a);
#endif
}
diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl
index 4c57f4e469a..37bc0720113 100644
--- a/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl
+++ b/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl
@@ -18,9 +18,9 @@
*/
struct VertexData {
- vec4 position;
- vec3 normal;
- vec2 uv;
+ vec4 position;
+ vec3 normal;
+ vec2 uv;
};
layout(lines_adjacency) in;
@@ -36,76 +36,77 @@ uniform int PrimitiveIdBase;
uniform int osd_fvar_count;
uniform int osd_active_uv_offset;
-in block {
- VertexData v;
-} inpt[];
-
-#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \
- { \
- vec2 v[4]; \
- int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \
- for (int i = 0; i < 4; ++i) { \
- int index = (primOffset + i) * osd_fvar_count + fvarOffset; \
- v[i] = vec2(texelFetch(FVarDataBuffer, index).s, \
- texelFetch(FVarDataBuffer, index + 1).s); \
- } \
- result = mix(mix(v[0], v[1], tessCoord.s), \
- mix(v[3], v[2], tessCoord.s), \
- tessCoord.t); \
- }
+in block
+{
+ VertexData v;
+}
+inpt[];
+
+#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \
+ { \
+ vec2 v[4]; \
+ int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \
+ for (int i = 0; i < 4; ++i) { \
+ int index = (primOffset + i) * osd_fvar_count + fvarOffset; \
+ v[i] = vec2(texelFetch(FVarDataBuffer, index).s, texelFetch(FVarDataBuffer, index + 1).s); \
+ } \
+ result = mix(mix(v[0], v[1], tessCoord.s), mix(v[3], v[2], tessCoord.s), tessCoord.t); \
+ }
uniform samplerBuffer FVarDataBuffer;
uniform isamplerBuffer FVarDataOffsetBuffer;
-out block {
- VertexData v;
-} outpt;
+out block
+{
+ VertexData v;
+}
+outpt;
#ifdef FLAT_SHADING
void emit(int index, vec3 normal)
{
- outpt.v.position = inpt[index].v.position;
- outpt.v.normal = normal;
+ outpt.v.position = inpt[index].v.position;
+ outpt.v.normal = normal;
- /* TODO(sergey): Only uniform subdivisions atm. */
- vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
- vec2 st = quadst[index];
+ /* TODO(sergey): Only uniform subdivisions atm. */
+ vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
+ vec2 st = quadst[index];
- INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
+ INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
- gl_Position = projectionMatrix * inpt[index].v.position;
- EmitVertex();
+ gl_Position = projectionMatrix * inpt[index].v.position;
+ EmitVertex();
}
# ifdef WIREFRAME
void emit_edge(int v0, int v1, vec3 normal)
{
- emit(v0, normal);
- emit(v1, normal);
+ emit(v0, normal);
+ emit(v1, normal);
}
# endif
#else
void emit(int index)
{
- outpt.v.position = inpt[index].v.position;
- outpt.v.normal = inpt[index].v.normal;
+ outpt.v.position = inpt[index].v.position;
+ outpt.v.normal = inpt[index].v.normal;
- /* TODO(sergey): Only uniform subdivisions atm. */
- vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
- vec2 st = quadst[index];
+ /* TODO(sergey): Only uniform subdivisions atm. */
+ vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
+ vec2 st = quadst[index];
- INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
+ INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
- gl_Position = projectionMatrix * inpt[index].v.position;
- EmitVertex();
+ gl_Position = projectionMatrix * inpt[index].v.position;
+ EmitVertex();
}
# ifdef WIREFRAME
void emit_edge(int v0, int v1)
{
- emit(v0);
- emit(v1);
+ emit(v0);
+ emit(v1);
}
# endif
@@ -113,36 +114,36 @@ void emit_edge(int v0, int v1)
void main()
{
- gl_PrimitiveID = gl_PrimitiveIDIn;
+ gl_PrimitiveID = gl_PrimitiveIDIn;
#ifdef FLAT_SHADING
- vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
- vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
- vec3 flat_normal = normalize(cross(B, A));
+ vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
+ vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
+ vec3 flat_normal = normalize(cross(B, A));
# ifndef WIREFRAME
- emit(0, flat_normal);
- emit(1, flat_normal);
- emit(3, flat_normal);
- emit(2, flat_normal);
+ emit(0, flat_normal);
+ emit(1, flat_normal);
+ emit(3, flat_normal);
+ emit(2, flat_normal);
# else
- emit_edge(0, 1, flat_normal);
- emit_edge(1, 2, flat_normal);
- emit_edge(2, 3, flat_normal);
- emit_edge(3, 0, flat_normal);
+ emit_edge(0, 1, flat_normal);
+ emit_edge(1, 2, flat_normal);
+ emit_edge(2, 3, flat_normal);
+ emit_edge(3, 0, flat_normal);
# endif
#else
# ifndef WIREFRAME
- emit(0);
- emit(1);
- emit(3);
- emit(2);
+ emit(0);
+ emit(1);
+ emit(3);
+ emit(2);
# else
- emit_edge(0, 1);
- emit_edge(1, 2);
- emit_edge(2, 3);
- emit_edge(3, 0);
+ emit_edge(0, 1);
+ emit_edge(1, 2);
+ emit_edge(2, 3);
+ emit_edge(3, 0);
# endif
#endif
- EndPrimitive();
+ EndPrimitive();
}
diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl
index 1e89a806b18..474a716e927 100644
--- a/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl
+++ b/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl
@@ -18,9 +18,9 @@
*/
struct VertexData {
- vec4 position;
- vec3 normal;
- vec2 uv;
+ vec4 position;
+ vec3 normal;
+ vec2 uv;
};
in vec3 normal;
@@ -29,12 +29,14 @@ in vec4 position;
uniform mat4 modelViewMatrix;
uniform mat3 normalMatrix;
-out block {
- VertexData v;
-} outpt;
+out block
+{
+ VertexData v;
+}
+outpt;
void main()
{
- outpt.v.position = modelViewMatrix * position;
- outpt.v.normal = normalize(normalMatrix * normal);
+ outpt.v.position = modelViewMatrix * position;
+ outpt.v.normal = normalize(normalMatrix * normal);
}
diff --git a/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc b/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc
index 86c80fe8a54..b7c19bf4f9b 100644
--- a/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc
+++ b/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc
@@ -20,10 +20,12 @@
#include <cstddef>
-OpenSubdiv_Evaluator* openSubdiv_createEvaluatorFromTopologyRefiner(
- struct OpenSubdiv_TopologyRefiner* /*topology_refiner*/) {
+OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
+ struct OpenSubdiv_TopologyRefiner * /*topology_refiner*/)
+{
return NULL;
}
-void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator* /*evaluator*/) {
+void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator * /*evaluator*/)
+{
}
diff --git a/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc b/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc
index 8f14a2326dd..91ac0676dbd 100644
--- a/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc
+++ b/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc
@@ -21,17 +21,20 @@
#include <cstddef>
struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
- OpenSubdiv_TopologyRefiner* /*topology_refiner*/,
- eOpenSubdivEvaluator /*evaluator_type*/) {
+ OpenSubdiv_TopologyRefiner * /*topology_refiner*/, eOpenSubdivEvaluator /*evaluator_type*/)
+{
return NULL;
}
-void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh* /*gl_mesh*/) {
+void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh * /*gl_mesh*/)
+{
}
-bool openSubdiv_initGLMeshDrawingResources(void) {
+bool openSubdiv_initGLMeshDrawingResources(void)
+{
return false;
}
-void openSubdiv_deinitGLMeshDrawingResources(void) {
+void openSubdiv_deinitGLMeshDrawingResources(void)
+{
}
diff --git a/intern/opensubdiv/stub/opensubdiv_stub.cc b/intern/opensubdiv/stub/opensubdiv_stub.cc
index f03f0a0ef94..8c0b204d41a 100644
--- a/intern/opensubdiv/stub/opensubdiv_stub.cc
+++ b/intern/opensubdiv/stub/opensubdiv_stub.cc
@@ -20,16 +20,20 @@
#include <cstddef>
-void openSubdiv_init(void) {
+void openSubdiv_init(void)
+{
}
-void openSubdiv_cleanup(void) {
+void openSubdiv_cleanup(void)
+{
}
-int openSubdiv_getAvailableEvaluators(void) {
+int openSubdiv_getAvailableEvaluators(void)
+{
return 0;
}
-int openSubdiv_getVersionHex(void) {
+int openSubdiv_getVersionHex(void)
+{
return 0;
}
diff --git a/intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc b/intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc
index 01d58837b2b..a20f6df6a22 100644
--- a/intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc
+++ b/intern/opensubdiv/stub/opensubdiv_topology_refiner_stub.cc
@@ -20,18 +20,19 @@
#include <cstddef>
-OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
- OpenSubdiv_Converter* /*converter*/,
- const OpenSubdiv_TopologyRefinerSettings* /*settings*/) {
+OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter(
+ OpenSubdiv_Converter * /*converter*/, const OpenSubdiv_TopologyRefinerSettings * /*settings*/)
+{
return NULL;
}
-void openSubdiv_deleteTopologyRefiner(
- OpenSubdiv_TopologyRefiner* /*topology_refiner*/) {
+void openSubdiv_deleteTopologyRefiner(OpenSubdiv_TopologyRefiner * /*topology_refiner*/)
+{
}
bool openSubdiv_topologyRefinerCompareWithConverter(
- const OpenSubdiv_TopologyRefiner* /*topology_refiner*/,
- const OpenSubdiv_Converter* /*converter*/) {
+ const OpenSubdiv_TopologyRefiner * /*topology_refiner*/,
+ const OpenSubdiv_Converter * /*converter*/)
+{
return false;
}
diff --git a/intern/openvdb/CMakeLists.txt b/intern/openvdb/CMakeLists.txt
index 2d72febd3cf..bcb1d545c94 100644
--- a/intern/openvdb/CMakeLists.txt
+++ b/intern/openvdb/CMakeLists.txt
@@ -19,57 +19,57 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- intern
+ .
+ intern
)
set(INC_SYS
)
set(SRC
- openvdb_capi.h
+ openvdb_capi.h
)
set(LIB
)
if(WITH_OPENVDB)
- add_definitions(
- -DWITH_OPENVDB
- ${OPENVDB_DEFINITIONS}
- )
+ add_definitions(
+ -DWITH_OPENVDB
+ ${OPENVDB_DEFINITIONS}
+ )
- if(WITH_OPENVDB_3_ABI_COMPATIBLE)
- add_definitions(
- -DOPENVDB_3_ABI_COMPATIBLE
- )
- endif()
+ if(WITH_OPENVDB_3_ABI_COMPATIBLE)
+ add_definitions(
+ -DOPENVDB_3_ABI_COMPATIBLE
+ )
+ endif()
- list(APPEND INC_SYS
- ${BOOST_INCLUDE_DIR}
- ${TBB_INCLUDE_DIRS}
- ${OPENEXR_INCLUDE_DIRS}
- ${OPENVDB_INCLUDE_DIRS}
- )
+ list(APPEND INC_SYS
+ ${BOOST_INCLUDE_DIR}
+ ${TBB_INCLUDE_DIRS}
+ ${OPENEXR_INCLUDE_DIRS}
+ ${OPENVDB_INCLUDE_DIRS}
+ )
- list(APPEND SRC
- intern/openvdb_dense_convert.cc
- intern/openvdb_reader.cc
- intern/openvdb_writer.cc
- openvdb_capi.cc
- openvdb_util.cc
+ list(APPEND SRC
+ intern/openvdb_dense_convert.cc
+ intern/openvdb_reader.cc
+ intern/openvdb_writer.cc
+ openvdb_capi.cc
+ openvdb_util.cc
- intern/openvdb_dense_convert.h
- intern/openvdb_reader.h
- intern/openvdb_writer.h
- openvdb_util.h
- )
+ intern/openvdb_dense_convert.h
+ intern/openvdb_reader.h
+ intern/openvdb_writer.h
+ openvdb_util.h
+ )
- if(WITH_OPENVDB_BLOSC)
- add_definitions(
- -DWITH_OPENVDB_BLOSC
- )
- endif()
+ if(WITH_OPENVDB_BLOSC)
+ add_definitions(
+ -DWITH_OPENVDB_BLOSC
+ )
+ endif()
endif()
blender_add_lib(bf_intern_openvdb "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/openvdb/intern/openvdb_dense_convert.cc b/intern/openvdb/intern/openvdb_dense_convert.cc
index 56e856b19e6..085c04f1c81 100644
--- a/intern/openvdb/intern/openvdb_dense_convert.cc
+++ b/intern/openvdb/intern/openvdb_dense_convert.cc
@@ -19,158 +19,168 @@
#include "openvdb_dense_convert.h"
-#include <openvdb/tools/ValueTransformer.h> /* for tools::foreach */
+#include <openvdb/tools/ValueTransformer.h> /* for tools::foreach */
namespace internal {
openvdb::Mat4R convertMatrix(const float mat[4][4])
{
- return openvdb::Mat4R(
- mat[0][0], mat[0][1], mat[0][2], mat[0][3],
- mat[1][0], mat[1][1], mat[1][2], mat[1][3],
- mat[2][0], mat[2][1], mat[2][2], mat[2][3],
- mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
+ return openvdb::Mat4R(mat[0][0],
+ mat[0][1],
+ mat[0][2],
+ mat[0][3],
+ mat[1][0],
+ mat[1][1],
+ mat[1][2],
+ mat[1][3],
+ mat[2][0],
+ mat[2][1],
+ mat[2][2],
+ mat[2][3],
+ mat[3][0],
+ mat[3][1],
+ mat[3][2],
+ mat[3][3]);
}
-
class MergeScalarGrids {
- typedef openvdb::FloatTree ScalarTree;
-
- openvdb::tree::ValueAccessor<const ScalarTree> m_acc_x, m_acc_y, m_acc_z;
-
-public:
- MergeScalarGrids(const ScalarTree *x_tree, const ScalarTree *y_tree, const ScalarTree *z_tree)
- : m_acc_x(*x_tree)
- , m_acc_y(*y_tree)
- , m_acc_z(*z_tree)
- {}
-
- MergeScalarGrids(const MergeScalarGrids &other)
- : m_acc_x(other.m_acc_x)
- , m_acc_y(other.m_acc_y)
- , m_acc_z(other.m_acc_z)
- {}
-
- void operator()(const openvdb::Vec3STree::ValueOnIter &it) const
- {
- using namespace openvdb;
-
- const math::Coord xyz = it.getCoord();
- float x = m_acc_x.getValue(xyz);
- float y = m_acc_y.getValue(xyz);
- float z = m_acc_z.getValue(xyz);
-
- it.setValue(math::Vec3s(x, y, z));
- }
+ typedef openvdb::FloatTree ScalarTree;
+
+ openvdb::tree::ValueAccessor<const ScalarTree> m_acc_x, m_acc_y, m_acc_z;
+
+ public:
+ MergeScalarGrids(const ScalarTree *x_tree, const ScalarTree *y_tree, const ScalarTree *z_tree)
+ : m_acc_x(*x_tree), m_acc_y(*y_tree), m_acc_z(*z_tree)
+ {
+ }
+
+ MergeScalarGrids(const MergeScalarGrids &other)
+ : m_acc_x(other.m_acc_x), m_acc_y(other.m_acc_y), m_acc_z(other.m_acc_z)
+ {
+ }
+
+ void operator()(const openvdb::Vec3STree::ValueOnIter &it) const
+ {
+ using namespace openvdb;
+
+ const math::Coord xyz = it.getCoord();
+ float x = m_acc_x.getValue(xyz);
+ float y = m_acc_y.getValue(xyz);
+ float z = m_acc_z.getValue(xyz);
+
+ it.setValue(math::Vec3s(x, y, z));
+ }
};
-openvdb::GridBase *OpenVDB_export_vector_grid(
- OpenVDBWriter *writer,
- const openvdb::Name &name,
- const float *data_x, const float *data_y, const float *data_z,
- const int res[3],
- float fluid_mat[4][4],
- openvdb::VecType vec_type,
- const bool is_color,
- const float clipping,
- const openvdb::FloatGrid *mask)
+openvdb::GridBase *OpenVDB_export_vector_grid(OpenVDBWriter *writer,
+ const openvdb::Name &name,
+ const float *data_x,
+ const float *data_y,
+ const float *data_z,
+ const int res[3],
+ float fluid_mat[4][4],
+ openvdb::VecType vec_type,
+ const bool is_color,
+ const float clipping,
+ const openvdb::FloatGrid *mask)
{
- using namespace openvdb;
+ using namespace openvdb;
- math::CoordBBox bbox(Coord(0), Coord(res[0] - 1, res[1] - 1, res[2] - 1));
- Mat4R mat = convertMatrix(fluid_mat);
- math::Transform::Ptr transform = math::Transform::createLinearTransform(mat);
+ math::CoordBBox bbox(Coord(0), Coord(res[0] - 1, res[1] - 1, res[2] - 1));
+ Mat4R mat = convertMatrix(fluid_mat);
+ math::Transform::Ptr transform = math::Transform::createLinearTransform(mat);
- FloatGrid::Ptr grid[3];
+ FloatGrid::Ptr grid[3];
- grid[0] = FloatGrid::create(0.0f);
- tools::Dense<const float, tools::LayoutXYZ> dense_grid_x(bbox, data_x);
- tools::copyFromDense(dense_grid_x, grid[0]->tree(), clipping);
+ grid[0] = FloatGrid::create(0.0f);
+ tools::Dense<const float, tools::LayoutXYZ> dense_grid_x(bbox, data_x);
+ tools::copyFromDense(dense_grid_x, grid[0]->tree(), clipping);
- grid[1] = FloatGrid::create(0.0f);
- tools::Dense<const float, tools::LayoutXYZ> dense_grid_y(bbox, data_y);
- tools::copyFromDense(dense_grid_y, grid[1]->tree(), clipping);
+ grid[1] = FloatGrid::create(0.0f);
+ tools::Dense<const float, tools::LayoutXYZ> dense_grid_y(bbox, data_y);
+ tools::copyFromDense(dense_grid_y, grid[1]->tree(), clipping);
- grid[2] = FloatGrid::create(0.0f);
- tools::Dense<const float, tools::LayoutXYZ> dense_grid_z(bbox, data_z);
- tools::copyFromDense(dense_grid_z, grid[2]->tree(), clipping);
+ grid[2] = FloatGrid::create(0.0f);
+ tools::Dense<const float, tools::LayoutXYZ> dense_grid_z(bbox, data_z);
+ tools::copyFromDense(dense_grid_z, grid[2]->tree(), clipping);
- Vec3SGrid::Ptr vecgrid = Vec3SGrid::create(Vec3s(0.0f));
+ Vec3SGrid::Ptr vecgrid = Vec3SGrid::create(Vec3s(0.0f));
- /* Activate voxels in the vector grid based on the scalar grids to ensure
- * thread safety later on */
- for (int i = 0; i < 3; ++i) {
- vecgrid->tree().topologyUnion(grid[i]->tree());
- }
+ /* Activate voxels in the vector grid based on the scalar grids to ensure
+ * thread safety later on */
+ for (int i = 0; i < 3; ++i) {
+ vecgrid->tree().topologyUnion(grid[i]->tree());
+ }
- MergeScalarGrids op(&(grid[0]->tree()), &(grid[1]->tree()), &(grid[2]->tree()));
- tools::foreach(vecgrid->beginValueOn(), op, true, false);
+ MergeScalarGrids op(&(grid[0]->tree()), &(grid[1]->tree()), &(grid[2]->tree()));
+ tools::foreach (vecgrid->beginValueOn(), op, true, false);
- vecgrid->setTransform(transform);
+ vecgrid->setTransform(transform);
- /* Avoid clipping against an empty grid. */
- if (mask && !mask->tree().empty()) {
- vecgrid = tools::clip(*vecgrid, *mask);
- }
+ /* Avoid clipping against an empty grid. */
+ if (mask && !mask->tree().empty()) {
+ vecgrid = tools::clip(*vecgrid, *mask);
+ }
- vecgrid->setName(name);
- vecgrid->setIsInWorldSpace(false);
- vecgrid->setVectorType(vec_type);
- vecgrid->insertMeta("is_color", BoolMetadata(is_color));
- vecgrid->setGridClass(GRID_STAGGERED);
+ vecgrid->setName(name);
+ vecgrid->setIsInWorldSpace(false);
+ vecgrid->setVectorType(vec_type);
+ vecgrid->insertMeta("is_color", BoolMetadata(is_color));
+ vecgrid->setGridClass(GRID_STAGGERED);
- writer->insert(vecgrid);
+ writer->insert(vecgrid);
- return vecgrid.get();
+ return vecgrid.get();
}
-void OpenVDB_import_grid_vector(
- OpenVDBReader *reader,
- const openvdb::Name &name,
- float **data_x, float **data_y, float **data_z,
- const int res[3])
+void OpenVDB_import_grid_vector(OpenVDBReader *reader,
+ const openvdb::Name &name,
+ float **data_x,
+ float **data_y,
+ float **data_z,
+ const int res[3])
{
- using namespace openvdb;
-
- if (!reader->hasGrid(name)) {
- std::fprintf(stderr, "OpenVDB grid %s not found in file!\n", name.c_str());
- memset(*data_x, 0, sizeof(float) * res[0] * res[1] * res[2]);
- memset(*data_y, 0, sizeof(float) * res[0] * res[1] * res[2]);
- memset(*data_z, 0, sizeof(float) * res[0] * res[1] * res[2]);
- return;
- }
-
- Vec3SGrid::Ptr vgrid = gridPtrCast<Vec3SGrid>(reader->getGrid(name));
- Vec3SGrid::ConstAccessor acc = vgrid->getConstAccessor();
- math::Coord xyz;
- int &x = xyz[0], &y = xyz[1], &z = xyz[2];
-
- size_t index = 0;
- for (z = 0; z < res[2]; ++z) {
- for (y = 0; y < res[1]; ++y) {
- for (x = 0; x < res[0]; ++x, ++index) {
- math::Vec3s value = acc.getValue(xyz);
- (*data_x)[index] = value.x();
- (*data_y)[index] = value.y();
- (*data_z)[index] = value.z();
- }
- }
- }
+ using namespace openvdb;
+
+ if (!reader->hasGrid(name)) {
+ std::fprintf(stderr, "OpenVDB grid %s not found in file!\n", name.c_str());
+ memset(*data_x, 0, sizeof(float) * res[0] * res[1] * res[2]);
+ memset(*data_y, 0, sizeof(float) * res[0] * res[1] * res[2]);
+ memset(*data_z, 0, sizeof(float) * res[0] * res[1] * res[2]);
+ return;
+ }
+
+ Vec3SGrid::Ptr vgrid = gridPtrCast<Vec3SGrid>(reader->getGrid(name));
+ Vec3SGrid::ConstAccessor acc = vgrid->getConstAccessor();
+ math::Coord xyz;
+ int &x = xyz[0], &y = xyz[1], &z = xyz[2];
+
+ size_t index = 0;
+ for (z = 0; z < res[2]; ++z) {
+ for (y = 0; y < res[1]; ++y) {
+ for (x = 0; x < res[0]; ++x, ++index) {
+ math::Vec3s value = acc.getValue(xyz);
+ (*data_x)[index] = value.x();
+ (*data_y)[index] = value.y();
+ (*data_z)[index] = value.z();
+ }
+ }
+ }
}
openvdb::Name do_name_versionning(const openvdb::Name &name)
{
- openvdb::Name temp_name = name;
+ openvdb::Name temp_name = name;
- if (temp_name.find("_low", temp_name.size() - 4, 4) == temp_name.size() - 4) {
- return temp_name.replace(temp_name.size() - 4, 4, " low");
- }
+ if (temp_name.find("_low", temp_name.size() - 4, 4) == temp_name.size() - 4) {
+ return temp_name.replace(temp_name.size() - 4, 4, " low");
+ }
- if (temp_name.find("_old", temp_name.size() - 4, 4) == temp_name.size() - 4) {
- return temp_name.replace(temp_name.size() - 4, 4, " old");
- }
+ if (temp_name.find("_old", temp_name.size() - 4, 4) == temp_name.size() - 4) {
+ return temp_name.replace(temp_name.size() - 4, 4, " old");
+ }
- return temp_name;
+ return temp_name;
}
-} /* namespace internal */
+} /* namespace internal */
diff --git a/intern/openvdb/intern/openvdb_dense_convert.h b/intern/openvdb/intern/openvdb_dense_convert.h
index fe57ea86789..fbad15eae04 100644
--- a/intern/openvdb/intern/openvdb_dense_convert.h
+++ b/intern/openvdb/intern/openvdb_dense_convert.h
@@ -36,97 +36,97 @@ openvdb::Name do_name_versionning(const openvdb::Name &name);
openvdb::Mat4R convertMatrix(const float mat[4][4]);
-template <typename GridType, typename T>
-GridType *OpenVDB_export_grid(
- OpenVDBWriter *writer,
- const openvdb::Name &name,
- const T *data,
- const int res[3],
- float fluid_mat[4][4],
- const float clipping,
- const openvdb::FloatGrid *mask)
+template<typename GridType, typename T>
+GridType *OpenVDB_export_grid(OpenVDBWriter *writer,
+ const openvdb::Name &name,
+ const T *data,
+ const int res[3],
+ float fluid_mat[4][4],
+ const float clipping,
+ const openvdb::FloatGrid *mask)
{
- using namespace openvdb;
+ using namespace openvdb;
- math::CoordBBox bbox(Coord(0), Coord(res[0] - 1, res[1] - 1, res[2] - 1));
- Mat4R mat = convertMatrix(fluid_mat);
- math::Transform::Ptr transform = math::Transform::createLinearTransform(mat);
+ math::CoordBBox bbox(Coord(0), Coord(res[0] - 1, res[1] - 1, res[2] - 1));
+ Mat4R mat = convertMatrix(fluid_mat);
+ math::Transform::Ptr transform = math::Transform::createLinearTransform(mat);
- typename GridType::Ptr grid = GridType::create(T(0));
+ typename GridType::Ptr grid = GridType::create(T(0));
- tools::Dense<const T, openvdb::tools::LayoutXYZ> dense_grid(bbox, data);
- tools::copyFromDense(dense_grid, grid->tree(), static_cast<T>(clipping));
+ tools::Dense<const T, openvdb::tools::LayoutXYZ> dense_grid(bbox, data);
+ tools::copyFromDense(dense_grid, grid->tree(), static_cast<T>(clipping));
- grid->setTransform(transform);
+ grid->setTransform(transform);
- /* Avoid clipping against an empty grid. */
- if (mask && !mask->tree().empty()) {
- grid = tools::clip(*grid, *mask);
- }
+ /* Avoid clipping against an empty grid. */
+ if (mask && !mask->tree().empty()) {
+ grid = tools::clip(*grid, *mask);
+ }
- grid->setName(name);
- grid->setIsInWorldSpace(false);
- grid->setVectorType(openvdb::VEC_INVARIANT);
+ grid->setName(name);
+ grid->setIsInWorldSpace(false);
+ grid->setVectorType(openvdb::VEC_INVARIANT);
- writer->insert(grid);
+ writer->insert(grid);
- return grid.get();
+ return grid.get();
}
-template <typename GridType, typename T>
-void OpenVDB_import_grid(
- OpenVDBReader *reader,
- const openvdb::Name &name,
- T **data,
- const int res[3])
+template<typename GridType, typename T>
+void OpenVDB_import_grid(OpenVDBReader *reader,
+ const openvdb::Name &name,
+ T **data,
+ const int res[3])
{
- using namespace openvdb;
-
- openvdb::Name temp_name = name;
-
- if (!reader->hasGrid(temp_name)) {
- temp_name = do_name_versionning(temp_name);
-
- if (!reader->hasGrid(temp_name)) {
- std::fprintf(stderr, "OpenVDB grid %s not found in file!\n", temp_name.c_str());
- memset(*data, 0, sizeof(T) * res[0] * res[1] * res[2]);
- return;
- }
- }
-
- typename GridType::Ptr grid = gridPtrCast<GridType>(reader->getGrid(temp_name));
- typename GridType::ConstAccessor acc = grid->getConstAccessor();
-
- math::Coord xyz;
- int &x = xyz[0], &y = xyz[1], &z = xyz[2];
-
- size_t index = 0;
- for (z = 0; z < res[2]; ++z) {
- for (y = 0; y < res[1]; ++y) {
- for (x = 0; x < res[0]; ++x, ++index) {
- (*data)[index] = acc.getValue(xyz);
- }
- }
- }
+ using namespace openvdb;
+
+ openvdb::Name temp_name = name;
+
+ if (!reader->hasGrid(temp_name)) {
+ temp_name = do_name_versionning(temp_name);
+
+ if (!reader->hasGrid(temp_name)) {
+ std::fprintf(stderr, "OpenVDB grid %s not found in file!\n", temp_name.c_str());
+ memset(*data, 0, sizeof(T) * res[0] * res[1] * res[2]);
+ return;
+ }
+ }
+
+ typename GridType::Ptr grid = gridPtrCast<GridType>(reader->getGrid(temp_name));
+ typename GridType::ConstAccessor acc = grid->getConstAccessor();
+
+ math::Coord xyz;
+ int &x = xyz[0], &y = xyz[1], &z = xyz[2];
+
+ size_t index = 0;
+ for (z = 0; z < res[2]; ++z) {
+ for (y = 0; y < res[1]; ++y) {
+ for (x = 0; x < res[0]; ++x, ++index) {
+ (*data)[index] = acc.getValue(xyz);
+ }
+ }
+ }
}
openvdb::GridBase *OpenVDB_export_vector_grid(OpenVDBWriter *writer,
- const openvdb::Name &name,
- const float *data_x, const float *data_y, const float *data_z,
- const int res[3],
- float fluid_mat[4][4],
- openvdb::VecType vec_type,
- const bool is_color,
- const float clipping,
- const openvdb::FloatGrid *mask);
-
-
-void OpenVDB_import_grid_vector(
- OpenVDBReader *reader,
- const openvdb::Name &name,
- float **data_x, float **data_y, float **data_z,
- const int res[3]);
-
-} /* namespace internal */
+ const openvdb::Name &name,
+ const float *data_x,
+ const float *data_y,
+ const float *data_z,
+ const int res[3],
+ float fluid_mat[4][4],
+ openvdb::VecType vec_type,
+ const bool is_color,
+ const float clipping,
+ const openvdb::FloatGrid *mask);
+
+void OpenVDB_import_grid_vector(OpenVDBReader *reader,
+ const openvdb::Name &name,
+ float **data_x,
+ float **data_y,
+ float **data_z,
+ const int res[3]);
+
+} /* namespace internal */
#endif /* __OPENVDB_DENSE_CONVERT_H__ */
diff --git a/intern/openvdb/intern/openvdb_reader.cc b/intern/openvdb/intern/openvdb_reader.cc
index 3fdad2a553f..934b6e8869d 100644
--- a/intern/openvdb/intern/openvdb_reader.cc
+++ b/intern/openvdb/intern/openvdb_reader.cc
@@ -20,111 +20,109 @@
#include "openvdb_reader.h"
#include "openvdb_util.h"
-OpenVDBReader::OpenVDBReader()
- : m_meta_map(new openvdb::MetaMap)
- , m_file(NULL)
+OpenVDBReader::OpenVDBReader() : m_meta_map(new openvdb::MetaMap), m_file(NULL)
{
- /* Although it is safe, it may not be good to have this here, could be done
- * once instead of everytime we read a file. */
- openvdb::initialize();
+ /* Although it is safe, it may not be good to have this here, could be done
+ * once instead of everytime we read a file. */
+ openvdb::initialize();
}
OpenVDBReader::~OpenVDBReader()
{
- cleanupFile();
+ cleanupFile();
}
void OpenVDBReader::open(const openvdb::Name &filename)
{
- cleanupFile();
-
- try {
- m_file = new openvdb::io::File(filename);
- m_file->setCopyMaxBytes(0);
- m_file->open();
-
- m_meta_map = m_file->getMetadata();
- }
- /* Mostly to catch exceptions related to Blosc not being supported. */
- catch (const openvdb::IoError &e) {
- std::cerr << e.what() << '\n';
- cleanupFile();
- }
+ cleanupFile();
+
+ try {
+ m_file = new openvdb::io::File(filename);
+ m_file->setCopyMaxBytes(0);
+ m_file->open();
+
+ m_meta_map = m_file->getMetadata();
+ }
+ /* Mostly to catch exceptions related to Blosc not being supported. */
+ catch (const openvdb::IoError &e) {
+ std::cerr << e.what() << '\n';
+ cleanupFile();
+ }
}
void OpenVDBReader::floatMeta(const openvdb::Name &name, float &value) const
{
- try {
- value = m_meta_map->metaValue<float>(name);
- }
- CATCH_KEYERROR;
+ try {
+ value = m_meta_map->metaValue<float>(name);
+ }
+ CATCH_KEYERROR;
}
void OpenVDBReader::intMeta(const openvdb::Name &name, int &value) const
{
- try {
- value = m_meta_map->metaValue<int>(name);
- }
- CATCH_KEYERROR;
+ try {
+ value = m_meta_map->metaValue<int>(name);
+ }
+ CATCH_KEYERROR;
}
void OpenVDBReader::vec3sMeta(const openvdb::Name &name, float value[3]) const
{
- try {
- openvdb::Vec3s meta_val = m_meta_map->metaValue<openvdb::Vec3s>(name);
-
- value[0] = meta_val.x();
- value[1] = meta_val.y();
- value[2] = meta_val.z();
- }
- CATCH_KEYERROR;
+ try {
+ openvdb::Vec3s meta_val = m_meta_map->metaValue<openvdb::Vec3s>(name);
+
+ value[0] = meta_val.x();
+ value[1] = meta_val.y();
+ value[2] = meta_val.z();
+ }
+ CATCH_KEYERROR;
}
void OpenVDBReader::vec3IMeta(const openvdb::Name &name, int value[3]) const
{
- try {
- openvdb::Vec3i meta_val = m_meta_map->metaValue<openvdb::Vec3i>(name);
-
- value[0] = meta_val.x();
- value[1] = meta_val.y();
- value[2] = meta_val.z();
- }
- CATCH_KEYERROR;
+ try {
+ openvdb::Vec3i meta_val = m_meta_map->metaValue<openvdb::Vec3i>(name);
+
+ value[0] = meta_val.x();
+ value[1] = meta_val.y();
+ value[2] = meta_val.z();
+ }
+ CATCH_KEYERROR;
}
void OpenVDBReader::mat4sMeta(const openvdb::Name &name, float value[4][4]) const
{
- try {
- openvdb::Mat4s meta_val = m_meta_map->metaValue<openvdb::Mat4s>(name);
-
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- value[i][j] = meta_val[i][j];
- }
- }
- }
- CATCH_KEYERROR;
+ try {
+ openvdb::Mat4s meta_val = m_meta_map->metaValue<openvdb::Mat4s>(name);
+
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ value[i][j] = meta_val[i][j];
+ }
+ }
+ }
+ CATCH_KEYERROR;
}
bool OpenVDBReader::hasGrid(const openvdb::Name &name) const
{
- return m_file->hasGrid(name);
+ return m_file->hasGrid(name);
}
openvdb::GridBase::Ptr OpenVDBReader::getGrid(const openvdb::Name &name) const
{
- return m_file->readGrid(name);
+ return m_file->readGrid(name);
}
size_t OpenVDBReader::numGrids() const
{
- return m_file->getGrids()->size();
+ return m_file->getGrids()->size();
}
void OpenVDBReader::cleanupFile()
{
- if (m_file) {
- m_file->close();
- delete m_file;
- }
+ if (m_file) {
+ m_file->close();
+ delete m_file;
+ }
}
diff --git a/intern/openvdb/intern/openvdb_reader.h b/intern/openvdb/intern/openvdb_reader.h
index 39fbf6cd15a..f8c16cea141 100644
--- a/intern/openvdb/intern/openvdb_reader.h
+++ b/intern/openvdb/intern/openvdb_reader.h
@@ -23,27 +23,27 @@
#include <openvdb/openvdb.h>
struct OpenVDBReader {
-private:
- openvdb::MetaMap::Ptr m_meta_map;
- openvdb::io::File *m_file;
+ private:
+ openvdb::MetaMap::Ptr m_meta_map;
+ openvdb::io::File *m_file;
- void cleanupFile();
+ void cleanupFile();
-public:
- OpenVDBReader();
- ~OpenVDBReader();
+ public:
+ OpenVDBReader();
+ ~OpenVDBReader();
- void open(const openvdb::Name &filename);
+ void open(const openvdb::Name &filename);
- void floatMeta(const openvdb::Name &name, float &value) const;
- void intMeta(const openvdb::Name &name, int &value) const;
- void vec3sMeta(const openvdb::Name &name, float value[3]) const;
- void vec3IMeta(const openvdb::Name &name, int value[3]) const;
- void mat4sMeta(const openvdb::Name &name, float value[4][4]) const;
+ void floatMeta(const openvdb::Name &name, float &value) const;
+ void intMeta(const openvdb::Name &name, int &value) const;
+ void vec3sMeta(const openvdb::Name &name, float value[3]) const;
+ void vec3IMeta(const openvdb::Name &name, int value[3]) const;
+ void mat4sMeta(const openvdb::Name &name, float value[4][4]) const;
- bool hasGrid(const openvdb::Name &name) const;
- openvdb::GridBase::Ptr getGrid(const openvdb::Name &name) const;
- size_t numGrids() const;
+ bool hasGrid(const openvdb::Name &name) const;
+ openvdb::GridBase::Ptr getGrid(const openvdb::Name &name) const;
+ size_t numGrids() const;
};
#endif /* __OPENVDB_READER_H__ */
diff --git a/intern/openvdb/intern/openvdb_writer.cc b/intern/openvdb/intern/openvdb_writer.cc
index 900c5371682..9c6ff9ed226 100644
--- a/intern/openvdb/intern/openvdb_writer.cc
+++ b/intern/openvdb/intern/openvdb_writer.cc
@@ -21,96 +21,106 @@
#include "openvdb_util.h"
OpenVDBWriter::OpenVDBWriter()
- : m_grids(new openvdb::GridPtrVec())
- , m_meta_map(new openvdb::MetaMap())
- , m_save_as_half(false)
+ : m_grids(new openvdb::GridPtrVec()), m_meta_map(new openvdb::MetaMap()), m_save_as_half(false)
{
- m_meta_map->insertMeta("creator", openvdb::StringMetadata("Blender/Smoke"));
+ m_meta_map->insertMeta("creator", openvdb::StringMetadata("Blender/Smoke"));
}
OpenVDBWriter::~OpenVDBWriter()
-{}
+{
+}
void OpenVDBWriter::insert(const openvdb::GridBase::Ptr &grid)
{
- grid->setSaveFloatAsHalf(m_save_as_half);
- m_grids->push_back(grid);
+ grid->setSaveFloatAsHalf(m_save_as_half);
+ m_grids->push_back(grid);
}
void OpenVDBWriter::insert(const openvdb::GridBase &grid)
{
#if (OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER <= 3) || defined(OPENVDB_3_ABI_COMPATIBLE)
- m_grids->push_back(grid.copyGrid());
+ m_grids->push_back(grid.copyGrid());
#else
- m_grids->push_back(grid.copyGridWithNewTree());
+ m_grids->push_back(grid.copyGridWithNewTree());
#endif
}
void OpenVDBWriter::insertFloatMeta(const openvdb::Name &name, const float value)
{
- try {
- m_meta_map->insertMeta(name, openvdb::FloatMetadata(value));
- }
- CATCH_KEYERROR;
+ try {
+ m_meta_map->insertMeta(name, openvdb::FloatMetadata(value));
+ }
+ CATCH_KEYERROR;
}
void OpenVDBWriter::insertIntMeta(const openvdb::Name &name, const int value)
{
- try {
- m_meta_map->insertMeta(name, openvdb::Int32Metadata(value));
- }
- CATCH_KEYERROR;
+ try {
+ m_meta_map->insertMeta(name, openvdb::Int32Metadata(value));
+ }
+ CATCH_KEYERROR;
}
void OpenVDBWriter::insertVec3sMeta(const openvdb::Name &name, const openvdb::Vec3s &value)
{
- try {
- m_meta_map->insertMeta(name, openvdb::Vec3SMetadata(value));
- }
- CATCH_KEYERROR;
+ try {
+ m_meta_map->insertMeta(name, openvdb::Vec3SMetadata(value));
+ }
+ CATCH_KEYERROR;
}
void OpenVDBWriter::insertVec3IMeta(const openvdb::Name &name, const openvdb::Vec3I &value)
{
- try {
- m_meta_map->insertMeta(name, openvdb::Vec3IMetadata(value));
- }
- CATCH_KEYERROR;
+ try {
+ m_meta_map->insertMeta(name, openvdb::Vec3IMetadata(value));
+ }
+ CATCH_KEYERROR;
}
void OpenVDBWriter::insertMat4sMeta(const openvdb::Name &name, const float value[4][4])
{
- openvdb::Mat4s mat = openvdb::Mat4s(
- value[0][0], value[0][1], value[0][2], value[0][3],
- value[1][0], value[1][1], value[1][2], value[1][3],
- value[2][0], value[2][1], value[2][2], value[2][3],
- value[3][0], value[3][1], value[3][2], value[3][3]);
+ openvdb::Mat4s mat = openvdb::Mat4s(value[0][0],
+ value[0][1],
+ value[0][2],
+ value[0][3],
+ value[1][0],
+ value[1][1],
+ value[1][2],
+ value[1][3],
+ value[2][0],
+ value[2][1],
+ value[2][2],
+ value[2][3],
+ value[3][0],
+ value[3][1],
+ value[3][2],
+ value[3][3]);
- try {
- m_meta_map->insertMeta(name, openvdb::Mat4SMetadata(mat));
- }
- CATCH_KEYERROR;
+ try {
+ m_meta_map->insertMeta(name, openvdb::Mat4SMetadata(mat));
+ }
+ CATCH_KEYERROR;
}
void OpenVDBWriter::setFlags(const int compression, const bool save_as_half)
{
- m_compression_flags = compression;
- m_save_as_half = save_as_half;
+ m_compression_flags = compression;
+ m_save_as_half = save_as_half;
}
void OpenVDBWriter::write(const openvdb::Name &filename) const
{
- try {
- openvdb::io::File file(filename);
- file.setCompression(m_compression_flags);
- file.write(*m_grids, *m_meta_map);
- file.close();
+ try {
+ openvdb::io::File file(filename);
+ file.setCompression(m_compression_flags);
+ file.write(*m_grids, *m_meta_map);
+ file.close();
- /* Should perhaps be an option at some point */
- m_grids->clear();
- }
- /* Mostly to catch exceptions related to Blosc not being supported. */
- catch (const openvdb::IoError &e) {
- std::cerr << e.what() << '\n';
- }
+ /* Should perhaps be an option at some point */
+ m_grids->clear();
+ }
+ /* Mostly to catch exceptions related to Blosc not being supported. */
+ catch (const openvdb::IoError &e) {
+ std::cerr << e.what() << '\n';
+ }
}
diff --git a/intern/openvdb/intern/openvdb_writer.h b/intern/openvdb/intern/openvdb_writer.h
index 4205807a89c..d0e022b4b7a 100644
--- a/intern/openvdb/intern/openvdb_writer.h
+++ b/intern/openvdb/intern/openvdb_writer.h
@@ -23,29 +23,29 @@
#include <openvdb/openvdb.h>
struct OpenVDBWriter {
-private:
- openvdb::GridPtrVecPtr m_grids;
- openvdb::MetaMap::Ptr m_meta_map;
+ private:
+ openvdb::GridPtrVecPtr m_grids;
+ openvdb::MetaMap::Ptr m_meta_map;
- int m_compression_flags;
- bool m_save_as_half;
+ int m_compression_flags;
+ bool m_save_as_half;
-public:
- OpenVDBWriter();
- ~OpenVDBWriter();
+ public:
+ OpenVDBWriter();
+ ~OpenVDBWriter();
- void insert(const openvdb::GridBase::Ptr &grid);
- void insert(const openvdb::GridBase &grid);
+ void insert(const openvdb::GridBase::Ptr &grid);
+ void insert(const openvdb::GridBase &grid);
- void insertFloatMeta(const openvdb::Name &name, const float value);
- void insertIntMeta(const openvdb::Name &name, const int value);
- void insertVec3sMeta(const openvdb::Name &name, const openvdb::Vec3s &value);
- void insertVec3IMeta(const openvdb::Name &name, const openvdb::Vec3I &value);
- void insertMat4sMeta(const openvdb::Name &name, const float value[4][4]);
+ void insertFloatMeta(const openvdb::Name &name, const float value);
+ void insertIntMeta(const openvdb::Name &name, const int value);
+ void insertVec3sMeta(const openvdb::Name &name, const openvdb::Vec3s &value);
+ void insertVec3IMeta(const openvdb::Name &name, const openvdb::Vec3I &value);
+ void insertMat4sMeta(const openvdb::Name &name, const float value[4][4]);
- void setFlags(const int compression, const bool save_as_half);
+ void setFlags(const int compression, const bool save_as_half);
- void write(const openvdb::Name &filename) const;
+ void write(const openvdb::Name &filename) const;
};
#endif /* __OPENVDB_WRITER_H__ */
diff --git a/intern/openvdb/openvdb_capi.cc b/intern/openvdb/openvdb_capi.cc
index 997c7638537..aff27ee6c62 100644
--- a/intern/openvdb/openvdb_capi.cc
+++ b/intern/openvdb/openvdb_capi.cc
@@ -21,216 +21,220 @@
#include "openvdb_dense_convert.h"
#include "openvdb_util.h"
-struct OpenVDBFloatGrid { int unused; };
-struct OpenVDBIntGrid { int unused; };
-struct OpenVDBVectorGrid { int unused; };
+struct OpenVDBFloatGrid {
+ int unused;
+};
+struct OpenVDBIntGrid {
+ int unused;
+};
+struct OpenVDBVectorGrid {
+ int unused;
+};
int OpenVDB_getVersionHex()
{
- return openvdb::OPENVDB_LIBRARY_VERSION;
+ return openvdb::OPENVDB_LIBRARY_VERSION;
}
-OpenVDBFloatGrid *OpenVDB_export_grid_fl(
- OpenVDBWriter *writer,
- const char *name, float *data,
- const int res[3], float matrix[4][4], const float clipping,
- OpenVDBFloatGrid *mask)
+OpenVDBFloatGrid *OpenVDB_export_grid_fl(OpenVDBWriter *writer,
+ const char *name,
+ float *data,
+ const int res[3],
+ float matrix[4][4],
+ const float clipping,
+ OpenVDBFloatGrid *mask)
{
- Timer(__func__);
+ Timer(__func__);
- using openvdb::FloatGrid;
+ using openvdb::FloatGrid;
- FloatGrid *mask_grid = reinterpret_cast<FloatGrid *>(mask);
- FloatGrid *grid = internal::OpenVDB_export_grid<FloatGrid>(
- writer,
- name,
- data,
- res,
- matrix,
- clipping,
- mask_grid);
+ FloatGrid *mask_grid = reinterpret_cast<FloatGrid *>(mask);
+ FloatGrid *grid = internal::OpenVDB_export_grid<FloatGrid>(
+ writer, name, data, res, matrix, clipping, mask_grid);
- return reinterpret_cast<OpenVDBFloatGrid *>(grid);
+ return reinterpret_cast<OpenVDBFloatGrid *>(grid);
}
-OpenVDBIntGrid *OpenVDB_export_grid_ch(
- OpenVDBWriter *writer,
- const char *name, unsigned char *data,
- const int res[3], float matrix[4][4], const float clipping,
- OpenVDBFloatGrid *mask)
+OpenVDBIntGrid *OpenVDB_export_grid_ch(OpenVDBWriter *writer,
+ const char *name,
+ unsigned char *data,
+ const int res[3],
+ float matrix[4][4],
+ const float clipping,
+ OpenVDBFloatGrid *mask)
{
- Timer(__func__);
+ Timer(__func__);
- using openvdb::FloatGrid;
- using openvdb::Int32Grid;
+ using openvdb::FloatGrid;
+ using openvdb::Int32Grid;
- FloatGrid *mask_grid = reinterpret_cast<FloatGrid *>(mask);
- Int32Grid *grid = internal::OpenVDB_export_grid<Int32Grid>(
- writer,
- name,
- data,
- res,
- matrix,
- clipping,
- mask_grid);
+ FloatGrid *mask_grid = reinterpret_cast<FloatGrid *>(mask);
+ Int32Grid *grid = internal::OpenVDB_export_grid<Int32Grid>(
+ writer, name, data, res, matrix, clipping, mask_grid);
- return reinterpret_cast<OpenVDBIntGrid *>(grid);
+ return reinterpret_cast<OpenVDBIntGrid *>(grid);
}
OpenVDBVectorGrid *OpenVDB_export_grid_vec(struct OpenVDBWriter *writer,
- const char *name,
- const float *data_x, const float *data_y, const float *data_z,
- const int res[3], float matrix[4][4], short vec_type, const float clipping,
- const bool is_color, OpenVDBFloatGrid *mask)
+ const char *name,
+ const float *data_x,
+ const float *data_y,
+ const float *data_z,
+ const int res[3],
+ float matrix[4][4],
+ short vec_type,
+ const float clipping,
+ const bool is_color,
+ OpenVDBFloatGrid *mask)
{
- Timer(__func__);
+ Timer(__func__);
- using openvdb::GridBase;
- using openvdb::FloatGrid;
- using openvdb::VecType;
+ using openvdb::FloatGrid;
+ using openvdb::GridBase;
+ using openvdb::VecType;
- FloatGrid *mask_grid = reinterpret_cast<FloatGrid *>(mask);
- GridBase *grid = internal::OpenVDB_export_vector_grid(
- writer,
- name,
- data_x,
- data_y,
- data_z,
- res,
- matrix,
- static_cast<VecType>(vec_type),
- is_color,
- clipping,
- mask_grid);
+ FloatGrid *mask_grid = reinterpret_cast<FloatGrid *>(mask);
+ GridBase *grid = internal::OpenVDB_export_vector_grid(writer,
+ name,
+ data_x,
+ data_y,
+ data_z,
+ res,
+ matrix,
+ static_cast<VecType>(vec_type),
+ is_color,
+ clipping,
+ mask_grid);
- return reinterpret_cast<OpenVDBVectorGrid *>(grid);
+ return reinterpret_cast<OpenVDBVectorGrid *>(grid);
}
-void OpenVDB_import_grid_fl(
- OpenVDBReader *reader,
- const char *name, float **data,
- const int res[3])
+void OpenVDB_import_grid_fl(OpenVDBReader *reader,
+ const char *name,
+ float **data,
+ const int res[3])
{
- Timer(__func__);
+ Timer(__func__);
- internal::OpenVDB_import_grid<openvdb::FloatGrid>(reader, name, data, res);
+ internal::OpenVDB_import_grid<openvdb::FloatGrid>(reader, name, data, res);
}
-void OpenVDB_import_grid_ch(
- OpenVDBReader *reader,
- const char *name, unsigned char **data,
- const int res[3])
+void OpenVDB_import_grid_ch(OpenVDBReader *reader,
+ const char *name,
+ unsigned char **data,
+ const int res[3])
{
- internal::OpenVDB_import_grid<openvdb::Int32Grid>(reader, name, data, res);
+ internal::OpenVDB_import_grid<openvdb::Int32Grid>(reader, name, data, res);
}
-void OpenVDB_import_grid_vec(
- struct OpenVDBReader *reader,
- const char *name,
- float **data_x, float **data_y, float **data_z,
- const int res[3])
+void OpenVDB_import_grid_vec(struct OpenVDBReader *reader,
+ const char *name,
+ float **data_x,
+ float **data_y,
+ float **data_z,
+ const int res[3])
{
- Timer(__func__);
+ Timer(__func__);
- internal::OpenVDB_import_grid_vector(reader, name, data_x, data_y, data_z, res);
+ internal::OpenVDB_import_grid_vector(reader, name, data_x, data_y, data_z, res);
}
OpenVDBWriter *OpenVDBWriter_create()
{
- return new OpenVDBWriter();
+ return new OpenVDBWriter();
}
void OpenVDBWriter_free(OpenVDBWriter *writer)
{
- delete writer;
+ delete writer;
}
void OpenVDBWriter_set_flags(OpenVDBWriter *writer, const int flag, const bool half)
{
- int compression_flags = openvdb::io::COMPRESS_ACTIVE_MASK;
+ int compression_flags = openvdb::io::COMPRESS_ACTIVE_MASK;
#ifdef WITH_OPENVDB_BLOSC
- if (flag == 0) {
- compression_flags |= openvdb::io::COMPRESS_BLOSC;
- }
- else
+ if (flag == 0) {
+ compression_flags |= openvdb::io::COMPRESS_BLOSC;
+ }
+ else
#endif
- if (flag == 1) {
- compression_flags |= openvdb::io::COMPRESS_ZIP;
- }
- else {
- compression_flags = openvdb::io::COMPRESS_NONE;
- }
+ if (flag == 1) {
+ compression_flags |= openvdb::io::COMPRESS_ZIP;
+ }
+ else {
+ compression_flags = openvdb::io::COMPRESS_NONE;
+ }
- writer->setFlags(compression_flags, half);
+ writer->setFlags(compression_flags, half);
}
void OpenVDBWriter_add_meta_fl(OpenVDBWriter *writer, const char *name, const float value)
{
- writer->insertFloatMeta(name, value);
+ writer->insertFloatMeta(name, value);
}
void OpenVDBWriter_add_meta_int(OpenVDBWriter *writer, const char *name, const int value)
{
- writer->insertIntMeta(name, value);
+ writer->insertIntMeta(name, value);
}
void OpenVDBWriter_add_meta_v3(OpenVDBWriter *writer, const char *name, const float value[3])
{
- writer->insertVec3sMeta(name, value);
+ writer->insertVec3sMeta(name, value);
}
void OpenVDBWriter_add_meta_v3_int(OpenVDBWriter *writer, const char *name, const int value[3])
{
- writer->insertVec3IMeta(name, value);
+ writer->insertVec3IMeta(name, value);
}
void OpenVDBWriter_add_meta_mat4(OpenVDBWriter *writer, const char *name, float value[4][4])
{
- writer->insertMat4sMeta(name, value);
+ writer->insertMat4sMeta(name, value);
}
void OpenVDBWriter_write(OpenVDBWriter *writer, const char *filename)
{
- writer->write(filename);
+ writer->write(filename);
}
OpenVDBReader *OpenVDBReader_create()
{
- return new OpenVDBReader();
+ return new OpenVDBReader();
}
void OpenVDBReader_free(OpenVDBReader *reader)
{
- delete reader;
+ delete reader;
}
void OpenVDBReader_open(OpenVDBReader *reader, const char *filename)
{
- reader->open(filename);
+ reader->open(filename);
}
void OpenVDBReader_get_meta_fl(OpenVDBReader *reader, const char *name, float *value)
{
- reader->floatMeta(name, *value);
+ reader->floatMeta(name, *value);
}
void OpenVDBReader_get_meta_int(OpenVDBReader *reader, const char *name, int *value)
{
- reader->intMeta(name, *value);
+ reader->intMeta(name, *value);
}
void OpenVDBReader_get_meta_v3(OpenVDBReader *reader, const char *name, float value[3])
{
- reader->vec3sMeta(name, value);
+ reader->vec3sMeta(name, value);
}
void OpenVDBReader_get_meta_v3_int(OpenVDBReader *reader, const char *name, int value[3])
{
- reader->vec3IMeta(name, value);
+ reader->vec3IMeta(name, value);
}
void OpenVDBReader_get_meta_mat4(OpenVDBReader *reader, const char *name, float value[4][4])
{
- reader->mat4sMeta(name, value);
+ reader->mat4sMeta(name, value);
}
diff --git a/intern/openvdb/openvdb_capi.h b/intern/openvdb/openvdb_capi.h
index 7af16509753..236bceea3e2 100644
--- a/intern/openvdb/openvdb_capi.h
+++ b/intern/openvdb/openvdb_capi.h
@@ -33,55 +33,72 @@ struct OpenVDBVectorGrid;
int OpenVDB_getVersionHex(void);
enum {
- VEC_INVARIANT = 0,
- VEC_COVARIANT = 1,
- VEC_COVARIANT_NORMALIZE = 2,
- VEC_CONTRAVARIANT_RELATIVE = 3,
- VEC_CONTRAVARIANT_ABSOLUTE = 4,
+ VEC_INVARIANT = 0,
+ VEC_COVARIANT = 1,
+ VEC_COVARIANT_NORMALIZE = 2,
+ VEC_CONTRAVARIANT_RELATIVE = 3,
+ VEC_CONTRAVARIANT_ABSOLUTE = 4,
};
-struct OpenVDBFloatGrid *OpenVDB_export_grid_fl(
- struct OpenVDBWriter *writer,
- const char *name, float *data,
- const int res[3], float matrix[4][4], const float clipping,
- struct OpenVDBFloatGrid *mask);
+struct OpenVDBFloatGrid *OpenVDB_export_grid_fl(struct OpenVDBWriter *writer,
+ const char *name,
+ float *data,
+ const int res[3],
+ float matrix[4][4],
+ const float clipping,
+ struct OpenVDBFloatGrid *mask);
struct OpenVDBIntGrid *OpenVDB_export_grid_ch(struct OpenVDBWriter *writer,
- const char *name, unsigned char *data,
- const int res[3], float matrix[4][4], const float clipping,
- struct OpenVDBFloatGrid *mask);
+ const char *name,
+ unsigned char *data,
+ const int res[3],
+ float matrix[4][4],
+ const float clipping,
+ struct OpenVDBFloatGrid *mask);
struct OpenVDBVectorGrid *OpenVDB_export_grid_vec(struct OpenVDBWriter *writer,
- const char *name,
- const float *data_x, const float *data_y, const float *data_z,
- const int res[3], float matrix[4][4], short vec_type, const float clipping,
- const bool is_color,
- struct OpenVDBFloatGrid *mask);
+ const char *name,
+ const float *data_x,
+ const float *data_y,
+ const float *data_z,
+ const int res[3],
+ float matrix[4][4],
+ short vec_type,
+ const float clipping,
+ const bool is_color,
+ struct OpenVDBFloatGrid *mask);
-void OpenVDB_import_grid_fl(
- struct OpenVDBReader *reader,
- const char *name, float **data,
- const int res[3]);
+void OpenVDB_import_grid_fl(struct OpenVDBReader *reader,
+ const char *name,
+ float **data,
+ const int res[3]);
-void OpenVDB_import_grid_ch(
- struct OpenVDBReader *reader,
- const char *name, unsigned char **data,
- const int res[3]);
+void OpenVDB_import_grid_ch(struct OpenVDBReader *reader,
+ const char *name,
+ unsigned char **data,
+ const int res[3]);
-void OpenVDB_import_grid_vec(
- struct OpenVDBReader *reader,
- const char *name,
- float **data_x, float **data_y, float **data_z,
- const int res[3]);
+void OpenVDB_import_grid_vec(struct OpenVDBReader *reader,
+ const char *name,
+ float **data_x,
+ float **data_y,
+ float **data_z,
+ const int res[3]);
struct OpenVDBWriter *OpenVDBWriter_create(void);
void OpenVDBWriter_free(struct OpenVDBWriter *writer);
void OpenVDBWriter_set_flags(struct OpenVDBWriter *writer, const int flag, const bool half);
void OpenVDBWriter_add_meta_fl(struct OpenVDBWriter *writer, const char *name, const float value);
void OpenVDBWriter_add_meta_int(struct OpenVDBWriter *writer, const char *name, const int value);
-void OpenVDBWriter_add_meta_v3(struct OpenVDBWriter *writer, const char *name, const float value[3]);
-void OpenVDBWriter_add_meta_v3_int(struct OpenVDBWriter *writer, const char *name, const int value[3]);
-void OpenVDBWriter_add_meta_mat4(struct OpenVDBWriter *writer, const char *name, float value[4][4]);
+void OpenVDBWriter_add_meta_v3(struct OpenVDBWriter *writer,
+ const char *name,
+ const float value[3]);
+void OpenVDBWriter_add_meta_v3_int(struct OpenVDBWriter *writer,
+ const char *name,
+ const int value[3]);
+void OpenVDBWriter_add_meta_mat4(struct OpenVDBWriter *writer,
+ const char *name,
+ float value[4][4]);
void OpenVDBWriter_write(struct OpenVDBWriter *writer, const char *filename);
struct OpenVDBReader *OpenVDBReader_create(void);
@@ -91,7 +108,9 @@ void OpenVDBReader_get_meta_fl(struct OpenVDBReader *reader, const char *name, f
void OpenVDBReader_get_meta_int(struct OpenVDBReader *reader, const char *name, int *value);
void OpenVDBReader_get_meta_v3(struct OpenVDBReader *reader, const char *name, float value[3]);
void OpenVDBReader_get_meta_v3_int(struct OpenVDBReader *reader, const char *name, int value[3]);
-void OpenVDBReader_get_meta_mat4(struct OpenVDBReader *reader, const char *name, float value[4][4]);
+void OpenVDBReader_get_meta_mat4(struct OpenVDBReader *reader,
+ const char *name,
+ float value[4][4]);
#ifdef __cplusplus
}
diff --git a/intern/openvdb/openvdb_util.cc b/intern/openvdb/openvdb_util.cc
index 5d8dcbf41f9..a221a537851 100644
--- a/intern/openvdb/openvdb_util.cc
+++ b/intern/openvdb/openvdb_util.cc
@@ -21,12 +21,11 @@
#include <cstdio>
-ScopeTimer::ScopeTimer(const std::string &message)
- : m_message(message)
- , m_timer()
-{}
+ScopeTimer::ScopeTimer(const std::string &message) : m_message(message), m_timer()
+{
+}
ScopeTimer::~ScopeTimer()
{
- std::printf("%s: %fms\n", m_message.c_str(), m_timer.delta());
+ std::printf("%s: %fms\n", m_message.c_str(), m_timer.delta());
}
diff --git a/intern/openvdb/openvdb_util.h b/intern/openvdb/openvdb_util.h
index 13c2ac610cb..7a19d588068 100644
--- a/intern/openvdb/openvdb_util.h
+++ b/intern/openvdb/openvdb_util.h
@@ -24,28 +24,28 @@
#include <openvdb/util/CpuTimer.h>
#define CATCH_KEYERROR \
- catch (const openvdb::KeyError &e) { \
- std::cerr << e.what() << '\n'; \
- }
+ catch (const openvdb::KeyError &e) \
+ { \
+ std::cerr << e.what() << '\n'; \
+ }
//#define DEBUG_TIME
/* A utility class which prints the time elapsed during its lifetime, useful for
* e.g. timing the overall execution time of a function */
class ScopeTimer {
- std::string m_message;
- openvdb::util::CpuTimer m_timer;
+ std::string m_message;
+ openvdb::util::CpuTimer m_timer;
-public:
- ScopeTimer(const std::string &message);
- ~ScopeTimer();
+ public:
+ ScopeTimer(const std::string &message);
+ ~ScopeTimer();
};
#ifdef DEBUG_TIME
-# define Timer(x) \
- ScopeTimer prof(x);
+# define Timer(x) ScopeTimer prof(x);
#else
-# define Timer(x)
+# define Timer(x)
#endif
#endif /* __OPENVDB_UTIL_H__ */
diff --git a/intern/rigidbody/CMakeLists.txt b/intern/rigidbody/CMakeLists.txt
index 02841c134c0..cf9b70448e0 100644
--- a/intern/rigidbody/CMakeLists.txt
+++ b/intern/rigidbody/CMakeLists.txt
@@ -19,17 +19,17 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
+ .
)
set(INC_SYS
- ${BULLET_INCLUDE_DIRS}
+ ${BULLET_INCLUDE_DIRS}
)
set(SRC
- rb_bullet_api.cpp
+ rb_bullet_api.cpp
- RBI_api.h
+ RBI_api.h
)
set(LIB
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 19ddc8467b6..9a7cbec6879 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -84,7 +84,10 @@ void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse);
/* Simulation ----------------------- */
/* Step the simulation by the desired amount (in seconds) with extra controls on substep sizes and maximum substeps */
-void RB_dworld_step_simulation(rbDynamicsWorld *world, float timeStep, int maxSubSteps, float timeSubStep);
+void RB_dworld_step_simulation(rbDynamicsWorld *world,
+ float timeStep,
+ int maxSubSteps,
+ float timeSubStep);
/* Export -------------------------- */
@@ -104,10 +107,14 @@ void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *body);
/* Collision detection */
-void RB_world_convex_sweep_test(
- rbDynamicsWorld *world, rbRigidBody *object,
- const float loc_start[3], const float loc_end[3],
- float v_location[3], float v_hitpoint[3], float v_normal[3], int *r_hit);
+void RB_world_convex_sweep_test(rbDynamicsWorld *world,
+ rbRigidBody *object,
+ const float loc_start[3],
+ const float loc_end[3],
+ float v_location[3],
+ float v_hitpoint[3],
+ float v_normal[3],
+ int *r_hit);
/* ............ */
@@ -180,7 +187,6 @@ void RB_body_set_activation_state(rbRigidBody *body, int use_deactivation);
void RB_body_activate(rbRigidBody *body);
void RB_body_deactivate(rbRigidBody *body);
-
/* Simulation ----------------------- */
/* Get current transform matrix of RigidBody to use in Blender (OpenGL format) */
@@ -215,21 +221,22 @@ rbCollisionShape *RB_shape_new_cylinder(float radius, float height);
/* Setup (Convex Hull) ------------ */
-rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed);
+rbCollisionShape *RB_shape_new_convex_hull(
+ float *verts, int stride, int count, float margin, bool *can_embed);
/* Setup (Triangle Mesh) ---------- */
/* 1 */
rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts);
void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride);
-void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2);
+void RB_trimesh_add_triangle_indices(
+ rbMeshData *mesh, int num, int index0, int index1, int index2);
void RB_trimesh_finish(rbMeshData *mesh);
/* 2a - Triangle Meshes */
rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh);
/* 2b - GImpact Meshes */
rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh);
-
/* Cleanup --------------------------- */
void RB_shape_delete(rbCollisionShape *shape);
@@ -240,7 +247,12 @@ void RB_shape_delete(rbCollisionShape *shape);
float RB_shape_get_margin(rbCollisionShape *shape);
void RB_shape_set_margin(rbCollisionShape *shape, float value);
-void RB_shape_trimesh_update(rbCollisionShape *shape, float *vertices, int num_verts, int vert_stride, float min[3], float max[3]);
+void RB_shape_trimesh_update(rbCollisionShape *shape,
+ float *vertices,
+ int num_verts,
+ int vert_stride,
+ float min[3],
+ float max[3]);
/* ********************************** */
/* Constraints */
@@ -254,14 +266,38 @@ void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int dis
void RB_dworld_remove_constraint(rbDynamicsWorld *world, rbConstraint *con);
rbConstraint *RB_constraint_new_point(float pivot[3], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_fixed(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_hinge(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
-rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_fixed(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_hinge(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_slider(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_piston(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_6dof(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_6dof_spring(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_motor(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2);
/* ............ */
@@ -288,7 +324,8 @@ void RB_constraint_set_enabled(rbConstraint *con, int enabled);
*/
void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper);
void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper);
-void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper);
+void RB_constraint_set_limits_piston(
+ rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper);
void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper);
/* 6dof spring specific */
@@ -306,8 +343,12 @@ void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con);
/* motors */
void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang);
-void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang);
-void RB_constraint_set_target_velocity_motor(rbConstraint *con, float velocity_lin, float velocity_ang);
+void RB_constraint_set_max_impulse_motor(rbConstraint *con,
+ float max_impulse_lin,
+ float max_impulse_ang);
+void RB_constraint_set_target_velocity_motor(rbConstraint *con,
+ float velocity_lin,
+ float velocity_ang);
/* Set number of constraint solver iterations made per step, this overrided world setting
* To use default set it to -1 */
@@ -323,4 +364,3 @@ void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold);
#endif
#endif /* __RB_API_H__ */
-
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 195107d71d5..afeddc4d790 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -36,7 +36,7 @@ subject to the following restrictions:
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
-
+
/* This file defines the "RigidBody interface" for the
* Bullet Physics Engine. This API is designed to be used
* from C-code in Blender as part of the Rigid Body simulation
@@ -56,7 +56,7 @@ subject to the following restrictions:
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
-#include "LinearMath/btScalar.h"
+#include "LinearMath/btScalar.h"
#include "LinearMath/btMatrix3x3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btConvexHullComputer.h"
@@ -66,66 +66,65 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
struct rbDynamicsWorld {
- btDiscreteDynamicsWorld *dynamicsWorld;
- btDefaultCollisionConfiguration *collisionConfiguration;
- btDispatcher *dispatcher;
- btBroadphaseInterface *pairCache;
- btConstraintSolver *constraintSolver;
- btOverlapFilterCallback *filterCallback;
+ btDiscreteDynamicsWorld *dynamicsWorld;
+ btDefaultCollisionConfiguration *collisionConfiguration;
+ btDispatcher *dispatcher;
+ btBroadphaseInterface *pairCache;
+ btConstraintSolver *constraintSolver;
+ btOverlapFilterCallback *filterCallback;
};
struct rbRigidBody {
- btRigidBody *body;
- int col_groups;
+ btRigidBody *body;
+ int col_groups;
};
struct rbVert {
- float x, y, z;
+ float x, y, z;
};
struct rbTri {
- int v0, v1, v2;
+ int v0, v1, v2;
};
struct rbMeshData {
- btTriangleIndexVertexArray *index_array;
- rbVert *vertices;
- rbTri *triangles;
- int num_vertices;
- int num_triangles;
+ btTriangleIndexVertexArray *index_array;
+ rbVert *vertices;
+ rbTri *triangles;
+ int num_vertices;
+ int num_triangles;
};
struct rbCollisionShape {
- btCollisionShape *cshape;
- rbMeshData *mesh;
+ btCollisionShape *cshape;
+ rbMeshData *mesh;
};
-struct rbFilterCallback : public btOverlapFilterCallback
-{
- virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
- {
- rbRigidBody *rb0 = (rbRigidBody *)((btRigidBody *)proxy0->m_clientObject)->getUserPointer();
- rbRigidBody *rb1 = (rbRigidBody *)((btRigidBody *)proxy1->m_clientObject)->getUserPointer();
-
- bool collides;
- collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
- collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
- collides = collides && (rb0->col_groups & rb1->col_groups);
-
- return collides;
- }
+struct rbFilterCallback : public btOverlapFilterCallback {
+ virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
+ {
+ rbRigidBody *rb0 = (rbRigidBody *)((btRigidBody *)proxy0->m_clientObject)->getUserPointer();
+ rbRigidBody *rb1 = (rbRigidBody *)((btRigidBody *)proxy1->m_clientObject)->getUserPointer();
+
+ bool collides;
+ collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+ collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+ collides = collides && (rb0->col_groups & rb1->col_groups);
+
+ return collides;
+ }
};
static inline void copy_v3_btvec3(float vec[3], const btVector3 &btvec)
{
- vec[0] = (float)btvec[0];
- vec[1] = (float)btvec[1];
- vec[2] = (float)btvec[2];
+ vec[0] = (float)btvec[0];
+ vec[1] = (float)btvec[1];
+ vec[2] = (float)btvec[2];
}
static inline void copy_quat_btquat(float quat[4], const btQuaternion &btquat)
{
- quat[0] = btquat.getW();
- quat[1] = btquat.getX();
- quat[2] = btquat.getY();
- quat[3] = btquat.getZ();
+ quat[0] = btquat.getW();
+ quat[1] = btquat.getX();
+ quat[2] = btquat.getY();
+ quat[3] = btquat.getZ();
}
/* ********************************** */
@@ -135,43 +134,41 @@ static inline void copy_quat_btquat(float quat[4], const btQuaternion &btquat)
rbDynamicsWorld *RB_dworld_new(const float gravity[3])
{
- rbDynamicsWorld *world = new rbDynamicsWorld;
-
- /* collision detection/handling */
- world->collisionConfiguration = new btDefaultCollisionConfiguration();
-
- world->dispatcher = new btCollisionDispatcher(world->collisionConfiguration);
- btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher *)world->dispatcher);
-
- world->pairCache = new btDbvtBroadphase();
-
- world->filterCallback = new rbFilterCallback();
- world->pairCache->getOverlappingPairCache()->setOverlapFilterCallback(world->filterCallback);
-
- /* constraint solving */
- world->constraintSolver = new btSequentialImpulseConstraintSolver();
-
- /* world */
- world->dynamicsWorld = new btDiscreteDynamicsWorld(world->dispatcher,
- world->pairCache,
- world->constraintSolver,
- world->collisionConfiguration);
-
- RB_dworld_set_gravity(world, gravity);
-
- return world;
+ rbDynamicsWorld *world = new rbDynamicsWorld;
+
+ /* collision detection/handling */
+ world->collisionConfiguration = new btDefaultCollisionConfiguration();
+
+ world->dispatcher = new btCollisionDispatcher(world->collisionConfiguration);
+ btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher *)world->dispatcher);
+
+ world->pairCache = new btDbvtBroadphase();
+
+ world->filterCallback = new rbFilterCallback();
+ world->pairCache->getOverlappingPairCache()->setOverlapFilterCallback(world->filterCallback);
+
+ /* constraint solving */
+ world->constraintSolver = new btSequentialImpulseConstraintSolver();
+
+ /* world */
+ world->dynamicsWorld = new btDiscreteDynamicsWorld(
+ world->dispatcher, world->pairCache, world->constraintSolver, world->collisionConfiguration);
+
+ RB_dworld_set_gravity(world, gravity);
+
+ return world;
}
void RB_dworld_delete(rbDynamicsWorld *world)
{
- /* bullet doesn't like if we free these in a different order */
- delete world->dynamicsWorld;
- delete world->constraintSolver;
- delete world->pairCache;
- delete world->dispatcher;
- delete world->collisionConfiguration;
- delete world->filterCallback;
- delete world;
+ /* bullet doesn't like if we free these in a different order */
+ delete world->dynamicsWorld;
+ delete world->constraintSolver;
+ delete world->pairCache;
+ delete world->dispatcher;
+ delete world->collisionConfiguration;
+ delete world->filterCallback;
+ delete world;
}
/* Settings ------------------------- */
@@ -179,35 +176,38 @@ void RB_dworld_delete(rbDynamicsWorld *world)
/* Gravity */
void RB_dworld_get_gravity(rbDynamicsWorld *world, float g_out[3])
{
- copy_v3_btvec3(g_out, world->dynamicsWorld->getGravity());
+ copy_v3_btvec3(g_out, world->dynamicsWorld->getGravity());
}
void RB_dworld_set_gravity(rbDynamicsWorld *world, const float g_in[3])
{
- world->dynamicsWorld->setGravity(btVector3(g_in[0], g_in[1], g_in[2]));
+ world->dynamicsWorld->setGravity(btVector3(g_in[0], g_in[1], g_in[2]));
}
/* Constraint Solver */
void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iterations)
{
- btContactSolverInfo& info = world->dynamicsWorld->getSolverInfo();
-
- info.m_numIterations = num_solver_iterations;
+ btContactSolverInfo &info = world->dynamicsWorld->getSolverInfo();
+
+ info.m_numIterations = num_solver_iterations;
}
/* Split Impulse */
void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
{
- btContactSolverInfo& info = world->dynamicsWorld->getSolverInfo();
-
- info.m_splitImpulse = split_impulse;
+ btContactSolverInfo &info = world->dynamicsWorld->getSolverInfo();
+
+ info.m_splitImpulse = split_impulse;
}
/* Simulation ----------------------- */
-void RB_dworld_step_simulation(rbDynamicsWorld *world, float timeStep, int maxSubSteps, float timeSubStep)
+void RB_dworld_step_simulation(rbDynamicsWorld *world,
+ float timeStep,
+ int maxSubSteps,
+ float timeSubStep)
{
- world->dynamicsWorld->stepSimulation(timeStep, maxSubSteps, timeSubStep);
+ world->dynamicsWorld->stepSimulation(timeStep, maxSubSteps, timeSubStep);
}
/* Export -------------------------- */
@@ -221,20 +221,20 @@ void RB_dworld_step_simulation(rbDynamicsWorld *world, float timeStep, int maxSu
*/
void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
{
- //create a large enough buffer. There is no method to pre-calculate the buffer size yet.
- int maxSerializeBufferSize = 1024 * 1024 * 5;
-
- btDefaultSerializer *serializer = new btDefaultSerializer(maxSerializeBufferSize);
- world->dynamicsWorld->serialize(serializer);
-
- FILE *file = fopen(filename, "wb");
- if (file) {
- fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
- fclose(file);
- }
- else {
- fprintf(stderr, "RB_dworld_export: %s\n", strerror(errno));
- }
+ //create a large enough buffer. There is no method to pre-calculate the buffer size yet.
+ int maxSerializeBufferSize = 1024 * 1024 * 5;
+
+ btDefaultSerializer *serializer = new btDefaultSerializer(maxSerializeBufferSize);
+ world->dynamicsWorld->serialize(serializer);
+
+ FILE *file = fopen(filename, "wb");
+ if (file) {
+ fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
+ fclose(file);
+ }
+ else {
+ fprintf(stderr, "RB_dworld_export: %s\n", strerror(errno));
+ }
}
/* ********************************** */
@@ -244,327 +244,332 @@ void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
{
- btRigidBody *body = object->body;
- object->col_groups = col_groups;
-
- world->dynamicsWorld->addRigidBody(body);
+ btRigidBody *body = object->body;
+ object->col_groups = col_groups;
+
+ world->dynamicsWorld->addRigidBody(body);
}
void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *object)
{
- btRigidBody *body = object->body;
-
- world->dynamicsWorld->removeRigidBody(body);
+ btRigidBody *body = object->body;
+
+ world->dynamicsWorld->removeRigidBody(body);
}
/* Collision detection */
-void RB_world_convex_sweep_test(
- rbDynamicsWorld *world, rbRigidBody *object,
- const float loc_start[3], const float loc_end[3],
- float v_location[3], float v_hitpoint[3], float v_normal[3], int *r_hit)
-{
- btRigidBody *body = object->body;
- btCollisionShape *collisionShape = body->getCollisionShape();
- /* only convex shapes are supported, but user can specify a non convex shape */
- if (collisionShape->isConvex()) {
- btCollisionWorld::ClosestConvexResultCallback result(btVector3(loc_start[0], loc_start[1], loc_start[2]), btVector3(loc_end[0], loc_end[1], loc_end[2]));
-
- btQuaternion obRot = body->getWorldTransform().getRotation();
-
- btTransform rayFromTrans;
- rayFromTrans.setIdentity();
- rayFromTrans.setRotation(obRot);
- rayFromTrans.setOrigin(btVector3(loc_start[0], loc_start[1], loc_start[2]));
-
- btTransform rayToTrans;
- rayToTrans.setIdentity();
- rayToTrans.setRotation(obRot);
- rayToTrans.setOrigin(btVector3(loc_end[0], loc_end[1], loc_end[2]));
-
- world->dynamicsWorld->convexSweepTest((btConvexShape *)collisionShape, rayFromTrans, rayToTrans, result, 0);
-
- if (result.hasHit()) {
- *r_hit = 1;
-
- v_location[0] = result.m_convexFromWorld[0] + (result.m_convexToWorld[0] - result.m_convexFromWorld[0]) * result.m_closestHitFraction;
- v_location[1] = result.m_convexFromWorld[1] + (result.m_convexToWorld[1] - result.m_convexFromWorld[1]) * result.m_closestHitFraction;
- v_location[2] = result.m_convexFromWorld[2] + (result.m_convexToWorld[2] - result.m_convexFromWorld[2]) * result.m_closestHitFraction;
-
- v_hitpoint[0] = result.m_hitPointWorld[0];
- v_hitpoint[1] = result.m_hitPointWorld[1];
- v_hitpoint[2] = result.m_hitPointWorld[2];
-
- v_normal[0] = result.m_hitNormalWorld[0];
- v_normal[1] = result.m_hitNormalWorld[1];
- v_normal[2] = result.m_hitNormalWorld[2];
-
- }
- else {
- *r_hit = 0;
- }
- }
- else {
- /* we need to return a value if user passes non convex body, to report */
- *r_hit = -2;
- }
+void RB_world_convex_sweep_test(rbDynamicsWorld *world,
+ rbRigidBody *object,
+ const float loc_start[3],
+ const float loc_end[3],
+ float v_location[3],
+ float v_hitpoint[3],
+ float v_normal[3],
+ int *r_hit)
+{
+ btRigidBody *body = object->body;
+ btCollisionShape *collisionShape = body->getCollisionShape();
+ /* only convex shapes are supported, but user can specify a non convex shape */
+ if (collisionShape->isConvex()) {
+ btCollisionWorld::ClosestConvexResultCallback result(
+ btVector3(loc_start[0], loc_start[1], loc_start[2]),
+ btVector3(loc_end[0], loc_end[1], loc_end[2]));
+
+ btQuaternion obRot = body->getWorldTransform().getRotation();
+
+ btTransform rayFromTrans;
+ rayFromTrans.setIdentity();
+ rayFromTrans.setRotation(obRot);
+ rayFromTrans.setOrigin(btVector3(loc_start[0], loc_start[1], loc_start[2]));
+
+ btTransform rayToTrans;
+ rayToTrans.setIdentity();
+ rayToTrans.setRotation(obRot);
+ rayToTrans.setOrigin(btVector3(loc_end[0], loc_end[1], loc_end[2]));
+
+ world->dynamicsWorld->convexSweepTest(
+ (btConvexShape *)collisionShape, rayFromTrans, rayToTrans, result, 0);
+
+ if (result.hasHit()) {
+ *r_hit = 1;
+
+ v_location[0] = result.m_convexFromWorld[0] +
+ (result.m_convexToWorld[0] - result.m_convexFromWorld[0]) *
+ result.m_closestHitFraction;
+ v_location[1] = result.m_convexFromWorld[1] +
+ (result.m_convexToWorld[1] - result.m_convexFromWorld[1]) *
+ result.m_closestHitFraction;
+ v_location[2] = result.m_convexFromWorld[2] +
+ (result.m_convexToWorld[2] - result.m_convexFromWorld[2]) *
+ result.m_closestHitFraction;
+
+ v_hitpoint[0] = result.m_hitPointWorld[0];
+ v_hitpoint[1] = result.m_hitPointWorld[1];
+ v_hitpoint[2] = result.m_hitPointWorld[2];
+
+ v_normal[0] = result.m_hitNormalWorld[0];
+ v_normal[1] = result.m_hitNormalWorld[1];
+ v_normal[2] = result.m_hitNormalWorld[2];
+ }
+ else {
+ *r_hit = 0;
+ }
+ }
+ else {
+ /* we need to return a value if user passes non convex body, to report */
+ *r_hit = -2;
+ }
}
/* ............ */
rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
{
- rbRigidBody *object = new rbRigidBody;
- /* current transform */
- btTransform trans;
- trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
- trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
-
- /* create motionstate, which is necessary for interpolation (includes reverse playback) */
- btDefaultMotionState *motionState = new btDefaultMotionState(trans);
-
- /* make rigidbody */
- btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
-
- object->body = new btRigidBody(rbInfo);
-
- object->body->setUserPointer(object);
-
- return object;
+ rbRigidBody *object = new rbRigidBody;
+ /* current transform */
+ btTransform trans;
+ trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
+ trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+
+ /* create motionstate, which is necessary for interpolation (includes reverse playback) */
+ btDefaultMotionState *motionState = new btDefaultMotionState(trans);
+
+ /* make rigidbody */
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
+
+ object->body = new btRigidBody(rbInfo);
+
+ object->body->setUserPointer(object);
+
+ return object;
}
void RB_body_delete(rbRigidBody *object)
{
- btRigidBody *body = object->body;
-
- /* motion state */
- btMotionState *ms = body->getMotionState();
- if (ms)
- delete ms;
-
- /* collision shape is done elsewhere... */
-
- /* body itself */
-
- /* manually remove constraint refs of the rigid body, normally this happens when removing constraints from the world
- * but since we delete everything when the world is rebult, we need to do it manually here */
- for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
- btTypedConstraint *con = body->getConstraintRef(i);
- body->removeConstraintRef(con);
- }
-
- delete body;
- delete object;
+ btRigidBody *body = object->body;
+
+ /* motion state */
+ btMotionState *ms = body->getMotionState();
+ if (ms)
+ delete ms;
+
+ /* collision shape is done elsewhere... */
+
+ /* body itself */
+
+ /* manually remove constraint refs of the rigid body, normally this happens when removing constraints from the world
+ * but since we delete everything when the world is rebult, we need to do it manually here */
+ for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
+ btTypedConstraint *con = body->getConstraintRef(i);
+ body->removeConstraintRef(con);
+ }
+
+ delete body;
+ delete object;
}
/* Settings ------------------------- */
void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
{
- btRigidBody *body = object->body;
-
- /* set new collision shape */
- body->setCollisionShape(shape->cshape);
-
- /* recalculate inertia, since that depends on the collision shape... */
- RB_body_set_mass(object, RB_body_get_mass(object));
+ btRigidBody *body = object->body;
+
+ /* set new collision shape */
+ body->setCollisionShape(shape->cshape);
+
+ /* recalculate inertia, since that depends on the collision shape... */
+ RB_body_set_mass(object, RB_body_get_mass(object));
}
/* ............ */
float RB_body_get_mass(rbRigidBody *object)
{
- btRigidBody *body = object->body;
-
- /* there isn't really a mass setting, but rather 'inverse mass'
- * which we convert back to mass by taking the reciprocal again
- */
- float value = (float)body->getInvMass();
-
- if (value)
- value = 1.0f / value;
-
- return value;
+ btRigidBody *body = object->body;
+
+ /* there isn't really a mass setting, but rather 'inverse mass'
+ * which we convert back to mass by taking the reciprocal again
+ */
+ float value = (float)body->getInvMass();
+
+ if (value)
+ value = 1.0f / value;
+
+ return value;
}
void RB_body_set_mass(rbRigidBody *object, float value)
{
- btRigidBody *body = object->body;
- btVector3 localInertia(0, 0, 0);
-
- /* calculate new inertia if non-zero mass */
- if (value) {
- btCollisionShape *shape = body->getCollisionShape();
- shape->calculateLocalInertia(value, localInertia);
- }
-
- body->setMassProps(value, localInertia);
- body->updateInertiaTensor();
-}
+ btRigidBody *body = object->body;
+ btVector3 localInertia(0, 0, 0);
+ /* calculate new inertia if non-zero mass */
+ if (value) {
+ btCollisionShape *shape = body->getCollisionShape();
+ shape->calculateLocalInertia(value, localInertia);
+ }
+
+ body->setMassProps(value, localInertia);
+ body->updateInertiaTensor();
+}
float RB_body_get_friction(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- return body->getFriction();
+ btRigidBody *body = object->body;
+ return body->getFriction();
}
void RB_body_set_friction(rbRigidBody *object, float value)
{
- btRigidBody *body = object->body;
- body->setFriction(value);
+ btRigidBody *body = object->body;
+ body->setFriction(value);
}
-
float RB_body_get_restitution(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- return body->getRestitution();
+ btRigidBody *body = object->body;
+ return body->getRestitution();
}
void RB_body_set_restitution(rbRigidBody *object, float value)
{
- btRigidBody *body = object->body;
- body->setRestitution(value);
+ btRigidBody *body = object->body;
+ body->setRestitution(value);
}
-
float RB_body_get_linear_damping(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- return body->getLinearDamping();
+ btRigidBody *body = object->body;
+ return body->getLinearDamping();
}
void RB_body_set_linear_damping(rbRigidBody *object, float value)
{
- RB_body_set_damping(object, value, RB_body_get_linear_damping(object));
+ RB_body_set_damping(object, value, RB_body_get_linear_damping(object));
}
float RB_body_get_angular_damping(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- return body->getAngularDamping();
+ btRigidBody *body = object->body;
+ return body->getAngularDamping();
}
void RB_body_set_angular_damping(rbRigidBody *object, float value)
{
- RB_body_set_damping(object, RB_body_get_linear_damping(object), value);
+ RB_body_set_damping(object, RB_body_get_linear_damping(object), value);
}
void RB_body_set_damping(rbRigidBody *object, float linear, float angular)
{
- btRigidBody *body = object->body;
- body->setDamping(linear, angular);
+ btRigidBody *body = object->body;
+ body->setDamping(linear, angular);
}
-
float RB_body_get_linear_sleep_thresh(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- return body->getLinearSleepingThreshold();
+ btRigidBody *body = object->body;
+ return body->getLinearSleepingThreshold();
}
void RB_body_set_linear_sleep_thresh(rbRigidBody *object, float value)
{
- RB_body_set_sleep_thresh(object, value, RB_body_get_angular_sleep_thresh(object));
+ RB_body_set_sleep_thresh(object, value, RB_body_get_angular_sleep_thresh(object));
}
float RB_body_get_angular_sleep_thresh(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- return body->getAngularSleepingThreshold();
+ btRigidBody *body = object->body;
+ return body->getAngularSleepingThreshold();
}
void RB_body_set_angular_sleep_thresh(rbRigidBody *object, float value)
{
- RB_body_set_sleep_thresh(object, RB_body_get_linear_sleep_thresh(object), value);
+ RB_body_set_sleep_thresh(object, RB_body_get_linear_sleep_thresh(object), value);
}
void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
{
- btRigidBody *body = object->body;
- body->setSleepingThresholds(linear, angular);
+ btRigidBody *body = object->body;
+ body->setSleepingThresholds(linear, angular);
}
/* ............ */
void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
{
- btRigidBody *body = object->body;
-
- copy_v3_btvec3(v_out, body->getLinearVelocity());
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getLinearVelocity());
}
void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3])
{
- btRigidBody *body = object->body;
-
- body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
-}
+ btRigidBody *body = object->body;
+ body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
+}
void RB_body_get_angular_velocity(rbRigidBody *object, float v_out[3])
{
- btRigidBody *body = object->body;
-
- copy_v3_btvec3(v_out, body->getAngularVelocity());
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getAngularVelocity());
}
void RB_body_set_angular_velocity(rbRigidBody *object, const float v_in[3])
{
- btRigidBody *body = object->body;
-
- body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
+ btRigidBody *body = object->body;
+
+ body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
}
void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z)
{
- btRigidBody *body = object->body;
- body->setLinearFactor(btVector3(x, y, z));
+ btRigidBody *body = object->body;
+ body->setLinearFactor(btVector3(x, y, z));
}
void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
{
- btRigidBody *body = object->body;
- body->setAngularFactor(btVector3(x, y, z));
+ btRigidBody *body = object->body;
+ body->setAngularFactor(btVector3(x, y, z));
}
/* ............ */
void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
{
- btRigidBody *body = object->body;
- if (kinematic)
- body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- else
- body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
+ btRigidBody *body = object->body;
+ if (kinematic)
+ body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ else
+ body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
}
/* ............ */
void RB_body_set_activation_state(rbRigidBody *object, int use_deactivation)
{
- btRigidBody *body = object->body;
- if (use_deactivation)
- body->forceActivationState(ACTIVE_TAG);
- else
- body->setActivationState(DISABLE_DEACTIVATION);
+ btRigidBody *body = object->body;
+ if (use_deactivation)
+ body->forceActivationState(ACTIVE_TAG);
+ else
+ body->setActivationState(DISABLE_DEACTIVATION);
}
void RB_body_activate(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- body->setActivationState(ACTIVE_TAG);
+ btRigidBody *body = object->body;
+ body->setActivationState(ACTIVE_TAG);
}
void RB_body_deactivate(rbRigidBody *object)
{
- btRigidBody *body = object->body;
- body->setActivationState(ISLAND_SLEEPING);
+ btRigidBody *body = object->body;
+ body->setActivationState(ISLAND_SLEEPING);
}
/* ............ */
-
-
/* Simulation ----------------------- */
/* The transform matrices Blender uses are OpenGL-style matrices,
@@ -573,41 +578,41 @@ void RB_body_deactivate(rbRigidBody *object)
void RB_body_get_transform_matrix(rbRigidBody *object, float m_out[4][4])
{
- btRigidBody *body = object->body;
- btMotionState *ms = body->getMotionState();
-
- btTransform trans;
- ms->getWorldTransform(trans);
-
- trans.getOpenGLMatrix((btScalar *)m_out);
+ btRigidBody *body = object->body;
+ btMotionState *ms = body->getMotionState();
+
+ btTransform trans;
+ ms->getWorldTransform(trans);
+
+ trans.getOpenGLMatrix((btScalar *)m_out);
}
void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float rot[4])
{
- btRigidBody *body = object->body;
- btMotionState *ms = body->getMotionState();
-
- /* set transform matrix */
- btTransform trans;
- trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
- trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
-
- ms->setWorldTransform(trans);
+ btRigidBody *body = object->body;
+ btMotionState *ms = body->getMotionState();
+
+ /* set transform matrix */
+ btTransform trans;
+ trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
+ trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+
+ ms->setWorldTransform(trans);
}
void RB_body_set_scale(rbRigidBody *object, const float scale[3])
{
- btRigidBody *body = object->body;
-
- /* apply scaling factor from matrix above to the collision shape */
- btCollisionShape *cshape = body->getCollisionShape();
- if (cshape) {
- cshape->setLocalScaling(btVector3(scale[0], scale[1], scale[2]));
-
- /* GIimpact shapes have to be updated to take scaling into account */
- if (cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
- ((btGImpactMeshShape *)cshape)->updateBound();
- }
+ btRigidBody *body = object->body;
+
+ /* apply scaling factor from matrix above to the collision shape */
+ btCollisionShape *cshape = body->getCollisionShape();
+ if (cshape) {
+ cshape->setLocalScaling(btVector3(scale[0], scale[1], scale[2]));
+
+ /* GIimpact shapes have to be updated to take scaling into account */
+ if (cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
+ ((btGImpactMeshShape *)cshape)->updateBound();
+ }
}
/* ............ */
@@ -615,16 +620,16 @@ void RB_body_set_scale(rbRigidBody *object, const float scale[3])
void RB_body_get_position(rbRigidBody *object, float v_out[3])
{
- btRigidBody *body = object->body;
-
- copy_v3_btvec3(v_out, body->getWorldTransform().getOrigin());
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getWorldTransform().getOrigin());
}
void RB_body_get_orientation(rbRigidBody *object, float v_out[4])
{
- btRigidBody *body = object->body;
-
- copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
+ btRigidBody *body = object->body;
+
+ copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
}
/* ............ */
@@ -632,9 +637,9 @@ void RB_body_get_orientation(rbRigidBody *object, float v_out[4])
void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
{
- btRigidBody *body = object->body;
-
- body->applyCentralForce(btVector3(v_in[0], v_in[1], v_in[2]));
+ btRigidBody *body = object->body;
+
+ body->applyCentralForce(btVector3(v_in[0], v_in[1], v_in[2]));
}
/* ********************************** */
@@ -644,62 +649,64 @@ void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
rbCollisionShape *RB_shape_new_box(float x, float y, float z)
{
- rbCollisionShape *shape = new rbCollisionShape;
- shape->cshape = new btBoxShape(btVector3(x, y, z));
- shape->mesh = NULL;
- return shape;
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btBoxShape(btVector3(x, y, z));
+ shape->mesh = NULL;
+ return shape;
}
rbCollisionShape *RB_shape_new_sphere(float radius)
{
- rbCollisionShape *shape = new rbCollisionShape;
- shape->cshape = new btSphereShape(radius);
- shape->mesh = NULL;
- return shape;
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btSphereShape(radius);
+ shape->mesh = NULL;
+ return shape;
}
rbCollisionShape *RB_shape_new_capsule(float radius, float height)
{
- rbCollisionShape *shape = new rbCollisionShape;
- shape->cshape = new btCapsuleShapeZ(radius, height);
- shape->mesh = NULL;
- return shape;
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btCapsuleShapeZ(radius, height);
+ shape->mesh = NULL;
+ return shape;
}
rbCollisionShape *RB_shape_new_cone(float radius, float height)
{
- rbCollisionShape *shape = new rbCollisionShape;
- shape->cshape = new btConeShapeZ(radius, height);
- shape->mesh = NULL;
- return shape;
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btConeShapeZ(radius, height);
+ shape->mesh = NULL;
+ return shape;
}
rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
{
- rbCollisionShape *shape = new rbCollisionShape;
- shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
- shape->mesh = NULL;
- return shape;
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
+ shape->mesh = NULL;
+ return shape;
}
/* Setup (Convex Hull) ------------ */
-rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed)
+rbCollisionShape *RB_shape_new_convex_hull(
+ float *verts, int stride, int count, float margin, bool *can_embed)
{
- btConvexHullComputer hull_computer = btConvexHullComputer();
-
- // try to embed the margin, if that fails don't shrink the hull
- if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
- hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
- *can_embed = false;
- }
-
- rbCollisionShape *shape = new rbCollisionShape;
- btConvexHullShape *hull_shape = new btConvexHullShape(&(hull_computer.vertices[0].getX()), hull_computer.vertices.size());
-
- shape->cshape = hull_shape;
- shape->mesh = NULL;
- return shape;
+ btConvexHullComputer hull_computer = btConvexHullComputer();
+
+ // try to embed the margin, if that fails don't shrink the hull
+ if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
+ hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
+ *can_embed = false;
+ }
+
+ rbCollisionShape *shape = new rbCollisionShape;
+ btConvexHullShape *hull_shape = new btConvexHullShape(&(hull_computer.vertices[0].getX()),
+ hull_computer.vertices.size());
+
+ shape->cshape = hull_shape;
+ shape->mesh = NULL;
+ return shape;
}
/* Setup (Triangle Mesh) ---------- */
@@ -708,118 +715,129 @@ rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count,
rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts)
{
- rbMeshData *mesh = new rbMeshData;
- mesh->vertices = new rbVert[num_verts];
- mesh->triangles = new rbTri[num_tris];
- mesh->num_vertices = num_verts;
- mesh->num_triangles = num_tris;
-
- return mesh;
+ rbMeshData *mesh = new rbMeshData;
+ mesh->vertices = new rbVert[num_verts];
+ mesh->triangles = new rbTri[num_tris];
+ mesh->num_vertices = num_verts;
+ mesh->num_triangles = num_tris;
+
+ return mesh;
}
static void RB_trimesh_data_delete(rbMeshData *mesh)
{
- delete mesh->index_array;
- delete[] mesh->vertices;
- delete[] mesh->triangles;
- delete mesh;
+ delete mesh->index_array;
+ delete[] mesh->vertices;
+ delete[] mesh->triangles;
+ delete mesh;
}
-
+
void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride)
{
- for (int i = 0; i < num_verts; i++) {
- float *vert = (float*)(((char*)vertices + i * vert_stride));
- mesh->vertices[i].x = vert[0];
- mesh->vertices[i].y = vert[1];
- mesh->vertices[i].z = vert[2];
- }
+ for (int i = 0; i < num_verts; i++) {
+ float *vert = (float *)(((char *)vertices + i * vert_stride));
+ mesh->vertices[i].x = vert[0];
+ mesh->vertices[i].y = vert[1];
+ mesh->vertices[i].z = vert[2];
+ }
}
void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2)
{
- mesh->triangles[num].v0 = index0;
- mesh->triangles[num].v1 = index1;
- mesh->triangles[num].v2 = index2;
+ mesh->triangles[num].v0 = index0;
+ mesh->triangles[num].v1 = index1;
+ mesh->triangles[num].v2 = index2;
}
void RB_trimesh_finish(rbMeshData *mesh)
{
- mesh->index_array = new btTriangleIndexVertexArray(mesh->num_triangles, (int*)mesh->triangles, sizeof(rbTri),
- mesh->num_vertices, (float*)mesh->vertices, sizeof(rbVert));
+ mesh->index_array = new btTriangleIndexVertexArray(mesh->num_triangles,
+ (int *)mesh->triangles,
+ sizeof(rbTri),
+ mesh->num_vertices,
+ (float *)mesh->vertices,
+ sizeof(rbVert));
}
-
+
rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh)
{
- rbCollisionShape *shape = new rbCollisionShape;
-
- /* triangle-mesh we create is a BVH wrapper for triangle mesh data (for faster lookups) */
- // RB_TODO perhaps we need to allow saving out this for performance when rebuilding?
- btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(mesh->index_array, true, true);
-
- shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
- shape->mesh = mesh;
- return shape;
-}
-
-void RB_shape_trimesh_update(rbCollisionShape *shape, float *vertices, int num_verts, int vert_stride, float min[3], float max[3])
-{
- if (shape->mesh == NULL || num_verts != shape->mesh->num_vertices)
- return;
-
- for (int i = 0; i < num_verts; i++) {
- float *vert = (float*)(((char*)vertices + i * vert_stride));
- shape->mesh->vertices[i].x = vert[0];
- shape->mesh->vertices[i].y = vert[1];
- shape->mesh->vertices[i].z = vert[2];
- }
-
- if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
- btScaledBvhTriangleMeshShape *scaled_shape = (btScaledBvhTriangleMeshShape *)shape->cshape;
- btBvhTriangleMeshShape *mesh_shape = scaled_shape->getChildShape();
- mesh_shape->refitTree(btVector3(min[0], min[1], min[2]), btVector3(max[0], max[1], max[2]));
- }
- else if (shape->cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) {
- btGImpactMeshShape *mesh_shape = (btGImpactMeshShape*)shape->cshape;
- mesh_shape->updateBound();
- }
+ rbCollisionShape *shape = new rbCollisionShape;
+
+ /* triangle-mesh we create is a BVH wrapper for triangle mesh data (for faster lookups) */
+ // RB_TODO perhaps we need to allow saving out this for performance when rebuilding?
+ btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(
+ mesh->index_array, true, true);
+
+ shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
+ shape->mesh = mesh;
+ return shape;
+}
+
+void RB_shape_trimesh_update(rbCollisionShape *shape,
+ float *vertices,
+ int num_verts,
+ int vert_stride,
+ float min[3],
+ float max[3])
+{
+ if (shape->mesh == NULL || num_verts != shape->mesh->num_vertices)
+ return;
+
+ for (int i = 0; i < num_verts; i++) {
+ float *vert = (float *)(((char *)vertices + i * vert_stride));
+ shape->mesh->vertices[i].x = vert[0];
+ shape->mesh->vertices[i].y = vert[1];
+ shape->mesh->vertices[i].z = vert[2];
+ }
+
+ if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
+ btScaledBvhTriangleMeshShape *scaled_shape = (btScaledBvhTriangleMeshShape *)shape->cshape;
+ btBvhTriangleMeshShape *mesh_shape = scaled_shape->getChildShape();
+ mesh_shape->refitTree(btVector3(min[0], min[1], min[2]), btVector3(max[0], max[1], max[2]));
+ }
+ else if (shape->cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) {
+ btGImpactMeshShape *mesh_shape = (btGImpactMeshShape *)shape->cshape;
+ mesh_shape->updateBound();
+ }
}
rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh)
{
- rbCollisionShape *shape = new rbCollisionShape;
-
- btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(mesh->index_array);
- gimpactShape->updateBound(); // TODO: add this to the update collision margin call?
-
- shape->cshape = gimpactShape;
- shape->mesh = mesh;
- return shape;
+ rbCollisionShape *shape = new rbCollisionShape;
+
+ btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(mesh->index_array);
+ gimpactShape->updateBound(); // TODO: add this to the update collision margin call?
+
+ shape->cshape = gimpactShape;
+ shape->mesh = mesh;
+ return shape;
}
/* Cleanup --------------------------- */
void RB_shape_delete(rbCollisionShape *shape)
{
- if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
- btBvhTriangleMeshShape *child_shape = ((btScaledBvhTriangleMeshShape *)shape->cshape)->getChildShape();
- if (child_shape)
- delete child_shape;
- }
- if (shape->mesh)
- RB_trimesh_data_delete(shape->mesh);
- delete shape->cshape;
- delete shape;
+ if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
+ btBvhTriangleMeshShape *child_shape =
+ ((btScaledBvhTriangleMeshShape *)shape->cshape)->getChildShape();
+ if (child_shape)
+ delete child_shape;
+ }
+ if (shape->mesh)
+ RB_trimesh_data_delete(shape->mesh);
+ delete shape->cshape;
+ delete shape;
}
/* Settings --------------------------- */
float RB_shape_get_margin(rbCollisionShape *shape)
{
- return shape->cshape->getMargin();
+ return shape->cshape->getMargin();
}
void RB_shape_set_margin(rbCollisionShape *shape, float value)
{
- shape->cshape->setMargin(value);
+ shape->cshape->setMargin(value);
}
/* ********************************** */
@@ -829,319 +847,368 @@ void RB_shape_set_margin(rbCollisionShape *shape, float value)
void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int disable_collisions)
{
- btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
-
- world->dynamicsWorld->addConstraint(constraint, disable_collisions);
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
+
+ world->dynamicsWorld->addConstraint(constraint, disable_collisions);
}
void RB_dworld_remove_constraint(rbDynamicsWorld *world, rbConstraint *con)
{
- btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
-
- world->dynamicsWorld->removeConstraint(constraint);
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
+
+ world->dynamicsWorld->removeConstraint(constraint);
}
/* ............ */
-static void make_constraint_transforms(btTransform &transform1, btTransform &transform2, btRigidBody *body1, btRigidBody *body2, float pivot[3], float orn[4])
+static void make_constraint_transforms(btTransform &transform1,
+ btTransform &transform2,
+ btRigidBody *body1,
+ btRigidBody *body2,
+ float pivot[3],
+ float orn[4])
{
- btTransform pivot_transform = btTransform();
- pivot_transform.setOrigin(btVector3(pivot[0], pivot[1], pivot[2]));
- pivot_transform.setRotation(btQuaternion(orn[1], orn[2], orn[3], orn[0]));
-
- transform1 = body1->getWorldTransform().inverse() * pivot_transform;
- transform2 = body2->getWorldTransform().inverse() * pivot_transform;
+ btTransform pivot_transform = btTransform();
+ pivot_transform.setOrigin(btVector3(pivot[0], pivot[1], pivot[2]));
+ pivot_transform.setRotation(btQuaternion(orn[1], orn[2], orn[3], orn[0]));
+
+ transform1 = body1->getWorldTransform().inverse() * pivot_transform;
+ transform2 = body2->getWorldTransform().inverse() * pivot_transform;
}
rbConstraint *RB_constraint_new_point(float pivot[3], rbRigidBody *rb1, rbRigidBody *rb2)
{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
-
- btVector3 pivot1 = body1->getWorldTransform().inverse() * btVector3(pivot[0], pivot[1], pivot[2]);
- btVector3 pivot2 = body2->getWorldTransform().inverse() * btVector3(pivot[0], pivot[1], pivot[2]);
-
- btTypedConstraint *con = new btPoint2PointConstraint(*body1, *body2, pivot1, pivot2);
-
- return (rbConstraint *)con;
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+
+ btVector3 pivot1 = body1->getWorldTransform().inverse() *
+ btVector3(pivot[0], pivot[1], pivot[2]);
+ btVector3 pivot2 = body2->getWorldTransform().inverse() *
+ btVector3(pivot[0], pivot[1], pivot[2]);
+
+ btTypedConstraint *con = new btPoint2PointConstraint(*body1, *body2, pivot1, pivot2);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_fixed(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btFixedConstraint *con = new btFixedConstraint(*body1, *body2, transform1, transform2);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_hinge(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btHingeConstraint *con = new btHingeConstraint(*body1, *body2, transform1, transform2);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_slider(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_piston(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
+ con->setUpperAngLimit(-1.0f); // unlock rotation axis
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_6dof(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btTypedConstraint *con = new btGeneric6DofConstraint(
+ *body1, *body2, transform1, transform2, true);
+
+ return (rbConstraint *)con;
}
-
-rbConstraint *RB_constraint_new_fixed(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+
+rbConstraint *RB_constraint_new_6dof_spring(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btFixedConstraint *con = new btFixedConstraint(*body1, *body2, transform1, transform2);
-
- return (rbConstraint *)con;
-}
-
-rbConstraint *RB_constraint_new_hinge(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
-{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btHingeConstraint *con = new btHingeConstraint(*body1, *body2, transform1, transform2);
-
- return (rbConstraint *)con;
-}
-
-rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
-{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
-
- return (rbConstraint *)con;
-}
-
-rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
-{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
- con->setUpperAngLimit(-1.0f); // unlock rotation axis
-
- return (rbConstraint *)con;
-}
-
-rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
-{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btTypedConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
-
- return (rbConstraint *)con;
-}
-
-rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
-{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btTypedConstraint *con = new btGeneric6DofSpringConstraint(*body1, *body2, transform1, transform2, true);
-
- return (rbConstraint *)con;
-}
-
-rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
-{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2);
-
- return (rbConstraint *)con;
-}
-
-rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
-{
- btRigidBody *body1 = rb1->body;
- btRigidBody *body2 = rb2->body;
- btTransform transform1;
- btTransform transform2;
-
- make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
-
- btGeneric6DofConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
-
- /* unlock constraint axes */
- for (int i = 0; i < 6; i++) {
- con->setLimit(i, 0.0f, -1.0f);
- }
- /* unlock motor axes */
- con->getTranslationalLimitMotor()->m_upperLimit.setValue(-1.0f, -1.0f, -1.0f);
-
- return (rbConstraint *)con;
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btTypedConstraint *con = new btGeneric6DofSpringConstraint(
+ *body1, *body2, transform1, transform2, true);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btTypedConstraint *con = new btGeneric6DofSpring2Constraint(
+ *body1, *body2, transform1, transform2);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_motor(float pivot[3],
+ float orn[4],
+ rbRigidBody *rb1,
+ rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btGeneric6DofConstraint *con = new btGeneric6DofConstraint(
+ *body1, *body2, transform1, transform2, true);
+
+ /* unlock constraint axes */
+ for (int i = 0; i < 6; i++) {
+ con->setLimit(i, 0.0f, -1.0f);
+ }
+ /* unlock motor axes */
+ con->getTranslationalLimitMotor()->m_upperLimit.setValue(-1.0f, -1.0f, -1.0f);
+
+ return (rbConstraint *)con;
}
/* Cleanup ----------------------------- */
void RB_constraint_delete(rbConstraint *con)
{
- btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
- delete constraint;
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
+ delete constraint;
}
/* Settings ------------------------- */
void RB_constraint_set_enabled(rbConstraint *con, int enabled)
{
- btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
-
- constraint->setEnabled(enabled);
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
+
+ constraint->setEnabled(enabled);
}
void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper)
{
- btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint*>(con);
-
- // RB_TODO expose these
- float softness = 0.9f;
- float bias_factor = 0.3f;
- float relaxation_factor = 1.0f;
-
- constraint->setLimit(lower, upper, softness, bias_factor, relaxation_factor);
+ btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint *>(con);
+
+ // RB_TODO expose these
+ float softness = 0.9f;
+ float bias_factor = 0.3f;
+ float relaxation_factor = 1.0f;
+
+ constraint->setLimit(lower, upper, softness, bias_factor, relaxation_factor);
}
void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper)
{
- btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint*>(con);
-
- constraint->setLowerLinLimit(lower);
- constraint->setUpperLinLimit(upper);
+ btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
+
+ constraint->setLowerLinLimit(lower);
+ constraint->setUpperLinLimit(upper);
}
-void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper)
+void RB_constraint_set_limits_piston(
+ rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper)
{
- btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint*>(con);
-
- constraint->setLowerLinLimit(lin_lower);
- constraint->setUpperLinLimit(lin_upper);
- constraint->setLowerAngLimit(ang_lower);
- constraint->setUpperAngLimit(ang_upper);
+ btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
+
+ constraint->setLowerLinLimit(lin_lower);
+ constraint->setUpperLinLimit(lin_upper);
+ constraint->setLowerAngLimit(ang_lower);
+ constraint->setUpperAngLimit(ang_upper);
}
void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper)
{
- btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
-
- constraint->setLimit(axis, lower, upper);
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
+
+ constraint->setLimit(axis, lower, upper);
}
void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
+ con);
- constraint->setLimit(axis, lower, upper);
+ constraint->setLimit(axis, lower, upper);
}
void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
+ con);
- constraint->setStiffness(axis, stiffness);
+ constraint->setStiffness(axis, stiffness);
}
void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
+ con);
- // invert damping range so that 0 = no damping
- damping = (damping > 1.0f) ? 0.0f : 1.0f - damping;
+ // invert damping range so that 0 = no damping
+ damping = (damping > 1.0f) ? 0.0f : 1.0f - damping;
- constraint->setDamping(axis, damping);
+ constraint->setDamping(axis, damping);
}
void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
+ con);
- constraint->enableSpring(axis, enable);
+ constraint->enableSpring(axis, enable);
}
void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
+ con);
- constraint->setEquilibriumPoint();
+ constraint->setEquilibriumPoint();
}
void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
+ con);
- constraint->setStiffness(axis, stiffness);
+ constraint->setStiffness(axis, stiffness);
}
void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
+ con);
- constraint->setDamping(axis, damping);
+ constraint->setDamping(axis, damping);
}
void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
+ con);
- constraint->enableSpring(axis, enable);
+ constraint->enableSpring(axis, enable);
}
void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
+ con);
- constraint->setEquilibriumPoint();
+ constraint->setEquilibriumPoint();
}
void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations)
{
- btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
-
- constraint->setOverrideNumSolverIterations(num_solver_iterations);
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
+
+ constraint->setOverrideNumSolverIterations(num_solver_iterations);
}
void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold)
{
- btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
-
- constraint->setBreakingImpulseThreshold(threshold);
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
+
+ constraint->setBreakingImpulseThreshold(threshold);
}
void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang)
{
- btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
-
- constraint->getTranslationalLimitMotor()->m_enableMotor[0] = enable_lin;
- constraint->getRotationalLimitMotor(0)->m_enableMotor = enable_ang;
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
+
+ constraint->getTranslationalLimitMotor()->m_enableMotor[0] = enable_lin;
+ constraint->getRotationalLimitMotor(0)->m_enableMotor = enable_ang;
}
-void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang)
+void RB_constraint_set_max_impulse_motor(rbConstraint *con,
+ float max_impulse_lin,
+ float max_impulse_ang)
{
- btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
-
- constraint->getTranslationalLimitMotor()->m_maxMotorForce.setX(max_impulse_lin);
- constraint->getRotationalLimitMotor(0)->m_maxMotorForce = max_impulse_ang;
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
+
+ constraint->getTranslationalLimitMotor()->m_maxMotorForce.setX(max_impulse_lin);
+ constraint->getRotationalLimitMotor(0)->m_maxMotorForce = max_impulse_ang;
}
-void RB_constraint_set_target_velocity_motor(rbConstraint *con, float velocity_lin, float velocity_ang)
+void RB_constraint_set_target_velocity_motor(rbConstraint *con,
+ float velocity_lin,
+ float velocity_ang)
{
- btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
-
- constraint->getTranslationalLimitMotor()->m_targetVelocity.setX(velocity_lin);
- constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
+
+ constraint->getTranslationalLimitMotor()->m_targetVelocity.setX(velocity_lin);
+ constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
}
/* ********************************** */
diff --git a/intern/string/CMakeLists.txt b/intern/string/CMakeLists.txt
index 3f436c79a69..8c400f320ae 100644
--- a/intern/string/CMakeLists.txt
+++ b/intern/string/CMakeLists.txt
@@ -19,7 +19,7 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
+ .
)
set(INC_SYS
@@ -27,9 +27,9 @@ set(INC_SYS
)
set(SRC
- intern/STR_String.cpp
+ intern/STR_String.cpp
- STR_String.h
+ STR_String.h
)
set(LIB
diff --git a/intern/string/STR_String.h b/intern/string/STR_String.h
index 27db035429c..5516f14bafa 100644
--- a/intern/string/STR_String.h
+++ b/intern/string/STR_String.h
@@ -25,8 +25,8 @@
#define __STR_STRING_H__
#ifndef STR_NO_ASSERTD
-#undef assertd
-#define assertd(exp) ((void)NULL)
+# undef assertd
+# define assertd(exp) ((void)NULL)
#endif
#include <vector>
@@ -36,174 +36,331 @@
#include <cstdlib>
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
#ifdef _WIN32
-#define stricmp _stricmp
+# define stricmp _stricmp
#endif
class STR_String;
-typedef unsigned long dword;
-typedef const STR_String& rcSTR_String;
+typedef unsigned long dword;
+typedef const STR_String &rcSTR_String;
typedef unsigned char byte;
/**
* Smart String Value class. Is used by parser when an expression tree is build containing string.
*/
-class STR_String
-{
-public:
- // Initialization
- STR_String();
- STR_String(char c);
- STR_String(char c, int len);
- STR_String(const char *str);
- STR_String(const char *str, int len);
- STR_String(const STR_String &str);
- STR_String(const STR_String & str, int len);
- STR_String(const char *src1, int src1_len, const char *src2, int src2_len);
- explicit STR_String(int val);
- explicit STR_String(dword val);
- explicit STR_String(float val);
- explicit STR_String(double val);
- inline ~STR_String() { delete[] this->m_data; }
-
- // Operations
- STR_String& Format(const char *fmt, ...) // Set formatted text to string
+class STR_String {
+ public:
+ // Initialization
+ STR_String();
+ STR_String(char c);
+ STR_String(char c, int len);
+ STR_String(const char *str);
+ STR_String(const char *str, int len);
+ STR_String(const STR_String &str);
+ STR_String(const STR_String &str, int len);
+ STR_String(const char *src1, int src1_len, const char *src2, int src2_len);
+ explicit STR_String(int val);
+ explicit STR_String(dword val);
+ explicit STR_String(float val);
+ explicit STR_String(double val);
+ inline ~STR_String()
+ {
+ delete[] this->m_data;
+ }
+
+ // Operations
+ STR_String &Format(const char *fmt, ...) // Set formatted text to string
#ifdef __GNUC__
- __attribute__ ((format(printf, 2, 3)))
+ __attribute__((format(printf, 2, 3)))
#endif
- ;
- STR_String& FormatAdd(const char *fmt, ...) // Add formatted text to string
+ ;
+ STR_String &FormatAdd(const char *fmt, ...) // Add formatted text to string
#ifdef __GNUC__
- __attribute__ ((format(printf, 2, 3)))
+ __attribute__((format(printf, 2, 3)))
#endif
- ;
- inline void Clear() { this->m_len = this->m_data[0] = 0; }
- inline const STR_String & Reverse()
- {
- for (int i1 = 0, i2 = this->m_len - 1; i1 < i2; i1++, i2--) {
- std::swap(this->m_data[i1], this->m_data[i2]);
- }
- return *this;
- }
-
- // Properties
- bool IsUpper() const;
- bool IsLower() const;
- inline bool IsEmpty() const { return this->m_len == 0; }
- inline int Length() const { return this->m_len; }
-
- // Data access
- inline STR_String& SetLength(int len) { AllocBuffer(len, true); this->m_len = len; this->m_data[len] = 0; return *this; }
- inline char GetAt(int pos) const { assertd(pos<this->m_len); return this->m_data[pos]; }
- inline void SetAt(int pos, char c) { assertd(pos<this->m_len); this->m_data[pos] = c; }
- inline void SetAt(int pos, rcSTR_String str);
- inline void SetAt(int pos, int num, rcSTR_String str);
- void Replace(int pos, rcSTR_String str);
- void Replace(int pos, int num, rcSTR_String str);
-
- // Substrings
- inline STR_String Left(int num) const { num = (num < this->m_len ? num:this->m_len ); return STR_String(this->m_data, num); }
- inline STR_String Right(int num) const { num = (num < this->m_len ? num:this->m_len ); return STR_String(this->m_data + this->m_len - num, num); }
- inline STR_String Mid(int pos, int num = INT_MAX) const { pos = (pos < this->m_len ? pos:this->m_len ); num = (num < (this->m_len - pos) ? num : (this->m_len - pos)); return STR_String(this->m_data + pos, num); }
-
- // Comparison
- int Compare(rcSTR_String rhs) const;
- int CompareNoCase(rcSTR_String rhs) const;
- inline bool IsEqual(rcSTR_String rhs) const { return (Compare(rhs) == 0); }
- inline bool IsEqualNoCase(rcSTR_String rhs) const { return (CompareNoCase(rhs) == 0); }
-
- // Search/replace
- int Find(char c, int pos = 0) const;
- int Find(const char *str, int pos = 0) const;
- int Find(rcSTR_String str, int pos = 0) const;
- int RFind(char c) const;
- int FindOneOf(const char *set, int pos = 0) const;
- int RFindOneOf(const char *set, int pos = 0) const;
-
- std::vector<STR_String> Explode(char c) const;
-
- // Formatting
- STR_String& Upper();
- STR_String& Lower();
- STR_String& Capitalize();
- STR_String& TrimLeft();
- STR_String& TrimLeft(char *set);
- STR_String& TrimRight();
- STR_String& TrimRight(char *set);
- STR_String& Trim();
- STR_String& Trim(char *set);
- STR_String& TrimQuotes();
-
- // Conversions
-// inline operator char*() { return this->m_data; }
- inline operator const char *() const { return this->m_data; }
- inline char *Ptr() { return this->m_data; }
- inline const char *ReadPtr() const { return this->m_data; }
- inline float ToFloat() const { float x=(float)(atof(this->m_data)); return x; }
- inline int ToInt() const { return atoi(this->m_data); }
-
- // Operators
- inline rcSTR_String operator=(const byte *rhs) { return Copy((const char *)rhs, strlen((const char *)rhs)); }
- inline rcSTR_String operator=(rcSTR_String rhs) { return Copy(rhs.ReadPtr(), rhs.Length()); }
- inline rcSTR_String operator=(char rhs) { return Copy(&rhs, 1); }
- inline rcSTR_String operator=(const char *rhs) { return Copy(rhs, strlen(rhs)); }
-
- inline rcSTR_String operator+=(const char *rhs) { return Concat(rhs, strlen(rhs)); }
- inline rcSTR_String operator+=(rcSTR_String rhs) { return Concat(rhs.ReadPtr(), rhs.Length()); }
- inline rcSTR_String operator+=(char rhs) { return Concat(&rhs, 1); }
-
-
- inline friend bool operator<(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)<0); }
- inline friend bool operator<(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs)<0); }
- inline friend bool operator<(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)<0); }
- inline friend bool operator>(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)>0); }
- inline friend bool operator>(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs)>0); }
- inline friend bool operator>(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)>0); }
- inline friend bool operator<=(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)<=0); }
- inline friend bool operator<=(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs)<=0); }
- inline friend bool operator<=(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)<=0); }
- inline friend bool operator>=(rcSTR_String lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)>=0); }
- inline friend bool operator>=(rcSTR_String lhs, const char *rhs) { return (strcmp(lhs, rhs)>=0); }
- inline friend bool operator>=(const char *lhs, rcSTR_String rhs) { return (strcmp(lhs, rhs)>=0); }
- inline friend bool operator==(rcSTR_String lhs, rcSTR_String rhs) { return ((lhs.Length() == rhs.Length()) && (memcmp(lhs, rhs, lhs.Length()) == 0)); }
- inline friend bool operator==(rcSTR_String lhs, const char *rhs) { return (strncmp(lhs, rhs, lhs.Length() + 1) == 0); }
- inline friend bool operator==(const char *lhs, rcSTR_String rhs) { return (strncmp(lhs, rhs, rhs.Length() + 1) == 0); }
- inline friend bool operator!=(rcSTR_String lhs, rcSTR_String rhs) { return ((lhs.Length() != rhs.Length()) || (memcmp(lhs, rhs, lhs.Length()) != 0)); }
- inline friend bool operator!=(rcSTR_String lhs, const char *rhs) { return (strncmp(lhs, rhs, lhs.Length() + 1) != 0); }
- inline friend bool operator!=(const char *lhs, rcSTR_String rhs) { return (strncmp(lhs, rhs, rhs.Length() + 1) != 0); }
-
- // serializing
- //int Serialize(pCStream stream);
-
-protected:
- // Implementation
- void AllocBuffer(int len, bool keep_contents);
- rcSTR_String Copy(const char *src, int len);
- rcSTR_String Concat(const char *data, int len);
-
- static bool isLower(char c) { return !isUpper(c); }
- static bool isUpper(char c) { return (c>='A') && (c <= 'Z'); }
- static bool isSpace(char c) { return (c==' ') || (c=='\t'); }
-
- char *m_data; // -> STR_String data
- int m_len; //z Data length
- int m_max; // Space in data buffer
-
+ ;
+ inline void Clear()
+ {
+ this->m_len = this->m_data[0] = 0;
+ }
+ inline const STR_String &Reverse()
+ {
+ for (int i1 = 0, i2 = this->m_len - 1; i1 < i2; i1++, i2--) {
+ std::swap(this->m_data[i1], this->m_data[i2]);
+ }
+ return *this;
+ }
+
+ // Properties
+ bool IsUpper() const;
+ bool IsLower() const;
+ inline bool IsEmpty() const
+ {
+ return this->m_len == 0;
+ }
+ inline int Length() const
+ {
+ return this->m_len;
+ }
+
+ // Data access
+ inline STR_String &SetLength(int len)
+ {
+ AllocBuffer(len, true);
+ this->m_len = len;
+ this->m_data[len] = 0;
+ return *this;
+ }
+ inline char GetAt(int pos) const
+ {
+ assertd(pos < this->m_len);
+ return this->m_data[pos];
+ }
+ inline void SetAt(int pos, char c)
+ {
+ assertd(pos < this->m_len);
+ this->m_data[pos] = c;
+ }
+ inline void SetAt(int pos, rcSTR_String str);
+ inline void SetAt(int pos, int num, rcSTR_String str);
+ void Replace(int pos, rcSTR_String str);
+ void Replace(int pos, int num, rcSTR_String str);
+
+ // Substrings
+ inline STR_String Left(int num) const
+ {
+ num = (num < this->m_len ? num : this->m_len);
+ return STR_String(this->m_data, num);
+ }
+ inline STR_String Right(int num) const
+ {
+ num = (num < this->m_len ? num : this->m_len);
+ return STR_String(this->m_data + this->m_len - num, num);
+ }
+ inline STR_String Mid(int pos, int num = INT_MAX) const
+ {
+ pos = (pos < this->m_len ? pos : this->m_len);
+ num = (num < (this->m_len - pos) ? num : (this->m_len - pos));
+ return STR_String(this->m_data + pos, num);
+ }
+
+ // Comparison
+ int Compare(rcSTR_String rhs) const;
+ int CompareNoCase(rcSTR_String rhs) const;
+ inline bool IsEqual(rcSTR_String rhs) const
+ {
+ return (Compare(rhs) == 0);
+ }
+ inline bool IsEqualNoCase(rcSTR_String rhs) const
+ {
+ return (CompareNoCase(rhs) == 0);
+ }
+
+ // Search/replace
+ int Find(char c, int pos = 0) const;
+ int Find(const char *str, int pos = 0) const;
+ int Find(rcSTR_String str, int pos = 0) const;
+ int RFind(char c) const;
+ int FindOneOf(const char *set, int pos = 0) const;
+ int RFindOneOf(const char *set, int pos = 0) const;
+
+ std::vector<STR_String> Explode(char c) const;
+
+ // Formatting
+ STR_String &Upper();
+ STR_String &Lower();
+ STR_String &Capitalize();
+ STR_String &TrimLeft();
+ STR_String &TrimLeft(char *set);
+ STR_String &TrimRight();
+ STR_String &TrimRight(char *set);
+ STR_String &Trim();
+ STR_String &Trim(char *set);
+ STR_String &TrimQuotes();
+
+ // Conversions
+ // inline operator char*() { return this->m_data; }
+ inline operator const char *() const
+ {
+ return this->m_data;
+ }
+ inline char *Ptr()
+ {
+ return this->m_data;
+ }
+ inline const char *ReadPtr() const
+ {
+ return this->m_data;
+ }
+ inline float ToFloat() const
+ {
+ float x = (float)(atof(this->m_data));
+ return x;
+ }
+ inline int ToInt() const
+ {
+ return atoi(this->m_data);
+ }
+
+ // Operators
+ inline rcSTR_String operator=(const byte *rhs)
+ {
+ return Copy((const char *)rhs, strlen((const char *)rhs));
+ }
+ inline rcSTR_String operator=(rcSTR_String rhs)
+ {
+ return Copy(rhs.ReadPtr(), rhs.Length());
+ }
+ inline rcSTR_String operator=(char rhs)
+ {
+ return Copy(&rhs, 1);
+ }
+ inline rcSTR_String operator=(const char *rhs)
+ {
+ return Copy(rhs, strlen(rhs));
+ }
+
+ inline rcSTR_String operator+=(const char *rhs)
+ {
+ return Concat(rhs, strlen(rhs));
+ }
+ inline rcSTR_String operator+=(rcSTR_String rhs)
+ {
+ return Concat(rhs.ReadPtr(), rhs.Length());
+ }
+ inline rcSTR_String operator+=(char rhs)
+ {
+ return Concat(&rhs, 1);
+ }
+
+ inline friend bool operator<(rcSTR_String lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) < 0);
+ }
+ inline friend bool operator<(rcSTR_String lhs, const char *rhs)
+ {
+ return (strcmp(lhs, rhs) < 0);
+ }
+ inline friend bool operator<(const char *lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) < 0);
+ }
+ inline friend bool operator>(rcSTR_String lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) > 0);
+ }
+ inline friend bool operator>(rcSTR_String lhs, const char *rhs)
+ {
+ return (strcmp(lhs, rhs) > 0);
+ }
+ inline friend bool operator>(const char *lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) > 0);
+ }
+ inline friend bool operator<=(rcSTR_String lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) <= 0);
+ }
+ inline friend bool operator<=(rcSTR_String lhs, const char *rhs)
+ {
+ return (strcmp(lhs, rhs) <= 0);
+ }
+ inline friend bool operator<=(const char *lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) <= 0);
+ }
+ inline friend bool operator>=(rcSTR_String lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) >= 0);
+ }
+ inline friend bool operator>=(rcSTR_String lhs, const char *rhs)
+ {
+ return (strcmp(lhs, rhs) >= 0);
+ }
+ inline friend bool operator>=(const char *lhs, rcSTR_String rhs)
+ {
+ return (strcmp(lhs, rhs) >= 0);
+ }
+ inline friend bool operator==(rcSTR_String lhs, rcSTR_String rhs)
+ {
+ return ((lhs.Length() == rhs.Length()) && (memcmp(lhs, rhs, lhs.Length()) == 0));
+ }
+ inline friend bool operator==(rcSTR_String lhs, const char *rhs)
+ {
+ return (strncmp(lhs, rhs, lhs.Length() + 1) == 0);
+ }
+ inline friend bool operator==(const char *lhs, rcSTR_String rhs)
+ {
+ return (strncmp(lhs, rhs, rhs.Length() + 1) == 0);
+ }
+ inline friend bool operator!=(rcSTR_String lhs, rcSTR_String rhs)
+ {
+ return ((lhs.Length() != rhs.Length()) || (memcmp(lhs, rhs, lhs.Length()) != 0));
+ }
+ inline friend bool operator!=(rcSTR_String lhs, const char *rhs)
+ {
+ return (strncmp(lhs, rhs, lhs.Length() + 1) != 0);
+ }
+ inline friend bool operator!=(const char *lhs, rcSTR_String rhs)
+ {
+ return (strncmp(lhs, rhs, rhs.Length() + 1) != 0);
+ }
+
+ // serializing
+ //int Serialize(pCStream stream);
+
+ protected:
+ // Implementation
+ void AllocBuffer(int len, bool keep_contents);
+ rcSTR_String Copy(const char *src, int len);
+ rcSTR_String Concat(const char *data, int len);
+
+ static bool isLower(char c)
+ {
+ return !isUpper(c);
+ }
+ static bool isUpper(char c)
+ {
+ return (c >= 'A') && (c <= 'Z');
+ }
+ static bool isSpace(char c)
+ {
+ return (c == ' ') || (c == '\t');
+ }
+
+ char *m_data; // -> STR_String data
+ int m_len; //z Data length
+ int m_max; // Space in data buffer
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("CXX:STR_String")
+ MEM_CXX_CLASS_ALLOC_FUNCS("CXX:STR_String")
#endif
};
-inline STR_String operator+(rcSTR_String lhs, rcSTR_String rhs) { return STR_String(lhs.ReadPtr(), lhs.Length(), rhs.ReadPtr(), rhs.Length()); }
-inline STR_String operator+(rcSTR_String lhs, char rhs) { return STR_String(lhs.ReadPtr(), lhs.Length(), &rhs, 1); }
-inline STR_String operator+(char lhs, rcSTR_String rhs) { return STR_String(&lhs, 1, rhs.ReadPtr(), rhs.Length()); }
-inline STR_String operator+(rcSTR_String lhs, const char *rhs) { return STR_String(lhs.ReadPtr(), lhs.Length(), rhs, strlen(rhs)); }
-inline STR_String operator+(const char *lhs, rcSTR_String rhs) { return STR_String(lhs, strlen(lhs), rhs.ReadPtr(), rhs.Length()); }
+inline STR_String operator+(rcSTR_String lhs, rcSTR_String rhs)
+{
+ return STR_String(lhs.ReadPtr(), lhs.Length(), rhs.ReadPtr(), rhs.Length());
+}
+inline STR_String operator+(rcSTR_String lhs, char rhs)
+{
+ return STR_String(lhs.ReadPtr(), lhs.Length(), &rhs, 1);
+}
+inline STR_String operator+(char lhs, rcSTR_String rhs)
+{
+ return STR_String(&lhs, 1, rhs.ReadPtr(), rhs.Length());
+}
+inline STR_String operator+(rcSTR_String lhs, const char *rhs)
+{
+ return STR_String(lhs.ReadPtr(), lhs.Length(), rhs, strlen(rhs));
+}
+inline STR_String operator+(const char *lhs, rcSTR_String rhs)
+{
+ return STR_String(lhs, strlen(lhs), rhs.ReadPtr(), rhs.Length());
+}
-#endif //__STR_STRING_H__
+#endif //__STR_STRING_H__
diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp
index b674871fbf3..b2134550ea9 100644
--- a/intern/string/intern/STR_String.cpp
+++ b/intern/string/intern/STR_String.cpp
@@ -32,700 +32,604 @@
#include "STR_String.h"
/*-------------------------------------------------------------------------------------------------
- Construction / destruction
+ Construction / destruction
-------------------------------------------------------------------------------------------------*/
-#define STR_STRING_SIZE_DEFAULT_WORD 32 /* default size for a new word */
-#define STR_STRING_SIZE_DEFAULT_CHAR 9 /* default size for a new char */
+#define STR_STRING_SIZE_DEFAULT_WORD 32 /* default size for a new word */
+#define STR_STRING_SIZE_DEFAULT_CHAR 9 /* default size for a new char */
//
// Construct an empty string
//
-STR_String::STR_String() :
- m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]),
- m_len(0),
- m_max(STR_STRING_SIZE_DEFAULT_WORD)
+STR_String::STR_String()
+ : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_len(0), m_max(STR_STRING_SIZE_DEFAULT_WORD)
{
- this->m_data[0] = 0;
+ this->m_data[0] = 0;
}
-
-
//
// Construct a string of one character
//
-STR_String::STR_String(char c) :
- m_data(new char[STR_STRING_SIZE_DEFAULT_CHAR]),
- m_len(1),
- m_max(STR_STRING_SIZE_DEFAULT_CHAR)
+STR_String::STR_String(char c)
+ : m_data(new char[STR_STRING_SIZE_DEFAULT_CHAR]), m_len(1), m_max(STR_STRING_SIZE_DEFAULT_CHAR)
{
- this->m_data[0] = c;
- this->m_data[1] = 0;
+ this->m_data[0] = c;
+ this->m_data[1] = 0;
}
-
-
//
// Construct a string of multiple repeating characters
//
-STR_String::STR_String(char c, int len) :
- m_data(new char[len + 8]),
- m_len(len),
- m_max(len + 8)
+STR_String::STR_String(char c, int len) : m_data(new char[len + 8]), m_len(len), m_max(len + 8)
{
- assertd(this->m_data != NULL);
- memset(this->m_data, c, len);
- this->m_data[len] = 0;
+ assertd(this->m_data != NULL);
+ memset(this->m_data, c, len);
+ this->m_data[len] = 0;
}
-
-
//
// Construct a string from a pointer-to-ASCIIZ-string
//
// MAART: Changed to test for null strings
STR_String::STR_String(const char *str)
{
- if (str) {
- this->m_len = ::strlen(str);
- this->m_max = this->m_len + 8;
- this->m_data = new char[this->m_max];
- assertd(this->m_data != NULL);
- ::memcpy(this->m_data, str, this->m_len);
- this->m_data[this->m_len] = 0;
- }
- else {
- this->m_data = NULL;
- this->m_len = 0;
- this->m_max = 8;
- }
+ if (str) {
+ this->m_len = ::strlen(str);
+ this->m_max = this->m_len + 8;
+ this->m_data = new char[this->m_max];
+ assertd(this->m_data != NULL);
+ ::memcpy(this->m_data, str, this->m_len);
+ this->m_data[this->m_len] = 0;
+ }
+ else {
+ this->m_data = NULL;
+ this->m_len = 0;
+ this->m_max = 8;
+ }
}
-
-
//
// Construct a string from a pointer-to-ASCII-string and a length
//
-STR_String::STR_String(const char *str, int len) :
- m_data(new char[len + 8]),
- m_len(len),
- m_max(len + 8)
+STR_String::STR_String(const char *str, int len)
+ : m_data(new char[len + 8]), m_len(len), m_max(len + 8)
{
- assertd(this->m_data != NULL);
- memcpy(this->m_data, str, len);
- this->m_data[len] = 0;
+ assertd(this->m_data != NULL);
+ memcpy(this->m_data, str, len);
+ this->m_data[len] = 0;
}
-
-
//
// Construct a string from another string
//
-STR_String::STR_String(rcSTR_String str) :
- m_data(new char[str.Length() + 8]),
- m_len(str.Length()),
- m_max(str.Length() + 8)
+STR_String::STR_String(rcSTR_String str)
+ : m_data(new char[str.Length() + 8]), m_len(str.Length()), m_max(str.Length() + 8)
{
- assertd(this->m_data != NULL);
- assertd(str.this->m_data != NULL);
- memcpy(this->m_data, str.ReadPtr(), str.Length());
- this->m_data[str.Length()] = 0;
+ assertd(this->m_data != NULL);
+ assertd(str.this->m_data != NULL);
+ memcpy(this->m_data, str.ReadPtr(), str.Length());
+ this->m_data[str.Length()] = 0;
}
-
-
//
// Construct a string from the first number of characters in another string
//
-STR_String::STR_String(rcSTR_String str, int len) :
- m_data(new char[len + 8]),
- m_len(len),
- m_max(len + 8)
+STR_String::STR_String(rcSTR_String str, int len)
+ : m_data(new char[len + 8]), m_len(len), m_max(len + 8)
{
- assertd(this->m_data != NULL);
- assertd(str.this->m_data != NULL);
- memcpy(this->m_data, str.ReadPtr(), str.Length());
- this->m_data[str.Length()] = 0;
+ assertd(this->m_data != NULL);
+ assertd(str.this->m_data != NULL);
+ memcpy(this->m_data, str.ReadPtr(), str.Length());
+ this->m_data[str.Length()] = 0;
}
-
-
//
// Create a string by concatenating two sources
//
-STR_String::STR_String(const char *src1, int len1, const char *src2, int len2) :
- m_data(new char[len1 + len2 + 8]),
- m_len(len1 + len2),
- m_max(len1 + len2 + 8)
+STR_String::STR_String(const char *src1, int len1, const char *src2, int len2)
+ : m_data(new char[len1 + len2 + 8]), m_len(len1 + len2), m_max(len1 + len2 + 8)
{
- assertd(this->m_data != NULL);
- memcpy(this->m_data, src1, len1);
- memcpy(this->m_data + len1, src2, len2);
- this->m_data[len1 + len2] = 0;
+ assertd(this->m_data != NULL);
+ memcpy(this->m_data, src1, len1);
+ memcpy(this->m_data + len1, src2, len2);
+ this->m_data[len1 + len2] = 0;
}
-
-
//
// Create a string with an integer value
//
-STR_String::STR_String(int val) :
- m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]),
- m_max(STR_STRING_SIZE_DEFAULT_WORD)
+STR_String::STR_String(int val)
+ : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%d", val);
+ assertd(this->m_data != NULL);
+ this->m_len = sprintf(this->m_data, "%d", val);
}
-
-
-
//
// Create a string with a dword value
//
-STR_String::STR_String(dword val) :
- m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]),
- m_max(STR_STRING_SIZE_DEFAULT_WORD)
+STR_String::STR_String(dword val)
+ : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%lu", val);
+ assertd(this->m_data != NULL);
+ this->m_len = sprintf(this->m_data, "%lu", val);
}
-
-
//
// Create a string with a floating point value
//
-STR_String::STR_String(float val) :
- m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]),
- m_max(STR_STRING_SIZE_DEFAULT_WORD)
+STR_String::STR_String(float val)
+ : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%g", val);
+ assertd(this->m_data != NULL);
+ this->m_len = sprintf(this->m_data, "%g", val);
}
-
-
//
// Create a string with a double value
//
-STR_String::STR_String(double val) :
- m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]),
- m_max(STR_STRING_SIZE_DEFAULT_WORD)
+STR_String::STR_String(double val)
+ : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%g", val);
+ assertd(this->m_data != NULL);
+ this->m_len = sprintf(this->m_data, "%g", val);
}
-
-
/*-------------------------------------------------------------------------------------------------
- Buffer management
+ Buffer management
-------------------------------------------------------------------------------------------------*/
-
-
//
// Make sure that the allocated buffer is at least <len> in size
//
void STR_String::AllocBuffer(int len, bool keep_contents)
{
- // Check if we have enough space
- if (len + 1 <= this->m_max) return;
+ // Check if we have enough space
+ if (len + 1 <= this->m_max)
+ return;
- // Reallocate string
- char *new_data = new char[len + 8];
- if (keep_contents) {
- memcpy(new_data, this->m_data, this->m_len);
- }
- delete[] this->m_data;
+ // Reallocate string
+ char *new_data = new char[len + 8];
+ if (keep_contents) {
+ memcpy(new_data, this->m_data, this->m_len);
+ }
+ delete[] this->m_data;
- // Accept new data
- this->m_max = len + 8;
- this->m_data = new_data;
- assertd(this->m_data != NULL);
+ // Accept new data
+ this->m_max = len + 8;
+ this->m_data = new_data;
+ assertd(this->m_data != NULL);
}
-
-
/*-------------------------------------------------------------------------------------------------
- Basic string operations
+ Basic string operations
-------------------------------------------------------------------------------------------------*/
-
-
//
// Format string (as does sprintf)
//
-STR_String& STR_String::Format(const char *fmt, ...)
+STR_String &STR_String::Format(const char *fmt, ...)
{
- AllocBuffer(2048, false);
+ AllocBuffer(2048, false);
- assertd(this->m_data != NULL);
- // Expand arguments and format to string
- va_list args;
- va_start(args, fmt);
- this->m_len = vsprintf(this->m_data, fmt, args);
- assertd(this->m_len <= 2048);
- va_end(args);
+ assertd(this->m_data != NULL);
+ // Expand arguments and format to string
+ va_list args;
+ va_start(args, fmt);
+ this->m_len = vsprintf(this->m_data, fmt, args);
+ assertd(this->m_len <= 2048);
+ va_end(args);
- return *this;
+ return *this;
}
-
-
//
// Format string (as does sprintf)
//
-STR_String& STR_String::FormatAdd(const char *fmt, ...)
+STR_String &STR_String::FormatAdd(const char *fmt, ...)
{
- AllocBuffer(2048, false);
+ AllocBuffer(2048, false);
- assertd(this->m_data != NULL);
- // Expand arguments and format to string
- va_list args;
- va_start(args, fmt);
- this->m_len += vsprintf(this->m_data + this->m_len, fmt, args);
- assertd(this->m_len <= 2048);
- va_end(args);
+ assertd(this->m_data != NULL);
+ // Expand arguments and format to string
+ va_list args;
+ va_start(args, fmt);
+ this->m_len += vsprintf(this->m_data + this->m_len, fmt, args);
+ assertd(this->m_len <= 2048);
+ va_end(args);
- return *this;
+ return *this;
}
-
-
/*-------------------------------------------------------------------------------------------------
- Properties
+ Properties
-------------------------------------------------------------------------------------------------*/
-
-
//
// Check if string is entirely in UPPERCase
//
bool STR_String::IsUpper() const
{
- for (int i = 0; i < this->m_len; i++)
- if (isLower(this->m_data[i]))
- return false;
+ for (int i = 0; i < this->m_len; i++)
+ if (isLower(this->m_data[i]))
+ return false;
- return true;
+ return true;
}
-
-
//
// Check if string is entirely in lowerCase
//
bool STR_String::IsLower() const
{
- for (int i = 0; i < this->m_len; i++)
- if (isUpper(this->m_data[i]))
- return false;
+ for (int i = 0; i < this->m_len; i++)
+ if (isUpper(this->m_data[i]))
+ return false;
- return true;
+ return true;
}
-
-
/*-------------------------------------------------------------------------------------------------
- Search/Replace
+ Search/Replace
-------------------------------------------------------------------------------------------------*/
-
-
//
// Find the first orccurence of <c> in the string
//
int STR_String::Find(char c, int pos) const
{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strchr(this->m_data + pos, c);
- return (find_pos) ? (find_pos - this->m_data) : -1;
+ assertd(pos >= 0);
+ assertd(this->m_len == 0 || pos < this->m_len);
+ assertd(this->m_data != NULL);
+ char *find_pos = strchr(this->m_data + pos, c);
+ return (find_pos) ? (find_pos - this->m_data) : -1;
}
-
-
//
// Find the first occurrence of <str> in the string
//
int STR_String::Find(const char *str, int pos) const
{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strstr(this->m_data + pos, str);
- return (find_pos) ? (find_pos - this->m_data) : -1;
+ assertd(pos >= 0);
+ assertd(this->m_len == 0 || pos < this->m_len);
+ assertd(this->m_data != NULL);
+ char *find_pos = strstr(this->m_data + pos, str);
+ return (find_pos) ? (find_pos - this->m_data) : -1;
}
-
-
//
// Find the first occurrence of <str> in the string
//
int STR_String::Find(rcSTR_String str, int pos) const
{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strstr(this->m_data + pos, str.ReadPtr());
- return (find_pos) ? (find_pos - this->m_data) : -1;
+ assertd(pos >= 0);
+ assertd(this->m_len == 0 || pos < this->m_len);
+ assertd(this->m_data != NULL);
+ char *find_pos = strstr(this->m_data + pos, str.ReadPtr());
+ return (find_pos) ? (find_pos - this->m_data) : -1;
}
-
-
//
// Find the last occurrence of <c> in the string
//
int STR_String::RFind(char c) const
{
- assertd(this->m_data != NULL);
- char *pos = strrchr(this->m_data, c);
- return (pos) ? (pos - this->m_data) : -1;
+ assertd(this->m_data != NULL);
+ char *pos = strrchr(this->m_data, c);
+ return (pos) ? (pos - this->m_data) : -1;
}
-
-
//
// Find the first occurrence of any character in character set <set> in the string
//
int STR_String::FindOneOf(const char *set, int pos) const
{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strpbrk(this->m_data + pos, set);
- return (find_pos) ? (find_pos - this->m_data) : -1;
+ assertd(pos >= 0);
+ assertd(this->m_len == 0 || pos < this->m_len);
+ assertd(this->m_data != NULL);
+ char *find_pos = strpbrk(this->m_data + pos, set);
+ return (find_pos) ? (find_pos - this->m_data) : -1;
}
-
-
//
// Replace a character in this string with another string
//
void STR_String::Replace(int pos, rcSTR_String str)
{
- //bounds(pos, 0, Length()-1);
+ //bounds(pos, 0, Length()-1);
- if (str.Length() < 1)
- {
- // Remove one character from the string
- memcpy(this->m_data + pos, this->m_data + pos + 1, this->m_len - pos);
- }
- else {
- // Insert zero or more characters into the string
- AllocBuffer(this->m_len + str.Length() - 1, true);
- if (str.Length() != 1) memcpy(this->m_data + pos + str.Length(), this->m_data + pos + 1, Length() - pos);
- memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
- }
+ if (str.Length() < 1) {
+ // Remove one character from the string
+ memcpy(this->m_data + pos, this->m_data + pos + 1, this->m_len - pos);
+ }
+ else {
+ // Insert zero or more characters into the string
+ AllocBuffer(this->m_len + str.Length() - 1, true);
+ if (str.Length() != 1)
+ memcpy(this->m_data + pos + str.Length(), this->m_data + pos + 1, Length() - pos);
+ memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
+ }
- this->m_len += str.Length() - 1;
+ this->m_len += str.Length() - 1;
}
-
-
//
// Replace a substring of this string with another string
//
void STR_String::Replace(int pos, int num, rcSTR_String str)
{
- //bounds(pos, 0, Length()-1);
- //bounds(pos+num, 0, Length());
- assertd(num >= 1);
+ //bounds(pos, 0, Length()-1);
+ //bounds(pos+num, 0, Length());
+ assertd(num >= 1);
- if (str.Length() < num)
- {
- // Remove some data from the string by replacement
- memcpy(this->m_data + pos + str.Length(), this->m_data + pos + num, this->m_len - pos - num + 1);
- memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
- }
- else {
- // Insert zero or more characters into the string
- AllocBuffer(this->m_len + str.Length() - num, true);
- if (str.Length() != num) memcpy(this->m_data + pos + str.Length(), this->m_data + pos + num, Length() - pos - num + 1);
- memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
- }
+ if (str.Length() < num) {
+ // Remove some data from the string by replacement
+ memcpy(
+ this->m_data + pos + str.Length(), this->m_data + pos + num, this->m_len - pos - num + 1);
+ memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
+ }
+ else {
+ // Insert zero or more characters into the string
+ AllocBuffer(this->m_len + str.Length() - num, true);
+ if (str.Length() != num)
+ memcpy(
+ this->m_data + pos + str.Length(), this->m_data + pos + num, Length() - pos - num + 1);
+ memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
+ }
- this->m_len += str.Length() - num;
+ this->m_len += str.Length() - num;
}
-
-
/*-------------------------------------------------------------------------------------------------
- Comparison
+ Comparison
-------------------------------------------------------------------------------------------------*/
-
-
//
// Compare two strings and return the result, <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
//
int STR_String::Compare(rcSTR_String rhs) const
{
- return strcmp(this->ReadPtr(), rhs.ReadPtr());
+ return strcmp(this->ReadPtr(), rhs.ReadPtr());
}
-
-
//
// Compare two strings without respecting case and return the result, <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
//
int STR_String::CompareNoCase(rcSTR_String rhs) const
{
#ifdef WIN32
- return stricmp(this->ReadPtr(), rhs.ReadPtr());
+ return stricmp(this->ReadPtr(), rhs.ReadPtr());
#else
- return strcasecmp(this->ReadPtr(), rhs.ReadPtr());
+ return strcasecmp(this->ReadPtr(), rhs.ReadPtr());
#endif
}
-
-
/*-------------------------------------------------------------------------------------------------
- Formatting
+ Formatting
-------------------------------------------------------------------------------------------------*/
-
-
//
// Capitalize string, "heLLo" -> "HELLO"
//
-STR_String& STR_String::Upper()
+STR_String &STR_String::Upper()
{
- assertd(this->m_data != NULL);
+ assertd(this->m_data != NULL);
#ifdef WIN32
- _strupr(this->m_data);
+ _strupr(this->m_data);
#else
- for (int i = 0; i < this->m_len; i++)
- this->m_data[i] = (this->m_data[i] >= 'a' && this->m_data[i] <= 'z') ? this->m_data[i] + 'A' - 'a' : this->m_data[i];
+ for (int i = 0; i < this->m_len; i++)
+ this->m_data[i] = (this->m_data[i] >= 'a' && this->m_data[i] <= 'z') ?
+ this->m_data[i] + 'A' - 'a' :
+ this->m_data[i];
#endif
- return *this;
+ return *this;
}
-
-
//
// Lower string, "heLLo" -> "hello"
//
-STR_String& STR_String::Lower()
+STR_String &STR_String::Lower()
{
- assertd(this->m_data != NULL);
+ assertd(this->m_data != NULL);
#ifdef WIN32
- _strlwr(this->m_data);
+ _strlwr(this->m_data);
#else
- for (int i = 0; i < this->m_len; i++)
- this->m_data[i] = (this->m_data[i] >= 'A' && this->m_data[i] <= 'Z') ? this->m_data[i] + 'a' - 'A' : this->m_data[i];
+ for (int i = 0; i < this->m_len; i++)
+ this->m_data[i] = (this->m_data[i] >= 'A' && this->m_data[i] <= 'Z') ?
+ this->m_data[i] + 'a' - 'A' :
+ this->m_data[i];
#endif
- return *this;
+ return *this;
}
-
-
//
// Capitalize string, "heLLo" -> "Hello"
//
-STR_String& STR_String::Capitalize()
+STR_String &STR_String::Capitalize()
{
- assertd(this->m_data != NULL);
+ assertd(this->m_data != NULL);
#ifdef WIN32
- if (this->m_len > 0) this->m_data[0] = toupper(this->m_data[0]);
- if (this->m_len > 1) _strlwr(this->m_data + 1);
+ if (this->m_len > 0)
+ this->m_data[0] = toupper(this->m_data[0]);
+ if (this->m_len > 1)
+ _strlwr(this->m_data + 1);
#else
- if (this->m_len > 0)
- this->m_data[0] = (this->m_data[0] >= 'a' && this->m_data[0] <= 'z') ? this->m_data[0] + 'A' - 'a' : this->m_data[0];
- for (int i = 1; i < this->m_len; i++)
- this->m_data[i] = (this->m_data[i] >= 'A' && this->m_data[i] <= 'Z') ? this->m_data[i] + 'a' - 'A' : this->m_data[i];
+ if (this->m_len > 0)
+ this->m_data[0] = (this->m_data[0] >= 'a' && this->m_data[0] <= 'z') ?
+ this->m_data[0] + 'A' - 'a' :
+ this->m_data[0];
+ for (int i = 1; i < this->m_len; i++)
+ this->m_data[i] = (this->m_data[i] >= 'A' && this->m_data[i] <= 'Z') ?
+ this->m_data[i] + 'a' - 'A' :
+ this->m_data[i];
#endif
- return *this;
+ return *this;
}
-
-
//
// Trim whitespace from the left side of the string
//
-STR_String& STR_String::TrimLeft()
+STR_String &STR_String::TrimLeft()
{
- int skip;
- assertd(this->m_data != NULL);
- for (skip = 0; isSpace(this->m_data[skip]); skip++, this->m_len--) {
- /* pass */
- }
- memmove(this->m_data, this->m_data + skip, this->m_len + 1);
- return *this;
+ int skip;
+ assertd(this->m_data != NULL);
+ for (skip = 0; isSpace(this->m_data[skip]); skip++, this->m_len--) {
+ /* pass */
+ }
+ memmove(this->m_data, this->m_data + skip, this->m_len + 1);
+ return *this;
}
-
-
//
// Trim whitespaces from the right side of the string
//
-STR_String& STR_String::TrimRight()
+STR_String &STR_String::TrimRight()
{
- assertd(this->m_data != NULL);
- while (this->m_len && isSpace(this->m_data[this->m_len - 1])) this->m_len--;
- this->m_data[this->m_len] = 0;
- return *this;
+ assertd(this->m_data != NULL);
+ while (this->m_len && isSpace(this->m_data[this->m_len - 1]))
+ this->m_len--;
+ this->m_data[this->m_len] = 0;
+ return *this;
}
-
-
//
// Trim spaces from both sides of the character set
//
-STR_String& STR_String::Trim()
+STR_String &STR_String::Trim()
{
- TrimRight();
- TrimLeft();
- return *this;
+ TrimRight();
+ TrimLeft();
+ return *this;
}
-
-
//
// Trim characters from the character set <set> from the left side of the string
//
-STR_String& STR_String::TrimLeft(char *set)
+STR_String &STR_String::TrimLeft(char *set)
{
- int skip;
- assertd(this->m_data != NULL);
- for (skip = 0; this->m_len && strchr(set, this->m_data[skip]); skip++, this->m_len--) {
- /* pass */
- }
- memmove(this->m_data, this->m_data + skip, this->m_len + 1);
- return *this;
+ int skip;
+ assertd(this->m_data != NULL);
+ for (skip = 0; this->m_len && strchr(set, this->m_data[skip]); skip++, this->m_len--) {
+ /* pass */
+ }
+ memmove(this->m_data, this->m_data + skip, this->m_len + 1);
+ return *this;
}
-
-
//
// Trim characters from the character set <set> from the right side of the string
//
-STR_String& STR_String::TrimRight(char *set)
+STR_String &STR_String::TrimRight(char *set)
{
- assertd(this->m_data != NULL);
- while (this->m_len && strchr(set, this->m_data[this->m_len - 1])) this->m_len--;
- this->m_data[this->m_len] = 0;
- return *this;
+ assertd(this->m_data != NULL);
+ while (this->m_len && strchr(set, this->m_data[this->m_len - 1]))
+ this->m_len--;
+ this->m_data[this->m_len] = 0;
+ return *this;
}
-
-
//
// Trim characters from the character set <set> from both sides of the character set
//
-STR_String& STR_String::Trim(char *set)
+STR_String &STR_String::Trim(char *set)
{
- TrimRight(set);
- TrimLeft(set);
- return *this;
+ TrimRight(set);
+ TrimLeft(set);
+ return *this;
}
-
-
//
// Trim quotes from both sides of the string
//
-STR_String& STR_String::TrimQuotes()
+STR_String &STR_String::TrimQuotes()
{
- // Trim quotes if they are on both sides of the string
- assertd(this->m_data != NULL);
- if ((this->m_len >= 2) && (this->m_data[0] == '\"') && (this->m_data[this->m_len - 1] == '\"'))
- {
- memmove(this->m_data, this->m_data + 1, this->m_len - 2 + 1);
- this->m_len -= 2;
- }
- return *this;
+ // Trim quotes if they are on both sides of the string
+ assertd(this->m_data != NULL);
+ if ((this->m_len >= 2) && (this->m_data[0] == '\"') && (this->m_data[this->m_len - 1] == '\"')) {
+ memmove(this->m_data, this->m_data + 1, this->m_len - 2 + 1);
+ this->m_len -= 2;
+ }
+ return *this;
}
-
-
/*-------------------------------------------------------------------------------------------------
- Assignment/Concatenation
+ Assignment/Concatenation
-------------------------------------------------------------------------------------------------*/
-
-
//
// Set the string's conents to a copy of <src> with length <len>
//
rcSTR_String STR_String::Copy(const char *src, int len)
{
- assertd(len >= 0);
- assertd(src);
- assertd(this->m_data != NULL);
+ assertd(len >= 0);
+ assertd(src);
+ assertd(this->m_data != NULL);
- AllocBuffer(len, false);
- this->m_len = len;
- memcpy(this->m_data, src, len);
- this->m_data[this->m_len] = 0;
+ AllocBuffer(len, false);
+ this->m_len = len;
+ memcpy(this->m_data, src, len);
+ this->m_data[this->m_len] = 0;
- return *this;
+ return *this;
}
-
-
//
// Concate a number of bytes to the current string
//
rcSTR_String STR_String::Concat(const char *data, int len)
{
- assertd(this->m_len >= 0);
- assertd(len >= 0);
- assertd(data);
- assertd(this->m_data != NULL);
+ assertd(this->m_len >= 0);
+ assertd(len >= 0);
+ assertd(data);
+ assertd(this->m_data != NULL);
- AllocBuffer(this->m_len + len, true);
- memcpy(this->m_data + this->m_len, data, len);
- this->m_len += len;
- this->m_data[this->m_len] = 0;
+ AllocBuffer(this->m_len + len, true);
+ memcpy(this->m_data + this->m_len, data, len);
+ this->m_len += len;
+ this->m_data[this->m_len] = 0;
- return *this;
+ return *this;
}
-
std::vector<STR_String> STR_String::Explode(char c) const
{
- STR_String lcv = *this;
- std::vector<STR_String> uc;
+ STR_String lcv = *this;
+ std::vector<STR_String> uc;
- while (lcv.Length()) {
- int pos = lcv.Find(c);
- if (pos < 0) {
- uc.push_back(lcv);
- lcv.Clear();
- }
- else {
- uc.push_back(lcv.Left(pos));
- lcv = lcv.Mid(pos + 1);
- }
- }
+ while (lcv.Length()) {
+ int pos = lcv.Find(c);
+ if (pos < 0) {
+ uc.push_back(lcv);
+ lcv.Clear();
+ }
+ else {
+ uc.push_back(lcv.Left(pos));
+ lcv = lcv.Mid(pos + 1);
+ }
+ }
- //uc. -= STR_String("");
+ //uc. -= STR_String("");
- return uc;
+ return uc;
}
-
#if 0
-int STR_String::Serialize(pCStream stream)
-{
- if (stream->GetAccess() == CStream::Access_Read) {
- int ln;
- stream->Read(&ln, sizeof(ln));
- AllocBuffer(ln, false);
- stream->Read(this->m_data, ln);
- this->m_data[ln] = '\0';
- this->m_len = ln;
- }
- else {
- stream->Write(&this->m_len, sizeof(this->m_len));
- stream->Write(this->m_data, this->m_len);
- }
-
- return this->m_len + sizeof(this->m_len);
+int STR_String::Serialize(pCStream stream)
+{
+ if (stream->GetAccess() == CStream::Access_Read) {
+ int ln;
+ stream->Read(&ln, sizeof(ln));
+ AllocBuffer(ln, false);
+ stream->Read(this->m_data, ln);
+ this->m_data[ln] = '\0';
+ this->m_len = ln;
+ }
+ else {
+ stream->Write(&this->m_len, sizeof(this->m_len));
+ stream->Write(this->m_data, this->m_len);
+ }
+
+ return this->m_len + sizeof(this->m_len);
}
#endif
diff --git a/intern/utfconv/CMakeLists.txt b/intern/utfconv/CMakeLists.txt
index 9450461f50b..1ed3849d53e 100644
--- a/intern/utfconv/CMakeLists.txt
+++ b/intern/utfconv/CMakeLists.txt
@@ -17,7 +17,7 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
+ .
)
set(INC_SYS
@@ -25,9 +25,9 @@ set(INC_SYS
)
set(SRC
- utfconv.c
+ utfconv.c
- utfconv.h
+ utfconv.h
)
set(LIB
@@ -37,10 +37,10 @@ set(LIB
# Why have win32 check here? - this is only used for windows.
# ... because one day we might want to use it on other platforms.
if(WIN32)
- list(APPEND SRC
- utf_winfunc.c
- utf_winfunc.h
- )
+ list(APPEND SRC
+ utf_winfunc.c
+ utf_winfunc.h
+ )
endif()
blender_add_lib(bf_intern_utfconv "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c
index 6a46807e148..4dc290a0146 100644
--- a/intern/utfconv/utf_winfunc.c
+++ b/intern/utfconv/utf_winfunc.c
@@ -18,7 +18,7 @@
*/
#ifndef _WIN32_IE
-#define _WIN32_IE 0x0501
+# define _WIN32_IE 0x0501
#endif
#include "utf_winfunc.h"
@@ -27,157 +27,156 @@
#include <windows.h>
#include <wchar.h>
-
FILE *ufopen(const char *filename, const char *mode)
{
- FILE *f = NULL;
- UTF16_ENCODE(filename);
- UTF16_ENCODE(mode);
-
- if (filename_16 && mode_16) {
- f = _wfopen(filename_16, mode_16);
- }
-
- UTF16_UN_ENCODE(mode);
- UTF16_UN_ENCODE(filename);
-
- if (!f) {
- if ((f = fopen(filename, mode))) {
- printf("WARNING: %s is not utf path. Please update it.\n",filename);
- }
- }
-
- return f;
+ FILE *f = NULL;
+ UTF16_ENCODE(filename);
+ UTF16_ENCODE(mode);
+
+ if (filename_16 && mode_16) {
+ f = _wfopen(filename_16, mode_16);
+ }
+
+ UTF16_UN_ENCODE(mode);
+ UTF16_UN_ENCODE(filename);
+
+ if (!f) {
+ if ((f = fopen(filename, mode))) {
+ printf("WARNING: %s is not utf path. Please update it.\n", filename);
+ }
+ }
+
+ return f;
}
int uopen(const char *filename, int oflag, int pmode)
{
- int f = -1;
- UTF16_ENCODE(filename);
-
- if (filename_16) {
- f = _wopen(filename_16, oflag, pmode);
- }
-
- UTF16_UN_ENCODE(filename);
-
- if (f == -1) {
- if ((f = open(filename,oflag, pmode)) != -1) {
- printf("WARNING: %s is not utf path. Please update it.\n",filename);
- }
- }
-
- return f;
+ int f = -1;
+ UTF16_ENCODE(filename);
+
+ if (filename_16) {
+ f = _wopen(filename_16, oflag, pmode);
+ }
+
+ UTF16_UN_ENCODE(filename);
+
+ if (f == -1) {
+ if ((f = open(filename, oflag, pmode)) != -1) {
+ printf("WARNING: %s is not utf path. Please update it.\n", filename);
+ }
+ }
+
+ return f;
}
int uaccess(const char *filename, int mode)
{
- int r = -1;
- UTF16_ENCODE(filename);
+ int r = -1;
+ UTF16_ENCODE(filename);
- if (filename_16) {
- r = _waccess(filename_16, mode);
- }
+ if (filename_16) {
+ r = _waccess(filename_16, mode);
+ }
- UTF16_UN_ENCODE(filename);
+ UTF16_UN_ENCODE(filename);
- return r;
+ return r;
}
-int urename(const char *oldname, const char *newname )
+int urename(const char *oldname, const char *newname)
{
- int r = -1;
- UTF16_ENCODE(oldname);
- UTF16_ENCODE(newname);
-
- if (oldname_16 && newname_16) {
- r = _wrename(oldname_16, newname_16);
- }
-
- UTF16_UN_ENCODE(newname);
- UTF16_UN_ENCODE(oldname);
- return r;
+ int r = -1;
+ UTF16_ENCODE(oldname);
+ UTF16_ENCODE(newname);
+
+ if (oldname_16 && newname_16) {
+ r = _wrename(oldname_16, newname_16);
+ }
+
+ UTF16_UN_ENCODE(newname);
+ UTF16_UN_ENCODE(oldname);
+ return r;
}
int umkdir(const char *pathname)
{
- BOOL r = 0;
- UTF16_ENCODE(pathname);
-
- if (pathname_16) {
- r = CreateDirectoryW(pathname_16, NULL);
- }
+ BOOL r = 0;
+ UTF16_ENCODE(pathname);
+
+ if (pathname_16) {
+ r = CreateDirectoryW(pathname_16, NULL);
+ }
- UTF16_UN_ENCODE(pathname);
+ UTF16_UN_ENCODE(pathname);
- return r ? 0 : -1;
+ return r ? 0 : -1;
}
char *u_alloc_getenv(const char *varname)
{
- char * r = 0;
- wchar_t * str;
- UTF16_ENCODE(varname);
- if (varname_16) {
- str = _wgetenv(varname_16);
- r = alloc_utf_8_from_16(str, 0);
- }
- UTF16_UN_ENCODE(varname);
-
- return r;
+ char *r = 0;
+ wchar_t *str;
+ UTF16_ENCODE(varname);
+ if (varname_16) {
+ str = _wgetenv(varname_16);
+ r = alloc_utf_8_from_16(str, 0);
+ }
+ UTF16_UN_ENCODE(varname);
+
+ return r;
}
-void u_free_getenv(char *val)
+void u_free_getenv(char *val)
{
- free(val);
+ free(val);
}
int uput_getenv(const char *varname, char *value, size_t buffsize)
{
- int r = 0;
- wchar_t * str;
-
- if (!buffsize) {
- return r;
- }
-
- UTF16_ENCODE(varname);
- if (varname_16) {
- str = _wgetenv(varname_16);
- conv_utf_16_to_8(str, value, buffsize);
- r = 1;
- }
- UTF16_UN_ENCODE(varname);
-
- if (!r) {
- value[0] = 0;
- }
-
- return r;
+ int r = 0;
+ wchar_t *str;
+
+ if (!buffsize) {
+ return r;
+ }
+
+ UTF16_ENCODE(varname);
+ if (varname_16) {
+ str = _wgetenv(varname_16);
+ conv_utf_16_to_8(str, value, buffsize);
+ r = 1;
+ }
+ UTF16_UN_ENCODE(varname);
+
+ if (!r) {
+ value[0] = 0;
+ }
+
+ return r;
}
int uputenv(const char *name, const char *value)
{
- int r = -1;
- UTF16_ENCODE(name);
-
- if (value) {
- /* set */
- UTF16_ENCODE(value);
-
- if (name_16 && value_16) {
- r = (SetEnvironmentVariableW(name_16,value_16)!= 0) ? 0 : -1;
- }
- UTF16_UN_ENCODE(value);
- }
- else {
- /* clear */
- if (name_16) {
- r = (SetEnvironmentVariableW(name_16,NULL)!= 0) ? 0 : -1;
- }
- }
-
- UTF16_UN_ENCODE(name);
-
- return r;
+ int r = -1;
+ UTF16_ENCODE(name);
+
+ if (value) {
+ /* set */
+ UTF16_ENCODE(value);
+
+ if (name_16 && value_16) {
+ r = (SetEnvironmentVariableW(name_16, value_16) != 0) ? 0 : -1;
+ }
+ UTF16_UN_ENCODE(value);
+ }
+ else {
+ /* clear */
+ if (name_16) {
+ r = (SetEnvironmentVariableW(name_16, NULL) != 0) ? 0 : -1;
+ }
+ }
+
+ UTF16_UN_ENCODE(name);
+
+ return r;
}
diff --git a/intern/utfconv/utf_winfunc.h b/intern/utfconv/utf_winfunc.h
index 06d3b106fd9..71fc9835d74 100644
--- a/intern/utfconv/utf_winfunc.h
+++ b/intern/utfconv/utf_winfunc.h
@@ -27,17 +27,17 @@
#include <stdio.h>
-FILE *ufopen(const char * filename, const char * mode);
+FILE *ufopen(const char *filename, const char *mode);
int uopen(const char *filename, int oflag, int pmode);
int uaccess(const char *filename, int mode);
int urename(const char *oldname, const char *newname);
char *u_alloc_getenv(const char *varname);
-void u_free_getenv(char *val);
+void u_free_getenv(char *val);
int uput_getenv(const char *varname, char *value, size_t buffsize);
int uputenv(const char *name, const char *value);
int umkdir(const char *pathname);
-#endif /* __UTF_WINFUNC_H__ */
+#endif /* __UTF_WINFUNC_H__ */
diff --git a/intern/utfconv/utfconv.c b/intern/utfconv/utfconv.c
index 767337b84b3..1dd868b8170 100644
--- a/intern/utfconv/utfconv.c
+++ b/intern/utfconv/utfconv.c
@@ -22,235 +22,282 @@
size_t count_utf_8_from_16(const wchar_t *string16)
{
- int i;
- size_t count = 0;
- wchar_t u = 0;
- if (!string16) {
- return 0;
- }
-
- for (i = 0; (u = string16[i]); i++) {
- if (u < 0x0080) {
- count += 1;
- }
- else {
- if (u < 0x0800) {
- count += 2;
- }
- else {
- if (u < 0xD800) {
- count += 3;
- }
- else {
- if (u < 0xDC00) {
- i++;
- if ((u = string16[i]) == 0) {
- break;
- }
- if (u >= 0xDC00 && u < 0xE000) {
- count += 4;
- }
- }
- else {
- if (u < 0xE000) {
- /*illigal*/;
- }
- else {
- count += 3;
- }
- }
- }
- }
- }
- }
-
- return ++count;
+ int i;
+ size_t count = 0;
+ wchar_t u = 0;
+ if (!string16) {
+ return 0;
+ }
+
+ for (i = 0; (u = string16[i]); i++) {
+ if (u < 0x0080) {
+ count += 1;
+ }
+ else {
+ if (u < 0x0800) {
+ count += 2;
+ }
+ else {
+ if (u < 0xD800) {
+ count += 3;
+ }
+ else {
+ if (u < 0xDC00) {
+ i++;
+ if ((u = string16[i]) == 0) {
+ break;
+ }
+ if (u >= 0xDC00 && u < 0xE000) {
+ count += 4;
+ }
+ }
+ else {
+ if (u < 0xE000) {
+ /*illigal*/;
+ }
+ else {
+ count += 3;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return ++count;
}
-
size_t count_utf_16_from_8(const char *string8)
{
- size_t count = 0;
- char u;
- char type = 0;
- unsigned int u32 = 0;
-
- if (!string8) return 0;
-
- for (; (u = *string8); string8++) {
- if (type == 0) {
- if ((u & 0x01 << 7) == 0) { count++; u32 = 0; continue; } //1 utf-8 char
- if ((u & 0x07 << 5) == 0xC0) { type = 1; u32 = u & 0x1F; continue; } //2 utf-8 char
- if ((u & 0x0F << 4) == 0xE0) { type = 2; u32 = u & 0x0F; continue; } //3 utf-8 char
- if ((u & 0x1F << 3) == 0xF0) { type = 3; u32 = u & 0x07; continue; } //4 utf-8 char
- continue;
- }
- else {
- if ((u & 0xC0) == 0x80) {
- u32 = (u32 << 6) | (u & 0x3F);
- type--;
- }
- else {
- u32 = 0;
- type = 0;
- }
- }
-
- if (type == 0) {
- if ((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000)) count++;
- else if (0x10000 <= u32 && u32 < 0x110000) count += 2;
- u32 = 0;
- }
- }
-
- return ++count;
+ size_t count = 0;
+ char u;
+ char type = 0;
+ unsigned int u32 = 0;
+
+ if (!string8)
+ return 0;
+
+ for (; (u = *string8); string8++) {
+ if (type == 0) {
+ if ((u & 0x01 << 7) == 0) {
+ count++;
+ u32 = 0;
+ continue;
+ } //1 utf-8 char
+ if ((u & 0x07 << 5) == 0xC0) {
+ type = 1;
+ u32 = u & 0x1F;
+ continue;
+ } //2 utf-8 char
+ if ((u & 0x0F << 4) == 0xE0) {
+ type = 2;
+ u32 = u & 0x0F;
+ continue;
+ } //3 utf-8 char
+ if ((u & 0x1F << 3) == 0xF0) {
+ type = 3;
+ u32 = u & 0x07;
+ continue;
+ } //4 utf-8 char
+ continue;
+ }
+ else {
+ if ((u & 0xC0) == 0x80) {
+ u32 = (u32 << 6) | (u & 0x3F);
+ type--;
+ }
+ else {
+ u32 = 0;
+ type = 0;
+ }
+ }
+
+ if (type == 0) {
+ if ((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000))
+ count++;
+ else if (0x10000 <= u32 && u32 < 0x110000)
+ count += 2;
+ u32 = 0;
+ }
+ }
+
+ return ++count;
}
-
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8)
{
- char *out8end = out8 + size8;
- wchar_t u = 0;
- int err = 0;
- if (!size8 || !in16 || !out8) return UTF_ERROR_NULL_IN;
- out8end--;
-
- for (; out8 < out8end && (u = *in16); in16++, out8++) {
- if (u < 0x0080) {
- *out8 = u;
- }
- else if (u < 0x0800) {
- if (out8 + 1 >= out8end) break;
- *out8++ = (0x3 << 6) | (0x1F & (u >> 6));
- *out8 = (0x1 << 7) | (0x3F & (u));
- }
- else if (u < 0xD800 || u >= 0xE000) {
- if (out8 + 2 >= out8end) break;
- *out8++ = (0x7 << 5) | (0xF & (u >> 12));
- *out8++ = (0x1 << 7) | (0x3F & (u >> 6));
- *out8 = (0x1 << 7) | (0x3F & (u));
- }
- else if (u < 0xDC00) {
- wchar_t u2 = *++in16;
-
- if (!u2) break;
- if (u2 >= 0xDC00 && u2 < 0xE000) {
- if (out8 + 3 >= out8end) break; else {
- unsigned int uc = 0x10000 + (u2 - 0xDC00) + ((u - 0xD800) << 10);
-
- *out8++ = (0xF << 4) | (0x7 & (uc >> 18));
- *out8++ = (0x1 << 7) | (0x3F & (uc >> 12));
- *out8++ = (0x1 << 7) | (0x3F & (uc >> 6));
- *out8 = (0x1 << 7) | (0x3F & (uc));
- }
- }
- else {
- out8--; err |= UTF_ERROR_ILLCHAR;
- }
- }
- else if (u < 0xE000) {
- out8--; err |= UTF_ERROR_ILLCHAR;
- }
- }
-
- *out8 = *out8end = 0;
-
- if (*in16) err |= UTF_ERROR_SMALL;
-
- return err;
+ char *out8end = out8 + size8;
+ wchar_t u = 0;
+ int err = 0;
+ if (!size8 || !in16 || !out8)
+ return UTF_ERROR_NULL_IN;
+ out8end--;
+
+ for (; out8 < out8end && (u = *in16); in16++, out8++) {
+ if (u < 0x0080) {
+ *out8 = u;
+ }
+ else if (u < 0x0800) {
+ if (out8 + 1 >= out8end)
+ break;
+ *out8++ = (0x3 << 6) | (0x1F & (u >> 6));
+ *out8 = (0x1 << 7) | (0x3F & (u));
+ }
+ else if (u < 0xD800 || u >= 0xE000) {
+ if (out8 + 2 >= out8end)
+ break;
+ *out8++ = (0x7 << 5) | (0xF & (u >> 12));
+ *out8++ = (0x1 << 7) | (0x3F & (u >> 6));
+ *out8 = (0x1 << 7) | (0x3F & (u));
+ }
+ else if (u < 0xDC00) {
+ wchar_t u2 = *++in16;
+
+ if (!u2)
+ break;
+ if (u2 >= 0xDC00 && u2 < 0xE000) {
+ if (out8 + 3 >= out8end)
+ break;
+ else {
+ unsigned int uc = 0x10000 + (u2 - 0xDC00) + ((u - 0xD800) << 10);
+
+ *out8++ = (0xF << 4) | (0x7 & (uc >> 18));
+ *out8++ = (0x1 << 7) | (0x3F & (uc >> 12));
+ *out8++ = (0x1 << 7) | (0x3F & (uc >> 6));
+ *out8 = (0x1 << 7) | (0x3F & (uc));
+ }
+ }
+ else {
+ out8--;
+ err |= UTF_ERROR_ILLCHAR;
+ }
+ }
+ else if (u < 0xE000) {
+ out8--;
+ err |= UTF_ERROR_ILLCHAR;
+ }
+ }
+
+ *out8 = *out8end = 0;
+
+ if (*in16)
+ err |= UTF_ERROR_SMALL;
+
+ return err;
}
-
int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16)
{
- char u;
- char type = 0;
- unsigned int u32 = 0;
- wchar_t *out16end = out16 + size16;
- int err = 0;
- if (!size16 || !in8 || !out16) return UTF_ERROR_NULL_IN;
- out16end--;
-
- for (; out16 < out16end && (u = *in8); in8++) {
- if (type == 0) {
- if ((u & 0x01 << 7) == 0) { *out16 = u; out16++; u32 = 0; continue; } //1 utf-8 char
- if ((u & 0x07 << 5) == 0xC0) { type = 1; u32 = u & 0x1F; continue; } //2 utf-8 char
- if ((u & 0x0F << 4) == 0xE0) { type = 2; u32 = u & 0x0F; continue; } //3 utf-8 char
- if ((u & 0x1F << 3) == 0xF0) { type = 3; u32 = u & 0x07; continue; } //4 utf-8 char
- err |= UTF_ERROR_ILLCHAR;
- continue;
- }
- else {
- if ((u & 0xC0) == 0x80) {
- u32 = (u32 << 6) | (u & 0x3F);
- type--;
- }
- else {
- u32 = 0; type = 0; err |= UTF_ERROR_ILLSEQ;
- }
- }
- if (type == 0) {
- if ((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000)) {
- *out16 = u32;
- out16++;
- }
- else if (0x10000 <= u32 && u32 < 0x110000) {
- if (out16 + 1 >= out16end) break;
- u32 -= 0x10000;
- *out16 = 0xD800 + (u32 >> 10);
- out16++;
- *out16 = 0xDC00 + (u32 & 0x3FF);
- out16++;
- }
- u32 = 0;
- }
-
- }
-
- *out16 = *out16end = 0;
-
- if (*in8) err |= UTF_ERROR_SMALL;
-
- return err;
+ char u;
+ char type = 0;
+ unsigned int u32 = 0;
+ wchar_t *out16end = out16 + size16;
+ int err = 0;
+ if (!size16 || !in8 || !out16)
+ return UTF_ERROR_NULL_IN;
+ out16end--;
+
+ for (; out16 < out16end && (u = *in8); in8++) {
+ if (type == 0) {
+ if ((u & 0x01 << 7) == 0) {
+ *out16 = u;
+ out16++;
+ u32 = 0;
+ continue;
+ } //1 utf-8 char
+ if ((u & 0x07 << 5) == 0xC0) {
+ type = 1;
+ u32 = u & 0x1F;
+ continue;
+ } //2 utf-8 char
+ if ((u & 0x0F << 4) == 0xE0) {
+ type = 2;
+ u32 = u & 0x0F;
+ continue;
+ } //3 utf-8 char
+ if ((u & 0x1F << 3) == 0xF0) {
+ type = 3;
+ u32 = u & 0x07;
+ continue;
+ } //4 utf-8 char
+ err |= UTF_ERROR_ILLCHAR;
+ continue;
+ }
+ else {
+ if ((u & 0xC0) == 0x80) {
+ u32 = (u32 << 6) | (u & 0x3F);
+ type--;
+ }
+ else {
+ u32 = 0;
+ type = 0;
+ err |= UTF_ERROR_ILLSEQ;
+ }
+ }
+ if (type == 0) {
+ if ((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000)) {
+ *out16 = u32;
+ out16++;
+ }
+ else if (0x10000 <= u32 && u32 < 0x110000) {
+ if (out16 + 1 >= out16end)
+ break;
+ u32 -= 0x10000;
+ *out16 = 0xD800 + (u32 >> 10);
+ out16++;
+ *out16 = 0xDC00 + (u32 & 0x3FF);
+ out16++;
+ }
+ u32 = 0;
+ }
+ }
+
+ *out16 = *out16end = 0;
+
+ if (*in8)
+ err |= UTF_ERROR_SMALL;
+
+ return err;
}
/* UNUSED FUNCTIONS */
#if 0
static int is_ascii(const char *in8)
{
- for (; *in8; in8++)
- if (0x80 & *in8) return 0;
+ for (; *in8; in8++)
+ if (0x80 & *in8) return 0;
- return 1;
+ return 1;
}
static void utf_8_cut_end(char *inout8, size_t maxcutpoint)
{
- char *cur = inout8 + maxcutpoint;
- char cc;
- if (!inout8) return;
+ char *cur = inout8 + maxcutpoint;
+ char cc;
+ if (!inout8) return;
- cc = *cur;
+ cc = *cur;
}
#endif
-
char *alloc_utf_8_from_16(const wchar_t *in16, size_t add)
{
- size_t bsize = count_utf_8_from_16(in16);
- char *out8 = NULL;
- if (!bsize) return NULL;
- out8 = (char *)malloc(sizeof(char) * (bsize + add));
- conv_utf_16_to_8(in16, out8, bsize);
- return out8;
+ size_t bsize = count_utf_8_from_16(in16);
+ char *out8 = NULL;
+ if (!bsize)
+ return NULL;
+ out8 = (char *)malloc(sizeof(char) * (bsize + add));
+ conv_utf_16_to_8(in16, out8, bsize);
+ return out8;
}
wchar_t *alloc_utf16_from_8(const char *in8, size_t add)
{
- size_t bsize = count_utf_16_from_8(in8);
- wchar_t *out16 = NULL;
- if (!bsize) return NULL;
- out16 = (wchar_t *) malloc(sizeof(wchar_t) * (bsize + add));
- conv_utf_8_to_16(in8, out16, bsize);
- return out16;
+ size_t bsize = count_utf_16_from_8(in8);
+ wchar_t *out16 = NULL;
+ if (!bsize)
+ return NULL;
+ out16 = (wchar_t *)malloc(sizeof(wchar_t) * (bsize + add));
+ conv_utf_8_to_16(in8, out16, bsize);
+ return out16;
}
diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h
index 35bbe3ac108..f13afbc0934 100644
--- a/intern/utfconv/utfconv.h
+++ b/intern/utfconv/utfconv.h
@@ -25,8 +25,8 @@
#include <stdio.h>
#include <stdlib.h>
-#ifdef __cplusplus
-extern "C" {
+#ifdef __cplusplus
+extern "C" {
#endif
/**
@@ -48,8 +48,9 @@ size_t count_utf_16_from_8(const char *string8);
*/
#define UTF_ERROR_NULL_IN 1 << 0 /* Error occures when requered parameter is missing*/
#define UTF_ERROR_ILLCHAR 1 << 1 /* Error if character is in illigal UTF rage*/
-#define UTF_ERROR_SMALL 1 << 2 /* Passed size is to small. It gives legal string with character missing at the end*/
-#define UTF_ERROR_ILLSEQ 1 << 3 /* Error if sequence is broken and doesn't finish*/
+#define UTF_ERROR_SMALL \
+ 1 << 2 /* Passed size is to small. It gives legal string with character missing at the end*/
+#define UTF_ERROR_ILLSEQ 1 << 3 /* Error if sequence is broken and doesn't finish*/
/**
* Converts utf-16 string to allocated utf-8 string
@@ -69,7 +70,6 @@ int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8);
*/
int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16);
-
/**
* Allocates and converts the utf-8 string from utf-16
* @param in16 utf-16 string to convert
@@ -87,14 +87,17 @@ char *alloc_utf_8_from_16(const wchar_t *in16, size_t add);
wchar_t *alloc_utf16_from_8(const char *in8, size_t add);
/* Easy allocation and conversion of new utf-16 string. New string has _16 suffix. Must be deallocated with UTF16_UN_ENCODE in right order*/
-#define UTF16_ENCODE(in8str) if (1) { \
- wchar_t *in8str ## _16 = alloc_utf16_from_8((const char *)in8str, 0)
+#define UTF16_ENCODE(in8str) \
+ if (1) { \
+ wchar_t *in8str##_16 = alloc_utf16_from_8((const char *)in8str, 0)
#define UTF16_UN_ENCODE(in8str) \
- free(in8str ## _16); } (void)0
+ free(in8str##_16); \
+ } \
+ (void)0
-#ifdef __cplusplus
+#ifdef __cplusplus
}
#endif
-#endif /* __UTFCONV_H__ */
+#endif /* __UTFCONV_H__ */